From 81e9e2729aee931f80bad70de8b7b19ddec2094d Mon Sep 17 00:00:00 2001 From: Enmanuel Date: Thu, 9 Apr 2026 00:36:06 +0000 Subject: [PATCH] =?UTF-8?q?feat:=20a=C3=B1adir=20skill=20/create-bot=20par?= =?UTF-8?q?a=20robots=20Matrix?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Skill declarativa para crear robots (command-only, sin LLM) con el pipeline completo: scaffold → build → register → verify → conversion a robot. Incluye template de config.yaml minimalista y soporte para comandos custom. Diferencia con /create-agent: los robots no tienen LLM, reglas, memoria ni system prompt. Solo responden a comandos. Co-Authored-By: Claude Opus 4.6 (1M context) --- .claude/skills/create-bot/SKILL.md | 195 ++++++++++++++++++ .../create-bot/templates/config.yaml.md | 71 +++++++ 2 files changed, 266 insertions(+) create mode 100644 .claude/skills/create-bot/SKILL.md create mode 100644 .claude/skills/create-bot/templates/config.yaml.md diff --git a/.claude/skills/create-bot/SKILL.md b/.claude/skills/create-bot/SKILL.md new file mode 100644 index 0000000..dca50ac --- /dev/null +++ b/.claude/skills/create-bot/SKILL.md @@ -0,0 +1,195 @@ +--- +name: create-bot +description: > + Crear un nuevo robot Matrix (command-only, sin LLM). Ejecuta el pipeline + scaffold + build + register + verify, luego personaliza config.yaml y + comandos custom segun los inputs del usuario. +allowed-tools: Bash Read Write Edit Grep Glob Agent +argument-hint: " [display-name]" +--- + +# Crear robot Matrix + +Skill para crear un robot Matrix ligero (command-only, sin LLM). +Un robot solo responde a comandos — no tiene reglas, memoria, tools ni system prompt. + +## Inputs requeridos + +Recoger del usuario (preguntar lo que falte): + +| Input | Requerido | Default | Ejemplo | +|-------|-----------|---------|---------| +| `bot-id` | si | — | `ping-bot` | +| `display-name` | si | bot-id | `"Ping Bot"` | +| `description` | si | — | `"Bot de monitoreo con ping"` | +| Comandos custom | no | ninguno | `!status`, `!deploy ` | + +Si `$ARGUMENTS` contiene el bot-id, usarlo directamente: `$0` = bot-id, `$1` = display-name. + +## Proceso completo + +### Paso 1: Validar inputs + +1. Verificar que `bot-id` es kebab-case (lowercase, letras, numeros, guiones) +2. Verificar que no existe `agents//` +3. Si faltan inputs, preguntar al usuario + +### Paso 2: Ejecutar pipeline de scaffold + +```bash +./dev-scripts/agent/create-full.sh "" +``` + +Este script ejecuta 4 etapas: scaffold → build → register Matrix → verify E2EE. +Si alguna etapa falla, revisar el error y corregir antes de continuar. + +### Paso 3: Convertir a robot + +El scaffold crea un agente por defecto. Convertirlo a robot: + +#### 3.1 Reemplazar `agents//agent.go` + +```go +package // sin guiones ni _bot: "ping-bot" → package ping + +import ( + "github.com/enmanuel/agents/agents" + "github.com/enmanuel/agents/pkg/decision" +) + +func init() { + agents.Register("", Rules) +} + +// Rules returns nil — robots don't use decision rules. +// All behavior is via RegisterCommand in the launcher. +func Rules() []decision.Rule { + return nil +} +``` + +Package name = bot-id sin guiones ni `_bot` (ej: `ping-bot` → `package ping`). + +#### 3.2 Reemplazar `agents//config.yaml` + +Consultar [templates/config.yaml.md](templates/config.yaml.md) para el template base. + +Ajustes obligatorios: +- `agent.id`: debe coincidir con el nombre del directorio +- `agent.type: robot` (CRITICO — sin esto se lanza como agent completo) +- `agent.description`: la descripcion del usuario +- `personality.prefix`: emoji representativo del bot +- Env vars: normalizar bot-id → mayusculas, guiones → underscores (NUNCA eliminar sufijos) + +#### 3.3 Eliminar `agents//prompts/system.md` + +Los robots no necesitan system prompt. Eliminar el directorio prompts/ completo: + +```bash +rm -rf agents//prompts/ +``` + +### Paso 4: Crear comandos custom (si el usuario los pidio) + +Si el usuario pidio comandos custom, crear `agents//commands.go`: + +```go +package + +import ( + "context" + "fmt" + + "github.com/enmanuel/agents/pkg/command" + "github.com/enmanuel/agents/pkg/decision" +) + +// CommandEntry pairs a spec with its handler. +type CommandEntry struct { + Spec command.Spec + Handler func(ctx context.Context, msgCtx decision.MessageContext) string +} + +// Commands returns the command specs and handlers for this bot. +func Commands() []CommandEntry { + return []CommandEntry{ + { + Spec: command.Spec{ + Name: "", + Description: "", + Usage: "! [args]", + }, + Handler: func(ctx context.Context, msgCtx decision.MessageContext) string { + // Implementar logica del comando + return "respuesta" + }, + }, + } +} +``` + +Luego registrar en `cmd/launcher/main.go` despues de `agents.NewRobot()`: + +```go +if cfg.Agent.ID == "" { + for _, cmd := range .Commands() { + r.RegisterCommand(cmd.Spec, cmd.Handler) + } +} +``` + +### Paso 5: Verificar compilacion + +```bash +go build -tags goolm ./... +``` + +Si falla, corregir y reintentar. + +### Paso 6: Checklist final + +Verificar y reportar al usuario: + +- [ ] `go build -tags goolm ./...` compila sin errores +- [ ] `agents//agent.go` exporta `Rules()` que retorna `nil` +- [ ] `agents//config.yaml` tiene `agent.type: robot` y `agent.id` coincide con directorio +- [ ] `cmd/launcher/main.go` tiene blank import del paquete del bot +- [ ] `.env` contiene las 4 env vars: `MATRIX_TOKEN_`, `MATRIX_PASSWORD_`, `PICKLE_KEY_`, `SSSS_RECOVERY_KEY_` +- [ ] No existe `agents//prompts/` (robots no necesitan system prompt) +- [ ] Si tiene comandos custom, estan registrados en el launcher + +Informar al usuario: +``` +Robot creado. Para arrancar: + ./dev-scripts/server/start.sh + +Comandos built-in: !help, !ping, !status, !info, !version +Comandos custom: + +Archivos a revisar: + agents//agent.go — reglas (nil para robots) + agents//config.yaml — configuracion + agents//commands.go — comandos custom (si aplica) +``` + +## Diferencias clave con /create-agent + +| Aspecto | /create-agent | /create-bot | +|---------|---------------|-------------| +| Runtime | `agents.New()` | `agents.NewRobot()` | +| Config type | `agent` (default) | `robot` | +| LLM | Si | No | +| System prompt | Obligatorio | No existe | +| Reglas | Si (agent.go con Rules) | nil | +| Tools | Opcionales | No | +| Memoria/Knowledge | Opcionales | No | +| Comandos built-in | help, ping, tools, tool, status, info, clear, prompts, version | help, ping, status, info, version | + +## Notas importantes + +- **Siempre compilar con `-tags goolm`** +- **Nunca commitear tokens ni passwords** — van en `.env` +- **Homeserver**: `https://matrix-af2f3d.organic-machine.com` +- **Server name**: `matrix-af2f3d.organic-machine.com` +- Referencia de robot existente: `agents/_template_robot/` +- El bot-id DEBE coincidir entre directorio, config.yaml y `agents.Register()` diff --git a/.claude/skills/create-bot/templates/config.yaml.md b/.claude/skills/create-bot/templates/config.yaml.md new file mode 100644 index 0000000..e1d2b95 --- /dev/null +++ b/.claude/skills/create-bot/templates/config.yaml.md @@ -0,0 +1,71 @@ +# Template: config.yaml para robots + +Config minimalista para robots (command-only, sin LLM). + +## Template base + +```yaml +# ============================================ +# ROBOT: +# ============================================ + +agent: + id: "" + name: "" + version: "1.0.0" + type: robot + enabled: true + description: "" + tags: [robot] + +# ============================================ +# PERSONALIDAD (minima para robots) +# ============================================ +personality: + prefix: "" + language: es + +# ============================================ +# MATRIX +# ============================================ +matrix: + homeserver: "https://matrix-af2f3d.organic-machine.com" + user_id: "@:matrix-af2f3d.organic-machine.com" + access_token_env: MATRIX_TOKEN_ + device_id: "" + + encryption: + enabled: true + store_path: "./agents//data/crypto/" + pickle_key_env: PICKLE_KEY_ + trust_mode: tofu + recovery_key_env: SSSS_RECOVERY_KEY_ + + rooms: + listen: [] + respond: [] + admin: [] + + filters: + command_prefix: "!" + mention_respond: false + dm_respond: false + ignore_bots: true + ignore_users: [] + unauthorized_response: silent + min_power_level: 0 + + threads: + enabled: true + auto_thread: false +``` + +## Regla de normalizacion de env vars + +`` = bot-id en mayusculas, guiones → underscores. **Nunca eliminar sufijos.** + +| bot-id | NORM | Ejemplo env var | +|--------|------|-----------------| +| `ping-bot` | `PING_BOT` | `MATRIX_TOKEN_PING_BOT` | +| `monitor` | `MONITOR` | `MATRIX_TOKEN_MONITOR` | +| `mi-bot-2` | `MI_BOT_2` | `MATRIX_TOKEN_MI_BOT_2` |