Escalation
The Escalation pattern flows a request up a tiered support stack. Each tier either resolves the request (terminating the workflow) or escalates to the next tier.
Classic (non-beta) primitives: DefaultPattern, ExpressionContextCondition("confidence < 7"), ReplyResult(context_variables={"confidence": 6}, target=AgentTarget(tier2)) from tier-1 to record its self-rated confidence and hand off.
Key Characteristics#
- Fixed tier order.
tier1→tier2→senior. Each tier knows only its own tools, so the senior agent has noescalate_to_*tool registered — the buck stops there structurally, not by prompt convention. - Two routing idioms in one graph. Escalation uses typed
Handoffreturns; termination uses aToolCalledgraph rule. The two compose freely.
Routing Mechanics#
- Typed
Handoffreturns for escalation — each tier'sescalate_to_*tool returns aHandoff(target=...)carrying the next tier's name. The framework reads it from the agent's localToolResultEventstream after the round and stamps it onto the packet'srouting.target. Mirrors classic AG2'sReplyResult(target=AgentTarget(...))pattern. set_context+ToolCalledgraph rule for termination — theresolvetool writes the answer intocontext_vars["resolution"]and aToolCalled("resolve")graph rule fires the terminate transition.
Agent Flow#
sequenceDiagram
participant User as user
participant Tier1 as tier1
participant Tier2 as tier2
participant Senior as senior
User->>Tier1: question
alt question in tier-1 scope
Tier1->>User: resolve(answer); ToolCalled("resolve") → terminate
else out of scope
Tier1->>Tier2: Handoff(target="tier2", reason=...)
alt question in tier-2 scope
Tier2->>User: resolve(answer); ToolCalled("resolve") → terminate
else genuinely edge case
Tier2->>Senior: Handoff(target="senior", reason=...)
Senior->>User: resolve(answer); ToolCalled("resolve") → terminate
end
end Migration Notes#
| Classic | Beta |
|---|---|
ReplyResult(target=AgentTarget(tier2), context_variables={...}) | return Handoff(target="tier2", reason=...) |
ContextVariables[...] = answer to record the answer | await set_context(session, "resolution", answer) |
Confidence threshold via ExpressionContextCondition("confidence < 7") | Custom ContextThreshold condition (recipe in Context Variables → Custom Conditions) |
Gaps & Workarounds#
ContextThresholdnot shipped as a built-in. If you'd rather the graph check a confidence threshold (e.g."confidence < 7"decides escalation, not the tool name), register aContextThresholdcondition.
Code#
Tip
All three tiers use real Sonnet so the escalation decision is genuinely LLM-driven. The demo's tier-2 prompt has a small rule that forces escalation when the question mentions "compressor", "GDPR", or "compliance" — the sample input ("refrigerator compressor") follows that path all the way to senior.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 | |
Output#
session: c047...
user: My refrigerator's compressor is humming louder than usual and occasionally clicks. What's wrong and how do I fix it?
[tool] escalate_to_tier2('Customer is reporting a technical issue with a refrigerator compressor that requires technical diagnosis, which is outside tier-1 scope.')
tier1: [Handed off via escalate_to_tier2] Customer is reporting a technical issue with a refrigerator compressor that requires technical diagnosis, which is outside tier-1 scope.
[tool] escalate_to_senior("Customer is reporting issues with a refrigerator compressor — per domain rules, any question mentioning 'compressor' requires senior escalation for proper diagnosis.")
tier2: [Handed off via escalate_to_senior] Customer is reporting issues with a refrigerator compressor — per domain rules, any question mentioning 'compressor' requires senior escalation for proper diagnosis.
[tool] resolve('A loud humming combined with clicking from your refrigerator'…)
senior: [Handed off via resolve]
closed: reason='resolved'
--- final resolution ---
A loud humming combined with clicking from your refrigerator compressor most commonly points to a faulty start relay — a small, inexpensive part that helps the compressor start up; when it fails, the compressor tries to start, clicks off, and hums under the strain. You can confirm this by removing the start relay (a small component plugged into the side of the compressor at the back of the fridge) and shaking it — if it rattles, it's bad and needs replacing.