Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -90,14 +90,17 @@ EVA_MODEL__STT_PARAMS='{"api_key": "your_cartesia_api_key", "model": "ink-2"}'
# --- TTS (LLM and AudioLLM modes) ---
#i TTS provider for the voice pipeline.
#d enum
#e cartesia,chatterbox,elevenlabs,gemini,kokoro,nvidia-baseten,openai,smallest,soniox,xtts
#e cartesia,chatterbox,deepgram,deepgram-flux,elevenlabs,gemini,kokoro,nvidia-baseten,openai,smallest,soniox,xtts
#x pipeline_mode=LLM,AudioLLM
EVA_MODEL__TTS=cartesia

#i TTS provider parameters. Must include "api_key" and "model". Use "urls" for round-robin load balancing, and "voice_id" to select a voice.
#i Some providers also accept extra provider-specific tuning parameters here.
#i Soniox example — omit "voice_id" to use pipecat's default voice ("Adrian"):
#i EVA_MODEL__TTS_PARAMS='{"api_key": "your_soniox_api_key", "model": "tts-rt-v2", "voice": "Sarah"}'
#i Deepgram Flux example (EVA_MODEL__TTS=deepgram-flux) — "voice" is the full flux-{voice}-{lang} model
#i string (defaults to "flux-alexis-en" if omitted); "model" is not used for Flux:
#i EVA_MODEL__TTS_PARAMS='{"api_key": "your_deepgram_api_key", "voice": "flux-haley-en"}'
#d json_object
#x pipeline_mode=LLM,AudioLLM
EVA_MODEL__TTS_PARAMS='{"api_key": "your_cartesia_api_key", "model": "sonic"}'
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ license = "MIT"
dependencies = [
"pydantic>=2.0",
"pydantic-settings>=2.0",
"pipecat-ai>=1.4.0",
"pipecat-ai>=1.6.0",
"elevenlabs>=2.53.0",
"openai>=2.36.0",
"anthropic>=0.83.0",
Expand Down
17 changes: 14 additions & 3 deletions src/eva/assistant/pipeline/services.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
from pipecat.services.cartesia.tts import CartesiaTTSService
from pipecat.services.cartesia.turns.stt import CartesiaTurnsSTTService
from pipecat.services.deepgram.flux.stt import DeepgramFluxSTTService, DeepgramFluxSTTSettings
from pipecat.services.deepgram.flux.tts import DeepgramFluxTTSService
from pipecat.services.deepgram.stt import DeepgramSTTService
from pipecat.services.deepgram.tts import DeepgramTTSService
from pipecat.services.elevenlabs.stt import CommitStrategy, ElevenLabsRealtimeSTTService
Expand Down Expand Up @@ -375,7 +376,7 @@ def create_tts_service(
Based on create_tts_service() from chatbot.py.

Args:
model: TTS model identifier (cartesia, elevenlabs, openai, gemini)
model: TTS model identifier (cartesia, deepgram, deepgram-flux, elevenlabs, openai, gemini)
params: Model-specific parameters (may include 'alias' key which is ignored here)
language_code: Language code for speech synthesis

Expand Down Expand Up @@ -430,7 +431,17 @@ def create_tts_service(
chatterbox_tts._settings.language = language_code
return chatterbox_tts

elif model_lower == "deepgram":
elif model_lower.startswith("deepgram"):
if "flux" in model_lower:
# Flux TTS (/v2/speak) has no separate "model" field: the flux-{voice}-{lang}
# string IS the voice, and pipecat keeps Settings.model in sync with it.
voice = params.get("voice", "flux-alexis-en")
logger.info(f"Using Deepgram Flux TTS: {voice}")
return DeepgramFluxTTSService(
api_key=api_key,
sample_rate=SAMPLE_RATE,
settings=DeepgramFluxTTSService.Settings(voice=voice),
)
logger.info(f"Using Deepgram TTS: {params['model']}")
return DeepgramTTSService(
api_key=api_key,
Expand Down Expand Up @@ -646,7 +657,7 @@ def create_tts_service(

else:
raise ValueError(
f"Unknown TTS model: {model}. Available: cartesia, chatterbox, deepgram, elevenlabs, gemini, kokoro, nvidia-baseten, openai, smallest, soniox, voxtral, xai, xtts"
f"Unknown TTS model: {model}. Available: cartesia, chatterbox, deepgram, deepgram-flux, elevenlabs, gemini, kokoro, nvidia-baseten, openai, smallest, soniox, voxtral, xai, xtts"
)


Expand Down
15 changes: 15 additions & 0 deletions tests/unit/assistant/test_services.py
Original file line number Diff line number Diff line change
Expand Up @@ -321,6 +321,21 @@ def test_soniox_defaults_voice_when_unset(self):
svc = create_tts_service("soniox", params={"api_key": "k", "model": "tts-rt-v1"})
assert svc._settings.voice == "Adrian"

def test_deepgram_returns_deepgram_service(self):
svc = create_tts_service("deepgram", params={"api_key": "k", "model": "aura-2-helena-en"})
assert "Deepgram" in type(svc).__name__
assert "Flux" not in type(svc).__name__
assert svc._settings.voice == "aura-2-helena-en"

def test_deepgram_flux_returns_flux_variant(self):
svc = create_tts_service("deepgram-flux", params={"api_key": "k", "voice": "flux-haley-en"})
assert "Flux" in type(svc).__name__
assert svc._settings.voice == "flux-haley-en"

def test_deepgram_flux_defaults_voice_when_unset(self):
svc = create_tts_service("deepgram-flux", params={"api_key": "k"})
assert svc._settings.voice == "flux-alexis-en"

def test_openai_respects_voice_param(self):
svc = create_tts_service("openai", params={"api_key": "k", "model": "tts-1", "voice": "nova"})
assert svc._settings.voice == "nova"
Expand Down
110 changes: 63 additions & 47 deletions uv.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading