You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
ai-chat: chat-recovery exhaustion has no terminal-status hydration (disconnected client misses the terminal banner on reconnect) #1645
In @cloudflare/ai-chat, when chat recovery is exhausted, _exhaustChatRecovery delivers the terminal UX only as a transient broadcast (_broadcastChatMessage with done: true, error: true). It does not durably record the terminal status. A client that is disconnected at the moment recovery gives up (e.g. mid deploy-churn / WS reconnect storm — the exact condition under which recovery exhausts) will never see the terminal banner on reconnect, and the turn appears frozen.
@cloudflare/think does not have this gap: its _exhaustChatRecovery additionally calls _recordTerminalChatStatus("interrupted", …), which persists CHAT_LAST_TERMINAL_KEY, and _buildIdleConnectMessages replays that terminal error to a client on (re)connect. ai-chat has no equivalent.
Scope
This affects all ai-chat recovery exhaustion paths (deploy/eviction exhaustion via _handleInternalFiberRecovery, and the stable-state-timeout give-up), not any single path. It is pre-existing.
Where
packages/ai-chat/src/index.ts — _exhaustChatRecovery only broadcasts; no durable terminal record.
Compare packages/think/src/think.ts — _exhaustChatRecovery → _recordTerminalChatStatus("interrupted", …), plus _buildIdleConnectMessages / _pendingTerminalChatResponse for replay on idle connect.
Repro sketch
Start a turn on an ai-chat agent with chatRecovery enabled and a custom terminalMessage.
Drive recovery to exhaustion while the client socket is closed (e.g. simulate deploy churn so the budget drains while disconnected).
Reconnect the client.
Expected: the client receives a terminal error message (the configured terminalMessage) on connect.
Actual: no terminal frame is replayed; the UI shows no resolution for the abandoned turn.
Proposed fix
Give ai-chat a durable last-terminal record analogous to think's: persist the terminal message/requestId in _exhaustChatRecovery and replay it in the agent's on-connect message build, so an exhausted turn surfaces on reconnect rather than freezing.
Context
Spun out of the chat-recovery stable-state-timeout exhaustion fix (which routes the give-up through onExhausted/terminalMessage like deploy/stall exhaustion). During that review we noted ai-chat's weaker terminal hydration is a separate, pre-existing concern and out of scope for that change.
Activity
fix(think,ai-chat): terminalize via onExhausted when recovery gives u…
fix(think,ai-chat): terminalize via onExhausted when recovery gives u…
feat(think,ai-chat): live "recovering…" status to chat clients (#1620)…
fix(think): eagerly clear terminal record on new submit to close reco…
fix(ai-chat): clear terminal record on aborted server-side turns, not…
fix(think): write #1645 terminal record before the submission-row wri…
fix(ai-chat): durably record terminal non-exhaustion errors for recon…
fix(chat): surface terminal recovery outcome to clients that reconnec…
fix(agents): reclaim resumable-stream buffers from an alarm (#1706) (#…
Recovery: e2e + unit coverage, and fix runFiber recovery starvation/b…
fix(agents,ai-chat,think): replay errored-stream content and scope ag…
fix(agents,ai-chat,think): replay errored-stream content and scope ag…
chat-recovery: Phase 0 breadth audit — record verified Phase 2 safety…
chat-recovery: share the exhaustion-notification core (Phase 2, slice…
chat-recovery (slice 4c): centralize the stable-timeout reschedule
chat-recovery (slice 4d-1): lift the give-up spine into the engine
chat-recovery (phase 5 / Tier-2): extract resume-handshake + codec se…
chat-recovery (phase 5 / second harness): TanStack AI client over the…
Chat recovery foundation: a shared, host-agnostic recovery engine for…
rebuild goal stretch 1: ISSUE-018 resolved — #1645 resume semantics
feat(agui): 1b — ResumeHandshake terminal replay in AGUIChatAgent
fix(agui): Phase 1 review fixes — awaited progress credit, repair bef…
test(agui): close Phase 1 review coverage gaps