diff --git a/src/elevenlabs/realtime/scribe.py b/src/elevenlabs/realtime/scribe.py index 6409253d..091ea77a 100644 --- a/src/elevenlabs/realtime/scribe.py +++ b/src/elevenlabs/realtime/scribe.py @@ -67,6 +67,8 @@ class RealtimeAudioOptions(typing.TypedDict, total=False): min_silence_duration_ms: int language_code: str include_timestamps: bool + keyterms: typing.List[str] + no_verbatim: bool class RealtimeUrlOptions(typing.TypedDict, total=False): @@ -93,6 +95,8 @@ class RealtimeUrlOptions(typing.TypedDict, total=False): min_silence_duration_ms: int language_code: str include_timestamps: bool + keyterms: typing.List[str] + no_verbatim: bool class ScribeRealtime: @@ -197,6 +201,8 @@ async def _connect_audio(self, options: RealtimeAudioOptions) -> RealtimeConnect min_silence_duration_ms = options.get("min_silence_duration_ms") language_code = options.get("language_code") include_timestamps = options.get("include_timestamps", False) + keyterms = options.get("keyterms") + no_verbatim = options.get("no_verbatim") if not audio_format or not sample_rate: raise ValueError("audio_format and sample_rate are required for manual audio mode") @@ -212,6 +218,8 @@ async def _connect_audio(self, options: RealtimeAudioOptions) -> RealtimeConnect min_silence_duration_ms=min_silence_duration_ms, language_code=language_code, include_timestamps=include_timestamps, + keyterms=keyterms, + no_verbatim=no_verbatim, ) # Connect to WebSocket @@ -244,6 +252,8 @@ async def _connect_url(self, options: RealtimeUrlOptions) -> RealtimeConnection: min_silence_duration_ms = options.get("min_silence_duration_ms") language_code = options.get("language_code") include_timestamps = options.get("include_timestamps", False) + keyterms = options.get("keyterms") + no_verbatim = options.get("no_verbatim") if not url: raise ValueError("url is required for URL mode") @@ -263,6 +273,8 @@ async def _connect_url(self, options: RealtimeUrlOptions) -> RealtimeConnection: min_silence_duration_ms=min_silence_duration_ms, language_code=language_code, include_timestamps=include_timestamps, + keyterms=keyterms, + no_verbatim=no_verbatim, ) # Connect to WebSocket @@ -365,7 +377,9 @@ def _build_websocket_url( min_speech_duration_ms: typing.Optional[int] = None, min_silence_duration_ms: typing.Optional[int] = None, language_code: typing.Optional[str] = None, - include_timestamps: typing.Optional[bool] = None + include_timestamps: typing.Optional[bool] = None, + keyterms: typing.Optional[typing.List[str]] = None, + no_verbatim: typing.Optional[bool] = None, ) -> str: """Build the WebSocket URL with query parameters""" params = [ @@ -384,6 +398,11 @@ def _build_websocket_url( params.append((key, str(value))) if include_timestamps is not None: params.append(("include_timestamps", str(include_timestamps).lower())) + if keyterms is not None: + for term in keyterms: + params.append(("keyterms", term)) + if no_verbatim is not None: + params.append(("no_verbatim", str(no_verbatim).lower())) return build_ws_url(self.base_url, ["v1", "speech-to-text", "realtime"], params) diff --git a/tests/test_stt_realtime.py b/tests/test_stt_realtime.py index bd50f232..5b1a7386 100644 --- a/tests/test_stt_realtime.py +++ b/tests/test_stt_realtime.py @@ -95,6 +95,51 @@ def test_url_converts_http_to_ws(self): assert url.startswith("ws://localhost:8080") + def test_includes_keyterms_as_repeated_query_params(self): + """Test that keyterms are included as repeated query params""" + url = self.scribe._build_websocket_url( + model_id="scribe_v2_realtime", + audio_format="pcm_16000", + commit_strategy="manual", + keyterms=["ElevenLabs", "Scribe"], + ) + + assert "keyterms=ElevenLabs" in url + assert "keyterms=Scribe" in url + + def test_includes_no_verbatim_true(self): + """Test that no_verbatim=true is included when set to True""" + url = self.scribe._build_websocket_url( + model_id="scribe_v2_realtime", + audio_format="pcm_16000", + commit_strategy="manual", + no_verbatim=True, + ) + + assert "no_verbatim=true" in url + + def test_includes_no_verbatim_false(self): + """Test that no_verbatim=false is included when set to False""" + url = self.scribe._build_websocket_url( + model_id="scribe_v2_realtime", + audio_format="pcm_16000", + commit_strategy="manual", + no_verbatim=False, + ) + + assert "no_verbatim=false" in url + + def test_omits_keyterms_and_no_verbatim_when_not_specified(self): + """Test that keyterms and no_verbatim are omitted when not specified""" + url = self.scribe._build_websocket_url( + model_id="scribe_v2_realtime", + audio_format="pcm_16000", + commit_strategy="manual", + ) + + assert "keyterms" not in url + assert "no_verbatim" not in url + class TestConnectValidation: """Tests for connect method validation"""