Add SubAgent capability for agent-to-agent task delegation#178
Conversation
Implements the Agent-as-Tool pattern: a parent agent can delegate tasks to named sub-agents via a `delegate_task` tool that blocks until the sub-agent finishes and returns its text output as the tool result. Refs #32 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Pydantic AI uses asyncio.gather in capabilities/combined.py which is incompatible with the Trio event loop. Override the anyio_backend fixture to asyncio-only, switch from pytest-asyncio to pytest-anyio, and update the lock file. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Implements the three audit findings for SubAgent:
- `share_history: bool = False` parameter: when True, passes the parent's
message history (minus pending tool calls) to sub-agent runs via
`message_history`, giving sub-agents full conversation context.
- `delegate_tasks` tool for parallel delegation: accepts a list of
`{"agent": "name", "task": "prompt"}` dicts and runs them concurrently
via `asyncio.gather`, returning results in input order.
- Structured output preservation: sub-agent outputs that are Pydantic
models get `model_dump_json()`, dicts/lists get `json.dumps()`, and
other non-str types get `repr()` instead of generic `str()`.
Also widens `agents` dict type from `Agent[Any]` to `Agent[Any, Any]`
to accept sub-agents with any output type.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Note: Sub-agent runs are currently opaque (parent sees only final text result). Real-time progress streaming from sub-agents to the parent's event stream requires #146 (sub-agent event propagation). |
Audit vs prior art: SubAgentWorth adding now:
Follow-up opportunities:
|
Recursion prevention -- there's nothing stopping a sub-agent from having its own Concurrency limits -- Timeouts / turn limits -- a hung sub-agent blocks the parent forever. Hermes uses an iteration budget (default 50). Mastra passes Tool filtering -- hermes intersects child toolsets with the parent's and strips dangerous tools ( Result metadata -- we return a single string. Hermes returns JSON with Streaming / progress -- all three (hermes, pi, mastra) stream intermediate progress from sub-agents. We're opaque until completion. Not a blocker but worth tracking. |
Summary
SubAgentcapability (AbstractCapabilitysubclass) that lets a parent agent delegate tasks to named sub-agents via adelegate_tasktoolagent.description,agent.name, or explicitdescriptionsdict)pass_deps=True), configurableModelRetryfor self-correctionCloses #32
Test plan
AbstractCapability, descriptions resolve from agent metadata or explicit overrides, empty agents returns None for instructions/toolsetdelegate_tasktool is registered with agent names in descriptionpass_deps=True, deps are None whenpass_deps=False, multiple agents called sequentiallySubAgentimportable frompydantic_harnesspackage🤖 Generated with Claude Code