feat: non-blocking background agent delegation (async_delegation toolset) - #8482
feat: non-blocking background agent delegation (async_delegation toolset)#8482iRonin wants to merge 2 commits into
Conversation
|
Related: #9556 proposes a synchronous |
PR #8482 Review: Non-blocking Background Agent Delegation (async_delegation)Reviewer: Gunnar (via Hermes Agent) SummaryThis PR introduces 6 new tools under the
New file: Bugs Found & Fixed🔴 Critical: Missing
|
| Category | Tests | Status |
|---|---|---|
AsyncTask dataclass |
7 | ✅ elapsed, status, done_event |
_get_task_registry |
4 | ✅ creation, idempotency, preservation |
delegate_task_async |
14 | ✅ validation, spawning, errors, completion |
check_task |
9 | ✅ status, preview, unknown task |
collect_task |
10 | ✅ blocking, timeout, already completed |
steer_task |
10 | ✅ queue injection, status checks |
cancel_task |
11 | ✅ interrupt, status, cleanup |
list_tasks |
7 | ✅ empty, multiple, truncation |
| Output truncation | 4 | ✅ _MAX_OUTPUT_LINES=200, _MAX_LINE_CHARS=500 |
| Concurrency | 3 | ✅ registry race, concurrent steer+cancel, multiple tasks |
| Skill loading | 6 | ✅ valid/invalid/empty skill, exception handling |
| Thread lifecycle | 4 | ✅ thread cleanup, _active_children removal |
| Multiple tasks | 3 | ✅ spawn 3, collect individually, cancel one |
| Registry persistence | 4 | ✅ memory leak documentation |
⚠️ Still Missing
- Integration test with real
AIAgent(requires API key) - Merge conflict resolution with main's
delegate_tool.pychanges - ACP transport compatibility (main added
acp_command/acp_argstodelegate_task) - Subagent approval callbacks (main added
_subagent_auto_deny/_subagent_auto_approve)
Compatibility with Main (1,892 commits behind)
Major Changes in delegate_tool.py on main:
- File grew from 1,103 → 2,458 lines (+1,355 lines)
MAX_DEPTHchanged from 2 → 1 with new_get_max_spawn_depth()function- Subagent approval callbacks (
_subagent_auto_deny,_subagent_auto_approve) — prevents TUI deadlocks - Active subagent registry (
_active_subagentsdict,interrupt_subagent(),list_active_subagents()) - File state coordination (new
tools/file_state.pymodule) - Delegate events (
DelegateEventenum for progress callbacks) _extract_output_tail()for error detection in output_get_child_timeout()bumped default to 600s_get_orchestrator_enabled()for nested delegation- MCP toolset inheritance (
_get_inherit_mcp_toolsets())
Merge Strategy
❌ Direct merge is NOT feasible — model_tools.py has a content conflict in the _discover_tools() module list, and delegate_tool.py has diverged too significantly.
✅ Recommended: Rebase onto current main
- Rebase
ironin/async-delegationontoorigin/main - Resolve the single conflict in
model_tools.py(addtools.async_delegate_toolto the import list) - Update
async_delegate_tool.pyto use main's new APIs:- Use
_get_max_spawn_depth()instead of hardcodedMAX_DEPTH - Wire subagent approval callbacks into spawned threads
- Register with
_active_subagentsfor TUI observability - Use
_get_child_timeout()for timeout defaults
- Use
- Consider extracting async delegation into its own module that imports from the refactored
delegate_tool.pyrather than reusing internal functions
Recommendation
🔄 Request Changes — The PR needs a rebase onto current main before it can be merged. The core design is sound and the test coverage is excellent (92 tests), but the 1,892-commit divergence means significant integration work is needed to align with main's delegation infrastructure.
Action Items for Author:
- Rebase onto
origin/main - Adopt
_get_max_spawn_depth()/_get_child_timeout()/ approval callbacks - Register async tasks with
_active_subagentsfor TUI observability - Add task cleanup mechanism (auto-prune old tasks)
- Consider the relationship with [Feature]:
delegate_task_streamwith mid-flight interrupt for synchronous delegation #9556 (streaming delegate primitive) — shared status channel
Files to Include in Merge:
tools/async_delegate_tool.py (new, 681 lines)
tools/delegate_tool.py (modified, +25 lines for _load_skill_for_subagent)
tests/tools/test_async_delegate.py (new, ~1420 lines, 92 tests)
toolsets.py (modified, adds async_delegation toolset)
model_tools.py (modified, adds async_delegate_tool to discovery)
|
Thanks for the substantial async-delegation implementation. This is now redundant with the integrated background lifecycle on current
This is an automated hermes-sweeper review. |
Adds non-blocking background agent execution as agent-callable tools. Unlike
delegate_taskwhich blocks the parent until all children complete, this lets the parent agent spawn long-running background agents and continue working immediately.\n\n### New tools (async_delegation toolset)\n\n| Tool | Description |\n|---|---|\n|delegate_task_async(goal, ...)| Spawn a background agent, returntask_idimmediately |\n|check_task(task_id)| Non-blocking: status + last 10 lines of output |\n|collect_task(task_id, timeout)| Block until done, return full result |\n|steer_task(task_id, message)| Inject steering mid-run |\n|cancel_task(task_id)| Stop a running background agent |\n|list_tasks()| All async tasks for this session |\n\n### Tests\n68 unit tests covering all 6 tools and theAsyncTaskdataclass.\n\nCloses #5586