chore(i18n): refresh zh-CN translations
This commit is contained in:
parent
cd7fcb49ee
commit
2c35fa34b8
@ -1,24 +1,24 @@
|
||||
---
|
||||
read_when:
|
||||
- 你想以非交互方式读取或编辑配置
|
||||
- 你想以非交互方式读取或编辑配置。
|
||||
summary: '`openclaw config` 的 CLI 参考(get/set/unset/file/schema/validate)'
|
||||
title: 配置
|
||||
x-i18n:
|
||||
generated_at: "2026-04-25T03:24:47Z"
|
||||
generated_at: "2026-04-25T04:54:56Z"
|
||||
model: gpt-5.4
|
||||
provider: openai
|
||||
source_hash: 1b8d5466d875967b6c9d5bf451f6affbe969d0ba5a48b98ee282612be67128db
|
||||
source_hash: 60935e011a72e08c47dc21a634a78ce11edf261ff9896009519dc4e04561f465
|
||||
source_path: cli/config.md
|
||||
workflow: 15
|
||||
---
|
||||
|
||||
# `openclaw config`
|
||||
|
||||
用于在 `openclaw.json` 中进行非交互式编辑的配置辅助命令:按路径获取/设置/取消设置/输出文件/输出 schema/校验值,并打印当前生效的配置文件。不带子命令运行时,会打开配置向导(与 `openclaw configure` 相同)。
|
||||
用于在 `openclaw.json` 中进行非交互式编辑的配置辅助命令:按路径 get/set/unset/file/schema/validate 值,并打印当前激活的配置文件。不带子命令运行时,会打开配置向导(与 `openclaw configure` 相同)。
|
||||
|
||||
根选项:
|
||||
|
||||
- `--section <section>`:当你运行不带子命令的 `openclaw config` 时,可重复使用的引导式设置分区过滤器
|
||||
- `--section <section>`:当你在不带子命令的情况下运行 `openclaw config` 时,可重复使用的引导式设置分区过滤器
|
||||
|
||||
支持的引导分区:
|
||||
|
||||
@ -41,6 +41,7 @@ openclaw config --section gateway --section daemon
|
||||
openclaw config schema
|
||||
openclaw config get browser.executablePath
|
||||
openclaw config set browser.executablePath "/usr/bin/google-chrome"
|
||||
openclaw config set browser.profiles.work.executablePath "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome"
|
||||
openclaw config set agents.defaults.heartbeat.every "2h"
|
||||
openclaw config set agents.list[0].tools.exec.node "node-id-or-name"
|
||||
openclaw config set agents.defaults.models '{"openai/gpt-5.4":{}}' --strict-json --merge
|
||||
@ -54,26 +55,26 @@ openclaw config validate --json
|
||||
|
||||
### `config schema`
|
||||
|
||||
将 `openclaw.json` 的生成式 JSON schema 以 JSON 形式打印到 stdout。
|
||||
将 `openclaw.json` 的生成 JSON schema 以 JSON 形式打印到 stdout。
|
||||
|
||||
包含内容:
|
||||
它包含的内容:
|
||||
|
||||
- 当前的根配置 schema,以及一个用于编辑器工具的根级 `$schema` 字符串字段
|
||||
- 当前的根配置 schema,以及一个用于编辑器工具的根 `$schema` 字符串字段
|
||||
- Control UI 使用的字段 `title` 和 `description` 文档元数据
|
||||
- 当存在匹配字段文档时,嵌套对象、通配符(`*`)和数组项(`[]`)节点会继承相同的 `title` / `description` 元数据
|
||||
- 当存在匹配字段文档时,`anyOf` / `oneOf` / `allOf` 分支也会继承相同的文档元数据
|
||||
- 当能够加载运行时清单时,尽力提供实时的插件 + 渠道 schema 元数据
|
||||
- 当存在匹配的字段文档时,嵌套对象、通配符(`*`)和数组项(`[]`)节点会继承相同的 `title` / `description` 元数据
|
||||
- 当存在匹配的字段文档时,`anyOf` / `oneOf` / `allOf` 分支也会继承相同的文档元数据
|
||||
- 当可以加载运行时清单时,尽力提供实时插件和渠道 schema 元数据
|
||||
- 即使当前配置无效,也会提供一个干净的后备 schema
|
||||
|
||||
相关运行时 RPC:
|
||||
|
||||
- `config.schema.lookup` 会返回一个规范化的配置路径,以及一个浅层 schema 节点(`title`、`description`、`type`、`enum`、`const`、常见边界)、匹配的 UI 提示元数据和直接子项摘要。可将其用于 Control UI 或自定义客户端中的路径范围下钻。
|
||||
- `config.schema.lookup` 会返回一个标准化的配置路径,以及一个浅层 schema 节点(`title`、`description`、`type`、`enum`、`const`、常见边界)、匹配的 UI 提示元数据和直接子项摘要。可将其用于 Control UI 或自定义客户端中的按路径范围逐层钻取。
|
||||
|
||||
```bash
|
||||
openclaw config schema
|
||||
```
|
||||
|
||||
当你想用其他工具检查或校验它时,可将其输出到文件:
|
||||
当你想用其他工具检查或验证它时,可以将其输出到文件:
|
||||
|
||||
```bash
|
||||
openclaw config schema > openclaw.schema.json
|
||||
@ -81,7 +82,7 @@ openclaw config schema > openclaw.schema.json
|
||||
|
||||
### 路径
|
||||
|
||||
路径使用点表示法或方括号表示法:
|
||||
路径使用点号或方括号表示法:
|
||||
|
||||
```bash
|
||||
openclaw config get agents.defaults.workspace
|
||||
@ -97,7 +98,7 @@ openclaw config set agents.list[1].tools.exec.node "node-id-or-name"
|
||||
|
||||
## 值
|
||||
|
||||
值会尽可能按 JSON5 解析;否则会被视为字符串。使用 `--strict-json` 可强制要求进行 JSON5 解析。`--json` 仍然支持作为旧版别名。
|
||||
值会尽可能按 JSON5 解析;否则会被视为字符串。使用 `--strict-json` 可强制要求进行 JSON5 解析。`--json` 仍然作为旧别名受支持。
|
||||
|
||||
```bash
|
||||
openclaw config set agents.defaults.heartbeat.every "0m"
|
||||
@ -107,7 +108,7 @@ openclaw config set channels.whatsapp.groups '["*"]' --strict-json
|
||||
|
||||
`config get <path> --json` 会将原始值以 JSON 形式打印,而不是终端格式化文本。
|
||||
|
||||
对象赋值默认会替换目标路径。对于通常存放用户新增条目的受保护映射/列表路径,例如 `agents.defaults.models`、`models.providers`、`models.providers.<id>.models`、`plugins.entries` 和 `auth.profiles`,如果替换会移除现有条目,则会拒绝,除非你传入 `--replace`。
|
||||
对象赋值默认会替换目标路径。对那些通常保存用户添加条目的受保护映射/列表路径,例如 `agents.defaults.models`、`models.providers`、`models.providers.<id>.models`、`plugins.entries` 和 `auth.profiles`,如果替换会移除现有条目,则会拒绝,除非你传入 `--replace`。
|
||||
|
||||
向这些映射中添加条目时,请使用 `--merge`:
|
||||
|
||||
@ -116,7 +117,7 @@ openclaw config set agents.defaults.models '{"openai/gpt-5.4":{}}' --strict-json
|
||||
openclaw config set models.providers.ollama.models '[{"id":"llama3.2","name":"Llama 3.2"}]' --strict-json --merge
|
||||
```
|
||||
|
||||
仅当你明确希望提供的值成为完整目标值时,才使用 `--replace`。
|
||||
仅当你明确希望所提供的值成为完整目标值时,才使用 `--replace`。
|
||||
|
||||
## `config set` 模式
|
||||
|
||||
@ -132,7 +133,7 @@ openclaw config set channels.discord.token \
|
||||
--ref-id DISCORD_BOT_TOKEN
|
||||
```
|
||||
|
||||
3. 提供商构建器模式(仅限 `secrets.providers.<alias>` 路径):
|
||||
3. provider 构建器模式(仅限 `secrets.providers.<alias>` 路径):
|
||||
|
||||
```bash
|
||||
openclaw config set secrets.providers.vault \
|
||||
@ -164,12 +165,12 @@ openclaw config set --batch-file ./config-set.batch.json --dry-run
|
||||
|
||||
策略说明:
|
||||
|
||||
- 在不支持运行时可变的目标面上,SecretRef 赋值会被拒绝(例如 `hooks.token`、`commands.ownerDisplaySecret`、Discord 线程绑定 webhook token,以及 WhatsApp creds JSON)。参见 [SecretRef 凭证目标面](/zh-CN/reference/secretref-credential-surface)。
|
||||
- 在不支持运行时可变更的表面上,SecretRef 赋值会被拒绝(例如 `hooks.token`、`commands.ownerDisplaySecret`、Discord 线程绑定 webhook token,以及 WhatsApp 凭据 JSON)。参见 [SecretRef 凭据表面](/zh-CN/reference/secretref-credential-surface)。
|
||||
|
||||
批量解析始终将批量负载(`--batch-json`/`--batch-file`)作为事实来源。
|
||||
`--strict-json` / `--json` 不会改变批量解析行为。
|
||||
|
||||
JSON 路径/值模式同样支持 SecretRef 和提供商:
|
||||
JSON 路径/值模式对 SecretRefs 和 providers 仍然受支持:
|
||||
|
||||
```bash
|
||||
openclaw config set channels.discord.token \
|
||||
@ -181,29 +182,29 @@ openclaw config set secrets.providers.vaultfile \
|
||||
--strict-json
|
||||
```
|
||||
|
||||
## 提供商构建器标志
|
||||
## Provider 构建器标志
|
||||
|
||||
提供商构建器目标路径必须使用 `secrets.providers.<alias>`。
|
||||
provider 构建器目标必须使用 `secrets.providers.<alias>` 作为路径。
|
||||
|
||||
通用标志:
|
||||
|
||||
- `--provider-source <env|file|exec>`
|
||||
- `--provider-timeout-ms <ms>`(`file`、`exec`)
|
||||
|
||||
环境提供商(`--provider-source env`):
|
||||
Env provider(`--provider-source env`):
|
||||
|
||||
- `--provider-allowlist <ENV_VAR>`(可重复)
|
||||
|
||||
文件提供商(`--provider-source file`):
|
||||
File provider(`--provider-source file`):
|
||||
|
||||
- `--provider-path <path>`(必填)
|
||||
- `--provider-path <path>`(必需)
|
||||
- `--provider-mode <singleValue|json>`
|
||||
- `--provider-max-bytes <bytes>`
|
||||
- `--provider-allow-insecure-path`
|
||||
|
||||
Exec 提供商(`--provider-source exec`):
|
||||
Exec provider(`--provider-source exec`):
|
||||
|
||||
- `--provider-command <path>`(必填)
|
||||
- `--provider-command <path>`(必需)
|
||||
- `--provider-arg <arg>`(可重复)
|
||||
- `--provider-no-output-timeout-ms <ms>`
|
||||
- `--provider-max-output-bytes <bytes>`
|
||||
@ -214,7 +215,7 @@ Exec 提供商(`--provider-source exec`):
|
||||
- `--provider-allow-insecure-path`
|
||||
- `--provider-allow-symlink-command`
|
||||
|
||||
强化型 Exec 提供商示例:
|
||||
强化型 exec provider 示例:
|
||||
|
||||
```bash
|
||||
openclaw config set secrets.providers.vault \
|
||||
@ -230,7 +231,7 @@ openclaw config set secrets.providers.vault \
|
||||
|
||||
## Dry run
|
||||
|
||||
使用 `--dry-run` 可在不写入 `openclaw.json` 的情况下校验变更。
|
||||
使用 `--dry-run` 可以在不写入 `openclaw.json` 的情况下验证变更。
|
||||
|
||||
```bash
|
||||
openclaw config set channels.discord.token \
|
||||
@ -256,22 +257,22 @@ openclaw config set channels.discord.token \
|
||||
|
||||
Dry-run 行为:
|
||||
|
||||
- 构建器模式:会对变更后的 ref/提供商运行 SecretRef 可解析性检查。
|
||||
- JSON 模式(`--strict-json`、`--json` 或批量模式):会运行 schema 校验以及 SecretRef 可解析性检查。
|
||||
- 对于已知不支持的 SecretRef 目标面,也会运行策略校验。
|
||||
- 策略检查会评估变更后的完整配置,因此父对象写入(例如将 `hooks` 设为对象)无法绕过不支持目标面的校验。
|
||||
- 为避免命令副作用,dry-run 期间默认会跳过 Exec SecretRef 检查。
|
||||
- 使用 `--allow-exec` 配合 `--dry-run` 可选择启用 Exec SecretRef 检查(这可能会执行提供商命令)。
|
||||
- `--allow-exec` 仅用于 dry-run;如果不带 `--dry-run` 使用会报错。
|
||||
- 构建器模式:对已更改的 refs/providers 运行 SecretRef 可解析性检查。
|
||||
- JSON 模式(`--strict-json`、`--json` 或批量模式):运行 schema 验证以及 SecretRef 可解析性检查。
|
||||
- 已知不支持的 SecretRef 目标表面也会运行策略验证。
|
||||
- 策略检查会评估变更后的完整配置,因此对父对象的写入(例如将 `hooks` 设为对象)无法绕过不支持表面的验证。
|
||||
- 为避免命令副作用,dry-run 期间默认跳过 exec SecretRef 检查。
|
||||
- 将 `--allow-exec` 与 `--dry-run` 一起使用,可选择启用 exec SecretRef 检查(这可能会执行 provider 命令)。
|
||||
- `--allow-exec` 仅用于 dry-run;如果未与 `--dry-run` 一起使用会报错。
|
||||
|
||||
`--dry-run --json` 会打印机器可读报告:
|
||||
|
||||
- `ok`:dry-run 是否通过
|
||||
- `operations`:已评估的赋值数量
|
||||
- `checks`:是否运行了 schema/可解析性检查
|
||||
- `checks.resolvabilityComplete`:可解析性检查是否完整运行结束(当跳过 exec ref 时为 false)
|
||||
- `checks.resolvabilityComplete`:可解析性检查是否完整运行结束(当 exec refs 被跳过时为 false)
|
||||
- `refsChecked`:dry-run 期间实际解析的 ref 数量
|
||||
- `skippedExecRefs`:因未设置 `--allow-exec` 而跳过的 exec ref 数量
|
||||
- `skippedExecRefs`:由于未设置 `--allow-exec` 而被跳过的 exec ref 数量
|
||||
- `errors`:当 `ok=false` 时的结构化 schema/可解析性失败信息
|
||||
|
||||
### JSON 输出结构
|
||||
@ -293,7 +294,7 @@ Dry-run 行为:
|
||||
{
|
||||
kind: "schema" | "resolvability",
|
||||
message: string,
|
||||
ref?: string, // 用于可解析性错误时会出现
|
||||
ref?: string, // 对于可解析性错误会出现
|
||||
},
|
||||
],
|
||||
}
|
||||
@ -344,18 +345,18 @@ Dry-run 行为:
|
||||
|
||||
如果 dry-run 失败:
|
||||
|
||||
- `config schema validation failed`:变更后的配置结构无效;请修正路径/值或提供商/ref 对象结构。
|
||||
- `Config policy validation failed: unsupported SecretRef usage`:请将该凭证移回明文/字符串输入,并仅在受支持的目标面上使用 SecretRef。
|
||||
- `SecretRef assignment(s) could not be resolved`:被引用的提供商/ref 当前无法解析(缺少环境变量、文件指针无效、Exec 提供商失败,或提供商/source 不匹配)。
|
||||
- `Dry run note: skipped <n> exec SecretRef resolvability check(s)`:dry-run 跳过了 exec ref;如果你需要验证 exec 可解析性,请使用 `--allow-exec` 重新运行。
|
||||
- `config schema validation failed`:你变更后的配置结构无效;请修正路径/值或 provider/ref 对象结构。
|
||||
- `Config policy validation failed: unsupported SecretRef usage`:请将该凭据移回明文/字符串输入,并仅在受支持的表面上使用 SecretRefs。
|
||||
- `SecretRef assignment(s) could not be resolved`:当前无法解析所引用的 provider/ref(缺少环境变量、文件指针无效、exec provider 失败,或 provider/source 不匹配)。
|
||||
- `Dry run note: skipped <n> exec SecretRef resolvability check(s)`:dry-run 跳过了 exec refs;如果你需要验证 exec 可解析性,请使用 `--allow-exec` 重新运行。
|
||||
- 对于批量模式,请修复失败的条目,并在写入前重新运行 `--dry-run`。
|
||||
|
||||
## 写入安全
|
||||
|
||||
`openclaw config set` 和其他由 OpenClaw 管理的配置写入器,会在提交到磁盘之前校验变更后的完整配置。如果新负载未通过 schema 校验,或看起来像是破坏性覆盖,当前生效配置将保持不变,被拒绝的负载会以 `openclaw.json.rejected.*` 的形式保存在其旁边。
|
||||
当前生效的配置路径必须是普通文件。写入时不支持符号链接形式的 `openclaw.json` 布局;请改用 `OPENCLAW_CONFIG_PATH` 直接指向真实文件。
|
||||
`openclaw config set` 以及其他由 OpenClaw 拥有的配置写入器,会在提交到磁盘前验证完整的变更后配置。如果新的负载未通过 schema 验证,或者看起来像是破坏性覆盖,则当前活动配置会保持不变,并且被拒绝的负载会保存在其旁边,命名为 `openclaw.json.rejected.*`。
|
||||
活动配置路径必须是常规文件。对于写入操作,不支持符号链接形式的 `openclaw.json` 布局;请改用 `OPENCLAW_CONFIG_PATH` 直接指向真实文件。
|
||||
|
||||
对于小改动,优先使用 CLI 写入:
|
||||
对于小型编辑,优先使用 CLI 写入:
|
||||
|
||||
```bash
|
||||
openclaw config set gateway.reload.mode hybrid --dry-run
|
||||
@ -363,7 +364,7 @@ openclaw config set gateway.reload.mode hybrid
|
||||
openclaw config validate
|
||||
```
|
||||
|
||||
如果写入被拒绝,请检查保存下来的负载,并修复完整配置结构:
|
||||
如果写入被拒绝,请检查保存的负载并修复完整配置结构:
|
||||
|
||||
```bash
|
||||
CONFIG="$(openclaw config file)"
|
||||
@ -371,34 +372,34 @@ ls -lt "$CONFIG".rejected.* 2>/dev/null | head
|
||||
openclaw config validate
|
||||
```
|
||||
|
||||
仍然允许直接通过编辑器写入,但正在运行的 Gateway 网关会在通过校验前将这些更改视为不可信。无效的直接编辑可能会在启动或热重载期间,通过上一次已知有效的备份进行恢复。参见 [Gateway 网关故障排除](/zh-CN/gateway/troubleshooting#gateway-restored-last-known-good-config)。
|
||||
直接通过编辑器写入仍然是允许的,但正在运行的 Gateway 网关会在它们通过验证前将其视为不可信。在启动或热重载期间,无效的直接编辑可以从最后一个已知正常备份中恢复。参见 [Gateway 网关故障排除](/zh-CN/gateway/troubleshooting#gateway-restored-last-known-good-config)。
|
||||
|
||||
整文件恢复仅用于全局损坏的配置,例如解析错误、根级 schema 校验失败、旧版迁移失败,或插件与根配置混合失败。如果校验仅在 `plugins.entries.<id>...` 下失败,OpenClaw 会保留当前生效的 `openclaw.json`,并报告该插件的局部问题,而不是恢复 `.last-good`。这样可以防止插件 schema 变更或 `minHostVersion` 偏差回滚与你无关的用户设置,例如模型、提供商、auth 配置档、渠道、Gateway 网关暴露方式、工具、内存、浏览器或 cron 配置。
|
||||
整文件恢复仅保留给全局性损坏的配置,例如解析错误、根级 schema 失败、旧版迁移失败,或插件与根配置的混合失败。如果验证仅在 `plugins.entries.<id>...` 下失败,OpenClaw 会保持当前 `openclaw.json` 不变,并报告插件本地问题,而不是恢复 `.last-good`。这可以防止插件 schema 变更或 `minHostVersion` 偏差回滚与你无关的用户设置,例如模型、提供商、auth 配置文件、渠道、Gateway 网关暴露、工具、内存、浏览器或 cron 配置。
|
||||
|
||||
## 子命令
|
||||
|
||||
- `config file`:打印当前生效的配置文件路径(从 `OPENCLAW_CONFIG_PATH` 或默认位置解析)。该路径应指向普通文件,而不是符号链接。
|
||||
- `config file`:打印当前激活的配置文件路径(从 `OPENCLAW_CONFIG_PATH` 或默认位置解析)。该路径应指向常规文件,而不是符号链接。
|
||||
|
||||
编辑后请重启 Gateway 网关。
|
||||
编辑后请重启网关。
|
||||
|
||||
## 校验
|
||||
## 验证
|
||||
|
||||
在不启动 Gateway 网关的情况下,使用当前生效的 schema 校验当前配置。
|
||||
在不启动 Gateway 网关的情况下,根据当前激活的 schema 验证当前配置。
|
||||
|
||||
```bash
|
||||
openclaw config validate
|
||||
openclaw config validate --json
|
||||
```
|
||||
|
||||
当 `openclaw config validate` 通过后,你可以使用本地 TUI,让内嵌智能体在同一个终端中,一边校验每项更改,一边将当前生效配置与文档进行比较:
|
||||
在 `openclaw config validate` 通过后,你可以使用本地 TUI,让内嵌智能体在同一个终端中比较当前配置与文档,同时验证每一项更改:
|
||||
|
||||
如果当前校验已经失败,请先运行 `openclaw configure` 或 `openclaw doctor --fix`。`openclaw chat` 不会绕过无效配置保护。
|
||||
如果验证当前已经失败,请先使用 `openclaw configure` 或 `openclaw doctor --fix`。`openclaw chat` 不会绕过无效配置保护。
|
||||
|
||||
```bash
|
||||
openclaw chat
|
||||
```
|
||||
|
||||
然后在 TUI 中执行:
|
||||
然后在 TUI 内:
|
||||
|
||||
```text
|
||||
!openclaw config file
|
||||
@ -410,9 +411,9 @@ openclaw chat
|
||||
典型修复循环:
|
||||
|
||||
- 让智能体将你当前的配置与相关文档页面进行比较,并建议最小修复方案。
|
||||
- 使用 `openclaw config set` 或 `openclaw configure` 应用有针对性的修改。
|
||||
- 每次修改后重新运行 `openclaw config validate`。
|
||||
- 如果校验通过但运行时状态仍不健康,请运行 `openclaw doctor` 或 `openclaw doctor --fix` 获取迁移和修复帮助。
|
||||
- 使用 `openclaw config set` 或 `openclaw configure` 应用有针对性的编辑。
|
||||
- 每次更改后重新运行 `openclaw config validate`。
|
||||
- 如果验证通过,但运行时仍然不健康,请运行 `openclaw doctor` 或 `openclaw doctor --fix` 以获取迁移和修复帮助。
|
||||
|
||||
## 相关内容
|
||||
|
||||
|
||||
@ -2,20 +2,20 @@
|
||||
read_when:
|
||||
- 你使用语音通话插件,并且想了解 CLI 入口点
|
||||
- 你想查看 `voicecall setup|smoke|call|continue|dtmf|status|tail|expose` 的快速示例
|
||||
summary: '`openclaw voicecall` 的 CLI 参考(语音通话插件命令接口)'
|
||||
title: Voicecall
|
||||
summary: '`openclaw voicecall` 的 CLI 参考(语音通话插件命令界面)'
|
||||
title: 语音通话
|
||||
x-i18n:
|
||||
generated_at: "2026-04-25T02:35:33Z"
|
||||
generated_at: "2026-04-25T04:55:01Z"
|
||||
model: gpt-5.4
|
||||
provider: openai
|
||||
source_hash: ffed2f9f6edc989066a0b7d1e44752bf30a2356955db2577d350c60070b7b5f0
|
||||
source_hash: 7c8b83ef75f792920024a67b0dee1b07aff9f55486de1149266c6d94854ca0fe
|
||||
source_path: cli/voicecall.md
|
||||
workflow: 15
|
||||
---
|
||||
|
||||
# `openclaw voicecall`
|
||||
|
||||
`voicecall` 是一个由插件提供的命令。只有在语音通话插件已安装并启用时,它才会显示。
|
||||
`voicecall` 是一个由插件提供的命令。只有在安装并启用语音通话插件后,它才会显示。
|
||||
|
||||
主要文档:
|
||||
|
||||
@ -33,17 +33,19 @@ openclaw voicecall dtmf --call-id <id> --digits "ww123456#"
|
||||
openclaw voicecall end --call-id <id>
|
||||
```
|
||||
|
||||
默认情况下,`setup` 会输出便于阅读的就绪检查结果。对于脚本,请使用 `--json`:
|
||||
`setup` 默认会输出人类可读的就绪检查结果。对于脚本,请使用 `--json`:
|
||||
|
||||
```bash
|
||||
openclaw voicecall setup --json
|
||||
```
|
||||
|
||||
对于外部提供商(`twilio`、`telnyx`、`plivo`),设置必须从 `publicUrl`、隧道或 Tailscale 暴露中解析一个公开的 webhook URL。由于运营商无法访问,local loopback/私有服务的回退方案会被拒绝。
|
||||
|
||||
`smoke` 会运行相同的就绪检查。除非同时提供 `--to` 和 `--yes`,否则它不会拨打真实电话:
|
||||
|
||||
```bash
|
||||
openclaw voicecall smoke --to "+15555550123" # 试运行
|
||||
openclaw voicecall smoke --to "+15555550123" --yes # 实际 notify 呼叫
|
||||
openclaw voicecall smoke --to "+15555550123" --yes # 实际通知呼叫
|
||||
```
|
||||
|
||||
## 暴露 webhook(Tailscale)
|
||||
@ -54,7 +56,7 @@ openclaw voicecall expose --mode funnel
|
||||
openclaw voicecall expose --mode off
|
||||
```
|
||||
|
||||
安全注意事项:仅将 webhook 端点暴露给你信任的网络。尽可能优先使用 Tailscale Serve,而不是 Funnel。
|
||||
安全说明:只将 webhook 端点暴露给你信任的网络。条件允许时,优先使用 Tailscale Serve 而不是 Funnel。
|
||||
|
||||
## 相关内容
|
||||
|
||||
|
||||
@ -1,15 +1,15 @@
|
||||
---
|
||||
read_when:
|
||||
- 解释流式传输或分块处理如何在渠道中工作
|
||||
- 解释流式传输或分块处理在渠道上的工作方式
|
||||
- 更改分块流式传输或渠道分块处理行为
|
||||
- 调试重复或过早的分块回复或渠道预览流式传输
|
||||
- 调试重复或过早的分块回复,或渠道预览流式传输
|
||||
summary: 流式传输 + 分块处理行为(分块回复、渠道预览流式传输、模式映射)
|
||||
title: 流式传输和分块处理
|
||||
x-i18n:
|
||||
generated_at: "2026-04-25T04:09:43Z"
|
||||
generated_at: "2026-04-25T04:55:02Z"
|
||||
model: gpt-5.4
|
||||
provider: openai
|
||||
source_hash: 29faf5c6f39f4a9ebf149b94f5945bd1454b4d4112f557f5cb20b4f1c7f72346
|
||||
source_hash: 5e81bc00f1f34de53e1d98309f23c057274787693ea4a44ac27c2db38cfa5b5a
|
||||
source_path: concepts/streaming.md
|
||||
workflow: 15
|
||||
---
|
||||
@ -18,90 +18,96 @@ x-i18n:
|
||||
|
||||
OpenClaw 有两个独立的流式传输层:
|
||||
|
||||
- **分块流式传输(渠道):** 在助手写作时,按已完成的 **块** 发出。这些是正常的渠道消息(不是 token 增量)。
|
||||
- **预览流式传输(Telegram/Discord/Slack):** 在生成过程中更新临时的**预览消息**。
|
||||
- **分块流式传输(渠道):** 在助手写作时,随着完整的 **块** 完成而发出。这些是普通的渠道消息(不是 token 增量)。
|
||||
- **预览流式传输(Telegram/Discord/Slack):** 在生成过程中更新一个临时的 **预览消息**。
|
||||
|
||||
目前**没有真正的 token 增量流式传输**到渠道消息。预览流式传输是基于消息的(发送 + 编辑/追加)。
|
||||
目前,渠道消息 **没有真正的 token 增量流式传输**。预览流式传输是基于消息的(发送 + 编辑/追加)。
|
||||
|
||||
## 分块流式传输(渠道消息)
|
||||
|
||||
分块流式传输会在助手输出可用时,将其以较粗粒度的片段发送出去。
|
||||
分块流式传输会在助手输出可用时,以较粗粒度的块发送出去。
|
||||
|
||||
```
|
||||
Model output
|
||||
```text
|
||||
模型输出
|
||||
└─ text_delta/events
|
||||
├─ (blockStreamingBreak=text_end)
|
||||
│ └─ chunker emits blocks as buffer grows
|
||||
└─ (blockStreamingBreak=message_end)
|
||||
└─ chunker flushes at message_end
|
||||
└─ channel send (block replies)
|
||||
├─ (blockStreamingBreak=text_end)
|
||||
│ └─ 随着缓冲区增长,chunker 发出块
|
||||
└─ (blockStreamingBreak=message_end)
|
||||
└─ chunker 在 message_end 时刷新
|
||||
└─ 渠道发送(分块回复)
|
||||
```
|
||||
|
||||
图例:
|
||||
|
||||
- `text_delta/events`:模型流事件(对于非流式模型,可能很稀疏)。
|
||||
- `chunker`:应用最小/最大边界和断点偏好的 `EmbeddedBlockChunker`。
|
||||
- `channel send`:实际发出的消息(分块回复)。
|
||||
- `text_delta/events`:模型流事件(对于非流式模型,可能较为稀疏)。
|
||||
- `chunker`:应用最小/最大边界 + 断点偏好的 `EmbeddedBlockChunker`。
|
||||
- `channel send`:实际发出的出站消息(分块回复)。
|
||||
|
||||
**控制项:**
|
||||
|
||||
- `agents.defaults.blockStreamingDefault`:`"on"`/`"off"`(默认关闭)。
|
||||
- 渠道覆盖:`*.blockStreaming`(以及每账号变体)可按渠道强制设为 `"on"`/`"off"`。
|
||||
- 渠道覆盖:`*.blockStreaming`(以及每账户变体)可按渠道强制设为 `"on"`/`"off"`。
|
||||
- `agents.defaults.blockStreamingBreak`:`"text_end"` 或 `"message_end"`。
|
||||
- `agents.defaults.blockStreamingChunk`:`{ minChars, maxChars, breakPreference? }`。
|
||||
- `agents.defaults.blockStreamingCoalesce`:`{ minChars?, maxChars?, idleMs? }`(在发送前合并流式块)。
|
||||
- `agents.defaults.blockStreamingCoalesce`:`{ minChars?, maxChars?, idleMs? }`(发送前合并流式块)。
|
||||
- 渠道硬上限:`*.textChunkLimit`(例如 `channels.whatsapp.textChunkLimit`)。
|
||||
- 渠道分块模式:`*.chunkMode`(默认 `length`,`newline` 会先按空行即段落边界拆分,再按长度分块)。
|
||||
- Discord 软上限:`channels.discord.maxLinesPerMessage`(默认 17),用于拆分过高的回复以避免 UI 裁切。
|
||||
- 渠道分块模式:`*.chunkMode`(默认 `length`;`newline` 会先按空行,也就是段落边界拆分,再按长度分块)。
|
||||
- Discord 软上限:`channels.discord.maxLinesPerMessage`(默认 17),会拆分过高的回复以避免 UI 裁剪。
|
||||
|
||||
**边界语义:**
|
||||
|
||||
- `text_end`:只要 chunker 发出块就立即流式发送;每次 `text_end` 时刷新。
|
||||
- `message_end`:等助手消息完成后,再刷新缓冲的输出。
|
||||
- `text_end`:一旦 chunker 发出块就立即流式发送;每次 `text_end` 时刷新。
|
||||
- `message_end`:等待助手消息完成后,再刷新缓冲输出。
|
||||
|
||||
即使在 `message_end` 下,如果缓冲文本超过 `maxChars`,仍会使用 chunker,因此可以在结束时发出多个分块。
|
||||
即使使用 `message_end`,如果缓冲文本超过 `maxChars`,仍然会使用 chunker,因此它可能在结束时发出多个块。
|
||||
|
||||
## 分块算法(低/高边界)
|
||||
### 分块流式传输中的媒体投递
|
||||
|
||||
分块处理由 `EmbeddedBlockChunker` 实现:
|
||||
`MEDIA:` 指令是普通的投递元数据。当分块流式传输提前发送一个媒体块时,OpenClaw 会为当前轮次记住这次投递。如果最终的助手载荷重复包含相同的媒体 URL,最终投递会去掉重复媒体,而不是再次发送附件。
|
||||
|
||||
- **低边界:** 在缓冲区 >= `minChars` 之前不发出(除非强制)。
|
||||
- **高边界:** 优先在 `maxChars` 之前拆分;如果必须强制拆分,则在 `maxChars` 处切开。
|
||||
- **断点偏好:** `paragraph` → `newline` → `sentence` → `whitespace` → 硬拆分。
|
||||
- **代码围栏:** 绝不在围栏内部拆分;如果必须在 `maxChars` 处强制拆分,则会先关闭再重新打开围栏,以保持 Markdown 有效。
|
||||
完全重复的最终载荷会被抑制。如果最终载荷在已经流式发送过的媒体周围又增加了不同的文本,OpenClaw 仍然会发送这些新文本,同时保持媒体只投递一次。这样可以避免在 Telegram 等渠道中,当智能体在流式传输期间发出 `MEDIA:`,而提供商又在完整回复中再次包含它时,出现重复的语音消息或文件。
|
||||
|
||||
`maxChars` 会被限制到渠道的 `textChunkLimit`,因此你不能超过各渠道的上限。
|
||||
## 分块处理算法(低/高边界)
|
||||
|
||||
## 合并(合并流式块)
|
||||
块分块处理由 `EmbeddedBlockChunker` 实现:
|
||||
|
||||
启用分块流式传输时,OpenClaw 可以在发送前**合并连续的分块片段**。这样既能提供渐进式输出,又能减少“单行刷屏”。
|
||||
- **低边界:** 在缓冲区达到 `minChars` 之前不发出(除非被强制)。
|
||||
- **高边界:** 优先在 `maxChars` 之前拆分;如果被强制,则在 `maxChars` 处拆分。
|
||||
- **断点偏好:** `paragraph` → `newline` → `sentence` → `whitespace` → 硬断开。
|
||||
- **代码围栏:** 绝不在围栏内部拆分;如果必须在 `maxChars` 处强制拆分,会先关闭再重新打开围栏,以保持 Markdown 有效。
|
||||
|
||||
- 合并会等待**空闲间隔**(`idleMs`)后再刷新。
|
||||
`maxChars` 会被限制到渠道的 `textChunkLimit`,因此你不能超过每个渠道的上限。
|
||||
|
||||
## 聚合(合并流式块)
|
||||
|
||||
启用分块流式传输时,OpenClaw 可以在发送前 **合并连续的块分片**。这样既能提供渐进式输出,又能减少“单行刷屏”。
|
||||
|
||||
- 聚合会等待 **空闲间隔**(`idleMs`)后再刷新。
|
||||
- 缓冲区受 `maxChars` 限制,超出时会刷新。
|
||||
- `minChars` 会阻止过小片段发送,直到积累了足够文本(最终刷新总会发送剩余文本)。
|
||||
- `minChars` 会阻止过小的片段发送,直到累积到足够文本(最终刷新总会发送剩余文本)。
|
||||
- 连接符由 `blockStreamingChunk.breakPreference` 推导而来(`paragraph` → `\n\n`,`newline` → `\n`,`sentence` → 空格)。
|
||||
- 可通过 `*.blockStreamingCoalesce` 进行渠道级覆盖(包括每账号配置)。
|
||||
- 对于 Signal/Slack/Discord,除非另有覆盖,默认的合并 `minChars` 会提升到 1500。
|
||||
- 可通过 `*.blockStreamingCoalesce` 使用渠道覆盖(包括每账户配置)。
|
||||
- 对于 Signal/Slack/Discord,默认的聚合 `minChars` 会提升到 1500,除非被覆盖。
|
||||
|
||||
## 分块之间的类人节奏延迟
|
||||
## 块之间更像人类的节奏
|
||||
|
||||
启用分块流式传输时,你可以在分块回复之间加入**随机暂停**(第一个分块之后)。这样多气泡回复会显得更自然。
|
||||
启用分块流式传输时,你可以在块回复之间(第一个块之后)加入 **随机暂停**。这会让多气泡回复感觉更自然。
|
||||
|
||||
- 配置:`agents.defaults.humanDelay`(可通过 `agents.list[].humanDelay` 按智能体覆盖)。
|
||||
- 模式:`off`(默认)、`natural`(800–2500ms)、`custom`(`minMs`/`maxMs`)。
|
||||
- 仅适用于**分块回复**,不适用于最终回复或工具摘要。
|
||||
- 仅适用于 **分块回复**,不适用于最终回复或工具摘要。
|
||||
|
||||
## “流式发送分块还是一次性发送全部”
|
||||
|
||||
这对应为:
|
||||
它映射为:
|
||||
|
||||
- **流式发送分块:** `blockStreamingDefault: "on"` + `blockStreamingBreak: "text_end"`(边生成边发出)。非 Telegram 渠道还需要 `*.blockStreaming: true`。
|
||||
- **在结束时发送全部:** `blockStreamingBreak: "message_end"`(刷新一次;如果很长,可能仍拆成多个分块)。
|
||||
- **流式发送分块:** `blockStreamingDefault: "on"` + `blockStreamingBreak: "text_end"`(边生成边发出)。非 Telegram 渠道还需要设置 `*.blockStreaming: true`。
|
||||
- **在结尾一次性流式发送全部:** `blockStreamingBreak: "message_end"`(刷新一次;如果内容很长,可能仍会拆成多个块)。
|
||||
- **不使用分块流式传输:** `blockStreamingDefault: "off"`(只发送最终回复)。
|
||||
|
||||
**渠道说明:** 分块流式传输默认**关闭**,除非显式将 `*.blockStreaming` 设为 `true`。渠道可以在没有分块回复的情况下,使用 `channels.<channel>.streaming` 流式显示实时预览。
|
||||
**渠道说明:** 除非显式将 `*.blockStreaming` 设为 `true`,否则分块流式传输 **默认关闭**。渠道可以在没有分块回复的情况下使用实时预览流式传输(`channels.<channel>.streaming`)。
|
||||
|
||||
配置位置提醒:`blockStreaming*` 默认值位于 `agents.defaults` 下,而不在根配置中。
|
||||
配置位置提醒:`blockStreaming*` 默认值位于 `agents.defaults` 下,而不是根配置。
|
||||
|
||||
## 预览流式传输模式
|
||||
|
||||
@ -110,9 +116,9 @@ Model output
|
||||
模式:
|
||||
|
||||
- `off`:禁用预览流式传输。
|
||||
- `partial`:单个预览,用最新文本替换。
|
||||
- `block`:预览以分块/追加的方式更新。
|
||||
- `progress`:生成期间显示进度/状态预览,完成后显示最终答案。
|
||||
- `partial`:使用单个预览,并用最新文本替换它。
|
||||
- `block`:以分块/追加的方式更新预览。
|
||||
- `progress`:生成期间显示进度/状态预览,完成时显示最终答案。
|
||||
|
||||
### 渠道映射
|
||||
|
||||
@ -123,62 +129,62 @@ Model output
|
||||
| Slack | ✅ | ✅ | ✅ | ✅ |
|
||||
| Mattermost | ✅ | ✅ | ✅ | ✅ |
|
||||
|
||||
仅 Slack:
|
||||
仅适用于 Slack:
|
||||
|
||||
- 当 `channels.slack.streaming.mode="partial"` 时,`channels.slack.streaming.nativeTransport` 控制是否启用 Slack 原生流式 API 调用(默认:`true`)。
|
||||
- Slack 原生流式传输和 Slack 助手线程状态都需要一个回复线程目标;顶层私信不会显示这种线程式预览。
|
||||
- `channels.slack.streaming.nativeTransport` 在 `channels.slack.streaming.mode="partial"` 时切换 Slack 原生流式 API 调用(默认:`true`)。
|
||||
- Slack 原生流式传输和 Slack 助手线程状态都需要一个回复线程目标;顶级私信不会显示这种线程式预览。
|
||||
|
||||
旧键迁移:
|
||||
|
||||
- Telegram:`streamMode` 和布尔值 `streaming` 会自动迁移到 `streaming` 枚举。
|
||||
- Discord:`streamMode` 和布尔值 `streaming` 会自动迁移到 `streaming` 枚举。
|
||||
- Slack:`streamMode` 会自动迁移到 `streaming.mode`;布尔值 `streaming` 会自动迁移到 `streaming.mode` 加 `streaming.nativeTransport`;旧版 `nativeStreaming` 会自动迁移到 `streaming.nativeTransport`。
|
||||
- Telegram:`streamMode` 和布尔值 `streaming` 会自动迁移到枚举 `streaming`。
|
||||
- Discord:`streamMode` 和布尔值 `streaming` 会自动迁移到枚举 `streaming`。
|
||||
- Slack:`streamMode` 会自动迁移到 `streaming.mode`;布尔值 `streaming` 会自动迁移到 `streaming.mode` 加 `streaming.nativeTransport`;旧的 `nativeStreaming` 会自动迁移到 `streaming.nativeTransport`。
|
||||
|
||||
### 运行时行为
|
||||
|
||||
Telegram:
|
||||
|
||||
- 在私信和群组/话题中,使用 `sendMessage` + `editMessageText` 更新预览。
|
||||
- 当 Telegram 分块流式传输被显式启用时,会跳过预览流式传输(以避免双重流式传输)。
|
||||
- `/reasoning stream` 可以将推理内容写入预览。
|
||||
- 当 Telegram 的分块流式传输被显式启用时,会跳过预览流式传输(以避免双重流式传输)。
|
||||
- `/reasoning stream` 可以把推理内容写入预览。
|
||||
|
||||
Discord:
|
||||
|
||||
- 使用发送 + 编辑预览消息。
|
||||
- `block` 模式使用草稿分块(`draftChunk`)。
|
||||
- 当 Discord 分块流式传输被显式启用时,会跳过预览流式传输。
|
||||
- 最终媒体、错误和显式回复载荷会取消待处理的预览,而不会刷新新的草稿,然后改用正常投递。
|
||||
- `block` 模式使用草稿分块处理(`draftChunk`)。
|
||||
- 当 Discord 的分块流式传输被显式启用时,会跳过预览流式传输。
|
||||
- 最终媒体、错误和显式回复载荷会取消待处理的预览,而不会刷新新的草稿,然后使用正常投递。
|
||||
|
||||
Slack:
|
||||
|
||||
- `partial` 在可用时可以使用 Slack 原生流式传输(`chat.startStream`/`append`/`stop`)。
|
||||
- `block` 使用追加式草稿预览。
|
||||
- `progress` 使用状态预览文本,然后显示最终答案。
|
||||
- 原生预览流式传输和草稿预览流式传输都会抑制该轮的分块回复,因此 Slack 回复只会通过一条投递路径进行流式传输。
|
||||
- 最终媒体/错误载荷和进度最终结果不会创建一次性草稿消息;只有可以编辑预览的文本/块最终结果才会刷新待处理的草稿文本。
|
||||
- `progress` 使用状态预览文本,然后发送最终答案。
|
||||
- 原生预览流式传输和草稿预览流式传输会抑制当前轮次的分块回复,因此 Slack 回复只会通过一种投递路径进行流式传输。
|
||||
- 最终媒体/错误载荷和 `progress` 最终结果不会创建一次性的草稿消息;只有可以编辑预览的文本/块最终结果,才会刷新待处理的草稿文本。
|
||||
|
||||
Mattermost:
|
||||
|
||||
- 将 thinking、工具活动和部分回复文本流式写入单个草稿预览帖子,在最终答案可安全发送时原地完成。
|
||||
- 如果预览帖子已被删除或在完成时不可用,则回退为发送一个新的最终帖子。
|
||||
- 最终媒体/错误载荷会在正常投递前取消待处理的预览更新,而不是刷新临时预览帖子。
|
||||
- 将 thinking、工具活动和部分回复文本流式写入单个草稿预览帖子,在最终答案可以安全发送时原地完成。
|
||||
- 如果预览帖子已被删除,或在最终化时不可用,则回退为发送一个新的最终帖子。
|
||||
- 最终媒体/错误载荷会在正常投递前取消待处理的预览更新,而不是刷新一个临时预览帖子。
|
||||
|
||||
Matrix:
|
||||
|
||||
- 当最终文本可以复用预览事件时,草稿预览会原地完成。
|
||||
- 纯媒体、错误和回复目标不匹配的最终结果会在正常投递前取消待处理的预览更新;已经可见的陈旧预览会被撤回。
|
||||
- 仅媒体、错误以及回复目标不匹配的最终结果,会在正常投递前取消待处理的预览更新;如果已经出现陈旧预览,则会被撤销。
|
||||
|
||||
### 工具进度预览更新
|
||||
|
||||
预览流式传输还可以包含**工具进度**更新——例如“正在搜索网页”、“正在读取文件”或“正在调用工具”这样的简短状态行——在工具运行期间,这些状态会出现在同一个预览消息中,先于最终回复显示。这让多步骤工具回合在视觉上保持活跃,而不是在第一次 thinking 预览和最终答案之间一片沉默。
|
||||
预览流式传输还可以包含 **工具进度** 更新 —— 比如“正在搜索网页”“正在读取文件”或“正在调用工具”这样的短状态行,在工具运行期间显示在同一个预览消息中,先于最终回复出现。这样可以让多步骤工具轮次在视觉上保持活跃,而不是在首次 thinking 预览和最终答案之间保持沉默。
|
||||
|
||||
支持的界面:
|
||||
|
||||
- 当预览流式传输处于激活状态时,**Discord**、**Slack** 和 **Telegram** 默认会将工具进度流式写入实时预览编辑中。
|
||||
- 自 `v2026.4.22` 起,Telegram 已发布并默认启用工具进度预览更新;保持启用可维持这一已发布行为。
|
||||
- **Mattermost** 已经会将工具活动折叠进其单一草稿预览帖子中(见上文)。
|
||||
- 工具进度编辑遵循当前激活的预览流式传输模式;当预览流式传输为 `off`,或消息已由分块流式传输接管时,会跳过这些更新。
|
||||
- 若要保留预览流式传输但隐藏工具进度行,请为该渠道将 `streaming.preview.toolProgress` 设为 `false`。若要完全禁用预览编辑,请将 `streaming.mode` 设为 `off`。
|
||||
- 当预览流式传输处于激活状态时,**Discord**、**Slack** 和 **Telegram** 默认会把工具进度流式写入实时预览编辑中。
|
||||
- 自 `v2026.4.22` 起,Telegram 已默认启用工具进度预览更新;保持启用即可保留这一已发布行为。
|
||||
- **Mattermost** 已经会把工具活动合并到它的单个草稿预览帖子中(见上文)。
|
||||
- 工具进度编辑遵循当前激活的预览流式传输模式;当预览流式传输为 `off`,或消息已被分块流式传输接管时,会跳过这些编辑。
|
||||
- 如果你想保留预览流式传输,但隐藏工具进度行,可将该渠道的 `streaming.preview.toolProgress` 设为 `false`。如果你想完全禁用预览编辑,请将 `streaming.mode` 设为 `off`。
|
||||
|
||||
示例:
|
||||
|
||||
@ -199,6 +205,6 @@ Matrix:
|
||||
|
||||
## 相关内容
|
||||
|
||||
- [Messages](/zh-CN/concepts/messages) — 消息生命周期和投递
|
||||
- [Messages](/zh-CN/concepts/messages) — 消息生命周期与投递
|
||||
- [Retry](/zh-CN/concepts/retry) — 投递失败时的重试行为
|
||||
- [Channels](/zh-CN/channels) — 各渠道的流式传输支持
|
||||
|
||||
@ -1,61 +1,61 @@
|
||||
---
|
||||
read_when:
|
||||
- 你需要精确到字段级别的配置语义或默认值
|
||||
- 你正在验证渠道、模型、Gateway 网关或工具配置块
|
||||
summary: Gateway 网关配置参考,涵盖 OpenClaw 核心键名、默认值以及指向各专用子系统参考文档的链接
|
||||
- 你正在验证渠道、模型、Gateway 网关 或工具配置块
|
||||
summary: Gateway 网关 配置参考,涵盖核心 OpenClaw 键名、默认值,以及指向专用子系统参考文档的链接
|
||||
title: 配置参考
|
||||
x-i18n:
|
||||
generated_at: "2026-04-25T02:35:32Z"
|
||||
generated_at: "2026-04-25T04:55:00Z"
|
||||
model: gpt-5.4
|
||||
provider: openai
|
||||
source_hash: 5c844b2af8d431d6bc090f128b6a2415254f284196f2c6612ed35bd5502f26bb
|
||||
source_hash: 2953146dc071c5fb5c9e7cdf628f92a4c12b3f30d21815626ed43de0bf39193f
|
||||
source_path: gateway/configuration-reference.md
|
||||
workflow: 15
|
||||
---
|
||||
|
||||
`~/.openclaw/openclaw.json` 的核心配置参考。若想查看面向任务的概览,请参见 [配置](/zh-CN/gateway/configuration)。
|
||||
`~/.openclaw/openclaw.json` 的核心配置参考。若需面向任务的概览,请参见 [配置](/zh-CN/gateway/configuration)。
|
||||
|
||||
本页介绍 OpenClaw 的主要配置面,并在某个子系统拥有自己更深入的参考文档时提供跳转链接。它**不会**尝试在单页中内联每个渠道/插件自有的命令目录,也不会内联所有深入的 memory/QMD 旋钮。
|
||||
本页介绍 OpenClaw 的主要配置面,并在某个子系统有自己更深入的参考文档时提供链接。它**不会**尝试在单个页面内联所有由渠道 / 插件拥有的命令目录,也不会内联所有深层 memory / QMD 细项配置。
|
||||
|
||||
代码真相:
|
||||
代码事实来源:
|
||||
|
||||
- `openclaw config schema` 会打印用于验证和 Control UI 的实时 JSON Schema,并在可用时合并内置/插件/渠道元数据
|
||||
- `config.schema.lookup` 会返回一个按路径范围限定的 schema 节点,用于深入查看工具
|
||||
- `pnpm config:docs:check` / `pnpm config:docs:gen` 会根据当前 schema 面验证配置文档基线哈希
|
||||
- `openclaw config schema` 会打印用于验证和 Control UI 的实时 JSON Schema,并在可用时合并内置 / 插件 / 渠道元数据
|
||||
- `config.schema.lookup` 返回一个按路径作用域定位的 schema 节点,用于下钻工具
|
||||
- `pnpm config:docs:check` / `pnpm config:docs:gen` 会根据当前 schema 表面校验配置文档基线哈希
|
||||
|
||||
专用深入参考:
|
||||
|
||||
- [内存配置参考](/zh-CN/reference/memory-config),适用于 `agents.defaults.memorySearch.*`、`memory.qmd.*`、`memory.citations`,以及位于 `plugins.entries.memory-core.config.dreaming` 下的 Dreaming 配置
|
||||
- [斜杠命令](/zh-CN/tools/slash-commands),适用于当前内建 + 内置的命令目录
|
||||
- 对应渠道/插件页面,适用于特定渠道的命令面
|
||||
- [Memory 配置参考](/zh-CN/reference/memory-config):用于 `agents.defaults.memorySearch.*`、`memory.qmd.*`、`memory.citations`,以及 `plugins.entries.memory-core.config.dreaming` 下的 dreaming 配置
|
||||
- [Slash Commands](/zh-CN/tools/slash-commands):当前内置 + 内置打包命令目录
|
||||
- 对应渠道 / 插件页面:用于渠道特定的命令面
|
||||
|
||||
配置格式为 **JSON5**(允许注释和尾随逗号)。所有字段都是可选的——省略时,OpenClaw 会使用安全的默认值。
|
||||
配置格式为 **JSON5**(允许注释和尾随逗号)。所有字段都是可选的——省略时,OpenClaw 会使用安全默认值。
|
||||
|
||||
---
|
||||
|
||||
## 渠道
|
||||
|
||||
每个渠道的配置键已移至专用页面——请参见
|
||||
每个渠道的配置键已移至专门页面——请参见
|
||||
[配置 — 渠道](/zh-CN/gateway/config-channels),了解 `channels.*`,
|
||||
包括 Slack、Discord、Telegram、WhatsApp、Matrix、iMessage 以及其他
|
||||
内置渠道(凭证、访问控制、多账号、提及门控)。
|
||||
其中包括 Slack、Discord、Telegram、WhatsApp、Matrix、iMessage 以及其他
|
||||
内置渠道(认证、访问控制、多账号、提及门控)。
|
||||
|
||||
## 智能体默认值、多智能体、会话和消息
|
||||
|
||||
已移至专用页面——请参见
|
||||
[配置 — 智能体](/zh-CN/gateway/config-agents),内容包括:
|
||||
已移至专门页面——请参见
|
||||
[配置 — 智能体](/zh-CN/gateway/config-agents),了解:
|
||||
|
||||
- `agents.defaults.*`(工作区、模型、思考、心跳、内存、媒体、Skills、沙箱)
|
||||
- `multiAgent.*`(多智能体路由和绑定)
|
||||
- `session.*`(会话生命周期、压缩、清理)
|
||||
- `messages.*`(消息传递、TTS、Markdown 渲染)
|
||||
- `agents.defaults.*`(工作区、模型、思考、心跳、memory、媒体、skills、沙箱)
|
||||
- `multiAgent.*`(多智能体路由与绑定)
|
||||
- `session.*`(会话生命周期、压缩、修剪)
|
||||
- `messages.*`(消息投递、TTS、Markdown 渲染)
|
||||
- `talk.*`(Talk 模式)
|
||||
- `talk.silenceTimeoutMs`:未设置时,Talk 会在发送转录文本前保持平台默认的静默等待窗口(`macOS 和 Android 为 700 ms,iOS 为 900 ms`)
|
||||
- `talk.silenceTimeoutMs`:未设置时,Talk 会在发送转录文本前保持平台默认静默窗口(`macOS 和 Android 为 700 ms,iOS 为 900 ms`)
|
||||
|
||||
## 工具和自定义提供商
|
||||
|
||||
工具策略、实验性开关、由提供商支持的工具配置,以及自定义
|
||||
提供商 / base-URL 设置已移至专用页面——请参见
|
||||
提供商 / base-URL 设置已移至专门页面——请参见
|
||||
[配置 — 工具和自定义提供商](/zh-CN/gateway/config-tools)。
|
||||
|
||||
## Skills
|
||||
@ -83,12 +83,12 @@ x-i18n:
|
||||
}
|
||||
```
|
||||
|
||||
- `allowBundled`:仅针对内置 Skills 的可选允许列表(托管/工作区 Skills 不受影响)。
|
||||
- `load.extraDirs`:额外的共享 Skills 根目录(优先级最低)。
|
||||
- `install.preferBrew`:为 true 时,若 `brew` 可用,则优先使用 Homebrew 安装器,之后才回退到其他安装器类型。
|
||||
- `install.nodeManager`:`metadata.openclaw.install` 规范的 Node 安装器偏好(`npm` | `pnpm` | `yarn` | `bun`)。
|
||||
- `entries.<skillKey>.enabled: false`:即使某个 Skill 已内置/已安装,也会将其禁用。
|
||||
- `entries.<skillKey>.apiKey`:为声明了主环境变量的 Skills 提供的便捷字段(明文字符串或 SecretRef 对象)。
|
||||
- `allowBundled`:仅针对内置 skills 的可选允许列表(托管 / 工作区 skills 不受影响)。
|
||||
- `load.extraDirs`:额外的共享 skill 根目录(优先级最低)。
|
||||
- `install.preferBrew`:为 true 时,如果可用 `brew`,则优先使用 Homebrew 安装器,然后再回退到其他安装器类型。
|
||||
- `install.nodeManager`:用于 `metadata.openclaw.install` 规范的 Node 安装器偏好(`npm` | `pnpm` | `yarn` | `bun`)。
|
||||
- `entries.<skillKey>.enabled: false`:即使某个 skill 已内置 / 已安装,也会将其禁用。
|
||||
- `entries.<skillKey>.apiKey`:为声明主要环境变量的 skill 提供的便捷字段(明文字符串或 SecretRef 对象)。
|
||||
|
||||
---
|
||||
|
||||
@ -117,41 +117,41 @@ x-i18n:
|
||||
```
|
||||
|
||||
- 从 `~/.openclaw/extensions`、`<workspace>/.openclaw/extensions` 以及 `plugins.load.paths` 加载。
|
||||
- 设备发现接受原生 OpenClaw 插件,以及兼容的 Codex bundle 和 Claude bundle,包括无 manifest 的 Claude 默认布局 bundle。
|
||||
- **配置变更需要重启 Gateway 网关。**
|
||||
- `allow`:可选允许列表(仅加载列出的插件)。`deny` 优先。
|
||||
- `plugins.entries.<id>.apiKey`:插件级 API key 便捷字段(插件支持时可用)。
|
||||
- 发现机制接受原生 OpenClaw 插件,以及兼容的 Codex bundle 和 Claude bundle,其中包括无 manifest 的 Claude 默认布局 bundle。
|
||||
- **配置更改需要重启 Gateway 网关。**
|
||||
- `allow`:可选允许列表(仅加载列出的插件)。`deny` 优先生效。
|
||||
- `plugins.entries.<id>.apiKey`:插件级 API 密钥便捷字段(当插件支持时)。
|
||||
- `plugins.entries.<id>.env`:插件作用域的环境变量映射。
|
||||
- `plugins.entries.<id>.hooks.allowPromptInjection`:为 `false` 时,核心会阻止 `before_prompt_build`,并忽略旧版 `before_agent_start` 中会变更提示词的字段,同时保留旧版 `modelOverride` 和 `providerOverride`。适用于原生插件钩子,以及受支持的 bundle 提供的钩子目录。
|
||||
- `plugins.entries.<id>.hooks.allowConversationAccess`:为 `true` 时,受信任的非内置插件可以从类型化钩子中读取原始对话内容,例如 `llm_input`、`llm_output` 和 `agent_end`。
|
||||
- `plugins.entries.<id>.subagent.allowModelOverride`:显式信任该插件可为后台子智能体运行请求按次覆盖 `provider` 和 `model`。
|
||||
- `plugins.entries.<id>.subagent.allowedModels`:受信任子智能体覆盖可用的规范 `provider/model` 目标可选允许列表。仅当你有意允许任意模型时才使用 `"*"`。
|
||||
- `plugins.entries.<id>.hooks.allowPromptInjection`:当为 `false` 时,core 会阻止 `before_prompt_build`,并忽略旧版 `before_agent_start` 中会修改提示词的字段,同时保留旧版 `modelOverride` 和 `providerOverride`。适用于原生插件钩子以及受支持的 bundle 提供的钩子目录。
|
||||
- `plugins.entries.<id>.hooks.allowConversationAccess`:当为 `true` 时,受信任的非内置插件可从类型化钩子(如 `llm_input`、`llm_output` 和 `agent_end`)读取原始对话内容。
|
||||
- `plugins.entries.<id>.subagent.allowModelOverride`:显式信任此插件,使其可以为后台子智能体运行请求按次执行的 `provider` 和 `model` 覆盖。
|
||||
- `plugins.entries.<id>.subagent.allowedModels`:受信任子智能体覆盖可使用的规范 `provider/model` 目标的可选允许列表。仅在你有意允许任意模型时使用 `"*"`。
|
||||
- `plugins.entries.<id>.config`:插件定义的配置对象(若可用,则由原生 OpenClaw 插件 schema 验证)。
|
||||
- 渠道插件的账号/运行时设置位于 `channels.<id>` 下,应由所属插件 manifest 的 `channelConfigs` 元数据描述,而不是由集中式 OpenClaw 选项注册表描述。
|
||||
- 渠道插件的账号 / 运行时设置位于 `channels.<id>` 下,应由该插件 manifest 的 `channelConfigs` 元数据描述,而不是由中央 OpenClaw 选项注册表描述。
|
||||
- `plugins.entries.firecrawl.config.webFetch`:Firecrawl 网页抓取提供商设置。
|
||||
- `apiKey`:Firecrawl API key(接受 SecretRef)。会回退到 `plugins.entries.firecrawl.config.webSearch.apiKey`、旧版 `tools.web.fetch.firecrawl.apiKey` 或 `FIRECRAWL_API_KEY` 环境变量。
|
||||
- `baseUrl`:Firecrawl API 基础 URL(默认:`https://api.firecrawl.dev`)。
|
||||
- `onlyMainContent`:仅提取页面主内容(默认:`true`)。
|
||||
- `maxAgeMs`:最大缓存时长(毫秒)(默认:`172800000` / 2 天)。
|
||||
- `timeoutSeconds`:抓取请求超时秒数(默认:`60`)。
|
||||
- `apiKey`:Firecrawl API 密钥(接受 SecretRef)。回退顺序为 `plugins.entries.firecrawl.config.webSearch.apiKey`、旧版 `tools.web.fetch.firecrawl.apiKey` 或 `FIRECRAWL_API_KEY` 环境变量。
|
||||
- `baseUrl`:Firecrawl API base URL(默认:`https://api.firecrawl.dev`)。
|
||||
- `onlyMainContent`:仅提取页面主体内容(默认:`true`)。
|
||||
- `maxAgeMs`:缓存最大时长(毫秒)(默认:`172800000` / 2 天)。
|
||||
- `timeoutSeconds`:抓取请求超时时间(秒)(默认:`60`)。
|
||||
- `plugins.entries.xai.config.xSearch`:xAI X Search(Grok 网页搜索)设置。
|
||||
- `enabled`:启用 X Search 提供商。
|
||||
- `model`:搜索使用的 Grok 模型(例如 `"grok-4-1-fast"`)。
|
||||
- `plugins.entries.memory-core.config.dreaming`:内存 Dreaming 设置。有关阶段和阈值,请参见 [Dreaming](/zh-CN/concepts/dreaming)。
|
||||
- `enabled`:Dreaming 总开关(默认 `false`)。
|
||||
- `frequency`:每次完整 Dreaming 扫描的 cron 频率(默认 `"0 3 * * *"`)。
|
||||
- `plugins.entries.memory-core.config.dreaming`:memory dreaming 设置。关于阶段和阈值,请参见 [Dreaming](/zh-CN/concepts/dreaming)。
|
||||
- `enabled`:dreaming 总开关(默认 `false`)。
|
||||
- `frequency`:每次完整 dreaming 扫描的 cron 周期(默认 `"0 3 * * *"`)。
|
||||
- 阶段策略和阈值属于实现细节(不是面向用户的配置键)。
|
||||
- 完整内存配置位于 [内存配置参考](/zh-CN/reference/memory-config):
|
||||
- 完整 memory 配置见 [Memory 配置参考](/zh-CN/reference/memory-config):
|
||||
- `agents.defaults.memorySearch.*`
|
||||
- `memory.backend`
|
||||
- `memory.citations`
|
||||
- `memory.qmd.*`
|
||||
- `plugins.entries.memory-core.config.dreaming`
|
||||
- 已启用的 Claude bundle 插件也可从 `settings.json` 提供嵌入式 Pi 默认值;OpenClaw 会将其作为已净化的智能体设置应用,而不是作为原始 OpenClaw 配置补丁应用。
|
||||
- `plugins.slots.memory`:选择活动内存插件 id,或设为 `"none"` 以禁用内存插件。
|
||||
- `plugins.slots.contextEngine`:选择活动上下文引擎插件 id;默认值为 `"legacy"`,除非你安装并选择了其他引擎。
|
||||
- 已启用的 Claude bundle 插件也可以从 `settings.json` 提供嵌入式 Pi 默认值;OpenClaw 会将其作为已净化的智能体设置应用,而不是作为原始 OpenClaw 配置补丁。
|
||||
- `plugins.slots.memory`:选择活动的 memory 插件 id,或使用 `"none"` 禁用 memory 插件。
|
||||
- `plugins.slots.contextEngine`:选择活动的上下文引擎插件 id;默认值为 `"legacy"`,除非你安装并选择了其他引擎。
|
||||
- `plugins.installs`:由 CLI 管理的安装元数据,供 `openclaw plugins update` 使用。
|
||||
- 包括 `source`、`spec`、`sourcePath`、`installPath`、`version`、`resolvedName`、`resolvedVersion`、`resolvedSpec`、`integrity`、`shasum`、`resolvedAt`、`installedAt`。
|
||||
- 包含 `source`、`spec`、`sourcePath`、`installPath`、`version`、`resolvedName`、`resolvedVersion`、`resolvedSpec`、`integrity`、`shasum`、`resolvedAt`、`installedAt`。
|
||||
- 将 `plugins.installs.*` 视为托管状态;优先使用 CLI 命令,而不是手动编辑。
|
||||
|
||||
请参见 [插件](/zh-CN/tools/plugin)。
|
||||
@ -180,7 +180,11 @@ x-i18n:
|
||||
},
|
||||
profiles: {
|
||||
openclaw: { cdpPort: 18800, color: "#FF4500" },
|
||||
work: { cdpPort: 18801, color: "#0066CC" },
|
||||
work: {
|
||||
cdpPort: 18801,
|
||||
color: "#0066CC",
|
||||
executablePath: "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome",
|
||||
},
|
||||
user: { driver: "existing-session", attachOnly: true, color: "#00AA00" },
|
||||
brave: {
|
||||
driver: "existing-session",
|
||||
@ -201,25 +205,25 @@ x-i18n:
|
||||
```
|
||||
|
||||
- `evaluateEnabled: false` 会禁用 `act:evaluate` 和 `wait --fn`。
|
||||
- `tabCleanup` 会在空闲超时后回收已跟踪的主智能体标签页,或在某个会话超过上限时回收。将 `idleMinutes: 0` 或 `maxTabsPerSession: 0` 设为 0,可禁用这些单独的清理模式。
|
||||
- `ssrfPolicy.dangerouslyAllowPrivateNetwork` 在未设置时为禁用状态,因此浏览器导航默认保持严格。
|
||||
- `tabCleanup` 会在空闲超时后,或当某个会话超过标签页上限时,回收被跟踪的主智能体标签页。将 `idleMinutes: 0` 或 `maxTabsPerSession: 0` 设为 0,可禁用对应的单项清理模式。
|
||||
- 未设置时,`ssrfPolicy.dangerouslyAllowPrivateNetwork` 为禁用状态,因此浏览器导航默认保持严格模式。
|
||||
- 仅当你明确信任私有网络浏览器导航时,才设置 `ssrfPolicy.dangerouslyAllowPrivateNetwork: true`。
|
||||
- 在严格模式下,远程 CDP 配置项端点(`profiles.*.cdpUrl`)在可达性/设备发现检查期间也会受到相同的私有网络阻止。
|
||||
- 在严格模式下,远程 CDP 配置文件端点(`profiles.*.cdpUrl`)在可达性 / 发现检查期间也会受到相同的私有网络阻止策略约束。
|
||||
- `ssrfPolicy.allowPrivateNetwork` 仍作为旧版别名受支持。
|
||||
- 在严格模式下,使用 `ssrfPolicy.hostnameAllowlist` 和 `ssrfPolicy.allowedHostnames` 来配置显式例外。
|
||||
- 远程配置项为仅附加模式(禁用启动/停止/重置)。
|
||||
- 在严格模式下,使用 `ssrfPolicy.hostnameAllowlist` 和 `ssrfPolicy.allowedHostnames` 来设置显式例外。
|
||||
- 远程配置文件为仅附加模式(禁用 start / stop / reset)。
|
||||
- `profiles.*.cdpUrl` 接受 `http://`、`https://`、`ws://` 和 `wss://`。
|
||||
当你希望 OpenClaw 发现 `/json/version` 时,请使用 HTTP(S);
|
||||
当提供商直接给出 DevTools WebSocket URL 时,请使用 WS(S)。
|
||||
- `existing-session` 配置项使用 Chrome MCP 而非 CDP,并且可以附加到所选主机上,或通过已连接的浏览器节点附加。
|
||||
- `existing-session` 配置项可设置 `userDataDir`,以定位特定的 Chromium 系浏览器配置,例如 Brave 或 Edge。
|
||||
- `existing-session` 配置项保留当前 Chrome MCP 路由限制:使用 snapshot/ref 驱动的操作而非 CSS 选择器定位、单文件上传钩子、不支持对话框超时覆盖、不支持 `wait --load networkidle`,并且不支持 `responsebody`、PDF 导出、下载拦截或批量操作。
|
||||
- 本地托管的 `openclaw` 配置项会自动分配 `cdpPort` 和 `cdpUrl`;仅在远程 CDP 场景下才显式设置 `cdpUrl`。
|
||||
- 自动检测顺序:默认浏览器若为 Chromium 系 → Chrome → Brave → Edge → Chromium → Chrome Canary。
|
||||
- `existing-session` 配置文件使用 Chrome MCP 而不是 CDP,并且可以在选定主机上附加,或通过已连接的浏览器节点附加。
|
||||
- `existing-session` 配置文件可以设置 `userDataDir`,以定位特定的基于 Chromium 的浏览器配置文件,例如 Brave 或 Edge。
|
||||
- `existing-session` 配置文件保留当前 Chrome MCP 路由限制:基于 snapshot/ref 的操作而不是基于 CSS 选择器的定位、单文件上传钩子、无对话框超时覆盖、无 `wait --load networkidle`,以及不支持 `responsebody`、PDF 导出、下载拦截或批量操作。
|
||||
- 本地托管的 `openclaw` 配置文件会自动分配 `cdpPort` 和 `cdpUrl`;仅在远程 CDP 场景下显式设置 `cdpUrl`。
|
||||
- 本地托管配置文件可以设置 `executablePath`,以覆盖该配置文件的全局 `browser.executablePath`。使用此项可让一个配置文件运行在 Chrome 中,另一个运行在 Brave 中。
|
||||
- 自动检测顺序:如果默认浏览器基于 Chromium,则优先使用默认浏览器 → Chrome → Brave → Edge → Chromium → Chrome Canary。
|
||||
- `browser.executablePath` 接受 `~` 作为你的操作系统主目录。
|
||||
- 控制服务:仅限 loopback(端口由 `gateway.port` 派生,默认 `18791`)。
|
||||
- `extraArgs` 会向本地 Chromium 启动追加额外启动标志(例如
|
||||
`--disable-gpu`、窗口尺寸设置或调试标志)。
|
||||
- 控制服务:仅 loopback(端口从 `gateway.port` 派生,默认 `18791`)。
|
||||
- `extraArgs` 会向本地 Chromium 启动追加额外启动标志(例如 `--disable-gpu`、窗口尺寸参数或调试标志)。
|
||||
|
||||
---
|
||||
|
||||
@ -237,8 +241,8 @@ x-i18n:
|
||||
}
|
||||
```
|
||||
|
||||
- `seamColor`:原生应用 UI 外观的强调色(Talk 模式气泡着色等)。
|
||||
- `assistant`:Control UI 身份覆盖。会回退到当前活动智能体身份。
|
||||
- `seamColor`:原生应用 UI 外壳的强调色(Talk 模式气泡着色等)。
|
||||
- `assistant`:Control UI 身份覆盖。回退到当前活动智能体身份。
|
||||
|
||||
---
|
||||
|
||||
@ -288,7 +292,7 @@ x-i18n:
|
||||
// 可选。默认值为 false。
|
||||
allowRealIpFallback: false,
|
||||
tools: {
|
||||
// 对 /tools/invoke HTTP 的额外拒绝列表
|
||||
// 额外的 /tools/invoke HTTP 拒绝项
|
||||
deny: ["browser"],
|
||||
// 从默认 HTTP 拒绝列表中移除工具
|
||||
allow: ["gateway"],
|
||||
@ -305,46 +309,49 @@ x-i18n:
|
||||
}
|
||||
```
|
||||
|
||||
<Accordion title="Gateway 网关字段详情">
|
||||
<Accordion title="Gateway 网关 字段详情">
|
||||
|
||||
- `mode`:`local`(运行 Gateway 网关)或 `remote`(连接到远程 Gateway 网关)。除非为 `local`,否则 Gateway 网关会拒绝启动。
|
||||
- `port`:用于 WS + HTTP 的单一复用端口。优先级:`--port` > `OPENCLAW_GATEWAY_PORT` > `gateway.port` > `18789`。
|
||||
- `mode`:`local`(运行 Gateway 网关)或 `remote`(连接到远程 Gateway 网关)。只有在 `local` 模式下,Gateway 网关 才会启动,否则会拒绝启动。
|
||||
- `port`:用于 WS + HTTP 的单一多路复用端口。优先级:`--port` > `OPENCLAW_GATEWAY_PORT` > `gateway.port` > `18789`。
|
||||
- `bind`:`auto`、`loopback`(默认)、`lan`(`0.0.0.0`)、`tailnet`(仅 Tailscale IP)或 `custom`。
|
||||
- **旧版 bind 别名**:请在 `gateway.bind` 中使用 bind 模式值(`auto`、`loopback`、`lan`、`tailnet`、`custom`),不要使用主机别名(`0.0.0.0`、`127.0.0.1`、`localhost`、`::`、`::1`)。
|
||||
- **Docker 注意事项**:默认的 `loopback` bind 会在容器内监听 `127.0.0.1`。使用 Docker bridge 网络(`-p 18789:18789`)时,流量会到达 `eth0`,因此 Gateway 网关不可访问。请使用 `--network host`,或设置 `bind: "lan"`(或 `bind: "custom"` 并配合 `customBindHost: "0.0.0.0"`)以在所有接口上监听。
|
||||
- **凭证**:默认要求开启。非 loopback bind 要求 Gateway 网关凭证。实际中,这意味着共享 token/password,或者使用配置了 `gateway.auth.mode: "trusted-proxy"` 的身份感知反向代理。新手引导向导默认会生成一个 token。
|
||||
- 如果同时配置了 `gateway.auth.token` 和 `gateway.auth.password`(包括 SecretRef),请将 `gateway.auth.mode` 明确设置为 `token` 或 `password`。若两者都已配置但未设置 mode,启动以及服务安装/修复流程都会失败。
|
||||
- `gateway.auth.mode: "none"`:显式无凭证模式。仅用于受信任的本地 local loopback 设置;新手引导提示中不会提供此选项。
|
||||
- `gateway.auth.mode: "trusted-proxy"`:将凭证委托给身份感知反向代理,并信任来自 `gateway.trustedProxies` 的身份头(参见 [受信任代理凭证](/zh-CN/gateway/trusted-proxy-auth))。该模式要求**非 loopback** 代理来源;同机 loopback 反向代理不满足 trusted-proxy 凭证要求。
|
||||
- `gateway.auth.allowTailscale`:为 `true` 时,Tailscale Serve 身份头可满足 Control UI/WebSocket 凭证要求(通过 `tailscale whois` 验证)。HTTP API 端点**不会**使用该 Tailscale 头部凭证;它们仍遵循 Gateway 网关正常的 HTTP 凭证模式。此无 token 流程假定 Gateway 网关主机受信任。当 `tailscale.mode = "serve"` 时默认值为 `true`。
|
||||
- `gateway.auth.rateLimit`:可选的凭证失败限流器。按客户端 IP 和凭证范围生效(共享密钥和设备 token 分别独立跟踪)。被阻止的尝试会返回 `429` + `Retry-After`。
|
||||
- 在异步 Tailscale Serve Control UI 路径上,同一 `{scope, clientIp}` 的失败尝试会在写入失败记录前被串行化。因此,来自同一客户端的并发错误尝试,可能会在第二个请求时触发限流,而不是两者都作为普通不匹配竞态通过。
|
||||
- `gateway.auth.rateLimit.exemptLoopback` 默认值为 `true`;如果你明确希望 localhost 流量也受到限流(例如测试环境或严格代理部署),请将其设为 `false`。
|
||||
- 来自浏览器源的 WS 凭证尝试始终会启用限流,并关闭 loopback 豁免(作为针对基于浏览器的 localhost 暴力破解的纵深防御)。
|
||||
- 在 loopback 上,这些来自浏览器源的锁定会按规范化后的 `Origin`
|
||||
值彼此隔离,因此某个 localhost origin 的重复失败不会自动
|
||||
- **旧版 bind 别名**:在 `gateway.bind` 中使用 bind 模式值(`auto`、`loopback`、`lan`、`tailnet`、`custom`),不要使用主机别名(`0.0.0.0`、`127.0.0.1`、`localhost`、`::`、`::1`)。
|
||||
- **Docker 注意事项**:默认的 `loopback` bind 会在容器内监听 `127.0.0.1`。使用 Docker bridge 网络(`-p 18789:18789`)时,流量会到达 `eth0`,因此 Gateway 网关 无法访问。请使用 `--network host`,或设置 `bind: "lan"`(或使用 `bind: "custom"` 且 `customBindHost: "0.0.0.0"`)以监听所有接口。
|
||||
- **认证**:默认必需。非 loopback bind 必须启用 Gateway 网关 认证。实际来说,这意味着共享 token / password,或者使用带 `gateway.auth.mode: "trusted-proxy"` 的身份感知反向代理。新手引导向导默认会生成一个 token。
|
||||
- 如果同时配置了 `gateway.auth.token` 和 `gateway.auth.password`(包括 SecretRef),请显式设置 `gateway.auth.mode` 为 `token` 或 `password`。如果两者都已配置但未设置 mode,启动以及服务安装 / 修复流程都会失败。
|
||||
- `gateway.auth.mode: "none"`:显式无认证模式。仅用于受信任的本地 local loopback 设置;新手引导提示中不会提供此选项。
|
||||
- `gateway.auth.mode: "trusted-proxy"`:将认证委托给身份感知反向代理,并信任来自 `gateway.trustedProxies` 的身份头(参见 [受信任代理认证](/zh-CN/gateway/trusted-proxy-auth))。此模式要求代理来源为**非 loopback**;同主机上的 loopback 反向代理不满足 trusted-proxy 认证要求。
|
||||
- `gateway.auth.allowTailscale`:为 `true` 时,Tailscale Serve 身份头可满足 Control UI / WebSocket 认证(通过 `tailscale whois` 验证)。HTTP API 端点**不会**使用该 Tailscale 头认证;它们仍遵循 Gateway 网关 的常规 HTTP 认证模式。此无 token 流程假定 Gateway 网关 主机是受信任的。当 `tailscale.mode = "serve"` 时,默认值为 `true`。
|
||||
- `gateway.auth.rateLimit`:可选的失败认证限流器。按客户端 IP 和认证作用域生效(共享密钥和设备 token 分别跟踪)。被阻止的尝试会返回 `429` + `Retry-After`。
|
||||
- 在异步 Tailscale Serve Control UI 路径中,对相同 `{scope, clientIp}` 的失败尝试会在写入失败记录之前串行化。因此,同一客户端并发的错误尝试可能会在第二个请求时触发限流,而不是两个请求都作为普通不匹配一起穿过。
|
||||
- `gateway.auth.rateLimit.exemptLoopback` 默认值为 `true`;如果你希望 localhost 流量也被限流(例如测试环境或严格代理部署),请将其设为 `false`。
|
||||
- 来自浏览器 origin 的 WS 认证尝试始终会启用限流,且不会豁免 loopback(作为针对基于浏览器的 localhost 暴力破解的纵深防御)。
|
||||
- 在 loopback 上,这些来自浏览器 origin 的锁定会按标准化后的 `Origin`
|
||||
值隔离,因此一个 localhost origin 的重复失败不会自动
|
||||
锁定另一个 origin。
|
||||
- `tailscale.mode`:`serve`(仅 tailnet,loopback bind)或 `funnel`(公开访问,要求凭证)。
|
||||
- `controlUi.allowedOrigins`:用于 Gateway 网关 WebSocket 连接的显式浏览器源允许列表。当预期浏览器客户端来自非 loopback origin 时为必填。
|
||||
- `controlUi.dangerouslyAllowHostHeaderOriginFallback`:危险模式,为有意依赖 Host 头 origin 策略的部署启用 Host 头 origin 回退。
|
||||
- `remote.transport`:`ssh`(默认)或 `direct`(ws/wss)。对于 `direct`,`remote.url` 必须是 `ws://` 或 `wss://`。
|
||||
- `OPENCLAW_ALLOW_INSECURE_PRIVATE_WS=1`:客户端进程环境变量中的紧急放行覆盖项,允许对受信任私有网络 IP 使用明文 `ws://`;默认仍仅允许对 loopback 使用明文。没有对应的 `openclaw.json` 配置项,并且浏览器私有网络配置,例如 `browser.ssrfPolicy.dangerouslyAllowPrivateNetwork`,不会影响 Gateway 网关 WebSocket 客户端。
|
||||
- `gateway.remote.token` / `.password`:远程客户端凭证字段。它们本身不会配置 Gateway 网关凭证。
|
||||
- `gateway.push.apns.relay.baseUrl`:官方/TestFlight iOS 构建在向 Gateway 网关发布基于 relay 的注册后,供其使用的外部 APNs relay 基础 HTTPS URL。此 URL 必须与编译进 iOS 构建中的 relay URL 一致。
|
||||
- `gateway.push.apns.relay.timeoutMs`:Gateway 网关到 relay 的发送超时时间,单位毫秒。默认值为 `10000`。
|
||||
- 基于 relay 的注册会委托给某个特定的 Gateway 网关身份。配对的 iOS 应用会获取 `gateway.identity.get`,在 relay 注册中包含该身份,并向 Gateway 网关转发一个作用于该注册的发送授权。另一个 Gateway 网关无法复用该已存储的注册。
|
||||
- `tailscale.mode`:`serve`(仅 tailnet,loopback bind)或 `funnel`(公开访问,需要认证)。
|
||||
- `controlUi.allowedOrigins`:用于 Gateway 网关 WebSocket 连接的显式浏览器 origin 允许列表。当预期浏览器客户端来自非 loopback origin 时,此项是必需的。
|
||||
- `controlUi.dangerouslyAllowHostHeaderOriginFallback`:危险模式,为有意依赖 Host 头 origin 策略的部署启用基于 Host 头的 origin 回退。
|
||||
- `remote.transport`:`ssh`(默认)或 `direct`(ws / wss)。对于 `direct`,`remote.url` 必须是 `ws://` 或 `wss://`。
|
||||
- `OPENCLAW_ALLOW_INSECURE_PRIVATE_WS=1`:客户端进程环境中的紧急放行覆盖项,允许对受信任私有网络 IP 使用明文 `ws://`;默认仍仅允许在 loopback 上使用明文。没有对应的 `openclaw.json`
|
||||
配置项,且浏览器私有网络配置(例如
|
||||
`browser.ssrfPolicy.dangerouslyAllowPrivateNetwork`)也不会影响 Gateway 网关
|
||||
WebSocket 客户端。
|
||||
- `gateway.remote.token` / `.password` 是远程客户端凭证字段。它们本身不会配置 Gateway 网关 认证。
|
||||
- `gateway.push.apns.relay.baseUrl`:供官方 / TestFlight iOS 构建在向 Gateway 网关 发布基于 relay 的注册后使用的外部 APNs relay 的基础 HTTPS URL。此 URL 必须与编译进 iOS 构建的 relay URL 匹配。
|
||||
- `gateway.push.apns.relay.timeoutMs`:Gateway 网关 到 relay 的发送超时时间(毫秒)。默认值为 `10000`。
|
||||
- 基于 relay 的注册会被委托给特定的 Gateway 网关 身份。配对的 iOS 应用会获取 `gateway.identity.get`,在 relay 注册中包含该身份,并将一个按注册作用域授予的发送许可转发给 Gateway 网关。其他 Gateway 网关 无法复用该已存储注册。
|
||||
- `OPENCLAW_APNS_RELAY_BASE_URL` / `OPENCLAW_APNS_RELAY_TIMEOUT_MS`:上述 relay 配置的临时环境变量覆盖项。
|
||||
- `OPENCLAW_APNS_RELAY_ALLOW_HTTP=true`:仅开发环境使用的逃生舱设置,用于 loopback HTTP relay URL。生产环境 relay URL 应保持为 HTTPS。
|
||||
- `gateway.channelHealthCheckMinutes`:渠道健康监控间隔,单位分钟。设为 `0` 可全局禁用健康监控重启。默认值:`5`。
|
||||
- `gateway.channelStaleEventThresholdMinutes`:陈旧 socket 阈值,单位分钟。应保持其大于或等于 `gateway.channelHealthCheckMinutes`。默认值:`30`。
|
||||
- `gateway.channelMaxRestartsPerHour`:滚动一小时内每个渠道/账号允许的最大健康监控重启次数。默认值:`10`。
|
||||
- `channels.<provider>.healthMonitor.enabled`:逐渠道退出健康监控重启,同时保持全局监控启用。
|
||||
- `channels.<provider>.accounts.<accountId>.healthMonitor.enabled`:多账号渠道的逐账号覆盖。设置后,其优先级高于渠道级覆盖。
|
||||
- 仅当 `gateway.auth.*` 未设置时,本地 Gateway 网关调用路径才可将 `gateway.remote.*` 用作回退。
|
||||
- 如果通过 SecretRef 显式配置了 `gateway.auth.token` / `gateway.auth.password` 但无法解析,解析会以关闭方式失败(不会被远程回退掩盖)。
|
||||
- `trustedProxies`:终止 TLS 或注入转发客户端头的反向代理 IP。只列出你控制的代理。loopback 条目对于同机代理/本地检测设置(例如 Tailscale Serve 或本地反向代理)仍然有效,但它们**不会**让 loopback 请求符合 `gateway.auth.mode: "trusted-proxy"` 的资格。
|
||||
- `allowRealIpFallback`:为 `true` 时,如果缺少 `X-Forwarded-For`,Gateway 网关接受 `X-Real-IP`。默认值为 `false`,以保持失败关闭行为。
|
||||
- `gateway.tools.deny`:对 HTTP `POST /tools/invoke` 额外阻止的工具名(扩展默认拒绝列表)。
|
||||
- `OPENCLAW_APNS_RELAY_ALLOW_HTTP=true`:仅用于开发的放行开关,允许 loopback HTTP relay URL。生产环境中的 relay URL 应保持为 HTTPS。
|
||||
- `gateway.channelHealthCheckMinutes`:渠道健康监视器间隔(分钟)。设为 `0` 可全局禁用健康监视器重启。默认值:`5`。
|
||||
- `gateway.channelStaleEventThresholdMinutes`:陈旧 socket 阈值(分钟)。请保持其大于或等于 `gateway.channelHealthCheckMinutes`。默认值:`30`。
|
||||
- `gateway.channelMaxRestartsPerHour`:每个渠道 / 账号在滚动一小时内允许的最大健康监视器重启次数。默认值:`10`。
|
||||
- `channels.<provider>.healthMonitor.enabled`:每个渠道单独退出健康监视器重启,同时保持全局监视器启用。
|
||||
- `channels.<provider>.accounts.<accountId>.healthMonitor.enabled`:多账号渠道中的每个账号覆盖项。设置后,它的优先级高于渠道级覆盖。
|
||||
- 仅当 `gateway.auth.*` 未设置时,本地 Gateway 网关 调用路径才可将 `gateway.remote.*` 用作回退。
|
||||
- 如果通过 SecretRef 显式配置了 `gateway.auth.token` / `gateway.auth.password` 但未成功解析,解析会以关闭方式失败(不会被远程回退所掩盖)。
|
||||
- `trustedProxies`:终止 TLS 或注入转发客户端头的反向代理 IP。只列出你控制的代理。loopback 条目对于同主机代理 / 本地检测设置仍然有效(例如 Tailscale Serve 或本地反向代理),但它们**不会**让 loopback 请求符合 `gateway.auth.mode: "trusted-proxy"` 的使用条件。
|
||||
- `allowRealIpFallback`:为 `true` 时,如果缺少 `X-Forwarded-For`,Gateway 网关 会接受 `X-Real-IP`。默认值为 `false`,以保持失败即关闭的行为。
|
||||
- `gateway.tools.deny`:为 HTTP `POST /tools/invoke` 额外阻止的工具名(扩展默认拒绝列表)。
|
||||
- `gateway.tools.allow`:从默认 HTTP 拒绝列表中移除工具名。
|
||||
|
||||
</Accordion>
|
||||
@ -357,14 +364,14 @@ x-i18n:
|
||||
- `gateway.http.endpoints.responses.maxUrlParts`
|
||||
- `gateway.http.endpoints.responses.files.urlAllowlist`
|
||||
- `gateway.http.endpoints.responses.images.urlAllowlist`
|
||||
空允许列表会被视为未设置;使用 `gateway.http.endpoints.responses.files.allowUrl=false`
|
||||
和/或 `gateway.http.endpoints.responses.images.allowUrl=false` 可禁用 URL 抓取。
|
||||
空允许列表会被视为未设置;请使用 `gateway.http.endpoints.responses.files.allowUrl=false`
|
||||
和 / 或 `gateway.http.endpoints.responses.images.allowUrl=false` 来禁用 URL 抓取。
|
||||
- 可选的响应加固头:
|
||||
- `gateway.http.securityHeaders.strictTransportSecurity`(仅对你控制的 HTTPS origin 设置;参见 [受信任代理凭证](/zh-CN/gateway/trusted-proxy-auth#tls-termination-and-hsts))
|
||||
- `gateway.http.securityHeaders.strictTransportSecurity`(仅对你控制的 HTTPS origin 设置;参见 [受信任代理认证](/zh-CN/gateway/trusted-proxy-auth#tls-termination-and-hsts))
|
||||
|
||||
### 多实例隔离
|
||||
|
||||
在同一主机上运行多个 Gateway 网关时,请使用不同的端口和状态目录:
|
||||
在同一主机上运行多个 Gateway 网关 实例时,请使用唯一端口和状态目录:
|
||||
|
||||
```bash
|
||||
OPENCLAW_CONFIG_PATH=~/.openclaw/a.json \
|
||||
@ -392,10 +399,10 @@ openclaw gateway --port 19001
|
||||
}
|
||||
```
|
||||
|
||||
- `enabled`:在 Gateway 网关监听器处启用 TLS 终止(HTTPS/WSS)(默认:`false`)。
|
||||
- `autoGenerate`:未配置显式文件时,自动生成本地自签名证书/密钥对;仅用于本地/开发环境。
|
||||
- `enabled`:在 Gateway 网关 监听器处启用 TLS 终止(HTTPS / WSS)(默认:`false`)。
|
||||
- `autoGenerate`:当未配置显式文件时,自动生成本地自签名证书 / 密钥对;仅适用于本地 / 开发场景。
|
||||
- `certPath`:TLS 证书文件的文件系统路径。
|
||||
- `keyPath`:TLS 私钥文件的文件系统路径;应限制权限。
|
||||
- `keyPath`:TLS 私钥文件的文件系统路径;应限制文件权限。
|
||||
- `caPath`:用于客户端验证或自定义信任链的可选 CA bundle 路径。
|
||||
|
||||
### `gateway.reload`
|
||||
@ -413,12 +420,12 @@ openclaw gateway --port 19001
|
||||
```
|
||||
|
||||
- `mode`:控制运行时如何应用配置编辑。
|
||||
- `"off"`:忽略实时编辑;变更需要显式重启。
|
||||
- `"restart"`:配置变更时始终重启 Gateway 网关进程。
|
||||
- `"hot"`:在不重启的情况下于进程内应用变更。
|
||||
- `"off"`:忽略实时编辑;更改需要显式重启。
|
||||
- `"restart"`:配置变更时始终重启 Gateway 网关 进程。
|
||||
- `"hot"`:在不重启的情况下于进程内应用更改。
|
||||
- `"hybrid"`(默认):先尝试热重载;如有需要则回退为重启。
|
||||
- `debounceMs`:应用配置变更前的防抖窗口,单位毫秒(非负整数)。
|
||||
- `deferralTimeoutMs`:在强制重启前等待进行中操作完成的最长时间,单位毫秒(默认:`300000` = 5 分钟)。
|
||||
- `debounceMs`:应用配置变更前的防抖窗口(毫秒)(非负整数)。
|
||||
- `deferralTimeoutMs`:在强制重启前等待进行中操作完成的最长时间(毫秒)(默认:`300000` = 5 分钟)。
|
||||
|
||||
---
|
||||
|
||||
@ -455,47 +462,47 @@ openclaw gateway --port 19001
|
||||
}
|
||||
```
|
||||
|
||||
凭证:`Authorization: Bearer <token>` 或 `x-openclaw-token: <token>`。
|
||||
认证:`Authorization: Bearer <token>` 或 `x-openclaw-token: <token>`。
|
||||
不接受查询字符串中的 hook token。
|
||||
|
||||
验证和安全说明:
|
||||
|
||||
- `hooks.enabled=true` 要求 `hooks.token` 为非空。
|
||||
- `hooks.enabled=true` 需要一个非空的 `hooks.token`。
|
||||
- `hooks.token` 必须与 `gateway.auth.token` **不同**;复用 Gateway 网关 token 会被拒绝。
|
||||
- `hooks.path` 不能为 `/`;请使用专用子路径,例如 `/hooks`。
|
||||
- `hooks.path` 不能是 `/`;请使用专用子路径,例如 `/hooks`。
|
||||
- 如果 `hooks.allowRequestSessionKey=true`,请约束 `hooks.allowedSessionKeyPrefixes`(例如 `["hook:"]`)。
|
||||
- 如果某个 mapping 或 preset 使用模板化的 `sessionKey`,请设置 `hooks.allowedSessionKeyPrefixes` 和 `hooks.allowRequestSessionKey=true`。静态 mapping 键不需要该显式启用。
|
||||
- 如果某个 mapping 或 preset 使用模板化的 `sessionKey`,请设置 `hooks.allowedSessionKeyPrefixes` 和 `hooks.allowRequestSessionKey=true`。静态 mapping 键不需要此显式启用。
|
||||
|
||||
**端点:**
|
||||
|
||||
- `POST /hooks/wake` → `{ text, mode?: "now"|"next-heartbeat" }`
|
||||
- `POST /hooks/agent` → `{ message, name?, agentId?, sessionKey?, wakeMode?, deliver?, channel?, to?, model?, thinking?, timeoutSeconds? }`
|
||||
- 仅当 `hooks.allowRequestSessionKey=true`(默认:`false`)时,才接受请求载荷中的 `sessionKey`。
|
||||
- 仅当 `hooks.allowRequestSessionKey=true`(默认:`false`)时,才接受请求负载中的 `sessionKey`。
|
||||
- `POST /hooks/<name>` → 通过 `hooks.mappings` 解析
|
||||
- 模板渲染后的 mapping `sessionKey` 值会被视为外部提供,因此同样要求 `hooks.allowRequestSessionKey=true`。
|
||||
|
||||
<Accordion title="映射详情">
|
||||
<Accordion title="Mapping 详情">
|
||||
|
||||
- `match.path` 匹配 `/hooks` 之后的子路径(例如 `/hooks/gmail` → `gmail`)。
|
||||
- `match.source` 匹配通用路径的载荷字段。
|
||||
- 像 `{{messages[0].subject}}` 这样的模板会从载荷中读取。
|
||||
- `transform` 可指向一个返回 hook 操作的 JS/TS 模块。
|
||||
- `transform.module` 必须是相对路径,并保持在 `hooks.transformsDir` 内(绝对路径和路径穿越会被拒绝)。
|
||||
- `agentId` 会路由到特定智能体;未知 ID 会回退到默认值。
|
||||
- `match.source` 匹配通用路径中的某个负载字段。
|
||||
- 像 `{{messages[0].subject}}` 这样的模板会从负载中读取。
|
||||
- `transform` 可以指向一个返回 hook 动作的 JS / TS 模块。
|
||||
- `transform.module` 必须是相对路径,并且必须位于 `hooks.transformsDir` 内(绝对路径和路径穿越都会被拒绝)。
|
||||
- `agentId` 路由到特定智能体;未知 ID 会回退到默认值。
|
||||
- `allowedAgentIds`:限制显式路由(`*` 或省略 = 允许全部,`[]` = 全部拒绝)。
|
||||
- `defaultSessionKey`:hook 智能体运行时的可选固定会话键,用于未显式提供 `sessionKey` 的情况。
|
||||
- `defaultSessionKey`:可选的固定会话键,用于未显式提供 `sessionKey` 的 hook 智能体运行。
|
||||
- `allowRequestSessionKey`:允许 `/hooks/agent` 调用方以及模板驱动的 mapping 会话键设置 `sessionKey`(默认:`false`)。
|
||||
- `allowedSessionKeyPrefixes`:显式 `sessionKey` 值(请求 + mapping)的可选前缀允许列表,例如 `["hook:"]`。当任意 mapping 或 preset 使用模板化 `sessionKey` 时,它会成为必填项。
|
||||
- `allowedSessionKeyPrefixes`:显式 `sessionKey` 值(请求 + mapping)的可选前缀允许列表,例如 `["hook:"]`。当任一 mapping 或 preset 使用模板化 `sessionKey` 时,它会变为必填项。
|
||||
- `deliver: true` 会将最终回复发送到某个渠道;`channel` 默认为 `last`。
|
||||
- `model`:覆盖本次 hook 运行的 LLM(如果设置了模型目录,则必须被允许)。
|
||||
- `model` 会覆盖此次 hook 运行的 LLM(如果设置了模型目录,则必须被允许)。
|
||||
|
||||
</Accordion>
|
||||
|
||||
### Gmail 集成
|
||||
|
||||
- 内建 Gmail preset 使用 `sessionKey: "hook:gmail:{{messages[0].id}}"`。
|
||||
- 内置 Gmail preset 使用 `sessionKey: "hook:gmail:{{messages[0].id}}"`。
|
||||
- 如果你保留这种按消息路由的方式,请设置 `hooks.allowRequestSessionKey: true`,并约束 `hooks.allowedSessionKeyPrefixes` 以匹配 Gmail 命名空间,例如 `["hook:", "hook:gmail:"]`。
|
||||
- 如果你需要 `hooks.allowRequestSessionKey: false`,请使用静态 `sessionKey` 覆盖该 preset,而不是使用默认的模板化值。
|
||||
- 如果你需要 `hooks.allowRequestSessionKey: false`,请用静态 `sessionKey` 覆盖 preset,而不是使用默认的模板化值。
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -518,8 +525,8 @@ openclaw gateway --port 19001
|
||||
}
|
||||
```
|
||||
|
||||
- 配置完成后,Gateway 网关会在启动时自动启动 `gog gmail watch serve`。设置 `OPENCLAW_SKIP_GMAIL_WATCHER=1` 可禁用。
|
||||
- 不要在 Gateway 网关旁边单独运行另一个 `gog gmail watch serve`。
|
||||
- 配置后,Gateway 网关 会在启动时自动启动 `gog gmail watch serve`。设置 `OPENCLAW_SKIP_GMAIL_WATCHER=1` 可禁用。
|
||||
- 不要在 Gateway 网关 旁边单独运行另一个 `gog gmail watch serve`。
|
||||
|
||||
---
|
||||
|
||||
@ -535,18 +542,18 @@ openclaw gateway --port 19001
|
||||
}
|
||||
```
|
||||
|
||||
- 通过 Gateway 网关端口下的 HTTP 提供可由智能体编辑的 HTML/CSS/JS 和 A2UI:
|
||||
- 通过 Gateway 网关 端口下的 HTTP 提供可由智能体编辑的 HTML / CSS / JS 和 A2UI:
|
||||
- `http://<gateway-host>:<gateway.port>/__openclaw__/canvas/`
|
||||
- `http://<gateway-host>:<gateway.port>/__openclaw__/a2ui/`
|
||||
- 仅本地:保持 `gateway.bind: "loopback"`(默认)。
|
||||
- 非 loopback bind:canvas 路由与其他 Gateway 网关 HTTP 面一样,要求 Gateway 网关凭证(token/password/trusted-proxy)。
|
||||
- Node WebView 通常不会发送凭证头;节点配对并连接后,Gateway 网关会为 canvas/A2UI 访问通告节点作用域的能力 URL。
|
||||
- 能力 URL 绑定到当前活动节点的 WS 会话,并会很快过期。不使用基于 IP 的回退。
|
||||
- 向已提供的 HTML 中注入 live-reload 客户端。
|
||||
- 为空时会自动创建起始 `index.html`。
|
||||
- 还会在 `/__openclaw__/a2ui/` 提供 A2UI。
|
||||
- 变更需要重启 Gateway 网关。
|
||||
- 对于大型目录或出现 `EMFILE` 错误时,请禁用 live reload。
|
||||
- 仅限本地:保持 `gateway.bind: "loopback"`(默认)。
|
||||
- 非 loopback bind:canvas 路由与其他 Gateway 网关 HTTP 面相同,需要 Gateway 网关 认证(token / password / trusted-proxy)。
|
||||
- 节点 WebView 通常不会发送认证头;在节点配对并连接后,Gateway 网关 会通告节点作用域的 capability URL,以便访问 canvas / A2UI。
|
||||
- Capability URL 绑定到当前活动节点 WS 会话,并且会很快过期。不使用基于 IP 的回退。
|
||||
- 会将 live-reload 客户端注入到所提供的 HTML 中。
|
||||
- 为空时会自动创建初始 `index.html`。
|
||||
- 同时还会在 `/__openclaw__/a2ui/` 提供 A2UI。
|
||||
- 更改需要重启 Gateway 网关。
|
||||
- 对于大型目录或 `EMFILE` 错误,请禁用 live reload。
|
||||
|
||||
---
|
||||
|
||||
@ -564,11 +571,11 @@ openclaw gateway --port 19001
|
||||
}
|
||||
```
|
||||
|
||||
- `minimal`(默认):在 TXT 记录中省略 `cliPath` + `sshPort`。
|
||||
- `minimal`(默认):从 TXT 记录中省略 `cliPath` + `sshPort`。
|
||||
- `full`:包含 `cliPath` + `sshPort`。
|
||||
- 主机名默认为 `openclaw`。可用 `OPENCLAW_MDNS_HOSTNAME` 覆盖。
|
||||
- 主机名默认为 `openclaw`。可通过 `OPENCLAW_MDNS_HOSTNAME` 覆盖。
|
||||
|
||||
### 广域(DNS-SD)
|
||||
### 广域网(DNS-SD)
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -578,7 +585,7 @@ openclaw gateway --port 19001
|
||||
}
|
||||
```
|
||||
|
||||
会在 `~/.openclaw/dns/` 下写入单播 DNS-SD 区域。要实现跨网络设备发现,请搭配 DNS 服务器(推荐 CoreDNS)+ Tailscale split DNS。
|
||||
会在 `~/.openclaw/dns/` 下写入一个单播 DNS-SD 区域。若要实现跨网络设备发现,请配合 DNS 服务器(推荐 CoreDNS)+ Tailscale split DNS。
|
||||
|
||||
设置:`openclaw dns setup --apply`。
|
||||
|
||||
@ -603,14 +610,14 @@ openclaw gateway --port 19001
|
||||
}
|
||||
```
|
||||
|
||||
- 仅当进程环境中缺少该键时,才会应用内联环境变量。
|
||||
- `.env` 文件:当前工作目录的 `.env` + `~/.openclaw/.env`(两者都不会覆盖现有变量)。
|
||||
- `shellEnv`:从你的登录 shell 配置中导入缺失的预期键名。
|
||||
- 仅当进程环境中缺少对应键时,才会应用内联环境变量。
|
||||
- `.env` 文件:当前工作目录中的 `.env` + `~/.openclaw/.env`(两者都不会覆盖现有变量)。
|
||||
- `shellEnv`:从你的登录 shell 配置文件导入缺失的预期键名。
|
||||
- 完整优先级请参见 [环境](/zh-CN/help/environment)。
|
||||
|
||||
### 环境变量替换
|
||||
|
||||
可在任意配置字符串中用 `${VAR_NAME}` 引用环境变量:
|
||||
可以在任何配置字符串中使用 `${VAR_NAME}` 引用环境变量:
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -621,19 +628,19 @@ openclaw gateway --port 19001
|
||||
```
|
||||
|
||||
- 仅匹配大写名称:`[A-Z_][A-Z0-9_]*`。
|
||||
- 缺失/为空的变量会在加载配置时抛出错误。
|
||||
- 使用 `$${VAR}` 可转义为字面量 `${VAR}`。
|
||||
- 对 `$include` 同样有效。
|
||||
- 缺失 / 为空的变量会在加载配置时抛出错误。
|
||||
- 使用 `$${VAR}` 来转义为字面量 `${VAR}`。
|
||||
- 可与 `$include` 一起使用。
|
||||
|
||||
---
|
||||
|
||||
## 密钥
|
||||
## Secrets
|
||||
|
||||
Secret ref 为增量特性:明文值仍然可用。
|
||||
SecretRef 是增量支持的:明文值仍然可用。
|
||||
|
||||
### `SecretRef`
|
||||
|
||||
使用如下对象形态之一:
|
||||
使用一种对象形状:
|
||||
|
||||
```json5
|
||||
{ source: "env" | "file" | "exec", provider: "default", id: "..." }
|
||||
@ -643,17 +650,17 @@ Secret ref 为增量特性:明文值仍然可用。
|
||||
|
||||
- `provider` 模式:`^[a-z][a-z0-9_-]{0,63}$`
|
||||
- `source: "env"` 的 id 模式:`^[A-Z][A-Z0-9_]{0,127}$`
|
||||
- `source: "file"` 的 id:绝对 JSON 指针(例如 `"/providers/openai/apiKey"`)
|
||||
- `source: "file"` 的 id:绝对 JSON pointer(例如 `"/providers/openai/apiKey"`)
|
||||
- `source: "exec"` 的 id 模式:`^[A-Za-z0-9][A-Za-z0-9._:/-]{0,255}$`
|
||||
- `source: "exec"` 的 id 不能包含 `.` 或 `..` 这类以斜杠分隔的路径段(例如 `a/../b` 会被拒绝)
|
||||
- `source: "exec"` 的 id 不能包含 `.` 或 `..` 这样的斜杠分隔路径段(例如 `a/../b` 会被拒绝)
|
||||
|
||||
### 支持的凭证面
|
||||
|
||||
- 规范矩阵:[SecretRef 凭证面](/zh-CN/reference/secretref-credential-surface)
|
||||
- `secrets apply` 作用于受支持的 `openclaw.json` 凭证路径。
|
||||
- `auth-profiles.json` ref 已纳入运行时解析和审计覆盖范围。
|
||||
- `secrets apply` 会定位受支持的 `openclaw.json` 凭证路径。
|
||||
- `auth-profiles.json` 引用也包含在运行时解析和审计覆盖范围内。
|
||||
|
||||
### 密钥提供商配置
|
||||
### Secret 提供商配置
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -683,14 +690,14 @@ Secret ref 为增量特性:明文值仍然可用。
|
||||
|
||||
说明:
|
||||
|
||||
- `file` 提供商支持 `mode: "json"` 和 `mode: "singleValue"`(在 singleValue 模式下,`id` 必须为 `"value"`)。
|
||||
- 当 Windows ACL 验证不可用时,file 和 exec 提供商路径会以失败关闭方式处理。仅对无法验证但受信任的路径设置 `allowInsecurePath: true`。
|
||||
- `exec` 提供商要求 `command` 为绝对路径,并通过 stdin/stdout 使用协议载荷。
|
||||
- 默认情况下,符号链接命令路径会被拒绝。设置 `allowSymlinkCommand: true` 可允许符号链接路径,同时仍验证解析后的目标路径。
|
||||
- 如果配置了 `trustedDirs`,受信任目录检查会作用于解析后的目标路径。
|
||||
- `exec` 子进程环境默认最小化;请使用 `passEnv` 显式传入所需变量。
|
||||
- Secret ref 会在激活时解析为内存快照,随后请求路径只读取该快照。
|
||||
- 激活期间会应用活动面过滤:启用面上无法解析的 ref 会导致启动/重载失败,而非活动面会被跳过并附带诊断信息。
|
||||
- `file` 提供商支持 `mode: "json"` 和 `mode: "singleValue"`(在 `singleValue` 模式下,`id` 必须为 `"value"`)。
|
||||
- 当无法验证 Windows ACL 时,file 和 exec 提供商路径会以关闭方式失败。仅在路径受信任但无法验证时,将 `allowInsecurePath: true` 设为 true。
|
||||
- `exec` 提供商要求使用绝对 `command` 路径,并通过 stdin / stdout 传输协议负载。
|
||||
- 默认情况下,符号链接命令路径会被拒绝。设置 `allowSymlinkCommand: true` 可允许符号链接路径,同时仍会验证解析后的目标路径。
|
||||
- 如果配置了 `trustedDirs`,受信任目录检查会应用到解析后的目标路径。
|
||||
- 默认情况下,`exec` 子进程环境是最小化的;请通过 `passEnv` 显式传递所需变量。
|
||||
- Secret 引用会在激活时解析为内存中的快照,之后请求路径只读取该快照。
|
||||
- 激活期间会应用活动表面过滤:已启用表面上的未解析引用会导致启动 / 重载失败,而非活动表面会被跳过并记录诊断信息。
|
||||
|
||||
---
|
||||
|
||||
@ -712,13 +719,13 @@ Secret ref 为增量特性:明文值仍然可用。
|
||||
}
|
||||
```
|
||||
|
||||
- 每个智能体的配置文件存储在 `<agentDir>/auth-profiles.json`。
|
||||
- `auth-profiles.json` 支持静态凭证模式的值级 ref(`api_key` 使用 `keyRef`,`token` 使用 `tokenRef`)。
|
||||
- OAuth 模式配置文件(`auth.profiles.<id>.mode = "oauth"`)不支持基于 SecretRef 的 auth-profile 凭证。
|
||||
- 每个智能体的 profile 存储在 `<agentDir>/auth-profiles.json`。
|
||||
- `auth-profiles.json` 支持值级引用(静态凭证模式中 `api_key` 使用 `keyRef`,`token` 使用 `tokenRef`)。
|
||||
- OAuth 模式 profile(`auth.profiles.<id>.mode = "oauth"`)不支持由 SecretRef 支持的 auth-profile 凭证。
|
||||
- 静态运行时凭证来自内存中的已解析快照;发现旧版静态 `auth.json` 条目时会被清理。
|
||||
- 旧版 OAuth 从 `~/.openclaw/credentials/oauth.json` 导入。
|
||||
- 旧版 OAuth 会从 `~/.openclaw/credentials/oauth.json` 导入。
|
||||
- 参见 [OAuth](/zh-CN/concepts/oauth)。
|
||||
- Secrets 运行时行为以及 `audit/configure/apply` 工具:参见 [Secrets 管理](/zh-CN/gateway/secrets)。
|
||||
- Secrets 运行时行为以及 `audit/configure/apply` 工具:参见 [Secrets Management](/zh-CN/gateway/secrets)。
|
||||
|
||||
### `auth.cooldowns`
|
||||
|
||||
@ -740,15 +747,20 @@ Secret ref 为增量特性:明文值仍然可用。
|
||||
}
|
||||
```
|
||||
|
||||
- `billingBackoffHours`:当某个配置文件因真正的计费/余额不足错误而失败时使用的基础退避时间,单位小时(默认:`5`)。即使在 `401`/`403` 响应上,明确的计费文本仍可能归入这里,但提供商特定的文本匹配器会继续限定在拥有它们的提供商范围内(例如 OpenRouter 的 `Key limit exceeded`)。可重试的 HTTP `402` 使用窗口或组织/工作区支出限制消息,则仍归入 `rate_limit` 路径。
|
||||
- `billingBackoffHoursByProvider`:按提供商分别覆盖计费退避小时数的可选设置。
|
||||
- `billingMaxHours`:计费退避指数增长的上限,单位小时(默认:`24`)。
|
||||
- `authPermanentBackoffMinutes`:高置信度 `auth_permanent` 失败的基础退避时间,单位分钟(默认:`10`)。
|
||||
- `authPermanentMaxMinutes`:`auth_permanent` 退避增长的上限,单位分钟(默认:`60`)。
|
||||
- `failureWindowHours`:用于退避计数器的滚动时间窗口,单位小时(默认:`24`)。
|
||||
- `overloadedProfileRotations`:对于 overloaded 错误,在切换到模型回退之前,同一提供商 auth-profile 允许轮换的最大次数(默认:`1`)。像 `ModelNotReadyException` 这样的提供商繁忙形态归入这里。
|
||||
- `overloadedBackoffMs`:在重试 overloaded 提供商/配置文件轮换前的固定延迟,单位毫秒(默认:`0`)。
|
||||
- `rateLimitedProfileRotations`:对于速率限制错误,在切换到模型回退之前,同一提供商 auth-profile 允许轮换的最大次数(默认:`1`)。该速率限制桶包括提供商特定文本,例如 `Too many concurrent requests`、`ThrottlingException`、`concurrency limit reached`、`workers_ai ... quota limit exceeded` 和 `resource exhausted`。
|
||||
- `billingBackoffHours`:当某个 profile 因真实的
|
||||
计费 / 余额不足错误而失败时使用的基础退避时长(小时)(默认:`5`)。即使在 `401` / `403` 响应中,
|
||||
明确的计费文本仍可能归入此类,但提供商特定的文本
|
||||
匹配器仍只作用于拥有它们的提供商(例如 OpenRouter 的
|
||||
`Key limit exceeded`)。可重试的 HTTP `402` 使用窗口或
|
||||
organization / workspace 支出上限消息则仍归入 `rate_limit` 路径。
|
||||
- `billingBackoffHoursByProvider`:针对计费退避时长(小时)的可选按提供商覆盖配置。
|
||||
- `billingMaxHours`:计费退避指数增长的上限时长(小时)(默认:`24`)。
|
||||
- `authPermanentBackoffMinutes`:高置信度 `auth_permanent` 失败的基础退避时长(分钟)(默认:`10`)。
|
||||
- `authPermanentMaxMinutes`:`auth_permanent` 退避增长的上限时长(分钟)(默认:`60`)。
|
||||
- `failureWindowHours`:用于退避计数器的滚动窗口时长(小时)(默认:`24`)。
|
||||
- `overloadedProfileRotations`:对 overloaded 错误,在切换到模型回退之前,同一提供商 auth-profile 允许轮换的最大次数(默认:`1`)。例如 `ModelNotReadyException` 这样的提供商忙碌形态会归入此类。
|
||||
- `overloadedBackoffMs`:在重试 overloaded 提供商 / profile 轮换之前的固定延迟(毫秒)(默认:`0`)。
|
||||
- `rateLimitedProfileRotations`:对 rate-limit 错误,在切换到模型回退之前,同一提供商 auth-profile 允许轮换的最大次数(默认:`1`)。该 rate-limit 类别包括提供商特定文本,例如 `Too many concurrent requests`、`ThrottlingException`、`concurrency limit reached`、`workers_ai ... quota limit exceeded` 和 `resource exhausted`。
|
||||
|
||||
---
|
||||
|
||||
@ -768,9 +780,9 @@ Secret ref 为增量特性:明文值仍然可用。
|
||||
```
|
||||
|
||||
- 默认日志文件:`/tmp/openclaw/openclaw-YYYY-MM-DD.log`。
|
||||
- 设置 `logging.file` 可使用固定路径。
|
||||
- 使用 `--verbose` 时,`consoleLevel` 会提升为 `debug`。
|
||||
- `maxFileBytes`:在抑制写入前,日志文件允许的最大字节数(正整数;默认:`524288000` = 500 MB)。生产环境部署请使用外部日志轮转。
|
||||
- 设置 `logging.file` 以使用固定路径。
|
||||
- 使用 `--verbose` 时,`consoleLevel` 会提升到 `debug`。
|
||||
- `maxFileBytes`:在抑制写入之前,日志文件允许的最大大小(字节)(正整数;默认:`524288000` = 500 MB)。生产部署请使用外部日志轮转。
|
||||
|
||||
---
|
||||
|
||||
@ -815,21 +827,21 @@ Secret ref 为增量特性:明文值仍然可用。
|
||||
}
|
||||
```
|
||||
|
||||
- `enabled`:检测输出总开关(默认:`true`)。
|
||||
- `flags`:用于启用定向日志输出的标志字符串数组(支持通配符,如 `"telegram.*"` 或 `"*"`)。
|
||||
- `stuckSessionWarnMs`:当会话仍处于处理中状态时,发出卡住会话警告的年龄阈值,单位毫秒。
|
||||
- `enabled`:仪表化输出的总开关(默认:`true`)。
|
||||
- `flags`:启用定向日志输出的标志字符串数组(支持像 `"telegram.*"` 或 `"*"` 这样的通配符)。
|
||||
- `stuckSessionWarnMs`:当某个会话仍处于处理状态时,发出卡住会话警告的年龄阈值(毫秒)。
|
||||
- `otel.enabled`:启用 OpenTelemetry 导出管线(默认:`false`)。
|
||||
- `otel.endpoint`:OTel 导出的采集器 URL。
|
||||
- `otel.endpoint`:OTel 导出的 collector URL。
|
||||
- `otel.protocol`:`"http/protobuf"`(默认)或 `"grpc"`。
|
||||
- `otel.headers`:随 OTel 导出请求发送的额外 HTTP/gRPC 元数据头。
|
||||
- `otel.serviceName`:资源属性的服务名称。
|
||||
- `otel.traces` / `otel.metrics` / `otel.logs`:启用 trace、metrics 或 log 导出。
|
||||
- `otel.sampleRate`:trace 采样率 `0`–`1`。
|
||||
- `otel.flushIntervalMs`:周期性遥测刷新间隔,单位毫秒。
|
||||
- `otel.captureContent`:用于 OTel span 属性的原始内容捕获显式启用项。默认关闭。布尔值 `true` 会捕获非 system 的消息/工具内容;对象形式则允许你显式启用 `inputMessages`、`outputMessages`、`toolInputs`、`toolOutputs` 和 `systemPrompt`。
|
||||
- `otel.headers`:随 OTel 导出请求发送的额外 HTTP / gRPC 元数据头。
|
||||
- `otel.serviceName`:资源属性使用的服务名。
|
||||
- `otel.traces` / `otel.metrics` / `otel.logs`:启用 trace、metrics 或日志导出。
|
||||
- `otel.sampleRate`:trace 采样率,范围 `0`–`1`。
|
||||
- `otel.flushIntervalMs`:定期刷新 telemetry 的间隔(毫秒)。
|
||||
- `otel.captureContent`:用于 OTEL span 属性的原始内容采集显式启用项。默认关闭。布尔值 `true` 会采集非 system 消息 / 工具内容;对象形式则允许你显式启用 `inputMessages`、`outputMessages`、`toolInputs`、`toolOutputs` 和 `systemPrompt`。
|
||||
- `cacheTrace.enabled`:记录嵌入式运行的缓存跟踪快照(默认:`false`)。
|
||||
- `cacheTrace.filePath`:缓存跟踪 JSONL 的输出路径(默认:`$OPENCLAW_STATE_DIR/logs/cache-trace.jsonl`)。
|
||||
- `cacheTrace.includeMessages` / `includePrompt` / `includeSystem`:控制缓存跟踪输出中包含的内容(默认都为 `true`)。
|
||||
- `cacheTrace.includeMessages` / `includePrompt` / `includeSystem`:控制缓存跟踪输出中包含哪些内容(默认全部为 `true`)。
|
||||
|
||||
---
|
||||
|
||||
@ -851,12 +863,12 @@ Secret ref 为增量特性:明文值仍然可用。
|
||||
}
|
||||
```
|
||||
|
||||
- `channel`:用于 npm/git 安装的发布渠道——`"stable"`、`"beta"` 或 `"dev"`。
|
||||
- `checkOnStart`:Gateway 网关启动时检查 npm 更新(默认:`true`)。
|
||||
- `auto.enabled`:为包安装启用后台自动更新(默认:`false`)。
|
||||
- `auto.stableDelayHours`:stable 渠道自动应用前的最小时延,单位小时(默认:`6`;最大:`168`)。
|
||||
- `auto.stableJitterHours`:stable 渠道额外的发布扩散窗口,单位小时(默认:`12`;最大:`168`)。
|
||||
- `auto.betaCheckIntervalHours`:beta 渠道检查的运行频率,单位小时(默认:`1`;最大:`24`)。
|
||||
- `channel`:npm / git 安装的发布渠道——`"stable"`、`"beta"` 或 `"dev"`。
|
||||
- `checkOnStart`:Gateway 网关 启动时检查 npm 更新(默认:`true`)。
|
||||
- `auto.enabled`:为 package 安装启用后台自动更新(默认:`false`)。
|
||||
- `auto.stableDelayHours`:稳定渠道自动应用前的最小时延(小时)(默认:`6`;最大:`168`)。
|
||||
- `auto.stableJitterHours`:稳定渠道额外的发布扩散窗口(小时)(默认:`12`;最大:`168`)。
|
||||
- `auto.betaCheckIntervalHours`:beta 渠道检查运行的频率(小时)(默认:`1`;最大:`24`)。
|
||||
|
||||
---
|
||||
|
||||
@ -891,20 +903,20 @@ Secret ref 为增量特性:明文值仍然可用。
|
||||
|
||||
- `enabled`:全局 ACP 功能开关(默认:`false`)。
|
||||
- `dispatch.enabled`:ACP 会话轮次分发的独立开关(默认:`true`)。设为 `false` 可在阻止执行的同时保留 ACP 命令可用。
|
||||
- `backend`:默认 ACP 运行时后端 id(必须匹配已注册的 ACP 运行时插件)。
|
||||
- `defaultAgent`:当 spawn 未指定显式目标时的 ACP 回退目标智能体 id。
|
||||
- `allowedAgents`:允许用于 ACP 运行时会话的智能体 id 允许列表;为空表示不施加额外限制。
|
||||
- `maxConcurrentSessions`:同时处于活动状态的 ACP 会话最大数量。
|
||||
- `stream.coalesceIdleMs`:流式文本的空闲合并刷新窗口,单位毫秒。
|
||||
- `stream.maxChunkChars`:流式分块投影在拆分前的最大块大小。
|
||||
- `stream.repeatSuppression`:每轮抑制重复的状态/工具行(默认:`true`)。
|
||||
- `stream.deliveryMode`:`"live"` 为增量流式传输;`"final_only"` 会缓冲到轮次终止事件后再输出。
|
||||
- `backend`:默认 ACP 运行时后端 id(必须与已注册的 ACP 运行时插件匹配)。
|
||||
- `defaultAgent`:当生成过程未指定显式目标时,ACP 的回退目标智能体 id。
|
||||
- `allowedAgents`:允许用于 ACP 运行时会话的智能体 id 允许列表;空值表示无额外限制。
|
||||
- `maxConcurrentSessions`:同时活跃的 ACP 会话最大数量。
|
||||
- `stream.coalesceIdleMs`:流式文本的空闲合并刷新窗口(毫秒)。
|
||||
- `stream.maxChunkChars`:在拆分流式分块投影前允许的最大块大小。
|
||||
- `stream.repeatSuppression`:每轮抑制重复的状态 / 工具行(默认:`true`)。
|
||||
- `stream.deliveryMode`:`"live"` 表示增量流式传输;`"final_only"` 表示缓冲到轮次终止事件后再输出。
|
||||
- `stream.hiddenBoundarySeparator`:隐藏工具事件后、可见文本前的分隔符(默认:`"paragraph"`)。
|
||||
- `stream.maxOutputChars`:每个 ACP 轮次投影的智能体输出最大字符数。
|
||||
- `stream.maxSessionUpdateChars`:投影的 ACP 状态/更新行最大字符数。
|
||||
- `stream.tagVisibility`:tag 名称到布尔可见性覆盖值的记录,用于流式事件。
|
||||
- `runtime.ttlMinutes`:ACP 会话工作进程在符合清理条件前的空闲 TTL,单位分钟。
|
||||
- `runtime.installCommand`:引导 ACP 运行时环境时要运行的可选安装命令。
|
||||
- `stream.maxSessionUpdateChars`:投影的 ACP 状态 / 更新行最大字符数。
|
||||
- `stream.tagVisibility`:tag 名称到布尔可见性覆盖的记录,用于流式事件。
|
||||
- `runtime.ttlMinutes`:ACP 会话 worker 在可清理前的空闲 TTL(分钟)。
|
||||
- `runtime.installCommand`:在引导 ACP 运行时环境时运行的可选安装命令。
|
||||
|
||||
---
|
||||
|
||||
@ -920,11 +932,11 @@ Secret ref 为增量特性:明文值仍然可用。
|
||||
}
|
||||
```
|
||||
|
||||
- `cli.banner.taglineMode` 控制横幅标语样式:
|
||||
- `"random"`(默认):轮换的有趣/季节性标语。
|
||||
- `cli.banner.taglineMode` 控制 banner 标语样式:
|
||||
- `"random"`(默认):轮换的有趣 / 季节性标语。
|
||||
- `"default"`:固定的中性标语(`All your chats, one OpenClaw.`)。
|
||||
- `"off"`:不显示标语文本(仍显示横幅标题/版本)。
|
||||
- 若要隐藏整个横幅(而不仅仅是标语),请设置环境变量 `OPENCLAW_HIDE_BANNER=1`。
|
||||
- `"off"`:不显示标语文本(仍显示 banner 标题 / 版本)。
|
||||
- 如需隐藏整个 banner(不只是标语),请设置环境变量 `OPENCLAW_HIDE_BANNER=1`。
|
||||
|
||||
---
|
||||
|
||||
@ -948,13 +960,13 @@ Secret ref 为增量特性:明文值仍然可用。
|
||||
|
||||
## 身份
|
||||
|
||||
请参见 [智能体默认值](/zh-CN/gateway/config-agents#agent-defaults) 下 `agents.list` 的身份字段。
|
||||
请参见 [智能体默认值](/zh-CN/gateway/config-agents#agent-defaults) 下的 `agents.list` 身份字段。
|
||||
|
||||
---
|
||||
|
||||
## Bridge protocol(旧版节点,历史参考)(旧版,已移除)
|
||||
|
||||
当前构建已不再包含 TCP bridge。节点通过 Gateway 网关 WebSocket 连接。`bridge.*` 键已不再属于配置 schema 的一部分(移除前验证会失败;`openclaw doctor --fix` 可以剥离未知键)。
|
||||
当前构建版本不再包含 TCP bridge。节点通过 Gateway 网关 WebSocket 连接。`bridge.*` 键已不再属于配置 schema 的一部分(在移除之前,验证会失败;`openclaw doctor --fix` 可以剥离未知键)。
|
||||
|
||||
<Accordion title="旧版 bridge 配置(历史参考)">
|
||||
|
||||
@ -994,11 +1006,11 @@ Secret ref 为增量特性:明文值仍然可用。
|
||||
}
|
||||
```
|
||||
|
||||
- `sessionRetention`:在从 `sessions.json` 清理前,保留已完成隔离 cron 运行会话的时长。也控制已归档的已删除 cron 转录的清理。默认:`24h`;设为 `false` 可禁用。
|
||||
- `runLog.maxBytes`:每个运行日志文件(`cron/runs/<jobId>.jsonl`)在触发裁剪前的最大大小。默认:`2_000_000` 字节。
|
||||
- `runLog.keepLines`:触发运行日志裁剪时保留的最新行数。默认:`2000`。
|
||||
- `webhookToken`:用于 cron webhook POST 投递(`delivery.mode = "webhook"`)的 bearer token;若省略,则不发送凭证头。
|
||||
- `webhook`:已弃用的旧版回退 webhook URL(http/https),仅用于仍保留 `notify: true` 的已存储任务。
|
||||
- `sessionRetention`:在从 `sessions.json` 修剪之前,已完成的隔离 cron 运行会话保留多长时间。同时也控制已归档的已删除 cron transcript 的清理。默认:`24h`;设为 `false` 可禁用。
|
||||
- `runLog.maxBytes`:每个运行日志文件(`cron/runs/<jobId>.jsonl`)在修剪前允许的最大大小。默认:`2_000_000` 字节。
|
||||
- `runLog.keepLines`:触发运行日志修剪时保留的最新行数。默认:`2000`。
|
||||
- `webhookToken`:用于 cron webhook POST 投递(`delivery.mode = "webhook"`)的 bearer token;若省略,则不会发送认证头。
|
||||
- `webhook`:已弃用的旧版回退 webhook URL(http / https),仅用于仍保留 `notify: true` 的已存储任务。
|
||||
|
||||
### `cron.retry`
|
||||
|
||||
@ -1014,11 +1026,11 @@ Secret ref 为增量特性:明文值仍然可用。
|
||||
}
|
||||
```
|
||||
|
||||
- `maxAttempts`:一次性任务在瞬时错误下的最大重试次数(默认:`3`;范围:`0`–`10`)。
|
||||
- `backoffMs`:每次重试尝试对应的退避延迟数组,单位毫秒(默认:`[30000, 60000, 300000]`;1–10 项)。
|
||||
- `retryOn`:触发重试的错误类型——`"rate_limit"`、`"overloaded"`、`"network"`、`"timeout"`、`"server_error"`。省略则会重试所有瞬时错误类型。
|
||||
- `maxAttempts`:one-shot cron 任务在瞬时错误下的最大重试次数(默认:`3`;范围:`0`–`10`)。
|
||||
- `backoffMs`:每次重试的退避延迟数组(毫秒)(默认:`[30000, 60000, 300000]`;1–10 项)。
|
||||
- `retryOn`:触发重试的错误类型——`"rate_limit"`、`"overloaded"`、`"network"`、`"timeout"`、`"server_error"`。省略则表示重试所有瞬时类型。
|
||||
|
||||
仅适用于一次性 cron 任务。周期性任务使用独立的失败处理逻辑。
|
||||
仅适用于 one-shot cron 任务。周期性任务使用单独的失败处理方式。
|
||||
|
||||
### `cron.failureAlert`
|
||||
|
||||
@ -1036,10 +1048,10 @@ Secret ref 为增量特性:明文值仍然可用。
|
||||
}
|
||||
```
|
||||
|
||||
- `enabled`:为 cron 任务启用失败告警(默认:`false`)。
|
||||
- `enabled`:启用 cron 任务失败告警(默认:`false`)。
|
||||
- `after`:连续失败多少次后触发告警(正整数,最小值:`1`)。
|
||||
- `cooldownMs`:同一任务重复告警之间的最短间隔,单位毫秒(非负整数)。
|
||||
- `mode`:投递模式——`"announce"` 通过渠道消息发送;`"webhook"` 则 POST 到已配置的 webhook。
|
||||
- `cooldownMs`:同一任务重复告警之间的最小间隔(毫秒)(非负整数)。
|
||||
- `mode`:投递模式——`"announce"` 通过渠道消息发送;`"webhook"` 向配置的 webhook 发送 POST 请求。
|
||||
- `accountId`:用于限定告警投递范围的可选账号或渠道 id。
|
||||
|
||||
### `cron.failureDestination`
|
||||
@ -1057,16 +1069,16 @@ Secret ref 为增量特性:明文值仍然可用。
|
||||
}
|
||||
```
|
||||
|
||||
- 所有任务共用的 cron 失败通知默认目标。
|
||||
- 所有 cron 任务失败通知的默认目标位置。
|
||||
- `mode`:`"announce"` 或 `"webhook"`;当存在足够的目标数据时,默认值为 `"announce"`。
|
||||
- `channel`:announce 投递的渠道覆盖值。`"last"` 会复用最后一次已知投递渠道。
|
||||
- `to`:显式的 announce 目标或 webhook URL。webhook 模式下为必填。
|
||||
- `accountId`:投递时使用的可选账号覆盖值。
|
||||
- 每个任务的 `delivery.failureDestination` 会覆盖该全局默认值。
|
||||
- 当既未设置全局失败目标,也未设置按任务失败目标时,那些已通过 `announce` 投递的任务会在失败时回退到其主 announce 目标。
|
||||
- `delivery.failureDestination` 仅支持 `sessionTarget="isolated"` 的任务,除非该任务的主 `delivery.mode` 为 `"webhook"`。
|
||||
- `channel`:announce 投递的渠道覆盖值。`"last"` 会复用上次已知的投递渠道。
|
||||
- `to`:显式的 announce 目标或 webhook URL。在 webhook 模式下为必填项。
|
||||
- `accountId`:可选的投递账号覆盖值。
|
||||
- 每个任务的 `delivery.failureDestination` 会覆盖此全局默认值。
|
||||
- 当全局和每个任务的失败目标位置都未设置时,已通过 `announce` 投递的任务在失败时会回退到其主 announce 目标。
|
||||
- `delivery.failureDestination` 仅对 `sessionTarget="isolated"` 的任务受支持,除非该任务的主 `delivery.mode` 为 `"webhook"`。
|
||||
|
||||
参见 [Cron 任务](/zh-CN/automation/cron-jobs)。隔离的 cron 执行会作为 [后台任务](/zh-CN/automation/tasks) 进行跟踪。
|
||||
参见 [Cron Jobs](/zh-CN/automation/cron-jobs)。隔离的 cron 执行会作为[后台任务](/zh-CN/automation/tasks)进行跟踪。
|
||||
|
||||
---
|
||||
|
||||
@ -1075,18 +1087,18 @@ Secret ref 为增量特性:明文值仍然可用。
|
||||
在 `tools.media.models[].args` 中展开的模板占位符:
|
||||
|
||||
| Variable | 说明 |
|
||||
| ------------------ | ------------------------------------------------- |
|
||||
| ------------------ | ---- |
|
||||
| `{{Body}}` | 完整的入站消息正文 |
|
||||
| `{{RawBody}}` | 原始正文(无历史记录/发送者包装) |
|
||||
| `{{BodyStripped}}` | 移除了群组提及的正文 |
|
||||
| `{{RawBody}}` | 原始正文(不含历史记录 / 发送者包装) |
|
||||
| `{{BodyStripped}}` | 去除群组提及后的正文 |
|
||||
| `{{From}}` | 发送者标识符 |
|
||||
| `{{To}}` | 目标标识符 |
|
||||
| `{{MessageSid}}` | 渠道消息 id |
|
||||
| `{{SessionId}}` | 当前会话 UUID |
|
||||
| `{{IsNewSession}}` | 新建会话时为 `"true"` |
|
||||
| `{{IsNewSession}}` | 新会话已创建时为 `"true"` |
|
||||
| `{{MediaUrl}}` | 入站媒体伪 URL |
|
||||
| `{{MediaPath}}` | 本地媒体路径 |
|
||||
| `{{MediaType}}` | 媒体类型(image/audio/document/…) |
|
||||
| `{{MediaType}}` | 媒体类型(image / audio / document / …) |
|
||||
| `{{Transcript}}` | 音频转录文本 |
|
||||
| `{{Prompt}}` | CLI 条目的已解析媒体提示词 |
|
||||
| `{{MaxChars}}` | CLI 条目的已解析最大输出字符数 |
|
||||
@ -1101,7 +1113,7 @@ Secret ref 为增量特性:明文值仍然可用。
|
||||
|
||||
## 配置 include(`$include`)
|
||||
|
||||
将配置拆分到多个文件中:
|
||||
将配置拆分为多个文件:
|
||||
|
||||
```json5
|
||||
// ~/.openclaw/openclaw.json
|
||||
@ -1116,18 +1128,18 @@ Secret ref 为增量特性:明文值仍然可用。
|
||||
|
||||
**合并行为:**
|
||||
|
||||
- 单个文件:替换所在的包含对象。
|
||||
- 文件数组:按顺序进行深度合并(后者覆盖前者)。
|
||||
- 同级键:在 includes 之后合并(覆盖 include 的值)。
|
||||
- 单个文件:替换其所在的包含对象。
|
||||
- 文件数组:按顺序深度合并(后者覆盖前者)。
|
||||
- 同级键:在 include 之后合并(覆盖 include 中的值)。
|
||||
- 嵌套 include:最多支持 10 层深度。
|
||||
- 路径:相对于包含它的文件解析,但必须保持在顶层配置目录(`openclaw.json` 的 `dirname`)内。仅当绝对路径/`../` 最终仍解析到该边界内时才允许。
|
||||
- 仅变更某个由单文件 include 支持的顶层 section 的 OpenClaw 自有写入,会直写到该 include 文件。例如,`plugins install` 会将 `plugins: { $include: "./plugins.json5" }` 更新到 `plugins.json5` 中,并保持 `openclaw.json` 不变。
|
||||
- 根级 include、include 数组以及带有同级覆盖的 include,对 OpenClaw 自有写入均为只读;这些写入会以失败关闭方式终止,而不是将配置拍平。
|
||||
- 错误:会为缺失文件、解析错误和循环 include 提供清晰消息。
|
||||
- 路径:相对于包含它的文件解析,但必须保持在顶层配置目录(`openclaw.json` 的 `dirname`)之内。仅当绝对路径 / `../` 形式最终仍解析到该边界内时才允许。
|
||||
- 当 OpenClaw 自有写入仅更改由单文件 include 支持的某个顶层 section 时,写入会透传到该 include 文件。例如,`plugins install` 会更新 `plugins: { $include: "./plugins.json5" }` 中的 `plugins.json5`,并保持 `openclaw.json` 不变。
|
||||
- 根 include、include 数组以及带同级覆盖的 include 对 OpenClaw 自有写入是只读的;这些写入会以关闭方式失败,而不是将配置拍平。
|
||||
- 错误:对于缺失文件、解析错误和循环 include,会提供清晰的错误消息。
|
||||
|
||||
---
|
||||
|
||||
_相关:[配置](/zh-CN/gateway/configuration) · [配置示例](/zh-CN/gateway/configuration-examples) · [Doctor](/zh-CN/gateway/doctor)_
|
||||
_相关内容:[配置](/zh-CN/gateway/configuration) · [配置示例](/zh-CN/gateway/configuration-examples) · [Doctor](/zh-CN/gateway/doctor)_
|
||||
|
||||
## 相关
|
||||
|
||||
|
||||
@ -1,111 +1,140 @@
|
||||
---
|
||||
read_when:
|
||||
- 运行实时模型矩阵 / CLI 后端 / ACP / 媒体提供商冒烟测试
|
||||
- 调试实时测试凭证解析
|
||||
- 调试实时测试的凭证解析
|
||||
- 添加新的提供商专用实时测试
|
||||
sidebarTitle: Live tests
|
||||
summary: 实时(涉及网络)的测试:模型矩阵、CLI 后端、ACP、媒体提供商、凭证
|
||||
title: 测试:实时测试套件
|
||||
title: 测试:实时套件
|
||||
x-i18n:
|
||||
generated_at: "2026-04-25T02:55:43Z"
|
||||
generated_at: "2026-04-25T04:55:00Z"
|
||||
model: gpt-5.4
|
||||
provider: openai
|
||||
source_hash: 1e49df93f47dfe6a53e72d13d4bf01c372ed163f2d08c656640370ef511a00cd
|
||||
source_hash: 3a475044ae7ae914d36b2530ca204eb7b632bc578e4ed16770811617ffc05d83
|
||||
source_path: help/testing-live.md
|
||||
workflow: 15
|
||||
---
|
||||
|
||||
如需了解快速开始、QA 运行器、单元/集成测试以及 Docker 流程,请参阅
|
||||
[测试](/zh-CN/help/testing)。本页介绍**实时**(涉及网络)的测试
|
||||
关于快速开始、QA 运行器、单元/集成套件以及 Docker 流程,请参见
|
||||
[测试](/zh-CN/help/testing)。本页介绍 **实时**(涉及网络)的测试
|
||||
套件:模型矩阵、CLI 后端、ACP 和媒体提供商实时测试,以及
|
||||
凭证处理。
|
||||
|
||||
## 实时:本地配置文件冒烟命令
|
||||
|
||||
在进行临时实时检查前,先加载 `~/.profile`,这样提供商密钥和本地工具路径
|
||||
才能与你的 shell 保持一致:
|
||||
|
||||
```bash
|
||||
source ~/.profile
|
||||
```
|
||||
|
||||
安全的媒体冒烟测试:
|
||||
|
||||
```bash
|
||||
pnpm openclaw infer tts convert --local --json \
|
||||
--text "OpenClaw live smoke." \
|
||||
--output /tmp/openclaw-live-smoke.mp3
|
||||
```
|
||||
|
||||
安全的语音呼叫就绪性冒烟测试:
|
||||
|
||||
```bash
|
||||
pnpm openclaw voicecall setup --json
|
||||
pnpm openclaw voicecall smoke --to "+15555550123"
|
||||
```
|
||||
|
||||
除非同时提供 `--yes`,否则 `voicecall smoke` 是一次演练。仅当
|
||||
你有意发起真实通知电话时才使用 `--yes`。对于 Twilio、Telnyx 和
|
||||
Plivo,成功的就绪性检查需要一个公开的 webhook URL;仅本地
|
||||
loopback/私有回退方案会按设计被拒绝。
|
||||
|
||||
## 实时:Android 节点能力全面检查
|
||||
|
||||
- 测试:`src/gateway/android-node.capabilities.live.test.ts`
|
||||
- 脚本:`pnpm android:test:integration`
|
||||
- 目标:调用已连接 Android 节点当前**声明的每一条命令**,并断言命令契约行为。
|
||||
- 目标:调用已连接 Android 节点当前**通告的每一条命令**,并断言命令契约行为。
|
||||
- 范围:
|
||||
- 需要预先完成/手动完成设置(该测试套件不会安装/运行/配对应用)。
|
||||
- 针对选定 Android 节点逐条命令执行 Gateway 网关 `node.invoke` 验证。
|
||||
- 所需预先设置:
|
||||
- 需要预先满足条件/手动设置(该套件不会安装/运行/配对应用)。
|
||||
- 对所选 Android 节点逐条执行 Gateway 网关 `node.invoke` 验证。
|
||||
- 必需的预先设置:
|
||||
- Android 应用已连接并已与 Gateway 网关配对。
|
||||
- 应用保持在前台。
|
||||
- 你期望通过的能力所需的权限/捕获同意已授予。
|
||||
- 应用保持在前台运行。
|
||||
- 你期望通过的能力所需的权限/采集授权已授予。
|
||||
- 可选目标覆盖:
|
||||
- `OPENCLAW_ANDROID_NODE_ID` 或 `OPENCLAW_ANDROID_NODE_NAME`。
|
||||
- `OPENCLAW_ANDROID_GATEWAY_URL` / `OPENCLAW_ANDROID_GATEWAY_TOKEN` / `OPENCLAW_ANDROID_GATEWAY_PASSWORD`。
|
||||
- 完整 Android 设置详情:[Android 应用](/zh-CN/platforms/android)
|
||||
- 完整 Android 设置详情: [Android App](/zh-CN/platforms/android)
|
||||
|
||||
## 实时:模型冒烟测试(配置档键)
|
||||
## 实时:模型冒烟测试(配置文件密钥)
|
||||
|
||||
实时测试分为两层,以便我们隔离故障:
|
||||
实时测试分为两层,这样我们可以隔离故障:
|
||||
|
||||
- “Direct model” 用于告诉我们,在给定键的情况下,提供商/模型是否至少能够返回响应。
|
||||
- “Gateway smoke” 用于告诉我们,该模型的完整 Gateway 网关 + 智能体流水线是否正常工作(会话、历史、工具、沙箱策略等)。
|
||||
- “直接模型”用于判断提供商/模型在给定密钥下是否至少能够返回响应。
|
||||
- “Gateway 冒烟测试”用于判断该模型的完整 Gateway 网关 + 智能体流水线是否正常工作(会话、历史、工具、沙箱策略等)。
|
||||
|
||||
### 第 1 层:直接模型补全(无 Gateway 网关)
|
||||
|
||||
- 测试:`src/agents/models.profiles.live.test.ts`
|
||||
- 目标:
|
||||
- 枚举发现到的模型
|
||||
- 使用 `getApiKeyForModel` 选择你拥有凭证的模型
|
||||
- 为每个模型运行一个小型补全测试(并在需要时运行定向回归测试)
|
||||
- 如何启用:
|
||||
- `pnpm test:live`(或在直接调用 Vitest 时设置 `OPENCLAW_LIVE_TEST=1`)
|
||||
- 设置 `OPENCLAW_LIVE_MODELS=modern`(或 `all`,它是 `modern` 的别名)才会实际运行此测试套件;否则会跳过,以便让 `pnpm test:live` 聚焦于 Gateway 网关冒烟测试
|
||||
- 枚举已发现的模型
|
||||
- 使用 `getApiKeyForModel` 选择你具备凭证的模型
|
||||
- 对每个模型运行一个小型补全请求(并在需要时运行定向回归测试)
|
||||
- 启用方式:
|
||||
- `pnpm test:live`(或如果你直接调用 Vitest,则设置 `OPENCLAW_LIVE_TEST=1`)
|
||||
- 设置 `OPENCLAW_LIVE_MODELS=modern`(或 `all`,即 modern 的别名)才会真正运行此套件;否则它会跳过,以便让 `pnpm test:live` 专注于 Gateway 网关冒烟测试
|
||||
- 如何选择模型:
|
||||
- `OPENCLAW_LIVE_MODELS=modern` 运行现代允许列表(Opus/Sonnet 4.6+、GPT-5.2 + Codex、Gemini 3、DeepSeek V4、GLM 4.7、MiniMax M2.7、Grok 4)
|
||||
- `OPENCLAW_LIVE_MODELS=all` 是现代允许列表的别名
|
||||
- 或 `OPENCLAW_LIVE_MODELS="openai/gpt-5.2,openai-codex/gpt-5.2,anthropic/claude-opus-4-6,..."`(逗号分隔的允许列表)
|
||||
- modern/all 全面检查默认会使用精心筛选的高信号上限;设置 `OPENCLAW_LIVE_MAX_MODELS=0` 可执行完整的现代模型全面检查,或设置为正数以使用更小的上限。
|
||||
- 完整全面检查会对整个直接模型测试超时使用 `OPENCLAW_LIVE_TEST_TIMEOUT_MS`。默认值:60 分钟。
|
||||
- 直接模型探测默认以 20 路并行运行;可设置 `OPENCLAW_LIVE_MODEL_CONCURRENCY` 进行覆盖。
|
||||
- 或者 `OPENCLAW_LIVE_MODELS="openai/gpt-5.2,openai-codex/gpt-5.2,anthropic/claude-opus-4-6,..."`(逗号分隔的允许列表)
|
||||
- modern/all 全量检查默认使用经过挑选的高信号上限;设置 `OPENCLAW_LIVE_MAX_MODELS=0` 可执行完整的 modern 全量检查,或设为正数以使用更小的上限。
|
||||
- 完整全量检查对整个直接模型测试使用 `OPENCLAW_LIVE_TEST_TIMEOUT_MS` 超时时间。默认值:60 分钟。
|
||||
- 直接模型探测默认使用 20 路并行;可设置 `OPENCLAW_LIVE_MODEL_CONCURRENCY` 进行覆盖。
|
||||
- 如何选择提供商:
|
||||
- `OPENCLAW_LIVE_PROVIDERS="google,google-antigravity,google-gemini-cli"`(逗号分隔的允许列表)
|
||||
- 键来自哪里:
|
||||
- 默认:配置档存储和环境变量回退
|
||||
- 设置 `OPENCLAW_LIVE_REQUIRE_PROFILE_KEYS=1` 以强制**仅使用配置档存储**
|
||||
- 为什么需要这个:
|
||||
- 将“提供商 API 已损坏 / 键无效”与“Gateway 网关智能体流水线已损坏”区分开来
|
||||
- 包含体量小、隔离良好的回归测试(示例:OpenAI Responses/Codex Responses 推理重放 + 工具调用流程)
|
||||
- 密钥来源:
|
||||
- 默认:配置文件存储和环境变量回退
|
||||
- 设置 `OPENCLAW_LIVE_REQUIRE_PROFILE_KEYS=1` 可强制**仅使用配置文件存储**
|
||||
- 存在意义:
|
||||
- 将“提供商 API 出故障 / 密钥无效”与“Gateway 网关智能体流水线出故障”区分开
|
||||
- 容纳小型、隔离的回归测试(例如:OpenAI Responses/Codex Responses 的推理回放 + 工具调用流程)
|
||||
|
||||
### 第 2 层:Gateway 网关 + dev 智能体冒烟测试(也就是 “@openclaw” 实际执行的内容)
|
||||
### 第 2 层:Gateway 网关 + dev 智能体冒烟测试(即 “@openclaw” 实际执行的内容)
|
||||
|
||||
- 测试:`src/gateway/gateway-models.profiles.live.test.ts`
|
||||
- 目标:
|
||||
- 启动进程内 Gateway 网关
|
||||
- 启动一个进程内 Gateway 网关
|
||||
- 创建/修补一个 `agent:dev:*` 会话(每次运行覆盖模型)
|
||||
- 遍历带键的模型并断言:
|
||||
- 遍历带密钥的模型并断言:
|
||||
- “有意义的”响应(无工具)
|
||||
- 一次真实工具调用可正常工作(读取探测)
|
||||
- 可选的额外工具探测(exec+read 探测)
|
||||
- OpenAI 回归路径(仅工具调用 → 后续跟进)持续可用
|
||||
- 探测细节(便于你快速解释故障):
|
||||
- `read` 探测:测试会在工作区写入一个 nonce 文件,并要求智能体 `read` 它并回显该 nonce。
|
||||
- `exec+read` 探测:测试会要求智能体通过 `exec` 将一个 nonce 写入临时文件,然后再 `read` 回来。
|
||||
- 图像探测:测试会附加一个生成的 PNG(猫 + 随机代码),并期望模型返回 `cat <CODE>`。
|
||||
- 一次真实的工具调用可以正常工作(read 探针)
|
||||
- 可选的额外工具探针(exec+read 探针)
|
||||
- OpenAI 回归路径(仅工具调用 → 后续跟进)持续正常
|
||||
- 探针细节(这样你可以快速解释故障):
|
||||
- `read` 探针:测试会在工作区中写入一个 nonce 文件,并要求智能体 `read` 该文件并回显 nonce。
|
||||
- `exec+read` 探针:测试会要求智能体通过 `exec` 将 nonce 写入临时文件,然后再 `read` 回来。
|
||||
- 图像探针:测试会附加一个生成的 PNG(猫 + 随机代码),并期望模型返回 `cat <CODE>`。
|
||||
- 实现参考:`src/gateway/gateway-models.profiles.live.test.ts` 和 `src/gateway/live-image-probe.ts`。
|
||||
- 如何启用:
|
||||
- `pnpm test:live`(或在直接调用 Vitest 时设置 `OPENCLAW_LIVE_TEST=1`)
|
||||
- 启用方式:
|
||||
- `pnpm test:live`(或如果你直接调用 Vitest,则设置 `OPENCLAW_LIVE_TEST=1`)
|
||||
- 如何选择模型:
|
||||
- 默认:现代允许列表(Opus/Sonnet 4.6+、GPT-5.2 + Codex、Gemini 3、DeepSeek V4、GLM 4.7、MiniMax M2.7、Grok 4)
|
||||
- `OPENCLAW_LIVE_GATEWAY_MODELS=all` 是现代允许列表的别名
|
||||
- 或设置 `OPENCLAW_LIVE_GATEWAY_MODELS="provider/model"`(或逗号列表)以缩小范围
|
||||
- modern/all Gateway 网关全面检查默认会使用精心筛选的高信号上限;设置 `OPENCLAW_LIVE_GATEWAY_MAX_MODELS=0` 可执行完整的现代模型全面检查,或设置为正数以使用更小的上限。
|
||||
- 如何选择提供商(避免“OpenRouter 全部都测”):
|
||||
- modern/all Gateway 网关全量检查默认使用经过挑选的高信号上限;设置 `OPENCLAW_LIVE_GATEWAY_MAX_MODELS=0` 可执行完整的 modern 全量检查,或设为正数以使用更小的上限。
|
||||
- 如何选择提供商(避免 “OpenRouter 全部都测”):
|
||||
- `OPENCLAW_LIVE_GATEWAY_PROVIDERS="google,google-antigravity,google-gemini-cli,openai,anthropic,zai,minimax"`(逗号分隔的允许列表)
|
||||
- 工具 + 图像探测在此实时测试中始终启用:
|
||||
- `read` 探测 + `exec+read` 探测(工具压力测试)
|
||||
- 当模型声明支持图像输入时,运行图像探测
|
||||
- 流程(高层概述):
|
||||
- 在此实时测试中,工具 + 图像探针始终启用:
|
||||
- `read` 探针 + `exec+read` 探针(工具压力测试)
|
||||
- 当模型声明支持图像输入时,图像探针会运行
|
||||
- 流程(高层说明):
|
||||
- 测试生成一个带有 “CAT” + 随机代码的小型 PNG(`src/gateway/live-image-probe.ts`)
|
||||
- 通过 `agent` `attachments: [{ mimeType: "image/png", content: "<base64>" }]` 发送
|
||||
- Gateway 网关将附件解析为 `images[]`(`src/gateway/server-methods/agent.ts` + `src/gateway/chat-attachments.ts`)
|
||||
- 嵌入式智能体将多模态用户消息转发给模型
|
||||
- 内嵌智能体将多模态用户消息转发给模型
|
||||
- 断言:回复包含 `cat` + 该代码(OCR 容错:允许轻微错误)
|
||||
|
||||
提示:如需查看你的机器上可以测试哪些内容(以及精确的 `provider/model` id),请运行:
|
||||
提示:要查看你的机器上可以测试什么(以及准确的 `provider/model` id),请运行:
|
||||
|
||||
```bash
|
||||
openclaw models list
|
||||
@ -115,10 +144,10 @@ openclaw models list --json
|
||||
## 实时:CLI 后端冒烟测试(Claude、Codex、Gemini 或其他本地 CLI)
|
||||
|
||||
- 测试:`src/gateway/gateway-cli-backend.live.test.ts`
|
||||
- 目标:在不触碰你的默认配置的前提下,使用本地 CLI 后端验证 Gateway 网关 + 智能体流水线。
|
||||
- 后端专用的冒烟测试默认值位于所属扩展的 `cli-backend.ts` 定义中。
|
||||
- 目标:在不触碰默认配置的情况下,使用本地 CLI 后端验证 Gateway 网关 + 智能体流水线。
|
||||
- 后端专用的默认冒烟设置位于所属扩展的 `cli-backend.ts` 定义中。
|
||||
- 启用:
|
||||
- `pnpm test:live`(或在直接调用 Vitest 时设置 `OPENCLAW_LIVE_TEST=1`)
|
||||
- `pnpm test:live`(或如果你直接调用 Vitest,则设置 `OPENCLAW_LIVE_TEST=1`)
|
||||
- `OPENCLAW_LIVE_CLI_BACKEND=1`
|
||||
- 默认值:
|
||||
- 默认提供商/模型:`claude-cli/claude-sonnet-4-6`
|
||||
@ -127,12 +156,12 @@ openclaw models list --json
|
||||
- `OPENCLAW_LIVE_CLI_BACKEND_MODEL="codex-cli/gpt-5.2"`
|
||||
- `OPENCLAW_LIVE_CLI_BACKEND_COMMAND="/full/path/to/codex"`
|
||||
- `OPENCLAW_LIVE_CLI_BACKEND_ARGS='["exec","--json","--color","never","--sandbox","read-only","--skip-git-repo-check"]'`
|
||||
- `OPENCLAW_LIVE_CLI_BACKEND_IMAGE_PROBE=1` 发送真实图像附件(路径会被注入到提示中)。Docker 配方默认关闭此项,除非明确请求。
|
||||
- `OPENCLAW_LIVE_CLI_BACKEND_IMAGE_ARG="--image"` 通过 CLI 参数传递图像文件路径,而不是注入到提示中。
|
||||
- `OPENCLAW_LIVE_CLI_BACKEND_IMAGE_PROBE=1` 发送真实图像附件(路径会注入到提示中)。除非明确请求,否则 Docker 配方默认关闭此项。
|
||||
- `OPENCLAW_LIVE_CLI_BACKEND_IMAGE_ARG="--image"` 通过 CLI 参数传递图像文件路径,而不是通过提示注入。
|
||||
- `OPENCLAW_LIVE_CLI_BACKEND_IMAGE_MODE="repeat"`(或 `"list"`)用于控制在设置 `IMAGE_ARG` 时如何传递图像参数。
|
||||
- `OPENCLAW_LIVE_CLI_BACKEND_RESUME_PROBE=1` 发送第二轮消息并验证恢复流程。
|
||||
- `OPENCLAW_LIVE_CLI_BACKEND_MODEL_SWITCH_PROBE=1` 在所选模型支持切换目标时,启用 Claude Sonnet -> Opus 同一会话连续性探测。为保证整体稳定性,Docker 配方默认关闭此项。
|
||||
- `OPENCLAW_LIVE_CLI_BACKEND_MCP_PROBE=1` 启用 MCP/工具 local loopback 探测。Docker 配方默认关闭此项,除非明确请求。
|
||||
- `OPENCLAW_LIVE_CLI_BACKEND_MODEL_SWITCH_PROBE=1` 在所选模型支持切换目标时,启用 Claude Sonnet -> Opus 同会话连续性探针。为了整体稳定性,Docker 配方默认关闭此项。
|
||||
- `OPENCLAW_LIVE_CLI_BACKEND_MCP_PROBE=1` 启用 MCP/工具 local loopback 探针。除非明确请求,否则 Docker 配方默认关闭此项。
|
||||
|
||||
示例:
|
||||
|
||||
@ -160,11 +189,11 @@ pnpm test:docker:live-cli-backend:gemini
|
||||
说明:
|
||||
|
||||
- Docker 运行器位于 `scripts/test-live-cli-backend-docker.sh`。
|
||||
- 它会在仓库 Docker 镜像内以非 root 的 `node` 用户身份运行实时 CLI 后端冒烟测试。
|
||||
- 它会从所属扩展解析 CLI 冒烟测试元数据,然后将对应的 Linux CLI 包(`@anthropic-ai/claude-code`、`@openai/codex` 或 `@google/gemini-cli`)安装到可缓存、可写的前缀目录 `OPENCLAW_DOCKER_CLI_TOOLS_DIR`(默认:`~/.cache/openclaw/docker-cli-tools`)。
|
||||
- `pnpm test:docker:live-cli-backend:claude-subscription` 要求使用可移植的 Claude Code 订阅 OAuth,可通过 `~/.claude/.credentials.json` 中的 `claudeAiOauth.subscriptionType`,或来自 `claude setup-token` 的 `CLAUDE_CODE_OAUTH_TOKEN` 提供。它会先在 Docker 中验证直接 `claude -p`,然后在不保留 Anthropic API 键环境变量的情况下运行两轮 Gateway 网关 CLI 后端交互。此订阅测试默认禁用 Claude MCP/工具和图像探测,因为 Claude 当前会将第三方应用用量计入额外用量计费,而不是普通订阅计划限额。
|
||||
- 实时 CLI 后端冒烟测试现在对 Claude、Codex 和 Gemini 执行相同的端到端流程:文本轮次、图像分类轮次,然后通过 Gateway 网关 CLI 验证 MCP `cron` 工具调用。
|
||||
- Claude 的默认冒烟测试还会将会话从 Sonnet 修补为 Opus,并验证恢复后的会话仍记得先前的一条备注。
|
||||
- 它在仓库 Docker 镜像内以非 root 的 `node` 用户身份运行实时 CLI 后端冒烟测试。
|
||||
- 它会从所属扩展解析 CLI 冒烟元数据,然后将匹配的 Linux CLI 软件包(`@anthropic-ai/claude-code`、`@openai/codex` 或 `@google/gemini-cli`)安装到 `OPENCLAW_DOCKER_CLI_TOOLS_DIR` 指向的可写缓存前缀中(默认:`~/.cache/openclaw/docker-cli-tools`)。
|
||||
- `pnpm test:docker:live-cli-backend:claude-subscription` 需要可移植的 Claude Code 订阅 OAuth,可通过以下任一方式提供:`~/.claude/.credentials.json` 中带有 `claudeAiOauth.subscriptionType`,或来自 `claude setup-token` 的 `CLAUDE_CODE_OAUTH_TOKEN`。它会先在 Docker 中验证直接 `claude -p` 可用,然后在不保留 Anthropic API 密钥环境变量的情况下运行两轮 Gateway 网关 CLI 后端测试。该订阅通道默认禁用 Claude MCP/工具和图像探针,因为 Claude 当前会通过额外使用计费来处理第三方应用使用,而不是采用普通订阅计划限制。
|
||||
- 实时 CLI 后端冒烟测试现在会对 Claude、Codex 和 Gemini 执行相同的端到端流程:文本轮次、图像分类轮次,然后是通过 Gateway 网关 CLI 验证的 MCP `cron` 工具调用。
|
||||
- Claude 的默认冒烟测试还会将会话从 Sonnet 修补为 Opus,并验证恢复后的会话仍记得之前的备注。
|
||||
|
||||
## 实时:ACP 绑定冒烟测试(`/acp spawn ... --bind here`)
|
||||
|
||||
@ -172,15 +201,15 @@ pnpm test:docker:live-cli-backend:gemini
|
||||
- 目标:使用实时 ACP 智能体验证真实 ACP 会话绑定流程:
|
||||
- 发送 `/acp spawn <agent> --bind here`
|
||||
- 原地绑定一个合成的消息渠道会话
|
||||
- 在同一个会话上发送正常的后续消息
|
||||
- 验证后续消息落入已绑定的 ACP 会话记录中
|
||||
- 在同一会话上发送一条普通后续消息
|
||||
- 验证该后续消息落入已绑定 ACP 会话的转录中
|
||||
- 启用:
|
||||
- `pnpm test:live src/gateway/gateway-acp-bind.live.test.ts`
|
||||
- `OPENCLAW_LIVE_ACP_BIND=1`
|
||||
- 默认值:
|
||||
- Docker 中的 ACP 智能体:`claude,codex,gemini`
|
||||
- 直接 `pnpm test:live ...` 使用的 ACP 智能体:`claude`
|
||||
- 合成渠道:类似 Slack 私信 的会话上下文
|
||||
- 合成渠道:Slack 私信风格的会话上下文
|
||||
- ACP 后端:`acpx`
|
||||
- 覆盖项:
|
||||
- `OPENCLAW_LIVE_ACP_BIND_AGENT=claude`
|
||||
@ -191,8 +220,8 @@ pnpm test:docker:live-cli-backend:gemini
|
||||
- `OPENCLAW_LIVE_ACP_BIND_CODEX_MODEL=gpt-5.2`
|
||||
- `OPENCLAW_LIVE_ACP_BIND_PARENT_MODEL=openai/gpt-5.2`
|
||||
- 说明:
|
||||
- 此测试通道使用 Gateway 网关 `chat.send` 接口,并带有仅管理员可用的合成来源路由字段,以便测试能够附加消息渠道上下文,而无需假装进行外部投递。
|
||||
- 当未设置 `OPENCLAW_LIVE_ACP_BIND_AGENT_COMMAND` 时,测试会使用嵌入式 `acpx` 插件内建的智能体注册表来获取所选 ACP harness 智能体。
|
||||
- 此通道使用 Gateway 网关 `chat.send` 接口,并带有仅管理员可用的合成来源路由字段,因此测试可以附加消息渠道上下文,而无需假装进行外部投递。
|
||||
- 当 `OPENCLAW_LIVE_ACP_BIND_AGENT_COMMAND` 未设置时,测试会对所选 ACP harness 智能体使用内嵌 `acpx` 插件的内置智能体注册表。
|
||||
|
||||
示例:
|
||||
|
||||
@ -219,34 +248,35 @@ pnpm test:docker:live-acp-bind:gemini
|
||||
Docker 说明:
|
||||
|
||||
- Docker 运行器位于 `scripts/test-live-acp-bind-docker.sh`。
|
||||
- 默认情况下,它会按顺序对所有受支持的实时 CLI 智能体运行 ACP 绑定冒烟测试:`claude`、`codex`,然后是 `gemini`。
|
||||
- 默认情况下,它会依次对所有受支持的实时 CLI 智能体运行 ACP 绑定冒烟测试:`claude`、`codex`,然后是 `gemini`。
|
||||
- 使用 `OPENCLAW_LIVE_ACP_BIND_AGENTS=claude`、`OPENCLAW_LIVE_ACP_BIND_AGENTS=codex` 或 `OPENCLAW_LIVE_ACP_BIND_AGENTS=gemini` 可缩小矩阵范围。
|
||||
- 它会加载 `~/.profile`,将匹配的 CLI 认证材料暂存到容器中,把 `acpx` 安装到可写的 npm 前缀中,然后在缺失时安装所请求的实时 CLI(`@anthropic-ai/claude-code`、`@openai/codex` 或 `@google/gemini-cli`)。
|
||||
- 在 Docker 内部,运行器会设置 `OPENCLAW_LIVE_ACP_BIND_ACPX_COMMAND=$HOME/.npm-global/bin/acpx`,以便 acpx 让来自已加载 profile 的提供商环境变量可用于其子 harness CLI。
|
||||
- 它会加载 `~/.profile`,将匹配的 CLI 认证材料暂存到容器中,在可写的 npm 前缀中安装 `acpx`,然后在缺失时安装所请求的实时 CLI(`@anthropic-ai/claude-code`、`@openai/codex` 或 `@google/gemini-cli`)。
|
||||
- 在 Docker 内,运行器会设置 `OPENCLAW_LIVE_ACP_BIND_ACPX_COMMAND=$HOME/.npm-global/bin/acpx`,这样 acpx 就能让从已加载配置文件中获得的提供商环境变量继续对其子 harness CLI 可用。
|
||||
|
||||
## 实时:Codex app-server harness 冒烟测试
|
||||
|
||||
- 目标:通过常规 Gateway 网关
|
||||
`agent` 方法验证由插件拥有的 Codex harness:
|
||||
`agent` 方法验证插件拥有的 Codex harness:
|
||||
- 加载内置的 `codex` 插件
|
||||
- 选择 `OPENCLAW_AGENT_RUNTIME=codex`
|
||||
- 在强制使用 Codex harness 的情况下,向 `openai/gpt-5.2` 发送第一轮 Gateway 网关智能体消息
|
||||
- 向 `openai/gpt-5.2` 发送第一轮 Gateway 网关智能体消息,并强制使用 Codex harness
|
||||
- 向同一个 OpenClaw 会话发送第二轮消息,并验证 app-server
|
||||
线程能够恢复
|
||||
- 通过相同的 Gateway 网关命令
|
||||
线程可以恢复
|
||||
- 通过同一个 Gateway 网关命令
|
||||
路径运行 `/codex status` 和 `/codex models`
|
||||
- 可选运行两个经 Guardian 审核的提权 shell 探测:一个应被批准的无害
|
||||
命令,以及一个应被拒绝的伪造密钥上传操作,以便智能体回问
|
||||
- 可选地运行两个经过 Guardian 审核的提权 shell 探针:一个应被批准的无害
|
||||
命令,以及一个应被拒绝的伪造秘密上传操作,
|
||||
以便智能体回头询问
|
||||
- 测试:`src/gateway/gateway-codex-harness.live.test.ts`
|
||||
- 启用:`OPENCLAW_LIVE_CODEX_HARNESS=1`
|
||||
- 默认模型:`openai/gpt-5.2`
|
||||
- 可选图像探测:`OPENCLAW_LIVE_CODEX_HARNESS_IMAGE_PROBE=1`
|
||||
- 可选 MCP/工具探测:`OPENCLAW_LIVE_CODEX_HARNESS_MCP_PROBE=1`
|
||||
- 可选 Guardian 探测:`OPENCLAW_LIVE_CODEX_HARNESS_GUARDIAN_PROBE=1`
|
||||
- 该冒烟测试设置 `OPENCLAW_AGENT_HARNESS_FALLBACK=none`,因此损坏的 Codex
|
||||
harness 不能通过静默回退到 Pi 而蒙混过关。
|
||||
- 可选图像探针:`OPENCLAW_LIVE_CODEX_HARNESS_IMAGE_PROBE=1`
|
||||
- 可选 MCP/工具探针:`OPENCLAW_LIVE_CODEX_HARNESS_MCP_PROBE=1`
|
||||
- 可选 Guardian 探针:`OPENCLAW_LIVE_CODEX_HARNESS_GUARDIAN_PROBE=1`
|
||||
- 该冒烟测试会设置 `OPENCLAW_AGENT_HARNESS_FALLBACK=none`,这样损坏的 Codex
|
||||
harness 就不能通过悄悄回退到 PI 来蒙混过关。
|
||||
- 认证:Codex app-server 认证来自本地 Codex 订阅登录。Docker
|
||||
冒烟测试在适用时也可提供 `OPENAI_API_KEY` 用于非 Codex 探测,
|
||||
冒烟测试在适用时也可以提供 `OPENAI_API_KEY` 用于非 Codex 探针,
|
||||
另外还可选复制 `~/.codex/auth.json` 和 `~/.codex/config.toml`。
|
||||
|
||||
本地配方:
|
||||
@ -273,19 +303,18 @@ Docker 说明:
|
||||
- Docker 运行器位于 `scripts/test-live-codex-harness-docker.sh`。
|
||||
- 它会加载挂载的 `~/.profile`,传递 `OPENAI_API_KEY`,在存在时复制 Codex CLI
|
||||
认证文件,将 `@openai/codex` 安装到可写的挂载 npm
|
||||
前缀中,暂存源代码树,然后只运行 Codex harness 实时测试。
|
||||
- Docker 默认启用图像、MCP/工具和 Guardian 探测。设置
|
||||
`OPENCLAW_LIVE_CODEX_HARNESS_IMAGE_PROBE=0` 或
|
||||
前缀中,暂存源码树,然后仅运行 Codex-harness 实时测试。
|
||||
- Docker 默认启用图像、MCP/工具和 Guardian 探针。需要更窄范围的调试
|
||||
运行时,可设置 `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_GUARDIAN_PROBE=0`。
|
||||
- Docker 还会导出 `OPENCLAW_AGENT_HARNESS_FALLBACK=none`,与实时
|
||||
测试配置保持一致,这样旧别名或回退到 Pi 都无法掩盖 Codex harness
|
||||
测试配置保持一致,因此旧别名或 PI 回退都无法掩盖 Codex harness
|
||||
回归问题。
|
||||
|
||||
### 推荐的实时测试配方
|
||||
### 推荐的实时配方
|
||||
|
||||
范围窄、显式的允许列表速度最快,且最不容易出现不稳定:
|
||||
范围窄、显式的允许列表最快,也最不容易波动:
|
||||
|
||||
- 单模型,直接测试(无 Gateway 网关):
|
||||
- `OPENCLAW_LIVE_MODELS="openai/gpt-5.2" pnpm test:live src/agents/models.profiles.live.test.ts`
|
||||
@ -293,34 +322,34 @@ Docker 说明:
|
||||
- 单模型,Gateway 网关冒烟测试:
|
||||
- `OPENCLAW_LIVE_GATEWAY_MODELS="openai/gpt-5.2" pnpm test:live src/gateway/gateway-models.profiles.live.test.ts`
|
||||
|
||||
- 跨多个提供商的工具调用:
|
||||
- 多个提供商的工具调用:
|
||||
- `OPENCLAW_LIVE_GATEWAY_MODELS="openai/gpt-5.2,openai-codex/gpt-5.2,anthropic/claude-opus-4-6,google/gemini-3-flash-preview,deepseek/deepseek-v4-flash,zai/glm-4.7,minimax/MiniMax-M2.7" pnpm test:live src/gateway/gateway-models.profiles.live.test.ts`
|
||||
|
||||
- 聚焦 Google(Gemini API 键 + Antigravity):
|
||||
- Gemini(API 键):`OPENCLAW_LIVE_GATEWAY_MODELS="google/gemini-3-flash-preview" pnpm test:live src/gateway/gateway-models.profiles.live.test.ts`
|
||||
- 聚焦 Google(Gemini API 密钥 + Antigravity):
|
||||
- Gemini(API 密钥):`OPENCLAW_LIVE_GATEWAY_MODELS="google/gemini-3-flash-preview" pnpm test:live src/gateway/gateway-models.profiles.live.test.ts`
|
||||
- Antigravity(OAuth):`OPENCLAW_LIVE_GATEWAY_MODELS="google-antigravity/claude-opus-4-6-thinking,google-antigravity/gemini-3-pro-high" pnpm test:live src/gateway/gateway-models.profiles.live.test.ts`
|
||||
|
||||
- Google 自适应思考冒烟测试:
|
||||
- 如果本地键位于 shell profile 中:`source ~/.profile`
|
||||
- 如果本地密钥存放在 shell 配置文件中:`source ~/.profile`
|
||||
- Gemini 3 动态默认值:`pnpm openclaw qa manual --provider-mode live-frontier --model google/gemini-3.1-pro-preview --alt-model google/gemini-3.1-pro-preview --message '/think adaptive Reply exactly: GEMINI_ADAPTIVE_OK' --timeout-ms 180000`
|
||||
- Gemini 2.5 动态预算:`pnpm openclaw qa manual --provider-mode live-frontier --model google/gemini-2.5-flash --alt-model google/gemini-2.5-flash --message '/think adaptive Reply exactly: GEMINI25_ADAPTIVE_OK' --timeout-ms 180000`
|
||||
|
||||
说明:
|
||||
|
||||
- `google/...` 使用 Gemini API(API 键)。
|
||||
- `google-antigravity/...` 使用 Antigravity OAuth 桥接(类似 Cloud Code Assist 的智能体端点)。
|
||||
- `google-gemini-cli/...` 使用你机器上的本地 Gemini CLI(单独的认证 + 工具行为差异)。
|
||||
- `google/...` 使用 Gemini API(API 密钥)。
|
||||
- `google-antigravity/...` 使用 Antigravity OAuth 桥接(Cloud Code Assist 风格的智能体端点)。
|
||||
- `google-gemini-cli/...` 使用你机器上的本地 Gemini CLI(单独的认证 + 工具链差异)。
|
||||
- Gemini API 与 Gemini CLI:
|
||||
- API:OpenClaw 通过 HTTP 调用 Google 托管的 Gemini API(API 键 / 配置档认证);这通常是大多数用户所说的 “Gemini”。
|
||||
- CLI:OpenClaw 会调用本地 `gemini` 二进制;它有自己的认证方式,并且行为可能不同(流式传输/工具支持/版本偏差)。
|
||||
- API:OpenClaw 通过 HTTP 调用 Google 托管的 Gemini API(API 密钥 / 配置文件认证);这也是大多数用户提到 “Gemini” 时的含义。
|
||||
- CLI:OpenClaw 调用本地 `gemini` 二进制;它有自己的认证方式,而且行为可能不同(流式传输/工具支持/版本偏差)。
|
||||
|
||||
## 实时:模型矩阵(我们的覆盖范围)
|
||||
|
||||
没有固定的“CI 模型列表”(实时测试为可选启用),但以下是建议你在具备键的开发机器上定期覆盖的**推荐**模型。
|
||||
没有固定的“CI 模型列表”(实时测试是可选启用的),但这些是**推荐**你在具备密钥的开发机器上定期覆盖的模型。
|
||||
|
||||
### 现代冒烟测试集(工具调用 + 图像)
|
||||
### 现代冒烟测试集合(工具调用 + 图像)
|
||||
|
||||
这是我们期望持续保持可用的“常见模型”运行集合:
|
||||
这是我们期望持续可用的“常用模型”运行集合:
|
||||
|
||||
- OpenAI(非 Codex):`openai/gpt-5.2`
|
||||
- OpenAI Codex OAuth:`openai-codex/gpt-5.2`
|
||||
@ -336,7 +365,7 @@ Docker 说明:
|
||||
|
||||
### 基线:工具调用(Read + 可选 Exec)
|
||||
|
||||
每个提供商家族至少选择一个:
|
||||
每个提供商家族至少选一个:
|
||||
|
||||
- OpenAI:`openai/gpt-5.2`
|
||||
- Anthropic:`anthropic/claude-opus-4-6`(或 `anthropic/claude-sonnet-4-6`)
|
||||
@ -345,51 +374,51 @@ Docker 说明:
|
||||
- Z.AI(GLM):`zai/glm-4.7`
|
||||
- MiniMax:`minimax/MiniMax-M2.7`
|
||||
|
||||
可选的额外覆盖(有更好):
|
||||
可选的额外覆盖(有则更好):
|
||||
|
||||
- xAI:`xai/grok-4`(或最新可用版本)
|
||||
- Mistral:`mistral/`…(选择一个你已启用、支持 “tools” 的模型)
|
||||
- xAI:`xai/grok-4`(或当前最新可用版本)
|
||||
- Mistral:`mistral/`…(任选一个你已启用、支持 “tools” 的模型)
|
||||
- Cerebras:`cerebras/`…(如果你有访问权限)
|
||||
- LM Studio:`lmstudio/`…(本地;工具调用取决于 API 模式)
|
||||
|
||||
### Vision:图像发送(附件 → 多模态消息)
|
||||
### 视觉:发送图像(附件 → 多模态消息)
|
||||
|
||||
至少在 `OPENCLAW_LIVE_GATEWAY_MODELS` 中包含一个支持图像的模型(Claude/Gemini/OpenAI 支持视觉的变体等),以触发图像探测。
|
||||
在 `OPENCLAW_LIVE_GATEWAY_MODELS` 中至少包含一个支持图像的模型(Claude/Gemini/OpenAI 支持视觉的变体等),以便执行图像探针。
|
||||
|
||||
### 聚合器 / 替代 Gateway 网关
|
||||
|
||||
如果你已启用相应键,我们也支持通过以下方式进行测试:
|
||||
如果你已启用相应密钥,我们也支持通过以下方式测试:
|
||||
|
||||
- OpenRouter:`openrouter/...`(数百个模型;使用 `openclaw models scan` 查找支持工具 + 图像的候选模型)
|
||||
- OpenCode:Zen 使用 `opencode/...`,Go 使用 `opencode-go/...`(通过 `OPENCODE_API_KEY` / `OPENCODE_ZEN_API_KEY` 认证)
|
||||
- OpenRouter:`openrouter/...`(数百种模型;使用 `openclaw models scan` 查找支持工具 + 图像的候选项)
|
||||
- OpenCode:`opencode/...` 用于 Zen,`opencode-go/...` 用于 Go(通过 `OPENCODE_API_KEY` / `OPENCODE_ZEN_API_KEY` 认证)
|
||||
|
||||
你还可以将更多提供商纳入实时矩阵(如果你有凭证/配置):
|
||||
你还可以纳入实时矩阵的更多提供商(如果你具备相应凭证/配置):
|
||||
|
||||
- 内置:`openai`、`openai-codex`、`anthropic`、`google`、`google-vertex`、`google-antigravity`、`google-gemini-cli`、`zai`、`openrouter`、`opencode`、`opencode-go`、`xai`、`groq`、`cerebras`、`mistral`、`github-copilot`
|
||||
- 通过 `models.providers`(自定义端点):`minimax`(云/API),以及任何兼容 OpenAI/Anthropic 的代理(LM Studio、vLLM、LiteLLM 等)
|
||||
|
||||
提示:不要试图在文档中硬编码“所有模型”。权威列表应以你机器上 `discoverModels(...)` 的返回结果 + 可用键为准。
|
||||
提示:不要试图在文档中硬编码“所有模型”。权威列表是你机器上 `discoverModels(...)` 返回的内容 + 当前可用的密钥。
|
||||
|
||||
## 凭证(绝不要提交)
|
||||
## 凭证(切勿提交)
|
||||
|
||||
实时测试发现凭证的方式与 CLI 相同。实际含义如下:
|
||||
|
||||
- 如果 CLI 能工作,实时测试应该也能找到同样的键。
|
||||
- 如果实时测试提示 “no creds”,请按你调试 `openclaw models list` / 模型选择时的相同方式来调试。
|
||||
- 如果 CLI 可用,实时测试应该能找到相同的密钥。
|
||||
- 如果实时测试提示 “no creds”,请像调试 `openclaw models list` / 模型选择那样调试。
|
||||
|
||||
- 每个智能体的认证配置档:`~/.openclaw/agents/<agentId>/agent/auth-profiles.json`(这就是实时测试中 “profile keys” 的含义)
|
||||
- 每个智能体的认证配置文件:`~/.openclaw/agents/<agentId>/agent/auth-profiles.json`(这就是实时测试中 “profile keys” 的含义)
|
||||
- 配置:`~/.openclaw/openclaw.json`(或 `OPENCLAW_CONFIG_PATH`)
|
||||
- 旧版状态目录:`~/.openclaw/credentials/`(存在时会复制到暂存的实时测试 home 中,但它不是主配置档键存储)
|
||||
- 默认情况下,本地实时运行会将当前活动配置、每个智能体的 `auth-profiles.json` 文件、旧版 `credentials/` 以及受支持的外部 CLI 认证目录复制到临时测试 home 中;暂存的实时 home 会跳过 `workspace/` 和 `sandboxes/`,并移除 `agents.*.workspace` / `agentDir` 路径覆盖,以确保探测不会落到你真实主机的工作区上。
|
||||
- 旧版状态目录:`~/.openclaw/credentials/`(存在时会复制到暂存的实时 home 中,但它不是主配置文件密钥存储)
|
||||
- 默认情况下,本地实时运行会把当前活动配置、每个智能体的 `auth-profiles.json` 文件、旧版 `credentials/` 以及受支持的外部 CLI 认证目录复制到临时测试 home 中;暂存的实时 home 会跳过 `workspace/` 和 `sandboxes/`,并且会去除 `agents.*.workspace` / `agentDir` 路径覆盖,这样探针就不会落到你真实主机的工作区上。
|
||||
|
||||
如果你想依赖环境变量键(例如从你的 `~/.profile` 导出),请在执行本地测试前运行 `source ~/.profile`,或使用下面的 Docker 运行器(它们可以将 `~/.profile` 挂载到容器中)。
|
||||
如果你想依赖环境变量密钥(例如在 `~/.profile` 中导出的密钥),请在本地测试前运行 `source ~/.profile`,或者使用下面的 Docker 运行器(它们可以将 `~/.profile` 挂载到容器中)。
|
||||
|
||||
## Deepgram 实时测试(音频转写)
|
||||
|
||||
- 测试:`extensions/deepgram/audio.live.test.ts`
|
||||
- 启用:`DEEPGRAM_API_KEY=... DEEPGRAM_LIVE_TEST=1 pnpm test:live extensions/deepgram/audio.live.test.ts`
|
||||
|
||||
## BytePlus(国际版)编码计划实时测试
|
||||
## BytePlus 编码计划实时测试
|
||||
|
||||
- 测试:`extensions/byteplus/live.test.ts`
|
||||
- 启用:`BYTEPLUS_API_KEY=... BYTEPLUS_LIVE_TEST=1 pnpm test:live extensions/byteplus/live.test.ts`
|
||||
@ -400,9 +429,9 @@ Docker 说明:
|
||||
- 测试:`extensions/comfy/comfy.live.test.ts`
|
||||
- 启用:`OPENCLAW_LIVE_TEST=1 COMFY_LIVE_TEST=1 pnpm test:live -- extensions/comfy/comfy.live.test.ts`
|
||||
- 范围:
|
||||
- 覆盖内置 comfy 图像、视频和 `music_generate` 路径
|
||||
- 除非已配置 `plugins.entries.comfy.config.<capability>`,否则会跳过各项能力
|
||||
- 在更改 comfy 工作流提交、轮询、下载或插件注册后很有帮助
|
||||
- 覆盖内置的 comfy 图像、视频和 `music_generate` 路径
|
||||
- 除非配置了 `plugins.entries.comfy.config.<capability>`,否则会跳过各项能力
|
||||
- 在修改 comfy 工作流提交、轮询、下载或插件注册后很有用
|
||||
|
||||
## 实时:图像生成
|
||||
|
||||
@ -410,14 +439,14 @@ Docker 说明:
|
||||
- 命令:`pnpm test:live test/image-generation.runtime.live.test.ts`
|
||||
- Harness:`pnpm test:live:media image`
|
||||
- 范围:
|
||||
- 枚举每个已注册的图像生成提供商插件
|
||||
- 在探测前,从你的登录 shell(`~/.profile`)加载缺失的提供商环境变量
|
||||
- 默认优先使用实时/环境变量 API 键,而不是已存储的认证配置档,因此 `auth-profiles.json` 中过期的测试键不会掩盖真实的 shell 凭证
|
||||
- 跳过没有可用认证/配置档/模型的提供商
|
||||
- 枚举每一个已注册的图像生成提供商插件
|
||||
- 在探测前先从你的登录 shell(`~/.profile`)加载缺失的提供商环境变量
|
||||
- 默认优先使用实时/环境变量 API 密钥,而不是已存储的认证配置文件,因此 `auth-profiles.json` 中过期的测试密钥不会掩盖真实的 shell 凭证
|
||||
- 跳过没有可用认证/配置文件/模型的提供商
|
||||
- 通过共享图像生成运行时运行每个已配置的提供商:
|
||||
- `<provider>:generate`
|
||||
- 当提供商声明支持编辑时运行 `<provider>:edit`
|
||||
- 当前覆盖的内置提供商:
|
||||
- 当提供商声明支持编辑时,运行 `<provider>:edit`
|
||||
- 当前已覆盖的内置提供商:
|
||||
- `fal`
|
||||
- `google`
|
||||
- `minimax`
|
||||
@ -430,10 +459,10 @@ Docker 说明:
|
||||
- `OPENCLAW_LIVE_IMAGE_GENERATION_MODELS="openai/gpt-image-2,google/gemini-3.1-flash-image-preview,openrouter/google/gemini-3.1-flash-image-preview,xai/grok-imagine-image"`
|
||||
- `OPENCLAW_LIVE_IMAGE_GENERATION_CASES="google:flash-generate,google:pro-edit,openrouter:generate,xai:default-generate,xai:default-edit"`
|
||||
- 可选认证行为:
|
||||
- `OPENCLAW_LIVE_REQUIRE_PROFILE_KEYS=1` 强制使用配置档存储认证,并忽略仅环境变量的覆盖
|
||||
- `OPENCLAW_LIVE_REQUIRE_PROFILE_KEYS=1` 可强制使用配置文件存储认证,并忽略仅环境变量的覆盖
|
||||
|
||||
对于已发布的 CLI 路径,在提供商/运行时实时
|
||||
测试通过后,添加一个 `infer` 冒烟测试:
|
||||
测试通过后,再添加一个 `infer` 冒烟测试:
|
||||
|
||||
```bash
|
||||
OPENCLAW_LIVE_TEST=1 OPENCLAW_LIVE_INFER_CLI_TEST=1 pnpm test:live -- test/image-generation.infer-cli.live.test.ts
|
||||
@ -445,11 +474,11 @@ openclaw infer image generate \
|
||||
--json
|
||||
```
|
||||
|
||||
这覆盖了 CLI 参数解析、配置/默认智能体解析、内置
|
||||
插件激活、按需内置运行时依赖修复、共享
|
||||
这涵盖了 CLI 参数解析、配置/默认智能体解析、内置
|
||||
插件激活、按需修复内置运行时依赖、共享
|
||||
图像生成运行时,以及实时提供商请求。
|
||||
|
||||
## 实时:音乐生成
|
||||
## 音乐生成实时测试
|
||||
|
||||
- 测试:`extensions/music-generation-providers.live.test.ts`
|
||||
- 启用:`OPENCLAW_LIVE_TEST=1 pnpm test:live -- extensions/music-generation-providers.live.test.ts`
|
||||
@ -457,64 +486,64 @@ openclaw infer image generate \
|
||||
- 范围:
|
||||
- 覆盖共享内置音乐生成提供商路径
|
||||
- 当前覆盖 Google 和 MiniMax
|
||||
- 在探测前,从你的登录 shell(`~/.profile`)加载提供商环境变量
|
||||
- 默认优先使用实时/环境变量 API 键,而不是已存储的认证配置档,因此 `auth-profiles.json` 中过期的测试键不会掩盖真实的 shell 凭证
|
||||
- 跳过没有可用认证/配置档/模型的提供商
|
||||
- 在探测前先从你的登录 shell(`~/.profile`)加载提供商环境变量
|
||||
- 默认优先使用实时/环境变量 API 密钥,而不是已存储的认证配置文件,因此 `auth-profiles.json` 中过期的测试密钥不会掩盖真实的 shell 凭证
|
||||
- 跳过没有可用认证/配置文件/模型的提供商
|
||||
- 在可用时运行两种已声明的运行时模式:
|
||||
- 使用仅提示词输入的 `generate`
|
||||
- 当提供商声明 `capabilities.edit.enabled` 时运行 `edit`
|
||||
- 当前共享通道覆盖:
|
||||
- `google`:`generate`、`edit`
|
||||
- `minimax`:`generate`
|
||||
- `comfy`:单独的 Comfy 实时文件,不在此共享全面检查中
|
||||
- `comfy`:单独的 Comfy 实时文件,不属于此共享全面检查
|
||||
- 可选缩小范围:
|
||||
- `OPENCLAW_LIVE_MUSIC_GENERATION_PROVIDERS="google,minimax"`
|
||||
- `OPENCLAW_LIVE_MUSIC_GENERATION_MODELS="google/lyria-3-clip-preview,minimax/music-2.5+"`
|
||||
- 可选认证行为:
|
||||
- `OPENCLAW_LIVE_REQUIRE_PROFILE_KEYS=1` 强制使用配置档存储认证,并忽略仅环境变量的覆盖
|
||||
- `OPENCLAW_LIVE_REQUIRE_PROFILE_KEYS=1` 可强制使用配置文件存储认证,并忽略仅环境变量的覆盖
|
||||
|
||||
## 实时:视频生成
|
||||
## 视频生成实时测试
|
||||
|
||||
- 测试:`extensions/video-generation-providers.live.test.ts`
|
||||
- 启用:`OPENCLAW_LIVE_TEST=1 pnpm test:live -- extensions/video-generation-providers.live.test.ts`
|
||||
- Harness:`pnpm test:live:media video`
|
||||
- 范围:
|
||||
- 覆盖共享内置视频生成提供商路径
|
||||
- 默认使用发布安全的冒烟测试路径:非 FAL 提供商、每个提供商一次文生视频请求、1 秒龙虾提示词,以及来自 `OPENCLAW_LIVE_VIDEO_GENERATION_TIMEOUT_MS` 的每提供商操作上限(默认 `180000`)
|
||||
- 默认使用对发布安全的冒烟路径:非 FAL 提供商、每个提供商一个文生视频请求、一秒龙虾提示词,以及来自 `OPENCLAW_LIVE_VIDEO_GENERATION_TIMEOUT_MS` 的每提供商操作上限(默认 `180000`)
|
||||
- 默认跳过 FAL,因为提供商侧队列延迟可能主导发布时间;传入 `--video-providers fal` 或 `OPENCLAW_LIVE_VIDEO_GENERATION_PROVIDERS="fal"` 可显式运行它
|
||||
- 在探测前,从你的登录 shell(`~/.profile`)加载提供商环境变量
|
||||
- 默认优先使用实时/环境变量 API 键,而不是已存储的认证配置档,因此 `auth-profiles.json` 中过期的测试键不会掩盖真实的 shell 凭证
|
||||
- 跳过没有可用认证/配置档/模型的提供商
|
||||
- 在探测前先从你的登录 shell(`~/.profile`)加载提供商环境变量
|
||||
- 默认优先使用实时/环境变量 API 密钥,而不是已存储的认证配置文件,因此 `auth-profiles.json` 中过期的测试密钥不会掩盖真实的 shell 凭证
|
||||
- 跳过没有可用认证/配置文件/模型的提供商
|
||||
- 默认仅运行 `generate`
|
||||
- 设置 `OPENCLAW_LIVE_VIDEO_GENERATION_FULL_MODES=1` 以在可用时也运行已声明的转换模式:
|
||||
- 当提供商声明 `capabilities.imageToVideo.enabled`,且所选提供商/模型在共享全面检查中接受基于缓冲区的本地图像输入时,运行 `imageToVideo`
|
||||
- 当提供商声明 `capabilities.videoToVideo.enabled`,且所选提供商/模型在共享全面检查中接受基于缓冲区的本地视频输入时,运行 `videoToVideo`
|
||||
- 当前在共享全面检查中已声明但被跳过的 `imageToVideo` 提供商:
|
||||
- 设置 `OPENCLAW_LIVE_VIDEO_GENERATION_FULL_MODES=1` 可在可用时也运行已声明的变换模式:
|
||||
- 当提供商声明 `capabilities.imageToVideo.enabled`,且所选提供商/模型在共享全面检查中接受基于 buffer 的本地图像输入时,运行 `imageToVideo`
|
||||
- 当提供商声明 `capabilities.videoToVideo.enabled`,且所选提供商/模型在共享全面检查中接受基于 buffer 的本地视频输入时,运行 `videoToVideo`
|
||||
- 当前在共享全面检查中已声明但跳过的 `imageToVideo` 提供商:
|
||||
- `vydra`,因为内置 `veo3` 仅支持文本,而内置 `kling` 需要远程图像 URL
|
||||
- Vydra 提供商专用覆盖:
|
||||
- 提供商专用的 Vydra 覆盖:
|
||||
- `OPENCLAW_LIVE_TEST=1 OPENCLAW_LIVE_VYDRA_VIDEO=1 pnpm test:live -- extensions/vydra/vydra.live.test.ts`
|
||||
- 该文件运行 `veo3` 文生视频,以及一个默认使用远程图像 URL 固定装置的 `kling` 通道
|
||||
- 该文件会运行 `veo3` 文生视频,以及默认使用远程图像 URL 固定装置的 `kling` 通道
|
||||
- 当前 `videoToVideo` 实时覆盖:
|
||||
- 仅 `runway`,且仅当所选模型为 `runway/gen4_aleph` 时
|
||||
- 当前在共享全面检查中已声明但被跳过的 `videoToVideo` 提供商:
|
||||
- 仅 `runway`,且仅当所选模型为 `runway/gen4_aleph`
|
||||
- 当前在共享全面检查中已声明但跳过的 `videoToVideo` 提供商:
|
||||
- `alibaba`、`qwen`、`xai`,因为这些路径当前需要远程 `http(s)` / MP4 参考 URL
|
||||
- `google`,因为当前共享 Gemini/Veo 通道使用基于本地缓冲区的输入,而该路径在共享全面检查中不被接受
|
||||
- `openai`,因为当前共享通道缺乏组织专用视频修补/混剪访问保障
|
||||
- `google`,因为当前共享 Gemini/Veo 通道使用的是基于本地 buffer 的输入,而该路径在共享全面检查中不被接受
|
||||
- `openai`,因为当前共享通道缺少特定组织的视频修补/重混访问保证
|
||||
- 可选缩小范围:
|
||||
- `OPENCLAW_LIVE_VIDEO_GENERATION_PROVIDERS="google,openai,runway"`
|
||||
- `OPENCLAW_LIVE_VIDEO_GENERATION_MODELS="google/veo-3.1-fast-generate-preview,openai/sora-2,runway/gen4_aleph"`
|
||||
- `OPENCLAW_LIVE_VIDEO_GENERATION_SKIP_PROVIDERS=""` 以在默认全面检查中包含所有提供商,包括 FAL
|
||||
- `OPENCLAW_LIVE_VIDEO_GENERATION_TIMEOUT_MS=60000` 以减少每个提供商的操作上限,用于激进的冒烟测试运行
|
||||
- `OPENCLAW_LIVE_VIDEO_GENERATION_SKIP_PROVIDERS=""` 以在默认全面检查中包含每个提供商,包括 FAL
|
||||
- `OPENCLAW_LIVE_VIDEO_GENERATION_TIMEOUT_MS=60000` 以降低每个提供商的操作上限,用于更激进的冒烟运行
|
||||
- 可选认证行为:
|
||||
- `OPENCLAW_LIVE_REQUIRE_PROFILE_KEYS=1` 强制使用配置档存储认证,并忽略仅环境变量的覆盖
|
||||
- `OPENCLAW_LIVE_REQUIRE_PROFILE_KEYS=1` 可强制使用配置文件存储认证,并忽略仅环境变量的覆盖
|
||||
|
||||
## 媒体实时测试 Harness
|
||||
## 媒体实时 harness
|
||||
|
||||
- 命令:`pnpm test:live:media`
|
||||
- 目的:
|
||||
- 通过一个仓库原生入口点运行共享的图像、音乐和视频实时测试套件
|
||||
- 通过一个仓库原生入口点运行共享的图像、音乐和视频实时套件
|
||||
- 自动从 `~/.profile` 加载缺失的提供商环境变量
|
||||
- 默认自动将每个测试套件缩小到当前具有可用认证的提供商
|
||||
- 默认自动将每个套件缩小到当前具有可用认证的提供商
|
||||
- 复用 `scripts/test-live.mjs`,因此心跳和静默模式行为保持一致
|
||||
- 示例:
|
||||
- `pnpm test:live:media`
|
||||
@ -524,4 +553,4 @@ openclaw infer image generate \
|
||||
|
||||
## 相关内容
|
||||
|
||||
- [测试](/zh-CN/help/testing) — 单元、集成、QA 和 Docker 测试套件
|
||||
- [测试](/zh-CN/help/testing) — 单元、集成、QA 和 Docker 套件
|
||||
|
||||
@ -1,28 +1,28 @@
|
||||
---
|
||||
read_when:
|
||||
- 你想从 OpenClaw 发起一个呼出语音通话
|
||||
- 你正在配置或开发 voice-call 插件
|
||||
summary: Voice Call 插件:通过 Twilio/Telnyx/Plivo 进行呼出 + 呼入通话(插件安装 + 配置 + CLI)
|
||||
title: Voice call 插件
|
||||
- 你正在配置或开发语音通话插件
|
||||
summary: 语音通话插件:通过 Twilio/Telnyx/Plivo 进行呼出 + 呼入通话(插件安装 + 配置 + CLI)
|
||||
title: 语音通话插件
|
||||
x-i18n:
|
||||
generated_at: "2026-04-25T04:09:44Z"
|
||||
generated_at: "2026-04-25T04:54:59Z"
|
||||
model: gpt-5.4
|
||||
provider: openai
|
||||
source_hash: d4615dd2c4e8431ebdff7d79a5323951fec7a9e14947260ef741adeef0907002
|
||||
source_hash: 54fff21558f5a8788f85a91ed84a60a3d74a4fa8da8edbe81a23adc9a9065e2f
|
||||
source_path: plugins/voice-call.md
|
||||
workflow: 15
|
||||
---
|
||||
|
||||
# Voice Call(插件)
|
||||
# 语音通话(插件)
|
||||
|
||||
通过插件为 OpenClaw 提供语音通话。支持呼出通知以及带有呼入策略的多轮对话。
|
||||
通过插件为 OpenClaw 提供语音通话。支持呼出通知,以及带有呼入策略的多轮对话。
|
||||
|
||||
当前提供商:
|
||||
|
||||
- `twilio`(Programmable Voice + Media Streams)
|
||||
- `telnyx`(Call Control v2)
|
||||
- `plivo`(Voice API + XML transfer + GetInput speech)
|
||||
- `mock`(开发 / 无网络)
|
||||
- `mock`(开发环境 / 无网络)
|
||||
|
||||
快速理解模型:
|
||||
|
||||
@ -33,9 +33,9 @@ x-i18n:
|
||||
|
||||
## 运行位置(本地 vs 远程)
|
||||
|
||||
Voice Call 插件**运行在 Gateway 网关进程内部**。
|
||||
语音通话插件运行在 **Gateway 网关进程内部**。
|
||||
|
||||
如果你使用远程 Gateway 网关,请在**运行 Gateway 网关的机器**上安装 / 配置该插件,然后重启 Gateway 网关以加载它。
|
||||
如果你使用远程 Gateway 网关,请在 **运行 Gateway 网关的机器** 上安装 / 配置该插件,然后重启 Gateway 网关以加载它。
|
||||
|
||||
## 安装
|
||||
|
||||
@ -47,7 +47,7 @@ openclaw plugins install @openclaw/voice-call
|
||||
|
||||
之后重启 Gateway 网关。
|
||||
|
||||
### 选项 B:从本地文件夹安装(开发,无需复制)
|
||||
### 选项 B:从本地文件夹安装(开发环境,不复制文件)
|
||||
|
||||
```bash
|
||||
PLUGIN_SRC=./path/to/local/voice-call-plugin
|
||||
@ -68,8 +68,8 @@ cd "$PLUGIN_SRC" && pnpm install
|
||||
"voice-call": {
|
||||
enabled: true,
|
||||
config: {
|
||||
provider: "twilio", // 或 "telnyx" | "plivo" | "mock"
|
||||
fromNumber: "+15550001234", // 或者 Twilio 使用 TWILIO_FROM_NUMBER
|
||||
provider: "twilio", // or "telnyx" | "plivo" | "mock"
|
||||
fromNumber: "+15550001234", // or TWILIO_FROM_NUMBER for Twilio
|
||||
toNumber: "+15550005678",
|
||||
|
||||
twilio: {
|
||||
@ -80,8 +80,8 @@ cd "$PLUGIN_SRC" && pnpm install
|
||||
telnyx: {
|
||||
apiKey: "...",
|
||||
connectionId: "...",
|
||||
// 来自 Telnyx Mission Control Portal 的 Telnyx webhook 公钥
|
||||
// (Base64 字符串;也可以通过 TELNYX_PUBLIC_KEY 设置)。
|
||||
// Telnyx webhook public key from the Telnyx Mission Control Portal
|
||||
// (Base64 string; can also be set via TELNYX_PUBLIC_KEY).
|
||||
publicKey: "...",
|
||||
},
|
||||
|
||||
@ -90,19 +90,19 @@ cd "$PLUGIN_SRC" && pnpm install
|
||||
authToken: "...",
|
||||
},
|
||||
|
||||
// Webhook 服务器
|
||||
// Webhook server
|
||||
serve: {
|
||||
port: 3334,
|
||||
path: "/voice/webhook",
|
||||
},
|
||||
|
||||
// Webhook 安全性(建议用于隧道 / 代理)
|
||||
// Webhook security (recommended for tunnels/proxies)
|
||||
webhookSecurity: {
|
||||
allowedHosts: ["voice.example.com"],
|
||||
trustedProxyIPs: ["100.64.0.1"],
|
||||
},
|
||||
|
||||
// 对外暴露方式(任选其一)
|
||||
// Public exposure (pick one)
|
||||
// publicUrl: "https://example.ngrok.app/voice/webhook",
|
||||
// tunnel: { provider: "ngrok" },
|
||||
// tailscale: { mode: "funnel", path: "/voice/webhook" }
|
||||
@ -113,11 +113,11 @@ cd "$PLUGIN_SRC" && pnpm install
|
||||
|
||||
streaming: {
|
||||
enabled: true,
|
||||
provider: "openai", // 可选;未设置时使用第一个已注册的实时转录提供商
|
||||
provider: "openai", // optional; first registered realtime transcription provider when unset
|
||||
streamPath: "/voice/stream",
|
||||
providers: {
|
||||
openai: {
|
||||
apiKey: "sk-...", // 如果已设置 OPENAI_API_KEY,则可选
|
||||
apiKey: "sk-...", // optional if OPENAI_API_KEY is set
|
||||
model: "gpt-4o-transcribe",
|
||||
silenceDurationMs: 800,
|
||||
vadThreshold: 0.5,
|
||||
@ -131,7 +131,7 @@ cd "$PLUGIN_SRC" && pnpm install
|
||||
|
||||
realtime: {
|
||||
enabled: false,
|
||||
provider: "google", // 可选;未设置时使用第一个已注册的实时语音提供商
|
||||
provider: "google", // optional; first registered realtime voice provider when unset
|
||||
toolPolicy: "safe-read-only",
|
||||
providers: {
|
||||
google: {
|
||||
@ -147,71 +147,74 @@ cd "$PLUGIN_SRC" && pnpm install
|
||||
}
|
||||
```
|
||||
|
||||
在使用真实提供商进行测试之前,先检查设置:
|
||||
在使用真实提供商测试之前,先检查设置:
|
||||
|
||||
```bash
|
||||
openclaw voicecall setup
|
||||
```
|
||||
|
||||
默认输出便于在聊天日志和终端会话中阅读。它会检查插件是否已启用、提供商和凭证是否存在、webhook 暴露是否已配置,以及是否只启用了一个音频模式。脚本可使用 `openclaw voicecall setup --json`。
|
||||
默认输出在聊天日志和终端会话中都易于阅读。它会检查插件是否已启用、提供商和凭证是否存在、Webhook 暴露是否已配置,以及是否只启用了一个音频模式。脚本使用时可执行 `openclaw voicecall setup --json`。
|
||||
|
||||
如果你想进行一次避免意外的冒烟测试,请运行:
|
||||
对于 Twilio、Telnyx 和 Plivo,设置必须解析为公共 Webhook URL。如果已配置的 `publicUrl`、隧道 URL、Tailscale URL 或 serve 回退地址解析到 loopback 或私有网络空间,则 setup 会失败,而不会启动一个无法接收真实运营商 Webhook 的提供商。
|
||||
|
||||
若要进行一个不出意外的冒烟测试,请运行:
|
||||
|
||||
```bash
|
||||
openclaw voicecall smoke
|
||||
openclaw voicecall smoke --to "+15555550123"
|
||||
```
|
||||
|
||||
第二个命令仍然是一次 dry run。添加 `--yes` 可发起一个简短的呼出通知通话:
|
||||
第二个命令仍然是一次 dry run。添加 `--yes` 以发起一个简短的呼出通知电话:
|
||||
|
||||
```bash
|
||||
openclaw voicecall smoke --to "+15555550123" --yes
|
||||
```
|
||||
|
||||
注意:
|
||||
说明:
|
||||
|
||||
- Twilio / Telnyx 需要一个**可公开访问**的 webhook URL。
|
||||
- Plivo 需要一个**可公开访问**的 webhook URL。
|
||||
- `mock` 是一个本地开发提供商(不进行网络调用)。
|
||||
- 如果旧配置仍在使用 `provider: "log"`、`twilio.from` 或旧版 `streaming.*` OpenAI 键,请运行 `openclaw doctor --fix` 进行重写。
|
||||
- Twilio/Telnyx 需要一个 **可被公网访问的** Webhook URL。
|
||||
- Plivo 需要一个 **可被公网访问的** Webhook URL。
|
||||
- `mock` 是一个本地开发用提供商(无网络调用)。
|
||||
- 如果旧配置仍在使用 `provider: "log"`、`twilio.from` 或旧版 `streaming.*` OpenAI 键,请运行 `openclaw doctor --fix` 来重写它们。
|
||||
- 除非 `skipSignatureVerification` 为 true,否则 Telnyx 需要 `telnyx.publicKey`(或 `TELNYX_PUBLIC_KEY`)。
|
||||
- `skipSignatureVerification` 仅用于本地测试。
|
||||
- 如果你使用 ngrok 免费层,请将 `publicUrl` 设置为精确的 ngrok URL;签名验证始终会被强制执行。
|
||||
- `tunnel.allowNgrokFreeTierLoopbackBypass: true` 仅在 `tunnel.provider="ngrok"` 且 `serve.bind` 为 loopback(ngrok 本地代理)时,允许带有无效签名的 Twilio webhook。仅用于本地开发。
|
||||
- Ngrok 免费层 URL 可能会变化,或增加中间跳转行为;如果 `publicUrl` 漂移,Twilio 签名验证将失败。生产环境中,优先选择稳定域名或 Tailscale funnel。
|
||||
- `realtime.enabled` 会启动完整的语音到语音对话;不要与 `streaming.enabled` 同时启用。
|
||||
- 如果你使用 ngrok 免费层,请将 `publicUrl` 设置为确切的 ngrok URL;签名验证始终会强制执行。
|
||||
- `tunnel.allowNgrokFreeTierLoopbackBypass: true` 仅在 `tunnel.provider="ngrok"` 且 `serve.bind` 为 loopback(ngrok 本地代理)时,允许 Twilio Webhook 使用无效签名。仅用于本地开发。
|
||||
- Ngrok 免费层 URL 可能会变化或增加中间页行为;如果 `publicUrl` 漂移,Twilio 签名校验将失败。在生产环境中,优先使用稳定域名或 Tailscale funnel。
|
||||
- `realtime.enabled` 会启动完整的语音到语音实时对话;不要与 `streaming.enabled` 同时启用。
|
||||
- 流式传输安全默认值:
|
||||
- `streaming.preStartTimeoutMs` 会关闭那些从未发送有效 `start` 帧的套接字。
|
||||
- `streaming.maxPendingConnections` 限制未经身份验证、启动前套接字的总数。
|
||||
- `streaming.maxPendingConnectionsPerIp` 限制每个源 IP 的未经身份验证、启动前套接字数量。
|
||||
- `streaming.maxConnections` 限制已打开媒体流套接字的总数(待启动 + 活跃)。
|
||||
- 运行时回退目前仍会接受这些旧的 voice-call 键,但推荐的重写路径是 `openclaw doctor --fix`,兼容垫片只是临时方案。
|
||||
- `streaming.maxPendingConnections` 限制未认证预启动套接字的总数。
|
||||
- `streaming.maxPendingConnectionsPerIp` 限制每个源 IP 的未认证预启动套接字数量。
|
||||
- `streaming.maxConnections` 限制打开的媒体流套接字总数(待处理 + 活动)。
|
||||
- 运行时回退目前仍接受这些旧的 voice-call 键,但重写路径是 `openclaw doctor --fix`,该兼容垫片只是临时方案。
|
||||
|
||||
## 实时语音对话
|
||||
|
||||
`realtime` 为实时通话音频选择一个全双工实时语音提供商。
|
||||
它与 `streaming` 分开,后者只会将音频转发给实时转录提供商。
|
||||
|
||||
它与 `streaming` 分开,后者只会把音频转发给实时转写提供商。
|
||||
|
||||
当前运行时行为:
|
||||
|
||||
- Twilio Media Streams 支持 `realtime.enabled`。
|
||||
- `realtime.enabled` 不能与 `streaming.enabled` 同时使用。
|
||||
- `realtime.provider` 是可选的。未设置时,Voice Call 会使用第一个已注册的实时语音提供商。
|
||||
- 内置的实时语音提供商包括 Google Gemini Live(`google`)和 OpenAI(`openai`),由它们各自的提供商插件注册。
|
||||
- 提供商自有的原始配置位于 `realtime.providers.<providerId>` 下。
|
||||
- Voice Call 默认暴露共享的 `openclaw_agent_consult` 实时工具。当来电者需要更深入的推理、当前信息或常规 OpenClaw 工具时,实时模型可以调用它。
|
||||
- `realtime.enabled` 支持用于 Twilio Media Streams。
|
||||
- `realtime.enabled` 不能与 `streaming.enabled` 组合使用。
|
||||
- `realtime.provider` 是可选的。未设置时,语音通话会使用第一个已注册的实时语音提供商。
|
||||
- 内置的实时语音提供商包括 Google Gemini Live(`google`)和 OpenAI(`openai`),它们由各自的提供商插件注册。
|
||||
- 提供商拥有的原始配置位于 `realtime.providers.<providerId>` 下。
|
||||
- 默认情况下,语音通话会暴露共享的 `openclaw_agent_consult` 实时工具。当来电者请求更深入的推理、当前信息或普通 OpenClaw 工具时,实时模型可以调用它。
|
||||
- `realtime.toolPolicy` 控制 consult 运行:
|
||||
- `safe-read-only`:暴露 consult 工具,并将常规智能体限制为使用 `read`、`web_search`、`web_fetch`、`x_search`、`memory_search` 和 `memory_get`。
|
||||
- `owner`:暴露 consult 工具,并让常规智能体使用正常的智能体工具策略。
|
||||
- `owner`:暴露 consult 工具,并允许常规智能体使用普通智能体工具策略。
|
||||
- `none`:不暴露 consult 工具。自定义 `realtime.tools` 仍会透传给实时提供商。
|
||||
- Consult 会话键会在可用时复用现有语音会话,否则回退到主叫 / 被叫电话号码,以便后续 consult 调用在通话期间保留上下文。
|
||||
- 如果 `realtime.provider` 指向未注册的提供商,或者根本没有注册任何实时语音提供商,Voice Call 会记录一条警告并跳过实时媒体,而不是让整个插件失败。
|
||||
- Consult 会话键会在可用时复用现有语音会话,然后回退到来电 / 被叫电话号码,以便后续 consult 调用在通话期间保持上下文。
|
||||
- 如果 `realtime.provider` 指向未注册的提供商,或根本没有注册任何实时语音提供商,语音通话会记录一条警告并跳过实时媒体,而不是让整个插件失败。
|
||||
|
||||
Google Gemini Live 实时默认值:
|
||||
|
||||
- API 密钥:`realtime.providers.google.apiKey`、`GEMINI_API_KEY` 或 `GOOGLE_GENERATIVE_AI_API_KEY`
|
||||
- model:`gemini-2.5-flash-native-audio-preview-12-2025`
|
||||
- voice:`Kore`
|
||||
- 模型:`gemini-2.5-flash-native-audio-preview-12-2025`
|
||||
- 语音:`Kore`
|
||||
|
||||
示例:
|
||||
|
||||
@ -270,28 +273,28 @@ Google Gemini Live 实时默认值:
|
||||
|
||||
有关特定提供商的实时语音选项,请参阅 [Google provider](/zh-CN/providers/google) 和 [OpenAI provider](/zh-CN/providers/openai)。
|
||||
|
||||
## 流式转录
|
||||
## 流式转写
|
||||
|
||||
`streaming` 为实时通话音频选择一个实时转录提供商。
|
||||
`streaming` 为实时通话音频选择一个实时转写提供商。
|
||||
|
||||
当前运行时行为:
|
||||
|
||||
- `streaming.provider` 是可选的。未设置时,Voice Call 会使用第一个已注册的实时转录提供商。
|
||||
- 内置的实时转录提供商包括 Deepgram(`deepgram`)、ElevenLabs(`elevenlabs`)、Mistral(`mistral`)、OpenAI(`openai`)和 xAI(`xai`),由它们各自的提供商插件注册。
|
||||
- 提供商自有的原始配置位于 `streaming.providers.<providerId>` 下。
|
||||
- 如果 `streaming.provider` 指向未注册的提供商,或者根本没有注册任何实时转录提供商,Voice Call 会记录一条警告,并跳过媒体流,而不是让整个插件失败。
|
||||
- `streaming.provider` 是可选的。未设置时,语音通话会使用第一个已注册的实时转写提供商。
|
||||
- 内置的实时转写提供商包括 Deepgram(`deepgram`)、ElevenLabs(`elevenlabs`)、Mistral(`mistral`)、OpenAI(`openai`)和 xAI(`xai`),它们由各自的提供商插件注册。
|
||||
- 提供商拥有的原始配置位于 `streaming.providers.<providerId>` 下。
|
||||
- 如果 `streaming.provider` 指向未注册的提供商,或根本没有注册任何实时转写提供商,语音通话会记录一条警告并跳过媒体流式传输,而不是让整个插件失败。
|
||||
|
||||
OpenAI 流式转录默认值:
|
||||
OpenAI 流式转写默认值:
|
||||
|
||||
- API 密钥:`streaming.providers.openai.apiKey` 或 `OPENAI_API_KEY`
|
||||
- model:`gpt-4o-transcribe`
|
||||
- 模型:`gpt-4o-transcribe`
|
||||
- `silenceDurationMs`:`800`
|
||||
- `vadThreshold`:`0.5`
|
||||
|
||||
xAI 流式转录默认值:
|
||||
xAI 流式转写默认值:
|
||||
|
||||
- API 密钥:`streaming.providers.xai.apiKey` 或 `XAI_API_KEY`
|
||||
- endpoint:`wss://api.x.ai/v1/stt`
|
||||
- 端点:`wss://api.x.ai/v1/stt`
|
||||
- `encoding`:`mulaw`
|
||||
- `sampleRate`:`8000`
|
||||
- `endpointingMs`:`800`
|
||||
@ -311,7 +314,7 @@ xAI 流式转录默认值:
|
||||
streamPath: "/voice/stream",
|
||||
providers: {
|
||||
openai: {
|
||||
apiKey: "sk-...", // 如果已设置 OPENAI_API_KEY,则可选
|
||||
apiKey: "sk-...", // optional if OPENAI_API_KEY is set
|
||||
model: "gpt-4o-transcribe",
|
||||
silenceDurationMs: 800,
|
||||
vadThreshold: 0.5,
|
||||
@ -339,7 +342,7 @@ xAI 流式转录默认值:
|
||||
streamPath: "/voice/stream",
|
||||
providers: {
|
||||
xai: {
|
||||
apiKey: "${XAI_API_KEY}", // 如果已设置 XAI_API_KEY,则可选
|
||||
apiKey: "${XAI_API_KEY}", // optional if XAI_API_KEY is set
|
||||
endpointingMs: 800,
|
||||
language: "en",
|
||||
},
|
||||
@ -352,7 +355,7 @@ xAI 流式转录默认值:
|
||||
}
|
||||
```
|
||||
|
||||
旧键仍然会被 `openclaw doctor --fix` 自动迁移:
|
||||
旧键仍可由 `openclaw doctor --fix` 自动迁移:
|
||||
|
||||
- `streaming.sttProvider` → `streaming.provider`
|
||||
- `streaming.openaiApiKey` → `streaming.providers.openai.apiKey`
|
||||
@ -362,15 +365,12 @@ xAI 流式转录默认值:
|
||||
|
||||
## 过期通话清理器
|
||||
|
||||
使用 `staleCallReaperSeconds` 结束那些从未收到终态 webhook 的通话
|
||||
(例如,永远未完成的通知模式通话)。默认值为 `0`
|
||||
(禁用)。
|
||||
使用 `staleCallReaperSeconds` 来结束那些始终未收到终止 Webhook 的通话(例如,始终未完成的通知模式通话)。默认值为 `0`(禁用)。
|
||||
|
||||
推荐范围:
|
||||
|
||||
- **生产环境:** 对于通知式流程,建议设置为 `120`–`300` 秒。
|
||||
- 保持该值**高于 `maxDurationSeconds`**,这样正常通话才能完成。
|
||||
一个好的起始值是 `maxDurationSeconds + 30–60` 秒。
|
||||
- **生产环境:** 对于通知式流程,使用 `120`–`300` 秒。
|
||||
- 将此值保持为 **高于 `maxDurationSeconds`**,这样正常通话才能完成。一个不错的起始值是 `maxDurationSeconds + 30–60` 秒。
|
||||
|
||||
示例:
|
||||
|
||||
@ -389,25 +389,25 @@ xAI 流式转录默认值:
|
||||
}
|
||||
```
|
||||
|
||||
## Webhook 安全性
|
||||
## Webhook 安全
|
||||
|
||||
当前方有代理或隧道位于 Gateway 网关之前时,插件会重建公开 URL 以进行签名验证。这些选项用于控制哪些转发头会被信任。
|
||||
当代理或隧道位于 Gateway 网关前面时,插件会重建公共 URL 以进行签名验证。这些选项用于控制哪些转发头会被信任。
|
||||
|
||||
`webhookSecurity.allowedHosts` 会对转发头中的主机进行 allowlist 限制。
|
||||
`webhookSecurity.allowedHosts` 允许通过转发头传递的主机名白名单。
|
||||
|
||||
`webhookSecurity.trustForwardingHeaders` 会在没有 allowlist 的情况下信任转发头。
|
||||
`webhookSecurity.trustForwardingHeaders` 在没有允许列表的情况下信任转发头。
|
||||
|
||||
`webhookSecurity.trustedProxyIPs` 仅在请求的远端 IP 与列表匹配时,才信任转发头。
|
||||
`webhookSecurity.trustedProxyIPs` 仅在请求远程 IP 与列表匹配时才信任转发头。
|
||||
|
||||
Twilio 和 Plivo 默认启用 webhook 重放保护。被重放的有效 webhook 请求会被确认接收,但会跳过副作用处理。
|
||||
Twilio 和 Plivo 启用了 Webhook 重放保护。被重放的有效 Webhook 请求会被确认,但会跳过副作用处理。
|
||||
|
||||
Twilio 对话轮次在 `<Gather>` 回调中包含每轮一个令牌,因此过期 / 重放的语音回调不能满足更新后的待处理转录轮次。
|
||||
Twilio 对话轮次在 `<Gather>` 回调中包含每轮专用令牌,因此过期 / 重放的语音回调无法满足较新的待处理转写轮次。
|
||||
|
||||
当缺少提供商要求的签名头时,未认证的 webhook 请求会在读取请求体之前被拒绝。
|
||||
当提供商要求的签名头缺失时,未认证的 Webhook 请求会在读取正文之前被拒绝。
|
||||
|
||||
voice-call webhook 在签名验证之前,使用共享的预认证请求体配置文件(64 KB / 5 秒)以及每个 IP 的处理中请求上限。
|
||||
voice-call Webhook 在签名验证之前使用共享的预认证 body 配置文件(64 KB / 5 秒)以及基于每个 IP 的并发上限。
|
||||
|
||||
使用稳定公开主机的示例:
|
||||
使用稳定公共主机的示例:
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -426,9 +426,9 @@ voice-call webhook 在签名验证之前,使用共享的预认证请求体配
|
||||
}
|
||||
```
|
||||
|
||||
## 通话的 TTS
|
||||
## 用于通话的 TTS
|
||||
|
||||
Voice Call 对通话中的流式语音使用核心 `messages.tts` 配置。你可以在插件配置下使用**相同的结构**进行覆盖——它会与 `messages.tts` 进行深度合并。
|
||||
语音通话会使用核心 `messages.tts` 配置来实现通话中的流式语音。你可以在插件配置下使用 **相同结构** 覆盖它 —— 它会与 `messages.tts` 进行深度合并。
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -444,13 +444,14 @@ Voice Call 对通话中的流式语音使用核心 `messages.tts` 配置。你
|
||||
}
|
||||
```
|
||||
|
||||
注意:
|
||||
说明:
|
||||
|
||||
- 插件配置中的旧版 `tts.<provider>` 键(`openai`、`elevenlabs`、`microsoft`、`edge`)可通过 `openclaw doctor --fix` 修复;已提交的配置应使用 `tts.providers.<provider>`。
|
||||
- **Microsoft speech 会被语音通话忽略**(电话音频需要 PCM;当前 Microsoft 传输不提供电话 PCM 输出)。
|
||||
- 启用 Twilio 媒体流时,会使用核心 TTS;否则通话会回退到提供商原生语音。
|
||||
- 如果 Twilio 媒体流已经激活,Voice Call 不会回退到 TwiML `<Say>`。如果在该状态下电话 TTS 不可用,播放请求会失败,而不是混用两条播放路径。
|
||||
- 当电话 TTS 回退到次级提供商时,Voice Call 会记录一条包含提供商链(`from`、`to`、`attempts`)的警告日志,以便调试。
|
||||
- 插件配置中的旧版 `tts.<provider>` 键(`openai`、`elevenlabs`、`microsoft`、`edge`)可由 `openclaw doctor --fix` 修复;提交的配置应使用 `tts.providers.<provider>`。
|
||||
- **Microsoft speech 会被语音通话忽略**(电话音频需要 PCM;当前 Microsoft 传输方式不暴露电话用 PCM 输出)。
|
||||
- 启用 Twilio 媒体流时会使用核心 TTS;否则通话会回退到提供商原生语音。
|
||||
- 如果 Twilio 媒体流已处于活动状态,语音通话不会回退到 TwiML `<Say>`。在该状态下,如果电话 TTS 不可用,则播放请求会失败,而不是混用两条播放路径。
|
||||
- 当电话 TTS 回退到次级提供商时,语音通话会记录一条包含提供商链(`from`、`to`、`attempts`)的警告,以便调试。
|
||||
- 当 Twilio 插话或流拆除清除待处理 TTS 队列时,排队的播放请求会结束,而不会让正在等待播放完成的来电者一直挂起。
|
||||
|
||||
### 更多示例
|
||||
|
||||
@ -494,7 +495,7 @@ Voice Call 对通话中的流式语音使用核心 `messages.tts` 配置。你
|
||||
}
|
||||
```
|
||||
|
||||
仅为通话覆盖 OpenAI 模型(深度合并示例):
|
||||
仅覆盖通话使用的 OpenAI 模型(深度合并示例):
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -519,7 +520,7 @@ Voice Call 对通话中的流式语音使用核心 `messages.tts` 配置。你
|
||||
|
||||
## 呼入通话
|
||||
|
||||
呼入策略默认是 `disabled`。要启用呼入通话,请设置:
|
||||
呼入策略默认值为 `disabled`。要启用呼入通话,请设置:
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -529,7 +530,7 @@ Voice Call 对通话中的流式语音使用核心 `messages.tts` 配置。你
|
||||
}
|
||||
```
|
||||
|
||||
`inboundPolicy: "allowlist"` 是一种低保障的来电号码筛选方式。插件会对提供商给出的 `From` 值进行标准化,并将其与 `allowFrom` 进行比较。Webhook 验证可以验证提供商投递和负载完整性,但不能证明 PSTN / VoIP 来电号码的所有权。应将 `allowFrom` 视为来电显示过滤,而不是强身份认证。
|
||||
`inboundPolicy: "allowlist"` 是一种低保障的来电显示筛选方式。插件会规范化提供商给出的 `From` 值,并将其与 `allowFrom` 进行比较。Webhook 验证可以验证提供商投递和载荷完整性,但不能证明 PSTN/VoIP 来电号码的归属权。请将 `allowFrom` 视为来电显示过滤,而不是强来电身份认证。
|
||||
|
||||
自动响应使用智能体系统。可通过以下项进行调整:
|
||||
|
||||
@ -539,51 +540,51 @@ Voice Call 对通话中的流式语音使用核心 `messages.tts` 配置。你
|
||||
|
||||
### 语音输出约定
|
||||
|
||||
对于自动响应,Voice Call 会在系统提示词后追加一个严格的语音输出约定:
|
||||
对于自动响应,语音通话会向系统提示附加一个严格的语音输出约定:
|
||||
|
||||
- `{"spoken":"..."}`
|
||||
|
||||
然后 Voice Call 会以防御性方式提取语音文本:
|
||||
然后语音通话会以防御式方式提取语音文本:
|
||||
|
||||
- 忽略被标记为推理 / 错误内容的负载。
|
||||
- 解析直接 JSON、带围栏的 JSON 或内联 `"spoken"` 键。
|
||||
- 回退到纯文本,并移除可能属于计划 / 元信息前导段落的内容。
|
||||
- 忽略标记为推理 / 错误内容的载荷。
|
||||
- 解析直接 JSON、围栏 JSON 或内联 `"spoken"` 键。
|
||||
- 回退为纯文本,并删除可能的规划 / 元信息引导段落。
|
||||
|
||||
这样可以让语音播放专注于面向来电者的文本,并避免将计划文本泄露到音频中。
|
||||
这样可以让语音播放聚焦于面向来电者的文本,并避免将规划文本泄漏到音频中。
|
||||
|
||||
### 对话启动行为
|
||||
|
||||
对于呼出 `conversation` 通话,首条消息处理与实时播放状态绑定:
|
||||
对于呼出的 `conversation` 通话,首条消息处理与实时播放状态绑定:
|
||||
|
||||
- 仅当初始问候语正在主动播放时,才会抑制插话清队列和自动响应。
|
||||
- 如果初始播放失败,通话会返回 `listening` 状态,初始消息会保留在队列中以便重试。
|
||||
- Twilio 流式传输的初始播放会在流连接时启动,无需额外延迟。
|
||||
- 实时语音对话使用实时流自身的开场轮次。Voice Call 不会为该初始消息发送旧版 `<Say>` TwiML 更新,因此呼出的 `<Connect><Stream>` 会话会保持附着状态。
|
||||
- 仅当初始问候正在主动播放时,才会抑制插话队列清除和自动响应。
|
||||
- 如果初始播放失败,通话会返回 `listening` 状态,且初始消息会继续保留在队列中等待重试。
|
||||
- Twilio 流式传输的初始播放会在流连接时立即开始,无额外延迟。
|
||||
- 插话会中止当前播放,并清除那些已排队但尚未开始播放的 Twilio TTS 条目。被清除的条目会以已跳过状态结束,因此后续响应逻辑可以继续,而不必等待那些永远不会播放的音频。
|
||||
- 实时语音对话使用实时流自身的开场轮次。语音通话不会为该初始消息发送旧版 `<Say>` TwiML 更新,因此呼出的 `<Connect><Stream>` 会话会保持附着状态。
|
||||
|
||||
### Twilio 流断开宽限期
|
||||
|
||||
当 Twilio 媒体流断开时,Voice Call 会等待 `2000ms` 后才自动结束通话:
|
||||
当 Twilio 媒体流断开时,语音通话会等待 `2000ms` 后再自动结束通话:
|
||||
|
||||
- 如果流在该时间窗口内重新连接,则会取消自动结束。
|
||||
- 如果宽限期过后仍未重新注册流,则通话会被结束,以防止卡住的活跃通话。
|
||||
- 如果流在该时间窗口内重新连接,则自动结束会被取消。
|
||||
- 如果宽限期过后仍未重新注册任何流,则该通话会被结束,以防止通话卡在活动状态。
|
||||
|
||||
## CLI
|
||||
|
||||
```bash
|
||||
openclaw voicecall call --to "+15555550123" --message "Hello from OpenClaw"
|
||||
openclaw voicecall start --to "+15555550123" # call 的别名
|
||||
openclaw voicecall start --to "+15555550123" # alias for call
|
||||
openclaw voicecall continue --call-id <id> --message "Any questions?"
|
||||
openclaw voicecall speak --call-id <id> --message "One moment"
|
||||
openclaw voicecall dtmf --call-id <id> --digits "ww123456#"
|
||||
openclaw voicecall end --call-id <id>
|
||||
openclaw voicecall status --call-id <id>
|
||||
openclaw voicecall tail
|
||||
openclaw voicecall latency # 从日志汇总轮次延迟
|
||||
openclaw voicecall latency # summarize turn latency from logs
|
||||
openclaw voicecall expose --mode funnel
|
||||
```
|
||||
|
||||
`latency` 会从默认的 voice-call 存储路径读取 `calls.jsonl`。使用
|
||||
`--file <path>` 指向其他日志文件,使用 `--last <n>` 将分析限制为最后 N 条记录(默认 200)。输出包括轮次延迟和监听等待时间的 p50 / p90 / p99。
|
||||
`latency` 会从默认的 voice-call 存储路径读取 `calls.jsonl`。使用 `--file <path>` 指向其他日志文件,使用 `--last <n>` 将分析限制为最后 N 条记录(默认 200)。输出包括轮次延迟和监听等待时间的 p50/p90/p99。
|
||||
|
||||
## 智能体工具
|
||||
|
||||
@ -591,21 +592,21 @@ openclaw voicecall expose --mode funnel
|
||||
|
||||
操作:
|
||||
|
||||
- `initiate_call`(message、to?、mode?)
|
||||
- `continue_call`(callId、message)
|
||||
- `speak_to_user`(callId、message)
|
||||
- `send_dtmf`(callId、digits)
|
||||
- `initiate_call`(message, to?, mode?)
|
||||
- `continue_call`(callId, message)
|
||||
- `speak_to_user`(callId, message)
|
||||
- `send_dtmf`(callId, digits)
|
||||
- `end_call`(callId)
|
||||
- `get_status`(callId)
|
||||
|
||||
此仓库在 `skills/voice-call/SKILL.md` 中提供了对应的 skill 文档。
|
||||
此仓库提供了对应的 skill 文档,路径为 `skills/voice-call/SKILL.md`。
|
||||
|
||||
## Gateway 网关 RPC
|
||||
|
||||
- `voicecall.initiate`(`to?`、`message`、`mode?`)
|
||||
- `voicecall.continue`(`callId`、`message`)
|
||||
- `voicecall.speak`(`callId`、`message`)
|
||||
- `voicecall.dtmf`(`callId`、`digits`)
|
||||
- `voicecall.initiate`(`to?`, `message`, `mode?`)
|
||||
- `voicecall.continue`(`callId`, `message`)
|
||||
- `voicecall.speak`(`callId`, `message`)
|
||||
- `voicecall.dtmf`(`callId`, `digits`)
|
||||
- `voicecall.end`(`callId`)
|
||||
- `voicecall.status`(`callId`)
|
||||
|
||||
|
||||
@ -1,26 +1,28 @@
|
||||
---
|
||||
read_when:
|
||||
- 更改 Control UI 中的助手输出渲染
|
||||
- 调试 `[embed ...]`、`MEDIA:`、reply 或音频展示指令
|
||||
summary: 用于 embeds、媒体、音频提示和回复的富输出短代码协议
|
||||
- 更改 Control UI 中的智能体输出渲染方式
|
||||
- 调试 `[embed ...]`、`MEDIA:`、回复或音频呈现指令
|
||||
summary: 用于嵌入、媒体、音频提示和回复的富输出短代码协议
|
||||
title: 富输出协议
|
||||
x-i18n:
|
||||
generated_at: "2026-04-24T03:43:28Z"
|
||||
generated_at: "2026-04-25T04:54:58Z"
|
||||
model: gpt-5.4
|
||||
provider: openai
|
||||
source_hash: 688d60c97180b4ba250e731d765e8469a01c68588c149b760c32eab77955f69b
|
||||
source_hash: 3ccd0698d88aae86d8f857f4f16f999d161e08542bf6d02bbd54a4a23bdbd5a8
|
||||
source_path: reference/rich-output-protocol.md
|
||||
workflow: 15
|
||||
---
|
||||
|
||||
助手输出可以携带一小组投递/渲染指令:
|
||||
智能体输出可以携带一小组传递/渲染指令:
|
||||
|
||||
- `MEDIA:` 用于附件投递
|
||||
- `[[audio_as_voice]]` 用于音频展示提示
|
||||
- `MEDIA:` 用于附件传递
|
||||
- `[[audio_as_voice]]` 用于音频呈现提示
|
||||
- `[[reply_to_current]]` / `[[reply_to:<id>]]` 用于回复元数据
|
||||
- `[embed ...]` 用于 Control UI 富渲染
|
||||
|
||||
这些指令彼此独立。`MEDIA:` 和 reply/voice 标签仍然属于投递元数据;`[embed ...]` 是仅限 Web 的富渲染路径。
|
||||
这些指令彼此独立。`MEDIA:` 和回复/语音标签仍然是传递元数据;`[embed ...]` 是仅限 Web 的富渲染路径。
|
||||
|
||||
启用分块流式传输后,`MEDIA:` 仍然是单次会话回合的单次传递元数据。如果同一个媒体 URL 在流式块中发送,并在最终智能体载荷中重复出现,OpenClaw 会只传递一次附件,并从最终载荷中移除重复项。
|
||||
|
||||
## `[embed ...]`
|
||||
|
||||
@ -35,15 +37,15 @@ x-i18n:
|
||||
规则:
|
||||
|
||||
- `[view ...]` 不再适用于新的输出。
|
||||
- Embed 短代码仅会在助手消息界面中渲染。
|
||||
- 只有基于 URL 的 embed 才会被渲染。请使用 `ref="..."` 或 `url="..."`。
|
||||
- Embed 短代码只会在智能体消息界面中渲染。
|
||||
- 只会渲染由 URL 支持的嵌入。请使用 `ref="..."` 或 `url="..."`。
|
||||
- 块形式的内联 HTML embed 短代码不会被渲染。
|
||||
- Web UI 会从可见文本中剥离该短代码,并将 embed 内联渲染。
|
||||
- `MEDIA:` 不是 embed 别名,不应用于富 embed 渲染。
|
||||
- Web UI 会从可见文本中移除该短代码,并以内联方式渲染嵌入内容。
|
||||
- `MEDIA:` 不是 embed 的别名,不应用于富嵌入渲染。
|
||||
|
||||
## 已存储的渲染形状
|
||||
## 存储的渲染形态
|
||||
|
||||
规范化/存储后的助手内容块是一个结构化的 `canvas` 项:
|
||||
标准化/存储后的智能体内容块是一个结构化的 `canvas` 项:
|
||||
|
||||
```json
|
||||
{
|
||||
@ -60,9 +62,9 @@ x-i18n:
|
||||
}
|
||||
```
|
||||
|
||||
已存储/已渲染的富块会直接使用这个 `canvas` 形状。`present_view` 不会被识别。
|
||||
已存储/已渲染的富块会直接使用这个 `canvas` 形态。`present_view` 不会被识别。
|
||||
|
||||
## 相关内容
|
||||
|
||||
- [RPC adapters](/zh-CN/reference/rpc)
|
||||
- [RPC 适配器](/zh-CN/reference/rpc)
|
||||
- [Typebox](/zh-CN/concepts/typebox)
|
||||
|
||||
@ -4,38 +4,36 @@ read_when:
|
||||
- 调试为什么 openclaw 会干扰你自己的 Chrome
|
||||
- 在 macOS 应用中实现浏览器设置 + 生命周期
|
||||
summary: 集成的浏览器控制服务 + 操作命令
|
||||
title: 浏览器(OpenClaw 管理)
|
||||
title: 浏览器(由 OpenClaw 管理)
|
||||
x-i18n:
|
||||
generated_at: "2026-04-25T02:55:43Z"
|
||||
generated_at: "2026-04-25T04:54:58Z"
|
||||
model: gpt-5.4
|
||||
provider: openai
|
||||
source_hash: 34b51f5d57a3a8092d2082efd9131933f4ae5777173143b521946edaf005b589
|
||||
source_hash: cdcc8c16f474f5265bcbd38bcc3266ad3bad9e61d378750427baa69349fefd89
|
||||
source_path: tools/browser.md
|
||||
workflow: 15
|
||||
---
|
||||
|
||||
OpenClaw 可以运行一个**专用的 Chrome/Brave/Edge/Chromium 配置文件**,由智能体进行控制。
|
||||
它与你的个人浏览器隔离,并通过 Gateway 网关内部的一个小型本地控制服务进行管理
|
||||
OpenClaw 可以运行一个**专用的 Chrome/Brave/Edge/Chromium 配置文件**,由智能体控制。
|
||||
它与你的个人浏览器隔离,并通过 Gateway 网关内部的小型本地控制服务进行管理
|
||||
(仅限 loopback)。
|
||||
|
||||
初学者视角:
|
||||
|
||||
- 可以把它看作一个**独立的、仅供智能体使用的浏览器**。
|
||||
- `openclaw` 配置文件**不会**触碰你的个人浏览器配置文件。
|
||||
- 把它理解成一个**独立的、仅供智能体使用的浏览器**。
|
||||
- `openclaw` 配置文件**不会**接触你的个人浏览器配置文件。
|
||||
- 智能体可以在一条安全通道中**打开标签页、读取页面、点击和输入**。
|
||||
- 内置的 `user` 配置文件会通过 Chrome MCP 连接到你真实的已登录 Chrome 会话。
|
||||
- 内置的 `user` 配置文件会通过 Chrome MCP 附加到你真实的已登录 Chrome 会话。
|
||||
|
||||
## 你将获得什么
|
||||
|
||||
- 一个名为 **openclaw** 的独立浏览器配置文件(默认带橙色强调色)。
|
||||
- 确定性的标签页控制(列出/打开/聚焦/关闭)。
|
||||
- 智能体操作(点击/输入/拖拽/选择)、快照、截图、PDF。
|
||||
- 一个内置的 `browser-automation` Skills,用于在启用浏览器
|
||||
插件时,教智能体处理 snapshot、stable-tab、stale-ref,以及
|
||||
manual-blocker 恢复循环。
|
||||
- 可选的多配置文件支持(`openclaw`、`work`、`remote` 等)。
|
||||
- 一个名为 **openclaw** 的独立浏览器配置文件(默认使用橙色强调色)。
|
||||
- 可预测的标签页控制(列出/打开/聚焦/关闭)。
|
||||
- 智能体操作(点击/输入/拖动/选择)、快照、截图、PDF。
|
||||
- 一个内置的 `browser-automation` Skills,在启用浏览器插件时,会教智能体使用快照、稳定标签页、过期引用和手动阻塞恢复循环。
|
||||
- 可选的多配置文件支持(`openclaw`、`work`、`remote`、……)。
|
||||
|
||||
这个浏览器**不是**你日常使用的主力浏览器。它是一个安全、隔离的表面,用于
|
||||
这个浏览器**不是**你的日常主力浏览器。它是一个安全、隔离的界面,用于
|
||||
智能体自动化和验证。
|
||||
|
||||
## 快速开始
|
||||
@ -48,15 +46,14 @@ openclaw browser --browser-profile openclaw open https://example.com
|
||||
openclaw browser --browser-profile openclaw snapshot
|
||||
```
|
||||
|
||||
如果你看到“Browser disabled”,请在配置中启用它(见下文),然后重启
|
||||
如果你看到 “Browser disabled”,请在配置中启用它(见下文),然后重启
|
||||
Gateway 网关。
|
||||
|
||||
如果根本没有 `openclaw browser`,或者智能体提示浏览器工具
|
||||
不可用,请跳转到[缺少浏览器命令或工具](/zh-CN/tools/browser#missing-browser-command-or-tool)。
|
||||
如果根本没有 `openclaw browser`,或者智能体提示浏览器工具不可用,请跳转到 [缺少浏览器命令或工具](/zh-CN/tools/browser#missing-browser-command-or-tool)。
|
||||
|
||||
## 插件控制
|
||||
|
||||
默认的 `browser` 工具是一个内置插件。你可以禁用它,以便用另一个注册了相同 `browser` 工具名的插件来替换:
|
||||
默认的 `browser` 工具是一个内置插件。你可以禁用它,并替换为另一个注册相同 `browser` 工具名称的插件:
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -70,29 +67,22 @@ Gateway 网关。
|
||||
}
|
||||
```
|
||||
|
||||
默认情况下需要同时设置 `plugins.entries.browser.enabled` **以及** `browser.enabled=true`。如果只禁用插件,会一并移除 `openclaw browser` CLI、`browser.request` Gateway 网关方法、智能体工具和控制服务;你的 `browser.*` 配置会保持不变,以供替代方案使用。
|
||||
默认值需要同时设置 `plugins.entries.browser.enabled` **和** `browser.enabled=true`。如果只禁用插件,会整体移除 `openclaw browser` CLI、`browser.request` Gateway 网关方法、智能体工具和控制服务;你的 `browser.*` 配置会保持不变,以供替代方案使用。
|
||||
|
||||
浏览器配置变更需要重启 Gateway 网关,这样插件才能重新注册其服务。
|
||||
|
||||
## 智能体指引
|
||||
|
||||
浏览器插件附带两层智能体指引:
|
||||
浏览器插件提供两层智能体指引:
|
||||
|
||||
- `browser` 工具描述承载的是精简且始终启用的契约:选择
|
||||
正确的配置文件,在同一标签页内保持 refs 一致,使用 `tabId`/标签进行标签页
|
||||
定位,并在执行多步骤任务时加载浏览器 Skills。
|
||||
- 内置的 `browser-automation` Skills 承载更长的操作循环:
|
||||
先检查状态/标签页,给任务标签页加标签,在操作前先做 snapshot,在 UI 变化后重新 snapshot,
|
||||
遇到 stale refs 时恢复一次,并将登录/2FA/captcha 或
|
||||
摄像头/麦克风阻塞报告为需要手动处理的操作,而不是猜测。
|
||||
- `browser` 工具说明中包含精简的常驻契约:选择正确的配置文件、在同一标签页中保持引用、使用 `tabId`/标签来定位标签页,以及在执行多步骤任务时加载浏览器 Skills。
|
||||
- 内置的 `browser-automation` Skills 包含更完整的操作循环:先检查状态/标签页、给任务标签页加标签、执行操作前先做快照、UI 变化后重新获取快照、遇到过期引用时重试恢复一次,并在遇到登录/2FA/captcha 或摄像头/麦克风阻塞时,报告为需要手动操作,而不是猜测处理。
|
||||
|
||||
当插件启用时,插件内置的 Skills 会列在智能体的可用 Skills 中。
|
||||
完整的 Skills 说明会按需加载,因此常规轮次
|
||||
不需要承担完整的 token 成本。
|
||||
当插件启用时,插件内置的 Skills 会列在智能体可用 Skills 中。完整的 Skills 指令按需加载,因此日常轮次不会承担完整的 token 成本。
|
||||
|
||||
## 缺少浏览器命令或工具
|
||||
|
||||
如果升级后 `openclaw browser` 变成未知命令,`browser.request` 缺失,或者智能体报告浏览器工具不可用,通常原因是 `plugins.allow` 列表中遗漏了 `browser`。请添加它:
|
||||
如果升级后 `openclaw browser` 无法识别、缺少 `browser.request`,或者智能体报告浏览器工具不可用,通常原因是 `plugins.allow` 列表中遗漏了 `browser`。请添加它:
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -102,20 +92,19 @@ Gateway 网关。
|
||||
}
|
||||
```
|
||||
|
||||
`browser.enabled=true`、`plugins.entries.browser.enabled=true` 和 `tools.alsoAllow: ["browser"]` 都不能替代 allowlist 成员资格——allowlist 控制插件是否加载,而工具策略只会在加载之后运行。完全移除 `plugins.allow` 也会恢复默认行为。
|
||||
`browser.enabled=true`、`plugins.entries.browser.enabled=true` 和 `tools.alsoAllow: ["browser"]` 不能替代允许列表成员资格——允许列表控制插件是否加载,而工具策略只有在加载后才会运行。彻底移除 `plugins.allow` 也会恢复默认行为。
|
||||
|
||||
## 配置文件:`openclaw` 与 `user`
|
||||
|
||||
- `openclaw`:受管理、隔离的浏览器(不需要扩展)。
|
||||
- `user`:内置的 Chrome MCP 附加配置文件,用于连接你**真实的已登录 Chrome**
|
||||
- `user`:内置 Chrome MCP 附加配置文件,用于接入你**真实已登录的 Chrome**
|
||||
会话。
|
||||
|
||||
对于智能体浏览器工具调用:
|
||||
|
||||
- 默认:使用隔离的 `openclaw` 浏览器。
|
||||
- 当现有已登录会话很重要,并且用户
|
||||
正在电脑前可以点击/批准任何连接提示时,优先使用 `profile="user"`。
|
||||
- 当你想要特定的浏览器模式时,`profile` 是显式覆盖项。
|
||||
- 当已有登录会话很重要,且用户就在电脑前可以点击/批准任何附加提示时,优先使用 `profile="user"`。
|
||||
- 当你想使用特定浏览器模式时,`profile` 是显式覆盖项。
|
||||
|
||||
如果你希望默认使用受管理模式,请设置 `browser.defaultProfile: "openclaw"`。
|
||||
|
||||
@ -126,10 +115,10 @@ Gateway 网关。
|
||||
```json5
|
||||
{
|
||||
browser: {
|
||||
enabled: true, // 默认值:true
|
||||
enabled: true, // 默认:true
|
||||
ssrfPolicy: {
|
||||
// dangerouslyAllowPrivateNetwork: true, // 仅在信任私有网络访问时选择启用
|
||||
// allowPrivateNetwork: true, // 旧版别名
|
||||
// dangerouslyAllowPrivateNetwork: true, // 仅在受信任的私有网络访问场景中启用
|
||||
// allowPrivateNetwork: true, // 旧别名
|
||||
// hostnameAllowlist: ["*.example.com", "example.com"],
|
||||
// allowedHostnames: ["localhost"],
|
||||
},
|
||||
@ -137,9 +126,9 @@ Gateway 网关。
|
||||
remoteCdpTimeoutMs: 1500, // 远程 CDP HTTP 超时(毫秒)
|
||||
remoteCdpHandshakeTimeoutMs: 3000, // 远程 CDP WebSocket 握手超时(毫秒)
|
||||
tabCleanup: {
|
||||
enabled: true, // 默认值:true
|
||||
idleMinutes: 120, // 设为 0 可禁用空闲清理
|
||||
maxTabsPerSession: 8, // 设为 0 可禁用每会话上限
|
||||
enabled: true, // 默认:true
|
||||
idleMinutes: 120, // 设为 0 以禁用空闲清理
|
||||
maxTabsPerSession: 8, // 设为 0 以禁用每会话上限
|
||||
sweepMinutes: 5,
|
||||
},
|
||||
defaultProfile: "openclaw",
|
||||
@ -150,7 +139,12 @@ Gateway 网关。
|
||||
executablePath: "/Applications/Brave Browser.app/Contents/MacOS/Brave Browser",
|
||||
profiles: {
|
||||
openclaw: { cdpPort: 18800, color: "#FF4500" },
|
||||
work: { cdpPort: 18801, color: "#0066CC", headless: true },
|
||||
work: {
|
||||
cdpPort: 18801,
|
||||
color: "#0066CC",
|
||||
headless: true,
|
||||
executablePath: "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome",
|
||||
},
|
||||
user: {
|
||||
driver: "existing-session",
|
||||
attachOnly: true,
|
||||
@ -172,46 +166,48 @@ Gateway 网关。
|
||||
|
||||
<Accordion title="端口与可达性">
|
||||
|
||||
- 控制服务会绑定到一个 loopback 端口,该端口由 `gateway.port` 派生而来(默认 `18791` = gateway + 2)。覆盖 `gateway.port` 或 `OPENCLAW_GATEWAY_PORT` 时,同一组派生端口也会相应变化。
|
||||
- 控制服务绑定到 loopback,端口由 `gateway.port` 派生而来(默认 `18791` = gateway + 2)。覆盖 `gateway.port` 或 `OPENCLAW_GATEWAY_PORT` 会同步移动同一组派生端口。
|
||||
- 本地 `openclaw` 配置文件会自动分配 `cdpPort`/`cdpUrl`;只有远程 CDP 才需要设置这些值。未设置时,`cdpUrl` 默认使用受管理的本地 CDP 端口。
|
||||
- `remoteCdpTimeoutMs` 适用于远程(非 loopback)CDP HTTP 可达性检查;`remoteCdpHandshakeTimeoutMs` 适用于远程 CDP WebSocket 握手。
|
||||
- `tabCleanup` 是针对主智能体浏览器会话所打开标签页的尽力清理机制。子智能体、cron 和 ACP 生命周期清理仍会在会话结束时关闭各自显式跟踪的标签页;主会话会保留活动标签页以便复用,然后在后台关闭空闲或超出数量的已跟踪标签页。
|
||||
- `tabCleanup` 是对主智能体浏览器会话所打开标签页的尽力清理。子智能体、cron 和 ACP 生命周期清理仍会在会话结束时关闭其显式跟踪的标签页;主会话会保留活跃标签页以便重复利用,然后在后台关闭空闲或超出的已跟踪标签页。
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="SSRF 策略">
|
||||
|
||||
- 浏览器导航和打开标签页在导航前会受到 SSRF 防护,并会在导航完成后对最终的 `http(s)` URL 再进行一次尽力复检。
|
||||
- 浏览器导航和打开标签页会在导航前进行 SSRF 防护,并在导航完成后的最终 `http(s)` URL 上尽力再次检查。
|
||||
- 在严格 SSRF 模式下,远程 CDP 端点发现和 `/json/version` 探测(`cdpUrl`)也会被检查。
|
||||
- Gateway 网关/提供商的 `HTTP_PROXY`、`HTTPS_PROXY`、`ALL_PROXY` 和 `NO_PROXY` 环境变量不会自动为 OpenClaw 管理的浏览器启用代理。受管理的 Chrome 默认直接启动,因此提供商代理设置不会削弱浏览器 SSRF 检查。
|
||||
- 若要为受管理浏览器本身设置代理,请通过 `browser.extraArgs` 传入显式 Chrome 代理标志,例如 `--proxy-server=...` 或 `--proxy-pac-url=...`。严格 SSRF 模式会阻止显式浏览器代理路由,除非你已明确启用私有网络浏览器访问。
|
||||
- `browser.ssrfPolicy.dangerouslyAllowPrivateNetwork` 默认关闭;仅当你明确可信任私有网络浏览器访问时才启用。
|
||||
- `browser.ssrfPolicy.allowPrivateNetwork` 仍然作为旧版别名受支持。
|
||||
- Gateway 网关/提供商的 `HTTP_PROXY`、`HTTPS_PROXY`、`ALL_PROXY` 和 `NO_PROXY` 环境变量不会自动代理由 OpenClaw 管理的浏览器。受管理的 Chrome 默认直连启动,因此提供商代理设置不会削弱浏览器的 SSRF 检查。
|
||||
- 如果你要代理受管理浏览器本身,请通过 `browser.extraArgs` 传递显式的 Chrome 代理标志,例如 `--proxy-server=...` 或 `--proxy-pac-url=...`。在严格 SSRF 模式下,除非你明确启用了私有网络浏览器访问,否则显式浏览器代理路由会被阻止。
|
||||
- `browser.ssrfPolicy.dangerouslyAllowPrivateNetwork` 默认关闭;只有在明确可信任私有网络浏览器访问时才应启用。
|
||||
- `browser.ssrfPolicy.allowPrivateNetwork` 仍然作为旧别名受支持。
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="配置文件行为">
|
||||
|
||||
- `attachOnly: true` 表示绝不启动本地浏览器;仅在浏览器已经运行时进行附加。
|
||||
- `headless` 可以在全局或按本地受管理配置文件设置。按配置文件设置的值会覆盖 `browser.headless`,因此一个本地启动的配置文件可以保持 headless,而另一个仍然保持可见。
|
||||
- `color`(顶层和按配置文件)会给浏览器 UI 着色,方便你查看当前激活的是哪个配置文件。
|
||||
- `attachOnly: true` 表示绝不启动本地浏览器;仅在浏览器已经运行时附加。
|
||||
- `headless` 可以在全局或每个本地受管理配置文件上设置。每个配置文件的值会覆盖 `browser.headless`,因此一个本地启动的配置文件可以保持无头,而另一个仍然可见。
|
||||
- `executablePath` 也可以在全局或每个本地受管理配置文件上设置。每个配置文件的值会覆盖 `browser.executablePath`,因此不同的受管理配置文件可以启动不同的 Chromium 系浏览器。
|
||||
- `color`(顶层和每个配置文件级别)会为浏览器 UI 着色,这样你可以看出当前激活的是哪个配置文件。
|
||||
- 默认配置文件是 `openclaw`(受管理的独立模式)。使用 `defaultProfile: "user"` 可切换为已登录的用户浏览器。
|
||||
- 自动检测顺序:如果系统默认浏览器是基于 Chromium,则优先使用它;否则按 Chrome → Brave → Edge → Chromium → Chrome Canary 的顺序检测。
|
||||
- `driver: "existing-session"` 使用 Chrome DevTools MCP,而不是原始 CDP。不要为这个 driver 设置 `cdpUrl`。
|
||||
- 当某个 existing-session 配置文件应附加到一个非默认的 Chromium 用户配置文件(Brave、Edge 等)时,请设置 `browser.profiles.<name>.userDataDir`。
|
||||
- 自动检测顺序:如果系统默认浏览器是 Chromium 系,则优先使用它;否则按 Chrome → Brave → Edge → Chromium → Chrome Canary 的顺序检测。
|
||||
- `driver: "existing-session"` 使用 Chrome DevTools MCP,而不是原始 CDP。不要为该驱动设置 `cdpUrl`。
|
||||
- 当 existing-session 配置文件需要附加到非默认的 Chromium 用户配置文件(Brave、Edge 等)时,请设置 `browser.profiles.<name>.userDataDir`。
|
||||
|
||||
</Accordion>
|
||||
|
||||
</AccordionGroup>
|
||||
|
||||
## 使用 Brave(或其他基于 Chromium 的浏览器)
|
||||
## 使用 Brave(或其他 Chromium 系浏览器)
|
||||
|
||||
如果你的**系统默认**浏览器是基于 Chromium 的(Chrome/Brave/Edge 等),
|
||||
OpenClaw 会自动使用它。设置 `browser.executablePath` 可以覆盖
|
||||
自动检测。`~` 会展开为你的操作系统主目录:
|
||||
如果你的**系统默认**浏览器是 Chromium 系(Chrome/Brave/Edge 等),
|
||||
OpenClaw 会自动使用它。设置 `browser.executablePath` 可以覆盖自动检测。
|
||||
`~` 会展开为你的操作系统主目录:
|
||||
|
||||
```bash
|
||||
openclaw config set browser.executablePath "/usr/bin/google-chrome"
|
||||
openclaw config set browser.profiles.work.executablePath "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome"
|
||||
```
|
||||
|
||||
或者按平台在配置中设置:
|
||||
@ -246,53 +242,46 @@ openclaw config set browser.executablePath "/usr/bin/google-chrome"
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
每个配置文件级别的 `executablePath` 只会影响由 OpenClaw 启动的本地受管理配置文件。`existing-session` 配置文件则会附加到一个已经运行的浏览器,而远程 CDP 配置文件使用的是 `cdpUrl` 后面的浏览器。
|
||||
|
||||
## 本地控制与远程控制
|
||||
|
||||
- **本地控制(默认):** Gateway 网关会启动 loopback 控制服务,并且可以启动本地浏览器。
|
||||
- **远程控制(节点主机):** 在拥有浏览器的机器上运行节点主机;Gateway 网关会将浏览器操作代理到该节点主机。
|
||||
- **远程 CDP:** 设置 `browser.profiles.<name>.cdpUrl`(或 `browser.cdpUrl`)以
|
||||
附加到远程的基于 Chromium 的浏览器。在这种情况下,OpenClaw 不会启动本地浏览器。
|
||||
- **本地控制(默认):** Gateway 网关启动 loopback 控制服务,并可启动本地浏览器。
|
||||
- **远程控制(节点主机):** 在拥有浏览器的那台机器上运行节点主机;Gateway 网关会将浏览器操作代理过去。
|
||||
- **远程 CDP:** 设置 `browser.profiles.<name>.cdpUrl`(或 `browser.cdpUrl`)以附加到远程 Chromium 系浏览器。在这种情况下,OpenClaw 不会启动本地浏览器。
|
||||
- `headless` 只影响由 OpenClaw 启动的本地受管理配置文件。它不会重启或更改 existing-session 或远程 CDP 浏览器。
|
||||
- `executablePath` 遵循相同的本地受管理配置文件规则。对正在运行的本地受管理配置文件修改它,会将该配置文件标记为需要重启/协调,以便下次启动时使用新的二进制文件。
|
||||
|
||||
停止行为会因配置文件模式而异:
|
||||
停止行为因配置文件模式而异:
|
||||
|
||||
- 本地受管理配置文件:`openclaw browser stop` 会停止
|
||||
由 OpenClaw 启动的浏览器进程
|
||||
- attach-only 和远程 CDP 配置文件:`openclaw browser stop` 会关闭当前活动的
|
||||
控制会话,并释放 Playwright/CDP 仿真覆盖项(视口、
|
||||
配色方案、区域设置、时区、离线模式以及类似状态),即使
|
||||
OpenClaw 并未启动任何浏览器进程
|
||||
- 本地受管理配置文件:`openclaw browser stop` 会停止由 OpenClaw 启动的浏览器进程
|
||||
- 仅附加和远程 CDP 配置文件:`openclaw browser stop` 会关闭当前控制会话,并释放 Playwright/CDP 仿真覆盖项(视口、配色方案、语言区域、时区、离线模式及类似状态),即使 OpenClaw 并未启动任何浏览器进程
|
||||
|
||||
远程 CDP URL 可以包含认证信息:
|
||||
|
||||
- 查询参数 token(例如 `https://provider.example?token=<token>`)
|
||||
- HTTP Basic 认证(例如 `https://user:pass@provider.example`)
|
||||
|
||||
OpenClaw 在调用 `/json/*` 端点以及连接
|
||||
到 CDP WebSocket 时都会保留这些认证信息。对于
|
||||
token,优先使用环境变量或 secrets manager,而不要把它们提交到配置文件中。
|
||||
OpenClaw 在调用 `/json/*` 端点以及连接 CDP WebSocket 时会保留这些认证信息。对于 token,优先使用环境变量或密钥管理器,而不是将它们提交到配置文件中。
|
||||
|
||||
## 节点浏览器代理(默认零配置)
|
||||
|
||||
如果你在拥有浏览器的机器上运行**节点主机**,OpenClaw 可以
|
||||
自动将浏览器工具调用路由到该节点,无需任何额外浏览器配置。
|
||||
如果你在拥有浏览器的那台机器上运行一个**节点主机**,OpenClaw 可以将浏览器工具调用自动路由到该节点,而无需任何额外的浏览器配置。
|
||||
这是远程 Gateway 网关的默认路径。
|
||||
|
||||
注意事项:
|
||||
说明:
|
||||
|
||||
- 节点主机会通过一个**代理命令**暴露其本地浏览器控制服务器。
|
||||
- 配置文件来自节点自身的 `browser.profiles` 配置(与本地相同)。
|
||||
- `nodeHost.browserProxy.allowProfiles` 是可选项。不设置时会保留旧版/默认行为:所有已配置的配置文件都可通过代理访问,包括配置文件创建/删除路由。
|
||||
- 如果你设置了 `nodeHost.browserProxy.allowProfiles`,OpenClaw 会将其视为最小权限边界:只有列入 allowlist 的配置文件可作为目标,且持久化配置文件的创建/删除路由会在代理表面被阻止。
|
||||
- `nodeHost.browserProxy.allowProfiles` 是可选项。留空即可保留旧版/默认行为:所有已配置的配置文件都可通过代理访问,包括配置文件创建/删除路由。
|
||||
- 如果你设置了 `nodeHost.browserProxy.allowProfiles`,OpenClaw 会将其视为最小权限边界:只有允许列表中的配置文件可作为目标,并且持久化配置文件创建/删除路由会在代理界面上被阻止。
|
||||
- 如果你不想启用它,可以禁用:
|
||||
- 在节点上:`nodeHost.browserProxy.enabled=false`
|
||||
- 在 gateway 上:`gateway.nodes.browser.mode="off"`
|
||||
- 在网关上:`gateway.nodes.browser.mode="off"`
|
||||
|
||||
## Browserless(托管远程 CDP)
|
||||
|
||||
[Browserless](https://browserless.io) 是一项托管式 Chromium 服务,可通过 HTTPS 和 WebSocket 暴露
|
||||
CDP 连接 URL。OpenClaw 两种形式都支持,但对于
|
||||
远程浏览器配置文件来说,最简单的选项通常是使用 Browserless 连接文档中提供的直接 WebSocket URL。
|
||||
[Browserless](https://browserless.io) 是一个托管的 Chromium 服务,可通过 HTTPS 和 WebSocket 暴露 CDP 连接 URL。OpenClaw 可以使用这两种形式,不过对于远程浏览器配置文件,最简单的选项是使用 Browserless 连接文档中提供的直接 WebSocket URL。
|
||||
|
||||
示例:
|
||||
|
||||
@ -313,40 +302,26 @@ CDP 连接 URL。OpenClaw 两种形式都支持,但对于
|
||||
}
|
||||
```
|
||||
|
||||
注意事项:
|
||||
说明:
|
||||
|
||||
- 将 `<BROWSERLESS_API_KEY>` 替换为你真实的 Browserless token。
|
||||
- 选择与你的 Browserless 账户对应的区域端点(参见其文档)。
|
||||
- 如果 Browserless 给你的是一个 HTTPS 基础 URL,你既可以将其转换为
|
||||
`wss://` 以进行直接 CDP 连接,也可以保留该 HTTPS URL,并让 OpenClaw
|
||||
去发现 `/json/version`。
|
||||
- 选择与你的 Browserless 账户匹配的区域端点(见其文档)。
|
||||
- 如果 Browserless 给你的是一个 HTTPS 基础 URL,你可以将其转换为 `wss://` 以进行直接 CDP 连接,或者保留该 HTTPS URL,让 OpenClaw 发现 `/json/version`。
|
||||
|
||||
## 直接 WebSocket CDP 提供商
|
||||
|
||||
某些托管浏览器服务暴露的是**直接 WebSocket** 端点,而不是
|
||||
标准的基于 HTTP 的 CDP 发现机制(`/json/version`)。OpenClaw 接受三种
|
||||
CDP URL 形式,并会自动选择正确的连接策略:
|
||||
有些托管浏览器服务暴露的是**直接 WebSocket** 端点,而不是标准的基于 HTTP 的 CDP 发现(`/json/version`)。OpenClaw 接受三种 CDP URL 形式,并会自动选择正确的连接策略:
|
||||
|
||||
- **HTTP(S) 发现** — `http://host[:port]` 或 `https://host[:port]`。
|
||||
OpenClaw 会调用 `/json/version` 来发现 WebSocket 调试器 URL,然后
|
||||
进行连接。不会回退到 WebSocket。
|
||||
- **直接 WebSocket 端点** — `ws://host[:port]/devtools/<kind>/<id>` 或
|
||||
`wss://...`,并带有 `/devtools/browser|page|worker|shared_worker|service_worker/<id>`
|
||||
路径。OpenClaw 会通过 WebSocket 握手直接连接,并跳过
|
||||
`/json/version`。
|
||||
- **裸 WebSocket 根路径** — `ws://host[:port]` 或 `wss://host[:port]`,且不带
|
||||
`/devtools/...` 路径(例如 [Browserless](https://browserless.io)、
|
||||
[Browserbase](https://www.browserbase.com))。OpenClaw 会先尝试 HTTP
|
||||
`/json/version` 发现(将协议规范化为 `http`/`https`);
|
||||
如果发现过程返回 `webSocketDebuggerUrl`,则使用该地址,否则 OpenClaw
|
||||
会回退为在裸根路径上直接执行 WebSocket 握手。这样一来,
|
||||
指向本地 Chrome 的裸 `ws://` 仍然可以连接,因为 Chrome 只会在
|
||||
`/json/version` 返回的特定逐目标路径上接受 WebSocket 升级。
|
||||
- **HTTP(S) 发现** — `http://host[:port]` 或 `https://host[:port]`。
|
||||
OpenClaw 会调用 `/json/version` 来发现 WebSocket 调试器 URL,然后进行连接。不会回退到 WebSocket。
|
||||
- **直接 WebSocket 端点** — `ws://host[:port]/devtools/<kind>/<id>` 或
|
||||
`wss://...`,路径为 `/devtools/browser|page|worker|shared_worker|service_worker/<id>`。
|
||||
OpenClaw 会直接通过 WebSocket 握手连接,并完全跳过 `/json/version`。
|
||||
- **裸 WebSocket 根路径** — `ws://host[:port]` 或 `wss://host[:port]`,且没有 `/devtools/...` 路径(例如 [Browserless](https://browserless.io)、[Browserbase](https://www.browserbase.com))。OpenClaw 会先尝试 HTTP `/json/version` 发现(将协议规范化为 `http`/`https`);如果发现结果返回 `webSocketDebuggerUrl`,则使用它,否则 OpenClaw 会回退为在裸根路径上直接进行 WebSocket 握手。这样,指向本地 Chrome 的裸 `ws://` 也能连接,因为 Chrome 只接受来自 `/json/version` 中特定目标路径的 WebSocket 升级。
|
||||
|
||||
### Browserbase
|
||||
|
||||
[Browserbase](https://www.browserbase.com) 是一个用于运行
|
||||
headless 浏览器的云平台,内置 CAPTCHA 求解、隐身模式和住宅代理。
|
||||
[Browserbase](https://www.browserbase.com) 是一个云平台,用于运行无头浏览器,内置 CAPTCHA 求解、隐身模式和住宅代理。
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -365,32 +340,25 @@ headless 浏览器的云平台,内置 CAPTCHA 求解、隐身模式和住宅
|
||||
}
|
||||
```
|
||||
|
||||
注意事项:
|
||||
说明:
|
||||
|
||||
- [注册](https://www.browserbase.com/sign-up),然后从 [Overview 仪表板](https://www.browserbase.com/overview) 复制你的 **API Key**。
|
||||
- [注册](https://www.browserbase.com/sign-up),并从 [Overview dashboard](https://www.browserbase.com/overview) 复制你的 **API Key**。
|
||||
- 将 `<BROWSERBASE_API_KEY>` 替换为你真实的 Browserbase API key。
|
||||
- Browserbase 会在 WebSocket 连接时自动创建浏览器会话,因此
|
||||
不需要手动创建会话。
|
||||
- 免费层每月允许一个并发会话和一个浏览器小时。
|
||||
付费计划限制请参见 [pricing](https://www.browserbase.com/pricing)。
|
||||
- 完整的 API 参考、SDK 指南和集成示例,请参见 [Browserbase 文档](https://docs.browserbase.com)。
|
||||
- Browserbase 会在 WebSocket 连接时自动创建浏览器会话,因此不需要手动创建会话步骤。
|
||||
- 免费层每月允许一个并发会话和一个浏览器小时。付费方案限制请参见 [pricing](https://www.browserbase.com/pricing)。
|
||||
- 完整的 API 参考、SDK 指南和集成示例请参见 [Browserbase docs](https://docs.browserbase.com)。
|
||||
|
||||
## 安全性
|
||||
|
||||
关键概念:
|
||||
|
||||
- 浏览器控制仅限 loopback;访问通过 Gateway 网关的认证或节点配对进行。
|
||||
- 独立的 loopback 浏览器 HTTP API **仅**使用共享密钥认证:
|
||||
gateway token bearer auth、`x-openclaw-password`,或者带有
|
||||
已配置 gateway 密码的 HTTP Basic auth。
|
||||
- Tailscale Serve 身份头,以及 `gateway.auth.mode: "trusted-proxy"`
|
||||
**不能**用于认证这个独立的 loopback 浏览器 API。
|
||||
- 如果启用了浏览器控制且未配置共享密钥认证,OpenClaw
|
||||
会在启动时自动生成 `gateway.auth.token` 并将其持久化到配置中。
|
||||
- 当 `gateway.auth.mode` 已经是
|
||||
`password`、`none` 或 `trusted-proxy` 时,OpenClaw **不会**自动生成该 token。
|
||||
- 请将 Gateway 网关和任何节点主机保持在私有网络中(Tailscale);避免对公网暴露。
|
||||
- 将远程 CDP URL/token 视为机密;优先使用环境变量或 secrets manager。
|
||||
- 浏览器控制仅限 loopback;访问通过 Gateway 网关认证或节点配对进行。
|
||||
- 独立的 loopback 浏览器 HTTP API **仅使用共享密钥认证**:gateway token bearer 认证、`x-openclaw-password`,或带有已配置网关密码的 HTTP Basic 认证。
|
||||
- Tailscale Serve 身份头,以及 `gateway.auth.mode: "trusted-proxy"`,**不能**为这个独立的 loopback 浏览器 API 提供认证。
|
||||
- 如果启用了浏览器控制且未配置任何共享密钥认证,OpenClaw 会在启动时自动生成 `gateway.auth.token`,并将其持久化到配置中。
|
||||
- 当 `gateway.auth.mode` 已经是 `password`、`none` 或 `trusted-proxy` 时,OpenClaw **不会**自动生成该 token。
|
||||
- 请将 Gateway 网关和任何节点主机保留在私有网络中(Tailscale);避免公开暴露。
|
||||
- 将远程 CDP URL/token 视为敏感信息;优先使用环境变量或密钥管理器。
|
||||
|
||||
远程 CDP 提示:
|
||||
|
||||
@ -401,44 +369,40 @@ headless 浏览器的云平台,内置 CAPTCHA 求解、隐身模式和住宅
|
||||
|
||||
OpenClaw 支持多个命名配置文件(路由配置)。配置文件可以是:
|
||||
|
||||
- **openclaw-managed**:一个专用的基于 Chromium 的浏览器实例,拥有自己的用户数据目录 + CDP 端口
|
||||
- **remote**:显式的 CDP URL(运行在其他位置的基于 Chromium 的浏览器)
|
||||
- **existing session**:通过 Chrome DevTools MCP 自动连接到你现有的 Chrome 配置文件
|
||||
- **openclaw-managed**:一个专用的 Chromium 系浏览器实例,拥有自己的用户数据目录和 CDP 端口
|
||||
- **remote**:一个显式的 CDP URL(运行在其他地方的 Chromium 系浏览器)
|
||||
- **existing session**:通过 Chrome DevTools MCP 自动连接你现有的 Chrome 配置文件
|
||||
|
||||
默认值:
|
||||
|
||||
- 如果缺失,会自动创建 `openclaw` 配置文件。
|
||||
- `user` 配置文件是内置的,用于 Chrome MCP existing-session 附加。
|
||||
- 除 `user` 外,existing-session 配置文件均需主动启用;请使用 `--driver existing-session` 创建它们。
|
||||
- 除 `user` 之外,existing-session 配置文件需要显式启用;请使用 `--driver existing-session` 创建它们。
|
||||
- 本地 CDP 端口默认从 **18800–18899** 分配。
|
||||
- 删除配置文件时,其本地数据目录会被移到废纸篓。
|
||||
- 删除配置文件会将其本地数据目录移到废纸篓。
|
||||
|
||||
所有控制端点都接受 `?profile=<name>`;CLI 使用 `--browser-profile`。
|
||||
|
||||
## 通过 Chrome DevTools MCP 使用 existing-session
|
||||
|
||||
OpenClaw 还可以通过官方 Chrome DevTools MCP 服务器附加到一个正在运行的基于 Chromium 的浏览器配置文件。
|
||||
这样可以复用该浏览器配置文件中
|
||||
已经打开的标签页和登录状态。
|
||||
OpenClaw 也可以通过官方 Chrome DevTools MCP 服务器附加到一个正在运行的 Chromium 系浏览器配置文件。这样可以复用该浏览器配置文件中已经打开的标签页和登录状态。
|
||||
|
||||
官方背景资料和设置参考:
|
||||
官方背景与设置参考:
|
||||
|
||||
- [Chrome for Developers:在你的浏览器会话中使用 Chrome DevTools MCP](https://developer.chrome.com/blog/chrome-devtools-mcp-debug-your-browser-session)
|
||||
- [Chrome for Developers: Use Chrome DevTools MCP with your browser session](https://developer.chrome.com/blog/chrome-devtools-mcp-debug-your-browser-session)
|
||||
- [Chrome DevTools MCP README](https://github.com/ChromeDevTools/chrome-devtools-mcp)
|
||||
|
||||
内置配置文件:
|
||||
|
||||
- `user`
|
||||
|
||||
可选:如果你希望使用不同的
|
||||
名称、颜色或浏览器数据目录,可以创建你自己的自定义 existing-session 配置文件。
|
||||
可选:如果你想使用不同的名称、颜色或浏览器数据目录,可以创建你自己的自定义 existing-session 配置文件。
|
||||
|
||||
默认行为:
|
||||
|
||||
- 内置的 `user` 配置文件使用 Chrome MCP 自动连接,目标为
|
||||
默认的本地 Google Chrome 配置文件。
|
||||
- 内置的 `user` 配置文件使用 Chrome MCP 自动连接,目标是默认的本地 Google Chrome 配置文件。
|
||||
|
||||
对于 Brave、Edge、Chromium 或非默认的 Chrome 配置文件,请使用 `userDataDir`:
|
||||
对于 Brave、Edge、Chromium 或非默认 Chrome 配置文件,请使用 `userDataDir`:
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -459,9 +423,9 @@ OpenClaw 还可以通过官方 Chrome DevTools MCP 服务器附加到一个正
|
||||
|
||||
1. 打开该浏览器用于远程调试的 inspect 页面。
|
||||
2. 启用远程调试。
|
||||
3. 保持浏览器运行,并在 OpenClaw 进行附加时批准连接提示。
|
||||
3. 保持浏览器运行,并在 OpenClaw 附加时批准连接提示。
|
||||
|
||||
常见的 inspect 页面:
|
||||
常见 inspect 页面:
|
||||
|
||||
- Chrome:`chrome://inspect/#remote-debugging`
|
||||
- Brave:`brave://inspect/#remote-debugging`
|
||||
@ -476,61 +440,51 @@ openclaw browser --browser-profile user tabs
|
||||
openclaw browser --browser-profile user snapshot --format ai
|
||||
```
|
||||
|
||||
成功时应表现为:
|
||||
成功时的表现:
|
||||
|
||||
- `status` 显示 `driver: existing-session`
|
||||
- `status` 显示 `transport: chrome-mcp`
|
||||
- `status` 显示 `running: true`
|
||||
- `tabs` 列出你已打开的浏览器标签页
|
||||
- `tabs` 列出你已经打开的浏览器标签页
|
||||
- `snapshot` 返回所选实时标签页中的 refs
|
||||
|
||||
如果附加不起作用,请检查:
|
||||
如果附加失败,请检查:
|
||||
|
||||
- 目标的基于 Chromium 的浏览器版本是否为 `144+`
|
||||
- 是否已在该浏览器的 inspect 页面中启用远程调试
|
||||
- 浏览器是否显示了附加同意提示,且你是否已接受
|
||||
- `openclaw doctor` 会迁移旧的基于扩展的浏览器配置,并检查
|
||||
默认自动连接配置文件所需的 Chrome 是否已在本地安装,但它无法
|
||||
替你启用浏览器端的远程调试
|
||||
- 目标 Chromium 系浏览器版本为 `144+`
|
||||
- 已在该浏览器的 inspect 页面启用远程调试
|
||||
- 浏览器显示了附加同意提示,且你已接受
|
||||
- `openclaw doctor` 会迁移旧的基于扩展的浏览器配置,并检查默认自动连接配置文件所需的 Chrome 是否已在本地安装,但它无法替你启用浏览器端的远程调试
|
||||
|
||||
智能体使用:
|
||||
|
||||
- 当你需要用户已登录的浏览器状态时,请使用 `profile="user"`。
|
||||
- 如果你使用的是自定义 existing-session 配置文件,请传入其显式配置文件名。
|
||||
- 只有在用户位于电脑前、能够批准附加
|
||||
提示时,才选择此模式。
|
||||
- Gateway 网关或节点主机可以生成 `npx chrome-devtools-mcp@latest --autoConnect`
|
||||
- 当你需要用户已登录的浏览器状态时,使用 `profile="user"`。
|
||||
- 如果你使用自定义 existing-session 配置文件,请传入该显式配置文件名称。
|
||||
- 仅当用户在电脑前可以批准附加提示时才选择此模式。
|
||||
- Gateway 网关或节点主机可以启动 `npx chrome-devtools-mcp@latest --autoConnect`
|
||||
|
||||
注意事项:
|
||||
说明:
|
||||
|
||||
- 与隔离的 `openclaw` 配置文件相比,这条路径风险更高,因为它可以
|
||||
在你已登录的浏览器会话中执行操作。
|
||||
- 对于这个 driver,OpenClaw 不会启动浏览器;它只会进行附加。
|
||||
- OpenClaw 在此处使用官方的 Chrome DevTools MCP `--autoConnect` 流程。如果
|
||||
设置了 `userDataDir`,它会被传递下去以定位该用户数据目录。
|
||||
- existing-session 可以附加到所选主机,或通过已连接的
|
||||
浏览器节点进行附加。如果 Chrome 位于其他地方,且没有连接浏览器节点,请改用
|
||||
远程 CDP 或节点主机。
|
||||
- 与隔离的 `openclaw` 配置文件相比,这条路径风险更高,因为它可以在你已登录的浏览器会话中执行操作。
|
||||
- 对于这个驱动,OpenClaw 不会启动浏览器;它只会附加。
|
||||
- OpenClaw 在这里使用官方的 Chrome DevTools MCP `--autoConnect` 流程。如果设置了 `userDataDir`,它会被透传,以定位到该用户数据目录。
|
||||
- existing-session 可以附加到所选主机上,也可以通过已连接的浏览器节点附加。如果 Chrome 位于其他地方且没有连接浏览器节点,请改用远程 CDP 或节点主机。
|
||||
|
||||
<Accordion title="existing-session 功能限制">
|
||||
|
||||
与受管理的 `openclaw` 配置文件相比,existing-session driver 的限制更多:
|
||||
与受管理的 `openclaw` 配置文件相比,existing-session 驱动限制更多:
|
||||
|
||||
- **截图** — 支持页面截图和 `--ref` 元素截图;不支持 CSS `--element` 选择器。`--full-page` 不能与 `--ref` 或 `--element` 组合使用。页面或基于 ref 的元素截图不需要 Playwright。
|
||||
- **操作** — `click`、`type`、`hover`、`scrollIntoView`、`drag` 和 `select` 需要 snapshot refs(不支持 CSS 选择器)。`click` 仅支持左键。`type` 不支持 `slowly=true`;请使用 `fill` 或 `press`。`press` 不支持 `delayMs`。`type`、`hover`、`scrollIntoView`、`drag`、`select`、`fill` 和 `evaluate` 不支持按调用设置超时。`select` 仅接受单个值。
|
||||
- **等待 / 上传 / 对话框** — `wait --url` 支持精确、子串和 glob 模式;不支持 `wait --load networkidle`。上传钩子需要 `ref` 或 `inputRef`,一次仅支持一个文件,不支持 CSS `element`。对话框钩子不支持超时覆盖。
|
||||
- **截图** — 支持页面截图和 `--ref` 元素截图;不支持 CSS `--element` 选择器。`--full-page` 不能与 `--ref` 或 `--element` 组合使用。页面截图或基于 ref 的元素截图不需要 Playwright。
|
||||
- **操作** — `click`、`type`、`hover`、`scrollIntoView`、`drag` 和 `select` 需要使用快照 refs(不支持 CSS 选择器)。`click` 仅支持鼠标左键。`type` 不支持 `slowly=true`;请使用 `fill` 或 `press`。`press` 不支持 `delayMs`。`type`、`hover`、`scrollIntoView`、`drag`、`select`、`fill` 和 `evaluate` 不支持按调用设置超时。`select` 接受单个值。
|
||||
- **等待 / 上传 / 对话框** — `wait --url` 支持精确、子串和 glob 模式;不支持 `wait --load networkidle`。上传钩子需要 `ref` 或 `inputRef`,每次只支持一个文件,不支持 CSS `element`。对话框钩子不支持超时覆盖。
|
||||
- **仅受管理模式支持的功能** — 批量操作、PDF 导出、下载拦截和 `responsebody` 仍然需要受管理浏览器路径。
|
||||
|
||||
</Accordion>
|
||||
|
||||
## 隔离保证
|
||||
|
||||
- **专用用户数据目录**:绝不会触碰你的个人浏览器配置文件。
|
||||
- **专用端口**:避开 `9222`,防止与开发工作流冲突。
|
||||
- **确定性的标签页控制**:`tabs` 会先返回 `suggestedTargetId`,然后是
|
||||
稳定的 `tabId` 句柄,如 `t1`、可选标签,以及原始 `targetId`。
|
||||
智能体应复用 `suggestedTargetId`;原始 id 仍保留用于
|
||||
调试和兼容性。
|
||||
- **专用用户数据目录**:绝不会接触你的个人浏览器配置文件。
|
||||
- **专用端口**:避免使用 `9222`,以防与开发工作流冲突。
|
||||
- **可预测的标签页控制**:`tabs` 会先返回 `suggestedTargetId`,然后是稳定的 `tabId` 句柄(如 `t1`)、可选标签以及原始 `targetId`。智能体应复用 `suggestedTargetId`;原始 id 仍会保留,用于调试和兼容性。
|
||||
|
||||
## 浏览器选择
|
||||
|
||||
@ -542,9 +496,9 @@ openclaw browser --browser-profile user snapshot --format ai
|
||||
4. Chromium
|
||||
5. Chrome Canary
|
||||
|
||||
你可以通过 `browser.executablePath` 进行覆盖。
|
||||
你可以使用 `browser.executablePath` 覆盖它。
|
||||
|
||||
平台:
|
||||
平台说明:
|
||||
|
||||
- macOS:检查 `/Applications` 和 `~/Applications`。
|
||||
- Linux:查找 `google-chrome`、`brave`、`microsoft-edge`、`chromium` 等。
|
||||
@ -552,25 +506,23 @@ openclaw browser --browser-profile user snapshot --format ai
|
||||
|
||||
## 控制 API(可选)
|
||||
|
||||
为了便于脚本编写和调试,Gateway 网关暴露了一个小型的**仅限 loopback 的 HTTP
|
||||
控制 API**,以及与之配套的 `openclaw browser` CLI(快照、refs、wait
|
||||
增强功能、JSON 输出、调试工作流)。完整参考请参见
|
||||
[浏览器控制 API](/zh-CN/tools/browser-control)。
|
||||
为了便于脚本编写和调试,Gateway 网关暴露了一个小型的**仅限 loopback 的 HTTP 控制 API**,以及与之匹配的 `openclaw browser` CLI(快照、refs、wait 增强功能、JSON 输出、调试工作流)。完整参考请参见
|
||||
[Browser control API](/zh-CN/tools/browser-control)。
|
||||
|
||||
## 故障排除
|
||||
|
||||
对于 Linux 特定问题(尤其是 snap Chromium),请参见
|
||||
[浏览器故障排除](/zh-CN/tools/browser-linux-troubleshooting)。
|
||||
|
||||
对于 WSL2 Gateway 网关 + Windows Chrome 分离主机部署,请参见
|
||||
对于 WSL2 Gateway 网关 + Windows Chrome 分离主机设置,请参见
|
||||
[WSL2 + Windows + 远程 Chrome CDP 故障排除](/zh-CN/tools/browser-wsl2-windows-remote-cdp-troubleshooting)。
|
||||
|
||||
### CDP 启动失败 vs 导航 SSRF 阻止
|
||||
### CDP 启动失败与导航 SSRF 阻止
|
||||
|
||||
这两者是不同的故障类别,分别指向不同的代码路径。
|
||||
这是两种不同的故障类型,对应不同的代码路径。
|
||||
|
||||
- **CDP 启动或就绪失败** 表示 OpenClaw 无法确认浏览器控制平面处于健康状态。
|
||||
- **导航 SSRF 阻止** 表示浏览器控制平面是健康的,但页面导航目标被策略拒绝。
|
||||
- **导航 SSRF 阻止** 表示浏览器控制平面是健康的,但某个页面导航目标被策略拒绝。
|
||||
|
||||
常见示例:
|
||||
|
||||
@ -578,9 +530,9 @@ openclaw browser --browser-profile user snapshot --format ai
|
||||
- `Chrome CDP websocket for profile "openclaw" is not reachable after start`
|
||||
- `Remote CDP for profile "<name>" is not reachable at <cdpUrl>`
|
||||
- 导航 SSRF 阻止:
|
||||
- 当 `start` 和 `tabs` 仍然可用时,`open`、`navigate`、snapshot 或打开标签页相关流程会因浏览器/网络策略错误而失败
|
||||
- 当 `start` 和 `tabs` 仍然可用时,`open`、`navigate`、snapshot 或打开标签页流程因浏览器/网络策略错误而失败
|
||||
|
||||
使用下面这个最小化序列来区分这两类问题:
|
||||
使用以下最小序列来区分这两种情况:
|
||||
|
||||
```bash
|
||||
openclaw browser --browser-profile openclaw start
|
||||
@ -588,48 +540,48 @@ openclaw browser --browser-profile openclaw tabs
|
||||
openclaw browser --browser-profile openclaw open https://example.com
|
||||
```
|
||||
|
||||
结果解读方式:
|
||||
如何理解结果:
|
||||
|
||||
- 如果 `start` 失败,并显示 `not reachable after start`,请先排查 CDP 就绪问题。
|
||||
- 如果 `start` 成功,但 `tabs` 失败,则控制平面仍然不健康。应将其视为 CDP 可达性问题,而不是页面导航问题。
|
||||
- 如果 `start` 和 `tabs` 成功,但 `open` 或 `navigate` 失败,则说明浏览器控制平面已启动,故障出在导航策略或目标页面上。
|
||||
- 如果 `start`、`tabs` 和 `open` 都成功,则基本的受管理浏览器控制路径是健康的。
|
||||
- 如果 `start` 失败并显示 `not reachable after start`,请先排查 CDP 就绪状态。
|
||||
- 如果 `start` 成功但 `tabs` 失败,说明控制平面仍然不健康。应将其视为 CDP 可达性问题,而不是页面导航问题。
|
||||
- 如果 `start` 和 `tabs` 成功,但 `open` 或 `navigate` 失败,说明浏览器控制平面已经就绪,故障出在导航策略或目标页面。
|
||||
- 如果 `start`、`tabs` 和 `open` 都成功,说明基础的受管理浏览器控制路径是健康的。
|
||||
|
||||
重要行为细节:
|
||||
|
||||
- 即使你没有配置 `browser.ssrfPolicy`,浏览器配置默认也会使用故障关闭的 SSRF 策略对象。
|
||||
- 对于本地 loopback 的受管理 `openclaw` 配置文件,CDP 健康检查会有意跳过针对 OpenClaw 自身本地控制平面的浏览器 SSRF 可达性强制检查。
|
||||
- 导航保护是独立的。`start` 或 `tabs` 成功,并不意味着后续的 `open` 或 `navigate` 目标就一定被允许。
|
||||
- 即使你没有配置 `browser.ssrfPolicy`,浏览器配置默认也会使用一个失败即关闭的 SSRF 策略对象。
|
||||
- 对于本地 loopback `openclaw` 受管理配置文件,CDP 健康检查会有意跳过对 OpenClaw 自身本地控制平面的浏览器 SSRF 可达性强制检查。
|
||||
- 导航保护是独立的。`start` 或 `tabs` 成功,并不意味着之后的 `open` 或 `navigate` 目标一定被允许。
|
||||
|
||||
安全指引:
|
||||
安全建议:
|
||||
|
||||
- **不要**默认放宽浏览器 SSRF 策略。
|
||||
- 优先使用范围更窄的主机例外,例如 `hostnameAllowlist` 或 `allowedHostnames`,而不是宽泛的私有网络访问。
|
||||
- 仅在经过审查且明确受信任、确实需要访问私有网络浏览器的环境中,才使用 `dangerouslyAllowPrivateNetwork: true`。
|
||||
- 默认情况下**不要**放宽浏览器 SSRF 策略。
|
||||
- 优先使用精确的主机例外,例如 `hostnameAllowlist` 或 `allowedHostnames`,而不是宽泛地开放私有网络访问。
|
||||
- 仅在明确受信任、确实需要且已审核私有网络浏览器访问的环境中,才使用 `dangerouslyAllowPrivateNetwork: true`。
|
||||
|
||||
## 智能体工具 + 控制工作方式
|
||||
## 智能体工具 + 控制方式
|
||||
|
||||
智能体会获得**一个工具**用于浏览器自动化:
|
||||
智能体获得**一个工具**用于浏览器自动化:
|
||||
|
||||
- `browser` — doctor/status/start/stop/tabs/open/focus/close/snapshot/screenshot/navigate/act
|
||||
|
||||
它的映射方式如下:
|
||||
映射关系如下:
|
||||
|
||||
- `browser snapshot` 返回稳定的 UI 树(AI 或 ARIA)。
|
||||
- `browser act` 使用 snapshot 的 `ref` ID 来执行 click/type/drag/select。
|
||||
- `browser act` 使用 snapshot 的 `ref` ID 来执行点击/输入/拖动/选择。
|
||||
- `browser screenshot` 捕获像素内容(整页、元素或带标签的 refs)。
|
||||
- `browser doctor` 检查 Gateway 网关、插件、配置文件、浏览器和标签页就绪状态。
|
||||
- `browser` 接受:
|
||||
- `profile`,用于选择命名浏览器配置文件(openclaw、chrome 或远程 CDP)。
|
||||
- `target`(`sandbox` | `host` | `node`),用于选择浏览器所在位置。
|
||||
- `browser doctor` 检查 Gateway 网关、插件、配置文件、浏览器和标签页的就绪状态。
|
||||
- `browser` 支持:
|
||||
- `profile` 用于选择命名浏览器配置文件(openclaw、chrome 或远程 CDP)。
|
||||
- `target`(`sandbox` | `host` | `node`)用于选择浏览器所在位置。
|
||||
- 在沙箱隔离会话中,`target: "host"` 需要 `agents.defaults.sandbox.browser.allowHostControl=true`。
|
||||
- 如果省略 `target`:沙箱隔离会话默认使用 `sandbox`,非沙箱隔离会话默认使用 `host`。
|
||||
- 如果已连接具备浏览器能力的节点,工具可能会自动路由到该节点,除非你固定指定 `target="host"` 或 `target="node"`。
|
||||
- 如果省略 `target`:沙箱隔离会话默认使用 `sandbox`,非沙箱会话默认使用 `host`。
|
||||
- 如果已连接支持浏览器的节点,工具可能会自动路由到它,除非你固定指定 `target="host"` 或 `target="node"`。
|
||||
|
||||
这样可以让智能体保持确定性,并避免脆弱的选择器。
|
||||
这样可以让智能体行为保持确定性,并避免脆弱的选择器。
|
||||
|
||||
## 相关内容
|
||||
|
||||
- [工具概览](/zh-CN/tools) —— 所有可用的智能体工具
|
||||
- [沙箱隔离](/zh-CN/gateway/sandboxing) —— 沙箱隔离环境中的浏览器控制
|
||||
- [安全性](/zh-CN/gateway/security) —— 浏览器控制的风险与加固
|
||||
- [工具概览](/zh-CN/tools) — 所有可用的智能体工具
|
||||
- [沙箱隔离](/zh-CN/gateway/sandboxing) — 沙箱隔离环境中的浏览器控制
|
||||
- [安全性](/zh-CN/gateway/security) — 浏览器控制的风险与加固
|
||||
|
||||
Loading…
Reference in New Issue
Block a user