Commit Graph

5 Commits

Author SHA1 Message Date
egutierrez 10f0614fc0 fix(launcher): supervisar agentes y reiniciarlos cuando salen sin cancelacion
El launcher salia con status=0 cuando todos los runners (Agent/Robot)
terminaban su Run() de forma natural — por ejemplo tras una rotacion de
token de Matrix o un drop del sync. systemd, configurado con
Restart=on-failure, no relanzaba el proceso al ver salida limpia y los
bots quedaban caidos hasta una intervencion manual.

Solucion: nueva rutina superviseUntilCanceled en agentRegistry que
bloquea sobre waitAll, y si el ctx padre sigue vivo, espera un backoff
y llama reloadAll para recrear los runners. Solo cuando el ctx padre
se cancela (SIGINT/SIGTERM) la rutina retorna y el launcher sale.

main.go pasa a invocar este supervisor en lugar de waitAll directo.

Tests:
- TestSuperviseUntilCanceled_ReturnsWhenCtxCanceledFirst — empty registry
- TestSuperviseUntilCanceled_ReturnsAfterCtxCancelDuringBackoff — cancel
  durante el backoff debe desbloquear inmediatamente
- TestSuperviseUntilCanceled_CallsReloadOnAgentExit — supervisor sigue
  vivo todo el deadline aunque reload falle por cfgPath invalido

Diagnostico: tras varias horas el journalctl mostraba "Deactivated
successfully" sin "Stopping" previo (Apr 13 18:22 tras 23h corriendo)
y el log del agent registraba "context canceled" tras "starting matrix
sync" — sintoma de que mautrix.SyncWithContext salio limpiamente y el
ctx.cancel se propago al cerrar la goroutine sin que systemd hubiera
enviado SIGTERM. El bucle supervisado lo arregla recreando los runners
sin tocar la unit ni depender del Restart de systemd.
2026-05-09 14:55:41 +02:00
egutierrez bd0c8c0dd3 refactor: mover runtime Go de agents/ a devagents/
agents/ ahora solo contiene carpetas de agentes (config, reglas, prompts).
El runtime (Agent, Robot, Runner, registry, handler, commands, llm, memory)
vive en devagents/ como package devagents.

Cambios:
- git mv agents/*.go → devagents/*.go
- package agents → package devagents en todos los archivos movidos
- Actualizar imports en agents/*/agent.go, cmd/launcher/, dev-scripts/
- Actualizar docs: CLAUDE.md, rules/, docs/e2ee.md, issues pendientes

Build y tests pasan sin errores.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-09 21:19:25 +00:00
egutierrez 7913918025 feat: implementar tipo Robot como runtime ligero para bots command-only
Introduce la separacion Robot vs Agent en el sistema:

- agents/types.go: interfaz Runner comun (Run, Stop, Done, RegisterCommand)
  que tanto Agent como Robot satisfacen
- agents/robot.go: struct Robot — runtime minimo que solo conecta a Matrix
  y despacha comandos. Sin LLM, reglas, memoria, knowledge, skills ni tools.
  Mensajes normales se ignoran silenciosamente
- internal/config/schema.go: campo Type en AgentMeta ("agent"|"robot")
- cmd/launcher: usa Runner interface para manejar ambos tipos uniformemente.
  Si cfg.Agent.Type == "robot" crea NewRobot en vez de New (tanto en
  arranque como en hot-reload)
- agents/_template_robot/config.yaml: plantilla minima (~55 lineas) para
  robots command-only

El Robot soporta built-in commands reducidos (help, ping, status, info,
version) y comandos custom via RegisterCommand. No incluye tools, tool,
clear ni prompts ya que no tiene LLM ni memoria.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-09 00:21:42 +00:00
egutierrez 8811d45fd1 feat: conectar sistema centralizado de seguridad al launcher y runtime
- Migrar admin a security/user-groups.yaml (admins group)
- agents.New() ahora acepta acl.ACL pre-resuelta como parámetro;
  elimina construcción interna desde cfg.Security.Roles
- cmd/launcher: carga shellsecurity.Load("security/") al arranque;
  si falla, WARN + política vacía (open access). Para cada agente
  llama pksecurity.ResolveACL y pasa la ACL a agents.New()
- cmd/launcher/registry.go: stores secPolicy en launchDeps para
  que reload() también resuelva ACL centralmente
- shell/matrix/listener.go: elimina invite gating y allowlist check
  basados en AllowedUsers; el control de acceso lo hace el runtime
- internal/config/schema.go: depreca campos Roles y AllowedUsers
  (backward compat, no eliminados)
- agents/*/config.yaml: elimina bloques security.roles y allowed_users
- dev/feature_flags.json: activa centralized-security-groups (enabled: true)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-08 20:56:21 +00:00
egutierrez 069f8758b1 feat: hot-reload de agentes individuales via SIGHUP
Implementa el mecanismo de hot-reload descrito en el issue 0013:

- agents/runtime.go: añade Agent.Stop() y Agent.Done() para ciclo de vida
  individual. Run() crea un contexto hijo cancelable y cierra el canal
  done al retornar.

- cmd/launcher/registry.go (nuevo): agentRegistry rastrea agentes vivos
  por ID. Métodos: register, stopAndWait, reload, reloadAll, waitAll,
  cleanupLogs. reload() sigue el flujo completo: stop→wait→unsubscribe
  →reload config→recreate→rewire bus/orch→start nueva goroutine.

- cmd/launcher/main.go: usa agentRegistry en lugar de sync.WaitGroup.
  Añade handler de SIGHUP en goroutine separada que lee run/reload.txt
  para determinar el agente objetivo (* o vacío = todos). Tras leer,
  borra run/reload.txt para no afectar el siguiente SIGHUP.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-08 18:41:32 +00:00