Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changing digit formatting on an active stream has no effect until an unrelated restart

The requested digit-formatting change is saved (self._opts.numerals = numerals at livekit-plugins/livekit-plugins-deepgram/livekit/plugins/deepgram/stt_v2.py:368-369) but is never sent to the service and does not trigger a fresh connection, so the change is silently ignored on the live stream.
Impact: A user who turns numeral conversion on or off mid-session sees no change until the connection happens to restart for another reason.

Why the update is dropped in SpeechStreamv2.update_options

In SpeechStreamv2.update_options, numerals is only ever passed to the service through the connection URL built in _connect_ws (stt_v2.py:579-580); it is not one of the in-band Configure fields. However, numerals is missing from the needs_reconnect tuple (model, sample_rate, mip_opt_out, tags, endpoint_url) at stt_v2.py:376-377, and it is also not added to changed_options (stt_v2.py:394-401, unlike language_hint/keyterm). As a result, when only numerals changes, needs_reconnect is False, no Configure message is queued, and self._reconnect_event is never set, so the new value only reaches the server on a later reconnect caused by a different option. mip_opt_out, another connection-URL-only param, is correctly listed in needs_reconnect.

(Refers to lines 376-377)

Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ class STTOptions:
mip_opt_out: bool = False
tags: NotGivenOr[list[str]] = NOT_GIVEN
language_hint: NotGivenOr[list[str]] = NOT_GIVEN
numerals: bool = False


class STTv2(stt.STT):
Expand All @@ -77,6 +78,7 @@ def __init__(
http_session: aiohttp.ClientSession | None = None,
base_url: str = "wss://api.deepgram.com/v2/listen",
mip_opt_out: bool = False,
numerals: bool = False,
# deprecated
keyterms: NotGivenOr[list[str]] = NOT_GIVEN,
) -> None:
Expand All @@ -95,6 +97,8 @@ def __init__(
http_session: Optional aiohttp ClientSession to use for requests.
base_url: The base URL for Deepgram API. Defaults to "https://api.deepgram.com/v1/listen".
mip_opt_out: Whether to take part in the model improvement program
numerals: Whether to convert numbers from written format to numerical format. Supported by
both `flux-general-en` and `flux-general-multi`. Defaults to False.

Raises:
ValueError: If no API key is provided or found in environment variables.
Expand Down Expand Up @@ -147,6 +151,7 @@ def __init__(
mip_opt_out=mip_opt_out,
tags=_validate_tags(tags) if is_given(tags) else [],
language_hint=language_hint if is_given(language_hint) else [],
numerals=numerals,
eager_eot_threshold=eager_eot_threshold,
eot_threshold=eot_threshold,
eot_timeout_ms=eot_timeout_ms,
Expand Down Expand Up @@ -212,6 +217,7 @@ def update_options(
mip_opt_out: NotGivenOr[bool] = NOT_GIVEN,
tags: NotGivenOr[list[str]] = NOT_GIVEN,
language_hint: NotGivenOr[list[str]] = NOT_GIVEN,
numerals: NotGivenOr[bool] = NOT_GIVEN,
endpoint_url: NotGivenOr[str] = NOT_GIVEN,
# deprecated
keyterms: NotGivenOr[list[str]] = NOT_GIVEN,
Expand Down Expand Up @@ -256,6 +262,8 @@ def update_options(
"`language_hint` is only supported by `flux-general-multi` and will be ignored for model '%s'",
self._opts.model,
)
if is_given(numerals):
self._opts.numerals = numerals
if is_given(endpoint_url):
self._opts.endpoint_url = endpoint_url
if is_given(eager_eot_threshold):
Expand All @@ -272,6 +280,7 @@ def update_options(
endpoint_url=endpoint_url,
tags=tags,
language_hint=language_hint,
numerals=numerals,
eager_eot_threshold=eager_eot_threshold,
)

Expand Down Expand Up @@ -329,6 +338,7 @@ def update_options(
mip_opt_out: NotGivenOr[bool] = NOT_GIVEN,
tags: NotGivenOr[list[str]] = NOT_GIVEN,
language_hint: NotGivenOr[list[str]] = NOT_GIVEN,
numerals: NotGivenOr[bool] = NOT_GIVEN,
endpoint_url: NotGivenOr[str] = NOT_GIVEN,
eager_eot_threshold: NotGivenOr[float] = NOT_GIVEN,
# deprecated
Expand All @@ -355,6 +365,8 @@ def update_options(
self._opts.tags = _validate_tags(tags)
if is_given(language_hint):
self._opts.language_hint = language_hint
if is_given(numerals):
self._opts.numerals = numerals
if is_given(endpoint_url):
self._opts.endpoint_url = endpoint_url
if is_given(eager_eot_threshold):
Expand Down Expand Up @@ -564,6 +576,9 @@ async def _connect_ws(self) -> aiohttp.ClientWebSocketResponse:
if self._opts.language_hint:
live_config["language_hint"] = self._opts.language_hint

if self._opts.numerals:
live_config["numerals"] = self._opts.numerals

try:
ws = await asyncio.wait_for(
self._session.ws_connect(
Expand Down