release: clear active_stream_id when chat workflow finishes (#604)

Merged
SW
5mo ago
+270-8

Summary

Releases #604 to main. After the chat-workflow cutover from open-agents โ†’ recoup-api, the workflow set chats.active_stream_id at start but never cleared it on finish. The chat UI's recovery probe (GET /api/sessions/{sessionId}/chats) reads isStreaming from that field, so a stale non-null value kept the AI SDK chat.status stuck in submitted indefinitely and the Send button never reverted from Stop.

Fix moves the clear into the workflow body itself ("use step" in runAgentWorkflow's try/finally), matching open-agents' clearActiveStream pattern in app/workflows/chat-post-finish.ts. CAS-gated on the run's own id so a newer run isn't clobbered; 3 retries at 50ms; no after()/polling lag.

Test plan

  • Unit tests โ€” 3151 โ†’ 3154 passing (+5 clearChatActiveStream cases, +2 runAgentWorkflow cases, +3 delay cases)
  • Manual probe on PR #604's preview deployment (detailed timing comparison in this comment) โ€” isStreaming: false within <1s of stream end (was ~20-30s with the original after() approach)
  • Confirm send button reverts to send after stream completes in the open-agents UI (next test)

๐Ÿค– Generated with Claude Code


Summary by cubic

Clears chats.active_stream_id as soon as a chat workflow ends so the UI stops showing a stuck stream and the Send button returns quickly. Moves the cleanup into the workflow body to avoid after()/polling lag.

  • Bug Fixes
    • Clear inside runAgentWorkflow via try/finally using getWorkflowMetadata().workflowRunId.
    • Compare-and-set on active_stream_id to avoid clobbering newer runs; 3 retries at 50ms.
    • isStreaming flips to false immediately after stream end (no more 20โ€“30s delay).