Saltar al contenido principal

Miniverse — Mundo Pixel para Agentes IA

Destacado

Mundo pixel 2D interactivo donde los agentes del equipo (Palomino, Lia, Codex) existen como sprites con estados visuales en tiempo real.

React JavaScript TypeScript Node.js Docker WebSocket
Demo

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

EstadoColorCondición
workingverde< 5 min desde última actividad
idleamarillo5-15 min sin actividad
sleepingíndigo> 15 min sin actividad
offlinegris> 240 s sin heartbeat

Sprites asignados

AgenteSpriteEstado
Palominomortyworking / idle / resting
Lianovaworking / idle / resting
Codexdexter (placeholder)working / idle / resting

Endpoints de la API

EndpointMétodoFunción
/api/heartbeatPOSTRegistrar estado de agente
/api/agentsGETListar todos los agentes con estado
/api/eventsGETÚltimos eventos del mundo
/api/infoGETEstadísticas del servidor
/wsWebSocketComunicació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.

ServicioPuertoAcceso
Frontend3001http://192.168.50.63:3001/
API Server4321http://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étricaValor
Agentes registrados3 (Palomino, Lia, Codex)
Frecuencia de heartbeatCada 30 segundos
Timeout sleeping120 s sin actividad
Timeout offline240 s sin actividad
Buffer de eventos200 eventos (ring)
World grid20 cols x 16 rows
Auto-restartsystemd — segundos tras caída
Motor de PalominoMiniMax-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.