feat: send_file — агент отдаёт файлы человеку в телеграм #1

Manually merged
hh merged 0 commits from dev/send-file into main 2026-09-08 15:49:35 +02:00
Owner

Одна тулза send_file(path, caption, method) — агент отдаёт файл человеку в тот же чат и топик, откуда идёт разговор (из джоба/deep — в мастер).

Что внутри

  • frontends/files.py — примитив без телеграма: SendFiles(roots, max_bytes), resolve() разворачивает ~, .. и симлинки до проверки корней; method_for() по расширению, потом по mime (картинка → photo, gif → animation, mp3/flac/m4a/wav → audio, ogg/opus → voice, mp4/mov → video, остальное → document); SendFileError — текст, который читает модель.
  • Frontend.sends_files / send_file / file_note в ABC (по умолчанию отказ); TelegramFrontend их реализует: FSInputFile в send_<method>, подпись через существующий to_html (длиннее 1024 или video_note — уезжает следующим сообщением обычным outbox-путём), для audio title из имени файла.
  • Conversations.send_file выбирает окно: сам разговор, иначе открытый мастер.
  • Корни: SEND_FILE_ROOTS (через :, дефолт /mnt/hole/shared) → GatewayRuntime.send_file_roots, плюс папка входящих вложений, которую фронтенд дописывает сам.
  • Потолок — SendFiles.max_bytes (50 МБ Bot API), не константа: TelegramFrontend(api_base_url=…) поднимает сессию на локальный telegram-bot-api (is_local=True), там ставится свой max_bytes до 2 ГБ.
  • Ошибки (нет файла, вне корней, размер, отказ телеграма, сеть/таймаут) приходят агенту текстом как is_error.

Тесты — 7 новых в test_telegram.py: выход из корня через .., через симлинк и абсолютным путём; лимит («2 MB, over the 1 MB limit»); выбор method; файл в топик ветки с HTML-подписью; длинная подпись следом сообщением; из джоба — в General; отказ телеграма агенту.

Чтобы заработало у хозяина

  1. Дописать send_file в gateway_tools агента в beaver-agent/config.py.
  2. Bind-mount /mnt/hole/shared в контейнер gateway (infra/komodo/dell.toml) — иначе корень пустой, resolve честно откажет.
  3. Рестарт сервиса после деплоя: bind-mount кода живой процесс не перезапускает, в post_deploy рестарта нет.

Не мержить и не деплоить — это руками.

Одна тулза `send_file(path, caption, method)` — агент отдаёт файл человеку в тот же чат и топик, откуда идёт разговор (из джоба/deep — в мастер). **Что внутри** - `frontends/files.py` — примитив без телеграма: `SendFiles(roots, max_bytes)`, `resolve()` разворачивает `~`, `..` и симлинки **до** проверки корней; `method_for()` по расширению, потом по mime (картинка → photo, gif → animation, mp3/flac/m4a/wav → audio, ogg/opus → voice, mp4/mov → video, остальное → document); `SendFileError` — текст, который читает модель. - `Frontend.sends_files` / `send_file` / `file_note` в ABC (по умолчанию отказ); `TelegramFrontend` их реализует: `FSInputFile` в `send_<method>`, подпись через существующий `to_html` (длиннее 1024 или `video_note` — уезжает следующим сообщением обычным outbox-путём), для `audio` `title` из имени файла. - `Conversations.send_file` выбирает окно: сам разговор, иначе открытый мастер. - Корни: `SEND_FILE_ROOTS` (через `:`, дефолт `/mnt/hole/shared`) → `GatewayRuntime.send_file_roots`, плюс папка входящих вложений, которую фронтенд дописывает сам. - Потолок — `SendFiles.max_bytes` (50 МБ Bot API), не константа: `TelegramFrontend(api_base_url=…)` поднимает сессию на локальный telegram-bot-api (`is_local=True`), там ставится свой `max_bytes` до 2 ГБ. - Ошибки (нет файла, вне корней, размер, отказ телеграма, сеть/таймаут) приходят агенту текстом как `is_error`. **Тесты** — 7 новых в `test_telegram.py`: выход из корня через `..`, через симлинк и абсолютным путём; лимит («2 MB, over the 1 MB limit»); выбор method; файл в топик ветки с HTML-подписью; длинная подпись следом сообщением; из джоба — в General; отказ телеграма агенту. **Чтобы заработало у хозяина** 1. Дописать `send_file` в `gateway_tools` агента в `beaver-agent/config.py`. 2. Bind-mount `/mnt/hole/shared` в контейнер gateway (`infra/komodo/dell.toml`) — иначе корень пустой, `resolve` честно откажет. 3. Рестарт сервиса после деплоя: bind-mount кода живой процесс не перезапускает, в `post_deploy` рестарта нет. Не мержить и не деплоить — это руками.
hh added 1 commit 2026-09-08 14:05:19 +02:00
hh manually merged commit 5c3218eeed into main 2026-09-08 15:49:35 +02:00
Sign in to join this conversation.
No Reviewers
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: beaver/beaver-gateway#1