Files
agents_and_robots/dev/issues/0028-decouple-launcher.md
T
egutierrez 8f6958f856 chore: agregar issues 0026-0032 y worktrees a gitignore
Registra los nuevos issues pendientes en el indice y excluye
la carpeta worktrees/ del control de versiones.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-09 00:20:53 +00:00

4.1 KiB

0028 — Desacoplar launcher del registro estatico de agentes

Objetivo

Eliminar la necesidad de editar cmd/launcher/main.go cada vez que se añade un agente. Reemplazar el rulesRegistry hard-coded con auto-discovery basado en la convencion de directorios.

Contexto

  • Actualmente cmd/launcher/main.go importa cada paquete de agente explicitamente:
    import (
        assistantagent "github.com/enmanuel/agents/agents/assistant-bot"
        asistente2agent "github.com/enmanuel/agents/agents/asistente-2"
    )
    var rulesRegistry = map[string]func() []decision.Rule{...}
    
  • Cada agente nuevo requiere: añadir import + añadir entrada al map + recompilar
  • El script dev-scripts/agent/new-agent.sh ya modifica el launcher automaticamente, pero es fragil (sed sobre codigo Go)
  • Contradiccion: el launcher hace glob de agents/*/config.yaml para descubrir configs, pero luego necesita imports estaticos para las reglas

Arquitectura

agents/registry.go        NEW → registro global de reglas (init-based)
agents/<id>/agent.go      → cada agente se auto-registra via init()
cmd/launcher/main.go      → eliminar rulesRegistry, usar agents.GetRules(id)

Patron pure core / impure shell

  • pkg/ — sin cambios
  • shell/ — sin cambios
  • agents/ — nuevo registry global + init() en cada agente
  • cmd/launcher/ — simplificacion

Tareas

Fase 1: Crear registry de reglas

  • 1.1 Crear agents/registry.go con Register(id, rulesFn) y GetRules(id)
  • 1.2 Usar sync.Mutex o sync.Map para seguridad en init()

Fase 2: Migrar agentes a auto-registro

  • 2.1 En agents/assistant-bot/agent.go añadir func init() { agents.Register("assistant-bot", Rules) }
  • 2.2 Repetir para asistente-2 y meteorologo
  • 2.3 Actualizar agents/_template/agent.go con el patron init()

Fase 3: Simplificar launcher

  • 3.1 Eliminar imports explicitos de agentes en cmd/launcher/main.go
  • 3.2 Añadir blank import: _ "github.com/enmanuel/agents/agents/assistant-bot" (etc.)
  • 3.3 Reemplazar rulesRegistry[id] con agents.GetRules(id)
  • 3.4 Si no hay reglas registradas para un agent id, log warning y usar reglas vacias (command-only bot)

Fase 4: Actualizar scripts

  • 4.1 Simplificar dev-scripts/agent/new-agent.sh — ya no necesita editar el map, solo añadir blank import
  • 4.2 Actualizar .claude/rules/create_agent.md con el nuevo patron

Fase 5: Tests

  • 5.1 Test para agents/registry.go (register, get, get-missing)
  • 5.2 go build -tags goolm ./... compila
  • 5.3 go test -tags goolm ./... pasa

Fase 6: Cleanup

  • 6.1 Actualizar CLAUDE.md seccion sobre registro en launcher
  • 6.2 Eliminar codigo muerto del launcher

Ejemplo de uso

Antes (crear agente):

// cmd/launcher/main.go — editar manualmente
import newagent "github.com/enmanuel/agents/agents/new-bot"
var rulesRegistry = map[string]func() []decision.Rule{
    "new-bot": newagent.Rules,  // añadir esta linea
}

Despues:

// agents/new-bot/agent.go — auto-registro
func init() {
    agents.Register("new-bot", Rules)
}

// cmd/launcher/main.go — solo blank import
import _ "github.com/enmanuel/agents/agents/new-bot"

Decisiones de diseno

  • init() + blank import: patron estandar en Go (database/sql drivers, image codecs). Simple y familiar
  • Blank imports en launcher: siguen siendo estaticos en el codigo, pero son una linea trivial sin logica. El script de scaffolding puede añadirla sin riesgo de romper sintaxis Go
  • No plugin system dinamico: Go no tiene plugins portables. init() es el mecanismo idomatic

Prerequisitos

  • Ninguno (puede hacerse independiente de otros issues)

Riesgos

  • Orden de init(): Go garantiza init() dentro de un paquete, pero no entre paquetes. Mitigacion: el registro es un map simple, el orden no importa
  • Olvidar blank import: si no se añade el blank import, el agente no se registra y el launcher lo trata como command-only. Mitigacion: el script de scaffolding lo añade automaticamente