From 7d0869c7ed9c5a116a0c7165509312a55adb7b49 Mon Sep 17 00:00:00 2001 From: gsxdsm Date: Sat, 25 Apr 2026 11:17:43 -0700 Subject: [PATCH] fix(dashboard): replay buffered planning thinking events on first connect MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The /planning/:sessionId/stream route only replayed buffered events when the client sent a Last-Event-ID (resume case). On a fresh subscription it just attached as a live subscriber. On slower devices (mobile especially), the agent often streamed several thinking deltas into the buffer before the SSE connection finished establishing — so the user saw the spinner sit there, then a question appear out of nowhere, with no streaming "thinking" content. When a session has no current question or summary yet (i.e. the agent is generating its first response) and the client connects without a Last-Event-ID, replay every buffered event before attaching the live subscription. This catches up the user on the in-flight thinking stream. Co-Authored-By: Claude Opus 4.7 (1M context) --- packages/dashboard/src/routes.ts | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/packages/dashboard/src/routes.ts b/packages/dashboard/src/routes.ts index 2f30022ef..34c2d23c2 100644 --- a/packages/dashboard/src/routes.ts +++ b/packages/dashboard/src/routes.ts @@ -9713,6 +9713,18 @@ export function createApiRoutes(store: TaskStore, options?: ServerOptions): Rout } } // Don't return — subscribe to continue receiving events (thinking, next question, etc.) + } else if (lastEventId === undefined) { + // First-connect catch-up for a session that is still generating its + // first response: there is no question or summary yet, but the agent + // may already be streaming thinking deltas into the buffer faster + // than the client could establish the SSE connection. Replay every + // buffered event so the user sees the running thinking output from + // the start of generation, especially on slower mobile connections. + const buffered = planningStreamManager.getBufferedEvents(sessionId, 0); + if (!replayBufferedSSE(res, buffered)) { + res.end(); + return; + } } // Subscribe to session events