You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Add non-blocking background agent execution as agent-callable tools. Unlike delegate_task which blocks the parent until all children complete, this lets the parent agent spawn long-running background agents and continue working immediately.
Motivation
delegate_task is synchronous — the parent agent is blocked in a tool call waiting for all subagents. This prevents Hermes from implementing workflows like:
Start a long research/coding agent and do other work while it runs
Run multiple independent agents across turns without waiting
Check in on running agents periodically and steer them
Collect results only when convenient
Proposed tools (new async_delegation toolset)
Tool
Description
delegate_task_async(goal, ...)
Spawn a background agent, return task_id immediately
check_task(task_id)
Non-blocking: status + last 10 lines of output
collect_task(task_id, timeout)
Block until done, return full result
steer_task(task_id, message)
Inject steering mid-run (via _steering_injection)
cancel_task(task_id)
Stop a running background agent
list_tasks()
All async tasks for this session
Example workflow
# Start three research taskst1=delegate_task_async(goal="Research CDAL environmental violations")
t2=delegate_task_async(goal="Find relevant ECSC case law on nuisance")
t3=delegate_task_async(goal="Draft outline for affidavit")
# Check progress while doing other workcheck_task(t1["task_id"]) # → {status: running, output_preview: "..."}# Steer one mid-runsteer_task(t2["task_id"], "Focus on post-2020 cases only")
# Collect when readyresults= [collect_task(t["task_id"]) fortin [t1, t2, t3]]
Design
In-process threads — reuses the existing AIAgent machinery, same credentials/toolsets as delegate_task
Output capture — child's _print_fn redirected to an in-memory ring buffer (200 lines × 500 chars)
Steering — direct _steering_injection queue wiring, same as synchronous subagents
Registry — parent_agent._async_tasks dict keyed by task_id, session-scoped
This is intentionally different from #4949 (Persistent ACP background subagents):
Persistent ACP background subagents #4949 proposes ACP-over-stdio with sandboxed containers and cross-turn persistence — the right long-term architecture for production multi-agent systems
This PR implements in-process threads with no external dependencies — works today, useful for single-session workflows
These are complementary. When #4949 ships, the API could be unified under the same tool names.
Tests
68 unit tests covering all 6 tools and the AsyncTask dataclass. No real LLM calls — all child agents are mocked.
Summary
Add 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.Motivation
delegate_taskis synchronous — the parent agent is blocked in a tool call waiting for all subagents. This prevents Hermes from implementing workflows like:Proposed tools (new
async_delegationtoolset)delegate_task_async(goal, ...)task_idimmediatelycheck_task(task_id)collect_task(task_id, timeout)steer_task(task_id, message)_steering_injection)cancel_task(task_id)list_tasks()Example workflow
Design
AIAgentmachinery, same credentials/toolsets asdelegate_task_print_fnredirected to an in-memory ring buffer (200 lines × 500 chars)_steering_injectionqueue wiring, same as synchronous subagentsparent_agent._async_tasksdict keyed by task_id, session-scopedRelationship to #4949
This is intentionally different from #4949 (Persistent ACP background subagents):
These are complementary. When #4949 ships, the API could be unified under the same tool names.
Tests
68 unit tests covering all 6 tools and the
AsyncTaskdataclass. No real LLM calls — all child agents are mocked.