{{}} interpolation syntax), see Expressions and functions.
Rich content
ABL supports multi-format output for delivering responses across different channels (web, mobile, voice, messaging platforms). TheVOICE:, RICH_CONTENT:, and ACTIONS: blocks can be attached to any RESPOND statement, COMPLETE condition, or lifecycle handler. A pure reasoning agent (no FLOW:) may also declare top-level RICH_CONTENT: and ACTIONS: blocks that attach to its generated responses.
Overview
A single response can include:- Plain text — the default
RESPONDstring. - Voice configuration — SSML markup or natural language voice instructions.
- Rich content — Markdown, Adaptive Cards, HTML, Slack Block Kit, WhatsApp, or AG-UI.
- Carousels — scrollable card collections with images and buttons.
- Interactive actions — buttons, select menus, and input fields.
- Templates — reusable named response definitions with interpolation.
Voice configuration
Voice configuration provides channel-specific voice output. TheVOICE: block can appear alongside any RESPOND.
Syntax
Voice properties
SSML example
Natural language instructions
For voice platforms that accept style instructions rather than SSML:Rich content formats
The rich-content block provides format-specific variants of a response. The runtime selects the variant matching the delivery channel.RICH_CONTENT: is the canonical block keyword; FORMATS: is the original spelling, kept as an accepted alias. The .agent.yaml format accepts rich_content: or formats: the same way. Most places a rich-content block is authored — directly under a RESPOND: (in a flow step, ON_START, HOOKS:, or an ON_ACTION/ON_ERROR handler), in a tool’s on_result:/on_error: action block, and in a COMPLETE: condition (including one with no RESPOND: at all) — accept either spelling interchangeably.Syntax
Rich content properties
Channel-specific string formats:
Structured template formats (channel-neutral; the runtime renders them per channel):
Named templates (in the
TEMPLATES: block) may also declare a RENDERABLES: list — customer-owned structured payloads with name, payload, optional targets (api/sdk_websocket/http_async), fallbackText, and schemaRef. Data-rich templates (KPI, TABLE, CHART, LIST, CAROUSEL, …) also support collection binding via from: / template: to render one entry per array item.Template modifiers
Two cross-cutting modifiers apply to structured templates:when— a conditional render guard (expression). On an agent-level rich-content block, the template renders only when the expression is truthy at reasoning finalization. Available on the rich-content block and on each structured template. See Expressions and functions for expression syntax.adaptive— onLIST,KPI, andTABLEtemplates whose items/rows are bound to a tool variable, setadaptive: trueto let the reasoning agent narrow which items/rows/columns render for the user’s request.
FEEDBACK surveys
AFEEDBACK block renders a rating/feedback card. Author it inside a RICH_CONTENT: (or FORMATS:) block.
Referencing a survey template
SetFEEDBACK_TEMPLATE to a project survey name. The prompt and type (the survey’s measure) then come from the template, so they become optional here; any copy fields you do set act as per-string overrides (useful for translation):
type, max, scoring, range, and comment_threshold are owned by the template, and setting them alongside a template is a compile error. Naming a template that doesn’t exist in the project is an error (UNKNOWN_SURVEY_TEMPLATE).
expires_after is the one exception to that rule — a numeric answer-window TTL (in seconds) that is overridable per-agent even when a template is referenced:
expires_after if set, else the template’s own TTL, else a 300-second platform default — clamped to 30–86400 seconds either way. A survey presented to the customer can only be answered within this window; a submission after it expires is rejected.
Inline FEEDBACK (deprecated)
Without a template,prompt and type are required:
Condition-based wording (<field>_rules)
To vary wording by condition — the second way to translate a survey, kept next to the source copy — add a <field>_rules list. Each rule has a when expression and the field’s replacement text (the field key, or the alias value). Rules are ordered, first match wins:
prompt, submit_label, pending_message, success_message, error_message, comment_prompt, comment_placeholder. There is no type_rules/max_rules — the measure is never rule-selectable.
Copy rules are evaluated before the customer answers, so a
when expression may reference max, language, channel, and session (as session.<name>) but not rating. An invalid condition is a compile error (INVALID_SURVEY_CONDITION).Carousels
Carousels display a horizontal scrollable collection of cards, each with a title, subtitle, image, and action buttons.Syntax
Carousel card properties
Interactive actions
Interactive actions add buttons, select menus, and input fields to a response. Users interact with these elements, and the agent handles the interactions viaON_ACTION blocks.
Syntax
Action element properties
Select element example
Input element example
Form submission
When theACTIONS block contains input elements, you can specify a submitLabel and submitId for the form submission button:
ON_ACTION handlers
Handle user interactions with action elements in flow steps:ON_ACTION handler properties are described below.
If a handler
RESPOND includes rich FORMATS: before terminal routing, that payload is forwarded as the fallback final channel payload. The terminal target’s own rich payload takes precedence.
Reusable handlers (ACTION_HANDLERS:)
ON_ACTION inside a flow step handles actions for that step only. To define reusable action handlers available across the whole agent, declare a top-level ACTION_HANDLERS: section. Each entry is keyed by the action element id and uses the same grammar as ON_ACTION (an optional CONDITION, shorthand RESPOND/SET/TRANSITION, or a canonical DO: block of ordered actions — SET, CLEAR, LOG, RESPOND, CALL, GOTO/TRANSITION/THEN, HANDOFF, DELEGATE, COMPLETE).
Templates
Templates are named, reusable response definitions declared in theTEMPLATES: block. They support {{}} interpolation and multi-format variants.
Syntax
Template properties
Referencing templates
UseTEMPLATE(name) in any RESPOND value:
Template interpolation
Template bodies use the same{{variable_name}} interpolation and {{#if variable}}...{{/if}} conditional-section syntax as any other ABL string — see Template strings in Expressions and functions for the full syntax, including calling built-in functions inside {{}}.
Channel selection
The runtime selects the response format based on the delivery channel.
If the preferred format isn’t available, the runtime falls back through the priority chain until it finds a defined format. Plain text (
RESPOND) is always the final fallback.
Related articles:
- Expressions and functions — operators, built-in functions,
{{}}template-string syntax, and type coercion rules - Lifecycle and hooks — ON_START and hooks that support rich content
- Multi-Agent and supervisor — COMPLETE conditions with rich responses
- Data Types and utilities — types used in rich content and template fields