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

# Customer Flows

> Define the customer conversations your agents should handle — and get graded against

## What is a customer flow?

A customer flow describes one type of customer conversation: who the customer is, what they want, the variants you need to cover (language, mood, environment), and the **agent expectations** the agent is graded against. Flows live under **Simulate → Customer flows** in the sidebar.

Today, flows drive simulations — you attach them to run plans and Roark generates test calls from them. The same definition is what live-call analytics will grade incoming traffic against next.

<Note>
  Customer flows supersede the "scenarios" concept from earlier versions of Roark. The REST API and SDKs still use the older name — for example, run requests take a `scenarios` field.
</Note>

Every flow has:

| Part                    | What it does                                                                          |
| :---------------------- | :------------------------------------------------------------------------------------ |
| **Title & description** | Identify the flow in the hub and in run reports                                       |
| **Linked agent(s)**     | At least one agent must be linked — saving is blocked otherwise                       |
| **Labels**              | System labels (Adversarial, Multilingual, IVR, Voicemail) and free-form custom labels |
| **Agent expectations**  | LLM-graded instructions, inherited by every variant                                   |
| **Variants**            | One default **happy path** plus any number of **edge cases**                          |

***

## Authoring modes: Improv vs Scripted

Each flow is authored in one of two modes, toggled with the **Improv / Scripted** pill in the editor header.

|           | **Improv**                                                                                    | **Scripted**                                                              |
| :-------- | :-------------------------------------------------------------------------------------------- | :------------------------------------------------------------------------ |
| You write | A free-text customer brief: the situation the customer is in, what they want, how they behave | The conversation itself, step by step, on a graph canvas                  |
| Each run  | The simulator improvises a fresh conversation — different words, same intent                  | Follows one path through your graph deterministically                     |
| Best for  | Realistic, open-ended conversations; broad behavioral coverage                                | IVR menus, DTMF entry, deterministic routing, precise turn-by-turn checks |
| Variants  | You author them by hand                                                                       | Derived automatically — one per path through the graph                    |

Switching modes is non-destructive: both data shapes coexist on the flow, so you can toggle back and forth. If the other mode already has authored content, the editor asks you to confirm the switch — your work is retained either way.

<Note>
  In the GraphQL API, Improv mode is the `UNSCRIPTED` value of the `FlowMode` enum — there is no `IMPROV` enum value. The UI label is newer than the API name.
</Note>

### Improv mode

The improv editor is organized into three numbered sections:

1. **Happy path** — the customer setup: a free-text brief describing the situation the customer is in, what they want, and how they typically behave. This section also carries the happy path's Persona, Environment, and Variables chips, and a **Link preceding flow** control (see [flow composition](#composing-flows) below).
2. **Agent expectations** — the required agent picker plus expectation rows, inherited by every variant.
3. **Edge cases** — additional variants that inherit from the happy path and override only what differs.

### Scripted mode

Scripted mode replaces the form with a full-screen canvas where you author the conversation as a graph of steps. See [the scripted graph](#the-scripted-graph) for step kinds and rules.

***

## Variants: happy path and edge cases

A variant is one per-caller configuration of the flow: a title, persona, environment, variables, per-variant labels, and optional additional expectations.

* **Exactly one variant is the default** — the **happy path**. It must have a customer setup and a persona.
* **Every other variant is an edge case.** Edge cases inherit the happy path's setup, persona, and environment unless they override them. The setup field on an edge case reads "Inherited from the happy path — type to override."
* **Additional expectations append.** An edge case can add expectations that apply just to that variant; they never replace the flow-level set.
* Each edge case can carry its **own labels**, and its menu lets you **Mark as happy path** (making it the new default) or **Delete edge case**.

<Tip>
  An edge case that overrides nothing is pointless — and the editor blocks saving it. Give each edge case at least a different setup, persona, or environment.
</Tip>

### Persona, Environment, and Variables chips

Every variant carries a chip strip configuring who's calling and from where:

* **Persona** — the simulated customer's voice and delivery. The happy path requires one (a new flow auto-seeds the built-in **Polite First-Time Caller** persona, falling back to your project's first persona); the picker can also create or edit personas inline. See [Personas](/documentation/simulation-testing/personas).
* **Environment** — background noise played under the customer's voice: Silent, Office, Coffee shop, City street, Driving, Airport, Children playing, or Thunderstorm. Edge cases also get an **Inherit** option.
* **Variables** — per-variant key/value entries (name, account ID, last visit…) handed to the customer-side model so it can answer the agent's questions consistently. Add rows manually, or use **Apply a test profile** to replace the entries with a saved profile's properties. Prompt and step text support `{{variable}}` tokens with autocomplete — `{{name}}` for flow-scoped properties, `{{persona.name}}` for persona-scoped ones. See [Variables](/documentation/simulation-testing/variables).

***

## Agent expectations

Agent expectations are the graded contract of the flow: short, LLM-evaluated instructions like *"Agent greets warmly and uses the caller's name once."* After each simulated conversation, Roark checks the transcript against every expectation and reports pass/fail per expectation, per call.

* **Flow-level expectations** are inherited by every variant.
* **Additional expectations** on an edge case apply only to that variant, on top of the flow-level set.
* In scripted flows, expectations are also derived from the agent turns along each path — what you wrote the agent should say becomes what it's graded on.

Write expectations as specific, checkable statements. "Agent offers a callback when the customer declines to hold" grades cleanly; "Agent is helpful" doesn't.

***

## Labels

Flows use a single label system with two kinds:

* **System labels** — Roark-curated: `Adversarial`, `Multilingual`, `IVR`, `Voicemail`. These drive template behavior; for example, the Red teaming template automatically runs flows carrying the Adversarial label.
* **Custom labels** — free-form tags for your own organization.

