From 6ef44c6689343de333e1b68a99d6670f8fdfc416 Mon Sep 17 00:00:00 2001 From: David Kaya Date: Mon, 13 Apr 2026 14:14:25 +0200 Subject: [PATCH] fix: prevent premature Quick Prompt completion from setup events MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The session emits completion signals (agent-activity:completed, message-complete, status:idle) during initialization before any response content arrives. These early events were incorrectly transitioning the popup to 'complete' phase, causing the Nothing → In Progress → Nothing cycling pattern. Track whether response content has been received via a ref and only transition to 'complete' when hasContentRef is true. This ensures setup/init completion events are ignored and the popup stays in streaming until actual content has arrived and a terminal event follows. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../quick-prompt/QuickPromptApp.tsx | 23 ++++++++++++++----- 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/src/renderer/components/quick-prompt/QuickPromptApp.tsx b/src/renderer/components/quick-prompt/QuickPromptApp.tsx index 4781d16..0f5a26f 100644 --- a/src/renderer/components/quick-prompt/QuickPromptApp.tsx +++ b/src/renderer/components/quick-prompt/QuickPromptApp.tsx @@ -33,6 +33,9 @@ export function QuickPromptApp() { const [visible, setVisible] = useState(false); const sessionIdRef = useRef(null); + // Track whether we've received any response content (non-thinking) so we + // don't prematurely treat setup/init events as the final completion signal. + const hasContentRef = useRef(false); const api = window.quickPromptApi; // Load capabilities on mount @@ -70,6 +73,7 @@ export function QuickPromptApp() { if (event.messageKind === 'thinking') { setResponse((prev) => ({ ...prev, thinkingContent: prev.thinkingContent + event.contentDelta! })); } else { + hasContentRef.current = true; setResponse((prev) => ({ ...prev, content: prev.content + event.contentDelta!, @@ -77,12 +81,17 @@ export function QuickPromptApp() { })); } setPhase('streaming'); - } else if (event.kind === 'message-complete') { - setPhase('complete'); - } else if (event.kind === 'status' && event.status === 'idle') { - setPhase((prev) => (prev === 'idle' || prev === 'complete' ? prev : 'complete')); - } else if (event.kind === 'agent-activity' && event.activityType === 'completed') { - setPhase((prev) => (prev === 'idle' || prev === 'complete' ? prev : 'complete')); + } else if ( + event.kind === 'message-complete' || + (event.kind === 'status' && event.status === 'idle') || + (event.kind === 'agent-activity' && event.activityType === 'completed') + ) { + // Only transition to "complete" once we've received actual response + // content. The session may emit completion events from initialisation + // or setup runs before the real content-generating turn starts. + if (hasContentRef.current) { + setPhase('complete'); + } } else if (event.kind === 'error') { setErrorMessage(event.error ?? 'An unexpected error occurred.'); setPhase('error'); @@ -96,6 +105,7 @@ export function QuickPromptApp() { setResponse({ content: '', thinkingContent: '', authorName: '' }); setErrorMessage(undefined); sessionIdRef.current = null; + hasContentRef.current = false; // Refresh capabilities in case models changed api.getCapabilities().then((caps) => { setCapabilities(caps); @@ -110,6 +120,7 @@ export function QuickPromptApp() { setPhase('streaming'); setResponse({ content: '', thinkingContent: '', authorName: '' }); setErrorMessage(undefined); + hasContentRef.current = false; try { const result = await api.send({