Prebuilt patterns¶
Ready-made graph patterns and node wrappers. See the Prebuilt patterns guide. Quality gates and idempotency helpers have their own reference page.
agentflow.prebuilt
¶
Prebuilt graph patterns built entirely from core primitives.
Tool
dataclass
¶
A callable the model may invoke, plus the schema advertised to it.
fn may be sync or async and is called with the model-supplied argument
dict as keyword arguments. Its return value becomes the tool result
content (stringified for the model).
Source code in agentflow/prebuilt/tool_loop.py
ToolLoopState
¶
Bases: State
Conversation plus loop bookkeeping.
Source code in agentflow/prebuilt/tool_loop.py
Candidate
dataclass
¶
iterate_until_converged
¶
iterate_until_converged(work: Worker, *, perfect_score: float = 100.0, patience: int = 4, max_iterations: int = 20, checkpointer: Any = None)
Compile a loop graph around work.
Stop conditions, in priority order:
- the worker returns
Candidate(done=True)->stop_reason="done" - best score reaches
perfect_score->stop_reason="optimal" - no improvement for
patiencerounds ->stop_reason="converged" max_iterationsreached ->stop_reason="exhausted"
The final state carries best_score, best_payload, stop_reason,
iterations, and history (a list of per-turn scores).
Source code in agentflow/prebuilt/loop.py
with_retry
¶
with_retry(node: Node, *, retries: int = 2, backoff: float = 0.1, backoff_factor: float = 2.0, max_backoff: float = 30.0, on: tuple[type[BaseException], ...] = (Exception,), jitter: float = 0.0) -> Node
Wrap node to retry on failure with exponential backoff.
retriesis the number of additional attempts after the first, so the node runs up toretries + 1times.onselects which exception types trigger a retry; anything else propagates immediately.- :class:
InterruptErroris always excluded, even ifonwould match it, so HITL suspends are never retried. - After the last attempt the final exception is re-raised unchanged.
backoff is the first delay; each retry multiplies it by
backoff_factor up to max_backoff. jitter adds up to that many
seconds of uniform random delay (0 disables it, keeping tests deterministic).
Source code in agentflow/prebuilt/resilience.py
with_timeout
¶
Wrap node so it fails if it runs longer than seconds.
Raises :class:asyncio.TimeoutError on expiry (the runtime wraps it as a
NodeError). An :class:InterruptError still propagates: a suspended
node is not a timeout.