Presence
OpenClawの「presence」は、以下を対象とした軽量でベストエフォートなビューです。- Gateway 自体
- Gatewayに接続しているクライアント(mac app、WebChat、CLIなど)
Presenceフィールド(表示されるもの)
presenceエントリは、次のようなフィールドを持つ構造化オブジェクトです。instanceId(任意ですが強く推奨): 安定したクライアント識別子(通常はconnect.client.instanceId)host: 人が読みやすいホスト名ip: ベストエフォートなIPアドレスversion: クライアントのバージョン文字列deviceFamily/modelIdentifier: ハードウェアのヒントmode:ui,webchat,cli,backend,probe,test,node, …lastInputSeconds: 「最後のユーザー入力からの秒数」(分かっている場合)reason:self,connect,node-connected,periodic, …ts: 最終更新タイムスタンプ(epochからのミリ秒)
Producers(presenceの生成元)
presenceエントリは複数のソースから生成され、マージされます。1) Gateway自身のエントリ
Gatewayは起動時に常に「self」エントリを初期投入するため、クライアントがまだ接続していない段階でもUIにgateway hostが表示されます。2) WebSocket接続
すべてのWSクライアントはconnect リクエストで開始します。ハンドシェイクが成功すると、
Gatewayはその接続に対するpresenceエントリをupsertします。
単発のCLIコマンドが表示されない理由
CLIは短時間の単発コマンドのために接続することがよくあります。Instancesリストが 過剰に埋まるのを防ぐため、client.mode === "cli" はpresenceエントリには変換されません。
3) system-event ビーコン
クライアントは system-event メソッドを通じて、より詳細な定期ビーコンを送信できます。mac
appはこれを使って、ホスト名、IP、lastInputSeconds を報告します。
4) ノード接続(role: node)
ノードがrole: node でGateway WebSocket経由で接続すると、Gatewayはそのノードのpresenceエントリをupsertします
(他のWSクライアントと同じフローです)。
マージ + 重複排除ルール(instanceId が重要な理由)
presenceエントリは、単一のインメモリマップに保存されます。
- エントリはpresence keyでキー付けされます。
- 最適なキーは、再起動後も維持される安定した
instanceId(connect.client.instanceId由来)です。 - キーは大文字小文字を区別しません。
instanceId なしで再接続すると、
重複した行として表示される場合があります。
TTLと件数上限
presenceは意図的に一時的なものです。- TTL: 5分より古いエントリは削除されます
- 最大エントリ数: 200(最も古いものから先に削除)
リモート/トンネル時の注意点(ループバックIP)
クライアントがSSHトンネル / ローカルポートフォワード経由で接続すると、Gatewayは リモートアドレスを127.0.0.1 として見ることがあります。良好なクライアント報告IPを上書きしないように、
ループバックのリモートアドレスは無視されます。
Consumers
macOS Instancesタブ
macOS appはsystem-presence の出力を描画し、最終更新の経過時間に基づいて
小さなステータス表示(Active/Idle/Stale)を適用します。
デバッグのヒント
- 生の一覧を見るには、Gatewayに対して
system-presenceを呼び出します。 - 重複が見える場合:
- クライアントがハンドシェイクで安定した
client.instanceIdを送信していることを確認してください - 定期ビーコンが同じ
instanceIdを使っていることを確認してください - 接続由来のエントリに
instanceIdが欠けていないか確認してください(その場合、重複は想定内です)
- クライアントがハンドシェイクで安定した