8f6958f856
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>
5.6 KiB
5.6 KiB
0030 — Separacion Robot vs Agente
Objetivo
Crear un tipo Robot como runtime ligero para bots que solo responden comandos, sin LLM, reglas, memoria ni tools. Distinguir en config entre type: robot y type: agent para que el launcher sepa que runtime instanciar.
Contexto
- Actualmente todos los bots usan el mismo
Agentstruct (1,182 lineas) con 25+ subsistemas - Un bot de comandos simples (ej:
!deploy prod,!status) no necesita LLM, memoria, knowledge, skills, sanitizacion, ni tool-use - Si
llm.primary.provideresta vacio,runtime.gologuea "running as command-only bot" pero sigue inicializando todo el subsistema - No hay forma idiomatica de crear un bot simple sin arrastrar toda la complejidad
- Ejemplos de robots: bot de deploys, bot de health checks, bot de notificaciones, bot de CI/CD
Arquitectura
agents/robot.go NEW → Robot struct (~150 lineas): Matrix + Commands
agents/robot_test.go NEW → tests del runtime minimo
agents/types.go NEW → interfaz comun Runner { Run(ctx), Stop(), RegisterCommand() }
cmd/launcher/main.go → detectar type: robot y crear Robot en vez de Agent
internal/config/schema.go → añadir campo Agent.Type ("robot" | "agent")
Patron pure core / impure shell
pkg/— sin cambios (el Robot no usa decision engine ni reglas)shell/matrix/— sin cambios (el Robot reutiliza el mismo cliente Matrix)agents/robot.go— impuro (tiene Matrix client), pero minimoagents/runtime.go— sin cambios (Agent sigue igual)
Tareas
Fase 1: Definir interfaz comun
- 1.1 Crear
agents/types.gocon interfazRunner:type Runner interface { Run(ctx context.Context) error Stop() RegisterCommand(spec command.Spec, handler CommandHandler) } - 1.2 Verificar que
Agentya satisfaceRunner(o adaptar)
Fase 2: Implementar Robot
- 2.1 Crear
agents/robot.gocon structRobot:matrix *matrix.Clientcommands *command.Registry(built-ins + custom)logger *slog.Loggerconfig config.AgentConfig
- 2.2 Implementar
NewRobot(cfg, logger)— solo inicializa Matrix + commands - 2.3 Implementar
Run()— sync loop que solo despacha comandos - 2.4 Implementar
Stop()— cierra Matrix client - 2.5 Implementar
RegisterCommand()— registra comando custom - 2.6 En
handleEvent(): si no es comando, ignorar silenciosamente (no hay LLM)
Fase 3: Config y launcher
- 3.1 Añadir campo
Type stringaAgentCfgen schema.go (default: "agent") - 3.2 En launcher: si
cfg.Agent.Type == "robot", crearNewRobot()en vez deNew() - 3.3 El launcher usa la interfaz
Runnerpara manejar ambos tipos uniformemente
Fase 4: Template y scaffolding
- 4.1 Crear
agents/_template_robot/con config minimo para robots - 4.2 Config de robot ejemplo (~20 lineas):
agent: id: deploy-bot type: robot description: "Bot de deploys" personality: prefix: "🤖" matrix: threads: enabled: true - 4.3 Actualizar
dev-scripts/agent/create-full.shpara aceptar flag--robot
Fase 5: Tests
- 5.1 Test: Robot responde a
!helpcon lista de comandos - 5.2 Test: Robot responde a
!pingcon pong - 5.3 Test: Robot ignora mensajes normales (no es error, simplemente no responde)
- 5.4 Test: Robot con comando custom registrado lo ejecuta
- 5.5 Test:
Runnerinterfaz es satisfecha por ambosAgentyRobot
Fase 6: Documentacion
- 6.1 Actualizar
CLAUDE.mdcon seccion Robot vs Agent - 6.2 Actualizar
.claude/rules/create_agent.mdmencionando la opcion robot - 6.3 Añadir tabla comparativa en docs
Ejemplo de uso
# agents/deploy-bot/config.yaml
agent:
id: deploy-bot
type: robot
description: "Bot de deploys con comandos directos"
personality:
prefix: "🚀"
matrix:
homeserver: ${MATRIX_HOMESERVER}
user_id: "@deploy-bot:matrix-af2f3d.organic-machine.com"
access_token_env: MATRIX_TOKEN_DEPLOY_BOT
// agents/deploy-bot/commands.go
package deploy
func Commands() []agents.CommandEntry {
return []agents.CommandEntry{
{
Spec: command.Spec{Name: "deploy", Usage: "!deploy <env>"},
Handler: func(ctx context.Context, msg decision.MessageContext) string {
return fmt.Sprintf("Deploying to %s...", msg.Args[0])
},
},
}
}
Interaccion en Element:
Usuario: !deploy staging
Bot: 🚀 Deploying to staging...
Usuario: hola bot
Bot: (silencio — no tiene LLM)
Decisiones de diseno
- Interfaz
Runner: permite al launcher tratar robots y agentes uniformemente sin type switches - Robot NO tiene reglas: las reglas son para routing inteligente. Un robot solo hace dispatch de comandos
- Robot NO tiene memory/knowledge/skills: mantener el runtime lo mas ligero posible
- Config minimo: un robot funcional se define en ~20 lineas de YAML
- Silencio ante mensajes normales: un robot no responde "no entiendo", simplemente ignora. Los comandos tienen
!helppara descubrirse
Prerequisitos
- Ninguno (puede hacerse independiente)
- Se beneficia de 0026 (split runtime) pero no lo requiere
Riesgos
- Duplicacion: Robot y Agent comparten logica de Matrix, commands, lifecycle. Mitigacion: reutilizar
shell/matrix/ypkg/command/sin duplicar - Scope creep: tentacion de añadir "un poquito de LLM" al Robot. Mitigacion: la linea es clara — si necesita LLM, es un Agent