Skip to content

symfonic.agent.facade_types

facade_types

Value types of the simple Agent facade (T2.1.1 RES-/EVT-).

These are deliberately new types rather than reuses of AgentResponse and StreamChunk. Nine of AgentResponse's fifteen fields (memory_entries_used, graph_edges, activation_log, …) are capability columns that are permanently empty on the stateless path, and StreamChunk's event taxonomy includes consolidating and spreading_activation. Shipping either would be exactly the inactive-feature surface story S2.1 exists to remove. The legacy types are untouched and stay on SymfonicAgent.

Every model is frozen — the repo's existing convention for public value types.

AgentEvent

Bases: BaseModel

One event of an Agent.stream() (EVT-1…EVT-10).

A projection of the same invocation the non-streaming path runs — not a second pipeline. Field population per kind:

============== =================================================== kind populated fields ============== =================================================== thinking text (reasoning delta) text_delta text (answer delta) tool_call tool_call with result/error both None tool_result tool_call with result or error set done result error error cancelled (none) ask_user interrupt interrupt interrupt stage stage, and stage.counts where it counted ============== ===================================================

stage is what a capability's execution reported: which stage ran, in which phase, for which capability, with what outcome and why. It shares the dense index with everything else, so a consumer can place a retrieval against the round it fed. It carries counts and never contents -- see :class:StageRecord.

AgentResult

Bases: BaseModel, Generic[OutputT]

The result of one Agent.run() (RES-1…RES-8).

text is never None — a run that produced no text yields "". AgentResponse.final_response's None-vs-"" tri-state has no meaning a caller can act on and forces a null check on the happiest path.

messages is the whole turn in order and is designed to be fed straight back as the next call's history; that round trip is how a stateless agent takes a second turn.

CapabilityConfig

Bases: Protocol

Marker protocol for the API-ADR A5 optional-behavior seam (FAC-7).

Optional behavior attaches by passing a typed configuration object, and absence means disabled — there are no boolean feature flags on the facade, ever. W1 registers zero capabilities, so the parameter exists solely so the first real capability is an additive change rather than a signature change.

Message

Bases: BaseModel

One typed conversation message (RES-2).

content is text. Attachments are deliberately not replayed through history — the catalogued rule is that they do not participate in hydration or routing, so a round trip through history is lossless for text and documented-lossy for attachments.

PendingInterrupt

Bases: BaseModel

A run that stopped to ask a person, as the facade publishes it (HK1).

The facade's own value, built by the response port from the kernel's symfonic.kernel.contracts.interrupts.PendingInterrupt -- the same seam ToolCall sits on. The kernel value is a stdlib dataclass every layer may name; this one is what an adopter holds.

resumable is the field to read before building a reply UI. TA8.34 mints the pause and publishes it and nothing in this build redeems one on the kernel route; resume is TA8.35. A pause that says False is a real pause -- the run has stopped -- whose token no resume endpoint on this route will accept yet.

RecoveredContinuation dataclass

RecoveredContinuation(prompt: str, history: tuple[Message, ...], session_id: str, paused_run_id: str, root_run_id: str)

Trusted host-recovery input for :meth:Agent.continue_recovered.

A host constructs this only after it has authenticated a pause token, verified its recovered scope, claimed the token, and restored the paused turn. It is an immutable in-process composition value, not authentication: callers must never accept it from an external request as authority. Its lineage labels correlate an already-authorized recovery; they never select a scope or grant permission to recover one.

StageRecord

Bases: BaseModel

One capability stage execution, as a consumer sees it.

Counts, never contents. counts is a mapping of name to integer and the kernel refuses anything else, because this record reaches the public event stream, an operator's screen and durable storage at once. How many memories a turn recalled is publishable to all three; the memories are not, and a field that could hold one would hand it to every consumer with no way to opt out.

outcome distinguishes the two zeroes that matter: no-change with found=0 is a stage that ran and found nothing, and no record at all is a stage that never ran.

TokenUsage

Bases: BaseModel

What the provider reported (RES-4).

0 means "unreported", not "free": the facade never estimates token counts, so a provider that reports nothing leaves the zero value.

ToolCall

Bases: BaseModel

One tool invocation and its outcome (RES-3).

On a completed run exactly one of result / error is non-None. Both are None only on the in-flight tool_call stream event, which is what makes id the join key to the matching tool_result.