chore(i18n): refresh zh-CN translations
This commit is contained in:
parent
7dbc3a200d
commit
aa27364593
@ -1,21 +1,21 @@
|
||||
---
|
||||
read_when:
|
||||
- 调度后台作业或唤醒
|
||||
- 调度后台任务或唤醒
|
||||
- 将外部触发器(网络钩子、Gmail)接入 OpenClaw
|
||||
- 为定时任务决定使用心跳还是 cron
|
||||
- 为定时任务选择 Heartbeat 还是 cron
|
||||
sidebarTitle: Scheduled tasks
|
||||
summary: Gateway 网关调度器的定时任务、网络钩子和 Gmail PubSub 触发器
|
||||
summary: Gateway 网关调度器的定时作业、网络钩子和 Gmail PubSub 触发器
|
||||
title: 定时任务
|
||||
x-i18n:
|
||||
generated_at: "2026-04-29T15:58:19Z"
|
||||
generated_at: "2026-05-02T04:47:38Z"
|
||||
model: gpt-5.5
|
||||
provider: openai
|
||||
source_hash: 021e623bdea786178e0948e9905360c897c26d31fdf866e9af8cfc9538968d60
|
||||
source_hash: cdda94c3c31e4530e0944cd8f5667a7eb567fcff8e602d6a86d5699d078e9b48
|
||||
source_path: automation/cron-jobs.md
|
||||
workflow: 16
|
||||
---
|
||||
|
||||
Cron 是 Gateway 网关的内置调度器。它会持久化作业,在合适的时间唤醒智能体,并且可以将输出传送回聊天渠道或网络钩子端点。
|
||||
Cron 是 Gateway 网关内置的调度器。它会持久化任务,在正确时间唤醒智能体,并且可以把输出送回聊天渠道或 webhook 端点。
|
||||
|
||||
## 快速开始
|
||||
|
||||
@ -31,7 +31,7 @@ Cron 是 Gateway 网关的内置调度器。它会持久化作业,在合适的
|
||||
--delete-after-run
|
||||
```
|
||||
</Step>
|
||||
<Step title="检查你的作业">
|
||||
<Step title="检查你的任务">
|
||||
```bash
|
||||
openclaw cron list
|
||||
openclaw cron show <job-id>
|
||||
@ -46,41 +46,41 @@ Cron 是 Gateway 网关的内置调度器。它会持久化作业,在合适的
|
||||
|
||||
## cron 的工作方式
|
||||
|
||||
- Cron 在 **Gateway 网关**进程内运行(不在模型内运行)。
|
||||
- 作业定义会持久化到 `~/.openclaw/cron/jobs.json`,因此重启不会丢失计划。
|
||||
- Cron 在 **Gateway 网关** 进程内运行(不是在模型内)。
|
||||
- 任务定义会持久化到 `~/.openclaw/cron/jobs.json`,因此重启不会丢失计划。
|
||||
- 运行时执行状态会持久化到旁边的 `~/.openclaw/cron/jobs-state.json`。如果你在 git 中跟踪 cron 定义,请跟踪 `jobs.json`,并将 `jobs-state.json` 加入 gitignore。
|
||||
- 拆分之后,较旧的 OpenClaw 版本可以读取 `jobs.json`,但可能会将作业视为新作业,因为运行时字段现在位于 `jobs-state.json` 中。
|
||||
- 当 Gateway 网关正在运行或已停止时编辑 `jobs.json`,OpenClaw 会将变更后的计划字段与待处理的运行时槽位元数据进行比较,并清除过期的 `nextRunAtMs` 值。仅格式化或仅键顺序改写会保留待处理槽位。
|
||||
- 拆分后,较旧的 OpenClaw 版本可以读取 `jobs.json`,但可能会把任务视为全新任务,因为运行时字段现在位于 `jobs-state.json`。
|
||||
- 当 `jobs.json` 在 Gateway 网关运行或停止时被编辑,OpenClaw 会将变更后的计划字段与待处理的运行时槽位元数据进行比较,并清除过期的 `nextRunAtMs` 值。纯格式化或仅键顺序的重写会保留待处理槽位。
|
||||
- 所有 cron 执行都会创建[后台任务](/zh-CN/automation/tasks)记录。
|
||||
- Gateway 网关启动时,逾期的隔离智能体回合作业会被重新调度到渠道连接窗口之外,而不是立即重放,因此 Discord/Telegram 启动和原生命令设置在重启后仍能保持响应。
|
||||
- 一次性作业(`--at`)默认会在成功后自动删除。
|
||||
- 隔离 cron 运行完成时,会尽力为其 `cron:<jobId>` 会话关闭已跟踪的浏览器标签页/进程,因此脱离的浏览器自动化不会留下孤立进程。
|
||||
- 隔离 cron 运行还会防止过期的确认回复。如果第一个结果只是临时状态更新(`on it`、`pulling everything together` 以及类似提示),并且没有后代子智能体运行仍负责最终答案,OpenClaw 会在投递前重新提示一次以获取实际结果。
|
||||
- 隔离 cron 运行会优先使用嵌入式运行中的结构化执行拒绝元数据,然后回退到已知的最终摘要/输出标记,例如 `SYSTEM_RUN_DENIED` 和 `INVALID_REQUEST`,因此被阻止的命令不会被报告为绿色运行。
|
||||
- 隔离 cron 运行还会将运行级智能体失败视为作业错误,即使没有生成回复载荷也是如此,因此模型/提供商失败会递增错误计数并触发失败通知,而不是将作业清除为成功。
|
||||
- 当隔离智能体回合作业达到 `timeoutSeconds` 时,cron 会中止底层智能体运行,并给它一个短暂的清理窗口。如果该运行未能排空,Gateway 网关拥有的清理会在 cron 记录超时前强制清除该运行的会话所有权,因此排队的聊天工作不会被留在过期的处理中会话之后。
|
||||
- Gateway 网关启动时,已逾期的隔离智能体回合任务会被重新安排到渠道连接窗口之外,而不是立即重放,因此 Discord/Telegram 启动和原生命令设置在重启后仍保持响应。
|
||||
- 一次性任务(`--at`)默认在成功后自动删除。
|
||||
- 隔离 cron 运行在完成时会尽力为其 `cron:<jobId>` 会话关闭已跟踪的浏览器标签页/进程,因此分离的浏览器自动化不会留下孤立进程。
|
||||
- 隔离 cron 运行还会防止过期的确认回复。如果第一个结果只是临时状态更新(`on it`、`pulling everything together` 以及类似提示),并且没有后代子智能体运行仍负责最终答案,OpenClaw 会在交付前重新提示一次以获取实际结果。
|
||||
- 隔离 cron 运行会优先使用嵌入运行提供的结构化执行拒绝元数据,然后回退到已知的最终摘要/输出标记,例如 `SYSTEM_RUN_DENIED` 和 `INVALID_REQUEST`,因此被阻止的命令不会被报告为绿色运行。
|
||||
- 隔离 cron 运行还会将运行级智能体失败视为任务错误,即使没有生成回复载荷也是如此,因此模型/提供商失败会递增错误计数器并触发失败通知,而不是把任务清为成功。
|
||||
- 当隔离智能体回合任务达到 `timeoutSeconds` 时,cron 会中止底层智能体运行,并给它一个短暂的清理窗口。如果运行没有排空,Gateway 网关拥有的清理会在 cron 记录超时前强制清除该运行的会话所有权,因此排队的聊天工作不会被留在过期的处理中会话之后。
|
||||
|
||||
<a id="maintenance"></a>
|
||||
|
||||
<Note>
|
||||
cron 的任务协调首先由运行时拥有,其次由持久历史支撑:只要 cron 运行时仍将该作业跟踪为运行中,活动 cron 任务就会保持活动,即使旧的子会话行仍然存在。一旦运行时停止拥有该作业且 5 分钟宽限窗口到期,维护会检查持久化的运行日志和作业状态,以查找匹配的 `cron:<jobId>:<startedAt>` 运行。如果该持久历史显示终止结果,任务台账会据此完成;否则 Gateway 网关拥有的维护可以将任务标记为 `lost`。离线 CLI 审计可以从持久历史中恢复,但它不会把自己进程内的空活动作业集视为 Gateway 网关拥有的 cron 运行已经消失的证明。
|
||||
cron 的任务对账首先由运行时拥有,其次由持久历史支撑:只要 cron 运行时仍将该任务跟踪为运行中,活动 cron 任务就会保持存活,即使旧的子会话行仍然存在。一旦运行时停止拥有该任务且 5 分钟宽限窗口到期,维护检查会在持久化运行日志和任务状态中查找匹配的 `cron:<jobId>:<startedAt>` 运行。如果该持久历史显示终止结果,任务账本会据此完成;否则 Gateway 网关拥有的维护可以将任务标记为 `lost`。离线 CLI 审计可以从持久历史恢复,但它不会把自身空的进程内活动任务集合当作 Gateway 网关拥有的 cron 运行已消失的证明。
|
||||
</Note>
|
||||
|
||||
## 计划类型
|
||||
|
||||
| 类型 | CLI 标志 | 说明 |
|
||||
| 类型 | CLI 标志 | 描述 |
|
||||
| ------- | --------- | ------------------------------------------------------- |
|
||||
| `at` | `--at` | 一次性时间戳(ISO 8601 或像 `20m` 这样的相对时间) |
|
||||
| `at` | `--at` | 一次性时间戳(ISO 8601 或类似 `20m` 的相对时间) |
|
||||
| `every` | `--every` | 固定间隔 |
|
||||
| `cron` | `--cron` | 5 字段或 6 字段 cron 表达式,可选 `--tz` |
|
||||
|
||||
没有时区的时间戳会被视为 UTC。添加 `--tz America/New_York` 可按本地挂钟时间调度。
|
||||
没有时区的时间戳会被视为 UTC。添加 `--tz America/New_York` 可进行本地墙钟时间调度。
|
||||
|
||||
每小时整点的循环表达式会自动错开最多 5 分钟,以减少负载峰值。使用 `--exact` 强制精确时间,或使用 `--stagger 30s` 指定显式窗口。
|
||||
整点循环表达式会自动错开最多 5 分钟,以减少负载峰值。使用 `--exact` 强制精确定时,或使用 `--stagger 30s` 指定显式窗口。
|
||||
|
||||
### 月日期和周日期使用 OR 逻辑
|
||||
### 每月某日和每周某日使用 OR 逻辑
|
||||
|
||||
Cron 表达式由 [croner](https://github.com/Hexagon/croner) 解析。当月日期和周日期字段都不是通配符时,croner 会在**任一**字段匹配时匹配,而不是两个字段都匹配。这是标准的 Vixie cron 行为。
|
||||
Cron 表达式由 [croner](https://github.com/Hexagon/croner) 解析。当每月某日和每周某日字段都不是通配符时,croner 会在**任一**字段匹配时视为匹配,而不是两个都匹配。这是标准 Vixie cron 行为。
|
||||
|
||||
```
|
||||
# Intended: "9 AM on the 15th, only if it's a Monday"
|
||||
@ -88,45 +88,45 @@ Cron 表达式由 [croner](https://github.com/Hexagon/croner) 解析。当月日
|
||||
0 9 15 * 1
|
||||
```
|
||||
|
||||
这会每月触发约 5 到 6 次,而不是每月 0 到 1 次。OpenClaw 在这里使用 Croner 的默认 OR 行为。若要要求两个条件都满足,请使用 Croner 的 `+` 周日期修饰符(`0 9 15 * +1`),或在一个字段上调度,并在你的作业提示词或命令中守卫另一个字段。
|
||||
这会每月触发约 5 到 6 次,而不是每月 0 到 1 次。OpenClaw 在这里使用 Croner 的默认 OR 行为。若要要求两个条件都满足,请使用 Croner 的 `+` 每周某日修饰符(`0 9 15 * +1`),或只按一个字段调度,并在你的任务提示或命令中保护另一个条件。
|
||||
|
||||
## 执行风格
|
||||
## 执行样式
|
||||
|
||||
| 风格 | `--session` 值 | 运行位置 | 最适合 |
|
||||
| 样式 | `--session` 值 | 运行位置 | 最适合 |
|
||||
| --------------- | ------------------- | ------------------------ | ------------------------------- |
|
||||
| 主会话 | `main` | 下一个心跳回合 | 提醒、系统事件 |
|
||||
| 主会话 | `main` | 下一次 Heartbeat 回合 | 提醒、系统事件 |
|
||||
| 隔离 | `isolated` | 专用 `cron:<jobId>` | 报告、后台杂务 |
|
||||
| 当前会话 | `current` | 创建时绑定 | 上下文感知的循环工作 |
|
||||
| 自定义会话 | `session:custom-id` | 持久命名会话 | 基于历史构建的工作流 |
|
||||
|
||||
<AccordionGroup>
|
||||
<Accordion title="主会话、隔离和自定义的区别">
|
||||
**主会话**作业会将系统事件入队,并可选择唤醒心跳(`--wake now` 或 `--wake next-heartbeat`)。这些系统事件不会延长目标会话的每日/空闲重置新鲜度。**隔离**作业会以新会话运行专用智能体回合。**自定义会话**(`session:xxx`)会跨运行保留上下文,从而支持每日站会这类基于先前摘要构建的工作流。
|
||||
<Accordion title="主会话、隔离与自定义">
|
||||
**主会话**任务会将系统事件入队,并可选择唤醒 Heartbeat(`--wake now` 或 `--wake next-heartbeat`)。这些系统事件不会延长目标会话的每日/空闲重置新鲜度。**隔离**任务会使用新会话运行专用智能体回合。**自定义会话**(`session:xxx`)会跨运行保留上下文,支持每日站会等基于先前摘要构建的工作流。
|
||||
</Accordion>
|
||||
<Accordion title="隔离作业中“新会话”的含义">
|
||||
对于隔离作业,“新会话”表示每次运行都有新的转录/会话 id。OpenClaw 可能会携带安全偏好,例如 thinking/fast/verbose 设置、标签,以及用户显式选择的模型/凭证覆盖,但它不会从旧 cron 行继承环境会话上下文:渠道/群组路由、发送或队列策略、提权、来源,或 ACP 运行时绑定。当循环作业应有意基于同一对话上下文构建时,请使用 `current` 或 `session:<id>`。
|
||||
<Accordion title="隔离任务中的“新会话”含义">
|
||||
对于隔离任务,“新会话”表示每次运行都会有新的转录/会话 ID。OpenClaw 可能会携带安全偏好,例如思考/快速/详细设置、标签,以及显式用户选择的模型/凭证覆盖,但不会从旧 cron 行继承环境会话上下文:渠道/群组路由、发送或队列策略、提权、来源,或 ACP 运行时绑定。当循环任务应当有意基于同一个对话上下文构建时,请使用 `current` 或 `session:<id>`。
|
||||
</Accordion>
|
||||
<Accordion title="运行时清理">
|
||||
对于隔离作业,运行时拆除现在包括对该 cron 会话的尽力浏览器清理。清理失败会被忽略,因此实际 cron 结果仍然优先。
|
||||
对于隔离任务,运行时拆除现在包括针对该 cron 会话的尽力浏览器清理。清理失败会被忽略,因此实际 cron 结果仍然优先。
|
||||
|
||||
隔离 cron 运行还会通过共享运行时清理路径释放为该作业创建的任何内置 MCP 运行时实例。这与主会话和自定义会话 MCP 客户端的拆除方式一致,因此隔离 cron 作业不会跨运行泄漏 stdio 子进程或长期存在的 MCP 连接。
|
||||
隔离 cron 运行还会通过共享运行时清理路径释放为该任务创建的任何内置 MCP 运行时实例。这与主会话和自定义会话 MCP 客户端的拆除方式一致,因此隔离 cron 任务不会在运行之间泄漏 stdio 子进程或长生命周期 MCP 连接。
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="子智能体和 Discord 投递">
|
||||
当隔离 cron 运行编排子智能体时,投递也会优先使用最终后代输出,而不是过期的父级临时文本。如果后代仍在运行,OpenClaw 会抑制该部分父级更新,而不是宣布它。
|
||||
<Accordion title="子智能体与 Discord 交付">
|
||||
当隔离 cron 运行编排子智能体时,交付也会优先使用最终后代输出,而不是过期的父级临时文本。如果后代仍在运行,OpenClaw 会抑制该部分父级更新,而不是宣布它。
|
||||
|
||||
对于仅文本的 Discord 公告目标,OpenClaw 会发送一次规范的最终助手文本,而不是同时重放流式/中间文本载荷和最终答案。媒体和结构化 Discord 载荷仍会作为单独载荷投递,因此附件和组件不会被丢弃。
|
||||
对于纯文本 Discord announce 目标,OpenClaw 会发送一次规范最终助手文本,而不是同时重放流式/中间文本载荷和最终答案。媒体和结构化 Discord 载荷仍会作为单独载荷交付,因此附件和组件不会被丢弃。
|
||||
|
||||
</Accordion>
|
||||
</AccordionGroup>
|
||||
|
||||
### 隔离作业的载荷选项
|
||||
### 隔离任务的载荷选项
|
||||
|
||||
<ParamField path="--message" type="string" required>
|
||||
提示词文本(隔离作业必需)。
|
||||
提示文本(隔离任务必需)。
|
||||
</ParamField>
|
||||
<ParamField path="--model" type="string">
|
||||
模型覆盖;使用为该作业选择的允许模型。
|
||||
模型覆盖;使用该任务所选的允许模型。
|
||||
</ParamField>
|
||||
<ParamField path="--thinking" type="string">
|
||||
思考级别覆盖。
|
||||
@ -135,47 +135,49 @@ Cron 表达式由 [croner](https://github.com/Hexagon/croner) 解析。当月日
|
||||
跳过工作区引导文件注入。
|
||||
</ParamField>
|
||||
<ParamField path="--tools" type="string">
|
||||
限制该作业可以使用的工具,例如 `--tools exec,read`。
|
||||
限制任务可使用的工具,例如 `--tools exec,read`。
|
||||
</ParamField>
|
||||
|
||||
`--model` 使用选定的允许模型作为该作业的主模型。它不同于聊天会话 `/model` 覆盖:当作业主模型失败时,配置的回退链仍然适用。如果请求的模型不被允许或无法解析,cron 会让该运行以显式验证错误失败,而不是静默回退到该作业的智能体/默认模型选择。
|
||||
`--model` 会使用所选允许模型作为该任务的主模型。它不同于聊天会话 `/model` 覆盖:当任务主模型失败时,已配置的回退链仍会应用。如果请求的模型不被允许或无法解析,cron 会以显式验证错误使运行失败,而不是静默回退到任务的智能体/默认模型选择。
|
||||
|
||||
Cron 作业也可以携带载荷级 `fallbacks`。存在时,该列表会替换该作业的已配置回退链。当你需要严格的 cron 运行,只尝试选定模型时,请在作业载荷/API 中使用 `fallbacks: []`。如果作业有 `--model`,但没有载荷回退或已配置回退,OpenClaw 会传入显式空回退覆盖,因此智能体主模型不会被追加为隐藏的额外重试目标。
|
||||
Cron 任务还可以携带载荷级 `fallbacks`。存在时,该列表会替换该任务的已配置回退链。当你想要严格的 cron 运行、只尝试所选模型时,请在任务载荷/API 中使用 `fallbacks: []`。如果任务有 `--model`,但既没有载荷回退也没有已配置回退,OpenClaw 会传递显式空回退覆盖,因此智能体主模型不会作为隐藏的额外重试目标追加。
|
||||
|
||||
隔离作业的模型选择优先级为:
|
||||
隔离任务的模型选择优先级如下:
|
||||
|
||||
1. Gmail 钩子模型覆盖(当运行来自 Gmail 且该覆盖被允许时)
|
||||
2. 每作业载荷 `model`
|
||||
3. 用户选择的已存储 cron 会话模型覆盖
|
||||
2. 每任务载荷 `model`
|
||||
3. 用户选择并存储的 cron 会话模型覆盖
|
||||
4. 智能体/默认模型选择
|
||||
|
||||
快速模式也会跟随解析后的实时选择。如果选定模型配置有 `params.fastMode`,隔离 cron 默认使用它。已存储会话 `fastMode` 覆盖仍会在任一方向上优先于配置。
|
||||
快速模式也会遵循解析后的实时选择。如果所选模型配置具有 `params.fastMode`,隔离 cron 默认使用该值。已存储的会话 `fastMode` 覆盖仍会在任一方向上优先于配置。
|
||||
|
||||
如果隔离运行遇到实时模型切换交接,cron 会使用切换后的提供商/模型重试,并在重试前为活动运行持久化该实时选择。当切换还携带新的凭证配置文件时,cron 也会为活动运行持久化该凭证配置文件覆盖。重试有边界:初始尝试加 2 次切换重试之后,cron 会中止,而不是无限循环。
|
||||
如果隔离运行命中实时模型切换交接,cron 会使用切换后的提供商/模型重试,并在重试前为活动运行持久化该实时选择。当切换还携带新的凭证配置文件时,cron 也会为活动运行持久化该凭证配置文件覆盖。重试有上限:初始尝试加 2 次切换重试后,cron 会中止而不是无限循环。
|
||||
|
||||
在隔离 cron 运行进入智能体运行器之前,OpenClaw 会检查已配置的 `api: "ollama"` 和 `api: "openai-completions"` 提供商的可达本地提供商端点,其 `baseUrl` 为 local loopback、私有网络或 `.local`。如果该端点宕机,运行会被记录为 `skipped`,并给出清晰的提供商/模型错误,而不是开始模型调用。端点结果会缓存 5 分钟,因此大量到期作业使用同一个已宕机的本地 Ollama、vLLM、SGLang 或 LM Studio 服务器时,会共享一次小探测,而不是造成请求风暴。跳过的提供商预检运行不会递增执行错误退避;当你需要重复跳过通知时,启用 `failureAlert.includeSkipped`。
|
||||
在隔离 cron 运行进入智能体运行器之前,OpenClaw 会检查可达的本地提供商端点,面向配置了 `api: "ollama"` 和 `api: "openai-completions"` 且其 `baseUrl` 为 loopback、专用网络或 `.local` 的提供商。如果该端点不可用,运行会被记录为 `skipped`,并带有清晰的提供商/模型错误,而不是开始模型调用。端点结果会缓存 5 分钟,因此许多到期任务如果使用同一个宕掉的本地 Ollama、vLLM、SGLang 或 LM Studio 服务器,会共享一次小型探测,而不是制造请求风暴。跳过的提供商预检运行不会递增执行错误退避;当你想要重复跳过通知时,请启用 `failureAlert.includeSkipped`。
|
||||
|
||||
## 投递和输出
|
||||
## 交付和输出
|
||||
|
||||
| 模式 | 会发生什么 |
|
||||
| 模式 | 发生的事情 |
|
||||
| ---------- | ------------------------------------------------------------------- |
|
||||
| `announce` | 如果智能体没有发送,则向目标回退投递最终文本 |
|
||||
| `announce` | 如果智能体未发送,则向目标回退交付最终文本 |
|
||||
| `webhook` | 将完成事件载荷 POST 到 URL |
|
||||
| `none` | 无运行器回退投递 |
|
||||
| `none` | 无运行器回退交付 |
|
||||
|
||||
使用 `--announce --channel telegram --to "-1001234567890"` 进行渠道投递。对于 Telegram 论坛主题,使用 `-1001234567890:topic:123`;直接 RPC/配置调用方也可以传入字符串或数字形式的 `delivery.threadId`。Slack/Discord/Mattermost 目标应使用显式前缀(`channel:<id>`、`user:<id>`)。Matrix 房间 ID 区分大小写;请使用 Matrix 中的精确房间 ID 或 `room:!room:server` 形式。
|
||||
Use `--announce --channel telegram --to "-1001234567890"` 进行渠道投递。对于 Telegram 论坛主题,请使用 `-1001234567890:topic:123`;直接 RPC/配置调用方也可以将 `delivery.threadId` 作为字符串或数字传入。Slack/Discord/Mattermost 目标应使用显式前缀(`channel:<id>`、`user:<id>`)。Matrix 房间 ID 区分大小写;请使用精确的房间 ID,或使用来自 Matrix 的 `room:!room:server` 形式。
|
||||
|
||||
对于隔离任务,聊天投递是共享的。如果聊天路由可用,即使任务使用 `--no-deliver`,智能体也可以使用 `message` 工具。如果智能体发送到已配置/当前目标,OpenClaw 会跳过后备公告。否则,`announce`、`webhook` 和 `none` 只控制运行器在智能体回合后如何处理最终回复。
|
||||
当公告投递使用 `channel: "last"` 或省略 `channel` 时,带提供商前缀的目标(例如 `telegram:123`)可以在 cron 回退到会话历史或单个已配置渠道之前选择渠道。只有已加载插件所声明的前缀才是提供商选择器。如果 `delivery.channel` 是显式设置的,目标前缀必须命名同一个提供商;例如,`channel: "whatsapp"` 搭配 `to: "telegram:123"` 会被拒绝,而不是让 WhatsApp 将 Telegram ID 解释为电话号码。目标类型和服务前缀(例如 `channel:<id>`、`user:<id>`、`imessage:<handle>` 和 `sms:<number>`)仍然是渠道拥有的目标语法,而不是提供商选择器。
|
||||
|
||||
当智能体从活跃聊天创建隔离提醒时,OpenClaw 会为后备公告路由存储保留的实时投递目标。内部会话键可以是小写;当当前聊天上下文可用时,不会从这些键重建提供商投递目标。
|
||||
对于隔离作业,聊天投递是共享的。如果聊天路由可用,即使作业使用 `--no-deliver`,智能体也可以使用 `message` 工具。如果智能体发送到已配置/当前目标,OpenClaw 会跳过回退公告。否则,`announce`、`webhook` 和 `none` 只控制运行器在智能体轮次结束后如何处理最终回复。
|
||||
|
||||
当智能体从活动聊天中创建隔离提醒时,OpenClaw 会为回退公告路由存储保留下来的实时投递目标。内部会话键可以是小写;当当前聊天上下文可用时,不会从这些键重建提供商投递目标。
|
||||
|
||||
失败通知遵循单独的目标路径:
|
||||
|
||||
- `cron.failureDestination` 设置失败通知的全局默认值。
|
||||
- `job.delivery.failureDestination` 按任务覆盖该值。
|
||||
- 如果两者都未设置,并且任务已通过 `announce` 投递,失败通知现在会回退到该主公告目标。
|
||||
- 除非主投递模式是 `webhook`,否则 `delivery.failureDestination` 仅支持 `sessionTarget="isolated"` 任务。
|
||||
- `failureAlert.includeSkipped: true` 让任务或全局 cron 告警策略启用重复的已跳过运行告警。已跳过运行会保留单独的连续跳过计数器,因此不会影响执行错误退避。
|
||||
- `cron.failureDestination` 为失败通知设置全局默认值。
|
||||
- `job.delivery.failureDestination` 会按作业覆盖该设置。
|
||||
- 如果两者都未设置,并且作业已经通过 `announce` 投递,失败通知现在会回退到该主要公告目标。
|
||||
- `delivery.failureDestination` 仅在 `sessionTarget="isolated"` 作业上受支持,除非主要投递模式是 `webhook`。
|
||||
- `failureAlert.includeSkipped: true` 会让作业或全局 cron 警报策略启用重复的跳过运行警报。跳过的运行会保留单独的连续跳过计数器,因此不会影响执行错误退避。
|
||||
|
||||
## CLI 示例
|
||||
|
||||
@ -220,7 +222,7 @@ Cron 作业也可以携带载荷级 `fallbacks`。存在时,该列表会替换
|
||||
|
||||
## Webhook
|
||||
|
||||
Gateway 网关可以公开 HTTP webhook 端点,用于外部触发。在配置中启用:
|
||||
Gateway 网关可以暴露 HTTP webhook 端点,用于外部触发器。在配置中启用:
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -234,16 +236,16 @@ Gateway 网关可以公开 HTTP webhook 端点,用于外部触发。在配置
|
||||
|
||||
### 身份验证
|
||||
|
||||
每个请求都必须通过请求头包含 hook token:
|
||||
每个请求都必须通过标头包含钩子令牌:
|
||||
|
||||
- `Authorization: Bearer <token>`(推荐)
|
||||
- `x-openclaw-token: <token>`
|
||||
|
||||
查询字符串 token 会被拒绝。
|
||||
查询字符串令牌会被拒绝。
|
||||
|
||||
<AccordionGroup>
|
||||
<Accordion title="POST /hooks/wake">
|
||||
为主会话将一个系统事件加入队列:
|
||||
为主会话将系统事件加入队列:
|
||||
|
||||
```bash
|
||||
curl -X POST http://127.0.0.1:18789/hooks/wake \
|
||||
@ -261,7 +263,7 @@ Gateway 网关可以公开 HTTP webhook 端点,用于外部触发。在配置
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="POST /hooks/agent">
|
||||
运行一次隔离的智能体回合:
|
||||
运行隔离的智能体轮次:
|
||||
|
||||
```bash
|
||||
curl -X POST http://127.0.0.1:18789/hooks/agent \
|
||||
@ -274,19 +276,19 @@ Gateway 网关可以公开 HTTP webhook 端点,用于外部触发。在配置
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="Mapped hooks (POST /hooks/<name>)">
|
||||
自定义 hook 名称会通过配置中的 `hooks.mappings` 解析。映射可以使用模板或代码转换,将任意载荷转换为 `wake` 或 `agent` 操作。
|
||||
自定义钩子名称会通过配置中的 `hooks.mappings` 解析。映射可以使用模板或代码转换,将任意载荷转换为 `wake` 或 `agent` 操作。
|
||||
</Accordion>
|
||||
</AccordionGroup>
|
||||
|
||||
<Warning>
|
||||
请将 hook 端点置于 loopback、tailnet 或受信任的反向代理之后。
|
||||
请将钩子端点放在 loopback、tailnet 或受信任的反向代理之后。
|
||||
|
||||
- 使用专用 hook token;不要复用 Gateway 网关身份验证 token。
|
||||
- 使用专用钩子令牌;不要复用 Gateway 网关身份验证令牌。
|
||||
- 将 `hooks.path` 保持在专用子路径;`/` 会被拒绝。
|
||||
- 设置 `hooks.allowedAgentIds` 以限制显式 `agentId` 路由。
|
||||
- 除非需要调用方选择会话,否则保持 `hooks.allowRequestSessionKey=false`。
|
||||
- 除非你需要由调用方选择会话,否则保持 `hooks.allowRequestSessionKey=false`。
|
||||
- 如果启用 `hooks.allowRequestSessionKey`,也请设置 `hooks.allowedSessionKeyPrefixes` 以约束允许的会话键形状。
|
||||
- 默认情况下,hook 载荷会使用安全边界包装。
|
||||
- 默认情况下,钩子载荷会用安全边界包装。
|
||||
|
||||
</Warning>
|
||||
|
||||
@ -295,7 +297,7 @@ Gateway 网关可以公开 HTTP webhook 端点,用于外部触发。在配置
|
||||
通过 Google PubSub 将 Gmail 收件箱触发器接入 OpenClaw。
|
||||
|
||||
<Note>
|
||||
**前提条件:** `gcloud` CLI、`gog`(gogcli)、已启用的 OpenClaw hooks、用于公共 HTTPS 端点的 Tailscale。
|
||||
**前提条件:**`gcloud` CLI、`gog`(gogcli)、已启用的 OpenClaw 钩子、用于公共 HTTPS 端点的 Tailscale。
|
||||
</Note>
|
||||
|
||||
### 向导设置(推荐)
|
||||
@ -304,11 +306,11 @@ Gateway 网关可以公开 HTTP webhook 端点,用于外部触发。在配置
|
||||
openclaw webhooks gmail setup --account openclaw@gmail.com
|
||||
```
|
||||
|
||||
这会写入 `hooks.gmail` 配置,启用 Gmail preset,并使用 Tailscale Funnel 作为推送端点。
|
||||
这会写入 `hooks.gmail` 配置,启用 Gmail 预设,并使用 Tailscale Funnel 作为推送端点。
|
||||
|
||||
### Gateway 网关自动启动
|
||||
|
||||
当 `hooks.enabled=true` 且设置了 `hooks.gmail.account` 时,Gateway 网关会在启动时启动 `gog gmail watch serve`,并自动续期 watch。设置 `OPENCLAW_SKIP_GMAIL_WATCHER=1` 可选择退出。
|
||||
当 `hooks.enabled=true` 且设置了 `hooks.gmail.account` 时,Gateway 网关会在启动时启动 `gog gmail watch serve`,并自动续订 watch。设置 `OPENCLAW_SKIP_GMAIL_WATCHER=1` 可选择退出。
|
||||
|
||||
### 手动一次性设置
|
||||
|
||||
@ -354,7 +356,7 @@ openclaw webhooks gmail setup --account openclaw@gmail.com
|
||||
}
|
||||
```
|
||||
|
||||
## 管理任务
|
||||
## 管理作业
|
||||
|
||||
```bash
|
||||
# List all jobs
|
||||
@ -386,12 +388,12 @@ openclaw cron edit <jobId> --clear-agent
|
||||
<Note>
|
||||
模型覆盖说明:
|
||||
|
||||
- `openclaw cron add|edit --model ...` 会更改任务选择的模型。
|
||||
- 如果该模型被允许,那个精确的提供商/模型会进入隔离智能体运行。
|
||||
- 如果不被允许或无法解析,cron 会因明确的验证错误而使该次运行失败。
|
||||
- 已配置的后备链仍会生效,因为 cron `--model` 是任务主模型,而不是会话 `/model` 覆盖。
|
||||
- 载荷中的 `fallbacks` 会替换该任务的已配置后备项;`fallbacks: []` 会禁用后备并使运行严格执行。
|
||||
- 没有显式或已配置后备列表的普通 `--model`,不会静默回退到智能体主模型作为额外重试目标。
|
||||
- `openclaw cron add|edit --model ...` 会更改作业选择的模型。
|
||||
- 如果允许该模型,那个精确的提供商/模型会到达隔离智能体运行。
|
||||
- 如果不允许或无法解析,cron 会以显式验证错误让该运行失败。
|
||||
- 已配置的回退链仍然适用,因为 cron `--model` 是作业主模型,而不是会话 `/model` 覆盖。
|
||||
- 载荷 `fallbacks` 会替换该作业已配置的回退;`fallbacks: []` 会禁用回退并让运行变为严格模式。
|
||||
- 如果没有显式或已配置的回退列表,普通 `--model` 不会静默落入智能体主模型作为额外重试目标。
|
||||
|
||||
</Note>
|
||||
|
||||
@ -415,19 +417,19 @@ openclaw cron edit <jobId> --clear-agent
|
||||
}
|
||||
```
|
||||
|
||||
`maxConcurrentRuns` 同时限制计划 cron 调度和隔离智能体回合执行。隔离 cron 智能体回合在内部使用队列专用的 `cron-nested` 执行通道,因此提高此值会让独立的 cron LLM 运行并行推进,而不只是启动它们的外层 cron 包装器。共享的非 cron `nested` 通道不会被此设置扩宽。
|
||||
`maxConcurrentRuns` 会限制计划的 cron 调度和隔离智能体轮次执行。隔离 cron 智能体轮次会在内部使用队列专用的 `cron-nested` 执行通道,因此提高此值会让独立的 cron LLM 运行并行推进,而不是只启动它们的外层 cron 包装器。共享的非 cron `nested` 通道不会被此设置拓宽。
|
||||
|
||||
运行时状态 sidecar 派生自 `cron.store`:像 `~/clawd/cron/jobs.json` 这样的 `.json` 存储会使用 `~/clawd/cron/jobs-state.json`,而没有 `.json` 后缀的存储路径会追加 `-state.json`。
|
||||
|
||||
如果你手动编辑 `jobs.json`,请不要将 `jobs-state.json` 纳入源代码控制。OpenClaw 使用该 sidecar 存放待处理槽位、活跃标记、上次运行元数据,以及告诉调度器外部编辑的任务何时需要新的 `nextRunAtMs` 的计划标识。
|
||||
如果你手动编辑 `jobs.json`,请不要将 `jobs-state.json` 放入源代码控制。OpenClaw 使用该 sidecar 存放待处理槽位、活动标记、上次运行元数据,以及用于告诉调度器外部编辑的作业何时需要新的 `nextRunAtMs` 的计划身份。
|
||||
|
||||
禁用 cron:`cron.enabled: false` 或 `OPENCLAW_SKIP_CRON=1`。
|
||||
|
||||
<AccordionGroup>
|
||||
<Accordion title="Retry behavior">
|
||||
**一次性重试**:瞬态错误(速率限制、过载、网络、服务器错误)会使用指数退避最多重试 3 次。永久错误会立即禁用。
|
||||
**一次性重试**:瞬态错误(速率限制、过载、网络、服务器错误)最多重试 3 次,并使用指数退避。永久错误会立即禁用。
|
||||
|
||||
**重复重试**:重试之间使用指数退避(30 秒到 60 分钟)。下一次成功运行后会重置退避。
|
||||
**重复任务重试**:重试之间使用指数退避(30 秒到 60 分钟)。下一次成功运行后退避会重置。
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="Maintenance">
|
||||
@ -453,37 +455,37 @@ openclaw doctor
|
||||
<AccordionGroup>
|
||||
<Accordion title="Cron not firing">
|
||||
- 检查 `cron.enabled` 和 `OPENCLAW_SKIP_CRON` 环境变量。
|
||||
- 确认 Gateway 网关正在持续运行。
|
||||
- 对于 `cron` 计划,检查时区(`--tz`)与主机时区是否一致。
|
||||
- 运行输出中的 `reason: not-due` 表示手动运行是通过 `openclaw cron run <jobId> --due` 检查的,并且任务尚未到期。
|
||||
- 确认 Gateway 网关持续运行。
|
||||
- 对于 `cron` 计划,请核对时区(`--tz`)与主机时区。
|
||||
- 运行输出中的 `reason: not-due` 表示手动运行是通过 `openclaw cron run <jobId> --due` 检查的,并且作业尚未到期。
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="Cron fired but no delivery">
|
||||
- 投递模式 `none` 表示不应有运行器后备发送。当聊天路由可用时,智能体仍可使用 `message` 工具直接发送。
|
||||
<Accordion title="Cron 已触发但没有投递">
|
||||
- 投递模式 `none` 表示不会有预期的 runner 回退发送。只要有可用的聊天路由,智能体仍然可以直接用 `message` 工具发送。
|
||||
- 投递目标缺失/无效(`channel`/`to`)表示出站已跳过。
|
||||
- 对于 Matrix,复制的任务或旧任务中小写的 `delivery.to` 房间 ID 可能会失败,因为 Matrix 房间 ID 区分大小写。请将任务编辑为 Matrix 中的精确 `!room:server` 或 `room:!room:server` 值。
|
||||
- 渠道身份验证错误(`unauthorized`、`Forbidden`)表示投递被凭证阻止。
|
||||
- 如果隔离运行只返回静默 token(`NO_REPLY` / `no_reply`),OpenClaw 会抑制直接出站投递,也会抑制后备排队摘要路径,因此不会向聊天发布任何内容。
|
||||
- 如果智能体应自行给用户发消息,请检查任务是否有可用路由(带有先前聊天的 `channel: "last"`,或显式渠道/目标)。
|
||||
- 对于 Matrix,复制的或旧版任务如果包含小写的 `delivery.to` 房间 ID,可能会失败,因为 Matrix 房间 ID 区分大小写。请将任务编辑为来自 Matrix 的精确 `!room:server` 或 `room:!room:server` 值。
|
||||
- 渠道认证错误(`unauthorized`、`Forbidden`)表示投递被凭证阻止。
|
||||
- 如果隔离运行只返回静默标记(`NO_REPLY` / `no_reply`),OpenClaw 会抑制直接出站投递,也会抑制回退的队列摘要路径,因此不会有任何内容发回聊天。
|
||||
- 如果智能体应该自己给用户发消息,请检查任务是否有可用路由(`channel: "last"` 且有之前的聊天,或显式的渠道/目标)。
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="Cron 或心跳似乎阻止了 /new-style 轮转">
|
||||
- 每日重置和空闲重置的时效判定不基于 `updatedAt`;请参阅[会话管理](/zh-CN/concepts/session#session-lifecycle)。
|
||||
- Cron 唤醒、心跳运行、exec 通知和 Gateway 网关的内部维护可能会为了路由/Status 更新会话行,但它们不会延长 `sessionStartedAt` 或 `lastInteractionAt`。
|
||||
- 对于在这些字段存在之前创建的旧版行,如果文件仍然可用,OpenClaw 可以从会话记录 JSONL 的会话头中恢复 `sessionStartedAt`。没有 `lastInteractionAt` 的旧版空闲行会使用该恢复出的开始时间作为空闲基线。
|
||||
<Accordion title="Cron 或 Heartbeat 似乎阻止 /new-style 滚动切换">
|
||||
- 每日和空闲重置的新鲜度不是基于 `updatedAt`;请参阅[会话管理](/zh-CN/concepts/session#session-lifecycle)。
|
||||
- Cron 唤醒、Heartbeat 运行、exec 通知和 Gateway 网关记账可能会更新用于路由/Status 的会话行,但它们不会延长 `sessionStartedAt` 或 `lastInteractionAt`。
|
||||
- 对于在这些字段存在之前创建的旧版行,只要文件仍可用,OpenClaw 就可以从 transcript JSONL 会话头中恢复 `sessionStartedAt`。没有 `lastInteractionAt` 的旧版空闲行会使用该恢复的开始时间作为其空闲基线。
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="时区注意事项">
|
||||
- 未带 `--tz` 的 Cron 使用 Gateway 网关主机时区。
|
||||
- 未指定时区的 `at` 调度会按 UTC 处理。
|
||||
- 心跳 `activeHours` 使用配置的时区解析。
|
||||
- 不带 `--tz` 的 Cron 使用 Gateway 网关主机时区。
|
||||
- 不带时区的 `at` 定时会按 UTC 处理。
|
||||
- Heartbeat `activeHours` 使用配置的时区解析。
|
||||
|
||||
</Accordion>
|
||||
</AccordionGroup>
|
||||
|
||||
## 相关内容
|
||||
## 相关
|
||||
|
||||
- [自动化和任务](/zh-CN/automation) — 一览所有自动化机制
|
||||
- [后台任务](/zh-CN/automation/tasks) — Cron 执行的任务台账
|
||||
- [心跳](/zh-CN/gateway/heartbeat) — 定期的主会话轮次
|
||||
- [自动化与任务](/zh-CN/automation) — 所有自动化机制一览
|
||||
- [后台任务](/zh-CN/automation/tasks) — Cron 执行的任务账本
|
||||
- [Heartbeat](/zh-CN/gateway/heartbeat) — 定期的主会话轮次
|
||||
- [时区](/zh-CN/concepts/timezone) — 时区配置
|
||||
|
||||
@ -1,87 +1,93 @@
|
||||
---
|
||||
read_when:
|
||||
- 更改渠道路由或收件箱行为
|
||||
summary: 各个渠道(WhatsApp、Telegram、Discord、Slack)的路由规则和共享上下文
|
||||
summary: 各渠道(WhatsApp、Telegram、Discord、Slack)的路由规则和共享上下文
|
||||
title: 渠道路由
|
||||
x-i18n:
|
||||
generated_at: "2026-04-27T20:15:01Z"
|
||||
model: gpt-5.4
|
||||
generated_at: "2026-05-02T04:47:21Z"
|
||||
model: gpt-5.5
|
||||
provider: openai
|
||||
source_hash: c43347048fcfd137cc3a0b2cfdc4cf36426fdcf9645f2d1a05ce9cf49688cf0d
|
||||
source_hash: 9a752696e70d2c13d3ab1c9cedd41442e0d8aee6d78b3a069b53dd2b262174da
|
||||
source_path: channels/channel-routing.md
|
||||
workflow: 15
|
||||
workflow: 16
|
||||
---
|
||||
|
||||
# 渠道与路由
|
||||
|
||||
OpenClaw 会将回复**发回消息来源的那个渠道**。模型不会选择渠道;路由是确定性的,并由宿主配置控制。
|
||||
OpenClaw 会将回复**发送回消息来源的渠道**。模型不会选择渠道;路由是确定性的,并由主机配置控制。
|
||||
|
||||
## 关键术语
|
||||
|
||||
- **渠道**:`telegram`、`whatsapp`、`discord`、`irc`、`googlechat`、`slack`、`signal`、`imessage`、`line`,以及插件渠道。`webchat` 是内部 WebChat UI 渠道,不是可配置的出站渠道。
|
||||
- **AccountId**:每个渠道的账户实例(在支持时)。
|
||||
- 可选的渠道默认账户:`channels.<channel>.defaultAccount` 用于选择当出站路径未指定 `accountId` 时使用哪个账户。
|
||||
- 在多账户设置中,当配置了两个或更多账户时,请设置显式默认值(`defaultAccount` 或 `accounts.default`)。否则,回退路由可能会选择第一个规范化后的账户 ID。
|
||||
- **AgentId**:一个隔离的工作区 + 会话存储(“大脑”)。
|
||||
- **SessionKey**:用于存储上下文并控制并发的桶键。
|
||||
- 可选的渠道默认账户:`channels.<channel>.defaultAccount` 选择在出站路径未指定 `accountId` 时使用哪个账户。
|
||||
- 在多账户设置中,如果配置了两个或更多账户,请设置显式默认值(`defaultAccount` 或 `accounts.default`)。如果不设置,回退路由可能会选择第一个规范化后的账户 ID。
|
||||
- **AgentId**:隔离的工作区 + 会话存储(“大脑”)。
|
||||
- **SessionKey**:用于存储上下文和控制并发的桶键。
|
||||
|
||||
## 会话键形状(示例)
|
||||
## 出站目标前缀
|
||||
|
||||
默认情况下,私信会收敛到智能体的**主**会话:
|
||||
显式出站目标可以包含提供商前缀,例如 `telegram:123` 或 `tg:123`。只有当选中的渠道是 `last` 或仍未解析,并且已加载的插件声明了该前缀时,核心才会将该前缀视为渠道选择提示。如果调用方已经选择了显式渠道,提供商前缀必须匹配该渠道;诸如将 WhatsApp 投递到 `telegram:123` 这类跨渠道组合,会在插件特定目标规范化之前失败。
|
||||
|
||||
目标类型和服务前缀,例如 `channel:<id>`、`user:<id>`、`room:<id>`、`thread:<id>`、`imessage:<handle>` 和 `sms:<number>`,保留在所选渠道的语法内。它们本身不会选择提供商。
|
||||
|
||||
## 会话键形态(示例)
|
||||
|
||||
默认情况下,私信会折叠到智能体的 **main** 会话:
|
||||
|
||||
- `agent:<agentId>:<mainKey>`(默认:`agent:main:main`)
|
||||
|
||||
即使私信会话历史默认与主会话共享,对于外部私信,沙箱和工具策略仍会使用派生出的按账户划分的直接聊天运行时键,这样源自渠道的消息就不会被当作本地主会话运行来处理。
|
||||
即使私信对话历史与 main 共享,沙箱和工具策略也会为外部私信使用派生的、按账户区分的私聊运行时键,因此来自渠道的消息不会被当作本地 main 会话运行来处理。
|
||||
|
||||
群组和频道在每个渠道内仍然彼此隔离:
|
||||
群组和频道会按渠道保持隔离:
|
||||
|
||||
- 群组:`agent:<agentId>:<channel>:group:<id>`
|
||||
- 渠道/房间:`agent:<agentId>:<channel>:channel:<id>`
|
||||
- 频道/房间:`agent:<agentId>:<channel>:channel:<id>`
|
||||
|
||||
线程:
|
||||
话题串:
|
||||
|
||||
- Slack/Discord 线程会在基础键后追加 `:thread:<threadId>`。
|
||||
- Telegram 论坛话题会在群组键中嵌入 `:topic:<topicId>`。
|
||||
- Slack/Discord 话题串会将 `:thread:<threadId>` 追加到基础键后。
|
||||
- Telegram 论坛主题会在群组键中嵌入 `:topic:<topicId>`。
|
||||
|
||||
示例:
|
||||
|
||||
- `agent:main:telegram:group:-1001234567890:topic:42`
|
||||
- `agent:main:discord:channel:123456:thread:987654`
|
||||
|
||||
## 主私信路由固定
|
||||
## Main 私信路由固定
|
||||
|
||||
当 `session.dmScope` 为 `main` 时,私信可能共享同一个主会话。为了防止会话的 `lastRoute` 被非所有者私信覆盖,当以下条件全部满足时,OpenClaw 会根据 `allowFrom` 推断一个固定所有者:
|
||||
当 `session.dmScope` 为 `main` 时,私信可能共享一个 main 会话。为防止会话的 `lastRoute` 被非所有者私信覆盖,在以下条件全部为真时,OpenClaw 会从 `allowFrom` 推断固定所有者:
|
||||
|
||||
- `allowFrom` 恰好只有一个非通配符条目。
|
||||
- 该条目可以被规范化为该渠道的具体发送者 ID。
|
||||
- `allowFrom` 恰好有一个非通配符条目。
|
||||
- 该条目可以规范化为该渠道的具体发送者 ID。
|
||||
- 入站私信发送者与该固定所有者不匹配。
|
||||
|
||||
在这种不匹配情况下,OpenClaw 仍会记录入站会话元数据,但会跳过更新主会话的 `lastRoute`。
|
||||
在这种不匹配的情况下,OpenClaw 仍会记录入站会话元数据,但会跳过更新 main 会话的 `lastRoute`。
|
||||
|
||||
## 受保护的入站记录
|
||||
|
||||
当某条受保护路径不得创建新的 OpenClaw 会话时,渠道插件可以将入站会话记录标记为 `createIfMissing: false`。在这种模式下,OpenClaw 可以为现有会话更新元数据和 `lastRoute`,但不会仅因为观察到一条消息就创建一个仅用于路由的会话条目。
|
||||
当受保护路径不得创建新的 OpenClaw 会话时,渠道插件可以将入站会话记录标记为 `createIfMissing: false`。在该模式下,OpenClaw 可以更新现有会话的元数据和 `lastRoute`,但不会仅仅因为观察到一条消息就创建一个仅用于路由的会话条目。
|
||||
|
||||
## 路由规则(如何选择智能体)
|
||||
|
||||
路由会为每条入站消息选择**一个智能体**:
|
||||
|
||||
1. **精确 peer 匹配**(带有 `peer.kind` + `peer.id` 的 `bindings`)。
|
||||
2. **父级 peer 匹配**(线程继承)。
|
||||
1. **精确对端匹配**(带有 `peer.kind` + `peer.id` 的 `bindings`)。
|
||||
2. **父对端匹配**(话题串继承)。
|
||||
3. **Guild + 角色匹配**(Discord),通过 `guildId` + `roles`。
|
||||
4. **Guild 匹配**(Discord),通过 `guildId`。
|
||||
5. **团队匹配**(Slack),通过 `teamId`。
|
||||
6. **账户匹配**(渠道上的 `accountId`)。
|
||||
7. **渠道匹配**(该渠道上的任意账户,`accountId: "*"`)。
|
||||
8. **默认智能体**(`agents.list[].default`,否则为列表中的第一个条目,回退到 `main`)。
|
||||
8. **默认智能体**(`agents.list[].default`,否则列表中的第一个条目,回退到 `main`)。
|
||||
|
||||
当一个绑定包含多个匹配字段(`peer`、`guildId`、`teamId`、`roles`)时,**该绑定中所有已提供的字段都必须匹配**,该绑定才会生效。
|
||||
当一个绑定包含多个匹配字段(`peer`、`guildId`、`teamId`、`roles`)时,**所有已提供字段都必须匹配**,该绑定才会生效。
|
||||
|
||||
匹配到的智能体决定使用哪个工作区和会话存储。
|
||||
|
||||
## 广播群组(运行多个智能体)
|
||||
## 广播组(运行多个智能体)
|
||||
|
||||
广播群组让你可以在同一个 peer 上运行**多个智能体**,前提是 **OpenClaw 通常会回复**(例如:在 WhatsApp 群组中,在提及/激活门控之后)。
|
||||
广播组允许你针对同一对端运行**多个智能体**,前提是 **OpenClaw 通常会回复**(例如:在 WhatsApp 群组中,经过提及/激活门控之后)。
|
||||
|
||||
配置:
|
||||
|
||||
@ -95,12 +101,12 @@ OpenClaw 会将回复**发回消息来源的那个渠道**。模型不会选择
|
||||
}
|
||||
```
|
||||
|
||||
参见:[广播群组](/zh-CN/channels/broadcast-groups)。
|
||||
参见:[广播组](/zh-CN/channels/broadcast-groups)。
|
||||
|
||||
## 配置概览
|
||||
|
||||
- `agents.list`:具名智能体定义(工作区、模型等)。
|
||||
- `bindings`:将入站渠道/账户/peer 映射到智能体。
|
||||
- `agents.list`:命名智能体定义(工作区、模型等)。
|
||||
- `bindings`:将入站渠道/账户/对端映射到智能体。
|
||||
|
||||
示例:
|
||||
|
||||
@ -121,27 +127,27 @@ OpenClaw 会将回复**发回消息来源的那个渠道**。模型不会选择
|
||||
会话存储位于状态目录下(默认 `~/.openclaw`):
|
||||
|
||||
- `~/.openclaw/agents/<agentId>/sessions/sessions.json`
|
||||
- JSONL 记录文件与该存储文件位于同一目录
|
||||
- JSONL 逐行记录与存储位于同一位置
|
||||
|
||||
你可以通过 `session.store` 和 `{agentId}` 模板覆盖存储路径。
|
||||
|
||||
Gateway 网关 和 ACP 会话发现还会扫描默认 `agents/` 根目录下,以及模板化 `session.store` 根目录下的基于磁盘的智能体存储。发现到的存储必须保持在解析后的智能体根目录内,并使用常规的 `sessions.json` 文件。符号链接和超出根目录的路径会被忽略。
|
||||
Gateway 网关 和 ACP 会话发现还会扫描默认 `agents/` 根目录以及模板化 `session.store` 根目录下基于磁盘的智能体存储。发现的存储必须保留在解析后的智能体根目录内,并使用常规的 `sessions.json` 文件。符号链接和根目录外路径会被忽略。
|
||||
|
||||
## WebChat 行为
|
||||
|
||||
WebChat 会附加到**所选智能体**,并默认使用该智能体的主会话。因此,WebChat 让你可以在一个地方查看该智能体的跨渠道上下文。
|
||||
WebChat 附加到**选中的智能体**,并默认使用该智能体的 main 会话。因此,WebChat 允许你在一个位置查看该智能体的跨渠道上下文。
|
||||
|
||||
## 回复上下文
|
||||
|
||||
入站回复会包含:
|
||||
入站回复在可用时包含:
|
||||
|
||||
- 在可用时包含 `ReplyToId`、`ReplyToBody` 和 `ReplyToSender`。
|
||||
- 引用的上下文会作为 `[Replying to ...]` 块追加到 `Body` 中。
|
||||
- `ReplyToId`、`ReplyToBody` 和 `ReplyToSender`。
|
||||
- 引用上下文会作为 `[Replying to ...]` 块追加到 `Body`。
|
||||
|
||||
这一行为在各个渠道之间保持一致。
|
||||
这在各个渠道之间保持一致。
|
||||
|
||||
## 相关内容
|
||||
|
||||
- [群组](/zh-CN/channels/groups)
|
||||
- [广播群组](/zh-CN/channels/broadcast-groups)
|
||||
- [广播组](/zh-CN/channels/broadcast-groups)
|
||||
- [配对](/zh-CN/channels/pairing)
|
||||
|
||||
@ -1,18 +1,18 @@
|
||||
---
|
||||
read_when:
|
||||
- 设置 Slack 或调试 Slack socket/HTTP 模式
|
||||
summary: Slack 设置和运行时行为(Socket Mode + HTTP 请求 URL)
|
||||
- 设置 Slack 或调试 Slack 套接字/HTTP 模式
|
||||
summary: Slack 设置和运行时行为(Socket 模式 + HTTP 请求 URL)
|
||||
title: Slack
|
||||
x-i18n:
|
||||
generated_at: "2026-05-02T04:01:28Z"
|
||||
generated_at: "2026-05-02T04:47:21Z"
|
||||
model: gpt-5.5
|
||||
provider: openai
|
||||
source_hash: 1a676acabdb4dce83f813f991692624e1f5b2dff739e68b5c5bd7b064dd82d03
|
||||
source_hash: 60e06b138e1579156ccd07bb6db1a25009be970d072ba500b61810c5b78fd01d
|
||||
source_path: channels/slack.md
|
||||
workflow: 16
|
||||
---
|
||||
|
||||
已可用于通过 Slack 应用集成处理私信和渠道的生产环境。默认模式是 Socket Mode;也支持 HTTP Request URLs。
|
||||
可通过 Slack 应用集成用于私信和渠道,满足生产环境要求。默认模式是 Socket Mode;也支持 HTTP Request URLs。
|
||||
|
||||
<CardGroup cols={3}>
|
||||
<Card title="配对" icon="link" href="/zh-CN/channels/pairing">
|
||||
@ -22,7 +22,7 @@ x-i18n:
|
||||
原生命令行为和命令目录。
|
||||
</Card>
|
||||
<Card title="渠道故障排除" icon="wrench" href="/zh-CN/channels/troubleshooting">
|
||||
跨渠道诊断和修复操作手册。
|
||||
跨渠道诊断和修复手册。
|
||||
</Card>
|
||||
</CardGroup>
|
||||
|
||||
@ -32,11 +32,11 @@ x-i18n:
|
||||
<Tab title="Socket Mode(默认)">
|
||||
<Steps>
|
||||
<Step title="创建新的 Slack 应用">
|
||||
在 Slack 应用设置中按下 **[Create New App](https://api.slack.com/apps/new)** 按钮:
|
||||
在 Slack 应用设置中按 **[Create New App](https://api.slack.com/apps/new)** 按钮:
|
||||
|
||||
- 选择 **from a manifest** 并为你的应用选择一个工作区
|
||||
- 粘贴下面的[示例 manifest](#manifest-and-scope-checklist),然后继续创建
|
||||
- 生成带有 `connections:write` 的 **App-Level Token**(`xapp-...`)
|
||||
- 选择 **from a manifest**,并为你的应用选择一个工作区
|
||||
- 粘贴下面的[示例清单](#manifest-and-scope-checklist),然后继续创建
|
||||
- 生成一个带有 `connections:write` 的 **App-Level Token**(`xapp-...`)
|
||||
- 安装应用并复制显示的 **Bot Token**(`xoxb-...`)
|
||||
|
||||
</Step>
|
||||
@ -64,7 +64,7 @@ openclaw config patch --file ./slack.socket.patch.json5 --dry-run
|
||||
openclaw config patch --file ./slack.socket.patch.json5
|
||||
```
|
||||
|
||||
环境变量回退(仅默认账号):
|
||||
Env 回退方式(仅默认账户):
|
||||
|
||||
```bash
|
||||
SLACK_APP_TOKEN=xapp-...
|
||||
@ -87,10 +87,10 @@ openclaw gateway
|
||||
<Tab title="HTTP Request URLs">
|
||||
<Steps>
|
||||
<Step title="创建新的 Slack 应用">
|
||||
在 Slack 应用设置中按下 **[Create New App](https://api.slack.com/apps/new)** 按钮:
|
||||
在 Slack 应用设置中按 **[Create New App](https://api.slack.com/apps/new)** 按钮:
|
||||
|
||||
- 选择 **from a manifest** 并为你的应用选择一个工作区
|
||||
- 粘贴[示例 manifest](#manifest-and-scope-checklist),并在创建前更新 URL
|
||||
- 选择 **from a manifest**,并为你的应用选择一个工作区
|
||||
- 粘贴[示例清单](#manifest-and-scope-checklist),并在创建前更新 URL
|
||||
- 保存用于请求验证的 **Signing Secret**
|
||||
- 安装应用并复制显示的 **Bot Token**(`xoxb-...`)
|
||||
|
||||
@ -121,9 +121,9 @@ openclaw config patch --file ./slack.http.patch.json5
|
||||
```
|
||||
|
||||
<Note>
|
||||
为多账号 HTTP 使用唯一的 webhook 路径
|
||||
为多账户 HTTP 使用唯一的 webhook 路径
|
||||
|
||||
为每个账号指定不同的 `webhookPath`(默认 `/slack/events`),避免注册冲突。
|
||||
为每个账户提供不同的 `webhookPath`(默认 `/slack/events`),这样注册就不会冲突。
|
||||
</Note>
|
||||
|
||||
</Step>
|
||||
@ -142,7 +142,7 @@ openclaw gateway
|
||||
|
||||
## Socket Mode 传输调优
|
||||
|
||||
对于 Socket Mode,OpenClaw 默认将 Slack SDK 客户端 pong 超时设置为 15 秒。仅在需要针对工作区或主机进行特定调优时覆盖传输设置:
|
||||
默认情况下,OpenClaw 会将 Socket Mode 的 Slack SDK 客户端 pong 超时设为 15 秒。仅在需要针对工作区或主机进行特定调优时覆盖传输设置:
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -159,13 +159,13 @@ openclaw gateway
|
||||
}
|
||||
```
|
||||
|
||||
仅在记录了 Slack websocket pong/server-ping 超时日志,或运行在存在已知事件循环饥饿问题主机上的 Socket Mode 工作区中使用此配置。`clientPingTimeout` 是 SDK 发送客户端 ping 后等待 pong 的时间;`serverPingTimeout` 是等待 Slack 服务器 ping 的时间。应用消息和事件仍属于应用状态,不是传输活性信号。
|
||||
仅在 Socket Mode 工作区记录 Slack websocket pong/server-ping 超时,或运行在已知存在事件循环饥饿的主机上时使用此项。`clientPingTimeout` 是 SDK 发送客户端 ping 后等待 pong 的时间;`serverPingTimeout` 是等待 Slack 服务器 ping 的时间。应用消息和事件仍是应用状态,而不是传输活性信号。
|
||||
|
||||
## Manifest 和 scope 检查清单
|
||||
## 清单和 scope 检查清单
|
||||
|
||||
基础 Slack 应用 manifest 对 Socket Mode 和 HTTP Request URLs 相同。只有 `settings` 块(以及斜杠命令的 `url`)不同。
|
||||
基础 Slack 应用清单对于 Socket Mode 和 HTTP Request URLs 相同。只有 `settings` 块(以及斜杠命令 `url`)不同。
|
||||
|
||||
基础 manifest(Socket Mode 默认):
|
||||
基础清单(Socket Mode 默认):
|
||||
|
||||
```json
|
||||
{
|
||||
@ -240,7 +240,7 @@ openclaw gateway
|
||||
}
|
||||
```
|
||||
|
||||
对于 **HTTP Request URLs 模式**,将 `settings` 替换为 HTTP 变体,并为每个斜杠命令添加 `url`。需要公开 URL:
|
||||
对于 **HTTP Request URLs 模式**,将 `settings` 替换为 HTTP 变体,并向每个斜杠命令添加 `url`。需要公网 URL:
|
||||
|
||||
```json
|
||||
{
|
||||
@ -270,21 +270,21 @@ openclaw gateway
|
||||
}
|
||||
```
|
||||
|
||||
### 其他 manifest 设置
|
||||
### 其他清单设置
|
||||
|
||||
公开可扩展上述默认配置的不同功能。
|
||||
展示扩展上述默认设置的不同功能。
|
||||
|
||||
默认 manifest 启用 Slack App Home 的 **Home** 标签页,并订阅 `app_home_opened`。当工作区成员打开 Home 标签页时,OpenClaw 会使用 `views.publish` 发布安全的默认 Home 视图;其中不包含会话 payload 或私有配置。**Messages** 标签页仍会为 Slack 私信启用。
|
||||
默认清单启用 Slack App Home 的 **Home** 标签页,并订阅 `app_home_opened`。当工作区成员打开 Home 标签页时,OpenClaw 会通过 `views.publish` 发布安全的默认 Home 视图;其中不包含会话载荷或私有配置。**Messages** 标签页仍为 Slack 私信启用。
|
||||
|
||||
<AccordionGroup>
|
||||
<Accordion title="可选原生斜杠命令">
|
||||
|
||||
可以使用多个[原生斜杠命令](#commands-and-slash-behavior)替代单个配置命令,但需注意:
|
||||
可以使用多个[原生斜杠命令](#commands-and-slash-behavior),以替代单个已配置命令,并获得更细致的控制:
|
||||
|
||||
- 使用 `/agentstatus` 而不是 `/status`,因为 `/status` 命令已被保留。
|
||||
- 一次最多只能提供 25 个斜杠命令。
|
||||
- 使用 `/agentstatus` 替代 `/status`,因为 `/status` 命令已被保留。
|
||||
- 一次最多可以提供 25 个斜杠命令。
|
||||
|
||||
将现有 `features.slash_commands` 部分替换为[可用命令](/zh-CN/tools/slash-commands#command-list)的一个子集:
|
||||
将现有 `features.slash_commands` 部分替换为[可用命令](/zh-CN/tools/slash-commands#command-list)的子集:
|
||||
|
||||
<Tabs>
|
||||
<Tab title="Socket Mode(默认)">
|
||||
@ -404,7 +404,7 @@ openclaw gateway
|
||||
|
||||
</Tab>
|
||||
<Tab title="HTTP Request URLs">
|
||||
使用上方与 Socket Mode 相同的 `slash_commands` 列表,并为每个条目添加 `"url": "https://gateway-host.example.com/slack/events"`。示例:
|
||||
使用与上方 Socket Mode 相同的 `slash_commands` 列表,并为每个条目添加 `"url": "https://gateway-host.example.com/slack/events"`。示例:
|
||||
|
||||
```json
|
||||
"slash_commands": [
|
||||
@ -428,13 +428,13 @@ openclaw gateway
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="可选作者身份 scope(写入操作)">
|
||||
如果你希望发出的消息使用当前 agent 身份(自定义用户名和图标),而不是默认 Slack 应用身份,请添加 `chat:write.customize` bot scope。
|
||||
如果你希望传出消息使用活动智能体身份(自定义用户名和图标),而不是默认 Slack 应用身份,请添加 `chat:write.customize` bot scope。
|
||||
|
||||
如果使用 emoji 图标,Slack 期望采用 `:emoji_name:` 语法。
|
||||
如果使用 emoji 图标,Slack 预期使用 `:emoji_name:` 语法。
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="可选用户令牌作用域(读取操作)">
|
||||
如果你配置了 `channels.slack.userToken`,典型读取作用域为:
|
||||
<Accordion title="可选的用户令牌作用域(读取操作)">
|
||||
如果你配置了 `channels.slack.userToken`,典型的读取作用域包括:
|
||||
|
||||
- `channels:history`, `groups:history`, `im:history`, `mpim:history`
|
||||
- `channels:read`, `groups:read`, `im:read`, `mpim:read`
|
||||
@ -453,23 +453,23 @@ openclaw gateway
|
||||
- HTTP 模式需要 `botToken` + `signingSecret`。
|
||||
- `botToken`、`appToken`、`signingSecret` 和 `userToken` 接受明文
|
||||
字符串或 SecretRef 对象。
|
||||
- 配置令牌会覆盖环境变量回退。
|
||||
- `SLACK_BOT_TOKEN` / `SLACK_APP_TOKEN` 环境变量回退仅适用于默认账户。
|
||||
- `userToken`(`xoxp-...`)仅支持配置(没有环境变量回退),并默认使用只读行为(`userTokenReadOnly: true`)。
|
||||
- 配置令牌会覆盖环境回退。
|
||||
- `SLACK_BOT_TOKEN` / `SLACK_APP_TOKEN` 环境回退仅适用于默认账户。
|
||||
- `userToken`(`xoxp-...`)仅能通过配置提供(没有环境回退),并默认采用只读行为(`userTokenReadOnly: true`)。
|
||||
|
||||
Status 快照行为:
|
||||
|
||||
- Slack 账户检查会跟踪每个凭证的 `*Source` 和 `*Status`
|
||||
字段(`botToken`、`appToken`、`signingSecret`、`userToken`)。
|
||||
- Status 为 `available`、`configured_unavailable` 或 `missing`。
|
||||
- `configured_unavailable` 表示账户是通过 SecretRef
|
||||
或其他非内联密钥来源配置的,但当前命令/运行时路径
|
||||
- `configured_unavailable` 表示账户通过 SecretRef
|
||||
或其他非内联密钥来源进行了配置,但当前命令/运行时路径
|
||||
无法解析实际值。
|
||||
- 在 HTTP 模式下,会包含 `signingSecretStatus`;在 Socket Mode 下,
|
||||
所需组合是 `botTokenStatus` + `appTokenStatus`。
|
||||
- 在 HTTP 模式中会包含 `signingSecretStatus`;在 Socket Mode 中,
|
||||
必需的组合是 `botTokenStatus` + `appTokenStatus`。
|
||||
|
||||
<Tip>
|
||||
对于操作/目录读取,配置后可以优先使用用户令牌。对于写入,仍优先使用机器人令牌;只有当 `userTokenReadOnly: false` 且机器人令牌不可用时,才允许用户令牌写入。
|
||||
对于操作/目录读取,配置后可优先使用用户令牌。对于写入,仍优先使用机器人令牌;仅当 `userTokenReadOnly: false` 且机器人令牌不可用时,才允许用户令牌写入。
|
||||
</Tip>
|
||||
|
||||
## 操作和门控
|
||||
@ -478,13 +478,13 @@ Slack 操作由 `channels.slack.actions.*` 控制。
|
||||
|
||||
当前 Slack 工具中可用的操作组:
|
||||
|
||||
| 组 | 默认值 |
|
||||
| 组 | 默认值 |
|
||||
| ---------- | ------- |
|
||||
| 消息 | 启用 |
|
||||
| 反应 | 启用 |
|
||||
| 置顶 | 启用 |
|
||||
| 成员信息 | 启用 |
|
||||
| 表情列表 | 启用 |
|
||||
| messages | 已启用 |
|
||||
| reactions | 已启用 |
|
||||
| pins | 已启用 |
|
||||
| memberInfo | 已启用 |
|
||||
| emojiList | 已启用 |
|
||||
|
||||
当前 Slack 消息操作包括 `send`、`upload-file`、`download-file`、`read`、`edit`、`delete`、`pin`、`unpin`、`list-pins`、`member-info` 和 `emoji-list`。`download-file` 接受入站文件占位符中显示的 Slack 文件 ID,并为图片返回图片预览,或为其他文件类型返回本地文件元数据。
|
||||
|
||||
@ -510,10 +510,10 @@ Slack 操作由 `channels.slack.actions.*` 控制。
|
||||
多账户优先级:
|
||||
|
||||
- `channels.slack.accounts.default.allowFrom` 仅适用于 `default` 账户。
|
||||
- 命名账户在自己的 `allowFrom` 未设置时会继承 `channels.slack.allowFrom`。
|
||||
- 命名账户在自身未设置 `allowFrom` 时继承 `channels.slack.allowFrom`。
|
||||
- 命名账户不会继承 `channels.slack.accounts.default.allowFrom`。
|
||||
|
||||
旧版 `channels.slack.dm.policy` 和 `channels.slack.dm.allowFrom` 仍会读取以保持兼容。`openclaw doctor --fix` 会在不改变访问权限的情况下,将它们迁移到 `dmPolicy` 和 `allowFrom`。
|
||||
为了兼容性,仍会读取旧版 `channels.slack.dm.policy` 和 `channels.slack.dm.allowFrom`。`openclaw doctor --fix` 会在不改变访问权限的情况下,将它们迁移到 `dmPolicy` 和 `allowFrom`。
|
||||
|
||||
私信中的配对使用 `openclaw pairing approve slack <code>`。
|
||||
|
||||
@ -526,20 +526,20 @@ Slack 操作由 `channels.slack.actions.*` 控制。
|
||||
- `allowlist`
|
||||
- `disabled`
|
||||
|
||||
渠道允许列表位于 `channels.slack.channels` 下,并且配置键**必须使用稳定的 Slack 渠道 ID**(例如 `C12345678`)。
|
||||
渠道允许列表位于 `channels.slack.channels` 下,并且**必须使用稳定的 Slack 渠道 ID**(例如 `C12345678`)作为配置键。
|
||||
|
||||
运行时注意事项:如果完全缺少 `channels.slack`(仅环境变量设置),运行时会回退到 `groupPolicy="allowlist"` 并记录警告(即使设置了 `channels.defaults.groupPolicy`)。
|
||||
运行时说明:如果完全缺少 `channels.slack`(仅环境变量设置),运行时会回退到 `groupPolicy="allowlist"` 并记录一条警告(即使设置了 `channels.defaults.groupPolicy`)。
|
||||
|
||||
名称/ID 解析:
|
||||
|
||||
- 当令牌访问允许时,渠道允许列表条目和私信允许列表条目会在启动时解析
|
||||
- 未解析的渠道名称条目会按配置保留,但默认会在路由中被忽略
|
||||
- 当令牌访问权限允许时,渠道允许列表条目和私信允许列表条目会在启动时解析
|
||||
- 未解析的渠道名称条目会按配置保留,但默认会被路由忽略
|
||||
- 入站授权和渠道路由默认优先使用 ID;直接用户名/slug 匹配需要 `channels.slack.dangerouslyAllowNameMatching: true`
|
||||
|
||||
<Warning>
|
||||
基于名称的键(`#channel-name` 或 `channel-name`)在 `groupPolicy: "allowlist"` 下**不会**匹配。渠道查找默认优先使用 ID,因此基于名称的键永远无法成功路由,该渠道中的所有消息都会被静默阻止。这不同于 `groupPolicy: "open"`,在该模式下路由不需要渠道键,因此基于名称的键看起来可以工作。
|
||||
基于名称的键(`#channel-name` 或 `channel-name`)在 `groupPolicy: "allowlist"` 下**不会**匹配。渠道查找默认优先使用 ID,因此基于名称的键永远无法成功路由,该渠道中的所有消息都会被静默阻止。这不同于 `groupPolicy: "open"`,在该模式下路由不需要渠道键,因此基于名称的键看起来可以正常工作。
|
||||
|
||||
始终使用 Slack 渠道 ID 作为键。查找方式:在 Slack 中右键点击渠道 → **复制链接** — ID(`C...`)会出现在 URL 末尾。
|
||||
始终使用 Slack 渠道 ID 作为键。查找方法:在 Slack 中右键点击该渠道 → **复制链接** — ID(`C...`)会显示在 URL 末尾。
|
||||
|
||||
正确:
|
||||
|
||||
@ -575,16 +575,16 @@ Slack 操作由 `channels.slack.actions.*` 控制。
|
||||
</Tab>
|
||||
|
||||
<Tab title="提及和渠道用户">
|
||||
渠道消息默认由提及门控。
|
||||
渠道消息默认受提及门控。
|
||||
|
||||
提及来源:
|
||||
|
||||
- 显式应用提及(`<@botId>`)
|
||||
- 当 bot 用户是该用户组成员时的 Slack 用户组提及(`<!subteam^S...>`);需要 `usergroups:read`
|
||||
- 提及正则表达式模式(`agents.list[].groupChat.mentionPatterns`,回退到 `messages.groupChat.mentionPatterns`)
|
||||
- 隐式回复 bot 的线程行为(当 `thread.requireExplicitMention` 为 `true` 时禁用)
|
||||
- 当机器人用户是该用户组成员时的 Slack 用户组提及(`<!subteam^S...>`);需要 `usergroups:read`
|
||||
- 提及正则模式(`agents.list[].groupChat.mentionPatterns`,回退为 `messages.groupChat.mentionPatterns`)
|
||||
- 隐式回复机器人线程行为(当 `thread.requireExplicitMention` 为 `true` 时禁用)
|
||||
|
||||
单渠道控制项(`channels.slack.channels.<id>`;名称仅通过启动解析或 `dangerouslyAllowNameMatching` 使用):
|
||||
每渠道控制项(`channels.slack.channels.<id>`;名称仅通过启动解析或 `dangerouslyAllowNameMatching` 可用):
|
||||
|
||||
- `requireMention`
|
||||
- `users`(允许列表)
|
||||
@ -592,10 +592,10 @@ Slack 操作由 `channels.slack.actions.*` 控制。
|
||||
- `skills`
|
||||
- `systemPrompt`
|
||||
- `tools`, `toolsBySender`
|
||||
- `toolsBySender` 键格式:`id:`, `e164:`, `username:`, `name:`,或 `"*"` 通配符
|
||||
(旧版无前缀键仍仅映射到 `id:`)
|
||||
- `toolsBySender` 键格式:`id:`、`e164:`、`username:`、`name:` 或 `"*"` 通配符
|
||||
(旧版未加前缀的键仍仅映射到 `id:`)
|
||||
|
||||
`allowBots` 对渠道和私有渠道较为保守:仅当发送 bot 明确列在该房间的 `users` 允许列表中,或 `channels.slack.allowFrom` 中至少有一个显式 Slack 所有者 ID 当前是房间成员时,才接受 bot 发送的房间消息。通配符和显示名称所有者条目不满足所有者在场条件。所有者在场使用 Slack `conversations.members`;请确保应用具有对应房间类型的匹配读取 scope(公共渠道为 `channels:read`,私有渠道为 `groups:read`)。如果成员查询失败,OpenClaw 会丢弃 bot 发送的房间消息。
|
||||
对于渠道和私有渠道,`allowBots` 是保守的:仅当发送机器人被明确列入该房间的 `users` 允许列表,或 `channels.slack.allowFrom` 中至少一个显式 Slack 所有者 ID 当前是房间成员时,才会接受机器人作者的房间消息。通配符和显示名称所有者条目不满足所有者存在条件。所有者存在检查使用 Slack `conversations.members`;确保应用拥有与房间类型匹配的读取作用域(公共渠道为 `channels:read`,私有渠道为 `groups:read`)。如果成员查找失败,OpenClaw 会丢弃机器人作者的房间消息。
|
||||
|
||||
</Tab>
|
||||
</Tabs>
|
||||
@ -603,17 +603,18 @@ Slack 操作由 `channels.slack.actions.*` 控制。
|
||||
## 线程、会话和回复标签
|
||||
|
||||
- 私信路由为 `direct`;渠道路由为 `channel`;MPIM 路由为 `group`。
|
||||
- Slack 路由绑定接受原始对等方 ID,以及 Slack 目标形式,例如 `channel:C12345678`、`user:U12345678` 和 `<@U12345678>`。
|
||||
- 使用默认 `session.dmScope=main` 时,Slack 私信会折叠到智能体主会话。
|
||||
- 渠道会话:`agent:<agentId>:slack:channel:<channelId>`。
|
||||
- 适用时,线程回复可以创建线程会话后缀(`:thread:<threadTs>`)。
|
||||
- 线程回复在适用时可创建线程会话后缀(`:thread:<threadTs>`)。
|
||||
- `channels.slack.thread.historyScope` 默认为 `thread`;`thread.inheritParent` 默认为 `false`。
|
||||
- `channels.slack.thread.initialHistoryLimit` 控制新线程会话启动时获取多少条已有线程消息(默认 `20`;设为 `0` 可禁用)。
|
||||
- `channels.slack.thread.requireExplicitMention`(默认 `false`):当为 `true` 时,抑制隐式线程提及,因此 bot 只会响应线程内显式的 `@bot` 提及,即使 bot 已参与该线程也是如此。没有此设置时,bot 已参与线程中的回复会绕过 `requireMention` 门控。
|
||||
- `channels.slack.thread.initialHistoryLimit` 控制新线程会话启动时获取多少条现有线程消息(默认 `20`;设为 `0` 可禁用)。
|
||||
- `channels.slack.thread.requireExplicitMention`(默认 `false`):当为 `true` 时,会抑制隐式线程提及,因此机器人只会响应线程内显式的 `@bot` 提及,即使机器人已经参与过该线程。否则,机器人已参与线程中的回复会绕过 `requireMention` 门控。
|
||||
|
||||
回复线程控制项:
|
||||
|
||||
- `channels.slack.replyToMode`:`off|first|all|batched`(默认 `off`)
|
||||
- `channels.slack.replyToModeByChatType`:按 `direct|group|channel` 设置
|
||||
- `channels.slack.replyToMode`: `off|first|all|batched`(默认 `off`)
|
||||
- `channels.slack.replyToModeByChatType`: 按 `direct|group|channel` 设置
|
||||
- 直接聊天的旧版回退:`channels.slack.dm.replyToMode`
|
||||
|
||||
支持手动回复标签:
|
||||
@ -622,12 +623,12 @@ Slack 操作由 `channels.slack.actions.*` 控制。
|
||||
- `[[reply_to:<id>]]`
|
||||
|
||||
<Note>
|
||||
`replyToMode="off"` 会禁用 Slack 中的**所有**回复线程,包括显式 `[[reply_to_*]]` 标签。这不同于 Telegram,后者在 `"off"` 模式下仍会遵循显式标签。Slack 线程会从渠道中隐藏消息,而 Telegram 回复仍以内联方式可见。
|
||||
`replyToMode="off"` 会禁用 Slack 中的**所有**回复线程,包括显式 `[[reply_to_*]]` 标签。这不同于 Telegram,后者在 `"off"` 模式下仍会遵守显式标签。Slack 线程会将消息从渠道中隐藏,而 Telegram 回复会以内联形式保持可见。
|
||||
</Note>
|
||||
|
||||
## 确认回应
|
||||
## 确认响应
|
||||
|
||||
`ackReaction` 会在 OpenClaw 处理入站消息时发送确认回应表情符号。
|
||||
`ackReaction` 会在 OpenClaw 处理入站消息时发送一个确认表情符号。
|
||||
|
||||
解析顺序:
|
||||
|
||||
@ -636,10 +637,10 @@ Slack 操作由 `channels.slack.actions.*` 控制。
|
||||
- `messages.ackReaction`
|
||||
- 智能体身份表情符号回退(`agents.list[].identity.emoji`,否则为 "👀")
|
||||
|
||||
注意:
|
||||
说明:
|
||||
|
||||
- Slack 需要短代码(例如 `"eyes"`)。
|
||||
- 使用 `""` 可为 Slack 账户或全局禁用该回应。
|
||||
- 使用 `""` 可为该 Slack 账户或全局禁用该响应。
|
||||
|
||||
## 文本流式传输
|
||||
|
||||
@ -649,16 +650,16 @@ Slack 操作由 `channels.slack.actions.*` 控制。
|
||||
- `partial`(默认):用最新的部分输出替换预览文本。
|
||||
- `block`:追加分块预览更新。
|
||||
- `progress`:生成时显示进度状态文本,然后发送最终文本。
|
||||
- `streaming.preview.toolProgress`:当草稿预览处于活动状态时,将工具/进度更新路由到同一条已编辑预览消息中(默认:`true`)。设为 `false` 可保留单独的工具/进度消息。
|
||||
- `streaming.preview.toolProgress`:当草稿预览处于活动状态时,将工具/进度更新路由到同一条已编辑的预览消息中(默认:`true`)。设为 `false` 可保留单独的工具/进度消息。
|
||||
|
||||
当 `channels.slack.streaming.mode` 为 `partial` 时,`channels.slack.streaming.nativeTransport` 控制 Slack 原生文本流式传输(默认:`true`)。
|
||||
|
||||
- 必须有可用的回复线程,原生文本流式传输和 Slack assistant 线程状态才会出现。线程选择仍遵循 `replyToMode`。
|
||||
- 当原生流式传输不可用时,渠道和群聊根消息仍可使用普通草稿预览。
|
||||
- 顶层 Slack 私信默认不在线程中,因此不会显示线程样式预览;如果你想在那里显示可见进度,请使用线程回复或 `typingReaction`。
|
||||
- 媒体和非文本 payload 会回退到普通投递。
|
||||
- 媒体/错误最终消息会取消待处理的预览编辑;符合条件的文本/分块最终消息仅在可以就地编辑预览时才会 flush。
|
||||
- 如果流式传输在回复中途失败,OpenClaw 会对剩余 payload 回退到普通投递。
|
||||
- 必须有可用的回复线程,原生文本流式传输和 Slack 助手线程 Status 才会出现。线程选择仍遵循 `replyToMode`。
|
||||
- 当原生流式传输不可用时,渠道和群组聊天根消息仍可使用普通草稿预览。
|
||||
- 顶层 Slack 私信默认保持在线程外,因此不会显示线程样式预览;如果你希望在那里显示可见进度,请使用线程回复或 `typingReaction`。
|
||||
- 媒体和非文本负载会回退到普通投递。
|
||||
- 媒体/错误最终消息会取消待处理的预览编辑;符合条件的文本/分块最终消息仅在可以就地编辑预览时刷新。
|
||||
- 如果流式传输在回复中途失败,OpenClaw 会对剩余负载回退到普通投递。
|
||||
|
||||
使用草稿预览而不是 Slack 原生文本流式传输:
|
||||
|
||||
@ -681,37 +682,37 @@ Slack 操作由 `channels.slack.actions.*` 控制。
|
||||
- 布尔值 `channels.slack.streaming` 会自动迁移到 `channels.slack.streaming.mode` 和 `channels.slack.streaming.nativeTransport`。
|
||||
- 旧版 `channels.slack.nativeStreaming` 会自动迁移到 `channels.slack.streaming.nativeTransport`。
|
||||
|
||||
## 输入状态回应回退
|
||||
## 输入反应回退
|
||||
|
||||
`typingReaction` 会在 OpenClaw 处理回复时,向入站 Slack 消息添加临时回应,并在运行完成时移除。它在线程回复之外最有用,因为线程回复会使用默认的 "is typing..." 状态指示器。
|
||||
`typingReaction` 会在 OpenClaw 处理回复时,向入站 Slack 消息添加一个临时反应,并在运行完成后移除。它在线程回复之外最有用,因为线程回复会使用默认的 “is typing...” Status 指示器。
|
||||
|
||||
解析顺序:
|
||||
|
||||
- `channels.slack.accounts.<accountId>.typingReaction`
|
||||
- `channels.slack.typingReaction`
|
||||
|
||||
注意:
|
||||
说明:
|
||||
|
||||
- Slack 需要短代码(例如 `"hourglass_flowing_sand"`)。
|
||||
- 该回应是尽力而为,并会在回复或失败路径完成后自动尝试清理。
|
||||
- 该反应按尽力而为处理,并会在回复或失败路径完成后自动尝试清理。
|
||||
|
||||
## 媒体、分块和投递
|
||||
|
||||
<AccordionGroup>
|
||||
<Accordion title="入站附件">
|
||||
Slack 文件附件会从 Slack 托管的私有 URL 下载(带 token 认证的请求流程),并在获取成功且大小限制允许时写入媒体存储。文件占位符包含 Slack `fileId`,因此智能体可以使用 `download-file` 获取原始文件。
|
||||
Slack 文件附件会从 Slack 托管的私有 URL 下载(基于令牌认证的请求流程),并在获取成功且大小限制允许时写入媒体存储。文件占位符包含 Slack `fileId`,因此智能体可以使用 `download-file` 获取原始文件。
|
||||
|
||||
下载使用有界的空闲超时和总超时。如果 Slack 文件检索停滞或失败,OpenClaw 会继续处理消息,并回退到文件占位符。
|
||||
下载使用有界空闲超时和总超时。如果 Slack 文件检索停滞或失败,OpenClaw 会继续处理消息,并回退到文件占位符。
|
||||
|
||||
运行时入站大小上限默认是 `20MB`,除非通过 `channels.slack.mediaMaxMb` 覆盖。
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="出站文本和文件">
|
||||
- 文本分块使用 `channels.slack.textChunkLimit`(默认 4000)
|
||||
- `channels.slack.chunkMode="newline"` 启用优先按段落拆分
|
||||
- 文本块使用 `channels.slack.textChunkLimit`(默认 4000)
|
||||
- `channels.slack.chunkMode="newline"` 启用段落优先拆分
|
||||
- 文件发送使用 Slack 上传 API,并且可以包含线程回复(`thread_ts`)
|
||||
- 配置后,出站媒体上限遵循 `channels.slack.mediaMaxMb`;否则渠道发送使用媒体管道中的 MIME 类型默认值
|
||||
- 出站媒体上限在配置时遵循 `channels.slack.mediaMaxMb`;否则渠道发送使用媒体管线中的 MIME 类型默认值
|
||||
|
||||
</Accordion>
|
||||
|
||||
@ -721,14 +722,14 @@ Slack 操作由 `channels.slack.actions.*` 控制。
|
||||
- `user:<id>` 用于私信
|
||||
- `channel:<id>` 用于渠道
|
||||
|
||||
仅文本/分块的 Slack 私信可以直接发送到用户 ID;文件上传和线程发送会先通过 Slack 会话 API 打开私信,因为这些路径需要具体的会话 ID。
|
||||
仅文本/分块的 Slack 私信可以直接发布到用户 ID;文件上传和线程发送会先通过 Slack 会话 API 打开私信,因为这些路径需要具体的会话 ID。
|
||||
|
||||
</Accordion>
|
||||
</AccordionGroup>
|
||||
|
||||
## 命令和斜杠行为
|
||||
|
||||
斜杠命令在 Slack 中显示为一个已配置命令或多个原生命令。配置 `channels.slack.slashCommand` 可更改命令默认值:
|
||||
斜杠命令在 Slack 中显示为单个已配置命令或多个原生命令。配置 `channels.slack.slashCommand` 可更改命令默认值:
|
||||
|
||||
- `enabled: false`
|
||||
- `name: "openclaw"`
|
||||
@ -739,30 +740,30 @@ Slack 操作由 `channels.slack.actions.*` 控制。
|
||||
/openclaw /help
|
||||
```
|
||||
|
||||
原生命令需要你的 Slack 应用中有[额外的 manifest 设置](#additional-manifest-settings),并通过 `channels.slack.commands.native: true` 启用,或在全局配置中通过 `commands.native: true` 启用。
|
||||
原生命令需要在你的 Slack 应用中配置[额外的清单设置](#additional-manifest-settings),并通过 `channels.slack.commands.native: true` 启用,或者改为在全局配置中使用 `commands.native: true` 启用。
|
||||
|
||||
- Slack 的原生命令自动模式为**关闭**,因此 `commands.native: "auto"` 不会启用 Slack 原生命令。
|
||||
- Slack 的原生命令自动模式是**关闭**的,因此 `commands.native: "auto"` 不会启用 Slack 原生命令。
|
||||
|
||||
```txt
|
||||
/help
|
||||
```
|
||||
|
||||
原生参数菜单使用自适应渲染策略,在分派所选选项值之前显示确认模态框:
|
||||
原生参数菜单使用自适应渲染策略,在派发选定选项值之前显示确认模态框:
|
||||
|
||||
- 最多 5 个选项:按钮块
|
||||
- 6-100 个选项:静态选择菜单
|
||||
- 超过 100 个选项:当交互选项处理程序可用时,使用带异步选项筛选的外部选择
|
||||
- 超过 100 个选项:当交互选项处理器可用时,使用带异步选项过滤的外部选择
|
||||
- 超出 Slack 限制:编码后的选项值回退为按钮
|
||||
|
||||
```txt
|
||||
/think
|
||||
```
|
||||
|
||||
斜杠会话使用类似 `agent:<agentId>:slack:slash:<userId>` 的隔离键,并且仍会使用 `CommandTargetSessionKey` 将命令执行路由到目标对话会话。
|
||||
斜杠会话使用类似 `agent:<agentId>:slack:slash:<userId>` 的隔离键,并且仍会使用 `CommandTargetSessionKey` 将命令执行路由到目标会话会话。
|
||||
|
||||
## 交互式回复
|
||||
|
||||
Slack 可以渲染智能体编写的交互式回复控件,但此功能默认禁用。
|
||||
Slack 可以渲染由智能体撰写的交互式回复控件,但此功能默认禁用。
|
||||
|
||||
全局启用:
|
||||
|
||||
@ -778,7 +779,7 @@ Slack 可以渲染智能体编写的交互式回复控件,但此功能默认
|
||||
}
|
||||
```
|
||||
|
||||
或仅为一个 Slack 账号启用:
|
||||
或者仅为一个 Slack 账号启用:
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -801,36 +802,38 @@ Slack 可以渲染智能体编写的交互式回复控件,但此功能默认
|
||||
- `[[slack_buttons: Approve:approve, Reject:reject]]`
|
||||
- `[[slack_select: Choose a target | Canary:canary, Production:production]]`
|
||||
|
||||
这些指令会编译为 Slack Block Kit,并通过现有的 Slack 交互事件路径路由点击或选择。
|
||||
这些指令会编译为 Slack Block Kit,并通过现有 Slack 交互事件路径将点击或选择路由回来。
|
||||
|
||||
注意:
|
||||
|
||||
- 这是 Slack 专用 UI。其他渠道不会将 Slack Block Kit 指令转换为自己的按钮系统。
|
||||
- 交互回调值是 OpenClaw 生成的不透明令牌,不是智能体编写的原始值。
|
||||
- 如果生成的交互块会超出 Slack Block Kit 限制,OpenClaw 会回退到原始文本回复,而不是发送无效的 blocks 载荷。
|
||||
- 交互式回调值是 OpenClaw 生成的不透明令牌,不是智能体撰写的原始值。
|
||||
- 如果生成的交互式块会超出 Slack Block Kit 限制,OpenClaw 会回退到原始文本回复,而不是发送无效的块载荷。
|
||||
|
||||
## Slack 中的 Exec 审批
|
||||
## Slack 中的执行审批
|
||||
|
||||
Slack 可以作为带交互式按钮和交互的原生审批客户端,而不是回退到 Web UI 或终端。
|
||||
Slack 可以作为带有交互式按钮和交互的原生审批客户端,而不是回退到 Web UI 或终端。
|
||||
|
||||
- Exec 审批使用 `channels.slack.execApprovals.*` 进行原生私信/渠道路由。
|
||||
- 当请求已落在 Slack 中且审批 id 类型是 `plugin:` 时,插件审批仍可通过相同的 Slack 原生按钮表面完成。
|
||||
- 执行审批使用 `channels.slack.execApprovals.*` 进行原生私信/渠道路由。
|
||||
- 当请求已经落在 Slack 中且审批 ID 类型是 `plugin:` 时,插件审批仍可通过同一个 Slack 原生按钮界面完成。
|
||||
- 审批人授权仍会强制执行:只有被识别为审批人的用户才能通过 Slack 批准或拒绝请求。
|
||||
|
||||
这使用与其他渠道相同的共享审批按钮表面。在你的 Slack 应用设置中启用 `interactivity` 后,审批提示会直接在对话中渲染为 Block Kit 按钮。
|
||||
当这些按钮存在时,它们是主要审批 UX;只有当工具结果表明聊天审批不可用,或手动审批是唯一路径时,OpenClaw 才应包含手动 `/approve` 命令。
|
||||
这使用与其他渠道相同的共享审批按钮界面。当你的 Slack 应用设置中启用了 `interactivity` 时,审批提示会直接在会话中渲染为 Block Kit 按钮。
|
||||
当这些按钮存在时,它们就是主要审批 UX;OpenClaw
|
||||
只有在工具结果表明聊天审批不可用或手动审批是唯一路径时,
|
||||
才应包含手动 `/approve` 命令。
|
||||
|
||||
配置路径:
|
||||
|
||||
- `channels.slack.execApprovals.enabled`
|
||||
- `channels.slack.execApprovals.approvers`(可选;可能时回退到 `commands.ownerAllowFrom`)
|
||||
- `channels.slack.execApprovals.approvers`(可选;可行时回退到 `commands.ownerAllowFrom`)
|
||||
- `channels.slack.execApprovals.target`(`dm` | `channel` | `both`,默认:`dm`)
|
||||
- `agentFilter`、`sessionFilter`
|
||||
|
||||
当 `enabled` 未设置或为 `"auto"` 且至少解析出一个审批人时,Slack 会自动启用原生 exec 审批。设置 `enabled: false` 可显式禁用 Slack 作为原生审批客户端。
|
||||
当审批人可解析时,设置 `enabled: true` 可强制开启原生审批。
|
||||
当 `enabled` 未设置或为 `"auto"` 且至少能解析出一个审批人时,Slack 会自动启用原生执行审批。设置 `enabled: false` 可显式禁用 Slack 作为原生审批客户端。
|
||||
设置 `enabled: true` 可在审批人能解析时强制启用原生审批。
|
||||
|
||||
没有显式 Slack exec 审批配置时的默认行为:
|
||||
没有显式 Slack 执行审批配置时的默认行为:
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -840,7 +843,8 @@ Slack 可以作为带交互式按钮和交互的原生审批客户端,而不
|
||||
}
|
||||
```
|
||||
|
||||
仅当你想覆盖审批人、添加筛选器或选择加入来源聊天投递时,才需要显式 Slack 原生配置:
|
||||
只有在你想要覆盖审批人、添加过滤器,或
|
||||
选择加入源聊天投递时,才需要显式 Slack 原生配置:
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -856,21 +860,23 @@ Slack 可以作为带交互式按钮和交互的原生审批客户端,而不
|
||||
}
|
||||
```
|
||||
|
||||
共享 `approvals.exec` 转发是独立的。仅当 exec 审批提示还必须路由到其他聊天或显式带外目标时才使用它。共享 `approvals.plugin` 转发也是独立的;当这些请求已落在 Slack 中时,Slack 原生按钮仍可完成插件审批。
|
||||
共享的 `approvals.exec` 转发是独立的。仅当执行审批提示还必须
|
||||
路由到其他聊天或显式带外目标时才使用它。共享的 `approvals.plugin` 转发也是
|
||||
独立的;当这些请求已经落在 Slack 中时,Slack 原生按钮仍可完成插件审批。
|
||||
|
||||
同一聊天中的 `/approve` 也可在已支持命令的 Slack 渠道和私信中工作。请参阅 [Exec 审批](/zh-CN/tools/exec-approvals),了解完整的审批转发模型。
|
||||
同聊天 `/approve` 也可在已经支持命令的 Slack 渠道和私信中使用。查看[执行审批](/zh-CN/tools/exec-approvals),了解完整的审批转发模型。
|
||||
|
||||
## 事件和运维行为
|
||||
## 事件和运行行为
|
||||
|
||||
- 消息编辑/删除会映射为系统事件。
|
||||
- 线程广播(“也发送到渠道”的线程回复)会作为普通用户消息处理。
|
||||
- 添加/移除表情回应事件会映射为系统事件。
|
||||
- 成员加入/离开、渠道创建/重命名,以及添加/移除置顶事件会映射为系统事件。
|
||||
- 启用 `configWrites` 时,`channel_id_changed` 可以迁移渠道配置键。
|
||||
- 渠道主题/用途元数据会被视为不受信任的上下文,并且可以注入到路由上下文中。
|
||||
- 适用时,线程起始消息和初始线程历史上下文播种会按配置的发送者允许列表进行筛选。
|
||||
- 分块操作和模态框交互会发出结构化的 `Slack interaction: ...` 系统事件,并包含丰富的载荷字段:
|
||||
- 分块操作:所选值、标签、选择器值和 `workflow_*` 元数据
|
||||
- 线程广播(“Also send to channel”线程回复)会作为普通用户消息处理。
|
||||
- 表情添加/移除事件会映射为系统事件。
|
||||
- 成员加入/离开、渠道创建/重命名,以及置顶添加/移除事件会映射为系统事件。
|
||||
- 当启用 `configWrites` 时,`channel_id_changed` 可以迁移渠道配置键。
|
||||
- 渠道主题/用途元数据会被视为不可信上下文,并可注入路由上下文。
|
||||
- 线程起始消息和初始线程历史上下文种子在适用时会按已配置的发送者允许列表过滤。
|
||||
- 块操作和模态框交互会发出带有丰富载荷字段的结构化 `Slack interaction: ...` 系统事件:
|
||||
- 块操作:选定值、标签、选择器值和 `workflow_*` 元数据
|
||||
- 模态框 `view_submission` 和 `view_closed` 事件,包含已路由的渠道元数据和表单输入
|
||||
|
||||
## 配置参考
|
||||
@ -896,9 +902,9 @@ Slack 可以作为带交互式按钮和交互的原生审批客户端,而不
|
||||
按顺序检查:
|
||||
|
||||
- `groupPolicy`
|
||||
- 渠道允许列表(`channels.slack.channels`)——**键必须是渠道 ID**(`C12345678`),而不是名称(`#channel-name`)。在 `groupPolicy: "allowlist"` 下,基于名称的键会静默失败,因为默认情况下渠道路由优先使用 ID。查找 ID:在 Slack 中右键点击该渠道 → **Copy link** —— URL 末尾的 `C...` 值就是渠道 ID。
|
||||
- 渠道允许列表(`channels.slack.channels`)— **键必须是渠道 ID**(`C12345678`),而不是名称(`#channel-name`)。在 `groupPolicy: "allowlist"` 下,基于名称的键会静默失败,因为渠道路由默认以 ID 优先。查找 ID:在 Slack 中右键点击渠道 → **Copy link** — URL 末尾的 `C...` 值就是渠道 ID。
|
||||
- `requireMention`
|
||||
- 每渠道 `users` 允许列表
|
||||
- 单个渠道的 `users` 允许列表
|
||||
|
||||
有用命令:
|
||||
|
||||
@ -915,8 +921,10 @@ openclaw doctor
|
||||
|
||||
- `channels.slack.dm.enabled`
|
||||
- `channels.slack.dmPolicy`(或旧版 `channels.slack.dm.policy`)
|
||||
- 配对审批 / 允许列表条目
|
||||
- Slack Assistant 私信事件:提到 `drop message_changed` 的详细日志通常表示 Slack 发送了一个已编辑的 Assistant 线程事件,但消息元数据中没有可恢复的人类发送者
|
||||
- 配对审批/允许列表条目
|
||||
- Slack Assistant 私信事件:提到 `drop message_changed` 的详细日志
|
||||
通常表示 Slack 发送了已编辑的 Assistant 线程事件,但消息元数据中
|
||||
没有可恢复的人类发送者
|
||||
|
||||
```bash
|
||||
openclaw pairing list slack
|
||||
@ -925,9 +933,11 @@ openclaw pairing list slack
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Socket 模式未连接">
|
||||
验证 Slack 应用设置中的机器人令牌、应用令牌和 Socket Mode 启用状态。
|
||||
验证 Slack 应用设置中的机器人 + 应用令牌以及 Socket Mode 启用状态。
|
||||
|
||||
如果 `openclaw channels status --probe --json` 显示 `botTokenStatus` 或 `appTokenStatus: "configured_unavailable"`,表示 Slack 账号已配置,但当前运行时无法解析由 SecretRef 支持的值。
|
||||
如果 `openclaw channels status --probe --json` 显示 `botTokenStatus` 或
|
||||
`appTokenStatus: "configured_unavailable"`,则 Slack 账号已配置,
|
||||
但当前运行时无法解析由 SecretRef 支撑的值。
|
||||
|
||||
</Accordion>
|
||||
|
||||
@ -936,55 +946,56 @@ openclaw pairing list slack
|
||||
|
||||
- 签名密钥
|
||||
- webhook 路径
|
||||
- Slack 请求 URL(Events + Interactivity + Slash Commands)
|
||||
- Slack Request URL(Events + Interactivity + Slash Commands)
|
||||
- 每个 HTTP 账号唯一的 `webhookPath`
|
||||
|
||||
如果账号快照中出现 `signingSecretStatus: "configured_unavailable"`,表示 HTTP 账号已配置,但当前运行时无法解析由 SecretRef 支持的签名密钥。
|
||||
如果账号快照中出现 `signingSecretStatus: "configured_unavailable"`,
|
||||
则 HTTP 账号已配置,但当前运行时无法解析由 SecretRef 支撑的签名密钥。
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="原生/斜杠命令未触发">
|
||||
验证你预期的是:
|
||||
|
||||
- 原生命令模式(`channels.slack.commands.native: true`),并且 Slack 中注册了匹配的斜杠命令
|
||||
- 或单一斜杠命令模式(`channels.slack.slashCommand.enabled: true`)
|
||||
- 原生命令模式(`channels.slack.commands.native: true`),并且 Slack 中已注册匹配的斜杠命令
|
||||
- 或单斜杠命令模式(`channels.slack.slashCommand.enabled: true`)
|
||||
|
||||
同时检查 `commands.useAccessGroups` 和渠道/用户允许列表。
|
||||
还要检查 `commands.useAccessGroups` 和渠道/用户允许列表。
|
||||
|
||||
</Accordion>
|
||||
</AccordionGroup>
|
||||
|
||||
## 附件视觉参考
|
||||
|
||||
当 Slack 文件下载成功且大小限制允许时,Slack 可以将下载的媒体附加到智能体回合中。图片文件可以通过媒体理解路径传递,或直接传递给支持视觉的回复模型;其他文件会作为可下载文件上下文保留,而不是作为图片输入处理。
|
||||
当 Slack 文件下载成功且大小限制允许时,Slack 可以将下载的媒体附加到智能体轮次。图像文件可以通过媒体理解路径传递,或直接传递给具备视觉能力的回复模型;其他文件会作为可下载文件上下文保留,而不是被视为图像输入。
|
||||
|
||||
### 支持的媒体类型
|
||||
|
||||
| 媒体类型 | 来源 | 当前行为 | 备注 |
|
||||
| ------------------------------ | -------------------- | --------------------------------------------------------------------------------- | ------------------------------------------------------------------------- |
|
||||
| JPEG / PNG / GIF / WebP 图片 | Slack 文件 URL | 下载并附加到本轮对话,以供支持视觉的处理使用 | 单文件上限:`channels.slack.mediaMaxMb`(默认 20 MB) |
|
||||
| PDF 文件 | Slack 文件 URL | 下载并作为文件上下文暴露给 `download-file` 或 `pdf` 等工具 | Slack 入站不会自动将 PDF 转换为图像视觉输入 |
|
||||
| 其他文件 | Slack 文件 URL | 尽可能下载并作为文件上下文暴露 | 二进制文件不会被视为图像输入 |
|
||||
| 线程回复 | 线程起始消息文件 | 当回复没有直接媒体时,可将根消息文件注入为上下文 | 仅包含文件的起始消息会使用附件占位符 |
|
||||
| 多图像消息 | 多个 Slack 文件 | 每个文件都会独立评估 | Slack 处理上限为每条消息八个文件 |
|
||||
| 媒体类型 | 来源 | 当前行为 | 备注 |
|
||||
| ------------------------------ | -------------------- | --------------------------------------------------------------------------- | ------------------------------------------------------------------------ |
|
||||
| JPEG / PNG / GIF / WebP 图像 | Slack 文件 URL | 已下载并附加到该轮次,以供支持视觉的处理使用 | 单文件上限:`channels.slack.mediaMaxMb`(默认 20 MB) |
|
||||
| PDF 文件 | Slack 文件 URL | 已下载并作为文件上下文暴露给 `download-file` 或 `pdf` 等工具 | Slack 入站不会自动将 PDF 转换为图像视觉输入 |
|
||||
| 其他文件 | Slack 文件 URL | 在可行时下载,并作为文件上下文暴露 | 二进制文件不会被视为图像输入 |
|
||||
| 线程回复 | 线程起始消息文件 | 当回复没有直接媒体时,根消息文件可作为上下文补全 | 仅包含文件的起始消息会使用附件占位符 |
|
||||
| 多图消息 | 多个 Slack 文件 | 每个文件都会独立评估 | Slack 处理每条消息最多限制为八个文件 |
|
||||
|
||||
### 入站流水线
|
||||
|
||||
当带有文件附件的 Slack 消息到达时:
|
||||
|
||||
1. OpenClaw 使用 bot token(`xoxb-...`)从 Slack 的私有 URL 下载文件。
|
||||
2. 文件下载成功后会写入媒体存储。
|
||||
1. OpenClaw 使用机器人令牌(`xoxb-...`)从 Slack 的私有 URL 下载文件。
|
||||
2. 文件会在成功后写入媒体存储。
|
||||
3. 下载的媒体路径和内容类型会添加到入站上下文。
|
||||
4. 支持图像的模型/工具路径可以使用该上下文中的图像附件。
|
||||
5. 非图像文件仍会作为文件元数据或媒体引用提供给能够处理它们的工具。
|
||||
5. 非图像文件仍可作为文件元数据或媒体引用提供给能够处理它们的工具。
|
||||
|
||||
### 线程根附件继承
|
||||
|
||||
当消息在线程中到达(具有 `thread_ts` 父级)时:
|
||||
当消息到达线程中(有一个 `thread_ts` 父级)时:
|
||||
|
||||
- 如果回复本身没有直接媒体,而包含的根消息有文件,Slack 可以将根文件注入为线程起始上下文。
|
||||
- 如果回复本身没有直接媒体,而包含的根消息有文件,Slack 可以将根文件补全为线程起始消息上下文。
|
||||
- 直接回复附件优先于根消息附件。
|
||||
- 只有文件而没有文本的根消息会用附件占位符表示,因此回退仍可包含其文件。
|
||||
- 只有文件且没有文本的根消息会用附件占位符表示,以便回退仍可包含其文件。
|
||||
|
||||
### 多附件处理
|
||||
|
||||
@ -993,31 +1004,31 @@ openclaw pairing list slack
|
||||
- 每个附件都会通过媒体流水线独立处理。
|
||||
- 下载的媒体引用会聚合到消息上下文中。
|
||||
- 处理顺序遵循事件载荷中的 Slack 文件顺序。
|
||||
- 某个附件下载失败不会阻塞其他附件。
|
||||
- 一个附件下载失败不会阻塞其他附件。
|
||||
|
||||
### 大小、下载和模型限制
|
||||
|
||||
- **大小上限**:默认每个文件 20 MB。可通过 `channels.slack.mediaMaxMb` 配置。
|
||||
- **下载失败**:Slack 无法提供的文件、过期 URL、无法访问的文件、超大文件,以及 Slack 认证/登录 HTML 响应会被跳过,而不是被报告为不支持的格式。
|
||||
- **视觉模型**:图像分析会在当前回复模型支持视觉时使用它,或者使用 `agents.defaults.imageModel` 配置的图像模型。
|
||||
- **下载失败**:Slack 无法提供的文件、过期 URL、不可访问文件、超大文件,以及 Slack 认证/登录 HTML 响应都会被跳过,而不是被报告为不支持的格式。
|
||||
- **视觉模型**:图像分析会使用支持视觉的当前回复模型,或配置在 `agents.defaults.imageModel` 的图像模型。
|
||||
|
||||
### 已知限制
|
||||
|
||||
| 场景 | 当前行为 | 解决方法 |
|
||||
| -------------------------------------- | ---------------------------------------------------------------------------- | -------------------------------------------------------------------------- |
|
||||
| 过期的 Slack 文件 URL | 跳过文件;不显示错误 | 在 Slack 中重新上传文件 |
|
||||
| 未配置视觉模型 | 图像附件会存储为媒体引用,但不会作为图像分析 | 配置 `agents.defaults.imageModel` 或使用支持视觉的回复模型 |
|
||||
| 非常大的图像(默认 > 20 MB) | 按大小上限跳过 | 如果 Slack 允许,可提高 `channels.slack.mediaMaxMb` |
|
||||
| 转发/共享附件 | 文本和 Slack 托管的图像/文件媒体会尽力处理 | 直接在 OpenClaw 线程中重新共享 |
|
||||
| PDF 附件 | 存储为文件/媒体上下文,不会自动路由到图像视觉 | 使用 `download-file` 获取文件元数据,或使用 `pdf` 工具进行 PDF 分析 |
|
||||
| 场景 | 当前行为 | 解决方法 |
|
||||
| -------------------------------------- | -------------------------------------------------------------- | ------------------------------------------------------------------------ |
|
||||
| 过期的 Slack 文件 URL | 文件被跳过;不会显示错误 | 在 Slack 中重新上传该文件 |
|
||||
| 未配置视觉模型 | 图像附件会存储为媒体引用,但不会作为图像分析 | 配置 `agents.defaults.imageModel`,或使用支持视觉的回复模型 |
|
||||
| 非常大的图像(默认 > 20 MB) | 按大小上限跳过 | 如果 Slack 允许,增大 `channels.slack.mediaMaxMb` |
|
||||
| 转发/共享的附件 | 文本和 Slack 托管的图像/文件媒体会尽力处理 | 直接在 OpenClaw 线程中重新共享 |
|
||||
| PDF 附件 | 存储为文件/媒体上下文,不会自动通过图像视觉路由 | 使用 `download-file` 获取文件元数据,或使用 `pdf` 工具进行 PDF 分析 |
|
||||
|
||||
### 相关文档
|
||||
|
||||
- [媒体理解流水线](/zh-CN/nodes/media-understanding)
|
||||
- [PDF 工具](/zh-CN/tools/pdf)
|
||||
- Epic: [#51349](https://github.com/openclaw/openclaw/issues/51349) — Slack 附件视觉启用
|
||||
- 回归测试: [#51353](https://github.com/openclaw/openclaw/issues/51353)
|
||||
- 实时验证: [#51354](https://github.com/openclaw/openclaw/issues/51354)
|
||||
- Epic:[#51349](https://github.com/openclaw/openclaw/issues/51349) — Slack 附件视觉启用
|
||||
- 回归测试:[#51353](https://github.com/openclaw/openclaw/issues/51353)
|
||||
- 实时验证:[#51354](https://github.com/openclaw/openclaw/issues/51354)
|
||||
|
||||
## 相关
|
||||
|
||||
@ -1037,7 +1048,7 @@ openclaw pairing list slack
|
||||
<Card title="配置" icon="sliders" href="/zh-CN/gateway/configuration">
|
||||
配置布局和优先级。
|
||||
</Card>
|
||||
<Card title="斜杠命令" icon="terminal" href="/zh-CN/tools/slash-commands">
|
||||
<Card title="Slash 命令" icon="terminal" href="/zh-CN/tools/slash-commands">
|
||||
命令目录和行为。
|
||||
</Card>
|
||||
</CardGroup>
|
||||
|
||||
@ -1,28 +1,28 @@
|
||||
---
|
||||
read_when:
|
||||
- 设置 Synology Chat 与 OpenClaw 配合使用
|
||||
- 设置 Synology Chat 以配合 OpenClaw 使用
|
||||
- 调试 Synology Chat 网络钩子路由
|
||||
summary: Synology Chat 网络钩子设置和 OpenClaw 配置
|
||||
title: Synology Chat
|
||||
x-i18n:
|
||||
generated_at: "2026-04-29T05:57:46Z"
|
||||
generated_at: "2026-05-02T04:47:33Z"
|
||||
model: gpt-5.5
|
||||
provider: openai
|
||||
source_hash: c3d6d7a56bd15d29de38c6ae29ae496b491c2e75df5e0a0a15410b0fbdc55a00
|
||||
source_hash: 1f1946425fa6e7a071b03d212854476dc2c0af98097f38da93d3711e5a5c7e96
|
||||
source_path: channels/synology-chat.md
|
||||
workflow: 16
|
||||
---
|
||||
|
||||
Status:使用 Synology Chat webhook 的内置插件私信渠道。
|
||||
该插件接受来自 Synology Chat outgoing webhook 的入站消息,并通过 Synology Chat incoming webhook 发送回复。
|
||||
该插件接收来自 Synology Chat 外发 webhook 的入站消息,并通过 Synology Chat 传入 webhook 发送回复。
|
||||
|
||||
## 内置插件
|
||||
|
||||
Synology Chat 在当前 OpenClaw 版本中作为内置插件随附,因此正常的打包构建不需要单独安装。
|
||||
Synology Chat 在当前 OpenClaw 版本中作为内置插件随附,因此常规打包版本不需要单独安装。
|
||||
|
||||
如果你使用的是较旧构建,或排除了 Synology Chat 的自定义安装,请手动安装:
|
||||
如果你使用的是较旧版本,或排除了 Synology Chat 的自定义安装,请手动安装:
|
||||
|
||||
从本地检出安装:
|
||||
从本地 checkout 安装:
|
||||
|
||||
```bash
|
||||
openclaw plugins install ./path/to/local/synology-chat-plugin
|
||||
@ -33,30 +33,30 @@ openclaw plugins install ./path/to/local/synology-chat-plugin
|
||||
## 快速设置
|
||||
|
||||
1. 确保 Synology Chat 插件可用。
|
||||
- 当前打包的 OpenClaw 版本已内置该插件。
|
||||
- 较旧/自定义安装可以使用上面的命令从源码检出手动添加。
|
||||
- 当前打包的 OpenClaw 版本已经内置它。
|
||||
- 较旧/自定义安装可以使用上面的命令从源码 checkout 手动添加它。
|
||||
- `openclaw onboard` 现在会在与 `openclaw channels add` 相同的渠道设置列表中显示 Synology Chat。
|
||||
- 非交互式设置:`openclaw channels add --channel synology-chat --token <token> --url <incoming-webhook-url>`
|
||||
2. 在 Synology Chat 集成中:
|
||||
- 创建一个 incoming webhook 并复制其 URL。
|
||||
- 使用你的 secret token 创建一个 outgoing webhook。
|
||||
3. 将 outgoing webhook URL 指向你的 OpenClaw Gateway 网关:
|
||||
- 创建一个传入 webhook,并复制其 URL。
|
||||
- 使用你的 secret token 创建一个外发 webhook。
|
||||
3. 将外发 webhook URL 指向你的 OpenClaw Gateway 网关:
|
||||
- 默认是 `https://gateway-host/webhook/synology`。
|
||||
- 或使用你的自定义 `channels.synology-chat.webhookPath`。
|
||||
4. 在 OpenClaw 中完成设置。
|
||||
- 引导式:`openclaw onboard`
|
||||
- 直接:`openclaw channels add --channel synology-chat --token <token> --url <incoming-webhook-url>`
|
||||
5. 重启 Gateway 网关,并向 Synology Chat 机器人发送私信。
|
||||
5. 重启 Gateway 网关,并向 Synology Chat 机器人发送一条私信。
|
||||
|
||||
Webhook 认证详情:
|
||||
|
||||
- OpenClaw 会先从 `body.token` 接受 outgoing webhook token,然后是 `?token=...`,最后是 headers。
|
||||
- OpenClaw 先从 `body.token` 接受外发 webhook token,然后是 `?token=...`,最后是 headers。
|
||||
- 接受的 header 形式:
|
||||
- `x-synology-token`
|
||||
- `x-webhook-token`
|
||||
- `x-openclaw-token`
|
||||
- `Authorization: Bearer <token>`
|
||||
- 空 token 或缺失 token 会失败关闭。
|
||||
- 空 token 或缺失 token 会失败并关闭访问。
|
||||
|
||||
最小配置:
|
||||
|
||||
@ -79,7 +79,7 @@ Webhook 认证详情:
|
||||
|
||||
## 环境变量
|
||||
|
||||
对于默认账户,你可以使用环境变量:
|
||||
对于默认账号,你可以使用环境变量:
|
||||
|
||||
- `SYNOLOGY_CHAT_TOKEN`
|
||||
- `SYNOLOGY_CHAT_INCOMING_URL`
|
||||
@ -94,12 +94,12 @@ Webhook 认证详情:
|
||||
|
||||
## 私信策略和访问控制
|
||||
|
||||
- `dmPolicy: "allowlist"` 是推荐的默认值。
|
||||
- `dmPolicy: "allowlist"` 是推荐默认值。
|
||||
- `allowedUserIds` 接受 Synology 用户 ID 列表(或逗号分隔字符串)。
|
||||
- 在 `allowlist` 模式下,空的 `allowedUserIds` 列表会被视为配置错误,webhook 路由不会启动(如需允许所有用户,请使用 `dmPolicy: "open"` 与 `allowedUserIds: ["*"]`)。
|
||||
- 只有当 `allowedUserIds` 包含 `"*"` 时,`dmPolicy: "open"` 才允许公开私信;如果是限制性条目,则只有匹配的用户可以聊天。
|
||||
- 在 `allowlist` 模式下,空的 `allowedUserIds` 列表会被视为配置错误,并且 webhook 路由不会启动(若要允许所有人,请使用 `dmPolicy: "open"` 搭配 `allowedUserIds: ["*"]`)。
|
||||
- `dmPolicy: "open"` 只有在 `allowedUserIds` 包含 `"*"` 时才允许公开私信;如果有受限条目,只有匹配用户可以聊天。
|
||||
- `dmPolicy: "disabled"` 会阻止私信。
|
||||
- 默认情况下,回复收件人绑定保持在稳定的数字 `user_id` 上。`channels.synology-chat.dangerouslyAllowNameMatching: true` 是应急兼容模式,会重新启用可变用户名/昵称查找来投递回复。
|
||||
- 回复收件人绑定默认保持在稳定的数字 `user_id` 上。`channels.synology-chat.dangerouslyAllowNameMatching: true` 是破窗兼容模式,会重新启用可变用户名/昵称查找来投递回复。
|
||||
- 配对批准可使用:
|
||||
- `openclaw pairing list synology-chat`
|
||||
- `openclaw pairing approve synology-chat <CODE>`
|
||||
@ -113,18 +113,19 @@ Webhook 认证详情:
|
||||
```bash
|
||||
openclaw message send --channel synology-chat --target 123456 --text "Hello from OpenClaw"
|
||||
openclaw message send --channel synology-chat --target synology-chat:123456 --text "Hello again"
|
||||
openclaw message send --channel synology-chat --target synology:123456 --text "Short prefix"
|
||||
```
|
||||
|
||||
支持通过基于 URL 的文件投递发送媒体。
|
||||
出站文件 URL 必须使用 `http` 或 `https`,并且在 OpenClaw 将该 URL 转发到 NAS webhook 之前,会拒绝私有或其他被阻止的网络目标。
|
||||
出站文件 URL 必须使用 `http` 或 `https`,并且私有或其他被阻止的网络目标会在 OpenClaw 将 URL 转发到 NAS webhook 之前被拒绝。
|
||||
|
||||
## 多账户
|
||||
## 多账号
|
||||
|
||||
`channels.synology-chat.accounts` 下支持多个 Synology Chat 账户。
|
||||
每个账户都可以覆盖 token、incoming URL、webhook path、私信策略和限制。
|
||||
私信会话按账户和用户隔离,因此两个不同 Synology 账户上的相同数字 `user_id` 不会共享对话状态。
|
||||
为每个已启用账户指定不同的 `webhookPath`。OpenClaw 现在会拒绝重复的精确路径,并且在多账户设置中会拒绝启动仅继承共享 webhook path 的命名账户。
|
||||
如果你有意需要为某个命名账户使用旧版继承,请在该账户上或在 `channels.synology-chat` 设置 `dangerouslyAllowInheritedWebhookPath: true`,但重复的精确路径仍会失败关闭。优先使用显式的按账户路径。
|
||||
`channels.synology-chat.accounts` 下支持多个 Synology Chat 账号。
|
||||
每个账号都可以覆盖 token、传入 URL、webhook 路径、私信策略和限制。
|
||||
私信会话按账号和用户隔离,因此两个不同 Synology 账号上的相同数字 `user_id` 不会共享对话记录状态。
|
||||
为每个启用的账号提供不同的 `webhookPath`。OpenClaw 现在会拒绝重复的精确路径,并且在多账号设置中,会拒绝启动仅继承共享 webhook 路径的命名账号。
|
||||
如果你确实需要为某个命名账号使用旧版继承,请在该账号或 `channels.synology-chat` 上设置 `dangerouslyAllowInheritedWebhookPath: true`,但重复的精确路径仍会失败并关闭访问。优先使用显式的逐账号路径。
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -151,34 +152,34 @@ openclaw message send --channel synology-chat --target synology-chat:123456 --te
|
||||
|
||||
## 安全说明
|
||||
|
||||
- 保持 `token` 机密,如果泄露请轮换。
|
||||
- 除非你明确信任自签名的本地 NAS 证书,否则保持 `allowInsecureSsl: false`。
|
||||
- 入站 webhook 请求会按发送者进行 token 验证和限速。
|
||||
- 无效 token 检查使用常量时间 secret 比较,并失败关闭。
|
||||
- 保持 `token` 机密;如果泄露,请轮换它。
|
||||
- 除非你明确信任自签名本地 NAS 证书,否则保持 `allowInsecureSsl: false`。
|
||||
- 入站 webhook 请求会经过 token 验证,并按发送者限速。
|
||||
- 无效 token 检查使用常量时间 secret 比较,并会失败并关闭访问。
|
||||
- 生产环境优先使用 `dmPolicy: "allowlist"`。
|
||||
- 除非你明确需要基于旧版用户名的回复投递,否则保持 `dangerouslyAllowNameMatching` 关闭。
|
||||
- 除非你明确接受多账户设置中的共享路径路由风险,否则保持 `dangerouslyAllowInheritedWebhookPath` 关闭。
|
||||
- 除非你明确需要旧版基于用户名的回复投递,否则保持 `dangerouslyAllowNameMatching` 关闭。
|
||||
- 除非你明确接受多账号设置中的共享路径路由风险,否则保持 `dangerouslyAllowInheritedWebhookPath` 关闭。
|
||||
|
||||
## 故障排除
|
||||
|
||||
- `Missing required fields (token, user_id, text)`:
|
||||
- outgoing webhook payload 缺少某个必填字段
|
||||
- 如果 Synology 通过 headers 发送 token,请确保 Gateway 网关/代理保留这些 headers
|
||||
- 外发 webhook payload 缺少某个必需字段
|
||||
- 如果 Synology 在 headers 中发送 token,请确保 Gateway 网关/代理保留这些 headers
|
||||
- `Invalid token`:
|
||||
- outgoing webhook secret 与 `channels.synology-chat.token` 不匹配
|
||||
- 请求命中了错误的账户/webhook path
|
||||
- 外发 webhook secret 与 `channels.synology-chat.token` 不匹配
|
||||
- 请求命中了错误的账号/webhook 路径
|
||||
- 反向代理在请求到达 OpenClaw 之前剥离了 token header
|
||||
- `Rate limit exceeded`:
|
||||
- 来自同一来源的无效 token 尝试过多,可能会暂时锁定该来源
|
||||
- 已认证发送者也有单独的按用户消息速率限制
|
||||
- 来自同一来源的过多无效 token 尝试可能会暂时锁定该来源
|
||||
- 已认证发送者也有单独的按用户消息限速
|
||||
- `Allowlist is empty. Configure allowedUserIds or use dmPolicy=open with allowedUserIds=["*"].`:
|
||||
- `dmPolicy="allowlist"` 已启用,但未配置用户
|
||||
- `dmPolicy="allowlist"` 已启用,但未配置任何用户
|
||||
- `User not authorized`:
|
||||
- 发送者的数字 `user_id` 不在 `allowedUserIds` 中
|
||||
|
||||
## 相关
|
||||
## 相关内容
|
||||
|
||||
- [渠道概览](/zh-CN/channels) — 所有支持的渠道
|
||||
- [Channels 概览](/zh-CN/channels) — 所有受支持渠道
|
||||
- [配对](/zh-CN/channels/pairing) — 私信认证和配对流程
|
||||
- [群组](/zh-CN/channels/groups) — 群聊行为和提及门控
|
||||
- [渠道路由](/zh-CN/channels/channel-routing) — 消息的会话路由
|
||||
|
||||
@ -1,18 +1,18 @@
|
||||
---
|
||||
read_when:
|
||||
- 处理 Telegram 功能或 Webhook
|
||||
summary: Telegram 机器人支持状态、功能和配置
|
||||
- 开发 Telegram 功能或网络钩子
|
||||
summary: Telegram 机器人支持状态、能力和配置
|
||||
title: Telegram
|
||||
x-i18n:
|
||||
generated_at: "2026-04-30T15:18:33Z"
|
||||
generated_at: "2026-05-02T04:47:23Z"
|
||||
model: gpt-5.5
|
||||
provider: openai
|
||||
source_hash: d18ca6c7ab39d7d34848c562857661501d8364329f6e5a266213aa23846047dd
|
||||
source_hash: e6ef6fc51d18f4bde9219b75b69da204e18a227b40c4c916eae701494c099de3
|
||||
source_path: channels/telegram.md
|
||||
workflow: 16
|
||||
---
|
||||
|
||||
可用于生产环境中的 bot 私信和群组,基于 grammY。长轮询是默认模式;webhook 模式是可选的。
|
||||
可用于生产环境的机器人私信和群组,基于 grammY。默认模式是长轮询;webhook 模式为可选。
|
||||
|
||||
<CardGroup cols={3}>
|
||||
<Card title="配对" icon="link" href="/zh-CN/channels/pairing">
|
||||
@ -29,14 +29,14 @@ x-i18n:
|
||||
## 快速设置
|
||||
|
||||
<Steps>
|
||||
<Step title="在 BotFather 中创建 bot token">
|
||||
打开 Telegram 并与 **@BotFather** 聊天(确认账号名完全是 `@BotFather`)。
|
||||
<Step title="在 BotFather 中创建机器人令牌">
|
||||
打开 Telegram 并与 **@BotFather** 聊天(确认句柄正好是 `@BotFather`)。
|
||||
|
||||
运行 `/newbot`,按照提示操作,并保存 token。
|
||||
运行 `/newbot`,按提示操作,并保存令牌。
|
||||
|
||||
</Step>
|
||||
|
||||
<Step title="配置 token 和私信策略">
|
||||
<Step title="配置令牌和私信策略">
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -52,11 +52,11 @@ x-i18n:
|
||||
```
|
||||
|
||||
环境变量回退:`TELEGRAM_BOT_TOKEN=...`(仅默认账号)。
|
||||
Telegram **不**使用 `openclaw channels login telegram`;请在配置/环境变量中配置 token,然后启动 Gateway 网关。
|
||||
Telegram **不**使用 `openclaw channels login telegram`;请在配置/环境变量中配置令牌,然后启动 Gateway 网关。
|
||||
|
||||
</Step>
|
||||
|
||||
<Step title="启动 Gateway 网关并批准第一个私信">
|
||||
<Step title="启动 Gateway 网关并批准第一条私信">
|
||||
|
||||
```bash
|
||||
openclaw gateway
|
||||
@ -68,34 +68,34 @@ openclaw pairing approve telegram <CODE>
|
||||
|
||||
</Step>
|
||||
|
||||
<Step title="将 bot 添加到群组">
|
||||
将 bot 添加到你的群组,然后设置 `channels.telegram.groups` 和 `groupPolicy`,使其与你的访问模型匹配。
|
||||
<Step title="将机器人添加到群组">
|
||||
将机器人添加到你的群组,然后设置 `channels.telegram.groups` 和 `groupPolicy`,使其符合你的访问模型。
|
||||
</Step>
|
||||
</Steps>
|
||||
|
||||
<Note>
|
||||
token 解析顺序是账号感知的。实际使用中,配置值优先于环境变量回退,并且 `TELEGRAM_BOT_TOKEN` 只适用于默认账号。
|
||||
令牌解析顺序感知账号。实际使用中,配置值优先于环境变量回退,而 `TELEGRAM_BOT_TOKEN` 仅适用于默认账号。
|
||||
</Note>
|
||||
|
||||
## Telegram 端设置
|
||||
|
||||
<AccordionGroup>
|
||||
<Accordion title="隐私模式和群组可见性">
|
||||
Telegram bot 默认使用**隐私模式**,这会限制它们接收的群组消息。
|
||||
Telegram 机器人默认使用**隐私模式**,这会限制它们接收哪些群组消息。
|
||||
|
||||
如果 bot 必须看到所有群组消息,可以:
|
||||
如果机器人必须看到所有群组消息,可以:
|
||||
|
||||
- 通过 `/setprivacy` 禁用隐私模式,或
|
||||
- 将 bot 设为群组管理员。
|
||||
- 将机器人设为群组管理员。
|
||||
|
||||
切换隐私模式时,请在每个群组中移除并重新添加 bot,以便 Telegram 应用该变更。
|
||||
切换隐私模式时,请在每个群组中移除并重新添加机器人,以便 Telegram 应用该更改。
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="群组权限">
|
||||
管理员状态在 Telegram 群组设置中控制。
|
||||
|
||||
管理员 bot 会接收所有群组消息,这对始终在线的群组行为很有用。
|
||||
管理员机器人会接收所有群组消息,这对始终在线的群组行为很有用。
|
||||
|
||||
</Accordion>
|
||||
|
||||
@ -111,34 +111,34 @@ token 解析顺序是账号感知的。实际使用中,配置值优先于环
|
||||
|
||||
<Tabs>
|
||||
<Tab title="私信策略">
|
||||
`channels.telegram.dmPolicy` 控制直接消息访问:
|
||||
`channels.telegram.dmPolicy` 控制私信访问:
|
||||
|
||||
- `pairing`(默认)
|
||||
- `allowlist`(要求 `allowFrom` 中至少有一个发送者 ID)
|
||||
- `open`(要求 `allowFrom` 包含 `"*"`)
|
||||
- `disabled`
|
||||
|
||||
`dmPolicy: "open"` 搭配 `allowFrom: ["*"]` 会让任何找到或猜到 bot 用户名的 Telegram 账号都能向 bot 发出命令。仅将其用于有意公开且工具受到严格限制的 bot;单一所有者 bot 应使用带数字用户 ID 的 `allowlist`。
|
||||
`dmPolicy: "open"` 搭配 `allowFrom: ["*"]` 会让任何找到或猜到机器人用户名的 Telegram 账号都能命令该机器人。仅对有意公开且工具受到严格限制的机器人使用它;单所有者机器人应使用带数字用户 ID 的 `allowlist`。
|
||||
|
||||
`channels.telegram.allowFrom` 接受数字 Telegram 用户 ID。`telegram:` / `tg:` 前缀会被接受并规范化。
|
||||
在多账号配置中,限制性的顶层 `channels.telegram.allowFrom` 会被视为安全边界:账号级 `allowFrom: ["*"]` 条目不会让该账号公开,除非合并后的有效账号允许列表仍包含显式通配符。
|
||||
`dmPolicy: "allowlist"` 搭配空的 `allowFrom` 会阻止所有私信,并会被配置验证拒绝。
|
||||
设置只会要求数字用户 ID。
|
||||
如果你升级后配置中包含 `@username` 允许列表条目,请运行 `openclaw doctor --fix` 来解析它们(尽力而为;需要 Telegram bot token)。
|
||||
如果你之前依赖配对存储允许列表文件,`openclaw doctor --fix` 可以在允许列表流程中将条目恢复到 `channels.telegram.allowFrom`(例如当 `dmPolicy: "allowlist"` 还没有显式 ID 时)。
|
||||
`dmPolicy: "allowlist"` 搭配空的 `allowFrom` 会阻止所有私信,并会被配置校验拒绝。
|
||||
设置只要求数字用户 ID。
|
||||
如果你已升级且配置中包含 `@username` 允许列表条目,请运行 `openclaw doctor --fix` 来解析它们(尽力而为;需要 Telegram 机器人令牌)。
|
||||
如果你之前依赖配对存储允许列表文件,`openclaw doctor --fix` 可以在允许列表流程中将条目恢复到 `channels.telegram.allowFrom`(例如当 `dmPolicy: "allowlist"` 尚无显式 ID 时)。
|
||||
|
||||
对于单一所有者 bot,建议使用 `dmPolicy: "allowlist"` 并配置显式数字 `allowFrom` ID,以便将访问策略持久保存在配置中(而不是依赖之前的配对批准)。
|
||||
对于单所有者机器人,建议使用 `dmPolicy: "allowlist"` 并设置显式数字 `allowFrom` ID,以便将访问策略持久保存在配置中(而不是依赖之前的配对批准)。
|
||||
|
||||
常见困惑:私信配对批准并不表示“此发送者在任何地方都已授权”。
|
||||
配对会授予私信访问权限。如果尚未存在命令所有者,第一个获批配对还会设置 `commands.ownerAllowFrom`,让仅所有者命令和 exec 批准拥有显式操作员账号。
|
||||
常见混淆:私信配对批准并不意味着“此发送者已在所有位置获得授权”。
|
||||
配对授予私信访问权限。如果还没有命令所有者,第一次获批配对还会设置 `commands.ownerAllowFrom`,使仅所有者命令和 exec 批准拥有显式操作员账号。
|
||||
群组发送者授权仍来自显式配置允许列表。
|
||||
如果你想要“我授权一次后,私信和群组命令都可用”,请将你的数字 Telegram 用户 ID 放入 `channels.telegram.allowFrom`;对于仅所有者命令,确保 `commands.ownerAllowFrom` 包含 `telegram:<your user id>`。
|
||||
如果你希望“我授权一次,私信和群组命令都能工作”,请将你的数字 Telegram 用户 ID 放入 `channels.telegram.allowFrom`;对于仅所有者命令,请确保 `commands.ownerAllowFrom` 包含 `telegram:<your user id>`。
|
||||
|
||||
### 查找你的 Telegram 用户 ID
|
||||
|
||||
更安全(不使用第三方 bot):
|
||||
更安全(无第三方机器人):
|
||||
|
||||
1. 给你的 bot 发送私信。
|
||||
1. 私信你的机器人。
|
||||
2. 运行 `openclaw logs --follow`。
|
||||
3. 读取 `from.id`。
|
||||
|
||||
@ -153,13 +153,13 @@ curl "https://api.telegram.org/bot<bot_token>/getUpdates"
|
||||
</Tab>
|
||||
|
||||
<Tab title="群组策略和允许列表">
|
||||
两个控制项会一起生效:
|
||||
两个控制项共同生效:
|
||||
|
||||
1. **允许哪些群组**(`channels.telegram.groups`)
|
||||
- 没有 `groups` 配置:
|
||||
- 使用 `groupPolicy: "open"`:任何群组都可以通过群组 ID 检查
|
||||
- 使用 `groupPolicy: "allowlist"`(默认):在你添加 `groups` 条目(或 `"*"`)之前,群组会被阻止
|
||||
- 已配置 `groups`:作为允许列表生效(显式 ID 或 `"*"`)
|
||||
- 搭配 `groupPolicy: "open"`:任何群组都可以通过群组 ID 检查
|
||||
- 搭配 `groupPolicy: "allowlist"`(默认):在你添加 `groups` 条目(或 `"*"`)之前,群组会被阻止
|
||||
- 已配置 `groups`:作为允许列表(显式 ID 或 `"*"`)
|
||||
|
||||
2. **群组中允许哪些发送者**(`channels.telegram.groupPolicy`)
|
||||
- `open`
|
||||
@ -168,13 +168,13 @@ curl "https://api.telegram.org/bot<bot_token>/getUpdates"
|
||||
|
||||
`groupAllowFrom` 用于群组发送者过滤。如果未设置,Telegram 会回退到 `allowFrom`。
|
||||
`groupAllowFrom` 条目应为数字 Telegram 用户 ID(`telegram:` / `tg:` 前缀会被规范化)。
|
||||
不要把 Telegram 群组或超级群组聊天 ID 放在 `groupAllowFrom` 中。负数聊天 ID 应放在 `channels.telegram.groups` 下。
|
||||
非数字条目会被发送者授权忽略。
|
||||
不要将 Telegram 群组或超级群组聊天 ID 放入 `groupAllowFrom`。负数聊天 ID 属于 `channels.telegram.groups`。
|
||||
非数字条目会被忽略,不用于发送者授权。
|
||||
安全边界(`2026.2.25+`):群组发送者认证**不会**继承私信配对存储批准。
|
||||
配对仅限私信。对于群组,请设置 `groupAllowFrom` 或每群组/每话题的 `allowFrom`。
|
||||
如果未设置 `groupAllowFrom`,Telegram 会回退到配置中的 `allowFrom`,而不是配对存储。
|
||||
单一所有者 bot 的实用模式:在 `channels.telegram.allowFrom` 中设置你的用户 ID,保持 `groupAllowFrom` 未设置,并在 `channels.telegram.groups` 下允许目标群组。
|
||||
运行时注意事项:如果完全缺少 `channels.telegram`,运行时默认采用故障关闭的 `groupPolicy="allowlist"`,除非显式设置了 `channels.defaults.groupPolicy`。
|
||||
配对仅限私信。对于群组,请设置 `groupAllowFrom` 或按群组/按话题设置 `allowFrom`。
|
||||
如果未设置 `groupAllowFrom`,Telegram 会回退到配置 `allowFrom`,而不是配对存储。
|
||||
单所有者机器人的实用模式:在 `channels.telegram.allowFrom` 中设置你的用户 ID,保持 `groupAllowFrom` 未设置,并在 `channels.telegram.groups` 下允许目标群组。
|
||||
运行时说明:如果完全缺少 `channels.telegram`,运行时默认会故障关闭为 `groupPolicy="allowlist"`,除非显式设置了 `channels.defaults.groupPolicy`。
|
||||
|
||||
示例:允许一个特定群组中的任何成员:
|
||||
|
||||
@ -193,7 +193,7 @@ curl "https://api.telegram.org/bot<bot_token>/getUpdates"
|
||||
}
|
||||
```
|
||||
|
||||
示例:只允许一个特定群组内的特定用户:
|
||||
示例:仅允许一个特定群组中的特定用户:
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -214,8 +214,8 @@ curl "https://api.telegram.org/bot<bot_token>/getUpdates"
|
||||
常见错误:`groupAllowFrom` 不是 Telegram 群组允许列表。
|
||||
|
||||
- 将类似 `-1001234567890` 的负数 Telegram 群组或超级群组聊天 ID 放在 `channels.telegram.groups` 下。
|
||||
- 当你想限制允许群组中哪些人可以触发 bot 时,将类似 `8734062810` 的 Telegram 用户 ID 放在 `groupAllowFrom` 下。
|
||||
- 仅在你希望允许群组中的任何成员都能与 bot 对话时,使用 `groupAllowFrom: ["*"]`。
|
||||
- 当你想限制允许群组内哪些人可以触发机器人时,将类似 `8734062810` 的 Telegram 用户 ID 放在 `groupAllowFrom` 下。
|
||||
- 仅当你希望允许群组中的任何成员都能与机器人对话时,才使用 `groupAllowFrom: ["*"]`。
|
||||
|
||||
</Warning>
|
||||
|
||||
@ -236,7 +236,7 @@ curl "https://api.telegram.org/bot<bot_token>/getUpdates"
|
||||
- `/activation always`
|
||||
- `/activation mention`
|
||||
|
||||
这些只会更新会话状态。使用配置实现持久化。
|
||||
这些只更新会话状态。使用配置实现持久化。
|
||||
|
||||
持久化配置示例:
|
||||
|
||||
@ -264,13 +264,13 @@ curl "https://api.telegram.org/bot<bot_token>/getUpdates"
|
||||
## 运行时行为
|
||||
|
||||
- Telegram 由 Gateway 网关进程拥有。
|
||||
- 路由是确定性的:Telegram 入站消息会回复到 Telegram(模型不会选择渠道)。
|
||||
- 入站消息会规范化为共享渠道信封,其中包含回复元数据和媒体占位符。
|
||||
- 群组会话按群组 ID 隔离。论坛话题会追加 `:topic:<threadId>` 以保持话题隔离。
|
||||
- 私信消息可以携带 `message_thread_id`;OpenClaw 会使用线程感知的会话键路由它们,并为回复保留线程 ID。
|
||||
- 长轮询使用 grammY runner,并按每个聊天/每个线程排序。整体 runner sink 并发使用 `agents.defaults.maxConcurrent`。
|
||||
- 长轮询在每个 Gateway 网关进程内受到保护,因此同一时间只有一个活跃 poller 可以使用一个 bot token。如果你仍然看到 `getUpdates` 409 冲突,很可能有另一个 OpenClaw Gateway 网关、脚本或外部 poller 正在使用同一个 token。
|
||||
- 默认情况下,长轮询 watchdog 会在 120 秒内没有完成的 `getUpdates` 存活信号后触发重启。只有当你的部署在长时间运行工作期间仍出现误判的轮询停滞重启时,才增加 `channels.telegram.pollingStallThresholdMs`。该值以毫秒为单位,允许范围为 `30000` 到 `600000`;支持按账号覆盖。
|
||||
- 路由是确定性的:Telegram 入站会回复到 Telegram(模型不会选择渠道)。
|
||||
- 入站消息会规范化为共享渠道信封,并带有回复元数据和媒体占位符。
|
||||
- 群组会话按群组 ID 隔离。论坛话题会附加 `:topic:<threadId>`,以保持话题隔离。
|
||||
- 私信消息可以携带 `message_thread_id`;OpenClaw 会使用感知线程的会话键进行路由,并保留线程 ID 用于回复。
|
||||
- 长轮询使用 grammY runner,并按聊天/按线程排序。整体 runner sink 并发使用 `agents.defaults.maxConcurrent`。
|
||||
- 长轮询在每个 Gateway 网关进程内部受到保护,因此同一时间只有一个活动 poller 可以使用一个机器人令牌。如果你仍然看到 `getUpdates` 409 冲突,可能是另一个 OpenClaw Gateway 网关、脚本或外部 poller 正在使用同一令牌。
|
||||
- 默认情况下,如果 120 秒内没有完成的 `getUpdates` 活性信号,长轮询 watchdog 会触发重启。仅当你的部署在长时间运行的工作中仍看到误判的轮询停滞重启时,才增大 `channels.telegram.pollingStallThresholdMs`。该值以毫秒为单位,允许范围为 `30000` 到 `600000`;支持按账号覆盖。
|
||||
- Telegram Bot API 不支持已读回执(`sendReadReceipts` 不适用)。
|
||||
|
||||
## 功能参考
|
||||
@ -285,11 +285,11 @@ curl "https://api.telegram.org/bot<bot_token>/getUpdates"
|
||||
要求:
|
||||
|
||||
- `channels.telegram.streaming` 为 `off | partial | block | progress`(默认:`partial`)
|
||||
- 在 Telegram 上,`progress` 映射到 `partial`(兼容跨渠道命名)
|
||||
- `progress` 在 Telegram 上映射到 `partial`(兼容跨渠道命名)
|
||||
- `streaming.preview.toolProgress` 控制工具/进度更新是否复用同一条已编辑的预览消息(默认:预览流式传输启用时为 `true`)
|
||||
- 会检测旧版 `channels.telegram.streamMode` 和布尔值 `streaming`;运行 `openclaw doctor --fix` 可将它们迁移到 `channels.telegram.streaming.mode`
|
||||
- 会检测旧版 `channels.telegram.streamMode` 和布尔型 `streaming` 值;运行 `openclaw doctor --fix` 将它们迁移到 `channels.telegram.streaming.mode`
|
||||
|
||||
工具进度预览更新是工具运行时显示的简短“Working...”行,例如命令执行、文件读取、规划更新或补丁摘要。Telegram 默认保持启用这些更新,以匹配 `v2026.4.22` 及之后版本发布的 OpenClaw 行为。若要保留回答文本的已编辑预览,但隐藏工具进度行,请设置:
|
||||
工具进度预览更新是在工具运行时显示的简短“Working...”行,例如命令执行、文件读取、规划更新或补丁摘要。Telegram 默认保持启用,以匹配 `v2026.4.22` 及更高版本中已发布的 OpenClaw 行为。若要保留回答文本的已编辑预览,但隐藏工具进度行,请设置:
|
||||
|
||||
```json
|
||||
{
|
||||
@ -306,18 +306,18 @@ curl "https://api.telegram.org/bot<bot_token>/getUpdates"
|
||||
}
|
||||
```
|
||||
|
||||
仅当你想要只交付最终消息时,才使用 `streaming.mode: "off"`:Telegram 预览编辑会被禁用,通用工具/进度闲聊会被抑制,而不是作为独立的“Working...”消息发送。批准提示、媒体载荷和错误仍会通过正常最终交付路由。仅当你想保留回答预览编辑,同时隐藏工具进度状态行时,才使用 `streaming.preview.toolProgress: false`。
|
||||
仅当你希望只交付最终消息时,才使用 `streaming.mode: "off"`:Telegram 预览编辑会被禁用,通用工具/进度闲聊会被抑制,而不是作为独立的“Working...”消息发送。批准提示、媒体载荷和错误仍会通过正常最终交付路由。仅当你只想保留回答预览编辑,同时隐藏工具进度状态行时,才使用 `streaming.preview.toolProgress: false`。
|
||||
|
||||
对于纯文本回复:
|
||||
|
||||
- 短私信/群组/话题预览:OpenClaw 保留同一条预览消息,并在原处执行最终编辑
|
||||
- 超过约一分钟的预览:OpenClaw 将完成后的回复作为新的最终消息发送,然后清理预览,因此 Telegram 的可见时间戳会反映完成时间,而不是预览创建时间
|
||||
- 简短私信/群组/话题预览:OpenClaw 保持同一条预览消息,并在原处执行最终编辑
|
||||
- 超过约一分钟的预览:OpenClaw 将完成的回复作为新的最终消息发送,然后清理预览,因此 Telegram 的可见时间戳反映的是完成时间,而不是预览创建时间
|
||||
|
||||
对于复杂回复(例如媒体载荷),OpenClaw 会回退到正常的最终送达方式,然后清理预览消息。
|
||||
对于复杂回复(例如媒体载荷),OpenClaw 会回退到常规最终投递,然后清理预览消息。
|
||||
|
||||
预览流式传输与分块流式传输是分开的。当为 Telegram 显式启用分块流式传输时,OpenClaw 会跳过预览流,以避免双重流式传输。
|
||||
预览流式传输独立于分块流式传输。当为 Telegram 显式启用分块流式传输时,OpenClaw 会跳过预览流,以避免双重流式传输。
|
||||
|
||||
仅限 Telegram 的推理流:
|
||||
仅 Telegram 的推理流:
|
||||
|
||||
- `/reasoning stream` 在生成时将推理发送到实时预览
|
||||
- 最终答案发送时不包含推理文本
|
||||
@ -331,16 +331,16 @@ curl "https://api.telegram.org/bot<bot_token>/getUpdates"
|
||||
- 原始模型 HTML 会被转义,以减少 Telegram 解析失败。
|
||||
- 如果 Telegram 拒绝解析后的 HTML,OpenClaw 会以纯文本重试。
|
||||
|
||||
链接预览默认启用,可通过 `channels.telegram.linkPreview: false` 禁用。
|
||||
链接预览默认启用,可用 `channels.telegram.linkPreview: false` 禁用。
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="原生命令和自定义命令">
|
||||
Telegram 命令菜单注册会在启动时通过 `setMyCommands` 处理。
|
||||
Telegram 命令菜单注册在启动时通过 `setMyCommands` 处理。
|
||||
|
||||
原生命令默认值:
|
||||
|
||||
- `commands.native: "auto"` 为 Telegram 启用原生命令
|
||||
- `commands.native: "auto"` 会为 Telegram 启用原生命令
|
||||
|
||||
添加自定义命令菜单项:
|
||||
|
||||
@ -359,24 +359,24 @@ curl "https://api.telegram.org/bot<bot_token>/getUpdates"
|
||||
|
||||
规则:
|
||||
|
||||
- 名称会被规范化(去除开头的 `/`,转换为小写)
|
||||
- 名称会被规范化(去掉开头的 `/`,转为小写)
|
||||
- 有效模式:`a-z`、`0-9`、`_`,长度 `1..32`
|
||||
- 自定义命令不能覆盖原生命令
|
||||
- 冲突/重复项会被跳过并记录日志
|
||||
|
||||
注意:
|
||||
注意事项:
|
||||
|
||||
- 自定义命令只是菜单项;它们不会自动实现行为
|
||||
- 插件/skill 命令即使未显示在 Telegram 菜单中,在输入时仍可工作
|
||||
- 即使未显示在 Telegram 菜单中,插件/skill 命令在输入时仍然可以工作
|
||||
|
||||
如果禁用原生命令,内置命令会被移除。自定义/插件命令在配置后仍可注册。
|
||||
如果原生命令被禁用,内置项会被移除。自定义/插件命令在已配置时仍可注册。
|
||||
|
||||
常见设置失败:
|
||||
|
||||
- `setMyCommands failed` 并带有 `BOT_COMMANDS_TOO_MUCH` 表示 Telegram 菜单在裁剪后仍然溢出;减少插件/skill/自定义命令,或禁用 `channels.telegram.commands.native`。
|
||||
- 当直接 Bot API curl 命令可用,但 `deleteWebhook`、`deleteMyCommands` 或 `setMyCommands` 以 `404: Not Found` 失败时,可能表示 `channels.telegram.apiRoot` 被设置为了完整的 `/bot<TOKEN>` 端点。`apiRoot` 必须只是 Bot API 根地址,而 `openclaw doctor --fix` 会移除意外追加的 `/bot<TOKEN>`。
|
||||
- `getMe returned 401` 表示 Telegram 拒绝了配置的机器人令牌。使用当前 BotFather 令牌更新 `botToken`、`tokenFile` 或 `TELEGRAM_BOT_TOKEN`;OpenClaw 会在轮询前停止,因此这不会被报告为 webhook 清理失败。
|
||||
- `setMyCommands failed` 并带有网络/抓取错误通常表示到 `api.telegram.org` 的出站 DNS/HTTPS 被阻止。
|
||||
- `setMyCommands failed` 且带有 `BOT_COMMANDS_TOO_MUCH` 表示 Telegram 菜单在裁剪后仍然溢出;请减少插件/skill/自定义命令,或禁用 `channels.telegram.commands.native`。
|
||||
- 当直接 Bot API curl 命令可用,但 `deleteWebhook`、`deleteMyCommands` 或 `setMyCommands` 失败并带有 `404: Not Found` 时,可能表示 `channels.telegram.apiRoot` 被设置成了完整的 `/bot<TOKEN>` 端点。`apiRoot` 必须只是 Bot API 根地址,并且 `openclaw doctor --fix` 会移除意外追加的 `/bot<TOKEN>`。
|
||||
- `getMe returned 401` 表示 Telegram 拒绝了配置的 bot 令牌。请用当前 BotFather 令牌更新 `botToken`、`tokenFile` 或 `TELEGRAM_BOT_TOKEN`;OpenClaw 会在轮询前停止,因此这不会被报告为 webhook 清理失败。
|
||||
- `setMyCommands failed` 且带有网络/fetch 错误,通常表示到 `api.telegram.org` 的出站 DNS/HTTPS 被阻止。
|
||||
|
||||
### 设备配对命令(`device-pair` 插件)
|
||||
|
||||
@ -387,12 +387,12 @@ curl "https://api.telegram.org/bot<bot_token>/getUpdates"
|
||||
3. `/pair pending` 列出待处理请求(包括角色/作用域)
|
||||
4. 批准请求:
|
||||
- `/pair approve <requestId>` 用于显式批准
|
||||
- 只有一个待处理请求时使用 `/pair approve`
|
||||
- `/pair approve` 用于只有一个待处理请求时
|
||||
- `/pair approve latest` 用于最近的请求
|
||||
|
||||
设置代码携带一个短期有效的 bootstrap 令牌。内置 bootstrap 交接会将主节点令牌保持在 `scopes: []`;任何被交接的 operator 令牌都限制在 `operator.approvals`、`operator.read`、`operator.talk.secrets` 和 `operator.write` 内。Bootstrap 作用域检查带有角色前缀,因此该 operator 允许列表只满足 operator 请求;非 operator 角色仍需要其自身角色前缀下的作用域。
|
||||
设置代码携带一个短期有效的引导令牌。内置引导交接会将主节点令牌保持在 `scopes: []`;任何被交接的操作员令牌都会被限制在 `operator.approvals`、`operator.read`、`operator.talk.secrets` 和 `operator.write` 内。引导作用域检查带有角色前缀,因此该操作员允许列表只满足操作员请求;非操作员角色仍需要其自身角色前缀下的作用域。
|
||||
|
||||
如果设备使用更改后的认证详细信息(例如角色/作用域/公钥)重试,先前的待处理请求会被取代,新请求会使用不同的 `requestId`。批准前请重新运行 `/pair pending`。
|
||||
如果设备使用已更改的认证详情重试(例如角色/作用域/公钥),之前的待处理请求会被取代,新请求会使用不同的 `requestId`。批准前请重新运行 `/pair pending`。
|
||||
|
||||
更多详情:[配对](/zh-CN/channels/pairing#pair-via-telegram-recommended-for-ios)。
|
||||
|
||||
@ -413,7 +413,7 @@ curl "https://api.telegram.org/bot<bot_token>/getUpdates"
|
||||
}
|
||||
```
|
||||
|
||||
按账号覆盖:
|
||||
按账户覆盖:
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -473,7 +473,7 @@ curl "https://api.telegram.org/bot<bot_token>/getUpdates"
|
||||
- `editMessage`(`chatId`、`messageId`、`content`)
|
||||
- `createForumTopic`(`chatId`、`name`、可选 `iconColor`、`iconCustomEmojiId`)
|
||||
|
||||
渠道消息操作提供符合人体工学的别名(`send`、`react`、`delete`、`edit`、`sticker`、`sticker-search`、`topic-create`)。
|
||||
渠道消息操作会暴露符合人体工程学的别名(`send`、`react`、`delete`、`edit`、`sticker`、`sticker-search`、`topic-create`)。
|
||||
|
||||
门控控制:
|
||||
|
||||
@ -482,15 +482,15 @@ curl "https://api.telegram.org/bot<bot_token>/getUpdates"
|
||||
- `channels.telegram.actions.reactions`
|
||||
- `channels.telegram.actions.sticker`(默认:禁用)
|
||||
|
||||
注意:`edit` 和 `topic-create` 当前默认启用,并且没有单独的 `channels.telegram.actions.*` 开关。
|
||||
运行时发送使用活跃的配置/密钥快照(启动/重新加载),因此操作路径不会在每次发送时执行临时 SecretRef 重新解析。
|
||||
注意:`edit` 和 `topic-create` 当前默认启用,且没有单独的 `channels.telegram.actions.*` 开关。
|
||||
运行时发送使用活动配置/密钥快照(启动/重载),因此操作路径不会在每次发送时执行临时 SecretRef 重新解析。
|
||||
|
||||
反应移除语义:[/tools/reactions](/zh-CN/tools/reactions)
|
||||
表情反应移除语义:[/tools/reactions](/zh-CN/tools/reactions)
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="回复线程标签">
|
||||
Telegram 支持在生成的输出中使用显式回复线程标签:
|
||||
Telegram 支持在生成输出中使用显式回复线程标签:
|
||||
|
||||
- `[[reply_to_current]]` 回复触发消息
|
||||
- `[[reply_to:<id>]]` 回复特定 Telegram 消息 ID
|
||||
@ -501,9 +501,9 @@ curl "https://api.telegram.org/bot<bot_token>/getUpdates"
|
||||
- `first`
|
||||
- `all`
|
||||
|
||||
当回复线程启用且原始 Telegram 文本或标题可用时,OpenClaw 会自动包含一段原生 Telegram 引用摘录。Telegram 将原生引用文本限制为 1024 个 UTF-16 代码单元,因此较长消息会从开头开始引用;如果 Telegram 拒绝该引用,则回退到普通回复。
|
||||
当启用回复线程且原始 Telegram 文本或说明文字可用时,OpenClaw 会自动包含一段原生 Telegram 引用摘录。Telegram 将原生引用文本限制为 1024 个 UTF-16 代码单元,因此更长的消息会从开头开始引用,并在 Telegram 拒绝引用时回退为普通回复。
|
||||
|
||||
注意:`off` 会禁用隐式回复线程。显式 `[[reply_to_*]]` 标签仍会被遵守。
|
||||
注意:`off` 会禁用隐式回复线程。显式 `[[reply_to_*]]` 标签仍会被遵循。
|
||||
|
||||
</Accordion>
|
||||
|
||||
@ -511,19 +511,19 @@ curl "https://api.telegram.org/bot<bot_token>/getUpdates"
|
||||
论坛超级群组:
|
||||
|
||||
- 话题会话键追加 `:topic:<threadId>`
|
||||
- 回复和输入状态面向话题线程
|
||||
- 回复和输入状态会指向话题线程
|
||||
- 话题配置路径:
|
||||
`channels.telegram.groups.<chatId>.topics.<threadId>`
|
||||
|
||||
常规话题(`threadId=1`)特殊情况:
|
||||
常规话题(`threadId=1`)特殊处理:
|
||||
|
||||
- 消息发送会省略 `message_thread_id`(Telegram 会拒绝 `sendMessage(...thread_id=1)`)
|
||||
- 输入状态操作仍包含 `message_thread_id`
|
||||
- 输入状态操作仍会包含 `message_thread_id`
|
||||
|
||||
话题继承:话题条目会继承群组设置,除非被覆盖(`requireMention`、`allowFrom`、`skills`、`systemPrompt`、`enabled`、`groupPolicy`)。
|
||||
`agentId` 仅限话题,不会从群组默认值继承。
|
||||
话题继承:除非被覆盖,否则话题条目会继承群组设置(`requireMention`、`allowFrom`、`skills`、`systemPrompt`、`enabled`、`groupPolicy`)。
|
||||
`agentId` 仅适用于话题,不会从群组默认值继承。
|
||||
|
||||
**按话题进行智能体路由**:每个话题都可以通过在话题配置中设置 `agentId` 路由到不同智能体。这让每个话题都有自己的隔离工作区、记忆和会话。示例:
|
||||
**按话题进行智能体路由**:每个话题都可以通过在话题配置中设置 `agentId` 路由到不同智能体。这会为每个话题提供自己的隔离工作区、记忆和会话。示例:
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -545,22 +545,22 @@ curl "https://api.telegram.org/bot<bot_token>/getUpdates"
|
||||
|
||||
然后每个话题都有自己的会话键:`agent:zu:telegram:group:-1001234567890:topic:3`
|
||||
|
||||
**持久 ACP 话题绑定**:论坛话题可以通过顶层 typed ACP bindings(`bindings[]`,其中 `type: "acp"`、`match.channel: "telegram"`、`peer.kind: "group"`,并使用话题限定 ID,例如 `-1001234567890:topic:42`)固定 ACP harness 会话。目前作用域限于群组/超级群组中的论坛话题。参见 [ACP 智能体](/zh-CN/tools/acp-agents)。
|
||||
**持久 ACP 话题绑定**:论坛话题可以通过顶层类型化 ACP 绑定(`bindings[]`,其中 `type: "acp"` 且 `match.channel: "telegram"`、`peer.kind: "group"`,并使用类似 `-1001234567890:topic:42` 的话题限定 ID)固定 ACP harness 会话。当前范围限定为群组/超级群组中的论坛话题。参见 [ACP 智能体](/zh-CN/tools/acp-agents)。
|
||||
|
||||
**从聊天发起线程绑定的 ACP spawn**:`/acp spawn <agent> --thread here|auto` 将当前话题绑定到新的 ACP 会话;后续消息会直接路由到那里。OpenClaw 会在话题内置顶 spawn 确认。需要 `channels.telegram.threadBindings.spawnAcpSessions=true`。
|
||||
**从聊天生成线程绑定的 ACP**:`/acp spawn <agent> --thread here|auto` 会将当前话题绑定到新的 ACP 会话;后续消息会直接路由到那里。OpenClaw 会在话题内置顶生成确认。需要 `channels.telegram.threadBindings.spawnAcpSessions=true`。
|
||||
|
||||
模板上下文公开 `MessageThreadId` 和 `IsForum`。带有 `message_thread_id` 的私信聊天会保留私信路由,但使用感知线程的会话键。
|
||||
模板上下文暴露 `MessageThreadId` 和 `IsForum`。带有 `message_thread_id` 的私信聊天会保持私信路由,但使用线程感知的会话键。
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="音频、视频和贴纸">
|
||||
### 音频消息
|
||||
|
||||
Telegram 区分语音留言和音频文件。
|
||||
Telegram 区分语音消息和音频文件。
|
||||
|
||||
- 默认:音频文件行为
|
||||
- 在智能体回复中使用标签 `[[audio_as_voice]]` 以强制发送语音留言
|
||||
- 入站语音留言转录会在智能体上下文中被框定为机器生成的非可信文本;提及检测仍使用原始转录,因此受提及门控的语音消息会继续工作。
|
||||
- 在智能体回复中使用标签 `[[audio_as_voice]]` 可强制发送语音消息
|
||||
- 入站语音消息转录会在智能体上下文中被框定为机器生成的、不受信任文本;提及检测仍使用原始转录,因此受提及门控的语音消息会继续工作。
|
||||
|
||||
消息操作示例:
|
||||
|
||||
@ -576,7 +576,7 @@ curl "https://api.telegram.org/bot<bot_token>/getUpdates"
|
||||
|
||||
### 视频消息
|
||||
|
||||
Telegram 区分视频文件和视频留言。
|
||||
Telegram 区分视频文件和视频消息。
|
||||
|
||||
消息操作示例:
|
||||
|
||||
@ -590,14 +590,14 @@ curl "https://api.telegram.org/bot<bot_token>/getUpdates"
|
||||
}
|
||||
```
|
||||
|
||||
视频留言不支持标题;提供的消息文本会单独发送。
|
||||
视频消息不支持说明文字;提供的消息文本会单独发送。
|
||||
|
||||
### 贴纸
|
||||
|
||||
入站贴纸处理:
|
||||
|
||||
- 静态 WEBP:下载并处理(占位符 `<media:sticker>`)
|
||||
- 动画 TGS:跳过
|
||||
- 动态 TGS:跳过
|
||||
- 视频 WEBM:跳过
|
||||
|
||||
贴纸上下文字段:
|
||||
@ -612,7 +612,7 @@ curl "https://api.telegram.org/bot<bot_token>/getUpdates"
|
||||
|
||||
- `~/.openclaw/telegram/sticker-cache.json`
|
||||
|
||||
贴纸会被描述一次(如果可行),并缓存以减少重复的视觉调用。
|
||||
贴纸会被描述一次(在可能时)并缓存,以减少重复视觉调用。
|
||||
|
||||
启用贴纸操作:
|
||||
|
||||
@ -639,7 +639,7 @@ curl "https://api.telegram.org/bot<bot_token>/getUpdates"
|
||||
}
|
||||
```
|
||||
|
||||
搜索缓存的贴纸:
|
||||
搜索已缓存贴纸:
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -652,10 +652,10 @@ curl "https://api.telegram.org/bot<bot_token>/getUpdates"
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="反应通知">
|
||||
Telegram 反应以 `message_reaction` 更新的形式到达(与消息载荷分开)。
|
||||
<Accordion title="表情反应通知">
|
||||
Telegram 表情反应会作为 `message_reaction` 更新到达(独立于消息载荷)。
|
||||
|
||||
启用后,OpenClaw 会将如下系统事件加入队列:
|
||||
启用后,OpenClaw 会将系统事件加入队列,例如:
|
||||
|
||||
- `Telegram reaction added: 👍 by Alice (@alice) on msg 42`
|
||||
|
||||
@ -664,37 +664,37 @@ curl "https://api.telegram.org/bot<bot_token>/getUpdates"
|
||||
- `channels.telegram.reactionNotifications`:`off | own | all`(默认:`own`)
|
||||
- `channels.telegram.reactionLevel`:`off | ack | minimal | extensive`(默认:`minimal`)
|
||||
|
||||
注意:
|
||||
注意事项:
|
||||
|
||||
- `own` 表示仅用户对机器人发送消息的回应(通过已发送消息缓存尽力而为)。
|
||||
- 回应事件仍遵守 Telegram 访问控制(`dmPolicy`、`allowFrom`、`groupPolicy`、`groupAllowFrom`);未授权发送者会被丢弃。
|
||||
- Telegram 不会在回应更新中提供 thread ID。
|
||||
- 非论坛群组会路由到群聊会话
|
||||
- 论坛群组会路由到群组常规话题会话(`:topic:1`),而不是精确的原始话题
|
||||
- `own` 表示仅用户对机器人发送消息的回应(通过已发送消息缓存尽力实现)。
|
||||
- 回应事件仍遵守 Telegram 访问控制(`dmPolicy`、`allowFrom`、`groupPolicy`、`groupAllowFrom`);未授权的发送者会被丢弃。
|
||||
- Telegram 不会在回应更新中提供帖子 ID。
|
||||
- 非论坛群组会路由到群组聊天会话
|
||||
- 论坛群组会路由到群组通用话题会话(`:topic:1`),而不是确切的来源话题
|
||||
|
||||
轮询/webhook 的 `allowed_updates` 会自动包含 `message_reaction`。
|
||||
用于轮询/webhook 的 `allowed_updates` 会自动包含 `message_reaction`。
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="确认回应">
|
||||
`ackReaction` 会在 OpenClaw 处理传入消息时发送一个确认 emoji。
|
||||
`ackReaction` 会在 OpenClaw 处理入站消息时发送一个确认表情符号。
|
||||
|
||||
解析顺序:
|
||||
|
||||
- `channels.telegram.accounts.<accountId>.ackReaction`
|
||||
- `channels.telegram.ackReaction`
|
||||
- `messages.ackReaction`
|
||||
- 智能体身份 emoji 兜底(`agents.list[].identity.emoji`,否则为 “👀”)
|
||||
- 智能体身份表情符号回退(`agents.list[].identity.emoji`,否则为 “👀”)
|
||||
|
||||
注意事项:
|
||||
|
||||
- Telegram 需要 unicode emoji(例如 “👀”)。
|
||||
- Telegram 要求使用 Unicode 表情符号(例如 “👀”)。
|
||||
- 使用 `""` 可为某个渠道或账号禁用回应。
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="来自 Telegram 事件和命令的配置写入">
|
||||
渠道配置写入默认启用(`configWrites !== false`)。
|
||||
默认启用渠道配置写入(`configWrites !== false`)。
|
||||
|
||||
Telegram 触发的写入包括:
|
||||
|
||||
@ -716,28 +716,28 @@ curl "https://api.telegram.org/bot<bot_token>/getUpdates"
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="长轮询与 webhook">
|
||||
默认是长轮询。对于 webhook 模式,设置 `channels.telegram.webhookUrl` 和 `channels.telegram.webhookSecret`;可选 `webhookPath`、`webhookHost`、`webhookPort`(默认值为 `/telegram-webhook`、`127.0.0.1`、`8787`)。
|
||||
默认使用长轮询。要使用 webhook 模式,请设置 `channels.telegram.webhookUrl` 和 `channels.telegram.webhookSecret`;可选设置 `webhookPath`、`webhookHost`、`webhookPort`(默认值为 `/telegram-webhook`、`127.0.0.1`、`8787`)。
|
||||
|
||||
本地监听器绑定到 `127.0.0.1:8787`。对于公共入口,可以在本地端口前放置反向代理,或者有意设置 `webhookHost: "0.0.0.0"`。
|
||||
本地监听器绑定到 `127.0.0.1:8787`。对于公网入口,可以在本地端口前放置反向代理,或有意设置 `webhookHost: "0.0.0.0"`。
|
||||
|
||||
Webhook 模式会在向 Telegram 返回 `200` 之前验证请求防护、Telegram secret token 和 JSON body。
|
||||
随后 OpenClaw 会通过长轮询所用的同一套按聊天/按话题机器人通道路异步处理更新,因此较慢的智能体回合不会占用 Telegram 的投递 ACK。
|
||||
webhook 模式会先验证请求保护、Telegram 密钥令牌和 JSON 正文,然后再向 Telegram 返回 `200`。
|
||||
随后 OpenClaw 会通过与长轮询相同的按聊天/按话题机器人通道异步处理该更新,因此较慢的智能体轮次不会占用 Telegram 的投递 ACK。
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="限制、重试和 CLI 目标">
|
||||
- `channels.telegram.textChunkLimit` 默认值为 4000。
|
||||
- `channels.telegram.chunkMode="newline"` 会在按长度拆分之前优先使用段落边界(空行)。
|
||||
- `channels.telegram.mediaMaxMb`(默认 100)限制传入和传出的 Telegram 媒体大小。
|
||||
- `channels.telegram.timeoutSeconds` 覆盖 Telegram API 客户端超时(如未设置,则使用 grammY 默认值)。长轮询机器人客户端会将低于 45 秒 `getUpdates` 请求防护的配置值钳制住,避免空闲轮询在 30 秒轮询窗口完成前被中止。
|
||||
- `channels.telegram.pollingStallThresholdMs` 默认值为 `120000`;仅在出现误报轮询停滞重启时,才在 `30000` 到 `600000` 之间调整。
|
||||
- `channels.telegram.chunkMode="newline"` 会先优先按段落边界(空行)切分,再按长度切分。
|
||||
- `channels.telegram.mediaMaxMb`(默认 100)会限制入站和出站 Telegram 媒体大小。
|
||||
- `channels.telegram.timeoutSeconds` 会覆盖 Telegram API 客户端超时(未设置时使用 grammY 默认值)。长轮询机器人客户端会将低于 45 秒 `getUpdates` 请求保护的配置值钳制住,确保空闲轮询不会在 30 秒轮询窗口完成前被中止。
|
||||
- `channels.telegram.pollingStallThresholdMs` 默认值为 `120000`;仅在轮询停滞重启出现误报时,才在 `30000` 到 `600000` 之间调整。
|
||||
- 群组上下文历史使用 `channels.telegram.historyLimit` 或 `messages.groupChat.historyLimit`(默认 50);`0` 表示禁用。
|
||||
- 回复/引用/转发的补充上下文目前会按收到的内容传递。
|
||||
- Telegram 允许列表主要限制谁可以触发智能体,而不是完整的补充上下文脱敏边界。
|
||||
- Telegram 允许列表主要用于限制谁可以触发智能体,而不是完整的补充上下文脱敏边界。
|
||||
- 私信历史控制:
|
||||
- `channels.telegram.dmHistoryLimit`
|
||||
- `channels.telegram.dms["<user_id>"].historyLimit`
|
||||
- `channels.telegram.retry` 配置适用于 Telegram 发送辅助工具(CLI/工具/动作)中的可恢复出站 API 错误。传入最终回复投递也会对 Telegram 预连接失败使用有界安全发送重试,但不会重试可能重复显示消息的模糊发送后网络信封。
|
||||
- `channels.telegram.retry` 配置适用于 Telegram 发送辅助函数(CLI/工具/actions)中可恢复的出站 API 错误。入站最终回复投递也会针对 Telegram 预连接失败使用有界的安全发送重试,但不会重试可能导致可见消息重复的、发送后状态不明确的网络封装。
|
||||
|
||||
CLI 发送目标可以是数字聊天 ID 或用户名:
|
||||
|
||||
@ -756,7 +756,7 @@ openclaw message poll --channel telegram --target -1001234567890:topic:42 \
|
||||
--poll-duration-seconds 300 --poll-public
|
||||
```
|
||||
|
||||
仅 Telegram 支持的投票标志:
|
||||
仅 Telegram 使用的投票标志:
|
||||
|
||||
- `--poll-duration-seconds`(5-600)
|
||||
- `--poll-anonymous`
|
||||
@ -765,34 +765,34 @@ openclaw message poll --channel telegram --target -1001234567890:topic:42 \
|
||||
|
||||
Telegram 发送还支持:
|
||||
|
||||
- 当 `channels.telegram.capabilities.inlineButtons` 允许时,使用带有 `buttons` 块的 `--presentation` 来创建内联键盘
|
||||
- 当机器人可以在该聊天中置顶时,使用 `--pin` 或 `--delivery '{"pin":true}'` 请求置顶投递
|
||||
- 使用 `--force-document` 将出站图片和 GIF 作为文档发送,而不是压缩照片或动画媒体上传
|
||||
- 当 `channels.telegram.capabilities.inlineButtons` 允许时,使用带有 `buttons` 块的 `--presentation` 创建内联键盘
|
||||
- 当机器人可在该聊天中置顶时,使用 `--pin` 或 `--delivery '{"pin":true}'` 请求置顶投递
|
||||
- 使用 `--force-document` 将出站图片和 GIF 作为文档发送,而不是作为压缩照片或动画媒体上传
|
||||
|
||||
动作门控:
|
||||
Action 门控:
|
||||
|
||||
- `channels.telegram.actions.sendMessage=false` 禁用出站 Telegram 消息,包括投票
|
||||
- `channels.telegram.actions.poll=false` 禁用 Telegram 投票创建,同时保留常规发送启用
|
||||
- `channels.telegram.actions.sendMessage=false` 会禁用出站 Telegram 消息,包括投票
|
||||
- `channels.telegram.actions.poll=false` 会禁用 Telegram 投票创建,同时保持常规发送启用
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Telegram 中的 exec 审批">
|
||||
Telegram 支持在审批者私信中进行 exec 审批,并可选择在原始聊天或话题中发布提示。审批者必须是数字 Telegram 用户 ID。
|
||||
Telegram 支持在审批人私信中进行 exec 审批,也可以选择在来源聊天或话题中发布提示。审批人必须是数字 Telegram 用户 ID。
|
||||
|
||||
配置路径:
|
||||
|
||||
- `channels.telegram.execApprovals.enabled`(至少能解析一个审批者时自动启用)
|
||||
- `channels.telegram.execApprovals.approvers`(回退到 `commands.ownerAllowFrom` 中的数字 owner ID)
|
||||
- `channels.telegram.execApprovals.target`: `dm`(默认) | `channel` | `both`
|
||||
- `channels.telegram.execApprovals.enabled`(当至少可解析一个审批人时自动启用)
|
||||
- `channels.telegram.execApprovals.approvers`(回退到来自 `commands.ownerAllowFrom` 的数字所有者 ID)
|
||||
- `channels.telegram.execApprovals.target`:`dm`(默认)| `channel` | `both`
|
||||
- `agentFilter`、`sessionFilter`
|
||||
|
||||
`channels.telegram.allowFrom`、`groupAllowFrom` 和 `defaultTo` 控制谁可以和机器人对话,以及机器人在哪里发送普通回复。它们不会让某人成为 exec 审批者。当还没有命令 owner 时,首次获批的私信配对会引导写入 `commands.ownerAllowFrom`,因此单 owner 设置仍无需在 `execApprovals.approvers` 下重复 ID 即可工作。
|
||||
`channels.telegram.allowFrom`、`groupAllowFrom` 和 `defaultTo` 控制谁可以与机器人对话,以及机器人在哪里发送普通回复。它们不会让某人成为 exec 审批人。当还不存在命令所有者时,第一个已审批的私信配对会引导生成 `commands.ownerAllowFrom`,因此单所有者设置仍可正常工作,无需在 `execApprovals.approvers` 下重复填写 ID。
|
||||
|
||||
渠道投递会在聊天中显示命令文本;仅在受信任的群组/话题中启用 `channel` 或 `both`。当提示落在论坛话题中时,OpenClaw 会为审批提示和后续消息保留该话题。Exec 审批默认会在 30 分钟后过期。
|
||||
渠道投递会在聊天中显示命令文本;仅在受信任的群组/话题中启用 `channel` 或 `both`。当提示落入论坛话题时,OpenClaw 会为审批提示和后续消息保留该话题。exec 审批默认在 30 分钟后过期。
|
||||
|
||||
内联审批按钮还要求 `channels.telegram.capabilities.inlineButtons` 允许目标表面(`dm`、`group` 或 `all`)。带有 `plugin:` 前缀的审批 ID 会通过插件审批解析;其他 ID 会先通过 exec 审批解析。
|
||||
|
||||
参见 [Exec 审批](/zh-CN/tools/exec-approvals)。
|
||||
请参阅 [exec 审批](/zh-CN/tools/exec-approvals)。
|
||||
|
||||
</Accordion>
|
||||
</AccordionGroup>
|
||||
@ -801,10 +801,10 @@ openclaw message poll --channel telegram --target -1001234567890:topic:42 \
|
||||
|
||||
当智能体遇到投递或提供商错误时,Telegram 可以回复错误文本,也可以将其抑制。两个配置键控制此行为:
|
||||
|
||||
| 键 | 值 | 默认值 | 描述 |
|
||||
| ----------------------------------- | ----------------- | ------- | ------------------------------------------------------------------------------------------- |
|
||||
| `channels.telegram.errorPolicy` | `reply`, `silent` | `reply` | `reply` 会向聊天发送友好的错误消息。`silent` 会完全抑制错误回复。 |
|
||||
| `channels.telegram.errorCooldownMs` | 数字(毫秒) | `60000` | 向同一聊天发送错误回复之间的最小间隔。防止故障期间出现错误刷屏。 |
|
||||
| 键 | 值 | 默认值 | 描述 |
|
||||
| ----------------------------------- | ----------------- | ------- | -------------------------------------------------------------------------------------------- |
|
||||
| `channels.telegram.errorPolicy` | `reply`, `silent` | `reply` | `reply` 会向聊天发送友好的错误消息。`silent` 会完全抑制错误回复。 |
|
||||
| `channels.telegram.errorCooldownMs` | 数字(毫秒) | `60000` | 同一聊天两次错误回复之间的最短时间。防止中断期间出现错误刷屏。 |
|
||||
|
||||
支持按账号、按群组和按话题覆盖(继承方式与其他 Telegram 配置键相同)。
|
||||
|
||||
@ -827,13 +827,13 @@ openclaw message poll --channel telegram --target -1001234567890:topic:42 \
|
||||
## 故障排除
|
||||
|
||||
<AccordionGroup>
|
||||
<Accordion title="机器人不响应非提及的群组消息">
|
||||
<Accordion title="机器人不响应群组中的非提及消息">
|
||||
|
||||
- 如果 `requireMention=false`,Telegram 隐私模式必须允许完整可见性。
|
||||
- BotFather:`/setprivacy` -> Disable
|
||||
- 然后将机器人从群组移除并重新添加
|
||||
- BotFather:`/setprivacy` -> 禁用
|
||||
- 然后将机器人从群组中移除并重新添加
|
||||
- 当配置期望未提及的群组消息时,`openclaw channels status` 会发出警告。
|
||||
- `openclaw channels status --probe` 可以检查显式数字群组 ID;通配符 `"*"` 无法进行成员探测。
|
||||
- `openclaw channels status --probe` 可以检查显式数字群组 ID;通配符 `"*"` 无法探测成员资格。
|
||||
- 快速会话测试:`/activation always`。
|
||||
|
||||
</Accordion>
|
||||
@ -841,40 +841,40 @@ openclaw message poll --channel telegram --target -1001234567890:topic:42 \
|
||||
<Accordion title="机器人完全看不到群组消息">
|
||||
|
||||
- 当 `channels.telegram.groups` 存在时,群组必须被列出(或包含 `"*"`)
|
||||
- 验证机器人的群组成员身份
|
||||
- 验证机器人在群组中的成员资格
|
||||
- 查看日志:`openclaw logs --follow` 以了解跳过原因
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="命令只能部分工作或完全不工作">
|
||||
<Accordion title="命令部分可用或完全不可用">
|
||||
|
||||
- 授权你的发送者身份(配对和/或数字 `allowFrom`)
|
||||
- 即使群组策略是 `open`,命令授权仍然适用
|
||||
- `setMyCommands failed` 且伴随 `BOT_COMMANDS_TOO_MUCH` 表示原生命令菜单条目过多;减少插件/skill/自定义命令,或禁用原生菜单
|
||||
- 启动时的 `deleteMyCommands` / `setMyCommands` 调用有边界,并会在请求超时时通过 Telegram 的传输回退重试一次。持续的网络/抓取错误通常表示到 `api.telegram.org` 的 DNS/HTTPS 可达性存在问题
|
||||
- 即使群组策略为 `open`,命令授权仍然适用
|
||||
- `setMyCommands failed` 和 `BOT_COMMANDS_TOO_MUCH` 表示原生命令菜单条目过多;请减少插件/技能/自定义命令,或禁用原生命令菜单
|
||||
- 启动时的 `deleteMyCommands` / `setMyCommands` 调用是有界的,并会在请求超时时通过 Telegram 的传输回退重试一次。持续的网络/fetch 错误通常表示到 `api.telegram.org` 的 DNS/HTTPS 可达性存在问题
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="启动报告未授权 token">
|
||||
<Accordion title="启动报告未授权令牌">
|
||||
|
||||
- `getMe returned 401` 是配置的机器人 token 出现 Telegram 认证失败。
|
||||
- 在 BotFather 中重新复制或重新生成机器人 token,然后更新默认账号的 `channels.telegram.botToken`、`channels.telegram.tokenFile`、`channels.telegram.accounts.<id>.botToken` 或 `TELEGRAM_BOT_TOKEN`。
|
||||
- 启动期间的 `deleteWebhook 401 Unauthorized` 也是认证失败;将其视为 “不存在 webhook” 只会把同一个错误 token 失败延后到后续 API 调用。
|
||||
- 如果 `deleteWebhook` 在轮询启动期间因瞬时网络错误失败,OpenClaw 会检查 `getWebhookInfo`;当 Telegram 报告空 webhook URL 时,轮询会继续,因为清理已满足。
|
||||
- `getMe returned 401` 是配置的机器人令牌导致的 Telegram 身份验证失败。
|
||||
- 在 BotFather 中重新复制或重新生成机器人令牌,然后为默认账号更新 `channels.telegram.botToken`、`channels.telegram.tokenFile`、`channels.telegram.accounts.<id>.botToken` 或 `TELEGRAM_BOT_TOKEN`。
|
||||
- 启动期间的 `deleteWebhook 401 Unauthorized` 也是身份验证失败;将其视为 “不存在 webhook” 只会把同一个错误令牌失败推迟到后续 API 调用。
|
||||
- 如果轮询启动期间 `deleteWebhook` 因暂时性网络错误失败,OpenClaw 会检查 `getWebhookInfo`;当 Telegram 报告 webhook URL 为空时,轮询会继续,因为清理已满足条件。
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="轮询或网络不稳定">
|
||||
|
||||
- Node 22+ + 自定义 fetch/proxy 可能会在 AbortSignal 类型不匹配时触发立即中止行为。
|
||||
- 一些主机会先将 `api.telegram.org` 解析到 IPv6;损坏的 IPv6 出站可能导致间歇性的 Telegram API 故障。
|
||||
- 如果日志包含 `TypeError: fetch failed` 或 `Network request for 'getUpdates' failed!`,OpenClaw 现在会将这些作为可恢复的网络错误重试。
|
||||
- 如果 Telegram 套接字以较短的固定节奏回收,请检查是否存在较低的 `channels.telegram.timeoutSeconds`;长轮询 bot 客户端会将配置值限制在 `getUpdates` 请求保护值以下,但较旧版本在该值低于长轮询超时时,可能会在每次轮询时中止。
|
||||
- 如果日志包含 `Polling stall detected`,默认情况下,OpenClaw 会在 120 秒内没有完成的长轮询存活信号后重启轮询并重建 Telegram 传输。
|
||||
- 当正在运行的轮询账号在启动宽限期后尚未完成 `getUpdates`、正在运行的 webhook 账号在启动宽限期后尚未完成 `setWebhook`,或上一次成功的轮询传输活动已过期时,`openclaw channels status --probe` 和 `openclaw doctor` 会发出警告。
|
||||
- 只有在长时间运行的 `getUpdates` 调用健康,但你的主机仍报告误报的轮询停滞重启时,才增加 `channels.telegram.pollingStallThresholdMs`。持续停滞通常指向主机与 `api.telegram.org` 之间的 proxy、DNS、IPv6 或 TLS 出站问题。
|
||||
- Telegram 的 Bot API 传输也遵循进程 proxy 环境变量,包括 `HTTP_PROXY`、`HTTPS_PROXY`、`ALL_PROXY` 及其小写变体。`NO_PROXY` / `no_proxy` 仍可绕过 `api.telegram.org`。
|
||||
- 如果在服务环境中通过 `OPENCLAW_PROXY_URL` 配置了 OpenClaw 托管 proxy,且没有标准 proxy 环境变量,Telegram 也会将该 URL 用于 Bot API 传输。
|
||||
- Node 22+ 加上自定义 fetch/代理时,如果 AbortSignal 类型不匹配,可能会触发立即中止行为。
|
||||
- 某些主机会优先将 `api.telegram.org` 解析为 IPv6;损坏的 IPv6 出站连接可能导致间歇性 Telegram API 失败。
|
||||
- 如果日志包含 `TypeError: fetch failed` 或 `Network request for 'getUpdates' failed!`,OpenClaw 现在会将它们作为可恢复的网络错误进行重试。
|
||||
- 如果 Telegram 套接字以较短的固定周期回收,请检查 `channels.telegram.timeoutSeconds` 是否过低;长轮询 bot 客户端会将低于 `getUpdates` 请求保护值的配置值钳制住,但旧版本在该值低于长轮询超时时,可能会在每次轮询时中止。
|
||||
- 如果日志包含 `Polling stall detected`,默认情况下,OpenClaw 会在 120 秒内没有完成的长轮询存活性后重启轮询并重建 Telegram 传输层。
|
||||
- 当正在运行的轮询账号在启动宽限期后仍未完成 `getUpdates`、正在运行的 webhook 账号在启动宽限期后仍未完成 `setWebhook`,或最近一次成功的轮询传输活动已经过期时,`openclaw channels status --probe` 和 `openclaw doctor` 会发出警告。
|
||||
- 仅当长时间运行的 `getUpdates` 调用健康,但你的主机仍报告误报的轮询停滞重启时,才提高 `channels.telegram.pollingStallThresholdMs`。持续停滞通常指向主机与 `api.telegram.org` 之间的代理、DNS、IPv6 或 TLS 出站问题。
|
||||
- Telegram 也会为 Bot API 传输遵循进程代理环境,包括 `HTTP_PROXY`、`HTTPS_PROXY`、`ALL_PROXY` 及其小写变体。`NO_PROXY` / `no_proxy` 仍可绕过 `api.telegram.org`。
|
||||
- 如果在服务环境中通过 `OPENCLAW_PROXY_URL` 配置了 OpenClaw 托管代理,且不存在标准代理环境变量,Telegram 也会将该 URL 用于 Bot API 传输。
|
||||
- 在直接出站/TLS 不稳定的 VPS 主机上,通过 `channels.telegram.proxy` 路由 Telegram API 调用:
|
||||
|
||||
```yaml
|
||||
@ -883,7 +883,7 @@ channels:
|
||||
proxy: socks5://<user>:<password>@proxy-host:1080
|
||||
```
|
||||
|
||||
- Node 22+ 默认使用 `autoSelectFamily=true`(WSL2 除外)和 `dnsResultOrder=ipv4first`。
|
||||
- Node 22+ 默认使用 `autoSelectFamily=true`(WSL2 除外)。Telegram DNS 结果顺序依次遵循 `OPENCLAW_TELEGRAM_DNS_RESULT_ORDER`、`channels.telegram.network.dnsResultOrder`,然后是进程默认值,例如 `NODE_OPTIONS=--dns-result-order=ipv4first`;如果都不适用,Node 22+ 会回退到 `ipv4first`。
|
||||
- 如果你的主机是 WSL2,或明确更适合仅 IPv4 行为,请强制选择地址族:
|
||||
|
||||
```yaml
|
||||
@ -893,7 +893,7 @@ channels:
|
||||
autoSelectFamily: false
|
||||
```
|
||||
|
||||
- 默认已允许 Telegram 媒体下载使用 RFC 2544 基准范围答案(`198.18.0.0/15`)。如果可信的 fake-IP 或透明 proxy 在媒体下载期间将 `api.telegram.org` 重写为其他私有/内部/特殊用途地址,你可以选择启用仅限 Telegram 的绕过:
|
||||
- 默认已允许 Telegram 媒体下载使用 RFC 2544 基准范围答案(`198.18.0.0/15`)。如果受信任的 fake-IP 或透明代理在媒体下载期间将 `api.telegram.org` 重写为其他私有/内部/特殊用途地址,你可以选择启用仅限 Telegram 的绕过:
|
||||
|
||||
```yaml
|
||||
channels:
|
||||
@ -902,15 +902,13 @@ channels:
|
||||
dangerouslyAllowPrivateNetwork: true
|
||||
```
|
||||
|
||||
- 同一选择也可按账号在 `channels.telegram.accounts.<accountId>.network.dangerouslyAllowPrivateNetwork` 启用。
|
||||
- 如果你的 proxy 将 Telegram 媒体主机解析到 `198.18.x.x`,请先关闭危险标志。Telegram 媒体默认已经允许 RFC 2544 基准范围。
|
||||
- 同一选择启用项也可按账号设置在
|
||||
`channels.telegram.accounts.<accountId>.network.dangerouslyAllowPrivateNetwork`。
|
||||
- 如果你的代理将 Telegram 媒体主机解析为 `198.18.x.x`,请先保持危险标志关闭。Telegram 媒体默认已允许 RFC 2544 基准范围。
|
||||
|
||||
<Warning>
|
||||
`channels.telegram.network.dangerouslyAllowPrivateNetwork` 会削弱 Telegram
|
||||
媒体 SSRF 防护。仅在可信的操作员控制 proxy
|
||||
环境中使用它,例如 Clash、Mihomo 或 Surge fake-IP 路由,当它们
|
||||
合成 RFC 2544 基准范围之外的私有或特殊用途答案时。
|
||||
正常公共互联网 Telegram 访问请保持关闭。
|
||||
媒体 SSRF 防护。仅在受信任、由操作员控制的代理环境中使用它,例如 Clash、Mihomo 或 Surge fake-IP 路由,且它们会合成 RFC 2544 基准范围之外的私有或特殊用途答案。普通公网 Telegram 访问请保持关闭。
|
||||
</Warning>
|
||||
|
||||
- 环境覆盖(临时):
|
||||
@ -933,48 +931,48 @@ dig +short api.telegram.org AAAA
|
||||
|
||||
主要参考:[配置参考 - Telegram](/zh-CN/gateway/config-channels#telegram)。
|
||||
|
||||
<Accordion title="High-signal Telegram fields">
|
||||
<Accordion title="高信号 Telegram 字段">
|
||||
|
||||
- 启动/auth:`enabled`、`botToken`、`tokenFile`、`accounts.*`(`tokenFile` 必须指向普通文件;符号链接会被拒绝)
|
||||
- 启动/凭证:`enabled`、`botToken`、`tokenFile`、`accounts.*`(`tokenFile` 必须指向常规文件;符号链接会被拒绝)
|
||||
- 访问控制:`dmPolicy`、`allowFrom`、`groupPolicy`、`groupAllowFrom`、`groups`、`groups.*.topics.*`、顶层 `bindings[]`(`type: "acp"`)
|
||||
- exec 审批:`execApprovals`、`accounts.*.execApprovals`
|
||||
- 命令/menu:`commands.native`、`commands.nativeSkills`、`customCommands`
|
||||
- 线程/replies:`replyToMode`
|
||||
- 执行审批:`execApprovals`、`accounts.*.execApprovals`
|
||||
- 命令/菜单:`commands.native`、`commands.nativeSkills`、`customCommands`
|
||||
- 线程/回复:`replyToMode`
|
||||
- 流式传输:`streaming`(预览)、`streaming.preview.toolProgress`、`blockStreaming`
|
||||
- 格式/投递:`textChunkLimit`、`chunkMode`、`linkPreview`、`responsePrefix`
|
||||
- 格式化/投递:`textChunkLimit`、`chunkMode`、`linkPreview`、`responsePrefix`
|
||||
- 媒体/网络:`mediaMaxMb`、`timeoutSeconds`、`pollingStallThresholdMs`、`retry`、`network.autoSelectFamily`、`network.dangerouslyAllowPrivateNetwork`、`proxy`
|
||||
- 自定义 API 根:`apiRoot`(仅 Bot API 根;不要包含 `/bot<TOKEN>`)
|
||||
- webhook:`webhookUrl`、`webhookSecret`、`webhookPath`、`webhookHost`
|
||||
- 操作/能力:`capabilities.inlineButtons`、`actions.sendMessage|editMessage|deleteMessage|reactions|sticker`
|
||||
- reactions:`reactionNotifications`、`reactionLevel`
|
||||
- 表情回应:`reactionNotifications`、`reactionLevel`
|
||||
- 错误:`errorPolicy`、`errorCooldownMs`
|
||||
- 写入/history:`configWrites`、`historyLimit`、`dmHistoryLimit`、`dms.*.historyLimit`
|
||||
- 写入/历史:`configWrites`、`historyLimit`、`dmHistoryLimit`、`dms.*.historyLimit`
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Note>
|
||||
多账号优先级:配置两个或更多账号 ID 时,请设置 `channels.telegram.defaultAccount`(或包含 `channels.telegram.accounts.default`),以明确默认路由。否则,OpenClaw 会回退到第一个规范化账号 ID,并且 `openclaw doctor` 会发出警告。命名账号会继承 `channels.telegram.allowFrom` / `groupAllowFrom`,但不会继承 `accounts.default.*` 值。
|
||||
多账号优先级:配置两个或更多账号 ID 时,设置 `channels.telegram.defaultAccount`(或包含 `channels.telegram.accounts.default`)以明确默认路由。否则 OpenClaw 会回退到第一个规范化账号 ID,且 `openclaw doctor` 会发出警告。命名账号会继承 `channels.telegram.allowFrom` / `groupAllowFrom`,但不会继承 `accounts.default.*` 值。
|
||||
</Note>
|
||||
|
||||
## 相关内容
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="Pairing" icon="link" href="/zh-CN/channels/pairing">
|
||||
将 Telegram 用户配对到 Gateway 网关。
|
||||
<Card title="配对" icon="link" href="/zh-CN/channels/pairing">
|
||||
将 Telegram 用户与 Gateway 网关配对。
|
||||
</Card>
|
||||
<Card title="Groups" icon="users" href="/zh-CN/channels/groups">
|
||||
群组和 topic allowlist 行为。
|
||||
<Card title="群组" icon="users" href="/zh-CN/channels/groups">
|
||||
群组和话题允许列表行为。
|
||||
</Card>
|
||||
<Card title="Channel routing" icon="route" href="/zh-CN/channels/channel-routing">
|
||||
<Card title="渠道路由" icon="route" href="/zh-CN/channels/channel-routing">
|
||||
将入站消息路由到智能体。
|
||||
</Card>
|
||||
<Card title="Security" icon="shield" href="/zh-CN/gateway/security">
|
||||
<Card title="安全" icon="shield" href="/zh-CN/gateway/security">
|
||||
威胁模型和加固。
|
||||
</Card>
|
||||
<Card title="Multi-agent routing" icon="sitemap" href="/zh-CN/concepts/multi-agent">
|
||||
将群组和 topic 映射到智能体。
|
||||
<Card title="多智能体路由" icon="sitemap" href="/zh-CN/concepts/multi-agent">
|
||||
将群组和话题映射到智能体。
|
||||
</Card>
|
||||
<Card title="Troubleshooting" icon="wrench" href="/zh-CN/channels/troubleshooting">
|
||||
<Card title="故障排除" icon="wrench" href="/zh-CN/channels/troubleshooting">
|
||||
跨渠道诊断。
|
||||
</Card>
|
||||
</CardGroup>
|
||||
|
||||
377
docs/zh-CN/ci.md
377
docs/zh-CN/ci.md
@ -1,93 +1,93 @@
|
||||
---
|
||||
read_when:
|
||||
- 你需要了解 CI 作业为什么运行或没有运行
|
||||
- 你需要了解某个 CI 作业为何运行或未运行
|
||||
- 你正在调试一个失败的 GitHub Actions 检查
|
||||
- 你正在协调一次发布验证运行或重新运行
|
||||
- 你正在协调一次发布验证的运行或重新运行
|
||||
- 你正在更改 ClawSweeper 调度或 GitHub 活动转发
|
||||
summary: CI 作业图、范围门控、发布总括流程和本地等效命令
|
||||
summary: CI 作业图、范围门禁、发布总括流程和本地命令等价项
|
||||
title: CI 流水线
|
||||
x-i18n:
|
||||
generated_at: "2026-05-02T01:24:20Z"
|
||||
generated_at: "2026-05-02T04:47:43Z"
|
||||
model: gpt-5.5
|
||||
provider: openai
|
||||
source_hash: d7312e6367d24a5f61546fa84c3a281124d463821332ae11ac7bbbbab83cb8d4
|
||||
source_hash: a2da3014e67b8d2d4bb4c1c9d4c6134eed29309bb176544864df568809ae3ac7
|
||||
source_path: ci.md
|
||||
workflow: 16
|
||||
---
|
||||
|
||||
OpenClaw CI 会在每次推送到 `main` 以及每个拉取请求上运行。`preflight` 作业会对差异进行分类,并在仅有无关区域变更时关闭高成本通道。手动 `workflow_dispatch` 运行会有意绕过智能范围限定,并为候选发布和广泛验证展开完整图。Android 通道通过 `include_android` 保持可选启用。仅发布用的插件覆盖位于单独的 [`插件预发布`](#plugin-prerelease) 工作流中,并且只会从 [`完整发布验证`](#full-release-validation) 或显式手动调度运行。
|
||||
OpenClaw CI 会在每次推送到 `main` 以及每个拉取请求时运行。`preflight` 作业会对 diff 进行分类,并在仅有无关区域发生变更时关闭高成本的执行分支。手动 `workflow_dispatch` 运行会有意绕过智能范围限定,并为发布候选版本和广泛验证展开完整图。Android 分支通过 `include_android` 保持可选。仅发布使用的插件覆盖位于单独的 [`Plugin Prerelease`](#plugin-prerelease) 工作流中,并且只会从 [`Full Release Validation`](#full-release-validation) 或显式手动调度运行。
|
||||
|
||||
## 流水线概览
|
||||
|
||||
| 作业 | 目的 | 运行时机 |
|
||||
| 作业 | 用途 | 运行时机 |
|
||||
| -------------------------------- | -------------------------------------------------------------------------------------------- | ---------------------------------- |
|
||||
| `preflight` | 检测仅文档变更、变更范围、变更的插件,并构建 CI 清单 | 始终在非草稿推送和 PR 上运行 |
|
||||
| `security-scm-fast` | 通过 `zizmor` 进行私钥检测和工作流审计 | 始终在非草稿推送和 PR 上运行 |
|
||||
| `security-dependency-audit` | 针对 npm 公告执行无依赖的生产 lockfile 审计 | 始终在非草稿推送和 PR 上运行 |
|
||||
| `security-fast` | 快速安全作业的必需聚合项 | 始终在非草稿推送和 PR 上运行 |
|
||||
| `check-dependencies` | 仅生产 Knip 依赖检查,以及未使用文件 allowlist 守卫 | Node 相关变更 |
|
||||
| `build-artifacts` | 构建 `dist/`、Control UI、构建产物检查,以及可复用的下游产物 | Node 相关变更 |
|
||||
| `checks-fast-core` | 快速 Linux 正确性通道,例如内置/插件契约/协议检查 | Node 相关变更 |
|
||||
| `checks-fast-contracts-channels` | 分片的渠道契约检查,并提供稳定的聚合检查结果 | Node 相关变更 |
|
||||
| `checks-node-core-test` | 核心 Node 测试分片,排除渠道、内置、契约和插件通道 | Node 相关变更 |
|
||||
| `check` | 分片的主本地门禁等价项:生产类型、lint、守卫、测试类型和严格 smoke | Node 相关变更 |
|
||||
| `check-additional` | 架构、边界、插件表面守卫、包边界和 gateway-watch 分片 | Node 相关变更 |
|
||||
| `build-smoke` | 已构建 CLI smoke 测试和启动内存 smoke | Node 相关变更 |
|
||||
| `checks` | 已构建产物渠道测试的验证器 | Node 相关变更 |
|
||||
| `checks-node-compat-node22` | Node 22 兼容性构建和 smoke 通道 | 发布用手动 CI 调度 |
|
||||
| `check-docs` | 文档格式、lint 和坏链检查 | 文档已变更 |
|
||||
| `skills-python` | 面向 Python 支撑的 Skills 执行 Ruff + pytest | Python Skills 相关变更 |
|
||||
| `checks-windows` | Windows 专用进程/路径测试,以及共享运行时导入说明符回归检查 | Windows 相关变更 |
|
||||
| `macos-node` | 使用共享构建产物的 macOS TypeScript 测试通道 | macOS 相关变更 |
|
||||
| `macos-swift` | macOS 应用的 Swift lint、构建和测试 | macOS 相关变更 |
|
||||
| `android` | 两个 flavor 的 Android 单元测试,以及一次 debug APK 构建 | Android 相关变更 |
|
||||
| `test-performance-agent` | 可信活动之后的每日 Codex 慢测试优化 | 主 CI 成功或手动调度 |
|
||||
| `preflight` | 检测仅文档变更、变更范围、变更插件,并构建 CI 清单 | 始终在非草稿推送和 PR 上运行 |
|
||||
| `security-scm-fast` | 通过 `zizmor` 进行私钥检测和工作流审计 | 始终在非草稿推送和 PR 上运行 |
|
||||
| `security-dependency-audit` | 针对 npm advisories 进行不依赖外部依赖的生产 lockfile 审计 | 始终在非草稿推送和 PR 上运行 |
|
||||
| `security-fast` | 快速安全作业的必需聚合 | 始终在非草稿推送和 PR 上运行 |
|
||||
| `check-dependencies` | 生产 Knip 仅依赖检查,以及未使用文件 allowlist 防护 | Node 相关变更 |
|
||||
| `build-artifacts` | 构建 `dist/`、Control UI、构建产物检查,以及可复用的下游产物 | Node 相关变更 |
|
||||
| `checks-fast-core` | 快速 Linux 正确性分支,例如内置插件、插件合约和协议检查 | Node 相关变更 |
|
||||
| `checks-fast-contracts-channels` | 分片的渠道合约检查,并提供稳定的聚合检查结果 | Node 相关变更 |
|
||||
| `checks-node-core-test` | 核心 Node 测试分片,不包括渠道、内置插件、合约和插件分支 | Node 相关变更 |
|
||||
| `check` | 分片的主本地门禁等价项:生产类型、lint、防护、测试类型和严格 smoke | Node 相关变更 |
|
||||
| `check-additional` | 架构、边界、插件表面防护、包边界和 gateway-watch 分片 | Node 相关变更 |
|
||||
| `build-smoke` | 构建后的 CLI smoke 测试和启动内存 smoke | Node 相关变更 |
|
||||
| `checks` | 构建产物渠道测试的验证器 | Node 相关变更 |
|
||||
| `checks-node-compat-node22` | Node 22 兼容性构建和 smoke 分支 | 发布用手动 CI 调度 |
|
||||
| `check-docs` | 文档格式化、lint 和断链检查 | 文档变更 |
|
||||
| `skills-python` | 面向 Python 支持的 Skills 的 Ruff + pytest | Python Skill 相关变更 |
|
||||
| `checks-windows` | Windows 特定的进程/路径测试,以及共享运行时导入说明符回归检查 | Windows 相关变更 |
|
||||
| `macos-node` | 使用共享构建产物的 macOS TypeScript 测试分支 | macOS 相关变更 |
|
||||
| `macos-swift` | macOS 应用的 Swift lint、构建和测试 | macOS 相关变更 |
|
||||
| `android` | 两种 flavor 的 Android 单元测试,以及一次 debug APK 构建 | Android 相关变更 |
|
||||
| `test-performance-agent` | 可信活动之后的每日 Codex 慢测试优化 | Main CI 成功或手动调度 |
|
||||
|
||||
## 快速失败顺序
|
||||
|
||||
1. `preflight` 决定哪些通道实际存在。`docs-scope` 和 `changed-scope` 逻辑是此作业中的步骤,不是独立作业。
|
||||
2. `security-scm-fast`、`security-dependency-audit`、`security-fast`、`check`、`check-additional`、`check-docs` 和 `skills-python` 会快速失败,而不会等待更重的产物和平台矩阵作业。
|
||||
3. `build-artifacts` 会与快速 Linux 通道重叠运行,这样下游消费者可以在共享构建就绪后立即开始。
|
||||
4. 更重的平台和运行时通道随后展开:`checks-fast-core`、`checks-fast-contracts-channels`、`checks-node-core-test`、`checks`、`checks-windows`、`macos-node`、`macos-swift` 和 `android`。
|
||||
1. `preflight` 决定哪些分支会实际存在。`docs-scope` 和 `changed-scope` 逻辑是此作业中的步骤,不是独立作业。
|
||||
2. `security-scm-fast`、`security-dependency-audit`、`security-fast`、`check`、`check-additional`、`check-docs` 和 `skills-python` 会快速失败,而不等待更重的产物和平台矩阵作业。
|
||||
3. `build-artifacts` 会与快速 Linux 分支重叠运行,因此下游使用方可在共享构建准备就绪后立即开始。
|
||||
4. 更重的平台和运行时分支随后展开:`checks-fast-core`、`checks-fast-contracts-channels`、`checks-node-core-test`、`checks`、`checks-windows`、`macos-node`、`macos-swift` 和 `android`。
|
||||
|
||||
当同一 PR 或 `main` 引用上有更新的推送落地时,GitHub 可能会将被取代的作业标记为 `cancelled`。除非同一引用的最新运行也在失败,否则将其视为 CI 噪声。聚合分片检查使用 `!cancelled() && always()`,因此它们仍会报告正常的分片失败,但不会在整个工作流已被取代后继续排队。自动 CI 并发键带版本号(`CI-v7-*`),这样 GitHub 端旧队列组中的僵尸项无法无限期阻塞较新的 main 运行。手动完整套件运行使用 `CI-manual-v1-*`,并且不会取消正在运行的任务。
|
||||
当同一 PR 或 `main` ref 上有更新推送落地时,GitHub 可能会将被取代的作业标记为 `cancelled`。除非同一 ref 的最新运行也失败,否则应将其视为 CI 噪声。聚合分片检查使用 `!cancelled() && always()`,因此它们仍会报告正常的分片失败,但不会在整个工作流已经被取代后继续排队。自动 CI 并发键带有版本号(`CI-v7-*`),因此 GitHub 端旧队列组中的僵尸项无法无限期阻塞较新的 main 运行。手动全套件运行使用 `CI-manual-v1-*`,并且不会取消进行中的运行。
|
||||
|
||||
## 范围和路由
|
||||
## 范围与路由
|
||||
|
||||
范围逻辑位于 `scripts/ci-changed-scope.mjs`,并由 `src/scripts/ci-changed-scope.test.ts` 中的单元测试覆盖。手动调度会跳过变更范围检测,并让 preflight 清单表现得像每个已限定范围的区域都发生了变更。
|
||||
范围逻辑位于 `scripts/ci-changed-scope.mjs`,并由 `src/scripts/ci-changed-scope.test.ts` 中的单元测试覆盖。手动调度会跳过变更范围检测,并让 preflight 清单表现得像每个限定区域都发生了变更。
|
||||
|
||||
- **CI 工作流编辑**会验证 Node CI 图和工作流 lint,但其本身不会强制触发 Windows、Android 或 macOS 原生构建;这些平台通道仍限定为平台源代码变更。
|
||||
- **仅 CI 路由编辑、选定的低成本核心测试 fixture 编辑,以及窄范围插件契约 helper/测试路由编辑**使用快速的仅 Node 清单路径:`preflight`、安全检查,以及单个 `checks-fast-core` 任务。当变更仅限于该快速任务直接覆盖的路由或 helper 表面时,该路径会跳过构建产物、Node 22 兼容性、渠道契约、完整核心分片、内置插件分片和额外守卫矩阵。
|
||||
- **Windows Node 检查**限定到 Windows 专用进程/路径包装器、npm/pnpm/UI runner helper、包管理器配置,以及执行该通道的 CI 工作流表面;无关源代码、插件、安装 smoke 和仅测试变更仍留在 Linux Node 通道上。
|
||||
- **CI 工作流编辑**会验证 Node CI 图和工作流 lint,但本身不会强制触发 Windows、Android 或 macOS 原生构建;这些平台分支仍限定在平台源代码变更范围内。
|
||||
- **仅 CI 路由编辑、选定的低成本核心测试 fixture 编辑,以及窄范围插件合约 helper/test-routing 编辑**使用快速 Node-only 清单路径:`preflight`、安全检查,以及单个 `checks-fast-core` 任务。当变更仅限于该快速任务直接覆盖的路由或 helper 表面时,此路径会跳过构建产物、Node 22 兼容性、渠道合约、完整核心分片、内置插件分片和额外防护矩阵。
|
||||
- **Windows Node 检查**限定在 Windows 特定的进程/路径包装器、npm/pnpm/UI runner helper、包管理器配置,以及执行该分支的 CI 工作流表面;无关源代码、插件、安装 smoke 和仅测试变更仍保留在 Linux Node 分支上。
|
||||
|
||||
最慢的 Node 测试族会被拆分或均衡,以便每个作业保持较小规模且不过度预留 runner:渠道契约以三个加权分片运行,小型核心单元通道会配对,auto-reply 以四个均衡 worker 运行(reply 子树拆为 agent-runner、dispatch 和 commands/state-routing 分片),agentic gateway/plugin 配置会分布到现有仅源码 agentic Node 作业中,而不是等待构建产物。广泛的浏览器、QA、媒体和杂项插件测试使用各自专用的 Vitest 配置,而不是共享插件 catch-all。include-pattern 分片使用 CI 分片名称记录计时条目,因此 `.artifacts/vitest-shard-timings.json` 可以区分整个配置和过滤后的分片。`check-additional` 将 package-boundary compile/canary 工作放在一起,并将运行时拓扑架构与 gateway watch 覆盖分开;边界守卫分片会在一个作业内并发运行其小型独立守卫。Gateway watch、渠道测试和核心支持边界分片会在 `dist/` 和 `dist-runtime/` 已构建后,在 `build-artifacts` 内并发运行。
|
||||
最慢的 Node 测试族会被拆分或平衡,使每个作业保持较小规模而不超额预留 runner:渠道合约作为三个加权分片运行,小型核心单元分支会配对,auto-reply 作为四个平衡 worker 运行(reply 子树拆分为 agent-runner、dispatch 和 commands/state-routing 分片),agentic gateway/plugin 配置分散到现有的仅源代码 agentic Node 作业中,而不是等待构建产物。广泛的浏览器、QA、媒体和其他杂项插件测试使用各自专用的 Vitest 配置,而不是共享的插件 catch-all。include-pattern 分片会使用 CI 分片名称记录计时条目,因此 `.artifacts/vitest-shard-timings.json` 可以区分完整配置和过滤后的分片。`check-additional` 将包边界编译/canary 工作放在一起,并将运行时拓扑架构与 gateway watch 覆盖分开;边界防护分片会在一个作业内并发运行其小型独立防护。Gateway watch、渠道测试和核心支持边界分片会在 `dist/` 与 `dist-runtime/` 已经构建完成后,于 `build-artifacts` 内并发运行。
|
||||
|
||||
Android CI 会同时运行 `testPlayDebugUnitTest` 和 `testThirdPartyDebugUnitTest`,然后构建 Play debug APK。第三方 flavor 没有单独的 source set 或 manifest;它的单元测试通道仍会使用 SMS/call-log BuildConfig 标志编译该 flavor,同时避免在每次 Android 相关推送上重复执行 debug APK 打包作业。
|
||||
Android CI 会运行 `testPlayDebugUnitTest` 和 `testThirdPartyDebugUnitTest`,随后构建 Play debug APK。third-party flavor 没有单独的源集或 manifest;它的单元测试分支仍会使用 SMS/call-log BuildConfig 标志编译该 flavor,同时避免在每个 Android 相关推送上重复执行 debug APK 打包作业。
|
||||
|
||||
`check-dependencies` 分片运行 `pnpm deadcode:dependencies`(一个仅生产 Knip 依赖检查,固定到最新 Knip 版本,并在 `dlx` 安装中禁用 pnpm 的最低发布时间限制)和 `pnpm deadcode:unused-files`,后者会将 Knip 的生产未使用文件发现与 `scripts/deadcode-unused-files.allowlist.mjs` 进行比较。当 PR 添加新的未经审核的未使用文件,或留下陈旧的 allowlist 条目时,未使用文件守卫会失败,同时保留 Knip 无法静态解析的有意动态插件、生成产物、构建、live-test 和包 bridge 表面。
|
||||
`check-dependencies` 分片运行 `pnpm deadcode:dependencies`(生产 Knip 仅依赖检查,固定到最新 Knip 版本,并为 `dlx` 安装禁用 pnpm 的最低发布年龄限制)和 `pnpm deadcode:unused-files`,后者会将 Knip 的生产未使用文件发现结果与 `scripts/deadcode-unused-files.allowlist.mjs` 进行比较。当 PR 添加新的未经审核未使用文件,或留下过期 allowlist 条目时,未使用文件防护会失败,同时保留 Knip 无法静态解析的有意动态插件、生成文件、构建、实时测试和包桥接表面。
|
||||
|
||||
## ClawSweeper 活动转发
|
||||
|
||||
`.github/workflows/clawsweeper-dispatch.yml` 是从 OpenClaw 仓库活动到 ClawSweeper 的目标侧 bridge。它不会检出或执行不受信任的拉取请求代码。该工作流会从 `CLAWSWEEPER_APP_PRIVATE_KEY` 创建 GitHub App 令牌,然后向 `openclaw/clawsweeper` 调度紧凑的 `repository_dispatch` 载荷。
|
||||
`.github/workflows/clawsweeper-dispatch.yml` 是从 OpenClaw 仓库活动到 ClawSweeper 的目标端桥接。它不会检出或执行不受信任的拉取请求代码。该工作流会从 `CLAWSWEEPER_APP_PRIVATE_KEY` 创建 GitHub App token,然后向 `openclaw/clawsweeper` 调度紧凑的 `repository_dispatch` payload。
|
||||
|
||||
该工作流有四个通道:
|
||||
该工作流有四个分支:
|
||||
|
||||
- `clawsweeper_item` 用于精确的问题和拉取请求审查请求;
|
||||
- `clawsweeper_comment` 用于问题评论中的显式 ClawSweeper 命令;
|
||||
- `clawsweeper_commit_review` 用于 `main` 推送上的提交级审查请求;
|
||||
- `clawsweeper_item` 用于精确的问题和拉取请求评审请求;
|
||||
- `clawsweeper_comment` 用于 issue comment 中的显式 ClawSweeper 命令;
|
||||
- `clawsweeper_commit_review` 用于 `main` 推送上的 commit 级评审请求;
|
||||
- `github_activity` 用于 ClawSweeper 智能体可能检查的一般 GitHub 活动。
|
||||
|
||||
`github_activity` 通道仅转发规范化元数据:事件类型、操作、actor、仓库、条目编号、URL、标题、状态,以及存在评论或审查时的短摘录。它有意避免转发完整 webhook 正文。`openclaw/clawsweeper` 中的接收工作流是 `.github/workflows/github-activity.yml`,它会将规范化事件发布到用于 ClawSweeper 智能体的 OpenClaw Gateway 网关 hook。
|
||||
`github_activity` 分支仅转发标准化元数据:event type、action、actor、repository、item number、URL、title、state,以及存在评论或评审时的短摘录。它有意避免转发完整 webhook body。`openclaw/clawsweeper` 中的接收工作流是 `.github/workflows/github-activity.yml`,它会将标准化事件发布到 ClawSweeper 智能体的 OpenClaw Gateway 网关 hook。
|
||||
|
||||
一般活动是观察,不是默认投递。ClawSweeper 智能体会在其提示中收到 Discord 目标,并且只有在事件令人意外、可执行、有风险或对运维有用时才应发布到 `#clawsweeper`。常规打开、编辑、机器人变动、重复 webhook 噪声和普通审查流量应产生 `NO_REPLY`。
|
||||
一般活动是观察,而不是默认投递。ClawSweeper 智能体会在提示中收到 Discord 目标,并且只应在事件令人意外、可执行、有风险或对运维有用时发布到 `#clawsweeper`。常规打开、编辑、bot 变动、重复 webhook 噪声和正常评审流量应产生 `NO_REPLY`。
|
||||
|
||||
在整个路径中,将 GitHub 标题、评论、正文、审查文本、分支名称和提交消息都视为不受信任的数据。它们是用于摘要和分流的输入,不是工作流或智能体运行时的指令。
|
||||
在整条路径中,将 GitHub 标题、评论、正文、评审文本、分支名称和 commit message 都视为不受信任的数据。它们是用于摘要和分诊的输入,不是工作流或智能体运行时的指令。
|
||||
|
||||
## 手动调度
|
||||
|
||||
手动 CI 调度运行与普通 CI 相同的作业图,但会强制开启每个非 Android 限定范围通道:Linux Node 分片、内置插件分片、渠道契约、Node 22 兼容性、`check`、`check-additional`、构建 smoke、文档检查、Python Skills、Windows、macOS 和 Control UI i18n。独立手动 CI 调度只有在 `include_android=true` 时才运行 Android;完整发布总入口会通过传递 `include_android=true` 启用 Android。插件预发布静态检查、仅发布用 `agentic-plugins` 分片、完整插件批量扫描,以及插件预发布 Docker 通道都排除在 CI 之外。Docker 预发布套件仅在 `完整发布验证` 通过启用 release-validation 门禁调度单独的 `插件预发布` 工作流时运行。
|
||||
手动 CI 调度运行与普通 CI 相同的作业图,但会强制开启每个非 Android 范围分支:Linux Node 分片、内置插件分片、渠道合约、Node 22 兼容性、`check`、`check-additional`、build smoke、文档检查、Python Skills、Windows、macOS 和 Control UI i18n。独立的手动 CI 调度仅在 `include_android=true` 时运行 Android;完整发布总工作流会通过传入 `include_android=true` 启用 Android。插件预发布静态检查、仅发布使用的 `agentic-plugins` 分片、完整插件批量扫描以及插件预发布 Docker 分支都不包含在 CI 中。Docker 预发布套件只会在 `Full Release Validation` 调度单独的 `Plugin Prerelease` 工作流并启用 release-validation 门禁时运行。
|
||||
|
||||
手动运行使用唯一并发组,因此候选发布完整套件不会被同一引用上的另一个推送或 PR 运行取消。可选的 `target_ref` 输入允许可信调用方针对分支、标签或完整提交 SHA 运行该图,同时使用来自所选调度引用的工作流文件。
|
||||
手动运行使用唯一并发组,因此发布候选版本的全套件不会被同一 ref 上的另一次推送或 PR 运行取消。可选的 `target_ref` 输入允许受信任调用方使用所选调度 ref 中的工作流文件,针对分支、标签或完整 commit SHA 运行该图。
|
||||
|
||||
```bash
|
||||
gh workflow run ci.yml --ref release/YYYY.M.D
|
||||
@ -97,17 +97,17 @@ gh workflow run full-release-validation.yml --ref main -f ref=<branch-or-sha>
|
||||
|
||||
## 运行器
|
||||
|
||||
| 运行器 | 任务 |
|
||||
| 运行器 | 作业 |
|
||||
| -------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `ubuntu-24.04` | `preflight`、快速安全任务和聚合任务(`security-scm-fast`、`security-dependency-audit`、`security-fast`)、快速协议/契约/内置检查、分片渠道契约检查、除 lint 外的 `check` 分片、`check-additional` 分片和聚合任务、Node 测试聚合验证器、文档检查、Python Skills、workflow-sanity、labeler、auto-response;install-smoke preflight 也使用 GitHub 托管的 Ubuntu,以便 Blacksmith 矩阵可以更早排队 |
|
||||
| `ubuntu-24.04` | `preflight`、快速安全作业和聚合项(`security-scm-fast`、`security-dependency-audit`、`security-fast`)、快速协议/契约/内置检查、分片的渠道契约检查、除 lint 外的 `check` 分片、`check-additional` 分片和聚合项、Node 测试聚合验证器、文档检查、Python Skills、workflow-sanity、labeler、auto-response;install-smoke 预检也使用 GitHub 托管的 Ubuntu,以便 Blacksmith 矩阵可以更早排队 |
|
||||
| `blacksmith-4vcpu-ubuntu-2404` | `CodeQL Critical Quality`、较低权重的插件分片、`checks-fast-core`、`checks-node-compat-node22`、`check-prod-types` 和 `check-test-types` |
|
||||
| `blacksmith-8vcpu-ubuntu-2404` | `build-artifacts`、build-smoke、Linux Node 测试分片、内置插件测试分片、`android` |
|
||||
| `blacksmith-16vcpu-ubuntu-2404` | `check-lint`(对 CPU 足够敏感,8 vCPU 的成本高于它节省的成本);install-smoke Docker 构建(32-vCPU 排队时间的成本高于它节省的成本) |
|
||||
| `blacksmith-16vcpu-ubuntu-2404` | `check-lint`(对 CPU 足够敏感,8 vCPU 的成本高于节省的成本);install-smoke Docker 构建(32-vCPU 队列时间成本高于节省的成本) |
|
||||
| `blacksmith-16vcpu-windows-2025` | `checks-windows` |
|
||||
| `blacksmith-6vcpu-macos-latest` | `openclaw/openclaw` 上的 `macos-node`;fork 回退到 `macos-latest` |
|
||||
| `blacksmith-12vcpu-macos-latest` | `openclaw/openclaw` 上的 `macos-swift`;fork 回退到 `macos-latest` |
|
||||
|
||||
## 本地等效命令
|
||||
## 本地等价命令
|
||||
|
||||
```bash
|
||||
pnpm changed:lanes # inspect the local changed-lane classifier for origin/main...HEAD
|
||||
@ -135,31 +135,40 @@ pnpm test:perf:groups:compare .artifacts/test-perf/baseline-before.json .artifac
|
||||
|
||||
## 完整发布验证
|
||||
|
||||
`Full Release Validation` 是“在发布前运行所有内容”的手动总控工作流。它接受分支、标签或完整提交 SHA,使用该目标分发手动 `CI` 工作流,分发 `Plugin Prerelease` 以提供仅发布所需的插件/包/静态/Docker 证明,并分发 `OpenClaw Release Checks` 以运行安装冒烟、包验收、Docker 发布路径套件、live/E2E、OpenWebUI、QA Lab parity、Matrix 和 Telegram 通道。使用 `rerun_group=all` 和 `release_profile=full` 时,它还会针对来自发布检查的 `release-package-under-test` 构件运行 `NPM Telegram Beta E2E`。发布后,传入 `npm_telegram_package_spec`,即可针对已发布的 npm 包重新运行同一个 Telegram 包通道。
|
||||
`Full Release Validation` 是用于“在发布前运行所有内容”的手动总控工作流。它接受分支、标签或完整提交 SHA,使用该目标分发手动 `CI` 工作流,分发 `Plugin Prerelease` 以提供仅发布所需的插件/包/静态/Docker 证明,并分发 `OpenClaw Release Checks` 以覆盖安装冒烟、包验收、Docker 发布路径套件、live/E2E、OpenWebUI、QA Lab 奇偶校验、Matrix 和 Telegram 通道。使用 `rerun_group=all` 和 `release_profile=full` 时,它还会针对来自发布检查的 `release-package-under-test` 制品运行 `NPM Telegram Beta E2E`。发布后,传入 `npm_telegram_package_spec` 可针对已发布的 npm 包重新运行同一个 Telegram 包通道。
|
||||
|
||||
请参阅[完整发布验证](/zh-CN/reference/full-release-validation),了解阶段矩阵、精确的工作流任务名称、配置差异、构件以及定向重跑句柄。
|
||||
请参阅[完整发布验证](/zh-CN/reference/full-release-validation),了解阶段矩阵、确切的工作流作业名称、配置差异、制品和定向重跑句柄。
|
||||
|
||||
`release_profile` 控制传递给发布检查的 live/提供商覆盖范围。手动发布工作流默认使用 `stable`;只有在你明确想要广泛的建议性提供商/媒体矩阵时,才使用 `full`。
|
||||
对于快速变化分支上的固定提交证明,请使用辅助命令,而不是
|
||||
`gh workflow run ... --ref main -f ref=<sha>`:
|
||||
|
||||
- `minimum` 保留最快的 OpenAI/核心发布关键通道。
|
||||
```bash
|
||||
pnpm ci:full-release --sha <full-sha>
|
||||
```
|
||||
|
||||
GitHub 工作流分发 ref 必须是分支或标签,不能是原始提交 SHA。该辅助命令会在目标 SHA 上推送一个临时 `release-ci/<sha>-...` 分支,从该固定 ref 分发 `Full Release Validation`,验证每个子工作流的 `headSha` 都与目标匹配,并在运行完成后删除临时分支。如果任何子工作流在不同的 SHA 上运行,总控验证器也会失败。
|
||||
|
||||
`release_profile` 控制传入发布检查的 live/provider 覆盖范围。手动发布工作流默认使用 `stable`;只有在你有意需要广泛的建议 provider/媒体矩阵时才使用 `full`。
|
||||
|
||||
- `minimum` 保留最快的 OpenAI/core 发布关键通道。
|
||||
- `stable` 添加稳定的提供商/后端集合。
|
||||
- `full` 运行广泛的建议性提供商/媒体矩阵。
|
||||
- `full` 运行广泛的建议提供商/媒体矩阵。
|
||||
|
||||
总控工作流会记录已分发的子运行 ID,最终的 `Verify full validation` 任务会重新检查当前子运行结论,并为每个子运行追加最慢任务表。如果某个子工作流被重新运行并变绿,只需重新运行父验证器任务即可刷新总控结果和耗时摘要。
|
||||
总控会记录已分发的子运行 ID,最终的 `Verify full validation` 作业会重新检查当前子运行结论,并为每个子运行追加最慢作业表。如果某个子工作流被重新运行并变为绿色,只需重新运行父验证器作业即可刷新总控结果和时间摘要。
|
||||
|
||||
对于恢复,`Full Release Validation` 和 `OpenClaw Release Checks` 都接受 `rerun_group`。对发布候选使用 `all`,仅对普通完整 CI 子项使用 `ci`,仅对插件预发布子项使用 `plugin-prerelease`,对每个发布子项使用 `release-checks`,或在总控工作流上使用更窄的组:`install-smoke`、`cross-os`、`live-e2e`、`package`、`qa`、`qa-parity`、`qa-live` 或 `npm-telegram`。这样可以在定向修复后,将失败发布环境的重跑范围保持受限。
|
||||
恢复时,`Full Release Validation` 和 `OpenClaw Release Checks` 都接受 `rerun_group`。对发布候选使用 `all`,仅对普通完整 CI 子项使用 `ci`,仅对插件预发布子项使用 `plugin-prerelease`,对每个发布子项使用 `release-checks`,或在总控中使用更窄的组:`install-smoke`、`cross-os`、`live-e2e`、`package`、`qa`、`qa-parity`、`qa-live` 或 `npm-telegram`。这会让失败的发布环境在定向修复后保持重跑范围受限。
|
||||
|
||||
`OpenClaw Release Checks` 使用受信任的工作流 ref,将所选 ref 一次性解析为 `release-package-under-test` tarball,然后将该构件传递给 live/E2E 发布路径 Docker 工作流和包验收分片。这能让发布环境之间的包字节保持一致,并避免在多个子任务中重新打包同一个候选版本。
|
||||
`OpenClaw Release Checks` 使用受信任的工作流 ref 将所选 ref 解析一次为 `release-package-under-test` tarball,然后将该制品同时传给 live/E2E 发布路径 Docker 工作流和包验收分片。这样可以让发布环境之间的包字节保持一致,并避免在多个子作业中重新打包同一个候选版本。
|
||||
|
||||
对于 `ref=main` 且 `rerun_group=all` 的重复 `Full Release Validation` 运行,较新的总控工作流会取代较旧的总控工作流。父监视器会在父运行取消时,取消它已分发的所有子工作流,因此较新的 main 验证不会排在过时的两小时发布检查运行后面。发布分支/标签验证和定向重跑组保留 `cancel-in-progress: false`。
|
||||
对于 `ref=main` 且 `rerun_group=all` 的重复 `Full Release Validation` 运行,较新的总控会取代较旧的总控。父监控器在父项被取消时会取消它已经分发的任何子工作流,因此较新的 main 验证不会排在过期的两小时发布检查运行之后。发布分支/标签验证和定向重跑组保持 `cancel-in-progress: false`。
|
||||
|
||||
## Live 和 E2E 分片
|
||||
|
||||
发布 live/E2E 子项保留广泛的原生 `pnpm test:live` 覆盖,但它通过 `scripts/test-live-shard.mjs` 作为命名分片运行,而不是一个串行任务:
|
||||
发布 live/E2E 子项保留广泛的原生 `pnpm test:live` 覆盖,但它通过 `scripts/test-live-shard.mjs` 以命名分片运行,而不是一个串行作业:
|
||||
|
||||
- `native-live-src-agents`
|
||||
- `native-live-src-gateway-core`
|
||||
- 提供商过滤的 `native-live-src-gateway-profiles` 任务
|
||||
- provider 过滤的 `native-live-src-gateway-profiles` 作业
|
||||
- `native-live-src-gateway-backends`
|
||||
- `native-live-test`
|
||||
- `native-live-extensions-a-k`
|
||||
@ -167,59 +176,59 @@ pnpm test:perf:groups:compare .artifacts/test-perf/baseline-before.json .artifac
|
||||
- `native-live-extensions-openai`
|
||||
- `native-live-extensions-o-z-other`
|
||||
- `native-live-extensions-xai`
|
||||
- 拆分的媒体音频/视频分片和提供商过滤的音乐分片
|
||||
- 拆分的媒体音频/视频分片和 provider 过滤的音乐分片
|
||||
|
||||
这会保持相同的文件覆盖,同时让较慢的 live 提供商故障更容易重跑和诊断。聚合的 `native-live-extensions-o-z`、`native-live-extensions-media` 和 `native-live-extensions-media-music` 分片名称仍可用于手动一次性重跑。
|
||||
这样可以保持相同的文件覆盖,同时让缓慢的 live provider 失败更容易重跑和诊断。聚合的 `native-live-extensions-o-z`、`native-live-extensions-media` 和 `native-live-extensions-media-music` 分片名称对于手动一次性重跑仍然有效。
|
||||
|
||||
原生 live 媒体分片运行在 `ghcr.io/openclaw/openclaw-live-media-runner:ubuntu-24.04` 中,该镜像由 `Live Media Runner Image` 工作流构建。该镜像预装 `ffmpeg` 和 `ffprobe`;媒体任务只会在设置前验证这些二进制文件。将 Docker 支持的 live 套件保留在普通 Blacksmith 运行器上,容器任务不适合启动嵌套 Docker 测试。
|
||||
原生 live 媒体分片在 `ghcr.io/openclaw/openclaw-live-media-runner:ubuntu-24.04` 中运行,该镜像由 `Live Media Runner Image` 工作流构建。该镜像预安装 `ffmpeg` 和 `ffprobe`;媒体作业只在设置前验证这些二进制文件。将 Docker 支持的 live 套件保留在普通 Blacksmith 运行器上,容器作业不是启动嵌套 Docker 测试的合适位置。
|
||||
|
||||
Docker 支持的 live 模型/后端分片会为每个选定提交使用单独的共享 `ghcr.io/openclaw/openclaw-live-test:<sha>` 镜像。live 发布工作流会构建并推送该镜像一次,然后 Docker live 模型、按提供商分片的 Gateway 网关、CLI 后端、ACP bind 和 Codex harness 分片会使用 `OPENCLAW_SKIP_DOCKER_BUILD=1` 运行。Gateway 网关 Docker 分片在脚本层带有明确的 `timeout` 上限,低于工作流任务超时,因此卡住的容器或清理路径会快速失败,而不是耗尽整个发布检查预算。如果这些分片独立重建完整源码 Docker 目标,则说明发布运行配置错误,并会在重复镜像构建上浪费墙钟时间。
|
||||
Docker 支持的 live 模型/后端分片会为每个所选提交使用单独的共享 `ghcr.io/openclaw/openclaw-live-test:<sha>` 镜像。live 发布工作流会构建并推送该镜像一次,然后 Docker live 模型、provider 分片的 Gateway 网关、CLI 后端、ACP 绑定和 Codex harness 分片会使用 `OPENCLAW_SKIP_DOCKER_BUILD=1` 运行。Gateway 网关 Docker 分片会携带显式的脚本级 `timeout` 上限,低于工作流作业超时,因此卡住的容器或清理路径会快速失败,而不是消耗整个发布检查预算。如果这些分片独立重建完整源 Docker 目标,则说明发布运行配置错误,并会在重复镜像构建上浪费实际耗时。
|
||||
|
||||
## 包验收
|
||||
|
||||
当问题是“这个可安装的 OpenClaw 包作为产品是否可用?”时,使用 `Package Acceptance`。它不同于普通 CI:普通 CI 验证源码树,而包验收通过用户安装或更新后使用的同一个 Docker E2E harness 验证单个 tarball。
|
||||
当问题是“这个可安装的 OpenClaw 包能否作为产品正常工作?”时,使用 `Package Acceptance`。它不同于普通 CI:普通 CI 验证源码树,而 package acceptance 会通过用户安装或更新后使用的同一套 Docker E2E harness 验证单个 tarball。
|
||||
|
||||
### 任务
|
||||
### 作业
|
||||
|
||||
1. `resolve_package` 检出 `workflow_ref`,解析一个候选包,写入 `.artifacts/docker-e2e-package/openclaw-current.tgz`,写入 `.artifacts/docker-e2e-package/package-candidate.json`,将二者作为 `package-under-test` 工件上传,并在 GitHub 步骤摘要中打印来源、工作流引用、包引用、版本、SHA-256 和配置文件。
|
||||
2. `docker_acceptance` 使用 `ref=workflow_ref` 和 `package_artifact_name=package-under-test` 调用 `openclaw-live-and-e2e-checks-reusable.yml`。可复用工作流下载该工件,验证 tarball 清单,在需要时准备包摘要 Docker 镜像,并针对该包运行所选 Docker 测试通道,而不是打包工作流检出内容。当一个配置文件选择多个定向 `docker_lanes` 时,可复用工作流会先准备一次包和共享镜像,然后将这些测试通道分发为并行的定向 Docker 作业,并使用唯一工件。
|
||||
3. `package_telegram` 可选择调用 `NPM Telegram Beta E2E`。当 `telegram_mode` 不是 `none` 时运行;如果包验收已解析出包,它会安装同一个 `package-under-test` 工件;独立 Telegram 分发仍可安装已发布的 npm 规格。
|
||||
4. 如果包解析、Docker 验收或可选 Telegram 测试通道失败,`summary` 会让工作流失败。
|
||||
1. `resolve_package` 会检出 `workflow_ref`,解析一个包候选项,写入 `.artifacts/docker-e2e-package/openclaw-current.tgz`,写入 `.artifacts/docker-e2e-package/package-candidate.json`,将两者作为 `package-under-test` artifact 上传,并在 GitHub 步骤摘要中打印来源、workflow ref、package ref、版本、SHA-256 和 profile。
|
||||
2. `docker_acceptance` 会用 `ref=workflow_ref` 和 `package_artifact_name=package-under-test` 调用 `openclaw-live-and-e2e-checks-reusable.yml`。这个可复用 workflow 会下载该 artifact,验证 tarball inventory,在需要时准备 package-digest Docker 镜像,并针对该包运行所选 Docker lanes,而不是打包 workflow checkout。当一个 profile 选择多个目标 `docker_lanes` 时,可复用 workflow 会先准备一次包和共享镜像,然后将这些 lanes 分发为并行的目标 Docker jobs,并使用唯一 artifacts。
|
||||
3. `package_telegram` 可选地调用 `NPM Telegram Beta E2E`。当 `telegram_mode` 不是 `none` 时运行;如果 Package Acceptance 已解析出一个包,它会安装同一个 `package-under-test` artifact;独立 Telegram dispatch 仍可安装已发布的 npm spec。
|
||||
4. `summary` 会在包解析、Docker acceptance 或可选 Telegram lane 失败时使 workflow 失败。
|
||||
|
||||
### 候选来源
|
||||
|
||||
- `source=npm` 只接受 `openclaw@beta`、`openclaw@latest`,或精确的 OpenClaw 发布版本,例如 `openclaw@2026.4.27-beta.2`。将此用于已发布 beta/稳定版的验收。
|
||||
- `source=ref` 会打包受信任的 `package_ref` 分支、标签或完整提交 SHA。解析器会获取 OpenClaw 分支/标签,验证所选提交可从仓库分支历史或发布标签访问,在分离的工作树中安装依赖,并用 `scripts/package-openclaw-for-docker.mjs` 打包。
|
||||
- `source=url` 下载一个 HTTPS `.tgz`;必须提供 `package_sha256`。
|
||||
- `source=artifact` 从 `artifact_run_id` 和 `artifact_name` 下载一个 `.tgz`;`package_sha256` 可选,但对于外部共享工件应提供。
|
||||
- `source=npm` 只接受 `openclaw@beta`、`openclaw@latest`,或精确的 OpenClaw 发布版本,例如 `openclaw@2026.4.27-beta.2`。将它用于已发布 beta/stable 的 acceptance。
|
||||
- `source=ref` 会打包受信任的 `package_ref` 分支、tag 或完整 commit SHA。resolver 会获取 OpenClaw 分支/tag,验证所选 commit 可从仓库分支历史或 release tag 到达,在 detached worktree 中安装依赖,并用 `scripts/package-openclaw-for-docker.mjs` 打包。
|
||||
- `source=url` 会下载 HTTPS `.tgz`;必须提供 `package_sha256`。
|
||||
- `source=artifact` 会从 `artifact_run_id` 和 `artifact_name` 下载一个 `.tgz`;`package_sha256` 可选,但对于外部共享的 artifacts 应提供。
|
||||
|
||||
保持 `workflow_ref` 和 `package_ref` 分离。`workflow_ref` 是运行测试的受信任工作流/测试框架代码。`package_ref` 是 `source=ref` 时被打包的源提交。这样,当前测试框架可以验证较旧的受信任源提交,而不运行旧的工作流逻辑。
|
||||
保持 `workflow_ref` 和 `package_ref` 分离。`workflow_ref` 是运行测试的受信任 workflow/harness 代码。`package_ref` 是在 `source=ref` 时会被打包的源 commit。这样当前测试 harness 就能验证较旧的受信任源 commit,而不运行旧 workflow 逻辑。
|
||||
|
||||
### 套件配置文件
|
||||
### 套件 profiles
|
||||
|
||||
- `smoke` — `npm-onboard-channel-agent`、`gateway-network`、`config-reload`
|
||||
- `package` — `npm-onboard-channel-agent`、`doctor-switch`、`update-channel-switch`、`upgrade-survivor`、`published-upgrade-survivor`、`plugins-offline`、`plugin-update`
|
||||
- `product` — `package` 加上 `mcp-channels`、`cron-mcp-cleanup`、`openai-web-search-minimal`、`openwebui`
|
||||
- `full` — 带 OpenWebUI 的完整 Docker 发布路径分块
|
||||
- `smoke` — `npm-onboard-channel-agent`, `gateway-network`, `config-reload`
|
||||
- `package` — `npm-onboard-channel-agent`, `doctor-switch`, `update-channel-switch`, `upgrade-survivor`, `published-upgrade-survivor`, `plugins-offline`, `plugin-update`
|
||||
- `product` — `package` 加上 `mcp-channels`, `cron-mcp-cleanup`, `openai-web-search-minimal`, `openwebui`
|
||||
- `full` — 包含 OpenWebUI 的完整 Docker release-path chunks
|
||||
- `custom` — 精确的 `docker_lanes`;当 `suite_profile=custom` 时必需
|
||||
|
||||
`package` 配置文件使用离线插件覆盖,因此已发布包验证不会受实时 ClawHub 可用性限制。可选 Telegram 测试通道会在 `NPM Telegram Beta E2E` 中复用 `package-under-test` 工件,同时保留已发布 npm 规格路径用于独立分发。
|
||||
`package` profile 使用离线插件覆盖,因此已发布包验证不会被实时 ClawHub 可用性阻塞。可选 Telegram lane 会在 `NPM Telegram Beta E2E` 中复用 `package-under-test` artifact,同时为独立 dispatch 保留已发布 npm spec 路径。
|
||||
|
||||
有关专用的更新和插件测试策略,包括本地命令、Docker 测试通道、包验收输入、发布默认值和失败分类,请参阅[更新和插件测试](/zh-CN/help/testing-updates-plugins)。
|
||||
关于专门的更新和插件测试策略,包括本地命令、Docker lanes、Package Acceptance 输入、release 默认值和失败分诊,请参阅[更新和插件测试](/zh-CN/help/testing-updates-plugins)。
|
||||
|
||||
发布检查会使用 `source=artifact`、准备好的发布包工件、`suite_profile=custom`、`docker_lanes='doctor-switch update-channel-switch upgrade-survivor published-upgrade-survivor plugins-offline plugin-update'`、`published_upgrade_survivor_baselines=release-history`、`published_upgrade_survivor_scenarios=reported-issues` 和 `telegram_mode=mock-openai` 调用包验收。这会让包迁移、更新、过时插件依赖清理、离线插件、插件更新和 Telegram 证明都基于同一个已解析包 tarball。跨操作系统发布检查仍覆盖特定操作系统的新手引导、安装程序和平台行为;包/更新产品验证应从包验收开始。`published-upgrade-survivor` Docker 测试通道每次运行验证一个已发布包基线。在包验收中,已解析的 `package-under-test` tarball 始终是候选包,而 `published_upgrade_survivor_baseline` 选择回退的已发布基线,默认是 `openclaw@latest`;失败测试通道的重跑命令会保留该基线。设置 `published_upgrade_survivor_baselines=release-history` 可将该测试通道扩展到去重历史矩阵:最近六个稳定版本、`2026.4.23`,以及 `2026-03-15` 之前的最新稳定版本。设置 `published_upgrade_survivor_scenarios=reported-issues` 可将相同基线扩展到问题形状的夹具,覆盖 Feishu 配置、保留的启动/角色文件、波浪号日志路径,以及过时旧版插件依赖根目录。单独的 `Update Migration` 工作流在问题是穷尽式已发布更新清理,而不是普通完整发布 CI 广度时,会使用 `update-migration` Docker 测试通道,并带上 `all-since-2026.4.23` 和 `plugin-deps-cleanup`。本地聚合运行可以通过 `OPENCLAW_UPGRADE_SURVIVOR_BASELINE_SPECS` 传入精确包规格,也可以通过 `OPENCLAW_UPGRADE_SURVIVOR_BASELINE_SPEC` 保持单个测试通道,例如 `openclaw@2026.4.15`,或设置 `OPENCLAW_UPGRADE_SURVIVOR_SCENARIOS` 以启用场景矩阵。已发布测试通道使用内置的 `openclaw config set` 命令配方来配置基线,在 `summary.json` 中记录配方步骤,并在 Gateway 网关启动后探测 `/healthz`、`/readyz` 以及 RPC 状态。Windows 打包和安装程序全新测试通道还会验证已安装包可以从原始绝对 Windows 路径导入浏览器控制覆盖。OpenAI 跨操作系统 agent 回合冒烟测试在设置时默认使用 `OPENCLAW_CROSS_OS_OPENAI_MODEL`,否则使用 `openai/gpt-5.5`,因此安装和 Gateway 网关证明会保持在首选的 GPT-5 测试模型上。
|
||||
Release checks 会使用 `source=artifact`、已准备好的 release package artifact、`suite_profile=custom`、`docker_lanes='doctor-switch update-channel-switch upgrade-survivor published-upgrade-survivor plugins-offline plugin-update'`、`published_upgrade_survivor_baselines=release-history`、`published_upgrade_survivor_scenarios=reported-issues` 和 `telegram_mode=mock-openai` 调用 Package Acceptance。这样可以让包迁移、更新、陈旧插件依赖清理、离线插件、plugin-update 和 Telegram 证明都基于同一个已解析的包 tarball。Cross-OS release checks 仍覆盖特定于 OS 的新手引导、安装器和平台行为;包/更新产品验证应从 Package Acceptance 开始。`published-upgrade-survivor` Docker lane 每次运行会验证一个已发布包基线。在 Package Acceptance 中,解析出的 `package-under-test` tarball 始终是候选包,而 `published_upgrade_survivor_baseline` 选择回退的已发布基线,默认是 `openclaw@latest`;失败 lane 的重跑命令会保留该基线。设置 `published_upgrade_survivor_baselines=release-history` 可将该 lane 扩展到一个去重历史矩阵:最新六个 stable releases、`2026.4.23`,以及 `2026-03-15` 之前的最新 stable release。设置 `published_upgrade_survivor_scenarios=reported-issues` 可将同一组 baselines 扩展到面向 issue 的 fixtures,覆盖 Feishu 配置、保留的 bootstrap/persona 文件、tilde 日志路径,以及陈旧旧版插件依赖根。单独的 `Update Migration` workflow 会使用 `update-migration` Docker lane,并在问题是彻底的已发布更新清理而不是普通 Full Release CI 广度时使用 `all-since-2026.4.23` 和 `plugin-deps-cleanup`。本地聚合运行可以用 `OPENCLAW_UPGRADE_SURVIVOR_BASELINE_SPECS` 传入精确包 specs,也可以用 `OPENCLAW_UPGRADE_SURVIVOR_BASELINE_SPEC` 保持单个 lane,例如 `openclaw@2026.4.15`,或设置 `OPENCLAW_UPGRADE_SURVIVOR_SCENARIOS` 来生成场景矩阵。published lane 会用内置的 `openclaw config set` 命令 recipe 配置基线,在 `summary.json` 中记录 recipe 步骤,并在 Gateway 网关启动后探测 `/healthz`、`/readyz` 以及 RPC status。Windows packaged 和 installer fresh lanes 还会验证已安装的包可以从原始 Windows 绝对路径导入 browser-control override。OpenAI cross-OS agent-turn smoke 在设置 `OPENCLAW_CROSS_OS_OPENAI_MODEL` 时默认使用它,否则使用 `openai/gpt-5.5`,因此安装和 Gateway 网关证明会保持在首选 GPT-5 测试模型上。
|
||||
|
||||
### 旧版兼容窗口
|
||||
|
||||
包验收为已发布包设置了有界的旧版兼容窗口。到 `2026.4.25` 为止的包,包括 `2026.4.25-beta.*`,可以使用兼容路径:
|
||||
Package Acceptance 对已发布包有有限的旧版兼容窗口。到 `2026.4.25` 为止的包,包括 `2026.4.25-beta.*`,可以使用兼容路径:
|
||||
|
||||
- `dist/postinstall-inventory.json` 中已知的私有 QA 条目可以指向 tarball 中省略的文件;
|
||||
- 当包未暴露 `gateway install --wrapper` 标志时,`doctor-switch` 可以跳过 `gateway install --wrapper` 持久化子用例;
|
||||
- `update-channel-switch` 可以从 tarball 派生的假 git 夹具中删减缺失的 `pnpm.patchedDependencies`,并且可以记录缺失的持久化 `update.channel`;
|
||||
- 插件冒烟测试可以读取旧版安装记录位置,或接受缺失的市场安装记录持久化;
|
||||
- `plugin-update` 可以允许配置元数据迁移,但仍要求安装记录和不重装行为保持不变。
|
||||
- `dist/postinstall-inventory.json` 中已知的私有 QA entries 可以指向 tarball 中省略的文件;
|
||||
- 当包未暴露该 flag 时,`doctor-switch` 可以跳过 `gateway install --wrapper` 持久化子用例;
|
||||
- `update-channel-switch` 可以从 tarball 派生的 fake git fixture 中修剪缺失的 `pnpm.patchedDependencies`,也可以记录缺失的持久化 `update.channel`;
|
||||
- plugin smokes 可以读取旧版 install-record 位置,或接受缺失的 marketplace install-record 持久化;
|
||||
- `plugin-update` 可以允许配置元数据迁移,同时仍要求 install record 和 no-reinstall 行为保持不变。
|
||||
|
||||
已发布的 `2026.4.26` 包也可以对已经发布的本地构建元数据戳文件发出警告。之后的包必须满足现代契约;相同条件会失败,而不是警告或跳过。
|
||||
已发布的 `2026.4.26` 包也可能对已经发布的本地构建元数据 stamp 文件发出警告。之后的包必须满足现代 contracts;相同条件会失败,而不是警告或跳过。
|
||||
|
||||
### 示例
|
||||
|
||||
@ -262,152 +271,152 @@ gh workflow run package-acceptance.yml \
|
||||
-f docker_lanes='install-e2e plugin-update'
|
||||
```
|
||||
|
||||
调试失败的包验收运行时,先查看 `resolve_package` 摘要,确认包来源、版本和 SHA-256。然后检查 `docker_acceptance` 子运行及其 Docker 构件:`.artifacts/docker-tests/**/summary.json`、`failures.json`、lane 日志、阶段耗时和重新运行命令。优先重新运行失败的包 profile 或精确的 Docker lanes,而不是重新运行完整发布验证。
|
||||
调试失败的 package acceptance 运行时,从 `resolve_package` 摘要开始,确认包来源、版本和 SHA-256。然后检查 `docker_acceptance` 子运行及其 Docker artifacts:`.artifacts/docker-tests/**/summary.json`、`failures.json`、lane logs、phase timings 和重跑命令。优先重跑失败的 package profile 或精确 Docker lanes,而不是重跑完整 release validation。
|
||||
|
||||
## 安装冒烟测试
|
||||
|
||||
独立的 `Install Smoke` 工作流通过自己的 `preflight` 作业复用同一个 scope 脚本。它将冒烟覆盖拆分为 `run_fast_install_smoke` 和 `run_full_install_smoke`。
|
||||
单独的 `Install Smoke` workflow 会通过自己的 `preflight` job 复用同一个 scope 脚本。它将 smoke 覆盖拆分为 `run_fast_install_smoke` 和 `run_full_install_smoke`。
|
||||
|
||||
- **快速路径**会在拉取请求触及 Docker/包表面、内置插件包/manifest 变更,或 Docker 冒烟作业会覆盖的核心插件/渠道/Gateway 网关/插件 SDK 表面时运行。仅源代码的内置插件变更、仅测试编辑和仅文档编辑不会占用 Docker workers。快速路径会构建一次根 Dockerfile 镜像,检查 CLI,运行 agents delete shared-workspace CLI 冒烟测试,运行容器 gateway-network e2e,验证内置扩展构建参数,并在 240 秒聚合命令超时内运行有界的内置插件 Docker profile(每个场景的 Docker 运行单独设限)。
|
||||
- **完整路径**为夜间定时运行、手动触发、workflow-call 发布检查,以及真正触及安装器/包/Docker 表面的拉取请求保留 QR 包安装和安装器 Docker/更新覆盖。在完整模式下,install-smoke 会准备或复用一个目标 SHA 的 GHCR 根 Dockerfile 冒烟镜像,然后将 QR 包安装、根 Dockerfile/Gateway 网关冒烟测试、安装器/更新冒烟测试,以及快速内置插件 Docker E2E 作为独立作业运行,这样安装器工作不必等待根镜像冒烟测试。
|
||||
- **快速路径** 会在 pull requests 触及 Docker/package surfaces、内置插件 package/manifest 变更,或 Docker smoke jobs 会执行的 core plugin/channel/gateway/插件 SDK surfaces 时运行。仅源码的内置插件变更、仅测试编辑和仅文档编辑不会预留 Docker workers。快速路径会构建一次 root Dockerfile 镜像,检查 CLI,运行 agents delete shared-workspace CLI smoke,运行 container gateway-network e2e,验证内置扩展 build arg,并在 240 秒聚合命令超时内运行有界的 bundled-plugin Docker profile(每个场景的 Docker run 会单独封顶)。
|
||||
- **完整路径** 会为夜间定时运行、手动 dispatches、workflow-call release checks,以及确实触及 installer/package/Docker surfaces 的 pull requests 保留 QR package install 和 installer Docker/update 覆盖。在 full mode 下,install-smoke 会准备或复用一个 target-SHA GHCR root Dockerfile smoke 镜像,然后将 QR package install、root Dockerfile/gateway smokes、installer/update smokes,以及快速 bundled-plugin Docker E2E 作为单独 jobs 运行,以便 installer 工作不会被 root image smokes 阻塞。
|
||||
|
||||
`main` 推送(包括合并提交)不会强制走完整路径;当变更范围逻辑会在推送上请求完整覆盖时,工作流会保留快速 Docker 冒烟测试,并将完整安装冒烟测试留给夜间或发布验证。
|
||||
`main` pushes(包括 merge commits)不会强制执行完整路径;当 changed-scope 逻辑会在 push 上请求完整覆盖时,workflow 会保留快速 Docker smoke,并将完整 install smoke 留给夜间或 release validation。
|
||||
|
||||
较慢的 Bun 全局安装 image-provider 冒烟测试由 `run_bun_global_install_smoke` 单独控制。它会在夜间计划和发布检查工作流中运行,手动 `Install Smoke` 触发也可以选择启用它,但拉取请求和 `main` 推送不会运行。QR 和安装器 Docker 测试保留各自面向安装的 Dockerfile。
|
||||
较慢的 Bun global install image-provider smoke 由 `run_bun_global_install_smoke` 单独 gate。它会在夜间 schedule 和 release checks workflow 中运行,手动 `Install Smoke` dispatches 可以选择加入,但 pull requests 和 `main` pushes 不会运行。QR 和 installer Docker tests 保留各自专注于安装的 Dockerfiles。
|
||||
|
||||
## 本地 Docker E2E
|
||||
|
||||
`pnpm test:docker:all` 会预构建一个共享 live-test 镜像,将 OpenClaw 打包一次为 npm tarball,并构建两个共享的 `scripts/e2e/Dockerfile` 镜像:
|
||||
|
||||
- 用于安装器/更新/plugin-dependency lanes 的裸 Node/Git runner;
|
||||
- 一个功能镜像,将同一个 tarball 安装到 `/app`,用于普通功能 lanes。
|
||||
- 用于 installer/update/plugin-dependency lanes 的裸 Node/Git runner;
|
||||
- 一个会将同一 tarball 安装到 `/app` 中的功能镜像,用于普通功能 lanes。
|
||||
|
||||
Docker lane 定义位于 `scripts/lib/docker-e2e-scenarios.mjs`,规划器逻辑位于 `scripts/lib/docker-e2e-plan.mjs`,runner 只执行选中的计划。调度器通过 `OPENCLAW_DOCKER_E2E_BARE_IMAGE` 和 `OPENCLAW_DOCKER_E2E_FUNCTIONAL_IMAGE` 为每个 lane 选择镜像,然后使用 `OPENCLAW_SKIP_DOCKER_BUILD=1` 运行 lanes。
|
||||
Docker lane definitions 位于 `scripts/lib/docker-e2e-scenarios.mjs`,planner 逻辑位于 `scripts/lib/docker-e2e-plan.mjs`,runner 只执行所选 plan。scheduler 会用 `OPENCLAW_DOCKER_E2E_BARE_IMAGE` 和 `OPENCLAW_DOCKER_E2E_FUNCTIONAL_IMAGE` 为每个 lane 选择镜像,然后用 `OPENCLAW_SKIP_DOCKER_BUILD=1` 运行 lanes。
|
||||
|
||||
### 可调项
|
||||
### 可调参数
|
||||
|
||||
| 变量 | 默认值 | 用途 |
|
||||
| -------------------------------------- | ------ | --------------------------------------------------------------------------------------------- |
|
||||
| `OPENCLAW_DOCKER_ALL_PARALLELISM` | 10 | 普通任务通道的主池槽位数。 |
|
||||
| `OPENCLAW_DOCKER_ALL_TAIL_PARALLELISM` | 10 | 对提供商敏感的尾池槽位数。 |
|
||||
| `OPENCLAW_DOCKER_ALL_LIVE_LIMIT` | 9 | 并发实测任务通道上限,避免提供商限流。 |
|
||||
| `OPENCLAW_DOCKER_ALL_NPM_LIMIT` | 10 | 并发 npm 安装任务通道上限。 |
|
||||
| `OPENCLAW_DOCKER_ALL_SERVICE_LIMIT` | 7 | 并发多服务任务通道上限。 |
|
||||
| `OPENCLAW_DOCKER_ALL_START_STAGGER_MS` | 2000 | 任务通道启动之间的错峰时间,用于避免 Docker 守护进程创建风暴;设为 `0` 表示不启用错峰。 |
|
||||
| `OPENCLAW_DOCKER_ALL_LANE_TIMEOUT_MS` | 7200000 | 每个任务通道的后备超时(120 分钟);选定的实测/尾部任务通道使用更严格的上限。 |
|
||||
| `OPENCLAW_DOCKER_ALL_DRY_RUN` | 未设置 | `1` 会打印调度器计划而不运行任务通道。 |
|
||||
| `OPENCLAW_DOCKER_ALL_LANES` | 未设置 | 逗号分隔的精确任务通道列表;跳过清理 smoke,以便智能体复现某个失败的任务通道。 |
|
||||
| 变量 | 默认值 | 用途 |
|
||||
| -------------------------------------- | ------- | ------------------------------------------------------------------------------------------------------ |
|
||||
| `OPENCLAW_DOCKER_ALL_PARALLELISM` | 10 | 普通执行线的主池槽位数。 |
|
||||
| `OPENCLAW_DOCKER_ALL_TAIL_PARALLELISM` | 10 | 对提供商敏感的尾部池槽位数。 |
|
||||
| `OPENCLAW_DOCKER_ALL_LIVE_LIMIT` | 9 | 并发 live 执行线上限,避免提供商限流。 |
|
||||
| `OPENCLAW_DOCKER_ALL_NPM_LIMIT` | 10 | 并发 npm install 执行线上限。 |
|
||||
| `OPENCLAW_DOCKER_ALL_SERVICE_LIMIT` | 7 | 并发多服务执行线上限。 |
|
||||
| `OPENCLAW_DOCKER_ALL_START_STAGGER_MS` | 2000 | 执行线启动之间的错峰间隔,用于避免 Docker 守护进程创建风暴;设为 `0` 表示不错峰。 |
|
||||
| `OPENCLAW_DOCKER_ALL_LANE_TIMEOUT_MS` | 7200000 | 每条执行线的回退超时(120 分钟);选定的 live/尾部执行线会使用更严格的上限。 |
|
||||
| `OPENCLAW_DOCKER_ALL_DRY_RUN` | unset | `1` 会打印调度器计划而不运行执行线。 |
|
||||
| `OPENCLAW_DOCKER_ALL_LANES` | unset | 以逗号分隔的精确执行线列表;会跳过清理 smoke,以便智能体复现某一条失败的执行线。 |
|
||||
|
||||
重于其有效上限的任务通道仍可从空池启动,然后独占运行,直到它释放容量。本地聚合会预检 Docker、移除陈旧的 OpenClaw E2E 容器、输出活跃任务通道 Status、持久化任务通道耗时以支持最长优先排序,并且默认在首次失败后停止调度新的池化任务通道。
|
||||
比有效上限更重的执行线仍可从空池启动,然后会独占运行,直到释放容量。本地聚合会预检 Docker、移除陈旧的 OpenClaw E2E 容器、输出活跃执行线状态、持久化执行线耗时以支持最长优先排序,并且默认在第一次失败后停止调度新的池化执行线。
|
||||
|
||||
### 可复用的实测/E2E 工作流
|
||||
### 可复用的 live/E2E 工作流
|
||||
|
||||
可复用的实测/E2E 工作流会询问 `scripts/test-docker-all.mjs --plan-json` 需要哪些包、镜像类型、实测镜像、任务通道和凭证覆盖。随后 `scripts/docker-e2e.mjs` 会把该计划转换为 GitHub 输出和摘要。它会通过 `scripts/package-openclaw-for-docker.mjs` 打包 OpenClaw,下载当前运行的包构件,或者从 `package_artifact_run_id` 下载包构件;验证 tarball 清单;当计划需要已安装包的任务通道时,通过 Blacksmith 的 Docker 层缓存构建并推送带包摘要标签的 bare/functional GHCR Docker E2E 镜像;并复用提供的 `docker_e2e_bare_image`/`docker_e2e_functional_image` 输入或现有的包摘要镜像,而不是重新构建。Docker 镜像拉取会使用每次尝试 180 秒的有界超时进行重试,因此卡住的 registry/cache 流会快速重试,而不是消耗 CI 关键路径的大部分时间。
|
||||
可复用的 live/E2E 工作流会询问 `scripts/test-docker-all.mjs --plan-json` 需要哪些 package、镜像类型、live 镜像、执行线和凭证覆盖范围。随后 `scripts/docker-e2e.mjs` 会把该计划转换为 GitHub 输出和摘要。它会通过 `scripts/package-openclaw-for-docker.mjs` 打包 OpenClaw、下载当前运行的 package 构件,或从 `package_artifact_run_id` 下载 package 构件;验证 tarball 清单;当计划需要已安装 package 的执行线时,通过 Blacksmith 的 Docker layer cache 构建并推送带 package digest 标签的 bare/functional GHCR Docker E2E 镜像;并复用提供的 `docker_e2e_bare_image`/`docker_e2e_functional_image` 输入或现有 package digest 镜像,而不是重新构建。Docker 镜像拉取会使用每次尝试 180 秒的有界超时重试,因此卡住的 registry/cache 流会快速重试,而不会消耗 CI 关键路径的大部分时间。
|
||||
|
||||
### 发布路径分块
|
||||
|
||||
发布 Docker 覆盖使用较小的分块作业运行,并设置 `OPENCLAW_SKIP_DOCKER_BUILD=1`,因此每个分块只拉取它需要的镜像类型,并通过同一个加权调度器执行多个任务通道:
|
||||
发布 Docker 覆盖会使用 `OPENCLAW_SKIP_DOCKER_BUILD=1` 运行更小的分块任务,因此每个分块只拉取自己需要的镜像类型,并通过同一个加权调度器执行多条执行线:
|
||||
|
||||
- `OPENCLAW_DOCKER_ALL_PROFILE=release-path`
|
||||
- `OPENCLAW_DOCKER_ALL_CHUNK=core | package-update-openai | package-update-anthropic | package-update-core | plugins-runtime-plugins | plugins-runtime-services | plugins-runtime-install-a..h`
|
||||
|
||||
当前的发布 Docker 分块是 `core`、`package-update-openai`、`package-update-anthropic`、`package-update-core`、`plugins-runtime-plugins`、`plugins-runtime-services`,以及从 `plugins-runtime-install-a` 到 `plugins-runtime-install-h`。`plugins-runtime-core`、`plugins-runtime` 和 `plugins-integrations` 保持为聚合插件/运行时别名。`install-e2e` 任务通道别名保持为两个提供商安装器任务通道的聚合手动重跑别名。
|
||||
当前发布 Docker 分块包括 `core`、`package-update-openai`、`package-update-anthropic`、`package-update-core`、`plugins-runtime-plugins`、`plugins-runtime-services`,以及从 `plugins-runtime-install-a` 到 `plugins-runtime-install-h`。`plugins-runtime-core`、`plugins-runtime` 和 `plugins-integrations` 仍是聚合插件/运行时别名。`install-e2e` 执行线别名仍是两个提供商安装器执行线的聚合手动重跑别名。
|
||||
|
||||
当完整发布路径覆盖请求 OpenWebUI 时,OpenWebUI 会并入 `plugins-runtime-services`,并且只为仅 OpenWebUI 的分发保留独立的 `openwebui` 分块。内置渠道更新任务通道会针对临时 npm 网络失败重试一次。
|
||||
当完整发布路径覆盖请求 OpenWebUI 时,它会被并入 `plugins-runtime-services`;只有 OpenWebUI 专用调度才保留独立的 `openwebui` 分块。内置渠道更新执行线会针对临时 npm 网络失败重试一次。
|
||||
|
||||
每个分块都会上传 `.artifacts/docker-tests/`,其中包含任务通道日志、耗时、`summary.json`、`failures.json`、阶段耗时、调度器计划 JSON、慢任务通道表,以及每个任务通道的重跑命令。工作流的 `docker_lanes` 输入会针对准备好的镜像运行选定任务通道,而不是运行分块作业,这会把失败任务通道调试限制在一个有目标的 Docker 作业内,并为该运行准备、下载或复用包构件;如果选定任务通道是实测 Docker 任务通道,则目标作业会为该次重跑在本地构建实测镜像。生成的每个任务通道 GitHub 重跑命令会在这些值存在时包含 `package_artifact_run_id`、`package_artifact_name` 和准备好的镜像输入,因此失败的任务通道可以复用失败运行中的精确包和镜像。
|
||||
每个分块都会上传 `.artifacts/docker-tests/`,其中包含执行线日志、耗时、`summary.json`、`failures.json`、阶段耗时、调度器计划 JSON、慢执行线表,以及逐执行线重跑命令。工作流的 `docker_lanes` 输入会针对准备好的镜像运行选定执行线,而不是运行分块任务,这能把失败执行线调试限制在一个有针对性的 Docker 任务内,并为该次运行准备、下载或复用 package 构件;如果选定执行线是 live Docker 执行线,定向任务会为该次重跑在本地构建 live-test 镜像。生成的逐执行线 GitHub 重跑命令会在这些值存在时包含 `package_artifact_run_id`、`package_artifact_name` 和准备好的镜像输入,因此失败执行线可以复用失败运行中的确切 package 和镜像。
|
||||
|
||||
```bash
|
||||
pnpm test:docker:rerun <run-id> # download Docker artifacts and print combined/per-lane targeted rerun commands
|
||||
pnpm test:docker:timings <summary> # slow-lane and phase critical-path summaries
|
||||
```
|
||||
|
||||
定时实测/E2E 工作流每天运行完整的发布路径 Docker 套件。
|
||||
定时 live/E2E 工作流每天运行完整的发布路径 Docker 套件。
|
||||
|
||||
## 插件预发布
|
||||
|
||||
`Plugin Prerelease` 是成本更高的产品/包覆盖,因此它是一个单独的工作流,由 `Full Release Validation` 或显式操作员分发。普通拉取请求、`main` 推送和独立的手动 CI 分发不会开启该套件。它会在八个插件工作器之间均衡内置插件测试;这些插件分片作业每次最多运行两个插件配置组,每组使用一个 Vitest worker 和更大的 Node 堆,因此导入较重的插件批次不会创建额外的 CI 作业。仅发布的 Docker 预发布路径会以小组批处理目标 Docker 任务通道,避免为一到三分钟的作业保留数十个 runner。
|
||||
`Plugin Prerelease` 是成本更高的产品/package 覆盖,因此它是一个独立工作流,由 `Full Release Validation` 或明确的操作员调度。普通 pull request、`main` 推送和独立的手动 CI 调度都会关闭该套件。它会在八个扩展 worker 之间均衡内置插件测试;这些扩展分片任务每次最多运行两个插件配置组,每组使用一个 Vitest worker 和更大的 Node heap,这样导入密集型插件批次就不会创建额外 CI 任务。仅发布的 Docker 预发布路径会把定向 Docker 执行线按小组批处理,避免为一到三分钟的任务预留数十个 runner。
|
||||
|
||||
## QA Lab
|
||||
|
||||
QA Lab 在主智能范围工作流之外有专用 CI 任务通道。
|
||||
QA Lab 在主智能作用域工作流之外拥有专用 CI 执行线。
|
||||
|
||||
- `Parity gate` 工作流在匹配的 PR 变更和手动分发时运行;它构建私有 QA 运行时,并比较 mock GPT-5.5 和 Opus 4.6 agentic 包。
|
||||
- `QA-Lab - All Lanes` 工作流每晚在 `main` 上运行,也可手动分发;它会把 mock parity gate、实测 Matrix 任务通道、以及实测 Telegram 和 Discord 任务通道作为并行作业展开。实测作业使用 `qa-live-shared` 环境,Telegram/Discord 使用 Convex 租约。
|
||||
- `Parity gate` 工作流会在匹配的 PR 变更和手动调度时运行;它会构建私有 QA 运行时,并比较 mock GPT-5.5 和 Opus 4.6 agentic packs。
|
||||
- `QA-Lab - All Lanes` 工作流会在 `main` 上每晚运行,也会在手动调度时运行;它会把 mock parity gate、live Matrix 执行线,以及 live Telegram 和 Discord 执行线并行展开为任务。Live 任务使用 `qa-live-shared` 环境,Telegram/Discord 使用 Convex leases。
|
||||
|
||||
发布检查会使用确定性的 mock 提供商和 mock 限定模型(`mock-openai/gpt-5.5` 和 `mock-openai/gpt-5.5-alt`)运行 Matrix 和 Telegram 实测传输任务通道,因此渠道契约会与实测模型延迟和常规提供商插件启动隔离。实测传输 Gateway 网关会禁用记忆搜索,因为 QA parity 会单独覆盖记忆行为;提供商连接性由独立的实测模型、原生提供商和 Docker 提供商套件覆盖。
|
||||
发布检查会使用确定性的 mock 提供商和 mock 限定模型(`mock-openai/gpt-5.5` 和 `mock-openai/gpt-5.5-alt`)运行 Matrix 和 Telegram live 传输执行线,因此渠道契约会与 live 模型延迟和普通提供商插件启动隔离。live 传输 Gateway 网关会禁用记忆搜索,因为 QA parity 会单独覆盖记忆行为;提供商连通性由独立的 live 模型、原生提供商和 Docker 提供商套件覆盖。
|
||||
|
||||
Matrix 对定时和发布 gate 使用 `--profile fast`,仅当检出的 CLI 支持时才添加 `--fail-fast`。CLI 默认值和手动工作流输入保持为 `all`;手动 `matrix_profile=all` 分发始终会把完整 Matrix 覆盖分片为 `transport`、`media`、`e2ee-smoke`、`e2ee-deep` 和 `e2ee-cli` 作业。
|
||||
Matrix 对定时和发布门禁使用 `--profile fast`,并且只有在检出的 CLI 支持时才添加 `--fail-fast`。CLI 默认值和手动工作流输入仍为 `all`;手动 `matrix_profile=all` 调度始终会把完整 Matrix 覆盖分片为 `transport`、`media`、`e2ee-smoke`、`e2ee-deep` 和 `e2ee-cli` 任务。
|
||||
|
||||
`OpenClaw Release Checks` 也会在发布批准前运行发布关键的 QA Lab 任务通道;其 QA parity gate 会把候选包和基线包作为并行任务通道作业运行,然后将两个构件下载到一个小型报告作业中,用于最终的 parity 比较。
|
||||
`OpenClaw Release Checks` 也会在发布批准前运行发布关键的 QA Lab 执行线;它的 QA parity gate 会把候选包和基线包作为并行执行线任务运行,然后把两个构件下载到一个小型报告任务中,用于最终 parity 比较。
|
||||
|
||||
不要把 PR 落地路径置于 `Parity gate` 之后,除非变更实际触及 QA 运行时、模型包 parity,或 parity 工作流拥有的表面。对于常规渠道、配置、文档或单元测试修复,把它视为可选信号,并遵循有范围的 CI/检查证据。
|
||||
不要把 PR 落地路径放在 `Parity gate` 后面,除非变更确实触及 QA 运行时、模型包 parity,或 parity 工作流拥有的表面。对于普通渠道、配置、文档或单元测试修复,应把它视为可选信号,并遵循作用域化的 CI/检查证据。
|
||||
|
||||
## CodeQL
|
||||
|
||||
`CodeQL` 工作流有意作为范围较窄的第一轮安全扫描器,而不是完整仓库扫描。每日、手动和非草稿拉取请求 guard 运行会扫描 Actions 工作流代码,以及最高风险的 JavaScript/TypeScript 表面,并使用过滤到高/严重 `security-severity` 的高置信度安全查询。
|
||||
`CodeQL` 工作流是有意保持狭窄的第一轮安全扫描器,而不是完整仓库扫描。每日、手动和非草稿 pull request 保护运行会扫描 Actions 工作流代码,以及风险最高的 JavaScript/TypeScript 表面,并使用过滤到高/严重 `security-severity` 的高置信度安全查询。
|
||||
|
||||
拉取请求 guard 保持轻量:它只针对 `.github/actions`、`.github/codeql`、`.github/workflows`、`packages` 或 `src` 下的变更启动,并运行与定时工作流相同的高置信度安全矩阵。Android 和 macOS CodeQL 不进入 PR 默认项。
|
||||
pull request 保护保持轻量:它只会针对 `.github/actions`、`.github/codeql`、`.github/workflows`、`packages` 或 `src` 下的变更启动,并运行与定时工作流相同的高置信度安全矩阵。Android 和 macOS CodeQL 不包含在 PR 默认项中。
|
||||
|
||||
### 安全类别
|
||||
|
||||
| 类别 | 表面 |
|
||||
| 类别 | 表面 |
|
||||
| ------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `/codeql-security-high/core-auth-secrets` | 凭证、secret、沙箱、cron 和 Gateway 网关基线 |
|
||||
| `/codeql-security-high/channel-runtime-boundary` | 核心渠道实现契约,加上渠道插件运行时、Gateway 网关、插件 SDK、secret、审计接触点 |
|
||||
| `/codeql-security-high/network-ssrf-boundary` | 核心 SSRF、IP 解析、网络 guard、web-fetch,以及插件 SDK SSRF 策略表面 |
|
||||
| `/codeql-security-high/mcp-process-tool-boundary` | MCP 服务器、进程执行 helper、出站投递,以及智能体工具执行 gate |
|
||||
| `/codeql-security-high/plugin-trust-boundary` | 插件安装、加载器、manifest、registry、包管理器安装、源码加载,以及插件 SDK 包契约信任表面 |
|
||||
| `/codeql-security-high/core-auth-secrets` | Auth、secrets、沙箱、cron 和 gateway baseline |
|
||||
| `/codeql-security-high/channel-runtime-boundary` | 核心渠道实现契约,加上渠道插件运行时、Gateway 网关、插件 SDK、secrets、audit 触点 |
|
||||
| `/codeql-security-high/network-ssrf-boundary` | 核心 SSRF、IP parsing、network guard、web-fetch,以及插件 SDK SSRF policy 表面 |
|
||||
| `/codeql-security-high/mcp-process-tool-boundary` | MCP servers、process execution helpers、outbound delivery,以及智能体工具执行门禁 |
|
||||
| `/codeql-security-high/plugin-trust-boundary` | 插件安装、loader、manifest、registry、package-manager install、source-loading,以及插件 SDK package contract trust 表面 |
|
||||
|
||||
### 平台特定安全分片
|
||||
### 特定平台安全分片
|
||||
|
||||
- `CodeQL Android Critical Security` — 定时 Android 安全分片。在工作流 sanity 接受的最小 Blacksmith Linux runner 上为 CodeQL 手动构建 Android 应用。上传到 `/codeql-critical-security/android` 下。
|
||||
- `CodeQL macOS Critical Security` — 每周/手动 macOS 安全分片。在 Blacksmith macOS 上为 CodeQL 手动构建 macOS 应用,从上传的 SARIF 中过滤依赖构建结果,并上传到 `/codeql-critical-security/macos` 下。它保留在每日默认项之外,因为即使干净时 macOS 构建也会主导运行时间。
|
||||
- `CodeQL Android Critical Security` — 定时 Android 安全分片。在 workflow sanity 接受的最小 Blacksmith Linux runner 上手动构建 Android app,用于 CodeQL。上传到 `/codeql-critical-security/android` 下。
|
||||
- `CodeQL macOS Critical Security` — 每周/手动 macOS 安全分片。在 Blacksmith macOS 上手动构建 macOS app,用于 CodeQL,从上传的 SARIF 中过滤 dependency build 结果,并上传到 `/codeql-critical-security/macos` 下。它保留在每日默认项之外,因为即使干净时,macOS build 也会主导运行时间。
|
||||
|
||||
### 关键质量类别
|
||||
|
||||
`CodeQL Critical Quality` 是对应的非安全分片。它只在较小的 Blacksmith Linux runner 上,对较窄的高价值表面运行错误严重性、非安全的 JavaScript/TypeScript 质量查询。它的拉取请求 guard 有意小于定时配置:非草稿 PR 只会针对智能体命令/模型/工具执行和回复分发代码、配置 schema/迁移/IO 代码、凭证/secret/沙箱/安全代码、核心渠道和内置渠道插件运行时、Gateway 网关协议/server-method、记忆运行时/SDK 胶水代码、MCP/进程/出站投递、提供商运行时/模型目录、会话诊断/投递队列、插件加载器、插件 SDK/包契约,或插件 SDK 回复运行时变更,运行匹配的 `agent-runtime-boundary`、`config-boundary`、`core-auth-secrets`、`channel-runtime-boundary`、`gateway-runtime-boundary`、`memory-runtime-boundary`、`mcp-process-runtime-boundary`、`provider-runtime-boundary`、`session-diagnostics-boundary`、`plugin-boundary`、`plugin-sdk-package-contract` 和 `plugin-sdk-reply-runtime` 分片。CodeQL 配置和质量工作流变更会运行全部十二个 PR 质量分片。
|
||||
`CodeQL Critical Quality` 是对应的非安全分片。它只会在较小的 Blacksmith Linux runner 上,对狭窄的高价值表面运行 error-severity、非安全 JavaScript/TypeScript 质量查询。它的 pull request 保护有意小于定时 profile:非草稿 PR 只会针对智能体命令/模型/工具执行和回复分发代码、配置 schema/迁移/IO 代码、auth/secrets/沙箱/security 代码、核心渠道和内置渠道插件运行时、Gateway 网关 protocol/server-method、记忆运行时/SDK glue、MCP/process/outbound delivery、提供商运行时/模型目录、会话 diagnostics/delivery queues、插件 loader、插件 SDK/package-contract,或插件 SDK reply runtime 变更,运行匹配的 `agent-runtime-boundary`、`config-boundary`、`core-auth-secrets`、`channel-runtime-boundary`、`gateway-runtime-boundary`、`memory-runtime-boundary`、`mcp-process-runtime-boundary`、`provider-runtime-boundary`、`session-diagnostics-boundary`、`plugin-boundary`、`plugin-sdk-package-contract` 和 `plugin-sdk-reply-runtime` 分片。CodeQL 配置和质量工作流变更会运行全部十二个 PR 质量分片。
|
||||
|
||||
手动分发接受:
|
||||
手动调度接受:
|
||||
|
||||
```
|
||||
profile=all|agent-runtime-boundary|config-boundary|core-auth-secrets|channel-runtime-boundary|gateway-runtime-boundary|memory-runtime-boundary|mcp-process-runtime-boundary|plugin-boundary|plugin-sdk-package-contract|plugin-sdk-reply-runtime|provider-runtime-boundary|session-diagnostics-boundary
|
||||
```
|
||||
|
||||
窄配置是用于单独运行一个质量分片的教学/迭代钩子。
|
||||
狭窄 profile 是用于单独运行一个质量分片的教学/迭代钩子。
|
||||
|
||||
| 类别 | 涉及面 |
|
||||
| ------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `/codeql-critical-quality/core-auth-secrets` | 认证、密钥、沙箱、cron 和 Gateway 网关安全边界代码 |
|
||||
| `/codeql-critical-quality/config-boundary` | 配置 schema、迁移、规范化和 IO 契约 |
|
||||
| `/codeql-critical-quality/gateway-runtime-boundary` | Gateway 网关协议 schema 和服务器方法契约 |
|
||||
| `/codeql-critical-quality/channel-runtime-boundary` | 核心渠道和内置渠道插件实现契约 |
|
||||
| `/codeql-critical-quality/agent-runtime-boundary` | 命令执行、模型/提供商分发、自动回复分发和队列,以及 ACP 控制平面运行时契约 |
|
||||
| `/codeql-critical-quality/mcp-process-runtime-boundary` | MCP 服务器和工具桥接、进程监督辅助工具,以及出站投递契约 |
|
||||
| `/codeql-critical-quality/memory-runtime-boundary` | 记忆宿主 SDK、记忆运行时门面、记忆插件 SDK 别名、记忆运行时激活粘合层,以及记忆 doctor 命令 |
|
||||
| `/codeql-critical-quality/session-diagnostics-boundary` | 回复队列内部机制、会话投递队列、出站会话绑定/投递辅助工具、诊断事件/日志包表面,以及会话 doctor CLI 契约 |
|
||||
| `/codeql-critical-quality/plugin-sdk-reply-runtime` | 插件 SDK 入站回复分发、回复载荷/分块/运行时辅助工具、渠道回复选项、投递队列,以及会话/线程绑定辅助工具 |
|
||||
| `/codeql-critical-quality/provider-runtime-boundary` | 模型目录规范化、提供商认证和设备发现、提供商运行时注册、提供商默认值/目录,以及 web/搜索/抓取/嵌入注册表 |
|
||||
| `/codeql-critical-quality/ui-control-plane` | 控制 UI 启动、本地持久化、Gateway 网关控制流,以及任务控制平面运行时契约 |
|
||||
| `/codeql-critical-quality/web-media-runtime-boundary` | 核心 web 抓取/搜索、媒体 IO、媒体理解、图像生成和媒体生成运行时契约 |
|
||||
| `/codeql-critical-quality/plugin-boundary` | 加载器、注册表、公共表面和插件 SDK 入口点契约 |
|
||||
| `/codeql-critical-quality/plugin-sdk-package-contract` | 已发布包侧插件 SDK 源码和插件包契约辅助工具 |
|
||||
| 类别 | 范围 |
|
||||
| ------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
||||
| `/codeql-critical-quality/core-auth-secrets` | 身份验证、机密、沙箱、cron 和 Gateway 网关安全边界代码 |
|
||||
| `/codeql-critical-quality/config-boundary` | 配置 schema、迁移、规范化和 IO 契约 |
|
||||
| `/codeql-critical-quality/gateway-runtime-boundary` | Gateway 网关协议 schema 和服务器方法契约 |
|
||||
| `/codeql-critical-quality/channel-runtime-boundary` | 核心渠道和内置渠道插件实现契约 |
|
||||
| `/codeql-critical-quality/agent-runtime-boundary` | 命令执行、模型/提供商分发、自动回复分发与队列,以及 ACP 控制平面运行时契约 |
|
||||
| `/codeql-critical-quality/mcp-process-runtime-boundary` | MCP 服务器和工具桥接、进程监控 helper,以及出站投递契约 |
|
||||
| `/codeql-critical-quality/memory-runtime-boundary` | 记忆宿主 SDK、记忆运行时 facade、记忆插件 SDK 别名、记忆运行时激活粘合逻辑,以及记忆 Doctor 命令 |
|
||||
| `/codeql-critical-quality/session-diagnostics-boundary` | 回复队列内部机制、会话投递队列、出站会话绑定/投递 helper、诊断事件/日志 bundle 接口,以及会话 Doctor CLI 契约 |
|
||||
| `/codeql-critical-quality/plugin-sdk-reply-runtime` | 插件 SDK 入站回复分发、回复 payload/分块/运行时 helper、渠道回复选项、投递队列,以及会话/thread 绑定 helper |
|
||||
| `/codeql-critical-quality/provider-runtime-boundary` | 模型目录规范化、提供商身份验证与设备发现、提供商运行时注册、提供商默认值/目录,以及 web/search/fetch/embedding 注册表 |
|
||||
| `/codeql-critical-quality/ui-control-plane` | 控制 UI 启动、本地持久化、Gateway 网关控制流,以及任务控制平面运行时契约 |
|
||||
| `/codeql-critical-quality/web-media-runtime-boundary` | 核心 web fetch/search、媒体 IO、媒体理解、图像生成和媒体生成运行时契约 |
|
||||
| `/codeql-critical-quality/plugin-boundary` | 加载器、注册表、公开接口和插件 SDK 入口点契约 |
|
||||
| `/codeql-critical-quality/plugin-sdk-package-contract` | 已发布 package 侧插件 SDK 源码和插件 package 契约 helper |
|
||||
|
||||
质量与安全保持分离,这样质量发现就可以被排期、衡量、禁用或扩展,而不会掩盖安全信号。只有在窄配置文件具备稳定运行时和信号之后,才应将 Swift、Python 和内置插件 CodeQL 扩展作为有范围或分片的后续工作加回。
|
||||
质量与安全保持分离,这样质量发现可以被排期、度量、禁用或扩展,而不会遮蔽安全信号。Swift、Python 和内置插件 CodeQL 扩展应仅在窄配置文件具备稳定运行时和稳定信号后,作为有作用域或分片的后续工作加回。
|
||||
|
||||
## 维护工作流
|
||||
|
||||
### Docs Agent
|
||||
### 文档智能体
|
||||
|
||||
`Docs Agent` 工作流是一个事件驱动的 Codex 维护通道,用于让现有文档与最近落地的变更保持一致。它没有纯定时计划:`main` 上一次成功的非机器人 push CI 运行可以触发它,手动分发也可以直接运行它。当 `main` 已继续前进,或过去一小时内已创建另一个未跳过的 Docs Agent 运行时,workflow-run 调用会跳过。运行时,它会审查从上一个未跳过的 Docs Agent 源 SHA 到当前 `main` 的提交范围,因此每小时一次运行可以覆盖自上次文档处理以来累积的所有 main 变更。
|
||||
`Docs Agent` 工作流是一个事件驱动的 Codex 维护通道,用于让现有文档与最近落地的更改保持一致。它没有纯定时计划:`main` 上一次成功的非 bot push CI 运行可以触发它,手动分发也可以直接运行它。当 `main` 已经向前移动,或过去一小时内已经创建过另一个未跳过的 Docs Agent 运行时,workflow-run 调用会跳过。运行时,它会审查从上一次未跳过的 Docs Agent 源 SHA 到当前 `main` 的提交范围,因此每小时一次运行可以覆盖自上次文档检查以来累积的所有 main 更改。
|
||||
|
||||
### Test Performance Agent
|
||||
### 测试性能智能体
|
||||
|
||||
`Test Performance Agent` 工作流是一个事件驱动的 Codex 维护通道,用于处理慢测试。它没有纯定时计划:`main` 上一次成功的非机器人 push CI 运行可以触发它,但如果当天 UTC 已有另一个 workflow-run 调用运行过或正在运行,它会跳过。手动分发会绕过这个每日活动门禁。该通道会构建全套分组 Vitest 性能报告,让 Codex 只做小型、保持覆盖率的测试性能修复,而不是大范围重构,然后重新运行全套报告,并拒绝会降低通过基线测试数量的变更。如果基线存在失败测试,Codex 只能修复明显的失败,并且智能体执行后的全套报告必须通过,才会提交任何内容。当 `main` 在机器人 push 落地前前进时,该通道会 rebase 已验证的补丁,重新运行 `pnpm check:changed`,并重试 push;有冲突的陈旧补丁会被跳过。它使用 GitHub 托管的 Ubuntu,因此 Codex action 可以保持与 docs agent 相同的 drop-sudo 安全姿态。
|
||||
`Test Performance Agent` 工作流是一个事件驱动的 Codex 维护通道,用于处理慢测试。它没有纯定时计划:`main` 上一次成功的非 bot push CI 运行可以触发它,但如果当天 UTC 已经有另一个 workflow-run 调用运行过或正在运行,它会跳过。手动分发会绕过这个每日活动门禁。该通道会构建一个全套分组 Vitest 性能报告,让 Codex 只做保留覆盖率的小型测试性能修复,而不是大范围重构,然后重新运行全套报告,并拒绝会降低通过基线测试数量的更改。如果基线存在失败测试,Codex 只能修复明显失败,并且 after-agent 全套报告必须在提交任何内容前通过。当 `main` 在 bot push 落地前前进时,该通道会 rebase 已验证的补丁,重新运行 `pnpm check:changed`,然后重试 push;有冲突的过期补丁会被跳过。它使用 GitHub 托管的 Ubuntu,因此 Codex action 可以保持与 docs agent 相同的 drop-sudo 安全姿态。
|
||||
|
||||
### 合并后的重复 PR
|
||||
|
||||
`Duplicate PRs After Merge` 工作流是用于落地后重复项清理的手动维护者工作流。它默认 dry-run,且仅在 `apply=true` 时关闭显式列出的 PR。在修改 GitHub 之前,它会验证已落地的 PR 已合并,并验证每个重复项要么有共享的引用 issue,要么有重叠的变更 hunk。
|
||||
`Duplicate PRs After Merge` 工作流是一个手动维护者工作流,用于落地后的重复项清理。它默认 dry-run,并且只有在 `apply=true` 时才会关闭显式列出的 PR。在变更 GitHub 之前,它会验证落地 PR 已合并,并验证每个重复项要么有共享的引用 issue,要么有重叠的变更 hunk。
|
||||
|
||||
```bash
|
||||
gh workflow run duplicate-after-merge.yml \
|
||||
@ -418,27 +427,27 @@ gh workflow run duplicate-after-merge.yml \
|
||||
|
||||
## 本地检查门禁和变更路由
|
||||
|
||||
本地变更通道逻辑位于 `scripts/changed-lanes.mjs`,并由 `scripts/check-changed.mjs` 执行。与宽泛的 CI 平台范围相比,该本地检查门禁对架构边界更严格:
|
||||
本地 changed-lane 逻辑位于 `scripts/changed-lanes.mjs`,并由 `scripts/check-changed.mjs` 执行。这个本地检查门禁在架构边界上比宽泛的 CI 平台范围更严格:
|
||||
|
||||
- 核心生产变更会运行核心生产和核心测试 typecheck,以及核心 lint/guard;
|
||||
- 仅核心测试变更只运行核心测试 typecheck 和核心 lint;
|
||||
- 插件生产变更会运行插件生产和插件测试 typecheck,以及插件 lint;
|
||||
- 仅插件测试变更会运行插件测试 typecheck 和插件 lint;
|
||||
- 公共插件 SDK 或插件契约变更会扩展到插件 typecheck,因为插件依赖这些核心契约(Vitest 插件扫测仍是显式测试工作);
|
||||
- 仅发布元数据的版本号提升会运行有针对性的版本/配置/根依赖检查;
|
||||
- 未知的根目录/配置变更会 fail safe 到所有检查通道。
|
||||
- 核心生产更改会运行核心 prod 和核心 test 类型检查,加上核心 lint/guard;
|
||||
- 仅核心测试的更改只运行核心 test 类型检查,加上核心 lint;
|
||||
- 插件生产更改会运行插件 prod 和插件 test 类型检查,加上插件 lint;
|
||||
- 仅插件测试的更改会运行插件 test 类型检查,加上插件 lint;
|
||||
- 公开插件 SDK 或插件契约更改会扩展到插件类型检查,因为插件依赖这些核心契约(Vitest 插件 sweep 仍然是显式测试工作);
|
||||
- 仅发布元数据的版本 bump 会运行定向版本/配置/root-dependency 检查;
|
||||
- 未知 root/配置更改会 fail safe 到所有检查通道。
|
||||
|
||||
本地变更测试路由位于 `scripts/test-projects.test-support.mjs`,并且刻意比 `check:changed` 更轻量:直接测试编辑会运行自身,源码编辑优先使用显式映射,然后是同级测试和导入图依赖项。共享群组房间投递配置是显式映射之一:对群组可见回复配置、源码回复投递模式或消息工具系统提示词的变更,会通过核心回复测试以及 Discord 和 Slack 投递回归测试进行路由,因此共享默认值变更会在第一次 PR push 前失败。只有当变更的范围足够覆盖整个 harness,以至于廉价映射集合不是可信代理时,才使用 `OPENCLAW_TEST_CHANGED_BROAD=1 pnpm test:changed`。
|
||||
本地 changed-test 路由位于 `scripts/test-projects.test-support.mjs`,并且有意比 `check:changed` 更轻量:直接测试编辑会运行自身,源代码编辑优先使用显式映射,然后是 sibling 测试和 import-graph 依赖项。共享 group-room 投递配置是显式映射之一:对 group 可见回复配置、源回复投递模式或 message-tool 系统提示词的更改,会经过核心回复测试以及 Discord 和 Slack 投递回归,因此共享默认值更改会在第一次 PR push 前失败。仅当更改足够覆盖整个 harness,以至于低成本映射集不是可信代理时,才使用 `OPENCLAW_TEST_CHANGED_BROAD=1 pnpm test:changed`。
|
||||
|
||||
## Testbox 验证
|
||||
|
||||
从仓库根目录运行 Testbox,并优先为宽泛证明使用新预热的 box。在把慢门禁花在一个被复用、已过期或刚刚报告意外大同步的 box 上之前,先在 box 内运行 `pnpm testbox:sanity`。
|
||||
从 repo root 运行 Testbox,并且对宽泛证明优先使用一个新的 warmed box。在把慢门禁花到一个被复用、已过期或刚刚报告了异常大同步的 box 上之前,先在 box 内运行 `pnpm testbox:sanity`。
|
||||
|
||||
当 `pnpm-lock.yaml` 等必需根文件消失,或 `git status --short` 显示至少 200 个已跟踪删除时,完整性检查会快速失败。这通常意味着远程同步状态不是 PR 的可信副本;停止该 box 并预热一个新的,而不是调试产品测试失败。对于有意的大量删除 PR,为该完整性检查运行设置 `OPENCLAW_TESTBOX_ALLOW_MASS_DELETIONS=1`。
|
||||
当必需的 root 文件(例如 `pnpm-lock.yaml`)消失,或 `git status --short` 显示至少 200 个已跟踪删除时,完整性检查会快速失败。这通常意味着远程同步状态不是 PR 的可信副本;停止该 box 并 warm 一个新的,而不是调试产品测试失败。对于有意的大规模删除 PR,为那次 sanity 运行设置 `OPENCLAW_TESTBOX_ALLOW_MASS_DELETIONS=1`。
|
||||
|
||||
`pnpm testbox:run` 还会终止本地 Blacksmith CLI 调用,如果该调用在同步阶段停留超过五分钟且没有同步后输出。设置 `OPENCLAW_TESTBOX_SYNC_TIMEOUT_MS=0` 可禁用该 guard,或为异常大的本地 diff 使用更大的毫秒值。
|
||||
`pnpm testbox:run` 也会终止本地 Blacksmith CLI 调用,如果它在同步阶段停留超过五分钟且没有同步后输出。设置 `OPENCLAW_TESTBOX_SYNC_TIMEOUT_MS=0` 可禁用该 guard,或者对异常大的本地 diff 使用更大的毫秒值。
|
||||
|
||||
Crabbox 是仓库自有的第二条远程 box 路径,用于在 Blacksmith 不可用或更适合使用自有云容量时进行 Linux 证明。预热一个 box,通过项目工作流对其 hydrate,然后通过 Crabbox CLI 运行命令:
|
||||
当 Blacksmith 不可用或更适合使用自有云容量时,Crabbox 是 repo 拥有的第二条远程 box Linux 证明路径。Warm 一个 box,通过项目工作流 hydrate 它,然后通过 Crabbox CLI 运行命令:
|
||||
|
||||
```bash
|
||||
pnpm crabbox:warmup -- --idle-timeout 90m
|
||||
@ -447,9 +456,9 @@ pnpm crabbox:run -- --id <cbx_id> --shell "OPENCLAW_TESTBOX=1 pnpm check:changed
|
||||
pnpm crabbox:stop -- <cbx_id>
|
||||
```
|
||||
|
||||
`.crabbox.yaml` 管理提供商、同步和 GitHub Actions hydrate 默认值。它会排除本地 `.git`,因此 hydrate 后的 Actions checkout 会保留自己的远程 Git 元数据,而不是同步维护者本地的 remotes 和对象存储;它还会排除不应传输的本地运行时/构建产物。`.github/workflows/crabbox-hydrate.yml` 管理 checkout、Node/pnpm 设置、`origin/main` 抓取,以及后续 `crabbox run --id <cbx_id>` 命令会 source 的非密钥环境交接。
|
||||
`.crabbox.yaml` 管理提供商、同步和 GitHub Actions hydration 默认值。它会排除本地 `.git`,因此 hydrated Actions checkout 会保留自身的远程 Git 元数据,而不是同步维护者本地的 remote 和 object store;它还会排除绝不应传输的本地运行时/构建产物。`.github/workflows/crabbox-hydrate.yml` 管理 checkout、Node/pnpm 设置、`origin/main` fetch,以及后续 `crabbox run --id <cbx_id>` 命令会 source 的非机密环境交接。
|
||||
|
||||
## 相关内容
|
||||
## 相关
|
||||
|
||||
- [安装概览](/zh-CN/install)
|
||||
- [开发渠道](/zh-CN/install/development-channels)
|
||||
|
||||
@ -1,24 +1,24 @@
|
||||
---
|
||||
read_when:
|
||||
- 你需要定时任务和唤醒
|
||||
- 你正在调试 cron 的执行和日志
|
||||
- 你正在调试 cron 执行和日志
|
||||
summary: '`openclaw cron` 的 CLI 参考(调度并运行后台作业)'
|
||||
title: 定时调度
|
||||
title: 定时任务
|
||||
x-i18n:
|
||||
generated_at: "2026-04-30T08:43:44Z"
|
||||
generated_at: "2026-05-02T04:47:25Z"
|
||||
model: gpt-5.5
|
||||
provider: openai
|
||||
source_hash: 03d79e0e2c71f673c900b84eb2beeab705662c1d016e1d0567323c8da73060bb
|
||||
source_hash: 298ac3fc868462eb301febbc1aa5296d8087cad7fdc466870487081444c5856f
|
||||
source_path: cli/cron.md
|
||||
workflow: 16
|
||||
---
|
||||
|
||||
# `openclaw cron`
|
||||
|
||||
管理 Gateway 网关调度器的 cron 任务。
|
||||
管理 Gateway 网关调度器的 cron 作业。
|
||||
|
||||
<Tip>
|
||||
运行 `openclaw cron --help` 查看完整命令界面。概念指南见 [Cron 任务](/zh-CN/automation/cron-jobs)。
|
||||
运行 `openclaw cron --help` 查看完整命令界面。概念指南见 [cron 作业](/zh-CN/automation/cron-jobs)。
|
||||
</Tip>
|
||||
|
||||
## 会话
|
||||
@ -26,126 +26,130 @@ x-i18n:
|
||||
`--session` 接受 `main`、`isolated`、`current` 或 `session:<id>`。
|
||||
|
||||
<AccordionGroup>
|
||||
<Accordion title="Session keys">
|
||||
<Accordion title="会话键">
|
||||
- `main` 绑定到智能体的主会话。
|
||||
- `isolated` 会为每次运行创建新的转录和会话 id。
|
||||
- `isolated` 为每次运行创建新的转录记录和会话 ID。
|
||||
- `current` 绑定到创建时的活动会话。
|
||||
- `session:<id>` 固定到显式的持久会话键。
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="Isolated session semantics">
|
||||
隔离运行会重置环境会话上下文。渠道和群组路由、发送/排队策略、提权、来源以及 ACP 运行时绑定都会为新运行重置。安全偏好以及用户显式选择的模型或凭证覆盖可以跨运行保留。
|
||||
<Accordion title="隔离会话语义">
|
||||
隔离运行会重置环境对话上下文。渠道和群组路由、发送/排队策略、提权、来源以及 ACP 运行时绑定都会为新的运行重置。安全偏好以及用户显式选择的模型或认证覆盖项可以跨运行保留。
|
||||
</Accordion>
|
||||
</AccordionGroup>
|
||||
|
||||
## 交付
|
||||
## 投递
|
||||
|
||||
`openclaw cron list` 和 `openclaw cron show <job-id>` 会预览解析后的交付路由。对于 `channel: "last"`,预览会显示该路由是从主会话还是当前会话解析得到,或者会关闭失败。
|
||||
`openclaw cron list` 和 `openclaw cron show <job-id>` 会预览解析后的投递路由。对于 `channel: "last"`,预览会显示路由是从主会话还是当前会话解析而来,或将以关闭方式失败。
|
||||
|
||||
带提供商前缀的目标可以消除未解析公告渠道的歧义。例如,`to: "telegram:123"` 会在省略 `delivery.channel` 或其值为 `last` 时选择 Telegram。只有已加载插件声明的前缀才是提供商选择器。如果 `delivery.channel` 是显式的,前缀必须匹配该渠道;`channel: "whatsapp"` 搭配 `to: "telegram:123"` 会被拒绝。`imessage:` 和 `sms:` 等服务前缀仍然是渠道拥有的目标语法。
|
||||
|
||||
<Note>
|
||||
隔离的 `cron add` 任务默认使用 `--announce` 交付。使用 `--no-deliver` 可将输出保持为内部输出。`--deliver` 仍作为 `--announce` 的已弃用别名保留。
|
||||
隔离的 `cron add` 作业默认使用 `--announce` 投递。使用 `--no-deliver` 可将输出保留为内部输出。`--deliver` 仍作为 `--announce` 的已弃用别名保留。
|
||||
</Note>
|
||||
|
||||
### 交付所有权
|
||||
### 投递所有权
|
||||
|
||||
隔离 cron 聊天交付由智能体和运行器共享:
|
||||
隔离 cron 聊天投递由智能体和运行器共享:
|
||||
|
||||
- 当聊天路由可用时,智能体可以使用 `message` 工具直接发送。
|
||||
- 只有在智能体没有直接发送到解析后的目标时,`announce` 才会回退交付最终回复。
|
||||
- `webhook` 会将完成后的载荷发布到 URL。
|
||||
- `none` 会禁用运行器回退交付。
|
||||
- `announce` 仅在智能体未直接发送到解析目标时,才回退投递最终回复。
|
||||
- `webhook` 会将完成的载荷发布到 URL。
|
||||
- `none` 会禁用运行器回退投递。
|
||||
|
||||
`--announce` 是最终回复的运行器回退交付。`--no-deliver` 会禁用该回退,但当聊天路由可用时,不会移除智能体的 `message` 工具。
|
||||
`--announce` 是运行器对最终回复的回退投递。`--no-deliver` 会禁用该回退,但当聊天路由可用时,不会移除智能体的 `message` 工具。
|
||||
|
||||
从活动聊天创建的提醒会保留实时聊天交付目标,用于回退 announce 交付。内部会话键可能是小写;不要将其用作区分大小写的提供商 ID(例如 Matrix 房间 ID)的真实来源。
|
||||
从活动聊天创建的提醒会保留实时聊天投递目标,以便进行回退公告投递。内部会话键可能是小写;不要将它们用作 Matrix 房间 ID 等区分大小写的提供商 ID 的事实来源。
|
||||
|
||||
### 失败交付
|
||||
### 失败投递
|
||||
|
||||
失败通知按以下顺序解析:
|
||||
|
||||
1. 任务上的 `delivery.failureDestination`。
|
||||
1. 作业上的 `delivery.failureDestination`。
|
||||
2. 全局 `cron.failureDestination`。
|
||||
3. 任务的主要 announce 目标(未设置显式失败目标时)。
|
||||
3. 作业的主要公告目标(未设置显式失败目标时)。
|
||||
|
||||
<Note>
|
||||
主会话任务只有在主要交付模式为 `webhook` 时才能使用 `delivery.failureDestination`。隔离任务在所有模式下都接受它。
|
||||
主会话作业只有在主要投递模式为 `webhook` 时,才可以使用 `delivery.failureDestination`。隔离作业在所有模式下都接受它。
|
||||
</Note>
|
||||
|
||||
注意:即使没有生成回复载荷,隔离 cron 运行也会把运行级智能体失败视为任务错误,因此模型/提供商失败仍会增加错误计数并触发失败通知。
|
||||
注意:隔离 cron 运行会将运行级智能体失败视为作业错误,即使
|
||||
没有生成回复载荷也是如此,因此模型/提供商失败仍会递增错误
|
||||
计数器并触发失败通知。
|
||||
|
||||
## 调度
|
||||
|
||||
### 一次性任务
|
||||
### 一次性作业
|
||||
|
||||
`--at <datetime>` 会调度一次性运行。没有偏移量的日期时间会被视为 UTC,除非你同时传入 `--tz <iana>`,该参数会按给定时区解释挂钟时间。
|
||||
`--at <datetime>` 会调度一次性运行。没有偏移量的日期时间会被视为 UTC,除非你同时传入 `--tz <iana>`,此时会按给定时区解释该挂钟时间。
|
||||
|
||||
<Note>
|
||||
一次性任务默认在成功后删除。使用 `--keep-after-run` 可保留它们。
|
||||
一次性作业默认在成功后删除。使用 `--keep-after-run` 可保留它们。
|
||||
</Note>
|
||||
|
||||
### 周期性任务
|
||||
### 周期性作业
|
||||
|
||||
周期性任务在连续错误后使用指数重试退避:30s、1m、5m、15m、60m。下次运行成功后,调度会恢复正常。
|
||||
周期性作业在连续错误后使用指数重试退避:30 秒、1 分钟、5 分钟、15 分钟、60 分钟。下一次成功运行后,调度会恢复正常。
|
||||
|
||||
跳过的运行会与执行错误分开跟踪。它们不会影响重试退避,但 `openclaw cron edit <job-id> --failure-alert-include-skipped` 可以选择让失败提醒包含重复的跳过运行通知。
|
||||
跳过的运行会与执行错误分开跟踪。它们不会影响重试退避,但 `openclaw cron edit <job-id> --failure-alert-include-skipped` 可以选择让失败警报包含重复的跳过运行通知。
|
||||
|
||||
对于目标是本地已配置模型提供商的隔离任务,cron 会在启动智能体轮次前运行轻量级提供商预检。Loopback、private-network 和 `.local` 的 `api: "ollama"` 提供商会在 `/api/tags` 探测;本地 OpenAI 兼容提供商(例如 vLLM、SGLang 和 LM Studio)会在 `/models` 探测。如果端点不可达,该运行会记录为 `skipped` 并在之后的调度中重试;匹配的失效端点会缓存 5 分钟,以避免大量任务反复冲击同一个本地服务器。
|
||||
对于以本地已配置模型提供商为目标的隔离作业,cron 会在启动智能体回合前运行轻量级提供商预检。Loopback、私有网络和 `.local` 的 `api: "ollama"` 提供商会在 `/api/tags` 探测;本地 OpenAI 兼容提供商(如 vLLM、SGLang 和 LM Studio)会在 `/models` 探测。如果端点无法访问,该运行会被记录为 `skipped`,并在后续调度中重试;匹配的失效端点会缓存 5 分钟,避免大量作业反复冲击同一个本地服务器。
|
||||
|
||||
注意:cron 任务定义存放在 `jobs.json` 中,而待处理运行时状态存放在 `jobs-state.json` 中。如果外部编辑了 `jobs.json`,Gateway 网关会重新加载已更改的调度并清除过期的待处理槽位;仅格式变更的重写不会清除待处理槽位。
|
||||
注意:cron 作业定义位于 `jobs.json`,而待处理运行时状态位于 `jobs-state.json`。如果外部编辑了 `jobs.json`,Gateway 网关会重新加载变更后的调度并清除过期的待处理槽位;仅格式化的重写不会清除待处理槽位。
|
||||
|
||||
### 手动运行
|
||||
|
||||
`openclaw cron run` 会在手动运行入队后立即返回。成功响应包含 `{ ok: true, enqueued: true, runId }`。使用 `openclaw cron runs --id <job-id>` 跟踪最终结果。
|
||||
`openclaw cron run` 会在手动运行排队后立即返回。成功响应包括 `{ ok: true, enqueued: true, runId }`。使用 `openclaw cron runs --id <job-id>` 跟踪最终结果。
|
||||
|
||||
<Note>
|
||||
`openclaw cron run <job-id>` 默认会强制运行。使用 `--due` 可保留较旧的“仅在到期时运行”行为。
|
||||
`openclaw cron run <job-id>` 默认强制运行。使用 `--due` 可保留较旧的“仅在到期时运行”行为。
|
||||
</Note>
|
||||
|
||||
## Models
|
||||
|
||||
`cron add|edit --model <ref>` 为任务选择允许的模型。
|
||||
`cron add|edit --model <ref>` 会为该作业选择一个允许的模型。
|
||||
|
||||
<Warning>
|
||||
如果模型不被允许或无法解析,cron 会让该运行失败并给出显式验证错误,而不是回退到任务的智能体或默认模型选择。
|
||||
如果模型不被允许或无法解析,cron 会以显式校验错误使运行失败,而不是回退到作业的智能体或默认模型选择。
|
||||
</Warning>
|
||||
|
||||
Cron `--model` 是**任务主模型**,不是聊天会话 `/model` 覆盖。这意味着:
|
||||
Cron `--model` 是**作业主模型**,不是聊天会话 `/model` 覆盖项。这意味着:
|
||||
|
||||
- 当所选任务模型失败时,已配置的模型回退仍会应用。
|
||||
- 存在逐任务载荷 `fallbacks` 时,它会替换已配置的回退列表。
|
||||
- 空的逐任务回退列表(任务载荷/API 中的 `fallbacks: []`)会让 cron 运行变为严格模式。
|
||||
- 当任务有 `--model` 但未配置回退列表时,OpenClaw 会传递显式的空回退覆盖,这样智能体主模型不会作为隐藏的重试目标追加进去。
|
||||
- 当所选作业模型失败时,仍会应用已配置的模型回退。
|
||||
- 存在按作业载荷的 `fallbacks` 时,它会替换已配置的回退列表。
|
||||
- 空的按作业回退列表(作业载荷/API 中的 `fallbacks: []`)会使 cron 运行变为严格模式。
|
||||
- 当作业有 `--model` 但未配置回退列表时,OpenClaw 会传递显式空回退覆盖项,这样智能体主模型不会作为隐藏重试目标追加。
|
||||
|
||||
### 隔离 cron 模型优先级
|
||||
|
||||
隔离 cron 按以下顺序解析活动模型:
|
||||
|
||||
1. Gmail-hook 覆盖。
|
||||
2. 逐任务 `--model`。
|
||||
3. 已存储的 cron 会话模型覆盖(当用户选择过时)。
|
||||
1. Gmail 钩子覆盖项。
|
||||
2. 按作业的 `--model`。
|
||||
3. 已存储的 cron 会话模型覆盖项(当用户选择过一个时)。
|
||||
4. 智能体或默认模型选择。
|
||||
|
||||
### 快速模式
|
||||
|
||||
隔离 cron 快速模式遵循解析后的实时模型选择。模型配置 `params.fastMode` 默认应用,但已存储的会话 `fastMode` 覆盖仍优先于配置。
|
||||
隔离 cron 快速模式遵循解析后的实时模型选择。默认会应用模型配置 `params.fastMode`,但已存储的会话 `fastMode` 覆盖项仍优先于配置。
|
||||
|
||||
### 实时模型切换重试
|
||||
|
||||
如果隔离运行抛出 `LiveSessionModelSwitchError`,cron 会在重试前为活动运行持久化已切换的提供商和模型(以及存在时的已切换凭证配置文件覆盖)。外层重试循环限制为初次尝试后的两次切换重试,之后会中止而不是无限循环。
|
||||
如果隔离运行抛出 `LiveSessionModelSwitchError`,cron 会在重试前为活动运行持久化切换后的提供商和模型(以及存在时切换后的认证配置文件覆盖项)。外层重试循环限制为初始尝试后的两次切换重试,随后中止而不是无限循环。
|
||||
|
||||
## 运行输出和拒绝
|
||||
|
||||
### 过期确认抑制
|
||||
|
||||
隔离 cron 轮次会抑制过期的仅确认回复。如果第一个结果只是临时状态更新,且没有后代子智能体运行负责最终答案,cron 会在交付前重新提示一次以获取真实结果。
|
||||
隔离 cron 回合会抑制过期的仅确认回复。如果第一个结果只是临时状态更新,并且没有后代子智能体运行负责最终答案,cron 会在投递前重新提示一次以获取真实结果。
|
||||
|
||||
### 静默令牌抑制
|
||||
|
||||
如果隔离 cron 运行只返回静默令牌(`NO_REPLY` 或 `no_reply`),cron 会同时抑制直接外发交付和回退排队摘要路径,因此不会向聊天发回任何内容。
|
||||
如果隔离 cron 运行只返回静默令牌(`NO_REPLY` 或 `no_reply`),cron 会同时抑制直接出站投递和回退队列摘要路径,因此不会向聊天回发任何内容。
|
||||
|
||||
### 结构化拒绝
|
||||
|
||||
隔离 cron 运行优先使用嵌入式运行中的结构化执行拒绝元数据,然后回退到最终输出中的已知拒绝标记,例如 `SYSTEM_RUN_DENIED`、`INVALID_REQUEST` 和凭证绑定拒绝短语。
|
||||
隔离 cron 运行优先使用嵌入式运行中的结构化执行拒绝元数据,然后回退到最终输出中的已知拒绝标记,例如 `SYSTEM_RUN_DENIED`、`INVALID_REQUEST` 和审批绑定拒绝短语。
|
||||
|
||||
`cron list` 和运行历史会显示拒绝原因,而不是将被阻止的命令报告为 `ok`。
|
||||
|
||||
@ -156,45 +160,45 @@ Cron `--model` 是**任务主模型**,不是聊天会话 `/model` 覆盖。这
|
||||
- `cron.sessionRetention`(默认 `24h`)会修剪已完成的隔离运行会话。
|
||||
- `cron.runLog.maxBytes` 和 `cron.runLog.keepLines` 会修剪 `~/.openclaw/cron/runs/<jobId>.jsonl`。
|
||||
|
||||
## 迁移旧任务
|
||||
## 迁移较旧作业
|
||||
|
||||
<Note>
|
||||
如果你有当前交付和存储格式之前创建的 cron 任务,请运行 `openclaw doctor --fix`。Doctor 会规范化旧版 cron 字段(`jobId`、`schedule.cron`、顶层交付字段,包括旧版 `threadId`、载荷 `provider` 交付别名),并在配置了 `cron.webhook` 时,将简单的 `notify: true` webhook 回退任务迁移为显式 webhook 交付。
|
||||
如果你有当前投递和存储格式之前的 cron 作业,请运行 `openclaw doctor --fix`。Doctor 会规范化旧版 cron 字段(`jobId`、`schedule.cron`、顶层投递字段,包括旧版 `threadId`、载荷 `provider` 投递别名),并在配置了 `cron.webhook` 时,将简单的 `notify: true` webhook 回退作业迁移为显式 webhook 投递。
|
||||
</Note>
|
||||
|
||||
## 常见编辑
|
||||
|
||||
在不更改消息的情况下更新交付设置:
|
||||
在不更改消息的情况下更新投递设置:
|
||||
|
||||
```bash
|
||||
openclaw cron edit <job-id> --announce --channel telegram --to "123456789"
|
||||
```
|
||||
|
||||
禁用隔离任务的交付:
|
||||
禁用隔离作业的投递:
|
||||
|
||||
```bash
|
||||
openclaw cron edit <job-id> --no-deliver
|
||||
```
|
||||
|
||||
为隔离任务启用轻量级引导上下文:
|
||||
为隔离作业启用轻量级引导上下文:
|
||||
|
||||
```bash
|
||||
openclaw cron edit <job-id> --light-context
|
||||
```
|
||||
|
||||
announce 到特定渠道:
|
||||
公告到特定渠道:
|
||||
|
||||
```bash
|
||||
openclaw cron edit <job-id> --announce --channel slack --to "channel:C1234567890"
|
||||
```
|
||||
|
||||
announce 到 Telegram 论坛话题:
|
||||
公告到 Telegram 论坛话题:
|
||||
|
||||
```bash
|
||||
openclaw cron edit <job-id> --announce --channel telegram --to "-1001234567890" --thread-id 42
|
||||
```
|
||||
|
||||
创建带轻量级引导上下文的隔离任务:
|
||||
创建带轻量级引导上下文的隔离作业:
|
||||
|
||||
```bash
|
||||
openclaw cron add \
|
||||
@ -206,7 +210,7 @@ openclaw cron add \
|
||||
--no-deliver
|
||||
```
|
||||
|
||||
`--light-context` 仅适用于隔离的智能体轮次任务。对于 cron 运行,轻量级模式会保持引导上下文为空,而不是注入完整的工作区引导集合。
|
||||
`--light-context` 仅适用于隔离智能体回合作业。对于 cron 运行,轻量级模式会保持引导上下文为空,而不是注入完整的工作区引导集合。
|
||||
|
||||
## 常见管理命令
|
||||
|
||||
@ -220,7 +224,7 @@ openclaw cron run <job-id> --due
|
||||
openclaw cron runs --id <job-id> --limit 50
|
||||
```
|
||||
|
||||
`cron runs` 条目包含交付诊断信息,包括预期的 cron 目标、解析后的目标、message 工具发送、回退使用情况以及已交付状态。
|
||||
`cron runs` 条目包含投递诊断信息,包括预期的 cron 目标、解析后的目标、消息工具发送、回退使用情况以及已投递状态。
|
||||
|
||||
智能体和会话重定向:
|
||||
|
||||
@ -231,9 +235,9 @@ openclaw cron edit <job-id> --session current
|
||||
openclaw cron edit <job-id> --session "session:daily-brief"
|
||||
```
|
||||
|
||||
当智能体轮次任务省略 `--agent` 时,`openclaw cron add` 会发出警告并回退到默认智能体(`main`)。在创建时传入 `--agent <id>` 可固定到特定智能体。
|
||||
`openclaw cron add` 会在智能体回合作业省略 `--agent` 时发出警告,并回退到默认智能体(`main`)。在创建时传入 `--agent <id>` 可固定到特定智能体。
|
||||
|
||||
交付微调:
|
||||
投递微调:
|
||||
|
||||
```bash
|
||||
openclaw cron edit <job-id> --announce --channel slack --to "channel:C1234567890"
|
||||
|
||||
@ -1,14 +1,14 @@
|
||||
---
|
||||
read_when:
|
||||
- 你想在 OpenClaw 中使用 Google Gemini 模型
|
||||
- 你想将 Google Gemini 模型与 OpenClaw 搭配使用
|
||||
- 你需要 API 密钥或 OAuth 认证流程
|
||||
summary: Google Gemini 设置(API 密钥 + OAuth、图像生成、媒体理解、TTS、Web 搜索)
|
||||
title: Google(Gemini)
|
||||
x-i18n:
|
||||
generated_at: "2026-05-02T02:49:07Z"
|
||||
generated_at: "2026-05-02T04:47:34Z"
|
||||
model: gpt-5.5
|
||||
provider: openai
|
||||
source_hash: 17d7694408dd02ea87d71530a544ad45e0284a973803f76313338a5065b3f7d5
|
||||
source_hash: 14605b88f0d1d7e01796d429113a73b2b52a48fde6443565dcb3db47653be5e7
|
||||
source_path: providers/google.md
|
||||
workflow: 16
|
||||
---
|
||||
@ -24,11 +24,11 @@ Gemini Grounding 提供图像生成、媒体理解(图像/音频/视频)、
|
||||
|
||||
## 入门指南
|
||||
|
||||
选择你偏好的认证方式,并按照设置步骤操作。
|
||||
选择你偏好的认证方式并按照设置步骤操作。
|
||||
|
||||
<Tabs>
|
||||
<Tab title="API key">
|
||||
**适用于:**通过 Google AI Studio 进行标准 Gemini API 访问。
|
||||
**最适合:**通过 Google AI Studio 进行标准 Gemini API 访问。
|
||||
|
||||
<Steps>
|
||||
<Step title="Run onboarding">
|
||||
@ -36,7 +36,7 @@ Gemini Grounding 提供图像生成、媒体理解(图像/音频/视频)、
|
||||
openclaw onboard --auth-choice gemini-api-key
|
||||
```
|
||||
|
||||
或者直接传入密钥:
|
||||
或直接传入密钥:
|
||||
|
||||
```bash
|
||||
openclaw onboard --non-interactive \
|
||||
@ -70,15 +70,15 @@ Gemini Grounding 提供图像生成、媒体理解(图像/音频/视频)、
|
||||
</Tab>
|
||||
|
||||
<Tab title="Gemini CLI (OAuth)">
|
||||
**适用于:**通过 PKCE OAuth 复用现有的 Gemini CLI 登录,而不是单独使用 API key。
|
||||
**最适合:**通过 PKCE OAuth 复用现有 Gemini CLI 登录,而不是使用单独的 API key。
|
||||
|
||||
<Warning>
|
||||
`google-gemini-cli` 提供商是非官方集成。有些用户报告以这种方式使用 OAuth 时会遇到账户限制。请自行承担风险。
|
||||
`google-gemini-cli` 提供商是非官方集成。一些用户报告以这种方式使用 OAuth 时遇到账户限制。请自行承担风险。
|
||||
</Warning>
|
||||
|
||||
<Steps>
|
||||
<Step title="Install the Gemini CLI">
|
||||
本地 `gemini` 命令必须可在 `PATH` 上使用。
|
||||
本地 `gemini` 命令必须在 `PATH` 上可用。
|
||||
|
||||
```bash
|
||||
# Homebrew
|
||||
@ -88,8 +88,7 @@ Gemini Grounding 提供图像生成、媒体理解(图像/音频/视频)、
|
||||
npm install -g @google/gemini-cli
|
||||
```
|
||||
|
||||
OpenClaw 同时支持 Homebrew 安装和全局 npm 安装,包括
|
||||
常见的 Windows/npm 布局。
|
||||
OpenClaw 同时支持 Homebrew 安装和全局 npm 安装,包括常见的 Windows/npm 布局。
|
||||
</Step>
|
||||
<Step title="Log in via OAuth">
|
||||
```bash
|
||||
@ -107,7 +106,7 @@ Gemini Grounding 提供图像生成、媒体理解(图像/音频/视频)、
|
||||
- 运行时:`google-gemini-cli`
|
||||
- 别名:`gemini-cli`
|
||||
|
||||
Gemini 3.1 Pro 的 Gemini API 模型 ID 是 `gemini-3.1-pro-preview`。OpenClaw 接受较短的 `google/gemini-3.1-pro` 作为便捷别名,并会在提供商调用前对其进行规范化。
|
||||
Gemini 3.1 Pro 的 Gemini API 模型 ID 是 `gemini-3.1-pro-preview`。OpenClaw 接受更短的 `google/gemini-3.1-pro` 作为便捷别名,并会在调用提供商之前将其规范化。
|
||||
|
||||
**环境变量:**
|
||||
|
||||
@ -122,12 +121,11 @@ Gemini Grounding 提供图像生成、媒体理解(图像/音频/视频)、
|
||||
</Note>
|
||||
|
||||
<Note>
|
||||
如果登录在浏览器流程开始前失败,请确保本地 `gemini`
|
||||
如果浏览器流程开始前登录失败,请确保本地 `gemini`
|
||||
命令已安装并位于 `PATH` 上。
|
||||
</Note>
|
||||
|
||||
`google-gemini-cli/*` 模型引用是旧版兼容别名。新的
|
||||
配置应使用 `google/*` 模型引用,并在需要本地 Gemini CLI 执行时搭配 `google-gemini-cli`
|
||||
`google-gemini-cli/*` 模型引用是旧版兼容别名。新的配置应使用 `google/*` 模型引用,并在需要本地 Gemini CLI 执行时搭配 `google-gemini-cli`
|
||||
运行时。
|
||||
|
||||
</Tab>
|
||||
@ -152,7 +150,8 @@ Gemini Grounding 提供图像生成、媒体理解(图像/音频/视频)、
|
||||
## Web 搜索
|
||||
|
||||
内置的 `gemini` Web 搜索提供商使用 Gemini Google Search grounding。
|
||||
在 `plugins.entries.google.config.webSearch` 下配置它:
|
||||
在 `plugins.entries.google.config.webSearch` 下配置专用搜索密钥,
|
||||
或者让它在 `GEMINI_API_KEY` 之后复用 `models.providers.google.apiKey`:
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -161,8 +160,8 @@ Gemini Grounding 提供图像生成、媒体理解(图像/音频/视频)、
|
||||
google: {
|
||||
config: {
|
||||
webSearch: {
|
||||
apiKey: "AIza...", // optional if GEMINI_API_KEY is set
|
||||
baseUrl: "https://generativelanguage.googleapis.com/v1beta",
|
||||
apiKey: "AIza...", // optional if GEMINI_API_KEY or models.providers.google.apiKey is set
|
||||
baseUrl: "https://generativelanguage.googleapis.com/v1beta", // falls back to models.providers.google.baseUrl
|
||||
model: "gemini-2.5-flash",
|
||||
},
|
||||
},
|
||||
@ -172,24 +171,24 @@ Gemini Grounding 提供图像生成、媒体理解(图像/音频/视频)、
|
||||
}
|
||||
```
|
||||
|
||||
`webSearch.baseUrl` 是可选项,用于操作方代理或兼容的
|
||||
Gemini API 端点。请参阅 [Gemini 搜索](/zh-CN/tools/gemini-search) 了解
|
||||
提供商特定的工具行为。
|
||||
凭据优先级依次为专用 `webSearch.apiKey`、`GEMINI_API_KEY`,
|
||||
然后是 `models.providers.google.apiKey`。`webSearch.baseUrl` 是可选的,
|
||||
用于运营方代理或兼容的 Gemini API 端点;省略时,Gemini Web 搜索会复用 `models.providers.google.baseUrl`。参见
|
||||
[Gemini 搜索](/zh-CN/tools/gemini-search),了解提供商特定的工具行为。
|
||||
|
||||
<Tip>
|
||||
Gemini 3 模型使用 `thinkingLevel` 而不是 `thinkingBudget`。OpenClaw 会将
|
||||
Gemini 3、Gemini 3.1 和 `gemini-*-latest` 别名的推理控制映射到
|
||||
`thinkingLevel`,因此默认/低延迟运行不会发送已禁用的
|
||||
`thinkingLevel`,这样默认/低延迟运行就不会发送已禁用的
|
||||
`thinkingBudget` 值。
|
||||
|
||||
`/think adaptive` 会保留 Google 的动态思考语义,而不是选择
|
||||
固定的 OpenClaw 级别。Gemini 3 和 Gemini 3.1 会省略固定的 `thinkingLevel`,以便
|
||||
`/think adaptive` 会保留 Google 的动态思考语义,而不是选择固定的 OpenClaw 级别。Gemini 3 和 Gemini 3.1 会省略固定的 `thinkingLevel`,以便
|
||||
Google 可以选择级别;Gemini 2.5 会发送 Google 的动态哨兵值
|
||||
`thinkingBudget: -1`。
|
||||
|
||||
Gemma 4 模型(例如 `gemma-4-26b-a4b-it`)支持思考模式。OpenClaw
|
||||
会为 Gemma 4 将 `thinkingBudget` 重写为受支持的 Google `thinkingLevel`。
|
||||
将思考设置为 `off` 会保持思考禁用状态,而不是映射到
|
||||
会将 `thinkingBudget` 重写为 Gemma 4 支持的 Google `thinkingLevel`。
|
||||
将思考设置为 `off` 会保持思考禁用,而不是映射到
|
||||
`MINIMAL`。
|
||||
</Tip>
|
||||
|
||||
@ -199,7 +198,7 @@ Gemma 4 模型(例如 `gemma-4-26b-a4b-it`)支持思考模式。OpenClaw
|
||||
`google/gemini-3.1-flash-image-preview`。
|
||||
|
||||
- 还支持 `google/gemini-3-pro-image-preview`
|
||||
- 生成:每次请求最多 4 张图像
|
||||
- 生成:每个请求最多 4 张图像
|
||||
- 编辑模式:已启用,最多 5 张输入图像
|
||||
- 几何控制:`size`、`aspectRatio` 和 `resolution`
|
||||
|
||||
@ -218,7 +217,7 @@ Gemma 4 模型(例如 `gemma-4-26b-a4b-it`)支持思考模式。OpenClaw
|
||||
```
|
||||
|
||||
<Note>
|
||||
请参阅[图像生成](/zh-CN/tools/image-generation),了解共享工具参数、提供商选择和故障转移行为。
|
||||
参见[图像生成](/zh-CN/tools/image-generation),了解共享工具参数、提供商选择和故障转移行为。
|
||||
</Note>
|
||||
|
||||
## 视频生成
|
||||
@ -227,7 +226,7 @@ Gemma 4 模型(例如 `gemma-4-26b-a4b-it`)支持思考模式。OpenClaw
|
||||
`video_generate` 工具注册视频生成。
|
||||
|
||||
- 默认视频模型:`google/veo-3.1-fast-generate-preview`
|
||||
- 模式:文本转视频、图像转视频,以及单视频参考流程
|
||||
- 模式:文本转视频、图像转视频,以及单视频引用流程
|
||||
- 支持 `aspectRatio`、`resolution` 和 `audio`
|
||||
- 当前时长限制:**4 到 8 秒**
|
||||
|
||||
@ -246,7 +245,7 @@ Gemma 4 模型(例如 `gemma-4-26b-a4b-it`)支持思考模式。OpenClaw
|
||||
```
|
||||
|
||||
<Note>
|
||||
请参阅[视频生成](/zh-CN/tools/video-generation),了解共享工具参数、提供商选择和故障转移行为。
|
||||
参见[视频生成](/zh-CN/tools/video-generation),了解共享工具参数、提供商选择和故障转移行为。
|
||||
</Note>
|
||||
|
||||
## 音乐生成
|
||||
@ -257,9 +256,9 @@ Gemma 4 模型(例如 `gemma-4-26b-a4b-it`)支持思考模式。OpenClaw
|
||||
- 默认音乐模型:`google/lyria-3-clip-preview`
|
||||
- 还支持 `google/lyria-3-pro-preview`
|
||||
- 提示词控制:`lyrics` 和 `instrumental`
|
||||
- 输出格式:默认 `mp3`,在 `google/lyria-3-pro-preview` 上还支持 `wav`
|
||||
- 参考输入:最多 10 张图像
|
||||
- 由会话支撑的运行会通过共享的任务/Status 流程分离,包括 `action: "status"`
|
||||
- 输出格式:默认是 `mp3`,在 `google/lyria-3-pro-preview` 上还支持 `wav`
|
||||
- 引用输入:最多 10 张图像
|
||||
- 由会话支持的运行会通过共享任务/Status 流程分离,包括 `action: "status"`
|
||||
|
||||
要将 Google 用作默认音乐提供商:
|
||||
|
||||
@ -276,7 +275,7 @@ Gemma 4 模型(例如 `gemma-4-26b-a4b-it`)支持思考模式。OpenClaw
|
||||
```
|
||||
|
||||
<Note>
|
||||
请参阅[音乐生成](/zh-CN/tools/music-generation),了解共享工具参数、提供商选择和故障转移行为。
|
||||
参见[音乐生成](/zh-CN/tools/music-generation),了解共享工具参数、提供商选择和故障转移行为。
|
||||
</Note>
|
||||
|
||||
## 文本转语音
|
||||
@ -286,8 +285,8 @@ Gemma 4 模型(例如 `gemma-4-26b-a4b-it`)支持思考模式。OpenClaw
|
||||
|
||||
- 默认语音:`Kore`
|
||||
- 认证:`messages.tts.providers.google.apiKey`、`models.providers.google.apiKey`、`GEMINI_API_KEY` 或 `GOOGLE_API_KEY`
|
||||
- 输出:常规 TTS 附件使用 WAV,语音笔记目标使用 Opus,Talk/电话使用 PCM
|
||||
- 语音笔记输出:Google PCM 会被包装为 WAV,并用 `ffmpeg` 转码为 48 kHz Opus
|
||||
- 输出:常规 TTS 附件使用 WAV,语音备注目标使用 Opus,Talk/电话使用 PCM
|
||||
- 语音备注输出:Google PCM 会封装为 WAV,并通过 `ffmpeg` 转码为 48 kHz Opus
|
||||
|
||||
要将 Google 用作默认 TTS 提供商:
|
||||
|
||||
@ -310,13 +309,12 @@ Gemma 4 模型(例如 `gemma-4-26b-a4b-it`)支持思考模式。OpenClaw
|
||||
```
|
||||
|
||||
Gemini API TTS 使用自然语言提示词进行风格控制。设置
|
||||
`audioProfile` 可在朗读文本前添加一个可复用的风格提示词。当你的提示词文本提到具名说话人时,请设置
|
||||
`audioProfile` 可在朗读文本前添加可复用的风格提示词。当你的提示词文本引用命名说话人时,请设置
|
||||
`speakerName`。
|
||||
|
||||
Gemini API TTS 还接受文本中的表现性方括号音频标签,
|
||||
例如 `[whispers]` 或 `[laughs]`。要在将标签发送给 TTS 的同时,让标签不出现在可见聊天回复中,
|
||||
请把它们放在 `[[tts:text]]...[[/tts:text]]`
|
||||
块内:
|
||||
例如 `[whispers]` 或 `[laughs]`。要在将标签发送到 TTS 的同时让它们不出现在可见的聊天回复中,请把它们放入 `[[tts:text]]...[[/tts:text]]`
|
||||
块中:
|
||||
|
||||
```text
|
||||
Here is the clean reply text.
|
||||
@ -325,29 +323,28 @@ Here is the clean reply text.
|
||||
```
|
||||
|
||||
<Note>
|
||||
限制为 Gemini API 的 Google Cloud Console API key 可用于此
|
||||
提供商。这不是单独的 Cloud Text-to-Speech API 路径。
|
||||
限制为 Gemini API 的 Google Cloud Console API key 可用于此提供商。这不是单独的 Cloud Text-to-Speech API 路径。
|
||||
</Note>
|
||||
|
||||
## 实时语音
|
||||
|
||||
内置的 `google` 插件注册了一个由
|
||||
Gemini Live API 支撑的实时语音提供商,用于 Voice Call 和 Google Meet 等后端音频桥接。
|
||||
Gemini Live API 支持的实时语音提供商,用于 Voice Call 和 Google Meet 等后端音频桥接。
|
||||
|
||||
| 设置 | 配置路径 | 默认值 |
|
||||
| --------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------------------------- |
|
||||
| 模型 | `plugins.entries.voice-call.config.realtime.providers.google.model` | `gemini-2.5-flash-native-audio-preview-12-2025` |
|
||||
| 语音 | `...google.voice` | `Kore` |
|
||||
| 温度 | `...google.temperature` | (未设置) |
|
||||
| VAD 开始敏感度 | `...google.startSensitivity` | (未设置) |
|
||||
| VAD 结束敏感度 | `...google.endSensitivity` | (未设置) |
|
||||
| VAD 开始灵敏度 | `...google.startSensitivity` | (未设置) |
|
||||
| VAD 结束灵敏度 | `...google.endSensitivity` | (未设置) |
|
||||
| 静音时长 | `...google.silenceDurationMs` | (未设置) |
|
||||
| 活动处理 | `...google.activityHandling` | Google 默认值,`start-of-activity-interrupts` |
|
||||
| 轮次覆盖 | `...google.turnCoverage` | Google 默认值,`only-activity` |
|
||||
| 轮次覆盖范围 | `...google.turnCoverage` | Google 默认值,`only-activity` |
|
||||
| 禁用自动 VAD | `...google.automaticActivityDetectionDisabled` | `false` |
|
||||
| API key | `...google.apiKey` | 回退到 `models.providers.google.apiKey`、`GEMINI_API_KEY` 或 `GOOGLE_API_KEY` |
|
||||
| API 密钥 | `...google.apiKey` | 回退到 `models.providers.google.apiKey`、`GEMINI_API_KEY` 或 `GOOGLE_API_KEY` |
|
||||
|
||||
Voice Call 实时配置示例:
|
||||
语音通话实时配置示例:
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -378,24 +375,23 @@ Voice Call 实时配置示例:
|
||||
<Note>
|
||||
Google Live API 通过 WebSocket 使用双向音频和函数调用。
|
||||
OpenClaw 会将电话/Meet 桥接音频适配到 Gemini 的 PCM Live API 流,并
|
||||
让工具调用继续使用共享的实时语音契约。除非需要更改采样,否则保持 `temperature`
|
||||
未设置;OpenClaw 会省略非正值,
|
||||
因为 Google Live 可能会在 `temperature: 0` 时返回没有音频的转写内容。
|
||||
Gemini API 转写会在没有 `languageCodes` 的情况下启用;当前 Google
|
||||
在共享实时语音契约上保留工具调用。除非你需要更改采样,否则请让 `temperature`
|
||||
保持未设置;OpenClaw 会省略非正值,因为 Google Live 对 `temperature: 0`
|
||||
可能返回没有音频的转录。
|
||||
Gemini API 转录在没有 `languageCodes` 的情况下启用;当前 Google
|
||||
SDK 会拒绝此 API 路径上的语言代码提示。
|
||||
</Note>
|
||||
|
||||
<Note>
|
||||
Control UI Talk 支持带受限一次性
|
||||
令牌的 Google Live 浏览器会话。仅后端的实时语音提供商也可以通过通用
|
||||
Gateway 网关中继传输运行,这会将提供商凭证保留在 Gateway 网关上。
|
||||
Control UI Talk 支持使用受限一次性令牌的 Google Live 浏览器会话。
|
||||
仅后端实时语音提供商也可以通过通用 Gateway 网关中继传输运行,
|
||||
这会将提供商凭证保留在 Gateway 网关上。
|
||||
</Note>
|
||||
|
||||
对于维护者实时验证,请运行
|
||||
`OPENAI_API_KEY=... GEMINI_API_KEY=... node --import tsx scripts/dev/realtime-talk-live-smoke.ts`。
|
||||
Google 分支会签发与 Control
|
||||
UI Talk 使用的相同受限 Live API 令牌形态,打开浏览器 WebSocket 端点,发送初始设置载荷,
|
||||
并等待 `setupComplete`。
|
||||
Google 这一路径会生成与 Control UI Talk 使用的同一种受限 Live API 令牌形态,
|
||||
打开浏览器 WebSocket 端点,发送初始设置载荷,并等待 `setupComplete`。
|
||||
|
||||
## 高级配置
|
||||
|
||||
@ -404,12 +400,10 @@ UI Talk 使用的相同受限 Live API 令牌形态,打开浏览器 WebSocket
|
||||
对于直接 Gemini API 运行(`api: "google-generative-ai"`),OpenClaw
|
||||
会将配置的 `cachedContent` 句柄传递给 Gemini 请求。
|
||||
|
||||
- 使用 `cachedContent` 或旧版 `cached_content`
|
||||
配置按模型或全局参数
|
||||
- 如果两者同时存在,`cachedContent` 优先
|
||||
- 使用 `cachedContent` 或旧版 `cached_content` 配置按模型或全局参数
|
||||
- 如果两者都存在,`cachedContent` 优先
|
||||
- 示例值:`cachedContents/prebuilt-context`
|
||||
- Gemini 缓存命中用量会从上游 `cachedContentTokenCount`
|
||||
规范化为 OpenClaw `cacheRead`
|
||||
- Gemini 缓存命中用量会从上游 `cachedContentTokenCount` 归一化为 OpenClaw `cacheRead`
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -429,20 +423,20 @@ UI Talk 使用的相同受限 Live API 令牌形态,打开浏览器 WebSocket
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Gemini CLI JSON 使用说明">
|
||||
使用 `google-gemini-cli` OAuth 提供商时,OpenClaw 会按如下方式规范化
|
||||
<Accordion title="Gemini CLI JSON 用量说明">
|
||||
使用 `google-gemini-cli` OAuth 提供商时,OpenClaw 会按如下方式归一化
|
||||
CLI JSON 输出:
|
||||
|
||||
- 回复文本来自 CLI JSON `response` 字段。
|
||||
- 当 CLI 将 `usage` 留空时,用量会回退到 `stats`。
|
||||
- `stats.cached` 会规范化为 OpenClaw `cacheRead`。
|
||||
- `stats.cached` 会归一化为 OpenClaw `cacheRead`。
|
||||
- 如果缺少 `stats.input`,OpenClaw 会从
|
||||
`stats.input_tokens - stats.cached` 推导输入令牌数。
|
||||
`stats.input_tokens - stats.cached` 派生输入 token 数。
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="环境和守护进程设置">
|
||||
如果 Gateway 网关作为守护进程(launchd/systemd)运行,请确保 `GEMINI_API_KEY`
|
||||
如果 Gateway 网关作为守护进程运行(launchd/systemd),请确保 `GEMINI_API_KEY`
|
||||
可供该进程使用(例如,在 `~/.openclaw/.env` 中,或通过
|
||||
`env.shellEnv`)。
|
||||
</Accordion>
|
||||
|
||||
@ -5,10 +5,10 @@ read_when:
|
||||
summary: 在 OpenClaw 中使用 MiniMax 模型
|
||||
title: MiniMax
|
||||
x-i18n:
|
||||
generated_at: "2026-04-28T12:01:54Z"
|
||||
generated_at: "2026-05-02T04:48:01Z"
|
||||
model: gpt-5.5
|
||||
provider: openai
|
||||
source_hash: 0ef833258692c78f40a160131c2a0d36f84889e5d5196ddadb648485ba8cb04a
|
||||
source_hash: 3becdbd14243ce0817d630e6af70559a9b2c9f66860d3f588fef0a118034d2f9
|
||||
source_path: providers/minimax.md
|
||||
workflow: 16
|
||||
---
|
||||
@ -20,35 +20,35 @@ MiniMax 还提供:
|
||||
- 通过 T2A v2 内置语音合成
|
||||
- 通过 `MiniMax-VL-01` 内置图像理解
|
||||
- 通过 `music-2.6` 内置音乐生成
|
||||
- 通过 MiniMax Coding Plan 搜索 API 内置 `web_search`
|
||||
- 通过 MiniMax Token Plan 搜索 API 内置 `web_search`
|
||||
|
||||
提供商拆分:
|
||||
|
||||
| 提供商 ID | 认证 | 能力 |
|
||||
| ---------------- | ------- | -------------------------------------------------------------------------------------------------- |
|
||||
| `minimax` | API key | 文本、图像生成、音乐生成、视频生成、图像理解、语音、Web 搜索 |
|
||||
| `minimax-portal` | OAuth | 文本、图像生成、音乐生成、视频生成、图像理解、语音 |
|
||||
| 提供商 ID | 身份验证 | 能力 |
|
||||
| ---------------- | -------- | ----------------------------------------------------------------------------------------------------- |
|
||||
| `minimax` | API 密钥 | 文本、图像生成、音乐生成、视频生成、图像理解、语音、Web 搜索 |
|
||||
| `minimax-portal` | OAuth | 文本、图像生成、音乐生成、视频生成、图像理解、语音 |
|
||||
|
||||
## 内置目录
|
||||
|
||||
| 模型 | 类型 | 描述 |
|
||||
| ------------------------ | ---------------- | ---------------------------- |
|
||||
| `MiniMax-M2.7` | 聊天(推理) | 默认托管推理模型 |
|
||||
| `MiniMax-M2.7-highspeed` | 聊天(推理) | 更快的 M2.7 推理层级 |
|
||||
| `MiniMax-VL-01` | 视觉 | 图像理解模型 |
|
||||
| `image-01` | 图像生成 | 文生图和图生图编辑 |
|
||||
| `music-2.6` | 音乐生成 | 默认音乐模型 |
|
||||
| `music-2.5` | 音乐生成 | 上一个音乐生成层级 |
|
||||
| `music-2.0` | 音乐生成 | 旧版音乐生成层级 |
|
||||
| `MiniMax-Hailuo-2.3` | 视频生成 | 文生视频和图像参考流程 |
|
||||
| 模型 | 类型 | 描述 |
|
||||
| ------------------------ | -------------- | ---------------------------- |
|
||||
| `MiniMax-M2.7` | 聊天(推理) | 默认托管推理模型 |
|
||||
| `MiniMax-M2.7-highspeed` | 聊天(推理) | 更快的 M2.7 推理层级 |
|
||||
| `MiniMax-VL-01` | 视觉 | 图像理解模型 |
|
||||
| `image-01` | 图像生成 | 文本生成图像和图像到图像编辑 |
|
||||
| `music-2.6` | 音乐生成 | 默认音乐模型 |
|
||||
| `music-2.5` | 音乐生成 | 上一个音乐生成层级 |
|
||||
| `music-2.0` | 音乐生成 | 旧版音乐生成层级 |
|
||||
| `MiniMax-Hailuo-2.3` | 视频生成 | 文本生成视频和图像参考流程 |
|
||||
|
||||
## 入门指南
|
||||
|
||||
选择你偏好的认证方式并按照设置步骤操作。
|
||||
选择你偏好的身份验证方式,并按照设置步骤操作。
|
||||
|
||||
<Tabs>
|
||||
<Tab title="OAuth(Coding Plan)">
|
||||
**最适合:**通过 OAuth 快速设置 MiniMax Coding Plan,无需 API key。
|
||||
**最适合:**通过 OAuth 快速设置 MiniMax Coding Plan,无需 API 密钥。
|
||||
|
||||
<Tabs>
|
||||
<Tab title="国际版">
|
||||
@ -58,7 +58,7 @@ MiniMax 还提供:
|
||||
openclaw onboard --auth-choice minimax-global-oauth
|
||||
```
|
||||
|
||||
这会对 `api.minimax.io` 进行认证。
|
||||
这会针对 `api.minimax.io` 进行身份验证。
|
||||
</Step>
|
||||
<Step title="验证模型可用">
|
||||
```bash
|
||||
@ -74,7 +74,7 @@ MiniMax 还提供:
|
||||
openclaw onboard --auth-choice minimax-cn-oauth
|
||||
```
|
||||
|
||||
这会对 `api.minimaxi.com` 进行认证。
|
||||
这会针对 `api.minimaxi.com` 进行身份验证。
|
||||
</Step>
|
||||
<Step title="验证模型可用">
|
||||
```bash
|
||||
@ -95,8 +95,8 @@ MiniMax 还提供:
|
||||
|
||||
</Tab>
|
||||
|
||||
<Tab title="API key">
|
||||
**最适合:**使用兼容 Anthropic 的 API 的托管 MiniMax。
|
||||
<Tab title="API 密钥">
|
||||
**最适合:**使用与 Anthropic 兼容的 API 托管 MiniMax。
|
||||
|
||||
<Tabs>
|
||||
<Tab title="国际版">
|
||||
@ -173,11 +173,11 @@ MiniMax 还提供:
|
||||
```
|
||||
|
||||
<Warning>
|
||||
在兼容 Anthropic 的流式传输路径上,除非你显式设置 `thinking`,否则 OpenClaw 默认会禁用 MiniMax 思考。MiniMax 的流式传输端点会以 OpenAI 风格的增量块发出 `reasoning_content`,而不是原生 Anthropic 思考块;如果隐式保持启用,可能会将内部推理泄露到可见输出中。
|
||||
在与 Anthropic 兼容的流式传输路径上,除非你显式设置 `thinking`,否则 OpenClaw 默认会禁用 MiniMax thinking。MiniMax 的流式端点会以 OpenAI 风格的 delta 块发出 `reasoning_content`,而不是原生 Anthropic thinking 块;如果隐式保持启用,内部推理可能会泄露到可见输出中。
|
||||
</Warning>
|
||||
|
||||
<Note>
|
||||
API key 设置使用 `minimax` 提供商 ID。模型引用遵循 `minimax/MiniMax-M2.7` 形式。
|
||||
API 密钥设置使用 `minimax` 提供商 ID。模型引用遵循 `minimax/MiniMax-M2.7` 形式。
|
||||
</Note>
|
||||
|
||||
</Tab>
|
||||
@ -193,18 +193,18 @@ MiniMax 还提供:
|
||||
openclaw configure
|
||||
```
|
||||
</Step>
|
||||
<Step title="选择模型/凭证">
|
||||
从菜单中选择 **模型/凭证**。
|
||||
<Step title="选择模型/认证">
|
||||
从菜单中选择 **模型/认证**。
|
||||
</Step>
|
||||
<Step title="选择 MiniMax 凭证选项">
|
||||
<Step title="选择 MiniMax 认证选项">
|
||||
选择一个可用的 MiniMax 选项:
|
||||
|
||||
| 凭证选择 | 描述 |
|
||||
| 认证选择 | 描述 |
|
||||
| --- | --- |
|
||||
| `minimax-global-oauth` | 国际 OAuth(Coding Plan) |
|
||||
| `minimax-cn-oauth` | 中国 OAuth(Coding Plan) |
|
||||
| `minimax-global-api` | 国际 API key |
|
||||
| `minimax-cn-api` | 中国 API key |
|
||||
| `minimax-global-api` | 国际 API 密钥 |
|
||||
| `minimax-cn-api` | 中国 API 密钥 |
|
||||
|
||||
</Step>
|
||||
<Step title="选择你的默认模型">
|
||||
@ -219,12 +219,12 @@ MiniMax 还提供:
|
||||
MiniMax 插件为 `image_generate` 工具注册了 `image-01` 模型。它支持:
|
||||
|
||||
- 带宽高比控制的**文本生成图像**
|
||||
- 带宽高比控制的**图像编辑**(主体参考)
|
||||
- 带宽高比控制的**图像到图像编辑**(主体参考)
|
||||
- 每次请求最多 **9 张输出图像**
|
||||
- 每次编辑请求最多 **1 张参考图像**
|
||||
- 支持的宽高比:`1:1`、`16:9`、`4:3`、`3:2`、`2:3`、`3:4`、`9:16`、`21:9`
|
||||
|
||||
要使用 MiniMax 进行图像生成,请将它设置为图像生成提供商:
|
||||
若要使用 MiniMax 进行图像生成,请将它设置为图像生成提供商:
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -236,70 +236,52 @@ MiniMax 插件为 `image_generate` 工具注册了 `image-01` 模型。它支持
|
||||
}
|
||||
```
|
||||
|
||||
该插件使用与文本模型相同的 `MINIMAX_API_KEY` 或 OAuth 凭证。如果 MiniMax 已经设置好,则无需额外配置。
|
||||
该插件使用与文本模型相同的 `MINIMAX_API_KEY` 或 OAuth 认证。如果已经设置了 MiniMax,则不需要额外配置。
|
||||
|
||||
`minimax` 和 `minimax-portal` 都会使用相同的
|
||||
`image-01` 模型注册 `image_generate`。API-key 设置使用 `MINIMAX_API_KEY`;OAuth 设置可以改用内置的 `minimax-portal` 凭证路径。
|
||||
`minimax` 和 `minimax-portal` 都使用相同的 `image-01` 模型注册 `image_generate`。API 密钥设置使用 `MINIMAX_API_KEY`;OAuth 设置则可以改用内置的 `minimax-portal` 认证路径。
|
||||
|
||||
图像生成始终使用 MiniMax 专用的图像端点
|
||||
(`/v1/image_generation`),并忽略 `models.providers.minimax.baseUrl`,
|
||||
因为该字段用于配置聊天/Anthropic 兼容的基础 URL。设置
|
||||
`MINIMAX_API_HOST=https://api.minimaxi.com` 可通过 CN 端点路由图像生成;默认的全球端点是
|
||||
`https://api.minimax.io`。
|
||||
图像生成始终使用 MiniMax 专用图像端点(`/v1/image_generation`),并忽略 `models.providers.minimax.baseUrl`,因为该字段配置的是聊天/Anthropic 兼容的基础 URL。设置 `MINIMAX_API_HOST=https://api.minimaxi.com` 可将图像生成路由到 CN 端点;默认的全球端点是 `https://api.minimax.io`。
|
||||
|
||||
当新手引导或 API-key 设置写入显式的 `models.providers.minimax`
|
||||
条目时,OpenClaw 会将 `MiniMax-M2.7` 和
|
||||
`MiniMax-M2.7-highspeed` 具体化为仅文本聊天模型。图像理解通过插件拥有的 `MiniMax-VL-01` 媒体提供商单独暴露。
|
||||
当新手引导或 API 密钥设置写入显式的 `models.providers.minimax` 条目时,OpenClaw 会将 `MiniMax-M2.7` 和 `MiniMax-M2.7-highspeed` 实体化为仅文本聊天模型。图像理解则通过插件拥有的 `MiniMax-VL-01` 媒体提供商单独暴露。
|
||||
|
||||
<Note>
|
||||
请参阅[图像生成](/zh-CN/tools/image-generation),了解共享工具参数、提供商选择和故障转移行为。
|
||||
参见[图像生成](/zh-CN/tools/image-generation),了解共享工具参数、提供商选择和故障转移行为。
|
||||
</Note>
|
||||
|
||||
### 文本转语音
|
||||
|
||||
内置的 `minimax` 插件将 MiniMax T2A v2 注册为
|
||||
`messages.tts` 的语音提供商。
|
||||
内置的 `minimax` 插件将 MiniMax T2A v2 注册为 `messages.tts` 的语音提供商。
|
||||
|
||||
- 默认 TTS 模型:`speech-2.8-hd`
|
||||
- 默认语音:`English_expressive_narrator`
|
||||
- 支持的内置模型 ID 包括 `speech-2.8-hd`、`speech-2.8-turbo`、
|
||||
`speech-2.6-hd`、`speech-2.6-turbo`、`speech-02-hd`、
|
||||
`speech-02-turbo`、`speech-01-hd` 和 `speech-01-turbo`。
|
||||
- 凭证解析顺序为 `messages.tts.providers.minimax.apiKey`,然后是
|
||||
`minimax-portal` OAuth/token 凭证配置,然后是 Token Plan 环境变量
|
||||
键(`MINIMAX_OAUTH_TOKEN`、`MINIMAX_CODE_PLAN_KEY`、
|
||||
`MINIMAX_CODING_API_KEY`),最后是 `MINIMAX_API_KEY`。
|
||||
- 如果未配置 TTS 主机,OpenClaw 会复用已配置的
|
||||
`minimax-portal` OAuth 主机,并移除 Anthropic 兼容路径后缀,
|
||||
例如 `/anthropic`。
|
||||
- 支持的内置模型 ID 包括 `speech-2.8-hd`、`speech-2.8-turbo`、`speech-2.6-hd`、`speech-2.6-turbo`、`speech-02-hd`、`speech-02-turbo`、`speech-01-hd` 和 `speech-01-turbo`。
|
||||
- 认证解析顺序为 `messages.tts.providers.minimax.apiKey`,然后是 `minimax-portal` OAuth/token 认证配置文件,然后是 Token Plan 环境键(`MINIMAX_OAUTH_TOKEN`、`MINIMAX_CODE_PLAN_KEY`、`MINIMAX_CODING_API_KEY`),再然后是 `MINIMAX_API_KEY`。
|
||||
- 如果未配置 TTS 主机,OpenClaw 会复用已配置的 `minimax-portal` OAuth 主机,并移除 Anthropic 兼容路径后缀,例如 `/anthropic`。
|
||||
- 普通音频附件保持为 MP3。
|
||||
- Feishu 和 Telegram 等语音消息目标会通过 `ffmpeg` 将 MiniMax
|
||||
MP3 转码为 48kHz Opus,因为 Feishu/Lark 文件 API 对原生音频消息只接受
|
||||
`file_type: "opus"`。
|
||||
- Feishu 和 Telegram 等语音消息目标会通过 `ffmpeg` 从 MiniMax MP3 转码为 48kHz Opus,因为 Feishu/Lark 文件 API 对原生音频消息只接受 `file_type: "opus"`。
|
||||
- MiniMax T2A 接受小数形式的 `speed` 和 `vol`,但 `pitch` 会作为整数发送;OpenClaw 会在 API 请求前截断小数形式的 `pitch` 值。
|
||||
|
||||
| 设置 | 环境变量 | 默认值 | 描述 |
|
||||
| ---------------------------------------- | ---------------------- | ----------------------------- | -------------------------------- |
|
||||
| `messages.tts.providers.minimax.baseUrl` | `MINIMAX_API_HOST` | `https://api.minimax.io` | MiniMax T2A API 主机。 |
|
||||
| `messages.tts.providers.minimax.model` | `MINIMAX_TTS_MODEL` | `speech-2.8-hd` | TTS 模型 ID。 |
|
||||
| `messages.tts.providers.minimax.voiceId` | `MINIMAX_TTS_VOICE_ID` | `English_expressive_narrator` | 用于语音输出的语音 ID。 |
|
||||
| `messages.tts.providers.minimax.speed` | | `1.0` | 播放速度,`0.5..2.0`。 |
|
||||
| `messages.tts.providers.minimax.vol` | | `1.0` | 音量,`(0, 10]`。 |
|
||||
| `messages.tts.providers.minimax.pitch` | | `0` | 整数音高偏移,`-12..12`。 |
|
||||
| 设置 | 环境变量 | 默认值 | 描述 |
|
||||
| ---------------------------------------- | ---------------------- | ----------------------------- | ------------------------------ |
|
||||
| `messages.tts.providers.minimax.baseUrl` | `MINIMAX_API_HOST` | `https://api.minimax.io` | MiniMax T2A API 主机。 |
|
||||
| `messages.tts.providers.minimax.model` | `MINIMAX_TTS_MODEL` | `speech-2.8-hd` | TTS 模型 ID。 |
|
||||
| `messages.tts.providers.minimax.voiceId` | `MINIMAX_TTS_VOICE_ID` | `English_expressive_narrator` | 用于语音输出的语音 ID。 |
|
||||
| `messages.tts.providers.minimax.speed` | | `1.0` | 播放速度,`0.5..2.0`。 |
|
||||
| `messages.tts.providers.minimax.vol` | | `1.0` | 音量,`(0, 10]`。 |
|
||||
| `messages.tts.providers.minimax.pitch` | | `0` | 整数音高偏移,`-12..12`。 |
|
||||
|
||||
### 音乐生成
|
||||
|
||||
内置的 MiniMax 插件通过共享的
|
||||
`music_generate` 工具为 `minimax` 和 `minimax-portal` 注册音乐生成。
|
||||
内置的 MiniMax 插件通过共享的 `music_generate` 工具为 `minimax` 和 `minimax-portal` 注册音乐生成。
|
||||
|
||||
- 默认音乐模型:`minimax/music-2.6`
|
||||
- OAuth 音乐模型:`minimax-portal/music-2.6`
|
||||
- 还支持 `minimax/music-2.5` 和 `minimax/music-2.0`
|
||||
- 提示词控制:`lyrics`、`instrumental`、`durationSeconds`
|
||||
- 输出格式:`mp3`
|
||||
- 由会话支持的运行会通过共享任务/Status 流程分离,包括 `action: "status"`
|
||||
- 基于会话的运行会通过共享的任务/Status 流程分离,包括 `action: "status"`
|
||||
|
||||
要将 MiniMax 用作默认音乐提供商:
|
||||
若要将 MiniMax 用作默认音乐提供商:
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -314,20 +296,19 @@ MiniMax 插件为 `image_generate` 工具注册了 `image-01` 模型。它支持
|
||||
```
|
||||
|
||||
<Note>
|
||||
请参阅[音乐生成](/zh-CN/tools/music-generation),了解共享工具参数、提供商选择和故障转移行为。
|
||||
参见[音乐生成](/zh-CN/tools/music-generation),了解共享工具参数、提供商选择和故障转移行为。
|
||||
</Note>
|
||||
|
||||
### 视频生成
|
||||
|
||||
内置的 MiniMax 插件通过共享的
|
||||
`video_generate` 工具为 `minimax` 和 `minimax-portal` 注册视频生成。
|
||||
内置的 MiniMax 插件通过共享的 `video_generate` 工具为 `minimax` 和 `minimax-portal` 注册视频生成。
|
||||
|
||||
- 默认视频模型:`minimax/MiniMax-Hailuo-2.3`
|
||||
- OAuth 视频模型:`minimax-portal/MiniMax-Hailuo-2.3`
|
||||
- 模式:文本生成视频和单图参考流程
|
||||
- 模式:文本生成视频和单图像参考流程
|
||||
- 支持 `aspectRatio` 和 `resolution`
|
||||
|
||||
要将 MiniMax 用作默认视频提供商:
|
||||
若要将 MiniMax 用作默认视频提供商:
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -342,36 +323,36 @@ MiniMax 插件为 `image_generate` 工具注册了 `image-01` 模型。它支持
|
||||
```
|
||||
|
||||
<Note>
|
||||
参见[视频生成](/zh-CN/tools/video-generation),了解共享工具参数、提供商选择和故障转移行为。
|
||||
请参阅[视频生成](/zh-CN/tools/video-generation),了解共享工具参数、提供商选择和故障转移行为。
|
||||
</Note>
|
||||
|
||||
### 图像理解
|
||||
|
||||
MiniMax 插件将图像理解与文本目录分开注册:
|
||||
MiniMax 插件会将图像理解与文本目录分开注册:
|
||||
|
||||
| 提供商 ID | 默认图像模型 |
|
||||
| 提供商 ID | 默认图像模型 |
|
||||
| ---------------- | ------------------- |
|
||||
| `minimax` | `MiniMax-VL-01` |
|
||||
| `minimax-portal` | `MiniMax-VL-01` |
|
||||
|
||||
因此,即使内置文本提供商目录仍然显示仅文本的 M2.7 聊天引用,自动媒体路由也可以使用 MiniMax 图像理解。
|
||||
这就是为什么即使内置文本提供商目录仍显示仅文本的 M2.7 聊天引用,自动媒体路由也可以使用 MiniMax 图像理解。
|
||||
|
||||
### Web 搜索
|
||||
|
||||
MiniMax 插件还通过 MiniMax Coding Plan 搜索 API 注册 `web_search`。
|
||||
MiniMax 插件还会通过 MiniMax Token Plan 搜索 API 注册 `web_search`。
|
||||
|
||||
- 提供商 ID:`minimax`
|
||||
- 提供商 id:`minimax`
|
||||
- 结构化结果:标题、URL、摘要、相关查询
|
||||
- 首选环境变量:`MINIMAX_CODE_PLAN_KEY`
|
||||
- 接受的环境变量别名:`MINIMAX_CODING_API_KEY`
|
||||
- 兼容性回退:当 `MINIMAX_API_KEY` 已经指向 coding-plan 令牌时使用它
|
||||
- 区域复用:`plugins.entries.minimax.config.webSearch.region`,然后是 `MINIMAX_API_HOST`,然后是 MiniMax 提供商基础 URL
|
||||
- 搜索保持在提供商 ID `minimax` 上;OAuth 中国/全球设置仍可通过 `models.providers.minimax-portal.baseUrl` 间接引导区域
|
||||
- 接受的环境变量别名:`MINIMAX_CODING_API_KEY`、`MINIMAX_OAUTH_TOKEN`
|
||||
- 兼容性回退:当 `MINIMAX_API_KEY` 已指向 token-plan 凭证时使用它
|
||||
- 区域复用:`plugins.entries.minimax.config.webSearch.region`,然后是 `MINIMAX_API_HOST`,再然后是 MiniMax 提供商基础 URL
|
||||
- 搜索保留在提供商 id `minimax` 上;OAuth 中国/全球设置可以通过 `models.providers.minimax-portal.baseUrl` 间接控制区域,并可以通过 `MINIMAX_OAUTH_TOKEN` 提供 bearer 认证
|
||||
|
||||
配置位于 `plugins.entries.minimax.config.webSearch.*` 下。
|
||||
|
||||
<Note>
|
||||
参见 [MiniMax 搜索](/zh-CN/tools/minimax-search),了解完整的 Web 搜索配置和用法。
|
||||
请参阅 [MiniMax 搜索](/zh-CN/tools/minimax-search),了解完整的 Web 搜索配置和用法。
|
||||
</Note>
|
||||
|
||||
## 高级配置
|
||||
@ -380,18 +361,18 @@ MiniMax 插件还通过 MiniMax Coding Plan 搜索 API 注册 `web_search`。
|
||||
<Accordion title="配置选项">
|
||||
| 选项 | 描述 |
|
||||
| --- | --- |
|
||||
| `models.providers.minimax.baseUrl` | 优先使用 `https://api.minimax.io/anthropic`(兼容 Anthropic);`https://api.minimax.io/v1` 可选,用于兼容 OpenAI 的载荷 |
|
||||
| `models.providers.minimax.api` | 优先使用 `anthropic-messages`;`openai-completions` 可选,用于兼容 OpenAI 的载荷 |
|
||||
| `models.providers.minimax.apiKey` | MiniMax API 密钥(`MINIMAX_API_KEY`) |
|
||||
| `models.providers.minimax.baseUrl` | 优先使用 `https://api.minimax.io/anthropic`(兼容 Anthropic);`https://api.minimax.io/v1` 可选用于兼容 OpenAI 的载荷 |
|
||||
| `models.providers.minimax.api` | 优先使用 `anthropic-messages`;`openai-completions` 可选用于兼容 OpenAI 的载荷 |
|
||||
| `models.providers.minimax.apiKey` | MiniMax API key(`MINIMAX_API_KEY`) |
|
||||
| `models.providers.minimax.models` | 定义 `id`、`name`、`reasoning`、`contextWindow`、`maxTokens`、`cost` |
|
||||
| `agents.defaults.models` | 为你想加入允许列表的模型设置别名 |
|
||||
| `models.mode` | 如果你想在内置模型旁添加 MiniMax,请保持 `merge` |
|
||||
| `models.mode` | 如果你想在内置项旁添加 MiniMax,请保持 `merge` |
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="思考默认值">
|
||||
在 `api: "anthropic-messages"` 上,除非已经在参数/配置中显式设置了 thinking,否则 OpenClaw 会注入 `thinking: { type: "disabled" }`。
|
||||
<Accordion title="Thinking 默认值">
|
||||
在 `api: "anthropic-messages"` 上,除非 params/config 中已经显式设置了 thinking,否则 OpenClaw 会注入 `thinking: { type: "disabled" }`。
|
||||
|
||||
这会防止 MiniMax 的流式端点以 OpenAI 风格的 delta 分块发出 `reasoning_content`,从而避免将内部推理泄露到可见输出中。
|
||||
这会防止 MiniMax 的流式端点在 OpenAI 风格的 delta 分块中发出 `reasoning_content`,从而避免内部推理泄露到可见输出中。
|
||||
|
||||
</Accordion>
|
||||
|
||||
@ -400,7 +381,7 @@ MiniMax 插件还通过 MiniMax Coding Plan 搜索 API 注册 `web_search`。
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="回退示例">
|
||||
**最适合:** 将你最强的最新一代模型作为主模型,并故障转移到 MiniMax M2.7。下面的示例使用 Opus 作为具体主模型;可替换为你偏好的最新一代主模型。
|
||||
**最适合:**将你最强的最新一代模型作为主模型,故障转移到 MiniMax M2.7。下面的示例使用 Opus 作为具体主模型;请替换为你偏好的最新一代主模型。
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -422,49 +403,49 @@ MiniMax 插件还通过 MiniMax Coding Plan 搜索 API 注册 `web_search`。
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Coding Plan 使用详情">
|
||||
- Coding Plan 使用量 API:`https://api.minimaxi.com/v1/api/openplatform/coding_plan/remains`(需要 coding plan 密钥)。
|
||||
- OpenClaw 会将 MiniMax coding-plan 使用量标准化为其他提供商使用的同一 `% left` 显示。MiniMax 原始的 `usage_percent` / `usagePercent` 字段表示剩余额度,而不是已消耗额度,因此 OpenClaw 会将其反转。存在按次数统计的字段时优先使用这些字段。
|
||||
- 当 API 返回 `model_remains` 时,OpenClaw 会优先使用聊天模型条目,在需要时从 `start_time` / `end_time` 派生窗口标签,并在套餐标签中包含所选模型名称,以便更容易区分 coding-plan 窗口。
|
||||
- 使用量快照会将 `minimax`、`minimax-cn` 和 `minimax-portal` 视为同一个 MiniMax 额度界面,并优先使用已存储的 MiniMax OAuth,然后再回退到 Coding Plan 密钥环境变量。
|
||||
<Accordion title="Coding Plan 用法详情">
|
||||
- Coding Plan 用量 API:`https://api.minimaxi.com/v1/api/openplatform/coding_plan/remains`(需要 coding plan key)。
|
||||
- OpenClaw 会将 MiniMax coding-plan 用量规范化为其他提供商使用的同一种 `% left` 显示。MiniMax 原始的 `usage_percent` / `usagePercent` 字段表示剩余额度,而不是已消耗额度,因此 OpenClaw 会将其反转。存在基于数量的字段时,以它们为准。
|
||||
- 当 API 返回 `model_remains` 时,OpenClaw 优先选择聊天模型条目,在需要时从 `start_time` / `end_time` 推导窗口标签,并在套餐标签中包含所选模型名称,使 coding-plan 窗口更容易区分。
|
||||
- 用量快照会将 `minimax`、`minimax-cn` 和 `minimax-portal` 视为同一个 MiniMax 额度表面,并优先使用已存储的 MiniMax OAuth,然后才回退到 Coding Plan key 环境变量。
|
||||
|
||||
</Accordion>
|
||||
</AccordionGroup>
|
||||
|
||||
## 备注
|
||||
## 注意事项
|
||||
|
||||
- 模型引用遵循凭证路径:
|
||||
- API 密钥设置:`minimax/<model>`
|
||||
- 模型引用遵循认证路径:
|
||||
- API-key 设置:`minimax/<model>`
|
||||
- OAuth 设置:`minimax-portal/<model>`
|
||||
- 默认聊天模型:`MiniMax-M2.7`
|
||||
- 备用聊天模型:`MiniMax-M2.7-highspeed`
|
||||
- 新手引导和直接 API 密钥设置会为两个 M2.7 变体写入仅文本模型定义
|
||||
- 新手引导和直接 API-key 设置会为两个 M2.7 变体写入仅文本模型定义
|
||||
- 图像理解使用插件拥有的 `MiniMax-VL-01` 媒体提供商
|
||||
- 如果需要精确成本跟踪,请更新 `models.json` 中的价格值
|
||||
- 使用 `openclaw models list` 确认当前提供商 ID,然后通过 `openclaw models set minimax/MiniMax-M2.7` 或 `openclaw models set minimax-portal/MiniMax-M2.7` 切换
|
||||
- 如果你需要精确成本跟踪,请更新 `models.json` 中的定价值
|
||||
- 使用 `openclaw models list` 确认当前提供商 id,然后用 `openclaw models set minimax/MiniMax-M2.7` 或 `openclaw models set minimax-portal/MiniMax-M2.7` 切换
|
||||
|
||||
<Tip>
|
||||
MiniMax Coding Plan 推荐链接(九折):[MiniMax Coding Plan](https://platform.minimax.io/subscribe/coding-plan?code=DbXJTRClnb&source=link)
|
||||
</Tip>
|
||||
|
||||
<Note>
|
||||
参见[模型提供商](/zh-CN/concepts/model-providers),了解提供商规则。
|
||||
请参阅[模型提供商](/zh-CN/concepts/model-providers),了解提供商规则。
|
||||
</Note>
|
||||
|
||||
## 故障排除
|
||||
|
||||
<AccordionGroup>
|
||||
<Accordion title='"未知模型:minimax/MiniMax-M2.7"'>
|
||||
这通常表示 **MiniMax 提供商未配置**(没有匹配的提供商条目,也没有找到 MiniMax 凭证配置文件/环境密钥)。此检测修复包含在 **2026.1.12** 中。修复方式:
|
||||
这通常意味着 **MiniMax 提供商未配置**(没有匹配的提供商条目,也没有找到 MiniMax 认证配置文件/环境变量键)。此检测的修复位于 **2026.1.12**。修复方式:
|
||||
|
||||
- 升级到 **2026.1.12**(或从源码 `main` 运行),然后重启 Gateway 网关。
|
||||
- 运行 `openclaw configure` 并选择一个 **MiniMax** 凭证选项,或者
|
||||
- 手动添加匹配的 `models.providers.minimax` 或 `models.providers.minimax-portal` 块,或者
|
||||
- 设置 `MINIMAX_API_KEY`、`MINIMAX_OAUTH_TOKEN`,或 MiniMax 凭证配置文件,以便注入匹配的提供商。
|
||||
- 升级到 **2026.1.12**(或从源代码 `main` 运行),然后重启 Gateway 网关。
|
||||
- 运行 `openclaw configure` 并选择一个 **MiniMax** 认证选项,或
|
||||
- 手动添加匹配的 `models.providers.minimax` 或 `models.providers.minimax-portal` 块,或
|
||||
- 设置 `MINIMAX_API_KEY`、`MINIMAX_OAUTH_TOKEN` 或 MiniMax 认证配置文件,以便注入匹配的提供商。
|
||||
|
||||
请确保模型 ID **区分大小写**:
|
||||
请确保模型 id **区分大小写**:
|
||||
|
||||
- API 密钥路径:`minimax/MiniMax-M2.7` 或 `minimax/MiniMax-M2.7-highspeed`
|
||||
- API-key 路径:`minimax/MiniMax-M2.7` 或 `minimax/MiniMax-M2.7-highspeed`
|
||||
- OAuth 路径:`minimax-portal/MiniMax-M2.7` 或 `minimax-portal/MiniMax-M2.7-highspeed`
|
||||
|
||||
然后使用以下命令重新检查:
|
||||
@ -496,9 +477,9 @@ MiniMax Coding Plan 推荐链接(九折):[MiniMax Coding Plan](https://pla
|
||||
共享视频工具参数和提供商选择。
|
||||
</Card>
|
||||
<Card title="MiniMax 搜索" href="/zh-CN/tools/minimax-search" icon="magnifying-glass">
|
||||
通过 MiniMax Coding Plan 进行 Web 搜索配置。
|
||||
通过 MiniMax Token Plan 配置 Web 搜索。
|
||||
</Card>
|
||||
<Card title="故障排除" href="/zh-CN/help/troubleshooting" icon="wrench">
|
||||
常规故障排除和常见问题。
|
||||
通用故障排除和常见问题。
|
||||
</Card>
|
||||
</CardGroup>
|
||||
|
||||
@ -6,18 +6,18 @@ read_when:
|
||||
summary: 发布通道、操作员检查清单、验证环境、版本命名和节奏
|
||||
title: 发布策略
|
||||
x-i18n:
|
||||
generated_at: "2026-05-01T23:38:40Z"
|
||||
generated_at: "2026-05-02T04:48:22Z"
|
||||
model: gpt-5.5
|
||||
provider: openai
|
||||
source_hash: e915840070324f7614c993d20490f0bf4c9b266c57ce74eddfc461e019d3dc07
|
||||
source_hash: 3ce380a8277e7c8764359e4ded86d1042dcb250691ac62fbee28651f20aa0580
|
||||
source_path: reference/RELEASING.md
|
||||
workflow: 16
|
||||
---
|
||||
|
||||
OpenClaw 有三条公开发布通道:
|
||||
OpenClaw 有三个公开发布通道:
|
||||
|
||||
- stable:带标签的发布版本,默认发布到 npm `beta`,或在明确请求时发布到 npm `latest`
|
||||
- beta:预发布标签,发布到 npm `beta`
|
||||
- stable:默认发布到 npm `beta` 的带标签版本,或在明确请求时发布到 npm `latest`
|
||||
- beta:发布到 npm `beta` 的预发布标签
|
||||
- dev:`main` 的移动头部
|
||||
|
||||
## 版本命名
|
||||
@ -28,109 +28,130 @@ OpenClaw 有三条公开发布通道:
|
||||
- Git 标签:`vYYYY.M.D-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/包路径,mac 应用的构建/签名/公证会保留给稳定版本,除非明确请求
|
||||
- 稳定和稳定修正版本默认发布到 npm `beta`;发布操作员可以明确指定 `latest`,或稍后提升经过验证的 beta 构建
|
||||
- 每个稳定版 OpenClaw 发布都会同时交付 npm 包和 macOS 应用;
|
||||
beta 发布通常会先验证并发布 npm/package 路径,而
|
||||
mac 应用构建/签名/公证仅保留给稳定版,除非明确请求
|
||||
|
||||
## 发布节奏
|
||||
|
||||
- 发布按 beta 优先推进
|
||||
- 只有在最新 beta 验证完成后才会推出稳定版本
|
||||
- 维护者通常会从当前 `main` 创建 `release/YYYY.M.D` 分支来切发布,
|
||||
这样发布验证和修复不会阻塞 `main` 上的新开发
|
||||
- 如果 beta 标签已经推送或发布且需要修复,维护者会切下一个
|
||||
`-beta.N` 标签,而不是删除或重新创建旧的 beta 标签
|
||||
- 详细发布流程、审批、凭证和恢复说明仅限维护者使用
|
||||
- 只有最新 beta 通过验证后,稳定版才会跟进
|
||||
- 维护者通常从基于当前 `main` 创建的 `release/YYYY.M.D` 分支切出发布,
|
||||
因此发布验证和修复不会阻塞 `main` 上的新开发
|
||||
- 如果 beta 标签已经推送或发布并且需要修复,维护者会切出下一个
|
||||
`-beta.N` 标签,而不是删除或重新创建旧 beta 标签
|
||||
- 详细的发布流程、审批、凭证和恢复说明仅限维护者可见
|
||||
|
||||
## 发布操作员清单
|
||||
## 发布操作员检查清单
|
||||
|
||||
此清单是发布流程的公开形态。私有凭证、签名、公证、dist-tag 恢复和紧急回滚细节保留在仅限维护者使用的发布运行手册中。
|
||||
此检查清单是发布流程的公开形态。私有凭证、
|
||||
签名、公证、dist-tag 恢复和紧急回滚细节保留在
|
||||
仅限维护者的发布运行手册中。
|
||||
|
||||
1. 从当前 `main` 开始:拉取最新内容,确认目标提交已推送,
|
||||
并确认当前 `main` CI 的状态足够适合从它创建分支。
|
||||
2. 使用真实提交历史通过 `/changelog` 重写顶部 `CHANGELOG.md` 章节,
|
||||
保持条目面向用户,提交并推送,然后在创建分支前再 rebase/pull
|
||||
一次。
|
||||
3. 查看
|
||||
并确认当前 `main` CI 足够健康,可以从它创建分支。
|
||||
2. 使用 `/changelog` 根据真实提交历史重写顶部 `CHANGELOG.md` 章节,
|
||||
保持条目面向用户,提交并推送,然后在创建分支前再次 rebase/pull。
|
||||
3. 审查
|
||||
`src/plugins/compat/registry.ts` 和
|
||||
`src/commands/doctor/shared/deprecation-compat.ts` 中的发布兼容性记录。只有在升级路径仍然有覆盖时才移除过期兼容性,或者记录为何有意继续保留。
|
||||
4. 从当前 `main` 创建 `release/YYYY.M.D`;不要直接在 `main` 上做常规发布工作。
|
||||
5. 为目标标签更新所有必需的版本位置,然后运行本地确定性预检:
|
||||
`src/commands/doctor/shared/deprecation-compat.ts` 中的发布兼容性记录。仅当升级路径仍被覆盖时才移除过期
|
||||
兼容性,或记录为什么有意继续保留。
|
||||
4. 从当前 `main` 创建 `release/YYYY.M.D`;不要直接在 `main` 上进行常规发布工作。
|
||||
5. 为预期标签更新每个必需的版本位置,然后运行
|
||||
本地确定性预检:
|
||||
`pnpm check:test-types`、`pnpm check:architecture`、
|
||||
`pnpm build && pnpm ui:build` 和 `pnpm release:check`。
|
||||
6. 使用 `preflight_only=true` 运行 `OpenClaw NPM Release`。在标签存在之前,
|
||||
可以使用完整的 40 字符发布分支 SHA 进行仅验证预检。保存成功的
|
||||
`preflight_run_id`。
|
||||
7. 对发布分支、标签或完整提交 SHA 使用 `Full Release Validation` 启动所有预发布测试。这是四个大型发布测试箱的唯一手动入口点:Vitest、Docker、QA Lab 和 Package。
|
||||
8. 如果验证失败,在发布分支上修复,并重新运行能证明修复的最小失败文件、通道、工作流作业、包配置文件、提供商或模型 allowlist。只有在变更面使先前证据过期时,才重新运行完整总入口。
|
||||
9. 对于 beta,打标签 `vYYYY.M.D-beta.N`,使用 npm dist-tag `beta` 发布,然后针对已发布的 `openclaw@YYYY.M.D-beta.N`
|
||||
或 `openclaw@beta` 包运行发布后包验收。如果已推送或已发布的 beta 需要修复,切下一个 `-beta.N`;不要删除或重写旧 beta。
|
||||
10. 对于稳定版本,只有在经过审查的 beta 或发布候选版本具备所需验证证据后才继续。稳定 npm 发布会通过 `preflight_run_id` 复用成功的预检产物;稳定 macOS 发布就绪还要求打包好的 `.zip`、`.dmg`、`.dSYM.zip` 以及 `main` 上已更新的
|
||||
允许使用完整的 40 字符发布分支 SHA 进行仅验证
|
||||
预检。保存成功的 `preflight_run_id`。
|
||||
7. 使用 `Full Release Validation` 针对
|
||||
发布分支、标签或完整提交 SHA 启动所有预发布测试。这是四个大型发布测试箱的唯一手动入口点:
|
||||
Vitest、Docker、QA Lab 和 Package。
|
||||
8. 如果验证失败,在发布分支上修复,并重新运行能证明修复的最小失败
|
||||
文件、通道、工作流作业、包配置、提供商或模型 allowlist。仅当变更表面使
|
||||
之前的证据失效时,才重新运行完整总控流程。
|
||||
9. 对于 beta,标记 `vYYYY.M.D-beta.N`,使用 npm dist-tag `beta` 发布,然后针对已发布的 `openclaw@YYYY.M.D-beta.N`
|
||||
或 `openclaw@beta` 包运行发布后包验收。如果已推送或已发布的 beta 需要修复,则切出
|
||||
下一个 `-beta.N`;不要删除或重写旧 beta。
|
||||
10. 对于稳定版,只有经过验证的 beta 或候选发布版本具备所需验证证据后才继续。
|
||||
稳定版 npm 发布会通过 `preflight_run_id` 复用成功的
|
||||
预检工件;稳定版 macOS 发布就绪还要求 `main` 上存在打包后的 `.zip`、`.dmg`、`.dSYM.zip` 和已更新的
|
||||
`appcast.xml`。
|
||||
11. 发布后,运行 npm 发布后验证器;在需要发布后渠道证明时,可选运行独立的已发布 npm Telegram E2E;按需进行 dist-tag 推广;根据完整匹配的 `CHANGELOG.md` 章节生成 GitHub release/prerelease 说明;并执行发布公告步骤。
|
||||
11. 发布后,运行 npm 发布后验证器;当你需要发布后渠道证明时,可选运行独立的
|
||||
published-npm Telegram E2E;按需进行 dist-tag 提升;根据完整匹配的 `CHANGELOG.md` 章节生成 GitHub release/prerelease 说明;并执行发布公告
|
||||
步骤。
|
||||
|
||||
## 发布预检
|
||||
|
||||
- 在发布预检前运行 `pnpm check:test-types`,使测试 TypeScript 在更快的本地 `pnpm check` 门禁之外仍被覆盖
|
||||
- 在发布预检前运行 `pnpm check:architecture`,使更广泛的导入循环和架构边界检查在更快的本地门禁之外保持绿色
|
||||
- 在 `pnpm release:check` 前运行 `pnpm build && pnpm ui:build`,使预期的 `dist/*` 发布产物和 Control UI 包存在,供打包验证步骤使用
|
||||
- 在发布批准前运行手动 `Full Release Validation` 工作流,从一个入口点启动所有预发布测试盒。它接受分支、标签或完整提交 SHA,分派手动 `CI`,并分派 `OpenClaw Release Checks`,覆盖安装冒烟、包验收、Docker 发布路径套件、live/E2E、OpenWebUI、QA Lab 一致性、Matrix 和 Telegram 线路。使用 `release_profile=full` 和 `rerun_group=all` 时,它还会针对发布检查中的 `release-package-under-test` 产物运行包 Telegram E2E。当同一个 Telegram E2E 也应验证已发布的 npm 包时,请在发布后提供 `npm_telegram_package_spec`。当私有证据报告应证明验证与已发布的 npm 包匹配、但不强制运行 Telegram E2E 时,请提供 `evidence_package_spec`。
|
||||
- 在发布预检前运行 `pnpm check:test-types`,确保测试 TypeScript 在更快的本地 `pnpm check` 门禁之外也保持覆盖
|
||||
- 在发布预检前运行 `pnpm check:architecture`,确保更广泛的导入循环和架构边界检查在更快的本地门禁之外也为绿色
|
||||
- 在 `pnpm release:check` 前运行 `pnpm build && pnpm ui:build`,确保预期的 `dist/*` 发布产物和 Control UI 包存在,以供打包验证步骤使用
|
||||
- 在发布批准前运行手动 `Full Release Validation` 工作流,以便从一个入口点启动所有预发布 test boxes。它接受分支、标签或完整提交 SHA,分派手动 `CI`,并分派 `OpenClaw Release Checks`,覆盖安装冒烟、包验收、Docker 发布路径套件、实时/E2E、OpenWebUI、QA Lab 对等性、Matrix 和 Telegram 通道。使用 `release_profile=full` 和 `rerun_group=all` 时,它还会针对发布检查中的 `release-package-under-test` 产物运行包 Telegram E2E。发布后,如果同一 Telegram E2E 也应验证已发布的 npm 包,请提供 `npm_telegram_package_spec`。如果私有证据报告应证明验证与已发布的 npm 包匹配,但不强制运行 Telegram E2E,请提供 `evidence_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` 以当前 `workflow_ref` harness 打包受信任的 `package_ref` 分支/标签/SHA;对带有必需 SHA-256 的 HTTPS tarball 使用 `source=url`;或对另一个 GitHub Actions 运行上传的 tarball 使用 `source=artifact`。该工作流会将候选版本解析为 `package-under-test`,针对该 tarball 复用 Docker E2E 发布调度器,并可通过 `telegram_mode=mock-openai` 或 `telegram_mode=live-frontier` 针对同一 tarball 运行 Telegram QA。当选中的 Docker 线路包含 `published-upgrade-survivor` 时,包产物就是候选版本,`published_upgrade_survivor_baseline` 选择已发布基线。
|
||||
- 当你希望在发布工作继续进行时为包候选项提供旁路证明,请运行手动 `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`,复用 Docker E2E 发布调度器针对该 tarball 运行,并可通过 `telegram_mode=mock-openai` 或 `telegram_mode=live-frontier` 针对同一个 tarball 运行 Telegram QA。当所选 Docker 通道包含 `published-upgrade-survivor` 时,包产物就是候选项,而 `published_upgrade_survivor_baseline` 选择已发布的基线。
|
||||
示例:`gh workflow run package-acceptance.yml --ref main -f workflow_ref=main -f source=npm -f package_spec=openclaw@beta -f suite_profile=product -f published_upgrade_survivor_baseline=openclaw@2026.4.26 -f telegram_mode=mock-openai`
|
||||
常用配置:
|
||||
- `smoke`:安装/渠道/智能体、Gateway 网关网络和配置重载线路
|
||||
- `package`:不含 OpenWebUI 或 live ClawHub 的产物原生包/更新/插件线路
|
||||
- `product`:package 配置加 MCP 渠道、cron/subagent 清理、OpenAI web 搜索和 OpenWebUI
|
||||
- `smoke`:安装/渠道/智能体、Gateway 网关网络和配置重载通道
|
||||
- `package`:面向产物原生的包/更新/插件通道,不包含 OpenWebUI 或实时 ClawHub
|
||||
- `product`:包配置加上 MCP 渠道、cron/subagent 清理、OpenAI Web 搜索和 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 线路。
|
||||
- 当你只需要发布候选项的完整常规 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 凭证租约。当你希望并行获得完整 Matrix 传输、媒体和 E2EE 清单时,请使用 `matrix_profile=all` 和 `matrix_shards=true` 运行手动 `QA-Lab - All Lanes` 工作流。
|
||||
- 跨操作系统安装和升级运行时验证是公开 `OpenClaw Release Checks` 和 `Full Release Validation` 的一部分,它们会直接调用可复用工作流 `.github/workflows/openclaw-cross-os-release-checks-reusable.yml`
|
||||
- 这种拆分是有意的:保持真实 npm 发布路径简短、确定且聚焦产物,同时较慢的 live 检查留在自己的线路中,避免拖慢或阻塞发布
|
||||
- 带密钥的发布检查应通过 `Full Release Validation` 分派,或从 `main`/release 工作流引用分派,以便工作流逻辑和密钥保持受控
|
||||
- 只要解析出的提交可从 OpenClaw 分支或发布标签访问,`OpenClaw Release Checks` 就接受分支、标签或完整提交 SHA
|
||||
- `OpenClaw NPM Release` 仅验证预检也接受当前完整 40 字符工作流分支提交 SHA,而不需要已推送标签
|
||||
- `OpenClaw Release Checks` 还会在发布批准前运行 QA Lab mock 对等性门禁,以及快速实时 Matrix 配置和 Telegram QA 通道。实时通道使用 `qa-live-shared` 环境;Telegram 还使用 Convex CI 凭据租约。当你希望并行运行完整 Matrix 传输、媒体和 E2EE 清单时,请使用 `matrix_profile=all` 和 `matrix_shards=true` 运行手动 `QA-Lab - All Lanes` 工作流。
|
||||
- 跨操作系统安装和升级运行时验证属于公开 `OpenClaw Release Checks` 和 `Full Release Validation` 的一部分,它们会直接调用可复用工作流 `.github/workflows/openclaw-cross-os-release-checks-reusable.yml`
|
||||
- 这种拆分是有意的:保持真实 npm 发布路径短小、确定且聚焦产物,同时较慢的实时检查留在自己的通道中,避免它们拖慢或阻塞发布
|
||||
- 带有密钥的发布检查应通过 `Full Release Validation` 分派,或从 `main`/发布工作流 ref 分派,以便工作流逻辑和密钥保持受控
|
||||
- 只要解析后的提交可从 OpenClaw 分支或发布标签访问,`OpenClaw Release Checks` 就接受分支、标签或完整提交 SHA
|
||||
- `OpenClaw NPM Release` 仅验证预检也接受当前完整 40 字符工作流分支提交 SHA,无需推送标签
|
||||
- 该 SHA 路径仅用于验证,不能提升为真实发布
|
||||
- 在 SHA 模式下,工作流仅为包元数据检查合成 `v<package.json version>`;真实发布仍需要真实发布标签
|
||||
- 在 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 发布预检不再等待单独的发布检查线路
|
||||
- 在批准前运行 `RELEASE_TAG=vYYYY.M.D node --import tsx scripts/openclaw-npm-release-check.ts`(或匹配的 beta/修正版标签)
|
||||
- npm 发布后,运行 `node --import tsx scripts/openclaw-npm-postpublish-verify.ts YYYY.M.D`(或匹配的 beta/修正版版本),在全新的临时前缀中验证已发布 registry 安装路径
|
||||
- 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`,使用共享租约 Telegram 凭证池,针对已发布的 npm 包验证已安装包的新手引导、Telegram 设置和真实 Telegram E2E。本地维护者的一次性运行可以省略 Convex 变量,直接传入三个 `OPENCLAW_QA_TELEGRAM_*` 环境变量凭证。
|
||||
- 维护者可以通过手动 `NPM Telegram Beta E2E` 工作流,从 GitHub Actions 运行相同的发布后检查。它有意仅限手动,不会在每次合并时运行。
|
||||
- 维护者发布自动化现在使用预检后提升:
|
||||
- 该工作流会使用 `OPENAI_API_KEY` 和 `ANTHROPIC_API_KEY` 工作流密钥运行 `OPENCLAW_LIVE_TEST=1 OPENCLAW_LIVE_CACHE_TEST=1 pnpm test:live:cache`
|
||||
- npm 发布预检不再等待单独的发布检查通道
|
||||
- 批准前运行 `RELEASE_TAG=vYYYY.M.D node --import tsx scripts/openclaw-npm-release-check.ts`(或匹配的 beta/修正版标签)
|
||||
- npm 发布后,运行 `node --import tsx scripts/openclaw-npm-postpublish-verify.ts YYYY.M.D`(或匹配的 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`,使用共享的租赁 Telegram 凭据池,针对已发布 npm 包验证已安装包的新手引导、Telegram 设置和真实 Telegram E2E。本地维护者的一次性运行可以省略 Convex 变量,并直接传入三个 `OPENCLAW_QA_TELEGRAM_*` 环境变量凭据。
|
||||
- 维护者可以通过手动 `NPM Telegram Beta E2E` 工作流,从 GitHub Actions 运行相同的发布后检查。它有意设为仅手动,不会在每次合并时运行。
|
||||
- 维护者发布自动化现在使用先预检再提升:
|
||||
- 真实 npm 发布必须通过成功的 npm `preflight_run_id`
|
||||
- 真实 npm 发布必须从与成功预检运行相同的 `main` 或 `release/YYYY.M.D` 分支分派
|
||||
- stable npm 发布默认指向 `beta`
|
||||
- stable npm 发布可通过工作流输入显式指向 `latest`
|
||||
- 基于 token 的 npm dist-tag 变更现在位于 `openclaw/releases-private/.github/workflows/openclaw-npm-dist-tags.yml`,以保证安全,因为 `npm dist-tag add` 仍需要 `NPM_TOKEN`,而公开仓库保持仅 OIDC 发布
|
||||
- 公开 `macOS Release` 仅用于验证;当标签只存在于发布分支上、但工作流从 `main` 分派时,设置 `public_release_branch=release/YYYY.M.D`
|
||||
- 稳定 npm 发布默认使用 `beta`
|
||||
- 稳定 npm 发布可以通过工作流输入显式目标为 `latest`
|
||||
- 基于令牌的 npm dist-tag 变更现在位于 `openclaw/releases-private/.github/workflows/openclaw-npm-dist-tags.yml` 中以提升安全性,因为 `npm dist-tag add` 仍需要 `NPM_TOKEN`,而公开仓库保持仅 OIDC 发布
|
||||
- 公开 `macOS Release` 仅用于验证;当标签只存在于发布分支上但工作流从 `main` 分派时,请设置 `public_release_branch=release/YYYY.M.D`
|
||||
- 真实私有 mac 发布必须通过成功的私有 mac `preflight_run_id` 和 `validate_run_id`
|
||||
- 真实发布路径会提升已准备好的产物,而不是再次重新构建它们
|
||||
- 对于像 `YYYY.M.D-N` 这样的 stable 修正发布,发布后验证器也会检查从 `YYYY.M.D` 到 `YYYY.M.D-N` 的同一临时前缀升级路径,因此发布修正不会悄悄让旧的全局安装停留在基础 stable 载荷上
|
||||
- 除非 tarball 同时包含 `dist/control-ui/index.html` 和非空的 `dist/control-ui/assets/` 载荷,否则 npm 发布预检会失败关闭,避免我们再次发布空的浏览器仪表板
|
||||
- 发布后验证还会检查已发布插件入口点和包元数据是否存在于已安装的 registry 布局中。缺少插件运行时载荷的发布会导致 postpublish 验证器失败,且不能提升到 `latest`。
|
||||
- `pnpm test:install:smoke` 还会对候选更新 tarball 强制执行 npm pack `unpackedSize` 预算,因此安装器 e2e 会在发布路径发布前捕获意外的包体积膨胀
|
||||
- 如果发布工作触及 CI 规划、插件 timing manifest 或插件测试矩阵,请在批准前重新生成并审查由 planner 拥有的 `plugin-prerelease-extension-shard` 矩阵输出,来源为 `.github/workflows/plugin-prerelease.yml`,避免发布说明描述过时的 CI 布局
|
||||
- stable macOS 发布就绪还包括更新器表面:
|
||||
- GitHub 发布必须最终包含打包后的 `.zip`、`.dmg` 和 `.dSYM.zip`
|
||||
- 发布后,`main` 上的 `appcast.xml` 必须指向新的 stable zip
|
||||
- 打包后的应用必须保留非 debug bundle id、非空 Sparkle feed URL,以及不低于该发布版本规范 Sparkle 构建下限的 `CFBundleVersion`
|
||||
- 真实发布路径会提升已准备好的产物,而不是再次重建它们
|
||||
- 对于 `YYYY.M.D-N` 这样的稳定修正版发布,发布后验证器也会检查从 `YYYY.M.D` 到 `YYYY.M.D-N` 的相同临时前缀升级路径,确保发布修正不会悄悄让旧的全局安装停留在基础稳定负载上
|
||||
- npm 发布预检会失败关闭,除非 tarball 同时包含 `dist/control-ui/index.html` 和非空 `dist/control-ui/assets/` 负载,避免再次发布空的浏览器仪表板
|
||||
- 发布后验证还会检查已发布的插件入口点和包元数据是否存在于已安装的注册表布局中。缺少插件运行时负载的发布会导致发布后验证器失败,且不能提升到 `latest`。
|
||||
- `pnpm test:install:smoke` 还会对候选更新 tarball 强制执行 npm pack `unpackedSize` 预算,因此安装器 e2e 会在发布发布路径前捕获意外的打包膨胀
|
||||
- 如果发布工作触及 CI 规划、插件时间清单或插件测试矩阵,请在批准前重新生成并审查 `.github/workflows/plugin-prerelease.yml` 中由规划器拥有的 `plugin-prerelease-extension-shard` 矩阵输出,确保发布说明不会描述过期的 CI 布局
|
||||
- 稳定 macOS 发布就绪状态还包括更新器表面:
|
||||
- GitHub 发布最终必须包含打包后的 `.zip`、`.dmg` 和 `.dSYM.zip`
|
||||
- 发布后,`main` 上的 `appcast.xml` 必须指向新的稳定 zip
|
||||
- 打包后的应用必须保留非调试 bundle id、非空 Sparkle feed URL,以及不低于该发布版本规范 Sparkle 构建下限的 `CFBundleVersion`
|
||||
|
||||
## 发布测试盒
|
||||
## 发布 test boxes
|
||||
|
||||
`Full Release Validation` 是操作员从一个入口点启动所有预发布测试的方式。从受信任的 `main` 工作流引用运行它,并将发布分支、标签或完整提交 SHA 作为 `ref` 传入:
|
||||
`Full Release Validation` 是操作员从一个入口点启动所有预发布测试的方式。对于快速变化分支上的固定提交证明,请使用该 helper,确保每个子工作流都从固定到目标 SHA 的临时分支运行:
|
||||
|
||||
```bash
|
||||
pnpm ci:full-release --sha <full-sha>
|
||||
```
|
||||
|
||||
该 helper 会推送 `release-ci/<sha>-...`,从该分支分派 `Full Release Validation` 并传入 `ref=<sha>`,验证每个子工作流的 `headSha` 都匹配目标,然后删除临时分支。这可避免意外证明更新的 `main` 子运行。
|
||||
|
||||
对于发布分支或标签验证,请从受信任的 `main` 工作流 ref 运行它,并将发布分支或标签作为 `ref` 传入:
|
||||
|
||||
```bash
|
||||
gh workflow run full-release-validation.yml \
|
||||
@ -142,17 +163,18 @@ gh workflow run full-release-validation.yml \
|
||||
-f evidence_package_spec=openclaw@YYYY.M.D-beta.N
|
||||
```
|
||||
|
||||
该工作流会解析目标引用,使用 `target_ref=<release-ref>` 分派手动 `CI`,分派 `OpenClaw Release Checks`,并在 `release_profile=full` 且 `rerun_group=all` 时,或设置了 `npm_telegram_package_spec` 时,分派独立包 Telegram E2E。随后 `OpenClaw Release Checks` 会扩展运行安装冒烟、跨操作系统发布检查、live/E2E Docker 发布路径覆盖、带 Telegram 包 QA 的 Package Acceptance、QA Lab 一致性、live Matrix 和 live Telegram。只有当 `Full Release Validation` 摘要显示 `normal_ci` 和 `release_checks` 成功时,完整运行才可接受。在 full/all 模式下,`npm_telegram` 子项也必须成功;在 full/all 之外,除非提供了已发布的 `npm_telegram_package_spec`,否则会跳过它。最终验证器摘要包含每个子运行的最慢作业表,因此发布经理无需下载日志即可看到当前关键路径。
|
||||
请参阅 [完整发布验证](/zh-CN/reference/full-release-validation),了解完整阶段矩阵、精确工作流作业名称、stable 与 full 配置差异、产物和聚焦重跑句柄。
|
||||
子工作流会从运行 `Full Release Validation` 的受信任引用分派,通常是 `--ref main`,即使目标 `ref` 指向较旧的发布分支或标签。没有单独的 Full Release Validation 工作流引用输入;通过选择工作流运行引用来选择受信任的 harness。
|
||||
该工作流会解析目标 ref,调度带有 `target_ref=<release-ref>` 的手动 `CI`,调度 `OpenClaw Release Checks`,并在 `release_profile=full` 且 `rerun_group=all` 或设置了 `npm_telegram_package_spec` 时调度独立的 Telegram 包 E2E。随后 `OpenClaw Release Checks` 会展开安装冒烟测试、跨 OS 发布检查、实时/E2E Docker 发布路径覆盖、带 Telegram 包 QA 的 Package Acceptance、QA Lab 对等校验、实时 Matrix 和实时 Telegram。只有当 `Full Release Validation` 摘要显示 `normal_ci` 和 `release_checks` 均成功时,完整运行才可接受。在 full/all 模式下,`npm_telegram` 子项也必须成功;在 full/all 之外,除非提供了已发布的 `npm_telegram_package_spec`,否则会跳过它。最终验证器摘要包含每个子运行的最慢作业表,因此发布经理无需下载日志即可查看当前关键路径。
|
||||
请参阅[完整发布验证](/zh-CN/reference/full-release-validation),了解完整阶段矩阵、精确的工作流作业名称、stable 与 full 配置差异、构件以及聚焦重跑句柄。
|
||||
子工作流从运行 `Full Release Validation` 的受信任 ref 调度,通常是 `--ref main`,即使目标 `ref` 指向较旧的发布分支或标签也是如此。不存在单独的 Full Release Validation workflow-ref 输入;通过选择工作流运行 ref 来选择受信任的执行框架。不要在移动的 `main` 上使用 `--ref main -f ref=<sha>` 来提供精确提交证明;原始提交 SHA 不能作为工作流调度 ref,因此请使用 `pnpm ci:full-release --sha <sha>` 创建固定的临时分支。
|
||||
|
||||
使用 `release_profile` 选择 live/provider 广度:
|
||||
使用 `release_profile` 选择实时/提供商覆盖范围:
|
||||
|
||||
- `minimum`:最快的发布关键 OpenAI/core live 和 Docker 路径
|
||||
- `stable`:minimum 加上用于发布批准的 stable provider/backend 覆盖
|
||||
- `full`:stable 加上广泛的 advisory provider/media 覆盖
|
||||
- `minimum`:最快的发布关键 OpenAI/core 实时与 Docker 路径
|
||||
- `stable`:minimum 加上用于发布批准的稳定提供商/后端覆盖
|
||||
- `full`:stable 加上更广的 advisory 提供商/媒体覆盖
|
||||
|
||||
`OpenClaw Release Checks` 使用受信任的工作流 ref,将目标 ref 一次性解析为 `release-package-under-test`,并在发布路径 Docker 检查和 Package Acceptance 中复用该产物。这会让所有面向软件包的 boxes 使用相同字节,并避免重复构建软件包。跨 OS OpenAI 安装冒烟在设置了 repo/org 变量时使用 `OPENCLAW_CROSS_OS_OPENAI_MODEL`,否则使用 `openai/gpt-5.5`,因为这条 lane 证明的是软件包安装、新手引导、Gateway 网关启动和一次实时智能体轮次,而不是对最慢的默认模型做基准测试。更广泛的实时提供商矩阵仍然负责模型特定覆盖。
|
||||
`OpenClaw Release Checks` 使用受信任的工作流 ref 将目标 ref 解析一次为 `release-package-under-test`,并在发布路径 Docker 检查和 Package Acceptance 中复用该构件。这会让所有面向包的环境使用同一份字节,并避免重复构建包。
|
||||
跨 OS OpenAI 安装冒烟测试在设置了 repo/org 变量时使用 `OPENCLAW_CROSS_OS_OPENAI_MODEL`,否则使用 `openai/gpt-5.5`,因为该通道用于证明包安装、新手引导、Gateway 网关启动以及一次实时智能体轮次,而不是对最慢的默认模型做基准测试。更广的实时提供商矩阵仍然是模型特定覆盖的位置。
|
||||
|
||||
根据发布阶段使用这些变体:
|
||||
|
||||
@ -184,22 +206,23 @@ gh workflow run full-release-validation.yml \
|
||||
-f npm_telegram_provider_mode=mock-openai
|
||||
```
|
||||
|
||||
不要把完整 umbrella 作为定向修复后的首次重跑。如果某个 box 失败,下一次证明应使用失败的子工作流、job、Docker lane、软件包 profile、模型提供商或 QA lane。只有当修复更改了共享发布编排,或让之前的全 box 证据过期时,才再次运行完整 umbrella。umbrella 的最终验证器会重新检查记录的子工作流运行 id,所以在子工作流成功重跑后,只重跑失败的 `Verify full validation` 父 job。
|
||||
不要把完整总控工作流用作聚焦修复后的第一次重跑。如果某个环境失败,请使用失败的子工作流、作业、Docker 通道、包配置、模型提供商或 QA 通道作为下一次证明。只有当修复改变了共享发布编排,或让先前的全环境证据过期时,才再次运行完整总控工作流。该总控工作流的最终验证器会重新检查记录的子工作流运行 ID,因此在子工作流成功重跑后,只需重跑失败的父作业 `Verify full validation`。
|
||||
|
||||
对于有界恢复,向 umbrella 传入 `rerun_group`。`all` 是真正的候选发布运行,`ci` 只运行普通 CI 子项,`plugin-prerelease` 只运行仅发布用插件子项,`release-checks` 运行每个发布 box,更窄的发布组包括 `install-smoke`、`cross-os`、`live-e2e`、`package`、`qa`、`qa-parity`、`qa-live` 和 `npm-telegram`。定向 `npm-telegram` 重跑需要 `npm_telegram_package_spec`;带有 `release_profile=full` 的 full/all 运行使用 release-checks 软件包产物。
|
||||
对于有界恢复,向总控工作流传入 `rerun_group`。`all` 是真正的候选发布运行,`ci` 仅运行普通 CI 子项,`plugin-prerelease` 仅运行发布专用插件子项,`release-checks` 运行每个发布环境,更窄的发布组包括 `install-smoke`、`cross-os`、`live-e2e`、`package`、`qa`、`qa-parity`、`qa-live` 和 `npm-telegram`。
|
||||
聚焦的 `npm-telegram` 重跑需要 `npm_telegram_package_spec`;使用 `release_profile=full` 的 full/all 运行会使用 release-checks 包构件。
|
||||
|
||||
### Vitest
|
||||
|
||||
Vitest box 是手动 `CI` 子工作流。手动 CI 会有意绕过 changed 范围限定,并为候选发布强制运行常规测试图:Linux Node 分片、内置插件分片、渠道契约、Node 22 兼容性、`check`、`check-additional`、构建冒烟、文档检查、Python Skills、Windows、macOS、Android 和 Control UI i18n。
|
||||
Vitest 环境是手动 `CI` 子工作流。手动 CI 会有意绕过变更范围筛选,并为候选发布强制执行普通测试图:Linux Node 分片、内置插件分片、渠道契约、Node 22 兼容性、`check`、`check-additional`、构建冒烟测试、文档检查、Python Skills、Windows、macOS、Android 和 Control UI i18n。
|
||||
|
||||
使用这个 box 来回答“源码树是否通过了完整的常规测试套件?”它与发布路径产品验证不同。需要保留的证据:
|
||||
使用此环境回答“源代码树是否通过了完整普通测试套件?”它不同于发布路径产品验证。需要保留的证据:
|
||||
|
||||
- `Full Release Validation` 摘要,显示已调度的 `CI` 运行 URL
|
||||
- `CI` 在精确目标 SHA 上变绿
|
||||
- 调查回归时来自 CI jobs 的失败或较慢分片名称
|
||||
- 当运行需要性能分析时,保留 Vitest 计时产物,例如 `.artifacts/vitest-shard-timings.json`
|
||||
- `CI` 在精确目标 SHA 上为绿色
|
||||
- 调查回归时来自 CI 作业的失败或缓慢分片名称
|
||||
- 当某次运行需要性能分析时,保留 Vitest 计时构件,例如 `.artifacts/vitest-shard-timings.json`
|
||||
|
||||
只有当发布需要确定性的常规 CI,但不需要 Docker、QA Lab、实时、跨 OS 或软件包 boxes 时,才直接运行手动 CI:
|
||||
仅在发布需要确定性的普通 CI、但不需要 Docker、QA Lab、实时、跨 OS 或包环境时,才直接运行手动 CI:
|
||||
|
||||
```bash
|
||||
gh workflow run ci.yml --ref main -f target_ref=release/YYYY.M.D
|
||||
@ -207,51 +230,52 @@ gh workflow run ci.yml --ref main -f target_ref=release/YYYY.M.D
|
||||
|
||||
### Docker
|
||||
|
||||
Docker box 位于 `OpenClaw Release Checks` 中,通过 `openclaw-live-and-e2e-checks-reusable.yml` 以及发布模式的 `install-smoke` 工作流运行。它通过打包后的 Docker 环境验证候选发布,而不只是源码级测试。
|
||||
Docker 环境位于 `OpenClaw Release Checks` 中,通过 `openclaw-live-and-e2e-checks-reusable.yml` 以及发布模式 `install-smoke` 工作流运行。它通过打包的 Docker 环境验证候选发布,而不是只做源码级测试。
|
||||
|
||||
发布 Docker 覆盖包括:
|
||||
|
||||
- 启用慢速 Bun 全局安装冒烟的完整安装冒烟
|
||||
- 按目标 SHA 准备/复用根 Dockerfile 冒烟镜像,其中 QR、root/gateway 和 installer/Bun 冒烟 jobs 作为独立 install-smoke 分片运行
|
||||
- 仓库 E2E lanes
|
||||
- 发布路径 Docker chunks:`core`、`package-update-openai`、`package-update-anthropic`、`package-update-core`、`plugins-runtime-plugins`、`plugins-runtime-services`、`plugins-runtime-install-a`、`plugins-runtime-install-b`、`plugins-runtime-install-c`、`plugins-runtime-install-d`、`plugins-runtime-install-e`、`plugins-runtime-install-f`、`plugins-runtime-install-g` 和 `plugins-runtime-install-h`
|
||||
- 请求时在 `plugins-runtime-services` chunk 内进行 OpenWebUI 覆盖
|
||||
- 拆分的内置插件安装/卸载 lanes,从 `bundled-plugin-install-uninstall-0` 到 `bundled-plugin-install-uninstall-23`
|
||||
- 当发布检查包含实时套件时,运行实时/E2E 提供商套件和 Docker 实时模型覆盖
|
||||
- 启用慢速 Bun 全局安装冒烟测试的完整安装冒烟测试
|
||||
- 按目标 SHA 准备/复用根 Dockerfile 冒烟镜像,并将 QR、root/gateway、installer/Bun 冒烟作业作为独立 install-smoke 分片运行
|
||||
- 仓库 E2E 通道
|
||||
- 发布路径 Docker 分块:`core`、`package-update-openai`、`package-update-anthropic`、`package-update-core`、`plugins-runtime-plugins`、`plugins-runtime-services`、`plugins-runtime-install-a`、`plugins-runtime-install-b`、`plugins-runtime-install-c`、`plugins-runtime-install-d`、`plugins-runtime-install-e`、`plugins-runtime-install-f`、`plugins-runtime-install-g` 和 `plugins-runtime-install-h`
|
||||
- 请求时,在 `plugins-runtime-services` 分块中覆盖 OpenWebUI
|
||||
- 拆分的内置插件安装/卸载通道,从 `bundled-plugin-install-uninstall-0` 到 `bundled-plugin-install-uninstall-23`
|
||||
- 当发布检查包含实时套件时,覆盖实时/E2E 提供商套件和 Docker 实时模型
|
||||
|
||||
重跑前先使用 Docker 产物。发布路径调度器会上传 `.artifacts/docker-tests/`,其中包含 lane 日志、`summary.json`、`failures.json`、阶段计时、调度器计划 JSON 和重跑命令。对于定向恢复,在可复用实时/E2E 工作流上使用 `docker_lanes=<lane[,lane]>`,而不是重跑所有发布 chunks。生成的重跑命令会在可用时包含之前的 `package_artifact_run_id` 和已准备 Docker 镜像输入,因此失败 lane 可以复用相同 tarball 和 GHCR 镜像。
|
||||
重跑前先使用 Docker 构件。发布路径调度器会上传 `.artifacts/docker-tests/`,其中包含通道日志、`summary.json`、`failures.json`、阶段计时、调度器计划 JSON 和重跑命令。对于聚焦恢复,请在可复用实时/E2E 工作流上使用 `docker_lanes=<lane[,lane]>`,而不是重跑所有发布分块。生成的重跑命令会在可用时包含之前的 `package_artifact_run_id` 和已准备的 Docker 镜像输入,因此失败通道可以复用同一个 tarball 和 GHCR 镜像。
|
||||
|
||||
### QA Lab
|
||||
|
||||
QA Lab box 也是 `OpenClaw Release Checks` 的一部分。它是智能体行为和渠道级发布门禁,独立于 Vitest 和 Docker 软件包机制。
|
||||
QA Lab 环境也是 `OpenClaw Release Checks` 的一部分。它是智能体行为和渠道级发布门禁,独立于 Vitest 和 Docker 包机制。
|
||||
|
||||
发布 QA Lab 覆盖包括:
|
||||
|
||||
- mock parity gate,使用 agentic parity pack 将 OpenAI 候选 lane 与 Opus 4.6 基线对比
|
||||
- 使用 `qa-live-shared` 环境的快速实时 Matrix QA profile
|
||||
- 使用 Convex CI 凭据租约的实时 Telegram QA lane
|
||||
- 当发布遥测需要明确本地证明时,运行 `pnpm qa:otel:smoke`
|
||||
- 使用 agentic parity pack 将 OpenAI 候选通道与 Opus 4.6 基线进行比较的 mock 对等门禁
|
||||
- 使用 `qa-live-shared` 环境的快速实时 Matrix QA 配置
|
||||
- 使用 Convex CI 凭证租约的实时 Telegram QA 通道
|
||||
- 当发布遥测需要显式本地证明时运行 `pnpm qa:otel:smoke`
|
||||
|
||||
使用这个 box 来回答“发布在 QA 场景和实时渠道流中是否表现正确?”批准发布时保留 parity、Matrix 和 Telegram lanes 的产物 URL。完整 Matrix 覆盖仍可作为手动分片 QA-Lab 运行使用,而不是默认的发布关键 lane。
|
||||
使用此环境回答“发布版在 QA 场景和实时渠道流程中是否表现正确?”批准发布时,请保留 parity、Matrix 和 Telegram 通道的构件 URL。完整 Matrix 覆盖仍可作为手动分片 QA-Lab 运行使用,而不是默认的发布关键通道。
|
||||
|
||||
### 软件包
|
||||
### Package
|
||||
|
||||
软件包 box 是可安装产品门禁。它由 `Package Acceptance` 和解析器 `scripts/resolve-openclaw-package-candidate.mjs` 支撑。解析器会将候选规范化为供 Docker E2E 使用的 `package-under-test` tarball,验证软件包清单,记录软件包版本和 SHA-256,并将工作流 harness ref 与软件包源码 ref 分开。
|
||||
Package 环境是可安装产品门禁。它由 `Package Acceptance` 和解析器 `scripts/resolve-openclaw-package-candidate.mjs` 支持。解析器会将候选项规范化为 Docker E2E 消费的 `package-under-test` tarball,验证包清单,记录包版本和 SHA-256,并将工作流执行框架 ref 与包来源 ref 分开。
|
||||
|
||||
支持的候选来源:
|
||||
|
||||
- `source=npm`:`openclaw@beta`、`openclaw@latest` 或精确的 OpenClaw 发布版本
|
||||
- `source=ref`:使用选定的 `workflow_ref` harness 打包受信任的 `package_ref` 分支、tag 或完整 commit SHA
|
||||
- `source=npm`:`openclaw@beta`、`openclaw@latest`,或精确的 OpenClaw 发布版本
|
||||
- `source=ref`:使用选定的 `workflow_ref` 执行框架打包受信任的 `package_ref` 分支、标签或完整提交 SHA
|
||||
- `source=url`:下载需要 `package_sha256` 的 HTTPS `.tgz`
|
||||
- `source=artifact`:复用另一个 GitHub Actions 运行上传的 `.tgz`
|
||||
|
||||
`OpenClaw Release Checks` 使用 `source=artifact`、已准备的发布软件包产物、`suite_profile=custom`、`docker_lanes=doctor-switch update-channel-switch upgrade-survivor published-upgrade-survivor plugins-offline plugin-update`、`published_upgrade_survivor_baselines=release-history`、`published_upgrade_survivor_scenarios=reported-issues` 和 `telegram_mode=mock-openai` 运行 Package Acceptance。Package Acceptance 会让迁移、更新、过期插件依赖清理、离线插件 fixtures、插件更新和 Telegram 软件包 QA 使用同一个已解析 tarball。它是 GitHub 原生的替代方案,用于覆盖此前大多需要 Parallels 的软件包/更新验证。跨 OS 发布检查对于 OS 特定的新手引导、安装器和平台行为仍然重要,但软件包/更新产品验证应优先使用 Package Acceptance。
|
||||
`OpenClaw Release Checks` 使用 `source=artifact`、已准备的发布包构件、`suite_profile=custom`、`docker_lanes=doctor-switch update-channel-switch upgrade-survivor published-upgrade-survivor plugins-offline plugin-update`、`published_upgrade_survivor_baselines=release-history`、`published_upgrade_survivor_scenarios=reported-issues` 和 `telegram_mode=mock-openai` 运行 Package Acceptance。Package Acceptance 会针对同一个已解析 tarball 保持迁移、更新、陈旧插件依赖清理、离线插件 fixture、插件更新和 Telegram 包 QA。它是 GitHub 原生替代方案,用于取代过去多数需要 Parallels 的包/更新覆盖。跨 OS 发布检查对于 OS 特定的新手引导、安装器和平台行为仍然重要,但包/更新产品验证应优先使用 Package Acceptance。
|
||||
|
||||
更新和插件验证的标准清单是 [更新和插件测试](/zh-CN/help/testing-updates-plugins)。在判断哪条本地、Docker、Package Acceptance 或 release-check lane 能证明插件安装/更新、Doctor 清理或已发布软件包迁移变更时使用它。从每个稳定版 `2026.4.23+` 软件包进行的穷尽式已发布更新迁移是单独的手动 `Update Migration` 工作流,不属于 Full Release CI。
|
||||
更新和插件验证的规范清单是[更新和插件测试](/zh-CN/help/testing-updates-plugins)。在判断哪个本地、Docker、Package Acceptance 或 release-check 通道可证明插件安装/更新、Doctor 清理或已发布包迁移变更时,请使用它。
|
||||
从每个稳定版 `2026.4.23+` 包进行的完整已发布更新迁移是单独的手动 `Update Migration` 工作流,不属于 Full Release CI。
|
||||
|
||||
旧版 package-acceptance 宽松处理是有意限时的。直到 `2026.4.25` 的软件包可以对已发布到 npm 的元数据缺口使用兼容路径:tarball 中缺少私有 QA 清单条目、缺少 `gateway install --wrapper`、tarball 派生 git fixture 中缺少补丁文件、缺少持久化的 `update.channel`、旧版插件安装记录位置、缺少 marketplace 安装记录持久化,以及 `plugins update` 期间的配置元数据迁移。已发布的 `2026.4.26` 软件包可以对已经发布的本地构建元数据 stamp 文件发出警告。后续软件包必须满足现代软件包契约;相同缺口会导致发布验证失败。
|
||||
旧版 package-acceptance 宽松策略是有意限时的。到 `2026.4.25` 为止的包可以对已经发布到 npm 的元数据缺口使用兼容路径:tarball 中缺失私有 QA 清单条目、缺失 `gateway install --wrapper`、tarball 派生 git fixture 中缺失补丁文件、缺失持久化的 `update.channel`、旧版插件安装记录位置、缺失 marketplace 安装记录持久化,以及 `plugins update` 期间的配置元数据迁移。已发布的 `2026.4.26` 包可能会对已交付的本地构建元数据 stamp 文件发出警告。之后的包必须满足现代包契约;这些同样的缺口会导致发布验证失败。
|
||||
|
||||
当发布问题涉及实际可安装软件包时,使用更广泛的 Package Acceptance profiles:
|
||||
当发布问题涉及实际可安装包时,使用更广的 Package Acceptance 配置:
|
||||
|
||||
```bash
|
||||
gh workflow run package-acceptance.yml \
|
||||
@ -263,72 +287,67 @@ gh workflow run package-acceptance.yml \
|
||||
-f published_upgrade_survivor_baseline=openclaw@2026.4.26
|
||||
```
|
||||
|
||||
常用软件包 profiles:
|
||||
常见包配置:
|
||||
|
||||
- `smoke`:快速软件包安装/渠道/智能体、Gateway 网关网络和配置重载 lanes
|
||||
- `package`:不含实时 ClawHub 的安装/更新/插件软件包契约;这是 release-check 默认值
|
||||
- `smoke`:快速包安装/渠道/智能体、Gateway 网关网络和配置重载通道
|
||||
- `package`:不含实时 ClawHub 的安装/更新/插件包契约;这是 release-check 默认值
|
||||
- `product`:`package` 加上 MCP 渠道、cron/subagent 清理、OpenAI web 搜索和 OpenWebUI
|
||||
- `full`:带 OpenWebUI 的 Docker 发布路径 chunks
|
||||
- `custom`:用于定向重跑的精确 `docker_lanes` 列表
|
||||
- `full`:带 OpenWebUI 的 Docker 发布路径分块
|
||||
- `custom`:用于聚焦重跑的精确 `docker_lanes` 列表
|
||||
|
||||
对于软件包候选 Telegram 证明,在 Package Acceptance 上启用 `telegram_mode=mock-openai` 或 `telegram_mode=live-frontier`。该工作流会将已解析的 `package-under-test` tarball 传入 Telegram lane;独立 Telegram 工作流仍接受用于发布后检查的已发布 npm 规范。
|
||||
对于包候选版本的 Telegram 验证,在包验收中启用 `telegram_mode=mock-openai` 或
|
||||
`telegram_mode=live-frontier`。该工作流会将解析后的 `package-under-test` tarball 传入 Telegram 通道;独立的
|
||||
Telegram 工作流仍接受已发布的 npm 规范,用于发布后的检查。
|
||||
|
||||
## NPM 工作流输入
|
||||
|
||||
`OpenClaw NPM Release` 接受这些操作员控制的输入:
|
||||
`OpenClaw NPM Release` 接受这些由操作者控制的输入:
|
||||
|
||||
- `tag`:必需的发布 tag,例如 `v2026.4.2`、`v2026.4.2-1` 或 `v2026.4.2-beta.1`;当 `preflight_only=true` 时,它也可以是当前工作流分支的完整 40 字符 commit SHA,用于仅验证 preflight
|
||||
- `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`:真实发布路径必需,这样工作流可复用成功 preflight 运行中准备好的 tarball
|
||||
- `npm_dist_tag`:发布路径的 npm 目标 tag;默认为 `beta`
|
||||
- `preflight_run_id`:真实发布路径必填,以便工作流复用成功预检运行中准备好的 tarball
|
||||
- `npm_dist_tag`:发布路径的 npm 目标标签;默认值为 `beta`
|
||||
|
||||
`OpenClaw Release Checks` 接受这些操作员控制的输入:
|
||||
`OpenClaw Release Checks` 接受这些由操作者控制的输入:
|
||||
|
||||
- `ref`:要验证的分支、tag 或完整 commit SHA。带密钥的检查要求解析出的 commit 可从 OpenClaw 分支或发布 tag 到达。
|
||||
- `ref`:要验证的分支、标签或完整提交 SHA。带有密钥的检查要求解析后的提交可从某个 OpenClaw 分支或发布标签访问。
|
||||
|
||||
规则:
|
||||
|
||||
- 稳定版和修正版 tag 可以发布到 `beta` 或 `latest`
|
||||
- Beta 预发布 tag 只能发布到 `beta`
|
||||
- 对于 `OpenClaw NPM Release`,只有在 `preflight_only=true` 时才允许完整 commit SHA 输入
|
||||
- `OpenClaw Release Checks` 和 `Full Release Validation` 始终只做验证
|
||||
- 真实发布路径必须使用 preflight 期间使用的同一个 `npm_dist_tag`;工作流会在发布继续前验证该元数据
|
||||
- 稳定版和修正版标签可以发布到 `beta` 或 `latest`
|
||||
- Beta 预发布标签只能发布到 `beta`
|
||||
- 对于 `OpenClaw NPM Release`,仅当 `preflight_only=true` 时才允许输入完整提交 SHA
|
||||
- `OpenClaw Release Checks` 和 `Full Release Validation` 始终仅用于验证
|
||||
- 真实发布路径必须使用与预检期间相同的 `npm_dist_tag`;工作流会在发布继续之前验证该元数据
|
||||
|
||||
## 稳定版 npm 发布流程
|
||||
|
||||
切稳定版 npm 发布时:
|
||||
|
||||
1. 运行 `OpenClaw NPM Release`,并设置 `preflight_only=true`
|
||||
- 在标签存在之前,你可以使用当前完整工作流分支提交
|
||||
SHA 对预检工作流执行一次仅验证的试运行
|
||||
2. 为常规 beta 优先流程选择 `npm_dist_tag=beta`,只有在你有意直接发布稳定版时才选择 `latest`
|
||||
3. 当你希望通过一个手动工作流获得常规 CI,以及实时提示缓存、Docker、QA Lab、
|
||||
Matrix 和 Telegram 覆盖时,请在发布分支、发布标签或完整
|
||||
提交 SHA 上运行 `Full Release Validation`
|
||||
4. 如果你明确只需要确定性的常规测试图,请改为在发布引用上运行
|
||||
手动 `CI` 工作流
|
||||
1. 运行 `OpenClaw NPM Release` 并设置 `preflight_only=true`
|
||||
- 在标签存在之前,你可以使用当前完整的工作流分支提交 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-tags 都指向该稳定版本,或者让它的计划
|
||||
自修复同步稍后移动 `beta`
|
||||
也应立即跟随同一个稳定版构建,请使用同一个私有工作流将两个 dist-tag 都指向该稳定版本,或让它的定时自愈同步稍后移动 `beta`
|
||||
|
||||
出于安全原因,dist-tag 变更位于私有仓库中,因为它仍然
|
||||
需要 `NPM_TOKEN`,而公开仓库保持仅 OIDC 发布。
|
||||
dist-tag 变更位于私有仓库中是出于安全考虑,因为它仍然需要
|
||||
`NPM_TOKEN`,而公共仓库保持仅 OIDC 发布。
|
||||
|
||||
这样会让直接发布路径和 beta 优先提升路径都
|
||||
有文档记录,并且对操作人员可见。
|
||||
这会让直接发布路径和先 beta 后提升路径都保持有文档记录,并且对操作者可见。
|
||||
|
||||
如果维护者必须回退到本地 npm 身份验证,请只在专用 tmux 会话中运行任何 1Password
|
||||
CLI(`op`)命令。不要直接从主智能体 shell 调用 `op`;将它保留在 tmux 中可以让提示、
|
||||
警报和 OTP 处理可观察,并防止重复的主机警报。
|
||||
CLI(`op`)命令。不要从主智能体 shell 直接调用 `op`;将它保持在 tmux 内部可以让提示、警报和 OTP 处理可观察,并防止重复的主机警报。
|
||||
|
||||
## 公共参考资料
|
||||
## 公共参考
|
||||
|
||||
- [`.github/workflows/full-release-validation.yml`](https://github.com/openclaw/openclaw/blob/main/.github/workflows/full-release-validation.yml)
|
||||
- [`.github/workflows/package-acceptance.yml`](https://github.com/openclaw/openclaw/blob/main/.github/workflows/package-acceptance.yml)
|
||||
@ -344,6 +363,6 @@ CLI(`op`)命令。不要直接从主智能体 shell 调用 `op`;将它保
|
||||
[`openclaw/maintainers/release/README.md`](https://github.com/openclaw/maintainers/blob/main/release/README.md)
|
||||
中的私有发布文档作为实际运行手册。
|
||||
|
||||
## 相关内容
|
||||
## 相关
|
||||
|
||||
- [发布渠道](/zh-CN/install/development-channels)
|
||||
|
||||
@ -1,32 +1,33 @@
|
||||
---
|
||||
read_when:
|
||||
- 你想使用 Gemini 进行 web_search
|
||||
- 你需要一个 GEMINI_API_KEY
|
||||
- 你想要 Google Search 作为事实依据
|
||||
summary: 基于 Google Search 依据增强的 Gemini 网页搜索
|
||||
- 你需要 GEMINI_API_KEY 或 models.providers.google.apiKey
|
||||
- 你想要使用 Google Search 进行事实依据增强
|
||||
summary: 使用 Google Search 事实依据增强的 Gemini 网页搜索
|
||||
title: Gemini 搜索
|
||||
x-i18n:
|
||||
generated_at: "2026-05-02T04:04:58Z"
|
||||
generated_at: "2026-05-02T04:48:27Z"
|
||||
model: gpt-5.5
|
||||
provider: openai
|
||||
source_hash: e48b73a59f1af08cb1e30f149a18534dc76ba8dff26935d83fe8ccdaa8ab74e6
|
||||
source_hash: 015d77fef123b1fd99d43eb6472bb8c672585328e17735d1fa0ead387cd2066a
|
||||
source_path: tools/gemini-search.md
|
||||
workflow: 16
|
||||
---
|
||||
|
||||
OpenClaw 支持带内置
|
||||
OpenClaw 支持内置
|
||||
[Google Search grounding](https://ai.google.dev/gemini-api/docs/grounding)
|
||||
的 Gemini 模型,它会返回由实时 Google Search 结果支持并带有引用的 AI 合成答案。
|
||||
的 Gemini 模型,这会返回由实时 Google Search 结果支持、带有引用的 AI 综合答案。
|
||||
|
||||
## 获取 API key
|
||||
|
||||
<Steps>
|
||||
<Step title="Create a key">
|
||||
<Step title="创建 key">
|
||||
前往 [Google AI Studio](https://aistudio.google.com/apikey) 并创建一个
|
||||
API key。
|
||||
</Step>
|
||||
<Step title="Store the key">
|
||||
在 Gateway 网关环境中设置 `GEMINI_API_KEY`,或通过以下方式配置:
|
||||
<Step title="存储 key">
|
||||
在 Gateway 网关环境中设置 `GEMINI_API_KEY`,复用
|
||||
`models.providers.google.apiKey`,或通过以下方式配置专用 Web 搜索 key:
|
||||
|
||||
```bash
|
||||
openclaw configure --section web
|
||||
@ -44,8 +45,8 @@ OpenClaw 支持带内置
|
||||
google: {
|
||||
config: {
|
||||
webSearch: {
|
||||
apiKey: "AIza...", // optional if GEMINI_API_KEY is set
|
||||
baseUrl: "https://generativelanguage.googleapis.com/v1beta", // optional proxy/base URL override
|
||||
apiKey: "AIza...", // optional if GEMINI_API_KEY or models.providers.google.apiKey is set
|
||||
baseUrl: "https://generativelanguage.googleapis.com/v1beta", // optional; falls back to models.providers.google.baseUrl
|
||||
model: "gemini-2.5-flash", // default
|
||||
},
|
||||
},
|
||||
@ -62,27 +63,27 @@ OpenClaw 支持带内置
|
||||
}
|
||||
```
|
||||
|
||||
**环境替代方案:**在 Gateway 网关环境中设置 `GEMINI_API_KEY`。
|
||||
对于 Gateway 网关安装,请将它放在 `~/.openclaw/.env` 中。
|
||||
**凭据优先级:** Gemini Web 搜索首先使用
|
||||
`plugins.entries.google.config.webSearch.apiKey`,然后是 `GEMINI_API_KEY`,
|
||||
再然后是 `models.providers.google.apiKey`。对于 base URL,专用的
|
||||
`plugins.entries.google.config.webSearch.baseUrl` 优先于
|
||||
`models.providers.google.baseUrl`。
|
||||
|
||||
对于 Gateway 网关安装,请将环境 key 放在 `~/.openclaw/.env` 中。
|
||||
|
||||
## 工作原理
|
||||
|
||||
不同于返回链接和摘要列表的传统搜索提供商,Gemini 使用 Google Search grounding 来生成带有内联引用的 AI 合成答案。结果同时包含合成答案和源
|
||||
URL。
|
||||
不同于返回链接和摘要列表的传统搜索提供商,Gemini 使用 Google Search grounding 来生成带有内联引用的 AI 综合答案。结果同时包含综合答案和来源 URL。
|
||||
|
||||
- 来自 Gemini grounding 的引用 URL 会自动从 Google
|
||||
重定向 URL 解析为直接 URL。
|
||||
- 重定向解析会使用 SSRF 防护路径(HEAD + 重定向检查 +
|
||||
http/https 校验),然后返回最终引用 URL。
|
||||
- 重定向解析使用严格的 SSRF 默认设置,因此指向
|
||||
私有/内部目标的重定向会被阻止。
|
||||
- Gemini grounding 的引用 URL 会自动从 Google 重定向 URL 解析为直接 URL。
|
||||
- 重定向解析在返回最终引用 URL 之前,会使用 SSRF 防护路径(HEAD + 重定向检查 + http/https 校验)。
|
||||
- 重定向解析使用严格的 SSRF 默认值,因此会阻止重定向到私有/内部目标。
|
||||
|
||||
## 支持的参数
|
||||
|
||||
Gemini 搜索支持 `query`、`freshness`、`date_after` 和 `date_before`。
|
||||
|
||||
`count` 可用于兼容共享的 `web_search`,但 Gemini grounding
|
||||
仍会返回一个带引用的合成答案,而不是 N 条结果列表。
|
||||
`count` 会被接受以兼容共享的 `web_search`,但 Gemini grounding 仍会返回一个带引用的综合答案,而不是 N 条结果的列表。
|
||||
|
||||
`freshness` 接受 `day`、`week`、`month`、`year`,以及共享快捷值
|
||||
`pd`、`pw`、`pm` 和 `py`。OpenClaw 会将这些值,或显式的
|
||||
@ -96,12 +97,12 @@ Gemini 搜索支持 `query`、`freshness`、`date_after` 和 `date_before`。
|
||||
|
||||
## Base URL 覆盖
|
||||
|
||||
当 Gemini Web 搜索必须通过运营方代理或自定义 Gemini 兼容端点路由时,请设置
|
||||
`plugins.entries.google.config.webSearch.baseUrl`。普通的
|
||||
当 Gemini Web 搜索必须通过运营方代理或自定义 Gemini 兼容端点路由时,设置
|
||||
`plugins.entries.google.config.webSearch.baseUrl`。如果未设置,Gemini Web 搜索会复用 `models.providers.google.baseUrl`。普通的
|
||||
`https://generativelanguage.googleapis.com` 值会被规范化为
|
||||
`https://generativelanguage.googleapis.com/v1beta`;自定义代理路径会在去除末尾斜杠后按提供值保留。
|
||||
`https://generativelanguage.googleapis.com/v1beta`;自定义代理路径会在去除尾随斜杠后按原样保留。
|
||||
|
||||
## 相关
|
||||
## 相关内容
|
||||
|
||||
- [Web 搜索概览](/zh-CN/tools/web) -- 所有提供商和自动检测
|
||||
- [Brave Search](/zh-CN/tools/brave-search) -- 带摘要的结构化结果
|
||||
|
||||
@ -1,32 +1,30 @@
|
||||
---
|
||||
read_when:
|
||||
- 你想将 MiniMax 用于 `web_search`
|
||||
- 你需要一个 MiniMax Coding Plan key
|
||||
- 你想了解 MiniMax 中国区 / 全球搜索主机的配置指引
|
||||
summary: 通过 Coding Plan 搜索 API 使用 MiniMax Search
|
||||
- 你想使用 MiniMax 进行 web_search
|
||||
- 你需要 MiniMax Token Plan key 或 OAuth token
|
||||
- 你需要 MiniMax 中国/全球搜索主机指南
|
||||
summary: 通过 Token Plan 搜索 API 使用 MiniMax 搜索
|
||||
title: MiniMax 搜索
|
||||
x-i18n:
|
||||
generated_at: "2026-04-23T21:09:10Z"
|
||||
model: gpt-5.4
|
||||
generated_at: "2026-05-02T04:48:49Z"
|
||||
model: gpt-5.5
|
||||
provider: openai
|
||||
source_hash: 20a91bfae72661efd5e0bc3b6247ab05c3487db40ecd9cd5a874858bf3c69df3
|
||||
source_hash: cf721a293d6b244e69d952f433bde83417eb907ef8c0b46d04a567f1b668a32e
|
||||
source_path: tools/minimax-search.md
|
||||
workflow: 15
|
||||
workflow: 16
|
||||
---
|
||||
|
||||
OpenClaw 支持将 MiniMax 作为 `web_search` 提供商,通过 MiniMax
|
||||
Coding Plan 搜索 API 使用。它会返回结构化搜索结果,包括标题、URL、
|
||||
摘要以及相关查询。
|
||||
OpenClaw 通过 MiniMax Token Plan 搜索 API 支持将 MiniMax 作为 `web_search` 提供商。它会返回带有标题、URL、摘要和相关查询的结构化搜索结果。
|
||||
|
||||
## 获取 Coding Plan key
|
||||
## 获取 Token Plan 凭证
|
||||
|
||||
<Steps>
|
||||
<Step title="创建 key">
|
||||
在
|
||||
[MiniMax Platform](https://platform.minimax.io/user-center/basic-information/interface-key) 创建或复制一个 MiniMax Coding Plan key。
|
||||
<Step title="创建密钥">
|
||||
从 [MiniMax Platform](https://platform.minimax.io/user-center/basic-information/interface-key) 创建或复制 MiniMax Token Plan 密钥。
|
||||
OAuth 设置可以改用 `MINIMAX_OAUTH_TOKEN`。
|
||||
</Step>
|
||||
<Step title="存储 key">
|
||||
在 Gateway 网关环境中设置 `MINIMAX_CODE_PLAN_KEY`,或通过以下命令配置:
|
||||
<Step title="存储密钥">
|
||||
在 Gateway 网关环境中设置 `MINIMAX_CODE_PLAN_KEY`,或通过以下方式配置:
|
||||
|
||||
```bash
|
||||
openclaw configure --section web
|
||||
@ -35,8 +33,7 @@ Coding Plan 搜索 API 使用。它会返回结构化搜索结果,包括标题
|
||||
</Step>
|
||||
</Steps>
|
||||
|
||||
OpenClaw 也接受 `MINIMAX_CODING_API_KEY` 作为环境变量别名。当 `MINIMAX_API_KEY`
|
||||
已经指向 coding-plan token 时,它仍会作为兼容性回退被读取。
|
||||
OpenClaw 也接受 `MINIMAX_CODING_API_KEY` 和 `MINIMAX_OAUTH_TOKEN` 作为环境变量别名。当 `MINIMAX_API_KEY` 已指向 Token Plan 凭证时,仍会将其作为兼容性回退读取。
|
||||
|
||||
## 配置
|
||||
|
||||
@ -47,7 +44,7 @@ OpenClaw 也接受 `MINIMAX_CODING_API_KEY` 作为环境变量别名。当 `MINI
|
||||
minimax: {
|
||||
config: {
|
||||
webSearch: {
|
||||
apiKey: "sk-cp-...", // 如果已设置 MINIMAX_CODE_PLAN_KEY,则可选
|
||||
apiKey: "sk-cp-...", // optional if a MiniMax Token Plan env var is set
|
||||
region: "global", // or "cn"
|
||||
},
|
||||
},
|
||||
@ -64,41 +61,37 @@ OpenClaw 也接受 `MINIMAX_CODING_API_KEY` 作为环境变量别名。当 `MINI
|
||||
}
|
||||
```
|
||||
|
||||
**环境变量替代方式:** 在 Gateway 网关环境中设置 `MINIMAX_CODE_PLAN_KEY`。
|
||||
**环境变量替代方式:**在 Gateway 网关环境中设置 `MINIMAX_CODE_PLAN_KEY` 或 `MINIMAX_OAUTH_TOKEN`。
|
||||
对于 Gateway 网关安装,请将其放入 `~/.openclaw/.env`。
|
||||
|
||||
## 地区选择
|
||||
## 区域选择
|
||||
|
||||
MiniMax Search 使用以下端点:
|
||||
MiniMax Search 使用这些端点:
|
||||
|
||||
- 全球:`https://api.minimax.io/v1/coding_plan/search`
|
||||
- 中国区:`https://api.minimaxi.com/v1/coding_plan/search`
|
||||
- 中国大陆:`https://api.minimaxi.com/v1/coding_plan/search`
|
||||
|
||||
如果未设置 `plugins.entries.minimax.config.webSearch.region`,OpenClaw 会按以下顺序解析
|
||||
地区:
|
||||
如果未设置 `plugins.entries.minimax.config.webSearch.region`,OpenClaw 会按以下顺序解析区域:
|
||||
|
||||
1. `tools.web.search.minimax.region` / 插件自有 `webSearch.region`
|
||||
1. `tools.web.search.minimax.region` / 插件拥有的 `webSearch.region`
|
||||
2. `MINIMAX_API_HOST`
|
||||
3. `models.providers.minimax.baseUrl`
|
||||
4. `models.providers.minimax-portal.baseUrl`
|
||||
|
||||
这意味着,中国区新手引导,或设置了 `MINIMAX_API_HOST=https://api.minimaxi.com/...`
|
||||
时,也会自动让 MiniMax Search 走中国区主机。
|
||||
这意味着中国大陆新手引导或 `MINIMAX_API_HOST=https://api.minimaxi.com/...` 也会自动让 MiniMax Search 使用中国大陆主机。
|
||||
|
||||
即使你是通过 OAuth `minimax-portal` 路径完成 MiniMax 认证,
|
||||
网页搜索仍然会注册为提供商 id `minimax`;OAuth 提供商 base URL
|
||||
仅用于作为中国区 / 全球主机选择的地区提示。
|
||||
即使你通过 OAuth 的 `minimax-portal` 路径认证 MiniMax,Web 搜索仍会注册为提供商 ID `minimax`;OAuth 提供商基础 URL 会作为中国大陆/全球主机选择的区域提示,并且 `MINIMAX_OAUTH_TOKEN` 可以满足 MiniMax Search 的 bearer 凭证要求。
|
||||
|
||||
## 支持的参数
|
||||
|
||||
MiniMax Search 支持:
|
||||
|
||||
- `query`
|
||||
- `count`(OpenClaw 会将返回的结果列表裁剪到所请求的数量)
|
||||
- `count`(OpenClaw 会将返回的结果列表裁剪到请求的数量)
|
||||
|
||||
目前尚不支持提供商专用过滤项。
|
||||
目前不支持提供商特定的筛选器。
|
||||
|
||||
## 相关内容
|
||||
|
||||
- [网页搜索概览](/zh-CN/tools/web) -- 所有提供商与自动检测
|
||||
- [MiniMax](/zh-CN/providers/minimax) -- 模型、图像、语音与认证设置
|
||||
- [Web Search 概览](/zh-CN/tools/web) -- 所有提供商和自动检测
|
||||
- [MiniMax](/zh-CN/providers/minimax) -- 模型、图像、语音和认证设置
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
---
|
||||
read_when:
|
||||
- 你想要启用或配置 web_search
|
||||
- 你想启用或配置 web_search
|
||||
- 你想启用或配置 x_search
|
||||
- 你需要选择一个搜索提供商
|
||||
- 你想了解自动检测和提供商回退
|
||||
@ -8,39 +8,35 @@ sidebarTitle: Web Search
|
||||
summary: web_search、x_search 和 web_fetch -- 搜索 Web、搜索 X 帖子,或获取页面内容
|
||||
title: Web 搜索
|
||||
x-i18n:
|
||||
generated_at: "2026-05-02T04:04:58Z"
|
||||
generated_at: "2026-05-02T04:49:11Z"
|
||||
model: gpt-5.5
|
||||
provider: openai
|
||||
source_hash: 6112a067d6261dcad47a3a83c5185e6e492693b6df6a9d0bb2ca83d7ce2294cb
|
||||
source_hash: 6200b148d750e1ed7205bd256ba6d33b4f6491577ba7544a684ffd11990ac274
|
||||
source_path: tools/web.md
|
||||
workflow: 16
|
||||
---
|
||||
|
||||
`web_search` 工具会使用你配置的提供商搜索 Web,并返回结果。结果会按查询缓存 15 分钟(可配置)。
|
||||
`web_search` 工具会使用你配置的提供商搜索网页并返回结果。结果会按查询缓存 15 分钟(可配置)。
|
||||
|
||||
OpenClaw 还包含用于 X(原 Twitter)帖子的 `x_search`,以及用于轻量级 URL 获取的 `web_fetch`。在此阶段,`web_fetch` 保持本地执行,而 `web_search` 和 `x_search` 可以在底层使用 xAI Responses。
|
||||
OpenClaw 还包含用于 X(原 Twitter)帖子的 `x_search`,以及用于轻量 URL 获取的 `web_fetch`。在此阶段,`web_fetch` 保持本地执行,而 `web_search` 和 `x_search` 可以在底层使用 xAI Responses。
|
||||
|
||||
<Info>
|
||||
`web_search` 是轻量级 HTTP 工具,不是浏览器自动化。对于
|
||||
JS 密集型站点或登录,请使用 [Web Browser](/zh-CN/tools/browser)。对于
|
||||
获取特定 URL,请使用 [Web Fetch](/zh-CN/tools/web-fetch)。
|
||||
`web_search` 是轻量级 HTTP 工具,不是浏览器自动化。对于大量依赖 JS 的站点或登录场景,请使用 [Web 浏览器](/zh-CN/tools/browser)。要获取特定 URL,请使用 [Web 获取](/zh-CN/tools/web-fetch)。
|
||||
</Info>
|
||||
|
||||
## 快速开始
|
||||
|
||||
<Steps>
|
||||
<Step title="选择提供商">
|
||||
选择一个提供商并完成所有必需设置。某些提供商无需密钥,
|
||||
另一些则使用 API key。详情请参阅下面的提供商页面。
|
||||
选择一个提供商,并完成所有必需设置。有些提供商免密钥,另一些则使用 API 密钥。详情见下面的提供商页面。
|
||||
</Step>
|
||||
<Step title="配置">
|
||||
```bash
|
||||
openclaw configure --section web
|
||||
```
|
||||
这会存储提供商和任何所需凭证。你也可以设置环境变量
|
||||
(例如 `BRAVE_API_KEY`),并对 API 支持的提供商跳过此步骤。
|
||||
这会存储提供商和任何所需凭证。你也可以设置一个环境变量(例如 `BRAVE_API_KEY`),并为 API 支持的提供商跳过此步骤。
|
||||
</Step>
|
||||
<Step title="使用它">
|
||||
<Step title="使用">
|
||||
智能体现在可以调用 `web_search`:
|
||||
|
||||
```javascript
|
||||
@ -60,37 +56,37 @@ OpenClaw 还包含用于 X(原 Twitter)帖子的 `x_search`,以及用于
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="Brave Search" icon="shield" href="/zh-CN/tools/brave-search">
|
||||
带摘要片段的结构化结果。支持 `llm-context` 模式、国家/语言筛选器。提供免费层级。
|
||||
带摘要片段的结构化结果。支持 `llm-context` 模式、国家/语言筛选条件。提供免费层级。
|
||||
</Card>
|
||||
<Card title="DuckDuckGo" icon="bird" href="/zh-CN/tools/duckduckgo-search">
|
||||
无需密钥的备用方案。不需要 API key。基于非官方 HTML 的集成。
|
||||
免密钥后备方案。无需 API 密钥。基于非官方 HTML 的集成。
|
||||
</Card>
|
||||
<Card title="Exa" icon="brain" href="/zh-CN/tools/exa-search">
|
||||
神经搜索 + 关键词搜索,并提供内容提取(高亮、文本、摘要)。
|
||||
</Card>
|
||||
<Card title="Firecrawl" icon="flame" href="/zh-CN/tools/firecrawl">
|
||||
结构化结果。最适合与 `firecrawl_search` 和 `firecrawl_scrape` 配合用于深度提取。
|
||||
结构化结果。最适合与 `firecrawl_search` 和 `firecrawl_scrape` 搭配,用于深度提取。
|
||||
</Card>
|
||||
<Card title="Gemini" icon="sparkles" href="/zh-CN/tools/gemini-search">
|
||||
通过 Google Search grounding 提供带引用的 AI 综合答案。
|
||||
通过 Google Search grounding 提供带引用的 AI 综合回答。
|
||||
</Card>
|
||||
<Card title="Grok" icon="zap" href="/zh-CN/tools/grok-search">
|
||||
通过 xAI web grounding 提供带引用的 AI 综合答案。
|
||||
通过 xAI web grounding 提供带引用的 AI 综合回答。
|
||||
</Card>
|
||||
<Card title="Kimi" icon="moon" href="/zh-CN/tools/kimi-search">
|
||||
通过 Moonshot Web 搜索提供带引用的 AI 综合答案。
|
||||
通过 Moonshot 网页搜索提供带引用的 AI 综合回答。
|
||||
</Card>
|
||||
<Card title="MiniMax Search" icon="globe" href="/zh-CN/tools/minimax-search">
|
||||
通过 MiniMax Coding Plan 搜索 API 提供结构化结果。
|
||||
通过 MiniMax Token Plan 搜索 API 提供结构化结果。
|
||||
</Card>
|
||||
<Card title="Ollama Web Search" icon="globe" href="/zh-CN/tools/ollama-search">
|
||||
通过已登录的本地 Ollama 主机或托管的 Ollama API 搜索。
|
||||
<Card title="Ollama Web 搜索" icon="globe" href="/zh-CN/tools/ollama-search">
|
||||
通过已登录的本地 Ollama 主机或托管 Ollama API 进行搜索。
|
||||
</Card>
|
||||
<Card title="Perplexity" icon="search" href="/zh-CN/tools/perplexity-search">
|
||||
带内容提取控制和域名筛选的结构化结果。
|
||||
</Card>
|
||||
<Card title="SearXNG" icon="server" href="/zh-CN/tools/searxng-search">
|
||||
自托管元搜索。不需要 API key。聚合 Google、Bing、DuckDuckGo 等。
|
||||
自托管元搜索。无需 API 密钥。聚合 Google、Bing、DuckDuckGo 等更多来源。
|
||||
</Card>
|
||||
<Card title="Tavily" icon="globe" href="/zh-CN/tools/tavily">
|
||||
带搜索深度、主题筛选,以及用于 URL 提取的 `tavily_extract` 的结构化结果。
|
||||
@ -99,34 +95,34 @@ OpenClaw 还包含用于 X(原 Twitter)帖子的 `x_search`,以及用于
|
||||
|
||||
### 提供商对比
|
||||
|
||||
| 提供商 | 结果样式 | 筛选器 | API key |
|
||||
| 提供商 | 结果样式 | 筛选条件 | API 密钥 |
|
||||
| ----------------------------------------- | -------------------------- | ------------------------------------------------ | --------------------------------------------------------------------------------------- |
|
||||
| [Brave](/zh-CN/tools/brave-search) | 结构化摘要片段 | 国家、语言、时间、`llm-context` 模式 | `BRAVE_API_KEY` |
|
||||
| [DuckDuckGo](/zh-CN/tools/duckduckgo-search) | 结构化摘要片段 | -- | 无(无需密钥) |
|
||||
| [DuckDuckGo](/zh-CN/tools/duckduckgo-search) | 结构化摘要片段 | -- | 无(免密钥) |
|
||||
| [Exa](/zh-CN/tools/exa-search) | 结构化 + 已提取内容 | 神经/关键词模式、日期、内容提取 | `EXA_API_KEY` |
|
||||
| [Firecrawl](/zh-CN/tools/firecrawl) | 结构化摘要片段 | 通过 `firecrawl_search` 工具 | `FIRECRAWL_API_KEY` |
|
||||
| [Gemini](/zh-CN/tools/gemini-search) | AI 综合 + 引用 | -- | `GEMINI_API_KEY` |
|
||||
| [Grok](/zh-CN/tools/grok-search) | AI 综合 + 引用 | -- | `XAI_API_KEY` |
|
||||
| [Kimi](/zh-CN/tools/kimi-search) | AI 综合 + 引用 | -- | `KIMI_API_KEY` / `MOONSHOT_API_KEY` |
|
||||
| [MiniMax Search](/zh-CN/tools/minimax-search) | 结构化摘要片段 | 区域(`global` / `cn`) | `MINIMAX_CODE_PLAN_KEY` / `MINIMAX_CODING_API_KEY` |
|
||||
| [Ollama Web Search](/zh-CN/tools/ollama-search) | 结构化摘要片段 | -- | 已登录的本地主机无需;直接 `https://ollama.com` 搜索使用 `OLLAMA_API_KEY` |
|
||||
| [Gemini](/zh-CN/tools/gemini-search) | AI 综合回答 + 引用 | -- | `GEMINI_API_KEY` |
|
||||
| [Grok](/zh-CN/tools/grok-search) | AI 综合回答 + 引用 | -- | `XAI_API_KEY` |
|
||||
| [Kimi](/zh-CN/tools/kimi-search) | AI 综合回答 + 引用 | -- | `KIMI_API_KEY` / `MOONSHOT_API_KEY` |
|
||||
| [MiniMax Search](/zh-CN/tools/minimax-search) | 结构化摘要片段 | 区域(`global` / `cn`) | `MINIMAX_CODE_PLAN_KEY` / `MINIMAX_CODING_API_KEY` / `MINIMAX_OAUTH_TOKEN` |
|
||||
| [Ollama Web 搜索](/zh-CN/tools/ollama-search) | 结构化摘要片段 | -- | 已登录的本地主机无需密钥;直接搜索 `https://ollama.com` 时使用 `OLLAMA_API_KEY` |
|
||||
| [Perplexity](/zh-CN/tools/perplexity-search) | 结构化摘要片段 | 国家、语言、时间、域名、内容限制 | `PERPLEXITY_API_KEY` / `OPENROUTER_API_KEY` |
|
||||
| [SearXNG](/zh-CN/tools/searxng-search) | 结构化摘要片段 | 分类、语言 | 无(自托管) |
|
||||
| [SearXNG](/zh-CN/tools/searxng-search) | 结构化摘要片段 | 类别、语言 | 无(自托管) |
|
||||
| [Tavily](/zh-CN/tools/tavily) | 结构化摘要片段 | 通过 `tavily_search` 工具 | `TAVILY_API_KEY` |
|
||||
|
||||
## 自动检测
|
||||
|
||||
## 原生 OpenAI Web 搜索
|
||||
## 原生 OpenAI 网页搜索
|
||||
|
||||
当 OpenClaw Web 搜索已启用且未固定托管提供商时,直接的 OpenAI Responses 模型会自动使用 OpenAI 托管的 `web_search` 工具。这是内置 OpenAI 插件中由提供商拥有的行为,只适用于原生 OpenAI API 流量,不适用于兼容 OpenAI 的代理 base URL 或 Azure 路由。将 `tools.web.search.provider` 设置为其他提供商(例如 `brave`)即可为 OpenAI 模型保留托管的 `web_search` 工具,或设置 `tools.web.search.enabled: false` 以同时禁用托管搜索和原生 OpenAI 搜索。
|
||||
当启用 OpenClaw 网页搜索且未固定托管提供商时,直接使用 OpenAI Responses 的模型会自动使用 OpenAI 托管的 `web_search` 工具。这是内置 OpenAI 插件中由提供商负责的行为,并且只适用于原生 OpenAI API 流量,不适用于 OpenAI 兼容的代理基础 URL 或 Azure 路由。将 `tools.web.search.provider` 设置为另一个提供商(例如 `brave`),可让 OpenAI 模型继续使用托管 `web_search` 工具;或设置 `tools.web.search.enabled: false`,以同时禁用托管搜索和原生 OpenAI 搜索。
|
||||
|
||||
## 原生 Codex Web 搜索
|
||||
## 原生 Codex 网页搜索
|
||||
|
||||
支持 Codex 的模型可以选择使用提供商原生 Responses `web_search` 工具,而不是 OpenClaw 托管的 `web_search` 函数。
|
||||
支持 Codex 的模型可以选择使用提供商原生的 Responses `web_search` 工具,而不是 OpenClaw 托管的 `web_search` 函数。
|
||||
|
||||
- 在 `tools.web.search.openaiCodex` 下配置它
|
||||
- 它只会为支持 Codex 的模型激活(`openai-codex/*` 或使用 `api: "openai-codex-responses"` 的提供商)
|
||||
- 托管的 `web_search` 仍适用于非 Codex 模型
|
||||
- 它只会对支持 Codex 的模型激活(`openai-codex/*`,或使用 `api: "openai-codex-responses"` 的提供商)
|
||||
- 托管 `web_search` 仍适用于非 Codex 模型
|
||||
- `mode: "cached"` 是默认且推荐的设置
|
||||
- `tools.web.search.enabled: false` 会同时禁用托管搜索和原生搜索
|
||||
|
||||
@ -155,19 +151,17 @@ OpenClaw 还包含用于 X(原 Twitter)帖子的 `x_search`,以及用于
|
||||
|
||||
如果启用了原生 Codex 搜索,但当前模型不支持 Codex,OpenClaw 会保留正常的托管 `web_search` 行为。
|
||||
|
||||
## 设置 Web 搜索
|
||||
## 设置网页搜索
|
||||
|
||||
文档和设置流程中的提供商列表按字母顺序排列。自动检测使用
|
||||
单独的优先级顺序。
|
||||
文档和设置流程中的提供商列表按字母顺序排列。自动检测保留单独的优先级顺序。
|
||||
|
||||
如果未设置 `provider`,OpenClaw 会按以下顺序检查提供商,并使用
|
||||
第一个已就绪的提供商:
|
||||
如果未设置 `provider`,OpenClaw 会按以下顺序检查提供商,并使用第一个已就绪的提供商:
|
||||
|
||||
先检查 API 支持的提供商:
|
||||
先检查由 API 支持的提供商:
|
||||
|
||||
1. **Brave** -- `BRAVE_API_KEY` 或 `plugins.entries.brave.config.webSearch.apiKey`(顺序 10)
|
||||
2. **MiniMax Search** -- `MINIMAX_CODE_PLAN_KEY` / `MINIMAX_CODING_API_KEY` 或 `plugins.entries.minimax.config.webSearch.apiKey`(顺序 15)
|
||||
3. **Gemini** -- `GEMINI_API_KEY` 或 `plugins.entries.google.config.webSearch.apiKey`(顺序 20)
|
||||
2. **MiniMax Search** -- `MINIMAX_CODE_PLAN_KEY` / `MINIMAX_CODING_API_KEY` / `MINIMAX_OAUTH_TOKEN` 或 `plugins.entries.minimax.config.webSearch.apiKey`(顺序 15)
|
||||
3. **Gemini** -- `plugins.entries.google.config.webSearch.apiKey`、`GEMINI_API_KEY` 或 `models.providers.google.apiKey`(顺序 20)
|
||||
4. **Grok** -- `XAI_API_KEY` 或 `plugins.entries.xai.config.webSearch.apiKey`(顺序 30)
|
||||
5. **Kimi** -- `KIMI_API_KEY` / `MOONSHOT_API_KEY` 或 `plugins.entries.moonshot.config.webSearch.apiKey`(顺序 40)
|
||||
6. **Perplexity** -- `PERPLEXITY_API_KEY` / `OPENROUTER_API_KEY` 或 `plugins.entries.perplexity.config.webSearch.apiKey`(顺序 50)
|
||||
@ -175,24 +169,16 @@ OpenClaw 还包含用于 X(原 Twitter)帖子的 `x_search`,以及用于
|
||||
8. **Exa** -- `EXA_API_KEY` 或 `plugins.entries.exa.config.webSearch.apiKey`(顺序 65)
|
||||
9. **Tavily** -- `TAVILY_API_KEY` 或 `plugins.entries.tavily.config.webSearch.apiKey`(顺序 70)
|
||||
|
||||
之后是无需密钥的备用方案:
|
||||
之后是免密钥后备方案:
|
||||
|
||||
10. **DuckDuckGo** -- 无需账号或 API key 的无密钥 HTML 备用方案(顺序 100)
|
||||
11. **Ollama Web Search** -- 当你配置的本地 Ollama 主机可访问且已通过 `ollama signin` 登录时,通过该主机提供无密钥备用方案;当主机需要时可复用 Ollama provider bearer 认证,并且在配置了 `OLLAMA_API_KEY` 时可直接调用 `https://ollama.com` 搜索(顺序 110)
|
||||
10. **DuckDuckGo** -- 免密钥 HTML 后备方案,无需账户或 API 密钥(顺序 100)
|
||||
11. **Ollama Web 搜索** -- 当你配置的本地 Ollama 主机可访问且已通过 `ollama signin` 登录时,可通过它作为免密钥后备方案;主机需要时可复用 Ollama 提供商的 Bearer 认证;配置了 `OLLAMA_API_KEY` 时,可直接调用 `https://ollama.com` 搜索(顺序 110)
|
||||
12. **SearXNG** -- `SEARXNG_BASE_URL` 或 `plugins.entries.searxng.config.webSearch.baseUrl`(顺序 200)
|
||||
|
||||
如果未检测到提供商,它会回退到 Brave(你会收到缺少密钥的
|
||||
错误,提示你配置一个)。
|
||||
如果未检测到提供商,会回退到 Brave(你会收到缺少密钥的错误,提示你配置一个密钥)。
|
||||
|
||||
<Note>
|
||||
所有提供商密钥字段都支持 SecretRef 对象。位于
|
||||
`plugins.entries.<plugin>.config.webSearch.apiKey` 下的插件作用域 SecretRef
|
||||
会为内置 API 支持的 Web 搜索提供商解析,包括 Brave、Exa、Firecrawl、
|
||||
Gemini、Grok、Kimi、MiniMax、Perplexity 和 Tavily,
|
||||
无论该提供商是通过 `tools.web.search.provider` 显式选择,
|
||||
还是通过自动检测选择。在自动检测模式下,OpenClaw 只解析
|
||||
所选提供商的密钥 -- 未选中的 SecretRef 保持未激活,因此你可以
|
||||
保留多个已配置的提供商,而无需为未使用的提供商支付解析成本。
|
||||
所有提供商密钥字段都支持 SecretRef 对象。对于内置的 API 支持网页搜索提供商,OpenClaw 会解析 `plugins.entries.<plugin>.config.webSearch.apiKey` 下插件作用域的 SecretRefs,包括 Brave、Exa、Firecrawl、Gemini、Grok、Kimi、MiniMax、Perplexity 和 Tavily,无论提供商是通过 `tools.web.search.provider` 显式选择,还是通过自动检测选中。在自动检测模式下,OpenClaw 只解析选中提供商的密钥——未选中的 SecretRefs 保持非活动状态,因此你可以配置多个提供商,而无需为未使用的提供商支付解析成本。
|
||||
</Note>
|
||||
|
||||
## 配置
|
||||
@ -213,38 +199,30 @@ OpenClaw 还包含用于 X(原 Twitter)帖子的 `x_search`,以及用于
|
||||
}
|
||||
```
|
||||
|
||||
提供商专用配置(API key、base URL、模式)位于
|
||||
`plugins.entries.<plugin>.config.webSearch.*` 下。示例请参阅提供商页面。
|
||||
提供商专用配置(API 密钥、基础 URL、模式)位于 `plugins.entries.<plugin>.config.webSearch.*` 下。Gemini 还可以复用 `models.providers.google.apiKey` 和 `models.providers.google.baseUrl` 作为较低优先级的后备项,优先级低于其专用网页搜索配置和 `GEMINI_API_KEY`。示例见各提供商页面。
|
||||
|
||||
`web_fetch` 备用提供商选择是独立的:
|
||||
`web_fetch` 后备提供商的选择是独立的:
|
||||
|
||||
- 使用 `tools.web.fetch.provider` 选择它
|
||||
- 或省略该字段,让 OpenClaw 从可用凭证中自动检测第一个已就绪的 web-fetch
|
||||
提供商
|
||||
- 非沙箱隔离的 `web_fetch` 可以使用声明了
|
||||
`contracts.webFetchProviders` 的已安装插件提供商;沙箱隔离的获取保持仅使用内置提供商
|
||||
- 目前内置的 web-fetch 提供商是 Firecrawl,配置位于
|
||||
`plugins.entries.firecrawl.config.webFetch.*` 下
|
||||
- 或省略该字段,让 OpenClaw 从可用凭证中自动检测第一个已就绪的 `web_fetch` 提供商
|
||||
- 非沙箱隔离的 `web_fetch` 可以使用声明了 `contracts.webFetchProviders` 的已安装插件提供商;沙箱隔离的获取仍仅使用内置提供商
|
||||
- 目前内置的 `web_fetch` 提供商是 Firecrawl,配置位于 `plugins.entries.firecrawl.config.webFetch.*` 下
|
||||
|
||||
当你在 `openclaw onboard` 或
|
||||
`openclaw configure --section web` 期间选择 **Kimi** 时,OpenClaw 还可以询问:
|
||||
当你在 `openclaw onboard` 或 `openclaw configure --section web` 期间选择 **Kimi** 时,OpenClaw 还可以询问:
|
||||
|
||||
- Moonshot API 区域(`https://api.moonshot.ai/v1` 或 `https://api.moonshot.cn/v1`)
|
||||
- 默认 Kimi Web 搜索模型(默认为 `kimi-k2.6`)
|
||||
- 默认 Kimi 网页搜索模型(默认为 `kimi-k2.6`)
|
||||
|
||||
对于 `x_search`,配置 `plugins.entries.xai.config.xSearch.*`。它使用与 Grok Web 搜索相同的 `XAI_API_KEY` 兜底项。
|
||||
对于 `x_search`,配置 `plugins.entries.xai.config.xSearch.*`。它使用与 Grok Web 搜索相同的 `XAI_API_KEY` 回退。
|
||||
旧版 `tools.web.x_search.*` 配置会由 `openclaw doctor --fix` 自动迁移。
|
||||
当你在 `openclaw onboard` 或 `openclaw configure --section web` 期间选择 Grok 时,
|
||||
OpenClaw 也可以使用同一个密钥提供可选的 `x_search` 设置。
|
||||
这是 Grok 路径中的一个单独后续步骤,而不是单独的顶层
|
||||
Web 搜索提供商选项。如果你选择其他提供商,OpenClaw 不会
|
||||
显示 `x_search` 提示。
|
||||
当你在 `openclaw onboard` 或 `openclaw configure --section web` 期间选择 Grok 时,OpenClaw 也可以使用同一个密钥提供可选的 `x_search` 设置。
|
||||
这是 Grok 路径中的一个独立后续步骤,不是一个独立的顶层 Web 搜索提供商选择。如果你选择其他提供商,OpenClaw 不会显示 `x_search` 提示。
|
||||
|
||||
### 存储 API 密钥
|
||||
### 存储 API key
|
||||
|
||||
<Tabs>
|
||||
<Tab title="配置文件">
|
||||
运行 `openclaw configure --section web` 或直接设置密钥:
|
||||
运行 `openclaw configure --section web`,或直接设置密钥:
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -270,8 +248,8 @@ Web 搜索提供商选项。如果你选择其他提供商,OpenClaw 不会
|
||||
export BRAVE_API_KEY="YOUR_KEY"
|
||||
```
|
||||
|
||||
对于 Gateway 网关安装,请把它放在 `~/.openclaw/.env` 中。
|
||||
参见[环境变量](/zh-CN/help/faq#env-vars-and-env-loading)。
|
||||
对于 Gateway 网关安装,请将其放入 `~/.openclaw/.env`。
|
||||
请参阅 [环境变量](/zh-CN/help/faq#env-vars-and-env-loading)。
|
||||
|
||||
</Tab>
|
||||
</Tabs>
|
||||
@ -280,12 +258,12 @@ Web 搜索提供商选项。如果你选择其他提供商,OpenClaw 不会
|
||||
|
||||
| 参数 | 描述 |
|
||||
| --------------------- | ----------------------------------------------------- |
|
||||
| `query` | 搜索查询(必需) |
|
||||
| `count` | 要返回的结果数(1-10,默认:5) |
|
||||
| `country` | 2 字母 ISO 国家/地区代码(例如 “US”、“DE”) |
|
||||
| `language` | ISO 639-1 语言代码(例如 “en”、“de”) |
|
||||
| `query` | 搜索查询(必填) |
|
||||
| `count` | 要返回的结果数(1-10,默认值:5) |
|
||||
| `country` | 2 字母 ISO 国家/地区代码(例如 "US"、"DE") |
|
||||
| `language` | ISO 639-1 语言代码(例如 "en"、"de") |
|
||||
| `search_lang` | 搜索语言代码(仅 Brave) |
|
||||
| `freshness` | 时间过滤器:`day`、`week`、`month` 或 `year` |
|
||||
| `freshness` | 时间筛选器:`day`、`week`、`month` 或 `year` |
|
||||
| `date_after` | 此日期之后的结果(YYYY-MM-DD) |
|
||||
| `date_before` | 此日期之前的结果(YYYY-MM-DD) |
|
||||
| `ui_lang` | UI 语言代码(仅 Brave) |
|
||||
@ -294,35 +272,19 @@ Web 搜索提供商选项。如果你选择其他提供商,OpenClaw 不会
|
||||
| `max_tokens_per_page` | 每页 token 限制,默认 2048(仅 Perplexity) |
|
||||
|
||||
<Warning>
|
||||
并非所有参数都适用于所有提供商。Brave `llm-context` 模式
|
||||
会拒绝 `ui_lang`;`date_before` 也需要 `date_after`,因为 Brave 自定义
|
||||
新鲜度范围要求同时提供开始日期和结束日期。
|
||||
Gemini、Grok 和 Kimi 会返回一个带引用的综合答案。它们
|
||||
为共享工具兼容性接受 `count`,但它不会改变
|
||||
有依据答案的形态。Gemini 支持 `freshness`、`date_after` 和
|
||||
`date_before`,会将它们转换为 Google Search 依据时间范围。
|
||||
当你使用 Sonar/OpenRouter 兼容路径(`plugins.entries.perplexity.config.webSearch.baseUrl` /
|
||||
`model` 或 `OPENROUTER_API_KEY`)时,Perplexity 的行为相同。
|
||||
SearXNG 仅对受信任的私有网络或 loopback 主机接受 `http://`;
|
||||
公共 SearXNG 端点必须使用 `https://`。
|
||||
Firecrawl 和 Tavily 通过 `web_search`
|
||||
仅支持 `query` 和 `count` -- 高级选项请使用它们的专用工具。
|
||||
并非所有参数都适用于所有提供商。Brave `llm-context` 模式会拒绝 `ui_lang`;`date_before` 也需要 `date_after`,因为 Brave 自定义新鲜度范围要求同时提供开始日期和结束日期。
|
||||
Gemini、Grok 和 Kimi 会返回一个带引用的合成答案。它们接受 `count` 以兼容共享工具,但这不会改变有依据答案的形态。Gemini 支持 `freshness`、`date_after` 和 `date_before`,方式是将它们转换为 Google Search grounding 时间范围。
|
||||
当你使用 Sonar/OpenRouter 兼容路径(`plugins.entries.perplexity.config.webSearch.baseUrl` / `model` 或 `OPENROUTER_API_KEY`)时,Perplexity 的行为方式相同。
|
||||
SearXNG 只对受信任的私有网络或回环主机接受 `http://`;公共 SearXNG 端点必须使用 `https://`。
|
||||
Firecrawl 和 Tavily 通过 `web_search` 仅支持 `query` 和 `count`,高级选项请使用它们的专用工具。
|
||||
</Warning>
|
||||
|
||||
## x_search
|
||||
|
||||
`x_search` 使用 xAI 查询 X(原 Twitter)帖子,并返回
|
||||
带引用的 AI 综合答案。它接受自然语言查询和
|
||||
可选的结构化过滤器。OpenClaw 只会在服务此工具调用的请求上启用内置 xAI `x_search`
|
||||
工具。
|
||||
`x_search` 使用 xAI 查询 X(原 Twitter)帖子,并返回带引用的 AI 合成答案。它接受自然语言查询和可选的结构化筛选器。OpenClaw 仅在服务此工具调用的请求上启用内置 xAI `x_search` 工具。
|
||||
|
||||
<Note>
|
||||
xAI 文档说明 `x_search` 支持关键词搜索、语义搜索、用户
|
||||
搜索和 thread 获取。对于每条帖子的互动统计,例如转发、
|
||||
回复、书签或浏览量,优先针对精确帖子 URL
|
||||
或 status ID 进行定向查找。宽泛的关键词搜索可能找到正确的帖子,但返回的每条帖子元数据不够
|
||||
完整。一个好的模式是:先定位帖子,然后
|
||||
再运行第二次聚焦该精确帖子的 `x_search` 查询。
|
||||
xAI 文档说明 `x_search` 支持关键词搜索、语义搜索、用户搜索和线程获取。对于单帖互动统计信息,例如转发、回复、书签或浏览量,建议针对精确帖子 URL 或状态 ID 进行定向查找。广泛关键词搜索可能找到正确的帖子,但返回的单帖元数据可能不够完整。一个好的模式是:先定位帖子,然后运行第二次 `x_search` 查询,聚焦于该确切帖子。
|
||||
</Note>
|
||||
|
||||
### x_search 配置
|
||||
@ -353,21 +315,19 @@ Web 搜索提供商选项。如果你选择其他提供商,OpenClaw 不会
|
||||
}
|
||||
```
|
||||
|
||||
设置 `plugins.entries.xai.config.xSearch.baseUrl` 时,`x_search` 会 POST 到 `<baseUrl>/responses`。
|
||||
如果省略该字段,它会回退到 `plugins.entries.xai.config.webSearch.baseUrl`,然后是
|
||||
旧版 `tools.web.search.grok.baseUrl`,最后是公共 xAI 端点。
|
||||
当设置 `plugins.entries.xai.config.xSearch.baseUrl` 时,`x_search` 会 POST 到 `<baseUrl>/responses`。如果省略该字段,它会回退到 `plugins.entries.xai.config.webSearch.baseUrl`,然后是旧版 `tools.web.search.grok.baseUrl`,最后是公共 xAI 端点。
|
||||
|
||||
### x_search 参数
|
||||
|
||||
| 参数 | 描述 |
|
||||
| ---------------------------- | ----------------------------------------------------- |
|
||||
| `query` | 搜索查询(必需) |
|
||||
| `allowed_x_handles` | 将结果限制为特定 X handles |
|
||||
| `excluded_x_handles` | 排除特定 X handles |
|
||||
| `from_date` | 只包含此日期当天或之后的帖子(YYYY-MM-DD) |
|
||||
| `to_date` | 只包含此日期当天或之前的帖子(YYYY-MM-DD) |
|
||||
| `enable_image_understanding` | 让 xAI 检查匹配帖子附带的图片 |
|
||||
| `enable_video_understanding` | 让 xAI 检查匹配帖子附带的视频 |
|
||||
| 参数 | 描述 |
|
||||
| ---------------------------- | ------------------------------------------------------ |
|
||||
| `query` | 搜索查询(必填) |
|
||||
| `allowed_x_handles` | 将结果限制为特定 X 用户名 |
|
||||
| `excluded_x_handles` | 排除特定 X 用户名 |
|
||||
| `from_date` | 仅包含此日期当天或之后的帖子(YYYY-MM-DD) |
|
||||
| `to_date` | 仅包含此日期当天或之前的帖子(YYYY-MM-DD) |
|
||||
| `enable_image_understanding` | 让 xAI 检查匹配帖子附带的图片 |
|
||||
| `enable_video_understanding` | 让 xAI 检查匹配帖子附带的视频 |
|
||||
|
||||
### x_search 示例
|
||||
|
||||
@ -412,9 +372,9 @@ await web_search({
|
||||
});
|
||||
```
|
||||
|
||||
## 工具配置文件
|
||||
## 工具配置集
|
||||
|
||||
如果你使用工具配置文件或允许列表,请添加 `web_search`、`x_search` 或 `group:web`:
|
||||
如果你使用工具配置集或允许列表,请添加 `web_search`、`x_search` 或 `group:web`:
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -428,6 +388,6 @@ await web_search({
|
||||
## 相关内容
|
||||
|
||||
- [Web Fetch](/zh-CN/tools/web-fetch) -- 获取 URL 并提取可读内容
|
||||
- [Web Browser](/zh-CN/tools/browser) -- 面向 JS 较重网站的完整浏览器自动化
|
||||
- [Grok Search](/zh-CN/tools/grok-search) -- 将 Grok 用作 `web_search` 提供商
|
||||
- [Ollama Web 搜索](/zh-CN/tools/ollama-search) -- 通过你的 Ollama 主机进行免密钥 Web 搜索
|
||||
- [Web Browser](/zh-CN/tools/browser) -- 面向 JS 密集型站点的完整浏览器自动化
|
||||
- [Grok Search](/zh-CN/tools/grok-search) -- 将 Grok 作为 `web_search` 提供商
|
||||
- [Ollama Web Search](/zh-CN/tools/ollama-search) -- 通过你的 Ollama 主机进行免密钥 Web 搜索
|
||||
|
||||
Loading…
Reference in New Issue
Block a user