feat(steer): cascade steer to active child agents (subagent delegation) - #66548
feat(steer): cascade steer to active child agents (subagent delegation)#66548trac3r00 wants to merge 2 commits into
Conversation
Related to #66046 for live subagent control, but this PR bundles that steer-cascade proposal with a separate CUA action-marker feature. Please split or rebase the independent changes so maintainers can evaluate the delegation behavior separately. |
|
[Bob] Thanks for the review @alt-glitch — good call. I'll split out the CUA action-marker changes into a separate PR and rebase this one to focus solely on the steer-cascade delegation behavior. Will update shortly. |
Verifies across CLI and gateway/TUI frontends: (1) One-shot dispatch sets pending seed, MoA provider swap, disable flag (2) Normal mode leaves all MoA state untouched (3) Invalid inputs (bare, whitespace) show usage with no side effects (4) Restore path clears all MoA continuation state after one-shot Documents that CLI /moa lacks agent-running guard (gateway has one). Part of: feat/moa-one-shot-routing
When a user sends a mid-turn steer (/steer or busy_input_mode=steer), the message now propagates to all active child agents via _active_children, not just the parent agent. This mirrors the existing interrupt() cascade pattern (line 2686-2692). Previously, steers only reached the parent agent's _pending_steer slot. If the parent was blocked waiting on a delegate_task subagent, the steer would not be delivered until after the subagent completed — making it effectively useless for redirecting subagent work. Now child.steer(text) is called for each active child, so the subagent model sees the user's correction in its next tool result via the OOB marker. Cascade is recursive (grandchildren get it too) and fault- tolerant (a broken child doesn't block others). Tests: 4 new tests in TestSteerCascadeToChildren covering direct cascade, recursive propagation, broken-child tolerance, and no-children baseline.
55d3bcf to
961809f
Compare
961809f to
83b084d
Compare
teknium1
left a comment
There was a problem hiding this comment.
Thanks for the focused steer-cascade implementation. The underlying gap is present on current main: run_agent.py:2864-2877 stores /steer only on the parent, while tools/delegate_tool.py:1392-1399 registers live children for the delegation lifetime.
Problems
- This PR still includes unrelated MoA tests from
fa5480a47f08(tests/cli/test_moa_one_shot_behavior.pyandtests/tui_gateway/test_moa_one_shot_behavior.py, 398 lines). The member review requested that independent changes be split; the CUA portion was moved to #66618, but this MoA-only commit remains here.
Suggested changes
- Move the MoA test commit to the MoA-focused work and retain only the steer cascade and its focused tests (
83b084d006d6).
Automated hermes-sweeper review.
| @@ -0,0 +1,260 @@ | |||
| """Tests for /moa one-shot behavior: dispatch, no-continuation-state, invalid input. | |||
There was a problem hiding this comment.
This new MoA-only test file is unrelated to the steer cascade. The prior member review requested splitting independent changes; please move this commit's MoA coverage to the MoA-focused work so this PR remains reviewable as the delegation change.
|
Thanks for this — the gap was real (steer didn't cascade to children the way interrupt does). The steer-delivery slice just landed via #76805, which adds a targeted |
[Bob] Propagate user mid-turn steers to active subagents.
Problem
When a user sends a steer while a subagent is running via delegate_task, the steer only reaches the parent agent. The parent is blocked waiting on the subagent, so the steer doesn't get delivered until after the subagent completes — making it useless for redirecting subagent work.
Solution
Mirror the existing interrupt() cascade pattern: when steer() is called on the parent, iterate _active_children under lock and call child.steer(cleaned) on each. The child's next tool result will include the OOB marker with the user's message.
Changes
Testing
All 39 steer-related tests pass.