# SHiNE-agent-bot-coder Локальный Telegram-бот-сервис для пользователя `ai`: - принимает сообщения от `@AidarKC`; - поддерживает whitelist игроков (`ALLOWED_TELEGRAM_PLAYERS`) с отдельными историями; - ведёт историю диалога в `JSONL`; - ставит задачи в файловую очередь; - обрабатывает задачи строго последовательно; - поддерживает текстовые и голосовые сообщения (voice/audio через OpenAI transcription); - вызывает Codex CLI и отправляет ответ в Telegram; - в личном чате умеет работать в двух персонально переключаемых режимах: через одно редактируемое статусное сообщение или через отдельные сообщения по этапам; - умеет персонально для каждого пользователя озвучивать финальный ответ через OpenAI TTS; - при рестарте восстанавливает незавершённые задачи; - отправляет аварийный статус только если Codex молчит 2 минуты подряд во время активной задачи; - принимает сообщения из канала/группы `@shine_writing`, выполняет команды только от `@AidarKC`; - учитывает миграцию обычной Telegram-группы в supergroup и перенаправляет ответы на новый `chat_id`. Рабочая реализация сервиса — только `py_bot_service.py`. Старая Java-реализация удалена, потому что не заработала и больше не используется. ## Структура - `.env` — локальные секреты и параметры запуска (не коммитится); - `data/py_queue.jsonl` — очередь Python-сервиса; - `data/py_state.json` — текущее состояние Python-сервиса; - `data/py_processed_updates.log` — дедуп входящих update; - `data/history//*.jsonl` — активные истории по пользователям; - `data/history//archive/*.jsonl` — архивы после `/new`. ## Локальный запуск 1. Скопировать пример: - `cp .env.example .env` 2. Заполнить секреты в `.env`. - `TELEGRAM_BOT_TOKEN` — токен рабочего Telegram-бота. - `ALLOWED_TELEGRAM_USERNAME` — пользователь, чьи сообщения выполняются как команды. - `ALLOWED_TELEGRAM_PLAYERS` — whitelist игроков в формате `username:Имя,username2:Имя2`. - `ALLOWED_TELEGRAM_CHANNEL_USERNAME` — канал, из которого принимаются `channel_post`; обычные group/supergroup-сообщения обрабатываются как `message`. - `TELEGRAM_API_BASE_URL` — базовый URL Bot API; по умолчанию `https://api.telegram.org`. Для очень больших voice/audio можно поднять локальный `telegram-bot-api` и направить бота туда. - `TELEGRAM_FILE_DOWNLOAD_TIMEOUT_SECONDS` — тайм-аут скачивания voice/audio из Telegram, по умолчанию 300 секунд. - `OPENAI_TRANSCRIBE_TIMEOUT_SECONDS` — тайм-аут распознавания voice/audio в OpenAI, по умолчанию 900 секунд. - `OPENAI_TRANSCRIBE_MAX_UPLOAD_BYTES` — безопасный лимит размера одного куска для OpenAI transcription, по умолчанию `24 MiB`. - `OPENAI_TRANSCRIBE_MAX_CHUNK_SECONDS` — максимальная длина одного куска при длинном аудио, по умолчанию `900` секунд. - `OPENAI_TRANSCRIBE_OVERLAP_SECONDS` — перекрытие соседних кусков для более ровной склейки текста, по умолчанию `2` секунды. - `OPENAI_TRANSCRIBE_REENCODE_BITRATE_KBPS` — битрейт локального пережатия длинного аудио через `ffmpeg`, по умолчанию `24`. - `OPENAI_TRANSCRIBE_FFMPEG_TIMEOUT_SECONDS` — тайм-аут локальной обработки длинного аудио через `ffmpeg`/`ffprobe`, по умолчанию `1800`. - `FFMPEG_BIN` и `FFPROBE_BIN` — пути к локальным бинарям `ffmpeg`/`ffprobe`, если они не лежат в `PATH`. - `OPENAI_TTS_MODEL` — модель синтеза речи, по умолчанию `gpt-4o-mini-tts`. - `OPENAI_TTS_VOICE` — голос синтеза речи, по умолчанию `alloy`. - `OPENAI_TTS_RESPONSE_FORMAT` — аудиоформат для Telegram voice, по умолчанию `opus`. - `OPENAI_TTS_TIMEOUT_SECONDS` — тайм-аут генерации одного фрагмента речи, по умолчанию 180 секунд. - `OPENAI_TTS_CHUNK_CHARS` — максимальный размер одного фрагмента озвучки, по умолчанию 3500 символов. 3. Запуск: - `python3 SHiNE-agent-bot-coder/py_bot_service.py` ## Быстрый self-test Codex (без Telegram) ```bash python3 SHiNE-agent-bot-coder/py_bot_service.py --selftest-codex "Ответь одной строкой: Codex работает" ``` ## Длинные voice/audio - Если аудио короткое, бот отправляет его в OpenAI как раньше. - Если аудио большое или длинное, бот локально пережимает его через `ffmpeg`, при необходимости режет на куски и распознаёт последовательно. - Если Telegram заранее сообщает большой размер файла, бот больше не отказывается сразу: сначала явно пишет, что пробует скачать файл, затем отдельно сообщает, удалось ли скачивание, и только после успешной загрузки переходит к подготовке аудио и OpenAI. - Для очень больших файлов упираемся не только в OpenAI, но и в лимит обычного облачного Telegram Bot API на скачивание файла ботом. Для таких случаев нужно использовать локальный `telegram-bot-api` сервер и указать его через `TELEGRAM_API_BASE_URL`. ## Статусы в личке - Для `private`-чата бот поддерживает персональную настройку режима ответа. - По умолчанию он старается не засорять переписку промежуточными сообщениями: создаёт одно статусное сообщение и редактирует его по этапам. - Если включить `/single_message_off`, бот возвращается к старому режиму и отправляет отдельные сообщения по этапам и финальный ответ отдельно. - Если финальный текст в режиме одного сообщения не помещается целиком, бот оставляет первую часть в отредактированном статусном сообщении и отправляет максимум ещё одно дополнительное текстовое сообщение с хвостом ответа. - Голосовой ответ, если он включён, всегда приходит отдельным новым сообщением. ## Запуск как systemd-сервис Файлы для установки: - `scripts/systemd/shine-agent-bot-coder.service` - `scripts/systemd/install-local-systemd.sh` Установка: - `bash SHiNE-agent-bot-coder/scripts/systemd/install-local-systemd.sh` Проверка: - `systemctl --user status shine-agent-bot-coder --no-pager` - `journalctl --user -u shine-agent-bot-coder -f` Перезапуск после изменений: - `systemctl --user restart shine-agent-bot-coder` ## Telegram-команды - `/status` — активная задача и размер очереди. - `/settings` — текущие пользовательские настройки и команды для их изменения. - `/queue` — список задач в очереди. - `/stop` — остановить текущую задачу. - `/cancel ` — удалить задачу по id/префиксу или очистить очередь. - `/new` — архивировать текущую историю и начать новый диалог. - `/voice_on` — включить озвучивание финальных ответов для текущего пользователя. - `/voice_off` — выключить озвучивание финальных ответов для текущего пользователя. - `/voice_rewrite_on` — включить адаптацию текста перед озвучкой. - `/voice_rewrite_off` — выключить адаптацию текста перед озвучкой. - `/single_message_on` — вести ответ в личке через одно редактируемое сообщение. - `/single_message_off` — слать отдельные сообщения по этапам и отдельный финальный ответ. - `/restart` или `/restart_service` — отложенный рестарт после текущей задачи, до взятия следующей (только для Айдара). - `/restart_hard` — жёсткий рестарт прямо сейчас (только для Айдара).