Files
GoClaw/todo.md
bboxwtf 153399f41e feat(phase-A): agent-worker container — autonomous agent HTTP server
PHASE A COMPLETE: каждый агент теперь может жить в отдельном Docker Swarm контейнере как автономная единица.

- HTTP-сервер агента: GET /health, GET /info, POST /chat, POST /task, GET /tasks, GET /tasks/{id}, GET /memory
- Загружает конфиг из shared DB по AGENT_ID env var (model, systemPrompt, allowedTools)
- 4 горутины-воркера для параллельной обработки задач
- In-memory task queue (buffered channel, depth=100) + ring buffer последних 50 задач
- Callback URL: POST результата при завершении async задачи
- Sliding window памяти: загружает последние 20 сообщений из DB при каждом запросе
- Изолированные инструменты: агент получает только allowedTools из своей конфигурации
- Агент сам вызывает LLM напрямую через LLM_BASE_URL (не через Gateway)
- Graceful shutdown с таймаутом 15s

- 20 unit-тестов: все PASS
- Покрытие: инициализация, task queue, /health, /info, /task, /tasks, /memory, инструменты, lifecycle

- Multi-stage Go build: golang:1.23-alpine → alpine:3.21
- EXPOSE 8001, HEALTHCHECK на /health каждые 15s
- Агенты деплоятся динамически Swarm (не статический сервис в stack)

- Новые поля в таблице agents: serviceName, servicePort, containerImage, containerStatus
- SQL migration: drizzle/migrations/0006_agent_container_fields.sql

- AgentConfig + AgentRow: новые поля serviceName, servicePort, containerImage, containerStatus
- UpdateContainerStatus() — обновление статуса при деплое/остановке
- GetAgentHistory() — sliding window памяти агента из DB
- SaveHistory() — сохранение диалога агента в DB

- delegate_to_agent: реальный HTTP POST к контейнеру агента через overlay DNS
  - sync: POST /chat (ждёт ответ)
  - async: POST /task (возвращает task_id)
  - fallback: если агент не запущен — информативное сообщение
- SetDatabase() — инжекция DB для резолва адресов живых агентов

- Orchestrator инжектирует DB в Executor через SetDatabase() при инициализации
2026-03-31 23:11:02 +00:00

