Summary
The TUI stops rendering and responding to input while a multi-agent workflow is active. Separate from #509 (cap counting) — that one is logic the model can work around. This one is fatal: the user can't see what's happening, can't cancel, can't type. Once the agent fan-out hits a few children, the UI freezes.
Repro
Multi-agent workflow: spawn 5 exploration agents → as each completes, spawn 5 implementation agents in parallel. Around the time the cap is being approached or contested, the TUI stops drawing and stops accepting input.
Suspect: shared mutex on the manager
crates/tui/src/tools/subagent/mod.rs:1195:
pub type SharedSubAgentManager = Arc<Mutex<SubAgentManager>>;
Every sub-agent operation (spawn, cancel, result, running_count, mailbox bookkeeping, status updates) takes the same global lock. The agent loop, the renderer, the mailbox pump, and N children all contend on it; the renderer starves.
The mailbox uses its own Arc<Mutex<...>> (mailbox.rs:265), compounding the contention.
Fix direction
- Convert
SharedSubAgentManager to Arc<RwLock<...>>. Most callers are read-mostly.
- Audit
manager.lock() call sites — many likely keep the guard alive across await points or tokio::spawn. Drop the guard before awaiting.
- Move sub-agent state-change notifications to a dedicated channel so the renderer doesn't have to acquire the lock to observe progress.
Severity
High — makes the multi-agent workflow effectively unusable on real tasks.
Related
Summary
The TUI stops rendering and responding to input while a multi-agent workflow is active. Separate from #509 (cap counting) — that one is logic the model can work around. This one is fatal: the user can't see what's happening, can't cancel, can't type. Once the agent fan-out hits a few children, the UI freezes.
Repro
Multi-agent workflow: spawn 5 exploration agents → as each completes, spawn 5 implementation agents in parallel. Around the time the cap is being approached or contested, the TUI stops drawing and stops accepting input.
Suspect: shared mutex on the manager
crates/tui/src/tools/subagent/mod.rs:1195:Every sub-agent operation (
spawn,cancel,result,running_count, mailbox bookkeeping, status updates) takes the same global lock. The agent loop, the renderer, the mailbox pump, and N children all contend on it; the renderer starves.The mailbox uses its own
Arc<Mutex<...>>(mailbox.rs:265), compounding the contention.Fix direction
SharedSubAgentManagertoArc<RwLock<...>>. Most callers are read-mostly.manager.lock()call sites — many likely keep the guard alive acrossawaitpoints ortokio::spawn. Drop the guard before awaiting.Severity
High — makes the multi-agent workflow effectively unusable on real tasks.
Related
:51Ztimestamp fragments persist across cells when scrolling (regression of v0.8.5 fix) #400 — earlier UI-thread off-loading work.