> ## Documentation Index
> Fetch the complete documentation index at: https://docs.orcapods.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Workflow Orchestration

> DAG-based multi-agent workflows executed by the conductor-side planner engine.

## What is a Workflow Run?

A **workflow run** is one execution instance of a directed acyclic graph of work nodes. Each node names an agent profile and a prompt template. The conductor validates the DAG, schedules ready nodes, dispatches runs through the runner pool, and persists state in the workflow store.

Workflow runs are useful when a request has clear parallel or ordered subtasks, such as research -> synthesis -> review.

***

## Shape

```go theme={null}
type WorkflowRun = Plan       // legacy alias kept during the migration
type WorkflowNode = PlanNode

type Plan struct {
  ID                    string
  UserPrompt            string
  OrchestratorRunID     string
  OrchestratorSessionID string
  Status                PlanStatus
  AutoStart             bool
  Nodes                 []PlanNode
  CreatedAt             time.Time
  StartedAt             time.Time
  FinishedAt            time.Time
  RepairCount           int
  Deadline              time.Time
  DelegationDepth       int
}

type PlanNode struct {
  ID             string
  Title          string
  Profile        string
  SessionID      string
  PromptTemplate string
  DependsOn      []string
  OutputSchema   json.RawMessage
  Status         NodeStatus
  RunID          string
  Output         string
  Fields         json.RawMessage
  Error          string
  Attempt        int
  StartedAt      time.Time
  FinishedAt     time.Time
}
```

`Plan` / `PlanNode` are the legacy Go names; `WorkflowRun` / `WorkflowNode` are aliases. The wire shape and storage layer are unchanged.

Status fields are numeric enums in full snapshots.

| Run value | Label       |
| --------- | ----------- |
| `0`       | `pending`   |
| `1`       | `running`   |
| `2`       | `paused`    |
| `3`       | `completed` |
| `4`       | `failed`    |
| `5`       | `cancelled` |

| Node value | Label       |
| ---------- | ----------- |
| `0`        | `pending`   |
| `1`        | `ready`     |
| `2`        | `running`   |
| `3`        | `ok`        |
| `4`        | `error`     |
| `5`        | `skipped`   |
| `6`        | `cancelled` |

***

## Example DAG

```mermaid theme={null}
flowchart LR
  langgraph["research-langgraph"] --> compare
  autogen["research-autogen"] --> compare
  compare --> review
```

```json theme={null}
{
  "userPrompt": "Compare LangGraph and AutoGen",
  "nodes": [
    {
      "id": "research-langgraph",
      "title": "Research LangGraph",
      "profile": "researcher",
      "promptTemplate": "Summarize LangGraph features and use cases."
    },
    {
      "id": "research-autogen",
      "title": "Research AutoGen",
      "profile": "researcher",
      "promptTemplate": "Summarize AutoGen features and use cases."
    },
    {
      "id": "compare",
      "title": "Compare results",
      "profile": "analyst",
      "promptTemplate": "Compare these findings:\n\nLangGraph:\n{{research-langgraph.output}}\n\nAutoGen:\n{{research-autogen.output}}",
      "dependsOn": ["research-langgraph", "research-autogen"]
    },
    {
      "id": "review",
      "title": "Review comparison",
      "profile": "reviewer",
      "promptTemplate": "Review this comparison for accuracy:\n\n{{compare.output}}",
      "dependsOn": ["compare"]
    }
  ]
}
```

Execution order:

1. `research-langgraph` and `research-autogen` run in parallel.
2. `compare` starts after both research nodes reach `ok`.
3. `review` starts after `compare` reaches `ok`.

***

## Prompt Templates

Node prompt templates can reference upstream outputs:

| Template                 | Meaning                                                  |
| ------------------------ | -------------------------------------------------------- |
| `{{node-id.output}}`     | Raw output text from an upstream node                    |
| `{{node-id.fields.key}}` | Structured output field when `outputSchema` was provided |

