Session Tools

목표: agent가 session을 나열하고, 기록을 가져오고, 다른 session으로 전송할 수 있도록 작고 오용하기 어려운 tool 세트를 제공합니다.

Tool 이름

  • sessions_list
  • sessions_history
  • sessions_send
  • sessions_spawn

Key 모델

  • Main direct chat 버킷은 항상 리터럴 키 "main"입니다(현재 agent의 main key로 해석됨).
  • Group chat은 agent:<agentId>:<channel>:group:<id> 또는 agent:<agentId>:<channel>:channel:<id>를 사용합니다(전체 키 전달).
  • Cron 작업은 cron:<job.id>를 사용합니다.
  • Hook은 명시적으로 설정하지 않는 한 hook:<uuid>를 사용합니다.
  • Node session은 명시적으로 설정하지 않는 한 node-<nodeId>를 사용합니다.

globalunknown은 예약된 값이며 절대 나열되지 않습니다. session.scope = "global"인 경우 모든 tool에 대해 main으로 별칭을 지정하여 호출자가 global을 보지 않도록 합니다.

sessions_list

Session을 행 배열로 나열합니다.

매개변수:

  • kinds?: string[] 필터: "main" | "group" | "cron" | "hook" | "node" | "other" 중 하나
  • limit?: number 최대 행 수(기본값: 서버 기본값, 예: 200으로 제한)
  • activeMinutes?: number N분 이내에 업데이트된 session만
  • messageLimit?: number 0 = 메시지 없음(기본값 0); >0 = 마지막 N개 메시지 포함

동작:

  • messageLimit > 0은 session별로 chat.history를 가져오고 마지막 N개 메시지를 포함합니다.
  • Tool 결과는 list 출력에서 필터링됩니다. Tool 메시지는 sessions_history를 사용하세요.
  • Sandbox된 agent session에서 실행할 때 session tool은 기본적으로 spawned-only 가시성으로 설정됩니다(아래 참조).

행 형태 (JSON):

  • key: session 키(문자열)
  • kind: main | group | cron | hook | node | other
  • channel: whatsapp | telegram | discord | signal | imessage | webchat | internal | unknown
  • displayName (사용 가능한 경우 그룹 표시 레이블)
  • updatedAt (ms)
  • sessionId
  • model, contextTokens, totalTokens
  • thinkingLevel, verboseLevel, systemSent, abortedLastRun
  • sendPolicy (설정된 경우 session 재정의)
  • lastChannel, lastTo
  • deliveryContext (사용 가능한 경우 정규화된 { channel, to, accountId })
  • transcriptPath (store dir + sessionId에서 파생된 best-effort 경로)
  • messages? (messageLimit > 0인 경우에만)

sessions_history

하나의 session에 대한 transcript를 가져옵니다.

매개변수:

  • sessionKey (필수; sessions_list의 session 키 또는 sessionId 허용)
  • limit?: number 최대 메시지 수(서버 제한)
  • includeTools?: boolean (기본값 false)

동작:

  • includeTools=falserole: "toolResult" 메시지를 필터링합니다.
  • 원시 transcript 형식의 메시지 배열을 반환합니다.
  • sessionId가 주어지면 OpenClaw는 이를 해당 session 키로 해석합니다(누락된 id는 오류).

sessions_send

다른 session으로 메시지를 전송합니다.

매개변수:

  • sessionKey (필수; sessions_list의 session 키 또는 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 }.
  • Announce 전달은 primary 실행이 완료된 후 실행되며 best-effort입니다. status: "ok"는 announce가 전달되었음을 보장하지 않습니다.
  • Gateway agent.wait(서버 측)을 통해 대기하므로 재연결해도 대기가 중단되지 않습니다.
  • Agent 간 메시지 컨텍스트는 primary 실행에 주입됩니다.
  • Primary 실행이 완료된 후 OpenClaw는 reply-back 루프를 실행합니다:
    • Round 2+는 요청자와 대상 agent 간에 번갈아 진행됩니다.
    • 정확히 REPLY_SKIP으로 답장하면 ping‑pong을 중지합니다.
    • 최대 턴 수는 session.agentToAgent.maxPingPongTurns(0–5, 기본값 5)입니다.
  • 루프가 종료되면 OpenClaw는 agent‑to‑agent announce 단계(대상 agent만)를 실행합니다:
    • 정확히 ANNOUNCE_SKIP으로 답장하면 침묵을 유지합니다.
    • 다른 답장은 대상 channel로 전송됩니다.
    • Announce 단계에는 원래 요청 + round‑1 답장 + 최신 ping‑pong 답장이 포함됩니다.

