Session 工具

設計目標:精簡、不易誤用的工具組,讓 Agent 可以列出 Session、讀取歷史紀錄、傳送訊息到其他 Session。

工具名稱

  • sessions_list
  • sessions_history
  • sessions_send
  • sessions_spawn

Key 模型

  • 主要的直接對話 Bucket 固定使用字面值 "main"(解析為當前 Agent 的 Main Key)。
  • 群組對話使用 agent:<agentId>:<channel>:group:<id>agent:<agentId>:<channel>:channel:<id>(傳入完整 Key)。
  • Cron 工作使用 cron:<job.id>
  • Hook 使用 hook:<uuid>,除非另有明確設定。
  • Node Session 使用 node-<nodeId>,除非另有明確設定。

globalunknown 是保留值,不會出現在清單中。若 session.scope = "global",所有工具都會將其別名為 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 則訊息。
  • 清單輸出會過濾掉工具結果;若需要工具訊息請使用 sessions_history
  • 沙箱化 Agent Session 中執行時,Session 工具預設為僅 spawn 出的可見範圍(見下方說明)。

列項結構(JSON):

  • key:Session Key(字串)
  • kindmain | group | cron | hook | node | other
  • channelwhatsapp | telegram | discord | signal | imessage | webchat | internal | unknown
  • displayName(群組顯示標籤,若有的話)
  • updatedAt(毫秒)
  • sessionId
  • modelcontextTokenstotalTokens
  • thinkingLevelverboseLevelsystemSentabortedLastRun
  • sendPolicy(Session 覆蓋設定,若有設定)
  • lastChannellastTo
  • deliveryContext(正規化的 { channel, to, accountId },若可用)
  • transcriptPath(依 store 目錄 + sessionId 推導的最佳路徑)
  • messages?(僅在 messageLimit > 0 時出現)

sessions_history

取得單一 Session 的對話記錄。

