fix: voice_mode break fix (#8014)
* 🔧 (use-get-messages-polling.ts): refactor enqueuePolling method to simplify logic and improve readability 🔧 (use-get-messages-polling.ts): refactor startNextPolling method to remove unnecessary code and improve efficiency 🔧 (use-get-messages-polling.ts): refactor removeFromQueue method to simplify and improve maintainability 🔧 (use-get-messages-polling.ts): refactor useGetMessagesPollingMutation to handle stopping polling and removing from queue 🔧 (use-get-transactions.ts): add early return to getTransactionsFn to handle empty id case 🔧 (use-get-voice-list.ts): refactor useGetVoiceList function to handle empty elevenlabsApiKey case and improve readability 🔧 (audio-settings-dialog.tsx): update useGetVoiceList call to pass elevenLabsApiKey as argument * queues should hold payloads not strings * ✨ (use-get-global-variables.ts): add setGlobalVariablesEntities function to store global variables entities for use in the application ✨ (audio-settings-dialog.tsx): introduce debounced function to update ElevenLabs API key in global variables entities 📝 (globalVariables.ts): add setGlobalVariablesEntities function to the global variables store for managing entities 📝 (index.ts): define GlobalVariable type for global variables entities in the store * ✨ (frontend): add support for extracting flowId from URL query parameters to allow direct linking to specific flow logs. --------- Co-authored-by: cristhianzl <cristhian.lousa@gmail.com>
This commit is contained in:
parent
0e6fc94dad
commit
9096293e52
9 changed files with 74 additions and 44 deletions
|
|
@ -1143,8 +1143,8 @@ async def flow_tts_websocket(
|
|||
try:
|
||||
await client_websocket.accept()
|
||||
|
||||
openai_send_q: asyncio.Queue[str] = asyncio.Queue()
|
||||
client_send_q: asyncio.Queue[str] = asyncio.Queue()
|
||||
openai_send_q: asyncio.Queue[dict] = asyncio.Queue()
|
||||
client_send_q: asyncio.Queue[dict] = asyncio.Queue()
|
||||
|
||||
log_event = create_event_logger()
|
||||
|
||||
|
|
@ -1171,13 +1171,13 @@ async def flow_tts_websocket(
|
|||
def openai_send(payload):
|
||||
log_event(payload, LF_TO_OPENAI)
|
||||
logger.trace(f"Sending text {LF_TO_OPENAI}: {payload['type']}")
|
||||
openai_send_q.put_nowait(json.dumps(payload))
|
||||
openai_send_q.put_nowait(payload)
|
||||
logger.trace("JSON sent.")
|
||||
|
||||
def client_send(payload):
|
||||
log_event(payload, LF_TO_CLIENT)
|
||||
logger.trace(f"Sending JSON {LF_TO_CLIENT}: {payload['type']}")
|
||||
client_send_q.put_nowait(json.dumps(payload))
|
||||
client_send_q.put_nowait(payload)
|
||||
logger.trace("JSON sent.")
|
||||
|
||||
async def close():
|
||||
|
|
|
|||
|
|
@ -34,20 +34,12 @@ const MessagesPollingManager = {
|
|||
activePolls: new Map<string, PollingItem>(),
|
||||
|
||||
enqueuePolling(id: string, pollingItem: PollingItem) {
|
||||
if (!this.pollingQueue.has(id)) {
|
||||
this.pollingQueue.set(id, []);
|
||||
}
|
||||
this.pollingQueue.set(
|
||||
id,
|
||||
(this.pollingQueue.get(id) || []).filter(
|
||||
(item) => item.timestamp !== pollingItem.timestamp,
|
||||
),
|
||||
);
|
||||
this.pollingQueue.get(id)?.push(pollingItem);
|
||||
this.stopAll();
|
||||
|
||||
if (!this.activePolls.has(id)) {
|
||||
this.startNextPolling(id);
|
||||
}
|
||||
this.pollingQueue.clear();
|
||||
this.pollingQueue.set(id, [pollingItem]);
|
||||
|
||||
this.startNextPolling(id);
|
||||
},
|
||||
|
||||
startNextPolling(id: string) {
|
||||
|
|
@ -67,12 +59,7 @@ const MessagesPollingManager = {
|
|||
if (activePoll) {
|
||||
clearInterval(activePoll.interval);
|
||||
this.activePolls.delete(id);
|
||||
const queue = this.pollingQueue.get(id) || [];
|
||||
this.pollingQueue.set(
|
||||
id,
|
||||
queue.filter((item) => item.timestamp !== activePoll.timestamp),
|
||||
);
|
||||
this.startNextPolling(id);
|
||||
this.pollingQueue.delete(id);
|
||||
}
|
||||
},
|
||||
|
||||
|
|
@ -83,11 +70,7 @@ const MessagesPollingManager = {
|
|||
},
|
||||
|
||||
removeFromQueue(id: string, timestamp: number) {
|
||||
const queue = this.pollingQueue.get(id) || [];
|
||||
this.pollingQueue.set(
|
||||
id,
|
||||
queue.filter((item) => item.timestamp !== timestamp),
|
||||
);
|
||||
this.pollingQueue.delete(id);
|
||||
},
|
||||
};
|
||||
|
||||
|
|
@ -146,6 +129,10 @@ export const useGetMessagesPollingMutation = (
|
|||
return Promise.reject("Request already in progress");
|
||||
}
|
||||
|
||||
if (MessagesPollingManager.activePolls.has(requestId)) {
|
||||
MessagesPollingManager.stopPoll(requestId);
|
||||
}
|
||||
|
||||
if (
|
||||
requestIdRef.current === requestId &&
|
||||
MessagesPollingManager.activePolls.has(requestId)
|
||||
|
|
@ -189,11 +176,15 @@ export const useGetMessagesPollingMutation = (
|
|||
return () => {
|
||||
if (requestIdRef.current) {
|
||||
MessagesPollingManager.stopPoll(requestIdRef.current);
|
||||
MessagesPollingManager.removeFromQueue(
|
||||
requestIdRef.current,
|
||||
Date.now(),
|
||||
);
|
||||
requestIdRef.current = null;
|
||||
}
|
||||
};
|
||||
}, []);
|
||||
|
||||
// Cast the mutation to the correct type
|
||||
const mutation = mutate(
|
||||
["useGetMessagesMutation"],
|
||||
(payload: MessagesQueryParams) =>
|
||||
|
|
|
|||
|
|
@ -46,7 +46,10 @@ export const useGetTransactionsQuery: useQueryFunctionType<
|
|||
};
|
||||
|
||||
const getTransactionsFn = async () => {
|
||||
if (!id) return { pagination: {}, rows: [], columns: [] };
|
||||
|
||||
const config = {};
|
||||
|
||||
config["params"] = { flow_id: id };
|
||||
if (params) {
|
||||
config["params"] = { ...config["params"], ...params };
|
||||
|
|
|
|||
|
|
@ -20,6 +20,9 @@ export const useGetGlobalVariables: useQueryFunctionType<
|
|||
const setUnavailableFields = useGlobalVariablesStore(
|
||||
(state) => state.setUnavailableFields,
|
||||
);
|
||||
const setGlobalVariablesEntities = useGlobalVariablesStore(
|
||||
(state) => state.setGlobalVariablesEntities,
|
||||
);
|
||||
|
||||
const isAuthenticated = useAuthStore((state) => state.isAuthenticated);
|
||||
|
||||
|
|
@ -28,6 +31,7 @@ export const useGetGlobalVariables: useQueryFunctionType<
|
|||
const res = await api.get(`${getURL("VARIABLES")}/`);
|
||||
setGlobalVariablesEntries(res.data.map((entry) => entry.name));
|
||||
setUnavailableFields(getUnavailableFields(res.data));
|
||||
setGlobalVariablesEntities(res.data);
|
||||
return res.data;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -4,22 +4,18 @@ import { api } from "../../api";
|
|||
import { getURL } from "../../helpers/constants";
|
||||
import { UseRequestProcessor } from "../../services/request-processor";
|
||||
|
||||
export const useGetVoiceList: useQueryFunctionType<undefined, any> = (
|
||||
options,
|
||||
) => {
|
||||
export const useGetVoiceList = (elevenlabsApiKey: string, options?: any) => {
|
||||
const { query } = UseRequestProcessor();
|
||||
const setVoices = useVoiceStore((state) => state.setVoices);
|
||||
const voices = useVoiceStore((state) => state.voices);
|
||||
|
||||
const getVoiceListFn = async (): Promise<
|
||||
{
|
||||
name: string;
|
||||
voice_id: string;
|
||||
}[]
|
||||
> => {
|
||||
const getVoiceListFn = async () => {
|
||||
if (voices.length > 0) {
|
||||
return voices;
|
||||
}
|
||||
if (!elevenlabsApiKey) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const res = await api.get(`${getURL("VOICE")}/elevenlabs/voice_ids`);
|
||||
const data = res.data;
|
||||
|
|
@ -41,7 +37,7 @@ export const useGetVoiceList: useQueryFunctionType<undefined, any> = (
|
|||
};
|
||||
|
||||
const queryResult = query(
|
||||
["useGetVoiceList"],
|
||||
["useGetVoiceList", elevenlabsApiKey],
|
||||
getVoiceListFn,
|
||||
defaultOptions,
|
||||
);
|
||||
|
|
|
|||
|
|
@ -9,7 +9,9 @@ import {
|
|||
DropdownMenuTrigger,
|
||||
} from "@/components/ui/dropdown-menu";
|
||||
import { Separator } from "@/components/ui/separator";
|
||||
import { usePatchGlobalVariables } from "@/controllers/API/queries/variables";
|
||||
import { useGetVoiceList } from "@/controllers/API/queries/voice/use-get-voice-list";
|
||||
import { useDebounce } from "@/hooks/use-debounce";
|
||||
import GeneralDeleteConfirmationModal from "@/shared/components/delete-confirmation-modal";
|
||||
import GeneralGlobalVariableModal from "@/shared/components/global-variable-modal";
|
||||
import { useGlobalVariablesStore } from "@/stores/globalVariablesStore/globalVariables";
|
||||
|
|
@ -69,6 +71,10 @@ const SettingsVoiceModal = ({
|
|||
(state) => state.globalVariablesEntries,
|
||||
);
|
||||
|
||||
const globalVariablesEntities = useGlobalVariablesStore(
|
||||
(state) => state.globalVariablesEntities,
|
||||
);
|
||||
|
||||
const openaiVoices = useVoiceStore((state) => state.openaiVoices);
|
||||
const [allVoices, setAllVoices] = useState<
|
||||
{
|
||||
|
|
@ -83,7 +89,7 @@ const SettingsVoiceModal = ({
|
|||
data: voiceList,
|
||||
isFetched,
|
||||
refetch,
|
||||
} = useGetVoiceList({
|
||||
} = useGetVoiceList(elevenLabsApiKey, {
|
||||
enabled: shouldFetchVoices,
|
||||
refetchOnMount: shouldFetchVoices,
|
||||
refetchOnWindowFocus: shouldFetchVoices,
|
||||
|
|
@ -158,6 +164,8 @@ const SettingsVoiceModal = ({
|
|||
return globalVariables?.map((variable) => variable).includes(variable);
|
||||
};
|
||||
|
||||
const { mutate: updateVariable } = usePatchGlobalVariables();
|
||||
|
||||
const handleSetMicrophone = (deviceId: string) => {
|
||||
setSelectedMicrophone(deviceId);
|
||||
localStorage.setItem("lf_selected_microphone", deviceId);
|
||||
|
|
@ -227,6 +235,25 @@ const SettingsVoiceModal = ({
|
|||
const showAddOpenAIKeyButton = !hasOpenAIAPIKey || isEditingOpenAIKey;
|
||||
const showAllSettings = hasOpenAIAPIKey && !isEditingOpenAIKey;
|
||||
|
||||
const debouncedSetElevenLabsApiKey = useDebounce((value: string) => {
|
||||
const globalVariable = globalVariablesEntities?.find(
|
||||
(variable) => variable.name === "ELEVENLABS_API_KEY",
|
||||
);
|
||||
|
||||
if (globalVariable) {
|
||||
updateVariable({
|
||||
name: "ELEVENLABS_API_KEY",
|
||||
value: value,
|
||||
id: globalVariable.id,
|
||||
});
|
||||
}
|
||||
}, 2000);
|
||||
|
||||
const handleSetElevenLabsApiKey = (value: string) => {
|
||||
setElevenLabsApiKey(value);
|
||||
debouncedSetElevenLabsApiKey(value);
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<DropdownMenu open={open} onOpenChange={onOpenChangeDropdownMenu}>
|
||||
|
|
@ -372,9 +399,7 @@ const SettingsVoiceModal = ({
|
|||
/>
|
||||
)}
|
||||
value={elevenLabsApiKey}
|
||||
onChange={(value) => {
|
||||
setElevenLabsApiKey(value);
|
||||
}}
|
||||
onChange={handleSetElevenLabsApiKey}
|
||||
selectedOption={
|
||||
checkIfGlobalVariableExists(elevenLabsApiKey)
|
||||
? elevenLabsApiKey
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ import { FlowSettingsPropsType } from "@/types/components";
|
|||
import { convertUTCToLocalTimezone } from "@/utils/utils";
|
||||
import { ColDef, ColGroupDef } from "ag-grid-community";
|
||||
import { useCallback, useEffect, useState } from "react";
|
||||
import { useSearchParams } from "react-router-dom";
|
||||
import BaseModal from "../baseModal";
|
||||
|
||||
export default function FlowLogsModal({
|
||||
|
|
@ -19,9 +20,11 @@ export default function FlowLogsModal({
|
|||
const [pageSize, setPageSize] = useState(20);
|
||||
const [columns, setColumns] = useState<Array<ColDef | ColGroupDef>>([]);
|
||||
const [rows, setRows] = useState<any>([]);
|
||||
const [searchParams] = useSearchParams();
|
||||
const flowIdFromUrl = searchParams.get("id");
|
||||
|
||||
const { data, isLoading, refetch } = useGetTransactionsQuery({
|
||||
id: currentFlowId,
|
||||
id: currentFlowId ?? flowIdFromUrl,
|
||||
params: {
|
||||
page: pageIndex,
|
||||
size: pageSize,
|
||||
|
|
|
|||
|
|
@ -11,5 +11,9 @@ export const useGlobalVariablesStore = create<GlobalVariablesStore>(
|
|||
setGlobalVariablesEntries: (entries) => {
|
||||
set({ globalVariablesEntries: entries });
|
||||
},
|
||||
setGlobalVariablesEntities: (entities) => {
|
||||
set({ globalVariablesEntities: entities });
|
||||
},
|
||||
globalVariablesEntities: undefined,
|
||||
}),
|
||||
);
|
||||
|
|
|
|||
|
|
@ -1,6 +1,10 @@
|
|||
import { GlobalVariable } from "@/types/global_variables";
|
||||
|
||||
export type GlobalVariablesStore = {
|
||||
globalVariablesEntries: Array<string> | undefined;
|
||||
setGlobalVariablesEntries: (entries: Array<string>) => void;
|
||||
unavailableFields: { [name: string]: string };
|
||||
setUnavailableFields: (fields: { [name: string]: string }) => void;
|
||||
globalVariablesEntities: Array<GlobalVariable> | undefined;
|
||||
setGlobalVariablesEntities: (entities: GlobalVariable[]) => void;
|
||||
};
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue