chore(i18n): refresh zh-CN translations

This commit is contained in:
openclaw-docs-i18n[bot] 2026-04-27 03:50:22 +00:00
parent add3490548
commit bd16dac3b8
4 changed files with 737 additions and 709 deletions

View File

@ -1,26 +1,26 @@
---
read_when:
- 在 OpenClaw 中设置 Matrix
- 配置 Matrix 端到端加密和验证
- 配置 Matrix E2EE 和验证
summary: Matrix 支持状态、设置和配置示例
title: Matrix
x-i18n:
generated_at: "2026-04-26T01:24:04Z"
generated_at: "2026-04-27T03:46:56Z"
model: gpt-5.4
provider: openai
source_hash: 1850d51aba7279a3d495c346809b4df26d7da4b7611c5a8c9ab70f9a2b3c827d
source_hash: 3f69a671e5151224a4050f9b1d28924b8450cf1a54dec1a7ea42ad1ed728060a
source_path: channels/matrix.md
workflow: 15
---
Matrix 是 OpenClaw 的内置渠道插件。
它使用官方 `matrix-js-sdk`,并支持私信、房间、线程、媒体、回应、投票、位置和端到端加密
它使用官方 `matrix-js-sdk`,并支持私信、房间、线程、媒体、回应、投票、位置和 E2EE
## 内置插件
Matrix 作为内置插件随当前 OpenClaw 版本一起发布,因此普通打包构建无需单独安装。
Matrix 作为当前 OpenClaw 版本中的内置插件随附,因此普通的打包构建不需要单独安装。
如果你使用的是较旧版本,或是不包含 Matrix 的自定义安装,请手动安装:
如果你使用的是较旧的构建版本,或者是排除了 Matrix 的自定义安装,请手动安装:
从 npm 安装:
@ -40,14 +40,14 @@ openclaw plugins install ./path/to/local/matrix-plugin
1. 确保 Matrix 插件可用。
- 当前打包的 OpenClaw 版本已内置该插件。
- 较旧版本/自定义安装可使用上述命令手动添加。
2. 在你的 homeserver 上创建一个 Matrix 账
- 较旧/自定义安装可使用上述命令手动添加
2. 在你的 homeserver 上创建一个 Matrix 账
3. 使用以下任一方式配置 `channels.matrix`
- `homeserver` + `accessToken`,或
- `homeserver` + `userId` + `password`
4. 重启 Gateway 网关。
5. 与机器人发起私信,或邀请它加入房间。
- 只有 `channels.matrix.autoJoin` 允许时,新的 Matrix 邀请才会生效。
5. 与机器人开始私信,或邀请它加入房间。
- 只有 `channels.matrix.autoJoin` 允许时,新的 Matrix 邀请才会生效。
交互式设置路径:
@ -59,32 +59,33 @@ openclaw configure --section channels
Matrix 向导会询问:
- homeserver URL
- 认证方式access token 或密码
- 认证方式access token 或 password
- 用户 ID仅密码认证
- 可选设备名称
- 是否启用端到端加密
- 可选设备名称
- 是否启用 E2EE
- 是否配置房间访问和邀请自动加入
向导的关键行为:
- 如果 Matrix 认证环境变量已存在,并且该账户尚未在配置中保存认证信息,向导会提供一个环境变量快捷方式,以便将认证信息保留在环境变量中。
- 账户名称会规范化为账户 ID。例如`Ops Bot` 会变成 `ops-bot`
- 私信 allowlist 条目可直接接受 `@user:server`;显示名称仅在实时目录查找找到一个精确匹配时才有效
- 房间 allowlist 条目可直接接受房间 ID 和别名。优先使用 `!room:server``#alias:server`;无法解析的名称会在运行时被 allowlist 解析忽略。
- 在邀请自动加入 allowlist 模式中,只能使用稳定的邀请目标:`!roomId:server`、`#alias:server` 或 `*`。纯房间名称会被拒绝。
- 如果 Matrix 认证环境变量已存在,并且该账号尚未在配置中保存认证信息,则向导会提供一个环境变量快捷方式,将认证信息保留在环境变量中。
- 账号名称会规范化为账号 ID。例如`Ops Bot` 会变成 `ops-bot`
- 私信允许列表条目可直接接受 `@user:server`;显示名称仅在实时目录查找找到一个精确匹配项时才可用
- 房间允许列表条目可直接接受房间 ID 和别名。优先使用 `!room:server``#alias:server`;无法解析的名称会在运行时的允许列表解析中被忽略。
- 在邀请自动加入允许列表模式下,仅使用稳定的邀请目标:`!roomId:server`、`#alias:server` 或 `*`。纯房间名称会被拒绝。
- 若要在保存前解析房间名称,请使用 `openclaw channels resolve --channel matrix "Project Room"`
- 当设置启用 E2EE 时OpenClaw 会写入加密配置,并运行与 `openclaw matrix encryption setup` 相同的验证引导流程。
<Warning>
`channels.matrix.autoJoin` 默认为 `off`
如果你不设置它,机器人将不会加入被邀请的房间或新的私信式邀请,因此除非你先手动加入,否则它不会出现在新群组或被邀请的私信中。
如果你不设置它,机器人将不会加入受邀房间或新的私信式邀请,因此除非你先手动加入,否则它不会出现在新群组或受邀私信中。
如果你想限制它接受哪些邀请,请设置 `autoJoin: "allowlist"` 并同时配置 `autoJoinAllowlist`;如果你希望它加入每一个邀请,请设置 `autoJoin: "always"`
设置 `autoJoin: "allowlist"` 并同时配置 `autoJoinAllowlist`,可以限制它接受哪些邀请;或者设置 `autoJoin: "always"`,让它加入每一个邀请
`allowlist` 模式下,`autoJoinAllowlist` 仅接受 `!roomId:server`、`#alias:server` 或 `*`
</Warning>
Allowlist 示例:
允许列表示例:
```json5
{
@ -114,7 +115,7 @@ Allowlist 示例:
}
```
最小化的基于 token 的设置:
基于 token 的最小设置:
```json5
{
@ -146,8 +147,8 @@ Allowlist 示例:
```
Matrix 会将缓存的凭证存储在 `~/.openclaw/credentials/matrix/` 中。
默认账户使用 `credentials.json`;命名账户使用 `credentials-<account>.json`
该位置存在缓存凭证时即使当前认证未直接在配置中设置OpenClaw 也会在设置、Doctor 和渠道状态发现中将 Matrix 视为已配置。
默认账号使用 `credentials.json`;命名账号使用 `credentials-<account>.json`
这些位置存在缓存凭证时即使当前认证信息未直接在配置中设置OpenClaw 仍会在设置、Doctor 和渠道状态发现中将 Matrix 视为已配置。
对应的环境变量(当未设置配置键时使用):
@ -158,7 +159,7 @@ Matrix 会将缓存的凭证存储在 `~/.openclaw/credentials/matrix/` 中。
- `MATRIX_DEVICE_ID`
- `MATRIX_DEVICE_NAME`
对于非默认账户,请使用账户范围环境变量:
对于非默认账号,请使用带账号作用域的环境变量:
- `MATRIX_<ACCOUNT_ID>_HOMESERVER`
- `MATRIX_<ACCOUNT_ID>_ACCESS_TOKEN`
@ -167,26 +168,26 @@ Matrix 会将缓存的凭证存储在 `~/.openclaw/credentials/matrix/` 中。
- `MATRIX_<ACCOUNT_ID>_DEVICE_ID`
- `MATRIX_<ACCOUNT_ID>_DEVICE_NAME`
`ops` 的示例:
`ops` 的示例:
- `MATRIX_OPS_HOMESERVER`
- `MATRIX_OPS_ACCESS_TOKEN`
对于规范化账户 ID `ops-bot`,请使用:
对于规范化后的账号 ID `ops-bot`,请使用:
- `MATRIX_OPS_X2D_BOT_HOMESERVER`
- `MATRIX_OPS_X2D_BOT_ACCESS_TOKEN`
Matrix 会转义账户 ID 中的标点,以避免带作用域的环境变量发生冲突。
例如,`-` 会变成 `_X2D_`,因此 `ops-prod` 会映射 `MATRIX_OPS_X2D_PROD_*`
Matrix 会对账号 ID 中的标点符号进行转义,以避免带作用域的环境变量发生冲突。
例如,`-` 会变成 `_X2D_`,因此 `ops-prod` 会映射 `MATRIX_OPS_X2D_PROD_*`
只有当这些认证环境变量已经存在,且所选账户尚未在配置中保存 Matrix 认证信息时,交互式向导才会提供环境变量快捷方式。
只有当这些认证环境变量已存在,且所选账号尚未在配置中保存 Matrix 认证信息时,交互式向导才会提供环境变量快捷方式。
`MATRIX_HOMESERVER` 不能通过工作区 `.env` 设置;请参阅 [Workspace `.env` files](/zh-CN/gateway/security)。
## 配置示例
这是一个实用的基础配置,启用了私信配对、房间 allowlist 和端到端加密
这是一个启用了私信配对、房间允许列表和 E2EE 的实用基线配置
```json5
{
@ -221,13 +222,13 @@ Matrix 会转义账户 ID 中的标点,以避免带作用域的环境变量发
}
```
`autoJoin` 适用于所有 Matrix 邀请包括私信式邀请。OpenClaw 无法在邀请时可靠地区分被邀请房间是私信还是群组,因此所有邀请都会先经过 `autoJoin`。`dm.policy` 会在机器人加入之后、且房间被分类为私信后才生效。
`autoJoin` 适用于所有 Matrix 邀请包括私信式邀请。OpenClaw 无法在邀请发生时可靠地将受邀房间分类为私信还是群组,因此所有邀请都会先经过 `autoJoin`。`dm.policy` 会在机器人加入之后、并且该房间被分类为私信后再生效。
## 流式预览
Matrix 回复流式传输需要主动启用。
Matrix 回复流式传输为可选启用。
当你希望 OpenClaw 发送一条单独的实时预览回复、在模型生成文本时原地编辑该预览,并在回复完成后将其定稿时,请将 `channels.matrix.streaming` 设置为 `"partial"`
当你希望 OpenClaw 发送一条实时预览回复、在模型生成文本期间原地编辑该预览,并在回复完成后将其定稿时,请将 `channels.matrix.streaming` 设置为 `"partial"`
```json5
{
@ -239,32 +240,32 @@ Matrix 回复流式传输需要主动启用。
}
```
- `streaming: "off"` 是默认值。OpenClaw 会等待最终回复,然后发送一次
- `streaming: "partial"` 会为当前助手块创建一条可编辑的预览消息,使用普通 Matrix 文本消息。这会保留 Matrix 传统的“预览优先”通知行为,因此标准客户端可能会在第一段流式预览文本到达时通知,而不是在最终块完成时通知。
- `streaming: "quiet"` 会为当前助手块创建一条可编辑的静默预览通知。仅当你同时为最终定稿的预览编辑配置了接收者推送规则时才应使用它
- `blockStreaming: true` 会启用独的 Matrix 进度消息。启用预览流式传输Matrix 会保留当前块的实时草稿,并将已完成的块保留为独立消息。
- 当预览流式传输开启且 `blockStreaming` 关闭时Matrix 会原地编辑实时草稿,并在块或轮次结束时定稿同一个事件。
- 如果预览内容已无法容纳在单个 Matrix 事件中OpenClaw 会停止预览流式传输,并回退到普通的最终发送
- 媒体回复仍会正常发送附件。如果陈旧预览已无法安全复用OpenClaw 会在发送最终媒体回复前将其清除
- 预览编辑会产生额外的 Matrix API 调用。如果你希望采用最保守的速率限制行为,请保持关闭流式传输。
- `streaming: "off"` 是默认值。OpenClaw 会等待最终回复,然后一次性发送。
- `streaming: "partial"` 会为当前智能体块创建一条可编辑的预览消息,使用普通 Matrix 文本消息。这会保留 Matrix 旧式的“预览优先”通知行为,因此标准客户端可能会在首次流式预览文本时发送通知,而不是在完成的内容块上发送通知。
- `streaming: "quiet"` 会为当前智能体块创建一条可编辑的静默预览通知。只有当你同时为最终定稿的预览编辑配置了接收者推送规则时,才应使用此选项
- `blockStreaming: true` 会启用独的 Matrix 进度消息。启用预览流式传输Matrix 会为当前块保留实时草稿,并将已完成的块保留为单独消息。
- 当预览流式传输开启且 `blockStreaming` 关闭时Matrix 会原地编辑实时草稿,并在块或轮次完成时定稿该同一事件。
- 如果预览内容已无法容纳在单个 Matrix 事件中OpenClaw 会停止预览流式传输,并回退到普通最终投递
- 媒体回复仍会正常发送附件。如果过期的预览已无法安全复用OpenClaw 会在发送最终媒体回复之前将其隐藏
- 预览编辑会增加额外的 Matrix API 调用。如果你希望使用最保守的限流行为,请保持关闭流式传输。
`blockStreaming` 本身不会启用草稿预览。
如需预览编辑,请使用 `streaming: "partial"``streaming: "quiet"`;只有当你还希望已完成的助手块作为独立进度消息保留可见时,才再添加 `blockStreaming: true`
使用 `streaming: "partial"``streaming: "quiet"` 来启用预览编辑;只有在你还希望已完成的智能体块以单独进度消息形式保留可见时,再额外设置 `blockStreaming: true`
如果你需要标准 Matrix 通知而不使用自定义推送规则,请使用 `streaming: "partial"` 获得“预览优先”行为,或保持 `streaming` 关闭以仅发送最终结果。使用 `streaming: "off"` 时:
如果你需要标准 Matrix 通知而不想配置自定义推送规则,请使用 `streaming: "partial"` 获得“预览优先”行为,或保持 `streaming` 关闭以仅进行最终投递。使用 `streaming: "off"` 时:
- `blockStreaming: true` 会将每个已完成块作为普通可通知的 Matrix 消息发送。
- `blockStreaming: false` 只会将最终完成的回复作为普通可通知的 Matrix 消息发送。
### 自托管静默定稿预览的推送规则
### 用于静默定稿预览的自托管推送规则
静默流式传输(`streaming: "quiet"`只有在一个块或轮次定稿后才会通知接收者——每个用户都必须有一条推送规则来匹配定稿预览标记。完整设置(接收者 token、pusher 检查、规则安装、各 homeserver 注意事项)请参阅 [Matrix push rules for quiet previews](/zh-CN/channels/matrix-push-rules)。
静默流式传输(`streaming: "quiet"`仅在某个块或轮次定稿后通知接收者——需要一条按用户生效的推送规则来匹配定稿后的预览标记。完整设置(接收者 token、pusher 检查、规则安装、按 homeserver 的说明)请参阅 [Matrix push rules for quiet previews](/zh-CN/channels/matrix-push-rules)。
## 机器人对机器人房间
## Bot-to-bot 房间
默认情况下,来自其他已配置 OpenClaw Matrix 账的 Matrix 消息会被忽略。
默认情况下,来自其他已配置 OpenClaw Matrix 账的 Matrix 消息会被忽略。
如果你有意启用智能体之间的 Matrix 通信,请使用 `allowBots`
当你明确希望启用智能体之间的 Matrix 通信时,请使用 `allowBots`
```json5
{
@ -281,19 +282,42 @@ Matrix 回复流式传输需要主动启用。
}
```
- `allowBots: true` 会在允许的房间和私信中接受来自其他已配置 Matrix 机器人账的消息。
- `allowBots: "mentions"`当这些消息在房间中明确提及此机器人时才接受。私信仍然允许。
- `groups.<room>.allowBots` 会覆盖某个房间的账户级设置。
- OpenClaw 仍会忽略来自同 Matrix 用户 ID 的消息,以避免自回复循环。
- Matrix 在这里不会暴露原生机器人标记OpenClaw 将“由机器人发送”视为“由此 OpenClaw Gateway 网关上另一已配置的 Matrix 账户发送”。
- `allowBots: true` 会在允许的房间和私信中接受来自其他已配置 Matrix 机器人账的消息。
- `allowBots: "mentions"`在这些消息在房间中明确提到此机器人时才接受。私信仍然允许。
- `groups.<room>.allowBots` 会覆盖单个房间的账号级设置。
- OpenClaw 仍会忽略来自同 Matrix 用户 ID 的消息,以避免自回复循环。
- Matrix 在这里不提供原生的机器人标记OpenClaw 将“由机器人发送”视为“由此 OpenClaw Gateway 网关上的另一个已配置 Matrix 账号发送”。
在共享房间中启用机器人对机器人通信时,请使用严格的房间 allowlist 和提及要求。
在共享房间中启用 bot-to-bot 流量时,请使用严格的房间允许列表和提及要求。
## 加密验证
## 加密验证
在加密的(端到端加密)房间中,出站图片事件使用 `thumbnail_file`,因此图片预览会与完整附件一起加密。未加密房间仍使用普通的 `thumbnail_url`。无需任何配置——插件会自动检测端到端加密状态。
在加密E2EE房间中出站图片事件会使用 `thumbnail_file`,因此图片预览会与完整附件一起加密。未加密房间仍使用普通的 `thumbnail_url`。无需任何配置——该插件会自动检测 E2EE 状态。
启用加密:
推荐的设置流程:
```bash
openclaw matrix encryption setup
```
这会启用 `channels.matrix.encryption`,引导 Matrix secret storage 和 cross-signing在需要时创建房间密钥备份状态然后输出当前验证和备份状态以及后续步骤。
对于新账号,请在创建账号时启用 E2EE
```bash
openclaw matrix account add \
--homeserver https://matrix.example.org \
--access-token syt_xxx \
--enable-e2ee
```
多账号设置可以针对特定账号:
```bash
openclaw matrix encryption setup --account assistant
```
等效的手动配置:
```json5
{
@ -309,7 +333,7 @@ Matrix 回复流式传输需要主动启用。
}
```
验证命令(全部支持 `--verbose` 用于诊断,支持 `--json` 输出机器可读结果
验证命令(全部支持 `--verbose` 用于诊断,支持 `--json` 用于机器可读输出
```bash
openclaw matrix verify status
@ -321,25 +345,25 @@ openclaw matrix verify status
openclaw matrix verify status --verbose
```
在机器可读输出中包含存储的恢复密钥:
在机器可读输出中包含存储的恢复密钥:
```bash
openclaw matrix verify status --include-recovery-key --json
```
引导跨签名和验证状态:
引导 cross-signing 和验证状态:
```bash
openclaw matrix verify bootstrap
```
详细引导诊断:
详细引导诊断:
```bash
openclaw matrix verify bootstrap --verbose
```
在引导前强制重置跨签名身份
在引导前强制执行全新的 cross-signing 身份重置:
```bash
openclaw matrix verify bootstrap --force-reset-cross-signing
@ -353,24 +377,23 @@ openclaw matrix verify device "<your-recovery-key>"
此命令会报告三个独立状态:
- `Recovery key accepted`Matrix 已接受该恢复密钥,用于秘密存储或设备信任。
- `Recovery key accepted`Matrix 已接受该恢复密钥,用于 secret storage 或设备信任。
- `Backup usable`:可使用受信任的恢复材料加载房间密钥备份。
- `Device verified by owner`:当前 OpenClaw 设备已获得完整的 Matrix 跨签名身份信任。
- `Device verified by owner`:当前 OpenClaw 设备已获得完整的 Matrix cross-signing 身份信任。
详细输出或 JSON 输出中的 `Signed by owner` 仅用于诊断。除非 `Cross-signing verified` 同时为 `yes`,否则 OpenClaw 不会将其视为充分条件
详细输出或 JSON 输出中的 `Signed by owner` 仅用于诊断。除非 `Cross-signing verified` 也为 `yes`,否则 OpenClaw 不会将其视为足够
即使恢复密钥可以解锁备份材料,只要完整的 Matrix 身份信任尚未完成,该命令仍会以非零状态退出。
在这种情况下,请从另一个 Matrix 客户端完成自验证:
即使恢复密钥可以解锁备份材料,只要完整的 Matrix 身份信任尚未完成,此命令仍会以非零状态退出。在这种情况下,请从另一个 Matrix 客户端完成自验证:
```bash
openclaw matrix verify self
```
在另一个 Matrix 客户端中接受请求,比较 SAS 表情符号或十进制数字,并且仅在它们匹配时输入 `yes`。该命令会等待 Matrix 报告 `Cross-signing verified: yes` 后才成功退出。
在另一个 Matrix 客户端中接受请求,比较 SAS 表情符号或数字,并且仅在它们匹配时输入 `yes`。该命令会等待 Matrix 报告 `Cross-signing verified: yes`,然后才会成功退出。
仅当你有意替换当前跨签名身份时,才使用 `verify bootstrap --force-reset-cross-signing`
仅当你明确想要替换当前 cross-signing 身份时,才使用 `verify bootstrap --force-reset-cross-signing`
详细设备验证信息:
详细设备验证信息:
```bash
openclaw matrix verify device "<your-recovery-key>" --verbose
@ -382,7 +405,7 @@ openclaw matrix verify device "<your-recovery-key>" --verbose
openclaw matrix verify backup status
```
详细备份健康状态诊断:
详细备份健康诊断:
```bash
openclaw matrix verify backup status --verbose
@ -406,7 +429,7 @@ openclaw matrix verify backup restore --recovery-key "<your-recovery-key>"
openclaw matrix verify self
```
如需更底层的操作或处理入站验证请求,请使用:
对于更底层或入站验证请求,请使用:
```bash
openclaw matrix verify accept <id>
@ -417,24 +440,24 @@ openclaw matrix verify confirm-sas <id>
使用 `openclaw matrix verify cancel <id>` 可取消请求。
详细恢复诊断:
详细恢复诊断:
```bash
openclaw matrix verify backup restore --verbose
```
删除当前服务器备份并创建新的备份基线。如果存储的备份密钥无法被干净地加载,此重置还可以重新创建秘密存储,以便未来冷启动时可以加载新的备份密钥:
删除当前服务器备份并创建一个全新的备份基线。如果存储的备份密钥无法被干净地加载,此重置也可以重新创建 secret storage以便未来冷启动时能够加载新的备份密钥:
```bash
openclaw matrix verify backup reset --yes
```
所有 `verify` 命令默认都简洁(包括安静的内部 SDK 日志),只有在使用 `--verbose` 时才显示详细诊断。
编写脚本时请使用 `--json` 以获得完整的机器可读输出。
所有 `verify` 命令默认都保持简洁(包括安静的内部 SDK 日志),只有在使用 `--verbose` 时才显示详细诊断信息
在编写脚本时,请使用 `--json` 获取完整的机器可读输出。
在多账户设置中,除非你传入 `--account <id>`,否则 Matrix CLI 命令会使用隐式的 Matrix 默认账户
如果你配置了多个命名账,请先设置 `channels.matrix.defaultAccount`,否则这些隐式 CLI 操作会停止并要求你明确选择一个账户
当你希望验证或设备操作明确针对某个命名账时,请使用 `--account`
在多账号设置中Matrix CLI 命令会使用隐式的 Matrix 默认账号,除非你传入 `--account <id>`
如果你配置了多个命名账,请先设置 `channels.matrix.defaultAccount`,否则这些隐式 CLI 操作会停止并要求你显式选择一个账号
当你希望验证或设备操作明确针对某个命名账时,请使用 `--account`
```bash
openclaw matrix verify status --account assistant
@ -442,35 +465,35 @@ openclaw matrix verify backup restore --account assistant
openclaw matrix devices list --account assistant
```
当某个命名账户禁用了加密或该账户不可用加密时Matrix 警告和验证错误会指向该账户的配置键,例如 `channels.matrix.accounts.assistant.encryption`
当某个命名账号的加密被禁用或不可用时Matrix 警告和验证错误会指向该账号的配置键,例如 `channels.matrix.accounts.assistant.encryption`
<AccordionGroup>
<Accordion title="已验证的含义">
只有当你自己的跨签名身份对某个设备进行了签名时OpenClaw 才会将该设备视为已验证。`verify status --verbose` 会暴露三个信任信号:
只有当你自己的 cross-signing 身份对设备进行了签名时OpenClaw 才会将设备视为已验证。`verify status --verbose` 会显示三种信任信号:
- `Locally trusted`:仅被此客户端信任
- `Cross-signing verified`SDK 报告已通过跨签名验证
- `Signed by owner`:已由你自己的自签名密钥签名
- `Locally trusted`:仅被此客户端本地信任
- `Cross-signing verified`SDK 报告已通过 cross-signing 完成验证
- `Signed by owner`:已由你自己的 self-signing 密钥签名
只有在存在跨签名验证时,`Verified by owner` 才会变为 `yes`
仅有本地信任或仅有所有者签名,都不足以让 OpenClaw 将该设备视为已完全验证。
只有在存在 cross-signing 验证时,`Verified by owner` 才会变为 `yes`
仅有本地信任或 owner 签名本身,并不足以让 OpenClaw 将该设备视为完全已验证。
</Accordion>
<Accordion title="bootstrap 的作用">
`verify bootstrap` 是加密账户的修复与设置命令。按顺序,它会
`verify bootstrap` 是加密账号的修复与设置命令。它会按以下顺序执行
- 引导秘密存储,并在可能时复用现有恢复密钥
- 引导跨签名并上传缺失的公开跨签名密钥
- 标记并跨签名当前设备
- 如果服务器端房间密钥备份尚不存在,则创建一个
- 引导 secret storage,并在可能时复用现有恢复密钥
- 引导 cross-signing 并上传缺失的公开 cross-signing 密钥
- 标记并 cross-sign 当前设备
- 如果服务器端尚不存在房间密钥备份,则创建一个
如果 homeserver 需要 UIA 才能上传跨签名密钥OpenClaw 会先尝试无认证,然后尝试 `m.login.dummy`,最后尝试 `m.login.password`(需要 `channels.matrix.password`)。仅在有意丢弃当前身份时才使用 `--force-reset-cross-signing`
如果 homeserver 需要 UIA 才能上传 cross-signing 密钥OpenClaw 会先尝试无认证方式,然后尝试 `m.login.dummy`,最后尝试 `m.login.password`(需要 `channels.matrix.password`)。只有在你明确要丢弃当前身份时,才使用 `--force-reset-cross-signing`
</Accordion>
<Accordion title="新的备份基线">
如果你希望未来的加密消息继续可用,并接受丢失无法恢复的旧历史记录:
<Accordion title="新的备份基线">
如果你想让未来的加密消息继续可用,并接受丢失无法恢复的旧历史记录:
```bash
openclaw matrix verify backup reset --yes
@ -478,31 +501,31 @@ openclaw matrix verify backup status --verbose
openclaw matrix verify status
```
添加 `--account <id>` 可针对某个命名账户。这也可以在当前备份密钥无法安全加载时重新创建秘密存储
仅当你有意让旧恢复密钥不再能够解锁新的备份基线时,才添加 `--rotate-recovery-key`
添加 `--account <id>` 可针对某个命名账号。这也可以在当前备份密钥无法安全加载时重新创建 secret storage
仅当你明确希望旧恢复密钥不再能解锁新的备份基线时,才添加 `--rotate-recovery-key`
</Accordion>
<Accordion title="启动行为">
`encryption: true` 时,`startupVerification` 默认为 `"if-unverified"`。启动时,未验证设备会在另一个 Matrix 客户端中请求自验证,同时跳过重复请求并应用冷却时间。可通过 `startupVerificationCooldownHours` 调整,或通过 `startupVerification: "off"` 禁用。
启动时还会运行一次保守的加密 bootstrap 检查,复用当前的秘密存储和跨签名身份。如果 bootstrap 状态损坏,即使没有 `channels.matrix.password`OpenClaw 也会尝试受保护的修复;如果 homeserver 需要密码 UIA启动时会记录警告,但不会导致致命错误。已由所有者签名的设备会被保留。
启动时还会执行一次保守的加密 bootstrap 过程,复用当前的 secret storage 和 cross-signing 身份。如果 bootstrap 状态损坏,即使没有 `channels.matrix.password`OpenClaw 也会尝试进行受保护的修复;如果 homeserver 需要密码 UIA启动时会记录警告且不会视为致命错误。已由 owner 签名的设备会被保留。
完整升级流程请参阅 [Matrix migration](/zh-CN/install/migrating-matrix)。
</Accordion>
<Accordion title="验证通知">
Matrix 会将验证生命周期通知作为 `m.notice` 消息发布到严格的私信验证房间中:请求、就绪(附带“通过表情符号验证”指引)、开始/完成,以及在可用时显示 SAS表情符号/十进制)详情。
Matrix 会将验证生命周期通知作为 `m.notice` 消息发布到严格的私信验证房间中:请求、就绪(附带“通过表情符号验证”的说明)、开始/完成,以及在可用时附带 SAS表情符号/数字)详情。
来自另一个 Matrix 客户端的入站请求会被跟踪并自动接受。对于自验证OpenClaw 会自动启动 SAS 流程,并在表情符号验证可用后自动确认自身这一侧——你仍然需要在你的 Matrix 客户端中进行比较并确认“它们匹配”。
来自另一个 Matrix 客户端的入站请求会被跟踪并自动接受。对于自验证OpenClaw 会在表情符号验证可用后自动启动 SAS 流程并确认自身这一侧——但你仍然需要在你的 Matrix 客户端中比较并确认 “They match”。
验证系统通知不会转发到智能体聊天管道
验证系统通知不会被转发到智能体聊天流水线
</Accordion>
<Accordion title="已删除或无效的 Matrix 设备">
如果 `verify status` 示当前设备已不再列在 homeserver 上,请创建一个新的 OpenClaw Matrix 设备。对于密码登录:
如果 `verify status` 示当前设备已不再列在 homeserver 上,请创建一个新的 OpenClaw Matrix 设备。对于密码登录:
```bash
openclaw matrix account add \
@ -513,7 +536,7 @@ openclaw matrix account add \
--device-name OpenClaw-Gateway
```
对于 token 认证,请在你的 Matrix 客户端或管理界面中创建一个新的 access token然后更新 OpenClaw
对于 token 认证,请在你的 Matrix 客户端或管理 UI 中创建一个新的 access token然后更新 OpenClaw
```bash
openclaw matrix account add \
@ -522,12 +545,12 @@ openclaw matrix account add \
--access-token '<token>'
```
`assistant` 替换为失败命令中的账户 ID或省略 `--account` 以使用默认账户
`assistant` 替换为失败命令中的账号 ID或者对默认账号省略 `--account`
</Accordion>
<Accordion title="设备清理">
由 OpenClaw 管理的旧设备可能会不断累。可列出并清理:
由 OpenClaw 管理的旧设备可能会不断累。可列出并清理:
```bash
openclaw matrix devices list
@ -537,65 +560,65 @@ openclaw matrix devices prune-stale
</Accordion>
<Accordion title="加密存储">
Matrix 端到端加密使用官方 `matrix-js-sdk` Rust 加密路径,并使用 `fake-indexeddb` 作为 IndexedDB shim。加密状态会持久化到 `crypto-idb-snapshot.json`(文件权限较严格)。
Matrix E2EE 使用官方 `matrix-js-sdk` Rust 加密路径,并以 `fake-indexeddb` 作为 IndexedDB shim。加密状态会持久化到 `crypto-idb-snapshot.json`采用严格的文件权限)。
加密运行时状态位于 `~/.openclaw/matrix/accounts/<account>/<homeserver>__<user>/<token-hash>/`其中包括同步存储、加密存储、恢复密钥、IDB 快照、线程绑定和启动验证状态。当 token 变化但账户身份保持不变时OpenClaw 会复用现有的最佳根目录,以便先前状态仍然可见。
加密运行时状态位于 `~/.openclaw/matrix/accounts/<account>/<homeserver>__<user>/<token-hash>/`其中包括同步存储、加密存储、恢复密钥、IDB 快照、线程绑定和启动验证状态。当 token 发生变化但账号身份保持不变时OpenClaw 会复用现有的最佳根目录,以便先前状态仍然可见。
</Accordion>
</AccordionGroup>
## 配置文件管理
## 个人资料管理
使用以下命令更新所选账的 Matrix 自身资料:
使用以下命令更新所选账的 Matrix 自身资料:
```bash
openclaw matrix profile set --name "OpenClaw Assistant"
openclaw matrix profile set --avatar-url https://cdn.example.org/avatar.png
```
当你希望明确针对某个命名 Matrix 账时,请添加 `--account <id>`
当你希望明确针对某个命名 Matrix 账时,请添加 `--account <id>`
Matrix 可直接接受 `mxc://` 头像 URL。当你传入 `http://``https://` 头像 URL 时OpenClaw 会先将其上传到 Matrix然后将解析后的 `mxc://` URL 回写到 `channels.matrix.avatarUrl`(或所选账户覆盖项)中。
Matrix 可直接接受 `mxc://` 头像 URL。当你传入 `http://``https://` 头像 URL 时OpenClaw 会先将其上传到 Matrix然后把解析后的 `mxc://` URL 回写到 `channels.matrix.avatarUrl`(或所选账号的覆盖项)中。
## 线程
Matrix 同时支持自动回复和消息工具发送使用原生 Matrix 线程。
Matrix 同时支持用于自动回复和消息工具发送的原生 Matrix 线程。
- `dm.sessionScope: "per-user"`(默认)会让 Matrix 私信路由保持按发送者范围划分,因此多个私信房间在解析为同一对端时可以共享一个会话。
- `dm.sessionScope: "per-room"` 会将每个 Matrix 私信房间隔离为各自独立的会话键,同时仍使用普通的私信认证和 allowlist 检查。
- 显式 Matrix 会话绑定的优先级仍高于 `dm.sessionScope`,因此已绑定的房间和线程会保留其所选目标会话。
- `dm.sessionScope: "per-user"`(默认)会让 Matrix 私信路由保持发送者作用域,因此多个私信房间在解析为同一对端时可以共享一个会话。
- `dm.sessionScope: "per-room"` 会将每个 Matrix 私信房间隔离为各自独立的会话键,同时仍使用正常的私信认证和允许列表检查。
- 显式的 Matrix 会话绑定仍然优先于 `dm.sessionScope`,因此已绑定的房间和线程会继续使用其所选目标会话。
- `threadReplies: "off"` 会让回复保持在顶层,并将入站线程消息保留在父会话上。
- `threadReplies: "inbound"` 仅当入站消息本身已经在该线程中时,才在线程内回复。
- `threadReplies: "always"`让房间回复保持在线程中,并以触发消息为线程根,从第一条触发消息开始通过对应的线程范围会话来路由该对话。
- `dm.threadReplies` 仅覆盖私信的顶层设置。例如,你可以让房间线程保持隔离,同时让私信保持平
- 入站线程消息会将线程根消息作为额外智能体上下文包含进来。
- 当目标是同一房间或同一私信用户目标时,消息工具发送会自动继承当前 Matrix 线程,除非显式提供了 `threadId`
- 仅当当前会话元数据能够证明它是同一 Matrix 账户上的同一私信对端时,才会启用同会话私信用户目标复用;否则 OpenClaw 会回退到普通的按用户范围路由。
- 当 OpenClaw 发现某个 Matrix 私信房间与同一共享 Matrix 私信会话上的另一个私信房间发生冲突时,如果启用了线程绑定,并且提供了 `dm.sessionScope` 提示,它会在该房间中发布一次性 `m.notice`,其中包含 `/focus` 逃生口。
- Matrix 支持运行时线程绑定。`/focus`、`/unfocus`、`/agents`、`/session idle`、`/session max-age` 以及线程绑定的 `/acp spawn` 都可在 Matrix 房间和私信中使用。
- 当 `threadBindings.spawnSubagentSessions=true` 时,顶层 Matrix 房间/私信中的 `/focus` 会创建一个新的 Matrix 线程,并将其绑定到目标会话。
- 在现有 Matrix 线程运行 `/focus``/acp spawn --thread here`,则会改为绑定当前线程。
- `threadReplies: "inbound"` 仅当入站消息本来就在该线程中时,才在线程内回复。
- `threadReplies: "always"`将房间回复保留在线程中,并以触发消息为根,同时从第一条触发消息开始,通过匹配的线程作用域会话来路由该会话。
- `dm.threadReplies` 仅覆盖私信的顶层设置。例如,你可以让房间线程保持隔离,同时让私信保持平。
- 入站线程消息会将线程根消息作为额外智能体上下文包含进来。
- 消息工具发送会在目标为同一房间或同一私信用户目标时自动继承当前 Matrix 线程,除非明确提供了 `threadId`
- 同一会话的私信用户目标复用,仅当当前会话元数据能够证明是同一 Matrix 账号上的同一私信对端时才会生效;否则 OpenClaw 会回退到正常的用户作用域路由。
- 当 OpenClaw 发现某个 Matrix 私信房间与同一共享 Matrix 私信会话上的另一个私信房间发生冲突时,如果启用了线程绑定并设置了 `dm.sessionScope` 提示,它会在该房间中发布一次性 `m.notice`,提示可使用 `/focus` 作为逃生口。
- Matrix 支持运行时线程绑定。`/focus`、`/unfocus`、`/agents`、`/session idle`、`/session max-age` 线程绑定的 `/acp spawn` 都可在 Matrix 房间和私信中使用。
- 当 `threadBindings.spawnSubagentSessions=true` 时,在顶层 Matrix 房间/私信中执行 `/focus` 会创建一个新的 Matrix 线程,并将其绑定到目标会话。
- 在现有 Matrix 线程运行 `/focus``/acp spawn --thread here`,则会改为绑定当前线程。
## ACP 会话绑定
Matrix 房间、私信和现有 Matrix 线程都可以变为持久 ACP 工作区,而无需更改聊天界面。
Matrix 房间、私信和现有 Matrix 线程都可以转换为持久化 ACP 工作区,而无需改变聊天界面。
快速操作流程:
快速操作流程:
- 在你希望继续使用的 Matrix 私信、房间或现有线程中运行 `/acp spawn codex --bind here`
- 在顶层 Matrix 私信或房间中,当前私信/房间会保持为聊天界面,后续消息会路由到新建的 ACP 会话。
- 在现有 Matrix 线程中,`--bind here` 会将当前线程原地绑定。
- 在你继续使用的 Matrix 私信、房间或现有线程中运行 `/acp spawn codex --bind here`
- 在顶层 Matrix 私信或房间中,当前私信/房间会保持为聊天界面,后续消息会路由到生成的 ACP 会话。
- 在现有线程中,`--bind here` 会将当前线程原地绑定。
- `/new``/reset` 会原地重置同一个已绑定 ACP 会话。
- `/acp close` 会关闭 ACP 会话并移除绑定。
说明
注意
- `--bind here` 不会创建子 Matrix 线程。
- 只有在 `/acp spawn --thread auto|here` 场景下OpenClaw 需要创建或绑定子 Matrix 线程时,才需要 `threadBindings.spawnAcpSessions`
- `threadBindings.spawnAcpSessions` 仅在 `/acp spawn --thread auto|here` 时需要,因为此时 OpenClaw 需要创建或绑定一个子 Matrix 线程
### 线程绑定配置
Matrix 会继承来自 `session.threadBindings` 的全局默认值,并且也支持按渠道覆盖:
Matrix 会继承来自 `session.threadBindings` 的全局默认值,同时也支持按渠道覆盖:
- `threadBindings.enabled`
- `threadBindings.idleHours`
@ -603,20 +626,20 @@ Matrix 会继承来自 `session.threadBindings` 的全局默认值,并且也
- `threadBindings.spawnSubagentSessions`
- `threadBindings.spawnAcpSessions`
Matrix 线程绑定的 spawn 标志为主动启用:
Matrix 的线程绑定 spawn 标志为可选启用:
- 设置 `threadBindings.spawnSubagentSessions: true`允许顶层 `/focus` 创建并绑定新的 Matrix 线程。
- 设置 `threadBindings.spawnAcpSessions: true`允许 `/acp spawn --thread auto|here` 将 ACP 会话绑定到 Matrix 线程。
- 设置 `threadBindings.spawnSubagentSessions: true`,允许顶层 `/focus` 创建并绑定新的 Matrix 线程。
- 设置 `threadBindings.spawnAcpSessions: true`,允许 `/acp spawn --thread auto|here` 将 ACP 会话绑定到 Matrix 线程。
## 回应
Matrix 支持出站回应操作、入站回应通知以及入站确认回应。
Matrix 支持出站回应操作、入站回应通知入站确认回应。
- 出站回应工具受 `channels["matrix"].actions.reactions` 控制。
- `react` 会向特定 Matrix 事件添加一个回应。
- `reactions` 会列出特定 Matrix 事件当前的回应摘要。
- `emoji=""` 会移除机器人账户自己在该事件上的回应。
- `remove: true` 只会移除机器人账户的指定表情回应。
- `emoji=""` 会移除机器人账号在该事件上的自身回应。
- `remove: true` 仅移除机器人账号对指定表情符号的回应。
确认回应使用标准 OpenClaw 解析顺序:
@ -625,7 +648,7 @@ Matrix 支持出站回应操作、入站回应通知以及入站确认回应。
- `messages.ackReaction`
- 智能体身份 emoji 回退值
确认回应范围按以下顺序解析:
确认回应作用域按以下顺序解析:
- `channels["matrix"].accounts.<accountId>.ackReactionScope`
- `channels["matrix"].ackReactionScope`
@ -645,22 +668,22 @@ Matrix 支持出站回应操作、入站回应通知以及入站确认回应。
## 历史上下文
- `channels.matrix.historyLimit` 控制当 Matrix 房间消息触发智能体时,有多少条最近的房间消息会作为 `InboundHistory` 包含进去。它会回退到 `messages.groupChat.historyLimit`;如果两者都未设置,则有效默认值为 `0`。设置为 `0` 可禁用。
- `channels.matrix.historyLimit` 控制当 Matrix 房间消息触发智能体时,作为 `InboundHistory` 包含多少条最近房间消息。它会回退到 `messages.groupChat.historyLimit`;如果两者都未设置,则实际默认值为 `0`。设置为 `0` 可禁用。
- Matrix 房间历史仅限房间。私信仍使用普通会话历史。
- Matrix 房间历史为“仅待处理”OpenClaw 会缓冲尚未触发回复的房间消息,然后在提及或其他触发到来时对该窗口进行快照。
- 当前触发消息不会包含在 `InboundHistory` 中;它会保留在该轮的主入站正文中。
- 对同一 Matrix 事件的重试会复用原始历史快照,而不是漂移到更新的房间消息上
- Matrix 房间历史为“仅待处理”模式OpenClaw 会缓冲那些尚未触发回复的房间消息,然后在提及或其他触发到来时对该窗口进行快照。
- 当前触发消息不会包含在 `InboundHistory` 中;它会保留在该轮的主入站正文中。
- 对同一 Matrix 事件的重试会复用原始历史快照,而不会漂移到较新的房间消息
## 上下文可见性
Matrix 支持共享的 `contextVisibility` 控制,用于控制补充房间上下文,例如获取到的回复文本、线程根消息和待处理历史。
Matrix 支持共享的 `contextVisibility` 控制,用于补充房间上下文,例如获取到的回复文本、线程根消息和待处理历史。
- `contextVisibility: "all"` 是默认值。补充上下文会按接收时原样保留。
- `contextVisibility: "allowlist"` 会将补充上下文过滤为仅保留通过当前房间/用户 allowlist 检查的发送者内容
- `contextVisibility: "allowlist_quote"` 的行为`allowlist` 相同,但仍会保留一个显式引用回复。
- `contextVisibility: "allowlist"` 会将补充上下文过滤为仅包含通过当前房间/用户允许列表检查的发送者
- `contextVisibility: "allowlist_quote"` 的行为类似 `allowlist`,但仍会保留一条显式引用回复。
此设置影响的是补充上下文的可见性,而不是入站消息本身是否可以触发回复。
触发授权仍然来自 `groupPolicy`、`groups`、`groupAllowFrom` 和私信策略设置。
触发授权仍 `groupPolicy`、`groups`、`groupAllowFrom` 和私信策略设置决定
## 私信和房间策略
@ -685,7 +708,7 @@ Matrix 支持共享的 `contextVisibility` 控制,用于控制补充房间上
}
```
有关提及门控和 allowlist 行为,请参阅 [Groups](/zh-CN/channels/groups)。
有关提及门控和允许列表行为,请参阅 [Groups](/zh-CN/channels/groups)。
Matrix 私信的配对示例:
@ -694,13 +717,13 @@ openclaw pairing list matrix
openclaw pairing approve matrix <CODE>
```
如果某个未批的 Matrix 用户在批前持续向你发送消息OpenClaw 会复用同一个待处理配对码,并且可能会在短暂冷却后再次发送提醒回复,而不是生成新的配对码。
如果某个批的 Matrix 用户在批前持续向你发送消息OpenClaw 会复用同一个待处理配对码,并且可能会在短暂冷却后再次发送提醒回复,而不是生成新的码。
有关共享的私信配对流程和存储布局,请参阅 [Pairing](/zh-CN/channels/pairing)。
## 直接房间修复
如果私信状态不同步OpenClaw 最终可能会保留过期的 `m.direct` 映射,使其指向旧的单聊房间而不是当前活动私信。可使用以下命令检查某个对端的当前映射:
如果私信状态不同步OpenClaw 可能最终会留下陈旧的 `m.direct` 映射,将其指向旧的单聊房间,而不是当前活跃的私信。可使用以下命令检查某个对端当前的映射:
```bash
openclaw matrix direct inspect --user-id @alice:example.org
@ -714,61 +737,60 @@ openclaw matrix direct repair --user-id @alice:example.org
修复流程:
- 优先选择已在 `m.direct`映射的严格 1:1 私信
- 如果没有,则回退到当前已加入、与该用户的任意严格 1:1 私信
- 如果不存在健康的私信,则创建一个新的 direct room 并重写 `m.direct`
- 优先选择已映射`m.direct` 中的严格 1:1 私信
- 如果没有,则回退到当前已加入、与该用户的任意严格 1:1 私信
- 如果不存在健康的私信,则创建一个新的直接房间并重写 `m.direct`
修复流程不会自动删除旧房间。它只会选择健康的私信并更新映射,这样新的 Matrix 发送、验证通知和其他私信流程才会再次指向正确的房间。
修复流程不会自动删除旧房间。它只会选择健康的私信并更新映射,以便新的 Matrix 发送、验证通知和其他直接消息流程再次定向到正确的房间。
## Exec 审批
Matrix 可以作为 Matrix 账户的原生审批客户端。原生
私信/渠道路由控制项仍位于 exec 审批配置下:
Matrix 可以作为 Matrix 账号的原生审批客户端。原生私信/渠道路由开关仍位于 exec 审批配置下:
- `channels.matrix.execApprovals.enabled`
- `channels.matrix.execApprovals.approvers`(可选;回退到 `channels.matrix.dm.allowFrom`
- `channels.matrix.execApprovals.approvers`(可选;回退到 `channels.matrix.dm.allowFrom`
- `channels.matrix.execApprovals.target``dm` | `channel` | `both`,默认值:`dm`
- `channels.matrix.execApprovals.agentFilter`
- `channels.matrix.execApprovals.sessionFilter`
审批人必须是 Matrix 用户 ID例如 `@owner:example.org`。当 `enabled` 未设置或为 `"auto"`且至少有一个审批人可被解析时Matrix 会自动启用原生审批。Exec 审批会优先使用 `execApprovals.approvers`也可以回退到 `channels.matrix.dm.allowFrom`。插件审批通过 `channels.matrix.dm.allowFrom` 授权。设置 `enabled: false` 可显式禁用 Matrix 作为原生审批客户端。否则,审批请求会回退到其他已配置的审批路由或审批回退策略。
审批人必须是 Matrix 用户 ID例如 `@owner:example.org`。当 `enabled` 未设置或为 `"auto"`且至少有一个审批人可被解析时Matrix 会自动启用原生审批。Exec 审批会优先使用 `execApprovals.approvers`并可回退到 `channels.matrix.dm.allowFrom`。插件审批通过 `channels.matrix.dm.allowFrom` 进行授权。设置 `enabled: false` 可显式禁用 Matrix 作为原生审批客户端。否则,审批请求会回退到其他已配置的审批路由或审批回退策略。
Matrix 原生路由同时支持两种审批类型
Matrix 原生路由支持这两类审批
- `channels.matrix.execApprovals.*` 控制 Matrix 审批提示的原生私信/渠道扇出模式。
- Exec 审批使用来自 `execApprovals.approvers``channels.matrix.dm.allowFrom` 的 exec 审批人集合。
- 插件审批使用来自 `channels.matrix.dm.allowFrom` 的 Matrix 私信 allowlist
- Matrix 回应快捷方式和消息更新同时适用于 exec 审批和插件审批。
- 插件审批使用来自 `channels.matrix.dm.allowFrom` 的 Matrix 私信允许列表
- Matrix 回应快捷方式和消息更新同时适用于 exec 和插件审批。
发送规则:
投递规则:
- `target: "dm"` 会将审批提示发送到审批人的私信
- `target: "channel"` 会将提示发回 Matrix 房间或私信
- `target: "both"` 会同时发送到审批人的私信以及 Matrix 房间或私信
- `target: "channel"` 会将提示发回原始 Matrix 房间或私信
- `target: "both"` 会同时发送到审批人的私信以及原始 Matrix 房间或私信
Matrix 审批提示会在主审批消息上植入回应快捷方式:
Matrix 审批提示会在主审批消息上预置回应快捷方式:
- `✅` = 允许一次
- `❌` = 拒绝
- `♾️` = 始终允许,前提是该决定在有效 exec 策略中被允许
- `♾️` = 在当前生效的 exec 策略允许该决策时始终允许
审批人可以对该消息做出回应,或使用回退 slash 命令:`/approve <id> allow-once`、`/approve <id> allow-always` 或 `/approve <id> deny`
审批人可以对此消息添加回应,也可以使用回退斜杠命令:`/approve <id> allow-once`、`/approve <id> allow-always` 或 `/approve <id> deny`
只有已解析的审批人才能批准或拒绝。对于 exec 审批,渠道发送会包含命令文本,因此仅应在受信任房间中启用 `channel``both`
只有已解析的审批人才能批准或拒绝。对于 exec 审批,渠道投递包含命令文本,因此仅应在受信任房间中启用 `channel``both`
按账覆盖:
按账覆盖:
- `channels.matrix.accounts.<account>.execApprovals`
相关文档:[Exec approvals](/zh-CN/tools/exec-approvals)
相关文档: [Exec approvals](/zh-CN/tools/exec-approvals)
## Slash 命令
## 斜杠命令
Matrix slash 命令(例如 `/new`、`/reset`、`/model`可直接在私信中使用。在房间中OpenClaw 还会识别带有机器人自身 Matrix 提及前缀的 slash 命令,因此 `@bot:server /new` 会触发命令路径,而无需自定义提及正则。这使得机器人能够响应 Element 和类似客户端在用户先补全机器人名称、再输入命令时产生的房间式 `@mention /command` 帖子。
Matrix 斜杠命令(例如 `/new`、`/reset`、`/model`可直接在私信中使用。在房间中OpenClaw 也能识别以前缀为机器人自身 Matrix 提及的斜杠命令,因此 `@bot:server /new` 会触发命令路径,而无需自定义提及正则。这使得机器人能够响应 Element 和类似客户端在用户先 Tab 补全机器人再输入命令时发出的房间式 `@mention /command` 帖子。
授权规则仍然适用:命令发送者必须像普通消息一样满足私信或房间的 allowlist/所有者策略。
授权规则仍然适用:命令发送者必须像普通消息一样满足私信或房间允许列表/owner 策略。
## 多账
## 多账
```json5
{
@ -798,25 +820,23 @@ Matrix slash 命令(例如 `/new`、`/reset`、`/model`)可直接在私信
}
```
顶层 `channels.matrix` 值会作为命名账户的默认值,除非某个账户进行了覆盖。
你可以通过 `groups.<room>.account` 将继承的房间条目限定到某一个 Matrix 账户
未设置 `account` 的条目会在所有 Matrix 账户之间共享,而设置了 `account: "default"` 的条目在默认账户直接配置在顶层 `channels.matrix.*` 时也仍然有效。
部分共享认证默认值本身不会创建一个单独的隐式默认账户。只有当该默认值具有新的认证信息(`homeserver` 加 `accessToken`,或 `homeserver``userId``password`OpenClaw 才会合成顶层 `default`户;而命名账户即使只有 `homeserver``userId`,只要后续缓存凭证满足认证要求,仍可保持可发现状态。
如果 Matrix 已经只有一个命名账户,或者 `defaultAccount` 指向某个现有命名账户键,那么从单账户到多账户的修复/设置提升会保留该账户,而不是新建一个新的 `accounts.default` 条目。只有 Matrix 认证/bootstrap 键会移动到该提升后的账户中;共享的发送策略键仍保留在顶层。
如果你希望 OpenClaw 在隐式路由、探测和 CLI 操作中优先使用某个命名 Matrix 账户,请设置 `defaultAccount`
如果配置了多个 Matrix 账户,且其中一个账户 id 是 `default`,那么即使 `defaultAccount` 未设置OpenClaw 也会隐式使用该账户
如果你配置了多个命名账户,请设置 `defaultAccount`,或为依赖隐式账户选择的 CLI 命令传入 `--account <id>`
当你希望为单个命令覆盖该隐式选择时,请为 `openclaw matrix verify ...``openclaw matrix devices ...` 传入 `--account <id>`
顶层 `channels.matrix` 值会作为命名账号的默认值,除非某个账号进行了覆盖。
你可以使用 `groups.<room>.account` 将继承的房间条目限定到某个 Matrix 账号
未设置 `account` 的条目会在所有 Matrix 账号之间共享,而设置了 `account: "default"` 的条目在默认账号直接配置于顶层 `channels.matrix.*`仍然有效。
部分共享认证默认值本身不会创建一个单独的隐式默认账号。只有当该默认值具备新的认证信息(`homeserver` 加 `accessToken`,或 `homeserver``userId``password`OpenClaw 才会合成顶层 `default`号;命名账号在稍后由缓存凭证满足认证时,仍然可以通过 `homeserver``userId` 保持可发现状态。
如果 Matrix 已经正好有一个命名账号,或者 `defaultAccount` 指向现有的命名账号键,则单账号到多账号的修复/设置升级会保留该账号,而不是创建新的 `accounts.default` 条目。只有 Matrix 认证/bootstrap 键会移动到该提升后的账号中;共享的投递策略键仍保留在顶层。
当你希望 OpenClaw 在隐式路由、探测和 CLI 操作中优先使用某个命名 Matrix 账号时,请设置 `defaultAccount`
如果配置了多个 Matrix 账号,且其中一个账号 ID 为 `default`,即使 `defaultAccount` 未设置OpenClaw 也会隐式使用该账号
如果你配置了多个命名账号,请设置 `defaultAccount`,或者为依赖隐式账号选择的 CLI 命令传入 `--account <id>`
当你希望对单个命令覆盖这种隐式选择时,请为 `openclaw matrix verify ...``openclaw matrix devices ...` 传入 `--account <id>`
有关共享多账户模式,请参阅 [Configuration reference](/zh-CN/gateway/config-channels#multi-account-all-channels)。
共享多账号模式请参阅 [Configuration reference](/zh-CN/gateway/config-channels#multi-account-all-channels)。
## 私有/LAN homeserver
默认情况下,出于 SSRF 保护OpenClaw 会阻止私有/内部 Matrix homeserver除非你
按账户显式选择启用。
默认情况下,出于 SSRF 保护考虑OpenClaw 会阻止私有/内部 Matrix homeserver除非你针对每个账号显式选择启用。
如果你的 homeserver 运行在 localhost、LAN/Tailscale IP 或内部主机名上,请为该 Matrix 账户启用
`network.dangerouslyAllowPrivateNetwork`
如果你的 homeserver 运行在 localhost、LAN/Tailscale IP 或内部主机名上,请为该 Matrix 账号启用 `network.dangerouslyAllowPrivateNetwork`
```json5
{
@ -842,8 +862,7 @@ openclaw matrix account add \
--access-token syt_ops_xxx
```
此选择启用仅允许受信任的私有/内部目标。像
`http://matrix.example.org:8008` 这样的公共明文 homeserver 仍会被阻止。请尽可能优先使用 `https://`
此选择启用仅允许受信任的私有/内部目标。诸如 `http://matrix.example.org:8008` 之类的公共明文 homeserver 仍会被阻止。尽可能优先使用 `https://`
## 代理 Matrix 流量
@ -861,90 +880,88 @@ openclaw matrix account add \
}
```
命名账户可通过 `channels.matrix.accounts.<id>.proxy` 覆盖顶层默认值。
OpenClaw 会对运行时 Matrix 流量和账户状态探测使用相同的代理设置。
命名账号可以使用 `channels.matrix.accounts.<id>.proxy` 覆盖顶层默认值。
OpenClaw 会对运行时 Matrix 流量和账号状态探测使用同一个代理设置。
## 目标解析
在 OpenClaw 要求你提供房间或用户目标的任何位置Matrix 都接受以下目标形式:
无论 OpenClaw 在何处要求你提供房间或用户目标Matrix 都接受以下目标形式:
- 用户:`@user:server`、`user:@user:server` 或 `matrix:user:@user:server`
- 房间:`!room:server`、`room:!room:server` 或 `matrix:room:!room:server`
- 别名:`#alias:server`、`channel:#alias:server` 或 `matrix:channel:#alias:server`
Matrix 房间 ID 区分大小写。在配置显式发送目标、cron 作业、绑定或 allowlist 时,
请使用 Matrix 中房间 ID 的准确大小写形式。
OpenClaw 会将内部会话键规范化以便存储,因此这些小写键
不能作为 Matrix 发送 ID 的可靠来源。
Matrix 房间 ID 区分大小写。在配置显式投递目标、cron 作业、绑定或允许列表时,请使用 Matrix 中房间 ID 的精确大小写。
OpenClaw 会将内部会话键保持为规范形式以供存储,因此这些小写键不能作为 Matrix 投递 ID 的可靠来源。
实时目录查找会使用已登录的 Matrix 账户
实时目录查找使用当前登录的 Matrix 账号:
- 用户查找会查询该 homeserver 上的 Matrix 用户目录。
- 房间查找会直接接受显式房间 ID 和别名,然后回退为搜索该账户已加入房间的名称。
- 已加入房间名称查找是尽力而为的。如果某个房间名称无法解析为 ID 或别名,它会在运行时 allowlist 解析中被忽略。
- 房间查找会直接接受显式房间 ID 和别名,然后回退到搜索该账号已加入的房间名称。
- 已加入房间名称查找是尽力而为的。如果某个房间名称无法解析为 ID 或别名,它会在运行时允许列表解析中被忽略。
## 配置参考
- `enabled`:启用或禁用该渠道。
- `name`:账的可选标签。
- `defaultAccount`:配置了多个 Matrix 账户时的首选账户 ID。
- `name`:账的可选标签。
- `defaultAccount`:配置了多个 Matrix 账号时的首选账号 ID。
- `homeserver`homeserver URL例如 `https://matrix.example.org`
- `network.dangerouslyAllowPrivateNetwork`:允许此 Matrix 账连接到私有/内部 homeserver。当 homeserver 解析到 `localhost`、LAN/Tailscale IP 或诸如 `matrix-synapse` 之类的内部主机时,请启用此项。
- `proxy`:用于 Matrix 流量的可选 HTTP(S) 代理 URL。命名账户可以用它们自己的 `proxy` 覆盖顶层默认值。
- `userId`:完整 Matrix 用户 ID例如 `@bot:example.org`
- `accessToken`:基于 token 认证的 access token。`channels.matrix.accessToken` 和 `channels.matrix.accounts.<id>.accessToken` 支持明文值和 SecretRef 值,适用于 env/file/exec 提供商。请参阅 [Secrets Management](/zh-CN/gateway/secrets)。
- `password`:基于密码登录的密码。支持明文值和 SecretRef 值。
- `deviceId`:显式 Matrix 设备 ID。
- `network.dangerouslyAllowPrivateNetwork`:允许此 Matrix 账连接到私有/内部 homeserver。当 homeserver 解析到 `localhost`、LAN/Tailscale IP 或内部主机(例如 `matrix-synapse`)时启用此项。
- `proxy`:用于 Matrix 流量的可选 HTTP(S) 代理 URL。命名账号可以用自己的 `proxy` 覆盖顶层默认值。
- `userId`:完整 Matrix 用户 ID例如 `@bot:example.org`
- `accessToken`:基于 token 认证所使用的 access token。`channels.matrix.accessToken` 和 `channels.matrix.accounts.<id>.accessToken` 在 env/file/exec provider 中均支持纯文本值和 SecretRef 值。请参阅 [Secrets Management](/zh-CN/gateway/secrets)。
- `password`:基于密码登录所使用的密码。支持纯文本值和 SecretRef 值。
- `deviceId`:显式 Matrix 设备 ID。
- `deviceName`:用于密码登录的设备显示名称。
- `avatarUrl`:用于资料同步和 `profile set` 更新的已存储自头像 URL。
- `avatarUrl`:用于资料同步和 `profile set` 更新的已存储自头像 URL。
- `initialSyncLimit`:启动同步期间获取的最大事件数。
- `encryption`:启用端到端加密
- `allowlistOnly`:当为 `true` 时,会将 `open` 房间策略升级为 `allowlist`,并强制所有活动私信策略(除 `disabled` 外,包括 `pairing``open`)变为 `allowlist`。不影响 `disabled` 策略。
- `allowBots`:允许来自其他已配置 OpenClaw Matrix 账的消息(`true` 或 `"mentions"`)。
- `encryption`:启用 E2EE
- `allowlistOnly`:当为 `true` 时,会将 `open` 房间策略升级为 `allowlist`,并强制`disabled` 之外的所有活动私信策略(包括 `pairing``open`)变为 `allowlist`。不影响 `disabled` 策略。
- `allowBots`:允许来自其他已配置 OpenClaw Matrix 账的消息(`true` 或 `"mentions"`)。
- `groupPolicy``open`、`allowlist` 或 `disabled`
- `contextVisibility`:补充房间上下文可见性模式(`all`、`allowlist`、`allowlist_quote`)。
- `groupAllowFrom`:房间流量的用户 ID allowlist。完整 Matrix 用户 ID 最安全;当监视器运行时,会在启动时以及 allowlist 发生变化时解析精确目录匹配。无法解析的名称会被忽略。
- `historyLimit`:作为群组历史上下文包含的最大房间消息数。会回退到 `messages.groupChat.historyLimit`;如果两者都未设置,则有效默认值为 `0`。设置为 `0` 可禁用。
- `contextVisibility`:补充房间上下文可见性模式(`all`、`allowlist`、`allowlist_quote`)。
- `groupAllowFrom`:房间流量的用户 ID 允许列表。完整 Matrix 用户 ID 最安全;精确目录匹配会在启动时以及监视器运行期间允许列表变更时进行解析。无法解析的名称会被忽略。
- `historyLimit`:作为群组历史上下文包含的最大房间消息数。会回退到 `messages.groupChat.historyLimit`;如果两者都未设置,则实际默认值为 `0`。设置为 `0` 可禁用。
- `replyToMode``off`、`first`、`all` 或 `batched`
- `markdown`:出站 Matrix 文本的可选 Markdown 渲染配置。
- `streaming``off`(默认)、`"partial"`、`"quiet"`、`true` 或 `false`。`"partial"` 和 `true` 会使用普通 Matrix 文本消息启用“预览优先”的草稿更新。`"quiet"` 会为自托管推送规则设置使用不通知的预览通知。`false` 等同于 `"off"`
- `blockStreaming`当草稿预览流式传输处于活动状态时,`true` 会为已完成的助手块启用独立的进度消息。
- `streaming``off`(默认)、`"partial"`、`"quiet"`、`true` 或 `false`。`"partial"` 和 `true` 会使用普通 Matrix 文本消息启用“预览优先”的草稿更新。`"quiet"` 对自托管推送规则设置使用不触发通知的预览通知。`false` 等同于 `"off"`
- `blockStreaming``true` 会在草稿预览流式传输激活时,为已完成的智能体块启用独立进度消息。
- `threadReplies``off`、`inbound` 或 `always`
- `threadBindings`:线程绑定会话路由和生命周期的按渠道覆盖
- `startupVerification`:启动时自动自验证请求模式(`if-unverified`、`off`)。
- `startupVerificationCooldownHours`:自动启动验证请求重试前的冷却时间。
- `textChunkLimit`:出站消息分块大小(按字符计;`chunkMode``length` 时适用)。
- `threadBindings`按渠道覆盖线程绑定会话路由和生命周期。
- `startupVerification`:启动时自动自验证请求模式(`if-unverified`、`off`)。
- `startupVerificationCooldownHours`重试自动启动验证请求前的冷却时间。
- `textChunkLimit`:出站消息按字符数块时的块大小上限(当 `chunkMode``length` 时适用)。
- `chunkMode``length` 按字符数拆分消息;`newline` 按行边界拆分。
- `responsePrefix`:为该渠道所有出站回复添加的可选前缀字符串。
- `ackReaction`该渠道/账户的可选确认回应覆盖值。
- `ackReactionScope`:可选确认回应范围覆盖值(`group-mentions`、`group-all`、`direct`、`all`、`none`、`off`)。
- `responsePrefix`:为此渠道的所有出站回复添加的可选前缀字符串。
- `ackReaction`此渠道/账号的可选确认回应覆盖值。
- `ackReactionScope`:可选的确认回应作用域覆盖值(`group-mentions`、`group-all`、`direct`、`all`、`none`、`off`)。
- `reactionNotifications`:入站回应通知模式(`own`、`off`)。
- `mediaMaxMb`用于出站发送和入站媒体处理的媒体大小上限MB
- `mediaMaxMb`:出站发送和入站媒体处理的媒体大小上限,单位为 MB
- `autoJoin`:邀请自动加入策略(`always`、`allowlist`、`off`)。默认值:`off`。适用于所有 Matrix 邀请,包括私信式邀请。
- `autoJoinAllowlist`:当 `autoJoin``allowlist` 时允许的房间/别名。在邀请处理期间,别名条目会被解析为房间 IDOpenClaw 不信任被邀请房间声称的别名状态。
- `autoJoinAllowlist`:当 `autoJoin``allowlist` 时允许的房间/别名。别名条目会在处理邀请时解析为房间 IDOpenClaw 不信任受邀房间所声明的别名状态。
- `dm`:私信策略块(`enabled`、`policy`、`allowFrom`、`sessionScope`、`threadReplies`)。
- `dm.policy`:控制 OpenClaw 加入房间并将其分类为私信之后的私信访问权限。它不会改变邀请是否会被自动加入。
- `dm.allowFrom`:私信流量的用户 ID allowlist。完整 Matrix 用户 ID 最安全;当监视器运行时,会在启动时以及 allowlist 发生变化时解析精确目录匹配。无法解析的名称会被忽略。
- `dm.allowFrom`:私信流量的用户 ID 允许列表。完整 Matrix 用户 ID 最安全;精确目录匹配会在启动时以及监视器运行期间允许列表变更时进行解析。无法解析的名称会被忽略。
- `dm.sessionScope``per-user`(默认)或 `per-room`。如果你希望每个 Matrix 私信房间即使对端相同也保持独立上下文,请使用 `per-room`
- `dm.threadReplies`:仅私信的线程策略覆盖值(`off`、`inbound`、`always`)。它会覆盖顶层 `threadReplies` 设置,同时影响私信中的回复位置和会话隔离。
- `execApprovals`Matrix 原生 exec 审批发送`enabled`、`approvers`、`target`、`agentFilter`、`sessionFilter`)。
- `execApprovals.approvers`:允许批 exec 请求的 Matrix 用户 ID。当 `dm.allowFrom` 已经标识审批人时,项可选。
- `dm.threadReplies`:仅用于私信的线程策略覆盖值(`off`、`inbound`、`always`)。它会覆盖顶层 `threadReplies` 设置,影响私信中的回复位置和会话隔离。
- `execApprovals`Matrix 原生 exec 审批投递`enabled`、`approvers`、`target`、`agentFilter`、`sessionFilter`)。
- `execApprovals.approvers`:允许批 exec 请求的 Matrix 用户 ID。当 `dm.allowFrom` 已经标识审批人时,项可选。
- `execApprovals.target``dm | channel | both`(默认值:`dm`)。
- `accounts`:按账命名的覆盖项。顶层 `channels.matrix` 值会作为这些条目的默认值。
- `groups`:按房间划分的策略映射。优先使用房间 ID 或别名;无法解析的房间名称会在运行时被忽略。解析后,会话/群组身份使用稳定的房间 ID。
- `groups.<room>.account`:在多账户设置中,将一条继承的房间条目限制到特定 Matrix 账户
- `accounts`:按账命名的覆盖项。顶层 `channels.matrix` 值会作为这些条目的默认值。
- `groups`:按房间的策略映射。优先使用房间 ID 或别名;无法解析的房间名称会在运行时被忽略。解析后,会话/群组身份使用稳定的房间 ID。
- `groups.<room>.account`:在多账号设置中,将一个继承的房间条目限制到某个特定 Matrix 账号
- `groups.<room>.allowBots`:针对已配置机器人发送者的房间级覆盖值(`true` 或 `"mentions"`)。
- `groups.<room>.users`:按房间划分的发送者 allowlist
- `groups.<room>.tools`:按房间划分的工具允许/拒绝覆盖。
- `groups.<room>.users`:按房间的发送者允许列表
- `groups.<room>.tools`:按房间的工具允许/拒绝覆盖
- `groups.<room>.autoReply`:房间级提及门控覆盖值。`true` 会禁用该房间的提及要求;`false` 会强制重新启用。
- `groups.<room>.skills`:可选的房间级 Skills 过滤器。
- `groups.<room>.systemPrompt`:可选的房间级 system prompt 片段。
- `rooms``groups` 的旧别名。
- `actions`:按操作划分的工具门控(`messages`、`reactions`、`pins`、`profile`、`memberInfo`、`channelInfo`、`verification`)。
- `actions`:按操作的工具门控(`messages`、`reactions`、`pins`、`profile`、`memberInfo`、`channelInfo`、`verification`)。
## 相关内容
- [Channels Overview](/zh-CN/channels) — 所有支持的渠道
- [Channels Overview](/zh-CN/channels) — 所有支持的渠道
- [Pairing](/zh-CN/channels/pairing) — 私信认证和配对流程
- [Groups](/zh-CN/channels/groups) — 群聊行为和提及门控
- [Channel Routing](/zh-CN/channels/channel-routing) — 消息的会话路由

