Skip to content

TUI: improve readability of delegated / multi-agent execution #3104

@aheritier

Description

@aheritier

Summary

When root delegates to a sub-agent and waits, the TUI is ambiguous about who is working, who is waiting, and how many agents are in flight — and it gets worse when multiple agents are involved. This issue groups a set of focused, independently-shippable improvements (see the linked phase issues).

Background: two delegation mechanisms that render very differently

  1. transfer_task (synchronous "forwarding")LocalRuntime.runForwarding (pkg/runtime/agent_delegation.go) with SwitchCurrentAgent: true. The parent loop is blocked while the child runs; child events are forwarded inline into the same transcript. Multiple transfer_task calls in one assistant turn run sequentially (Dispatcher.Process iterates calls in order, pkg/runtime/toolexec/dispatcher.go).
  2. run_background_agent (asynchronous "collecting")RunAgentrunCollecting (pkg/runtime/agent_delegation.go) with NonInteractive + PinAgent, up to 20 concurrent. Child events are dropped; only the final result is collected. The human sees nothing live except the initial "task started" tool call and any later view_background_agent polls the model chooses to make.

Concrete readability gaps

  • The waiting spinner is anonymous — no "who's working / who's waiting" label (pkg/tui/components/message/message.go, MessageTypeSpinner renders a bare spinner.View(); added via setPendingResponse in pkg/tui/page/chat/chat.go).
  • The transfer_task card hardcodes a green ✓ regardless of status (pkg/tui/components/tool/transfertask/transfertask.go uses styles.ToolCompletedIcon unconditionally), so an in-progress delegation looks finished.
  • The transcript is flat: chatPage.streamDepth is tracked but used only to balance spinner/cancel state, never to group or label sub-agent output.
  • SubSessionCompletedEvent is emitted by the runtime but not handled by the TUI (no references under pkg/tui/).
  • Background-agent tools have no dedicated renderer (run/list/view/stop_background_agent fall through to the default tool renderer) and the sidebar tracks only one working agent (pkg/tui/components/sidebar/sidebar.go).

Proposed phases

Open questions

  • Which path matters most to users — blocking transfer_task or concurrent run_background_agent?
  • Appetite for depth-based indentation (high blast radius) vs. labeled brackets + a sidebar breadcrumb?
  • Is it acceptable to add coarse runtime lifecycle events for background agents, or must the UI rely only on the model's view_background_agent polling?
  • Default-on vs. a userconfig toggle (and behavior in --exec / lean mode)?

Metadata

Metadata

Assignees

Labels

area/agentFor work that has to do with the general agent loop/agentic features of the apparea/tuiFor features/issues/fixes related to the TUIkind/featPR adds a new feature (maps to feat: commit prefix)
No fields configured for Enhancement.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions