chore(i18n): refresh zh-CN translations

This commit is contained in:
openclaw-docs-i18n[bot] 2026-04-27 08:03:32 +00:00
parent 19095bdadf
commit 245aeb5a9e
13 changed files with 1924 additions and 1441 deletions

File diff suppressed because one or more lines are too long

View File

@ -1,28 +1,28 @@
---
read_when:
- 从 CLI 运行 Gateway 网关(开发环境或服务器)
- 调试 Gateway 网关证、绑定模式和连接性
- 调试 Gateway 网关身份验证、绑定模式和连接性
- 通过 Bonjour 发现 Gateway 网关(本地 + 广域 DNS-SD
sidebarTitle: Gateway
summary: OpenClaw Gateway 网关 CLI`openclaw gateway`)——运行、查询发现 Gateway 网关
summary: OpenClaw Gateway 网关 CLI`openclaw gateway`)——运行、查询发现 Gateway 网关
title: Gateway 网关
x-i18n:
generated_at: "2026-04-27T04:26:19Z"
generated_at: "2026-04-27T08:00:05Z"
model: gpt-5.4
provider: openai
source_hash: 795d30511ad7a98093edfcfb862869349e1454d3e01f18dec7912cc2128934de
source_hash: 9c909e8f6e1fb56b612eb1a0826cd993626c9f65b1736924b33c95a37dc60d14
source_path: cli/gateway.md
workflow: 15
---
Gateway 网关是 OpenClaw 的 WebSocket 服务器(渠道、节点、会话、钩子)。本页中的子命令位于 `openclaw gateway …` 之下。
Gateway 网关是 OpenClaw 的 WebSocket 服务器(渠道、节点、会话、钩子)。本页中的子命令位于 `openclaw gateway …` 之下。
<CardGroup cols={3}>
<Card title="Bonjour 发现" href="/zh-CN/gateway/bonjour">
本地 mDNS + 广域 DNS-SD 设置。
</Card>
<Card title="设备发现概览" href="/zh-CN/gateway/discovery">
OpenClaw 如何通告发现 Gateway 网关。
OpenClaw 如何通告发现 Gateway 网关。
</Card>
<Card title="配置" href="/zh-CN/gateway/configuration">
顶层 Gateway 网关配置键。
@ -45,31 +45,31 @@ openclaw gateway run
<AccordionGroup>
<Accordion title="启动行为">
- 默认情况下,除非在 `~/.openclaw/openclaw.json` 中设置了 `gateway.mode=local`,否则 Gateway 网关会拒绝启动。对于临时 / 开发运行,请使用 `--allow-unconfigured`
- `openclaw onboard --mode local``openclaw setup` 预期会写入 `gateway.mode=local`。如果文件存在但缺少 `gateway.mode`,应将其视为损坏或被覆盖的配置,并修复它,而不是隐式假定为本地模式。
- 如果文件存在且缺少 `gateway.mode`Gateway 网关会将其视为可疑的配置损坏,并拒绝为你“猜测为 local”。
- 未启用证时,禁止绑定到 loopback 之外的地址(安全护栏)。
- 在获得授权时,`SIGUSR1` 会触发进程内重启(`commands.restart` 默认启用;设置 `commands.restart: false` 可阻止手动重启,但 gateway 工具 / config apply / update 仍然允许)。
- `SIGINT` / `SIGTERM` 处理程序会停止 gateway 进程,但不会恢复任何自定义终端状态。如果你使用 TUI 或 raw-mode 输入包装 CLI请在退出前恢复终端。
- 默认情况下,除非在 `~/.openclaw/openclaw.json` 中设置了 `gateway.mode=local`,否则 Gateway 网关会拒绝启动。临时 / 开发运行可使用 `--allow-unconfigured`
- `openclaw onboard --mode local``openclaw setup` 预期会写入 `gateway.mode=local`。如果文件存在但缺少 `gateway.mode`,应将其视为损坏或被覆盖的配置,并修复它,而不是默认隐式假定为本地模式。
- 如果文件存在且缺少 `gateway.mode`Gateway 网关会将其视为可疑的配置损坏,并拒绝为你“猜测为本地”。
- 未启用身份验证时,禁止绑定到 loopback 之外的地址(安全护栏)。
- 在获得授权时,`SIGUSR1` 会触发进程内重启(`commands.restart` 默认启用;设置 `commands.restart: false` 可阻止手动重启,但 gateway 工具 / 配置 apply/update 仍然允许)。
- `SIGINT` / `SIGTERM` 处理器会停止 gateway 进程,但不会恢复任何自定义终端状态。如果你用 TUI 或 raw-mode 输入封装 CLI请在退出前恢复终端。
</Accordion>
</AccordionGroup>
### 选项
<ParamField path="--port <port>" type="number">
WebSocket 端口(默认值来自 config / env;通常为 `18789`)。
WebSocket 端口(默认值来自配置 / 环境变量;通常为 `18789`)。
</ParamField>
<ParamField path="--bind <loopback|lan|tailnet|auto|custom>" type="string">
监听器绑定模式。
</ParamField>
<ParamField path="--auth <token|password>" type="string">
认证模式覆盖
身份验证模式覆盖值
</ParamField>
<ParamField path="--token <token>" type="string">
Token 覆盖(也会为该进程设置 `OPENCLAW_GATEWAY_TOKEN`)。
令牌覆盖值(也会为当前进程设置 `OPENCLAW_GATEWAY_TOKEN`)。
</ParamField>
<ParamField path="--password <password>" type="string">
密码覆盖。
密码覆盖
</ParamField>
<ParamField path="--password-file <path>" type="string">
从文件读取 gateway 密码。
@ -81,10 +81,10 @@ openclaw gateway run
在关闭时重置 Tailscale serve / funnel 配置。
</ParamField>
<ParamField path="--allow-unconfigured" type="boolean">
允许在配置中没有 `gateway.mode=local` 的情况下启动 gateway。仅绕过临时 / 开发引导的启动保护;不会写入或修复配置文件。
允许在配置中没有 `gateway.mode=local` 的情况下启动 gateway。仅用于临时 / 开发引导,绕过启动保护;不会写入或修复配置文件。
</ParamField>
<ParamField path="--dev" type="boolean">
如果缺失,则创建开发配置 + 工作区(跳过 `BOOTSTRAP.md`)。
如果缺失,则创建开发配置 + 工作区(跳过 BOOTSTRAP.md
</ParamField>
<ParamField path="--reset" type="boolean">
重置开发配置 + 凭证 + 会话 + 工作区(需要 `--dev`)。
@ -99,7 +99,7 @@ openclaw gateway run
仅在控制台中显示 CLI 后端日志(并启用 stdout / stderr
</ParamField>
<ParamField path="--ws-log <auto|full|compact>" type="string" default="auto">
Websocket 日志样式。
WebSocket 日志样式。
</ParamField>
<ParamField path="--compact" type="boolean">
`--ws-log compact` 的别名。
@ -117,8 +117,8 @@ openclaw gateway run
### 启动性能分析
- 设置 `OPENCLAW_GATEWAY_STARTUP_TRACE=1`以在 Gateway 网关启动期间记录各阶段耗时。
- 运行 `pnpm test:startup:gateway -- --runs 5 --warmup 1` 以对 Gateway 网关启动进行基准测试。该基准测试会记录首次进程输出、`/healthz`、`/readyz` 和启动跟踪耗时
- 设置 `OPENCLAW_GATEWAY_STARTUP_TRACE=1`可在 Gateway 网关启动期间记录各阶段耗时,包括每个阶段的 `eventLoopMax` 延迟,以及 installed-index、manifest registry、startup planning 和 owner-map 工作中的插件查找表耗时。
- 运行 `pnpm test:startup:gateway -- --runs 5 --warmup 1` 以对 Gateway 网关启动进行基准测试。该基准会记录首个进程输出、`/healthz`、`/readyz`、启动跟踪耗时、事件循环延迟,以及插件查找表耗时详情
## 查询正在运行的 Gateway 网关
@ -127,12 +127,12 @@ openclaw gateway run
<Tabs>
<Tab title="输出模式">
- 默认:人类可读(在 TTY 中带颜色)。
- `--json`:机器可读 JSON无样式 / 无 spinner
- `--json`:机器可读 JSON无样式 / 无 spinner
- `--no-color`(或 `NO_COLOR=1`):禁用 ANSI同时保留人类可读布局。
</Tab>
<Tab title="共享选项">
- `--url <url>`Gateway 网关 WebSocket URL。
- `--token <token>`Gateway 网关 token
- `--token <token>`Gateway 网关令牌
- `--password <password>`Gateway 网关密码。
- `--timeout <ms>`:超时 / 预算(因命令而异)。
- `--expect-final`等待“final”响应智能体调用
@ -140,7 +140,7 @@ openclaw gateway run
</Tabs>
<Note>
当你设置 `--url`CLI 不会回退到配置或环境凭证。请显式传递 `--token``--password`。缺少显式凭证会报错。
设置 `--url`CLI 不会回退使用配置或环境变量中的凭证。请显式传入 `--token``--password`。缺少显式凭证会报错。
</Note>
### `gateway health`
@ -149,11 +149,11 @@ openclaw gateway run
openclaw gateway health --url ws://127.0.0.1:18789
```
HTTP `/healthz` 端点是存活探针:一旦服务器可以响应 HTTP它就会返回。HTTP `/readyz` 端点更严格,在启动 sidecar、渠道或已配置钩子仍在稳定之前会一直保持红色状态
HTTP `/healthz` 端点是存活探针:一旦服务器可以响应 HTTP它就会返回。HTTP `/readyz` 端点更严格,在启动 sidecar、渠道或已配置钩子仍在稳定期间会持续显示为未就绪
### `gateway usage-cost`
从会话日志中获取 usage-cost 摘要
从会话日志中获取 usage-cost 汇总
```bash
openclaw gateway usage-cost
@ -167,7 +167,7 @@ openclaw gateway usage-cost --json
### `gateway stability`
从正在运行的 Gateway 网关获取最近的诊断稳定性记录器数据
从正在运行的 Gateway 网关获取最近的诊断稳定性记录器内容
```bash
openclaw gateway stability
@ -178,7 +178,7 @@ openclaw gateway stability --json
```
<ParamField path="--limit <limit>" type="number" default="25">
要包含的最近事件最大数量(最大为 `1000`)。
要包含的最近事件最大数量(最大为 `1000`)。
</ParamField>
<ParamField path="--type <type>" type="string">
按诊断事件类型筛选,例如 `payload.large``diagnostic.memory.pressure`
@ -187,7 +187,7 @@ openclaw gateway stability --json
仅包含某个诊断序列号之后的事件。
</ParamField>
<ParamField path="--bundle [path]" type="string">
读取持久化的稳定性 bundle而不是调用正在运行的 Gateway 网关。对状态目录下最新的 bundle 使用 `--bundle latest`(或直接 `--bundle`),或者直接传入 bundle JSON 路径。
读取持久化的稳定性 bundle而不是调用正在运行的 Gateway 网关。对状态目录下最新的 bundle 使用 `--bundle latest`(或`--bundle`),或直接传入 bundle JSON 路径。
</ParamField>
<ParamField path="--export" type="boolean">
写出一个可共享的支持诊断 zip而不是打印稳定性详情。
@ -198,14 +198,14 @@ openclaw gateway stability --json
<AccordionGroup>
<Accordion title="隐私和 bundle 行为">
- 记录会保留运维元数据:事件名称、计数、字节大小、内存读数、队列 / 会话状态、渠道 / 插件名称以及已脱敏的会话摘要。它们不会保留聊天文本、webhook 正文、工具输出、原始请求或响应正文、token、cookie、secret 值、主机名或原始会话 id。设置 `diagnostics.enabled: false` 可完全禁用记录器。
- 在 Gateway 网关发生致命退出、关闭超时和重启启动失败时如果记录器中有事件OpenClaw 会将相同的诊断快照写入 `~/.openclaw/logs/stability/openclaw-stability-*.json`。使用 `openclaw gateway stability --bundle latest` 检查最新 bundle`--limit`、`--type` 和 `--since-seq` 适用于 bundle 输出。
- 记录会保留运维元数据:事件名称、计数、字节大小、内存读数、队列 / 会话状态、渠道 / 插件名称以及已脱敏的会话摘要。它们不会保留聊天文本、webhook 正文、工具输出、原始请求或响应正文、令牌、cookie、秘密值、主机名或原始会话 ID。将 `diagnostics.enabled: false` 设为关闭,可完全禁用该记录器。
- 在 Gateway 网关发生致命退出、关闭超时和重启启动失败时如果记录器中有事件OpenClaw 会将相同的诊断快照写入 `~/.openclaw/logs/stability/openclaw-stability-*.json`使用 `openclaw gateway stability --bundle latest` 检查最新 bundle`--limit`、`--type` 和 `--since-seq` 同样适用于 bundle 输出。
</Accordion>
</AccordionGroup>
### `gateway diagnostics export`
写出一个本地诊断 zip专门用于附加到 bug 报告。有关隐私模型和 bundle 内容,请参阅 [Diagnostics Export](/zh-CN/gateway/diagnostics)。
写出一个本地诊断 zip设计用于附加到 bug 报告。有关隐私模型和 bundle 内容,请参见 [Diagnostics Export](/zh-CN/gateway/diagnostics)。
```bash
openclaw gateway diagnostics export
@ -214,10 +214,10 @@ openclaw gateway diagnostics export --json
```
<ParamField path="--output <path>" type="string">
输出 zip 路径。默认是在状态目录下生成一个支持导出文件。
输出 zip 路径。默认为状态目录下的支持导出文件。
</ParamField>
<ParamField path="--log-lines <count>" type="number" default="5000">
要包含的最大已脱敏日志行数。
要包含的已脱敏日志行最大
</ParamField>
<ParamField path="--log-bytes <bytes>" type="number" default="1000000">
要检查的最大日志字节数。
@ -226,28 +226,28 @@ openclaw gateway diagnostics export --json
用于健康快照的 Gateway 网关 WebSocket URL。
</ParamField>
<ParamField path="--token <token>" type="string">
用于健康快照的 Gateway 网关 token
用于健康快照的 Gateway 网关令牌
</ParamField>
<ParamField path="--password <password>" type="string">
用于健康快照的 Gateway 网关密码。
</ParamField>
<ParamField path="--timeout <ms>" type="number" default="3000">
Status / health 快照超时。
Status / 健康快照超时。
</ParamField>
<ParamField path="--no-stability-bundle" type="boolean">
跳过持久化稳定性 bundle 查找。
</ParamField>
<ParamField path="--json" type="boolean">
以 JSON 格式打印写入路径、大小和清单。
以 JSON 打印写入路径、大小和清单。
</ParamField>
导出内容包括清单、Markdown 摘要、配置形状、已脱敏的配置详情、已脱敏的日志摘要、已脱敏的 Gateway 网关 status / health 快照,以及存在时的最新稳定性 bundle。
该导出包含清单、Markdown 摘要、配置结构、已脱敏配置详情、已脱敏日志摘要、已脱敏 Gateway 网关状态 / 健康快照,以及存在时的最新稳定性 bundle。
它旨在用于共享。它会保留有助于调试的运维细节,例如安全的 OpenClaw 日志字段、子系统名称、状态码、持续时间、已配置模式、端口、插件 id、提供商 id、非 secret 功能设置,以及已脱敏的运维日志消息。它会省略或脱敏聊天文本、webhook 正文、工具输出、凭证、cookie、账户 / 消息标识符、提示 / 指令文本、主机名和 secret 值。当类似 LogTape 风格的消息看起来像用户 / 聊天 / 工具负载文本时,导出仅保留“某条消息已省略”及其字节数。
它旨在共享。它会保留有助于调试的运维细节,例如安全的 OpenClaw 日志字段、子系统名称、状态码、持续时间、已配置模式、端口、插件 ID、提供商 ID、非机密功能设置以及已脱敏的运维日志消息。它会省略或脱敏聊天文本、webhook 正文、工具输出、凭证、cookie、账户 / 消息标识符、提示 / 指令文本、主机名和秘密值。当 LogTape 风格消息看起来像用户 / 聊天 / 工具负载文本时,导出只会保留“某条消息已被省略”及其字节计数。
### `gateway status`
`gateway status` 显示 Gateway 网关服务launchd / systemd / schtasks以及可选的连接性 / 认证能力探测。
`gateway status` 显示 Gateway 网关服务launchd / systemd / schtasks,以及可选的连接性 / 身份验证能力探测。
```bash
openclaw gateway status
@ -256,13 +256,13 @@ openclaw gateway status --require-rpc
```
<ParamField path="--url <url>" type="string">
添加一个显式探测目标。仍会探测已配置的远程目标和 localhost。
添加显式探测目标。仍会探测已配置的远程地址和 localhost。
</ParamField>
<ParamField path="--token <token>" type="string">
用于探测的 token 认证。
用于探测的令牌身份验证。
</ParamField>
<ParamField path="--password <password>" type="string">
用于探测的密码证。
用于探测的密码身份验证。
</ParamField>
<ParamField path="--timeout <ms>" type="number" default="10000">
探测超时。
@ -280,19 +280,19 @@ openclaw gateway status --require-rpc
<AccordionGroup>
<Accordion title="Status 语义">
- 即使本地 CLI 配置缺失或无效,`gateway status` 仍可用于诊断。
- 默认的 `gateway status` 可证明服务状态、WebSocket 连接,以及握手时可见的认证能力。它不能证明读 / 写 / 管理操作。
- 对于首次设备认证,诊断探针不会产生变更:如果已有缓存的设备 token它会复用但不会仅为了检查状态而创建新的 CLI 设备身份或只读设备配对记录。
- `gateway status` 会在可能的情况下解析已配置的认证 SecretRef 以用于探测认证。
- 如果在此命令路径中某个必需的认证 SecretRef 无法解析,当探测连接 / 认证失败时,`gateway status --json` 会报告 `rpc.authWarning`;请显式传递 `--token` / `--password`,或先解析 secret 来源。
- 如果探测成功,则会抑制未解析的 auth-ref 警告,以避免误报
- 当监听中的服务本身还不够、你还需要读范围 RPC 调用也保持健康时,请在脚本和自动化中使用 `--require-rpc`
- `--deep` 会尽力扫描额外的 launchd / systemd / schtasks 安装。当检测到多个类似 gateway 的服务时,人类可读输出会打印清理提示,并警告大多数部署应当每台机器只运行一个 gateway。
- 人类可读输出包含解析的文件日志路径,以及 CLI 与服务配置路径 / 有效性快照,以帮助诊断 profile 或状态目录漂移。
- 默认的 `gateway status` 可证明服务状态、WebSocket 连接以及握手时可见的身份验证能力。它不能证明读 / 写 / 管理操作。
- 对于首次设备身份验证,诊断探针不会产生变更:如果已有缓存的设备令牌,它会复用该令牌,但不会仅为了检查状态而创建新的 CLI 设备身份或只读设备配对记录。
- `gateway status` 会在可能的情况下解析已配置的身份验证 SecretRef用于探针身份验证。
- 如果此命令路径中某个必需的身份验证 SecretRef 无法解析,且探针连接 / 身份验证失败,`gateway status --json` 会报告 `rpc.authWarning`;请显式传入 `--token` / `--password`,或先解析对应的 secret 来源。
- 如果探针成功,为避免误报,未解析的 auth-ref 警告会被抑制
- 当仅有监听服务还不够、你还需要读作用域的 RPC 调用也保持健康时,请在脚本和自动化中使用 `--require-rpc`
- `--deep` 会尽力扫描额外的 launchd / systemd / schtasks 安装。当检测到多个类似 gateway 的服务时,人类可读输出会打印清理提示,并警告大多数环境应每台机器仅运行一个 gateway。
- 人类可读输出包含解析的文件日志路径,以及 CLI 与服务配置路径 / 有效性快照,以帮助诊断 profile 或状态目录漂移。
</Accordion>
<Accordion title="Linux systemd 证漂移检查">
- 在 Linux systemd 安装中,服务认证漂移检查会同时读取 unit 中的 `Environment=``EnvironmentFile=` 值(包括 `%h`、带引号的路径、多个文件可选的 `-` 文件)。
- 漂移检查会使用合并后的运行时环境变量解析 `gateway.auth.token` SecretRef优先使用服务命令环境变量然后回退到进程环境变量)。
- 如果 token 认证实际上未激活(显式 `gateway.auth.mode``password` / `none` / `trusted-proxy`,或 mode 未设置且 password 可能优先、并且没有任何 token 候选能胜出),则 token 漂移检查会跳过配置 token 解析。
<Accordion title="Linux systemd 身份验证漂移检查">
- 在 Linux systemd 安装中,服务身份验证漂移检查会同时读取单元中的 `Environment=``EnvironmentFile=` 值(包括 `%h`、带引号的路径、多个文件以及可选的 `-` 文件)。
- 漂移检查会使用合并后的运行时环境变量解析 `gateway.auth.token` SecretRef优先使用服务命令环境变量其次回退到进程环境变量)。
- 如果令牌身份验证实际上未启用(显式 `gateway.auth.mode``password` / `none` / `trusted-proxy`,或 mode 未设置且 password 可能胜出,同时没有任何可能胜出的令牌候选值),则令牌漂移检查会跳过配置中的令牌解析。
</Accordion>
</AccordionGroup>
@ -301,16 +301,16 @@ openclaw gateway status --require-rpc
`gateway probe` 是“调试一切”的命令。它始终会探测:
- 你已配置的远程 gateway如果已设置以及
- localhostlocal loopback**即使已配置远程地址也是如此**。
- localhostlocal loopback**即使已配置远程地址**。
如果你传`--url`,则会在这两者之前添加该显式目标。人类可读输出会将目标标记为:
如果你传`--url`,该显式目标会被添加到两者之前。人类可读输出会将目标标记为:
- `URL显式`
- `Remote已配置``Remote已配置未激活`
- `Local loopback`
<Note>
如果有多个 gateway 可达,它会全部打印出来。当你使用隔离的 profile / 端口(例如 rescue bot时支持多个 gateway,但大多数安装仍然只运行单个 gateway。
如果有多个 gateway 可达,它会全部打印出来。当你使用隔离的 profile / 端口时,支持多个 gateway(例如 rescue bot但大多数安装仍然只运行单个 gateway。
</Note>
```bash
@ -321,49 +321,49 @@ openclaw gateway probe --json
<AccordionGroup>
<Accordion title="结果解读">
- `Reachable: yes` 表示至少有一个目标接受了 WebSocket 连接。
- `Capability: read-only|write-capable|admin-capable|pairing-pending|connect-only` 表示探针能够证明的证能力。它与可达性是分开的。
- `Read probe: ok` 表示读范围详情 RPC 调用(`health` / `status` / `system-presence` / `config.get`)也成功了。
- `Read probe: limited - missing scope: operator.read` 表示连接成功,但读范围 RPC 受限。这会被报告为**降级**可达性,而不是完全失败。
- 与 `gateway status` 一样probe 会复用现有缓存的设备证,但不会创建首次设备身份或配对状态。
- 只有在所有被探测目标都不可达时,退出码才为非零。
- `Capability: read-only|write-capable|admin-capable|pairing-pending|connect-only` 表示探针能够证明的身份验证能力。它与可达性是分开的。
- `Read probe: ok` 表示读作用域的详情 RPC 调用(`health` / `status` / `system-presence` / `config.get`)也成功了。
- `Read probe: limited - missing scope: operator.read` 表示连接成功,但读作用域 RPC 受限。它会被报告为**降级**可达性,而不是完全失败。
- 与 `gateway status` 一样probe 会复用现有缓存的设备身份验证,但不会创建首次设备身份或配对状态。
- 仅当所有被探测目标都不可达时,退出码才为非零。
</Accordion>
<Accordion title="JSON 输出">
顶层:
- `ok`:至少有一个目标可达。
- `degraded`:至少有一个目标的详情 RPC 受到范围
- `capability`在所有可达目标中观察到的最佳能力(`read_only`、`write_capable`、`admin_capable`、`pairing_pending`、`connected_no_operator_scope` 或 `unknown`)。
- `primaryTargetId`:按以下顺序作为活动优胜者处理的最佳目标:显式 URL、SSH 隧道、已配置远程目标,然后是本地 loopback。
- `warnings[]`:尽力而为的警告记录,包含 `code`、`message` 和可选的 `targetIds`
- `network`从当前配置和主机网络派生出的本地 loopback / tailnet URL 提示。
- `discovery.timeoutMs``discovery.count`本次探测实际使用的设备发现预算 / 结果计数
- `degraded`:至少有一个目标的详情 RPC 因作用域限制而受限。
- `capability`所有可达目标中观测到的最佳能力(`read_only`、`write_capable`、`admin_capable`、`pairing_pending`、`connected_no_operator_scope` 或 `unknown`)。
- `primaryTargetId`:按以下顺序选出的最佳活跃目标:显式 URL、SSH 隧道、已配置的远程目标,然后是 local loopback。
- `warnings[]`:尽力生成的警告记录,包含 `code`、`message` 和可选的 `targetIds`
- `network`根据当前配置和主机网络推导出的 local loopback / tailnet URL 提示。
- `discovery.timeoutMs``discovery.count`此次探测过程实际使用的设备发现预算 / 结果数量
每个目标(`targets[].connect`
- `ok`在连接以及降级分类之后的可达性。
- `ok`连接后并经过降级分类后的可达性。
- `rpcOk`:完整详情 RPC 成功。
- `scopeLimited`由于缺少 operator 范围,详情 RPC 失败。
- `scopeLimited`详情 RPC 因缺少 operator 作用域而失败。
每个目标(`targets[].auth`
- `role`可用时,在 `hello-ok` 中报告的认证角色。
- `scopes`可用时,在 `hello-ok` 中报告的已授予范围
- `capability`为该目标呈现的认证能力分类。
- `role`在可用时,由 `hello-ok` 报告的身份验证角色。
- `scopes`在可用时,由 `hello-ok` 报告的已授予作用域
- `capability`该目标暴露出的身份验证能力分类。
</Accordion>
<Accordion title="常见警告代码">
- `ssh_tunnel_failed`SSH 隧道设置失败;命令已回退为直接探测。
- `multiple_gateways`有多个目标可达;除非你有意运行隔离的 profile例如 rescue bot否则这并不常见。
- `auth_secretref_unresolved`:某个已配置的认证 SecretRef 无法为失败目标解析。
- `probe_scope_limited`WebSocket 连接成功,但读探针因缺少 `operator.read` 而受限。
- `ssh_tunnel_failed`SSH 隧道建立失败;命令已回退为直接探测。
- `multiple_gateways`可达目标不止一个;除非你有意运行隔离的 profile例如 rescue bot否则这并不常见。
- `auth_secretref_unresolved`:某个失败目标的已配置身份验证 SecretRef 无法解析。
- `probe_scope_limited`WebSocket 连接成功,但读探针因缺少 `operator.read` 而受限。
</Accordion>
</AccordionGroup>
#### 通过 SSH 连接远程目标(与 Mac 应用一致)
#### 通过 SSH 连接远程(与 Mac 应用一致)
macOS 应用的“Remote over SSH”模式使用本地端口转发使远程 gateway它可能仅绑定到 loopback可以通过 `ws://127.0.0.1:<port>` 访问。
macOS 应用的“Remote over SSH”模式使用本地端口转发使远程 gateway其绑定地址可能仅为 loopback可以通过 `ws://127.0.0.1:<port>` 访问。
等效 CLI
等效 CLI
```bash
openclaw gateway probe --ssh user@gateway-host
@ -376,7 +376,7 @@ openclaw gateway probe --ssh user@gateway-host
身份文件。
</ParamField>
<ParamField path="--ssh-auto" type="boolean">
解析的设备发现端点中选择第一个发现的 gateway 主机作为 SSH 目标`local.` 加上已配置的广域域名(如果有))。仅 TXT 的提示会被忽略。
从解析的设备发现端点`local.` 加上已配置的广域域名(如果有))选择第一个发现的 gateway 主机作为 SSH 目标。仅 TXT 的提示会被忽略。
</ParamField>
配置(可选,用作默认值):
@ -386,7 +386,7 @@ openclaw gateway probe --ssh user@gateway-host
### `gateway call <method>`
底层 RPC 辅助命令
底层 RPC 帮助工具
```bash
openclaw gateway call status
@ -394,13 +394,13 @@ openclaw gateway call logs.tail --params '{"sinceMs": 60000}'
```
<ParamField path="--params <json>" type="string" default="{}">
用于 params 的 JSON 对象字符串。
参数的 JSON 对象字符串。
</ParamField>
<ParamField path="--url <url>" type="string">
Gateway 网关 WebSocket URL。
</ParamField>
<ParamField path="--token <token>" type="string">
Gateway 网关 token
Gateway 网关令牌
</ParamField>
<ParamField path="--password <password>" type="string">
Gateway 网关密码。
@ -409,7 +409,7 @@ openclaw gateway call logs.tail --params '{"sinceMs": 60000}'
超时预算。
</ParamField>
<ParamField path="--expect-final" type="boolean">
主要用于智能体风格的 RPC,这类 RPC 会在最终负载之前流式传输中间事件。
主要用于智能体风格的 RPC:在最终负载之前会先流式传输中间事件。
</ParamField>
<ParamField path="--json" type="boolean">
机器可读的 JSON 输出。
@ -432,8 +432,7 @@ openclaw gateway uninstall
### 使用 wrapper 安装
当托管服务必须通过另一个可执行文件启动时,请使用 `--wrapper`,例如
secret 管理器 shim 或 run-as 辅助程序。wrapper 会接收正常的 Gateway 网关参数,并
负责最终使用这些参数执行 `openclaw` 或 Node。
secret 管理器 shim 或 run-as helper。wrapper 会接收正常的 Gateway 网关参数,并负责最终使用这些参数执行 `openclaw` 或 Node。
```bash
cat > ~/.local/bin/openclaw-doppler <<'EOF'
@ -448,9 +447,8 @@ openclaw gateway restart
```
你也可以通过环境变量设置 wrapper。`gateway install` 会验证该路径是
一个可执行文件,将 wrapper 写入服务 `ProgramArguments`,并在服务环境中持久化
`OPENCLAW_WRAPPER`,供后续强制重新安装、更新和 Doctor
修复使用。
可执行文件,将 wrapper 写入服务的 `ProgramArguments`,并在服务环境中持久化
`OPENCLAW_WRAPPER`,供后续强制重装、更新和 Doctor 修复使用。
```bash
OPENCLAW_WRAPPER="$HOME/.local/bin/openclaw-doppler" openclaw gateway install --force
@ -471,36 +469,36 @@ openclaw gateway restart
- `gateway uninstall|start|stop|restart``--json`
</Accordion>
<Accordion title="生命周期行为">
- 使用 `gateway restart` 重启托管服务。不要`gateway stop``gateway start` 串联起来替代重启;在 macOS 上,`gateway stop` 会在停止之前有意禁用 LaunchAgent
- 生命周期命令接受 `--json` 以供脚本使用。
- 使用 `gateway restart` 重启托管服务。不要`gateway stop``gateway start` 串联起来作为重启替代方案;在 macOS 上,`gateway stop` 会先有意禁用 LaunchAgent然后再停止它
- 生命周期命令接受 `--json`,便于脚本调用。
</Accordion>
<Accordion title="安装时的证和 SecretRef">
- 当 token 认证需要 token `gateway.auth.token` 由 SecretRef 管理时,`gateway install` 会验证 SecretRef 可解析,但不会将解析后的 token 持久化到服务环境元数据中。
- 如果 token 认证需要 token而已配置的 token SecretRef 无法解析,则安装会以封闭失败的方式终止,而不是持久化回退明文。
- 对于 `gateway run` 的密码证,优先使用 `OPENCLAW_GATEWAY_PASSWORD`、`--password-file` 或由 SecretRef 支持的 `gateway.auth.password`而不是内联 `--password`
- 在推断认证模式下,仅 shell 中的 `OPENCLAW_GATEWAY_PASSWORD` 不会放宽安装的 token 要求;安装托管服务时,请使用持久配置(`gateway.auth.password` 或 config `env`)。
- 如果同时配置了 `gateway.auth.token``gateway.auth.password` `gateway.auth.mode` 未设置,则在显式设置 mode 之前会阻止安装。
<Accordion title="安装时的身份验证和 SecretRef">
- 当令牌身份验证需要令牌`gateway.auth.token` 由 SecretRef 管理时,`gateway install` 会验证 SecretRef 可解析,但不会将解析后的令牌持久化到服务环境元数据中。
- 如果令牌身份验证需要令牌且已配置的令牌 SecretRef 无法解析,安装会以安全失败方式中止,而不是持久化回退的明文。
- 对于 `gateway run` 的密码身份验证,优先使用 `OPENCLAW_GATEWAY_PASSWORD`、`--password-file` 或由 SecretRef 支持的 `gateway.auth.password`不要使用内联 `--password`
- 在推断身份验证模式下,仅 shell 中的 `OPENCLAW_GATEWAY_PASSWORD` 不会放宽安装时的令牌要求;安装托管服务时,请使用持久配置(`gateway.auth.password` 或配置中的 `env`)。
- 如果同时配置了 `gateway.auth.token``gateway.auth.password` `gateway.auth.mode` 未设置,则在显式设置 mode 之前会阻止安装。
</Accordion>
</AccordionGroup>
## 发现 gatewayBonjour
## 发现 Gateway 网关Bonjour
`gateway discover` 会扫描 Gateway 网关 beacon`_openclaw-gw._tcp`)。
`gateway discover` 会扫描 Gateway 网关信标`_openclaw-gw._tcp`)。
- Multicast DNS-SD`local.`
- Unicast DNS-SD广域 Bonjour选择一个域名例如`openclaw.internal.`),并设置 split DNS + DNS 服务器;参见 [Bonjour](/zh-CN/gateway/bonjour)。
- 组播 DNS-SD`local.`
- 单播 DNS-SD广域 Bonjour选择一个域名例如`openclaw.internal.`),并设置 split DNS + DNS 服务器;参见 [Bonjour](/zh-CN/gateway/bonjour)。
只有启用了 Bonjour 设备发现(默认启用)的 gateway 才会通告该 beacon
只有启用了 Bonjour 设备发现的 gateway默认启用才会通告该信标
广域发现记录包TXT
广域发现记录包TXT
- `role`gateway 角色提示)
- `transport`(传输提示,例如 `gateway`
- `gatewayPort`WebSocket 端口,通常为 `18789`
- `sshPort`(可选;缺失时客户端默认 SSH 目标端口为 `22`
- `sshPort`(可选;缺失时客户端默认 SSH 目标端口为 `22`
- `tailnetDns`(可用时的 MagicDNS 主机名)
- `gatewayTls` / `gatewayTlsSha256`TLS 是否启用 + 证书指纹)
- `cliPath`(写入广域区域的远程安装提示)
- `gatewayTls` / `gatewayTlsSha256`(是否启用 TLS + 证书指纹)
- `cliPath`(写入广域 zone 的远程安装提示)
### `gateway discover`
@ -523,9 +521,9 @@ openclaw gateway discover --json | jq '.beacons[].wsUrl'
```
<Note>
- CLI 会扫描 `local.` 以及已配置的广域域名(如果已启用)
- JSON 输出中的 `wsUrl` 派生自已解析的服务端点,而不是 `lanHost``tailnetDns` 之类仅 TXT 的提示
- 在 `local.` mDNS 上,只有`discovery.mdns.mode``full` 时,才会广播 `sshPort``cliPath`。广域 DNS-SD 仍会写入 `cliPath``sshPort` 在那里同样保持可选
- CLI 会扫描 `local.`,以及启用时已配置的广域域名
- JSON 输出中的 `wsUrl` 是从解析后的服务端点推导出来的,而不是来自仅 TXT 的提示,例如 `lanHost``tailnetDns`
- 在 `local.` mDNS 上,`discovery.mdns.mode``full` 时,才会广播 `sshPort``cliPath`。广域 DNS-SD 仍会写入 `cliPath``sshPort` 在那里也仍然是可选的
</Note>
## 相关内容

82
docs/zh-CN/cli/migrate.md Normal file
View File

@ -0,0 +1,82 @@
---
read_when:
- 你想从 Hermes 或另一个智能体系统迁移到 OpenClaw】【。
- 你正在添加一个由插件拥有的迁移提供商】【。
summary: 从另一个智能体系统导入状态的 CLI 参考
title: 迁移
x-i18n:
generated_at: "2026-04-27T08:00:10Z"
model: gpt-5.4
provider: openai
source_hash: 3efe1f29ae0e7832b7a349f2260e6934990d09ca74a16b73b31350613e2f77aa
source_path: cli/migrate.md
workflow: 15
---
# `openclaw migrate`
通过由插件拥有的迁移提供商,从另一个智能体系统导入状态。
```bash
openclaw migrate list
openclaw migrate hermes --dry-run
openclaw migrate hermes
openclaw migrate apply hermes --yes
openclaw migrate apply hermes --include-secrets --yes
openclaw onboard --flow import
openclaw onboard --import-from hermes --import-source ~/.hermes
```
## 安全模型
`openclaw migrate` 采用“预览优先”模式。提供商会在任何更改发生前返回一份逐项列出的计划其中包括冲突、已跳过的项以及敏感项。JSON 计划、应用输出和迁移报告会对嵌套的疑似密钥字段进行脱敏,例如 API 密钥、令牌、授权头、cookie 和密码。
`openclaw migrate apply <provider>` 会先预览计划,并在更改状态之前提示确认,除非设置了 `--yes`。在非交互模式下apply 需要 `--yes`。使用 `--json` 且未设置 `--yes`apply 会打印 JSON 计划,并且不会修改状态。
Apply 会在执行迁移之前创建并验证一个 OpenClaw 备份。如果本地尚不存在 OpenClaw 状态,则会跳过备份步骤,迁移仍可继续。若在状态已存在时跳过备份,请同时传入 `--no-backup``--force`
当计划中存在冲突时Apply 模式会拒绝继续执行。请先查看计划,然后在确实有意替换现有目标时,使用 `--overwrite` 重新运行。对于被覆盖的文件,提供商仍可能在迁移报告目录中写入逐项备份。
默认情况下绝不会导入密钥。使用 `--include-secrets` 以导入受支持的凭证。
## Hermes
内置的 Hermes 提供商默认会在 `~/.hermes` 检测 Hermes 状态。如果 Hermes 位于其他位置,请使用 `--from <path>`
Hermes 迁移可导入:
- `config.yaml` 中的默认模型配置
- `providers``custom_providers` 中已配置的模型提供商及自定义 OpenAI 兼容端点
- `mcp_servers``mcp.servers` 中的 MCP 服务器定义
- 将 `SOUL.md``AGENTS.md` 导入到 OpenClaw 智能体工作区
- 通过追加到工作区 memory 文件,导入 `memories/MEMORY.md``memories/USER.md`
- OpenClaw 文件 memory 的 memory 配置默认值,以及针对 Honcho 等外部 memory 提供商的仅归档 / 需手动审核项
- 来自 `skills/<name>/` 且带有 `SKILL.md` 文件的 Skills
- 来自 `skills.config` 的按 Skill 划分的配置值
- 来自 `.env` 的受支持 API 密钥,仅在使用 `--include-secrets` 时导入
仅归档的 Hermes 状态会被复制到迁移报告中,供手动审核,但不会载入到在线的 OpenClaw 配置或凭证中。这会保留不透明或不安全的状态,例如 `plugins/`、`sessions/`、`logs/`、`cron/`、`mcp-tokens/`、`auth.json` 和 `state.db`,而不会假装 OpenClaw 可以自动执行或信任它们。
受支持的 Hermes `.env` 键包括 `OPENAI_API_KEY`、`ANTHROPIC_API_KEY`、`OPENROUTER_API_KEY`、`GOOGLE_API_KEY`、`GEMINI_API_KEY`、`GROQ_API_KEY`、`XAI_API_KEY`、`MISTRAL_API_KEY` 和 `DEEPSEEK_API_KEY`
应用迁移后,请运行:
```bash
openclaw doctor
```
## 插件契约
迁移源是插件。插件会在 `openclaw.plugin.json` 中声明其提供商 id
```json
{
"contracts": {
"migrationProviders": ["hermes"]
}
}
```
在运行时,插件会调用 `api.registerMigrationProvider(...)`。该提供商实现 `detect`、`plan` 和 `apply`;核心负责 CLI 编排、备份策略、提示、JSON 输出和冲突预检。核心会将审核后的计划传入 `apply(ctx, plan)`,而提供商仅可在该参数缺失时重新构建计划,以保持兼容性。提供商插件可以使用 `openclaw/plugin-sdk/migration` 进行条目构造和汇总计数,也可以使用 `openclaw/plugin-sdk/migration-runtime` 进行具备冲突感知的文件复制、仅归档报告复制和迁移报告处理。
当某个提供商检测到已知来源时,新手引导也可以提供迁移。`openclaw onboard --flow import` 和 `openclaw setup --wizard --import-from hermes` 使用相同的插件迁移提供商,并且在应用前仍会显示预览。新手引导导入要求使用全新的 OpenClaw 设置;如果你已经有本地状态,请先重置配置、凭证、会话和工作区。对于现有设置,带备份以及覆盖或合并的导入目前受功能开关控制。

View File

@ -1,13 +1,13 @@
---
read_when:
- 你想通过引导式设置来配置网关、工作区、凭证、渠道和 Skills
summary: '`openclaw onboard` 的 CLI 参考(交互式新手引导)'
- 你希望通过引导式设置来配置 Gateway 网关、工作区、凭证、渠道和 Skills。
summary: '`openclaw onboard`(交互式新手引导)的 CLI 参考'
title: 新手引导
x-i18n:
generated_at: "2026-04-27T04:37:31Z"
generated_at: "2026-04-27T08:00:02Z"
model: gpt-5.4
provider: openai
source_hash: 98985c119f64ba41ed1a74fbb0bf1feb78b3c5daa4844e66f3aa1ae73ef6d0f5
source_hash: 041063bce6616ed32225cb411f385dcbfd750c0bb2779ec17bc58e1aa9ada254
source_path: cli/onboard.md
workflow: 15
---
@ -23,10 +23,10 @@ x-i18n:
交互式 CLI 流程的演练说明。
</Card>
<Card title="新手引导概览" href="/zh-CN/start/onboarding-overview" icon="map">
OpenClaw 新手引导如何协同工作。
OpenClaw 新手引导如何协同工作。
</Card>
<Card title="CLI 设置参考" href="/zh-CN/start/wizard-cli-reference" icon="book">
输出、内部机制以及每一步的行为。
输出、内部机制和各步骤行为。
</Card>
<Card title="CLI 自动化" href="/zh-CN/start/wizard-cli-automation" icon="terminal">
非交互式标志和脚本化设置。
@ -43,13 +43,20 @@ openclaw onboard
openclaw onboard --modern
openclaw onboard --flow quickstart
openclaw onboard --flow manual
openclaw onboard --flow import
openclaw onboard --import-from hermes --import-source ~/.hermes
openclaw onboard --skip-bootstrap
openclaw onboard --mode remote --remote-url wss://gateway-host:18789
```
`--modern` 会启动 Crestodian 对话式新手引导预览。若不使用 `--modern``openclaw onboard` 将继续使用经典新手引导流程
`--flow import` 使用由插件拥有的迁移提供商,例如 Hermes。它仅适用于全新的 OpenClaw 设置;如果已存在配置、凭证、会话或工作区内存/身份文件,请在导入前重置或选择一个全新的设置
对于明文私有网络 `ws://` 目标(仅限受信任网络),请在新手引导进程环境中设置 `OPENCLAW_ALLOW_INSECURE_PRIVATE_WS=1`。此客户端传输层的紧急兜底选项没有对应的 `openclaw.json` 配置方式。
`--modern` 会启动 Crestodian 对话式新手引导预览。不使用
`--modern` 时,`openclaw onboard` 会保留经典的新手引导流程。
对于明文私有网络 `ws://` 目标(仅限受信任网络),请在新手引导进程环境中设置
`OPENCLAW_ALLOW_INSECURE_PRIVATE_WS=1`
这种客户端传输层的紧急开关没有对应的 `openclaw.json` 配置项。
非交互式自定义提供商:
@ -65,7 +72,7 @@ openclaw onboard --non-interactive \
在非交互式模式下,`--custom-api-key` 是可选的。如果省略,新手引导会检查 `CUSTOM_API_KEY`
LM Studio 在非交互式模式下也支持提供商专用的密钥标志:
LM Studio 在非交互式模式下也支持特定于提供商的密钥标志:
```bash
openclaw onboard --non-interactive \
@ -86,7 +93,7 @@ openclaw onboard --non-interactive \
--accept-risk
```
`--custom-base-url` 默认为 `http://127.0.0.1:11434`。`--custom-model-id` 是可选的;如果省略,新手引导会使用 Ollama 建议的默认值。`kimi-k2.5:cloud` 这样的云端模型 ID 在这里也可用。
`--custom-base-url` 默认`http://127.0.0.1:11434`。`--custom-model-id` 是可选的;如果省略,新手引导会使用 Ollama 建议的默认值。诸如 `kimi-k2.5:cloud` 之类的云模型 ID 在这里也可用。
将提供商密钥存储为引用而不是明文:
@ -97,26 +104,26 @@ openclaw onboard --non-interactive \
--accept-risk
```
使用 `--secret-input-mode ref` 时,新手引导会写入基于环境变量的引用,而不是明文密钥值。
对于基于 auth-profile 的提供商,这会写入 `keyRef` 条目;对于自定义提供商,这会将 `models.providers.<id>.apiKey` 写为环境变量引用(例如 `{ source: "env", provider: "default", id: "CUSTOM_API_KEY" }`)。
使用 `--secret-input-mode ref` 时,新手引导会写入由环境变量支持的引用,而不是明文密钥值。
对于由 auth-profile 支持的提供商,这会写入 `keyRef` 条目;对于自定义提供商,这会将 `models.providers.<id>.apiKey` 写为环境变量引用(例如 `{ source: "env", provider: "default", id: "CUSTOM_API_KEY" }`)。
非交互式 `ref` 模式约定:
- 在新手引导进程环境中设置提供商环境变量(例如 `OPENAI_API_KEY`)。
- 不要传递内联密钥标志(例如 `--openai-api-key`),除非同时也设置了该环境变量。
- 如果传递了内联密钥标志,但未设置所需的环境变量,新手引导会快速失败并提供指引。
- 不要传递内联密钥标志(例如 `--openai-api-key`),除非该环境变量也已设置
- 如果传递了内联密钥标志但所需环境变量未设置,新手引导会快速失败并给出指引。
非交互式模式下的 Gateway 网关令牌选项:
- `--gateway-auth token --gateway-token <token>` 存储明文令牌。
- `--gateway-auth token --gateway-token-ref-env <name>` `gateway.auth.token` 存储为环境变量 SecretRef。
- `--gateway-auth token --gateway-token <token>` 存储明文令牌。
- `--gateway-auth token --gateway-token-ref-env <name>``gateway.auth.token` 存储为环境变量 SecretRef。
- `--gateway-token``--gateway-token-ref-env` 互斥。
- `--gateway-token-ref-env` 要求在新手引导进程环境中存在非空环境变量。
- 使用 `--install-daemon` 时,当令牌认证需要令牌时,由 SecretRef 管理的 Gateway 网关令牌会被验证,但不会以解析后的明文形式持久化到监督服务环境元数据中。
- 使用 `--install-daemon` 时,如果令牌模式需要令牌,而已配置的令牌 SecretRef 无法解析,新手引导会以关闭失败的方式终止,并提供修复指引。
- 使用 `--install-daemon` 时,如果同时配置了 `gateway.auth.token``gateway.auth.password`且未设置 `gateway.auth.mode`,新手引导会阻止安装,直到显式设置 mode
- 本地新手引导会将 `gateway.mode="local"` 写入配置。如果后续某个配置文件缺少 `gateway.mode`,应将其视为配置损坏或不完整的手动编辑,而不是有效的本地模式快捷方式
- `--allow-unconfigured` 是单独的 Gateway 网关运行时紧急兜底选项。它并不表示新手引导可以省略 `gateway.mode`
- `--gateway-token-ref-env` 要求在新手引导进程环境中存在一个非空环境变量。
- 使用 `--install-daemon` 时,当令牌认证需要令牌时,由 SecretRef 管理的 Gateway 网关令牌会被验证,但不会以已解析的明文形式持久化到 supervisor 服务环境元数据中。
- 使用 `--install-daemon` 时,如果令牌模式需要令牌,而配置的令牌 SecretRef 未解析,新手引导会以安全关闭方式失败,并给出修复指引。
- 使用 `--install-daemon` 时,如果同时配置了 `gateway.auth.token``gateway.auth.password`但未设置 `gateway.auth.mode`,则在显式设置模式之前,新手引导会阻止安装
- 本地新手引导会将 `gateway.mode="local"` 写入配置。如果后续配置文件缺少 `gateway.mode`,应将其视为配置损坏或不完整的手动编辑,而不是有效的本地模式捷径
- `--allow-unconfigured` 是单独的 Gateway 网关运行时紧急开关。它并不表示新手引导可以省略 `gateway.mode`
示例:
@ -132,25 +139,25 @@ openclaw onboard --non-interactive \
非交互式本地 Gateway 网关健康检查:
- 除非你传`--skip-health`,否则新手引导会等待本地 Gateway 网关可访问后,才会成功退出
- `--install-daemon` 会先启动受管 Gateway 网关安装路径。不使用它,你必须已经有一个正在运行的本地 Gateway 网关,例如 `openclaw gateway run`
- 如果你在自动化中只想写入 config/workspace/bootstrap请使用 `--skip-health`
- 如果你自行管理工作区文件,请传 `--skip-bootstrap` 以设置 `agents.defaults.skipBootstrap: true`,并跳过创建 `AGENTS.md`、`SOUL.md`、`TOOLS.md`、`IDENTITY.md`、`USER.md`、`HEARTBEAT.md` 和 `BOOTSTRAP.md`
- 在原生 Windows 上,`--install-daemon` 会先尝试 Scheduled Tasks如果任务创建被拒绝则回退到每用户 Startup 文件夹登录项。
- 除非你传`--skip-health`,否则新手引导会在成功退出前等待本地 Gateway 网关可连接
- `--install-daemon` 会先启动受管 Gateway 网关安装路径。如果不使用它,你必须已经有一个正在运行的本地 Gateway 网关,例如 `openclaw gateway run`
- 如果你只想在自动化中写入配置/工作区/bootstrap请使用 `--skip-health`
- 如果你自行管理工作区文件,请传 `--skip-bootstrap` 以设置 `agents.defaults.skipBootstrap: true`,并跳过创建 `AGENTS.md`、`SOUL.md`、`TOOLS.md`、`IDENTITY.md`、`USER.md`、`HEARTBEAT.md` 和 `BOOTSTRAP.md`
- 在原生 Windows 上,`--install-daemon` 会先尝试 Scheduled Tasks如果任务创建被拒绝则回退到按用户的 Startup 文件夹登录项。
使用引用模式时的交互式新手引导行为:
- 出现提示时,选择 **Use secret reference**。
- 然后选择以下之一:
- Environment variable
- Configured secret provider (`file` 或 `exec`)
- 新手引导会在保存引用前执行快速预检验证。
- 出现提示时,选择 **使用秘密引用**。
- 然后选择以下其中之一:
- 环境变量
- 已配置的秘密提供商(`file` 或 `exec`
- 在保存引用前,新手引导会执行快速预检验证。
- 如果验证失败,新手引导会显示错误并允许你重试。
### 非交互式 Z.AI 端点选择
<Note>
`--auth-choice zai-api-key`为你的密钥自动检测最佳 Z.AI 端点(优先选择通用 API 和 `zai/glm-5.1`)。如果你明确想使用 GLM Coding Plan 端点,请选择 `zai-coding-global``zai-coding-cn`
`--auth-choice zai-api-key`自动为你的密钥检测最佳 Z.AI 端点(优先使用通用 API 和 `zai/glm-5.1`)。如果你明确想使用 GLM Coding Plan 端点,请选择 `zai-coding-global``zai-coding-cn`
</Note>
```bash
@ -178,25 +185,27 @@ openclaw onboard --non-interactive \
<AccordionGroup>
<Accordion title="流程类型">
- `quickstart`:最少提示,自动生成 Gateway 网关令牌。
- `manual`:针对端口、绑定和认证的完整提示(`advanced` 的别名)。
- `manual`:完整提示端口、绑定和认证(`advanced` 的别名)。
- `import`:运行检测到的迁移提供商,预览计划,然后在确认后应用。
</Accordion>
<Accordion title="提供商预筛选">
当某个认证选项意味着优先提供商时,新手引导会将默认模型和 allowlist 选择器预筛选到该提供商。对于 Volcengine 和 BytePlus国际版这也会匹配 coding-plan 变体(`volcengine-plan/*`、`byteplus-plan/*`)。
当某个认证选择暗示了首选提供商时,新手引导会将默认模型和 allowlist 选择器预筛选到该提供商。对于 Volcengine 和 BytePlus国际版这也会匹配 coding-plan 变体(`volcengine-plan/*`、`byteplus-plan/*`)。
如果优先提供商过滤后尚未得到任何已加载模型,新手引导会回退到未筛选的目录,而不是让选择器保持空
如果首选提供商筛选后尚未产生任何已加载模型,新手引导会回退到未筛选的目录,而不是让选择器保持空。
</Accordion>
<Accordion title="Web 搜索后续步骤">
某些 Web 搜索提供商会触发提供商专用的后续提示:
<Accordion title="Web 搜索后续提示">
某些 Web 搜索提供商会触发特定于提供商的后续提示:
- **Grok**提供可选的 `x_search` 设置,使用相同的 `XAI_API_KEY` 和一个 `x_search` 模型选择。
- **Kimi**以询问 Moonshot API 区域(`api.moonshot.ai` 与 `api.moonshot.cn`)以及默认的 Kimi Web 搜索模型。
- **Grok**能会提供可选的 `x_search` 设置,使用相同的 `XAI_API_KEY` 和一个 `x_search` 模型选择。
- **Kimi**能会询问 Moonshot API 区域(`api.moonshot.ai` 还是 `api.moonshot.cn`)以及默认的 Kimi Web 搜索模型。
</Accordion>
<Accordion title="其他行为">
- 本地新手引导的私信 范围行为:[CLI 设置参考](/zh-CN/start/wizard-cli-reference#outputs-and-internals)。
- 最快开始首次聊天:`openclaw dashboard`Control UI无需渠道设置)。
- 最快开始首次聊天:`openclaw dashboard`Control UI无需设置渠道)。
- 自定义提供商:连接任何兼容 OpenAI 或 Anthropic 的端点,包括未列出的托管提供商。使用 Unknown 可自动检测。
- 如果检测到 Hermes 状态,新手引导会提供迁移流程。使用 [迁移](/zh-CN/cli/migrate) 获取 dry-run 计划、覆盖模式、报告和精确映射。
</Accordion>
</AccordionGroup>
@ -208,5 +217,5 @@ openclaw agents add <name>
```
<Note>
`--json` 并不意味着非交互式模式。脚本中请使用 `--non-interactive`
`--json` 并不表示非交互式模式。脚本中请使用 `--non-interactive`
</Note>

View File

@ -1,14 +1,14 @@
---
read_when:
- 你正在进行首次运行设置,而不执行完整的 CLI 新手引导
- 你正在进行首次运行设置,但不使用完整的 CLI 新手引导
- 你想设置默认工作区路径
summary: '`openclaw setup` 的 CLI 参考(初始化配置 + 工作区)'
title: 设置
x-i18n:
generated_at: "2026-04-24T04:01:28Z"
generated_at: "2026-04-27T08:00:03Z"
model: gpt-5.4
provider: openai
source_hash: 650b0faf99ef1bc24ec6514661093a9a2ba7edead2e2622b863d51553c44f267
source_hash: 68e5c07a6b1769420c2125677f3eda9bd4841c938b4fc62583c5bed2a2596250
source_path: cli/setup.md
workflow: 15
---
@ -28,6 +28,7 @@ x-i18n:
openclaw setup
openclaw setup --workspace ~/.openclaw/workspace
openclaw setup --wizard
openclaw setup --wizard --import-from hermes --import-source ~/.hermes
openclaw setup --non-interactive --mode remote --remote-url wss://gateway-host:18789 --remote-token <token>
```
@ -35,12 +36,15 @@ openclaw setup --non-interactive --mode remote --remote-url wss://gateway-host:1
- `--workspace <dir>`:智能体工作区目录(存储为 `agents.defaults.workspace`
- `--wizard`:运行新手引导
- `--non-interactive`:无提示运行新手引导
- `--non-interactive`无提示的情况下运行新手引导
- `--mode <local|remote>`:新手引导模式
- `--import-from <provider>`:在新手引导期间运行的迁移提供商
- `--import-source <path>`:用于 `--import-from` 的源智能体主目录
- `--import-secrets`:在新手引导迁移期间导入受支持的密钥
- `--remote-url <url>`:远程 Gateway 网关 WebSocket URL
- `--remote-token <token>`:远程 Gateway 网关令牌
通过 setup 运行新手引导:
通过 setup 运行新手引导:
```bash
openclaw setup --wizard
@ -49,9 +53,10 @@ openclaw setup --wizard
说明:
- 普通的 `openclaw setup` 会初始化配置 + 工作区,而不会运行完整的新手引导流程。
- 当存在任一新手引导标志时,会自动运行新手引导(`--wizard`、`--non-interactive`、`--mode`、`--remote-url`、`--remote-token`)。
- 当存在任一新手引导标志时,会自动运行新手引导(`--wizard`、`--non-interactive`、`--mode`、`--import-from`、`--import-source`、`--import-secrets`、`--remote-url`、`--remote-token`)。
- 如果检测到 Hermes 状态,交互式新手引导可以自动提供迁移选项。导入新手引导需要全新的设置;如需在新手引导之外使用试运行计划、备份和覆盖模式,请使用 [迁移](/zh-CN/cli/migrate)。
## 相关内容
## 相关
- [CLI 参考](/zh-CN/cli)
- [安装概览](/zh-CN/install)

View File

@ -1,26 +1,26 @@
---
read_when:
- 你希望从自己的 GPU 主机提供模型服务
- 你正在连接 LM Studio 或兼容 OpenAI 的代理
- 你想从你自己的 GPU 机器提供模型服务
- 你正在配置 LM Studio 或兼容 OpenAI 的代理
- 你需要最安全的本地模型使用指南
summary: 在本地 LLM 上运行 OpenClawLM Studio、vLLM、LiteLLM、自定义 OpenAI 端点)
title: 本地模型
x-i18n:
generated_at: "2026-04-27T06:04:15Z"
generated_at: "2026-04-27T08:00:04Z"
model: gpt-5.4
provider: openai
source_hash: 1fe9f5f7e3fc4f5660769fddef1f524b303d309f77551880cd74f3395286816c
source_hash: 4a42076e542448018eaf8633c18dfd290c822be502d78a135d03d138e9713668
source_path: gateway/local-models.md
workflow: 15
---
本地部署是可行的,但 OpenClaw 需要大上下文窗口以及针对提示注入的强防护。小显存显卡会截断上下文并削弱安全性。目标应尽量高:**至少 2 台满配 Mac Studio 或同等 GPU 主机(约 3 万美元以上)**。单张 **24 GB** GPU 仅适用于较轻的提示,且延迟更高。请使用你能运行的**最大 / 完整尺寸模型变体**;激进量化或“小型”检查点会提高提示注入风险(参见[安全](/zh-CN/gateway/security))。
本地部署是可行的,但 OpenClaw 需要大上下文窗口,并且要对提示注入有较强防御。小显卡会截断上下文,并削弱安全性。尽量提高配置:**至少 2 台满配 Mac Studio 或同等级 GPU 设备(约 3 万美元以上)**。单张 **24 GB** GPU 仅适用于较轻的提示,且延迟更高。请使用**你能运行的最大 / 完整尺寸模型变体**;激进量化或“small”检查点会提高提示注入风险参见 [Security](/zh-CN/gateway/security))。
如果你想要最低摩擦的本地设置,请从 [LM Studio](/zh-CN/providers/lmstudio) 或 [Ollama](/zh-CN/providers/ollama) 和 `openclaw onboard` 开始。本页是面向更高端本地堆栈和自定义 OpenAI 兼容本地服务器的建议性指南。
如果你想要摩擦最小的本地部署方式,先从 [LM Studio](/zh-CN/providers/lmstudio) 或 [Ollama](/zh-CN/providers/ollama) 和 `openclaw onboard` 开始。本页是面向更高端本地方案和自定义兼容 OpenAI 的本地服务器的带有明确倾向性的指南。
## 推荐LM Studio + 大型本地模型Responses API
当前最佳的本地堆栈。将大型模型加载到 LM Studio 中(例如完整尺寸的 Qwen、DeepSeek 或 Llama 构建),启用本地服务器(默认 `http://127.0.0.1:1234`),并使用 Responses API 将推理与最终文本分离。
这是当前最佳的本地方案。在 LM Studio 中加载一个大型模型(例如完整尺寸的 Qwen、DeepSeek 或 Llama 构建),启用本地服务器(默认 `http://127.0.0.1:1234`),并使用 Responses API 将推理过程与最终文本分离。
```json5
{
@ -60,15 +60,15 @@ x-i18n:
**设置检查清单**
- 安装 LM Studio[https://lmstudio.ai](https://lmstudio.ai)
- 在 LM Studio 中,下载**可用的最大模型构建**(避免 “small” / 重度量化变体),启动服务器,并确认 `http://127.0.0.1:1234/v1/models` 列出该模型。
- 在 LM Studio 中,下载**可用的最大模型构建**(避免使用 “small”/重度量化变体),启动服务器,并确认 `http://127.0.0.1:1234/v1/models` 列出该模型。
- 将 `my-local-model` 替换为 LM Studio 中显示的实际模型 ID。
- 保持模型已加载;冷加载会增加启动延迟。
- 如果你的 LM Studio 构建不同,请调整 `contextWindow` / `maxTokens`
- 保持模型处于已加载状态;冷加载会增加启动延迟。
- 如果你的 LM Studio 构建不同,请调整 `contextWindow`/`maxTokens`。
- 对于 WhatsApp请坚持使用 Responses API这样只会发送最终文本。
即使在本地运行,也请保留托管模型配置;使用 `models.mode: "merge"`,这样回退模型仍然可用。
即使在本地运行,也请保留已配置的托管模型;使用 `models.mode: "merge"` 以便回退模型仍然可用。
### 混合配置:托管模型,本地回退
### 混合配置:托管模型为主,本地模型为回退
```json5
{
@ -109,18 +109,18 @@ x-i18n:
}
```
### 本地优先,托管安全兜底
### 本地优先,并保留托管安全兜底
交换主模型和回退模型的顺序;保留相同的 provider 块和 `models.mode: "merge"`,这样当本地主机宕机时,你仍可回退到 Sonnet 或 Opus。
交换主模型与回退模型的顺序;保留相同的 provider 配置块和 `models.mode: "merge"`,这样当本地设备宕机时,你仍可回退到 Sonnet 或 Opus。
### 区域托管 / 数据路由
- 托管的 MiniMax / Kimi / GLM 变体也存在于 OpenRouter 上,并提供区域固定端点(例如美国托管)。在那里选择对应区域变体,即可将流量保留在你选择的司法辖区内,同时仍使用 `models.mode: "merge"` 为 Anthropic / OpenAI 回退保留能力
- 纯本地仍然是最强的隐私路径;当你需要 provider 功能但又希望控制数据流向时,托管区域路由是中间方案。
- 托管的 MiniMax/Kimi/GLM 变体在 OpenRouter 上也可用,并提供区域固定端点(例如托管于美国)。你可以在那里选择区域变体,以便在所选司法辖区内保留流量,同时仍然使用 `models.mode: "merge"` 为 Anthropic/OpenAI 回退保留支持
- 纯本地仍然是隐私性最强的路径;当你需要提供商功能但又希望控制数据流向时,托管的区域路由是折中方案。
## 其他 OpenAI 兼容本地代理
## 其他兼容 OpenAI 的本地代理
如果 vLLM、LiteLLM、OAI-proxy 或自定义 Gateway 网关暴露的是 OpenAI 风格的 `/v1` 端点,它们就可以工作。将上面的 provider 块替换为你的端点和模型 ID
vLLM、LiteLLM、OAI-proxy 或自定义 Gateway 网关 只要暴露出兼容 OpenAI 风格的 `/v1` 端点即可使用。将上面的 provider 配置块替换为你的端点和模型 ID
```json5
{
@ -149,55 +149,36 @@ x-i18n:
}
```
保留 `models.mode: "merge"`,这样托管模型仍可作为回退使用。
对于较慢的本地或远程模型
服务器,请先使用 `models.providers.<id>.timeoutSeconds`,再考虑提高 `agents.defaults.timeoutSeconds`。provider 超时
仅适用于模型 HTTP 请求,包括连接、响应头、正文流式传输
以及整个受保护 fetch 的中止。
请保留 `models.mode: "merge"`,这样托管模型仍可作为回退使用。
对于较慢的本地或远程模型服务器,请使用 `models.providers.<id>.timeoutSeconds`,再考虑提高 `agents.defaults.timeoutSeconds`。provider 超时仅适用于模型 HTTP 请求,包括连接、响应头、正文流式传输,以及整个受保护抓取的中止超时。
关于本地 / 代理 `/v1` 后端的行为说明:
- OpenClaw 会将这些视为代理风格的 OpenAI 兼容路由,而不是原生
OpenAI 端点
- 原生 OpenAI 专用的请求整形不会在这里生效:没有
`service_tier`、没有 Responses `store`、没有 OpenAI 推理兼容负载
整形,也没有提示缓存提示
- 隐藏的 OpenClaw 归因请求头(`originator`、`version`、`User-Agent`
不会注入到这些自定义代理 URL 中
- OpenClaw 会将这些视为代理风格的兼容 OpenAI 路由,而不是原生 OpenAI 端点
- 仅适用于原生 OpenAI 的请求整形不会在这里生效:没有 `service_tier`,没有 Responses `store`,没有 OpenAI 推理兼容负载整形,也没有提示缓存提示
- 隐藏的 OpenClaw 归因请求头(`originator`、`version`、`User-Agent`)不会注入到这些自定义代理 URL 中
针对更严格的 OpenAI 兼容后端的兼容性说明:
针对更严格的兼容 OpenAI 后端的兼容性说明:
- 某些服务器在 Chat Completions 中只接受字符串形式的 `messages[].content`,而不接受
结构化内容分片数组。对于这些端点,请设置
`models.providers.<provider>.models[].compat.requiresStringContent: true`
- 某些较小或更严格的本地后端在面对 OpenClaw 完整的
agent 运行时提示形态时不稳定,尤其是在包含工具 schema 时。如果后端
对极小的直接 `/v1/chat/completions` 调用可用,但在正常的
OpenClaw 智能体轮次中失败,请先尝试
`agents.defaults.experimental.localModelLean: true`,以移除重量级的
默认工具,如 `browser`、`cron` 和 `message`;这是一个实验性
标志,不是稳定的默认模式设置。参见
[Experimental Features](/zh-CN/concepts/experimental-features)。如果这样仍然失败,再尝试
`models.providers.<provider>.models[].compat.supportsTools: false`
- 如果后端仍然只在更大的 OpenClaw 运行中失败,那么剩余问题
通常是上游模型 / 服务器容量不足或后端 bug而不是 OpenClaw 的
传输层问题。
- 某些服务器在 Chat Completions 中只接受字符串形式的 `messages[].content`,不接受结构化的内容片段数组。对于这些端点,请设置 `models.providers.<provider>.models[].compat.requiresStringContent: true`
- 某些本地模型会以文本形式输出独立的方括号工具请求,例如 `[tool_name]`,后跟 JSON再跟 `[END_TOOL_REQUEST]`。只有当该名称与当前轮次已注册工具完全匹配时OpenClaw 才会将其提升为真实工具调用;否则该块会被视为不受支持的文本,并从面向用户的回复中隐藏。
- 某些较小或更严格的本地后端在面对 OpenClaw 完整的智能体运行时提示结构时不稳定,尤其是在包含工具 schema 时。如果该后端可以处理极小的直接 `/v1/chat/completions` 调用,但在正常的 OpenClaw 智能体轮次中失败,请先尝试设置 `agents.defaults.experimental.localModelLean: true`,以移除像 `browser`、`cron` 和 `message` 这类重量级默认工具;这是一个实验性标志,不是稳定的默认模式设置。参见 [Experimental Features](/zh-CN/concepts/experimental-features)。如果这样仍然失败,再尝试 `models.providers.<provider>.models[].compat.supportsTools: false`
- 如果后端仅在较大的 OpenClaw 运行中仍然失败,剩余问题通常是上游模型/服务器容量限制或后端 bug而不是 OpenClaw 的传输层问题。
## 故障排除
- Gateway 网关能访问代理吗?`curl http://127.0.0.1:1234/v1/models`。
- LM Studio 模型未加载?重新加载;冷启动是常见的“卡住”原因。
- 当检测到的上下文窗口低于 **32k**OpenClaw 会发出警告;低于 **16k** 时会阻止运行。如果你遇到这个预检,请提高服务器 / 模型的上下文限制,或选择更大的模型。
- 上下文错误?降低 `contextWindow` 或提高你的服务器限制。
- OpenAI 兼容服务器返回 `messages[].content ... expected a string`
在该模型条目上添加 `compat.requiresStringContent: true`
- 直接的小型 `/v1/chat/completions` 调用可用,但 `openclaw infer model run`
在 Gemma 或其他本地模型上失败?先通过
`compat.supportsTools: false` 禁用工具 schema然后重新测试。如果服务器
仍然只在更大的 OpenClaw 提示上崩溃,请将其视为上游服务器 / 模型限制。
- 安全性:本地模型会跳过 provider 侧过滤;请保持智能体范围收窄,并启用 compact以限制提示注入的影响范围。
- Gateway 网关 能连到代理吗?`curl http://127.0.0.1:1234/v1/models`
- LM Studio 模型已卸载?重新加载;冷启动是常见的“卡住”原因。
- 当检测到的上下文窗口低于 **32k**OpenClaw 会发出警告;低于 **16k** 时会阻止运行。如果你遇到这个预检,请提高服务器/模型的上下文限制,或选择更大的模型。
- 出现上下文错误?降低 `contextWindow` 或提高你的服务器限制。
- 兼容 OpenAI 的服务器返回 `messages[].content ... expected a string`
在该模型条目中添加 `compat.requiresStringContent: true`
- 直接的小型 `/v1/chat/completions` 调用可以工作,但 `openclaw infer model run`
在 Gemma 或其他本地模型上失败?先用
`compat.supportsTools: false` 禁用工具 schema然后重新测试。如果服务器仍然只在更大的 OpenClaw 提示下崩溃,请将其视为上游服务器/模型限制。
- 安全性:本地模型会跳过提供商侧过滤;请让智能体范围保持狭窄,并开启压缩,以限制提示注入的影响半径。
## 相关内容
- [配置参考](/zh-CN/gateway/configuration-reference)
- [模型故障转移](/zh-CN/concepts/model-failover)
- [Configuration reference](/zh-CN/gateway/configuration-reference)
- [Model failover](/zh-CN/concepts/model-failover)

View File

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

View File

@ -1,34 +1,34 @@
---
read_when:
- 你想使用容器化的 Gateway 网关,而不是本地安装
- 你想要一个容器化的 Gateway 网关,而不是本地安装版本
- 你正在验证 Docker 流程
summary: OpenClaw 的可选 Docker 安装与新手引导
summary: OpenClaw 的基于 Docker 的可选设置和新手引导
title: Docker
x-i18n:
generated_at: "2026-04-27T07:11:35Z"
generated_at: "2026-04-27T08:00:10Z"
model: gpt-5.4
provider: openai
source_hash: 56766c90b2751d186b0e9a7b55241fb45f05a37c2e8d7c0d0155b41eefc2177a
source_hash: 434d11db92060c20902db626f48e79077d24446450dd186af820c0a08a773c47
source_path: install/docker.md
workflow: 15
---
Docker **是可选的**仅当你想使用容器化的 Gateway 网关,或验证 Docker 流程时才使用它。
Docker **是可选的**只有当你想要一个容器化的 Gateway 网关,或想验证 Docker 流程时,才使用它。
## Docker 适合我吗?
- **是**:你想要一个隔离的、可随时丢弃的 Gateway 网关环境,或者想在没有本地安装的主机上运行 OpenClaw。
- **否**:你是在自己的机器上运行,只想获得最快的开发循环。请改用常规安装流程。
- **沙箱注意事项**:启用沙箱隔离时,默认的沙箱后端会使用 Docker但沙箱隔离默认是关闭的,并且**不**要求整个 Gateway 网关都运行在 Docker 中。也可使用 SSH 和 OpenShell 沙箱后端。参见 [沙箱隔离](/zh-CN/gateway/sandboxing)。
- **是**:你想要一个隔离的、可随时丢弃的 Gateway 网关环境,或者想在一台不进行本地安装的主机上运行 OpenClaw。
- **否**:你是在自己的机器上运行,并且只想要最快的开发循环。请改用常规安装流程。
- **沙箱注意事项**:启用沙箱隔离时,默认的沙箱后端会使用 Docker默认情况下沙箱隔离是关闭的,并且**不**要求整个 Gateway 网关都在 Docker 中运行。也可使用 SSH 和 OpenShell 沙箱后端。参见 [沙箱隔离](/zh-CN/gateway/sandboxing)。
## 前条件
## 前条件
- Docker Desktop或 Docker Engine+ Docker Compose v2
- 至少 2 GB 内存用于构建镜像(在 1 GB 主机上,`pnpm install` 可能因 OOM 被杀死并以 137 退出
- 足够的磁盘空间用于镜像和日志
- 镜像构建至少需要 2 GB 内存(在 1 GB 主机上,`pnpm install` 可能会因 OOM 被终止,并以退出码 137 结束
- 足够的磁盘空间用于存储镜像和日志
- 如果在 VPS/公网主机上运行,请查看
[网络暴露的安全加固](/zh-CN/gateway/security)
尤其是 Docker `DOCKER-USER` 防火墙策略。
特别是 Docker `DOCKER-USER` 防火墙策略。
## 容器化 Gateway 网关
@ -40,7 +40,7 @@ Docker **是可选的**。仅当你想使用容器化的 Gateway 网关,或验
./scripts/docker/setup.sh
```
这会在本地构建 Gateway 网关镜像。若要改用预构建镜像,请使用
这会在本地构建 Gateway 网关镜像。若要改用预构建镜像,请执行
```bash
export OPENCLAW_IMAGE="ghcr.io/openclaw/openclaw:latest"
@ -57,17 +57,18 @@ Docker **是可选的**。仅当你想使用容器化的 Gateway 网关,或验
设置脚本会自动运行新手引导。它将会:
- 提示你输入提供商 API 密钥
- 生成一个 Gateway 网关令牌并写入 `.env`
- 生成一个 Gateway 网关令牌并将其写入 `.env`
- 通过 Docker Compose 启动 Gateway 网关
在设置过程中,启动前的新手引导和配置写入会直接通过
`openclaw-gateway` 完成。`openclaw-cli` 用于在
Gateway 网关容器已经存在之后再行的命令。
`openclaw-gateway` 执行。`openclaw-cli` 用于在
Gateway 网关容器已经存在之后再行的命令。
</Step>
<Step title="打开控制 UI">
在浏览器中打开 `http://127.0.0.1:18789/`,然后将已配置的共享密钥粘贴到设置中。设置脚本默认会将令牌写入 `.env`;如果你把容器配置切换为密码认证,请改用该密码。
在浏览器中打开 `http://127.0.0.1:18789/`,然后将已配置的
共享密钥粘贴到 Settings 中。设置脚本默认会把令牌写入 `.env`;如果你把容器配置切换为密码认证,请改用该密码。
需要再次获取 URL 吗?
@ -91,14 +92,14 @@ Docker **是可选的**。仅当你想使用容器化的 Gateway 网关,或验
docker compose run --rm openclaw-cli channels add --channel discord --token "<token>"
```
文档: [WhatsApp](/zh-CN/channels/whatsapp)、[Telegram](/zh-CN/channels/telegram)、[Discord](/zh-CN/channels/discord)
文档:[WhatsApp](/zh-CN/channels/whatsapp)、[Telegram](/zh-CN/channels/telegram)、[Discord](/zh-CN/channels/discord)
</Step>
</Steps>
### 手动流程
如果你更喜欢自己逐步执行每一步,而不是使用设置脚本:
如果你更喜欢自己逐步执行,而不是使用设置脚本:
```bash
docker build -t openclaw:local -f Dockerfile .
@ -116,41 +117,43 @@ docker compose up -d openclaw-gateway
</Note>
<Note>
由于 `openclaw-cli``openclaw-gateway` 共享网络命名空间,它是一个启动后的工具。在 `docker compose up -d openclaw-gateway` 之前,请通过带有
`--no-deps --entrypoint node``openclaw-gateway` 运行新手引导和设置期间的配置写入。
由于 `openclaw-cli``openclaw-gateway` 共享网络命名空间,因此它是一个
启动后的工具。在执行 `docker compose up -d openclaw-gateway` 之前,请通过
`openclaw-gateway` 配合 `--no-deps --entrypoint node`
来运行新手引导和设置期间的配置写入。
</Note>
### 环境变量
设置脚本支持以下可选环境变量:
设置脚本接受以下可选环境变量:
| Variable | Purpose |
| 变量 | 用途 |
| ------------------------------------------ | --------------------------------------------------------------- |
| `OPENCLAW_IMAGE` | 使用远程镜像而不是在本地构建 |
| `OPENCLAW_DOCKER_APT_PACKAGES` | 在构建期间安装额外的 apt 软件包(以空格分隔) |
| `OPENCLAW_EXTENSIONS` | 在构建时预安装插件依赖(以空格分隔名称) |
| `OPENCLAW_EXTRA_MOUNTS` | 额外的主机绑定挂载(以逗号分隔的 `source:target[:opts]` |
| `OPENCLAW_HOME_VOLUME` | 在具名 Docker 卷中持久化 `/home/node` |
| `OPENCLAW_SANDBOX` | 选择启用沙箱引导(`1`、`true`、`yes`、`on` |
| `OPENCLAW_DOCKER_SOCKET` | 覆盖 Docker socket 路径 |
| `OPENCLAW_DISABLE_BONJOUR` | 禁用 Bonjour/mDNS 广播Docker 默认值为 `1` |
| `OPENCLAW_IMAGE` | 使用远程镜像而不是在本地构建 |
| `OPENCLAW_DOCKER_APT_PACKAGES` | 在构建期间安装额外的 apt 软件包(以空格分隔) |
| `OPENCLAW_EXTENSIONS` | 在构建时预安装插件依赖(以空格分隔名称) |
| `OPENCLAW_EXTRA_MOUNTS` | 额外的主机绑定挂载(以逗号分隔的 `source:target[:opts]` |
| `OPENCLAW_HOME_VOLUME` | 将 `/home/node` 持久化到一个命名的 Docker 卷 |
| `OPENCLAW_SANDBOX` | 选择启用沙箱引导初始化`1`、`true`、`yes`、`on` |
| `OPENCLAW_DOCKER_SOCKET` | 覆盖 Docker socket 路径 |
| `OPENCLAW_DISABLE_BONJOUR` | 禁用 Bonjour/mDNS 广播Docker 默认值为 `1` |
| `OPENCLAW_DISABLE_BUNDLED_SOURCE_OVERLAYS` | 禁用内置插件源码绑定挂载覆盖 |
| `OTEL_EXPORTER_OTLP_ENDPOINT` | 用于 OpenTelemetry 导出的共享 OTLP/HTTP 收集器端点 |
| `OTEL_EXPORTER_OTLP_*_ENDPOINT` | 用于 traces、metrics 或 logs 的各信号专用 OTLP 端点 |
| `OTEL_EXPORTER_OTLP_PROTOCOL` | OTLP 协议覆盖。当前仅支持 `http/protobuf` |
| `OTEL_SERVICE_NAME` | 用于 OpenTelemetry 资源的服务名称 |
| `OTEL_SEMCONV_STABILITY_OPT_IN` | 选择启用最新的实验性 GenAI 语义属性 |
| `OPENCLAW_OTEL_PRELOADED` | 当已预加载一个 OpenTelemetry SDK 时,跳过启动第二个 |
| `OTEL_EXPORTER_OTLP_ENDPOINT` | 用于 OpenTelemetry 导出的共享 OTLP/HTTP 收集器端点 |
| `OTEL_EXPORTER_OTLP_*_ENDPOINT` | 用于 traces、metrics 或 logs 的按信号划分的 OTLP 端点 |
| `OTEL_EXPORTER_OTLP_PROTOCOL` | OTLP 协议覆盖。目前仅支持 `http/protobuf` |
| `OTEL_SERVICE_NAME` | 用于 OpenTelemetry 资源的服务名称 |
| `OTEL_SEMCONV_STABILITY_OPT_IN` | 选择启用最新的实验性 GenAI 语义属性 |
| `OPENCLAW_OTEL_PRELOADED` | 当已有预加载实例时,跳过启动第二个 OpenTelemetry SDK |
维护者可以通过把某个插件源码目录挂载到其打包后的源码路径之上,来针对打包镜像测试内置插件源码,例如
维护者可以通过将某个插件源码目录挂载到其打包后的源码路径之上,在打包镜像中测试内置插件源码,例如
`OPENCLAW_EXTRA_MOUNTS=/path/to/fork/extensions/synology-chat:/app/extensions/synology-chat:ro`
挂载的源码目录会覆盖同插件 id 对应的已编译
`/app/dist/extensions/synology-chat`
该挂载的源码目录会覆盖同插件 id 对应的已编译
`/app/dist/extensions/synology-chat` bundle
### 可观测性
OpenTelemetry 导出是从 Gateway 网关容器向你的 OTLP
collector 发起的出站连接。它不需要发布 Docker 端口。如果你在本地构建镜像,并希望镜像中包含可用的内置 OpenTelemetry exporter,请加入其运行时依赖:
收集器发起的出站连接。它不需要发布 Docker 端口。如果你在本地构建镜像,并希望镜像中包含可用的内置 OpenTelemetry 导出器,请加入其运行时依赖:
```bash
export OPENCLAW_EXTENSIONS="diagnostics-otel"
@ -160,24 +163,27 @@ export OTEL_SERVICE_NAME="openclaw-gateway"
```
官方 OpenClaw Docker 发布镜像包含内置的
`diagnostics-otel` 插件源码。根据镜像和缓存状态Gateway 网关在首次启用该插件时,可能仍需暂存插件本地的 OpenTelemetry 运行时依赖,因此请确保首次启动时可以访问软件包注册表,或在你的发布流程中预热镜像。要启用导出,请在配置中允许并启用 `diagnostics-otel` 插件,然后设置
`diagnostics-otel` 插件源码。根据镜像和缓存状态的不同,
在首次启用该插件时Gateway 网关仍可能需要暂存插件本地的 OpenTelemetry 运行时依赖,因此请确保首次启动时能够访问软件包注册表,或在你的发布流程中预热镜像。要启用导出,请先在配置中允许并启用
`diagnostics-otel` 插件,然后设置
`diagnostics.otel.enabled=true`,或使用
[OpenTelemetry 导出](/zh-CN/gateway/opentelemetry) 中的配置示例。collector 认证头通过
[OpenTelemetry 导出](/zh-CN/gateway/opentelemetry) 中的配置示例。收集器认证头通过
`diagnostics.otel.headers` 配置,而不是通过 Docker 环境变量配置。
Prometheus 指标使用已经发布的 Gateway 网关端口。启用
`diagnostics-prometheus` 插件后,抓取:
`diagnostics-prometheus` 插件后,抓取以下地址
```text
http://<gateway-host>:18789/api/diagnostics/prometheus
```
该路由受 Gateway 网关认证保护。不要暴露单独的公共 `/metrics` 端口,也不要暴露未认证的反向代理路径。参见
该路由受 Gateway 网关认证保护。不要暴露单独的公共
`/metrics` 端口,也不要提供未经认证的反向代理路径。参见
[Prometheus 指标](/zh-CN/gateway/prometheus)。
### 健康检查
容器探端点(无需认证):
容器探端点(无需认证):
```bash
curl -fsS http://127.0.0.1:18789/healthz # 存活检查
@ -188,7 +194,7 @@ Docker 镜像内置了一个 `HEALTHCHECK`,会探测 `/healthz`。
如果检查持续失败Docker 会将容器标记为 `unhealthy`
编排系统即可重启或替换它。
需要认证的深度健康状态快照:
需要认证的深度健康快照:
```bash
docker compose exec openclaw-gateway node dist/index.js health --token "$OPENCLAW_GATEWAY_TOKEN"
@ -196,8 +202,8 @@ docker compose exec openclaw-gateway node dist/index.js health --token "$OPENCLA
### LAN 与 loopback
`scripts/docker/setup.sh` 默认设置 `OPENCLAW_GATEWAY_BIND=lan`,因此通过 Docker 端口发布时,主机可以访问
`http://127.0.0.1:18789`
`scripts/docker/setup.sh` 默认`OPENCLAW_GATEWAY_BIND=lan`,以便主机可以通过
Docker 端口发布访问 `http://127.0.0.1:18789`
- `lan`(默认):主机浏览器和主机 CLI 都可以访问已发布的 Gateway 网关端口。
- `loopback`:只有容器网络命名空间内的进程可以直接访问
@ -205,50 +211,76 @@ docker compose exec openclaw-gateway node dist/index.js health --token "$OPENCLA
<Note>
请在 `gateway.bind` 中使用绑定模式值(`lan` / `loopback` / `custom` /
`tailnet` / `auto`),不要使用主机别名,`0.0.0.0``127.0.0.1`
`tailnet` / `auto`),不要使用主机别名,如 `0.0.0.0``127.0.0.1`
</Note>
### 主机本地提供商
当 OpenClaw 在 Docker 中运行时,容器内的 `127.0.0.1` 指向的是容器自身,
而不是你的主机。对于运行在主机上的 AI 提供商,请使用 `host.docker.internal`
| Provider | 主机默认 URL | Docker 设置 URL |
| --------- | ------------------------ | ----------------------------------- |
| LM Studio | `http://127.0.0.1:1234` | `http://host.docker.internal:1234` |
| Ollama | `http://127.0.0.1:11434` | `http://host.docker.internal:11434` |
内置的 Docker 设置会将这些主机 URL 用作 LM Studio 和 Ollama
在新手引导期间的默认值,并且 `docker-compose.yml` 会在 Linux Docker Engine 上将
`host.docker.internal` 映射到 Docker 的 host gateway。Docker Desktop 在 macOS 和 Windows 上已默认提供同名主机名。
主机服务还必须监听一个 Docker 可访问的地址:
```bash
lms server start --port 1234 --bind 0.0.0.0
OLLAMA_HOST=0.0.0.0:11434 ollama serve
```
如果你使用自己的 Compose 文件或 `docker run` 命令,请自行添加相同的主机映射,例如
`--add-host=host.docker.internal:host-gateway`
### Bonjour / mDNS
Docker bridge 网络通常无法可靠地转发 Bonjour/mDNS 多播
`224.0.0.251:5353`)。因此,内置的 Compose 设置默认使用
`OPENCLAW_DISABLE_BONJOUR=1`,以避免 Gateway 网关因桥接网络丢弃多播流量而崩溃循环或反复重启广播。
Docker bridge 网络通常无法可靠地转发 Bonjour/mDNS
`224.0.0.251:5353`)。因此,内置的 Compose 设置默认
`OPENCLAW_DISABLE_BONJOUR=1`这样 Gateway 网关就不会因为 bridge 丢失组播流量而崩溃重启或反复重新启动广播。
对于 Docker 主机,请使用已发布的 Gateway 网关 URL、Tailscale 或广域 DNS-SD。仅当你运行在 host networking、macvlan 或其他已知支持 mDNS 多播的网络中时,才将 `OPENCLAW_DISABLE_BONJOUR=0`
对于 Docker 主机,请使用已发布的 Gateway 网关 URL、Tailscale 或广域 DNS-SD。
只有在使用 host networking、macvlan
或其他已知支持 mDNS 组播的网络时,才将 `OPENCLAW_DISABLE_BONJOUR=0`
有关注意事项和故障排除,请参见 [Bonjour 设备发现](/zh-CN/gateway/bonjour)。
如需了解常见问题和故障排除,请参见 [Bonjour 设备发现](/zh-CN/gateway/bonjour)。
### 存储与持久化
Docker Compose 会将 `OPENCLAW_CONFIG_DIR` 绑定挂载到 `/home/node/.openclaw`,并将
`OPENCLAW_WORKSPACE_DIR` 绑定挂载到 `/home/node/.openclaw/workspace`,因此这些路径在容器被替换后仍会保留。
Docker Compose 会将 `OPENCLAW_CONFIG_DIR` 绑定挂载到 `/home/node/.openclaw`
并将 `OPENCLAW_WORKSPACE_DIR` 绑定挂载到 `/home/node/.openclaw/workspace`,因此这些路径在容器替换后仍会保留。
这个已挂载的配置目录是 OpenClaw 存储以下内容的位置:
挂载的配置目录是 OpenClaw 存储以下内容的位置:
- 用于行为配置的 `openclaw.json`
- 用于已存储提供商 OAuth/API 密钥认证的 `agents/<agentId>/agent/auth-profiles.json`
- 用于基于环境变量的运行时密钥(例如 `OPENCLAW_GATEWAY_TOKEN`)的 `.env`
- 用于存储提供商 OAuth/API-key 认证的 `agents/<agentId>/agent/auth-profiles.json`
- 用于存储基于环境变量的运行时密钥(如 `OPENCLAW_GATEWAY_TOKEN`)的 `.env`
关于 VM 部署中持久化细节的完整说明,请参见
[Docker VM Runtime - What persists where](/zh-CN/install/docker-vm-runtime#what-persists-where)。
如需了解 VM 部署中的完整持久化细节,请参见
[Docker VM Runtime - 持久化内容及其位置](/zh-CN/install/docker-vm-runtime#what-persists-where)。
**磁盘增长热点:** 请关注 `media/`、会话 JSONL 文件、`cron/runs/*.jsonl`
以及 `/tmp/openclaw/` 下的滚动文件日志。
### Shell 助手(可选)
### Shell 辅助工具(可选)
为了更轻松地进行日常 Docker 管理,请安装 `ClawDock`
为了更方便地进行日常 Docker 管理,请安装 `ClawDock`
```bash
mkdir -p ~/.clawdock && curl -sL https://raw.githubusercontent.com/openclaw/openclaw/main/scripts/clawdock/clawdock-helpers.sh -o ~/.clawdock/clawdock-helpers.sh
echo 'source ~/.clawdock/clawdock-helpers.sh' >> ~/.zshrc && source ~/.zshrc
```
如果你之前是通过旧的 `scripts/shell-helpers/clawdock-helpers.sh` 原始路径安装 ClawDock,请重新运行上面的安装命令,以便你的本地 helper 文件跟踪新位置。
如果你是通过旧的原始路径 `scripts/shell-helpers/clawdock-helpers.sh` 安装 ClawDock请重新运行上面的安装命令以便你的本地辅助文件跟踪新位置。
然后你就可以使用 `clawdock-start`、`clawdock-stop`、`clawdock-dashboard` 等命令。
运行 `clawdock-help` 查看全部命令。
完整 helper 指南请参见 [ClawDock](/zh-CN/install/clawdock)。
然后使用 `clawdock-start`、`clawdock-stop`、`clawdock-dashboard` 等命令。运行
`clawdock-help` 可查看所有命令。
完整的辅助工具指南请参见 [ClawDock](/zh-CN/install/clawdock)。
<AccordionGroup>
<Accordion title="为 Docker Gateway 网关启用智能体沙箱">
@ -265,7 +297,8 @@ echo 'source ~/.clawdock/clawdock-helpers.sh' >> ~/.zshrc && source ~/.zshrc
./scripts/docker/setup.sh
```
只有在沙箱前置条件检查通过后,脚本才会挂载 `docker.sock`。如果沙箱设置无法完成,脚本会将 `agents.defaults.sandbox.mode`
该脚本只有在沙箱前提条件通过后才会挂载 `docker.sock`。如果
沙箱设置无法完成,脚本会将 `agents.defaults.sandbox.mode`
重置为 `off`
</Accordion>
@ -281,9 +314,10 @@ echo 'source ~/.clawdock/clawdock-helpers.sh' >> ~/.zshrc && source ~/.zshrc
</Accordion>
<Accordion title="共享网络安全说明">
`openclaw-cli` 使用 `network_mode: "service:openclaw-gateway"`,这样 CLI
命令就可以通过 `127.0.0.1` 访问 Gateway 网关。请将其视为一个共享信任边界。Compose 配置在 `openclaw-cli` 上移除了 `NET_RAW`/`NET_ADMIN`,并启用了
`no-new-privileges`
`openclaw-cli` 使用 `network_mode: "service:openclaw-gateway"`,因此 CLI
命令可以通过 `127.0.0.1` 访问 Gateway 网关。请将此视为一个共享的
信任边界。compose 配置会移除 `NET_RAW`/`NET_ADMIN`,并在
`openclaw-cli` 上启用 `no-new-privileges`
</Accordion>
<Accordion title="权限和 EACCES">
@ -297,8 +331,8 @@ echo 'source ~/.clawdock/clawdock-helpers.sh' >> ~/.zshrc && source ~/.zshrc
</Accordion>
<Accordion title="更快的重建">
请按依赖层可缓存的方式组织你的 Dockerfile。这样可以避免在 lockfile 未变化时重复运行
`pnpm install`
请按依赖层可缓存的方式安排你的 Dockerfile。这可避免在锁文件未变化时
重新运行 `pnpm install`
```dockerfile
FROM node:24-bookworm
@ -331,42 +365,48 @@ echo 'source ~/.clawdock/clawdock-helpers.sh' >> ~/.zshrc && source ~/.zshrc
node /app/node_modules/playwright-core/cli.js install chromium
```
4. **持久化浏览器下载内容**:设置
`PLAYWRIGHT_BROWSERS_PATH=/home/node/.cache/ms-playwright` 并使用
`PLAYWRIGHT_BROWSERS_PATH=/home/node/.cache/ms-playwright`并使用
`OPENCLAW_HOME_VOLUME``OPENCLAW_EXTRA_MOUNTS`
</Accordion>
<Accordion title="OpenAI Codex OAuth无头 Docker">
如果你在向导中选择 OpenAI Codex OAuth它会打开一个浏览器 URL。在
Docker 或无头环境中,请复制你最终跳转到的完整重定向 URL并将其粘贴回向导中以完成认证。
Docker 或无头环境中,请复制你最终跳转到的完整重定向 URL并将其粘贴回
向导中以完成认证。
</Accordion>
<Accordion title="基础镜像元数据">
主 Docker 运行时镜像使用 `node:24-bookworm-slim`,并发布 OCI
基础镜像注解,包括 `org.opencontainers.image.base.name`
`org.opencontainers.image.source` 等。Node 基础镜像摘要会通过 Dependabot 的 Docker 基础镜像 PR 刷新;发布构建不会运行发行版升级层。参见
[OCI image annotations](https://github.com/opencontainers/image-spec/blob/main/annotations.md)。
`org.opencontainers.image.source` 等。Node 基础镜像摘要
会通过 Dependabot 的 Docker 基础镜像 PR 刷新;发布构建不会运行
发行版升级层。参见
[OCI 镜像注解](https://github.com/opencontainers/image-spec/blob/main/annotations.md)。
</Accordion>
</AccordionGroup>
### 在 VPS 上运行?
共享 VM 部署步骤(包括二进制预置、持久化和更新)请参见
有关共享 VM 部署步骤,包括二进制预烘焙、持久化和更新,请参见
[HetznerDocker VPS](/zh-CN/install/hetzner) 和
[Docker VM Runtime](/zh-CN/install/docker-vm-runtime)。
## 智能体沙箱
当使用 Docker 后端启用 `agents.defaults.sandbox`Gateway 网关会在隔离的 Docker
容器中运行智能体工具执行shell、文件读写等而 Gateway 网关本身仍保留在主机上运行。这能在不将整个 Gateway 网关容器化的情况下,为不受信任或多租户智能体会话提供一道强隔离边界。
当通过 Docker 后端启用 `agents.defaults.sandbox`Gateway 网关会在隔离的 Docker
容器中运行智能体工具执行shell、文件读写等而 Gateway 网关本身仍运行在主机上。这为不受信任或多租户的智能体会话提供了一道硬隔离边界,而无需将整个
Gateway 网关都容器化。
沙箱作用域可以是每个智能体(默认)、每个会话,或共享。每种作用域都会获得其自己的工作区,并挂载到 `/workspace`。你还可以配置工具允许/拒绝策略、网络隔离、资源限制和浏览器容器。
沙箱范围可以按智能体(默认)、按会话,或共享。每种范围
都会获得自己挂载到 `/workspace` 的工作区。你还可以配置
工具允许/拒绝策略、网络隔离、资源限制以及浏览器容器。
有关完整配置、镜像、安全说明和多智能体配置文件,请参见:
完整配置、镜像、安全说明和多智能体配置文件请参见:
- [沙箱隔离](/zh-CN/gateway/sandboxing) -- 完整的沙箱参考
- [OpenShell](/zh-CN/gateway/openshell) -- 对沙箱容器的交互式 shell 访问
- [Multi-Agent Sandbox and Tools](/zh-CN/tools/multi-agent-sandbox-tools) -- 每个智能体的覆盖配置
- [Multi-Agent Sandbox and Tools](/zh-CN/tools/multi-agent-sandbox-tools) -- 按智能体覆盖
### 快速启用
@ -392,11 +432,11 @@ scripts/sandbox-setup.sh
## 故障排除
<AccordionGroup>
<Accordion title="缺少镜像或沙箱容器无法启动">
<Accordion title="镜像缺失或沙箱容器无法启动">
使用
[`scripts/sandbox-setup.sh`](https://github.com/openclaw/openclaw/blob/main/scripts/sandbox-setup.sh)
构建沙箱镜像,或将 `agents.defaults.sandbox.docker.image` 设置为你的自定义镜像。
容器会按需为每个会话自动创建
容器会在会话按需创建时自动生成
</Accordion>
<Accordion title="沙箱中的权限错误">
@ -404,17 +444,18 @@ scripts/sandbox-setup.sh
或对工作区文件夹执行 chown。
</Accordion>
<Accordion title="在沙箱中找不到自定义工具">
OpenClaw 使用 `sh -lc`(登录 shell运行命令这会加载
`/etc/profile` 并且可能重置 PATH。请设置 `docker.env.PATH` 以预先添加你的自定义工具路径,或在你的 Dockerfile 中向 `/etc/profile.d/` 添加脚本。
<Accordion title="沙箱中找不到自定义工具">
OpenClaw 使用 `sh -lc`(登录 shell运行命令它会加载
`/etc/profile`,并且可能重置 PATH。请设置 `docker.env.PATH` 以预先加入你的
自定义工具路径,或在 Dockerfile 中向 `/etc/profile.d/` 添加脚本。
</Accordion>
<Accordion title="镜像构建期间因 OOM 被杀死(退出码 137">
VM 至少需要 2 GB 内存。请使用更大的机器规格后重试。
<Accordion title="镜像构建期间因 OOM 被终止(退出码 137">
VM 至少需要 2 GB 内存。请使用更大规格的机器后重试。
</Accordion>
<Accordion title="控制 UI 中显示 Unauthorized 或需要配对">
获取新的 dashboard 链接并批准浏览器设备:
<Accordion title="Control UI 中出现 Unauthorized 或需要配对">
获取一个新的仪表盘链接并批准该浏览器设备:
```bash
docker compose run --rm openclaw-cli dashboard --no-open
@ -422,11 +463,11 @@ scripts/sandbox-setup.sh
docker compose run --rm openclaw-cli devices approve <requestId>
```
更多详情 [Dashboard](/zh-CN/web/dashboard)、[Devices](/zh-CN/cli/devices)。
更多细节 [Dashboard](/zh-CN/web/dashboard)、[Devices](/zh-CN/cli/devices)。
</Accordion>
<Accordion title="Gateway 网关目标显示 ws://172.x.x.x 或 Docker CLI 出现配对错误">
<Accordion title="Gateway 网关目标显示为 ws://172.x.x.x或从 Docker CLI 出现配对错误">
重置 Gateway 网关模式和绑定:
```bash

View File

@ -6,24 +6,24 @@ read_when:
- 实现提供商运行时钩子或渠道插件
sidebarTitle: Internals
summary: 插件内部机制:能力模型、归属、契约、加载管线和运行时辅助工具
title: 插件架构内部机制
title: 插件内部机制
x-i18n:
generated_at: "2026-04-26T07:50:09Z"
generated_at: "2026-04-27T08:00:17Z"
model: gpt-5.4
provider: openai
source_hash: 16664d284a8bfbfcb9914bb012d1f36dfdd60406636d6bf4b011f76e886cb518
source_hash: 5b7622b361c6d19069106785f2b80cb3155e58f9a27a2fac9733e976d7c27f13
source_path: plugins/architecture.md
workflow: 15
---
这是 OpenClaw 插件系统的**深度架构参考**。如果你想看实用指南,请先从下面这些聚焦页面之一开始。
这是 OpenClaw 插件系统的**深度架构参考**。如需实用指南,请先从下面其中一个聚焦页面开始。
<CardGroup cols={2}>
<Card title="安装和使用插件" icon="plug" href="/zh-CN/tools/plugin">
面向最终用户的指南,介绍如何添加、启用以及排查插件问题
面向终端用户的指南,介绍如何添加、启用和故障排除插件
</Card>
<Card title="构建插件" icon="rocket" href="/zh-CN/plugins/building-plugins">
第一个插件教程,包含最小可工作的 manifest
使用最小可运行 manifest 的首个插件教程
</Card>
<Card title="渠道插件" icon="comments" href="/zh-CN/plugins/sdk-channel-plugins">
构建一个消息渠道插件。
@ -31,46 +31,46 @@ x-i18n:
<Card title="提供商插件" icon="microchip" href="/zh-CN/plugins/sdk-provider-plugins">
构建一个模型提供商插件。
</Card>
<Card title="插件 SDK 概览" icon="book" href="/zh-CN/plugins/sdk-overview">
导入映射和注册 API 参考。
<Card title="SDK 概览" icon="book" href="/zh-CN/plugins/sdk-overview">
import map 和注册 API 参考。
</Card>
</CardGroup>
## 公能力模型
## 公能力模型
能力是 OpenClaw 内部公的**原生插件**模型。每个原生 OpenClaw 插件都会针对一种或多种能力类型进行注册:
能力是 OpenClaw 内部公的**原生插件**模型。每个原生 OpenClaw 插件都会针对一种或多种能力类型进行注册:
| 能力 | 注册方法 | 示例插件 |
| ---------------------- | ------------------------------------------------ | ------------------------------------ |
| 文本推理 | `api.registerProvider(...)` | `openai`、`anthropic` |
| CLI 推理后端 | `api.registerCliBackend(...)` | `openai`、`anthropic` |
| 语音 | `api.registerSpeechProvider(...)` | `elevenlabs`、`microsoft` |
| 实时转 | `api.registerRealtimeTranscriptionProvider(...)` | `openai` |
| 文本推理 | `api.registerProvider(...)` | `openai`, `anthropic` |
| CLI 推理后端 | `api.registerCliBackend(...)` | `openai`, `anthropic` |
| 语音 | `api.registerSpeechProvider(...)` | `elevenlabs`, `microsoft` |
| 实时转 | `api.registerRealtimeTranscriptionProvider(...)` | `openai` |
| 实时语音 | `api.registerRealtimeVoiceProvider(...)` | `openai` |
| 媒体理解 | `api.registerMediaUnderstandingProvider(...)` | `openai`、`google` |
| 图像生成 | `api.registerImageGenerationProvider(...)` | `openai`、`google`、`fal`、`minimax` |
| 音乐生成 | `api.registerMusicGenerationProvider(...)` | `google`、`minimax` |
| 媒体理解 | `api.registerMediaUnderstandingProvider(...)` | `openai`, `google` |
| 图像生成 | `api.registerImageGenerationProvider(...)` | `openai`, `google`, `fal`, `minimax` |
| 音乐生成 | `api.registerMusicGenerationProvider(...)` | `google`, `minimax` |
| 视频生成 | `api.registerVideoGenerationProvider(...)` | `qwen` |
| Web 抓取 | `api.registerWebFetchProvider(...)` | `firecrawl` |
| Web 搜索 | `api.registerWebSearchProvider(...)` | `google` |
| 渠道 / 消息传递 | `api.registerChannel(...)` | `msteams`、`matrix` |
| 渠道 / 消息 | `api.registerChannel(...)` | `msteams`, `matrix` |
| Gateway 网关发现 | `api.registerGatewayDiscoveryService(...)` | `bonjour` |
<Note>
一个注册了零能力、但提供钩子、工具、发现服务或后台服务的插件,属于**旧式纯钩子**插件。该模式目前仍然被完全支持。
一个注册了零能力、但提供钩子、工具、发现服务或后台服务的插件,属于**旧版仅钩子**插件。这种模式仍然得到完整支持。
</Note>
### 外部兼容性立场
能力模型已经落地到核心中,并已被今天的内置 / 原生插件使用,但外部插件兼容性仍然需要比“它已导出,因此它已冻结”更严格的标准。
能力模型已经在核心中落地,并已被当前内置/原生插件使用,但外部插件兼容性仍需要比“它已导出,因此它已冻结”更严格的标准。
| 插件情况 | 指导原则 |
| 插件情况 | 指导建议 |
| ------------------------------------------------- | ------------------------------------------------------------------------------------------------ |
| 现有外部插件 | 保持基于钩子的集成可用;这是兼容性的基线。 |
| 新的内置 / 原生插件 | 优先使用显式能力注册,而不是针对特定厂商的深入调用或新的纯钩子设计。 |
| 采用能力注册的外部插件 | 允许,但除非文档将其标记为稳定,否则应将特定能力的辅助表面视为仍在演进中。 |
| 现有外部插件 | 保持基于钩子的集成继续工作;这是兼容性的基线。 |
| 新的内置/原生插件 | 优先选择显式能力注册,而不是特定厂商的深层接入或新的仅钩子设计。 |
| 采用能力注册的外部插件 | 允许,但除非文档将能力专用辅助接口标记为稳定,否则应将其视为仍在演进中。 |
能力注册是预期的发展方向。在过渡期间,旧式钩子仍然是对外部插件最安全、最不易破坏的路径。已导出的辅助子路径并不都同样稳定——应优先使用范围收窄、且有文档说明的契约,而不是偶然暴露出来的辅助导出。
能力注册是预期的发展方向。在过渡期间,对于外部插件,旧版钩子仍然是最安全、最不容易破坏兼容性的路径。导出的辅助子路径并不都具有同等稳定性——请优先使用文档化的窄接口契约,而不是偶然暴露的辅助导出。
### 插件形态
@ -78,32 +78,32 @@ OpenClaw 会根据每个已加载插件的实际注册行为(而不只是静
<AccordionGroup>
<Accordion title="plain-capability">
只注册一种能力类型(例如像 `mistral` 这样的仅提供商插件)。
仅注册一种能力类型(例如仅提供商插件 `mistral`)。
</Accordion>
<Accordion title="hybrid-capability">
注册多种能力类型(例如 `openai` 同时拥有文本推理、语音、媒体理解和图像生成)。
</Accordion>
<Accordion title="hook-only">
注册钩子(类型化或自定义),不注册任何能力、工具、命令或服务。
注册钩子(类型化或自定义),不注册能力、工具、命令或服务。
</Accordion>
<Accordion title="non-capability">
注册工具、命令、服务或路由,但不注册能力。
</Accordion>
</AccordionGroup>
使用 `openclaw plugins inspect <id>`以查看插件的形态和能力拆分。详情请参见 [CLI 参考](/zh-CN/cli/plugins#inspect)。
使用 `openclaw plugins inspect <id>`查看插件的形态和能力明细。详见 [CLI 参考](/zh-CN/cli/plugins#inspect)。
### 旧钩子
### 旧钩子
`before_agent_start` 钩子仍然作为纯钩子插件的兼容路径被支持。现实中的旧插件仍然依赖它。
`before_agent_start` 钩子仍然作为仅钩子插件的兼容路径受到支持。现有真实插件仍然依赖它。
方向如下:
- 保持其可用
- 在文档中标记为旧式
- 涉及模型 / 提供商覆盖工作时,优先使用 `before_model_resolve`
- 涉及提示词变更工作时,优先使用 `before_prompt_build`
- 仅在真实使用下降,且 fixture 覆盖证明迁移安全之后,才移除
- 在文档中将其标记为旧版
- 对于模型/提供商覆盖工作,优先使用 `before_model_resolve`
- 对于提示词变更工作,优先使用 `before_prompt_build`
- 仅在真实使用量下降且夹具覆盖证明迁移安全后再移除
### 兼容性信号
@ -111,76 +111,90 @@ OpenClaw 会根据每个已加载插件的实际注册行为(而不只是静
| 信号 | 含义 |
| -------------------------- | ------------------------------------------------------------ |
| **config valid** | 配置解析正常,插件可解析 |
| **compatibility advisory** | 插件使用了受支持但较旧的模式(例如 `hook-only` |
| **legacy warning** | 插件使用了 `before_agent_start`,该功能已弃用 |
| **hard error** | 配置无效,或插件加载失败 |
| **配置有效** | 配置解析正常,且插件解析成功 |
| **兼容性提示** | 插件使用受支持但较旧的模式(例如 `hook-only` |
| **旧版警告** | 插件使用 `before_agent_start`,该机制已弃用 |
| **硬错误** | 配置无效或插件加载失败 |
如今,`hook-only` 和 `before_agent_start` 都不会破坏你的插件`hook-only` 只是提示信息,而 `before_agent_start` 只会触发警告。这些信号也会出现`openclaw status --all``openclaw plugins doctor` 中。
`hook-only``before_agent_start` 目前都不会导致你的插件失效`hook-only` 只是提示信息,而 `before_agent_start` 只会触发警告。这些信号也会显示`openclaw status --all``openclaw plugins doctor` 中。
## 架构概览
OpenClaw 的插件系统四层:
OpenClaw 的插件系统分为四层:
<Steps>
<Step title="Manifest + 设备发现">
OpenClaw 会从已配置路径、工作区根目录、全局插件根目录以及内置插件中查找候选插件。设备发现会先读取原生 `openclaw.plugin.json` manifest 以及受支持 bundle manifest。
OpenClaw 会从已配置路径、工作区根目录、全局插件根目录以及内置插件中查找候选插件。设备发现会先读取原生 `openclaw.plugin.json` manifest 以及受支持 bundle manifest。
</Step>
<Step title="启用 + 验证">
核心决定某个已发现插件是启用、禁用、阻止,还是被选中用于某个独占插槽,例如 memory
核心决定已发现的插件是启用、禁用、阻止,还是被选入某个独占槽位(例如 memory
</Step>
<Step title="运行时加载">
原生 OpenClaw 插件通过 jiti 在进程内加载,并将能力注册到中央注册表中。兼容的 bundle 会被标准化为注册表记录,而无需导入运行时代码。
原生 OpenClaw 插件通过 jiti 在进程内加载,并将能力注册到中央注册表中。兼容 bundle 会被规范化为注册表记录,而无需导入运行时代码。
</Step>
<Step title="表面消费">
OpenClaw 的其余部分会读取注册表以暴露工具、渠道、提供商设置、钩子、HTTP 路由、CLI 命令和服务。
</Step>
</Steps>
就插件 CLI 而言,根命令发现分为两个阶段:
具体到插件 CLI,根命令发现分为两个阶段:
- 解析时元数据来自 `registerCli(..., { descriptors: [...] })`
- 真正的插件 CLI 模块可以保持懒加载,并在第一次调用时注册
- 实际的插件 CLI 模块可以保持惰性,并在首次调用时注册
这样既能让插件自有的 CLI 代码保留在插件内部,又能让 OpenClaw 在解析前预留根命令名称。
这样既能将插件拥有的 CLI 代码保留在插件内部,又能让 OpenClaw 在解析前预留根命令名称。
重要的设计边界是:
- manifest / 配置验证应仅根据 **manifest / schema 元数据** 即可完成,而无需执行插件代码
- 原生能力发现可以加载受信任的插件入口代码,以构建一个不激活的注册表快照
- 原生运行时行为来自插件模块的 `register(api)` 路径,并带有 `api.registrationMode === "full"`
- manifest/配置验证应当仅依据**manifest/schema 元数据**完成,而不执行插件代码
- 原生能力发现可以加载受信任的插件入口代码,以构建一个不激活的注册表快照
- 原生运行时行为来自插件模块的 `register(api)` 路径,其中 `api.registrationMode === "full"`
这种拆分让 OpenClaw 能够在完整运行时尚未激活前,验证配置、解释缺失 / 禁用的插件,并构建 UI / schema 提示。
这种拆分让 OpenClaw 能在完整运行时尚未激活前,就验证配置、解释缺失/禁用的插件,并构建 UI/schema 提示。
### 插件查找表
Gateway 网关启动时,会基于当前配置快照中的已安装插件索引和 manifest 注册表构建一个 `PluginLookUpTable`。该表仅包含元数据:存储插件 id、manifest 记录、诊断信息、所有者映射、插件 id 规范化器以及启动插件计划。它不持有已加载的插件模块、提供商 SDK、包内容或运行时导出。
查找表使重复启动决策能够走快速路径:
- 渠道归属
- 延迟渠道启动
- 启动插件 id
- 提供商和 CLI 后端归属
- setup provider、命令别名、模型目录提供商以及 manifest 契约归属
安全边界在于快照替换,而不是变更。配置、插件清单、安装记录或持久化索引策略发生变化时,应重新构建该表。不要将其视为一个可广泛变更的全局注册表,也不要保留无限制的历史表。运行时插件加载仍然独立于查找表元数据,因此过期的运行时状态不会被元数据缓存掩盖。
### 激活规划
激活规划是控制平面的一部分。调用方可以在加载更广泛的运行时注册表之前,先询问哪些插件与某个具体命令、提供商、渠道、路由、智能体 harness 或能力相关。
激活规划是控制平面的一部分。调用方可以在加载更广泛的运行时注册表之前,询问哪些插件与具体命令、提供商、渠道、路由、Agent harness 或能力相关。
规划器会保持当前 manifest 行为兼容:
规划器保持当前 manifest 行为兼容:
- `activation.*` 字段是显式的规划器提示
- `providers`、`channels`、`commandAliases`、`setup.providers`、`contracts.tools` 和钩子仍然保留为 manifest 归属回退
- 仅返回 id 的规划器 API 仍然可供现有调用方使用
- plan API 会报告原因标签,以便诊断信息区分显式提示与归属回退
- `activation.*` 字段是显式的规划提示
- `providers`、`channels`、`commandAliases`、`setup.providers`、`contracts.tools` 和钩子仍然是 manifest 归属的回退来源
- 仅返回 id 的规划器 API 仍对现有调用方可
- 计划 API 会报告原因标签,以便诊断能够区分显式提示和归属回退
<Warning>
不要把 `activation` 当作生命周期钩子,或当作 `register(...)` 的替代品。它只是用于缩小加载范围的元数据。当归属字段已经能够描述该关系时,应优先使用归属字段;只有在需要额外规划器提示时才使用 `activation`
不要把 `activation` 当作生命周期钩子`register(...)` 的替代品。它是用于缩小加载范围的元数据。若归属字段已经能描述该关系,请优先使用归属字段;仅在需要额外规划提示时使用 `activation`
</Warning>
### 渠道插件和共享 message 工具
### 渠道插件与共享消息工具
对于普通聊天动作,渠道插件不需要单独注册发送 / 编辑 / 反应工具。OpenClaw 在核心中保留了一个共享的 `message` 工具,而渠道插件负责其背后的渠道特定发现与执行。
对于普通聊天操作,渠道插件无需单独注册发送/编辑/回应工具。OpenClaw 在核心中保留一个共享的 `message` 工具,而渠道插件负责其背后的渠道专属发现与执行。
当前边界如下:
- 核心拥有共享 `message` 工具宿主、提示词接线、会话 / 线程簿记以及执行分发
- 渠道插件拥有带作用域的动作发现、能力发现以及任何渠道特定的 schema 片段
- 渠道插件拥有提供商特定的会话对话语法,例如对话 id 如何编码线程 id或如何从父对话继承
- 渠道插件通过其动作适配器执行最终动
- 核心拥有共享 `message` 工具宿主、提示词接线、会话/线程记以及执行分发
- 渠道插件拥有作用域操作发现、能力发现以及任何渠道专属 schema 片段
- 渠道插件拥有提供商专属的会话对话语法,例如对话 id 如何编码线程 id或如何继承父对话
- 渠道插件通过其 action adapter 执行最终操
对于渠道插件SDK 表面是 `ChannelMessageActionAdapter.describeMessageTool(...)`。这种统一的发现调用让插件可以把可见动作、能力和 schema 贡献一起返回,从而避免这些部分彼此漂移。
对于渠道插件SDK 接口是 `ChannelMessageActionAdapter.describeMessageTool(...)`。该统一发现调用允许插件同时返回其可见操作、能力和 schema 贡献,从而避免这些部分发生漂移。
当某个渠道特定的 message-tool 参数携带媒体源(例如本地路径或远程媒体 URL插件还应从 `describeMessageTool(...)` 返回 `mediaSourceParams`。核心使用这个显式列表来应用沙箱路径规范化以及出站媒体访问提示,而不是对插件自有参数名进行硬编码。这里应优先使用按动作划分的映射,而不是整个渠道范围的扁平列表,这样某个仅用于 profile 的媒体参数就不会在 `send` 这类无关动作上被规范化。
当某个渠道专属消息工具参数携带媒体源(例如本地路径或远程媒体 URL插件还应从 `describeMessageTool(...)` 返回 `mediaSourceParams`。核心使用这个显式列表来应用沙箱路径规范化和出站媒体访问提示,而无需硬编码插件拥有的参数名。这里应优先使用按操作划分的映射,而不是整个渠道共用的扁平列表,这样仅用于 profile 的媒体参数就不会在 `send` 这类无关操作上被规范化。
核心会将运行时作用域传入该发现步骤。重要字段包括:
@ -193,57 +207,57 @@ OpenClaw 的插件系统有四层:
- `agentId`
- 受信任的入站 `requesterSenderId`
这对于依赖上下文的插件很重要。渠道可以根据当前活跃账号、当前房间 / 线程 / 消息,或受信任的请求者身份,隐藏或暴露消息动作,而无需在核心 `message` 工具中硬编码渠道特定分支。
这对上下文敏感型插件很重要。渠道可以根据活动账号、当前房间/线程/消息,或受信任的请求方身份,隐藏或暴露消息操作,而无需在核心 `message` 工具中硬编码渠道专属分支。
这也是为什么嵌入式运行器路由变更仍然属于插件工作:运行器负责将当前聊天 / 会话身份转发到插件发现边界,从而让共享 `message` 工具为当前轮次暴露正确的渠道自有表面。
这也是为什么嵌入式 runner 路由变更仍然属于插件工作runner 负责将当前聊天/会话身份转发到插件发现边界,以便共享的 `message` 工具为当前轮次暴露正确的渠道拥有表面。
对于渠道自有的执行辅助工具,内置插件应将执行运行时保留在各自的扩展模块内部。核心不再拥有位于 `src/agents/tools` 下的 Discord、Slack、Telegram 或 WhatsApp 消息作运行时。我们不会发布单独的 `plugin-sdk/*-action-runtime` 子路径,内置插件应直接从各自扩展自有模块导入本地运行时代码。
对于渠道拥有的执行辅助工具,内置插件应将执行运行时保留在它们自己的扩展模块中。核心不再拥有位于 `src/agents/tools` 下的 Discord、Slack、Telegram 或 WhatsApp 消息作运行时。我们不会发布单独的 `plugin-sdk/*-action-runtime` 子路径,内置插件应直接从扩展自有模块导入本地运行时代码。
同样的边界原则也适用于一般性的、以提供商命名的 SDK 接缝:核心不应导入 Slack、Discord、Signal、WhatsApp 或类似扩展的渠道专用便捷 barrel。如果核心需要某种行为要么使用内置插件自己的 `api.ts` / `runtime-api.ts` barrel要么将该需求提升为共享 SDK 中一个范围收窄的通用能力。
相同的边界通常也适用于带提供商名称的 SDK 接缝:核心不应导入针对 Slack、Discord、Signal、WhatsApp 或类似扩展的渠道专用便捷 barrel。如果核心需要某种行为要么消费内置插件自己的 `api.ts` / `runtime-api.ts` barrel要么将该需求提升为共享 SDK 中一个狭义的通用能力。
对于投票,具体有两条执行路径:
- `outbound.sendPoll` 是适用于符合通用投票模型渠道的共享基线
- `actions.handleAction("poll")` 是处理渠道特定投票语义或额外投票参数的首选路径
- `outbound.sendPoll` 是适用于符合通用投票模型渠道的共享基线
- `actions.handleAction("poll")` 是处理渠道专属投票语义或额外投票参数的首选路径
现在,核心会在插件投票分发拒绝该动作之后,才延后执行共享投票解析,因此插件自有的投票处理器可以接受渠道特定的投票字段,而不会先被通用投票解析器拦住。
现在,核心会在插件投票分发拒绝该操作之后,才延迟执行共享投票解析,因此插件自有的投票处理器可以接受渠道专属投票字段,而不会先被通用投票解析器拦住。
完整启动序请参见 [插件架构内部机制](/zh-CN/plugins/architecture-internals)。
完整启动序请参见 [插件架构内部机制](/zh-CN/plugins/architecture-internals)。
## 能力归属模型
OpenClaw 将一个原生插件视为某个**公司**或某项**功能**的归属边界,而不是一堆彼此无关集成的杂物袋。
OpenClaw 将原生插件视为**公司**或**功能**的归属边界,而不是一堆彼此无关集成的杂物袋。
这意味着:
- 一个公司插件通常应拥有该公司的所有 OpenClaw 对外表面
- 一个功能插件通常应拥有它所引入的完整功能表面
- 渠道应消费共享核心能力,而不是临时性地重复实现提供商行为
- 公司插件通常应拥有该公司的所有 OpenClaw 对外表面
- 功能插件通常应拥有其引入的完整功能表面
- 渠道应消费共享核心能力,而不是临时重复实现提供商行为
<AccordionGroup>
<Accordion title="Vendor multi-capability">
<Accordion title="供应商多能力">
`openai` 拥有文本推理、语音、实时语音、媒体理解和图像生成。`google` 拥有文本推理,以及媒体理解、图像生成和 Web 搜索。`qwen` 拥有文本推理,以及媒体理解和视频生成。
</Accordion>
<Accordion title="Vendor single-capability">
<Accordion title="供应商单能力">
`elevenlabs``microsoft` 拥有语音;`firecrawl` 拥有 Web 抓取;`minimax` / `mistral` / `moonshot` / `zai` 拥有媒体理解后端。
</Accordion>
<Accordion title="Feature plugin">
`voice-call` 拥有呼叫传输、工具、CLI、路由和 Twilio 媒体流桥接,但它会消费共享的语音、实时转写和实时语音能力,而不是直接导入厂商插件。
<Accordion title="功能插件">
`voice-call` 拥有通话传输、工具、CLI、路由和 Twilio 媒体流桥接,但会消费共享的语音、实时转录和实时语音能力,而不是直接导入供应商插件。
</Accordion>
</AccordionGroup>
预期的最终状态是:
- OpenAI 即使横跨文本模型、语音、图像以及未来的视频,也仍然驻留在一个插件中
- 其他厂商也可以对自己的表面区域采取同样做法
- 渠道并不关心是哪一个厂商插件拥有该提供商;它们消费的是核心暴露的共享能力契约
- OpenAI 即使同时涵盖文本模型、语音、图像和未来的视频,也仍位于一个插件中
- 其他供应商也可以为其自身的表面采用同样方式
- 渠道不关心哪个供应商插件拥有该提供商;它们消费的是核心暴露的共享能力契约
里的关键区别是
是关键区别
- **plugin** = 归属边界
- **capability** = 可由多个插件实现或消费的核心契约
因此,如果 OpenClaw 新增了一个像视频这样的领域,第一个问题不应该是“哪个提供商应该硬编码视频处理?”第一个问题应该是“核心的视频能力契约是什么?”一旦这个契约存在,厂商插件就可以针对它注册,而渠道 / 功能插件也可以消费它。
因此,如果 OpenClaw 增加像视频这样的新领域,第一个问题不应是“哪个提供商应该硬编码视频处理?”第一个问题应是“核心视频能力契约是什么?”一旦该契约存在,供应商插件就可以针对它注册,渠道/功能插件也可以消费它。
如果该能力尚不存在,通常正确的做法是:
@ -252,45 +266,45 @@ OpenClaw 将一个原生插件视为某个**公司**或某项**功能**的归属
在核心中定义缺失的能力。
</Step>
<Step title="通过 SDK 暴露">
以类型化方式通过插件 API / 运行时将其暴露出来
通过插件 API/运行时以类型化方式暴露它
</Step>
<Step title="线消费者">
将渠道 / 功能接入该能力。
<Step title="接消费者">
让渠道/功能接入该能力。
</Step>
<Step title="商实现">
厂商插件注册其实现。
<Step title="供应商实现">
供应商插件注册具体实现。
</Step>
</Steps>
这样既能保持归属清晰,又能避免核心行为依赖于单一厂商或某条一次性的插件专用代码路径。
这样既能保持归属明确,又能避免核心行为依赖单一供应商或某个一次性插件专用代码路径。
### 能力分层
当你决定代码应该放在哪里时,请使用这个思维模型:
在判断代码应放在哪里时,可使用以下思维模型:
<Tabs>
<Tab title="核心能力层">
共享的编排、策略、回退、配置合并规则、投递语义和类型化契约。
共享的编排、策略、回退、配置合并规则、交付语义和类型化契约。
</Tab>
<Tab title="商插件层">
厂商特定 API、认证、模型目录、语音合成、图像生成、未来视频后端、用量端点。
<Tab title="供应商插件层">
供应商专属 API、认证、模型目录、语音合成、图像生成、未来视频后端、用量端点。
</Tab>
<Tab title="渠道/功能插件层">
Slack / Discord / voice-call / 等集成,它们消费核心能力并在某个表面上呈现出来
Slack/Discord/voice-call 等集成,它们消费核心能力并将其呈现在某个表面上。
</Tab>
</Tabs>
例如TTS 遵循这种结构
例如TTS 遵循这种形态
- 核心拥有回复时 TTS 策略、回退顺序、偏好设置和渠道投递
- `openai`、`elevenlabs` 和 `microsoft` 拥有语音合成实现
- 核心拥有回复时 TTS 策略、回退顺序、偏好设置和渠道交付
- `openai`、`elevenlabs` 和 `microsoft` 拥有合成实现
- `voice-call` 消费电话 TTS 运行时辅助工具
对于未来能力也应优先采用同样模式。
未来能力也应优先采用同样模式。
### 多能力公司插件示例
从外部看,一个公司插件应当具有一致性。如果 OpenClaw 拥有针对模型、语音、实时转写、实时语音、媒体理解、图像生成、视频生成、Web 抓取和 Web 搜索的共享契约,那么一个厂商就可以在一个地方拥有其所有表面:
从外部看,公司插件应具备一致性。如果 OpenClaw 具有针对模型、语音、实时转录、实时语音、媒体理解、图像生成、视频生成、Web 抓取和 Web 搜索的共享契约,那么供应商可以在一个地方拥有其全部表面:
```ts
import type { OpenClawPluginDefinition } from "openclaw/plugin-sdk/plugin-entry";
@ -344,125 +358,125 @@ const plugin: OpenClawPluginDefinition = {
export default plugin;
```
重要的不是确切的辅助函数名,而是这种结构
重要的不是确切的辅助函数名称,而是整体形态
- 一个插件拥有商表面
- 一个插件拥有供应商表面
- 核心仍然拥有能力契约
- 渠道和功能插件消费 `api.runtime.*` 辅助工具,而不是商代码
- 契约测试可以断言该插件确实注册了它声称拥有的能力
- 渠道和功能插件消费 `api.runtime.*` 辅助工具,而不是供应商代码
- 契约测试可以断言该插件已注册其声称拥有的能力
### 能力示例:视频理解
OpenClaw 已经将图像 / 音频 / 视频理解视为一个共享能力。这里同样适用相同的归属模型:
OpenClaw 已经将图像/音频/视频理解视为一个共享能力。相同的归属模型也适用于这里
<Steps>
<Step title="核心定义契约">
核心定义媒体理解契约。
</Step>
<Step title="商插件注册">
厂商插件按需注册 `describeImage`、`transcribeAudio` 和 `describeVideo`
<Step title="供应商插件注册">
供应商插件按适用情况注册 `describeImage`、`transcribeAudio` 和 `describeVideo`
</Step>
<Step title="消费者使用共享行为">
渠道和功能插件消费共享的核心行为,而不是直接接线到厂商代码。
渠道和功能插件消费共享核心行为,而不是直接连接到供应商代码。
</Step>
</Steps>
避免了把某个提供商对视频的假设烘焙进核心。插件拥有厂商表面;核心拥有能力契约和回退行为。
样可以避免将某一提供商的视频假设固化进核心。插件拥有供应商表面;核心拥有能力契约和回退行为。
视频生成已经采用了同样的顺序:核心拥有类型化能力契约和运行时辅助工具,而厂商插件则针对其注册 `api.registerVideoGenerationProvider(...)` 实现。
视频生成已经使用同样的顺序:核心拥有类型化能力契约和运行时辅助工具,而供应商插件则针对其注册 `api.registerVideoGenerationProvider(...)` 实现。
需要一个具体的发布清单?请参见 [能力扩展手册](/zh-CN/plugins/architecture)。
需要具体的发布检查清单?请参见 [能力扩展手册](/zh-CN/plugins/architecture)。
## 契约与约束执行
## 契约与强制执行
插件 API 表面有意在 `OpenClawPluginApi`集中并做了类型化。该契约定义了受支持的注册点,以及插件可依赖的运行时辅助工具。
插件 API 表面有意设计为类型化,并集中`OpenClawPluginApi` 中。该契约定义了受支持的注册点,以及插件可依赖的运行时辅助工具。
很重要,因为:
之所以重要,是因为:
- 插件作者可以得到一套稳定的内部标准
- 插件作者可获得一个稳定的内部标准
- 核心可以拒绝重复归属,例如两个插件注册相同的提供商 id
- 启动过程可以为格式错误的注册暴露可执行的诊断信息
- 契约测试可以强制执行内置插件的归属,并防止静默漂移
- 启动过程可以为格式错误的注册暴露可操作的诊断信息
- 契约测试可以强制约束内置插件归属并防止无声漂移
这里有两层约束执行:
存在两层强制执行:
<AccordionGroup>
<Accordion title="运行时注册约束执行">
插件注册表会在插件加载时验证注册。例:重复的提供商 id、重复的语音提供商 id,以及格式错误的注册,都会产生插件诊断信息,而不是导致未定义行为
<Accordion title="运行时注册强制执行">
插件注册表会在插件加载时验证注册内容例:重复的提供商 id、重复的语音提供商 id 以及格式错误的注册,不会产生未定义行为,而会生成插件诊断信息
</Accordion>
<Accordion title="契约测试">
在测试运行期间,内置插件会被捕获到契约注册表中,这样 OpenClaw 就可以显式断言归属。当前这用于模型提供商、语音提供商、Web 搜索提供商和内置注册归属。
在测试运行期间,内置插件会被捕获到契约注册表中,以便 OpenClaw 明确断言归属。当前这用于模型提供商、语音提供商、Web 搜索提供商以及内置注册归属。
</Accordion>
</AccordionGroup>
实际效果是OpenClaw 可以预先知道哪个插件拥有哪个表面。这使得核心和渠道能够无缝组合,因为归属是声明、类型化且可测试的,而不是隐式的。
实际效果是OpenClaw 能在一开始就知道哪个插件拥有哪些表面。这使核心和渠道能够无缝组合,因为归属是声明、类型化且可测试的,而不是隐式的。
### 什么应该属于契约
<Tabs>
<Tab title="好契约">
<Tab title="好契约">
- 类型化
- 小而精
- 能力特定
- 能力专属
- 由核心拥有
- 可被多个插件复用
- 可在不了解厂商细节的情况下被渠道 / 功能消费
- 渠道/功能无需了解供应商即可消费
</Tab>
<Tab title="契约">
- 隐藏在核心中的厂商特定策略
<Tab title="糟糕的契约">
- 隐藏在核心中的供应商专属策略
- 绕过注册表的一次性插件逃生口
- 直接深入调用厂商实现的渠道代码
- 直接深入某个供应商实现的渠道代码
- 不属于 `OpenClawPluginApi``api.runtime` 的临时运行时对象
</Tab>
</Tabs>
拿不准时,就提升抽象层级:先定义能力,再让插件接入它
如有疑问,请提升抽象层级:先定义能力,再让插件接入该能力
## 执行模型
原生 OpenClaw 插件与 Gateway 网关**在同一进程中**运行。它们没有沙箱隔离。一个已加载的原生插件与核心代码具有相同的进程级信任边界。
原生 OpenClaw 插件与 Gateway 网关**在同一进程内**运行。它们没有经过沙箱隔离。已加载的原生插件与核心代码具有相同的进程级信任边界。
<Warning>
影响包括:
- 原生插件可以注册工具、网络处理器、钩子和服务
- 原生插件的 bug 可能导致 Gateway 网关崩溃或不稳定
- 恶意原生插件等同于在 OpenClaw 进程内执行任意代码
- 原生插件中的 bug 可能导致 gateway 崩溃或不稳定
- 恶意原生插件等同于在 OpenClaw 进程内执行任意代码
</Warning>
兼容 bundle 默认情况下更安全,因为 OpenClaw 当前将其视为元数据 / 内容包。在当前版本中,这主要指内置 Skills。
兼容 bundle 默认更安全,因为 OpenClaw 当前将其视为元数据/内容包。在当前版本中,这主要意味着内置的 Skills。
对于非内置插件,请使用允许列表和显式安装 / 加载路径。应将工作区插件视为开发时代码,而不是生产默认值。
对于非内置插件,请使用 allowlist 和显式的安装/加载路径。应将工作区插件视为开发阶段代码,而不是生产默认值。
对于内置工作区 package 名称,请让插件 id 锚定在 npm 名称中:默认使用 `@openclaw/<id>`,或者在该 package 有意暴露更窄的插件角色时,使用经批准的类型化后缀,例如 `-provider`、`-plugin`、`-speech`、`-sandbox` 或 `-media-understanding`
对于内置工作区包名,请让插件 id 锚定在 npm 名称中:默认使用 `@openclaw/<id>`,或者在包有意暴露更窄的插件角色时,使用批准的类型化后缀,例如 `-provider`、`-plugin`、`-speech`、`-sandbox` 或 `-media-understanding`
<Note>
**信任说明:**
- `plugins.allow` 信任的是**插件 id**,而不是来源出处。
- 当启用 / 加入允许列表的工作区插件与某个内置插件具有相同 id 时,它会有意遮蔽该内置副本。
- 这在本地开发、补丁测试和热修复中是正常且有用的
- 内置插件信任是根据源快照解析的——也就是加载时磁盘上的 manifest 和代码——而不是根据安装元数据。一个被破坏或被替换的安装记录,不能在实际源代码未声明的情况下,静默扩大某个内置插件的信任表面。
- 当工作区插件已启用/加入 allowlist且其 id 与某个内置插件相同时,它会有意覆盖该内置副本。
- 这属于正常行为,并且对本地开发、补丁测试和热修复很有用
- 内置插件信任是根据源快照解析的——也就是加载时磁盘上的 manifest 和代码——而不是根据安装元数据解析。损坏或被替换的安装记录不能在实际源码声明范围之外,悄悄扩大内置插件的信任表面。
</Note>
## 导出边界
OpenClaw 导出的是能力,而不是实现层面的便捷工具
OpenClaw 导出的是能力,而不是实现层面的便捷接口
保持能力注册为公共接口。收紧非契约辅助导出:
保持能力注册公开。收紧非契约辅助导出:
- 内置插件专用的辅助子路径
- 不打算作为公 API 的运行时管线子路径
- 厂商特定的便捷辅助工具
- 属于实现细节的设置 / 新手引导辅助工具
- 不打算作为公 API 的运行时管线子路径
- 供应商专属的便捷辅助函数
- 属于实现细节的 setup/新手引导辅助函数
为了兼容性和内置插件维护,一些内置插件辅助子路径仍然保留在生成的 SDK 导出映射中。当前示例包括 `plugin-sdk/feishu`、`plugin-sdk/feishu-setup`、`plugin-sdk/zalo`、`plugin-sdk/zalo-setup` 以及若干 `plugin-sdk/matrix*` 接缝。应将这些视为保留的实现细节导出,而不是第三方插件推荐的 SDK 模式。
出于兼容性和内置插件维护原因,一些内置插件辅助子路径仍然保留在生成的 SDK 导出映射中。当前示例包括 `plugin-sdk/feishu`、`plugin-sdk/feishu-setup`、`plugin-sdk/zalo`、`plugin-sdk/zalo-setup` 以及若干 `plugin-sdk/matrix*` 接缝。应将这些视为保留的实现细节导出,而不是新第三方插件推荐采用的 SDK 模式。
## 内部机制与参考
关于加载管线、注册表模型、提供商运行时钩子、Gateway 网关 HTTP 路由、消息工具 schema、渠道目标解析、提供商目录、上下文引擎插件以及添加新能力的指南,请参见 [插件架构内部机制](/zh-CN/plugins/architecture-internals)。
关于加载管线、注册表模型、提供商运行时钩子、Gateway 网关 HTTP 路由、消息工具 schema、渠道目标解析、提供商目录、上下文引擎插件以及新能力的指南,请参见 [插件架构内部机制](/zh-CN/plugins/architecture-internals)。
## 相关内容
## 相关
- [构建插件](/zh-CN/plugins/building-plugins)
- [插件 manifest](/zh-CN/plugins/manifest)

File diff suppressed because it is too large Load Diff

View File

@ -1,53 +1,53 @@
---
read_when:
- 你正在构建一个 OpenClaw 插件
- 你需要发布一个插件配置 schema或调试插件验证错误
- 你正在构建一个 OpenClaw 插件】【。
- 你需要发布一个插件配置 schema或调试插件验证错误】【。
summary: 插件清单 + JSON schema 要求(严格配置验证)
title: 插件清单
x-i18n:
generated_at: "2026-04-26T08:13:19Z"
generated_at: "2026-04-27T08:00:40Z"
model: gpt-5.4
provider: openai
source_hash: b86920ad774c5ef4ace7b546ef44e5b087a8ca694dea622ddb440258ffff4237
source_hash: 9d6e1da1cc57f6ba89ef511b01636439dd34f0b847a306b96271ccf9c2b878d4
source_path: plugins/manifest.md
workflow: 15
---
此页面仅适用于**原生 OpenClaw 插件清单**。
关于兼容的 bundle 布局,请参 [Plugin bundles](/zh-CN/plugins/bundles)。
关于兼容的 bundle 布局,请参 [Plugin bundles](/zh-CN/plugins/bundles)。
兼容的 bundle 格式使用不同的清单文件:
- Codex bundle`.codex-plugin/plugin.json`
- Claude bundle`.claude-plugin/plugin.json` 或不带清单的默认 Claude 组件布局
- Claude bundle`.claude-plugin/plugin.json`或不带清单的默认 Claude 组件布局
- Cursor bundle`.cursor-plugin/plugin.json`
OpenClaw 也会自动检测这些 bundle 布局,但不会根据此处描述的 `openclaw.plugin.json` schema 对它们进行验证。
OpenClaw 也会自动检测这些 bundle 布局,但它们不会根据此处描述的 `openclaw.plugin.json` schema 进行验证。
对于兼容 bundle当其布局符合 OpenClaw 运行时预期时OpenClaw 目前会读取 bundle 元数据、已声明的 skill 根目录、Claude 命令根目录、Claude bundle `settings.json` 默认值、Claude bundle 的 LSP 默认值,以及受支持的 hook 包
对于兼容 bundleOpenClaw 当前会在布局符合 OpenClaw 运行时期望时,读取 bundle 元数据、已声明的 Skill 根目录、Claude 命令根目录、Claude bundle `settings.json` 默认值、Claude bundle LSP 默认值以及受支持的 hook pack
每个原生 OpenClaw 插件**必须**在**插件根目录**中提供一个 `openclaw.plugin.json` 文件。OpenClaw 使用清单在**不执行插件代码的情况下**验证配置。缺失或无效的清单会被视为插件错误,并阻止配置验证。
每个原生 OpenClaw 插件**必须**在**插件根目录**中提供一个 `openclaw.plugin.json` 文件。OpenClaw 使用这个清单在**不执行插件代码的情况下**验证配置。缺失或无效的清单会被视为插件错误,并阻止配置验证。
请参阅完整的插件系统指南:[Plugins](/zh-CN/tools/plugin)。
关于原生能力模型和当前外部兼容性指南,请参阅
关于原生能力模型和当前外部兼容性指导,请参见
[能力模型](/zh-CN/plugins/architecture#public-capability-model)。
## 文件的作用
## 这个文件的作用
`openclaw.plugin.json` 是 OpenClaw 在**加载你的插件代码之前**读取的元数据。以下所有内容都必须足够轻量,能够在不启动插件运行时的情况下进行检查。
`openclaw.plugin.json` 是 OpenClaw 在**加载你的插件代码之前**读取的元数据。下面的所有内容都必须足够轻量,以便在不启动插件运行时的情况下进行检查。
**用于:**
**将它用于:**
- 插件标识、配置验证,以及配置 UI 提示
- 认证、新手引导和设置元数据(别名、自动启用、provider 环境变量、认证选项)
- control-plane 表面的激活提示
- 简写模型族归属
- 插件标识、配置验证配置 UI 提示
- 认证、新手引导和设置元数据(别名、自动启用、提供商环境变量、认证选项)
- 控制平面界面的激活提示
- 简写模型族归属
- 静态能力归属快照(`contracts`
- 共享 `openclaw qa` 宿主可检查的 QA 运行器元数据
- 合并到目录和验证表面的渠道专用配置元数据
- 共享 `openclaw qa`可检查的 QA 运行器元数据
- 合并到目录和验证界面中的渠道专用配置元数据
**不要用于:** 注册运行时行为、声明代码入口点,或 npm 安装元数据。这些应放在你的插件代码和 `package.json`
**不要将它用于:** 注册运行时行为、声明代码入口点或 npm 安装元数据。这些属于你的插件代码和 `package.json`
## 最小示例
@ -131,64 +131,67 @@ OpenClaw 也会自动检测这些 bundle 布局,但不会根据此处描述的
| ------------------------------------ | -------- | -------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `id` | 是 | `string` | 规范插件 id。这是在 `plugins.entries.<id>` 中使用的 id。 |
| `configSchema` | 是 | `object` | 此插件配置的内联 JSON Schema。 |
| `enabledByDefault` | 否 | `true` | 将内置插件标记为默认启用。省略此字段,或设置为任何非 `true` 的值,以使该插件默认保持禁用。 |
| `enabledByDefault` | 否 | `true` | 将内置插件标记为默认启用。省略此,或设置为任何非 `true` 的值,以使该插件默认禁用。 |
| `legacyPluginIds` | 否 | `string[]` | 会规范化为此规范插件 id 的旧版 id。 |
| `autoEnableWhenConfiguredProviders` | 否 | `string[]` | 当认证、配置或模型引用提到这些 provider id 时,应自动启用此插件。 |
| `kind` | 否 | `"memory"` \| `"context-engine"` | 声明`plugins.slots.*` 使用的独占插件类型。 |
| `autoEnableWhenConfiguredProviders` | 否 | `string[]` | 当认证、配置或模型引用提到这些提供商 id 时,应自动启用此插件。 |
| `kind` | 否 | `"memory"` \| `"context-engine"` | 声明一个由 `plugins.slots.*` 使用的互斥插件种类。 |
| `channels` | 否 | `string[]` | 由此插件拥有的渠道 id。用于发现和配置验证。 |
| `providers` | 否 | `string[]` | 由此插件拥有的 provider id。 |
| `providerDiscoveryEntry` | 否 | `string` | 轻量级 provider 发现模块路径,相对于插件根目录,用于可在不激活完整插件运行时的情况下加载的、作用域限定于清单的 provider 目录元数据。 |
| `modelSupport` | 否 | `object` | 由清单拥有的简写模型族元数据,用于在运行时之前自动加载插件。 |
| `modelCatalog` | 否 | `object` | 由声明式方式定义的、适用于此插件所拥有 providers 的模型目录元数据。这是未来只读列表、onboarding、模型选择器、别名和抑制功能在不加载插件运行时情况下使用的 control-plane 合约。 |
| `providerEndpoints` | 否 | `object[]` | 由清单拥有的 endpoint 主机 / `baseUrl` 元数据,用于核心在 provider 运行时加载前必须分类的 provider 路由。 |
| `providers` | 否 | `string[]` | 由此插件拥有的提供商 id。 |
| `providerDiscoveryEntry` | 否 | `string` | 轻量级 provider 发现模块路径,相对于插件根目录,用于可在不激活完整插件运行时的情况下加载的、限定于清单范围内的 provider 目录元数据。 |
| `modelSupport` | 否 | `object` | 由清单拥有的简写模型族元数据,用于在运行时之前自动加载插件。 |
| `modelCatalog` | 否 | `object` | 适用于由此插件拥有的提供商的声明式模型目录元数据。这是未来只读列表、新手引导、模型选择器、别名和抑制功能在不加载插件运行时情况下的控制平面契约。 |
| `providerEndpoints` | 否 | `object[]` | 由清单拥有的端点 host / `baseUrl` 元数据,用于核心在 provider 运行时加载前必须分类的 provider 路由。 |
| `cliBackends` | 否 | `string[]` | 由此插件拥有的 CLI 推理后端 id。用于根据显式配置引用在启动时自动激活。 |
| `syntheticAuthRefs` | 否 | `string[]` | 在运行时加载之前、冷启动模型发现期间,应探测其插件自有 synthetic auth hook 的 provider 或 CLI 后端引用。 |
| `nonSecretAuthMarkers` | 否 | `string[]` | 由内置插件拥有的占位 API key 值,表示非机密的本地、OAuth 或环境凭证状态。 |
| `commandAliases` | 否 | `object[]` | 由此插件拥有的命令名称,应在运行时加载之前生成带有插件感知能力的配置和 CLI 诊断信息。 |
| `providerAuthEnvVars` | 否 | `Record<string, string[]>` | 用于 provider 认证 / Status 查找的已弃用兼容性环境变量元数据。对于新插件,优先使用 `setup.providers[].envVars`OpenClaw 在弃用窗口期内仍会读取此字段。 |
| `providerAuthAliases` | 否 | `Record<string, string>` | 应复用另一个 provider id 进行认证查找的 provider id例如与基础 provider 共享 API key 和认证配置文件的编码 provider。 |
| `channelEnvVars` | 否 | `Record<string, string[]>` | OpenClaw 可在不加载插件代码的情况下检查的轻量级渠道环境变量元数据。将其用于通用启动 / 配置辅助工具应可见的、由环境变量驱动的渠道设置或认证面。 |
| `providerAuthChoices` | 否 | `object[]` | 用于 onboarding 选择器、首选 provider 解析和简单 CLI 标志接线的轻量级认证选项元数据。 |
| `activation` | 否 | `object` | 轻量级激活规划器元数据,用于由 provider、命令、渠道、路由和能力触发的加载。仅包含元数据插件运行时仍拥有实际行为。 |
| `setup` | 否 | `object` | 轻量级设置 / onboarding 描述符,供发现和设置表面在不加载插件运行时的情况下检查。 |
| `qaRunners` | 否 | `object[]` | 共享 `openclaw qa` 宿主在插件运行时加载前使用的轻量级 QA 运行器描述符。 |
| `contracts` | 否 | `object` | 静态内置能力快照,涵盖外部认证 hook、speech、实时转录、实时语音、媒体理解、图像生成、音乐生成、视频生成、网页抓取、网页搜索和工具归属。 |
| `mediaUnderstandingProviderMetadata` | 否 | `Record<string, object>` | `contracts.mediaUnderstandingProviders` 中声明的 provider id 提供的轻量级媒体理解默认元数据。 |
| `channelConfigs` | 否 | `Record<string, object>` | 由清单拥有的渠道配置元数据,在运行时加载前合并到发现和验证面中。 |
| `syntheticAuthRefs` | 否 | `string[]` | provider 或 CLI 后端引用;在运行时加载前的冷启动模型发现期间,应探测其由插件拥有的合成认证钩子。 |
| `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 密钥和 auth profile 的编码 provider。 |
| `channelEnvVars` | 否 | `Record<string, string[]>` | OpenClaw 可在不加载插件代码的情况下检查的轻量级渠道环境变量元数据。将其用于通用启动 / 配置辅助工具应可见的、由环境变量驱动的渠道设置或认证面。 |
| `providerAuthChoices` | 否 | `object[]` | 适用于新手引导选择器、首选 provider 解析和简单 CLI 标志接线的轻量级认证选项元数据。 |
| `activation` | 否 | `object` | 适用于由 provider、命令、渠道、路由和能力触发加载的轻量级激活规划器元数据。仅为元数据实际行为仍由插件运行时负责。 |
| `setup` | 否 | `object` | 可供发现和设置界面在不加载插件运行时情况下检查的轻量级设置 / 新手引导描述符。 |
| `qaRunners` | 否 | `object[]` | 共享 `openclaw qa`在插件运行时加载前使用的轻量级 QA 运行器描述符。 |
| `contracts` | 否 | `object` | 外部认证钩子、语音、实时转写、实时语音、媒体理解、图像生成、音乐生成、视频生成、网页抓取、Ollama Web 搜索 和工具归属的静态内置能力快照。 |
| `mediaUnderstandingProviderMetadata` | 否 | `Record<string, object>` | 适用于在 `contracts.mediaUnderstandingProviders` 中声明的 provider id 的轻量级媒体理解默认值。 |
| `channelConfigs` | 否 | `Record<string, object>` | 由清单拥有的渠道配置元数据,在运行时加载前合并到发现和验证面中。 |
| `skills` | 否 | `string[]` | 要加载的 Skills 目录,相对于插件根目录。 |
| `name` | 否 | `string` | 人类可读的插件名称。 |
| `description` | 否 | `string` | 显示在插件面中的简短摘要。 |
| `description` | 否 | `string` | 显示在插件面中的简短摘要。 |
| `version` | 否 | `string` | 信息性插件版本。 |
| `uiHints` | 否 | `Record<string, object>` | 配置字段的 UI 标签、占位符和敏感性提示。 |
## `providerAuthChoices` 参考
每个 `providerAuthChoices` 条目描述一个 onboarding 或认证选项。
OpenClaw 会在 provider 运行时加载之前读取这些内容。
provider 设置列表会使用这些清单选项、从描述符派生的设置选项,以及安装目录元数据,而无需加载 provider 运行时。
每个 `providerAuthChoices` 条目描述一个新手引导或认证选项。
OpenClaw 会在 provider 运行时加载前读取它。
provider 设置列表会使用这些清单选项、由描述符派生的设置选项,
以及安装目录元数据,而无需加载 provider 运行时。
| 字段 | 必填 | 类型 | 含义 |
| --------------------- | -------- | ----------------------------------------------- | -------------------------------------------------------------------------------------------------------- |
| `provider` | 是 | `string` | 此选项所属的 provider id。 |
| `method` | 是 | `string` | 要分到的认证方法 id。 |
| `choiceId` | 是 | `string` | onboarding 和 CLI 流程使用的稳定认证选项 id。 |
| `choiceLabel` | 否 | `string` | 面向用户的标签。如果省略OpenClaw 会回退 `choiceId`。 |
| `choiceHint` | 否 | `string` | 选择器的简短辅助文本。 |
| `method` | 是 | `string` | 要分到的认证方法 id。 |
| `choiceId` | 是 | `string` | 新手引导和 CLI 流程使用的稳定认证选项 id。 |
| `choiceLabel` | 否 | `string` | 面向用户的标签。如果省略OpenClaw 会回退 `choiceId`。 |
| `choiceHint` | 否 | `string` | 选择器中的简短帮助文本。 |
| `assistantPriority` | 否 | `number` | 在由助手驱动的交互式选择器中,值越小排序越靠前。 |
| `assistantVisibility` | 否 | `"visible"` \| `"manual-only"` | 在助手选择器中隐藏该选项,但仍允许手动通过 CLI 选择。 |
| `deprecatedChoiceIds` | 否 | `string[]` | 应将用户重定向到此替代选项的旧版选项 id。 |
| `groupId` | 否 | `string` | 用于对相关选项进行分组的可选分组 id。 |
| `groupLabel` | 否 | `string` | 该分组面向用户标签。 |
| `groupHint` | 否 | `string` | 该分组的简短助文本。 |
| `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"]`。 |
| `cliDescription` | 否 | `string` | 用于 CLI 帮助中的说明。 |
| `onboardingScopes` | 否 | `Array<"text-inference" \| "image-generation">` | 该选项应出现在哪些新手引导界面中。如果省略,默认值为 `["text-inference"]`。 |
## `commandAliases` 参考
当插件拥有某个运行时命令名称,而用户可能会误将其放入 `plugins.allow`,或尝试将其作为根 CLI 命令运行时,请使用 `commandAliases`。OpenClaw 使用此元数据在不导入插件运行时代码的情况下提供诊断信息。
当插件拥有一个运行时命令名称,而用户可能误将其放入 `plugins.allow`
或尝试将其作为根 CLI 命令运行时,请使用 `commandAliases`。OpenClaw
使用这些元数据来提供诊断,而无需导入插件运行时代码。
```json
{
@ -206,18 +209,33 @@ provider 设置列表会使用这些清单选项、从描述符派生的设置
| ------------ | -------- | ----------------- | ----------------------------------------------------------------------- |
| `name` | 是 | `string` | 属于此插件的命令名称。 |
| `kind` | 否 | `"runtime-slash"` | 将该别名标记为聊天斜杠命令,而不是根 CLI 命令。 |
| `cliCommand` | 否 | `string` | 若存在,可为 CLI 操作建议的相关根 CLI 命令。 |
| `cliCommand` | 否 | `string` | 若存在,用于建议 CLI 操作的相关根 CLI 命令。 |
## `activation` 参考
当插件可以以低成本声明哪些 control-plane 事件应将其纳入激活 / 加载计划时,请使用 `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` 作为额外的规划器提示。
对于 `claude-cli`、`codex-cli` 或 `google-gemini-cli` 之类的 CLI 运行时别名,请使用顶层 `cliBackends``activation.onAgentHarnesses` 仅适用于尚无归属字段的嵌入式 Agent harness id。
优先使用已经能够描述归属关系的最窄元数据。能用
`providers`、`channels`、`commandAliases`、setup 描述符或 `contracts`
表达关系时,就使用这些字段。对于无法由这些归属字段表示的额外规划器
提示,再使用 `activation`
对于 `claude-cli`、`codex-cli` 或 `google-gemini-cli` 这类 CLI 运行时别名,
请使用顶层 `cliBackends``activation.onAgentHarnesses` 仅适用于
那些尚无归属字段的嵌入式 Agent harness id。
此代码块仅包含元数据。它不会注册运行时行为,也不会替代 `register(...)`、`setupEntry` 或其他运行时 / 插件入口点。当前使用方会在更广泛的插件加载之前将其作为缩小范围的提示,因此缺少激活元数据通常只会带来性能损耗;在旧版清单归属回退仍然存在的情况下,它不应影响正确性。
此块仅为元数据。它不会注册运行时行为,也不会
替代 `register(...)`、`setupEntry` 或其他运行时 / 插件入口点。
当前使用方会在更广泛的插件加载之前将其作为缩小范围的提示,因此
缺少激活元数据通常只会带来性能成本;
只要旧版清单归属回退仍然存在,就不应影响正确性。
```json
{
@ -233,27 +251,39 @@ provider 设置列表会使用这些清单选项、从描述符派生的设置
| 字段 | 必填 | 类型 | 含义 |
| ------------------ | -------- | ---------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- |
| `onProviders` | 否 | `string[]` | 在激活 / 加载计划中应包含此插件的 provider id。 |
| `onAgentHarnesses` | 否 | `string[]` | 在激活 / 加载计划中应包含此插件的嵌入式 Agent harness 运行时 id。对于 CLI 后端别名,请使用顶层 `cliBackends`。 |
| `onCommands` | 否 | `string[]` | 在激活 / 加载计划中应包含此插件的命令 id。 |
| `onChannels` | 否 | `string[]` | 在激活 / 加载计划中应包含此插件的渠道 id。 |
| `onRoutes` | 否 | `string[]` | 在激活 / 加载计划中应包含此插件的路由类型。 |
| `onCapabilities` | 否 | `Array<"provider" \| "channel" \| "tool" \| "hook">` | control-plane 激活规划使用的宽泛能力提示。可能的话,优先使用更窄的字段。 |
| `onProviders` | 否 | `string[]` | 应将此插件包含在激活 / 加载计划中的 provider id。 |
| `onAgentHarnesses` | 否 | `string[]` | 应将此插件包含在激活 / 加载计划中的嵌入式 Agent harness 运行时 id。对于 CLI 后端别名,请使用顶层 `cliBackends`。 |
| `onCommands` | 否 | `string[]` | 应将此插件包含在激活 / 加载计划中的命令 id。 |
| `onChannels` | 否 | `string[]` | 应将此插件包含在激活 / 加载计划中的渠道 id。 |
| `onRoutes` | 否 | `string[]` | 应将此插件包含在激活 / 加载计划中的路由类型。 |
| `onCapabilities` | 否 | `Array<"provider" \| "channel" \| "tool" \| "hook">` | 用于控制平面激活规划的宽泛能力提示。可以的话,优先使用更窄的字段。 |
当前在线使用方:
- 由命令触发的 CLI 规划会回退到旧版
`commandAliases[].cliCommand``commandAliases[].name`
- 智能体运行时启动规划对嵌入式 harness 使用 `activation.onAgentHarnesses`,对 CLI 运行时别名使用顶层 `cliBackends[]`
- 由渠道触发的设置 / 渠道规划在缺少显式渠道激活元数据时,会回退到旧版 `channels[]` 归属
- 由 provider 触发的设置 / 运行时规划在缺少显式 provider 激活元数据时,会回退到旧版
- 智能体运行时启动规划对嵌入式 harness 使用 `activation.onAgentHarnesses`
对 CLI 运行时别名使用顶层 `cliBackends[]`
- 由渠道触发的设置 / 渠道规划在缺少显式渠道激活元数据时,
会回退到旧版 `channels[]`
归属
- 由 provider 触发的设置 / 运行时规划在缺少显式 provider
激活元数据时,会回退到旧版
`providers[]` 和顶层 `cliBackends[]` 归属
规划器诊断可以区分显式激活提示和清单归属回退。例如,`activation-command-hint` 表示匹配了 `activation.onCommands`,而 `manifest-command-alias` 表示规划器改为使用 `commandAliases` 归属。这些原因标签用于宿主诊断和测试;插件作者应继续声明最能描述归属关系的元数据。
规划器诊断可以区分显式激活提示和清单
归属回退。例如,`activation-command-hint` 表示
匹配了 `activation.onCommands`,而 `manifest-command-alias` 表示
规划器改用了 `commandAliases` 归属。这些原因标签
用于宿主诊断和测试;插件作者应继续声明最能描述
归属关系的元数据。
## `qaRunners` 参考
当插件在共享 `openclaw qa` 根命令下贡献一个或多个传输运行器时,请使用 `qaRunners`。请保持此元数据轻量且静态;实际的 CLI 注册仍由插件运行时通过导出 `qaRunnerCliRegistrations` 的轻量级 `runtime-api.ts` 表面来负责。
当插件在共享的 `openclaw qa` 根命令下贡献一个或多个传输运行器时,
请使用 `qaRunners`。请保持这些元数据轻量且静态;
实际的 CLI 注册仍由插件运行时通过一个轻量级
`runtime-api.ts` 接口负责,该接口导出 `qaRunnerCliRegistrations`
```json
{
@ -269,11 +299,12 @@ provider 设置列表会使用这些清单选项、从描述符派生的设置
| 字段 | 必填 | 类型 | 含义 |
| ------------- | -------- | -------- | ------------------------------------------------------------------ |
| `commandName` | 是 | `string` | 挂载在 `openclaw qa` 下的子命令,例如 `matrix`。 |
| `description` | 否 | `string` | 当共享宿主需要一个占位命令时使用的回退帮助文本。 |
| `description` | 否 | `string` | 当共享宿主需要一个命令时使用的回退帮助文本。 |
## `setup` 参考
当设置和 onboarding 表面需要在运行时加载前读取由插件拥有的低成本元数据时,请使用 `setup`
当设置和新手引导界面需要在运行时加载前获取由插件拥有的轻量级元数据时,
请使用 `setup`
```json
{
@ -292,40 +323,65 @@ provider 设置列表会使用这些清单选项、从描述符派生的设置
}
```
顶层 `cliBackends` 仍然有效,并继续描述 CLI 推理后端。`setup.cliBackends` 是面向 control-plane / 设置流程的、应保持仅元数据形式的 setup 专用描述符表面。
顶层 `cliBackends` 仍然有效,并继续描述 CLI 推理
后端。`setup.cliBackends` 是面向
应保持仅元数据化的控制平面 / 设置流程的、设置专用描述符界面。
存在时,`setup.providers` 和 `setup.cliBackends` 是设置发现的首选“descriptor-first”查找表面。如果描述符只能缩小候选插件范围而设置仍需要更丰富的设置期运行时 hooks请设置 `requiresRuntime: true`,并保留 `setup-api` 作为回退执行路径。
存在 `setup.providers``setup.cliBackends` 时,它们是
设置发现中优先使用的描述符优先查询界面。如果该描述符仅用于
缩小候选插件范围,而设置仍需要更丰富的设置期运行时钩子,
请将 `requiresRuntime` 设为 `true`,并保留 `setup-api`
作为回退执行路径。
OpenClaw 还会将 `setup.providers[].envVars` 纳入通用 provider 认证和环境变量查找。`providerAuthEnvVars` 在弃用窗口期内仍通过兼容适配器受支持,但仍在使用它的非内置插件会收到清单诊断。新插件应将设置 / Status 环境变量元数据放在 `setup.providers[].envVars` 上。
OpenClaw 还会将 `setup.providers[].envVars` 包含在通用 provider 认证和
环境变量查询中。`providerAuthEnvVars` 在弃用窗口期内仍通过兼容适配器
继续受支持,但仍在使用它的非内置插件
会收到清单诊断。新插件应将设置 / Status 环境变量元数据
放在 `setup.providers[].envVars` 上。
当没有 setup 条目可用,或 `setup.requiresRuntime: false` 声明设置运行时不是必需时OpenClaw 还可以从 `setup.providers[].authMethods` 派生简单的设置选项。对于自定义标签、CLI 标志、onboarding 范围和助手元数据,显式的 `providerAuthChoices` 条目仍然是首选。
在没有 setup 入口时,或者当
`setup.requiresRuntime: false` 声明设置运行时不必要时OpenClaw 也可以从 `setup.providers[].authMethods`
派生出简单的设置选项。对于自定义标签、CLI 标志、新手引导范围
和助手元数据,显式的 `providerAuthChoices` 条目仍然是首选。
仅当这些描述符对于设置表面已经足够时,才设置 `requiresRuntime: false`。OpenClaw 将显式的 `false` 视为仅描述符合约,并且不会为设置查找执行 `setup-api``openclaw.setupEntry`。如果仅描述符插件仍然提供了这些设置运行时入口之一OpenClaw 会报告一条附加诊断,并继续忽略它。省略 `requiresRuntime` 会保留旧版回退行为,这样那些在未设置该标志的情况下添加了描述符的现有插件就不会出问题。
仅当这些描述符已足以满足
设置界面时,才将 `requiresRuntime: false`。OpenClaw 将显式的 `false` 视为仅描述符契约,
并且不会为设置查询执行 `setup-api``openclaw.setupEntry`。如果
一个仅描述符插件仍然提供了其中某个设置运行时入口,
OpenClaw 会报告一条附加诊断,并继续忽略它。省略
`requiresRuntime` 会保留旧版回退行为,因此现有那些在未设置该标志的情况下添加了
描述符的插件不会失效。
由于设置查找可能会执行由插件拥有的 `setup-api` 代码,规范化后的 `setup.providers[].id``setup.cliBackends[]` 值必须在已发现插件之间保持唯一。归属不明确时会采用失败即关闭的方式,而不是根据发现顺序挑选一个“胜出者”。
由于设置查询可能会执行由插件拥有的 `setup-api` 代码,
规范化后的 `setup.providers[].id``setup.cliBackends[]` 值必须在所有已发现插件中
保持唯一。归属不明确时会采取失败即关闭的方式,而不是按发现顺序选一个
“赢家”。
当设置运行时确实执行时,如果 `setup-api` 注册了清单描述符未声明的 provider 或 CLI 后端,或者某个描述符没有对应的运行时注册,设置注册表诊断就会报告描述符漂移。这些诊断是附加性的,不会拒绝旧版插件。
当设置运行时确实执行时,如果 `setup-api` 注册了一个提供商或 CLI 后端,
但清单描述符没有声明它,或者某个描述符没有匹配的运行时
注册,设置注册表诊断就会报告描述符漂移。
这些诊断是附加性的,不会拒绝旧版插件。
### `setup.providers` 参考
| 字段 | 必填 | 类型 | 含义 |
| ------------- | -------- | ---------- | ------------------------------------------------------------------------------------ |
| `id` | 是 | `string` | 在设置或 onboarding 期间公开的 provider id。保持规范化 id 在全局范围内唯一。 |
| `id` | 是 | `string` | 在设置或新手引导期间暴露的 provider id。请保持规范化 id 在全局范围内唯一。 |
| `authMethods` | 否 | `string[]` | 此 provider 在不加载完整运行时的情况下支持的设置 / 认证方法 id。 |
| `envVars` | 否 | `string[]` | 通用设置 / Status 面可在插件运行时加载前检查的环境变量。 |
| `envVars` | 否 | `string[]` | 通用设置 / Status 面可在插件运行时加载前检查的环境变量。 |
### `setup` 字段
| 字段 | 必填 | 类型 | 含义 |
| ------------------ | -------- | ---------- | --------------------------------------------------------------------------------------------------- |
| `providers` | 否 | `object[]` | 在设置和 onboarding 期间公开的 provider 设置描述符。 |
| `cliBackends` | 否 | `string[]` | 用于 descriptor-first 设置查找的设置期后端 id。保持规范化 id 在全局范围内唯一。 |
| `configMigrations` | 否 | `string[]` | 由此插件的设置面拥有的配置迁移 id。 |
| `requiresRuntime` | 否 | `boolean` | 在描述符查找之后,设置是否仍需要执行 `setup-api`。 |
| `providers` | 否 | `object[]` | 在设置和新手引导期间暴露的 provider 设置描述符。 |
| `cliBackends` | 否 | `string[]` | 用于描述符优先设置查询的设置期后端 id。请保持规范化 id 在全局范围内唯一。 |
| `configMigrations` | 否 | `string[]` | 由此插件的设置面拥有的配置迁移 id。 |
| `requiresRuntime` | 否 | `boolean` | 描述符查询后,设置是否仍需要执行 `setup-api`。 |
## `uiHints` 参考
`uiHints`从配置字段名称到小型渲染提示的映射
`uiHints`一个从配置字段名映射到小型渲染提示的映射表
```json
{
@ -345,15 +401,16 @@ OpenClaw 还会将 `setup.providers[].envVars` 纳入通用 provider 认证和
| 字段 | 类型 | 含义 |
| ------------- | ---------- | --------------------------------------- |
| `label` | `string` | 面向用户的字段标签。 |
| `help` | `string` | 简短助文本。 |
| `tags` | `string[]` | 可选 UI 标签。 |
| `help` | `string` | 简短助文本。 |
| `tags` | `string[]` | 可选 UI 标签。 |
| `advanced` | `boolean` | 将该字段标记为高级项。 |
| `sensitive` | `boolean` | 将该字段标记为密或敏感项。 |
| `sensitive` | `boolean` | 将该字段标记为密或敏感项。 |
| `placeholder` | `string` | 表单输入的占位文本。 |
## `contracts` 参考
仅将 `contracts` 用于 OpenClaw 能够在不导入插件运行时的情况下读取的静态能力归属元数据。
仅当 OpenClaw 可以在不导入插件运行时的情况下读取静态能力归属元数据时,
才使用 `contracts`
```json
{
@ -369,6 +426,7 @@ OpenClaw 还会将 `setup.providers[].envVars` 纳入通用 provider 认证和
"videoGenerationProviders": ["qwen"],
"webFetchProviders": ["firecrawl"],
"webSearchProviders": ["gemini"],
"migrationProviders": ["hermes"],
"tools": ["firecrawl_search", "firecrawl_scrape"]
}
}
@ -380,27 +438,43 @@ OpenClaw 还会将 `setup.providers[].envVars` 纳入通用 provider 认证和
| -------------------------------- | ---------- | --------------------------------------------------------------------- |
| `embeddedExtensionFactories` | `string[]` | Codex app-server 扩展工厂 id目前为 `codex-app-server`。 |
| `agentToolResultMiddleware` | `string[]` | 内置插件可为其注册工具结果中间件的运行时 id。 |
| `externalAuthProviders` | `string[]` | 此插件拥有其外部认证配置文件 hook 的 provider id。 |
| `speechProviders` | `string[]` | 此插件拥有的 speech 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[]` | 此插件拥有的智能体工具名称,用于内置合约检查。 |
| `externalAuthProviders` | `string[]` | 其外部 auth profile 钩子由该插件拥有的 provider id。 |
| `speechProviders` | `string[]` | 该插件拥有的语音 provider id。 |
| `realtimeTranscriptionProviders` | `string[]` | 该插件拥有的实时转写 provider id。 |
| `realtimeVoiceProviders` | `string[]` | 该插件拥有的实时语音 provider id。 |
| `memoryEmbeddingProviders` | `string[]` | 该插件拥有的 memory embedding provider id。 |
| `mediaUnderstandingProviders` | `string[]` | 该插件拥有的媒体理解 provider id。 |
| `imageGenerationProviders` | `string[]` | 该插件拥有的图像生成 provider id。 |
| `videoGenerationProviders` | `string[]` | 该插件拥有的视频生成 provider id。 |
| `webFetchProviders` | `string[]` | 该插件拥有的网页抓取 provider id。 |
| `webSearchProviders` | `string[]` | 该插件拥有的网页搜索 provider id。 |
| `migrationProviders` | `string[]` | 该插件为 `openclaw migrate` 拥有的导入 provider id。 |
| `tools` | `string[]` | 该插件为内置契约检查拥有的智能体工具名称。 |
`contracts.embeddedExtensionFactories` 保留用于内置、仅限 Codex app-server 的扩展工厂。内置工具结果转换应声明 `contracts.agentToolResultMiddleware`,并改为使用 `api.registerAgentToolResultMiddleware(...)` 进行注册。外部插件不能注册工具结果中间件,因为该接缝可以在模型看到之前重写高信任度工具输出。
`contracts.embeddedExtensionFactories` 被保留用于内置的、仅适用于 Codex
app-server 的扩展工厂。内置工具结果转换应
声明 `contracts.agentToolResultMiddleware`,并使用
`api.registerAgentToolResultMiddleware(...)` 进行注册。外部插件不能
注册工具结果中间件,因为该接口可以在模型看到高信任度工具输出之前
改写它。
实现了 `resolveExternalAuthProfiles` 的 provider 插件应声明 `contracts.externalAuthProviders`。未声明该字段的插件仍会通过已弃用的兼容性回退运行,但这种回退更慢,并将在迁移窗口结束后移除。
实现了 `resolveExternalAuthProfiles` 的 provider 插件
应声明 `contracts.externalAuthProviders`。未声明该项的插件仍会通过
已弃用的兼容性回退运行,但该回退更慢,
并将在迁移窗口结束后移除。
内置 Memory 嵌入 providers 应为其公开的每个适配器 id 声明 `contracts.memoryEmbeddingProviders`,包括诸如 `local` 之类的内置适配器。独立 CLI 路径会使用此清单合约,仅在完整 Gateway 网关运行时完成 provider 注册之前加载其所属插件。
内置 memory embedding provider 应为其暴露的每个适配器 id 声明
`contracts.memoryEmbeddingProviders`
包括诸如 `local` 之类的内置适配器。独立 CLI 路径使用这个清单
契约,在完整 Gateway 网关运行时尚未
注册 provider 之前,仅加载拥有该能力的插件。
## `mediaUnderstandingProviderMetadata` 参考
当媒体理解 provider 具有默认模型、自动认证回退优先级,或通用核心辅助工具在运行时加载前所需的原生文档支持时,请使用 `mediaUnderstandingProviderMetadata`。其键也必须在 `contracts.mediaUnderstandingProviders` 中声明。
当某个媒体理解 provider 具有默认模型、自动认证回退优先级
或原生文档支持,并且通用核心辅助工具需要在运行时加载前获取这些信息时,
请使用 `mediaUnderstandingProviderMetadata`。其键也必须在
`contracts.mediaUnderstandingProviders` 中声明。
```json
{
@ -427,25 +501,39 @@ OpenClaw 还会将 `setup.providers[].envVars` 纳入通用 provider 认证和
| 字段 | 类型 | 含义 |
| ---------------------- | ----------------------------------- | ---------------------------------------------------------------------------- |
| `capabilities` | `("image" \| "audio" \| "video")[]` | 该 provider 公开的媒体能力。 |
| `defaultModels` | `Record<string, string>` | 当配置未指定模型时使用的“能力到模型”默认值。 |
| `autoPriority` | `Record<string, number>` | 对于基于凭证的自动 provider 回退,数字越小排序越靠前。 |
| `capabilities` | `("image" \| "audio" \| "video")[]` | 该 provider 暴露的媒体能力。 |
| `defaultModels` | `Record<string, string>` | 当配置未指定模型时,按能力映射到模型的默认值。 |
| `autoPriority` | `Record<string, number>` | 用于基于凭证自动回退 provider 时,数字越小排序越靠前。 |
| `nativeDocumentInputs` | `"pdf"[]` | 该 provider 支持的原生文档输入。 |
## `channelConfigs` 参考
当渠道插件在运行时加载前需要低成本配置元数据时,请使用 `channelConfigs`。当没有可用的 setup 条目,或 `setup.requiresRuntime: false` 声明设置运行时不是必需时,只读的渠道设置 / Status 发现可以直接使用这些元数据来处理已配置的外部渠道。
当某个渠道插件需要在运行时加载前获取低成本配置元数据时,
请使用 `channelConfigs`。只读的渠道设置 / Status 发现可以
在没有 setup 入口时直接使用这些元数据来处理已配置的外部渠道,
或者在 `setup.requiresRuntime: false` 声明设置运行时不必要时使用它们。
`channelConfigs` 是插件清单元数据,而不是新的顶层用户配置部分。用户仍然在 `channels.<channel-id>` 下配置渠道实例。OpenClaw 读取清单元数据,以便在插件运行时代码执行之前决定哪个插件拥有该已配置渠道。
`channelConfigs` 是插件清单元数据,而不是新的顶层用户配置
区段。用户仍然在 `channels.<channel-id>` 下配置渠道实例。
OpenClaw 会读取清单元数据,以决定哪个插件拥有该已配置的
渠道,然后才执行插件运行时代码。
对于渠道插件,`configSchema` 和 `channelConfigs` 描述的是不同路径:
对于渠道插件,`configSchema` 和 `channelConfigs` 描述的是不同
路径:
- `configSchema` 验证 `plugins.entries.<plugin-id>.config`
- `channelConfigs.<channel-id>.schema` 验证 `channels.<channel-id>`
- `configSchema` 用于验证 `plugins.entries.<plugin-id>.config`
- `channelConfigs.<channel-id>.schema` 用于验证 `channels.<channel-id>`
声明了 `channels[]` 的非内置插件,也应声明匹配的 `channelConfigs` 条目。没有这些条目时OpenClaw 仍然可以加载该插件,但冷路径配置 schema、设置和 Control UI 表面在插件运行时执行之前无法获知渠道自有选项的形状。
声明了 `channels[]` 的非内置插件也应声明匹配的
`channelConfigs` 条目。若没有它们OpenClaw 仍然可以加载该插件,
但冷路径配置 schema、设置和 Control UI 界面在插件运行时执行前
无法知道该渠道拥有的选项结构。
`channelConfigs.<channel-id>.commands.nativeCommandsAutoEnabled``nativeSkillsAutoEnabled` 可以为在渠道运行时加载前执行的命令配置检查声明静态 `auto` 默认值。内置渠道也可以通过 `package.json#openclaw.channel.commands` 发布相同的默认值,并与其其他由包拥有的渠道目录元数据一起提供。
`channelConfigs.<channel-id>.commands.nativeCommandsAutoEnabled`
`nativeSkillsAutoEnabled` 可以为在渠道运行时加载前执行的命令配置检查
声明静态 `auto` 默认值。内置渠道也可以通过
`package.json#openclaw.channel.commands` 发布相同默认值,并与其他由 package 拥有的
渠道目录元数据一起提供。
```json
{
@ -481,15 +569,18 @@ OpenClaw 还会将 `setup.providers[].envVars` 纳入通用 provider 认证和
| 字段 | 类型 | 含义 |
| ------------- | ------------------------ | ----------------------------------------------------------------------------------------- |
| `schema` | `object` | `channels.<id>` 的 JSON Schema。每个已声明的渠道配置条目都必须提供。 |
| `uiHints` | `Record<string, object>` | 该渠道配置部分的可选 UI 标签 / 占位符 / 敏感性提示。 |
| `label` | `string` | 当运行时元数据尚未就绪时,合并到选择器和检查面中的渠道标签。 |
| `description` | `string` | 用于检查和目录面的简短渠道描述。 |
| `uiHints` | `Record<string, object>` | 该渠道配置区段的可选 UI 标签 / 占位符 / 敏感性提示。 |
| `label` | `string` | 当运行时元数据尚未就绪时,合并到选择器和检查面中的渠道标签。 |
| `description` | `string` | 用于检查和目录面的简短渠道描述。 |
| `commands` | `object` | 用于运行时前配置检查的静态原生命令和原生 Skills 自动默认值。 |
| `preferOver` | `string[]` | 在选择表面中,此渠道应优先于的旧版或较低优先级插件 id。 |
| `preferOver` | `string[]` | 在选择界面中,此渠道应优先于其之上的旧版或低优先级插件 id。 |
### 替换另一个渠道插件
当你的插件是某个渠道 id 的首选归属方,而另一个插件也能提供该渠道时,请使用 `preferOver`。常见情况包括:插件 id 已重命名、某个独立插件取代了内置插件,或者某个维护中的分支为了保持配置兼容性而沿用相同的渠道 id。
当你的插件是某个渠道 id 的首选拥有者,而另一个插件
也可以提供该渠道时,请使用 `preferOver`。常见情况包括:插件 id 已重命名、
独立插件取代了内置插件,或者维护中的分支为了配置兼容性
保留了相同的渠道 id。
```json
{
@ -510,13 +601,22 @@ OpenClaw 还会将 `setup.providers[].envVars` 纳入通用 provider 认证和
}
```
当配置了 `channels.chat`OpenClaw 会同时考虑渠道 id 和首选插件 id。如果低优先级插件之所以被选中仅仅是因为它是内置的或默认启用的OpenClaw 就会在有效运行时配置中将其禁用以便由一个插件拥有该渠道及其工具。显式用户选择仍然优先如果用户显式启用了这两个插件OpenClaw 会保留该选择,并报告重复渠道 / 工具诊断,而不是静默更改所请求的插件集。
当配置了 `channels.chat`OpenClaw 会同时考虑渠道 id 和
首选插件 id。如果低优先级插件之所以被选中
只是因为它是内置的或默认启用的,
OpenClaw 会在生效运行时配置中禁用它,以便由一个插件统一拥有该渠道
及其工具。显式的用户选择仍然优先:如果用户明确启用了两个插件,
OpenClaw 会保留该选择,并报告重复渠道 / 工具诊断,
而不是静默更改用户请求的插件集合。
请将 `preferOver` 的范围限定在确实能够提供同一渠道的插件 id 上。它不是一个通用优先级字段,也不会重命名用户配置键。
请将 `preferOver` 限定在那些确实能提供相同渠道的插件 id 上。
它不是一个通用优先级字段,也不会重命名用户配置键。
## `modelSupport` 参考
当 OpenClaw 应在插件运行时加载之前,根据 `gpt-5.5``claude-sonnet-4.6` 之类的简写模型 id 推断你的 provider 插件时,请使用 `modelSupport`
当 OpenClaw 应在插件运行时加载前,根据简写模型 id
`gpt-5.5``claude-sonnet-4.6` 推断你的 provider 插件时,
请使用 `modelSupport`
```json
{
@ -527,23 +627,28 @@ OpenClaw 还会将 `setup.providers[].envVars` 纳入通用 provider 认证和
}
```
OpenClaw 按以下优先级处理
OpenClaw 按以下优先级应用
- 显式 `provider/model` 引用使用所属 `providers` 清单元数据
- 显式`provider/model` 引用使用拥有该项的 `providers` 清单元数据
- `modelPatterns` 优先于 `modelPrefixes`
- 如果一个非内置插件和一个内置插件都匹配,则非内置插件胜出
- 对于其余歧义,在用户或配置指定 provider 之前会被忽略
- 如果一个非内置插件和一个内置插件都匹配,则非内置
插件优先
- 其余歧义会被忽略,直到用户或配置指定某个 provider
字段:
| 字段 | 类型 | 含义 |
| --------------- | ---------- | ------------------------------------------------------------------------------- |
| `modelPrefixes` | `string[]` | 使用 `startsWith` 与简写模型 id 匹配的前缀。 |
| `modelPatterns` | `string[]` | 在移除配置文件后缀后,与简写模型 id 匹配的正则表达式源码。 |
| `modelPrefixes` | `string[]` | 通过 `startsWith` 与简写模型 id 匹配的前缀。 |
| `modelPatterns` | `string[]` | 在移除 profile 后缀后,与简写模型 id 匹配的正则表达式源码。 |
## `modelCatalog` 参考
当 OpenClaw 应在加载插件运行时之前了解 provider 模型元数据时,请使用 `modelCatalog`。这是固定目录行、provider 别名、抑制规则和发现模式的清单归属来源。运行时刷新仍属于 provider 运行时代码,但清单会告知核心何时需要运行时。
当 OpenClaw 应在加载插件运行时之前了解 provider 模型元数据时,
请使用 `modelCatalog`。这是由清单拥有的固定目录
条目、provider 别名、抑制规则和发现模式的数据源。
运行时刷新仍属于 provider 运行时代码负责,但清单会告知核心
何时需要运行时。
```json
{
@ -596,19 +701,19 @@ OpenClaw 按以下优先级处理:
| 字段 | 类型 | 含义 |
| -------------- | -------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------- |
| `providers` | `Record<string, object>` | 此插件拥有的 provider id 的目录行。键也应出现在顶层 `providers` 中。 |
| `aliases` | `Record<string, object>` | 应解析为某个已拥有 provider 的 provider 别名,用于目录或抑制规划。 |
| `suppressions` | `object[]` | 此插件因 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 字段:
| 字段 | 类型 | 含义 |
| --------- | ------------------------ | ----------------------------------------------------------------- |
| `baseUrl` | `string` | 此 provider 目录中模型的可选默认 `baseUrl`。 |
| `baseUrl` | `string` | 此 provider 目录中模型的可选默认 base URL。 |
| `api` | `ModelApi` | 此 provider 目录中模型的可选默认 API 适配器。 |
| `headers` | `Record<string, string>` | 适用于此 provider 目录的可选静态头。 |
| `models` | `object[]` | 必需的模型行。没有 `id` 的行会被忽略。 |
| `headers` | `Record<string, string>` | 适用于此 provider 目录的可选静态请求头。 |
| `models` | `object[]` | 必填模型条目。没有 `id` 的条目会被忽略。 |
模型字段:
@ -616,93 +721,143 @@ provider 字段:
| --------------- | -------------------------------------------------------------- | --------------------------------------------------------------------------- |
| `id` | `string` | provider 本地模型 id不含 `provider/` 前缀。 |
| `name` | `string` | 可选显示名称。 |
| `api` | `ModelApi` | 可选的逐模型 API 覆盖。 |
| `baseUrl` | `string` | 可选的逐模型 `baseUrl` 覆盖。 |
| `headers` | `Record<string, string>` | 可选的逐模型静态头。 |
| `api` | `ModelApi` | 可选的逐模型 API 覆盖。 |
| `baseUrl` | `string` | 可选的逐模型 base URL 覆盖值。 |
| `headers` | `Record<string, string>` | 可选的逐模型静态请求头。 |
| `input` | `Array<"text" \| "image" \| "document" \| "audio" \| "video">` | 该模型接受的模态。 |
| `reasoning` | `boolean` | 该模型是否公开推理行为。 |
| `reasoning` | `boolean` | 该模型是否暴露推理行为。 |
| `contextWindow` | `number` | provider 原生上下文窗口。 |
| `contextTokens` | `number` | 当与 `contextWindow` 不同时,可选的有效运行时上下文上限。 |
| `contextTokens` | `number` | 当与 `contextWindow` 不同时,可选的实际运行时上下文上限。 |
| `maxTokens` | `number` | 已知时的最大输出 token 数。 |
| `cost` | `object` | 可选的每百万 token 美元定价,包括可选的 `tieredPricing`。 |
| `compat` | `object` | 与 OpenClaw 模型配置兼容性匹配的可选兼容性标志。 |
| `status` | `"available"` \| `"preview"` \| `"deprecated"` \| `"disabled"` | 列表状态。仅当该行完全不应出现时才使用 suppress。 |
| `statusReason` | `string` | 与不可用状态一同显示的可选原因。 |
| `replaces` | `string[]` | 此模型所取代的旧 provider 本地模型 id。 |
| `replacedBy` | `string` | 已弃用的替代 provider 本地模型 id。 |
| `tags` | `string[]` | 供选择器和筛选器使用的稳定标签。 |
| `status` | `"available"` \| `"preview"` \| `"deprecated"` \| `"disabled"` | 列表状态。仅当某条目绝不能出现时才使用 suppress。 |
| `statusReason` | `string` | 在非可用状态下显示的可选原因。 |
| `replaces` | `string[]` | 该模型取代的旧 provider 本地模型 id。 |
| `replacedBy` | `string` | 已弃用条目的替代 provider 本地模型 id。 |
| `tags` | `string[]` | 供选择器和过滤器使用的稳定标签。 |
不要将仅运行时数据放入 `modelCatalog`。如果某个 provider 需要账户状态、API 请求或本地进程发现才能得知完整模型集,请在 `discovery` 中将该 provider 声明为 `refreshable``runtime`
不要将仅运行时数据放入 `modelCatalog`。如果某个 provider 需要账户
状态、API 请求或本地进程发现才能得知完整模型集合,
请在 `discovery` 中将该 provider 声明为 `refreshable``runtime`
### OpenClaw Provider Index
OpenClaw Provider Index 是由 OpenClaw 拥有的预览元数据,用于那些插件可能尚未安装的 providers。它不是插件清单的一部分。插件清单仍然是已安装插件的权威来源。Provider Index 是未来可安装 provider 和安装前模型选择器表面在 provider 插件尚未安装时所使用的内部回退合约。
OpenClaw Provider Index 是由 OpenClaw 拥有的预览元数据,适用于那些
插件可能尚未安装的 provider。它不是插件清单的一部分。
插件清单仍然是已安装插件的权威来源。Provider Index 是内部回退契约,
未来可安装 provider 和安装前模型选择器界面将在未安装 provider 插件时
使用它。
目录权威顺序:
1. 用户配置。
2. 已安装插件清单中的 `modelCatalog`
3. 通过显式刷新得的模型目录缓存。
4. OpenClaw Provider Index 预览
3. 通过显式刷新得的模型目录缓存。
4. OpenClaw Provider Index 预览条目
Provider Index 不得包含机密、启用状态、运行时 hooks或实时的账户专属模型数据。其预览目录使用与插件清单相同的 `modelCatalog` provider 行形状,但除非有意与已安装插件清单保持一致,否则应限制为稳定显示元数据,而不要包含诸如 `api`、`baseUrl`、定价或兼容性标志之类的运行时适配器字段。对于带有实时 `/models` 发现的 providers应通过显式模型目录缓存路径写入刷新后的行而不是让常规列表或 onboarding 去调用 provider API。
Provider Index 不得包含密钥、启用状态、运行时钩子
或与实际账户相关的在线模型数据。它的预览目录使用与插件清单
相同的 `modelCatalog` provider 条目结构,但应仅限于稳定显示元数据,
除非有意让 `api`
`baseUrl`、定价或兼容性标志等运行时适配器字段与已安装插件清单保持一致。
对于具有在线 `/models` 发现能力的 provider应通过显式模型目录缓存路径
写入刷新后的条目,而不是在常规列表或新手引导期间调用 provider API。
对于那些其插件已移出核心或尚未安装的 providersProvider Index 条目也可以携带可安装插件元数据。此元数据遵循与渠道目录相同的模式包名、npm 安装规范、预期完整性以及轻量级认证选项标签足以展示一个可安装的设置选项。一旦插件安装完成其清单即成为权威Provider Index 中对应 provider 的条目将被忽略。
Provider Index 条目还可以携带适用于那些插件已移出核心
或尚未安装的 provider 的可安装插件元数据。此元数据遵循渠道目录模式:
package 名称、npm 安装规格、预期完整性以及轻量级认证选项标签
足以展示一个可安装的设置选项。一旦插件安装完成,
其清单将优先生效,而该 provider 的 Provider Index 条目会被忽略。
旧版顶层能力键已弃用。使用 `openclaw doctor --fix``speechProviders`、`realtimeTranscriptionProviders`、`realtimeVoiceProviders`、`mediaUnderstandingProviders`、`imageGenerationProviders`、`videoGenerationProviders`、`webFetchProviders` 和 `webSearchProviders` 移动到 `contracts` 下;常规清单加载不再将这些顶层字段视为能力归属。
旧版顶层能力键已弃用。使用 `openclaw doctor --fix`
`speechProviders`、`realtimeTranscriptionProviders`、
`realtimeVoiceProviders`、`mediaUnderstandingProviders`、
`imageGenerationProviders`、`videoGenerationProviders`、
`webFetchProviders``webSearchProviders`
移动到 `contracts` 下;常规
清单加载不再将这些顶层字段视为能力
归属。
## Manifest 与 `package.json`
## 清单与 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 字段
一些运行时前插件元数据有意放在 `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.commands` | 在渠道运行时加载前,由配置、审计和命令列表面使用的静态原生命令和原生 Skills 自动默认元数据。 |
| `openclaw.channel.configuredState` | 轻量级已配置状态检查器元数据,可在不加载完整渠道运行时的情况下回答“是否已存在仅环境变量的设置?”。 |
| `openclaw.channel.persistedAuthState` | 轻量级持久化认证状态检查器元数据,可在不加载完整渠道运行时的情况下回答“是否已经有任何登录状态?”。 |
| `openclaw.install.npmSpec` / `openclaw.install.localPath` | 面向内置和外部发布插件的安装 / 更新提示。 |
| `openclaw.install.defaultChoice` | 当存在多个安装来源时的首选安装路径。 |
| `openclaw.extensions` | 声明原生插件入口点。必须保留在插件 package 目录内。 |
| `openclaw.runtimeExtensions` | 为已安装 package 声明已构建的 JavaScript 运行时入口点。必须保留在插件 package 目录内。 |
| `openclaw.setupEntry` | 在新手引导、延迟渠道启动和只读渠道 Status / SecretRef 设备发现期间使用的轻量级仅设置入口点。必须保留在插件 package 目录内。 |
| `openclaw.runtimeSetupEntry` | 为已安装 package 声明已构建的 JavaScript 设置入口点。必须保留在插件 package 目录内。 |
| `openclaw.channel` | 轻量级渠道目录元数据,例如标签、文档路径、别名和选择说明文本。 |
| `openclaw.channel.commands` | 在渠道运行时加载前,由配置、审计和命令列表面使用的静态原生命令和原生 Skills 自动默认元数据。 |
| `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` | 允许在启动期间于完整渠道插件之前加载仅设置用的渠道表面。 |
| `openclaw.install.expectedIntegrity` | 预期的 npm 分发完整性字符串,例如 `sha512-...`;安装和更新流程会据此校验获取的制品。 |
| `openclaw.install.allowInvalidConfigRecovery` | 当配置无效时,允许狭义的内置插件重新安装恢复路径。 |
| `openclaw.startup.deferConfiguredChannelFullLoadUntilAfterListen` | 允许仅设置用途的渠道界面在启动期间于完整渠道插件之前加载。 |
清单元数据决定在运行时加载前onboarding 中会出现哪些 provider / 渠道 / 设置选项。`package.json#openclaw.install` 则告诉 onboarding当用户选择这些选项之一时应如何获取或启用该插件。不要将安装提示移入 `openclaw.plugin.json`
清单元数据决定了在运行时加载前,
哪些 provider / channel / setup 选项会出现在新手引导中。`package.json#openclaw.install` 则告诉
新手引导,当用户选择其中某个选项时,
应如何获取或启用该插件。不要将安装提示移到 `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` 时,安装 / 更新流程会强制执行它;当省略时,注册表解析会被记录下来,但不会附带完整性固定。
`"npmSpec": "@wecom/wecom-openclaw-plugin@1.2.3"`。官方外部目录
条目应将精确 spec 与 `expectedIntegrity` 配对,这样如果获取到的 npm 制品
不再匹配固定版本,更新流程就会失败即关闭。
出于兼容性考虑,交互式新手引导仍会提供受信任注册表的 npm spec
包括裸 package 名称和 dist-tag。目录诊断可以
区分精确、浮动、带完整性固定、缺少完整性、package 名称不匹配
以及无效默认选项来源。它们还会在
存在 `expectedIntegrity` 但没有可用于固定它的有效 npm 来源时发出警告。
当存在 `expectedIntegrity` 时,
安装 / 更新流程会强制校验它;省略时,注册表解析结果
会被记录下来,但不带完整性固定。
当 Status、渠道列表或 SecretRef 扫描需要在不加载完整运行时的情况下识别已配置账户时,渠道插件应提供 `openclaw.setupEntry`。该设置入口应公开渠道元数据以及适用于设置的配置、Status 和密钥适配器请将网络客户端、Gateway 网关监听器和传输运行时保留在主扩展入口点中。
当 Status、渠道列表
或 SecretRef 扫描需要在不加载完整运行时的情况下识别已配置账户时,渠道插件应提供 `openclaw.setupEntry`
该设置入口点应暴露渠道元数据以及适用于设置场景的配置、
Status 和密钥适配器请将网络客户端、Gateway 网关监听器
和传输运行时保留在主扩展入口点中。
运行时入口点字段不会覆盖源入口点字段的包边界检查。例如,`openclaw.runtimeExtensions` 不能让一个越界的 `openclaw.extensions` 路径变得可加载。
运行时入口点字段不会覆盖针对源代码
入口点字段的 package 边界检查。例如,`openclaw.runtimeExtensions` 不能让一个
越界的 `openclaw.extensions` 路径变得可加载。
`openclaw.install.allowInvalidConfigRecovery` 的设计范围是有意收窄的。它不会让任意损坏的配置都能被安装。当前它仅允许安装流程从特定的陈旧内置插件升级失败中恢复,例如缺失的内置插件路径,或该同一内置插件的陈旧 `channels.<id>` 条目。无关的配置错误仍会阻止安装,并将操作员引导至 `openclaw doctor --fix`
`openclaw.install.allowInvalidConfigRecovery` 被有意保持为狭义能力。它
不会让任意损坏配置都变得可安装。目前它只允许安装流程
从特定的过期内置插件升级失败中恢复,例如
缺失的内置插件路径,或同一个内置插件对应的陈旧 `channels.<id>` 条目。
无关的配置错误仍会阻止安装,并引导操作人员
运行 `openclaw doctor --fix`
`openclaw.channel.persistedAuthState` 是一个微型检查器模块的包元数据:
`openclaw.channel.persistedAuthState` 是一个微型检查器
模块的 package 元数据:
```json
{
@ -718,9 +873,13 @@ Provider Index 不得包含机密、启用状态、运行时 hooks或实时
}
```
当设置、Doctor 或已配置状态流程需要在完整渠道插件加载前执行轻量级的“是 / 否”认证探测时,请使用它。目标导出应是一个仅读取持久化状态的小函数;不要通过完整渠道运行时 barrel 来路由它。
当设置、Doctor 或 configured-state 流程需要在完整渠道插件加载前进行一个
低成本的是否已认证探测时,请使用它。目标导出应是一个仅
读取持久化状态的小函数;不要通过完整的
渠道运行时 barrel 转发它。
`openclaw.channel.configuredState` 对轻量级的仅环境变量已配置检查采用相同结构:
`openclaw.channel.configuredState` 采用相同结构,用于低成本的仅环境变量
configured 检查:
```json
{
@ -736,51 +895,57 @@ Provider Index 不得包含机密、启用状态、运行时 hooks或实时
}
```
当某个渠道可以根据环境变量或其他微型的非运行时输入来判断已配置状态时,请使用它。如果检查需要完整配置解析或真实的渠道运行时,请将该逻辑保留在插件 `config.hasConfiguredState` hook 中。
当某个渠道可以通过环境变量或其他微型
非运行时输入来回答 configured-state 时,请使用它。如果检查需要完整配置解析或真实
渠道运行时,请将该逻辑保留在插件 `config.hasConfiguredState`
钩子中。
## 发现优先级(重复插件 id
## 设备发现优先级(重复插件 id
OpenClaw 会从多个根位置发现插件(内置、全局安装、工作区、配置中显式选择的路径)。如果两个发现结果共享同一个 `id`,则只保留**优先级最高**的清单;较低优先级的重复项会被丢弃,而不是与其并列加载。
OpenClaw 会从多个根目录发现插件(内置、全局安装、工作区、显式由配置选择的路径)。如果两个发现结果共享相同的 `id`,则只保留**优先级最高**的清单;优先级较低的重复项会被丢弃,而不是与其一起加载。
优先级从高到低如下
优先级从高到低:
1. **配置选定** —— 在 `plugins.entries.<id>` 中显式固定的路径
2. **内置** —— 随 OpenClaw 一提供的插件
1. **由配置选择** —— 在 `plugins.entries.<id>` 中显式固定的路径
2. **内置** —— 随 OpenClaw 一提供的插件
3. **全局安装** —— 安装到全局 OpenClaw 插件根目录中的插件
4. **工作区** —— 相对于当前工作区发现的插件
影响:
- 位于工作区中的某个内置插件的分支或陈旧副本,不会遮蔽内置构建版本
- 若要真正用本地插件覆盖内置插件,请通过 `plugins.entries.<id>` 固定它,使其按优先级获胜,而不是依赖工作区发现。
- 被丢弃的重复项会被记录,以便 Doctor 和启动诊断能够指向被舍弃的副本。
- 位于工作区中的某个内置插件分支或过期副本不会遮蔽内置构建
- 如果你确实要用本地插件覆盖内置插件,请通过 `plugins.entries.<id>` 固定它,让它凭优先级获胜,而不是依赖工作区发现。
- 被丢弃的重复项会记录到日志中,以便 Doctor 和启动诊断指出被舍弃的副本。
## JSON Schema 要求
- **每个插件都必须提供一个 JSON Schema**,即使它不接受任何配置。
- 空 schema 是可接受的(例如,`{ "type": "object", "additionalProperties": false }`)。
- schema 在配置读取 / 写入时验证,而不是在运行时验证。
- 可以接受空 schema例如 `{ "type": "object", "additionalProperties": false }`)。
- Schema 会在配置读写时验证,而不是在运行时验证。
## 验证行为
- 未知的 `channels.*` 键是**错误**,除非该渠道 id 由某个插件清单声明。
- 未知的 `channels.*` 键是**错误**,除非该渠道 id 已由
某个插件清单声明。
- `plugins.entries.<id>`、`plugins.allow`、`plugins.deny` 和 `plugins.slots.*`
必须引用**可发现的**插件 id。未知 id 是**错误**。
- 如果某个插件已安装,但其清单或 schema 缺失或损坏验证会失败Doctor 会报告该插件错误。
- 如果插件配置存在,但插件被**禁用**,该配置会被保留,并且在 Doctor + 日志中显示**警告**。
- 如果某个插件已安装,但其清单或 schema 损坏或缺失,
验证会失败Doctor 会报告该插件错误。
- 如果插件配置存在,但插件已**禁用**,则配置会被保留,并且
Doctor + 日志中会显示一条**警告**。
完整的 `plugins.*` schema 请参阅 [配置参考](/zh-CN/gateway/configuration)。
有关完整 `plugins.*` schema请参见 [配置参考](/zh-CN/gateway/configuration)。
## 说明
## 注意事项
- 对于**原生 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)。
- 对于原生 OpenClaw 插件,清单是**必需的**,包括本地文件系统加载的插件。运行时仍会单独加载插件模块;清单仅用于设备发现 + 验证。
- 原生清单使用 JSON5 解析,因此支持注释、尾随逗号和未加引号的键,只要最终值仍然是一个对象即可。
- 清单加载器只会读取已文档化的清单字段。避免使用自定义顶层键。
- 当插件不需要它们时,可以省略 `channels`、`providers`、`cliBackends` 和 `skills`
- `providerDiscoveryEntry` 必须保持轻量,不应导入宽泛的运行时代码;应将其用于静态 provider 目录元数据或窄范围发现描述符,而不是请求时执行。
- 互斥插件种类通过 `plugins.slots.*` 选择:`kind: "memory"` 通过 `plugins.slots.memory` 选择`kind: "context-engine"` 通过 `plugins.slots.contextEngine` 选择(默认值为 `legacy`)。
- 环境变量元数据(`setup.providers[].envVars`、已弃用的 `providerAuthEnvVars` 以及 `channelEnvVars`仅是声明式信息。Status、审计、cron 投递验证和其他只读界面在将某个环境变量视为已配置之前,仍会应用插件信任和生效激活策略。
- 关于需要 provider 代码的运行时向导元数据,请参见 [Provider 运行时钩子](/zh-CN/plugins/architecture-internals#provider-runtime-hooks)。
- 如果你的插件依赖原生模块,请记录构建步骤以及任何包管理器允许列表要求(例如 pnpm `allow-build-scripts` + `pnpm rebuild <package>`)。
## 相关内容
@ -792,7 +957,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>

View File

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

View File

@ -1,19 +1,19 @@
---
read_when:
- 你想通过 LM Studio 使用开源模型运行 OpenClaw
- 你想设置并配置 LM Studio
- 你想通过 LM Studio 使用开源模型运行 OpenClaw
- 你想设置并配置 LM Studio
summary: 使用 LM Studio 运行 OpenClaw
title: LM Studio
x-i18n:
generated_at: "2026-04-27T07:21:11Z"
generated_at: "2026-04-27T08:01:18Z"
model: gpt-5.4
provider: openai
source_hash: 0077108b7ab3171084f89234e25f5f5e8b68239a6fa6c11fa70c65f52d56670f
source_hash: 98edefa8b57ab2a89d1c4405827335a421c3157f51c5d23ac5f83c1cbeab20a9
source_path: providers/lmstudio.md
workflow: 15
---
LM Studio 是一款对用户友好且功能强大的应用,可让你在自己的硬件上运行开放权重模型。它支持运行 llama.cppGGUF或 MLX 模型Apple Silicon提供 GUI 安装包,也提供无头守护进程(`llmster`)。产品和设置文档请参阅 [lmstudio.ai](https://lmstudio.ai/)。
LM Studio 是一款友好且功能强大的应用,可让你在自己的硬件上运行开放权重模型。它支持运行 llama.cppGGUF或 MLX 模型Apple Silicon既提供 GUI 应用,也提供无头守护进程(`llmster`)。产品和设置文档请参见 [lmstudio.ai](https://lmstudio.ai/)。
## 快速开始
@ -25,7 +25,7 @@ curl -fsSL https://lmstudio.ai/install.sh | bash
2. 启动服务器
确保你已启动桌面应用,或使用以下命令运行守护进程:
确保你已启动桌面应用,或使用以下命令运行守护进程:
```bash
lms daemon up
@ -35,17 +35,17 @@ lms daemon up
lms server start --port 1234
```
如果你使用的是应用,请确保已启用 JIT以获得流畅的体验。详情请参阅 [LM Studio JIT and TTL guide](https://lmstudio.ai/docs/developer/core/ttl-and-auto-evict)。
如果你使用的是应用,请确保已启用 JIT以获得更流畅的体验。更多信息请参见 [LM Studio JIT and TTL guide](https://lmstudio.ai/docs/developer/core/ttl-and-auto-evict)。
3. 如果已启用 LM Studio 身份验证,请设置 `LM_API_TOKEN`
3. 如果已启用 LM Studio 证,请设置 `LM_API_TOKEN`
```bash
export LM_API_TOKEN="your-lm-studio-api-token"
```
如果 LM Studio 身份验证已禁用,你可以在交互式 OpenClaw 设置期间将 API 密钥留空。
如果 LM Studio 认证已禁用,则在交互式 OpenClaw 设置期间,你可以将 API 密钥留空。
有关 LM Studio 身份验证设置的详细信息,请参阅 [LM Studio Authentication](https://lmstudio.ai/docs/developer/core/authentication)。
有关 LM Studio 认证设置的详细信息,请参见 [LM Studio Authentication](https://lmstudio.ai/docs/developer/core/authentication)。
4. 运行新手引导并选择 `LM Studio`
@ -61,11 +61,12 @@ openclaw onboard
openclaw models set lmstudio/qwen/qwen3.5-9b
```
LM Studio 模型键遵循 `author/model-name` 格式(例如 `qwen/qwen3.5-9b`。OpenClaw 模型引用会在前面加上提供商名称:`lmstudio/qwen/qwen3.5-9b`。你可以运行 `curl http://localhost:1234/api/v1/models` 并查看 `key` 字段,以找到某个模型的准确键名。
LM Studio 模型键采用 `author/model-name` 格式(例如 `qwen/qwen3.5-9b`。OpenClaw
模型引用会加上提供商名前缀:`lmstudio/qwen/qwen3.5-9b`。你可以通过运行 `curl http://localhost:1234/api/v1/models` 并查看 `key` 字段,找到某个模型的精确键名。
## 非交互式新手引导
当你想通过脚本完成设置时CI、预配、远程引导),请使用非交互式新手引导:
如果你想通过脚本完成设置CI、预配、远程引导初始化),请使用非交互式新手引导:
```bash
openclaw onboard \
@ -74,7 +75,7 @@ openclaw onboard \
--auth-choice lmstudio
```
或者指定基础 URL、模型和可选的 API 密钥:
或者指定 base URL、模型和可选 API 密钥:
```bash
openclaw onboard \
@ -86,28 +87,30 @@ openclaw onboard \
--custom-model-id qwen/qwen3.5-9b
```
`--custom-model-id` 接受 LM Studio 返回的模型键(例如 `qwen/qwen3.5-9b`),不包含 `lmstudio/` 提供商前缀。
`--custom-model-id` 接收 LM Studio 返回的模型键(例如 `qwen/qwen3.5-9b`),不包含
`lmstudio/` 提供商前缀。
对于启用了身份验证的 LM Studio 服务器,请传入 `--lmstudio-api-key` 或设置 `LM_API_TOKEN`
对于未启用身份验证的 LM Studio 服务器请省略该密钥OpenClaw 会存储一个本地非机密标记。
对于启用了证的 LM Studio 服务器,请传入 `--lmstudio-api-key` 或设置 `LM_API_TOKEN`
对于未启用证的 LM Studio 服务器请省略该密钥OpenClaw 会存储一个本地非机密标记。
出于兼容性考虑,`--custom-api-key` 仍然受支持,但对于 LM Studio优先使用 `--lmstudio-api-key`
`--custom-api-key` 仍然支持以保持兼容性,但对于 LM Studio更推荐使用 `--lmstudio-api-key`
这会写入 `models.providers.lmstudio`,并将默认模型设置为
`lmstudio/<custom-model-id>`。当你提供 API 密钥时,设置还会写入
`lmstudio:default` 身份验证配置文件。
`lmstudio:default` 证配置文件。
交互式设置可以提示输入一个可选的首选加载上下文长度,并将其应用到发现到的、保存进配置中的所有 LM Studio 模型。
交互式设置可以提示输入一个可选的首选加载上下文长度,并将其应用到保存进配置中的已发现 LM Studio 模型。
LM Studio 插件配置会信任为模型请求所配置的 LM Studio 端点,包括 loopback、LAN 和 tailnet 主机。你可以通过设置 `models.providers.lmstudio.request.allowPrivateNetwork: false` 选择退出。
## 配置
### 流式传输用量兼容性
### 流式传输 usage 兼容性
LM Studio 兼容流式传输用量统计。当它没有输出符合 OpenAI 形状的
LM Studio 与流式 usage 兼容。当它未发出 OpenAI 形状的
`usage` 对象时OpenClaw 会改为从 llama.cpp 风格的
`timings.prompt_n` / `timings.predicted_n` 元数据中恢复 token 计数。
同行为也适用于这些兼容 OpenAI 的本地后端:
样的行为也适用于这些兼容 OpenAI 的本地后端:
- vLLM
- SGLang
@ -148,30 +151,51 @@ LM Studio 兼容流式传输用量统计。当它没有输出符合 OpenAI 形
### 未检测到 LM Studio
请确认 LM Studio 正在运行。如果已启用身份验证,还要设置 `LM_API_TOKEN`
请确保 LM Studio 正在运行。如果启用了认证,还要设置 `LM_API_TOKEN`
```bash
# 通过桌面应用启动,或以无头方式启动:
lms server start --port 1234
```
确认 API 可访问:
验证 API 是否可访问:
```bash
curl http://localhost:1234/api/v1/models
```
### 身份验证错误HTTP 401
### 证错误HTTP 401
如果设置报告 HTTP 401请验证你的 API 密钥:
- 检查 `LM_API_TOKEN` 是否与 LM Studio 中配置的密钥匹配
- 有关 LM Studio 身份验证设置的详细信息,请参阅 [LM Studio Authentication](https://lmstudio.ai/docs/developer/core/authentication)。
- 如果你的服务器不需要身份验证,请在设置期间将密钥留空。
- 检查 `LM_API_TOKEN` 是否与你在 LM Studio 中配置的密钥一致
- 有关 LM Studio 认证设置的详细信息,请参见 [LM Studio Authentication](https://lmstudio.ai/docs/developer/core/authentication)。
- 如果你的服务器不要求认证,请在设置期间将密钥留空。
### 即时模型加载
LM Studio 支持即时JIT模型加载即模型会在第一次请求时加载。请确保已启用此功能以避免出现“Model not loaded”错误。
LM Studio 支持即时JIT模型加载即模型会在首次请求时加载。请确保已启用此功能以避免出现“Model not loaded”错误。
### LAN 或 tailnet LM Studio 主机
请使用 LM Studio 主机的可访问地址,保留 `/v1`,并确保该机器上的 LM Studio 绑定到了 loopback 之外的地址:
```json5
{
models: {
providers: {
lmstudio: {
baseUrl: "http://gpu-box.local:1234/v1",
apiKey: "lmstudio",
api: "openai-completions",
models: [{ id: "qwen/qwen3.5-9b" }],
},
},
},
}
```
与通用的兼容 OpenAI 提供商不同,`lmstudio` 会自动信任其为受保护模型请求所配置的本地/私有端点。如果你使用的是自定义提供商 id 而不是 `lmstudio`,请显式设置 `models.providers.<id>.request.allowPrivateNetwork: true`
## 相关内容