Skip to main content

First pastoral call — visitor dials the voice agent

Persona

A visitor calling the church for the first time — asking about service times, requesting prayer, or following up on an event. They expect a human-sounding response within a few seconds. They don't expect a robot, but accept an AI if it sounds warm and understands their need.

Entry points

  • Direct dial: Visitor calls the Telnyx number assigned during provisioning (e.g., +1-414-400-7103).
  • Call forwarding: Pastor forwarded their existing church landline to the Telnyx number; visitor dials the familiar number.
  • Scheduled callback: Visitor requested a callback during a previous chatbot or voice interaction.

Click-through flow

Steps

  1. Call arrives at Telnyx — Telnyx receives the call, routes SIP INVITE to 5u9xu5ysoly.sip.livekit.cloud:5060. If SIP trunk is down, caller hears "number not available."

  2. LiveKit receives and dispatches — Dispatch rule SDR_cYzx7sAkUTvx routes to the churchwiseai-voice agent. Agent's main.py:rtc_session() initializes with caller audio stream ready.

  3. Agent initializesresolve_route(dialed_number) maps the number to a church UUID via PHONE_REGISTRY dict (with DB fallback on church_voice_agents). Church data loads in parallel: greeting, hours, beliefs, staff. Typical latency 200–800ms while caller hears silence.

  4. Greeting plays — Coordinator's on_enter() calls session.say(greeting, allow_interruptions=False). Cartesia Sonic TTS generates audio. Caller cannot interrupt until greeting finishes. Latency ~1–2 seconds from connect to greeting heard.

  5. Caller responds — Deepgram Nova-3 STT (with keyterms boost) transcribes in real-time. LLM (Claude Haiku 4.5) applies HEAR protocol: Hear, Empathize, Address (next action), Respond. Tool invocations run mid-loop at ~500ms per call.

  6. Tool execution and staff notification — Prayer requests, visitor contacts, and callbacks are written to their respective tables with source='voice' and full transcript. Email fires immediately to escalation_contact_email.

  7. Call ends, transcript saved — Agent detects mutual farewell, plays brief closing, waits 2 seconds, then hangs up. _finalize_call() runs: classify, summarize via Haiku, write to voice_calls. Dashboard updates via WebSocket within ~2 seconds.

Acceptance spec

Canonical: knowledge/acceptance/starter-voice.md (62 touchpoints, COMPLETE).

Key requirements: call connects <5 seconds, greeting is church-specific, HEAR protocol observed (no counseling or advice), tool execution invisible to caller, Care agent escalation available.

Success criteria

  1. Phone connects after 1–2 rings (never >8 seconds).
  2. Agent answers with a warm, church-specific greeting (not generic).
  3. Agent listens without interrupting; reflects back what it heard.
  4. Prayer request or visitor contact confirmed: "Got it — I've added Sarah to the prayer list."
  5. Call feels natural. Visitor never thinks "I'm talking to a robot."
  6. No delays or audio artifacts.

Known failure modes

  • SIP trunk auth misconfigured. If LiveKit SIP inbound trunk has Authentication enabled, every call is rejected 401. Verify: lk.exe sip inbound list --project cwa-voice — Authentication column must be blank.

  • Agent routes to wrong church. If resolve_route() fails (stale PHONE_REGISTRY, DB query hung), caller hears generic greeting. Fix: ensure church_voice_agents phone field matches assigned Telnyx number post-provisioning.

  • Greeting slow or garbled. Cartesia startup plan caps 5 concurrent TTS streams. If voice agent + other tools hit the cap simultaneously, greeting is delayed. See crisis-call-escalation.md for the same TTS ceiling risk.

  • Transcript missing. If Deepgram or the Supabase write fails mid-call, transcript is blank in dashboard. Monitor: SELECT COUNT(*) FROM voice_calls WHERE transcript IS NULL OR transcript = ''.

  • Crisis safety net bypassed. safety.py:detect_crisis() must run on every response before TTS. See crisis-call-escalation.md for the full pattern. Disabling it is a P0 incident.

  • Callback fulfillment incomplete. As of 2026-04-24, callback requests are logged in voice_callback_requests but outbound calling is not yet implemented. Pastor must call visitor manually.