DAG/graph-based workflow engine for orchestrating agents, tools, and control flow.
Workflows define execution graphs where nodes are steps (agent calls, tool executions, transformations, branches, parallel fan-outs) and edges define the flow between them.
Architecture
- Complementary to Decisions: Decisions track why an agent made choices. Workflows define what executes and when.
- Complementary to Teams: Teams manage persistent agent groups. Workflows define transient execution plans.
- Standalone system: Not a Behaviour or Plugin — operates above the agent level.
Quick Start
alias Nous.{Agent, Workflow}
planner = Agent.new("openai:gpt-4o-mini", instructions: "You are a research planner.")
searcher = Agent.new("openai:gpt-4o-mini", instructions: "You search for information.")
reporter = Agent.new("openai:gpt-4o-mini", instructions: "You write reports.")
workflow =
Workflow.new("research")
|> Workflow.add_node(:plan, :agent_step, %{agent: planner, prompt: "Plan research on: ..."})
|> Workflow.add_node(:search, :agent_step, %{agent: searcher, prompt: fn s -> "Search: #{s.data.plan}" end})
|> Workflow.add_node(:report, :agent_step, %{agent: reporter, prompt: "Write report from findings."})
|> Workflow.chain([:plan, :search, :report])
{:ok, result} = Workflow.run(workflow, %{topic: "AI agents in 2026"})Graph Definition
Build graphs using an Ecto.Multi-style pipe API:
new/1,2— create an empty graphadd_node/4,5— add a typed nodeconnect/3,4— add an edge between nodeschain/2— connect nodes in sequence
Execution
compile/1— validate and compile the graphrun/2,3— compile and execute in one step
Summary
Functions
Compile and validate a workflow graph.
Compile and execute a workflow in one step.
Generate a Mermaid flowchart diagram string from the graph.
Validate a workflow graph without compiling.
Functions
@spec compile(Nous.Workflow.Graph.t()) :: {:ok, Nous.Workflow.Compiler.compiled()} | {:error, [term()]}
Compile and validate a workflow graph.
Returns {:ok, compiled} or {:error, errors}.
@spec run(Nous.Workflow.Graph.t(), map(), keyword()) :: {:ok, Nous.Workflow.State.t()} | {:suspended, Nous.Workflow.State.t(), map()} | {:error, term()}
Compile and execute a workflow in one step.
Options
Forwarded verbatim to Nous.Workflow.Engine.execute/3:
:deps— dependencies passed to agents/tools:callbacks— callback functions for agent steps:notify_pid— PID to receive progress notifications:max_iterations— max cycle iterations (default: 10):hooks—Nous.Hookstructs; the engine dispatches:workflow_start,:workflow_end,:pre_nodeand:post_node(default:[]):trace— whentrue, record aNous.Workflow.Traceand attach it tostate.metadata.traceon completion or suspension (default:false):scratch— whentrue, allocate a run-scopedNous.Workflow.Scratchand clean it up on completion. It is NOT attached to the state; see that module's docs (default:false):pause_ref— reference used to resume a suspended run:on_node_complete— 1-arity function invoked after each node finishes
Returns
{:ok, final_state}— workflow completed successfully{:suspended, state, info}— a node paused the run (e.g. a{:pause, _}hook or a human-review node){:error, reason}— compilation or execution failed
@spec to_mermaid( Nous.Workflow.Graph.t(), keyword() ) :: String.t()
Generate a Mermaid flowchart diagram string from the graph.
@spec validate(Nous.Workflow.Graph.t()) :: :ok | {:error, [term()]}
Validate a workflow graph without compiling.