Skip to content

TUI: cycled tool display with compact Worked-for summaries by default - #682

Closed
alejandro-ao wants to merge 7 commits into
mainfrom
tui-tool-display-cycle
Closed

TUI: cycled tool display with compact Worked-for summaries by default#682
alejandro-ao wants to merge 7 commits into
mainfrom
tui-tool-display-cycle

Conversation

@alejandro-ao

Copy link
Copy Markdown
Collaborator

Description

Reworks tool activity rendering in the TUI around a three-way display cycle and a new compact default.

Ctrl+O now cycles three modes (announced in a toast):

  1. Summary (new default) — while the agent works, tool rows render as live compact call lines; when the turn settles, each contiguous burst representing two or more calls compacts into one line such as Worked for 1m 23s · 5 tool calls (failures counted, e.g. · 1 failed; bursts left pending after a cancel show Running… 2/5 tool calls). Thinking blocks and tool-driven skill loads interleaved with a summarized burst are swallowed into its line and skill loads count toward the call total. A single tool call keeps its own row.
  2. Calls — the previous default: one compact line per call or grouped batch, without result contents.
  3. Expanded — call lines plus exact commands and result previews.

The line renders in the tool status color (green on success, red on failures, neutral while pending). Starting a new turn expands the rows again; cycling is available at any time, including mid-turn.

User-experience improvement

Long turns no longer bury the narrative under dozens of tool rows: the default transcript shows one green line per burst of work ("Worked for 1m 23s · 5 tool calls"), with full call/results detail still one Ctrl+O press away. Terminal ! commands, extension-rendered tool cards, and user-invoked skill rows never collapse.

Implementation notes

  • TuiState.tool_display (summary | calls | expanded) replaces show_tool_results (kept as a property mapping to expanded, so per-row rendering call sites are unchanged); cycle_tool_display() advances the mode.
  • Tool rows record finished_at (started_at is no longer cleared on completion; batch pending detection uses tool_result_text); restored sessions set a _restoring flag so no timing is invented and summaries fall back to call counts.
  • TranscriptView owns collapse rendering via _display_rows() (hidden-thinking-placeholder pattern); member→summary-widget mappings let live update_item calls recompute the summary line in place. Turn boundaries (AgentStartEvent / AgentEndEvent / AgentSettledEvent) drive the expand/compact rebuilds.
  • Custom-rendered tools, always_show_tool_result rows, and user-invoked skills are exempt from collapsing.

Manual validation

  • uv run pytest tests — 1866 passed, 2 skipped
  • uv run ruff check . / uv run ruff format --check . — clean
  • uv run mypy — clean
  • Interactive: run the TUI, submit a prompt that uses several tools, observe live call rows during the turn and green Worked for … summaries after; press Ctrl+O to cycle summary → calls → expanded.

Ctrl+O now cycles three modes instead of toggling two states:

- summary: each contiguous burst of tool rows collapses into one line
  ("Worked for 1m 23s · 5 tool calls", with live "Running… 2/5 tool
  calls" progress while tools execute); terminal ! commands and
  extension-rendered tool cards never collapse
- calls: the previous default compact per-call lines
- expanded: call lines plus exact commands and result previews

TuiState.tool_display replaces show_tool_results (kept as a property
mapping to expanded) and cycle_tool_display() advances the mode. Tool
rows now record finished_at (started_at is no longer cleared on
completion; restored sessions set _restoring so no invented timing).
TranscriptView collapses runs via _display_rows and keeps per-member
mappings so live updates recompute the summary line in place; entering
or leaving summary mode rebuilds the window while calls/expanded still
update rows without remounting.
Summary mode now mirrors the request flow instead of collapsing live:
while the agent works, tool rows render as compact call lines so
progress stays visible; when the turn settles (AgentEndEvent or
AgentSettledEvent), the window rebuilds with each completed run
compacted into its "Worked for ... · N tool calls" line. Starting the
next turn expands the rows again. Ctrl+O still cycles summary / calls /
expanded at any time.

TranscriptView._collapsing() gates run collapsing on state.running, and
the app rebuilds the mounted transcript window at turn boundaries.
A run representing exactly one call renders as its own compact call
row in summary mode instead of a "Worked for ... · 1 tool call" line;
only runs of two or more calls (counting batch/group members via
tool_run_leaves) compact. When a second call arrives while idle, the
existing single row is replaced in place by a run summary.
The collapsed Worked-for line now renders fully in the theme tool
success color with a green left border, matching tool rows. Runs
containing failures render red, and pending runs keep the neutral
accent. The synthetic summary item carries a check/cross/ellipsis
status marker plus a tool_run_summary flag so the plain-body renderer
can style the whole line instead of only the invocation segment.
In summary mode, thinking blocks interleaved with a multi-call tool run
are folded into the run's summary line instead of rendering as their
own rows (even when thinking tokens are toggled on). Standalone
thinking stays under Ctrl+T control, and single-call runs keep both
their row and adjacent thinking. tool_run_leaves now counts only
tool-role members so thinking items do not inflate call counts or
trigger the pending state.
Skill load rows (role skill backed by a tool call id) interleaved with
a collapsed tool burst now fold into its Worked-for summary line and
count toward the call total, since they are re-labeled reads.
User-invoked skill rows keep their own place in the transcript. Items
mapped to a run summary are no longer re-rendered through the per-row
update path.
TuiState.tool_display now starts at summary, so tool activity collapses
into Worked-for lines (with swallowed thinking and skill loads) unless
the user cycles Ctrl+O to calls or expanded. Tests that exercise
per-row rendering pin the calls mode through a _set_tool_display_mode
helper that also lets Textual settle the async removal of replaced
widgets before identity-sensitive queries.
@alejandro-ao alejandro-ao added the bug Something isn't working label Sep 5, 2026
@alejandro-ao

Copy link
Copy Markdown
Collaborator Author

Defective — closed without merge

Closed at the maintainer's request following isolated-worktree review of 3dc3e2c.

Reproduced defects:

  • P2: Mixed batches report success while grouped reads remain pending (src/tau_coding/tui/state.py:439). Determine completion from grouped leaves rather than aggregate result text.
  • P2: Restored grouped calls invent elapsed durations (src/tau_coding/tui/state.py:429). Apply the restoration timing guard to grouped members.
  • P3: Pending summaries render success green (src/tau_coding/tui/widgets.py:1728–1735). Use neutral styling for pending status.

Validation: full suite 1865 passed, 3 skipped; TUI suite 399 passed; Ruff lint/format, mypy, and diff whitespace checks passed. Existing tests do not cover these reproduced defects.

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

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant