Both issues delivered end-to-end: 0128 (backend, merged via dataforge/agents_and_robots/pulls/1): - HTTP daemon in cmd/launcher with apikey Bearer auth + SSE - LIVE at https://agents.organic-machine.com via Coolify Traefik + LE cert - systemd Restart=always - Unified status autodetect fix applied 0129 (frontend, merged via dataforge/agents_dashboard/pulls/1): - C++ ImGui app in projects/element_agents/apps/agents_dashboard - 4 panels: Connection / Agents / Logs / Status - secret_store_cpp_infra new function (DPAPI Windows / XOR Linux) - Deployed to Windows Desktop, App Hub tarjeta visible Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
6.9 KiB
id, title, status, type, domain, scope, priority, depends, blocks, related, created, updated, tags, dod_evidence_schema
| id | title | status | type | domain | scope | priority | depends | blocks | related | created | updated | tags | dod_evidence_schema | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0128 | agents_and_robots: HTTP API + SSE + apikey + TLS subdominio | pendiente | feature |
|
app | alta |
|
2026-05-22 | 2026-05-22 |
|
|
0128 — agents_and_robots HTTP API + SSE + apikey + TLS
Contexto
Hoy agents_and_robots solo expone control via agentctl CLI local (filesystem-based, shell/process.Manager). No hay forma remota de gestionar agentes.
Necesitamos backend HTTP seguro para que un frontend local C++ (issue 0129) pueda listar, start/stop/restart agentes, y streamear logs/status en vivo.
Decision
Integrar daemon HTTP DENTRO de cmd/launcher como goroutine. Comparte process.Manager + acceso a shell/memory/*.db + Matrix clients. Un solo proceso, sin drift entre daemon y supervisor.
Auth: Authorization: Bearer <AGENTS_API_KEY> con subtle.ConstantTimeCompare. Clave 32 bytes hex en .env (AGENTS_API_KEY). 401 sin header o key invalida.
TLS: Traefik en VPS organic-machine.com con LE cert auto. Subdominio agents.organic-machine.com (DNS A record nuevo → IP del VPS). Ruta Traefik agents.organic-machine.com → 127.0.0.1:8487.
SSE in-memory pubsub. NATS OFF de momento (1 cliente local, broker = overhead). Documentar TODO en app.md para anadir bus si llega 2do consumidor.
Scope v0.1 (lean)
| Verbo | Path | Wrap |
|---|---|---|
| GET | /health |
200 OK sin auth (liveness) |
| GET | /agents |
Scan + StatusAll + msg_count_24h (query shell/memory/*.db) |
| GET | /agents/{id} |
detail + config + LogTail(200) |
| POST | /agents/{id}/start |
Manager.Start |
| POST | /agents/{id}/stop |
Manager.Stop |
| POST | /agents/{id}/restart |
Stop+Start con espera health |
| GET | /agents/{id}/logs?n=200 |
LogTail snapshot |
SSE:
GET /sse/status— broadcast cambios de status (poll cada 2s + diff)GET /sse/agents/{id}/logs— tail -f del logfile, emite line events
Fuera de scope v0.1 (queda v0.2):
- POST
/agents/{id}/message(send Matrix message) - PUT
/agents/{id}/config(config edit) - SSE messages stream
Tareas
- Nuevo paquete
internal/apicon server HTTP (stdlibnet/http, sin gin/echo).api.New(mgr *process.Manager, apiKey string, port int) *ServerServer.Run(ctx) errorarranca y bloquea hasta ctx done.- Middleware: log + auth + recover.
- Handlers REST sobre
process.Manager. Tests unitarios con mock manager. - SSE pubsub in-memory (
internal/api/pubsub.go):BusconSubscribe(topic) <-chan event+Publish(topic, event).- Poller goroutine que llama
StatusAllcada 2s y publica diffs. - Tail goroutine por logfile (
file_tail_follow— buscar en registry o crear).
- Integrar en launcher —
cmd/launcher/main.goarrancaapi.Serveren goroutine si--api-port > 0. - Crear systemd unit
/etc/systemd/system/agents_and_robots.serviceconRestart=always,EnvironmentFile=.env,ExecStart=.../bin/launcher --log-level info --api-port 8487. - Traefik route + DNS:
- Anadir
agents.organic-machine.comen DNS (A record). - Anadir config Traefik (label en docker-compose del stack o file provider) apuntando a
127.0.0.1:8487.
- Anadir
- Fix drift app.md —
runtime: systemd-systemahora es verdad. Verificar confn doctor services-spec. - Tests:
- Go: pkg
internal/apicon httptest. - e2e:
e2e_checksenapp.mdcon curl smoke.
- Go: pkg
- Deploy:
rsync_deploy_bash_infraodeploy_servertarget nuevo.- Generar
AGENTS_API_KEYconopenssl rand -hex 32y escribir.envremoto. systemctl enable --now agents_and_robots.service.
Funciones del registry a usar / proponer
Buscar antes de codear:
mcp__registry__fn_search query="tail follow file" lang="go"— ¿existefile_tail_follow_go_infra? Si no, delegar a fn-constructor.mcp__registry__fn_search query="http auth bearer" lang="go"— middleware auth.mcp__registry__fn_search query="sse server" lang="go"— helper SSE.systemd_generate_unit_go_infra+systemd_install_go_infra— generar/instalar unit.
Acceptance
curl -fsS -H 'Authorization: Bearer $KEY' https://agents.organic-machine.com/agentsdevuelve lista correcta.- Sin header → 401. Con key invalida → 401. Key valida → 200.
- Start/Stop/Restart cambian estado real del proceso (verificable con
ps). - SSE logs entrega lineas en menos de 1s de aparecer en el archivo.
- SSE status broadcast tras stop/start manual.
- systemd unit activo y reinicia tras kill -9.
fn doctor services-specreporta OK.- Tests Go pasan.
DoD humano
- Donde: terminal local →
curl https://agents.organic-machine.com/agents. SSE verificable concurl -N. - Latencia: SSE log lag < 1s. REST list < 200ms.
- Onboarding: README de agents_and_robots actualizado con seccion "HTTP API" + ejemplos curl.
Riesgos
- DNS propagation puede tardar (configurar con TTL bajo).
- Traefik en este VPS: verificar si esta gestionado por Coolify o standalone — anadir ruta donde corresponda.
LogTailactual solo lee snapshot — necesitamostail -freal para SSE. Si no existe en el registry, ronda previa.