# Policy: Crear un nuevo agente o robot Guia ejecutable para Claude. Seguir paso a paso sin desviarse. ## Pipeline formalizado (12 pasos) Todo agente o robot creado debe pasar por TODOS estos pasos, en orden estricto: ``` 1. SCAFFOLD → crear archivos base desde template 2. BUILD → go build -tags goolm ./... 3. REGISTER → crear usuario Matrix + token 4. VERIFY E2EE → cross-signing + recovery key 5. CONVERT (robot) → eliminar LLM/prompts si type=robot 6. AUTO-AVATAR → generar y aplicar foto de perfil 7. DISPLAY NAME → configurar nombre visible en Matrix 8. PERSONALIZE → config.yaml, agent.go, system prompt 9. REBUILD → recompilar tras personalizacion 10. START/RESTART → arrancar el launcher con el bot 11. HEALTH CHECK → verificar que el bot esta activo 12. SELF-INTRODUCE → el bot envia bienvenida a los devs ``` **Pasos 1-7**: ejecutados por `./dev-scripts/agent/create-full.sh` **Paso 8**: personalizar manualmente agent.go, config.yaml, prompts/system.md **Paso 9**: `go build -tags goolm ./...` **Paso 10**: `./dev-scripts/server/start.sh` (o `restart.sh`) **Paso 11**: `./dev-scripts/agent/health-check.sh ` **Paso 12**: `./dev-scripts/agent/notify-developer.sh ""` (requiere `DEVELOPER_MATRIX_USERS` en `.env`) ## Robot vs Agent — decidir primero | | Agent | Robot | |---|---|---| | **Cuando usar** | Necesita LLM, reglas, memoria, tools | Solo responde comandos (!xxx) | | **Runtime** | `devagents.New()` — completo | `devagents.NewRobot()` — ligero | | **Config type** | `type: agent` (default) | `type: robot` | | **LLM** | Si | No | | **Reglas** | Si (`agent.go` con `Rules()`) | No (sin `agent.go`) | | **Memoria/Knowledge/Skills** | Si (opcionales) | No | | **Tools** | Si (opcionales) | No | | **System prompt** | Si (`prompts/system.md`) | No necesario | | **Comandos built-in** | help, ping, tools, tool, status, info, clear, prompts, version | help, ping, status, info, version | | **Comandos custom** | Si (`RegisterCommand`) | Si (`RegisterCommand`) | | **Template** | `agents/_template/` | `agents/_template_robot/` | | **Config ejemplo** | ~260 lineas | ~55 lineas | **Regla**: si el bot necesita entender lenguaje natural, es un Agent. Si solo necesita comandos directos, es un Robot. ## Inputs — preguntar al usuario si no los da | Input | Requerido | Default | Ejemplo | |-------|-----------|---------|---------| | `agent-id` | si | — | `monitor-bot` | | `display-name` | si | — | `"Monitor Agent"` | | `description` | si | — | `"Monitorea servicios y reporta estado"` | | `type` | no | `agent` | `agent` o `robot` | | `llm.provider` | no (N/A para robots) | `openai` | `openai` o `anthropic` | | `llm.model` | no (N/A para robots) | `gpt-4o` | `gpt-4o`, `claude-sonnet-4-20250514` | | `tool_use` | no (N/A para robots) | `false` | `true` si necesita herramientas | | System prompt | si (N/A para robots) | — | Texto describiendo rol y capacidades | Si el usuario da todos los inputs, ir directo a la Ruta Rapida. Si faltan, preguntar antes de empezar. ## Ruta rapida — script automatizado (pasos 1-8) Si tienes todos los datos del agente (description + system prompt), el Paso 8 puede hacerse automaticamente: ```bash ./dev-scripts/agent/create-full.sh "Display Name" \ --description "" \ --provider \ --system-prompt "" \ [--tone ] \ [--prefix ""] \ [--tool-use] ``` Este script ejecuta en orden: scaffold, build, register Matrix, verify E2EE, auto-avatar, display name, **personalizar (auto)**, notify. Crea todos los archivos, registra en el launcher, genera todas las env vars en `.env`. **Si se omiten los flags de personalización**, el script se comporta como antes (pasos 1-7) y el Paso 8 queda pendiente de edición manual. **Personalización independiente** (sobre agente ya creado): ```bash ./dev-scripts/agent/personalize.sh --description "..." --system-prompt "..." ``` **Auto-detección de provider**: omitir `--provider` para que `detect-provider.sh` elija automáticamente según `.env`. Despues del script, continuar con pasos 9-12 (rebuild, start, health check, self-introduce). ## Archivos a personalizar despues del scaffold (paso 8) ### 1. `agents//agent.go` — Reglas puras Template base (generado por el scaffold): ```go package // sin guiones: "monitor-bot" → package monitor (strip hyphens, strip _bot) import ( "github.com/enmanuel/agents/devagents" "github.com/enmanuel/agents/pkg/decision" ) func init() { devagents.Register("", Rules) } func Rules() []decision.Rule { return []decision.Rule{ // Any DM or mention → LLM { Name: "llm-all", Match: func(ctx decision.MessageContext) bool { return ctx.IsDirectMsg || ctx.IsMention }, Actions: []decision.Action{{ Kind: decision.ActionKindLLM, LLM: &decision.LLMAction{}, }}, }, } } ``` **Reglas estrictas:** - **PURO**: solo imports de `pkg/decision` y `agents` (para Register), cero I/O, cero side effects - **Auto-registro**: cada agente se registra via `init()` con `devagents.Register("", Rules)` - Package name = ID sin guiones ni `_bot` (e.g. `monitor-bot` → `package monitor`) - **No usar reglas para comandos** (`!help`, `!ping`, etc.) — los comandos se gestionan via `RegisterCommand` (ver policy `create_command.md`) - Las reglas solo aplican a mensajes normales (sin prefijo `!`) Tipos de accion disponibles: - `ActionKindReply` — respuesta estatica (con `ReplyAction{Content: "..."}`) - `ActionKindLLM` — pasa al LLM (con `LLMAction{}`) ### 2. `agents//config.yaml` — Configuracion El scaffold genera un config completo con defaults sensatos. Solo personalizar estas secciones: **Identidad** (siempre editar): ```yaml agent: description: "" ``` **LLM** (si quieres cambiar provider/model): ```yaml llm: primary: provider: anthropic # o openai (default) model: claude-sonnet-4-20250514 # o gpt-4o (default) api_key_env: ANTHROPIC_API_KEY # o OPENAI_API_KEY (default) ``` **Claude-code provider** (si usa `claude-code` como provider): ```yaml llm: primary: provider: claude-code claude_code: working_dir: "/tmp/claude-agents/" # SIEMPRE configurar, nunca dejar vacio permission_mode: "bypassPermissions" ``` **Importante**: `working_dir` debe apuntar fuera del repositorio para evitar que el subproceso `claude -p` acceda al codigo fuente. Si se deja vacio, se usara un directorio temporal (con WARN en logs). **Tool use** (si el agente necesita herramientas): ```yaml llm: tool_use: enabled: true # cambiar de false a true max_iterations: 5 ``` **Personalidad** (ajustar tono): ```yaml personality: tone: friendly # friendly | professional | casual | technical language: es # es | en prefix: "🤖" # emoji del bot ``` **Threads** (habilitado por defecto en el scaffold): ```yaml matrix: threads: enabled: true # responder en threads cuando el mensaje viene de un thread auto_thread: false # true para crear thread automatico por cada conversacion nueva ``` Referencia completa del schema: `internal/config/schema.go` ### 3. `agents//prompts/system.md` — System prompt Escribir el system prompt completo. Debe incluir: - **Identidad**: quien es, como se llama - **Rol**: que hace, para que sirve - **Capacidades**: que puede hacer (incluir tools si `tool_use.enabled: true`) - **Estilo**: idioma, tono, formato de respuestas - **Restricciones**: que NO debe hacer - **Seguridad** (obligatorio): copiar la seccion de `.claude/templates/security-prompt.md` al final del prompt. Esta seccion protege contra prompt injection. Ejemplo de referencia: `agents/asistente-2/prompts/system.md` ## Registro en el launcher — `cmd/launcher/main.go` El script `new-agent.sh` (ejecutado por `create-full.sh`) hace esto automaticamente. Si falla, hacer manualmente: **Blank import** (en la seccion de blank imports de agentes): ```go _ "github.com/enmanuel/agents/agents/" ``` Las reglas se registran automaticamente via `init()` en el paquete del agente. No se necesita editar ningun map ni registry manualmente. **El ID en `devagents.Register()` DEBE coincidir exactamente con `agent.id` en config.yaml.** ## Convencion de env vars — REGLA CRITICA Normalizacion: `normalize_id()` → mayusculas, guiones → underscores. **Sin eliminar sufijos.** | Agent ID | Normalizado | Env vars | |---|---|---| | `assistant-bot` | `ASSISTANT_BOT` | `MATRIX_TOKEN_ASSISTANT_BOT`, `MATRIX_PASSWORD_ASSISTANT_BOT`, `PICKLE_KEY_ASSISTANT_BOT`, `SSSS_RECOVERY_KEY_ASSISTANT_BOT` | | `mi-bot` | `MI_BOT` | `MATRIX_TOKEN_MI_BOT`, ... | **NUNCA** aplicar transformaciones que eliminen partes del ID (no `sed 's/_BOT$//'`). ## Pasos 9-12: post-personalizacion ### Paso 9 — REBUILD ```bash go build -tags goolm ./... ``` Si falla, corregir y reintentar. **Nunca arrancar el launcher si la compilacion falla.** ### Paso 10 — START/RESTART ```bash ./dev-scripts/server/start.sh # primera vez ./dev-scripts/server/restart.sh # si ya estaba corriendo ``` ### Paso 11 — HEALTH CHECK ```bash ./dev-scripts/agent/health-check.sh ``` Verifica en los logs del launcher que el agente arranco correctamente (busca `"e2ee ready"`, `"runner started"`, etc.). Timeout: 30 segundos (configurable como segundo argumento). **No continuar al paso 12 si el health check falla.** Diagnosticar primero. ### Paso 12 — SELF-INTRODUCE ```bash ./dev-scripts/agent/notify-developer.sh "" ``` El propio bot envia DM de bienvenida a cada developer en `DEVELOPER_MATRIX_USERS`. Incluye: - Nombre y tipo (agent/robot) - Descripcion (leida de config.yaml) - Tools habilitadas (si aplica) - Instrucciones de uso Reintenta hasta 3 veces con backoff si el envio falla. Si `DEVELOPER_MATRIX_USERS` no esta definida en `.env`, se salta con warning. ## Verificacion post-creacion Checklist a verificar antes de considerar el agente listo: - [ ] `go build -tags goolm ./...` compila sin errores - [ ] `agents//agent.go` exporta `Rules()` y es puro (sin I/O) - [ ] `agents//config.yaml` tiene `agent.id` = nombre del directorio - [ ] `cmd/launcher/main.go` tiene blank import del paquete del agente - [ ] `.env` contiene: `MATRIX_TOKEN_`, `MATRIX_PASSWORD_`, `PICKLE_KEY_`, `SSSS_RECOVERY_KEY_` - [ ] `prompts/system.md` tiene contenido real (no el stub) - [ ] `prompts/system.md` incluye la seccion de seguridad anti-injection (de `.claude/templates/security-prompt.md`) - [ ] Si `tool_use.enabled: true`, el prompt menciona las tools disponibles - [ ] Health check pasa (`./dev-scripts/agent/health-check.sh `) - [ ] Bot envio bienvenida a los devs (o `DEVELOPER_MATRIX_USERS` no esta configurado) ## Troubleshooting E2EE | Problema | Solucion | |----------|----------| | "device not verified by its owner" | `./dev-scripts/agent/verify.sh ` y reiniciar | | "self-signing private key not in cache" | Recovery key incorrecta → re-ejecutar verify.sh | | "received update for device with different signing key" | Recompilar launcher: `go build -tags goolm -o bin/launcher ./cmd/launcher` | | Recovery key sin comillas en .env | Anadir comillas: `SSSS_RECOVERY_KEY_*="EsXX YYYY ..."` | ## Reglas generales - **Nunca** side effects en `agent.go` - **Siempre** compilar con `-tags goolm` - **Siempre** que `agent.id` coincida entre config.yaml, `devagents.Register()` y directorio - **No** crear `data/` manualmente — se auto-genera - **No** commitear tokens ni passwords - **No** compartir crypto stores entre agentes - Referencia de agente con tools: `agents/asistente-2/` - Referencia de agente simple: `agents/assistant-bot/`