mcpField
V
voice-agents

voice-agents

github.com/sarvamaiDevelopment72188 installsUpdated 3d ago
Repository

About voice-agents

voice-agents is a skill for building voice agents with Sarvam services, aimed at Python developers using LiveKit or Pipecat. It provides integration examples and notes on voice, model, and framework configuration.

Key features

  1. 01Provides a LiveKit integration example
  2. 02Provides a Pipecat integration example
  3. 03Covers speech recognition, synthesis, and LLM
  4. 04Documents plugin parameters and model limits

Use cases

  1. 01Building real-time voice agents
  2. 02Combining speech recognition and synthesis in a Pipecat pipeline
  3. 03Configuring audio sample rates for telephony

MCP support

The README says in-chat one-shot voice and dubbing are provided by sarvam-mcp through `sarvam_tools_voice` and `_dub`; this skill focuses on LiveKit/Pipecat agent code.

Install

Copy the command and run it in a terminal.

$npx skills add https://github.com/sarvamai/skills --skill voice-agents

After installing, type/voice-agentsin Claude Code to confirm it loaded.

Details

From the project README

Voice Agents — Sarvam AI

One-shot in-chat voice/dub → sarvam-mcp (sarvam_tools_voice / _dub). This skill = LiveKit/Pipecat agent code.

Important

Auth: api-subscription-key header — NOT Authorization: Bearer. Env var: SARVAM_API_KEY

LiveKit Quick Start

pip install "livekit-agents[sarvam,silero]" python-dotenv
from livekit.agents import JobContext, WorkerOptions, cli
from livekit.agents.voice import Agent, AgentSession
from livekit.plugins import sarvam

class VoiceAgent(Agent):
    def __init__(self) -> None:
        super().__init__(
            instructions="You are a helpful voice assistant. Be friendly, concise, and conversational.",
            stt=sarvam.STT(
                language="unknown",   # auto-detect; or "hi-IN", "ta-IN", etc.
                model="saaras:v3",
                mode="transcribe",
                flush_signal=True     # emits speech start/end events for turn-taking
            ),
            llm=sarvam.LLM(model="sarvam-105b"),
            tts=sarvam.TTS(
                target_language_code="en-IN",
                model="bulbul:v4-flash",
                speaker="simran_en_customer",
            ),
        )

    async def on_enter(self):
        self.session.generate_reply()

async def entrypoint(ctx: JobContext):
    # Do NOT pass vad= — VAD is handled internally by the Sarvam plugin
    session = AgentSession(
        turn_detection="stt",       # let Sarvam STT handle turn detection
        min_endpointing_delay=0.07  # ~70ms matches Sarvam STT processing latency
    )
    await session.start(agent=VoiceAgent(), room=ctx.room)

if __name__ == "__main__":
    cli.run_app(WorkerOptions(entrypoint_fnc=entrypoint))

Run with python agent.py dev, test with python agent.py console.

Pipecat Quick Start

pip install "pipecat-ai[daily,sarvam]" python-dotenv loguru
import os
from pipecat.pipeline.pipeline import Pipeline
from pipecat.processors.aggregators.llm_context import LLMContext
from pipecat.processors.aggregators.llm_response_universal import LLMContextAggregatorPair
from pipecat.services.sarvam.stt import SarvamSTTService
from pipecat.services.sarvam.tts import SarvamTTSService
from pipecat.services.sarvam.llm import SarvamLLMService

stt = SarvamSTTService(
    api_key=os.getenv("SARVAM_API_KEY"),
    language="unknown",   # auto-detect; or "hi-IN", "ta-IN", etc.
    model="saaras:v3",
    mode="transcribe"     # or "translate" for speech-to-English
)
tts = SarvamTTSService(
    api_key=os.getenv("SARVAM_API_KEY"),
    settings=SarvamTTSService.Settings(
        model="bulbul:v4-flash",
        voice="simran_en_customer",  # persona ID — not a v3 short name
        language="en-IN",
        pace=1.0,
    ),
)
llm = SarvamLLMService(
    api_key=os.getenv("SARVAM_API_KEY"),
    settings=SarvamLLMService.Settings(model="sarvam-105b"),
)

messages = [{"role": "system", "content": "You are a friendly AI assistant. Keep responses brief."}]
context_aggregator = LLMContextAggregatorPair(LLMContext(messages))

