Sessions and memory

세션 상태 인식

여러 세션이 동일한 문제를 함께 처리할 때(관리자가 하위 에이전트에게 위임하거나, 사람이 작업자 세션에 직접 개입하거나, 두 에이전트가 sessions_send를 통해 조율하는 경우) 각 세션은 다른 세션에 대한 가정을 형성합니다. 다른 행위자가 개입하는 순간 이러한 가정은 최신 상태가 아니게 됩니다. 세션 상태 인식은 이러한 개입을 감지하고, 영향을 받는 세션에 한 번 알리며, 해당 세션이 작업하기 전에 적은 비용으로 변경 사항을 파악할 수 있게 하는 메커니즘입니다.

다음 세 가지 요소가 함께 작동합니다.

  1. 내구성 있는 신호 로그는 세션별로 선별된 상태 변경을 기록합니다.
  2. 감시자는 대상별 커서를 유지하고 병합된 오래된 상태 알림을 한 번 받습니다.
  3. 조정changesSince를 지정한 session_status를 통해 정확한 변경분을 가져옵니다.

신호 로그

감시 중인 세션이 실질적으로 변경되면 OpenClaw는 공유 상태 데이터베이스(session_state_events)에 형식이 지정된 이벤트를 추가합니다. 이벤트에는 메타데이터와 한 줄 요약이 포함되며, 메시지 내용은 절대 포함되지 않습니다.

종류 기록 시점 감시자에게 알림
human_direct_message 사람이 감시 중인 세션에 직접 턴을 전송할 때
goal_changed 세션의 목표 상태가 생성, 업데이트 또는 삭제될 때
child_spawned 하위 에이전트 또는 ACP 하위 세션이 생성될 때 아니요(커서 초기화)
run_completed 하위 실행이 성공적으로 종료될 때 아니요(로그만 기록)
run_failed 하위 실행이 실패하거나 시간 초과 또는 취소될 때 아니요(로그만 기록)
compacted 세션 기록이 Compaction될 때 아니요(로그만 기록)

각 이벤트에는 행위자(human, agent 또는 system)가 명시됩니다. 취소되거나 시간 초과된 하위 실행은 실패로 기록되며, 정확한 결과(cancelled, timeout 또는 error)가 이벤트 페이로드에 보존됩니다.

세션의 상태 버전은 로그에서 가장 높은 시퀀스 번호이며, 정리 후에도 유지되는 내구성 있는 세션별 헤드에서 추적됩니다. 변경 사항이 기록된 세션의 sessions_list 행에는 stateVersion이 포함되며, session_status는 항상 이를 보고합니다.

로그 전용 종류는 알림이 아니라 조정 기록을 위해 존재합니다. 일반적인 하위 실행 완료 전달은 계속 하위 에이전트 알림이 담당하며, 신호 로그는 이를 절대 중복하지 않습니다.

감시자

감시자는 대상에 대한 커서(session_watch_cursors)를 보유한 세션입니다. 커서는 다음 두 경로로 생성됩니다.

  • 암시적(생성 연결). 세션이 하위 에이전트 또는 ACP 하위 세션을 생성하면 상위 세션의 커서가 하위 세션의 생성 버전으로 자동 초기화됩니다. 상위 세션은 수동으로 구독할 필요가 없습니다.
  • 명시적(sessions_send watch: true). 모든 조정자는 생성 관계가 없는 대상을 감시할 수 있습니다. sessions_sendwatch: true를 전달하면 전송이 성공적으로 디스패치된 후 발신자가 실제로 메시지를 받은 세션의 감시자로 등록됩니다. 등록은 대상의 현재 상태 버전에서 시작하므로 이전 기록은 알림을 생성하지 않습니다. 매개변수가 설정된 경우 도구 결과에 watched: true|false가 표시됩니다.

감시자의 ID는 에이전트로 한정된 세션 키여야 합니다. session.scope="global"에서는 공유 global 키가 여러 에이전트에 걸쳐 모호하므로, 이러한 세션에는 내구성 있는 로그와 changesSince가 제공되지만 선제적 알림은 제공되지 않습니다.

감시는 자동으로 정리됩니다. 커서 행은 신호 로그의 보존 기간에 맞춰 만료되고, 감시자 세션이 재설정되면 제거되며, 어느 한쪽 세션이 삭제되면 함께 삭제됩니다. v1에는 감시 해제 동작이 없습니다.

