Migrate Speechmatics STT plugin to Agent STT - #7028
Conversation
--- Import agent STT from pseudo-version + add constraints for model<->op
--- Revert everything except using agent STT SDK as the driver
--- model<->op sync
--- Rip out tdm handling
--- Added new tdm handling - depends on agent stt sdk
--- Completely remove Voice SDK
--- url handling
--- Error surfacing
--- Remove dead knobs
--- Wire dz fields to sdk
β¦t-migration # Conflicts: # livekit-plugins/livekit-plugins-speechmatics/livekit/plugins/speechmatics/stt.py # livekit-plugins/livekit-plugins-speechmatics/pyproject.toml
|
|
| # Log all other messages | ||
| else: | ||
| logger.debug(f"unhandled message: {event}", extra={"lk.pii.message": message}) | ||
| logger.debug(f"{event} -> {message}") |
There was a problem hiding this comment.
π‘ Unhandled provider messages logged without PII marker
The catch-all branch interpolates the full provider message into the debug log body via f-string, dropping the prior lk.pii.message structured marker, so payloads that can contain customer content are logged unredacted.
| logger.debug(f"{event} -> {message}") | |
| logger.debug("unhandled speechmatics message", extra={"event": str(event), "lk.pii.message": message}) |
Was this helpful? React with π or π to provide feedback.
--- fix capability obs issue with dz
There was a problem hiding this comment.
Devin Review found 2 new potential issues.
2 flags not posted on this PR by your GitHub settings β view them in Devin Review. (Configure)
| streaming=True, | ||
| interim_results=True, | ||
| diarization=enable_diarization if is_given(enable_diarization) else True, | ||
| diarization=True, |
There was a problem hiding this comment.
π‘ Diarization capability advertised even when disabled
The diarization capability is hardcoded to True regardless of enable_diarization=False, whereas it previously mirrored the flag. MultiSpeakerAdapter gates on this capability, so it accepts an STT that will never diarize.
| diarization=True, | |
| diarization=enable_diarization if is_given(enable_diarization) else True, |
Was this helpful? React with π or π to provide feedback.
--- dz capability resolution
--- Added finalize gate if self.vad is not none
The plugin is a translation layer between LiveKit's STT interface and the Speechmatics Agent STT endpoint (
/v2/agent).It used to talk to Speechmatics' older "voice" endpoint through the
speechmatics-voiceSDK. This PR moves it to the dedicated Agent STT endpoint (/v2/agent) and its SDK,speechmatics-agent-stt- and makes all the necessary consequential changes:Changelog
Non-breaking:
max_speakers,speaker_sensitivity,prefer_current_speaker,known_speakers) are now sent to the serverAPIErroron the stream.Breaking:
OperatingPoint(enhanced/standard) is removed. Usemodelβ theModelenum or astring like
"linden-1".operating_pointstill works but is deprecated, and onlylinden-1is valid.
TurnDetectionModeis now justDEFAULT(server-side VAD) andEXTERNAL; the oldFIXED/ADAPTIVE/SMART_TURNvalues are gone. The default isDEFAULT:)focus_speakers,ignore_speakers,focus_mode,SpeakerFocusMode,update_speakers(). Agent STT has no equivalent.max_delay,end_of_utterance_silence_trigger,end_of_utterance_max_delay,punctuation_overrides,speaker_passive_format.base_urlis nowwss://global.rt.speechmatics.com/v2/agent. This might require some discussion.What's left
Context: problems in the previous plugin
transcriptfield; the old SDK expected a list of segments with atextfield, so everytranscript was parsed against a shape that wasn't there and dropped. Now
Segment.from_messagereads the singular segment the server actually sends.
max_delay,enable_entities,vad_config, ...), soStartRecognitionwas rejected and the socket closedat startup. The plugin now sends only allowed fields.
turn_detection_mode=EXTERNALturns off server-side VAD,but Agent STT needs that VAD to finalize a turn β so nothing ever finalized. The default is now
server-side VAD, which endpoints on its own;
EXTERNALstays for callers who drive turns viafinalize().linden-1, but the enum offeredenhanced/standard. Resolution now runs through_resolve_model(model, operating_point)βmodelpreferred,operating_pointdeprecated, conflict is a fail-fast error, defaultlinden-1.timeout and no reason. Server errors now raise an
APIErroron the stream (non-retryable for abad config, retryable for a dropped connection).
punctuation overrides, end-of-utterance tuning β were exposed and either ignored or rejected.
They're removed.
max_speakersand friends were accepted from the caller but neversent; they're now put on the wire.
livekit.plugins.silero, an ImportErrorwaiting to happen on a package the plugin never declared. Nothing is auto-loaded now; pass a VAD
explicitly if you want one.