Conversation flows
A conversation flow is an AI agent’s in-conversation routing map. Attach one under an agent’sconfig.conversation_flow and every turn picks an active node whose instructions replace the single static base system prompt that turn — instead of relying on one prompt for the whole conversation. This is the multi-state routing model most operators know from voice agents, available on any chat or voice agent in Orbit.
Classic Flows route contacts through channel automations (send, delay, branch, run an agent). A conversation flow routes the conversation itself between named states once the agent has taken over.
Concept
- Each node carries its own
instructions— the per-state prompt that becomes the active prompt segment while that node is selected. - Edges carry routing conditions evaluated against the customer’s latest message (first match wins).
- When no condition matches, the turn either falls through a node’s unconditional edge or stays on the current node — the conversation never resets mid-flow.
- A flat routing preamble is prepended ahead of your base persona/policy prompt: “This agent is a multi-state conversation flow. Stay on the ACTIVE NODE’s instructions; branch to one of the fallback nodes only when the customer’s message matches its condition.” — the base prompt stays in place below it.
Graph anatomy
The persisted shape, stored verbatim inconfig.conversation_flow:
Conditions
A condition is matched case-insensitively against the customer’s latest message, in one of three shapes:
An edge with a missing or empty condition is unconditional — it is the node’s fallback branch, taken only when no condition edge fires. A
/pattern/flags string that fails to compile is treated as a keyword list instead, so a bad regex cannot stall routing.
The evaluation order per turn: walk the active node’s edges in declaration order; the first condition that matches wins. If nothing matches, take the unconditional edge if one exists; otherwise stay on the active node.
Fallbacks
fallbacks names nodes the model may branch to when the active node itself has no answer. Fallback entries that name the entry node are deduplicated away. The composed system prompt lists fallbacks explicitly as [FALLBACKS — branch ONLY when one of these matches] with their instructions plus routing conditions, so the model can swap states mid-conversation without inventing a node that is not on the graph.
Validation contract
Save validation rejects the dangerous classes up front, with one issue per path so the API error names exactly which edge or fallback is wrong:- Duplicate node ids —
nodes—Duplicate conversation-flow node id…. entrythat names a node not on the graph —entry.- An edge whose
tonames an unknown node —nodes[i].edges[j].to. - A fallback id that names an unknown node —
fallbacks.
nodes array, a number where a string belongs, or a malformed edge) is not fatal at run time. The executor re-validates the blob when it builds the turn, treats any failure as undefined, and the agent runs exactly as it did before flows existed — on its base system prompt alone. A bad save can never block a customer-facing turn; at worst, the routing layer disappears until the config is corrected.
Versioning & experiments
The flow graph is versioned through agent versions and A/B experiments:- Bump
versioninconfig.conversation_flow(2, 3, …) for a meaningful revision. - Save an agent version snapshot (
POST /agents/:id/versions) — the snapshot captures the whole agent config, including the flow blob. - Run that candidate as an experiment variant; the variant’s snapshot carries
conversation_flowverbatim, so the experiment pins a specific flow revision and an A/B winner promotes the candidate’s flow along with its prompt.
Deterministic replay
Every turn replays the flow from theentry node over the conversation’s user messages (chronological order, current turn appended). Resolution is deliberately stateless — no per-pod map, no shared cache — so:
- Any replica recomputes the identical active node for a given history.
- Both turn paths —
runandstreamTurn— produce the same routing. - Voice and chat agents share branch semantics: the same graph routes a phone call and a chat session the same way.
entry, so a conversation does not reset mid-flow.
Testing a route before you send
The same logic powers a simulate step: pick an active node, supply a hypothetical customer message, and resolve which node would activate — without mutating any conversation state. Prove a branch set before traffic ever sees it.Dashboard surface
Two editors in the dashboard are built around conversation flows:- Agent Studio (
/agents/studio) — the visual canvas where you draw nodes, drag edges, and edit per-node instructions with their conditions. The same graph is what save-validation and the runtime executor consume. - Conversations (
/agents/conversations) — per-conversation transcripts. When an agent has a flow attached, the transcript shows the same deterministic routing the executor used, so a mis-routed branch is inspectable per turn against the customer’s message.
Worked examples
Billing / tech triage
The overview-page sketch expanded into a complete graph — an unconditional edge plus one fallback keeps the agent on the rails when the customer mentions something outside both intents:invoice fires on the first edge, the turn runs on billing. “The app keeps crashing” — the tech regex fires, the turn runs on tech. “What are your hours?” — no condition matches, the triage node has no unconditional edge, so the conversation stays on triage; the model can still use the general fallback.
Escalation with fallbacks
An escalation graph where unresolved or unhappy customers move to an escalation node with an explicit human-handoff fallback:escalation. “I’ll file a chargeback” — the high-stakes regex fires. Anything else stays on support; the unconditional fallback pool still offers escalation when the support node itself cannot answer.
See also
- Flows overview — channel-facing flows that trigger an agent, versus the in-conversation routing this page covers.
- Creating agents — the base agent config the flow attaches to.
- Agent versions — snapshots that pin a flow revision.
- Continuous production evals — graded replays against a pinned version.