symfonic.capabilities.delegation.values¶
values ¶
The values delegation passes around: entries, plans, outcomes, reports.
Every type here is frozen. A roster entry that could be edited after the graph compiled would let the palette the model was shown and the child that actually runs disagree, and nothing downstream would notice.
ChildBuildPlan
dataclass
¶
ChildBuildPlan(*, name: str, description: str, config: Any, provider: Any, tools: Sequence[Any] = (), when_to_use: str | None = None, shared: dict[str, Any] = dict())
Everything a builder needs, and nothing about how to build it.
The compiler's whole output for one spec. Splitting the decision (this package) from the construction (a builder port at the composition root) is what lets inheritance, sanitisation, and ownership be tested without ever constructing an agent — and what keeps a capability from importing the facade whose children it compiles.
Attributes:
| Name | Type | Description |
|---|---|---|
shared |
dict[str, Any]
|
Wiring the parent hands every child it builds — the memory orchestrator, for instance. A dict rather than named fields because the set is the composition root's business, not this package's: a capability that enumerated the parent's collaborators would be coupled to all of them. |
ChildDefinition
dataclass
¶
The catalogue shape an agent store answers list/read with.
DelegationOutcome ¶
Bases: StrEnum
What happened when the parent's model asked to delegate.
Four values, and only one of them is a delegation. The other three are the reasons the shipped tool returned prose for — depth reached, name unknown, child raised — promoted from strings a caller would have to pattern-match into a value it can branch on. The message stays; what changes is that the message is no longer the only record.
delivered
property
¶
True only for a hand-off a child actually completed.
Read by the recording path: a refused, misrouted, or failed delegation
is not something the parent delegated to, and stamping it on the
response would make an operator reading delegated_to believe a
child ran.
DelegationRecord
dataclass
¶
DelegationRecord(*, name: str, outcome: DelegationOutcome, depth: int, message: str, run_id: str = '', root_run_id: str = '', parent_run_id: str | None = None)
One attempted hand-off, as a value.
Attributes:
| Name | Type | Description |
|---|---|---|
name |
str
|
The routing key the model asked for — kept even when it matched nothing, because "which name did it guess?" is the question an operator asks about an unknown-child outcome. |
depth |
int
|
The depth the child would have run at, whether or not it ran. |
message |
str
|
Exactly what the tool returns to the model. |
RosterEntry
dataclass
¶
RosterEntry(*, name: str, description: str, runner: Any, when_to_use: str | None = None, owned: bool = False)
One registered child: how to reach it, and who owns it.
The declaration form is deliberately not carried here. By the time an entry exists the compiler has already answered every question the two forms differed on, and keeping the spec around would invite a later stage to re-decide inheritance behind the compiler's back.
listing ¶
The one line the parent's model reads for this child.
TeardownReport
dataclass
¶
What a flush or close managed, and what it did not.
clean is derived from :attr:failures rather than set, so there is no
field an unlucky caller can pass to make a teardown that lost a pool look
successful.
merge ¶
Combine two phases of one shutdown into a single report.