Repository navigation
fix(stt): stop per-call language leaking in openai/elevenlabs, forward deepgram options to open streams - #7828
Open
Atharvsinh-codez wants to merge 5 commits into
Conversation
STT._recognize_impl wrote a `language` override back to self._opts, so a single recognize(language="fr") changed the language of every later recognize() and new stream. StreamAdapter passes its stream's language on every call, so a non-streaming OpenAI or Groq STT wrapped for a session ended up pinned to whatever language was last requested. Apply the override to a copy of the options for that request only, the same way stream() already does.
STT.update_options() stored enable_diarization and tags on the STT but left them out of the call that updates the open streams. Each stream keeps its own copy of the options, so it reconnected with the old values: turning diarization on mid-session never sent diarize=true, and new tags never reached Deepgram.
…ize() STT._recognize_impl wrote a `language` override to self._opts.language_code, so one recognize(language="fr") changed the language of every later batch request, the default language of new streams, and the fallback language reported on transcripts. StreamAdapter passes its stream's language on every call, so a wrapped batch STT stayed on the last language it was asked for. Use the override for that request only.
The stt branch asserts the anchor clamps to a 'now' captured before setup, but _process_stt_event reads time.time() again later. Any stall in between on a busy runner pushes the value past the 0.05s tolerance, which is what has been failing the unit-tests job (off by ~0.4-0.55s). Pin the clock the same way test_vad_anchor_survives_a_transcript_without_timestamps does.
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
This was referenced Oct 14, 2026
…tions update_options(enable_diarization=...) changed the options used for new and open streams but left capabilities.diarization at its constructor value, so MultiSpeakerAdapter still rejected an STT that had diarization turned on afterwards.
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Three small STT plugin fixes, plus a fix for the flaky test that is currently failing
unit-testson PRs. These were #7820, #7821 and #7822. I've put them in one PR so they're easier to review, and I'll close the other three.openai: don't persist the per-call language passed to
recognize()openai.STT._recognize_implwrote a per-calllanguageback toself._opts. So onerecognize(buffer, language="fr")changed the language for every laterrecognize()and every newstream()on that STT.This also hits the framework path.
StreamAdapterpasses its stream's language to everyrecognize()call, so any STT built on this plugin (groq.STTand the OpenAI-compatible providers too) stays on whatever language was requested last. Two streams with different languages overwrite each other's setting.The override now goes on a copy of the options for that one request. That's how
stream(language=...)already handles it, and #6097 made the same fix for Clova.elevenlabs: same bug in Scribe batch recognition
elevenlabs.STT._recognize_implwrote the per-calllanguagetoself._opts.language_code. After onerecognize(buffer, language="fr"):frstream()calls started infrlanguage_codein the response were tagged with the last overrideThe override now applies only to the request it came with.
deepgram: forward
enable_diarizationandtagsto open streamsdeepgram.STT.update_options()savesenable_diarizationandtagson the STT, but leaves both out of the call that updates open streams. Each stream keeps its own copy of the options, so it reconnects with the old values:stt.update_options(enable_diarization=True)mid-session reconnects withoutdiarize=true. No speaker IDs come back, and nothing reports an error.tagsnever reach Deepgram for the open stream.SpeechStream.update_options()already accepts both, andstt_v2already forwardstags. Only these two arguments were missing.test: freeze the clock in
test_skewed_provider_timestamptest_skewed_provider_timestamp[stt]currently failsunit-testson every PR I looked at, including unrelated ones like #7807 andfix/7805-credit-balance-exhausted-fatal. Each time the value is off by about 0.4 to 0.55s:The test captures
nowbefore setup._process_stt_eventthen callstime.time()again for the clamp, so any pause in between on a busy runner pushes the result past the 0.05s tolerance. It passes locally because nothing stalls there. I pinned the clock the same waytest_vad_anchor_survives_a_transcript_without_timestampsin the same file already does (#7398). The assertion and the behavior it checks are unchanged.Test plan
test_file_transcription_language_override_applies_to_one_callfails onmain(the second request sendsfr) and passes here. I checkedgroq.STTthe same way.test_recognize_language_override_applies_to_one_callfails onmain(['fr', 'fr']) and passes here (['fr', 'en']).test_stt_update_options_reaches_open_streams_diarization_and_tagsfails onmain(nodiarizein the reconnect URL) and passes here._process_stt_eventto mimic a slow runner. With that delay the old test fails exactly like CI (only[stt]), and the new version passes.uv run pytest tests/test_plugin_openai_stt_context.py tests/test_plugin_deepgram_stt.py tests/test_plugin_elevenlabs_stt.py: 200 passed.uv run pytest --unit --audio_eot: 5279 passed (I skippedtests/test_room.pylocally because it needs a local livekit-server binary).ruff check,ruff format --check, andscripts/check_types.pyare clean.