Agent chat: a turn's tokens split into output and input, its time and tokens quieter

Merged
TE
8d ago
+902-35

Leo (2026-10-21): "shouldnt the token text and maybe time tho be less prominent? darker? also i think usually anthropic talks about output instead of read tokens... but its ok if we show both, we just ought to split it up"

Follows #23996 (merged), which added tests for the quieter token count, and builds on #25118 (merged), which made the turn count output only.

What changes

  • The running line reads "Thinking 3m 27s · ↓ 12.4K out ↑ 3.9M in". Output comes first, and "out" is #25118's output-only count (turnTokens); output is never folded into one total with what the model read. "in" is everything the model read: fresh input plus cache reads plus cache writes. Hovering the count shows each part ("Output 12.4K · fresh input 18K · cache reads 2.1M · cache writes 42K").
  • The time and the tokens use the tertiary text token (--cv-text-dim) with tabular numerals. That covers the time beside "Thinking" or a running call, and the time inside "Working for 35s" and "Worked for 1m 16s". "Thinking" and the other words keep their color.
  • A finished turn's "Worked for" line (when it is the turn's only one: not a steered turn, nor one folded into several stretches), and its footer when the turn isn't folded, show that turn's tokens the same way. The numbers come from its turn_result (outputTokens, inputTokens, cacheReadTokens, cacheWriteTokens, acpmux hub/turn_usage.rs, Claude Code's main loop).
  • The split reuses the counts acpmux already sends on each marked Claude call since #25118 (inputTokens, cachedReadTokens, cachedWriteTokens, outputTokens beside used, claude_stdio/inbound.rs); acpmux sends nothing new. The pane (direct.ts) adds the read side up per turn beside the output count.
  • Fallbacks:
    • If any call in the turn arrives without its input and output counts (an older acpmux), the split goes away and the line shows the output alone, "2.1M out" (turn.working.outputTokens), so it never shows a split that leaves calls out.
    • Codex and other harnesses report no per-call usage, so they still show the time alone.
  • "out" and "in" and the hover text are localized in all 21 pane languages (turn.tokens.out, turn.tokens.in, turn.tokens.detail). Non-English strings are marked needs_review.

Tests

  • test/agent-pane-turn-tokens.test.tsx:
    • The count stays output only while the split adds up what the calls read.
    • A call without the counts clears the split and adds no output.
    • #25118's five-step output-only test still holds.
    • The turn_result tokens reach the summary row.
  • test/agent-pane-turn-token-split.test.tsx:
    • Markup for both live lines and for Worked for.
    • The hover text.
    • The time sits in the quieter span.
    • The CSS rule uses the tertiary token.
  • cmux-tui/.../context_window.rs: the streamed call's used is 4200 (#25118) and it carries input 1200, cache reads 3000, cache writes 0, output 300.
  • Gallery: agent-pane.transcript gets working-tokens (split), working-tokens-total (fallback, "2.1M out") and worked-tokens (finished turn).

Before / after

Gallery agent-pane.transcript, synthetic fixtures with Reduce Motion on. Before is feat-cmux-next's live gallery; after is this branch.

BeforeAfter
Running line, darkbeforeafter
Running line, lightbeforeafter
Worked for, darkbeforeafter
Worked for, lightafter

Computed colors in the dark theme: words rgb(170,170,170); time and tokens rgb(136,136,136). Light theme: words rgb(97,97,97); time and tokens rgb(127,128,128). Hover text in the after state: "Output 12.4K · fresh input 18K · cache reads 2.1M · cache writes 42K". The before Worked for has no tokens and its time is in the words' color ("Worked for 1m").

Changelog

Changed: The agent chat's turn line shows output and input tokens separately, with the time and token counts in a quieter color.

Observed / Not run

  • Ran: the gallery screenshots above, with colors computed in headless Chromium; rustfmt, vp fmt, the browser-lane import check, the xcstrings duplicate-key check, and gen-strings.mjs.
  • On Linux fast checks at the current head: bun test for agent-pane-turn-tokens, agent-pane-turn-token-split, transcript-codex-live-line and agent-pane-turn-tokens-muted (47 pass), the vp check typecheck, vp fmt and vp lint on the touched files, the xcstrings key check, and cargo test -p acpmux --test hub_integration context_window, clippy with -D warnings and rustfmt.
  • The screenshots were taken before the base update; the fallback line now reads "2.1M out" rather than "2.1M tokens".

Agent session: agent session

🤖 Generated with Claude Code