Agent chat: the live line says what the turn does, and its time reads as the turn's total
Leo, 2026-11-03: "i think the "thinking" accounting is also off pretty frequently", with a capture of the agent pane reading Thinking 1h 24m 7s.
What the timer was measuring
The running turn's live line (conversation/Thinking.tsx, built by turns.ts codexLiveTurn) has one clock: the turn's wall time since the prompt. Its label said "Thinking" whenever no call was in flight and no step could be held on the line. In the session behind the capture, one turn ran about 1.5 h, and almost all of it was the parent waiting on foreground subagents: the turn's last row was the subagent group, which names no call, so the line fell back to "Thinking" with the whole turn's time. It read as a 1.5 h think, and as hung.
The same clock sat beside a finished step the line holds between calls. An "Opened 1 agent session" step read 1h 22m 31s, though its app_agent_open_tab call ran about 3.5 min (05:50:56 to 05:54:23Z).
A third sample, "Thinking 7m 34s · ↓ 4.5K out ↑ 1.4M in": 7.5 min of "thinking" for 4.5K output tokens. The time was the turn's wall clock, so every call, wait and queue between the thoughts counted as thinking.
The folded thought's "Thought for X" was already right: it counts only the thought's own first to last chunk (thoughts.ts thoughtDuration), so this change leaves it alone.
Change
- The label names what the turn does now. With no call in flight:
- foreground subagents still running in the turn: Waiting on 3 subagents, counted from the turn's subagent groups (background ones outlive the turn, so they are no wait);
- a reply that paused for under 5 s: Writing;
- else Thinking, as before: a quiet model still reads Thinking (Leo, 2026-11-03, on "No response from the model yet"). Past the first step the time beside it is only the turn's thinking, the summed spans its thoughts streamed:
Thinking 8s · 7m 34s total. - A call in flight still names the call ("Running bun test"), and an ask still says "Waiting for you: …" (unchanged).
- The time says whose it is. Past the turn's first step the turn's clock reads as the total:
Waiting on 3 subagents · 1h 24m 7s total. A finished step on the line shows its own start-to-end time first:Opened 1 agent session 3m 27s · 1h 22m 31s total. A running call shows only the total (Running bun test · 4m total): the line's one ticking clock is still the turn's and never restarts at a call (Leo, 2026-11-01: "it should just keep going";transcript-live-line-continuous-browserchecks it every frame); it is only labelled. - Before the turn's first output nothing changes:
Thinking 18s. - With the running tray off, the line no longer counts the subagents a second time after naming them.
- Strings:
turn.live.waitingOnSubagents(plural),turn.live.writing,turn.live.total, every app language.
Files: conversation/turns.ts, conversation/Thinking.tsx, model.ts (four row fields), App.tsx (ThinkingRow passes and compares them), Localizable.xcstrings.
Gallery
New entry agent-pane.long-subagent-wait (LongSubagentWait.gallery.ts): waiting-on-subagents (a 1h 24m turn with three running subagents), finished-step (a 3m 27s step held on the line), writing.
Tests
webviews/test/transcript-live-line-state.test.tsx, focused command cd webviews && bun test test/transcript-live-line-state.test.tsx, on fast checks (Linux):
| base (0ca06467) | this head | |
|---|---|---|
| subagent wait reads Waiting on 2 subagents · 1h 24m 7s total | fail | pass |
| background and finished subagents are no wait | fail | pass |
| finished step reads its own time, not the turn's | fail | pass |
| paused reply reads Writing | fail | pass |
| Thinking shows the summed thought spans, the rest goes to the total (added after this table's base run) | fail | pass |
| gallery entry's line | fail | pass |
| before the first output: Thinking 18s | pass | pass |
Also run with it: transcript-codex-live-line, transcript-live-line-below, transcript-running-live-line, transcript-working-line, agent-pane-working-counts, transcript-live-line-row-classes and every test under src/agent-session/acpmux/conversation/ (94 files). Three of them fail identically on base 0ca06467 and here (one running call reads once…, a running call whose group the reader closed…, the live line draws Running or Ran…), so they are base reds. bun run check: fmt, lint and type check pass on the changed files; check:design-tokens is red on base for cloudStart.css, which this change does not touch.
Observed / Not run
Observed: the red/green table above and the related suites on fast checks (job d8874748fdc54e00c4367ca4 for base vs head; the final head's run is linked in a comment). Not run: a tagged Mac build or a live acpmux session; the subagent-wait state is exercised through turnView and the gallery entry's rows. No capture: webview-only change, the gallery entry shows the states.
agent-pane-working-counts (browser) now expects the busy line's turn time as · N total.
Follow-ups (from the review): the summed thinking time grows only as thought chunks arrive, so a long silent think can read "Thinking 8s · 7m total"; a todo-list turn (Debug agent.sessionStatus) still names the plan's step while it waits on subagents; tests for a steer turn with a subagent group before the steer.
Changelog
- Fixed: a running agent turn's status line says what it is doing (waiting on subagents, writing, a call) instead of "Thinking" for the whole turn, and its time reads as the turn's total.
Agent session: agent session
🤖 Generated with Claude Code