Inbound calls handled by ElevenLabs voice agent with Karen AI brain
A patient calls (876) 676-6297 — Oshun's published phone number. The call hits a Twilio SIP trunk, which routes it to the antigravity-core voice system. Twilio fires a TwiML webhook to the server to initiate the voice pipeline.
Oshun/create_oshun_trunk.mjs — SIP trunk provisioning scriptOshun/oshun_twiml.xml — TwiML response that connects call to ElevenLabs
TWILIO_ACCOUNT_SID, TWILIO_AUTH_TOKENA real-time AI voice agent answers the call. The voice sounds natural — not robotic. The patient hears: "Hello, thank you for calling Oshun Beauty and Wellness. How can I help you today?" ElevenLabs handles both speech-to-text (what the patient says) and text-to-speech (Karen's replies) in real time.
src/webhooks/voice.js — ElevenLabs conversation endpoint (line ~350+)ELEVENLABS_API_KEY, ELEVENLABS_AGENT_IDEach patient utterance is transcribed and routed through the Karen AI brain — the same core logic that handles WhatsApp and Instagram, but with a voice-optimized prompt that keeps responses concise and conversational. No long paragraphs; short, spoken sentences only.
src/webhooks/voice.js → handleElevenLabsTool()src/ai.js → chat() — same pipeline as chat channelssrc/gemini.js — used for cheaper/faster voice sub-tasks
handleElevenLabsTool() receives the transcribed speech and calls chat() with a voice-mode flag. The prompt instructs Karen to respond in 1–2 short sentences max — mimicking natural speech rhythm. Gemini handles lightweight classification tasks (e.g., "is this a booking request?") to reduce OpenRouter spend on the voice pipeline. Each exchange is logged to voice_call_log.voice_call_logKaren identifies what the patient needs and acts. Simple pricing questions are answered directly. Appointment requests trigger real-time booking via Cal.com. Complex medical questions — anything Karen can't confidently answer — fire an immediate Telegram alert to Oshun staff so a human can follow up.
src/webhooks/voice_helpers.js → handleScheduleCallback(), handleBookAppointment()
handleBookAppointment() calls the Cal.com API to check availability and create a booking in real time while the patient is still on the call. Karen reads back the confirmed time slot. handleScheduleCallback() handles cases where no slots are immediately available — it schedules a follow-up call and sends confirmation via WhatsApp. Escalations trigger sendNotification() to the Oshun Telegram group with the caller's name, number, and what they asked.voice_call_log, bookings, voice_callbacksWhen the call ends, the full transcript is stored and analyzed. What the caller asked, whether a booking was made, any follow-up actions required — all of it feeds the contact's profile and memory system, the same as a WhatsApp conversation would.
src/watchdog_voice.js → runCallTranscriptSync()
runCallTranscriptSync() runs on a scheduled interval (via watchdog). It pulls completed call transcripts from ElevenLabs, matches them to contacts by phone number, and stores the full exchange in memory. Key facts extracted ("asked about lip fillers", "booked for Friday") are written to memory_knowledge with vector embeddings. conversation_metrics tracks call outcome (booked / info only / escalated / no-answer).voice_call_log, conversation_metrics, memory_conversations