LiveKit Agents
Use Svara as the TTS service in a LiveKit Agents pipeline.
Overview
LiveKit Agents builds voice agents out of three swappable legs — STT, LLM, TTS — plus VAD and end-of-turn detection. Svara plugs into the TTS leg through the official Python SDK: from svara.livekit import TTS. By default it rides the input-streaming WebSocket, so the agent starts speaking while the LLM is still writing its sentence.
The plugin emits 24 kHz, 16-bit, mono PCM straight into LiveKit’s AudioEmitter — no decode, no resample on the hot path — and pins the platform-certified sampling defaults so the agent sounds exactly like the API it fronts.
The TTS plugin
Two synthesis paths, chosen by mode:
mode="eager"(default) — forwards the LLM token stream into the input-streaming WebSocket; speech starts a few words in and prosody stays continuous across the whole turn. Measured roughly 2× faster to first audio than the sentence-buffered path in the same pipeline.mode="http"— buffers whole sentences and synthesizes each over streaming HTTP. Used automatically for fixed-textsay(), and available as the conservative fallback for full turns.
pip install "svara-voice[livekit] @ git+https://github.com/kenpath-labs/svara-python.git"Wiring the agent
Pass the plugin as tts= on the AgentSession. Every other leg is a stock plugin, and each is independently swappable — nothing below is Svara-specific.
pip install 'livekit-agents[openai,silero,turn-detector]'| Parameter | Type | Default | Description |
|---|---|---|---|
| SVARA_API_KEY | env | - | Your Svara key (the SDK reads it automatically). |
| SVARA_BASE_URL | env | https://api.kenpathlabs.com | The gateway origin; override for a regional pin (api-in, api-us, api-eu). |
| LIVEKIT_URL / _API_KEY / _API_SECRET | env | - | Your LiveKit server or Cloud project. |
Run python agent.py download-files once (it fetches the VAD and turn-detector models), then python agent.py dev.
Streaming from the LLM
With mode="eager" the plugin declares streaming=True and LiveKit hands it the raw token stream; the plugin forwards each delta over one WebSocket and pushes the binary PCM frames that come back. Nothing to implement — the protocol details in Input streaming are what the plugin speaks for you.
Prefer sentence-at-a-time synthesis for a specific agent? Construct the plugin with mode="http", or flip it at runtime with tts.update_options(mode="http").
Gotchas
- Use the gateway host.
https://api.kenpathlabs.comserves the API; the console host does not. - Don’t resample. The plugin declares
sample_rate=24000and LiveKit’s emitter takes the raw PCM; LiveKit itself resamples for an 8 kHz telephony leg. Anything you add on top only brings latency and artifacts. - 429s are already mapped. The plugin converts Svara’s ElevenLabs-shaped errors into LiveKit’s
APIStatusErrorwith the right retryability, so the agent backs off onrate_limit_exceededandtoo_many_concurrent_requestsinstead of dropping the turn.insufficient_quotais terminal until your quota resets. - Use
sv_voice ids in code. Ids likesv_enhdbrj5come from GET /v1/voices and are stable across renames. - Leave the sampling knobs alone. The plugin pins the platform-certified sampling; overriding it per-agent is how long utterances start to ramble.