symfonic.agent.subagents¶
subagents ¶
Sub-agent delegation primitive.
Declare child agents a parent can delegate to via run_agent(name, task):
from symfonic.agent.subagents import SubAgent
parent = SymfonicAgent(
model_provider=provider,
config=FrameworkConfig(),
sub_agents=[
SubAgent(name="researcher", agent=research_agent,
description="Deep web research"),
],
)
Declaring sub_agents auto-registers a concrete AgentStore plus the
run_agent / list_agents tools before the graph compiles. Children are
isolated agents that inherit the parent's tenant scope and run under a
depth guard (max_agent_depth).
SubAgent
dataclass
¶
A named child agent the parent may delegate to.
Attributes:
| Name | Type | Description |
|---|---|---|
name |
str
|
Unique routing key the parent's model passes to
|
agent |
_Runnable
|
The child agent — any object exposing |
description |
str
|
One-line summary shown to the parent model in the
|
when_to_use |
str | None
|
Optional longer guidance appended to the roster listing. |
SubAgentRegistry ¶
Concrete AgentStore that runs registered child agents in-process.
Satisfies the AgentStore protocol (list / read / run). The
run method inherits the parent's tenant scope into the child and
threads the (already incremented) agent depth so the child's own
delegation guard can enforce max_agent_depth for nested delegation.
Source code in src/symfonic/agent/subagents/registry.py
run
async
¶
run(
name: str,
agent_input: Any,
*,
parent_scope: Any = None,
agent_depth: int = 1,
run_id: str | None = None,
) -> Any
Run child name on agent_input; returns its AgentResponse.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
Registered sub-agent name. |
required |
agent_input
|
Any
|
The delegated task (coerced to |
required |
parent_scope
|
Any
|
Tenant scope inherited from the parent run. |
None
|
agent_depth
|
int
|
Depth to stamp on the child run (parent depth + 1). |
1
|
run_id
|
str | None
|
Optional correlation id passed to the child. |
None
|
Raises:
| Type | Description |
|---|---|
StorageError
|
If |
Source code in src/symfonic/agent/subagents/registry.py
SubAgentSpec
dataclass
¶
SubAgentSpec(
name: str,
description: str,
when_to_use: str | None = None,
tools: Sequence[Any] = tuple(),
domain_description: str | None = None,
model_name: str | None = None,
temperature: float | None = None,
max_tokens: int | None = None,
provider: Any | None = None,
config: Any | None = None,
)
A declarative sub-agent: describe the child, let the parent build it.
v9.1.0 (issue #27). SubAgent requires a fully pre-constructed child
agent; SubAgentSpec closes that ergonomics gap -- you declare what
the child should be and the parent constructs the inner SymfonicAgent
at wiring time, inheriting the parent's :class:ModelProvider (#26A) and
base :class:FrameworkConfig via :meth:FrameworkConfig.child (#28). Pass
either form in SymfonicAgent(sub_agents=[...]); mix freely.
The child is an isolated agent with its own fresh domain (scoped to
name/domain_description) so its tool manifest auto-derives from its
own tools rather than leaking the parent's. Every behaviour flag
(auto_hydrate, lazy_tooling, enable_hms_prompt, ...) is inherited from the
parent unless a full config is supplied. For a child that needs shared
backends or bespoke wiring, build it yourself and use SubAgent(agent=...)
as the escape hatch.
Attributes:
| Name | Type | Description |
|---|---|---|
name |
str
|
Unique routing key the parent's model passes to
|
description |
str
|
One-line summary shown to the parent model in the
|
when_to_use |
str | None
|
Optional longer guidance appended to the roster listing. |
tools |
Sequence[Any]
|
Tools the child agent gets (its manifest auto-derives from them). |
domain_description |
str | None
|
Optional child |
model_name |
str | None
|
Optional child model override; inherits the parent model. |
temperature |
float | None
|
Optional child sampling temperature override. |
max_tokens |
int | None
|
Optional child max-output-tokens override. |
provider |
Any | None
|
Optional :class: |
config |
Any | None
|
Optional full :class: |