chore(i18n): refresh zh-CN translations
This commit is contained in:
parent
7dc0c57a7c
commit
4af59a06e0
@ -1,21 +1,21 @@
|
||||
---
|
||||
read_when:
|
||||
- 调度后台作业或唤醒任务
|
||||
- 将外部触发器(webhooks、Gmail)接入 OpenClaw
|
||||
- 为计划任务决定使用 heartbeat 还是 cron
|
||||
- 安排后台作业或唤醒任务
|
||||
- 将外部触发器(webhook、Gmail)接入 OpenClaw
|
||||
- 为计划任务决定使用心跳还是 cron
|
||||
sidebarTitle: Scheduled tasks
|
||||
summary: 用于 Gateway 网关调度器的计划任务、webhooks 和 Gmail PubSub 触发器
|
||||
summary: Gateway 网关调度器的计划任务、webhook 和 Gmail PubSub 触发器
|
||||
title: 计划任务
|
||||
x-i18n:
|
||||
generated_at: "2026-04-27T08:36:59Z"
|
||||
generated_at: "2026-04-27T08:44:47Z"
|
||||
model: gpt-5.4
|
||||
provider: openai
|
||||
source_hash: 52d48c5d6f19fe9bcaae63afd6a736d953de3f25a710faae9c1ac1df0c081354
|
||||
source_hash: a8764103e2d6a9b35b3112e3e95c9570d196c03ed86f4fcdcf4536049a05ac6d
|
||||
source_path: automation/cron-jobs.md
|
||||
workflow: 15
|
||||
---
|
||||
|
||||
Cron 是 Gateway 网关的内置调度器。它会持久化作业,在正确的时间唤醒智能体,并且可以将输出回传到聊天渠道或 webhook 端点。
|
||||
Cron 是 Gateway 网关的内置调度器。它会持久化作业,在正确的时间唤醒智能体,并可将输出回传到聊天渠道或 webhook 端点。
|
||||
|
||||
## 快速开始
|
||||
|
||||
@ -44,76 +44,76 @@ Cron 是 Gateway 网关的内置调度器。它会持久化作业,在正确的
|
||||
</Step>
|
||||
</Steps>
|
||||
|
||||
## cron 的工作原理
|
||||
## cron 的工作方式
|
||||
|
||||
- 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` 值。纯格式调整或仅键顺序重写会保留待处理槽位。
|
||||
- 所有 cron 执行都会创建 [后台任务](/zh-CN/automation/tasks) 记录。
|
||||
- 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` 值。纯格式调整或仅键顺序重写会保留待处理槽位。
|
||||
- 所有 cron 执行都会创建[后台任务](/zh-CN/automation/tasks)记录。
|
||||
- 一次性作业(`--at`)默认会在成功后自动删除。
|
||||
- 独立 cron 运行会尽力在运行完成后关闭其 `cron:<jobId>` 会话所跟踪的浏览器标签页/进程,因此分离的浏览器自动化不会留下孤儿进程。
|
||||
- 独立 cron 运行还会防止过时的确认回复。如果第一个结果只是中间状态更新(如 `on it`、`pulling everything together` 以及类似提示),且没有任何后代子智能体运行仍负责给出最终答案,OpenClaw 会在投递前再次提示一次,以获取实际结果。
|
||||
- 独立 cron 运行会优先使用嵌入式运行中的结构化执行拒绝元数据,然后回退到已知的最终摘要/输出标记,例如 `SYSTEM_RUN_DENIED` 和 `INVALID_REQUEST`,从而避免将被阻止的命令报告为绿色成功运行。
|
||||
- 独立 cron 运行还会在未产生任何回复负载时,将运行级别的智能体失败视为作业错误,因此模型/提供商失败会增加错误计数并触发失败通知,而不是将作业清除为成功。
|
||||
- 独立 cron 运行会尽力在运行完成时关闭其 `cron:<jobId>` 会话所跟踪的浏览器标签页 / 进程,这样分离的浏览器自动化就不会留下孤儿进程。
|
||||
- 独立 cron 运行还会防止过期的确认回复。如果第一个结果只是中间状态更新(如 “on it”、“pulling everything together” 及类似提示),并且没有任何后代子智能体运行仍负责最终答案,OpenClaw 会再提示一次以获取实际结果,然后再投递。
|
||||
- 独立 cron 运行会优先使用嵌入式运行中的结构化执行拒绝元数据,然后再回退到已知的最终摘要 / 输出标记,例如 `SYSTEM_RUN_DENIED` 和 `INVALID_REQUEST`,这样被阻止的命令就不会被报告为绿色成功运行。
|
||||
- 独立 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 标志 | 说明 |
|
||||
| ------- | --------- | ----------------------------------------------------- |
|
||||
| `at` | `--at` | 一次性时间戳(ISO 8601 或像 `20m` 这样的相对时间) |
|
||||
| `every` | `--every` | 固定间隔 |
|
||||
| `cron` | `--cron` | 5 字段或 6 字段 cron 表达式,可选 `--tz` |
|
||||
| 类型 | CLI 标志 | 描述 |
|
||||
| ------- | --------- | ------------------------------------------------ |
|
||||
| `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 行为。
|
||||
|
||||
```
|
||||
# 预期:“每月 15 日上午 9 点,仅当这一天是星期一时”
|
||||
# 实际: “每月所有 15 日上午 9 点,以及每周所有星期一上午 9 点”
|
||||
# 预期:“15 日上午 9 点,但仅当这一天是周一”
|
||||
# 实际:“每月 15 日上午 9 点,以及每个周一上午 9 点”
|
||||
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` 值 | 运行于 | 最适合 |
|
||||
| -------------- | ------------------ | ------------------------- | ----------------------------------- |
|
||||
| 主会话 | `main` | 下一次 heartbeat 回合 | 提醒、系统事件 |
|
||||
| 独立 | `isolated` | 专用 `cron:<jobId>` | 报告、后台事务 |
|
||||
| 当前会话 | `current` | 在创建时绑定 | 有上下文感知的重复性工作 |
|
||||
| 自定义会话 | `session:custom-id`| 持久化命名会话 | 基于历史逐步构建的工作流 |
|
||||
| 样式 | `--session` 值 | 运行位置 | 最适合 |
|
||||
| -------------- | ------------------ | ------------------------ | ----------------------------- |
|
||||
| 主会话 | `main` | 下一个心跳回合 | 提醒、系统事件 |
|
||||
| 独立 | `isolated` | 专用 `cron:<jobId>` | 报告、后台杂务 |
|
||||
| 当前会话 | `current` | 在创建时绑定 | 感知上下文的循环工作 |
|
||||
| 自定义会话 | `session:custom-id`| 持久化命名会话 | 基于历史逐步构建的工作流 |
|
||||
|
||||
<AccordionGroup>
|
||||
<Accordion title="主会话、独立会话与自定义会话">
|
||||
**主会话** 作业会将系统事件加入队列,并可选择唤醒 heartbeat(`--wake now` 或 `--wake next-heartbeat`)。这些系统事件不会延长目标会话的每日/空闲重置新鲜度。**独立** 作业会使用全新会话执行专用智能体回合。**自定义会话**(`session:xxx`)会在多次运行之间保留上下文,从而支持如基于前一次摘要继续构建的每日报告等工作流。
|
||||
<Accordion title="主会话 vs 独立 vs 自定义">
|
||||
**主会话**作业会排入一个系统事件,并可选择唤醒心跳(`--wake now` 或 `--wake next-heartbeat`)。这些系统事件不会延长目标会话的每日 / 空闲重置新鲜度。**独立**作业会使用一个全新的会话运行一个专用智能体回合。**自定义会话**(`session:xxx`)会在多次运行间保留上下文,可支持例如基于先前摘要构建的每日站会等工作流。
|
||||
</Accordion>
|
||||
<Accordion title="独立作业中的“全新会话”是什么意思">
|
||||
对于独立作业,“全新会话”表示每次运行都有新的 transcript/session id。OpenClaw 可能会携带安全偏好设置,例如 thinking/fast/verbose 设置、标签以及用户明确选择的模型/凭证覆盖,但不会从旧的 cron 行继承环境对话上下文:渠道/群组路由、发送或排队策略、提权、来源或 ACP 运行时绑定。当重复性作业应有意建立在同一会话上下文上时,请使用 `current` 或 `session:<id>`。
|
||||
对独立作业来说,“全新会话”表示每次运行都使用新的 transcript / session id。OpenClaw 可能会携带安全偏好,例如 thinking / fast / verbose 设置、标签以及用户显式选择的模型 / 认证覆盖,但不会从旧的 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 会抑制该部分父级更新,而不是将其宣布出去。
|
||||
当独立 cron 运行编排子智能体时,投递也会优先使用最终的后代输出,而不是陈旧的父级中间文本。如果后代仍在运行,OpenClaw 会抑制该部分父级更新,而不是将其对外宣布。
|
||||
|
||||
对于仅文本的 Discord announce 目标,OpenClaw 只会发送一次规范化的最终助手文本,而不会重放流式/中间文本负载和最终答案。媒体和结构化 Discord 负载仍会作为单独的负载投递,以避免附件和组件丢失。
|
||||
对于仅文本的 Discord announce 目标,OpenClaw 只会发送一次规范化的最终 assistant 文本,而不会同时重放流式 / 中间文本负载和最终答案。媒体和结构化 Discord 负载仍会作为独立负载投递,以免附件和组件丢失。
|
||||
|
||||
</Accordion>
|
||||
</AccordionGroup>
|
||||
@ -121,10 +121,10 @@ Cron 表达式由 [croner](https://github.com/Hexagon/croner) 解析。当“每
|
||||
### 独立作业的负载选项
|
||||
|
||||
<ParamField path="--message" type="string" required>
|
||||
提示文本(独立模式必填)。
|
||||
提示文本(独立模式必需)。
|
||||
</ParamField>
|
||||
<ParamField path="--model" type="string">
|
||||
模型覆盖;使用该作业所选的允许模型。
|
||||
模型覆盖;使用为该作业所选且允许的模型。
|
||||
</ParamField>
|
||||
<ParamField path="--thinking" type="string">
|
||||
Thinking 级别覆盖。
|
||||
@ -136,40 +136,40 @@ Cron 表达式由 [croner](https://github.com/Hexagon/croner) 解析。当“每
|
||||
限制作业可使用的工具,例如 `--tools exec,read`。
|
||||
</ParamField>
|
||||
|
||||
`--model` 会使用该作业所选的允许模型。如果请求的模型不被允许,cron 会记录警告,并回退到该作业的智能体/默认模型选择。已配置的回退链仍然适用,但如果只是普通模型覆盖而没有显式的每作业回退列表,则不会再把智能体主模型作为隐藏的额外重试目标附加进去。
|
||||
`--model` 会使用该作业所选且允许的模型。如果请求的模型不被允许,cron 会记录一条警告,并回退到该作业的智能体 / 默认模型选择。已配置的回退链仍然适用,但如果只是普通的模型覆盖且没有显式的按作业回退列表,则不会再将智能体主模型作为隐藏的额外重试目标附加进去。
|
||||
|
||||
独立作业的模型选择优先级为:
|
||||
独立作业的模型选择优先级如下:
|
||||
|
||||
1. Gmail hook 模型覆盖(当运行来自 Gmail 且该覆盖被允许时)
|
||||
2. 每作业负载 `model`
|
||||
3. 用户选择的已存储 cron 会话模型覆盖
|
||||
4. 智能体/默认模型选择
|
||||
1. Gmail hook 模型覆盖(当该运行来自 Gmail 且该覆盖被允许时)
|
||||
2. 按作业负载中的 `model`
|
||||
3. 用户选择并存储的 cron 会话模型覆盖
|
||||
4. 智能体 / 默认模型选择
|
||||
|
||||
快速模式同样遵循已解析的实时选择。如果所选模型配置具有 `params.fastMode`,独立 cron 默认会使用它。已存储的会话 `fastMode` 覆盖仍会在任一方向上优先生效。
|
||||
Fast 模式也会跟随已解析的实时选择。如果选中的模型配置包含 `params.fastMode`,独立 cron 默认会使用它。无论方向如何,已存储会话中的 `fastMode` 覆盖仍优先于配置。
|
||||
|
||||
如果独立运行命中实时模型切换交接,cron 会使用切换后的提供商/模型进行重试,并在重试前为当前运行持久化该实时选择。当切换同时携带新的凭证配置文件时,cron 也会为当前运行持久化该凭证配置文件覆盖。重试是有上限的:在初始尝试加上 2 次切换重试之后,cron 会中止,而不是无限循环。
|
||||
如果独立运行遇到实时模型切换交接,cron 会使用切换后的提供商 / 模型重试,并在重试前为当前运行持久化该实时选择。如果切换还携带新的认证配置文件,cron 也会为当前运行持久化该认证配置文件覆盖。重试次数是有界的:初次尝试之后再加 2 次切换重试后,cron 会中止,而不是无限循环。
|
||||
|
||||
## 投递与输出
|
||||
|
||||
| 模式 | 发生的情况 |
|
||||
| ---------- | ----------------------------------------------------------------- |
|
||||
| `announce` | 如果智能体未发送,则回退投递最终文本到目标 |
|
||||
| `webhook` | 将完成事件负载 POST 到某个 URL |
|
||||
| `none` | 不进行运行器回退投递 |
|
||||
| 模式 | 行为 |
|
||||
| ---------- | --------------------------------------------------------------------- |
|
||||
| `announce` | 如果智能体未发送,则回退将最终文本投递到目标 |
|
||||
| `webhook` | 将完成事件负载以 POST 方式发送到 URL |
|
||||
| `none` | 运行器不执行回退投递 |
|
||||
|
||||
使用 `--announce --channel telegram --to "-1001234567890"` 可投递到渠道。对于 Telegram forum topics,请使用 `-1001234567890:topic:123`。Slack/Discord/Mattermost 目标应使用显式前缀(`channel:<id>`、`user:<id>`)。Matrix 房间 ID 区分大小写;请使用精确的房间 ID,或使用来自 Matrix 的 `room:!room:server` 形式。
|
||||
使用 `--announce --channel telegram --to "-1001234567890"` 可投递到渠道。对于 Telegram forum topic,请使用 `-1001234567890:topic:123`。Slack / Discord / Mattermost 目标应使用显式前缀(`channel:<id>`、`user:<id>`)。Matrix 房间 ID 区分大小写;请使用精确的房间 ID,或使用来自 Matrix 的 `room:!room:server` 形式。
|
||||
|
||||
对于独立作业,聊天投递是共享的。如果聊天路由可用,即使作业使用 `--no-deliver`,智能体也可以使用 `message` 工具。如果智能体发送到了已配置/当前目标,OpenClaw 会跳过回退 announce。否则,`announce`、`webhook` 和 `none` 只控制运行器在智能体回合结束后如何处理最终回复。
|
||||
对于独立作业,聊天投递是共享的。如果存在聊天路由,即使作业使用 `--no-deliver`,智能体仍可使用 `message` 工具。如果智能体发送到了已配置 / 当前目标,OpenClaw 会跳过回退 announce。否则,`announce`、`webhook` 和 `none` 只控制在智能体回合结束后,运行器如何处理最终回复。
|
||||
|
||||
当智能体从活动聊天中创建独立提醒时,OpenClaw 会为回退 announce 路由存储保留的实时投递目标。内部会话键可能是小写;当当前聊天上下文可用时,不会根据这些键重建提供商投递目标。
|
||||
当智能体从活跃聊天中创建独立提醒时,OpenClaw 会为回退 announce 路由存储保留的实时投递目标。内部会话键可能是小写;当当前聊天上下文可用时,不会依据这些键重建提供商投递目标。
|
||||
|
||||
失败通知遵循单独的目标路径:
|
||||
失败通知遵循独立的目标路径:
|
||||
|
||||
- `cron.failureDestination` 设置失败通知的全局默认值。
|
||||
- `job.delivery.failureDestination` 可按作业覆盖该设置。
|
||||
- 如果两者都未设置,且作业已通过 `announce` 进行投递,失败通知现在会回退到该主 announce 目标。
|
||||
- `job.delivery.failureDestination` 可按作业覆盖它。
|
||||
- 如果两者都未设置,且该作业已经通过 `announce` 投递,失败通知现在会回退到该主 announce 目标。
|
||||
- `delivery.failureDestination` 仅在 `sessionTarget="isolated"` 作业中受支持,除非主投递模式为 `webhook`。
|
||||
- `failureAlert.includeSkipped: true` 允许作业或全局 cron 告警策略选择加入重复跳过运行告警。跳过运行会保留单独的连续跳过计数,因此不会影响执行错误退避。
|
||||
- `failureAlert.includeSkipped: true` 可让某个作业或全局 cron 告警策略选择加入重复的跳过运行告警。跳过运行会维护独立的连续跳过计数,因此不会影响执行错误退避。
|
||||
|
||||
## CLI 示例
|
||||
|
||||
@ -184,7 +184,7 @@ Cron 表达式由 [croner](https://github.com/Hexagon/croner) 解析。当“每
|
||||
--wake now
|
||||
```
|
||||
</Tab>
|
||||
<Tab title="重复性独立作业">
|
||||
<Tab title="循环独立作业">
|
||||
```bash
|
||||
openclaw cron add \
|
||||
--name "Morning brief" \
|
||||
@ -212,9 +212,9 @@ Cron 表达式由 [croner](https://github.com/Hexagon/croner) 解析。当“每
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
## Webhooks
|
||||
## Webhook
|
||||
|
||||
Gateway 网关可以暴露 HTTP webhook 端点以接收外部触发器。在配置中启用:
|
||||
Gateway 网关可以暴露 HTTP webhook 端点以供外部触发器使用。在配置中启用:
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -233,11 +233,11 @@ Gateway 网关可以暴露 HTTP webhook 端点以接收外部触发器。在配
|
||||
- `Authorization: Bearer <token>`(推荐)
|
||||
- `x-openclaw-token: <token>`
|
||||
|
||||
查询字符串中的 token 会被拒绝。
|
||||
不接受查询字符串 token。
|
||||
|
||||
<AccordionGroup>
|
||||
<Accordion title="POST /hooks/wake">
|
||||
为主会话将一个系统事件加入队列:
|
||||
为主会话排入一个系统事件:
|
||||
|
||||
```bash
|
||||
curl -X POST http://127.0.0.1:18789/hooks/wake \
|
||||
@ -255,7 +255,7 @@ Gateway 网关可以暴露 HTTP webhook 端点以接收外部触发器。在配
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="POST /hooks/agent">
|
||||
运行一次独立的智能体回合:
|
||||
运行一个独立的智能体回合:
|
||||
|
||||
```bash
|
||||
curl -X POST http://127.0.0.1:18789/hooks/agent \
|
||||
@ -267,20 +267,20 @@ Gateway 网关可以暴露 HTTP webhook 端点以接收外部触发器。在配
|
||||
字段:`message`(必填)、`name`、`agentId`、`wakeMode`、`deliver`、`channel`、`to`、`model`、`thinking`、`timeoutSeconds`。
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="映射 hook(POST /hooks/<name>)">
|
||||
<Accordion title="映射 hooks(POST /hooks/<name>)">
|
||||
自定义 hook 名称通过配置中的 `hooks.mappings` 解析。映射可以使用模板或代码转换,将任意负载转换为 `wake` 或 `agent` 动作。
|
||||
</Accordion>
|
||||
</AccordionGroup>
|
||||
|
||||
<Warning>
|
||||
将 hook 端点放在 loopback、tailnet 或可信任的反向代理之后。
|
||||
将 hook 端点放在 loopback、tailnet 或受信任的反向代理之后。
|
||||
|
||||
- 使用专用 hook token;不要复用 gateway 认证 token。
|
||||
- 将 `hooks.path` 设为专用子路径;`/` 会被拒绝。
|
||||
- 使用专用 hook token;不要复用 gateway 身份验证 token。
|
||||
- 将 `hooks.path` 保持为专用子路径;`/` 会被拒绝。
|
||||
- 设置 `hooks.allowedAgentIds` 以限制显式 `agentId` 路由。
|
||||
- 除非你需要调用方自行选择会话,否则保持 `hooks.allowRequestSessionKey=false`。
|
||||
- 如果你启用了 `hooks.allowRequestSessionKey`,也要设置 `hooks.allowedSessionKeyPrefixes` 来约束允许的会话键形态。
|
||||
- 默认情况下,hook 负载会被安全边界包装。
|
||||
- 除非你确实需要由调用方选择会话,否则请保持 `hooks.allowRequestSessionKey=false`。
|
||||
- 如果你启用了 `hooks.allowRequestSessionKey`,也请设置 `hooks.allowedSessionKeyPrefixes` 来约束允许的会话键形态。
|
||||
- 默认情况下,hook 负载会被安全边界包裹。
|
||||
</Warning>
|
||||
|
||||
## Gmail PubSub 集成
|
||||
@ -288,7 +288,7 @@ Gateway 网关可以暴露 HTTP webhook 端点以接收外部触发器。在配
|
||||
通过 Google PubSub 将 Gmail 收件箱触发器接入 OpenClaw。
|
||||
|
||||
<Note>
|
||||
**前提条件:** `gcloud` CLI、`gog`(gogcli)、已启用 OpenClaw hooks,以及用于公共 HTTPS 端点的 Tailscale。
|
||||
**前置条件:**`gcloud` CLI、`gog`(gogcli)、已启用 OpenClaw hooks,以及用于公共 HTTPS 端点的 Tailscale。
|
||||
</Note>
|
||||
|
||||
### 向导设置(推荐)
|
||||
@ -297,17 +297,17 @@ Gateway 网关可以暴露 HTTP webhook 端点以接收外部触发器。在配
|
||||
openclaw webhooks gmail setup --account openclaw@gmail.com
|
||||
```
|
||||
|
||||
这会写入 `hooks.gmail` 配置,启用 Gmail 预设,并为推送端点使用 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` 可选择退出。
|
||||
|
||||
### 手动一次性设置
|
||||
|
||||
<Steps>
|
||||
<Step title="选择 GCP 项目">
|
||||
选择拥有 `gog` 所用 OAuth 客户端的 GCP 项目:
|
||||
选择由 `gog` 所使用 OAuth 客户端所属的 GCP 项目:
|
||||
|
||||
```bash
|
||||
gcloud auth login
|
||||
@ -353,7 +353,7 @@ openclaw webhooks gmail setup --account openclaw@gmail.com
|
||||
# 列出所有作业
|
||||
openclaw cron list
|
||||
|
||||
# 显示单个作业,包括解析后的投递路由
|
||||
# 显示一个作业,包括解析后的投递路由
|
||||
openclaw cron show <jobId>
|
||||
|
||||
# 编辑作业
|
||||
@ -379,10 +379,10 @@ openclaw cron edit <jobId> --clear-agent
|
||||
<Note>
|
||||
模型覆盖说明:
|
||||
|
||||
- `openclaw cron add|edit --model ...` 会更改作业所选模型。
|
||||
- 如果该模型被允许,该精确的提供商/模型会传递到独立智能体运行。
|
||||
- 如果不被允许,cron 会发出警告,并回退到作业的智能体/默认模型选择。
|
||||
- 已配置的回退链仍然适用,但普通的 `--model` 覆盖若没有显式的每作业回退列表,将不再静默落回到智能体主模型作为额外重试目标。
|
||||
- `openclaw cron add|edit --model ...` 会更改作业的已选模型。
|
||||
- 如果该模型被允许,确切的 provider / model 会传递给独立智能体运行。
|
||||
- 如果不被允许,cron 会发出警告并回退到该作业的智能体 / 默认模型选择。
|
||||
- 已配置的回退链仍然适用,但纯 `--model` 覆盖如果没有显式的按作业回退列表,将不再悄悄回退到智能体主模型作为额外重试目标。
|
||||
</Note>
|
||||
|
||||
## 配置
|
||||
@ -405,11 +405,11 @@ openclaw cron edit <jobId> --clear-agent
|
||||
}
|
||||
```
|
||||
|
||||
`maxConcurrentRuns` 同时限制计划 cron 分发和独立智能体回合执行。独立 cron 智能体回合在内部使用队列的 `nested` 执行通道,因此提高该值可让相互独立的 cron LLM 运行并行推进,而不只是启动它们的外层 cron 包装器。
|
||||
`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`。
|
||||
运行时状态 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`。
|
||||
|
||||
@ -417,11 +417,11 @@ openclaw cron edit <jobId> --clear-agent
|
||||
<Accordion title="重试行为">
|
||||
**一次性重试**:瞬时错误(限流、过载、网络、服务器错误)最多重试 3 次,并使用指数退避。永久性错误会立即禁用。
|
||||
|
||||
**重复性重试**:重试之间使用指数退避(30 秒到 60 分钟)。在下一次成功运行后,退避会重置。
|
||||
**循环重试**:重试之间使用指数退避(30 秒到 60 分钟)。下一次成功运行后会重置退避。
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="维护">
|
||||
`cron.sessionRetention`(默认 `24h`)会清理独立运行的会话条目。`cron.runLog.maxBytes` / `cron.runLog.keepLines` 会自动清理运行日志文件。
|
||||
`cron.sessionRetention`(默认 `24h`)会清理独立运行会话条目。`cron.runLog.maxBytes` / `cron.runLog.keepLines` 会自动清理运行日志文件。
|
||||
</Accordion>
|
||||
</AccordionGroup>
|
||||
|
||||
@ -443,33 +443,33 @@ openclaw doctor
|
||||
<AccordionGroup>
|
||||
<Accordion title="Cron 未触发">
|
||||
- 检查 `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 已触发但没有投递">
|
||||
- 投递模式 `none` 表示不应期望运行器进行回退发送。如果聊天路由可用,智能体仍可直接使用 `message` 工具发送。
|
||||
- 缺少/无效的投递目标(`channel`/`to`)表示出站发送已被跳过。
|
||||
- 对于 Matrix,复制的或旧版作业中被小写化的 `delivery.to` 房间 ID 可能会失败,因为 Matrix 房间 ID 区分大小写。请将作业编辑为 Matrix 中精确的 `!room:server` 或 `room:!room:server` 值。
|
||||
- 渠道认证错误(`unauthorized`、`Forbidden`)表示投递被凭证阻止。
|
||||
- 投递模式 `none` 表示不应期望运行器执行回退发送。当聊天路由可用时,智能体仍可直接使用 `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"`,或显式渠道/目标)。
|
||||
- 如果智能体本应自行向用户发消息,请检查该作业是否有可用路由(`channel: "last"` 且有先前聊天,或显式的渠道 / 目标)。
|
||||
</Accordion>
|
||||
<Accordion title="Cron 或 heartbeat 似乎阻止了 /new 风格轮转">
|
||||
- 每日和空闲重置新鲜度并不是基于 `updatedAt`;参见 [会话管理](/zh-CN/concepts/session#session-lifecycle)。
|
||||
- Cron 唤醒、heartbeat 运行、exec 通知和 gateway 记账可能会为了路由/Status 更新会话行,但不会延长 `sessionStartedAt` 或 `lastInteractionAt`。
|
||||
- 对于这些字段出现之前创建的旧版行,当文件仍可用时,OpenClaw 可以从 transcript JSONL 会话头恢复 `sessionStartedAt`。没有 `lastInteractionAt` 的旧版空闲行会将该恢复出来的开始时间作为空闲基线。
|
||||
<Accordion title="Cron 或心跳似乎阻止了 /new 样式轮转">
|
||||
- 每日和空闲重置新鲜度并不基于 `updatedAt`;参见[会话管理](/zh-CN/concepts/session#session-lifecycle)。
|
||||
- Cron 唤醒、心跳运行、exec 通知和 gateway 记账可能会更新会话行以用于路由 / 状态,但它们不会延长 `sessionStartedAt` 或 `lastInteractionAt`。
|
||||
- 对于这些字段出现前创建的旧版行,只要 transcript JSONL 会话头文件仍可用,OpenClaw 就能从中恢复 `sessionStartedAt`。对于没有 `lastInteractionAt` 的旧版空闲行,会使用恢复出的启动时间作为空闲基线。
|
||||
</Accordion>
|
||||
<Accordion title="时区注意事项">
|
||||
- 不带 `--tz` 的 cron 使用 gateway 主机时区。
|
||||
- 不带时区的 `at` 调度会被视为 UTC。
|
||||
- Heartbeat `activeHours` 使用已配置的时区解析。
|
||||
- 不带时区的 `at` 计划按 UTC 处理。
|
||||
- 心跳 `activeHours` 使用已配置的时区解析。
|
||||
</Accordion>
|
||||
</AccordionGroup>
|
||||
|
||||
## 相关内容
|
||||
|
||||
- [自动化与任务](/zh-CN/automation) — 所有自动化机制一览
|
||||
- [自动化与任务](/zh-CN/automation) — 所有自动化机制概览
|
||||
- [后台任务](/zh-CN/automation/tasks) — cron 执行的任务账本
|
||||
- [Heartbeat](/zh-CN/gateway/heartbeat) — 周期性的主会话回合
|
||||
- [Heartbeat](/zh-CN/gateway/heartbeat) — 周期性主会话回合
|
||||
- [时区](/zh-CN/concepts/timezone) — 时区配置
|
||||
|
||||
@ -1,35 +1,35 @@
|
||||
---
|
||||
read_when:
|
||||
- 你使用 `openclaw browser`,并希望查看常见任务的示例
|
||||
- 你想通过节点主机控制另一台机器上运行的浏览器
|
||||
- 你使用 `openclaw browser`,并且想要查看常见任务的示例
|
||||
- 你想通过节点主机控制运行在另一台机器上的浏览器
|
||||
- 你想通过 Chrome MCP 连接到你本地已登录的 Chrome
|
||||
summary: '`openclaw browser` 的 CLI 参考(生命周期、配置文件、标签页、操作、状态和调试)'
|
||||
summary: '`openclaw browser` 的 CLI 参考(生命周期、配置档案、标签页、操作、状态和调试)'
|
||||
title: 浏览器
|
||||
x-i18n:
|
||||
generated_at: "2026-04-26T03:53:16Z"
|
||||
generated_at: "2026-04-27T08:44:48Z"
|
||||
model: gpt-5.4
|
||||
provider: openai
|
||||
source_hash: b42511e841e768bfa4031463f213d78c67d5c63efb655a90f65c7e8c71da9881
|
||||
source_hash: c7b5112c61e8289ab6a02bc30c9aefe640c053271f82197c0ee810b4a5efa580
|
||||
source_path: cli/browser.md
|
||||
workflow: 15
|
||||
---
|
||||
|
||||
# `openclaw browser`
|
||||
|
||||
管理 OpenClaw 的浏览器控制界面并运行浏览器操作(生命周期、配置文件、标签页、快照、截图、导航、输入、状态模拟和调试)。
|
||||
管理 OpenClaw 的浏览器控制界面并运行浏览器操作(生命周期、配置档案、标签页、快照、截图、导航、输入、状态模拟和调试)。
|
||||
|
||||
相关内容:
|
||||
|
||||
- 浏览器工具 + API:[浏览器工具](/zh-CN/tools/browser)
|
||||
- 浏览器工具 + API:[Browser 工具](/zh-CN/tools/browser)
|
||||
|
||||
## 常用标志
|
||||
|
||||
- `--url <gatewayWsUrl>`:Gateway 网关 WebSocket URL(默认取自配置)。
|
||||
- `--url <gatewayWsUrl>`:Gateway 网关 WebSocket URL(默认来自配置)。
|
||||
- `--token <token>`:Gateway 网关令牌(如果需要)。
|
||||
- `--timeout <ms>`:请求超时时间(毫秒)。
|
||||
- `--expect-final`:等待最终的 Gateway 网关响应。
|
||||
- `--browser-profile <name>`:选择浏览器配置文件(默认值来自配置)。
|
||||
- `--json`:机器可读输出(在支持时)。
|
||||
- `--browser-profile <name>`:选择浏览器配置档案(默认来自配置)。
|
||||
- `--json`:机器可读输出(在支持的地方)。
|
||||
|
||||
## 快速开始(本地)
|
||||
|
||||
@ -40,13 +40,13 @@ openclaw browser --browser-profile openclaw open https://example.com
|
||||
openclaw browser --browser-profile openclaw snapshot
|
||||
```
|
||||
|
||||
智能体也可以使用 `browser({ action: "doctor" })` 运行相同的就绪性检查。
|
||||
智能体也可以使用同样的就绪检查:`browser({ action: "doctor" })`。
|
||||
|
||||
## 快速故障排除
|
||||
|
||||
如果 `start` 因 `not reachable after start` 失败,请先排查 CDP 就绪性。如果 `start` 和 `tabs` 成功,但 `open` 或 `navigate` 失败,则浏览器控制平面是健康的,失败通常是导航 SSRF 策略导致的。
|
||||
如果 `start` 失败并显示 `not reachable after start`,请先排查 CDP 就绪状态。如果 `start` 和 `tabs` 成功,但 `open` 或 `navigate` 失败,说明浏览器控制平面是正常的,而失败通常是导航 SSRF 策略导致的。
|
||||
|
||||
最小排查步骤:
|
||||
最小排查顺序:
|
||||
|
||||
```bash
|
||||
openclaw browser --browser-profile openclaw doctor
|
||||
@ -71,17 +71,17 @@ openclaw browser --browser-profile openclaw reset-profile
|
||||
|
||||
说明:
|
||||
|
||||
- `doctor --deep` 会增加实时快照探测。当基础 CDP 就绪性已显示正常,但你想确认当前标签页确实可被检查时,这很有用。
|
||||
- 对于 `attachOnly` 和远程 CDP 配置文件,即使 OpenClaw 本身没有启动浏览器进程,`openclaw browser stop` 也会关闭当前活动控制会话并清除临时模拟覆盖项。
|
||||
- 对于本地托管配置文件,`openclaw browser stop` 会停止已启动的浏览器进程。
|
||||
- `openclaw browser start --headless` 仅适用于该次启动请求,并且只在 OpenClaw 启动本地托管浏览器时生效。它不会重写 `browser.headless` 或配置文件配置,对于已经运行的浏览器也不会产生效果。
|
||||
- 在没有 `DISPLAY` 或 `WAYLAND_DISPLAY` 的 Linux 主机上,本地托管配置文件会自动以无头模式运行,除非通过 `OPENCLAW_BROWSER_HEADLESS=0`、`browser.headless=false` 或 `browser.profiles.<name>.headless=false` 明确请求显示浏览器界面。
|
||||
- `doctor --deep` 会增加一个实时快照探测。当基础 CDP 就绪状态显示正常,但你想确认当前标签页确实可被检查时,这会很有用。
|
||||
- 对于 `attachOnly` 和远程 CDP 配置档案,`openclaw browser stop` 会关闭当前活动控制会话,并清除临时模拟覆盖项,即使 OpenClaw 本身没有启动浏览器进程也是如此。
|
||||
- 对于本地受管配置档案,`openclaw browser stop` 会停止所启动的浏览器进程。
|
||||
- `openclaw browser start --headless` 仅适用于这一次启动请求,并且只在 OpenClaw 启动本地受管浏览器时生效。它不会改写 `browser.headless` 或配置档案配置,对于已经在运行的浏览器也不会产生效果。
|
||||
- 在没有 `DISPLAY` 或 `WAYLAND_DISPLAY` 的 Linux 主机上,本地受管配置档案会自动以无头模式运行,除非 `OPENCLAW_BROWSER_HEADLESS=0`、`browser.headless=false` 或 `browser.profiles.<name>.headless=false` 明确要求显示浏览器界面。
|
||||
|
||||
## 如果命令缺失
|
||||
## 如果命令不存在
|
||||
|
||||
如果 `openclaw browser` 是未知命令,请检查 `~/.openclaw/openclaw.json` 中的 `plugins.allow`。
|
||||
|
||||
当存在 `plugins.allow` 时,内置的浏览器插件必须被显式列出:
|
||||
当存在 `plugins.allow` 时,请显式列出内置的浏览器插件,除非配置中已经有根级 `browser` 块:
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -91,17 +91,17 @@ openclaw browser --browser-profile openclaw reset-profile
|
||||
}
|
||||
```
|
||||
|
||||
当插件允许列表排除了 `browser` 时,`browser.enabled=true` 不会恢复该 CLI 子命令。
|
||||
显式的根级 `browser` 块,例如 `browser.enabled=true` 或 `browser.profiles.<name>`,也会在受限的插件允许列表下激活内置浏览器插件。
|
||||
|
||||
相关内容:[浏览器工具](/zh-CN/tools/browser#missing-browser-command-or-tool)
|
||||
相关内容:[Browser 工具](/zh-CN/tools/browser#missing-browser-command-or-tool)
|
||||
|
||||
## 配置文件
|
||||
## 配置档案
|
||||
|
||||
配置文件是命名的浏览器路由配置。实际使用中:
|
||||
配置档案是具名的浏览器路由配置。实际使用中:
|
||||
|
||||
- `openclaw`:启动或连接到专用的 OpenClaw 托管 Chrome 实例(隔离的用户数据目录)。
|
||||
- `user`:通过 Chrome DevTools MCP 控制你现有的已登录 Chrome 会话。
|
||||
- 自定义 CDP 配置文件:指向本地或远程 CDP 端点。
|
||||
- `openclaw`:启动或连接到专用的 OpenClaw 受管 Chrome 实例(隔离的用户数据目录)。
|
||||
- `user`:通过 Chrome DevTools MCP 控制你当前已登录的 Chrome 会话。
|
||||
- 自定义 CDP 配置档案:指向本地或远程 CDP 端点。
|
||||
|
||||
```bash
|
||||
openclaw browser profiles
|
||||
@ -111,7 +111,7 @@ openclaw browser create-profile --name remote --cdp-url https://browser-host.exa
|
||||
openclaw browser delete-profile --name work
|
||||
```
|
||||
|
||||
使用特定配置文件:
|
||||
使用特定配置档案:
|
||||
|
||||
```bash
|
||||
openclaw browser --browser-profile work tabs
|
||||
@ -130,8 +130,8 @@ openclaw browser focus docs
|
||||
openclaw browser close t1
|
||||
```
|
||||
|
||||
`tabs` 会先返回 `suggestedTargetId`,然后是稳定的 `tabId`(如 `t1`)、可选标签以及原始 `targetId`。智能体应将 `suggestedTargetId` 传回 `focus`、`close`、快照和操作中。你可以通过 `open --label`、`tab new --label` 或 `tab label` 分配标签;标签、标签页 ID、原始目标 ID 以及唯一的目标 ID 前缀都可接受。
|
||||
当 Chromium 在导航或表单提交期间替换底层原始目标时,如果 OpenClaw 能证明匹配关系,它会将稳定的 `tabId`/标签保留并附加到替换后的标签页上。原始目标 ID 仍然是易变的;优先使用 `suggestedTargetId`。
|
||||
`tabs` 会先返回 `suggestedTargetId`,然后是稳定的 `tabId`(如 `t1`)、可选标签以及原始 `targetId`。智能体应将 `suggestedTargetId` 传回 `focus`、`close`、快照和操作命令。你可以通过 `open --label`、`tab new --label` 或 `tab label` 分配标签;标签、标签页 ID、原始目标 ID,以及唯一的目标 ID 前缀都可以使用。
|
||||
当 Chromium 在导航或表单提交期间替换底层原始目标时,只要 OpenClaw 能够确认匹配关系,就会将稳定的 `tabId`/标签附加到替换后的标签页上。原始目标 ID 仍然是不稳定的;优先使用 `suggestedTargetId`。
|
||||
|
||||
## 快照 / 截图 / 操作
|
||||
|
||||
@ -153,10 +153,10 @@ openclaw browser screenshot --labels
|
||||
|
||||
说明:
|
||||
|
||||
- `--full-page` 仅用于页面捕获;不能与 `--ref` 或 `--element` 组合使用。
|
||||
- `existing-session` / `user` 配置文件支持页面截图以及基于快照输出中的 `--ref` 截图,但不支持 CSS `--element` 截图。
|
||||
- `--full-page` 仅用于整页截图;不能与 `--ref` 或 `--element` 组合使用。
|
||||
- `existing-session` / `user` 配置档案支持整页截图,以及基于快照输出中的 `--ref` 的截图,但不支持 CSS `--element` 截图。
|
||||
- `--labels` 会在截图上叠加当前快照引用标记。
|
||||
- `snapshot --urls` 会将已发现的链接目标地址附加到 AI 快照中,这样智能体就能选择直接导航目标,而不是仅根据链接文本进行猜测。
|
||||
- `snapshot --urls` 会将已发现的链接目标地址追加到 AI 快照中,这样智能体就可以选择直接导航目标,而不必仅根据链接文本猜测。
|
||||
|
||||
导航 / 点击 / 输入(基于 ref 的 UI 自动化):
|
||||
|
||||
@ -175,9 +175,9 @@ openclaw browser wait --text "Done"
|
||||
openclaw browser evaluate --fn '(el) => el.textContent' --ref <ref>
|
||||
```
|
||||
|
||||
当操作触发页面替换且 OpenClaw 能证明替换后的标签页时,操作响应会返回当前原始 `targetId`。但对于长期工作流,脚本仍应存储并传递 `suggestedTargetId`/标签。
|
||||
在 OpenClaw 能够确认替换标签页时,操作响应会在操作触发页面替换后返回当前原始 `targetId`。对于长生命周期工作流,脚本仍应存储并传递 `suggestedTargetId`/标签。
|
||||
|
||||
文件 + 对话框辅助:
|
||||
文件和对话框辅助命令:
|
||||
|
||||
```bash
|
||||
openclaw browser upload /tmp/openclaw/uploads/file.pdf --ref <ref>
|
||||
@ -186,7 +186,7 @@ openclaw browser download <ref> report.pdf
|
||||
openclaw browser dialog --accept
|
||||
```
|
||||
|
||||
托管 Chrome 配置文件会将普通点击触发的下载保存到 OpenClaw 下载目录中(默认是 `/tmp/openclaw/downloads`,或配置的临时根目录)。当智能体需要等待特定文件并返回其路径时,请使用 `waitfordownload` 或 `download`;这些显式等待器会接管下一次下载。
|
||||
受管 Chrome 配置档案会将普通点击触发的下载保存到 OpenClaw 下载目录(默认是 `/tmp/openclaw/downloads`,或已配置的临时根目录)。当智能体需要等待特定文件并返回其路径时,请使用 `waitfordownload` 或 `download`;这些显式等待器会接管下一次下载。
|
||||
|
||||
## 状态和存储
|
||||
|
||||
@ -229,9 +229,9 @@ openclaw browser trace start
|
||||
openclaw browser trace stop --out trace.zip
|
||||
```
|
||||
|
||||
## 通过 MCP 连接现有 Chrome
|
||||
## 通过 MCP 使用现有 Chrome
|
||||
|
||||
使用内置的 `user` 配置文件,或创建你自己的 `existing-session` 配置文件:
|
||||
使用内置的 `user` 配置档案,或者创建你自己的 `existing-session` 配置档案:
|
||||
|
||||
```bash
|
||||
openclaw browser --browser-profile user tabs
|
||||
@ -240,33 +240,32 @@ openclaw browser create-profile --name brave-live --driver existing-session --us
|
||||
openclaw browser --browser-profile chrome-live tabs
|
||||
```
|
||||
|
||||
这条路径仅适用于主机本机。对于 Docker、无头服务器、Browserless 或其他远程设置,请改用 CDP 配置文件。
|
||||
这一路径仅适用于主机本机。对于 Docker、无头服务器、Browserless 或其他远程设置,请改用 CDP 配置档案。
|
||||
|
||||
当前 existing-session 的限制:
|
||||
|
||||
- 基于快照的操作使用 refs,而不是 CSS 选择器
|
||||
- 当调用方省略 `timeoutMs` 时,`browser.actionTimeoutMs` 会将受支持的 `act` 请求默认设置为 60000 毫秒;但每次调用的 `timeoutMs` 仍然优先生效。
|
||||
- 基于快照的操作使用 ref,而不是 CSS 选择器
|
||||
- 当调用方省略 `timeoutMs` 时,`browser.actionTimeoutMs` 会将受支持的 `act` 请求默认设置为 60000 毫秒;但每次调用传入的 `timeoutMs` 仍然优先生效。
|
||||
- `click` 仅支持左键点击
|
||||
- `type` 不支持 `slowly=true`
|
||||
- `press` 不支持 `delayMs`
|
||||
- `hover`、`scrollintoview`、`drag`、`select`、`fill` 和 `evaluate` 会拒绝每次调用的超时覆盖
|
||||
- `select` 仅支持单个值
|
||||
- 不支持 `wait --load networkidle`
|
||||
- 文件上传需要 `--ref` / `--input-ref`,不支持 CSS
|
||||
`--element`,并且当前一次只支持一个文件
|
||||
- 文件上传需要 `--ref` / `--input-ref`,不支持 CSS `--element`,并且当前一次只支持一个文件
|
||||
- 对话框钩子不支持 `--timeout`
|
||||
- 截图支持页面捕获和 `--ref`,但不支持 CSS `--element`
|
||||
- `responsebody`、下载拦截、PDF 导出和批量操作仍然需要托管浏览器或原始 CDP 配置文件
|
||||
- 截图支持整页截图和 `--ref`,但不支持 CSS `--element`
|
||||
- `responsebody`、下载拦截、PDF 导出以及批量操作仍然需要受管浏览器或原始 CDP 配置档案
|
||||
|
||||
## 远程浏览器控制(节点主机代理)
|
||||
|
||||
如果 Gateway 网关运行在与浏览器不同的机器上,请在安装有 Chrome/Brave/Edge/Chromium 的机器上运行一个 **节点主机**。Gateway 网关会将浏览器操作代理到该节点(不需要单独的浏览器控制服务器)。
|
||||
如果 Gateway 网关运行在与浏览器不同的机器上,请在安装了 Chrome/Brave/Edge/Chromium 的机器上运行一个**节点主机**。Gateway 网关会将浏览器操作代理到该节点(不需要单独的浏览器控制服务器)。
|
||||
|
||||
使用 `gateway.nodes.browser.mode` 控制自动路由,使用 `gateway.nodes.browser.node` 在连接了多个节点时固定到特定节点。
|
||||
使用 `gateway.nodes.browser.mode` 控制自动路由,并使用 `gateway.nodes.browser.node` 在连接了多个节点时固定到特定节点。
|
||||
|
||||
安全性和远程设置:[浏览器工具](/zh-CN/tools/browser)、[远程访问](/zh-CN/gateway/remote)、[Tailscale](/zh-CN/gateway/tailscale)、[安全性](/zh-CN/gateway/security)
|
||||
安全性与远程设置:[Browser 工具](/zh-CN/tools/browser)、[远程访问](/zh-CN/gateway/remote)、[Tailscale](/zh-CN/gateway/tailscale)、[安全性](/zh-CN/gateway/security)
|
||||
|
||||
## 相关
|
||||
## 相关内容
|
||||
|
||||
- [CLI 参考](/zh-CN/cli)
|
||||
- [浏览器](/zh-CN/tools/browser)
|
||||
- [Browser](/zh-CN/tools/browser)
|
||||
|
||||
@ -4,48 +4,48 @@ read_when:
|
||||
summary: 将入站自动回复运行串行化的命令队列设计
|
||||
title: 命令队列
|
||||
x-i18n:
|
||||
generated_at: "2026-04-27T08:36:53Z"
|
||||
generated_at: "2026-04-27T08:44:44Z"
|
||||
model: gpt-5.4
|
||||
provider: openai
|
||||
source_hash: 90824e592379b46b568b9f7ab017c2d68bf9b741349fe88f63e358a4c8754751
|
||||
source_hash: 8fa2d4953ba8a3d9be7080599e550c796ccedf622a9467bf77e50454b6ea4c4a
|
||||
source_path: concepts/queue.md
|
||||
workflow: 15
|
||||
---
|
||||
|
||||
我们通过一个小型进程内队列,将入站自动回复运行(所有渠道)串行化,以防止多个智能体运行发生冲突,同时仍允许会话之间进行安全并行。
|
||||
我们通过一个小型进程内队列,将入站自动回复运行(所有渠道)串行化,以防止多个智能体运行发生冲突,同时仍允许跨会话进行安全并行。
|
||||
|
||||
## 原因
|
||||
|
||||
- 自动回复运行可能开销较大(LLM 调用),并且当多条入站消息在相近时间到达时,运行之间可能发生冲突。
|
||||
- 自动回复运行可能开销较大(LLM 调用),并且当多条入站消息在短时间内接连到达时,可能发生冲突。
|
||||
- 串行化可以避免争用共享资源(会话文件、日志、CLI stdin),并降低触发上游速率限制的可能性。
|
||||
|
||||
## 工作方式
|
||||
## 工作原理
|
||||
|
||||
- 一个按 lane 感知的 FIFO 队列会按每个 lane 进行排空,并带有可配置的并发上限(未配置 lane 默认值为 1;`main` 默认为 4,`subagent` 默认为 8)。
|
||||
- `runEmbeddedPiAgent` 会按 **session key** 入队(lane `session:<key>`),以确保每个会话同一时间只有一个活动运行。
|
||||
- 随后,每个会话运行会被排入一个**全局 lane**(默认为 `main`),因此整体并行度会受 `agents.defaults.maxConcurrent` 限制。
|
||||
- 启用详细日志时,如果排队运行在开始前等待超过约 2 秒,队列会输出一条简短提示。
|
||||
- 输入指示器在入队时仍会立即触发(若该渠道支持),因此等待期间用户体验不会改变。
|
||||
- 一个按 lane 感知的 FIFO 队列会按每个 lane 进行排空,并带有可配置的并发上限(未配置的 lane 默认为 1;`main` 默认为 4,`subagent` 默认为 8)。
|
||||
- `runEmbeddedPiAgent` 按**会话键**入队(lane `session:<key>`),以保证每个会话同一时间只有一个活动运行。
|
||||
- 然后,每个会话运行会再被放入一个**全局 lane**(默认是 `main`)中,因此整体并行度受到 `agents.defaults.maxConcurrent` 的限制。
|
||||
- 启用详细日志时,如果某个已排队运行在开始前等待超过约 2 秒,它会输出一条简短提示。
|
||||
- 输入中指示器在入队时仍会立即触发(当渠道支持时),因此在等待轮到自己时,用户体验不会改变。
|
||||
|
||||
## 队列模式(按渠道)
|
||||
|
||||
入站消息可以引导当前运行、等待后续轮次,或同时执行两者:
|
||||
入站消息可以控制当前运行、等待后续轮次,或两者同时进行:
|
||||
|
||||
- `steer`:立即注入当前运行(在下一个工具边界之后取消待处理的工具调用)。如果当前未处于流式传输,则回退为 followup。
|
||||
- `followup`:在当前运行结束后,为下一个智能体轮次入队。
|
||||
- `collect`:将所有已排队消息合并为**单个**后续轮次(默认)。如果消息目标是不同渠道/线程,则会分别排空以保留路由。
|
||||
- `steer-backlog`(也叫 `steer+backlog`):立即 steer,**并且**为后续轮次保留该消息。
|
||||
- `interrupt`(旧版):中止该会话的当前活动运行,然后运行最新消息。
|
||||
- `queue`(旧版别名):与 `steer` 相同。
|
||||
- `steer`:立即注入当前运行(在下一个工具边界之后取消待处理的工具调用)。如果未处于流式传输中,则回退为 followup。
|
||||
- `followup`:在当前运行结束后,排队进入下一轮智能体处理。
|
||||
- `collect`:将所有排队消息合并为**单个**后续轮次(默认)。如果消息目标是不同的渠道/线程,它们会分别排空以保留路由。
|
||||
- `steer-backlog`(也叫 `steer+backlog`):立即 steer,**并且**保留该消息用于后续轮次。
|
||||
- `interrupt`(旧版):中止该会话的活动运行,然后运行最新消息。
|
||||
- `queue`(旧别名):与 `steer` 相同。
|
||||
|
||||
Steer-backlog 意味着在 steered 运行之后,你可能还会收到一条 followup 响应,因此流式界面看起来可能像是重复回复。如果你希望每条入站消息只得到一个响应,优先使用 `collect`/`steer`。
|
||||
将 `/queue collect` 作为独立命令发送(按会话生效),或设置 `messages.queue.byChannel.discord: "collect"`。
|
||||
Steer-backlog 意味着在 steered 运行之后,你可能还会收到一个后续响应,因此在流式界面上看起来可能像重复内容。如果你希望每条入站消息只对应一个响应,优先使用 `collect`/`steer`。
|
||||
发送独立命令 `/queue collect`(按会话生效),或设置 `messages.queue.byChannel.discord: "collect"`。
|
||||
|
||||
默认值(配置中未设置时):
|
||||
|
||||
- 所有界面 → `collect`
|
||||
|
||||
可通过 `messages.queue` 全局配置或按渠道配置:
|
||||
可通过 `messages.queue` 进行全局配置或按渠道配置:
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -63,35 +63,35 @@ Steer-backlog 意味着在 steered 运行之后,你可能还会收到一条 fo
|
||||
|
||||
## 队列选项
|
||||
|
||||
这些选项适用于 `followup`、`collect` 和 `steer-backlog`(也适用于回退为 followup 的 `steer`):
|
||||
这些选项适用于 `followup`、`collect` 和 `steer-backlog`(以及回退为 followup 时的 `steer`):
|
||||
|
||||
- `debounceMs`:在启动后续轮次之前等待静默期(防止出现“continue, continue”)。
|
||||
- `debounceMs`:在启动后续轮次前等待一段静默时间(防止出现“continue, continue”)。
|
||||
- `cap`:每个会话允许排队的最大消息数。
|
||||
- `drop`:溢出策略(`old`、`new`、`summarize`)。
|
||||
|
||||
Summarize 会保留一份简短的已丢弃消息项目符号列表,并将其作为合成的 followup 提示注入。
|
||||
Summarize 会保留一份简短的已丢弃消息项目符号列表,并将其作为合成的后续提示注入。
|
||||
默认值:`debounceMs: 1000`、`cap: 20`、`drop: summarize`。
|
||||
|
||||
## 按会话覆盖
|
||||
|
||||
- 将 `/queue <mode>` 作为独立命令发送,以为当前会话存储该模式。
|
||||
- 选项可组合使用:`/queue collect debounce:2s cap:25 drop:summarize`
|
||||
- 发送独立命令 `/queue <mode>`,即可为当前会话存储该模式。
|
||||
- 可组合选项:`/queue collect debounce:2s cap:25 drop:summarize`
|
||||
- `/queue default` 或 `/queue reset` 会清除该会话的覆盖设置。
|
||||
|
||||
## 范围与保证
|
||||
|
||||
- 适用于所有使用 Gateway 网关回复流水线的入站渠道中的自动回复智能体运行(WhatsApp web、Telegram、Slack、Discord、Signal、iMessage、webchat 等)。
|
||||
- 默认 lane(`main`)是入站回复与主心跳共享的进程级 lane;设置 `agents.defaults.maxConcurrent` 可允许多个会话并行。
|
||||
- 还可以存在其他 lane(例如 `cron`、`nested`、`subagent`),这样后台任务就可以并行运行,而不会阻塞入站回复。隔离的 cron 智能体轮次会占用一个 `cron` 槽位,而其内部智能体执行会使用 `nested`;两者都使用 `cron.maxConcurrentRuns`。这些分离运行会作为[后台任务](/zh-CN/automation/tasks)进行跟踪。
|
||||
- 按会话 lane 可保证同一时间只有一个智能体运行会触及特定会话。
|
||||
- 无需外部依赖或后台工作线程;纯 TypeScript + promises。
|
||||
- 默认 lane(`main`)是针对入站消息 + 主心跳的进程级 lane;设置 `agents.defaults.maxConcurrent` 可允许多个会话并行。
|
||||
- 还可能存在其他 lane(例如 `cron`、`cron-nested`、`nested`、`subagent`),以便后台作业可以并行运行,而不会阻塞入站回复。隔离的 cron 智能体轮次会占用一个 `cron` 槽位,而其内部智能体执行使用 `cron-nested`;两者都使用 `cron.maxConcurrentRuns`。共享的非 cron `nested` 流程保持其自身的 lane 行为。这些分离运行会作为[后台任务](/zh-CN/automation/tasks)进行跟踪。
|
||||
- 按会话 lane 可保证任一给定会话同一时间只有一个智能体运行会对其进行操作。
|
||||
- 无需外部依赖,也不使用后台工作线程;纯 TypeScript + promises。
|
||||
|
||||
## 故障排除
|
||||
|
||||
- 如果命令似乎卡住了,请启用详细日志,并查找“queued for …ms”行,以确认队列正在排空。
|
||||
- 如果你需要查看队列深度,请启用详细日志并关注队列计时相关日志行。
|
||||
- 如果命令似乎卡住了,请启用详细日志,并查找“queued for …ms”日志行,以确认队列正在排空。
|
||||
- 如果你需要查看队列深度,请启用详细日志并观察队列耗时相关日志行。
|
||||
|
||||
## 相关
|
||||
## 相关内容
|
||||
|
||||
- [会话管理](/zh-CN/concepts/session)
|
||||
- [重试策略](/zh-CN/concepts/retry)
|
||||
|
||||
@ -1,23 +1,23 @@
|
||||
---
|
||||
read_when:
|
||||
- 你正从 Hermes 迁移过来,并且希望保留你的模型配置、提示词、记忆和 Skills
|
||||
- 你想了解 OpenClaw 会自动导入哪些内容,以及哪些内容会保持为仅归档
|
||||
- 你正从 Hermes 迁移而来,并希望保留你的模型配置、提示词、记忆和 Skills
|
||||
- 你想了解 OpenClaw 会自动导入哪些内容,以及哪些内容会保持为仅归档状态
|
||||
- 你需要一条干净、可脚本化的迁移路径(CI、全新笔记本电脑、自动化)
|
||||
summary: 通过可预览、可逆的导入,从 Hermes 迁移到 OpenClaw
|
||||
summary: 通过可预览、可回滚的导入,从 Hermes 迁移到 OpenClaw
|
||||
title: 从 Hermes 迁移
|
||||
x-i18n:
|
||||
generated_at: "2026-04-27T08:25:10Z"
|
||||
generated_at: "2026-04-27T08:44:49Z"
|
||||
model: gpt-5.4
|
||||
provider: openai
|
||||
source_hash: f424defc61e4f1127adb6e99b504c1f3a84c59635293208bb24bf3113aa7724d
|
||||
source_hash: 59aa622f9c60095db19f54d51b8bbde0d61b97402dc49bc9b7a3cb855176e16a
|
||||
source_path: install/migrating-hermes.md
|
||||
workflow: 15
|
||||
---
|
||||
|
||||
OpenClaw 通过内置的迁移提供商导入 Hermes 状态。该提供商会在更改状态前预览所有内容,在计划和报告中隐藏密钥,并在应用前创建经过验证的备份。
|
||||
OpenClaw 通过内置的迁移提供商导入 Hermes 状态。该提供商会在更改状态前预览所有内容,在计划和报告中隐去密钥,并在应用前创建经过验证的备份。
|
||||
|
||||
<Note>
|
||||
导入需要全新的 OpenClaw 设置。如果你已经有本地 OpenClaw 状态,请先重置配置、凭证、会话和工作区,或者在查看计划后直接使用 `openclaw migrate` 并加上 `--overwrite`。
|
||||
导入需要全新的 OpenClaw 设置。如果你已经有本地 OpenClaw 状态,请先重置配置、凭证、会话和工作区,或者在审查计划后直接使用带 `--overwrite` 的 `openclaw migrate`。
|
||||
</Note>
|
||||
|
||||
## 两种导入方式
|
||||
@ -38,46 +38,46 @@ OpenClaw 通过内置的迁移提供商导入 Hermes 状态。该提供商会在
|
||||
|
||||
</Tab>
|
||||
<Tab title="CLI">
|
||||
对于可脚本化或可重复的运行,请使用 `openclaw migrate`。完整参考请见 [`openclaw migrate`](/zh-CN/cli/migrate)。
|
||||
对于脚本化或可重复执行的运行,请使用 `openclaw migrate`。完整参考请参见 [`openclaw migrate`](/zh-CN/cli/migrate)。
|
||||
|
||||
```bash
|
||||
openclaw migrate hermes --dry-run # 仅预览
|
||||
openclaw migrate apply hermes --yes # 跳过确认并应用
|
||||
```
|
||||
|
||||
当 Hermes 不在 `~/.hermes` 下时,添加 `--from <path>`。
|
||||
当 Hermes 位于 `~/.hermes` 之外时,添加 `--from <path>`。
|
||||
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
## 导入的内容
|
||||
## 导入内容
|
||||
|
||||
<AccordionGroup>
|
||||
<Accordion title="模型配置">
|
||||
- 来自 Hermes `config.yaml` 的默认模型选择。
|
||||
- 来自 `providers` 和 `custom_providers` 的已配置模型提供商以及自定义 OpenAI 兼容端点。
|
||||
- 来自 `providers` 和 `custom_providers` 的已配置模型提供商及自定义 OpenAI 兼容端点。
|
||||
</Accordion>
|
||||
<Accordion title="MCP 服务器">
|
||||
来自 `mcp_servers` 或 `mcp.servers` 的 MCP 服务器定义。
|
||||
</Accordion>
|
||||
<Accordion title="工作区文件">
|
||||
- `SOUL.md` 和 `AGENTS.md` 会被复制到 OpenClaw 智能体工作区中。
|
||||
- `SOUL.md` 和 `AGENTS.md` 会复制到 OpenClaw 智能体工作区。
|
||||
- `memories/MEMORY.md` 和 `memories/USER.md` 会**追加**到对应的 OpenClaw 记忆文件中,而不是覆盖它们。
|
||||
</Accordion>
|
||||
<Accordion title="记忆配置">
|
||||
OpenClaw 文件记忆的默认记忆配置。像 Honcho 这样的外部记忆提供商会被记录为归档项或需要手动审查的项,以便你有意识地迁移它们。
|
||||
OpenClaw 文件记忆的默认记忆配置。像 Honcho 这样的外部记忆提供商会被记录为归档项或手动审查项,以便你有意识地迁移它们。
|
||||
</Accordion>
|
||||
<Accordion title="Skills">
|
||||
`skills/<name>/` 下带有 `SKILL.md` 文件的 Skills 会被复制,同时还会复制来自 `skills.config` 的每个 Skill 配置值。
|
||||
`skills/<name>/` 下带有 `SKILL.md` 文件的 Skills 会被复制,同时复制 `skills.config` 中每个 Skill 的配置值。
|
||||
</Accordion>
|
||||
<Accordion title="API 密钥(可选加入)">
|
||||
设置 `--include-secrets` 以导入受支持的 `.env` 键:`OPENAI_API_KEY`、`ANTHROPIC_API_KEY`、`OPENROUTER_API_KEY`、`GOOGLE_API_KEY`、`GEMINI_API_KEY`、`GROQ_API_KEY`、`XAI_API_KEY`、`MISTRAL_API_KEY`、`DEEPSEEK_API_KEY`。如果不加这个标志,密钥绝不会被复制。
|
||||
<Accordion title="API 密钥(可选启用)">
|
||||
设置 `--include-secrets` 以导入受支持的 `.env` 键:`OPENAI_API_KEY`、`ANTHROPIC_API_KEY`、`OPENROUTER_API_KEY`、`GOOGLE_API_KEY`、`GEMINI_API_KEY`、`GROQ_API_KEY`、`XAI_API_KEY`、`MISTRAL_API_KEY`、`DEEPSEEK_API_KEY`。如果不带此标志,密钥绝不会被复制。
|
||||
</Accordion>
|
||||
</AccordionGroup>
|
||||
|
||||
## 保持为仅归档的内容
|
||||
|
||||
该提供商会将以下内容复制到迁移报告目录中供手动审查,但**不会**将它们加载到在线的 OpenClaw 配置或凭证中:
|
||||
该提供商会将以下内容复制到迁移报告目录以供手动审查,但**不会**将其加载到在线 OpenClaw 配置或凭证中:
|
||||
|
||||
- `plugins/`
|
||||
- `sessions/`
|
||||
@ -87,7 +87,7 @@ OpenClaw 通过内置的迁移提供商导入 Hermes 状态。该提供商会在
|
||||
- `auth.json`
|
||||
- `state.db`
|
||||
|
||||
OpenClaw 会拒绝自动执行或信任这些状态,因为不同系统之间的格式和信任假设可能会发生变化。查看归档后,再手动迁移你需要的内容。
|
||||
OpenClaw 拒绝自动执行或信任这些状态,因为不同系统之间的格式和信任假设可能会发生漂移。审查归档后,再手动迁移你需要的内容。
|
||||
|
||||
## 推荐流程
|
||||
|
||||
@ -97,7 +97,7 @@ OpenClaw 会拒绝自动执行或信任这些状态,因为不同系统之间
|
||||
openclaw migrate hermes --dry-run
|
||||
```
|
||||
|
||||
计划会列出所有将发生的更改,包括冲突、已跳过的项以及任何敏感项。计划输出会隐藏嵌套的疑似密钥键名。
|
||||
该计划会列出所有将发生的变更,包括冲突、已跳过的项目以及任何敏感项目。计划输出会隐去嵌套的疑似密钥键名。
|
||||
|
||||
</Step>
|
||||
<Step title="带备份应用">
|
||||
@ -105,7 +105,7 @@ OpenClaw 会拒绝自动执行或信任这些状态,因为不同系统之间
|
||||
openclaw migrate apply hermes --yes
|
||||
```
|
||||
|
||||
OpenClaw 会在应用前创建并验证备份。如果你还需要导入 API 密钥,请加上 `--include-secrets`。
|
||||
OpenClaw 会在应用前创建并验证备份。如果你还需要导入 API 密钥,请添加 `--include-secrets`。
|
||||
|
||||
</Step>
|
||||
<Step title="运行 Doctor">
|
||||
@ -113,7 +113,7 @@ OpenClaw 会拒绝自动执行或信任这些状态,因为不同系统之间
|
||||
openclaw doctor
|
||||
```
|
||||
|
||||
[Doctor](/zh-CN/gateway/doctor) 会重新应用所有待处理的配置迁移,并检查导入期间引入的问题。
|
||||
[Doctor](/zh-CN/gateway/doctor) 会重新应用任何待处理的配置迁移,并检查导入过程中引入的问题。
|
||||
|
||||
</Step>
|
||||
<Step title="重启并验证">
|
||||
@ -122,7 +122,7 @@ OpenClaw 会拒绝自动执行或信任这些状态,因为不同系统之间
|
||||
openclaw status
|
||||
```
|
||||
|
||||
确认 Gateway 网关运行正常,并且已加载你导入的模型、记忆和 Skills。
|
||||
确认 Gateway 网关状态正常,并且你导入的模型、记忆和 Skills 已加载。
|
||||
|
||||
</Step>
|
||||
</Steps>
|
||||
@ -132,17 +132,19 @@ OpenClaw 会拒绝自动执行或信任这些状态,因为不同系统之间
|
||||
当计划报告冲突时(目标位置已存在文件或配置值),应用会拒绝继续。
|
||||
|
||||
<Warning>
|
||||
只有在你明确打算替换现有目标时,才使用 `--overwrite` 重新运行。对于被覆盖的文件,提供商仍可能在迁移报告目录中写入按项目划分的备份。
|
||||
仅当替换现有目标是有意为之时,才使用 `--overwrite` 重新运行。对于被覆盖的文件,提供商仍可能在迁移报告目录中写入逐项备份。
|
||||
</Warning>
|
||||
|
||||
对于全新的 OpenClaw 安装,冲突并不常见。它们通常出现在你对已经有用户编辑的设置重复运行导入时。
|
||||
对于全新的 OpenClaw 安装,冲突并不常见。它们通常出现在你对已经有用户修改的设置重复运行导入时。
|
||||
|
||||
如果在应用过程中出现冲突(例如配置文件上发生意外竞争),Hermes 会将其余依赖的配置项标记为 `skipped`,原因是 `blocked by earlier apply conflict`,而不是部分写入它们。迁移报告会记录每个被阻止的项目,以便你解决原始冲突后重新运行导入。
|
||||
|
||||
## 密钥
|
||||
|
||||
默认情况下绝不会导入密钥。
|
||||
默认情况下,密钥绝不会被导入。
|
||||
|
||||
- 先运行 `openclaw migrate apply hermes --yes` 以导入非密钥状态。
|
||||
- 如果你还希望一并复制受支持的 `.env` 键,请使用 `--include-secrets` 重新运行。
|
||||
- 如果你还希望复制受支持的 `.env` 键,请使用 `--include-secrets` 重新运行。
|
||||
- 对于由 SecretRef 管理的凭证,请在导入完成后配置 SecretRef 来源。
|
||||
|
||||
## 用于自动化的 JSON 输出
|
||||
@ -152,22 +154,22 @@ openclaw migrate hermes --dry-run --json
|
||||
openclaw migrate apply hermes --json --yes
|
||||
```
|
||||
|
||||
使用 `--json` 且不加 `--yes` 时,apply 会打印计划且不会更改状态。这是 CI 和共享脚本中最安全的模式。
|
||||
使用 `--json` 且不带 `--yes` 时,apply 会打印计划且不会修改状态。这是用于 CI 和共享脚本的最安全模式。
|
||||
|
||||
## 故障排除
|
||||
|
||||
<AccordionGroup>
|
||||
<Accordion title="应用因冲突而被拒绝">
|
||||
检查计划输出。每个冲突都会标明源路径和现有目标。针对每一项,决定是跳过、编辑目标,还是使用 `--overwrite` 重新运行。
|
||||
<Accordion title="Apply 因冲突而拒绝执行">
|
||||
检查计划输出。每个冲突都会标明源路径和现有目标。你可以按项目决定是跳过、编辑目标,还是使用 `--overwrite` 重新运行。
|
||||
</Accordion>
|
||||
<Accordion title="Hermes 不在 ~/.hermes">
|
||||
<Accordion title="Hermes 位于 ~/.hermes 之外">
|
||||
传入 `--from /actual/path`(CLI)或 `--import-source /actual/path`(新手引导)。
|
||||
</Accordion>
|
||||
<Accordion title="新手引导在现有设置上拒绝导入">
|
||||
新手引导导入需要全新设置。你可以重置状态后重新新手引导,或者直接使用 `openclaw migrate apply hermes`,它支持 `--overwrite` 和显式备份控制。
|
||||
<Accordion title="新手引导拒绝在现有设置上导入">
|
||||
新手引导导入需要全新设置。你可以重置状态并重新进行新手引导,或者直接使用 `openclaw migrate apply hermes`,它支持 `--overwrite` 和显式备份控制。
|
||||
</Accordion>
|
||||
<Accordion title="API 密钥没有导入">
|
||||
必须使用 `--include-secrets`,并且只有上面列出的键会被识别。`.env` 中的其他变量会被忽略。
|
||||
必须使用 `--include-secrets`,并且只识别上面列出的键。`.env` 中的其他变量会被忽略。
|
||||
</Accordion>
|
||||
</AccordionGroup>
|
||||
|
||||
@ -175,6 +177,6 @@ openclaw migrate apply hermes --json --yes
|
||||
|
||||
- [`openclaw migrate`](/zh-CN/cli/migrate):完整 CLI 参考、插件契约和 JSON 结构。
|
||||
- [新手引导](/zh-CN/cli/onboard):向导流程和非交互式标志。
|
||||
- [迁移](/zh-CN/install/migrating):在不同机器之间迁移 OpenClaw 安装。
|
||||
- [迁移](/zh-CN/install/migrating):在机器之间迁移 OpenClaw 安装。
|
||||
- [Doctor](/zh-CN/gateway/doctor):迁移后的健康检查。
|
||||
- [智能体工作区](/zh-CN/concepts/agent-workspace):`SOUL.md`、`AGENTS.md` 和记忆文件的存放位置。
|
||||
- [智能体工作区](/zh-CN/concepts/agent-workspace):`SOUL.md`、`AGENTS.md` 和记忆文件所在的位置。
|
||||
|
||||
@ -1,53 +1,53 @@
|
||||
---
|
||||
read_when:
|
||||
- 你正在构建一个 OpenClaw 插件
|
||||
- 你需要发布一个插件配置 schema,或调试插件验证错误
|
||||
summary: 插件清单 + JSON schema 要求(严格配置验证)
|
||||
- 你需要发布一个插件配置模式,或调试插件校验错误
|
||||
summary: 插件清单 + JSON 模式要求(严格配置校验)
|
||||
title: 插件清单
|
||||
x-i18n:
|
||||
generated_at: "2026-04-27T08:31:19Z"
|
||||
generated_at: "2026-04-27T08:44:46Z"
|
||||
model: gpt-5.4
|
||||
provider: openai
|
||||
source_hash: 5b3ffcdfcf09b4480d0cec007d645daebdaeb86a051a233dec192f555359162a
|
||||
source_hash: b656e2d80716e7a1fd8dae1f63bc7cc7ab4b2a1ebdb4790ab3c6b211558b35eb
|
||||
source_path: plugins/manifest.md
|
||||
workflow: 15
|
||||
---
|
||||
|
||||
此页面仅适用于**原生 OpenClaw 插件清单**。
|
||||
此页面仅适用于 **原生 OpenClaw 插件清单**。
|
||||
|
||||
关于兼容的 bundle 布局,请参阅 [Plugin bundles](/zh-CN/plugins/bundles)。
|
||||
如需了解兼容的 bundle 布局,请参阅 [Plugin bundles](/zh-CN/plugins/bundles)。
|
||||
|
||||
兼容的 bundle 格式使用不同的清单文件:
|
||||
|
||||
- Codex bundle:`.codex-plugin/plugin.json`
|
||||
- Claude bundle:`.claude-plugin/plugin.json`,或不带清单的默认 Claude 组件布局
|
||||
- Claude bundle:`.claude-plugin/plugin.json` 或不带清单的默认 Claude 组件布局
|
||||
- Cursor bundle:`.cursor-plugin/plugin.json`
|
||||
|
||||
OpenClaw 也会自动检测这些 bundle 布局,但不会按照此处描述的 `openclaw.plugin.json` schema 对它们进行验证。
|
||||
OpenClaw 也会自动检测这些 bundle 布局,但不会根据此处描述的 `openclaw.plugin.json` 模式对它们进行校验。
|
||||
|
||||
对于兼容 bundle,当布局符合 OpenClaw 运行时预期时,OpenClaw 当前会读取 bundle 元数据、已声明的 skill 根目录、Claude 命令根目录、Claude bundle `settings.json` 默认值、Claude bundle LSP 默认值,以及受支持的 hook pack。
|
||||
对于兼容 bundle,当其布局符合 OpenClaw 运行时预期时,OpenClaw 当前会读取 bundle 元数据、声明的 skill 根目录、Claude 命令根目录、Claude bundle 的 `settings.json` 默认值、Claude bundle 的 LSP 默认值,以及受支持的钩子包。
|
||||
|
||||
每个原生 OpenClaw 插件**都必须**在**插件根目录**中提供一个 `openclaw.plugin.json` 文件。OpenClaw 使用此清单在**不执行插件代码**的情况下验证配置。缺失或无效的清单会被视为插件错误,并阻止配置验证。
|
||||
每个原生 OpenClaw 插件 **都必须** 在 **插件根目录** 中提供一个 `openclaw.plugin.json` 文件。OpenClaw 使用此清单在 **不执行插件代码** 的情况下校验配置。缺失或无效的清单会被视为插件错误,并阻止配置校验。
|
||||
|
||||
请参阅完整的插件系统指南:[插件](/zh-CN/tools/plugin)。
|
||||
关于原生能力模型和当前的外部兼容性指引,请参阅:
|
||||
请参阅完整的插件系统指南:[Plugins](/zh-CN/tools/plugin)。
|
||||
如需了解原生能力模型和当前的外部兼容性指导,请参阅:
|
||||
[能力模型](/zh-CN/plugins/architecture#public-capability-model)。
|
||||
|
||||
## 此文件的作用
|
||||
|
||||
`openclaw.plugin.json` 是 OpenClaw 在**加载你的插件代码之前**读取的元数据。下面的所有内容都必须足够轻量,以便在不启动插件运行时的情况下进行检查。
|
||||
`openclaw.plugin.json` 是 OpenClaw 在 **加载你的插件代码之前** 读取的元数据。下面的所有内容都必须足够轻量,能够在不启动插件运行时的情况下进行检查。
|
||||
|
||||
**用于:**
|
||||
**适用场景:**
|
||||
|
||||
- 插件标识、配置验证和配置 UI 提示
|
||||
- 凭证、onboarding 和设置元数据(别名、自动启用、provider 环境变量、凭证选项)
|
||||
- 插件标识、配置校验和配置 UI 提示
|
||||
- 认证、新手引导和设置元数据(别名、自动启用、provider 环境变量、认证选项)
|
||||
- control-plane 界面的激活提示
|
||||
- 简写的模型家族归属
|
||||
- 简写模型家族归属
|
||||
- 静态能力归属快照(`contracts`)
|
||||
- 供共享 `openclaw qa` 主机检查的 QA 运行器元数据
|
||||
- 合并到 catalog 和验证界面中的渠道专用配置元数据
|
||||
- 合并到目录和校验界面的渠道特定配置元数据
|
||||
|
||||
**不要用于:**注册运行时行为、声明代码入口点或 npm 安装元数据。这些应放在你的插件代码和 `package.json` 中。
|
||||
**不适用场景:** 注册运行时行为、声明代码入口点,或 npm 安装元数据。这些应放在你的插件代码和 `package.json` 中。
|
||||
|
||||
## 最小示例
|
||||
|
||||
@ -129,67 +129,67 @@ OpenClaw 也会自动检测这些 bundle 布局,但不会按照此处描述的
|
||||
|
||||
| 字段 | 必填 | 类型 | 含义 |
|
||||
| ------------------------------------ | -------- | -------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `id` | 是 | `string` | 规范的插件 id。这是在 `plugins.entries.<id>` 中使用的 id。 |
|
||||
| `configSchema` | 是 | `object` | 此插件配置的内联 JSON Schema。 |
|
||||
| `enabledByDefault` | 否 | `true` | 将内置插件标记为默认启用。省略此字段,或将其设置为任何非 `true` 的值,则插件默认保持禁用。 |
|
||||
| `legacyPluginIds` | 否 | `string[]` | 会规范化为此标准插件 id 的旧版 id。 |
|
||||
| `autoEnableWhenConfiguredProviders` | 否 | `string[]` | 当凭证、配置或模型引用提到这些 provider id 时,应自动启用此插件。 |
|
||||
| `kind` | 否 | `"memory"` \| `"context-engine"` | 声明一个由 `plugins.slots.*` 使用的排他性插件种类。 |
|
||||
| `channels` | 否 | `string[]` | 由此插件拥有的渠道 id。用于设备发现和配置验证。 |
|
||||
| `providers` | 否 | `string[]` | 由此插件拥有的 provider id。 |
|
||||
| `providerDiscoveryEntry` | 否 | `string` | 轻量级 provider 发现模块路径,相对于插件根目录,用于可在不激活完整插件运行时的情况下加载的、限定于清单范围内的 provider catalog 元数据。 |
|
||||
| `modelSupport` | 否 | `object` | 由清单拥有的简写模型家族元数据,用于在运行时之前自动加载插件。 |
|
||||
| `modelCatalog` | 否 | `object` | 由此插件拥有的 providers 的声明式模型 catalog 元数据。这是未来只读列表、新手引导、模型选择器、别名和抑制功能的 control-plane 契约,无需加载插件运行时。 |
|
||||
| `modelPricing` | 否 | `object` | provider 自有的外部定价查询策略。用它可让本地 / 自托管 provider 退出远程定价 catalog,或将 provider 引用映射到 OpenRouter / LiteLLM catalog id,而无需在核心中硬编码 provider id。 |
|
||||
| `providerEndpoints` | 否 | `object[]` | 由清单拥有的 endpoint host / `baseUrl` 元数据,用于核心在 provider 运行时加载前必须分类的 provider 路由。 |
|
||||
| `cliBackends` | 否 | `string[]` | 由此插件拥有的 CLI 推理后端 id。用于基于显式配置引用的启动时自动激活。 |
|
||||
| `syntheticAuthRefs` | 否 | `string[]` | provider 或 CLI 后端引用;在运行时加载之前的冷启动模型发现期间,应探测其由插件拥有的 synthetic auth hook。 |
|
||||
| `nonSecretAuthMarkers` | 否 | `string[]` | 由内置插件拥有的占位 API key 值,表示非密钥的本地、OAuth 或环境凭证状态。 |
|
||||
| `commandAliases` | 否 | `object[]` | 由此插件拥有的命令名称,应在运行时加载前生成具备插件感知能力的配置和 CLI 诊断信息。 |
|
||||
| `providerAuthEnvVars` | 否 | `Record<string, string[]>` | 已弃用的兼容性环境变量元数据,用于 provider 凭证 / Status 查询。新插件请优先使用 `setup.providers[].envVars`;在弃用过渡期内,OpenClaw 仍会读取此字段。 |
|
||||
| `providerAuthAliases` | 否 | `Record<string, string>` | 应复用另一个 provider id 进行凭证查询的 provider id,例如与基础 provider 共享 API key 和凭证配置文件的编码 provider。 |
|
||||
| `channelEnvVars` | 否 | `Record<string, string[]>` | OpenClaw 可在不加载插件代码的情况下检查的轻量级渠道环境变量元数据。将其用于由环境变量驱动的渠道设置或凭证界面,以便通用的启动 / 配置辅助工具可以识别。 |
|
||||
| `providerAuthChoices` | 否 | `object[]` | 轻量级的凭证选项元数据,用于 onboarding 选择器、首选 provider 解析和简单的 CLI 标志绑定。 |
|
||||
| `activation` | 否 | `object` | 轻量级的激活规划器元数据,用于基于 provider、命令、渠道、路由和能力触发的加载。仅为元数据;实际行为仍由插件运行时负责。 |
|
||||
| `setup` | 否 | `object` | 轻量级的设置 / onboarding 描述符,供设备发现和设置界面在不加载插件运行时的情况下检查。 |
|
||||
| `qaRunners` | 否 | `object[]` | 轻量级 QA 运行器描述符,供共享 `openclaw qa` 主机在插件运行时加载前使用。 |
|
||||
| `contracts` | 否 | `object` | 静态内置能力快照,用于 external auth hooks、speech、实时转录、实时语音、媒体理解、图像生成、音乐生成、视频生成、web-fetch、网络搜索和工具归属。 |
|
||||
| `mediaUnderstandingProviderMetadata` | 否 | `Record<string, object>` | 为 `contracts.mediaUnderstandingProviders` 中声明的 provider id 提供的轻量级媒体理解默认值。 |
|
||||
| `channelConfigs` | 否 | `Record<string, object>` | 由清单拥有的渠道配置元数据,在运行时加载前合并到设备发现和验证界面中。 |
|
||||
| `skills` | 否 | `string[]` | 要加载的 Skills 目录,相对于插件根目录。 |
|
||||
| `name` | 否 | `string` | 人类可读的插件名称。 |
|
||||
| `description` | 否 | `string` | 在插件界面中显示的简短摘要。 |
|
||||
| `version` | 否 | `string` | 信息性插件版本。 |
|
||||
| `uiHints` | 否 | `Record<string, object>` | 配置字段的 UI 标签、占位符和敏感性提示。 |
|
||||
| `id` | 是 | `string` | 规范插件 id。这是 `plugins.entries.<id>` 中使用的 id。 |
|
||||
| `configSchema` | 是 | `object` | 此插件配置的内联 JSON Schema。 |
|
||||
| `enabledByDefault` | 否 | `true` | 将内置插件标记为默认启用。若要让插件默认禁用,请省略此字段,或设置为任何非 `true` 的值。 |
|
||||
| `legacyPluginIds` | 否 | `string[]` | 会规范化为此规范插件 id 的旧版 id。 |
|
||||
| `autoEnableWhenConfiguredProviders` | 否 | `string[]` | 当认证、配置或模型引用提到这些 provider id 时,应自动启用此插件。 |
|
||||
| `kind` | 否 | `"memory"` \| `"context-engine"` | 声明一个由 `plugins.slots.*` 使用的排他性插件类型。 |
|
||||
| `channels` | 否 | `string[]` | 由此插件拥有的渠道 id。用于设备发现和配置校验。 |
|
||||
| `providers` | 否 | `string[]` | 由此插件拥有的 provider id。 |
|
||||
| `providerDiscoveryEntry` | 否 | `string` | 轻量级 provider 发现模块路径,相对于插件根目录,用于作用域限定在清单中的 provider 目录元数据,这些元数据可在不激活完整插件运行时的情况下加载。 |
|
||||
| `modelSupport` | 否 | `object` | 由清单拥有的简写模型家族元数据,用于在运行时之前自动加载插件。 |
|
||||
| `modelCatalog` | 否 | `object` | 由声明式模型目录元数据构成,适用于此插件拥有的 provider。这是未来只读列表、新手引导、模型选择器、别名和抑制机制的 control-plane 合约,无需加载插件运行时。 |
|
||||
| `modelPricing` | 否 | `object` | 由 provider 拥有的外部定价查找策略。用它将本地/自托管 provider 排除在远程定价目录之外,或将 provider 引用映射到 OpenRouter/LiteLLM 目录 id,而无需在核心中硬编码 provider id。 |
|
||||
| `providerEndpoints` | 否 | `object[]` | 由清单拥有的端点 host/baseUrl 元数据,适用于核心必须在 provider 运行时加载前进行分类的 provider 路由。 |
|
||||
| `cliBackends` | 否 | `string[]` | 由此插件拥有的 CLI 推理后端 id。用于根据显式配置引用在启动时自动激活。 |
|
||||
| `syntheticAuthRefs` | 否 | `string[]` | 在运行时加载前进行冷模型发现期间,应探测其插件自有 synthetic auth hook 的 provider 或 CLI 后端引用。 |
|
||||
| `nonSecretAuthMarkers` | 否 | `string[]` | 由内置插件拥有的占位 API key 值,表示非机密的本地、OAuth 或环境凭证状态。 |
|
||||
| `commandAliases` | 否 | `object[]` | 由此插件拥有的命令名称,应在运行时加载前生成具备插件感知能力的配置和 CLI 诊断信息。 |
|
||||
| `providerAuthEnvVars` | 否 | `Record<string, string[]>` | 用于 provider 认证/Status 查找的已弃用兼容环境变量元数据。新插件应优先使用 `setup.providers[].envVars`;在弃用窗口期间,OpenClaw 仍会读取此字段。 |
|
||||
| `providerAuthAliases` | 否 | `Record<string, string>` | 应复用另一个 provider id 进行认证查找的 provider id,例如与基础 provider API key 和认证配置文件共享的编码 provider。 |
|
||||
| `channelEnvVars` | 否 | `Record<string, string[]>` | OpenClaw 可在不加载插件代码的情况下检查的轻量渠道环境变量元数据。用于基于环境变量的渠道设置或认证界面,以便通用启动/配置辅助功能能够识别。 |
|
||||
| `providerAuthChoices` | 否 | `object[]` | 轻量认证选项元数据,用于新手引导选择器、首选 provider 解析和简单的 CLI 标志接线。 |
|
||||
| `activation` | 否 | `object` | 轻量激活规划器元数据,用于由 provider、命令、渠道、路由和能力触发的加载。仅限元数据;实际行为仍由插件运行时负责。 |
|
||||
| `setup` | 否 | `object` | 轻量设置/新手引导描述符,供设备发现和设置界面在不加载插件运行时的情况下检查。 |
|
||||
| `qaRunners` | 否 | `object[]` | 轻量 QA 运行器描述符,供共享 `openclaw qa` 主机在插件运行时加载前使用。 |
|
||||
| `contracts` | 否 | `object` | 静态内置能力快照,适用于外部认证钩子、语音、实时转录、实时语音、媒体理解、图像生成、音乐生成、视频生成、网页抓取、网页搜索和工具归属。 |
|
||||
| `mediaUnderstandingProviderMetadata` | 否 | `Record<string, object>` | 适用于 `contracts.mediaUnderstandingProviders` 中声明的 provider id 的轻量媒体理解默认元数据。 |
|
||||
| `channelConfigs` | 否 | `Record<string, object>` | 由清单拥有的渠道配置元数据,在运行时加载前合并到设备发现和校验界面中。 |
|
||||
| `skills` | 否 | `string[]` | 要加载的 Skills 目录,相对于插件根目录。 |
|
||||
| `name` | 否 | `string` | 人类可读的插件名称。 |
|
||||
| `description` | 否 | `string` | 显示在插件界面中的简短摘要。 |
|
||||
| `version` | 否 | `string` | 信息性插件版本。 |
|
||||
| `uiHints` | 否 | `Record<string, object>` | 配置字段的 UI 标签、占位符和敏感性提示。 |
|
||||
|
||||
## `providerAuthChoices` 参考
|
||||
|
||||
每个 `providerAuthChoices` 条目描述一个 onboarding 或凭证选项。
|
||||
每个 `providerAuthChoices` 条目描述一个新手引导或认证选项。
|
||||
OpenClaw 会在 provider 运行时加载前读取它。
|
||||
provider 设置列表会使用这些清单选项、从描述符派生的设置选项以及安装 catalog 元数据,而无需加载 provider 运行时。
|
||||
provider 设置列表会使用这些清单选项、从描述符派生的设置选项,以及安装目录元数据,而无需加载 provider 运行时。
|
||||
|
||||
| 字段 | 必填 | 类型 | 含义 |
|
||||
| --------------------- | -------- | ----------------------------------------------- | -------------------------------------------------------------------------------------------------------- |
|
||||
| `provider` | 是 | `string` | 此选项所属的 provider id。 |
|
||||
| `method` | 是 | `string` | 要分派到的凭证方法 id。 |
|
||||
| `choiceId` | 是 | `string` | onboarding 和 CLI 流程使用的稳定凭证选项 id。 |
|
||||
| `choiceLabel` | 否 | `string` | 面向用户的标签。如省略,OpenClaw 会回退到 `choiceId`。 |
|
||||
| `choiceHint` | 否 | `string` | 选择器中的简短辅助文本。 |
|
||||
| `assistantPriority` | 否 | `number` | 在由 assistant 驱动的交互式选择器中,值越小排序越靠前。 |
|
||||
| `assistantVisibility` | 否 | `"visible"` \| `"manual-only"` | 在 assistant 选择器中隐藏此选项,但仍允许手动 CLI 选择。 |
|
||||
| `deprecatedChoiceIds` | 否 | `string[]` | 应将用户重定向到此替代选项的旧版选项 id。 |
|
||||
| `groupId` | 否 | `string` | 用于对相关选项分组的可选分组 id。 |
|
||||
| `groupLabel` | 否 | `string` | 该分组面向用户的标签。 |
|
||||
| `groupHint` | 否 | `string` | 该分组的简短辅助文本。 |
|
||||
| `optionKey` | 否 | `string` | 用于简单单标志凭证流程的内部选项键。 |
|
||||
| `cliFlag` | 否 | `string` | CLI 标志名称,例如 `--openrouter-api-key`。 |
|
||||
| `cliOption` | 否 | `string` | 完整的 CLI 选项形式,例如 `--openrouter-api-key <key>`。 |
|
||||
| `cliDescription` | 否 | `string` | 在 CLI 帮助中使用的描述。 |
|
||||
| `onboardingScopes` | 否 | `Array<"text-inference" \| "image-generation">` | 此选项应出现在哪些 onboarding 界面中。如省略,默认值为 `["text-inference"]`。 |
|
||||
| `provider` | 是 | `string` | 此选项所属的 provider id。 |
|
||||
| `method` | 是 | `string` | 要分派到的认证方法 id。 |
|
||||
| `choiceId` | 是 | `string` | 由新手引导和 CLI 流程使用的稳定认证选项 id。 |
|
||||
| `choiceLabel` | 否 | `string` | 面向用户的标签。若省略,OpenClaw 会回退为 `choiceId`。 |
|
||||
| `choiceHint` | 否 | `string` | 选择器的简短辅助文本。 |
|
||||
| `assistantPriority` | 否 | `number` | 在由助手驱动的交互式选择器中,值越小排序越靠前。 |
|
||||
| `assistantVisibility` | 否 | `"visible"` \| `"manual-only"` | 在助手选择器中隐藏该选项,但仍允许通过手动 CLI 进行选择。 |
|
||||
| `deprecatedChoiceIds` | 否 | `string[]` | 应将用户重定向到此替代选项的旧版选项 id。 |
|
||||
| `groupId` | 否 | `string` | 用于对相关选项进行分组的可选组 id。 |
|
||||
| `groupLabel` | 否 | `string` | 该分组面向用户的标签。 |
|
||||
| `groupHint` | 否 | `string` | 该分组的简短辅助文本。 |
|
||||
| `optionKey` | 否 | `string` | 用于简单单标志认证流程的内部选项键。 |
|
||||
| `cliFlag` | 否 | `string` | CLI 标志名称,例如 `--openrouter-api-key`。 |
|
||||
| `cliOption` | 否 | `string` | 完整的 CLI 选项形式,例如 `--openrouter-api-key <key>`。 |
|
||||
| `cliDescription` | 否 | `string` | CLI 帮助中使用的说明。 |
|
||||
| `onboardingScopes` | 否 | `Array<"text-inference" \| "image-generation">` | 此选项应出现在哪些新手引导界面中。若省略,默认值为 `["text-inference"]`。 |
|
||||
|
||||
## `commandAliases` 参考
|
||||
|
||||
当插件拥有一个运行时命令名,而用户可能错误地将它放入 `plugins.allow` 中,或尝试将它作为根 CLI 命令运行时,请使用 `commandAliases`。OpenClaw 使用这些元数据提供诊断,而无需导入插件运行时代码。
|
||||
当一个插件拥有某个运行时命令名,而用户可能误将其放入 `plugins.allow`,或尝试将其作为根 CLI 命令运行时,请使用 `commandAliases`。OpenClaw 使用这些元数据来提供诊断,而无需导入插件运行时代码。
|
||||
|
||||
```json
|
||||
{
|
||||
@ -205,20 +205,20 @@ provider 设置列表会使用这些清单选项、从描述符派生的设置
|
||||
|
||||
| 字段 | 必填 | 类型 | 含义 |
|
||||
| ------------ | -------- | ----------------- | ----------------------------------------------------------------------- |
|
||||
| `name` | 是 | `string` | 属于此插件的命令名称。 |
|
||||
| `kind` | 否 | `"runtime-slash"` | 将该别名标记为聊天斜杠命令,而不是根 CLI 命令。 |
|
||||
| `cliCommand` | 否 | `string` | 若存在,可建议用于 CLI 操作的相关根 CLI 命令。 |
|
||||
| `name` | 是 | `string` | 属于此插件的命令名称。 |
|
||||
| `kind` | 否 | `"runtime-slash"` | 将该别名标记为聊天斜杠命令,而不是根 CLI 命令。 |
|
||||
| `cliCommand` | 否 | `string` | 若存在,用于建议 CLI 操作的相关根 CLI 命令。 |
|
||||
|
||||
## `activation` 参考
|
||||
|
||||
当插件能够以低成本声明哪些 control-plane 事件应将其纳入激活 / 加载计划时,请使用 `activation`。
|
||||
当插件可以以低成本声明哪些 control-plane 事件应将其纳入激活/加载计划时,请使用 `activation`。
|
||||
|
||||
此块是规划器元数据,不是生命周期 API。它不会注册运行时行为,不会替代 `register(...)`,也不保证插件代码已经执行。激活规划器使用这些字段在回退到现有清单归属元数据(如 `providers`、`channels`、`commandAliases`、`setup.providers`、`contracts.tools` 和 hooks)之前,先缩小候选插件范围。
|
||||
此块是规划器元数据,而不是生命周期 API。它不会注册运行时行为,不会替代 `register(...)`,也不保证插件代码已经执行。激活规划器使用这些字段在回退到现有清单归属元数据(如 `providers`、`channels`、`commandAliases`、`setup.providers`、`contracts.tools` 和 hooks)之前,先缩小候选插件范围。
|
||||
|
||||
优先使用已经能够描述归属关系的最窄元数据。当这些字段可以表达该关系时,请使用 `providers`、`channels`、`commandAliases`、setup 描述符或 `contracts`。对于这些归属字段无法表示的额外规划提示,再使用 `activation`。
|
||||
对于诸如 `claude-cli`、`codex-cli` 或 `google-gemini-cli` 之类的 CLI 运行时别名,请使用顶层 `cliBackends`;`activation.onAgentHarnesses` 仅用于那些尚无归属字段的嵌入式 agent harness id。
|
||||
优先使用已经能够描述归属关系的最窄元数据。如果这些字段能表达关系,请使用 `providers`、`channels`、`commandAliases`、设置描述符或 `contracts`。只有在这些归属字段无法表示的情况下,才使用 `activation` 提供额外的规划提示。
|
||||
对于 `claude-cli`、`codex-cli` 或 `google-gemini-cli` 等 CLI 运行时别名,请使用顶层 `cliBackends`;`activation.onAgentHarnesses` 仅适用于尚未拥有归属字段的嵌入式 Agent harness id。
|
||||
|
||||
此块仅为元数据。它不会注册运行时行为,也不会替代 `register(...)`、`setupEntry` 或其他运行时 / 插件入口点。当前使用方会在更广泛的插件加载之前,将其作为缩小范围的提示,因此缺失激活元数据通常只会带来性能成本;在旧版清单归属回退仍存在的情况下,它不应改变正确性。
|
||||
此块仅为元数据。它不会注册运行时行为,也不会替代 `register(...)`、`setupEntry` 或其他运行时/插件入口点。当前使用方会在更广泛的插件加载之前将其作为缩小范围的提示,因此缺少激活元数据通常只会影响性能;在旧版清单归属回退仍然存在时,它不应影响正确性。
|
||||
|
||||
```json
|
||||
{
|
||||
@ -227,6 +227,7 @@ provider 设置列表会使用这些清单选项、从描述符派生的设置
|
||||
"onCommands": ["models"],
|
||||
"onChannels": ["web"],
|
||||
"onRoutes": ["gateway-webhook"],
|
||||
"onConfigPaths": ["browser"],
|
||||
"onCapabilities": ["provider", "tool"]
|
||||
}
|
||||
}
|
||||
@ -234,29 +235,27 @@ provider 设置列表会使用这些清单选项、从描述符派生的设置
|
||||
|
||||
| 字段 | 必填 | 类型 | 含义 |
|
||||
| ------------------ | -------- | ---------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `onProviders` | 否 | `string[]` | 应将此插件纳入激活 / 加载计划的 provider id。 |
|
||||
| `onAgentHarnesses` | 否 | `string[]` | 应将此插件纳入激活 / 加载计划的嵌入式 Agent harness 运行时 id。对于 CLI 后端别名,请使用顶层 `cliBackends`。 |
|
||||
| `onCommands` | 否 | `string[]` | 应将此插件纳入激活 / 加载计划的命令 id。 |
|
||||
| `onChannels` | 否 | `string[]` | 应将此插件纳入激活 / 加载计划的渠道 id。 |
|
||||
| `onRoutes` | 否 | `string[]` | 应将此插件纳入激活 / 加载计划的路由种类。 |
|
||||
| `onCapabilities` | 否 | `Array<"provider" \| "channel" \| "tool" \| "hook">` | control-plane 激活规划中使用的宽泛能力提示。可能时优先使用更窄的字段。 |
|
||||
| `onProviders` | 否 | `string[]` | 应将此插件纳入激活/加载计划的 provider id。 |
|
||||
| `onAgentHarnesses` | 否 | `string[]` | 应将此插件纳入激活/加载计划的嵌入式 Agent harness 运行时 id。对于 CLI 后端别名,请使用顶层 `cliBackends`。 |
|
||||
| `onCommands` | 否 | `string[]` | 应将此插件纳入激活/加载计划的命令 id。 |
|
||||
| `onChannels` | 否 | `string[]` | 应将此插件纳入激活/加载计划的渠道 id。 |
|
||||
| `onRoutes` | 否 | `string[]` | 应将此插件纳入激活/加载计划的路由类型。 |
|
||||
| `onConfigPaths` | 否 | `string[]` | 当这些相对于根目录的配置路径存在且未被显式禁用时,应将此插件纳入启动/加载计划。 |
|
||||
| `onCapabilities` | 否 | `Array<"provider" \| "channel" \| "tool" \| "hook">` | control-plane 激活规划使用的宽泛能力提示。若可能,优先使用更窄的字段。 |
|
||||
|
||||
当前在线使用方:
|
||||
|
||||
- 命令触发的 CLI 规划会回退到旧版的
|
||||
`commandAliases[].cliCommand` 或 `commandAliases[].name`
|
||||
- agent 运行时启动规划对嵌入式 harness 使用 `activation.onAgentHarnesses`,对 CLI 运行时别名使用顶层 `cliBackends[]`
|
||||
- 渠道触发的 setup / 渠道规划在缺少显式渠道激活元数据时,会回退到旧版 `channels[]`
|
||||
归属
|
||||
- provider 触发的 setup / 运行时规划在缺少显式 provider
|
||||
激活元数据时,会回退到旧版 `providers[]` 和顶层 `cliBackends[]`
|
||||
归属
|
||||
- 由命令触发的 CLI 规划会回退到旧版 `commandAliases[].cliCommand` 或 `commandAliases[].name`
|
||||
- Agent 运行时启动规划对嵌入式 harness 使用 `activation.onAgentHarnesses`,对 CLI 运行时别名使用顶层 `cliBackends[]`
|
||||
- 由渠道触发的设置/渠道规划在缺少显式渠道激活元数据时,会回退到旧版 `channels[]` 归属
|
||||
- 启动插件规划对非渠道的根配置界面(例如内置浏览器插件的 `browser` 块)使用 `activation.onConfigPaths`
|
||||
- 由 provider 触发的设置/运行时规划在缺少显式 provider 激活元数据时,会回退到旧版 `providers[]` 和顶层 `cliBackends[]` 归属
|
||||
|
||||
规划器诊断可以区分显式激活提示和清单归属回退。例如,`activation-command-hint` 表示匹配了 `activation.onCommands`,而 `manifest-command-alias` 表示规划器改用了 `commandAliases` 归属。这些原因标签用于主机诊断和测试;插件作者应继续声明最能描述归属关系的元数据。
|
||||
规划器诊断可以区分显式激活提示和清单归属回退。例如,`activation-command-hint` 表示匹配了 `activation.onCommands`,而 `manifest-command-alias` 表示规划器改为使用 `commandAliases` 归属。这些原因标签用于主机诊断和测试;插件作者应继续声明最能描述归属关系的元数据。
|
||||
|
||||
## `qaRunners` 参考
|
||||
|
||||
当插件在共享 `openclaw qa` 根命令下贡献一个或多个传输运行器时,请使用 `qaRunners`。请保持这些元数据轻量且静态;实际的 CLI 注册仍由插件运行时通过导出 `qaRunnerCliRegistrations` 的轻量级 `runtime-api.ts` 界面负责。
|
||||
当插件在共享 `openclaw qa` 根命令下提供一个或多个传输运行器时,请使用 `qaRunners`。请将这些元数据保持为轻量且静态;实际的 CLI 注册仍由插件运行时通过一个导出 `qaRunnerCliRegistrations` 的轻量 `runtime-api.ts` 接口负责。
|
||||
|
||||
```json
|
||||
{
|
||||
@ -271,12 +270,12 @@ provider 设置列表会使用这些清单选项、从描述符派生的设置
|
||||
|
||||
| 字段 | 必填 | 类型 | 含义 |
|
||||
| ------------- | -------- | -------- | ------------------------------------------------------------------ |
|
||||
| `commandName` | 是 | `string` | 挂载在 `openclaw qa` 之下的子命令,例如 `matrix`。 |
|
||||
| `description` | 否 | `string` | 当共享主机需要一个 stub 命令时使用的回退帮助文本。 |
|
||||
| `commandName` | 是 | `string` | 挂载在 `openclaw qa` 下的子命令,例如 `matrix`。 |
|
||||
| `description` | 否 | `string` | 当共享主机需要存根命令时使用的回退帮助文本。 |
|
||||
|
||||
## `setup` 参考
|
||||
|
||||
当设置和 onboarding 界面在运行时加载前需要轻量级的、由插件拥有的元数据时,请使用 `setup`。
|
||||
当设置和新手引导界面在运行时加载前需要低成本的插件自有元数据时,请使用 `setup`。
|
||||
|
||||
```json
|
||||
{
|
||||
@ -295,17 +294,17 @@ provider 设置列表会使用这些清单选项、从描述符派生的设置
|
||||
}
|
||||
```
|
||||
|
||||
顶层 `cliBackends` 仍然有效,并继续描述 CLI 推理后端。`setup.cliBackends` 是面向 control-plane / 设置流程的、特定于设置的描述符界面,应保持为纯元数据。
|
||||
顶层 `cliBackends` 仍然有效,并继续描述 CLI 推理后端。`setup.cliBackends` 是面向 control-plane/设置流程的设置专用描述符界面,应保持为纯元数据。
|
||||
|
||||
存在时,`setup.providers` 和 `setup.cliBackends` 是设置发现时首选的 descriptor-first 查询界面。如果描述符仅缩小候选插件范围,而设置仍需要更丰富的设置时运行时 hooks,请将 `requiresRuntime` 设为 `true`,并保留 `setup-api` 作为回退执行路径。
|
||||
当存在 `setup.providers` 和 `setup.cliBackends` 时,它们是设置发现的首选“描述符优先”查找界面。如果描述符只能缩小候选插件范围,而设置仍需要更丰富的设置时运行时钩子,请设置 `requiresRuntime: true`,并保留 `setup-api` 作为回退执行路径。
|
||||
|
||||
OpenClaw 还会将 `setup.providers[].envVars` 纳入通用 provider 凭证和环境变量查询中。`providerAuthEnvVars` 在弃用过渡期内仍通过兼容适配器受支持,但仍使用它的非内置插件会收到清单诊断。新插件应将设置 / Status 环境变量元数据放在 `setup.providers[].envVars` 上。
|
||||
OpenClaw 还会将 `setup.providers[].envVars` 纳入通用的 provider 认证和环境变量查找。`providerAuthEnvVars` 在弃用窗口期间仍通过兼容适配器受到支持,但仍使用它的非内置插件会收到清单诊断。新插件应将设置/Status 环境变量元数据放在 `setup.providers[].envVars` 上。
|
||||
|
||||
当没有 setup 条目,或者 `setup.requiresRuntime: false` 表示无需设置运行时时,OpenClaw 也可以根据 `setup.providers[].authMethods` 推导简单的设置选项。显式的 `providerAuthChoices` 条目仍然更适合自定义标签、CLI 标志、onboarding 范围和 assistant 元数据。
|
||||
当没有可用的 setup 条目,或 `setup.requiresRuntime: false` 声明设置运行时并非必需时,OpenClaw 也可以根据 `setup.providers[].authMethods` 推导出简单的设置选项。对于自定义标签、CLI 标志、新手引导范围和助手元数据,显式的 `providerAuthChoices` 条目仍然是首选。
|
||||
|
||||
仅当这些描述符已足以满足设置界面需求时,才将 `requiresRuntime` 设为 `false`。OpenClaw 将显式的 `false` 视为仅描述符契约,并且不会为设置查询执行 `setup-api` 或 `openclaw.setupEntry`。如果一个仅描述符插件仍然提供了这些设置运行时入口之一,OpenClaw 会报告一条附加诊断,并继续忽略它。省略 `requiresRuntime` 会保留旧版回退行为,这样那些在未添加该标志的情况下新增描述符的现有插件就不会出问题。
|
||||
仅当这些描述符已足以满足设置界面需求时,才设置 `requiresRuntime: false`。OpenClaw 会将显式的 `false` 视为纯描述符合约,并且不会为了设置查找而执行 `setup-api` 或 `openclaw.setupEntry`。如果一个纯描述符插件仍然提供了这些设置运行时入口之一,OpenClaw 会报告一条附加诊断,并继续忽略它。省略 `requiresRuntime` 会保留旧版回退行为,以便现有那些添加了描述符但未添加该标志的插件不会出错。
|
||||
|
||||
由于设置查询可能会执行由插件拥有的 `setup-api` 代码,规范化后的 `setup.providers[].id` 和 `setup.cliBackends[]` 值在已发现插件之间必须保持唯一。归属不明确时会以封闭失败方式处理,而不是按发现顺序选一个胜出者。
|
||||
由于设置查找可能会执行插件自有的 `setup-api` 代码,因此规范化后的 `setup.providers[].id` 和 `setup.cliBackends[]` 值必须在所有已发现插件中保持唯一。归属不明确时会以失败关闭的方式处理,而不是根据发现顺序选出一个“赢家”。
|
||||
|
||||
当设置运行时确实执行时,如果 `setup-api` 注册了清单描述符未声明的 provider 或 CLI 后端,或者某个描述符没有对应的运行时注册,设置注册表诊断会报告描述符漂移。这些诊断是附加性的,不会拒绝旧版插件。
|
||||
|
||||
@ -313,22 +312,22 @@ OpenClaw 还会将 `setup.providers[].envVars` 纳入通用 provider 凭证和
|
||||
|
||||
| 字段 | 必填 | 类型 | 含义 |
|
||||
| ------------- | -------- | ---------- | ------------------------------------------------------------------------------------ |
|
||||
| `id` | 是 | `string` | 在设置或 onboarding 期间公开的 provider id。保持规范化 id 在全局范围内唯一。 |
|
||||
| `authMethods` | 否 | `string[]` | 此 provider 在不加载完整运行时的情况下支持的设置 / 凭证方法 id。 |
|
||||
| `envVars` | 否 | `string[]` | 通用设置 / Status 界面可在插件运行时加载前检查的环境变量。 |
|
||||
| `id` | 是 | `string` | 在设置或新手引导期间暴露的 provider id。保持规范化 id 在全局唯一。 |
|
||||
| `authMethods` | 否 | `string[]` | 此 provider 在不加载完整运行时的情况下支持的设置/认证方法 id。 |
|
||||
| `envVars` | 否 | `string[]` | 通用设置/Status 界面可在插件运行时加载前检查的环境变量。 |
|
||||
|
||||
### `setup` 字段
|
||||
|
||||
| 字段 | 必填 | 类型 | 含义 |
|
||||
| ------------------ | -------- | ---------- | --------------------------------------------------------------------------------------------------- |
|
||||
| `providers` | 否 | `object[]` | 在设置和 onboarding 期间公开的 provider 设置描述符。 |
|
||||
| `cliBackends` | 否 | `string[]` | 用于 descriptor-first 设置查询的设置时后端 id。保持规范化 id 在全局范围内唯一。 |
|
||||
| `configMigrations` | 否 | `string[]` | 由此插件的设置界面拥有的配置迁移 id。 |
|
||||
| `requiresRuntime` | 否 | `boolean` | 在描述符查询之后,设置是否仍需要执行 `setup-api`。 |
|
||||
| `providers` | 否 | `object[]` | 在设置和新手引导期间暴露的 provider 设置描述符。 |
|
||||
| `cliBackends` | 否 | `string[]` | 用于“描述符优先”设置查找的设置时后端 id。保持规范化 id 在全局唯一。 |
|
||||
| `configMigrations` | 否 | `string[]` | 由此插件的设置界面拥有的配置迁移 id。 |
|
||||
| `requiresRuntime` | 否 | `boolean` | 在描述符查找之后,设置是否仍需要执行 `setup-api`。 |
|
||||
|
||||
## `uiHints` 参考
|
||||
|
||||
`uiHints` 是从配置字段名称映射到小型渲染提示的映射表。
|
||||
`uiHints` 是一个从配置字段名映射到小型渲染提示的映射表。
|
||||
|
||||
```json
|
||||
{
|
||||
@ -343,20 +342,20 @@ OpenClaw 还会将 `setup.providers[].envVars` 纳入通用 provider 凭证和
|
||||
}
|
||||
```
|
||||
|
||||
每个字段提示可包含:
|
||||
每个字段提示可以包含:
|
||||
|
||||
| 字段 | 类型 | 含义 |
|
||||
| ------------- | ---------- | --------------------------------------- |
|
||||
| `label` | `string` | 面向用户的字段标签。 |
|
||||
| `help` | `string` | 简短辅助文本。 |
|
||||
| `tags` | `string[]` | 可选 UI 标签。 |
|
||||
| `advanced` | `boolean` | 将该字段标记为高级项。 |
|
||||
| `sensitive` | `boolean` | 将该字段标记为密钥或敏感项。 |
|
||||
| `placeholder` | `string` | 表单输入的占位文本。 |
|
||||
| `label` | `string` | 面向用户的字段标签。 |
|
||||
| `help` | `string` | 简短辅助文本。 |
|
||||
| `tags` | `string[]` | 可选的 UI 标签。 |
|
||||
| `advanced` | `boolean` | 将该字段标记为高级项。 |
|
||||
| `sensitive` | `boolean` | 将该字段标记为机密或敏感项。 |
|
||||
| `placeholder` | `string` | 表单输入的占位文本。 |
|
||||
|
||||
## `contracts` 参考
|
||||
|
||||
仅将 `contracts` 用于 OpenClaw 可在不导入插件运行时的情况下读取的静态能力归属元数据。
|
||||
仅在 OpenClaw 可以在不导入插件运行时的情况下读取静态能力归属元数据时,才使用 `contracts`。
|
||||
|
||||
```json
|
||||
{
|
||||
@ -382,30 +381,30 @@ OpenClaw 还会将 `setup.providers[].envVars` 纳入通用 provider 凭证和
|
||||
|
||||
| 字段 | 类型 | 含义 |
|
||||
| -------------------------------- | ---------- | --------------------------------------------------------------------- |
|
||||
| `embeddedExtensionFactories` | `string[]` | Codex app-server 扩展工厂 id,目前为 `codex-app-server`。 |
|
||||
| `agentToolResultMiddleware` | `string[]` | 内置插件可为其注册工具结果中间件的运行时 id。 |
|
||||
| `externalAuthProviders` | `string[]` | 此插件拥有其外部凭证配置文件 hook 的 provider id。 |
|
||||
| `speechProviders` | `string[]` | 此插件拥有的语音 provider id。 |
|
||||
| `realtimeTranscriptionProviders` | `string[]` | 此插件拥有的实时转录 provider id。 |
|
||||
| `realtimeVoiceProviders` | `string[]` | 此插件拥有的实时语音 provider id。 |
|
||||
| `memoryEmbeddingProviders` | `string[]` | 此插件拥有的 Memory 嵌入 provider id。 |
|
||||
| `mediaUnderstandingProviders` | `string[]` | 此插件拥有的媒体理解 provider id。 |
|
||||
| `imageGenerationProviders` | `string[]` | 此插件拥有的图像生成 provider id。 |
|
||||
| `videoGenerationProviders` | `string[]` | 此插件拥有的视频生成 provider id。 |
|
||||
| `webFetchProviders` | `string[]` | 此插件拥有的 web-fetch provider id。 |
|
||||
| `webSearchProviders` | `string[]` | 此插件拥有的网络搜索 provider id。 |
|
||||
| `migrationProviders` | `string[]` | 此插件为 `openclaw migrate` 拥有的导入 provider id。 |
|
||||
| `tools` | `string[]` | 此插件为内置契约检查拥有的智能体工具名称。 |
|
||||
| `embeddedExtensionFactories` | `string[]` | Codex app-server 扩展工厂 id,目前为 `codex-app-server`。 |
|
||||
| `agentToolResultMiddleware` | `string[]` | 内置插件可为其注册工具结果中间件的运行时 id。 |
|
||||
| `externalAuthProviders` | `string[]` | 此插件拥有其外部认证配置文件钩子的 provider id。 |
|
||||
| `speechProviders` | `string[]` | 此插件拥有的语音 provider id。 |
|
||||
| `realtimeTranscriptionProviders` | `string[]` | 此插件拥有的实时转录 provider id。 |
|
||||
| `realtimeVoiceProviders` | `string[]` | 此插件拥有的实时语音 provider id。 |
|
||||
| `memoryEmbeddingProviders` | `string[]` | 此插件拥有的 Memory 嵌入 provider id。 |
|
||||
| `mediaUnderstandingProviders` | `string[]` | 此插件拥有的媒体理解 provider id。 |
|
||||
| `imageGenerationProviders` | `string[]` | 此插件拥有的图像生成 provider id。 |
|
||||
| `videoGenerationProviders` | `string[]` | 此插件拥有的视频生成 provider id。 |
|
||||
| `webFetchProviders` | `string[]` | 此插件拥有的网页抓取 provider id。 |
|
||||
| `webSearchProviders` | `string[]` | 此插件拥有的网页搜索 provider id。 |
|
||||
| `migrationProviders` | `string[]` | 此插件为 `openclaw migrate` 拥有的导入 provider id。 |
|
||||
| `tools` | `string[]` | 此插件为内置合约检查拥有的智能体工具名称。 |
|
||||
|
||||
`contracts.embeddedExtensionFactories` 为内置的、仅限 Codex app-server 的扩展工厂保留。内置工具结果转换应声明 `contracts.agentToolResultMiddleware`,并使用 `api.registerAgentToolResultMiddleware(...)` 注册。外部插件不能注册工具结果中间件,因为该接口可以在模型看到高信任工具输出之前重写它。
|
||||
`contracts.embeddedExtensionFactories` 保留给仅限内置 Codex app-server 的扩展工厂。内置工具结果转换应声明 `contracts.agentToolResultMiddleware`,并改用 `api.registerAgentToolResultMiddleware(...)` 进行注册。外部插件不能注册工具结果中间件,因为该接口可以在模型看到高信任度工具输出之前重写它。
|
||||
|
||||
实现了 `resolveExternalAuthProfiles` 的 provider 插件应声明 `contracts.externalAuthProviders`。未声明的插件仍会通过已弃用的兼容性回退运行,但该回退更慢,并将在迁移窗口结束后移除。
|
||||
实现了 `resolveExternalAuthProfiles` 的 provider 插件应声明 `contracts.externalAuthProviders`。未声明该字段的插件仍会通过一个已弃用的兼容回退路径运行,但该回退更慢,并将在迁移窗口结束后移除。
|
||||
|
||||
内置 Memory 嵌入 provider 应为其公开的每个适配器 id 声明 `contracts.memoryEmbeddingProviders`,包括诸如 `local` 这样的内置适配器。独立 CLI 路径使用此清单契约,只在完整 Gateway 网关运行时注册 provider 之前加载归属插件。
|
||||
内置的 Memory 嵌入 provider 应为其暴露的每个适配器 id 声明 `contracts.memoryEmbeddingProviders`,包括诸如 `local` 之类的内置适配器。独立 CLI 路径使用此清单合约,在完整 Gateway 网关运行时注册 provider 之前,仅加载其所属插件。
|
||||
|
||||
## `mediaUnderstandingProviderMetadata` 参考
|
||||
|
||||
当媒体理解 provider 具有默认模型、自动凭证回退优先级或原生文档支持,并且通用核心辅助工具在运行时加载前需要这些信息时,请使用 `mediaUnderstandingProviderMetadata`。这些键也必须在 `contracts.mediaUnderstandingProviders` 中声明。
|
||||
当媒体理解 provider 具有默认模型、自动认证回退优先级,或通用核心辅助功能在运行时加载前所需的原生文档支持时,请使用 `mediaUnderstandingProviderMetadata`。键名也必须在 `contracts.mediaUnderstandingProviders` 中声明。
|
||||
|
||||
```json
|
||||
{
|
||||
@ -428,29 +427,29 @@ OpenClaw 还会将 `setup.providers[].envVars` 纳入通用 provider 凭证和
|
||||
}
|
||||
```
|
||||
|
||||
每个 provider 条目可包含:
|
||||
每个 provider 条目可以包含:
|
||||
|
||||
| 字段 | 类型 | 含义 |
|
||||
| ---------------------- | ----------------------------------- | ---------------------------------------------------------------------------- |
|
||||
| `capabilities` | `("image" \| "audio" \| "video")[]` | 此 provider 公开的媒体能力。 |
|
||||
| `defaultModels` | `Record<string, string>` | 当配置未指定模型时使用的能力到模型默认值映射。 |
|
||||
| `autoPriority` | `Record<string, number>` | 用于自动基于凭证的 provider 回退时,数值越小排序越靠前。 |
|
||||
| `nativeDocumentInputs` | `"pdf"[]` | provider 支持的原生文档输入。 |
|
||||
| `capabilities` | `("image" \| "audio" \| "video")[]` | 此 provider 暴露的媒体能力。 |
|
||||
| `defaultModels` | `Record<string, string>` | 当配置未指定模型时使用的能力到模型默认值。 |
|
||||
| `autoPriority` | `Record<string, number>` | 自动基于凭证的 provider 回退中,数字越小排序越靠前。 |
|
||||
| `nativeDocumentInputs` | `"pdf"[]` | 该 provider 支持的原生文档输入。 |
|
||||
|
||||
## `channelConfigs` 参考
|
||||
|
||||
当渠道插件在运行时加载前需要轻量级配置元数据时,请使用 `channelConfigs`。在没有设置条目,或 `setup.requiresRuntime: false` 声明无需设置运行时时,只读的渠道设置 / Status 发现可直接对已配置的外部渠道使用这些元数据。
|
||||
当渠道插件在运行时加载前需要低成本的配置元数据时,请使用 `channelConfigs`。当没有可用的设置条目,或 `setup.requiresRuntime: false` 声明设置运行时并非必需时,只读的渠道设置/Status 发现可以直接使用这些元数据来处理已配置的外部渠道。
|
||||
|
||||
`channelConfigs` 是插件清单元数据,不是新的顶层用户配置部分。用户仍然在 `channels.<channel-id>` 下配置渠道实例。OpenClaw 会读取清单元数据,以便在插件运行时代码执行前判断哪个插件拥有该已配置渠道。
|
||||
`channelConfigs` 是插件清单元数据,而不是新的顶层用户配置区段。用户仍然在 `channels.<channel-id>` 下配置渠道实例。OpenClaw 会读取清单元数据,以便在插件运行时代码执行前确定哪个插件拥有该已配置渠道。
|
||||
|
||||
对于渠道插件,`configSchema` 和 `channelConfigs` 描述的是不同路径:
|
||||
|
||||
- `configSchema` 验证 `plugins.entries.<plugin-id>.config`
|
||||
- `channelConfigs.<channel-id>.schema` 验证 `channels.<channel-id>`
|
||||
- `configSchema` 校验 `plugins.entries.<plugin-id>.config`
|
||||
- `channelConfigs.<channel-id>.schema` 校验 `channels.<channel-id>`
|
||||
|
||||
声明了 `channels[]` 的非内置插件也应声明匹配的 `channelConfigs` 条目。没有它们时,OpenClaw 仍然可以加载插件,但冷路径配置 schema、设置和 Control UI 界面在插件运行时执行前无法知道该渠道拥有的选项结构。
|
||||
声明了 `channels[]` 的非内置插件也应声明对应的 `channelConfigs` 条目。若未声明,OpenClaw 仍然可以加载该插件,但冷路径配置模式、设置和 Control UI 界面在插件运行时执行前,无法了解该渠道所拥有的选项结构。
|
||||
|
||||
`channelConfigs.<channel-id>.commands.nativeCommandsAutoEnabled` 和 `nativeSkillsAutoEnabled` 可以为在渠道运行时加载前执行的命令配置检查声明静态 `auto` 默认值。内置渠道还可以通过 `package.json#openclaw.channel.commands` 发布相同的默认值,并与其余由包拥有的渠道 catalog 元数据一同提供。
|
||||
`channelConfigs.<channel-id>.commands.nativeCommandsAutoEnabled` 和 `nativeSkillsAutoEnabled` 可以为在渠道运行时加载前执行的命令配置检查声明静态 `auto` 默认值。内置渠道也可以通过 `package.json#openclaw.channel.commands` 发布相同的默认值,并与其其他由包拥有的渠道目录元数据一起提供。
|
||||
|
||||
```json
|
||||
{
|
||||
@ -481,20 +480,20 @@ OpenClaw 还会将 `setup.providers[].envVars` 纳入通用 provider 凭证和
|
||||
}
|
||||
```
|
||||
|
||||
每个渠道条目可包含:
|
||||
每个渠道条目可以包含:
|
||||
|
||||
| 字段 | 类型 | 含义 |
|
||||
| ------------- | ------------------------ | ----------------------------------------------------------------------------------------- |
|
||||
| `schema` | `object` | `channels.<id>` 的 JSON Schema。每个已声明的渠道配置条目都必须提供。 |
|
||||
| `uiHints` | `Record<string, object>` | 该渠道配置部分的可选 UI 标签 / 占位符 / 敏感性提示。 |
|
||||
| `label` | `string` | 当运行时元数据尚未就绪时,合并到选择器和检查界面中的渠道标签。 |
|
||||
| `description` | `string` | 用于检查和 catalog 界面的简短渠道描述。 |
|
||||
| `commands` | `object` | 用于运行时前配置检查的静态原生命令和原生 Skills 自动默认值。 |
|
||||
| `preferOver` | `string[]` | 在选择界面中,此渠道应优先于的旧版或较低优先级插件 id。 |
|
||||
| `schema` | `object` | `channels.<id>` 的 JSON Schema。每个已声明的渠道配置条目都必须提供。 |
|
||||
| `uiHints` | `Record<string, object>` | 该渠道配置区段的可选 UI 标签 / 占位符 / 敏感性提示。 |
|
||||
| `label` | `string` | 当运行时元数据尚未就绪时,合并到选择器和检查界面中的渠道标签。 |
|
||||
| `description` | `string` | 用于检查和目录界面的简短渠道说明。 |
|
||||
| `commands` | `object` | 用于运行时前配置检查的静态原生命令和原生 Skills 自动默认值。 |
|
||||
| `preferOver` | `string[]` | 在选择界面中,此渠道应优先于的旧版或较低优先级插件 id。 |
|
||||
|
||||
### 替换另一个渠道插件
|
||||
|
||||
当你的插件是某个渠道 id 的首选拥有者,而另一个插件也能提供该渠道时,请使用 `preferOver`。常见情况包括:插件 id 已重命名、独立插件取代了内置插件,或维护中的分支为了配置兼容性保留了相同的渠道 id。
|
||||
当你的插件是某个渠道 id 的首选拥有者,而另一个插件也可以提供该渠道时,请使用 `preferOver`。常见情况包括:插件 id 已重命名、独立插件取代了内置插件,或维护中的分叉为了配置兼容性保留了相同的渠道 id。
|
||||
|
||||
```json
|
||||
{
|
||||
@ -515,13 +514,13 @@ OpenClaw 还会将 `setup.providers[].envVars` 纳入通用 provider 凭证和
|
||||
}
|
||||
```
|
||||
|
||||
当配置了 `channels.chat` 时,OpenClaw 会同时考虑渠道 id 和首选插件 id。如果较低优先级插件之所以被选中只是因为它是内置的或默认启用的,OpenClaw 会在生效运行时配置中将其禁用,从而由一个插件拥有该渠道及其工具。显式的用户选择仍然优先:如果用户显式启用了两个插件,OpenClaw 会保留该选择,并报告重复渠道 / 工具诊断,而不是静默更改请求的插件集合。
|
||||
当配置了 `channels.chat` 时,OpenClaw 会同时考虑渠道 id 和首选插件 id。如果较低优先级插件之所以被选中,只是因为它是内置插件或默认启用,OpenClaw 会在生效的运行时配置中禁用它,以便由单个插件拥有该渠道及其工具。显式的用户选择仍然优先:如果用户显式启用了这两个插件,OpenClaw 会保留该选择,并报告重复渠道/工具诊断,而不是静默更改请求的插件集合。
|
||||
|
||||
请将 `preferOver` 的范围限制在确实能提供同一渠道的插件 id 上。它不是通用优先级字段,也不会重命名用户配置键。
|
||||
请将 `preferOver` 限定为确实能够提供同一渠道的插件 id。它不是通用优先级字段,也不会重命名用户配置键。
|
||||
|
||||
## `modelSupport` 参考
|
||||
|
||||
当 OpenClaw 应在插件运行时加载前,根据简写模型 id(如 `gpt-5.5` 或 `claude-sonnet-4.6`)推断你的 provider 插件时,请使用 `modelSupport`。
|
||||
当 OpenClaw 应在插件运行时加载前,根据 `gpt-5.5` 或 `claude-sonnet-4.6` 这类简写模型 id 推断你的 provider 插件时,请使用 `modelSupport`。
|
||||
|
||||
```json
|
||||
{
|
||||
@ -532,23 +531,23 @@ OpenClaw 还会将 `setup.providers[].envVars` 纳入通用 provider 凭证和
|
||||
}
|
||||
```
|
||||
|
||||
OpenClaw 按以下优先级应用:
|
||||
OpenClaw 会按以下优先级处理:
|
||||
|
||||
- 显式 `provider/model` 引用使用其所属 `providers` 清单元数据
|
||||
- `modelPatterns` 优先于 `modelPrefixes`
|
||||
- 如果一个非内置插件和一个内置插件都匹配,则非内置插件胜出
|
||||
- 其余歧义会被忽略,直到用户或配置指定某个 provider
|
||||
- 如果一个非内置插件和一个内置插件都匹配,则非内置插件优先
|
||||
- 剩余歧义会被忽略,直到用户或配置明确指定 provider
|
||||
|
||||
字段:
|
||||
|
||||
| 字段 | 类型 | 含义 |
|
||||
| --------------- | ---------- | ------------------------------------------------------------------------------- |
|
||||
| `modelPrefixes` | `string[]` | 使用 `startsWith` 对简写模型 id 进行匹配的前缀。 |
|
||||
| `modelPatterns` | `string[]` | 在移除配置文件后缀后,与简写模型 id 匹配的正则表达式源码。 |
|
||||
| `modelPrefixes` | `string[]` | 使用 `startsWith` 与简写模型 id 进行匹配的前缀。 |
|
||||
| `modelPatterns` | `string[]` | 在移除 profile 后缀后,与简写模型 id 进行匹配的正则表达式源码。 |
|
||||
|
||||
## `modelCatalog` 参考
|
||||
|
||||
当 OpenClaw 应在加载插件运行时之前了解 provider 模型元数据时,请使用 `modelCatalog`。这是固定 catalog 行、provider 别名、抑制规则和发现模式的清单自有来源。运行时刷新仍归属于 provider 运行时代码,但清单会告诉核心何时需要运行时。
|
||||
当 OpenClaw 应在加载插件运行时之前了解 provider 模型元数据时,请使用 `modelCatalog`。这是由清单拥有的固定目录行、provider 别名、抑制规则和发现模式的数据源。运行时刷新仍然属于 provider 运行时代码,但清单会告知核心何时需要运行时。
|
||||
|
||||
```json
|
||||
{
|
||||
@ -601,47 +600,47 @@ OpenClaw 按以下优先级应用:
|
||||
|
||||
| 字段 | 类型 | 含义 |
|
||||
| -------------- | -------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------- |
|
||||
| `providers` | `Record<string, object>` | 由此插件拥有的 provider id 的 catalog 行。键也应出现在顶层 `providers` 中。 |
|
||||
| `aliases` | `Record<string, object>` | 在 catalog 或抑制规划中应解析到某个所属 provider 的 provider 别名。 |
|
||||
| `suppressions` | `object[]` | 出于 provider 特定原因,由此插件抑制的来自其他来源的模型行。 |
|
||||
| `discovery` | `Record<string, "static" \| "refreshable" \| "runtime">` | provider catalog 是否可从清单元数据读取、可刷新到缓存,或需要运行时。 |
|
||||
| `providers` | `Record<string, object>` | 由此插件拥有的 provider id 的目录行。键名也应出现在顶层 `providers` 中。 |
|
||||
| `aliases` | `Record<string, object>` | 应解析到某个所属 provider 的 provider 别名,用于目录或抑制规划。 |
|
||||
| `suppressions` | `object[]` | 由于特定 provider 原因,由此插件抑制的来自其他来源的模型行。 |
|
||||
| `discovery` | `Record<string, "static" \| "refreshable" \| "runtime">` | provider 目录是可从清单元数据读取、可刷新到缓存,还是必须依赖运行时。 |
|
||||
|
||||
provider 字段:
|
||||
|
||||
| 字段 | 类型 | 含义 |
|
||||
| --------- | ------------------------ | ----------------------------------------------------------------- |
|
||||
| `baseUrl` | `string` | 此 provider catalog 中模型的可选默认 `baseUrl`。 |
|
||||
| `api` | `ModelApi` | 此 provider catalog 中模型的可选默认 API 适配器。 |
|
||||
| `headers` | `Record<string, string>` | 适用于此 provider catalog 的可选静态请求头。 |
|
||||
| `models` | `object[]` | 必填模型行。没有 `id` 的行会被忽略。 |
|
||||
| `baseUrl` | `string` | 此 provider 目录中模型的可选默认 base URL。 |
|
||||
| `api` | `ModelApi` | 此 provider 目录中模型的可选默认 API 适配器。 |
|
||||
| `headers` | `Record<string, string>` | 适用于此 provider 目录的可选静态 headers。 |
|
||||
| `models` | `object[]` | 必填的模型行。没有 `id` 的行会被忽略。 |
|
||||
|
||||
模型字段:
|
||||
|
||||
| 字段 | 类型 | 含义 |
|
||||
| --------------- | -------------------------------------------------------------- | --------------------------------------------------------------------------- |
|
||||
| `id` | `string` | provider 本地模型 id,不含 `provider/` 前缀。 |
|
||||
| `name` | `string` | 可选显示名称。 |
|
||||
| `api` | `ModelApi` | 可选的按模型覆盖的 API。 |
|
||||
| `baseUrl` | `string` | 可选的按模型覆盖的 `baseUrl`。 |
|
||||
| `headers` | `Record<string, string>` | 可选的按模型静态请求头。 |
|
||||
| `input` | `Array<"text" \| "image" \| "document" \| "audio" \| "video">` | 该模型接受的模态。 |
|
||||
| `reasoning` | `boolean` | 该模型是否公开 reasoning 行为。 |
|
||||
| `contextWindow` | `number` | 原生 provider 上下文窗口。 |
|
||||
| `contextTokens` | `number` | 当与 `contextWindow` 不同时,可选的有效运行时上下文上限。 |
|
||||
| `maxTokens` | `number` | 已知时的最大输出 token 数。 |
|
||||
| `cost` | `object` | 可选的每百万 token 美元定价,包括可选的 `tieredPricing`。 |
|
||||
| `compat` | `object` | 与 OpenClaw 模型配置兼容性匹配的可选兼容性标志。 |
|
||||
| `status` | `"available"` \| `"preview"` \| `"deprecated"` \| `"disabled"` | 列表状态。仅当该行完全不应出现时才使用 suppress。 |
|
||||
| `statusReason` | `string` | 随非可用状态显示的可选原因。 |
|
||||
| `replaces` | `string[]` | 此模型取代的旧 provider 本地模型 id。 |
|
||||
| `replacedBy` | `string` | 已弃用行的替代 provider 本地模型 id。 |
|
||||
| `tags` | `string[]` | 供选择器和过滤器使用的稳定标签。 |
|
||||
| `id` | `string` | provider 本地模型 id,不包含 `provider/` 前缀。 |
|
||||
| `name` | `string` | 可选显示名称。 |
|
||||
| `api` | `ModelApi` | 可选的按模型覆盖的 API。 |
|
||||
| `baseUrl` | `string` | 可选的按模型覆盖的 base URL。 |
|
||||
| `headers` | `Record<string, string>` | 可选的按模型静态 headers。 |
|
||||
| `input` | `Array<"text" \| "image" \| "document" \| "audio" \| "video">` | 模型接受的模态。 |
|
||||
| `reasoning` | `boolean` | 该模型是否暴露推理行为。 |
|
||||
| `contextWindow` | `number` | 原生 provider 上下文窗口。 |
|
||||
| `contextTokens` | `number` | 当与 `contextWindow` 不同时,可选的有效运行时上下文上限。 |
|
||||
| `maxTokens` | `number` | 已知时的最大输出 token 数。 |
|
||||
| `cost` | `object` | 可选的每百万 token 美元定价,包括可选的 `tieredPricing`。 |
|
||||
| `compat` | `object` | 与 OpenClaw 模型配置兼容性匹配的可选兼容性标志。 |
|
||||
| `status` | `"available"` \| `"preview"` \| `"deprecated"` \| `"disabled"` | 列表状态。仅当该行完全不应显示时才使用 suppress。 |
|
||||
| `statusReason` | `string` | 与非可用状态一起显示的可选原因。 |
|
||||
| `replaces` | `string[]` | 此模型取代的旧 provider 本地模型 id。 |
|
||||
| `replacedBy` | `string` | 已弃用行对应的替代 provider 本地模型 id。 |
|
||||
| `tags` | `string[]` | 供选择器和筛选器使用的稳定标签。 |
|
||||
|
||||
不要把仅运行时数据放入 `modelCatalog`。如果某个 provider 需要账户状态、API 请求或本地进程发现才能知道完整模型集,请在 `discovery` 中将该 provider 声明为 `refreshable` 或 `runtime`。
|
||||
不要在 `modelCatalog` 中放入仅运行时可用的数据。如果某个 provider 需要账户状态、API 请求或本地进程发现才能知道完整模型集合,请在 `discovery` 中将该 provider 声明为 `refreshable` 或 `runtime`。
|
||||
|
||||
## `modelPricing` 参考
|
||||
|
||||
当 provider 在运行时加载前需要 control-plane 定价行为时,请使用 `modelPricing`。Gateway 网关定价缓存会读取这些元数据,而无需导入 provider 运行时代码。
|
||||
当某个 provider 在运行时加载前需要 control-plane 定价行为时,请使用 `modelPricing`。Gateway 网关定价缓存会在不导入 provider 运行时代码的情况下读取这些元数据。
|
||||
|
||||
```json
|
||||
{
|
||||
@ -666,85 +665,86 @@ provider 字段:
|
||||
|
||||
| 字段 | 类型 | 含义 |
|
||||
| ------------ | ----------------- | -------------------------------------------------------------------------------------------------- |
|
||||
| `external` | `boolean` | 对于绝不应获取 OpenRouter 或 LiteLLM 定价的本地 / 自托管 provider,将其设为 `false`。 |
|
||||
| `openRouter` | `false \| object` | OpenRouter 定价查询映射。`false` 会禁用该 provider 的 OpenRouter 查询。 |
|
||||
| `liteLLM` | `false \| object` | LiteLLM 定价查询映射。`false` 会禁用该 provider 的 LiteLLM 查询。 |
|
||||
| `external` | `boolean` | 对于本地/自托管 provider,请设为 `false`,表示永远不应拉取 OpenRouter 或 LiteLLM 定价。 |
|
||||
| `openRouter` | `false \| object` | OpenRouter 定价查找映射。`false` 表示为该 provider 禁用 OpenRouter 查找。 |
|
||||
| `liteLLM` | `false \| object` | LiteLLM 定价查找映射。`false` 表示为该 provider 禁用 LiteLLM 查找。 |
|
||||
|
||||
来源字段:
|
||||
源字段:
|
||||
|
||||
| 字段 | 类型 | 含义 |
|
||||
| -------------------------- | ------------------ | -------------------------------------------------------------------------------------------------------------------- |
|
||||
| `provider` | `string` | 当外部 catalog provider id 与 OpenClaw provider id 不同时使用的外部 catalog provider id,例如 `zai` provider 对应的 `z-ai`。 |
|
||||
| `passthroughProviderModel` | `boolean` | 将包含斜杠的模型 id 视为嵌套的 provider/model 引用,这对 OpenRouter 之类的代理 provider 很有用。 |
|
||||
| `modelIdTransforms` | `"version-dots"[]` | 额外的外部 catalog 模型 id 变体。`version-dots` 会尝试带点的版本 id,例如 `claude-opus-4.6`。 |
|
||||
| `provider` | `string` | 当外部目录 provider id 与 OpenClaw provider id 不同时使用,例如对 `zai` provider 使用 `z-ai`。 |
|
||||
| `passthroughProviderModel` | `boolean` | 将包含斜杠的模型 id 视为嵌套的 provider/model 引用,这对 OpenRouter 之类的代理 provider 很有用。 |
|
||||
| `modelIdTransforms` | `"version-dots"[]` | 额外的外部目录模型 id 变体。`version-dots` 会尝试诸如 `claude-opus-4.6` 这类带点号的版本 id。 |
|
||||
|
||||
### OpenClaw Provider Index
|
||||
|
||||
OpenClaw Provider Index 是由 OpenClaw 拥有的预览元数据,用于那些插件可能尚未安装的 provider。它不是插件清单的一部分。插件清单仍然是已安装插件的权威来源。Provider Index 是内部回退契约,未来可安装 provider 和安装前模型选择器界面会在 provider 插件尚未安装时使用它。
|
||||
OpenClaw Provider Index 是由 OpenClaw 拥有的预览元数据,适用于其插件可能尚未安装的 provider。它不是插件清单的一部分。插件清单仍然是已安装插件的权威来源。Provider Index 是未来可安装 provider 和安装前模型选择界面在 provider 插件尚未安装时会使用的内部回退合约。
|
||||
|
||||
catalog 权威顺序:
|
||||
目录权威顺序:
|
||||
|
||||
1. 用户配置。
|
||||
2. 已安装插件清单 `modelCatalog`。
|
||||
3. 来自显式刷新的模型 catalog 缓存。
|
||||
2. 已安装插件清单中的 `modelCatalog`。
|
||||
3. 来自显式刷新的模型目录缓存。
|
||||
4. OpenClaw Provider Index 预览行。
|
||||
|
||||
Provider Index 不得包含密钥、启用状态、运行时 hooks 或实时的账户专属模型数据。它的预览 catalog 使用与插件清单相同的 `modelCatalog` provider 行结构,但除非诸如 `api`、`baseUrl`、定价或兼容性标志等运行时适配器字段有意与已安装插件清单保持一致,否则应限制为稳定的显示元数据。具有实时 `/models` 发现能力的 provider 应通过显式模型 catalog 缓存路径写入刷新后的行,而不是在普通列表或 onboarding 过程中调用 provider API。
|
||||
Provider Index 绝不能包含密钥、启用状态、运行时钩子或与账户相关的实时模型数据。它的预览目录使用与插件清单相同的 `modelCatalog` provider 行结构,但应限制为稳定的显示元数据,除非刻意让 `api`、`baseUrl`、定价或兼容性标志等运行时适配器字段与已安装插件清单保持一致。对于具有实时 `/models` 发现的 provider,应通过显式模型目录缓存路径写入刷新后的行,而不是在普通列表或新手引导过程中调用 provider API。
|
||||
|
||||
Provider Index 条目还可以携带适用于那些插件已移出核心或尚未安装的 provider 的可安装插件元数据。这些元数据遵循渠道 catalog 模式:包名、npm 安装 spec、预期完整性以及轻量级凭证选项标签,已足以显示一个可安装的设置选项。一旦插件安装完成,其清单即成为权威,该 provider 的 Provider Index 条目将被忽略。
|
||||
Provider Index 条目也可以为那些插件已移出核心或尚未安装的 provider 携带可安装插件元数据。这些元数据遵循与渠道目录相同的模式:包名、npm 安装规范、预期完整性,以及轻量认证选项标签,足以显示一个可安装的设置选项。一旦插件安装完成,其清单将优先,此 provider 的 Provider Index 条目会被忽略。
|
||||
|
||||
旧版顶层能力键已弃用。请使用 `openclaw doctor --fix` 将 `speechProviders`、`realtimeTranscriptionProviders`、`realtimeVoiceProviders`、`mediaUnderstandingProviders`、`imageGenerationProviders`、`videoGenerationProviders`、`webFetchProviders` 和 `webSearchProviders` 移动到 `contracts` 下;常规清单加载不再将这些顶层字段视为能力归属。
|
||||
|
||||
## 清单与 `package.json`
|
||||
## 清单与 `package.json` 的区别
|
||||
|
||||
这两个文件承担不同职责:
|
||||
|
||||
| 文件 | 用途 |
|
||||
| ---------------------- | -------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `openclaw.plugin.json` | 在插件代码运行前必须存在的设备发现、配置验证、凭证选项元数据和 UI 提示 |
|
||||
| `package.json` | npm 元数据、依赖安装,以及用于入口点、安装门控、设置或 catalog 元数据的 `openclaw` 块 |
|
||||
| `openclaw.plugin.json` | 设备发现、配置校验、认证选项元数据,以及必须在插件代码运行前就存在的 UI 提示 |
|
||||
| `package.json` | npm 元数据、依赖安装,以及用于入口点、安装门控、设置或目录元数据的 `openclaw` 区块 |
|
||||
|
||||
如果你不确定某项元数据应放在哪里,请使用以下规则:
|
||||
如果你不确定某段元数据应放在哪里,请使用这条规则:
|
||||
|
||||
- 如果 OpenClaw 必须在加载插件代码之前知道它,就放到 `openclaw.plugin.json`
|
||||
- 如果它与打包、入口文件或 npm 安装行为有关,就放到 `package.json`
|
||||
|
||||
### 影响设备发现的 `package.json` 字段
|
||||
### 会影响设备发现的 `package.json` 字段
|
||||
|
||||
某些运行时前插件元数据有意放在 `package.json` 的 `openclaw` 块下,而不是 `openclaw.plugin.json` 中。
|
||||
某些运行时前插件元数据有意放在 `package.json` 的 `openclaw` 区块下,而不是 `openclaw.plugin.json` 中。
|
||||
|
||||
重要示例:
|
||||
|
||||
| 字段 | 含义 |
|
||||
| ----------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
||||
| `openclaw.extensions` | 声明原生插件入口点。必须保留在插件包目录内。 |
|
||||
| `openclaw.runtimeExtensions` | 为已安装包声明已构建的 JavaScript 运行时入口点。必须保留在插件包目录内。 |
|
||||
| `openclaw.setupEntry` | 在 onboarding、延迟渠道启动以及只读渠道 Status / SecretRef 发现期间使用的轻量级仅设置入口点。必须保留在插件包目录内。 |
|
||||
| `openclaw.runtimeSetupEntry` | 声明已安装包的已构建 JavaScript 设置入口点。必须保留在插件包目录内。 |
|
||||
| `openclaw.channel` | 轻量级渠道 catalog 元数据,例如标签、文档路径、别名和选择文案。 |
|
||||
| `openclaw.channel.commands` | 在渠道运行时加载前供配置、审计和命令列表界面使用的静态原生命令和原生 Skills 自动默认元数据。 |
|
||||
| `openclaw.channel.configuredState` | 轻量级已配置状态检查器元数据,可在不加载完整渠道运行时的情况下回答“是否已存在仅环境变量设置?”。 |
|
||||
| `openclaw.channel.persistedAuthState` | 轻量级持久化凭证状态检查器元数据,可在不加载完整渠道运行时的情况下回答“是否已经有任何登录状态?”。 |
|
||||
| `openclaw.install.npmSpec` / `openclaw.install.localPath` | 内置和外部发布插件的安装 / 更新提示。 |
|
||||
| `openclaw.install.defaultChoice` | 当存在多个安装来源时的首选安装路径。 |
|
||||
| `openclaw.install.minHostVersion` | 最低支持的 OpenClaw 主机版本,使用如 `>=2026.3.22` 这样的 semver 下限。 |
|
||||
| `openclaw.install.expectedIntegrity` | 预期的 npm 分发完整性字符串,例如 `sha512-...`;安装和更新流程会用它验证获取到的工件。 |
|
||||
| `openclaw.install.allowInvalidConfigRecovery` | 当配置无效时,允许一个范围很窄的内置插件重装恢复路径。 |
|
||||
| `openclaw.startup.deferConfiguredChannelFullLoadUntilAfterListen` | 允许在启动期间,完整渠道插件之前先加载仅设置的渠道界面。 |
|
||||
| `openclaw.extensions` | 声明原生插件入口点。必须保持在插件包目录内。 |
|
||||
| `openclaw.runtimeExtensions` | 为已安装包声明已构建的 JavaScript 运行时入口点。必须保持在插件包目录内。 |
|
||||
| `openclaw.setupEntry` | 在新手引导、延迟渠道启动和只读渠道 Status / SecretRef 发现期间使用的轻量级仅设置入口点。必须保持在插件包目录内。 |
|
||||
| `openclaw.runtimeSetupEntry` | 为已安装包声明已构建的 JavaScript 设置入口点。必须保持在插件包目录内。 |
|
||||
| `openclaw.channel` | 轻量渠道目录元数据,例如标签、文档路径、别名和选择说明文案。 |
|
||||
| `openclaw.channel.commands` | 在渠道运行时加载前,由配置、审计和命令列表界面使用的静态原生命令和原生 Skills 自动默认元数据。 |
|
||||
| `openclaw.channel.configuredState` | 轻量已配置状态检查器元数据,可在不加载完整渠道运行时的情况下回答“是否已经存在仅基于环境变量的设置?”。 |
|
||||
| `openclaw.channel.persistedAuthState` | 轻量持久化认证状态检查器元数据,可在不加载完整渠道运行时的情况下回答“是否已经有任何内容处于已登录状态?”。 |
|
||||
| `openclaw.install.npmSpec` / `openclaw.install.localPath` | 用于内置和外部发布插件的安装/更新提示。 |
|
||||
| `openclaw.install.defaultChoice` | 当有多个安装来源可用时的首选安装路径。 |
|
||||
| `openclaw.install.minHostVersion` | 最低支持的 OpenClaw 主机版本,使用类似 `>=2026.3.22` 的 semver 下限。 |
|
||||
| `openclaw.install.expectedIntegrity` | 预期的 npm 分发完整性字符串,例如 `sha512-...`;安装和更新流程会据此校验拉取到的构件。 |
|
||||
| `openclaw.install.allowInvalidConfigRecovery` | 当配置无效时,允许一个范围受限的内置插件重新安装恢复路径。 |
|
||||
| `openclaw.startup.deferConfiguredChannelFullLoadUntilAfterListen` | 允许仅设置的渠道界面在启动期间先于完整渠道插件加载。 |
|
||||
|
||||
清单元数据决定了在运行时加载前,哪些 provider / 渠道 / 设置选项会出现在 onboarding 中。`package.json#openclaw.install` 则告诉 onboarding,当用户选择这些选项之一时,如何获取或启用该插件。不要将安装提示移到 `openclaw.plugin.json` 中。
|
||||
清单元数据决定了在运行时加载前,新手引导中会显示哪些 provider / 渠道 / 设置选项。`package.json#openclaw.install` 则告诉新手引导,当用户选择这些选项之一时,应如何获取或启用该插件。不要将安装提示移入 `openclaw.plugin.json`。
|
||||
|
||||
`openclaw.install.minHostVersion` 会在安装期间和清单注册表加载期间强制执行。无效值会被拒绝;在较旧主机上,较新但有效的值会跳过该插件。
|
||||
`openclaw.install.minHostVersion` 会在安装和清单注册表加载期间强制执行。无效值会被拒绝;在较旧主机上,更新但有效的值会跳过该插件。
|
||||
|
||||
精确的 npm 版本固定已存在于 `npmSpec` 中,例如 `"npmSpec": "@wecom/wecom-openclaw-plugin@1.2.3"`。官方外部 catalog 条目应将精确 spec 与 `expectedIntegrity` 搭配使用,以便当获取的 npm 工件不再匹配固定版本时,更新流程以封闭失败方式终止。出于兼容性考虑,交互式 onboarding 仍会提供受信任注册表的 npm spec,包括裸包名和 dist-tag。catalog 诊断可以区分精确、浮动、完整性固定、缺少完整性、包名不匹配以及无效默认选项来源。它们还会在存在 `expectedIntegrity` 但没有可供固定的有效 npm 来源时发出警告。当存在 `expectedIntegrity` 时,安装 / 更新流程会强制执行它;省略时,将记录注册表解析结果,但不会附带完整性固定。
|
||||
精确 npm 版本锁定已经存在于 `npmSpec` 中,例如
|
||||
`"npmSpec": "@wecom/wecom-openclaw-plugin@1.2.3"`。官方外部目录条目应将精确规范与 `expectedIntegrity` 配对,以便当拉取到的 npm 构件不再匹配已锁定版本时,更新流程以失败关闭的方式中止。出于兼容性考虑,交互式新手引导仍会提供受信任注册表中的 npm 规范,包括裸包名和 dist-tag。目录诊断可以区分精确源、浮动源、带完整性锁定的源、缺少完整性的源、包名不匹配的源以及无效的默认选项来源。它们还会在存在 `expectedIntegrity` 但没有可用于锁定的有效 npm 来源时发出警告。当存在 `expectedIntegrity` 时,安装/更新流程会强制执行它;当省略时,会记录注册表解析结果,但不会附带完整性锁定。
|
||||
|
||||
当 Status、渠道列表或 SecretRef 扫描需要在不加载完整运行时的情况下识别已配置账户时,渠道插件应提供 `openclaw.setupEntry`。该设置入口应公开渠道元数据,以及适用于设置场景的配置、状态和密钥适配器;请将网络客户端、gateway 监听器和传输运行时保留在主扩展入口点中。
|
||||
当 Status、渠道列表或 SecretRef 扫描需要在不加载完整运行时的情况下识别已配置账户时,渠道插件应提供 `openclaw.setupEntry`。该设置入口应暴露渠道元数据以及设置安全的配置、Status 和密钥适配器;请将网络客户端、网关监听器和传输运行时保留在主扩展入口点中。
|
||||
|
||||
运行时入口点字段不会覆盖源入口点字段的包边界检查。例如,`openclaw.runtimeExtensions` 不能让一个越界的 `openclaw.extensions` 路径变得可加载。
|
||||
运行时入口点字段不会覆盖源码入口点字段的包边界检查。例如,`openclaw.runtimeExtensions` 不能让一个越界的 `openclaw.extensions` 路径变得可加载。
|
||||
|
||||
`openclaw.install.allowInvalidConfigRecovery` 被有意限制在很窄的范围内。它不会让任意损坏的配置变得可安装。当前它只允许安装流程从特定的旧内置插件升级故障中恢复,例如缺失的内置插件路径,或同一个内置插件对应的过期 `channels.<id>` 条目。无关的配置错误仍会阻止安装,并引导运维人员使用 `openclaw doctor --fix`。
|
||||
`openclaw.install.allowInvalidConfigRecovery` 的设计范围是刻意受限的。它不会让任意损坏的配置变得可安装。当前它仅允许安装流程从特定的过时内置插件升级故障中恢复,例如缺失的内置插件路径,或该同一内置插件对应的过时 `channels.<id>` 条目。无关的配置错误仍会阻止安装,并将操作人员引导到 `openclaw doctor --fix`。
|
||||
|
||||
`openclaw.channel.persistedAuthState` 是用于一个极小检查器模块的包元数据:
|
||||
`openclaw.channel.persistedAuthState` 是一个微型检查器模块的包元数据:
|
||||
|
||||
```json
|
||||
{
|
||||
@ -760,9 +760,9 @@ Provider Index 条目还可以携带适用于那些插件已移出核心或尚
|
||||
}
|
||||
```
|
||||
|
||||
当设置、Doctor 或已配置状态流程需要在完整渠道插件加载前进行一个廉价的“是 / 否”凭证探测时,请使用它。目标导出应是一个只读取持久化状态的小函数;不要通过完整渠道运行时 barrel 暴露它。
|
||||
当设置、Doctor 或已配置状态流程需要在完整渠道插件加载前进行一个低成本的是/否认证探测时,请使用它。目标导出应是一个只读取持久化状态的小函数;不要通过完整渠道运行时 barrel 暴露它。
|
||||
|
||||
`openclaw.channel.configuredState` 对于廉价的仅环境变量已配置检查采用相同结构:
|
||||
`openclaw.channel.configuredState` 对应同样的结构,用于低成本的仅环境变量已配置检查:
|
||||
|
||||
```json
|
||||
{
|
||||
@ -778,51 +778,50 @@ Provider Index 条目还可以携带适用于那些插件已移出核心或尚
|
||||
}
|
||||
```
|
||||
|
||||
当渠道可以仅凭环境变量或其他极小的非运行时输入回答已配置状态时,请使用它。如果检查需要完整配置解析或真实渠道运行时,请将该逻辑保留在插件 `config.hasConfiguredState` hook 中。
|
||||
当一个渠道能够基于环境变量或其他极小型的非运行时输入来判断已配置状态时,请使用它。如果检查需要完整配置解析或真实渠道运行时,请改为将该逻辑保留在插件 `config.hasConfiguredState` hook 中。
|
||||
|
||||
## 设备发现优先级(重复插件 id)
|
||||
|
||||
OpenClaw 会从多个根位置发现插件(内置、全局安装、工作区、显式配置选择的路径)。如果两个发现结果共享同一个 `id`,则只保留**优先级最高**的清单;较低优先级的重复项会被丢弃,而不是与其一起加载。
|
||||
OpenClaw 会从多个根路径发现插件(内置、全局安装、工作区、配置中显式选择的路径)。如果两个发现结果共享相同的 `id`,则只保留 **优先级最高** 的那个清单;较低优先级的重复项会被丢弃,而不是与之并排加载。
|
||||
|
||||
优先级从高到低:
|
||||
|
||||
1. **配置选定** —— 在 `plugins.entries.<id>` 中显式固定的路径
|
||||
2. **内置** —— 随 OpenClaw 一起发布的插件
|
||||
3. **全局安装** —— 安装到全局 OpenClaw 插件根目录中的插件
|
||||
4. **工作区** —— 相对于当前工作区发现的插件
|
||||
1. **配置中选定** — 在 `plugins.entries.<id>` 中显式固定的路径
|
||||
2. **内置** — 随 OpenClaw 一起发布的插件
|
||||
3. **全局安装** — 安装到全局 OpenClaw 插件根目录中的插件
|
||||
4. **工作区** — 相对于当前工作区发现的插件
|
||||
|
||||
影响:
|
||||
|
||||
- 放在工作区中的某个内置插件分支或旧副本,不会覆盖内置构建。
|
||||
- 若要真正用本地插件覆盖内置插件,请通过 `plugins.entries.<id>` 固定它,使其凭借优先级获胜,而不是依赖工作区发现。
|
||||
- 被丢弃的重复项会被记录日志,这样 Doctor 和启动诊断就可以指向被舍弃的副本。
|
||||
- 工作区中存在的某个内置插件分叉版本或过时副本,不会遮蔽内置构建版本。
|
||||
- 若要真正用本地插件覆盖内置插件,请通过 `plugins.entries.<id>` 固定它,使其凭借优先级获胜,而不要依赖工作区发现。
|
||||
- 被丢弃的重复项会记录到日志中,以便 Doctor 和启动诊断可以指出被舍弃的副本。
|
||||
|
||||
## JSON Schema 要求
|
||||
|
||||
- **每个插件都必须提供一个 JSON Schema**,即使它不接受任何配置。
|
||||
- 可以接受空 schema(例如 `{ "type": "object", "additionalProperties": false }`)。
|
||||
- schema 会在配置读写时验证,而不是在运行时验证。
|
||||
- **每个插件都必须提供一个 JSON Schema**,即使它不接受任何配置也是如此。
|
||||
- 可以接受空模式(例如 `{ "type": "object", "additionalProperties": false }`)。
|
||||
- 模式会在配置读取/写入时校验,而不是在运行时校验。
|
||||
|
||||
## 验证行为
|
||||
## 校验行为
|
||||
|
||||
- 未知的 `channels.*` 键是**错误**,除非该渠道 id 由某个插件清单声明。
|
||||
- `plugins.entries.<id>`、`plugins.allow`、`plugins.deny` 和 `plugins.slots.*`
|
||||
必须引用**可发现的**插件 id。未知 id 属于**错误**。
|
||||
- 如果某个插件已安装,但其清单或 schema 损坏或缺失,验证会失败,Doctor 会报告该插件错误。
|
||||
- 如果插件配置存在,但插件被**禁用**,配置会被保留,并且 Doctor + 日志中会显示一条**警告**。
|
||||
- 未知的 `channels.*` 键是 **错误**,除非该渠道 id 由某个插件清单声明。
|
||||
- `plugins.entries.<id>`、`plugins.allow`、`plugins.deny` 和 `plugins.slots.*` 必须引用 **可发现的** 插件 id。未知 id 属于 **错误**。
|
||||
- 如果某个插件已安装,但其清单或模式损坏或缺失,校验会失败,Doctor 会报告该插件错误。
|
||||
- 如果插件配置存在,但插件处于 **禁用** 状态,则配置会被保留,并且 Doctor + 日志中会显示 **警告**。
|
||||
|
||||
完整的 `plugins.*` schema 请参阅[配置参考](/zh-CN/gateway/configuration)。
|
||||
有关完整的 `plugins.*` 模式,请参阅 [配置参考](/zh-CN/gateway/configuration)。
|
||||
|
||||
## 说明
|
||||
|
||||
- 清单对**原生 OpenClaw 插件**是**必需的**,包括本地文件系统加载。运行时仍会单独加载插件模块;清单仅用于设备发现 + 验证。
|
||||
- 原生清单使用 JSON5 解析,因此接受注释、尾随逗号和未加引号的键,只要最终值仍然是一个对象即可。
|
||||
- 清单加载器只会读取文档中记录的清单字段。请避免使用自定义顶层键。
|
||||
- 当插件不需要它们时,`channels`、`providers`、`cliBackends` 和 `skills` 都可以省略。
|
||||
- `providerDiscoveryEntry` 必须保持轻量,不应导入大范围运行时代码;请将其用于静态 provider catalog 元数据或狭义发现描述符,而不是请求时执行。
|
||||
- 排他性插件种类通过 `plugins.slots.*` 选择:`kind: "memory"` 通过 `plugins.slots.memory`,`kind: "context-engine"` 通过 `plugins.slots.contextEngine`(默认 `legacy`)。
|
||||
- 环境变量元数据(`setup.providers[].envVars`、已弃用的 `providerAuthEnvVars` 和 `channelEnvVars`)仅具声明性。Status、审计、cron 投递验证和其他只读界面在将环境变量视为已配置之前,仍会应用插件信任和有效激活策略。
|
||||
- 关于需要 provider 代码的运行时向导元数据,请参阅[provider 运行时钩子](/zh-CN/plugins/architecture-internals#provider-runtime-hooks)。
|
||||
- 清单对于 **原生 OpenClaw 插件** 是 **必需的**,包括本地文件系统加载。运行时仍会单独加载插件模块;清单仅用于设备发现 + 校验。
|
||||
- 原生清单使用 JSON5 解析,因此支持注释、尾随逗号和未加引号的键,只要最终值仍然是一个对象即可。
|
||||
- 清单加载器只会读取文档中说明的清单字段。避免使用自定义顶层键。
|
||||
- 当插件不需要时,可以省略 `channels`、`providers`、`cliBackends` 和 `skills`。
|
||||
- `providerDiscoveryEntry` 必须保持轻量,不应导入宽泛的运行时代码;应将其用于静态 provider 目录元数据或窄范围发现描述符,而不是请求时执行。
|
||||
- 排他性插件类型通过 `plugins.slots.*` 选择:`kind: "memory"` 对应 `plugins.slots.memory`,`kind: "context-engine"` 对应 `plugins.slots.contextEngine`(默认值为 `legacy`)。
|
||||
- 环境变量元数据(`setup.providers[].envVars`、已弃用的 `providerAuthEnvVars` 以及 `channelEnvVars`)仅具声明性。Status、审计、cron 投递校验以及其他只读界面,在将某个环境变量视为已配置之前,仍会应用插件信任和有效激活策略。
|
||||
- 如需依赖 provider 代码的运行时向导元数据,请参阅 [Provider 运行时钩子](/zh-CN/plugins/architecture-internals#provider-runtime-hooks)。
|
||||
- 如果你的插件依赖原生模块,请记录构建步骤以及任何包管理器允许列表要求(例如 pnpm `allow-build-scripts` + `pnpm rebuild <package>`)。
|
||||
|
||||
## 相关内容
|
||||
|
||||
@ -1,42 +1,39 @@
|
||||
---
|
||||
read_when:
|
||||
- 添加由智能体控制的浏览器自动化
|
||||
- 排查 openclaw 为什么会干扰你自己的 Chrome
|
||||
- 在 macOS 应用中实现浏览器设置和生命周期
|
||||
summary: 集成式浏览器控制服务 + 操作命令
|
||||
title: 浏览器(由 OpenClaw 管理)
|
||||
- 调试为什么 openclaw 会干扰你自己的 Chrome
|
||||
- 在 macOS 应用中实现浏览器设置 + 生命周期
|
||||
summary: 集成的浏览器控制服务 + 操作命令
|
||||
title: 浏览器(OpenClaw 管理)
|
||||
x-i18n:
|
||||
generated_at: "2026-04-27T07:13:25Z"
|
||||
generated_at: "2026-04-27T08:44:47Z"
|
||||
model: gpt-5.4
|
||||
provider: openai
|
||||
source_hash: 0e576b013e49917b6d5b118c22d7b91a65e1f1997dc86eb51881ed30806dafe9
|
||||
source_hash: 65397ea2405aeb34d4e08c8968f3dc15ab8ed446c69d77274f069fc72f90c59a
|
||||
source_path: tools/browser.md
|
||||
workflow: 15
|
||||
---
|
||||
|
||||
OpenClaw 可以运行一个由**专用 Chrome/Brave/Edge/Chromium 配置文件**组成的环境,并由智能体控制。
|
||||
它与你的个人浏览器隔离,并通过 Gateway 网关内部的一个小型本地
|
||||
控制服务进行管理(仅限 loopback)。
|
||||
OpenClaw 可以运行一个**专用的 Chrome/Brave/Edge/Chromium 配置文件**,由智能体控制。
|
||||
它与你的个人浏览器隔离,并通过 Gateway 网关内部的一个小型本地控制服务进行管理(仅 loopback)。
|
||||
|
||||
新手视角:
|
||||
|
||||
- 可以把它理解为一个**单独的、仅供智能体使用的浏览器**。
|
||||
- 把它看作一个**独立的、仅供智能体使用的浏览器**。
|
||||
- `openclaw` 配置文件**不会**触碰你的个人浏览器配置文件。
|
||||
- 智能体可以在一条安全通道中**打开标签页、读取页面、点击和输入**。
|
||||
- 内置的 `user` 配置文件会通过 Chrome MCP 连接到你真实、已登录的 Chrome 会话。
|
||||
- 内置的 `user` 配置文件会通过 Chrome MCP 附加到你真实的已登录 Chrome 会话。
|
||||
|
||||
## 你将获得什么
|
||||
## 你会获得什么
|
||||
|
||||
- 一个名为 **openclaw** 的独立浏览器配置文件(默认使用橙色强调色)。
|
||||
- 可预测的标签页控制(列出/打开/聚焦/关闭)。
|
||||
- 智能体操作(点击/输入/拖动/选择)、快照、截图、PDF。
|
||||
- 一个内置的 `browser-automation` Skills,当浏览器
|
||||
插件启用时,它会教智能体使用 snapshot、
|
||||
stable-tab、stale-ref 和 manual-blocker 恢复循环。
|
||||
- 可选的多配置文件支持(`openclaw`、`work`、`remote` 等)。
|
||||
- 智能体操作(点击/输入/拖拽/选择)、快照、截图、PDF。
|
||||
- 一个内置的 `browser-automation` Skills,用于在启用浏览器插件时,教会智能体使用 snapshot、stable-tab、stale-ref 和 manual-blocker 恢复循环。
|
||||
- 可选的多配置文件支持(`openclaw`、`work`、`remote`,等等)。
|
||||
|
||||
这个浏览器**不是**你的日常主力浏览器。它是一个安全、隔离的表面,用于
|
||||
智能体自动化和验证。
|
||||
这个浏览器**不是**你日常使用的主力浏览器。
|
||||
它是一个安全、隔离的表面,用于智能体自动化和验证。
|
||||
|
||||
## 快速开始
|
||||
|
||||
@ -49,15 +46,13 @@ openclaw browser --browser-profile openclaw open https://example.com
|
||||
openclaw browser --browser-profile openclaw snapshot
|
||||
```
|
||||
|
||||
如果你看到“Browser disabled”,请在配置中启用它(见下文),然后重启
|
||||
Gateway 网关。
|
||||
如果你看到“Browser disabled”,请在配置中启用它(见下文),然后重启 Gateway 网关。
|
||||
|
||||
如果根本没有 `openclaw browser`,或者智能体提示浏览器工具
|
||||
不可用,请跳转到 [缺少浏览器命令或工具](/zh-CN/tools/browser#missing-browser-command-or-tool)。
|
||||
如果 `openclaw browser` 完全不存在,或者智能体提示浏览器工具不可用,请跳转到[缺少浏览器命令或工具](/zh-CN/tools/browser#missing-browser-command-or-tool)。
|
||||
|
||||
## 插件控制
|
||||
|
||||
默认的 `browser` 工具是一个内置插件。禁用它即可用另一个注册相同 `browser` 工具名称的插件来替换它:
|
||||
默认的 `browser` 工具是一个内置插件。禁用它即可用另一个注册相同 `browser` 工具名称的插件替换它:
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -71,16 +66,13 @@ Gateway 网关。
|
||||
}
|
||||
```
|
||||
|
||||
默认设置需要同时启用 `plugins.entries.browser.enabled` **和** `browser.enabled=true`。如果只禁用插件,会一次性移除 `openclaw browser` CLI、`browser.request` Gateway 网关方法、智能体工具和控制服务;你的 `browser.*` 配置会保持不变,以供替代方案使用。
|
||||
默认值需要同时设置 `plugins.entries.browser.enabled` **以及** `browser.enabled=true`。如果只禁用插件,就会一次性移除 `openclaw browser` CLI、`browser.request` Gateway 网关方法、智能体工具和控制服务;你的 `browser.*` 配置会保持不变,以供替代方案使用。
|
||||
|
||||
浏览器配置变更需要重启 Gateway 网关,这样插件才能重新注册其服务。
|
||||
浏览器配置更改需要重启 Gateway 网关,以便插件重新注册其服务。
|
||||
|
||||
## 智能体指引
|
||||
|
||||
工具配置说明:`tools.profile: "coding"` 包含 `web_search` 和
|
||||
`web_fetch`,但不包含完整的 `browser` 工具。如果智能体或某个
|
||||
派生的子智能体需要使用浏览器自动化,请在 profile
|
||||
阶段添加 browser:
|
||||
工具配置文件说明:`tools.profile: "coding"` 包含 `web_search` 和 `web_fetch`,但不包含完整的 `browser` 工具。如果智能体或生成的子智能体需要使用浏览器自动化,请在配置文件阶段添加 browser:
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -91,26 +83,19 @@ Gateway 网关。
|
||||
}
|
||||
```
|
||||
|
||||
对于单个智能体,请使用 `agents.list[].tools.alsoAllow: ["browser"]`。
|
||||
仅设置 `tools.subagents.tools.allow: ["browser"]` 还不够,因为子智能体
|
||||
策略会在 profile 过滤之后才应用。
|
||||
对于单个智能体,使用 `agents.list[].tools.alsoAllow: ["browser"]`。
|
||||
仅设置 `tools.subagents.tools.allow: ["browser"]` 还不够,因为子智能体策略会在配置文件过滤之后应用。
|
||||
|
||||
浏览器插件提供两层智能体指引:
|
||||
浏览器插件提供两个层级的智能体指引:
|
||||
|
||||
- `browser` 工具描述携带始终启用的精简契约:选择
|
||||
正确的配置文件,在同一标签页上保留引用,使用 `tabId`/标签进行标签页
|
||||
定位,并在多步骤工作时加载浏览器 skill。
|
||||
- 内置的 `browser-automation` skill 携带更长的操作循环:
|
||||
先检查状态/标签页,给任务标签页加标签,操作前先做快照,在 UI 变化后重新快照,
|
||||
过期引用恢复一次,并将登录/2FA/captcha 或
|
||||
摄像头/麦克风阻塞报告为需要人工操作,而不是猜测。
|
||||
- `browser` 工具说明携带精简且始终启用的契约:选择正确的配置文件,在同一标签页中保持 refs,使用 `tabId`/标签来定位标签页,并在多步骤任务中加载浏览器 Skills。
|
||||
- 内置的 `browser-automation` Skills 携带更长的操作循环:先检查状态/标签页,为任务标签页打标签,操作前先做快照,UI 变化后重新快照,过期引用恢复一次,并将登录/2FA/captcha 或摄像头/麦克风阻塞报告为需要手动操作,而不是猜测处理。
|
||||
|
||||
当插件启用时,由插件内置的 Skills 会列在智能体的可用 Skills 中。
|
||||
完整的 skill 说明按需加载,因此日常轮次不会承担全部 token 成本。
|
||||
启用插件后,插件内置 Skills 会列在智能体可用 Skills 中。完整的 Skills 指令按需加载,因此日常轮次不会承担完整的 token 成本。
|
||||
|
||||
## 缺少浏览器命令或工具
|
||||
|
||||
如果升级后 `openclaw browser` 未知,`browser.request` 缺失,或者智能体报告浏览器工具不可用,通常原因是 `plugins.allow` 列表中未包含 `browser`。请添加它:
|
||||
如果升级后 `openclaw browser` 无法识别、`browser.request` 缺失,或者智能体报告浏览器工具不可用,通常原因是 `plugins.allow` 列表中遗漏了 `browser`,并且不存在根级 `browser` 配置块。请添加它:
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -120,20 +105,18 @@ Gateway 网关。
|
||||
}
|
||||
```
|
||||
|
||||
`browser.enabled=true`、`plugins.entries.browser.enabled=true` 和 `tools.alsoAllow: ["browser"]` 不能替代允许列表成员资格——允许列表控制插件加载,而工具策略只会在加载后运行。完全移除 `plugins.allow` 也会恢复默认行为。
|
||||
显式的根级 `browser` 块,例如 `browser.enabled=true` 或 `browser.profiles.<name>`,即使在严格的 `plugins.allow` 下,也会激活内置浏览器插件,这与渠道配置行为一致。仅设置 `plugins.entries.browser.enabled=true` 和 `tools.alsoAllow: ["browser"]` 本身不能替代 allowlist 成员资格。完全移除 `plugins.allow` 也会恢复默认行为。
|
||||
|
||||
## 配置文件:`openclaw` 与 `user`
|
||||
|
||||
- `openclaw`:受管、隔离的浏览器(无需扩展)。
|
||||
- `user`:内置的 Chrome MCP 附加配置文件,用于连接你**真实、已登录的 Chrome**
|
||||
会话。
|
||||
- `user`:内置的 Chrome MCP 附加配置文件,用于你的**真实已登录 Chrome** 会话。
|
||||
|
||||
对于智能体浏览器工具调用:
|
||||
|
||||
- 默认:使用隔离的 `openclaw` 浏览器。
|
||||
- 当现有登录会话很重要,并且用户
|
||||
正在电脑前可以点击/批准任何附加提示时,优先使用 `profile="user"`。
|
||||
- 当你想指定某种浏览器模式时,`profile` 是显式覆盖项。
|
||||
- 当已有登录会话很重要,并且用户在电脑前可以点击/批准任何附加提示时,优先使用 `profile="user"`。
|
||||
- 当你想指定特定浏览器模式时,`profile` 是显式覆盖项。
|
||||
|
||||
如果你希望默认使用受管模式,请设置 `browser.defaultProfile: "openclaw"`。
|
||||
|
||||
@ -144,23 +127,23 @@ Gateway 网关。
|
||||
```json5
|
||||
{
|
||||
browser: {
|
||||
enabled: true, // 默认:true
|
||||
enabled: true, // default: true
|
||||
ssrfPolicy: {
|
||||
// dangerouslyAllowPrivateNetwork: true, // 仅在信任私有网络访问时启用
|
||||
// allowPrivateNetwork: true, // 旧版别名
|
||||
// dangerouslyAllowPrivateNetwork: true, // opt in only for trusted private-network access
|
||||
// allowPrivateNetwork: true, // legacy alias
|
||||
// hostnameAllowlist: ["*.example.com", "example.com"],
|
||||
// allowedHostnames: ["localhost"],
|
||||
},
|
||||
// cdpUrl: "http://127.0.0.1:18792", // 旧版单配置文件覆盖
|
||||
remoteCdpTimeoutMs: 1500, // 远程 CDP HTTP 超时(毫秒)
|
||||
remoteCdpHandshakeTimeoutMs: 3000, // 远程 CDP WebSocket 握手超时(毫秒)
|
||||
localLaunchTimeoutMs: 15000, // 本地受管 Chrome 发现超时(毫秒)
|
||||
localCdpReadyTimeoutMs: 8000, // 本地受管启动后 CDP 就绪超时(毫秒)
|
||||
actionTimeoutMs: 60000, // 默认浏览器 act 超时(毫秒)
|
||||
// cdpUrl: "http://127.0.0.1:18792", // legacy single-profile override
|
||||
remoteCdpTimeoutMs: 1500, // remote CDP HTTP timeout (ms)
|
||||
remoteCdpHandshakeTimeoutMs: 3000, // remote CDP WebSocket handshake timeout (ms)
|
||||
localLaunchTimeoutMs: 15000, // local managed Chrome discovery timeout (ms)
|
||||
localCdpReadyTimeoutMs: 8000, // local managed post-launch CDP readiness timeout (ms)
|
||||
actionTimeoutMs: 60000, // default browser act timeout (ms)
|
||||
tabCleanup: {
|
||||
enabled: true, // 默认:true
|
||||
idleMinutes: 120, // 设为 0 以禁用空闲清理
|
||||
maxTabsPerSession: 8, // 设为 0 以禁用每会话上限
|
||||
enabled: true, // default: true
|
||||
idleMinutes: 120, // set 0 to disable idle cleanup
|
||||
maxTabsPerSession: 8, // set 0 to disable the per-session cap
|
||||
sweepMinutes: 5,
|
||||
},
|
||||
defaultProfile: "openclaw",
|
||||
@ -196,51 +179,41 @@ Gateway 网关。
|
||||
|
||||
<AccordionGroup>
|
||||
|
||||
<Accordion title="端口和可达性">
|
||||
<Accordion title="端口与可达性">
|
||||
|
||||
- 控制服务绑定到 loopback,端口从 `gateway.port` 派生(默认 `18791` = gateway + 2)。覆盖 `gateway.port` 或 `OPENCLAW_GATEWAY_PORT` 会使同一族中的派生端口一起偏移。
|
||||
- 本地 `openclaw` 配置文件会自动分配 `cdpPort`/`cdpUrl`;只有远程 CDP 才需要设置这些值。未设置时,`cdpUrl` 默认使用受管本地 CDP 端口。
|
||||
- `remoteCdpTimeoutMs` 适用于远程和 `attachOnly` CDP HTTP 可达性
|
||||
检查,以及打开标签页的 HTTP 请求;`remoteCdpHandshakeTimeoutMs` 适用于
|
||||
它们的 CDP WebSocket 握手。
|
||||
- `localLaunchTimeoutMs` 是本地启动的受管 Chrome
|
||||
进程暴露其 CDP HTTP 端点的时间预算。`localCdpReadyTimeoutMs` 是
|
||||
进程被发现后,CDP websocket 就绪的后续时间预算。
|
||||
在 Raspberry Pi、低配 VPS 或较旧硬件上,如 Chromium
|
||||
启动较慢,请提高这些值。数值必须是正整数,且不超过 `120000` 毫秒;无效
|
||||
配置值会被拒绝。
|
||||
- `actionTimeoutMs` 是浏览器 `act` 请求的默认时间预算,当调用方未传递 `timeoutMs` 时使用。客户端传输层会增加一个小的宽限窗口,以便长时间等待可以完成,而不是在 HTTP 边界处超时。
|
||||
- `tabCleanup` 是对主智能体浏览器会话所打开标签页的尽力清理。子智能体、cron 和 ACP 生命周期清理仍会在会话结束时关闭它们显式跟踪的标签页;主会话则会保留活动标签页以供复用,然后在后台关闭空闲或超额的已跟踪标签页。
|
||||
- 控制服务绑定到 loopback 上,其端口根据 `gateway.port` 派生(默认 `18791` = gateway + 2)。覆盖 `gateway.port` 或 `OPENCLAW_GATEWAY_PORT` 会让同一端口族中的派生端口一起变化。
|
||||
- 本地 `openclaw` 配置文件会自动分配 `cdpPort`/`cdpUrl`;仅远程 CDP 需要设置这些项。未设置时,`cdpUrl` 默认使用受管本地 CDP 端口。
|
||||
- `remoteCdpTimeoutMs` 适用于远程和 `attachOnly` CDP HTTP 可达性检查,以及打开标签页的 HTTP 请求;`remoteCdpHandshakeTimeoutMs` 适用于它们的 CDP WebSocket 握手。
|
||||
- `localLaunchTimeoutMs` 是本地启动的受管 Chrome 进程暴露其 CDP HTTP 端点的时间预算。`localCdpReadyTimeoutMs` 是在发现该进程后,为 CDP websocket 就绪预留的后续时间预算。在 Raspberry Pi、低配 VPS 或较旧硬件上,如果 Chromium 启动较慢,请提高这些值。取值必须是正整数,且不超过 `120000` ms;无效的配置值会被拒绝。
|
||||
- `actionTimeoutMs` 是浏览器 `act` 请求的默认时间预算,当调用方未传递 `timeoutMs` 时使用。客户端传输层会增加一个较小的宽限窗口,以便较长等待可以完成,而不是在 HTTP 边界超时。
|
||||
- `tabCleanup` 是针对由主智能体浏览器会话打开的标签页的尽力清理。子智能体、cron 和 ACP 生命周期清理仍会在会话结束时关闭它们明确跟踪的标签页;主会话会保留活动标签页以便复用,然后在后台关闭空闲或超出数量的已跟踪标签页。
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="SSRF 策略">
|
||||
|
||||
- 浏览器导航和打开标签页会在导航前经过 SSRF 防护,并在最终 `http(s)` URL 上尽力再次检查。
|
||||
- 浏览器导航和打开标签页在导航前会受到 SSRF 防护,并会在导航完成后的最终 `http(s)` URL 上进行尽力重新检查。
|
||||
- 在严格 SSRF 模式下,远程 CDP 端点发现和 `/json/version` 探测(`cdpUrl`)也会被检查。
|
||||
- Gateway 网关/提供商的 `HTTP_PROXY`、`HTTPS_PROXY`、`ALL_PROXY` 和 `NO_PROXY` 环境变量不会自动为 OpenClaw 管理的浏览器设置代理。默认情况下,受管 Chrome 直接启动,因此提供商代理设置不会削弱浏览器 SSRF 检查。
|
||||
- 如需为受管浏览器本身设置代理,请通过 `browser.extraArgs` 传入显式的 Chrome 代理标志,例如 `--proxy-server=...` 或 `--proxy-pac-url=...`。除非你有意启用私有网络浏览器访问,否则严格 SSRF 模式会阻止显式浏览器代理路由。
|
||||
- `browser.ssrfPolicy.dangerouslyAllowPrivateNetwork` 默认关闭;仅当你明确信任私有网络浏览器访问时才启用。
|
||||
- `browser.ssrfPolicy.allowPrivateNetwork` 仍作为旧版别名受支持。
|
||||
- Gateway 网关/提供商的 `HTTP_PROXY`、`HTTPS_PROXY`、`ALL_PROXY` 和 `NO_PROXY` 环境变量不会自动代理 OpenClaw 管理的浏览器。默认情况下,受管 Chrome 会直接启动,因此提供商代理设置不会削弱浏览器 SSRF 检查。
|
||||
- 如果要代理受管浏览器本身,请通过 `browser.extraArgs` 传递显式 Chrome 代理标志,例如 `--proxy-server=...` 或 `--proxy-pac-url=...`。除非明确启用了私有网络浏览器访问,否则严格 SSRF 模式会阻止显式浏览器代理路由。
|
||||
- `browser.ssrfPolicy.dangerouslyAllowPrivateNetwork` 默认关闭;只有在你明确可信任私有网络浏览器访问时才启用它。
|
||||
- `browser.ssrfPolicy.allowPrivateNetwork` 仍作为旧别名受到支持。
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="配置文件行为">
|
||||
|
||||
- `attachOnly: true` 表示绝不启动本地浏览器;仅在浏览器已运行时附加。
|
||||
- `headless` 可以全局设置,也可以按本地受管配置文件设置。按配置文件设置的值会覆盖 `browser.headless`,因此一个本地启动的配置文件可以保持 headless,而另一个仍然可见。
|
||||
- `POST /start?headless=true` 和 `openclaw browser start --headless` 会请求对本地受管配置文件进行一次性 headless 启动,而不会改写 `browser.headless` 或配置文件设置。existing-session、attach-only 和远程 CDP 配置文件会拒绝此覆盖,因为 OpenClaw 不会启动这些浏览器进程。
|
||||
- 在没有 `DISPLAY` 或 `WAYLAND_DISPLAY` 的 Linux 主机上,如果环境、配置文件或全局
|
||||
配置都未显式选择有界面模式,则本地受管配置文件会自动默认使用 headless。`openclaw browser status --json`
|
||||
会将 `headlessSource` 报告为 `env`、`profile`、`config`、
|
||||
`request`、`linux-display-fallback` 或 `default`。
|
||||
- `OPENCLAW_BROWSER_HEADLESS=1` 会为当前进程强制本地受管启动使用 headless。`OPENCLAW_BROWSER_HEADLESS=0` 会为普通启动强制使用有界面模式,并在 Linux 主机没有显示服务器时返回可执行的错误;显式的 `start --headless` 请求在该次启动中仍然优先。
|
||||
- `executablePath` 可以全局设置,也可以按本地受管配置文件设置。按配置文件设置的值会覆盖 `browser.executablePath`,因此不同的受管配置文件可以启动不同的 Chromium 系浏览器。这两种形式都接受 `~` 作为你的操作系统主目录。
|
||||
- `color`(顶层和按配置文件)会为浏览器 UI 着色,以便你看到哪个配置文件处于活动状态。
|
||||
- 默认配置文件是 `openclaw`(受管独立模式)。使用 `defaultProfile: "user"` 可选择加入已登录用户浏览器。
|
||||
- 自动检测顺序:如果系统默认浏览器是 Chromium 系,则优先使用它;否则按 Chrome → Brave → Edge → Chromium → Chrome Canary 的顺序检测。
|
||||
- `driver: "existing-session"` 使用 Chrome DevTools MCP,而不是原始 CDP。不要为该 driver 设置 `cdpUrl`。
|
||||
- 当某个 existing-session 配置文件需要附加到非默认的 Chromium 用户配置文件(Brave、Edge 等)时,请设置 `browser.profiles.<name>.userDataDir`。该路径也接受 `~` 作为你的操作系统主目录。
|
||||
- `headless` 可以全局设置,也可以按本地受管配置文件设置。按配置文件设置的值会覆盖 `browser.headless`,因此一个本地启动的配置文件可以保持 headless,而另一个保持可见。
|
||||
- `POST /start?headless=true` 和 `openclaw browser start --headless` 会为本地受管配置文件请求一次性的 headless 启动,而不会改写 `browser.headless` 或配置文件配置。现有会话、仅附加和远程 CDP 配置文件会拒绝该覆盖,因为 OpenClaw 不会启动这些浏览器进程。
|
||||
- 在没有 `DISPLAY` 或 `WAYLAND_DISPLAY` 的 Linux 主机上,如果环境或配置文件/全局配置都没有显式选择有界面模式,本地受管配置文件会自动默认使用 headless。`openclaw browser status --json` 会将 `headlessSource` 报告为 `env`、`profile`、`config`、`request`、`linux-display-fallback` 或 `default`。
|
||||
- `OPENCLAW_BROWSER_HEADLESS=1` 会强制当前进程启动的本地受管浏览器使用 headless。`OPENCLAW_BROWSER_HEADLESS=0` 会强制普通启动使用有界面模式,并在没有显示服务器的 Linux 主机上返回可操作的错误;显式的 `start --headless` 请求仍会在该次启动中优先生效。
|
||||
- `executablePath` 可以全局设置,也可以按本地受管配置文件设置。按配置文件设置的值会覆盖 `browser.executablePath`,因此不同的受管配置文件可以启动不同的基于 Chromium 的浏览器。这两种形式都接受 `~` 作为你的操作系统主目录。
|
||||
- `color`(顶层和按配置文件)会为浏览器 UI 着色,以便你看到当前活动的是哪个配置文件。
|
||||
- 默认配置文件是 `openclaw`(受管独立模式)。使用 `defaultProfile: "user"` 可选择已登录用户浏览器。
|
||||
- 自动检测顺序:如果系统默认浏览器基于 Chromium,则优先使用它;否则按 Chrome → Brave → Edge → Chromium → Chrome Canary 的顺序检测。
|
||||
- `driver: "existing-session"` 使用 Chrome DevTools MCP,而不是原始 CDP。不要为该驱动设置 `cdpUrl`。
|
||||
- 当 existing-session 配置文件需要附加到非默认的 Chromium 用户配置文件(Brave、Edge 等)时,请设置 `browser.profiles.<name>.userDataDir`。这个路径同样接受 `~` 作为你的操作系统主目录。
|
||||
|
||||
</Accordion>
|
||||
|
||||
@ -248,10 +221,7 @@ Gateway 网关。
|
||||
|
||||
## 使用 Brave 或其他基于 Chromium 的浏览器
|
||||
|
||||
如果你的**系统默认**浏览器是基于 Chromium 的(Chrome/Brave/Edge 等),
|
||||
OpenClaw 会自动使用它。设置 `browser.executablePath` 可覆盖
|
||||
自动检测。顶层和按配置文件的 `executablePath` 值都接受 `~`
|
||||
作为你的操作系统主目录:
|
||||
如果你的**系统默认**浏览器是基于 Chromium 的(Chrome/Brave/Edge 等),OpenClaw 会自动使用它。设置 `browser.executablePath` 可覆盖自动检测。顶层和按配置文件设置的 `executablePath` 值都接受 `~` 作为你的操作系统主目录:
|
||||
|
||||
```bash
|
||||
openclaw config set browser.executablePath "/usr/bin/google-chrome"
|
||||
@ -290,59 +260,46 @@ openclaw config set browser.profiles.work.executablePath "/Applications/Google C
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
按配置文件设置的 `executablePath` 仅影响 OpenClaw
|
||||
启动的本地受管配置文件。`existing-session` 配置文件会附加到已在运行的浏览器,
|
||||
而远程 CDP 配置文件则使用 `cdpUrl` 背后的浏览器。
|
||||
按配置文件设置的 `executablePath` 只会影响 OpenClaw 启动的本地受管配置文件。`existing-session` 配置文件则会附加到一个已经运行的浏览器,而远程 CDP 配置文件使用 `cdpUrl` 背后的浏览器。
|
||||
|
||||
## 本地控制与远程控制
|
||||
|
||||
- **本地控制(默认):** Gateway 网关启动 loopback 控制服务,并可启动本地浏览器。
|
||||
- **远程控制(节点主机):** 在安装浏览器的机器上运行节点主机;Gateway 网关将浏览器操作代理到该节点主机。
|
||||
- **远程 CDP:** 设置 `browser.profiles.<name>.cdpUrl`(或 `browser.cdpUrl`)以
|
||||
附加到远程的 Chromium 系浏览器。在这种情况下,OpenClaw 不会启动本地浏览器。
|
||||
- 对于运行在 loopback 上的外部托管 CDP 服务(例如在 Docker 中发布到 `127.0.0.1` 的 Browserless),还应设置 `attachOnly: true`。没有 `attachOnly` 的 loopback CDP 会被视为本地 OpenClaw 受管浏览器配置文件。
|
||||
- **本地控制(默认):** Gateway 网关启动 loopback 控制服务,并且可以启动本地浏览器。
|
||||
- **远程控制(节点主机):** 在拥有浏览器的机器上运行节点主机;Gateway 网关会将浏览器操作代理到该节点主机。
|
||||
- **远程 CDP:** 设置 `browser.profiles.<name>.cdpUrl`(或 `browser.cdpUrl`)以附加到远程的基于 Chromium 的浏览器。在这种情况下,OpenClaw 不会启动本地浏览器。
|
||||
- 对于运行在 loopback 上的外部管理 CDP 服务(例如发布到 `127.0.0.1` 的 Docker 中的 Browserless),还需要设置 `attachOnly: true`。如果 loopback CDP 未设置 `attachOnly`,则会被视为由 OpenClaw 管理的本地浏览器配置文件。
|
||||
- `headless` 仅影响 OpenClaw 启动的本地受管配置文件。它不会重启或更改 existing-session 或远程 CDP 浏览器。
|
||||
- `executablePath` 也遵循相同的本地受管配置文件规则。对运行中的本地受管配置文件修改该值时,会将该配置文件标记为需要重启/协调,以便下次启动时使用新的二进制文件。
|
||||
- `executablePath` 遵循相同的本地受管配置文件规则。在一个正在运行的本地受管配置文件上更改它时,该配置文件会被标记为需要重启/协调,以便下一次启动使用新的二进制文件。
|
||||
|
||||
不同配置文件模式的停止行为不同:
|
||||
停止行为会因配置文件模式而异:
|
||||
|
||||
- 本地受管配置文件:`openclaw browser stop` 会停止
|
||||
由 OpenClaw 启动的浏览器进程
|
||||
- attach-only 和远程 CDP 配置文件:`openclaw browser stop` 会关闭活动的
|
||||
控制会话,并释放 Playwright/CDP 仿真覆盖(视口、
|
||||
配色方案、区域设置、时区、离线模式及类似状态),即使
|
||||
没有由 OpenClaw 启动任何浏览器进程
|
||||
- 本地受管配置文件:`openclaw browser stop` 会停止由 OpenClaw 启动的浏览器进程
|
||||
- 仅附加和远程 CDP 配置文件:`openclaw browser stop` 会关闭活动控制会话,并释放 Playwright/CDP 仿真覆盖项(视口、配色方案、区域设置、时区、离线模式及类似状态),即使浏览器进程并非由 OpenClaw 启动
|
||||
|
||||
远程 CDP URL 可以包含认证信息:
|
||||
|
||||
- 查询参数令牌(例如 `https://provider.example?token=<token>`)
|
||||
- HTTP Basic 认证(例如 `https://user:pass@provider.example`)
|
||||
- 查询参数 token(例如 `https://provider.example?token=<token>`)
|
||||
- HTTP Basic auth(例如 `https://user:pass@provider.example`)
|
||||
|
||||
OpenClaw 在调用 `/json/*` 端点以及连接
|
||||
CDP WebSocket 时会保留这些认证信息。对于
|
||||
令牌,优先使用环境变量或密钥管理器,而不是将它们提交到配置文件中。
|
||||
OpenClaw 在调用 `/json/*` 端点以及连接到 CDP WebSocket 时都会保留这些认证信息。对于 token,优先使用环境变量或密钥管理器,而不是将其提交到配置文件中。
|
||||
|
||||
## 节点浏览器代理(默认零配置)
|
||||
|
||||
如果你在安装有浏览器的机器上运行**节点主机**,OpenClaw 可以
|
||||
自动将浏览器工具调用路由到该节点,而无需任何额外浏览器配置。
|
||||
这是远程 Gateway 网关的默认路径。
|
||||
如果你在拥有浏览器的机器上运行了**节点主机**,OpenClaw 可以自动将浏览器工具调用路由到该节点,而无需任何额外的浏览器配置。对于远程 Gateway 网关,这是默认路径。
|
||||
|
||||
说明:
|
||||
|
||||
- 节点主机会通过一个**代理命令**公开其本地浏览器控制服务器。
|
||||
- 配置文件来自节点自身的 `browser.profiles` 配置(与本地相同)。
|
||||
- `nodeHost.browserProxy.allowProfiles` 是可选的。留空可保持旧版/默认行为:所有已配置的配置文件都可通过代理访问,包括配置文件创建/删除路由。
|
||||
- 如果你设置了 `nodeHost.browserProxy.allowProfiles`,OpenClaw 会将其视为最小权限边界:只有允许列表中的配置文件可被定位,持久化配置文件的创建/删除路由会在代理接口上被阻止。
|
||||
- 如果你不想启用它,可将其禁用:
|
||||
- 节点主机会通过一个**代理命令**暴露其本地浏览器控制服务器。
|
||||
- 配置文件来自节点自己的 `browser.profiles` 配置(与本地相同)。
|
||||
- `nodeHost.browserProxy.allowProfiles` 是可选的。将其留空即可保留旧版/默认行为:所有已配置的配置文件都可通过该代理访问,包括配置文件创建/删除路由。
|
||||
- 如果你设置了 `nodeHost.browserProxy.allowProfiles`,OpenClaw 会将其视为最小权限边界:只有 allowlist 中的配置文件可以作为目标,并且持久化配置文件创建/删除路由会在代理表面被阻止。
|
||||
- 如果你不想启用它,可以禁用:
|
||||
- 在节点上:`nodeHost.browserProxy.enabled=false`
|
||||
- 在 gateway 上:`gateway.nodes.browser.mode="off"`
|
||||
|
||||
## Browserless(托管远程 CDP)
|
||||
|
||||
[Browserless](https://browserless.io) 是一个托管的 Chromium 服务,通过 HTTPS 和 WebSocket 公开
|
||||
CDP 连接 URL。OpenClaw 可以使用任一形式,但对于远程浏览器配置文件,
|
||||
最简单的选项是使用 Browserless 连接文档中的直接 WebSocket URL。
|
||||
[Browserless](https://browserless.io) 是一个托管的 Chromium 服务,它通过 HTTPS 和 WebSocket 暴露 CDP 连接 URL。OpenClaw 可以使用任一形式,但对于远程浏览器配置文件,最简单的选项是使用 Browserless 连接文档中提供的直接 WebSocket URL。
|
||||
|
||||
示例:
|
||||
|
||||
@ -365,16 +322,13 @@ CDP 连接 URL。OpenClaw 可以使用任一形式,但对于远程浏览器配
|
||||
|
||||
说明:
|
||||
|
||||
- 将 `<BROWSERLESS_API_KEY>` 替换为你真实的 Browserless 令牌。
|
||||
- 选择与你的 Browserless 账户匹配的区域端点(参见其文档)。
|
||||
- 如果 Browserless 提供给你的是 HTTPS 基础 URL,你可以将其转换为
|
||||
`wss://` 用于直接 CDP 连接,也可以保留 HTTPS URL 并让 OpenClaw
|
||||
发现 `/json/version`。
|
||||
- 将 `<BROWSERLESS_API_KEY>` 替换为你真实的 Browserless token。
|
||||
- 选择与你的 Browserless 账户匹配的区域端点(见其文档)。
|
||||
- 如果 Browserless 提供给你的是 HTTPS 基础 URL,你可以将其转换为 `wss://` 以建立直接 CDP 连接,或者保留该 HTTPS URL,让 OpenClaw 去发现 `/json/version`。
|
||||
|
||||
### 同一主机上的 Browserless Docker
|
||||
|
||||
当 Browserless 在 Docker 中自托管,而 OpenClaw 运行在宿主机上时,请将
|
||||
Browserless 视为外部托管的 CDP 服务:
|
||||
当 Browserless 以 Docker 形式自托管,而 OpenClaw 运行在宿主机上时,应将 Browserless 视为一个外部管理的 CDP 服务:
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -392,47 +346,22 @@ Browserless 视为外部托管的 CDP 服务:
|
||||
}
|
||||
```
|
||||
|
||||
`browser.profiles.browserless.cdpUrl` 中的地址必须能从
|
||||
OpenClaw 进程访问。Browserless 还必须公布一个与之匹配的可达端点;
|
||||
请将 Browserless `EXTERNAL` 设置为同一个 OpenClaw 可访问的公共 WebSocket 基址,例如
|
||||
`ws://127.0.0.1:3000`、`ws://browserless:3000` 或稳定的私有 Docker
|
||||
网络地址。如果 `/json/version` 返回的 `webSocketDebuggerUrl` 指向
|
||||
OpenClaw 无法访问的地址,那么 CDP HTTP 看起来可能是正常的,但 WebSocket
|
||||
附加仍然会失败。
|
||||
`browser.profiles.browserless.cdpUrl` 中的地址必须能被 OpenClaw 进程访问。Browserless 也必须通告一个同样可访问的匹配端点;将 Browserless 的 `EXTERNAL` 设置为同一个面向 OpenClaw 的 WebSocket 基地址,例如 `ws://127.0.0.1:3000`、`ws://browserless:3000`,或稳定的私有 Docker 网络地址。如果 `/json/version` 返回的 `webSocketDebuggerUrl` 指向的是 OpenClaw 无法访问的地址,那么 CDP HTTP 看起来可能正常,但 WebSocket 附加仍会失败。
|
||||
|
||||
对于 loopback 上的 Browserless 配置文件,不要让 `attachOnly` 保持未设置。没有
|
||||
`attachOnly` 时,OpenClaw 会将该 loopback 端口视为本地受管浏览器
|
||||
配置文件,并可能报告该端口正在使用但不属于 OpenClaw。
|
||||
对于 loopback Browserless 配置文件,不要让 `attachOnly` 保持未设置。没有 `attachOnly` 时,OpenClaw 会将该 loopback 端口视为本地受管浏览器配置文件,并且可能报告该端口正在使用但不属于 OpenClaw。
|
||||
|
||||
## 直接 WebSocket CDP 提供商
|
||||
|
||||
某些托管浏览器服务暴露的是**直接 WebSocket** 端点,而不是
|
||||
标准的基于 HTTP 的 CDP 发现(`/json/version`)。OpenClaw 接受三种
|
||||
CDP URL 形式,并会自动选择正确的连接策略:
|
||||
一些托管浏览器服务暴露的是**直接 WebSocket** 端点,而不是标准的基于 HTTP 的 CDP 发现(`/json/version`)。OpenClaw 接受三种 CDP URL 形式,并会自动选择正确的连接策略:
|
||||
|
||||
- **HTTP(S) 发现** — `http://host[:port]` 或 `https://host[:port]`。
|
||||
OpenClaw 调用 `/json/version` 以发现 WebSocket 调试器 URL,然后
|
||||
建立连接。没有 WebSocket 回退。
|
||||
- **直接 WebSocket 端点** — `ws://host[:port]/devtools/<kind>/<id>` 或
|
||||
`wss://...`,其中路径为 `/devtools/browser|page|worker|shared_worker|service_worker/<id>`。
|
||||
OpenClaw 通过 WebSocket 握手直接连接,并完全跳过
|
||||
`/json/version`。
|
||||
- **裸 WebSocket 根路径** — `ws://host[:port]` 或 `wss://host[:port]`,没有
|
||||
`/devtools/...` 路径(例如 [Browserless](https://browserless.io)、
|
||||
[Browserbase](https://www.browserbase.com))。OpenClaw 会先尝试 HTTP
|
||||
`/json/version` 发现(将协议规范化为 `http`/`https`);
|
||||
如果发现返回了 `webSocketDebuggerUrl`,则使用它,否则 OpenClaw
|
||||
会回退为在裸根路径上直接进行 WebSocket 握手。如果公布的
|
||||
WebSocket 端点拒绝 CDP 握手,但配置的裸根路径
|
||||
可以接受,OpenClaw 也会回退到该根路径。这使得指向本地 Chrome 的裸 `ws://`
|
||||
仍可连接,因为 Chrome 只接受来自 `/json/version` 的特定按目标路径的 WebSocket
|
||||
升级;而托管
|
||||
提供商在其发现端点公布了不适合 Playwright CDP 的短期 URL 时,仍可以使用其根 WebSocket 端点。
|
||||
- **HTTP(S) 发现** —— `http://host[:port]` 或 `https://host[:port]`。
|
||||
OpenClaw 调用 `/json/version` 来发现 WebSocket 调试器 URL,然后再连接。没有 WebSocket 回退。
|
||||
- **直接 WebSocket 端点** —— `ws://host[:port]/devtools/<kind>/<id>` 或带有 `/devtools/browser|page|worker|shared_worker|service_worker/<id>` 路径的 `wss://...`。OpenClaw 直接通过 WebSocket 握手连接,并完全跳过 `/json/version`。
|
||||
- **裸 WebSocket 根地址** —— 没有 `/devtools/...` 路径的 `ws://host[:port]` 或 `wss://host[:port]`(例如 [Browserless](https://browserless.io)、[Browserbase](https://www.browserbase.com))。OpenClaw 会先尝试 HTTP `/json/version` 发现(把协议规范化为 `http`/`https`);如果发现过程返回了 `webSocketDebuggerUrl`,则使用它,否则 OpenClaw 会回退到在裸根地址上直接进行 WebSocket 握手。如果通告的 WebSocket 端点拒绝 CDP 握手,但已配置的裸根地址接受它,OpenClaw 也会回退到该根地址。这样一来,指向本地 Chrome 的裸 `ws://` 依然可以连接,因为 Chrome 只接受 `/json/version` 中特定按目标划分路径上的 WebSocket 升级;而托管提供商在其发现端点通告了不适用于 Playwright CDP 的短时 URL 时,仍然可以使用它们的根 WebSocket 端点。
|
||||
|
||||
### Browserbase
|
||||
|
||||
[Browserbase](https://www.browserbase.com) 是一个用于运行
|
||||
headless 浏览器的云平台,内置 CAPTCHA 求解、隐身模式和住宅代理。
|
||||
[Browserbase](https://www.browserbase.com) 是一个云平台,用于运行带有内置 CAPTCHA 求解、隐身模式和住宅代理的 headless 浏览器。
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -453,78 +382,67 @@ headless 浏览器的云平台,内置 CAPTCHA 求解、隐身模式和住宅
|
||||
|
||||
说明:
|
||||
|
||||
- [注册](https://www.browserbase.com/sign-up),然后从 [Overview 仪表板](https://www.browserbase.com/overview) 复制你的 **API Key**。
|
||||
- 将 `<BROWSERBASE_API_KEY>` 替换为你真实的 Browserbase API 密钥。
|
||||
- Browserbase 会在 WebSocket 连接时自动创建浏览器会话,因此
|
||||
不需要手动创建会话步骤。
|
||||
- 免费层每月允许一个并发会话和一个浏览器小时。
|
||||
付费计划限制请参阅 [定价](https://www.browserbase.com/pricing)。
|
||||
- 完整 API
|
||||
参考、SDK 指南和集成示例请参阅 [Browserbase 文档](https://docs.browserbase.com)。
|
||||
- [注册](https://www.browserbase.com/sign-up),并从 [Overview dashboard](https://www.browserbase.com/overview) 复制你的 **API Key**。
|
||||
- 将 `<BROWSERBASE_API_KEY>` 替换为你真实的 Browserbase API key。
|
||||
- Browserbase 会在 WebSocket 连接时自动创建浏览器会话,因此不需要手动创建会话。
|
||||
- 免费套餐每月允许一个并发会话和一个浏览器小时。有关付费套餐限制,请参阅 [pricing](https://www.browserbase.com/pricing)。
|
||||
- 完整的 API 参考、SDK 指南和集成示例,请参阅 [Browserbase docs](https://docs.browserbase.com)。
|
||||
|
||||
## 安全性
|
||||
## 安全
|
||||
|
||||
关键概念:
|
||||
关键点:
|
||||
|
||||
- 浏览器控制仅限 loopback;访问通过 Gateway 网关的认证或节点配对进行。
|
||||
- 独立的 loopback 浏览器 HTTP API **仅**使用共享密钥认证:
|
||||
gateway token Bearer 认证、`x-openclaw-password`,或使用
|
||||
已配置 gateway 密码的 HTTP Basic 认证。
|
||||
- Tailscale Serve 身份请求头和 `gateway.auth.mode: "trusted-proxy"`
|
||||
**不能**用于认证这个独立的 loopback 浏览器 API。
|
||||
- 如果启用了浏览器控制但未配置共享密钥认证,OpenClaw
|
||||
会在启动时自动生成 `gateway.auth.token` 并将其持久化到配置中。
|
||||
- 当 `gateway.auth.mode` 已经是
|
||||
`password`、`none` 或 `trusted-proxy` 时,OpenClaw **不会**自动生成该令牌。
|
||||
- 将 Gateway 网关和任何节点主机保持在私有网络中(Tailscale);避免公开暴露。
|
||||
- 将远程 CDP URL/令牌视为密钥;优先使用环境变量或密钥管理器。
|
||||
- 浏览器控制仅限 loopback;访问通过 Gateway 网关认证或节点配对进行。
|
||||
- 独立的 loopback 浏览器 HTTP API **仅**使用共享密钥认证:gateway token bearer auth、`x-openclaw-password`,或使用已配置 gateway 密码的 HTTP Basic auth。
|
||||
- Tailscale Serve 身份头和 `gateway.auth.mode: "trusted-proxy"` **不会**对这个独立的 loopback 浏览器 API 进行认证。
|
||||
- 如果启用了浏览器控制且未配置共享密钥认证,OpenClaw 会在启动时自动生成 `gateway.auth.token` 并将其持久化到配置中。
|
||||
- 当 `gateway.auth.mode` 已经是 `password`、`none` 或 `trusted-proxy` 时,OpenClaw **不会**自动生成该 token。
|
||||
- 请将 Gateway 网关和任何节点主机保持在私有网络中(Tailscale);避免公开暴露。
|
||||
- 将远程 CDP URL/token 视为机密;优先使用环境变量或密钥管理器。
|
||||
|
||||
远程 CDP 提示:
|
||||
|
||||
- 尽可能优先使用加密端点(HTTPS 或 WSS)和短期令牌。
|
||||
- 避免将长期令牌直接嵌入配置文件中。
|
||||
- 尽可能优先使用加密端点(HTTPS 或 WSS)和短时 token。
|
||||
- 避免将长期有效的 token 直接嵌入配置文件。
|
||||
|
||||
## 配置文件(多浏览器)
|
||||
|
||||
OpenClaw 支持多个命名配置文件(路由配置)。配置文件可以是:
|
||||
|
||||
- **由 OpenClaw 管理**:具有独立用户数据目录 + CDP 端口的专用 Chromium 系浏览器实例
|
||||
- **远程**:显式 CDP URL(运行在其他地方的 Chromium 系浏览器)
|
||||
- **现有会话**:通过 Chrome DevTools MCP 自动连接到你现有的 Chrome 配置文件
|
||||
- **OpenClaw 管理**:一个专用的、基于 Chromium 的浏览器实例,具有自己的用户数据目录 + CDP 端口
|
||||
- **远程**:显式 CDP URL(运行在其他地方的基于 Chromium 的浏览器)
|
||||
- **现有会话**:通过 Chrome DevTools MCP 自动连接你的现有 Chrome 配置文件
|
||||
|
||||
默认值:
|
||||
|
||||
- 如果缺失,会自动创建 `openclaw` 配置文件。
|
||||
- `user` 配置文件内置用于 Chrome MCP existing-session 附加。
|
||||
- 除 `user` 外,existing-session 配置文件需要显式启用;请使用 `--driver existing-session` 创建。
|
||||
- `user` 配置文件是内置的,用于通过 Chrome MCP 附加到 existing-session。
|
||||
- 除 `user` 之外,existing-session 配置文件需要显式启用;请使用 `--driver existing-session` 创建它们。
|
||||
- 本地 CDP 端口默认从 **18800–18899** 分配。
|
||||
- 删除配置文件会将其本地数据目录移到废纸篓。
|
||||
- 删除配置文件时,其本地数据目录会被移到废纸篓。
|
||||
|
||||
所有控制端点都接受 `?profile=<name>`;CLI 使用 `--browser-profile`。
|
||||
|
||||
## 通过 Chrome DevTools MCP 连接现有会话
|
||||
## 通过 Chrome DevTools MCP 附加现有会话
|
||||
|
||||
OpenClaw 还可以通过官方 Chrome DevTools MCP 服务器附加到正在运行的 Chromium 系浏览器配置文件。
|
||||
这样会复用该浏览器配置文件中已经打开的标签页和登录状态。
|
||||
OpenClaw 还可以通过官方的 Chrome DevTools MCP 服务器附加到一个正在运行的基于 Chromium 的浏览器配置文件。这样可以复用该浏览器配置文件中已经打开的标签页和登录状态。
|
||||
|
||||
官方背景和设置参考:
|
||||
官方背景与设置参考:
|
||||
|
||||
- [Chrome for Developers:使用 Chrome DevTools MCP 与你的浏览器会话协作](https://developer.chrome.com/blog/chrome-devtools-mcp-debug-your-browser-session)
|
||||
- [Chrome for Developers: Use Chrome DevTools MCP with your browser session](https://developer.chrome.com/blog/chrome-devtools-mcp-debug-your-browser-session)
|
||||
- [Chrome DevTools MCP README](https://github.com/ChromeDevTools/chrome-devtools-mcp)
|
||||
|
||||
内置配置文件:
|
||||
|
||||
- `user`
|
||||
|
||||
可选:如果你想使用不同的名称、颜色或浏览器数据目录,
|
||||
可以创建自己的自定义 existing-session 配置文件。
|
||||
可选:如果你想使用不同的名称、颜色或浏览器数据目录,可以创建你自己的自定义 existing-session 配置文件。
|
||||
|
||||
默认行为:
|
||||
|
||||
- 内置的 `user` 配置文件使用 Chrome MCP 自动连接,目标是
|
||||
默认的本地 Google Chrome 配置文件。
|
||||
- 内置的 `user` 配置文件使用 Chrome MCP 自动连接,目标是默认的本地 Google Chrome 配置文件。
|
||||
|
||||
对于 Brave、Edge、Chromium 或非默认 Chrome 配置文件,请使用 `userDataDir`。
|
||||
对于 Brave、Edge、Chromium 或非默认的 Chrome 配置文件,请使用 `userDataDir`。
|
||||
`~` 会展开为你的操作系统主目录:
|
||||
|
||||
```json5
|
||||
@ -544,11 +462,11 @@ OpenClaw 还可以通过官方 Chrome DevTools MCP 服务器附加到正在运
|
||||
|
||||
然后在对应的浏览器中:
|
||||
|
||||
1. 打开该浏览器的远程调试 inspect 页面。
|
||||
1. 打开该浏览器用于远程调试的 inspect 页面。
|
||||
2. 启用远程调试。
|
||||
3. 保持浏览器运行,并在 OpenClaw 附加时批准连接提示。
|
||||
|
||||
常见 inspect 页面:
|
||||
常见的 inspect 页面:
|
||||
|
||||
- Chrome:`chrome://inspect/#remote-debugging`
|
||||
- Brave:`brave://inspect/#remote-debugging`
|
||||
@ -569,79 +487,65 @@ openclaw browser --browser-profile user snapshot --format ai
|
||||
- `status` 显示 `transport: chrome-mcp`
|
||||
- `status` 显示 `running: true`
|
||||
- `tabs` 列出你已经打开的浏览器标签页
|
||||
- `snapshot` 从所选的实时标签页返回 refs
|
||||
- `snapshot` 返回来自所选实时标签页的 refs
|
||||
|
||||
如果附加失败,请检查:
|
||||
如果附加不起作用,请检查:
|
||||
|
||||
- 目标 Chromium 系浏览器版本是否为 `144+`
|
||||
- 该浏览器的 inspect 页面中是否已启用远程调试
|
||||
- 浏览器是否显示了附加同意提示,并且你已接受
|
||||
- `openclaw doctor` 会迁移旧的基于扩展的浏览器配置,并检查默认自动连接配置文件所需的 Chrome 是否已在本地安装,但它不能替你在浏览器端启用远程调试
|
||||
- 目标的基于 Chromium 的浏览器版本是 `144+`
|
||||
- 已在该浏览器的 inspect 页面中启用远程调试
|
||||
- 浏览器显示了附加同意提示,并且你已接受
|
||||
- `openclaw doctor` 会迁移旧的基于扩展的浏览器配置,并检查默认自动连接配置文件所需的 Chrome 是否已在本地安装,但它无法替你启用浏览器端的远程调试
|
||||
|
||||
智能体使用方式:
|
||||
智能体使用:
|
||||
|
||||
- 当你需要用户已登录的浏览器状态时,使用 `profile="user"`。
|
||||
- 如果你使用自定义 existing-session 配置文件,请传入该显式配置文件名称。
|
||||
- 仅在用户就在电脑前可以批准附加
|
||||
提示时,才选择此模式。
|
||||
- Gateway 网关或节点主机可以启动 `npx chrome-devtools-mcp@latest --autoConnect`
|
||||
- 如果你使用自定义 existing-session 配置文件,请传入该明确的配置文件名称。
|
||||
- 仅当用户在电脑前可以批准附加提示时,才选择此模式。
|
||||
- Gateway 网关或节点主机可以生成 `npx chrome-devtools-mcp@latest --autoConnect`
|
||||
|
||||
说明:
|
||||
|
||||
- 这条路径比隔离的 `openclaw` 配置文件风险更高,因为它可以
|
||||
在你已登录的浏览器会话中执行操作。
|
||||
- 对于此 driver,OpenClaw 不会启动浏览器;它只会附加。
|
||||
- OpenClaw 在此使用官方 Chrome DevTools MCP `--autoConnect` 流程。如果
|
||||
设置了 `userDataDir`,它会被透传以定位该用户数据目录。
|
||||
- Existing-session 可以附加到所选主机上,或通过已连接的
|
||||
浏览器节点附加。如果 Chrome 位于其他地方且没有连接任何浏览器节点,请改用
|
||||
远程 CDP 或节点主机。
|
||||
- 与隔离的 `openclaw` 配置文件相比,这条路径风险更高,因为它可以在你已登录的浏览器会话中执行操作。
|
||||
- 对于这个驱动,OpenClaw 不会启动浏览器;它只会进行附加。
|
||||
- OpenClaw 在这里使用官方的 Chrome DevTools MCP `--autoConnect` 流程。如果设置了 `userDataDir`,它会被传递下去,以定位该用户数据目录。
|
||||
- Existing-session 可以附加到所选主机上,或通过已连接的浏览器节点进行附加。如果 Chrome 位于其他地方且没有连接浏览器节点,请改用远程 CDP 或节点主机。
|
||||
|
||||
### 自定义 Chrome MCP 启动
|
||||
|
||||
当默认的
|
||||
`npx chrome-devtools-mcp@latest` 流程不符合你的需求时(离线主机、
|
||||
固定版本、内置二进制文件),可以按配置文件覆盖启动的 Chrome DevTools MCP 服务器:
|
||||
当默认的 `npx chrome-devtools-mcp@latest` 流程不是你想要的方式时(离线主机、固定版本、随附二进制文件),可以按配置文件覆盖所生成的 Chrome DevTools MCP 服务器:
|
||||
|
||||
| 字段 | 作用 |
|
||||
| ------------ | -------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `mcpCommand` | 要启动的可执行文件,用于替代 `npx`。按原样解析;绝对路径会被保留。 |
|
||||
| `mcpCommand` | 要生成的可执行文件,用来替代 `npx`。按原样解析;支持绝对路径。 |
|
||||
| `mcpArgs` | 原样传递给 `mcpCommand` 的参数数组。会替换默认的 `chrome-devtools-mcp@latest --autoConnect` 参数。 |
|
||||
|
||||
当在 existing-session 配置文件上设置 `cdpUrl` 时,OpenClaw 会跳过
|
||||
`--autoConnect`,并自动将该端点转发给 Chrome MCP:
|
||||
当在 existing-session 配置文件上设置了 `cdpUrl` 时,OpenClaw 会跳过 `--autoConnect`,并自动将该端点转发给 Chrome MCP:
|
||||
|
||||
- `http(s)://...` → `--browserUrl <url>`(DevTools HTTP 发现端点)。
|
||||
- `ws(s)://...` → `--wsEndpoint <url>`(直接 CDP WebSocket)。
|
||||
|
||||
端点标志和 `userDataDir` 不能同时组合使用:当设置了 `cdpUrl` 时,
|
||||
`userDataDir` 会在 Chrome MCP 启动时被忽略,因为 Chrome MCP 会附加到
|
||||
端点背后正在运行的浏览器,而不是打开一个配置文件
|
||||
目录。
|
||||
端点标志与 `userDataDir` 不能组合使用:设置了 `cdpUrl` 时,Chrome MCP 启动会忽略 `userDataDir`,因为 Chrome MCP 会附加到端点背后正在运行的浏览器,而不是打开一个配置文件目录。
|
||||
|
||||
<Accordion title="Existing-session 功能限制">
|
||||
|
||||
与受管的 `openclaw` 配置文件相比,existing-session driver 的限制更多:
|
||||
与受管的 `openclaw` 配置文件相比,existing-session 驱动受到更多限制:
|
||||
|
||||
- **截图** — 支持整页截图和 `--ref` 元素截图;不支持 CSS `--element` 选择器。`--full-page` 不能与 `--ref` 或 `--element` 组合。页面截图或基于 ref 的元素截图不需要 Playwright。
|
||||
- **操作** — `click`、`type`、`hover`、`scrollIntoView`、`drag` 和 `select` 需要 snapshot refs(不支持 CSS 选择器)。`click-coords` 会点击可见视口坐标,不需要 snapshot ref。`click` 仅支持鼠标左键。`type` 不支持 `slowly=true`;请改用 `fill` 或 `press`。`press` 不支持 `delayMs`。`type`、`hover`、`scrollIntoView`、`drag`、`select`、`fill` 和 `evaluate` 不支持按调用单独设置超时。`select` 只接受单个值。
|
||||
- **等待 / 上传 / 对话框** — `wait --url` 支持精确匹配、子串匹配和 glob 模式;不支持 `wait --load networkidle`。上传钩子需要 `ref` 或 `inputRef`,一次只能上传一个文件,不支持 CSS `element`。对话框钩子不支持超时覆盖。
|
||||
- **仅受管模式功能** — 批量操作、PDF 导出、下载拦截和 `responsebody` 仍然需要受管浏览器路径。
|
||||
- **截图** —— 支持页面截图和 `--ref` 元素截图;不支持 CSS `--element` 选择器。`--full-page` 不能与 `--ref` 或 `--element` 组合使用。页面或基于 ref 的元素截图不需要 Playwright。
|
||||
- **操作** —— `click`、`type`、`hover`、`scrollIntoView`、`drag` 和 `select` 需要 snapshot refs(不支持 CSS 选择器)。`click-coords` 点击可见视口坐标,不需要 snapshot ref。`click` 仅支持左键。`type` 不支持 `slowly=true`;请使用 `fill` 或 `press`。`press` 不支持 `delayMs`。`type`、`hover`、`scrollIntoView`、`drag`、`select`、`fill` 和 `evaluate` 不支持按调用单独设置超时。`select` 接受单个值。
|
||||
- **等待 / 上传 / 对话框** —— `wait --url` 支持精确、子串和 glob 模式;不支持 `wait --load networkidle`。上传钩子要求使用 `ref` 或 `inputRef`,一次一个文件,不支持 CSS `element`。对话框钩子不支持超时覆盖。
|
||||
- **仅受管功能** —— 批量操作、PDF 导出、下载拦截和 `responsebody` 仍然需要使用受管浏览器路径。
|
||||
|
||||
</Accordion>
|
||||
|
||||
## 隔离保证
|
||||
|
||||
- **专用用户数据目录**:绝不会触碰你的个人浏览器配置文件。
|
||||
- **专用端口**:避免使用 `9222`,以防与开发工作流冲突。
|
||||
- **可预测的标签页控制**:`tabs` 会先返回 `suggestedTargetId`,然后是
|
||||
稳定的 `tabId` 句柄,例如 `t1`、可选标签以及原始 `targetId`。
|
||||
智能体应复用 `suggestedTargetId`;原始 id 仍保留供
|
||||
调试和兼容性使用。
|
||||
- **专用端口**:避免使用 `9222`,防止与开发工作流冲突。
|
||||
- **可预测的标签页控制**:`tabs` 会先返回 `suggestedTargetId`,然后是稳定的 `tabId` 句柄,例如 `t1`、可选标签,以及原始 `targetId`。智能体应复用 `suggestedTargetId`;原始 id 仍然保留用于调试和兼容性。
|
||||
|
||||
## 浏览器选择
|
||||
|
||||
在本地启动时,OpenClaw 会选择第一个可用项:
|
||||
在本地启动时,OpenClaw 会选择第一个可用的浏览器:
|
||||
|
||||
1. Chrome
|
||||
2. Brave
|
||||
@ -649,49 +553,41 @@ openclaw browser --browser-profile user snapshot --format ai
|
||||
4. Chromium
|
||||
5. Chrome Canary
|
||||
|
||||
你可以使用 `browser.executablePath` 覆盖。
|
||||
你可以使用 `browser.executablePath` 进行覆盖。
|
||||
|
||||
平台说明:
|
||||
平台:
|
||||
|
||||
- macOS:检查 `/Applications` 和 `~/Applications`。
|
||||
- Linux:检查 `/usr/bin`、
|
||||
`/snap/bin`、`/opt/google`、`/opt/brave.com`、`/usr/lib/chromium` 和
|
||||
`/usr/lib/chromium-browser` 下常见的 Chrome/Brave/Edge/Chromium 位置。
|
||||
- Linux:检查 `/usr/bin`、`/snap/bin`、`/opt/google`、`/opt/brave.com`、`/usr/lib/chromium` 和 `/usr/lib/chromium-browser` 下常见的 Chrome/Brave/Edge/Chromium 位置。
|
||||
- Windows:检查常见安装位置。
|
||||
|
||||
## 控制 API(可选)
|
||||
|
||||
用于脚本和调试时,Gateway 网关会暴露一个小型的**仅限 loopback 的 HTTP
|
||||
控制 API**,以及与之匹配的 `openclaw browser` CLI(快照、refs、wait
|
||||
增强功能、JSON 输出、调试工作流)。完整参考请参阅
|
||||
[浏览器控制 API](/zh-CN/tools/browser-control)。
|
||||
对于脚本编写和调试,Gateway 网关暴露了一个小型的**仅限 loopback 的 HTTP 控制 API**,以及对应的 `openclaw browser` CLI(快照、refs、wait 增强、JSON 输出、调试工作流)。完整参考请参阅[Browser control API](/zh-CN/tools/browser-control)。
|
||||
|
||||
## 故障排除
|
||||
|
||||
对于 Linux 特有问题(尤其是 snap Chromium),请参阅
|
||||
[浏览器故障排除](/zh-CN/tools/browser-linux-troubleshooting)。
|
||||
有关 Linux 特有问题(尤其是 snap Chromium),请参阅[Browser 故障排除](/zh-CN/tools/browser-linux-troubleshooting)。
|
||||
|
||||
对于 WSL2 Gateway 网关 + Windows Chrome 分离主机设置,请参阅
|
||||
[WSL2 + Windows + 远程 Chrome CDP 故障排除](/zh-CN/tools/browser-wsl2-windows-remote-cdp-troubleshooting)。
|
||||
有关 WSL2 Gateway 网关 + Windows Chrome 分离主机设置,请参阅[WSL2 + Windows + 远程 Chrome CDP 故障排除](/zh-CN/tools/browser-wsl2-windows-remote-cdp-troubleshooting)。
|
||||
|
||||
### CDP 启动失败与导航 SSRF 阻止
|
||||
|
||||
这是两类不同的失败,它们指向不同的代码路径。
|
||||
|
||||
- **CDP 启动或就绪失败** 表示 OpenClaw 无法确认浏览器控制平面处于健康状态。
|
||||
- **导航 SSRF 阻止** 表示浏览器控制平面是健康的,但页面导航目标因策略被拒绝。
|
||||
- **CDP 启动或就绪失败**表示 OpenClaw 无法确认浏览器控制平面处于健康状态。
|
||||
- **导航 SSRF 阻止**表示浏览器控制平面是健康的,但页面导航目标被策略拒绝。
|
||||
|
||||
常见示例:
|
||||
|
||||
- CDP 启动或就绪失败:
|
||||
- `Chrome CDP websocket for profile "openclaw" is not reachable after start`
|
||||
- `Remote CDP for profile "<name>" is not reachable at <cdpUrl>`
|
||||
- `Port <port> is in use for profile "<name>" but not by openclaw`,当
|
||||
配置了 loopback 外部 CDP 服务却未设置 `attachOnly: true` 时
|
||||
- `Port <port> is in use for profile "<name>" but not by openclaw`,当 loopback 外部 CDP 服务配置时未设置 `attachOnly: true`
|
||||
- 导航 SSRF 阻止:
|
||||
- 当 `start` 和 `tabs` 仍可用时,`open`、`navigate`、snapshot 或标签页打开流程因浏览器/网络策略错误而失败
|
||||
- 当 `start` 和 `tabs` 仍然可用时,`open`、`navigate`、snapshot 或打开标签页流程因浏览器/网络策略错误而失败
|
||||
|
||||
使用以下最小序列来区分这两类问题:
|
||||
使用以下最小命令序列来区分这两类问题:
|
||||
|
||||
```bash
|
||||
openclaw browser --browser-profile openclaw start
|
||||
@ -701,46 +597,46 @@ openclaw browser --browser-profile openclaw open https://example.com
|
||||
|
||||
结果解读方式:
|
||||
|
||||
- 如果 `start` 失败并显示 `not reachable after start`,先排查 CDP 就绪问题。
|
||||
- 如果 `start` 成功但 `tabs` 失败,说明控制平面仍然不健康。应将其视为 CDP 可达性问题,而不是页面导航问题。
|
||||
- 如果 `start` 和 `tabs` 成功,但 `open` 或 `navigate` 失败,说明浏览器控制平面已启动,失败点在导航策略或目标页面。
|
||||
- 如果 `start`、`tabs` 和 `open` 全部成功,则基础受管浏览器控制路径是健康的。
|
||||
- 如果 `start` 因 `not reachable after start` 失败,请先排查 CDP 就绪问题。
|
||||
- 如果 `start` 成功但 `tabs` 失败,控制平面仍然不健康。请将其视为 CDP 可达性问题,而不是页面导航问题。
|
||||
- 如果 `start` 和 `tabs` 成功,但 `open` 或 `navigate` 失败,则说明浏览器控制平面已经正常,失败发生在导航策略或目标页面上。
|
||||
- 如果 `start`、`tabs` 和 `open` 都成功,则说明基础的受管浏览器控制路径是健康的。
|
||||
|
||||
重要行为细节:
|
||||
|
||||
- 即使你没有配置 `browser.ssrfPolicy`,浏览器配置默认也会使用一个默认拒绝的 SSRF 策略对象。
|
||||
- 对于本地 loopback 的 `openclaw` 受管配置文件,CDP 健康检查会有意跳过对 OpenClaw 自身本地控制平面的浏览器 SSRF 可达性强制检查。
|
||||
- 导航保护是独立的。`start` 或 `tabs` 成功并不意味着后续的 `open` 或 `navigate` 目标一定被允许。
|
||||
- 即使你没有配置 `browser.ssrfPolicy`,浏览器配置默认也会采用失败即关闭的 SSRF 策略对象。
|
||||
- 对于本地 loopback 的 `openclaw` 受管配置文件,CDP 健康检查会有意跳过浏览器 SSRF 可达性强制检查,以便 OpenClaw 自己的本地控制平面能够正常工作。
|
||||
- 导航保护是独立的。`start` 或 `tabs` 成功,并不意味着后续的 `open` 或 `navigate` 目标一定被允许。
|
||||
|
||||
安全指引:
|
||||
|
||||
- **不要**默认放宽浏览器 SSRF 策略。
|
||||
- 优先使用精确的主机例外,例如 `hostnameAllowlist` 或 `allowedHostnames`,而不是宽泛的私有网络访问。
|
||||
- 仅在明确受信任且已审查、并且确实需要私有网络浏览器访问的环境中,才使用 `dangerouslyAllowPrivateNetwork: true`。
|
||||
- 优先使用范围较窄的主机例外,例如 `hostnameAllowlist` 或 `allowedHostnames`,而不是宽泛的私有网络访问。
|
||||
- 仅在明确受信任、确实需要私有网络浏览器访问并且已经过审查的环境中,才使用 `dangerouslyAllowPrivateNetwork: true`。
|
||||
|
||||
## 智能体工具 + 控制方式
|
||||
## 智能体工具 + 控制工作原理
|
||||
|
||||
智能体获得**一个工具**用于浏览器自动化:
|
||||
智能体获得**一个工具**来进行浏览器自动化:
|
||||
|
||||
- `browser` — doctor/status/start/stop/tabs/open/focus/close/snapshot/screenshot/navigate/act
|
||||
|
||||
其映射方式如下:
|
||||
它的映射方式如下:
|
||||
|
||||
- `browser snapshot` 返回稳定的 UI 树(AI 或 ARIA)。
|
||||
- `browser act` 使用 snapshot `ref` ID 来点击/输入/拖动/选择。
|
||||
- `browser snapshot` 返回一个稳定的 UI 树(AI 或 ARIA)。
|
||||
- `browser act` 使用 snapshot `ref` ID 来执行 click/type/drag/select。
|
||||
- `browser screenshot` 捕获像素(整页、元素或带标签的 refs)。
|
||||
- `browser doctor` 检查 Gateway 网关、插件、配置文件、浏览器和标签页就绪状态。
|
||||
- `browser` 接受:
|
||||
- `profile` 用于选择命名的浏览器配置文件(openclaw、chrome 或远程 CDP)。
|
||||
- `profile` 用于选择命名浏览器配置文件(openclaw、chrome 或远程 CDP)。
|
||||
- `target`(`sandbox` | `host` | `node`)用于选择浏览器所在位置。
|
||||
- 在沙箱隔离会话中,`target: "host"` 需要 `agents.defaults.sandbox.browser.allowHostControl=true`。
|
||||
- 如果省略 `target`:沙箱隔离会话默认使用 `sandbox`,非沙箱隔离会话默认使用 `host`。
|
||||
- 如果连接了具备浏览器能力的节点,除非你固定使用 `target="host"` 或 `target="node"`,否则该工具可能会自动路由到该节点。
|
||||
- 如果连接了具备浏览器能力的节点,工具可能会自动路由到它,除非你固定指定 `target="host"` 或 `target="node"`。
|
||||
|
||||
这让智能体保持可预测,并避免使用脆弱的选择器。
|
||||
这样可以让智能体保持确定性,并避免脆弱的选择器。
|
||||
|
||||
## 相关内容
|
||||
|
||||
- [工具概览](/zh-CN/tools) — 所有可用的智能体工具
|
||||
- [Tools Overview](/zh-CN/tools) — 所有可用的智能体工具
|
||||
- [沙箱隔离](/zh-CN/gateway/sandboxing) — 沙箱隔离环境中的浏览器控制
|
||||
- [安全性](/zh-CN/gateway/security) — 浏览器控制的风险与加固
|
||||
- [安全](/zh-CN/gateway/security) — 浏览器控制的风险与加固
|
||||
|
||||
Loading…
Reference in New Issue
Block a user