Template validation happens before a workflow run is accepted. Bad references return `400` with a `bad_template` error.

***

## Creating Workflow Runs

```bash theme={null}
curl -X POST https://api.orcapods.ai/api/workflows/runs \
  -H 'Content-Type: application/json' \
  -d @workflow.json
```

Create response:

```json theme={null}
{
  "workflowRunId": "workflow-8b2a9c4f",
  "status": "pending"
}
```

`autoStart` defaults to `true`. Set `"autoStart": false` to create a workflow run without submitting it to the engine, then call:

```bash theme={null}
curl -X POST https://api.orcapods.ai/api/workflows/runs/workflow-8b2a9c4f/start
```

***

## Streaming

```bash theme={null}
curl -N https://api.orcapods.ai/api/workflows/runs/workflow-8b2a9c4f/stream
```

The stream sends an initial `snapshot` event followed by `plan_status` events. Each frame carries the full workflow-run snapshot under the `workflowRun` key:

```
event: snapshot
data: {"type":"snapshot","workflowRun":{...}}

event: plan_status
data: {"type":"plan_status","workflowRun":{...}}
```

***

## Repair

When execution pauses, a coordinator can repair the workflow run:

```json theme={null}
{
  "type": "retry_node",
  "nodeId": "research-langgraph"
}
```

Supported repair actions:

| Type             | Effect                                        |
| ---------------- | --------------------------------------------- |
| `retry_node`     | Re-runs a failed node                         |
| `replace_node`   | Replaces a node definition                    |
| `add_dependency` | Adds dependency edges and revalidates the DAG |
| `abort`          | Ends the workflow run                         |

`AGENT_ORC_PLAN_MAX_REPAIRS` limits how many repairs a workflow run can consume.

***

## Orchestrator-Driven Mode

A coordinator agent can create a workflow run with `autoStart: false`, delegate node work itself, then mark nodes terminal with `POST /api/workflows/runs/{workflowRunId}/nodes/{nodeId}/status`.

```json theme={null}
{
  "workflowRunId": "workflow-8b2a9c4f",
  "nodeId": "research-langgraph",
  "status": "ok",
  "output": "Research result..."
}
```

This mode is useful when the orchestrator needs to inspect, transform, or gate each node result before unlocking downstream work.

***

## Configuration

| Env Var                             | Default | Scope                                                            |
| ----------------------------------- | ------- | ---------------------------------------------------------------- |
| `AGENT_ORC_PLANS_DIR`               | unset   | JSONL file path for workflow run persistence (MemStore fallback) |
| `AGENT_ORC_PLAN_NODE_PARALLELISM`   | `8`     | Max in-flight nodes per workflow run                             |
| `AGENT_ORC_PLAN_GLOBAL_PARALLELISM` | `64`    | Max in-flight nodes process-wide                                 |
| `AGENT_ORC_PLAN_NODE_RETRIES`       | `0`     | Transport-error retry budget per node                            |
| `AGENT_ORC_PLAN_MAX_NODES`          | `64`    | Validation cap on workflow size                                  |
| `AGENT_ORC_PLAN_MAX_REPAIRS`        | `5`     | Repair budget before auto-fail                                   |

Env vars retain their `AGENT_ORC_PLAN_*` prefix because the planner engine is still the underlying substrate.

***

## Validation Errors

The conductor returns `400` with stable prefixes for user-correctable workflow errors:

| Prefix                  | Meaning                                     |
| ----------------------- | ------------------------------------------- |
| `cycle_detected`        | DAG has a cycle                             |
| `unknown_profile`       | A node references a missing profile         |
| `bad_template`          | Prompt template references invalid data     |
| `too_many_nodes`        | Workflow exceeds `AGENT_ORC_PLAN_MAX_NODES` |
| `duplicate_node_id`     | Node IDs are not unique                     |
| `dependency_unresolved` | A dependency references a missing node      |