參數:

  • sessionKey(必填;接受 Session Key 或來自 sessions_listsessionId
  • limit?: number 最大訊息數(伺服器會進行上限限制)
  • includeTools?: boolean(預設 false)

行為:

  • includeTools=false 會過濾掉 role: "toolResult" 的訊息。
  • 回傳原始對話記錄格式的訊息陣列。
  • 若提供的是 sessionId,OpenClaw 會解析為對應的 Session Key(找不到 ID 會報錯)。

sessions_send

傳送訊息到另一個 Session。

參數:

  • sessionKey(必填;接受 Session Key 或來自 sessions_listsessionId
  • message(必填)
  • timeoutSeconds?: number(預設 >0;0 = 發射後不管)

行為:

  • timeoutSeconds = 0:入列後回傳 { runId, status: "accepted" }
  • timeoutSeconds > 0:等待最多 N 秒完成,然後回傳 { runId, status: "ok", reply }
  • 等待逾時:{ runId, status: "timeout", error }。執行仍會繼續;稍後呼叫 sessions_history 查看結果。
  • 執行失敗:{ runId, status: "error", error }
  • 通知投遞會在主要執行完成後進行,屬於盡力而為;status: "ok" 不保證通知已送達。
  • 等待透過 Gateway 的 agent.wait(伺服器端)進行,重新連線不會中斷等待。
  • Agent 間訊息的上下文會注入到主要執行中。
  • 跨 Session 訊息以 message.provenance.kind = "inter_session" 持久化,讓對話記錄讀取端能區分路由的 Agent 指示與外部使用者輸入。
  • 主要執行完成後,OpenClaw 會執行回覆來回循環
    • 第 2 輪起在請求方與目標 Agent 之間交替進行。
    • 回覆 REPLY_SKIP 可停止乒乓循環。
    • 最大輪數為 session.agentToAgent.maxPingPongTurns(0–5,預設 5)。
  • 循環結束後,OpenClaw 執行 Agent 間通知步驟(僅限目標 Agent):
    • 回覆 ANNOUNCE_SKIP 可保持靜默。
    • 其他回覆會傳送到目標頻道。
    • 通知步驟包含原始請求 + 第 1 輪回覆 + 最新乒乓回覆。

Channel 欄位

  • 群組的 channel 取自 Session 項目記錄的頻道。
  • 直接對話的 channellastChannel 對應。
  • Cron/Hook/Node 的 channelinternal
  • 若缺少,channelunknown

安全性 / 傳送策略

基於頻道/對話類型的策略阻擋(非依 Session ID)。

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

執行期間覆蓋(依 Session 項目):

  • sendPolicy: "allow" | "deny"(未設定 = 繼承設定)
  • 可透過 sessions.patch 或僅限擁有者的 /send on|off|inherit(獨立訊息)設定。

強制執行點:

  • chat.send / agent(Gateway)
  • 自動回覆投遞邏輯

sessions_spawn

在隔離的 Session 中啟動子 Agent 執行,並將結果通知回請求方的對話頻道。

參數:

  • task(必填)
  • label?(選填;用於日誌/UI)
  • agentId?(選填;如果允許的話,在另一個 Agent ID 下啟動)
  • model?(選填;覆蓋子 Agent 的模型;無效值會報錯)
  • thinking?(選填;覆蓋子 Agent 執行的思考等級)
  • runTimeoutSeconds?(預設為 agents.defaults.subagents.runTimeoutSeconds(若有設定),否則為 0;設定後會在 N 秒後中止子 Agent 執行)
  • thread?(預設 false;當頻道/外掛支援時,為此 spawn 請求綁定討論串路由)
  • mode?run|session;預設為 run,但 thread=true 時預設為 sessionmode="session" 需要 thread=true
  • cleanup?delete|keep,預設 keep
  • sandbox?inherit|require,預設 inheritrequire 會在目標子執行期間未沙箱化時拒絕 spawn)
  • attachments?(選填,行內檔案陣列;僅限子 Agent 執行期間,ACP 會拒絕)。每個項目:{ name, content, encoding?: "utf8" | "base64", mimeType? }。檔案會在子 Workspace 的 .openclaw/attachments/<uuid>/ 中實體化。回傳每個檔案的 sha256 收據。
  • attachAs?(選填;{ mountPath? } 提示,保留給未來掛載實作)

允許清單:

  • agents.list[].subagents.allowAgents:可透過 agentId 使用的 Agent ID 清單(["*"] 允許任何)。預設:僅限請求方 Agent。
  • 沙箱繼承防護:如果請求方 Session 是沙箱化的,sessions_spawn 會拒絕會在非沙箱化環境中執行的目標。

探索:

  • 使用 agents_list 查看哪些 Agent ID 可用於 sessions_spawn

行為:

  • 啟動一個新的 agent:<agentId>:subagent:<uuid> Session,deliver: false
  • 子 Agent 預設擁有完整工具組減去 Session 工具(可透過 tools.subagents.tools 設定)。
  • 子 Agent 不允許呼叫 sessions_spawn(禁止子 Agent 再 spawn 子 Agent)。
  • 永遠非阻塞:立即回傳 { status: "accepted", runId, childSessionKey }
  • 使用 thread=true 時,頻道外掛可將投遞/路由綁定到討論串目標(Discord 支援受 session.threadBindings.*channels.discord.threadBindings.* 控制)。
  • 完成後,OpenClaw 執行子 Agent 通知步驟,並將結果發布到請求方的對話頻道。
    • 若助理最終回覆為空,會將子 Agent 歷史紀錄中最新的 toolResult 作為 Result 包含在內。
  • 在通知步驟中回覆 ANNOUNCE_SKIP 可保持靜默。
  • 通知回覆會正規化為 Status/Result/NotesStatus 來自執行結果(非模型文字)。
  • 子 Agent Session 在 agents.defaults.subagents.archiveAfterMinutes(預設:60)後自動封存。
  • 通知回覆包含統計資訊(執行時間、Token 數、sessionKey/sessionId、對話記錄路徑,以及選填的成本)。

沙箱 Session 可見性

Session 工具可設定作用範圍以限制跨 Session 存取。

預設行為:

  • tools.sessions.visibility 預設為 tree(當前 Session + 由此 spawn 出的子 Agent Session)。
  • 對於沙箱化的 Session,agents.defaults.sandbox.sessionToolsVisibility 可強制限制可見性。

設定:

{
  tools: {
    sessions: {
      // "self" | "tree" | "agent" | "all"
      // 預設: "tree"
      visibility: "tree",
    },
  },
  agents: {
    defaults: {
      sandbox: {
        // 預設: "spawned"
        sessionToolsVisibility: "spawned", // 或 "all"
      },
    },
  },
}

說明:

  • self:僅限當前 Session Key。
  • tree:當前 Session + 由當前 Session spawn 出的 Session。
  • agent:屬於當前 Agent ID 的任何 Session。
  • all:任何 Session(跨 Agent 存取仍需要 tools.agentToAgent)。
  • 當 Session 是沙箱化且 sessionToolsVisibility="spawned" 時,即使你設定 tools.sessions.visibility="all",OpenClaw 也會將可見性限制為 tree