Initial agent-news: Dart Telegram bot + Claude Code runner + MCP bridge

/news spawns claude-code as a local subprocess (single pod, no cross-container
exec on K3s); Claude delivers the digest itself via the send_to_telegram MCP tool.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-21 20:40:32 +03:00
commit be09de2ad7
15 changed files with 764 additions and 0 deletions

65
README.md Normal file
View File

@@ -0,0 +1,65 @@
# agent-news
Telegram-бот на Dart: по команде `/news` (или `/news <тема>`) запускает Claude Code
для ресёрча и присылает выжимку в чат. Учебный проект для platformteam — архитектура
и урок описаны в [aidoc](https://aidoc.platformteam.tech), страница `practices/agent-news-bot`.
## Как это работает
Один под, один контейнер, три процесса:
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.
Подробности и диаграммы — в уроке aidoc.
## Локальная разработка
```bash
cd bot && dart pub get && dart analyze
cd ../mcp_server && dart pub get && dart analyze
```
Сборка образа (контекст — корень репозитория):
```bash
docker build -f runner/Dockerfile -t agent-news:dev .
```
## Переменные окружения
| Переменная | Обязательна | Назначение |
|---|---|---|
| `TELEGRAM_BOT_TOKEN` | да | токен бота, используется и ботом, и MCP-сервером |
| `ALLOWED_CHAT_IDS` | да | список chat_id через запятую — кому отвечает бот |
| `NEWS_PROMPT` | нет | промпт по умолчанию для `/news` без темы |
| `CLAUDE_TIMEOUT_SECONDS` | нет | таймаут на ресёрч (по умолчанию 360) |
| `MCP_CONFIG_PATH` | нет | путь к `mcp.json` (по умолчанию `/home/agent/claude-config/mcp.json`) |
## Первичная авторизация Claude Code
Claude Code CLI использует OAuth-логин через Claude.ai (подписка, не API-ключ). После
первого деплоя нужно один раз пройти логин внутри пода — иначе `claude -p ...` будет
падать с ошибкой авторизации:
```bash
kubectl exec -it -n platformteam deploy/agent-news -- claude
```
CLI напечатает ссылку — открой её в браузере, авторизуйся. Токен сохранится в
`~/.claude` (persist через PVC `agent-news-home`, см. `deploy/agent-news`), так что
после рестарта пода логин не слетит.
## Деплой
Стандартный BearsDev CI/CD (см. `bearsdev-systems/ai-agents/knowledge/cicd.md`):
`git push``.gitea/workflows/build.yaml` собирает и пушит образ → бампит тег в
`deploy/agent-news``.gitea/workflows/deploy.yaml` применяет манифест в K3s.
Перед первым деплоем вручную (см. план и `cicd.md`):
1. Создать `deploy/agent-news` репо с `deployment.yaml` + `.gitea/workflows/deploy.yaml`.
2. `kubectl apply -f pvc.yaml` — PVC `agent-news-home`, один раз, не через CI.
3. `kubectl create secret generic agent-news-secrets -n platformteam --from-literal=TELEGRAM_BOT_TOKEN=... --from-literal=ALLOWED_CHAT_IDS=...`
4. После первого деплоя — авторизация Claude Code (см. выше).