Skip to content

v0.8.66: Make sub-agent sidebar refresh read-only and coalesced #3803

Description

@Hmbown

Problem

The TUI requests Op::ListSubAgents after event-drain batches, but the engine handles that op by taking the SubAgentManager write lock, running cleanup, listing agents, and sending an AgentList event. Under fanout/completion bursts, this refresh path contends with completion updates and persistence.

Parent: #3800

Verified evidence

  • crates/tui/src/tui/ui.rs: trailing-edge sub-agent list refresh sends Op::ListSubAgents after drain batches.
  • crates/tui/src/core/engine.rs: Op::ListSubAgents takes self.subagent_manager.write().await, calls cleanup, then list, then awaits tx_event.send(Event::AgentList { ... }).
  • crates/tui/src/tools/subagent/mod.rs: completion handling also takes the manager write lock and updates terminal state.

Desired behavior

Sidebar refresh should be a cheap snapshot read, and cleanup should not run on every UI list request. Multiple refresh requests during a burst should coalesce to one latest-state update.

Suggested implementation options

  • Split ListSubAgents into a read-only snapshot path and a separate periodic cleanup path.
  • Use a read lock for listing where possible.
  • Coalesce pending list requests while one is already queued or in flight.
  • Make AgentList delivery latest-state/convergent rather than one event per trigger.

Acceptance criteria

  • Op::ListSubAgents no longer requires the manager write lock merely to render the sidebar.
  • Cleanup cadence is bounded and not tied to every UI refresh request.
  • Multiple spawn/complete events produce at most one queued/in-flight list refresh at a time.
  • Tests cover concurrent completion updates plus sidebar refresh convergence.
  • The 20-agent release gate in v0.8.66: Release gate for multi sub-agent fanout freeze #3800 shows the sidebar remains alive without starving completions.

Security / policy guardrails

Making sidebar refresh read-only must not weaken lifecycle enforcement:

  • Moving cleanup out of ListSubAgents must be paired with a periodic or event-driven cleanup path so stale children still time out and cancel.
  • A skipped or coalesced sidebar refresh must not affect child cancellation, completion recording, or approval/tool policy.
  • The UI can show a stale marker, but the manager authoritative state must remain consistent and inspectable.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingenhancementNew feature or requestrelease-blockerMust be fixed before the next releasereliabilityReliability, flaky behavior, retries, fallbacks, and robustnesssubagentsSub-agent orchestration, lifecycle, and completion handlingtuiTerminal UI behavior, rendering, or interactionv0.8.66Targeting v0.8.66

    Projects

    Status
    Done

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions