세션 도구
목표: 에이전트가 세션 목록을 조회하고, 히스토리를 가져오고, 다른 세션으로 메시지를 보낼 수 있는 작고 오용하기 어려운 도구 세트.
도구 이름
sessions_listsessions_historysessions_sendsessions_spawn
키 모델
- 메인 직접 대화 버킷은 항상 리터럴 키
"main"(현재 에이전트의 메인 키로 해석됨)입니다. - 그룹 채팅은
agent:<agentId>:<channel>:group:<id>또는agent:<agentId>:<channel>:channel:<id>를 사용합니다(전체 키를 전달). - 크론 작업은
cron:<job.id>를 사용합니다. - 훅은 명시적으로 설정하지 않으면
hook:<uuid>를 사용합니다. - 노드 세션은 명시적으로 설정하지 않으면
node-<nodeId>를 사용합니다.
global과 unknown은 예약된 값이며 목록에 표시되지 않습니다. session.scope = "global"이면 모든 도구에서 main으로 별칭 처리하여 호출자가 global을 볼 일이 없습니다.
sessions_list
세션을 행 배열로 나열합니다.
파라미터:
kinds?: string[]필터:"main" | "group" | "cron" | "hook" | "node" | "other"중 하나limit?: number최대 행 수 (기본값: 서버 기본값, 예: 200으로 제한)activeMinutes?: numberN분 이내에 업데이트된 세션만messageLimit?: number0 = 메시지 없음 (기본값 0), >0 = 마지막 N개 메시지 포함
동작:
messageLimit > 0이면 세션별로chat.history를 가져와 마지막 N개 메시지를 포함합니다.- 도구 결과는 목록 출력에서 필터링됩니다. 도구 메시지는
sessions_history를 사용하세요. - 샌드박스 에이전트 세션에서 실행할 때 세션 도구는 기본적으로 스폰된 항목만 표시됩니다(아래 참고).
행 구조 (JSON):
key: 세션 키 (문자열)kind:main | group | cron | hook | node | otherchannel:whatsapp | telegram | discord | signal | imessage | webchat | internal | unknowndisplayName(그룹 표시 레이블, 있는 경우)updatedAt(ms)sessionIdmodel,contextTokens,totalTokensthinkingLevel,verboseLevel,systemSent,abortedLastRunsendPolicy(세션 오버라이드, 설정된 경우)lastChannel,lastTodeliveryContext(가능한 경우 정규화된{ channel, to, accountId })transcriptPath(저장소 디렉터리 + sessionId에서 파생된 최선 노력 경로)messages?(messageLimit > 0인 경우에만)
sessions_history
하나의 세션에 대한 대화 기록을 가져옵니다.
파라미터:
sessionKey(필수,sessions_list의 세션 키 또는sessionId허용)limit?: number최대 메시지 수 (서버에서 제한)includeTools?: boolean(기본값 false)
동작:
includeTools=false이면role: "toolResult"메시지를 필터링합니다.- 원시 대화 기록 형식의 메시지 배열을 반환합니다.
sessionId가 주어지면 OpenClaw이 해당 세션 키로 해석합니다(누락된 ID는 오류 발생).
sessions_send
다른 세션에 메시지를 보냅니다.
파라미터:
sessionKey(필수,sessions_list의 세션 키 또는sessionId허용)message(필수)timeoutSeconds?: number(기본값 >0, 0 = 실행 후 잊기(fire-and-forget))
동작:
timeoutSeconds = 0: 큐에 넣고{ runId, status: "accepted" }를 반환합니다.timeoutSeconds > 0: 최대 N초 동안 완료를 기다린 후{ runId, status: "ok", reply }를 반환합니다.- 대기 시간 초과 시:
{ runId, status: "timeout", error }. 실행은 계속되며 나중에sessions_history를 호출하세요. - 실행 실패 시:
{ runId, status: "error", error }. - 알림 전달 실행은 기본 실행 완료 후에 수행되며 최선 노력 기반입니다.
status: "ok"가 알림 전달을 보장하지는 않습니다. - 게이트웨이
agent.wait(서버 측)를 통해 대기하므로 재연결 시 대기가 끊기지 않습니다. - 에이전트 간 메시지 컨텍스트가 기본 실행에 주입됩니다.
- 세션 간 메시지는
message.provenance.kind = "inter_session"으로 기록되어 대화 기록 열람자가 라우팅된 에이전트 지시와 외부 사용자 입력을 구분할 수 있습니다. - 기본 실행 완료 후 OpenClaw은 응답 반복 루프를 실행합니다:
- 2라운드 이후부터 요청자와 대상 에이전트가 번갈아 진행합니다.
- 핑퐁을 멈추려면
REPLY_SKIP을 정확히 응답하세요. - 최대 턴 수는
session.agentToAgent.maxPingPongTurns(0-5, 기본값 5)입니다.
- 루프 종료 후 OpenClaw은 에이전트 간 알림 단계를 실행합니다(대상 에이전트만):
- 알림을 보내지 않으려면
ANNOUNCE_SKIP을 정확히 응답하세요. - 다른 응답은 대상 채널로 전송됩니다.
- 알림 단계에는 원본 요청 + 1라운드 응답 + 최신 핑퐁 응답이 포함됩니다.
- 알림을 보내지 않으려면
채널 필드
- 그룹의 경우
channel은 세션 항목에 기록된 채널입니다. - 직접 대화의 경우
channel은lastChannel에서 매핑됩니다. - 크론/훅/노드의 경우
channel은internal입니다. - 누락된 경우
channel은unknown입니다.
보안 / 전송 정책
채널/대화 유형별 정책 기반 차단(세션 ID별이 아님).
{
"session": {
"sendPolicy": {
"rules": [
{
"match": { "channel": "discord", "chatType": "group" },
"action": "deny"
}
],
"default": "allow"
}
}
}
런타임 오버라이드 (세션 항목별):
sendPolicy: "allow" | "deny"(미설정 = 설정 상속)sessions.patch또는 소유자 전용/send on|off|inherit(독립 메시지)로 설정 가능.
적용 지점:
chat.send/agent(게이트웨이)- 자동 응답 전달 로직
sessions_spawn
격리된 세션에서 서브 에이전트 실행을 시작하고 결과를 요청자 대화 채널로 알립니다.
파라미터:
task(필수)label?(선택, 로그/UI에 사용)agentId?(선택, 허용되는 경우 다른 에이전트 ID로 스폰)model?(선택, 서브 에이전트 모델 오버라이드, 유효하지 않은 값은 오류)thinking?(선택, 서브 에이전트 실행의 사고 수준 오버라이드)runTimeoutSeconds?(설정 시agents.defaults.subagents.runTimeoutSeconds를 기본값으로 사용, 그렇지 않으면0, 설정 시 N초 후 서브 에이전트 실행 중단)thread?(기본값 false, 채널/플러그인이 지원할 때 이 스폰에 대해 스레드 바인딩 라우팅 요청)mode?(run|session, 기본값run,thread=true일 때 기본값session,mode="session"은thread=true필요)cleanup?(delete|keep, 기본값keep)sandbox?(inherit|require, 기본값inherit,require는 대상 자식 런타임이 샌드박스가 아니면 스폰 거부)attachments?(선택, 인라인 파일 배열, 서브에이전트 런타임 전용, ACP는 거부). 각 항목:{ name, content, encoding?: "utf8" | "base64", mimeType? }. 파일은 자식 워크스페이스의.openclaw/attachments/<uuid>/에 생성됩니다. 파일별 sha256이 포함된 수신 확인을 반환합니다.attachAs?(선택,{ mountPath? }힌트, 향후 마운트 구현을 위해 예약)
허용 목록:
agents.list[].subagents.allowAgents:agentId를 통해 허용되는 에이전트 ID 목록 (["*"]로 전체 허용). 기본값: 요청자 에이전트만.- 샌드박스 상속 가드: 요청자 세션이 샌드박스인 경우,
sessions_spawn은 샌드박스 없이 실행되는 대상을 거부합니다.
디스커버리:
agents_list를 사용하여sessions_spawn에 허용되는 에이전트 ID를 확인합니다.
동작:
deliver: false로 새agent:<agentId>:subagent:<uuid>세션을 시작합니다.- 서브 에이전트는 기본적으로 세션 도구를 제외한 전체 도구 세트를 사용합니다(
tools.subagents.tools로 구성 가능). - 서브 에이전트는
sessions_spawn을 호출할 수 없습니다(서브 에이전트 → 서브 에이전트 스폰 불가). - 항상 비차단: 즉시
{ status: "accepted", runId, childSessionKey }를 반환합니다. thread=true일 때 채널 플러그인이 전달/라우팅을 스레드 대상에 바인딩할 수 있습니다(Discord 지원은session.threadBindings.*및channels.discord.threadBindings.*로 제어).- 완료 후 OpenClaw은 서브 에이전트 알림 단계를 실행하고 결과를 요청자 대화 채널에 게시합니다.
- 어시스턴트 최종 응답이 비어 있으면 서브 에이전트 히스토리의 최신
toolResult가Result로 포함됩니다.
- 어시스턴트 최종 응답이 비어 있으면 서브 에이전트 히스토리의 최신
- 알림 단계에서
ANNOUNCE_SKIP을 정확히 응답하면 알림을 보내지 않습니다. - 알림 응답은
Status/Result/Notes로 정규화됩니다.Status는 런타임 결과에서 가져오며 모델 텍스트가 아닙니다. - 서브 에이전트 세션은
agents.defaults.subagents.archiveAfterMinutes(기본값: 60) 이후 자동 보관됩니다. - 알림 응답에는 통계 행(런타임, 토큰, sessionKey/sessionId, 대화 기록 경로, 선택적 비용)이 포함됩니다.
샌드박스 세션 가시성
세션 도구의 범위를 제한하여 교차 세션 접근을 줄일 수 있습니다.
기본 동작:
tools.sessions.visibility의 기본값은tree(현재 세션 + 스폰된 서브에이전트 세션)입니다.- 샌드박스 세션의 경우
agents.defaults.sandbox.sessionToolsVisibility로 가시성을 강제 제한할 수 있습니다.
설정:
{
tools: {
sessions: {
// "self" | "tree" | "agent" | "all"
// 기본값: "tree"
visibility: "tree",
},
},
agents: {
defaults: {
sandbox: {
// 기본값: "spawned"
sessionToolsVisibility: "spawned", // 또는 "all"
},
},
},
}
참고:
self: 현재 세션 키만.tree: 현재 세션 + 현재 세션에서 스폰된 세션.agent: 현재 에이전트 ID에 속하는 모든 세션.all: 모든 세션 (교차 에이전트 접근은 여전히tools.agentToAgent이 필요).- 세션이 샌드박스이고
sessionToolsVisibility="spawned"이면,tools.sessions.visibility="all"로 설정해도 OpenClaw이 가시성을tree로 강제 제한합니다.