204 lines
14 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# GoClaw — TODO
## Целевая архитектура
```
┌─────────────────────────────────────────────────────────────┐
│ Docker Swarm overlay net │
│ │
│ [Web Panel :3000] [Orchestrator :18789] [Agent-1 :8001] │
│ │ │ │ │
│ └────────────────────┴────────────────────┘ │
│ goclaw-net │
│ │
│ Каждый агент = отдельный Docker Swarm service: │
│ • своя LLM модель + systemPrompt из DB │
│ • своя память (conversation history в shared DB) │
│ • HTTP API: POST /task, POST /chat, GET /health, GET /mem │
│ • принимает параллельные задачи от любых источников │
│ • автодеплой при создании агента через Web Panel │
│ │
│ Orchestrator = мозг экосистемы: │
│ • маршрутизирует задачи между агентами │
│ • tool: delegate_to_agent → HTTP к agent-N:8001/task │
│ • знает topology: какой агент где живёт │
│ │
│ Web Panel = панель управления и мониторинга: │
│ • создать/удалить агента → автодеплой контейнера │
│ • видеть статус контейнеров в реальном времени │
│ • логи, метрики, история задач │
└─────────────────────────────────────────────────────────────┘
```
---
## ✅ ЗАВЕРШЕНО (фундамент)
- [x] Basic Dashboard layout (Mission Control theme)
- [x] Docker Stack integration (docker-stack.yml, docker-compose.yml)
- [x] Go Gateway — отдельный контейнер-оркестратор (:18789)
- [x] Web Panel — отдельный контейнер (:3000)
- [x] Overlay network `goclaw-net` (attachable)
- [x] MySQL shared DB (агенты, метрики, история)
- [x] tRPC API: agents CRUD, metrics, history
- [x] Go Gateway: LLM client (OpenAI-compatible), tool executor
- [x] Go Gateway: tool loop (shell_exec, file_read/write, http_request, docker_exec)
- [x] Go Gateway: DockerClient.CreateAgentServiceFull() — готов к деплою агентов
- [x] Nodes page: реальные данные из Docker API (Swarm nodes, containers)
- [x] Seed: 6 системных агентов в DB при старте
- [x] SSE streaming chat (Phase 18, remote branch)
- [x] Persistent chat sessions в DB (Phase 20, remote branch)
- [x] Workflows: визуальный конструктор граф-воркфлоу (remote branch)
- [x] Real Docker Swarm management: live nodes/services/tasks (Phase 21, remote branch)
---
## 🔥 PHASE A: Agent Worker Container (КРИТИЧЕСКИЙ ПУТЬ)
> Цель: каждый агент живёт в своём контейнере с HTTP API.
> Orchestrator обращается к нему по имени в overlay сети.
### A1: agent-worker binary (Go)
- [x] Создать `gateway/cmd/agent-worker/main.go` — HTTP-сервер агента
- [x] Загружает конфиг из DB по `AGENT_ID` env var (model, systemPrompt, allowedTools)
- [x] `GET /health` — liveness/readiness probe
- [x] `GET /info` — конфиг агента (name, model, allowedTools)
- [x] `POST /task` — принять задачу от Orchestrator/другого агента (async, возвращает task_id)
- [x] `POST /chat` — синхронный чат (LLM loop с инструментами агента)
- [x] `GET /memory` — последние N сообщений из conversation history (sliding window)
- [x] Агент сам вызывает LLM через `LLM_BASE_URL` (не через Gateway)
- [x] 4 горутины-воркера на агента — параллельная обработка задач
- [x] Переиспользует `internal/llm`, `internal/db`, `internal/tools`
### A2: Task Queue внутри агента
- [x] In-memory очередь задач (buffered channel, depth=100)
- [x] 4 worker goroutines: берут задачи из очереди, выполняют LLM loop
- [x] `GET /tasks` + `GET /tasks/{id}` — список задач и статус конкретной
- [x] Callback URL: агент POST результат на `callback_url` когда задача готова
- [x] Timeout per task (из запроса, default 120s)
- [x] Recent ring buffer (последние 50 задач)
### A3: DB schema — agent container fields
- [x] Добавить в `drizzle/schema.ts`: `serviceName`, `servicePort`, `containerImage`, `containerStatus`
- [x] SQL migration `drizzle/migrations/0006_agent_container_fields.sql`
- [x] `gateway/internal/db/db.go`: `AgentConfig` + `AgentRow` с новыми полями
- [x] `UpdateContainerStatus()` — обновление статуса при деплое/остановке
- [x] `GetAgentHistory()` + `SaveHistory()` — память агента в DB
### A4: Auto-deploy при создании агента
- [ ] Gateway: `POST /api/agents` — создаёт агента в DB + деплоит Swarm service
- [ ] `CreateAgentServiceFull()` с параметрами:
- image: `goclaw-agent-worker:latest`
- name: `goclaw-agent-{agentId}`
- env: `AGENT_ID`, `DATABASE_URL`, `LLM_BASE_URL`, `LLM_API_KEY`
- network: `goclaw-net`
- port: назначить из пула (8001+)
- [ ] Записать `serviceName`, `servicePort`, `containerStatus=running` в DB
- [ ] Gateway: `DELETE /api/agents/{id}` — удалить Swarm service + запись в DB
- [ ] Gateway: `POST /api/agents/{id}/scale` — масштабировать реплики агента
### A5: delegate_to_agent tool (Orchestrator → Agent HTTP)
- [x] Обновить `gateway/internal/tools/executor.go`:
- tool `delegate_to_agent`: args: `{agentId, task, callbackUrl?, async?}`
- Получить `serviceName`+`servicePort` агента из DB
- HTTP POST к `http://goclaw-agent-{id}:{port}/chat` (sync) или `/task` (async)
- Fallback: если агент не запущен — информативное сообщение
- [x] `Executor.SetDatabase()` — инжекция DB для резолва адресов агентов
- [x] Orchestrator инжектирует DB в Executor при инициализации
### A6: Dockerfile.agent-worker
- [x] Создать `docker/Dockerfile.agent-worker` (multi-stage Go build)
- [x] Stage 1: `golang:1.23-alpine` — build agent-worker binary
- [x] Stage 2: `alpine:3.21` — минимальный runtime (ca-certificates, tzdata)
- [x] EXPOSE 8001 + HEALTHCHECK на /health
- [x] Агенты деплоятся динамически (не статический сервис в stack)
### A7: Тесты и верификация
- [x] `go build ./cmd/agent-worker/...` — компилируется (11MB binary)
- [x] `go build ./cmd/gateway/...` — не сломан (11MB binary)
- [x] `go build ./...` — все пакеты компилируются
- [x] 20 unit-тестов: /health, /task, /tasks, /memory, task queue, tools, lifecycle — все PASS
- [ ] Docker build: `docker build -f docker/Dockerfile.agent-worker -t goclaw-agent-worker .` (нужен Docker daemon)
- [ ] Интеграционный тест: Gateway `delegate_to_agent` → agent-worker `/task` (нужна живая DB)
---
## 🟡 PHASE B: Web Panel — управление живыми агентами
> Цель: Web Panel показывает реальный статус контейнеров и позволяет деплоить/останавливать.
- [ ] `/agents` страница: колонка `Container Status` (running/stopped/deploying/error)
- [ ] `/agents` страница: кнопка `Deploy` — вызывает `POST /api/agents/{id}/deploy`
- [ ] `/agents` страница: кнопка `Stop` / `Scale` для запущенных агентов
- [ ] `/agents` страница: live polling статуса контейнера (10s)
- [ ] tRPC: `agents.deploy`, `agents.stop`, `agents.scale` → Gateway REST
- [ ] Dashboard: topology карта — агенты как узлы, стрелки = делегирование задач
- [ ] `/agents/{id}` detail: вкладка `Tasks` — активные задачи агента в реальном времени
- [ ] `/agents/{id}` detail: вкладка `Memory` — последние N сообщений агента
---
## 🟡 PHASE C: Межагентная коммуникация
> Цель: агенты могут обращаться друг к другу параллельно, с разных мест.
- [ ] Стандарт сообщения agent-to-agent:
```json
{ "task_id": "uuid", "from_agent_id": 1, "task": "...", "callback_url": "http://...", "priority": "normal", "timeout_secs": 120 }
```
- [ ] Service Discovery: агент получает список других агентов из DB (GET /api/agents)
- [ ] Orchestrator: параллельный fanout — отправить задачу нескольким агентам одновременно
- [ ] Rate limiting: агент принимает не более N параллельных задач (configurable)
- [ ] Dead letter: если агент недоступен — Orchestrator автоматически рестартует сервис
---
## 🟡 PHASE D: Память агента
> Цель: каждый агент имеет изолированную персистентную память.
- [ ] Sliding window: агент загружает последние 20 сообщений своей истории при каждом запросе
- [ ] История привязана к `agentId` (уже есть `agentHistory` в DB)
- [ ] `GET /memory?limit=20` — endpoint агента отдаёт свою историю
- [ ] Опционально: summary compression — если история > N токенов, сжать через LLM
---
## 🟢 PHASE E: Специализированные образы агентов
> Цель: разные типы агентов с разными возможностями.
- [ ] `goclaw-agent-browser` — образ с Chromium + Puppeteer (или playwright-go)
- [ ] `goclaw-agent-coder` — образ с git, node, python, go
- [ ] `goclaw-agent-researcher` — образ с curl + базовый HTTP scraping
- [ ] Agent Compiler: из ТЗ → config в DB → auto-deploy нужного образа
- [ ] Tool Builder: динамическая регистрация инструментов через API агента
---
## 🟢 PHASE F: Observability & Production
- [ ] Centralized logging: агенты пишут структурированные логи в shared volume / Loki
- [ ] Metrics endpoint: `GET /metrics` (Prometheus-compatible) на каждом агенте
- [ ] Alert: Orchestrator получает webhook при падении агента (Docker healthcheck)
- [ ] Traefik reverse proxy: раскомментировать в docker-stack.yml + TLS
- [ ] Auth: JWT для межагентного API (если выйдет за периметр Swarm сети)
- [ ] Go unit tests: `gateway/internal/tools/executor_test.go`
- [ ] Go integration test: Orchestrator chat loop end-to-end
---
## 🚫 ОТБРОШЕНО (не соответствует архитектуре)
> Эти задачи противоречат концепции "агент = контейнер" или дублируют существующее.
- ~~Browser Agent как Puppeteer в Node.js~~ → заменяется специализированным образом `goclaw-agent-browser`
- ~~server/browser-agent.ts~~ → логика переезжает в отдельный Go binary
- ~~server/tool-builder.ts / server/agent-compiler.ts~~ → реализуются как агент-контейнеры (Phase E)
- ~~BrowserAgent.tsx / ToolBuilder.tsx / AgentCompiler.tsx как отдельные страницы~~ → управляются через стандартный `/agents` с типом
- ~~/skills страница~~ → заменяется `allowedTools` per-agent-container
- ~~server/web-research.ts~~ → реализуется как задача для агента-researcher через `delegate_to_agent`
- ~~server/chat-resilience.ts (Node.js retry)~~ → retry логика в Go agent-worker
- ~~Web Research Panel~~ → задача через Orchestrator chat
- ~~Phase 19 commit to Gitea (NW)~~ → история перезаписана целевой архитектурой