This page documents multi-agent orchestration constructs (DELEGATE, HANDOFF, ESCALATE, COMPLETE) and the SUPERVISOR: declaration for top-level routing.
SUPERVISOR Declaration
A Supervisor is a top-level orchestrator that routes user messages to the appropriate child agent based on intent, context, and declarative rules. Supervisor documents use the SUPERVISOR: keyword instead of AGENT: and define agent references, routing rules, state schemas, policies, and communication settings.
Overview
While agents handle domain-specific tasks, the Supervisor decides which agent should handle each user message. It does not execute tools or gather information directly; it classifies intent and routes accordingly.
SUPERVISOR: Travel_Supervisor
VERSION: "2.0"
DESCRIPTION: "Routes customers to booking, support, or sales specialists"
GOAL: "Route requests to the right specialist with full context preservation"
PERSONA: |
Professional travel booking assistant. Friendly, efficient, and helpful.
Routes requests quickly and transparently.
Agent references
The Supervisor declares which agents are available for routing. Each reference includes a file path, an alias, and a list of capabilities.
Syntax
AGENTS:
- REF: ./agents/flight_search.agent.abl
ALIAS: Flight_Search
CAPABILITIES: [flight_booking, fare_search, seat_selection]
CHANNELS: [web, mobile, voice]
REQUIRES_VALIDATION: false
- REF: ./agents/support.agent.abl
ALIAS: Support_Agent
CAPABILITIES: [booking_management, cancellation, refund]
REQUIRES_VALIDATION: true
Agent reference properties
| Property | Type | Required | Default | Description |
|---|
REF | string | Yes | — | File path to the agent’s ABL definition. |
ALIAS | string | Yes | — | Local name used in routing rules and handoff targets. |
CAPABILITIES | string[] | Yes | — | List of capability tags describing what the agent can do. |
CHANNELS | string[] | No | — | Channels this agent supports (for example. web, mobile, voice). |
REQUIRES_VALIDATION | boolean | No | false | Whether the user must be authenticated before routing to this agent. |
Routing rules
Routing rules define conditional logic for directing messages to agents. Rules are evaluated in priority order.
Syntax
ROUTING:
- NAME: escalation_route
DESCRIPTION: "Route frustrated or explicitly requesting human"
PRIORITY: 1
WHEN: intent.category == "escalation" OR user.frustration_detected == true
THEN: ROUTE_TO Live_Agent_Transfer
FLAGS: [set_active]
- NAME: booking_route
PRIORITY: 5
WHEN: intent.category == "new_booking"
THEN: ROUTE_TO Sales_Agent
Alternatively, routing can be declared using the HANDOFF: block within a Supervisor, following the same syntax as agent handoffs:
HANDOFF:
- TO: Sales_Agent
WHEN: intent.category == "new_booking"
CONTEXT:
pass: [search_context, user_preferences, budget]
summary: "User looking to book new travel"
EXPECT_RETURN: false
Routing rule properties
| Property | Type | Required | Default | Description |
|---|
NAME | string | Yes | — | Unique name for the routing rule. |
DESCRIPTION | string | No | — | Human-readable description. |
PRIORITY | number | Yes | — | Evaluation order. Lower values are evaluated first. |
WHEN | string | Yes | — | Condition expression that must be true for this rule to activate. |
THEN | RoutingAction | Yes | — | Action to take. See Routing actions. |
FLAGS | string[] | No | — | Behavioral flags. See Routing flags. |
CONSTRAINTS | object | No | — | Additional constraints on when this rule applies. |
Routing actions
| Action | Syntax | Description |
|---|
| Route to agent | ROUTE_TO Agent_Name | Send the message to a specific agent. |
| Route to user | ROUTE_TO_USER "message" | Send a message and wait for user input. |
| Route by variable | ROUTE_TO_VARIABLE var_name | Route to the agent named in a variable. |
| Intent-based routing | INTENT_MATCH | Route based on detected intent. See below. |
| End conversation | END_CONVERSATION | End the session. |
| System action | SYSTEM_ACTION action_name | Execute a system-level action (for example. handoff). |
Intent-based routing
For more granular routing, use INTENT_MATCH with intent-to-agent mappings:
ROUTING:
- NAME: intent_router
PRIORITY: 10
WHEN: true
THEN:
INTENT_MATCH:
- INTENTS: [flight_search, hotel_search]
ACTION: ROUTE_TO Sales_Agent
- INTENTS: [manage_booking, cancel_booking]
ACTION: ROUTE_TO Support_Agent
FALLBACK: ROUTE_TO Fallback_Handler
Routing flags
| Flag | Effect |
|---|
set_active | Mark the target agent as the active agent for subsequent messages. |
silent | Route without sending a user-visible message. |
no_log | Do not log this routing decision in the trace store. |
priority_boost | Apply a priority boost in the target agent’s queue. |
Conditional routing (WHEN clauses)
WHEN clauses use the same expression syntax as Expressions & functions. Common patterns include:
# Intent-based
WHEN: intent.category == "complaint"
# State-based
WHEN: user.is_authenticated == true AND intent.category == "manage_booking"
# Negation
WHEN: NOT intent.has_specific_request
# Compound
WHEN: intent.unclear == true OR intent.confidence < 0.5
# Variable check
WHEN: handoff_count >= 4
Routing constraint blocks
Add constraints to limit when a rule applies beyond the WHEN condition:
ROUTING:
- NAME: voice_only_route
PRIORITY: 3
WHEN: intent.category == "voice_action"
THEN: ROUTE_TO Voice_Agent
CONSTRAINTS:
channels: [voice]
requiresState: [user.is_authenticated]
ignoreIntents: [greeting, farewell]
| Constraint | Type | Description |
|---|
ignoreIntents | string[] | Intents that should not trigger this rule. |
channels | string[] | Channels where this rule applies (for example. [web, voice]). |
requiresState | string[] | State variables that must be set for this rule to activate. |
State schema
The Supervisor can declare a state schema that defines typed variables organized by namespace.
STATE:
user:
is_authenticated:
type: boolean
required: false
default: false
description: "Whether the user has been authenticated"
language:
type: string
required: false
source: user
system:
routing_failures:
type: number
required: false
default: 0
source: system
State variables follow the same VariableDefinition structure as agent variables, with the addition of namespace grouping.
State variable properties
| Property | Type | Required | Default | Description |
|---|
type | See Data types | Yes | — | Variable type. |
required | boolean | No | false | Whether the variable must have a value. |
default | any | No | — | Default value. |
description | string | No | — | Human-readable description. |
source | system, user , agent, computed | No | — | Origin of the variable value. |
updatedBy | string[] | No | — | List of agent aliases that can update this variable. |
Policies
Policies define high-level behavioral rules for the Supervisor, constraining what it is allowed and forbidden to do.
POLICIES:
- NAME: no_direct_booking
DESCRIPTION: "Supervisor must not make bookings directly"
RULES:
forbiddenWhen: intent.category == "booking" AND active_agent IS NOT SET
behavior: "Route to Sales_Agent instead of handling directly"
- NAME: auth_required_for_account
DESCRIPTION: "Account operations require authentication"
RULES:
allowedWhen: user.is_authenticated == true
triggerSignal: "auth_required"
Policy properties
| Property | Type | Required | Default | Description |
|---|
NAME | string | Yes | — | Unique policy name. |
DESCRIPTION | string | No | — | Human-readable description. |
RULES | object | Yes | — | Policy rule definitions. See below. |
Policy rule properties
| Property | Type | Required | Default | Description |
|---|
allowedWhen | string | No | — | Condition under which the action is allowed. |
forbiddenWhen | string | No | — | Condition under which the action is forbidden. |
triggerSignal | string | No | — | Signal to emit when the policy is triggered. |
behavior | string | No | — | Description of the expected behavior when triggered. |
Communication settings
Communication settings define the Supervisor’s language, tone, and vocabulary preferences.
COMMUNICATION:
language: en
formality: neutral
pronouns:
use: "we"
avoid: "I"
vocabulary:
prefer: [assist, help, guide]
avoid: [unfortunately, regrettably]
constraints:
- "Never reveal internal agent names to the user"
- "Always explain why a transfer is happening"
Communication properties
| Property | Type | Required | Default | Description |
|---|
language | string | Yes | — | Primary language code (for example. en, es). |
formality | formal, informal, neutral | Yes | — | Communication tone. |
pronouns | object | No | — | Pronoun preferences (use and avoid). |
vocabulary | object | No | — | Preferred and avoided vocabulary. |
constraints | string[] | Yes | — | Communication behavioral constraints. |
Behavior settings
The BEHAVIOR block defines whether the Supervisor can respond directly to users or must always route to an agent.
BEHAVIOR:
canRespondDirectly: false
allowedDirectActions: [greet, clarify_intent]
forbiddenActions: [make_booking, process_payment, access_account]
| Property | Type | Required | Default | Description |
|---|
canRespondDirectly | boolean | Yes | — | Whether the Supervisor can send messages directly to users. |
allowedDirectActions | string[] | No | [] | Actions the Supervisor can perform directly. |
forbiddenActions | string[] | No | [] | Actions the Supervisor must never perform. |
Intents
In addition to INTENT_MATCH inside a routing rule, a Supervisor may declare a top-level INTENTS:
block listing intent labels (and optional lexical-fallback behavior) that routing and classification
draw on. Supervisors can also hand off to other supervisors, enabling hierarchical composition,
and may declare an ON_ERROR block to handle routing failures.
Execution pipeline (pre-classification)
This is an advanced, opt-in optimization. Most supervisors do not need it — routing works without
an EXECUTION block.
A Supervisor can enable a pre-classification pipeline that runs a smaller, faster model before the
main reasoning LLM. The classifier detects user intent and can short-circuit routing for obvious
cases, avoiding the cost of a full reasoning call.
SUPERVISOR: Support_Router
EXECUTION:
model: claude-sonnet-4-5-20250929 # main reasoning model
pipeline:
enabled: true
mode: sequential # 'parallel' | 'sequential'
shortCircuit:
enabled: true
confidenceThreshold: 0.85
toolFilter:
enabled: true
maxTools: 6
keywordVeto:
enabled: true
keywords: [reset, cancel, undo]
intentBridge:
enabled: true
programmaticThreshold: 0.85
guidedThreshold: 0.5
outOfScopeDecline: true
multiIntentSignal: true
HANDOFF:
- TO: Billing_Agent
WHEN: intent.category == "billing"
- TO: General_Inquiry
WHEN: true
The classifier model is not selected in the agent’s EXECUTION.pipeline block — it is resolved
from project-level runtime configuration via modelSource (default uses the platform’s
tool-selection model; tenant uses a specific tenant model identified by tenantModelId). A
model: key inside the pipeline block is deprecated and ignored by the runtime. The top-level
EXECUTION.model still sets the main reasoning model as usual.
Pipeline options
| Option | Type | Default | Description |
|---|
enabled | boolean | false | Enable the pre-classification pipeline. |
mode | string | parallel | parallel — classifier and main LLM run simultaneously; sequential — classifier runs first, main LLM only if no short-circuit. |
shortCircuit.enabled | boolean | true | Allow direct routing when classifier confidence is high. |
shortCircuit.confidenceThreshold | number | 0.85 | Minimum confidence to skip the reasoning loop. |
toolFilter.enabled | boolean | true | Filter tools to only relevant ones before reasoning. |
toolFilter.maxTools | number | 6 | Maximum tools passed to the reasoning loop. |
keywordVeto.enabled | boolean | true | Prevent short-circuit when the user mentions local tool keywords. |
keywordVeto.keywords | string[] | [] | Additional keywords that veto short-circuit routing. |
intentBridge.enabled | boolean | true | Bridge classifier intent into routing decisions. |
intentBridge.programmaticThreshold | number | 0.85 | Confidence at/above which intent routing is applied programmatically. |
intentBridge.guidedThreshold | number | 0.5 | Confidence at/above which intent is offered to the model as guidance. |
intentBridge.outOfScopeDecline | boolean | true | Decline out-of-scope requests detected by the classifier. |
intentBridge.multiIntentSignal | boolean | true | Signal when the message contains multiple distinct intents. |
For pure routing supervisors, sequential mode with shortCircuit.enabled: true gives the best
cost savings. In parallel mode the classifier adds latency protection but no cost savings, since
both calls run regardless.
HANDOFF
HANDOFF transfers conversational control from the current agent to another agent, passing context and optionally expecting a return.
Syntax
HANDOFF:
- TO: Compliance_Officer
WHEN: sanctions_clear == false
PRIORITY: 0
CONTEXT:
pass: [customer_id, beneficiary_name, amount, sanctions_match_score]
summary: "Wire flagged during sanctions screening (score: {{sanctions_match_score}})."
history: full
memory_grants:
- path: user.compliance_notes
access: readwrite
EXPECT_RETURN: true
ON_FAILURE: ESCALATE
ON_RETURN:
action: continue
map:
compliance_decision: sanctions_clear
review_notes: compliance_review_notes
Properties
| Property | Type | Required | Default | Description |
|---|
TO | string | Yes | — | Target agent name. |
WHEN | string | Yes | — | Condition that triggers the handoff. |
PRIORITY | number | No | — | Evaluation priority. Lower values are evaluated first when multiple handoff rules match. |
CONTEXT | object | Yes | — | Context to pass to the target agent. See Context. |
EXPECT_RETURN | boolean | Yes | false | Whether control should return to this agent after the target completes. RETURN is accepted as a backward-compatible alias. |
ON_FAILURE | string / object | No | — | Parent-side fallback for setup or dispatch failures before the target accepts the handoff. See Handoff failure strategies. |
ON_RETURN | string / object | No | — | How to handle the target returning control. See Return expectations. |
EXPERIENCE_MODE | string | No | — | End-user experience when the transfer happens. See Experience modes. |
REMOTE | object | No | — | Remote agent configuration. Can also be expressed as top-level LOCATION/ENDPOINT/PROTOCOL keys. See Remote agent support. |
ASYNC | boolean | No | false | Use async dispatch with push notifications for remote agents. |
ASYNC_TIMEOUT | number | No | — | Timeout in seconds for async handoff. (Also accepted as TIMEOUT.) |
The primary keyword is EXPECT_RETURN. The older RETURN keyword is still parsed for
backward compatibility, but new agents should use EXPECT_RETURN. The legacy top-level MAP
block is superseded by ON_RETURN.map (see Return expectations).
Handoff context
The CONTEXT block defines what information the target agent receives.
| Property | Type | Required | Default | Description |
|---|
pass | string[] | Yes | — | Session variable names to include in the handoff context. |
summary | string | Yes | — | Human-readable summary of why the handoff is occurring. Supports {{}} interpolation. |
history | string / object | No | auto | Conversation history strategy. See History strategies. |
memory_grants | object[] | No | — | Persistent memory paths to grant the target agent access to. See Memory grants. |
The legacy grant_memory: [path, ...] form is no longer supported and produces a parse
error. Use memory_grants with explicit path/access entries instead (see
Memory grants).
CONTEXT may also be expressed as a shorthand where pass, summary, and history appear as
direct siblings of the handoff entry rather than nested under CONTEXT:.
History strategies
The history property controls how much conversation history the target agent receives.
| Value | Behavior |
|---|
auto | Platform default. Uses the handoff summary when available; otherwise passes a bounded recent transcript. Usually you can omit history entirely. |
none | No conversation history is passed. The target agent starts fresh. |
summary_only | Only the summary text is passed, no raw messages. |
full | The complete conversation history is passed. |
{ mode: last_n, count: <n> } | The last N messages are passed. |
CONTEXT:
pass: [customer_id, amount]
summary: "Customer needs fraud review."
history:
mode: last_n
count: 10
The legacy shorthand history: last_10 is still accepted during the compatibility window, but
new agents should use the typed mode + count block.
Return expectations
When EXPECT_RETURN: true, the calling agent pauses and waits for the target agent to complete.
When the target explicitly returns control (via its built-in return capability), the parent resumes.
When EXPECT_RETURN: false, the handoff is a one-way transfer and the calling agent’s turn ends.
ON_RETURN controls what happens when the target returns. It accepts either a string (the name
of a named return handler, or a built-in action) or a structured block:
HANDOFF:
- TO: Authentication_Agent
WHEN: user.is_authenticated == false
CONTEXT:
pass: [session_context]
summary: "User needs authentication"
EXPECT_RETURN: true
ON_RETURN:
action: continue # continue | resume_intent
handler: route_to_booking # optional: named RETURN_HANDLERS entry
resume_with: latest_session_user_utterance
map: # child result field -> parent variable
user_id: auth_result.user_id
auth_token: auth_result.token
set: # parent assignments after mapping
auth_summary: "Authenticated {{auth_result.user_id}}"
ON_RETURN properties
| Property | Type | Description |
|---|
action | string | Built-in resume behavior: continue (resume the parent’s current flow) or resume_intent (re-run routing against the original user intent with the returned context). |
handler | string | Name of a named return handler declared in the top-level RETURN_HANDLERS: block. |
resume_with | string | Which utterance to replay when resuming. One of original_handoff_utterance, latest_child_user_utterance, latest_session_user_utterance, forwarded_return_message. |
map | Record<string,string> | Copies child return fields into parent variables (child key → parent variable). |
set | Record<string,string> | Parent assignments applied after map, using the same templated assignment shape as flow ON_RESULT branches. |
Return handlers
A top-level RETURN_HANDLERS: block declares reusable named handlers that run on the parent after a
EXPECT_RETURN: true child returns. Reference one from ON_RETURN.handler.
RETURN_HANDLERS:
route_to_booking:
RESPOND: "You're verified — let's finish your booking."
CLEAR: [pending_auth_reason]
CONTINUE: true # leave the parent waiting for the next user turn
# RESUME_INTENT: true # or replay the parent's last user message
| Property | Type | Description |
|---|
RESPOND | string | Message to send when the handler runs. |
CLEAR | string[] | Session variables to reset after the child returns. |
CONTINUE | boolean | Leave the parent waiting for the next user turn. |
RESUME_INTENT | boolean | Replay the parent’s last user message through routing. |
Handoff failure strategies
ON_FAILURE defines a parent-side fallback for failures that occur before the target accepts the
handoff — for example target lookup, pre-transfer validation, or dispatch failures. It does not
replace the timeout path after an accepted returnable handoff, and it does not fire when a downstream
child later reports its own failure.
HANDOFF:
- TO: Specialist_Agent
WHEN: needs_specialist == true
CONTEXT:
pass: [user_id, query]
summary: "User needs specialist help"
ON_FAILURE: ESCALATE # CONTINUE | ESCALATE | RESPOND "message"
| Value | Behavior |
|---|
CONTINUE | Silently continue in the current agent. |
ESCALATE | Trigger human escalation. |
RESPOND "message" | Send a message and continue in the current agent. |
Experience modes
EXPERIENCE_MODE shapes how the transfer is presented to the end user. It is valid on both
HANDOFF and DELEGATE.
| Value | Behavior |
|---|
shared_voice_handoff | Voice channels — hand off while keeping a single shared voice experience. |
visible_handoff | The user is told the conversation is being transferred. |
silent_delegate | The sub-agent runs without a user-visible transfer. |
human_escalation | Present the transfer as an escalation to a human. |
Async dispatch
For remote agents, set ASYNC: true to dispatch the handoff asynchronously. The calling agent receives a notification when the remote agent completes rather than blocking.
HANDOFF:
- TO: External_Review
WHEN: requires_external_review == true
CONTEXT:
pass: [case_id, documents]
summary: "Documents require external review."
EXPECT_RETURN: true
REMOTE:
location: remote
endpoint: "https://review.partner.com/api/v1/submit"
protocol: a2a
ASYNC: true
ASYNC_TIMEOUT: 3600
Memory grants
Use memory_grants to give the target agent scoped access to specific persistent memory paths.
Without this, the target agent cannot read or write the parent’s persistent variables. Each grant
declares a path and an access level.
CONTEXT:
pass: [user_id, booking_reference]
summary: "User needs to authenticate to manage booking."
memory_grants:
- path: user.last_verified_at
access: read
- path: workflow.auth_token
access: readwrite
| Property | Type | Required | Default | Description |
|---|
path | string | Yes | — | Persistent memory path being granted. |
access | string | No | read | Access level: read or readwrite. |
DELEGATE
DELEGATE invokes a sub-agent synchronously, waits for it to complete, and maps the result back into the calling agent’s context. The sub-agent runs in its own scope and does not have direct access to the parent’s session variables.
Syntax
DELEGATE:
- AGENT: Sanctions_Screening
WHEN: beneficiary_name IS SET AND beneficiary_country IS SET
PURPOSE: "Screen beneficiary against OFAC SDN and EU sanctions lists"
INPUT:
name: beneficiary_name
account: beneficiary_account
country: beneficiary_country
RETURNS:
cleared: sanctions_clear
match_score: sanctions_match_score
USE_RESULT: "Block if match_score > 85. Proceed only if cleared."
TIMEOUT: "15s"
ON_FAIL: escalate
Properties
| Property | Type | Required | Default | Description |
|---|
AGENT | string | Yes | — | Name of the sub-agent to invoke. TO is accepted as an alias. |
WHEN | string | Yes | — | Condition that must be true for delegation to occur. |
PURPOSE | string | Yes | — | Description of why this delegation exists. Included in trace events. SUMMARY is accepted as an alias. |
INPUT | Record<string,string> | Yes | — | Input mapping. Keys are sub-agent parameter names; values are expressions from the parent’s context. PASS is accepted as an alias. |
RETURNS | Record<string,string> | Yes | — | Output mapping. Keys are sub-agent result fields; values are parent context variable names to write to. |
USE_RESULT | string | Yes | — | Instructions for interpreting the sub-agent’s result. |
MEMORY_GRANTS | object[] | No | — | Persistent memory paths to grant the sub-agent, each with path and access (read / readwrite). Same shape as handoff memory grants. |
TIMEOUT | string | No | — | Maximum time to wait for the sub-agent. Format: "Ns" (seconds). |
ON_FAIL | string, object | No | — | Action when the sub-agent fails or times out. See Failure strategies. |
EXPERIENCE_MODE | string | No | — | End-user experience for the delegation. See Experience modes. |
REMOTE | object | No | — | Remote agent configuration. Can also be given as top-level LOCATION/ENDPOINT/PROTOCOL keys. See Remote agent support. |
FAILURE_MESSAGE | string | No | — | Message to display when delegation fails. |
The INPUT block maps values from the parent agent’s session context into the sub-agent’s input parameters:
INPUT:
name: beneficiary_name # parent's beneficiary_name -> sub-agent's "name" parameter
account: beneficiary_account
amount: amount
The RETURNS block maps the sub-agent’s result fields back into the parent’s session variables:
RETURNS:
cleared: sanctions_clear # sub-agent's "cleared" field -> parent's sanctions_clear
match_score: sanctions_match_score
Delegate failure strategies
| Value | Behavior |
|---|
respond | Send a message and continue. Requires FAILURE_MESSAGE. |
continue | Silently continue without the sub-agent’s result. |
escalate | Trigger human escalation. |
retry | Retry the delegation. Accepts a count for max retries. |
Structured failure example:
ON_FAIL:
type: retry
count: 2
Remote agent support
DELEGATE supports invoking agents running on remote services. Add a REMOTE block to configure the connection.
DELEGATE:
- AGENT: External_Compliance
WHEN: amount > 10000
PURPOSE: "External compliance check for high-value transfers"
INPUT:
transaction_id: wire_reference
amount: amount
RETURNS:
approved: compliance_approved
USE_RESULT: "Proceed only if approved."
REMOTE:
location: remote
endpoint: "https://compliance.partner.com/api/v1/check"
protocol: a2a
auth:
type: bearer
timeout: "30s"
Remote properties
| Property | Type | Required | Default | Description |
|---|
location | local, remote | No | local | Whether the agent is co-located or remote. |
endpoint | string | No | — | URL for remote agent invocation. |
protocol | a2a , rest | No | — | Communication protocol. a2a for Agent-to-Agent, rest for REST API. |
auth | object | No | — | Authentication configuration. type is bearer or api_key; an optional header names the header to carry the credential. Credential values are resolved from runtime config / auth-profile resolution — never inlined in ABL. |
timeout | string | No | — | Override timeout for the remote call. |
LOCATION: remote is explicit and recommended, but the compiler also treats an ENDPOINT
without LOCATION as remote. The remote block can be authored either nested under REMOTE: or
as top-level LOCATION/ENDPOINT/PROTOCOL keys on the entry.
Parallel delegation (fan-out)
There is no FAN_OUT: section in ABL. Fan-out is a runtime capability, not an authored
construct — agents do not declare it directly.
When a single user message contains multiple distinct requests that need different specialists,
a supervisor’s runtime can dispatch them in parallel and then synthesize the branch results into one
unified response. This is exposed to the reasoning model as a built-in __fan_out__ system tool
(you never write this tool yourself) and is bounded to 2–5 sub-tasks per message.
Separately, when multiple DELEGATE entries have their WHEN conditions satisfied on the same
turn, the runtime can run those delegations concurrently. Each delegation runs in its own scope and
its RETURNS are mapped back into the parent context as it completes.
DELEGATE:
- AGENT: Sanctions_Screening
WHEN: beneficiary_name IS SET
PURPOSE: "Screen beneficiary"
INPUT:
name: beneficiary_name
RETURNS:
cleared: sanctions_clear
- AGENT: Fraud_Detection
WHEN: amount IS SET
PURPOSE: "Score fraud risk"
INPUT:
amount: amount
account: source_account
RETURNS:
score: fraud_score
ESCALATE
ESCALATE transfers the conversation to a human operator. It is designed for situations where the agent cannot or should not continue autonomously.
Syntax
ESCALATE:
triggers:
- WHEN: sanctions_screening_unavailable == true AND retry_count >= 2
REASON: "Sanctions screening service down. Compliance check cannot be bypassed."
PRIORITY: critical
TAGS: [compliance, service_outage]
- WHEN: user.wants_human_agent == true
REASON: "Customer requesting human specialist."
PRIORITY: medium
TAGS: [human_request]
context_for_human:
- customer_id
- customer_name
- amount
- conversation_history
routing:
connection: livechat
queue: "wire_operations_l2"
skills: [wire_transfer, compliance]
priority: 1
on_human_complete:
- IF human.resolved == true: COMPLETE
- IF human.needs_agent == true: HANDOFF to specified_agent
CONNECTOR_ACTION: create_servicenow_incident
Trigger properties
| Property | Type | Required | Default | Description |
|---|
WHEN | string | Yes | — | Condition that triggers escalation. |
REASON | string | Yes | — | Human-readable reason for the escalation. |
PRIORITY | string / number | No | medium | Priority level: low, medium, high, critical, or a non-negative integer. |
TAGS | string[] | No | — | Tags for routing and categorization in the human agent queue. |
SET | Record<string,string> | No | — | Session variable assignments applied when this trigger fires (key = value). |
PRIORITY is optional and defaults to medium. Note that ESCALATE inside an ON_ERROR handler
is not parsed — to escalate from an error handler use THEN: ESCALATE with REASON: "..."
instead of an inline ESCALATE: block.
Connector action
CONNECTOR_ACTION names a connector action to invoke for ITSM integration when the escalation
fires (for example, opening an incident in an external ticketing system). It is declared at the top
level of the ESCALATE block, alongside triggers, context_for_human, routing, and
on_human_complete.
Priority levels
| Level | Use case |
|---|
low | Non-urgent requests (for example. general feedback). |
medium | Standard requests (for example. customer asks to speak with a human). |
high | Urgent issues (for example. service outages, repeated failures). |
critical | Immediate attention required (for example. compliance violations, fraud). |
Context for human
The context_for_human block lists session variable names to include in the escalation package. The human agent sees these values in their interface.
context_for_human:
- customer_id
- customer_name
- source_account
- amount
- fraud_score
- conversation_history
You can also use structured context items with templates:
context_for_human:
- NAME: case_summary
TEMPLATE: "Customer {{customer_name}} requesting wire of {{amount}} {{currency}}"
INCLUDE: [fraud_score, sanctions_match_score]
Routing configuration
The routing block controls how the escalation is routed in the human agent system.
| Property | Type | Required | Default | Description |
|---|
connection | string | No | — | Human-agent connection/channel to route through. |
queue | string | No | — | Target queue name in the human agent system. |
skills | string[] | No | — | Required skills for the human agent. |
priority | number | No | — | Numeric routing priority for the queue entry. |
post_agent | string | No | — | What happens after the human agent finishes: return or end. |
Earlier drafts used skill_tags and priority_boost. The current runtime contract uses skills
and priority — the older keys are silently ignored. Additional advanced routing keys
(sub_type, named_agents, named_agent_options, agent_matching_conditions, voice,
flow_policy_ref / transfer_flow_policy_ref, provider_config) are also supported for
human-agent integrations.
Post-completion actions
The on_human_complete block defines what happens after the human agent finishes.
on_human_complete:
- IF human.resolved == true: COMPLETE
- IF human.needs_agent == true: HANDOFF to specified_agent
- IF human.needs_followup == true: CONTINUE
Each entry has a condition and an action. The action can be COMPLETE (end the conversation), HANDOFF (transfer to another agent), or CONTINUE (resume the current agent).
COMPLETE
COMPLETE defines the conditions under which the agent considers its task finished. Each completion condition specifies a WHEN expression and an optional response.
Syntax
COMPLETE:
- WHEN: confirmation_number IS SET AND transfer_status == "released"
RESPOND: |
Your wire transfer has been executed successfully.
**Confirmation:** {{confirmation_number}}
**Amount:** {{amount}} {{currency}}
**To:** {{beneficiary_name}}
**Estimated Arrival:** {{estimated_arrival}}
STORE: "wire_transfers"
- WHEN: transfer_status == "queued"
RESPOND: "Your wire has been queued for the next processing window."
Properties
| Property | Type | Required | Default | Description |
|---|
WHEN | string | Yes | — | Condition expression. The agent completes when this evaluates to true. |
RESPOND | string | No | — | Final message to the user. Supports {{}} template interpolation. |
STORE | string | No | — | Collection or path name to store the completion result for analytics. |
Rich content in completion
COMPLETE responses support voice configuration and rich content, the same as any RESPOND:
COMPLETE:
- WHEN: booking_confirmed == true
RESPOND: "Your booking is confirmed!"
VOICE:
ssml: "<speak>Your booking is confirmed!</speak>"
RICH_CONTENT:
MARKDOWN: |
## Booking Confirmed
| Detail | Value |
|--------|-------|
| Reference | {{booking_ref}} |
| Date | {{travel_date}} |
ACTIONS:
- id: view_itinerary
type: button
label: "View Itinerary"
Completion evaluation
Completion conditions are evaluated after every turn, in declaration order. The first matching condition triggers completion. If no condition matches, the agent continues the conversation.
Context Passing
Evaluation order across constructs
When multiple multi-agent constructs apply on the same turn, the runtime evaluates them in this order:
- ESCALATE triggers — checked first; critical safety and compliance.
- HANDOFF rules — evaluated by priority (lower first).
- DELEGATE conditions — evaluated in declaration order.
- COMPLETE conditions — checked last.
Complete Supervisor example
SUPERVISOR: Customer_Service_Hub
VERSION: "2.0"
GOAL: "Route customers to the right specialist"
PERSONA: |
Professional customer service coordinator. Routes requests
efficiently and preserves context across agent transfers.
HANDOFF:
- TO: Live_Agent
WHEN: intent.category == "escalation"
CONTEXT:
pass: [user_id, conversation_summary]
summary: "User requests human assistance"
EXPECT_RETURN: false
- TO: Sales_Agent
WHEN: intent.category == "new_booking"
CONTEXT:
pass: [search_context, preferences]
summary: "User looking to book"
EXPECT_RETURN: false
ESCALATE:
triggers:
- WHEN: routing_failures >= 3
REASON: "Multiple routing failures"
PRIORITY: high
ON_ERROR:
routing_failure:
RESPOND: "Let me connect you with someone who can help."
RETRY: 1
THEN: HANDOFF Live_Agent
COMPLETE:
- WHEN: handoff_successful == true
RESPOND: "I've connected you with the right specialist."
Related pages