fix(voice): correct yandex asr endpoints
This commit is contained in:
+3
-2
@@ -76,9 +76,10 @@ AI_VOICE_AUDIOSOCKET_ENABLED=0
|
||||
AI_VOICE_AUDIOSOCKET_HOST=0.0.0.0
|
||||
AI_VOICE_AUDIOSOCKET_PORT=9019
|
||||
AI_VOICE_ASR_MODEL=gpt-4o-mini-transcribe
|
||||
AI_VOICE_ASR_YANDEX_API_BASE=https://stt.api.ml.yandexcloud.kz
|
||||
AI_VOICE_ASR_YANDEX_API_BASE=https://stt.api.cloud.yandex.net
|
||||
AI_VOICE_ASR_YANDEX_OPERATIONS_BASE=https://operation.api.cloud.yandex.net
|
||||
AI_VOICE_ASR_YANDEX_API_VERSION=auto
|
||||
AI_VOICE_ASR_YANDEX_GRPC_TARGET=stt.api.ml.yandexcloud.kz:443
|
||||
AI_VOICE_ASR_YANDEX_GRPC_TARGET=stt.api.cloud.yandex.net:443
|
||||
AI_VOICE_ASR_YANDEX_API_KEY=
|
||||
AI_VOICE_ASR_YANDEX_IAM_TOKEN=
|
||||
AI_VOICE_ASR_YANDEX_FOLDER_ID=
|
||||
|
||||
@@ -39,13 +39,20 @@ def _openai_asr_model() -> str:
|
||||
def _yandex_asr_api_base() -> str:
|
||||
explicit = os.getenv("AI_VOICE_ASR_YANDEX_API_BASE", "").strip()
|
||||
if explicit:
|
||||
return explicit.rstrip("/")
|
||||
tts_base = os.getenv("AI_VOICE_TTS_YANDEX_API_BASE", "https://tts.api.ml.yandexcloud.kz").strip().lower()
|
||||
if "yandexcloud.kz" in tts_base:
|
||||
return "https://stt.api.ml.yandexcloud.kz"
|
||||
normalized = explicit.rstrip("/")
|
||||
if "stt.api.ml.yandexcloud.kz" in normalized.lower():
|
||||
return "https://stt.api.cloud.yandex.net"
|
||||
return normalized
|
||||
return "https://stt.api.cloud.yandex.net"
|
||||
|
||||
|
||||
def _yandex_asr_operations_base() -> str:
|
||||
explicit = os.getenv("AI_VOICE_ASR_YANDEX_OPERATIONS_BASE", "").strip()
|
||||
if explicit:
|
||||
return explicit.rstrip("/")
|
||||
return "https://operation.api.cloud.yandex.net"
|
||||
|
||||
|
||||
def _yandex_asr_api_key() -> str:
|
||||
return (
|
||||
os.getenv("AI_VOICE_ASR_YANDEX_API_KEY", "").strip()
|
||||
@@ -99,7 +106,8 @@ def _yandex_asr_api_version(api_base: str) -> str:
|
||||
return "v1"
|
||||
if raw in {"v3", "v3_async", "async"}:
|
||||
return "v3"
|
||||
if "yandexcloud.kz" in str(api_base or "").lower():
|
||||
normalized_base = str(api_base or "").lower()
|
||||
if "stt.api.cloud.yandex.net" in normalized_base or "stt.api.ml.yandexcloud.kz" in normalized_base:
|
||||
return "v3"
|
||||
return "v1"
|
||||
|
||||
@@ -116,9 +124,9 @@ def _yandex_asr_poll_interval_seconds() -> float:
|
||||
def _yandex_asr_grpc_target(api_base: str) -> str:
|
||||
explicit = os.getenv("AI_VOICE_ASR_YANDEX_GRPC_TARGET", "").strip()
|
||||
if explicit:
|
||||
if "stt.api.ml.yandexcloud.kz" in explicit.lower():
|
||||
return "stt.api.cloud.yandex.net:443"
|
||||
return explicit
|
||||
if "yandexcloud.kz" in str(api_base or "").lower():
|
||||
return "stt.api.ml.yandexcloud.kz:443"
|
||||
return "stt.api.cloud.yandex.net:443"
|
||||
|
||||
|
||||
@@ -296,6 +304,7 @@ class YandexSpeechKitASRProvider(ASRProvider):
|
||||
self._api_key = str(api_key if api_key is not None else _yandex_asr_api_key()).strip()
|
||||
self._iam_token = str(iam_token if iam_token is not None else _yandex_asr_iam_token()).strip()
|
||||
self._folder_id = str(folder_id if folder_id is not None else _yandex_asr_folder_id()).strip()
|
||||
self._operations_base = _yandex_asr_operations_base()
|
||||
self._timeout_seconds = max(
|
||||
float(timeout_seconds if timeout_seconds is not None else _yandex_asr_timeout_seconds()),
|
||||
3.0,
|
||||
@@ -417,7 +426,7 @@ class YandexSpeechKitASRProvider(ASRProvider):
|
||||
raise TimeoutError("Yandex ASR v3 recognition timed out")
|
||||
time.sleep(self._poll_interval_seconds)
|
||||
operation_response = client.get(
|
||||
f"{self._api_base}/operations/{operation_id}",
|
||||
f"{self._operations_base}/operations/{operation_id}",
|
||||
headers=headers,
|
||||
)
|
||||
operation_response.raise_for_status()
|
||||
|
||||
@@ -132,7 +132,7 @@ def test_yandex_asr_provider_supports_kz_v3_async_rest(monkeypatch):
|
||||
|
||||
def post(self, url: str, *, headers: dict[str, str], json: dict) -> _DummyResponse:
|
||||
calls.append({"method": "POST", "url": url, "headers": headers, "json": json})
|
||||
return _DummyResponse({"id": "operation-1", "done": True})
|
||||
return _DummyResponse({"id": "operation-1", "done": False})
|
||||
|
||||
def get(
|
||||
self,
|
||||
@@ -142,6 +142,8 @@ def test_yandex_asr_provider_supports_kz_v3_async_rest(monkeypatch):
|
||||
params: dict[str, str] | None = None,
|
||||
) -> _DummyResponse:
|
||||
calls.append({"method": "GET", "url": url, "headers": headers, "params": params or {}})
|
||||
if "operation.api.cloud.yandex.net/operations/" in url:
|
||||
return _DummyResponse({"id": "operation-1", "done": True})
|
||||
return _DummyResponse(
|
||||
{
|
||||
"finalRefinement": {
|
||||
@@ -158,6 +160,7 @@ def test_yandex_asr_provider_supports_kz_v3_async_rest(monkeypatch):
|
||||
|
||||
monkeypatch.setenv("AI_VOICE_ASR_YANDEX_API_KEY", "asr-key")
|
||||
monkeypatch.setenv("AI_VOICE_ASR_YANDEX_API_BASE", "https://stt.api.ml.yandexcloud.kz")
|
||||
monkeypatch.delenv("AI_VOICE_ASR_YANDEX_OPERATIONS_BASE", raising=False)
|
||||
monkeypatch.setenv("AI_VOICE_ASR_YANDEX_FOLDER_ID", "folder-test")
|
||||
monkeypatch.setenv("AI_VOICE_ASR_YANDEX_POLL_INTERVAL_SECONDS", "0.05")
|
||||
monkeypatch.setattr(asr_module.httpx, "Client", _DummyClient)
|
||||
@@ -167,14 +170,16 @@ def test_yandex_asr_provider_supports_kz_v3_async_rest(monkeypatch):
|
||||
|
||||
assert result.text == "almaty schedule"
|
||||
assert result.language == "ru-RU"
|
||||
assert calls[0]["url"] == "https://stt.api.ml.yandexcloud.kz/stt/v3/recognizeFileAsync"
|
||||
assert calls[0]["url"] == "https://stt.api.cloud.yandex.net/stt/v3/recognizeFileAsync"
|
||||
assert calls[0]["headers"]["Authorization"] == "Api-Key asr-key"
|
||||
assert calls[0]["headers"]["Content-Type"] == "application/json"
|
||||
assert calls[0]["headers"]["x-folder-id"] == "folder-test"
|
||||
assert calls[0]["json"]["recognitionModel"]["audioFormat"]["rawAudio"]["sampleRateHertz"] == "8000"
|
||||
assert calls[0]["json"]["recognitionModel"]["languageRestriction"]["languageCode"] == ["ru-RU"]
|
||||
assert calls[1]["url"] == "https://stt.api.ml.yandexcloud.kz/stt/v3/getRecognition"
|
||||
assert calls[1]["params"] == {"operationId": "operation-1"}
|
||||
assert calls[1]["url"] == "https://operation.api.cloud.yandex.net/operations/operation-1"
|
||||
assert calls[1]["params"] == {}
|
||||
assert calls[2]["url"] == "https://stt.api.cloud.yandex.net/stt/v3/getRecognition"
|
||||
assert calls[2]["params"] == {"operationId": "operation-1"}
|
||||
|
||||
|
||||
def test_yandex_buffered_streaming_provider_buffers_pcm_until_finalize():
|
||||
|
||||
Reference in New Issue
Block a user