docs: actualizar paths y simplificar policy de creación de agentes
Se actualizan todas las referencias a dev-scripts para usar los nuevos paths con subdirectorios server/ y agent/ en: - .claude/CLAUDE.md — sección de dev-scripts y guía rápida - .claude/policies/create_agent.md — simplificada y reorganizada como guía ejecutable - README.md — sección de uso y estructura de directorios - docs/creating-agents.md — todos los pasos del flujo La policy create_agent.md se reduce de ~230 a ~140 líneas, eliminando secciones redundantes y reorganizando como checklist práctico con ruta rápida via create-full.sh. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
+31
-22
@@ -55,6 +55,8 @@ cmd/launcher/main.go → inicia agentes, tiene rulesRegistry
|
|||||||
cmd/agentctl/main.go → CLI de gestión (list, start, stop, remove)
|
cmd/agentctl/main.go → CLI de gestión (list, start, stop, remove)
|
||||||
cmd/register/main.go → registra bots en Synapse via admin API
|
cmd/register/main.go → registra bots en Synapse via admin API
|
||||||
dev-scripts/ → scripts bash para operaciones del día a día
|
dev-scripts/ → scripts bash para operaciones del día a día
|
||||||
|
dev-scripts/server/ → gestión del launcher (start, stop, restart, ps, logs, dashboard)
|
||||||
|
dev-scripts/agent/ → gestión de agentes (new, register, verify, avatar, remove, list)
|
||||||
```
|
```
|
||||||
|
|
||||||
## Políticas para LLMs
|
## Políticas para LLMs
|
||||||
@@ -103,42 +105,49 @@ Secciones principales del config: `agent`, `personality`, `llm`, `tools`, `matri
|
|||||||
|
|
||||||
Guía rápida (detalle completo en `docs/creating-agents.md`, policy en `.claude/policies/create_agent.md`):
|
Guía rápida (detalle completo en `docs/creating-agents.md`, policy en `.claude/policies/create_agent.md`):
|
||||||
|
|
||||||
1. Crear scaffold: `./dev-scripts/new-agent.sh <id> "Display Name"` o manual en `agents/<id>/`
|
1. Crear scaffold: `./dev-scripts/agent/new-agent.sh <id> "Display Name"` o manual en `agents/<id>/`
|
||||||
2. Crear `agent.go` (reglas puras), `config.yaml`, `prompts/system.md`
|
2. Crear `agent.go` (reglas puras), `config.yaml`, `prompts/system.md`
|
||||||
3. Registrar en `cmd/launcher/main.go` → import + `rulesRegistry`
|
3. Registrar en `cmd/launcher/main.go` → import + `rulesRegistry`
|
||||||
4. Registrar en Matrix: `./dev-scripts/register.sh <id> "Display Name"`
|
4. Registrar en Matrix: `./dev-scripts/agent/register.sh <id> "Display Name"`
|
||||||
5. Avatar y nombre: `./dev-scripts/avatar.sh <id> static/<imagen>.jpg`
|
5. Avatar y nombre: `./dev-scripts/agent/avatar.sh <id> static/<imagen>.jpg`
|
||||||
6. Verificación E2EE: `go run -tags goolm ./cmd/verify --homeserver ... --username <id> --password ... --token ...`
|
6. Verificación E2EE: `go run -tags goolm ./cmd/verify --homeserver ... --username <id> --password ... --token ...`
|
||||||
7. Arrancar: `./dev-scripts/start.sh <id>`
|
7. Arrancar: `./dev-scripts/server/start.sh <id>`
|
||||||
|
|
||||||
## Dev-scripts disponibles
|
## Dev-scripts disponibles
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
./dev-scripts/list.sh # ver todos los bots y estado
|
# === server/ — gestión del launcher ===
|
||||||
./dev-scripts/start.sh [agent-id] # iniciar uno o todos
|
./dev-scripts/server/start.sh # iniciar el launcher
|
||||||
./dev-scripts/stop.sh [agent-id] # detener uno o todos
|
./dev-scripts/server/stop.sh # detener el launcher
|
||||||
./dev-scripts/restart.sh [agent-id] # reiniciar uno o todos
|
./dev-scripts/server/restart.sh # reiniciar el launcher
|
||||||
./dev-scripts/ps.sh [agent-id] # procesos con detalle (PID, mem, CPU, uptime)
|
./dev-scripts/server/ps.sh # procesos con detalle (PID, mem, CPU, uptime)
|
||||||
./dev-scripts/remove.sh <agent-id> # deshabilitar (sin borrar datos)
|
./dev-scripts/server/logs.sh [lines] # tail -f de logs
|
||||||
./dev-scripts/register.sh <id> [name] # registrar bot en Matrix
|
./dev-scripts/server/dashboard.sh # TUI interactiva
|
||||||
./dev-scripts/logs.sh [agent-id] # tail -f de logs
|
|
||||||
./dev-scripts/new-agent.sh <id> [name] # scaffold completo
|
|
||||||
|
|
||||||
# Gestión unificada del servidor
|
# Gestión unificada (wrapper)
|
||||||
./dev-scripts/server.sh start [id] # iniciar agentes
|
./dev-scripts/server/server.sh start # iniciar
|
||||||
./dev-scripts/server.sh stop [id] # detener agentes
|
./dev-scripts/server/server.sh stop # detener
|
||||||
./dev-scripts/server.sh restart [id] # reiniciar agentes
|
./dev-scripts/server/server.sh restart # reiniciar
|
||||||
./dev-scripts/server.sh status # resumen general del servidor
|
./dev-scripts/server/server.sh status # resumen general del servidor
|
||||||
./dev-scripts/server.sh ps [id] # procesos con detalle
|
./dev-scripts/server/server.sh ps # procesos con detalle
|
||||||
./dev-scripts/server.sh logs [id] # tail -f de logs
|
./dev-scripts/server/server.sh logs # tail -f de logs
|
||||||
./dev-scripts/server.sh kill [id] # SIGKILL forzado (emergencia)
|
./dev-scripts/server/server.sh kill # SIGKILL forzado (emergencia)
|
||||||
|
|
||||||
|
# === agent/ — gestión de agentes ===
|
||||||
|
./dev-scripts/agent/list.sh # ver todos los bots y estado
|
||||||
|
./dev-scripts/agent/new-agent.sh <id> [name] # scaffold completo
|
||||||
|
./dev-scripts/agent/register.sh <id> [name] # registrar bot en Matrix
|
||||||
|
./dev-scripts/agent/verify.sh [agent-id] # verificación E2EE
|
||||||
|
./dev-scripts/agent/avatar.sh <id> <img> # subir avatar
|
||||||
|
./dev-scripts/agent/reset-password.sh <id> # resetear password
|
||||||
|
./dev-scripts/agent/remove.sh <agent-id> # deshabilitar (sin borrar datos)
|
||||||
```
|
```
|
||||||
|
|
||||||
PID files: `run/<id>.pid` | Log files: `run/<id>.log`
|
PID files: `run/<id>.pid` | Log files: `run/<id>.log`
|
||||||
|
|
||||||
## Gestión de procesos
|
## Gestión de procesos
|
||||||
|
|
||||||
Los bots corren como procesos independientes lanzados por `agentctl` o `dev-scripts/start.sh`.
|
Los bots corren como procesos independientes lanzados por `agentctl` o `dev-scripts/server/start.sh`.
|
||||||
Cada proceso escribe su PID en `run/<id>.pid` y su log en `run/<id>.log`.
|
Cada proceso escribe su PID en `run/<id>.pid` y su log en `run/<id>.log`.
|
||||||
`is_running()` usa `kill -0 <pid>` para verificar sin matar el proceso.
|
`is_running()` usa `kill -0 <pid>` para verificar sin matar el proceso.
|
||||||
|
|
||||||
|
|||||||
+118
-153
@@ -1,81 +1,55 @@
|
|||||||
# Cómo crear un nuevo agente
|
# Policy: Crear un nuevo agente
|
||||||
|
|
||||||
Guía para LLMs que asisten en la creación de agentes en este proyecto.
|
Guía ejecutable para Claude. Seguir paso a paso sin desviarse.
|
||||||
|
|
||||||
## Flujo completo automatizado
|
## 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
|
```bash
|
||||||
# 1. Scaffold — crea config.yaml (E2EE habilitado), agent.go, prompts/, data/
|
./dev-scripts/agent/create-full.sh <agent-id> "Display Name"
|
||||||
./dev-scripts/new-agent.sh <agent-id> "Display Name"
|
|
||||||
|
|
||||||
# 2. Registrar en Matrix — genera y guarda en .env:
|
|
||||||
# MATRIX_TOKEN_<NORM>, MATRIX_PASSWORD_<NORM>, PICKLE_KEY_<NORM>
|
|
||||||
./dev-scripts/register.sh <agent-id> "Display Name"
|
|
||||||
|
|
||||||
# 3. Verificar E2EE — genera cross-signing keys, firma el device,
|
|
||||||
# guarda SSSS_RECOVERY_KEY_<NORM> en .env
|
|
||||||
./dev-scripts/verify.sh <agent-id>
|
|
||||||
|
|
||||||
# 4. Arrancar — ya verificado desde el primer arranque
|
|
||||||
./dev-scripts/start.sh <agent-id>
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Los scripts automatizan todo. Solo intervenir manualmente si un paso falla.
|
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`.
|
||||||
|
|
||||||
## Convención de nombres de env vars — REGLA CRÍTICA
|
Después del script, personalizar los 3 archivos del agente (ver sección siguiente).
|
||||||
|
|
||||||
**Normalización**: agent ID → mayúsculas, guiones → underscores. **Sin eliminar sufijos.**
|
## Archivos a personalizar después del scaffold
|
||||||
|
|
||||||
Función canónica en `dev-scripts/_common.sh`:
|
|
||||||
```bash
|
|
||||||
normalize_id() { echo "$1" | tr '[:lower:]-' '[:upper:]_'; }
|
|
||||||
```
|
|
||||||
|
|
||||||
| Agent ID | Sufijo normalizado | Env vars |
|
|
||||||
|---|---|---|
|
|
||||||
| `assistant-bot` | `ASSISTANT_BOT` | `MATRIX_TOKEN_ASSISTANT_BOT`, `MATRIX_PASSWORD_ASSISTANT_BOT`, `PICKLE_KEY_ASSISTANT_BOT`, `SSSS_RECOVERY_KEY_ASSISTANT_BOT` |
|
|
||||||
| `asistente-2` | `ASISTENTE_2` | `MATRIX_TOKEN_ASISTENTE_2`, `MATRIX_PASSWORD_ASISTENTE_2`, `PICKLE_KEY_ASISTENTE_2`, `SSSS_RECOVERY_KEY_ASISTENTE_2` |
|
|
||||||
| `monitor-bot` | `MONITOR_BOT` | `MATRIX_TOKEN_MONITOR_BOT`, ... |
|
|
||||||
|
|
||||||
**NUNCA** usar `sed 's/_BOT$//'` ni transformaciones que eliminen partes del ID.
|
|
||||||
|
|
||||||
## Estructura requerida
|
|
||||||
|
|
||||||
Cada agente vive en `agents/<agent-id>/` con esta estructura:
|
|
||||||
|
|
||||||
```
|
|
||||||
agents/<agent-id>/
|
|
||||||
├── agent.go # Package propio, exporta Rules() []decision.Rule
|
|
||||||
├── config.yaml # Configuración completa (ver schema en internal/config/schema.go)
|
|
||||||
├── data/ # Runtime data (crypto, logs) — en .gitignore
|
|
||||||
│ └── crypto/ # Crypto store E2EE — NUNCA compartir entre agentes
|
|
||||||
└── prompts/
|
|
||||||
└── system.md # System prompt del LLM
|
|
||||||
```
|
|
||||||
|
|
||||||
## Archivos a crear
|
|
||||||
|
|
||||||
### 1. `agents/<agent-id>/agent.go` — Reglas puras
|
### 1. `agents/<agent-id>/agent.go` — Reglas puras
|
||||||
|
|
||||||
|
Template base (generado por el scaffold):
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package <agentpkg>
|
package <pkgname> // sin guiones: "monitor-bot" → package monitor (strip hyphens, strip _bot)
|
||||||
|
|
||||||
import "github.com/enmanuel/agents/pkg/decision"
|
import "github.com/enmanuel/agents/pkg/decision"
|
||||||
|
|
||||||
func Rules() []decision.Rule {
|
func Rules() []decision.Rule {
|
||||||
return []decision.Rule{
|
return []decision.Rule{
|
||||||
// Regla help explícita
|
|
||||||
{
|
{
|
||||||
Name: "help",
|
Name: "help",
|
||||||
Match: decision.MatchCommand("help"),
|
Match: decision.MatchCommand("help"),
|
||||||
Actions: []decision.Action{{
|
Actions: []decision.Action{{
|
||||||
Kind: decision.ActionKindReply,
|
Kind: decision.ActionKindReply,
|
||||||
Reply: &decision.ReplyAction{Content: "Descripción de capacidades del bot."},
|
Reply: &decision.ReplyAction{Content: "<descripción de capacidades>"},
|
||||||
}},
|
}},
|
||||||
},
|
},
|
||||||
// Catch-all → LLM
|
|
||||||
{
|
{
|
||||||
Name: "llm-all",
|
Name: "llm-fallback",
|
||||||
Match: func(ctx decision.MessageContext) bool {
|
Match: func(ctx decision.MessageContext) bool {
|
||||||
return ctx.IsDirectMsg || ctx.IsMention
|
return ctx.IsDirectMsg || ctx.IsMention
|
||||||
},
|
},
|
||||||
@@ -88,145 +62,136 @@ func Rules() []decision.Rule {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
**Reglas del archivo de reglas:**
|
**Reglas estrictas:**
|
||||||
- **PURO**: sin imports de I/O, sin side effects, solo `pkg/decision`
|
- **PURO**: solo imports de `pkg/decision`, cero I/O, cero side effects
|
||||||
- El package name debe ser Go-valid (sin guiones): `agents/mi-bot/` → `package mibot`
|
- Package name = ID sin guiones ni `_bot` (e.g. `monitor-bot` → `package monitor`)
|
||||||
- Las reglas se evalúan en orden — poner las específicas antes del catch-all
|
- Reglas se evalúan en orden — específicas arriba, catch-all al final
|
||||||
- El catch-all debe cubrir `ctx.IsDirectMsg || ctx.IsMention` como mínimo
|
- El catch-all DEBE cubrir `ctx.IsDirectMsg || ctx.IsMention`
|
||||||
- `ActionKindReply` para respuestas estáticas, `ActionKindLLM` para respuestas dinámicas
|
|
||||||
|
Para añadir reglas extra, insertar antes del catch-all. 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
|
### 2. `agents/<agent-id>/config.yaml` — Configuración
|
||||||
|
|
||||||
`new-agent.sh` genera esto automáticamente. Campos que hay que personalizar:
|
El scaffold genera un config completo con defaults sensatos. Solo personalizar estas secciones:
|
||||||
|
|
||||||
|
**Identidad** (siempre editar):
|
||||||
```yaml
|
```yaml
|
||||||
agent:
|
agent:
|
||||||
id: <agent-id> # DEBE coincidir con el directorio y rulesRegistry
|
description: "<la descripción del agente>"
|
||||||
name: "Display Name"
|
```
|
||||||
description: "Qué hace este agente"
|
|
||||||
|
|
||||||
|
**LLM** (si quieres cambiar provider/model):
|
||||||
|
```yaml
|
||||||
llm:
|
llm:
|
||||||
primary:
|
primary:
|
||||||
provider: openai # o anthropic
|
provider: anthropic # o openai (default)
|
||||||
model: gpt-4o # o claude-sonnet-4-20250514
|
model: claude-sonnet-4-20250514 # o gpt-4o (default)
|
||||||
api_key_env: OPENAI_API_KEY # o ANTHROPIC_API_KEY
|
api_key_env: ANTHROPIC_API_KEY # o OPENAI_API_KEY (default)
|
||||||
tool_use:
|
|
||||||
enabled: true/false # true si el agente usa herramientas
|
|
||||||
|
|
||||||
matrix:
|
|
||||||
user_id: "@<agent-id>:matrix-af2f3d.organic-machine.com"
|
|
||||||
access_token_env: MATRIX_TOKEN_<NORM>
|
|
||||||
device_id: "" # se resuelve automáticamente via whoami
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### Sección E2EE en config.yaml (generada por new-agent.sh)
|
**Tool use** (si el agente necesita herramientas):
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
encryption:
|
llm:
|
||||||
enabled: true # SIEMPRE true para agentes nuevos
|
tool_use:
|
||||||
store_path: "./agents/<agent-id>/data/crypto/" # SIEMPRE por agente, nunca compartida
|
enabled: true # cambiar de false a true
|
||||||
pickle_key_env: PICKLE_KEY_<NORM> # generada por register.sh
|
max_iterations: 5
|
||||||
trust_mode: tofu
|
|
||||||
recovery_key_env: SSSS_RECOVERY_KEY_<NORM> # generada por verify.sh
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
**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
|
### 3. `agents/<agent-id>/prompts/system.md` — System prompt
|
||||||
|
|
||||||
Debe incluir:
|
Escribir el system prompt completo. Debe incluir:
|
||||||
- Identidad del bot (quién es, qué hace)
|
- **Identidad**: quién es, cómo se llama
|
||||||
- Capacidades y limitaciones
|
- **Rol**: qué hace, para qué sirve
|
||||||
- Herramientas disponibles (si `tool_use.enabled: true`)
|
- **Capacidades**: qué puede hacer (incluir tools si `tool_use.enabled: true`)
|
||||||
- Estilo de respuesta (idioma, tono, formato)
|
- **Estilo**: idioma, tono, formato de respuestas
|
||||||
- Instrucciones de uso de herramientas (cuándo y cómo usarlas)
|
- **Restricciones**: qué NO debe hacer
|
||||||
|
|
||||||
## Archivos a modificar
|
Ejemplo de referencia: `agents/asistente-2/prompts/system.md`
|
||||||
|
|
||||||
### 4. `cmd/launcher/main.go` — Registro en el launcher
|
## Registro en el launcher — `cmd/launcher/main.go`
|
||||||
|
|
||||||
`new-agent.sh` hace esto automáticamente. Dos cambios:
|
El script `new-agent.sh` (ejecutado por `create-full.sh`) hace esto automáticamente.
|
||||||
|
Si falla, hacer manualmente:
|
||||||
|
|
||||||
**Import:**
|
**Import** (después de los imports de agentes existentes):
|
||||||
```go
|
```go
|
||||||
<agentpkg>agent "github.com/enmanuel/agents/agents/<agent-id>"
|
<pkg>agent "github.com/enmanuel/agents/agents/<agent-id>"
|
||||||
```
|
```
|
||||||
|
|
||||||
**rulesRegistry:**
|
**rulesRegistry** (dentro del map):
|
||||||
```go
|
```go
|
||||||
var rulesRegistry = map[string]func() []decision.Rule{
|
"<agent-id>": <pkg>agent.Rules,
|
||||||
// ... agentes existentes ...
|
|
||||||
"<agent-id>": <agentpkg>agent.Rules, // ← nuevo
|
|
||||||
}
|
|
||||||
```
|
```
|
||||||
|
|
||||||
**El ID en rulesRegistry DEBE coincidir exactamente con `agent.id` del config.yaml.**
|
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.**
|
||||||
|
|
||||||
### 5. `agents/runtime.go` — Registro de herramientas (solo si hay tools nuevas)
|
## Convención de env vars — REGLA CRÍTICA
|
||||||
|
|
||||||
Si el agente necesita una herramienta nueva (no existente), ver la policy `create_tool.md`.
|
Normalización: `normalize_id()` → mayúsculas, guiones → underscores. **Sin eliminar sufijos.**
|
||||||
|
|
||||||
Las herramientas "siempre disponibles" (`current_time`, `matrix_send`) ya están registradas para todos los agentes.
|
| Agent ID | Normalizado | Env vars |
|
||||||
|
|
||||||
## E2EE — Cómo funciona la verificación
|
|
||||||
|
|
||||||
### Flujo al arrancar (agents/runtime.go)
|
|
||||||
|
|
||||||
```
|
|
||||||
InitCrypto → crea/carga el device y Olm account del crypto store
|
|
||||||
FetchCrossSigningKeys → obtiene private keys de SSSS usando recovery key
|
|
||||||
SignOwnDevice → fetch device keys del servidor + firma con self-signing key
|
|
||||||
```
|
|
||||||
|
|
||||||
### Qué hace cada script
|
|
||||||
|
|
||||||
| Script | Qué genera | Dónde se guarda |
|
|
||||||
|---|---|---|
|
|---|---|---|
|
||||||
| `register.sh` | Token, password, pickle key (32 bytes hex) | `.env` |
|
| `assistant-bot` | `ASSISTANT_BOT` | `MATRIX_TOKEN_ASSISTANT_BOT`, `MATRIX_PASSWORD_ASSISTANT_BOT`, `PICKLE_KEY_ASSISTANT_BOT`, `SSSS_RECOVERY_KEY_ASSISTANT_BOT` |
|
||||||
| `verify.sh` | Cross-signing keys (master, self-signing, user-signing) + recovery key | Server (keys) + `.env` (recovery key) |
|
| `mi-bot` | `MI_BOT` | `MATRIX_TOKEN_MI_BOT`, ... |
|
||||||
|
|
||||||
### Por qué cada credential importa
|
**NUNCA** aplicar transformaciones que eliminen partes del ID (no `sed 's/_BOT$//'`).
|
||||||
|
|
||||||
| Credential | Para qué | Si falta |
|
## Verificación post-creación
|
||||||
|---|---|---|
|
|
||||||
| `MATRIX_TOKEN_*` | Autenticación del bot con el homeserver | Bot no arranca |
|
|
||||||
| `MATRIX_PASSWORD_*` | UIA al subir cross-signing keys (verify.sh) | verify.sh intenta dummy auth (MSC3967) |
|
|
||||||
| `PICKLE_KEY_*` | Cifrar el crypto store en disco | Usa sha256(token) como fallback — inseguro |
|
|
||||||
| `SSSS_RECOVERY_KEY_*` | Recuperar private keys de cross-signing al arrancar | Device no se firma → "not verified by its owner" |
|
|
||||||
|
|
||||||
### Problemas comunes y soluciones
|
Checklist a verificar antes de considerar el agente listo:
|
||||||
|
|
||||||
**"Encrypted by a device not verified by its owner"**
|
- [ ] `go build -tags goolm ./...` compila sin errores
|
||||||
→ Ejecutar `./dev-scripts/verify.sh <agent-id>` y reiniciar
|
- [ ] `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
|
||||||
|
|
||||||
**"self-signing private key not in cache"**
|
## Arranque y verificación
|
||||||
→ La recovery key en `.env` no corresponde a las cross-signing keys actuales. Re-ejecutar verify.sh.
|
|
||||||
|
|
||||||
**"received update for device with different signing key"**
|
|
||||||
→ Bug resuelto: `SignOwnDevice` ahora hace `FetchKeys` antes de firmar. Si reaparece, recompilar el launcher: `go build -tags goolm -o bin/launcher ./cmd/launcher`
|
|
||||||
|
|
||||||
**"data is not encrypted for given key ID"**
|
|
||||||
→ Las cross-signing keys fueron regeneradas pero la recovery key en `.env` es la vieja. Re-ejecutar verify.sh (actualiza .env automáticamente).
|
|
||||||
|
|
||||||
**Recovery key sin comillas en .env**
|
|
||||||
→ Causan `command not found` al hacer `source .env`. Las recovery keys tienen espacios y DEBEN ir entre comillas: `SSSS_RECOVERY_KEY_*="EsXX YYYY ZZZZ ..."`
|
|
||||||
|
|
||||||
## Después de crear los archivos
|
|
||||||
|
|
||||||
Verificar compilación:
|
|
||||||
```bash
|
```bash
|
||||||
go build -tags goolm ./...
|
# 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"}
|
||||||
```
|
```
|
||||||
|
|
||||||
Luego seguir con registro, verificación y arranque usando los dev-scripts.
|
## 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
|
## Reglas generales
|
||||||
|
|
||||||
- **Nunca** poner side effects en `agent.go` — es código puro
|
- **Nunca** side effects en `agent.go`
|
||||||
- **Siempre** verificar que `agent.id` coincide entre config.yaml, rulesRegistry y el directorio
|
- **Siempre** compilar con `-tags goolm`
|
||||||
- **Siempre** compilar con `-tags goolm` para soporte E2EE
|
- **Siempre** que `agent.id` coincida entre config.yaml, rulesRegistry y directorio
|
||||||
- **Siempre** usar `normalize_id()` de `_common.sh` para nombres de env vars
|
- **No** crear `data/` manualmente — se auto-genera
|
||||||
- **Idioma**: español en configs, prompts y descripciones de dominio; inglés en código Go
|
- **No** commitear tokens ni passwords
|
||||||
- **No** crear archivos `data/` — se generan automáticamente al arrancar
|
- **No** compartir crypto stores entre agentes
|
||||||
- **No** commitear tokens ni passwords — solo van en `.env`
|
- Referencia de agente con tools: `agents/asistente-2/`
|
||||||
- **No** compartir crypto stores entre agentes — cada uno tiene su `store_path`
|
- Referencia de agente simple: `agents/assistant-bot/`
|
||||||
- Si el agente usa tool_use, asegurarse de que `llm.tool_use.enabled: true` en el config
|
|
||||||
- Usar `agents/asistente-2/` como referencia completa de un agente con tools habilitadas
|
|
||||||
|
|||||||
@@ -94,6 +94,8 @@ agents_and_robots/
|
|||||||
│ └── register/ registra bots en Synapse via admin API
|
│ └── register/ registra bots en Synapse via admin API
|
||||||
│
|
│
|
||||||
├── dev-scripts/ scripts bash para el día a día
|
├── dev-scripts/ scripts bash para el día a día
|
||||||
|
│ ├── server/ gestión del launcher (start, stop, restart, ps, logs, dashboard)
|
||||||
|
│ └── agent/ gestión de agentes (new, register, verify, avatar, remove, list)
|
||||||
├── config/ configuración global (matrix.yaml, servers.yaml)
|
├── config/ configuración global (matrix.yaml, servers.yaml)
|
||||||
└── .env.example plantilla de variables de entorno
|
└── .env.example plantilla de variables de entorno
|
||||||
```
|
```
|
||||||
@@ -129,20 +131,20 @@ go mod tidy
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Registrar el bot en el servidor Matrix (necesita MATRIX_ADMIN_TOKEN en .env)
|
# Registrar el bot en el servidor Matrix (necesita MATRIX_ADMIN_TOKEN en .env)
|
||||||
./dev-scripts/register.sh assistant-bot "Assistant"
|
./dev-scripts/agent/register.sh assistant-bot "Assistant"
|
||||||
# → imprime el token, copiarlo a .env como MATRIX_TOKEN_ASSISTANT
|
# → imprime el token, copiarlo a .env como MATRIX_TOKEN_ASSISTANT
|
||||||
|
|
||||||
# Ver todos los bots y su estado
|
# Ver todos los bots y su estado
|
||||||
./dev-scripts/list.sh
|
./dev-scripts/agent/list.sh
|
||||||
|
|
||||||
# Iniciar
|
# Iniciar
|
||||||
./dev-scripts/start.sh assistant-bot
|
./dev-scripts/server/start.sh assistant-bot
|
||||||
|
|
||||||
# Ver logs en vivo
|
# Ver logs en vivo
|
||||||
./dev-scripts/logs.sh assistant-bot
|
./dev-scripts/server/logs.sh assistant-bot
|
||||||
|
|
||||||
# Detener
|
# Detener
|
||||||
./dev-scripts/stop.sh assistant-bot
|
./dev-scripts/server/stop.sh assistant-bot
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
@@ -169,7 +171,7 @@ make build # genera bin/launcher, bin/agentctl, bin/register
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
# 1. Generar el scaffold completo
|
# 1. Generar el scaffold completo
|
||||||
./dev-scripts/new-agent.sh monitor-bot "Monitor Agent"
|
./dev-scripts/agent/new-agent.sh monitor-bot "Monitor Agent"
|
||||||
```
|
```
|
||||||
|
|
||||||
Genera:
|
Genera:
|
||||||
@@ -193,9 +195,9 @@ var rulesRegistry = map[string]func() []decision.Rule{
|
|||||||
}
|
}
|
||||||
|
|
||||||
# 3. Registrarlo en Matrix y arrancar
|
# 3. Registrarlo en Matrix y arrancar
|
||||||
./dev-scripts/register.sh monitor-bot "Monitor Agent"
|
./dev-scripts/agent/register.sh monitor-bot "Monitor Agent"
|
||||||
# → añadir token a .env
|
# → añadir token a .env
|
||||||
./dev-scripts/start.sh monitor-bot
|
./dev-scripts/server/start.sh monitor-bot
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|||||||
+11
-11
@@ -13,8 +13,8 @@ Esta guía documenta todos los pasos para crear, registrar, configurar y poner e
|
|||||||
### Opción A: Script automático
|
### Opción A: Script automático
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
./dev-scripts/new-agent.sh <agent-id> "Display Name"
|
./dev-scripts/agent/new-agent.sh <agent-id> "Display Name"
|
||||||
# Ejemplo: ./dev-scripts/new-agent.sh mi-bot "Mi Bot"
|
# Ejemplo: ./dev-scripts/agent/new-agent.sh mi-bot "Mi Bot"
|
||||||
```
|
```
|
||||||
|
|
||||||
Esto crea la estructura base en `agents/<agent-id>/`.
|
Esto crea la estructura base en `agents/<agent-id>/`.
|
||||||
@@ -159,7 +159,7 @@ var rulesRegistry = map[string]func() []decision.Rule{
|
|||||||
## Paso 3: Registrar en Matrix
|
## Paso 3: Registrar en Matrix
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
./dev-scripts/register.sh <agent-id> "Display Name"
|
./dev-scripts/agent/register.sh <agent-id> "Display Name"
|
||||||
```
|
```
|
||||||
|
|
||||||
Este comando:
|
Este comando:
|
||||||
@@ -192,7 +192,7 @@ Colocar la imagen del bot en `static/`:
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Subir avatar y sincronizar displayname desde el config
|
# Subir avatar y sincronizar displayname desde el config
|
||||||
./dev-scripts/avatar.sh <agent-id> static/<imagen>.jpg
|
./dev-scripts/agent/avatar.sh <agent-id> static/<imagen>.jpg
|
||||||
```
|
```
|
||||||
|
|
||||||
Esto hace:
|
Esto hace:
|
||||||
@@ -272,7 +272,7 @@ Cambiar la password (admin API) invalida el token anterior. Hay que:
|
|||||||
## Paso 6: Arrancar el agente
|
## Paso 6: Arrancar el agente
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
./dev-scripts/start.sh <agent-id>
|
./dev-scripts/server/start.sh <agent-id>
|
||||||
```
|
```
|
||||||
|
|
||||||
Verificar que arrancó correctamente:
|
Verificar que arrancó correctamente:
|
||||||
@@ -282,10 +282,10 @@ Verificar que arrancó correctamente:
|
|||||||
tail -f run/<agent-id>.log
|
tail -f run/<agent-id>.log
|
||||||
|
|
||||||
# Verificar proceso
|
# Verificar proceso
|
||||||
./dev-scripts/ps.sh <agent-id>
|
./dev-scripts/server/ps.sh <agent-id>
|
||||||
|
|
||||||
# Estado general
|
# Estado general
|
||||||
./dev-scripts/list.sh
|
./dev-scripts/agent/list.sh
|
||||||
```
|
```
|
||||||
|
|
||||||
**Logs esperados al arrancar correctamente:**
|
**Logs esperados al arrancar correctamente:**
|
||||||
@@ -308,7 +308,7 @@ tail -f run/<agent-id>.log
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
# 1. Crear scaffold
|
# 1. Crear scaffold
|
||||||
./dev-scripts/new-agent.sh <id> "Nombre"
|
./dev-scripts/agent/new-agent.sh <id> "Nombre"
|
||||||
|
|
||||||
# 2. Editar reglas, config, prompt
|
# 2. Editar reglas, config, prompt
|
||||||
# agents/<id>/agent.go
|
# agents/<id>/agent.go
|
||||||
@@ -319,10 +319,10 @@ tail -f run/<agent-id>.log
|
|||||||
# Editar cmd/launcher/main.go → import + rulesRegistry
|
# Editar cmd/launcher/main.go → import + rulesRegistry
|
||||||
|
|
||||||
# 4. Registrar en Matrix
|
# 4. Registrar en Matrix
|
||||||
./dev-scripts/register.sh <id> "Nombre"
|
./dev-scripts/agent/register.sh <id> "Nombre"
|
||||||
|
|
||||||
# 5. Avatar y displayname
|
# 5. Avatar y displayname
|
||||||
./dev-scripts/avatar.sh <id> static/<imagen>.jpg
|
./dev-scripts/agent/avatar.sh <id> static/<imagen>.jpg
|
||||||
|
|
||||||
# 6. Generar pickle key (si no existe)
|
# 6. Generar pickle key (si no existe)
|
||||||
openssl rand -hex 32 # → guardar como PICKLE_KEY_<AGENT> en .env
|
openssl rand -hex 32 # → guardar como PICKLE_KEY_<AGENT> en .env
|
||||||
@@ -339,7 +339,7 @@ openssl rand -hex 32 # → guardar como PICKLE_KEY_<AGENT> en .env
|
|||||||
# → Añadir recovery_key_env al config.yaml
|
# → Añadir recovery_key_env al config.yaml
|
||||||
|
|
||||||
# 8. Arrancar
|
# 8. Arrancar
|
||||||
./dev-scripts/start.sh <id>
|
./dev-scripts/server/start.sh <id>
|
||||||
|
|
||||||
# 9. Verificar
|
# 9. Verificar
|
||||||
tail -f run/<id>.log
|
tail -f run/<id>.log
|
||||||
|
|||||||
Reference in New Issue
Block a user