Miniverse — Mundo Pixel para Agentes IA
DestacadoMundo pixel 2D interactivo donde los agentes del equipo (Palomino, Lia, Codex) existen como sprites con estados visuales en tiempo real.
El problema
El equipo de agentes IA (Palomino, Lia, Codex) trabaja de forma autónoma, pero no hay una forma visual de saber quién está haciendo qué. Para saber si un agente está trabajando, ocioso, o ha fallado, hay que revisar logs o hacer SSH a las máquinas. Con tres agentes ejecutándose en paralelo, eso no escala.
Necesitaba un panel que respondiera instantáneamente a: ¿Quién está activo ahora? ¿Qué está haciendo? ¿Lleva mucho tiempo sin responder?
La decisión — un mundo pixel 2D
En lugar de un dashboard tradicional con tablas y gráficos, decidí darle una personalidad visual al equipo. Un mundo pixel 2D donde cada agente existe como un sprite con estados que cambian en tiempo real. No es decoración — es la interfaz principal de monitorización del equipo.
La idea: si Palomino está trabajando, su sprite (morty) se ve activo. Si está idle, cambia a reposo. Si lleva más de 15 minutos sin actividad, pasa a durmiendo. Todo visible de un vistazo.
Implementación
Arquitectura
El sistema tiene dos componentes conectados:
- API Server (Node.js, puerto 4321): recibe heartbeats de los agentes vía REST, gestiona el estado, y lo sirve a los clientes
- Frontend (React + Vite, puerto 3001): renderiza el mundo pixel con los sprites y sus estados
Los agentes reportan su estado mediante un script heartbeat que se ejecuta cada 30 segundos vía cron, enviando un POST a /api/heartbeat con su ID, estado, y tarea actual.
Estados de agente
| Estado | Color | Condición |
|---|---|---|
| working | verde | < 5 min desde última actividad |
| idle | amarillo | 5-15 min sin actividad |
| sleeping | índigo | > 15 min sin actividad |
| offline | gris | > 240 s sin heartbeat |
Sprites asignados
| Agente | Sprite | Estado |
|---|---|---|
| Palomino | morty | working / idle / resting |
| Lia | nova | working / idle / resting |
| Codex | dexter (placeholder) | working / idle / resting |
Endpoints de la API
| Endpoint | Método | Función |
|---|---|---|
/api/heartbeat | POST | Registrar estado de agente |
/api/agents | GET | Listar todos los agentes con estado |
/api/events | GET | Últimos eventos del mundo |
/api/info | GET | Estadísticas del servidor |
/ws | WebSocket | Comunicación bidireccional en tiempo real |
Heartbeat
Cada 30 segundos, los agentes ejecutan un script que envía su estado al servidor:
* * * * * /opt/miniverse/my-miniverse/heartbeat-smart-v7.sh
* * * * * sleep 30; /opt/miniverse/my-miniverse/heartbeat-smart-v7.sh
El servidor tiene un AgentStore que hace sweep cada 5 segundos. Si un agente no envía heartbeat durante 120 segundos, pasa a sleeping. Tras 240 segundos, a offline.
Infraestructura
Miniverse no es un proyecto aislado. Está montado sobre la infraestructura del homelab y conectado al sistema de agentes real.
Dónde corre
El servidor y el frontend viven en la VM palomino-dopado (ID 108), dentro del host Proxmox luffy (192.168.50.2). La VM tiene 10 GB de RAM y corre Debian 13. Ambos servicios están gestionados por systemd con auto-restart — si el proceso cae, systemd lo levanta en segundos sin intervención manual.
| Servicio | Puerto | Acceso |
|---|---|---|
| Frontend | 3001 | http://192.168.50.63:3001/ |
| API Server | 4321 | http://192.168.50.63:4321/api/ |
El equipo de agentes
Palomino, el agente principal de infraestructura, corre sobre OpenClaw Gateway en la misma VM. Su motor principal es MiniMax-M2.7 (plan Plus, conexión directa, contexto 1M tokens). OpenClaw gestiona el routing de sesiones, el sistema de memoria LanceDB, y la ejecución de skills. Palomino no es un chatbot — es un operador digital que arranca VMs, monitoriza servicios, diagnostica problemas, y coordina al resto del equipo.
Lia corre en un VPS independiente (Oracle Cloud, Ampere A1). Codex también opera desde su propio entorno. Los tres son autónomos y asíncronos.
Cómo se comunican los agentes
Los agentes no se hablan directamente. Usan un sistema de buzones compartidos montado en el NAS Synology (192.168.50.10), accesible mediante montura CIFS a través de Tailscale. Cada agente escribe mensajes JSON en su directorio de salida y el otro agente los recoge por polling cada ~30-60 segundos.
Palomino → /mnt/nas_cifs/lia/from_palomino/ → Lia
Lia → /mnt/nas_cifs/from_lia/ → Palomino
Codex → /mnt/nas_cifs/lia/from_codex/ → Lia
Palomino → /mnt/nas_cifs/codex/from_palomino/ → Codex
Los heartbeats específicos de Miniverse son independientes de este sistema de mensajería. Van directos al API server del mundo pixel, no pasan por el NAS.
Pipeline completo
Agente (Palomino/Lia/Codex)
→ cron cada 30s ejecuta heartbeat-smart-v7.sh
→ POST /api/heartbeat { agentId, status, task }
→ API Server actualiza AgentStore (in-memory, sweep cada 5s)
→ Frontend polling GET /api/agents
→ Sprite cambia de estado en el mundo 2D
Métricas
| Métrica | Valor |
|---|---|
| Agentes registrados | 3 (Palomino, Lia, Codex) |
| Frecuencia de heartbeat | Cada 30 segundos |
| Timeout sleeping | 120 s sin actividad |
| Timeout offline | 240 s sin actividad |
| Buffer de eventos | 200 eventos (ring) |
| World grid | 20 cols x 16 rows |
| Auto-restart | systemd — segundos tras caída |
| Motor de Palomino | MiniMax-M2.7 via OpenClaw Gateway |
Qué cambiaría
WebSocket en lugar de polling. El frontend actual usa REST polling para obtener el estado de los agentes. No es crítico para 3 agentes, pero para actualización en tiempo real habría debido implementar WebSocket desde el principio. El servidor ya lo soporta — el frontend no lo consume. El Gateway de OpenClaw sí usa WebSocket para su control plane; esta misma aproximación debería aplicarse al mundo pixel.
Sprites personalizados en lugar de placeholders. Codex usa dexter como sprite placeholder porque no tiene uno propio. Los sprites personalizados de Palomino y Lia (morty, nova) funcionan bien, pero el del tercer agente está pendiente desde el inicio.
Header y branding de la UI. El frontend sigue teniendo aspecto de demo. Sin cabecera, sin logo, sin identidad visual propia. Funciona, pero no está terminado. Lo puse en funcionamiento para que el equipo tuviera visibilidad y no volví a tocarlo.
Documentar la instalación desde el día uno. El sistema está montado a mano sobre systemd, con scripts en /opt/miniverse/ y dependencias instaladas ad-hoc. Si mañana tengo que replicar la VM, tendría que reconstruir la configuración de memoria. Una skill de instalación automatizada para OpenClaw sería lo correcto.