Channel 필드

  • 그룹의 경우 channel은 session 항목에 기록된 channel입니다.
  • Direct chat의 경우 channellastChannel에서 매핑됩니다.
  • Cron/hook/node의 경우 channelinternal입니다.
  • 누락된 경우 channelunknown입니다.

보안 / Send Policy

Channel/chat 유형별 정책 기반 차단(session id별이 아님).

{
  "session": {
    "sendPolicy": {
      "rules": [
        {
          "match": { "channel": "discord", "chatType": "group" },
          "action": "deny"
        }
      ],
      "default": "allow"
    }
  }
}

런타임 재정의(session 항목별):

  • sendPolicy: "allow" | "deny" (설정 안 함 = config 상속)
  • sessions.patch 또는 소유자 전용 /send on|off|inherit(독립 실행형 메시지)를 통해 설정 가능.

강제 지점:

  • chat.send / agent (gateway)
  • 자동 응답 전달 로직

sessions_spawn

격리된 session에서 sub-agent 실행을 생성하고 결과를 요청자 채팅 channel로 다시 알립니다.

매개변수:

  • task (필수)
  • label? (선택사항; 로그/UI에 사용됨)
  • agentId? (선택사항; 허용된 경우 다른 agent id로 생성)
  • model? (선택사항; sub-agent model 재정의; 잘못된 값은 오류)
  • runTimeoutSeconds? (기본값 0; 설정 시 N초 후 sub-agent 실행 중단)
  • cleanup? (delete|keep, 기본값 keep)

Allowlist:

  • agents.list[].subagents.allowAgents: agentId를 통해 허용된 agent id 목록(["*"]는 모든 것을 허용). 기본값: 요청자 agent만.

Discovery:

  • agents_list를 사용하여 sessions_spawn에 허용된 agent id를 발견하세요.

동작:

  • deliver: false로 새로운 agent:<agentId>:subagent:<uuid> session을 시작합니다.
  • Sub-agent는 기본적으로 session tool을 제외한 전체 tool 세트로 설정됩니다(tools.subagents.tools를 통해 구성 가능).
  • Sub-agent는 sessions_spawn을 호출할 수 없습니다(sub-agent → sub-agent 생성 불가).
  • 항상 비차단: 즉시 { status: "accepted", runId, childSessionKey }를 반환합니다.
  • 완료 후 OpenClaw는 sub-agent announce 단계를 실행하고 결과를 요청자 채팅 channel에 게시합니다.
  • Announce 단계에서 정확히 ANNOUNCE_SKIP으로 답장하면 침묵을 유지합니다.
  • Announce 답장은 Status/Result/Notes로 정규화됩니다. Status는 런타임 결과에서 가져옵니다(model 텍스트가 아님).
  • Sub-agent session은 agents.defaults.subagents.archiveAfterMinutes(기본값: 60) 후 자동 아카이브됩니다.
  • Announce 답장에는 통계 라인(런타임, 토큰, sessionKey/sessionId, transcript 경로 및 선택적 비용)이 포함됩니다.

Sandbox Session 가시성

Sandbox된 session은 session tool을 사용할 수 있지만 기본적으로 sessions_spawn을 통해 생성한 session만 볼 수 있습니다.

Config:

{
  agents: {
    defaults: {
      sandbox: {
        // 기본값: "spawned"
        sessionToolsVisibility: "spawned" // 또는 "all"
      }
    }
  }
}