Labels attach at the flow level and per edge case, and the hub filters by them (alongside a **Mode** filter for Improv vs Scripted).

***

## The scripted graph

In scripted mode you build the conversation as a directed graph rooted at a start node. Click **Add step** to insert a step, then connect steps with edges; selecting a node opens an inspect panel with its kind-specific fields.

### Step kinds

| Step              | What it does                                                                      |
| :---------------- | :-------------------------------------------------------------------------------- |
| **Agent**         | What the agent says at this point — also becomes a graded expectation on the path |
| **Customer**      | What the customer says back                                                       |
| **First message** | The customer's opening line — only valid immediately after the start node         |
| **DTMF**          | The caller presses keypad digits (`0–9`, `*`, `#`; use `#` to mark end-of-input)  |
| **Silence**       | The caller pauses for 1–60 seconds                                                |
| **Voicemail**     | A voicemail message plays — terminal; the conversation ends on tape               |
| **Flow link**     | Splices another scripted flow's steps in at this point                            |

<Note>
  The API keeps older names here too: step kinds map to the `SimulationStepType` enum, where a Flow link is `SCENARIO_LINK` and a First message is `CUSTOMER_FIRST_MESSAGE`.
</Note>

### Graph rules

* **Branching is allowed** — give a step multiple outgoing edges to fork the conversation.
* **Merges are allowed** — branches can rejoin.
* **Cycles are blocked** — the graph must be a DAG, so a conversation always terminates.

### Paths derive variants

Every unique route through the graph from start to finish is a **path**, and when you save the flow, Roark derives one variant per path — each path card in the right rail shows a generated description of its route. You don't hand-author scripted variants; you shape the graph and the variants follow.

You can still control *who* runs each path: **Add variant for path** creates an extra copy of a path that runs it with a different persona, environment, or variables. The rail marks the flow's default variant with a **Default** badge and groups the rest under **Edge cases**, with **Make default** and **Delete variant** available per variant.

<Warning>
  Structural edits — adding or deleting nodes or edges — freeze variant editing until you save: "You've edited the graph. Save the flow to refresh its paths before adding or removing variants."
</Warning>

***

## Composing flows

Flows compose in two directions:

* **Flow link (scripted → scripted).** A scripted flow can include a **Flow link** step that splices another scripted flow's steps in mid-graph. Use this to reuse a shared segment — an IVR menu, an identity-verification exchange — across many flows. Only scripted flows can be linked this way.
* **Preceded by (scripted → improv).** An improv variant's **Link preceding flow** control names a scripted flow — and optionally a specific variant of it — that runs *before* the improv segment. Typical use: navigate a scripted IVR tree deterministically, then improvise the conversation once a human-like agent picks up.

Improv has no deterministic end, so an improv segment can only ever come last — you can't link *into* an improv flow from a scripted step.

***

## Creating a flow

From the hub, click **New flow** to open the chooser at `/customer-flows/new`. You can generate a draft or start blank:

**Generate — from existing material** (each opens the Ask Roark assistant with a seeded prompt):

* **Describe what you want** — tell Ask Roark the conversation in plain language and it drafts the flow.
* **From a transcript** — upload or paste a transcript and Roark turns it into a flow.
* **From your calls** — pick real calls from your production traffic to base the flow on.

**Or start blank:**

* **Improv — Describe the customer** opens the brief editor.
* **Scripted — Author the conversation** opens the graph canvas.

Variants drafted by Ask Roark carry a **Generated** badge until you review or promote them.

<Steps>
  <Step title="Title and describe the flow">
    Give it a clear title and a short description of the conversation type it covers.
  </Step>

  <Step title="Write the happy path">
    In Improv, write the customer setup brief; in Scripted, build the graph. Pin a persona, pick an environment, and add any variables the customer should know.
  </Step>

  <Step title="Link an agent and add expectations">
    Pick at least one agent, then add expectation rows describing what the agent must do. These are inherited by every variant.
  </Step>

  <Step title="Add edge cases">
    Cover the deviations that matter — a different language, a frustrated caller, a noisy environment, missing information. Override only what differs from the happy path.
  </Step>

  <Step title="Save">
    The save button surfaces the first blocking issue if anything is missing — for example "Link at least one agent to save", "The happy path needs a prompt", or (scripted) "Add at least one step to the graph".
  </Step>
</Steps>

***

## Using flows in a run

Flows drive simulations through run plans. In the create-run page, the **Attach flows** picker lists your library; expand a flow to choose its variants. Each attachment carries:

* **A variant selection** — all variants, the default variant (happy path) only, or specific variants you pick.
* **An optional persona override** — run the flow as a different customer without editing it. The Multilingual template uses this to fan one flow out across language personas.
* **Variable overrides** — per-attachment `{{variable}}` values that win over the variant's stored values at run time.

When a run starts, it snapshots the attached flows and variants, so the report always reflects exactly what was tested — even if you edit the flow afterwards.

<CardGroup cols={2}>
  <Card title="Run Plans" icon="list-checks" href="/documentation/simulation-testing/run-plans">
    Combine flows, agents, and metrics into reusable test suites
  </Card>

  <Card title="Personas" icon="users" href="/documentation/simulation-testing/personas">
    Configure the simulated customer's voice and delivery
  </Card>

  <Card title="Variables" icon="braces" href="/documentation/simulation-testing/variables">
    Parameterize flows with per-variant and run-time values
  </Card>

  <Card title="Templates" icon="layout-template" href="/documentation/simulation-testing/templates">
    Start runs from goals like red teaming or multilingual coverage
  </Card>
</CardGroup>
