- 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>
73 lines
3.8 KiB
Markdown
73 lines
3.8 KiB
Markdown
# 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`.
|
||
|
||
## Запуск локально
|
||
|
||
```bash
|
||
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-ключ). Один раз
|
||
после первого запуска нужно зайти в контейнер и залогиниться:
|
||
|
||
```bash
|
||
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`. Ресёрч
|
||
занимает несколько минут — это нормально, статусы как раз для этого.
|
||
|
||
```bash
|
||
docker compose logs -f agent-news
|
||
```
|
||
|
||
## Локальная разработка (без Docker)
|
||
|
||
```bash
|
||
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`) |
|