# Workflows and steps

A workflow is written in YAML: the requests it accepts, the operations its steps may use, the steps in order, and what it returns.

Trigger: Triggers → Declare: Operations → Steps: Steps → Output: Output

The four parts every workflow file has, in the order they are usually written.

## A complete workflow

```yaml title="SummarizePage.yaml"
Workflow: SummarizePage
Description: Fetches a page and answers a question about it.
Triggers:
  - New: Ask
    Schema:
      type: object
      required: [Prompt, Url]
      properties:
        Prompt: { type: string }
        Url: { type: string }
Instructions: Answer the question using the fetched page.
Operations:
  - Tool: Fetch
    Locator: embedded://momor.ai/services/tools/fetchPage
Output: Content
Steps:
  - ExecuteTool: Read
    Operations: [Fetch]
    Input:
      url: { Field: Trigger.Url }
  - DeliverResults: HandOver
```

`ExecuteTool` fetches the page, `DeliverResults` puts it into the run’s conversation, and because the conversation then ends on a result, the engine asks the model to reply to it. That reply is the workflow’s `Content` answer.

## Writing a step

A step is written under its kind, and the value of that key is the step’s name: `- ModelCall: Triage`. The name is optional, and only needed where a later step reads the step’s output. Names are unique within a workflow. The same form names every list entry: `- New: Ask` for a trigger, `- Tool: Fetch` for an operation, `- Hook: Title` for a hook.

## Step kinds

| Kind | What it does | Step reference |
| --- | --- | --- |
| [`ModelCall`](/docs/workflows/steps/ask-the-model/) | Asks the model for one reply. | Ask the model |
| [`ExecuteTool`](/docs/workflows/steps/call-a-tool/) | Runs one or more declared tools the author chose. | Call a tool |
| `ExecuteModelToolCall` | Runs the calls a model chose. | Call a tool |
| `DeliverResults` | Puts results into the run’s conversation. | Call a tool |
| [`Branch`](/docs/workflows/steps/if/) | Sends the flow down one of several paths. | If |
| [`ForEach`](/docs/workflows/steps/for-each/) | Runs work once per item of a list: one operation per item, or a body of steps per item. | For each |
| [`Wait`](/docs/workflows/steps/wait-for-approval/) | Asks a person a question. | Wait for approval |
| [`WorkflowCall`](/docs/workflows/steps/run-a-workflow/) | Runs one or more declared workflows. | Run a workflow |
| `Repeat` | Runs a body of steps more than once, up to a number of rounds. | — |
| `While` | Runs a body of steps for as long as a condition holds. | — |
| `Exit` | Ends the enclosing Repeat or While, or one item’s pass inside a ForEach body. | — |
| `Guard` | Wraps one step and serves an earlier run’s output where the key matches. | — |
| `RefineLoop` | Invokes an operation until what the run holds is good enough. | — |
| `AgentCall` | Gives a task to one or more agents and takes their answers. | — |
| `Supervise` | Runs agents in rounds and judges their answers between rounds. | — |
| `Debate` | Gives the same instructions to two models and crosses their positions in rounds until they agree. | — |
| `Scope` | Charges every call its steps make against a budget of its own. | Limits |

The fields of every kind are listed in the [YAML reference](/docs/workflows/yaml/). A step kind the engine does not know is refused when the workflow is uploaded.

## Data between steps

- **The feed.** Each step receives the value the step before it produced. The request that opened the turn is the first value in the feed.
- **Named outputs.** A named step’s output stays readable for the rest of the turn: { Field: Triage.Topic } reads the Topic field of the step named Triage. Trigger reads the request: { Field: Trigger.Url }.
- **Input mappings.** A step with an Input mapping reads that instead of the feed. The keys are the target’s own field names, so they follow the tool’s or the called workflow’s schema.
- **The conversation.** Model steps read the run’s conversation, not the feed. The opening request is its first message; DeliverResults adds tool results to it.

> **Names inside a branch or a loop**
> A step named inside a branch case can be read only inside that case, and a step named inside a loop body only inside that body. The branch or loop’s own name carries its result out.
