Skip to content
Open
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
4 changes: 2 additions & 2 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ EVA_MODEL__LLM=gpt-5.2
# --- LLM mode: STT ---
#i STT provider for the voice pipeline.
#d enum
#e assemblyai,cartesia,cartesia-multilingual,deepgram,deepgram-flux,elevenlabs,nvidia,nvidia-baseten,openai
#e assemblyai,cartesia,cartesia-multilingual,deepgram,deepgram-flux,elevenlabs,nvidia,nvidia-baseten,openai,smallest
#x pipeline_mode=LLM
EVA_MODEL__STT=cartesia

Expand All @@ -87,7 +87,7 @@ 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,xtts
#e cartesia,chatterbox,elevenlabs,gemini,kokoro,nvidia-baseten,openai,smallest,xtts
#x pipeline_mode=LLM,AudioLLM
EVA_MODEL__TTS=cartesia

Expand Down
2 changes: 1 addition & 1 deletion src/eva/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

# Bump simulation_version when changes affect benchmark outputs (agent code,
# user simulator, orchestrator, simulation prompts, agent configs, tool mocks).
simulation_version = "2.0.1"
simulation_version = "2.0.2"

# Bump metrics_version when changes affect metric computation (metrics code,
# judge prompts, pricing tables, postprocessor).
Expand Down
40 changes: 38 additions & 2 deletions src/eva/assistant/pipeline/services.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@
from pipecat.services.openai.realtime.llm import OpenAIRealtimeLLMService
from pipecat.services.openai.stt import OpenAISTTService
from pipecat.services.openai.tts import OpenAITTSService
from pipecat.services.smallest.stt import SmallestSTTService
from pipecat.services.smallest.tts import SmallestTTSService
from pipecat.services.stt_service import STTService
from pipecat.services.tts_service import TTSService
from pipecat.services.xai.stt import XAISTTService
Expand Down Expand Up @@ -279,6 +281,21 @@ def create_stt_service(
)
return stt_service

elif model_lower == "smallest":
logger.info(f"Using Smallest Pulse STT: {params['model']}")
smallest_stt_settings_kwargs = {
k: params[k] for f in dataclasses.fields(SmallestSTTService.Settings) if (k := f.name) in params
}
return SmallestSTTService(
api_key=api_key,
base_url=url or "wss://api.smallest.ai",
sample_rate=params.get("sample_rate", SAMPLE_RATE),
settings=SmallestSTTService.Settings(
language=_to_language_enum(language_code),
**smallest_stt_settings_kwargs,
),
)

elif model_lower == "xai":
logger.info("Using xAI STT")
xai_settings_kwargs = {
Expand All @@ -298,7 +315,7 @@ def create_stt_service(

else:
raise ValueError(
f"Unknown STT model: {model}. Available: assemblyai, cartesia, cartesia-multilingual, cohere, deepgram, deepgram-flux, elevenlabs, nvidia, nvidia-baseten, openai, xai"
f"Unknown STT model: {model}. Available: assemblyai, cartesia, cartesia-multilingual, cohere, deepgram, deepgram-flux, elevenlabs, nvidia, nvidia-baseten, openai, smallest, xai"
)


Expand Down Expand Up @@ -500,6 +517,25 @@ def create_tts_service(

return openai_tts

elif model_lower == "smallest":
logger.info(f"Using Smallest Lightning TTS: {params['model']}")
smallest_tts_settings_kwargs = {
k: params[k] for f in dataclasses.fields(SmallestTTSService.Settings) if (k := f.name) in params
}
if "voice_id" in params:
# Omit "voice" entirely when unset so pipecat's per-model default (e.g. "sophia" for
# lightning_v3.1, "meher" for lightning_v3.1_pro) applies instead of a hardcoded EVA default.
smallest_tts_settings_kwargs["voice"] = params["voice_id"]
return SmallestTTSService(
api_key=api_key,
base_url=url or "wss://api.smallest.ai",
sample_rate=SAMPLE_RATE,
settings=SmallestTTSService.Settings(
language=_to_language_enum(language_code),
**smallest_tts_settings_kwargs,
),
)

elif model_lower == "voxtral":
logger.info(f"Using Voxtral TTS: {params['model']}")
voxtral_tts = OpenAITTSService(
Expand Down Expand Up @@ -557,7 +593,7 @@ def create_tts_service(

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


Expand Down
30 changes: 30 additions & 0 deletions tests/unit/assistant/test_services.py
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,19 @@ def test_xai_stt_defaults_and_forwards(self):
assert svc._settings.endpointing == 42 # Explicit override wins over the Eva default
assert svc._settings.interim_results is True # EVA default preserved

def test_smallest_returns_smallest_service(self):
svc = create_stt_service("smallest", params={"api_key": "k", "model": "pulse"})
assert "Smallest" in type(svc).__name__
assert svc._settings.model == "pulse"

def test_smallest_forwards_optional_settings(self):
svc = create_stt_service(
"smallest",
params={"api_key": "k", "model": "pulse", "word_timestamps": True, "diarize": True},
)
assert svc._settings.word_timestamps is True
assert svc._settings.diarize is True

def test_cartesia_is_ink2_turns_service(self):
svc = create_stt_service("cartesia", params={"api_key": "k", "model": "ink-2"})
assert "Turns" in type(svc).__name__
Expand Down Expand Up @@ -256,6 +269,23 @@ def test_elevenlabs_forwards_voice_tuning(self):
assert svc._settings.stability == 0.7
assert svc._settings.speed == 1.1

def test_smallest_returns_smallest_service(self):
svc = create_tts_service("smallest", params={"api_key": "k", "model": "lightning_v3.1"})
assert "Smallest" in type(svc).__name__

def test_smallest_forwards_voice_id_and_speed(self):
svc = create_tts_service(
"smallest",
params={"api_key": "k", "model": "lightning_v3.1", "voice_id": "sophia", "speed": 1.2},
)
assert svc._settings.voice == "sophia"
assert svc._settings.speed == 1.2

def test_smallest_defaults_voice_per_model_when_unset(self):
"""Omitting voice_id must not override pipecat's per-model default voice."""
svc = create_tts_service("smallest", params={"api_key": "k", "model": "lightning_v3.1_pro"})
assert svc._settings.voice == "meher"

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
Loading