From 71d908c6b5f6e8744bfa877843f1c7996d1d5263 Mon Sep 17 00:00:00 2001 From: claude_code Date: Sun, 21 Jun 2026 20:58:08 +0300 Subject: [PATCH] docs(backlog): remove STT providers and async design doc Delete the backlog markdown file that outlined additional STT providers and the future async transcription architecture, as the content is now superseded by newer implementation plans. --- docs/backlog/stt-providers-and-async.md | 192 ------------------------ 1 file changed, 192 deletions(-) delete mode 100644 docs/backlog/stt-providers-and-async.md diff --git a/docs/backlog/stt-providers-and-async.md b/docs/backlog/stt-providers-and-async.md deleted file mode 100644 index 58da2879..00000000 --- a/docs/backlog/stt-providers-and-async.md +++ /dev/null @@ -1,192 +0,0 @@ -# STT: дополнительные провайдеры и переход на асинхронную схему - -> Статус: беклог / план развития. Контекст — фича «голосовая диктовка» (STT, -> speech-to-text): кнопка-микрофон в чате агента и в редакторе, аудио -> распознаётся на сервере через AI-провайдер воркспейса. Документ фиксирует -> (1) какие ещё форматы STT-API имеет смысл поддержать и как, и (2) как в -> будущем перейти с текущей синхронной схемы (push-to-talk) на асинхронную. - -## 1. Где мы сейчас - -Распознавание построено как **синхронный запрос-ответ**: - -- Клиент пишет звук (`MediaRecorder`), POST-ит blob → сервер распознаёт → - возвращает `{ text }`, который вставляется в ввод. Никакого состояния задачи нет. -- Клиентская часть: `apps/client/src/features/dictation/` (`hooks/use-dictation.ts`, - `components/mic-button.tsx`, `services/dictation-service.ts`). -- Эндпоинт: `POST /ai-chat/transcribe` - (`apps/server/src/core/ai-chat/ai-chat.controller.ts`) — фича-гейт - `settings.ai.dictation`, throttle, лимит 25 МБ, whitelist mime, вывод реальной - ошибки провайдера (`describeProviderError`), формат контейнера выводится из mime. -- Тонкая обёртка: `apps/server/src/core/ai-chat/ai-transcription.service.ts` → - делегирует в `AiService.transcribe(workspaceId, audio, format)`. -- Выбор кодировки запроса — **явное** поле `sttApiStyle` - (`apps/server/src/integrations/ai/ai.types.ts`, `SttApiStyle`, - `STT_API_STYLES`): - - `multipart` — OpenAI-совместимый `POST /v1/audio/transcriptions` (form-data) - через AI SDK (`createOpenAI(...).transcription()` + `experimental_transcribe`); - - `json` — OpenRouter-стиль: `POST {baseURL}/audio/transcriptions`, - `Content-Type: application/json`, тело `{ model, input_audio: { data:, format } }`, - ответ `{ text }` (`AiService.transcribeJsonBase64`). -- Поле прокладывается как любой не-секрет: `resolve()` / `getMasked()` / - whitelist в `AiSettingsService.update` - (`apps/server/src/integrations/ai/ai-settings.service.ts`) **и** массив - `ALLOWED` в `WorkspaceRepo.updateAiProviderSettings` - (`apps/server/src/database/repos/workspace/workspace.repo.ts`). -- UI: селектор «Request format» на карточке Voice / STT - (`apps/client/.../settings/components/ai-provider-settings.tsx`) + - кнопка «Test endpoint» (бэкенд-проба — тихий WAV через тот же `transcribe`). - -**Важно:** `multipart` уже покрывает почти всю экосистему — её реализуют OpenAI, -Azure OpenAI (Whisper), Groq, Together, Fireworks, DeepInfra, vLLM, LM Studio, -whisper.cpp/llama.cpp server, `speaches`, `faster-whisper-server`, WhisperX. -Для них **новый формат не нужен**, достаточно base URL + модель + ключ. -`json` покрывает OpenRouter. Ось `sttApiStyle` — это абстракция над -*контрактом запроса/ответа*: каждый реально иной контракт = одно значение enum -+ одна ветка-энкодер. - -### Точки расширения для нового СИНХРОННОГО формата (чек-лист) - -1. `ai.types.ts` — добавить значение в `SttApiStyle` и `STT_API_STYLES`. -2. `dto/update-ai-settings.dto.ts` — `@IsIn(STT_API_STYLES)` подхватит автоматически. -3. `ai.service.ts` — ветка в `transcribe()` + приватный энкодер - (по образцу `transcribeJsonBase64`): сборка запроса, заголовок авторизации, - `!res.ok` → бросок со статусом+телом (без утечки ключа), парс ответа в `text`. -4. Клиент: `ai-settings-service.ts` (тип `SttApiStyle`), опция в `