feat(ui): turn-scoped thinking indicator with live reasoning readout#11
Merged
Conversation
Surface what a model turn is doing — the feature the full-screen rework was for. On submit the app echoes the user's message, then a live 'frontier' line renders as the last transcript row: ✈·· cruising… 38s · 1.8k reasoning The plane glides, the phrase advances through flight phases, the timer ticks, and the reasoning-token estimate climbs while the model is thinking. Completed tool calls and responses append above the line, so it moves down the transcript as work finishes, and the auto-following pane keeps it in view. At turn end it freezes to a permanent record: ✓ done · 38s · 1.8k reasoning · 2.4k total The timer and phrase span the WHOLE turn — started once at the first model call and never reset per tool call (unlike the old per-call spinner). Only turn_finished freezes it. The reasoning figure is a chars/4 estimate (no tokenizer); the done line's total is the exact summed output-token count from the turn stats. The readout is gated on [ui] show_reasoning_summary (default on; off → plane/phrase/timer only), which until now was dead config. Animation rides the Application's refresh_interval; the indicator render bypasses the width cache while active. A dangling indicator from an errored turn is discarded at the next turn's start so it never poisons the following timer (full turn-failure UX is a later branch). Only AppUI gains this; the default TerminalUI REPL is unchanged. DESIGN.md §31.14 added.
lavindeep
added a commit
that referenced
this pull request
Jul 2, 2026
feat(ui): turn-scoped thinking indicator with live reasoning readout
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.
Branch 5/9 — the flagship of the UI v2 rework. Surfaces what a model turn is doing (the rework was motivated by cloud reasoning models running ~80 min invisible).
What
On submit the app echoes
❯ <message>, then a live frontier line renders as the last transcript row:✈·· cruising… 38s · 1.8k reasoning— plane glides, phrase advances through flight phases, timer ticks, reasoning-token estimate climbs while the model thinks. Completed tool calls/responses append above it, so it moves down as work finishes (and the auto-following pane keeps it visible). At turn end it freezes to a permanent record:✓ done · 38s · 1.8k reasoning · 2.4k total.turn_finishedfreezes it.total= exact summedoutput_tokensfrom turn stats; elapsed from the runtime's authoritativestats.elapsed_s.[ui] show_reasoning_summary(default on; off → plane/phrase/timer only) — previously dead config, now consumed at both AppUI construction sites.Application(refresh_interval=0.1); the indicator render bypasses the width cache while active. A dangling indicator from an errored turn is discarded at the next turn's start so it never poisons the following timer (full turn-failure UX → branch 6).Verification
mypy --strict, 1357 passed.begin_responseto restart, orend_responseto clear → continuity tests red-fail). The cross-turn-poisoning fix (Opus catch) is also red-first tested.TerminalUIREPL byte-identical;stream_thinkingstays a no-op there. DESIGN §31.14 in the same commit.