Fix service settings init ordering and example bugs
- Speechmatics: move config build after super().__init__ and settings delta so turn_detection_mode (e.g. ADAPTIVE) takes effect - Google STT: fix example passing bare Language enum instead of list - Google TTS: add missing explicit defaults for all custom settings fields - Soniox: fix accidental tuple wrapping of STT service in example - Speechmatics examples: fix system->user role in kick-off messages - Deepgram Flux: move tag from settings to __init__ (billing metadata) - ElevenLabs STT: default tag_audio_events to None (use API default) - Fal STT: simplify language default handling - Google TTS: rename GoogleStreamTTSSettings to GoogleTTSSettings
This commit is contained in:
@@ -55,8 +55,9 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments):
|
|||||||
|
|
||||||
stt = GoogleSTTService(
|
stt = GoogleSTTService(
|
||||||
settings=GoogleSTTSettings(
|
settings=GoogleSTTSettings(
|
||||||
languages=Language.EN_US,
|
languages=[Language.EN_US],
|
||||||
model="chirp_3",
|
# Add model to use a specific model
|
||||||
|
# model="chirp_3",
|
||||||
),
|
),
|
||||||
credentials=os.getenv("GOOGLE_TEST_CREDENTIALS"),
|
credentials=os.getenv("GOOGLE_TEST_CREDENTIALS"),
|
||||||
location="us",
|
location="us",
|
||||||
|
|||||||
@@ -51,13 +51,13 @@ transport_params = {
|
|||||||
async def run_bot(transport: BaseTransport, runner_args: RunnerArguments):
|
async def run_bot(transport: BaseTransport, runner_args: RunnerArguments):
|
||||||
logger.info(f"Starting bot")
|
logger.info(f"Starting bot")
|
||||||
|
|
||||||
stt = (
|
stt = SonioxSTTService(
|
||||||
SonioxSTTService(
|
api_key=os.getenv("SONIOX_API_KEY"),
|
||||||
api_key=os.getenv("SONIOX_API_KEY"),
|
settings=SonioxSTTSettings(
|
||||||
settings=SonioxSTTSettings(
|
# Add language hints to use a specific language
|
||||||
language_hints=[Language.EN],
|
# Add strict mode to enforce the language hints
|
||||||
language_hints_strict=True,
|
language_hints=[Language.EN],
|
||||||
),
|
language_hints_strict=True,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -81,7 +81,6 @@ class DeepgramFluxSTTSettings(STTSettings):
|
|||||||
eot_timeout_ms: Time in ms after speech to finish a turn regardless of EOT
|
eot_timeout_ms: Time in ms after speech to finish a turn regardless of EOT
|
||||||
confidence (default 5000).
|
confidence (default 5000).
|
||||||
keyterm: Keyterms to boost recognition accuracy for specialized terminology.
|
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.
|
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_threshold: float | None | _NotGiven = field(default_factory=lambda: NOT_GIVEN)
|
||||||
eot_timeout_ms: int | 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)
|
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)
|
min_confidence: float | None | _NotGiven = field(default_factory=lambda: NOT_GIVEN)
|
||||||
|
|
||||||
|
|
||||||
@@ -157,6 +155,7 @@ class DeepgramFluxSTTService(WebsocketSTTService):
|
|||||||
mip_opt_out: Optional[bool] = None,
|
mip_opt_out: Optional[bool] = None,
|
||||||
model: Optional[str] = None,
|
model: Optional[str] = None,
|
||||||
flux_encoding: str = "linear16",
|
flux_encoding: str = "linear16",
|
||||||
|
tag: Optional[list] = None,
|
||||||
params: Optional[InputParams] = None,
|
params: Optional[InputParams] = None,
|
||||||
should_interrupt: bool = True,
|
should_interrupt: bool = True,
|
||||||
settings: Optional[DeepgramFluxSTTSettings] = None,
|
settings: Optional[DeepgramFluxSTTSettings] = None,
|
||||||
@@ -177,6 +176,7 @@ class DeepgramFluxSTTService(WebsocketSTTService):
|
|||||||
|
|
||||||
flux_encoding: Audio encoding format required by Flux API. Must be "linear16".
|
flux_encoding: Audio encoding format required by Flux API. Must be "linear16".
|
||||||
Raw signed little-endian 16-bit PCM encoding.
|
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.
|
params: InputParams instance containing detailed API configuration options.
|
||||||
|
|
||||||
.. deprecated:: 0.0.105
|
.. deprecated:: 0.0.105
|
||||||
@@ -224,7 +224,6 @@ class DeepgramFluxSTTService(WebsocketSTTService):
|
|||||||
eot_threshold=None,
|
eot_threshold=None,
|
||||||
eot_timeout_ms=None,
|
eot_timeout_ms=None,
|
||||||
keyterm=[],
|
keyterm=[],
|
||||||
tag=[],
|
|
||||||
min_confidence=None,
|
min_confidence=None,
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -241,7 +240,8 @@ class DeepgramFluxSTTService(WebsocketSTTService):
|
|||||||
default_settings.eot_threshold = params.eot_threshold
|
default_settings.eot_threshold = params.eot_threshold
|
||||||
default_settings.eot_timeout_ms = params.eot_timeout_ms
|
default_settings.eot_timeout_ms = params.eot_timeout_ms
|
||||||
default_settings.keyterm = params.keyterm or []
|
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
|
default_settings.min_confidence = params.min_confidence
|
||||||
if params.mip_opt_out is not None:
|
if params.mip_opt_out is not None:
|
||||||
mip_opt_out = params.mip_opt_out
|
mip_opt_out = params.mip_opt_out
|
||||||
@@ -261,6 +261,7 @@ class DeepgramFluxSTTService(WebsocketSTTService):
|
|||||||
self._should_interrupt = should_interrupt
|
self._should_interrupt = should_interrupt
|
||||||
self._encoding = flux_encoding
|
self._encoding = flux_encoding
|
||||||
self._mip_opt_out = mip_opt_out
|
self._mip_opt_out = mip_opt_out
|
||||||
|
self._tag = tag or []
|
||||||
self._websocket_url = None
|
self._websocket_url = None
|
||||||
self._receive_task = None
|
self._receive_task = None
|
||||||
|
|
||||||
@@ -469,7 +470,7 @@ class DeepgramFluxSTTService(WebsocketSTTService):
|
|||||||
url_params.append(urlencode({"keyterm": keyterm}))
|
url_params.append(urlencode({"keyterm": keyterm}))
|
||||||
|
|
||||||
# Add tag parameters (can have multiple)
|
# 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}))
|
url_params.append(urlencode({"tag": tag_value}))
|
||||||
|
|
||||||
self._websocket_url = f"{self._url}?{'&'.join(url_params)}"
|
self._websocket_url = f"{self._url}?{'&'.join(url_params)}"
|
||||||
|
|||||||
@@ -186,7 +186,7 @@ class ElevenLabsSTTSettings(STTSettings):
|
|||||||
(coughing) in the transcription.
|
(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
|
@dataclass
|
||||||
@@ -277,8 +277,8 @@ class ElevenLabsSTTService(SegmentedSTTService):
|
|||||||
# 1. Initialize default_settings with hardcoded defaults
|
# 1. Initialize default_settings with hardcoded defaults
|
||||||
default_settings = ElevenLabsSTTSettings(
|
default_settings = ElevenLabsSTTSettings(
|
||||||
model="scribe_v2",
|
model="scribe_v2",
|
||||||
language="eng",
|
language=language_to_elevenlabs_language(Language.EN),
|
||||||
tag_audio_events=True,
|
tag_audio_events=None,
|
||||||
)
|
)
|
||||||
|
|
||||||
# 2. Apply direct init arg overrides (deprecated)
|
# 2. Apply direct init arg overrides (deprecated)
|
||||||
@@ -291,9 +291,7 @@ class ElevenLabsSTTService(SegmentedSTTService):
|
|||||||
_warn_deprecated_param("params", ElevenLabsSTTSettings)
|
_warn_deprecated_param("params", ElevenLabsSTTSettings)
|
||||||
if not settings:
|
if not settings:
|
||||||
if params.language is not None:
|
if params.language is not None:
|
||||||
default_settings.language = (
|
default_settings.language = language_to_elevenlabs_language(params.language)
|
||||||
self.language_to_service_language(params.language) or "eng"
|
|
||||||
)
|
|
||||||
default_settings.tag_audio_events = params.tag_audio_events
|
default_settings.tag_audio_events = params.tag_audio_events
|
||||||
|
|
||||||
# 4. Apply settings delta (canonical API, always wins)
|
# 4. Apply settings delta (canonical API, always wins)
|
||||||
@@ -354,10 +352,11 @@ class ElevenLabsSTTService(SegmentedSTTService):
|
|||||||
content_type="audio/x-wav",
|
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("model_id", self._settings.model)
|
||||||
data.add_field("language_code", self._settings.language)
|
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:
|
async with self._session.post(url, data=data, headers=headers) as response:
|
||||||
if response.status != 200:
|
if response.status != 200:
|
||||||
|
|||||||
@@ -215,7 +215,7 @@ class FalSTTService(SegmentedSTTService):
|
|||||||
# 1. Initialize default_settings with hardcoded defaults
|
# 1. Initialize default_settings with hardcoded defaults
|
||||||
default_settings = FalSTTSettings(
|
default_settings = FalSTTSettings(
|
||||||
model=None,
|
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)
|
# 2. (no deprecated direct args for this service)
|
||||||
@@ -224,9 +224,8 @@ class FalSTTService(SegmentedSTTService):
|
|||||||
if params is not None:
|
if params is not None:
|
||||||
_warn_deprecated_param("params", FalSTTSettings)
|
_warn_deprecated_param("params", FalSTTSettings)
|
||||||
if not settings:
|
if not settings:
|
||||||
default_settings.language = (
|
if params.language is not None:
|
||||||
language_to_fal_language(params.language) if params.language else "en"
|
default_settings.language = language_to_fal_language(params.language)
|
||||||
)
|
|
||||||
if params.task != "transcribe":
|
if params.task != "transcribe":
|
||||||
task = params.task
|
task = params.task
|
||||||
if params.chunk_level != "segment":
|
if params.chunk_level != "segment":
|
||||||
|
|||||||
@@ -512,7 +512,7 @@ class GoogleHttpTTSSettings(TTSSettings):
|
|||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class GoogleStreamTTSSettings(TTSSettings):
|
class GoogleTTSSettings(TTSSettings):
|
||||||
"""Settings for Google streaming TTS service.
|
"""Settings for Google streaming TTS service.
|
||||||
|
|
||||||
Parameters:
|
Parameters:
|
||||||
@@ -619,6 +619,13 @@ class GoogleHttpTTSService(TTSService):
|
|||||||
model=None,
|
model=None,
|
||||||
voice="en-US-Chirp3-HD-Charon",
|
voice="en-US-Chirp3-HD-Charon",
|
||||||
language="en-US",
|
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)
|
# 2. Apply direct init arg overrides (deprecated)
|
||||||
@@ -1008,13 +1015,13 @@ class GoogleTTSService(GoogleBaseTTSService):
|
|||||||
)
|
)
|
||||||
"""
|
"""
|
||||||
|
|
||||||
_settings: GoogleStreamTTSSettings
|
_settings: GoogleTTSSettings
|
||||||
|
|
||||||
class InputParams(BaseModel):
|
class InputParams(BaseModel):
|
||||||
"""Input parameters for Google streaming TTS configuration.
|
"""Input parameters for Google streaming TTS configuration.
|
||||||
|
|
||||||
.. deprecated:: 0.0.105
|
.. deprecated:: 0.0.105
|
||||||
Use ``GoogleStreamTTSSettings`` directly via the ``settings`` parameter instead.
|
Use ``GoogleTTSSettings`` directly via the ``settings`` parameter instead.
|
||||||
|
|
||||||
Parameters:
|
Parameters:
|
||||||
language: Language for synthesis. Defaults to English.
|
language: Language for synthesis. Defaults to English.
|
||||||
@@ -1034,7 +1041,7 @@ class GoogleTTSService(GoogleBaseTTSService):
|
|||||||
voice_cloning_key: Optional[str] = None,
|
voice_cloning_key: Optional[str] = None,
|
||||||
sample_rate: Optional[int] = None,
|
sample_rate: Optional[int] = None,
|
||||||
params: Optional[InputParams] = None,
|
params: Optional[InputParams] = None,
|
||||||
settings: Optional[GoogleStreamTTSSettings] = None,
|
settings: Optional[GoogleTTSSettings] = None,
|
||||||
**kwargs,
|
**kwargs,
|
||||||
):
|
):
|
||||||
"""Initializes the Google streaming TTS service.
|
"""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").
|
voice_id: Google TTS voice identifier (e.g., "en-US-Chirp3-HD-Charon").
|
||||||
|
|
||||||
.. deprecated:: 0.0.105
|
.. 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.
|
voice_cloning_key: The voice cloning key for Chirp 3 custom voices.
|
||||||
sample_rate: Audio sample rate in Hz. If None, uses default.
|
sample_rate: Audio sample rate in Hz. If None, uses default.
|
||||||
params: Language configuration parameters.
|
params: Language configuration parameters.
|
||||||
|
|
||||||
.. deprecated:: 0.0.105
|
.. deprecated:: 0.0.105
|
||||||
Use ``settings=GoogleStreamTTSSettings(...)`` instead.
|
Use ``settings=GoogleTTSSettings(...)`` instead.
|
||||||
|
|
||||||
settings: Runtime-updatable settings. When provided alongside deprecated
|
settings: Runtime-updatable settings. When provided alongside deprecated
|
||||||
parameters, ``settings`` values take precedence.
|
parameters, ``settings`` values take precedence.
|
||||||
**kwargs: Additional arguments passed to parent TTSService.
|
**kwargs: Additional arguments passed to parent TTSService.
|
||||||
"""
|
"""
|
||||||
# 1. Initialize default_settings with hardcoded defaults
|
# 1. Initialize default_settings with hardcoded defaults
|
||||||
default_settings = GoogleStreamTTSSettings(
|
default_settings = GoogleTTSSettings(
|
||||||
model=None,
|
model=None,
|
||||||
voice="en-US-Chirp3-HD-Charon",
|
voice="en-US-Chirp3-HD-Charon",
|
||||||
language="en-US",
|
language="en-US",
|
||||||
|
speaking_rate=None,
|
||||||
)
|
)
|
||||||
|
|
||||||
# 2. Apply direct init arg overrides (deprecated)
|
# 2. Apply direct init arg overrides (deprecated)
|
||||||
if voice_id is not None:
|
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
|
default_settings.voice = voice_id
|
||||||
|
|
||||||
# 3. Apply params overrides — only if settings not provided
|
# 3. Apply params overrides — only if settings not provided
|
||||||
if params is not None:
|
if params is not None:
|
||||||
_warn_deprecated_param("params", GoogleStreamTTSSettings)
|
_warn_deprecated_param("params", GoogleTTSSettings)
|
||||||
if not settings:
|
if not settings:
|
||||||
if params.language is not None:
|
if params.language is not None:
|
||||||
default_settings.language = self.language_to_service_language(params.language)
|
default_settings.language = self.language_to_service_language(params.language)
|
||||||
@@ -1104,7 +1112,7 @@ class GoogleTTSService(GoogleBaseTTSService):
|
|||||||
Args:
|
Args:
|
||||||
delta: Settings delta. Can include 'speaking_rate' (float).
|
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)
|
rate_value = float(delta.speaking_rate)
|
||||||
if not (0.25 <= rate_value <= 2.0):
|
if not (0.25 <= rate_value <= 2.0):
|
||||||
logger.warning(
|
logger.warning(
|
||||||
@@ -1308,6 +1316,9 @@ class GeminiTTSService(GoogleBaseTTSService):
|
|||||||
model="gemini-2.5-flash-tts",
|
model="gemini-2.5-flash-tts",
|
||||||
voice="Kore",
|
voice="Kore",
|
||||||
language="en-US",
|
language="en-US",
|
||||||
|
prompt=None,
|
||||||
|
multi_speaker=False,
|
||||||
|
speaker_configs=None,
|
||||||
)
|
)
|
||||||
|
|
||||||
# 2. Apply direct init arg overrides (deprecated)
|
# 2. Apply direct init arg overrides (deprecated)
|
||||||
|
|||||||
@@ -90,7 +90,6 @@ class SpeechmaticsSTTSettings(STTSettings):
|
|||||||
See ``SpeechmaticsSTTService.InputParams`` for detailed descriptions of each field.
|
See ``SpeechmaticsSTTService.InputParams`` for detailed descriptions of each field.
|
||||||
|
|
||||||
Parameters:
|
Parameters:
|
||||||
model: The operating point / model name.
|
|
||||||
domain: Domain for Speechmatics API.
|
domain: Domain for Speechmatics API.
|
||||||
turn_detection_mode: Endpoint handling mode.
|
turn_detection_mode: Endpoint handling mode.
|
||||||
speaker_active_format: Formatter for active speaker ID.
|
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.prefer_current_speaker = _params.prefer_current_speaker
|
||||||
default_settings.extra_params = _params.extra_params
|
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) ---
|
# --- 4. Settings delta (canonical API, always wins) ---
|
||||||
if settings is not None:
|
if settings is not None:
|
||||||
default_settings.apply_update(settings)
|
default_settings.apply_update(settings)
|
||||||
@@ -507,6 +500,13 @@ class SpeechmaticsSTTService(STTService):
|
|||||||
**kwargs,
|
**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
|
# Outbound frame queue
|
||||||
self._outbound_frames: asyncio.Queue[Frame] = asyncio.Queue()
|
self._outbound_frames: asyncio.Queue[Frame] = asyncio.Queue()
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user