From 97f50c8aa2ac55230304c8984fec32b33848c202 Mon Sep 17 00:00:00 2001 From: TimTk Date: Wed, 13 May 2026 21:43:02 +0300 Subject: [PATCH] Address review: use resolve_language, narrow delivery_mode type, update changelog - Replace custom LANGUAGE_MAP fallback in language_to_inworld_language with resolve_language(language, LANGUAGE_MAP, use_base_code=False) to match the pattern used by other services and restore the unverified-language warning - Tighten delivery_mode type from str to Literal["STABLE", "BALANCED", "CREATIVE"] - Update changelog entry to mention delivery_mode and language normalization --- changelog/4473.added.md | 4 +++- src/pipecat/services/inworld/tts.py | 23 +++++++++-------------- 2 files changed, 12 insertions(+), 15 deletions(-) diff --git a/changelog/4473.added.md b/changelog/4473.added.md index 0d60fadc9..099728922 100644 --- a/changelog/4473.added.md +++ b/changelog/4473.added.md @@ -1 +1,3 @@ -- Added support for Inworld TTS v2 fields. +- Inworld TTS updates: + - Added `delivery_mode` setting (`STABLE`/`BALANCED`/`CREATIVE`) to `InworldTTSService` and `InworldHttpTTSService`, enabling the stability-vs-creativity tradeoff in `inworld-tts-2`. + - Added language support to `InworldTTSService` and `InworldHttpTTSService`. The `language` setting is now forwarded to the API, and a new `language_to_inworld_language()` helper normalizes Pipecat `Language` enums to Inworld's BCP-47 locale tags. diff --git a/src/pipecat/services/inworld/tts.py b/src/pipecat/services/inworld/tts.py index d6c037a63..6bad30e28 100644 --- a/src/pipecat/services/inworld/tts.py +++ b/src/pipecat/services/inworld/tts.py @@ -60,27 +60,21 @@ from pipecat.frames.frames import ( ) from pipecat.processors.frame_processor import FrameDirection from pipecat.services.tts_service import TextAggregationMode, TTSService, WebsocketTTSService -from pipecat.transcriptions.language import Language +from pipecat.transcriptions.language import Language, resolve_language from pipecat.utils.tracing.service_decorators import traced_tts def language_to_inworld_language(language: Language) -> str: - """Convert a Language enum to an Inworld TTS language code. - - Inworld TTS accepts BCP-47 language tags. For the generally available - languages, Inworld's Playground emits regional tags (e.g. ``en-US``, - ``ru-RU``), so base Pipecat languages resolve to those canonical locales. - Regional variants can be used to nudge a voice toward a specific accent. + """Convert a Language enum to an Inworld TTS BCP-47 language tag. Args: language: The Language enum value to convert. Returns: - The corresponding Inworld language code. Base GA language enums are - normalized to Inworld's canonical regional locales. Other language enums - are returned as their BCP-47 string values. + The corresponding Inworld BCP-47 language tag (e.g. ``"en-US"``). + Unverified languages fall back to their BCP-47 string value with a warning. """ - CANONICAL_LOCALES = { + LANGUAGE_MAP = { Language.AR: "ar-SA", Language.DE: "de-DE", Language.EN: "en-US", @@ -97,8 +91,7 @@ def language_to_inworld_language(language: Language) -> str: Language.RU: "ru-RU", Language.ZH: "zh-CN", } - - return CANONICAL_LOCALES.get(language, str(language)) + return resolve_language(language, LANGUAGE_MAP, use_base_code=False) @dataclass @@ -117,7 +110,9 @@ class InworldTTSSettings(TTSSettings): speaking_rate: float | None | _NotGiven = field(default_factory=lambda: NOT_GIVEN) temperature: float | None | _NotGiven = field(default_factory=lambda: NOT_GIVEN) - delivery_mode: str | None | _NotGiven = field(default_factory=lambda: NOT_GIVEN) + delivery_mode: Literal["STABLE", "BALANCED", "CREATIVE"] | None | _NotGiven = field( + default_factory=lambda: NOT_GIVEN + ) _aliases: ClassVar[dict[str, str]] = { "voiceId": "voice",