Transitions, Variables & the Director
A Voice Workflow is a state machine: the caller is always sitting on exactly one node, and after each thing they say the engine decides where to go next. This page explains the machinery behind that decision — the variables the flow tracks, the edge conditions that wire nodes together, the resolution order the engine follows every turn, and the Director (a fast LLM) that extracts data and picks ambiguous routes. For the nodes these transitions connect, see Node Types. To build and arrange the graph, see The Workflow Builder.Variables
Variables are the workflow’s memory. You declare them in the Variables panel (the right sidebar in the builder), reference them anywhere as{{name}}, and the flow uses them for two things:
- Collection — a Conversation or Collector node
extracts declared variables from what the caller says, andrequires certain ones before the flow may move on. - Branching — edge conditions and Condition nodes read variables to decide the next node.
| Type | Holds | Example value | Notes |
|---|---|---|---|
string | Free text | "Mumbai" | Use an enum to restrict to known options |
integer | Whole numbers | 42 | Compare with >, <, >=, <= in equations |
number | Decimals | 19.99 | For amounts, durations, scores |
boolean | true / false | true | Ideal for branch flags (e.g. {{slot_available}}) |
Edge conditions
Edges are top-down: each edge leaves the bottom of one node and connects to the top of another, and the canvas prints each edge’s condition as a label so you can read the routing at a glance. You set an edge’s condition in the edge condition editor (select an edge; the Inspector tab switches to the editor). It has a single mode toggle with three options:Unconditional
The “else” path. No test — taken when no other edge from this node matches.
Prompt
A natural-language condition the Director judges (a textarea), e.g. “caller agreed to continue”.
Equation
A deterministic expression evaluated in code, e.g.
{{age}} > 18. A guided builder (variable / operator / value) plus a raw-expression option.Prompt conditions
A prompt condition is plain English describing when this edge should fire. The Director reads the caller’s latest turn and decides whether the condition is met. Use prompt conditions when intent is fuzzy and only a model can judge it:caller agreed to continuecaller wants to speak to a humancaller raised a pricing objection
Equation conditions
An equation is a deterministic expression over variables, numbers, quoted strings, and booleans. Because equations run in code — not through the model — they always resolve the same way for the same inputs.| Operator | Meaning | Example |
|---|---|---|
exists | The variable has been captured | {{email}} exists |
== | Equal to | {{slot_available}} == true |
!= | Not equal to | {{plan}} != "free" |
> | Greater than | {{age}} > 18 |
< | Less than | {{quantity}} < 5 |
>= | Greater than or equal | {{score}} >= 0.8 |
<= | Less than or equal | {{wait_minutes}} <= 10 |
CONTAINS | Substring / membership | {{city}} CONTAINS "Mumbai" |
AND | Both sides true | {{age}} >= 18 AND {{consent}} == true |
OR | Either side true | {{plan}} == "pro" OR {{plan}} == "enterprise" |
{{variable}} references, bare numbers, "quoted strings", or true / false.
Resolution order
This is the most important rule on the page. After each caller turn, the engine decides the next node by checking, in this exact order:Equation edges first (deterministic)
Every equation edge leaving the current node is evaluated in code, top to bottom. The first one that is true wins — the flow takes that edge immediately. No model is involved, so this step is fully predictable.
The Director's prompt-edge pick
If no equation edge matched, the Director’s chosen prompt-condition edge is taken — but only if the node’s
require[] variables are all satisfied. If a required variable is still missing, the flow does not leave (see Staying on a node).Global enter-conditions
If neither of the above produced a transition, the engine checks whether any global node’s enter-condition matches. If one does, the flow jumps to that global node, handles the situation, then returns.
Why equation-first matters. Equations are checked deterministically before the model ever sees the routing decision. That makes critical branches — eligibility gates, “did we get a yes”, “is a slot available” — debuggable and reproducible: the same variables always take the same edge, every call. Reserve prompt conditions for the genuinely fuzzy cases the model is good at.
The Director
The Director is a fast LLM that runs each caller turn to do two jobs:- Extract the current node’s declared variables from what the caller just said (filling in
{{name}},{{preferred_date}}, and so on). - Pick which prompt-condition edge is met, when routing requires judgement.
require[] and staying on a node
A Conversation or Collector node can mark some of its variables asrequire[] — the flow may not leave until those variables are captured. If the caller hasn’t yet given a required value, the engine stays on the node and re-asks, turn after turn, until it has what it needs.
This is how you guarantee data before moving on: a booking node that requires {{preferred_date}}, or a collector that requires a verified {{email}}, will keep the caller on that phase until the value is in hand. Only then does Step 2 of the resolution order (the Director’s prompt-edge pick) become eligible. Equation edges are still checked first regardless — so a require gate governs prompt-edge transitions, not hard equation branches you’ve wired for edge cases like an early exit.
Global nodes and interruptions
A global node is a Conversation node marked Global with an enter-condition (a prompt or an equation). It is reachable from any interruptible node — when its enter-condition matches, the flow jumps to the global node no matter where the caller currently is. This is how you handle situations that can come up anywhere in the call: the caller raises a pricing objection, asks for a human, or goes off-script. The global node handles the situation, then returns the caller to the node they were on so the main flow resumes where it left off.- Enter-condition — a prompt (e.g. “caller asks to speak to a human”) or an equation, evaluated as part of the resolution order’s globals step.
- Interruptible toggle — each Conversation node controls whether globals may interrupt it. A node with interrupts off is shielded from globals during its turn.
- Cooldown — measured in turns, this prevents a global from re-triggering immediately after it just ran, so the caller isn’t bounced back into it on the very next turn.
Globals fire only after equation edges and the Director’s prompt-edge pick have had their chance (step 3 of the resolution order). A clean, in-script transition always wins over a global interruption.
Putting it together
A typical turn looks like this: the caller speaks → the Director extracts the current node’s variables → equation edges are checked in code (first-true-wins) → if none match andrequire[] is satisfied, the Director’s prompt-edge is taken → otherwise a global may interrupt → otherwise the caller stays. The destination node then produces the reply.
For the worked end-to-end example — an API call that maps a response field into a boolean a Condition then branches on — see the API Request Node. To start from a ready-made graph, see Workflow Templates.
