chore(i18n): refresh zh-CN translations

This commit is contained in:
openclaw-docs-i18n[bot] 2026-04-24 04:22:33 +00:00
parent 3a60036892
commit 4aeacdc9c4
8 changed files with 1524 additions and 924 deletions

View File

@ -1,23 +1,26 @@
---
read_when:
- 你想了解 OpenClaw 如何组装模型上下文
- 你正在切换旧版引擎与插件引擎
- 你正在旧版引擎和插件引擎之间切换
- 你正在构建一个上下文引擎插件
summary: 上下文引擎:可插拔的上下文组装、压缩子智能体生命周期
summary: 上下文引擎:可插拔的上下文组装、压缩子智能体生命周期
title: 上下文引擎
x-i18n:
generated_at: "2026-04-23T22:56:25Z"
generated_at: "2026-04-24T04:20:42Z"
model: gpt-5.4
provider: openai
source_hash: 0a84953df3ecac8ebfc194e802858a6b155bf6764a4faaeea632018186bd3833
source_hash: 8f4e5f01f945f7fe3056587f2aa60bec607dd0dd64b29e9ab2afe8e77b5d2f1e
source_path: concepts/context-engine.md
workflow: 15
---
**上下文引擎** 控制 OpenClaw 如何为每次运行构建模型上下文:
包括要包含哪些消息、如何总结较早的历史记录,以及如何跨子智能体边界管理上下文。
**上下文引擎**控制 OpenClaw 如何为每次运行构建模型上下文:
包含哪些消息、如何总结较早的历史记录,以及如何跨子智能体边界管理
上下文。
OpenClaw 内置了一个 `legacy` 引擎,并默认使用它——大多数用户无需更改。只有当你希望使用不同的组装、压缩或跨会话召回行为时,才需要安装并选择插件引擎。
OpenClaw 内置了 `legacy` 引擎,并默认使用它——大多数
用户都不需要更改。只有当你想要不同的组装、压缩或跨会话召回行为时,
才需要安装并选择插件引擎。
## 快速开始
@ -25,35 +28,36 @@ OpenClaw 内置了一个 `legacy` 引擎,并默认使用它——大多数用
```bash
openclaw doctor
# or inspect config directly:
# 或直接检查配置:
cat ~/.openclaw/openclaw.json | jq '.plugins.slots.contextEngine'
```
### 安装上下文引擎插件
上下文引擎插件的安装方式与其他 OpenClaw 插件相同。先安装,再在插槽中选择该引擎:
上下文引擎插件的安装方式与其他 OpenClaw 插件相同。先安装,
然后在插槽中选择该引擎:
```bash
# Install from npm
# 从 npm 安装
openclaw plugins install @martian-engineering/lossless-claw
# Or install from a local path (for development)
# 或从本地路径安装(用于开发)
openclaw plugins install -l ./my-context-engine
```
然后在配置中启用该插件,并将其选为当前激活的引擎:
然后在你的配置中启用该插件,并将其选为当前激活的引擎:
```json5
// openclaw.json
{
plugins: {
slots: {
contextEngine: "lossless-claw", // must match the plugin's registered engine id
contextEngine: "lossless-claw", // 必须与插件注册的引擎 id 匹配
},
entries: {
"lossless-claw": {
enabled: true,
// Plugin-specific config goes here (see the plugin's docs)
// 插件特定配置写在这里(参见该插件的文档)
},
},
},
@ -62,40 +66,61 @@ openclaw plugins install -l ./my-context-engine
安装并配置后,重启 Gateway 网关。
如需切换回内置引擎,请将 `contextEngine` 设为 `"legacy"`(或直接删除该键——`"legacy"` 是默认值)。
若要切换回内置引擎,将 `contextEngine` 设为 `"legacy"`(或者
直接删除该键——`"legacy"` 是默认值)。
## 工作原理
每次 OpenClaw 运行模型提示词时,上下文引擎都会参与以下四个生命周期节点:
每次 OpenClaw 运行模型提示词时,上下文引擎都会参与
四个生命周期阶段:
1. **摄取** — 当新消息被添加到会话时调用。引擎可以将该消息存储或索引到自己的数据存储中。
2. **组装** — 在每次模型运行前调用。引擎返回一组按顺序排列、且能适配 token 预算的消息(以及一个可选的 `systemPromptAddition`)。
3. **压缩** — 当上下文窗口已满,或者用户运行 `/compact` 时调用。引擎会总结较早的历史记录以释放空间。
4. **轮次后处理** — 在一次运行完成后调用。引擎可以持久化状态、触发后台压缩或更新索引。
1. **摄取**——当新消息被添加到会话时调用。引擎
可以将该消息存储或索引到它自己的数据存储中。
2. **组装**——在每次模型运行前调用。引擎返回一组按顺序排列的
消息(以及可选的 `systemPromptAddition`),这些内容会适配
token 预算。
3. **压缩**——当上下文窗口已满,或当用户运行
`/compact` 时调用。引擎会总结较早的历史记录以释放空间。
4. **轮次结束后**——在一次运行完成后调用。引擎可以持久化状态、
触发后台压缩,或更新索引。
对于内置的非 ACP Codex harnessOpenClaw 通过将已组装的上下文投射到
Codex 开发者指令和当前轮次提示词中应用相同的生命周期。Codex 仍然保留
其原生线程历史记录和原生压缩器。
### 子智能体生命周期(可选)
OpenClaw 会调用两个可选的子智能体生命周期钩子:
- **prepareSubagentSpawn** — 在子运行开始前准备共享上下文状态。该钩子会接收父 / 子会话键、`contextMode``isolated` 或 `fork`)、可用的 transcript ID / 文件,以及可选的 TTL。如果它返回一个回滚句柄则当准备成功后但 spawn 失败时OpenClaw 会调用它。
- **onSubagentEnded** — 当子智能体会话完成或被清理时执行清理。
- **prepareSubagentSpawn**——在子运行开始前准备共享上下文状态。
该钩子接收父/子会话键、`contextMode`
`isolated` 或 `fork`)、可用的转录 id/文件,以及可选的 TTL。
如果它返回一个回滚句柄,那么当准备成功后生成失败时,
OpenClaw 会调用它。
- **onSubagentEnded**——在子智能体会话完成或被清理时执行清理。
### 系统提示补充
### 系统提示词追加内容
`assemble` 方法可以返回一个 `systemPromptAddition` 字符串。OpenClaw 会将其前置到本次运行的系统提示中。这使引擎能够注入动态召回指导、检索说明或具备上下文感知的提示,而无需依赖静态工作区文件。
`assemble` 方法可以返回一个 `systemPromptAddition` 字符串。OpenClaw
会将其预置到本次运行的系统提示词前面。这让引擎能够注入
动态召回指引、检索指令或上下文感知提示,
而无需依赖静态工作区文件。
## legacy 引擎
内置的 `legacy` 引擎保留了 OpenClaw 的原始行为:
- **摄取**:空操作(会话管理器会直接处理消息持久化)。
- **组装**:直通(运行时中的现有 sanitize → validate → limit 流程会处理上下文组装)。
- **压缩**:委托给内置的总结式压缩,它会为较早的消息创建单一摘要,并保留最近消息不变。
- **轮次后处理**:空操作。
- **摄取**:无操作(会话管理器会直接处理消息持久化)。
- **组装**:直通(运行时中的现有 sanitize → validate → limit 流水线
负责处理上下文组装)。
- **压缩**:委托给内置的总结式压缩,它会对较早的消息生成
单一摘要,并保留最近的消息不变。
- **轮次结束后**:无操作。
legacy 引擎不会注册工具,也不会提供 `systemPromptAddition`
当未设置 `plugins.slots.contextEngine`(或其值设为 `"legacy"`)时,会自动使用此引擎。
当未设置 `plugins.slots.contextEngine`(或者它被设为 `"legacy"`)时,
会自动使用该引擎。
## 插件引擎
@ -113,12 +138,12 @@ export default function register(api) {
},
async ingest({ sessionId, message, isHeartbeat }) {
// Store the message in your data store
// 将消息存储到你的数据存储中
return { ingested: true };
},
async assemble({ sessionId, messages, tokenBudget, availableTools, citationsMode }) {
// Return messages that fit the budget
// 返回适配预算的消息
return {
messages: buildContext(messages, tokenBudget),
estimatedTokens: countTokens(messages),
@ -130,7 +155,7 @@ export default function register(api) {
},
async compact({ sessionId, force }) {
// Summarize older context
// 总结较早的上下文
return { ok: true, compacted: true };
},
}));
@ -160,43 +185,56 @@ export default function register(api) {
| 成员 | 类型 | 用途 |
| ------------------ | -------- | ---- |
| `info` | 属性 | 引擎 ID、名称、版本以及它是否拥有压缩控制权 |
| `info` | 属性 | 引擎 id、名称、版本以及它是否负责压缩 |
| `ingest(params)` | 方法 | 存储单条消息 |
| `assemble(params)` | 方法 | 为模型运行构建上下文(返回 `AssembleResult` |
| `compact(params)` | 方法 | 总结 / 缩减上下文 |
| `assemble(params)` | 方法 | 为一次模型运行构建上下文(返回 `AssembleResult` |
| `compact(params)` | 方法 | 总结/缩减上下文 |
`assemble` 返回一个 `AssembleResult`其中包含:
`assemble` 返回一个 `AssembleResult`,包含:
- `messages` — 要发送给模型的有序消息。
- `estimatedTokens`(必需,`number`)— 引擎对已组装上下文总 token 数的估算。OpenClaw 会将其用于压缩阈值决策和诊断报告。
- `systemPromptAddition`(可选,`string`)— 前置到系统提示中的内容。
- `messages`——发送给模型的有序消息。
- `estimatedTokens`(必需,`number`)——引擎对
已组装上下文总 token 数的估算。OpenClaw 会将其用于压缩阈值
决策和诊断报告。
- `systemPromptAddition`(可选,`string`)——预置到系统提示词前面的内容。
可选成员:
| 成员 | 类型 | 用途 |
| ------------------------------ | ------ | ---- |
| `bootstrap(params)` | 方法 | 为会话初始化引擎状态。当引擎首次看到某个会话时调用一次(例如导入历史记录)。 |
| `ingestBatch(params)` | 方法 | 以批处理方式摄取一个已完成轮次。在一次运行完成后调用,并一次性传入该轮次的所有消息。 |
| `ingestBatch(params)` | 方法 | 批量摄取一个已完成的轮次。在一次运行结束后调用,且该轮次的所有消息会一次性传入。 |
| `afterTurn(params)` | 方法 | 运行后的生命周期工作(持久化状态、触发后台压缩)。 |
| `prepareSubagentSpawn(params)` | 方法 | 在子会话开始前为其设置共享状态。 |
| `onSubagentEnded(params)` | 方法 | 在子智能体结束后执行清理。 |
| `dispose()` | 方法 | 释放资源。在 Gateway 网关关闭或插件重新加载时调用——不是按会话调用。 |
| `dispose()` | 方法 | 释放资源。在 Gateway 网关关闭或插件重载时调用——不是按会话调用。 |
### ownsCompaction
`ownsCompaction` 控制 Pi 内置的单次尝试内自动压缩在本次运行中是否保持启用:
`ownsCompaction` 控制 Pi 的内置单次尝试内自动压缩是否在本次运行中
保持启用:
- `true` — 该引擎拥有压缩行为的控制权。OpenClaw 会为该次运行禁用 Pi 内置的自动压缩,而引擎的 `compact()` 实现将负责 `/compact`、溢出恢复压缩,以及它希望在 `afterTurn()` 中执行的任何主动压缩。
- `false` 或未设置 — Pi 内置的自动压缩仍可能在提示词执行期间运行,但激活引擎的 `compact()` 方法仍会在 `/compact` 和溢出恢复时被调用。
- `true`——该引擎负责压缩行为。OpenClaw 会为该次运行禁用 Pi 的内置
自动压缩,而引擎的 `compact()` 实现则负责处理 `/compact`
溢出恢复压缩,以及它希望在 `afterTurn()` 中执行的任何主动
压缩。
- `false` 或未设置——Pi 的内置自动压缩仍可能在提示词
执行期间运行,但当前激活引擎的 `compact()` 方法仍会用于
`/compact` 和溢出恢复。
`ownsCompaction: false` **并不** 意味着 OpenClaw 会自动回退到 legacy 引擎的压缩路径。
`ownsCompaction: false` **并不**意味着 OpenClaw 会自动回退到
legacy 引擎的压缩路径。
这意味着插件有两种有效模式:
这意味着存在两种有效的插件模式:
- **拥有模式** — 实现你自己的压缩算法,并设置 `ownsCompaction: true`
- **委托模式** — 设置 `ownsCompaction: false`,并让 `compact()` 调用 `openclaw/plugin-sdk/core` 中的 `delegateCompactionToRuntime(...)`,以使用 OpenClaw 的内置压缩行为。
- **接管模式**——实现你自己的压缩算法,并设置
`ownsCompaction: true`
- **委托模式**——设置 `ownsCompaction: false`,并让 `compact()` 调用
`openclaw/plugin-sdk/core` 中的 `delegateCompactionToRuntime(...)`
以使用 OpenClaw 的内置压缩行为。
对于一个处于激活状态且不拥有压缩控制权的引擎来说,空操作的 `compact()` 是不安全的,因为这会禁用该引擎插槽的正常 `/compact` 和溢出恢复压缩路径。
对于一个处于激活状态的非接管引擎来说,无操作的 `compact()` 是不安全的,因为它
会禁用该引擎插槽的常规 `/compact` 和溢出恢复压缩路径。
## 配置参考
@ -204,33 +242,57 @@ export default function register(api) {
{
plugins: {
slots: {
// Select the active context engine. Default: "legacy".
// Set to a plugin id to use a plugin engine.
// 选择当前激活的上下文引擎。默认值:"legacy"。
// 设为某个插件 id 即可使用插件引擎。
contextEngine: "legacy",
},
},
}
```
该插槽在运行时是互斥的——对于给定的一次运行或压缩操作,只会解析一个已注册的上下文引擎。其他已启用的 `kind: "context-engine"` 插件仍然可以加载并运行其注册代码;`plugins.slots.contextEngine` 只负责选择当 OpenClaw 需要上下文引擎时要解析哪个已注册引擎 ID。
该插槽在运行时是互斥的——对于一次给定的运行或压缩操作,只会解析
一个已注册的上下文引擎。其他已启用的
`kind: "context-engine"` 插件仍然可以加载并运行其注册
代码;`plugins.slots.contextEngine` 只决定当 OpenClaw 需要上下文引擎时,
它会解析哪个已注册的引擎 id。
## 与压缩和记忆的关系
- **压缩** 是上下文引擎的职责之一。legacy 引擎会委托给 OpenClaw 的内置总结机制。插件引擎可以实现任意压缩策略DAG 摘要、向量检索等)。
- **记忆插件**`plugins.slots.memory`)与上下文引擎是分离的。记忆插件提供搜索 / 检索;上下文引擎控制模型能看到什么。两者可以协同工作——上下文引擎可能会在组装期间使用记忆插件的数据。希望使用激活记忆提示路径的插件引擎,优先应使用 `openclaw/plugin-sdk/core` 中的 `buildMemorySystemPromptAddition(...)`,它会将当前激活的记忆提示片段转换为可直接前置的 `systemPromptAddition`。如果某个引擎需要更底层的控制,它仍然可以通过 `openclaw/plugin-sdk/memory-host-core` 中的 `buildActiveMemoryPromptSection(...)` 提取原始行。
- **会话修剪**(在内存中裁剪旧工具结果)仍会运行,无论当前激活的是哪个上下文引擎。
- **压缩**是上下文引擎的一项职责。legacy 引擎
委托给 OpenClaw 的内置总结机制。插件引擎可以实现
任意压缩策略DAG 摘要、向量检索等)。
- **记忆插件**`plugins.slots.memory`)与上下文引擎是分开的。
记忆插件提供搜索/检索;上下文引擎控制
模型看到什么。它们可以协同工作——上下文引擎可能会在
组装期间使用记忆插件的数据。想要使用当前激活记忆
提示路径的插件引擎,应优先使用
`openclaw/plugin-sdk/core` 中的 `buildMemorySystemPromptAddition(...)`
它会把当前激活的记忆提示部分转换成可直接预置的
`systemPromptAddition`。如果引擎需要更底层的
控制,它仍然可以通过
`openclaw/plugin-sdk/memory-host-core` 中的
`buildActiveMemoryPromptSection(...)`
拉取原始行内容。
- **会话裁剪**(在内存中修剪旧的工具结果)仍会运行,
无论当前激活的是哪个上下文引擎。
## 提示
- 使用 `openclaw doctor` 验证你的引擎是否已正确加载。
- 如果切换引擎,现有会话会继续保留当前历史记录。新引擎会接管后续运行。
- 引擎错误会被记录并显示在诊断信息中。如果插件引擎注册失败,或者无法解析所选引擎 IDOpenClaw 不会自动回退;运行会失败,直到你修复插件,或将 `plugins.slots.contextEngine` 切回 `"legacy"`
- 在开发过程中,使用 `openclaw plugins install -l ./my-engine` 可以链接本地插件目录,而无需复制。
- 使用 `openclaw doctor` 验证你的引擎是否正确加载。
- 如果切换引擎,现有会话会继续保留其当前历史记录。
新引擎将接管后续运行。
- 引擎错误会被记录并显示在诊断中。如果插件引擎
注册失败,或无法解析所选引擎 idOpenClaw
不会自动回退;运行会失败,直到你修复插件或
`plugins.slots.contextEngine` 切回 `"legacy"`
- 在开发时,使用 `openclaw plugins install -l ./my-engine` 可以链接
本地插件目录而不进行复制。
另请参阅:[压缩](/zh-CN/concepts/compaction)、[上下文](/zh-CN/concepts/context)、[插件](/zh-CN/tools/plugin)、[插件清单](/zh-CN/plugins/manifest)。
另见:[压缩](/zh-CN/concepts/compaction)、[上下文](/zh-CN/concepts/context)、
[插件](/zh-CN/tools/plugin)、[插件清单](/zh-CN/plugins/manifest)。
## 相关内容
- [上下文](/zh-CN/concepts/context) — 如何为智能体轮次构建上下文
- [插件架构](/zh-CN/plugins/architecture) — 注册上下文引擎插件
- [压缩](/zh-CN/concepts/compaction)总结长对话
- [上下文](/zh-CN/concepts/context)——如何为智能体轮次构建上下文
- [插件架构](/zh-CN/plugins/architecture)——注册上下文引擎插件
- [压缩](/zh-CN/concepts/compaction)——总结长对话

View File

@ -1,141 +1,143 @@
---
read_when:
- 运行实时 model matrix / CLI 后端 / ACP / media-provider smoke 测试
- 运行实时模型矩阵 / CLI 后端 / ACP / 媒体提供商冒烟测试
- 调试实时测试凭证解析
- 添加新的 provider 专用实时测试
- 添加新的提供商专用实时测试
sidebarTitle: Live tests
summary: 实时涉及网络的测试模型矩阵、CLI 后端、ACP、媒体提供商、凭证
title: 测试:实时套件
title: 测试:实时测试套件
x-i18n:
generated_at: "2026-04-24T04:03:51Z"
generated_at: "2026-04-24T04:20:46Z"
model: gpt-5.4
provider: openai
source_hash: fcc6f6518d8e5207460a6aabc137beb9e0df2c9b6ab3da1f39123416c708971e
source_hash: db73b9ad5c15569f5772a91d0d2532923015bf98a21da9c833c59a9cfa5cec4e
source_path: help/testing-live.md
workflow: 15
---
如需了解快速开始、QA runner、单元/集成套件以及 Docker 流程,请参见
[Testing](/zh-CN/help/testing)。本页介绍**实时**(涉及网络)的测试
套件:model 矩阵、CLI 后端、ACP 和媒体 provider 实时测试,以及
如需了解快速开始、QA 运行器、单元/集成测试套件以及 Docker 流程,请参阅
[测试](/zh-CN/help/testing)。本页介绍**实时**(涉及网络)的测试
套件:模型矩阵、CLI 后端、ACP 和媒体提供商实时测试,以及
凭证处理。
## 实时Android 节点能力扫描
## 实时Android 节点能力全面检查
- 测试:`src/gateway/android-node.capabilities.live.test.ts`
- 脚本:`pnpm android:test:integration`
- 目标:调用已连接 Android 节点**当前公开的每个命令**,并断言命令 contract 行为。
- 目标:调用已连接 Android 节点当前**发布的每一个命令**,并断言命令契约行为。
- 范围:
- 预设条件/手动设置(该套件不会安装/运行/配对应用)。
- 对所选 Android 节点逐命令执行 Gateway 网关 `node.invoke` 验证
- 所需预先设置:
- 预设条件 / 手动设置(该测试套件不会安装 / 运行 / 配对应用)。
- 针对所选 Android 节点逐个命令进行 Gateway 网关 `node.invoke` 校验
- 必需的预先设置:
- Android 应用已连接并与 Gateway 网关配对。
- 应用保持在前台。
- 已为你期望通过的能力授予权限/采集同意。
- 已为你期望通过的能力授予权限 / 捕获同意。
- 可选目标覆盖:
- `OPENCLAW_ANDROID_NODE_ID``OPENCLAW_ANDROID_NODE_NAME`
- `OPENCLAW_ANDROID_GATEWAY_URL` / `OPENCLAW_ANDROID_GATEWAY_TOKEN` / `OPENCLAW_ANDROID_GATEWAY_PASSWORD`
- 完整 Android 设置详情:[Android App](/zh-CN/platforms/android)
- 完整 Android 设置详情: [Android App](/zh-CN/platforms/android)
## 实时:model smokeprofile keys
## 实时:模型冒烟测试(配置档键
实时测试分为两层,以便我们隔离故障:
- “直接 model” 告诉我们 provider/model 在给定 key 下是否至少能响应。
- “Gateway smoke” 告诉我们该 model 的完整 gateway + agent 流水线是否正常工作(会话、历史、工具、沙箱策略等)。
- “Direct model” 用于确认提供商 / 模型在给定密钥下是否至少能够响应。
- “Gateway smoke” 用于确认该模型的完整 Gateway 网关 + 智能体流水线正常工作(会话、历史记录、工具、沙箱策略等)。
### 第 1 层:直接 model completion(无 Gateway 网关)
### 第 1 层:直接模型补全(无 Gateway 网关)
- 测试:`src/agents/models.profiles.live.test.ts`
- 目标:
- 枚举已发现的模型
- 使用 `getApiKeyForModel` 选择你拥有凭证的模型
- 为每个模型运行一个小型 completion并在需要时运行定向回归
- 为每个模型运行一个小型补全(并在需要时运行定向回归测试
- 启用方式:
- `pnpm test:live`(或在直接调用 Vitest 时设置 `OPENCLAW_LIVE_TEST=1`
- 设置 `OPENCLAW_LIVE_MODELS=modern`(或 `all`,即 modern 的别名)才会真正运行此套件;否则它会跳过,以便让 `pnpm test:live` 聚焦于 gateway smoke
- 选择模型的方式:
- `OPENCLAW_LIVE_MODELS=modern` 运行现代 allowlistOpus/Sonnet 4.6+、GPT-5.x + Codex、Gemini 3、GLM 4.7、MiniMax M2.7、Grok 4
- `OPENCLAW_LIVE_MODELS=all` 是现代 allowlist 的别名
- 或 `OPENCLAW_LIVE_MODELS="openai/gpt-5.4,openai-codex/gpt-5.5,anthropic/claude-opus-4-6,..."`(逗号分隔的 allowlist
- modern/all 扫描默认带有精心挑选的高信号上限;设置 `OPENCLAW_LIVE_MAX_MODELS=0` 可进行完整 modern 扫描,或设置为正数以使用更小上限。
- 选择 provider 的方式:
- `OPENCLAW_LIVE_PROVIDERS="google,google-antigravity,google-gemini-cli"`(逗号分隔的 allowlist
- key 的来源:
- 默认profile 存储和环境变量回退
- 设置 `OPENCLAW_LIVE_REQUIRE_PROFILE_KEYS=1` 可强制**仅使用 profile 存储**
- `pnpm test:live`(或者如果你直接调用 Vitest则设置 `OPENCLAW_LIVE_TEST=1`
- 设置 `OPENCLAW_LIVE_MODELS=modern`(或 `all`,即 modern 的别名)来实际运行此套件;否则它会跳过,以便让 `pnpm test:live` 聚焦于 Gateway 网关冒烟测试
- 选择模型的方法:
- `OPENCLAW_LIVE_MODELS=modern` 运行现代允许列表Opus / Sonnet 4.6+、GPT-5.2 + Codex、Gemini 3、GLM 4.7、MiniMax M2.7、Grok 4
- `OPENCLAW_LIVE_MODELS=all` 是现代允许列表的别名
- 或者 `OPENCLAW_LIVE_MODELS="openai/gpt-5.2,openai-codex/gpt-5.2,anthropic/claude-opus-4-6,..."`(逗号分隔的允许列表)
- modern / all 全量检查默认使用精心挑选的高信号上限;设置 `OPENCLAW_LIVE_MAX_MODELS=0` 可执行完整的 modern 全量检查,或设置为正数以使用更小的上限。
- 完整全量检查对整个直接模型测试超时使用 `OPENCLAW_LIVE_TEST_TIMEOUT_MS`。默认值60 分钟。
- 设置 `OPENCLAW_LIVE_MODEL_CONCURRENCY=10` 可并行运行直接模型探测。默认值1。
- 选择提供商的方法:
- `OPENCLAW_LIVE_PROVIDERS="google,google-antigravity,google-gemini-cli"`(逗号分隔的允许列表)
- 密钥来源:
- 默认:配置档存储和环境变量回退
- 设置 `OPENCLAW_LIVE_REQUIRE_PROFILE_KEYS=1` 可强制**仅使用配置档存储**
- 存在原因:
- 将“provider API 已损坏 / key 无效”与“gateway agent 流水线已损坏”分离
- 包含小型、隔离的回归示例OpenAI Responses/Codex Responses 的 reasoning replay + tool-call 流程)
- 将“提供商 API 已损坏 / 密钥无效”和“Gateway 网关智能体流水线已损坏”区分开来
- 包含小型、隔离的回归测试示例OpenAI Responses / Codex Responses 推理回放 + 工具调用流程)
### 第 2 层Gateway 网关 + dev agent smoke “@openclaw” 实际执行的内容)
### 第 2 层Gateway 网关 + dev 智能体冒烟测试(也就是 “@openclaw” 实际执行的内容)
- 测试:`src/gateway/gateway-models.profiles.live.test.ts`
- 目标:
- 启动一个进程内 Gateway 网关
- 创建/修补一个 `agent:dev:*` 会话(每次运行覆盖 model
- 遍历带 key 的 models并断言:
- “有意义”响应(无工具)
- 真实工具调用有效read 探针)
- 可选的额外工具探针exec+read 探针)
- OpenAI 回归路径(仅 tool-call → 后续跟进)持续有效
- 探针详情(方便你快速解释故障):
- `read` 探针:测试会在工作区写入一个 nonce 文件,并要求 agent `read` 它并回显 nonce。
- `exec+read` 探针:测试会要求 agent 通过 `exec` 将 nonce 写入临时文件,然后再 `read` 回来。
- 图片探针:测试会附加一个生成的 PNG猫 + 随机代码),并期望 model 返回 `cat <CODE>`
- 创建 / 修补一个 `agent:dev:*` 会话(每次运行时覆盖模型
- 遍历带有密钥的模型并断言:
- “有意义”响应(无工具)
- 一次真实的工具调用可正常工作(读取探针)
- 可选的额外工具探针exec + read 探针)
- OpenAI 回归路径(仅工具调用 → 后续跟进)继续保持正常
- 探针详情(这样你可以快速解释故障):
- `read` 探针:测试会在工作区写入一个 nonce 文件,并要求智能体 `read` 它并回显该 nonce。
- `exec+read` 探针:测试要求智能体通过 `exec` 将 nonce 写入临时文件,然后再将其 `read` 回来。
- image 探针:测试附加一个生成的 PNG猫 + 随机代码),并期望模型返回 `cat <CODE>`
- 实现参考:`src/gateway/gateway-models.profiles.live.test.ts` 和 `src/gateway/live-image-probe.ts`
- 启用方式:
- `pnpm test:live`(或在直接调用 Vitest 时设置 `OPENCLAW_LIVE_TEST=1`
- 选择模型的方
- 默认:现代 allowlistOpus/Sonnet 4.6+、GPT-5.x + Codex、Gemini 3、GLM 4.7、MiniMax M2.7、Grok 4
- `OPENCLAW_LIVE_GATEWAY_MODELS=all` 是现代 allowlist 的别名
- 或设置 `OPENCLAW_LIVE_GATEWAY_MODELS="provider/model"`(或逗号列表)以缩小范围
- modern/all Gateway 网关扫描默认带有精心挑选的高信号上限;设置 `OPENCLAW_LIVE_GATEWAY_MAX_MODELS=0` 可进行完整 modern 扫描,或设置为正数以使用更小上限。
- 选择 provider 的方式避免“OpenRouter 全都测”):
- `OPENCLAW_LIVE_GATEWAY_PROVIDERS="google,google-antigravity,google-gemini-cli,openai,anthropic,zai,minimax"`(逗号分隔的 allowlist
- 在此实时测试中,工具 + 图片探针始终启用:
- `pnpm test:live`(或者如果你直接调用 Vitest设置 `OPENCLAW_LIVE_TEST=1`
- 选择模型的方
- 默认:现代允许列表Opus / Sonnet 4.6+、GPT-5.2 + Codex、Gemini 3、GLM 4.7、MiniMax M2.7、Grok 4
- `OPENCLAW_LIVE_GATEWAY_MODELS=all` 是现代允许列表的别名
- 或设置 `OPENCLAW_LIVE_GATEWAY_MODELS="provider/model"`(或逗号分隔列表)以缩小范围
- modern / all Gateway 网关全量检查默认使用精心挑选的高信号上限;设置 `OPENCLAW_LIVE_GATEWAY_MAX_MODELS=0` 可执行完整的 modern 全量检查,或设置为正数以使用更小的上限。
- 选择提供商的方法避免“OpenRouter 全部都测”):
- `OPENCLAW_LIVE_GATEWAY_PROVIDERS="google,google-antigravity,google-gemini-cli,openai,anthropic,zai,minimax"`(逗号分隔的允许列表
- 工具和图像探针在此实时测试中始终启用:
- `read` 探针 + `exec+read` 探针(工具压力测试)
- 当 model 声明支持图片输入时,会运行图片探针
- 流程(高层概
- 当模型声明支持图像输入时,会运行 image 探针
- 流程(高层概
- 测试生成一个带有 “CAT” + 随机代码的小型 PNG`src/gateway/live-image-probe.ts`
- 通过 `agent` `attachments: [{ mimeType: "image/png", content: "<base64>" }]` 发送
- Gateway 网关将附件解析为 `images[]``src/gateway/server-methods/agent.ts` + `src/gateway/chat-attachments.ts`
- 嵌入式 agent 将多模态用户消息转发给 model
- 断言:回复包含 `cat` + 该代码OCR 容错:允许轻微错误)
- 内嵌智能体将多模态用户消息转发给模型
- 断言:回复包含 `cat` + 该代码OCR 容错:允许轻微错误)
提示:要查看你的机器上可以测试哪些内容(以及确切的 `provider/model` id),请运行:
提示:要查看你在本机上可以测试什么(以及精确的 `provider/model` ID),请运行:
```bash
openclaw models list
openclaw models list --json
```
## 实时CLI 后端 smokeClaude、Codex、Gemini 或其他本地 CLI
## 实时CLI 后端冒烟测试Claude、Codex、Gemini 或其他本地 CLI
- 测试:`src/gateway/gateway-cli-backend.live.test.ts`
- 目标:在不触碰默认配置的前提下,使用本地 CLI 后端验证 Gateway 网关 + agent 流水线。
- 后端专用的 smoke 默认值位于拥有该后端的扩展的 `cli-backend.ts` 定义中。
- 目标:在不触碰你的默认配置的情况下,使用本地 CLI 后端验证 Gateway 网关 + 智能体流水线。
- 后端专用的冒烟测试默认值位于对应扩展的 `cli-backend.ts` 定义中。
- 启用:
- `pnpm test:live`(或在直接调用 Vitest 时设置 `OPENCLAW_LIVE_TEST=1`
- `pnpm test:live`(或者如果你直接调用 Vitest设置 `OPENCLAW_LIVE_TEST=1`
- `OPENCLAW_LIVE_CLI_BACKEND=1`
- 默认值:
- 默认 provider/model`claude-cli/claude-sonnet-4-6`
- command/args/image 行为来自拥有该 CLI 后端的 plugin 元数据。
- 默认提供商 / 模型`claude-cli/claude-sonnet-4-6`
- command / args / image 行为来自所属 CLI 后端插件元数据。
- 覆盖项(可选):
- `OPENCLAW_LIVE_CLI_BACKEND_MODEL="codex-cli/gpt-5.5"`
- `OPENCLAW_LIVE_CLI_BACKEND_MODEL="codex-cli/gpt-5.2"`
- `OPENCLAW_LIVE_CLI_BACKEND_COMMAND="/full/path/to/codex"`
- `OPENCLAW_LIVE_CLI_BACKEND_ARGS='["exec","--json","--color","never","--sandbox","read-only","--skip-git-repo-check"]'`
- `OPENCLAW_LIVE_CLI_BACKEND_IMAGE_PROBE=1` 发送真实图片附件(路径会注入到提示词中)。
- `OPENCLAW_LIVE_CLI_BACKEND_IMAGE_ARG="--image"` 通过 CLI 参数传递图片文件路径,而不是注入到提示词中。
- `OPENCLAW_LIVE_CLI_BACKEND_IMAGE_MODE="repeat"`(或 `"list"`控制在设置 `IMAGE_ARG` 时如何传递图片参数
- `OPENCLAW_LIVE_CLI_BACKEND_IMAGE_PROBE=1` 发送真实图像附件(路径会注入到提示中)。
- `OPENCLAW_LIVE_CLI_BACKEND_IMAGE_ARG="--image"` 通过 CLI 参数传递图像文件路径,而不是注入到提示中。
- `OPENCLAW_LIVE_CLI_BACKEND_IMAGE_MODE="repeat"`(或 `"list"`用于在设置 `IMAGE_ARG` 时控制图像参数的传递方式
- `OPENCLAW_LIVE_CLI_BACKEND_RESUME_PROBE=1` 发送第二轮消息并验证恢复流程。
- `OPENCLAW_LIVE_CLI_BACKEND_MODEL_SWITCH_PROBE=0` 禁用默认的 Claude Sonnet -> Opus 同会话连续性探针(当所选 model 支持切换目标时,设置为 `1`强制启用)。
- `OPENCLAW_LIVE_CLI_BACKEND_MODEL_SWITCH_PROBE=0` 禁用默认的 Claude Sonnet -> Opus 同会话连续性探针(当所选模型支持切换目标时,可设为 `1`强制启用)。
示例:
```bash
OPENCLAW_LIVE_CLI_BACKEND=1 \
OPENCLAW_LIVE_CLI_BACKEND_MODEL="codex-cli/gpt-5.5" \
OPENCLAW_LIVE_CLI_BACKEND_MODEL="codex-cli/gpt-5.2" \
pnpm test:live src/gateway/gateway-cli-backend.live.test.ts
```
@ -145,7 +147,7 @@ Docker 配方:
pnpm test:docker:live-cli-backend
```
provider Docker 配方:
提供商 Docker 配方:
```bash
pnpm test:docker:live-cli-backend:claude
@ -156,28 +158,28 @@ pnpm test:docker:live-cli-backend:gemini
说明:
- Docker runner 位于 `scripts/test-live-cli-backend-docker.sh`
- 它会在仓库 Docker 镜像内,以非 root 的 `node` 用户运行实时 CLI 后端 smoke
- 它会从拥有该后端的扩展解析 CLI smoke 元数据,然后将匹配的 Linux CLI 包(`@anthropic-ai/claude-code`、`@openai/codex` 或 `@google/gemini-cli`)安装到 `OPENCLAW_DOCKER_CLI_TOOLS_DIR` 指定的可写缓存前缀中(默认:`~/.cache/openclaw/docker-cli-tools`)。
- `pnpm test:docker:live-cli-backend:claude-subscription` 需要可移植的 Claude Code 订阅 OAuth可通过 `~/.claude/.credentials.json`带有 `claudeAiOauth.subscriptionType`配置,或来自 `claude setup-token``CLAUDE_CODE_OAUTH_TOKEN` 提供。它会先在 Docker 中验证直接 `claude -p`,然后在不保留 Anthropic API key 环境变量的情况下运行两个 Gateway 网关 CLI 后端轮次。该订阅通道默认禁用 Claude MCP/tool 和图片探针,因为 Claude 当前会将第三方应用使用路由到额外用量计费,而不是普通订阅计划限额
- 实时 CLI 后端 smoke 现在会对 Claude、Codex 和 Gemini 执行相同的端到端流程:文本轮次、图片分类轮次,然后是通过 gateway CLI 验证的 MCP `cron` 工具调用。
- Claude 的默认 smoke 还会将会话从 Sonnet 修补为 Opus并验证恢复后的会话仍记得之前的备注。
- Docker 运行器位于 `scripts/test-live-cli-backend-docker.sh`
- 它会以非 root 的 `node` 用户身份,在仓库 Docker 镜像中运行实时 CLI 后端冒烟测试
- 它会从所属扩展解析 CLI 冒烟测试元数据,然后将匹配的 Linux CLI 包(`@anthropic-ai/claude-code`、`@openai/codex` 或 `@google/gemini-cli`)安装到缓存的可写前缀 `OPENCLAW_DOCKER_CLI_TOOLS_DIR` 中(默认`~/.cache/openclaw/docker-cli-tools`)。
- `pnpm test:docker:live-cli-backend:claude-subscription` 需要可移植的 Claude Code 订阅 OAuth可通过带有 `claudeAiOauth.subscriptionType` `~/.claude/.credentials.json`,或来自 `claude setup-token``CLAUDE_CODE_OAUTH_TOKEN` 提供。它会先在 Docker 中验证直接 `claude -p`,然后在不保留 Anthropic API 密钥环境变量的情况下运行两轮 Gateway 网关 CLI 后端测试。该订阅测试默认禁用 Claude MCP / 工具和图像探针,因为 Claude 当前会将第三方应用使用路由到额外用量计费,而不是常规订阅套餐限制
- 实时 CLI 后端冒烟测试现在会对 Claude、Codex 和 Gemini 执行相同的端到端流程:文本轮次、图像分类轮次,然后是通过 Gateway 网关 CLI 验证的 MCP `cron` 工具调用。
- Claude 的默认冒烟测试还会将会话从 Sonnet 修补为 Opus并验证恢复后的会话仍记得之前的备注。
## 实时ACP bind smoke`/acp spawn ... --bind here`
## 实时ACP 绑定冒烟测试`/acp spawn ... --bind here`
- 测试:`src/gateway/gateway-acp-bind.live.test.ts`
- 目标:使用实时 ACP agent 验证真实的 ACP 会话绑定流程:
- 目标:使用实时 ACP 智能体验证真实 ACP 会话绑定流程:
- 发送 `/acp spawn <agent> --bind here`
- 就地绑定一个合成的 message-channel 对
- 在同一话中发送普通后续消息
- 验证该后续消息进入已绑定 ACP 会话转录
- 原地绑定一个合成的消息渠道会
- 在同一话中发送普通后续消息
- 验证该后续消息进入已绑定 ACP 会话转录
- 启用:
- `pnpm test:live src/gateway/gateway-acp-bind.live.test.ts`
- `OPENCLAW_LIVE_ACP_BIND=1`
- 默认值:
- Docker 中的 ACP agents`claude,codex,gemini`
- 直接运行 `pnpm test:live ...` 时的 ACP agent`claude`
- 合成渠道Slack 私信风格的话上下文
- Docker 中的 ACP 智能体`claude,codex,gemini`
- 直接 `pnpm test:live ...` 使用的 ACP 智能体`claude`
- 合成渠道Slack 私信风格的话上下文
- ACP 后端:`acpx`
- 覆盖项:
- `OPENCLAW_LIVE_ACP_BIND_AGENT=claude`
@ -185,11 +187,11 @@ pnpm test:docker:live-cli-backend:gemini
- `OPENCLAW_LIVE_ACP_BIND_AGENT=gemini`
- `OPENCLAW_LIVE_ACP_BIND_AGENTS=claude,codex,gemini`
- `OPENCLAW_LIVE_ACP_BIND_AGENT_COMMAND='npx -y @agentclientprotocol/claude-agent-acp@<version>'`
- `OPENCLAW_LIVE_ACP_BIND_CODEX_MODEL=gpt-5.5`
- `OPENCLAW_LIVE_ACP_BIND_PARENT_MODEL=openai/gpt-5.4`
- `OPENCLAW_LIVE_ACP_BIND_CODEX_MODEL=gpt-5.2`
- `OPENCLAW_LIVE_ACP_BIND_PARENT_MODEL=openai/gpt-5.2`
- 说明:
- 该通道使用 gateway `chat.send` 表面,并带有仅管理员可用的合成 originating-route 字段,因此测试可以附加 message-channel 上下文,而无需伪装成外部投递。
- 当 `OPENCLAW_LIVE_ACP_BIND_AGENT_COMMAND` 未设置时,测试会使用嵌入式 `acpx` plugin 的内置 agent 注册表来处理所选 ACP harness agent
- 此测试路径使用 Gateway 网关 `chat.send` 接口,并带有仅管理员可用的合成来源路由字段,这样测试就可以附加消息渠道上下文,而无需伪装成外部投递。
- 当未设置 `OPENCLAW_LIVE_ACP_BIND_AGENT_COMMAND` 时,测试会对所选 ACP harness 智能体使用内嵌 `acpx` 插件的内置智能体注册表
示例:
@ -205,7 +207,7 @@ Docker 配方:
pnpm test:docker:live-acp-bind
```
agent Docker 配方:
智能体 Docker 配方:
```bash
pnpm test:docker:live-acp-bind:claude
@ -215,32 +217,37 @@ pnpm test:docker:live-acp-bind:gemini
Docker 说明:
- Docker runner 位于 `scripts/test-live-acp-bind-docker.sh`
- 默认情况下,它会按顺序对所有受支持的实时 CLI agents 运行 ACP bind smoke`claude`、`codex`,然后 `gemini`
- 使用 `OPENCLAW_LIVE_ACP_BIND_AGENTS=claude`、`OPENCLAW_LIVE_ACP_BIND_AGENTS=codex` 或 `OPENCLAW_LIVE_ACP_BIND_AGENTS=gemini`缩小矩阵范围。
- 它会读取 `~/.profile`,将匹配的 CLI 认证材料暂存到容器中,把 `acpx` 安装到可写 npm 前缀中,然后在缺失时安装所请求的实时 CLI`@anthropic-ai/claude-code`、`@openai/codex` 或 `@google/gemini-cli`)。
- 在 Docker 内runner 会设置 `OPENCLAW_LIVE_ACP_BIND_ACPX_COMMAND=$HOME/.npm-global/bin/acpx`,以便 acpx 保留从 profile 读取到的 provider 环境变量,并传递给子 harness CLI。
- Docker 运行器位于 `scripts/test-live-acp-bind-docker.sh`
- 默认情况下,它会按顺序对所有受支持的实时 CLI 智能体运行 ACP 绑定冒烟测试`claude`、`codex`,然后 `gemini`
- 使用 `OPENCLAW_LIVE_ACP_BIND_AGENTS=claude`、`OPENCLAW_LIVE_ACP_BIND_AGENTS=codex` 或 `OPENCLAW_LIVE_ACP_BIND_AGENTS=gemini` 可缩小矩阵范围。
- 它会加载 `~/.profile`,将匹配的 CLI 凭证材料暂存到容器中,在可写 npm 前缀中安装 `acpx`,然后在缺失时安装所请求的实时 CLI`@anthropic-ai/claude-code`、`@openai/codex` 或 `@google/gemini-cli`)。
- 在 Docker 内部,运行器会设置 `OPENCLAW_LIVE_ACP_BIND_ACPX_COMMAND=$HOME/.npm-global/bin/acpx`,以便 acpx 保留来自已加载 profile 的提供商环境变量,并将其提供给子 harness CLI。
## 实时Codex app-server harness smoke
## 实时Codex app-server harness 冒烟测试
- 目标:通过正常的 Gateway 网关 `agent` 方法,验证由 plugin 所拥有的 Codex harness
- 加载内置的 `codex` plugin
- 目标:通过正常的 Gateway 网关
`agent` 方法验证由插件拥有的 Codex harness
- 加载内置的 `codex` 插件
- 选择 `OPENCLAW_AGENT_RUNTIME=codex`
- 向 `openai/gpt-5.4` 发送第一轮 Gateway 网关 agent 消息,并强制使用 Codex harness
- 向 `openai/gpt-5.2` 发送第一轮 Gateway 网关智能体请求,并强制使用 Codex harness
- 向同一个 OpenClaw 会话发送第二轮消息,并验证 app-server
线程可以恢复
- 通过相同的 Gateway 网关命令路径运行 `/codex status``/codex models`
- 可选地运行两个经过 Guardian 审核的提权 shell 探针:一个应被批准的无害命令,以及一个应被拒绝的伪造密钥上传,以便让智能体回问
- 通过同一个 Gateway 网关命令
路径运行 `/codex status``/codex models`
- 可选运行两个经 Guardian 审核的提权 shell 探针:一个应被批准的
无害命令,以及一个应被
拒绝从而让智能体回问的伪造密钥上传操作
- 测试:`src/gateway/gateway-codex-harness.live.test.ts`
- 启用:`OPENCLAW_LIVE_CODEX_HARNESS=1`
- 默认模型:`openai/gpt-5.4`
- 可选图探针:`OPENCLAW_LIVE_CODEX_HARNESS_IMAGE_PROBE=1`
- 可选 MCP/工具探针:`OPENCLAW_LIVE_CODEX_HARNESS_MCP_PROBE=1`
- 默认模型:`openai/gpt-5.2`
- 可选图探针:`OPENCLAW_LIVE_CODEX_HARNESS_IMAGE_PROBE=1`
- 可选 MCP / 工具探针:`OPENCLAW_LIVE_CODEX_HARNESS_MCP_PROBE=1`
- 可选 Guardian 探针:`OPENCLAW_LIVE_CODEX_HARNESS_GUARDIAN_PROBE=1`
- 该 smoke 会设置 `OPENCLAW_AGENT_HARNESS_FALLBACK=none`,因此损坏的 Codex
harness 不能通过静默回退到 PI 来“通过”
- 该冒烟测试会设置 `OPENCLAW_AGENT_HARNESS_FALLBACK=none`,这样损坏的 Codex
harness 就无法通过悄悄回退到 PI 来蒙混过关
- 认证Codex app-server 认证来自本地 Codex 订阅登录。Docker
smoke 在适用时也可以为非 Codex 探针提供 `OPENAI_API_KEY`,并且可选复制 `~/.codex/auth.json``~/.codex/config.toml`
冒烟测试在适用时也可为非 Codex 探针提供 `OPENAI_API_KEY`
另外还可选复制 `~/.codex/auth.json``~/.codex/config.toml`
本地配方:
@ -250,7 +257,7 @@ OPENCLAW_LIVE_CODEX_HARNESS=1 \
OPENCLAW_LIVE_CODEX_HARNESS_IMAGE_PROBE=1 \
OPENCLAW_LIVE_CODEX_HARNESS_MCP_PROBE=1 \
OPENCLAW_LIVE_CODEX_HARNESS_GUARDIAN_PROBE=1 \
OPENCLAW_LIVE_CODEX_HARNESS_MODEL=openai/gpt-5.4 \
OPENCLAW_LIVE_CODEX_HARNESS_MODEL=openai/gpt-5.2 \
pnpm test:live -- src/gateway/gateway-codex-harness.live.test.ts
```
@ -263,118 +270,118 @@ pnpm test:docker:live-codex-harness
Docker 说明:
- Docker runner 位于 `scripts/test-live-codex-harness-docker.sh`
- 它会读取挂载的 `~/.profile`,传递 `OPENAI_API_KEY`,在存在时复制 Codex CLI
认证文件,将 `@openai/codex` 安装到一个可写的挂载 npm
前缀中,准备源代码树,然后仅运行 Codex-harness 实时测试。
- Docker 默认启用图片、MCP/工具以及 Guardian 探针。设置
- Docker 运行器位于 `scripts/test-live-codex-harness-docker.sh`
- 它会加载挂载的 `~/.profile`,传递 `OPENAI_API_KEY`,在存在时复制 Codex CLI
认证文件,将 `@openai/codex` 安装到可写的挂载 npm
前缀中,暂存源代码树,然后只运行 Codex-harness 实时测试。
- Docker 默认启用图像、MCP / 工具和 Guardian 探针。设置
`OPENCLAW_LIVE_CODEX_HARNESS_IMAGE_PROBE=0`
`OPENCLAW_LIVE_CODEX_HARNESS_MCP_PROBE=0`
`OPENCLAW_LIVE_CODEX_HARNESS_GUARDIAN_PROBE=0`,即可在你需要更窄范围调试运行时关闭它们
- Docker 会导出 `OPENCLAW_AGENT_HARNESS_FALLBACK=none`,与实时
测试配置一致,因此旧别名或 PI 回退不能掩盖 Codex harness
回归。
`OPENCLAW_LIVE_CODEX_HARNESS_GUARDIAN_PROBE=0`,即可在需要更窄范围调试运行时使用
- Docker 会导出 `OPENCLAW_AGENT_HARNESS_FALLBACK=none`,与实时
测试配置保持一致,这样旧别名或回退到 PI 都无法掩盖 Codex harness
回归问题
### 推荐的实时配方
### 推荐的实时测试配方
范围窄且显式的 allowlist 速度最快,也最不容易出现不稳定
范围窄、明确的允许列表速度最快,也最不容易出问题
- 单模型,直接方式(无 Gateway 网关):
- `OPENCLAW_LIVE_MODELS="openai/gpt-5.4" pnpm test:live src/agents/models.profiles.live.test.ts`
- 单模型,直接测试(无 Gateway 网关):
- `OPENCLAW_LIVE_MODELS="openai/gpt-5.2" pnpm test:live src/agents/models.profiles.live.test.ts`
- 单模型Gateway 网关 smoke
- `OPENCLAW_LIVE_GATEWAY_MODELS="openai/gpt-5.4" pnpm test:live src/gateway/gateway-models.profiles.live.test.ts`
- 单模型Gateway 网关冒烟测试
- `OPENCLAW_LIVE_GATEWAY_MODELS="openai/gpt-5.2" pnpm test:live src/gateway/gateway-models.profiles.live.test.ts`
- 跨多个 provider 的工具调用:
- `OPENCLAW_LIVE_GATEWAY_MODELS="openai/gpt-5.4,openai-codex/gpt-5.5,anthropic/claude-opus-4-6,google/gemini-3-flash-preview,zai/glm-4.7,minimax/MiniMax-M2.7" pnpm test:live src/gateway/gateway-models.profiles.live.test.ts`
- 跨多个提供商的工具调用:
- `OPENCLAW_LIVE_GATEWAY_MODELS="openai/gpt-5.2,openai-codex/gpt-5.2,anthropic/claude-opus-4-6,google/gemini-3-flash-preview,zai/glm-4.7,minimax/MiniMax-M2.7" pnpm test:live src/gateway/gateway-models.profiles.live.test.ts`
- 聚焦 GoogleGemini API key + Antigravity
- GeminiAPI key`OPENCLAW_LIVE_GATEWAY_MODELS="google/gemini-3-flash-preview" pnpm test:live src/gateway/gateway-models.profiles.live.test.ts`
- 聚焦 GoogleGemini API 密钥 + Antigravity
- GeminiAPI 密钥`OPENCLAW_LIVE_GATEWAY_MODELS="google/gemini-3-flash-preview" pnpm test:live src/gateway/gateway-models.profiles.live.test.ts`
- AntigravityOAuth`OPENCLAW_LIVE_GATEWAY_MODELS="google-antigravity/claude-opus-4-6-thinking,google-antigravity/gemini-3-pro-high" pnpm test:live src/gateway/gateway-models.profiles.live.test.ts`
说明:
- `google/...` 使用 Gemini APIAPI key)。
- `google/...` 使用 Gemini APIAPI 密钥)。
- `google-antigravity/...` 使用 Antigravity OAuth 桥接Cloud Code Assist 风格的智能体端点)。
- `google-gemini-cli/...` 使用你机器上的本地 Gemini CLI的认证 + 工具行为差异)。
- `google-gemini-cli/...` 使用你机器上的本地 Gemini CLI独的认证 + 工具行为差异)。
- Gemini API 与 Gemini CLI
- APIOpenClaw 通过 HTTP 调用 Google 托管的 Gemini APIAPI key / profile 认证);这是大多数用户所说的“Gemini”。
- CLIOpenClaw 会 shell 调用本地 `gemini` 二进制文件;它有自己的认证方式,行为可能不同(流式传输/工具支持/版本偏差)。
- APIOpenClaw 通过 HTTP 调用 Google 托管的 Gemini APIAPI 密钥 / 配置档认证);这通常是大多数用户所说的 “Gemini”。
- CLIOpenClaw 会调用本地 `gemini` 二进制;它有自己的认证方式,行为可能不同(流式传输 / 工具支持 / 版本偏差)。
## 实时:model 矩阵(我们覆盖什么
## 实时:模型矩阵(我们的覆盖范围
没有固定的“CI model 列表”(实时测试是选择启用的),但以下是建议在拥有 key 的开发机器上定期覆盖的**推荐**模型。
没有固定的“CI 模型列表”(实时测试为按需启用),但以下是**推荐**在有密钥的开发机器上定期覆盖的模型。
### 现代 smoke 集合(工具调用 + 图片
### 现代冒烟测试集(工具调用 + 图像
这是我们期望持续保持可用的“常见模型”运行
这是我们期望持续保持可用的“常用模型”运行集
- OpenAI非 Codex`openai/gpt-5.4`(可选:`openai/gpt-5.4-mini`
- OpenAI Codex OAuth`openai-codex/gpt-5.5`
- OpenAI非 Codex`openai/gpt-5.2`
- OpenAI Codex OAuth`openai-codex/gpt-5.2`
- Anthropic`anthropic/claude-opus-4-6`(或 `anthropic/claude-sonnet-4-6`
- GoogleGemini API`google/gemini-3.1-pro-preview` 和 `google/gemini-3-flash-preview`(避免较旧的 Gemini 2.x 模型)
- GoogleAntigravity`google-antigravity/claude-opus-4-6-thinking` 和 `google-antigravity/gemini-3-flash`
- Z.AIGLM`zai/glm-4.7`
- MiniMax`minimax/MiniMax-M2.7`
运行带工具 + 图片的 Gateway 网关 smoke
`OPENCLAW_LIVE_GATEWAY_MODELS="openai/gpt-5.4,openai-codex/gpt-5.5,anthropic/claude-opus-4-6,google/gemini-3.1-pro-preview,google/gemini-3-flash-preview,google-antigravity/claude-opus-4-6-thinking,google-antigravity/gemini-3-flash,zai/glm-4.7,minimax/MiniMax-M2.7" pnpm test:live src/gateway/gateway-models.profiles.live.test.ts`
运行带工具 + 图像的 Gateway 网关冒烟测试
`OPENCLAW_LIVE_GATEWAY_MODELS="openai/gpt-5.2,openai-codex/gpt-5.2,anthropic/claude-opus-4-6,google/gemini-3.1-pro-preview,google/gemini-3-flash-preview,google-antigravity/claude-opus-4-6-thinking,google-antigravity/gemini-3-flash,zai/glm-4.7,minimax/MiniMax-M2.7" pnpm test:live src/gateway/gateway-models.profiles.live.test.ts`
### 基线工具调用Read + 可选 Exec
每个 provider 家族至少选一个:
每个提供商家族至少选一个:
- OpenAI`openai/gpt-5.4`(或 `openai/gpt-5.4-mini`
- OpenAI`openai/gpt-5.2`
- Anthropic`anthropic/claude-opus-4-6`(或 `anthropic/claude-sonnet-4-6`
- Google`google/gemini-3-flash-preview`(或 `google/gemini-3.1-pro-preview`
- Z.AIGLM`zai/glm-4.7`
- MiniMax`minimax/MiniMax-M2.7`
可选的额外覆盖(有则更好
可选的附加覆盖(有更好,没有也行
- xAI`xai/grok-4`(或最新可用版本)
- Mistral`mistral/`…(选择一个你已启用且支持工具的模型)
- Mistral`mistral/`…(选择一个你已启用、支持 “tools” 的模型)
- Cerebras`cerebras/`…(如果你有访问权限)
- LM Studio`lmstudio/`…(本地;工具调用取决于 API 模式)
### 视觉:发送图片(附件 → 多模态消息)
### Vision图像发送(附件 → 多模态消息)
`OPENCLAW_LIVE_GATEWAY_MODELS` 中至少包含一个支持图片的模型Claude/Gemini/OpenAI 支持视觉的变体等),以执行图片探针。
`OPENCLAW_LIVE_GATEWAY_MODELS` 中至少包含一个支持图像的模型Claude / Gemini / OpenAI 支持 Vision 的变体等),以执行图像探针。
### 聚合器 / 替代 Gateway 网关
如果你启用了相应 key我们也支持通过以下方式测试:
如果你已启用相关密钥,我们还支持通过以下方式进行测试:
- OpenRouter`openrouter/...`(数百个模型;使用 `openclaw models scan` 查找支持工具 + 图片的候选项
- OpenCode`opencode/...` 用于 Zen`opencode-go/...` 用于 Go(通过 `OPENCODE_API_KEY` / `OPENCODE_ZEN_API_KEY` 认证)
- OpenRouter`openrouter/...`(数百个模型;使用 `openclaw models scan` 查找支持工具 + 图像的候选模型
- OpenCodeZen 使用 `opencode/...`Go 使用 `opencode-go/...`(通过 `OPENCODE_API_KEY` / `OPENCODE_ZEN_API_KEY` 认证)
你还可以将更多 provider 纳入实时矩阵(前提是你有相应凭证/配置):
你还可以在实时矩阵中加入更多提供商(如果你有凭证 / 配置):
- 内置:`openai`、`openai-codex`、`anthropic`、`google`、`google-vertex`、`google-antigravity`、`google-gemini-cli`、`zai`、`openrouter`、`opencode`、`opencode-go`、`xai`、`groq`、`cerebras`、`mistral`、`github-copilot`
- 通过 `models.providers`(自定义端点):`minimax`(云/API以及任何兼容 OpenAI/Anthropic 的代理LM Studio、vLLM、LiteLLM 等)
- 通过 `models.providers`(自定义端点):`minimax`(云 / API以及任何兼容 OpenAI / Anthropic 的代理LM Studio、vLLM、LiteLLM 等)
提示:不要试图在文档中硬编码“所有模型”。权威列表应以你的机器上 `discoverModels(...)` 的返回结果,以及当前可用的 key 为准
提示:不要试图在文档中硬编码 “all models”。权威列表始终是你机器上 `discoverModels(...)` 的返回结果,加上当前可用的密钥
## 凭证(切勿提交)
实时测试以与 CLI 相同的方式发现凭证。实际含义如下:
实时测试发现凭证的方式与 CLI 相同。实际含义如下:
- 如果 CLI 能工作,实时测试应能找到相同的 key
- 如果实时测试提示“无凭证”,请使用与你调试 `openclaw models list` / model 选择时相同的方式来调试。
- 如果 CLI 能用,实时测试也应该能找到同样的密钥
- 如果某个实时测试提示 “no creds”请像调试 `openclaw models list` / 模型选择那样去调试。
- 每智能体 auth profile`~/.openclaw/agents/<agentId>/agent/auth-profiles.json`这就是实时测试中“profile keys”的含义
- 每个智能体的认证配置档`~/.openclaw/agents/<agentId>/agent/auth-profiles.json`(这就是实时测试中 “profile keys” 的含义)
- 配置:`~/.openclaw/openclaw.json`(或 `OPENCLAW_CONFIG_PATH`
- 旧版状态目录:`~/.openclaw/credentials/`(存在时会复制到准备好的实时 home 中,但它不是主 profile-key 存储)
- 本地实时运行默认会将当前活动配置、每智能体 `auth-profiles.json` 文件、旧版 `credentials/` 以及受支持的外部 CLI 认证目录复制到临时测试 home准备好的实时 home 会跳过 `workspace/``sandboxes/`,并去除 `agents.*.workspace` / `agentDir` 路径覆盖,以便探针不会进入你真实主机的工作区
- 旧版状态目录:`~/.openclaw/credentials/`(存在时会被复制到暂存的实时测试 home 中,但它不是主配置档密钥存储)
- 实时本地运行默认会将当前活动配置、每智能体 `auth-profiles.json` 文件、旧版 `credentials/` 以及受支持的外部 CLI 认证目录复制到临时测试 home暂存的实时 home 会跳过 `workspace/``sandboxes/`,并移除 `agents.*.workspace` / `agentDir` 路径覆盖,以确保探针不会落到你的真实宿主工作区上
如果你想依赖环境变量 key例如在 `~/.profile` 中导出的 key请在执行本地测试前运行 `source ~/.profile`,或者使用下面的 Docker runner它们可以将 `~/.profile` 挂载到容器中)。
如果你想依赖环境变量密钥(例如在你的 `~/.profile` 中导出),请在执行本地测试前运行 `source ~/.profile`,或使用下面的 Docker 运行器(它们可以把 `~/.profile` 挂载进容器)。
## Deepgram 实时测试(音频转写)
- 测试:`extensions/deepgram/audio.live.test.ts`
- 启用:`DEEPGRAM_API_KEY=... DEEPGRAM_LIVE_TEST=1 pnpm test:live extensions/deepgram/audio.live.test.ts`
## BytePlus 编码计划实时测试
## BytePlus(国际版) 编码计划实时测试
- 测试:`extensions/byteplus/live.test.ts`
- 启用:`BYTEPLUS_API_KEY=... BYTEPLUS_LIVE_TEST=1 pnpm test:live extensions/byteplus/live.test.ts`
@ -385,26 +392,26 @@ Docker 说明:
- 测试:`extensions/comfy/comfy.live.test.ts`
- 启用:`OPENCLAW_LIVE_TEST=1 COMFY_LIVE_TEST=1 pnpm test:live -- extensions/comfy/comfy.live.test.ts`
- 范围:
- 覆盖内置 comfy 图、视频和 `music_generate` 路径
- 覆盖内置 comfy 图、视频和 `music_generate` 路径
- 除非配置了 `models.providers.comfy.<capability>`,否则会跳过各项能力
- 在更改 comfy 工作流提交、轮询、下载或 plugin 注册后非常有用
- 在修改 comfy 工作流提交、轮询、下载或插件注册后非常有用
## 图生成实时测试
## 图生成实时测试
- 测试:`test/image-generation.runtime.live.test.ts`
- 命令:`pnpm test:live test/image-generation.runtime.live.test.ts`
- Harness`pnpm test:live:media image`
- 范围:
- 枚举每个已注册的图片生成 provider plugin
- 在探测前从你的登录 shell`~/.profile`)加载缺失的 provider 环境变量
- 默认优先使用实时/环境变量 API key而不是已存储的 auth profile这样 `auth-profiles.json` 中过期的测试 key 就不会掩盖真实的 shell 凭证
- 跳过没有可用 auth/profile/model 的 provider
- 通过共享运行时能力运行标准图生成变体:
- 枚举每个已注册的图像生成提供商插件
- 在探测前从你的登录 shell`~/.profile`)加载缺失的提供商环境变量
- 默认优先使用实时 / 环境变量 API 密钥,而不是已存储的认证配置档,因此 `auth-profiles.json` 中过期的测试密钥不会掩盖真实的 shell 凭证
- 跳过没有可用认证 / 配置档 / 模型的提供商
- 通过共享运行时能力运行标准图生成变体:
- `google:flash-generate`
- `google:pro-generate`
- `google:pro-edit`
- `openai:default-generate`
- 当前覆盖的内置 provider
- 当前覆盖的内置提供商
- `fal`
- `google`
- `minimax`
@ -417,7 +424,7 @@ Docker 说明:
- `OPENCLAW_LIVE_IMAGE_GENERATION_MODELS="openai/gpt-image-2,google/gemini-3.1-flash-image-preview,openrouter/google/gemini-3.1-flash-image-preview,xai/grok-imagine-image"`
- `OPENCLAW_LIVE_IMAGE_GENERATION_CASES="google:flash-generate,google:pro-edit,openrouter:generate,xai:default-generate,xai:default-edit"`
- 可选认证行为:
- `OPENCLAW_LIVE_REQUIRE_PROFILE_KEYS=1` 强制使用 profile 存储认证,并忽略仅环境变量覆盖
- `OPENCLAW_LIVE_REQUIRE_PROFILE_KEYS=1` 可强制使用配置档存储认证,并忽略仅环境变量覆盖
## 音乐生成实时测试
@ -425,23 +432,23 @@ Docker 说明:
- 启用:`OPENCLAW_LIVE_TEST=1 pnpm test:live -- extensions/music-generation-providers.live.test.ts`
- Harness`pnpm test:live:media music`
- 范围:
- 覆盖共享的内置音乐生成 provider 路径
- 覆盖共享的内置音乐生成提供商路径
- 当前覆盖 Google 和 MiniMax
- 在探测前从你的登录 shell`~/.profile`)加载 provider 环境变量
- 默认优先使用实时/环境变量 API key而不是已存储的 auth profile这样 `auth-profiles.json` 中过期的测试 key 就不会掩盖真实的 shell 凭证
- 跳过没有可用 auth/profile/model 的 provider
- 在可用时运行两声明的运行时模式:
- `generate`,仅使用提示词输入
- `edit`,当 provider 声明 `capabilities.edit.enabled`
- 当前共享通道覆盖:
- 在探测前从你的登录 shell`~/.profile`)加载提供商环境变量
- 默认优先使用实时 / 环境变量 API 密钥,而不是已存储的认证配置档,因此 `auth-profiles.json` 中过期的测试密钥不会掩盖真实的 shell 凭证
- 跳过没有可用认证 / 配置档 / 模型的提供商
- 在可用时运行两个已声明的运行时模式:
- 使用仅提示输入的 `generate`
- 当提供商声明 `capabilities.edit.enabled` 时运行 `edit`
- 当前共享测试路径覆盖:
- `google``generate`、`edit`
- `minimax``generate`
- `comfy`使用独立的 Comfy 实时文件,而不是这个共享扫描
- `comfy`单独的 Comfy 实时文件,不属于该共享全量检查
- 可选缩小范围:
- `OPENCLAW_LIVE_MUSIC_GENERATION_PROVIDERS="google,minimax"`
- `OPENCLAW_LIVE_MUSIC_GENERATION_MODELS="google/lyria-3-clip-preview,minimax/music-2.5+"`
- 可选认证行为:
- `OPENCLAW_LIVE_REQUIRE_PROFILE_KEYS=1` 强制使用 profile 存储认证,并忽略仅环境变量覆盖
- `OPENCLAW_LIVE_REQUIRE_PROFILE_KEYS=1` 可强制使用配置档存储认证,并忽略仅环境变量覆盖
## 视频生成实时测试
@ -449,43 +456,43 @@ Docker 说明:
- 启用:`OPENCLAW_LIVE_TEST=1 pnpm test:live -- extensions/video-generation-providers.live.test.ts`
- Harness`pnpm test:live:media video`
- 范围:
- 覆盖共享的内置视频生成 provider 路径
- 默认使用对发布安全的 smoke 路径:非 FAL provider、每个 provider 一个文生视频请求、一秒钟龙虾提示词,以及来自 `OPENCLAW_LIVE_VIDEO_GENERATION_TIMEOUT_MS` 的每 provider 操作上限(默认 `180000`
- 默认跳过 FAL因为 provider 端的队列延迟可能主导发布时间;传入 `--video-providers fal``OPENCLAW_LIVE_VIDEO_GENERATION_PROVIDERS="fal"` 可显式运行它
- 在探测前从你的登录 shell`~/.profile`)加载 provider 环境变量
- 默认优先使用实时/环境变量 API key而不是已存储的 auth profile这样 `auth-profiles.json` 中过期的测试 key 就不会掩盖真实的 shell 凭证
- 跳过没有可用 auth/profile/model 的 provider
- 覆盖共享的内置视频生成提供商路径
- 默认使用适合发布的冒烟测试路径:非 FAL 提供商、每个提供商一个文生视频请求、时长一秒的龙虾提示词,以及来自 `OPENCLAW_LIVE_VIDEO_GENERATION_TIMEOUT_MS` 的每提供商操作上限(默认值为 `180000`
- 默认跳过 FAL因为提供商侧队列延迟可能主导发布时间;传入 `--video-providers fal``OPENCLAW_LIVE_VIDEO_GENERATION_PROVIDERS="fal"` 可显式运行它
- 在探测前从你的登录 shell`~/.profile`)加载提供商环境变量
- 默认优先使用实时 / 环境变量 API 密钥,而不是已存储的认证配置档,因此 `auth-profiles.json` 中过期的测试密钥不会掩盖真实的 shell 凭证
- 跳过没有可用认证 / 配置档 / 模型的提供商
- 默认仅运行 `generate`
- 设置 `OPENCLAW_LIVE_VIDEO_GENERATION_FULL_MODES=1` 还会在可用时运行已声明的 transform 模式:
- `imageToVideo`:当 provider 声明 `capabilities.imageToVideo.enabled`,且所选 provider/model 在共享扫描中接受基于 buffer 的本地图片输入时
- `videoToVideo`:当 provider 声明 `capabilities.videoToVideo.enabled`,且所选 provider/model 在共享扫描中接受基于 buffer 的本地视频输入时
- 当前在共享扫描中已声明但被跳过的 `imageToVideo` provider
- `vydra`,因为内置 `veo3` 仅支持文本,而内置 `kling` 需要远程图片 URL
- provider 专用的 Vydra 覆盖:
- 设置 `OPENCLAW_LIVE_VIDEO_GENERATION_FULL_MODES=1`,在可用时也会运行已声明的转换模式:
- 当提供商声明 `capabilities.imageToVideo.enabled`,且所选提供商 / 模型在共享全量检查中接受基于缓冲区的本地图像输入时,运行 `imageToVideo`
- 当提供商声明 `capabilities.videoToVideo.enabled`,且所选提供商 / 模型在共享全量检查中接受基于缓冲区的本地视频输入时,运行 `videoToVideo`
- 共享全量检查中当前已声明但跳过的 `imageToVideo` 提供商
- `vydra`,因为内置`veo3` 仅支持文本,而内置的 `kling` 需要远程图像 URL
- 提供商专用的 Vydra 覆盖:
- `OPENCLAW_LIVE_TEST=1 OPENCLAW_LIVE_VYDRA_VIDEO=1 pnpm test:live -- extensions/vydra/vydra.live.test.ts`
- 该文件会运行 `veo3` 文生视频,以及一个默认使用远程图片 URL fixture 的 `kling` 通道
- 该文件默认运行 `veo3` 文生视频,以及一个使用远程图像 URL 固定数据的 `kling` 测试路径
- 当前 `videoToVideo` 实时覆盖:
- 仅 `runway`,且所选模型为 `runway/gen4_aleph`
- 当前在共享扫描中已声明但被跳过的 `videoToVideo` provider
- 共享全量检查中当前已声明但跳过的 `videoToVideo` 提供商
- `alibaba`、`qwen`、`xai`,因为这些路径当前需要远程 `http(s)` / MP4 参考 URL
- `google`,因为当前共享 Gemini/Veo 通道使用基于本地 buffer 的输入,而该路径在共享扫描中不被接受
- `openai`,因为当前共享通道缺少对组织专用视频 inpaint/remix 访问的保证
- `google`,因为当前共享 Gemini / Veo 路径使用基于本地缓冲区的输入,而该路径在共享全量检查中不被接受
- `openai`,因为当前共享路径缺乏针对组织的视频修补 / remix 访问保证
- 可选缩小范围:
- `OPENCLAW_LIVE_VIDEO_GENERATION_PROVIDERS="google,openai,runway"`
- `OPENCLAW_LIVE_VIDEO_GENERATION_MODELS="google/veo-3.1-fast-generate-preview,openai/sora-2,runway/gen4_aleph"`
- `OPENCLAW_LIVE_VIDEO_GENERATION_SKIP_PROVIDERS=""` 以在默认扫描中包含所有 provider,包括 FAL
- `OPENCLAW_LIVE_VIDEO_GENERATION_TIMEOUT_MS=60000` 以降低每个 provider 的操作上限,用于更激进的 smoke 运行
- `OPENCLAW_LIVE_VIDEO_GENERATION_SKIP_PROVIDERS=""` 以在默认全量检查中包含所有提供商,包括 FAL
- `OPENCLAW_LIVE_VIDEO_GENERATION_TIMEOUT_MS=60000` 以降低每个提供商的操作上限,用于激进的冒烟测试运行
- 可选认证行为:
- `OPENCLAW_LIVE_REQUIRE_PROFILE_KEYS=1` 强制使用 profile 存储认证,并忽略仅环境变量覆盖
- `OPENCLAW_LIVE_REQUIRE_PROFILE_KEYS=1` 可强制使用配置档存储认证,并忽略仅环境变量覆盖
## 媒体实时 harness
## 媒体实时测试 Harness
- 命令:`pnpm test:live:media`
- 目的:
- 通过一个仓库原生入口运行共享的图片、音乐和视频实时套件
- 自动从 `~/.profile` 加载缺失的 provider 环境变量
- 默认自动将每个套件缩小到当前拥有可用认证的 provider
- 复用 `scripts/test-live.mjs`,因此 heartbeat 和 quiet-mode 行为保持一致
- 通过一个仓库原生入口点运行共享的图像、音乐和视频实时测试套件
- 自动从 `~/.profile` 加载缺失的提供商环境变量
- 默认自动将每个测试套件缩小到当前具有可用认证的提供商
- 复用 `scripts/test-live.mjs`,因此心跳和静默模式行为保持一致
- 示例:
- `pnpm test:live:media`
- `pnpm test:live:media image video --providers openai,google,minimax`
@ -494,4 +501,4 @@ Docker 说明:
## 相关内容
- [Testing](/zh-CN/help/testing) — 单元、集成、QA 和 Docker 套件
- [测试](/zh-CN/help/testing) — 单元、集成、QA 和 Docker 测试套件

View File

@ -0,0 +1,544 @@
---
read_when:
- 你正在将 context-engine 生命周期行为接入 Codex harness
- 你需要让 lossless-claw 或其他 context-engine 插件能够与 `codex/*` 内嵌 harness 会话一起工作
- 你正在比较嵌入式 PI 与 Codex app-server 的上下文行为
summary: 使内置的 Codex app-server harness 支持 OpenClaw context-engine 插件的规范
title: Codex Harness Context Engine Port
x-i18n:
generated_at: "2026-04-24T04:20:49Z"
model: gpt-5.4
provider: openai
source_hash: 9d6b106915f2888337cb08c831c1722770ad8ec6612c575efe88fe2fc263dec5
source_path: plan/codex-context-engine-harness.md
workflow: 15
---
# Codex Harness Context Engine Port
## 状态
实施规范草案。
## 目标
让内置的 Codex app-server harness 遵循与嵌入式 PI 轮次当前已遵循的相同 OpenClaw context-engine 生命周期契约。
使用 `agents.defaults.embeddedHarness.runtime: "codex"``codex/*` 模型的会话,仍应允许所选的 context-engine 插件(例如 `lossless-claw`)在 Codex app-server 边界允许的范围内,控制上下文组装、轮次后摄取、维护以及 OpenClaw 级别的压缩策略。
## 非目标
- 不要重新实现 Codex app-server 内部机制。
- 不要让 Codex 原生线程压缩生成 `lossless-claw` 摘要。
- 不要要求非 Codex 模型使用 Codex harness。
- 不要更改 ACP/acpx 会话行为。此规范仅适用于非 ACP 的嵌入式智能体 harness 路径。
- 不要让第三方插件注册 Codex app-server 扩展工厂;现有的内置插件信任边界保持不变。
## 当前架构
嵌入式运行循环在选择具体的底层 harness 之前,每次运行都会解析一次已配置的 context engine
- `src/agents/pi-embedded-runner/run.ts`
- 初始化 context-engine 插件
- 调用 `resolveContextEngine(params.config)`
- 将 `contextEngine``contextTokenBudget` 传入 `runEmbeddedAttemptWithBackend(...)`
`runEmbeddedAttemptWithBackend(...)` 会委托给所选的智能体 harness
- `src/agents/pi-embedded-runner/run/backend.ts`
- `src/agents/harness/selection.ts`
Codex app-server harness 由内置的 Codex 插件注册:
- `extensions/codex/index.ts`
- `extensions/codex/harness.ts`
Codex harness 实现接收与 PI 支持的 attempt 相同的 `EmbeddedRunAttemptParams`
- `extensions/codex/src/app-server/run-attempt.ts`
这意味着所需的 hook 点位于 OpenClaw 可控的代码中。外部边界是 Codex app-server 协议本身OpenClaw 可以控制发送到 `thread/start`、`thread/resume` 和 `turn/start` 的内容,也可以观察通知,但无法更改 Codex 的内部线程存储或原生压缩器。
## 当前缺口
嵌入式 PI attempt 会直接调用 context-engine 生命周期:
- 在 attempt 之前执行 bootstrap/maintenance
- 在模型调用之前执行 assemble
- 在 attempt 之后执行 afterTurn 或 ingest
- 在成功轮次后执行 maintenance
- 对于拥有压缩能力的引擎,执行 context-engine compaction
相关 PI 代码:
- `src/agents/pi-embedded-runner/run/attempt.ts`
- `src/agents/pi-embedded-runner/run/attempt.context-engine-helpers.ts`
- `src/agents/pi-embedded-runner/context-engine-maintenance.ts`
Codex app-server attempt 目前会运行通用的智能体 harness hook 并镜像转录记录,但不会调用 `params.contextEngine.bootstrap`、`params.contextEngine.assemble`、`params.contextEngine.afterTurn`、`params.contextEngine.ingestBatch`、`params.contextEngine.ingest` 或 `params.contextEngine.maintain`
相关 Codex 代码:
- `extensions/codex/src/app-server/run-attempt.ts`
- `extensions/codex/src/app-server/thread-lifecycle.ts`
- `extensions/codex/src/app-server/event-projector.ts`
- `extensions/codex/src/app-server/compact.ts`
## 期望行为
对于 Codex harness 轮次OpenClaw 应保留以下生命周期:
1. 读取镜像后的 OpenClaw 会话转录记录。
2. 当存在先前的会话文件时,对活动的 context engine 执行 bootstrap。
3. 在可用时运行 bootstrap maintenance。
4. 使用活动的 context engine 组装上下文。
5. 将组装后的上下文转换为与 Codex 兼容的输入。
6. 使用包含任意 context-engine `systemPromptAddition` 的开发者指令启动或恢复 Codex 线程。
7. 使用组装后的面向用户提示启动 Codex 轮次。
8. 将 Codex 结果镜像回 OpenClaw 转录记录。
9. 如果已实现,则调用 `afterTurn`;否则使用镜像后的转录记录快照调用 `ingestBatch`/`ingest`。
10. 在成功且未中止的轮次后运行轮次 maintenance。
11. 保留 Codex 原生压缩信号和 OpenClaw 压缩 hook。
## 设计约束
### Codex app-server 仍然是原生线程状态的规范来源
Codex 拥有其原生线程以及任何内部扩展历史。OpenClaw 不应尝试修改 app-server 的内部历史,除非通过受支持的协议调用。
OpenClaw 的转录镜像仍然是 OpenClaw 功能的来源:
- 聊天历史
- 搜索
- `/new``/reset` 记账
- 未来的模型或 harness 切换
- context-engine 插件状态
### Context engine 组装必须投影为 Codex 输入
context-engine 接口返回的是 OpenClaw `AgentMessage[]`,而不是 Codex 线程补丁。Codex app-server 的 `turn/start` 接受当前用户输入,而 `thread/start``thread/resume` 接受开发者指令。
因此,实现需要一个投影层。安全的第一个版本应避免假装它可以替换 Codex 内部历史。它应在当前轮次周围,将组装后的上下文注入为确定性的提示/开发者指令材料。
### Prompt-cache 稳定性很重要
对于像 lossless-claw 这样的引擎,在输入未变化时,组装后的上下文应保持确定性。不要向生成的上下文文本中添加时间戳、随机 id 或非确定性排序。
### PI 回退语义不变
harness 选择逻辑保持不变:
- `runtime: "pi"` 强制使用 PI
- `runtime: "codex"` 选择已注册的 Codex harness
- `runtime: "auto"` 允许插件 harness 声明其支持的提供商
- `fallback: "none"` 在没有匹配的插件 harness 时禁用 PI 回退
这项工作改变的是选中 Codex harness 之后发生的行为。
## 实施计划
### 1. 导出或迁移可复用的 context-engine attempt helper
目前,可复用的生命周期 helper 位于 PI runner 下:
- `src/agents/pi-embedded-runner/run/attempt.context-engine-helpers.ts`
- `src/agents/pi-embedded-runner/run/attempt.prompt-helpers.ts`
- `src/agents/pi-embedded-runner/context-engine-maintenance.ts`
如果可以避免Codex 不应从一个名称暗示 PI 的实现路径导入。
创建一个与 harness 无关的模块,例如:
- `src/agents/harness/context-engine-lifecycle.ts`
迁移或重新导出:
- `runAttemptContextEngineBootstrap`
- `assembleAttemptContextEngine`
- `finalizeAttemptContextEngineTurn`
- `buildAfterTurnRuntimeContext`
- `buildAfterTurnRuntimeContextFromUsage`
- 一个围绕 `runContextEngineMaintenance` 的小型包装器
通过从旧文件重新导出,或在同一个 PR 中更新 PI 调用点,保持 PI 导入继续正常工作。
中性的 helper 名称不应提及 PI。
建议命名:
- `bootstrapHarnessContextEngine`
- `assembleHarnessContextEngine`
- `finalizeHarnessContextEngineTurn`
- `buildHarnessContextEngineRuntimeContext`
- `runHarnessContextEngineMaintenance`
### 2. 添加一个 Codex 上下文投影 helper
添加一个新模块:
- `extensions/codex/src/app-server/context-engine-projection.ts`
职责:
- 接收组装后的 `AgentMessage[]`、原始镜像历史和当前提示。
- 确定哪些上下文应放入开发者指令,哪些应放入当前用户输入。
- 保留当前用户提示作为最终的可执行请求。
- 以稳定、明确的格式渲染先前消息。
- 避免易变元数据。
建议 API
```ts
export type CodexContextProjection = {
developerInstructionAddition?: string;
promptText: string;
assembledMessages: AgentMessage[];
prePromptMessageCount: number;
};
export function projectContextEngineAssemblyForCodex(params: {
assembledMessages: AgentMessage[];
originalHistoryMessages: AgentMessage[];
prompt: string;
systemPromptAddition?: string;
}): CodexContextProjection;
```
建议的第一版投影:
- 将 `systemPromptAddition` 放入开发者指令。
- 将组装后的转录上下文放在 `promptText` 中当前提示之前。
- 明确标注这是 OpenClaw 为本轮组装的上下文。
- 保持当前提示位于最后。
- 如果当前用户提示已出现在尾部,则排除重复的当前用户提示。
示例提示结构:
```text
OpenClaw assembled context for this turn:
<conversation_context>
[user]
...
[assistant]
...
</conversation_context>
Current user request:
...
```
这不如原生的 Codex 历史修补优雅,但它可以在 OpenClaw 内部实现,并保留 context-engine 语义。
未来改进:如果 Codex app-server 暴露了用于替换或补充线程历史的协议,则将此投影层切换为使用该 API。
### 3. 在 Codex 线程启动之前接入 bootstrap
`extensions/codex/src/app-server/run-attempt.ts` 中:
- 像现在一样读取镜像会话历史。
- 确定本次运行之前会话文件是否已存在。优先使用一个在镜像写入前检查 `fs.stat(params.sessionFile)` 的 helper。
- 打开一个 `SessionManager`,或者如果 helper 需要,使用一个窄接口的会话管理器适配器。
- 当 `params.contextEngine` 存在时,调用中性的 bootstrap helper。
伪流程:
```ts
const hadSessionFile = await fileExists(params.sessionFile);
const sessionManager = SessionManager.open(params.sessionFile);
const historyMessages = sessionManager.buildSessionContext().messages;
await bootstrapHarnessContextEngine({
hadSessionFile,
contextEngine: params.contextEngine,
sessionId: params.sessionId,
sessionKey: sandboxSessionKey,
sessionFile: params.sessionFile,
sessionManager,
runtimeContext: buildHarnessContextEngineRuntimeContext(...),
runMaintenance: runHarnessContextEngineMaintenance,
warn,
});
```
使用与 Codex 工具桥接和转录镜像相同的 `sessionKey` 约定。当前 Codex 会根据 `params.sessionKey``params.sessionId` 计算 `sandboxSessionKey`;除非有理由保留原始 `params.sessionKey`,否则应一致使用该值。
### 4. 在 `thread/start` / `thread/resume``turn/start` 之前接入 assemble
`runCodexAppServerAttempt` 中:
1. 先构建动态工具,这样 context engine 才能看到实际可用的工具名称。
2. 读取镜像会话历史。
3. 当 `params.contextEngine` 存在时,运行 context-engine `assemble(...)`
4. 将组装结果投影为:
- 开发者指令追加内容
- `turn/start` 的提示文本
现有的 hook 调用:
```ts
resolveAgentHarnessBeforePromptBuildResult({
prompt: params.prompt,
developerInstructions: buildDeveloperInstructions(params),
messages: historyMessages,
ctx: hookContext,
});
```
应改为具备上下文感知能力:
1. 使用 `buildDeveloperInstructions(params)` 计算基础开发者指令
2. 应用 context-engine 组装/投影
3. 运行 `before_prompt_build`,并传入投影后的提示/开发者指令
这个顺序让通用提示 hook 能看到 Codex 实际会收到的同一份提示。如果我们需要与 PI 严格一致,应在 hook 组合之前运行 context-engine 组装,因为 PI 会在其提示流水线之后,将 context-engine `systemPromptAddition` 应用到最终系统提示中。重要的不变量是context engine 和 hook 都要得到一个确定且有文档说明的顺序。
第一版实现建议顺序:
1. `buildDeveloperInstructions(params)`
2. context-engine `assemble()`
3. 将 `systemPromptAddition` 追加/前置到开发者指令中
4. 将组装后的消息投影到提示文本中
5. `resolveAgentHarnessBeforePromptBuildResult(...)`
6. 将最终开发者指令传给 `startOrResumeThread(...)`
7. 将最终提示文本传给 `buildTurnStartParams(...)`
应将该规范编码进测试中,以避免未来的改动意外改变顺序。
### 5. 保持 prompt-cache 的稳定格式
投影 helper 必须对相同输入生成字节稳定的输出:
- 稳定的消息顺序
- 稳定的角色标签
- 不生成时间戳
- 不泄露对象键顺序
- 不使用随机分隔符
- 不使用每次运行都变化的 id
使用固定分隔符和明确的分段。
### 6. 在转录镜像之后接入轮次后处理
Codex 的 `CodexAppServerEventProjector` 会为当前轮次构建一个本地 `messagesSnapshot`。`mirrorTranscriptBestEffort(...)` 会将该快照写入 OpenClaw 转录镜像。
在镜像成功或失败之后,使用最佳可用的消息快照调用 context-engine finalizer
- 优先使用写入后的完整镜像会话上下文,因为 `afterTurn` 期望的是会话快照,而不只是当前轮次。
- 如果无法重新打开会话文件,则回退到 `historyMessages + result.messagesSnapshot`
伪流程:
```ts
const prePromptMessageCount = historyMessages.length;
await mirrorTranscriptBestEffort(...);
const finalMessages = readMirroredSessionHistoryMessages(params.sessionFile)
?? [...historyMessages, ...result.messagesSnapshot];
await finalizeHarnessContextEngineTurn({
contextEngine: params.contextEngine,
promptError: Boolean(finalPromptError),
aborted: finalAborted,
yieldAborted,
sessionIdUsed: params.sessionId,
sessionKey: sandboxSessionKey,
sessionFile: params.sessionFile,
messagesSnapshot: finalMessages,
prePromptMessageCount,
tokenBudget: params.contextTokenBudget,
runtimeContext: buildHarnessContextEngineRuntimeContextFromUsage({
attempt: params,
workspaceDir: effectiveWorkspace,
agentDir,
tokenBudget: params.contextTokenBudget,
lastCallUsage: result.attemptUsage,
promptCache: result.promptCache,
}),
runMaintenance: runHarnessContextEngineMaintenance,
sessionManager,
warn,
});
```
如果镜像失败,仍然使用回退快照调用 `afterTurn`,但要记录 context engine 正在使用回退轮次数据进行摄取。
### 7. 规范化 usage 和 prompt-cache 运行时上下文
Codex 结果在可用时会包含来自 app-server token 通知的规范化 usage。将该 usage 传入 context-engine 运行时上下文。
如果 Codex app-server 未来暴露缓存读/写细节,将其映射到 `ContextEnginePromptCacheInfo`。在此之前,省略 `promptCache`,而不是虚构零值。
### 8. 压缩策略
存在两套压缩系统:
1. OpenClaw context-engine `compact()`
2. Codex app-server 原生 `thread/compact/start`
不要悄悄将它们混为一谈。
#### `/compact` 和显式 OpenClaw 压缩
当所选 context engine 具有 `info.ownsCompaction === true` 时,显式 OpenClaw 压缩应优先使用 context engine 的 `compact()` 结果,以更新 OpenClaw 转录镜像和插件状态。
当所选 Codex harness 具有原生线程绑定时,我们还可以额外请求 Codex 原生压缩,以保持 app-server 线程健康,但这必须在详情中作为单独的后端操作进行报告。
建议行为:
- 如果 `contextEngine.info.ownsCompaction === true`
- 先调用 context-engine `compact()`
- 然后在存在线程绑定时尽力调用 Codex 原生压缩
- 返回 context-engine 结果作为主结果
- 在 `details.codexNativeCompaction` 中包含 Codex 原生压缩状态
- 如果活动的 context engine 不拥有压缩能力:
- 保留当前 Codex 原生压缩行为
这可能需要修改 `extensions/codex/src/app-server/compact.ts`,或从通用压缩路径中对其进行包装,具体取决于 `maybeCompactAgentHarnessSession(...)` 的调用位置。
#### 轮次内 Codex 原生 `contextCompaction` 事件
Codex 可能在轮次中发出 `contextCompaction` item 事件。保留 `event-projector.ts` 中当前的压缩前/压缩后 hook 发射逻辑,但不要将其视为已完成的 context-engine 压缩。
对于拥有压缩能力的引擎,当 Codex 仍然执行原生压缩时,发出明确的诊断信息:
- stream/event 名称:现有的 `compaction` stream 可以接受
- details`{ backend: "codex-app-server", ownsCompaction: true }`
这样可以让这一区分可审计。
### 9. 会话重置与绑定行为
现有的 Codex harness `reset(...)` 会从 OpenClaw 会话文件中清除 Codex app-server 绑定。保留该行为。
同时,确保 context-engine 状态清理继续通过现有 OpenClaw 会话生命周期路径进行。不要添加 Codex 专用清理,除非当前的 context-engine 生命周期对所有 harness 都遗漏了 reset/delete 事件。
### 10. 错误处理
遵循 PI 语义:
- bootstrap 失败时发出警告并继续
- assemble 失败时发出警告,并回退到未组装的流水线消息/提示
- afterTurn/ingest 失败时发出警告,并将轮次后 finalize 标记为不成功
- maintenance 仅在成功、未中止、非 yield 终止的轮次后运行
- 压缩错误不应作为新的提示重试
Codex 专属补充:
- 如果上下文投影失败,发出警告并回退到原始提示。
- 如果转录镜像失败,仍尝试使用回退消息执行 context-engine finalize。
- 如果在 context-engine 压缩成功后 Codex 原生压缩失败,当 context engine 是主路径时,不要让整个 OpenClaw 压缩失败。
## 测试计划
### 单元测试
`extensions/codex/src/app-server` 下添加测试:
1. `run-attempt.context-engine.test.ts`
- 当会话文件存在时Codex 调用 `bootstrap`
- Codex 使用镜像消息、token budget、工具名称、citations 模式、模型 id 和提示调用 `assemble`
- `systemPromptAddition` 会包含在开发者指令中。
- 组装后的消息会在当前请求之前投影到提示中。
- Codex 会在转录镜像之后调用 `afterTurn`
- 在没有 `afterTurn`Codex 调用 `ingestBatch` 或按消息逐条调用 `ingest`
- 轮次 maintenance 会在成功轮次后运行。
- 在提示错误、中止或 yield 中止时,不运行轮次 maintenance。
2. `context-engine-projection.test.ts`
- 相同输入生成稳定输出
- 当组装后的历史已包含当前提示时,不重复当前提示
- 处理空历史
- 保留角色顺序
- 仅在开发者指令中包含 system prompt addition
3. `compact.context-engine.test.ts`
- 拥有压缩能力的 context engine 主结果优先
- 在同时尝试时,详情中会出现 Codex 原生压缩状态
- Codex 原生压缩失败不会导致拥有压缩能力的 context-engine 压缩失败
- 不拥有压缩能力的 context engine 保留当前原生压缩行为
### 需要更新的现有测试
- `extensions/codex/src/app-server/run-attempt.test.ts`,如果存在;否则更新最近的 Codex app-server 运行测试。
- `extensions/codex/src/app-server/event-projector.test.ts`,仅当压缩事件详情发生变化时更新。
- `src/agents/harness/selection.test.ts` 除非配置行为发生变化,否则不应需要修改;它应保持稳定。
- PI context-engine 测试应继续在不改动的情况下通过。
### 集成 / 实时测试
添加或扩展实时 Codex harness 冒烟测试:
- 配置 `plugins.slots.contextEngine` 为测试引擎
- 配置 `agents.defaults.model``codex/*` 模型
- 配置 `agents.defaults.embeddedHarness.runtime = "codex"`
- 断言测试引擎已观察到:
- bootstrap
- assemble
- afterTurn 或 ingest
- maintenance
避免在 OpenClaw 核心测试中要求依赖 lossless-claw。使用仓库内一个小型的 fake context engine 插件。
## 可观测性
围绕 Codex context-engine 生命周期调用添加调试日志:
- `codex context engine bootstrap started/completed/failed`
- `codex context engine assemble applied`
- `codex context engine finalize completed/failed`
- `codex context engine maintenance skipped`,并带上原因
- `codex native compaction completed alongside context-engine compaction`
避免记录完整提示或转录内容。
在有用时添加结构化字段:
- `sessionId`
- `sessionKey`,根据现有日志实践进行脱敏或省略
- `engineId`
- `threadId`
- `turnId`
- `assembledMessageCount`
- `estimatedTokens`
- `hasSystemPromptAddition`
## 迁移 / 兼容性
这应当保持向后兼容:
- 如果未配置 context engine旧版 context engine 行为应与当前 Codex harness 行为等价。
- 如果 context-engine `assemble` 失败Codex 应继续使用原始提示路径。
- 现有 Codex 线程绑定应继续有效。
- 动态工具指纹不应包含 context-engine 输出;否则每次上下文变化都可能强制创建新的 Codex 线程。只有工具目录应影响动态工具指纹。
## 未决问题
1. 组装后的上下文应全部注入用户提示、全部注入开发者指令,还是拆分注入?
建议:拆分。将 `systemPromptAddition` 放入开发者指令;将组装后的转录上下文放入用户提示包装中。这最符合当前 Codex 协议,同时不修改原生线程历史。
2. 当 context engine 拥有压缩能力时,是否应禁用 Codex 原生压缩?
建议至少初期不要。Codex 原生压缩可能仍然是保持 app-server 线程存活所必需的。但必须将其报告为 Codex 原生压缩,而不是 context-engine 压缩。
3. `before_prompt_build` 应在 context-engine assemble 之前还是之后运行?
建议:对于 Codex在 context-engine 投影之后运行,这样通用 harness hook 能看到 Codex 实际会收到的提示/开发者指令。如果与 PI 的一致性要求相反,应在测试中编码所选顺序,并在此处记录。
4. Codex app-server 是否可以接受未来的结构化上下文/历史覆盖?
未知。如果可以,用该协议替换文本投影层,并保持生命周期调用不变。
## 验收标准
- 一个 `codex/*` 内嵌 harness 轮次会调用所选 context engine 的 assemble 生命周期。
- context-engine `systemPromptAddition` 会影响 Codex 开发者指令。
- 组装后的上下文会以确定性的方式影响 Codex 轮次输入。
- 成功的 Codex 轮次会调用 `afterTurn` 或 ingest 回退路径。
- 成功的 Codex 轮次会运行 context-engine 轮次 maintenance。
- 失败/中止/yield 中止的轮次不会运行轮次 maintenance。
- 由 context-engine 拥有的压缩仍然是 OpenClaw/插件状态的主路径。
- Codex 原生压缩仍然可作为原生 Codex 行为被审计。
- 现有 PI context-engine 行为保持不变。
- 当未选择非旧版 context engine或当 assemble 失败时,现有 Codex harness 行为保持不变。

View File

@ -1,27 +1,27 @@
---
read_when:
- 为插件导入选择合适的 plugin-sdk 子路径
- 审查 bundled-plugin 子路径和辅助接口 surface
summary: 插件 SDK 子路径目录:按领域分组说明各导入路径的位置
- 审查 bundled-plugin 子路径和辅助接口
summary: 插件 SDK 子路径目录:按领域分组说明各导入项所在位置
title: 插件 SDK 子路径
x-i18n:
generated_at: "2026-04-24T02:20:28Z"
generated_at: "2026-04-24T04:20:43Z"
model: gpt-5.4
provider: openai
source_hash: 592cd599c9026eb584773cb7991dd75796f58cd62cd3a85d32e5b106440f7c3e
source_hash: 2436ef1e2ecba9e5d29947819871763a7ca2fafc6cc220676d6147dad8a78247
source_path: plugins/sdk-subpaths.md
workflow: 15
---
plugin SDK 通过 `openclaw/plugin-sdk/` 下的一组精细子路径公开
本页按用途分组,汇总常用的子路径。完整的 200+ 子路径生成列表位于 `scripts/lib/plugin-sdk-entrypoints.json`
其中也包含保留的 bundled-plugin 辅助子路径,但除非某个文档页面明确将其作为公开能力介绍,否则它们都属于实现细节。
plugin SDK 通过 `openclaw/plugin-sdk/` 下的一组精简子路径对外暴露
本页按用途分组,汇总了常用子路径。生成的完整列表200 多个子路径)位于 `scripts/lib/plugin-sdk-entrypoints.json`
其中也会出现为 bundled-plugin 预留的辅助子路径,但除非某个文档页面明确将其推广为公开接口,否则它们都属于实现细节。
关于插件编写指南,参见 [插件 SDK 概览](/zh-CN/plugins/sdk-overview)。
关于插件编写指南,请参阅 [插件 SDK 概览](/zh-CN/plugins/sdk-overview)。
## 插件入口
| 子路径 | 关键导出 |
| 子路径 | 关键导出 |
| --------------------------- | -------------------------------------------------------------------------------------------------------------------------------------- |
| `plugin-sdk/plugin-entry` | `definePluginEntry` |
| `plugin-sdk/core` | `defineChannelPluginEntry`, `createChatChannelPlugin`, `createChannelPluginBase`, `defineSetupPluginEntry`, `buildChannelConfigSchema` |
@ -32,216 +32,217 @@ x-i18n:
<Accordion title="渠道子路径">
| 子路径 | 关键导出 |
| --- | --- |
| `plugin-sdk/channel-core` | `defineChannelPluginEntry`、`defineSetupPluginEntry`、`createChatChannelPlugin`、`createChannelPluginBase` |
| `plugin-sdk/config-schema` | 根 `openclaw.json` Zod schema 导出(`OpenClawSchema` |
| `plugin-sdk/channel-setup` | `createOptionalChannelSetupSurface`、`createOptionalChannelSetupAdapter`、`createOptionalChannelSetupWizard`,以及 `DEFAULT_ACCOUNT_ID`、`createTopLevelChannelDmPolicy`、`setSetupChannelEnabled`、`splitSetupEntries` |
| `plugin-sdk/setup` | 共享设置向导辅助工具、allowlist 提示、设置状态构建器 |
| `plugin-sdk/setup-runtime` | `createPatchedAccountSetupAdapter`、`createEnvPatchedAccountSetupAdapter`、`createSetupInputPresenceValidator`、`noteChannelLookupFailure`、`noteChannelLookupSummary`、`promptResolvedAllowFrom`、`splitSetupEntries`、`createAllowlistSetupWizardProxy`、`createDelegatedSetupWizardProxy` |
| `plugin-sdk/channel-core` | `defineChannelPluginEntry`, `defineSetupPluginEntry`, `createChatChannelPlugin`, `createChannelPluginBase` |
| `plugin-sdk/config-schema` | 根 `openclaw.json` Zod schema 导出(`OpenClawSchema` |
| `plugin-sdk/channel-setup` | `createOptionalChannelSetupSurface`, `createOptionalChannelSetupAdapter`, `createOptionalChannelSetupWizard`,以及 `DEFAULT_ACCOUNT_ID`, `createTopLevelChannelDmPolicy`, `setSetupChannelEnabled`, `splitSetupEntries` |
| `plugin-sdk/setup` | 共享设置向导辅助工具、allowlist 提示、设置状态构建器 |
| `plugin-sdk/setup-runtime` | `createPatchedAccountSetupAdapter`, `createEnvPatchedAccountSetupAdapter`, `createSetupInputPresenceValidator`, `noteChannelLookupFailure`, `noteChannelLookupSummary`, `promptResolvedAllowFrom`, `splitSetupEntries`, `createAllowlistSetupWizardProxy`, `createDelegatedSetupWizardProxy` |
| `plugin-sdk/setup-adapter-runtime` | `createEnvPatchedAccountSetupAdapter` |
| `plugin-sdk/setup-tools` | `formatCliCommand`、`detectBinary`、`extractArchive`、`resolveBrewExecutable`、`formatDocsLink`、`CONFIG_DIR` |
| `plugin-sdk/account-core` | 多账户配置/操作门控辅助工具,以及默认账户回退辅助工具 |
| `plugin-sdk/setup-tools` | `formatCliCommand`, `detectBinary`, `extractArchive`, `resolveBrewExecutable`, `formatDocsLink`, `CONFIG_DIR` |
| `plugin-sdk/account-core` | 多账户配置 / 操作门控辅助工具,以及默认账户回退辅助工具 |
| `plugin-sdk/account-id` | `DEFAULT_ACCOUNT_ID`、account-id 规范化辅助工具 |
| `plugin-sdk/account-resolution` | 账户查找 + 默认回退辅助工具 |
| `plugin-sdk/account-helpers` | 精细的账户列表/账户操作辅助工具 |
| `plugin-sdk/account-resolution` | 账户查找 + 默认回退辅助工具 |
| `plugin-sdk/account-helpers` | 精简的账户列表 / 账户操作辅助工具 |
| `plugin-sdk/channel-pairing` | `createChannelPairingController` |
| `plugin-sdk/channel-reply-pipeline` | `createChannelReplyPipeline` |
| `plugin-sdk/channel-config-helpers` | `createHybridChannelConfigAdapter` |
| `plugin-sdk/channel-config-schema` | 渠道配置 schema 类型 |
| `plugin-sdk/telegram-command-config` | Telegram 自定义命令规范化/校验辅助工具,并带有 bundled-contract 回退 |
| `plugin-sdk/command-gating` | 精的命令授权门控辅助工具 |
| `plugin-sdk/telegram-command-config` | Telegram 自定义命令规范化 / 校验辅助工具,并带有 bundled-contract 回退 |
| `plugin-sdk/command-gating` | 精的命令授权门控辅助工具 |
| `plugin-sdk/channel-policy` | `resolveChannelGroupRequireMention` |
| `plugin-sdk/channel-lifecycle` | `createAccountStatusSink`、草稿流生命周期/完成辅助工具 |
| `plugin-sdk/inbound-envelope` | 共享入站路由 + envelope 构建辅助工具 |
| `plugin-sdk/inbound-reply-dispatch` | 共享入站记录与分发辅助工具 |
| `plugin-sdk/messaging-targets` | 目标解析/匹配辅助工具 |
| `plugin-sdk/outbound-media` | 共享出站媒体加载辅助工具 |
| `plugin-sdk/channel-lifecycle` | `createAccountStatusSink`、草稿流生命周期 / 收尾辅助工具 |
| `plugin-sdk/inbound-envelope` | 共享入站路由 + envelope 构建辅助工具 |
| `plugin-sdk/inbound-reply-dispatch` | 共享入站记录与分发辅助工具 |
| `plugin-sdk/messaging-targets` | 目标解析 / 匹配辅助工具 |
| `plugin-sdk/outbound-media` | 共享出站媒体加载辅助工具 |
| `plugin-sdk/outbound-runtime` | 出站身份、发送委托和负载规划辅助工具 |
| `plugin-sdk/poll-runtime` | 精的投票规范化辅助工具 |
| `plugin-sdk/poll-runtime` | 精的投票规范化辅助工具 |
| `plugin-sdk/thread-bindings-runtime` | 线程绑定生命周期与适配器辅助工具 |
| `plugin-sdk/agent-media-payload` | 旧版智能体媒体负载构建器 |
| `plugin-sdk/conversation-runtime` | 会话/线程绑定、配对和已配置绑定辅助工具 |
| `plugin-sdk/conversation-runtime` | 会话 / 线程绑定、配对以及已配置绑定辅助工具 |
| `plugin-sdk/runtime-config-snapshot` | 运行时配置快照辅助工具 |
| `plugin-sdk/runtime-group-policy` | 运行时群组策略解析辅助工具 |
| `plugin-sdk/channel-status` | 共享渠道状态快照/摘要辅助工具 |
| `plugin-sdk/channel-config-primitives` | 精的渠道配置 schema 基元 |
| `plugin-sdk/channel-status` | 共享渠道状态快照 / 摘要辅助工具 |
| `plugin-sdk/channel-config-primitives` | 精的渠道配置 schema 基元 |
| `plugin-sdk/channel-config-writes` | 渠道配置写入授权辅助工具 |
| `plugin-sdk/channel-plugin-common` | 共享的渠道插件前导导出 |
| `plugin-sdk/allowlist-config-edit` | allowlist 配置编辑/读取辅助工具 |
| `plugin-sdk/group-access` | 共享的群组访问决策辅助工具 |
| `plugin-sdk/direct-dm` | 共享的私信认证/保护辅助工具 |
| `plugin-sdk/interactive-runtime` | 语义化消息呈现、投递和旧版交互式回复辅助工具。参见 [消息呈现](/zh-CN/plugins/message-presentation) |
| `plugin-sdk/channel-inbound` | 为入站去抖动、提及匹配、提及策略辅助工具和 envelope 辅助工具提供兼容性 barrel |
| `plugin-sdk/channel-mention-gating` | 不包含更广泛入站运行时接口的精细提及策略辅助工具 |
| `plugin-sdk/channel-location` | 渠道位置上下文与格式化辅助工具 |
| `plugin-sdk/channel-logging` | 用于入站丢弃以及 typing/ack 失败的渠道日志辅助工具 |
| `plugin-sdk/channel-plugin-common` | 共享渠道插件前导导出 |
| `plugin-sdk/allowlist-config-edit` | allowlist 配置编辑 / 读取辅助工具 |
| `plugin-sdk/group-access` | 共享群组访问决策辅助工具 |
| `plugin-sdk/direct-dm` | 共享直接私信认证 / 守卫辅助工具 |
| `plugin-sdk/interactive-runtime` | 语义化消息呈现、投递以及旧版交互式回复辅助工具。参阅 [消息呈现](/zh-CN/plugins/message-presentation) |
| `plugin-sdk/channel-inbound` | 兼容性 barrel包含入站去抖、提及匹配、提及策略辅助工具以及 envelope 辅助工具 |
| `plugin-sdk/channel-inbound-debounce` | 精简的入站去抖辅助工具 |
| `plugin-sdk/channel-mention-gating` | 不包含更宽泛入站运行时接口的精简提及策略辅助工具 |
| `plugin-sdk/channel-location` | 渠道位置上下文和格式化辅助工具 |
| `plugin-sdk/channel-logging` | 用于入站丢弃以及 typing / ack 失败的渠道日志辅助工具 |
| `plugin-sdk/channel-send-result` | 回复结果类型 |
| `plugin-sdk/channel-actions` | 渠道消息操作辅助工具,以及为插件兼容性保留的已弃用原生 schema 辅助工具 |
| `plugin-sdk/channel-targets` | 目标解析/匹配辅助工具 |
| `plugin-sdk/channel-targets` | 目标解析 / 匹配辅助工具 |
| `plugin-sdk/channel-contract` | 渠道契约类型 |
| `plugin-sdk/channel-feedback` | 反馈/reaction 接线 |
| `plugin-sdk/channel-secret-runtime` | 精细的 secret-contract 辅助工具,例如 `collectSimpleChannelFieldAssignments`、`getChannelSurface`、`pushAssignment` 和 secret target 类型 |
| `plugin-sdk/channel-feedback` | 反馈 / reaction 接线 |
| `plugin-sdk/channel-secret-runtime` | 精简的 secret-contract 辅助工具,例如 `collectSimpleChannelFieldAssignments`, `getChannelSurface`, `pushAssignment`,以及 secret target 类型 |
</Accordion>
<Accordion title="提供商子路径">
| 子路径 | 关键导出 |
| --- | --- |
| `plugin-sdk/provider-entry` | `defineSingleProviderPluginEntry` |
| `plugin-sdk/provider-setup` | 精选的本地/自托管提供商设置辅助工具 |
| `plugin-sdk/self-hosted-provider-setup` | 专注于 OpenAI 兼容自托管提供商的设置辅助工具 |
| `plugin-sdk/provider-setup` | 精选的本地 / 自托管提供商设置辅助工具 |
| `plugin-sdk/self-hosted-provider-setup` | 专注于兼容 OpenAI 的自托管提供商设置辅助工具 |
| `plugin-sdk/cli-backend` | CLI 后端默认值 + watchdog 常量 |
| `plugin-sdk/provider-auth-runtime` | 面向提供商插件的运行时 API key 解析辅助工具 |
| `plugin-sdk/provider-auth-api-key` | API key 新手引导/profile 写入辅助工具,例如 `upsertApiKeyProfile` |
| `plugin-sdk/provider-auth-runtime` | 用于提供商插件的运行时 API key 解析辅助工具 |
| `plugin-sdk/provider-auth-api-key` | API key 新手引导 / profile 写入辅助工具,例如 `upsertApiKeyProfile` |
| `plugin-sdk/provider-auth-result` | 标准 OAuth 认证结果构建器 |
| `plugin-sdk/provider-auth-login` | 面向提供商插件的共享交互式登录辅助工具 |
| `plugin-sdk/provider-auth-login` | 用于提供商插件的共享交互式登录辅助工具 |
| `plugin-sdk/provider-env-vars` | 提供商认证环境变量查找辅助工具 |
| `plugin-sdk/provider-auth` | `createProviderApiKeyAuthMethod`、`ensureApiKeyFromOptionEnvOrPrompt`、`upsertAuthProfile`、`upsertApiKeyProfile`、`writeOAuthCredentials` |
| `plugin-sdk/provider-model-shared` | `ProviderReplayFamily`、`buildProviderReplayFamilyHooks`、`normalizeModelCompat`、共享 replay-policy 构建器、提供商端点辅助工具,以及诸如 `normalizeNativeXaiModelId` 之类的 model-id 规范化辅助工具 |
| `plugin-sdk/provider-catalog-shared` | `findCatalogTemplate`、`buildSingleProviderApiKeyCatalog`、`supportsNativeStreamingUsageCompat`、`applyProviderNativeStreamingUsageCompat` |
| `plugin-sdk/provider-http` | 通用提供商 HTTP/端点能力辅助工具,包括音频转录 multipart form 辅助工具 |
| `plugin-sdk/provider-web-fetch-contract` | 精细的 web-fetch 配置/选择契约辅助工具,例如 `enablePluginInConfig``WebFetchProviderPlugin` |
| `plugin-sdk/provider-web-fetch` | web-fetch 提供商注册/缓存辅助工具 |
| `plugin-sdk/provider-web-search-config-contract` | 面向不需要插件启用接线的提供商的精细 web-search 配置/凭证辅助工具 |
| `plugin-sdk/provider-web-search-contract` | 精细的 web-search 配置/凭证契约辅助工具,例如 `createWebSearchProviderContractFields`、`enablePluginInConfig`、`resolveProviderWebSearchPluginConfig` 以及带作用域的凭证 setter/getter |
| `plugin-sdk/provider-web-search` | web-search 提供商注册/缓存/运行时辅助工具 |
| `plugin-sdk/provider-tools` | `ProviderToolCompatFamily`、`buildProviderToolCompatFamilyHooks`、Gemini schema 清理 + 诊断,以及诸`resolveXaiModelCompatPatch` / `applyXaiModelCompat` 之类的 xAI 兼容辅助工具 |
| `plugin-sdk/provider-usage` | `fetchClaudeUsage` 及类似能力 |
| `plugin-sdk/provider-stream` | `ProviderStreamFamily`、`buildProviderStreamFamilyHooks`、`composeProviderStreamWrappers`、流包装器类型,以及共享的 Anthropic/Bedrock/Google/Kilocode/Moonshot/OpenAI/OpenRouter/Z.A.I/MiniMax/Copilot 包装器辅助工具 |
| `plugin-sdk/provider-transport-runtime` | 原生提供商传输辅助工具,例如受保护的 fetch、传输消息转换可写传输事件流 |
| `plugin-sdk/provider-auth` | `createProviderApiKeyAuthMethod`, `ensureApiKeyFromOptionEnvOrPrompt`, `upsertAuthProfile`, `upsertApiKeyProfile`, `writeOAuthCredentials` |
| `plugin-sdk/provider-model-shared` | `ProviderReplayFamily`, `buildProviderReplayFamilyHooks`, `normalizeModelCompat`、共享 replay-policy 构建器、provider-endpoint 辅助工具,以及诸如 `normalizeNativeXaiModelId` 之类的 model-id 规范化辅助工具 |
| `plugin-sdk/provider-catalog-shared` | `findCatalogTemplate`, `buildSingleProviderApiKeyCatalog`, `supportsNativeStreamingUsageCompat`, `applyProviderNativeStreamingUsageCompat` |
| `plugin-sdk/provider-http` | 通用提供商 HTTP / endpoint 能力辅助工具,包括音频转写 multipart form 辅助工具 |
| `plugin-sdk/provider-web-fetch-contract` | 精简的 web-fetch 配置 / 选择契约辅助工具,例如 `enablePluginInConfig``WebFetchProviderPlugin` |
| `plugin-sdk/provider-web-fetch` | web-fetch 提供商注册 / 缓存辅助工具 |
| `plugin-sdk/provider-web-search-config-contract` | 适用于不需要插件启用接线的提供商的精简 web-search 配置 / 凭证辅助工具 |
| `plugin-sdk/provider-web-search-contract` | 精简的 web-search 配置 / 凭证契约辅助工具,例如 `createWebSearchProviderContractFields`, `enablePluginInConfig`, `resolveProviderWebSearchPluginConfig`,以及带作用域的凭证 setter / getter |
| `plugin-sdk/provider-web-search` | web-search 提供商注册 / 缓存 / 运行时辅助工具 |
| `plugin-sdk/provider-tools` | `ProviderToolCompatFamily`, `buildProviderToolCompatFamilyHooks`、Gemini schema 清理 + 诊断,以及 xAI 兼容性辅助工具,例`resolveXaiModelCompatPatch` / `applyXaiModelCompat` |
| `plugin-sdk/provider-usage` | `fetchClaudeUsage` 及类似内容 |
| `plugin-sdk/provider-stream` | `ProviderStreamFamily`, `buildProviderStreamFamilyHooks`, `composeProviderStreamWrappers`、流包装器类型,以及共享的 Anthropic / Bedrock / Google / Kilocode / Moonshot / OpenAI / OpenRouter / Z.A.I / MiniMax / Copilot 包装器辅助工具 |
| `plugin-sdk/provider-transport-runtime` | 原生提供商传输辅助工具,例如受保护的 fetch、传输消息转换以及可写传输事件流 |
| `plugin-sdk/provider-onboard` | 新手引导配置补丁辅助工具 |
| `plugin-sdk/global-singleton` | 进程本地 singleton/map/cache 辅助工具 |
| `plugin-sdk/global-singleton` | 进程本地 singleton / map / cache 辅助工具 |
</Accordion>
<Accordion title="认证与安全子路径">
| 子路径 | 关键导出 |
| --- | --- |
| `plugin-sdk/command-auth` | `resolveControlCommandGate`、命令注册表辅助工具、发送授权辅助工具 |
| `plugin-sdk/command-status` | 命令/帮助消息构建器,例如 `buildCommandsMessagePaginated``buildHelpMessage` |
| `plugin-sdk/approval-auth-runtime` | 审批人解析和同聊天操作认证辅助工具 |
| `plugin-sdk/approval-client-runtime` | 原生 exec 审批 profile/filter 辅助工具 |
| `plugin-sdk/approval-delivery-runtime` | 原生审批能力/投递适配器 |
| `plugin-sdk/approval-gateway-runtime` | 共享审批 Gateway 网关解析辅助工具 |
| `plugin-sdk/approval-handler-adapter-runtime` | 面向高频渠道入口点的轻量级原生审批适配器加载辅助工具 |
| `plugin-sdk/approval-handler-runtime` | 范围更广的审批处理器运行时辅助工具;如果更精细的 adapter/gateway 接口已足够,优先使用它们 |
| `plugin-sdk/command-auth` | `resolveControlCommandGate`、命令注册表辅助工具、发送授权辅助工具 |
| `plugin-sdk/command-status` | 命令 / 帮助消息构建器,例如 `buildCommandsMessagePaginated``buildHelpMessage` |
| `plugin-sdk/approval-auth-runtime` | 审批人解析和同聊天操作认证辅助工具 |
| `plugin-sdk/approval-client-runtime` | 原生 exec 审批 profile / filter 辅助工具 |
| `plugin-sdk/approval-delivery-runtime` | 原生审批能力 / 投递适配器 |
| `plugin-sdk/approval-gateway-runtime` | 共享审批 Gateway 网关解析辅助工具 |
| `plugin-sdk/approval-handler-adapter-runtime` | 用于高频渠道入口点的轻量级原生审批适配器加载辅助工具 |
| `plugin-sdk/approval-handler-runtime` | 更宽泛的审批处理器运行时辅助工具;如果更精简的 adapter / gateway 接口已足够,优先使用那些接口 |
| `plugin-sdk/approval-native-runtime` | 原生审批目标 + 账户绑定辅助工具 |
| `plugin-sdk/approval-reply-runtime` | exec/插件审批回复负载辅助工具 |
| `plugin-sdk/channel-contract-testing` | 不包含宽泛 testing barrel 的精渠道契约测试辅助工具 |
| `plugin-sdk/approval-reply-runtime` | exec / 插件审批回复负载辅助工具 |
| `plugin-sdk/channel-contract-testing` | 不包含宽泛 testing barrel 的精渠道契约测试辅助工具 |
| `plugin-sdk/command-auth-native` | 原生命令认证 + 原生会话目标辅助工具 |
| `plugin-sdk/command-detection` | 共享命令检测辅助工具 |
| `plugin-sdk/command-primitives-runtime` | 面向高频渠道路径的轻量级命令文本谓词 |
| `plugin-sdk/command-surface` | 命令主体规范化和命令 surface 辅助工具 |
| `plugin-sdk/command-primitives-runtime` | 用于高频渠道路径的轻量级命令文本谓词 |
| `plugin-sdk/command-surface` | 命令体规范化和命令表面辅助工具 |
| `plugin-sdk/allow-from` | `formatAllowFromLowercase` |
| `plugin-sdk/channel-secret-runtime` | 面向渠道/插件 secret surface 的精细 secret-contract 收集辅助工具 |
| `plugin-sdk/secret-ref-runtime` | 面向 secret-contract/配置解析的精细 `coerceSecretRef` 和 SecretRef 类型辅助工具 |
| `plugin-sdk/security-runtime` | 共享信任、私信门控、外部内容和 secret 收集辅助工具 |
| `plugin-sdk/channel-secret-runtime` | 用于渠道 / 插件 secret surface 的精简 secret-contract 收集辅助工具 |
| `plugin-sdk/secret-ref-runtime` | 用于 secret-contract / 配置解析的精简 `coerceSecretRef` 和 SecretRef 类型辅助工具 |
| `plugin-sdk/security-runtime` | 共享信任、私信门控、外部内容和 secret 收集辅助工具 |
| `plugin-sdk/ssrf-policy` | 主机 allowlist 和私有网络 SSRF 策略辅助工具 |
| `plugin-sdk/ssrf-dispatcher` | 不包含宽泛基础设施运行时接口的精细 pinned-dispatcher 辅助工具 |
| `plugin-sdk/ssrf-runtime` | pinned-dispatcher、受 SSRF 保护的 fetch SSRF 策略辅助工具 |
| `plugin-sdk/ssrf-dispatcher` | 不包含宽泛 infra 运行时接口的精简 pinned-dispatcher 辅助工具 |
| `plugin-sdk/ssrf-runtime` | pinned-dispatcher、受 SSRF 保护的 fetch,以及 SSRF 策略辅助工具 |
| `plugin-sdk/secret-input` | secret 输入解析辅助工具 |
| `plugin-sdk/webhook-ingress` | webhook 请求/目标辅助工具 |
| `plugin-sdk/webhook-request-guards` | 请求体大小/超时辅助工具 |
| `plugin-sdk/webhook-ingress` | Webhook 请求 / 目标辅助工具 |
| `plugin-sdk/webhook-request-guards` | 请求体大小 / 超时辅助工具 |
</Accordion>
<Accordion title="运行时与存储子路径">
| 子路径 | 关键导出 |
| --- | --- |
| `plugin-sdk/runtime` | 范围广泛的运行时/日志/备份/插件安装辅助工具 |
| `plugin-sdk/runtime-env` | 精的运行时环境、日志器、超时、重试和退避辅助工具 |
| `plugin-sdk/runtime` | 宽泛的运行时 / 日志 / 备份 / 插件安装辅助工具 |
| `plugin-sdk/runtime-env` | 精的运行时环境、日志器、超时、重试和退避辅助工具 |
| `plugin-sdk/channel-runtime-context` | 通用渠道运行时上下文注册与查找辅助工具 |
| `plugin-sdk/runtime-store` | `createPluginRuntimeStore` |
| `plugin-sdk/plugin-runtime` | 共享的插件命令/hook/http/交互式辅助工具 |
| `plugin-sdk/hook-runtime` | 共享的 webhook/内部 hook 管道辅助工具 |
| `plugin-sdk/lazy-runtime` | 延迟运行时导入/绑定辅助工具,例如 `createLazyRuntimeModule`、`createLazyRuntimeMethod` 和 `createLazyRuntimeSurface` |
| `plugin-sdk/plugin-runtime` | 共享插件命令 / hook / HTTP / 交互式辅助工具 |
| `plugin-sdk/hook-runtime` | 共享 webhook / 内部 hook 流水线辅助工具 |
| `plugin-sdk/lazy-runtime` | 惰性运行时导入 / 绑定辅助工具,例如 `createLazyRuntimeModule`、`createLazyRuntimeMethod` 和 `createLazyRuntimeSurface` |
| `plugin-sdk/process-runtime` | 进程 exec 辅助工具 |
| `plugin-sdk/cli-runtime` | CLI 格式化、等待和版本辅助工具 |
| `plugin-sdk/gateway-runtime` | Gateway 网关客户端和渠道状态补丁辅助工具 |
| `plugin-sdk/config-runtime` | 配置加载/写入辅助工具,以及插件配置查找辅助工具 |
| `plugin-sdk/telegram-command-config` | Telegram 命令名称/描述规范化,以及重复/冲突检查,即使 bundled Telegram 契约接口不可用也可使用 |
| `plugin-sdk/config-runtime` | 配置加载 / 写入辅助工具,以及插件配置查找辅助工具 |
| `plugin-sdk/telegram-command-config` | Telegram 命令名称 / 描述规范化以及重复 / 冲突检查,即使 bundled Telegram contract surface 不可用时也可使用 |
| `plugin-sdk/text-autolink-runtime` | 不包含宽泛 text-runtime barrel 的文件引用自动链接检测 |
| `plugin-sdk/approval-runtime` | exec/插件审批辅助工具、审批能力构建器、认证/profile 辅助工具、原生路由/运行时辅助工具 |
| `plugin-sdk/reply-runtime` | 共享入站/回复运行时辅助工具、分块、分发、心跳、回复规划器 |
| `plugin-sdk/reply-dispatch-runtime` | 精细的回复分发/完成辅助工具 |
| `plugin-sdk/reply-history` | 共享时间窗口回复历史辅助工具,例如 `buildHistoryContext`、`recordPendingHistoryEntry` 和 `clearHistoryEntriesIfEnabled` |
| `plugin-sdk/approval-runtime` | exec / 插件审批辅助工具、审批能力构建器、认证 / profile 辅助工具、原生路由 / 运行时辅助工具 |
| `plugin-sdk/reply-runtime` | 共享入站 / 回复运行时辅助工具、分块、分发、心跳、回复规划器 |
| `plugin-sdk/reply-dispatch-runtime` | 精简的回复分发 / 收尾辅助工具 |
| `plugin-sdk/reply-history` | 共享短窗口回复历史辅助工具,例如 `buildHistoryContext`、`recordPendingHistoryEntry` 和 `clearHistoryEntriesIfEnabled` |
| `plugin-sdk/reply-reference` | `createReplyReferencePlanner` |
| `plugin-sdk/reply-chunking` | 精细的文本/Markdown 分块辅助工具 |
| `plugin-sdk/reply-chunking` | 精简的文本 / Markdown 分块辅助工具 |
| `plugin-sdk/session-store-runtime` | 会话存储路径 + updated-at 辅助工具 |
| `plugin-sdk/state-paths` | 状态/OAuth 目录路径辅助工具 |
| `plugin-sdk/routing` | 路由/会话键/账户绑定辅助工具,例如 `resolveAgentRoute`、`buildAgentSessionKey` 和 `resolveDefaultAgentBoundAccountId` |
| `plugin-sdk/status-helpers` | 共享渠道/账户状态摘要辅助工具、运行时状态默认值和问题元数据辅助工具 |
| `plugin-sdk/target-resolver-runtime` | 共享目标解析器辅助工具 |
| `plugin-sdk/string-normalization-runtime` | slug/字符串规范化辅助工具 |
| `plugin-sdk/request-url` | 从 fetch/request 类输入中提取字符串 URL |
| `plugin-sdk/run-command` | 带超时的命令运行器,返回规范化的 stdout/stderr 结果 |
| `plugin-sdk/param-readers` | 通用工具/CLI 参数读取器 |
| `plugin-sdk/state-paths` | 状态 / OAuth 目录路径辅助工具 |
| `plugin-sdk/routing` | 路由 / session-key / 账户绑定辅助工具,例如 `resolveAgentRoute`、`buildAgentSessionKey` 和 `resolveDefaultAgentBoundAccountId` |
| `plugin-sdk/status-helpers` | 共享渠道 / 账户状态摘要辅助工具、运行时状态默认值和问题元数据辅助工具 |
| `plugin-sdk/target-resolver-runtime` | 共享目标解析器辅助工具 |
| `plugin-sdk/string-normalization-runtime` | slug / 字符串规范化辅助工具 |
| `plugin-sdk/request-url` | 从 fetch / request 类输入中提取字符串 URL |
| `plugin-sdk/run-command` | 带超时的命令运行器,返回规范化的 stdout / stderr 结果 |
| `plugin-sdk/param-readers` | 常用工具 / CLI 参数读取器 |
| `plugin-sdk/tool-payload` | 从工具结果对象中提取规范化负载 |
| `plugin-sdk/tool-send` | 从工具参数中提取规范发送目标字段 |
| `plugin-sdk/temp-path` | 共享临时下载路径辅助工具 |
| `plugin-sdk/temp-path` | 共享临时下载路径辅助工具 |
| `plugin-sdk/logging-core` | 子系统日志器和脱敏辅助工具 |
| `plugin-sdk/markdown-table-runtime` | Markdown 表格模式辅助工具 |
| `plugin-sdk/json-store` | 小型 JSON 状态读写辅助工具 |
| `plugin-sdk/file-lock` | 可重入文件锁辅助工具 |
| `plugin-sdk/persistent-dedupe` | 磁盘支持的去重缓存辅助工具 |
| `plugin-sdk/acp-runtime` | ACP 运行时/会话和回复分发辅助工具 |
| `plugin-sdk/acp-runtime` | ACP 运行时 / 会话和回复分发辅助工具 |
| `plugin-sdk/acp-binding-resolve-runtime` | 不引入生命周期启动导入的只读 ACP 绑定解析 |
| `plugin-sdk/agent-config-primitives` | 精细的智能体运行时 config-schema 基元 |
| `plugin-sdk/agent-config-primitives` | 精简的智能体运行时配置 schema 基元 |
| `plugin-sdk/boolean-param` | 宽松布尔参数读取器 |
| `plugin-sdk/dangerous-name-runtime` | 危险名称匹配解析辅助工具 |
| `plugin-sdk/device-bootstrap` | 设备引导和配对令牌辅助工具 |
| `plugin-sdk/extension-shared` | 共享的被动渠道、状态和环境代理辅助基元 |
| `plugin-sdk/models-provider-runtime` | `/models` 命令/提供商回复辅助工具 |
| `plugin-sdk/extension-shared` | 共享被动渠道、状态和环境代理辅助原语 |
| `plugin-sdk/models-provider-runtime` | `/models` 命令 / 提供商回复辅助工具 |
| `plugin-sdk/skill-commands-runtime` | Skill 命令列表辅助工具 |
| `plugin-sdk/native-command-registry` | 原生命令注册表构建/序列化辅助工具 |
| `plugin-sdk/agent-harness` | 面向受信任插件的实验性低层智能体 harness 接口harness 类型、活动运行 steer/abort 辅助工具、OpenClaw 工具桥接辅助工具以及 attempt 结果实用工具 |
| `plugin-sdk/provider-zai-endpoint` | Z.AI 端点检测辅助工具 |
| `plugin-sdk/infra-runtime` | 系统事件/心跳辅助工具 |
| `plugin-sdk/native-command-registry` | 原生命令注册表 / 构建 / 序列化辅助工具 |
| `plugin-sdk/agent-harness` | 面向受信任插件的实验性低层智能体 harness 接口harness 类型、活动运行 steer / abort 辅助工具、OpenClaw 工具桥接辅助工具以及尝试结果工具 |
| `plugin-sdk/provider-zai-endpoint` | Z.A.I endpoint 检测辅助工具 |
| `plugin-sdk/infra-runtime` | 系统事件 / 心跳辅助工具 |
| `plugin-sdk/collection-runtime` | 小型有界缓存辅助工具 |
| `plugin-sdk/diagnostic-runtime` | 诊断标志和事件辅助工具 |
| `plugin-sdk/error-runtime` | 错误图、格式化、共享错误分类辅助工具、`isApprovalNotFoundError` |
| `plugin-sdk/fetch-runtime` | 包装后的 fetch、代理和 pinned 查找辅助工具 |
| `plugin-sdk/runtime-fetch` | 具备 dispatcher 感知能力的运行时 fetch不引入 proxy/guarded-fetch 导入 |
| `plugin-sdk/response-limit-runtime` | 不包含宽泛媒体运行时接口的有界响应体读取器 |
| `plugin-sdk/fetch-runtime` | 包装后的 fetch、代理和 pinned lookup 辅助工具 |
| `plugin-sdk/runtime-fetch` | 不引入 proxy / guarded-fetch 的 dispatcher-aware 运行时 fetch |
| `plugin-sdk/response-limit-runtime` | 不包含宽泛 media 运行时接口的有界响应体读取器 |
| `plugin-sdk/session-binding-runtime` | 当前会话绑定状态,不包含已配置绑定路由或配对存储 |
| `plugin-sdk/session-store-runtime` | 不包含宽泛配置写入/维护导入的会话存储读取辅助工具 |
| `plugin-sdk/context-visibility-runtime` | 上下文可见性解析和补充上下文过滤,不引入宽泛配置/安全导入 |
| `plugin-sdk/string-coerce-runtime` | 不引入 Markdown/日志导入的精细原始记录/字符串强制转换与规范化辅助工具 |
| `plugin-sdk/session-store-runtime` | 不包含宽泛配置写入 / 维护导入的会话存储读取辅助工具 |
| `plugin-sdk/context-visibility-runtime` | 上下文可见性解析和补充上下文过滤,不包含宽泛配置 / 安全导入 |
| `plugin-sdk/string-coerce-runtime` | 不包含 markdown / 日志导入的精简原始记录 / 字符串强制转换与规范化辅助工具 |
| `plugin-sdk/host-runtime` | 主机名和 SCP 主机规范化辅助工具 |
| `plugin-sdk/retry-runtime` | 重试配置和重试行器辅助工具 |
| `plugin-sdk/agent-runtime` | 智能体目录/身份/工作区辅助工具 |
| `plugin-sdk/directory-runtime` | 基于配置的目录查询/去重 |
| `plugin-sdk/retry-runtime` | 重试配置和重试行器辅助工具 |
| `plugin-sdk/agent-runtime` | 智能体目录 / 身份 / 工作区辅助工具 |
| `plugin-sdk/directory-runtime` | 基于配置的目录查询 / 去重 |
| `plugin-sdk/keyed-async-queue` | `KeyedAsyncQueue` |
</Accordion>
<Accordion title="能力与测试子路径">
| 子路径 | 关键导出 |
| --- | --- |
| `plugin-sdk/media-runtime` | 共享媒体获取/转换/存储辅助工具,以及媒体负载构建器 |
| `plugin-sdk/media-generation-runtime` | 共享媒体生成故障切换辅助工具、候选项选择和缺失模型提示消息 |
| `plugin-sdk/media-understanding` | 媒体理解提供商类型,以及面向提供商的图像/音频辅助导出 |
| `plugin-sdk/text-runtime` | 共享的文本/Markdown/日志辅助工具例如面向助手可见文本剥离、Markdown 渲染/分块/表格辅助工具、脱敏辅助工具、directive-tag 辅助工具和安全文本实用工具 |
| `plugin-sdk/media-runtime` | 共享媒体获取 / 转换 / 存储辅助工具,以及媒体负载构建器 |
| `plugin-sdk/media-generation-runtime` | 共享媒体生成故障切换辅助工具、候选项选择和缺失模型提示 |
| `plugin-sdk/media-understanding` | 媒体理解提供商类型,以及面向提供商的图像 / 音频辅助导出 |
| `plugin-sdk/text-runtime` | 共享文本 / Markdown / 日志辅助工具,例如 assistant 可见文本剥离、Markdown 渲染 / 分块 / 表格辅助工具、脱敏辅助工具、directive-tag 辅助工具和安全文本工具 |
| `plugin-sdk/text-chunking` | 出站文本分块辅助工具 |
| `plugin-sdk/speech` | 语音提供商类型,以及面向提供商的 directive、注册表和校验辅助工具 |
| `plugin-sdk/speech-core` | 共享语音提供商类型、注册表、directive 和规范化辅助工具 |
| `plugin-sdk/realtime-transcription` | 实时转提供商类型、注册表辅助工具和共享 WebSocket 会话辅助工具 |
| `plugin-sdk/speech-core` | 共享语音提供商类型、注册表、directive 和规范化辅助工具 |
| `plugin-sdk/realtime-transcription` | 实时转提供商类型、注册表辅助工具和共享 WebSocket 会话辅助工具 |
| `plugin-sdk/realtime-voice` | 实时语音提供商类型和注册表辅助工具 |
| `plugin-sdk/image-generation` | 图像生成提供商类型 |
| `plugin-sdk/image-generation-core` | 共享图像生成类型、故障切换、认证和注册表辅助工具 |
| `plugin-sdk/music-generation` | 音乐生成提供商/请求/结果类型 |
| `plugin-sdk/music-generation-core` | 共享音乐生成类型、故障切换辅助工具、提供商查找和 model-ref 解析 |
| `plugin-sdk/video-generation` | 视频生成提供商/请求/结果类型 |
| `plugin-sdk/video-generation-core` | 共享视频生成类型、故障切换辅助工具、提供商查找和 model-ref 解析 |
| `plugin-sdk/webhook-targets` | webhook 目标注册表和路由安装辅助工具 |
| `plugin-sdk/webhook-path` | webhook 路径规范化辅助工具 |
| `plugin-sdk/web-media` | 共享远程/本地媒体加载辅助工具 |
| `plugin-sdk/zod` | 为 plugin SDK 使用重新导出的 `zod` |
| `plugin-sdk/image-generation-core` | 共享图像生成类型、故障切换、认证和注册表辅助工具 |
| `plugin-sdk/music-generation` | 音乐生成提供商 / 请求 / 结果类型 |
| `plugin-sdk/music-generation-core` | 共享音乐生成类型、故障切换辅助工具、提供商查找和 model-ref 解析 |
| `plugin-sdk/video-generation` | 视频生成提供商 / 请求 / 结果类型 |
| `plugin-sdk/video-generation-core` | 共享视频生成类型、故障切换辅助工具、提供商查找和 model-ref 解析 |
| `plugin-sdk/webhook-targets` | Webhook 目标注册表和路由安装辅助工具 |
| `plugin-sdk/webhook-path` | Webhook 路径规范化辅助工具 |
| `plugin-sdk/web-media` | 共享远程 / 本地媒体加载辅助工具 |
| `plugin-sdk/zod` | 为 plugin SDK 使用重新导出的 `zod` |
| `plugin-sdk/testing` | `installCommonResolveTargetErrorCases`、`shouldAckReaction` |
</Accordion>
<Accordion title="Memory 子路径">
| 子路径 | 关键导出 |
| --- | --- |
| `plugin-sdk/memory-core` | bunded memory-core 辅助接口,用于 manager/config/file/CLI 辅助工具 |
| `plugin-sdk/memory-core-engine-runtime` | Memory 索引/搜索运行时门面 |
| `plugin-sdk/memory-core` | bundled memory-core 辅助接口,用于 manager / config / file / CLI 辅助工具 |
| `plugin-sdk/memory-core-engine-runtime` | Memory 索引 / 搜索运行时门面 |
| `plugin-sdk/memory-core-host-engine-foundation` | Memory host foundation engine 导出 |
| `plugin-sdk/memory-core-host-engine-embeddings` | Memory host embedding 契约、注册表访问、本地提供商,以及通用批处理/远程辅助工具 |
| `plugin-sdk/memory-core-host-engine-embeddings` | Memory host embedding 契约、注册表访问、本地 provider以及通用批处理 / 远程辅助工具 |
| `plugin-sdk/memory-core-host-engine-qmd` | Memory host QMD engine 导出 |
| `plugin-sdk/memory-core-host-engine-storage` | Memory host storage engine 导出 |
| `plugin-sdk/memory-core-host-multimodal` | Memory host 多模态辅助工具 |
@ -251,25 +252,25 @@ x-i18n:
| `plugin-sdk/memory-core-host-status` | Memory host 状态辅助工具 |
| `plugin-sdk/memory-core-host-runtime-cli` | Memory host CLI 运行时辅助工具 |
| `plugin-sdk/memory-core-host-runtime-core` | Memory host 核心运行时辅助工具 |
| `plugin-sdk/memory-core-host-runtime-files` | Memory host 文件/运行时辅助工具 |
| `plugin-sdk/memory-host-core` | 面向不同供应商的 memory host 核心运行时辅助工具别名 |
| `plugin-sdk/memory-host-events` | 面向不同供应商的 memory host 事件日志辅助工具别名 |
| `plugin-sdk/memory-host-files` | 面向不同供应商的 memory host 文件/运行时辅助工具别名 |
| `plugin-sdk/memory-host-markdown` | 面向 memory 邻插件的共享托管 Markdown 辅助工具 |
| `plugin-sdk/memory-host-search` | 用于访问 search-manager 的 active memory 运行时门面 |
| `plugin-sdk/memory-host-status` | 面向不同供应商的 memory host 状态辅助工具别名 |
| `plugin-sdk/memory-core-host-runtime-files` | Memory host 文件 / 运行时辅助工具 |
| `plugin-sdk/memory-host-core` | 面向厂商中立的别名,用于 memory host 核心运行时辅助工具 |
| `plugin-sdk/memory-host-events` | 面向厂商中立的别名,用于 memory host 事件日志辅助工具 |
| `plugin-sdk/memory-host-files` | 面向厂商中立的别名,用于 memory host 文件 / 运行时辅助工具 |
| `plugin-sdk/memory-host-markdown` | 面向 memory 邻插件的共享托管 Markdown 辅助工具 |
| `plugin-sdk/memory-host-search` | 用于 search-manager 访问的活动 Memory 运行时门面 |
| `plugin-sdk/memory-host-status` | 面向厂商中立的别名,用于 memory host 状态辅助工具 |
| `plugin-sdk/memory-lancedb` | bundled memory-lancedb 辅助接口 |
</Accordion>
<Accordion title="保留的 bundled-helper 子路径">
| 家族 | 当前子路径 | 预期用途 |
| 分类 | 当前子路径 | 预期用途 |
| --- | --- | --- |
| Browser | `plugin-sdk/browser-cdp`, `plugin-sdk/browser-config-runtime`, `plugin-sdk/browser-config-support`, `plugin-sdk/browser-control-auth`, `plugin-sdk/browser-node-runtime`, `plugin-sdk/browser-profiles`, `plugin-sdk/browser-security-runtime`, `plugin-sdk/browser-setup-tools`, `plugin-sdk/browser-support` | bundled browser 插件支持辅助工具(`browser-support` 仍兼容性 barrel |
| Matrix | `plugin-sdk/matrix`, `plugin-sdk/matrix-helper`, `plugin-sdk/matrix-runtime-heavy`, `plugin-sdk/matrix-runtime-shared`, `plugin-sdk/matrix-runtime-surface`, `plugin-sdk/matrix-surface`, `plugin-sdk/matrix-thread-bindings` | bundled Matrix 辅助/运行时接口 |
| Line | `plugin-sdk/line`, `plugin-sdk/line-core`, `plugin-sdk/line-runtime`, `plugin-sdk/line-surface` | bundled LINE 辅助/运行时接口 |
| Browser | `plugin-sdk/browser-cdp`, `plugin-sdk/browser-config-runtime`, `plugin-sdk/browser-config-support`, `plugin-sdk/browser-control-auth`, `plugin-sdk/browser-node-runtime`, `plugin-sdk/browser-profiles`, `plugin-sdk/browser-security-runtime`, `plugin-sdk/browser-setup-tools`, `plugin-sdk/browser-support` | bundled browser 插件支持辅助工具(`browser-support` 仍兼容性 barrel |
| Matrix | `plugin-sdk/matrix`, `plugin-sdk/matrix-helper`, `plugin-sdk/matrix-runtime-heavy`, `plugin-sdk/matrix-runtime-shared`, `plugin-sdk/matrix-runtime-surface`, `plugin-sdk/matrix-surface`, `plugin-sdk/matrix-thread-bindings` | bundled Matrix 辅助 / 运行时接口 |
| Line | `plugin-sdk/line`, `plugin-sdk/line-core`, `plugin-sdk/line-runtime`, `plugin-sdk/line-surface` | bundled LINE 辅助 / 运行时接口 |
| IRC | `plugin-sdk/irc`, `plugin-sdk/irc-surface` | bundled IRC 辅助接口 |
| 渠道特定辅助工具 | `plugin-sdk/googlechat`, `plugin-sdk/zalouser`, `plugin-sdk/bluebubbles`, `plugin-sdk/bluebubbles-policy`, `plugin-sdk/mattermost`, `plugin-sdk/mattermost-policy`, `plugin-sdk/feishu-conversation`, `plugin-sdk/msteams`, `plugin-sdk/nextcloud-talk`, `plugin-sdk/nostr`, `plugin-sdk/tlon`, `plugin-sdk/twitch` | bundled 渠道兼容性/辅助接口 |
| 认证/插件特定辅助工具 | `plugin-sdk/github-copilot-login`, `plugin-sdk/github-copilot-token`, `plugin-sdk/diagnostics-otel`, `plugin-sdk/diffs`, `plugin-sdk/llm-task`, `plugin-sdk/thread-ownership`, `plugin-sdk/voice-call` | bundled 功能/插件辅助接口;`plugin-sdk/github-copilot-token` 当前导出 `DEFAULT_COPILOT_API_BASE_URL`、`deriveCopilotApiBaseUrlFromToken` 和 `resolveCopilotApiToken` |
| 渠道专用辅助工具 | `plugin-sdk/googlechat`, `plugin-sdk/zalouser`, `plugin-sdk/bluebubbles`, `plugin-sdk/bluebubbles-policy`, `plugin-sdk/mattermost`, `plugin-sdk/mattermost-policy`, `plugin-sdk/feishu-conversation`, `plugin-sdk/msteams`, `plugin-sdk/nextcloud-talk`, `plugin-sdk/nostr`, `plugin-sdk/tlon`, `plugin-sdk/twitch` | bundled 渠道兼容性 / 辅助接口 |
| 认证 / 插件专用辅助工具 | `plugin-sdk/github-copilot-login`, `plugin-sdk/github-copilot-token`, `plugin-sdk/diagnostics-otel`, `plugin-sdk/diffs`, `plugin-sdk/llm-task`, `plugin-sdk/thread-ownership`, `plugin-sdk/voice-call` | bundled 功能 / 插件辅助接口;`plugin-sdk/github-copilot-token` 当前导出 `DEFAULT_COPILOT_API_BASE_URL`、`deriveCopilotApiBaseUrlFromToken` 和 `resolveCopilotApiToken` |
</Accordion>
</AccordionGroup>

View File

@ -1,22 +0,0 @@
---
read_when:
- 你访问了较旧的 Model Studio 链接
- 你想查看规范的 Qwen 提供商页面
summary: 重定向到 /providers/qwen
title: Qwen / Model Studio
x-i18n:
generated_at: "2026-04-24T03:43:15Z"
model: gpt-5.4
provider: openai
source_hash: 04fcb811b399931e8a18974c0f13bf882551185e16a7c3563a86214d175b07fb
source_path: providers/qwen_modelstudio.md
workflow: 15
---
此页面已移动到 [Qwen](/zh-CN/providers/qwen)。有关规范的提供商设置、端点详情、兼容性别名和 Wan 视频生成说明,请参阅 [Qwen](/zh-CN/providers/qwen)。
## 相关
- [Alibaba Model Studio](/zh-CN/providers/alibaba)
- [Qwen](/zh-CN/providers/qwen)
- [模型选择](/zh-CN/concepts/model-providers)

View File

@ -2,13 +2,13 @@
read_when:
- 重构 QA 场景定义或 qa-lab harness 代码
- 在 Markdown 场景与 TypeScript harness 逻辑之间迁移 QA 行为
summary: QA 重构计划:scenario catalog 与 harness consolidation
summary: QA 重构计划:场景目录与 harness 整合
title: QA 重构
x-i18n:
generated_at: "2026-04-24T04:06:27Z"
generated_at: "2026-04-24T04:20:56Z"
model: gpt-5.4
provider: openai
source_hash: 9c825b17b9af9ccb7902832327897510ac789b5bec0188f7903430324187bca0
source_hash: 0d774d7b5e0fffd5c2504d9a4d6063198d77b866263ea8448474dce6246012d4
source_path: refactor/qa.md
workflow: 15
---
@ -17,54 +17,53 @@ x-i18n:
## 目标
将 OpenClaw QA 从分裂定义模型迁移到单一事实来源:
将 OpenClaw QA 从“定义分散”的模式迁移为单一事实来源:
- 场景元数据
- 发送给模型的提示
- setup 和 teardown
- 发送给模型的提示
- 设置与清理
- harness 逻辑
- 断言成功标准
- 产物报告提示
- 断言成功标准
- 产物报告提示
期望的最终状态是:一个通用 QA harness 加载功能强大的场景定义文件,而不是将大多数行为硬编码在 TypeScript 中。
期望的最终状态是:一个通用 QA harness 加载功能强大的场景定义文件,而不是在 TypeScript 中硬编码大多数行为
## 当前状态
当前的主要事实来源现在位于 `qa/scenarios/index.md`,以及
`qa/scenarios/<theme>/*.md` 下每个场景对应的单独文件中。
主要事实来源现在位于 `qa/scenarios/index.md`,以及每个场景对应的 `qa/scenarios/<theme>/*.md` 文件中。
已实现:
- `qa/scenarios/index.md`
- 规范的 QA pack 元数据
- operator 身份
- kickoff 任务
- 规范的 QA 元数据
- 操作员身份
- 启动任务
- `qa/scenarios/<theme>/*.md`
- 每个场景一个 markdown 文件
- 每个场景一个 Markdown 文件
- 场景元数据
- handler 绑定
- 场景特定执行配置
- `extensions/qa-lab/src/scenario-catalog.ts`
- markdown pack 解析器 + zod 验证
- Markdown 包解析器 + zod 校验
- `extensions/qa-lab/src/qa-agent-bootstrap.ts`
- 从 markdown pack 渲染 plan
- 基于 Markdown 包渲染计划
- `extensions/qa-lab/src/qa-agent-workspace.ts`
- 生成兼容性文件以及 `QA_SCENARIOS.md`
- `extensions/qa-lab/src/suite.ts`
- 通过 markdown 定义的 handler 绑定选择可执行场景
- QA 总线协议 + UI
- 用于图/视频/音频/文件渲染的通用内联附件
- 通过 Markdown 定义的 handler 绑定选择可执行场景
- QA bus 协议 + UI
- 用于图/视频/音频/文件渲染的通用内联附件
剩余的分裂表面:
仍然分散的表面:
- `extensions/qa-lab/src/suite.ts`
- 仍然拥有大部分可执行自定义 handler 逻辑
- 仍然拥有大多数可执行的自定义 handler 逻辑
- `extensions/qa-lab/src/report.ts`
- 仍然从运行时输出推导报告结构
- 仍然从运行时输出推导报告结构
因此,事实来源分裂问题已经修复,但执行仍然主要依赖 handler而不是完全声明式。
因此,事实来源分裂问题已经修复,但执行仍然主要依赖 handler而不是完全声明式。
## 实的场景表面是什么样
## 实的场景表面是什么样
阅读当前 suite 可以看出几类不同的场景。
@ -72,73 +71,72 @@ x-i18n:
- 渠道基线
- 私信基线
- 线程后续跟进
- 线程跟进
- 模型切换
- 审批后续执行
- reaction/edit/delete
- 反应/编辑/删除
### 配置运行时变更
### 配置运行时变更
- config patch skill disable
- config apply restart wake-up
- config restart capability flip
- runtime inventory drift check
- 配置补丁禁用 skill
- 配置应用后重启唤醒
- 配置重启能力切换
- 运行时清单漂移检查
### 文件系统仓库断言
### 文件系统与代码仓库断言
- source/docs discovery report
- build Lobster Invaders
- generated image artifact lookup
- source/docs 发现报告
- 构建 Lobster Invaders
- 生成图片产物查找
### memory 编排
### Memory 编排
- memory recall
- 渠道上下文中的 memory 工具
- memory failure fallback
- session memory ranking
- 线程 memory 隔离
- memory dreaming sweep
- Memory 召回
- 渠道上下文中的 Memory 工具
- Memory 失败回退
- 会话 Memory 排序
- 线程 Memory 隔离
- Memory Dreaming sweep
### 工具插件集成
### 工具插件集成
- MCP plugin-tools call
- skill visibility
- skill hot install
- native image generation
- image roundtrip
- 从附件理解图像
- MCP plugin-tools 调用
- skill 可见性
- skill 热安装
- 原生图片生成
- 图片往返
- 基于附件的图片理解
### 多轮与多参与者
- subagent handoff
- subagent fanout synthesis
- restart recovery style flows
- subagent 交接
- subagent 扇出综合
- 重启恢复类流程
这些分类之所以重要,是因为它们驱动 DSL 需求。单纯的提示 + 预期文本列表是不够的。
这些分类很重要,因为它们决定 DSL 的需求。单纯的“提示词 + 期望文本”平铺列表是不够的。
## 方向
### 单一事实来源
使用 `qa/scenarios/index.md``qa/scenarios/<theme>/*.md` 作为
编写时的事实来源。
使用 `qa/scenarios/index.md``qa/scenarios/<theme>/*.md` 作为编写时的事实来源。
该 pack 应保持:
这个包应保持:
- 在 code review 中人类可
- 机器解析
- 在代码评审中易于阅
- 可被机器解析
- 足够丰富,能够驱动:
- suite 执行
- QA workspace bootstrap
- QA 工作区 bootstrap
- QA Lab UI 元数据
- docs/discovery prompts
- docs/discovery 提示词
- 报告生成
### 首选编写格式
使用 markdown 作为顶层格式,其中包含结构化 YAML。
使用 Markdown 作为顶层格式,并在其中嵌入结构化 YAML。
推荐结构
推荐形态
- YAML frontmatter
- id
@ -159,15 +157,15 @@ x-i18n:
- assertions
- cleanup
这样可以得
这样可以得:
- 比庞大的 JSON 更适合 PR 阅读
- 比大型 JSON 更好的 PR 可读性
- 比纯 YAML 更丰富的上下文
- 严格解析和 zod 验证
- 严格解析与 zod 校验
原始 JSON 只应作为中间生成形式被接受。
原始 JSON 仅可作为中间生成格式接受。
## 提议的场景文件结构
## 建议的场景文件形态
示例:
@ -240,11 +238,11 @@ Verify generated media is reattached on the follow-up turn.
```
````
## DSL 必须覆盖的运行器能力
## DSL 必须覆盖的 runner 能力
基于当前 suite通用运行器需要的不仅仅是提示执行。
根据当前 suite通用 runner 需要的不只是提示词执行。
### 环境和 setup 操
### 环境与设置动
- `bus.reset`
- `gateway.waitHealthy`
@ -253,14 +251,14 @@ Verify generated media is reattached on the follow-up turn.
- `thread.create`
- `workspace.writeSkill`
### 智能体回合操
### 智能体轮次动
- `agent.send`
- `agent.wait`
- `bus.injectInbound`
- `bus.injectOutbound`
### 配置和运行时操
### 配置与运行时动
- `config.get`
- `config.patch`
@ -269,7 +267,7 @@ Verify generated media is reattached on the follow-up turn.
- `tools.effective`
- `skills.status`
### 文件和产物操
### 文件与产物动
- `file.write`
- `file.read`
@ -278,7 +276,7 @@ Verify generated media is reattached on the follow-up turn.
- `artifact.captureGeneratedImage`
- `artifact.capturePath`
### memory 和 cron 操
### Memory 与 cron 动
- `memory.indexForce`
- `memory.searchCli`
@ -288,7 +286,7 @@ Verify generated media is reattached on the follow-up turn.
- `cron.waitCompletion`
- `sessionTranscript.write`
### MCP
### MCP
- `mcp.callTool`
@ -308,15 +306,15 @@ Verify generated media is reattached on the follow-up turn.
- `cron.managedPresent`
- `artifact.exists`
## 变量产物引用
## 变量产物引用
DSL 必须支持保存输出并在后续引用。
来自当前 suite 的示例:
当前 suite 的示例:
- 创建线程,然后复用 `threadId`
- 创建会话,然后复用 `sessionKey`
- 生成图像,然后在下一轮附加该文件
- 创建一个线程,然后复用 `threadId`
- 创建一个会话,然后复用 `sessionKey`
- 生成一张图片,然后在下一轮中附加该文件
- 生成一个唤醒标记字符串,然后断言它稍后出现
所需能力:
@ -324,63 +322,63 @@ DSL 必须支持保存输出并在后续引用。
- `saveAs`
- `${vars.name}`
- `${artifacts.name}`
- 路径、会话键、线程 id、标记、工具输出的类型化引用
- 针对路径、会话键、线程 id、标记、工具输出的类型化引用
如果没有变量支持harness 逻辑就会继续泄漏回 TypeScript。
如果没有变量支持harness 逻辑就会继续从场景泄漏回 TypeScript。
## 哪些内容应保留为逃生舱
## 哪些部分应保留为逃生舱
在第一阶段,实现完全纯粹的声明式运行器并不现实。
在第 1 阶段,实现一个完全纯声明式的 runner 并不现实。
有些场景天然就需要大量编排:
- memory dreaming sweep
- config apply restart wake-up
- config restart capability flip
- 基于时间戳/路径的 generated image artifact 解析
- discovery-report evaluation
- Memory Dreaming sweep
- 配置应用后重启唤醒
- 配置重启能力切换
- 基于时间戳/路径的生成图片产物解析
- discovery-report 评估
目前这些场景应改为使用显式自定义 handler。
目前这些场景应继续使用显式自定义 handler。
推荐规则:
- 85-90% 声明式
- 对于剩余困难部分使用显式 `customHandler` 步骤
- 仅允许具名且有文档说明的 custom handlers
- 85-90% 声明式
- 对于剩余较难的部分,使用显式 `customHandler` 步骤
- 仅允许具名且有文档的自定义 handler
- 场景文件中不允许匿名内联代码
这样既能保持通用引擎整洁,能继续推进。
这样既能保持通用引擎整洁,能继续推进。
## 架构变更
### 当前
场景 markdown 现在已经是以下内容的事实来源:
场景 Markdown 已经是以下内容的事实来源:
- suite 执行
- workspace bootstrap 文件
- 工作区 bootstrap 文件
- QA Lab UI 场景目录
- 报告元数据
- discovery prompts
- discovery 提示词
生成的兼容性内容:
- 已植入的 workspace 仍包含 `QA_KICKOFF_TASK.md`
- 已植入的 workspace 仍包含 `QA_SCENARIO_PLAN.md`
- 已植入的 workspace 现在也包含 `QA_SCENARIOS.md`
- 种子工作区仍然包含 `QA_KICKOFF_TASK.md`
- 种子工作区仍然包含 `QA_SCENARIO_PLAN.md`
- 种子工作区现在也包含 `QA_SCENARIOS.md`
## 重构计划
### 第 1 阶段:加载器 schema
### 第 1 阶段:加载器 schema
已完成。
- 添加 `qa/scenarios/index.md`
- 添加 `qa/scenarios/index.md`
- 将场景拆分到 `qa/scenarios/<theme>/*.md`
- 为具名 markdown YAML pack 内容添加解析器
- 使用 zod 验
- 将消费者切换到解析后的 pack
- 删除仓库级别`qa/seed-scenarios.json``qa/QA_KICKOFF_TASK.md`
- 为具名 Markdown YAML 包内容添加了解析器
- 使用 zod 进行校
- 将消费者切换到解析后的
- 移除了仓库级`qa/seed-scenarios.json``qa/QA_KICKOFF_TASK.md`
### 第 2 阶段:通用引擎
@ -394,51 +392,51 @@ DSL 必须支持保存输出并在后续引用。
交付物:
- 引擎执行简单的声明式场景
- 引擎执行简单的声明式场景
先从主要由 prompt + wait + assert 构成的场景开始:
从主要是“提示词 + 等待 + 断言”的场景开始:
- threaded follow-up
- 从附件理解图像
- skill visibility and invocation
- channel baseline
- 线程跟进
- 基于附件的图片理解
- skill 可见性与调用
- 渠道基线
交付物:
- 第一批真正由 markdown 定义并通过通用引擎运行的场景
- 第一批真正由 Markdown 定义并通过通用引擎运行的场景上线
### 第 4 阶段:迁移中等复杂度场景
- image generation roundtrip
- 渠道上下文中的 memory 工具
- session memory ranking
- subagent handoff
- subagent fanout synthesis
- 图片生成往返
- 渠道上下文中的 Memory 工具
- 会话 Memory 排序
- subagent 交接
- subagent 扇出综合
交付物:
- 变量、产物、工具断言、request-log 断言都得到验证
- 变量、产物、工具断言、request-log 断言已被验证
### 第 5 阶段:将困难场景保留在 custom handlers 中
### 第 5 阶段:保留困难场景为自定义 handler
- memory dreaming sweep
- config apply restart wake-up
- config restart capability flip
- runtime inventory drift
- Memory Dreaming sweep
- 配置应用后重启唤醒
- 配置重启能力切换
- 运行时清单漂移
交付物:
- 使用相同的编写格式,但在需要时使用显式 custom-step 块
- 相同的编写格式,但在需要时带有显式 custom-step 块
### 第 6 阶段:删除硬编码场景映射
一旦 pack 覆盖率足够高:
一旦覆盖率足够高:
- 删除 `extensions/qa-lab/src/suite.ts` 中大多数场景特定的 TypeScript 分支
- 删除 `extensions/qa-lab/src/suite.ts` 中大多数按场景分支的 TypeScript 逻辑
## Slack / 富媒体支持
## Fake Slack / 富媒体支持
当前 QA 总线是以文本为主的
当前的 QA bus 以文本优先
相关文件:
@ -448,17 +446,17 @@ DSL 必须支持保存输出并在后续引用。
- `extensions/qa-lab/src/bus-server.ts`
- `extensions/qa-lab/web/src/ui-render.ts`
如今 QA 总线支持:
目前 QA bus 支持:
- 文本
- reactions
- 反应
- 线程
尚未建模内联媒体附件
还不能对内联媒体附件建模
### 所需传输契约
添加一个通用 QA 总线附件模型:
添加一个通用的 QA bus 附件模型:
```ts
type QaBusAttachment = {
@ -477,72 +475,71 @@ type QaBusAttachment = {
};
```
然后为以下类型添加 `attachments?: QaBusAttachment[]`
然后`attachments?: QaBusAttachment[]` 添加到
- `QaBusMessage`
- `QaBusInboundMessageInput`
- `QaBusOutboundMessageInput`
### 为什么先做通用
### 为什么先做通用模型
不要构建仅 Slack 专用的媒体模型。
不要构建仅适用于 Slack 的媒体模型。
应该采用
- 一个通用 QA 传输模型
- 一个通用 QA 传输模型
- 在其上构建多个渲染器
- 当前 QA Lab 聊天
- 未来的 Slack web
- 任何其他假传输视图
- 当前 QA Lab 聊天视图
- 未来的 fake Slack web
- 任何其他 fake transport 视图
这样可以防止重复逻辑,并让媒体场景保持与传输无关。
这样可以避免重复逻辑,并让媒体场景保持传输无关。
### 需要的 UI 工作
### 需 UI 工作
更新 QA UI 以渲染:
更新 QA UI以渲染:
- 内联图预览
- 内联图预览
- 内联音频播放器
- 内联视频播放器
- 文件附件 chip
当前 UI 已经可以渲染线程和 reactions因此附件渲染应叠加到相同的消息卡片模型上。
当前 UI 已经可以渲染线程与反应,因此附件渲染应当能够叠加到同一套消息卡片模型上。
### 媒体传输启用后的场景工作
一旦附件能通过 QA 总线流转,我们就可以添加更丰富的假聊天场景:
一旦附件可以通过 QA bus 流转,就可以添加更丰富的 fake-chat 场景:
- 假 Slack 中的内联图像回复
- fake Slack 中的内联图片回复
- 音频附件理解
- 视频附件理解
- 混合附件
- 混合附件
- 保留媒体的线程回复
## 建议
下一个实现块应为
下一块实现工作应当是
1. 添加 markdown 场景加载器 + zod schema
2. 从 markdown 生成当前目录
1. 添加 Markdown 场景加载器 + zod schema
2. 从 Markdown 生成当前目录
3. 先迁移几个简单场景
4. 添加通用 QA 总线附件支持
5. 在 QA UI 中渲染内联图
4. 添加通用 QA bus 附件支持
5. 在 QA UI 中渲染内联图
6. 然后扩展到音频和视频
这是验证两个目标的最小路径:
这是能够同时证明两个目标的最小路径:
- 通用的 markdown 定义 QA
- 更丰富的假消息表面
- 通用的、由 Markdown 定义的 QA
- 更丰富的 fake messaging surfaces
## 未决问题
- 场景文件是否应允许嵌入带变量插值的 markdown 提示模板
- setup/cleanup 应该是具名 section还是仅作为有序操作列表
- 产物引用在 schema 中应强类型,还是基于字符串
- custom handlers 应集中放在一个 registry 中,还是按 surface 分 registry
- 迁移期间,生成的 JSON 兼容文件是否应继续保持已检入状态
- 场景文件是否应允许嵌入带变量插值的 Markdown 提示词模板
- 设置/清理应当是具名 section还是仅作为有序动作列表
- 产物引用在 schema 中应采用强类型,还是基于字符串
- 自定义 handler 应集中放在一个 registry 中,还是按 surface 分 registry
- 迁移期间,生成的 JSON 兼容文件是否应继续检入
## 相关内容
- [QA E2E 自动化](/zh-CN/concepts/qa-e2e-automation)
- [QA 重构](/refactor/qa-refactor)

View File

@ -1,175 +1,188 @@
---
read_when:
- 查找公开发布渠道的定义
- 查找版本命名和发布节奏
- 正在查找公开发布渠道的定义
- 正在查找版本命名和发布节奏
summary: 公开发布渠道、版本命名和发布节奏
title: 发布策略
x-i18n:
generated_at: "2026-04-24T04:06:32Z"
generated_at: "2026-04-24T04:20:41Z"
model: gpt-5.4
provider: openai
source_hash: 6360bb22e5d945c3520cf0b7141f75a52fdac193debd47e402be50c31cddefe6
source_hash: c752c399ad3df90d54a6582454febbffefff4d785309c756cc3a2ac4c3c24ceb
source_path: reference/RELEASING.md
workflow: 15
---
OpenClaw 有三个公开发布流程
OpenClaw 有三个公开发布通道
- stable带标签的发布版本默认发布到 npm `beta`,或在明确要求时发布到 npm `latest`
- stable带标签的发布版本默认发布到 npm `beta`,或在明确指定时发布到 npm `latest`
- beta预发布标签发布到 npm `beta`
- dev`main` 的滚动最新版本
- dev`main` 的持续更新头部版本
## 版本命名
- Stable 发布版本:`YYYY.M.D`
- 稳定版发布版本:`YYYY.M.D`
- Git 标签:`vYYYY.M.D`
- Stable 修正版发布版本:`YYYY.M.D-N`
- 稳定版修正版发布版本:`YYYY.M.D-N`
- Git 标签:`vYYYY.M.D-N`
- Beta 预发布版本:`YYYY.M.D-beta.N`
- beta 预发布版本:`YYYY.M.D-beta.N`
- Git 标签:`vYYYY.M.D-beta.N`
- 月和日不要补零
- `latest` 表示当前已提升的 stable npm 发布版本
- 月和日不要使用零填充
- `latest` 表示当前已提升为正式版的稳定 npm 发布版本
- `beta` 表示当前 beta 安装目标
- Stable 和 stable 修正版默认发布到 npm `beta`;发布操作员可以显式指定为 `latest`,或之后再将经过验证的 beta 构建提升过去
- 每个 stable OpenClaw 发布都会同时发布 npm 包和 macOS 应用;
beta 发布通常会先验证并发布 npm / package 路径mac 应用的构建 / 签名 / 公证通常保留给 stable除非另有明确要求
- 稳定版和稳定版修正版默认发布到 npm `beta`;发布操作人员也可以明确指定目标为 `latest`,或者稍后将经过验证的 beta 构建提升为正式版
- 每个稳定版 OpenClaw 发布都会同时交付 npm 包和 macOS 应用;
beta 发布通常会先验证并发布 npm/包路径,而 mac 应用的构建/签名/公证默认保留给稳定版,除非有明确要求
## 发布节奏
- 发布遵循 beta 优先
- 只有在最新 beta 验证完成stable 才会跟进
- 维护者通常会从当前 `main` 创建一个 `release/YYYY.M.D` 分支来切发布,
- 只有在最新 beta 完成验证后,才会发布 stable
- 维护者通常会从当前 `main` 创建 `release/YYYY.M.D` 分支来切发布,
这样发布验证和修复就不会阻塞 `main` 上的新开发
- 如果某个 beta 标签已经被推送或发布,之后又需要修复,维护者会切下一个
- 如果某个 beta 标签已经推送或发布后仍需修复,维护者会切下一个
`-beta.N` 标签,而不是删除或重建旧的 beta 标签
- 详细发布流程、审批、凭证和恢复说明仅供维护者使用
- 详细发布流程、审批、凭证和恢复说明仅供维护者使用
## 发布预检
## 发布前检查
- 在发布预检之前运行 `pnpm check:test-types`,这样测试 TypeScript 也能在更快的本地 `pnpm check` 门禁之外得到覆盖
- 在发布预检之前运行 `pnpm check:architecture`,这样更广泛的导入环和架构边界检查也能在更快的本地门禁之外保持绿色
- 在运行 `pnpm release:check` 之前先运行 `pnpm build && pnpm ui:build`,这样 pack
校验步骤所需的 `dist/*` 发布产物和控制 UI bundle 才会存在
- 在发布前检查前运行 `pnpm check:test-types`,这样测试 TypeScript 也会继续被覆盖,
不会只依赖更快的本地 `pnpm check` 检查门
- 在发布前检查前运行 `pnpm check:architecture`,这样更广泛的导入环和架构边界检查会保持通过,
不会只依赖更快的本地检查门
- 在 `pnpm release:check` 之前运行 `pnpm build && pnpm ui:build`,这样打包验证步骤所需的
`dist/*` 发布产物和 Control UI bundle 都会存在
- 每次带标签发布前都要运行 `pnpm release:check`
- 发布检查现在在单独的手动工作流中运行:
`OpenClaw Release Checks`
- `OpenClaw Release Checks` 还会在发布审批前运行 QA Lab mock parity gate以及实时
Matrix 和 Telegram QA 流程。实时流程使用
- `OpenClaw Release Checks` 还会在发布审批前运行 QA Lab mock 一致性检查门,以及实时的
Matrix 和 Telegram QA 通道。实时通道使用
`qa-live-shared` 环境Telegram 还会使用 Convex CI 凭证租约。
- 跨 OS 的安装和升级运行时验证由私有调用方工作流派发:
`openclaw/releases-private/.github/workflows/openclaw-cross-os-release-checks.yml`
会调用可复用的公开工作流
- 跨操作系统的安装和升级运行时验证由私有调用方工作流
`openclaw/releases-private/.github/workflows/openclaw-cross-os-release-checks.yml`
发起,该工作流会调用可复用的公开工作流
`.github/workflows/openclaw-cross-os-release-checks-reusable.yml`
- 这种拆分是有意为之:让真正的 npm 发布路径保持短小、
确定性且以产物为中心,而较慢的实时检查保持在它们自己的流程中,
这样就不会拖慢或阻塞发布
- 发布检查必须从 `main` 工作流引用或
`release/YYYY.M.D` 工作流引用派发,这样工作流逻辑和密钥才能保持受控
- 该工作流接受一个现有发布标签,或者当前工作流分支的完整
40 字符 commit SHA
- 在 commit-SHA 模式下,它只接受当前工作流分支的 HEAD对于较旧的发布 commit请使用发布标签
- `OpenClaw NPM Release` 的仅校验预检也接受当前工作流分支的完整 40 字符 commit SHA而不要求先推送标签
- 该 SHA 路径仅用于校验,不能被提升为真实发布
- 在 SHA 模式下,工作流只会为 package 元数据检查合成 `v<package.json version>`;真实发布仍然需要真实发布标签
- 两个工作流都会把真实发布和提升路径保留在 GitHub 托管 runner 上,而非变更性的校验路径可以使用更大的
Blacksmith Linux runner
- 这样的拆分是有意为之:让真正的 npm 发布路径保持简短、
可预测且以产物为中心,同时把更慢的实时检查放在它们自己的通道中,
以免拖慢或阻塞发布
- 发布检查必须从 `main` 工作流引用,或从
`release/YYYY.M.D` 工作流引用发起,这样工作流逻辑和密钥才能保持受控
- 该工作流接受现有的发布标签,或当前完整的
40 字符工作流分支提交 SHA
- 在提交 SHA 模式下,它只接受当前工作流分支的 HEAD较早的发布提交必须使用
发布标签
- `OpenClaw NPM Release` 的仅验证型前置检查也接受当前完整的
40 字符工作流分支提交 SHA而不要求已推送的标签
- 该 SHA 路径仅用于验证,不能提升为真实发布
- 在 SHA 模式下,工作流只会为包元数据检查临时生成
`v<package.json version>`;真实发布仍然需要真实的发布标签
- 两个工作流都会把真实发布和提升路径保留在 GitHub 托管 runner 上,
而非变更型验证路径可以使用更大的
Blacksmith Linux runners
- 该工作流会运行
`OPENCLAW_LIVE_TEST=1 OPENCLAW_LIVE_CACHE_TEST=1 pnpm test:live:cache`
,并使用 `OPENAI_API_KEY``ANTHROPIC_API_KEY` 两个工作流密钥
- npm 发布预检不再等待单独的发布检查流程
,并同时使用 `OPENAI_API_KEY``ANTHROPIC_API_KEY` 工作流密钥
- npm 发布前置检查不再等待单独的发布检查通道
- 在审批前运行
`RELEASE_TAG=vYYYY.M.D node --import tsx scripts/openclaw-npm-release-check.ts`
(或匹配的 beta / 修正版标签)
(或对应的 beta/修正版标签)
- npm 发布后,运行
`node --import tsx scripts/openclaw-npm-postpublish-verify.ts YYYY.M.D`
(或匹配的 beta / 修正版版本)以在一个全新的临时前缀中验证已发布的注册表安装路径
- 维护者发布自动化现在使用“先预检、后提升”
- 真实 npm 发布必须基于一个成功的 npm `preflight_run_id`
- 真实 npm 发布必须从与成功预检运行相同的 `main`
`release/YYYY.M.D` 分支
- stable npm 发布默认使用 `beta`
- stable npm 发布可以通过工作流输入显式指定`latest`
- 基于令牌的 npm dist-tag 变更现在位于
(或对应的 beta/修正版版本),以在全新的临时前缀中验证已发布的注册表安装路径
- 维护者发布自动化现在使用“前置检查后提升”流程
- 真实 npm 发布必须通过成功的 npm `preflight_run_id`
- 真实 npm 发布必须从与成功前置检查运行相同的 `main`
`release/YYYY.M.D` 分支发
- 稳定 npm 发布默认使用 `beta`
- 稳定 npm 发布可以通过工作流输入明确指定目标`latest`
- 基于 token 的 npm dist-tag 变更现在位于
`openclaw/releases-private/.github/workflows/openclaw-npm-dist-tags.yml`
中,以增强安全性,因为 `npm dist-tag add` 仍然需要 `NPM_TOKEN`,而公开仓库保持仅使用 OIDC 发布
- 公开的 `macOS Release` 仅用于校验
中,以提升安全性,因为 `npm dist-tag add` 仍然需要 `NPM_TOKEN`,而公开仓库保留
仅使用 OIDC 的发布方式
- 公开的 `macOS Release` 仅用于验证
- 真实的私有 mac 发布必须通过成功的私有 mac
`preflight_run_id``validate_run_id`
- 真实发布路径会提升已准备好的产物,而不是再次重建它们
- 对于像 `YYYY.M.D-N` 这样的 stable 修正版发布,发布后校验器
还会检查同一个临时前缀中从 `YYYY.M.D` 升级到 `YYYY.M.D-N` 的路径,
以防修正版发布悄悄让旧的全局安装仍停留在基础 stable 载荷上
- npm 发布预检会在 tarball 不包含 `dist/control-ui/index.html`
和非空的 `dist/control-ui/assets/` 载荷时以关闭失败处理,
以防我们再次发布空的浏览器仪表板
- 发布后校验还会检查已发布的注册表安装中,在根级 `dist/*`
布局下是否包含非空的内置插件运行时依赖。若发布时缺失或为空的内置插件
依赖载荷,发布后校验器将失败,并且该版本不能被提升到 `latest`
- `pnpm test:install:smoke` 还会对候选更新 tarball 的 npm pack `unpackedSize` 预算进行强制检查,因此安装器 e2e 可以在发布路径之前捕获意外的 pack 体积膨胀
- 如果发布工作涉及 CI 规划、extension 时序清单或
extension 测试矩阵,请在审批前重新生成并审阅由规划器维护的
`.github/workflows/ci.yml``checks-node-extensions` 工作流矩阵输出,
这样发布说明就不会描述一个过时的 CI 布局
- Stable macOS 发布准备情况还包括更新器表面:
- GitHub 发布最终必须包含打包好的 `.zip`、`.dmg` 和 `.dSYM.zip`
- 发布后,`main` 上的 `appcast.xml` 必须指向新的 stable zip
- 打包应用必须保持非调试 bundle id、非空的 Sparkle feed
URL以及不低于该发布版本规范 Sparkle 构建下限的 `CFBundleVersion`
- 真实发布路径会提升已准备好的产物,而不是再次重新构建它们
- 对于像 `YYYY.M.D-N` 这样的稳定修正版发布,发布后验证器还会检查
`YYYY.M.D``YYYY.M.D-N` 的同一临时前缀升级路径,
这样修正版发布就不能在无提示的情况下让旧的全局安装仍停留在基础稳定版内容上
- npm 发布前置检查会默认失败关闭,除非 tarball 同时包含
`dist/control-ui/index.html` 和非空的 `dist/control-ui/assets/` 内容,
以避免再次发布出空的浏览器仪表盘
- 发布后验证还会检查已发布的注册表安装是否在根级 `dist/*`
布局下包含非空的内置插件运行时依赖。若某次发布缺少这些依赖内容
或内容为空,则发布后验证器会失败,并且该版本不能被提升到
`latest`
- `pnpm test:install:smoke` 还会对候选更新 tarball 的 npm pack `unpackedSize` 预算进行强制检查,
这样安装器 e2e 可以在发布路径之前捕捉意外的打包膨胀
- 如果发布工作涉及 CI 规划、扩展时序清单或扩展测试矩阵,
请在审批前重新生成并审查来自 `.github/workflows/ci.yml`
规划器负责的 `checks-node-extensions` 工作流矩阵输出,
以免发布说明描述的是过时的 CI 布局
- 稳定版 macOS 发布就绪性还包括更新器相关表面:
- GitHub release 最终必须包含已打包的 `.zip`、`.dmg` 和 `.dSYM.zip`
- 发布后,`main` 上的 `appcast.xml` 必须指向新的稳定版 zip
- 已打包应用必须保持非调试 bundle id、非空的 Sparkle feed
URL以及不低于该发布版本规范 Sparkle 构建底线的 `CFBundleVersion`
## NPM 工作流输入
`OpenClaw NPM Release` 接受以下由操作员控制的输入:
`OpenClaw NPM Release` 接受以下由操作员控制的输入:
- `tag`:必填发布标签,例如 `v2026.4.2`、`v2026.4.2-1`
- `tag`:必填发布标签,例如 `v2026.4.2`、`v2026.4.2-1`
`v2026.4.2-beta.1`;当 `preflight_only=true` 时,也可以是当前
工作流分支的完整 40 字符 commit SHA用于仅校验预检
- `preflight_only``true` 表示仅校验 / 构建 / 打包,`false` 表示
完整的 40 字符工作流分支提交 SHA用于仅验证的前置检查
- `preflight_only``true` 表示仅执行验证/构建/打包,`false` 表示执行
真实发布路径
- `preflight_run_id`:在真实发布路径中必填,这样工作流会复用成功预检运行中准备好的 tarball
- `preflight_run_id`:真实发布路径必填,用于让工作流复用成功前置检查运行中
准备好的 tarball
- `npm_dist_tag`:发布路径的 npm 目标标签;默认为 `beta`
`OpenClaw Release Checks` 接受以下由操作员控制的输入:
`OpenClaw Release Checks` 接受以下由操作员控制的输入:
- `ref`:现有发布标签,或者在`main` 发时用于验的当前完整 40 字符 `main` commit
SHA如果从发布分支派发则使用现有发布标签或当前完整 40 字符发布分支 commit
SHA
- `ref`:现有发布标签,或从 `main`时用于验的当前完整
40 字符 `main` 提交 SHA从发布分支发起时请使用现有发布标签或
当前完整的 40 字符发布分支提交 SHA
规则:
- Stable 和修正标签可以发布到 `beta``latest`
- Beta 预发布标签只能发布到 `beta`
- 稳定版和修正版标签可以发布到 `beta``latest`
- beta 预发布标签只能发布到 `beta`
- 对于 `OpenClaw NPM Release`,只有在
`preflight_only=true` 时才允许使用完整 commit SHA 输入
- `OpenClaw Release Checks` 始终仅用于校验,也接受当前工作流分支 commit SHA
- 发布检查的 commit-SHA 模式还要求当前工作流分支 HEAD
- 真实发布路径必须使用与预检时相同的 `npm_dist_tag`
工作流会在继续发布前校验该元数据
`preflight_only=true` 时才允许输入完整提交 SHA
- `OpenClaw Release Checks` 始终仅用于验证,也接受
当前工作流分支提交 SHA
- 发布检查的提交 SHA 模式还要求必须是当前工作流分支的 HEAD
- 真实发布路径必须使用与前置检查相同的 `npm_dist_tag`
工作流会在继续发布前验证该元数据
## Stable npm 发布顺序
## 稳定 npm 发布顺序
在切一个 stable npm 发布时:
切割稳定 npm 发布时:
1. 先运行 `OpenClaw NPM Release`,并设置 `preflight_only=true`
- 在标签尚不存在前,你可以使用当前工作流分支的完整 commit
SHA 对预检工作流进行一次仅校验的试运行
2. 按正常的 beta 优先流程选择 `npm_dist_tag=beta`,或仅当你明确想直接发布 stable 时才选择 `latest`
3. 单独运行 `OpenClaw Release Checks`,使用相同的标签,或
当前工作流分支的完整 SHA以便获得实时 prompt cache、
QA Lab parity、Matrix 和 Telegram 覆盖
- 这是有意分开的,这样实时覆盖就能保持可用,而不会再次把长时间运行或不稳定的检查耦合回发布工作流
1. 使用 `preflight_only=true` 运行 `OpenClaw NPM Release`
- 在标签尚不存在前,你可以使用当前完整的工作流分支提交
SHA对前置检查工作流进行一次仅验证的演练
2. 对于正常的 beta 优先流程,选择 `npm_dist_tag=beta`;只有在你
明确想直接发布稳定版时才选择 `latest`
3. 另外使用相同标签运行 `OpenClaw Release Checks`,或者在你需要实时 prompt cache、
QA Lab 一致性、Matrix 和 Telegram 覆盖时,使用完整的当前工作流分支提交 SHA
- 这一步之所以刻意分离,是为了在不重新耦合长时间运行或不稳定检查到发布工作流的前提下,
仍保留实时覆盖能力
4. 保存成功的 `preflight_run_id`
5. 再次运行 `OpenClaw NPM Release`,设置 `preflight_only=false`相同的
`tag`、相同的 `npm_dist_tag` 和保存下来`preflight_run_id`
6. 如果该发布先落在 `beta`,使用私有的
5. 再次运行 `OpenClaw NPM Release`,设置 `preflight_only=false`,并使用相同的
`tag`、相同的 `npm_dist_tag` 以及保存`preflight_run_id`
6. 如果该发布先落在 `beta`使用私有的
`openclaw/releases-private/.github/workflows/openclaw-npm-dist-tags.yml`
工作流,将该 stable 版本从 `beta` 提升到 `latest`
7. 如果该发布是有意直接发布到 `latest`,并且希望 `beta`
立即跟随同一 stable 构建,则使用同一个私有工作流,让两个 dist-tag 都指向这个 stable 版本,或者让其定时自愈同步稍后再移动 `beta`
工作流,将该稳定版从 `beta` 提升到 `latest`
7. 如果该发布有意直接发布到 `latest`,并且 `beta`
也应立即跟进相同的稳定构建,请使用同一个私有工作流将两个 dist-tag 都指向该稳定版本,
或让其定时自愈同步稍后再移动 `beta`
dist-tag 变更位于私有仓库中是出于安全考虑,因为它仍然
需要 `NPM_TOKEN`,而公开仓库保持仅使用 OIDC 发布
需要 `NPM_TOKEN`,而公开仓库保留仅使用 OIDC 的发布方式
这样可以让直接发布路径和 beta 优先提升路径都得到文档化,并且对操作员可见
这样既能让直接发布路径保持文档化和对操作人员可见,也能让 beta 优先的提升路径同样如此
## 公开参考
@ -180,11 +193,10 @@ dist-tag 变更位于私有仓库中是出于安全考虑,因为它仍然
- [`scripts/package-mac-dist.sh`](https://github.com/openclaw/openclaw/blob/main/scripts/package-mac-dist.sh)
- [`scripts/make_appcast.sh`](https://github.com/openclaw/openclaw/blob/main/scripts/make_appcast.sh)
维护者会使用私有发布文档
维护者会使用
[`openclaw/maintainers/release/README.md`](https://github.com/openclaw/maintainers/blob/main/release/README.md)
作为实际运行手册。
中的私有发布文档作为实际操作手册。
## 相关内容
- [发布策略](/reference/release-policy)
- [发布渠道](/zh-CN/install/development-channels)

View File

@ -1,96 +1,95 @@
---
read_when:
- 通过 ACP 运行编码 harness
- 在消息渠道上设置与对话绑定的 ACP 会话
- 将消息渠道话绑定到持久化 ACP 会话
- 排查 ACP 后端和插件接线问题
- 调试 ACP 完成结果递或智能体到智能体循环
- 在消息渠道上设置绑定到会话的 ACP 会话
- 将消息渠道话绑定到持久化 ACP 会话
- 排查 ACP 后端和插件接问题
- 调试 ACP 完成结果递或智能体到智能体循环
- 从聊天中操作 `/acp` 命令
summary: 为 Claude Code、Cursor、Gemini CLI、显式 Codex ACP 回退、OpenClaw ACP 及其他 harness 智能体使用 ACP 运行时会话
summary: 对 Claude Code、Cursor、Gemini CLI 使用 ACP 运行时会话,明确将 Codex ACP 作为回退方案,并适用于 OpenClaw ACP 及其他 harness 智能体
title: ACP 智能体
x-i18n:
generated_at: "2026-04-24T03:43:48Z"
generated_at: "2026-04-24T04:20:48Z"
model: gpt-5.4
provider: openai
source_hash: 81965807f86bac46e758d88c21e0b462909e1ce22945587828e7599c2e9659aa
source_hash: 6d59c5aa858e7888c9188ec9fc7dd5bcb9c8a5458f40d6458a5157ebc16332c2
source_path: tools/acp-agents.md
workflow: 15
---
[Agent Client ProtocolACP](https://agentclientprotocol.com/) 会话让 OpenClaw 能通过 ACP 后端插件运行外部编码 harness例如 Pi、Claude Code、Cursor、Copilot、OpenClaw ACP、OpenCode、Gemini CLI 以及其他受支持的 ACPX harness
[Agent Client Protocol (ACP)](https://agentclientprotocol.com/) 会话让 OpenClaw 能通过 ACP 后端插件运行外部编码 harness例如 Pi、Claude Code、Cursor、Copilot、OpenClaw ACP、OpenCode、Gemini CLI以及其他受支持的 ACPX harness
如果你用自然语言要求 OpenClaw 在当前话中绑定或控制 CodexOpenClaw 应使用原生 Codex app-server 插件(`/codex bind`、`/codex threads`、`/codex resume`)。如果你要求 `/acp`、ACP、acpx或 Codex 后台子会话OpenClaw 仍可通过 ACP 路由 Codex。每次 ACP 会话生成都会被跟踪为一个[后台任务](/zh-CN/automation/tasks)。
如果你用自然语言要求 OpenClaw 在当前话中绑定或控制 CodexOpenClaw 应使用原生 Codex app-server 插件(`/codex bind`、`/codex threads`、`/codex resume`)。如果你请求 `/acp`、ACP、acpx或 Codex 后台子会话OpenClaw 仍然可以通过 ACP 路由 Codex。每次 ACP 会话启动都会被跟踪为一个[后台任务](/zh-CN/automation/tasks)。
如果你用自然语言要求 OpenClaw “在线程中启动 Claude Code” 或使用其他外部 harnessOpenClaw 应将该请求路由到 ACP 运行时(而不是原生子智能体运行时)。
如果你希望 Codex 或 Claude Code 作为外部 MCP 客户端直接
连接到现有 OpenClaw 渠道对话,请使用 [`openclaw mcp serve`](/zh-CN/cli/mcp)
而不是 ACP。
如果你希望 Codex 或 Claude Code 作为外部 MCP 客户端直接连接到现有的 OpenClaw 渠道会话,
请使用 [`openclaw mcp serve`](/zh-CN/cli/mcp),而不是 ACP。
## 想看哪一页?
## 想看哪一页?
这里有三个很容易混淆的相邻功能面:
这里附近有三个很容易混淆的界面:
| 你想要…… | 使用这个 | 说明 |
| 你想要…… | 使用这个 | 说明 |
| ----------------------------------------------------------------------------------------------- | ------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 在当前对话中绑定或控制 Codex | `/codex bind`、`/codex threads` | 原生 Codex app-server 路径包括绑定聊天回复、图像转发、model/fast/permissions、停止和引导控制。ACP 是显式回退路径 |
| 通过 OpenClaw 运行 Claude Code、Gemini CLI、显式 Codex ACP 或其他外部 harness | 本页ACP 智能体 | 聊天绑定会话、`/acp spawn`、`sessions_spawn({ runtime: "acp" })`、后台任务、运行时控制 |
| 将 OpenClaw Gateway 网关会话作为 ACP 服务器暴露给编辑器或客户端 | [`openclaw acp`](/zh-CN/cli/acp) | 桥接模式。IDE/客户端通过 stdio/WebSocket 向 OpenClaw 发送 ACP |
| 复用本地 AI CLI 作为纯文本回退模型 | [CLI 后端](/zh-CN/gateway/cli-backends) | 不是 ACP。没有 OpenClaw 工具、没有 ACP 控制、没有 harness 运行时 |
| 在当前会话中绑定或控制 Codex | `/codex bind`、`/codex threads` | 原生 Codex app-server 路径;包括绑定聊天回复、图片转发、模型/快速/权限、停止和引导控制。ACP 是一种显式回退方案 |
| 通过 OpenClaw 运行 Claude Code、Gemini CLI、显式 Codex ACP 或其他外部 harness | 本页ACP 智能体 | 绑定聊天的会话、`/acp spawn`、`sessions_spawn({ runtime: "acp" })`、后台任务、运行时控制 |
| 将 OpenClaw Gateway 网关会话作为 ACP 服务器暴露给编辑器或客户端 | [`openclaw acp`](/zh-CN/cli/acp) | 桥接模式。IDE/客户端通过 stdio/WebSocket 使用 ACP 与 OpenClaw 通信 |
| 将本地 AI CLI 复用为纯文本回退模型 | [CLI 后端](/zh-CN/gateway/cli-backends) | 不是 ACP。没有 OpenClaw 工具、没有 ACP 控制、没有 harness 运行时 |
## 这是开箱即用的吗?
## 这个开箱即用吗?
通常是。全新安装默认启用内置的 `acpx` 运行时插件,该插件带有插件本地固定版本的 `acpx` 二进制文件OpenClaw 会在启动时探测并自我修复。运行 `/acp doctor` 可进行就绪性检查。
通常可以。全新安装会默认启用内置的 `acpx` 运行时插件,并附带一个插件本地固定版本的 `acpx` 二进制文件OpenClaw 会在启动时探测并自我修复它。运行 `/acp doctor` 可执行就绪检查。
首次运行的常见问题
首次运行的注意事项
- 目标 harness 适配器Codex、Claude 等)可能会在你次使用时通过 `npx` 按需获取。
- 该 harness 的厂商认证仍必须已存在于主机上。
- 如果主机没有 npm 或网络访问,首次适配器获取会失败,直到缓存预热完成或通过其他方式安装适配器
- 目标 harness 适配器Codex、Claude 等)可能会在你第一次使用时通过 `npx` 按需获取。
- 该 harness 的厂商认证仍必须已存在于主机上。
- 如果主机没有 npm 或网络访问能力,首次运行时的适配器获取会失败,直到缓存被预热或适配器以其他方式安装为止
## 操作员运行手册
## 操作手册
在聊天中快速使用 `/acp` 的流程:
1. **生成** — `/acp spawn claude --bind here`、`/acp spawn gemini --mode persistent --thread auto`,或显式 `/acp spawn codex --bind here`
2. 在绑定的话或线程中**工作**(或者显式指定会话键)。
1. **启动** — `/acp spawn claude --bind here`、`/acp spawn gemini --mode persistent --thread auto`,或显式使用 `/acp spawn codex --bind here`
2. 在绑定的话或线程中**工作**(或者显式指定会话键)。
3. **检查状态**`/acp status`
4. **调** — `/acp model <provider/model>`、`/acp permissions <profile>`、`/acp timeout <seconds>`
5. 在不替换上下文的情况下**引导** — `/acp steer tighten logging and continue`
4. **调** — `/acp model <provider/model>`、`/acp permissions <profile>`、`/acp timeout <seconds>`
5. **引导**而不替换上下文`/acp steer tighten logging and continue`
6. **停止**`/acp cancel`(当前轮次)或 `/acp close`(会话 + 绑定)
应路由到原生 Codex 插件的自然语言触发
应路由到原生 Codex 插件的自然语言触发
- “这个 Discord 渠道绑定到 Codex。”
- “这个聊天附加到 Codex 线程 `<id>`。”
- “这个 Discord 渠道绑定到 Codex。”
- “这个聊天附加到 Codex 线程 `<id>`。”
- “显示 Codex 线程,然后绑定这个。”
原生 Codex 话绑定是默认的聊天控制路径,但对于交互式 Codex 批/工具流程它有意保持保守OpenClaw 动态工具和审批提示目前尚未通过这条绑定聊天路径暴露,因此这类请求会以清晰的解释被拒绝。当工作流依赖 OpenClaw 动态工具或长时间运行的交互式批时,请使用 Codex harness 路径或显式 ACP 回退。
原生 Codex 话绑定是默认的聊天控制路径,但对于交互式 Codex 批/工具流程它有意保持保守OpenClaw 动态工具和批准提示目前尚未通过此绑定聊天路径暴露,因此这些请求会被拒绝,并附带清晰说明。当工作流依赖 OpenClaw 动态工具或长时间运行的交互式批时,请使用 Codex harness 路径或显式 ACP 回退方案
应路由到 ACP 运行时的自然语言触发
应路由到 ACP 运行时的自然语言触发
- “把这个作为一次性 Claude Code ACP 会话运行,并总结结果。”
- “这个任务使用 Gemini CLI 在线程中运行,然后后续继续留在同一线程中。”
- “通过 ACP 在线程后台运行 Codex。”
- “将这个作为一次性的 Claude Code ACP 会话运行,并总结结果。”
- “对这个任务使用 Gemini CLI 在线程中处理,然后在同一个线程中继续后续操作。”
- “通过 ACP 在后台线程中运行 Codex。”
OpenClaw 会选择 `runtime: "acp"`,解析 harness `agentId`,在支持时绑定到当前对话或线程,并将后续消息路由到该会话,直到关闭/过期。只有在明确要求 ACP请求的后台运行时仍然需要 ACP 时Codex 才会走这条路径。
OpenClaw 会选择 `runtime: "acp"`,解析 harness `agentId`,在支持时绑定到当前会话或线程,并将后续内容路由到该会话,直到关闭或过期。只有在明确要求 ACP或所请求的后台运行时仍然需要 ACP 时Codex 才会走这条路径。
## ACP 与子智能体
当你需要外部 harness 运行时时,请使用 ACP。对于 Codex 对话绑定/控制,请使用原生 Codex app-server。若你想使用 OpenClaw 原生的委托运行,请使用子智能体。
当你需要外部 harness 运行时时,请使用 ACP。对于 Codex 会话绑定/控制,请使用原生 Codex app-server。当你需要 OpenClaw 原生委托执行时,请使用子智能体。
| 区域 | ACP 会话 | 子智能体运行 |
| 区域 | ACP 会话 | 子智能体运行 |
| ------------- | ------------------------------------- | ---------------------------------- |
| 运行时 | ACP 后端插件(例如 acpx | OpenClaw 原生子智能体运行时 |
| 会话键 | `agent:<agentId>:acp:<uuid>` | `agent:<agentId>:subagent:<uuid>` |
| 主要命令 | `/acp ...` | `/subagents ...` |
| 生成工具 | `sessions_spawn` 搭配 `runtime:"acp"` | `sessions_spawn`(默认运行时) |
| 运行时 | ACP 后端插件(例如 acpx | OpenClaw 原生子智能体运行时 |
| 会话键 | `agent:<agentId>:acp:<uuid>` | `agent:<agentId>:subagent:<uuid>` |
| 主要命令 | `/acp ...` | `/subagents ...` |
| 启动工具 | `sessions_spawn` with `runtime:"acp"` | `sessions_spawn`(默认运行时) |
[子智能体](/zh-CN/tools/subagents)。
请参阅 [子智能体](/zh-CN/tools/subagents)。
## ACP 如何运行 Claude Code
对于通过 ACP 运行的 Claude Code其栈为
对于通过 ACP 运行的 Claude Code栈为:
1. OpenClaw ACP 会话控制平面
2. 内置 `acpx` 运行时插件
@ -99,59 +98,59 @@ OpenClaw 会选择 `runtime: "acp"`,解析 harness `agentId`,在支持时绑
重要区别:
- ACP Claude 是 harness 会话,具有 ACP 控制、会话恢复、后台任务跟踪以及可选的对话/线程绑定。
- ACP Claude 是一种 harness 会话,具有 ACP 控制、会话恢复、后台任务跟踪,以及可选的会话/线程绑定。
- CLI 后端是独立的纯文本本地回退运行时。参见 [CLI 后端](/zh-CN/gateway/cli-backends)。
操作员,实用规则是:
对操作来说,实用规则是:
- 想要 `/acp spawn`、可绑定会话、运行时控制或持久化 harness 工作:使用 ACP
- 想要通过原始 CLI 实现简单的本地文本回退:使用 CLI 后端
- 想要 `/acp spawn`、可绑定的会话、运行时控制或持久的 harness 工作:使用 ACP
- 想通过原始 CLI 获得简单的本地文本回退:使用 CLI 后端
## 绑定会话
### 当前话绑定
### 当前话绑定
`/acp spawn <harness> --bind here` 会将当前对话固定到新生成的 ACP 会话 —— 不创建子线程继续使用同一个聊天界面。OpenClaw 仍然持有传输、认证、安全和投递;该对话中的后续消息会路由到同一会话;`/new` 和 `/reset`原地重置该会话;`/acp close` 会移除绑定。
`/acp spawn <harness> --bind here` 会将当前会话固定到新启动的 ACP 会话上——不创建子线程保持同一个聊天界面。OpenClaw 继续负责传输、认证、安全和投递;该会话中的后续消息会路由到同一个会话;`/new` 和 `/reset` 会在原地重置该会话;`/acp close` 会移除绑定。
理解模型:
心智模型:
- **聊天界面**— 人们持续交谈的地方Discord 渠道、Telegram 话题、iMessage 聊天)。
- **ACP 会话** OpenClaw 路由到的持久 Codex/Claude/Gemini 运行时状态。
- **子线程/话题**— 仅由 `--thread ...` 创建的可选额外消息界面。
- **运行时工作区** harness 运行所在的文件系统位置(`cwd`、仓库检出目录、后端工作区)。它独立于聊天界面。
- **聊天界面** 人们持续交流的地方Discord 渠道、Telegram 话题、iMessage 聊天)。
- **ACP 会话** — OpenClaw 路由到的持久 Codex/Claude/Gemini 运行时状态。
- **子线程/话题** 仅在使用 `--thread ...`创建的可选额外消息界面。
- **运行时工作区** — harness 运行所在的文件系统位置(`cwd`、仓库检出目录、后端工作区)。它独立于聊天界面。
示例:
- `/codex bind`— 保持当前聊天,生成或附加原生 Codex app-server并将未来消息路由到这里。
- `/codex model gpt-5.4`、`/codex fast on`、`/codex permissions yolo` —— 在聊天中调优已绑定的原生 Codex 线程。
- `/codex stop``/codex steer focus on the failing tests first` 控制当前活跃的原生 Codex 轮次。
- `/acp spawn codex --bind here` 对 Codex 显式使用 ACP 回退。
- `/acp spawn codex --thread auto`— OpenClaw 可能会创建一个子线程/话题并绑定到那里。
- `/acp spawn codex --bind here --cwd /workspace/repo`— 保持同一聊天绑定,但 Codex 在 `/workspace/repo` 中运行。
- `/codex bind` 保留当前聊天,启动或附加原生 Codex app-server并将未来消息路由到这里。
- `/codex model gpt-5.4`、`/codex fast on`、`/codex permissions yolo` — 在聊天中调整已绑定的原生 Codex 线程。
- `/codex stop``/codex steer focus on the failing tests first` — 控制当前活跃的原生 Codex 轮次。
- `/acp spawn codex --bind here` — 对 Codex 使用显式 ACP 回退方案
- `/acp spawn codex --thread auto` OpenClaw 可以创建一个子线程/话题并绑定到那里。
- `/acp spawn codex --bind here --cwd /workspace/repo` 绑定同一个聊天,Codex 在 `/workspace/repo` 中运行。
说明:
- `--bind here``--thread ...` 互斥。
- `--bind here` 仅适用于声明支持当前话绑定的渠道;否则 OpenClaw 会返回清晰的不支持提示。绑定会在 Gateway 网关重启后继续保留。
- 在 Discord 上,只有当 OpenClaw 需要为 `--thread auto|here` 创建子线程时,才要 `spawnAcpSessions` —— 对于 `--bind here` 不需要。
- 如果你在未指定 `--cwd` 的情况下生成到另一个 ACP 智能体OpenClaw 默认继承**目标智能体的**工作区。缺失的继承路径(`ENOENT`/`ENOTDIR`)会回退到后端默认值;其他访问错误(如 `EACCES`)会作为生成错误直接暴露
- `--bind here` 仅适用于声明支持当前话绑定的渠道;否则 OpenClaw 会返回清晰的不支持提示。绑定会在 Gateway 网关重启后继续保留。
- 在 Discord 上,当 OpenClaw 需要为 `--thread auto|here` 创建子线程时,才`spawnAcpSessions`——`--bind here` 不需要。
- 如果你启动到另一个 ACP 智能体且未指定 `--cwd`OpenClaw 默认会继承**目标智能体的**工作区。缺失的继承路径(`ENOENT`/`ENOTDIR`)会回退到后端默认值;其他访问错误(如 `EACCES`)会作为启动错误直接显示
### 线程绑定会话
当渠道适配器启用了线程绑定时ACP 会话可以绑定到线程:
某个渠道适配器启用了线程绑定时ACP 会话可以绑定到线程:
- OpenClaw 将线程绑定到目标 ACP 会话。
- OpenClaw 将一个线程绑定到目标 ACP 会话。
- 该线程中的后续消息会路由到绑定的 ACP 会话。
- ACP 输出会投递回同一线程。
- 取消聚焦/关闭/归档/空闲超时或最大生命周期过期会移除绑定。
- ACP 输出会回传到同一线程。
- 取消聚焦/关闭/归档/空闲超时或最大存活时间到期会移除绑定。
线程绑定支持取决于适配器。如果当前渠道适配器不支持线程绑定OpenClaw 会返回清晰的不支持/不可用提示。
线程绑定 ACP 所需功能标志:
线程绑定 ACP 所需功能标志:
- `acp.enabled=true`
- `acp.dispatch.enabled` 默认开启(设为 `false` 可暂停 ACP 分发)
- 已启用渠道适配器的 ACP 线程生成标志(适配器专属
- 已启用渠道适配器的 ACP 线程启动标志(特定于适配器
- Discord`channels.discord.threadBindings.spawnAcpSessions=true`
- Telegram`channels.telegram.threadBindings.spawnAcpSessions=true`
@ -161,30 +160,30 @@ OpenClaw 会选择 `runtime: "acp"`,解析 harness `agentId`,在支持时绑
- 当前内置支持:
- Discord 线程/渠道
- Telegram 话题(群组/超级群组中的论坛话题和私信话题)
- 插件渠道也可通过相同的绑定接口添加支持。
- 渠道插件也可通过相同的绑定接口添加支持。
## 渠道专属设置
## 渠道特定设置
对于非临时工作流,请在顶层 `bindings[]` 条目中配置持久 ACP 绑定。
对于非临时工作流,请在顶层 `bindings[]` 条目中配置持久 ACP 绑定。
### 绑定模型
- `bindings[].type="acp"` 表示持久化 ACP 对话绑定。
- `bindings[].match` 用于标识目标话:
- `bindings[].type="acp"` 用于标记持久 ACP 会话绑定。
- `bindings[].match` 用于标识目标话:
- Discord 渠道或线程:`match.channel="discord"` + `match.peer.id="<channelOrThreadId>"`
- Telegram 论坛话题:`match.channel="telegram"` + `match.peer.id="<chatId>:topic:<topicId>"`
- BlueBubbles 私信/群聊:`match.channel="bluebubbles"` + `match.peer.id="<handle|chat_id:*|chat_guid:*|chat_identifier:*>"`
- BlueBubbles 私信/群聊:`match.channel="bluebubbles"` + `match.peer.id="<handle|chat_id:*|chat_guid:*|chat_identifier:*>"`
对于稳定的群组绑定,优先使用 `chat_id:*``chat_identifier:*`
- iMessage 私信/群聊:`match.channel="imessage"` + `match.peer.id="<handle|chat_id:*|chat_guid:*|chat_identifier:*>"`
- iMessage 私信/群聊:`match.channel="imessage"` + `match.peer.id="<handle|chat_id:*|chat_guid:*|chat_identifier:*>"`
对于稳定的群组绑定,优先使用 `chat_id:*`
- `bindings[].agentId` 是所属 OpenClaw 智能体 id。
- 可选的 ACP 覆盖位于 `bindings[].acp` 下:
- `bindings[].agentId` 是所属 OpenClaw 智能体 id。
- 可选的 ACP 覆盖位于 `bindings[].acp` 下:
- `mode``persistent` 或 `oneshot`
- `label`
- `cwd`
- `backend`
### 每智能体运行时默认值
### 每智能体运行时默认值
使用 `agents.list[].runtime` 为每个智能体一次性定义 ACP 默认值:
@ -282,22 +281,22 @@ ACP 绑定会话的覆盖优先级:
行为:
- OpenClaw 会确保已配置的 ACP 会话在使用前存在。
- 该渠道或话题中的消息会路由到已配置的 ACP 会话。
- 在已绑定的对话中,`/new` 和 `/reset`原地重置同一个 ACP 会话键。
- 临时运行时绑定(例如由线程聚焦流程创建的绑定)在存在时仍会生效
- 对于没有显式 `cwd` 的跨智能体 ACP 生成OpenClaw 会从智能体配置中继承目标智能体工作区。
- 缺失的继承工作区路径会回退到后端默认 `cwd`;非缺失访问失败则会作为生成错误暴露
- OpenClaw 会在使用前确保已配置的 ACP 会话存在。
- 该渠道或话题中的消息会路由到已配置的 ACP 会话。
- 在绑定的会话中,`/new` 和 `/reset` 会在原地重置同一个 ACP 会话键。
- 临时运行时绑定(例如由线程聚焦流程创建的绑定)在存在时仍然适用
- 对于未显式指定 `cwd` 的跨智能体 ACP 启动OpenClaw 会从智能体配置中继承目标智能体工作区。
- 缺失的继承工作区路径会回退到后端默认 `cwd`;非缺失类访问失败会作为启动错误直接显示
## 启动 ACP 会话(界面
## 启动 ACP 会话(接口
### 来自 `sessions_spawn`
### `sessions_spawn` 启动
使用 `runtime: "acp"` 从智能体轮次或工具调用中启动 ACP 会话。
使用 `runtime: "acp"` 从智能体轮次或工具调用中启动 ACP 会话。
```json
{
"task": "Open the repo and summarize failing tests",
"task": "打开仓库并总结失败的测试",
"runtime": "acp",
"agentId": "codex",
"thread": true,
@ -307,121 +306,121 @@ ACP 绑定会话的覆盖优先级:
说明:
- `runtime` 默认是 `subagent`,因此对于 ACP 会话请显式设置 `runtime: "acp"`
- 如果省略 `agentId`则在已配置时,OpenClaw 会使用 `acp.defaultAgent`
- `mode: "session"` 需要 `thread: true` 才能保留持久化绑定对话。
- `runtime` 默认是 `subagent`,因此对于 ACP 会话请显式设置 `runtime: "acp"`
- 如果省略 `agentId`OpenClaw 会在已配置时使用 `acp.defaultAgent`
- `mode: "session"` 需要 `thread: true` 才能保持持久的绑定会话。
接口详情:
- `task`(必需):发送到 ACP 会话的初始提示词
- `runtime`ACP 必需):必须是 `"acp"`
- `agentId`可选ACP 目标 harness id。已设置,则回退到 `acp.defaultAgent`
- `task`(必填):发送到 ACP 会话的初始提示
- `runtime`ACP 必填):必须为 `"acp"`
- `agentId`可选ACP 目标 harness id。如果已设置,则回退到 `acp.defaultAgent`
- `thread`(可选,默认 `false`):在支持时请求线程绑定流程。
- `mode`(可选):`run`(一次性)或 `session`(持久)。
- 默认值 `run`
- 如果 `thread: true` 且省略 modeOpenClaw 可能会按运行时路径默认采用持久化行为
- `mode`(可选):`run`(一次性)或 `session`(持久)。
- 默认值 `run`
- 如果 `thread: true` 且省略`mode`OpenClaw 可能会根据运行时路径默认采用持久行为
- `mode: "session"` 需要 `thread: true`
- `cwd`(可选):请求的运行时工作目录(由后端/运行时策略校验)。如果省略,则 ACP 生成会在已配置时继承目标智能体工作区;缺失的继承路径会回退到后端默认值,而真正的访问错误会被返回。
- `label`(可选):用于会话/banner 文本中的面向操作员标签。
- `resumeSessionId`(可选):恢复现有 ACP 会话,而不是创建新会话。智能体会通过 `session/load` 回放其对话历史。需要 `runtime: "acp"`
- `streamTo`(可选):`"parent"` 会将初始 ACP 运行进度摘要作为系统事件流式传回请求方会话。
- 可用时,接受的响应会包含 `streamLogPath`,指向一个会话作用域 JSONL 日志(`<sessionId>.acp-stream.jsonl`),你可以 tail 它来查看完整中继历史。
- `model`(可选):对子 ACP 会话的显式模型覆盖。对于 `runtime: "acp"` 会生效,因此子会话会使用请求的模型,而不是静默回退到目标智能体默认
- `cwd`(可选):请求的运行时工作目录(由后端/运行时策略校验)。如果省略,ACP 启动会在配置时继承目标智能体工作区;缺失的继承路径会回退到后端默认值,而真实访问错误会被直接返回。
- `label`(可选):用于会话/横幅文本中的面向操作员标签。
- `resumeSessionId`(可选):恢复现有 ACP 会话,而不是创建新会话。智能体会通过 `session/load` 重放其会话历史。需要 `runtime: "acp"`
- `streamTo`(可选):`"parent"` 会将初始 ACP 运行进度摘要作为系统事件流式返回给请求方会话。
- 可用时,接受的响应会包含 `streamLogPath`,指向会话范围内的 JSONL 日志(`<sessionId>.acp-stream.jsonl`),你可以对其执行 `tail`查看完整中继历史。
- `model`可选ACP 会话的显式模型覆盖。对于 `runtime: "acp"` 会生效,因此子会话会使用请求的模型,而不是静默回退到目标智能体默认模型
## 递模型
## 递模型
ACP 会话既可以是交互式工作区,也可以是由父级持有的后台工作。投递路径取决于其形态。
ACP 会话既可以是交互式工作区,也可以是父级拥有的后台任务。传递路径取决于它的形态。
### 交互式 ACP 会话
交互式会话旨在持续在可见聊天界面对话:
交互式会话旨在持续在可见聊天界面对话:
- `/acp spawn ... --bind here` 会将当前话绑定到 ACP 会话。
- `/acp spawn ... --bind here` 会将当前话绑定到 ACP 会话。
- `/acp spawn ... --thread ...` 会将渠道线程/话题绑定到 ACP 会话。
- 持久配置的 `bindings[].type="acp"` 会将匹配的话路由到同一个 ACP 会话。
- 持久配置的 `bindings[].type="acp"` 会将匹配的话路由到同一个 ACP 会话。
在绑定对话中的后续消息会直接路由到 ACP 会话,ACP 输出会投递回同一个渠道/线程/话题。
绑定会话中的后续消息会直接路由到 ACP 会话ACP 输出会回传到同一个渠道/线程/话题。
### 父级有的一次性 ACP 会话
### 父级有的一次性 ACP 会话
由另一智能体运行生成的一次性 ACP 会话是后台子会话,类似子智能体:
由另一个智能体运行启动的一次性 ACP 会话是后台子级,类似子智能体:
- 父级通过 `sessions_spawn({ runtime: "acp", mode: "run" })` 请求工作
- 子级在自己的 ACP harness 会话中运行。
- 完成后通过内部任务完成通知路径回报结果
- 父级通过 `sessions_spawn({ runtime: "acp", mode: "run" })` 请求执行任务
- 子级在自己的 ACP harness 会话中运行。
- 完成结果通过内部任务完成公告路径回报
- 当需要面向用户的回复时,父级会以普通助手语气重写子级结果。
不要将这条路径视为父子之间的点对点聊天。子级已经有回传给父级的完成通道。
不要把这一路径视为父级与子级之间的点对点聊天。子级已经有一条回传给父级的完成通道。
### `sessions_send` 和 A2A
### `sessions_send` 和 A2A
`sessions_send` 可以在生成后指向另一个会话。对于普通对等会话OpenClaw 在注入消息后会使用智能体到智能体A2A的后续路径
`sessions_send` 可以在启动后以另一个会话为目标。对于普通对等会话OpenClaw 会在注入消息后使用智能体到智能体A2A的后续路径
- 等待目标会话回复
- 等待目标会话回复
- 可选地让请求方与目标交换有限轮次的后续消息
- 要求目标生成一条 announce 消息
- 将该 announce 投递到可见渠道或线程
- 要求目标生成一条公告消息
- 将该公告投递到可见渠道或线程
这条 A2A 路径是对等发送中的回退机制,用于发送方需要一个可见后续结果的场景。当一个无关会话在较宽松的 `tools.sessions.visibility` 设置下可以查看并向 ACP 目标发消息时,该路径仍保持启用。
对于发送方需要可见后续内容的对等发送,这条 A2A 路径是一种回退机制。当一个无关会话能够查看并向 ACP 目标发送消息时,例如在宽泛的 `tools.sessions.visibility` 设置下,它仍会保持启用。
只有当请求方是其自己所持有的一次性 ACP 子会话的父级时OpenClaw 才会跳过 A2A 后续。在这种情况下,如果在任务完成之上再运行 A2A可能会用子级结果唤醒父级把父级回复转发回子级,从而形成父子回声循环。对于这种已持有子会话场景`sessions_send` 结果会报告 `delivery.status="skipped"`,因为完成路径已经负责结果。
仅当请求方是其自身父级拥有的一次性 ACP 子级的父级时OpenClaw 才会跳过 A2A 后续流程。在这种情况下,如果在任务完成之上再运行 A2A可能会用子级结果唤醒父级将父级回复转发回子级,从而形成父/子回声循环。对于这种已拥有子级的情况`sessions_send` 结果会报告 `delivery.status="skipped"`,因为完成路径已经负责处理结果。
### 恢复现有会话
使用 `resumeSessionId`以继续先前的 ACP 会话,而不是重新开始。智能体会通过 `session/load` 回放其对话历史,因此会带着之前的完整上下文继续
使用 `resumeSessionId`继续之前的 ACP 会话,而不是重新开始。智能体会通过 `session/load` 重放其会话历史,因此它会带着先前完整上下文继续执行
```json
{
"task": "Continue where we left off — fix the remaining test failures",
"task": "从我们上次中断的地方继续——修复剩余的测试失败",
"runtime": "acp",
"agentId": "codex",
"resumeSessionId": "<previous-session-id>"
}
```
常见使用场景
常见用例
- 将 Codex 会话从你的笔记本切换到手机 —— 告诉你的智能体从你中断的地方继续
- 继续你在 CLI 中以交互方式启动、现在要通过智能体无头运行的编码会话
- 将一个 Codex 会话从你的笔记本电脑移交到手机上——告诉你的智能体从你上次离开的地方继续
- 继续你之前在 CLI 中以交互方式启动、现在改为通过智能体无头运行的编码会话
- 接着处理因 Gateway 网关重启或空闲超时而中断的工作
说明:
- `resumeSessionId` 需要 `runtime: "acp"` —— 如果与子智能体运行时一起使用,会返回错误。
- `resumeSessionId` 会恢复上游 ACP 话历史;`thread` 和 `mode` 仍会正常应用于你正在创建的新 OpenClaw 会话,因此 `mode: "session"`需要 `thread: true`
- `resumeSessionId` 需要 `runtime: "acp"`——如果与子智能体运行时一起使用,将返回错误。
- `resumeSessionId` 会恢复上游 ACP 话历史;`thread` 和 `mode` 仍会正常应用于你正在创建的新 OpenClaw 会话,因此 `mode: "session"` 仍需要 `thread: true`
- 目标智能体必须支持 `session/load`Codex 和 Claude Code 都支持)。
- 如果找不到该会话 ID生成会以清晰错误失败 —— 不会静默回退到新会话。
- 如果找不到该会话 id启动会以清晰错误失败——不会静默回退到新会话。
<Accordion title="部署后冒烟测试">
<Accordion title="部署后冒烟测试">
在 Gateway 网关部署后,请运行实时端到端检查,而不要只依赖单元测试:
在 Gateway 网关部署后,运行一次真实的端到端检查,而不是只相信单元测试:
1. 验证目标主机上的已部署 Gateway 网关版本和提交。
2. 向实时智能体打开一个临时 ACPX 桥接会话。
3. 要求该智能体调用 `sessions_spawn`参数为 `runtime: "acp"`、`agentId: "codex"`、`mode: "run"`,任务 `Reply with exactly LIVE-ACP-SPAWN-OK`
1. 在目标主机上验证已部署的 Gateway 网关版本和提交。
2. 打开一个临时 ACPX 桥接会话并连接到一个在线智能体
3. 要求该智能体调用 `sessions_spawn`并传入 `runtime: "acp"`、`agentId: "codex"`、`mode: "run"`以及任务 `Reply with exactly LIVE-ACP-SPAWN-OK`
4. 验证 `accepted=yes`、真实的 `childSessionKey`,且没有校验器错误。
5. 清理临时桥接会话。
5. 清理临时桥接会话。
将检查门槛保持在 `mode: "run"`,并跳过 `streamTo: "parent"` —— 线程绑定的 `mode: "session"` 和流式中继路径属于另一个更丰富的集成验证阶段。
将检查门槛保持在 `mode: "run"`,并跳过 `streamTo: "parent"`——绑定线程的 `mode: "session"` 和流中继路径属于独立且更丰富的集成验证阶段。
</Accordion>
## 沙箱兼容性
ACP 会话当前运行在主机运行时中,而不是 OpenClaw 沙箱内
ACP 会话当前在主机运行时上运行,而不是在 OpenClaw 沙箱内运行
当前限制:
- 如果请求方会话处于沙箱中,则无论是 `sessions_spawn({ runtime: "acp" })` 还是 `/acp spawn`ACP 生成都会被阻止
- 如果请求方会话处于沙箱隔离状态,则 `sessions_spawn({ runtime: "acp" })``/acp spawn` 都会阻止 ACP 启动
- 错误:`Sandboxed sessions cannot spawn ACP sessions because runtime="acp" runs on the host. Use runtime="subagent" from sandboxed sessions.`
- 使用 `runtime: "acp"``sessions_spawn` 不支持 `sandbox: "require"`
- 带有 `runtime: "acp"``sessions_spawn` 不支持 `sandbox: "require"`
- 错误:`sessions_spawn sandbox="require" is unsupported for runtime="acp" because ACP sessions run outside the sandbox. Use runtime="subagent" or sandbox="inherit".`
当你需要强制沙箱执行时,请使用 `runtime: "subagent"`
### 来自 `/acp` 命令
### `/acp` 命令启动
当需要在聊天中进行显式操作员控制时,请使用 `/acp spawn`
在需要时,使用 `/acp spawn` 从聊天中进行显式的操作员控制
```text
/acp spawn codex --mode persistent --thread auto
@ -438,121 +437,121 @@ ACP 会话当前运行在主机运行时中,而不是 OpenClaw 沙箱内。
- `--cwd <absolute-path>`
- `--label <name>`
参见 [斜杠命令](/zh-CN/tools/slash-commands)。
参见[斜杠命令](/zh-CN/tools/slash-commands)。
## 会话目标解析
大多数 `/acp` action 都接受一个可选的会话目标(`session-key`、`session-id` 或 `session-label`)。
大多数 `/acp` 操作都接受一个可选的会话目标(`session-key`、`session-id` 或 `session-label`)。
解析顺序:
1. 显式目标参数(或 `/acp steer``--session`
- 先尝试 key
- 再尝试 UUID 形式的 session id
- 再尝试 label
2. 当前线程绑定(如果当前对话/线程已绑定到 ACP 会话)
- 先尝试
- 再尝试 UUID 形式的会话 id
- 最后尝试标签
2. 当前线程绑定(如果此会话/线程已绑定到 ACP 会话)
3. 当前请求方会话回退
当前话绑定和线程绑定都会参与第 2 步。
当前话绑定和线程绑定都会参与第 2 步。
如果没有解析出目标OpenClaw 会返回清晰错误(`Unable to resolve session target: ...`)。
如果无法解析出目标OpenClaw 会返回清晰错误(`Unable to resolve session target: ...`)。
## 生成绑定模式
## 启动绑定模式
`/acp spawn` 支持 `--bind here|off`
| 模式 | 行为 |
| 模式 | 行为 |
| ------ | ---------------------------------------------------------------------- |
| `here` | 原地绑定当前活跃对话;如果当前没有活跃对话则失败。 |
| `off` | 不创建当前对话绑定。 |
| `here` | 原地绑定当前活动会话;如果当前没有活动会话则失败。 |
| `off` | 不创建当前会话绑定。 |
说明:
- `--bind here`“让这个渠道或聊天由 Codex 驱动”的最简单操作员路径。
- `--bind here`操作员实现“让这个渠道或聊天由 Codex 提供支持”的最简单路径。
- `--bind here` 不会创建子线程。
- `--bind here` 仅在暴露当前话绑定支持的渠道上可用。
- `--bind``--thread` 不能在同一个 `/acp spawn` 调用中组合使用。
- `--bind here` 仅在暴露当前话绑定支持的渠道上可用。
- `--bind``--thread` 不能在同一个 `/acp spawn` 调用中同时使用。
## 生成线程模式
## 启动线程模式
`/acp spawn` 支持 `--thread auto|here|off`
| 模式 | 行为 |
| 模式 | 行为 |
| ------ | --------------------------------------------------------------------------------------------------- |
| `auto` | 在活线程中:绑定该线程。在线程外:在支持时创建/绑定一个子线程。 |
| `here` | 要求当前处于活跃线程中;否则失败。 |
| `off` | 不进行绑定。会话以未绑定状态启动。 |
| `auto` | 在活线程中:绑定该线程。在线程外:在支持时创建/绑定一个子线程。 |
| `here` | 要求当前处于活动线程中;如果不在线程内则失败。 |
| `off` | 不进行绑定。会话以未绑定状态启动。 |
说明:
- 在不支持线程绑定的界面上,默认行为实际上等同于 `off`
- 线程绑定生成需要渠道策略支持:
- 在非线程绑定界面上,默认行为实际上等同于 `off`
- 线程绑定启动需要渠道策略支持:
- Discord`channels.discord.threadBindings.spawnAcpSessions=true`
- Telegram`channels.telegram.threadBindings.spawnAcpSessions=true`
- 如果你想固定当前对话而不创建子线程,请使用 `--bind here`
- 当你想固定当前会话而不创建子线程时,请使用 `--bind here`
## ACP 控制
| 命令 | 功能 | 示例 |
| 命令 | 作用 | 示例 |
| -------------------- | --------------------------------------------------------- | ------------------------------------------------------------- |
| `/acp spawn` | 创建 ACP 会话;可选当前绑定或线程绑定。 | `/acp spawn codex --bind here --cwd /repo` |
| `/acp cancel` | 取消目标会话中正在进行的轮次。 | `/acp cancel agent:codex:acp:<uuid>` |
| `/acp steer` | 向运行的会话发送引导指令。 | `/acp steer --session support inbox prioritize failing tests` |
| `/acp close` | 关闭会话并解除线程目标绑定。 | `/acp close` |
| `/acp status` | 显示后端、模式、状态、运行时选项、能力。 | `/acp status` |
| `/acp set-mode` | 为目标会话设置运行时模式。 | `/acp set-mode plan` |
| `/acp set` | 写入通用运行时配置选项。 | `/acp set model openai/gpt-5.4` |
| `/acp cwd` | 设置运行时工作目录覆盖。 | `/acp cwd /Users/user/Projects/repo` |
| `/acp permissions` | 设置批策略配置文件。 | `/acp permissions strict` |
| `/acp timeout` | 设置运行时超时(秒)。 | `/acp timeout 120` |
| `/acp model` | 设置运行时模型覆盖。 | `/acp model anthropic/claude-opus-4-6` |
| `/acp reset-options` | 移除会话运行时选项覆盖。 | `/acp reset-options` |
| `/acp sessions` | 从存储中列出最近的 ACP 会话。 | `/acp sessions` |
| `/acp doctor` | 检查后端健康状态、能力和可执行修复。 | `/acp doctor` |
| `/acp install` | 打印确定性的安装和启用步骤。 | `/acp install` |
| `/acp spawn` | 创建 ACP 会话;可选当前绑定或线程绑定。 | `/acp spawn codex --bind here --cwd /repo` |
| `/acp cancel` | 取消目标会话中正在进行的轮次。 | `/acp cancel agent:codex:acp:<uuid>` |
| `/acp steer` | 向正在运行的会话发送引导指令。 | `/acp steer --session support inbox prioritize failing tests` |
| `/acp close` | 关闭会话并解除线程目标绑定。 | `/acp close` |
| `/acp status` | 显示后端、模式、状态、运行时选项和能力。 | `/acp status` |
| `/acp set-mode` | 为目标会话设置运行时模式。 | `/acp set-mode plan` |
| `/acp set` | 写入通用运行时配置选项。 | `/acp set model openai/gpt-5.4` |
| `/acp cwd` | 设置运行时工作目录覆盖。 | `/acp cwd /Users/user/Projects/repo` |
| `/acp permissions` | 设置批策略配置文件。 | `/acp permissions strict` |
| `/acp timeout` | 设置运行时超时(秒)。 | `/acp timeout 120` |
| `/acp model` | 设置运行时模型覆盖。 | `/acp model anthropic/claude-opus-4-6` |
| `/acp reset-options` | 移除会话运行时选项覆盖。 | `/acp reset-options` |
| `/acp sessions` | 从存储中列出最近的 ACP 会话。 | `/acp sessions` |
| `/acp doctor` | 后端健康状态、能力和可执行修复建议。 | `/acp doctor` |
| `/acp install` | 输出确定性的安装和启用步骤。 | `/acp install` |
`/acp status` 会显示生效中的运行时选项,以及运行时级别和后端级别的会话标识符。当某个后端缺少能力时,不支持的控制错误会清晰呈现。`/acp sessions` 会读取当前已绑定或请求方会话的存储;目标 token`session-key`、`session-id` 或 `session-label`)会通过 Gateway 网关会话发现机制解析,包括自定义的每智能体 `session.store` 根路径
`/acp status` 会显示生效中的运行时选项,以及运行时级别和后端级别的会话标识符。当后端缺少某项能力时,不支持的控制错误会被清晰显示。`/acp sessions` 会读取当前绑定会话或请求方会话的存储;目标令牌(`session-key`、`session-id` 或 `session-label`)会通过 Gateway 网关会话发现来解析,包括每个智能体自定义的 `session.store` 根目录
## 运行时选项映射
`/acp` 提供便捷命令和通用 setter
`/acp` 提供便捷命令和一个通用设置器
等价操作:
- `/acp model <id>` 映射到运行时配置键 `model`
- `/acp permissions <profile>` 映射到运行时配置键 `approval_policy`
- `/acp timeout <seconds>` 映射到运行时配置键 `timeout`
- `/acp cwd <path>` 直接更新运行时 `cwd` 覆盖。
- `/acp cwd <path>` 直接更新运行时 `cwd` 覆盖
- `/acp set <key> <value>` 是通用路径。
- 特殊情况:`key=cwd` 使用 `cwd` 覆盖路径。
- `/acp reset-options` 会清除目标会话的所有运行时覆盖。
- `/acp reset-options` 会清除目标会话的所有运行时覆盖
## acpx harness、插件设置和权限
有关 acpx harness 配置Claude Code / Codex / Gemini CLI 别名)、
plugin-tools 和 OpenClaw-tools MCP 桥接,以及 ACP 权限模式,请参
有关 acpx harness 配置Claude Code / Codex / Gemini CLI 别名)、
plugin-tools 和 OpenClaw-tools MCP 桥接,以及 ACP 权限模式,请参
[ACP 智能体 — 设置](/zh-CN/tools/acp-agents-setup)。
## 故障排除
| 症状 | 可能原因 | 修复方法 |
| --------------------------------------------------------------------------- | ------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `ACP runtime backend is not configured` | 后端插件缺失或被禁用。 | 安装并启用后端插件,然后运行 `/acp doctor` |
| `ACP is disabled by policy (acp.enabled=false)` | ACP 被全局禁用。 | 设置 `acp.enabled=true` |
| `ACP dispatch is disabled by policy (acp.dispatch.enabled=false)` | 来自普通线程消息的分发已禁用。 | 设置 `acp.dispatch.enabled=true` |
| `ACP agent "<id>" is not allowed by policy` | 智能体不在 allowlist 中。 | 使用允许的 `agentId` 或更新 `acp.allowedAgents` |
| `Unable to resolve session target: ...` | key/id/label token 错误。 | 运行 `/acp sessions`,复制准确的 key/label然后重试。 |
| `--bind here requires running /acp spawn inside an active ... conversation` | 在没有活跃可绑定对话的情况下使用了 `--bind here` | 移动到目标聊天/渠道后重试,或使用未绑定生成。 |
| `Conversation bindings are unavailable for <channel>.` | 适配器缺少当前对话 ACP 绑定能力。 | 在支持时使用 `/acp spawn ... --thread ...`,配置顶层 `bindings[]`,或切换到受支持渠道。 |
| `--thread here requires running /acp spawn inside an active ... thread` | 在线程上下文之外使用了 `--thread here` | 移动到目标线程,或使用 `--thread auto`/`off`。 |
| `Only <user-id> can rebind this channel/conversation/thread.` | 活跃绑定目标归另一位用户所有。 | 由所有者重新绑定,或使用其他对话或线程。 |
| `Thread bindings are unavailable for <channel>.` | 适配器缺少线程绑定能力。 | 使用 `--thread off`,或切换到受支持的适配器/渠道。 |
| `Sandboxed sessions cannot spawn ACP sessions ...` | ACP 运行时位于主机侧;请求方会话处于沙箱中。 | 在沙箱会话中使用 `runtime="subagent"`,或从非沙箱会话中执行 ACP 生成。 |
| `sessions_spawn sandbox="require" is unsupported for runtime="acp" ...` | 为 ACP 运行时请求了 `sandbox="require"` | 对必须启用沙箱的场景使用 `runtime="subagent"`,或者在非沙箱会话中对 ACP 使用 `sandbox="inherit"` |
| 绑定会话缺少 ACP 元数据 | ACP 会话元数据已过时/被删除。 | 使用 `/acp spawn` 重新创建,然后重新绑定/聚焦线程。 |
| `AcpRuntimeError: Permission prompt unavailable in non-interactive mode` | `permissionMode` 在非交互式 ACP 会话中阻止写入/exec。 | 将 `plugins.entries.acpx.config.permissionMode` 设为 `approve-all`,然后重启 Gateway 网关。参见 [ACP 智能体设置](/zh-CN/tools/acp-agents-setup)。 |
| ACP 会话在几乎没有输出的情况下很早失败 | 权限提示被 `permissionMode`/`nonInteractivePermissions` 阻止。 | 检查 Gateway 网关日志中的 `AcpRuntimeError`若需完整权限,设置 `permissionMode=approve-all`;若要优雅降级,设置 `nonInteractivePermissions=deny`。 |
| ACP 会话在完成工作后无限期卡住 | Harness 进程已结束,但 ACP 会话未报告完成。 | 使用 `ps aux \| grep acpx` 监控;手动杀掉陈旧进程。 |
| 症状 | 可能原因 | 修复方法 |
| --------------------------------------------------------------------------- | ------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `ACP runtime backend is not configured` | 后端插件缺失或被禁用。 | 安装并启用后端插件,然后运行 `/acp doctor`。 |
| `ACP is disabled by policy (acp.enabled=false)` | ACP 在全局范围内被禁用。 | 设置 `acp.enabled=true` |
| `ACP dispatch is disabled by policy (acp.dispatch.enabled=false)` | 来自普通线程消息的分发被禁用。 | 设置 `acp.dispatch.enabled=true` |
| `ACP agent "<id>" is not allowed by policy` | 智能体不在允许列表中。 | 使用被允许的 `agentId`,或更新 `acp.allowedAgents` |
| `Unable to resolve session target: ...` | 错误的键/id/标签令牌。 | 运行 `/acp sessions`,复制准确的键/标签,然后重试。 |
| `--bind here requires running /acp spawn inside an active ... conversation` | 在没有活动可绑定会话的情况下使用了 `--bind here`。 | 移动到目标聊天/渠道后重试,或使用无绑定启动。 |
| `Conversation bindings are unavailable for <channel>.` | 适配器缺少当前会话 ACP 绑定能力。 | 在支持时使用 `/acp spawn ... --thread ...`,配置顶层 `bindings[]`,或切换到受支持渠道。 |
| `--thread here requires running /acp spawn inside an active ... thread` | 在线程上下文之外使用了 `--thread here`。 | 移动到目标线程,或使用 `--thread auto`/`off`。 |
| `Only <user-id> can rebind this channel/conversation/thread.` | 另一个用户拥有当前活动绑定目标。 | 由拥有者重新绑定,或使用其他会话或线程。 |
| `Thread bindings are unavailable for <channel>.` | 适配器缺少线程绑定能力。 | 使用 `--thread off`,或切换到受支持的适配器/渠道。 |
| `Sandboxed sessions cannot spawn ACP sessions ...` | ACP 运行时位于主机侧;请求方会话处于沙箱隔离状态。 | 在沙箱隔离会话中使用 `runtime="subagent"`,或从非沙箱隔离会话中启动 ACP。 |
| `sessions_spawn sandbox="require" is unsupported for runtime="acp" ...` | 为 ACP 运行时请求了 `sandbox="require"`| 对需要沙箱隔离的情况使用 `runtime="subagent"`,或在非沙箱隔离会话中将 ACP 与 `sandbox="inherit"` 搭配使用。 |
| 绑定会话缺少 ACP 元数据 | ACP 会话元数据已过期/被删除。 | 使用 `/acp spawn` 重新创建,然后重新绑定/聚焦线程。 |
| `AcpRuntimeError: Permission prompt unavailable in non-interactive mode` | `permissionMode` 在非交互式 ACP 会话中阻止写入/执行。 | 将 `plugins.entries.acpx.config.permissionMode` 设为 `approve-all` 并重启 Gateway 网关。参见[权限配置](/zh-CN/tools/acp-agents-setup#permission-configuration)。 |
| ACP 会话过早失败且输出很少 | 权限提示被 `permissionMode`/`nonInteractivePermissions` 阻止。 | 检查 Gateway 网关日志中的 `AcpRuntimeError`如需完全权限,设置 `permissionMode=approve-all`;如需优雅降级,设置 `nonInteractivePermissions=deny`。 |
| ACP 会话在完成工作后无限期卡住 | harness 进程已结束,但 ACP 会话未报告完成。 | 使用 `ps aux \| grep acpx` 进行监控;手动终止陈旧进程。 |
## 相关内容