From cfc8db3fe7dc141b983abbb8bcd33e43dfe388ff Mon Sep 17 00:00:00 2001 From: Xin Wang Date: Thu, 26 Feb 2026 12:04:59 +0800 Subject: [PATCH] Implement API URL resolution in OpenAICompatibleASRService to ensure correct endpoint handling for transcription requests. --- engine/services/openai_compatible_asr.py | 28 +++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/engine/services/openai_compatible_asr.py b/engine/services/openai_compatible_asr.py index bcf0fae..7972189 100644 --- a/engine/services/openai_compatible_asr.py +++ b/engine/services/openai_compatible_asr.py @@ -9,6 +9,7 @@ import io import os import wave from typing import AsyncIterator, Optional, Callable, Awaitable +from urllib.parse import urlparse, urlunparse from loguru import logger try: @@ -75,7 +76,8 @@ class OpenAICompatibleASRService(BaseASRService): raise RuntimeError("aiohttp is required for OpenAICompatibleASRService") self.api_key = api_key or os.getenv("ASR_API_KEY") or os.getenv("SILICONFLOW_API_KEY") - self.api_url = api_url or os.getenv("ASR_API_URL") or self.API_URL + raw_api_url = api_url or os.getenv("ASR_API_URL") or self.API_URL + self.api_url = self._resolve_transcriptions_endpoint(raw_api_url) self.model = self.MODELS.get(model.lower(), model) self.interim_interval_ms = interim_interval_ms self.min_audio_for_interim_ms = min_audio_for_interim_ms @@ -97,6 +99,30 @@ class OpenAICompatibleASRService(BaseASRService): self._running = False logger.info(f"OpenAICompatibleASRService initialized with model: {self.model}") + + @staticmethod + def _resolve_transcriptions_endpoint(api_url: str) -> str: + """ + Accept either: + - base URL: https://host/v1 + - full endpoint: https://host/v1/audio/transcriptions + and always return the final transcriptions endpoint URL. + """ + raw = str(api_url or "").strip() + if not raw: + return OpenAICompatibleASRService.API_URL + + parsed = urlparse(raw) + path = (parsed.path or "").rstrip("/") + if path.endswith("/audio/transcriptions"): + return raw + + if not path: + new_path = "/audio/transcriptions" + else: + new_path = f"{path}/audio/transcriptions" + + return urlunparse(parsed._replace(path=new_path)) async def connect(self) -> None: """Connect to the service."""