From f44b68812d93b7e7334e47411924cdf5e5c908fe Mon Sep 17 00:00:00 2001 From: Woody Date: Tue, 19 May 2026 13:34:06 +0800 Subject: [PATCH] fix: add diagnostic logging and OpenRouter language code filter Add transcribe-start/complete logs for both providers, error response body logging, and ASR provider in startup log. Filter yue (ISO 639-3) language code from OpenRouter STT requests. Ultraworked with Sisyphus Co-authored-by: Sisyphus --- backend/app/services/asr_providers.py | 36 ++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/backend/app/services/asr_providers.py b/backend/app/services/asr_providers.py index 1921461..e385fa5 100644 --- a/backend/app/services/asr_providers.py +++ b/backend/app/services/asr_providers.py @@ -39,6 +39,10 @@ class DashScopeASRProvider(ASRProvider): async def transcribe(self, audio_bytes: bytes, language: str) -> str: loop = asyncio.get_running_loop() + logger.info( + "asr-transcribe-start provider=dashscope model=%s audio_bytes=%d language=%s", + self._model, len(audio_bytes), language, + ) return await loop.run_in_executor( None, self._transcribe_sync, audio_bytes, language ) @@ -92,6 +96,10 @@ class OpenRouterASRProvider(ASRProvider): async def transcribe(self, audio_bytes: bytes, language: str) -> str: audio_b64 = base64.b64encode(audio_bytes).decode("ascii") + logger.info( + "asr-transcribe-start provider=openrouter model=%s url=%s audio_bytes=%d language=%s", + self._model, self._stt_url, len(audio_bytes), language, + ) payload: dict = { "model": self._model, @@ -100,7 +108,10 @@ class OpenRouterASRProvider(ASRProvider): "format": "wav", }, } - if language and language != "auto": + # OpenRouter STT expects ISO-639-1 (2-letter) codes. + # DashScope languages like "yue" (Cantonese, ISO-639-3) are not valid here. + # Omit to let auto-detection handle it. + if language and language not in ("auto", "yue"): payload["language"] = language try: @@ -112,6 +123,10 @@ class OpenRouterASRProvider(ASRProvider): if not text: raise ASRError("OpenRouter STT returned empty transcription") + logger.info( + "asr-transcribe-complete provider=openrouter text_len=%d", + len(text), + ) return _to_traditional(text) @retry( @@ -123,6 +138,12 @@ class OpenRouterASRProvider(ASRProvider): async def _call_stt_api(self, payload: dict) -> dict: client = await self._get_client() response = await client.post(self._stt_url, json=payload) + if response.status_code >= 400: + logger.error( + "openrouter-stt-error status=%d body=%s", + response.status_code, + response.text[:500], + ) response.raise_for_status() return response.json() @@ -134,8 +155,16 @@ class OpenRouterASRProvider(ASRProvider): def create_asr_provider(settings) -> ASRProvider: provider_name = settings.asr_provider + logger.info( + "asr-provider-selected provider=%s dashscope_key=%s openrouter_key=%s llm_base_url=%s", + provider_name, + "set" if settings.dashscope_api_key else "empty", + "set" if settings.openrouter_api_key else "empty", + settings.llm_base_url, + ) if provider_name == "dashscope": + logger.info("asr-provider-init provider=dashscope model=%s", settings.asr_model_name) return DashScopeASRProvider( api_key=settings.dashscope_api_key, model=settings.asr_model_name, @@ -147,6 +176,11 @@ def create_asr_provider(settings) -> ASRProvider: "OPENROUTER_API_KEY is not configured. " "Set it in .env to use OpenRouter ASR." ) + logger.info( + "asr-provider-init provider=openrouter model=%s url=%s", + settings.asr_openrouter_model, + f"{settings.llm_base_url.rstrip('/')}/audio/transcriptions", + ) return OpenRouterASRProvider( api_key=settings.openrouter_api_key, base_url=settings.llm_base_url,