알림: 여러 번이 아닌 한 번만

알림 대상 이벤트가 발생하고 감시자의 커서가 뒤처져 있으면, 감시자는 다음 턴에 시스템 알림을 한 번 받습니다.

Code
세션 "agent:main:subagent:child"이(가) 변경되었습니다(다른 행위자). 작업하기 전에 조정하십시오: session_status sessionKey "agent:main:subagent:child" changesSince 12.

기본 세션 감시자는 Heartbeat 깨우기를 통해 즉시 활성화되며, 중첩된 하위 에이전트 감시자는 다음 턴에 알림을 받습니다.

이 프로토콜은 의도적으로 과도한 알림을 방지하도록 설계되었습니다.

  • 감시자/대상 쌍당 대기 중인 알림 하나. 대기 중에는 알림 텍스트가 바이트 단위로 동일하게 유지되고 시스템 이벤트 대기열이 이를 중복 제거하므로, 같은 대상에 빠르게 20개의 변경이 발생하더라도 감시자의 프롬프트에는 한 줄만 생성됩니다.
  • 고정된 워터마크. 알림이 대기열에 추가되면 커서가 알림 위치를 고정합니다. 이후 발생하는 실질적 이벤트는 실질적 워터마크만 진행시키며 다시 알리지 않습니다.
  • 소진 시 확인하며, 중간에 작업이 발생한 경우에만 다시 엽니다. 감시자의 턴이 알림을 소비하면 커서가 진행됩니다. 대기열 추가와 소비 사이에 추가적인 실질적 이벤트가 도착했다면 나머지에 대해 새로운 알림이 정확히 하나 열립니다.
  • 자체 억제. 감시자는 자신이 발생시킨 이벤트에 대한 알림을 받지 않습니다.
  • 재시작 복구. 대기 중인 알림은 메모리 내 대기열에 저장됩니다. Gateway가 재시작되면 시작 시 검사가 내구성 있는 커서에서 알림을 다시 구체화합니다.

조정

알림은 감시자가 수행해야 할 작업을 정확히 알려 줍니다. changesSince: <version>을 지정한 session_status는 커서를 진행시키지 않고 해당 버전 이후의 형식이 지정된 이벤트를 최대 200개까지 반환합니다.

json
{  "stateVersion": 19,  "stateChanges": {    "events": [      {        "sequence": 14,        "kind": "human_direct_message",        "actorType": "human",        "summary": "Telegram을 통한 사람의 메시지"      },      { "sequence": 19, "kind": "goal_changed", "actorType": "human", "summary": "목표 업데이트됨" }    ],    "historyGap": false  }}

historyGap: true는 요청한 버전이 보존된 기록보다 오래되었음을 의미합니다. 응답을 정확한 변경분으로 취급하지 말고 전체 세션 상태(sessions_history, session_status)를 새로 고치십시오. 간격 신호는 정확합니다. 시퀀스 산술로 추론하지 않고 세션별 정리 워터마크에서 가져옵니다.

저장소 및 제한

기록은 공유 상태 데이터베이스에 저장되며, 30일 및 50,000행으로 제한됩니다. 세션별 헤드는 정리 후에도 단조 증가를 유지합니다. 기록은 최선형으로 수행됩니다. 추가 작업이 실패하면 로그에 남지만 원래 턴을 실패시키지는 않습니다. 따라서 stateVersion은 트랜잭션 변경 데이터 캡처 버전이 아니라 신호 로그의 헤드입니다.

현재 제한 사항은 다음과 같습니다.

  • 알림 전달은 하나의 Gateway 프로세스가 공유 상태 데이터베이스를 소유한다고 가정합니다. 여러 Gateway가 내구성 있는 로그와 changesSince를 공유할 수 있지만, v1은 프로세스 간에 알림을 푸시하지 않습니다.
  • Compaction 이벤트는 내장 런타임의 Compaction 소유자를 포함하지만, 네이티브 하니스 전용 Compaction은 완전히 기록되지 않습니다.
  • 취소 결과의 상세 페이로드는 현재 ACP 하위 실행에서 생성됩니다. 네이티브 하위 에이전트의 취소는 일반적인 실패로 표시됩니다.

관련 문서

Was this useful?
On this page

On this page