30.2 在线追踪

生成模型:Claude Opus 4.6 (anthropic/claude-opus-4-6) Token 消耗:输入 ~260k tokens,输出 ~5k tokens(本节)


在多设备环境中,用户需要知道哪些设备正在连接、它们的状态如何。OpenClaw 的 System Presence(系统在线追踪)机制记录所有连接的设备信息,并实时同步到所有客户端。

30.2.1 Presence 数据结构

每个在线设备对应一条 SystemPresence 记录(src/infra/system-presence.ts):

export type SystemPresence = {
  host?: string;              // 主机名
  ip?: string;                // IP 地址
  version?: string;           // OpenClaw 版本
  platform?: string;          // 平台信息(如 "macos 15.2")
  deviceFamily?: string;      // 设备族(Mac / Linux / Windows)
  modelIdentifier?: string;   // 硬件型号(如 "Mac16,10")
  lastInputSeconds?: number;  // 最后输入时间(秒前)
  mode?: string;              // 运行模式(gateway / node / cli)
  reason?: string;            // 连接原因(self / heartbeat / connect)
  deviceId?: string;          // 设备唯一标识
  roles?: string[];           // 角色列表(operator / node)
  scopes?: string[];          // 权限作用域
  instanceId?: string;        // 实例 UUID
  text: string;               // 人类可读的摘要文本
  ts: number;                 // 最后更新时间戳
};

自身 Presence 初始化

Gateway 启动时立即调用 initSelfPresence() 注册自身:

注意这里用了同步的 spawnSync("sysctl", ...)——这是因为 initSelfPresence() 在模块加载时执行(顶层调用),此时异步 API 会增加不必要的复杂性。而且 sysctl 的执行时间通常在 1 毫秒以内。

30.2.2 Presence 存储与过期

Presence 数据存储在模块级的 Map<string, SystemPresence> 中:

listSystemPresence() 在返回数据前执行两项清理:

  1. TTL 过期清理:删除超过 5 分钟未更新的记录

  2. 容量限制:如果记录数超过 200,按时间戳排序删除最旧的记录(LRU 策略)

衍生解释:LRU(Least Recently Used)是一种缓存淘汰策略。当缓存满时,优先淘汰最久未被访问的数据。这里的 Presence Map 本质上就是一个 LRU 缓存——超过容量时删除 ts 最小(最久未更新)的记录。

30.2.3 Presence 更新

当客户端(CLI、macOS 应用、iOS/Android 节点)连接或发送心跳时,Gateway 调用 updateSystemPresence() 更新 Presence:

合并策略遵循"新值优先"原则:payload(最新的客户端数据) > parsed(从 text 解析的数据) > existing(已有记录)。角色和作用域列表使用集合合并(mergeStringList),避免重复项。

文本解析

客户端发送的 Presence 数据包含一个人类可读的 text 字段,格式为:

parsePresence() 使用正则表达式从这个文本中提取结构化字段,这是一种兼容性设计——即使客户端只发送 text 字段而没有结构化数据,Gateway 也能解析出关键信息。

30.2.4 Presence 版本与广播

Presence 变更会触发版本号递增和实时广播:

Gateway 在以下时机广播 Presence 更新:

  1. 新客户端连接

  2. 客户端断开

  3. 心跳更新

  4. 设备配对/取消配对

客户端(如 Web 控制台)收到 Presence 更新后,可以实时显示在线设备列表、打字指示器等 UI 元素。

30.2.5 打字指示器

衍生解释:打字指示器(Typing Indicator)是即时通讯中常见的功能——当对方正在输入消息时,显示"正在输入…"的提示。在 OpenClaw 中,打字指示器的含义更广泛:它不仅包括用户正在输入,还包括 Agent 正在"思考"(调用 LLM API)和正在输出流式响应。

OpenClaw 的打字指示器通过 Presence 系统实现。当 Agent 开始处理用户消息时,Gateway 会向所有客户端广播 mode 变更:

Web 控制台和原生客户端监听这些 mode 变化来显示相应的 UI 状态(如三点动画、进度指示器等)。


本节小结

  1. SystemPresence 记录每个连接设备的详细信息:主机名、IP、平台、硬件型号、运行模式、版本等。Gateway 启动时自动注册自身。

  2. TTL + LRU 双重机制控制 Presence 数据的生命周期:5 分钟过期自动清除,超过 200 条时淘汰最旧记录。

  3. Presence 更新采用"新值优先"的合并策略,Key 选择支持 deviceId、instanceId、host 多级回退,确保同一设备的记录不会重复。

  4. 版本号广播让客户端能以最小开销感知 Presence 变更——只需比较一个整数即可判断是否需要拉取最新数据。

  5. 打字指示器基于 Presence 的 mode 字段实现,覆盖了 idle/thinking/writing/tool 四种状态。

Last updated