pipeline = Pipeline([
    transport.input(),            # Daily or WebRTC transport
    stt,
    context_aggregator.user(),
    llm,
    tts,
    transport.output(),
    context_aggregator.assistant(),
])

JavaScript/TypeScript Note

LiveKit and Pipecat agents are Python-only. For JS/TS voice pipelines, use the individual SDK methods directly:

import { SarvamAIClient } from "sarvamai";
const client = new SarvamAIClient({ apiSubscriptionKey: "YOUR_SARVAM_API_KEY" });

// STT: client.speechToText.transcribe({...})
// TTS: client.textToSpeech.convertStream({...})  // returns BinaryResponse
// LLM: client.chat.completions({...})

Gotchas

GotchaDetail
LiveKit: no vad=Do NOT pass vad= to AgentSession — VAD is handled internally by the Sarvam plugin. Set turn_detection="stt" and min_endpointing_delay=0.07 instead.
LiveKit: flush_signal=TrueRequired on sarvam.STT for speech start/end events and proper turn-taking.
TTS voice params differ by pluginLiveKit (livekit-plugins-sarvam through 1.5.2): target_language_code + speaker. language_code= on sarvam.TTS() is rejected. Pipecat (1.0): settings=SarvamTTSService.Settings(voice=..., language=..., model=...) — voice, not speaker, and not bare constructor kwargs.
v4 speakers are persona IDsmodel="bulbul:v4-flash" needs voice_language_style (simran_en_customer, aparna_hi_customer). Short names (shubh, anand, priya) 400. LiveKit defaults a missing speaker to anushka when the model is not v3 — always pass speaker. Hindi: aparna_hi_customer. Tamil: gokul_ta_narration. No v4 personas for ml-IN / od-IN — use bulbul:v3 there.
Pipecat class namesSarvamSTTService/SarvamTTSService/SarvamLLMService from pipecat.services.sarvam.stt/.tts/.llm — NOT SarvamSTT. LLM model goes in SarvamLLMService.Settings(model=...), system prompt in LLMContext messages.
sarvam-30b is deprecated — and now hard-errors at the APIVerified live: calling sarvam-30b via the chat API now returns 400: "Model 'sarvam-30b' has been deprecated. Please use one of the available models instead: sarvam-105b, sarvam-105b-conversations." A Pipecat pipeline built on sarvam-30b will still construct fine (see below) but every LLM turn will start failing at runtime — this isn't a future risk, it's already broken if you're on it.
sarvam-105b-conversations may not be in your installed Pipecat's allowlist yetSarvam ships sarvam-105b-conversations — a 32K-context variant post-trained specifically for real-time dialogue/voice agents, i.e. the slot sarvam-30b used to fill. Verified live against pipecat-ai==0.0.108: SarvamLLMService._SUPPORTED_MODELS is frozenset({"sarvam-105b", "sarvam-105b-32k", "sarvam-30b", "sarvam-30b-16k"}) — it does not include sarvam-105b-conversations yet, and constructing SarvamLLMService(settings=SarvamLLMService.Settings(model="sarvam-105b-conversations")) raises ValueError: Unsupported Sarvam LLM model 'sarvam-105b-conversations'. Allowed values: sarvam-105b, sarvam-105b-32k, sarvam-30b, sarvam-30b-16k. immediately. Also note the same allowlist still happily accepts sarvam-30b/sarvam-30b-16k at construction time even though those are now dead at the API level (see row above) — construction succeeding is not a signal the model works. Check your installed pipecat-ai version's allowlist before switching to sarvam-105b-conversations; use plain sarvam-105b if it's not there yet.
max_tokens budgetSarvam models reason internally. Don't set low max_tokens or content will be None. Omit, set 500+, or disable with reasoning_effort=None.
TTS pitch/loudnessOn bulbul:v4-flash, pitch is −0.5–0.5 and loudness is 0.1–2.5. Bulbul v3 now accepts them too (live-verified 2026-10-06); pace is 0.5–2.0. Out-of-range values return 400.
STT WebSocket codecsOnly wav/pcm — no MP3/AAC/OGG for streaming.
HTTP Stream for TTSconvert_stream returns binary audio directly (no base64), better for pipelines.
TelephonyFor phone agents (e.g. Exotel), set audio_in_sample_rate=8000 and audio_out_sample_rate=8000 to match telephony audio.

Full Docs

Fetch framework integration guides, environment setup, and advanced patterns from:

Comments

Markdown supported