Files
agent-news/README.md
matt2dev 7bfe0dfe0c Fix HOME volume mount, genericize topic, add progress statuses, extract lexicon
- Volume was mounted at ~/.claude only, but claude-code writes auth to
  ~/.claude.json too — that file lived on the ephemeral container layer and
  was lost on every recreate. Now the whole $HOME is on the named volume,
  and claude-config moved outside HOME (/app) so it isn't shadowed by it.
- Default /news topic was hardcoded to AI; now it's a configurable
  DEFAULT_TOPIC (plain "главные новости дня"), topic is fully free-form.
- Prompt now instructs Claude to send interim " ..." progress updates via
  send_to_telegram while researching, not just the final digest — a bare
  request like "call this tool" was already taking 3+ minutes end-to-end,
  so silence read as broken.
- All user-facing/prompt text moved into bot/lib/lexicon.dart.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-21 21:53:38 +03:00

3.8 KiB
Raw Blame History

agent-news

Telegram-бот на Dart: по команде /news (или /news <тема>) запускает Claude Code для ресёрча и присылает выжимку в чат. Тестовый/учебный проект — пока гоняем локально в Docker, без деплоя в кластер.

Как это работает

Один контейнер, три процесса:

  1. agent-news-bot (Dart, long polling) — слушает /news <тема>, спавнит claude как сабпроцесс.
  2. claude (Claude Code CLI) — делает ресёрч; по ходу и в конце сам вызывает MCP-тул send_to_telegram (промежуточные статусы + финальная выжимка).
  3. agent-news-mcp (Dart, stdio MCP-сервер) — спавнится самим claude, шлёт готовый текст в Telegram Bot API.

Все тексты, которые бот показывает пользователю или подставляет в промпт Claude, лежат в одном месте — bot/lib/lexicon.dart.

Запуск локально

cp .env.example .env
# заполнить TELEGRAM_BOT_TOKEN и ALLOWED_CHAT_IDS (через запятую)

docker compose up -d --build

~/.claude (авторизация Claude Code) хранится в именованном volume claude-home — переживает пересборку и рестарт контейнера.

Первичная авторизация Claude Code

Claude Code CLI использует OAuth-логин через Claude.ai (подписка, не API-ключ). Один раз после первого запуска нужно зайти в контейнер и залогиниться:

docker compose exec agent-news claude auth login

CLI напечатает ссылку — открой её в браузере, авторизуйся, вставь код обратно в терминал, если попросит. Учти: и ~/.claude/, и ~/.claude.jsonоба нужны для логина, поэтому в volume смонтирован весь /home/agent (см. docker-compose.yml), не только ~/.claude/. После docker compose restart логин не слетит.

Проверка

Напиши боту /news <тема> (или просто /news — возьмёт DEFAULT_TOPIC) из чата с id из ALLOWED_CHAT_IDS. Бот сразу ответит "начинаю…", дальше Claude сам присылает статусы по ходу ресёрча и в конце — готовую выжимку, всё через send_to_telegram. Ресёрч занимает несколько минут — это нормально, статусы как раз для этого.

docker compose logs -f agent-news

Локальная разработка (без Docker)

cd bot && dart pub get && dart analyze
cd ../mcp_server && dart pub get && dart analyze

Переменные окружения

Переменная Обязательна Назначение
TELEGRAM_BOT_TOKEN да токен бота, используется и ботом, и MCP-сервером
ALLOWED_CHAT_IDS да список chat_id через запятую — кому отвечает бот
DEFAULT_TOPIC нет тема для /news без аргумента (по умолчанию — «главные новости дня»)
CLAUDE_TIMEOUT_SECONDS нет таймаут на ресёрч (по умолчанию 600)
MCP_CONFIG_PATH нет путь к mcp.json (по умолчанию /app/claude-config/mcp.json)