Presence
OpenClaw “presence” is a lightweight, best‑effort view of:- the Gateway itself, and
- clients connected to the Gateway (mac app, WebChat, CLI, etc.)
Presence fields (what shows up)
Presence entries are structured objects with fields like:-
instanceId(optional but strongly recommended): stable client identity (usuallyconnect.client.instanceId) host: human‑friendly host nameip: best‑effort IP addressversion: client version stringdeviceFamily/modelIdentifier: hardware hints-
mode:ui,webchat,cli,backend,probe,test,node, … lastInputSeconds: “seconds since last user input” (if known)-
reason:self,connect,node-connected,periodic, … ts: last update timestamp (ms since epoch)
Producers (where presence comes from)
Presence entries are produced by multiple sources and merged.1) Gateway self entry
The Gateway always seeds a “self” entry at startup so UIs show the gateway host even before any clients connect.2) WebSocket connect
Every WS client begins with aconnect request. On successful handshake
the Gateway
upserts a presence entry for that connection.
Why one‑off CLI commands don’t show up
The CLI often connects for short, one‑off commands. To avoid spamming the Instances list,client.mode === "cli" is not turned into a presence entry.
3) system-event beacons
Clients can send richer periodic beacons via the system-event method.
The mac app
uses this to report host name, IP, and lastInputSeconds.
4) Node connects (role: node)
When a node connects over the Gateway WebSocket withrole: node, the
Gateway upserts
a presence entry for that node (same flow as other WS clients).
Merge + dedupe rules (why instanceId matters)
Presence entries are stored in a single in‑memory map:
- Entries are keyed by a presence key.
-
The best key is a stable
instanceId(fromconnect.client.instanceId) that survives restarts. - Keys are case‑insensitive.
instanceId, it may show up as a
duplicate row.
TTL and bounded size
Presence is intentionally ephemeral:- TTL: entries older than 5 minutes are pruned
- Max entries: 200 (oldest dropped first)
Remote/tunnel caveat (loopback IPs)
When a client connects over an SSH tunnel / local port forward, the Gateway may see the remote address as127.0.0.1. To avoid overwriting a good client‑reported IP, loopback remote
addresses are ignored.
Consumers
macOS Instances tab
The macOS app renders the output ofsystem-presence and applies a small
status
indicator (Active/Idle/Stale) based on the age of the last update.
Debugging tips
- To see the raw list, call
system-presenceagainst the Gateway. -
If you see duplicates:
- confirm clients send a stable
client.instanceIdin the handshake - confirm periodic beacons use the same
instanceId -
check whether the connection‑derived entry is missing
instanceId(duplicates are expected)
- confirm clients send a stable