Appearance
Session Tools(会话工具)
目标:提供一套小而不易误用的工具,让 Agent 能够列出会话、拉取历史记录,以及向其他会话发送消息。
工具名称
sessions_listsessions_historysessions_sendsessions_spawn
核心模型
- 主直聊桶始终使用字面量键
"main"(解析为当前 Agent 的主键)。 - 群聊使用
agent:<agentId>:<channel>:group:<id>或agent:<agentId>:<channel>:channel:<id>(传入完整键)。 - Cron 任务使用
cron:<job.id>。 - Hook 使用
hook:<uuid>(除非显式设置)。 - Node 会话使用
node-<nodeId>(除非显式设置)。
global 和 unknown 是保留值,永远不会出现在列表中。如果 session.scope = "global",所有工具均将其别名为 main,调用方不会看到 global。
sessions_list
以数组形式列出会话。
参数:
kinds?: string[]过滤器:可选值"main" | "group" | "cron" | "hook" | "node" | "other"limit?: number最大行数(默认:服务端默认值,例如上限 200)activeMinutes?: number仅返回 N 分钟内有更新的会话messageLimit?: number0 = 不含消息(默认 0);>0 = 包含最后 N 条消息
行为:
messageLimit > 0时,每个会话调用chat.history并附上最后 N 条消息。- 列表输出中过滤掉工具调用结果;如需查看工具消息请用
sessions_history。 - 在沙盒 Agent 会话中运行时,会话工具默认为仅派生可见(见下文)。
返回行结构(JSON):
key:会话键(字符串)kind:main | group | cron | hook | node | otherchannel:whatsapp | telegram | discord | signal | imessage | webchat | internal | unknowndisplayName(群组显示标签,如果有)updatedAt(毫秒时间戳)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 会将其解析为对应的会话键(找不到则报错)。
Gateway 会话历史与实时转录 API
控制界面和 gateway 客户端可以直接使用底层历史和实时转录接口。
HTTP:
GET /sessions/{sessionKey}/history- 查询参数:
limit、cursor、includeTools=1、follow=1 - 未知会话返回 HTTP
404,error.type = "not_found" follow=1将响应升级为该会话转录更新的 SSE 流
WebSocket:
sessions.subscribe订阅客户端可见的所有会话生命周期和转录事件sessions.messages.subscribe { key }仅订阅某个会话的session.message事件sessions.messages.unsubscribe { key }取消该定向转录订阅session.message携带追加的转录消息,以及可用时的实时用量元数据sessions.changed在转录追加时发送phase: "message",方便会话列表刷新计数和预览
sessions_send
向另一个会话发送消息。
参数:
sessionKey(必填;接受来自sessions_list的会话键或sessionId)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 间消息上下文会在主运行中注入。
- 跨会话消息以
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取自会话条目上记录的频道。 - 直聊:
channel映射自lastChannel。 - Cron/Hook/Node:
channel为internal。 - 缺失时:
channel为unknown。
安全策略 / Send Policy
基于频道/聊天类型(非每个会话 ID)的策略拦截。
json
{
"session": {
"sendPolicy": {
"rules": [
{
"match": { "channel": "discord", "chatType": "group" },
"action": "deny"
}
],
"default": "allow"
}
}
}运行时覆盖(每个会话条目):
sendPolicy: "allow" | "deny"(未设置 = 继承配置)- 可通过
sessions.patch或仅限所有者的/send on|off|inherit(独立消息)设置。
执行点:
chat.send/agent(gateway)- 自动回复投递逻辑
sessions_spawn
派生一个隔离的委托会话——相当于给你的小龙虾开一个独立的小分队去执行子任务。
- 默认运行时:OpenClaw 子 Agent(
runtime: "subagent")。 - ACP 装置会话使用
runtime: "acp",遵循 ACP 特定的目标/策略规则。 - 本节重点介绍子 Agent 行为,ACP 特定行为请参阅 ACP Agents。
参数:
task(必填)runtime?(subagent|acp;默认subagent)label?(可选;用于日志/UI)agentId?(可选)runtime: "subagent":若subagents.allowAgents允许,可目标另一个 OpenClaw Agent IDruntime: "acp":若acp.allowedAgents允许,可目标 ACP 装置 ID
model?(可选;覆盖子 Agent 模型;无效值报错)thinking?(可选;覆盖子 Agent 运行的思考等级)runTimeoutSeconds?(若agents.defaults.subagents.runTimeoutSeconds已设置则默认使用,否则默认0;设置后在 N 秒后中止子 Agent 运行)thread?(默认 false;请求频道/插件支持的线程绑定路由)mode?(run|session;默认run,thread=true时默认session;mode="session"需要thread=true)cleanup?(delete|keep,默认keep)sandbox?(inherit|require,默认inherit;require在目标子运行时非沙盒时拒绝派生)attachments?(可选内联文件数组;仅限子 Agent 运行时,ACP 拒绝)。每条:{ name, content, encoding?: "utf8" | "base64", mimeType? }。文件会在子工作空间的.openclaw/attachments/<uuid>/下实体化。返回含每文件 sha256 的回执。attachAs?(可选;{ mountPath? }保留供未来挂载实现使用的提示)
允许列表:
runtime: "subagent":agents.list[].subagents.allowAgents控制哪些 OpenClaw Agent ID 可通过agentId使用(["*"]允许任意)。默认:仅请求方 Agent。runtime: "acp":acp.allowedAgents控制哪些 ACP 装置 ID 被允许,与subagents.allowAgents策略独立。- 沙盒继承保护:若请求方会话是沙盒,
sessions_spawn拒绝目标运行时为非沙盒的情况。
发现可用目标:
- 使用
agents_list发现runtime: "subagent"的允许目标。 - 对于
runtime: "acp",使用已配置的 ACP 装置 ID 和acp.allowedAgents;agents_list不列出 ACP 装置目标。
行为:
- 启动一个新的
agent:<agentId>:subagent:<uuid>会话,deliver: false。 - 子 Agent 默认拥有完整工具集减去会话工具(可通过
tools.subagents.tools配置)。 - 子 Agent 不允许调用
sessions_spawn(禁止子 Agent → 子 Agent 派生)。 - 始终非阻塞:立即返回
{ status: "accepted", runId, childSessionKey }。 thread=true时,频道插件可将投递/路由绑定到线程目标(Discord 支持受session.threadBindings.*和channels.discord.threadBindings.*控制)。- 完成后,OpenClaw 运行子 Agent 通知步骤,将结果推送到请求方聊天频道。
- 若 Assistant 最终回复为空,子 Agent 历史中最新的
toolResult会作为Result附上。
- 若 Assistant 最终回复为空,子 Agent 历史中最新的
- 通知步骤中回复恰好为
ANNOUNCE_SKIP可保持沉默。 - 通知回复归一化为
Status/Result/Notes;Status来自运行时结果(非模型文本)。 - 子 Agent 会话在
agents.defaults.subagents.archiveAfterMinutes后自动归档(默认:60 分钟)。 - 通知回复包含统计行(运行时、Token 数、sessionKey/sessionId、转录路径及可选费用)。
沙盒会话可见性
会话工具可以限定范围以减少跨会话访问。
默认行为:
tools.sessions.visibility默认为tree(当前会话 + 派生的子 Agent 会话)。- 对于沙盒会话,
agents.defaults.sandbox.sessionToolsVisibility可强制限制可见性。
配置:
json5
{
tools: {
sessions: {
// "self" | "tree" | "agent" | "all"
// 默认: "tree"
visibility: "tree",
},
},
agents: {
defaults: {
sandbox: {
// 默认: "spawned"
sessionToolsVisibility: "spawned", // 或 "all"
},
},
},
}说明:
self:仅当前会话键。tree:当前会话 + 当前会话派生的会话。agent:属于当前 Agent ID 的任意会话。all:任意会话(跨 Agent 访问仍需tools.agentToAgent)。- 当会话处于沙盒且
sessionToolsVisibility="spawned"时,OpenClaw 会将可见性强制限制为tree,即便你设置了tools.sessions.visibility="all"。