chore(i18n): refresh zh-CN translations
This commit is contained in:
parent
bd55f5135f
commit
85bc3102e5
File diff suppressed because it is too large
Load Diff
@ -2,38 +2,39 @@
|
||||
read_when:
|
||||
- 更改日志输出或格式
|
||||
- 调试 CLI 或 Gateway 网关输出
|
||||
summary: 日志输出界面、文件日志、WS 日志样式和控制台格式
|
||||
summary: 日志输出面、文件日志、WS 日志样式,以及控制台格式化
|
||||
title: Gateway 网关日志
|
||||
x-i18n:
|
||||
generated_at: "2026-04-25T23:50:19Z"
|
||||
generated_at: "2026-04-26T06:01:21Z"
|
||||
model: gpt-5.4
|
||||
provider: openai
|
||||
source_hash: 706c9eb05f805057c2465cf00a4654dea81d53d24acb4b6fc63658bc959bc8ff
|
||||
source_hash: c005cfc4cfe456b3734d3928a16c9cd131a2b465d46f2aba9c9c61db22dcc399
|
||||
source_path: gateway/logging.md
|
||||
workflow: 15
|
||||
---
|
||||
|
||||
# 日志
|
||||
# 日志记录
|
||||
|
||||
如需查看面向用户的概览(CLI + Control UI + 配置),请参阅 [/logging](/zh-CN/logging)。
|
||||
如需面向用户的概览(CLI + Control UI + 配置),请参见 [/logging](/zh-CN/logging)。
|
||||
|
||||
OpenClaw 有两个日志“输出界面”:
|
||||
OpenClaw 有两个日志“输出面”:
|
||||
|
||||
- **控制台输出**(你在终端 / Debug UI 中看到的内容)。
|
||||
- **文件日志**(JSON 行),由 Gateway 网关日志记录器写入。
|
||||
- **文件日志**(JSON lines),由 Gateway 网关日志记录器写入。
|
||||
|
||||
## 基于文件的日志记录器
|
||||
|
||||
- 默认滚动日志文件位于 `/tmp/openclaw/` 下(每天一个文件):`openclaw-YYYY-MM-DD.log`
|
||||
- 日期使用 Gateway 网关主机的本地时区。
|
||||
- 活动日志文件会在达到 `logging.maxFileBytes` 时轮转(默认:100 MB),最多保留五个带编号的归档文件,然后继续写入新的活动文件。
|
||||
- 日志文件路径和级别可通过 `~/.openclaw/openclaw.json` 配置:
|
||||
- `logging.file`
|
||||
- `logging.level`
|
||||
|
||||
文件格式为每行一个 JSON 对象。
|
||||
|
||||
Control UI 的 Logs 标签页会通过 Gateway 网关跟踪此文件(`logs.tail`)。
|
||||
CLI 也可以执行同样的操作:
|
||||
Control UI 的 Logs 标签页通过 Gateway 网关跟随此文件(`logs.tail`)。
|
||||
CLI 也可以执行同样操作:
|
||||
|
||||
```bash
|
||||
openclaw logs --follow
|
||||
@ -42,15 +43,12 @@ openclaw logs --follow
|
||||
**详细模式与日志级别**
|
||||
|
||||
- **文件日志** 仅由 `logging.level` 控制。
|
||||
- `--verbose` 只影响 **控制台详细程度**(以及 WS 日志样式);它**不会**
|
||||
提高文件日志级别。
|
||||
- 如需在文件日志中捕获仅详细模式可见的细节,请将 `logging.level` 设置为 `debug` 或
|
||||
`trace`。
|
||||
- `--verbose` 只影响 **控制台详细程度**(以及 WS 日志样式);它 **不会** 提高文件日志级别。
|
||||
- 若要在文件日志中捕获仅详细模式可见的细节,请将 `logging.level` 设为 `debug` 或 `trace`。
|
||||
|
||||
## 控制台捕获
|
||||
|
||||
CLI 会捕获 `console.log/info/warn/error/debug/trace` 并将其写入文件日志,
|
||||
同时仍然输出到 stdout/stderr。
|
||||
CLI 会捕获 `console.log/info/warn/error/debug/trace` 并将其写入文件日志,同时仍然输出到 stdout/stderr。
|
||||
|
||||
你可以通过以下方式独立调整控制台详细程度:
|
||||
|
||||
@ -59,20 +57,19 @@ CLI 会捕获 `console.log/info/warn/error/debug/trace` 并将其写入文件日
|
||||
|
||||
## 工具摘要脱敏
|
||||
|
||||
详细的工具摘要(例如 `🛠️ Exec: ...`)在进入
|
||||
控制台流之前,可以屏蔽敏感令牌。这**仅适用于工具**,不会更改文件日志。
|
||||
详细的工具摘要(例如 `🛠️ Exec: ...`)可以在进入控制台流之前屏蔽敏感令牌。这 **仅适用于工具**,不会更改文件日志。
|
||||
|
||||
- `logging.redactSensitive`: `off` | `tools`(默认:`tools`)
|
||||
- `logging.redactPatterns`: 正则表达式字符串数组(覆盖默认值)
|
||||
- 使用原始正则字符串(自动加上 `gi`),或者在需要自定义标志时使用 `/pattern/flags`。
|
||||
- 匹配内容会被屏蔽:保留前 6 个字符 + 后 4 个字符(长度 >= 18),否则为 `***`。
|
||||
- 默认规则涵盖常见的密钥赋值、CLI 标志、JSON 字段、bearer 标头、PEM 块以及常见令牌前缀。
|
||||
- `logging.redactSensitive`:`off` | `tools`(默认:`tools`)
|
||||
- `logging.redactPatterns`:正则表达式字符串数组(覆盖默认值)
|
||||
- 使用原始正则字符串(自动加 `gi`),如果你需要自定义标志,也可以使用 `/pattern/flags`。
|
||||
- 匹配结果会被屏蔽:保留前 6 个字符 + 后 4 个字符(长度 >= 18),否则为 `***`。
|
||||
- 默认规则涵盖常见的密钥赋值、CLI 标志、JSON 字段、bearer 标头、PEM 块,以及常见的令牌前缀。
|
||||
|
||||
## Gateway 网关 WebSocket 日志
|
||||
|
||||
Gateway 网关会以两种模式打印 WebSocket 协议日志:
|
||||
Gateway 网关以两种模式打印 WebSocket 协议日志:
|
||||
|
||||
- **普通模式(不使用 `--verbose`)**:只打印“值得关注”的 RPC 结果:
|
||||
- **普通模式(不使用 `--verbose`)**:仅打印“重要”的 RPC 结果:
|
||||
- 错误(`ok=false`)
|
||||
- 慢调用(默认阈值:`>= 50ms`)
|
||||
- 解析错误
|
||||
@ -80,7 +77,7 @@ Gateway 网关会以两种模式打印 WebSocket 协议日志:
|
||||
|
||||
### WS 日志样式
|
||||
|
||||
`openclaw gateway` 支持按 Gateway 网关设置样式切换:
|
||||
`openclaw gateway` 支持按 Gateway 网关切换样式:
|
||||
|
||||
- `--ws-log auto`(默认):普通模式经过优化;详细模式使用紧凑输出
|
||||
- `--ws-log compact`:详细模式下使用紧凑输出(配对的请求/响应)
|
||||
@ -90,37 +87,37 @@ Gateway 网关会以两种模式打印 WebSocket 协议日志:
|
||||
示例:
|
||||
|
||||
```bash
|
||||
# optimized (only errors/slow)
|
||||
# 优化模式(仅错误/慢调用)
|
||||
openclaw gateway
|
||||
|
||||
# show all WS traffic (paired)
|
||||
# 显示所有 WS 流量(配对)
|
||||
openclaw gateway --verbose --ws-log compact
|
||||
|
||||
# show all WS traffic (full meta)
|
||||
# 显示所有 WS 流量(完整元数据)
|
||||
openclaw gateway --verbose --ws-log full
|
||||
```
|
||||
|
||||
## 控制台格式化(子系统日志)
|
||||
|
||||
控制台格式化器**可感知 TTY**,并打印一致的带前缀行。
|
||||
子系统日志记录器会让输出保持分组且易于浏览。
|
||||
控制台格式化器 **可感知 TTY**,并输出一致且带前缀的行。
|
||||
子系统日志记录器会让输出保持分组且易于扫描。
|
||||
|
||||
行为:
|
||||
|
||||
- 每行都有 **子系统前缀**(例如 `[gateway]`、`[canvas]`、`[tailscale]`)
|
||||
- **子系统颜色**(每个子系统固定)以及级别着色
|
||||
- **当输出为 TTY 或环境看起来像丰富终端时启用颜色**(`TERM`/`COLORTERM`/`TERM_PROGRAM`),并遵循 `NO_COLOR`
|
||||
- **缩短的子系统前缀**:去掉前导 `gateway/` 和 `channels/`,保留最后 2 段(例如 `whatsapp/outbound`)
|
||||
- **子系统颜色**(每个子系统保持稳定)以及级别颜色
|
||||
- 当输出为 TTY 或环境看起来像富终端时启用 **颜色**(`TERM` / `COLORTERM` / `TERM_PROGRAM`),并遵循 `NO_COLOR`
|
||||
- **缩短的子系统前缀**:去掉前导 `gateway/` + `channels/`,保留最后 2 个段(例如 `whatsapp/outbound`)
|
||||
- **按子系统划分的子日志记录器**(自动前缀 + 结构化字段 `{ subsystem }`)
|
||||
- 用于 QR/UX 输出的 **`logRaw()`**(无前缀、无格式化)
|
||||
- 用于 QR / UX 输出的 **`logRaw()`**(无前缀、无格式化)
|
||||
- **控制台样式**(例如 `pretty | compact | json`)
|
||||
- **控制台日志级别** 与文件日志级别分离(当 `logging.level` 设置为 `debug`/`trace` 时,文件仍保留完整细节)
|
||||
- **WhatsApp 消息正文** 记录在 `debug` 级别(使用 `--verbose` 可查看)
|
||||
- **控制台日志级别** 与文件日志级别分离(当 `logging.level` 设为 `debug` / `trace` 时,文件仍保留完整细节)
|
||||
- **WhatsApp 消息正文** 以 `debug` 级别记录(使用 `--verbose` 可查看)
|
||||
|
||||
这样可以在保持现有文件日志稳定的同时,让交互式输出更易于浏览。
|
||||
这样既能保持现有文件日志稳定,又能让交互式输出更易于扫描。
|
||||
|
||||
## 相关内容
|
||||
|
||||
- [日志](/zh-CN/logging)
|
||||
- [日志记录](/zh-CN/logging)
|
||||
- [OpenTelemetry 导出](/zh-CN/gateway/opentelemetry)
|
||||
- [诊断导出](/zh-CN/gateway/diagnostics)
|
||||
|
||||
@ -1,25 +1,25 @@
|
||||
---
|
||||
read_when:
|
||||
- 你需要一份面向初学者的 OpenClaw 日志概览
|
||||
- 你想要配置日志级别、格式或脱敏处理
|
||||
- 你想要配置日志级别、格式或敏感信息脱敏处理
|
||||
- 你正在进行故障排除,需要快速找到日志
|
||||
summary: 文件日志、控制台输出、CLI 尾部日志查看,以及 Control UI 的日志标签页
|
||||
summary: 文件日志、控制台输出、CLI 尾部输出,以及 Control UI 的日志标签页
|
||||
title: 日志
|
||||
x-i18n:
|
||||
generated_at: "2026-04-26T04:54:50Z"
|
||||
generated_at: "2026-04-26T06:01:23Z"
|
||||
model: gpt-5.4
|
||||
provider: openai
|
||||
source_hash: 3d4d32e4cdee429221c020fcb9e862e8f7c06f1e7973f36deac2a3476e8c31c8
|
||||
source_hash: 6fa55caa65a2a06a757e37ad64c5fd030f958cf6827596db5c183c6c6db2ed9b
|
||||
source_path: logging.md
|
||||
workflow: 15
|
||||
---
|
||||
|
||||
OpenClaw 有两个主要的日志界面:
|
||||
OpenClaw 有两个主要的日志显示面:
|
||||
|
||||
- 由 Gateway 网关写入的**文件日志**(JSON 行)。
|
||||
- 在终端和 Gateway 网关调试 UI 中显示的**控制台输出**。
|
||||
|
||||
Control UI 的**日志**标签页会尾随 gateway 文件日志。本页说明日志位于哪里、如何读取,以及如何配置日志级别和格式。
|
||||
Control UI 的**日志**标签页会对 gateway 文件日志执行尾部跟踪。本页说明日志位于哪里、如何读取日志,以及如何配置日志级别和格式。
|
||||
|
||||
## 日志位于哪里
|
||||
|
||||
@ -29,6 +29,8 @@ Control UI 的**日志**标签页会尾随 gateway 文件日志。本页说明
|
||||
|
||||
日期使用 gateway 主机的本地时区。
|
||||
|
||||
每个文件在达到 `logging.maxFileBytes`(默认值:100 MB)时会轮转。OpenClaw 会在活动文件旁边最多保留五个带编号的归档文件,例如 `openclaw-YYYY-MM-DD.1.log`,并继续写入一个新的活动日志文件,而不是抑制诊断信息。
|
||||
|
||||
你可以在 `~/.openclaw/openclaw.json` 中覆盖此设置:
|
||||
|
||||
```json
|
||||
@ -41,19 +43,19 @@ Control UI 的**日志**标签页会尾随 gateway 文件日志。本页说明
|
||||
|
||||
## 如何读取日志
|
||||
|
||||
### CLI:实时尾随(推荐)
|
||||
### CLI:实时尾部跟踪(推荐)
|
||||
|
||||
使用 CLI 通过 RPC 尾随 gateway 日志文件:
|
||||
使用 CLI 通过 RPC 对 gateway 日志文件执行尾部跟踪:
|
||||
|
||||
```bash
|
||||
openclaw logs --follow
|
||||
```
|
||||
|
||||
当前常用选项:
|
||||
当前实用选项:
|
||||
|
||||
- `--local-time`:以你的本地时区显示时间戳
|
||||
- `--url <url>` / `--token <token>` / `--timeout <ms>`:标准 Gateway 网关 RPC 标志
|
||||
- `--expect-final`:由智能体支持的 RPC 最终响应等待标志(此处通过共享客户端层接受)
|
||||
- `--local-time`:以你的本地时区渲染时间戳
|
||||
- `--url <url>` / `--token <token>` / `--timeout <ms>`:标准 Gateway RPC 标志
|
||||
- `--expect-final`:由智能体支持的 RPC 最终响应等待标志(通过共享客户端层在此处接受)
|
||||
|
||||
输出模式:
|
||||
|
||||
@ -63,16 +65,16 @@ openclaw logs --follow
|
||||
- `--plain`:在 TTY 会话中强制使用纯文本。
|
||||
- `--no-color`:禁用 ANSI 颜色。
|
||||
|
||||
当你传入显式的 `--url` 时,CLI 不会自动应用配置或环境变量凭证;如果目标 Gateway 网关需要认证,请自行包含 `--token`。
|
||||
当你传入显式的 `--url` 时,CLI 不会自动应用配置或环境变量凭证;如果目标 Gateway 网关需要身份验证,请自行附带 `--token`。
|
||||
|
||||
在 JSON 模式下,CLI 会输出带有 `type` 标记的对象:
|
||||
在 JSON 模式下,CLI 会输出带有 `type` 标签的对象:
|
||||
|
||||
- `meta`:流元数据(文件、游标、大小)
|
||||
- `log`:已解析的日志条目
|
||||
- `notice`:截断 / 轮转提示
|
||||
- `raw`:未解析的日志行
|
||||
|
||||
如果本地 local loopback Gateway 网关请求配对,`openclaw logs` 会自动回退到已配置的本地日志文件。显式 `--url` 目标不会使用此回退。
|
||||
如果 local loopback Gateway 网关请求配对,`openclaw logs` 会自动回退到已配置的本地日志文件。显式的 `--url` 目标不会使用此回退机制。
|
||||
|
||||
如果 Gateway 网关无法访问,CLI 会打印一条简短提示,建议运行:
|
||||
|
||||
@ -82,11 +84,11 @@ openclaw doctor
|
||||
|
||||
### Control UI(网页)
|
||||
|
||||
Control UI 的**日志**标签页会使用 `logs.tail` 尾随同一个文件。有关如何打开它,请参阅 [/web/control-ui](/zh-CN/web/control-ui)。
|
||||
Control UI 的**日志**标签页使用 `logs.tail` 对同一个文件执行尾部跟踪。如何打开它,请参阅 [/web/control-ui](/zh-CN/web/control-ui)。
|
||||
|
||||
### 仅渠道日志
|
||||
|
||||
要筛选渠道活动(WhatsApp/Telegram 等),请使用:
|
||||
如需筛选渠道活动(WhatsApp / Telegram 等),请使用:
|
||||
|
||||
```bash
|
||||
openclaw channels logs --channel whatsapp
|
||||
@ -100,21 +102,21 @@ openclaw channels logs --channel whatsapp
|
||||
|
||||
### 控制台输出
|
||||
|
||||
控制台日志会**感知 TTY**,并以便于阅读的方式格式化:
|
||||
控制台日志是**TTY 感知**的,并针对可读性进行了格式化:
|
||||
|
||||
- 子系统前缀(例如 `gateway/channels/whatsapp`)
|
||||
- 级别着色(info/warn/error)
|
||||
- 级别着色(info / warn / error)
|
||||
- 可选的紧凑模式或 JSON 模式
|
||||
|
||||
控制台格式由 `logging.consoleStyle` 控制。
|
||||
|
||||
### Gateway 网关 WebSocket 日志
|
||||
### Gateway WebSocket 日志
|
||||
|
||||
`openclaw gateway` 还提供用于 RPC 流量的 WebSocket 协议日志:
|
||||
|
||||
- 普通模式:仅记录值得关注的结果(错误、解析错误、慢调用)
|
||||
- `--verbose`:记录所有请求/响应流量
|
||||
- `--ws-log auto|compact|full`:选择详细日志的渲染样式
|
||||
- 普通模式:仅显示重要结果(错误、解析错误、慢调用)
|
||||
- `--verbose`:显示所有请求 / 响应流量
|
||||
- `--ws-log auto|compact|full`:选择详细渲染样式
|
||||
- `--compact`:`--ws-log compact` 的别名
|
||||
|
||||
示例:
|
||||
@ -127,7 +129,7 @@ openclaw gateway --verbose --ws-log full
|
||||
|
||||
## 配置日志
|
||||
|
||||
所有日志配置都位于 `~/.openclaw/openclaw.json` 中的 `logging` 下。
|
||||
所有日志配置都位于 `~/.openclaw/openclaw.json` 的 `logging` 下。
|
||||
|
||||
```json
|
||||
{
|
||||
@ -147,7 +149,7 @@ openclaw gateway --verbose --ws-log full
|
||||
- `logging.level`:**文件日志**(JSONL)级别。
|
||||
- `logging.consoleLevel`:**控制台**详细程度级别。
|
||||
|
||||
你可以通过 **`OPENCLAW_LOG_LEVEL`** 环境变量覆盖这两个设置(例如 `OPENCLAW_LOG_LEVEL=debug`)。该环境变量优先于配置文件,因此你可以在不编辑 `openclaw.json` 的情况下,仅针对单次运行提高详细程度。你也可以传入全局 CLI 选项 **`--log-level <level>`**(例如,`openclaw --log-level debug gateway run`),它会在该命令中覆盖环境变量。
|
||||
你可以通过 **`OPENCLAW_LOG_LEVEL`** 环境变量覆盖这两者(例如 `OPENCLAW_LOG_LEVEL=debug`)。该环境变量优先于配置文件,因此你可以在不编辑 `openclaw.json` 的情况下,仅为单次运行提高详细程度。你也可以传递全局 CLI 选项 **`--log-level <level>`**(例如 `openclaw --log-level debug gateway run`),它会为该命令覆盖环境变量。
|
||||
|
||||
`--verbose` 只影响控制台输出和 WS 日志详细程度;它不会更改文件日志级别。
|
||||
|
||||
@ -156,30 +158,28 @@ openclaw gateway --verbose --ws-log full
|
||||
`logging.consoleStyle`:
|
||||
|
||||
- `pretty`:适合人工阅读,带颜色和时间戳。
|
||||
- `compact`:输出更紧凑(最适合长时间会话)。
|
||||
- `compact`:更紧凑的输出(最适合长时间会话)。
|
||||
- `json`:每行一个 JSON(适用于日志处理器)。
|
||||
|
||||
### 脱敏
|
||||
### 脱敏处理
|
||||
|
||||
工具摘要可以在输出到控制台之前,对敏感令牌进行脱敏:
|
||||
|
||||
- `logging.redactSensitive`:`off` | `tools`(默认:`tools`)
|
||||
- `logging.redactSensitive`:`off` | `tools`(默认值:`tools`)
|
||||
- `logging.redactPatterns`:用于覆盖默认集合的正则表达式字符串列表
|
||||
|
||||
脱敏会在日志输出目标处应用于**控制台输出**、**路由到 stderr 的控制台诊断信息**以及**文件日志**。文件日志仍保持为 JSONL,但匹配的秘密值会在写入磁盘前被屏蔽。
|
||||
脱敏处理会在日志输出端应用于**控制台输出**、**路由到 stderr 的控制台诊断信息**以及**文件日志**。文件日志仍保持为 JSONL,但在将行写入磁盘之前,匹配的秘密值会被屏蔽。
|
||||
|
||||
## 诊断与 OpenTelemetry
|
||||
|
||||
诊断是用于模型运行和消息流遥测(webhook、队列、会话状态)的结构化、机器可读事件。它们**不会**替代日志——它们用于提供指标、追踪和导出器。无论你是否导出它们,事件都会在进程内发出。
|
||||
诊断是结构化、机器可读的事件,用于模型运行和消息流遥测(webhook、排队、会话状态)。它们**不会**取代日志——它们为指标、追踪和导出器提供输入。无论你是否导出它们,事件都会在进程内发出。
|
||||
|
||||
相邻的两个界面:
|
||||
两个相邻的显示面:
|
||||
|
||||
- **OpenTelemetry 导出**——通过 OTLP/HTTP 将指标、追踪和日志发送到任何兼容 OpenTelemetry 的收集器或后端(Grafana、Datadog、Honeycomb、New Relic、Tempo 等)。完整配置、信号目录、指标 / span 名称、环境变量和隐私模型位于专门页面:
|
||||
[OpenTelemetry 导出](/zh-CN/gateway/opentelemetry)。
|
||||
- **诊断标志**——将额外日志定向写入 `logging.file` 的定向调试日志标志,而无需提高 `logging.level`。标志不区分大小写,并支持通配符(`telegram.*`、`*`)。可在 `diagnostics.flags` 下配置,或通过 `OPENCLAW_DIAGNOSTICS=...` 环境变量覆盖。完整指南:
|
||||
[诊断标志](/zh-CN/diagnostics/flags)。
|
||||
- **OpenTelemetry 导出** —— 通过 OTLP / HTTP 将指标、追踪和日志发送到任何兼容 OpenTelemetry 的收集器或后端(Grafana、Datadog、Honeycomb、New Relic、Tempo 等)。完整配置、信号目录、指标 / span 名称、环境变量和隐私模型位于专门页面:[OpenTelemetry 导出](/zh-CN/gateway/opentelemetry)。
|
||||
- **诊断标志** —— 定向调试日志标志,可在不提高 `logging.level` 的情况下,将额外日志路由到 `logging.file`。标志不区分大小写,并支持通配符(`telegram.*`、`*`)。可在 `diagnostics.flags` 下配置,或通过 `OPENCLAW_DIAGNOSTICS=...` 环境变量覆盖。完整指南请参阅:[诊断标志](/zh-CN/diagnostics/flags)。
|
||||
|
||||
要在不使用 OTLP 导出的情况下,为插件或自定义输出目标启用诊断事件:
|
||||
如果你想为插件或自定义输出端启用诊断事件,而不使用 OTLP 导出:
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -187,17 +187,17 @@ openclaw gateway --verbose --ws-log full
|
||||
}
|
||||
```
|
||||
|
||||
有关导出到收集器的 OTLP,请参阅 [OpenTelemetry 导出](/zh-CN/gateway/opentelemetry)。
|
||||
如需将 OTLP 导出到收集器,请参阅 [OpenTelemetry 导出](/zh-CN/gateway/opentelemetry)。
|
||||
|
||||
## 故障排除提示
|
||||
|
||||
- **Gateway 网关无法访问?** 先运行 `openclaw doctor`。
|
||||
- **日志为空?** 检查 Gateway 网关是否正在运行,并正在写入 `logging.file` 中的文件路径。
|
||||
- **日志为空?** 检查 Gateway 网关是否正在运行,以及是否正在向 `logging.file` 中的文件路径写入。
|
||||
- **需要更多细节?** 将 `logging.level` 设置为 `debug` 或 `trace` 后重试。
|
||||
|
||||
## 相关内容
|
||||
|
||||
- [OpenTelemetry 导出](/zh-CN/gateway/opentelemetry) — OTLP/HTTP 导出、指标 / span 目录、隐私模型
|
||||
- [OpenTelemetry 导出](/zh-CN/gateway/opentelemetry) — OTLP / HTTP 导出、指标 / span 目录、隐私模型
|
||||
- [诊断标志](/zh-CN/diagnostics/flags) — 定向调试日志标志
|
||||
- [Gateway 网关日志内部机制](/zh-CN/gateway/logging) — WS 日志样式、子系统前缀和控制台捕获
|
||||
- [配置参考](/zh-CN/gateway/configuration-reference#diagnostics) — 完整的 `diagnostics.*` 字段参考
|
||||
|
||||
@ -1,108 +1,108 @@
|
||||
---
|
||||
read_when:
|
||||
- 实现提供商运行时钩子、渠道生命周期或包打包集合
|
||||
- 实现提供商运行时钩子、渠道生命周期或软件包打包
|
||||
- 调试插件加载顺序或注册表状态
|
||||
- 添加新的插件能力或上下文引擎插件
|
||||
summary: 插件架构内部机制:加载流水线、注册表、运行时钩子、HTTP 路由和参考表格
|
||||
title: 插件架构内部机制
|
||||
x-i18n:
|
||||
generated_at: "2026-04-26T00:16:05Z"
|
||||
generated_at: "2026-04-26T06:01:23Z"
|
||||
model: gpt-5.4
|
||||
provider: openai
|
||||
source_hash: b8d82e74fc30e47dc5d699c5cf2268a7a65f4e3871d06cb0a1936aede5591625
|
||||
source_hash: 9a435e118dc6acbacd44008f0b1c47b51da32dc3f17c24fe4c99f75c8cbd9311
|
||||
source_path: plugins/architecture-internals.md
|
||||
workflow: 15
|
||||
---
|
||||
|
||||
有关公开能力模型、插件形状以及所有权/执行契约,请参见 [插件架构](/zh-CN/plugins/architecture)。本页是内部机制的参考:加载流水线、注册表、运行时钩子、Gateway 网关 HTTP 路由、导入路径和模式表。
|
||||
关于公开的能力模型、插件形态以及所有权/执行契约,请参阅 [插件架构](/zh-CN/plugins/architecture)。本页是内部机制的参考:加载流水线、注册表、运行时钩子、Gateway 网关 HTTP 路由、导入路径和架构表格。
|
||||
|
||||
## 加载流水线
|
||||
|
||||
启动时,OpenClaw 大致会执行以下步骤:
|
||||
在启动时,OpenClaw 大致会执行以下步骤:
|
||||
|
||||
1. 发现候选插件根目录
|
||||
2. 读取原生或兼容 bundle 清单以及包元数据
|
||||
2. 读取原生或兼容 bundle 清单以及软件包元数据
|
||||
3. 拒绝不安全的候选项
|
||||
4. 规范化插件配置(`plugins.enabled`、`allow`、`deny`、`entries`、`slots`、`load.paths`)
|
||||
5. 为每个候选项决定是否启用
|
||||
6. 加载已启用的原生模块:已构建的内置模块使用原生加载器;未构建的原生插件使用 `jiti`
|
||||
7. 调用原生 `register(api)` 钩子,并将注册内容收集到插件注册表中
|
||||
8. 向命令/运行时表面暴露注册表
|
||||
8. 将注册表暴露给命令/运行时表面
|
||||
|
||||
<Note>
|
||||
`activate` 是 `register` 的旧别名——加载器会解析其中存在的那个(`def.register ?? def.activate`),并在同一时机调用它。所有内置插件都使用 `register`;新插件优先使用 `register`。
|
||||
`activate` 是 `register` 的旧别名——加载器会解析当前存在的那个(`def.register ?? def.activate`),并在同一时机调用。所有内置插件都使用 `register`;新插件优先使用 `register`。
|
||||
</Note>
|
||||
|
||||
安全门控会在运行时执行**之前**发生。当入口逃逸出插件根目录、路径可被所有用户写入,或对于非内置插件来说路径所有权看起来可疑时,候选项会被阻止。
|
||||
安全门控发生在运行时执行**之前**。当入口逃逸出插件根目录、路径对所有人可写,或对于非内置插件而言路径所有权看起来可疑时,候选项会被阻止。
|
||||
|
||||
### Manifest-first 行为
|
||||
|
||||
清单是控制平面的事实来源。OpenClaw 使用它来:
|
||||
manifest 是控制平面的事实来源。OpenClaw 用它来:
|
||||
|
||||
- 标识插件
|
||||
- 发现声明的渠道/Skills/配置模式或 bundle 能力
|
||||
- 发现已声明的渠道/Skills/配置 schema 或 bundle 能力
|
||||
- 验证 `plugins.entries.<id>.config`
|
||||
- 增强 Control UI 标签/占位符
|
||||
- 补充 Control UI 标签/占位符
|
||||
- 显示安装/目录元数据
|
||||
- 在不加载插件运行时的情况下保留低成本激活和设置描述符
|
||||
- 在不加载插件运行时的情况下保留轻量激活和设置描述符
|
||||
|
||||
对于原生插件,运行时模块是数据平面部分。它会注册实际行为,例如钩子、工具、命令或提供商流程。
|
||||
|
||||
可选的清单 `activation` 和 `setup` 块仍然保留在控制平面。它们只是用于激活规划和设置发现的纯元数据描述符;它们不会替代运行时注册、`register(...)` 或 `setupEntry`。
|
||||
现在,首批实时激活使用方会利用清单中的命令、渠道和提供商提示,在更广泛的注册表实体化之前先缩小插件加载范围:
|
||||
可选的 manifest `activation` 和 `setup` 代码块仍然位于控制平面。它们只是激活规划和设置发现的纯元数据描述符;它们不会替代运行时注册、`register(...)` 或 `setupEntry`。
|
||||
首批实时激活使用方现在会使用 manifest 中的命令、渠道和提供商提示,在更广泛的注册表实体化之前缩小插件加载范围:
|
||||
|
||||
- CLI 加载会缩小到拥有所请求主命令的插件
|
||||
- 渠道设置/插件解析会缩小到拥有所请求渠道 id 的插件
|
||||
- 显式提供商设置/运行时解析会缩小到拥有所请求提供商 id 的插件
|
||||
- 显式的提供商设置/运行时解析会缩小到拥有所请求提供商 id 的插件
|
||||
|
||||
激活规划器既为现有调用方暴露仅含 id 的 API,也为新的诊断暴露 plan API。Plan 条目会报告某个插件为何被选中,并将显式 `activation.*` 规划提示与基于清单归属的回退原因分开,例如 `providers`、`channels`、`commandAliases`、`setup.providers`、`contracts.tools` 和 hooks。这种原因拆分是兼容性边界:现有插件元数据仍然有效,而新代码无需改变运行时加载语义,就可以检测宽泛提示或回退行为。
|
||||
激活规划器同时为现有调用方提供仅含 id 的 API,也为新的诊断场景提供计划 API。计划项会报告插件为何被选中,并将显式的 `activation.*` 规划器提示与基于 manifest 所有权的回退原因分开,例如 `providers`、`channels`、`commandAliases`、`setup.providers`、`contracts.tools` 和 hooks。这种原因拆分就是兼容性边界:现有插件元数据仍可继续工作,而新代码可以检测宽泛提示或回退行为,而无需改变运行时加载语义。
|
||||
|
||||
设置发现现在优先使用描述符拥有的 id,例如 `setup.providers` 和 `setup.cliBackends`,以便在回退到 `setup-api` 之前先缩小候选插件范围;`setup-api` 仅用于那些仍然需要设置时运行时钩子的插件。提供商设置流程会优先使用清单 `providerAuthChoices`,然后为了兼容性再回退到运行时向导选项和安装目录选项。显式的 `setup.requiresRuntime: false` 是一个仅描述符层面的截止点;省略 `requiresRuntime` 则会为了兼容性保留旧版 `setup-api` 回退。如果发现的多个插件声明了同一个规范化后的设置提供商或 CLI 后端 id,设置查找会拒绝这个存在歧义的归属者,而不是依赖发现顺序。当设置运行时确实执行时,注册表诊断会报告 `setup.providers` / `setup.cliBackends` 与由 `setup-api` 注册的提供商或 CLI 后端之间的漂移,但不会阻止旧版插件。
|
||||
设置发现现在会优先使用描述符拥有的 id,例如 `setup.providers` 和 `setup.cliBackends`,以在回退到 `setup-api` 之前缩小候选插件范围;而 `setup-api` 仅用于那些在设置时仍需要运行时钩子的插件。提供商设置列表会使用 manifest `providerAuthChoices`、从描述符派生的设置选项,以及安装目录元数据,而无需加载提供商运行时。显式的 `setup.requiresRuntime: false` 是仅描述符层面的截断;如果省略 `requiresRuntime`,则会保留旧版 `setup-api` 回退以维持兼容性。如果有多个已发现插件声称拥有同一个规范化后的设置提供商或 CLI backend id,设置查找会拒绝这个歧义所有者,而不是依赖发现顺序。当设置运行时确实执行时,注册表诊断会报告 `setup.providers` / `setup.cliBackends` 与由 `setup-api` 注册的提供商或 CLI backends 之间的漂移,但不会阻止旧版插件。
|
||||
|
||||
### 加载器会缓存什么
|
||||
|
||||
OpenClaw 会保留一些短生命周期的进程内缓存,用于:
|
||||
OpenClaw 会保留以下短生命周期的进程内缓存:
|
||||
|
||||
- 发现结果
|
||||
- 清单注册表数据
|
||||
- manifest 注册表数据
|
||||
- 已加载的插件注册表
|
||||
|
||||
这些缓存可减少突发式启动开销和重复命令开销。可以将它们视为短生命周期的性能缓存,而不是持久化机制。
|
||||
这些缓存可减少突发启动和重复命令的开销。你可以把它们安全地理解为短期性能缓存,而不是持久化。
|
||||
|
||||
性能说明:
|
||||
|
||||
- 设置 `OPENCLAW_DISABLE_PLUGIN_DISCOVERY_CACHE=1` 或 `OPENCLAW_DISABLE_PLUGIN_MANIFEST_CACHE=1` 可禁用这些缓存。
|
||||
- 可使用 `OPENCLAW_PLUGIN_DISCOVERY_CACHE_MS` 和 `OPENCLAW_PLUGIN_MANIFEST_CACHE_MS` 调整缓存窗口。
|
||||
- 使用 `OPENCLAW_PLUGIN_DISCOVERY_CACHE_MS` 和 `OPENCLAW_PLUGIN_MANIFEST_CACHE_MS` 调整缓存窗口。
|
||||
|
||||
## 注册表模型
|
||||
|
||||
已加载的插件不会直接修改任意核心全局状态。它们会注册到一个中心插件注册表中。
|
||||
已加载的插件不会直接修改任意核心全局状态。它们会注册到一个中央插件注册表中。
|
||||
|
||||
注册表会跟踪:
|
||||
|
||||
- 插件记录(身份、来源、起源、状态、诊断)
|
||||
- 插件记录(身份、来源、源头、Status、诊断)
|
||||
- 工具
|
||||
- 旧版钩子和类型化钩子
|
||||
- 旧版 hooks 和类型化 hooks
|
||||
- 渠道
|
||||
- 提供商
|
||||
- Gateway 网关 RPC 处理器
|
||||
- gateway RPC 处理器
|
||||
- HTTP 路由
|
||||
- CLI 注册器
|
||||
- 后台服务
|
||||
- 插件拥有的命令
|
||||
|
||||
随后,核心功能会从这个注册表中读取,而不是直接与插件模块交互。这样可保持单向加载:
|
||||
随后,核心功能会从这个注册表中读取,而不是直接与插件模块通信。这样可保持单向加载:
|
||||
|
||||
- 插件模块 -> 注册表注册
|
||||
- 核心运行时 -> 注册表消费
|
||||
|
||||
这种分离对可维护性很重要。它意味着大多数核心表面只需要一个集成点:“读取注册表”,而不是“为每个插件模块做特殊处理”。
|
||||
这种分离对于可维护性很重要。它意味着大多数核心表面只需要一个集成点:“读取注册表”,而不是“为每个插件模块做特殊处理”。
|
||||
|
||||
## 对话绑定回调
|
||||
## 会话绑定回调
|
||||
|
||||
绑定对话的插件可以在审批被解决时作出响应。
|
||||
绑定会话的插件可以在审批结果确定时作出响应。
|
||||
|
||||
使用 `api.onConversationBindingResolved(...)` 可在绑定请求被批准或拒绝后接收回调:
|
||||
使用 `api.onConversationBindingResolved(...)` 可在绑定请求获批或被拒后接收回调:
|
||||
|
||||
```ts
|
||||
export default {
|
||||
@ -110,12 +110,12 @@ export default {
|
||||
register(api) {
|
||||
api.onConversationBindingResolved(async (event) => {
|
||||
if (event.status === "approved") {
|
||||
// 此插件 + 对话现在已有绑定。
|
||||
// 现在已为此插件 + 会话创建了一个绑定。
|
||||
console.log(event.binding?.conversationId);
|
||||
return;
|
||||
}
|
||||
|
||||
// 请求被拒绝;清除任何本地挂起状态。
|
||||
// 请求被拒绝;清除任何本地待处理状态。
|
||||
console.log(event.request.conversation.conversationId);
|
||||
});
|
||||
},
|
||||
@ -126,87 +126,87 @@ export default {
|
||||
|
||||
- `status`:`"approved"` 或 `"denied"`
|
||||
- `decision`:`"allow-once"`、`"allow-always"` 或 `"deny"`
|
||||
- `binding`:已批准请求的已解析绑定
|
||||
- `request`:原始请求摘要、分离提示、发送方 id 和对话元数据
|
||||
- `binding`:已获批请求对应的已解析绑定
|
||||
- `request`:原始请求摘要、分离提示、发送者 id 和会话元数据
|
||||
|
||||
此回调仅用于通知。它不会改变谁被允许绑定对话,并且会在核心审批处理完成后运行。
|
||||
此回调仅用于通知。它不会改变谁被允许绑定会话,并且它会在核心审批处理完成后运行。
|
||||
|
||||
## 提供商运行时钩子
|
||||
|
||||
提供商插件有三层:
|
||||
|
||||
- **清单元数据**,用于低成本的运行时前查找:
|
||||
- **Manifest 元数据**,用于廉价的运行前查找:
|
||||
`setup.providers[].envVars`、已弃用的兼容项 `providerAuthEnvVars`、
|
||||
`providerAuthAliases`、`providerAuthChoices` 和 `channelEnvVars`。
|
||||
- **配置时钩子**:`catalog`(旧称 `discovery`)以及
|
||||
`applyConfigDefaults`。
|
||||
- **运行时钩子**:40 多个可选钩子,涵盖认证、模型解析、
|
||||
流包装、思考级别、重放策略和用量端点。完整列表请参见
|
||||
流包装、思考级别、重放策略和用量端点。完整列表请参阅
|
||||
[钩子顺序和用法](#hook-order-and-usage)。
|
||||
|
||||
OpenClaw 仍然负责通用智能体循环、故障切换、转录处理和工具策略。这些钩子是提供商特定行为的扩展表面,无需为此实现完整的自定义推理传输。
|
||||
OpenClaw 仍然负责通用的智能体循环、故障切换、转录处理和工具策略。这些钩子是提供商特定行为的扩展表面,无需为此实现一整套自定义推理传输。
|
||||
|
||||
当提供商具有基于环境变量的凭证,并且通用认证/Status/模型选择器路径需要在不加载插件运行时的情况下看到这些凭证时,请使用清单 `setup.providers[].envVars`。已弃用的 `providerAuthEnvVars` 在弃用窗口期间仍会由兼容适配器读取,而使用它的非内置插件会收到清单诊断。当一个提供商 id 需要复用另一个提供商 id 的环境变量、认证配置文件、基于配置的认证以及 API 密钥新手引导选项时,请使用清单 `providerAuthAliases`。当新手引导/认证选项 CLI 表面需要在不加载提供商运行时的情况下了解该提供商的 choice id、分组标签和简单的单标志认证接线时,请使用清单 `providerAuthChoices`。将提供商运行时 `envVars` 保留给面向运维人员的提示,例如新手引导标签或 OAuth client-id/client-secret 设置变量。
|
||||
当提供商具有基于环境变量的凭证,并且你希望通用的认证/Status/模型选择器路径在不加载插件运行时的情况下也能看到这些凭证时,请使用 manifest `setup.providers[].envVars`。在弃用窗口期内,已弃用的 `providerAuthEnvVars` 仍会由兼容适配器读取,而使用它的非内置插件会收到一条 manifest 诊断。当一个提供商 id 应复用另一个提供商 id 的环境变量、认证配置文件、基于配置的认证和 API key 新手引导选项时,请使用 manifest `providerAuthAliases`。当新手引导/认证选项 CLI 表面需要在不加载提供商运行时的情况下了解该提供商的选项 id、分组标签以及简单的单标志认证接线时,请使用 manifest `providerAuthChoices`。提供商运行时中的 `envVars` 则应保留给面向运维者的提示,例如新手引导标签或 OAuth client-id/client-secret 设置变量。
|
||||
|
||||
当某个渠道具有由环境变量驱动的认证或设置,并且通用 shell 环境变量回退、配置/Status 检查或设置提示需要在不加载渠道运行时的情况下看到这些内容时,请使用清单 `channelEnvVars`。
|
||||
当某个渠道具有由环境变量驱动的认证或设置,并且你希望通用 shell 环境变量回退、配置/Status 检查或设置提示在不加载渠道运行时的情况下也能看到这些内容时,请使用 manifest `channelEnvVars`。
|
||||
|
||||
### 钩子顺序和用法
|
||||
|
||||
对于模型/提供商插件,OpenClaw 会大致按以下顺序调用钩子。
|
||||
“何时使用”列是快速决策指南。
|
||||
对于模型/提供商插件,OpenClaw 会按以下大致顺序调用钩子。
|
||||
“何时使用”这一列是快速决策指南。
|
||||
|
||||
| # | 钩子 | 作用 | 何时使用 |
|
||||
| # | 钩子 | 作用 | 何时使用 |
|
||||
| --- | --------------------------------- | -------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| 1 | `catalog` | 在生成 `models.json` 期间,将提供商配置发布到 `models.providers` 中 | 提供商拥有目录或 base URL 默认值 |
|
||||
| 2 | `applyConfigDefaults` | 在配置实体化期间应用由提供商拥有的全局配置默认值 | 默认值依赖于认证模式、环境变量或提供商模型族语义 |
|
||||
| -- | _(内置模型查找)_ | OpenClaw 会先尝试正常的注册表/目录路径 | _(不是插件钩子)_ |
|
||||
| 3 | `normalizeModelId` | 在查找之前规范化旧版或预览版 model-id 别名 | 提供商在规范模型解析之前拥有别名清理逻辑 |
|
||||
| 4 | `normalizeTransport` | 在通用模型组装之前,规范化提供商族的 `api` / `baseUrl` | 提供商为同一传输族中的自定义提供商 id 拥有传输清理逻辑 |
|
||||
| 5 | `normalizeConfig` | 在运行时/提供商解析之前规范化 `models.providers.<id>` | 提供商需要应与插件放在一起的配置清理;内置的 Google 族辅助逻辑也会为受支持的 Google 配置项提供兜底 |
|
||||
| 6 | `applyNativeStreamingUsageCompat` | 将原生流式用量兼容性重写应用到配置提供商 | 提供商需要基于端点驱动的原生流式用量元数据修复 |
|
||||
| 7 | `resolveConfigApiKey` | 在加载运行时认证之前,为配置提供商解析环境变量标记认证 | 提供商拥有环境变量标记 API 密钥解析逻辑;`amazon-bedrock` 在这里也有一个内置的 AWS 环境变量标记解析器 |
|
||||
| 8 | `resolveSyntheticAuth` | 在不持久化明文的情况下暴露 local/self-hosted 或基于配置的认证 | 提供商可以使用合成/local 凭证标记运行 |
|
||||
| 9 | `resolveExternalAuthProfiles` | 叠加由提供商拥有的外部认证配置文件;CLI/应用拥有的凭证默认 `persistence` 为 `runtime-only` | 提供商会复用外部认证凭证,而不持久化复制的刷新令牌;请在清单中声明 `contracts.externalAuthProviders` |
|
||||
| 10 | `shouldDeferSyntheticProfileAuth` | 将已存储的合成配置文件占位符降级到环境变量/基于配置的认证之后 | 提供商会存储不应获得优先级的合成占位配置文件 |
|
||||
| 11 | `resolveDynamicModel` | 对尚未进入本地注册表的、由提供商拥有的模型 id 进行同步回退解析 | 提供商接受任意上游模型 id |
|
||||
| 12 | `prepareDynamicModel` | 先进行异步预热,然后再次运行 `resolveDynamicModel` | 提供商在解析未知 id 之前需要网络元数据 |
|
||||
| 13 | `normalizeResolvedModel` | 在嵌入式运行器使用已解析模型之前执行最终重写 | 提供商需要传输重写,但仍使用核心传输 |
|
||||
| 14 | `contributeResolvedModelCompat` | 为位于其他兼容传输之后的供应商模型贡献兼容标记 | 提供商可以在代理传输上识别自己的模型,而无需接管该提供商 |
|
||||
| 15 | `capabilities` | 由提供商拥有、供共享核心逻辑使用的转录/工具元数据 | 提供商需要转录或提供商族特有的特殊处理 |
|
||||
| 16 | `normalizeToolSchemas` | 在嵌入式运行器看到工具模式之前先规范化它们 | 提供商需要传输族级别的模式清理 |
|
||||
| 17 | `inspectToolSchemas` | 在规范化之后暴露由提供商拥有的模式诊断 | 提供商希望给出关键字警告,而无需让核心理解提供商特定规则 |
|
||||
| 18 | `resolveReasoningOutputMode` | 选择原生推理输出契约还是带标签的推理输出契约 | 提供商需要带标签的推理/最终输出,而不是原生字段 |
|
||||
| 19 | `prepareExtraParams` | 在通用流选项包装器之前规范化请求参数 | 提供商需要默认请求参数或按提供商进行参数清理 |
|
||||
| 20 | `createStreamFn` | 用自定义传输完全替换正常的流路径 | 提供商需要自定义线协议,而不仅仅是包装器 |
|
||||
| 21 | `wrapStreamFn` | 在应用通用包装器之后包装流函数 | 提供商需要请求头/请求体/模型兼容性包装器,而不是自定义传输 |
|
||||
| 22 | `resolveTransportTurnState` | 附加原生的逐轮传输头或元数据 | 提供商希望通用传输发送提供商原生的轮次标识 |
|
||||
| 23 | `resolveWebSocketSessionPolicy` | 附加原生 WebSocket 头或会话冷却策略 | 提供商希望通用 WS 传输调整会话头或回退策略 |
|
||||
| 24 | `formatApiKey` | 认证配置文件格式化器:已存储配置文件会变成运行时 `apiKey` 字符串 | 提供商会存储额外的认证元数据,并需要自定义运行时令牌形状 |
|
||||
| 25 | `refreshOAuth` | 为自定义刷新端点或刷新失败策略覆写 OAuth 刷新逻辑 | 提供商不适配共享的 `pi-ai` 刷新器 |
|
||||
| 26 | `buildAuthDoctorHint` | 当 OAuth 刷新失败时附加修复提示 | 提供商在刷新失败后需要由提供商拥有的认证修复指导 |
|
||||
| 27 | `matchesContextOverflowError` | 由提供商拥有的上下文窗口溢出匹配器 | 提供商存在通用启发式无法捕获的原始溢出错误 |
|
||||
| 28 | `classifyFailoverReason` | 由提供商拥有的故障切换原因分类 | 提供商可以将原始 API/传输错误映射为速率限制/过载等 |
|
||||
| 29 | `isCacheTtlEligible` | 面向代理/回传提供商的提示缓存策略 | 提供商需要代理特定的缓存 TTL 门控 |
|
||||
| 30 | `buildMissingAuthMessage` | 替换通用的缺失认证恢复消息 | 提供商需要提供商特定的缺失认证恢复提示 |
|
||||
| 31 | `suppressBuiltInModel` | 过时上游模型抑制,并可附带面向用户的错误提示 | 提供商需要隐藏过时的上游条目,或用供应商提示替换它们 |
|
||||
| 32 | `augmentModelCatalog` | 在发现之后附加合成/最终目录条目 | 提供商需要在 `models list` 和选择器中加入面向未来兼容的合成条目 |
|
||||
| 33 | `resolveThinkingProfile` | 为特定模型设置 `/think` 级别、显示标签和默认值 | 提供商为选定模型公开自定义思考阶梯或二元标签 |
|
||||
| 34 | `isBinaryThinking` | 开/关推理切换兼容性钩子 | 提供商只公开二元的思考开/关 |
|
||||
| 35 | `supportsXHighThinking` | `xhigh` 推理支持兼容性钩子 | 提供商希望仅在部分模型上启用 `xhigh` |
|
||||
| 36 | `resolveDefaultThinkingLevel` | 默认 `/think` 级别兼容性钩子 | 提供商拥有某个模型族的默认 `/think` 策略 |
|
||||
| 37 | `isModernModelRef` | 用于实时配置文件过滤和 smoke 选择的现代模型匹配器 | 提供商拥有实时/smoke 首选模型匹配逻辑 |
|
||||
| 38 | `prepareRuntimeAuth` | 在推理之前,将已配置凭证交换为实际运行时令牌/密钥 | 提供商需要令牌交换或短生命周期请求凭证 |
|
||||
| 39 | `resolveUsageAuth` | 为 `/usage` 和相关 Status 表面解析用量/计费凭证 | 提供商需要自定义用量/配额令牌解析,或使用不同的用量凭证 |
|
||||
| 40 | `fetchUsageSnapshot` | 在认证解析完成后,获取并规范化提供商特定的用量/配额快照 | 提供商需要提供商特定的用量端点或负载解析器 |
|
||||
| 41 | `createEmbeddingProvider` | 为 Memory Wiki/搜索构建由提供商拥有的嵌入适配器 | Memory Wiki 嵌入行为应归属于提供商插件 |
|
||||
| 42 | `buildReplayPolicy` | 返回一个重放策略,用于控制该提供商的转录处理 | 提供商需要自定义转录策略(例如剥离 thinking 块) |
|
||||
| 43 | `sanitizeReplayHistory` | 在通用转录清理之后重写重放历史 | 提供商需要超出共享压缩辅助逻辑之外的提供商特定重放重写 |
|
||||
| 44 | `validateReplayTurns` | 在嵌入式运行器之前,对重放轮次进行最终验证或重塑 | 提供商传输在通用净化之后需要更严格的轮次验证 |
|
||||
| 45 | `onModelSelected` | 在模型被选中后运行由提供商拥有的副作用 | 当模型变为活动状态时,提供商需要遥测或由提供商拥有的状态 |
|
||||
| 1 | `catalog` | 在生成 `models.json` 期间,将提供商配置发布到 `models.providers` 中 | 提供商拥有目录,或拥有 base URL 默认值 |
|
||||
| 2 | `applyConfigDefaults` | 在配置实体化期间应用由提供商拥有的全局配置默认值 | 默认值取决于认证模式、环境变量或提供商模型家族语义 |
|
||||
| -- | _(内置模型查找)_ | OpenClaw 会先尝试常规的注册表/目录路径 | _(不是插件钩子)_ |
|
||||
| 3 | `normalizeModelId` | 在查找之前规范化旧版或预览版 model-id 别名 | 提供商负责在规范模型解析之前清理别名 |
|
||||
| 4 | `normalizeTransport` | 在通用模型组装之前规范化提供商家族的 `api` / `baseUrl` | 提供商负责清理同一传输家族中自定义提供商 id 的传输配置 |
|
||||
| 5 | `normalizeConfig` | 在运行时/提供商解析之前规范化 `models.providers.<id>` | 提供商需要与插件放在一起的配置清理;内置的 Google 家族辅助逻辑也会为受支持的 Google 配置项提供兜底 |
|
||||
| 6 | `applyNativeStreamingUsageCompat` | 对配置提供商应用原生流式用量兼容性重写 | 提供商需要基于端点驱动的原生流式用量元数据修复 |
|
||||
| 7 | `resolveConfigApiKey` | 在加载运行时认证之前,为配置提供商解析环境变量标记认证 | 提供商拥有自己的环境变量标记 API key 解析逻辑;`amazon-bedrock` 在这里也有一个内置的 AWS 环境变量标记解析器 |
|
||||
| 8 | `resolveSyntheticAuth` | 暴露 local/self-hosted 或基于配置的认证,而不持久化明文 | 提供商可以使用 synthetic/local 凭证标记运行 |
|
||||
| 9 | `resolveExternalAuthProfiles` | 叠加由提供商拥有的外部认证配置文件;CLI/应用拥有的凭证默认 `persistence` 为 `runtime-only` | 提供商复用外部认证凭证,而不持久化复制的 refresh token;请在 manifest 中声明 `contracts.externalAuthProviders` |
|
||||
| 10 | `shouldDeferSyntheticProfileAuth` | 将已存储的 synthetic 配置文件占位符优先级降到环境变量/基于配置的认证之后 | 提供商会存储 synthetic 占位配置文件,而这些占位项不应获得更高优先级 |
|
||||
| 11 | `resolveDynamicModel` | 为尚未在本地注册表中的、由提供商拥有的模型 id 提供同步回退 | 提供商接受任意上游模型 id |
|
||||
| 12 | `prepareDynamicModel` | 先进行异步预热,然后再次运行 `resolveDynamicModel` | 提供商在解析未知 id 之前需要网络元数据 |
|
||||
| 13 | `normalizeResolvedModel` | 在嵌入式运行器使用已解析模型之前进行最终重写 | 提供商需要进行传输重写,但仍使用核心传输 |
|
||||
| 14 | `contributeResolvedModelCompat` | 为位于另一兼容传输之后的厂商模型提供兼容性标志 | 提供商可以在不接管该提供商的情况下,在代理传输上识别自己的模型 |
|
||||
| 15 | `capabilities` | 由提供商拥有、供共享核心逻辑使用的转录/工具元数据 | 提供商需要转录或提供商家族特有的兼容逻辑 |
|
||||
| 16 | `normalizeToolSchemas` | 在嵌入式运行器看到工具 schema 之前对其进行规范化 | 提供商需要传输家族层面的 schema 清理 |
|
||||
| 17 | `inspectToolSchemas` | 在规范化之后暴露由提供商拥有的 schema 诊断 | 提供商希望输出关键字警告,而不需要让核心理解特定于提供商的规则 |
|
||||
| 18 | `resolveReasoningOutputMode` | 选择原生推理输出契约还是带标签的推理输出契约 | 提供商需要使用带标签的推理/最终输出,而不是原生字段 |
|
||||
| 19 | `prepareExtraParams` | 在通用流选项包装器之前,对请求参数进行规范化 | 提供商需要默认请求参数,或按提供商进行参数清理 |
|
||||
| 20 | `createStreamFn` | 用自定义传输完全替换正常的流路径 | 提供商需要自定义线协议,而不仅仅是包装器 |
|
||||
| 21 | `wrapStreamFn` | 在应用通用包装器之后对流函数进行包装 | 提供商需要请求头/请求体/模型兼容包装器,但不需要自定义传输 |
|
||||
| 22 | `resolveTransportTurnState` | 附加原生的逐轮传输头或元数据 | 提供商希望通用传输发送提供商原生的轮次身份信息 |
|
||||
| 23 | `resolveWebSocketSessionPolicy` | 附加原生 WebSocket 请求头或会话冷却策略 | 提供商希望通用 WS 传输调整会话请求头或回退策略 |
|
||||
| 24 | `formatApiKey` | 认证配置文件格式化器:将已存储配置文件转换为运行时 `apiKey` 字符串 | 提供商会存储额外的认证元数据,并需要自定义运行时 token 形态 |
|
||||
| 25 | `refreshOAuth` | 为自定义刷新端点或刷新失败策略覆盖 OAuth 刷新逻辑 | 提供商不适配共享的 `pi-ai` 刷新器 |
|
||||
| 26 | `buildAuthDoctorHint` | 当 OAuth 刷新失败时附加修复提示 | 提供商需要在刷新失败后给出由提供商拥有的认证修复指引 |
|
||||
| 27 | `matchesContextOverflowError` | 由提供商拥有的上下文窗口溢出匹配器 | 提供商存在通用启发式无法捕捉的原始溢出错误 |
|
||||
| 28 | `classifyFailoverReason` | 由提供商拥有的故障切换原因分类 | 提供商可以将原始 API/传输错误映射为速率限制、过载等原因 |
|
||||
| 29 | `isCacheTtlEligible` | 面向代理/回程提供商的提示缓存策略 | 提供商需要代理特定的缓存 TTL 门控 |
|
||||
| 30 | `buildMissingAuthMessage` | 用于替换通用缺失认证恢复消息 | 提供商需要提供商特定的缺失认证恢复提示 |
|
||||
| 31 | `suppressBuiltInModel` | 抑制过时的上游模型,并可选择提供面向用户的错误提示 | 提供商需要隐藏过时的上游条目,或用厂商提示替换它们 |
|
||||
| 32 | `augmentModelCatalog` | 在发现之后附加 synthetic/最终目录条目 | 提供商需要在 `models list` 和选择器中提供 synthetic 的前向兼容条目 |
|
||||
| 33 | `resolveThinkingProfile` | 为特定模型设置 `/think` 级别、显示标签和默认值 | 提供商为选定模型暴露自定义思考层级,或二元标签 |
|
||||
| 34 | `isBinaryThinking` | 开/关推理切换兼容钩子 | 提供商只暴露二元的思考开/关 |
|
||||
| 35 | `supportsXHighThinking` | `xhigh` 推理支持兼容钩子 | 提供商只希望在部分模型上启用 `xhigh` |
|
||||
| 36 | `resolveDefaultThinkingLevel` | 默认 `/think` 级别兼容钩子 | 提供商拥有某个模型家族的默认 `/think` 策略 |
|
||||
| 37 | `isModernModelRef` | 用于实时配置文件过滤和 smoke 选择的现代模型匹配器 | 提供商拥有实时/smoke 首选模型匹配逻辑 |
|
||||
| 38 | `prepareRuntimeAuth` | 在推理之前,将已配置的凭证交换为实际运行时 token/key | 提供商需要进行 token 交换,或需要短生命周期的请求凭证 |
|
||||
| 39 | `resolveUsageAuth` | 为 `/usage` 和相关 Status 表面解析用量/计费凭证 | 提供商需要自定义用量/配额 token 解析,或需要不同的用量凭证 |
|
||||
| 40 | `fetchUsageSnapshot` | 在认证解析完成后获取并规范化特定于提供商的用量/配额快照 | 提供商需要提供商特定的用量端点或负载解析器 |
|
||||
| 41 | `createEmbeddingProvider` | 为内存/搜索构建由提供商拥有的嵌入适配器 | 内存嵌入行为应归属于提供商插件 |
|
||||
| 42 | `buildReplayPolicy` | 返回一个重放策略,用于控制该提供商的转录处理 | 提供商需要自定义转录策略(例如剥离 thinking block) |
|
||||
| 43 | `sanitizeReplayHistory` | 在通用转录清理之后重写重放历史 | 提供商需要在共享压缩辅助逻辑之外,执行特定于提供商的重放重写 |
|
||||
| 44 | `validateReplayTurns` | 在嵌入式运行器执行之前,对重放轮次做最终验证或重塑 | 提供商传输在通用清理之后需要更严格的轮次验证 |
|
||||
| 45 | `onModelSelected` | 运行由提供商拥有的模型选定后副作用 | 当模型变为活动状态时,提供商需要遥测或由提供商拥有的状态 |
|
||||
|
||||
`normalizeModelId`、`normalizeTransport` 和 `normalizeConfig` 会先检查匹配到的提供商插件,然后继续尝试其他具备相应钩子能力的提供商插件,直到有一个实际更改了模型 id 或传输/配置。这样可以让别名/兼容性提供商 shim 正常工作,而无需调用方知道是哪个内置插件拥有该重写逻辑。如果没有任何提供商钩子重写受支持的 Google 族配置项,内置的 Google 配置规范化器仍会应用该兼容性清理。
|
||||
`normalizeModelId`、`normalizeTransport` 和 `normalizeConfig` 会先检查匹配到的提供商插件,然后继续检查其他具备相应钩子能力的提供商插件,直到某个插件实际更改了模型 id 或传输/配置为止。这使得别名/兼容性提供商 shim 能继续工作,而不需要调用方知道究竟是哪个内置插件拥有该重写逻辑。如果没有任何提供商钩子重写受支持的 Google 家族配置项,内置的 Google 配置规范化器仍会应用这层兼容性清理。
|
||||
|
||||
如果提供商需要完全自定义的线协议或自定义请求执行器,那是另一类扩展。这些钩子适用于仍运行在 OpenClaw 正常推理循环上的提供商行为。
|
||||
如果提供商需要完全自定义的线协议或自定义请求执行器,那属于另一类扩展。这些钩子适用于仍运行在 OpenClaw 常规推理循环上的提供商行为。
|
||||
|
||||
### 提供商示例
|
||||
|
||||
@ -264,41 +264,40 @@ api.registerProvider({
|
||||
|
||||
### 内置示例
|
||||
|
||||
内置的提供商插件会组合使用上述钩子,以适配各供应商在目录、认证、思考、重放和用量方面的需求。权威的钩子集合与各插件一起存放在 `extensions/` 下;本页旨在说明这些形状,而不是镜像那份列表。
|
||||
内置的提供商插件会组合使用上述钩子,以适配各厂商在目录、认证、思考、重放和用量方面的需求。权威的钩子集合与各插件一起保存在 `extensions/` 下;本页只是说明其形态,而不是镜像整个列表。
|
||||
|
||||
<AccordionGroup>
|
||||
<Accordion title="直通目录提供商">
|
||||
OpenRouter、Kilocode、Z.AI、xAI 会注册 `catalog` 以及
|
||||
`resolveDynamicModel` / `prepareDynamicModel`,这样它们就能在
|
||||
OpenClaw 的静态目录之前先暴露上游模型 id。
|
||||
OpenRouter、Kilocode、Z.AI、xAI 会注册 `catalog`,以及
|
||||
`resolveDynamicModel` / `prepareDynamicModel`,这样它们就能在 OpenClaw 的静态目录之前暴露上游模型 id。
|
||||
</Accordion>
|
||||
<Accordion title="OAuth 和用量端点提供商">
|
||||
GitHub Copilot、Gemini CLI、ChatGPT Codex、MiniMax、Xiaomi、z.ai 会将
|
||||
`prepareRuntimeAuth` 或 `formatApiKey` 与 `resolveUsageAuth` +
|
||||
`fetchUsageSnapshot` 搭配使用,以掌控令牌交换和 `/usage` 集成。
|
||||
`fetchUsageSnapshot` 组合使用,以接管 token 交换和 `/usage` 集成。
|
||||
</Accordion>
|
||||
<Accordion title="重放和转录清理系列">
|
||||
共享的命名系列(`google-gemini`、`passthrough-gemini`、
|
||||
`anthropic-by-model`、`hybrid-anthropic-openai`)让提供商可以通过
|
||||
`buildReplayPolicy` 选择加入转录策略,而不必由每个插件各自重新实现清理逻辑。
|
||||
<Accordion title="重放和转录清理家族">
|
||||
共享命名家族(`google-gemini`、`passthrough-gemini`、
|
||||
`anthropic-by-model`、`hybrid-anthropic-openai`)允许提供商通过
|
||||
`buildReplayPolicy` 选择加入转录策略,而不是让每个插件各自重新实现清理逻辑。
|
||||
</Accordion>
|
||||
<Accordion title="仅目录提供商">
|
||||
`byteplus`、`cloudflare-ai-gateway`、`huggingface`、`kimi-coding`、`nvidia`、
|
||||
`qianfan`、`synthetic`、`together`、`venice`、`vercel-ai-gateway` 和
|
||||
`volcengine` 只注册 `catalog`,并使用共享的推理循环。
|
||||
`volcengine` 只注册 `catalog`,并直接运行在共享推理循环上。
|
||||
</Accordion>
|
||||
<Accordion title="Anthropic 专用流辅助工具">
|
||||
Beta 标头、`/fast` / `serviceTier` 以及 `context1m` 位于
|
||||
<Accordion title="Anthropic 特定的流辅助工具">
|
||||
Beta 请求头、`/fast` / `serviceTier` 以及 `context1m` 位于
|
||||
Anthropic 插件公开的 `api.ts` / `contract-api.ts` 接缝中
|
||||
(`wrapAnthropicProviderStream`、`resolveAnthropicBetas`、
|
||||
`resolveAnthropicFastMode`、`resolveAnthropicServiceTier`),而不是位于
|
||||
`resolveAnthropicFastMode`、`resolveAnthropicServiceTier`),而不在
|
||||
通用 SDK 中。
|
||||
</Accordion>
|
||||
</AccordionGroup>
|
||||
|
||||
## 运行时辅助工具
|
||||
|
||||
插件可以通过 `api.runtime` 访问部分选定的核心辅助工具。对于 TTS:
|
||||
插件可以通过 `api.runtime` 访问部分核心辅助工具。对于 TTS:
|
||||
|
||||
```ts
|
||||
const clip = await api.runtime.tts.textToSpeech({
|
||||
@ -319,12 +318,12 @@ const voices = await api.runtime.tts.listVoices({
|
||||
|
||||
说明:
|
||||
|
||||
- `textToSpeech` 会返回用于文件/语音便笺表面的常规核心 TTS 输出负载。
|
||||
- `textToSpeech` 会返回普通核心 TTS 输出负载,供文件/语音便笺表面使用。
|
||||
- 使用核心 `messages.tts` 配置和提供商选择逻辑。
|
||||
- 返回 PCM 音频缓冲区 + 采样率。插件必须为提供商自行重采样/编码。
|
||||
- `listVoices` 对每个提供商来说是可选的。可将其用于由供应商拥有的语音选择器或设置流程。
|
||||
- 语音列表可包含更丰富的元数据,例如语言区域、性别和个性标签,供具备提供商感知能力的选择器使用。
|
||||
- OpenAI 和 ElevenLabs 目前支持电话语音。Microsoft 不支持。
|
||||
- 返回 PCM 音频缓冲区 + 采样率。插件必须为各提供商自行重采样/编码。
|
||||
- `listVoices` 对每个提供商来说是可选的。可将它用于厂商拥有的语音选择器或设置流程。
|
||||
- 语音列表可包含更丰富的元数据,例如区域设置、性别和个性标签,供具备提供商感知能力的选择器使用。
|
||||
- 目前 OpenAI 和 ElevenLabs 支持电话语音。Microsoft 不支持。
|
||||
|
||||
插件也可以通过 `api.registerSpeechProvider(...)` 注册语音提供商。
|
||||
|
||||
@ -347,11 +346,11 @@ api.registerSpeechProvider({
|
||||
说明:
|
||||
|
||||
- 将 TTS 策略、回退和回复投递保留在核心中。
|
||||
- 语音提供商用于由供应商拥有的合成行为。
|
||||
- 将语音提供商用于厂商拥有的合成行为。
|
||||
- 旧版 Microsoft `edge` 输入会被规范化为 `microsoft` 提供商 id。
|
||||
- 首选的归属模型是面向公司的:随着 OpenClaw 增加这些能力契约,一个供应商插件可以统一拥有文本、语音、图像以及未来的媒体提供商。
|
||||
- 首选的所有权模型是面向公司/厂商的:随着 OpenClaw 增加这些能力契约,一个厂商插件可以同时拥有文本、语音、图像以及未来的媒体提供商。
|
||||
|
||||
对于图像/音频/视频理解,插件会注册一个类型化的媒体理解提供商,而不是通用的键值袋:
|
||||
对于图像/音频/视频理解,插件会注册一个类型化的媒体理解提供商,而不是一个通用的键值对包:
|
||||
|
||||
```ts
|
||||
api.registerMediaUnderstandingProvider({
|
||||
@ -366,12 +365,12 @@ api.registerMediaUnderstandingProvider({
|
||||
说明:
|
||||
|
||||
- 将编排、回退、配置和渠道接线保留在核心中。
|
||||
- 将供应商行为保留在提供商插件中。
|
||||
- 增量扩展应保持类型化:新的可选方法、新的可选结果字段、新的可选能力。
|
||||
- 将厂商行为保留在提供商插件中。
|
||||
- 增量扩展应保持类型化:新增可选方法、新增可选结果字段、新增可选能力。
|
||||
- 视频生成已经遵循相同模式:
|
||||
- 核心拥有能力契约和运行时辅助工具
|
||||
- 供应商插件注册 `api.registerVideoGenerationProvider(...)`
|
||||
- 功能/渠道插件使用 `api.runtime.videoGeneration.*`
|
||||
- 厂商插件注册 `api.registerVideoGenerationProvider(...)`
|
||||
- 功能/渠道插件消费 `api.runtime.videoGeneration.*`
|
||||
|
||||
对于媒体理解运行时辅助工具,插件可以调用:
|
||||
|
||||
@ -388,13 +387,13 @@ const video = await api.runtime.mediaUnderstanding.describeVideoFile({
|
||||
});
|
||||
```
|
||||
|
||||
对于音频转写,插件既可以使用媒体理解运行时,也可以使用旧版 STT 别名:
|
||||
对于音频转录,插件可以使用媒体理解运行时,或使用旧版 STT 别名:
|
||||
|
||||
```ts
|
||||
const { text } = await api.runtime.mediaUnderstanding.transcribeAudioFile({
|
||||
filePath: "/tmp/inbound-audio.ogg",
|
||||
cfg: api.config,
|
||||
// 当无法可靠推断 MIME 时可选:
|
||||
// 当 MIME 无法可靠推断时可选:
|
||||
mime: "audio/ogg",
|
||||
});
|
||||
```
|
||||
@ -403,10 +402,10 @@ const { text } = await api.runtime.mediaUnderstanding.transcribeAudioFile({
|
||||
|
||||
- `api.runtime.mediaUnderstanding.*` 是图像/音频/视频理解的首选共享表面。
|
||||
- 使用核心媒体理解音频配置(`tools.media.audio`)和提供商回退顺序。
|
||||
- 当没有产生转写输出时(例如输入被跳过/不受支持),返回 `{ text: undefined }`。
|
||||
- 当没有产生转录输出时返回 `{ text: undefined }`(例如输入被跳过或不受支持)。
|
||||
- `api.runtime.stt.transcribeAudioFile(...)` 仍保留为兼容性别名。
|
||||
|
||||
插件也可以通过 `api.runtime.subagent` 启动后台子智能体运行:
|
||||
插件还可以通过 `api.runtime.subagent` 启动后台子智能体运行:
|
||||
|
||||
```ts
|
||||
const result = await api.runtime.subagent.run({
|
||||
@ -420,13 +419,13 @@ const result = await api.runtime.subagent.run({
|
||||
|
||||
说明:
|
||||
|
||||
- `provider` 和 `model` 是每次运行可选的覆写项,而不是持久化的会话变更。
|
||||
- OpenClaw 仅对受信任调用方接受这些覆写字段。
|
||||
- 对于插件拥有的回退运行,运维人员必须通过 `plugins.entries.<id>.subagent.allowModelOverride: true` 显式启用。
|
||||
- 使用 `plugins.entries.<id>.subagent.allowedModels` 可将受信任插件限制为特定的规范 `provider/model` 目标,或者使用 `"*"` 显式允许任意目标。
|
||||
- 不受信任插件的子智能体运行仍然可用,但覆写请求会被拒绝,而不是静默回退。
|
||||
- `provider` 和 `model` 是每次运行可选的覆盖项,不是持久的会话变更。
|
||||
- OpenClaw 只会为受信任调用方接受这些覆盖字段。
|
||||
- 对于插件拥有的回退运行,运维者必须通过 `plugins.entries.<id>.subagent.allowModelOverride: true` 显式启用。
|
||||
- 使用 `plugins.entries.<id>.subagent.allowedModels` 将受信任插件限制到特定的规范 `provider/model` 目标,或使用 `"*"` 显式允许任意目标。
|
||||
- 不受信任插件的子智能体运行仍然可用,但覆盖请求会被拒绝,而不是静默回退。
|
||||
|
||||
对于 web 搜索,插件可以使用共享运行时辅助工具,而不是深入智能体工具接线:
|
||||
对于 web 搜索,插件可以使用共享运行时辅助工具,而不是深入智能体工具接线层:
|
||||
|
||||
```ts
|
||||
const providers = api.runtime.webSearch.listProviders({
|
||||
@ -447,8 +446,8 @@ const result = await api.runtime.webSearch.search({
|
||||
说明:
|
||||
|
||||
- 将提供商选择、凭证解析和共享请求语义保留在核心中。
|
||||
- web 搜索提供商用于供应商特定的搜索传输。
|
||||
- `api.runtime.webSearch.*` 是功能/渠道插件在需要搜索行为但不依赖智能体工具包装器时的首选共享表面。
|
||||
- 将 web 搜索提供商用于厂商特定的搜索传输。
|
||||
- `api.runtime.webSearch.*` 是功能/渠道插件的首选共享表面,适用于那些需要搜索能力但不依赖智能体工具包装器的场景。
|
||||
|
||||
### `api.runtime.imageGeneration`
|
||||
|
||||
@ -486,53 +485,52 @@ api.registerHttpRoute({
|
||||
路由字段:
|
||||
|
||||
- `path`:Gateway 网关 HTTP 服务器下的路由路径。
|
||||
- `auth`:必填。使用 `"gateway"` 以要求普通 Gateway 网关认证,或使用 `"plugin"` 以要求插件管理的认证/webhook 验证。
|
||||
- `auth`:必填。使用 `"gateway"` 表示要求普通 Gateway 网关认证,或使用 `"plugin"` 表示由插件管理认证/webhook 校验。
|
||||
- `match`:可选。`"exact"`(默认)或 `"prefix"`。
|
||||
- `replaceExisting`:可选。允许同一插件替换它自己现有的路由注册。
|
||||
- `replaceExisting`:可选。允许同一插件替换自己现有的路由注册。
|
||||
- `handler`:当路由处理了请求时返回 `true`。
|
||||
|
||||
说明:
|
||||
|
||||
- `api.registerHttpHandler(...)` 已被移除,并会导致插件加载错误。请改用 `api.registerHttpRoute(...)`。
|
||||
- `api.registerHttpHandler(...)` 已移除,并会导致插件加载错误。请改用 `api.registerHttpRoute(...)`。
|
||||
- 插件路由必须显式声明 `auth`。
|
||||
- 除非设置 `replaceExisting: true`,否则精确的 `path + match` 冲突会被拒绝,而且一个插件不能替换另一个插件的路由。
|
||||
- 具有不同 `auth` 级别的重叠路由会被拒绝。请仅在相同认证级别内保持 `exact`/`prefix` 的贯穿链。
|
||||
- `auth: "plugin"` 路由**不会**自动接收运维人员运行时作用域。它们用于插件管理的 webhook/签名验证,而不是有特权的 Gateway 网关辅助调用。
|
||||
- `auth: "gateway"` 路由会在 Gateway 网关请求运行时作用域内运行,但该作用域是有意保守的:
|
||||
- 共享密钥 bearer 认证(`gateway.auth.mode = "token"` / `"password"`)会将插件路由运行时作用域固定为 `operator.write`,即使调用方发送了 `x-openclaw-scopes` 也是如此
|
||||
- 受信任、带身份的 HTTP 模式(例如 `trusted-proxy`,或私有入口上的 `gateway.auth.mode = "none"`)只有在显式提供该标头时,才会遵循 `x-openclaw-scopes`
|
||||
- 如果这些带身份的插件路由请求中缺少 `x-openclaw-scopes`,运行时作用域会回退为 `operator.write`
|
||||
- 实际规则:不要假设一个经过 gateway 认证的插件路由就是隐式的管理员表面。如果你的路由需要仅管理员可用的行为,请要求带身份的认证模式,并记录显式的 `x-openclaw-scopes` 标头契约。
|
||||
- 精确的 `path + match` 冲突会被拒绝,除非设置了 `replaceExisting: true`,并且一个插件不能替换另一个插件的路由。
|
||||
- `auth` 级别不同的重叠路由会被拒绝。仅在相同认证级别内保留 `exact`/`prefix` 贯穿链。
|
||||
- `auth: "plugin"` 路由**不会**自动接收运维者运行时 scopes。它们适用于插件管理的 webhook/签名校验,而不是特权 Gateway 网关辅助调用。
|
||||
- `auth: "gateway"` 路由运行在 Gateway 网关请求运行时 scope 内,但该 scope 是刻意保守的:
|
||||
- 共享密钥 bearer 认证(`gateway.auth.mode = "token"` / `"password"`)会将插件路由的运行时 scope 固定为 `operator.write`,即使调用方发送了 `x-openclaw-scopes` 也是如此
|
||||
- 受信任的带身份 HTTP 模式(例如 `trusted-proxy`,或私有入口上的 `gateway.auth.mode = "none"`)仅在明确存在该请求头时才会接受 `x-openclaw-scopes`
|
||||
- 如果这类带身份的插件路由请求中缺少 `x-openclaw-scopes`,运行时 scope 会回退到 `operator.write`
|
||||
- 实用规则:不要假设启用了 gateway 认证的插件路由就是隐式管理表面。如果你的路由需要仅管理员可用的行为,请要求使用带身份的认证模式,并记录清楚显式的 `x-openclaw-scopes` 请求头契约。
|
||||
|
||||
## 插件 SDK 导入路径
|
||||
|
||||
在编写新插件时,请使用更窄的 SDK 子路径,而不是单体式的 `openclaw/plugin-sdk` 根 barrel。核心子路径:
|
||||
在编写新插件时,请使用更窄的 SDK 子路径,而不是整体式的 `openclaw/plugin-sdk` 根 barrel。核心子路径包括:
|
||||
|
||||
| 子路径 | 用途 |
|
||||
| 子路径 | 用途 |
|
||||
| ----------------------------------- | -------------------------------------------------- |
|
||||
| `openclaw/plugin-sdk/plugin-entry` | 插件注册原语 |
|
||||
| `openclaw/plugin-sdk/channel-core` | 渠道入口/构建辅助工具 |
|
||||
| `openclaw/plugin-sdk/core` | 通用共享辅助工具和总括契约 |
|
||||
| `openclaw/plugin-sdk/config-schema` | 根 `openclaw.json` Zod 模式(`OpenClawSchema`) |
|
||||
| `openclaw/plugin-sdk/plugin-entry` | 插件注册原语 |
|
||||
| `openclaw/plugin-sdk/channel-core` | 渠道入口/构建辅助工具 |
|
||||
| `openclaw/plugin-sdk/core` | 通用共享辅助工具和总括契约 |
|
||||
| `openclaw/plugin-sdk/config-schema` | 根级 `openclaw.json` Zod schema(`OpenClawSchema`) |
|
||||
|
||||
渠道插件应从一组窄接缝中进行选择——`channel-setup`、
|
||||
渠道插件可从一组窄接缝中选择——`channel-setup`、
|
||||
`setup-runtime`、`setup-adapter-runtime`、`setup-tools`、`channel-pairing`、
|
||||
`channel-contract`、`channel-feedback`、`channel-inbound`、`channel-lifecycle`、
|
||||
`channel-reply-pipeline`、`command-auth`、`secret-input`、`webhook-ingress`、
|
||||
`channel-targets` 和 `channel-actions`。审批行为应统一到单一的
|
||||
`approvalCapability` 契约上,而不是分散混用在不相关的插件字段之间。
|
||||
请参见 [渠道插件](/zh-CN/plugins/sdk-channel-plugins)。
|
||||
`channel-targets` 和 `channel-actions`。审批行为应收敛到单一的
|
||||
`approvalCapability` 契约,而不是分散混用在不相关的插件字段中。
|
||||
请参阅 [渠道插件](/zh-CN/plugins/sdk-channel-plugins)。
|
||||
|
||||
运行时和配置辅助工具位于对应的 `*-runtime` 子路径下
|
||||
(`approval-runtime`、`config-runtime`、`infra-runtime`、`agent-runtime`、
|
||||
`lazy-runtime`、`directory-runtime`、`text-runtime`、`runtime-store` 等)。
|
||||
|
||||
<Info>
|
||||
`openclaw/plugin-sdk/channel-runtime` 已弃用——它是为旧版插件保留的兼容性 shim。
|
||||
新代码应改为导入更窄的通用原语。
|
||||
`openclaw/plugin-sdk/channel-runtime` 已弃用——它只是对旧插件的兼容性 shim。新代码应改为导入更窄的通用原语。
|
||||
</Info>
|
||||
|
||||
仓库内部入口点(按每个内置插件包根目录划分):
|
||||
仓库内部入口点(按每个内置插件软件包根目录划分):
|
||||
|
||||
- `index.js` —— 内置插件入口
|
||||
- `api.js` —— 辅助工具/类型 barrel
|
||||
@ -540,83 +538,82 @@ api.registerHttpRoute({
|
||||
- `setup-entry.js` —— 设置插件入口
|
||||
|
||||
外部插件应只导入 `openclaw/plugin-sdk/*` 子路径。绝不要从核心或其他插件中导入另一个插件包的 `src/*`。
|
||||
通过 facade 加载的入口点在存在活动运行时配置快照时会优先使用它,否则回退到磁盘上的已解析配置文件。
|
||||
Facade 加载的入口点在存在活动运行时配置快照时会优先使用它,否则回退到磁盘上的已解析配置文件。
|
||||
|
||||
诸如 `image-generation`、`media-understanding` 和 `speech` 之类的能力专用子路径之所以存在,是因为内置插件目前正在使用它们。它们并不自动构成长久冻结的外部契约——在依赖它们时,请查阅相应的 SDK 参考页面。
|
||||
诸如 `image-generation`、`media-understanding` 和 `speech` 之类的能力专用子路径之所以存在,是因为内置插件目前在使用它们。它们并不自动构成长期冻结的外部契约——在依赖它们之前,请查阅相应的 SDK 参考页。
|
||||
|
||||
## 消息工具模式
|
||||
## 消息工具 schema
|
||||
|
||||
对于反应、已读和投票等非消息原语,插件应拥有渠道特定的 `describeMessageTool(...)` 模式贡献。
|
||||
共享发送呈现应使用通用 `MessagePresentation` 契约,而不是提供商原生的按钮、组件、块或卡片字段。
|
||||
关于契约、回退规则、提供商映射以及插件作者检查清单,请参见 [消息呈现](/zh-CN/plugins/message-presentation)。
|
||||
对于反应、已读和投票等非消息原语,插件应拥有特定于渠道的 `describeMessageTool(...)` schema 贡献。
|
||||
共享发送展示应使用通用的 `MessagePresentation` 契约,而不是提供商原生的按钮、组件、block 或 card 字段。
|
||||
关于契约、回退规则、提供商映射以及插件作者检查清单,请参阅 [Message Presentation](/zh-CN/plugins/message-presentation)。
|
||||
|
||||
具备发送能力的插件通过消息能力声明自己能渲染什么:
|
||||
具备发送能力的插件会通过消息能力声明它们可以渲染的内容:
|
||||
|
||||
- `presentation`,用于语义化呈现块(`text`、`context`、`divider`、`buttons`、`select`)
|
||||
- `delivery-pin`,用于置顶投递请求
|
||||
- `presentation`:用于语义化展示块(`text`、`context`、`divider`、`buttons`、`select`)
|
||||
- `delivery-pin`:用于置顶投递请求
|
||||
|
||||
核心决定是原生渲染该呈现,还是将其降级为文本。
|
||||
不要从通用消息工具中暴露提供商原生 UI 的逃生通道。
|
||||
针对旧版原生模式的已弃用 SDK 辅助工具仍然会为现有第三方插件导出,但新插件不应使用它们。
|
||||
核心会决定是原生渲染该展示,还是将其降级为文本。
|
||||
不要从通用消息工具中暴露提供商原生 UI 的逃逸口。
|
||||
面向旧版原生 schema 的已弃用 SDK 辅助工具仍会为现有第三方插件继续导出,但新插件不应使用它们。
|
||||
|
||||
## 渠道目标解析
|
||||
|
||||
渠道插件应拥有渠道特定的目标语义。请让共享出站宿主保持通用,并使用消息适配器表面处理提供商规则:
|
||||
渠道插件应拥有特定于渠道的目标语义。保持共享出站主机通用,并使用消息适配器表面处理提供商规则:
|
||||
|
||||
- `messaging.inferTargetChatType({ to })` 决定规范化后的目标在目录查找之前应被视为 `direct`、`group` 还是 `channel`。
|
||||
- `messaging.targetResolver.looksLikeId(raw, normalized)` 告诉核心某个输入是否应跳过目录搜索,直接进入类 id 解析。
|
||||
- `messaging.targetResolver.resolveTarget(...)` 是当核心在规范化之后或目录未命中之后需要最终由提供商拥有的解析时,插件侧的回退。
|
||||
- `messaging.resolveOutboundSessionRoute(...)` 在目标解析完成后拥有提供商特定的会话路由构建逻辑。
|
||||
- `messaging.inferTargetChatType({ to })` 用于在目录查找之前判断规范化目标应被视为 `direct`、`group` 还是 `channel`。
|
||||
- `messaging.targetResolver.looksLikeId(raw, normalized)` 用于告诉核心,某个输入是否应跳过目录搜索,直接进入类 id 解析。
|
||||
- `messaging.targetResolver.resolveTarget(...)` 是当核心在规范化之后或目录未命中之后仍需要最终由提供商拥有的解析时,插件侧的回退逻辑。
|
||||
- `messaging.resolveOutboundSessionRoute(...)` 在目标解析完成后负责构建特定于提供商的会话路由。
|
||||
|
||||
推荐拆分方式:
|
||||
建议的拆分方式:
|
||||
|
||||
- 对于应在搜索联系人/群组之前进行的类别判断,请使用 `inferTargetChatType`。
|
||||
- 对于“把它视为显式/原生目标 id”检查,请使用 `looksLikeId`。
|
||||
- 对于提供商特定的规范化回退,请使用 `resolveTarget`,而不要将其用于广泛的目录搜索。
|
||||
- 将提供商原生 id,例如 chat id、thread id、JID、handle 和 room id,保留在 `target` 值或提供商特定参数中,而不是放进通用 SDK 字段里。
|
||||
- 对于应在搜索 peers/groups 之前发生的类别判断,使用 `inferTargetChatType`。
|
||||
- 对于“将其视为显式/原生目标 id”的检查,使用 `looksLikeId`。
|
||||
- 将 `resolveTarget` 用于特定于提供商的规范化回退,而不是用于广泛的目录搜索。
|
||||
- 将提供商原生 id(如 chat id、thread id、JID、handle 和 room id)保留在 `target` 值或提供商特定参数中,而不是放在通用 SDK 字段中。
|
||||
|
||||
## 基于配置的目录
|
||||
|
||||
如果插件会从配置派生目录条目,应将该逻辑保留在插件内,并复用
|
||||
`openclaw/plugin-sdk/directory-runtime` 中的共享辅助工具。
|
||||
如果插件根据配置派生目录项,应将这部分逻辑保留在插件中,并复用
|
||||
`openclaw/plugin-sdk/directory-runtime` 提供的共享辅助工具。
|
||||
|
||||
当某个渠道需要基于配置的联系人/群组时,请使用这种方式,例如:
|
||||
适用场景包括渠道需要基于配置的 peers/groups,例如:
|
||||
|
||||
- 由 allowlist 驱动的私信联系人
|
||||
- 由 allowlist 驱动的私信 peers
|
||||
- 已配置的渠道/群组映射
|
||||
- 按账户作用域划分的静态目录回退
|
||||
- 基于账号作用域的静态目录回退
|
||||
|
||||
`directory-runtime` 中的共享辅助工具只处理通用操作:
|
||||
|
||||
- 查询过滤
|
||||
- 限制应用
|
||||
- limit 应用
|
||||
- 去重/规范化辅助工具
|
||||
- 构建 `ChannelDirectoryEntry[]`
|
||||
|
||||
渠道特定的账户检查和 id 规范化应保留在插件实现中。
|
||||
特定于渠道的账号检查和 id 规范化应保留在插件实现中。
|
||||
|
||||
## 提供商目录
|
||||
|
||||
提供商插件可以通过
|
||||
`registerProvider({ catalog: { run(...) { ... } } })`
|
||||
为推理定义模型目录。
|
||||
`registerProvider({ catalog: { run(...) { ... } } })` 定义用于推理的模型目录。
|
||||
|
||||
`catalog.run(...)` 返回的形状与 OpenClaw 写入
|
||||
`models.providers` 的形状相同:
|
||||
`catalog.run(...)` 返回的形态与 OpenClaw 写入
|
||||
`models.providers` 的内容相同:
|
||||
|
||||
- `{ provider }`:一个提供商条目
|
||||
- `{ providers }`:多个提供商条目
|
||||
|
||||
当插件拥有提供商特定的模型 id、base URL 默认值或受认证控制的模型元数据时,请使用 `catalog`。
|
||||
当插件拥有特定于提供商的模型 id、base URL 默认值或受认证控制的模型元数据时,请使用 `catalog`。
|
||||
|
||||
`catalog.order` 控制插件目录相对于 OpenClaw 内置隐式提供商的合并时机:
|
||||
`catalog.order` 用于控制插件目录相对于 OpenClaw 内置隐式提供商的合并时机:
|
||||
|
||||
- `simple`:纯 API 密钥或环境变量驱动的提供商
|
||||
- `profile`:当存在认证配置文件时出现的提供商
|
||||
- `paired`:会合成多个相关提供商条目的提供商
|
||||
- `simple`:普通 API key 或环境变量驱动的提供商
|
||||
- `profile`:存在认证配置文件时出现的提供商
|
||||
- `paired`:合成多个相关提供商条目的提供商
|
||||
- `late`:最后一轮,在其他隐式提供商之后
|
||||
|
||||
后出现的提供商会在键冲突时胜出,因此插件可以有意覆写具有相同提供商 id 的内置提供商条目。
|
||||
后合并的提供商会在键冲突时获胜,因此插件可以有意使用相同的提供商 id 覆盖内置提供商条目。
|
||||
|
||||
兼容性:
|
||||
|
||||
@ -625,31 +622,31 @@ api.registerHttpRoute({
|
||||
|
||||
## 只读渠道检查
|
||||
|
||||
如果你的插件注册了一个渠道,优先同时实现
|
||||
`plugin.config.inspectAccount(cfg, accountId)` 和 `resolveAccount(...)`。
|
||||
如果你的插件注册了一个渠道,请优先实现
|
||||
`plugin.config.inspectAccount(cfg, accountId)`,并与 `resolveAccount(...)` 搭配使用。
|
||||
|
||||
原因:
|
||||
|
||||
- `resolveAccount(...)` 是运行时路径。它可以假定凭证已被完整实体化,并且在缺少必需密钥时快速失败。
|
||||
- `openclaw status`、`openclaw status --all`、`openclaw channels status`、`openclaw channels resolve` 以及 Doctor/配置修复流程等只读命令路径,不应仅为了描述配置就必须实体化运行时凭证。
|
||||
- `resolveAccount(...)` 是运行时路径。它可以假定凭证已被完整实体化,并且在必需 secret 缺失时可以快速失败。
|
||||
- 诸如 `openclaw status`、`openclaw status --all`、`openclaw channels status`、`openclaw channels resolve` 以及 doctor/配置修复流程等只读命令路径,不应仅仅为了描述配置就去实体化运行时凭证。
|
||||
|
||||
推荐的 `inspectAccount(...)` 行为:
|
||||
|
||||
- 仅返回描述性的账户状态。
|
||||
- 仅返回具有描述性的账号状态。
|
||||
- 保留 `enabled` 和 `configured`。
|
||||
- 在相关时包含凭证来源/状态字段,例如:
|
||||
- `tokenSource`、`tokenStatus`
|
||||
- `botTokenSource`、`botTokenStatus`
|
||||
- `appTokenSource`、`appTokenStatus`
|
||||
- `signingSecretSource`、`signingSecretStatus`
|
||||
- 你不需要为了报告只读可用性而返回原始令牌值。返回 `tokenStatus: "available"`(以及匹配的 source 字段)就足够用于 Status 风格命令。
|
||||
- 当某个凭证通过 SecretRef 配置,但在当前命令路径中不可用时,请使用 `configured_unavailable`。
|
||||
- 为了报告只读可用性,你不需要返回原始 token 值。返回 `tokenStatus: "available"`(以及对应的来源字段)就足以支持 Status 风格命令。
|
||||
- 当凭证通过 SecretRef 配置,但在当前命令路径中不可用时,请使用 `configured_unavailable`。
|
||||
|
||||
这样一来,只读命令就能报告“已配置,但在此命令路径中不可用”,而不会崩溃或错误地将该账户报告为未配置。
|
||||
这样,只读命令就能报告“已配置,但在此命令路径中不可用”,而不是崩溃,或错误地将该账号报告为未配置。
|
||||
|
||||
## 包打包集合
|
||||
## 软件包打包
|
||||
|
||||
一个插件目录可以包含一个带有 `openclaw.extensions` 的 `package.json`:
|
||||
插件目录可以包含一个带有 `openclaw.extensions` 的 `package.json`:
|
||||
|
||||
```json
|
||||
{
|
||||
@ -661,53 +658,48 @@ api.registerHttpRoute({
|
||||
}
|
||||
```
|
||||
|
||||
每个条目都会成为一个插件。如果该打包集合列出了多个扩展,插件 id
|
||||
将变为 `name/<fileBase>`。
|
||||
每个条目都会成为一个插件。如果一个 pack 列出多个扩展,插件 id
|
||||
会变为 `name/<fileBase>`。
|
||||
|
||||
如果你的插件导入了 npm 依赖,请在该目录中安装它们,以便
|
||||
如果你的插件导入了 npm 依赖,请在该目录中安装它们,以确保
|
||||
`node_modules` 可用(`npm install` / `pnpm install`)。
|
||||
|
||||
安全护栏:每个 `openclaw.extensions` 条目在解析符号链接后都必须保持在插件目录内。逃逸出包目录的条目会被拒绝。
|
||||
安全护栏:每个 `openclaw.extensions` 条目在解析符号链接后都必须仍位于插件目录内。任何逃逸出包目录的条目都会被拒绝。
|
||||
|
||||
安全说明:`openclaw plugins install` 会使用项目本地的
|
||||
`npm install --omit=dev --ignore-scripts` 安装插件依赖
|
||||
(无生命周期脚本,运行时无开发依赖),并忽略继承的全局 npm 安装设置。
|
||||
请保持插件依赖树为“纯 JS/TS”,并避免使用需要
|
||||
(不运行生命周期脚本,运行时不安装 dev dependencies),并忽略继承的全局 npm 安装设置。请保持插件依赖树为“纯 JS/TS”,并避免那些需要
|
||||
`postinstall` 构建的包。
|
||||
|
||||
可选项:`openclaw.setupEntry` 可以指向一个轻量级的仅设置模块。
|
||||
当 OpenClaw 需要为已禁用的渠道插件提供设置表面,或者某个渠道插件已启用但仍未配置时,它会加载 `setupEntry`,而不是完整插件入口。
|
||||
当你的主插件入口还会接线工具、钩子或其他仅运行时代码时,这可以让启动和设置更加轻量。
|
||||
可选:`openclaw.setupEntry` 可以指向一个轻量的仅设置模块。
|
||||
当 OpenClaw 需要为已禁用的渠道插件提供设置表面,或者某个渠道插件已启用但仍未完成配置时,它会加载 `setupEntry`,而不是完整插件入口。
|
||||
当你的主插件入口还会接线工具、钩子或其他仅运行时代码时,这样可以让启动和设置过程更轻量。
|
||||
|
||||
可选项:`openclaw.startup.deferConfiguredChannelFullLoadUntilAfterListen`
|
||||
可让一个渠道插件即使在渠道已经配置完成时,也在 Gateway 网关预监听启动阶段进入同样的 `setupEntry` 路径。
|
||||
可选:`openclaw.startup.deferConfiguredChannelFullLoadUntilAfterListen`
|
||||
可让渠道插件在 gateway 的监听前启动阶段也选择使用同样的 `setupEntry` 路径,即使该渠道已经配置完成。
|
||||
|
||||
只有在 `setupEntry` 完全覆盖 Gateway 网关开始监听之前必须存在的启动表面时,才应使用此选项。
|
||||
在实践中,这意味着设置入口必须注册启动所依赖的每一项渠道自有能力,例如:
|
||||
只有当 `setupEntry` 能完全覆盖 Gateway 网关开始监听之前必须存在的启动表面时,才应使用此项。
|
||||
在实践中,这意味着设置入口必须注册启动所依赖的每一种由渠道拥有的能力,例如:
|
||||
|
||||
- 渠道注册本身
|
||||
- Gateway 网关开始监听之前必须可用的所有 HTTP 路由
|
||||
- 在同一窗口期间必须存在的所有 Gateway 网关方法、工具或服务
|
||||
- 任何必须在 Gateway 网关开始监听之前可用的 HTTP 路由
|
||||
- 任何必须在同一时间窗口内存在的 gateway 方法、工具或服务
|
||||
|
||||
如果你的完整入口仍然拥有任何必需的启动能力,请不要启用这个标志。
|
||||
请保持插件使用默认行为,并让 OpenClaw 在启动期间加载完整入口。
|
||||
如果完整入口仍然拥有任何必需的启动能力,就不要启用这个标志。请保留插件默认行为,让 OpenClaw 在启动期间加载完整入口。
|
||||
|
||||
内置渠道也可以发布仅设置用的契约表面辅助工具,以便核心在完整渠道运行时尚未加载之前进行查询。当前的设置提升表面包括:
|
||||
内置渠道还可以发布仅设置阶段的契约表面辅助工具,以便核心在完整渠道运行时尚未加载前进行查询。当前的设置提升表面包括:
|
||||
|
||||
- `singleAccountKeysToMove`
|
||||
- `namedAccountPromotionKeys`
|
||||
- `resolveSingleAccountPromotionTarget(...)`
|
||||
|
||||
当核心需要在不加载完整插件入口的情况下,将旧版单账户渠道配置提升到
|
||||
`channels.<id>.accounts.*` 时,就会使用这组表面。
|
||||
Matrix 是当前的内置示例:当具名账户已存在时,它只会把认证/引导键移动到一个具名的提升账户中,并且它可以保留一个已配置的非规范默认账户键,而不是总是创建
|
||||
`accounts.default`。
|
||||
当核心需要将旧版单账号渠道配置提升到 `channels.<id>.accounts.*`,而又不加载完整插件入口时,就会使用这层表面。
|
||||
Matrix 是当前的内置示例:当已存在命名账号时,它只会将认证/引导键移动到一个已命名的提升账号中,并且可以保留一个已配置但非规范名称的默认账号键,而不是总是创建 `accounts.default`。
|
||||
|
||||
这些设置补丁适配器让内置契约表面发现保持惰性。导入时保持轻量;只有首次使用时才会加载提升表面,而不是在模块导入时重新进入内置渠道启动流程。
|
||||
这些设置补丁适配器让内置契约表面发现保持惰性。导入时保持轻量;只有在首次使用时才会加载提升表面,而不是在模块导入时重新进入内置渠道启动流程。
|
||||
|
||||
当这些启动表面包含 Gateway 网关 RPC 方法时,请将它们保留在插件专用前缀下。核心管理员命名空间(`config.*`、
|
||||
`exec.approvals.*`、`wizard.*`、`update.*`)仍然保留,并且始终解析为
|
||||
`operator.admin`,即使某个插件请求了更窄的作用域也是如此。
|
||||
当这些启动表面包含 gateway RPC 方法时,请将它们保留在插件专用前缀下。核心管理命名空间(`config.*`、
|
||||
`exec.approvals.*`、`wizard.*`、`update.*`)仍然是保留的,并且无论插件请求更窄的 scope 与否,始终都会解析为 `operator.admin`。
|
||||
|
||||
示例:
|
||||
|
||||
@ -726,7 +718,7 @@ Matrix 是当前的内置示例:当具名账户已存在时,它只会把认
|
||||
|
||||
### 渠道目录元数据
|
||||
|
||||
渠道插件可以通过 `openclaw.channel` 公布设置/发现元数据,并通过 `openclaw.install` 公布安装提示。这让核心目录保持无数据状态。
|
||||
渠道插件可以通过 `openclaw.channel` 声明设置/发现元数据,并通过 `openclaw.install` 声明安装提示。这样可以让核心目录保持无数据状态。
|
||||
|
||||
示例:
|
||||
|
||||
@ -741,7 +733,7 @@ Matrix 是当前的内置示例:当具名账户已存在时,它只会把认
|
||||
"selectionLabel": "Nextcloud Talk(self-hosted)",
|
||||
"docsPath": "/channels/nextcloud-talk",
|
||||
"docsLabel": "nextcloud-talk",
|
||||
"blurb": "通过 Nextcloud Talk webhook bots 提供 self-hosted 聊天。",
|
||||
"blurb": "通过 Nextcloud Talk webhook 机器人实现的 self-hosted 聊天。",
|
||||
"order": 65,
|
||||
"aliases": ["nc-talk", "nc"]
|
||||
},
|
||||
@ -754,42 +746,43 @@ Matrix 是当前的内置示例:当具名账户已存在时,它只会把认
|
||||
}
|
||||
```
|
||||
|
||||
除最小示例外,其他有用的 `openclaw.channel` 字段包括:
|
||||
除了最小示例之外,还有一些有用的 `openclaw.channel` 字段:
|
||||
|
||||
- `detailLabel`:用于更丰富目录/Status 表面的次级标签
|
||||
- `docsLabel`:覆盖文档链接的链接文本
|
||||
- `preferOver`:此目录条目应优先于的较低优先级插件/渠道 id
|
||||
- `selectionDocsPrefix`、`selectionDocsOmitLabel`、`selectionExtras`:选择表面的文案控制
|
||||
- `markdownCapable`:将该渠道标记为支持 Markdown,以用于出站格式决策
|
||||
- `exposure.configured`:设为 `false` 时,在已配置渠道列表表面中隐藏该渠道
|
||||
- `exposure.setup`:设为 `false` 时,在交互式设置/配置选择器中隐藏该渠道
|
||||
- `exposure.docs`:将该渠道标记为内部/私有,以用于文档导航表面
|
||||
- `showConfigured` / `showInSetup`:为兼容性仍接受的旧别名;优先使用 `exposure`
|
||||
- `quickstartAllowFrom`:让该渠道选择加入标准快速开始 `allowFrom` 流程
|
||||
- `forceAccountBinding`:即使只存在一个账户,也要求显式账户绑定
|
||||
- `preferOver`:该目录条目应优先于的低优先级插件/渠道 id
|
||||
- `selectionDocsPrefix`、`selectionDocsOmitLabel`、`selectionExtras`:选择表面的文案控制项
|
||||
- `markdownCapable`:将渠道标记为支持 markdown,以供出站格式决策使用
|
||||
- `exposure.configured`:设置为 `false` 时,在已配置渠道列表表面中隐藏该渠道
|
||||
- `exposure.setup`:设置为 `false` 时,在交互式设置/配置选择器中隐藏该渠道
|
||||
- `exposure.docs`:将该渠道标记为内部/私有,以供文档导航表面使用
|
||||
- `showConfigured` / `showInSetup`:仍接受的旧版兼容别名;优先使用 `exposure`
|
||||
- `quickstartAllowFrom`:使该渠道加入标准快速开始 `allowFrom` 流程
|
||||
- `forceAccountBinding`:即使只存在一个账号,也要求显式账号绑定
|
||||
- `preferSessionLookupForAnnounceTarget`:在解析公告目标时优先使用会话查找
|
||||
|
||||
OpenClaw 还可以合并**外部渠道目录**(例如 MPM 注册表导出)。将一个 JSON 文件放到以下任一位置:
|
||||
OpenClaw 还可以合并**外部渠道目录**(例如 MPM 注册表导出)。将一个 JSON 文件放在以下任一位置:
|
||||
|
||||
- `~/.openclaw/mpm/plugins.json`
|
||||
- `~/.openclaw/mpm/catalog.json`
|
||||
- `~/.openclaw/plugins/catalog.json`
|
||||
|
||||
或者将 `OPENCLAW_PLUGIN_CATALOG_PATHS`(或 `OPENCLAW_MPM_CATALOG_PATHS`)指向一个或多个 JSON 文件(以逗号/分号/`PATH` 分隔)。每个文件应包含 `{ "entries": [ { "name": "@scope/pkg", "openclaw": { "channel": {...}, "install": {...} } } ] }`。解析器也接受 `"packages"` 或 `"plugins"` 作为 `"entries"` 键的旧别名。
|
||||
或者,将 `OPENCLAW_PLUGIN_CATALOG_PATHS`(或 `OPENCLAW_MPM_CATALOG_PATHS`)指向一个或多个 JSON 文件(使用逗号/分号/`PATH` 分隔)。每个文件应包含 `{ "entries": [ { "name": "@scope/pkg", "openclaw": { "channel": {...}, "install": {...} } } ] }`。解析器也接受 `"packages"` 或 `"plugins"` 作为 `"entries"` 键的旧版别名。
|
||||
|
||||
生成的渠道目录条目和提供商安装目录条目会在原始 `openclaw.install` 块旁边暴露规范化后的安装源事实。这些规范化事实会标识 npm 规范是否为精确版本或浮动选择器、是否存在预期的完整性元数据,以及本地源路径是否也可用。当目录/包身份已知时,如果解析出的 npm 包名与该身份发生漂移,这些规范化事实会发出警告。它们也会在 `defaultChoice` 无效、指向不可用源,或者存在 npm 完整性元数据但没有有效 npm 源时发出警告。使用方应将 `installSource` 视为一个增量的可选字段,这样手工构建的条目和目录 shim 就不必合成它。
|
||||
这让新手引导和诊断能够解释源平面状态,而无需导入插件运行时。
|
||||
生成后的渠道目录条目和提供商安装目录条目会在原始 `openclaw.install` 代码块旁暴露已规范化的安装源事实。这些规范化事实可标识 npm spec 是精确版本还是浮动选择器、是否存在预期完整性元数据,以及本地源路径是否也可用。当目录/软件包身份已知时,这些规范化事实会在解析出的 npm 包名与该身份不一致时发出警告。它们也会在 `defaultChoice` 无效、指向不可用来源,或存在 npm 完整性元数据但没有有效 npm 源时发出警告。使用方应将 `installSource` 视为一个增量的可选字段,这样手工构建的条目和目录 shim 就不必自行合成它。
|
||||
这使得新手引导和诊断能够解释源平面状态,而无需导入插件运行时。
|
||||
|
||||
官方外部 npm 条目应优先使用精确的 `npmSpec` 加上 `expectedIntegrity`。裸包名和 dist-tag 仍可出于兼容性继续使用,但它们会暴露源平面警告,从而让目录可以在不破坏现有插件的前提下逐步迁移到固定版本、带完整性校验的安装方式。
|
||||
当新手引导从本地目录路径安装时,它会记录一条托管插件索引项,其中 `source: "path"`,并在可能时记录相对于工作区的 `sourcePath`。绝对操作加载路径仍保留在 `plugins.load.paths` 中;安装记录则避免将本地工作站路径重复写入长期配置。这样可以让本地开发安装对源平面诊断保持可见,而无需增加第二个原始文件系统路径暴露表面。持久化的 `plugins/installs.json` 插件索引是安装源的事实来源,并且可以在不加载插件运行时模块的情况下刷新。即使插件清单缺失或无效,它的 `installRecords` 映射仍然是持久的;其 `plugins` 数组则是可重建的清单/缓存视图。
|
||||
官方外部 npm 条目应优先使用精确的 `npmSpec` 加上 `expectedIntegrity`。裸包名和 dist-tag 仍可出于兼容性而继续工作,但它们会暴露源平面警告,从而让目录可以逐步转向固定版本、带完整性校验的安装,同时不破坏现有插件。
|
||||
当新手引导从本地目录路径安装时,它会记录一条受管理插件索引条目,其中包含 `source: "path"`,并尽可能记录相对于工作区的 `sourcePath`。绝对的实际加载路径仍保存在 `plugins.load.paths` 中;安装记录则避免将本地工作站路径重复写入长期配置中。这使本地开发安装对源平面诊断保持可见,同时不会增加第二个原始文件系统路径暴露表面。
|
||||
持久化的 `plugins/installs.json` 插件索引是安装来源的事实源,并且可以在不加载插件运行时模块的情况下刷新。即使插件 manifest 缺失或无效,其中的 `installRecords` 映射仍然可持久保留;其 `plugins` 数组则是可重建的 manifest/缓存视图。
|
||||
|
||||
## 上下文引擎插件
|
||||
|
||||
上下文引擎插件负责会话上下文编排,包括摄取、组装和压缩。通过
|
||||
`api.registerContextEngine(id, factory)` 在你的插件中注册它们,然后使用
|
||||
上下文引擎插件负责会话上下文的摄取、组装和压缩编排。通过
|
||||
`api.registerContextEngine(id, factory)` 从你的插件中注册它们,然后通过
|
||||
`plugins.slots.contextEngine` 选择活动引擎。
|
||||
|
||||
当你的插件需要替换或扩展默认上下文流水线,而不仅仅是添加 Memory Wiki 搜索或钩子时,请使用这种方式。
|
||||
当你的插件需要替换或扩展默认上下文流水线,而不仅仅是添加内存搜索或 hooks 时,请使用此方式。
|
||||
|
||||
```ts
|
||||
import { buildMemorySystemPromptAddition } from "openclaw/plugin-sdk/core";
|
||||
@ -817,7 +810,7 @@ export default function (api) {
|
||||
}
|
||||
```
|
||||
|
||||
如果你的引擎**不**拥有压缩算法,请保持 `compact()` 已实现,并显式委托它:
|
||||
如果你的引擎**不**拥有压缩算法,请保留 `compact()` 实现,并显式委托它:
|
||||
|
||||
```ts
|
||||
import {
|
||||
@ -854,24 +847,23 @@ export default function (api) {
|
||||
|
||||
## 添加新能力
|
||||
|
||||
当插件需要当前 API 无法适配的行为时,不要通过私有内部访问来绕过插件系统。应添加缺失的能力。
|
||||
当插件需要当前 API 无法容纳的行为时,不要通过私有深入访问绕过插件系统。请添加缺失的能力。
|
||||
|
||||
推荐顺序:
|
||||
|
||||
1. 定义核心契约
|
||||
1. 定义核心契约
|
||||
决定哪些共享行为应由核心拥有:策略、回退、配置合并、
|
||||
生命周期、面向渠道的语义,以及运行时辅助工具形状。
|
||||
2. 添加类型化的插件注册/运行时表面
|
||||
使用最小但有用的类型化能力表面来扩展 `OpenClawPluginApi` 和/或 `api.runtime`。
|
||||
3. 接入核心 + 渠道/功能使用方
|
||||
渠道和功能插件应通过核心使用这个新能力,
|
||||
而不是直接导入某个供应商实现。
|
||||
4. 注册供应商实现
|
||||
然后由供应商插件针对该能力注册其后端实现。
|
||||
5. 添加契约覆盖
|
||||
添加测试,使所有权和注册形状在时间推移中保持明确。
|
||||
生命周期、面向渠道的语义,以及运行时辅助工具形态。
|
||||
2. 添加类型化的插件注册/运行时表面
|
||||
以最小但有用的类型化能力表面扩展 `OpenClawPluginApi` 和/或 `api.runtime`。
|
||||
3. 接入核心 + 渠道/功能使用方
|
||||
渠道和功能插件应通过核心消费新能力,而不是直接导入某个厂商实现。
|
||||
4. 注册厂商实现
|
||||
然后由厂商插件针对该能力注册它们的后端实现。
|
||||
5. 添加契约覆盖
|
||||
添加测试,使所有权和注册形态随着时间推移仍保持明确。
|
||||
|
||||
这就是 OpenClaw 如何在保持明确主张的同时,又不会被硬编码到某一家提供商的世界观中。关于具体的文件检查清单和完整示例,请参见 [能力扩展手册](/zh-CN/plugins/architecture)。
|
||||
这就是 OpenClaw 在保持鲜明主张的同时,又不会被某一家提供商的世界观硬编码绑定的方式。请参阅 [能力扩展手册](/zh-CN/plugins/architecture),其中提供了具体的文件清单和完整示例。
|
||||
|
||||
### 能力检查清单
|
||||
|
||||
@ -881,26 +873,26 @@ export default function (api) {
|
||||
- `src/<capability>/runtime.ts` 中的核心运行器/运行时辅助工具
|
||||
- `src/plugins/types.ts` 中的插件 API 注册表面
|
||||
- `src/plugins/registry.ts` 中的插件注册表接线
|
||||
- 当功能/渠道插件需要消费它时,`src/plugins/runtime/*` 中的插件运行时暴露
|
||||
- 当功能/渠道插件需要消费它时,位于 `src/plugins/runtime/*` 中的插件运行时暴露
|
||||
- `src/test-utils/plugin-registration.ts` 中的捕获/测试辅助工具
|
||||
- `src/plugins/contracts/registry.ts` 中的所有权/契约断言
|
||||
- `docs/` 中的运维人员/插件文档
|
||||
- `docs/` 中面向运维者/插件作者的文档
|
||||
|
||||
如果其中某个表面缺失,通常意味着该能力尚未完全集成。
|
||||
如果其中某个表面缺失,通常说明该能力还没有真正完成集成。
|
||||
|
||||
### 能力模板
|
||||
|
||||
最小模式:
|
||||
|
||||
```ts
|
||||
// 核心契约
|
||||
// core contract
|
||||
export type VideoGenerationProviderPlugin = {
|
||||
id: string;
|
||||
label: string;
|
||||
generateVideo: (req: VideoGenerationRequest) => Promise<VideoGenerationResult>;
|
||||
};
|
||||
|
||||
// 插件 API
|
||||
// plugin API
|
||||
api.registerVideoGenerationProvider({
|
||||
id: "openai",
|
||||
label: "OpenAI",
|
||||
@ -909,7 +901,7 @@ api.registerVideoGenerationProvider({
|
||||
},
|
||||
});
|
||||
|
||||
// 面向功能/渠道插件的共享运行时辅助工具
|
||||
// feature/channel 插件的共享运行时辅助工具
|
||||
const clip = await api.runtime.videoGeneration.generate({
|
||||
prompt: "Show the robot walking through the lab.",
|
||||
cfg,
|
||||
@ -922,16 +914,16 @@ const clip = await api.runtime.videoGeneration.generate({
|
||||
expect(findVideoGenerationProviderIdsForPlugin("openai")).toEqual(["openai"]);
|
||||
```
|
||||
|
||||
这样可以让规则保持简单:
|
||||
这样可让规则保持简单:
|
||||
|
||||
- 核心拥有能力契约 + 编排
|
||||
- 供应商插件拥有供应商实现
|
||||
- 厂商插件拥有厂商实现
|
||||
- 功能/渠道插件消费运行时辅助工具
|
||||
- 契约测试让所有权保持明确
|
||||
- 契约测试使所有权保持明确
|
||||
|
||||
## 相关内容
|
||||
|
||||
- [插件架构](/zh-CN/plugins/architecture) —— 公开能力模型和形状
|
||||
- [插件架构](/zh-CN/plugins/architecture) —— 公开的能力模型和形态
|
||||
- [插件 SDK 子路径](/zh-CN/plugins/sdk-subpaths)
|
||||
- [插件 SDK 设置](/zh-CN/plugins/sdk-setup)
|
||||
- [构建插件](/zh-CN/plugins/building-plugins)
|
||||
|
||||
@ -5,17 +5,17 @@ read_when:
|
||||
summary: 插件清单 + JSON schema 要求(严格配置校验)
|
||||
title: 插件清单
|
||||
x-i18n:
|
||||
generated_at: "2026-04-26T04:44:22Z"
|
||||
generated_at: "2026-04-26T06:01:21Z"
|
||||
model: gpt-5.4
|
||||
provider: openai
|
||||
source_hash: 6b4988c8d383d27e10d04bc327d45e41714456288922aa1b108e4c5609e4a803
|
||||
source_hash: fa906a38666a3773130bb8b4725f73c7b1534f5ab10408acbec8b4b732ecd578
|
||||
source_path: plugins/manifest.md
|
||||
workflow: 15
|
||||
---
|
||||
|
||||
此页面仅适用于**原生 OpenClaw 插件清单**。
|
||||
|
||||
关于兼容的 bundle 布局,请参见 [Plugin bundles](/zh-CN/plugins/bundles)。
|
||||
有关兼容的 bundle 布局,请参阅 [插件 bundles](/zh-CN/plugins/bundles)。
|
||||
|
||||
兼容的 bundle 格式使用不同的清单文件:
|
||||
|
||||
@ -23,31 +23,31 @@ x-i18n:
|
||||
- Claude bundle:`.claude-plugin/plugin.json`,或不带清单的默认 Claude 组件布局
|
||||
- Cursor bundle:`.cursor-plugin/plugin.json`
|
||||
|
||||
OpenClaw 也会自动检测这些 bundle 布局,但不会按照此处描述的 `openclaw.plugin.json` schema 对它们进行校验。
|
||||
OpenClaw 也会自动检测这些 bundle 布局,但它们不会按照此处描述的 `openclaw.plugin.json` schema 进行校验。
|
||||
|
||||
对于兼容 bundle,当其布局符合 OpenClaw 运行时预期时,OpenClaw 当前会读取 bundle 元数据,以及声明的 skill 根目录、Claude 命令根目录、Claude bundle `settings.json` 默认值、Claude bundle LSP 默认值和受支持的 hook pack。
|
||||
对于兼容 bundles,当布局符合 OpenClaw 运行时预期时,OpenClaw 当前会读取 bundle 元数据,以及已声明的 skill 根目录、Claude 命令根目录、Claude bundle `settings.json` 默认值、Claude bundle LSP 默认值,以及受支持的 hook packs。
|
||||
|
||||
每个原生 OpenClaw 插件**必须**在**插件根目录**中提供一个 `openclaw.plugin.json` 文件。OpenClaw 使用此清单在**不执行插件代码**的情况下校验配置。缺失或无效的清单会被视为插件错误,并阻止配置校验。
|
||||
每个原生 OpenClaw 插件**都必须**在**插件根目录**中提供一个 `openclaw.plugin.json` 文件。OpenClaw 使用此清单在**不执行插件代码**的情况下校验配置。缺失或无效的清单会被视为插件错误,并阻止配置校验。
|
||||
|
||||
请参见完整的插件系统指南:[Plugins](/zh-CN/tools/plugin)。
|
||||
关于原生能力模型和当前外部兼容性指南,请参见:
|
||||
查看完整的插件系统指南:[插件](/zh-CN/tools/plugin)。
|
||||
有关原生能力模型和当前外部兼容性指南,请参阅:
|
||||
[能力模型](/zh-CN/plugins/architecture#public-capability-model)。
|
||||
|
||||
## 此文件的作用
|
||||
|
||||
`openclaw.plugin.json` 是 OpenClaw 在**加载你的插件代码之前**读取的元数据。下面的所有内容都必须足够轻量,以便在不启动插件运行时的情况下进行检查。
|
||||
`openclaw.plugin.json` 是 OpenClaw 在**加载你的插件代码之前**读取的元数据。下面的所有内容都必须足够轻量,能够在不启动插件运行时的情况下进行检查。
|
||||
|
||||
**可用于:**
|
||||
**用于:**
|
||||
|
||||
- 插件标识、配置校验和配置 UI 提示
|
||||
- 认证、新手引导和设置元数据(别名、自动启用、提供商环境变量、认证选项)
|
||||
- 插件标识、配置校验,以及配置 UI 提示
|
||||
- 凭证、onboarding 和设置元数据(别名、自动启用、提供商环境变量、凭证选项)
|
||||
- 控制平面界面的激活提示
|
||||
- 简写模型族归属
|
||||
- 简写模型家族归属
|
||||
- 静态能力归属快照(`contracts`)
|
||||
- 供共享 `openclaw qa` 主机检查的 QA runner 元数据
|
||||
- 共享 `openclaw qa` 主机可检查的 QA 运行器元数据
|
||||
- 合并到目录和校验界面的渠道特定配置元数据
|
||||
|
||||
**不要用于:**注册运行时行为、声明代码入口点或 npm 安装元数据。这些应放在你的插件代码和 `package.json` 中。
|
||||
**不要用于:**注册运行时行为、声明代码入口点,或 npm 安装元数据。这些应放在你的插件代码和 `package.json` 中。
|
||||
|
||||
## 最小示例
|
||||
|
||||
@ -96,19 +96,19 @@ OpenClaw 也会自动检测这些 bundle 布局,但不会按照此处描述的
|
||||
"provider": "openrouter",
|
||||
"method": "api-key",
|
||||
"choiceId": "openrouter-api-key",
|
||||
"choiceLabel": "OpenRouter API key",
|
||||
"choiceLabel": "OpenRouter API 密钥",
|
||||
"groupId": "openrouter",
|
||||
"groupLabel": "OpenRouter",
|
||||
"optionKey": "openrouterApiKey",
|
||||
"cliFlag": "--openrouter-api-key",
|
||||
"cliOption": "--openrouter-api-key <key>",
|
||||
"cliDescription": "OpenRouter API key",
|
||||
"cliDescription": "OpenRouter API 密钥",
|
||||
"onboardingScopes": ["text-inference"]
|
||||
}
|
||||
],
|
||||
"uiHints": {
|
||||
"apiKey": {
|
||||
"label": "API key",
|
||||
"label": "API 密钥",
|
||||
"placeholder": "sk-or-v1-...",
|
||||
"sensitive": true
|
||||
}
|
||||
@ -129,66 +129,66 @@ 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 目录元数据。 |
|
||||
| `modelSupport` | 否 | `object` | 由清单拥有的简写模型族元数据,用于在运行时之前自动加载插件。 |
|
||||
| `modelCatalog` | 否 | `object` | 由此插件拥有的 provider 的声明式模型目录元数据。这是未来只读列表、onboarding、新手引导、模型选择器、别名和抑制功能在不加载插件运行时情况下的控制平面契约。 |
|
||||
| `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 和认证配置文件共享的 coding provider。 |
|
||||
| `channelEnvVars` | 否 | `Record<string, string[]>` | OpenClaw 可在不加载插件代码的情况下检查的轻量级渠道环境变量元数据。将其用于通用启动/配置辅助工具应可见的、由环境变量驱动的渠道设置或认证界面。 |
|
||||
| `providerAuthChoices` | 否 | `object[]` | 用于 onboarding 选择器、首选 provider 解析和简单 CLI 标志连接的轻量级认证选项元数据。 |
|
||||
| `activation` | 否 | `object` | 用于 provider、命令、渠道、路由和能力触发加载的轻量级激活规划器元数据。仅为元数据;实际行为仍由插件运行时负责。 |
|
||||
| `setup` | 否 | `object` | 轻量级设置/新手引导描述符,供发现和设置界面在不加载插件运行时的情况下检查。 |
|
||||
| `qaRunners` | 否 | `object[]` | 由共享 `openclaw qa` 主机在插件运行时加载前使用的轻量级 QA runner 描述符。 |
|
||||
| `contracts` | 否 | `object` | 外部认证 hook、语音、实时转录、实时语音、媒体理解、图像生成、音乐生成、视频生成、网页抓取、网页搜索和工具归属的静态内置能力快照。 |
|
||||
| `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` | 适用于此插件拥有的 providers 的声明式模型目录元数据。这是未来只读列表、onboarding、模型选择器、别名和抑制功能的控制平面契约,无需加载插件运行时。 |
|
||||
| `providerEndpoints` | 否 | `object[]` | 由清单拥有的 endpoint host/baseUrl 元数据,用于核心在 provider 运行时加载前必须分类的 provider 路由。 |
|
||||
| `cliBackends` | 否 | `string[]` | 此插件拥有的 CLI 推理后端 id。用于根据显式配置引用在启动时自动激活。 |
|
||||
| `syntheticAuthRefs` | 否 | `string[]` | provider 或 CLI 后端引用;在运行时加载前的冷模型发现期间,应探测其由插件拥有的 synthetic auth hook。 |
|
||||
| `nonSecretAuthMarkers` | 否 | `string[]` | 由内置插件拥有的占位 API 密钥值,表示非机密的本地、OAuth 或环境凭证状态。 |
|
||||
| `commandAliases` | 否 | `object[]` | 此插件拥有的命令名称;在运行时加载前,这些命令应生成具备插件感知能力的配置和 CLI 诊断信息。 |
|
||||
| `providerAuthEnvVars` | 否 | `Record<string, string[]>` | 用于 provider 凭证/Status 查询的已弃用兼容性环境变量元数据。新插件优先使用 `setup.providers[].envVars`;在弃用窗口期内,OpenClaw 仍会读取此字段。 |
|
||||
| `providerAuthAliases` | 否 | `Record<string, string>` | 应复用另一个 provider id 进行凭证查询的 provider id,例如共享基础 provider API 密钥和凭证配置文件的 coding provider。 |
|
||||
| `channelEnvVars` | 否 | `Record<string, string[]>` | OpenClaw 可在不加载插件代码的情况下检查的轻量渠道环境变量元数据。将其用于通用启动/配置辅助工具应可见的、由环境变量驱动的渠道设置或凭证界面。 |
|
||||
| `providerAuthChoices` | 否 | `object[]` | 用于 onboarding 选择器、首选 provider 解析和简单 CLI flag 连接的轻量凭证选项元数据。 |
|
||||
| `activation` | 否 | `object` | 用于 provider、命令、渠道、路由和能力触发加载的轻量激活规划器元数据。仅为元数据;插件运行时仍拥有实际行为。 |
|
||||
| `setup` | 否 | `object` | 发现和设置界面可在不加载插件运行时的情况下检查的轻量设置/onboarding 描述符。 |
|
||||
| `qaRunners` | 否 | `object[]` | 共享 `openclaw qa` 主机在插件运行时加载前使用的轻量 QA 运行器描述符。 |
|
||||
| `contracts` | 否 | `object` | 面向外部 auth hooks、speech、realtime transcription、realtime voice、media-understanding、image-generation、music-generation、video-generation、web-fetch、web search 和工具归属的静态内置能力快照。 |
|
||||
| `mediaUnderstandingProviderMetadata` | 否 | `Record<string, object>` | 针对 `contracts.mediaUnderstandingProviders` 中声明的 provider id 的轻量 media-understanding 默认值。 |
|
||||
| `channelConfigs` | 否 | `Record<string, object>` | 由清单拥有的渠道配置元数据,会在运行时加载前合并到发现和校验界面中。 |
|
||||
| `skills` | 否 | `string[]` | 要加载的 Skills 目录,相对于插件根目录。 |
|
||||
| `name` | 否 | `string` | 人类可读的插件名称。 |
|
||||
| `description` | 否 | `string` | 显示在插件界面中的简短摘要。 |
|
||||
| `version` | 否 | `string` | 信息性插件版本。 |
|
||||
| `uiHints` | 否 | `Record<string, object>` | 配置字段的 UI 标签、占位符和敏感性提示。 |
|
||||
|
||||
## `providerAuthChoices` 参考
|
||||
|
||||
每个 `providerAuthChoices` 条目描述一个 onboarding 或认证选项。
|
||||
OpenClaw 会在 provider 运行时加载之前读取这些内容。
|
||||
provider 设置流程会优先使用这些清单选项,然后为兼容性回退到运行时向导元数据和安装目录选项。
|
||||
每个 `providerAuthChoices` 条目描述一个 onboarding 或凭证选项。
|
||||
OpenClaw 会在 provider 运行时加载前读取它。
|
||||
Provider 设置列表会使用这些清单选项、从描述符派生的设置选项,以及安装目录元数据,而无需加载 provider 运行时。
|
||||
|
||||
| 字段 | 必填 | 类型 | 含义 |
|
||||
| --------------------- | -------- | ----------------------------------------------- | -------------------------------------------------------------------------------------------------------- |
|
||||
| `provider` | 是 | `string` | 此选项所属的 provider id。 |
|
||||
| `method` | 是 | `string` | 要分发到的认证方法 id。 |
|
||||
| `choiceId` | 是 | `string` | onboarding 和 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">` | 此选项应出现在哪些 onboarding 界面中。如果省略,默认为 `["text-inference"]`。 |
|
||||
| `provider` | 是 | `string` | 此选项所属的 provider id。 |
|
||||
| `method` | 是 | `string` | 要分发到的凭证方法 id。 |
|
||||
| `choiceId` | 是 | `string` | onboarding 和 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` | 用于简单单 flag 凭证流程的内部选项键。 |
|
||||
| `cliFlag` | 否 | `string` | CLI flag 名称,例如 `--openrouter-api-key`。 |
|
||||
| `cliOption` | 否 | `string` | 完整的 CLI 选项形式,例如 `--openrouter-api-key <key>`。 |
|
||||
| `cliDescription` | 否 | `string` | CLI 帮助中使用的说明。 |
|
||||
| `onboardingScopes` | 否 | `Array<"text-inference" \| "image-generation">` | 此选项应出现在哪些 onboarding 界面中。如果省略,默认值为 `["text-inference"]`。 |
|
||||
|
||||
## `commandAliases` 参考
|
||||
|
||||
当插件拥有一个运行时命令名,而用户可能会误将其放入 `plugins.allow`,或尝试将其作为根 CLI 命令运行时,请使用 `commandAliases`。OpenClaw 使用此元数据在不导入插件运行时代码的情况下提供诊断信息。
|
||||
当插件拥有一个运行时命令名称,而用户可能会错误地将其放入 `plugins.allow`,或尝试将其作为根 CLI 命令运行时,请使用 `commandAliases`。OpenClaw 使用此元数据在不导入插件运行时代码的情况下提供诊断信息。
|
||||
|
||||
```json
|
||||
{
|
||||
@ -204,19 +204,19 @@ provider 设置流程会优先使用这些清单选项,然后为兼容性回
|
||||
|
||||
| 字段 | 必填 | 类型 | 含义 |
|
||||
| ------------ | -------- | ----------------- | ----------------------------------------------------------------------- |
|
||||
| `name` | 是 | `string` | 属于此插件的命令名称。 |
|
||||
| `kind` | 否 | `"runtime-slash"` | 将该别名标记为聊天斜杠命令,而不是根 CLI 命令。 |
|
||||
| `cliCommand` | 否 | `string` | 相关的根 CLI 命令;如果存在,可用于建议 CLI 操作。 |
|
||||
| `name` | 是 | `string` | 属于此插件的命令名称。 |
|
||||
| `kind` | 否 | `"runtime-slash"` | 将该别名标记为聊天 slash 命令,而不是根 CLI 命令。 |
|
||||
| `cliCommand` | 否 | `string` | 若存在,用于建议 CLI 操作的相关根 CLI 命令。 |
|
||||
|
||||
## `activation` 参考
|
||||
|
||||
当插件可以以低成本声明哪些控制平面事件应将其纳入激活/加载计划时,请使用 `activation`。
|
||||
当插件可以低成本声明哪些控制平面事件应将其纳入激活/加载计划时,请使用 `activation`。
|
||||
|
||||
此块是规划器元数据,不是生命周期 API。它不会注册运行时行为,不会替代 `register(...)`,也不保证插件代码已经执行。激活规划器会使用这些字段缩小候选插件范围,然后再回退到现有的清单归属元数据,例如 `providers`、`channels`、`commandAliases`、`setup.providers`、`contracts.tools` 和 hooks。
|
||||
此代码块是规划器元数据,不是生命周期 API。它不会注册运行时行为,不会替代 `register(...)`,也不保证插件代码已经执行。激活规划器使用这些字段来缩小候选插件范围,然后再回退到现有的清单归属元数据,例如 `providers`、`channels`、`commandAliases`、`setup.providers`、`contracts.tools` 和 hooks。
|
||||
|
||||
优先使用已经描述归属关系的最窄元数据。如果 `providers`、`channels`、`commandAliases`、设置描述符或 `contracts` 这些字段已经能够表达该关系,就使用它们。只有在这些归属字段无法表示额外规划提示时,才使用 `activation`。
|
||||
优先使用已经能描述归属关系的最窄元数据。当这些字段能够表达该关系时,请使用 `providers`、`channels`、`commandAliases`、setup 描述符或 `contracts`。只有在这些归属字段无法表示额外规划提示时,才使用 `activation`。
|
||||
|
||||
此块仅为元数据。它不会注册运行时行为,也不会替代 `register(...)`、`setupEntry` 或其他运行时/插件入口点。当前使用方会先将它作为缩小范围的提示,再进行更广泛的插件加载,因此缺失激活元数据通常只会带来性能成本;只要旧版清单归属回退仍然存在,它就不应影响正确性。
|
||||
此代码块仅是元数据。它不会注册运行时行为,也不会替代 `register(...)`、`setupEntry` 或其他运行时/插件入口点。当前使用方会在更广泛的插件加载之前将其作为缩小范围的提示,因此缺失激活元数据通常只会带来性能成本;在旧版清单归属回退仍然存在时,它不应改变正确性。
|
||||
|
||||
```json
|
||||
{
|
||||
@ -232,27 +232,27 @@ provider 设置流程会优先使用这些清单选项,然后为兼容性回
|
||||
|
||||
| 字段 | 必填 | 类型 | 含义 |
|
||||
| ---------------- | -------- | ---------------------------------------------------- | ------------------------------------------------------------------------------------------------------- |
|
||||
| `onProviders` | 否 | `string[]` | 应将此插件纳入激活/加载计划的 provider id。 |
|
||||
| `onCommands` | 否 | `string[]` | 应将此插件纳入激活/加载计划的命令 id。 |
|
||||
| `onChannels` | 否 | `string[]` | 应将此插件纳入激活/加载计划的渠道 id。 |
|
||||
| `onRoutes` | 否 | `string[]` | 应将此插件纳入激活/加载计划的路由类型。 |
|
||||
| `onCapabilities` | 否 | `Array<"provider" \| "channel" \| "tool" \| "hook">` | 控制平面激活规划使用的宽泛能力提示。尽可能优先使用更窄的字段。 |
|
||||
| `onProviders` | 否 | `string[]` | 应将此插件纳入激活/加载计划的 provider id。 |
|
||||
| `onCommands` | 否 | `string[]` | 应将此插件纳入激活/加载计划的命令 id。 |
|
||||
| `onChannels` | 否 | `string[]` | 应将此插件纳入激活/加载计划的渠道 id。 |
|
||||
| `onRoutes` | 否 | `string[]` | 应将此插件纳入激活/加载计划的路由类型。 |
|
||||
| `onCapabilities` | 否 | `Array<"provider" \| "channel" \| "tool" \| "hook">` | 控制平面激活规划使用的宽泛能力提示。可能时优先使用更窄的字段。 |
|
||||
|
||||
当前的实际使用方:
|
||||
当前在线使用方:
|
||||
|
||||
- 由命令触发的 CLI 规划会回退到旧版
|
||||
`commandAliases[].cliCommand` 或 `commandAliases[].name`
|
||||
- 由渠道触发的设置/渠道规划在缺少显式渠道激活元数据时,会回退到旧版 `channels[]`
|
||||
- 当缺少显式渠道激活元数据时,由渠道触发的设置/渠道规划会回退到旧版 `channels[]`
|
||||
归属
|
||||
- 由 provider 触发的设置/运行时规划在缺少显式 provider
|
||||
激活元数据时,会回退到旧版
|
||||
- 当缺少显式 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` 根命令下提供一个或多个传输 runner 时,请使用 `qaRunners`。保持此元数据轻量且静态;插件运行时仍通过导出 `qaRunnerCliRegistrations` 的轻量级 `runtime-api.ts` 界面负责实际 CLI 注册。
|
||||
当插件在共享的 `openclaw qa` 根命令下提供一个或多个传输运行器时,请使用 `qaRunners`。保持此元数据轻量且静态;插件运行时仍通过导出 `qaRunnerCliRegistrations` 的轻量级 `runtime-api.ts` 界面拥有实际 CLI 注册逻辑。
|
||||
|
||||
```json
|
||||
{
|
||||
@ -267,12 +267,12 @@ provider 设置流程会优先使用这些清单选项,然后为兼容性回
|
||||
|
||||
| 字段 | 必填 | 类型 | 含义 |
|
||||
| ------------- | -------- | -------- | ------------------------------------------------------------------ |
|
||||
| `commandName` | 是 | `string` | 挂载在 `openclaw qa` 下的子命令,例如 `matrix`。 |
|
||||
| `description` | 否 | `string` | 当共享主机需要 stub 命令时使用的回退帮助文本。 |
|
||||
| `commandName` | 是 | `string` | 挂载在 `openclaw qa` 下的子命令,例如 `matrix`。 |
|
||||
| `description` | 否 | `string` | 当共享宿主需要一个占位命令时使用的回退帮助文本。 |
|
||||
|
||||
## `setup` 参考
|
||||
|
||||
当设置和 onboarding 界面需要在运行时加载前读取由插件拥有的轻量级元数据时,请使用 `setup`。
|
||||
当设置和 onboarding 界面在运行时加载前需要轻量的、由插件拥有的元数据时,请使用 `setup`。
|
||||
|
||||
```json
|
||||
{
|
||||
@ -293,38 +293,38 @@ provider 设置流程会优先使用这些清单选项,然后为兼容性回
|
||||
|
||||
顶层 `cliBackends` 仍然有效,并继续描述 CLI 推理后端。`setup.cliBackends` 是面向控制平面/设置流程的设置专用描述符界面,应保持为仅元数据。
|
||||
|
||||
当存在时,`setup.providers` 和 `setup.cliBackends` 是设置发现的首选“描述符优先”查找界面。如果描述符只能缩小候选插件范围,而设置仍需要更丰富的设置期运行时 hook,请设置 `requiresRuntime: true`,并保留 `setup-api` 作为回退执行路径。
|
||||
存在时,`setup.providers` 和 `setup.cliBackends` 是设置发现的首选“描述符优先”查询界面。如果描述符仅用于缩小候选插件范围,而设置仍需要更丰富的设置期运行时 hooks,请设置 `requiresRuntime: true`,并保留 `setup-api` 作为回退执行路径。
|
||||
|
||||
OpenClaw 还会在通用 provider 认证和环境变量查找中包含 `setup.providers[].envVars`。`providerAuthEnvVars` 在弃用过渡期内仍通过兼容适配器受支持,但仍使用它的非内置插件会收到清单诊断。新插件应将设置/Status 环境变量元数据放在 `setup.providers[].envVars` 上。
|
||||
OpenClaw 还会将 `setup.providers[].envVars` 纳入通用 provider 凭证和环境变量查询。`providerAuthEnvVars` 在弃用窗口期内仍通过兼容适配器受到支持,但仍在使用它的非内置插件会收到清单诊断。新插件应将设置/Status 环境变量元数据放在 `setup.providers[].envVars` 上。
|
||||
|
||||
当没有设置入口,或 `setup.requiresRuntime: false` 声明设置运行时非必需时,OpenClaw 还可以从 `setup.providers[].authMethods` 派生简单的设置选项。对于自定义标签、CLI 标志、onboarding 范围和智能体元数据,显式的 `providerAuthChoices` 条目仍然是首选。
|
||||
当没有可用的 setup 条目时,或者当 `setup.requiresRuntime: false` 声明不需要设置运行时时,OpenClaw 也可以根据 `setup.providers[].authMethods` 推导简单的设置选项。对于自定义标签、CLI flags、onboarding 范围和助手元数据,显式的 `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 后端,或者某个描述符没有匹配的运行时注册项,设置注册表诊断会报告描述符漂移。这些诊断是附加性的,不会拒绝旧版插件。
|
||||
当设置运行时确实执行时,如果 `setup-api` 注册了清单描述符未声明的 provider 或 CLI 后端,或者某个描述符没有匹配的运行时注册,设置注册表诊断会报告描述符漂移。这些诊断是附加性的,不会拒绝旧版插件。
|
||||
|
||||
### `setup.providers` 参考
|
||||
|
||||
| 字段 | 必填 | 类型 | 含义 |
|
||||
| ------------- | -------- | ---------- | ------------------------------------------------------------------------------------ |
|
||||
| `id` | 是 | `string` | 在设置或 onboarding 期间暴露的 provider id。保持规范化 id 在全局唯一。 |
|
||||
| `authMethods` | 否 | `string[]` | 此 provider 在不加载完整运行时的情况下支持的设置/认证方法 id。 |
|
||||
| `envVars` | 否 | `string[]` | 通用设置/Status 界面可在插件运行时加载前检查的环境变量。 |
|
||||
| `id` | 是 | `string` | 在设置或 onboarding 期间公开的 provider id。请保持归一化后的 id 在全局唯一。 |
|
||||
| `authMethods` | 否 | `string[]` | 该 provider 在不加载完整运行时的情况下支持的设置/凭证方法 id。 |
|
||||
| `envVars` | 否 | `string[]` | 通用设置/Status 界面可在插件运行时加载前检查的环境变量。 |
|
||||
|
||||
### `setup` 字段
|
||||
|
||||
| 字段 | 必填 | 类型 | 含义 |
|
||||
| ------------------ | -------- | ---------- | --------------------------------------------------------------------------------------------------- |
|
||||
| `providers` | 否 | `object[]` | 在设置和 onboarding 期间暴露的 provider 设置描述符。 |
|
||||
| `cliBackends` | 否 | `string[]` | 用于“描述符优先”设置查找的设置期后端 id。保持规范化 id 在全局唯一。 |
|
||||
| `configMigrations` | 否 | `string[]` | 属于此插件设置界面的配置迁移 id。 |
|
||||
| `requiresRuntime` | 否 | `boolean` | 在描述符查找之后,设置是否仍需要执行 `setup-api`。 |
|
||||
| `providers` | 否 | `object[]` | 在设置和 onboarding 期间公开的 provider 设置描述符。 |
|
||||
| `cliBackends` | 否 | `string[]` | 用于描述符优先设置查询的设置期后端 id。请保持归一化后的 id 在全局唯一。 |
|
||||
| `configMigrations` | 否 | `string[]` | 由此插件设置界面拥有的配置迁移 id。 |
|
||||
| `requiresRuntime` | 否 | `boolean` | 在描述符查询之后,设置是否仍需要执行 `setup-api`。 |
|
||||
|
||||
## `uiHints` 参考
|
||||
|
||||
`uiHints` 是一个从配置字段名称映射到小型渲染提示的映射表。
|
||||
`uiHints` 是一个从配置字段名称到小型渲染提示的映射。
|
||||
|
||||
```json
|
||||
{
|
||||
@ -339,16 +339,16 @@ OpenClaw 还会在通用 provider 认证和环境变量查找中包含 `setup.pr
|
||||
}
|
||||
```
|
||||
|
||||
每个字段提示可包含:
|
||||
每个字段提示可以包含:
|
||||
|
||||
| 字段 | 类型 | 含义 |
|
||||
| ------------- | ---------- | --------------------------------------- |
|
||||
| `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` 参考
|
||||
|
||||
@ -377,35 +377,29 @@ OpenClaw 还会在通用 provider 认证和环境变量查找中包含 `setup.pr
|
||||
|
||||
| 字段 | 类型 | 含义 |
|
||||
| -------------------------------- | ---------- | --------------------------------------------------------------------- |
|
||||
| `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[]` | 此插件拥有的网页抓取 provider id。 |
|
||||
| `webSearchProviders` | `string[]` | 此插件拥有的网页搜索 provider id。 |
|
||||
| `tools` | `string[]` | 此插件拥有的 Agent 工具名称,用于内置契约检查。 |
|
||||
| `embeddedExtensionFactories` | `string[]` | Codex app-server 扩展工厂 id,目前为 `codex-app-server`。 |
|
||||
| `agentToolResultMiddleware` | `string[]` | 内置插件可为其注册工具结果中间件的运行时 id。 |
|
||||
| `externalAuthProviders` | `string[]` | 此插件拥有其外部凭证配置文件 hook 的 provider id。 |
|
||||
| `speechProviders` | `string[]` | 此插件拥有的 speech provider id。 |
|
||||
| `realtimeTranscriptionProviders` | `string[]` | 此插件拥有的 realtime-transcription provider id。 |
|
||||
| `realtimeVoiceProviders` | `string[]` | 此插件拥有的 realtime-voice provider id。 |
|
||||
| `memoryEmbeddingProviders` | `string[]` | 此插件拥有的 Memory embedding provider id。 |
|
||||
| `mediaUnderstandingProviders` | `string[]` | 此插件拥有的 media-understanding provider id。 |
|
||||
| `imageGenerationProviders` | `string[]` | 此插件拥有的 image-generation provider id。 |
|
||||
| `videoGenerationProviders` | `string[]` | 此插件拥有的 video-generation provider id。 |
|
||||
| `webFetchProviders` | `string[]` | 此插件拥有的 web-fetch provider id。 |
|
||||
| `webSearchProviders` | `string[]` | 此插件拥有的 web search provider id。 |
|
||||
| `tools` | `string[]` | 此插件拥有的 Agent 工具名称,用于内置契约检查。 |
|
||||
|
||||
`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 embedding providers 应为其公开的每个适配器 id 声明 `contracts.memoryEmbeddingProviders`,包括诸如 `local` 之类的内置适配器。独立 CLI 路径使用此清单契约在完整 Gateway 网关运行时注册 providers 之前,仅加载所属插件。
|
||||
|
||||
## `mediaUnderstandingProviderMetadata` 参考
|
||||
|
||||
当媒体理解 provider 具有默认模型、自动认证回退优先级,或通用核心辅助工具在运行时加载前需要的原生文档支持时,请使用 `mediaUnderstandingProviderMetadata`。键也必须在
|
||||
`contracts.mediaUnderstandingProviders` 中声明。
|
||||
当某个 media-understanding provider 具有默认模型、自动凭证回退优先级或原生文档支持,而通用核心辅助工具需要在运行时加载前知道这些信息时,请使用 `mediaUnderstandingProviderMetadata`。键还必须在 `contracts.mediaUnderstandingProviders` 中声明。
|
||||
|
||||
```json
|
||||
{
|
||||
@ -428,27 +422,27 @@ app-server 的扩展工厂。内置工具结果转换应声明 `contracts.agentT
|
||||
}
|
||||
```
|
||||
|
||||
每个 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 条目,或 `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>`
|
||||
|
||||
声明了 `channels[]` 的非内置插件也应声明匹配的 `channelConfigs` 条目。没有它们时,OpenClaw 仍然可以加载插件,但冷路径配置 schema、设置和 Control UI 界面在插件运行时执行前无法知道该渠道拥有的选项结构。
|
||||
声明了 `channels[]` 的非内置插件也应声明匹配的 `channelConfigs` 条目。若缺少这些条目,OpenClaw 仍可加载该插件,但冷路径配置 schema、设置和控制 UI 界面在插件运行时执行之前将无法知道该渠道拥有的选项结构。
|
||||
|
||||
```json
|
||||
{
|
||||
@ -475,19 +469,19 @@ app-server 的扩展工厂。内置工具结果转换应声明 `contracts.agentT
|
||||
}
|
||||
```
|
||||
|
||||
每个渠道条目可包含:
|
||||
每个渠道条目可以包含:
|
||||
|
||||
| 字段 | 类型 | 含义 |
|
||||
| ------------- | ------------------------ | ----------------------------------------------------------------------------------------- |
|
||||
| `schema` | `object` | `channels.<id>` 的 JSON Schema。每个声明的渠道配置条目都必须提供。 |
|
||||
| `uiHints` | `Record<string, object>` | 该渠道配置节的可选 UI 标签/占位符/敏感性提示。 |
|
||||
| `label` | `string` | 当运行时元数据尚未准备好时,合并到选择器和检查界面中的渠道标签。 |
|
||||
| `description` | `string` | 用于检查和目录界面的简短渠道说明。 |
|
||||
| `preferOver` | `string[]` | 在选择界面中,此渠道应优先于的旧版或较低优先级插件 id。 |
|
||||
| `schema` | `object` | `channels.<id>` 的 JSON Schema。每个已声明的渠道配置条目都必须提供。 |
|
||||
| `uiHints` | `Record<string, object>` | 该渠道配置部分可选的 UI 标签/占位符/敏感性提示。 |
|
||||
| `label` | `string` | 当运行时元数据尚未准备好时,合并到选择器和检查界面中的渠道标签。 |
|
||||
| `description` | `string` | 用于检查和目录界面的简短渠道描述。 |
|
||||
| `preferOver` | `string[]` | 在选择界面中,此渠道应优先于的旧版或较低优先级插件 id。 |
|
||||
|
||||
### 替换另一个渠道插件
|
||||
|
||||
当你的插件是某个渠道 id 的首选拥有者,而另一个插件也能提供该渠道时,请使用 `preferOver`。常见情况包括:插件 id 已重命名、独立插件替代了内置插件,或一个维护中的 fork 为了配置兼容性而保留相同的渠道 id。
|
||||
当你的插件是某个渠道 id 的首选拥有者,而另一个插件也可以提供该渠道时,请使用 `preferOver`。常见情况包括重命名后的插件 id、取代内置插件的独立插件,或为了配置兼容性而保留相同渠道 id 的维护分支。
|
||||
|
||||
```json
|
||||
{
|
||||
@ -508,13 +502,13 @@ app-server 的扩展工厂。内置工具结果转换应声明 `contracts.agentT
|
||||
}
|
||||
```
|
||||
|
||||
当配置了 `channels.chat` 时,OpenClaw 会同时考虑渠道 id 和首选插件 id。如果低优先级插件之所以被选中,只是因为它是内置的或默认启用,OpenClaw 会在生效运行时配置中将其禁用,从而确保只有一个插件拥有该渠道及其工具。显式用户选择仍然优先:如果用户显式启用了两个插件,OpenClaw 会保留该选择,并报告重复渠道/工具诊断,而不是静默更改所请求的插件集合。
|
||||
当配置了 `channels.chat` 时,OpenClaw 会同时考虑渠道 id 和首选插件 id。如果较低优先级的插件之所以被选中只是因为它是内置的或默认启用的,OpenClaw 会在生效的运行时配置中禁用它,以便只有一个插件拥有该渠道及其工具。显式的用户选择仍然优先:如果用户显式启用了两个插件,OpenClaw 会保留该选择,并报告重复渠道/工具诊断,而不是静默更改请求的插件集合。
|
||||
|
||||
请将 `preferOver` 限定在确实能够提供同一渠道的插件 id 范围内。它不是通用优先级字段,也不会重命名用户配置键。
|
||||
请将 `preferOver` 限定为那些确实可以提供同一渠道的插件 id。它不是通用优先级字段,也不会重命名用户配置键。
|
||||
|
||||
## `modelSupport` 参考
|
||||
|
||||
当 OpenClaw 需要在插件运行时加载前,根据诸如 `gpt-5.5` 或 `claude-sonnet-4.6` 这样的简写模型 id 推断你的 provider 插件时,请使用 `modelSupport`。
|
||||
当 OpenClaw 应在插件运行时加载前,根据 `gpt-5.5` 或 `claude-sonnet-4.6` 之类的简写模型 id 推断你的 provider 插件时,请使用 `modelSupport`。
|
||||
|
||||
```json
|
||||
{
|
||||
@ -527,21 +521,21 @@ app-server 的扩展工厂。内置工具结果转换应声明 `contracts.agentT
|
||||
|
||||
OpenClaw 按以下优先级应用:
|
||||
|
||||
- 显式 `provider/model` 引用使用其所属 `providers` 清单元数据
|
||||
- 显式 `provider/model` 引用使用所属 `providers` 清单元数据
|
||||
- `modelPatterns` 优先于 `modelPrefixes`
|
||||
- 如果一个非内置插件和一个内置插件同时匹配,则非内置插件胜出
|
||||
- 剩余的歧义会被忽略,直到用户或配置指定某个 provider
|
||||
- 剩余的歧义会被忽略,直到用户或配置指定一个 provider
|
||||
|
||||
字段:
|
||||
|
||||
| 字段 | 类型 | 含义 |
|
||||
| --------------- | ---------- | ------------------------------------------------------------------------------- |
|
||||
| `modelPrefixes` | `string[]` | 对简写模型 id 使用 `startsWith` 匹配的前缀。 |
|
||||
| `modelPatterns` | `string[]` | 在移除 profile 后缀后,对简写模型 id 进行匹配的正则表达式源码。 |
|
||||
| `modelPrefixes` | `string[]` | 使用 `startsWith` 与简写模型 id 进行匹配的前缀。 |
|
||||
| `modelPatterns` | `string[]` | 在移除 profile 后缀后,针对简写模型 id 进行匹配的正则表达式源码。 |
|
||||
|
||||
## `modelCatalog` 参考
|
||||
|
||||
当 OpenClaw 需要在加载插件运行时之前了解 provider 模型元数据时,请使用 `modelCatalog`。这是由清单拥有的固定目录行、provider 别名、抑制规则和发现模式的数据源。运行时刷新仍属于 provider 运行时代码,但清单会告知核心何时需要运行时。
|
||||
当 OpenClaw 应在加载插件运行时之前知道 provider 模型元数据时,请使用 `modelCatalog`。这是由清单拥有的固定目录行、provider 别名、抑制规则和发现模式的数据源。运行时刷新仍属于 provider 运行时代码,但清单会告知核心何时需要运行时。
|
||||
|
||||
```json
|
||||
{
|
||||
@ -594,113 +588,109 @@ OpenClaw 按以下优先级应用:
|
||||
|
||||
| 字段 | 类型 | 含义 |
|
||||
| -------------- | -------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------- |
|
||||
| `providers` | `Record<string, object>` | 由此插件拥有的 provider id 的目录行。键也应出现在顶层 `providers` 中。 |
|
||||
| `aliases` | `Record<string, object>` | 应解析到所属 provider 的 provider 别名,用于目录或抑制规划。 |
|
||||
| `suppressions` | `object[]` | 因特定 provider 原因而由此插件抑制的、来自其他来源的模型行。 |
|
||||
| `discovery` | `Record<string, "static" \| "refreshable" \| "runtime">` | provider 目录是否可从清单元数据读取、刷新到缓存,或是否需要运行时。 |
|
||||
| `providers` | `Record<string, object>` | 由此插件拥有的 provider id 的目录条目。键也应出现在顶层 `providers` 中。 |
|
||||
| `aliases` | `Record<string, object>` | 在目录或抑制规划中应解析为所属 provider 的 provider 别名。 |
|
||||
| `suppressions` | `object[]` | 由于 provider 特定原因,被此插件从其他来源抑制的模型条目。 |
|
||||
| `discovery` | `Record<string, "static" \| "refreshable" \| "runtime">` | provider 目录是否可从清单元数据读取、刷新到缓存,或需要运行时。 |
|
||||
|
||||
provider 字段:
|
||||
Provider 字段:
|
||||
|
||||
| 字段 | 类型 | 含义 |
|
||||
| --------- | ------------------------ | ----------------------------------------------------------------- |
|
||||
| `baseUrl` | `string` | 此 provider 目录中模型的可选默认 base URL。 |
|
||||
| `api` | `ModelApi` | 此 provider 目录中模型的可选默认 API 适配器。 |
|
||||
| `headers` | `Record<string, string>` | 应用于此 provider 目录的可选静态标头。 |
|
||||
| `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` | 可选的逐模型 base URL 覆盖。 |
|
||||
| `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"` | 列表状态。仅当该行完全不应出现时才使用抑制。 |
|
||||
| `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` | 模型是否公开 reasoning 行为。 |
|
||||
| `contextWindow` | `number` | 原生 provider 上下文窗口。 |
|
||||
| `contextTokens` | `number` | 当与 `contextWindow` 不同时,可选的实际运行时上下文上限。 |
|
||||
| `maxTokens` | `number` | 已知时的最大输出 token 数。 |
|
||||
| `cost` | `object` | 可选的每百万 token 美元定价,包括可选的 `tieredPricing`。 |
|
||||
| `compat` | `object` | 与 OpenClaw 模型配置兼容性相匹配的可选兼容性标志。 |
|
||||
| `status` | `"available"` \| `"preview"` \| `"deprecated"` \| `"disabled"` | 列表状态。仅当该条目绝对不能出现时才使用抑制。 |
|
||||
| `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`。
|
||||
|
||||
### OpenClaw Provider Index
|
||||
|
||||
OpenClaw Provider Index 是由 OpenClaw 拥有的预览元数据,用于那些其插件可能尚未安装的 provider。它不是插件清单的一部分。插件清单仍然是已安装插件的权威来源。Provider Index 是内部回退契约,未来可安装 provider 和预安装模型选择器界面会在 provider 插件未安装时使用它。
|
||||
OpenClaw Provider Index 是由 OpenClaw 拥有的预览元数据,用于其插件可能尚未安装的 providers。它不是插件清单的一部分。插件清单仍然是已安装插件的权威来源。Provider Index 是未来可安装 provider 和预安装模型选择器界面在 provider 插件尚未安装时将使用的内部回退契约。
|
||||
|
||||
目录权威顺序:
|
||||
|
||||
1. 用户配置。
|
||||
2. 已安装插件清单 `modelCatalog`。
|
||||
3. 显式刷新得到的模型目录缓存。
|
||||
4. OpenClaw Provider Index 预览行。
|
||||
2. 已安装插件清单中的 `modelCatalog`。
|
||||
3. 通过显式刷新得到的模型目录缓存。
|
||||
4. OpenClaw Provider Index 预览条目。
|
||||
|
||||
Provider Index 不得包含机密、启用状态、运行时 hook 或实时的账户特定模型数据。它的预览目录使用与插件清单相同的 `modelCatalog` provider 行结构,但除非运行时适配器字段(如 `api`、`baseUrl`、定价或兼容标志)被有意与已安装插件清单保持一致,否则应限制为稳定显示元数据。具有实时 `/models` 发现能力的 provider,应通过显式模型目录缓存路径写入刷新后的行,而不是在常规列表或 onboarding 期间调用 provider API。
|
||||
Provider Index 不得包含机密、启用状态、运行时 hooks 或实时账户特定模型数据。它的预览目录使用与插件清单相同的 `modelCatalog` provider 条目结构,但除非像 `api`、`baseUrl`、定价或兼容性标志这类运行时适配器字段有意与已安装插件清单保持一致,否则应限制为稳定的显示元数据。具有实时 `/models` 发现能力的 providers 应通过显式模型目录缓存路径写入刷新后的条目,而不是在常规列表或 onboarding 中调用 provider API。
|
||||
|
||||
旧版顶层能力键已弃用。使用 `openclaw doctor --fix` 将
|
||||
`speechProviders`、`realtimeTranscriptionProviders`、
|
||||
`realtimeVoiceProviders`、`mediaUnderstandingProviders`、
|
||||
`imageGenerationProviders`、`videoGenerationProviders`、
|
||||
`webFetchProviders` 和 `webSearchProviders`
|
||||
移动到 `contracts` 下;常规清单加载已不再将这些顶层字段视为能力归属。
|
||||
Provider Index 条目还可以携带可安装插件元数据,用于那些插件已移出核心或尚未安装的 providers。此元数据遵循渠道目录模式:包名、npm 安装说明、预期完整性,以及轻量凭证选项标签,足以显示一个可安装的设置选项。一旦插件安装完成,其清单即成为优先来源,Provider Index 中该 provider 的条目会被忽略。
|
||||
|
||||
## 清单与 `package.json` 的区别
|
||||
旧版顶层能力键已弃用。使用 `openclaw doctor --fix` 将 `speechProviders`、`realtimeTranscriptionProviders`、`realtimeVoiceProviders`、`mediaUnderstandingProviders`、`imageGenerationProviders`、`videoGenerationProviders`、`webFetchProviders` 和 `webSearchProviders` 移动到 `contracts` 下;常规清单加载不再将这些顶层字段视为能力归属。
|
||||
|
||||
这两个文件承担不同职责:
|
||||
## 清单与 package.json 的区别
|
||||
|
||||
这两个文件承担不同的职责:
|
||||
|
||||
| 文件 | 用途 |
|
||||
| ---------------------- | -------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `openclaw.plugin.json` | 发现、配置校验、认证选项元数据,以及必须在插件代码运行前存在的 UI 提示 |
|
||||
| `package.json` | npm 元数据、依赖安装,以及用于入口点、安装门控、设置或目录元数据的 `openclaw` 配置块 |
|
||||
| `openclaw.plugin.json` | 发现、配置校验、凭证选项元数据,以及必须在插件代码运行前存在的 UI 提示 |
|
||||
| `package.json` | npm 元数据、依赖安装,以及 `openclaw` 代码块中用于入口点、安装门控、设置或目录元数据的内容 |
|
||||
|
||||
如果你不确定某段元数据应放在哪里,请使用这个规则:
|
||||
如果你不确定某段元数据应放在哪里,请使用以下规则:
|
||||
|
||||
- 如果 OpenClaw 必须在加载插件代码之前知道它,请将其放在 `openclaw.plugin.json` 中
|
||||
- 如果它与打包、入口文件或 npm 安装行为有关,请将其放在 `package.json` 中
|
||||
- 如果 OpenClaw 必须在加载插件代码之前知道它,就把它放在 `openclaw.plugin.json` 中
|
||||
- 如果它与打包、入口文件或 npm 安装行为有关,就把它放在 `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` | 轻量级渠道目录元数据,例如标签、文档路径、别名和选择文案。 |
|
||||
| `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` | 在 onboarding、延迟渠道启动以及只读渠道 Status/SecretRef 发现期间使用的轻量级、仅设置入口点。必须保持在插件包目录内。 |
|
||||
| `openclaw.runtimeSetupEntry` | 声明已安装包的已构建 JavaScript 设置入口点。必须保持在插件包目录内。 |
|
||||
| `openclaw.channel` | 轻量渠道目录元数据,例如标签、文档路径、别名和选择文案。 |
|
||||
| `openclaw.channel.configuredState` | 轻量级 configured-state 检查器元数据,可在不加载完整渠道运行时的情况下回答“是否已经存在仅由环境变量驱动的设置?”。 |
|
||||
| `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` 中。
|
||||
清单元数据决定了在运行时加载前,onboarding 中会出现哪些 provider/渠道/设置选项。`package.json#openclaw.install` 则告诉 onboarding,当用户选择这些选项之一时,应如何获取或启用该插件。不要将安装提示移到 `openclaw.plugin.json` 中。
|
||||
|
||||
`openclaw.install.minHostVersion` 会在安装和清单注册表加载期间强制执行。无效值会被拒绝;在旧主机上,较新但有效的值会导致跳过该插件。
|
||||
`openclaw.install.minHostVersion` 会在安装和清单注册表加载期间强制执行。无效值会被拒绝;较新的但有效的值会让旧宿主跳过该插件。
|
||||
|
||||
精确的 npm 版本固定已经存在于 `npmSpec` 中,例如
|
||||
`"npmSpec": "@wecom/wecom-openclaw-plugin@1.2.3"`。官方外部目录条目应将精确 spec 与 `expectedIntegrity` 配对使用,这样如果获取到的 npm 工件不再匹配已固定的发布版本,更新流程就会采用失败即关闭策略。出于兼容性考虑,交互式 onboarding 仍会提供受信任注册表的 npm spec,包括裸包名和 dist-tag。目录诊断可以区分精确来源、浮动来源、带完整性固定的来源、缺少完整性的来源、包名不匹配来源以及无效默认选项来源。如果存在 `expectedIntegrity`,但没有可供其固定的有效 npm 来源,它们也会发出警告。当存在 `expectedIntegrity` 时,安装/更新流程会强制执行;当省略时,注册表解析结果会被记录,但没有完整性固定。
|
||||
精确的 npm 版本固定已经在 `npmSpec` 中,例如
|
||||
`"npmSpec": "@wecom/wecom-openclaw-plugin@1.2.3"`。官方外部目录条目应将精确 spec 与 `expectedIntegrity` 配对使用,以便当获取到的 npm 构件不再匹配固定版本时,更新流程会采用失败关闭。为了兼容性,交互式 onboarding 仍会提供受信任注册表的 npm specs,包括裸包名和 dist-tags。目录诊断可以区分精确、浮动、带完整性固定、缺少完整性、包名不匹配和无效默认选项来源。它们还会在存在 `expectedIntegrity` 但没有可用于固定的有效 npm 源时发出警告。当存在 `expectedIntegrity` 时,安装/更新流程会强制执行它;当省略该字段时,注册表解析结果会被记录,但不会附带完整性固定。
|
||||
|
||||
当 Status、渠道列表或 SecretRef 扫描需要在不加载完整运行时的情况下识别已配置账号时,渠道插件应提供 `openclaw.setupEntry`。该设置入口应暴露渠道元数据,以及适用于设置的安全配置、Status 和 secrets 适配器;网络客户端、网关监听器和传输运行时应保留在主扩展入口点中。
|
||||
当 Status、渠道列表或 SecretRef 扫描需要在不加载完整运行时的情况下识别已配置账号时,渠道插件应提供 `openclaw.setupEntry`。该设置入口应公开渠道元数据,以及对设置安全的配置、Status 和 secrets 适配器;网络客户端、网关监听器和传输运行时应保留在主扩展入口点中。
|
||||
|
||||
运行时入口点字段不会覆盖源码入口点字段的包边界检查。例如,`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` 是一个微型检查器模块的包元数据:
|
||||
|
||||
@ -718,9 +708,9 @@ Provider Index 不得包含机密、启用状态、运行时 hook 或实时的
|
||||
}
|
||||
```
|
||||
|
||||
当设置、Doctor 或已配置状态流程需要在完整渠道插件加载前进行一个低成本的是/否认证探测时,请使用它。目标导出应是一个仅读取持久化状态的小函数;不要通过完整渠道运行时 barrel 转发它。
|
||||
当设置、Doctor 或 configured-state 流程需要在完整渠道插件加载前执行轻量级的是/否凭证探测时,请使用它。目标导出应是一个只读取持久化状态的小函数;不要通过完整渠道运行时 barrel 转发它。
|
||||
|
||||
`openclaw.channel.configuredState` 对于低成本的仅环境变量已配置检查,采用相同的结构:
|
||||
`openclaw.channel.configuredState` 对轻量级的、仅由环境变量驱动的配置检查使用相同结构:
|
||||
|
||||
```json
|
||||
{
|
||||
@ -736,53 +726,54 @@ Provider Index 不得包含机密、启用状态、运行时 hook 或实时的
|
||||
}
|
||||
```
|
||||
|
||||
当一个渠道可以仅根据环境变量或其他微型非运行时输入来回答其已配置状态时,请使用它。如果该检查需要完整配置解析或真实渠道运行时,请改为将该逻辑保留在插件 `config.hasConfiguredState` hook 中。
|
||||
当某个渠道可以通过环境变量或其他微型非运行时输入来回答 configured-state 时,请使用它。如果该检查需要完整配置解析或真实渠道运行时,请将该逻辑保留在插件 `config.hasConfiguredState` hook 中。
|
||||
|
||||
## 发现优先级(重复插件 id)
|
||||
|
||||
OpenClaw 会从多个根目录发现插件(内置、全局安装、工作区、配置中显式选择的路径)。如果两个发现结果共享相同的 `id`,则只保留**优先级最高**的清单;较低优先级的重复项会被丢弃,而不是与其并行加载。
|
||||
OpenClaw 会从多个根路径发现插件(内置、全局安装、工作区、显式配置选择的路径)。如果两个发现结果共享同一个 `id`,则只保留**最高优先级**的清单;较低优先级的重复项会被丢弃,而不是并排加载。
|
||||
|
||||
优先级从高到低如下:
|
||||
|
||||
1. **配置中选定** —— 在 `plugins.entries.<id>` 中显式固定的路径
|
||||
1. **配置选中** —— 在 `plugins.entries.<id>` 中显式固定的路径
|
||||
2. **内置** —— 随 OpenClaw 一起发布的插件
|
||||
3. **全局安装** —— 安装到全局 OpenClaw 插件根目录中的插件
|
||||
3. **全局安装** —— 安装到全局 OpenClaw 插件根目录的插件
|
||||
4. **工作区** —— 相对于当前工作区发现的插件
|
||||
|
||||
影响:
|
||||
|
||||
- 位于工作区中的某个内置插件 fork 或陈旧副本,不会遮蔽内置构建版本。
|
||||
- 如果要真正用本地插件覆盖一个内置插件,请通过 `plugins.entries.<id>` 固定它,使其依靠优先级胜出,而不是依赖工作区发现。
|
||||
- 被丢弃的重复项会被记录日志,以便 Doctor 和启动诊断能指出被舍弃的副本。
|
||||
- 工作区中某个内置插件的 fork 或陈旧副本不会遮蔽内置构建。
|
||||
- 若要真正用本地插件覆盖内置插件,请通过 `plugins.entries.<id>` 固定它,使其依靠优先级获胜,而不是依赖工作区发现。
|
||||
- 被丢弃的重复项会记录到日志中,以便 Doctor 和启动诊断能够指向被舍弃的副本。
|
||||
|
||||
## JSON Schema 要求
|
||||
|
||||
- **每个插件都必须提供一个 JSON Schema**,即使它不接受任何配置。
|
||||
- 允许空 schema(例如 `{ "type": "object", "additionalProperties": false }`)。
|
||||
- Schema 会在配置读写时校验,而不是在运行时校验。
|
||||
- 空 schema 也是可以接受的(例如 `{ "type": "object", "additionalProperties": false }`)。
|
||||
- Schema 会在配置读取/写入时校验,而不是在运行时校验。
|
||||
|
||||
## 校验行为
|
||||
|
||||
- 未知的 `channels.*` 键是**错误**,除非该渠道 id 由某个插件清单声明。
|
||||
- 未知的 `channels.*` 键是**错误**,除非该渠道 id 已由
|
||||
某个插件清单声明。
|
||||
- `plugins.entries.<id>`、`plugins.allow`、`plugins.deny` 和 `plugins.slots.*`
|
||||
必须引用**可发现的**插件 id。未知 id 属于**错误**。
|
||||
- 如果某个插件已安装,但其清单或 schema 缺失或损坏,
|
||||
- 如果插件已安装,但其清单或 schema 损坏或缺失,
|
||||
校验会失败,Doctor 会报告该插件错误。
|
||||
- 如果插件配置存在,但插件处于**禁用**状态,则该配置会被保留,并且
|
||||
Doctor + 日志中会显示一条**警告**。
|
||||
- 如果插件配置存在,但插件已**禁用**,该配置会被保留,
|
||||
并会在 Doctor + 日志中显示一条**警告**。
|
||||
|
||||
有关完整 `plugins.*` schema,请参见 [配置参考](/zh-CN/gateway/configuration)。
|
||||
有关完整的 `plugins.*` schema,请参阅[配置参考](/zh-CN/gateway/configuration)。
|
||||
|
||||
## 说明
|
||||
|
||||
- **原生 OpenClaw 插件必须提供清单**,包括本地文件系统加载。运行时仍会单独加载插件模块;清单仅用于发现 + 校验。
|
||||
- 原生清单使用 JSON5 解析,因此允许注释、尾随逗号和未加引号的键,只要最终值仍然是一个对象即可。
|
||||
- 清单加载器只会读取有文档记录的清单字段。请避免使用自定义顶层键。
|
||||
- 当插件不需要它们时,可以省略 `channels`、`providers`、`cliBackends` 和 `skills`。
|
||||
- 清单对于**原生 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 runtime hooks](/zh-CN/plugins/architecture-internals#provider-runtime-hooks)。
|
||||
- 互斥插件类型通过 `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)。
|
||||
- 如果你的插件依赖原生模块,请记录构建步骤以及任何包管理器 allowlist 要求(例如 pnpm `allow-build-scripts` + `pnpm rebuild <package>`)。
|
||||
|
||||
## 相关内容
|
||||
@ -794,7 +785,7 @@ OpenClaw 会从多个根目录发现插件(内置、全局安装、工作区
|
||||
<Card title="插件架构" href="/zh-CN/plugins/architecture" icon="diagram-project">
|
||||
内部架构和能力模型。
|
||||
</Card>
|
||||
<Card title="插件 SDK 概览" href="/zh-CN/plugins/sdk-overview" icon="book">
|
||||
<Card title="SDK 概览" href="/zh-CN/plugins/sdk-overview" icon="book">
|
||||
插件 SDK 参考和子路径导入。
|
||||
</Card>
|
||||
</CardGroup>
|
||||
|
||||
@ -1,288 +1,298 @@
|
||||
---
|
||||
read_when:
|
||||
- 向新用户介绍 ClawHub
|
||||
- 安装、搜索或发布 Skills 或插件
|
||||
- 解释 ClawHub CLI 标志和同步行为
|
||||
summary: ClawHub 指南:公共注册表、原生 OpenClaw 安装流程和 ClawHub CLI 工作流
|
||||
- 搜索、安装或更新 Skills 或插件
|
||||
- 将 Skills 或插件发布到注册表
|
||||
- 配置 `clawhub` CLI 或其环境变量覆盖项
|
||||
sidebarTitle: ClawHub
|
||||
summary: ClawHub:面向 OpenClaw Skills 和插件的公开注册表、原生安装流程,以及 `clawhub` CLI
|
||||
title: ClawHub
|
||||
x-i18n:
|
||||
generated_at: "2026-04-23T23:04:32Z"
|
||||
generated_at: "2026-04-26T06:01:22Z"
|
||||
model: gpt-5.4
|
||||
provider: openai
|
||||
source_hash: 887bbf942238e3aee84389aa1c85b31b263144021301de37452522e215a0b1e5
|
||||
source_hash: 9e002bb56b643bfdfb5715ac3632d854df182475be632ebe36c46d04008cf6e5
|
||||
source_path: tools/clawhub.md
|
||||
workflow: 15
|
||||
---
|
||||
|
||||
ClawHub 是 **OpenClaw Skills 和插件**的公共注册表。
|
||||
ClawHub 是面向 **OpenClaw Skills 和插件** 的公开注册表。
|
||||
|
||||
- 使用原生 `openclaw` 命令来搜索/安装/更新 Skills,以及从 ClawHub 安装插件。
|
||||
- 当你需要注册表认证、发布、删除、恢复删除或同步工作流时,请使用单独的 `clawhub` CLI。
|
||||
- 使用原生 `openclaw` 命令来搜索、安装和更新 Skills,以及从 ClawHub 安装插件。
|
||||
- 使用单独的 `clawhub` CLI 进行注册表认证、发布、删除 / 恢复删除,以及同步工作流。
|
||||
|
||||
站点:[clawhub.ai](https://clawhub.ai)
|
||||
网站:[clawhub.ai](https://clawhub.ai)
|
||||
|
||||
## 原生 OpenClaw 工作流
|
||||
## 快速开始
|
||||
|
||||
Skills:
|
||||
<Steps>
|
||||
<Step title="搜索">
|
||||
```bash
|
||||
openclaw skills search "calendar"
|
||||
```
|
||||
</Step>
|
||||
<Step title="安装">
|
||||
```bash
|
||||
openclaw skills install <skill-slug>
|
||||
```
|
||||
</Step>
|
||||
<Step title="使用">
|
||||
启动一个新的 OpenClaw 会话——它会识别新安装的 Skill。
|
||||
</Step>
|
||||
<Step title="发布(可选)">
|
||||
对于需要注册表认证的工作流(发布、同步、管理),请安装单独的 `clawhub` CLI:
|
||||
|
||||
```bash
|
||||
openclaw skills search "calendar"
|
||||
openclaw skills install <skill-slug>
|
||||
openclaw skills update --all
|
||||
```
|
||||
```bash
|
||||
npm i -g clawhub
|
||||
# or
|
||||
pnpm add -g clawhub
|
||||
```
|
||||
|
||||
插件:
|
||||
</Step>
|
||||
</Steps>
|
||||
|
||||
```bash
|
||||
openclaw plugins install clawhub:<package>
|
||||
openclaw plugins update --all
|
||||
```
|
||||
## 原生 OpenClaw 流程
|
||||
|
||||
裸 npm 安全插件规格也会在 npm 之前优先尝试 ClawHub:
|
||||
<Tabs>
|
||||
<Tab title="Skills">
|
||||
```bash
|
||||
openclaw skills search "calendar"
|
||||
openclaw skills install <skill-slug>
|
||||
openclaw skills update --all
|
||||
```
|
||||
|
||||
```bash
|
||||
openclaw plugins install openclaw-codex-app-server
|
||||
```
|
||||
原生 `openclaw` 命令会安装到你的当前工作区中,并持久保存源元数据,以便后续的 `update` 调用能够继续使用 ClawHub。
|
||||
|
||||
原生 `openclaw` 命令会安装到你当前活动工作区中,并持久保存来源元数据,以便后续 `update` 调用可以继续留在 ClawHub 上。
|
||||
</Tab>
|
||||
<Tab title="插件">
|
||||
```bash
|
||||
openclaw plugins install clawhub:<package>
|
||||
openclaw plugins update --all
|
||||
```
|
||||
|
||||
插件安装会在归档安装开始前验证声明的 `pluginApi` 和 `minGatewayVersion`
|
||||
兼容性,因此不兼容的宿主会尽早以默认拒绝方式失败,而不会部分安装该包。
|
||||
裸的、符合 npm 安全规范的插件说明符也会在 npm 之前先尝试通过 ClawHub 解析:
|
||||
|
||||
`openclaw plugins install clawhub:...` 只接受可安装的插件家族。
|
||||
如果某个 ClawHub 包实际上是一个 Skill,OpenClaw 会停止并提示你改用
|
||||
`openclaw skills install <slug>`。
|
||||
```bash
|
||||
openclaw plugins install openclaw-codex-app-server
|
||||
```
|
||||
|
||||
插件安装会在归档安装开始前验证所声明的 `pluginApi` 和 `minGatewayVersion` 兼容性,因此不兼容的宿主会尽早以关闭方式失败,而不是在包部分安装后才失败。
|
||||
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
<Note>
|
||||
`openclaw plugins install clawhub:...` 只接受可安装的插件族。如果某个 ClawHub 包实际上是一个 Skill,OpenClaw 会停止操作,并改为提示你使用 `openclaw skills install <slug>`。
|
||||
|
||||
匿名安装 ClawHub 插件时,私有包同样会以关闭方式失败。社区或其他非官方渠道仍然可以安装,但 OpenClaw 会发出警告,以便运营者在启用前审查来源和验证信息。
|
||||
</Note>
|
||||
|
||||
## ClawHub 是什么
|
||||
|
||||
- OpenClaw Skills 和插件的公共注册表。
|
||||
- Skills bundle 和元数据的版本化存储。
|
||||
- 用于搜索、标签和使用信号的发现界面。
|
||||
- 一个面向 OpenClaw Skills 和插件的公开注册表。
|
||||
- 一个带版本管理的 Skill 包和元数据存储。
|
||||
- 一个用于搜索、标签和使用信号的发现入口。
|
||||
|
||||
## 工作原理
|
||||
一个典型的 Skill 是一个带版本的文件包,通常包含:
|
||||
|
||||
1. 用户发布一个 Skill bundle(文件 + 元数据)。
|
||||
2. ClawHub 存储该 bundle,解析元数据,并分配一个版本。
|
||||
3. 注册表为该 Skill 建立索引,以支持搜索和发现。
|
||||
4. 用户在 OpenClaw 中浏览、下载并安装 Skills。
|
||||
|
||||
## 你可以做什么
|
||||
|
||||
- 发布新 Skills,以及现有 Skills 的新版本。
|
||||
- 通过名称、标签或搜索发现 Skills。
|
||||
- 下载 Skill bundle 并检查其中的文件。
|
||||
- 举报滥用或不安全的 Skills。
|
||||
- 如果你是版主,可以隐藏、取消隐藏、删除或封禁。
|
||||
|
||||
## 适合谁使用(对新手友好)
|
||||
|
||||
如果你想为 OpenClaw 智能体添加新能力,ClawHub 是查找和安装 Skills 的最简单方式。你不需要了解后端如何工作。你可以:
|
||||
|
||||
- 使用自然语言搜索 Skills。
|
||||
- 将 Skill 安装到你的工作区中。
|
||||
- 之后用一条命令更新 Skills。
|
||||
- 通过发布自己的 Skills 来备份它们。
|
||||
|
||||
## 快速开始(非技术用户)
|
||||
|
||||
1. 搜索你需要的内容:
|
||||
- `openclaw skills search "calendar"`
|
||||
2. 安装一个 Skill:
|
||||
- `openclaw skills install <skill-slug>`
|
||||
3. 启动一个新的 OpenClaw 会话,让它加载新的 Skill。
|
||||
4. 如果你想发布内容或管理注册表认证,请另外安装
|
||||
`clawhub` CLI。
|
||||
|
||||
## 安装 ClawHub CLI
|
||||
|
||||
你只在需要注册表认证工作流(如发布/同步)时才需要它:
|
||||
|
||||
```bash
|
||||
npm i -g clawhub
|
||||
```
|
||||
|
||||
```bash
|
||||
pnpm add -g clawhub
|
||||
```
|
||||
|
||||
## 它如何融入 OpenClaw
|
||||
|
||||
原生 `openclaw skills install` 会安装到当前活动工作区的 `skills/`
|
||||
目录中。`openclaw plugins install clawhub:...` 会记录一次正常的受管插件安装,
|
||||
并额外记录 ClawHub 来源元数据以供更新使用。
|
||||
|
||||
匿名 ClawHub 插件安装也会对私有包采用默认拒绝方式失败。
|
||||
社区或其他非官方渠道仍可安装,但 OpenClaw 会发出警告,
|
||||
以便操作员在启用前审查来源和验证信息。
|
||||
|
||||
单独的 `clawhub` CLI 也会将 Skills 安装到当前工作目录下的 `./skills` 中。
|
||||
如果已配置 OpenClaw 工作区,`clawhub`
|
||||
会回退到该工作区,除非你通过 `--workdir`(或
|
||||
`CLAWHUB_WORKDIR`)进行覆盖。OpenClaw 会从 `<workspace>/skills`
|
||||
加载工作区 Skills,并会在**下一个**会话中加载它们。如果你已经在使用
|
||||
`~/.openclaw/skills` 或内置 Skills,工作区 Skills 会优先生效。
|
||||
|
||||
有关 Skills 如何加载、共享和门控的更多详情,请参阅
|
||||
[Skills](/zh-CN/tools/skills)。
|
||||
|
||||
## Skill 系统概览
|
||||
|
||||
Skill 是一个带版本的文件 bundle,用于教会 OpenClaw 如何执行特定任务。每次发布都会创建一个新版本,而注册表会保留版本历史,以便用户审计变更。
|
||||
|
||||
一个典型的 Skill 包括:
|
||||
|
||||
- 一个 `SKILL.md` 文件,包含主要描述和用法。
|
||||
- 可选的配置、脚本或 Skill 使用的支持文件。
|
||||
- 一个 `SKILL.md` 文件,内含主要描述和使用方式。
|
||||
- Skill 所使用的可选配置、脚本或辅助文件。
|
||||
- 标签、摘要和安装要求等元数据。
|
||||
|
||||
ClawHub 使用元数据来支持发现,并安全地暴露 Skill 能力。
|
||||
注册表还会跟踪使用信号(如星标和下载量),以改善排序和可见性。
|
||||
ClawHub 使用元数据来支持发现能力,并安全地公开 Skill 的能力。注册表会追踪使用信号(星标、下载量)以改进排序和可见性。每次发布都会创建一个新的 semver 版本,注册表会保留版本历史,以便用户审计变更。
|
||||
|
||||
## 服务提供的内容(功能)
|
||||
## 工作区和 Skill 加载
|
||||
|
||||
- **公开浏览** Skills 及其 `SKILL.md` 内容。
|
||||
- 由 embeddings(向量搜索)驱动的**搜索**,而不仅仅是关键词。
|
||||
- 带 semver、变更日志和标签(包括 `latest`)的**版本控制**。
|
||||
- 每个版本以 zip 格式提供的**下载**。
|
||||
- 用于社区反馈的**星标和评论**。
|
||||
- 用于审批和审计的**审核** hook。
|
||||
- 面向自动化和脚本的**CLI 友好 API**。
|
||||
单独的 `clawhub` CLI 也会将 Skills 安装到当前工作目录下的 `./skills` 中。如果已配置 OpenClaw 工作区,`clawhub` 会回退到该工作区,除非你使用 `--workdir`(或 `CLAWHUB_WORKDIR`)覆盖。OpenClaw 会从 `<workspace>/skills` 加载工作区 Skills,并在**下一次**会话中识别它们。
|
||||
|
||||
## 安全和审核
|
||||
如果你已经在使用 `~/.openclaw/skills` 或内置 Skills,工作区 Skills 会优先生效。关于 Skills 如何加载、共享和受限的更多细节,请参阅 [Skills](/zh-CN/tools/skills)。
|
||||
|
||||
ClawHub 默认开放。任何人都可以上传 Skills,但 GitHub 账户必须至少存在一周才能发布。这有助于减缓滥用行为,同时不阻碍合法贡献者。
|
||||
## 服务功能
|
||||
|
||||
举报和审核:
|
||||
| 功能 | 说明 |
|
||||
| ------------------ | ---------------------------------------------------------- |
|
||||
| 公开浏览 | Skills 及其 `SKILL.md` 内容可公开查看。 |
|
||||
| 搜索 | 由嵌入驱动(向量搜索),而不只是关键词。 |
|
||||
| 版本管理 | Semver、更新日志和标签(包括 `latest`)。 |
|
||||
| 下载 | 每个版本提供 Zip。 |
|
||||
| 星标和评论 | 社区反馈。 |
|
||||
| 审核 | 审批和审计。 |
|
||||
| 适合 CLI 的 API | 适用于自动化和脚本编写。 |
|
||||
|
||||
- 任何已登录用户都可以举报 Skill。
|
||||
- 举报原因是必填项并会被记录。
|
||||
- 每个用户最多可同时拥有 20 个活跃举报。
|
||||
- 超过 3 个不同用户举报的 Skill 默认会被自动隐藏。
|
||||
- 版主可以查看隐藏的 Skills、取消隐藏、删除它们,或封禁用户。
|
||||
- 滥用举报功能可能导致账户被封禁。
|
||||
## 安全性与审核
|
||||
|
||||
有兴趣成为版主?请在 OpenClaw Discord 中联系版主或维护者。
|
||||
ClawHub 默认开放——任何人都可以上传 Skills,但发布者的 GitHub 账号必须**至少注册满一周**。这样可以减缓滥用,同时不阻碍合法贡献者。
|
||||
|
||||
## CLI 命令和参数
|
||||
<AccordionGroup>
|
||||
<Accordion title="举报">
|
||||
- 任何已登录用户都可以举报一个 Skill。
|
||||
- 举报原因是必填项,并会被记录。
|
||||
- 每位用户同时最多可有 20 个有效举报。
|
||||
- 收到超过 3 个不同用户举报的 Skill 默认会被自动隐藏。
|
||||
</Accordion>
|
||||
<Accordion title="审核">
|
||||
- 审核员可以查看被隐藏的 Skills、取消隐藏、删除它们,或封禁用户。
|
||||
- 滥用举报功能可能导致账号被封禁。
|
||||
- 想成为审核员?请在 OpenClaw Discord 中提出,并联系一位审核员或维护者。
|
||||
</Accordion>
|
||||
</AccordionGroup>
|
||||
|
||||
全局选项(适用于所有命令):
|
||||
## ClawHub CLI
|
||||
|
||||
- `--workdir <dir>`:工作目录(默认:当前目录;会回退到 OpenClaw 工作区)。
|
||||
- `--dir <dir>`:Skills 目录,相对于 workdir(默认:`skills`)。
|
||||
- `--site <url>`:站点基础 URL(浏览器登录)。
|
||||
- `--registry <url>`:注册表 API 基础 URL。
|
||||
- `--no-input`:禁用提示(非交互式)。
|
||||
- `-V, --cli-version`:打印 CLI 版本。
|
||||
你只在需要注册表认证的工作流(例如发布 / 同步)时才需要它。
|
||||
|
||||
认证:
|
||||
### 全局选项
|
||||
|
||||
- `clawhub login`(浏览器流程)或 `clawhub login --token <token>`
|
||||
- `clawhub logout`
|
||||
- `clawhub whoami`
|
||||
<ParamField path="--workdir <dir>" type="string">
|
||||
工作目录。默认:当前目录;回退到 OpenClaw 工作区。
|
||||
</ParamField>
|
||||
<ParamField path="--dir <dir>" type="string" default="skills">
|
||||
Skills 目录,相对于 workdir。
|
||||
</ParamField>
|
||||
<ParamField path="--site <url>" type="string">
|
||||
站点基础 URL(浏览器登录)。
|
||||
</ParamField>
|
||||
<ParamField path="--registry <url>" type="string">
|
||||
注册表 API 基础 URL。
|
||||
</ParamField>
|
||||
<ParamField path="--no-input" type="boolean">
|
||||
禁用提示(非交互模式)。
|
||||
</ParamField>
|
||||
<ParamField path="-V, --cli-version" type="boolean">
|
||||
打印 CLI 版本。
|
||||
</ParamField>
|
||||
|
||||
选项:
|
||||
### 命令
|
||||
|
||||
- `--token <token>`:粘贴一个 API token。
|
||||
- `--label <label>`:为浏览器登录 token 存储的标签(默认:`CLI token`)。
|
||||
- `--no-browser`:不打开浏览器(需要 `--token`)。
|
||||
<AccordionGroup>
|
||||
<Accordion title="认证(login / logout / whoami)">
|
||||
```bash
|
||||
clawhub login # browser flow
|
||||
clawhub login --token <token>
|
||||
clawhub logout
|
||||
clawhub whoami
|
||||
```
|
||||
|
||||
搜索:
|
||||
登录选项:
|
||||
|
||||
- `clawhub search "query"`
|
||||
- `--limit <n>`:最大结果数。
|
||||
- `--token <token>` — 粘贴一个 API 令牌。
|
||||
- `--label <label>` — 为浏览器登录令牌存储的标签(默认:`CLI token`)。
|
||||
- `--no-browser` — 不打开浏览器(需要 `--token`)。
|
||||
|
||||
安装:
|
||||
</Accordion>
|
||||
<Accordion title="搜索">
|
||||
```bash
|
||||
clawhub search "query"
|
||||
```
|
||||
|
||||
- `clawhub install <slug>`
|
||||
- `--version <version>`:安装指定版本。
|
||||
- `--force`:如果目录已存在则覆盖。
|
||||
- `--limit <n>` — 最大结果数。
|
||||
|
||||
更新:
|
||||
</Accordion>
|
||||
<Accordion title="安装 / 更新 / 列表">
|
||||
```bash
|
||||
clawhub install <slug>
|
||||
clawhub update <slug>
|
||||
clawhub update --all
|
||||
clawhub list
|
||||
```
|
||||
|
||||
- `clawhub update <slug>`
|
||||
- `clawhub update --all`
|
||||
- `--version <version>`:更新到指定版本(仅单个 slug)。
|
||||
- `--force`:当本地文件与任何已发布版本都不匹配时覆盖。
|
||||
选项:
|
||||
|
||||
列表:
|
||||
- `--version <version>` — 安装或更新到指定版本(在 `update` 中仅适用于单个 slug)。
|
||||
- `--force` — 如果文件夹已存在,或本地文件与任何已发布版本都不匹配时,执行覆盖。
|
||||
- `clawhub list` 会读取 `.clawhub/lock.json`。
|
||||
|
||||
- `clawhub list`(读取 `.clawhub/lock.json`)
|
||||
</Accordion>
|
||||
<Accordion title="发布 Skills">
|
||||
```bash
|
||||
clawhub skill publish <path>
|
||||
```
|
||||
|
||||
发布 Skills:
|
||||
选项:
|
||||
|
||||
- `clawhub skill publish <path>`
|
||||
- `--slug <slug>`:Skill slug。
|
||||
- `--name <name>`:显示名称。
|
||||
- `--version <version>`:semver 版本。
|
||||
- `--changelog <text>`:变更日志文本(可为空)。
|
||||
- `--tags <tags>`:逗号分隔标签(默认:`latest`)。
|
||||
- `--slug <slug>` — Skill slug。
|
||||
- `--name <name>` — 显示名称。
|
||||
- `--version <version>` — semver 版本。
|
||||
- `--changelog <text>` — 更新日志文本(可以为空)。
|
||||
- `--tags <tags>` — 逗号分隔的标签(默认:`latest`)。
|
||||
|
||||
发布插件:
|
||||
</Accordion>
|
||||
<Accordion title="发布插件">
|
||||
```bash
|
||||
clawhub package publish <source>
|
||||
```
|
||||
|
||||
- `clawhub package publish <source>`
|
||||
- `<source>` 可以是本地文件夹、`owner/repo`、`owner/repo@ref` 或 GitHub URL。
|
||||
- `--dry-run`:构建精确的发布计划,但不上传任何内容。
|
||||
- `--json`:输出面向 CI 的机器可读格式。
|
||||
- `--source-repo`、`--source-commit`、`--source-ref`:当自动检测不够时可用的可选覆盖。
|
||||
`<source>` 可以是本地文件夹、`owner/repo`、`owner/repo@ref` 或 GitHub URL。
|
||||
|
||||
删除/恢复删除(仅所有者/管理员):
|
||||
选项:
|
||||
|
||||
- `clawhub delete <slug> --yes`
|
||||
- `clawhub undelete <slug> --yes`
|
||||
- `--dry-run` — 构建精确的发布计划,但不上传任何内容。
|
||||
- `--json` — 为 CI 输出机器可读格式。
|
||||
- `--source-repo`、`--source-commit`、`--source-ref` — 当自动检测不足时使用的可选覆盖项。
|
||||
|
||||
同步(扫描本地 Skills + 发布新增/已更新内容):
|
||||
</Accordion>
|
||||
<Accordion title="删除 / 恢复删除(所有者或管理员)">
|
||||
```bash
|
||||
clawhub delete <slug> --yes
|
||||
clawhub undelete <slug> --yes
|
||||
```
|
||||
</Accordion>
|
||||
<Accordion title="同步(扫描本地 + 发布新增或更新项)">
|
||||
```bash
|
||||
clawhub sync
|
||||
```
|
||||
|
||||
- `clawhub sync`
|
||||
- `--root <dir...>`:额外扫描根目录。
|
||||
- `--all`:不提示,直接上传所有内容。
|
||||
- `--dry-run`:显示将要上传的内容。
|
||||
- `--bump <type>`:更新时使用 `patch|minor|major`(默认:`patch`)。
|
||||
- `--changelog <text>`:非交互式更新的变更日志。
|
||||
- `--tags <tags>`:逗号分隔标签(默认:`latest`)。
|
||||
- `--concurrency <n>`:注册表检查并发数(默认:4)。
|
||||
选项:
|
||||
|
||||
## 面向智能体的常见工作流
|
||||
- `--root <dir...>` — 额外的扫描根目录。
|
||||
- `--all` — 不提示,直接上传所有内容。
|
||||
- `--dry-run` — 显示将要上传的内容。
|
||||
- `--bump <type>` — 更新时使用 `patch|minor|major`(默认:`patch`)。
|
||||
- `--changelog <text>` — 非交互更新时的更新日志。
|
||||
- `--tags <tags>` — 逗号分隔的标签(默认:`latest`)。
|
||||
- `--concurrency <n>` — 注册表检查并发数(默认:`4`)。
|
||||
|
||||
### 搜索 Skills
|
||||
</Accordion>
|
||||
</AccordionGroup>
|
||||
|
||||
```bash
|
||||
clawhub search "postgres backups"
|
||||
```
|
||||
## 常见工作流
|
||||
|
||||
### 下载新 Skills
|
||||
<Tabs>
|
||||
<Tab title="搜索">
|
||||
```bash
|
||||
clawhub search "postgres backups"
|
||||
```
|
||||
</Tab>
|
||||
<Tab title="安装">
|
||||
```bash
|
||||
clawhub install my-skill-pack
|
||||
```
|
||||
</Tab>
|
||||
<Tab title="全部更新">
|
||||
```bash
|
||||
clawhub update --all
|
||||
```
|
||||
</Tab>
|
||||
<Tab title="发布单个 Skill">
|
||||
```bash
|
||||
clawhub skill publish ./my-skill --slug my-skill --name "My Skill" --version 1.0.0 --tags latest
|
||||
```
|
||||
</Tab>
|
||||
<Tab title="同步多个 Skills">
|
||||
```bash
|
||||
clawhub sync --all
|
||||
```
|
||||
</Tab>
|
||||
<Tab title="从 GitHub 发布插件">
|
||||
```bash
|
||||
clawhub package publish your-org/your-plugin --dry-run
|
||||
clawhub package publish your-org/your-plugin
|
||||
clawhub package publish your-org/your-plugin@v1.0.0
|
||||
clawhub package publish https://github.com/your-org/your-plugin
|
||||
```
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
```bash
|
||||
clawhub install my-skill-pack
|
||||
```
|
||||
|
||||
### 更新已安装 Skills
|
||||
|
||||
```bash
|
||||
clawhub update --all
|
||||
```
|
||||
|
||||
### 备份你的 Skills(发布或同步)
|
||||
|
||||
对于单个 Skill 文件夹:
|
||||
|
||||
```bash
|
||||
clawhub skill publish ./my-skill --slug my-skill --name "My Skill" --version 1.0.0 --tags latest
|
||||
```
|
||||
|
||||
要一次扫描并备份多个 Skill:
|
||||
|
||||
```bash
|
||||
clawhub sync --all
|
||||
```
|
||||
|
||||
### 从 GitHub 发布插件
|
||||
|
||||
```bash
|
||||
clawhub package publish your-org/your-plugin --dry-run
|
||||
clawhub package publish your-org/your-plugin
|
||||
clawhub package publish your-org/your-plugin@v1.0.0
|
||||
clawhub package publish https://github.com/your-org/your-plugin
|
||||
```
|
||||
### 插件包元数据
|
||||
|
||||
代码插件必须在 `package.json` 中包含所需的 OpenClaw 元数据:
|
||||
|
||||
@ -306,49 +316,48 @@ clawhub package publish https://github.com/your-org/your-plugin
|
||||
}
|
||||
```
|
||||
|
||||
已发布包应包含构建后的 JavaScript,并将 `runtimeExtensions`
|
||||
指向该输出。Git checkout 安装在不存在构建文件时仍可回退到 TypeScript 源码,
|
||||
但构建后的运行时入口可避免在启动、Doctor 和插件加载路径中进行运行时 TypeScript 编译。
|
||||
已发布的包应当附带**已构建的 JavaScript**,并将 `runtimeExtensions` 指向该输出。Git 检出安装在不存在已构建文件时,仍可回退到 TypeScript 源码,但使用已构建的运行时入口可以避免在启动、Doctor 和插件加载路径中进行运行时 TypeScript 编译。
|
||||
|
||||
## 高级细节(技术向)
|
||||
## 版本管理、锁文件和遥测
|
||||
|
||||
### 版本控制和标签
|
||||
<AccordionGroup>
|
||||
<Accordion title="版本管理和标签">
|
||||
- 每次发布都会创建一个新的 **semver** `SkillVersion`。
|
||||
- 标签(如 `latest`)指向某个版本;移动标签可以让你回滚。
|
||||
- 更新日志按版本附加,在同步或发布更新时可以为空。
|
||||
</Accordion>
|
||||
<Accordion title="本地更改与注册表版本">
|
||||
更新会使用内容哈希将本地 Skill 内容与注册表版本进行比较。如果本地文件与任何已发布版本都不匹配,CLI 会在覆盖前询问(或者在非交互运行中要求使用 `--force`)。
|
||||
</Accordion>
|
||||
<Accordion title="同步扫描和回退根目录">
|
||||
`clawhub sync` 会先扫描你当前的 workdir。如果未找到任何 Skills,它会回退到已知的旧版位置(例如 `~/openclaw/skills` 和 `~/.openclaw/skills`)。这是为了在无需额外标志的情况下找到较旧的 Skill 安装。
|
||||
</Accordion>
|
||||
<Accordion title="存储和锁文件">
|
||||
- 已安装的 Skills 会记录在你的 workdir 下的 `.clawhub/lock.json` 中。
|
||||
- 认证令牌会存储在 ClawHub CLI 配置文件中(可通过 `CLAWHUB_CONFIG_PATH` 覆盖)。
|
||||
</Accordion>
|
||||
<Accordion title="遥测(安装计数)">
|
||||
当你在登录状态下运行 `clawhub sync` 时,CLI 会发送一个最小化快照以计算安装计数。你可以完全禁用此功能:
|
||||
|
||||
- 每次发布都会创建一个新的 **semver** `SkillVersion`。
|
||||
- 标签(如 `latest`)指向某个版本;移动标签即可回滚。
|
||||
- 变更日志按版本附加,在同步或发布更新时可以为空。
|
||||
```bash
|
||||
export CLAWHUB_DISABLE_TELEMETRY=1
|
||||
```
|
||||
|
||||
### 本地变更与注册表版本
|
||||
|
||||
更新会使用内容哈希将本地 Skill 内容与注册表版本进行比较。如果本地文件与任何已发布版本都不匹配,CLI 会在覆盖前询问(或在非交互式运行中要求使用 `--force`)。
|
||||
|
||||
### 同步扫描和回退根目录
|
||||
|
||||
`clawhub sync` 会首先扫描当前 workdir。如果未找到 Skills,它会回退到已知的旧版位置(例如 `~/openclaw/skills` 和 `~/.openclaw/skills`)。这一设计是为了在不加额外标志的情况下找到旧版 Skill 安装。
|
||||
|
||||
### 存储和 lockfile
|
||||
|
||||
- 已安装 Skills 会记录在 workdir 下的 `.clawhub/lock.json` 中。
|
||||
- 认证 token 存储在 ClawHub CLI 配置文件中(可通过 `CLAWHUB_CONFIG_PATH` 覆盖)。
|
||||
|
||||
### 遥测(安装计数)
|
||||
|
||||
当你在登录状态下运行 `clawhub sync` 时,CLI 会发送一个最小快照来计算安装计数。你可以完全禁用此功能:
|
||||
|
||||
```bash
|
||||
export CLAWHUB_DISABLE_TELEMETRY=1
|
||||
```
|
||||
</Accordion>
|
||||
</AccordionGroup>
|
||||
|
||||
## 环境变量
|
||||
|
||||
- `CLAWHUB_SITE`:覆盖站点 URL。
|
||||
- `CLAWHUB_REGISTRY`:覆盖注册表 API URL。
|
||||
- `CLAWHUB_CONFIG_PATH`:覆盖 CLI 存储 token/配置的位置。
|
||||
- `CLAWHUB_WORKDIR`:覆盖默认 workdir。
|
||||
- `CLAWHUB_DISABLE_TELEMETRY=1`:在 `sync` 时禁用遥测。
|
||||
| 环境变量 | 作用 |
|
||||
| ----------------------------- | ----------------------------------------------- |
|
||||
| `CLAWHUB_SITE` | 覆盖站点 URL。 |
|
||||
| `CLAWHUB_REGISTRY` | 覆盖注册表 API URL。 |
|
||||
| `CLAWHUB_CONFIG_PATH` | 覆盖 CLI 存储令牌 / 配置的位置。 |
|
||||
| `CLAWHUB_WORKDIR` | 覆盖默认 workdir。 |
|
||||
| `CLAWHUB_DISABLE_TELEMETRY=1` | 禁用 `sync` 的遥测。 |
|
||||
|
||||
## 相关内容
|
||||
|
||||
- [Plugin](/zh-CN/tools/plugin)
|
||||
- [Skills](/zh-CN/tools/skills)
|
||||
- [社区插件](/zh-CN/plugins/community)
|
||||
- [插件](/zh-CN/tools/plugin)
|
||||
- [Skills](/zh-CN/tools/skills)
|
||||
|
||||
@ -3,63 +3,68 @@ read_when:
|
||||
- 配置执行审批或允许列表
|
||||
- 在 macOS 应用中实现执行审批 UX
|
||||
- 审查沙箱逃逸提示及其影响
|
||||
summary: 执行审批、允许列表和沙箱逃逸提示
|
||||
sidebarTitle: Exec approvals
|
||||
summary: 主机执行审批:策略开关、允许列表,以及 YOLO/严格工作流
|
||||
title: 执行审批
|
||||
x-i18n:
|
||||
generated_at: "2026-04-25T03:24:35Z"
|
||||
generated_at: "2026-04-26T06:01:24Z"
|
||||
model: gpt-5.4
|
||||
provider: openai
|
||||
source_hash: 44bf7af57d322280f6d0089207041214b1233d0c9eca99656d51fc4aed88941b
|
||||
source_hash: 868cee97882f7298a092bdcb9ec8fd058a5d7cb8745fad2edd712fabfb512e52
|
||||
source_path: tools/exec-approvals.md
|
||||
workflow: 15
|
||||
---
|
||||
|
||||
执行审批是**配套应用 / 节点主机防护栏**,用于让处于沙箱隔离的智能体在真实主机(`gateway` 或 `node`)上运行命令。这是一种安全联锁机制:只有当策略 + 允许列表 +(可选)用户审批全部同意时,命令才会被允许执行。执行审批叠加在工具策略和 elevated 门控机制**之上**(除非 elevated 设为 `full`,此时会跳过审批)。
|
||||
执行审批是**配套应用 / 节点主机护栏**,用于让处于沙箱中的智能体在真实主机(`gateway` 或 `node`)上运行命令。它是一种安全联锁机制:只有当策略 + 允许列表 +(可选)用户审批全部同意时,命令才会被允许执行。执行审批**叠加在**工具策略和提升权限门控之上(除非提升权限设置为 `full`,此时会跳过审批)。
|
||||
|
||||
<Note>
|
||||
生效策略是 `tools.exec.*` 与审批默认值中**更严格**的那一个;如果某个审批字段被省略,则使用 `tools.exec` 的值。主机执行还会使用该机器上的本地审批状态——如果 `~/.openclaw/exec-approvals.json` 中存在主机本地的 `ask: "always"`,即使会话或配置默认值请求 `ask: "on-miss"`,系统仍然会持续提示。
|
||||
有效策略取 `tools.exec.*` 与审批默认值两者中**更严格**的那个;如果某个审批字段被省略,则使用 `tools.exec` 的值。主机执行还会使用该机器上的本地审批状态——如果 `~/.openclaw/exec-approvals.json` 中主机本地的 `ask: "always"` 已设置,那么即使会话或配置默认值请求 `ask: "on-miss"`,它也仍然会持续提示。
|
||||
</Note>
|
||||
|
||||
## 检查生效策略
|
||||
## 检查有效策略
|
||||
|
||||
- `openclaw approvals get`、`... --gateway`、`... --node <id|name|ip>` —— 显示请求的策略、主机策略来源以及最终生效结果。
|
||||
- `openclaw exec-policy show` —— 显示本地机器上的合并视图。
|
||||
- `openclaw exec-policy set|preset` —— 一步完成,将本地请求的策略与本地主机审批文件同步。
|
||||
| 命令 | 显示内容 |
|
||||
| ---------------------------------------------------------------- | -------------------------------------------------------------------------------------- |
|
||||
| `openclaw approvals get` / `--gateway` / `--node <id\|name\|ip>` | 请求的策略、主机策略来源,以及最终的有效结果。 |
|
||||
| `openclaw exec-policy show` | 本地机器的合并视图。 |
|
||||
| `openclaw exec-policy set` / `preset` | 一步将本地请求的策略与本地主机审批文件同步。 |
|
||||
|
||||
当本地作用域请求 `host=node` 时,`exec-policy show` 会在运行时将该作用域报告为由节点管理,而不是假装本地审批文件是真实来源。
|
||||
当本地作用域请求 `host=node` 时,`exec-policy show` 会在运行时将该作用域报告为由节点管理,而不会假装本地审批文件才是事实来源。
|
||||
|
||||
如果配套应用 UI **不可用**,任何通常需要提示的请求都会由 **ask fallback** 处理(默认:拒绝)。
|
||||
如果配套应用 UI **不可用**,任何原本需要提示的请求都会通过**询问回退策略**来处理(默认:`deny`)。
|
||||
|
||||
<Tip>
|
||||
原生聊天审批客户端可以在待审批消息上预置特定渠道的便捷交互。例如,Matrix 会预置反应快捷方式(`✅` 允许一次、`❌` 拒绝、`♾️` 始终允许),同时仍在消息中保留 `/approve ...` 命令作为后备方案。
|
||||
原生聊天审批客户端可以在待审批消息上预置特定渠道的交互方式。例如,Matrix 会预置反应快捷方式(`✅` 允许一次,`❌` 拒绝,`♾️` 始终允许),同时仍保留消息中的 `/approve ...` 命令作为回退方案。
|
||||
</Tip>
|
||||
|
||||
## 适用范围
|
||||
## 适用位置
|
||||
|
||||
执行审批会在执行主机本地强制执行:
|
||||
执行审批在执行主机本地强制生效:
|
||||
|
||||
- **gateway host** → Gateway 机器上的 `openclaw` 进程
|
||||
- **node host** → 节点运行器(macOS 配套应用或无头节点主机)
|
||||
- **Gateway 网关主机** → Gateway 网关机器上的 `openclaw` 进程。
|
||||
- **节点主机** → 节点运行器(macOS 配套应用或无头节点主机)。
|
||||
|
||||
信任模型说明:
|
||||
### 信任模型
|
||||
|
||||
- 通过 Gateway 认证的调用方,是该 Gateway 网关的受信任操作员。
|
||||
- 已配对节点会将这种受信任操作员能力扩展到节点主机上。
|
||||
- 执行审批可以降低意外执行风险,但并不是按用户划分的身份验证边界。
|
||||
- 已批准的节点主机执行会绑定规范化执行上下文:规范化的 cwd、精确的 argv、存在时的 env 绑定,以及适用时固定的可执行文件路径。
|
||||
- 对于 shell 脚本和直接的解释器 / 运行时文件调用,OpenClaw 还会尝试绑定一个具体的本地文件操作数。如果该绑定文件在审批后、执行前发生变化,运行将被拒绝,而不是执行已漂移的内容。
|
||||
- 这种文件绑定是有意设计为“尽力而为”,而不是覆盖所有解释器 / 运行时加载路径的完整语义模型。如果审批模式无法识别并绑定**恰好一个**具体本地文件,它将拒绝签发基于审批的运行,而不是假装已经完全覆盖。
|
||||
- 通过 Gateway 网关认证的调用方被视为该 Gateway 网关的受信任操作员。
|
||||
- 已配对的节点会将这种受信任操作员能力扩展到节点主机。
|
||||
- 执行审批可降低误执行风险,但**不是**按用户划分的认证边界。
|
||||
- 已批准的节点主机执行会绑定规范化执行上下文:规范化的 cwd、精确的 argv、存在时的环境变量绑定,以及适用时固定的可执行文件路径。
|
||||
- 对于 shell 脚本和直接解释器 / 运行时文件调用,OpenClaw 还会尝试绑定一个具体的本地文件操作数。如果该绑定文件在批准后、执行前发生变化,则会拒绝本次执行,而不是执行已漂移的内容。
|
||||
- 文件绑定有意采用尽力而为策略,**并非**对每一种解释器 / 运行时加载路径都提供完整语义模型。如果审批模式无法准确识别并绑定唯一一个具体的本地文件,它会拒绝生成基于审批的执行,而不是假装已实现全面覆盖。
|
||||
|
||||
macOS 拆分:
|
||||
### macOS 拆分
|
||||
|
||||
- **node host service** 通过本地 IPC 将 `system.run` 转发给 **macOS app**。
|
||||
- **macOS app** 负责执行审批 + 在 UI 上下文中运行命令。
|
||||
- **节点主机服务**会通过本地 IPC 将 `system.run` 转发给 **macOS 应用**。
|
||||
- **macOS 应用**负责强制执行审批并在 UI 上下文中执行命令。
|
||||
|
||||
## 设置与存储
|
||||
|
||||
审批存储在执行主机上的本地 JSON 文件中:
|
||||
审批保存在执行主机上的本地 JSON 文件中:
|
||||
|
||||
`~/.openclaw/exec-approvals.json`
|
||||
```text
|
||||
~/.openclaw/exec-approvals.json
|
||||
```
|
||||
|
||||
示例结构:
|
||||
|
||||
@ -96,69 +101,130 @@ macOS 拆分:
|
||||
}
|
||||
```
|
||||
|
||||
## 无需审批的 “YOLO” 模式
|
||||
## 策略开关
|
||||
|
||||
如果你希望主机执行在没有审批提示的情况下运行,必须同时放开**两个**策略层:
|
||||
### `exec.security`
|
||||
|
||||
- OpenClaw 配置中的请求执行策略(`tools.exec.*`)
|
||||
- `~/.openclaw/exec-approvals.json` 中主机本地的审批策略
|
||||
<ParamField path="security" type='"deny" | "allowlist" | "full"'>
|
||||
- `deny` — 阻止所有主机执行请求。
|
||||
- `allowlist` — 仅允许允许列表中的命令。
|
||||
- `full` — 允许所有内容(等同于提升权限)。
|
||||
</ParamField>
|
||||
|
||||
除非你显式收紧,否则这现在是默认的主机行为:
|
||||
### `exec.ask`
|
||||
|
||||
- `tools.exec.security`:在 `gateway` / `node` 上设为 `full`
|
||||
- `tools.exec.ask`:设为 `off`
|
||||
- 主机 `askFallback`:设为 `full`
|
||||
<ParamField path="ask" type='"off" | "on-miss" | "always"'>
|
||||
- `off` — 从不提示。
|
||||
- `on-miss` — 仅当允许列表未匹配时提示。
|
||||
- `always` — 每条命令都提示。当有效询问模式为 `always` 时,`allow-always` 的持久信任**不会**抑制提示。
|
||||
</ParamField>
|
||||
|
||||
重要区别:
|
||||
### `askFallback`
|
||||
|
||||
- `tools.exec.host=auto` 决定执行在哪里运行:有沙箱时在沙箱中,否则在 gateway 上运行。
|
||||
- YOLO 决定主机执行如何获批:`security=full` 加 `ask=off`。
|
||||
- 暴露其自身非交互权限模式的基于 CLI 的提供商可以遵循此策略。
|
||||
当 OpenClaw 请求的执行策略为 YOLO 时,Claude CLI 会添加 `--permission-mode bypassPermissions`。你可以通过 `agents.defaults.cliBackends.claude-cli.args` / `resumeArgs` 下的显式 Claude 参数覆盖该后端行为,例如 `--permission-mode default`、`acceptEdits` 或 `bypassPermissions`。
|
||||
- 在 YOLO 模式下,OpenClaw 不会在已配置的主机执行策略之上,额外添加单独的启发式命令混淆审批门控或脚本预检拒绝层。
|
||||
- `auto` 不会让 gateway 路由成为来自沙箱隔离会话的免费覆盖项。每次调用的 `host=node` 请求可在 `auto` 下被允许,而 `host=gateway` 只有在没有活动沙箱运行时时,才可从 `auto` 被允许。如果你想要稳定的非 auto 默认值,请设置 `tools.exec.host`,或显式使用 `/exec host=...`。
|
||||
<ParamField path="askFallback" type='"deny" | "allowlist" | "full"'>
|
||||
当需要提示但没有可达 UI 时的处理结果。
|
||||
|
||||
如果你想采用更保守的设置,可以将任一层重新收紧为 `allowlist` / `on-miss`
|
||||
或 `deny`。
|
||||
- `deny` — 阻止。
|
||||
- `allowlist` — 仅当允许列表匹配时允许。
|
||||
- `full` — 允许。
|
||||
</ParamField>
|
||||
|
||||
持久化的 gateway host “永不提示” 设置:
|
||||
### `tools.exec.strictInlineEval`
|
||||
|
||||
```bash
|
||||
openclaw config set tools.exec.host gateway
|
||||
openclaw config set tools.exec.security full
|
||||
openclaw config set tools.exec.ask off
|
||||
openclaw gateway restart
|
||||
```
|
||||
<ParamField path="strictInlineEval" type="boolean">
|
||||
当为 `true` 时,OpenClaw 会将内联代码求值形式视为仅可通过审批执行,
|
||||
即使解释器二进制文件本身已在允许列表中也是如此。这是对那些无法
|
||||
干净映射到单一稳定文件操作数的解释器加载方式所做的纵深防御。
|
||||
</ParamField>
|
||||
|
||||
然后将主机审批文件设置为匹配值:
|
||||
严格模式会捕获的示例:
|
||||
|
||||
```bash
|
||||
openclaw approvals set --stdin <<'EOF'
|
||||
{
|
||||
version: 1,
|
||||
defaults: {
|
||||
security: "full",
|
||||
ask: "off",
|
||||
askFallback: "full"
|
||||
}
|
||||
}
|
||||
EOF
|
||||
```
|
||||
- `python -c`
|
||||
- `node -e`, `node --eval`, `node -p`
|
||||
- `ruby -e`
|
||||
- `perl -e`, `perl -E`
|
||||
- `php -r`
|
||||
- `lua -e`
|
||||
- `osascript -e`
|
||||
|
||||
在当前机器上应用相同 gateway host 策略的本地快捷方式:
|
||||
在严格模式下,这些命令仍然需要显式审批,并且 `allow-always`
|
||||
不会自动为它们持久化新的允许列表条目。
|
||||
|
||||
## YOLO 模式(无审批)
|
||||
|
||||
如果你希望主机执行在没有审批提示的情况下运行,就必须同时放开
|
||||
**两层**策略——OpenClaw 配置中的请求执行策略
|
||||
(`tools.exec.*`)**以及** `~/.openclaw/exec-approvals.json`
|
||||
中的主机本地审批策略。
|
||||
|
||||
YOLO 是默认的主机行为,除非你显式收紧它:
|
||||
|
||||
| 层级 | YOLO 设置 |
|
||||
| --------------------- | -------------------------- |
|
||||
| `tools.exec.security` | `gateway` / `node` 上设为 `full` |
|
||||
| `tools.exec.ask` | `off` |
|
||||
| 主机 `askFallback` | `full` |
|
||||
|
||||
<Warning>
|
||||
**重要区别:**
|
||||
|
||||
- `tools.exec.host=auto` 选择执行的**位置**:如果有沙箱则在沙箱中执行,否则在 Gateway 网关执行。
|
||||
- YOLO 选择主机执行如何被批准:`security=full` 加 `ask=off`。
|
||||
- 在 YOLO 模式下,OpenClaw **不会**在已配置的主机执行策略之上,再额外添加单独的启发式命令混淆审批门或脚本预检拒绝层。
|
||||
- `auto` 不会让 Gateway 网关路由从沙箱会话中变成一个免费覆盖项。来自 `auto` 的单次调用 `host=node` 请求是允许的;只有在没有活动沙箱运行时时,来自 `auto` 的 `host=gateway` 请求才允许。若要获得稳定的非 `auto` 默认值,请设置 `tools.exec.host`,或显式使用 `/exec host=...`。
|
||||
</Warning>
|
||||
|
||||
暴露自身非交互式权限模式的 CLI 支持型提供商可以遵循此策略。当 OpenClaw 请求的执行策略为 YOLO 时,Claude CLI 会添加
|
||||
`--permission-mode bypassPermissions`。你可以通过
|
||||
`agents.defaults.cliBackends.claude-cli.args` / `resumeArgs` 下的显式 Claude 参数覆盖该后端行为——例如 `--permission-mode default`、`acceptEdits` 或
|
||||
`bypassPermissions`。
|
||||
|
||||
如果你想采用更保守的设置,可以将任一层重新收紧为
|
||||
`allowlist` / `on-miss` 或 `deny`。
|
||||
|
||||
### 持久化的 Gateway 网关主机“永不提示”设置
|
||||
|
||||
<Steps>
|
||||
<Step title="设置请求配置策略">
|
||||
```bash
|
||||
openclaw config set tools.exec.host gateway
|
||||
openclaw config set tools.exec.security full
|
||||
openclaw config set tools.exec.ask off
|
||||
openclaw gateway restart
|
||||
```
|
||||
</Step>
|
||||
<Step title="匹配主机审批文件">
|
||||
```bash
|
||||
openclaw approvals set --stdin <<'EOF'
|
||||
{
|
||||
version: 1,
|
||||
defaults: {
|
||||
security: "full",
|
||||
ask: "off",
|
||||
askFallback: "full"
|
||||
}
|
||||
}
|
||||
EOF
|
||||
```
|
||||
</Step>
|
||||
</Steps>
|
||||
|
||||
### 本地快捷方式
|
||||
|
||||
```bash
|
||||
openclaw exec-policy preset yolo
|
||||
```
|
||||
|
||||
该本地快捷方式会同时更新:
|
||||
这个本地快捷方式会同时更新:
|
||||
|
||||
- 本地 `tools.exec.host/security/ask`
|
||||
- 本地 `~/.openclaw/exec-approvals.json` 默认值
|
||||
- 本地 `tools.exec.host/security/ask`。
|
||||
- 本地 `~/.openclaw/exec-approvals.json` 默认值。
|
||||
|
||||
它有意只作用于本地。如果你需要远程更改 gateway host 或 node host 审批,请继续使用 `openclaw approvals set --gateway` 或
|
||||
它有意仅作用于本地。要远程更改 Gateway 网关主机或节点主机的审批,请使用 `openclaw approvals set --gateway` 或
|
||||
`openclaw approvals set --node <id|name|ip>`。
|
||||
|
||||
### 节点主机
|
||||
|
||||
对于节点主机,请改为在该节点上应用相同的审批文件:
|
||||
|
||||
```bash
|
||||
@ -174,67 +240,31 @@ openclaw approvals set --node <id|name|ip> --stdin <<'EOF'
|
||||
EOF
|
||||
```
|
||||
|
||||
重要的仅本地限制:
|
||||
<Note>
|
||||
**仅限本地的限制:**
|
||||
|
||||
- `openclaw exec-policy` 不会同步节点审批
|
||||
- `openclaw exec-policy set --host node` 会被拒绝
|
||||
- 节点执行审批会在运行时从节点获取,因此针对节点的更新必须使用 `openclaw approvals --node ...`
|
||||
- `openclaw exec-policy` 不会同步节点审批。
|
||||
- `openclaw exec-policy set --host node` 会被拒绝。
|
||||
- 节点执行审批会在运行时从节点获取,因此面向节点的更新必须使用 `openclaw approvals --node ...`。
|
||||
</Note>
|
||||
|
||||
仅会话快捷方式:
|
||||
### 仅会话快捷方式
|
||||
|
||||
- `/exec security=full ask=off` 只会更改当前会话。
|
||||
- `/elevated full` 是一个紧急破窗快捷方式,也会为该会话跳过执行审批。
|
||||
- `/elevated full` 是一个紧急放行快捷方式,它也会跳过该会话的执行审批。
|
||||
|
||||
如果主机审批文件仍比配置更严格,仍以更严格的主机策略为准。
|
||||
|
||||
## 策略开关
|
||||
|
||||
### 安全性(`exec.security`)
|
||||
|
||||
- **deny**:阻止所有主机执行请求。
|
||||
- **allowlist**:仅允许允许列表中的命令。
|
||||
- **full**:允许所有内容(等同于 elevated)。
|
||||
|
||||
### 询问(`exec.ask`)
|
||||
|
||||
- **off**:从不提示。
|
||||
- **on-miss**:仅当允许列表不匹配时提示。
|
||||
- **always**:每个命令都提示。
|
||||
- 当生效的询问模式为 `always` 时,`allow-always` 的持久信任不会抑制提示
|
||||
|
||||
### 询问后备(`askFallback`)
|
||||
|
||||
如果需要提示但没有可达的 UI,则由后备策略决定:
|
||||
|
||||
- **deny**:阻止。
|
||||
- **allowlist**:仅当允许列表匹配时允许。
|
||||
- **full**:允许。
|
||||
|
||||
### 内联解释器 eval 加固(`tools.exec.strictInlineEval`)
|
||||
|
||||
当 `tools.exec.strictInlineEval=true` 时,即使解释器二进制本身在允许列表中,OpenClaw 也会将内联代码求值形式视为“仅可通过审批执行”。
|
||||
|
||||
示例:
|
||||
|
||||
- `python -c`
|
||||
- `node -e`, `node --eval`, `node -p`
|
||||
- `ruby -e`
|
||||
- `perl -e`, `perl -E`
|
||||
- `php -r`
|
||||
- `lua -e`
|
||||
- `osascript -e`
|
||||
|
||||
这是对那些无法干净映射到单一稳定文件操作数的解释器加载路径所做的纵深防御。在严格模式下:
|
||||
|
||||
- 这些命令仍然需要显式审批;
|
||||
- `allow-always` 不会自动为它们持久保存新的允许列表条目。
|
||||
如果主机审批文件仍然比配置更严格,那么更严格的主机策略仍然会生效。
|
||||
|
||||
## 允许列表(按智能体)
|
||||
|
||||
允许列表是**按智能体**划分的。如果存在多个智能体,请在 macOS 应用中切换你要编辑的智能体。模式使用 glob 匹配。
|
||||
模式可以是已解析的二进制路径 glob,也可以是裸命令名 glob。裸名称只匹配通过 PATH 调用的命令,因此当命令是 `rg` 时,`rg` 可以匹配 `/opt/homebrew/bin/rg`,但不能匹配 `./rg` 或 `/tmp/rg`。如果你想信任某一个特定的二进制位置,请使用路径 glob。
|
||||
允许列表是**按智能体**区分的。如果存在多个智能体,请在 macOS 应用中切换你要编辑的智能体。模式使用 glob 匹配。
|
||||
|
||||
模式既可以是解析后的二进制路径 glob,也可以是裸命令名 glob。
|
||||
裸名称只匹配通过 `PATH` 调用的命令,因此如果命令是 `rg`,那么 `rg` 可以匹配
|
||||
`/opt/homebrew/bin/rg`,但**不能**匹配 `./rg` 或 `/tmp/rg`。如果你只想信任某个特定位置的二进制文件,请使用路径 glob。
|
||||
|
||||
旧版 `agents.default` 条目会在加载时迁移到 `agents.main`。
|
||||
像 `echo ok && pwd` 这样的 shell 链式命令,仍然要求每个顶层片段都满足允许列表规则。
|
||||
像 `echo ok && pwd` 这样的 shell 链式命令仍然要求每个顶层片段都满足允许列表规则。
|
||||
|
||||
示例:
|
||||
|
||||
@ -245,100 +275,102 @@ EOF
|
||||
|
||||
每个允许列表条目会跟踪:
|
||||
|
||||
- **id**:供 UI 标识使用的稳定 UUID(可选)
|
||||
- **last used**:上次使用时间戳
|
||||
- **last used command**
|
||||
- **last resolved path**
|
||||
| 字段 | 含义 |
|
||||
| ------------------ | -------------------------------- |
|
||||
| `id` | 用于 UI 身份识别的稳定 UUID |
|
||||
| `lastUsedAt` | 上次使用时间戳 |
|
||||
| `lastUsedCommand` | 上次匹配到的命令 |
|
||||
| `lastResolvedPath` | 上次解析出的二进制路径 |
|
||||
|
||||
## 自动允许 Skill CLI
|
||||
## 自动允许 Skills CLI
|
||||
|
||||
启用 **Auto-allow skill CLIs** 后,已知 Skills 引用的可执行文件会在节点上(macOS 节点或无头节点主机)被视为已加入允许列表。这会通过 Gateway RPC 使用 `skills.bins` 获取 skill 二进制列表。如果你想使用严格的手动允许列表,请关闭此选项。
|
||||
启用 **Auto-allow skill CLIs** 后,已知 Skills 引用的可执行文件会在节点上(macOS 节点或无头节点主机)被视为已加入允许列表。它通过 Gateway 网关 RPC 使用 `skills.bins` 获取 skill bin 列表。如果你希望使用严格的手动允许列表,请关闭此选项。
|
||||
|
||||
重要信任说明:
|
||||
|
||||
- 这是一个**隐式的便捷允许列表**,与手动路径允许列表条目分开。
|
||||
<Warning>
|
||||
- 这是一种**隐式便捷允许列表**,与手动路径允许列表条目分开。
|
||||
- 它适用于 Gateway 网关与节点处于同一信任边界内的受信任操作员环境。
|
||||
- 如果你需要严格的显式信任,请保持 `autoAllowSkills: false`,并仅使用手动路径允许列表条目。
|
||||
- 如果你要求严格的显式信任,请保持 `autoAllowSkills: false`,并且只使用手动路径允许列表条目。
|
||||
</Warning>
|
||||
|
||||
## 安全二进制与审批转发
|
||||
## 安全 bin 与审批转发
|
||||
|
||||
关于安全二进制(仅 stdin 的快速路径)、解释器绑定细节,以及如何将审批提示转发到 Slack/Discord/Telegram(或将它们作为原生审批客户端运行),请参见 [执行审批——高级](/zh-CN/tools/exec-approvals-advanced)。
|
||||
|
||||
<!-- moved to /tools/exec-approvals-advanced -->
|
||||
关于安全 bin(仅 stdin 快速路径)、解释器绑定细节,以及如何将审批提示转发到 Slack/Discord/Telegram(或将它们作为原生审批客户端运行),请参见
|
||||
[执行审批——高级](/zh-CN/tools/exec-approvals-advanced)。
|
||||
|
||||
## Control UI 编辑
|
||||
|
||||
使用 **Control UI → Nodes → Exec approvals** 卡片来编辑默认值、按智能体的覆盖项和允许列表。选择一个作用域(默认值或某个智能体),调整策略,添加 / 删除允许列表模式,然后点击 **Save**。UI 会为每个模式显示 **last used** 元数据,方便你保持列表整洁。
|
||||
使用 **Control UI → Nodes → Exec approvals** 卡片来编辑默认值、按智能体覆盖项和允许列表。选择一个作用域(Defaults 或某个智能体),调整策略,添加 / 删除允许列表模式,然后点击 **Save**。UI 会显示每个模式的上次使用元数据,方便你保持列表整洁。
|
||||
|
||||
目标选择器可选择 **Gateway**(本地审批)或 **Node**。节点必须声明 `system.execApprovals.get/set`(macOS 应用或无头节点主机)。
|
||||
如果某个节点尚未声明执行审批,请直接编辑其本地
|
||||
`~/.openclaw/exec-approvals.json`。
|
||||
目标选择器用于选择 **Gateway 网关**(本地审批)或某个**节点**。
|
||||
节点必须声明 `system.execApprovals.get/set`(macOS 应用或无头节点主机)。如果某个节点尚未声明执行审批,请直接编辑它本地的 `~/.openclaw/exec-approvals.json`。
|
||||
|
||||
CLI:`openclaw approvals` 支持编辑 gateway 或 node(参见 [Approvals CLI](/zh-CN/cli/approvals))。
|
||||
CLI:`openclaw approvals` 支持编辑 Gateway 网关或节点——参见
|
||||
[Approvals CLI](/zh-CN/cli/approvals)。
|
||||
|
||||
## 审批流程
|
||||
|
||||
当需要提示时,gateway 会向操作员客户端广播 `exec.approval.requested`。
|
||||
Control UI 和 macOS 应用通过 `exec.approval.resolve` 进行处理,然后 gateway 会将已批准的请求转发到节点主机。
|
||||
当需要提示时,Gateway 网关会向操作员客户端广播
|
||||
`exec.approval.requested`。Control UI 和 macOS 应用通过
|
||||
`exec.approval.resolve` 处理它,然后 Gateway 网关再将已批准的请求转发给节点主机。
|
||||
|
||||
对于 `host=node`,审批请求会包含规范化的 `systemRunPlan` 负载。gateway 在转发已批准的 `system.run`
|
||||
请求时,会将该 plan 作为权威的命令 / cwd / 会话上下文。
|
||||
对于 `host=node`,审批请求会包含一个规范化的 `systemRunPlan`
|
||||
载荷。Gateway 网关在转发已批准的 `system.run`
|
||||
请求时,会将该计划用作权威的命令 / cwd / 会话上下文。
|
||||
|
||||
这对于异步审批延迟很重要:
|
||||
这对异步审批延迟很重要:
|
||||
|
||||
- 节点执行路径会预先准备一个规范化 plan
|
||||
- 审批记录会存储该 plan 及其绑定元数据
|
||||
- 一旦获批,最终转发的 `system.run` 调用会复用已存储的 plan
|
||||
而不是信任调用方后续的修改
|
||||
- 如果审批请求创建后,调用方更改了 `command`、`rawCommand`、`cwd`、`agentId` 或
|
||||
`sessionKey`,gateway 会将该转发运行拒绝为审批不匹配
|
||||
- 节点执行路径会预先准备一个规范化计划。
|
||||
- 审批记录会存储该计划及其绑定元数据。
|
||||
- 一旦获得批准,最终转发的 `system.run` 调用会复用已存储的计划,而不是信任调用方后续的修改。
|
||||
- 如果调用方在审批请求创建后更改了 `command`、`rawCommand`、`cwd`、`agentId` 或 `sessionKey`,Gateway 网关会将转发的执行拒绝为审批不匹配。
|
||||
|
||||
## 系统事件
|
||||
|
||||
执行生命周期会作为系统消息呈现:
|
||||
执行生命周期会以系统消息形式呈现:
|
||||
|
||||
- `Exec running`(仅当命令超过“正在运行”通知阈值时显示)
|
||||
- `Exec finished`
|
||||
- `Exec denied`
|
||||
- `Exec running`(仅当命令超过运行通知阈值时)。
|
||||
- `Exec finished`。
|
||||
- `Exec denied`。
|
||||
|
||||
这些消息会在节点上报事件后发布到智能体的会话中。
|
||||
gateway host 执行审批也会在命令结束时发出相同的生命周期事件(如果运行时间超过阈值,也会在运行中发出可选事件)。
|
||||
Gateway 网关主机执行审批在命令完成时也会发出相同的生命周期事件(如果运行时间超过阈值,也可在运行中发出)。
|
||||
受审批门控的执行会在这些消息中复用审批 id 作为 `runId`,以便轻松关联。
|
||||
|
||||
## 审批被拒绝时的行为
|
||||
|
||||
当异步执行审批被拒绝时,OpenClaw 会阻止智能体复用该会话中此前同一命令任意一次运行的输出。拒绝原因会连同明确指引一起传递,说明没有可用的命令输出,这样可阻止智能体声称存在新的输出,或使用先前成功运行的陈旧结果重复已被拒绝的命令。
|
||||
当异步执行审批被拒绝时,OpenClaw 会阻止智能体在该会话中复用此前同一命令任意早先执行的输出。
|
||||
拒绝原因会附带明确说明,指出没有可用的命令输出,这可以阻止智能体声称存在新输出,或使用先前成功执行留下的陈旧结果重复被拒绝的命令。
|
||||
|
||||
## 影响
|
||||
|
||||
- **full** 权限很强;如果可能,优先使用允许列表。
|
||||
- **ask** 让你保持参与审批流程,同时仍可实现快速审批。
|
||||
- 按智能体划分的允许列表可防止一个智能体的审批泄漏到其他智能体。
|
||||
- 审批仅适用于来自**已授权发送方**的主机执行请求。未授权发送方无法发出 `/exec`。
|
||||
- `/exec security=full` 是面向已授权操作员的会话级便捷方式,并且按设计会跳过审批。若要强制阻止主机执行,请将审批安全性设为 `deny`,或通过工具策略拒绝 `exec` 工具。
|
||||
- **`full`** 权限很强;尽可能优先使用允许列表。
|
||||
- **`ask`** 让你保持在回路中,同时仍允许快速审批。
|
||||
- 按智能体划分的允许列表可防止某个智能体的审批泄漏到其他智能体。
|
||||
- 审批只适用于来自**已授权发送方**的主机执行请求。未授权发送方无法发出 `/exec`。
|
||||
- `/exec security=full` 是面向已授权操作员的会话级便捷方式,并且按设计会跳过审批。若要硬性阻止主机执行,请将审批安全级别设为 `deny`,或通过工具策略拒绝 `exec` 工具。
|
||||
|
||||
## 相关内容
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="执行审批——高级" href="/zh-CN/tools/exec-approvals-advanced" icon="gear">
|
||||
安全二进制、解释器绑定以及将审批转发到聊天渠道。
|
||||
安全 bin、解释器绑定,以及向聊天转发审批。
|
||||
</Card>
|
||||
<Card title="Exec 工具" href="/zh-CN/tools/exec" icon="terminal">
|
||||
Shell 命令执行工具。
|
||||
</Card>
|
||||
<Card title="Elevated 模式" href="/zh-CN/tools/elevated" icon="shield-exclamation">
|
||||
也会跳过审批的紧急破窗路径。
|
||||
<Card title="提升权限模式" href="/zh-CN/tools/elevated" icon="shield-exclamation">
|
||||
同样会跳过审批的紧急放行路径。
|
||||
</Card>
|
||||
<Card title="沙箱隔离" href="/zh-CN/gateway/sandboxing" icon="box">
|
||||
沙箱模式与工作区访问。
|
||||
</Card>
|
||||
<Card title="安全性" href="/zh-CN/gateway/security" icon="lock">
|
||||
<Card title="安全" href="/zh-CN/gateway/security" icon="lock">
|
||||
安全模型与加固。
|
||||
</Card>
|
||||
<Card title="沙箱隔离 vs 工具策略 vs elevated" href="/zh-CN/gateway/sandbox-vs-tool-policy-vs-elevated" icon="sliders">
|
||||
何时应使用各项控制。
|
||||
<Card title="沙箱 vs 工具策略 vs 提升权限" href="/zh-CN/gateway/sandbox-vs-tool-policy-vs-elevated" icon="sliders">
|
||||
何时应使用每一种控制方式。
|
||||
</Card>
|
||||
<Card title="Skills" href="/zh-CN/tools/skills" icon="sparkles">
|
||||
由 Skills 支持的自动允许行为。
|
||||
由 Skill 支持的自动允许行为。
|
||||
</Card>
|
||||
</CardGroup>
|
||||
|
||||
@ -1,310 +1,378 @@
|
||||
---
|
||||
read_when:
|
||||
- 你想通过智能体进行后台 / 并行工作
|
||||
- 你希望通过智能体进行后台或并行工作
|
||||
- 你正在更改 `sessions_spawn` 或子智能体工具策略
|
||||
- 你正在实现或排查线程绑定的子智能体会话
|
||||
summary: 子智能体:生成隔离的智能体运行,并将结果通告回请求者聊天界面
|
||||
- 你正在实现或排查受线程绑定的子智能体会话
|
||||
sidebarTitle: Sub-agents
|
||||
summary: 启动隔离的后台智能体运行,并将结果回报到请求者聊天中
|
||||
title: 子智能体
|
||||
x-i18n:
|
||||
generated_at: "2026-04-26T00:39:26Z"
|
||||
generated_at: "2026-04-26T06:01:22Z"
|
||||
model: gpt-5.4
|
||||
provider: openai
|
||||
source_hash: ae5c51e89541e3dd48646afb86a49eea21b778d816f8edb7c4b35e93b62bb64f
|
||||
source_hash: e7f2f1b8ae08026dd0f8c1b466bb7a8b044ae1d12c2ae61735dcf9f380179986
|
||||
source_path: tools/subagents.md
|
||||
workflow: 15
|
||||
---
|
||||
|
||||
子智能体是从现有智能体运行中生成的后台智能体运行。它们在各自独立的会话中运行(`agent:<agentId>:subagent:<uuid>`),并在完成后将其结果**通告**回请求者聊天渠道。每个子智能体运行都会作为一个[后台任务](/zh-CN/automation/tasks)进行跟踪。
|
||||
|
||||
## 斜杠命令
|
||||
|
||||
使用 `/subagents` 可检查或控制**当前会话**的子智能体运行:
|
||||
|
||||
- `/subagents list`
|
||||
- `/subagents kill <id|#|all>`
|
||||
- `/subagents log <id|#> [limit] [tools]`
|
||||
- `/subagents info <id|#>`
|
||||
- `/subagents send <id|#> <message>`
|
||||
- `/subagents steer <id|#> <message>`
|
||||
- `/subagents spawn <agentId> <task> [--model <model>] [--thinking <level>]`
|
||||
|
||||
线程绑定控制:
|
||||
|
||||
这些命令适用于支持持久线程绑定的渠道。请参见下方的**支持线程的渠道**。
|
||||
|
||||
- `/focus <subagent-label|session-key|session-id|session-label>`
|
||||
- `/unfocus`
|
||||
- `/agents`
|
||||
- `/session idle <duration|off>`
|
||||
- `/session max-age <duration|off>`
|
||||
|
||||
`/subagents info` 会显示运行元数据(状态、时间戳、会话 id、转录路径、清理设置)。
|
||||
使用 `sessions_history` 获取有边界且经过安全过滤的回溯视图;当你需要原始完整转录时,请检查磁盘上的转录路径。
|
||||
|
||||
### 生成行为
|
||||
|
||||
`/subagents spawn` 以用户命令而非内部中继的方式启动一个后台子智能体,并在运行结束时向请求者聊天发送一条最终完成更新。
|
||||
|
||||
- 生成命令是非阻塞的;它会立即返回一个运行 id。
|
||||
- 完成后,子智能体会向请求者聊天渠道通告一条摘要 / 结果消息。
|
||||
- 完成投递是基于推送的。生成后,不要仅为了等待其完成而循环轮询 `/subagents list`、`sessions_list` 或 `sessions_history`;仅在调试或干预时按需检查状态。
|
||||
- 完成时,OpenClaw 会尽最大努力在通告清理流程继续之前关闭该子智能体会话打开的已跟踪浏览器标签页 / 进程。
|
||||
- 对于手动生成,投递具有弹性:
|
||||
- OpenClaw 会先使用稳定的幂等键尝试直接 `agent` 投递。
|
||||
- 如果直接投递失败,则回退到队列路由。
|
||||
- 如果队列路由仍不可用,则会以短暂的指数退避重试通告,之后才最终放弃。
|
||||
- 完成投递会保留已解析的请求者路由:
|
||||
- 可用时,线程绑定或会话绑定的完成路由优先
|
||||
- 如果完成来源只提供渠道,OpenClaw 会从请求者会话的已解析路由(`lastChannel` / `lastTo` / `lastAccountId`)中补全缺失的目标 / 账号,从而让直接投递仍然可用
|
||||
- 向请求者会话移交完成结果时,使用的是运行时生成的内部上下文(不是用户撰写的文本),其中包括:
|
||||
- `Result`(最新可见的 `assistant` 回复文本;否则为已净化的最新 `tool` / `toolResult` 文本;终态失败的运行不会复用已捕获的回复文本)
|
||||
- `Status`(`completed successfully` / `failed` / `timed out` / `unknown`)
|
||||
- 紧凑的运行时 / token 统计信息
|
||||
- 一条投递指令,告知请求者智能体用正常的 assistant 语气重写,而不是转发原始内部元数据
|
||||
- `--model` 和 `--thinking` 会覆盖该次特定运行的默认值。
|
||||
- 完成后,使用 `info` / `log` 检查详细信息和输出。
|
||||
- `/subagents spawn` 是一次性模式(`mode: "run"`)。对于持久线程绑定会话,请使用带有 `thread: true` 和 `mode: "session"` 的 `sessions_spawn`。
|
||||
- 对于 ACP harness 会话(Claude Code、Gemini CLI、OpenCode,或显式的 Codex ACP / acpx),当工具声明了该运行时,请使用 `runtime: "acp"` 的 `sessions_spawn`,并参见 [ACP Agents](/zh-CN/tools/acp-agents),尤其是在调试完成回传或智能体到智能体循环时的 [ACP delivery model](/zh-CN/tools/acp-agents#delivery-model)。启用 `codex` 插件后,Codex 聊天 / 线程控制应优先使用 `/codex ...` 而不是 ACP,除非用户明确要求 ACP / acpx。只有在 ACP 已启用、请求者未处于沙箱隔离状态,并且已加载 `acpx` 等后端插件时,OpenClaw 才会显示 `runtime: "acp"`。`runtime: "acp"` 需要一个外部 ACP harness id,或 `agents.list[]` 中 `runtime.type="acp"` 的条目;对于来自 `agents_list` 的普通 OpenClaw 配置智能体,请使用默认子智能体运行时。
|
||||
子智能体是从现有智能体运行中派生出来的后台智能体运行。
|
||||
它们在各自独立的会话(`agent:<agentId>:subagent:<uuid>`)中运行,并且在完成后,会将结果**通知**回请求者聊天渠道。每个子智能体运行都会作为一个[后台任务](/zh-CN/automation/tasks)进行跟踪。
|
||||
|
||||
主要目标:
|
||||
|
||||
- 将“研究 / 长任务 / 慢工具”工作并行化,而不阻塞主运行。
|
||||
- 默认保持子智能体隔离(会话分离 + 可选沙箱隔离)。
|
||||
- 保持工具表面不易被误用:子智能体默认**不会**获得会话工具。
|
||||
- 支持可配置的嵌套深度,以适配编排器模式。
|
||||
- 将“研究 / 长任务 / 慢工具”类工作并行化,而不阻塞主运行。
|
||||
- 默认保持子智能体隔离(会话隔离 + 可选沙箱隔离)。
|
||||
- 让工具使用面难以被误用:默认情况下,子智能体**不会**获得会话工具。
|
||||
- 支持可配置的嵌套深度,以满足编排器模式。
|
||||
|
||||
成本说明:默认情况下,每个子智能体都有其**自己的**上下文和 token 使用量。对于高负载或重复性任务,请为子智能体设置更便宜的模型,并让你的主智能体继续使用质量更高的模型。你可以通过 `agents.defaults.subagents.model` 或按智能体覆盖来配置这一点。当子级确实需要请求者当前转录时,智能体可以在该次生成中请求 `context: "fork"`。
|
||||
<Note>
|
||||
**成本说明:** 默认情况下,每个子智能体都有自己的上下文和 token 用量。对于高负载或重复性任务,建议为子智能体设置更便宜的模型,并让主智能体继续使用质量更高的模型。可通过 `agents.defaults.subagents.model` 或按智能体覆盖进行配置。当某个子智能体确实需要请求者的当前对话记录时,智能体可以在该次派生时请求 `context: "fork"`。
|
||||
</Note>
|
||||
|
||||
## 斜杠命令
|
||||
|
||||
使用 `/subagents` 来检查或控制**当前会话**的子智能体运行:
|
||||
|
||||
```text
|
||||
/subagents list
|
||||
/subagents kill <id|#|all>
|
||||
/subagents log <id|#> [limit] [tools]
|
||||
/subagents info <id|#>
|
||||
/subagents send <id|#> <message>
|
||||
/subagents steer <id|#> <message>
|
||||
/subagents spawn <agentId> <task> [--model <model>] [--thinking <level>]
|
||||
```
|
||||
|
||||
`/subagents info` 会显示运行元数据(Status、时间戳、会话 id、transcript 路径、cleanup)。使用 `sessions_history` 可查看有界且经过安全过滤的回顾视图;当你需要原始完整 transcript 时,可检查磁盘上的 transcript 路径。
|
||||
|
||||
### 线程绑定控制
|
||||
|
||||
这些命令适用于支持持久线程绑定的渠道。请参见下方的[支持线程的渠道](#thread-supporting-channels)。
|
||||
|
||||
```text
|
||||
/focus <subagent-label|session-key|session-id|session-label>
|
||||
/unfocus
|
||||
/agents
|
||||
/session idle <duration|off>
|
||||
/session max-age <duration|off>
|
||||
```
|
||||
|
||||
### 派生行为
|
||||
|
||||
`/subagents spawn` 会以用户命令(而非内部中继)的方式启动一个后台子智能体,并在运行完成后向请求者聊天发送一条最终完成更新。
|
||||
|
||||
<AccordionGroup>
|
||||
<Accordion title="非阻塞、基于推送的完成">
|
||||
- 派生命令是非阻塞的;它会立即返回一个运行 id。
|
||||
- 完成时,子智能体会将摘要/结果消息通知回请求者聊天渠道。
|
||||
- 完成采用推送方式。一旦派生完成,**不要**仅为了等待其结束而循环轮询 `/subagents list`、`sessions_list` 或 `sessions_history`;只有在调试或干预时才按需检查状态。
|
||||
- 完成时,OpenClaw 会尽最大努力在继续执行通知清理流程之前,关闭该子智能体会话打开并被跟踪的浏览器标签页/进程。
|
||||
</Accordion>
|
||||
<Accordion title="手动派生的投递韧性">
|
||||
- OpenClaw 会先尝试使用稳定的幂等键进行直接 `agent` 投递。
|
||||
- 如果直接投递失败,则回退到队列路由。
|
||||
- 如果队列路由仍不可用,则会在最终放弃之前,使用短时指数退避重试通知。
|
||||
- 完成投递会保留已解析的请求者路由:如果可用,线程绑定或会话绑定的完成路由优先;如果完成来源只提供渠道,OpenClaw 会从请求者会话的已解析路由(`lastChannel` / `lastTo` / `lastAccountId`)中补全缺失的 target/account,以便直接投递仍能正常工作。
|
||||
</Accordion>
|
||||
<Accordion title="完成移交元数据">
|
||||
向请求者会话的完成移交是运行时生成的内部上下文(不是用户编写的文本),其中包括:
|
||||
|
||||
- `Result` —— 最新可见的 `assistant` 回复文本;否则为经过净化的最新 tool/toolResult 文本。终态失败运行不会复用捕获的回复文本。
|
||||
- `Status` —— `completed successfully` / `failed` / `timed out` / `unknown`。
|
||||
- 紧凑的运行时/token 统计信息。
|
||||
- 一条投递说明,指示请求者智能体以正常 assistant 语气重写,而不是转发原始内部元数据。
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="模式与 ACP 运行时">
|
||||
- `--model` 和 `--thinking` 会覆盖该次运行的默认值。
|
||||
- 完成后可使用 `info`/`log` 检查详细信息和输出。
|
||||
- `/subagents spawn` 是一次性模式(`mode: "run"`)。对于持久的线程绑定会话,请使用带有 `thread: true` 和 `mode: "session"` 的 `sessions_spawn`。
|
||||
- 对于 ACP harness 会话(Claude Code、Gemini CLI、OpenCode 或显式的 Codex ACP/acpx),当工具声明该运行时时,请使用 `runtime: "acp"` 的 `sessions_spawn`。调试完成回传或智能体之间循环时,请参见 [ACP 投递模型](/zh-CN/tools/acp-agents#delivery-model)。当启用了 `codex` 插件时,除非用户明确要求 ACP/acpx,否则 Codex 聊天/线程控制应优先使用 `/codex ...` 而不是 ACP。
|
||||
- 只有在 ACP 已启用、请求者未处于沙箱中,且已加载 `acpx` 等后端插件时,OpenClaw 才会显示 `runtime: "acp"`。`runtime: "acp"` 需要一个外部 ACP harness id,或某个带有 `runtime.type="acp"` 的 `agents.list[]` 条目;对于 `agents_list` 中的普通 OpenClaw 配置智能体,应使用默认的子智能体运行时。
|
||||
</Accordion>
|
||||
</AccordionGroup>
|
||||
|
||||
## 上下文模式
|
||||
|
||||
原生子智能体默认以隔离方式启动,除非调用方明确要求分叉当前转录。
|
||||
原生子智能体默认以隔离方式启动,除非调用方明确要求分叉当前对话记录。
|
||||
|
||||
| 模式 | 适用场景 | 行为 |
|
||||
| ---------- | -------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------- |
|
||||
| `isolated` | 全新的研究、独立实现、慢工具工作,或任何可以在任务文本中简要说明的事项 | 创建一个干净的子级转录。这是默认模式,并且会保持较低的 token 使用量。 |
|
||||
| `fork` | 依赖当前对话、先前工具结果,或请求者转录中已存在的细致指令的工作 | 在子级启动前,将请求者转录分支到子会话中。 |
|
||||
| 模式 | 适用场景 | 行为 |
|
||||
| ---------- | -------- | ---- |
|
||||
| `isolated` | 新研究、独立实现、慢工具工作,或任何可以在任务文本中简要说明的工作 | 创建一个干净的子 transcript。这是默认值,并且能将 token 用量保持得更低。 |
|
||||
| `fork` | 依赖当前对话、先前工具结果,或请求者 transcript 中已有的细致指令的工作 | 在子会话开始前,将请求者 transcript 分支到子会话中。 |
|
||||
|
||||
谨慎使用 `fork`。它用于对上下文敏感的委派,而不是替代清晰编写任务提示。
|
||||
谨慎使用 `fork`。它适用于对上下文敏感的委派,而不是用来替代清晰的任务提示编写。
|
||||
|
||||
## 工具
|
||||
## 工具:`sessions_spawn`
|
||||
|
||||
使用 `sessions_spawn`:
|
||||
以 `deliver: false` 在全局 `subagent` 通道上启动一个子智能体运行,然后执行通知步骤,并将通知回复发布到请求者聊天渠道。
|
||||
|
||||
- 启动一个子智能体运行(`deliver: false`,全局 lane:`subagent`)
|
||||
- 然后执行一个通告步骤,并将通告回复发布到请求者聊天渠道
|
||||
- 默认模型:继承调用方,除非你设置了 `agents.defaults.subagents.model`(或按智能体设置 `agents.list[].subagents.model`);显式指定的 `sessions_spawn.model` 仍然优先。
|
||||
- 默认 thinking:继承调用方,除非你设置了 `agents.defaults.subagents.thinking`(或按智能体设置 `agents.list[].subagents.thinking`);显式指定的 `sessions_spawn.thinking` 仍然优先。
|
||||
- 默认运行超时:如果省略 `sessions_spawn.runTimeoutSeconds`,OpenClaw 会在已设置时使用 `agents.defaults.subagents.runTimeoutSeconds`;否则回退到 `0`(无超时)。
|
||||
**默认值:**
|
||||
|
||||
工具参数:
|
||||
- **模型:** 继承调用方,除非你设置了 `agents.defaults.subagents.model`(或按智能体设置 `agents.list[].subagents.model`);显式指定的 `sessions_spawn.model` 仍然优先。
|
||||
- **Thinking:** 继承调用方,除非你设置了 `agents.defaults.subagents.thinking`(或按智能体设置 `agents.list[].subagents.thinking`);显式指定的 `sessions_spawn.thinking` 仍然优先。
|
||||
- **运行超时:** 如果省略 `sessions_spawn.runTimeoutSeconds`,OpenClaw 会在已设置时使用 `agents.defaults.subagents.runTimeoutSeconds`;否则回退到 `0`(无超时)。
|
||||
|
||||
- `task`(必填)
|
||||
- `label?`(可选)
|
||||
- `agentId?`(可选;如果允许,可在另一个智能体 id 下生成)
|
||||
- `runtime?`(`subagent|acp`,默认 `subagent`;`acp` 仅用于外部 ACP harness,例如 `claude`、`droid`、`gemini`、`opencode`,或显式请求的 Codex ACP / acpx,或 `agents.list[]` 中 `runtime.type` 为 `acp` 的条目)
|
||||
- `model?`(可选;覆盖子智能体模型;无效值会被跳过,子智能体会使用默认模型运行,并在工具结果中给出警告)
|
||||
- `thinking?`(可选;覆盖子智能体运行的 thinking 级别)
|
||||
- `runTimeoutSeconds?`(默认在已设置时使用 `agents.defaults.subagents.runTimeoutSeconds`,否则为 `0`;设置后,子智能体运行会在 N 秒后中止)
|
||||
- `thread?`(默认 `false`;为 `true` 时,请求为该子智能体会话启用渠道线程绑定)
|
||||
- `mode?`(`run|session`)
|
||||
- 默认值为 `run`
|
||||
- 如果 `thread: true` 且省略 `mode`,默认变为 `session`
|
||||
- `mode: "session"` 需要 `thread: true`
|
||||
- `cleanup?`(`delete|keep`,默认 `keep`)
|
||||
- `sandbox?`(`inherit|require`,默认 `inherit`;`require` 会在目标子级运行时未处于沙箱隔离时拒绝生成)
|
||||
- `context?`(`isolated|fork`,默认 `isolated`;仅适用于原生子智能体)
|
||||
- `isolated` 会创建一个干净的子级转录,并且是默认值。
|
||||
- `fork` 会将请求者当前转录分支到子会话中,使子级以相同的对话上下文启动。
|
||||
- 仅当子级需要当前转录时才使用 `fork`。对于范围明确的工作,请省略 `context`。
|
||||
- `sessions_spawn` **不**接受渠道投递参数(`target`、`channel`、`to`、`threadId`、`replyTo`、`transport`)。如需投递,请从已生成的运行中使用 `message` / `sessions_send`。
|
||||
### 工具参数
|
||||
|
||||
<ParamField path="task" type="string" required>
|
||||
子智能体的任务描述。
|
||||
</ParamField>
|
||||
<ParamField path="label" type="string">
|
||||
可选的人类可读标签。
|
||||
</ParamField>
|
||||
<ParamField path="agentId" type="string">
|
||||
在 `subagents.allowAgents` 允许的情况下,以另一个智能体 id 派生。
|
||||
</ParamField>
|
||||
<ParamField path="runtime" type='"subagent" | "acp"' default="subagent">
|
||||
`acp` 仅用于外部 ACP harness(`claude`、`droid`、`gemini`、`opencode` 或显式请求的 Codex ACP/acpx),以及 `agents.list[]` 中 `runtime.type` 为 `acp` 的条目。
|
||||
</ParamField>
|
||||
<ParamField path="model" type="string">
|
||||
覆盖子智能体模型。无效值会被跳过,子智能体会使用默认模型运行,并在工具结果中给出警告。
|
||||
</ParamField>
|
||||
<ParamField path="thinking" type="string">
|
||||
覆盖子智能体运行的 thinking 级别。
|
||||
</ParamField>
|
||||
<ParamField path="runTimeoutSeconds" type="number">
|
||||
在已设置时默认使用 `agents.defaults.subagents.runTimeoutSeconds`,否则为 `0`。设置后,子智能体运行会在 N 秒后中止。
|
||||
</ParamField>
|
||||
<ParamField path="thread" type="boolean" default="false">
|
||||
当为 `true` 时,请求为该子智能体会话启用渠道线程绑定。
|
||||
</ParamField>
|
||||
<ParamField path="mode" type='"run" | "session"' default="run">
|
||||
如果 `thread: true` 且省略 `mode`,默认值会变为 `session`。`mode: "session"` 需要 `thread: true`。
|
||||
</ParamField>
|
||||
<ParamField path="cleanup" type='"delete" | "keep"' default="keep">
|
||||
`"delete"` 会在通知后立即归档(仍会通过重命名保留 transcript)。
|
||||
</ParamField>
|
||||
<ParamField path="sandbox" type='"inherit" | "require"' default="inherit">
|
||||
`require` 会在目标子运行时未处于沙箱隔离时拒绝派生。
|
||||
</ParamField>
|
||||
<ParamField path="context" type='"isolated" | "fork"' default="isolated">
|
||||
`fork` 会将请求者当前的 transcript 分支到子会话中。仅适用于原生子智能体。仅在子智能体需要当前 transcript 时使用 `fork`。
|
||||
</ParamField>
|
||||
|
||||
<Warning>
|
||||
`sessions_spawn` **不**接受渠道投递参数(`target`、`channel`、`to`、`threadId`、`replyTo`、`transport`)。如需投递,请从已派生的运行中使用 `message`/`sessions_send`。
|
||||
</Warning>
|
||||
|
||||
## 线程绑定会话
|
||||
|
||||
当某个渠道启用了线程绑定时,子智能体可以持续绑定到一个线程上,以便该线程中的后续用户消息继续路由到同一个子智能体会话。
|
||||
当某个渠道启用了线程绑定时,子智能体可以保持绑定到某个线程,因此该线程中的后续用户消息会持续路由到同一个子智能体会话。
|
||||
|
||||
### 支持线程的渠道
|
||||
|
||||
- Discord(当前唯一受支持的渠道):支持持久的线程绑定子智能体会话(使用带 `thread: true` 的 `sessions_spawn`)、手动线程控制(`/focus`、`/unfocus`、`/agents`、`/session idle`、`/session max-age`),以及适配器键 `channels.discord.threadBindings.enabled`、`channels.discord.threadBindings.idleHours`、`channels.discord.threadBindings.maxAgeHours` 和 `channels.discord.threadBindings.spawnSubagentSessions`。
|
||||
目前只有 **Discord** 是受支持的渠道。它支持持久的线程绑定子智能体会话(`sessions_spawn` 配合 `thread: true`)、手动线程控制(`/focus`、`/unfocus`、`/agents`、`/session idle`、`/session max-age`),以及适配器键
|
||||
`channels.discord.threadBindings.enabled`、
|
||||
`channels.discord.threadBindings.idleHours`、
|
||||
`channels.discord.threadBindings.maxAgeHours` 和
|
||||
`channels.discord.threadBindings.spawnSubagentSessions`。
|
||||
|
||||
快速流程:
|
||||
### 快速流程
|
||||
|
||||
1. 使用带有 `thread: true` 的 `sessions_spawn` 进行生成(可选地加上 `mode: "session"`)。
|
||||
2. OpenClaw 会在活动渠道中创建一个线程或将线程绑定到该会话目标。
|
||||
3. 该线程中的回复和后续消息都会路由到绑定的会话。
|
||||
4. 使用 `/session idle` 检查 / 更新不活动自动取消聚焦设置,使用 `/session max-age` 控制硬性上限。
|
||||
5. 使用 `/unfocus` 手动解除绑定。
|
||||
<Steps>
|
||||
<Step title="派生">
|
||||
使用带有 `thread: true` 的 `sessions_spawn`(并可选指定 `mode: "session"`)。
|
||||
</Step>
|
||||
<Step title="绑定">
|
||||
OpenClaw 会在当前活动渠道中为该会话目标创建或绑定一个线程。
|
||||
</Step>
|
||||
<Step title="路由后续消息">
|
||||
该线程中的回复和后续消息会路由到已绑定的会话。
|
||||
</Step>
|
||||
<Step title="检查超时">
|
||||
使用 `/session idle` 检查/更新不活动自动取消聚焦,并使用 `/session max-age` 控制硬性上限。
|
||||
</Step>
|
||||
<Step title="解除绑定">
|
||||
使用 `/unfocus` 手动解除绑定。
|
||||
</Step>
|
||||
</Steps>
|
||||
|
||||
手动控制:
|
||||
### 手动控制
|
||||
|
||||
- `/focus <target>` 会将当前线程(或创建一个线程)绑定到某个子智能体 / 会话目标。
|
||||
- `/unfocus` 会移除当前已绑定线程的绑定。
|
||||
- `/agents` 会列出活动运行及绑定状态(`thread:<id>` 或 `unbound`)。
|
||||
- `/session idle` 和 `/session max-age` 仅对已聚焦的绑定线程有效。
|
||||
| 命令 | 效果 |
|
||||
| ------------------ | --------------------------------------------------------------------- |
|
||||
| `/focus <target>` | 将当前线程(或创建一个线程)绑定到某个子智能体/会话目标 |
|
||||
| `/unfocus` | 移除当前已绑定线程的绑定 |
|
||||
| `/agents` | 列出活动运行和绑定状态(`thread:<id>` 或 `unbound`) |
|
||||
| `/session idle` | 检查/更新空闲自动取消聚焦(仅适用于已聚焦的绑定线程) |
|
||||
| `/session max-age` | 检查/更新硬性上限(仅适用于已聚焦的绑定线程) |
|
||||
|
||||
配置开关:
|
||||
### 配置开关
|
||||
|
||||
- 全局默认值:`session.threadBindings.enabled`、`session.threadBindings.idleHours`、`session.threadBindings.maxAgeHours`
|
||||
- 渠道覆盖和生成自动绑定键是特定于适配器的。请参见上方的**支持线程的渠道**。
|
||||
- **全局默认值:** `session.threadBindings.enabled`、`session.threadBindings.idleHours`、`session.threadBindings.maxAgeHours`。
|
||||
- **渠道覆盖和派生自动绑定键** 由各适配器分别定义。请参见上方的[支持线程的渠道](#thread-supporting-channels)。
|
||||
|
||||
当前适配器的详细信息请参见 [Configuration Reference](/zh-CN/gateway/configuration-reference) 和 [Slash commands](/zh-CN/tools/slash-commands)。
|
||||
当前适配器详情请参见[配置参考](/zh-CN/gateway/configuration-reference)和[斜杠命令](/zh-CN/tools/slash-commands)。
|
||||
|
||||
允许列表:
|
||||
### 允许列表
|
||||
|
||||
- `agents.list[].subagents.allowAgents`:可通过 `agentId` 定向的智能体 id 列表(`["*"]` 表示允许任意)。默认值:仅允许请求者智能体。
|
||||
- `agents.defaults.subagents.allowAgents`:当请求者智能体未设置自己的 `subagents.allowAgents` 时,使用的默认目标智能体允许列表。
|
||||
- 沙箱继承保护:如果请求者会话处于沙箱隔离中,`sessions_spawn` 会拒绝那些将以非沙箱方式运行的目标。
|
||||
- `agents.defaults.subagents.requireAgentId` / `agents.list[].subagents.requireAgentId`:为 true 时,阻止省略 `agentId` 的 `sessions_spawn` 调用(强制显式选择配置文件)。默认值:false。
|
||||
<ParamField path="agents.list[].subagents.allowAgents" type="string[]">
|
||||
可通过 `agentId` 定向的智能体 id 列表(`["*"]` 表示允许任意智能体)。默认值:仅允许请求者智能体。
|
||||
</ParamField>
|
||||
<ParamField path="agents.defaults.subagents.allowAgents" type="string[]">
|
||||
当请求者智能体未设置自己的 `subagents.allowAgents` 时使用的默认目标智能体允许列表。
|
||||
</ParamField>
|
||||
<ParamField path="agents.defaults.subagents.requireAgentId" type="boolean" default="false">
|
||||
阻止省略 `agentId` 的 `sessions_spawn` 调用(强制显式选择配置文件)。按智能体覆盖:`agents.list[].subagents.requireAgentId`。
|
||||
</ParamField>
|
||||
|
||||
发现:
|
||||
如果请求者会话处于沙箱隔离中,`sessions_spawn` 会拒绝那些将以非沙箱方式运行的目标。
|
||||
|
||||
- 使用 `agents_list` 查看当前哪些智能体 id 允许用于 `sessions_spawn`。响应中包含每个列出智能体的有效模型和嵌入式运行时元数据,以便调用方区分 PI、Codex app-server 以及其他已配置的原生运行时。
|
||||
### 发现
|
||||
|
||||
自动归档:
|
||||
使用 `agents_list` 查看当前哪些智能体 id 被允许用于 `sessions_spawn`。响应中包含每个已列出智能体的生效模型和嵌入式运行时元数据,以便调用方区分 PI、Codex app-server 以及其他已配置的原生运行时。
|
||||
|
||||
- 子智能体会话会在 `agents.defaults.subagents.archiveAfterMinutes` 之后自动归档(默认值:60)。
|
||||
- 归档使用 `sessions.delete`,并将转录重命名为 `*.deleted.<timestamp>`(同一文件夹中)。
|
||||
- `cleanup: "delete"` 会在通告后立即归档(仍会通过重命名保留转录)。
|
||||
- 自动归档是尽力而为的;如果 Gateway 网关重启,待处理计时器会丢失。
|
||||
### 自动归档
|
||||
|
||||
- 子智能体会话会在 `agents.defaults.subagents.archiveAfterMinutes`(默认值为 `60`)后自动归档。
|
||||
- 归档使用 `sessions.delete`,并将 transcript 重命名为 `*.deleted.<timestamp>`(同一文件夹内)。
|
||||
- `cleanup: "delete"` 会在通知后立即归档(仍会通过重命名保留 transcript)。
|
||||
- 自动归档是尽力而为的;如果 Gateway 网关重启,待处理的定时器将会丢失。
|
||||
- `runTimeoutSeconds` **不会**自动归档;它只会停止运行。会话会一直保留到自动归档发生。
|
||||
- 自动归档对深度 1 和深度 2 会话一视同仁。
|
||||
- 浏览器清理与归档清理是分开的:当运行结束时,会尽最大努力关闭已跟踪的浏览器标签页 / 进程,即使转录 / 会话记录被保留也是如此。
|
||||
- 自动归档同样适用于深度 1 和深度 2 的会话。
|
||||
- 浏览器清理独立于归档清理:当运行结束时,即使保留了 transcript/会话记录,被跟踪的浏览器标签页/进程也会尽力关闭。
|
||||
|
||||
## 嵌套子智能体
|
||||
|
||||
默认情况下,子智能体不能生成它们自己的子智能体(`maxSpawnDepth: 1`)。你可以通过将 `maxSpawnDepth` 设置为 `2` 来启用一层嵌套,这允许使用**编排器模式**:主智能体 → 编排器子智能体 → 工作子子智能体。
|
||||
|
||||
### 如何启用
|
||||
默认情况下,子智能体不能派生它们自己的子智能体(`maxSpawnDepth: 1`)。将 `maxSpawnDepth` 设置为 `2` 可启用一层嵌套 —— **编排器模式**:主智能体 → 编排器子智能体 → 工作子子智能体。
|
||||
|
||||
```json5
|
||||
{
|
||||
agents: {
|
||||
defaults: {
|
||||
subagents: {
|
||||
maxSpawnDepth: 2, // 允许子智能体生成子级(默认值:1)
|
||||
maxSpawnDepth: 2, // 允许子智能体派生子级(默认值:1)
|
||||
maxChildrenPerAgent: 5, // 每个智能体会话的最大活动子级数(默认值:5)
|
||||
maxConcurrent: 8, // 全局并发 lane 上限(默认值:8)
|
||||
runTimeoutSeconds: 900, // 省略时 sessions_spawn 的默认超时(0 = 无超时)
|
||||
maxConcurrent: 8, // 全局并发通道上限(默认值:8)
|
||||
runTimeoutSeconds: 900, // sessions_spawn 省略时的默认超时(0 = 无超时)
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
### 深度级别
|
||||
### 深度层级
|
||||
|
||||
| 深度 | 会话键形态 | 角色 | 可生成? |
|
||||
| 深度 | 会话键形态 | 角色 | 可否派生? |
|
||||
| ----- | -------------------------------------------- | --------------------------------------------- | ---------------------------- |
|
||||
| 0 | `agent:<id>:main` | 主智能体 | 始终可以 |
|
||||
| 1 | `agent:<id>:subagent:<uuid>` | 子智能体(当允许深度 2 时可作为编排器) | 仅当 `maxSpawnDepth >= 2` |
|
||||
| 2 | `agent:<id>:subagent:<uuid>:subagent:<uuid>` | 子子智能体(叶子工作单元) | 永不允许 |
|
||||
| 1 | `agent:<id>:subagent:<uuid>` | 子智能体(允许深度 2 时为编排器) | 仅当 `maxSpawnDepth >= 2` 时 |
|
||||
| 2 | `agent:<id>:subagent:<uuid>:subagent:<uuid>` | 子子智能体(叶子工作节点) | 永不允许 |
|
||||
|
||||
### 通告链
|
||||
### 通知链
|
||||
|
||||
结果会沿链路向上回流:
|
||||
结果会沿链路向上回传:
|
||||
|
||||
1. 深度 2 工作单元完成 → 向其父级(深度 1 编排器)通告
|
||||
2. 深度 1 编排器接收通告、综合结果、完成 → 向主智能体通告
|
||||
3. 主智能体接收通告并投递给用户
|
||||
1. 深度 2 的工作节点完成 → 向其父级(深度 1 编排器)通知。
|
||||
2. 深度 1 编排器接收通知,综合结果并完成 → 向主智能体通知。
|
||||
3. 主智能体接收通知并将结果投递给用户。
|
||||
|
||||
每一层只能看到其直接子级发来的通告。
|
||||
每一层只能看到其直接子级的通知。
|
||||
|
||||
操作指南:
|
||||
|
||||
- 子级工作启动一次后,等待完成事件即可,不要围绕 `sessions_list`、`sessions_history`、`/subagents list` 或 `exec` sleep 命令构建轮询循环。
|
||||
- `sessions_list` 和 `/subagents list` 会让子会话关系聚焦于实时工作:活跃子级保持附着,已结束子级会在一个较短的最近窗口内保持可见,而仅存储中的过期子级链接会在其新鲜度窗口过后被忽略。这样可以防止旧的 `spawnedBy` / `parentSessionKey` 元数据在重启后重新唤起幽灵子级。
|
||||
- 如果某个子级完成事件在你已经发送最终答案之后才到达,正确的后续处理是精确的静默 token `NO_REPLY` / `no_reply`。
|
||||
<Note>
|
||||
**操作指南:** 启动一次子级工作后,等待完成事件,而不是围绕 `sessions_list`、`sessions_history`、`/subagents list` 或 `exec` sleep 命令构建轮询循环。`sessions_list` 和 `/subagents list` 会让子会话关系聚焦于实时工作 —— 仍在运行的子级会保持附着,已结束的子级会在一个较短的最近窗口内保持可见,而仅存在于存储中的过期子级链接会在其新鲜期窗口之后被忽略。这样可以防止旧的 `spawnedBy` / `parentSessionKey` 元数据在重启后重新“复活”幽灵子级。如果某个子级完成事件在你已发送最终答案之后才到达,正确的后续处理是精确的静默 token `NO_REPLY` / `no_reply`。
|
||||
</Note>
|
||||
|
||||
### 按深度划分的工具策略
|
||||
|
||||
- 角色和控制范围会在生成时写入会话元数据。这可以防止扁平化或已恢复的会话键意外重新获得编排器权限。
|
||||
- **深度 1(编排器,当 `maxSpawnDepth >= 2` 时)**:获得 `sessions_spawn`、`subagents`、`sessions_list`、`sessions_history`,以便管理其子级。其他会话 / 系统工具仍被拒绝。
|
||||
- **深度 1(叶子,当 `maxSpawnDepth == 1` 时)**:没有会话工具(当前默认行为)。
|
||||
- **深度 2(叶子工作单元)**:没有会话工具 —— 在深度 2 上始终拒绝 `sessions_spawn`。不能继续生成更多子级。
|
||||
- 角色和控制范围会在派生时写入会话元数据。这样可防止扁平化或恢复后的会话键意外重新获得编排器权限。
|
||||
- **深度 1(编排器,且 `maxSpawnDepth >= 2` 时):** 获得 `sessions_spawn`、`subagents`、`sessions_list`、`sessions_history`,以便管理其子级。其他会话/系统工具仍被拒绝。
|
||||
- **深度 1(叶子节点,且 `maxSpawnDepth == 1` 时):** 无会话工具(当前默认行为)。
|
||||
- **深度 2(叶子工作节点):** 无会话工具 —— 在深度 2 时,`sessions_spawn` 始终被拒绝。不能继续派生更多子级。
|
||||
|
||||
### 每个智能体的生成上限
|
||||
### 按智能体的派生上限
|
||||
|
||||
每个智能体会话(任意深度)同一时间最多可以有 `maxChildrenPerAgent`(默认值:5)个活动子级。这可以防止单个编排器发生失控扇出。
|
||||
每个智能体会话(任意深度)同一时间最多只能拥有 `maxChildrenPerAgent`(默认值 `5`)个活动子级。这可防止单个编排器发生失控扇出。
|
||||
|
||||
### 级联停止
|
||||
|
||||
停止一个深度 1 编排器会自动停止其所有深度 2 子级:
|
||||
|
||||
- 在主聊天中发送 `/stop` 会停止所有深度 1 智能体,并级联停止它们的深度 2 子级。
|
||||
- `/subagents kill <id>` 会停止指定子智能体,并级联到其子级。
|
||||
- `/subagents kill all` 会停止请求者的所有子智能体,并进行级联。
|
||||
- 主聊天中的 `/stop` 会停止所有深度 1 智能体,并级联停止它们的深度 2 子级。
|
||||
- `/subagents kill <id>` 会停止指定子智能体,并级联停止其子级。
|
||||
- `/subagents kill all` 会停止请求者的所有子智能体,并执行级联停止。
|
||||
|
||||
## 身份验证
|
||||
|
||||
子智能体认证按**智能体 id**解析,而不是按会话类型:
|
||||
子智能体身份验证按**智能体 id**解析,而不是按会话类型解析:
|
||||
|
||||
- 子智能体会话键是 `agent:<agentId>:subagent:<uuid>`。
|
||||
- 认证存储从该智能体的 `agentDir` 加载。
|
||||
- 主智能体的认证配置文件会作为**回退**合并进来;发生冲突时,智能体配置文件会覆盖主配置文件。
|
||||
- 子智能体会话键为 `agent:<agentId>:subagent:<uuid>`。
|
||||
- 身份验证存储从该智能体的 `agentDir` 加载。
|
||||
- 主智能体的身份验证配置文件会作为**回退**合并进来;发生冲突时,智能体配置文件会覆盖主配置文件。
|
||||
|
||||
注意:该合并是附加式的,因此主配置文件始终可作为回退使用。当前尚不支持每个智能体完全隔离的认证。
|
||||
这种合并是增量式的,因此主配置文件始终可作为回退使用。当前尚不支持每个智能体完全隔离的身份验证。
|
||||
|
||||
## 通告
|
||||
## 通知
|
||||
|
||||
子智能体通过一个通告步骤回报结果:
|
||||
子智能体通过通知步骤回报结果:
|
||||
|
||||
- 通告步骤在子智能体会话内部运行(而不是在请求者会话中)。
|
||||
- 通知步骤在子智能体会话内部运行(而不是请求者会话内)。
|
||||
- 如果子智能体精确回复 `ANNOUNCE_SKIP`,则不会发布任何内容。
|
||||
- 如果最新的 assistant 文本是精确的静默 token `NO_REPLY` / `no_reply`,则即使之前存在可见进度,也会抑制通告输出。
|
||||
- 否则,投递取决于请求者深度:
|
||||
- 顶层请求者会话使用带外部投递的后续 `agent` 调用(`deliver=true`)
|
||||
- 嵌套请求者子智能体会话接收内部后续注入(`deliver=false`),以便编排器可在会话内综合子级结果
|
||||
- 如果嵌套请求者子智能体会话已不存在,OpenClaw 会在可用时回退到该会话的请求者
|
||||
- 对于顶层请求者会话,完成模式的直接投递会先解析任何已绑定的会话 / 线程路由和 hook 覆盖,然后从请求者会话存储的路由中补全缺失的渠道目标字段。这样即使完成来源仅标识了渠道,也能将完成结果保持在正确的聊天 / 主题中。
|
||||
- 在构建嵌套完成发现结果时,子级完成聚合会限定在当前请求者运行范围内,从而防止过期的前一次运行子级输出泄漏到当前通告中。
|
||||
- 在渠道适配器可用时,通告回复会保留线程 / 主题路由。
|
||||
- 通告上下文会规范化为稳定的内部事件块:
|
||||
- 来源(`subagent` 或 `cron`)
|
||||
- 子会话键 / id
|
||||
- 通告类型 + 任务标签
|
||||
- 从运行时结果推导出的状态行(`success`、`error`、`timeout` 或 `unknown`)
|
||||
- 从最新可见 assistant 文本中选取的结果内容;否则使用已净化的最新 `tool` / `toolResult` 文本;终态失败运行会报告失败状态,而不会重放已捕获的回复文本
|
||||
- 一条后续指令,说明何时回复、何时保持静默
|
||||
- `Status` 不是从模型输出推断的;它来自运行时结果信号。
|
||||
- 超时时,如果子级只执行到了工具调用,通告可以将该历史折叠为简短的部分进度摘要,而不是重放原始工具输出。
|
||||
- 如果最新的 assistant 文本是精确的静默 token `NO_REPLY` / `no_reply`,即使之前存在可见进度,也会抑制通知输出。
|
||||
|
||||
通告载荷在末尾包含一行统计信息(即使被包装也是如此):
|
||||
投递方式取决于请求者深度:
|
||||
|
||||
- 运行时长(例如 `runtime 5m12s`)
|
||||
- token 使用量(输入 / 输出 / 总计)
|
||||
- 已配置模型定价时的预估成本(`models.providers.*.models[].cost`)
|
||||
- `sessionKey`、`sessionId` 和转录路径(这样主智能体可以通过 `sessions_history` 获取历史记录,或在磁盘上检查文件)
|
||||
- 内部元数据仅用于编排;面向用户的回复应以正常 assistant 语气重写。
|
||||
- 顶层请求者会话使用后续 `agent` 调用并进行外部投递(`deliver=true`)。
|
||||
- 嵌套的请求者子智能体会话接收内部后续注入(`deliver=false`),以便编排器在会话内综合子级结果。
|
||||
- 如果某个嵌套的请求者子智能体会话已不存在,OpenClaw 会在可用时回退到该会话的请求者。
|
||||
|
||||
对于顶层请求者会话,完成模式下的直接投递会首先解析任何已绑定的会话/线程路由及 hook 覆盖,然后从请求者会话存储的路由中补全缺失的渠道目标字段。这样即使完成来源只标识了渠道,也能确保完成消息投递到正确的聊天/话题。
|
||||
|
||||
在构建嵌套完成结果时,子级完成聚合会限定在当前请求者运行范围内,从而防止之前运行中陈旧的子级输出泄漏到当前通知中。通知回复会在渠道适配器可用时保留线程/话题路由。
|
||||
|
||||
### 通知上下文
|
||||
|
||||
通知上下文会被规范化为稳定的内部事件块:
|
||||
|
||||
| 字段 | 来源 |
|
||||
| -------------- | ------------------------------------------------------------------------------------------------------------- |
|
||||
| Source | `subagent` 或 `cron` |
|
||||
| Session ids | 子会话 key/id |
|
||||
| Type | 通知类型 + 任务标签 |
|
||||
| Status | 根据运行时结果派生(`success`、`error`、`timeout` 或 `unknown`)—— **不是**从模型文本推断 |
|
||||
| Result content | 最新可见 assistant 文本;否则为经过净化的最新 tool/toolResult 文本 |
|
||||
| Follow-up | 描述何时回复、何时保持静默的说明 |
|
||||
|
||||
终态失败运行会报告失败状态,而不会重放已捕获的回复文本。超时时,如果子级只执行到了工具调用阶段,通知可以将该历史压缩为简短的部分进度摘要,而不是重放原始工具输出。
|
||||
|
||||
### 统计信息行
|
||||
|
||||
通知负载在末尾包含一行统计信息(即使被包裹时也是如此):
|
||||
|
||||
- 运行时长(例如 `runtime 5m12s`)。
|
||||
- Token 用量(输入/输出/总量)。
|
||||
- 当配置了模型定价(`models.providers.*.models[].cost`)时的预估成本。
|
||||
- `sessionKey`、`sessionId` 和 transcript 路径,以便主智能体通过 `sessions_history` 获取历史记录,或在磁盘上检查该文件。
|
||||
|
||||
内部元数据仅用于编排;面向用户的回复应以正常 assistant 语气重写。
|
||||
|
||||
### 为什么优先使用 `sessions_history`
|
||||
|
||||
`sessions_history` 是更安全的编排路径:
|
||||
|
||||
- 会先对 assistant 回溯进行规范化:
|
||||
- 去除 thinking 标签
|
||||
- 去除 `<relevant-memories>` / `<relevant_memories>` 脚手架块
|
||||
- 去除纯文本工具调用 XML 载荷块,例如 `<tool_call>...</tool_call>`、`<function_call>...</function_call>`、`<tool_calls>...</tool_calls>` 和 `<function_calls>...</function_calls>`,包括那些从未正常闭合的截断载荷
|
||||
- 去除降级后的工具调用 / 结果脚手架和历史上下文标记
|
||||
- 去除泄漏的模型控制 token,例如 `<|assistant|>`、其他 ASCII `<|...|>` token,以及全角变体 `<|...|>`
|
||||
- 去除格式错误的 MiniMax 工具调用 XML
|
||||
- 类凭证 / token 文本会被脱敏
|
||||
- 长内容块可能会被截断
|
||||
- 非常大的历史记录可能会丢弃较早的行,或用 `[sessions_history omitted: message too large]` 替换过大的行
|
||||
- 当你需要完整、逐字节的转录时,后备方案是在磁盘上检查原始转录
|
||||
- assistant 回顾会先被规范化:移除 thinking 标签;移除 `<relevant-memories>` / `<relevant_memories>` 脚手架;移除纯文本工具调用 XML 负载块(`<tool_call>`、`<function_call>`、`<tool_calls>`、`<function_calls>`),包括那些被截断且未能正常闭合的负载;移除降级的工具调用/结果脚手架和历史上下文标记;移除泄漏的模型控制 token(`<|assistant|>`、其他 ASCII `<|...|>`、全角 `<|...|>`);移除格式错误的 MiniMax 工具调用 XML。
|
||||
- 类凭证/token 的文本会被脱敏。
|
||||
- 长块内容可能会被截断。
|
||||
- 极大的历史记录可能会丢弃较早的行,或用 `[sessions_history omitted: message too large]` 替换某个过大的行。
|
||||
- 当你需要完整逐字节 transcript 时,回退方案是直接检查磁盘上的原始 transcript。
|
||||
|
||||
## 工具策略(子智能体工具)
|
||||
## 工具策略
|
||||
|
||||
子智能体首先使用与父级或目标智能体相同的配置文件和工具策略流水线。之后,OpenClaw 会应用子智能体限制层。
|
||||
子智能体首先使用与父智能体或目标智能体相同的配置文件和工具策略流水线。之后,OpenClaw 会应用子智能体限制层。
|
||||
|
||||
在没有限制性 `tools.profile` 的情况下,子智能体获得**除会话工具**和系统工具之外的**所有工具**:
|
||||
在没有限制性 `tools.profile` 的情况下,子智能体将获得**除会话工具和系统工具之外的所有工具**:
|
||||
|
||||
- `sessions_list`
|
||||
- `sessions_history`
|
||||
- `sessions_send`
|
||||
- `sessions_spawn`
|
||||
|
||||
这里的 `sessions_history` 也仍然是有边界、已净化的回溯视图;它不是原始转录转储。
|
||||
这里的 `sessions_history` 仍然是有界、经过净化的回顾视图 —— 它不是原始 transcript 转储。
|
||||
|
||||
当 `maxSpawnDepth >= 2` 时,深度 1 编排器子智能体还会额外获得 `sessions_spawn`、`subagents`、`sessions_list` 和 `sessions_history`,以便管理其子级。
|
||||
当 `maxSpawnDepth >= 2` 时,深度 1 的编排器子智能体还会额外获得 `sessions_spawn`、`subagents`、`sessions_list` 和 `sessions_history`,以便管理其子级。
|
||||
|
||||
通过配置覆盖:
|
||||
### 通过配置覆盖
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -320,7 +388,7 @@ x-i18n:
|
||||
tools: {
|
||||
// deny 优先
|
||||
deny: ["gateway", "cron"],
|
||||
// 如果设置了 allow,它会变为仅允许列表(deny 仍然优先)
|
||||
// 如果设置了 allow,则变为仅允许这些(deny 仍然优先)
|
||||
// allow: ["read", "exec", "process"]
|
||||
},
|
||||
},
|
||||
@ -328,7 +396,7 @@ x-i18n:
|
||||
}
|
||||
```
|
||||
|
||||
`tools.subagents.tools.allow` 是最终的仅允许过滤器。它可以缩小已解析的工具集合,但不能把已被 `tools.profile` 移除的工具重新加回来。例如,`tools.profile: "coding"` 包含 `web_search` / `web_fetch`,但不包含 `browser` 工具。若要让 coding 配置文件的子智能体使用浏览器自动化,请在配置文件阶段加入 browser:
|
||||
`tools.subagents.tools.allow` 是最终的仅允许过滤器。它可以缩小已经解析出的工具集,但不能**重新加入**被 `tools.profile` 移除的工具。例如,`tools.profile: "coding"` 包含 `web_search`/`web_fetch`,但不包含 `browser` 工具。若要让 coding 配置文件的子智能体使用浏览器自动化,请在配置文件阶段加入 browser:
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -339,39 +407,42 @@ x-i18n:
|
||||
}
|
||||
```
|
||||
|
||||
如果只希望某一个智能体获得浏览器自动化,请使用按智能体配置的 `agents.list[].tools.alsoAllow: ["browser"]`。
|
||||
当仅有一个智能体应获得浏览器自动化时,可使用按智能体的 `agents.list[].tools.alsoAllow: ["browser"]`。
|
||||
|
||||
## 并发
|
||||
|
||||
子智能体使用一个专用的进程内队列 lane:
|
||||
子智能体使用专用的进程内队列通道:
|
||||
|
||||
- lane 名称:`subagent`
|
||||
- 并发数:`agents.defaults.subagents.maxConcurrent`(默认值 `8`)
|
||||
- **通道名称:** `subagent`
|
||||
- **并发数:** `agents.defaults.subagents.maxConcurrent`(默认值 `8`)
|
||||
|
||||
## 存活性与恢复
|
||||
|
||||
OpenClaw 不会将缺少 `endedAt` 永久视为某个子智能体仍然存活的证明。超过过期运行窗口的未结束运行将不再在 `/subagents list`、状态摘要、后代完成门控以及每会话并发检查中计为活动 / 待处理。
|
||||
OpenClaw 不会将缺少 `endedAt` 视为某个子智能体仍然存活的永久证据。超过过期运行窗口且未结束的运行,将不再在 `/subagents list`、状态摘要、后代完成门控以及按会话的并发检查中计为活动/待处理。
|
||||
|
||||
在 Gateway 网关重启后,过期且未结束的已恢复运行会被修剪,除非其子会话被标记为 `abortedLastRun: true`。这些因重启而中止的子会话仍可通过子智能体孤儿恢复流程进行恢复,该流程会先发送一条合成恢复消息,然后再清除中止标记。
|
||||
Gateway 网关重启后,过期且未结束的已恢复运行会被清理,除非其子会话被标记为 `abortedLastRun: true`。这些因重启而中止的子会话仍可通过子智能体孤儿恢复流程进行恢复,该流程会在清除中止标记之前发送一条合成恢复消息。
|
||||
|
||||
如果子智能体生成因 Gateway 网关 `PAIRING_REQUIRED` / `scope-upgrade` 失败,在编辑配对状态之前,请先检查 RPC 调用方。内部 `sessions_spawn` 协调应通过 direct loopback shared-token / password auth 以 `client.id: "gateway-client"` 和 `client.mode: "backend"` 连接;该路径不依赖 CLI 的配对设备 scope 基线。远程调用方、显式 `deviceIdentity`、显式设备 token 路径以及浏览器 / node 客户端仍然需要正常的设备批准来进行 scope 升级。
|
||||
<Note>
|
||||
如果子智能体派生因 Gateway 网关 `PAIRING_REQUIRED` / `scope-upgrade` 而失败,请先检查 RPC 调用方,再编辑配对状态。内部 `sessions_spawn` 协调应通过直接 loopback shared-token/password 身份验证,以 `client.id: "gateway-client"` 和 `client.mode: "backend"` 进行连接;该路径不依赖 CLI 已配对设备的 scope 基线。远程调用方、显式 `deviceIdentity`、显式 device-token 路径以及浏览器/node 客户端仍然需要正常的设备批准才能完成 scope 升级。
|
||||
</Note>
|
||||
|
||||
## 停止
|
||||
|
||||
- 在请求者聊天中发送 `/stop` 会中止请求者会话,并停止由其生成的任何活动子智能体运行,同时级联到嵌套子级。
|
||||
- `/subagents kill <id>` 会停止指定子智能体,并级联到其子级。
|
||||
- 在请求者聊天中发送 `/stop` 会中止请求者会话,并停止由其派生的所有活动子智能体运行,同时级联停止嵌套子级。
|
||||
- `/subagents kill <id>` 会停止指定子智能体,并级联停止其子级。
|
||||
|
||||
## 限制
|
||||
|
||||
- 子智能体通告是**尽力而为**的。如果 Gateway 网关重启,待处理的“回传通告”工作会丢失。
|
||||
- 子智能体仍共享同一个 Gateway 网关进程资源;请将 `maxConcurrent` 视为一个安全阀。
|
||||
- 子智能体通知是**尽力而为**的。如果 Gateway 网关重启,待处理的“通知回传”工作将会丢失。
|
||||
- 子智能体仍共享同一个 Gateway 网关进程资源;请将 `maxConcurrent` 视为安全阀。
|
||||
- `sessions_spawn` 始终是非阻塞的:它会立即返回 `{ status: "accepted", runId, childSessionKey }`。
|
||||
- 子智能体上下文只会注入 `AGENTS.md` + `TOOLS.md`(不包含 `SOUL.md`、`IDENTITY.md`、`USER.md`、`HEARTBEAT.md` 或 `BOOTSTRAP.md`)。
|
||||
- 最大嵌套深度为 5(`maxSpawnDepth` 范围:1–5)。对于大多数用例,建议使用深度 2。
|
||||
- `maxChildrenPerAgent` 限制每个会话的活动子级数量上限(默认值:5,范围:1–20)。
|
||||
- 子智能体上下文只会注入 `AGENTS.md` + `TOOLS.md`(不包括 `SOUL.md`、`IDENTITY.md`、`USER.md`、`HEARTBEAT.md` 或 `BOOTSTRAP.md`)。
|
||||
- 最大嵌套深度为 5(`maxSpawnDepth` 范围:1–5)。对于大多数使用场景,建议使用深度 2。
|
||||
- `maxChildrenPerAgent` 会限制每个会话的活动子级数量(默认值 `5`,范围 `1–20`)。
|
||||
|
||||
## 相关内容
|
||||
|
||||
- [ACP 智能体](/zh-CN/tools/acp-agents)
|
||||
- [多智能体沙箱工具](/zh-CN/tools/multi-agent-sandbox-tools)
|
||||
- [智能体发送](/zh-CN/tools/agent-send)
|
||||
- [后台任务](/zh-CN/automation/tasks)
|
||||
- [多智能体沙箱工具](/zh-CN/tools/multi-agent-sandbox-tools)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user