Fix freebuff grace-period hang where UI looks stuck streaming#518
Fix freebuff grace-period hang where UI looks stuck streaming#518
Conversation
Two separate hang vectors after a freebuff session ends mid-run: 1. `handleFreebuffGateError` for session_expired/waiting_room_required only flipped session state — it never finalized the in-flight AI message. Result: `isComplete` stayed false, the streaming cursor kept rendering, and the batched-updater flush interval leaked. Users saw an apparently still-streaming message next to the rejoin banner, assumed the agent was working, and waited indefinitely. Now calls `updater.markComplete()` so the message visibly finalizes. 2. If the agent was mid-`ask_user` when the session ended, the SessionEndedBanner replaced the ChatInputBar and hid the answer form, leaving the agent waiting on input that could never arrive. Chat.tsx now lets ask_user take precedence over the banner (same pattern as review mode) so in-flight runs can still finish during grace. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Greptile SummaryThis PR fixes two distinct UI hang scenarios that occur when a freebuff session ends mid-agent-run. The changes are minimal, well-scoped, and follow existing patterns in the codebase. Key changes:
Confidence Score: 5/5Safe to merge — two tightly-scoped bug fixes with no regressions introduced. Both changes are minimal one-liners targeting clearly identified hang paths. They follow existing, well-tested patterns ( No files require special attention. Important Files Changed
Sequence DiagramsequenceDiagram
participant Agent as Agent (server)
participant SM as send-message.ts
participant Updater as BatchedMessageUpdater
participant Store as ChatStore
participant UI as chat.tsx
Agent->>SM: session_expired / waiting_room_required error
SM->>SM: handleFreebuffGateError()
SM->>Updater: markComplete() NEW
Note over Updater: flush() → dispose() → isComplete=true
Updater->>Store: message.isComplete = true
Store->>UI: streaming cursor stops
SM->>Store: markFreebuffSessionEnded()
Store->>UI: isFreebuffSessionOver = true
alt askUserState is active (ask_user mid-flight)
UI->>UI: show ChatInputBar (MultipleChoiceForm) NEW
Note over UI: banner suppressed via !askUserState guard
UI->>SM: user submits answer
SM->>Store: askUserState = null
UI->>UI: show SessionEndedBanner
else no pending ask_user
UI->>UI: show SessionEndedBanner immediately
end
Reviews (1): Last reviewed commit: "Fix freebuff grace-period hang where UI ..." | Re-trigger Greptile |
Summary
Two separate hang vectors after a freebuff session ends mid-run, both reported as "task keeps running then just hangs, only option is to close the terminal":
handleFreebuffGateErrornever finalized the AI message. For `session_expired`/`waiting_room_required`, the handler only flipped session state, leaving `isComplete: false` on the in-flight message. The streaming cursor kept rendering and the batched-updater flush interval leaked — users saw an apparently still-streaming message next to the rejoin banner and waited indefinitely. Now calls `updater.markComplete()`.Test plan
🤖 Generated with Claude Code