Files

66 lines
8.9 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Алиса для Станции Мини 2
Собственный голосовой клиент для рутированной Mini 2, сервер на Node.js и пульт в Telegram. На колонке работает русская модель ключевого слова «Алиса». Когда клиент готов принимать команду, верхнее кольцо загорается сине-фиолетовым. Произнеси команду после включения кольца.
```text
Mini 2 → VQE → WSS с PCM16 / 16 кГц → Scribe v3 Live
← WSS с PCM16 / 24 кГц ← Eleven v4 Turbo ← OpenRouter / Haiku 5.5
```
Модель Scribe можно переключить в пульте, включая Scribe v2 Realtime. Scribe выдаёт промежуточный текст, а запрос к LLM начинается после подтверждения конца команды. После инструментов сервер озвучивает один короткий ответ. Звуковые фрагменты сразу уходят на колонку. Запрос и ответ в текстовом виде сохраняются после успешного хода. Сервер держит 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. Музыка и ответы идут через разные входы микшера. Во время запроса музыкальный вход затихает, а после запроса его громкость восстанавливается. Станция буферизует начало команды, пока устанавливает соединение.
[Калибровка Room EQ](room-eq/README.md) измеряет акустику возле Mini 2 или в зоне прослушивания и позволяет сравнить коррекцию с исходным звучанием Spotify.
Для поиска по названию создай 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` для трека, исполнителя, альбома или плейлиста. Поддерживаются пауза, продолжение, следующий и предыдущий трек и установка громкости. Короткие команды «пауза», «выключи музыку» и «громкость 50» выполняются без озвучивания подтверждения. Для актуальных сведений и проверки неизвестных фактов Клод может вызвать [серверный веб-поиск 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/)
### Разговор и Spotify
В «Пульте Алисы» можно включить сигнал активации и настроить окно продолжения разговора. По умолчанию сигнал отключён, а окно открывается на три секунды после голосового ответа. «Стоп» и «хватит» распознаются на колонке и прекращают текущий ответ. Spotify продолжает воспроизведение с обычным уровнем.
Штатный локальный детектор также принимает «громче», «тише», «пауза», «продолжи», «дальше» и «назад». Голосовой ассистент может показать состояние Spotify Connect, назвать текущий трек, перемотать, включить повтор или перемешивание, посмотреть и дополнить очередь. Для изменения плейлистов нужно повторно авторизовать Spotify в Mini App. Пульт показывает состояние колонки и последний известный трек. Источник состояния воспроизведения — Spotify Connect.
Тап по центру переключает воспроизведение Spotify или останавливает активный ответ. Удержание центра три секунды открывает прослушивание. Тап «−» или «+» меняет громкость на 10 процентных пунктов, удержание повторяет шаг. Свайп через три зоны от «−» к «+» включает следующий трек. Свайп обратно возвращает к началу текущего трека после пяти секунд воспроизведения и включает предыдущий в первые пять секунд.
Eleven v4 Turbo и Eleven v3 Conversational могут получать один тег интонации в начале ответа. Модель выбирает подачу при генерации текста ответа. Повседневные фразы и короткие команды остаются нейтральными. В истории сохраняется чистый текст.