57a1602e8f
- reports/ Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
88 lines
5.3 KiB
Markdown
88 lines
5.3 KiB
Markdown
# Report 0002 — Matrix-out: los bots de agents_and_robots hablan solo por unibus
|
|
|
|
- **Fecha:** 07/06/2026
|
|
- **Autor:** Claude (Opus 4.8)
|
|
- **Ámbito:** `~/DataProyects/Github/agents_and_robots` (Gitea `egutierrez/agents_and_robots`) y `projects/message_bus/apps/unibus` (`dataforge/unibus`)
|
|
- **Estado:** done (con gaps acotados)
|
|
|
|
## Resumen
|
|
|
|
Se arranca **todo Matrix (mautrix) de raíz** de `agents_and_robots` y se reconecta el core de
|
|
agentes al bus `unibus` por el seam neutral `pkg/transport`. Modelo **"todo son rooms"** con **E2E**
|
|
(`room.ModeMatrix`): el bot descubre por polling las rooms a las que lo invitan, se une, descifra y
|
|
**responde en la misma room**. Resultado: el binario de agentes no contiene una sola línea de
|
|
mautrix y compila sin `-tags goolm` ni `libolm`. Trabajo en ramas TBD, mergeado a master en ambos
|
|
repos.
|
|
|
|
Antecedente: la migración a mautrix v0.28 que se barajó NO era necesaria — era un parche para
|
|
convivencia. Al quitar Matrix, el conflicto de versiones desaparece de raíz.
|
|
|
|
## Cambios
|
|
|
|
### unibus — descubrimiento de rooms (v0.4.0)
|
|
| Cambio | Archivo |
|
|
|---|---|
|
|
| `GET /members/{endpoint}/rooms` (rooms de un endpoint + rol) | `pkg/membership/server.go` |
|
|
| `Store.ListRoomsForEndpoint` (JOIN members+rooms) | `pkg/membership/store.go` |
|
|
| `client.ListMyRooms() []RoomRef` | `pkg/client/client.go` |
|
|
| Tests store + e2e cliente (descubrir room por invitación) | `pkg/membership/store_test.go`, `pkg/client/client_test.go` |
|
|
|
|
El control plane es pull (no hay push de invitaciones); un peer recién invitado a una room cifrada
|
|
la descubre por polling y luego hace `Join` + `Subscribe`.
|
|
|
|
### agents_and_robots — Matrix-out (4 commits)
|
|
| Cambio | Detalle |
|
|
|---|---|
|
|
| **Borrado** | `shell/matrix/`, `tools/matrix/`, `cmd/verify/`, `cmd/agentctl/avatar.go`, dep `maunium.net/go/mautrix` |
|
|
| **Config** | `MatrixCfg` → `BusCfg{NatsURL,CtrlURL,IdentityPath,Handle,CommandPrefix,Threads}`; loader valida `bus.*` |
|
|
| **Interfaces** | `MatrixSender` → `Sender` en `effects/runner.go`, `cron/scheduler.go`, tool |
|
|
| **Orquestador** | `shell/orchestration` despojado de mautrix (RoomScanner/scan/membership); aparcado, no se wirea |
|
|
| **Transporte** | `shell/transportunibus` pasa al módulo principal (borrado el `go.mod` anidado) y se reescribe **room-based**: descubre (`ListMyRooms` polling) → `Join`+`Subscribe`; ignora sus propios frames; `IsDirectMsg` = room de 2 miembros (GET `/rooms/{id}/members` cacheado); `IsMention` = handle en el body; `Reply` publica en la room de origen. `busSender` adapta runner/cron/tools |
|
|
| **Reconexión** | `runtime.go`/`robot.go` construyen el transport desde `BusCfg`, inyectan `busSender`, `Run` arranca `transport.Run(handleInbound)`; `sendReply` por el bus; nueva tool `bus_send` |
|
|
| **Bots** | bloque `matrix:` → `bus:` en los 5 `agents/*/config.yaml` |
|
|
|
|
## Verificación
|
|
|
|
```
|
|
# unibus (Fase 0)
|
|
$ cd projects/message_bus/apps/unibus && CGO_ENABLED=0 go test ./...
|
|
ok pkg/membership ok pkg/client ok pkg/frame
|
|
$ ./fn doctor services-spec | grep unibus # service vivo en la LAN
|
|
OK unibus systemd-user 8470 /healthz ...
|
|
$ curl -s -o /dev/null -w "%{http_code}\n" http://127.0.0.1:8470/members/x/rooms
|
|
200
|
|
|
|
# agents (Matrix-out), en master
|
|
$ go build ./... # exit 0, SIN -tags goolm
|
|
$ go vet ./... # exit 0
|
|
$ grep -rl maunium --include='*.go' . | grep -v /vendor/ # vacío
|
|
$ grep -c maunium go.mod # 0
|
|
$ go test -count=1 ./shell/transportunibus/ ./pkg/transport/
|
|
ok shell/transportunibus (2.3s) ok pkg/transport
|
|
```
|
|
|
|
Test e2e clave `TestBotEchoesInEncryptedRoom` (room-based, E2E): un peer "humano" crea room
|
|
`ModeMatrix`, invita al bot por su endpoint, publica; el bot descubre/join/subscribe, descifra y
|
|
**responde en la misma room** con ancla `ReplyTo`; el humano recibe la respuesta descifrada.
|
|
|
|
Suite completa agents: **25 paquetes ok**, 1 FAIL pre-existente ajeno (`shell/logger/TestCleanOldLogs`,
|
|
dependiente de fecha contra fixtures de marzo).
|
|
|
|
## Gaps / pendientes
|
|
|
|
1. **Directorio de bots.** El frontend/humano necesita el `EndpointID` (+ claves públicas) del bot
|
|
para invitarlo a una room cifrada. Hoy el bot lo expone (`Transport.BusEndpoint()`) y se invita
|
|
a mano; un directorio formal (registro en membershipd o subject de anuncio) es fase posterior.
|
|
2. **member-count cacheado sin invalidación**: `IsDirectMsg` se fija la primera vez por room. Si una
|
|
room de 2 crece, sigue marcada como DM. Aceptable v1 (la mención sigue disparando el LLM).
|
|
3. **Orquestador multi-bot aparcado**: el paquete compila sin mautrix pero no se wirea. Su
|
|
reimplementación sobre `GET /rooms/{id}/members` + `bus.AgentMessage` queda para después.
|
|
4. **Presencia / typing / avatars**: no existen en unibus v1 → eliminados (no-op). Features nuevas
|
|
del bus si se quieren.
|
|
5. **Smoke de launcher real**: el e2e valida transport + handler de eco; un arranque del `launcher`
|
|
con un Agent real (LLM) contra el service vivo no se ha probado (requiere config LLM + invitar al
|
|
bot). Recomendado como siguiente validación manual.
|
|
6. **Sin push**: master local en ambos repos; push vía `/full-git-push` del operador.
|
|
7. **Carrera git en unibus**: el agente de frontend trabaja en paralelo en el mismo repo unibus;
|
|
Fase 0 se consolidó vigilando HEAD. agents_and_robots es repo aparte (sin carrera).
|