diff --git a/examples/foundational/07n-interruptible-google.py b/examples/foundational/07n-interruptible-google.py index 522d168e1..4f5409085 100644 --- a/examples/foundational/07n-interruptible-google.py +++ b/examples/foundational/07n-interruptible-google.py @@ -55,8 +55,9 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): stt = GoogleSTTService( settings=GoogleSTTSettings( - languages=Language.EN_US, - model="chirp_3", + languages=[Language.EN_US], + # Add model to use a specific model + # model="chirp_3", ), credentials=os.getenv("GOOGLE_TEST_CREDENTIALS"), location="us", diff --git a/examples/foundational/07za-interruptible-soniox.py b/examples/foundational/07za-interruptible-soniox.py index 78e3ac873..71011c5d9 100644 --- a/examples/foundational/07za-interruptible-soniox.py +++ b/examples/foundational/07za-interruptible-soniox.py @@ -51,13 +51,13 @@ transport_params = { async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): logger.info(f"Starting bot") - stt = ( - SonioxSTTService( - api_key=os.getenv("SONIOX_API_KEY"), - settings=SonioxSTTSettings( - language_hints=[Language.EN], - language_hints_strict=True, - ), + stt = SonioxSTTService( + api_key=os.getenv("SONIOX_API_KEY"), + settings=SonioxSTTSettings( + # Add language hints to use a specific language + # Add strict mode to enforce the language hints + language_hints=[Language.EN], + language_hints_strict=True, ), ) diff --git a/src/pipecat/services/deepgram/flux/stt.py b/src/pipecat/services/deepgram/flux/stt.py index 1e7f135b2..678d373b4 100644 --- a/src/pipecat/services/deepgram/flux/stt.py +++ b/src/pipecat/services/deepgram/flux/stt.py @@ -81,7 +81,6 @@ class DeepgramFluxSTTSettings(STTSettings): eot_timeout_ms: Time in ms after speech to finish a turn regardless of EOT confidence (default 5000). keyterm: Keyterms to boost recognition accuracy for specialized terminology. - tag: Tags to label requests for identification during usage reporting. min_confidence: Minimum confidence required to create a TranscriptionFrame. """ @@ -89,7 +88,6 @@ class DeepgramFluxSTTSettings(STTSettings): eot_threshold: float | None | _NotGiven = field(default_factory=lambda: NOT_GIVEN) eot_timeout_ms: int | None | _NotGiven = field(default_factory=lambda: NOT_GIVEN) keyterm: list | _NotGiven = field(default_factory=lambda: NOT_GIVEN) - tag: list | _NotGiven = field(default_factory=lambda: NOT_GIVEN) min_confidence: float | None | _NotGiven = field(default_factory=lambda: NOT_GIVEN) @@ -157,6 +155,7 @@ class DeepgramFluxSTTService(WebsocketSTTService): mip_opt_out: Optional[bool] = None, model: Optional[str] = None, flux_encoding: str = "linear16", + tag: Optional[list] = None, params: Optional[InputParams] = None, should_interrupt: bool = True, settings: Optional[DeepgramFluxSTTSettings] = None, @@ -177,6 +176,7 @@ class DeepgramFluxSTTService(WebsocketSTTService): flux_encoding: Audio encoding format required by Flux API. Must be "linear16". Raw signed little-endian 16-bit PCM encoding. + tag: Tags to label requests for identification during usage reporting. params: InputParams instance containing detailed API configuration options. .. deprecated:: 0.0.105 @@ -224,7 +224,6 @@ class DeepgramFluxSTTService(WebsocketSTTService): eot_threshold=None, eot_timeout_ms=None, keyterm=[], - tag=[], min_confidence=None, ) @@ -241,7 +240,8 @@ class DeepgramFluxSTTService(WebsocketSTTService): default_settings.eot_threshold = params.eot_threshold default_settings.eot_timeout_ms = params.eot_timeout_ms default_settings.keyterm = params.keyterm or [] - default_settings.tag = params.tag or [] + if params.tag and tag is None: + tag = params.tag default_settings.min_confidence = params.min_confidence if params.mip_opt_out is not None: mip_opt_out = params.mip_opt_out @@ -261,6 +261,7 @@ class DeepgramFluxSTTService(WebsocketSTTService): self._should_interrupt = should_interrupt self._encoding = flux_encoding self._mip_opt_out = mip_opt_out + self._tag = tag or [] self._websocket_url = None self._receive_task = None @@ -469,7 +470,7 @@ class DeepgramFluxSTTService(WebsocketSTTService): url_params.append(urlencode({"keyterm": keyterm})) # Add tag parameters (can have multiple) - for tag_value in self._settings.tag: + for tag_value in self._tag: url_params.append(urlencode({"tag": tag_value})) self._websocket_url = f"{self._url}?{'&'.join(url_params)}" diff --git a/src/pipecat/services/elevenlabs/stt.py b/src/pipecat/services/elevenlabs/stt.py index f9899f7f1..6c21a9d20 100644 --- a/src/pipecat/services/elevenlabs/stt.py +++ b/src/pipecat/services/elevenlabs/stt.py @@ -186,7 +186,7 @@ class ElevenLabsSTTSettings(STTSettings): (coughing) in the transcription. """ - tag_audio_events: bool | _NotGiven = field(default_factory=lambda: NOT_GIVEN) + tag_audio_events: bool | None | _NotGiven = field(default_factory=lambda: NOT_GIVEN) @dataclass @@ -277,8 +277,8 @@ class ElevenLabsSTTService(SegmentedSTTService): # 1. Initialize default_settings with hardcoded defaults default_settings = ElevenLabsSTTSettings( model="scribe_v2", - language="eng", - tag_audio_events=True, + language=language_to_elevenlabs_language(Language.EN), + tag_audio_events=None, ) # 2. Apply direct init arg overrides (deprecated) @@ -291,9 +291,7 @@ class ElevenLabsSTTService(SegmentedSTTService): _warn_deprecated_param("params", ElevenLabsSTTSettings) if not settings: if params.language is not None: - default_settings.language = ( - self.language_to_service_language(params.language) or "eng" - ) + default_settings.language = language_to_elevenlabs_language(params.language) default_settings.tag_audio_events = params.tag_audio_events # 4. Apply settings delta (canonical API, always wins) @@ -354,10 +352,11 @@ class ElevenLabsSTTService(SegmentedSTTService): content_type="audio/x-wav", ) - # Add required model_id, language_code, and tag_audio_events + # Add required model_id and language_code data.add_field("model_id", self._settings.model) data.add_field("language_code", self._settings.language) - data.add_field("tag_audio_events", str(self._settings.tag_audio_events).lower()) + if self._settings.tag_audio_events is not None: + data.add_field("tag_audio_events", str(self._settings.tag_audio_events).lower()) async with self._session.post(url, data=data, headers=headers) as response: if response.status != 200: diff --git a/src/pipecat/services/fal/stt.py b/src/pipecat/services/fal/stt.py index 18b8ed85c..54aa750b4 100644 --- a/src/pipecat/services/fal/stt.py +++ b/src/pipecat/services/fal/stt.py @@ -215,7 +215,7 @@ class FalSTTService(SegmentedSTTService): # 1. Initialize default_settings with hardcoded defaults default_settings = FalSTTSettings( model=None, - language=language_to_fal_language(Language.EN) or "en", + language=language_to_fal_language(Language.EN), ) # 2. (no deprecated direct args for this service) @@ -224,9 +224,8 @@ class FalSTTService(SegmentedSTTService): if params is not None: _warn_deprecated_param("params", FalSTTSettings) if not settings: - default_settings.language = ( - language_to_fal_language(params.language) if params.language else "en" - ) + if params.language is not None: + default_settings.language = language_to_fal_language(params.language) if params.task != "transcribe": task = params.task if params.chunk_level != "segment": diff --git a/src/pipecat/services/google/tts.py b/src/pipecat/services/google/tts.py index 071d731b1..a937e2588 100644 --- a/src/pipecat/services/google/tts.py +++ b/src/pipecat/services/google/tts.py @@ -512,7 +512,7 @@ class GoogleHttpTTSSettings(TTSSettings): @dataclass -class GoogleStreamTTSSettings(TTSSettings): +class GoogleTTSSettings(TTSSettings): """Settings for Google streaming TTS service. Parameters: @@ -619,6 +619,13 @@ class GoogleHttpTTSService(TTSService): model=None, voice="en-US-Chirp3-HD-Charon", language="en-US", + pitch=None, + rate=None, + speaking_rate=None, + volume=None, + emphasis=None, + gender=None, + google_style=None, ) # 2. Apply direct init arg overrides (deprecated) @@ -1008,13 +1015,13 @@ class GoogleTTSService(GoogleBaseTTSService): ) """ - _settings: GoogleStreamTTSSettings + _settings: GoogleTTSSettings class InputParams(BaseModel): """Input parameters for Google streaming TTS configuration. .. deprecated:: 0.0.105 - Use ``GoogleStreamTTSSettings`` directly via the ``settings`` parameter instead. + Use ``GoogleTTSSettings`` directly via the ``settings`` parameter instead. Parameters: language: Language for synthesis. Defaults to English. @@ -1034,7 +1041,7 @@ class GoogleTTSService(GoogleBaseTTSService): voice_cloning_key: Optional[str] = None, sample_rate: Optional[int] = None, params: Optional[InputParams] = None, - settings: Optional[GoogleStreamTTSSettings] = None, + settings: Optional[GoogleTTSSettings] = None, **kwargs, ): """Initializes the Google streaming TTS service. @@ -1046,34 +1053,35 @@ class GoogleTTSService(GoogleBaseTTSService): voice_id: Google TTS voice identifier (e.g., "en-US-Chirp3-HD-Charon"). .. deprecated:: 0.0.105 - Use ``settings=GoogleStreamTTSSettings(voice=...)`` instead. + Use ``settings=GoogleTTSSettings(voice=...)`` instead. voice_cloning_key: The voice cloning key for Chirp 3 custom voices. sample_rate: Audio sample rate in Hz. If None, uses default. params: Language configuration parameters. .. deprecated:: 0.0.105 - Use ``settings=GoogleStreamTTSSettings(...)`` instead. + Use ``settings=GoogleTTSSettings(...)`` instead. settings: Runtime-updatable settings. When provided alongside deprecated parameters, ``settings`` values take precedence. **kwargs: Additional arguments passed to parent TTSService. """ # 1. Initialize default_settings with hardcoded defaults - default_settings = GoogleStreamTTSSettings( + default_settings = GoogleTTSSettings( model=None, voice="en-US-Chirp3-HD-Charon", language="en-US", + speaking_rate=None, ) # 2. Apply direct init arg overrides (deprecated) if voice_id is not None: - _warn_deprecated_param("voice_id", GoogleStreamTTSSettings, "voice") + _warn_deprecated_param("voice_id", GoogleTTSSettings, "voice") default_settings.voice = voice_id # 3. Apply params overrides — only if settings not provided if params is not None: - _warn_deprecated_param("params", GoogleStreamTTSSettings) + _warn_deprecated_param("params", GoogleTTSSettings) if not settings: if params.language is not None: default_settings.language = self.language_to_service_language(params.language) @@ -1104,7 +1112,7 @@ class GoogleTTSService(GoogleBaseTTSService): Args: delta: Settings delta. Can include 'speaking_rate' (float). """ - if isinstance(delta, GoogleStreamTTSSettings) and is_given(delta.speaking_rate): + if isinstance(delta, GoogleTTSSettings) and is_given(delta.speaking_rate): rate_value = float(delta.speaking_rate) if not (0.25 <= rate_value <= 2.0): logger.warning( @@ -1308,6 +1316,9 @@ class GeminiTTSService(GoogleBaseTTSService): model="gemini-2.5-flash-tts", voice="Kore", language="en-US", + prompt=None, + multi_speaker=False, + speaker_configs=None, ) # 2. Apply direct init arg overrides (deprecated) diff --git a/src/pipecat/services/speechmatics/stt.py b/src/pipecat/services/speechmatics/stt.py index b3ded9255..2500dd712 100644 --- a/src/pipecat/services/speechmatics/stt.py +++ b/src/pipecat/services/speechmatics/stt.py @@ -90,7 +90,6 @@ class SpeechmaticsSTTSettings(STTSettings): See ``SpeechmaticsSTTService.InputParams`` for detailed descriptions of each field. Parameters: - model: The operating point / model name. domain: Domain for Speechmatics API. turn_detection_mode: Endpoint handling mode. speaker_active_format: Formatter for active speaker ID. @@ -490,12 +489,6 @@ class SpeechmaticsSTTService(STTService): default_settings.prefer_current_speaker = _params.prefer_current_speaker default_settings.extra_params = _params.extra_params - # Build SDK config from settings, then resolve model from operating_point - self._client: VoiceAgentClient | None = None - self._audio_encoding = encoding - self._config: VoiceAgentConfig = self._build_config(default_settings) - default_settings.model = self._config.operating_point.value - # --- 4. Settings delta (canonical API, always wins) --- if settings is not None: default_settings.apply_update(settings) @@ -507,6 +500,13 @@ class SpeechmaticsSTTService(STTService): **kwargs, ) + # Build SDK config from settings, then resolve model from operating_point + self._client: VoiceAgentClient | None = None + self._audio_encoding = encoding + self._config: VoiceAgentConfig = self._build_config(self._settings) + self._settings.model = self._config.operating_point.value + self._sync_model_name_to_metrics() + # Outbound frame queue self._outbound_frames: asyncio.Queue[Frame] = asyncio.Queue()