Skip to main content
Level: Advanced · Tags: AI, Tools, Handoff, WhatsApp, Telegram Features shown: AI tool calling · human handoff (ctx.handoff, bot.resume) · escape commands while handed off · 'message' and 'handoff' events · sending to another chat (bot.send) · enum validation of arguments

Prerequisites

  • Node.js 22.12 or newer.
  • An Anthropic API key in the ANTHROPIC_API_KEY environment variable (or another model with tool calling, see below).
  • AGENTS_CHAT_ID, the chat where your agents get the summaries (for example a WhatsApp group id). It is required on WhatsApp and Telegram; the simulator uses a chat called agents.

The bot

How it works

  • The model decides when to escalate. escalate_to_human is an ordinary tool: the persona says when to call it, and the enum keeps reason to a closed set you can route on (queues, priorities).
  • The summary is a tool argument. The model writes it while deciding to escalate, so the agent gets “problem, what was tried, what the customer wants” without an extra model call.
  • Hand off first, notify second. The tool calls ctx.handoff() before it tells the agents, and notifyAgents() catches its own errors: if the agents’ chat cannot be reached, the customer is still handed off and the failure goes to the log instead of crashing the process.
  • ctx.handoff() pauses the bot in that chat. Messages are still stored, hooks run and the 'message' event fires (the example relays them to the agents, starting with the message that triggered the escalation), but no handler, flow or AI answers. The state survives restarts with a persistent store.
  • Getting the bot back. handoff.allowCommands: ['bot'] lets /bot through while handed off; in production your inbox calls bot.resume(chatId) when the agent closes the case. Agents answer the customer with bot.send(chatId, text).
  • No confirmation here. Escalating has no side effect for the customer, so the tool has no confirm: true; keep it for refunds or bookings.

Try it

A run of the code above in the terminal simulator, where the customer’s chat is user. The model is scripted by the test that runs this page (packages/ai/tests/docs-examples-ai.test.ts); the handoff, the relay to agents and /bot are real. Lines marked bot → agents are what the agents’ chat receives.

Other model providers

Tool calling works on every provider; on Ollama pick a model tagged tools.OpenAI (npm install openai, key in OPENAI_API_KEY):
Gemini (npm install @google/genai, key in GEMINI_API_KEY):
Ollama on your machine (no package, no key; run ollama pull qwen3 first):

Run it on WhatsApp or Telegram

node bot.js prints a QR code: scan it with WhatsApp (Linked devices) and set AGENTS_CHAT_ID to the group where your agents are. For Telegram, install @botmesh/telegram, start the factory with new TelegramProvider({ token: process.env.TELEGRAM_TOKEN ?? '' }) and use the numeric id of the agents’ group.

Next steps