ThunderPhone 2.0 is live.Self-serve, from 2¢/min.Read the announcement

Facts verified against published sources on .

LiveKit Agents

LiveKit Agents is an open-source framework for realtime voice agents on top of LiveKit rooms. ThunderPhone plugs in as the realtime model: the framework sends the participant's audio, ThunderPhone returns the agent's voice, transcripts and function calls, and LiveKit's room, SIP trunks and telephony carry the audio. Speech recognition, the language model, the voice, turn-taking, 47 languages and tools all run on ThunderPhone.

The plugin, livekit-plugins-thunderphone, is under review in the LiveKit Agents repository. Until LiveKit publishes it, it installs from the contribution branch; the docs guide carries the exact command. Everything below describes the plugin as it works today, not a roadmap.

What the plugin does

RealtimeModel subclasses LiveKit's OpenAI Realtime model, because ThunderPhone's realtime WebSocket speaks the same protocol. The plugin adds the endpoint and its query parameters, sk_live_ keys, saved-agent sessions, a single fully-configured session start for inline sessions, and ThunderPhone's call events.

  • Saved agent. RealtimeModel(agent_id=12). The agent's prompt, voice, engine, languages, tools and greeting come from ThunderPhone; the LiveKit Agent's instructions and tools are not sent.
  • Inline session. RealtimeModel(product="bolt", voice="olivia"). Instructions and function tools come from the LiveKit Agent, and the tools run in your worker.

Each AgentSession that starts is one ThunderPhone call, visible in call history with recording, transcript and grade, billed at the product's per-minute rate. When the ThunderPhone agent hangs up, the session receives call.ended and closes cleanly instead of reconnecting; a reconnect would start a second call.

Typical call flows

SIP inbound through LiveKit

A LiveKit SIP trunk delivers the call into a room, the worker starts an AgentSession with a saved ThunderPhone agent, and the caller talks to the agent exactly as they would on a ThunderPhone number. from_number and to_number record the real parties on the call. This is the path for teams that already route telephony through LiveKit and want a virtual receptionist without assembling one from separate services.

Browser or mobile voice with your own tools

An inline session takes instructions from your Agent class and exposes its @function_tool methods to ThunderPhone. The model calls them mid-conversation; LiveKit runs them and returns the result, and ThunderPhone finishes the turn. The RealtimeSession exposes call_id so the app can fetch the recording and transcript afterwards through the REST API.

Events the app can react to

Besides the framework's own events, the session emits thunderphone_call_event for every platform event (transfer, keypad, ignored speech) and thunderphone_call_ended with the hang-up reason.

Setup outline

  1. Create a secret API key in the ThunderPhone dashboard and set THUNDERPHONE_API_KEY.
  2. Install the plugin (LiveKit Agents 1.8 or newer) following the install line in the docs guide.
  3. Construct AgentSession(llm=thunderphone.RealtimeModel(agent_id=...)) or the inline form, and start it on the room as usual.
  4. For inline sessions, call generate_reply() after start so the agent speaks first; a saved agent greets on its own.
  5. Test barge-in, a tool round trip and an agent hang-up before production.

The full walkthrough with code is in the docs: Use ThunderPhone from LiveKit Agents.

Limits worth knowing

  • Turn detection is ThunderPhone's and always on. Framework-side VAD and turn detectors are not applied, and the plugin declares that to the framework so it does not try.
  • Instructions and tools cannot change once the call starts, so agent hand-offs keep the first configuration.
  • The framework's periodic connection recycling is disabled for ThunderPhone, since a recycled socket would be a new call.
  • Audio is 16-bit mono PCM at 24 kHz in both directions; video is ignored.

Related workflows and terms