-
Notifications
You must be signed in to change notification settings - Fork 363
Description
Problem
When a page is refreshed during an active stream that includes reasoning/thinking (e.g., OpenAI o-series or GPT models with thinking enabled), the "thinking" state is lost after reconnect. The text response continues correctly via stream resumption, but reasoning parts are no longer visible.
Root cause
_sendStreamChunks replays all stored chunks synchronously in a tight loop:
for (const chunk of chunks || []) {
connection.send(JSON.stringify({...}));
}On the client, each chunk triggers a setMessages call. React batches all these state updates and only renders the final state. By that time, reasoning-end has already been processed, so reasoning parts have state: 'done' and are never visible to the user — even though the model may still be actively thinking.
During the original stream this isn't an issue because chunks arrive gradually (as the LLM generates tokens), giving React time to render intermediate states like "Thinking...".
Secondary issue
There's also a race condition between onConnect (which sends CF_AGENT_STREAM_RESUMING) and the useEffect in useAgentChat that registers the message handler. If the WebSocket connects before the handler is registered, the notification is lost and stream resumption doesn't happen at all.
Suggested fix directions
- Expose a "replaying" flag so the client knows chunks are being replayed and can preserve intermediate states
- Send chunks with microtask yields between them so React can render intermediate states
- For the race condition: have the client request stream resumption after the handler is ready, rather than relying solely on the server pushing it in
onConnect