FLOW: section adds structured execution steps to any agent. It defines a step-by-step execution graph where each step declares actions (collect information, call tools, respond, branch) and transitions to other steps.
Agents operate in reasoning mode by default, where the LLM autonomously decides actions based on the goal. Adding a FLOW: section gives an agent a structured step graph, with each step declaring whether it uses LLM reasoning or deterministic execution via the REASONING: toggle.
Flow structure
Basic syntax
Entry point
Theentry_point: property declares which step the flow begins at:
| Property | Type | Required | Default | Description |
|---|---|---|---|---|
entry_point | string | No | First step in the steps list | The step name where execution begins |
steps array.
Step list
Thesteps: array declares the ordered list of step names. While steps can transition to any other step (not just the next in order), the list establishes the canonical ordering:
Step definitions
Each step is defined as a named block underFLOW: with its properties indented:
Per-step REASONING toggle
Every step in aFLOW: section must declare REASONING: true or REASONING: false. This controls whether the step uses LLM reasoning or deterministic execution.
| Property | Type | Required | Default | Description |
|---|---|---|---|---|
REASONING | boolean | Yes | — | true for LLM-driven reasoning, false for deterministic execution |
Reasoning step properties
WhenREASONING: true, the following additional properties are available:
| Property | Type | Required | Default | Description |
|---|---|---|---|---|
GOAL | string | No | Agent-level GOAL: | Step-specific goal (overrides the agent’s goal for this step) |
AVAILABLE_TOOLS | string[] | No | All agent tools | Subset of agent tools available in this step |
EXIT_WHEN | string | No | none | Condition that ends the reasoning loop |
MAX_TURNS | number | No | 10 | Maximum reasoning turns before forced exit |
STEP_CONSTRAINTS | string[] | No | none | Constraints specific to this reasoning zone |
Validation rules:
- A step with
REASONING: truemust have either a step-levelGOALor an agent-levelGOAL:defined.- A step with
REASONING: falseshould not have aGOAL(it has no effect on deterministic steps).- A step with
REASONING: falseshould not haveAVAILABLE_TOOLS(useCALLto invoke tools deterministically).
Entry guards
TheWHEN: property on a step defines a condition that must be true for the step to execute. If the condition is false, the step is skipped:
| Property | Type | Required | Default | Description |
|---|---|---|---|---|
WHEN | string | No | none | Condition expression that must be true for the step to execute |
Attempt limiting
Steps can limit the number of times they execute (useful for retry loops):| Property | Type | Required | Default | Description |
|---|---|---|---|---|
MAX_ATTEMPTS | number | No | none | Maximum number of times this step can execute |
ON_EXHAUSTED | string | No | none | Step to transition to after max attempts exhausted |
Step actions
SAY / RESPOND
TheRESPOND: action sends a message to the user. It supports template interpolation with {{variable}} syntax:
PRESENT
ThePRESENT: action displays a formatted presentation before collection. It is used alongside GATHER: to show the user what has been collected so far:
GATHER in flow steps
Within a flow step,GATHER: uses a list syntax different from the top-level GATHER: section:
Multi-field collection
Collect multiple fields in a single step using theFIELDS: sub-block:
Flow gather field properties
Each field in a flowGATHER: supports these properties:
| Property | Type | Required | Default | Description |
|---|---|---|---|---|
required / optional value after name | boolean | No | true | Whether the field must be collected |
prompt | string | No | none | Question shown to the user |
type | string | No | "string" | Data type |
default | any | No | none | Default value |
validation | string | No | none | Validation expression |
infer | boolean | No | false | Allow LLM inference |
infer_confidence | number | No | 0.8 | Minimum inference confidence |
infer_confirm | boolean | No | true | Confirm inferred values |
extraction_hints | string[] | No | none | LLM extraction guidance |
range | boolean | No | false | Collect as range |
list | boolean | No | false | Collect as array |
activation | string | {when: string} | No | none | Activation mode |
depends_on | string[] | No | none | Field dependencies |
prompt_mode | "ask" | "extract_only" | No | "ask" | Prompt usage mode |
Strategy
TheSTRATEGY: property on a flow GATHER: block controls the collection approach:
| Value | Description |
|---|---|
llm | Use LLM to extract values from natural conversation |
pattern | Use pattern matching and extraction rules |
hybrid | Combine LLM and pattern matching |
CORRECTIONS
WhenCORRECTIONS: true, the user can naturally correct previously collected values without restarting the step:
COMPLETE_WHEN
TheCOMPLETE_WHEN: condition specifies when the gather step is considered complete:
CALL…WITH…AS
TheCALL: action invokes a tool. Use WITH: to pass parameters and AS: to bind the result to a variable:
| Property | Type | Required | Default | Description |
|---|---|---|---|---|
CALL | string | — | — | Tool name to invoke |
WITH | Record<string, string> | No | none | Key-value parameter mapping |
AS | string | No | none | Variable name to bind the tool result |
WITH parameters
TheWITH: block maps tool parameter names to values or variable references:
- Variable references:
amount(resolves the session variableamount) - Literal strings:
"domestic" - Expressions:
COALESCE(reference, "")
SET
TheSET: action assigns values to session variables:
variable = expression syntax. The expression is resolved at execution time and can reference:
- Literal values:
"pending",0,true,false - Variable references:
acctResult.balance - Function calls:
FORMAT_CURRENCY(amount, "USD"),COALESCE(value, "default"),ADD(a, b),SUB(a, b),ROUND(n, decimals) - Unique ID generation:
UNIQUE_ID(12) - Current timestamp:
NOW()
CHECK
TheCHECK: action evaluates a condition. If the condition is false, execution transitions to the ON_FAIL: step:
| Property | Type | Required | Default | Description |
|---|---|---|---|---|
CHECK | string | — | — | Condition expression to evaluate |
ON_FAIL | string | No | none | Step to go to if the condition is false |
CLEAR
TheCLEAR: action removes variables from the session context:
TRANSFORM
TheTRANSFORM: action filters, maps, sorts, and limits an array from the session context:
| Property | Type | Required | Default | Description |
|---|---|---|---|---|
SOURCE | string | Yes | — | Dot-path to the source array |
AS | string | Yes | — | Loop variable name |
INTO | string | Yes | — | Output variable name |
FILTER | string | No | none | Condition expression using the loop variable |
MAP | Record<string, string> | No | none | Field mapping expressions |
SORT_BY | string | No | none | Sort field and direction (asc or desc) |
LIMIT | number | No | none | Maximum number of items in the output |
Branching and control flow
THEN / ON_FAIL
The most basic branching:THEN: specifies the next step on success, and ON_FAIL: specifies the step on failure:
ON_RESULT
ON_RESULT: provides multi-way branching based on the result of a CALL: action. Each branch has an IF: condition, optional actions, and a THEN: transition:
ON_RESULT branch properties
| Property | Type | Required | Default | Description |
|---|---|---|---|---|
IF | string | No | — | Condition expression. Omit for ELSE branch. |
RESPOND | string | No | none | Message to display |
SET | Record<string, string> | No | none | Variable assignments |
CALL | string | No | none | Optional nested tool call |
THEN | string | Yes | — | Next step |
ELSE branch (a branch with no IF condition) matches when no other condition is true.
ON_SUCCESS / ON_FAIL
An alternative toON_RESULT: for simpler success/failure branching:
ON_SUCCESS: and ON_FAIL: support conditional branches:
ON_INPUT
ON_INPUT: provides branching based on user input, typically used after a GATHER: action:
Digressions
Digressions are intent-based escapes that can interrupt the current step. They match user intent patterns and respond accordingly:Digression properties
| Property | Type | Required | Default | Description |
|---|---|---|---|---|
INTENT | string | Yes | — | Intent pattern to match |
KEYWORDS | string[] | No | none | Explicit keywords for matching |
CONDITION | string | No | none | Additional condition to check |
RESPOND | string | No | none | Response message |
RESUME | boolean | No | false | Return to the current step after handling |
GOTO | string | No | none | Transition to a specific step |
DELEGATE | string | No | none | Delegate to another agent |
CALL | string | No | none | Tool to invoke |
CLEAR | string[] | No | none | Variables to clear |
RESUME: true, the user returns to the interrupted step after the digression response. When GOTO: is specified, the flow transitions to that step instead.
Global digressions
Digressions declared at the flow level (underglobal_digressions:) are available at every step:
Sub-intents
Sub-intents are scoped intents valid only within a specific step. They handle step-specific user requests like corrections or clarifications:Sub-intent properties
| Property | Type | Required | Default | Description |
|---|---|---|---|---|
INTENT | string | Yes | — | Intent pattern to match |
RESPOND | string | No | none | Response message |
CLEAR | string[] | No | none | Variables to clear (triggers re-collection) |
SET | Record<string, string> | No | none | Variables to set |
CALL | string | No | none | Tool to invoke |
RESUME | boolean | No | true | Stay in the current step |
Interactive actions
Flow steps can present interactive UI elements (buttons, selects, inputs) to the user. These are attached toRESPOND: messages and handled with ON_ACTION: callbacks.
Action elements
Interactive actions are defined in anACTIONS: block within a step:
Element types
Buttons
Select (dropdown)
Input fields
Action element properties
| Property | Type | Required | Default | Description |
|---|---|---|---|---|
id | string | Yes | — | Unique identifier for the action element |
type | "button" | "select" | "input" | Yes | — | Element type |
label | string | Yes | — | Display label |
value | string | No | none | Hidden value sent when the element is interacted with |
description | string | No | none | Subtitle or helper text |
options | {id, label, description?}[] | No | none | Options for select type |
inputType | "text" | "number" | "date" | "time" | "email" | No | "text" | Input field type (for input type) |
placeholder | string | No | none | Placeholder text (for input type) |
required | boolean | No | false | Whether the input is required (for input type) |
Form submission
When a step containsinput type elements, you can configure a form submission button:
ON_ACTION callbacks
TheON_ACTION: block defines handlers for user interactions with action elements:
ON_ACTION handler properties
| Property | Type | Required | Default | Description |
|---|---|---|---|---|
ACTION | string | Yes | — | The id of the action element that triggered this handler |
CONDITION | string | No | none | Optional value-based condition |
RESPOND | string | No | none | Response message |
SET | Record<string, string> | No | none | Variable assignments |
THEN | string | No | none | Step to transition to |
Rich content
Steps can include rich content in multiple formats alongsideRESPOND: messages. The runtime selects the appropriate format based on the channel:
Rich content format properties
| Format | Description |
|---|---|
MARKDOWN | Formatted markdown text |
ADAPTIVE_CARD | Microsoft Adaptive Cards JSON |
HTML | HTML content |
SLACK | Slack Block Kit JSON |
AG_UI | AG-UI / CopilotKit event JSON |
WHATSAPP | WhatsApp interactive message JSON |
Voice configuration
Steps can include voice-specific overrides for text-to-speech engines:| Property | Type | Description |
|---|---|---|
SSML | string | W3C SSML markup for TTS engines |
INSTRUCTIONS | string | Natural language voice style instructions |
PLAIN_TEXT | string | Voice-optimized plaintext (fallback for all engines) |
Step-level error handling
Steps can define local error handlers that override agent-levelON_ERROR: handlers:
Complete example
Related
- Language overview — syntax rules and auto-detection
- Tools — tool definitions used by
CALLactions - GATHER — top-level gather field definitions
- Agent declaration — GOAL used by
REASONING: truesteps,max_flow_iterationsand model settings