Skip to content

[Feature]: Decouple post-turn summary display and composer readiness from full server settlement #910

Description

@loveRhythm1990

Is there an existing issue for the same feature?

  • I have checked the existing issues.

Is your feature request related to a problem?

After a turn's visible output finishes streaming, there's a noticeable gap before the post-turn summary band (Xs total · ttft Xs · Xk tokens · ...) appears and the composer is marked ready again. During that gap, users routinely start typing/submitting their next input — the composer doesn't block this (it's accepted as guidance for the still-active run, by design), so this isn't user error, it's the system inviting exactly this.

I traced where the summary is built (crates/astra-cli/src/tui/history_cell/turn_summary.rs, constructed in crates/astra-cli/src/tui/event_loop.rs around the TuiAppEvent::TurnComplete dispatch): all the data it needs (elapsed time, token counts, cache stats, cost) is already known client-side the moment the model's visible output stops — none of it requires an additional LLM call, and building/rendering the summary cell itself is a synchronous, local, effectively-zero-cost operation.

The delay is not from computing the summary. It's that rendering the summary and marking the composer Idle are both gated on the same signal (turn_result resolving from the client's turn-drive future / the TuiAppEvent::TurnComplete dispatch), which only fires once the server-side stream fully terminates. I was not able to confirm from client-side code alone whether the server withholds its terminal signal until it finishes persisting the turn's final durable state, but the architecture (durable, resumable runs backed by checkpoints/leases, discussed at length in #906) makes that plausible, and it would explain a real tail latency independent of anything the summary itself needs.

Whether or not that's the exact mechanism, the observable problem stands: something the user doesn't need to wait for (a cosmetic stats display) is bundled with something that currently does take real time, and the composer accepts input during that window regardless — which is exactly the kind of gap where a user's next submission can race against a run that the server doesn't yet consider settled. #906 documents 409s (session_execution_slot_occupied, durable execution authority expired ...) whose root cause I could not fully confirm either, but this UX gap looks like a plausible contributing factor to how users end up hitting them in practice, not just an isolated cosmetic issue.

Describe the feature you'd like

Worth a discussion, not a prescribed fix: should the post-turn summary display and "composer ready" state be decoupled from whatever signal currently gates them?

Concretely, two separable questions:

  1. Does displaying the stats band need to wait for anything at all, given all its data is already available client-side when the visible output stops? If not, render it immediately.
  2. Separately, should the composer's "ready for next input" state depend on full server-side settlement, or is there a safe way to accept the next input sooner (with the existing guidance-queueing mechanism absorbing the case where the prior run isn't fully settled yet)? If the current coupling exists specifically to avoid the same class of conflict as [Bug]: 409 CONFLICT for durable execution authority expiry has no stable error code #906, that's worth stating explicitly rather than leaving it as an implicit side effect.

Implementation / design notes (optional)

None from me — I don't have visibility into why the current signal is shaped the way it is (whether it's intentional backpressure to avoid #906-style conflicts, or just an artifact of using one event for both concerns). That's the thing worth discussing before anyone proposes a specific change.

Additional information

Related: #906 (409 conflicts from run/lifecycle, same underlying "is this run actually settled yet" question, root cause also not fully confirmed there).

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions