--- summary: "会话控制 RPC 系列:列出、发送、流式传输、分叉和生命周期方法" read_when: - "列出、过滤或分页会话" - "发送、流式传输或中断代理运行" - "分叉、存档或删除会话" title: "网关协议会话控制" sidebarTitle: "会话控制" doc-schema-version: 1 --- 会话控制 RPC 系列:会话列表和过滤、消息发送和流式传输、运行生命周期以及会话维护。 `chat.send` 拒绝格式错误的会话密钥、`agentId` 和代理限定密钥冲突以及与 `INVALID_REQUEST` 不明确的不限定目标。当密钥无法识别代理时,显式选择代理。 会话行包括 `snapshotAt`,即自 Unix 纪元以来网关的采样时间(以毫秒为单位)。缓存的行保留其原始采样时间。客户端使用它来订购读取快照,包括仅运行时的更改,这些更改不会提前持久化 `updatedAt`;请求顺序打破了同等时间的关系。在不采样元数据的情况下读取观察结果保留请求顺序协调。此读取时间戳不会取代事件排序或会话身份检查。 一旦会话存储被允许,直接会话目标的授权仅准备所请求的行。脏目标在授权之前必须通过存储数据验证;不相关的行继续在后台验证。准备后再次检查方法范围、配置文件绑定和启动可用性。 `sessions.list` 首先授权调用者的范围,并将行有效性和可见性过滤留给会话读取器。 `sessions.describe` 和 `sessions.get` 是连接绑定的观测值。断开连接会取消进一步的行准备重试,包括授权期间的准备、运行中准备完成后的准备。重新连接并发出新的读取以获得当前结果。接受的会话突变保留其现有的完成生命周期。 更改会话的模型或本机运行时同意可以等待运行时准备。在此等待期间,仍然可以创建或更新其他会话。对同一会话的更改保持有序,并且如果捕获的会话状态在提交之前发生更改,则准备好的更改将被拒绝。 模型目录读取 `sessions.create`、`sessions.patch`、`sessions.patchMany`,并且通过 `sessions.catalog.continue` 的网关副本共享每个请求 20 秒的预算。在受影响的会话更改提交之前,停滞的目录或取消的调用者返回可重试的 `UNAVAILABLE`。 `sessions.patchMany` 保留有序的每个目标结果;独立的成功目标仍然坚定不移。 会话列表顺序随着提交的会话元数据的变化而增量更新。每个请求在分页之前仍然应用当前的可见性、活动和时间过滤器。当存档会话的显示行从内存中释放时,它们会保留其列表位置。 项目最近使用所选会话的物理代理所有者批量读取存储库工作区。项目和会话目录列表使用提交的会话元数据,而无需等待不相关的运行时所有权或显示行准备。不确定的会话元数据和成员资格在选择之前仍然会进行协调,并且响应会在传递之前重新检查当前调用者和贡献会话身份。 GitHub 发布选项同时读取独立帐户状态和发布收据。在这些读取解决后,响应仍然检查当前会话访问和个人帐户权限。 ## 会话控制 - `sessions.catalog.list` 列出外部会话目录。当客户端需要目录 ID、标签、功能和共享路由元数据而不枚举主机或会话时,传递 `metadataOnly: true`。该模式返回 `hosts: []` 的普通目录对象;它保留代理和目录选择,跳过行 filtering/pagination,并且不发出主机进度事件。省略完整列表的标志,包括终端选择所需的主机可用性。 Control UI 对新会话选择器和“设置”中的隐藏源标签使用纯元数据发现。 - `sessions.catalog.import` (`operator.write`) 在普通网关会话中保留可读的目录记录。通过`{ catalogId, hostId, threadId, agentId?, sourceHomeId?, displayName? }`;调用者可见性和提供者解析匹配目录读取。可选 `displayName`(1–500 个字符)仅设置新创建的导入的演示文稿标题;现有的导入保留其标题。 Control UI 和 CLI `--all` 提供目录行名称(如果可用);没有标题的导入使用 `Imported session`。关闭结果为 `{ sessionKey, importedItems, totalItems, complete, created }`,具有非负整数项目计数。 `importedItems` 统计新追加的源项目,`totalItems` 统计读取的源项目,`created` 报告目标会话是否已创建。为同一代理重新导入相同的定位器会重用其会话并仅附加未见过的项目。导入保留最多 50,000 个项目或 64 MiB 的最新历史记录,并具有现有的每个项目文本限制; `complete: false` 表示较旧的历史记录被一定程度地省略。它记录源出处并将内容标记为不受信任的参考材料,无需本机延续、模型锁定或节点运行绑定。请参阅 [ 导入成绩单 ](/nodes/session-catalogs#import-transcripts)。 - `sessions.list` 返回当前会话索引,包括配置代理运行时后端时的每行 `agentRuntime` 元数据。 `hasActiveRun` 是权威的聚合直接会话活动事实。投影时,`activeRunIds` 是完整的精确活动集;空数组证明会话空闲。如果聚合活动为 true,而省略该字段,则另一个运行时所有者处于活动状态,但其确切身份不可用。快照遗漏意味着身份不可用。对于增量事件,省略意味着没有变化,`null` 是仅事件逻辑删除,可将缓存的确切 ID 清除为不可用,并用数组替换缓存。客户端仅关联他们在本地拥有的或从请求、历史记录或事件接收到的确切 ID,并且从不选择第一个列表条目作为所有者。当启用云工作线程放置或存在持久恢复状态时,会话行还包括关闭的 `placement` 状态(`local`、`requested`、`provisioning`、`syncing`、`starting`、`active`、`draining`、 `reconciling`、`reclaimed` 或 `failed`)以及特定于状态的环境、所有者纪元、工作区、捆绑包、ACK- 游标或恢复字段。工作器和终端放置可能包括 `providerId`、`profileId` 和可选的封闭 `machine` 对象:`class`(1–128 个字符)、`os` 和 `osLabel`(每个 1–64 个字符)以及整数 `cpu` 和`memoryGb`(每个 1–65,536)。每个机器字段都是可选的;未知字段和空机器摘要被省略。类和 OS 使用选定的覆盖或提供者目录默认值,标签和容量来自该目录。在目录可用之前,仅显示已知类别和 OS 覆盖。本地和请求的展示位置从不携带机器身份。活跃展示位置可能包括带有 `status`(`ok`、`warning` 或 `critical`)、`availableBytes`、`totalBytes` 和 `observedAtMs` 的咨询 `diskSpace` 示例。当网关正在传输或节点正在安装新的运行时时,配置和活动放置可能包括 `workerRuntimeInstall`:`phase`(`transferring` 或 `installing`)、`transferredBytes`、`totalBytes`、`startedAtMs` 和`updatedAtMs`。安装完成后,该进程本地进度就会清除;进度更改会发出 `sessions.changed`。活动配对设备放置还包括 `runner: { kind: "device", status: "available" | "offline", deviceId? }`; `deviceId` 命名托管放置的配对设备(用于 `autoDevice` 调度的选定主机),非设备放置省略该字段。此可用性是进程当前的,源自精确的活动环境绑定和重新连接范围的节点运行程序证明,并在网关重新启动后开始离线,直到运行程序重新连接。运行器可用性更改仅针对受影响的活动设备放置发出带键的 `sessions.changed` 快照,因此客户端无需重新加载会话列表即可更新保留的行。仅容量库存更改不会使会话行失效。行包含所有权投影 - 一次性写入 `createdActor`、可变 `owner`(参与者加上 `assignedBy`/`assignedAt`)、有界 `participants` 列表(所有者除外,最多 4 个参与者)以及完整的 `participantCount`;演员显示标签和头像是在读取时根据当前配置文件和代理身份解析的。通过 `creatorId` 通过不可变的 `createdActor.id` 进行过滤;通过 `ownerId` 按当前可分配所有者进行过滤,当未分配所有者时回退到 `createdActor`。完整的 `owners` 方面独立于分页,并且不会被任何查询过滤,因此客户端可以呈现完整的所有者选择器。经过身份验证的呼叫者可以传递 `involvingMe: true` 来仅保留呼叫者拥有或已提示的会话,并根据完整的参与者历史记录(仅限配置文件支持的人类参与者)进行评估。 - `sessions.list` 接受 `excludeDock: true` 以忽略在所有权和人员方面、计数和分页之前使用 `surface: "plugin-dock"` 创建的对话。行将 `isDock` 与 `createdSurface: "plugin-dock"` 一起公开。普通 Control UI 发现和 Workboard 名册使用此过滤器;精确会话读取和深层链接保留其正常访问检查。 `sessions.search.scope` 接受相同的过滤器。 - `sessions.list` 接受 `includeOwnerSessionCounts: true`,为有效的人性化所有者返回 `{ profileId, open, running }` 的完整 `ownerSessionCounts` 数组。计数在分页之前使用呼叫者可见的匹配会话,并将合并的配置文件解析为其主要身份。 `open` 统计未归档会话;当 `running` 具有直接执行代理轮流工作或活动委托子代理后代时,使用与会话行相同的后代活动投影,对每个对话进行一次计数。它包括仅后代工作和稍后转入保留的子会话,但不包括排队的仅直接工作和过时的存储运行状态。所有列表过滤器仍然适用。对于侧边栏范围的摘要,请省略 `agentId` 和 time/search/owner 过滤器,排除 global/unknown 标记,并使用 `excludeSubagents`、`excludeCron`、`excludeSystem` 和 `excludeDock`;小的 `limit` 不会截断计数。与基于有界关联的 `people` 方面不同,此数组不受人员选择器限制。仅当响应包含 `ownerSessionCounts` 时,不存在的配置文件才意味着零;省略的字段不会建立计数。客户端在 `sessions.changed` 上刷新此摘要,包括无密钥 visibility/profile 失效,而不是根据分页会话行或人员存在来重建它。 - `sessions.list` 首先接受 `sortBy: "activity"` 最新活动,无引脚优先级。其时间戳是最后一次完成的运行 (`lastActivityAt`) 和最后一次 user/channel 输入 (`lastInteractionAt`) 中较晚的一个。没有有效活动时间戳的会话回退到 `updatedAt`,然后是 `createdAt`;缺少时间戳则排在最后。在这种模式下,`activeMinutes` 使用相同的时间戳。过滤和排序发生在分页之前,会话键打破了时间戳关系。默认的 `updatedAt` 顺序将 pin 放在第一位,并按元数据更新年龄进行过滤; `lastInteractionAt` 保留其仅输入排序。 - 对于 `activeMinutes`,当可见候选人有年龄边界时,`sessions.list` 返回 `activityExpiresAt`。此 epoch-ms 截止日期包括所选人员和返回页面之外的候选者,因此派生视图也可能使其人员方面过期。边界是包容性的:在 `Date.now() > activityExpiresAt` 之后重读。如果没有年龄过滤器或没有候选人可以超龄,则该字段不存在;它不会取代会话更改失效。 - `sessions.list` 接受 `activityPulseBoundaries`,在调用方本地时区计算的 2–64 个严格升序纪元-毫秒边界。返回的`activityPulse.buckets`统计每个半开区间的活动;会话、运行和可选的不同人员计数涵盖了分页之前的完整过滤结果。 `started` 对 `activeMinutes` 内创建的会话进行计数,并且当该时间过滤器不存在时被忽略。 - `sessions.subscribe` 为当前 WebSocket 客户端启用会话更改事件,并接受与 `sessions.list` 相同的参数以在同一响应中返回初始列表。空 `{}` 参数仅返回订阅确认。当该客户端断开连接时订阅结束。请参阅 [ 会话列表 bootstrap](/gateway/protocol/rpc-bootstrap-and-events#session-list-bootstrap)。 - `sessions.messages.subscribe` 和 `sessions.messages.unsubscribe` 切换一个会话的 transcript/message 事件订阅。传递 `includeApprovals: true` 还可以接收已清理的 `session.approval` 生命周期事件,以进行批准,其持久受众包括该确切会话,并且其审阅者绑定授权订阅客户端。然后,订阅响应包含有界待处理 `approvalReplay`;当 `truncated` 为 false 时,它​​是权威的。对同一会话和审阅者的并发请求共享重播准备工作。干净重放读取检查过期并在一个批准存储准入中选择待批准的批准,使用读取工作线程,而不将事务排队到不相关的写入后面;到期和损坏的挂起行仍会在回复之前通过批准编写器解决。在选择待处理的重播之前,将对过期的批准进行核对。该会话和审阅者之外的批准活动不会使重播无效。如果准备过程中可见审批状态发生变化,网关会重试一次;另一项更改返回 `UNAVAILABLE` 并回滚临时订阅,以便客户端可以重试。选择加入是针对每个订阅调用的,而不是粘性的:在没有 `includeApprovals: true` 的情况下重新订阅同一会话将删除现有的批准订阅。除了正常的会话读取权限之外,此选择加入还需要配对设备上的 `operator.admin` 或 `operator.approvals`。 - `sessions.preview` 返回特定会话密钥的有界转录预览。冷记录返回 `status: "cold"` 和空 `items` 数组。批量预览请求将存档的有效负载保存在冷存储中;打开聊天或请求历史记录可以恢复它们。客户端应显示此状态的存档历史占位符。 - `sessions.storage.status` 返回每个代理的脚本计数、数据库和存档大小以及后台维护状态 (`operator.admin`)。 - `sessions.storage.run` 使用应用的策略启动或加入后台归档批处理并立即返回 (`operator.admin`)。当 `maintenance.running` 为真时,请遵循 `sessions.storage.status`。如果请求客户端断开连接,批处理将继续。请参见 [ 冷转录本存储 ](/reference/session-management-compaction/maintenance#cold-transcript-storage)。 - `sessions.describe` 返回一个网关会话行以获取确切的会话密钥,包括会话列表和聊天历史记录中报告的当前呼叫者的 `sharingRole`。 - `sessions.branches.list` 列出持久的转录分支,与结帐可用性无关。标签和活动同时更新不会使列表失效;对会话标识或读取访问权限的更改仍然会拒绝读取。 - `sessions.github.options`、`sessions.github.publish`、`sessions.github.status` 和 `sessions.github.confirm` 接受可选的 `agentId` 以及 `sessionKey`。通过所有四个调用携带所选会话的代理,特别是对于共享密钥 `global`,它无法识别其所有者。必须配置显式代理并匹配任何代理限定的会话密钥;格式错误、未知或冲突的所有者在发布前返回 `INVALID_REQUEST`。工具发起的发布仍然绑定到工具调用者的会话和代理。通过`error.details.leaseAcquisition`发布并确认租赁获取报告:`held`返回`FORBIDDEN`,记录持有者和租赁纪元; `store-unavailable` 返回可重试的 `UNAVAILABLE`,并带有封闭的 `reason` 代码(`sqlite-busy`、`lifecycle-busy` 或 `storage-error`);呼叫者取消返回不可重试的 `UNAVAILABLE`,其中包含 `aborted`、呼叫者信号原因和经过的时间。 SQLite 拥有有限写入许可。报告的存储故障清除后,重试相同的发布幂等性密钥或确认请求;获取失败不会启动发布效果。已被轮换或协调占用的工作空间仍可重试 `UNAVAILABLE`。当本机身份验证或凭证验证在后台刷新时,`sessions.github.options` 可能会返回 `stale: true` 以及缓存的帐户显示事实。本机刷新失败将停用缓存帐户;发布和 API-read 令牌轮换检查仍然需要当前身份验证。对同一注册工作树共享 Git 发现的并发 `sessions.github.options` 请求。积极的发现事实在 15 秒或注册表修改后过期;发布仍然解析实时 Git,并且每个选项读者在交付之前重新检查自己的会话和连接。 `sessions.github.options` 的处理程序截止时间为五秒,并在超时时返回可重试的 `UNAVAILABLE`。重试选项发现;过期可防止延迟交付和进一步读取步骤,而无需取消生命周期服务已拥有的 OAuth 令牌轮换。 - `sessions.resolve` 通过密钥、原始会话 ID、标签、Control UI 短 ID 或 `reference: { key, slug? }` 解析或规范化会话目标。参考搜索可见的活动和存档会话:其精确的规范化密钥获胜,然后将可选的显示名称段与 UUID- 支持的会话进行匹配。参考发现保留会话列表可见性规则;单独的 `key` 选择器保留精确键读取语义。不明确的参考文献和短 ID 最多返回 10 个候选者作为成功的 RPC 结果。设置 `allowMissing: true` 以在没有会话匹配时接收 `{ ok: false }`。 - `sessions.create` 创建一个新的会话条目。在具有 `agents.ownership: "explicit"` 的队列中,具有代理资格 `parentSessionKey` 且没有 `key` 或 `agentId` 的请求会在父代理下创建子代理。显式子密钥或 `agentId` 保持优先级,旧队列保持其现有的默认位置。当应用沙箱遏制时,将根据所选代理的已解析工作区检查本地 `cwd` 和项目路径:接受其中的别名,并拒绝在其外部解析的符号链接。可选的 `model`、`contextWindow` 和 `thinkingLevel` 值以原子方式保留初始模型、通告的上下文窗口选择和推理覆盖;可选 `category` 将会话分配给自定义组并在首次使用时注册该组。 `worktree: true` 提供托管工作树;可选 `worktreeBaseRef`/`worktreeName` 选择基本引用和分支名称,`execNode` (`operator.admin`) 将会话 exec 绑定到节点主机。如果没有 `worktreeName`,OpenClaw 会从会话标签或生成的第一条消息标题中派生出一个可读的名称,然后回退到甲壳类主题的名称;已被其他所有者、本地分支或非托管路径占用的名称会收到数字后缀。创建的工作树在结果中回显并保留在会话行 (`worktree: { id, branch, repoRoot }`) 中。当条目创建但其嵌套首字母`chat.send`被拒绝时,成功结果包括`runStarted: false`和`runError`;客户端可以保留提示并根据返回的会话密钥重试。使用 `emitCommandHooks: true` 传递 `parentSessionKey` 的调用者还应该声明不同子级的生命周期处置:`succeedsParent: true` 以 `session_end` 结束父级,而 `false` 保持父级活动并仅发出子级的 `session_start`。省略 `succeedsParent` 会保留现有客户端的旧父级翻转行为。该配置需要父链接和命令挂钩;分叉无法继承其父级。主会话重置行为未更改,因为没有创建不同的子会话。新行标记有来自可信创建路径的一次写入创建来源(`createdVia`、`createdActor`、`createdAt`);采用现有密钥永远不会重新标记它。对于人类配置文件参与者,当投影行时,`createdActor.label` 是从当前用户配置文件解析的,并且永远不会存储在会话条目中,因此配置文件重命名不会漂移。会话行还携带 `parentSessionKey`(导航父级,持久化)、`controlOwnerSessionKey`(实时运行时控制器)、`forkSource`(精确的源密钥 + 分叉的转录本生成)和 `previousSessionId`(同一密钥下的先前转录本生成)。 - `sessions.dispatch` 将授权的本地 OpenClaw 或 Codex 会话与实时、注册表拥有的会话管理工作树移动到配对设备或配置的云配置文件。对于显式设备,传递 `{ key, deviceId, agentId? }`;对于自动配对设备选择,传递 `{ key, autoDevice: true, agentId? }`;对于显式配置文件,传递 `{ key, profileId, machineClass?, agentId? }`;或者通过 `{ key, agentId? }` 在 `cloudWorkers.projectProfiles` 中查找托管工作树的规范化源。这些目标模式是互斥的,显式目标优先于项目配置文件查找。自动选择首先根据相对于工作人员容量的已承认工作对工作槽运行时间进行排名,然后根据待处理调度后的空闲槽位进行排名,最后根据设备 ID 进行排名;没有工作插槽的运行时使用设备 ID 顺序。只有在工作区准备开始之前检测到的主机资格失败才会在清理任何失败的分配后重试,总共最多三个排名候选者。其他错误立即返回;工作区准备和已经开始的工作永远不会重播。显式自动设备调度需要`operator.write`;显式配置文件和项目配置文件调度需要 `operator.admin`。缺少源、不匹配的映射或映射到未配置的配置文件会返回类型化的 `INVALID_REQUEST`,而无需配置或回退到另一个目标。格式错误的参数在模式验证之前使用写入范围。丢失的云配置文件仅隐藏云目标;符合条件的配对设备调度仍然可用。 Dispatch 在耗尽活动工作之前关闭本地轮流准入,并且仅在布局达到​​ `active` 后才返回,其中 `worker-turn` 具有工作子所有权,或者 `remote-exec` 具有网关拥有的harness执行。任意普通目录是不可分派的;准入后,如果托管工作树的 Git 元数据稍后变得不可用,工作区传输可能会使用清单镜像。 SSH 后备候选者仅针对安全重复检查、内容寻址传输、receipt/lock-guarded 工件安装、聚合托管工作树镜像和隧道重新连接进行轮换。不明确的不受保护的状态命令将被拒绝并且不会重播。调度是单向的;工人到本地的回调不属于此 RPC 的一部分。 - `sessions.reclaim` (`operator.write`) 通过密钥安全地停止会话放置。它等待正在进行的调度,排出已承认的工作,协调活动工作区更改,并通过布置所有者重试挂起的失败环境拆卸。调用者永远不需要原始环境破坏权限。 - `sessions.move` 将授权的活动会话移动到网关、配对设备或配置的配置文件。网关和设备目标需要 `operator.write`;配置文件目标需要 `operator.admin`;格式错误的目标在模式验证之前使用写入范围。调用者提供准确的观察到的世代、环境和所有者时代;会话授权和这些源事实在移动提交之前重新验证。平常举动总能调和源头。只有网关目标可以添加 `abandonSource: true`,并且仅当确切源是当前离线配对设备放置时。该持久决策强制隔离并破坏远程所有者,跳过远程工作区协调,并从最后一个网关同步状态继续,无需重播;未同步的文件和正在进行的工作可能会丢失。可用的、未知的、个人资料和其他工人来源拒绝明确放弃。 - `sessions.groups.list`、`sessions.groups.put`、`sessions.groups.rename`和`sessions.groups.delete`管理网关拥有的自定义会话组目录(名称+显示顺序)。读取范围的列表结果故意是无路径的。 `sessions.groups.defaults` 和 `sessions.groups.update` 需要 `operator.write` 并读取或替换一个自定义组的可选工作目录和工作树默认值。非管理员调用者只能保存配置的代理工作区中的目录;其他绝对网关路径需要 `operator.admin`。成员身份保留在每个会话的 `category` 字段中;重命名和删除更新成员会话服务器端。 `sessions.groups.put` 仅替换名单和顺序,并拒绝删除仍具有成员会话的组 - 首先将其显式删除。删除组参与与删除相同的成员会话授权。 - `sessions.send` 向现有会话发送消息。 - `sessions.files.list` 和 `sessions.files.get` 列出并预览可见会话的文件。根内文件需要会话读取访问权限。根外读取需要该会话的网关主机文件工具访问权限以及在此处开始轮次的当前权限;成功的根外预览会忽略 `hash` 并保持只读状态。 `sessions.files.set` 保留现有文件的工作空间包含和基于散列的比较和交换。 - `sessions.files.assets` 接受 `{ sessionKey, agentId?, path, refs }`,其中 `path` 是 HTML 文件返回的 `workspacePath` 或 `path`,而 `refs` 包含从其文件夹解析的相关资源 URL。它使用与 `sessions.files.get` 相同的当前会话读取边界。每个调用最多接受 64 个引用,最多 4,096 个字符,每个资产有 1 个 MiB,在 Base64 编码之前有 4 个 MiB 聚合字节上限。云存储库检查保留了更严格的 256 KiB 每个文件预览上限和已停止的存储库工件可用性。它返回 `{ assets }`,每个条目要么是包含 base64 字节的 `{ ref, mimeType, content }` 要么是 `{ ref, error }`,其中 `error` 是 `not_found`、`too_large`、`outside_session_boundary` 或 `unsupported`。不支持方案、协议相关和仅片段引用。 `canvas.document.preview` 接受调用者提供的 HTML 和隔离沙箱元数据的会话读取访问权限;它不读取会话数据。 - `sessions.steer` 是 `chat.send` 和 `queueMode: "interrupt"` 的已弃用别名;删除遵循协议弃用政策。 - `sessions.abort` 中止会话的活动工作,包括在运行程序启动之前允许或在没有网关聊天控制器的情况下排队的运行(例如 OpenAI- 兼容的 HTTP 请求)以及活动通道回复。会话范围的 `chat.abort { sessionKey }` 也涵盖了这些运行,而不会级联到子级。当该运行具有已知运行 ID 时,`chat.abort` 将其返回为 `runIds`,`sessions.abort` 将其返回为 `abortedRunId`。通过 `key` 加上可选的 `runId` 或单独的 `runId` 来进行网关可以解析为会话的活动运行。提供 `runId` 可以使取消范围保持在该运行范围内。当所选运行已完成并且没有剩余匹配工作时,调用将成功,并显示 `status: "no-active-run"` 和 `abortedRunId: null`。在仅密钥非全局请求上设置 `clearQueued: true`,以同时丢弃该会话拥有的后续队列和通道队列。省略 `clearQueued` 的现有调用者将保留这些队列。文字 `global` 密钥保留现有的代理合格 `chat.abort` 所有权规则,并且不执行非全局后续或通道清理。 - `sessions.patch` 更新会话 metadata/overrides 并报告标准化模型 ID 加上有效的 `agentRuntime`。 `contextWindow` 仅接受所选模型的 `contextWindows` 数组通告的 id; `null` 恢复 `contextWindowDefault`。会话组织字段和每会话 `model`、`thinkingLevel` 和 `fastMode` 覆盖需要 `operator.write`,包括使用 `null` 清除覆盖。相同的字段策略适用于 `sessions.patchMany`。上下文窗口、详细、跟踪、推理可见性、工具和其他特权覆盖仍然需要 `operator.admin`;将它们与写入范围的字段结合起来并不会降低该要求。只有管​​理模型选择可以保留为配置的代理默认值。在多用户网关上,存档和恢复还需要会话创建者或 `operator.admin`;成员资格和分配的所有权不授予存档访问权限。存档、恢复、暂停和唤醒补丁需要调用者观察到的 `sessionId` 从 `sessions.list` 或 `sessions.describe` 为 `expectedSessionId`;丢失或更改的目标会失败,而不会实现或改变替代品。通过 `archived: true`,网关可以保护代理主会话(配置全局范围时包括 `global`)和 `unknown` 哨兵;对于每个其他真实会话,它首先隔离新的准入,取消确切的会话活动、挂起、排队、回复、嵌入和工作人员工作,并在提交 `archivedAt` 之前等待准入和运行时终端持久性耗尽。取消、耗尽或持久性失败将返回可重试的 `UNAVAILABLE` 并使会话保持未归档状态。 `sessions.patchMany` 每个目标携带 `expectedSessionId`,在同一批次生命周期栅栏内按输入顺序准备存档目标,并返回有序的每个目标结果。生成沿袭(`spawnedBy`、`spawnedWorkspaceDir`、`spawnedCwd`、`spawnDepth`、`subagentRole`、`subagentControlScope`)不再可公开修补;这些事实由受信任的创建路径写入一次,并且仍然发送它们的请求将被拒绝。 - `sessions.patch` 收据包括会话元数据和已解析的 model/runtime 事实。其`entry`省略了保存的`skillsSnapshot`和`systemPromptReport`;两个快照都通过显示元数据补丁保持不变。 - `sessions.patch { snoozedUntil }` 设置未来的正整数唤醒时间(以纪元毫秒为单位); `null` 清除贪睡。当唤醒时间发生变化时,网关会标记 `snoozedAt`,并将其保留为相同的值。 Snooze 接受符合固定条件的活动会话,并拒绝与存档相同的受保护目标以及存档会话和子会话。它使会话保持活动状态并保持其引脚完整,没有生命周期耗尽、自动化禁用、工作树转换或工作准入更改。固定或存档可清除暂停。真实的 user/channel 交互和更新面向用户的活动的完整运行也清除了它;系统事件和保留状态运行则不然。会话行公开 `snoozedUntil` 和 `snoozedAt`,因此客户端将唤醒时间与自己的时钟进行比较。时间到期不会发出任何事件并留下陈旧的字段,直到稍后的写入清除它们;显式休眠和唤醒补丁会发布正常的 `sessions.changed` 事件,原因为 `patch`。 `sessions.list` 不会通过贪睡进行过滤。 - `sessions.assignOwner` (`operator.write`) 将会话的可变所有者重新分配给人员或配置的代理 (`{ key, owner: { type, id } }`)。它需要已识别的调用者(经过身份验证的配置文件或受信任的代理身份),通过会话可见性进行授权,并在该行的 `owner` 字段中记录 `assignedBy`/`assignedAt`。一次写入`createdActor`和创建者锚定共享权限不变;请参见 [ 多用户模式](/concepts/multi-user#assigning-an-owner)。 - `sessions.reset`、`sessions.delete`、`sessions.compact`执行会话维护。在重置清理或突变之前,无法识别代理的显式 `agentId` 值将被拒绝;他们永远不会退回到默认代理。 `sessions.reset` 接受来自 `sessions.list` 或 `sessions.describe` 的可选 `expectedSessionId`。如果在重置进入其生命周期围栏时该会话 ID 不再是当前会话,则网关会在中断与 `INVALID_REQUEST` 和 `error.details.reason: "session-changed"` 的工作之前拒绝该请求;在决定是否重试之前重新读取会话。省略该字段将保留无条件重置行为。守卫不会拒绝保持同一会话 ID 的更改,包括元数据编辑或其他就地重置。 - `sessions.get` 返回 `{ messages }`,其中包含来自 OpenClaw- 拥有的所选会话的存储记录的最新消息。它不导入外部 CLI 成绩单。使用 `sessions.describe` 作为会话元数据,使用 `chat.history` 作为显示标准化对话。 - Chat 执行仍使用 `chat.history`、`chat.send`、`chat.abort` 和 `chat.inject`。其 `sessionInfo` 使用与 `sessions.list` 相同的聚合 `hasActiveRun` 和可选的完全精确 `activeRunIds` 语义。 `chat.history` 针对 UI 客户端进行了显示标准化:内联指令标签、纯文本工具调用 XML 有效负载(`...`、`...`、`...`、`...` 和截断的工具调用块)和泄漏ASCII/full-width 模型控制令牌被剥离。存储的助手可见性首先尊重显示、相位和最终源事实,然后省略修剪为大写 `NO_REPLY` 的原始助手文本;小写和换行形式仍然可见。用户文本永远不会被归类为静音。过大的行可以用占位符替换。对于符合条件的 Claude CLI 绑定,`chat.history` 将外部转录消息与本地消息合并。这些合并的快照仍然是有字节限制的;终端快照不能保证完整的对话历史记录。尾部响应可以包括不透明的 `deltaCursor`。将其作为 `cursor` 传递回 `chat.history` 或 `chat.startup`,而不是 `offset` 或 `messageId`。成功追赶返回`{ kind: "delta", messages, deltaCursor, sessionInfo, inFlightRun? }`;通过与实时 `session.message` 有效负载相同的减速器重放每个 `messages` 条目,然后协调可选的有界 `inFlightRun` 快照,就像正常的尾部响应一样。未更改的历史记录返回一个空的 `messages` 数组,其中包含当前会话元数据和请求的输入收据。 `{ kind: "reset" }` 表示光标无效、过时、属于另一个会话、跨越了重置、压缩或分支选择,或者落后太多;获取正常的尾页。追赶永远不会返回部分页面或延续:超过 200 个原始事件或其字节预算重置为尾部提取。所有历史页面都使用512 KiB消息预算; `maxBytes`可以降低它。超大源行(包括不可分割的显示组)将成为其原始 `__openclaw.id` 和 `truncated: true` 的参考。通过`chat.message.get`读取;存储的转录字节保持不变。锚定的 `messageId` 读取可以返回不透明的 `olderCursor` 和 `newerCursor` 值。将任一 `cursor` 传回,并使用相同的 `sessionKey` 和可选的 `agentId` 继续朝该方向前进。这些响应使用整页形状,而不是三角形形状。当方向光标存在时继续浏览空白页面;隐藏的行仍然使光标前进。光标保留所选的物理会话和转录源; `windowReset: true` 表示源不再可用,调用者必须重新打开锚点。响应预算不会缩短错误恢复前瞻。锚定读取及其延续需要当前共享访问权限。删除后会删除逻辑会话条目但保留其记录,直接历史读取需要 `operator.admin`。 `cron.history` 单独验证对其记录的自动化运行和脚本的访问。在加载历史记录之前会检查访问权限,并在发布历史记录之前再次检查访问权限。 - `chat.message.get` 是单个可见转录本条目的附加有界完整消息阅读器。传递 `sessionKey`、可选的 `agentId`(当会话选择是代理范围时)以及之前通过 `chat.history` 出现的文字记录 `messageId`;当存储的条目仍然可用且尺寸未过大时,网关将返回相同的显示标准化投影,而无需轻量级历史截断上限。从保留的物理会话中获取引用时,传递历史页面的 `sessionId`;相同的会话所有权和当前共享检查适用。 `maxChars` 每个文本字段最多接受 8,000,000 个字符,以实现大型引用输出;序列化响应必须仍然符合 WebSocket 有效负载限制。 - `chat.toolTitles` 已弃用。它验证现有的有界请求形状并返回 `{ titles: {}, disabled: true }`,以便旧客户端停止请求标题。它不进行模型调用,也不访问旧的标题缓存。当前的 Control UI 客户端自动显示工具调用提供的描述。 - `chat.send` 接受一回合 `fastMode: "auto"` 以使用快速模式进行自动切断之前启动的模型调用,然后在没有快速模式的情况下启动稍后重试、回退、工具结果或继续调用。截止时间默认为 60 秒 (`DEFAULT_FAST_MODE_AUTO_ON_SECONDS`),并且可以使用 `agents.defaults.models["/"].params.fastAutoOnSeconds` 针对每个模型进行配置。 `chat.send` 调用者可以传递一圈 `fastAutoOnSeconds` 来覆盖该请求的截止。通过 `queueMode`(`steer`、`followup`、`collect` 或 `interrupt`)仅覆盖此请求的存储队列模式;显式 Control UI 转向操作使用 `queueMode: "steer"`。中断模式捕获并中止会话当前允许的轮次,等待确切的所有者解决,然后开始新的轮次;空闲会话正常启动。引导发送以选定会话的当前状态为目标:网关自动将消息注入该会话的直接活动运行,或者在会话空闲时启动新的轮次。后代子代理会话中的活动永远不会使选定的会话忙于此决策。 `expectedLeafEntryId` 是用于非引导交互式发送的独立转录分支比较和交换:传递显示的分支叶(或有意的 `null` 用于权威的空转录),如果另一个客户端首先切换转录分支,则发送会拒绝 `details.reason: "active-leaf-changed"` ;转向发送忽略它。 - `chat.send`、`sessions.send` 和初始转 `sessions.create` 确认报告与成绩单持久性分开。可选的 `messageSeq` 是来自实际承诺的用户回合收据的基于 1 的位置;它不存在,而输入仅存在于待决监管中。 `status: "started"` 和 `runStarted: true` 单独不建立转录本行。通过其提交身份与接受的保管或存储的转录本身份来协调临时输入,而不是预测的位置或匹配的内容。 - `sessions.create` 和 `fork: true` 根据子项选定的运行时容量和创作的模型上限检查父级成绩单。本机运行时不借用同一模型的 API 容量。当所选运行时没有已知或配置的容量时,现有的 100,000 个代币分叉限制适用;超大父母在复制历史记录之前返回 `INVALID_REQUEST`。 - `sessions.create.fastMode` 接受 `true`、`false` 或 `"auto"` 并在初始转弯开始前保持该速度覆盖。 - `sessions.create.label` 声明物理会话存储中的显式标签,包括存档会话。标签经过修剪且区分大小写。具有不同密钥的并发创建不能声明相同的标签:失败的请求收到 `INVALID_REQUEST` 和 `label already in use: