Broad refactor of service settings and how they’re updated at runtime#3714
Broad refactor of service settings and how they’re updated at runtime#3714
Conversation
|
|
||
| self.set_model_name(model) | ||
| self.set_voice(voice_id) | ||
| self._voice_id = voice_id |
There was a problem hiding this comment.
Previously it wasn't clear whether set_voice/set_model/set_language were meant to be public APIs that users could directly invoke—in which case they should handle applying the change by reconnecting if necessary, etc.—or whether they were meant to only be "bookkeeping" methods, invokable only by subclasses, to update the underlying instance variables (_voice_id, etc).
I've made the decision here to make set_voice/set_model/set_language the "public" methods (even though we probably would suggest that users to use *UpdateSettingsFrames instead) and if we just need to update bookkeeping, access the instance variable directly.
There was a problem hiding this comment.
We do use set_voice() directly in one example.
25536e8 to
b1f4c32
Compare
| language_codes: List of Google STT language code strings | ||
| (e.g. ``["en-US"]``). | ||
|
|
||
| .. deprecated:: 0.0.103 |
There was a problem hiding this comment.
TODO: update this (and all other occurrences of this) if it looks like these changes will land in a different version
7a8f453 to
6d7794f
Compare
| model: Any = field(default_factory=lambda: NOT_GIVEN) | ||
| """AI model identifier (e.g. ``"gpt-4o"``, ``"eleven_turbo_v2_5"``).""" | ||
|
|
||
| extra: Dict[str, Any] = field(default_factory=dict) |
There was a problem hiding this comment.
Note that this PR doesn't go through every service and add handling for the extra field. It will be up to each service to add it when it's a priority. This can be done piecemeal.
…ce settings discoverable and strongly-typed. Service settings can be updated at runtime with `*UpdateSettingsFrame`s. Does not (yet) touch `InputParams`, to avoid scope creep and touching something currently part of the public API. But there is a lot of overlap between `*Settings` object fields and `InputParams` fields. Other than discoverability/typing, these are some other improvements brought by this refactor: - There is now a single code path (see `_update_settings_from_typed`) where services can respond to settings changes (by, say, reconnecting if needed), improving maintainability and guaranteeing one and only one reconnection no matter which settings changed - `set_language`/`set_model`/`set_voice`—which we're assuming are usable as public methods, though *not* recommended over `*UpdateSettingsFrame`—all use the same code path as settings updates. They're also now all consistent in that, if a service needs to respond to a change (by, say, reconnecting if needed), any of these methods will kick off that process. Note that this is technically a behavior change. - Several services now properly react to changed settings by reconnecting: - `AWSTranscribeSTTService` - `AzureSTTService` - `SonioxSTTService` - `GladiaSTTService` - `SpeechmaticsSTTService` - `AssemblyAISTTService` - `CartesiaSTTService` - `FishAudioTTSService` (would previously only reconnect when `model` changed) - `GoogleSTTService` - `SpeechmaticsSTTService` (which previously only handled *some* settings updates through a nonstandard public `update_params` method) - `GradiumSTTService` - `NvidiaSegmentedSTTService` (which previously only handled changes to language) - Bookkeeping across various services has been reduced, mostly by deduping ivars; the `self._settings` ivar is treated as the source of truth NOTE: I pretty much guarantee that there are services missed in this PR in terms of bringing to consistency with how updates are handled (like whether changes in certain fields trigger reconnects when they need to). We can squash remaining inconsistencies as we stumble onto them, service by service. The goal here is to get things *mostly* in order, and establish the infrastructure and patterns we'll need going forward.
…d-service-settings path. `filter_incomplete_user_turns` and `user_turn_completion_config` were only handled in the legacy dict-based `_update_settings` code path. This adds them to `LLMSettings` and introduces `LLMService._update_settings_from_typed` so the typed path handles them too.
…or better editor support. Standardize all STT, TTS, and LLM service classes to declare `_settings` with the narrowed Settings type as a class-level annotation. This gives editors and type checkers the specific type when hovering or autocompleting on `self._settings` in each service and its subclasses. Inline `self._settings: Type = ...` assignments are replaced with plain `self._settings = ...`.
…UpdateSettingsFrame`.
- NvidiaSTTService.set_model: convert to proper DeprecationWarning (model can't change at runtime for Riva streaming STT) - NvidiaTTSService.set_model: same treatment for Riva TTS - NvidiaSegmentedSTTService.set_model: remove — base class now routes through _update_settings_from_typed which re-creates the recognition config - GeminiTTSService.set_voice: remove — move AVAILABLE_VOICES validation into _update_settings_from_typed so it fires on both legacy and new paths
…ngs_from_typed` to `_update_settings`. Now that all services use typed `ServiceSettings` objects, this removes the interim scaffolding that supported both dict-based and typed settings paths in parallel. Specifically: removes old dict-based `_update_settings(settings: Mapping)` methods from base classes, removes `isinstance(self._settings, ServiceSettings)` guards, simplifies `process_frame` branching, and renames `_update_settings_from_typed` to `_update_settings` across all ~30 service implementations. Also renames the no-arg `_update_settings()` helper on realtime services to `_send_session_update()` to avoid collision, adds `from_mapping` overrides on `GoogleLLMSettings` and `AnthropicLLMSettings` for ThinkingConfig dict-to-object conversion, and replaces a broken no-arg `_update_settings()` call in Gemini Live with a TODO.
465b700 to
b08548a
Compare
…settings pattern.
| model: The Deepgram model name to use. | ||
| Top-level ``model`` and ``language`` are the source of truth. When | ||
| they are given in *update* their values are propagated into | ||
| ``live_options``. When only ``live_options`` is given, its ``model`` |
There was a problem hiding this comment.
Developers will want to change more than just model and language. Is it possible to make any live_options change apply, as well?
Does not (yet) touch
InputParams, to avoid scope creep.Maybe the best way to understand these changes is to check out the COMMUNITY_INTEGRATIONS.md changes.