Refactor code structure for improved readability and maintainability

This commit is contained in:
2026-03-05 23:52:58 +00:00
parent a92fbff801
commit f2626f7007
6 changed files with 181 additions and 69 deletions
+93 -39
View File
@@ -2,6 +2,43 @@
Guía para LLMs que asisten en la creación de agentes en este proyecto.
## Flujo completo automatizado
```bash
# 1. Scaffold — crea config.yaml (E2EE habilitado), agent.go, prompts/, data/
./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.
## Convención de nombres de env vars — REGLA CRÍTICA
**Normalización**: agent ID → mayúsculas, guiones → underscores. **Sin eliminar sufijos.**
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:
@@ -10,6 +47,8 @@ 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
```
@@ -58,9 +97,7 @@ func Rules() []decision.Rule {
### 2. `agents/<agent-id>/config.yaml` — Configuración
Usar como plantilla `agents/assistant/config.yaml` o `agents/asistente2/config.yaml`.
**Campos que SIEMPRE hay que personalizar:**
`new-agent.sh` genera esto automáticamente. Campos que hay que personalizar:
```yaml
agent:
@@ -78,49 +115,21 @@ llm:
matrix:
user_id: "@<agent-id>:matrix-af2f3d.organic-machine.com"
access_token_env: MATRIX_TOKEN_<AGENT_UPPER>
device_id: "<se actualiza después del registro>"
access_token_env: MATRIX_TOKEN_<NORM>
device_id: "" # se resuelve automáticamente via whoami
```
**Convención de nombres de env vars:**
- Token: `MATRIX_TOKEN_<ID_UPPER>` donde ID se convierte a mayúsculas y guiones a underscores
- Ejemplo: `asistente-2``MATRIX_TOKEN_ASISTENTE2`
- Password: `MATRIX_PASSWORD_<ID_UPPER>` con la misma convención
- Pickle key E2EE: `PICKLE_KEY_<ID_UPPER>` — clave fija hex de 32 bytes
### Sección E2EE en config.yaml (generada por new-agent.sh)
**Sección encryption en config.yaml:**
```yaml
encryption:
enabled: true
enabled: true # SIEMPRE true para agentes nuevos
store_path: "./agents/<agent-id>/data/crypto/" # SIEMPRE por agente, nunca compartida
pickle_key_env: PICKLE_KEY_<ID_UPPER> # env var con clave hex
pickle_key_env: PICKLE_KEY_<NORM> # generada por register.sh
trust_mode: tofu
recovery_key_env: SSSS_RECOVERY_KEY_<ID_UPPER> # env var con base58 recovery key
recovery_key_env: SSSS_RECOVERY_KEY_<NORM> # generada por verify.sh
```
**Al crear un nuevo agente con E2EE:**
1. Generar pickle key: `openssl rand -hex 32`
2. Añadir a `.env`: `PICKLE_KEY_<ID_UPPER>=<hex>`
3. Añadir a `.env.example`: `PICKLE_KEY_<ID_UPPER>=`
4. Usar `store_path` propio del agente (no compartir entre agentes)
5. Ejecutar `cmd/verify` con `--store` y `--pickle-key` del agente:
```bash
./bin/verify --homeserver "$MATRIX_HOMESERVER" --username "<id>" \
--password "$MATRIX_PASSWORD_<AGENT>" --token "$MATRIX_TOKEN_<AGENT>" \
--store "./agents/<id>/data/crypto/" --pickle-key "$PICKLE_KEY_<AGENT>"
```
6. Guardar el recovery key en `.env` (con comillas por los espacios):
```bash
SSSS_RECOVERY_KEY_<ID_UPPER>="EsXX YYYY ZZZZ ..."
```
7. Añadir `recovery_key_env` al config.yaml:
```yaml
encryption:
recovery_key_env: SSSS_RECOVERY_KEY_<ID_UPPER>
```
**Sin el recovery key**, el agente arranca pero los mensajes muestran "Encrypted by a device not verified by its owner".
### 3. `agents/<agent-id>/prompts/system.md` — System prompt
Debe incluir:
@@ -134,7 +143,7 @@ Debe incluir:
### 4. `cmd/launcher/main.go` — Registro en el launcher
Dos cambios:
`new-agent.sh` hace esto automáticamente. Dos cambios:
**Import:**
```go
@@ -157,6 +166,49 @@ Si el agente necesita una herramienta nueva (no existente), ver la policy `creat
Las herramientas "siempre disponibles" (`current_time`, `matrix_send`) ya están registradas para todos los agentes.
## 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` |
| `verify.sh` | Cross-signing keys (master, self-signing, user-signing) + recovery key | Server (keys) + `.env` (recovery key) |
### Por qué cada credential importa
| Credential | Para qué | Si falta |
|---|---|---|
| `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
**"Encrypted by a device not verified by its owner"**
→ Ejecutar `./dev-scripts/verify.sh <agent-id>` y reiniciar
**"self-signing private key not in cache"**
→ 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:
@@ -164,15 +216,17 @@ Verificar compilación:
go build -tags goolm ./...
```
Luego seguir con registro, avatar, verificación y arranque (ver `docs/creating-agents.md`).
Luego seguir con registro, verificación y arranque usando los dev-scripts.
## Reglas generales
- **Nunca** poner side effects en `agent.go` — es código puro
- **Siempre** verificar que `agent.id` coincide entre config.yaml, rulesRegistry y el directorio
- **Siempre** compilar con `-tags goolm` para soporte E2EE
- **Siempre** usar `normalize_id()` de `_common.sh` para nombres de env vars
- **Idioma**: español en configs, prompts y descripciones de dominio; inglés en código Go
- **No** crear archivos `data/` — se generan automáticamente al arrancar
- **No** commitear tokens ni passwords — solo van en `.env`
- **No** compartir crypto stores entre agentes — cada uno tiene su `store_path`
- Si el agente usa tool_use, asegurarse de que `llm.tool_use.enabled: true` en el config
- Usar `agents/asistente2/` como referencia completa de un agente con tools habilitadas