From 03045ae8f605bcb93085fd6902172e8bab70aa47 Mon Sep 17 00:00:00 2001 From: Jicheng Lu Date: Fri, 18 Sep 2026 19:19:28 -0500 Subject: [PATCH 1/3] Replace the Audio Transcription LLM config with Live The agent LLM config card now offers a Live section, bound to llm_config.live and filtered to models typed Live, in place of Audio Transcription. It sits before Realtime, and uses the basic provider/model component: live reasoning effort comes from the agent's own config, so a reasoning dropdown there would do nothing. Co-Authored-By: Claude Opus 5 (1M context) --- src/lib/helpers/enums.js | 6 ++++-- src/lib/helpers/types/agentTypes.js | 2 +- .../agent-components/agent-llm-config.svelte | 16 ++++++++-------- 3 files changed, 13 insertions(+), 11 deletions(-) diff --git a/src/lib/helpers/enums.js b/src/lib/helpers/enums.js index fef2a980..63d242bf 100644 --- a/src/lib/helpers/enums.js +++ b/src/lib/helpers/enums.js @@ -228,7 +228,8 @@ const llmModelType = { Embedding: "Embedding", Audio: "Audio", Realtime: "Realtime", - Web: "Web" + Web: "Web", + Live: "Live" }; export const LlmModelType = Object.freeze(llmModelType); @@ -246,7 +247,8 @@ const llmModelCapability = { AudioGeneration: "AudioGeneration", Realtime: "Realtime", WebSearch: "WebSearch", - PdfReading: "PdfReading" + PdfReading: "PdfReading", + Live: "Live" }; export const LlmModelCapability = Object.freeze(llmModelCapability); diff --git a/src/lib/helpers/types/agentTypes.js b/src/lib/helpers/types/agentTypes.js index b0fb251e..3d637c62 100644 --- a/src/lib/helpers/types/agentTypes.js +++ b/src/lib/helpers/types/agentTypes.js @@ -21,8 +21,8 @@ * @property {string?} [reasoning_effort_level] * @property {string?} [response_format] * @property {any} [image_composition] - * @property {any} [audio_transcription] * @property {any} [realtime] + * @property {any} [live] */ /** diff --git a/src/routes/page/agent/[agentId]/agent-components/agent-llm-config.svelte b/src/routes/page/agent/[agentId]/agent-components/agent-llm-config.svelte index 21c95a3e..c5b7101a 100644 --- a/src/routes/page/agent/[agentId]/agent-components/agent-llm-config.svelte +++ b/src/routes/page/agent/[agentId]/agent-components/agent-llm-config.svelte @@ -20,12 +20,12 @@ export function fetchLlmConfig() { const chatConfig = chatConfigCmp?.fetchConfig(); const imageCompositionConfig = imageCompositionConfigCmp?.fetchConfig(); - const audioTranscriptionConfig = audioTranscriptionConfigCmp?.fetchConfig(); + const liveConfig = liveConfigCmp?.fetchConfig(); const realtimeConfig = realtimeConfigCmp?.fetchConfig(); return { ...chatConfig, image_composition: imageCompositionConfig ? {...imageCompositionConfig} : null, - audio_transcription: audioTranscriptionConfig ? {...audioTranscriptionConfig} : null, + live: liveConfig ? {...liveConfig} : null, realtime: realtimeConfig ? {...realtimeConfig} : null }; } @@ -35,7 +35,7 @@ /** @type {any} */ let imageCompositionConfigCmp = $state(null); /** @type {any} */ - let audioTranscriptionConfigCmp = $state(null); + let liveConfigCmp = $state(null); /** @type {any} */ let realtimeConfigCmp = $state(null); @@ -71,12 +71,12 @@ {handleAgentChange} /> Date: Tue, 22 Sep 2026 11:47:41 -0500 Subject: [PATCH 2/3] Identify the signed-in user on the realtime chat handshake A browser cannot set headers on a WebSocket, so no bearer token reached /chat/stream and the server saw nobody for the whole conversation. Pass the user id as a query string parameter instead, keeping it out of the path because the server reads agentId and conversationId from the end of it. --- src/lib/services/realtime-chat-service.js | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/src/lib/services/realtime-chat-service.js b/src/lib/services/realtime-chat-service.js index 72efedb9..4cd3c1f7 100644 --- a/src/lib/services/realtime-chat-service.js +++ b/src/lib/services/realtime-chat-service.js @@ -1,5 +1,6 @@ import { PUBLIC_SERVICE_URL } from "$env/static/public"; import { buildConversationUserStates } from "$lib/helpers/conversation"; +import { getUserStore } from "$lib/helpers/store"; import { AudioRecordingWorklet } from "$lib/helpers/realtime/pcmProcessor"; // @ts-ignore @@ -37,7 +38,7 @@ export const realtimeChat = { start(agentId, conversationId) { reset(); const wsUrl = buildWebsocketUrl(); - socket = new WebSocket(`${wsUrl}/chat/stream/${agentId}/${conversationId}`); + socket = new WebSocket(`${wsUrl}/chat/stream/${agentId}/${conversationId}${buildUserQuery()}`); socket.onopen = async () => { console.log("WebSocket connected"); @@ -131,6 +132,21 @@ export const realtimeChat = { }; +/** + * Identifies the signed-in user on the handshake. + * + * A browser cannot set headers on a WebSocket, so no bearer token reaches /chat/stream and the + * server would otherwise see nobody for the whole conversation. It goes in the query string + * rather than as a path segment because the server reads agentId and conversationId from the END + * of the path, so an extra segment would shift both. + * + * @returns {string} + */ +function buildUserQuery() { + const user = getUserStore(); + return user?.id ? `?user-id=${encodeURIComponent(user.id)}` : ''; +} + function buildWebsocketUrl() { let url = ''; const host = PUBLIC_SERVICE_URL.split('://'); From ce0f5c5d3b0f04f4d25d4be94c66fa9b6a7d3363 Mon Sep 17 00:00:00 2001 From: Jicheng Lu Date: Tue, 22 Sep 2026 11:47:48 -0500 Subject: [PATCH 3/3] Cover the full viewport with the loader backdrop outside the vertical layout The overlay offset its left edge by the sidebar width on every screen wider than 1024px, but only pages under VerticalLayout render a sidebar. On standalone routes such as /chat/[agentId]/[conversationId] that left a 250px strip uncovered and still clickable while loading. Gate the offset on .vertical-menu actually being in the document. Co-Authored-By: Claude Opus 5 (1M context) --- src/lib/common/spinners/Loader.svelte | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/lib/common/spinners/Loader.svelte b/src/lib/common/spinners/Loader.svelte index a69eff53..ea3b6c19 100644 --- a/src/lib/common/spinners/Loader.svelte +++ b/src/lib/common/spinners/Loader.svelte @@ -55,8 +55,7 @@