Skip to content

feat(desktop): streaming indicator with preparing/streaming/stalled states#3118

Merged
esengine merged 1 commit into
esengine:main-v2from
HUQIANTAO:feat/streaming-indicator
Jun 7, 2026
Merged

feat(desktop): streaming indicator with preparing/streaming/stalled states#3118
esengine merged 1 commit into
esengine:main-v2from
HUQIANTAO:feat/streaming-indicator

Conversation

@HUQIANTAO
Copy link
Copy Markdown
Contributor

Long agent turns sometimes hang in the middle of streaming. Today the user sees a frozen bubble with no signal of what state the request is in.

Add StreamingIndicator: a small inline status line that lives under the in-flight assistant bubble. State machine driven by the message's text length and a 1Hz heartbeat:

  • preparing turn started, no text yet (model warm-up pause)
  • streaming text deltas arrived within the last 6s
  • stalled no deltas for >6s while still streaming
  • error turn_done with e.err (with a Retry button)

A11y: role=status + aria-live=polite so screen readers announce the state transitions.

@github-actions github-actions Bot added the v2 Go rewrite (1.x) — main-v2 branch, active development label Jun 4, 2026
…tates

Long agent turns sometimes hang in the middle of streaming — the
provider accepts the request, sends the first 50 tokens, then nothing
for 30+ seconds while it thinks. Today the user sees a frozen bubble
with no signal of what state the request is in; they have to read the
status-bar spinner to guess.

Add StreamingIndicator: a small inline status line that lives under
the in-flight assistant bubble. It's a state machine driven by the
message's text length and a 1Hz heartbeat:

  preparing   turn started, no text yet
              (model warm-up pause, first few seconds)
  streaming   text deltas arrived within the last 6s
              (the normal happy path)
  stalled     no deltas for >6s while still streaming
              (the model is thinking OR the request dropped;
              the indicator gives the user a clear signal that
              something is happening, not that the app is hung)

The error state (turn_done with e.err) is shown as a separate chip
with a Retry button. The button is currently a no-op stub — the
controller integration needs a ResumeFrom(offset) binding that
re-submits the previous turn's prompt, which is a separate change.
The affordance is rendered so the wiring is a one-line drop-in.

A11y: role=status + aria-live=polite so screen readers announce the
state transitions (a stalled bubble is exactly the kind of event a
screen-reader user would want called out).

prefers-reduced-motion disables the loader spin. The chip re-uses
the existing soft surface / warn / err tokens, so the theme picker
(PR-03) automatically styles it correctly.
@HUQIANTAO HUQIANTAO force-pushed the feat/streaming-indicator branch from 4e8b2ee to cb9c02c Compare June 5, 2026 01:44
@HUQIANTAO HUQIANTAO requested a review from SivanCola as a code owner June 5, 2026 01:44
@esengine esengine merged commit 0f63839 into esengine:main-v2 Jun 7, 2026
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

v2 Go rewrite (1.x) — main-v2 branch, active development

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants