# Workflow designer

Build an agent's workflow on a drag-and-drop canvas, draft it from a description, add stages with SLAs, and dry run it with every tool stubbed.

A workflow is a versioned, deterministic process that an agent runs step by step. Each step is governed as the agent's own calls are: its tool allow-list, Cedar policies, guardrails, budget and approvals. The designer is where you build one. The drawing is the editor, so you do not need to write JSON.

Open the agent, then **Settings** › **Workflows**, and choose **New workflow** or **Open**.

## Step types

| Step | What it does |
| --- | --- |
| `agent` | Sends a prompt to the agent's model |
| `tool` | Calls a tool the agent has attached, with argument rows (`=expr` works a value out) |
| `condition` | Checks an expression and goes to its yes or no step |
| `assign` | Sets a variable |
| `parallel` | Runs up to 8 branches, each of up to 10 steps |
| `approval` | Files an approval and waits for a person's decision |
| `call_workflow` | Runs another workflow of the same agent as a child (at most 3 levels deep) |
| `set_output` | Sets the workflow's result |

`agent`, `tool`, `parallel`, `approval` and `call_workflow` steps can fail, so they also take a retry, a timeout, a fallback and a failure path.

## Build on the canvas

- **Add a step.** Drag a palette card onto a gap on the canvas. A line shows where it lands. A palette card is also a button: press it to add the step after the selected one.
- **Move a step.** Drag it to another place, or focus it and press Alt+Up or Alt+Down.
- **Connect steps.** Each step has ports: its next step, a condition's yes and no, and a failure path. Drag a port onto the step it should go to, or onto **End**. From the keyboard, press Enter on a port and then on a step. Escape cancels.
- **Edit a step.** Select it to open its fields: the prompt, the server and tool (listed from the agent's own tools), arguments, the check a condition makes, what an approver reads, a parallel step's branches, and the fallback or failure path. **Then go to** chooses where it goes next.
- **Rename or delete.** A rename updates every reference to the step. Deleting a step (Delete key) sends whatever led to it on to where it went.
- **Undo and redo.** **Undo** and **Redo**, or Ctrl/Cmd+Z, Shift+Ctrl/Cmd+Z and Ctrl+Y, cover every edit.

Pointer events drive the canvas, so mouse, pen and touch all work. The **JSON** view shows the same document if you prefer to read or paste it.

Every edit is checked by the server's validator (`POST /api/agents/{key}/workflows/validate`), and each problem is marked on the step it names.

### Autosave

**Autosave** is on by default; the toggle is on the toolbar. Once the workflow has a name, each change that passes the validator is saved as a new version after a short pause. The status line reads "Autosaved as version N", or says why it was not saved. Turn it off to save by hand with **Save**.

## Draft from a description

Choose **Draft from a description**, describe the process, and choose **Draft the steps** (`POST /api/agents/{key}/workflows/draft`, up to 4,000 characters). The draft is validated and loaded into the designer with every problem listed. It is never saved until you save it.

- **With the agent's model** (`TICKETIQ_WORKFLOW_DRAFT_WITH_MODEL`, default `true`): the agent's own model writes the draft in one governed call, so its budget, guardrails and transcript apply. Conditions and arguments are included. Each draft is a paid model call.
- **As an outline**: when the setting is off, or the agent's model cannot answer (no model bound, budget spent), the text is outlined instead and `model_fallback` says why. Lines or sentences become steps. "If ..." becomes a condition, "otherwise ..." its other branch, "approve" or "sign off" an approval step, a tool or workflow named by name a tool or child step, and "return ..." the result. An outline never writes the expression a condition checks: that is marked for you to fill in.

## Stages and case types

A workflow can group its top-level steps into stages, up to 20. A workflow with stages is a **case type**: a claim, an onboarding or a change request that moves through Intake, Review, Fulfilment and so on. Open **Stages: make this a case type** and choose **Add a stage**.

| Field | Meaning |
| --- | --- |
| **Stage name**, **Label** | The stage's id and the name people see |
| **Steps in this stage** | Top-level steps; each step is in one stage at most. A step in no stage keeps the run in the stage it is in |
| **May start when** | Entry expression, checked when the run first reaches the stage from outside it |
| **Is done when** | Exit expression, checked when the run leaves the stage or finishes |
| **Time goal (minutes)** | The stage's SLA |
| **Counted in the working hours of** | An SLA policy whose calendar (business hours, holidays, time zone) the goal is counted in. Leave it empty to count every hour |

A criterion that does not hold fails the case, named, while it is still in its stage. To route around a stage instead, use a condition step. Time spent waiting in a stage, for example on an approval, counts toward its goal.

The policy list reads `GET /api/sla/policies` (`tickets.read`); without that permission the field is free text. Create a policy under **IT service desk** › **Setup** › **SLA policies**. Only its calendar is used, not its priority targets.

Runs show the stage each case is in, and each stage's start, end, deadline and breach. A stage past its deadline reads as late before it ends. Entering and leaving a stage is audited as `agent.workflow.stage`.

> [!NOTE]
> Stage breaches are computed, not alerted. Nothing notifies anyone when a stage goes late, and there is no case list across workflows, case owner or stage-level pause.

## Dry run

Choose **Dry run** (`POST /api/agents/{key}/workflows/dry-run`) to walk the workflow before it does anything. Expressions are evaluated for real. Every tool call, agent reply, approval and child run is stubbed:

| Step | In a dry run |
| --- | --- |
| `tool` | Shows the server, tool and resolved arguments; returns the stub's result, or echoes the request |
| `agent` | Shows the resolved prompt; returns the stub's reply, or a placeholder |
| `approval` | Shows what the approver would read; approved unless the stub says otherwise |
| `call_workflow` | Dry runs the child's latest saved version in turn, unless a stub gives its result |

A stub is `{"output": value}` or `{"error": type, "message": text}` for one step id (up to 200 stubs). An error stub fails the step, so you can walk retries, fallbacks and failure paths as easily as the happy path. The designer shows each step's input, result and next step, and outlines the path on the drawing.

Nothing is called, filed or stored, and no run is written.

> [!WARNING]
> A dry run does not apply governance. A tool the agent would be refused at run time is still stubbed. The validator catches tools that are not attached; Cedar, guardrails and data policies are only met in a real run or in the playground.

## Step budgets and limits

| Limit | Value |
| --- | --- |
| Steps in a definition, branch steps included | 100 |
| Steps one run may execute | 200 (a loop that never ends fails the run with `workflow_error`) |
| Steps one dry run may walk, children included | 1,000 |
| Retry attempts per step | 10 |
| Step timeout | 600 s |
| Child workflow depth | 3 |
| Stages | 20 |

## Routes and permissions

| Task | Endpoint | Permission |
| --- | --- | --- |
| List workflows | `GET /api/agents/{key}/workflows` | `agents.get` |
| Validate, draft, dry run | `POST .../workflows/validate`, `/draft`, `/dry-run` | `agents.update` |
| Save a new version | `PUT /api/agents/{key}/workflows/{name}` | `agents.update` |
| Read a version | `GET /api/agents/{key}/workflows/{name}?version=` | `agents.get` |
| Delete every version | `DELETE /api/agents/{key}/workflows/{name}` | `agents.update` |
| Run | `POST /api/agents/{key}/workflows/{name}/runs` | `agents.run` |
| Run history | `GET /api/agents/{key}/workflow-runs` | `agents.read` |

Each route also checks Cedar on the agent: `update` for designing, `invoke` for running, `read` for history.

Workflows are also code. An agent's bundle carries a `workflows` section, and `liya workflows list | get | validate | dry-run | draft | run | runs` drives them from the CLI. See [GitOps](/docs/cli/gitops).

## What the designer does not do yet

- Free layout and zoom: the drawing is the step order as one column.
- Changing a step's type in place (delete it and add another), or editing per-step model and tool overrides outside the JSON view.
- Saving a dry run's input and stubs as a reusable test.
