symfonic.capabilities.tools.execution.executor¶
executor ¶
The tool executor — the lifecycle nothing else owns (T3.1.3).
Individual phases can each answer one question. Only the executor can answer these:
- order — preconditions, then steering, then dispatch, stated as a method you can read rather than as the order three modules happen to be called in;
- the calls-in-equals-results-out invariant — every call yields
exactly one :class:
ToolOutcome, whichever phase produced it, because an unansweredtool_useblock permanently bricks a provider thread; - retry accounting — attempts belong to the call, not to the tool;
- containment — a raising tool becomes an error outcome the model can read and recover from, while a cancellation propagates, because a cancelled run must not be kept alive one more hop by a ToolMessage.
Dispatch is injected as a callable. The executor therefore needs no graph, no provider and no tool object, and the suite drives the whole lifecycle with lambdas.
ToolExecutor ¶
ToolExecutor(*, preconditions: PreconditionSet | None = None, steering: SteeringGate | None = None, retries: RetrySchedule | None = None, progress: ProgressSink | None = None)
Run a batch of tool calls through the lifecycle, in order.