LiveKit¶
LiveKit is the media and session layer of the Voice AI pipeline. Every voice call — whether arriving via WebRTC or a SIP trunk — lands on LiveKit first. LiveKit then notifies the Call Service, which creates the room and dispatches the AI workers into it.
Source
Self-hosted LiveKit server + LiveKit SIP Gateway — not a custom microservice.
Role in the Pipeline¶
graph LR
WEB[WebRTC Caller] --> LK[LiveKit]
SIP[SIP / PBX / 3CX] --> GW[LiveKit SIP Gateway] --> LK
LK -->|webhook| CS[Call Service]
CS -->|manual dispatch| LK
LK --> AT[Atlas]
LK --> MB[Media Bot]
LiveKit sits between the telephony world and the AI workers. It is the only component that touches raw audio — all other services communicate via LiveKit's data channel or via HTTP callbacks.
Entry Points¶
WebRTC¶
Direct browser or WebRTC client connections arrive straight at the LiveKit server. The caller joins a room and LiveKit fires a participant_joined webhook.
SIP / PBX / 3CX¶
SIP calls (from any SIP-compatible PBX, trunk, or system such as 3CX, Asterisk, FreeSWITCH, Cisco, or Avaya) arrive at the LiveKit SIP Gateway. The gateway bridges the SIP leg into a LiveKit room, making the call indistinguishable from a WebRTC call to all downstream services.
Room Lifecycle¶
- Call arrives — LiveKit (or SIP Gateway) creates a room automatically on first participant join.
- Webhook — LiveKit sends a
participant_joinedwebhook to the Call Service. - Dispatch — Call Service resolves the
agent_id, then issues two manual dispatch requests back to LiveKit: - Atlas — the AI conversation agent
- Media Bot — handles hold music, ringback, busy tones, and live transcription
- Workers join — Atlas and Media Bot connect to the room as LiveKit participants.
- Conversation — audio flows between the caller and Atlas; Media Bot operates alongside.
- Call ends — room is closed; LiveKit fires a
room_finishedwebhook; Atlas publishes billing data.
Manual Dispatch¶
Call Service uses LiveKit's manual dispatch API to explicitly route workers to rooms. This gives Call Service full control over which AI agent handles each call, rather than relying on LiveKit's automatic agent assignment.
The agent_id is passed as room metadata so Atlas can fetch the correct configuration from Compass on join.
Workers Registered with LiveKit¶
| Worker | Registered as | Dispatch | Purpose |
|---|---|---|---|
| Atlas | LiveKit Agent (no agent_name) |
Manual | AI conversation — STT → LLM → TTS |
| Media Bot | LiveKit Worker (no agent_name) |
Manual | Tones, hold music, live transcription |
Both workers register without an agent_name, which means LiveKit does not auto-assign them — Call Service always controls dispatch explicitly.
SIP Gateway Configuration¶
The SIP Gateway maps inbound SIP trunks to LiveKit rooms. Key configuration points:
- Each SIP trunk (e.g. a 3CX outbound route, Asterisk dial plan, or direct SIP provider) is pointed at the LiveKit SIP Gateway address.
- The gateway terminates the SIP/RTP session and re-publishes the audio as a WebRTC track in a LiveKit room.
- DTMF, hold signals, and transfer requests from the PBX are translated into LiveKit data channel events.
Integration with Call Service¶
The Call Service interacts with LiveKit via:
| Interaction | Direction | Mechanism |
|---|---|---|
| Room creation notification | LiveKit → Call Service | HTTP webhook (participant_joined) |
| Dispatch Atlas | Call Service → LiveKit | LiveKit Server SDK — create_explicit_dispatch() |
| Dispatch Media Bot | Call Service → LiveKit | LiveKit Server SDK — create_explicit_dispatch() |
| Room metadata (agent_id) | Call Service → LiveKit | Room metadata on dispatch request |
| Recordings | Call Service → LiveKit | LiveKit Egress API → S3 |
| Call end notification | LiveKit → Call Service | HTTP webhook (room_finished) |