53 lines
5.8 KiB
Markdown
53 lines
5.8 KiB
Markdown
# Алиса для Станции Мини 2
|
||
|
||
Собственный голосовой клиент для рутированной Mini 2, сервер на Node.js и пульт в Telegram. На колонке работает экспериментальный детектор, обученный локально на нескольких произнесениях «Алиса». Когда клиент готов принимать команду, верхнее кольцо загорается сине-фиолетовым. Произнеси команду после включения кольца.
|
||
|
||
```text
|
||
Mini 2 → WSS с PCM16 / 16 кГц → Scribe v2 Realtime
|
||
← WSS с PCM16 / 24 кГц ← Eleven v4 Turbo ← OpenRouter / Haiku 5.5
|
||
```
|
||
|
||
Scribe выдаёт промежуточный текст, а запрос к LLM начинается после подтверждения конца команды. Текстовые фрагменты из OpenRouter сразу идут в ElevenLabs, звуковые фрагменты сразу уходят на колонку. Запрос и ответ в текстовом виде сохраняются после успешного хода. Сервер держит 50 последних ходов и использует до 10 из них как контекст. Аудио сервер не пишет на диск. Облачные провайдеры обрабатывают отправленные им аудио и текст.
|
||
|
||
## Запуск и проверка
|
||
|
||
```sh
|
||
npm ci
|
||
npm test
|
||
cp .env.example .env
|
||
# Заполнить .env локально
|
||
node --env-file=.env server/index.mjs
|
||
```
|
||
|
||
Клиент, сборка и пробный запуск описаны в [station/README.md](station/README.md). На колонку передаётся отдельный `DEVICE_TOKEN`, ключи провайдеров остаются на сервере. Для интеграционного теста с реальными STT/TTS и без OpenRouter можно отдельно запустить сервер с `LLM_MODE=echo`.
|
||
|
||
## Развёртывание
|
||
|
||
На VPS код находится в `~/projects/alice-backend`. В корне проекта нужны `.env` с правами `0600` и каталог `data/` для настроек и истории, доступный на запись UID 1000. Пример конфигурации для уже существующей Docker-сети `web` и Caddy лежит в [deploy/](deploy/).
|
||
|
||
```sh
|
||
docker compose -f deploy/compose.yaml up -d --build
|
||
```
|
||
|
||
Caddy проксирует голосовое соединение и `/healthz` на `alice.pepega.systems`, а пульт и API на `miniapp.pepega.systems`. История и редактирование настроек требуют Telegram `initData` с проверенной подписью и ID владельца из `TELEGRAM_OWNER_ID`. В пульте можно выбрать модель OpenRouter, голос и модель синтеза, изменить системный промпт, подключить Spotify и очистить историю. В текущем API распознавания в реальном времени доступна одна модель.
|
||
|
||
## Протокол колонки
|
||
|
||
`GET /v1/voice` с WebSocket Upgrade и `Authorization: Bearer <DEVICE_TOKEN>`. Один ход на соединение.
|
||
|
||
1. Сервер посылает `{"type":"ready"}`.
|
||
2. Клиент посылает `{"type":"start"}`, затем бинарные блоки mono PCM16LE 16 кГц и `{"type":"end"}`.
|
||
3. Сервер присылает JSON `partial` и `transcript` с полем `text`, затем бинарные блоки mono PCM16LE 24 кГц.
|
||
4. Для команды Spotify сервер присылает `device_tool` с полями `id`, `name` и `arguments`. Клиент возвращает `device_tool_result` с тем же `id` и полем `result`.
|
||
5. Сервер присылает `{"type":"done"}` или `{"type":"error","code":"…"}` и закрывает соединение.
|
||
|
||
## Spotify и поиск в интернете
|
||
|
||
Музыку на колонке воспроизводит официальный Spotify Soloist. На Mini 2 он запускается с отдельным ARM64 runtime и PulseAudio. Музыка и ответы идут через разные входы микшера. Кольцо включается после приглушения музыки, а после ответа громкость музыкального входа восстанавливается.
|
||
|
||
Для поиска по названию создай Spotify Web API приложение с Redirect URI `https://miniapp.pepega.systems/api/spotify/callback`, задай его Client ID в `SPOTIFY_CLIENT_ID` на сервере и подключи аккаунт в пульте. Soloist отдельно требует свой ключ и первый выбор устройства «Pepega Mini 2» в приложении Spotify. Сессия Connect сохраняется на колонке.
|
||
|
||
Клод вызывает `spotify_play` для трека, исполнителя, альбома или плейлиста. Поддерживаются пауза, продолжение, следующий и предыдущий трек и установка громкости. Для актуальных сведений и проверки неизвестных фактов Клод может вызвать [серверный веб-поиск OpenRouter](https://openrouter.ai/docs/guides/features/server-tools/web-search).
|
||
|
||
[Spotify Soloist](https://developer.spotify.com/documentation/soloist) · [Рецепт librespot для сравнения](https://hackalice.me/recipes/spotify/)
|