Agents and graphs
An Agent is a pure orchestrator: it validates input, walks a graph of
nodes according to explicit routing, validates output, and returns an
AgentResponse. Business logic lives in nodes, never in the agent itself.
AgentMessage → validate InputContract → resolve AgentSettings
→ router-guided node traversal → error handling (retry/fallback/circuit breaker)
→ validate OutputContract → AgentResponse
Node types
| Type | Class | Purpose |
|---|---|---|
| LLM | LLMNode |
Invokes an LLMCallable with tool loops, prompt assembly, streaming |
| Function | FunctionNode |
Deterministic Python logic, no LLM |
| Delegation | DelegationNode |
Delegates to another agent via a DelegationTransport |
| Aggregator | AggregatorNode |
Fan-in: collects delegation responses (all/any/majority policies) |
| Planner | PlannerNode |
LLM generates a DAG execution plan; PlanExecutor runs it |
All nodes subclass BaseNode and implement async _run(). BaseNode.execute()
validates input/output against the node's NodeContract around your logic.
Routing
Routing decides which node runs next, based on the previous node's output.
Built-in strategies (sofias_sdk_lite.routing):
StaticRoute— always the same target (used byadd_edge)FieldValueStrategy— route on a field's valueFieldPresenceStrategy— route on whether a field is present/truthyConditionalStrategy— a custom callable decidesConfidenceThresholdStrategy— route on a numeric thresholdCompositeStrategy— try several strategies in order, first match winsFanOutStrategy— dispatch to multiple nodes in parallel, join at anAggregatorNodeor merge point
from sofias_sdk_lite import FieldValueStrategy
builder.add_route(
"classifier",
FieldValueStrategy(field="category", mapping={"billing": "billing_agent", "other": "fallback"}),
)
Contracts
Every node and the agent itself has an InputContract/OutputContract pair
(a NodeContract/AgentContract). Contracts extend StrictContract
(extra="ignore" — unknown fields are silently dropped, not rejected;
strict=True — no implicit type coercion).
Building
AgentBuilder is a fluent builder. Nothing runs until .build(), which
validates the whole graph up front — a missing entry node, an unrouted node,
or a mismatched contract raises AgentBuildError listing every problem, not
just the first one.
Error handling
ErrorHandler (in sofias_sdk_lite.errors) wraps every node execution with
retry (configurable backoff), a circuit breaker (per-node, in-memory by
default), and fallback routing. See Errors and retries.