feat(0128): HTTP API REST+SSE para agents_and_robots #1

Open
dataforge wants to merge 0 commits from auto/0128-http-api-sse into master
Owner

feat(0128): HTTP API REST+SSE para gestion remota de agentes

task_run_id: task_b19cccf68791cc34
branch: auto/0128-http-api-sse
issue: 0128

Que incluye este PR

Nuevo paquete internal/api:

  • server.go — HTTP server stdlib, auth Bearer subtle.ConstantTimeCompare
  • handlers.go — REST endpoints: /health, /agents, /agents/{id}, /{id}/{start,stop,restart,logs}
  • pubsub.go — Bus in-memory para SSE broadcast (TODO NATS si llega 2do cliente)
  • poller.go — goroutine StatusAll cada 2s, publica StatusDiff al bus
  • tail.go — tail -f logfiles con poll 200ms para SSE streaming
  • server_test.go — 12 tests unitarios

cmd/launcher/main.go:

  • Flags --api-port y --api-key
  • Arranca api.Server como goroutine si apiPort > 0 y hay clave

systemd/agents_and_robots.service:

  • Restart=always (no on-failure)
  • EnvironmentFile apunta a .env del proyecto

app.md v0.2.0:

  • port: 8487, health_endpoint: /health (fix drift)
  • e2e_checks: build, tests, smoke_health, smoke_auth

Checks verificados

  • build PASS
  • 12/12 tests PASS
  • /health 200, /agents sin auth 401, /agents con key 200
  • SSE compilado y funcional
  • Restart=always en systemd unit

Pendiente humano (fuera de scope)

  • DNS A record agents.organic-machine.com
  • Traefik route + LE cert
  • openssl rand -hex 32 -> AGENTS_API_KEY en .env del VPS
  • systemctl enable --now agents_and_robots.service
  • issue 0129 se puede unbloquear tras merge
## feat(0128): HTTP API REST+SSE para gestion remota de agentes **task_run_id:** task_b19cccf68791cc34 **branch:** auto/0128-http-api-sse **issue:** 0128 ### Que incluye este PR **Nuevo paquete `internal/api`:** - `server.go` — HTTP server stdlib, auth Bearer subtle.ConstantTimeCompare - `handlers.go` — REST endpoints: /health, /agents, /agents/{id}, /{id}/{start,stop,restart,logs} - `pubsub.go` — Bus in-memory para SSE broadcast (TODO NATS si llega 2do cliente) - `poller.go` — goroutine StatusAll cada 2s, publica StatusDiff al bus - `tail.go` — tail -f logfiles con poll 200ms para SSE streaming - `server_test.go` — 12 tests unitarios **`cmd/launcher/main.go`:** - Flags `--api-port` y `--api-key` - Arranca `api.Server` como goroutine si apiPort > 0 y hay clave **`systemd/agents_and_robots.service`:** - `Restart=always` (no on-failure) - EnvironmentFile apunta a .env del proyecto **`app.md` v0.2.0:** - port: 8487, health_endpoint: /health (fix drift) - e2e_checks: build, tests, smoke_health, smoke_auth ### Checks verificados - build PASS - 12/12 tests PASS - /health 200, /agents sin auth 401, /agents con key 200 - SSE compilado y funcional - Restart=always en systemd unit ### Pendiente humano (fuera de scope) - DNS A record agents.organic-machine.com - Traefik route + LE cert - openssl rand -hex 32 -> AGENTS_API_KEY en .env del VPS - systemctl enable --now agents_and_robots.service - issue 0129 se puede unbloquear tras merge
dataforge added 1 commit 2026-05-22 19:20:58 +00:00
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)
dataforge added 1 commit 2026-05-22 19:31:52 +00:00
handlers + poller llamaban Manager.StatusAll() siempre. En unified mode (launcher
arranca todos los agents como goroutines bajo 1 PID) no existen PID files
por agente, asi que StatusAll devolvia Running=false aunque los agents estaban
operativos.

Anade Server.statusAllAuto() que chequea IsUnifiedRunning() y delega a
StatusAllUnified() o StatusAll() segun corresponda. Reemplaza las 3 llamadas
directas en handlers.go (handleListAgents, handleGetAgent) y poller.go
(pollStatus seed + checkAndPublishDiffs).

Sin esto el frontend (0129) mostraria running=false universal.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This branch is already included in the target branch. There is nothing to merge.
View command line instructions

Checkout

From your project repository, check out a new branch and test the changes.
git fetch -u origin auto/0128-http-api-sse:auto/0128-http-api-sse
git checkout auto/0128-http-api-sse
Sign in to join this conversation.
No Reviewers
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: dataforge/agents_and_robots#1