Escalation
Handle escalation requests — approval flows, budget warnings, and step limits.
Escalation Types
| Type | Trigger |
|---|---|
tool_call | A tool matched an 'escalate' policy |
budget_warning | Cost exceeded costEscalationThreshold |
step_limit | Steps exceeded stepEscalationThreshold |
EscalationRequest
interface EscalationRequest {
type: 'tool_call' | 'budget_warning' | 'step_limit';
toolName?: string;
toolInput?: unknown;
reason: string;
context: {
runId: string;
stepCount: number;
estimatedCostUsd?: number;
};
}Handling Escalations
With Callback
policy: {
tools: [{ pattern: 'delete*', permission: 'escalate' }],
onEscalation: async (request) => {
// Log, notify, or ask a human
if (request.type === 'tool_call') {
const approved = await askHuman(
`Agent wants to call ${request.toolName}. Approve?`
);
return approved ? 'approve' : 'deny';
}
return 'pause'; // Pause for async approval
},
},Without Callback (Async Approval)
When no onEscalation callback is provided, the run pauses automatically:
const result = await agent.run({ task: 'Clean up old data' });
if (result.status === 'awaiting_approval') {
// Later, approve or deny
const continued = await agent.approve(result.runId, true);
}EscalationDecision
| Decision | Effect |
|---|---|
'approve' | Tool call proceeds |
'deny' | Tool call blocked, error sent to LLM |
'abort' | Run fails immediately |
'pause' | Run enters awaiting_approval status |
Budget-Based Escalation
Escalate when costs get high:
policy: {
costEscalationThreshold: 0.50, // Escalate at $0.50
stepEscalationThreshold: 15, // Escalate at 15 steps
onEscalation: async (request) => {
if (request.type === 'budget_warning') {
console.warn(`Budget warning: $${request.context.estimatedCostUsd}`);
return 'approve'; // Continue but we're watching
}
return 'pause';
},
},Next Steps
- Human-in-the-Loop Guide — practical patterns
- Resume — resuming paused runs