Super-step execution engine inspired by Google's Pregel.
Processes the graph in discrete super-steps: resolve which nodes to run next, execute them, apply state updates via reducers, then repeat until reaching the END node or exhausting the recursion limit.
Supports checkpointing, interrupts (dynamic and static breakpoints),
streaming events, runtime context, Send fan-out, and managed values
(remaining_steps, is_last_step, and the remaining_ms /
remaining_tokens run budgets).
Interrupt model
Every LangEx.Interrupt.interrupt/1 call gets a stable ID derived from
the node name and the call order within the node ("node:0", "node:1").
Resume values are keyed by interrupt ID, so a node can interrupt multiple
times across resume cycles, and several nodes interrupting in the same
parallel super-step each keep their own pending entry. Completed sibling
results in a parallel super-step are merged into state before pausing,
and their resolved next targets are recorded in the checkpoint — nothing
is lost when one branch interrupts.
Error model
Node exceptions (after the node's retry policy, if any, is exhausted)
surface as {:error, %LangEx.NodeError{}} rather than raising out of
the run. Programmer errors — routing to an undefined node, a missing
conditional mapping — still raise.
Summary
Functions
Runs the compiled graph from the start node through to completion.
Types
@type entry() :: atom() | LangEx.Send.t()
@type run_opts() :: %{ optional(:start_nodes) => [entry()] | nil, optional(:parent_id) => String.t() | nil, optional(:bypass_breakpoints) => boolean(), optional(:resume_values) => %{required(String.t()) => term()}, optional(:raw_interrupts) => boolean(), optional(:max_concurrency) => pos_integer() | nil, optional(:node_timeout) => timeout() | nil, optional(:store) => {module(), keyword()} | nil, optional(:deferred_backlog) => [entry()], optional(:completed_next) => [entry()], optional(:durability) => :sync | :async | :exit, optional(:deadline) => integer() | nil, optional(:token_budget) => pos_integer() | nil, recursion_limit: pos_integer(), checkpointer: module() | nil, config: keyword(), context: term(), resume: %{nodes: [entry()], values: %{required(String.t()) => term()}} | nil, step: non_neg_integer(), emit_to: pid() | nil }
Functions
@spec run(LangEx.Graph.Compiled.t(), map(), run_opts() | pos_integer()) :: {:ok, map()} | {:interrupt, term(), map()} | {:error, term()}
Runs the compiled graph from the start node through to completion.