세션 도구

목표: 에이전트가 세션 목록을 조회하고, 히스토리를 가져오고, 다른 세션으로 메시지를 보낼 수 있는 작고 오용하기 어려운 도구 세트.

도구 이름

  • sessions_list
  • sessions_history
  • sessions_send
  • sessions_spawn

키 모델

  • 메인 직접 대화 버킷은 항상 리터럴 키 "main"(현재 에이전트의 메인 키로 해석됨)입니다.
  • 그룹 채팅은 agent:<agentId>:<channel>:group:<id> 또는 agent:<agentId>:<channel>:channel:<id>를 사용합니다(전체 키를 전달).
  • 크론 작업은 cron:<job.id>를 사용합니다.
  • 훅은 명시적으로 설정하지 않으면 hook:<uuid>를 사용합니다.
  • 노드 세션은 명시적으로 설정하지 않으면 node-<nodeId>를 사용합니다.

globalunknown은 예약된 값이며 목록에 표시되지 않습니다. session.scope = "global"이면 모든 도구에서 main으로 별칭 처리하여 호출자가 global을 볼 일이 없습니다.

sessions_list

세션을 행 배열로 나열합니다.

파라미터:

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

동작:

  • messageLimit > 0이면 세션별로 chat.history를 가져와 마지막 N개 메시지를 포함합니다.
  • 도구 결과는 목록 출력에서 필터링됩니다. 도구 메시지는 sessions_history를 사용하세요.
  • 샌드박스 에이전트 세션에서 실행할 때 세션 도구는 기본적으로 스폰된 항목만 표시됩니다(아래 참고).

행 구조 (JSON):

  • key: 세션 키 (문자열)
  • 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 (세션 오버라이드, 설정된 경우)
  • lastChannel, lastTo
  • deliveryContext (가능한 경우 정규화된 { 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은 세션 항목에 기록된 채널입니다.
  • 직접 대화의 경우 channellastChannel에서 매핑됩니다.
  • 크론/훅/노드의 경우 channelinternal입니다.
  • 누락된 경우 channelunknown입니다.

보안 / 전송 정책

채널/대화 유형별 정책 기반 차단(세션 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은 서브 에이전트 알림 단계를 실행하고 결과를 요청자 대화 채널에 게시합니다.
    • 어시스턴트 최종 응답이 비어 있으면 서브 에이전트 히스토리의 최신 toolResultResult로 포함됩니다.
  • 알림 단계에서 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로 강제 제한합니다.