메인 콘텐츠로 건너뛰기

Presence

OpenClaw “존재”는 다음과 같은 가벼운 최선의 노력을 위한 뷰입니다:
  • 게이트웨이 자체, 그리고
  • 게이트웨이에 연결된 클라이언트들 (mac 앱, WebChat, CLI 등)
존재는 주로 macOS 앱의 인스턴스 탭을 렌더링하고 신속한 운영자 가시성을 제공하는 데 사용됩니다.

존재 필드 (표시 항목)

존재 항목은 다음과 같은 필드를 가진 구조화된 객체입니다:
  • instanceId (선택 사항이지만 강력 추천): 안정적인 클라이언트 ID (일반적으로 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: 마지막 업데이트 타임스탬프 (에포크 이후 ms)

생성자 (존재가 오는 곳)

존재 항목은 여러 소스에서 생성되며 병합됩니다.

1) 게이트웨이 자체 항목

게이트웨이는 클라이언트가 연결되기 전에도 게이트웨이 호스트를 UI에 표시하기 위해 항상 시작 시 “자체” 항목을 시딩합니다.

2) WebSocket 연결

모든 WS 클라이언트는 connect 요청으로 시작합니다. 핸드셰이크가 성공적으로 이루어지면 게이트웨이는 해당 연결에 대한 존재 항목을 upsert 합니다.

왜 단발성 CLI 명령어가 표시되지 않는가

CLI는 종종 짧고 단발성인 명령어를 위해 연결됩니다. 인스턴스 목록을 스팸화하지 않기 위해 client.mode === "cli"는 존재 항목으로 변환되지 않습니다.

3) system-event 비콘

클라이언트는 system-event 메소드를 통해 더욱 풍부한 주기적 비콘을 전송할 수 있습니다. mac 앱은 이를 사용하여 호스트 이름, IP, lastInputSeconds를 보고합니다.

4) 노드 연결 (역할: 노드)

노드가 게이트웨이 WebSocket을 통해 role: node로 연결될 때, 게이트웨이는 해당 노드에 대한 존재 항목을 upsert 합니다 (다른 WS 클라이언트와 같은 흐름).

병합 + 중복 제거 규칙 (instanceId가 중요한 이유)

존재 항목은 단일 메모리 내 지도에 저장됩니다:
  • 항목은 존재 키로 키가 지정됩니다.
  • 최고의 키는 재시작 후에도 살아남는 안정적인 instanceId (connect.client.instanceId에서 가져옴)입니다.
  • 키는 대소문자를 구분하지 않습니다.
클라이언트가 안정적인 instanceId 없이 재연결하면 중복 행으로 나타날 수 있습니다.

TTL 및 제한된 크기

존재는 의도적으로 일시적입니다:
  • TTL: 5분을 지난 항목은 정리됩니다.
  • 최대 항목: 200 (가장 오래된 항목부터 삭제)
이는 목록이 신선하게 유지되고 메모리가 무한정 늘어나는 것을 방지합니다.

원격/터널 주의사항 (루프백 IP)

클라이언트가 SSH 터널 / 로컬 포트 포워드를 통해 연결될 경우, 게이트웨이는 원격 주소를 127.0.0.1로 볼 수 있습니다. 좋은 클라이언트 보고 IP를 덮어쓰지 않기 위해 루프백 원격 주소는 무시됩니다.

소비자

macOS 인스턴스 탭

macOS 앱은 system-presence의 출력을 렌더링하고 마지막 업데이트의 연령에 따라 작은 상태 표시기 (활성/대기/오래됨)를 적용합니다.

디버깅 팁

  • 원시 목록을 보려면 게이트웨이에 대해 system-presence를 호출하세요.
  • 중복 항목을 보면:
    • 클라이언트가 핸드셰이크에서 안정적인 client.instanceId를 전송하는지 확인하세요.
    • 주기적 비콘이 동일한 instanceId를 사용하는지 확인하세요.
    • 연결 소스로 유도된 항목에 instanceId가 누락되어 있는지 확인하세요 (중복이 예상 됩니다).