fix(chat): clear active_stream_id when chat workflow finishes
Summary
- Adds
clearChatActiveStreamWhenWorkflowFinishes()helper + 4 unit tests - Wires it into
handleChatWorkflowStreamvia Next.jsafter()so the post-stream cleanup runs without blocking the SSE response - Uses CAS (
expected = run.runId,next = null) so a newer run that already claimed the slot is never clobbered
Why
handleChatWorkflowStream sets chats.active_stream_id when it starts the workflow but never clears it afterward. The chat UI's recovery probe (GET /api/sessions/{sessionId}/chats) reports isStreaming based on active_stream_id !== null, so a stale non-null value tells the open-agents stream-recovery hook to call chat.resumeStream() forever — which keeps the AI SDK chat.status stuck in submitted / streaming. The send button never returns and the user can't submit a follow-up.
The bug only surfaced after the chat-cutover from open-agents to recoup-api (recoupable/open-agents#43) — before the cutover, open-agents' own workflow handler had similar cleanup logic.
Test plan
-
pnpm test -- --run lib/chat/__tests__/clearChatActiveStreamWhenWorkflowFinishes.test.ts— 4/4 pass (3148/3148 total) -
pnpm lint:check— no new lint errors -
tsc --noEmit— no new type errors - Manual: send a message in chat, confirm send button returns after the stream completes and a follow-up can be sent
🤖 Generated with Claude Code
Summary by cubic
Clears chats.active_stream_id when a chat workflow finishes to stop endless stream recovery. This fixes the stuck “submitted/streaming” status so the send button returns and follow-ups work.
-
Bug Fixes
- Added
clearChatActiveStream(chatId, runId)as a workflow "use step" that CAS-clears tonullwith 3 retries (50ms delay), preserving newer runs. - Calls it in
runAgentWorkflow(viatry/finallyandgetWorkflowMetadata().workflowRunId) so cleanup runs immediately on success, failure, or cancel; removed the handlerafter()approach. - New tests cover the step’s retry/race behavior and verify
runAgentWorkflowtriggers cleanup on both success and error paths.
- Added
-
Refactors
- Extracted
delay(ms)tolib/time/delaywith unit tests; used byclearChatActiveStream’s retry loop.
- Extracted
Summary by CodeRabbit
Release Notes
- Bug Fixes
- Improved chat stream state cleanup with automatic retry mechanism (up to 3 attempts) to gracefully handle transient failures without disrupting user sessions.
- Enhanced workflow execution error handling to ensure cleanup operations always complete, even when unexpected errors occur during workflow steps.