refactor: migrar policies/ a rules/ y añadir create_issue
Se renombra .claude/policies/ a .claude/rules/ para usar terminología más clara y consistente. Se añade la nueva regla create_issue.md con guía completa para crear issues en dev/issues/, incluyendo el template en .claude/templates/issue.md. El índice (index.md) se actualiza con la nueva regla. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,190 @@
|
||||
# Policy: Crear un nuevo agente
|
||||
|
||||
Guía ejecutable para Claude. Seguir paso a paso sin desviarse.
|
||||
|
||||
## Inputs — preguntar al usuario si no los da
|
||||
|
||||
| Input | Requerido | Default | Ejemplo |
|
||||
|-------|-----------|---------|---------|
|
||||
| `agent-id` | sí | — | `monitor-bot` |
|
||||
| `display-name` | sí | — | `"Monitor Agent"` |
|
||||
| `description` | sí | — | `"Monitorea servicios y reporta estado"` |
|
||||
| `llm.provider` | no | `openai` | `openai` o `anthropic` |
|
||||
| `llm.model` | no | `gpt-4o` | `gpt-4o`, `claude-sonnet-4-20250514` |
|
||||
| `tool_use` | no | `false` | `true` si necesita herramientas |
|
||||
| System prompt | sí | — | Texto describiendo rol y capacidades |
|
||||
|
||||
Si el usuario da todos los inputs, ir directo a la Ruta Rápida. Si faltan, preguntar antes de empezar.
|
||||
|
||||
## Ruta rápida — script automatizado
|
||||
|
||||
```bash
|
||||
./dev-scripts/agent/create-full.sh <agent-id> "Display Name"
|
||||
```
|
||||
|
||||
Este script ejecuta en orden: scaffold → build → register Matrix → verify E2EE.
|
||||
Crea todos los archivos, registra en el launcher, genera todas las env vars en `.env`.
|
||||
|
||||
Después del script, personalizar los 3 archivos del agente (ver sección siguiente).
|
||||
|
||||
## Archivos a personalizar después del scaffold
|
||||
|
||||
### 1. `agents/<agent-id>/agent.go` — Reglas puras
|
||||
|
||||
Template base (generado por el scaffold):
|
||||
|
||||
```go
|
||||
package <pkgname> // sin guiones: "monitor-bot" → package monitor (strip hyphens, strip _bot)
|
||||
|
||||
import "github.com/enmanuel/agents/pkg/decision"
|
||||
|
||||
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`, cero I/O, cero side effects
|
||||
- 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 acción disponibles:
|
||||
- `ActionKindReply` — respuesta estática (con `ReplyAction{Content: "..."}`)
|
||||
- `ActionKindLLM` — pasa al LLM (con `LLMAction{}`)
|
||||
|
||||
### 2. `agents/<agent-id>/config.yaml` — Configuración
|
||||
|
||||
El scaffold genera un config completo con defaults sensatos. Solo personalizar estas secciones:
|
||||
|
||||
**Identidad** (siempre editar):
|
||||
```yaml
|
||||
agent:
|
||||
description: "<la descripción del agente>"
|
||||
```
|
||||
|
||||
**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)
|
||||
```
|
||||
|
||||
**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
|
||||
```
|
||||
|
||||
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**: quién es, cómo se llama
|
||||
- **Rol**: qué hace, para qué sirve
|
||||
- **Capacidades**: qué puede hacer (incluir tools si `tool_use.enabled: true`)
|
||||
- **Estilo**: idioma, tono, formato de respuestas
|
||||
- **Restricciones**: qué NO debe hacer
|
||||
|
||||
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 automáticamente.
|
||||
Si falla, hacer manualmente:
|
||||
|
||||
**Import** (después de los imports de agentes existentes):
|
||||
```go
|
||||
<pkg>agent "github.com/enmanuel/agents/agents/<agent-id>"
|
||||
```
|
||||
|
||||
**rulesRegistry** (dentro del map):
|
||||
```go
|
||||
"<agent-id>": <pkg>agent.Rules,
|
||||
```
|
||||
|
||||
El `<pkg>` es el package name del agent.go (sin guiones, sin `_bot`).
|
||||
**El ID en rulesRegistry DEBE coincidir exactamente con `agent.id` en config.yaml.**
|
||||
|
||||
## Convención de env vars — REGLA CRÍTICA
|
||||
|
||||
Normalización: `normalize_id()` → mayúsculas, 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$//'`).
|
||||
|
||||
## Verificación post-creación
|
||||
|
||||
Checklist a verificar antes de considerar el agente listo:
|
||||
|
||||
- [ ] `go build -tags goolm ./...` compila sin errores
|
||||
- [ ] `agents/<id>/agent.go` exporta `Rules()` y es puro (sin I/O)
|
||||
- [ ] `agents/<id>/config.yaml` tiene `agent.id` = nombre del directorio
|
||||
- [ ] `cmd/launcher/main.go` tiene import + entry en rulesRegistry con el mismo ID
|
||||
- [ ] `.env` contiene: `MATRIX_TOKEN_<NORM>`, `MATRIX_PASSWORD_<NORM>`, `PICKLE_KEY_<NORM>`, `SSSS_RECOVERY_KEY_<NORM>`
|
||||
- [ ] `prompts/system.md` tiene contenido real (no el stub)
|
||||
- [ ] Si `tool_use.enabled: true`, el prompt menciona las tools disponibles
|
||||
|
||||
## Arranque y verificación
|
||||
|
||||
```bash
|
||||
# Arrancar (reconstruye y lanza todos los agentes habilitados)
|
||||
./dev-scripts/server/start.sh
|
||||
|
||||
# Verificar logs
|
||||
tail -f run/launcher.log
|
||||
|
||||
# Logs esperados al arrancar correctamente:
|
||||
# {"level":"INFO","msg":"e2ee ready"}
|
||||
# {"level":"INFO","msg":"agent running"}
|
||||
# {"level":"INFO","msg":"starting matrix sync"}
|
||||
```
|
||||
|
||||
## Troubleshooting E2EE
|
||||
|
||||
| Problema | Solución |
|
||||
|----------|----------|
|
||||
| "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 | Añadir 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, rulesRegistry 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/`
|
||||
Reference in New Issue
Block a user