2a26693e22
delegate_task gains a control plane: action='list' / 'steer' / 'stop' let the parent agent see, redirect, and early-stop its own running subagents mid-flight — the model-facing counterpart of the TUI's delegation.pause / subagent.interrupt / subagent.steer RPCs. - action='list': live children of this conversation's spawn tree (ids, goal, status, running_seconds, accepting_steer, live transcript path). Ownership is enforced via a _delegate_parent_ref weakref chain stamped at child build time, so a conversation can only control its own descendants, never a sibling tree. - action='steer': queues text into a running child via the existing steer_subagent() registry path (delivered at the child's next tool boundary; missed steers surface as missed_steer in the completion). - action='stop': interrupt_subagent() — child stops at its next iteration boundary, partial result still re-enters as a completion. - Spawn dispatch response now includes subagent_ids + control hint. - Control actions run synchronously (never backgrounded) and bypass the spawn pause gate and depth limit; they also never consume the per-turn subagent spawn cap, and remain usable once the cap is hit (that is when stop matters most). - Small-model robustness (found live with gpt-5.4-mini on Nous Portal): tasks=[] alongside goal no longer trips the "Batch mode requires at least 2 tasks" gate — treated as single-goal. - CLI display: control calls render as "steer sa-…" / "list" instead of an empty goal. Live-tested E2E on Nous Portal (fable-5 + gpt-5.4-mini): full spawn→list→steer→stop cycle, plus a steer-efficacy run where the child acked the steer mid-essay and switched topics before finishing.