feat: añadir skill /create-bot para robots Matrix
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) <noreply@anthropic.com>
This commit is contained in:
@@ -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: "<bot-id> [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 <env>` |
|
||||
|
||||
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/<bot-id>/`
|
||||
3. Si faltan inputs, preguntar al usuario
|
||||
|
||||
### Paso 2: Ejecutar pipeline de scaffold
|
||||
|
||||
```bash
|
||||
./dev-scripts/agent/create-full.sh <bot-id> "<display-name>"
|
||||
```
|
||||
|
||||
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/<bot-id>/agent.go`
|
||||
|
||||
```go
|
||||
package <pkgname> // sin guiones ni _bot: "ping-bot" → package ping
|
||||
|
||||
import (
|
||||
"github.com/enmanuel/agents/agents"
|
||||
"github.com/enmanuel/agents/pkg/decision"
|
||||
)
|
||||
|
||||
func init() {
|
||||
agents.Register("<bot-id>", 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/<bot-id>/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/<bot-id>/prompts/system.md`
|
||||
|
||||
Los robots no necesitan system prompt. Eliminar el directorio prompts/ completo:
|
||||
|
||||
```bash
|
||||
rm -rf agents/<bot-id>/prompts/
|
||||
```
|
||||
|
||||
### Paso 4: Crear comandos custom (si el usuario los pidio)
|
||||
|
||||
Si el usuario pidio comandos custom, crear `agents/<bot-id>/commands.go`:
|
||||
|
||||
```go
|
||||
package <pkgname>
|
||||
|
||||
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: "<command-name>",
|
||||
Description: "<descripcion>",
|
||||
Usage: "!<command-name> [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 == "<bot-id>" {
|
||||
for _, cmd := range <pkg>.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/<id>/agent.go` exporta `Rules()` que retorna `nil`
|
||||
- [ ] `agents/<id>/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_<NORM>`, `MATRIX_PASSWORD_<NORM>`, `PICKLE_KEY_<NORM>`, `SSSS_RECOVERY_KEY_<NORM>`
|
||||
- [ ] No existe `agents/<id>/prompts/` (robots no necesitan system prompt)
|
||||
- [ ] Si tiene comandos custom, estan registrados en el launcher
|
||||
|
||||
Informar al usuario:
|
||||
```
|
||||
Robot <bot-id> creado. Para arrancar:
|
||||
./dev-scripts/server/start.sh
|
||||
|
||||
Comandos built-in: !help, !ping, !status, !info, !version
|
||||
Comandos custom: <lista si hay>
|
||||
|
||||
Archivos a revisar:
|
||||
agents/<bot-id>/agent.go — reglas (nil para robots)
|
||||
agents/<bot-id>/config.yaml — configuracion
|
||||
agents/<bot-id>/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()`
|
||||
@@ -0,0 +1,71 @@
|
||||
# Template: config.yaml para robots
|
||||
|
||||
Config minimalista para robots (command-only, sin LLM).
|
||||
|
||||
## Template base
|
||||
|
||||
```yaml
|
||||
# ============================================
|
||||
# ROBOT: <bot-id>
|
||||
# ============================================
|
||||
|
||||
agent:
|
||||
id: "<bot-id>"
|
||||
name: "<display-name>"
|
||||
version: "1.0.0"
|
||||
type: robot
|
||||
enabled: true
|
||||
description: "<description>"
|
||||
tags: [robot]
|
||||
|
||||
# ============================================
|
||||
# PERSONALIDAD (minima para robots)
|
||||
# ============================================
|
||||
personality:
|
||||
prefix: "<emoji>"
|
||||
language: es
|
||||
|
||||
# ============================================
|
||||
# MATRIX
|
||||
# ============================================
|
||||
matrix:
|
||||
homeserver: "https://matrix-af2f3d.organic-machine.com"
|
||||
user_id: "@<bot-id>:matrix-af2f3d.organic-machine.com"
|
||||
access_token_env: MATRIX_TOKEN_<NORM>
|
||||
device_id: "<BOT-ID>"
|
||||
|
||||
encryption:
|
||||
enabled: true
|
||||
store_path: "./agents/<bot-id>/data/crypto/"
|
||||
pickle_key_env: PICKLE_KEY_<NORM>
|
||||
trust_mode: tofu
|
||||
recovery_key_env: SSSS_RECOVERY_KEY_<NORM>
|
||||
|
||||
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
|
||||
|
||||
`<NORM>` = 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` |
|
||||
Reference in New Issue
Block a user