Concept
AHANDOFF route can test any value in the session data. Write the test as an expression in WHEN. The platform evaluates it without the model, and it refuses the route when the expression is false.
Context routing differs from intent routing in one way. The classifier does not run when the supervisor has no intent.category condition and no INTENTS: section. The supervisor model then chooses among the routes, and the platform enforces each route’s WHEN when the model calls it.
Two tools control which routes the model can reach.
Values you can test
The platform provides channel, language, locale, time zone, and identity. It provides no role. Your channel, SDK, or a lookup must supply the role. Treat caller data from a browser as unverified. Pair a role test with
session.identityTier == 2.
Use session.channel for the channel. The paths channel.name and system.channel belong to other features. They do not resolve in a HANDOFF WHEN, and channel.name compiles without a warning. The path session.interaction.current.channel does not exist.
Voice has several channel types: voice, voice_twilio, voice_livekit, voice_realtime, voice_pipeline, voice_vxml, korevg, audiocodes, and genesys_audio_connector. A test for "voice" matches only the first one. Use IN [...] to match the family.
Order and ties
The position of an entry sets its priority. The first entry has the highest priority. ThePRIORITY: field is read and then ignored.
Several deterministic routes can be true at once, for example a Spanish speaker on a voice channel. The model then chooses, and the position shows as [Priority N] in each route description. To make the result certain, write exclusive conditions or put the combined route first. See Combine conditions.
Minimal working example
This supervisor routes verified administrators, Spanish speakers, and voice callers. AWHEN: true route handles everyone else. Put the supervisor and all agents in the same project. The target agents are short stand-ins.
agents/context-routing-supervisor.agent.abl
agents/admin-support-agent.agent.abl
agents/spanish-service-agent.agent.abl
agents/voice-support-agent.agent.abl
agents/standard-service-agent.agent.abl
session.user_roleis caller data that your SDK or channel sends, for example the valueadmin.customer_idandaccount_idfollow the same rules as in How to route users by detected intent. The platform passes the supervisor’s value when it has one. Otherwise the model fills the field from the conversation.
How it works
- The supervisor keeps the conversation until a route fires.
- The model calls a route. The platform evaluates that route’s
WHENagainst the session data. - A true expression admits the route. A false expression refuses it, and the model tries another route.
- The target receives the
PASSvalues, thesummary, and the history thathistoryallows. The default isfull. - With
EXPECT_RETURN: false, the target keeps the conversation. WithEXPECT_RETURN: true, the supervisor resumes when the target returns. - A missing value makes a test false.
session.user_role == "admin"is false when the role is absent. - The
WHEN: trueroute is always available. It receives any request that the other routes do not take.
intent.category test never reads the category.
Common variations
Combine conditions
Join tests withAND and OR. Put the combined route before the single-test routes. Here, Spanish voice callers reach a dedicated agent.
session.channel == "voice" AND "the user is a VIP", the compiler warns with CEL_CONDITION_UNRESOLVED_CALL. At runtime the phrase is a string that is always true, so the route fires for every voice caller. Test a field instead, for example session.customer_tier == "vip".
Route on locale
Use the locale when the dialect matters.Route on state that a child returns
UseEXPECT_RETURN: true when another agent collects the value first. This route asks for a language preference once. It then routes on the answer.
map copies the child’s chosen_language into the supervisor’s preferred_language. Write the child field first. The child must gather or produce chosen_language.
Use IS NOT SET on a plain variable such as preferred_language. Do not use it on a dotted path such as session.interaction.current.language. The path holds a null value when the language is unknown, and IS NOT SET is false for null.
Hide a route on other channels
AddENABLED_WHEN when a channel must never see a route. The model does not see the route while the condition is false.
ENABLED_WHEN as an expression over data that exists before the turn. A condition that reads intent or plain language fails to compile with ENABLED_WHEN_SEMANTIC_REFERENCE. A condition that reads a missing value counts as false.
Add ON_FAILURE
ON_FAILURE runs when the handoff fails before the target accepts it.
CONTINUE, ESCALATE, and RESPOND "message". A bare quoted string fails with INVALID_HANDOFF_FAILURE_ACTION.
Verification
- Start a voice session and send a message. Open the trace. Find the
handoff_condition_checkevent for the voice route. Confirmresult: trueandwhenOutcome: deterministic_pass. - In the same event, read
evaluatedContext. Confirm the value ofsession.channelthat your channel reports. - Send a Spanish message on a web channel. Confirm
Spanish_Service_Agent. Checksession.interaction.current.languagein the event. - Start a session with caller data
user_roleset toadminand an identity tier of2. ConfirmAdmin_Support_Agent. Repeat with tier0. Confirm the route is refused. - Send a message that matches no condition. Confirm
Standard_Service_Agent. - Check that each target receives the
passvalues and the summary.
Production readiness checklist
- Every value in a
WHENhas a source: the platform, caller data, a lookup, or a child’s return. - Role tests also require a verified identity, for example
session.identityTier == 2. - Channel tests list every channel type in the family, or you confirm the exact value in a trace.
- Overlapping routes are ordered, or their conditions exclude each other.
- A
WHEN: trueroute or an answering supervisor covers every other message. - Quoted phrases never appear inside an
ANDorORtest. ON_FAILUREis set on routes where a missing target must produce a reply.- Tests cover each channel, each language, each role, and one message with no match.