USE BEHAVIOR_PROFILE: <name>, and the compiler attaches the matching profile IR to that agent.
File contract
Behavior profile files belong inbehavior_profiles/ and should use the .behavior_profile.abl suffix:
behavior_profiles, while layers_included still uses core. Do’nt add behavior_profiles to layers_included.
The manifest entry is a pointer, not the profile definition. Import preview compiles the actual file at behavior_profiles.<name>.path. A package that only lists a profile in project.json but omits the referenced .abl file doesn’t create the profile; agents with USE BEHAVIOR_PROFILE: <name> will fail resolution with a missing profile diagnosis.
Grammar
WHEN evaluation context and timing
Session creation and pre-session policy checks evaluate metadata only:channel, caller, session, interaction, and env.
At runtime, the platform reevaluates profiles at each reasoning turn, agent activation, parent restoration, and cold session restoration boundary. These later evaluations also read the active session’s accepted expression values.
A declared memory INITIAL value can select a profile at the first runtime reevaluation. It does not select a business-state-dependent profile during the metadata-only creation check.
A SET, GATHER answer, or tool result becomes visible when the next existing evaluation boundary runs. It does not trigger an immediate profile reevaluation by itself.
session.is_new belongs to the creation check, while session.turn_count retains its reasoning-invocation count.
The runtime expression values include:
- Declared session memory
- Accepted GATHER fields
- Values saved by authored tool-result mappings
- The stamped current
input - The structured
intentobject, when present
Reference resolution at runtime reevaluation
Every ordinary accepted expression value is available directly and through
context. For example, customer_tier and context.customer_tier resolve to the same value, as do input and context.input.
Top-level channel, caller, and interaction retain profile metadata. Use context.channel, context.caller, and context.interaction for colliding business values.
Nested keys, including a business object’s own context property, remain ordinary accepted state.
Identifier references session_id, project_id, tenant_id, and user_id follow the existing expression projection: an accepted stored value wins, and the corresponding runtime identifier supplies a fallback when that value is absent. Adding an alias does not grant access to another session, project, or agent’s private state.
Conditions read session-visible config/env values. Secret values held exclusively for tool execution remain unavailable to conditions and their context aliases.
Tokenized PII comparisons use the active session’s comparator.
The evaluation map is not persisted or published as profile trace data, model instructions, or responses.
Missing references and invalid conditions skip the affected profile. They do not crash the session or become implicit string literals.
These expression values are comparison data, not authorization grants or proof of tenant/project ownership. Conditions use the accepted values; they do not classify text, synthesize intent, or fall back to older conversation history when input is absent.
Worked example
After an authored GATHER or tool mapping savescustomer_tier as "gold", WHEN: context.customer_tier == "gold" matches at the next runtime reevaluation. When the accepted value is "standard", the profile does not match. A channel predicate such as WHEN: channel.name == "voice" continues to read channel metadata even if a business field is named channel.
After a profile matches, its instruction overlay applies to the main reasoning prompt and reasoning
inside a FLOW step. The step keeps its own goal and constraints. This instruction projection does
not introduce another profile evaluation boundary.
Profile blocks
Beyond the required declarations, a profile can override several aspects of agent behavior. All blocks are optional.CONSTRAINTS
Adds business-rule constraints while the profile is active (a list of strings).RESPONSE
Shapes response rendering.VOICE
Voice (TTS) overrides while the profile is active. Accepts the full voice configuration —instructions, ssml, plain_text, provider, voice_id, speed, pace, temperature, and
auto_tts_language_switch.
TOOLS
HIDE: removes tools from the agent’s tool set; ADD: injects new tool definitions while the
profile is active.
CONVERSATION
CONVERSATION: is also a valid top-level agent section — an agent can declare it directly
(doc.conversation) with the exact same grammar shown here. Use the profile form to apply
conversation overrides conditionally (via the profile’s WHEN), or the top-level form to set an
agent’s baseline conversation behavior.speaking— output style:style,tone,emotion,pace,variety,max_sentences,one_thing_at_a_time,language_policy(interaction_context/agent_default/fixed),fixed_language,tool_lead_in,tool_results,readback,handoffs,phrases_ref,pronunciations_ref.listening— input handling:barge_in,backchannels,on_pause,on_overlap,on_unclear_audio,on_self_correction,use_audio_cues, and the voice sub-blockson_no_input,on_caller_backchannel,on_hold, andbarge_in_continuation(see Voice turn-taking).interaction— dialogue behavior:answer_shape,detail,initiative,grounding,clarification,confirmation,uncertainty,empathy,repair,context,closure,assumption_handling,flow_mode, and more.
Listening mode
On KoreVG pipeline voice, the listening mode is fixed for the whole call. Barge-in and streaming are decided for each spoken output, inside that mode. An agent or channel that authors none of these keys behaves as before.background. A sticky background gather listens during and after speech.turn_taking. Each agent turn is its own foreground gather that listens for the caller’s answer.- Resolution, most specific first. The channel’s explicit
listeningMode. The entry agent’sCONVERSATION.listening.mode, layered across behavior profiles and the agent. The derived mode:backgroundwhen the entry agent’slistening.barge_in(otherwiseon_overlap) allows interruption, or, when the agent sets neither, when the channel’s barge-in checkbox is on. Otherwiseturn_taking. - Fixed for the call. A handoff, a FLOW step, a reply or a tool cannot change the mode. A later agent’s
listening.modeis ignored. - No per-turn key.
LISTENINGin anyVOICEblock is the compile errorVOICE_LISTENING_CALL_LEVEL_ONLY. - Default barge-in. It comes from
listening.barge_in, otherwiselistening.on_overlap. Theon_overlapvaluesstop_and_listen,listen,yieldandyield_to_userallow. The valuesignore_overlap,continueandtalk_overdisallow.
CONVERSATION_BACKGROUND_DISALLOW_DEFAULT flags background with a default of disallow. CONVERSATION_BACKGROUND_ONLY_WITH_TURN_TAKING flags caller back-channel phrases or barge_in_continuation with turn_taking. A behavior profile that sets listening.mode gets the same two warnings.
An agent that sets listening.mode is published with the IR marker voice_listening_mode. A runtime without the marker refuses the agent. Per-output placements are described in Scoped barge-in, Voice delivery for a field and Voice reply policy.
Voice turn-taking
For voice/telephony channels, fourlistening sub-blocks control turn-taking behavior:
on_no_input — handle caller silence.
A no-input message can author
ssml as a string or a locale-to-string map, next to text:
- The compiler requires a well-formed XML
<speak>document. It rejects document declarations, processing instructions, and nested speech documents. - The speech provider checks voice and style availability.
- Values substituted into the markup are XML-escaped after output protection.
- When
textis absent, the runtime derives readable text from the rendered SSML for transcripts and for vendors without SSML delivery. - Azure pipeline voice plays the markup through buffered speech. Other vendors and realtime voice use the plain text.
exhausted_messagestays plain text.
- Recognized speech or speech barge-in resets the retry sequence. Accepted non-empty DTMF input also resets it. An ASR partial only restarts the silence window. It keeps the retry count until an answer is accepted, so partials that never commit (noise, abandoned speech) still exhaust the retries.
- Forwarded native voice activity detection (VAD) activity pauses the background silence window without resetting retries or accepting an answer. When the activity stops, the configured window starts again.
- DTMF barge-in stops the silence timer without resetting the retry sequence.
- A gather that receives no digits and no speech restarts the timer with the existing retry count. This includes a press of the finish key alone.
- A keypad-only gather, such as a secure card entry, never receives a speech end-of-speech timeout, whatever pause timeout the call has. Speech and mixed gathers keep it.
- The final line the caller hears before a hang-up is recorded in the Conversation as an assistant turn, like every reprompt. This covers the
exhausted_message, the fallback line when atransferhas no target, and the closing line of a flow target that could not run. If the voice gateway does not confirm that the line finished, the row is marked as playback unconfirmed. If only part of a long line played, it is also marked partial. A line the gateway never received is not recorded.
realtimeNoInputEnabled: false setting. A resolved configuration with an invalid value, such as a retry count outside 0 to 20, disables no-input handling for the session. Pipeline voice emits voice_no_input_config_dropped. Realtime voice reports a status_update with operation: no_input and source: invalid, or source: dynamic_unsupported when it rejects dynamic mode.
dtmf: set the default grouping of keypad digits for every KoreVG pipeline voice turn of the agent or profile. It takes the same keys as a FLOW field DTMF: block.
- Each key resolves on its own, in this order:
SECURE_INPUTCOLLECT, fieldDTMF:, active behavior profile, agent, project, platform default. The platform default is 2 seconds between key presses,#as the finish key, and 1 to 12 digits.digitscounts as one unit. - A project sets the same defaults in Studio (Settings > Runtime Config > Listening) or as Runtime Config
voiceListening.dtmf(minDigits,maxDigits,finishOnKey,interDigitTimeoutMs). SetminDigitsandmaxDigitstogether.voiceListening: nullclears the setting. - A minimum above 1 produces a warning at agent, profile, and project level. It applies to every keypad answer, including one-key menu choices. A pause does not end an entry shorter than the minimum, so the short entry is lost after the no-input timeout. Keep the minimum at 1 here and set a longer one on the fields that need it.
finishOnKey: "*"produces a warning at these levels, because*then ends every keypad answer, menus included.- A profile that turns on or off, a handoff, a return, or a language switch applies from the next caller turn. A profile that changes keypad settings on every turn restarts the listener every turn, so keep profile settings stable.
- An agent that uses these keys is published with the IR marker
voice_listening. A runtime without the marker refuses to publish, deploy, or run the agent, so upgrade every runtime first. Speech settings above field level (listening.asr) add the markervoice_listening_asr. A Studio import into a project whose runtime does not report this marker drops the speech block and reportsLISTENING_KEY_NEEDS_NEWER_RUNTIME.
on_caller_backchannel — recognize caller acknowledgements (“uh-huh”, “okay”) without treating them as a turn: enabled, phrases, max_words.
on_hold — handle caller hold requests (“hold on a sec”): enabled, phrases, phrases_by_locale, grace_ms, max_holds, suppress_response. phrases_by_locale is a { <BCP-47 tag>: string[] } map of additional hold phrases selected by the caller’s detected locale; its phrases are unioned with the language-neutral phrases list rather than replacing them. Locale keys are canonicalized at parse time (en_us → en-US).
phrases_by_locale is currently authored only in the .agent.yaml format (CONVERSATION.listening.on_hold.phrases_by_locale); the legacy .agent.abl parser does not yet accept this key.barge_in_continuation — when a caller barges in over the bot and the speech recognizer segments their continuous speech into multiple phrase-finals (for example “change to 2 years” then, without a real pause, “recalculate the EMI”), hold each eligible final briefly and merge a following one into a single turn instead of committing each phrase as its own turn.
barge_in_continuation refines what happens to an already-allowed interruption’s speech segmentation — it’s a sibling of, not a replacement for, the scalar barge_in: allow/disallow policy above, and distinct from the per-output scoped BARGE_IN covered in Scoped barge-in. A project-level default can be overlaid beneath this per-agent block.GATHER
Overrides gather behavior. Top-level keysvalidation_style and confirmation, plus a
FIELD_OVERRIDES: block (note the uppercase keyword) that adjusts individual fields.
FLOW
Overrides the agent’s flow while the profile is active.An inline
BEHAVIOR_PROFILE: declared inside an agent file (rather than as a standalone
document) supports only PRIORITY, WHEN, INSTRUCTIONS, and CONVERSATION. The other blocks
(CONSTRAINTS, RESPONSE, VOICE, TOOLS, GATHER, FLOW) are available only in standalone
profile files.Agent attachment
BEHAVIOR_PROFILE: header, not just the filename. Both
USE BEHAVIOR_PROFILE: (space) and USE_BEHAVIOR_PROFILE: (underscore) forms are accepted.
Where profiles apply
A profile attached at agent level applies to every model call the agent makes. That includes each turn of a reasoning agent and eachREASONING: true step of a FLOW agent.
In a FLOW reasoning step, the matched profiles’ INSTRUCTIONS, CONSTRAINTS, VOICE instructions (voice channels), and CONVERSATION (when a matched profile sets it) are added to the step prompt. They come before the step’s own GOAL, BEHAVIOR, and STEP_CONSTRAINTS, which take precedence for that step. A FLOW agent with no matching profile gets no profile text in its steps. Literal RESPOND text in a REASONING: false step is sent as written.
A flow step has no profile or persona setting of its own. The compiler ignores these and reports warning W498:
- A
USE BEHAVIOR_PROFILE:orPERSONA:line inside a step, inFLOW:or in legacySTEPS:. - A
personaoruse_behavior_profilekey on a YAML flow step.
WHEN to target channels, callers, or languages. Use the step GOAL, BEHAVIOR, STEP_CONSTRAINTS, AVAILABLE_TOOLS, and step VOICE block for step-specific behavior.
Compile and import behavior
During import preview, the platform:- Reads
project.jsonandabl.lock. - Categorizes
behavior_profiles/<name>.behavior_profile.ablas part of thecorelayer. - Parses the profile with the canonical ABL parser.
- Compiles profiles before agents.
- Resolves every
USE BEHAVIOR_PROFILEreference against compiled profile names. - Reports missing or malformed profiles as import/compiler issues.