Sessions and memory
세션 상태 인식
여러 세션이 같은 문제를 처리할 때(관리자가 하위 세션에 위임하거나, 사람이 작업자 세션에 직접 개입하거나, 두 에이전트가 sessions_send을 통해 조율하는 경우) 각 세션은 다른 세션에 대한 가정을 형성합니다. 다른 행위자가 개입하는 순간 이러한 가정은 오래된 정보가 됩니다. 세션 상태 인식은 개입을 감지하고, 영향을 받는 세션에 한 번 알리며, 해당 세션이 행동하기 전에 적은 비용으로 최신 상태를 파악할 수 있게 하는 메커니즘입니다.
세 가지 요소가 함께 작동합니다.
- 내구성 있는 신호 로그는 세션별로 선별된 상태 변경을 기록합니다.
- 감시자는 대상별 커서를 유지하고 통합된 오래된 상태 알림을 한 번 받습니다.
- 조정은
changesSince가 지정된session_status를 통해 정확한 델타를 가져옵니다.
신호 로그
감시 대상 세션에 중대한 변경이 발생하면 OpenClaw는 공유 상태 데이터베이스(session_state_events)에 형식이 지정된 이벤트를 추가합니다. 이벤트에는 메타데이터와 한 줄 요약이 포함되며, 메시지 내용은 절대 포함되지 않습니다.
| 종류 | 기록 시점 | 감시자에게 알림 |
|---|---|---|
human_direct_message |
사람이 감시 대상 세션에 턴을 직접 전송함 | 예 |
upstream_missing |
채택된 세션의 업스트림 소스가 사라짐 | 예 |
goal_changed |
세션의 목표 상태가 생성, 업데이트 또는 삭제됨 | 예 |
child_spawned |
하위 에이전트 또는 ACP 하위 세션이 생성됨 | 아니요(커서 초기화) |
run_completed |
하위 실행이 성공적으로 종료됨 | 아니요(로그만 기록) |
run_failed |
하위 실행이 실패하거나, 시간 초과되거나, 취소됨 | 아니요(로그만 기록) |
compacted |
세션 기록이 Compaction됨 | 아니요(로그만 기록) |
adopted |
카탈로그 세션이 OpenClaw에 채택됨 | 아니요(로그만 기록) |
각 이벤트에는 행위자(human, agent 또는 system)가 명시됩니다. 취소되거나 시간 초과된 하위 실행은 정확한 결과(cancelled, timeout 또는 error)가 이벤트 페이로드에 보존된 상태로 실패로 기록됩니다.
세션의 상태 버전은 해당 로그에서 가장 높은 시퀀스 번호이며, 정리 후에도 유지되는 세션별 내구성 헤드에서 추적됩니다. 변경 사항이 기록된 세션의 sessions_list 행에는 stateVersion가 포함되며, session_status는 항상 이를 보고합니다.
로그 전용 종류는 알림이 아닌 조정 기록을 위해 존재합니다. 일반적인 하위 실행 완료 전달은 계속 하위 에이전트 알림이 담당하며, 신호 로그는 이를 절대 중복하지 않습니다.
감시자
감시자는 대상에 대한 커서(session_watch_cursors)를 유지하는 세션입니다. 커서는 두 가지 경로로 생성됩니다.
- 암시적(생성 연결). 세션이 하위 에이전트 또는 ACP 하위 세션을 생성하면 상위 세션의 커서가 하위 세션의 생성 버전으로 자동 초기화됩니다. 상위 세션은 수동으로 구독하지 않습니다.
- 명시적(
sessions_send watch: true). 모든 조정자는 생성하지 않은 대상을 감시할 수 있습니다.sessions_send에서watch: true를 전달하면 전송이 성공적으로 디스패치된 후 발신자가 실제로 메시지를 받은 세션의 감시자로 등록됩니다. 등록은 대상의 현재 상태 버전에서 시작되므로 이전 기록은 절대 알림을 생성하지 않습니다. 매개변수가 설정되면 도구 결과에watched: true|false가 보고됩니다.
감시자 ID는 에이전트가 한정된 세션 키여야 합니다. session.scope="global"에서 공유 global 키는 에이전트 간에 모호하므로, 이러한 세션에는 내구성 로그와 changesSince가 제공되지만 선제적 알림은 제공되지 않습니다.
감시는 자동으로 정리됩니다. 커서 행은 신호 로그 보존 기간과 함께 만료되고, 감시자 세션이 재설정되면 제거되며, 두 세션 중 하나가 삭제되면 함께 삭제됩니다. v1에는 감시 해제 동작이 없습니다.
세션 카탈로그에서 채택된 감시 대상 세션은 고정 주기로 업스트림의 직접적인 사람 활동이 있는지 확인됩니다. 감지된 활동은 다른 직접적인 사람 턴과 동일한 신호 로그 및 감시자 흐름으로 진입합니다.
채택된 세션의 업스트림 소스가 외부에서 삭제되면 연속 세 번의 누락 확인(약 세 번의 모니터 틱) 후 감시자에게 upstream_missing 신호가 한 번 생성되고 업스트림 연결이 제거됩니다. 카탈로그 세션을 다시 계속하면 새로운 연결이 생성됩니다.
알림: 여러 번이 아닌 한 번
알림 대상 이벤트가 기록되고 감시자의 커서가 뒤처진 경우, 감시자는 다음 턴에 시스템 알림을 한 번 받습니다.
세션 "agent:main:subagent:child"이(가) 변경되었습니다(다른 행위자). 행동하기 전에 조정하십시오: session_status sessionKey "agent:main:subagent:child" changesSince 12.메인 세션 감시자는 Heartbeat 깨우기를 통해 즉시 활성화되기도 하며, 중첩된 하위 에이전트 감시자는 다음 턴에 알림을 받습니다.
프로토콜은 의도적으로 스팸을 방지하도록 설계되었습니다.
- 감시자/대상 쌍당 대기 중인 알림 하나. 대기 중에는 알림 텍스트가 바이트 단위로 동일하게 유지되고 시스템 이벤트 큐에서 이를 중복 제거하므로, 동일한 대상에 20개의 변경이 빠르게 발생하더라도 감시자의 프롬프트에는 한 줄만 생성됩니다.
- 고정 워터마크. 알림이 큐에 추가되면 커서의 알림 위치가 고정됩니다. 이후의 중대한 이벤트는 중대한 변경 워터마크만 전진시키며 다시 알리지 않습니다.
- 드레인 시 확인하고, 중간에 작업이 끼어든 경우에만 다시 엽니다. 감시자의 턴이 알림을 소비하면 커서가 전진합니다. 큐 추가와 드레인 사이에 중대한 이벤트가 더 도착했다면 나머지 이벤트에 대해 새로운 알림이 정확히 하나 열립니다.
- 자체 억제. 감시자는 자신이 발생시킨 이벤트에 대한 알림을 받지 않습니다.
- 재시작 복구. 대기 중인 알림은 메모리 내 큐에 저장됩니다. 시작 시 수행되는 스윕은 Gateway 재시작 후 내구성 커서에서 알림을 다시 구체화합니다.
조정
알림은 감시자에게 수행할 작업을 정확히 알려 줍니다. changesSince: <version>가 지정된 session_status는 커서를 전진시키지 않고 해당 버전 이후의 형식이 지정된 이벤트를 반환합니다(최대 200개).
{ "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 하위 실행에서 생성됩니다. 네이티브 하위 에이전트 취소는 일반적인 실패로 표시됩니다.
- 업스트림 자체 에코 감지는 정규화된 사용자 텍스트를 비교합니다. 외부 프롬프트가 세션에서 가장 최근에 OpenClaw 측에서 전송된 사용자 메시지 10개 중 하나와 일치하면 자체 에코로 처리됩니다.
- 1 MiB의 주기별 스캔 한도보다 큰 단일 로컬 Claude JSONL 행은 v1에서 해당 세션의 커서를 차단합니다. 분류되지 않은 바이트는 절대 건너뛰지 않습니다.
- 페어링된 Node의 Claude 검사는 주기마다 최신 트랜스크립트 항목 50개를 분류합니다. 이보다 큰 버스트는 v1 스캔 창을 벗어날 수 있습니다.
- 페어링된 Node의 Claude 기록 읽기는 확정적인 스레드 없음 결과를 노출하지 않으므로, 원격 Claude 삭제는 v1에서
upstream_missing로 분류되지 않습니다. - 채택되지 않은 카탈로그 세션은 v1에서 인식 계층의 적용을 받지 않습니다.
- 이 기능이 도입되기 전에 채택된 세션에는 업스트림 연결이 없습니다. 업스트림 모니터링을 시작하려면 카탈로그에서 해당 세션을 한 번 계속하십시오.
- 업스트림 연결은 채택된 각 세션 키가 하나의 소유 에이전트에 매핑된다고 가정합니다(채택 시 기본 저장소 에이전트를 사용함). 동일한 외부 스레드의 다중 에이전트 채택은 v1에서 모니터링되지 않습니다.