dograh/api/tests/test_smallest_service_factory.py
Harshita Jain e79cb42f31
feat: add Smallest AI TTS and STT provider integration (#444)
* feat: add Smallest AI TTS and STT provider integration

Integrates Smallest AI's Waves (TTS) and Pulse (STT) APIs as selectable
providers in the Dograh platform. Dograh's pipecat fork already contains
the pipecat-level service implementations; this wires them into the API
configuration registry and service factory.

- Added `SMALLEST = "smallest"` to `ServiceProviders` enum
- Registered `SmallestAITTSConfiguration` (lightning-v3.1/v2, voices,
  language, speed) and `SmallestAISTTConfiguration` (pulse model, 30+
  languages) Pydantic config classes with the TTS/STT registries
- Added factory branches in `create_tts_service` and `create_stt_service`
  routing to `SmallestTTSService` and `SmallestSTTService` from pipecat

* fix: update Smallest AI models to v4 naming convention

- TTS: rename lightning-v3.1 → lightning_v3.1, add lightning_v3.1_pro, drop deprecated lightning-v2
- STT: keep pulse only (pulse-pro is not a streaming model)

* fix: change default TTS voice from emily to sophia for lightning_v3.1

emily is not a verified lightning_v3.1 voice; sophia is the pipecat
SmallestTTSService default and confirmed to work with the standard pool.

* fix: replace 9 invalid lightning_v3.1 voice IDs with verified ones

jasmine, james, michael, aria, lara, asel, sarah, rishi, deepika do not
exist in the lightning_v3.1 voice catalog. Replaced with avery, liam,
lucas, olivia, freya, devansh, maya, dhruv, maithili — all verified
against the API.

* fix: smallest ai config validation and tts model compatibility

* chore: ruff fix

* chore: updated smallest ai schema in openapi.json

---------

Co-authored-by: Sabiha Khan <sabihak89@gmail.com>
Co-authored-by: Sabiha Khan <87858386+chewwbaka@users.noreply.github.com>
2026-06-17 12:55:53 +05:30

80 lines
2.3 KiB
Python

from types import SimpleNamespace
from unittest.mock import patch
from api.services.configuration.check_validity import UserConfigurationValidator
from api.services.configuration.registry import (
REGISTRY,
ServiceProviders,
ServiceType,
SmallestAISTTConfiguration,
SmallestAITTSConfiguration,
)
from api.services.pipecat.service_factory import create_tts_service
def test_smallest_tts_configuration_defaults_and_registry():
config = SmallestAITTSConfiguration(api_key="test-key")
assert config.provider == ServiceProviders.SMALLEST
assert config.model == "lightning_v3.1"
assert config.voice == "sophia"
assert config.language == "en"
assert config.speed == 1.0
assert (
REGISTRY[ServiceType.TTS][ServiceProviders.SMALLEST]
is SmallestAITTSConfiguration
)
def test_smallest_stt_configuration_defaults_and_registry():
config = SmallestAISTTConfiguration(api_key="test-key")
assert config.provider == ServiceProviders.SMALLEST
assert config.model == "pulse"
assert config.language == "en"
assert (
REGISTRY[ServiceType.STT][ServiceProviders.SMALLEST]
is SmallestAISTTConfiguration
)
def test_validator_accepts_smallest_services():
validator = UserConfigurationValidator()
assert (
validator._validate_service(
SmallestAITTSConfiguration(api_key="test-key"),
"tts",
)
== []
)
assert (
validator._validate_service(
SmallestAISTTConfiguration(api_key="test-key"),
"stt",
)
== []
)
def test_create_smallest_tts_service_normalizes_hyphenated_model_values():
user_config = SimpleNamespace(
tts=SimpleNamespace(
provider=ServiceProviders.SMALLEST.value,
api_key="test-key",
model="lightning-v3.1",
voice="sophia",
language="en",
speed=1.0,
)
)
audio_config = SimpleNamespace(transport_in_sample_rate=16000)
with patch(
"api.services.pipecat.service_factory.SmallestTTSService"
) as mock_service:
create_tts_service(user_config, audio_config)
assert mock_service.call_count == 1
kwargs = mock_service.call_args.kwargs
assert kwargs["settings"].model == "lightning_v3.1"