fix(chat): prevent stalled turns from hanging and show activity status#40
Merged
Conversation
The prior #38 fix covered silent *drops* (error parts, empty completions) but not silent *stalls*: compaction ran before the abort controller existed and its summarizer call had no abort signal or timeout, so a slow/stalled summarize (easy once a large tool result pushed history past the 24KB threshold) froze the turn with the Stop button dead and only a mute skeleton showing. There was also no idle timeout anywhere on the main stream. - compaction is now abortable: the abort controller is created before it and its signal is passed to the summarizer generateText; on abort it rethrows (so the turn stops) instead of failing open, while non-abort errors still fail open - idle watchdog: re-armed on every fullStream part and around compaction; on expiry it aborts the turn and surfaces a recoverable timeout error instead of an endless spinner. Generous default (90s), overridable via sessionStorage for tests - activity indicator: an `activity` phase (compacting/thinking/analyzing) is exposed from the composable and threaded to AgentChatMessages, which replaces the two ambiguous skeletons with one discreet muted label line (null while text streams) - compaction summary prompt + recap framing reworked to keep the continuation context actionable (open task/next step, verbatim ids/indices/paths/URLs) - mock "stall" seam + chat-hang e2e covering the indicator and the timeout Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
albanm
added a commit
that referenced
this pull request
Jun 21, 2026
…ssage While text streams there was no in-progress signal: renderStreamingMarkdown rendered no cursor and #40 removed the discreet 'receiving more' skeleton, setting activity=null during text. Append an inline blinking caret to the streamed markdown (before the last leaf block closer so it sits inline at the true end of the text), removed once the turn settles. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Prevent chat turns from hanging when the stream stalls or compaction can't be cancelled, and replace the ambiguous loading skeleton with a discreet activity indicator.
Why: conversations kept getting "stuck" with a mute spinner — most often around compaction in long sessions (e.g. an evaluator pulling large trace entries). The earlier #38 fix covered silent drops; this covers silent stalls, which it never touched.
activityrefHeads-up: during active text streaming there is no longer a skeleton — progress relies on the markdown streaming cursor. And the 90s watchdog will abort a turn that produces no bytes for that long.