File diff suppressed because one or more lines are too long

View File

@ -1,100 +1,101 @@
---
read_when:
- 在本地或 CI 中运行测试
- 为模型 / 提供商缺陷添加回归测试
- 为模型/提供商 bug 添加回归测试
- 调试 Gateway 网关 + 智能体行为
summary: 测试工具包:单元 / e2e / live 测试套件、Docker 运行器,以及每类测试覆盖的内容
summary: 测试工具包:unit/e2e/live 测试套件、Docker 运行器,以及每类测试覆盖的内容
title: 测试
x-i18n:
generated_at: "2026-04-27T03:28:53Z"
generated_at: "2026-04-27T03:46:56Z"
model: gpt-5.4
provider: openai
source_hash: 1c9975b9c7a6fa53d402219c9b8eb3855b0ed76c8599a35f209deeb700e43b11
source_hash: c2c9539ecc93c605cf1457f9d2a0b1364eb6b814d263eb9e40832cec683ee58b
source_path: help/testing.md
workflow: 15
---
OpenClaw 有三个 Vitest 测试套件(单元 / 集成、e2e、live以及一小组 Docker 运行器。本文档是一份“我们如何测试”的指南:
OpenClaw 有三个 Vitest 测试套件(unit/integration、e2e、live以及一小组 Docker 运行器。本文档是“我们如何测试”的指南:
- 每个套件覆盖什么(以及刻意 _不_ 覆盖什么)。
- 每个测试套件覆盖什么内容(以及刻意 _不_ 覆盖什么)。
- 常见工作流应运行哪些命令(本地、推送前、调试)。
- live 测试如何发现凭证并选择模型 / 提供商。
- 如何为真实世界中的模型 / 提供商问题添加回归测试。
- live 测试如何发现凭证并选择模型/提供商。
- 如何为真实世界中的模型/提供商问题添加回归测试。
## 快速开始
大多数时候:
- 完整门禁(预期在 push 前执行):`pnpm build && pnpm check && pnpm check:test-types && pnpm test`
- 在配置充足的机器上更快地运行本地完整测试套件:`pnpm test:max`
- 直接进入 Vitest 监听循环:`pnpm test:watch`
- 现在直接按文件定位也会路由扩展 / 渠道路径:`pnpm test extensions/discord/src/monitor/message-handler.preflight.test.ts`
- 当你正在迭代单个失败用例时,优先先跑有针对性的测试。
- 在性能充足的机器上更快地运行本地完整测试套件:`pnpm test:max`
- 直接进入 Vitest watch 循环:`pnpm test:watch`
- 现在可直接按文件定位,也支持 extension/channel 路径:`pnpm test extensions/discord/src/monitor/message-handler.preflight.test.ts`
- 当你在迭代单个失败用例时,优先先运行有针对性的测试。
- Docker 支持的 QA 站点:`pnpm qa:lab:up`
- Linux VM 支持的 QA 测试通道`pnpm openclaw qa suite --runner multipass --scenario channel-chat-baseline`
- Linux VM 支持的 QA lane`pnpm openclaw qa suite --runner multipass --scenario channel-chat-baseline`
当你改动了测试,或想获得更多信心时:
当你修改了测试,或想获得额外信心时:
- 覆盖率门禁:`pnpm test:coverage`
- E2E 套件:`pnpm test:e2e`
- E2E 测试套件:`pnpm test:e2e`
当你调试真实提供商 / 模型时(需要真实凭证):
当你调试真实提供商/模型时(需要真实凭证):
- live 套件(模型 + Gateway 网关工具 / 图像探测):`pnpm test:live`
- Live 测试套件(模型 + Gateway 网关工具/图像探测):`pnpm test:live`
- 安静地只跑一个 live 文件:`pnpm test:live -- src/agents/models.profiles.live.test.ts`
- Docker live 模型扫描:`pnpm test:docker:live-models`
- 每个被选中的模型现在都会运行一次文本轮次和一次小型文件读取式探测。元数据声明支持 `image` 输入的模型还会运行一个微型图像轮次。排查提供商故障时,可使用 `OPENCLAW_LIVE_MODEL_FILE_PROBE=0``OPENCLAW_LIVE_MODEL_IMAGE_PROBE=0` 关闭额外探测。
- CI 覆盖:每日的 `OpenClaw Scheduled Live And E2E Checks` 和手动触发的 `OpenClaw Release Checks` 都会调用可复用的 live / E2E 工作流,并设置 `include_live_suites: true`,其中包含按提供商分片的独立 Docker live 模型矩阵作业。
- 如需有针对性的 CI 重跑,可分发 `OpenClaw Live And E2E Checks (Reusable)` 并设置 `include_live_suites: true` `live_models_only: true`
- 将新的高信号提供商密钥添加到 `scripts/ci-hydrate-live-auth.sh`、`.github/workflows/openclaw-live-and-e2e-checks-reusable.yml` 及其定时 / 发布调用方中。
- 原生 Codex 绑定聊天冒烟测试`pnpm test:docker:live-codex-bind`
- 对 Codex app-server 路径运行一个 Docker live 测试通道,绑定一个合成的 Slack 私信并执行 `/codex bind`测试 `/codex fast``/codex permissions`,然后验证普通回复和图像附件是通过原生插件绑定路由,而不是通过 ACP。
- Codex app-server harness 冒烟测试`pnpm test:docker:live-codex-harness`
- 通过插件拥有的 Codex app-server harness 运行 Gateway 网关智能体轮次,验证 `/codex status``/codex models`,并且默认会测试图像、cron MCP、子智能体和 Guardian 探测。排查其他 Codex app-server 故障时,可使用 `OPENCLAW_LIVE_CODEX_HARNESS_SUBAGENT_PROBE=0` 关闭子智能体探测。如需专门检查子智能体,请关闭其他探测:`OPENCLAW_LIVE_CODEX_HARNESS_IMAGE_PROBE=0 OPENCLAW_LIVE_CODEX_HARNESS_MCP_PROBE=0 OPENCLAW_LIVE_CODEX_HARNESS_GUARDIAN_PROBE=0 OPENCLAW_LIVE_CODEX_HARNESS_SUBAGENT_PROBE=1 pnpm test:docker:live-codex-harness`。
除非设置了 `OPENCLAW_LIVE_CODEX_HARNESS_SUBAGENT_ONLY=0`,否则该命令会在子智能体探测后退出。
- Crestodian 救援命令冒烟测试`pnpm test:live:crestodian-rescue-channel`
- 针对消息渠道救援命令表面的可选多重保险检查。它会执行 `/crestodian status`,排队一个持久模型变更,回复 `/crestodian yes`,并验证审计 / 配置写入路径。
- Crestodian 规划器 Docker 冒烟测试`pnpm test:docker:crestodian-planner`
- 在没有配置的容器中运行 Crestodian容器的 `PATH` 中带有假的 Claude CLI并验证模糊规划器回退能转换为带审计的类型化配置写入。
- Crestodian 首次运行 Docker 冒烟测试`pnpm test:docker:crestodian-first-run`
- 从空的 OpenClaw 状态目录启动,将裸 `openclaw` 路由到 Crestodian应用 setup / model / agent / Discord 插件 + SecretRef 写入,验证配置,并验证审计条目。相同的 Ring 0 设置路径也在 QA Lab 中通过 `pnpm openclaw qa suite --scenario crestodian-ring-zero-setup` 覆盖。
- Moonshot / Kimi 成本冒烟测试:设置 `MOONSHOT_API_KEY` 后,运行 `openclaw models list --provider moonshot --json`,然后针对 `moonshot/kimi-k2.6` 运行独立命令 `openclaw agent --local --session-id live-kimi-cost --message 'Reply exactly: KIMI_LIVE_OK' --thinking off --json`
。验证 JSON 报告了 Moonshot / K2.6,并且助手转录中存储了规范化后`usage.cost`
- 现在每个选中的模型都会运行一次文本轮次外加一个小型文件读取式探测。元数据声明支持 `image` 输入的模型还会运行一个微型图像轮次。在隔离提供商故障时,可用 `OPENCLAW_LIVE_MODEL_FILE_PROBE=0``OPENCLAW_LIVE_MODEL_IMAGE_PROBE=0` 禁用这些额外探测。
- CI 覆盖:每日的 `OpenClaw Scheduled Live And E2E Checks` 和手动触发的 `OpenClaw Release Checks` 都会调用可复用的 live/E2E workflow,并设置 `include_live_suites: true`,其中包含按提供商分片的独立 Docker live 模型矩阵作业。
- 若只想有针对性地在 CI 中重跑,请触发 `OpenClaw Live And E2E Checks (Reusable)`,并设置 `include_live_suites: true` `live_models_only: true`
- 将新的高信号提供商 secret 添加到 `scripts/ci-hydrate-live-auth.sh`,以及 `.github/workflows/openclaw-live-and-e2e-checks-reusable.yml` 和其定时/发布调用方中。
- 原生 Codex 绑定聊天 smoke`pnpm test:docker:live-codex-bind`
- 在 Docker live lane 中针对 Codex app-server 路径运行,绑定一个合成的 Slack 私信并执行 `/codex bind`随后运行 `/codex fast``/codex permissions`,然后验证普通回复和图像附件是通过原生插件绑定路由,而不是 ACP。
- Codex app-server harness smoke`pnpm test:docker:live-codex-harness`
- 通过插件拥有的 Codex app-server harness 运行 Gateway 网关智能体轮次,验证 `/codex status``/codex models`,并且默认执行图像、cron MCP、sub-agent 和 Guardian 探测。在隔离其他 Codex app-server 故障时,可用 `OPENCLAW_LIVE_CODEX_HARNESS_SUBAGENT_PROBE=0` 禁用 sub-agent 探测。若只想聚焦 sub-agent 检查,请禁用其他探测:`OPENCLAW_LIVE_CODEX_HARNESS_IMAGE_PROBE=0 OPENCLAW_LIVE_CODEX_HARNESS_MCP_PROBE=0 OPENCLAW_LIVE_CODEX_HARNESS_GUARDIAN_PROBE=0 OPENCLAW_LIVE_CODEX_HARNESS_SUBAGENT_PROBE=1 pnpm test:docker:live-codex-harness`。
除非设置了 `OPENCLAW_LIVE_CODEX_HARNESS_SUBAGENT_ONLY=0`,否则该命令会在 sub-agent 探测后退出。
- Crestodian rescue command smoke`pnpm test:live:crestodian-rescue-channel`
- 面向消息渠道 rescue command 表面的可选双保险检查。它会执行 `/crestodian status`,排队一个持久模型变更,回复 `/crestodian yes`,并验证审计/配置写入路径。
- Crestodian planner Docker smoke`pnpm test:docker:crestodian-planner`
- 在一个无配置容器中运行 Crestodian并在 `PATH` 上提供一个假的 Claude CLI验证模糊 planner 回退会转换为带审计的类型化配置写入。
- Crestodian first-run Docker smoke`pnpm test:docker:crestodian-first-run`
- 从一个空的 OpenClaw 状态目录启动,将裸 `openclaw` 路由到 Crestodian应用 setup/model/agent/Discord 插件 + SecretRef 写入,验证配置,并检查审计条目。相同的 Ring 0 设置路径也在 QA Lab 中由 `pnpm openclaw qa suite --scenario crestodian-ring-zero-setup` 覆盖。
- Moonshot/Kimi 成本 smoke:设置 `MOONSHOT_API_KEY` 后,运行 `openclaw models list --provider moonshot --json`,然后针对 `moonshot/kimi-k2.6` 运行一个隔离的 `openclaw agent --local --session-id live-kimi-cost --message 'Reply exactly: KIMI_LIVE_OK' --thinking off --json`
验证 JSON 报告的是 Moonshot/K2.6,且 assistant transcript 存储了规范化`usage.cost`
提示:当你只需要一个失败用例时,优先使用下文描述的允许列表环境变量来缩小 live 测试范围。
提示:如果你只需要一个失败用例,优先通过下文描述的 allowlist 环境变量来缩小 live 测试范围。
## QA 专用运行器
当你需要 QA-lab 的真实环境时,这些命令与主测试套件配合使用:
当你需要接近 QA-lab 真实场景时,这些命令与主测试套件并列使用:
CI 会在专用工作流中运行 QA Lab。`Parity gate` 会在匹配的 PR 上运行,也可以通过手动分发使用 mock 提供商运行。`QA-Lab - All Lanes` 每晚在 `main` 上运行,也可以手动分发,以 mock parity gate、live Matrix 测试通道和由 Convex 管理的 live Telegram 测试通道作为并行作业运行。`OpenClaw Release Checks` 会在发布批准前运行相同的测试通道
CI 会在专用 workflow 中运行 QA Lab。`Parity gate` 会在匹配的 PR 上运行,也支持手动触发,并使用 mock 提供商。`QA-Lab - All Lanes` 会在 `main` 上每晚运行,也支持手动触发,其中 mock parity gate、live Matrix lane 和由 Convex 管理的 live Telegram lane 作为并行作业运行。`OpenClaw Release Checks` 会在发布批准前运行同样的 lanes
- `pnpm openclaw qa suite`
- 直接在宿主机上运行基于仓库的 QA 场景。
- 默认会并行运行多个选定场景,并使用隔离的 Gateway 网关工作进程。`qa-channel` 默认并发数为 4受所选场景数量限制。使用 `--concurrency <count>` 调整工作进程数量,或使用 `--concurrency 1` 启用旧的串行测试通道。
- 任一场景失败时会以非零状态退出。如果你想保留产物而不返回失败退出码,请使用 `--allow-failures`
- 支持提供商模式 `live-frontier`、`mock-openai` 和 `aimock`。`aimock` 会启动一个本地的 AIMock 支持提供商服务器,用于实验性的 fixture 和协议 mock 覆盖,而不会替代具备场景感知能力的 `mock-openai` 测试通道。
- 直接在主机上运行由仓库支持的 QA 场景。
- 默认会以隔离的 Gateway 网关 worker 并行运行多个选中的场景。`qa-channel` 默认并发数为 4受所选场景数量限制。使用 `--concurrency <count>` 调整 worker 数量,或使用 `--concurrency 1` 进入较早的串行 lane。
- 任一场景失败时以非零状态退出。若你想保留产物但不希望退出码失败,请使用 `--allow-failures`
- 支持提供商模式 `live-frontier`、`mock-openai` 和 `aimock`
`aimock` 会启动一个本地由 AIMock 支持的提供商服务器,用于实验性的 fixture 和协议 mock 覆盖,而不会替代具备场景感知能力的 `mock-openai` lane。
- `pnpm openclaw qa suite --runner multipass`
- 在一次性 Multipass Linux VM 中运行相同的 QA 套件。
- 与宿主机上的 `qa suite` 保持相同的场景选择行为。
- 复用与 `qa suite` 相同的提供商 / 模型选择参数。
- live 运行会转发适合来宾环境的受支持 QA 认证输入基于环境变量的提供商密钥、QA live 提供商配置路径,以及存在时的 `CODEX_HOME`
- 输出目录必须保留在仓库根目录下,这样来宾环境才能通过挂载的工作区回写数据
- 会将常规 QA 报告 + 摘要,以及 Multipass 日志写入 `.artifacts/qa-e2e/...`
- 在一次性 Multipass Linux VM 中运行相同的 QA 测试套件。
- 与主机上的 `qa suite` 保持相同的场景选择行为。
- 复用与 `qa suite` 相同的提供商/模型选择参数。
- live 运行会转发对 guest 来说实际可用的受支持 QA 凭证输入基于环境变量的提供商密钥、QA live 提供商配置路径,以及存在时的 `CODEX_HOME`
- 输出目录必须保持在仓库根目录下,这样 guest 才能通过挂载的工作区回写内容
- 会`.artifacts/qa-e2e/...` 下写入常规 QA 报告 + 汇总以及 Multipass 日志
- `pnpm qa:lab:up`
- 启动 Docker 支持的 QA 站点,用于偏运营者风格的 QA 工作。
- 启动 Docker 支持的 QA 站点,用于偏操作员风格的 QA 工作。
- `pnpm test:docker:npm-onboard-channel-agent`
- 从当前 checkout 构建一个 npm tarball在 Docker 中全局安装,运行非交互式 OpenAI API key 新手引导,默认配置 Telegram验证启用插件时会按需安装运行时依赖运行 doctor并针对一个 mock OpenAI 端点运行一次本地智能体轮次。
- 使用 `OPENCLAW_NPM_ONBOARD_CHANNEL=discord` 可在 Discord 上运行相同的打包安装测试通道
- 从当前 checkout 构建一个 npm tarball在 Docker 中全局安装,运行非交互式 OpenAI API-key 新手引导,默认配置 Telegram验证启用插件时会按需安装运行时依赖运行 doctor并针对一个模拟的 OpenAI endpoint 运行一次本地智能体轮次。
- 使用 `OPENCLAW_NPM_ONBOARD_CHANNEL=discord` 可在 Discord 上运行相同的打包安装 lane
- `pnpm test:docker:session-runtime-context`
- 运行一个用于嵌入式运行时上下文转录的确定性 built-app Docker 冒烟测试。它会验证隐藏的 OpenClaw 运行时上下文被保存为非展示型自定义消息,而不是泄漏到可见的用户轮次中;随后注入一个受影响的损坏会话 JSONL并验证 `openclaw doctor --fix` 会将其重写到当前活动分支并生成备份。
- 为嵌入式运行时上下文 transcript 运行一个确定性的内置应用 Docker smoke。它会验证隐藏的 OpenClaw 运行时上下文以非展示的自定义消息形式持久化,而不是泄漏到可见的用户轮次中;随后植入一个受影响的损坏 session JSONL并验证 `openclaw doctor --fix` 会将其重写到当前分支并保留备份。
- `pnpm test:docker:npm-telegram-live`
- 在 Docker 中安装一个已发布的 OpenClaw 包,运行已安装包的新手引导,通过已安装的 CLI 配置 Telegram然后将该已安装包作为被测 Gateway 网关复用 live Telegram QA 测试通道
- 默认值为 `OPENCLAW_NPM_TELEGRAM_PACKAGE_SPEC=openclaw@beta`
- 使用与 `pnpm openclaw qa telegram` 相同的 Telegram 环境变量凭证或 Convex 凭证源。对于 CI / 发布自动化,设置 `OPENCLAW_NPM_TELEGRAM_CREDENTIAL_SOURCE=convex`并提供 `OPENCLAW_QA_CONVEX_SITE_URL` 与角色密钥。如果在 CI 中存在 `OPENCLAW_QA_CONVEX_SITE_URL` 和 Convex 角色密钥Docker 包装器会自动选择 Convex。
- `OPENCLAW_NPM_TELEGRAM_CREDENTIAL_ROLE=ci|maintainer` 仅为该测试通道覆盖共享的 `OPENCLAW_QA_CREDENTIAL_ROLE`
- GitHub Actions 也将该测试通道暴露为手动维护者工作流 `NPM Telegram Beta E2E`。它不会在合并时运行。该工作流使用 `qa-live-shared` 环境和 Convex CI 凭证租约。
- GitHub Actions 还提供 `Package Acceptance`,用于针对单个候选包进行附带运行的产品证明。它接受受信任的 ref、已发布的 npm spec、带 SHA-256 的 HTTPS tarball URL或来自另一个运行的 tarball artifact上传规范化`openclaw-current.tgz` 作为 `package-under-test`,然后使用 smoke、package、product、full 或 custom 测试通道配置运行现有的 Docker E2E 调度器。已发布的 npm 候选包还可以额外运行 Telegram QA 工作流
- 在 Docker 中安装一个已发布的 OpenClaw package运行已安装 package 的新手引导,通过已安装的 CLI 配置 Telegram然后复用 live Telegram QA lane并将该已安装 package 作为被测 Gateway 网关
- 默认使用 `OPENCLAW_NPM_TELEGRAM_PACKAGE_SPEC=openclaw@beta`
- 使用与 `pnpm openclaw qa telegram` 相同的 Telegram 环境变量凭证或 Convex 凭证源。对于 CI/发布自动化,设置 `OPENCLAW_NPM_TELEGRAM_CREDENTIAL_SOURCE=convex`以及 `OPENCLAW_QA_CONVEX_SITE_URL` 和角色 secret。如果在 CI 中存在 `OPENCLAW_QA_CONVEX_SITE_URL` 和 Convex 角色 secretDocker wrapper 会自动选择 Convex。
- `OPENCLAW_NPM_TELEGRAM_CREDENTIAL_ROLE=ci|maintainer` 仅为该 lane 覆盖共享的 `OPENCLAW_QA_CREDENTIAL_ROLE`
- GitHub Actions 也将此 lane 暴露为手动维护者 workflow `NPM Telegram Beta E2E`。它不会在 merge 时运行。该 workflow 使用 `qa-live-shared` environment 和 Convex CI 凭证租约。
- GitHub Actions 还暴露了 `Package Acceptance`,用于对单个候选 package 进行旁路产品证明。它接受受信任 ref、已发布 npm spec、带 SHA-256 的 HTTPS tarball URL或来自另一个运行的 tarball artifact上传规范化的 `openclaw-current.tgz` 作为 `package-under-test`,然后运行现有 Docker E2E 调度器,支持 smoke、package、product、full 或自定义 lane 配置。已发布的 npm 候选版本还可以额外运行 Telegram QA workflow
- 最新 beta 产品证明:
```bash
@ -104,7 +105,7 @@ gh workflow run package-acceptance.yml --ref main \
-f suite_profile=product
```
- 精确 tarball URL 证明需要摘要
- 精确 tarball URL 证明需要摘要:
```bash
gh workflow run package-acceptance.yml --ref main \
@ -114,7 +115,7 @@ gh workflow run package-acceptance.yml --ref main \
-f suite_profile=package
```
- artifact 证明会从另一个 Actions 运行下载一个 tarball artifact
- Artifact 证明会从另一个 Actions 运行中下载 tarball artifact
```bash
gh workflow run package-acceptance.yml --ref main \
@ -125,49 +126,49 @@ gh workflow run package-acceptance.yml --ref main \
```
- `pnpm test:docker:bundled-channel-deps`
- 在 Docker 中打包并安装当前 OpenClaw 构建,启动已配置 OpenAI 的 Gateway 网关,然后通过配置编辑启用内置的渠道 / 插件
- 验证 setup 发现流程会让未配置的插件运行时依赖保持缺失状态;第一个已配置的 Gateway 网关或 doctor 运行会按需安装每个内置插件的运行时依赖;第二次重启不会重新安装已经激活的依赖。
- 还会安装一个已知的较旧 npm 基线,在运行 `openclaw update --tag <candidate>` 之前启用 Telegram并验证候选版本的更新后 doctor 会修复内置渠道运行时依赖,而不需要 harness 侧的 postinstall 修复。
- 在 Docker 中打包并安装当前 OpenClaw 构建,使用已配置好的 OpenAI 启动 Gateway 网关,然后通过编辑配置启用内置 channel/plugins
- 验证 setup 发现流程不会安装未配置插件的运行时依赖;首次配置完成后的 Gateway 网关运行或 doctor 运行会按需安装每个内置插件的运行时依赖;第二次重启不会重新安装已经激活的依赖。
- 还会安装一个已知的较旧 npm 基线版本,在运行 `openclaw update --tag <candidate>` 之前启用 Telegram并验证候选版本的更新后 doctor 能修复内置 channel 运行时依赖,而无需 harness 侧的 postinstall 修复。
- `pnpm test:parallels:npm-update`
- 在 Parallels 来宾环境中运行原生打包安装更新冒烟测试。每个被选中的平台都会先安装所请求的基线包,然后在同一个来宾环境中运行已安装的 `openclaw update` 命令并验证安装版本、更新状态、Gateway 网关就绪状态,以及一次本地智能体轮次。
- 在迭代单个来宾环境时,使用 `--platform macos`、`--platform windows` 或 `--platform linux`。使用 `--json` 获取摘要 artifact 路径和每个测试通道的状态。
- OpenAI 测试通道默认使用 `openai/gpt-5.5` 作为 live 智能体轮次证明。若有意验证其他 OpenAI 模型,请传入 `--model <provider/model>` 或设置 `OPENCLAW_PARALLELS_OPENAI_MODEL`
- 将长时间的本地运行包裹在宿主机超时控制中,这样 Parallels 传输停滞就不会耗尽其余测试时间窗口:
- 在 Parallels guest 上运行原生打包安装更新 smoke。每个选中的平台都会先安装请求的基线 package然后在同一个 guest 中运行已安装的 `openclaw update` 命令,并验证安装版本、更新状态、Gateway 网关就绪情况以及一次本地智能体轮次。
- 在迭代单个 guest 时,使用 `--platform macos`、`--platform windows` 或 `--platform linux`。使用 `--json` 可获取汇总 artifact 路径和每个 lane 的状态。
- OpenAI lane 默认使用 `openai/gpt-5.5` 作为 live 智能体轮次证明。若有意验证其他 OpenAI 模型,请传入 `--model <provider/model>` 或设置 `OPENCLAW_PARALLELS_OPENAI_MODEL`
- 对于较长的本地运行,请用主机超时包装,以避免 Parallels 传输阻塞占用剩余测试窗口:
```bash
timeout --foreground 150m pnpm test:parallels:npm-update -- --json
timeout --foreground 90m pnpm test:parallels:npm-update -- --platform windows --json
```
- 该脚本会将嵌套测试通道日志写入 `/tmp/openclaw-parallels-npm-update.*`
认定外层包装器卡住之前,先检查 `windows-update.log`、`macos-update.log` 或 `linux-update.log`
- Windows 更新在冷启动来宾环境中,可能会在更新后的 doctor / 运行时依赖修复阶段花费 10 到 15 分钟;只要嵌套的 npm 调试日志仍在推进,这仍然是健康状态。
- 不要将这个聚合包装器与单独的 Parallels macOS、Windows 或 Linux 冒烟测试通道并行运行。它们共享 VM 状态,可能会在快照恢复、包服务或来宾 Gateway 网关状态上发生冲突。
- 更新后证明会运行常规的内置插件表面,因为像语音、图像生成和媒体理解这样的能力门面,即使智能体轮次本身只检查一个简单的文本响应,也会通过内置运行时 API 加载。
- 该脚本会将嵌套 lane 日志写入 `/tmp/openclaw-parallels-npm-update.*`
假设外层包装器卡住之前,请先检查 `windows-update.log`、`macos-update.log` 或 `linux-update.log`
- Windows 更新在冷启动 guest 上可能会在更新后的 doctor/运行时依赖修复阶段花费 10 到 15 分钟;只要嵌套的 npm 调试日志仍在推进,这是健康状态。
- 不要将这个聚合包装器与单独的 Parallels macOS、Windows 或 Linux smoke lanes 并行运行。它们共享 VM 状态可能会在快照恢复、package 分发或 guest Gateway 网关状态上发生冲突。
- 更新后的验证会运行正常的内置插件表面,因为像 speech、image generation 和 media understanding 这样的 capability facade即使在智能体轮次本身只检查简单文本响应时,也会通过内置运行时 API 加载。
- `pnpm openclaw qa aimock`
- 仅启动本地 AIMock 提供商服务器,用于直接协议冒烟测试。
- 仅启动本地 AIMock 提供商服务器,用于直接协议 smoke 测试。
- `pnpm openclaw qa matrix`
- 针对一次性的 Docker 支持 Tuwunel homeserver 运行 Matrix live QA 测试通道
- 这个 QA 宿主当前仅供仓库 / 开发环境使用。已打包的 OpenClaw 安装不包含 `qa-lab`,因此不会暴露 `openclaw qa`
- 仓库 checkout 会直接加载内置运行器;不需要单独的插件安装步骤
- 预配三个临时 Matrix 用户(`driver`、`sut`、`observer`)和一个私有房间,然后启动一个以真实 Matrix 插件作为 SUT 传输层的 QA Gateway 网关子进程。
- 默认使用固定的稳定版 Tuwunel 镜像 `ghcr.io/matrix-construct/tuwunel:v1.5.1`。当你需要测试其他镜像时,可通过 `OPENCLAW_QA_MATRIX_TUWUNEL_IMAGE` 覆盖。
- Matrix 不暴露共享凭证源标志,因为该测试通道会在本地预配一次性用户。
- 会将 Matrix QA 报告、摘要、observed-events artifact 和合并后的 stdout / stderr 输出日志写入 `.artifacts/qa-e2e/...`
- 默认会输出进度,并通过 `OPENCLAW_QA_MATRIX_TIMEOUT_MS` 强制执行硬运行超时(默认 30 分钟)。清理阶段受 `OPENCLAW_QA_MATRIX_CLEANUP_TIMEOUT_MS` 限制;如果失败,输出中会包含用于恢复的 `docker compose ... down --remove-orphans` 命令
- 针对一次性的 Docker 支持 Tuwunel homeserver 运行 Matrix live QA lane
- 这个 QA 主机目前仅供仓库/开发环境使用。打包后的 OpenClaw 安装不附带 `qa-lab`,因此不会暴露 `openclaw qa`
- 仓库 checkout 会直接加载内置运行器;不需要单独安装插件
- 预配三个临时 Matrix 用户(`driver`、`sut`、`observer`)和一个私有房间,然后启动一个以真实 Matrix 插件作为 SUT 传输层的 QA Gateway 网关子进程。
- 默认使用固定的稳定版 Tuwunel 镜像 `ghcr.io/matrix-construct/tuwunel:v1.5.1`。当你需要测试不同镜像时,可用 `OPENCLAW_QA_MATRIX_TUWUNEL_IMAGE` 覆盖。
- Matrix 不暴露共享的 credential-source 标志,因为该 lane 会在本地预配一次性用户。
- 会`.artifacts/qa-e2e/...` 下写入 Matrix QA 报告、摘要、observed-events artifact以及合并的 stdout/stderr 输出日志
- 默认会输出进度,并通过 `OPENCLAW_QA_MATRIX_TIMEOUT_MS` 强制执行硬性运行超时(默认 30 分钟)。清理由 `OPENCLAW_QA_MATRIX_CLEANUP_TIMEOUT_MS` 限制,失败时会包含恢复命令 `docker compose ... down --remove-orphans`
- `pnpm openclaw qa telegram`
- 使用来自环境变量的 driver 和 SUT 机器人令牌,针对真实私有群组运行 Telegram live QA 测试通道
- 需要 `OPENCLAW_QA_TELEGRAM_GROUP_ID`、`OPENCLAW_QA_TELEGRAM_DRIVER_BOT_TOKEN` 和 `OPENCLAW_QA_TELEGRAM_SUT_BOT_TOKEN`群组 id 必须是 Telegram chat 的数字 id
- 支持 `--credential-source convex` 以使用共享池化凭证。默认使用环境变量模式,或设置 `OPENCLAW_QA_CREDENTIAL_SOURCE=convex` 以启用池化租约。
- 任一场景失败时会以非零状态退出。如果你想保留产物而不返回失败退出码,请使用 `--allow-failures`
- 需要同一个私有群组中的两个不同机器人,并且 SUT 机器人必须公开 Telegram 用户名。
- 为了实现稳定的机器人到机器人观察,请在 `@BotFather` 中为两个机器人启用 Bot-to-Bot Communication Mode并确保 driver 机器人可以观察群组中的机器人流量。
- 会将 Telegram QA 报告、摘要和 observed-messages artifact 写入 `.artifacts/qa-e2e/...`。回复场景会包含从 driver 发送请求到观察到 SUT 回复之间的 RTT。
- 使用环境变量中的 driver 和 SUT bot token针对真实私有群组运行 Telegram live QA lane
- 需要 `OPENCLAW_QA_TELEGRAM_GROUP_ID`、`OPENCLAW_QA_TELEGRAM_DRIVER_BOT_TOKEN` 和 `OPENCLAW_QA_TELEGRAM_SUT_BOT_TOKEN`group id 必须是 Telegram chat id 的数字值
- 支持 `--credential-source convex` 以使用共享凭证。默认使用环境变量模式,或设置 `OPENCLAW_QA_CREDENTIAL_SOURCE=convex` 以启用共享租约。
- 任一场景失败时以非零状态退出。若你想保留产物但不希望退出码失败,请使用 `--allow-failures`
- 需要同一个私有群组中的两个不同 bot并且 SUT bot 需要公开一个 Telegram 用户名。
- 为了稳定地观察 bot 到 bot 通信,请在 `@BotFather` 中为两个 bot 都启用 Bot-to-Bot Communication Mode并确保 driver bot 能观察群组中的 bot 流量。
- 会`.artifacts/qa-e2e/...` 下写入 Telegram QA 报告、摘要和 observed-messages artifact。回复场景还包含从 driver 发送请求到观察到 SUT 回复的 RTT。
live 传输测试通道共享一个标准契约,这样新传输层就不会发生漂移:
Live 传输 lanes 共享一个标准契约,这样新传输层就不会发生漂移:
`qa-channel` 仍然是广的合成 QA 套件,不属于 live 传输覆盖矩阵的一部分。
`qa-channel` 仍然是覆盖面较广的合成 QA 测试套件,不属于 live 传输覆盖矩阵的一部分。
| Lane | Canary | Mention gating | Allowlist block | Top-level reply | Restart resume | Thread follow-up | Thread isolation | Reaction observation | Help command |
| -------- | ------ | -------------- | --------------- | --------------- | -------------- | ---------------- | ---------------- | -------------------- | ------------ |
@ -176,21 +177,21 @@ live 传输测试通道共享一个标准契约,这样新传输层就不会发
### 通过 Convex 共享 Telegram 凭证v1
当为 `openclaw qa telegram` 启用 `--credential-source convex`(或 `OPENCLAW_QA_CREDENTIAL_SOURCE=convex`QA lab 会从一个 Convex 支持的池中获取独占租约,在测试通道运行期间对该租约发送心跳,并在关闭时释放租约。
当为 `openclaw qa telegram` 启用 `--credential-source convex`(或 `OPENCLAW_QA_CREDENTIAL_SOURCE=convex`QA lab 会从 Convex 支持的凭证池中获取一个独占租约,在 lane 运行期间为该租约发送 heartbeat并在关闭时释放该租约。
参考 Convex 项目脚手架:
参考 Convex 项目脚手架:
- `qa/convex-credential-broker/`
必需的环境变量:
- `OPENCLAW_QA_CONVEX_SITE_URL`(例如 `https://your-deployment.convex.site`
- 为所选角色提供的一个密钥
- `OPENCLAW_QA_CONVEX_SECRET_MAINTAINER` 对应 `maintainer`
- `OPENCLAW_QA_CONVEX_SECRET_CI` 对应 `ci`
- 为所选角色提供一个 secret
- `OPENCLAW_QA_CONVEX_SECRET_MAINTAINER` 用于 `maintainer`
- `OPENCLAW_QA_CONVEX_SECRET_CI` 用于 `ci`
- 凭证角色选择:
- CLI`--credential-role maintainer|ci`
- 环境变量默认值:`OPENCLAW_QA_CREDENTIAL_ROLE`(在 CI 中默认是 `ci`,否则 `maintainer`
- 环境变量默认值:`OPENCLAW_QA_CREDENTIAL_ROLE`(在 CI 中默认是 `ci`,否则默认是 `maintainer`
可选环境变量:
@ -199,12 +200,12 @@ live 传输测试通道共享一个标准契约,这样新传输层就不会发
- `OPENCLAW_QA_CREDENTIAL_ACQUIRE_TIMEOUT_MS`(默认 `90000`
- `OPENCLAW_QA_CREDENTIAL_HTTP_TIMEOUT_MS`(默认 `15000`
- `OPENCLAW_QA_CONVEX_ENDPOINT_PREFIX`(默认 `/qa-credentials/v1`
- `OPENCLAW_QA_CREDENTIAL_OWNER_ID`(可选追踪 id
- `OPENCLAW_QA_ALLOW_INSECURE_HTTP=1` 允许仅用于本地开发的 loopback `http://` Convex URL。
- `OPENCLAW_QA_CREDENTIAL_OWNER_ID`(可选追踪 id
- `OPENCLAW_QA_ALLOW_INSECURE_HTTP=1` 允许在仅限本地开发时使用 loopback `http://` Convex URL。
正常运行时`OPENCLAW_QA_CONVEX_SITE_URL` 应使用 `https://`
在正常运行中`OPENCLAW_QA_CONVEX_SITE_URL` 应使用 `https://`
维护者管理员命令(池添加 / 删除 / 列表)必须专门使用
维护者管理命令(池的添加/删除/列出)必须明确使用
`OPENCLAW_QA_CONVEX_SECRET_MAINTAINER`
面向维护者的 CLI 辅助命令:
@ -216,86 +217,85 @@ pnpm openclaw qa credentials list --kind telegram
pnpm openclaw qa credentials remove --credential-id <credential-id>
```
在 live 运行前使用 `doctor`,检查 Convex 站点 URL、broker 密钥、
endpoint prefix、HTTP 超时以及 admin / list 可达性,而不会打印密钥值。在脚本和 CI 工具中使用 `--json` 可获得机器可读输出。
在 live 运行之前使用 `doctor`,可在不打印 secret 值的情况下检查 Convex 站点 URL、broker secret、endpoint prefix、HTTP 超时,以及 admin/list 可达性。在脚本和 CI 工具中可使用 `--json` 获取机器可读输出。
默认端点契约(`OPENCLAW_QA_CONVEX_SITE_URL` + `/qa-credentials/v1`
默认 endpoint 契约(`OPENCLAW_QA_CONVEX_SITE_URL` + `/qa-credentials/v1`
- `POST /acquire`
- 请求:`{ kind, ownerId, actorRole, leaseTtlMs, heartbeatIntervalMs }`
- 成功:`{ status: "ok", credentialId, leaseToken, payload, leaseTtlMs?, heartbeatIntervalMs? }`
- 耗尽 / 可重试:`{ status: "error", code: "POOL_EXHAUSTED" | "NO_CREDENTIAL_AVAILABLE", ... }`
- 耗尽/可重试:`{ status: "error", code: "POOL_EXHAUSTED" | "NO_CREDENTIAL_AVAILABLE", ... }`
- `POST /heartbeat`
- 请求:`{ kind, ownerId, actorRole, credentialId, leaseToken, leaseTtlMs }`
- 成功:`{ status: "ok" }`(或空的 `2xx`
- `POST /release`
- 请求:`{ kind, ownerId, actorRole, credentialId, leaseToken }`
- 成功:`{ status: "ok" }`(或空的 `2xx`
- `POST /admin/add`(仅维护者密钥
- `POST /admin/add`(仅 maintainer secret
- 请求:`{ kind, actorId, payload, note?, status? }`
- 成功:`{ status: "ok", credential }`
- `POST /admin/remove`(仅维护者密钥
- `POST /admin/remove`(仅 maintainer secret
- 请求:`{ credentialId, actorId }`
- 成功:`{ status: "ok", changed, credential }`
- 活跃租约保护:`{ status: "error", code: "LEASE_ACTIVE", ... }`
- `POST /admin/list`(仅维护者密钥
- `POST /admin/list`(仅 maintainer secret
- 请求:`{ kind?, status?, includePayload?, limit? }`
- 成功:`{ status: "ok", credentials, count }`
Telegram 类型的载荷结构:
Telegram 类型的 payload 结构:
- `{ groupId: string, driverToken: string, sutToken: string }`
- `groupId` 必须是 Telegram chat 的数字 id 字符串。
- `admin/add``kind: "telegram"` 验证该结构,并拒绝格式错误的载荷
- `groupId` 必须是 Telegram chat id 的数字字符串。
- `admin/add``kind: "telegram"` 验证此结构,并拒绝格式错误的 payload
### 向 QA 添加一个渠道
向 Markdown QA 系统添加一个渠道,严格来说只需要两样东西:
向 Markdown QA 系统添加一个渠道,严格只需要两样东西:
1. 该渠道的传输适配器。
2. 一个用于测试该渠道契约的场景包。
2. 一个用于验证渠道契约的场景包。
如果共享的 `qa-lab` 宿主可以承载流程,就不要新增顶级 QA 命令根。
如果共享的 `qa-lab` 主机可以承载该流程,就不要添加新的顶级 QA 命令根。
`qa-lab` 负责共享宿主机制:
`qa-lab` 负责共享主机制:
- `openclaw qa` 命令根
- 套件启动和拆除
- 工作进程并发
- 测试套件启动与关闭
- worker 并发
- artifact 写入
- 报告生成
- 场景执行
- 对旧 `qa-channel` 场景的兼容别名
- 对旧 `qa-channel` 场景的兼容别名
运行器插件负责传输契约:
- `openclaw qa <runner>` 如何挂载到共享 `qa` 根下
- 如何将 `openclaw qa <runner>` 挂载到共享 `qa` 根下
- 如何为该传输层配置 Gateway 网关
- 如何检查就绪状态
- 如何注入入站事件
- 如何观察出站消息
- 如何暴露转录和规范化后的传输状态
- 如何执行传输层支持的操
- 如何处理传输层专属的重置或清理
- 如何暴露 transcript 和规范化后的传输状态
- 如何执行由传输层支撑的动
- 如何处理传输层特定的重置或清理
新渠道的最低采用门槛是:
1. 保持 `qa-lab` 作为共享 `qa` 根的有者。
2. 在共享的 `qa-lab` 宿主接缝上实现传输运行器。
3. 将传输层专属机制保留在运行器插件或渠道 harness 内部。
1. 保持 `qa-lab` 作为共享 `qa` 根的有者。
2. 在共享的 `qa-lab` 主机接口上实现传输运行器。
3. 将传输层特定机制保留在运行器插件或渠道 harness 内部。
4. 将运行器挂载为 `openclaw qa <runner>`,而不是注册一个相互竞争的根命令。
运行器插件应在 `openclaw.plugin.json` 中声明 `qaRunners`,并从 `runtime-api.ts` 导出匹配`qaRunnerCliRegistrations` 数组。
保持 `runtime-api.ts` 轻量;延迟 CLI 和运行器执行应保留在单独的入口点之后。
5. 在按主题划分的 `qa/scenarios/` 目录下编写或改造 Markdown 场景。
运行器插件应在 `openclaw.plugin.json` 中声明 `qaRunners`,并从 `runtime-api.ts` 导出对应`qaRunnerCliRegistrations` 数组。
保持 `runtime-api.ts` 轻量;惰性 CLI 和运行器执行应位于独立入口点之后。
5. 在按主题组织的 `qa/scenarios/` 目录下编写或调整 Markdown 场景。
6. 为新场景使用通用场景辅助函数。
7. 除非仓库正在进行有意迁移,否则保持现有兼容别名继续可用。
7. 除非仓库正在进行有意迁移,否则保持现有兼容别名可用。
决策规则严格:
决策规则非常严格:
- 如果某个行为可以在 `qa-lab` 中统一表达一次,就把它放 `qa-lab`
- 如果某个行为依赖单一渠道传输层,就把它保留在运行器插件或插件 harness 中。
- 如果某个场景需要一个多个渠道都可用的新能力,就添加一个通用辅助函数,而不是在 `suite.ts` 中加入渠道专用分支。
- 如果某个行为只对一种传输层有意义,就让该场景保持传输层专用,并在场景契约中明确说明。
- 如果某个行为可以在 `qa-lab` 中统一表达一次,就把它放 `qa-lab`
- 如果某个行为依赖单一渠道传输层,就把它保留在对应的运行器插件或插件 harness 中。
- 如果某个场景需要一种超过一个渠道都能使用的新能力,就添加一个通用辅助函数,而不是在 `suite.ts` 中加入渠道特定分支。
- 如果某个行为只对一种传输层有意义,就让场景保持传输层特定性,并在场景契约中明确说明。
新场景推荐使用的通用辅助函数名称是:
@ -323,85 +323,85 @@ Telegram 类型的载荷结构:
新的渠道工作应使用通用辅助函数名称。
兼容别名的存在是为了避免一次性强制迁移,而不是作为新场景编写的范式。
## 测试套件(哪些内容在哪里运行
## 测试套件(各自运行在哪里
可以把这些套件理解为“真实度逐步提升”(同时不稳定性 / 成本也逐步增加
可以把这些测试套件理解为“真实度逐步提高”(同时也更容易波动、成本更高
### 单元 / 集成(默认)
### Unit / integration(默认)
- 命令:`pnpm test`
- 配置:未定向运行使用 `vitest.full-*.config.ts` 分片集合,并可能将多项目分片展开为按项目划分的配置,以便并行调度
- 文件:核心 / 单元清单位于 `src/**/*.test.ts`、`packages/**/*.test.ts`、`test/**/*.test.ts`,以及由 `vitest.unit.config.ts` 覆盖的白名单 `ui` Node 测试
- 配置:未定向运行使用 `vitest.full-*.config.ts` 分片集合,并可能将多项目分片展开为按项目划分的配置,以便并行调度
- 文件:核心/unit 清单位于 `src/**/*.test.ts`、`packages/**/*.test.ts`、`test/**/*.test.ts`,以及由 `vitest.unit.config.ts` 覆盖并列入白名单的 `ui` node 测试
- 范围:
- 纯单元测试
- 进程内集成测试Gateway 网关证、路由、工具、解析、配置)
- 已知缺陷的确定性回归测试
- 进程内集成测试Gateway 网关证、路由、工具、解析、配置)
- 已知 bug 的确定性回归测试
- 预期:
- 在 CI 中运行
- 不需要真实密钥
- 应该快速且稳定
<AccordionGroup>
<Accordion title="项目、分片和作用域测试通道">
<Accordion title="项目、分片和定向 lanes">
- 未定向的 `pnpm test` 会运行 12 个更小的分片配置(`core-unit-fast`、`core-unit-src`、`core-unit-security`、`core-unit-ui`、`core-unit-support`、`core-support-boundary`、`core-contracts`、`core-bundled`、`core-runtime`、`agentic`、`auto-reply`、`extensions`),而不是一个庞大的原生根项目进程。这样可以降低高负载机器上的峰值 RSS并避免 auto-reply / 扩展工作拖慢无关套件。
- `pnpm test --watch` 仍然使用原生根 `vitest.config.ts` 项目图,因为多分片监听循环并不现实。
- `pnpm test`、`pnpm test:watch` 和 `pnpm test:perf:imports` 现在会优先通过作用域测试通道路由显式文件 / 目录目标,因此 `pnpm test extensions/discord/src/monitor/message-handler.preflight.test.ts` 不需要承担完整根项目启动开销
- `pnpm test:changed` 默认会将 git 变更路径展开为廉价的作用域测试通道:直接测试编辑、同级 `*.test.ts` 文件、显式源码映射,以及本地导入图依赖项。配置 / setup / package 编辑不会广泛运行测试,除非你显式使用 `OPENCLAW_TEST_CHANGED_BROAD=1 pnpm test:changed`
- `pnpm check:changed` 是针对小范围工作常规使用的智能本地检查门禁。它会将 diff 分类为 core、core tests、extensions、extension tests、apps、docs、release metadata、live Docker tooling 和 tooling然后运行匹配的类型检查、lint 和守卫命令。它不会运行 Vitest 测试;测试证明请调用 `pnpm test:changed` 或显式 `pnpm test <target>`。仅包含发布元数据的版本提升会运行有针对性的版本 / 配置 / 根依赖检查,并带有一个守卫,用于拒绝顶级 version 字段之外的 package 变更。
- live Docker ACP harness 编辑会运行聚焦检查:对 live Docker 认证脚本进行 shell 语法检查,以及执行 live Docker 调度器 dry-run。只有在 diff 仅限于 `scripts["test:docker:live-*"]` 时才包含 `package.json` 变更;依赖、导出、版本以及其他 package 表面编辑仍然使用更广泛的守卫
- 来自 agents、commands、plugins、auto-reply 辅助函数、`plugin-sdk` 以及类似纯工具区域的轻导入单元测试,会路由到 `unit-fast` 测试通道,该通道会跳过 `test/setup-openclaw-runtime.ts`;有状态 / 运行时较重的文件仍保留在现有测试通道上
- 部分选定的 `plugin-sdk``commands` 辅助源码文件也会在 changed 模式运行中映射到这些轻量测试通道中的显式同级测试,因此辅助函数编辑可以避免为该目录重新运行整个重型套件。
- `auto-reply` 为顶级 core 辅助函数、顶级 `reply.*` 集成测试,以及 `src/auto-reply/reply/**` 子树提供了专用分桶。CI 还会将 reply 子树进一步拆分为 agent-runner、dispatch 和 commands / state-routing 分片,这样某个导入较重的分桶就不会占据整个 Node 尾部时间。
- 未定向的 `pnpm test` 会运行十二个更小的分片配置(`core-unit-fast`、`core-unit-src`、`core-unit-security`、`core-unit-ui`、`core-unit-support`、`core-support-boundary`、`core-contracts`、`core-bundled`、`core-runtime`、`agentic`、`auto-reply`、`extensions`),而不是启动一个庞大的原生根项目进程。这样可以降低高负载机器上的峰值 RSS并避免 auto-reply/extension 工作拖累无关的测试套件。
- `pnpm test --watch` 仍然使用原生根 `vitest.config.ts` 项目图,因为多分片 watch 循环并不现实。
- `pnpm test`、`pnpm test:watch` 和 `pnpm test:perf:imports` 会先将显式的文件/目录目标路由到定向 lanes因此 `pnpm test extensions/discord/src/monitor/message-handler.preflight.test.ts` 不必承担完整根项目启动的成本
- `pnpm test:changed` 默认会将变更的 git 路径展开为低成本的定向 lanes直接修改的测试、同级 `*.test.ts` 文件、显式源映射以及本地导入图的依赖项。配置/setup/package 修改不会触发大范围测试,除非你显式使用 `OPENCLAW_TEST_CHANGED_BROAD=1 pnpm test:changed`
- `pnpm check:changed` 是针对小范围工作常规使用的智能本地检查门禁。它会将 diff 分类到 core、core tests、extensions、extension tests、apps、docs、发布元数据、live Docker 工具链和工具然后运行相应的类型检查、lint 和 guard 命令。它不会运行 Vitest 测试;如需测试证明,请调用 `pnpm test:changed` 或显式运行 `pnpm test <target>`。仅发布元数据的版本号提升会运行有针对性的版本/配置/根依赖检查,并带有一个 guard用于拒绝顶层版本字段之外的 package 变更。
- live Docker ACP harness 的修改会运行聚焦检查:对 live Docker auth 脚本做 shell 语法检查,以及执行一次 live Docker 调度器 dry-run。只有当 diff 仅限于 `scripts["test:docker:live-*"]` 时才包含 `package.json` 变更;依赖、导出、版本和其他 package 表面修改仍会走更宽泛的 guard
- 来自 agents、commands、plugins、auto-reply 辅助函数、`plugin-sdk` 以及类似纯工具区域的轻导入 unit 测试,会被路由到 `unit-fast` lane其中跳过 `test/setup-openclaw-runtime.ts`;有状态/运行时较重的文件则保留在现有 lanes 中
- 一些选定的 `plugin-sdk``commands` 辅助源文件也会将 changed 模式运行映射到这些轻量 lanes 中的显式同级测试,因此辅助函数修改不必为该目录重跑完整的重型测试套件。
- `auto-reply` 为顶层 core 辅助函数、顶层 `reply.*` 集成测试,以及 `src/auto-reply/reply/**` 子树提供了专用分桶。CI 还会进一步将 reply 子树拆分为 agent-runner、dispatch 和 commands/state-routing 分片,这样就不会让某个导入开销很重的分桶独占完整的 Node 尾部时间。
</Accordion>
<Accordion title="嵌入式运行器覆盖">
<Accordion title="嵌入式运行器覆盖范围">
- 当你更改消息工具发现输入或压缩运行时上下文时,请同时保持两个层级的覆盖。
- 为纯路由和规范化边界添加聚焦的辅助函数回归测试。
- 保持嵌入式运行器集成套件健康:
- 当你修改消息工具发现输入或 compaction 运行时上下文时,要同时保持这两级覆盖。
- 为纯路由和规范化边界添加有针对性的辅助函数回归测试。
- 保持嵌入式运行器集成测试套件健康:
`src/agents/pi-embedded-runner/compact.hooks.test.ts`
`src/agents/pi-embedded-runner/run.overflow-compaction.test.ts`
`src/agents/pi-embedded-runner/run.overflow-compaction.loop.test.ts`
- 这些套件会验证作用域 id 和压缩行为仍然会流经真实的 `run.ts` / `compact.ts` 路径;仅有辅助函数测试不足以替代这些集成路径。
- 这些测试套件会验证作用域 id 和 compaction 行为仍然会通过真实的 `run.ts` / `compact.ts` 路径流动;仅有辅助函数级别的测试不足以替代这些集成路径。
</Accordion>
<Accordion title="Vitest 池和隔离默认值">
- 基础 Vitest 配置默认使用 `threads`
- 共享 Vitest 配置固定 `isolate: false`并在根项目、e2e 和 live 配置中使用非隔离运行器。
- 根 UI 测试通道保留其 `jsdom` setup 和 optimizer但也运行在共享的非隔离运行器上。
- 共享 Vitest 配置固定使用 `isolate: false`并在根项目、e2e 和 live 配置中用非隔离运行器。
- 根 UI lane 保留其 `jsdom` setup 和 optimizer但也运行在共享的非隔离运行器上。
- 每个 `pnpm test` 分片都从共享 Vitest 配置继承相同的 `threads` + `isolate: false` 默认值。
- `scripts/run-vitest.mjs` 默认会为 Vitest 子 Node 进程添加 `--no-maglev`,以减少大型本地运行期间的 V8 编译抖动。设置 `OPENCLAW_VITEST_ENABLE_MAGLEV=1` 可与原生 V8 行为进行比。
- `scripts/run-vitest.mjs` 默认会为 Vitest 子 Node 进程添加 `--no-maglev`,以减少大型本地运行期间的 V8 编译抖动。设置 `OPENCLAW_VITEST_ENABLE_MAGLEV=1` 可与原生 V8 行为进行比
</Accordion>
<Accordion title="快速本地迭代">
- `pnpm changed:lanes` 会显示某个 diff 会触发哪些架构测试通道
- pre-commit hook 负责格式化。它会重新暂存已格式化文件,不会运行 lint、类型检查或测试。
- `pnpm changed:lanes` 会显示一个 diff 会触发哪些架构 lanes
- pre-commit hook 负责格式化。它会重新暂存已格式化文件,不会运行 lint、类型检查或测试。
- 当你需要智能本地检查门禁时,请在交接或 push 前显式运行 `pnpm check:changed`
- `pnpm test:changed` 默认通过廉价的作用域测试通道路由。仅当智能体判断 harness、配置、package 或契约编辑确实需要更广泛的 Vitest 覆盖时,才使用 `OPENCLAW_TEST_CHANGED_BROAD=1 pnpm test:changed`
- `pnpm test:max``pnpm test:changed:max` 保持相同的路由行为,只是使用更高的工作进程上限
- 本地工作进程自动扩缩容有意保持保守;当宿主机负载平均值已经较高时会主动回退,因此默认情况下多个并发 Vitest 运行造成的破坏会更小。
- 基础 Vitest 配置将项目 / 配置文件标记为 `forceRerunTriggers`从而在测试接线变更时changed 模式重跑仍然保持正确
- 在受支持的宿主机上,该配置会保持启用 `OPENCLAW_VITEST_FS_MODULE_CACHE`;如果你希望为直接性能分析指定一个明确的缓存位置,可设置 `OPENCLAW_VITEST_FS_MODULE_CACHE_PATH=/abs/path`
- `pnpm test:changed` 默认通过低成本的定向 lanes 路由。只有当智能体判断 harness、配置、package 或契约修改确实需要更广泛的 Vitest 覆盖时,才使用 `OPENCLAW_TEST_CHANGED_BROAD=1 pnpm test:changed`
- `pnpm test:max``pnpm test:changed:max` 保持相同的路由行为,只是 worker 上限更高
- 本地 worker 自动伸缩有意保持保守;当主机负载均值已经较高时会回退,因此默认情况下多个并发 Vitest 运行造成的影响更小。
- 基础 Vitest 配置将项目/配置文件标记为 `forceRerunTriggers`因此当测试接线发生变化时changed 模式重跑仍然是正确的
- 该配置会在受支持的主机上保持启用 `OPENCLAW_VITEST_FS_MODULE_CACHE`;如果你希望为直接性能分析指定一个明确的缓存位置,可设置 `OPENCLAW_VITEST_FS_MODULE_CACHE_PATH=/abs/path`
</Accordion>
<Accordion title="性能调试">
- `pnpm test:perf:imports` 会启用 Vitest 导入耗时报告以及导入拆解输出。
- `pnpm test:perf:imports:changed` 会将同的分析视图限定到自 `origin/main` 以来发生变的文件。
- 分片时数据会写入 `.artifacts/vitest-shard-timings.json`
体配置运行以配置路径作为键include-pattern CI 分片会追加分片名称,以便单独跟踪过滤后的分片。
- 当某个热点测试的大部分时间仍消耗在启动导入上时,请将重依赖放在狭窄的本地 `*.runtime.ts` 接缝之后,并直接 mock 该接缝,而不是为了通过 `vi.mock(...)` 传递它们就深度导入运行时辅助函数。
- `pnpm test:perf:changed:bench -- --ref <git-ref>`针对该已提交 diff对路由后的 `test:changed` 与原生根项目路径进行比较,并输出 wall time 以及 macOS 最大 RSS。
- `pnpm test:perf:changed:bench -- --worktree` 会通过 `scripts/test-projects.mjs` 和根 Vitest 配置,对当前有未提交更改的工作树进行基准测试
- `pnpm test:perf:profile:main` 会为 Vitest / Vite 启动和 transform 开销写入主线程 CPU profile。
- `pnpm test:perf:profile:runner` 会在关闭文件并行的情况下,为单元测试套件写入 runner CPU + heap profiles
- `pnpm test:perf:imports` 会启用 Vitest 导入耗时报告以及导入细分输出。
- `pnpm test:perf:imports:changed` 会将同的性能分析视图限定到自 `origin/main` 以来发生变的文件。
- 分片时数据会写入 `.artifacts/vitest-shard-timings.json`
个配置运行使用配置路径作为键;包含模式的 CI 分片会附加分片名称,以便单独跟踪经过筛选的分片。
- 当某个热点测试的大部分时间仍消耗在启动导入上时,请将重依赖放在狭窄的本地 `*.runtime.ts` 接缝之后,并直接 mock 这个接缝,而不是为了通过 `vi.mock(...)` 转发它们就深度导入运行时辅助函数。
- `pnpm test:perf:changed:bench -- --ref <git-ref>`将经路由的 `test:changed` 与该已提交 diff 的原生根项目路径进行比较,并打印 wall time 以及 macOS 最大 RSS。
- `pnpm test:perf:changed:bench -- --worktree` 会通过 `scripts/test-projects.mjs` 和根 Vitest 配置,将当前未提交工作树中的变更文件列表进行路由,并执行性能基准
- `pnpm test:perf:profile:main` 会为 Vitest/Vite 启动和转换开销写入主线程 CPU profile。
- `pnpm test:perf:profile:runner` 会在禁用文件并行的情况下,为 unit 测试套件写入运行器 CPU + heap profile
</Accordion>
</AccordionGroup>
@ -409,282 +409,283 @@ Telegram 类型的载荷结构:
### 稳定性Gateway 网关)
- 命令:`pnpm test:stability:gateway`
- 配置:`vitest.gateway.config.ts`,强制使用单个工作进程
- 配置:`vitest.gateway.config.ts`,强制使用单个 worker
- 范围:
- 启动一个默认启用诊断的真实 loopback Gateway 网关
- 通过诊断事件路径驱动合成的 Gateway 网关消息、内存和大载荷抖动
- 启动一个默认启用诊断功能的真实 loopback Gateway 网关
- 通过诊断事件路径驱动合成的 gateway 消息、memory 和大负载 churn
- 通过 Gateway 网关 WS RPC 查询 `diagnostics.stability`
- 覆盖诊断稳定性 bundle 持久化辅助函数
- 断言记录器保持有界,合成 RSS 样本保持在压力预算之下,并且每个会话的队列深度会回落到零
- 断言 recorder 仍保持有界、合成 RSS 样本低于压力预算,并且每个 session 的队列深度会回落到零
- 预期:
- 对 CI 安全且不需要密钥
- 这是一个用于稳定性回归跟进的窄测试通道,不是完整 Gateway 网关套件的替代品
- 对 CI 安全且无需密钥
- 是一个用于稳定性回归后续跟进的窄 lane而不是完整 Gateway 网关测试套件的替代品
### E2EGateway 网关冒烟测试
### E2EGateway 网关 smoke
- 命令:`pnpm test:e2e`
- 配置:`vitest.e2e.config.ts`
- 文件:`src/**/*.e2e.test.ts`、`test/**/*.e2e.test.ts`,以及 `extensions/` 下的内置插件 E2E 测试
- 运行时默认值:
- 使用 Vitest `threads` 并设置 `isolate: false`,与仓库其余部分保持一致。
- 使用自适应工作进程CI最多 2 个,本地:默认 1 个)。
- 默认以静默模式运行,以降低控制台 I/O 开销。
- 使用 Vitest `threads` `isolate: false`,与仓库其余部分保持一致。
- 使用自适应 workerCI最多 2 个,本地默认 1 个)。
- 默认以 silent 模式运行,以减少控制台 I/O 开销。
- 常用覆盖项:
- 使用 `OPENCLAW_E2E_WORKERS=<n>` 强制指定工作进程数量(上限为 16
- 使用 `OPENCLAW_E2E_VERBOSE=1` 重新启用详细控制台输出。
- `OPENCLAW_E2E_WORKERS=<n>`:强制指定 worker 数量(上限为 16
- `OPENCLAW_E2E_VERBOSE=1`重新启用详细控制台输出。
- 范围:
- 多实例 Gateway 网关端到端行为
- WebSocket / HTTP 表面、节点配对和更重的网络交互
- WebSocket/HTTP 表面、节点配对,以及更重型的网络行为
- 预期:
- 会在 CI 中运行(当流水线启用时)
- 在 CI 中运行(当 pipeline 启用时)
- 不需要真实密钥
- 比单元测试包含更多可变部分(可能更慢)
- 比 unit 测试涉及更多活动部件(可能更慢)
### E2EOpenShell 后端冒烟测试
### E2EOpenShell 后端 smoke
- 命令:`pnpm test:e2e:openshell`
- 文件:`extensions/openshell/src/backend.e2e.test.ts`
- 范围:
- 通过 Docker 在宿主机上启动一个隔离的 OpenShell Gateway 网关
- 临时本地 Dockerfile 创建一个沙箱
- 通过真实的 `sandbox ssh-config` + SSH exec 测试 OpenClaw 的 OpenShell 后端
- 通过沙箱 fs bridge 验证远端规范文件系统行为
- 通过 Docker 在主机上启动一个隔离的 OpenShell Gateway 网关
- 通过一个临时本地 Dockerfile 创建一个沙箱
- 通过真实的 `sandbox ssh-config` + SSH exec 来验证 OpenClaw 的 OpenShell 后端
- 通过沙箱文件系统桥验证远端规范文件系统行为
- 预期:
- 仅按需启用;不属于默认 `pnpm test:e2e` 运行的一部分
- 需要本地 `openshell` CLI 和可用的 Docker daemon
- 使用隔离的 `HOME` / `XDG_CONFIG_HOME`,然后销毁测试 Gateway 网关和沙箱
- 常用覆盖项:
- 运行更广泛 e2e 套件时,设置 `OPENCLAW_E2E_OPENSHELL=1`启用该测试
- 设置 `OPENCLAW_E2E_OPENSHELL_COMMAND=/path/to/openshell`,指向非默认 CLI 二进制或包装脚本
- `OPENCLAW_E2E_OPENSHELL=1`:在手动运行更广泛的 e2e 测试套件时启用该测试
- `OPENCLAW_E2E_OPENSHELL_COMMAND=/path/to/openshell`:指向一个非默认 CLI 二进制文件或包装脚本
### Live真实提供商 + 真实模型)
- 命令:`pnpm test:live`
- 配置:`vitest.live.config.ts`
- 文件:`src/**/*.live.test.ts`、`test/**/*.live.test.ts`,以及 `extensions/` 下的内置插件 live 测试
- 默认值:由 `pnpm test:live` **启用**设置 `OPENCLAW_LIVE_TEST=1`
- 默认值:由 `pnpm test:live` **启用**(设置 `OPENCLAW_LIVE_TEST=1`
- 范围:
- “这个提供商 / 模型 _今天_ 在真实凭证下是否真的可用?”
- 捕获提供商格式变化、工具调用怪癖、认证问题和限流行为
- “这个提供商/模型 _今天_ 配合真实凭证是否真的可用?”
- 捕获提供商格式变化、工具调用怪癖、认证问题以及速率限制行为
- 预期:
- 按设计来说不具备 CI 稳定性(真实网络、真实提供商策略、配额、故障)
- 会花钱 / 消耗限流额度
- 按设计不具备 CI 稳定性(真实网络、真实提供商策略、配额、故障)
- 会花钱 / 占用速率限制
- 优先运行缩小范围的子集,而不是“全部”
- live 运行会 source `~/.profile` 以获取缺失的 API key。
- 默认情况下live 运行仍然会隔离 `HOME`,并将配置 / 认证材料复制到临时测试 home 中,以便单元测试 fixture 不会修改你真实的 `~/.openclaw`
- 仅当你有意让 live 测试使用真实 home 目录时,才设置 `OPENCLAW_LIVE_USE_REAL_HOME=1`
- `pnpm test:live` 现在默认使用更安静的模式:它会保留 `[live] ...` 进度输出,但会隐藏额外的 `~/.profile` 提示,并静音 Gateway 网关启动日志 / Bonjour 杂音。若要恢复完整启动日志,请设置 `OPENCLAW_LIVE_TEST_QUIET=0`
- API key 轮换(按提供商区分):设置逗号 / 分号格式的 `*_API_KEYS`,或设置 `*_API_KEY_1`、`*_API_KEY_2`(例如 `OPENAI_API_KEYS`、`ANTHROPIC_API_KEYS`、`GEMINI_API_KEYS`也可通过 `OPENCLAW_LIVE_*_KEY` 为单次 live 运行覆盖;测试会在收到限流响应时重试。
- 进度 / 心跳输出:
- live 套件现在会将进度行输出到 stderr,因此即使 Vitest 控制台捕获处于安静模式,长时间提供商调用也能显示仍在活动。
- `vitest.live.config.ts` 会禁用 Vitest 控制台拦截,因此在 live 运行期间,提供商 / Gateway 网关进度行会立即流式输出。
- 使用 `OPENCLAW_LIVE_HEARTBEAT_MS` 调整直接模型心跳
- 使用 `OPENCLAW_LIVE_GATEWAY_HEARTBEAT_MS` 调整 Gateway 网关 / 探测心跳
- Live 运行会 source `~/.profile`,以补齐缺失的 API key。
- 默认情况下live 运行仍会隔离 `HOME`,并将配置/认证材料复制到一个临时测试 home 中,这样 unit fixture 就不会修改你的真实 `~/.openclaw`
- 仅当你明确需要 live 测试使用真实 home 目录时,才设置 `OPENCLAW_LIVE_USE_REAL_HOME=1`
- `pnpm test:live` 现在默认采用更安静的模式:保留 `[live] ...` 进度输出,但会抑制额外的 `~/.profile` 提示,并静音 gateway 启动日志/Bonjour 噪声。如需恢复完整启动日志,请设置 `OPENCLAW_LIVE_TEST_QUIET=0`
- API key 轮换(按提供商区分):设置逗号/分号格式的 `*_API_KEYS` `*_API_KEY_1`、`*_API_KEY_2`(例如 `OPENAI_API_KEYS`、`ANTHROPIC_API_KEYS`、`GEMINI_API_KEYS`或者通过 `OPENCLAW_LIVE_*_KEY` 为 live 运行单独覆盖;测试会在遇到速率限制响应时重试。
- 进度/heartbeat 输出:
- Live 测试套件现在会向 stderr 发出进度行,因此即使 Vitest 控制台捕获处于安静模式,长时间提供商调用也能清楚显示仍在活动。
- `vitest.live.config.ts` 会禁用 Vitest 控制台拦截,因此在 live 运行期间,提供商/Gateway 网关进度行会立即流式输出。
- 使用 `OPENCLAW_LIVE_HEARTBEAT_MS` 调整 direct-model heartbeat
- 使用 `OPENCLAW_LIVE_GATEWAY_HEARTBEAT_MS` 调整 gateway/probe heartbeat
## 我应该运行哪个套件?
## 我应该运行哪个测试套件?
使用这张决策表:
使用下面这张决策表:
- 编辑逻辑 / 测试:运行 `pnpm test`(如果你改动很多,再加上 `pnpm test:coverage`
- 涉及 Gateway 网关网络 / WS 协议 / 配对:补充运行 `pnpm test:e2e`
- 调试“我的机器人挂了” / 提供商专属故障 / 工具调用:运行缩小范围的 `pnpm test:live`
- 修改逻辑/测试:运行 `pnpm test`(如果你改动很多,再加上 `pnpm test:coverage`
- 触及 Gateway 网关网络 / WS 协议 / 配对:再加上 `pnpm test:e2e`
- 调试“我的 bot 挂了”/ 提供商特定故障 / 工具调用:运行一个缩小范围的 `pnpm test:live`
## Live触网测试
## Live触网)测试
关于 live 模型矩阵、CLI 后端冒烟测试、ACP 冒烟测试、Codex app-server harness以及所有媒体提供商 live 测试Deepgram、BytePlus国际版、ComfyUI、image、music、video、media harness——以及 live 运行的凭证处理——请参阅
[测试 — live 套件](/zh-CN/help/testing-live)。
关于 live 模型矩阵、CLI 后端 smoke、ACP smoke、Codex app-server harness以及所有媒体提供商 live 测试Deepgram、BytePlus、ComfyUI、图像、音乐、视频、媒体 harness——以及 live 运行的凭证处理——请参阅 [测试 — live suites](/zh-CN/help/testing-live)。
## Docker 运行器(可选的“在 Linux 中可”检查)
## Docker 运行器(可选的“在 Linux 中可运行”检查)
这些 Docker 运行器分为两类:
- live 模型运行器:`test:docker:live-models` 和 `test:docker:live-gateway` 仅在仓库 Docker 镜像内运行各自匹配 profile-key 的 live 文件(`src/agents/models.profiles.live.test.ts` 和 `src/gateway/gateway-models.profiles.live.test.ts`挂载你的本地配置目录和工作区(如果已挂载,还会 source `~/.profile`)。对应的本地入口点是 `test:live:models-profiles``test:live:gateway-profiles`
- Docker live 运行器默认采用更小的冒烟测试上限,以便完整的 Docker 扫描仍然可行:
`test:docker:live-models` 默认设置 `OPENCLAW_LIVE_MAX_MODELS=12`,而
`test:docker:live-gateway` 默认设置 `OPENCLAW_LIVE_GATEWAY_SMOKE=1`
- Live 模型运行器:`test:docker:live-models` 和 `test:docker:live-gateway` 只会在仓库 Docker 镜像中运行与其对应的 profile-key live 文件(`src/agents/models.profiles.live.test.ts` 和 `src/gateway/gateway-models.profiles.live.test.ts`并挂载你的本地配置目录与工作区(如果已挂载,也会 source `~/.profile`)。对应的本地入口点是 `test:live:models-profiles``test:live:gateway-profiles`
- Docker live 运行器默认使用较小的 smoke 上限,以便完整的 Docker 扫描仍然可行:
`test:docker:live-models` 默认使用 `OPENCLAW_LIVE_MAX_MODELS=12`,而
`test:docker:live-gateway` 默认使用 `OPENCLAW_LIVE_GATEWAY_SMOKE=1`
`OPENCLAW_LIVE_GATEWAY_MAX_MODELS=8`
`OPENCLAW_LIVE_GATEWAY_STEP_TIMEOUT_MS=45000`
`OPENCLAW_LIVE_GATEWAY_MODEL_TIMEOUT_MS=90000`。当你明确想要执行更大的穷尽式扫描时,可覆盖这些环境变量。
- `test:docker:all` 会先通过 `test:docker:live-build` 构建一次 live Docker 镜像,再通过 `scripts/package-openclaw-for-docker.mjs` 将 OpenClaw 打包一次为 npm tarball随后构建 / 复用两个 `scripts/e2e/Dockerfile` 镜像。裸镜像仅包含用于 install / update / plugin-dependency 测试通道的 Node / Git 运行器;这些测试通道会挂载预构建 tarball。功能镜像则将同一个 tarball 安装到 `/app` 中,用于 built-app 功能测试通道。Docker 测试通道定义位于 `scripts/lib/docker-e2e-scenarios.mjs`;规划逻辑位于 `scripts/lib/docker-e2e-plan.mjs``scripts/test-docker-all.mjs` 会执行所选计划。该聚合器使用带权重的本地调度器:`OPENCLAW_DOCKER_ALL_PARALLELISM` 控制进程槽位,而资源上限会防止重型 live、npm-install 和多服务测试通道同时全部启动。默认值为 10 个槽位、`OPENCLAW_DOCKER_ALL_LIVE_LIMIT=9`、`OPENCLAW_DOCKER_ALL_NPM_LIMIT=10` 和 `OPENCLAW_DOCKER_ALL_SERVICE_LIMIT=7`;仅当 Docker 宿主有更多余量时,才调整 `OPENCLAW_DOCKER_ALL_WEIGHT_LIMIT``OPENCLAW_DOCKER_ALL_DOCKER_LIMIT`。运行器默认会执行 Docker 预检查,移除陈旧的 OpenClaw E2E 容器,每 30 秒打印一次状态,将成功测试通道的耗时存入 `.artifacts/docker-tests/lane-timings.json`,并在后续运行时利用这些耗时优先启动更长的测试通道。使用 `OPENCLAW_DOCKER_ALL_DRY_RUN=1` 可以只打印带权重的测试通道清单而不构建或运行 Docker或使用 `node scripts/test-docker-all.mjs --plan-json` 打印所选测试通道、package / image 需求和凭证的 CI 计划。
- 容器冒烟测试运行器:`test:docker:openwebui`、`test:docker:onboard`、`test:docker:npm-onboard-channel-agent`、`test:docker:update-channel-switch`、`test:docker:session-runtime-context`、`test:docker:agents-delete-shared-workspace`、`test:docker:gateway-network`、`test:docker:browser-cdp-snapshot`、`test:docker:mcp-channels`、`test:docker:pi-bundle-mcp-tools`、`test:docker:cron-mcp-cleanup`、`test:docker:plugins`、`test:docker:plugin-update` 和 `test:docker:config-reload` 会启动一个或多个真实容器,并验证更高层级的集成路径。
`OPENCLAW_LIVE_GATEWAY_MODEL_TIMEOUT_MS=90000`。当你明确想进行更大范围的穷举扫描时,可覆盖这些环境变量。
- `test:docker:all` 会先通过 `test:docker:live-build` 构建一次 live Docker 镜像,再通过 `scripts/package-openclaw-for-docker.mjs` 将 OpenClaw 打包成一个 npm tarball然后构建/复用两个 `scripts/e2e/Dockerfile` 镜像。基础镜像仅包含用于 install/update/plugin-dependency lanes 的 Node/Git 运行器;这些 lanes 会挂载预构建的 tarball。功能镜像会将同一个 tarball 安装到 `/app` 中,用于内置应用功能 lanes。Docker lane 定义位于 `scripts/lib/docker-e2e-scenarios.mjs`;规划逻辑位于 `scripts/lib/docker-e2e-plan.mjs``scripts/test-docker-all.mjs` 负责执行所选计划。这个聚合运行器使用带权重的本地调度器:`OPENCLAW_DOCKER_ALL_PARALLELISM` 控制进程槽位,而资源上限会阻止高负载的 live、npm-install 和多服务 lanes 同时全部启动。默认值为 10 个槽位、`OPENCLAW_DOCKER_ALL_LIVE_LIMIT=9`、`OPENCLAW_DOCKER_ALL_NPM_LIMIT=10` 和 `OPENCLAW_DOCKER_ALL_SERVICE_LIMIT=7`;只有当 Docker 主机具备更多余量时,才调整 `OPENCLAW_DOCKER_ALL_WEIGHT_LIMIT``OPENCLAW_DOCKER_ALL_DOCKER_LIMIT`。运行器默认会执行 Docker preflight、移除陈旧的 OpenClaw E2E 容器、每 30 秒打印一次状态、将成功 lane 的耗时存入 `.artifacts/docker-tests/lane-timings.json`,并在后续运行中利用这些耗时优先启动更长的 lanes。使用 `OPENCLAW_DOCKER_ALL_DRY_RUN=1` 可在不构建或运行 Docker 的情况下打印带权 lane 清单,或使用 `node scripts/test-docker-all.mjs --plan-json` 打印所选 lanes、package/镜像需求和凭证的 CI 计划。
- `Package Acceptance` 是 GitHub 原生的 package 门禁,用于回答“这个可安装 tarball 作为产品是否可用?”它会从 `source=npm`、`source=ref`、`source=url` 或 `source=artifact` 中解析一个候选 package将其上传为 `package-under-test`,然后针对这个精确 tarball 运行可复用的 Docker E2E lanes而不是重新打包所选 ref。`workflow_ref` 选择受信任的 workflow/harness 脚本,而 `package_ref` 则在 `source=ref` 时选择要打包的源 commit/branch/tag这使得当前的 acceptance 逻辑也能验证较早的受信任提交。各个 profile 按覆盖广度排序:`smoke` 是快速的 install/channel/agent 加 gateway/config`package` 覆盖 package/update/plugin 契约,也是大多数 Parallels package/update 覆盖的默认原生替代方案;`product` 会再加入 MCP channels、cron/subagent cleanup、OpenAI web search 和 OpenWebUI`full` 则会运行包含 OpenWebUI 的发布路径 Docker 分块。发布验证会针对目标 ref 运行 `package` profile。
- 容器 smoke 运行器:`test:docker:openwebui`、`test:docker:onboard`、`test:docker:npm-onboard-channel-agent`、`test:docker:update-channel-switch`、`test:docker:session-runtime-context`、`test:docker:agents-delete-shared-workspace`、`test:docker:gateway-network`、`test:docker:browser-cdp-snapshot`、`test:docker:mcp-channels`、`test:docker:pi-bundle-mcp-tools`、`test:docker:cron-mcp-cleanup`、`test:docker:plugins`、`test:docker:plugin-update` 和 `test:docker:config-reload` 会启动一个或多个真实容器,并验证更高层级的集成路径。
live 模型 Docker 运行器还会仅 bind-mount 所需的 CLI 认证 home若运行未缩小范围则挂载所有受支持的认证 home然后在运行前将它们复制到容器 home 中,这样外部 CLI OAuth 就可以刷新令牌,而不会修改宿主机认证存储:
这些 live 模型 Docker 运行器还会只绑定挂载所需的 CLI 凭证 home若运行未缩小范围则挂载所有受支持的凭证 home然后在运行前将其复制到容器 home 中,这样外部 CLI OAuth 就可以刷新 token而不会修改主机上的凭证存储:
- 直接模型:`pnpm test:docker:live-models`(脚本:`scripts/test-live-models-docker.sh`
- ACP 绑定冒烟测试`pnpm test:docker:live-acp-bind`(脚本:`scripts/test-live-acp-bind-docker.sh`;默认覆盖 Claude、Codex 和 Gemini并通过 `pnpm test:docker:live-acp-bind:droid` `pnpm test:docker:live-acp-bind:opencode` 提供严格的 Droid / OpenCode 覆盖
- CLI 后端冒烟测试`pnpm test:docker:live-cli-backend`(脚本:`scripts/test-live-cli-backend-docker.sh`
- Codex app-server harness 冒烟测试`pnpm test:docker:live-codex-harness`(脚本:`scripts/test-live-codex-harness-docker.sh`
- Gateway 网关 + dev 智能体:`pnpm test:docker:live-gateway`(脚本:`scripts/test-live-gateway-models-docker.sh`
- 可观测性冒烟测试:`pnpm qa:otel:smoke` 是私有 QA 源码 checkout 测试通道。它有意不纳入 package Docker 发布测试通道,因为 npm tarball 不包含 QA Lab。
- Open WebUI live 冒烟测试`pnpm test:docker:openwebui`(脚本:`scripts/e2e/openwebui-docker.sh`
- ACP 绑定 smoke`pnpm test:docker:live-acp-bind`(脚本:`scripts/test-live-acp-bind-docker.sh`;默认覆盖 Claude、Codex 和 Gemini如需严格的 Droid/OpenCode 覆盖,可使用 `pnpm test:docker:live-acp-bind:droid` `pnpm test:docker:live-acp-bind:opencode`
- CLI 后端 smoke`pnpm test:docker:live-cli-backend`(脚本:`scripts/test-live-cli-backend-docker.sh`
- Codex app-server harness smoke`pnpm test:docker:live-codex-harness`(脚本:`scripts/test-live-codex-harness-docker.sh`
- Gateway 网关 + 开发智能体:`pnpm test:docker:live-gateway`(脚本:`scripts/test-live-gateway-models-docker.sh`
- 可观测性 smoke`pnpm qa:otel:smoke` 是一个私有 QA 源码 checkout lane。它有意不属于 package Docker 发布 lanes,因为 npm tarball 不包含 QA Lab。
- Open WebUI live smoke`pnpm test:docker:openwebui`(脚本:`scripts/e2e/openwebui-docker.sh`
- 新手引导向导TTY、完整脚手架`pnpm test:docker:onboard`(脚本:`scripts/e2e/onboard-docker.sh`
- Npm tarball 新手引导 / 渠道 / 智能体冒烟测试`pnpm test:docker:npm-onboard-channel-agent` 会在 Docker 中全局安装已打包的 OpenClaw tarball通过 env-ref 新手引导配置 OpenAI并默认配置 Telegram验证 doctor 会修复已激活插件的运行时依赖,然后运行一次 mock OpenAI 智能体轮次。可通过 `OPENCLAW_CURRENT_PACKAGE_TGZ=/path/to/openclaw-*.tgz` 复用预构建 tarball通过 `OPENCLAW_NPM_ONBOARD_HOST_BUILD=0` 跳过宿主构建,或通过 `OPENCLAW_NPM_ONBOARD_CHANNEL=discord` 切换渠道。
- 更新渠道切换冒烟测试`pnpm test:docker:update-channel-switch` 会在 Docker 中全局安装已打包的 OpenClaw tarball将渠道从 package `stable` 切换到 git `dev`,验证持久化的渠道和 plugin 在更新后正常工作,然后再切回 package `stable` 并检查更新状态。
- 会话运行时上下文冒烟测试:`pnpm test:docker:session-runtime-context` 会验证隐藏运行时上下文转录的持久化,以及 doctor 对受影响的重复 prompt-rewrite 分支的修复。
- Bun 全局安装冒烟测试`bash scripts/e2e/bun-global-install-smoke.sh` 会打包当前树,在隔离 home 中使`bun install -g` 安装,并验证 `openclaw infer image providers --json` 返回的是内置 image 提供商,而不是挂起。可通过 `OPENCLAW_BUN_GLOBAL_SMOKE_PACKAGE_TGZ=/path/to/openclaw-*.tgz` 复用预构建 tarball通过 `OPENCLAW_BUN_GLOBAL_SMOKE_HOST_BUILD=0` 跳过宿主构建,或通过 `OPENCLAW_BUN_GLOBAL_SMOKE_DIST_IMAGE=openclaw-dockerfile-smoke:local` 从已构建的 Docker 镜像复制 `dist/`
- Installer Docker 冒烟测试`bash scripts/test-install-sh-docker.sh` 会在其 root、update 和 direct-npm 容器之间共享一个 npm 缓存。更新冒烟测试默认使用 npm `latest` 作为稳定基线,然后再升级到候选 tarball。本地可通过 `OPENCLAW_INSTALL_SMOKE_UPDATE_BASELINE=2026.4.22` 覆盖,或在 GitHub 上通过 Install Smoke 工作流的 `update_baseline_version` 输入覆盖。非 root 的 installer 检查会保持隔离的 npm 缓存,这样 root 拥有的缓存条目就不会掩盖用户本地安装行为。设置 `OPENCLAW_INSTALL_SMOKE_NPM_CACHE_DIR=/path/to/cache` 可在本地重跑之间复用 root / update / direct-npm 缓存。
- Install Smoke CI 会通过 `OPENCLAW_INSTALL_SMOKE_SKIP_NPM_GLOBAL=1` 跳过重复的 direct-npm 全局更新;如果需要覆盖直接 `npm install -g`,请在本地运行脚本时不要设置该环境变量。
- 智能体删除共享工作区 CLI 冒烟测试`pnpm test:docker:agents-delete-shared-workspace`(脚本:`scripts/e2e/agents-delete-shared-workspace-docker.sh`)默认会构建根 Dockerfile 镜像,在隔离的容器 home 中预置两个共享一个工作区的智能体,运行 `agents delete --json`,并验证 JSON 有效且工作区保留行为正确。可使用 `OPENCLAW_AGENTS_DELETE_SHARED_WORKSPACE_E2E_IMAGE=openclaw-dockerfile-smoke:local OPENCLAW_AGENTS_DELETE_SHARED_WORKSPACE_E2E_SKIP_BUILD=1` 复用 install-smoke 镜像。
- Gateway 网关网络(两个容器WS 认证 + 健康检查):`pnpm test:docker:gateway-network`(脚本:`scripts/e2e/gateway-network-docker.sh`
- 浏览器 CDP 快照冒烟测试`pnpm test:docker:browser-cdp-snapshot`(脚本:`scripts/e2e/browser-cdp-snapshot-docker.sh`)会构建源码 E2E 镜像以及 Chromium 层,以原始 CDP 方式启动 Chromium运行 `browser doctor --deep`,并验证 CDP 角色快照覆盖链接 URL、由光标提升的可点击项、iframe 引用和 frame 元数据。
- OpenAI Responses `web_search` 最小推理回归测试`pnpm test:docker:openai-web-search-minimal`(脚本:`scripts/e2e/openai-web-search-minimal-docker.sh`)会通过 Gateway 网关运行一个 mock OpenAI 服务器,验证 `web_search` 会将 `reasoning.effort``minimal` 提升 `low`,然后强制提供商 schema 拒绝,并检查原始细节是否出现在 Gateway 网关日志中。
- MCP 渠道桥接(预置 Gateway 网关 + stdio bridge + 原始 Claude notification-frame 冒烟测试`pnpm test:docker:mcp-channels`(脚本:`scripts/e2e/mcp-channels-docker.sh`
- Pi 内置 MCP 工具(真实 stdio MCP 服务器 + 嵌入式 Pi profile allow / deny 冒烟测试`pnpm test:docker:pi-bundle-mcp-tools`(脚本:`scripts/e2e/pi-bundle-mcp-tools-docker.sh`
- Cron / subagent MCP 清理(真实 Gateway 网关 + 在隔离 cron 和一次性 subagent 运行后拆除 stdio MCP 子进程):`pnpm test:docker:cron-mcp-cleanup`(脚本:`scripts/e2e/cron-mcp-cleanup-docker.sh`
- 插件(安装冒烟测试、ClawHub 安装 / 卸载、marketplace 更新,以及 Claude-bundle 启用 / 检查):`pnpm test:docker:plugins`(脚本:`scripts/e2e/plugins-docker.sh`
设置 `OPENCLAW_PLUGINS_E2E_CLAWHUB=0` 可跳过 live ClawHub 模块,或通过 `OPENCLAW_PLUGINS_E2E_CLAWHUB_SPEC``OPENCLAW_PLUGINS_E2E_CLAWHUB_ID` 覆盖默认 package。
- 插件更新未变化冒烟测试`pnpm test:docker:plugin-update`(脚本:`scripts/e2e/plugin-update-unchanged-docker.sh`
- 配置热重载元数据冒烟测试`pnpm test:docker:config-reload`(脚本:`scripts/e2e/config-reload-source-docker.sh`
- 内置插件运行时依赖:`pnpm test:docker:bundled-channel-deps` 默认会构建一个小型 Docker 运行器镜像,在宿主上构建并打包一次 OpenClaw然后将该 tarball 挂载到每个 Linux 安装场景中。可通过 `OPENCLAW_SKIP_DOCKER_BUILD=1` 复用镜像,在完成一次本地构建后通过 `OPENCLAW_BUNDLED_CHANNEL_HOST_BUILD=0` 跳过宿主重新构建,或通过 `OPENCLAW_CURRENT_PACKAGE_TGZ=/path/to/openclaw-*.tgz` 指向现有 tarball。完整 Docker 聚合器会先预先打包该 tarball 一次,然后将内置渠道检查拆分为独立测试通道,其中包括 Telegram、Discord、Slack、Feishu、memory-lancedb 和 ACPX 的独立更新测试通道。直接运行内置测试通道时,使用 `OPENCLAW_BUNDLED_CHANNELS=telegram,slack` 缩小渠道矩阵,或使用 `OPENCLAW_BUNDLED_CHANNEL_UPDATE_TARGETS=telegram,acpx` 缩小更新场景。该测试通道还会验证 `channels.<id>.enabled=false``plugins.entries.<id>.enabled=false` 会抑制 doctor / 运行时依赖修复。
- 迭代时若想缩小内置插件运行时依赖范围,可禁用关场景,例如:
- Npm tarball 新手引导/渠道/智能体 smoke`pnpm test:docker:npm-onboard-channel-agent` 会在 Docker 中全局安装已打包的 OpenClaw tarball通过 env-ref 新手引导配置 OpenAI并默认配置 Telegram验证 doctor 会修复已激活插件的运行时依赖,然后运行一次模拟的 OpenAI 智能体轮次。可使用 `OPENCLAW_CURRENT_PACKAGE_TGZ=/path/to/openclaw-*.tgz` 复用预构建 tarball使用 `OPENCLAW_NPM_ONBOARD_HOST_BUILD=0` 跳过主机构建,或使用 `OPENCLAW_NPM_ONBOARD_CHANNEL=discord` 切换渠道。
- 更新渠道切换 smoke`pnpm test:docker:update-channel-switch` 会在 Docker 中全局安装已打包的 OpenClaw tarball从 package `stable` 切换到 git `dev`,验证持久化的渠道和插件在更新后仍然可用,然后再切回 package `stable` 并检查更新状态。
- Session 运行时上下文 smoke`pnpm test:docker:session-runtime-context` 会验证隐藏运行时上下文 transcript 的持久化,以及 doctor 对受影响的重复 prompt-rewrite 分支的修复。
- Bun 全局安装 smoke`bash scripts/e2e/bun-global-install-smoke.sh` 会打包当前工作树,在隔离 home 中用 `bun install -g` 安装,并验证 `openclaw infer image providers --json` 会返回内置图像提供商而不是卡住。可使用 `OPENCLAW_BUN_GLOBAL_SMOKE_PACKAGE_TGZ=/path/to/openclaw-*.tgz` 复用预构建 tarball使用 `OPENCLAW_BUN_GLOBAL_SMOKE_HOST_BUILD=0` 跳过主机构建,或使用 `OPENCLAW_BUN_GLOBAL_SMOKE_DIST_IMAGE=openclaw-dockerfile-smoke:local` 从已构建的 Docker 镜像复制 `dist/`
- Installer Docker smoke`bash scripts/test-install-sh-docker.sh` 会在其 root、update 和 direct-npm 容器之间共享一个 npm 缓存。更新 smoke 默认使用 npm `latest` 作为稳定基线,然后升级到候选 tarball。可在本地使用 `OPENCLAW_INSTALL_SMOKE_UPDATE_BASELINE=2026.4.22` 覆盖,或在 GitHub 上使用 Install Smoke workflow 的 `update_baseline_version` 输入覆盖。非 root 的 installer 检查会保留一个隔离的 npm 缓存,以避免 root 所有的缓存条目掩盖用户本地安装行为。设置 `OPENCLAW_INSTALL_SMOKE_NPM_CACHE_DIR=/path/to/cache` 可在本地重跑时复用 root/update/direct-npm 缓存。
- Install Smoke CI 会使用 `OPENCLAW_INSTALL_SMOKE_SKIP_NPM_GLOBAL=1` 跳过重复的 direct-npm 全局更新;当需要覆盖直接 `npm install -g` 时,请在本地运行该脚本且不要设置这个环境变量。
- 智能体删除共享工作区 CLI smoke`pnpm test:docker:agents-delete-shared-workspace`(脚本:`scripts/e2e/agents-delete-shared-workspace-docker.sh`)默认会构建根 Dockerfile 镜像,在隔离的容器 home 中植入两个智能体和一个工作区,运行 `agents delete --json`,并验证 JSON 有效且工作区保留行为正确。可使用 `OPENCLAW_AGENTS_DELETE_SHARED_WORKSPACE_E2E_IMAGE=openclaw-dockerfile-smoke:local OPENCLAW_AGENTS_DELETE_SHARED_WORKSPACE_E2E_SKIP_BUILD=1` 复用 install-smoke 镜像。
- Gateway 网关网络(两个容器WS 认证 + 健康检查):`pnpm test:docker:gateway-network`(脚本:`scripts/e2e/gateway-network-docker.sh`
- 浏览器 CDP 快照 smoke`pnpm test:docker:browser-cdp-snapshot`(脚本:`scripts/e2e/browser-cdp-snapshot-docker.sh`)会构建源码 E2E 镜像以及 Chromium 层,以原始 CDP 启动 Chromium运行 `browser doctor --deep`,并验证 CDP 角色快照覆盖链接 URL、光标提升的可点击元素、iframe 引用和 frame 元数据。
- OpenAI Responses `web_search` 最小推理回归:`pnpm test:docker:openai-web-search-minimal`(脚本:`scripts/e2e/openai-web-search-minimal-docker.sh`)会通过 Gateway 网关运行一个模拟的 OpenAI 服务器,验证 `web_search` 会将 `reasoning.effort``minimal` 提升 `low`,然后强制提供商 schema 拒绝,并检查原始细节是否出现在 Gateway 网关日志中。
- MCP 渠道桥(已植入的 Gateway 网关 + stdio bridge + 原始 Claude 通知帧 smoke`pnpm test:docker:mcp-channels`(脚本:`scripts/e2e/mcp-channels-docker.sh`
- Pi 内置 MCP 工具(真实 stdio MCP 服务器 + 嵌入式 Pi profile allow/deny smoke`pnpm test:docker:pi-bundle-mcp-tools`(脚本:`scripts/e2e/pi-bundle-mcp-tools-docker.sh`
- Cron/subagent MCP 清理(真实 Gateway 网关 + 在隔离的 cron 和一次性 subagent 运行后关闭 stdio MCP 子进程):`pnpm test:docker:cron-mcp-cleanup`(脚本:`scripts/e2e/cron-mcp-cleanup-docker.sh`
- 插件(安装 smoke、ClawHub 安装/卸载、市场更新,以及 Claude bundle 启用/检查):`pnpm test:docker:plugins`(脚本:`scripts/e2e/plugins-docker.sh`
设置 `OPENCLAW_PLUGINS_E2E_CLAWHUB=0` 可跳过 live ClawHub 区块,或使用 `OPENCLAW_PLUGINS_E2E_CLAWHUB_SPEC``OPENCLAW_PLUGINS_E2E_CLAWHUB_ID` 覆盖默认 package。
- 插件更新未变化 smoke`pnpm test:docker:plugin-update`(脚本:`scripts/e2e/plugin-update-unchanged-docker.sh`
- 配置热重载元数据 smoke`pnpm test:docker:config-reload`(脚本:`scripts/e2e/config-reload-source-docker.sh`
- 内置插件运行时依赖:`pnpm test:docker:bundled-channel-deps` 默认会构建一个小型 Docker 运行器镜像,在主上构建并打包一次 OpenClaw然后将该 tarball 挂载到每个 Linux 安装场景中。可使用 `OPENCLAW_SKIP_DOCKER_BUILD=1` 复用该镜像,在完成一次全新的本地构建后使用 `OPENCLAW_BUNDLED_CHANNEL_HOST_BUILD=0` 跳过主机重建,或使用 `OPENCLAW_CURRENT_PACKAGE_TGZ=/path/to/openclaw-*.tgz` 指向现有 tarball。完整 Docker 聚合运行器会先预先打包这个 tarball 一次,然后将内置渠道检查分片为独立 lanes包括 Telegram、Discord、Slack、Feishu、memory-lancedb 和 ACPX 的独立更新 lanes。直接运行内置 lane 时,可使用 `OPENCLAW_BUNDLED_CHANNELS=telegram,slack` 缩小渠道矩阵,或使用 `OPENCLAW_BUNDLED_CHANNEL_UPDATE_TARGETS=telegram,acpx` 缩小更新场景。该 lane 还会验证 `channels.<id>.enabled=false``plugins.entries.<id>.enabled=false` 会抑制 doctor/运行时依赖修复。
- 迭代时缩小内置插件运行时依赖范围,可禁用不相关场景,例如:
`OPENCLAW_BUNDLED_CHANNEL_SCENARIOS=0 OPENCLAW_BUNDLED_CHANNEL_UPDATE_SCENARIO=0 OPENCLAW_BUNDLED_CHANNEL_ROOT_OWNED_SCENARIO=0 OPENCLAW_BUNDLED_CHANNEL_SETUP_ENTRY_SCENARIO=0 pnpm test:docker:bundled-channel-deps`
如需手动预构建并复用共享功能镜像:
手动预构建并复用共享功能镜像:
```bash
OPENCLAW_DOCKER_E2E_IMAGE=openclaw-docker-e2e-functional:local pnpm test:docker:e2e-build
OPENCLAW_DOCKER_E2E_IMAGE=openclaw-docker-e2e-functional:local OPENCLAW_SKIP_DOCKER_BUILD=1 pnpm test:docker:mcp-channels
```
设置后,像 `OPENCLAW_GATEWAY_NETWORK_E2E_IMAGE` 这样的套件专用镜像覆盖仍然优先生效。当 `OPENCLAW_SKIP_DOCKER_BUILD=1` 指向远程共享镜像时,如果该镜像尚未存在于本地,脚本会先拉取它。QR 和 installer Docker 测试仍保留各自的 Dockerfile因为它们验证的是 package / 安装行为,而不是共享的 built-app 运行时。
如果设置了特定测试套件的镜像覆盖(如 `OPENCLAW_GATEWAY_NETWORK_E2E_IMAGE`),则仍以它们为准。当 `OPENCLAW_SKIP_DOCKER_BUILD=1` 指向一个远程共享镜像时,如果该镜像尚未存在于本地,脚本会将其拉取。QR 和 installer Docker 测试保留各自独立的 Dockerfile因为它们验证的是 package/install 行为,而不是共享的内置应用运行时。
live 模型 Docker 运行器还会以只读方式 bind-mount 当前 checkout并将其预置到容器内的临时工作目录中。这样既能保持运行时镜像精简又能确保 Vitest 仍然针对你当前本地的准确源码 / 配置运行。
预置步骤会跳过大型仅限本地的缓存和应用构建输出,例如
`.pnpm-store`、`.worktrees`、`__openclaw_vitest__`,以及应用本地的 `.build` 或 Gradle 输出目录,这样 Docker live 运行就不会花费数分钟复制机器专属产物。
它们还会设置 `OPENCLAW_SKIP_CHANNELS=1`,这样 Gateway 网关 live 探测就不会在容器内启动真实的 Telegram / Discord / 等渠道工作进程。
`test:docker:live-models` 仍然会运行 `pnpm test:live`,因此当你需要缩小或排除该 Docker 测试通道中的 Gateway 网关 live 覆盖范围时,也要一并传递 `OPENCLAW_LIVE_GATEWAY_*`
`test:docker:openwebui` 是更高层级的兼容性冒烟测试:它会启动一个启用了 OpenAI 兼容 HTTP 端点的 OpenClaw Gateway 网关容器,启动一个指向该 Gateway 网关的固定版 Open WebUI 容器,通过 Open WebUI 完成登录,验证 `/api/models` 暴露了 `openclaw/default`,然后通过 Open WebUI 的 `/api/chat/completions` 代理发送一个真实聊天请求。
首次运行可能会明显更慢,因为 Docker 可能需要拉取 Open WebUI 镜像,而且 Open WebUI 可能需要完成自己的冷启动设置。
该测试通道需要可用的 live 模型 key`OPENCLAW_PROFILE_FILE`
(默认值为 `~/.profile`)是在 Docker 化运行中提供该 key 的主要方式。
成功运行会打印一个小型 JSON 载荷,例如 `{ "ok": true, "model":
这些 live 模型 Docker 运行器还会将当前 checkout 以只读方式 bind-mount并在容器内暂存到一个临时 workdir。这样既能保持运行时镜像精简又能让 Vitest 针对你精确的本地 source/config 运行。
暂存步骤会跳过大型仅本地缓存和应用构建输出,例如
`.pnpm-store`、`.worktrees`、`__openclaw_vitest__`,以及应用本地 `.build`
Gradle 输出目录,这样 Docker live 运行就不会花上数分钟去复制机器特定 artifact。
它们还会设置 `OPENCLAW_SKIP_CHANNELS=1`,这样 gateway live 探测就不会在容器内启动真实的 Telegram/Discord 等渠道 worker。
`test:docker:live-models` 仍然运行 `pnpm test:live`,因此当你需要缩小或排除该 Docker lane 中的 gateway live 覆盖时,也请一并传入 `OPENCLAW_LIVE_GATEWAY_*`
`test:docker:openwebui` 是更高层级的兼容性 smoke它会启动一个启用了 OpenAI 兼容 HTTP endpoint 的 OpenClaw Gateway 网关容器,针对该网关启动一个固定版本的 Open WebUI 容器,通过 Open WebUI 完成登录,验证 `/api/models` 暴露了 `openclaw/default`,然后通过 Open WebUI 的 `/api/chat/completions` 代理发送一个真实聊天请求。
首次运行可能会明显更慢,因为 Docker 可能需要拉取 Open WebUI 镜像,而 Open WebUI 也可能需要完成自身的冷启动设置。
这个 lane 需要一个可用的 live 模型密钥,而 `OPENCLAW_PROFILE_FILE`
(默认是 `~/.profile`)是在 Docker 化运行中提供该密钥的主要方式。
成功运行会打印一个小型 JSON payload例如 `{ "ok": true, "model":
"openclaw/default", ... }`。
`test:docker:mcp-channels`有意设计为确定性的,不需要真实的 Telegram、Discord 或 iMessage 账号。它会启动一个已预置的 Gateway 网关容器,再启动第二个容器来拉起 `openclaw mcp serve`,然后验证路由会话发现、转录读取、附件元数据、live 事件队列行为、出站发送路由,以及通过真实 stdio MCP bridge 传递的 Claude 风格渠道 + 权限通知。通知检查会直接检查原始 stdio MCP frame因此该冒烟测试验证的是 bridge 实际发出的内容,而不仅仅是某个特定客户端 SDK 恰好暴露出来的内容。
`test:docker:pi-bundle-mcp-tools` 是确定性的,不需要 live 模型 key。它会构建仓库 Docker 镜像,在容器内启动一个真实 stdio MCP 探测服务器,通过嵌入式 Pi bundle MCP 运行时实例化该服务器,执行工具,然后验证 `coding``messaging` 会保留 `bundle-mcp` 工具,而 `minimal``tools.deny: ["bundle-mcp"]` 会将其过滤掉。
`test:docker:cron-mcp-cleanup` 是确定性的,不需要 live 模型 key。它会使用真实 stdio MCP 探测服务器启动一个已预置的 Gateway 网关,运行一次隔离的 cron 轮次和一次 `/subagents spawn` 一次性子智能体轮次,然后验证 MCP 子进程会在每次运行后退出。
`test:docker:mcp-channels`刻意设计成确定性的,不需要真实的 Telegram、Discord 或 iMessage 账号。它会启动一个已植入的 Gateway 网关容器,再启动第二个容器来运行 `openclaw mcp serve`然后验证路由后的会话发现、transcript 读取、附件元数据、live 事件队列行为、出站发送路由,以及通过真实 stdio MCP bridge 传递的 Claude 风格渠道 + 权限通知。通知检查会直接检查原始 stdio MCP 帧,因此这个 smoke 验证的是 bridge 实际发出的内容,而不只是某个特定客户端 SDK 恰好暴露出的内容。
`test:docker:pi-bundle-mcp-tools` 具有确定性,不需要 live 模型密钥。它会构建仓库 Docker 镜像,在容器内启动一个真实的 stdio MCP 探测服务器,通过嵌入式 Pi 内置 MCP 运行时实例化该服务器,执行工具,然后验证 `coding``messaging` 会保留 `bundle-mcp` 工具,而 `minimal``tools.deny: ["bundle-mcp"]` 会将其过滤掉。
`test:docker:cron-mcp-cleanup` 具有确定性,不需要 live 模型密钥。它会启动一个带真实 stdio MCP 探测服务器的已植入 Gateway 网关,运行一个隔离的 cron 轮次和一个 `/subagents spawn` 一次性子智能体轮次,然后验证 MCP 子进程会在每次运行后退出。
手动 ACP 自然语言线程冒烟测试(非 CI
手动 ACP 纯语言线程 smoke不在 CI 中运行
- `bun scripts/dev/discord-acp-plain-language-smoke.ts --channel <discord-channel-id> ...`
- 请保留该脚本用于回归 / 调试工作流。之后它可能还会再次用于 ACP 线程路由验证,因此不要删除
- 请将该脚本保留用于回归/调试工作流。它未来可能还会再次用于 ACP 线程路由验证,因此不要删除。
有用的环境变量:
常用环境变量:
- `OPENCLAW_CONFIG_DIR=...`(默认`~/.openclaw`)挂载到 `/home/node/.openclaw`
- `OPENCLAW_WORKSPACE_DIR=...`(默认`~/.openclaw/workspace`)挂载到 `/home/node/.openclaw/workspace`
- `OPENCLAW_PROFILE_FILE=...`(默认`~/.profile`)挂载到 `/home/node/.profile`,并在运行测试前 source
- `OPENCLAW_DOCKER_PROFILE_ENV_ONLY=1` 用于仅验证从 `OPENCLAW_PROFILE_FILE` source 的环境变量;它会使用临时配置 / 工作区目录,并且不挂载外部 CLI 认
- `OPENCLAW_DOCKER_CLI_TOOLS_DIR=...`(默认`~/.cache/openclaw/docker-cli-tools`)挂载到 `/home/node/.npm-global`,用于 Docker 内的 CLI 安装缓存
- `$HOME` 下的外部 CLI 认证目录 / 文件会以只读方式挂载到 `/host-auth...` 下,然后在测试开始前复制到 `/home/node/...`
- `OPENCLAW_CONFIG_DIR=...`(默认:`~/.openclaw`)挂载到 `/home/node/.openclaw`
- `OPENCLAW_WORKSPACE_DIR=...`(默认:`~/.openclaw/workspace`)挂载到 `/home/node/.openclaw/workspace`
- `OPENCLAW_PROFILE_FILE=...`(默认:`~/.profile`)挂载到 `/home/node/.profile`,并在运行测试前 source
- `OPENCLAW_DOCKER_PROFILE_ENV_ONLY=1` 用于仅验证从 `OPENCLAW_PROFILE_FILE` source 的环境变量,使用临时 config/workspace 目录,且不挂载外部 CLI 凭
- `OPENCLAW_DOCKER_CLI_TOOLS_DIR=...`(默认:`~/.cache/openclaw/docker-cli-tools`)挂载到 `/home/node/.npm-global`,用于 Docker 内缓存的 CLI 安装
- `$HOME` 下的外部 CLI 凭证目录/文件会以只读方式挂载到 `/host-auth...` 下,然后在测试开始前复制到 `/home/node/...`
- 默认目录:`.minimax`
- 默认文件:`~/.codex/auth.json`、`~/.codex/config.toml`、`.claude.json`、`~/.claude/.credentials.json`、`~/.claude/settings.json`、`~/.claude/settings.local.json`
- 缩小范围的提供商运行只会挂载根据 `OPENCLAW_LIVE_PROVIDERS` / `OPENCLAW_LIVE_GATEWAY_PROVIDERS` 推断出的所需目录 / 文件
- 可通过 `OPENCLAW_DOCKER_AUTH_DIRS=all`、`OPENCLAW_DOCKER_AUTH_DIRS=none` 或逗号列表(如 `OPENCLAW_DOCKER_AUTH_DIRS=.claude,.codex`)手动覆盖
- 缩小提供商范围的运行只会挂载从 `OPENCLAW_LIVE_PROVIDERS` / `OPENCLAW_LIVE_GATEWAY_PROVIDERS` 推断出的所需目录/文件
- 可通过 `OPENCLAW_DOCKER_AUTH_DIRS=all`、`OPENCLAW_DOCKER_AUTH_DIRS=none` 或逗号列表(`OPENCLAW_DOCKER_AUTH_DIRS=.claude,.codex`)手动覆盖
- `OPENCLAW_LIVE_GATEWAY_MODELS=...` / `OPENCLAW_LIVE_MODELS=...` 用于缩小运行范围
- `OPENCLAW_LIVE_GATEWAY_PROVIDERS=...` / `OPENCLAW_LIVE_PROVIDERS=...` 用于在容器内筛选提供商
- `OPENCLAW_SKIP_DOCKER_BUILD=1` 用于复用现有 `openclaw:local-live` 镜像,以便在不需要重新构建时重跑
- `OPENCLAW_LIVE_REQUIRE_PROFILE_KEYS=1` 用于确保凭证来自 profile 存储(而环境变量)
- `OPENCLAW_OPENWEBUI_MODEL=...` 用于为 Open WebUI 冒烟测试选择由 Gateway 网关暴露的模型
- `OPENCLAW_OPENWEBUI_PROMPT=...` 用于覆盖 Open WebUI 冒烟测试所使用的 nonce 检查提示词
- `OPENWEBUI_IMAGE=...` 用于覆盖固定 Open WebUI 镜像标签
- `OPENCLAW_SKIP_DOCKER_BUILD=1` 用于复用现有`openclaw:local-live` 镜像,适合不需要重建的重跑
- `OPENCLAW_LIVE_REQUIRE_PROFILE_KEYS=1` 用于确保凭证来自 profile 存储(而不是环境变量)
- `OPENCLAW_OPENWEBUI_MODEL=...` 用于选择 Gateway 网关为 Open WebUI smoke 暴露的模型
- `OPENCLAW_OPENWEBUI_PROMPT=...` 用于覆盖 Open WebUI smoke 使用的 nonce 检查 prompt
- `OPENWEBUI_IMAGE=...` 用于覆盖固定 Open WebUI 镜像标签
## 文档完整性检查
文档编辑后运行文档检查:`pnpm check:docs`。
当你还需要页内标题检查时,运行完整的 Mintlify 锚点校验:`pnpm docs:check-links:anchors`。
在修改文档后运行文档检查:`pnpm check:docs`。
当你还需要检查页内标题锚点时,运行完整的 Mintlify 锚点校验:`pnpm docs:check-links:anchors`。
## 离线回归(对 CI 安全)
## 离线回归测试(对 CI 安全)
这些是在没有真实提供商的情况下进行的“真实流水线”回归:
这些是在不使用真实提供商的情况下进行的“真实流水线”回归测试
- Gateway 网关工具调用(mock OpenAI真实 Gateway 网关 + Agent loop`src/gateway/gateway.test.ts`用例“runs a mock OpenAI tool call end-to-end via gateway agent loop”
- Gateway 网关向导WS `wizard.start` / `wizard.next`,强制写入配置 + 认证`src/gateway/gateway.test.ts`用例“runs wizard over ws and writes auth token config”
- Gateway 网关工具调用(模拟 OpenAI、真实 Gateway 网关 + Agent loop`src/gateway/gateway.test.ts`用例“runs a mock OpenAI tool call end-to-end via gateway agent loop”
- Gateway 网关向导WS `wizard.start`/`wizard.next`,强制写入 config + auth`src/gateway/gateway.test.ts`用例“runs wizard over ws and writes auth token config”
## 智能体可靠性评估Skills
我们已经有一些对 CI 安全的测试,其行为类似“智能体可靠性评估”:
- 通过真实 Gateway 网关 + Agent loop 进行 mock 工具调用(`src/gateway/gateway.test.ts`)。
- 通过真实 Gateway 网关 + Agent loop 进行模拟工具调用(`src/gateway/gateway.test.ts`)。
- 验证会话接线和配置效果的端到端向导流程(`src/gateway/gateway.test.ts`)。
对于 Skills见 [Skills](/zh-CN/tools/skills)),仍缺少的是
对于 Skills见 [Skills](/zh-CN/tools/skills)目前仍缺少:
- **决策能力:**提示词中列出 Skills 时,智能体是否会选择正确的 Skill或避开无关 Skill
- **合规性:** 智能体是否会在使用前读取 `SKILL.md`,并遵循所需步骤 / 参数?
- **工作流契约:** 断言工具顺序、会话历史延续和沙箱边界的多轮场景。
- **决策能力:** prompt 中列出 Skills 时,智能体是否会选择正确的 Skill或避开无关 Skill
- **合规性:** 智能体是否会在使用前读取 `SKILL.md` 并遵循要求的步骤/参数?
- **工作流契约:** 断言工具顺序、会话历史继承以及沙箱边界的多轮场景。
未来的评估应优先保持确定性:
- 一个使用 mock 提供商的场景运行器,用于断言工具调用 + 顺序、Skill 文件读取以及会话接线。
- 一小组面向 Skill 的场景(使用 vs 避免、门控、提示注入)。
- 仅在对 CI 安全的套件到位之后,再添加可选的 live 评估(按需启用、受环境变量门控)。
- 一个使用模拟提供商的场景运行器,用于断言工具调用 + 顺序、Skill 文件读取和会话接线。
- 一小组聚焦 Skill 的场景(使用 vs 避免、门禁、prompt 注入)。
- 仅在对 CI 安全的测试套件到位后,才添加可选的 live 评估(显式启用、受环境变量控制)。
## 契约测试(插件和渠道形状)
契约测试会验证每个已注册插件和渠道都符合其接口契约。它们会遍历所有已发现插件,并运行一组形状和行为断言。默认的 `pnpm test` 单元测试通道会有意跳过这些共享接缝和冒烟文件;当你修改共享渠道或提供商表面时,请显式运行契约命令。
契约测试用于验证每个已注册插件和渠道都符合其接口契约。它们会遍历所有已发现的插件,并运行一组形状与行为断言。默认的 `pnpm test` unit lane 会有意跳过这些共享接缝和 smoke 文件;当你修改共享渠道或提供商表面时,请显式运行契约命令。
### 命令
- 所有契约:`pnpm test:contracts`
- 仅渠道契约:`pnpm test:contracts:channels`
- 仅提供商契约:`pnpm test:contracts:plugins`
- 所有契约测试`pnpm test:contracts`
- 仅渠道契约测试`pnpm test:contracts:channels`
- 仅提供商契约测试`pnpm test:contracts:plugins`
### 渠道契约
### 渠道契约测试
位于 `src/channels/plugins/contracts/*.contract.test.ts`
- **plugin** - 基本插件形状id、name、capabilities
- **setup** - 设置向导契约
- **session-binding** - 会话绑定行为
- **outbound-payload** - 消息载结构
- **outbound-payload** - 消息载结构
- **inbound** - 入站消息处理
- **actions** - 渠道作处理器
- **actions** - 渠道作处理器
- **threading** - 线程 ID 处理
- **directory** - 目录 / roster API
- **group-policy** - 群组策略强制执行
- **directory** - 目录/成员列表 API
- **group-policy** - 群组策略执行
### 提供商 Status 契约
### 提供商 Status 契约测试
位于 `src/plugins/contracts/*.contract.test.ts`
- **status** - 渠道 Status 探测
- **registry** - 插件注册表形状
### 提供商契约
### 提供商契约测试
位于 `src/plugins/contracts/*.contract.test.ts`
- **auth** - 认证流程契约
- **auth-choice** - 认证选项 / 选择
- **auth-choice** - 认证选项/选择
- **catalog** - 模型目录 API
- **discovery** - 插件发现
- **loader** - 插件加载
- **runtime** - 提供商运行时
- **shape** - 插件形状 / 接口
- **shape** - 插件形状/接口
- **wizard** - 设置向导
### 何时运行
- 修改 `plugin-sdk` 导出或子路径后
- 添加或修改渠道或提供商插件后
- 重构插件注册或发现逻辑
- 重构插件注册或发现机制
契约测试会在 CI 中运行,不需要真实 API key。
契约测试会在 CI 中运行,并且不需要真实 API key。
## 添加回归测试(指南)
当你修复在 live 中发现的提供商 / 模型问题时:
当你修复一个在 live 中发现的提供商/模型问题时:
- 如果可能,添加一个对 CI 安全的回归测试(mock / stub 提供商,或捕获确切的请求形状转换)
- 如果问题本质上只能在 live 中出现(限流、认证策略),就让 live 测试保持窄范围,并通过环境变量按需启用
- 优先锁定最小但足以捕获该缺陷的层级:
- 提供商请求转换 / 回放缺陷 → 直接模型测试
- Gateway 网关会话 / 历史 / 工具流水线缺陷 → Gateway 网关 live 冒烟测试或对 CI 安全的 Gateway 网关 mock 测试
- SecretRef 遍历护:
- `src/secrets/exec-secret-ref-id-parity.test.ts` 会从注册表元数据(`listSecretTargetRegistryEntries()`)中为每个 SecretRef 类派生一个采样目标,然后断言会拒绝遍历片段 exec id。
- 如果你在 `src/secrets/target-registry-data.ts` 中添加了新的 `includeInPlan` SecretRef 目标族,请更新该测试中的 `classifyTargetClass`。该测试会故意在目标 id 未分类时失败,这样新类别就不能被静默跳过
- 如果可能,添加一个对 CI 安全的回归测试(模拟/stub 提供商,或捕获精确的请求形状转换)
- 如果它本质上只能在 live 中验证(速率限制、认证策略),则让 live 测试保持窄范围,并通过环境变量显式启用
- 优先定位能捕获该 bug 的最小层级:
- 提供商请求转换/重放 bug → 直接模型测试
- Gateway 网关会话/历史/工具流水线 bug → gateway live smoke 或对 CI 安全的 gateway mock 测试
- SecretRef 遍历护
- `src/secrets/exec-secret-ref-id-parity.test.ts` 会从注册表元数据(`listSecretTargetRegistryEntries()`)中为每个 SecretRef 类派生一个采样目标,然后断言遍历片段 exec id 会被拒绝
- 如果你在 `src/secrets/target-registry-data.ts` 中添加了新的 `includeInPlan` SecretRef 目标族,请更新该测试中的 `classifyTargetClass`。该测试会在遇到未分类目标 id 时故意失败,从而避免静默跳过新的类别
## 相关内容
- [Testing live](/zh-CN/help/testing-live)
- [测试 live](/zh-CN/help/testing-live)
- [CI](/zh-CN/ci)

View File

@ -1,162 +1,165 @@
---
read_when:
- 查找公开发布渠道定义
- 查找版本命名和发布节奏的说明
- 查找公开发布渠道定义
- 查找版本命名和发布节奏
summary: 公开发布渠道、版本命名和发布节奏
title: 发布策略
x-i18n:
generated_at: "2026-04-27T03:28:54Z"
generated_at: "2026-04-27T03:46:55Z"
model: gpt-5.4
provider: openai
source_hash: 2b6e0306f07ceec860ad2cce6bd6bb6a6d52fc8a87e9fa7acd3f48b963fb2bcb
source_hash: 5f2481413208fd227620980c48a2a3ef195be97926d240b0b350cc2ab649b91f
source_path: reference/RELEASING.md
workflow: 15
---
OpenClaw 有三个公开发布渠道:
- stable带标签的正式发布,默认发布到 npm `beta`,或在明确指定时发布到 npm `latest`
- stable带标签的发布版本,默认发布到 npm `beta`,或在明确要求时发布到 npm `latest`
- beta预发布标签发布到 npm `beta`
- dev`main` 的滚动最新版本
- dev`main` 的持续更新头部版本
## 版本命名
- 稳定版发布版本:`YYYY.M.D`
- 稳定版本`YYYY.M.D`
- Git 标签:`vYYYY.M.D`
- 稳定修正版发布版本:`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` 表示当前已提升的稳定 npm 发布
- 不要月份或日期补零
- `latest` 表示当前已提升为正式版的稳定 npm 发布
- `beta` 表示当前 beta 安装目标
- 稳定版和稳定修正版默认发布到 npm `beta`;发布操作人员可以显式将目标设为 `latest`,或者稍后再提升一个经过验证的 beta 构建
- 每个稳定版 OpenClaw 发布都会同时发布 npm 包和 macOS 应用;
beta 发布通常会先验证并发布 npm / package 路径mac 应用的构建 / 签名 / 公证则保留给稳定版,除非明确要求
- 稳定版和稳定修正版默认发布到 npm `beta`;发布操作人员可以显式指定发布到 `latest`,或者稍后再提升已验证的 beta 构建
- 每个稳定版 OpenClaw 发布都会同时交付 npm 包和 macOS 应用;
beta 发布通常会先验证并发布 npm/包路径,而 mac 应用的构建/签名/公证仅保留给稳定版,除非有明确要求
## 发布节奏
- 发布先走 beta
- 只有在最新 beta 通过验证后,才会跟进稳定版
- 维护者通常会从当前 `main` 创建 `release/YYYY.M.D` 分支来切发布,
这样发布验证和修复就不会阻塞 `main` 上的新开发
- 如果某个 beta 标签已经推送或发布,但之后需要修复,维护者会切下一个 `-beta.N` 标签,而不是删除或重建旧的 beta 标签
- 详细的发布流程、审批、凭证和恢复说明仅供维护者使用
- 只有在最新 beta 验证通过后,才会进入 stable
- 维护者通常从当前 `main` 创建的 `release/YYYY.M.D` 分支切出发布版本,这样发布验证和修复就不会阻塞 `main` 上的新开发
- 如果某个 beta 标签已经推送或发布后又需要修复,维护者会切出下一个 `-beta.N` 标签,而不是删除或重建旧的 beta 标签
- 详细的发布流程、审批、凭证和恢复说明仅对维护者开放
## 发布前
## 发布前检
- 在发布前预检前运行 `pnpm check:test-types`,这样测试 TypeScript 也能在更快的本地 `pnpm check` 检查之外得到覆盖
- 在发布前预检前运行 `pnpm check:architecture`,这样更广泛的导入循环和架构边界检查也能在更快的本地检查之外保持通过
- 在 `pnpm release:check` 之前运行 `pnpm build && pnpm ui:build`,这样打包验证步骤所需的预期 `dist/*` 发布产物和 Control UI bundle 都已生成
- 当你需要通过一个入口点运行完整的发布验证套件时,在发布审批前运行手动的 `Full Release Validation` 工作流。它接受分支、标签或完整提交 SHA会分发手动 `CI`,并分发 `OpenClaw Release Checks` 来执行安装冒烟测试、Docker 发布路径套件、live / E2E、OpenWebUI、QA Lab 一致性、Matrix 和 Telegram 通道。只有在包已经发布且还需要运行发布后的 Telegram E2E 时,才提供 `npm_telegram_package_spec`
- 在发布前检查之前运行 `pnpm check:test-types`,这样测试 TypeScript 也能在更快的本地 `pnpm check` 检查之外得到覆盖
- 在发布前检查之前运行 `pnpm check:architecture`,这样更广泛的导入循环和架构边界检查也能在更快的本地检查之外保持绿色
- 在 `pnpm release:check` 之前运行 `pnpm build && pnpm ui:build`,以便打包验证步骤所需的 `dist/*` 发布产物和 Control UI bundle 已存在
- 当你需要通过单一入口运行完整发布验证套件时,在发布审批前运行手动 `Full Release Validation` 工作流。它接受分支、标签或完整提交 SHA派发手动 `CI`,并派发 `OpenClaw Release Checks`用于安装冒烟测试、包验收、Docker 发布路径套件、实时/E2E、OpenWebUI、QA Lab 一致性、Matrix 和 Telegram 渠道。
只有在包已经发布,且还需要运行发布后的 Telegram E2E 时,才提供 `npm_telegram_package_spec`
示例:`gh workflow run full-release-validation.yml --ref main -f ref=release/YYYY.M.D`
- 当你希望在发布工作继续推进的同时,为某个包候选版本获得旁路验证时,运行手动的 `Package Acceptance` 工作流。对 `openclaw@beta`、`openclaw@latest` 或某个精确发布版本使用 `source=npm`;使用 `source=ref` 来打包受信任的分支 / 标签 / SHA对带必填 SHA-256 的 HTTPS tarball 使用 `source=url`或者对由其他 GitHub Actions 运行上传的 tarball 使用 `source=artifact`。该工作流会将候选版本解析为 `package-under-test`,针对该 tarball 复用 Docker E2E 发布调度器,并且可以按需运行已发布 npm 的 Telegram QA。
示例:`gh workflow run package-acceptance.yml --ref main -f source=npm -f package_spec=openclaw@beta -f suite_profile=product`
常见 profile
- `smoke`:安装 / channel / 智能体、Gateway 网关网络和配置重载通道
- `package`package / update / plugin 通道,不包含 OpenWebUI
- `product`package profile 加上 MCP 渠道、cron / subagent 清理、OpenAI web search 和 OpenWebUI
- `full`包含 OpenWebUI 的 Docker 发布路径分块
- `custom`:精确`docker_lanes` 选择,用于定向重跑
- 当你只需要对发布候选版本进行完整的常规 CI 覆盖时,直接运行手动 `CI` 工作流。手动触发的 CI 会绕过 changed 范围限制,并强制运行 Linux Node 分片、内置插件分片、渠道契约、Node 22 兼容性、`check`、`check-additional`、build smoke、文档检查、Python Skills、Windows、macOS、Android 和 Control UI i18n 通道。
- 当你希望在发布工作继续进行时,为某个候选包获取旁路证明,可运行手动 `Package Acceptance` 工作流。对 `openclaw@beta`、`openclaw@latest` 或精确发布版本使用 `source=npm`;使用 `source=ref` 通过当前 `workflow_ref` harness 打包可信的 `package_ref` 分支/标签/SHA对带必填 SHA-256 的 HTTPS tarball 使用 `source=url`;对由其他 GitHub Actions 运行上传的 tarball 使用 `source=artifact`。该工作流会将候选解析为 `package-under-test`,针对该 tarball 复用 Docker E2E 发布调度器,并且可运行已发布 npm 的 Telegram QA。
示例:`gh workflow run package-acceptance.yml --ref main -f workflow_ref=main -f source=npm -f package_spec=openclaw@beta -f suite_profile=product`
常见配置
- `smoke`:安装/渠道/智能体、Gateway 网关网络和配置重载通道
- `package`包/更新/插件通道,不含 OpenWebUI
- `product`在 package 配置基础上增加 MCP 渠道、cron/subagent 清理、OpenAI web search 和 OpenWebUI
- `full` OpenWebUI 的 Docker 发布路径分块
- `custom`:精确选择 `docker_lanes`,用于有针对性的重跑
- 当你只需要候选发布版本的完整常规 CI 覆盖时,直接运行手动 `CI` 工作流。手动 CI 派发会绕过变更范围裁剪,并强制运行 Linux Node 分片、内置插件分片、渠道契约、Node 22 兼容性、`check`、`check-additional`、构建冒烟、文档检查、Python Skills、Windows、macOS、Android 和 Control UI i18n 通道。
示例:`gh workflow run ci.yml --ref release/YYYY.M.D`
- 在验证发布遥测时运行 `pnpm qa:otel:smoke`。它通过本地 OTLP / HTTP 接收器运行 QA-lab并验证导出的 trace span 名称、有界属性以及内容 / 标识符脱敏,无需 Opik、Langfuse 或其他外部收集器。
- 在每次打标签发布前运行 `pnpm release:check`
- 发布检查现在在单独的手动工作流中运行:
- 在验证发布遥测时运行 `pnpm qa:otel:smoke`。它通过本地 OTLP/HTTP 接收器运行 QA-lab并验证导出的 trace span 名称、有界属性以及内容/标识符脱敏,而不需要 Opik、Langfuse 或其他外部收集器。
- 每次带标签发布之前都要运行 `pnpm release:check`
- 发布检查现在在一个单独的手动工作流中运行:
`OpenClaw Release Checks`
- `OpenClaw Release Checks` 还会在发布审批前运行 QA Lab mock 一致性检查,以及 live Matrix 和 Telegram QA 通道。live 通道使用 `qa-live-shared` 环境Telegram 还会使用 Convex CI 凭证租约。
- 跨操作系统的安装和升级运行时验证由私有调用方工作流
`openclaw/releases-private/.github/workflows/openclaw-cross-os-release-checks.yml`
分发,它会调用可复用的公开工作流
- `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`,它会调用可复用的公开工作流
`.github/workflows/openclaw-cross-os-release-checks-reusable.yml`
- 这种拆分是有意为之:让真实的 npm 发布路径保持简短、确定且以产物为中心,同时把较慢的 live 检查放在独立通道中,这样它们就不会拖慢或阻塞发布
- 带有密钥的发布检查应通过 `Full Release Validation` 分发,或从 `main` / release 工作流 ref 分发,以便工作流逻辑和密钥保持受控
- 这种拆分是有意为之:让真正的 npm 发布路径保持简短、确定性强且聚焦产物,而较慢的实时检查留在各自独立通道中,避免拖慢或阻塞发布
- 含密钥的发布检查应通过 `Full Release Validation` 派发,或从 `main`/发布工作流 ref 派发,以便工作流逻辑和密钥始终受控
- `OpenClaw Release Checks` 接受分支、标签或完整提交 SHA只要解析后的提交可从 OpenClaw 分支或发布标签到达即可
- `OpenClaw NPM Release` 的仅验证预检也接受当前工作流分支提交的完整 40 字符 SHA而不要求已推送的标签
- 该 SHA 路径仅用于验证,不能提升为真发布
- 在 SHA 模式下,工作流只会为包元数据检查合成 `v<package.json version>`;真发布仍然需要真实的发布标签
- 这两个工作流都将真实发布和提升路径保留在 GitHub 托管 runner 上,而不改变状态的验证路径则可以使用更大的 Blacksmith Linux runners
- `OpenClaw NPM Release` 的仅验证预检也接受当前工作流分支提交的完整 40 字符 SHA而不要求已推送的标签
- 该 SHA 路径仅用于验证,不能提升为真正的发布
- 在 SHA 模式下,工作流只会为包元数据检查合成 `v<package.json version>`;真发布仍然需要真实的发布标签
- 两个工作流都会把真正的发布和提升路径保留在 GitHub 托管 runner 上,而非变更性的验证路径则可以使用更大的 Blacksmith Linux runner
- 该工作流会运行
`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 / 修正版版本)以在全新临时前缀中验证已发布的 registry 安装路径
(或匹配的 beta/修正版版本),以便在全新的临时前缀中验证已发布的注册表安装路径
- beta 发布后,运行 `OPENCLAW_NPM_TELEGRAM_PACKAGE_SPEC=openclaw@YYYY.M.D-beta.N OPENCLAW_NPM_TELEGRAM_CREDENTIAL_SOURCE=convex OPENCLAW_NPM_TELEGRAM_CREDENTIAL_ROLE=ci pnpm test:docker:npm-telegram-live`
以针对已发布的 npm 包验证已安装包的新手引导、Telegram 设置和真实 Telegram E2E,使用共享租用的 Telegram 凭证池。本地维护者的一次性操作可以省略 Convex 变量,直接传入三个 `OPENCLAW_QA_TELEGRAM_*` 环境变量凭证。
- 维护者也可以通过 GitHub Actions 中手动 `NPM Telegram Beta E2E` 工作流运行相同的发布后检查。它有意设计为仅手动运行,不会在每次合并时执行。
- 维护者发布自动化现在采用“先预检再提升”:
- 真 npm 发布必须通过成功的 npm `preflight_run_id`
- 真实 npm 发布必须从与成功预检运行相同的 `main``release/YYYY.M.D` 分支分
- 稳定版 npm 发布默认目标为 `beta`
- 稳定版 npm 发布可以通过工作流输入显式将目标设为 `latest`
便使用共享租用的 Telegram 凭证池,针对已发布的 npm 包验证已安装包的新手引导、Telegram 设置和真实 Telegram E2E。维护者在本地一次性运行时可以省略 Convex 变量,并直接传入三个 `OPENCLAW_QA_TELEGRAM_*` 环境变量凭证。
- 维护者也可以通过 GitHub Actions 中手动 `NPM Telegram Beta E2E` 工作流运行相同的发布后检查。该工作流刻意只支持手动运行,不会在每次合并时执行。
- 维护者发布自动化现在使用“先预检查再提升”:
- 真正的 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 发布
出于安全原因,因为 `npm dist-tag add` 仍然需要 `NPM_TOKEN`,而公开仓库保持仅 OIDC 发布
- 公开的 `macOS Release` 仅用于验证
- 真的私有 mac 发布必须通过成功的私有 mac
- 真的私有 mac 发布必须通过成功的私有 mac
`preflight_run_id``validate_run_id`
- 真发布路径会提升已准备好的产物,而不是再次重新构建它们
- 对于像 `YYYY.M.D-N` 这样的稳定修正版发布,发布后验证器还会检查从 `YYYY.M.D` 升级到 `YYYY.M.D-N` 的同一临时前缀升级路径,以避免发布修正静默地让旧的全局安装仍停留在基础稳定版负载上
- npm 发布预检采用默认失败关闭策略,除非 tarball 同时包含 `dist/control-ui/index.html` 和非空的 `dist/control-ui/assets/` 负载,这样我们就不会再次发布一个空的浏览器仪表盘
- 发布后验证还会检查已发布的 registry 安装是否在根 `dist/*` 布局下包含非空的内置插件运行时依赖。若某次发布带有缺失或空的内置插件依赖负载,则发布后验证器会失败,并且不能被提升到 `latest`
- `pnpm test:install:smoke` 还会对候选更新 tarball 强制执行 npm pack `unpackedSize` 预算,因此安装器 e2e 可以在发布路径之前捕获意外的打包膨胀
- 如果发布工作触及了 CI 规划、扩展时序清单或扩展测试矩阵,请在审批前重新生成并审查 `.github/workflows/ci.yml`由规划器负责的 `checks-node-extensions` 工作流矩阵输出,以免发布说明描述过时的 CI 布局
- 稳定版 macOS 发布就绪性还包括更新器相关界面:
- GitHub 发布最终必须包含打包`.zip`、`.dmg` 和 `.dSYM.zip`
- 真正的发布路径会提升已准备好的产物,而不是再次重新构建
- 对于像 `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 发布最终必须包含打包`.zip`、`.dmg` 和 `.dSYM.zip`
- 发布后,`main` 上的 `appcast.xml` 必须指向新的稳定版 zip
- 打包后的应用必须保持非调试 bundle id、非空的 Sparkle feed URL以及不低于该发布版本规范 Sparkle build floor `CFBundleVersion`
- 打包后的应用必须保持非调试 bundle id、非空的 Sparkle feed URL以及不低于该发布版本规范 Sparkle 构建下限`CFBundleVersion`
## NPM 工作流输入
`OpenClaw NPM Release` 接受以下由操作人员控制的输入:
`OpenClaw NPM Release` 接受这些由操作人员控制的输入:
- `tag`:必填发布标签,例如 `v2026.4.2`、`v2026.4.2-1` 或
`v2026.4.2-beta.1`;当 `preflight_only=true` 时,也可以是当前工作流分支提交的完整 40 字符 SHA用于仅验证预检
- `preflight_only``true` 表示仅验证 / 构建 / 打包,`false` 表示真实发布路径
- `preflight_run_id`真实发布路径必填,这样工作流可以复用成功预检运行中准备好的 tarball
- `tag`:必填发布标签,例如 `v2026.4.2`、`v2026.4.2-1` 或
`v2026.4.2-beta.1`;当 `preflight_only=true` 时,也可以是当前工作流分支提交的完整 40 字符 SHA用于仅验证预检
- `preflight_only``true` 表示只做验证/构建/打包,`false` 表示真正的发布路径
- `preflight_run_id`在真正发布路径中必填,这样工作流才能复用成功预检查运行所准备的 tarball
- `npm_dist_tag`:发布路径的 npm 目标标签;默认为 `beta`
`OpenClaw Release Checks` 接受以下由操作人员控制的输入:
`OpenClaw Release Checks` 接受这些由操作人员控制的输入:
- `ref`:要验证的分支、标签或完整提交 SHA。密钥的检查要求解析后的提交必须可从 OpenClaw 分支或发布标签到达。
- `ref`:要验证的分支、标签或完整提交 SHA。密钥的检查要求解析后的提交必须可从 OpenClaw 分支或发布标签到达。
规则:
- 稳定版和修正版标签可以发布到 `beta``latest`
- 稳定标签和修正标签可以发布到 `beta``latest`
- Beta 预发布标签只能发布到 `beta`
- 对于 `OpenClaw NPM Release`,只有`preflight_only=true` 时才允许使用完整提交 SHA 作为输入
- 对于 `OpenClaw NPM Release`,只有`preflight_only=true` 时才允许输入完整提交 SHA
- `OpenClaw Release Checks``Full Release Validation` 始终仅用于验证
- 真实发布路径必须使用与预检期间相同的 `npm_dist_tag`;工作流会在发布继续前验证该元数据
- 真正的发布路径必须使用与预检查相同的 `npm_dist_tag`;工作流会在继续发布前验证该元数据
## 稳定 npm 发布顺序
## 稳定 npm 发布顺序
当切一个稳定版 npm 发布时:
切出稳定 npm 发布时:
1. 运行 `OpenClaw NPM Release`,并设置 `preflight_only=true`
- 在标签尚未存在之前,你可以使用当前工作流分支提交的完整 SHA对预检工作流进行一次仅验证的演练
2. 常规的 beta 优先流程选择 `npm_dist_tag=beta`,只有在你有意直接发布稳定版时才选择 `latest`
3. 当你希望通过一个手动工作流获得常规 CI 加上 live prompt cache、Docker、QA Lab、Matrix 和 Telegram 覆盖时,在发布分支、发布标签或完整提交 SHA 上运行 `Full Release Validation`
1. 使用 `preflight_only=true` 运行 `OpenClaw NPM Release`
- 在标签尚不存在之前,你可以使用当前工作流分支提交的完整
SHA对预检查工作流进行一次仅验证的预演
2. 常规的 beta 优先流程请选择 `npm_dist_tag=beta`,只有在你有意直接发布稳定版时才选择 `latest`
3. 当你希望通过一个手动工作流获得常规 CI 加上实时 prompt cache、Docker、QA Lab、
Matrix 和 Telegram 覆盖时,在发布分支、发布标签或完整提交 SHA 上运行 `Full Release Validation`
4. 如果你明确只需要确定性的常规测试图,则改为在发布 ref 上运行手动 `CI` 工作流
5. 保存成功的 `preflight_run_id`
6. 再次运行 `OpenClaw NPM Release`,并设置 `preflight_only=false`,同时使用相同的 `tag`、相同的 `npm_dist_tag` 以及已保存的 `preflight_run_id`
7. 如果该发布落在 `beta`,使用私有的
6. 再次运行 `OpenClaw NPM Release`,设置 `preflight_only=false`,并使用相同的
`tag`、相同的 `npm_dist_tag` 以及保存的 `preflight_run_id`
7. 如果该发布先落在 `beta`,使用私有的
`openclaw/releases-private/.github/workflows/openclaw-npm-dist-tags.yml`
工作流,将该稳定版本从 `beta` 提升到 `latest`
8. 如果该发布有意直接发布到 `latest`,并且 `beta`
也应立即跟随同一个稳定构建,则使用同一个私有工作流让两个 dist-tag 都指向该稳定版本,或者让其计划任务的自我修复同步稍后再移动 `beta`
8. 如果该发布有意直接发布到 `latest`,并且 `beta`
应立即跟随同一稳定构建,则使用同一个私有工作流将两个 dist-tag 都指向该稳定版本,或者让其计划中的自愈同步稍后再移动 `beta`
出于安全原因dist-tag 变更位于私有仓库中,因为它仍然需要
`NPM_TOKEN`,而公开仓库保持仅使用 OIDC 发布。
出于安全原因dist-tag 变更放在私有仓库中,因为它仍然需要
`NPM_TOKEN`,而公开仓库保持仅 OIDC 发布。
这样既记录了直接发布路径,也记录了 beta 优先提升路径,并且两者对操作人员都是可见的。
如果维护者必须回退到本地 npm 身份验证,只能在专用 tmux 会话内运行任何 1Password CLI`op`)命令。不要直接从主智能体 shell 调用 `op`;将其限制在 tmux 内可以让提示、告警和 OTP 处理保持可观察,并防止主机重复弹出告警。
如果维护者必须回退到本地 npm 身份验证,请仅在专用的 tmux 会话中运行任何 1Password
CLI`op`)命令。不要直接从主 agent shell 调用 `op`;将其限制在 tmux 中可以让提示、告警和 OTP 处理保持可观察,并防止主机重复弹出告警。
## 公开参考
## 公开参考资料
- [`.github/workflows/openclaw-npm-release.yml`](https://github.com/openclaw/openclaw/blob/main/.github/workflows/openclaw-npm-release.yml)
- [`.github/workflows/openclaw-release-checks.yml`](https://github.com/openclaw/openclaw/blob/main/.github/workflows/openclaw-release-checks.yml)