feat(api): HTTP API REST+SSE para gestion remota de agentes (issue 0128)
Nuevo paquete internal/api con servidor HTTP stdlib (sin gin/echo):
- Auth Bearer via AGENTS_API_KEY con subtle.ConstantTimeCompare
- REST: GET /health (sin auth), GET/POST /agents, /agents/{id}, /{id}/{start,stop,restart,logs}
- SSE: /sse/status (broadcast diffs cada 2s) y /sse/agents/{id}/logs (tail -f)
- Pubsub in-memory (TODO: NATS cuando haya 2do cliente)
- Tail de logfiles: retroalimenta ultimos 50KB + poll 200ms para streaming
Integracion en cmd/launcher/main.go:
- Flag --api-port (0=desactivado, 8487 en produccion)
- Flag --api-key (override de AGENTS_API_KEY env var)
- Si apiPort>0 y sin clave, WARN y deshabilita en vez de fallar
Systemd unit en systemd/agents_and_robots.service:
- Restart=always (no on-failure — evita que exit limpio mate el service)
- EnvironmentFile para AGENTS_API_KEY y demas tokens
- WorkingDirectory=/home/ubuntu/CodeProyects/agents_and_robots
app.md v0.2.0:
- port: 8487, health_endpoint: /health (fix drift anterior donde era null)
- e2e_checks: build, tests, smoke_health, smoke_auth
- Documentacion Traefik+DNS pendiente humano post-merge
Tests: 12 tests unitarios en internal/api (auth, health, bus, agents, logs)
Smoke: /health 200, /agents sin auth 401, /agents con key 200 — verificado local
Co-Authored-By: fn-constructor (agent)
This commit is contained in:
@@ -2,8 +2,8 @@
|
||||
name: agents_and_robots
|
||||
lang: go
|
||||
domain: agents
|
||||
version: 0.1.0
|
||||
description: "Plataforma Go de bots autonomos Matrix con arquitectura pure core / impure shell. Launcher, agentctl, dashboard TUI y register."
|
||||
version: 0.2.0
|
||||
description: "Plataforma Go de bots autonomos Matrix con arquitectura pure core / impure shell. Launcher, agentctl, dashboard TUI, register y HTTP API REST+SSE."
|
||||
tags: [agents, matrix, bots, llm, element, e2ee, tools, service]
|
||||
uses_functions: []
|
||||
uses_types: []
|
||||
@@ -12,8 +12,8 @@ entry_point: "cmd/launcher/main.go"
|
||||
dir_path: "projects/element_agents/apps/agents_and_robots"
|
||||
repo_url: "https://gitea-dgg044oo04woo4ggcsws4gk0.organic-machine.com/egutierrez/agents_and_robots.git"
|
||||
service:
|
||||
port: null
|
||||
health_endpoint: null
|
||||
port: 8487
|
||||
health_endpoint: /health
|
||||
health_timeout_s: 5
|
||||
systemd_unit: agents_and_robots.service
|
||||
systemd_scope: system
|
||||
@@ -22,6 +22,21 @@ service:
|
||||
pc_targets:
|
||||
- organic-machine.com
|
||||
is_local_only: false
|
||||
e2e_checks:
|
||||
- id: build
|
||||
cmd: "go build -tags goolm ./..."
|
||||
timeout_s: 120
|
||||
- id: tests
|
||||
cmd: "go test -tags goolm -count=1 ./internal/api/... ./cmd/launcher/..."
|
||||
timeout_s: 60
|
||||
- id: smoke_health
|
||||
cmd: "AGENTS_API_KEY=test-e2e-smoke ./bin/launcher --api-port 18487 &"
|
||||
health: "http://127.0.0.1:18487/health"
|
||||
timeout_s: 10
|
||||
- id: smoke_auth
|
||||
cmd: "curl -s -o /dev/null -w '%{http_code}' http://127.0.0.1:18487/agents"
|
||||
expect_stdout_contains: "401"
|
||||
timeout_s: 5
|
||||
---
|
||||
|
||||
## Deploy
|
||||
@@ -29,15 +44,56 @@ service:
|
||||
- **VPS:** organic-machine.com (SSH alias: organic-machine.com)
|
||||
- **Remote path:** /home/ubuntu/CodeProyects/agents_and_robots
|
||||
- **Build:** `go build -tags goolm -ldflags="-s -w" -o bin/launcher ./cmd/launcher`
|
||||
- **Run:** `./bin/launcher --log-level info`
|
||||
- **Run (manual):** `./bin/launcher --log-level info --api-port 8487`
|
||||
- **Run (systemd):** `systemctl start agents_and_robots.service` (unit en `systemd/agents_and_robots.service`)
|
||||
- **Binarios:** launcher, agentctl, register, dashboard, verify (en bin/)
|
||||
- **Proceso:** launcher corre como proceso directo (no systemd)
|
||||
- **Config:** agents/*/config.yaml + .env con tokens Matrix, API keys LLM, pickle keys E2EE
|
||||
|
||||
## HTTP API (v0.1)
|
||||
|
||||
Puerto: **8487** (local, Traefik termina TLS en `agents.organic-machine.com`).
|
||||
Auth: `Authorization: Bearer $AGENTS_API_KEY` (32 bytes hex en `.env`).
|
||||
|
||||
| Verbo | Path | Descripcion |
|
||||
|---|---|---|
|
||||
| GET | `/health` | Liveness (sin auth) |
|
||||
| GET | `/agents` | Lista todos los agentes con estado |
|
||||
| GET | `/agents/{id}` | Detalle + logs recientes |
|
||||
| POST | `/agents/{id}/start` | Arrancar agente |
|
||||
| POST | `/agents/{id}/stop` | Parar agente |
|
||||
| POST | `/agents/{id}/restart` | Stop + Start |
|
||||
| GET | `/agents/{id}/logs?n=200` | Snapshot de logs |
|
||||
| GET | `/sse/status` | SSE: diffs de estado cada 2s |
|
||||
| GET | `/sse/agents/{id}/logs` | SSE: tail -f del logfile |
|
||||
|
||||
**TODO v0.2:** POST `/agents/{id}/message`, PUT `/agents/{id}/config`, SSE messages stream.
|
||||
**TODO escala:** si se anade un 2do cliente HTTP (otro VPS, otro frontend), reemplazar el pubsub in-memory con NATS o Redis.
|
||||
|
||||
## Systemd
|
||||
|
||||
Unit en `systemd/agents_and_robots.service`. Para instalar en el VPS:
|
||||
|
||||
```bash
|
||||
# En el VPS (ubuntu@organic-machine.com)
|
||||
sudo cp systemd/agents_and_robots.service /etc/systemd/system/
|
||||
sudo systemctl daemon-reload
|
||||
sudo systemctl enable --now agents_and_robots.service
|
||||
```
|
||||
|
||||
Importante: usa `Restart=always` (no `on-failure`) para reiniciar incluso tras exit limpio.
|
||||
|
||||
## Traefik + DNS (post-merge, humano)
|
||||
|
||||
Pasos que el humano completa tras mergear el PR:
|
||||
1. Crear DNS A record `agents.organic-machine.com` apuntando a la IP del VPS.
|
||||
2. En Traefik (standalone o Coolify): ruta `agents.organic-machine.com → 127.0.0.1:8487` con HTTPS+LE.
|
||||
3. Verificar: `curl -fsS https://agents.organic-machine.com/health`.
|
||||
4. Generar API key: `openssl rand -hex 32` y escribir `AGENTS_API_KEY=<key>` en `.env` del VPS.
|
||||
|
||||
## Notas
|
||||
|
||||
4 binarios principales:
|
||||
- **launcher** — Inicia agentes como goroutines, descubre configs, sync Matrix
|
||||
- **launcher** — Inicia agentes como goroutines, descubre configs, sync Matrix, HTTP API
|
||||
- **agentctl** — CLI: list, start, stop, remove agentes
|
||||
- **register** — Registra usuarios bot en Synapse via admin API
|
||||
- **dashboard** — TUI interactiva (bubbletea) para gestion de agentes
|
||||
@@ -56,3 +112,4 @@ Una linea por bump SemVer. Bump-type segun `.claude/commands/version.md`:
|
||||
- `patch`: bugfix sin cambio observable.
|
||||
|
||||
- v0.1.0 (2026-05-18) — baseline.
|
||||
- v0.2.0 (2026-05-22) — HTTP API REST+SSE (internal/api), systemd unit, --api-port flag en launcher.
|
||||
|
||||
Reference in New Issue
Block a user