Skip to main content

Two Entry Points

Both surfaces produce a WorkflowGraph and support .run(input).

The Primitives

Sequential

Chain steps β€” output flows forward:

Branch (predicate routing)

Route based on output:

Loop (while-do)

Exit condition checked before body:

Loop (do-while / repeatUntilOutput)

Body runs first, exit condition reads actual output:

Gather (homogeneous fan-out)

Run steps concurrently, collect all results into a List<Object> that becomes the input to the next step. Use when all branches produce the same type and downstream needs everything together:
Chain directly into a join step:

Parallel (enrichment fan-out)

Run steps concurrently; the join passes the fork input through unchanged. Each branch writes its output to a named context key (Steps.outputOf(branchName)). Use when branches produce different types and downstream reads from context:

Parallel (dynamic fan-out)

Fan-out determined at runtime:

Decision (LLM-routed)

LLM picks which step to run:

Gate (quality checkpoint)

Approve, reject, or retry with feedback:
On failure, the full Verdict (score, reasoning, per-judge judgments) is written to AgentContext under JUDGE_VERDICT for the retry step to consume.

Supervisor (autonomous delegation)

LLM picks sub-agents each iteration:

Error Recovery

Route exceptions to recovery steps:

BackTo (cyclic back-edge)

Jump back to an earlier step when a condition is met β€” a lightweight escape hatch for retry patterns:
backTo creates an EdgeCondition.BackEdge in the graph IR β€” a real edge, visible in traces. The next .step() chains from the same node (not the back-edge target), so merge runs when the predicate returns false. Use RunOptions.maxIterations() as a circuit breaker to prevent infinite loops:
When to use backTo vs repeatUntil: repeatUntil creates structured loop nodes (entry β†’ body β†’ check β†’ exit). backTo is a single edge β€” no extra nodes, no loop wrapper. Use it when you need a quick β€œretry this section” without the overhead of a full loop construct.

Terminate

Exit early from anywhere:

Step Types

Steps are the atomic unit. Each wraps a different kind of execution:
The key differentiator: ClaudeStep runs a full agentic loop internally β€” many turns, many tool calls, minutes of execution. The workflow sees it as one step. This is the opposite of frameworks where each LLM API call is a separate workflow activity.

Composability

Workflows implement Step<I, O>. Nest them freely:

RunOptions

Runtime constraints β€” not DSL verbs, hints to the executor:

The Graph IR

Every primitive compiles to real nodes and typed edges β€” not opaque lambdas:
  • A branch is 4 nodes (gateway β†’ then-step, else-step β†’ join) + 4 edges
  • A loop has a back-edge from body to entry
  • A parallel has fork and join nodes with BranchIndex edges
This makes workflows inspectable, traceable, and replayable. The TraceRecorder sees every transition; Markov analysis works on the edge data.

Getting Started

Install, first workflow, four-layer architecture

Complete Examples

8 runnable integration tests validated against GPT-4.1