プレゼンス
OpenClawの「プレゼンス」は、以下の軽量なベストエフォート型ビューです:
- Gateway自体
- Gatewayに接続しているクライアント(macアプリ、WebChat、CLIなど)
主にmacOSアプリのインスタンスタブの表示や、運用者がすばやく状況を把握するために使われます。
プレゼンスのフィールド(表示内容)
プレゼンスエントリは以下のようなフィールドを持つ構造化オブジェクトです:
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:最終更新タイムスタンプ(エポックからのミリ秒)
プロデューサー(プレゼンスの発生源)
プレゼンスエントリは複数のソースから生成され、マージされます。
1)Gatewayのselfエントリ
Gatewayは起動時に必ず「self」エントリをシードするため、クライアントが接続する前でもUIにゲートウェイホストが表示されます。
2)WebSocket接続
すべてのWSクライアントはconnectリクエストから始まります。ハンドシェイクが成功すると、Gatewayはその接続のプレゼンスエントリをアップサートします。
単発CLIコマンドが表示されない理由
CLIは短時間の単発コマンドで接続することが多いため、インスタンス一覧がスパムされるのを避けるため、client.mode === "cli"の場合はプレゼンスエントリに変換されません。
3)system-eventビーコン
クライアントはsystem-eventメソッドを通じて、より詳細な定期ビーコンを送信できます。macアプリはこれを利用してホスト名、IP、lastInputSecondsを報告しています。
4)ノード接続(role: node)
ノードがrole: nodeでGateway WebSocketに接続すると、Gatewayはそのノードのプレゼンスエントリをアップサートします(他のWSクライアントと同じフロー)。
マージと重複排除のルール(instanceIdが重要な理由)
プレゼンスエントリは単一のインメモリマップに保存されます:
- エントリはプレゼンスキーでキーイングされる
- 最適なキーは、再起動しても維持される安定した
instanceId(connect.client.instanceIdから取得) - キーは大文字小文字を区別しない
安定したinstanceIdなしでクライアントが再接続すると、重複行として表示される場合があります。
TTLとサイズ上限
プレゼンスは意図的に一時的なものです:
- TTL: 5分以上前のエントリは削除される
- 最大エントリ数: 200(古い順に削除)
これにより一覧が常に最新に保たれ、メモリが無制限に増加するのを防ぎます。
リモート/トンネル接続時の注意(ループバックIP)
クライアントがSSHトンネルやローカルポートフォワーディング経由で接続すると、Gatewayにはリモートアドレスが127.0.0.1として見える場合があります。クライアントが報告した正しいIPを上書きしないよう、ループバックのリモートアドレスは無視されます。
コンシューマー
macOSインスタンスタブ
macOSアプリはsystem-presenceの出力をレンダリングし、最終更新からの経過時間に基づいて小さなステータスインジケーター(Active/Idle/Stale)を表示します。
デバッグのヒント
- 生データを確認するには、Gatewayに対して
system-presenceを呼び出してください。 - 重複が表示される場合:
- クライアントがハンドシェイクで安定した
client.instanceIdを送信しているか確認 - 定期ビーコンが同じ
instanceIdを使っているか確認 - 接続由来のエントリに
instanceIdがない場合は重複が想定される動作
- クライアントがハンドシェイクで安定した