diff --git a/gateway/run.py b/gateway/run.py index cef8dc845fa6..9d75774010f1 100644 --- a/gateway/run.py +++ b/gateway/run.py @@ -17968,7 +17968,17 @@ class GatewayRunner(GatewayAuthorizationMixin, GatewayKanbanWatchersMixin, Gatew return f"{prefix}\n\n{user_text}", [] return prefix, [] - from tools.transcription_tools import transcribe_audio + try: + from tools.transcription_tools import transcribe_audio + except ModuleNotFoundError as e: + logger.error("Transcription module unavailable: %s", e) + unavailable_note = "[voice message could not be transcribed]" + _placeholder = "(The user sent a message with no text content)" + if user_text and user_text.strip() == _placeholder: + return unavailable_note, [] + if user_text: + return f"{unavailable_note}\n\n{user_text}", [] + return unavailable_note, [] enriched_parts = [] successful_transcripts: List[str] = [] diff --git a/tests/gateway/test_stt_config.py b/tests/gateway/test_stt_config.py index 5006eafee319..3a0b54ea69a6 100644 --- a/tests/gateway/test_stt_config.py +++ b/tests/gateway/test_stt_config.py @@ -143,6 +143,44 @@ async def test_enrich_message_with_transcription_returns_tuple_for_empty_content assert transcripts == ["hello from a captionless voice note"] +@pytest.mark.parametrize( + ("user_text", "expected_text"), + [ + ("caption", "[voice message could not be transcribed]\n\ncaption"), + ("", "[voice message could not be transcribed]"), + ( + "(The user sent a message with no text content)", + "[voice message could not be transcribed]", + ), + ], +) +@pytest.mark.asyncio +async def test_enrich_message_with_transcription_handles_missing_transcription_module_gracefully( + user_text, + expected_text, +): + from gateway.run import GatewayRunner + + runner = GatewayRunner.__new__(GatewayRunner) + runner.config = GatewayConfig(stt_enabled=True) + + real_import = __import__ + + def fake_import(name, globals=None, locals=None, fromlist=(), level=0): + if name == "tools.transcription_tools": + raise ModuleNotFoundError("No module named 'tools.transcription_tools'") + return real_import(name, globals, locals, fromlist, level) + + with patch("builtins.__import__", side_effect=fake_import): + result, transcripts = await runner._enrich_message_with_transcription( + user_text, + ["/tmp/voice.ogg"], + ) + + assert result == expected_text + assert transcripts == [] + + @pytest.mark.asyncio async def test_prepare_inbound_message_text_transcribes_queued_voice_event(): from gateway.run import GatewayRunner