Browse Source

fix: trigger syncInterview on session idle to push final state to browser

Root cause: when confirm-complete (or chat message) finishes, the agent
writes the final spec without <interview_state> block. sessionBusy gets
set to false via session.status event, but handleEvent never called
syncInterview — so onStateChange never fired, and the browser stayed
stuck on 'Agent Thinking' until manual refresh.

Fix: in handleEvent's session.status handler, detect busy→idle
transition and fire-and-forget syncInterview for the active interview.
This triggers onStateChange → SSE broadcast → browser auto-updates.
bobbyunknown 1 month ago
parent
commit
ff08185b1c
1 changed files with 14 additions and 0 deletions
  1. 14 0
      src/interview/service.ts

+ 14 - 0
src/interview/service.ts

@@ -631,7 +631,21 @@ export function createInterviewService(
       const sessionID = properties.sessionID as string | undefined;
       const status = properties.status as { type?: string } | undefined;
       if (sessionID) {
+        const wasBusy = sessionBusy.get(sessionID) === true;
         sessionBusy.set(sessionID, status?.type === 'busy');
+
+        // When session transitions from busy → idle, sync state so the
+        // browser gets the final push (e.g. after confirm-complete or
+        // chat message processing). Without this, the browser stays
+        // stuck on "Agent Thinking" because no poll triggers syncInterview.
+        if (wasBusy && status?.type !== 'busy') {
+          const activeId = activeInterviewIds.get(sessionID);
+          const interview = activeId ? interviewsById.get(activeId) : null;
+          if (interview && interview.status === 'active') {
+            // Fire-and-forget — syncInterview pushes state via onStateChange
+            syncInterview(interview).catch(() => {});
+          }
+        }
       }
       return;
     }