An inbound WhatsApp message runs a short pipeline before any model is called. Cost is bounded per user, and when the bot is not the right answer it hands off to a human instead of guessing.
WhatsApp webhook delivers the user's text to the console.
Per-user window (default 15 / hour). Over the cap means stop paying for model calls.
Keyword search over the catalogue in BigQuery builds a small context block.
Claude primary, OpenAI alternative, selected by AI_PROVIDER.
Rule-based reply needs no API key, so a provider outage still answers the basics.
Send the answer, or flip the thread to operator mode.
The gateway auto-replies within the guardrails above. Default for new threads.
A human takes over; the bot stops auto-replying for that conversation until released.
The toggle is per conversation, so a busy operator can let the bot hold routine threads while they work a hard one.
../src/chat/ai-gateway.js.