feat: SaluteSpeech STT для пилота + запрет зарубежного STT вне демо #127

Merged
Eleboba merged 1 commits from feat/121-salute-stt into dev 2026-10-31 17:14:08 +03:00
Owner

Refs #121 — живая проверка ждёт ключ SaluteSpeech, поэтому задача остаётся открытой.

Что сделано

  • SaluteSTT (app/llm/stt.py) за протоколом SpeechToText: синхронный REST speech:recognize, из WAV браузера снимается заголовок, уходит PCM 16 бит mono (audio/x-pcm;bit=16;rate=…), language=ru-RU. Без gRPC и protobuf.
  • OAuth-токен кешируется на процесс, обновляется за минуту до истечения и один раз по 401. Ретраи на 429/5xx как у OpenRouter.
  • Настройки: STT_PROVIDER=salute, SALUTE_SPEECH_CREDENTIALS (SecretStr), SALUTE_SPEECH_SCOPE, SALUTE_SPEECH_CA (корневой сертификат Минцифры, TLS проверяется всегда).
  • Guard: STT_PROVIDER=openrouter при DEMO_CLOCK=false — ошибка настроек, приложение не стартует. auto выбирает Salute при наличии кредов; вне демо без них голос выключен (не OpenRouter и не mock).
  • Не-PCM/не-mono WAV → 415 вместо 500.
  • ADR-016.

Проверка

  • Новые тесты с httpx.MockTransport: формат запроса, кеш токена и обновление по 401, пустой результат → «нет речи», ошибки, отказ от стерео, выбор провайдера, guard вне демо, несуществующий CA.
  • Полный прогон: 1092 passed, 1 skipped; ruff чисто.
  • Дев-сервер работает с DEMO_CLOCK=true — на нём ничего не меняется.

🤖 Generated with Claude Code

Refs #121 — живая проверка ждёт ключ SaluteSpeech, поэтому задача остаётся открытой. ## Что сделано - `SaluteSTT` (`app/llm/stt.py`) за протоколом `SpeechToText`: синхронный REST `speech:recognize`, из WAV браузера снимается заголовок, уходит PCM 16 бит mono (`audio/x-pcm;bit=16;rate=…`), `language=ru-RU`. Без gRPC и protobuf. - OAuth-токен кешируется на процесс, обновляется за минуту до истечения и один раз по 401. Ретраи на 429/5xx как у OpenRouter. - Настройки: `STT_PROVIDER=salute`, `SALUTE_SPEECH_CREDENTIALS` (SecretStr), `SALUTE_SPEECH_SCOPE`, `SALUTE_SPEECH_CA` (корневой сертификат Минцифры, TLS проверяется всегда). - **Guard:** `STT_PROVIDER=openrouter` при `DEMO_CLOCK=false` — ошибка настроек, приложение не стартует. `auto` выбирает Salute при наличии кредов; вне демо без них голос выключен (не OpenRouter и не mock). - Не-PCM/не-mono WAV → 415 вместо 500. - ADR-016. ## Проверка - Новые тесты с `httpx.MockTransport`: формат запроса, кеш токена и обновление по 401, пустой результат → «нет речи», ошибки, отказ от стерео, выбор провайдера, guard вне демо, несуществующий CA. - Полный прогон: 1092 passed, 1 skipped; `ruff` чисто. - Дев-сервер работает с `DEMO_CLOCK=true` — на нём ничего не меняется. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
Eleboba added this to the Грант ВШЭ · пилот «Династия» milestone 2026-10-31 17:11:45 +03:00
Eleboba added 1 commit 2026-10-31 17:11:46 +03:00
Refs #121

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Eleboba merged commit 50b48a7290 into dev 2026-10-31 17:14:08 +03:00
Sign in to join this conversation.