diff --git a/tools/delegate_tool.py b/tools/delegate_tool.py index f6dccb8c68..f250856139 100644 --- a/tools/delegate_tool.py +++ b/tools/delegate_tool.py @@ -1489,13 +1489,9 @@ def delegate_task( # when a runaway tree is detected, without interrupting already-running # children. Cleared via the matching `delegation.pause` RPC. if is_spawn_paused(): - return json.dumps( - { - "error": ( - "Delegation spawning is paused. Clear the pause via the TUI " - "(`p` in /agents) or the `delegation.pause` RPC before retrying." - ) - } + return tool_error( + "Delegation spawning is paused. Clear the pause via the TUI " + "(`p` in /agents) or the `delegation.pause` RPC before retrying." ) # Normalise the top-level role once; per-task overrides re-normalise. diff --git a/ui-tui/src/app/createGatewayEventHandler.ts b/ui-tui/src/app/createGatewayEventHandler.ts index b3ef0d650f..395c2d3acd 100644 --- a/ui-tui/src/app/createGatewayEventHandler.ts +++ b/ui-tui/src/app/createGatewayEventHandler.ts @@ -66,7 +66,12 @@ export function createGatewayEventHandler(ctx: GatewayEventHandlerContext): (ev: return min === 0 ? s.startedAt : Math.min(min, s.startedAt) }, 0) - const top = subagents.filter(s => !s.parentId).slice(0, 2) + // Match buildSubagentTree semantics: an agent is top-level if it has + // no parent OR its parent isn't in the snapshot (orphan). Otherwise + // the disk label would fall back to `${N} subagents` for any turn + // whose roots got pruned mid-flight. + const ids = new Set(subagents.map(s => s.id)) + const top = subagents.filter(s => !s.parentId || !ids.has(s.parentId)).slice(0, 2) const label = top.length ? top