- .claude/CLAUDE.md - .claude/rules/create_agent.md - agents/_specials/father-bot/prompts/system.md - agents/_template/config.yaml - agents/_template_robot/config.yaml - cmd/agentctl/autoavatar.go - cmd/launcher/sqlite.go - dev-scripts/_common.sh - dev-scripts/agent/create-full.sh - dev-scripts/agent/delete-full.sh - ... Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
13 KiB
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 <id>
Paso 12: ./dev-scripts/agent/notify-developer.sh <id> <type> "<display-name>" (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) | claude-code |
claude-code (default), openai, anthropic |
llm.model |
no (N/A para robots) | sonnet |
sonnet (claude-code), gpt-4o (openai), claude-sonnet-4-20250514 (anthropic) |
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:
./dev-scripts/agent/create-full.sh <agent-id> "Display Name" \
--description "<descripcion>" \
--system-prompt "<system prompt con seccion de seguridad>" \
[--provider <claude-code|openai|anthropic>] \
[--tone <friendly|professional|casual|technical>] \
[--prefix "<emoji>"] \
[--tool-use] \
[--avatar <URL_o_ruta_local>]
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):
./dev-scripts/agent/personalize.sh <agent-id> --description "..." --system-prompt "..."
REGLA DE PROYECTO — Provider default = claude-code: TODOS los agentes nuevos usan claude-code (subprocess claude -p) por defecto. NO requiere API key, autentica via el CLI claude ya instalado. Solo cambiar a openai/anthropic si hay razon explicita (modelo no disponible en claude-code, requisitos de latencia distintos, etc.). detect-provider.sh ya prioriza claude-code si el binario claude esta en PATH.
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-id>/agent.go — Reglas puras
Template base (generado por el scaffold):
package <pkgname> // 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("<agent-id>", 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/decisionyagents(para Register), cero I/O, cero side effects - Auto-registro: cada agente se registra via
init()condevagents.Register("<agent-id>", 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 viaRegisterCommand(ver policycreate_command.md) - Las reglas solo aplican a mensajes normales (sin prefijo
!)
Tipos de accion disponibles:
ActionKindReply— respuesta estatica (conReplyAction{Content: "..."})ActionKindLLM— pasa al LLM (conLLMAction{})
2. agents/<agent-id>/config.yaml — Configuracion
El scaffold genera un config completo con defaults sensatos. Solo personalizar estas secciones:
Identidad (siempre editar):
agent:
description: "<la descripcion del agente>"
LLM — DEFAULT claude-code (subproceso claude -p, sin API key):
llm:
primary:
provider: claude-code # DEFAULT — usar SIEMPRE salvo razon explicita
model: "sonnet"
api_key_env: "" # claude-code no usa api key
claude_code:
working_dir: "/tmp/claude-agents/<agent-id>" # SIEMPRE fuera del repo
permission_mode: "bypassPermissions"
model: "sonnet"
fallback_model: "haiku"
streaming: true
show_tool_progress: true
Override a API providers (solo si claude-code no encaja):
llm:
primary:
provider: openai # o anthropic
model: gpt-4o # o claude-sonnet-4-20250514
api_key_env: OPENAI_API_KEY # o ANTHROPIC_API_KEY
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):
llm:
tool_use:
enabled: true # cambiar de false a true
max_iterations: 5
Personalidad (ajustar tono):
personality:
tone: friendly # friendly | professional | casual | technical
language: es # es | en
prefix: "🤖" # emoji del bot
Threads (habilitado por defecto en el scaffold):
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/<agent-id>/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.mdal 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):
_ "github.com/enmanuel/agents/agents/<agent-id>"
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
go build -tags goolm ./...
Si falla, corregir y reintentar. Nunca arrancar el launcher si la compilacion falla.
Paso 10 — START/RESTART
./dev-scripts/server/start.sh # primera vez
./dev-scripts/server/restart.sh # si ya estaba corriendo
Paso 11 — HEALTH CHECK
./dev-scripts/agent/health-check.sh <agent-id>
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
./dev-scripts/agent/notify-developer.sh <agent-id> <type> "<display-name>"
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 erroresagents/<id>/agent.goexportaRules()y es puro (sin I/O)agents/<id>/config.yamltieneagent.id= nombre del directoriocmd/launcher/main.gotiene blank import del paquete del agente.envcontiene:MATRIX_TOKEN_<NORM>,MATRIX_PASSWORD_<NORM>,PICKLE_KEY_<NORM>,SSSS_RECOVERY_KEY_<NORM>prompts/system.mdtiene contenido real (no el stub)prompts/system.mdincluye 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 <id>) - Bot envio bienvenida a los devs (o
DEVELOPER_MATRIX_USERSno esta configurado)
Troubleshooting E2EE
| Problema | Solucion |
|---|---|
| "device not verified by its owner" | ./dev-scripts/agent/verify.sh <id> 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.idcoincida 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/