Skip to content

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.