yaab.runner¶
The Runner: executes agents with events, sessions, plugins, and governance.
yaab.runner ¶
The Runner — the orchestration engine for the model-driven fast path.
Runs the ReAct-style loop: call the model, execute any requested tools, feed results back, repeat until a final (optionally typed-and-validated) output. It owns the session/memory/artifact services, the plugin chain, and the optional governance service, and yields a typed event stream.
The Runner is the deterministic seam between the developer API and the engine:
the same loop backs Agent.run and is reused by the graph and optimizer
layers.
Runner ¶
Drives agents; holds services, plugins, and governance.
run_stream
async
¶
run_stream(agent: Any, prompt: str = '', *, deps: Any = None, session_id: str | None = None, identity: str | None = None, state: State | None = None, usage_limits: UsageLimits | None = None, cancellation: CancellationToken | None = None, timeout: float | None = None, resume_id: str | None = None, approval_decision: str | None = None, resume_payload: dict[str, Any] | None = None, _transfer_depth: int = 0, _transfer_cap: int | None = None) -> AsyncIterator[Event]
Execute the loop, yielding a typed :class:Event per step.
When the runner has a run_checkpointer and resume_id is set, loop
progress is persisted after every completed step. A crashed run can then
be resumed by re-invoking with the same resume_id (the captured model
turns are NOT re-requested), and a finished resume_id returns the
persisted result idempotently. Sub-agent handoffs ignore resume_id —
only the root run is checkpointed.
A sensitive tool call guarded for out-of-band sign-off pauses the run
durably: the loop checkpoints a pending-approval marker, emits an
:attr:~yaab.types.EventType.APPROVAL_REQUIRED event, and returns (no
thread is blocked). Re-invoking with the same resume_id and an
approval_decision of "approved" (run the tool now) or "denied"
(feed the model a denial) finishes the loop without re-requesting the
captured model turns. Without a checkpointer the call raises instead —
backward compatible.
_transfer_depth/_transfer_cap are internal: they track how many
sub-agent handoffs deep this run already is (and the root's cap) so a
chain of transfer_to_agent calls can't loop forever. External callers
leave them at their defaults.
stream_run
async
¶
stream_run(agent: Any, prompt: str, *, deps: Any = None, session_id: str | None = None, identity: str | None = None, state: State | None = None, usage_limits: UsageLimits | None = None, cancellation: CancellationToken | None = None, timeout: float | None = None, _transfer_depth: int = 0, _transfer_cap: int | None = None) -> AsyncIterator[Event]
Run the full multi-step loop while streaming token deltas.
Unlike :meth:run_stream (which calls the model with complete and so
only emits whole responses), this drives each turn with model.stream:
text arrives as :attr:EventType.TEXT_DELTA events as it generates,
tools execute mid-run (TOOL_CALL/TOOL_RESULT), and the loop
continues until a final answer — the stream-through-the-tool-loop
behavior. Terminates with FINAL_OUTPUT then RUN_END.
_transfer_depth/_transfer_cap are internal handoff-loop guards
(see :meth:run_stream).
stream_text
async
¶
stream_text(agent: Any, prompt: Any, *, deps: Any = None, session_id: str | None = None, identity: str | None = None) -> AsyncIterator[str]
Token-level streaming for a single answering turn (no tool loop).
Yields text deltas as they arrive from the model. Use this for chat-style
streaming UX; use :meth:run_stream when you need the full tool loop and
semantic events.