# `Nous.Workflow`
[🔗](https://github.com/nyo16/nous/blob/v0.17.1/lib/nous/workflow.ex#L1)

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 graph
- `add_node/4,5` — add a typed node
- `connect/3,4` — add an edge between nodes
- `chain/2` — connect nodes in sequence

## Execution

- `compile/1` — validate and compile the graph
- `run/2,3` — compile and execute in one step

# `add_node`

# `chain`

# `compile`

```elixir
@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}`.

# `connect`

# `insert_after`

# `new`

# `remove_node`

# `run`

```elixir
@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.Hook` structs; the engine dispatches `:workflow_start`,
  `:workflow_end`, `:pre_node` and `:post_node` (default: `[]`)
- `:trace` — when `true`, record a `Nous.Workflow.Trace` and attach it to
  `state.metadata.trace` on completion or suspension (default: `false`)
- `:scratch` — when `true`, allocate a run-scoped `Nous.Workflow.Scratch` and
  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

# `set_entry`

# `to_mermaid`

```elixir
@spec to_mermaid(
  Nous.Workflow.Graph.t(),
  keyword()
) :: String.t()
```

Generate a Mermaid flowchart diagram string from the graph.

# `validate`

```elixir
@spec validate(Nous.Workflow.Graph.t()) :: :ok | {:error, [term()]}
```

Validate a workflow graph without compiling.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
