Presencia

La “presencia” de OpenClaw es una vista ligera y de mejor esfuerzo de:

  • el Gateway en sí, y
  • los clientes conectados al Gateway (app de mac, WebChat, CLI, etc.)

La presencia se usa principalmente para renderizar la pestaña Instances de la app de macOS y para dar visibilidad rápida al operador.

Campos de presencia (qué se muestra)

Las entradas de presencia son objetos estructurados con campos como:

  • instanceId (opcional pero muy recomendado): identidad estable del cliente (normalmente connect.client.instanceId)
  • host: nombre de host legible
  • ip: dirección IP de mejor esfuerzo
  • version: cadena de versión del cliente
  • deviceFamily / modelIdentifier: pistas de hardware
  • mode: ui, webchat, cli, backend, probe, test, node, …
  • lastInputSeconds: “segundos desde la última entrada del usuario” (si se conoce)
  • reason: self, connect, node-connected, periodic, …
  • ts: marca de tiempo de la última actualización (ms desde epoch)

Productores (de dónde viene la presencia)

Las entradas de presencia se producen desde múltiples fuentes y se fusionan.

1) Entrada propia del Gateway

El Gateway siempre genera una entrada “self” al iniciar para que las UIs muestren el host del gateway incluso antes de que se conecte algún cliente.

2) Conexión WebSocket

Cada cliente WS comienza con una solicitud connect. Al completar el handshake exitosamente, el Gateway inserta o actualiza una entrada de presencia para esa conexión.

Por qué los comandos CLI puntuales no aparecen

El CLI a menudo se conecta para comandos cortos y puntuales. Para evitar llenar la lista de Instances, client.mode === "cli" no se convierte en una entrada de presencia.

3) Señales system-event

Los clientes pueden enviar señales periódicas más ricas mediante el método system-event. La app de mac usa esto para reportar nombre de host, IP y lastInputSeconds.

4) Conexiones de nodos (role: node)

Cuando un nodo se conecta al WebSocket del Gateway con role: node, el Gateway inserta o actualiza una entrada de presencia para ese nodo (mismo flujo que otros clientes WS).

Reglas de fusión + deduplicación (por qué importa instanceId)

Las entradas de presencia se almacenan en un único mapa en memoria:

  • Las entradas se indexan por una clave de presencia.
  • La mejor clave es un instanceId estable (de connect.client.instanceId) que sobrevive a reinicios.
  • Las claves no distinguen mayúsculas de minúsculas.

Si un cliente se reconecta sin un instanceId estable, puede aparecer como una fila duplicada.

TTL y tamaño limitado

La presencia es intencionalmente efímera:

  • TTL: las entradas con más de 5 minutos se eliminan
  • Máximo de entradas: 200 (las más antiguas se descartan primero)

Esto mantiene la lista actualizada y evita el crecimiento de memoria sin límite.

Advertencia de remoto/túnel (IPs de loopback)

Cuando un cliente se conecta a través de un túnel SSH / reenvío de puerto local, el Gateway puede ver la dirección remota como 127.0.0.1. Para evitar sobrescribir una buena IP reportada por el cliente, las direcciones remotas de loopback se ignoran.

Consumidores

Pestaña Instances de macOS

La app de macOS renderiza la salida de system-presence y aplica un pequeño indicador de estado (Active/Idle/Stale) basado en la antigüedad de la última actualización.

Consejos de depuración

  • Para ver la lista cruda, llama a system-presence contra el Gateway.
  • Si ves duplicados:
    • confirma que los clientes envían un client.instanceId estable en el handshake
    • confirma que las señales periódicas usan el mismo instanceId
    • verifica si la entrada derivada de la conexión no tiene instanceId (los duplicados son esperados)