- app.md Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5.5 KiB
name, lang, domain, version, description, tags, uses_functions, uses_types, framework, entry_point, dir_path, repo_url, e2e_checks
| name | lang | domain | version | description | tags | uses_functions | uses_types | framework | entry_point | dir_path | repo_url | e2e_checks | ||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| unibots | go | infra | 0.1.0 | Plataforma de bots que consumen el bus unibus; primer bot = eco (bot sin LLM que demuestra los dos patrones de conversación del bus). |
|
cmd/echobot | projects/message_bus/apps/unibots | https://gitea-dgg044oo04woo4ggcsws4gk0.organic-machine.com/dataforge/unibots |
|
Qué es
unibots es la plataforma de bots que consumen el bus de mensajería
unibus. Un bot es todo peer automatizado del bus, con o sin
LLM. Un bot agente es un bot que contiene un LLM (no aplica todavía aquí). El
término único en código, nombres y docs es bot.
El primer bot es el bot eco (cmd/echobot): un bot sin LLM que se une al
bus y devuelve cada mensaje prefijado con "echo: ". Existe para demostrar de
forma autónoma los dos patrones de conversación que el bus expone, sin
depender de ningún modelo:
| Patrón | Subject | Cómo | Pareja |
|---|---|---|---|
| Chat (bot↔humano) | room.echo (cleartext, room.ModeNATS) |
Subscribe a la room + Publish la respuesta |
cualquier peer en el mismo subject |
| RPC (bot↔proceso) | rpc.echo |
request/reply de NATS (Client.Reply registra el responder) |
cualquier proceso que haga Client.Request |
unibots es código de aplicación, no funciones del registry: orquesta la
librería cliente de unibus (pkg/client) y no reimplementa nada. Por eso
uses_functions está vacío — el crypto/transporte lo aporta unibus, que a su
vez importa las primitivas del registry.
Referencia: convencion-bot-vs-agente. Consumidor de unibus.
Ejemplo
Lanzar el echobot contra un membershipd corriendo (NATS embebido en :4250,
HTTP en :8470, los defaults productivos de unibus):
cd projects/message_bus/apps/unibus
# 1. Bus de membresía/claves (NATS embebido + control plane HTTP)
go run ./cmd/membershipd
# 2. En otra terminal: el bot eco (defaults: nats://127.0.0.1:4250, http://127.0.0.1:8470)
cd ../unibots
go run ./cmd/echobot
# Loguea al arrancar: endpoint id, subjects de chat y rpc, y a qué bus apunta.
Probarlo desde otra terminal sin escribir más Go:
# Modo RPC (bot<->proceso) con la CLI de NATS contra el mismo NATS embebido:
# nats --server nats://127.0.0.1:4250 request rpc.echo "ping"
# -> recibe "echo: ping"
# Modo chat (bot<->humano): cualquier peer que publique en el subject room.echo
# (p.ej. el `chat` de unibus apuntando a ese subject, o un cliente propio) recibe
# de vuelta "echo: <su mensaje>".
Apuntar a un bus distinto:
go run ./cmd/echobot \
--nats-url nats://mi-host:4222 \
--ctrl-url http://mi-host:8470 \
--room-subject room.demo \
--rpc-subject rpc.demo
Cuando usarla
- Cuando quieras validar que un bus unibus está vivo end-to-end (chat y RPC) sin montar un bot agente con LLM.
- Como plantilla mínima para escribir un bot nuevo: copia
cmd/echobot, cambia la lógica del handler (en vez de"echo: " + body, llama a tu servicio, base de datos o, más adelante, a un LLM para convertirlo en bot agente). - Para demostrar los dos patrones del bus (chat por room cleartext vs RPC request/reply) a alguien que aprende la arquitectura.
Gotchas
- Guard anti-bucle (crítico). El handler de chat ignora los mensajes cuyo
frame.Frame.Sender == c.Endpoint().ID. Sin este guard, el bot se haría eco de su propio"echo: ..."indefinidamente (y dos echobots en el mismo subject entrarían en un bucle infinito). El testTestChatEchoverifica que nunca aparece"echo: echo: hola". - Cleartext comparte subject, no room id. El bot usa
room.ModeNATS(cleartext, efímero, sin firma). NATS enruta por subject, así que el bot conversa con cualquier peer en el mismo subject aunque cada uno tenga su propioroom_id(mismo patrón que el worker/chat de unibus). No hay "unirse a una room por nombre": cadaCreateRoomproduce un ULID nuevo mapeado al subject. - Modo RPC sí está soportado. La librería de unibus expone request/reply:
Client.Request(subject, body, timeout)yClient.Reply(subject, handler)(cleartext v1, sobrerpc.*). El echobot registra un responder conReply. No hubo que omitir ni inventar nada en unibus. - Identidad = secreto crítico.
local_files/echobot.idcontiene las claves privadas (Ed25519 + X25519), se escribe 0600. Perderlo no rompe el eco (es cleartext) pero cambia la identidad del bot. Está gitignorado. - Build sin CGO. Igual que unibus:
CGO_ENABLED=0, sinfts5nigcc. El crypto del registry (cybersecurity) y el driver SQLite pure-Go compilan limpio. - Los tests usan puertos propios aislados. El test de integración levanta un
membershipdcon NATS embebido en puertos libres (:0) bajot.TempDir(), nunca en8470/4250ni en los del playground del usuario; todo se limpia por handle víat.Cleanup.
Convención de subjects (heredada de unibus)
proc.<svc>.<canal> telemetría/coordinación de procesos
rpc.<svc> request/reply (rpc.echo)
room.<grupo> chat humano/grupo (room.echo)
agent.<nombre>.{in,out} inbox/outbox de bot agente (futuro)