Skip to main content
Use this when routing depends on customer profile, case status, fraud risk, policy coverage, entitlement, remembered preference, or any state loaded before the handoff — not just the user’s utterance.

Concept

Some routes cannot be decided from what the user typed. The supervisor first calls a read-only lookup tool, binds the result with AS, then routes with deterministic conditions over that result’s fields. This is the pattern for premium routing, existing-case routing, risk routing, entitlement routing, and remembered-preference routing. One behavior is worth knowing before you move past the happy path: you don’t have to copy tool-result fields into separate session variables before routing on them. You can reference the AS-bound object’s fields directly in WHEN; a flat copy (SET profile_tier = profile.tier) is only useful if you also want to pass a shorter, flatter set of fields through CONTEXT.pass.

Minimal working example

customer_id is referenced as both a tool parameter and a CONTEXT.pass field with no declared source in this example — treat it as a project-local assumption (typically populated earlier from authentication or a prior turn) and declare it via MEMORY in your actual project.

How it works

  • ON_START calls the read-only lookup tool once, before any HANDOFF is evaluated, and binds the result to profile with AS.
  • Each HANDOFF’s WHEN is evaluated in authored order. Every condition here is a plain equality comparison (profile.fraud_risk == "high", profile.has_open_case == true, profile.tier == "premium") — if the field hasn’t resolved yet, the comparison simply evaluates false rather than erroring, so you don’t need to write profile.fraud_risk IS SET AND profile.fraud_risk == "high" yourself.
  • The SET step that copies profile.tier/profile.has_open_case/profile.fraud_risk into flat variables is not required for the WHEN conditions to work — they reference profile.* directly. The copies exist here only so the flatter names can be listed in CONTEXT.pass; you can pass profile itself (or a subset via a shorthand) instead if you prefer not to duplicate fields.
  • The fallback route uses a quoted natural-language condition. Keep this kind of fallback text in lowercase, ordinary sentence form — a quoted condition containing an uppercase AND/OR/NOT can be misclassified by the runtime as a structured deterministic expression rather than natural language, which will not evaluate the way you intend. Lowercase words like “or”/“and” inside ordinary sentences (as in this example) are handled correctly.
  • Since none of the HANDOFF entries declare HISTORY, each child now receives the full conversation history by default (the current platform default when HISTORY is omitted). Set HISTORY: auto (or another explicit strategy) if you specifically want bounded/summary history instead.
  • lookup_customer_profile is declared with side_effects: false and confirm: never because it’s a read-only enrichment call used purely to decide a route — it should never require user confirmation and should never be confused with a state-changing action.

Common variations

Routing on remembered/persistent state instead of a live lookup

Replace the ON_START CALL ... AS: profile step with a read from persistent memory (see the memory HowTos for declaring and recalling scoped memory), then route on the recalled fields the same way — the WHEN conditions don’t change shape.

Passing the bound object instead of flat copies

If you don’t need a smaller/renamed field set in CONTEXT.pass, skip the flat SET copies entirely and pass profile (or specific profile.* paths) directly.

Verification

  • Parse and compile the ABL and confirm there are no parser or compiler errors/warnings.
  • Test at least one utterance that resolves to each of the four routes, including the fallback path (no fraud, no open case, non-premium tier).
  • Inspect the trace for the selected target and the evaluated condition — you’ll see your literal authored condition text, since HANDOFF conditions are not rewritten by the compiler.
  • Confirm the fallback route’s semantic condition resolves as intended by testing an utterance where all three deterministic conditions are false.

Production readiness checklist

  • The lookup tool is declared read-only (side_effects: false) and never requires confirmation for a routing-only call.
  • Every specialist route has a clear owner and a concise context summary.
  • Deterministic conditions reference fields that are actually present on the tool’s declared return shape.
  • Quoted natural-language fallback text avoids uppercase AND/OR/NOT.
  • customer_id (or any other assumed pre-existing variable) has a real declared source in your project, not just an assumption carried over from this example.
  • Fallback behavior is explicit and does not hide missing routing coverage.

Common mistakes

Troubleshooting