Skip to content

yaab.graph

Durable StateGraph orchestration: checkpoints, channels, HITL.

yaab.graph

Durable graph orchestration.

MemorySaver

In-memory checkpointer; keeps full history for time-travel debugging.

PostgresSaver

Durable checkpointer backed by Postgres / Aurora PostgreSQL.

Uses psycopg (pip install 'yaab-sdk[postgres]'), imported lazily. Stores the framed checkpoint blob per (thread_id, step) — point the DSN at an Aurora endpoint for a managed, HA checkpoint store.

RedisSaver

Durable checkpointer backed by Redis / ElastiCache / MemoryDB.

Uses redis (pip install 'yaab-sdk[redis]'), imported lazily. Each step is a base64 blob in a per-thread Redis hash, so the full history (and time-travel) survives across processes.

SQLiteSaver

Durable checkpointer backed by SQLite.

Channel

Declares how writes to a state key are reduced.

reducer is one of "last_value" (overwrite), "append" (accumulate into a list), or "add" (numeric sum) — matching the Rust reducer in :mod:yaab._core.

CompiledGraph

An executable graph with checkpointing and HITL resume.

GraphContext

Per-invocation context handed to each node as its second argument.

interrupt

interrupt(value: Any) -> Any

Pause for human input, or return the resumed value on continuation.

On the first pass this raises :class:Interrupt; the runtime checkpoints and surfaces value to the caller. When the caller resumes the thread, the same call returns the supplied resume value.

GraphResult

Bases: BaseModel

The outcome of a graph invocation.

RetryPolicy

Bases: BaseModel

Per-node retry policy with exponential backoff.

A node that raises a matching exception is re-run up to max_attempts times, waiting backoff * backoff_multiplier**(attempt-1) seconds before each retry.

retry_on is a tuple of exception types — only matching errors retry, so a deterministic bug (the wrong TypeError) can still surface fast instead of burning the whole budget. Note that :class:~yaab.exceptions.Interrupt is control flow, not an error: the engine handles it before consulting this policy, so an interrupt is never retried even when retry_on is the default (Exception,) (and Interrupt is an Exception).

backoff_for

backoff_for(attempt: int) -> float

Return the backoff (seconds) to wait before retrying attempt.

attempt is 1-indexed: attempt == 1 is the wait after the first failure (the first retry), so the exponent is attempt - 1.

sleep async

sleep(attempt: int) -> None

Sleep the computed backoff for attempt (async, cancellation-safe).

Routed through :func:asyncio.sleep so tests can monkeypatch it and so a cancelling caller can interrupt the wait between retries.

StateGraph

Builder for a stateful, durable graph.

add_node

add_node(name: str, fn: NodeFn, *, retry: RetryPolicy | None = None) -> StateGraph

Register a node, optionally with a :class:RetryPolicy.

Without retry the node aborts the run on its first exception (the historical behavior); with one, matching transient failures are retried with backoff before the error is allowed to propagate.

compile

compile(checkpointer: Checkpointer | None = None, *, engine: str = 'auto') -> CompiledGraph

Compile the graph to an executable form.

engine selects how a superstep's state is advanced:

  • "python" — the Python engine (applies node updates sequentially);
  • "rust" — offload the whole-superstep state fold to yaab-core (requires the compiled extension; raises if unavailable);
  • "auto" — use Rust when the extension is present, else Python.

Both engines produce identical results; the Rust engine reduces an entire superstep in one native call (one cross-language hop per superstep instead of one per key).

interrupt

interrupt(ctx: GraphContext, value: Any) -> Any

Module-level alias for :meth:GraphContext.interrupt.