Flow Builder Concepts
Flow Builder Concepts
Section titled “Flow Builder Concepts”The agent builder lists every tab and field; this page explains the concepts — the four things people most often ask after building their first agent: when to use freeform vs a flow, what Say and Collect actually do, how branch conditions are evaluated, and when changes go live.
Freeform vs Flow
Section titled “Freeform vs Flow”The first choice on the agent’s Overview tab is the conversation mode:
| Freeform | Flow | |
|---|---|---|
| How it works | The AI improvises every reply from your greeting + persona prompt | The agent walks the visual graph step by step |
| Setup effort | Minutes — write a prompt | More — build and connect nodes |
| Wording control | The AI phrases everything | Fixed lines are spoken word-for-word; AI lines only where you ask |
| Caller answers | Live in the conversation only (post-call extraction can still pull fields from the transcript) | Captured into variables ({{vars.name}}) you can branch on, speak back, or send to APIs |
| Routing the call | The AI ends or transfers when its prompt says to ([hangup] / [transfer]) | Explicit Transfer / Hang up nodes at exact points in the graph |
| Mid-call integrations | None | Tool call / HTTP action / Send message / Webhook nodes |
| Predictability | Conversational, less predictable | Deterministic steps; fully deterministic in Strict routing mode |
Use freeform when the call is conversational and the outcome is simple — reception and after-hours intake (“take a name and a message”), FAQ answering, lead screening that ends in a transfer. It’s the fastest way to a working agent, and a strong persona prompt plus Scope & refusals keeps it on the rails.
Use a flow when you need structure — specific answers captured into variables, guaranteed wording at specific moments (disclosures, menus), branching (“sales or support?”), or mid-call API calls and notifications.
Switching modes is non-destructive: a freeform agent keeps its saved flow dormant, and switching back to Flow mode resumes it.
Say vs Collect
Section titled “Say vs Collect”These two nodes are the core of every flow, and they divide cleanly:
- Say speaks. Collect listens. A Say node says its line and immediately moves to the next node — it never waits for the caller. If the agent should hear the caller, the flow needs a Collect node there.
Say — speak a line
Section titled “Say — speak a line”A Say node has two source modes:
-
Fixed text — spoken exactly as written. Supports
{{variables}}:Thank you for calling {{company_name}}. This call may be recorded.Use fixed text whenever the wording matters — greetings, disclosures, menu prompts.
-
AI-generated — you write a prompt, and the AI writes the actual line at call time in the persona’s voice:
Warmly acknowledge the reason the caller gave ({{vars.reason}}) andreassure them someone will follow up today.The spoken line varies call to call. Use it for natural acknowledgements and summaries — never for lines that must be word-for-word. An AI line can’t promise an action the flow doesn’t actually perform.
Each Say node also has a Caller can interrupt toggle — when the agent’s Barge-in setting is on, callers can talk over interruptible lines; mark a line non-interruptible to always play it in full (e.g. a legal disclosure).
Collect — ask, listen, capture
Section titled “Collect — ask, listen, capture”A Collect node optionally speaks a prompt (fixed text, supports {{variables}}), then waits for the caller and stores what they said in a variable:
- Variable
name→ reference it anywhere downstream as{{vars.name}}— in Say text, branch conditions, API URLs and bodies. - Caller input can be Speech (the default — the answer is transcribed) or Keypad (DTMF) — digits the caller presses are stored in the variable instead, for classic “press 1 for sales” menus (branch on
vars.choice equals 1). - The silence timeout on the node controls how long the agent waits after the caller stops before considering the answer complete.
Branch conditions
Section titled “Branch conditions”A Branch node holds no logic itself — its outgoing edges do. Select an edge in the builder to set its condition.
The three kinds of condition
Section titled “The three kinds of condition”1. Compare a variable — a deterministic check against a collected variable or call metadata:
| Comparator | Matches when… |
|---|---|
| equals / does not equal | exact string match (numbers compared as text) |
| contains | the value appears anywhere, case-insensitive |
| matches regex | the pattern matches, case-insensitive (an invalid pattern simply never matches) |
| greater/less than, at least, at most | numeric comparison |
| is set / is empty | the variable has / doesn’t have a value |
The variable is a path: vars.reason (a Collect result), caller.number, caller.name, call.id. Deterministic checks are exact, instant, and cost nothing.
2. Caller intent (AI) — you write a yes/no question and the AI judges the caller’s most recent reply against it:
Question: does the caller want to speak to sales? Take this path when intent is: yes
Use AI intent when the same meaning arrives phrased a hundred ways (“gimme sales”, “I’d like to buy something”, “who do I talk to about pricing?”). Each intent edge is its own independent yes/no check.
3. Combinators — All of (AND) / Any of (OR) / Not — nest the above into one condition, e.g. all of [caller intent is “support”, vars.tier equals pro].
Which edge wins
Section titled “Which edge wins”When the call reaches a branch, the edges are checked in order, and:
- The first edge whose condition matches is taken.
- If no condition matches, the edge marked “else” / fallback is taken.
- With no else edge either, an unconditional edge (one with no condition) is used if present.
A branch with no matching edge at all is a dead end: the caller is routed to the agent’s Fallback destination (Behavior tab), or the call ends if none is set. Always give a branch an else edge.
Strict routing mode
Section titled “Strict routing mode”The agent’s Routing mode (Behavior tab) has two settings:
- Flexible (default) — AI-generated Say lines and AI-intent conditions are allowed.
- Strict — deterministic only. Every Say must be fixed text and every condition explicit (compare/regex); saving a strict agent whose flow still contains an AI Say node or an AI-intent edge is rejected with the offending node/edge named. At call time, anything ambiguous falls to the else edge instead of the AI guessing.
Strict mode is for flows where predictability beats flexibility — compliance scripts, DTMF menus, regulated disclosures. Strict agents show a Strict badge on the agents list.
A worked example: reception flow
Section titled “A worked example: reception flow”A small front-desk flow that greets, captures a name, and routes by intent:
Start └─ Say (fixed): "Thank you for calling {{company_name}}." └─ Collect → variable: name prompt: "May I have your name?" └─ Collect → variable: reason prompt: "Thanks {{vars.name}} — are you calling about sales, or do you need support?" └─ Branch ├─ edge: Caller intent (AI) │ question: "does the caller want sales?" → Transfer 7001 (sales) ├─ edge: Compare — vars.reason contains "support" → Transfer 7002 (support) └─ else edge → Say (fixed): "Let me take a message." └─ Collect → variable: message └─ Say (AI): "Confirm you noted {{vars.message}} and say goodbye." └─ Hang upThings to notice:
{{vars.name}}collected in the second node is spoken back in the third node’s prompt.- The branch mixes an AI-intent edge (sales can be phrased any way) with a deterministic edge (
contains "support") and ends with an else edge, so no caller hits a dead end. - The closing Say is AI-generated — a natural goodbye — while the greeting is fixed text.
Pair this with the agent’s Data & Recording tab to extract name / reason / message into structured fields after the call and deliver them to email, Slack, Teams, or a webhook.
When changes go live: Save vs Apply Changes
Section titled “When changes go live: Save vs Apply Changes”Two different systems are involved in getting a call to your agent, and they update at different times:
- Agent config — live on Save. The platform reads the agent’s saved configuration fresh at the start of every call. Greeting, persona prompt, voice, flow graph, timing knobs, fallback: click Save changes and the very next call uses them. There is no Apply step for the agent itself.
- Routing — staged until Apply. Which phone number rings which destination is PBX configuration. Pointing an inbound route at your agent (or away from it) is staged when you save the route and pushed to your phone system only when you press Apply Changes — the banner shown on Nova pages. Until then, calls keep following the previous routing.
Symptom-to-cause:
| Symptom | Cause |
|---|---|
| ”I reworded the greeting but callers hear the old one” | Agent not saved — wording is live on the next call after Save changes |
| ”I pointed a number at the agent but calls still go to the old destination” | Routing staged but not applied — press Apply Changes on a Nova page |
| ”I saved the agent and now Nova shows an unapplied-changes banner” | Normal — the agent’s conversation behavior is already live; Apply pushes the PBX-level sync |
Related pages
Section titled “Related pages”- AI Voice Agents — the agents list, lifecycle, import/export, routing patterns.
- Building & Editing Agents — every tab and field in the builder.
- Connections — credentials for Tool call / HTTP action nodes.