Session Tools
목표는 agent가 session을 나열하고, history를 가져오고, 다른 session으로 message를 보낼 수 있게 하되, 오용하기 어렵고 작은 tool set을 제공하는 것입니다.Tool Names
sessions_listsessions_historysessions_sendsessions_spawn
Key Model
- main direct chat bucket은 항상 literal key
"main"입니다 (현재 agent의 main key로 resolve됨) - group chat은
agent:<agentId>:<channel>:group:<id>또는agent:<agentId>:<channel>:channel:<id>를 사용합니다 (full key 전달) - cron job은
cron:<job.id> - hook은 명시적으로 설정하지 않으면
hook:<uuid> - node session은 명시적으로 설정하지 않으면
node-<nodeId>
global과 unknown은 reserved value라 절대 list되지 않습니다.
session.scope = "global"이면 caller가 global을 보지 않도록, 모든 tool에서
main으로 alias합니다.
sessions_list
session을 row array로 반환합니다. Parameters:kinds?: string[]filter:"main" | "group" | "cron" | "hook" | "node" | "other"중 하나 이상limit?: number최대 row 수 (기본값은 server default, 예: 200으로 clamp)activeMinutes?: number최근 N분 내 update된 session만 포함messageLimit?: number0이면 message 제외 (기본값 0),>0이면 최근 N개 message 포함
messageLimit > 0이면 session별로chat.history를 가져와 마지막 N개 message를 포함- list output에서는 tool result를 필터링합니다.
tool message가 필요하면
sessions_history를 사용하세요 - sandboxed agent session에서는 session tool이 기본적으로 spawned-only visibility를 가집니다 (아래 설명 참고)
key: session keykind:main | group | cron | hook | node | otherchannel:whatsapp | telegram | discord | signal | imessage | webchat | internal | unknowndisplayName(가능하면 group display label)updatedAt(ms)sessionIdmodel,contextTokens,totalTokensthinkingLevel,verboseLevel,systemSent,abortedLastRunsendPolicy(session override가 있으면)lastChannel,lastTodeliveryContext(가능하면 normalized{ channel, to, accountId })transcriptPath(store dir + sessionId에서 유도한 best-effort path)messages?(messageLimit > 0일 때만)
sessions_history
하나의 session transcript를 가져옵니다. Parameters:sessionKey(required; session key 또는sessions_list의sessionId)limit?: number최대 message 수 (server clamp)includeTools?: boolean(기본값 false)
includeTools=false이면role: "toolResult"message를 필터링- raw transcript format의 messages array를 반환
sessionId를 주면 OpenClaw가 해당 session key로 resolve (없으면 error)
sessions_send
다른 session으로 message를 보냅니다. Parameters:sessionKey(required; session key 또는sessions_list의sessionId)message(required)timeoutSeconds?: number(기본값은 0보다 큼;0은 fire-and-forget)
timeoutSeconds = 0: enqueue 후{ runId, status: "accepted" }반환timeoutSeconds > 0: N초까지 completion을 기다렸다가{ runId, status: "ok", reply }반환- wait가 timeout되면:
{ runId, status: "timeout", error }run은 계속되므로 나중에sessions_history로 확인 가능 - run이 실패하면:
{ runId, status: "error", error } - announce delivery run은 primary run 완료 뒤에 best-effort로 실행되며,
status: "ok"라고 해서 announce delivery까지 보장되지는 않습니다 - wait는 gateway
agent.wait(server-side)로 처리되므로 reconnect되어도 wait가 끊기지 않습니다 - primary run에는 agent-to-agent message context가 inject됩니다
- inter-session message는
message.provenance.kind = "inter_session"로 저장되어 transcript reader가 routed agent instruction과 외부 user input을 구분할 수 있습니다 - primary run이 끝나면 OpenClaw는 reply-back loop를 실행합니다
- round 2+는 requester agent와 target agent가 번갈아가며 reply
- ping-pong을 멈추려면 정확히
REPLY_SKIP를 반환 - 최대 turn 수는
session.agentToAgent.maxPingPongTurns(0–5, 기본값 5)
- loop가 끝나면 OpenClaw는 agent-to-agent announce step
(target agent only)을 실행합니다
- 조용히 끝내려면 정확히
ANNOUNCE_SKIP를 반환 - 그 외 reply는 target channel로 전송
- announce step에는 original request, round-1 reply, latest ping-pong reply가 포함
- 조용히 끝내려면 정확히
Channel Field
- group은 session entry에 기록된 channel을 사용
- direct chat은
lastChannel에서 channel을 매핑 - cron/hook/node는
internal - 없으면
unknown
Security / Send Policy
channel/chat type 기준의 policy block을 적용합니다 (session id 기준이 아님).sendPolicy: "allow" | "deny"(unset이면 config 상속)sessions.patch또는 owner-only/send on|off|inherit(standalone message)로 설정 가능
chat.send/agent(gateway)- auto-reply delivery logic
sessions_spawn
isolated session에서 sub-agent run을 spawn하고, 결과를 requester chat channel에 announce합니다. Parameters:task(required)label?(optional; log/UI용)agentId?(optional; 허용되면 다른 agent id 아래에서 spawn)model?(optional; sub-agent model override, invalid value는 error)thinking?(optional; sub-agent run thinking level override)runTimeoutSeconds?(agents.defaults.subagents.runTimeoutSeconds가 있으면 그 값을 기본값으로, 없으면0; 설정되면 N초 후 sub-agent run abort)thread?(기본값 false; channel/plugin이 지원하면 thread-bound routing 요청)mode?(run|session; 기본값은run, 단thread=true이면session;mode="session"은thread=true필요)cleanup?(delete|keep, 기본값keep)sandbox?(inherit|require, 기본값inherit;require는 target child runtime이 sandbox가 아니면 reject)attachments?(optional inline file array; subagent runtime only, ACP는 reject) 각 항목은{ name, content, encoding?: "utf8" | "base64", mimeType? }형식이고, child workspace의.openclaw/attachments/<uuid>/에 materialize됩니다. file별 sha256 receipt를 반환합니다attachAs?(optional;{ mountPath? }형태의 향후 mount 구현용 hint)
agents.list[].subagents.allowAgents:agentId로 spawn 가능한 agent id 목록 (["*"]면 모두 허용). 기본값은 requester agent만 허용- sandbox inheritance guard: requester session이 sandboxed면, unsandboxed target은 reject
sessions_spawn에 허용된 agent id는agents_list로 찾습니다
deliver: false인 새agent:<agentId>:subagent:<uuid>session을 시작- sub-agent는 기본적으로 전체 tool set에서 session tool만 제외된 상태로 시작
(
tools.subagents.tools로 설정 가능) - sub-agent는
sessions_spawn을 다시 호출할 수 없습니다 (sub-agent → sub-agent spawn 금지) - 항상 non-blocking:
즉시
{ status: "accepted", runId, childSessionKey }반환 thread=true이면 channel plugin이 delivery/routing을 thread target에 bind할 수 있음 (Discord support는session.threadBindings.*,channels.discord.threadBindings.*로 제어)- completion 후 OpenClaw는 sub-agent announce step을 실행해 requester chat channel에
결과를 올립니다
- assistant final reply가 비어 있으면 sub-agent history의 최신
toolResult를Result로 포함
- assistant final reply가 비어 있으면 sub-agent history의 최신
- announce step에서 정확히
ANNOUNCE_SKIP를 reply하면 조용히 종료 - announce reply는
Status/Result/Notes로 normalize되며,Status는 model text가 아니라 runtime outcome에서 결정 - sub-agent session은
agents.defaults.subagents.archiveAfterMinutes(기본값 60) 후 auto-archive - announce reply에는 runtime, tokens, sessionKey/sessionId, transcript path, optional cost를 담은 stats line이 포함
Sandbox Session Visibility
session tool은 cross-session access를 줄이기 위해 scope를 제한할 수 있습니다. 기본 동작:tools.sessions.visibility기본값은tree(현재 session + spawned subagent session)- sandboxed session에서는
agents.defaults.sandbox.sessionToolsVisibility가 visibility를 강하게 clamp할 수 있음
self: 현재 session key만tree: 현재 session + 현재 session이 spawn한 sessionagent: 현재 agent id에 속한 어떤 session이든all: 어떤 session이든 (cross-agent access에는 여전히tools.agentToAgent필요)- session이 sandboxed이고
sessionToolsVisibility="spawned"이면,tools.sessions.visibility="all"이어도 OpenClaw는tree로 clamp합니다