From d79c748c4deb14e2e926d271a278b75f851f82e8 Mon Sep 17 00:00:00 2001 From: ajnart Date: Thu, 20 Aug 2026 14:50:00 +0200 Subject: [PATCH] fix: clean up assistant transient sessions --- .../components/assistant/assistant-panel.tsx | 17 +++++++++++++++-- .../assistant/assistant-runtime-provider.tsx | 15 ++++++++++++--- 2 files changed, 27 insertions(+), 5 deletions(-) diff --git a/apps/nextjs/src/components/assistant/assistant-panel.tsx b/apps/nextjs/src/components/assistant/assistant-panel.tsx index a9f0f02eb..cbf4400ca 100644 --- a/apps/nextjs/src/components/assistant/assistant-panel.tsx +++ b/apps/nextjs/src/components/assistant/assistant-panel.tsx @@ -3331,8 +3331,20 @@ export const AssistantPanel = ({ onReasoningChange, }: AssistantPanelProps) => { const t = useScopedI18n("common.assistant"); + const aui = useAui(); const previousFocusRef = useRef(null); const panelRef = useRef(null); + const stopVoiceActivityWithoutSurface = () => { + if (hasVisibleWidget) return; + const composer = aui.composer(); + if (composer.getState().dictation !== undefined) composer.stopDictation(); + const thread = aui.thread(); + if (thread.getState().speech !== undefined) thread.stopSpeaking(); + }; + const minimize = () => { + stopVoiceActivityWithoutSurface(); + onClose(); + }; useWindowEvent("keydown", (event) => { if ( @@ -3344,7 +3356,7 @@ export const AssistantPanel = ({ ) return; event.preventDefault(); - onClose(); + minimize(); }); useEffect(() => { if (!opened) { @@ -3394,8 +3406,9 @@ export const AssistantPanel = ({ onModelChange={onModelChange} onReasoningChange={onReasoningChange} autoFocusComposer - onMinimize={onClose} + onMinimize={minimize} onDismiss={() => { + stopVoiceActivityWithoutSurface(); onDismissActivity(); onClose(); }} diff --git a/apps/nextjs/src/components/assistant/assistant-runtime-provider.tsx b/apps/nextjs/src/components/assistant/assistant-runtime-provider.tsx index 807fab16c..e108e395e 100644 --- a/apps/nextjs/src/components/assistant/assistant-runtime-provider.tsx +++ b/apps/nextjs/src/components/assistant/assistant-runtime-provider.tsx @@ -42,6 +42,7 @@ class AssistantSurfaceComposerRuntimeCore extends INTERNAL.DefaultThreadComposer } public dispose() { + if (this.dictation !== undefined) this.stopDictation(); composerConnectionDisposers.get(this)?.(); composerConnectionDisposers.delete(this); } @@ -294,18 +295,22 @@ export const createAssistantSurfaceRuntime = (runtime: AssistantRuntime): Assist subscribe(callback) { let activeCore = sharedBinding.getState(); let activeConversationId = getConversationId(); + let activeComposer = getComposer(activeConversationId, activeCore); retainConversation(activeConversationId); - let unsubscribeComposer = getComposer(activeConversationId, activeCore).subscribe(callback); + let unsubscribeComposer = activeComposer.subscribe(callback); const handleSharedUpdate = () => { const nextCore = sharedBinding.getState(); const nextConversationId = getConversationId(); if (nextCore !== activeCore || nextConversationId !== activeConversationId) { + if (activeComposer.dictation !== undefined) activeComposer.stopDictation(); + if (activeCore.speech !== undefined) activeCore.stopSpeaking(); unsubscribeComposer(); releaseConversation(activeConversationId); activeCore = nextCore; activeConversationId = nextConversationId; retainConversation(activeConversationId); - unsubscribeComposer = getComposer(activeConversationId, activeCore).subscribe(callback); + activeComposer = getComposer(activeConversationId, activeCore); + unsubscribeComposer = activeComposer.subscribe(callback); } callback(); }; @@ -360,6 +365,10 @@ export const createAssistantSurfaceRuntime = (runtime: AssistantRuntime): Assist registerModelContextProvider: () => () => {}, dispose() { activeConversationCounts.clear(); + const threadCores = new Set(Array.from(surfaceCoreByConversation.values(), (entry) => entry.source)); + for (const threadCore of threadCores) { + if (threadCore.speech !== undefined) threadCore.stopSpeaking(); + } for (const [conversationId, entry] of composerByConversation) disposeComposer(conversationId, entry); }, }; @@ -509,7 +518,6 @@ export const AssistantComposerSurfaceBoundary = ({ children, surfaceId }: PropsW }} onPasteCapture={handlePasteCapture} > - {children} @@ -588,6 +596,7 @@ export const AssistantComposerRuntimeProvider = ({ children }: PropsWithChildren return ( + {children} );