Pular para o conteúdo principal

Escalation

Sometimes the agent can't finish what the user asked for, or the user just wants to talk to a person. Appilots' escalation flow hands the conversation to a human operator without the user leaving your app.

Built into <AppilotsChat/>

<AppilotsChat/> ships this flow out of the box — you don't need to build anything to get it:

  • A headset icon in the header lets the user request a human at any time.
  • The chat automatically offers a "talk to a human" chip when the agent gives up and can't complete the user's request.
  • While an escalation is open, the user's messages route to the human operator instead of the AI.
  • The operator's replies appear inline in the transcript as a distinct "human agent" bubble style (message role human_agent).
  • When the operator resolves the escalation, the AI resumes normally and a system message marks the transition back.

EscalationState

interface EscalationState {
id: string;
status: 'pending' | 'active';
operatorName?: string;
}
  • pending — the escalation was requested and is waiting for an operator to pick it up.
  • active — an operator has claimed the conversation and is replying. operatorName is set once this happens.

There's no client-visible resolved status. Resolution simply clears the escalation state (escalation becomes null again) after a system message is appended to the transcript.

Building a custom chat surface

If you're not using <AppilotsChat/> directly, the escalation surface lives on useAppilotsChat():

import { useAppilotsChat } from '@appilots/sdk';

const { escalation, requestHuman } = useAppilotsChat({
escalationStrings: {
requested: 'Connecting you with a human…',
connected: "You're now chatting with {{operatorName}}.",
resolved: 'Back to the assistant.',
offer: 'Want to talk to a person instead?',
},
});
FieldTypeDescription
escalationEscalationState | nullThe open escalation, or null if none.
requestHuman(reason?: 'user_requested' | 'agent_gave_up') => Promise<void>Requests a human operator.

requestHuman is idempotent — calling it again while an escalation is already pending or active is a no-op, so you can wire it to a button without guarding against double-taps yourself.

escalationStrings lets you localize the system messages shown at each transition: when the escalation is requested, when an operator connects, when it resolves back to the AI, and the copy shown on the auto-offered "talk to a human" chip.

Example: header button + status banner

function SupportButton() {
const { escalation, requestHuman } = useAppilotsChat();

return (
<>
<Pressable onPress={() => requestHuman('user_requested')}>
<HeadsetIcon />
</Pressable>
{escalation && (
<Banner>
{escalation.status === 'pending'
? 'Waiting for a human agent…'
: `Connected to ${escalation.operatorName ?? 'support'}`}
</Banner>
)}
</>
);
}

Reliability

The live channel that carries operator replies reconnects automatically if the connection drops while an escalation is open — your app doesn't need to do anything to handle that.

Operator side

Claiming an escalation, replying, and resolving it back to the AI is done by your support team from the Appilots dashboard, not from the SDK. See Dashboard: Human Escalation Ops for that side of the flow — this page only covers the client.

Next steps