From a344388b2af8488c657cec90fd06fe5663181fc4 Mon Sep 17 00:00:00 2001 From: "openclaw-docs-i18n[bot]" Date: Mon, 6 Apr 2026 12:48:32 +0000 Subject: [PATCH] chore(i18n): refresh zh-CN translations --- docs/zh-CN/concepts/context.md | 103 +- docs/zh-CN/concepts/model-providers.md | 467 +++-- docs/zh-CN/gateway/cli-backends.md | 289 +++ docs/zh-CN/gateway/configuration-reference.md | 1011 +++++----- docs/zh-CN/gateway/doctor.md | 333 ++-- docs/zh-CN/help/faq.md | 1775 ++++++++--------- docs/zh-CN/help/testing.md | 575 +++--- docs/zh-CN/plugins/architecture.md | 1066 +++++----- docs/zh-CN/plugins/building-plugins.md | 115 +- docs/zh-CN/plugins/manifest.md | 340 ++-- docs/zh-CN/plugins/sdk-overview.md | 530 ++--- docs/zh-CN/plugins/sdk-provider-plugins.md | 341 ++-- docs/zh-CN/providers/anthropic.md | 173 +- docs/zh-CN/providers/google.md | 105 +- docs/zh-CN/providers/models.md | 25 +- .../session-management-compaction.md | 242 ++- docs/zh-CN/tools/acp-agents.md | 468 ++--- 17 files changed, 4272 insertions(+), 3686 deletions(-) create mode 100644 docs/zh-CN/gateway/cli-backends.md diff --git a/docs/zh-CN/concepts/context.md b/docs/zh-CN/concepts/context.md index 482a82fa3..d80aab8a1 100644 --- a/docs/zh-CN/concepts/context.md +++ b/docs/zh-CN/concepts/context.md @@ -1,44 +1,44 @@ --- read_when: - - 你想了解 OpenClaw 中“上下文”的含义 - - 你正在调试为什么模型“知道”某些内容(或忘记了它) + - 你想了解在 OpenClaw 中“上下文”是什么意思 + - 你在调试为什么模型“知道”某件事(或忘记了它) - 你想减少上下文开销(`/context`、`/status`、`/compact`) -summary: 上下文:模型会看到什么、它是如何构建的,以及如何检查它 +summary: 上下文:模型看到了什么、它是如何构建的,以及如何检查它 title: 上下文 x-i18n: - generated_at: "2026-04-05T18:13:28Z" + generated_at: "2026-04-06T12:42:44Z" model: gpt-5.4 provider: openai - source_hash: fe7dfe52cb1a64df229c8622feed1804df6c483a6243e0d2f309f6ff5c9fe521 + source_hash: a75b4cd65bf6385d46265b9ce1643310bc99d220e35ec4b4924096bed3ca4aa0 source_path: concepts/context.md workflow: 15 --- # 上下文 -“上下文”是 **OpenClaw 在一次运行中发送给模型的全部内容**。它受限于模型的 **上下文窗口**(token 限制)。 +“上下文”是 **OpenClaw 在一次运行中发送给模型的全部内容**。它受模型的 **上下文窗口**(token 限制)约束。 适合初学者的理解方式: - **系统提示词**(由 OpenClaw 构建):规则、工具、Skills 列表、时间/运行时信息,以及注入的工作区文件。 -- **对话历史**:你在此会话中的消息,以及助手的消息。 -- **工具调用/结果 + 附件**:命令输出、文件读取、图片/音频等。 +- **对话历史**:你在此会话中的消息 + 助手的消息。 +- **工具调用/结果 + 附件**:命令输出、文件读取、图像/音频等。 上下文 _并不等同于_ “记忆”:记忆可以存储在磁盘上并在之后重新加载;上下文则是模型当前窗口中的内容。 ## 快速开始(检查上下文) -- `/status` → 快速查看“我的窗口用了多少?”以及会话设置。 +- `/status` → 快速查看“你的窗口用了多少?”以及会话设置。 - `/context list` → 查看注入了什么 + 粗略大小(每个文件 + 总计)。 -- `/context detail` → 更深入的细分:每个文件、每个工具 schema 的大小、每个 skill 条目的大小,以及系统提示词大小。 -- `/usage tokens` → 在普通回复后附加每次回复的用量页脚。 +- `/context detail` → 更深入的明细:每个文件、每个工具 schema 大小、每个 skill 条目大小,以及系统提示词大小。 +- `/usage tokens` → 在普通回复后附加每条回复的用量页脚。 - `/compact` → 将较早的历史总结为一条紧凑条目,以释放窗口空间。 -另见:[Slash commands](/zh-CN/tools/slash-commands)、[Token 用量与成本](/zh-CN/reference/token-use)、[压缩](/zh-CN/concepts/compaction)。 +另请参阅:[Slash 命令](/zh-CN/tools/slash-commands)、[Token 使用与成本](/zh-CN/reference/token-use)、[压缩](/zh-CN/concepts/compaction)。 ## 示例输出 -具体数值会因模型、提供商、工具策略以及你的工作区内容而异。 +具体值会因模型、提供商、工具策略以及你的工作区内容而异。 ### `/context list` @@ -90,22 +90,22 @@ Top tools (schema size): - 系统提示词(所有部分)。 - 对话历史。 - 工具调用 + 工具结果。 -- 附件/转录内容(图片/音频/文件)。 +- 附件/转录内容(图像/音频/文件)。 - 压缩摘要和裁剪产物。 -- 提供商“包装层”或隐藏头信息(不可见,但仍会计入)。 +- 提供商“包装层”或隐藏标头(不可见,但仍会计入)。 ## OpenClaw 如何构建系统提示词 -系统提示词由 **OpenClaw 持有**,并会在每次运行时重新构建。它包括: +系统提示词由 **OpenClaw 拥有**,并会在每次运行时重新构建。它包括: -- 工具列表 + 简短描述。 +- 工具列表 + 简短说明。 - Skills 列表(仅元数据;见下文)。 - 工作区位置。 -- 时间(UTC + 如果已配置则包含转换后的用户时区时间)。 +- 时间(UTC + 如果已配置则转换后的用户时间)。 - 运行时元数据(主机/OS/模型/思考设置)。 -- 在 **Project Context** 下注入的工作区引导文件。 +- **Project Context** 下已注入的工作区引导文件。 -完整细分请参见:[System Prompt](/zh-CN/concepts/system-prompt)。 +完整明细参见:[系统提示词](/zh-CN/concepts/system-prompt)。 ## 注入的工作区文件(Project Context) @@ -119,68 +119,67 @@ Top tools (schema size): - `HEARTBEAT.md` - `BOOTSTRAP.md`(仅首次运行) -大型文件会按文件依据 `agents.defaults.bootstrapMaxChars`(默认 `20000` 个字符)进行截断。OpenClaw 还会通过 `agents.defaults.bootstrapTotalMaxChars`(默认 `150000` 个字符)对所有文件的总引导注入量施加上限。`/context` 会显示 **原始大小 vs 注入后大小**,以及是否发生了截断。 +大文件会按文件使用 `agents.defaults.bootstrapMaxChars`(默认 `20000` 个字符)进行截断。OpenClaw 还会通过 `agents.defaults.bootstrapTotalMaxChars`(默认 `150000` 个字符)对所有文件的总引导注入量设置上限。`/context` 会显示 **原始大小与注入后大小**,以及是否发生了截断。 发生截断时,运行时可以在 Project Context 下方注入一个提示词内警告块。可通过 `agents.defaults.bootstrapPromptTruncationWarning` 进行配置(`off`、`once`、`always`;默认 `once`)。 -## Skills:默认注入与按需加载 +## Skills:默认注入 vs 按需加载 -系统提示词中包含一个紧凑的 **skills 列表**(名称 + 描述 + 位置)。这个列表会带来真实的上下文开销。 +系统提示词包含一个精简的 **Skills 列表**(名称 + 描述 + 位置)。这个列表确实会带来开销。 -Skill 指令默认 _不会_ 被包含进去。模型应当只在需要时才 `read` 该 skill 的 `SKILL.md`。 +Skill 指令默认 _不会_ 被包含。模型应仅在需要时通过 `read` 读取该 skill 的 `SKILL.md`。 ## 工具:有两种成本 工具会通过两种方式影响上下文: -1. 系统提示词中的 **工具列表文本**(也就是你看到的 “Tooling”)。 -2. **工具 schemas**(JSON)。这些会发送给模型,以便它调用工具。即使你看不到它们的纯文本形式,它们也会计入上下文。 +1. 系统提示词中的 **工具列表文本**(你看到的 “Tooling”)。 +2. **工具 schema**(JSON)。这些内容会发送给模型,以便它调用工具。即使你看不到它们的纯文本形式,它们仍然会计入上下文。 -`/context detail` 会拆分出最大的工具 schema,让你看清哪些部分占比最高。 +`/context detail` 会拆解最大的工具 schema,以便你查看主要开销来源。 -## 命令、指令和“行内快捷方式” +## 命令、指令和“内联快捷方式” -Slash commands 由 Gateway 网关处理。这里有几种不同的行为: +Slash 命令由 Gateway 网关 处理。这里有几种不同的行为: -- **独立命令**:一条只包含 `/...` 的消息会作为命令运行。 -- **指令**:`/think`、`/verbose`、`/reasoning`、`/elevated`、`/model`、`/queue` 会在消息被模型看到之前被剥离。 +- **独立命令**:如果一条消息只有 `/...`,它会作为命令执行。 +- **指令**:`/think`、`/verbose`、`/reasoning`、`/elevated`、`/model`、`/queue` 会在模型看到消息之前被剥离。 - 仅包含指令的消息会持久化会话设置。 - - 普通消息中的行内指令会作为单条消息级别的提示。 -- **行内快捷方式**(仅限于白名单发送者):普通消息中的某些 `/...` token 可以立即运行(例如:“hey /status”),并会在模型看到剩余文本之前被剥离。 + - 普通消息中的内联指令会作为单条消息级别的提示。 +- **内联快捷方式**(仅限 allowlist 发送者):普通消息中的某些 `/...` token 可以立即执行(例如:“hey /status”),并会在模型看到剩余文本之前被剥离。 -详情请参见:[Slash commands](/zh-CN/tools/slash-commands)。 +详情参见:[Slash 命令](/zh-CN/tools/slash-commands)。 ## 会话、压缩和裁剪(哪些内容会持久化) -跨消息持久化哪些内容,取决于所使用的机制: +跨消息持久化哪些内容,取决于具体机制: -- **普通历史** 会保留在会话转录中,直到根据策略被压缩/裁剪。 -- **压缩** 会将摘要持久化到转录中,并保留最近的消息不变。 +- **普通历史** 会持久保留在会话转录中,直到被策略压缩/裁剪。 +- **压缩** 会将摘要持久写入转录,并保留最近的消息不变。 - **裁剪** 会从某次运行的 _内存中_ 提示词里移除旧的工具结果,但不会重写转录。 -文档:[Session](/zh-CN/concepts/session)、[压缩](/zh-CN/concepts/compaction)、[会话裁剪](/zh-CN/concepts/session-pruning)。 +文档参见:[会话](/zh-CN/concepts/session)、[压缩](/zh-CN/concepts/compaction)、[会话裁剪](/zh-CN/concepts/session-pruning)。 -默认情况下,OpenClaw 使用内置的 `legacy` 上下文引擎进行组装和 +默认情况下,OpenClaw 使用内置的 `legacy` 上下文引擎来进行组装和 压缩。如果你安装了一个提供 `kind: "context-engine"` 的插件,并通过 -`plugins.slots.contextEngine` 选择它,OpenClaw 就会将上下文组装、 -`/compact` 以及相关的子智能体上下文生命周期钩子委托给该 -引擎处理。`ownsCompaction: false` 不会自动回退到 legacy -引擎;当前激活的引擎仍必须正确实现 `compact()`。完整的 -可插拔接口、生命周期钩子和配置请参见 +`plugins.slots.contextEngine` 选择它,OpenClaw 就会将上下文组装、`/compact` +以及相关的子智能体上下文生命周期钩子委托给该引擎。`ownsCompaction: false` +不会自动回退到 legacy 引擎;活动引擎仍必须正确实现 `compact()`。完整的 +可插拔接口、生命周期钩子和配置参见 [Context Engine](/zh-CN/concepts/context-engine)。 ## `/context` 实际报告的是什么 -在可用时,`/context` 会优先使用最新的 **按运行构建** 的系统提示词报告: +`/context` 在可用时会优先使用最新的 **按运行构建** 的系统提示词报告: -- `System prompt (run)` = 从最近一次嵌入式(支持工具)运行中捕获,并持久化到会话存储中的数据。 -- `System prompt (estimate)` = 当还没有运行报告时,动态计算得出的估算值。 +- `System prompt (run)` = 从上一次嵌入式(支持工具)运行中捕获,并持久保存到会话存储中。 +- `System prompt (estimate)` = 当不存在运行报告时即时计算(或在使用不会生成该报告的 CLI 后端运行时计算)。 -无论哪种方式,它报告的都是大小和主要贡献项;它**不会**输出完整的系统提示词或工具 schema。 +无论哪种方式,它报告的都是大小和主要贡献项;它 **不会** 转储完整的系统提示词或工具 schema。 ## 相关内容 -- [Context Engine](/zh-CN/concepts/context-engine) —— 通过插件实现自定义上下文注入 -- [压缩](/zh-CN/concepts/compaction) —— 对长对话进行总结 -- [System Prompt](/zh-CN/concepts/system-prompt) —— 系统提示词是如何构建的 -- [Agent Loop](/zh-CN/concepts/agent-loop) —— 完整的智能体执行周期 +- [Context Engine](/zh-CN/concepts/context-engine) — 通过插件进行自定义上下文注入 +- [压缩](/zh-CN/concepts/compaction) — 总结长对话 +- [系统提示词](/zh-CN/concepts/system-prompt) — 系统提示词的构建方式 +- [智能体循环](/zh-CN/concepts/agent-loop) — 完整的智能体执行周期 diff --git a/docs/zh-CN/concepts/model-providers.md b/docs/zh-CN/concepts/model-providers.md index b133d3cf7..84c4c5e90 100644 --- a/docs/zh-CN/concepts/model-providers.md +++ b/docs/zh-CN/concepts/model-providers.md @@ -2,31 +2,38 @@ read_when: - 你需要按提供商划分的模型设置参考 - 你想查看模型提供商的示例配置或 CLI 新手引导命令 -summary: 模型提供商概览,含示例配置和 CLI 流程 +summary: 模型提供商概览,包含示例配置和 CLI 流程 title: 模型提供商 x-i18n: - generated_at: "2026-04-05T23:53:49Z" + generated_at: "2026-04-06T12:44:06Z" model: gpt-5.4 provider: openai - source_hash: 15e4b82e07221018a723279d309e245bb4023bc06e64b3c910ef2cae3dfa2599 + source_hash: ec33cbfeec86c3f79ea0ec38932eebb819eba5932024b73fcf3acbc41fbce203 source_path: concepts/model-providers.md workflow: 15 --- # 模型提供商 -本页介绍的是 **LLM/模型提供商**(而不是像 WhatsApp/Telegram 这样的聊天渠道)。 +本页介绍 **LLM/模型提供商**(不是像 WhatsApp/Telegram 这样的聊天渠道)。 关于模型选择规则,请参见 [/concepts/models](/zh-CN/concepts/models)。 ## 快速规则 -- 模型引用使用 `provider/model` 格式(例如:`opencode/claude-opus-4-6`)。 +- 模型引用使用 `provider/model`(例如:`opencode/claude-opus-4-6`)。 - 如果你设置了 `agents.defaults.models`,它就会成为允许列表。 - CLI 辅助命令:`openclaw onboard`、`openclaw models list`、`openclaw models set `。 -- 运行时回退规则、冷却探测和会话覆盖持久化记录在 [/concepts/model-failover](/zh-CN/concepts/model-failover) 中。 -- `models.providers.*.models[].contextWindow` 是原生模型元数据;`models.providers.*.models[].contextTokens` 是实际运行时上限。 -- 提供商插件可以通过 `registerProvider({ catalog })` 注入模型目录;OpenClaw 会在写入 `models.json` 之前将该输出合并到 `models.providers` 中。 -- 提供商清单可以声明 `providerAuthEnvVars`,这样通用的基于环境变量的凭证探测就不需要加载插件运行时。剩余的核心环境变量映射现在仅用于非插件/核心提供商,以及少数通用优先级场景,例如 Anthropic 的“API 密钥优先”新手引导。 +- 回退运行时规则、冷却探测和会话覆盖持久化 + 记录于 [/concepts/model-failover](/zh-CN/concepts/model-failover)。 +- `models.providers.*.models[].contextWindow` 是原生模型元数据; + `models.providers.*.models[].contextTokens` 是实际运行时上限。 +- 提供商插件可以通过 `registerProvider({ catalog })` 注入模型目录; + OpenClaw 会在写入 + `models.json` 之前将该输出合并到 `models.providers` 中。 +- 提供商清单可以声明 `providerAuthEnvVars`,这样通用的基于环境变量的 + 凭证探测就不需要加载插件运行时。剩余的核心环境变量 + 映射现在只用于非插件/核心提供商以及少数通用优先级 + 场景,例如 Anthropic 以 API 密钥优先的新手引导。 - 提供商插件还可以通过以下方式拥有提供商运行时行为: `normalizeModelId`、`normalizeTransport`、`normalizeConfig`、 `applyNativeStreamingUsageCompat`、`resolveConfigApiKey`、 @@ -45,109 +52,194 @@ x-i18n: `resolveDefaultThinkingLevel`、`applyConfigDefaults`、`isModernModelRef`、 `prepareRuntimeAuth`、`resolveUsageAuth`、`fetchUsageSnapshot`,以及 `onModelSelected`。 -- 注意:提供商运行时 `capabilities` 是共享执行器元数据(提供商家族、转录/工具特性、传输/缓存提示)。它不同于[公开能力模型](/zh-CN/plugins/architecture#public-capability-model),后者描述的是插件注册了什么(文本推理、语音等)。 +- 注意:提供商运行时 `capabilities` 是共享运行器元数据(提供商 + 家族、转录/工具怪癖、传输/缓存提示)。它不同于 + [公开能力模型](/zh-CN/plugins/architecture#public-capability-model), + 后者描述的是插件注册了什么能力(文本推理、语音等)。 ## 插件拥有的提供商行为 -提供商插件现在可以拥有大多数提供商专属逻辑,而 OpenClaw 保留通用推理循环。 +提供商插件现在可以拥有大多数提供商特定逻辑,而 OpenClaw 保持 +通用推理循环。 -典型拆分如下: +典型划分: -- `auth[].run` / `auth[].runNonInteractive`:提供商拥有 `openclaw onboard`、`openclaw models auth` 和无头设置的 onboarding/登录流程 -- `wizard.setup` / `wizard.modelPicker`:提供商拥有凭证选择标签、旧别名、onboarding 允许列表提示,以及新手引导/模型选择器中的设置项 -- `catalog`:提供商出现在 `models.providers` 中 -- `normalizeModelId`:提供商在查找或规范化之前规范旧版/预览模型 ID -- `normalizeTransport`:提供商在通用模型组装前规范传输家族 `api` / `baseUrl`;OpenClaw 会先检查匹配的提供商,然后再检查其他具备该钩子能力的提供商插件,直到某个插件实际修改了传输配置 -- `normalizeConfig`:提供商在运行时使用前规范 `models.providers.` 配置;OpenClaw 会先检查匹配的提供商,然后再检查其他具备该钩子能力的提供商插件,直到某个插件实际修改了配置。如果没有任何提供商钩子重写配置,内置的 Google 家族辅助逻辑仍会规范受支持的 Google 提供商条目。 -- `applyNativeStreamingUsageCompat`:提供商对配置提供商应用由端点驱动的原生流式用量兼容性重写 -- `resolveConfigApiKey`:提供商为配置提供商解析环境变量标记凭证,而无需强制加载完整运行时凭证。即使 Bedrock 运行时凭证使用 AWS SDK 默认链,`amazon-bedrock` 这里也有内置的 AWS 环境变量标记解析器。 -- `resolveSyntheticAuth`:提供商可以在不持久化明文密钥的情况下,暴露本地/自托管或其他基于配置的凭证可用性 -- `shouldDeferSyntheticProfileAuth`:提供商可以将已存储的合成配置档占位符标记为低于环境变量/配置凭证的优先级 -- `resolveDynamicModel`:提供商接受尚未出现在本地静态目录中的模型 ID -- `prepareDynamicModel`:提供商在重试动态解析前需要刷新元数据 -- `normalizeResolvedModel`:提供商需要进行传输或 base URL 重写 -- `contributeResolvedModelCompat`:提供商即使在其厂商模型通过另一个兼容传输到达时,也能提供兼容性标记 -- `capabilities`:提供商发布转录/工具/提供商家族特性 -- `normalizeToolSchemas`:提供商在嵌入式执行器看到工具模式之前对其进行清理 -- `inspectToolSchemas`:提供商在规范化后暴露特定于传输的模式警告 -- `resolveReasoningOutputMode`:提供商选择原生或带标签的推理输出契约 -- `prepareExtraParams`:提供商为每个模型请求参数设置默认值或进行规范化 -- `createStreamFn`:提供商用完全自定义的传输替换正常流路径 -- `wrapStreamFn`:提供商应用请求头/请求体/模型兼容性包装器 -- `resolveTransportTurnState`:提供商提供每轮原生传输头或元数据 -- `resolveWebSocketSessionPolicy`:提供商提供原生 WebSocket 会话头或会话冷却策略 -- `createEmbeddingProvider`:当内存嵌入行为更适合放在提供商插件而不是核心嵌入切换层中时,由提供商拥有该行为 -- `formatApiKey`:提供商将已存储的凭证配置档格式化为传输所需的运行时 `apiKey` 字符串 -- `refreshOAuth`:当共享的 `pi-ai` 刷新器不足时,由提供商拥有 OAuth 刷新逻辑 -- `buildAuthDoctorHint`:当 OAuth 刷新失败时,提供商附加修复指导 -- `matchesContextOverflowError`:提供商识别通用启发式可能漏掉的提供商专属上下文窗口溢出错误 -- `classifyFailoverReason`:提供商将提供商专属的原始传输/API 错误映射为回退原因,例如限流或过载 -- `isCacheTtlEligible`:提供商决定哪些上游模型 ID 支持提示缓存 TTL -- `buildMissingAuthMessage`:提供商用提供商专属恢复提示替换通用凭证存储错误 -- `suppressBuiltInModel`:提供商隐藏陈旧的上游条目,并且可以在直接解析失败时返回厂商拥有的错误 -- `augmentModelCatalog`:提供商在发现和配置合并后附加合成/最终目录条目 -- `isBinaryThinking`:提供商拥有二元开/关 thinking 体验 -- `supportsXHighThinking`:提供商允许所选模型启用 `xhigh` -- `resolveDefaultThinkingLevel`:提供商拥有某个模型家族的默认 `/think` 策略 -- `applyConfigDefaults`:提供商在配置实体化过程中,根据凭证模式、环境变量或模型家族应用提供商专属全局默认值 -- `isModernModelRef`:提供商拥有 live/smoke 首选模型匹配 -- `prepareRuntimeAuth`:提供商将已配置凭证转换为短期有效的运行时令牌 -- `resolveUsageAuth`:提供商为 `/usage` 及相关状态/报告界面解析用量/配额凭证 -- `fetchUsageSnapshot`:提供商拥有用量端点的获取/解析逻辑,而核心仍拥有摘要外壳和格式化 -- `onModelSelected`:提供商在模型被选中后运行副作用,例如遥测或提供商拥有的会话记账 +- `auth[].run` / `auth[].runNonInteractive`:提供商拥有 `openclaw onboard`、`openclaw models auth` 和无头设置的 + 新手引导/登录流程 +- `wizard.setup` / `wizard.modelPicker`:提供商拥有凭证选择标签、 + 旧别名、新手引导允许列表提示,以及新手引导/模型选择器中的设置条目 +- `catalog`:提供商会出现在 `models.providers` 中 +- `normalizeModelId`:提供商在查找或规范化之前 + 归一化旧版/预览模型 id +- `normalizeTransport`:提供商会在通用模型组装之前归一化传输族的 `api` / `baseUrl`; + OpenClaw 会先检查匹配的提供商, + 然后检查其他具备 hook 能力的提供商插件,直到其中一个 + 实际修改了传输 +- `normalizeConfig`:提供商会在运行时使用前归一化 `models.providers.` 配置; + OpenClaw 会先检查匹配的提供商, + 然后检查其他具备 hook 能力的提供商插件,直到其中一个 + 实际修改了配置。如果没有 + 提供商 hook 重写配置,内置的 Google 家族辅助逻辑仍会 + 归一化受支持的 Google 提供商条目。 +- `applyNativeStreamingUsageCompat`:提供商为配置型提供商应用由端点驱动的原生流式使用量兼容性重写 +- `resolveConfigApiKey`:提供商为配置型提供商解析环境变量标记凭证, + 无需强制加载完整运行时凭证。`amazon-bedrock` 在这里也有一个 + 内置的 AWS 环境变量标记解析器,尽管 Bedrock 运行时凭证使用的是 + AWS SDK 默认链。 +- `resolveSyntheticAuth`:提供商可以暴露本地/自托管或其他 + 基于配置的凭证可用性,而不持久化明文密钥 +- `shouldDeferSyntheticProfileAuth`:提供商可以将已存储的合成配置档占位符 + 标记为低于环境变量/配置型凭证的优先级 +- `resolveDynamicModel`:提供商接受本地 + 静态目录中尚未存在的模型 id +- `prepareDynamicModel`:提供商在重试动态解析之前 + 需要刷新元数据 +- `normalizeResolvedModel`:提供商需要传输或 base URL 重写 +- `contributeResolvedModelCompat`:即使其 + 厂商模型是通过另一种兼容传输到达的,提供商也会为其贡献兼容标志 +- `capabilities`:提供商发布转录/工具/提供商家族怪癖 +- `normalizeToolSchemas`:提供商在内嵌 + 运行器看到工具 schema 之前进行清理 +- `inspectToolSchemas`:提供商在归一化后暴露传输特定的 schema 警告 +- `resolveReasoningOutputMode`:提供商选择原生还是带标签的 + 推理输出契约 +- `prepareExtraParams`:提供商为每个模型的请求参数设置默认值或进行归一化 +- `createStreamFn`:提供商用完全 + 自定义的传输替换正常流式路径 +- `wrapStreamFn`:提供商应用请求头/请求体/模型兼容包装器 +- `resolveTransportTurnState`:提供商提供每轮原生传输的 + 请求头或元数据 +- `resolveWebSocketSessionPolicy`:提供商提供原生 WebSocket 会话 + 请求头或会话冷却策略 +- `createEmbeddingProvider`:当内存嵌入行为 + 更适合归属于提供商插件而不是核心嵌入切换层时,由提供商负责 +- `formatApiKey`:提供商将已存储的凭证配置档格式化为 + 传输所需的运行时 `apiKey` 字符串 +- `refreshOAuth`:当共享的 `pi-ai` + 刷新器不足时,由提供商负责 OAuth 刷新 +- `buildAuthDoctorHint`:当 OAuth 刷新 + 失败时,提供商追加修复指引 +- `matchesContextOverflowError`:提供商识别提供商特定的 + 上下文窗口溢出错误,而通用启发式无法识别这些错误 +- `classifyFailoverReason`:提供商将提供商特定的原始传输/API + 错误映射为回退原因,例如速率限制或过载 +- `isCacheTtlEligible`:提供商决定哪些上游模型 id 支持提示缓存 TTL +- `buildMissingAuthMessage`:提供商用提供商特定的恢复提示 + 替换通用的凭证存储错误 +- `suppressBuiltInModel`:提供商隐藏过时的上游条目,并且可以在 + 直接解析失败时返回厂商拥有的错误 +- `augmentModelCatalog`:提供商在 + 发现和配置合并之后追加合成/最终目录条目 +- `isBinaryThinking`:提供商拥有二元开/关思考 UX +- `supportsXHighThinking`:提供商让选定模型支持 `xhigh` +- `resolveDefaultThinkingLevel`:提供商拥有某个 + 模型家族的默认 `/think` 策略 +- `applyConfigDefaults`:提供商在配置具体化期间,根据凭证模式、 + 环境变量或模型家族应用提供商特定的全局默认值 +- `isModernModelRef`:提供商拥有实时/冒烟优选模型匹配 +- `prepareRuntimeAuth`:提供商将已配置的凭证转换为短期 + 运行时令牌 +- `resolveUsageAuth`:提供商为 `/usage` + 及相关状态/报告界面解析用量/配额凭证 +- `fetchUsageSnapshot`:提供商拥有用量端点的抓取/解析逻辑, + 而核心仍然拥有摘要外壳与格式化 +- `onModelSelected`:提供商运行选择模型后的副作用,例如 + 遥测或由提供商拥有的会话记账 当前内置示例: -- `anthropic`:Claude 4.6 前向兼容回退、凭证修复提示、用量端点获取、缓存 TTL/提供商家族元数据,以及带凭证感知的全局配置默认值 -- `amazon-bedrock`:提供商拥有的上下文溢出匹配,以及针对 Bedrock 专属 throttle/not-ready 错误的回退原因分类,另加共享的 `anthropic-by-model` 重放家族,用于 Anthropic 流量上仅适用于 Claude 的重放策略保护 -- `anthropic-vertex`:Anthropic message 流量上的仅 Claude 重放策略保护 -- `openrouter`:透传模型 ID、请求包装器、提供商能力提示、代理 Gemini 流量上的 Gemini thought-signature 清理、通过 `openrouter-thinking` 流家族进行代理推理注入、路由元数据转发,以及缓存 TTL 策略 -- `github-copilot`:onboarding/设备登录、前向兼容模型回退、Claude thinking 转录提示、运行时令牌交换,以及用量端点获取 -- `openai`:GPT-5.4 前向兼容回退、直接 OpenAI 传输规范化、面向 Codex 的缺失凭证提示、Spark 抑制、合成 OpenAI/Codex 目录条目、thinking/live-model 策略、用量令牌别名规范化(`input` / `output` 和 `prompt` / `completion` 家族)、共享的 `openai-responses-defaults` 流家族用于原生 OpenAI/Codex 包装器、提供商家族元数据、为 `gpt-image-1` 内置图像生成提供商注册,以及为 `sora-2` 内置视频生成提供商注册 -- `google`:Gemini 3.1 前向兼容回退、原生 Gemini 重放校验、bootstrap 重放清理、带标签的推理输出模式、现代模型匹配、为 Gemini image-preview 模型内置图像生成提供商注册,以及为 Veo 模型内置视频生成提供商注册 -- `moonshot`:共享传输、插件拥有的 thinking 负载规范化 -- `kilocode`:共享传输、插件拥有的请求头、推理负载规范化、代理 Gemini thought-signature 清理,以及缓存 TTL 策略 -- `zai`:GLM-5 前向兼容回退、`tool_stream` 默认值、缓存 TTL 策略、二元 thinking/live-model 策略,以及用量凭证 + 配额获取;未知的 `glm-5*` ID 会基于内置的 `glm-4.7` 模板合成 -- `xai`:原生 Responses 传输规范化、Grok fast 变体的 `/fast` 别名重写、默认 `tool_stream`、xAI 专属工具模式 / 推理负载清理,以及为 `grok-imagine-video` 内置视频生成提供商注册 -- `mistral`:插件拥有的能力元数据 -- `opencode` 和 `opencode-go`:插件拥有的能力元数据,以及代理 Gemini thought-signature 清理 -- `alibaba`:插件拥有的直连 Wan 模型引用视频生成目录,例如 `alibaba/wan2.6-t2v` -- `byteplus`:插件拥有的目录,以及为 Seedance 文生视频/图生视频模型内置视频生成提供商注册 -- `fal`:为托管的第三方图像模型内置图像生成提供商注册,以及为托管的第三方视频模型内置视频生成提供商注册 +- `anthropic`:Claude 4.6 向前兼容回退、凭证修复提示、用量 + 端点抓取、缓存 TTL/提供商家族元数据,以及具备凭证感知能力的全局 + 配置默认值 +- `amazon-bedrock`:由提供商拥有的上下文溢出匹配,以及针对 Bedrock 特定的节流/未就绪错误的回退 + 原因分类,另外还有共享的 `anthropic-by-model` 重放家族,用于 + Anthropic 流量上的仅 Claude 重放策略保护 +- `anthropic-vertex`:针对 Anthropic-message + 流量的仅 Claude 重放策略保护 +- `openrouter`:透传模型 id、请求包装器、提供商能力 + 提示、代理 Gemini 流量上的 Gemini thought-signature 清理、 + 通过 `openrouter-thinking` 流家族进行的代理推理注入、 + 路由元数据转发,以及缓存 TTL 策略 +- `github-copilot`:新手引导/设备登录、向前兼容模型回退、 + Claude-thinking 转录提示、运行时令牌交换,以及用量端点 + 抓取 +- `openai`:GPT-5.4 向前兼容回退、直接 OpenAI 传输 + 归一化、兼容 Codex 的缺失凭证提示、Spark 抑制、合成 + OpenAI/Codex 目录条目、thinking/live-model 策略、用量令牌别名 + 归一化(`input` / `output` 和 `prompt` / `completion` 家族)、共享的 + `openai-responses-defaults` 流家族,用于原生 OpenAI/Codex + 包装器、提供商家族元数据、为 `gpt-image-1` 注册的内置图像生成提供商, + 以及为 `sora-2` 注册的内置视频生成提供商 +- `google` 和 `google-gemini-cli`:Gemini 3.1 向前兼容回退、 + 原生 Gemini 重放校验、bootstrap 重放清理、带标签的 + 推理输出模式、现代模型匹配、为 Gemini image-preview 模型注册的内置图像生成 + 提供商,以及为 Veo 模型注册的内置 + 视频生成提供商;Gemini CLI OAuth 还 + 负责凭证配置档令牌格式化、用量令牌解析,以及面向用量界面的配额端点 + 抓取 +- `moonshot`:共享传输、由插件拥有的思考载荷归一化 +- `kilocode`:共享传输、由插件拥有的请求头、推理载荷 + 归一化、代理 Gemini thought-signature 清理,以及缓存 TTL + 策略 +- `zai`:GLM-5 向前兼容回退、`tool_stream` 默认值、缓存 TTL + 策略、二元思考/live-model 策略,以及用量凭证 + 配额抓取; + 未知的 `glm-5*` id 会从内置的 `glm-4.7` 模板合成 +- `xai`:原生 Responses 传输归一化、Grok 快速变体的 `/fast` 别名重写、 + 默认 `tool_stream`、xAI 特定的工具 schema / + 推理载荷清理,以及为 `grok-imagine-video` 注册的内置视频生成 + 提供商 +- `mistral`:由插件拥有的能力元数据 +- `opencode` 和 `opencode-go`:由插件拥有的能力元数据,加上 + 代理 Gemini thought-signature 清理 +- `alibaba`:用于直接 Wan 模型引用(例如 + `alibaba/wan2.6-t2v`)的由插件拥有的视频生成目录 +- `byteplus`:由插件拥有的目录,加上为 Seedance 文生视频/图生视频模型注册的内置 + 视频生成提供商 +- `fal`:为托管第三方 + 图像生成提供商注册的内置图像生成提供商,用于 FLUX 图像模型;以及为托管第三方视频模型注册的内置 + 视频生成提供商 - `cloudflare-ai-gateway`、`huggingface`、`kimi`、`nvidia`、`qianfan`、 `stepfun`、`synthetic`、`venice`、`vercel-ai-gateway` 和 `volcengine`: - 仅插件拥有的目录 -- `qwen`:文本模型的插件拥有目录,以及其多模态表面的共享媒体理解和视频生成提供商注册;Qwen 视频生成使用 Standard DashScope 视频端点以及内置的 Wan 模型,如 `wan2.6-t2v` 和 `wan2.7-r2v` -- `runway`:为原生 Runway 基于任务的模型(例如 `gen4.5`)注册插件拥有的视频生成提供商 -- `minimax`:插件拥有的目录、为 Hailuo 视频模型内置视频生成提供商注册、为 `image-01` 内置图像生成提供商注册、混合 Anthropic/OpenAI 重放策略选择,以及用量凭证/快照逻辑 -- `together`:插件拥有的目录,以及为 Wan 视频模型内置视频生成提供商注册 -- `xiaomi`:插件拥有的目录,以及用量凭证/快照逻辑 + 仅由插件拥有目录 +- `qwen`:文本模型的由插件拥有目录,加上为其 + 多模态界面注册的共享 media-understanding 和视频生成提供商;Qwen 视频生成使用 + 标准 DashScope 视频端点,配合内置 Wan 模型,例如 `wan2.6-t2v` 和 `wan2.7-r2v` +- `runway`:为原生 + Runway 基于任务的模型(例如 `gen4.5`)注册的由插件拥有的视频生成提供商 +- `minimax`:由插件拥有目录、为 Hailuo 视频模型注册的内置视频生成提供商、 + 为 `image-01` 注册的内置图像生成提供商、混合 Anthropic/OpenAI 重放策略 + 选择,以及用量凭证/快照逻辑 +- `together`:由插件拥有目录,加上为 Wan 视频模型注册的内置视频生成 + 提供商 +- `xiaomi`:由插件拥有目录,加上用量凭证/快照逻辑 -内置的 `openai` 插件现在同时拥有两个提供商 ID:`openai` 和 +内置的 `openai` 插件现在同时拥有这两个提供商 id:`openai` 和 `openai-codex`。 -以上涵盖了仍适用于 OpenClaw 常规传输的提供商。需要完全自定义请求执行器的提供商,则属于另一个更深层的扩展接口。 +以上涵盖了仍然适配 OpenClaw 正常传输的提供商。一个提供商 +如果需要完全自定义的请求执行器,则属于另一个更深层的扩展接口。 ## API 密钥轮换 -- 对选定提供商支持通用提供商轮换。 -- 可通过以下方式配置多个密钥: +- 支持为选定提供商进行通用提供商轮换。 +- 通过以下方式配置多个密钥: - `OPENCLAW_LIVE__KEY`(单个实时覆盖,最高优先级) - `_API_KEYS`(逗号或分号分隔列表) - `_API_KEY`(主密钥) - `_API_KEY_*`(编号列表,例如 `_API_KEY_1`) -- 对于 Google 提供商,还会将 `GOOGLE_API_KEY` 作为回退。 +- 对于 Google 提供商,还会将 `GOOGLE_API_KEY` 作为回退包含在内。 - 密钥选择顺序会保留优先级并去重。 -- 仅在收到限流响应时,才会使用下一个密钥重试请求(例如 `429`、`rate_limit`、`quota`、`resource exhausted`、`Too many +- 仅在速率限制响应时,请求才会使用下一个密钥重试(例如 + `429`、`rate_limit`、`quota`、`resource exhausted`、`Too many concurrent requests`、`ThrottlingException`、`concurrency limit reached`、 - `workers_ai ... quota limit exceeded`,或周期性用量限制消息)。 -- 非限流失败会立即失败;不会尝试密钥轮换。 + `workers_ai ... quota limit exceeded` 或周期性的用量上限消息)。 +- 非速率限制失败会立即失败;不会尝试密钥轮换。 - 当所有候选密钥都失败时,将返回最后一次尝试的最终错误。 ## 内置提供商(pi-ai 目录) OpenClaw 附带 pi‑ai 目录。这些提供商**不需要** -`models.providers` 配置;只需设置凭证并选择模型。 +`models.providers` 配置;只需设置凭证并选择模型即可。 ### OpenAI @@ -156,15 +248,17 @@ OpenClaw 附带 pi‑ai 目录。这些提供商**不需要** - 可选轮换:`OPENAI_API_KEYS`、`OPENAI_API_KEY_1`、`OPENAI_API_KEY_2`,以及 `OPENCLAW_LIVE_OPENAI_KEY`(单个覆盖) - 示例模型:`openai/gpt-5.4`、`openai/gpt-5.4-pro` - CLI:`openclaw onboard --auth-choice openai-api-key` -- 默认传输是 `auto`(优先 WebSocket,回退到 SSE) +- 默认传输是 `auto`(WebSocket 优先,SSE 回退) - 可通过 `agents.defaults.models["openai/"].params.transport` 为每个模型覆盖(`"sse"`、`"websocket"` 或 `"auto"`) -- OpenAI Responses WebSocket 预热默认通过 `params.openaiWsWarmup`(`true`/`false`)启用 -- 可以通过 `agents.defaults.models["openai/"].params.serviceTier` 启用 OpenAI 优先处理 -- `/fast` 和 `params.fastMode` 会将直接 `openai/*` Responses 请求映射到 `api.openai.com` 上的 `service_tier=priority` -- 如果你想显式指定层级而不是使用共享的 `/fast` 开关,请使用 `params.serviceTier` -- 隐藏的 OpenClaw 归因头(`originator`、`version`、 - `User-Agent`)仅适用于发往 `api.openai.com` 的原生 OpenAI 流量,不适用于通用的 OpenAI 兼容代理 -- 原生 OpenAI 路由还会保留 Responses `store`、提示缓存提示和 OpenAI 推理兼容负载整形;代理路由则不会 +- OpenAI Responses WebSocket 预热默认启用,通过 `params.openaiWsWarmup` 控制(`true`/`false`) +- 可以通过 `agents.defaults.models["openai/"].params.serviceTier` 启用 OpenAI 优先级处理 +- `/fast` 和 `params.fastMode` 会将直接 `openai/*` Responses 请求映射为 `api.openai.com` 上的 `service_tier=priority` +- 如果你想使用显式 tier,而不是共享的 `/fast` 开关,请使用 `params.serviceTier` +- 隐藏的 OpenClaw 归因请求头(`originator`、`version`、 + `User-Agent`)仅应用于发送到 `api.openai.com` 的原生 OpenAI 流量,不会应用于 + 通用 OpenAI 兼容代理 +- 原生 OpenAI 路由还会保留 Responses `store`、提示缓存提示,以及 + OpenAI 推理兼容载荷整形;代理路由则不会 - `openai/gpt-5.3-codex-spark` 在 OpenClaw 中被有意抑制,因为实时 OpenAI API 会拒绝它;Spark 被视为仅限 Codex ```json5 @@ -180,9 +274,9 @@ OpenClaw 附带 pi‑ai 目录。这些提供商**不需要** - 可选轮换:`ANTHROPIC_API_KEYS`、`ANTHROPIC_API_KEY_1`、`ANTHROPIC_API_KEY_2`,以及 `OPENCLAW_LIVE_ANTHROPIC_KEY`(单个覆盖) - 示例模型:`anthropic/claude-opus-4-6` - CLI:`openclaw onboard --auth-choice apiKey` -- 直接公共 Anthropic 请求支持共享的 `/fast` 开关和 `params.fastMode`,包括发送到 `api.anthropic.com` 的 API 密钥和 OAuth 凭证流量;OpenClaw 会将其映射为 Anthropic `service_tier`(`auto` 与 `standard_only`) -- 计费说明:对于 OpenClaw 中的 Anthropic,实际可行的划分是 **API 密钥** 或 **启用了 Extra Usage 的 Claude 订阅**。Anthropic 在 **2026 年 4 月 4 日 PT 时间中午 12:00 / BST 时间晚上 8:00** 通知 OpenClaw 用户,**OpenClaw** 的 Claude 登录路径会被视为第三方 harness 使用,需要 **Extra Usage**,并与订阅分开计费。我们的本地复现也表明,在 Anthropic SDK + API 密钥路径中,不会复现 OpenClaw 标识性的提示字符串。 -- Anthropic setup-token 现已再次作为旧版/手动 OpenClaw 路径提供。使用时请预期 Anthropic 已告知 OpenClaw 用户,此路径需要 **Extra Usage**。 +- 直连公共 Anthropic 请求支持共享 `/fast` 开关和 `params.fastMode`,包括发送到 `api.anthropic.com` 的 API 密钥和 OAuth 凭证流量;OpenClaw 会将其映射为 Anthropic `service_tier`(`auto` 与 `standard_only`) +- 计费说明:对于 OpenClaw 中的 Anthropic,实际上的区分是**API 密钥**或**带 Extra Usage 的 Claude 订阅**。Anthropic 于 **2026 年 4 月 4 日太平洋时间中午 12:00 / 英国夏令时晚上 8:00** 通知 OpenClaw 用户,**OpenClaw** 的 Claude 登录路径被视为第三方 harness 用法,因此需要**额外用量**,并与订阅分开计费。我们的本地复现还显示,OpenClaw 标识提示字符串不会在 Anthropic SDK + API 密钥路径上复现。 +- Anthropic setup-token 现已再次作为旧版/手动 OpenClaw 路径可用。使用时请预期 Anthropic 已告知 OpenClaw 用户,此路径需要**额外用量**。 ```json5 { @@ -196,13 +290,14 @@ OpenClaw 附带 pi‑ai 目录。这些提供商**不需要** - 凭证:OAuth(ChatGPT) - 示例模型:`openai-codex/gpt-5.4` - CLI:`openclaw onboard --auth-choice openai-codex` 或 `openclaw models auth login --provider openai-codex` -- 默认传输是 `auto`(优先 WebSocket,回退到 SSE) +- 默认传输是 `auto`(WebSocket 优先,SSE 回退) - 可通过 `agents.defaults.models["openai-codex/"].params.transport` 为每个模型覆盖(`"sse"`、`"websocket"` 或 `"auto"`) -- `params.serviceTier` 也会在原生 Codex Responses 请求(`chatgpt.com/backend-api`)中透传 -- 隐藏的 OpenClaw 归因头(`originator`、`version`、 - `User-Agent`)仅附加在发往 `chatgpt.com/backend-api` 的原生 Codex 流量上,不适用于通用的 OpenAI 兼容代理 +- `params.serviceTier` 也会在原生 Codex Responses 请求(`chatgpt.com/backend-api`)上传递 +- 隐藏的 OpenClaw 归因请求头(`originator`、`version`、 + `User-Agent`)仅附加到发送到 + `chatgpt.com/backend-api` 的原生 Codex 流量,不会附加到通用 OpenAI 兼容代理 - 与直接 `openai/*` 共享相同的 `/fast` 开关和 `params.fastMode` 配置;OpenClaw 会将其映射为 `service_tier=priority` -- 当 Codex OAuth 目录暴露 `openai-codex/gpt-5.3-codex-spark` 时,它仍然可用;是否可用取决于 entitlement +- 当 Codex OAuth 目录公开 `openai-codex/gpt-5.3-codex-spark` 时,它仍然可用;取决于权限 - `openai-codex/gpt-5.4` 保留原生 `contextWindow = 1050000` 和默认运行时 `contextTokens = 272000`;可通过 `models.providers.openai-codex.models[].contextTokens` 覆盖运行时上限 - 策略说明:OpenAI Codex OAuth 明确支持用于 OpenClaw 之类的外部工具/工作流。 @@ -226,7 +321,7 @@ OpenClaw 附带 pi‑ai 目录。这些提供商**不需要** ### 其他订阅式托管选项 -- [Qwen Cloud](/zh-CN/providers/qwen):Qwen Cloud 提供商接口,以及 Alibaba DashScope 与 Coding Plan 端点映射 +- [Qwen Cloud](/zh-CN/providers/qwen):Qwen Cloud 提供商界面,以及 Alibaba DashScope 和 Coding Plan 端点映射 - [MiniMax](/zh-CN/providers/minimax):MiniMax Coding Plan OAuth 或 API 密钥访问 - [GLM Models](/zh-CN/providers/glm):Z.AI Coding Plan 或通用 API 端点 @@ -250,18 +345,29 @@ OpenClaw 附带 pi‑ai 目录。这些提供商**不需要** - 凭证:`GEMINI_API_KEY` - 可选轮换:`GEMINI_API_KEYS`、`GEMINI_API_KEY_1`、`GEMINI_API_KEY_2`、`GOOGLE_API_KEY` 回退,以及 `OPENCLAW_LIVE_GEMINI_KEY`(单个覆盖) - 示例模型:`google/gemini-3.1-pro-preview`、`google/gemini-3-flash-preview` -- 兼容性:使用 `google/gemini-3.1-flash-preview` 的旧版 OpenClaw 配置会被规范化为 `google/gemini-3-flash-preview` +- 兼容性:使用 `google/gemini-3.1-flash-preview` 的旧版 OpenClaw 配置会被归一化为 `google/gemini-3-flash-preview` - CLI:`openclaw onboard --auth-choice gemini-api-key` -- 直接 Gemini 运行还接受 `agents.defaults.models["google/"].params.cachedContent` - (或旧版 `cached_content`)以透传提供商原生的 - `cachedContents/...` 句柄;Gemini 缓存命中会作为 OpenClaw `cacheRead` 显示 +- 直连 Gemini 运行还接受 `agents.defaults.models["google/"].params.cachedContent` + (或旧版 `cached_content`),用于转发提供商原生的 + `cachedContents/...` 句柄;Gemini 缓存命中会以 OpenClaw `cacheRead` 形式呈现 -### Google Vertex +### Google Vertex 和 Gemini CLI -- 提供商:`google-vertex` -- 凭证:gcloud ADC - - Gemini CLI JSON 回复从 `response` 解析;用量回退到 - `stats`,其中 `stats.cached` 会被规范化为 OpenClaw `cacheRead`。 +- 提供商:`google-vertex`、`google-gemini-cli` +- 凭证:Vertex 使用 gcloud ADC;Gemini CLI 使用其 OAuth 流程 +- 注意:OpenClaw 中的 Gemini CLI OAuth 是非官方集成。一些用户报告在使用第三方客户端后遭到 Google 账号限制。若你选择继续,请先查看 Google 条款,并使用非关键账号。 +- Gemini CLI OAuth 作为内置 `google` 插件的一部分提供。 + - 先安装 Gemini CLI: + - `brew install gemini-cli` + - 或 `npm install -g @google/gemini-cli` + - 启用:`openclaw plugins enable google` + - 登录:`openclaw models auth login --provider google-gemini-cli --set-default` + - 默认模型:`google-gemini-cli/gemini-3.1-pro-preview` + - 注意:你**不需要**把 client id 或 secret 粘贴到 `openclaw.json` 中。CLI 登录流程会将 + 令牌存储在 Gateway 网关主机上的凭证配置档中。 + - 如果登录后请求失败,请在 Gateway 网关主机上设置 `GOOGLE_CLOUD_PROJECT` 或 `GOOGLE_CLOUD_PROJECT_ID`。 + - Gemini CLI JSON 回复会从 `response` 解析;用量会回退到 + `stats`,其中 `stats.cached` 会被归一化为 OpenClaw `cacheRead`。 ### Z.AI(GLM) @@ -269,8 +375,8 @@ OpenClaw 附带 pi‑ai 目录。这些提供商**不需要** - 凭证:`ZAI_API_KEY` - 示例模型:`zai/glm-5` - CLI:`openclaw onboard --auth-choice zai-api-key` - - 别名:`z.ai/*` 和 `z-ai/*` 会规范化为 `zai/*` - - `zai-api-key` 会自动检测匹配的 Z.AI 端点;`zai-coding-global`、`zai-coding-cn`、`zai-global` 和 `zai-cn` 会强制使用特定接口 + - 别名:`z.ai/*` 和 `z-ai/*` 会归一化为 `zai/*` + - `zai-api-key` 会自动检测匹配的 Z.AI 端点;`zai-coding-global`、`zai-coding-cn`、`zai-global` 和 `zai-cn` 会强制使用特定界面 ### Vercel AI Gateway @@ -287,8 +393,10 @@ OpenClaw 附带 pi‑ai 目录。这些提供商**不需要** - CLI:`openclaw onboard --auth-choice kilocode-api-key` - Base URL:`https://api.kilo.ai/api/gateway/` - 静态回退目录附带 `kilocode/kilo/auto`;实时 - `https://api.kilo.ai/api/gateway/models` 发现可进一步扩展运行时目录。 -- `kilocode/kilo/auto` 背后的确切上游路由由 Kilo Gateway 拥有,并非 OpenClaw 硬编码。 + `https://api.kilo.ai/api/gateway/models` 发现可以进一步扩展运行时 + 目录。 +- `kilocode/kilo/auto` 背后的确切上游路由由 Kilo Gateway + 决定,而不是在 OpenClaw 中硬编码。 设置详情请参见 [/providers/kilocode](/zh-CN/providers/kilocode)。 @@ -296,18 +404,25 @@ OpenClaw 附带 pi‑ai 目录。这些提供商**不需要** - OpenRouter:`openrouter`(`OPENROUTER_API_KEY`) - 示例模型:`openrouter/auto` -- 仅当请求实际指向 `openrouter.ai` 时,OpenClaw 才会应用 OpenRouter 文档中的应用归因头 -- OpenRouter 专属 Anthropic `cache_control` 标记同样仅对已验证的 OpenRouter 路由生效,不会作用于任意代理 URL -- OpenRouter 仍保持在代理式 OpenAI 兼容路径上,因此不会转发仅适用于原生 OpenAI 的请求整形(`serviceTier`、Responses `store`、提示缓存提示、OpenAI 推理兼容负载) -- 基于 Gemini 的 OpenRouter 引用仅保留代理 Gemini thought-signature 清理;原生 Gemini 重放校验和 bootstrap 重写不会启用 +- 只有当请求实际发送到 `openrouter.ai` 时,OpenClaw 才会应用 OpenRouter 文档中的应用归因请求头 +- OpenRouter 特有的 Anthropic `cache_control` 标记同样只会应用到 + 已验证的 OpenRouter 路由,而不是任意代理 URL +- OpenRouter 仍然走代理风格的 OpenAI 兼容路径,因此不会转发 + 原生 OpenAI 专属的请求整形(`serviceTier`、Responses `store`、 + 提示缓存提示、OpenAI 推理兼容载荷) +- 以 Gemini 为后端的 OpenRouter 引用仅保留代理 Gemini thought-signature 清理; + 原生 Gemini 重放校验和 bootstrap 重写仍然关闭 - Kilo Gateway:`kilocode`(`KILOCODE_API_KEY`) - 示例模型:`kilocode/kilo/auto` -- 基于 Gemini 的 Kilo 引用保留相同的代理 Gemini thought-signature 清理路径;`kilocode/kilo/auto` 以及其他不支持代理推理的提示会跳过代理推理注入 +- 以 Gemini 为后端的 Kilo 引用保留相同的代理 Gemini thought-signature + 清理路径;`kilocode/kilo/auto` 和其他不支持代理推理的提示 + 会跳过代理推理注入 - MiniMax:`minimax`(API 密钥)和 `minimax-portal`(OAuth) - 凭证:`MINIMAX_API_KEY` 用于 `minimax`;`MINIMAX_OAUTH_TOKEN` 或 `MINIMAX_API_KEY` 用于 `minimax-portal` - 示例模型:`minimax/MiniMax-M2.7` 或 `minimax-portal/MiniMax-M2.7` -- MiniMax onboarding/API 密钥设置会写入显式的 M2.7 模型定义,其中 - `input: ["text", "image"]`;内置提供商目录会在该提供商配置实体化之前,保持聊天引用为纯文本 +- MiniMax 新手引导/API 密钥设置会写入显式的 M2.7 模型定义, + 其中 `input: ["text", "image"]`;内置提供商目录会在 + 该提供商配置具体化之前将聊天引用保持为纯文本 - Moonshot:`moonshot`(`MOONSHOT_API_KEY`) - 示例模型:`moonshot/kimi-k2.5` - Kimi Coding:`kimi`(`KIMI_API_KEY` 或 `KIMICODE_API_KEY`) @@ -336,14 +451,15 @@ OpenClaw 附带 pi‑ai 目录。这些提供商**不需要** - 原生内置 xAI 请求使用 xAI Responses 路径 - `/fast` 或 `params.fastMode: true` 会将 `grok-3`、`grok-3-mini`、 `grok-4` 和 `grok-4-0709` 重写为对应的 `*-fast` 变体 - - `tool_stream` 默认启用;设置 - `agents.defaults.models["xai/"].params.tool_stream` 为 `false` 可禁用 + - `tool_stream` 默认开启;设置 + `agents.defaults.models["xai/"].params.tool_stream` 为 `false` 可 + 关闭它 - Mistral:`mistral`(`MISTRAL_API_KEY`) - 示例模型:`mistral/mistral-large-latest` - CLI:`openclaw onboard --auth-choice mistral-api-key` - Groq:`groq`(`GROQ_API_KEY`) - Cerebras:`cerebras`(`CEREBRAS_API_KEY`) - - Cerebras 上的 GLM 模型使用 `zai-glm-4.7` 和 `zai-glm-4.6` 作为 ID。 + - Cerebras 上的 GLM 模型使用 id `zai-glm-4.7` 和 `zai-glm-4.6`。 - OpenAI 兼容 base URL:`https://api.cerebras.ai/v1`。 - GitHub Copilot:`github-copilot`(`COPILOT_GITHUB_TOKEN` / `GH_TOKEN` / `GITHUB_TOKEN`) - Hugging Face Inference 示例模型:`huggingface/deepseek-ai/DeepSeek-R1`;CLI:`openclaw onboard --auth-choice huggingface-api-key`。请参见 [Hugging Face(Inference)](/zh-CN/providers/huggingface)。 @@ -351,14 +467,16 @@ OpenClaw 附带 pi‑ai 目录。这些提供商**不需要** ## 通过 `models.providers` 配置的提供商(自定义/base URL) 使用 `models.providers`(或 `models.json`)来添加**自定义**提供商或 -Anthropic/OpenAI 兼容代理。 +OpenAI/Anthropic 兼容代理。 -下面许多内置提供商插件已经发布了默认目录。 -只有当你想覆盖默认 base URL、请求头或模型列表时,才需要显式使用 `models.providers.` 条目。 +下方许多内置提供商插件已经发布了默认目录。 +只有当你想覆盖默认 base URL、请求头或模型列表时, +才需要显式使用 `models.providers.` 条目。 ### Moonshot AI(Kimi) -Moonshot 作为内置提供商插件提供。默认请使用内置提供商,仅当你需要覆盖 base URL 或模型元数据时,才添加显式的 `models.providers.moonshot` 条目: +Moonshot 作为内置提供商插件提供。默认应使用内置提供商, +只有在你需要覆盖 base URL 或模型元数据时,才添加显式的 `models.providers.moonshot` 条目: - 提供商:`moonshot` - 凭证:`MOONSHOT_API_KEY` @@ -412,13 +530,13 @@ Kimi Coding 使用 Moonshot AI 的 Anthropic 兼容端点: } ``` -旧版 `kimi/k2p5` 仍作为兼容模型 ID 被接受。 +旧版 `kimi/k2p5` 仍然作为兼容模型 id 被接受。 ### Volcano Engine(Doubao) -Volcano Engine(火山引擎)为中国用户提供 Doubao 和其他模型的访问。 +Volcano Engine(火山引擎)为中国用户提供对 Doubao 及其他模型的访问。 -- 提供商:`volcengine`(编程:`volcengine-plan`) +- 提供商:`volcengine`(编码:`volcengine-plan`) - 凭证:`VOLCANO_ENGINE_API_KEY` - 示例模型:`volcengine-plan/ark-code-latest` - CLI:`openclaw onboard --auth-choice volcengine-api-key` @@ -431,10 +549,13 @@ Volcano Engine(火山引擎)为中国用户提供 Doubao 和其他模型的 } ``` -新手引导默认使用编程接口,但通用 `volcengine/*` +新手引导默认使用编码界面,但通用 `volcengine/*` 目录也会同时注册。 -在新手引导/配置模型选择器中,Volcengine 凭证选项会优先显示 `volcengine/*` 和 `volcengine-plan/*` 两类条目。如果这些模型尚未加载,OpenClaw 会回退到未过滤目录,而不会显示空的提供商范围选择器。 +在新手引导/配置模型选择器中,Volcengine 凭证选择会优先显示 +`volcengine/*` 和 `volcengine-plan/*` 两类条目。如果这些模型尚未加载, +OpenClaw 会回退到未过滤目录,而不是显示一个空的 +提供商范围选择器。 可用模型: @@ -444,7 +565,7 @@ Volcano Engine(火山引擎)为中国用户提供 Doubao 和其他模型的 - `volcengine/glm-4-7-251222`(GLM 4.7) - `volcengine/deepseek-v3-2-251201`(DeepSeek V3.2 128K) -编程模型(`volcengine-plan`): +编码模型(`volcengine-plan`): - `volcengine-plan/ark-code-latest` - `volcengine-plan/doubao-seed-code` @@ -454,9 +575,9 @@ Volcano Engine(火山引擎)为中国用户提供 Doubao 和其他模型的 ### BytePlus(国际版) -BytePlus ARK 为国际用户提供与 Volcano Engine 相同模型的访问。 +BytePlus ARK 为国际用户提供对与 Volcano Engine 相同模型的访问。 -- 提供商:`byteplus`(编程:`byteplus-plan`) +- 提供商:`byteplus`(编码:`byteplus-plan`) - 凭证:`BYTEPLUS_API_KEY` - 示例模型:`byteplus-plan/ark-code-latest` - CLI:`openclaw onboard --auth-choice byteplus-api-key` @@ -469,10 +590,13 @@ BytePlus ARK 为国际用户提供与 Volcano Engine 相同模型的访问。 } ``` -新手引导默认使用编程接口,但通用 `byteplus/*` +新手引导默认使用编码界面,但通用 `byteplus/*` 目录也会同时注册。 -在新手引导/配置模型选择器中,BytePlus 凭证选项会优先显示 `byteplus/*` 和 `byteplus-plan/*` 两类条目。如果这些模型尚未加载,OpenClaw 会回退到未过滤目录,而不会显示空的提供商范围选择器。 +在新手引导/配置模型选择器中,BytePlus 凭证选择会优先显示 +`byteplus/*` 和 `byteplus-plan/*` 两类条目。如果这些模型尚未加载, +OpenClaw 会回退到未过滤目录,而不是显示一个空的 +提供商范围选择器。 可用模型: @@ -480,7 +604,7 @@ BytePlus ARK 为国际用户提供与 Volcano Engine 相同模型的访问。 - `byteplus/kimi-k2-5-260127`(Kimi K2.5) - `byteplus/glm-4-7-251222`(GLM 4.7) -编程模型(`byteplus-plan`): +编码模型(`byteplus-plan`): - `byteplus-plan/ark-code-latest` - `byteplus-plan/doubao-seed-code` @@ -520,28 +644,29 @@ Synthetic 通过 `synthetic` 提供商提供 Anthropic 兼容模型: MiniMax 通过 `models.providers` 配置,因为它使用自定义端点: -- MiniMax OAuth(全球):`--auth-choice minimax-global-oauth` -- MiniMax OAuth(中国):`--auth-choice minimax-cn-oauth` -- MiniMax API 密钥(全球):`--auth-choice minimax-global-api` -- MiniMax API 密钥(中国):`--auth-choice minimax-cn-api` +- MiniMax OAuth(Global):`--auth-choice minimax-global-oauth` +- MiniMax OAuth(CN):`--auth-choice minimax-cn-oauth` +- MiniMax API 密钥(Global):`--auth-choice minimax-global-api` +- MiniMax API 密钥(CN):`--auth-choice minimax-cn-api` - 凭证:`MINIMAX_API_KEY` 用于 `minimax`;`MINIMAX_OAUTH_TOKEN` 或 `MINIMAX_API_KEY` 用于 `minimax-portal` -有关设置详情、模型选项和配置片段,请参见 [/providers/minimax](/zh-CN/providers/minimax)。 +设置详情、模型选项和配置片段请参见 [/providers/minimax](/zh-CN/providers/minimax)。 -在 MiniMax 的 Anthropic 兼容流式路径上,OpenClaw 默认禁用 thinking,除非你显式设置它,并且 `/fast on` 会将 +在 MiniMax 的 Anthropic 兼容流式路径上,OpenClaw 默认禁用 thinking, +除非你显式设置它,并且 `/fast on` 会将 `MiniMax-M2.7` 重写为 `MiniMax-M2.7-highspeed`。 -插件拥有的能力拆分: +由插件拥有的能力划分: - 文本/聊天默认保持在 `minimax/MiniMax-M2.7` -- 图像生成使用 `minimax/image-01` 或 `minimax-portal/image-01` -- 图像理解在两种 MiniMax 凭证路径上都使用插件拥有的 `MiniMax-VL-01` -- Web 搜索仍使用提供商 ID `minimax` +- 图像生成是 `minimax/image-01` 或 `minimax-portal/image-01` +- 图像理解是在两个 MiniMax 凭证路径上都由插件拥有的 `MiniMax-VL-01` +- Web 搜索仍然使用提供商 id `minimax` ### Ollama -Ollama 作为内置提供商插件提供,并使用 Ollama 原生 API: +Ollama 作为内置提供商插件提供,并使用 Ollama 的原生 API: - 提供商:`ollama` - 凭证:无需(本地服务器) @@ -561,24 +686,26 @@ ollama pull llama3.3 } ``` -当你通过 `OLLAMA_API_KEY` 选择启用时,会在本地 `http://127.0.0.1:11434` 检测 Ollama,并且内置提供商插件会将 Ollama 直接添加到 -`openclaw onboard` 和模型选择器中。有关 onboarding、云端/本地模式和自定义配置,请参见 [/providers/ollama](/zh-CN/providers/ollama)。 +当你通过 `OLLAMA_API_KEY` 选择加入时,Ollama 会在本地 `http://127.0.0.1:11434` 被检测到, +并且内置提供商插件会将 Ollama 直接添加到 +`openclaw onboard` 和模型选择器中。关于新手引导、云端/本地模式以及自定义配置,请参见 [/providers/ollama](/zh-CN/providers/ollama)。 ### vLLM -vLLM 作为内置提供商插件提供,用于本地/自托管 OpenAI 兼容服务器: +vLLM 作为内置提供商插件提供,用于本地/自托管的 OpenAI 兼容 +服务器: - 提供商:`vllm` - 凭证:可选(取决于你的服务器) - 默认 base URL:`http://127.0.0.1:8000/v1` -要选择启用本地自动发现(如果你的服务器不强制凭证,任意值都可以): +若要在本地选择加入自动发现(如果你的服务器不强制凭证,任意值都可以): ```bash export VLLM_API_KEY="vllm-local" ``` -然后设置一个模型(替换为 `/v1/models` 返回的某个 ID): +然后设置一个模型(替换为 `/v1/models` 返回的某个 id): ```json5 { @@ -592,20 +719,21 @@ export VLLM_API_KEY="vllm-local" ### SGLang -SGLang 作为内置提供商插件提供,用于快速自托管 +SGLang 作为内置提供商插件提供,用于高速自托管的 OpenAI 兼容服务器: - 提供商:`sglang` - 凭证:可选(取决于你的服务器) - 默认 base URL:`http://127.0.0.1:30000/v1` -要选择启用本地自动发现(如果你的服务器不强制凭证,任意值都可以): +若要在本地选择加入自动发现(如果你的服务器不 +强制凭证,任意值都可以): ```bash export SGLANG_API_KEY="sglang-local" ``` -然后设置一个模型(替换为 `/v1/models` 返回的某个 ID): +然后设置一个模型(替换为 `/v1/models` 返回的某个 id): ```json5 { @@ -626,7 +754,7 @@ export SGLANG_API_KEY="sglang-local" agents: { defaults: { model: { primary: "lmstudio/my-local-model" }, - models: { "lmstudio/my-local-model": { alias: "本地" } }, + models: { "lmstudio/my-local-model": { alias: "Local" } }, }, }, models: { @@ -638,7 +766,7 @@ export SGLANG_API_KEY="sglang-local" models: [ { id: "my-local-model", - name: "本地模型", + name: "Local Model", reasoning: false, input: ["text"], cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, @@ -655,17 +783,20 @@ export SGLANG_API_KEY="sglang-local" 说明: - 对于自定义提供商,`reasoning`、`input`、`cost`、`contextWindow` 和 `maxTokens` 都是可选的。 - 若省略,OpenClaw 默认使用: + 省略时,OpenClaw 默认值为: - `reasoning: false` - `input: ["text"]` - `cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }` - `contextWindow: 200000` - `maxTokens: 8192` -- 建议:设置与你的代理/模型限制相匹配的显式值。 -- 对于非原生端点上的 `api: "openai-completions"`(任何非空 `baseUrl` 且其主机不是 `api.openai.com`),OpenClaw 会强制 `compat.supportsDeveloperRole: false`,以避免提供商因不支持 `developer` 角色而返回 400 错误。 -- 代理式 OpenAI 兼容路由同样会跳过仅适用于原生 OpenAI 的请求整形:没有 `service_tier`、没有 Responses `store`、没有提示缓存提示、没有 OpenAI 推理兼容负载整形,也没有隐藏的 OpenClaw 归因头。 -- 如果 `baseUrl` 为空/省略,OpenClaw 会保留默认的 OpenAI 行为(解析到 `api.openai.com`)。 -- 出于安全考虑,即使显式设置了 `compat.supportsDeveloperRole: true`,在非原生 `openai-completions` 端点上也仍会被覆盖。 +- 建议:设置与你的代理/模型限制匹配的显式值。 +- 对于非原生端点上的 `api: "openai-completions"`(任何主机不是 `api.openai.com` 的非空 `baseUrl`),OpenClaw 会强制 `compat.supportsDeveloperRole: false`,以避免提供商因不支持 `developer` 角色而返回 400 错误。 +- 代理风格的 OpenAI 兼容路由也会跳过原生 OpenAI 专属的请求 + 整形:没有 `service_tier`、没有 Responses `store`、没有提示缓存提示、没有 + OpenAI 推理兼容载荷整形,也没有隐藏的 OpenClaw 归因 + 请求头。 +- 如果 `baseUrl` 为空或省略,OpenClaw 会保留默认 OpenAI 行为(即解析到 `api.openai.com`)。 +- 出于安全考虑,即使显式设置了 `compat.supportsDeveloperRole: true`,在非原生 `openai-completions` 端点上仍会被覆盖。 ## CLI 示例 @@ -675,7 +806,7 @@ openclaw models set opencode/claude-opus-4-6 openclaw models list ``` -另请参见:[/gateway/configuration](/zh-CN/gateway/configuration) 查看完整配置示例。 +另请参见:[/gateway/configuration](/zh-CN/gateway/configuration) 了解完整配置示例。 ## 相关内容 diff --git a/docs/zh-CN/gateway/cli-backends.md b/docs/zh-CN/gateway/cli-backends.md new file mode 100644 index 000000000..57ec8fed0 --- /dev/null +++ b/docs/zh-CN/gateway/cli-backends.md @@ -0,0 +1,289 @@ +--- +read_when: + - 当 API 提供商失败时,你想要一个可靠的回退方案 + - 你正在运行 Codex CLI 或其他本地 AI CLI,并且想要复用它们 + - 你想了解用于 CLI 后端工具访问的 MCP loopback 桥接 +summary: CLI 后端:带可选 MCP 工具桥接的本地 AI CLI 回退方案 +title: CLI 后端 +x-i18n: + generated_at: "2026-04-06T12:42:54Z" + model: gpt-5.4 + provider: openai + source_hash: fe30bb4d5f51adcda53bf69a4f88e27832e78630ed5bfd8a33a66b6412b66f2d + source_path: gateway/cli-backends.md + workflow: 15 +--- + +# CLI 后端(回退运行时) + +当 API 提供商不可用、受到速率限制或暂时行为异常时,OpenClaw 可以将**本地 AI CLI** 作为**纯文本回退方案**运行。这种设计有意保持保守: + +- **OpenClaw 工具不会被直接注入**,但设置了 `bundleMcp: true` 的后端 + 可以通过 loopback MCP 桥接接收 Gateway 网关工具。 +- **JSONL 流式传输**,适用于支持该能力的 CLI。 +- **支持会话**(因此后续轮次可以保持连贯)。 +- 如果 CLI 接受图片路径,**图片也可以透传**。 + +这被设计为一种**安全兜底机制**,而不是主要路径。当你希望获得“不管怎样都能工作”的文本回复、而不依赖外部 API 时,可以使用它。 + +如果你想使用带有 ACP 会话控制、后台任务、线程/对话绑定以及持久化外部编码会话的完整 harness 运行时,请改用 +[ACP Agents](/zh-CN/tools/acp-agents)。CLI 后端不是 ACP。 + +## 面向初学者的快速开始 + +你可以**无需任何配置**使用 Codex CLI(内置的 OpenAI 插件会注册一个默认后端): + +```bash +openclaw agent --message "hi" --model codex-cli/gpt-5.4 +``` + +如果你的 Gateway 网关运行在 launchd/systemd 下,且 `PATH` 很精简,只需添加 +命令路径: + +```json5 +{ + agents: { + defaults: { + cliBackends: { + "codex-cli": { + command: "/opt/homebrew/bin/codex", + }, + }, + }, + }, +} +``` + +就是这样。除了 CLI 本身之外,不需要密钥,也不需要额外的凭证配置。 + +如果你在 gateway host 上将某个内置 CLI 后端用作**主要消息提供商**,当你的配置 +在模型引用中或在 +`agents.defaults.cliBackends` +下明确引用了该后端时,OpenClaw 现在会自动加载其所属的内置插件。 + +## 将其用作回退方案 + +将某个 CLI 后端添加到你的回退列表中,这样它只会在主要模型失败时运行: + +```json5 +{ + agents: { + defaults: { + model: { + primary: "anthropic/claude-opus-4-6", + fallbacks: ["codex-cli/gpt-5.4"], + }, + models: { + "anthropic/claude-opus-4-6": { alias: "Opus" }, + "codex-cli/gpt-5.4": {}, + }, + }, + }, +} +``` + +说明: + +- 如果你使用 `agents.defaults.models`(允许列表),你也必须将你的 CLI 后端模型包含在其中。 +- 如果主要提供商失败(凭证、速率限制、超时),OpenClaw 将会 + 接着尝试 CLI 后端。 + +## 配置概览 + +所有 CLI 后端都位于: + +``` +agents.defaults.cliBackends +``` + +每个条目都由一个**提供商 id** 作为键(例如 `codex-cli`、`my-cli`)。 +这个提供商 id 会成为你的模型引用左侧部分: + +``` +/ +``` + +### 配置示例 + +```json5 +{ + agents: { + defaults: { + cliBackends: { + "codex-cli": { + command: "/opt/homebrew/bin/codex", + }, + "my-cli": { + command: "my-cli", + args: ["--json"], + output: "json", + input: "arg", + modelArg: "--model", + modelAliases: { + "claude-opus-4-6": "opus", + "claude-sonnet-4-6": "sonnet", + }, + sessionArg: "--session", + sessionMode: "existing", + sessionIdFields: ["session_id", "conversation_id"], + systemPromptArg: "--system", + systemPromptWhen: "first", + imageArg: "--image", + imageMode: "repeat", + serialize: true, + }, + }, + }, + }, +} +``` + +## 工作原理 + +1. 根据提供商前缀(`codex-cli/...`)**选择一个后端**。 +2. 使用相同的 OpenClaw 提示词和工作区上下文**构建系统提示词**。 +3. 使用会话 id(如果支持)**执行 CLI**,以保持历史记录一致。 +4. **解析输出**(JSON 或纯文本),并返回最终文本。 +5. 按后端**持久化会话 id**,使后续轮次复用同一个 CLI 会话。 + + +内置的 Anthropic `claude-cli` 后端已被移除,因为 Anthropic 的 +OpenClaw 计费边界发生了变化。OpenClaw 仍然支持通用 CLI +后端,但 Anthropic API 流量应当直接使用 Anthropic 提供商, +而不是已移除的本地 Claude CLI 路径。 + + +## 会话 + +- 如果 CLI 支持会话,请设置 `sessionArg`(例如 `--session-id`)或 + `sessionArgs`(占位符 `{sessionId}`),用于在需要将该 ID 插入 + 到多个标志位时使用。 +- 如果 CLI 使用带有不同标志位的**恢复子命令**,请设置 + `resumeArgs`(恢复时替换 `args`),并可选设置 `resumeOutput` + (用于非 JSON 的恢复输出)。 +- `sessionMode`: + - `always`:始终发送会话 id(如果没有已存储值,则使用新的 UUID)。 + - `existing`:仅当之前已存储会话 id 时才发送。 + - `none`:从不发送会话 id。 + +序列化说明: + +- `serialize: true` 会保持同一通道运行按顺序执行。 +- 大多数 CLI 会在一个提供商通道上串行执行。 +- 当后端凭证状态发生变化时,包括重新登录、令牌轮换或凭证配置发生变化,OpenClaw 会丢弃已存储的 CLI 会话复用信息。 + +## 图片(透传) + +如果你的 CLI 接受图片路径,请设置 `imageArg`: + +```json5 +imageArg: "--image", +imageMode: "repeat" +``` + +OpenClaw 会将 base64 图片写入临时文件。如果设置了 `imageArg`,这些 +路径会作为 CLI 参数传递。如果缺少 `imageArg`,OpenClaw 会将 +这些文件路径附加到提示词中(路径注入),这对于那些可以从普通路径中自动 +加载本地文件的 CLI 来说已经足够。 + +## 输入 / 输出 + +- `output: "json"`(默认)会尝试解析 JSON,并提取文本 + 会话 id。 +- 对于 Gemini CLI 的 JSON 输出,当 `usage` 缺失或为空时,OpenClaw 会从 `response` 读取回复文本,并从 + `stats` 读取用量。 +- `output: "jsonl"` 会解析 JSONL 流(例如 Codex CLI `--json`),并提取最终的智能体消息以及存在时的会话 + 标识符。 +- `output: "text"` 会将 stdout 视为最终响应。 + +输入模式: + +- `input: "arg"`(默认)会将提示词作为最后一个 CLI 参数传递。 +- `input: "stdin"` 会通过 stdin 发送提示词。 +- 如果提示词很长且设置了 `maxPromptArgChars`,则会改用 stdin。 + +## 默认值(插件所有) + +内置的 OpenAI 插件也为 `codex-cli` 注册了一个默认值: + +- `command: "codex"` +- `args: ["exec","--json","--color","never","--sandbox","workspace-write","--skip-git-repo-check"]` +- `resumeArgs: ["exec","resume","{sessionId}","--color","never","--sandbox","workspace-write","--skip-git-repo-check"]` +- `output: "jsonl"` +- `resumeOutput: "text"` +- `modelArg: "--model"` +- `imageArg: "--image"` +- `sessionMode: "existing"` + +内置的 Google 插件也为 `google-gemini-cli` 注册了一个默认值: + +- `command: "gemini"` +- `args: ["--prompt", "--output-format", "json"]` +- `resumeArgs: ["--resume", "{sessionId}", "--prompt", "--output-format", "json"]` +- `modelArg: "--model"` +- `sessionMode: "existing"` +- `sessionIdFields: ["session_id", "sessionId"]` + +前提条件:本地 Gemini CLI 必须已安装,并且可以作为 +`gemini` 在 `PATH` 中使用(`brew install gemini-cli` 或 +`npm install -g @google/gemini-cli`)。 + +Gemini CLI JSON 说明: + +- 回复文本从 JSON 的 `response` 字段读取。 +- 当 `usage` 不存在或为空时,用量会回退到 `stats`。 +- `stats.cached` 会被规范化为 OpenClaw `cacheRead`。 +- 如果缺少 `stats.input`,OpenClaw 会根据 + `stats.input_tokens - stats.cached` 推导输入 token 数。 + +只在需要时覆盖这些默认值(常见情况:使用绝对 `command` 路径)。 + +## 插件所有的默认值 + +CLI 后端默认值现在已成为插件表面的一部分: + +- 插件使用 `api.registerCliBackend(...)` 注册它们。 +- 后端 `id` 会成为模型引用中的提供商前缀。 +- 用户在 `agents.defaults.cliBackends.` 中的配置仍会覆盖插件默认值。 +- 后端特定的配置清理由插件通过可选的 + `normalizeConfig` hook 保持所有权。 + +## Bundle MCP 覆盖层 + +CLI 后端**不会**直接接收 OpenClaw 工具调用,但某个后端可以通过 +`bundleMcp: true` 选择启用自动生成的 MCP 配置覆盖层。 + +当前内置行为: + +- `codex-cli`:不提供 bundle MCP 覆盖层 +- `google-gemini-cli`:不提供 bundle MCP 覆盖层 + +启用 bundle MCP 时,OpenClaw 会: + +- 启动一个 loopback HTTP MCP 服务器,将 Gateway 网关工具暴露给 CLI 进程 +- 使用每会话令牌(`OPENCLAW_MCP_TOKEN`)对桥接进行身份验证 +- 将工具访问范围限定在当前会话、账户和渠道上下文内 +- 为当前工作区加载已启用的 bundle-MCP 服务器 +- 将它们与任何现有的后端 `--mcp-config` 合并 +- 重写 CLI 参数,传入 `--strict-mcp-config --mcp-config ` + +如果没有启用任何 MCP 服务器,当后端选择启用 bundle MCP 时,OpenClaw 仍会注入严格配置,以便后台运行保持隔离。 + +## 限制 + +- **没有直接的 OpenClaw 工具调用。** OpenClaw 不会将工具调用直接注入 + 到 CLI 后端协议中。只有当后端启用 + `bundleMcp: true` 时,它们才会看到 Gateway 网关工具。 +- **流式传输是后端特定的。** 某些后端会流式输出 JSONL;其他后端则会 + 缓冲到退出时再输出。 +- **结构化输出** 取决于 CLI 的 JSON 格式。 +- **Codex CLI 会话** 通过文本输出恢复(没有 JSONL),其结构化程度 + 低于初始的 `--json` 运行。但 OpenClaw 会话仍然可以 + 正常工作。 + +## 故障排除 + +- **找不到 CLI**:将 `command` 设置为完整路径。 +- **模型名称错误**:使用 `modelAliases` 将 `provider/model` 映射到 CLI 模型。 +- **没有会话连续性**:确保已设置 `sessionArg`,并且 `sessionMode` 不是 + `none`(Codex CLI 当前无法使用 JSON 输出进行恢复)。 +- **图片被忽略**:设置 `imageArg`(并确认 CLI 支持文件路径)。 diff --git a/docs/zh-CN/gateway/configuration-reference.md b/docs/zh-CN/gateway/configuration-reference.md index c1898ff99..b12eac731 100644 --- a/docs/zh-CN/gateway/configuration-reference.md +++ b/docs/zh-CN/gateway/configuration-reference.md @@ -1,56 +1,56 @@ --- read_when: - - 你需要精确到字段级别的配置语义或默认值 + - 你需要精确的字段级配置语义或默认值 - 你正在验证渠道、模型、Gateway 网关或工具配置块 summary: 每个 OpenClaw 配置键、默认值和渠道设置的完整参考 title: 配置参考 x-i18n: - generated_at: "2026-04-06T04:37:33Z" + generated_at: "2026-04-06T12:47:50Z" model: gpt-5.4 provider: openai - source_hash: 6ae6c19666f65433361e1c8b100ae710448c8aa055a60c140241a8aea09b98a5 + source_hash: 67e3197e2dca37f43285b8aa0e5c77ef1662e1ba28ee874d4e7cbc90e6160ca3 source_path: gateway/configuration-reference.md workflow: 15 --- # 配置参考 -`~/.openclaw/openclaw.json` 中可用的每个字段。若需按任务组织的概览,请参见 [Configuration](/zh-CN/gateway/configuration)。 +`~/.openclaw/openclaw.json` 中可用的每个字段。若要查看按任务组织的概览,请参见 [Configuration](/zh-CN/gateway/configuration)。 -配置格式为 **JSON5**(允许注释和尾随逗号)。所有字段都是可选的——省略时,OpenClaw 会使用安全的默认值。 +配置格式为 **JSON5**(允许注释和尾随逗号)。所有字段都是可选的 —— 省略时,OpenClaw 会使用安全的默认值。 --- ## 渠道 -每个渠道在其配置段存在时都会自动启动(除非设置了 `enabled: false`)。 +只要某个渠道的配置段存在,它就会自动启动(除非设置了 `enabled: false`)。 ### 私信和群组访问 所有渠道都支持私信策略和群组策略: -| 私信策略 | 行为 | -| ------------------- | ------------------------------------------------------------ | -| `pairing`(默认) | 未知发送者会收到一次性配对码;必须由所有者批准 | -| `allowlist` | 仅允许 `allowFrom`(或已配对允许存储)中的发送者 | -| `open` | 允许所有传入私信(需要 `allowFrom: ["*"]`) | -| `disabled` | 忽略所有传入私信 | +| 私信策略 | 行为 | +| ------------------- | ---------------------------------------------- | +| `pairing`(默认) | 未知发送者会收到一次性配对码;所有者必须批准 | +| `allowlist` | 仅允许 `allowFrom` 中的发送者(或已配对允许存储) | +| `open` | 允许所有入站私信(需要 `allowFrom: ["*"]`) | +| `disabled` | 忽略所有入站私信 | -| 群组策略 | 行为 | -| --------------------- | ------------------------------------------------------ | -| `allowlist`(默认) | 仅允许匹配已配置允许列表的群组 | -| `open` | 绕过群组允许列表(仍然应用提及门控) | -| `disabled` | 阻止所有群组/房间消息 | +| 群组策略 | 行为 | +| --------------------- | ---------------------------------------------- | +| `allowlist`(默认) | 仅允许与已配置允许列表匹配的群组 | +| `open` | 绕过群组允许列表(仍然适用提及门控) | +| `disabled` | 阻止所有群组/房间消息 | `channels.defaults.groupPolicy` 会在提供商的 `groupPolicy` 未设置时作为默认值。 -配对码会在 1 小时后过期。待处理的私信配对请求限制为**每个渠道 3 个**。 -如果某个提供商配置块完全缺失(`channels.` 不存在),运行时群组策略会回退为 `allowlist`(默认拒绝)并在启动时发出警告。 +配对码会在 1 小时后过期。待处理的私信配对请求在**每个渠道**中上限为 **3 个**。 +如果某个提供商配置块完全缺失(`channels.` 不存在),运行时群组策略会回退为 `allowlist`(失败即关闭),并在启动时发出警告。 ### 渠道模型覆盖 -使用 `channels.modelByChannel` 将特定渠道 ID 固定到某个模型。值可接受 `provider/model` 或已配置的模型别名。当会话尚未拥有模型覆盖时(例如通过 `/model` 设置),才会应用渠道映射。 +使用 `channels.modelByChannel` 将特定渠道 ID 固定到某个模型。值可接受 `provider/model` 或已配置的模型别名。当会话尚未有模型覆盖时(例如通过 `/model` 设置),会应用该渠道映射。 ```json5 { @@ -91,15 +91,15 @@ x-i18n: } ``` -- `channels.defaults.groupPolicy`:当提供商级 `groupPolicy` 未设置时的回退群组策略。 -- `channels.defaults.contextVisibility`:所有渠道的默认补充上下文可见性模式。取值:`all`(默认,包含所有引用/线程/历史上下文)、`allowlist`(仅包含允许列表发送者的上下文)、`allowlist_quote`(与 allowlist 相同,但保留显式引用/回复上下文)。单渠道覆盖:`channels..contextVisibility`。 +- `channels.defaults.groupPolicy`:当提供商级 `groupPolicy` 未设置时使用的后备群组策略。 +- `channels.defaults.contextVisibility`:所有渠道的默认补充上下文可见性模式。可选值:`all`(默认,包含所有引用/线程/历史上下文)、`allowlist`(仅包含允许列表发送者的上下文)、`allowlist_quote`(与 allowlist 相同,但保留显式引用/回复上下文)。每渠道覆盖:`channels..contextVisibility`。 - `channels.defaults.heartbeat.showOk`:在心跳输出中包含健康渠道状态。 - `channels.defaults.heartbeat.showAlerts`:在心跳输出中包含降级/错误状态。 -- `channels.defaults.heartbeat.useIndicator`:渲染紧凑的指示器样式心跳输出。 +- `channels.defaults.heartbeat.useIndicator`:以紧凑的指示器样式渲染心跳输出。 ### WhatsApp -WhatsApp 通过 Gateway 网关的 Web 渠道(Baileys Web)运行。存在已关联会话时会自动启动。 +WhatsApp 通过 Gateway 网关的 web 渠道(Baileys Web)运行。存在已关联会话时会自动启动。 ```json5 { @@ -150,10 +150,10 @@ WhatsApp 通过 Gateway 网关的 Web 渠道(Baileys Web)运行。存在已 } ``` -- 出站命令默认使用 `default` 账号(如果存在);否则使用第一个已配置账号 ID(排序后)。 -- 可选的 `channels.whatsapp.defaultAccount` 可在其匹配已配置账号 ID 时覆盖该默认账号选择。 -- 旧版单账号 Baileys 认证目录会由 `openclaw doctor` 迁移到 `whatsapp/default`。 -- 按账号覆盖:`channels.whatsapp.accounts..sendReadReceipts`、`channels.whatsapp.accounts..dmPolicy`、`channels.whatsapp.accounts..allowFrom`。 +- 出站命令默认使用 `default` 账号(如果存在);否则使用第一个已配置的账号 ID(排序后)。 +- 可选的 `channels.whatsapp.defaultAccount` 会在其匹配某个已配置账号 ID 时覆盖上述默认账号选择逻辑。 +- 旧版单账号 Baileys 认证目录会被 `openclaw doctor` 迁移到 `whatsapp/default`。 +- 每账号覆盖:`channels.whatsapp.accounts..sendReadReceipts`、`channels.whatsapp.accounts..dmPolicy`、`channels.whatsapp.accounts..allowFrom`。 @@ -211,11 +211,11 @@ WhatsApp 通过 Gateway 网关的 Web 渠道(Baileys Web)运行。存在已 } ``` -- Bot token:`channels.telegram.botToken` 或 `channels.telegram.tokenFile`(仅允许常规文件;拒绝符号链接),默认账号还可回退到 `TELEGRAM_BOT_TOKEN`。 -- 可选的 `channels.telegram.defaultAccount` 可在其匹配已配置账号 ID 时覆盖默认账号选择。 -- 在多账号设置(2 个及以上账号 ID)中,设置显式默认值(`channels.telegram.defaultAccount` 或 `channels.telegram.accounts.default`)以避免回退路由;若缺失或无效,`openclaw doctor` 会发出警告。 +- Bot token:`channels.telegram.botToken` 或 `channels.telegram.tokenFile`(仅接受常规文件;拒绝符号链接),默认账号可回退到 `TELEGRAM_BOT_TOKEN`。 +- 可选的 `channels.telegram.defaultAccount` 会在其匹配某个已配置账号 ID 时覆盖默认账号选择。 +- 在多账号设置(2 个及以上账号 ID)中,请设置显式默认值(`channels.telegram.defaultAccount` 或 `channels.telegram.accounts.default`),以避免回退路由;若缺失或无效,`openclaw doctor` 会发出警告。 - `configWrites: false` 会阻止由 Telegram 发起的配置写入(超级群组 ID 迁移、`/config set|unset`)。 -- 顶层 `bindings[]` 中带有 `type: "acp"` 的条目可为论坛话题配置持久 ACP 绑定(在 `match.peer.id` 中使用规范的 `chatId:topic:topicId`)。字段语义与 [ACP Agents](/zh-CN/tools/acp-agents#channel-specific-settings) 共享。 +- 顶层 `bindings[]` 中带有 `type: "acp"` 的条目可为论坛主题配置持久 ACP 绑定(在 `match.peer.id` 中使用规范格式 `chatId:topic:topicId`)。字段语义与 [ACP Agents](/zh-CN/tools/acp-agents#channel-specific-settings) 共享。 - Telegram 流式预览使用 `sendMessage` + `editMessageText`(在私聊和群聊中都可用)。 - 重试策略:参见 [Retry policy](/zh-CN/concepts/retry)。 @@ -320,35 +320,35 @@ WhatsApp 通过 Gateway 网关的 Web 渠道(Baileys Web)运行。存在已 ``` - Token:`channels.discord.token`,默认账号可回退到 `DISCORD_BOT_TOKEN`。 -- 提供显式 Discord `token` 的直接出站调用会使用该 token 发起调用;账号的重试/策略设置仍来自活动运行时快照中所选账号。 -- 可选的 `channels.discord.defaultAccount` 可在其匹配已配置账号 ID 时覆盖默认账号选择。 +- 提供显式 Discord `token` 的直接出站调用会为该调用使用这个 token;账号重试/策略设置仍然来自活动运行时快照中所选账号。 +- 可选的 `channels.discord.defaultAccount` 会在其匹配某个已配置账号 ID 时覆盖默认账号选择。 - 使用 `user:`(私信)或 `channel:`(服务器频道)作为投递目标;裸数字 ID 会被拒绝。 - 服务器 slug 为小写,空格替换为 `-`;频道键使用 slug 化后的名称(不含 `#`)。优先使用服务器 ID。 -- 机器人自己发出的消息默认会被忽略。`allowBots: true` 可启用;使用 `allowBots: "mentions"` 则仅接受提及机器人的机器人消息(自己的消息仍会被过滤)。 -- `channels.discord.guilds..ignoreOtherMentions`(以及频道级覆盖)会丢弃提及其他用户或角色但未提及机器人的消息(不包括 @everyone/@here)。 -- `maxLinesPerMessage`(默认 17)会拆分过高消息,即使它们未超过 2000 字符。 +- 默认会忽略机器人发送的消息。`allowBots: true` 可启用它们;使用 `allowBots: "mentions"` 则只接受提及机器人的机器人消息(仍会过滤自己的消息)。 +- `channels.discord.guilds..ignoreOtherMentions`(以及频道覆盖)会丢弃提及其他用户或角色但未提及机器人的消息(不包括 @everyone/@here)。 +- `maxLinesPerMessage`(默认 17)即使消息未超过 2000 字符,也会拆分过高的消息。 - `channels.discord.threadBindings` 控制 Discord 线程绑定路由: - `enabled`:线程绑定会话功能的 Discord 覆盖(`/focus`、`/unfocus`、`/agents`、`/session idle`、`/session max-age` 以及绑定投递/路由) - - `idleHours`:按小时计算的不活动自动取消焦点 Discord 覆盖(`0` 表示禁用) - - `maxAgeHours`:按小时计算的硬性最大存活时间 Discord 覆盖(`0` 表示禁用) + - `idleHours`:按小时计算的 Discord 不活跃自动取消聚焦覆盖(`0` 禁用) + - `maxAgeHours`:按小时计算的 Discord 硬性最大时长覆盖(`0` 禁用) - `spawnSubagentSessions`:为 `sessions_spawn({ thread: true })` 自动创建/绑定线程的显式启用开关 - 顶层 `bindings[]` 中带有 `type: "acp"` 的条目可为频道和线程配置持久 ACP 绑定(在 `match.peer.id` 中使用频道/线程 ID)。字段语义与 [ACP Agents](/zh-CN/tools/acp-agents#channel-specific-settings) 共享。 -- `channels.discord.ui.components.accentColor` 为 Discord components v2 容器设置强调色。 -- `channels.discord.voice` 启用 Discord 语音频道对话,以及可选的自动加入 + TTS 覆盖。 -- `channels.discord.voice.daveEncryption` 和 `channels.discord.voice.decryptionFailureTolerance` 会直接透传给 `@discordjs/voice` 的 DAVE 选项(默认分别为 `true` 和 `24`)。 -- OpenClaw 还会在重复解密失败后,通过离开/重新加入语音会话来尝试恢复语音接收。 -- `channels.discord.streaming` 是规范的流式模式键。旧版 `streamMode` 和布尔型 `streaming` 值会被自动迁移。 -- `channels.discord.autoPresence` 会将运行时可用性映射为机器人状态(健康 => online,降级 => idle,耗尽 => dnd),并允许可选状态文本覆盖。 -- `channels.discord.dangerouslyAllowNameMatching` 会重新启用可变名称/tag 匹配(破玻璃兼容模式)。 -- `channels.discord.execApprovals`:Discord 原生的 exec 批准投递和批准者授权。 - - `enabled`:`true`、`false` 或 `"auto"`(默认)。在自动模式下,当可从 `approvers` 或 `commands.ownerAllowFrom` 解析出批准者时,exec 批准会激活。 +- `channels.discord.ui.components.accentColor` 设置 Discord components v2 容器的强调色。 +- `channels.discord.voice` 启用 Discord 语音频道对话,以及可选的自动加入和 TTS 覆盖。 +- `channels.discord.voice.daveEncryption` 和 `channels.discord.voice.decryptionFailureTolerance` 会透传给 `@discordjs/voice` 的 DAVE 选项(默认分别为 `true` 和 `24`)。 +- OpenClaw 还会在反复解密失败后,通过离开/重新加入语音会话来尝试恢复语音接收。 +- `channels.discord.streaming` 是规范的流式模式键。旧版 `streamMode` 和布尔型 `streaming` 值会自动迁移。 +- `channels.discord.autoPresence` 会将运行时可用性映射为机器人状态(healthy => online,degraded => idle,exhausted => dnd),并允许可选状态文本覆盖。 +- `channels.discord.dangerouslyAllowNameMatching` 会重新启用可变的名称/tag 匹配(紧急兼容模式)。 +- `channels.discord.execApprovals`:Discord 原生 exec 审批投递和审批人授权。 + - `enabled`:`true`、`false` 或 `"auto"`(默认)。在自动模式下,当可从 `approvers` 或 `commands.ownerAllowFrom` 解析出审批人时,exec 审批会激活。 - `approvers`:允许批准 exec 请求的 Discord 用户 ID。省略时回退到 `commands.ownerAllowFrom`。 - - `agentFilter`:可选的智能体 ID 允许列表。省略则转发所有智能体的批准请求。 + - `agentFilter`:可选的智能体 ID 允许列表。省略则转发所有智能体的审批。 - `sessionFilter`:可选的会话键模式(子串或正则)。 - - `target`:批准提示发送位置。`"dm"`(默认)发送到批准者私信,`"channel"` 发送到原始频道,`"both"` 同时发送。若 target 包含 `"channel"`,按钮仅对已解析出的批准者可用。 - - `cleanupAfterResolve`:设为 `true` 时,在批准、拒绝或超时后删除批准私信。 + - `target`:审批提示发送位置。`"dm"`(默认)发送到审批人私信,`"channel"` 发送到原始频道,`"both"` 两边都发送。当目标包含 `"channel"` 时,按钮仅对已解析出的审批人可用。 + - `cleanupAfterResolve`:为 `true` 时,在批准、拒绝或超时后删除审批私信。 -**反应通知模式:** `off`(无)、`own`(机器人的消息,默认)、`all`(所有消息)、`allowlist`(来自 `guilds..users` 的所有消息)。 +**表情通知模式:** `off`(无)、`own`(机器人自己的消息,默认)、`all`(所有消息)、`allowlist`(针对所有消息中的 `guilds..users`)。 ### Google Chat @@ -383,7 +383,7 @@ WhatsApp 通过 Gateway 网关的 Web 渠道(Baileys Web)运行。存在已 - 也支持服务账号 SecretRef(`serviceAccountRef`)。 - 环境变量回退:`GOOGLE_CHAT_SERVICE_ACCOUNT` 或 `GOOGLE_CHAT_SERVICE_ACCOUNT_FILE`。 - 使用 `spaces/` 或 `users/` 作为投递目标。 -- `channels.googlechat.dangerouslyAllowNameMatching` 会重新启用可变电子邮件主体匹配(破玻璃兼容模式)。 +- `channels.googlechat.dangerouslyAllowNameMatching` 会重新启用可变电子邮件主体匹配(紧急兼容模式)。 ### Slack @@ -449,36 +449,36 @@ WhatsApp 通过 Gateway 网关的 Web 渠道(Baileys Web)运行。存在已 ``` - **Socket mode** 需要同时提供 `botToken` 和 `appToken`(默认账号的环境变量回退为 `SLACK_BOT_TOKEN` + `SLACK_APP_TOKEN`)。 -- **HTTP mode** 需要 `botToken` 加 `signingSecret`(可在根级或每账号级设置)。 -- `botToken`、`appToken`、`signingSecret` 和 `userToken` 可接受明文字符串 - 或 SecretRef 对象。 -- Slack 账号快照会暴露按凭证分类的来源/状态字段,例如 - `botTokenSource`、`botTokenStatus`、`appTokenStatus`,以及在 HTTP mode 下的 +- **HTTP mode** 需要 `botToken` 加 `signingSecret`(位于根级或每账号级)。 +- `botToken`、`appToken`、`signingSecret` 和 `userToken` 接受明文 + 字符串或 SecretRef 对象。 +- Slack 账号快照会暴露每项凭证的来源/状态字段,例如 + `botTokenSource`、`botTokenStatus`、`appTokenStatus`,以及在 HTTP 模式下的 `signingSecretStatus`。`configured_unavailable` 表示该账号通过 SecretRef 配置,但当前命令/运行时路径无法解析该 secret 值。 -- `configWrites: false` 会阻止由 Slack 发起的配置写入。 -- 可选的 `channels.slack.defaultAccount` 可在其匹配已配置账号 ID 时覆盖默认账号选择。 -- `channels.slack.streaming` 是规范的流式模式键。旧版 `streamMode` 和布尔型 `streaming` 值会被自动迁移。 +- `configWrites: false` 会阻止 Slack 发起的配置写入。 +- 可选的 `channels.slack.defaultAccount` 会在其匹配某个已配置账号 ID 时覆盖默认账号选择。 +- `channels.slack.streaming` 是规范的流式模式键。旧版 `streamMode` 和布尔型 `streaming` 值会自动迁移。 - 使用 `user:`(私信)或 `channel:` 作为投递目标。 -**反应通知模式:** `off`、`own`(默认)、`all`、`allowlist`(来自 `reactionAllowlist`)。 +**表情通知模式:** `off`、`own`(默认)、`all`、`allowlist`(来自 `reactionAllowlist`)。 -**线程会话隔离:** `thread.historyScope` 可设置为每线程(默认)或按频道共享。`thread.inheritParent` 会将父频道转录复制到新线程。 +**线程会话隔离:** `thread.historyScope` 为每线程(默认)或在整个频道内共享。`thread.inheritParent` 会把父频道转录内容复制到新线程。 -- `typingReaction` 会在回复执行期间,为传入 Slack 消息添加临时反应,并在完成后移除。使用 Slack emoji 简码,例如 `"hourglass_flowing_sand"`。 -- `channels.slack.execApprovals`:Slack 原生的 exec 批准投递和批准者授权。与 Discord 使用相同 schema:`enabled`(`true`/`false`/`"auto"`)、`approvers`(Slack 用户 ID)、`agentFilter`、`sessionFilter` 和 `target`(`"dm"`、`"channel"` 或 `"both"`)。 +- `typingReaction` 会在回复运行期间,临时给入站 Slack 消息添加一个表情,完成后移除。使用 Slack emoji 简码,例如 `"hourglass_flowing_sand"`。 +- `channels.slack.execApprovals`:Slack 原生 exec 审批投递和审批人授权。与 Discord 使用相同模式:`enabled`(`true`/`false`/`"auto"`)、`approvers`(Slack 用户 ID)、`agentFilter`、`sessionFilter` 和 `target`(`"dm"`、`"channel"` 或 `"both"`)。 -| 操作组 | 默认值 | 说明 | -| ------------ | -------- | ---------------------- | -| reactions | enabled | 反应 + 列出反应 | -| messages | enabled | 读取/发送/编辑/删除 | -| pins | enabled | 固定/取消固定/列出 | -| memberInfo | enabled | 成员信息 | -| emojiList | enabled | 自定义 emoji 列表 | +| 操作组 | 默认值 | 说明 | +| ------------ | -------- | ------------------ | +| reactions | 启用 | 添加表情 + 列出表情 | +| messages | 启用 | 读取/发送/编辑/删除 | +| pins | 启用 | 置顶/取消置顶/列出 | +| memberInfo | 启用 | 成员信息 | +| emojiList | 启用 | 自定义 emoji 列表 | ### Mattermost -Mattermost 以插件形式提供:`openclaw plugins install @openclaw/mattermost`。 +Mattermost 作为插件提供:`openclaw plugins install @openclaw/mattermost`。 ```json5 { @@ -513,16 +513,17 @@ Mattermost 以插件形式提供:`openclaw plugins install @openclaw/mattermos 启用 Mattermost 原生命令时: - `commands.callbackPath` 必须是路径(例如 `/api/channels/mattermost/command`),不能是完整 URL。 -- `commands.callbackUrl` 必须解析到 OpenClaw Gateway 网关端点,并且 Mattermost 服务器可访问。 -- 原生斜杠命令回调使用 Mattermost 在斜杠命令注册期间返回的每命令 token 进行身份验证。如果注册失败或没有激活任何命令,OpenClaw 会以 - `Unauthorized: invalid command token.` 拒绝回调。 -- 对于私有/tailnet/内部回调主机,Mattermost 可能要求 +- `commands.callbackUrl` 必须解析到 OpenClaw Gateway 网关端点,并且 Mattermost 服务器可以访问。 +- 原生 slash 回调使用 Mattermost 在 slash 命令注册期间返回的每命令 token + 进行身份验证。如果注册失败或没有命令被激活,OpenClaw 会拒绝回调,并返回 + `Unauthorized: invalid command token.` +- 对于私有/tailnet/internal 回调主机,Mattermost 可能要求 `ServiceSettings.AllowedUntrustedInternalConnections` 包含回调主机/域名。 - 使用主机/域名值,而不是完整 URL。 -- `channels.mattermost.configWrites`:允许或拒绝由 Mattermost 发起的配置写入。 -- `channels.mattermost.requireMention`:在频道中回复前要求 `@mention`。 -- `channels.mattermost.groups..requireMention`:按频道设置的提及门控覆盖(`"*"` 用作默认值)。 -- 可选的 `channels.mattermost.defaultAccount` 可在其匹配已配置账号 ID 时覆盖默认账号选择。 + 请使用主机/域名值,而不是完整 URL。 +- `channels.mattermost.configWrites`:允许或拒绝 Mattermost 发起的配置写入。 +- `channels.mattermost.requireMention`:在频道中回复前要求有 `@mention`。 +- `channels.mattermost.groups..requireMention`:每频道提及门控覆盖(`"*"` 为默认值)。 +- 可选的 `channels.mattermost.defaultAccount` 会在其匹配某个已配置账号 ID 时覆盖默认账号选择。 ### Signal @@ -543,15 +544,15 @@ Mattermost 以插件形式提供:`openclaw plugins install @openclaw/mattermos } ``` -**反应通知模式:** `off`、`own`(默认)、`all`、`allowlist`(来自 `reactionAllowlist`)。 +**表情通知模式:** `off`、`own`(默认)、`all`、`allowlist`(来自 `reactionAllowlist`)。 -- `channels.signal.account`:将渠道启动固定到特定 Signal 账号身份。 -- `channels.signal.configWrites`:允许或拒绝由 Signal 发起的配置写入。 -- 可选的 `channels.signal.defaultAccount` 可在其匹配已配置账号 ID 时覆盖默认账号选择。 +- `channels.signal.account`:将渠道启动固定到特定 Signal 账号标识。 +- `channels.signal.configWrites`:允许或拒绝 Signal 发起的配置写入。 +- 可选的 `channels.signal.defaultAccount` 会在其匹配某个已配置账号 ID 时覆盖默认账号选择。 ### BlueBubbles -BlueBubbles 是推荐的 iMessage 路径(插件支持,在 `channels.bluebubbles` 下配置)。 +BlueBubbles 是推荐的 iMessage 路径(由插件支持,在 `channels.bluebubbles` 下配置)。 ```json5 { @@ -567,9 +568,9 @@ BlueBubbles 是推荐的 iMessage 路径(插件支持,在 `channels.bluebubb ``` - 此处涵盖的核心键路径:`channels.bluebubbles`、`channels.bluebubbles.dmPolicy`。 -- 可选的 `channels.bluebubbles.defaultAccount` 可在其匹配已配置账号 ID 时覆盖默认账号选择。 -- 顶层 `bindings[]` 中带有 `type: "acp"` 的条目可将 BlueBubbles 会话绑定到持久 ACP 会话。在 `match.peer.id` 中使用 BlueBubbles handle 或目标字符串(`chat_id:*`、`chat_guid:*`、`chat_identifier:*`)。共享字段语义: [ACP Agents](/zh-CN/tools/acp-agents#channel-specific-settings)。 -- 完整的 BlueBubbles 渠道配置记录在 [BlueBubbles](/zh-CN/channels/bluebubbles)。 +- 可选的 `channels.bluebubbles.defaultAccount` 会在其匹配某个已配置账号 ID 时覆盖默认账号选择。 +- 顶层 `bindings[]` 中带有 `type: "acp"` 的条目可将 BlueBubbles 对话绑定到持久 ACP 会话。在 `match.peer.id` 中使用 BlueBubbles handle 或目标字符串(`chat_id:*`、`chat_guid:*`、`chat_identifier:*`)。共享字段语义: [ACP Agents](/zh-CN/tools/acp-agents#channel-specific-settings)。 +- 完整 BlueBubbles 渠道配置记录于 [BlueBubbles](/zh-CN/channels/bluebubbles)。 ### iMessage @@ -597,17 +598,17 @@ OpenClaw 会启动 `imsg rpc`(通过 stdio 的 JSON-RPC)。不需要守护 } ``` -- 可选的 `channels.imessage.defaultAccount` 可在其匹配已配置账号 ID 时覆盖默认账号选择。 +- 可选的 `channels.imessage.defaultAccount` 会在其匹配某个已配置账号 ID 时覆盖默认账号选择。 -- 需要对 Messages DB 具有完整磁盘访问权限。 -- 优先使用 `chat_id:` 目标。使用 `imsg chats --limit 20` 列出聊天。 -- `cliPath` 可以指向 SSH 包装脚本;设置 `remoteHost`(`host` 或 `user@host`)以通过 SCP 获取附件。 -- `attachmentRoots` 和 `remoteAttachmentRoots` 会限制传入附件路径(默认:`/Users/*/Library/Messages/Attachments`)。 -- SCP 使用严格的主机密钥检查,因此请确保中继主机密钥已存在于 `~/.ssh/known_hosts` 中。 -- `channels.imessage.configWrites`:允许或拒绝由 iMessage 发起的配置写入。 -- 顶层 `bindings[]` 中带有 `type: "acp"` 的条目可将 iMessage 会话绑定到持久 ACP 会话。在 `match.peer.id` 中使用规范化 handle 或显式聊天目标(`chat_id:*`、`chat_guid:*`、`chat_identifier:*`)。共享字段语义: [ACP Agents](/zh-CN/tools/acp-agents#channel-specific-settings)。 +- 需要对 Messages 数据库授予完全磁盘访问权限。 +- 优先使用 `chat_id:` 目标。可用 `imsg chats --limit 20` 列出聊天。 +- `cliPath` 可以指向 SSH 包装器;为 SCP 附件抓取设置 `remoteHost`(`host` 或 `user@host`)。 +- `attachmentRoots` 和 `remoteAttachmentRoots` 会限制入站附件路径(默认:`/Users/*/Library/Messages/Attachments`)。 +- SCP 使用严格主机密钥检查,因此请确保中继主机密钥已存在于 `~/.ssh/known_hosts` 中。 +- `channels.imessage.configWrites`:允许或拒绝 iMessage 发起的配置写入。 +- 顶层 `bindings[]` 中带有 `type: "acp"` 的条目可将 iMessage 对话绑定到持久 ACP 会话。在 `match.peer.id` 中使用标准化 handle 或显式聊天目标(`chat_id:*`、`chat_guid:*`、`chat_identifier:*`)。共享字段语义:[ACP Agents](/zh-CN/tools/acp-agents#channel-specific-settings)。 - + ```bash #!/usr/bin/env bash @@ -618,7 +619,7 @@ exec ssh -T gateway-host imsg "$@" ### Matrix -Matrix 由扩展提供支持,并在 `channels.matrix` 下配置。 +Matrix 由扩展支持,在 `channels.matrix` 下配置。 ```json5 { @@ -649,23 +650,23 @@ Matrix 由扩展提供支持,并在 `channels.matrix` 下配置。 ``` - Token 身份验证使用 `accessToken`;密码身份验证使用 `userId` + `password`。 -- `channels.matrix.proxy` 通过显式 HTTP(S) 代理转发 Matrix HTTP 流量。命名账号可通过 `channels.matrix.accounts..proxy` 覆盖。 -- `channels.matrix.allowPrivateNetwork` 允许私有/内部 homeserver。`proxy` 与 `allowPrivateNetwork` 是相互独立的控制项。 +- `channels.matrix.proxy` 会让 Matrix HTTP 流量通过显式 HTTP(S) 代理。命名账号可通过 `channels.matrix.accounts..proxy` 覆盖它。 +- `channels.matrix.allowPrivateNetwork` 允许私有/internal homeserver。`proxy` 和 `allowPrivateNetwork` 是相互独立的控制项。 - `channels.matrix.defaultAccount` 在多账号设置中选择首选账号。 -- `channels.matrix.execApprovals`:Matrix 原生的 exec 批准投递和批准者授权。 - - `enabled`:`true`、`false` 或 `"auto"`(默认)。在自动模式下,当可从 `approvers` 或 `commands.ownerAllowFrom` 解析出批准者时,exec 批准会激活。 +- `channels.matrix.execApprovals`:Matrix 原生 exec 审批投递和审批人授权。 + - `enabled`:`true`、`false` 或 `"auto"`(默认)。在自动模式下,当可从 `approvers` 或 `commands.ownerAllowFrom` 解析出审批人时,exec 审批会激活。 - `approvers`:允许批准 exec 请求的 Matrix 用户 ID(例如 `@owner:example.org`)。 - - `agentFilter`:可选的智能体 ID 允许列表。省略则转发所有智能体的批准请求。 + - `agentFilter`:可选的智能体 ID 允许列表。省略则转发所有智能体的审批。 - `sessionFilter`:可选的会话键模式(子串或正则)。 - - `target`:批准提示发送位置。`"dm"`(默认)、`"channel"`(原始房间)或 `"both"`。 - - 按账号覆盖:`channels.matrix.accounts..execApprovals`。 -- `channels.matrix.dm.sessionScope` 控制 Matrix 私信如何归入会话:`per-user`(默认)按路由 peer 共享,`per-room` 将每个私信房间隔离开。 -- Matrix 状态探测和实时目录查找使用与运行时流量相同的代理策略。 -- 完整的 Matrix 配置、目标规则和设置示例记录在 [Matrix](/zh-CN/channels/matrix)。 + - `target`:审批提示发送位置。`"dm"`(默认)、`"channel"`(原房间)或 `"both"`。 + - 每账号覆盖:`channels.matrix.accounts..execApprovals`。 +- `channels.matrix.dm.sessionScope` 控制 Matrix 私信如何归入会话:`per-user`(默认)按路由对端共享,`per-room` 为每个私信房间单独隔离。 +- Matrix 状态探测和实时目录查找与运行时流量使用相同的代理策略。 +- 完整的 Matrix 配置、目标规则和设置示例记录于 [Matrix](/zh-CN/channels/matrix)。 ### Microsoft Teams -Microsoft Teams 由扩展提供支持,并在 `channels.msteams` 下配置。 +Microsoft Teams 由扩展支持,在 `channels.msteams` 下配置。 ```json5 { @@ -681,11 +682,11 @@ Microsoft Teams 由扩展提供支持,并在 `channels.msteams` 下配置。 ``` - 此处涵盖的核心键路径:`channels.msteams`、`channels.msteams.configWrites`。 -- 完整的 Teams 配置(凭证、webhook、私信/群组策略、按团队/频道覆盖)记录在 [Microsoft Teams](/zh-CN/channels/msteams)。 +- 完整 Teams 配置(凭证、webhook、私信/群组策略、每团队/每频道覆盖)记录于 [Microsoft Teams](/zh-CN/channels/msteams)。 ### IRC -IRC 由扩展提供支持,并在 `channels.irc` 下配置。 +IRC 由扩展支持,在 `channels.irc` 下配置。 ```json5 { @@ -707,8 +708,8 @@ IRC 由扩展提供支持,并在 `channels.irc` 下配置。 ``` - 此处涵盖的核心键路径:`channels.irc`、`channels.irc.dmPolicy`、`channels.irc.configWrites`、`channels.irc.nickserv.*`。 -- 可选的 `channels.irc.defaultAccount` 可在其匹配已配置账号 ID 时覆盖默认账号选择。 -- 完整的 IRC 渠道配置(主机/端口/TLS/频道/允许列表/提及门控)记录在 [IRC](/zh-CN/channels/irc)。 +- 可选的 `channels.irc.defaultAccount` 会在其匹配某个已配置账号 ID 时覆盖默认账号选择。 +- 完整 IRC 渠道配置(host/port/TLS/channels/allowlists/提及门控)记录于 [IRC](/zh-CN/channels/irc)。 ### 多账号(所有渠道) @@ -733,17 +734,17 @@ IRC 由扩展提供支持,并在 `channels.irc` 下配置。 } ``` -- 当省略 `accountId` 时,使用 `default`(CLI + 路由)。 -- 环境变量 token 仅适用于**默认**账号。 -- 基础渠道设置会应用到所有账号,除非在每账号级别被覆盖。 +- 省略 `accountId` 时使用 `default`(CLI + 路由)。 +- 环境变量 token 仅适用于 **default** 账号。 +- 基础渠道设置会应用到所有账号,除非在账号级单独覆盖。 - 使用 `bindings[].match.accountId` 将每个账号路由到不同智能体。 -- 如果你在仍为单账号顶层渠道配置时,通过 `openclaw channels add`(或渠道新手引导)添加非默认账号,OpenClaw 会先将账号作用域的顶层单账号值提升到渠道账号映射中,以确保原账号继续工作。大多数渠道会将其移到 `channels..accounts.default`;Matrix 则可以保留现有匹配的命名/默认目标。 -- 现有的仅渠道绑定(无 `accountId`)仍会匹配默认账号;账号作用域绑定仍是可选的。 -- `openclaw doctor --fix` 也会通过将账号作用域的顶层单账号值移动到为该渠道选定的提升后账号中来修复混合形状。大多数渠道使用 `accounts.default`;Matrix 则可以保留现有匹配的命名/默认目标。 +- 如果你在仍使用单账号顶层渠道配置时,通过 `openclaw channels add`(或渠道新手引导)添加了一个非默认账号,OpenClaw 会先把带账号作用域的顶层单账号值提升到渠道账号映射中,以便原始账号继续工作。多数渠道会把它们移到 `channels..accounts.default`;Matrix 则可以保留现有匹配的命名/default 目标。 +- 现有仅渠道级绑定(无 `accountId`)仍会匹配默认账号;账号级绑定仍然是可选的。 +- `openclaw doctor --fix` 也会修复混合结构:把带账号作用域的顶层单账号值移动到为该渠道选定的提升账号中。多数渠道使用 `accounts.default`;Matrix 则可以保留现有匹配的命名/default 目标。 ### 其他扩展渠道 -许多扩展渠道配置为 `channels.`,并在其专用渠道页面中记录(例如 Feishu、Matrix、LINE、Nostr、Zalo、Nextcloud Talk、Synology Chat 和 Twitch)。 +许多扩展渠道配置为 `channels.`,并在各自的专用渠道页面中有文档说明(例如 Feishu、Matrix、LINE、Nostr、Zalo、Nextcloud Talk、Synology Chat 和 Twitch)。 请参见完整渠道索引:[Channels](/zh-CN/channels)。 ### 群聊提及门控 @@ -752,9 +753,9 @@ IRC 由扩展提供支持,并在 `channels.irc` 下配置。 **提及类型:** -- **元数据提及**:原生平台 @ 提及。在 WhatsApp 自聊模式下会被忽略。 -- **文本模式**:`agents.list[].groupChat.mentionPatterns` 中的安全正则模式。无效模式和不安全的嵌套重复会被忽略。 -- 仅在可以检测到提及时(原生提及或至少一个模式),才会强制执行提及门控。 +- **元数据提及**:平台原生 @ 提及。在 WhatsApp 自聊模式中会被忽略。 +- **文本模式**:位于 `agents.list[].groupChat.mentionPatterns` 中的安全正则模式。无效模式和不安全的嵌套重复会被忽略。 +- 只有在能够检测到提及的情况下(原生提及或至少有一个模式)才会强制执行提及门控。 ```json5 { @@ -767,7 +768,7 @@ IRC 由扩展提供支持,并在 `channels.irc` 下配置。 } ``` -`messages.groupChat.historyLimit` 设置全局默认值。渠道可通过 `channels..historyLimit`(或按账号)覆盖。设置为 `0` 以禁用。 +`messages.groupChat.historyLimit` 设置全局默认值。渠道可通过 `channels..historyLimit`(或每账号)覆盖。设置为 `0` 可禁用。 #### 私信历史限制 @@ -784,13 +785,13 @@ IRC 由扩展提供支持,并在 `channels.irc` 下配置。 } ``` -解析顺序:按私信覆盖 → 提供商默认值 → 不限制(全部保留)。 +解析顺序:每私信覆盖 → 提供商默认值 → 无限制(全部保留)。 支持:`telegram`、`whatsapp`、`discord`、`slack`、`signal`、`imessage`、`msteams`。 #### 自聊模式 -将你自己的号码包含在 `allowFrom` 中以启用自聊模式(忽略原生 @ 提及,仅响应文本模式): +把你自己的号码加入 `allowFrom` 即可启用自聊模式(忽略原生 @ 提及,仅响应文本模式): ```json5 { @@ -811,7 +812,7 @@ IRC 由扩展提供支持,并在 `channels.irc` 下配置。 } ``` -### Commands(聊天命令处理) +### 命令(聊天命令处理) ```json5 { @@ -835,15 +836,15 @@ IRC 由扩展提供支持,并在 `channels.irc` 下配置。 - 文本命令必须是带前导 `/` 的**独立**消息。 -- `native: "auto"` 会为 Discord/Telegram 打开原生命令,而对 Slack 保持关闭。 -- 按渠道覆盖:`channels.discord.commands.native`(布尔值或 `"auto"`)。`false` 会清除先前已注册的命令。 -- `channels.telegram.customCommands` 会添加额外的 Telegram 机器人菜单项。 -- `bash: true` 启用宿主 shell 的 `! `。要求 `tools.elevated.enabled` 且发送者在 `tools.elevated.allowFrom.` 中。 -- `config: true` 启用 `/config`(读取/写入 `openclaw.json`)。对于 Gateway 网关 `chat.send` 客户端,持久化的 `/config set|unset` 写入还要求 `operator.admin`;只读的 `/config show` 对普通写作用域 operator 客户端仍然可用。 -- `channels..configWrites` 控制每个渠道的配置变更(默认:true)。 -- 对于多账号渠道,`channels..accounts..configWrites` 也会控制针对该账号的写入(例如 `/allowlist --config --account ` 或 `/config set channels..accounts....`)。 -- `allowFrom` 按提供商生效。设置后,它会成为**唯一**授权来源(渠道允许列表/配对和 `useAccessGroups` 都会被忽略)。 -- `useAccessGroups: false` 会在 `allowFrom` 未设置时,允许命令绕过访问组策略。 +- `native: "auto"` 会为 Discord/Telegram 打开原生命令,而将 Slack 保持关闭。 +- 可按渠道覆盖:`channels.discord.commands.native`(布尔值或 `"auto"`)。`false` 会清除之前已注册的命令。 +- `channels.telegram.customCommands` 会添加额外 Telegram 机器人菜单项。 +- `bash: true` 启用主机 shell 的 `! `(别名:`/bash`)。需要 `tools.elevated.enabled`,并且发送者位于 `tools.elevated.allowFrom.` 中。 +- `config: true` 启用 `/config`(读取/写入 `openclaw.json`)。对于 Gateway 网关 `chat.send` 客户端,持久化的 `/config set|unset` 写入还需要 `operator.admin`;只读的 `/config show` 对普通具有写作用域的 operator 客户端仍可用。 +- `channels..configWrites` 按渠道控制配置修改(默认:true)。 +- 对于多账号渠道,`channels..accounts..configWrites` 也会控制以该账号为目标的写入(例如 `/allowlist --config --account ` 或 `/config set channels..accounts....`)。 +- `allowFrom` 按提供商生效。设置后,它会成为**唯一**的授权来源(会忽略渠道允许列表/配对和 `useAccessGroups`)。 +- 当未设置 `allowFrom` 时,`useAccessGroups: false` 允许命令绕过访问组策略。 @@ -863,7 +864,7 @@ IRC 由扩展提供支持,并在 `channels.irc` 下配置。 ### `agents.defaults.repoRoot` -可选的仓库根目录,会显示在系统提示的 Runtime 行中。若未设置,OpenClaw 会从工作区向上遍历自动检测。 +可选的仓库根目录,会显示在系统提示的 Runtime 行中。若未设置,OpenClaw 会从工作区开始向上遍历自动检测。 ```json5 { @@ -873,7 +874,7 @@ IRC 由扩展提供支持,并在 `channels.irc` 下配置。 ### `agents.defaults.skills` -为未设置 `agents.list[].skills` 的智能体提供可选的默认 Skills 允许列表。 +为未设置 `agents.list[].skills` 的智能体提供可选默认 Skills 允许列表。 ```json5 { @@ -888,14 +889,15 @@ IRC 由扩展提供支持,并在 `channels.irc` 下配置。 } ``` -- 省略 `agents.defaults.skills` 表示默认 Skills 不受限制。 -- 省略 `agents.list[].skills` 则继承默认值。 -- 设置 `agents.list[].skills: []` 表示不允许任何 Skills。 -- 非空的 `agents.list[].skills` 列表就是该智能体的最终集合;不会与默认值合并。 +- 省略 `agents.defaults.skills` 表示默认不限制 Skills。 +- 省略 `agents.list[].skills` 表示继承默认值。 +- 设置 `agents.list[].skills: []` 表示不启用任何 Skills。 +- 非空的 `agents.list[].skills` 列表会成为该智能体的最终集合;它 + 不会与默认值合并。 ### `agents.defaults.skipBootstrap` -禁用工作区 bootstrap 文件的自动创建(`AGENTS.md`、`SOUL.md`、`TOOLS.md`、`IDENTITY.md`、`USER.md`、`HEARTBEAT.md`、`BOOTSTRAP.md`)。 +禁用工作区引导文件(`AGENTS.md`、`SOUL.md`、`TOOLS.md`、`IDENTITY.md`、`USER.md`、`HEARTBEAT.md`、`BOOTSTRAP.md`)的自动创建。 ```json5 { @@ -905,9 +907,9 @@ IRC 由扩展提供支持,并在 `channels.irc` 下配置。 ### `agents.defaults.contextInjection` -控制何时将工作区 bootstrap 文件注入系统提示。默认值:`"always"`。 +控制何时将工作区引导文件注入到系统提示中。默认值:`"always"`。 -- `"continuation-skip"`:安全续写轮次(在助手完成响应之后)会跳过重新注入工作区 bootstrap,从而减少提示大小。心跳运行和压缩后重试仍会重建上下文。 +- `"continuation-skip"`:安全续接轮次(在助手完成一次响应之后)会跳过重新注入工作区引导内容,从而减小提示大小。心跳运行和压缩后的重试仍会重建上下文。 ```json5 { @@ -917,7 +919,7 @@ IRC 由扩展提供支持,并在 `channels.irc` 下配置。 ### `agents.defaults.bootstrapMaxChars` -工作区每个 bootstrap 文件在被截断前允许的最大字符数。默认值:`20000`。 +每个工作区引导文件在截断前的最大字符数。默认值:`20000`。 ```json5 { @@ -927,7 +929,7 @@ IRC 由扩展提供支持,并在 `channels.irc` 下配置。 ### `agents.defaults.bootstrapTotalMaxChars` -所有工作区 bootstrap 文件合计注入的最大字符数。默认值:`150000`。 +注入的所有工作区引导文件的总最大字符数。默认值:`150000`。 ```json5 { @@ -937,11 +939,11 @@ IRC 由扩展提供支持,并在 `channels.irc` 下配置。 ### `agents.defaults.bootstrapPromptTruncationWarning` -控制当 bootstrap 上下文被截断时,对智能体可见的警告文本。 +控制在引导上下文被截断时,是否向智能体可见地注入警告文本。 默认值:`"once"`。 - `"off"`:绝不将警告文本注入系统提示。 -- `"once"`:对每个唯一的截断签名只注入一次警告(推荐)。 +- `"once"`:对每个唯一的截断签名注入一次警告(推荐)。 - `"always"`:只要存在截断,每次运行都注入警告。 ```json5 @@ -952,11 +954,11 @@ IRC 由扩展提供支持,并在 `channels.irc` 下配置。 ### `agents.defaults.imageMaxDimensionPx` -在调用提供商之前,转录/工具图片块中图像最长边的最大像素尺寸。 +在调用提供商之前,转录/工具图片块中最长边的最大像素尺寸。 默认值:`1200`。 -较低的值通常会减少视觉 token 使用量和请求负载大小,特别适合截图较多的运行。 -较高的值则保留更多视觉细节。 +较低的值通常会减少视觉 token 使用量和请求负载大小,尤其适用于大量截图的运行。 +较高的值会保留更多视觉细节。 ```json5 { @@ -966,7 +968,7 @@ IRC 由扩展提供支持,并在 `channels.irc` 下配置。 ### `agents.defaults.userTimezone` -系统提示上下文所用时区(不影响消息时间戳)。会回退到宿主机时区。 +系统提示上下文所用的时区(不是消息时间戳)。会回退到主机时区。 ```json5 { @@ -1029,43 +1031,43 @@ IRC 由扩展提供支持,并在 `channels.irc` 下配置。 } ``` -- `model`:可接受字符串(`"provider/model"`)或对象(`{ primary, fallbacks }`)。 +- `model`:接受字符串(`"provider/model"`)或对象(`{ primary, fallbacks }`)。 - 字符串形式只设置主模型。 - - 对象形式设置主模型及有序故障转移模型。 -- `imageModel`:可接受字符串(`"provider/model"`)或对象(`{ primary, fallbacks }`)。 - - 由 `image` 工具路径作为其视觉模型配置使用。 - - 当选定/默认模型无法接受图像输入时,也作为回退路由使用。 -- `imageGenerationModel`:可接受字符串(`"provider/model"`)或对象(`{ primary, fallbacks }`)。 - - 由共享图像生成能力以及任何未来会生成图像的工具/插件接口使用。 - - 典型值:`google/gemini-3.1-flash-image-preview`(Gemini 原生图像生成)、`fal/fal-ai/flux/dev`(fal)或 `openai/gpt-image-1`(OpenAI Images)。 - - 如果你直接选择某个提供商/模型,也要配置对应的提供商身份验证/API key(例如 `google/*` 需要 `GEMINI_API_KEY` 或 `GOOGLE_API_KEY`,`openai/*` 需要 `OPENAI_API_KEY`,`fal/*` 需要 `FAL_KEY`)。 - - 如果省略,`image_generate` 仍然可以推断出基于身份验证的提供商默认值。它会先尝试当前默认提供商,然后按提供商 ID 顺序尝试其余已注册的图像生成提供商。 -- `musicGenerationModel`:可接受字符串(`"provider/model"`)或对象(`{ primary, fallbacks }`)。 - - 由共享音乐生成能力和内置 `music_generate` 工具使用。 - - 典型值:`google/lyria-3-clip-preview`、`google/lyria-3-pro-preview` 或 `minimax/music-2.5+`。 - - 如果省略,`music_generate` 仍然可以推断出基于身份验证的提供商默认值。它会先尝试当前默认提供商,然后按提供商 ID 顺序尝试其余已注册的音乐生成提供商。 - - 如果你直接选择某个提供商/模型,也要配置对应的提供商身份验证/API key。 -- `videoGenerationModel`:可接受字符串(`"provider/model"`)或对象(`{ primary, fallbacks }`)。 - - 由共享视频生成能力和内置 `video_generate` 工具使用。 - - 典型值:`qwen/wan2.6-t2v`、`qwen/wan2.6-i2v`、`qwen/wan2.6-r2v`、`qwen/wan2.6-r2v-flash` 或 `qwen/wan2.7-r2v`。 - - 如果省略,`video_generate` 仍然可以推断出基于身份验证的提供商默认值。它会先尝试当前默认提供商,然后按提供商 ID 顺序尝试其余已注册的视频生成提供商。 - - 如果你直接选择某个提供商/模型,也要配置对应的提供商身份验证/API key。 - - 当前内置的 Qwen 视频生成提供商最多支持 1 个输出视频、1 张输入图片、4 个输入视频、10 秒时长,以及提供商级 `size`、`aspectRatio`、`resolution`、`audio` 和 `watermark` 选项。 -- `pdfModel`:可接受字符串(`"provider/model"`)或对象(`{ primary, fallbacks }`)。 - - 由 `pdf` 工具用于模型路由。 - - 如果省略,PDF 工具会回退到 `imageModel`,再回退到已解析的会话/默认模型。 + - 对象形式设置主模型以及按顺序排列的故障转移模型。 +- `imageModel`:接受字符串(`"provider/model"`)或对象(`{ primary, fallbacks }`)。 + - 被 `image` 工具路径用作其视觉模型配置。 + - 当所选/默认模型不能接受图片输入时,也会用作后备路由。 +- `imageGenerationModel`:接受字符串(`"provider/model"`)或对象(`{ primary, fallbacks }`)。 + - 用于共享的图像生成能力,以及任何将来会生成图像的工具/插件表面。 + - 常见值:`google/gemini-3.1-flash-image-preview`(Gemini 原生图像生成)、`fal/fal-ai/flux/dev`(fal)或 `openai/gpt-image-1`(OpenAI Images)。 + - 如果你直接选择某个 provider/model,也请配置相应的提供商认证/API key(例如 `google/*` 使用 `GEMINI_API_KEY` 或 `GOOGLE_API_KEY`,`openai/*` 使用 `OPENAI_API_KEY`,`fal/*` 使用 `FAL_KEY`)。 + - 如果省略,`image_generate` 仍可推断出有认证支持的提供商默认值。它会先尝试当前默认提供商,然后按 provider-id 顺序尝试其余已注册的图像生成提供商。 +- `musicGenerationModel`:接受字符串(`"provider/model"`)或对象(`{ primary, fallbacks }`)。 + - 用于共享的音乐生成能力和内置 `music_generate` 工具。 + - 常见值:`google/lyria-3-clip-preview`、`google/lyria-3-pro-preview` 或 `minimax/music-2.5+`。 + - 如果省略,`music_generate` 仍可推断出有认证支持的提供商默认值。它会先尝试当前默认提供商,然后按 provider-id 顺序尝试其余已注册的音乐生成提供商。 + - 如果你直接选择某个 provider/model,也请配置相应的提供商认证/API key。 +- `videoGenerationModel`:接受字符串(`"provider/model"`)或对象(`{ primary, fallbacks }`)。 + - 用于共享的视频生成能力和内置 `video_generate` 工具。 + - 常见值:`qwen/wan2.6-t2v`、`qwen/wan2.6-i2v`、`qwen/wan2.6-r2v`、`qwen/wan2.6-r2v-flash` 或 `qwen/wan2.7-r2v`。 + - 如果省略,`video_generate` 仍可推断出有认证支持的提供商默认值。它会先尝试当前默认提供商,然后按 provider-id 顺序尝试其余已注册的视频生成提供商。 + - 如果你直接选择某个 provider/model,也请配置相应的提供商认证/API key。 + - 内置的 Qwen 视频生成提供商目前最多支持 1 个输出视频、1 张输入图片、4 个输入视频、10 秒时长,以及提供商级的 `size`、`aspectRatio`、`resolution`、`audio` 和 `watermark` 选项。 +- `pdfModel`:接受字符串(`"provider/model"`)或对象(`{ primary, fallbacks }`)。 + - 被 `pdf` 工具用于模型路由。 + - 如果省略,PDF 工具会先回退到 `imageModel`,再回退到解析后的会话/默认模型。 - `pdfMaxBytesMb`:当调用时未传入 `maxBytesMb` 时,`pdf` 工具使用的默认 PDF 大小限制。 -- `pdfMaxPages`:`pdf` 工具在提取回退模式下考虑的默认最大页数。 -- `verboseDefault`:智能体的默认详细级别。取值:`"off"`、`"on"`、`"full"`。默认:`"off"`。 -- `elevatedDefault`:智能体的默认提权输出级别。取值:`"off"`、`"on"`、`"ask"`、`"full"`。默认:`"on"`。 -- `model.primary`:格式为 `provider/model`(例如 `openai/gpt-5.4`)。如果省略提供商,OpenClaw 会先尝试别名,然后尝试精确模型 ID 的唯一已配置提供商匹配,最后才会回退到已配置的默认提供商(已弃用的兼容行为,因此建议显式使用 `provider/model`)。如果该提供商不再暴露已配置默认模型,OpenClaw 会回退到第一个已配置提供商/模型,而不是继续使用已移除提供商的过时默认值。 -- `models`:为 `/model` 配置的模型目录和允许列表。每个条目可包含 `alias`(快捷名)和 `params`(提供商特定参数,例如 `temperature`、`maxTokens`、`cacheRetention`、`context1m`)。 +- `pdfMaxPages`:`pdf` 工具在提取回退模式中考虑的默认最大页数。 +- `verboseDefault`:智能体的默认详细程度。可选值:`"off"`、`"on"`、`"full"`。默认值:`"off"`。 +- `elevatedDefault`:智能体的默认提权输出级别。可选值:`"off"`、`"on"`、`"ask"`、`"full"`。默认值:`"on"`。 +- `model.primary`:格式为 `provider/model`(例如 `openai/gpt-5.4`)。如果你省略 provider,OpenClaw 会先尝试别名,然后尝试与该精确模型 ID 唯一匹配的已配置 provider,最后才回退到已配置的默认 provider(这是已弃用的兼容行为,因此建议优先使用显式 `provider/model`)。如果该 provider 不再暴露已配置的默认模型,OpenClaw 会回退到第一个已配置的 provider/model,而不是继续使用已失效、已移除的 provider 默认值。 +- `models`:已配置的模型目录和 `/model` 允许列表。每个条目可以包含 `alias`(快捷名)和 `params`(provider 专属参数,例如 `temperature`、`maxTokens`、`cacheRetention`、`context1m`)。 - `params`:适用于所有模型的全局默认提供商参数。设置在 `agents.defaults.params`(例如 `{ cacheRetention: "long" }`)。 -- `params` 合并优先级(配置):`agents.defaults.params`(全局基础)会被 `agents.defaults.models["provider/model"].params`(每模型)覆盖,然后 `agents.list[].params`(匹配的智能体 ID)再按键覆盖。详见 [Prompt Caching](/zh-CN/reference/prompt-caching)。 -- 会修改这些字段的配置写入器(例如 `/models set`、`/models set-image` 和回退模型的添加/移除命令)会保存为规范对象形式,并尽可能保留现有回退列表。 -- `maxConcurrent`:跨会话的最大并行智能体运行数(每个会话仍然串行)。默认:4。 +- `params` 合并优先级(配置):`agents.defaults.params`(全局基础)会被 `agents.defaults.models["provider/model"].params`(每模型)覆盖,然后 `agents.list[].params`(匹配智能体 id)按键覆盖。详见 [Prompt Caching](/zh-CN/reference/prompt-caching)。 +- 会修改这些字段的配置写入器(例如 `/models set`、`/models set-image` 以及后备添加/删除命令)会保存规范对象形式,并在可能时保留现有后备列表。 +- `maxConcurrent`:会话之间允许的最大并行智能体运行数(每个会话本身仍是串行)。默认值:4。 -**内置别名简写**(仅当模型位于 `agents.defaults.models` 中时适用): +**内置别名简写**(仅在模型位于 `agents.defaults.models` 中时适用): | 别名 | 模型 | | ------------------- | -------------------------------------- | @@ -1078,14 +1080,45 @@ IRC 由扩展提供支持,并在 `channels.irc` 下配置。 | `gemini-flash` | `google/gemini-3-flash-preview` | | `gemini-flash-lite` | `google/gemini-3.1-flash-lite-preview` | -你自己配置的别名始终优先于默认值。 +你配置的别名始终优先于默认值。 -Z.AI 的 GLM-4.x 模型会自动启用 thinking 模式,除非你设置 `--thinking off` 或自行定义 `agents.defaults.models["zai/"].params.thinking`。 +Z.AI GLM-4.x 模型会自动启用 thinking 模式,除非你设置 `--thinking off`,或自行定义 `agents.defaults.models["zai/"].params.thinking`。 Z.AI 模型默认启用 `tool_stream` 以进行工具调用流式传输。将 `agents.defaults.models["zai/"].params.tool_stream` 设为 `false` 可禁用它。 Anthropic Claude 4.6 模型在未设置显式 thinking 级别时,默认使用 `adaptive` thinking。 +### `agents.defaults.cliBackends` + +可选的 CLI 后端,用于纯文本回退运行(不调用工具)。当 API 提供商失败时,可作为备份。 + +```json5 +{ + agents: { + defaults: { + cliBackends: { + "codex-cli": { + command: "/opt/homebrew/bin/codex", + }, + "my-cli": { + command: "my-cli", + args: ["--json"], + output: "json", + modelArg: "--model", + sessionArg: "--session", + sessionMode: "existing", + systemPromptArg: "--system", + systemPromptWhen: "first", + imageArg: "--image", + imageMode: "repeat", + }, + }, + }, + }, +} +``` + +- CLI 后端以文本优先;工具始终禁用。 - 当设置了 `sessionArg` 时支持会话。 -- 当 `imageArg` 接受文件路径时支持图像透传。 +- 当 `imageArg` 接受文件路径时支持图片透传。 ### `agents.defaults.heartbeat` @@ -1114,13 +1147,13 @@ Anthropic Claude 4.6 模型在未设置显式 thinking 级别时,默认使用 } ``` -- `every`:持续时间字符串(ms/s/m/h)。默认值:`30m`(API key 身份验证)或 `1h`(OAuth 身份验证)。设为 `0m` 可禁用。 -- `suppressToolErrorWarnings`:设为 true 时,在心跳运行期间抑制工具错误警告负载。 -- `directPolicy`:direct/私信投递策略。`allow`(默认)允许 direct 目标投递。`block` 会阻止 direct 目标投递并发出 `reason=dm-blocked`。 -- `lightContext`:设为 true 时,心跳运行使用轻量 bootstrap 上下文,并且只保留工作区 bootstrap 文件中的 `HEARTBEAT.md`。 -- `isolatedSession`:设为 true 时,每次心跳都会在一个全新会话中运行,不带任何先前对话历史。与 cron 的 `sessionTarget: "isolated"` 使用相同的隔离模式。可将每次心跳的 token 成本从约 100K 降至约 2-5K。 -- 按智能体:设置 `agents.list[].heartbeat`。当任一智能体定义了 `heartbeat` 时,**只有这些智能体**会运行心跳。 -- 心跳会运行完整的智能体轮次——间隔越短,消耗的 token 越多。 +- `every`:时长字符串(ms/s/m/h)。默认值:`30m`(API key 认证)或 `1h`(OAuth 认证)。设置为 `0m` 可禁用。 +- `suppressToolErrorWarnings`:为 true 时,在心跳运行期间抑制工具错误警告负载。 +- `directPolicy`:直连/私信投递策略。`allow`(默认)允许直接目标投递。`block` 会抑制直接目标投递,并发出 `reason=dm-blocked`。 +- `lightContext`:为 true 时,心跳运行使用轻量引导上下文,并且仅保留工作区引导文件中的 `HEARTBEAT.md`。 +- `isolatedSession`:为 true 时,每次心跳运行都会在一个全新的会话中执行,没有此前的对话历史。与 cron 的 `sessionTarget: "isolated"` 使用相同的隔离模式。可将每次心跳的 token 成本从约 100K 降低到约 2-5K。 +- 每智能体:设置 `agents.list[].heartbeat`。如果任意智能体定义了 `heartbeat`,则**只有这些智能体**会运行心跳。 +- 心跳会执行完整智能体轮次 —— 更短的间隔会消耗更多 token。 ### `agents.defaults.compaction` @@ -1149,18 +1182,18 @@ Anthropic Claude 4.6 模型在未设置显式 thinking 级别时,默认使用 } ``` -- `mode`:`default` 或 `safeguard`(针对长历史进行分块摘要)。参见 [Compaction](/zh-CN/concepts/compaction)。 -- `timeoutSeconds`:OpenClaw 放弃单次 compaction 操作前允许的最大秒数。默认值:`900`。 -- `identifierPolicy`:`strict`(默认)、`off` 或 `custom`。`strict` 会在 compaction 摘要期间预置内建的不透明标识符保留指导。 +- `mode`:`default` 或 `safeguard`(针对长历史的分块摘要)。参见 [Compaction](/zh-CN/concepts/compaction)。 +- `timeoutSeconds`:OpenClaw 放弃单次压缩操作前允许的最大秒数。默认值:`900`。 +- `identifierPolicy`:`strict`(默认)、`off` 或 `custom`。`strict` 会在压缩摘要时预置内置的不透明标识符保留指导。 - `identifierInstructions`:当 `identifierPolicy=custom` 时使用的可选自定义标识符保留文本。 -- `postCompactionSections`:可选,要在 compaction 后重新注入的 AGENTS.md H2/H3 章节名称。默认值为 `["Session Startup", "Red Lines"]`;设置为 `[]` 可禁用重新注入。若未设置或显式设置为这对默认值,也会接受旧版 `Every Session`/`Safety` 标题作为兼容回退。 -- `model`:仅用于 compaction 摘要的可选 `provider/model-id` 覆盖。当主会话应保持一个模型,但 compaction 摘要应运行在另一个模型上时使用;未设置时,compaction 使用会话的主模型。 -- `notifyUser`:设为 `true` 时,在 compaction 开始时向用户发送简短提示(例如“Compacting context...”)。默认禁用以保持 compaction 静默。 -- `memoryFlush`:在自动 compaction 前执行静默的智能体轮次以存储持久记忆。工作区为只读时会跳过。 +- `postCompactionSections`:压缩后要重新注入的可选 AGENTS.md H2/H3 章节名。默认值为 `["Session Startup", "Red Lines"]`;设置为 `[]` 可禁用重新注入。当未设置,或显式设置为该默认对时,也会接受旧版 `Every Session`/`Safety` 标题作为兼容回退。 +- `model`:仅用于压缩摘要的可选 `provider/model-id` 覆盖。当你希望主会话继续使用一个模型,而压缩摘要在另一个模型上运行时可使用它;未设置时,压缩使用会话的主模型。 +- `notifyUser`:为 `true` 时,在压缩开始时向用户发送简短提示(例如 “Compacting context...”)。默认禁用,以保持压缩静默。 +- `memoryFlush`:自动压缩前的静默智能体轮次,用于存储持久记忆。工作区只读时会跳过。 ### `agents.defaults.contextPruning` -在将上下文发送给 LLM 之前,从内存上下文中修剪**旧工具结果**。**不会**修改磁盘上的会话历史。 +在发送给 LLM 之前,从内存上下文中裁剪**旧工具结果**。**不会**修改磁盘上的会话历史。 ```json5 { @@ -1184,19 +1217,19 @@ Anthropic Claude 4.6 模型在未设置显式 thinking 级别时,默认使用 -- `mode: "cache-ttl"` 启用修剪过程。 -- `ttl` 控制修剪在上次缓存触碰后,多久之后才能再次运行。 -- 修剪会先对过大的工具结果执行软裁剪,如仍需要则对更旧的工具结果执行硬清除。 +- `mode: "cache-ttl"` 启用裁剪流程。 +- `ttl` 控制何时可以再次运行裁剪(以上次缓存触达之后计算)。 +- 裁剪会先对过大的工具结果执行软裁剪,如仍有需要,再对更旧的工具结果执行硬清除。 -**软裁剪**会保留开头和结尾,并在中间插入 `...`。 +**软裁剪** 保留开头和结尾,中间插入 `...`。 -**硬清除**会用占位符替换整个工具结果。 +**硬清除** 会用占位符替换整个工具结果。 -注意: +说明: -- 图像块永远不会被裁剪/清除。 -- 比例按字符计算(近似),不是精确 token 计数。 -- 如果助手消息数量少于 `keepLastAssistants`,则跳过修剪。 +- 图片块永远不会被裁剪/清除。 +- 比例按字符计算(近似),不是精确 token 数。 +- 如果助手消息少于 `keepLastAssistants` 条,则跳过裁剪。 @@ -1219,12 +1252,12 @@ Anthropic Claude 4.6 模型在未设置显式 thinking 级别时,默认使用 ``` - 非 Telegram 渠道需要显式设置 `*.blockStreaming: true` 才能启用分块回复。 -- 渠道覆盖:`channels..blockStreamingCoalesce`(以及按账号变体)。Signal/Slack/Discord/Google Chat 默认 `minChars: 1500`。 -- `humanDelay`:分块回复之间的随机暂停。`natural` = 800–2500ms。按智能体覆盖:`agents.list[].humanDelay`。 +- 渠道覆盖:`channels..blockStreamingCoalesce`(以及每账号变体)。Signal/Slack/Discord/Google Chat 默认 `minChars: 1500`。 +- `humanDelay`:分块回复之间的随机停顿。`natural` = 800–2500ms。每智能体覆盖:`agents.list[].humanDelay`。 行为和分块细节参见 [Streaming](/zh-CN/concepts/streaming)。 -### 输入指示器 +### 输入状态指示器 ```json5 { @@ -1237,8 +1270,8 @@ Anthropic Claude 4.6 模型在未设置显式 thinking 级别时,默认使用 } ``` -- 默认值:私聊/被提及时为 `instant`,未被提及的群聊中为 `message`。 -- 按会话覆盖:`session.typingMode`、`session.typingIntervalSeconds`。 +- 默认值:私聊/被提及时为 `instant`,未提及的群聊为 `message`。 +- 每会话覆盖:`session.typingMode`、`session.typingIntervalSeconds`。 参见 [Typing Indicators](/zh-CN/concepts/typing-indicators)。 @@ -1246,7 +1279,7 @@ Anthropic Claude 4.6 模型在未设置显式 thinking 级别时,默认使用 ### `agents.defaults.sandbox` -嵌入式智能体的可选沙箱隔离。完整指南参见 [Sandboxing](/zh-CN/gateway/sandboxing)。 +为嵌入式智能体提供可选沙箱隔离。完整指南参见 [Sandboxing](/zh-CN/gateway/sandboxing)。 ```json5 { @@ -1349,43 +1382,43 @@ Anthropic Claude 4.6 模型在未设置显式 thinking 级别时,默认使用 - `ssh`:通用 SSH 远程运行时 - `openshell`:OpenShell 运行时 -当选择 `backend: "openshell"` 时,运行时特定设置会移动到 +选择 `backend: "openshell"` 时,运行时专属设置将移到 `plugins.entries.openshell.config`。 **SSH 后端配置:** -- `target`:`user@host[:port]` 形式的 SSH 目标 +- `target`:`user@host[:port]` 格式的 SSH 目标 - `command`:SSH 客户端命令(默认:`ssh`) -- `workspaceRoot`:用于按作用域工作区的远程绝对根目录 -- `identityFile` / `certificateFile` / `knownHostsFile`:传递给 OpenSSH 的现有本地文件 -- `identityData` / `certificateData` / `knownHostsData`:内联内容或 SecretRef,OpenClaw 会在运行时将其实体化为临时文件 +- `workspaceRoot`:用于每作用域工作区的远程绝对根路径 +- `identityFile` / `certificateFile` / `knownHostsFile`:传给 OpenSSH 的现有本地文件 +- `identityData` / `certificateData` / `knownHostsData`:内联内容或 SecretRef,OpenClaw 会在运行时将其物化为临时文件 - `strictHostKeyChecking` / `updateHostKeys`:OpenSSH 主机密钥策略开关 -**SSH 身份验证优先级:** +**SSH 认证优先级:** - `identityData` 优先于 `identityFile` - `certificateData` 优先于 `certificateFile` - `knownHostsData` 优先于 `knownHostsFile` -- 由 SecretRef 支持的 `*Data` 值会在沙箱会话开始前,从当前激活的 secrets 运行时快照中解析 +- 基于 SecretRef 的 `*Data` 值会在沙箱会话启动前,从当前激活的 secrets 运行时快照中解析 **SSH 后端行为:** -- 在创建或重建后,初始化远程工作区一次 -- 然后保持远程 SSH 工作区为规范副本 +- 在创建或重建后只播种远程工作区一次 +- 之后保持远程 SSH 工作区为规范源 - 通过 SSH 路由 `exec`、文件工具和媒体路径 -- 不会自动将远程更改同步回宿主机 +- 不会自动将远程更改同步回主机 - 不支持沙箱浏览器容器 **工作区访问:** -- `none`:在 `~/.openclaw/sandboxes` 下为每个作用域创建沙箱工作区 -- `ro`:沙箱工作区位于 `/workspace`,智能体工作区只读挂载到 `/agent` +- `none`:在 `~/.openclaw/sandboxes` 下使用每作用域沙箱工作区 +- `ro`:沙箱工作区位于 `/workspace`,智能体工作区以只读方式挂载到 `/agent` - `rw`:智能体工作区以读写方式挂载到 `/workspace` **作用域:** - `session`:每会话一个容器 + 工作区 -- `agent`:每智能体一个容器 + 工作区(默认) +- `agent`:每个智能体一个容器 + 工作区(默认) - `shared`:共享容器和工作区(无跨会话隔离) **OpenShell 插件配置:** @@ -1416,30 +1449,30 @@ Anthropic Claude 4.6 模型在未设置显式 thinking 级别时,默认使用 **OpenShell 模式:** -- `mirror`:执行前将本地内容播种到远端,执行后同步回来;本地工作区保持为规范副本 -- `remote`:沙箱创建时只向远端播种一次,之后保持远程工作区为规范副本 +- `mirror`:在 exec 前将本地内容播种到远程,在 exec 后同步回来;本地工作区保持为规范源 +- `remote`:在创建沙箱时将本地内容播种到远程一次,之后保持远程工作区为规范源 -在 `remote` 模式下,种子步骤之后,在 OpenClaw 外部对宿主机本地所做的编辑不会自动同步进沙箱。 -传输方式是通过 SSH 连接到 OpenShell 沙箱,但插件负责沙箱生命周期和可选的镜像同步。 +在 `remote` 模式下,在播种步骤之后,于 OpenClaw 之外对主机本地所做的编辑不会自动同步到沙箱中。 +传输层使用 SSH 连接到 OpenShell 沙箱,但沙箱生命周期和可选镜像同步由插件负责。 -**`setupCommand`** 会在容器创建后运行一次(通过 `sh -lc`)。它需要网络出口、可写根文件系统以及 root 用户。 +**`setupCommand`** 会在容器创建后运行一次(通过 `sh -lc`)。需要网络出口、可写根文件系统和 root 用户。 -**容器默认使用 `network: "none"`**——如果智能体需要对外访问,请设置为 `"bridge"`(或自定义 bridge 网络)。 -默认会阻止 `"host"`。除非你显式设置 -`sandbox.docker.dangerouslyAllowContainerNamespaceJoin: true`(破玻璃模式),否则也会默认阻止 `"container:"`。 +**容器默认使用 `network: "none"`** —— 如果智能体需要出站访问,请设置为 `"bridge"`(或自定义桥接网络)。 +`"host"` 被阻止。默认情况下 `"container:"` 也被阻止,除非你显式设置 +`sandbox.docker.dangerouslyAllowContainerNamespaceJoin: true`(紧急开关)。 -**传入附件**会被暂存到活动工作区中的 `media/inbound/*`。 +**入站附件** 会被暂存到活动工作区中的 `media/inbound/*`。 -**`docker.binds`** 会挂载额外的宿主目录;全局和按智能体的绑定会被合并。 +**`docker.binds`** 挂载额外的主机目录;全局和每智能体的 binds 会合并。 -**沙箱隔离浏览器**(`sandbox.browser.enabled`):在容器中运行 Chromium + CDP。noVNC URL 会被注入系统提示。不需要在 `openclaw.json` 中启用 `browser.enabled`。 -noVNC 观察者访问默认使用 VNC 身份验证,并且 OpenClaw 会发出短时有效 token URL(而不是在共享 URL 中暴露密码)。 +**沙箱隔离浏览器**(`sandbox.browser.enabled`):容器中的 Chromium + CDP。noVNC URL 会注入系统提示中。不需要在 `openclaw.json` 中启用 `browser.enabled`。 +noVNC 观察者访问默认使用 VNC 认证,OpenClaw 会发出短期 token URL(而不是在共享 URL 中暴露密码)。 -- `allowHostControl: false`(默认)会阻止沙箱隔离会话定位宿主浏览器。 -- `network` 默认为 `openclaw-sandbox-browser`(专用 bridge 网络)。仅当你明确需要全局 bridge 连通性时才设为 `bridge`。 -- `cdpSourceRange` 可选择在容器边界通过 CIDR 范围限制 CDP 入站(例如 `172.21.0.1/32`)。 -- `sandbox.browser.binds` 仅为沙箱浏览器容器挂载额外宿主目录。设置后(包括 `[]`),它会替换浏览器容器的 `docker.binds`。 -- 启动默认值定义在 `scripts/sandbox-browser-entrypoint.sh` 中,并针对容器宿主进行了调优: +- `allowHostControl: false`(默认)会阻止沙箱隔离会话将主机浏览器作为目标。 +- `network` 默认是 `openclaw-sandbox-browser`(专用桥接网络)。仅当你明确想要全局 bridge 连通性时才设置为 `bridge`。 +- `cdpSourceRange` 可选地在容器边缘将 CDP 入站限制到某个 CIDR 范围(例如 `172.21.0.1/32`)。 +- `sandbox.browser.binds` 仅为沙箱浏览器容器挂载额外主机目录。设置后(包括 `[]`)会替换浏览器容器的 `docker.binds`。 +- 启动默认值定义在 `scripts/sandbox-browser-entrypoint.sh` 中,并针对容器主机进行了调优: - `--remote-debugging-address=127.0.0.1` - `--remote-debugging-port=` - `--user-data-dir=${HOME}/.chrome` @@ -1457,13 +1490,17 @@ noVNC 观察者访问默认使用 VNC 身份验证,并且 OpenClaw 会发出 - `--no-zygote` - `--metrics-recording-only` - `--disable-extensions`(默认启用) - - `--disable-3d-apis`、`--disable-software-rasterizer` 和 `--disable-gpu` 默认启用,如需 WebGL/3D,可通过设置 - `OPENCLAW_BROWSER_DISABLE_GRAPHICS_FLAGS=0` 来禁用它们。 - - `OPENCLAW_BROWSER_DISABLE_EXTENSIONS=0` 会重新启用扩展,如果你的工作流依赖它们。 + - `--disable-3d-apis`、`--disable-software-rasterizer` 和 `--disable-gpu` 默认 + 开启;如果你的 WebGL/3D 工作流需要它们,可用 + `OPENCLAW_BROWSER_DISABLE_GRAPHICS_FLAGS=0` 关闭。 + - `OPENCLAW_BROWSER_DISABLE_EXTENSIONS=0` 会重新启用扩展,如果你的工作流 + 依赖它们。 - `--renderer-process-limit=2` 可通过 - `OPENCLAW_BROWSER_RENDERER_PROCESS_LIMIT=` 修改;设为 `0` 可使用 Chromium 的默认进程限制。 + `OPENCLAW_BROWSER_RENDERER_PROCESS_LIMIT=` 修改;设置为 `0` 使用 Chromium 的 + 默认进程限制。 - 当启用 `noSandbox` 时,还会加上 `--no-sandbox` 和 `--disable-setuid-sandbox`。 - - 这些默认值是容器镜像基线;如需更改容器默认值,请使用自定义浏览器镜像和自定义入口点。 + - 这些默认值是容器镜像的基线;如需更改容器默认行为,请使用带自定义 + 入口点的自定义浏览器镜像。 @@ -1476,7 +1513,7 @@ scripts/sandbox-setup.sh # main sandbox image scripts/sandbox-browser-setup.sh # optional browser image ``` -### `agents.list`(按智能体覆盖) +### `agents.list`(每智能体覆盖) ```json5 { @@ -1525,25 +1562,25 @@ scripts/sandbox-browser-setup.sh # optional browser image ``` - `id`:稳定的智能体 ID(必填)。 -- `default`:如果设置了多个,以第一个为准(会记录警告)。如果都未设置,则列表中的第一个条目为默认值。 -- `model`:字符串形式只覆盖 `primary`;对象形式 `{ primary, fallbacks }` 同时覆盖两者(`[]` 会禁用全局回退)。仅覆盖 `primary` 的 cron 作业仍会继承默认回退,除非你设置 `fallbacks: []`。 -- `params`:按智能体设置的流参数,会合并到 `agents.defaults.models` 中选定模型条目之上。用于像 `cacheRetention`、`temperature` 或 `maxTokens` 这样的智能体特定覆盖,而无需复制整个模型目录。 -- `skills`:可选的按智能体 Skills 允许列表。如果省略,智能体在设置了 `agents.defaults.skills` 时会继承它;显式列表会替换默认值而不是合并,`[]` 表示无 Skills。 -- `thinkingDefault`:可选的按智能体默认 thinking 级别(`off | minimal | low | medium | high | xhigh | adaptive`)。当未设置按消息或按会话覆盖时,会覆盖该智能体的 `agents.defaults.thinkingDefault`。 -- `reasoningDefault`:可选的按智能体默认 reasoning 可见性(`on | off | stream`)。当未设置按消息或按会话的 reasoning 覆盖时生效。 -- `fastModeDefault`:可选的按智能体 fast mode 默认值(`true | false`)。当未设置按消息或按会话的 fast mode 覆盖时生效。 -- `runtime`:可选的按智能体运行时描述符。当智能体应默认使用 ACP harness 会话时,使用 `type: "acp"` 并设置 `runtime.acp` 默认值(`agent`、`backend`、`mode`、`cwd`)。 +- `default`:如果设置了多个,以第一个为准(会记录警告)。如果一个都没设,列表第一项为默认。 +- `model`:字符串形式只覆盖 `primary`;对象形式 `{ primary, fallbacks }` 同时覆盖两者(`[]` 会禁用全局后备)。仅覆盖 `primary` 的 cron 作业仍会继承默认后备,除非你设置 `fallbacks: []`。 +- `params`:合并到 `agents.defaults.models` 中所选模型条目之上的每智能体流参数。用于这种按智能体区分的覆盖,例如 `cacheRetention`、`temperature` 或 `maxTokens`,而无需复制整个模型目录。 +- `skills`:可选的每智能体 Skills 允许列表。如果省略,智能体会在已设置时继承 `agents.defaults.skills`;显式列表会替换默认值而不是合并,`[]` 表示不启用任何 Skills。 +- `thinkingDefault`:可选的每智能体默认 thinking 级别(`off | minimal | low | medium | high | xhigh | adaptive`)。在未设置每消息或会话覆盖时,它会覆盖该智能体的 `agents.defaults.thinkingDefault`。 +- `reasoningDefault`:可选的每智能体默认 reasoning 可见性(`on | off | stream`)。在未设置每消息或会话 reasoning 覆盖时适用。 +- `fastModeDefault`:可选的每智能体 fast mode 默认值(`true | false`)。在未设置每消息或会话 fast-mode 覆盖时适用。 +- `runtime`:可选的每智能体运行时描述符。当智能体应默认使用 ACP harness 会话时,可使用 `type: "acp"` 并设置 `runtime.acp` 默认值(`agent`、`backend`、`mode`、`cwd`)。 - `identity.avatar`:工作区相对路径、`http(s)` URL 或 `data:` URI。 -- `identity` 会派生默认值:`ackReaction` 来自 `emoji`,`mentionPatterns` 来自 `name`/`emoji`。 -- `subagents.allowAgents`:用于 `sessions_spawn` 的智能体 ID 允许列表(`["*"]` = 任意;默认:仅同一智能体)。 -- 沙箱继承保护:如果请求方会话已处于沙箱隔离中,`sessions_spawn` 会拒绝运行目标为未沙箱隔离的情况。 +- `identity` 会派生默认值:从 `emoji` 派生 `ackReaction`,从 `name`/`emoji` 派生 `mentionPatterns`。 +- `subagents.allowAgents`:`sessions_spawn` 的智能体 ID 允许列表(`["*"]` = 任意;默认:仅同一智能体)。 +- 沙箱继承保护:如果请求方会话处于沙箱隔离中,`sessions_spawn` 会拒绝目标为无沙箱的运行。 - `subagents.requireAgentId`:为 true 时,阻止省略 `agentId` 的 `sessions_spawn` 调用(强制显式选择配置;默认:false)。 --- ## 多智能体路由 -在一个 Gateway 网关内运行多个隔离智能体。参见 [Multi-Agent](/zh-CN/concepts/multi-agent)。 +在一个 Gateway 网关内运行多个相互隔离的智能体。参见 [Multi-Agent](/zh-CN/concepts/multi-agent)。 ```json5 { @@ -1562,11 +1599,11 @@ scripts/sandbox-browser-setup.sh # optional browser image ### 绑定匹配字段 -- `type`(可选):正常路由用 `route`(缺失时默认 route),持久 ACP 会话绑定用 `acp` +- `type`(可选):普通路由用 `route`(缺失时默认 route),持久 ACP 对话绑定用 `acp` - `match.channel`(必填) - `match.accountId`(可选;`*` = 任意账号;省略 = 默认账号) - `match.peer`(可选;`{ kind: direct|group|channel, id }`) -- `match.guildId` / `match.teamId`(可选;特定渠道使用) +- `match.guildId` / `match.teamId`(可选;渠道专用) - `acp`(可选;仅用于 `type: "acp"`):`{ mode, label, cwd, backend }` **确定性匹配顺序:** @@ -1574,17 +1611,17 @@ scripts/sandbox-browser-setup.sh # optional browser image 1. `match.peer` 2. `match.guildId` 3. `match.teamId` -4. `match.accountId`(精确,无 peer/guild/team) -5. `match.accountId: "*"`(渠道级) +4. `match.accountId`(精确匹配,无 peer/guild/team) +5. `match.accountId: "*"`(渠道范围) 6. 默认智能体 -在每一层中,第一个匹配的 `bindings` 条目胜出。 +在每个层级内,首个匹配的 `bindings` 条目获胜。 -对于 `type: "acp"` 条目,OpenClaw 会通过精确会话身份(`match.channel` + 账号 + `match.peer.id`)解析,而不会使用上述 route 绑定分层顺序。 +对于 `type: "acp"` 条目,OpenClaw 按精确会话标识(`match.channel` + 账号 + `match.peer.id`)解析,不使用上面的 route 绑定层级顺序。 -### 按智能体访问配置 +### 每智能体访问配置 - + ```json5 { @@ -1631,7 +1668,7 @@ scripts/sandbox-browser-setup.sh # optional browser image - + ```json5 { @@ -1681,7 +1718,7 @@ scripts/sandbox-browser-setup.sh # optional browser image --- -## Session 会话 +## 会话 ```json5 { @@ -1728,43 +1765,43 @@ scripts/sandbox-browser-setup.sh # optional browser image } ``` - + - **`scope`**:群聊上下文的基础会话分组策略。 - - `per-sender`(默认):在一个渠道上下文中,每个发送者都有独立会话。 - - `global`:一个渠道上下文中的所有参与者共享同一个会话(仅在确实需要共享上下文时使用)。 + - `per-sender`(默认):在一个渠道上下文内,每个发送者拥有独立会话。 + - `global`:一个渠道上下文中的所有参与者共享同一会话(仅在明确需要共享上下文时使用)。 - **`dmScope`**:私信如何分组。 - `main`:所有私信共享主会话。 - `per-peer`:按发送者 ID 跨渠道隔离。 - `per-channel-peer`:按渠道 + 发送者隔离(推荐用于多用户收件箱)。 - `per-account-channel-peer`:按账号 + 渠道 + 发送者隔离(推荐用于多账号)。 -- **`identityLinks`**:将规范 ID 映射到带提供商前缀的 peer,用于跨渠道共享会话。 -- **`reset`**:主重置策略。`daily` 在本地时间 `atHour` 重置;`idle` 在 `idleMinutes` 后重置。当两者都配置时,先到期者生效。 -- **`resetByType`**:按类型覆盖(`direct`、`group`、`thread`)。旧版 `dm` 可作为 `direct` 的别名接受。 -- **`parentForkMaxTokens`**:创建分叉线程会话时允许的父会话 `totalTokens` 最大值(默认 `100000`)。 - - 如果父会话的 `totalTokens` 超过此值,OpenClaw 会启动新的线程会话,而不是继承父转录历史。 - - 设为 `0` 可禁用此保护,并始终允许父级分叉。 -- **`mainKey`**:旧版字段。运行时现在始终使用 `"main"` 作为主私聊桶。 -- **`agentToAgent.maxPingPongTurns`**:智能体之间进行 agent-to-agent 交换时,允许的最大来回回复轮次(整数,范围:`0`–`5`)。`0` 会禁用 ping-pong 链接。 -- **`sendPolicy`**:按 `channel`、`chatType`(`direct|group|channel`,旧版 `dm` 可作为别名)、`keyPrefix` 或 `rawKeyPrefix` 匹配。第一个 deny 胜出。 +- **`identityLinks`**:将规范 ID 映射到带 provider 前缀的对端,用于跨渠道共享会话。 +- **`reset`**:主重置策略。`daily` 会在本地时间 `atHour` 重置;`idle` 会在空闲 `idleMinutes` 后重置。如果两者都配置,以先到期者为准。 +- **`resetByType`**:按类型覆盖(`direct`、`group`、`thread`)。旧版 `dm` 可作为 `direct` 的别名。 +- **`parentForkMaxTokens`**:创建分叉线程会话时,父会话允许的最大 `totalTokens`(默认 `100000`)。 + - 如果父会话的 `totalTokens` 高于此值,OpenClaw 会启动一个全新线程会话,而不是继承父级转录历史。 + - 设置为 `0` 可禁用此保护,并始终允许父级分叉。 +- **`mainKey`**:旧版字段。运行时现在始终对主私聊桶使用 `"main"`。 +- **`agentToAgent.maxPingPongTurns`**:智能体间交换期间,智能体之间最多允许来回回复的轮次数(整数,范围:`0`–`5`)。`0` 会禁用 ping-pong 链接。 +- **`sendPolicy`**:按 `channel`、`chatType`(`direct|group|channel`,旧版 `dm` 为别名)、`keyPrefix` 或 `rawKeyPrefix` 匹配。第一个 deny 获胜。 - **`maintenance`**:会话存储清理 + 保留控制。 - - `mode`:`warn` 仅发出警告;`enforce` 执行清理。 - - `pruneAfter`:过期条目的时间截止(默认 `30d`)。 + - `mode`:`warn` 仅发出警告;`enforce` 实施清理。 + - `pruneAfter`:陈旧条目的年龄阈值(默认 `30d`)。 - `maxEntries`:`sessions.json` 中的最大条目数(默认 `500`)。 - `rotateBytes`:当 `sessions.json` 超过此大小时轮转(默认 `10mb`)。 - - `resetArchiveRetention`:`*.reset.` 转录归档的保留期。默认跟随 `pruneAfter`;设为 `false` 可禁用。 - - `maxDiskBytes`:可选的 sessions 目录硬性磁盘预算。在 `warn` 模式下记录警告;在 `enforce` 模式下优先移除最旧的工件/会话。 - - `highWaterBytes`:预算清理后的可选目标。默认是 `maxDiskBytes` 的 `80%`。 + - `resetArchiveRetention`:`*.reset.` 转录归档的保留期。默认值与 `pruneAfter` 相同;设为 `false` 可禁用。 + - `maxDiskBytes`:可选的会话目录磁盘硬预算。在 `warn` 模式下会记录警告;在 `enforce` 模式下会优先删除最旧的工件/会话。 + - `highWaterBytes`:预算清理后的可选目标值。默认是 `maxDiskBytes` 的 `80%`。 - **`threadBindings`**:线程绑定会话功能的全局默认值。 - `enabled`:主默认开关(提供商可覆盖;Discord 使用 `channels.discord.threadBindings.enabled`) - - `idleHours`:按小时计算的默认不活动自动取消焦点时间(`0` 表示禁用;提供商可覆盖) - - `maxAgeHours`:按小时计算的默认硬性最大存活时间(`0` 表示禁用;提供商可覆盖) + - `idleHours`:默认按小时计算的不活跃自动取消聚焦时长(`0` 禁用;提供商可覆盖) + - `maxAgeHours`:默认按小时计算的硬性最大时长(`0` 禁用;提供商可覆盖) --- -## Messages 消息 +## 消息 ```json5 { @@ -1794,38 +1831,38 @@ scripts/sandbox-browser-setup.sh # optional browser image } ``` -### 回复前缀 +### 响应前缀 -按渠道/账号覆盖:`channels..responsePrefix`、`channels..accounts..responsePrefix`。 +每渠道/账号覆盖:`channels..responsePrefix`、`channels..accounts..responsePrefix`。 解析顺序(越具体越优先):账号 → 渠道 → 全局。`""` 会禁用并停止级联。`"auto"` 会派生为 `[{identity.name}]`。 **模板变量:** -| 变量 | 说明 | 示例 | -| ----------------- | ------------------- | --------------------------- | -| `{model}` | 简短模型名 | `claude-opus-4-6` | -| `{modelFull}` | 完整模型标识符 | `anthropic/claude-opus-4-6` | -| `{provider}` | 提供商名称 | `anthropic` | -| `{thinkingLevel}` | 当前 thinking 级别 | `high`, `low`, `off` | -| `{identity.name}` | 智能体 identity 名称 | (与 `"auto"` 相同) | +| 变量 | 说明 | 示例 | +| ----------------- | -------------- | --------------------------- | +| `{model}` | 简短模型名 | `claude-opus-4-6` | +| `{modelFull}` | 完整模型标识符 | `anthropic/claude-opus-4-6` | +| `{provider}` | 提供商名称 | `anthropic` | +| `{thinkingLevel}` | 当前 thinking 级别 | `high`, `low`, `off` | +| `{identity.name}` | 智能体身份名称 | (与 `"auto"` 相同) | 变量不区分大小写。`{think}` 是 `{thinkingLevel}` 的别名。 -### 确认反应 +### 确认表情 -- 默认使用活动智能体的 `identity.emoji`,否则为 `"👀"`。设为 `""` 可禁用。 -- 按渠道覆盖:`channels..ackReaction`、`channels..accounts..ackReaction`。 +- 默认为当前活动智能体的 `identity.emoji`,否则为 `"👀"`。设置为 `""` 可禁用。 +- 每渠道覆盖:`channels..ackReaction`、`channels..accounts..ackReaction`。 - 解析顺序:账号 → 渠道 → `messages.ackReaction` → identity 回退。 - 作用范围:`group-mentions`(默认)、`group-all`、`direct`、`all`。 -- `removeAckAfterReply`:在 Slack、Discord 和 Telegram 上,回复后移除确认反应。 -- `messages.statusReactions.enabled`:在 Slack、Discord 和 Telegram 上启用生命周期状态反应。 - 在 Slack 和 Discord 上,未设置时若确认反应处于启用状态,则会保持状态反应启用。 - 在 Telegram 上,需要显式设置为 `true` 才能启用生命周期状态反应。 +- `removeAckAfterReply`:在 Slack、Discord 和 Telegram 上,回复后移除确认表情。 +- `messages.statusReactions.enabled`:在 Slack、Discord 和 Telegram 上启用生命周期状态表情。 + 在 Slack 和 Discord 上,未设置时会在确认表情启用时保持状态表情开启。 + 在 Telegram 上,需显式设置为 `true` 才会启用生命周期状态表情。 ### 入站防抖 -将同一发送者快速连续发送的纯文本消息合并为单个智能体轮次。媒体/附件会立即刷新。控制命令会绕过防抖。 +会把来自同一发送者的快速纯文本消息合并为一个智能体轮次。媒体/附件会立即刷新。控制命令会绕过防抖。 ### TTS(文本转语音) @@ -1869,11 +1906,11 @@ scripts/sandbox-browser-setup.sh # optional browser image ``` - `auto` 控制自动 TTS。`/tts off|always|inbound|tagged` 会按会话覆盖。 -- `summaryModel` 会覆盖 `agents.defaults.model.primary` 用于自动摘要。 +- `summaryModel` 会覆盖自动摘要时使用的 `agents.defaults.model.primary`。 - `modelOverrides` 默认启用;`modelOverrides.allowProvider` 默认是 `false`(需显式启用)。 -- API key 会回退到 `ELEVENLABS_API_KEY`/`XI_API_KEY` 和 `OPENAI_API_KEY`。 -- `openai.baseUrl` 会覆盖 OpenAI TTS 端点。解析顺序为配置、然后 `OPENAI_TTS_BASE_URL`、然后 `https://api.openai.com/v1`。 -- 当 `openai.baseUrl` 指向非 OpenAI 端点时,OpenClaw 会将其视为兼容 OpenAI 的 TTS 服务器,并放宽模型/语音校验。 +- API keys 会回退到 `ELEVENLABS_API_KEY`/`XI_API_KEY` 和 `OPENAI_API_KEY`。 +- `openai.baseUrl` 会覆盖 OpenAI TTS 端点。解析顺序是配置,然后 `OPENAI_TTS_BASE_URL`,最后 `https://api.openai.com/v1`。 +- 当 `openai.baseUrl` 指向非 OpenAI 端点时,OpenClaw 会将其视为兼容 OpenAI 的 TTS 服务器,并放宽对 model/voice 的校验。 --- @@ -1904,10 +1941,10 @@ Talk 模式的默认值(macOS/iOS/Android)。 ``` - 当配置了多个 Talk 提供商时,`talk.provider` 必须匹配 `talk.providers` 中的某个键。 -- 旧版扁平 Talk 键(`talk.voiceId`、`talk.voiceAliases`、`talk.modelId`、`talk.outputFormat`、`talk.apiKey`)仅用于兼容,并会自动迁移到 `talk.providers.`。 -- 语音 ID 会回退到 `ELEVENLABS_VOICE_ID` 或 `SAG_VOICE_ID`。 -- `providers.*.apiKey` 可接受明文字符串或 SecretRef 对象。 -- 仅在未配置 Talk API key 时,才会应用 `ELEVENLABS_API_KEY` 回退。 +- 旧版扁平 Talk 键(`talk.voiceId`、`talk.voiceAliases`、`talk.modelId`、`talk.outputFormat`、`talk.apiKey`)仅用于兼容,会自动迁移到 `talk.providers.` 中。 +- Voice ID 会回退到 `ELEVENLABS_VOICE_ID` 或 `SAG_VOICE_ID`。 +- `providers.*.apiKey` 接受明文字符串或 SecretRef 对象。 +- 只有在未配置任何 Talk API key 时,才会回退到 `ELEVENLABS_API_KEY`。 - `providers.*.voiceAliases` 允许 Talk 指令使用友好名称。 - `silenceTimeoutMs` 控制 Talk 模式在用户静音后等待多久再发送转录。未设置时保留平台默认暂停窗口(`macOS 和 Android 为 700 ms,iOS 为 900 ms`)。 @@ -1917,22 +1954,22 @@ Talk 模式的默认值(macOS/iOS/Android)。 ### 工具配置文件 -`tools.profile` 会在 `tools.allow`/`tools.deny` 之前设置基础允许列表: +`tools.profile` 会在 `tools.allow`/`tools.deny` 之前先设置一个基础允许列表: -本地新手引导在新建本地配置且未设置时,会默认使用 `tools.profile: "coding"`(现有显式配置文件会被保留)。 +本地新手引导会在新本地配置中、该值未设置时,默认使用 `tools.profile: "coding"`(现有显式 profile 会保留)。 -| 配置文件 | 包含内容 | -| ----------- | ----------------------------------------------------------------------------------------------------------------------------- | -| `minimal` | 仅 `session_status` | -| `coding` | `group:fs`、`group:runtime`、`group:web`、`group:sessions`、`group:memory`、`cron`、`image`、`image_generate`、`video_generate` | -| `messaging` | `group:messaging`、`sessions_list`、`sessions_history`、`sessions_send`、`session_status` | -| `full` | 不限制(与未设置相同) | +| 配置文件 | 包含内容 | +| ------------ | ------------------------------------------------------------------------------------------------------------------------------- | +| `minimal` | 仅 `session_status` | +| `coding` | `group:fs`、`group:runtime`、`group:web`、`group:sessions`、`group:memory`、`cron`、`image`、`image_generate`、`video_generate` | +| `messaging` | `group:messaging`、`sessions_list`、`sessions_history`、`sessions_send`、`session_status` | +| `full` | 无限制(与未设置相同) | ### 工具组 -| 组 | 工具 | -| ------------------ | --------------------------------------------------------------------------------------------------------------------- | -| `group:runtime` | `exec`、`process`、`code_execution`(`bash` 可作为 `exec` 的别名接受) | +| 组 | 工具 | +| ------------------ | ---------------------------------------------------------------------------------------------------------------------- | +| `group:runtime` | `exec`、`process`、`code_execution`(`bash` 可作为 `exec` 的别名) | | `group:fs` | `read`、`write`、`edit`、`apply_patch` | | `group:sessions` | `sessions_list`、`sessions_history`、`sessions_send`、`sessions_spawn`、`sessions_yield`、`subagents`、`session_status` | | `group:memory` | `memory_search`、`memory_get` | @@ -1943,11 +1980,11 @@ Talk 模式的默认值(macOS/iOS/Android)。 | `group:nodes` | `nodes` | | `group:agents` | `agents_list` | | `group:media` | `image`、`image_generate`、`video_generate`、`tts` | -| `group:openclaw` | 所有内置工具(不包括提供商插件) | +| `group:openclaw` | 所有内置工具(不包括 provider 插件) | ### `tools.allow` / `tools.deny` -全局工具允许/拒绝策略(deny 胜出)。不区分大小写,支持 `*` 通配符。即使 Docker 沙箱关闭也会应用。 +全局工具允许/拒绝策略(拒绝优先)。不区分大小写,支持 `*` 通配符。即使 Docker 沙箱已关闭,也会应用。 ```json5 { @@ -1957,7 +1994,7 @@ Talk 模式的默认值(macOS/iOS/Android)。 ### `tools.byProvider` -进一步限制特定提供商或模型的工具。顺序:基础配置文件 → 提供商配置文件 → allow/deny。 +进一步限制特定提供商或模型可用的工具。顺序:基础 profile → 提供商 profile → allow/deny。 ```json5 { @@ -1989,9 +2026,9 @@ Talk 模式的默认值(macOS/iOS/Android)。 } ``` -- 按智能体覆盖(`agents.list[].tools.elevated`)只能进一步收紧。 -- `/elevated on|off|ask|full` 会按会话存储状态;内联指令只应用于单条消息。 -- 提权 `exec` 会绕过沙箱隔离,并使用已配置的 escape path(默认为 `gateway`,当 exec 目标为 `node` 时为 `node`)。 +- 每智能体覆盖(`agents.list[].tools.elevated`)只能进一步收紧。 +- `/elevated on|off|ask|full` 会按会话存储状态;内联指令仅作用于单条消息。 +- 提权 `exec` 会绕过沙箱隔离,并使用已配置的逃逸路径(默认 `gateway`,当 exec 目标为 `node` 时则使用 `node`)。 ### `tools.exec` @@ -2015,8 +2052,8 @@ Talk 模式的默认值(macOS/iOS/Android)。 ### `tools.loopDetection` -工具循环安全检查**默认关闭**。设置 `enabled: true` 可激活检测。 -可在全局 `tools.loopDetection` 中定义设置,并在每智能体 `agents.list[].tools.loopDetection` 处覆盖。 +工具循环安全检查**默认禁用**。设置 `enabled: true` 以启用检测。 +可在全局 `tools.loopDetection` 中定义设置,并在每智能体的 `agents.list[].tools.loopDetection` 中覆盖。 ```json5 { @@ -2037,14 +2074,14 @@ Talk 模式的默认值(macOS/iOS/Android)。 } ``` -- `historySize`:保留用于循环分析的最大工具调用历史。 -- `warningThreshold`:重复无进展模式触发警告的阈值。 +- `historySize`:为循环分析保留的最大工具调用历史。 +- `warningThreshold`:发出警告前,无进展重复模式的阈值。 - `criticalThreshold`:阻止严重循环的更高重复阈值。 -- `globalCircuitBreakerThreshold`:任何无进展运行的硬停止阈值。 +- `globalCircuitBreakerThreshold`:任意无进展运行的硬停止阈值。 - `detectors.genericRepeat`:对重复的同工具/同参数调用发出警告。 -- `detectors.knownPollNoProgress`:对已知轮询工具(`process.poll`、`command_status` 等)上的无进展模式发出警告/阻止。 -- `detectors.pingPong`:对交替出现的无进展配对模式发出警告/阻止。 -- 如果 `warningThreshold >= criticalThreshold` 或 `criticalThreshold >= globalCircuitBreakerThreshold`,验证会失败。 +- `detectors.knownPollNoProgress`:对已知轮询工具(`process.poll`、`command_status` 等)的无进展行为发出警告/阻止。 +- `detectors.pingPong`:对交替出现的无进展成对模式发出警告/阻止。 +- 如果 `warningThreshold >= criticalThreshold` 或 `criticalThreshold >= globalCircuitBreakerThreshold`,校验会失败。 ### `tools.web` @@ -2078,7 +2115,7 @@ Talk 模式的默认值(macOS/iOS/Android)。 ### `tools.media` -配置传入媒体理解(图像/音频/视频): +配置入站媒体理解(图片/音频/视频): ```json5 { @@ -2114,9 +2151,9 @@ Talk 模式的默认值(macOS/iOS/Android)。 **提供商条目**(`type: "provider"` 或省略): -- `provider`:API 提供商 ID(`openai`、`anthropic`、`google`/`gemini`、`groq` 等) -- `model`:模型 ID 覆盖 -- `profile` / `preferredProfile`:`auth-profiles.json` 配置文件选择 +- `provider`:API 提供商 id(`openai`、`anthropic`、`google`/`gemini`、`groq` 等) +- `model`:模型 id 覆盖 +- `profile` / `preferredProfile`:`auth-profiles.json` profile 选择 **CLI 条目**(`type: "cli"`): @@ -2125,16 +2162,16 @@ Talk 模式的默认值(macOS/iOS/Android)。 **通用字段:** -- `capabilities`:可选列表(`image`、`audio`、`video`)。默认值:`openai`/`anthropic`/`minimax` → image,`google` → image+audio+video,`groq` → audio。 -- `prompt`、`maxChars`、`maxBytes`、`timeoutSeconds`、`language`:按条目覆盖。 +- `capabilities`:可选列表(`image`、`audio`、`video`)。默认:`openai`/`anthropic`/`minimax` → image,`google` → image+audio+video,`groq` → audio。 +- `prompt`、`maxChars`、`maxBytes`、`timeoutSeconds`、`language`:每条目覆盖。 - 失败时会回退到下一个条目。 -提供商身份验证遵循标准顺序:`auth-profiles.json` → 环境变量 → `models.providers.*.apiKey`。 +提供商认证遵循标准顺序:`auth-profiles.json` → 环境变量 → `models.providers.*.apiKey`。 **异步完成字段:** -- `asyncCompletion.directSend`:当为 `true` 时,已完成的异步 `music_generate` - 和 `video_generate` 任务会优先尝试直接发送到渠道。默认:`false` +- `asyncCompletion.directSend`:为 `true` 时,已完成的异步 `music_generate` + 和 `video_generate` 任务会先尝试直接投递到渠道。默认:`false` (旧版请求者会话唤醒/模型投递路径)。 @@ -2154,9 +2191,9 @@ Talk 模式的默认值(macOS/iOS/Android)。 ### `tools.sessions` -控制 session 工具(`sessions_list`、`sessions_history`、`sessions_send`)可以定位哪些会话。 +控制会话工具(`sessions_list`、`sessions_history`、`sessions_send`)可以访问哪些会话。 -默认值:`tree`(当前会话 + 由其派生的会话,例如子智能体)。 +默认值:`tree`(当前会话 + 由其生成的会话,例如子智能体)。 ```json5 { @@ -2169,13 +2206,13 @@ Talk 模式的默认值(macOS/iOS/Android)。 } ``` -注意: +说明: - `self`:仅当前会话键。 -- `tree`:当前会话 + 由当前会话派生的会话(子智能体)。 -- `agent`:属于当前智能体 ID 的任意会话(如果你在同一智能体 ID 下运行按发送者分会话,这也可能包含其他用户)。 -- `all`:任意会话。跨智能体定位仍需要 `tools.agentToAgent`。 -- 沙箱钳制:当当前会话已沙箱隔离且 `agents.defaults.sandbox.sessionToolsVisibility="spawned"` 时,即使 `tools.sessions.visibility="all"`,可见性也会被强制为 `tree`。 +- `tree`:当前会话 + 由当前会话生成的会话(子智能体)。 +- `agent`:属于当前智能体 id 的任意会话(如果你在同一智能体 id 下运行 per-sender 会话,可能包含其他用户)。 +- `all`:任意会话。跨智能体定向仍需要 `tools.agentToAgent`。 +- 沙箱钳制:当当前会话处于沙箱隔离中且 `agents.defaults.sandbox.sessionToolsVisibility="spawned"` 时,即使 `tools.sessions.visibility="all"`,可见性也会被强制为 `tree`。 ### `tools.sessions_spawn` @@ -2197,18 +2234,18 @@ Talk 模式的默认值(macOS/iOS/Android)。 } ``` -注意: +说明: - 仅 `runtime: "subagent"` 支持附件。ACP 运行时会拒绝它们。 -- 文件会实体化到子工作区的 `.openclaw/attachments//`,并附带 `.manifest.json`。 +- 文件会被物化到子工作区的 `.openclaw/attachments//` 中,并附带一个 `.manifest.json`。 - 附件内容会自动从转录持久化中脱敏。 -- Base64 输入会通过严格的字母表/填充检查以及解码前大小保护进行验证。 -- 目录权限为 `0700`,文件权限为 `0600`。 -- 清理遵循 `cleanup` 策略:`delete` 总会删除附件;仅在 `retainOnSessionKeep: true` 时,`keep` 才会保留它们。 +- Base64 输入会进行严格字母表/填充校验,以及解码前大小保护。 +- 文件权限为目录 `0700`、文件 `0600`。 +- 清理遵循 `cleanup` 策略:`delete` 始终移除附件;仅当 `retainOnSessionKeep: true` 时,`keep` 才保留它们。 ### `tools.experimental` -实验性内置工具开关。默认关闭,除非某个运行时特定的自动启用规则适用。 +实验性内置工具开关。默认关闭,除非某条运行时专属自动启用规则适用。 ```json5 { @@ -2220,11 +2257,11 @@ Talk 模式的默认值(macOS/iOS/Android)。 } ``` -注意: +说明: -- `planTool`:为非简单多步骤工作跟踪启用结构化 `update_plan` 工具。 +- `planTool`:为非琐碎的多步骤工作跟踪启用结构化 `update_plan` 工具。 - 默认:对非 OpenAI 提供商为 `false`。OpenAI 和 OpenAI Codex 运行会自动启用它。 -- 启用后,系统提示也会添加使用指导,使模型仅在实质性工作中使用它,并且最多只保留一个 `in_progress` 步骤。 +- 启用后,系统提示还会添加使用指导,使模型只在实质性工作中使用它,并且最多仅保留一个 `in_progress` 步骤。 ### `agents.defaults.subagents` @@ -2244,10 +2281,10 @@ Talk 模式的默认值(macOS/iOS/Android)。 } ``` -- `model`:生成的子智能体默认模型。如果省略,子智能体会继承调用者模型。 -- `allowAgents`:当请求方智能体未设置自己的 `subagents.allowAgents` 时,`sessions_spawn` 目标智能体 ID 的默认允许列表(`["*"]` = 任意;默认:仅同一智能体)。 -- `runTimeoutSeconds`:当工具调用省略 `runTimeoutSeconds` 时,`sessions_spawn` 使用的默认超时(秒)。`0` 表示无超时。 -- 按子智能体工具策略:`tools.subagents.tools.allow` / `tools.subagents.tools.deny`。 +- `model`:生成子智能体的默认模型。若省略,子智能体会继承调用方的模型。 +- `allowAgents`:当请求方智能体未设置自己的 `subagents.allowAgents` 时,`sessions_spawn` 允许的默认目标智能体 id 列表(`["*"]` = 任意;默认:仅同一智能体)。 +- `runTimeoutSeconds`:当工具调用省略 `runTimeoutSeconds` 时,`sessions_spawn` 使用的默认超时时间(秒)。`0` 表示无超时。 +- 每子智能体工具策略:`tools.subagents.tools.allow` / `tools.subagents.tools.deny`。 --- @@ -2282,46 +2319,46 @@ OpenClaw 使用内置模型目录。通过配置中的 `models.providers` 或 `~ } ``` -- 针对自定义身份验证需求,使用 `authHeader: true` + `headers`。 +- 对于自定义认证需求,使用 `authHeader: true` + `headers`。 - 使用 `OPENCLAW_AGENT_DIR`(或旧版环境变量别名 `PI_CODING_AGENT_DIR`)覆盖智能体配置根目录。 -- 对于匹配的提供商 ID,合并优先级如下: +- 对于匹配的 provider ID,合并优先级如下: - 非空的智能体 `models.json` `baseUrl` 值优先。 - - 非空的智能体 `apiKey` 值仅在该提供商在当前配置/auth-profile 上下文中不是由 SecretRef 管理时优先。 - - 由 SecretRef 管理的提供商 `apiKey` 值会根据来源标记刷新(环境变量引用用 `ENV_VAR_NAME`,file/exec 引用用 `secretref-managed`),而不是持久化已解析出的 secret。 - - 由 SecretRef 管理的提供商 header 值会根据来源标记刷新(环境变量引用用 `secretref-env:ENV_VAR_NAME`,file/exec 引用用 `secretref-managed`)。 - - 为空或缺失的智能体 `apiKey`/`baseUrl` 会回退到配置中的 `models.providers`。 + - 非空的智能体 `apiKey` 值仅在当前 config/auth-profile 上下文中,该 provider 不是 SecretRef 管理时才优先。 + - 由 SecretRef 管理的 provider `apiKey` 值会从源标记刷新(环境变量引用使用 `ENV_VAR_NAME`,file/exec 引用使用 `secretref-managed`),而不是持久化已解析的 secrets。 + - 由 SecretRef 管理的 provider header 值会从源标记刷新(环境变量引用使用 `secretref-env:ENV_VAR_NAME`,file/exec 引用使用 `secretref-managed`)。 + - 智能体缺失或为空的 `apiKey`/`baseUrl` 会回退到配置中的 `models.providers`。 - 匹配模型的 `contextWindow`/`maxTokens` 会在显式配置值和隐式目录值之间取较高者。 - - 匹配模型的 `contextTokens` 会在存在时保留显式运行时上限;可用它限制有效上下文,而不改变原生模型元数据。 - - 如果你希望配置完全重写 `models.json`,请使用 `models.mode: "replace"`。 - - 标记持久化以来源为准:标记从活动来源配置快照(解析前)写入,而不是从已解析的运行时 secret 值写入。 + - 匹配模型的 `contextTokens` 会在存在时保留显式运行时上限;用它来限制有效上下文,而不改变原生模型元数据。 + - 当你希望配置完整重写 `models.json` 时,使用 `models.mode: "replace"`。 + - 标记持久化以源为准:标记从当前源配置快照(解析前)写入,而不是从已解析的运行时 secret 值写入。 ### 提供商字段详情 -- `models.mode`:提供商目录行为(`merge` 或 `replace`)。 -- `models.providers`:以提供商 ID 为键的自定义提供商映射。 +- `models.mode`:provider 目录行为(`merge` 或 `replace`)。 +- `models.providers`:按 provider id 键控的自定义提供商映射。 - `models.providers.*.api`:请求适配器(`openai-completions`、`openai-responses`、`anthropic-messages`、`google-generative-ai` 等)。 -- `models.providers.*.apiKey`:提供商凭证(推荐使用 SecretRef/环境变量替换)。 -- `models.providers.*.auth`:身份验证策略(`api-key`、`token`、`oauth`、`aws-sdk`)。 -- `models.providers.*.injectNumCtxForOpenAICompat`:用于 Ollama + `openai-completions`,在请求中注入 `options.num_ctx`(默认:`true`)。 -- `models.providers.*.authHeader`:在需要时强制通过 `Authorization` header 传输凭证。 +- `models.providers.*.apiKey`:提供商凭证(优先使用 SecretRef/环境变量替换)。 +- `models.providers.*.auth`:认证策略(`api-key`、`token`、`oauth`、`aws-sdk`)。 +- `models.providers.*.injectNumCtxForOpenAICompat`:对于 Ollama + `openai-completions`,在请求中注入 `options.num_ctx`(默认:`true`)。 +- `models.providers.*.authHeader`:在需要时强制通过 `Authorization` 头传输凭证。 - `models.providers.*.baseUrl`:上游 API base URL。 -- `models.providers.*.headers`:用于代理/租户路由的额外静态 headers。 +- `models.providers.*.headers`:用于代理/租户路由的额外静态头。 - `models.providers.*.request`:模型提供商 HTTP 请求的传输覆盖。 - - `request.headers`:额外 headers(与提供商默认值合并)。值接受 SecretRef。 - - `request.auth`:身份验证策略覆盖。模式:`"provider-default"`(使用提供商内建身份验证)、`"authorization-bearer"`(配合 `token`)、`"header"`(配合 `headerName`、`value` 和可选 `prefix`)。 + - `request.headers`:额外头(与提供商默认值合并)。值接受 SecretRef。 + - `request.auth`:认证策略覆盖。模式:`"provider-default"`(使用提供商内置认证)、`"authorization-bearer"`(配合 `token`)、`"header"`(配合 `headerName`、`value` 和可选 `prefix`)。 - `request.proxy`:HTTP 代理覆盖。模式:`"env-proxy"`(使用 `HTTP_PROXY`/`HTTPS_PROXY` 环境变量)、`"explicit-proxy"`(配合 `url`)。两种模式都接受可选的 `tls` 子对象。 - - `request.tls`:直接连接时的 TLS 覆盖。字段:`ca`、`cert`、`key`、`passphrase`(都接受 SecretRef)、`serverName`、`insecureSkipVerify`。 + - `request.tls`:直接连接的 TLS 覆盖。字段:`ca`、`cert`、`key`、`passphrase`(都接受 SecretRef)、`serverName`、`insecureSkipVerify`。 - `models.providers.*.models`:显式提供商模型目录条目。 - `models.providers.*.models.*.contextWindow`:原生模型上下文窗口元数据。 -- `models.providers.*.models.*.contextTokens`:可选的运行时上下文上限。当你希望有效上下文预算小于模型原生 `contextWindow` 时使用。 -- `models.providers.*.models.*.compat.supportsDeveloperRole`:可选兼容性提示。对于 `api: "openai-completions"` 且非空、非原生 `baseUrl`(host 不是 `api.openai.com`)的情况,OpenClaw 会在运行时强制将其设为 `false`。空或省略的 `baseUrl` 会保留默认 OpenAI 行为。 +- `models.providers.*.models.*.contextTokens`:可选运行时上下文上限。如果你想要比模型原生 `contextWindow` 更小的有效上下文预算,可使用它。 +- `models.providers.*.models.*.compat.supportsDeveloperRole`:可选兼容性提示。对于 `api: "openai-completions"` 且非空、非原生的 `baseUrl`(host 不是 `api.openai.com`),OpenClaw 会在运行时强制将其设为 `false`。空或省略的 `baseUrl` 会保留默认 OpenAI 行为。 - `plugins.entries.amazon-bedrock.config.discovery`:Bedrock 自动发现设置根。 - `plugins.entries.amazon-bedrock.config.discovery.enabled`:开启/关闭隐式发现。 -- `plugins.entries.amazon-bedrock.config.discovery.region`:发现使用的 AWS 区域。 -- `plugins.entries.amazon-bedrock.config.discovery.providerFilter`:用于定向发现的可选 provider-id 过滤器。 +- `plugins.entries.amazon-bedrock.config.discovery.region`:发现所用 AWS 区域。 +- `plugins.entries.amazon-bedrock.config.discovery.providerFilter`:可选 provider-id 过滤器,用于定向发现。 - `plugins.entries.amazon-bedrock.config.discovery.refreshInterval`:发现刷新轮询间隔。 -- `plugins.entries.amazon-bedrock.config.discovery.defaultContextWindow`:已发现模型的回退上下文窗口。 -- `plugins.entries.amazon-bedrock.config.discovery.defaultMaxTokens`:已发现模型的回退最大输出 token 数。 +- `plugins.entries.amazon-bedrock.config.discovery.defaultContextWindow`:已发现模型的后备上下文窗口。 +- `plugins.entries.amazon-bedrock.config.discovery.defaultMaxTokens`:已发现模型的后备最大输出 token 数。 ### 提供商示例 @@ -2359,7 +2396,7 @@ OpenClaw 使用内置模型目录。通过配置中的 `models.providers` 或 `~ } ``` -Cerebras 使用 `cerebras/zai-glm-4.7`;Z.AI 直连使用 `zai/glm-4.7`。 +对 Cerebras 使用 `cerebras/zai-glm-4.7`;对 Z.AI 直连使用 `zai/glm-4.7`。 @@ -2376,7 +2413,7 @@ Cerebras 使用 `cerebras/zai-glm-4.7`;Z.AI 直连使用 `zai/glm-4.7`。 } ``` -设置 `OPENCODE_API_KEY`(或 `OPENCODE_ZEN_API_KEY`)。Zen 目录使用 `opencode/...` 引用,Go 目录使用 `opencode-go/...` 引用。快捷方式:`openclaw onboard --auth-choice opencode-zen` 或 `openclaw onboard --auth-choice opencode-go`。 +设置 `OPENCODE_API_KEY`(或 `OPENCODE_ZEN_API_KEY`)。对 Zen 目录使用 `opencode/...` 引用,对 Go 目录使用 `opencode-go/...` 引用。快捷方式:`openclaw onboard --auth-choice opencode-zen` 或 `openclaw onboard --auth-choice opencode-go`。 @@ -2393,11 +2430,11 @@ Cerebras 使用 `cerebras/zai-glm-4.7`;Z.AI 直连使用 `zai/glm-4.7`。 } ``` -设置 `ZAI_API_KEY`。`z.ai/*` 和 `z-ai/*` 都可作为别名接受。快捷方式:`openclaw onboard --auth-choice zai-api-key`。 +设置 `ZAI_API_KEY`。`z.ai/*` 和 `z-ai/*` 都可作为别名。快捷方式:`openclaw onboard --auth-choice zai-api-key`。 - 通用端点:`https://api.z.ai/api/paas/v4` - 编码端点(默认):`https://api.z.ai/api/coding/paas/v4` -- 若要使用通用端点,请定义一个带 base URL 覆盖的自定义提供商。 +- 若要使用通用端点,请定义带有 base URL 覆盖的自定义提供商。 @@ -2436,11 +2473,11 @@ Cerebras 使用 `cerebras/zai-glm-4.7`;Z.AI 直连使用 `zai/glm-4.7`。 } ``` -中国端点:`baseUrl: "https://api.moonshot.cn/v1"` 或 `openclaw onboard --auth-choice moonshot-api-key-cn`。 +对于中国端点:`baseUrl: "https://api.moonshot.cn/v1"` 或 `openclaw onboard --auth-choice moonshot-api-key-cn`。 -原生 Moonshot 端点会在共享 -`openai-completions` 传输上声明流式使用兼容性,OpenClaw 现在会根据端点 -能力而不是仅根据内置提供商 ID 来判断。 +原生 Moonshot 端点会在共享的 +`openai-completions` 传输层上声明流式使用兼容性,OpenClaw 现在根据端点 +能力而不是仅凭内置 provider id 来判定这一点。 @@ -2497,7 +2534,7 @@ Cerebras 使用 `cerebras/zai-glm-4.7`;Z.AI 直连使用 `zai/glm-4.7`。 } ``` -Base URL 应省略 `/v1`(Anthropic 客户端会追加它)。快捷方式:`openclaw onboard --auth-choice synthetic-api-key`。 +Base URL 不应包含 `/v1`(Anthropic 客户端会自动追加)。快捷方式:`openclaw onboard --auth-choice synthetic-api-key`。 @@ -2541,16 +2578,16 @@ Base URL 应省略 `/v1`(Anthropic 客户端会追加它)。快捷方式:` `openclaw onboard --auth-choice minimax-global-api` 或 `openclaw onboard --auth-choice minimax-cn-api`。 模型目录现在默认仅包含 M2.7。 -在兼容 Anthropic 的流式路径上,OpenClaw 默认禁用 MiniMax thinking, -除非你显式设置 `thinking`。`/fast on` 或 -`params.fastMode: true` 会将 `MiniMax-M2.7` 重写为 +在兼容 Anthropic 的流式路径上,除非你显式设置 `thinking`,否则 OpenClaw +默认会禁用 MiniMax thinking。`/fast on` 或 +`params.fastMode: true` 会把 `MiniMax-M2.7` 重写为 `MiniMax-M2.7-highspeed`。 -参见 [Local Models](/zh-CN/gateway/local-models)。简而言之:在性能足够强的硬件上,通过 LM Studio Responses API 运行大型本地模型;并保留托管模型合并配置用于回退。 +参见 [Local Models](/zh-CN/gateway/local-models)。简而言之:在性能较强的硬件上通过 LM Studio Responses API 运行大型本地模型;同时保留合并后的托管模型用于回退。 @@ -2582,12 +2619,13 @@ Base URL 应省略 `/v1`(Anthropic 客户端会追加它)。快捷方式:` ``` - `allowBundled`:仅针对内置 Skills 的可选允许列表(托管/工作区 Skills 不受影响)。 -- `load.extraDirs`:额外共享 Skill 根目录(最低优先级)。 -- `install.preferBrew`:为 true 时,如果 `brew` 可用,则优先使用 Homebrew 安装器,再回退到其他安装器类型。 -- `install.nodeManager`:用于 `metadata.openclaw.install` +- `load.extraDirs`:额外的共享 Skills 根目录(优先级最低)。 +- `install.preferBrew`:为 true 时,若 `brew` 可用,则优先使用 Homebrew 安装器, + 否则再回退到其他安装器类型。 +- `install.nodeManager`:`metadata.openclaw.install` 规范的 Node 安装器偏好(`npm` | `pnpm` | `yarn` | `bun`)。 - `entries..enabled: false`:即使某个 Skill 已内置/已安装,也会禁用它。 -- `entries..apiKey`:为声明了主环境变量的 Skills 提供便捷 API key 字段(明文字符串或 SecretRef 对象)。 +- `entries..apiKey`:对声明了主环境变量的 Skill 提供简便配置(明文字符串或 SecretRef 对象)。 --- @@ -2616,40 +2654,40 @@ Base URL 应省略 `/v1`(Anthropic 客户端会追加它)。快捷方式:` ``` - 从 `~/.openclaw/extensions`、`/.openclaw/extensions` 以及 `plugins.load.paths` 加载。 -- 设备发现支持原生 OpenClaw 插件,以及兼容的 Codex bundle 和 Claude bundle,包括无 manifest 的 Claude 默认布局 bundle。 +- 发现机制接受原生 OpenClaw 插件,以及兼容的 Codex bundle 和 Claude bundle,包括无 manifest 的 Claude 默认布局 bundle。 - **配置更改需要重启 Gateway 网关。** - `allow`:可选允许列表(仅加载列出的插件)。`deny` 优先。 - `plugins.entries..apiKey`:插件级 API key 便捷字段(当插件支持时)。 - `plugins.entries..env`:插件作用域环境变量映射。 -- `plugins.entries..hooks.allowPromptInjection`:为 `false` 时,core 会阻止 `before_prompt_build`,并忽略旧版 `before_agent_start` 中会修改提示的字段,同时保留旧版 `modelOverride` 和 `providerOverride`。适用于原生插件 hook 以及受支持 bundle 提供的 hook 目录。 -- `plugins.entries..subagent.allowModelOverride`:显式信任该插件,以便为后台子智能体运行请求按次 `provider` 和 `model` 覆盖。 -- `plugins.entries..subagent.allowedModels`:受信任子智能体覆盖可用的规范 `provider/model` 目标的可选允许列表。仅当你明确要允许任意模型时,才使用 `"*"`。 -- `plugins.entries..config`:插件定义的配置对象(如可用,将由原生 OpenClaw 插件 schema 验证)。 -- `plugins.entries.firecrawl.config.webFetch`:Firecrawl Web 抓取提供商设置。 +- `plugins.entries..hooks.allowPromptInjection`:为 `false` 时,core 会阻止 `before_prompt_build`,并忽略旧版 `before_agent_start` 中会修改提示的字段,同时保留旧版 `modelOverride` 和 `providerOverride`。适用于原生插件 hooks 和受支持的 bundle 提供 hooks 目录。 +- `plugins.entries..subagent.allowModelOverride`:显式信任该插件可以为后台子智能体运行请求每次运行级别的 `provider` 和 `model` 覆盖。 +- `plugins.entries..subagent.allowedModels`:受信任子智能体覆盖的可选规范 `provider/model` 目标允许列表。仅当你确实打算允许任意模型时才使用 `"*"`。 +- `plugins.entries..config`:插件定义的配置对象(若可用,会由原生 OpenClaw 插件 schema 校验)。 +- `plugins.entries.firecrawl.config.webFetch`:Firecrawl web 获取提供商设置。 - `apiKey`:Firecrawl API key(接受 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`)。 + - `onlyMainContent`:仅提取页面主内容(默认:`true`)。 + - `maxAgeMs`:最大缓存年龄(毫秒)(默认:`172800000` / 2 天)。 + - `timeoutSeconds`:抓取请求超时时间(秒)(默认:`60`)。 - `plugins.entries.xai.config.xSearch`:xAI X Search(Grok web 搜索)设置。 - `enabled`:启用 X Search 提供商。 - - `model`:用于搜索的 Grok 模型(例如 `"grok-4-1-fast"`)。 -- `plugins.entries.memory-core.config.dreaming`:记忆 dreaming(实验性)设置。关于阶段和阈值,请参见 [Dreaming](/zh-CN/concepts/dreaming)。 + - `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 * * *"`)。 - 阶段策略和阈值属于实现细节(不是面向用户的配置键)。 -- 已启用的 Claude bundle 插件也可以从 `settings.json` 提供内嵌 Pi 默认值;OpenClaw 会将它们作为已净化的智能体设置应用,而不是原始 OpenClaw 配置补丁。 -- `plugins.slots.memory`:选择活动记忆插件 ID,或设为 `"none"` 以禁用记忆插件。 -- `plugins.slots.contextEngine`:选择活动上下文引擎插件 ID;默认是 `"legacy"`,除非你安装并选择了其他引擎。 -- `plugins.installs`:由 CLI 管理的安装元数据,供 `openclaw plugins update` 使用。 - - 包含 `source`、`spec`、`sourcePath`、`installPath`、`version`、`resolvedName`、`resolvedVersion`、`resolvedSpec`、`integrity`、`shasum`、`resolvedAt`、`installedAt`。 - - 将 `plugins.installs.*` 视为托管状态;优先使用 CLI 命令而不是手动编辑。 +- 已启用的 Claude bundle 插件也可以从 `settings.json` 提供内嵌 Pi 默认值;OpenClaw 会将它们作为已清理的智能体设置应用,而不是原始 OpenClaw 配置补丁。 +- `plugins.slots.memory`:选择活动记忆插件 id,或设置为 `"none"` 以禁用记忆插件。 +- `plugins.slots.contextEngine`:选择活动上下文引擎插件 id;默认是 `"legacy"`,除非你安装并选择了其他引擎。 +- `plugins.installs`:CLI 管理的安装元数据,由 `openclaw plugins update` 使用。 + - 包括 `source`、`spec`、`sourcePath`、`installPath`、`version`、`resolvedName`、`resolvedVersion`、`resolvedSpec`、`integrity`、`shasum`、`resolvedAt`、`installedAt`。 + - 请将 `plugins.installs.*` 视为受管状态;优先使用 CLI 命令,而不是手动编辑。 参见 [Plugins](/zh-CN/tools/plugin)。 --- -## Browser 浏览器 +## 浏览器 ```json5 { @@ -2686,21 +2724,28 @@ Base URL 应省略 `/v1`(Anthropic 客户端会追加它)。快捷方式:` ``` - `evaluateEnabled: false` 会禁用 `act:evaluate` 和 `wait --fn`。 -- `ssrfPolicy.dangerouslyAllowPrivateNetwork` 在未设置时默认为 `true`(受信任网络模型)。 -- 对于严格的仅公共浏览器导航,请设置 `ssrfPolicy.dangerouslyAllowPrivateNetwork: false`。 -- 在严格模式下,远程 CDP 配置文件端点(`profiles.*.cdpUrl`)在可达性/设备发现检查期间也会受到同样的私有网络阻止。 -- `ssrfPolicy.allowPrivateNetwork` 仍支持作为旧版别名。 -- 在严格模式下,使用 `ssrfPolicy.hostnameAllowlist` 和 `ssrfPolicy.allowedHostnames` 作为显式例外。 -- 远程配置文件为仅附加模式(禁用 start/stop/reset)。 +- `ssrfPolicy.dangerouslyAllowPrivateNetwork` 在未设置时默认是 `true`(受信任网络模型)。 +- 如需严格的仅公共网络浏览导航,请设置 `ssrfPolicy.dangerouslyAllowPrivateNetwork: false`。 +- 在严格模式下,远程 CDP profile 端点(`profiles.*.cdpUrl`)在可达性/发现检查期间也会受相同的私有网络阻止策略约束。 +- `ssrfPolicy.allowPrivateNetwork` 仍被支持,作为旧版别名。 +- 在严格模式下,使用 `ssrfPolicy.hostnameAllowlist` 和 `ssrfPolicy.allowedHostnames` 进行显式例外配置。 +- 远程 profile 为仅附加模式(禁用 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 路由限制:基于快照/ref 的操作而非 CSS 选择器定位、单文件上传 hook、无对话框超时覆盖、无 `wait --load networkidle`,且不支持 `responsebody`、PDF 导出、下载拦截或批量操作。 -- 本地托管的 `openclaw` 配置文件会自动分配 `cdpPort` 和 `cdpUrl`;仅在远程 CDP 场景下显式设置 `cdpUrl`。 -- 自动检测顺序:默认浏览器(若为 Chromium 系)→ Chrome → Brave → Edge → Chromium → Chrome Canary。 + 当你希望 OpenClaw 发现 `/json/version` 时使用 HTTP(S); + 当提供商直接给出 DevTools WebSocket URL 时使用 WS(S)。 +- `existing-session` profile 仅限主机使用,并使用 Chrome MCP 而不是 CDP。 +- `existing-session` profile 可设置 `userDataDir`,用于指向特定的 + 基于 Chromium 的浏览器配置文件,例如 Brave 或 Edge。 +- `existing-session` profile 保持当前 Chrome MCP 路由限制: + 使用 snapshot/ref 驱动的动作而不是 CSS 选择器定位,仅支持单文件上传 + hook,不支持对话框超时覆盖,不支持 `wait --load networkidle`,也不支持 + `responsebody`、PDF 导出、下载拦截或批量动作。 +- 本地受管 `openclaw` profile 会自动分配 `cdpPort` 和 `cdpUrl`;仅在 + 远程 CDP 场景下显式设置 `cdpUrl`。 +- 自动检测顺序:默认浏览器(如果是基于 Chromium)→ Chrome → Brave → Edge → Chromium → Chrome Canary。 - 控制服务:仅 loopback(端口由 `gateway.port` 派生,默认 `18791`)。 -- `extraArgs` 会向本地 Chromium 启动附加额外 launch 标志(例如 `--disable-gpu`、窗口尺寸或调试标志)。 +- `extraArgs` 会将额外启动标志附加到本地 Chromium 启动命令中(例如 + `--disable-gpu`、窗口尺寸或调试标志)。 --- @@ -2718,8 +2763,8 @@ Base URL 应省略 `/v1`(Anthropic 客户端会追加它)。快捷方式:` } ``` -- `seamColor`:原生应用 UI 边框的强调色(Talk Mode 气泡色调等)。 -- `assistant`:Control UI identity 覆盖。会回退到活动智能体 identity。 +- `seamColor`:原生应用 UI 外观的强调色(Talk 模式气泡着色等)。 +- `assistant`:Control UI 身份覆盖。会回退到当前活动智能体身份。 --- @@ -2786,38 +2831,34 @@ Base URL 应省略 `/v1`(Anthropic 客户端会追加它)。快捷方式:` -- `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`),不要使用 host 别名(`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 绑定要求 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` 的身份头(参见 [Trusted Proxy Auth](/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 和身份验证范围生效(共享 secret 和设备 token 会分别跟踪)。被阻止的尝试会返回 `429` + `Retry-After`。 - - 在异步 Tailscale Serve Control UI 路径上,对于同一 `{scope, clientIp}` 的失败尝试,会在写入失败前进行串行化。因此,同一客户端的并发错误尝试可能会在第二个请求时触发限速,而不是两个都以普通不匹配方式通过竞争。 - - `gateway.auth.rateLimit.exemptLoopback` 默认为 `true`;如果你有意要让 localhost 流量也被限速(用于测试设置或严格代理部署),请设为 `false`。 -- 来自浏览器源的 WS 身份验证尝试始终会在禁用 loopback 豁免的情况下进行限速(作为针对基于浏览器的 localhost 暴力破解的纵深防御)。 -- 在 loopback 上,这些来自浏览器源的锁定会按规范化 `Origin` - 值进行隔离,因此来自某个 localhost origin 的重复失败不会自动锁定其他 origin。 -- `tailscale.mode`:`serve`(仅 tailnet,loopback 绑定)或 `funnel`(公开,需要身份验证)。 -- `controlUi.allowedOrigins`:用于 Gateway 网关 WebSocket 连接的显式浏览器来源允许列表。当预期浏览器客户端来自非 loopback 来源时必须设置。 -- `controlUi.dangerouslyAllowHostHeaderOriginFallback`:危险模式,允许依赖 Host 头 origin 策略的部署使用 Host 头 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` 的身份头(参见 [Trusted Proxy Auth](/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 的反复失败不会自动 + 锁定另一个 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 使用明文。 -- `gateway.remote.token` / `.password` 是远程客户端凭证字段。它们本身不会配置 Gateway 网关身份验证。 -- `gateway.push.apns.relay.baseUrl`:外部 APNs 中继的基础 HTTPS URL,官方/TestFlight iOS 构建在将基于中继的注册发布到 Gateway 网关后会使用它。此 URL 必须与编译进 iOS 构建中的中继 URL 匹配。 -- `gateway.push.apns.relay.timeoutMs`:Gateway 网关到中继的发送超时(毫秒)。默认值为 `10000`。 -- 基于中继的注册会委托给特定的 Gateway 网关 identity。已配对的 iOS 应用会获取 `gateway.identity.get`,将该 identity 包含在中继注册中,并将按注册范围的发送授权转发给 Gateway 网关。其他 Gateway 网关无法复用该已存储注册。 -- `OPENCLAW_APNS_RELAY_BASE_URL` / `OPENCLAW_APNS_RELAY_TIMEOUT_MS`:上述中继配置的临时环境变量覆盖。 -- `OPENCLAW_APNS_RELAY_ALLOW_HTTP=true`:仅供开发使用的逃生舱,允许 loopback HTTP 中继 URL。生产中继 URL 应保持使用 HTTPS。 -- `gateway.channelHealthCheckMinutes`:渠道健康监控间隔(分钟)。设为 `0` 可全局禁用健康监控重启。默认:`5`。 +- `OPENCLAW_ALLOW_INSECURE_PRIVATE_WS=1`:客户端紧急开关覆盖,允许明文 `ws://` 连接到受信任的私有网络 IP;默认情况下,明文仍仅限 loopback。 +- `gateway.remote.token` / `.password` 是远程客户端凭证字段。它们本身不会配置 gateway 认证。 +- `gateway.push.apns.relay.baseUrl`:官方/TestFlight iOS 构建将基于 relay 的注册发布到 gateway 后,gateway 所使用的外部 APNs relay 的 base 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..healthMonitor.enabled`:在保持全局监控启用的同时,为单个渠道选择退出健康监控重启。 -- `channels..accounts..healthMonitor.enabled`:多账号渠道的按账号覆盖。设置后,其优先级高于渠道级覆盖。 -- 只有在 `gateway.auth.*` 未设置时,本地 Gateway 网关调用路径才可将 `gateway.remote.*` 作为回退使用。 -- 如果 `gateway.auth.token` / `gateway.auth.password` 通过 SecretRef 显式配置但未解析,则解析会以默认拒绝的方式失败(不会使用远程回退来掩盖)。 -- `trustedProxies`:终止 TLS 或注入转发客户端头的反向代理 IP \ No newline at end of file +- `gateway.channelMaxRestartsPerHour`:滚动一小时内,每个渠道/账号允许的最大健康监控重启 \ No newline at end of file diff --git a/docs/zh-CN/gateway/doctor.md b/docs/zh-CN/gateway/doctor.md index aad6338ea..65ff32fcf 100644 --- a/docs/zh-CN/gateway/doctor.md +++ b/docs/zh-CN/gateway/doctor.md @@ -1,21 +1,21 @@ --- read_when: - - 添加或修改 Doctor 迁移 - - 引入破坏性配置更改 + - 添加或修改 doctor 迁移 + - 引入破坏性配置变更 summary: Doctor 命令:健康检查、配置迁移和修复步骤 title: Doctor x-i18n: - generated_at: "2026-04-05T18:14:18Z" + generated_at: "2026-04-06T12:43:39Z" model: gpt-5.4 provider: openai - source_hash: 6c0a15c522994552a1eef39206bed71fc5bf45746776372f24f31c101bfbd411 + source_hash: f20637d373c3b1be7c4a3d5424228908b5639cfded8ad5acb9c29f882d0f8d2b source_path: gateway/doctor.md workflow: 15 --- # Doctor -`openclaw doctor` 是 OpenClaw 的修复 + 迁移工具。它会修复过时的配置/状态、检查健康状况,并提供可执行的修复步骤。 +`openclaw doctor` 是 OpenClaw 的修复 + 迁移工具。它会修复过时的配置/状态,执行健康检查,并提供可操作的修复步骤。 ## 快速开始 @@ -35,7 +35,7 @@ openclaw doctor --yes openclaw doctor --repair ``` -应用推荐的修复而不提示(在安全的情况下执行修复 + 重启)。 +不经提示直接应用推荐修复(在安全的情况下进行修复 + 重启)。 ```bash openclaw doctor --repair --force @@ -47,8 +47,8 @@ openclaw doctor --repair --force openclaw doctor --non-interactive ``` -在无提示模式下运行,并且只应用安全迁移(配置规范化 + 磁盘状态移动)。跳过需要人工确认的重启/服务/沙箱操作。 -检测到旧版状态迁移时会自动运行。 +在无提示的情况下运行,并且仅应用安全迁移(配置规范化 + 磁盘状态移动)。跳过需要人工确认的重启/服务/沙箱操作。 +检测到旧状态迁移时会自动运行。 ```bash openclaw doctor --deep @@ -56,7 +56,7 @@ openclaw doctor --deep 扫描系统服务以查找额外的 Gateway 网关安装(`launchd`/`systemd`/`schtasks`)。 -如果你想在写入前先查看更改,请先打开配置文件: +如果你想在写入前查看更改,先打开配置文件: ```bash cat ~/.openclaw/openclaw.json @@ -64,67 +64,67 @@ cat ~/.openclaw/openclaw.json ## 它会做什么(摘要) -- 为 git 安装提供可选的预检更新(仅交互模式)。 +- 针对 git 安装的可选飞行前更新(仅交互式)。 - UI 协议新鲜度检查(当协议 schema 更新时重建 Control UI)。 - 健康检查 + 重启提示。 -- Skills 状态摘要(符合条件/缺失/被阻止)和插件状态。 -- 旧值的配置规范化。 +- Skills 状态摘要(可用/缺失/被阻止)和插件状态。 +- 对旧版值执行配置规范化。 - 将旧版扁平 `talk.*` 字段迁移到 `talk.provider` + `talk.providers.` 的 Talk 配置迁移。 - 针对旧版 Chrome 扩展配置和 Chrome MCP 就绪情况的浏览器迁移检查。 - OpenCode 提供商覆盖警告(`models.providers.opencode` / `models.providers.opencode-go`)。 -- OpenAI Codex OAuth 配置的 OAuth TLS 前置条件检查。 +- 针对 OpenAI Codex OAuth 配置文件的 OAuth TLS 前置条件检查。 - 旧版磁盘状态迁移(会话/智能体目录/WhatsApp 认证)。 -- 旧版插件清单契约键迁移(`speechProviders`、`realtimeTranscriptionProviders`、`realtimeVoiceProviders`、`mediaUnderstandingProviders`、`imageGenerationProviders`、`videoGenerationProviders`、`webFetchProviders`、`webSearchProviders` → `contracts`)。 +- 旧版插件清单 contract 键迁移(`speechProviders`、`realtimeTranscriptionProviders`、`realtimeVoiceProviders`、`mediaUnderstandingProviders`、`imageGenerationProviders`、`videoGenerationProviders`、`webFetchProviders`、`webSearchProviders` → `contracts`)。 - 旧版 cron 存储迁移(`jobId`、`schedule.cron`、顶层 delivery/payload 字段、payload `provider`、简单的 `notify: true` webhook 回退任务)。 - 会话锁文件检查和过期锁清理。 - 状态完整性和权限检查(会话、转录、状态目录)。 - 本地运行时的配置文件权限检查(`chmod 600`)。 -- 模型认证健康状况:检查 OAuth 过期情况,可刷新即将过期的令牌,并报告 auth-profile 的冷却/禁用状态。 -- 检测额外工作区目录(`~/openclaw`)。 -- 在启用沙箱隔离时修复沙箱镜像。 +- 模型认证健康状态:检查 OAuth 过期情况,可刷新即将过期的令牌,并报告认证配置文件的冷却/禁用状态。 +- 额外工作区目录检测(`~/openclaw`)。 +- 启用沙箱隔离时执行沙箱镜像修复。 - 旧版服务迁移和额外 Gateway 网关检测。 - Matrix 渠道旧版状态迁移(在 `--fix` / `--repair` 模式下)。 - Gateway 网关运行时检查(服务已安装但未运行;缓存的 `launchd` 标签)。 - 渠道状态警告(从正在运行的 Gateway 网关探测)。 -- Supervisor 配置审计(`launchd`/`systemd`/`schtasks`),并可选择修复。 +- supervisor 配置审计(`launchd`/`systemd`/`schtasks`)及可选修复。 - Gateway 网关运行时最佳实践检查(Node 与 Bun、版本管理器路径)。 - Gateway 网关端口冲突诊断(默认 `18789`)。 - 针对开放私信策略的安全警告。 -- 本地令牌模式下的 Gateway 网关认证检查(当没有令牌来源时提供生成令牌;不会覆盖令牌 SecretRef 配置)。 +- 本地令牌模式下的 Gateway 网关认证检查(当不存在令牌来源时提供生成令牌;不会覆盖令牌 SecretRef 配置)。 - Linux 上的 `systemd linger` 检查。 -- 工作区引导文件大小检查(上下文文件的截断/接近限制警告)。 +- 工作区 bootstrap 文件大小检查(上下文文件的截断/接近上限警告)。 - Shell 补全状态检查和自动安装/升级。 -- 记忆搜索嵌入提供商就绪检查(本地模型、远程 API 密钥或 `QMD` 二进制)。 -- 源码安装检查(`pnpm` 工作区不匹配、缺失 UI 资源、缺失 `tsx` 二进制)。 +- 内存搜索嵌入提供商就绪情况检查(本地模型、远程 API 密钥或 QMD 二进制文件)。 +- 源码安装检查(`pnpm` 工作区不匹配、缺失 UI 资源、缺失 `tsx` 二进制文件)。 - 写入更新后的配置 + 向导元数据。 -## 详细行为和原因说明 +## 详细行为和原理说明 ### 0)可选更新(git 安装) -如果这是一个 git 检出副本,并且 doctor 以交互模式运行,它会在运行 doctor 之前提供更新选项(fetch/rebase/build)。 +如果这是一个 git 检出副本,并且 doctor 以交互方式运行,它会在运行 doctor 之前提供更新选项(fetch/rebase/build)。 ### 1)配置规范化 -如果配置包含旧版值结构(例如 `messages.ackReaction` 没有特定于渠道的覆盖),doctor 会将其规范化为当前 schema。 +如果配置包含旧版值形态(例如 `messages.ackReaction` 没有渠道特定覆盖),doctor 会将其规范化为当前 schema。 -这也包括旧版 Talk 扁平字段。当前公开的 Talk 配置是 +这也包括旧版扁平 Talk 字段。当前公开的 Talk 配置是 `talk.provider` + `talk.providers.`。Doctor 会将旧的 `talk.voiceId` / `talk.voiceAliases` / `talk.modelId` / `talk.outputFormat` / -`talk.apiKey` 结构重写到提供商映射中。 +`talk.apiKey` 形式重写到 provider 映射中。 ### 2)旧版配置键迁移 -当配置包含已弃用键时,其他命令会拒绝运行,并要求你执行 +当配置中包含已弃用键时,其他命令会拒绝运行,并要求你运行 `openclaw doctor`。 -Doctor 会: +Doctor 将会: - 说明发现了哪些旧版键。 - 显示它应用的迁移。 - 使用更新后的 schema 重写 `~/.openclaw/openclaw.json`。 -当 Gateway 网关在启动时检测到旧版配置格式,它也会自动运行 doctor 迁移,因此过时配置无需手动干预即可修复。 +Gateway 网关 在启动时检测到旧版配置格式时,也会自动运行 doctor 迁移,因此过时配置无需手动干预即可被修复。 Cron 任务存储迁移由 `openclaw doctor --fix` 处理。 当前迁移包括: @@ -149,7 +149,7 @@ Cron 任务存储迁移由 `openclaw doctor --fix` 处理。 - `plugins.entries.voice-call.config.streaming.openaiApiKey|sttModel|silenceDurationMs|vadThreshold` → `plugins.entries.voice-call.config.streaming.providers.openai.*` - `bindings[].match.accountID` → `bindings[].match.accountId` -- 对于具有命名 `accounts`、但仍保留单账户顶层渠道值的渠道,将这些账户范围的值移动到为该渠道选择的提升账户中(大多数渠道使用 `accounts.default`;Matrix 可以保留现有匹配的命名/默认目标) +- 对于具有命名 `accounts` 但仍残留单账户顶层渠道值的渠道,将这些账户范围的值移动到该渠道所选的提升账户中(大多数渠道使用 `accounts.default`;Matrix 可保留现有匹配的命名/默认目标) - `identity` → `agents.list[].identity` - `agent.*` → `agents.defaults` + `tools.*`(tools/elevated/exec/sandbox/subagents) - `agent.model`/`allowedModels`/`modelAliases`/`modelFallbacks`/`imageModelFallbacks` @@ -158,57 +158,51 @@ Cron 任务存储迁移由 `openclaw doctor --fix` 处理。 - `browser.profiles.*.driver: "extension"` → `"existing-session"` - 删除 `browser.relayBindHost`(旧版扩展 relay 设置) -Doctor 警告还包括多账户渠道的默认账户指引: +Doctor 警告还包括针对多账户渠道的默认账户指导: -- 如果配置了两个或更多 `channels..accounts` 条目,但没有设置 `channels..defaultAccount` 或 `accounts.default`,doctor 会警告回退路由可能会选中意外的账户。 +- 如果配置了两个或更多 `channels..accounts` 条目,但没有 `channels..defaultAccount` 或 `accounts.default`,doctor 会警告回退路由可能会选择意外的账户。 - 如果 `channels..defaultAccount` 设置为未知账户 ID,doctor 会发出警告并列出已配置的账户 ID。 ### 2b)OpenCode 提供商覆盖 如果你手动添加了 `models.providers.opencode`、`opencode-zen` 或 `opencode-go`, 它会覆盖来自 `@mariozechner/pi-ai` 的内置 OpenCode 目录。 -这可能会把模型强制路由到错误的 API,或将成本清零。Doctor 会发出警告,以便你移除覆盖并恢复按模型进行的 API 路由 + 成本设置。 +这可能会将模型强制路由到错误的 API,或将成本归零。Doctor 会发出警告,以便你删除该覆盖并恢复按模型的 API 路由 + 成本。 ### 2c)浏览器迁移和 Chrome MCP 就绪情况 -如果你的浏览器配置仍然指向已移除的 Chrome 扩展路径,doctor -会将其规范化为当前基于主机本地的 Chrome MCP 附加模型: +如果你的浏览器配置仍指向已移除的 Chrome 扩展路径,doctor 会将其规范化为当前的主机本地 Chrome MCP 连接模型: - `browser.profiles.*.driver: "extension"` 变为 `"existing-session"` -- `browser.relayBindHost` 会被移除 +- 删除 `browser.relayBindHost` 当你使用 `defaultProfile: "user"` 或已配置的 `existing-session` 配置文件时,doctor 还会审计主机本地的 Chrome MCP 路径: -- 检查默认自动连接配置文件所用的同一主机上是否安装了 Google Chrome -- 检查检测到的 Chrome 版本,并在低于 Chrome 144 时发出警告 -- 提醒你在浏览器 inspect 页面中启用远程调试(例如 +- 检查默认自动连接配置文件是否在同一主机上安装了 Google Chrome +- 检查检测到的 Chrome 版本,并在其低于 Chrome 144 时发出警告 +- 提醒你在浏览器检查页面中启用远程调试(例如 `chrome://inspect/#remote-debugging`、`brave://inspect/#remote-debugging`, 或 `edge://inspect/#remote-debugging`) -Doctor 无法替你启用 Chrome 侧设置。主机本地 Chrome MCP -仍然要求: +Doctor 无法为你启用 Chrome 侧设置。主机本地 Chrome MCP +仍然需要: -- Gateway 网关/节点主机上有一个 144+ 的 Chromium 内核浏览器 +- Gateway 网关/节点主机上的 Chromium 内核浏览器 144+ - 浏览器在本地运行 - 在该浏览器中启用远程调试 -- 在浏览器中批准首次附加的同意提示 +- 在浏览器中批准首次连接的同意提示 -这里的就绪情况仅涉及本地附加前提条件。`existing-session` 会保留 -当前 Chrome MCP 路由限制;像 `responsebody`、PDF -导出、下载拦截和批量操作等高级路由,仍然需要受管浏览器 -或原始 CDP 配置文件。 +这里的就绪情况仅涉及本地连接前置条件。Existing-session 保留当前 Chrome MCP 路由限制;像 `responsebody`、PDF 导出、下载拦截和批处理操作这样的高级路由仍然需要受管浏览器或原始 CDP 配置文件。 -此检查**不**适用于 Docker、沙箱、remote-browser 或其他 -无头流程。这些流程会继续使用原始 CDP。 +此检查**不**适用于 Docker、沙箱、remote-browser 或其他无头流程。那些流程会继续使用原始 CDP。 ### 2d)OAuth TLS 前置条件 -当配置了 OpenAI Codex OAuth 配置文件时,doctor 会探测 OpenAI -授权端点,以验证本地 Node/OpenSSL TLS 栈是否可以校验证书链。如果探测因证书错误失败(例如 -`UNABLE_TO_GET_ISSUER_CERT_LOCALLY`、证书过期或自签名证书),doctor 会打印特定于平台的修复指引。在使用 Homebrew Node 的 macOS 上, -修复通常是 `brew postinstall ca-certificates`。使用 `--deep` 时, -即使 Gateway 网关健康,此探测也会运行。 +配置了 OpenAI Codex OAuth 配置文件时,doctor 会探测 OpenAI +授权端点,以验证本地 Node/OpenSSL TLS 栈是否能够校验证书链。如果探测因证书错误失败(例如 +`UNABLE_TO_GET_ISSUER_CERT_LOCALLY`、证书过期或自签名证书),doctor 会输出特定于平台的修复指导。在使用 Homebrew Node 的 macOS 上, +修复通常是 `brew postinstall ca-certificates`。使用 `--deep` 时,即使 Gateway 网关健康,该探测也会运行。 ### 3)旧版状态迁移(磁盘布局) @@ -219,26 +213,26 @@ Doctor 可以将旧版磁盘布局迁移到当前结构: - 智能体目录: - 从 `~/.openclaw/agent/` 到 `~/.openclaw/agents//agent/` - WhatsApp 认证状态(Baileys): - - 从旧版 `~/.openclaw/credentials/*.json`(不包括 `oauth.json`) - - 到 `~/.openclaw/credentials/whatsapp//...`(默认账户 ID:`default`) + - 从旧版 `~/.openclaw/credentials/*.json`(`oauth.json` 除外) + - 到 `~/.openclaw/credentials/whatsapp//...`(默认账户 id:`default`) -这些迁移是尽力而为且幂等的;doctor 会在留下任何旧版文件夹作为备份时发出警告。Gateway 网关/CLI 也会在启动时自动迁移旧版会话 + 智能体目录,因此历史记录/认证/模型会进入每个智能体路径,而无需手动运行 doctor。WhatsApp 认证则有意只通过 `openclaw doctor` 迁移。Talk provider/provider-map 规范化现在按结构相等进行比较,因此仅键顺序不同的差异不再触发重复的无操作 `doctor --fix` 更改。 +这些迁移尽力而为且可幂等;如果留下任何旧版文件夹作为备份,doctor 会发出警告。 +Gateway 网关/CLI 也会在启动时自动迁移旧版会话 + 智能体目录,因此历史记录/认证/模型会进入按智能体划分的路径,而无需手动运行 doctor。WhatsApp 认证则有意仅通过 `openclaw doctor` 迁移。Talk provider/provider-map 规范化现在按结构相等进行比较,因此仅键顺序不同的差异不再触发重复的无操作 `doctor --fix` 更改。 ### 3a)旧版插件清单迁移 -Doctor 会扫描所有已安装的插件清单,查找已弃用的顶层能力 +Doctor 会扫描所有已安装插件清单中的已弃用顶层 capability 键(`speechProviders`、`realtimeTranscriptionProviders`、 `realtimeVoiceProviders`、`mediaUnderstandingProviders`、 `imageGenerationProviders`、`videoGenerationProviders`、`webFetchProviders`、 -`webSearchProviders`)。找到后,它会提供将这些键移动到 `contracts` -对象中的选项,并原地重写清单文件。此迁移是幂等的; -如果 `contracts` 键中已存在相同值,则会移除旧版键, -而不会重复数据。 +`webSearchProviders`)。发现后,它会提供将它们移动到 `contracts` +对象并原地重写清单文件。此迁移是幂等的; +如果 `contracts` 键已经具有相同的值,则会删除旧版键,而不会重复数据。 ### 3b)旧版 cron 存储迁移 Doctor 还会检查 cron 任务存储(默认是 `~/.openclaw/cron/jobs.json`, -或在覆盖时使用 `cron.store`),查找调度器仍出于兼容性而接受的旧任务结构。 +或者在覆盖时使用 `cron.store`)中调度器仍为兼容性而接受的旧任务形态。 当前 cron 清理包括: @@ -247,232 +241,231 @@ Doctor 还会检查 cron 任务存储(默认是 `~/.openclaw/cron/jobs.json` - 顶层 payload 字段(`message`、`model`、`thinking`、...)→ `payload` - 顶层 delivery 字段(`deliver`、`channel`、`to`、`provider`、...)→ `delivery` - payload `provider` delivery 别名 → 显式 `delivery.channel` -- 简单的旧版 `notify: true` webhook 回退任务 → 显式 `delivery.mode="webhook"`,并配合 `delivery.to=cron.webhook` +- 简单旧版 `notify: true` webhook 回退任务 → 显式 `delivery.mode="webhook"` 并带有 `delivery.to=cron.webhook` -Doctor 仅在能够不改变行为的情况下自动迁移 `notify: true` 任务。 -如果某个任务将旧版 notify 回退与现有 -非 webhook delivery 模式结合使用,doctor 会发出警告,并将该任务留给人工审查。 +Doctor 仅会在能够不改变行为的情况下自动迁移 `notify: true` 任务。 +如果某个任务将旧版 notify 回退与现有非 webhook delivery 模式组合使用,doctor 会发出警告并将该任务留给你手动审查。 ### 3c)会话锁清理 -Doctor 会扫描每个智能体会话目录中是否存在过期写锁文件——即会话异常退出后遗留的文件。对于找到的每个锁文件,它会报告: -路径、PID、该 PID 是否仍然存活、锁文件存在时长,以及它是否 -被视为过期(PID 已死或存在时间超过 30 分钟)。在 `--fix` / `--repair` -模式下,它会自动移除过期锁文件;否则它会打印说明,并指示你使用 `--fix` 重新运行。 +Doctor 会扫描每个智能体会话目录中的过期写锁文件——即会话异常退出后遗留的文件。对于发现的每个锁文件,它会报告: +路径、PID、PID 是否仍存活、锁的年龄,以及它是否被视为过期(PID 已死亡或超过 30 分钟)。在 `--fix` / `--repair` +模式下,它会自动删除过期锁文件;否则会打印说明,并指示你使用 `--fix` 重新运行。 ### 4)状态完整性检查(会话持久化、路由和安全) -状态目录是运行中的中枢神经。如果它消失了,你会失去 -会话、凭证、日志和配置(除非你在其他地方有备份)。 +状态目录是运行中的核心中枢。如果它消失了,你将失去 +会话、凭证、日志和配置(除非你在别处有备份)。 Doctor 会检查: - **状态目录缺失**:警告灾难性的状态丢失,提示重新创建 - 目录,并提醒你它无法恢复缺失数据。 + 目录,并提醒你它无法恢复丢失的数据。 - **状态目录权限**:验证可写性;提供修复权限选项 - (并在检测到所有者/组不匹配时给出 `chown` 提示)。 -- **macOS 云同步状态目录**:当状态解析到 iCloud Drive + (检测到所有者/组不匹配时会给出 `chown` 提示)。 +- **macOS 云同步状态目录**:当状态路径解析到 iCloud Drive (`~/Library/Mobile Documents/com~apple~CloudDocs/...`)或 - `~/Library/CloudStorage/...` 下时发出警告,因为基于同步的路径可能导致更慢的 I/O + `~/Library/CloudStorage/...` 下时发出警告,因为由同步支持的路径可能导致更慢的 I/O 和锁/同步竞争。 -- **Linux SD 或 eMMC 状态目录**:当状态解析到 `mmcblk*` - 挂载源时发出警告,因为基于 SD 或 eMMC 的随机 I/O 在会话和凭证写入场景下可能更慢且磨损更快。 +- **Linux SD 或 eMMC 状态目录**:当状态路径解析到 `mmcblk*` + 挂载源时发出警告,因为基于 SD 或 eMMC 的随机 I/O 在会话和凭证写入下可能更慢且磨损更快。 - **会话目录缺失**:`sessions/` 和会话存储目录是 - 持久化历史并避免 `ENOENT` 崩溃所必需的。 + 持久保存历史记录并避免 `ENOENT` 崩溃所必需的。 - **转录不匹配**:当最近的会话条目缺少 转录文件时发出警告。 -- **主会话“单行 JSONL”**:当主转录只有一行时标记出来(历史未持续累积)。 -- **多个状态目录**:当不同主目录下存在多个 `~/.openclaw` 文件夹, - 或 `OPENCLAW_STATE_DIR` 指向其他位置时发出警告(历史记录可能在不同安装之间分裂)。 -- **远程模式提醒**:如果 `gateway.mode=remote`,doctor 会提醒你在远程主机上运行它 - (状态存储在那里)。 -- **配置文件权限**:如果 `~/.openclaw/openclaw.json` 可被 - 组/所有用户读取,则会发出警告,并提供将权限收紧为 `600` 的选项。 +- **主会话“1 行 JSONL”**:当主转录文件只有一行时标记出来(历史没有持续累积)。 +- **多个状态目录**:当不同 home 目录下存在多个 `~/.openclaw` 文件夹, + 或 `OPENCLAW_STATE_DIR` 指向其他位置时发出警告(历史可能在多个安装之间分裂)。 +- **远程模式提醒**:如果 `gateway.mode=remote`,doctor 会提醒你在 + 远程主机上运行它(状态存储在那里)。 +- **配置文件权限**:如果 `~/.openclaw/openclaw.json` 对 + 组/所有人可读,则会发出警告并提供收紧到 `600` 的选项。 -### 5)模型认证健康状况(OAuth 过期) +### 5)模型认证健康状态(OAuth 过期) Doctor 会检查认证存储中的 OAuth 配置文件,在令牌 -即将过期/已过期时发出警告,并可在安全的情况下刷新它们。如果 Anthropic +即将过期/已过期时发出警告,并在安全时进行刷新。如果 Anthropic OAuth/令牌配置文件已过期,它会建议使用 Anthropic API 密钥或旧版 Anthropic setup-token 路径。 -刷新提示仅在交互模式(TTY)下出现;`--non-interactive` +只有在交互式运行(TTY)时才会出现刷新提示;`--non-interactive` 会跳过刷新尝试。 -Doctor 还会检测过期且已移除的 Anthropic Claude CLI 状态。如果旧的 +Doctor 还会检测过时且已移除的 Anthropic Claude CLI 状态。如果旧的 `anthropic:claude-cli` 凭证字节仍存在于 `auth-profiles.json` 中, -doctor 会将其转换回 Anthropic 令牌/OAuth 配置文件,并重写 -过期的 `claude-cli/...` 模型引用。 -如果这些字节已不存在,doctor 会移除过期配置并打印恢复 -命令。 +doctor 会将其转换回 Anthropic 令牌/OAuth 配置文件,并重写过时的 +`claude-cli/...` 模型引用以及 `agents.defaults.cliBackends.claude-cli`。 +如果这些字节已不存在,doctor 会删除过时配置并输出恢复命令。 -Doctor 还会报告由于以下原因而暂时不可用的 auth profile: +Doctor 还会报告由于以下原因而暂时不可用的认证配置文件: -- 短期冷却(限流/超时/认证失败) -- 长期禁用(账单/余额失败) +- 短暂冷却(速率限制/超时/认证失败) +- 较长时间禁用(计费/额度失败) ### 6)Hooks 模型验证 -如果设置了 `hooks.gmail.model`,doctor 会根据目录和 allowlist 验证模型引用,并在它无法解析或不被允许时发出警告。 +如果设置了 `hooks.gmail.model`,doctor 会根据 +目录和 allowlist 验证该模型引用,并在无法解析或被禁止时发出警告。 ### 7)沙箱镜像修复 -当启用沙箱隔离时,doctor 会检查 Docker 镜像,并在当前镜像缺失时提供构建或切换到旧版名称的选项。 +启用沙箱隔离时,doctor 会检查 Docker 镜像,并在当前镜像缺失时提供构建或切换到旧版名称的选项。 ### 7b)内置插件运行时依赖 Doctor 会验证内置插件运行时依赖(例如 Discord 插件运行时包)是否存在于 OpenClaw 安装根目录中。 -如果缺失,doctor 会报告这些包,并在 +如果有任何缺失,doctor 会报告这些包,并在 `openclaw doctor --fix` / `openclaw doctor --repair` 模式下安装它们。 ### 8)Gateway 网关服务迁移和清理提示 -Doctor 会检测旧版 Gateway 网关服务(`launchd`/`systemd`/`schtasks`),并 -提供移除它们及使用当前 Gateway 网关端口安装 OpenClaw 服务的选项。它还可以扫描额外的类 Gateway 网关服务并打印清理提示。 -按 profile 命名的 OpenClaw Gateway 网关服务被视为一等公民,不会 -被标记为“额外”服务。 +Doctor 会检测旧版 Gateway 网关服务(`launchd`/`systemd`/`schtasks`), +并提供移除它们以及使用当前 Gateway 网关端口安装 OpenClaw 服务的选项。 +它还可以扫描额外的类 Gateway 网关服务并输出清理提示。 +带有配置文件名称的 OpenClaw Gateway 网关服务被视为一等公民,不会 +被标记为“额外”。 ### 8b)启动 Matrix 迁移 当 Matrix 渠道账户存在待处理或可执行的旧版状态迁移时, -doctor(在 `--fix` / `--repair` 模式下)会先创建迁移前快照,然后 -运行尽力而为的迁移步骤:旧版 Matrix 状态迁移和旧版 -加密状态准备。这两个步骤都不是致命的;错误会被记录,启动会继续进行。在只读模式下(不带 `--fix` 的 `openclaw doctor`),此检查 -会被完全跳过。 +doctor(在 `--fix` / `--repair` 模式下)会先创建迁移前快照, +然后运行尽力而为的迁移步骤:旧版 Matrix 状态迁移和旧版 +加密状态准备。这两个步骤都不是致命的;错误会被记录,启动会继续进行。在只读模式下(`openclaw doctor` 不带 `--fix`)此检查会被完全跳过。 ### 9)安全警告 -当某个提供商对私信开放却没有 allowlist,或 -某项策略以危险方式配置时,doctor 会发出警告。 +当某个提供商对私信开放但没有 allowlist,或 +当某个策略以危险方式配置时,doctor 会发出警告。 ### 10)systemd linger(Linux) -如果作为 `systemd` 用户服务运行,doctor 会确保启用了 lingering,以便 +如果作为 `systemd` 用户服务运行,doctor 会确保启用 lingering,以便 Gateway 网关在注销后仍保持运行。 ### 11)工作区状态(Skills、插件和旧版目录) -Doctor 会为默认智能体打印工作区状态摘要: +Doctor 会输出默认智能体的工作区状态摘要: -- **Skills 状态**:统计符合条件、缺失要求和被 allowlist 阻止的 Skills 数量。 +- **Skills 状态**:统计可用、缺少要求和被 allowlist 阻止的 Skills 数量。 - **旧版工作区目录**:当 `~/openclaw` 或其他旧版工作区目录 与当前工作区并存时发出警告。 -- **插件状态**:统计已加载/已禁用/出错的插件数量;列出出错插件的插件 ID; - 报告 bundle 插件能力。 -- **插件兼容性警告**:标记与当前运行时存在兼容性问题的插件。 -- **插件诊断**:呈现插件注册表在加载时发出的任何警告或错误。 +- **插件状态**:统计已加载/已禁用/出错的插件;列出任意 + 错误对应的插件 ID;报告 bundle 插件 capability。 +- **插件兼容性警告**:标记与 + 当前运行时存在兼容性问题的插件。 +- **插件诊断**:展示由 + 插件注册表在加载时发出的任何警告或错误。 -### 11b)引导文件大小 +### 11b)Bootstrap 文件大小 -Doctor 会检查工作区引导文件(例如 `AGENTS.md`、 +Doctor 会检查工作区 bootstrap 文件(例如 `AGENTS.md`、 `CLAUDE.md` 或其他注入的上下文文件)是否接近或超过已配置的 -字符预算。它会报告每个文件的原始字符数与注入字符数、截断 +字符预算。它会报告每个文件的原始字符数与注入后字符数、截断 百分比、截断原因(`max/file` 或 `max/total`),以及总注入 -字符数占总预算的比例。当文件被截断或接近 -限制时,doctor 会打印有关调整 `agents.defaults.bootstrapMaxChars` -和 `agents.defaults.bootstrapTotalMaxChars` 的提示。 +字符数占总预算的比例。当文件被截断或接近限制时,doctor 会输出调优 `agents.defaults.bootstrapMaxChars` +和 `agents.defaults.bootstrapTotalMaxChars` 的建议。 ### 11c)Shell 补全 Doctor 会检查当前 shell -(zsh、bash、fish 或 PowerShell)是否已安装 tab 补全: +(zsh、bash、fish 或 PowerShell)是否已安装 Tab 补全: - 如果 shell 配置文件使用较慢的动态补全模式 (`source <(openclaw completion ...)`),doctor 会将其升级为更快的 缓存文件变体。 - 如果补全已在配置文件中配置,但缓存文件缺失, doctor 会自动重新生成缓存。 -- 如果完全未配置补全,它会提示进行安装 +- 如果完全未配置补全, + doctor 会提示安装它 (仅交互模式;使用 `--non-interactive` 时跳过)。 运行 `openclaw completion --write-state` 可手动重新生成缓存。 ### 12)Gateway 网关认证检查(本地令牌) -Doctor 会检查本地 Gateway 网关令牌认证的就绪情况。 +Doctor 会检查本地 Gateway 网关令牌认证就绪情况。 -- 如果令牌模式需要令牌且没有令牌来源,doctor 会提供生成令牌的选项。 +- 如果令牌模式需要令牌但不存在令牌来源,doctor 会提供生成令牌的选项。 - 如果 `gateway.auth.token` 由 SecretRef 管理但不可用,doctor 会发出警告,并且不会用明文覆盖它。 -- `openclaw doctor --generate-gateway-token` 仅在未配置任何令牌 SecretRef 时强制生成。 +- `openclaw doctor --generate-gateway-token` 仅会在未配置令牌 SecretRef 时强制生成。 -### 12b)只读 SecretRef 感知修复 +### 12b)只读且感知 SecretRef 的修复 某些修复流程需要检查已配置的凭证,同时又不能削弱运行时快速失败行为。 -- `openclaw doctor --fix` 现在使用与状态类命令相同的只读 SecretRef 摘要模型,用于有针对性的配置修复。 -- 示例:Telegram `allowFrom` / `groupAllowFrom` 的 `@username` 修复会在可用时尝试使用已配置的机器人凭证。 -- 如果 Telegram 机器人令牌是通过 SecretRef 配置的,但在当前命令路径中不可用,doctor 会报告该凭证“已配置但不可用”,并跳过自动解析,而不是崩溃或误报令牌缺失。 +- `openclaw doctor --fix` 现在使用与 status 系列命令相同的只读 SecretRef 摘要模型来执行有针对性的配置修复。 +- 示例:Telegram `allowFrom` / `groupAllowFrom` `@username` 修复会在可用时尝试使用已配置的机器人凭证。 +- 如果 Telegram 机器人令牌通过 SecretRef 配置,但在当前命令路径中不可用,doctor 会报告该凭证“已配置但不可用”,并跳过自动解析,而不是崩溃或误报令牌缺失。 ### 13)Gateway 网关健康检查 + 重启 Doctor 会运行健康检查,并在 Gateway 网关看起来 不健康时提供重启选项。 -### 13b)记忆搜索就绪情况 +### 13b)内存搜索就绪情况 -Doctor 会检查为默认智能体配置的记忆搜索嵌入提供商是否已就绪。 -具体行为取决于已配置的后端和提供商: +Doctor 会检查为默认智能体配置的内存搜索嵌入提供商是否已就绪。 +行为取决于已配置的 backend 和 provider: -- **QMD 后端**:探测 `qmd` 二进制是否可用且可启动。 - 如果不可用,会打印修复指引,包括 npm 包和手动二进制路径选项。 -- **显式本地提供商**:检查本地模型文件或已识别的 - 远程/可下载模型 URL 是否存在。如果缺失,则建议切换到远程提供商。 -- **显式远程提供商**(`openai`、`voyage` 等):验证环境中或认证存储中是否存在 API 密钥。 - 如果缺失,会打印可执行的修复提示。 -- **自动提供商**:先检查本地模型可用性,然后按自动选择顺序尝试每个远程 - 提供商。 +- **QMD backend**:探测 `qmd` 二进制文件是否可用且可启动。 + 如果不可用,会输出修复指导,包括 npm 包和手动二进制路径选项。 +- **显式本地 provider**:检查本地模型文件或可识别的 + 远程/可下载模型 URL 是否存在。如果缺失,会建议切换到远程提供商。 +- **显式远程 provider**(`openai`、`voyage` 等):验证 API 密钥是否 + 存在于环境或认证存储中。如果缺失,会输出可操作的修复提示。 +- **自动 provider**:先检查本地模型可用性,然后按自动选择顺序尝试每个远程 + provider。 -当 Gateway 网关探测结果可用时(即检查时 Gateway 网关健康),doctor 会将其与 CLI 可见配置交叉对照,并指出 +当 Gateway 网关探测结果可用时(即检查时 Gateway 网关健康),doctor 会将其结果与 CLI 可见配置进行交叉比对,并注明 任何差异。 -使用 `openclaw memory status --deep` 在运行时验证嵌入就绪情况。 +使用 `openclaw memory status --deep` 可在运行时验证嵌入就绪情况。 ### 14)渠道状态警告 如果 Gateway 网关健康,doctor 会运行渠道状态探测,并报告 -附带建议修复方法的警告。 +带有建议修复方式的警告。 -### 15)Supervisor 配置审计 + 修复 +### 15)supervisor 配置审计 + 修复 -Doctor 会检查已安装的 supervisor 配置(`launchd`/`systemd`/`schtasks`),查看 -是否缺少或过期了默认值(例如 `systemd` 的 `network-online` 依赖和 -重启延迟)。当发现不匹配时,它会 -建议更新,并可将服务文件/任务重写为当前默认值。 +Doctor 会检查已安装的 supervisor 配置(`launchd`/`systemd`/`schtasks`)是否存在 +缺失或过时的默认值(例如 systemd 的 network-online 依赖项和 +重启延迟)。发现不匹配时,它会建议更新,并可以 +将服务文件/任务重写为当前默认值。 说明: -- `openclaw doctor` 会在重写 supervisor 配置前提示确认。 +- `openclaw doctor` 会在重写 supervisor 配置前进行提示。 - `openclaw doctor --yes` 会接受默认修复提示。 -- `openclaw doctor --repair` 会在无提示的情况下应用推荐修复。 +- `openclaw doctor --repair` 会不经提示应用推荐修复。 - `openclaw doctor --repair --force` 会覆盖自定义 supervisor 配置。 -- 如果令牌认证需要令牌,而 `gateway.auth.token` 由 SecretRef 管理,doctor 在安装/修复服务时会验证 SecretRef,但不会将解析出的明文令牌值持久化到 supervisor 服务环境元数据中。 -- 如果令牌认证需要令牌,而配置的令牌 SecretRef 无法解析,doctor 会阻止安装/修复路径,并提供可执行的指引。 -- 如果同时配置了 `gateway.auth.token` 和 `gateway.auth.password`,而 `gateway.auth.mode` 未设置,doctor 会阻止安装/修复,直到显式设置 mode。 -- 对于 Linux user-systemd 单元,doctor 的令牌漂移检查现在在比较服务认证元数据时会同时包含 `Environment=` 和 `EnvironmentFile=` 来源。 -- 你始终可以通过 `openclaw gateway install --force` 强制执行完整重写。 +- 如果令牌认证需要令牌,并且 `gateway.auth.token` 由 SecretRef 管理,doctor 在服务安装/修复时会验证 SecretRef,但不会将解析后的明文令牌值持久化到 supervisor 服务环境元数据中。 +- 如果令牌认证需要令牌,而已配置的令牌 SecretRef 无法解析,doctor 会阻止安装/修复路径,并给出可操作的指导。 +- 如果同时配置了 `gateway.auth.token` 和 `gateway.auth.password`,但未设置 `gateway.auth.mode`,doctor 会阻止安装/修复,直到明确设置模式。 +- 对于 Linux 用户级 systemd 单元,doctor 的令牌漂移检查现在会同时包含 `Environment=` 和 `EnvironmentFile=` 来源,以便比较服务认证元数据。 +- 你始终可以通过 `openclaw gateway install --force` 强制完整重写。 ### 16)Gateway 网关运行时 + 端口诊断 Doctor 会检查服务运行时(PID、上次退出状态),并在 -服务已安装但实际上未运行时发出警告。它还会检查 Gateway 网关端口 -(默认 `18789`)上的端口冲突,并报告可能原因(Gateway 网关已在运行、 -SSH 隧道)。 +服务已安装但实际上未运行时发出警告。它还会检查 +Gateway 网关端口(默认 `18789`)上的端口冲突,并报告可能原因(Gateway 网关已在运行、SSH 隧道)。 ### 17)Gateway 网关运行时最佳实践 -当 Gateway 网关服务运行在 Bun 或版本管理的 Node 路径 +当 Gateway 网关服务运行在 Bun 上,或运行在版本管理的 Node 路径 (`nvm`、`fnm`、`volta`、`asdf` 等)上时,doctor 会发出警告。WhatsApp + Telegram 渠道需要 Node, -而版本管理器路径在升级后可能会失效,因为服务不会 -加载你的 shell 初始化。Doctor 会在可用时提供迁移到系统 Node 安装(Homebrew/apt/choco)的选项。 +而版本管理器路径可能会在升级后失效,因为服务不会 +加载你的 shell 初始化。Doctor 会在系统 Node 安装可用时提供迁移到它的选项(Homebrew/apt/choco)。 ### 18)配置写入 + 向导元数据 -Doctor 会持久化所有配置更改,并写入向导元数据以记录 +Doctor 会持久化任何配置更改,并写入向导元数据以记录此次 doctor 运行。 -### 19)工作区提示(备份 + 记忆系统) +### 19)工作区提示(备份 + 内存系统) -当工作区缺少记忆系统时,doctor 会给出建议;如果工作区尚未处于 git 管理下,它还会打印备份提示。 +Doctor 会在缺失时建议设置工作区内存系统,并在工作区尚未纳入 git 管理时输出备份提示。 -参见 [/concepts/agent-workspace](/zh-CN/concepts/agent-workspace) 了解有关 +参见 [/concepts/agent-workspace](/zh-CN/concepts/agent-workspace),获取有关 工作区结构和 git 备份(推荐使用私有 GitHub 或 GitLab)的完整指南。 diff --git a/docs/zh-CN/help/faq.md b/docs/zh-CN/help/faq.md index c7433a834..1684dae3e 100644 --- a/docs/zh-CN/help/faq.md +++ b/docs/zh-CN/help/faq.md @@ -2,20 +2,20 @@ read_when: - 回答常见的设置、安装、新手引导或运行时支持问题时 - 在进行更深入调试之前,对用户报告的问题进行初步排查时 -summary: 关于 OpenClaw 设置、配置和使用的常见问题解答 +summary: 关于 OpenClaw 设置、配置和使用的常见问题 title: 常见问题 x-i18n: - generated_at: "2026-04-06T00:38:54Z" + generated_at: "2026-04-06T12:48:32Z" model: gpt-5.4 provider: openai - source_hash: 4d6d09621c6033d580cbcf1ff46f81587d69404d6f64c8d8fd8c3f09185bb920 + source_hash: 391262b77c6c9b35253fd46b7d6fab324816c3cc25830f322f840fad0c9f58cf source_path: help/faq.md workflow: 15 --- # 常见问题 -针对真实环境设置(本地开发、VPS、多智能体、OAuth/API 密钥、模型故障转移)的快速解答和更深入的故障排除。有关运行时诊断,请参阅 [故障排除](/zh-CN/gateway/troubleshooting)。有关完整的配置参考,请参阅 [Configuration](/zh-CN/gateway/configuration)。 +简明解答,以及针对真实场景部署(本地开发、VPS、多智能体、OAuth/API 密钥、模型故障切换)的更深入故障排除。关于运行时诊断,请参阅 [故障排除](/zh-CN/gateway/troubleshooting)。关于完整配置参考,请参阅 [Configuration](/zh-CN/gateway/configuration)。 ## 如果出现故障,最初的六十秒 @@ -33,7 +33,7 @@ x-i18n: openclaw status --all ``` - 只读诊断,包含日志尾部(令牌已脱敏)。 + 只读诊断,附带日志尾部(令牌已脱敏)。 3. **守护进程 + 端口状态** @@ -41,7 +41,7 @@ x-i18n: openclaw gateway status ``` - 显示 supervisor 运行时与 RPC 可达性、探测目标 URL,以及服务可能使用的是哪份配置。 + 显示监督器运行状态与 RPC 可达性、探测目标 URL,以及服务可能使用了哪个配置。 4. **深度探测** @@ -50,9 +50,9 @@ x-i18n: ``` 运行实时 Gateway 网关健康探测,包括在支持时的渠道探测 - (需要可访问的 Gateway 网关)。参阅 [Health](/zh-CN/gateway/health)。 + (需要可达的 Gateway 网关)。参阅 [Health](/zh-CN/gateway/health)。 -5. **查看最新日志尾部** +5. **跟踪最新日志** ```bash openclaw logs --follow @@ -64,7 +64,7 @@ x-i18n: tail -f "$(ls -t /tmp/openclaw/openclaw-*.log | head -1)" ``` - 文件日志与服务日志是分开的;参阅 [Logging](/zh-CN/logging) 和 [故障排除](/zh-CN/gateway/troubleshooting)。 + 文件日志与服务日志是分开的;请参阅 [Logging](/zh-CN/logging) 和 [故障排除](/zh-CN/gateway/troubleshooting)。 6. **运行 Doctor(修复)** @@ -72,13 +72,13 @@ x-i18n: openclaw doctor ``` - 修复/迁移配置和状态 + 运行健康检查。参阅 [Doctor](/zh-CN/gateway/doctor)。 + 修复/迁移配置与状态 + 运行健康检查。参阅 [Doctor](/zh-CN/gateway/doctor)。 7. **Gateway 网关快照** ```bash openclaw health --json - openclaw health --verbose # shows the target URL + config path on errors + openclaw health --verbose # 出错时显示目标 URL + 配置路径 ``` 向正在运行的 Gateway 网关请求完整快照(仅 WS)。参阅 [Health](/zh-CN/gateway/health)。 @@ -87,33 +87,33 @@ x-i18n: - 使用一个能**看到你的机器**的本地 AI 智能体。这比去 Discord 提问有效得多, - 因为大多数“我卡住了”的情况其实是**本地配置或环境问题**, + 使用一个能**看到你的机器**的本地 AI 智能体。这比在 Discord 里提问 + 有效得多,因为大多数“我卡住了”的情况其实都是**本地配置或环境问题**, 远程协助者无法直接检查。 - - **Claude Code**: [https://www.anthropic.com/claude-code/](https://www.anthropic.com/claude-code/) - - **OpenAI Codex**: [https://openai.com/codex/](https://openai.com/codex/) + - **Claude Code**: [https://www.anthropic.com/claude-code/](https://www.anthropic.com/claude-code/) + - **OpenAI Codex**: [https://openai.com/codex/](https://openai.com/codex/) - 这些工具可以读取仓库、运行命令、检查日志,并帮助修复你的机器级别设置 - (PATH、服务、权限、认证文件)。通过可修改的(git)安装方式, - 把**完整源码检出**交给它们: + 这些工具可以读取仓库、运行命令、检查日志,并帮助修复你机器层面的 + 设置问题(PATH、服务、权限、认证文件)。通过可修改的(git)安装方式, + 把**完整源代码检出**交给它们: ```bash curl -fsSL https://openclaw.ai/install.sh | bash -s -- --install-method git ``` - 这会通过 **git 检出**安装 OpenClaw,因此智能体可以读取代码 + 文档, - 并根据你正在运行的确切版本进行推理。以后你随时都可以 - 通过不带 `--install-method git` 重新运行安装器切回稳定版。 + 这会**从 git 检出**安装 OpenClaw,因此智能体可以读取代码 + 文档, + 并准确理解你当前运行的版本。之后你始终可以通过重新运行安装程序并去掉 + `--install-method git` 切回稳定版。 - 提示:让智能体先**规划并监督**修复过程(逐步执行),然后只执行 + 提示:让智能体先**规划并监督**修复过程(逐步进行),然后只执行 必要的命令。这样改动会更小,也更容易审计。 如果你发现了真实的 bug 或修复,请提交 GitHub issue 或发送 PR: [https://github.com/openclaw/openclaw/issues](https://github.com/openclaw/openclaw/issues) [https://github.com/openclaw/openclaw/pulls](https://github.com/openclaw/openclaw/pulls) - 先从这些命令开始(在寻求帮助时分享输出): + 先从这些命令开始(在求助时分享输出): ```bash openclaw status @@ -123,31 +123,30 @@ x-i18n: 它们的作用: - - `openclaw status`:快速查看 Gateway 网关/智能体健康状态 + 基本配置。 + - `openclaw status`:快速查看 Gateway 网关/智能体健康状态 + 基础配置。 - `openclaw models status`:检查提供商认证 + 模型可用性。 - - `openclaw doctor`:验证并修复常见配置/状态问题。 + - `openclaw doctor`:验证并修复常见的配置/状态问题。 - 其他有用的 CLI 检查:`openclaw status --all`, `openclaw logs --follow`, - `openclaw gateway status`, `openclaw health --verbose`。 + 其他有用的 CLI 检查:`openclaw status --all`、`openclaw logs --follow`、 + `openclaw gateway status`、`openclaw health --verbose`。 - 快速调试循环: [如果出现故障,最初的六十秒](#如果出现故障最初的六十秒)。 - 安装文档: [Install](/zh-CN/install), [Installer flags](/zh-CN/install/installer), [Updating](/zh-CN/install/updating)。 + 快速调试循环:[如果出现故障,最初的六十秒](#first-60-seconds-if-something-is-broken)。 + 安装文档:[Install](/zh-CN/install)、[Installer flags](/zh-CN/install/installer)、[Updating](/zh-CN/install/updating)。 - + 常见的 Heartbeat 跳过原因: - - `quiet-hours`:不在配置的活跃时间窗口内 - - `empty-heartbeat-file`:`HEARTBEAT.md` 存在,但只包含空白/仅标题的脚手架内容 - - `no-tasks-due`:`HEARTBEAT.md` 任务模式已启用,但还没有任何任务间隔到期 - - `alerts-disabled`:所有 Heartbeat 可见性都被禁用(`showOk`、`showAlerts` 和 `useIndicator` 全部关闭) + - `quiet-hours`:当前不在已配置的活跃时间窗口内 + - `empty-heartbeat-file`:`HEARTBEAT.md` 存在,但只包含空白/仅标题脚手架内容 + - `no-tasks-due`:`HEARTBEAT.md` 任务模式已启用,但当前没有任何任务间隔到期 + - `alerts-disabled`:所有 Heartbeat 可见性都已禁用(`showOk`、`showAlerts` 和 `useIndicator` 全部关闭) - 在任务模式下,只有在真正的 Heartbeat 运行 - 完成后,才会推进到期时间戳。 - 被跳过的运行不会将任务标记为已完成。 + 在任务模式下,只有在一次真实的 Heartbeat 运行 + 完成后,才会推进到期时间戳。被跳过的运行不会将任务标记为已完成。 - 文档: [Heartbeat](/zh-CN/gateway/heartbeat), [自动化与任务](/zh-CN/automation)。 + 文档:[Heartbeat](/zh-CN/gateway/heartbeat)、[Automation & Tasks](/zh-CN/automation)。 @@ -159,103 +158,103 @@ x-i18n: openclaw onboard --install-daemon ``` - 向导还可以自动构建 UI 资源。完成新手引导后,你通常会在 **18789** 端口运行 Gateway 网关。 + 该向导还可以自动构建 UI 资源。完成新手引导后,你通常会在 **18789** 端口运行 Gateway 网关。 - 从源码运行(贡献者/开发者): + 从源码安装(贡献者/开发者): ```bash git clone https://github.com/openclaw/openclaw.git cd openclaw pnpm install pnpm build - pnpm ui:build # auto-installs UI deps on first run + pnpm ui:build # 首次运行时自动安装 UI 依赖 openclaw onboard ``` - 如果你还没有全局安装,请通过 `pnpm openclaw onboard` 运行。 + 如果你还没有全局安装,可以通过 `pnpm openclaw onboard` 来运行。 - 向导会在新手引导完成后立即用干净的(不带令牌的)仪表板 URL 打开你的浏览器,并且也会在摘要中打印链接。保持该标签页打开;如果它没有自动启动,请在同一台机器上复制/粘贴打印出来的 URL。 + 向导会在新手引导完成后立即使用一个干净的(不带令牌的)仪表板 URL 打开你的浏览器,并且也会在摘要中打印该链接。请保持该标签页打开;如果没有自动启动,就在同一台机器上复制/粘贴打印出的 URL。 - **Localhost(同一台机器):** + **localhost(同一台机器):** - 打开 `http://127.0.0.1:18789/`。 - 如果它要求共享密钥认证,请将已配置的令牌或密码粘贴到 Control UI 设置中。 - 令牌来源:`gateway.auth.token`(或 `OPENCLAW_GATEWAY_TOKEN`)。 - 密码来源:`gateway.auth.password`(或 `OPENCLAW_GATEWAY_PASSWORD`)。 - - 如果尚未配置共享密钥,请使用 `openclaw doctor --generate-gateway-token` 生成一个令牌。 + - 如果尚未配置共享密钥,可以通过 `openclaw doctor --generate-gateway-token` 生成一个令牌。 **不在 localhost:** - - **Tailscale Serve**(推荐):保持 bind loopback,运行 `openclaw gateway --tailscale serve`,然后打开 `https:///`。如果 `gateway.auth.allowTailscale` 为 `true`,身份头会满足 Control UI/WebSocket 认证(无需粘贴共享密钥,假定 Gateway 网关主机可信);HTTP API 仍然需要共享密钥认证,除非你明确使用 private-ingress `none` 或 trusted-proxy HTTP auth。 - 来自同一客户端的并发 Serve 错误认证尝试会在 failed-auth limiter 记录之前被串行化,因此第二次错误重试就可能已经显示 `retry later`。 - - **Tailnet bind**:运行 `openclaw gateway --bind tailnet --token ""`(或配置密码认证),打开 `http://:18789/`,然后在仪表板设置中粘贴匹配的共享密钥。 - - **支持身份感知的反向代理**:将 Gateway 网关置于非 loopback 的 trusted proxy 后面,配置 `gateway.auth.mode: "trusted-proxy"`,然后打开代理 URL。 - - **SSH 隧道**:`ssh -N -L 18789:127.0.0.1:18789 user@host` 然后打开 `http://127.0.0.1:18789/`。共享密钥认证仍然会通过隧道生效;如果提示,请粘贴配置的令牌或密码。 + - **Tailscale Serve**(推荐):保持绑定 loopback,运行 `openclaw gateway --tailscale serve`,打开 `https:///`。如果 `gateway.auth.allowTailscale` 为 `true`,身份头会满足 Control UI/WebSocket 认证要求(无需粘贴共享密钥,假定 Gateway 网关主机可信);HTTP API 仍然需要共享密钥认证,除非你明确使用私有入口 `none` 或受信任代理 HTTP 认证。 + 来自同一客户端的错误并发 Serve 认证尝试会在失败认证限速器记录前被串行化,因此第二次错误重试可能已经显示 `retry later`。 + - **tailnet 绑定**:运行 `openclaw gateway --bind tailnet --token ""`(或配置密码认证),打开 `http://:18789/`,然后在仪表板设置中粘贴匹配的共享密钥。 + - **身份感知反向代理**:让 Gateway 网关保持在一个非 loopback 的受信任代理后面,配置 `gateway.auth.mode: "trusted-proxy"`,然后打开代理 URL。 + - **SSH 隧道**:`ssh -N -L 18789:127.0.0.1:18789 user@host`,然后打开 `http://127.0.0.1:18789/`。共享密钥认证在隧道上传输时仍然适用;如果出现提示,请粘贴已配置的令牌或密码。 - 有关 bind 模式和认证细节,请参阅 [Dashboard](/web/dashboard) 和 [Web surfaces](/web)。 + 关于绑定模式和认证细节,请参阅 [Dashboard](/web/dashboard) 和 [Web surfaces](/web)。 - + 它们控制的是不同层级: - `approvals.exec`:将审批提示转发到聊天目标 - - `channels..execApprovals`:让该渠道充当 exec 审批的原生审批客户端 + - `channels..execApprovals`:让该渠道作为 exec 审批的原生审批客户端 - 主机 exec 策略仍然是真正的审批关卡。聊天配置只控制审批 - 提示出现在哪里,以及人们如何回应它们。 + 主机 exec 策略仍然是真正的审批门禁。聊天配置只控制审批 + 提示出现在哪里,以及人们如何回应。 - 在大多数设置中,你**不**需要同时配置两者: + 在大多数设置中,你**不**需要同时启用两者: - - 如果聊天已经支持命令和回复,则同一聊天中的 `/approve` 会通过共享路径工作。 - - 如果支持的原生渠道可以安全推断审批人,OpenClaw 现在会在 `channels..execApprovals.enabled` 未设置或为 `"auto"` 时,自动启用私信优先的原生审批。 - - 当原生审批卡片/按钮可用时,该原生 UI 是主要路径;只有当工具结果表明聊天审批不可用或手动审批是唯一途径时,智能体才应包含手动 `/approve` 命令。 - - 只有当提示还必须转发到其他聊天或明确的运维房间时,才使用 `approvals.exec`。 - - 只有当你明确希望审批提示发回原始房间/话题时,才使用 `channels..execApprovals.target: "channel"` 或 `"both"`。 - - 插件审批又是另一个体系:它们默认使用同一聊天中的 `/approve`、可选的 `approvals.plugin` 转发,并且只有某些原生渠道会在此基础上保留 plugin-approval-native 处理。 + - 如果聊天本身已经支持命令和回复,那么同一聊天中的 `/approve` 会通过共享路径生效。 + - 如果某个受支持的原生渠道可以安全推断审批人,OpenClaw 现在会在 `channels..execApprovals.enabled` 未设置或为 `"auto"` 时自动启用私信优先的原生审批。 + - 当存在原生审批卡片/按钮时,该原生 UI 是主路径;只有当工具结果表明聊天审批不可用或手动审批是唯一途径时,智能体才应包含手动 `/approve` 命令。 + - 只有当提示还需要转发到其他聊天或明确的运维房间时,才使用 `approvals.exec`。 + - 只有当你明确希望把审批提示发回原始房间/主题时,才使用 `channels..execApprovals.target: "channel"` 或 `"both"`。 + - 插件审批则是另外一套:默认使用同一聊天中的 `/approve`,可选 `approvals.plugin` 转发,并且只有部分原生渠道会在其之上保留原生插件审批处理。 - 简短来说:转发用于路由,原生客户端配置用于提供更丰富的渠道特定 UX。 + 简而言之:转发用于路由,原生客户端配置用于更丰富的渠道特定 UX。 参阅 [Exec Approvals](/zh-CN/tools/exec-approvals)。 - 需要 Node **>= 22**。推荐使用 `pnpm`。Gateway 网关**不推荐**使用 Bun。 + 需要 Node **>= 22**。推荐使用 `pnpm`。**不推荐**使用 Bun 运行 Gateway 网关。 - 可以。Gateway 网关很轻量——文档中写明个人使用只需 **512MB-1GB RAM**、**1 个核心**,以及大约 **500MB** - 磁盘空间,并指出 **Raspberry Pi 4 可以运行它**。 + 可以。Gateway 网关非常轻量——文档中写明个人使用场景下 **512 MB - 1 GB RAM**、**1 个核心** 和大约 **500 MB** + 磁盘空间就足够,并且注明 **Raspberry Pi 4 可以运行它**。 - 如果你想要更多余量(日志、媒体、其他服务),推荐 **2GB**, + 如果你想留出更多余量(日志、媒体、其他服务),推荐使用 **2 GB**, 但这不是硬性最低要求。 - 提示:小型 Pi/VPS 可以托管 Gateway 网关,你还可以在笔记本/手机上配对 **nodes**, - 以获得本地屏幕/相机/canvas 或命令执行能力。参阅 [Nodes](/zh-CN/nodes)。 + 提示:小型 Pi/VPS 可以托管 Gateway 网关,而你可以在笔记本/手机上配对**节点**, + 以实现本地屏幕/摄像头/画布或命令执行。参阅 [Nodes](/zh-CN/nodes)。 - 简短回答:能用,但预计会有一些粗糙边缘。 + 简短回答:可以运行,但要预期会遇到一些边角问题。 - - 使用 **64 位**系统,并保持 Node >= 22。 - - 优先选择**可修改的(git)安装**,这样你可以查看日志并快速更新。 - - 先不要启用渠道/Skills,然后逐个添加。 - - 如果你遇到奇怪的二进制问题,通常是 **ARM 兼容性**问题。 + - 使用 **64 位**操作系统,并保持 Node >= 22。 + - 优先使用**可修改的(git)安装**,这样你可以查看日志并快速更新。 + - 先不要启用 channels/Skills,然后逐个添加。 + - 如果遇到奇怪的二进制问题,通常是 **ARM 兼容性**问题。 - 文档: [Linux](/zh-CN/platforms/linux), [Install](/zh-CN/install)。 + 文档:[Linux](/zh-CN/platforms/linux)、[Install](/zh-CN/install)。 - - 该界面依赖于 Gateway 网关可访问且已认证。TUI 也会在首次 hatch 时自动发送 - “Wake up, my friend!”。如果你看到这行文字但**没有回复**, - 且令牌一直是 0,说明智能体根本没有运行。 + + 该界面依赖 Gateway 网关可达且已认证。TUI 也会在首次 hatch 时自动发送 + “Wake up, my friend!”。如果你看到这行字却**没有回复**, + 且 token 仍然为 0,说明智能体从未真正运行。 1. 重启 Gateway 网关: @@ -278,13 +277,13 @@ x-i18n: ``` 如果 Gateway 网关是远程的,请确保隧道/Tailscale 连接正常,并且 UI - 指向了正确的 Gateway 网关。参阅 [远程访问](/zh-CN/gateway/remote)。 + 指向了正确的 Gateway 网关。参阅 [Remote access](/zh-CN/gateway/remote)。 - - 可以。复制**状态目录**和**工作区**,然后运行一次 Doctor 即可。这样 - 能让你的机器人“完全保持一致”(记忆、会话历史、认证和渠道 + + 可以。复制**状态目录**和**工作区**,然后运行一次 Doctor。这会 + 让你的机器人“完全保持一致”(记忆、会话历史、认证和渠道 状态),前提是你复制了**这两个**位置: 1. 在新机器上安装 OpenClaw。 @@ -292,60 +291,61 @@ x-i18n: 3. 复制你的工作区(默认:`~/.openclaw/workspace`)。 4. 运行 `openclaw doctor` 并重启 Gateway 网关服务。 - 这样会保留配置、认证配置文件、WhatsApp 凭据、会话和记忆。如果你正在使用 - 远程模式,请记住会话存储和工作区都归 gateway host 所有。 + 这会保留配置、认证档案、WhatsApp 凭据、会话和记忆。如果你处于 + 远程模式,请记住会话存储和工作区都由 gateway 主机持有。 - **重要:**如果你只是把工作区提交/推送到 GitHub,你备份的是 - **记忆 + 引导文件**,但**不是**会话历史或认证。这些数据位于 + **重要:**如果你只把工作区提交/推送到 GitHub,你备份的是 + **记忆 + 引导文件**,但**不是**会话历史或认证。这些都位于 `~/.openclaw/` 下(例如 `~/.openclaw/agents//sessions/`)。 - 相关内容: [迁移](/zh-CN/install/migrating), [磁盘上的文件位置](#磁盘上的文件位置), - [智能体工作区](/zh-CN/concepts/agent-workspace), [Doctor](/zh-CN/gateway/doctor), - [远程模式](/zh-CN/gateway/remote)。 + 相关内容:[Migrating](/zh-CN/install/migrating)、[磁盘上的存储位置](#where-things-live-on-disk)、 + [Agent workspace](/zh-CN/concepts/agent-workspace)、[Doctor](/zh-CN/gateway/doctor)、 + [Remote mode](/zh-CN/gateway/remote)。 - + 查看 GitHub 更新日志: [https://github.com/openclaw/openclaw/blob/main/CHANGELOG.md](https://github.com/openclaw/openclaw/blob/main/CHANGELOG.md) - 最新条目位于顶部。如果顶部部分标记为 **Unreleased**,那么下一个带日期的 + 最新条目位于顶部。如果最顶部的部分标记为 **Unreleased**,则下一节带日期的 部分就是最新发布版本。条目按 **Highlights**、**Changes** 和 - **Fixes** 分组(必要时还会有 docs/other 等部分)。 + **Fixes** 分组(必要时还会有 docs/其他部分)。 - 一些 Comcast/Xfinity 连接会通过 Xfinity - Advanced Security 错误地拦截 `docs.openclaw.ai`。请禁用它或将 `docs.openclaw.ai` 加入允许列表,然后重试。 - 也请通过这里帮助我们解除拦截: [https://spa.xfinity.com/check_url_status](https://spa.xfinity.com/check_url_status)。 + 某些 Comcast/Xfinity 连接会被 Xfinity + Advanced Security 错误地拦截 `docs.openclaw.ai`。请禁用它或将 `docs.openclaw.ai` + 加入允许列表,然后重试。 + 也请通过这里帮助我们解除拦截:[https://spa.xfinity.com/check_url_status](https://spa.xfinity.com/check_url_status)。 - 如果你仍然无法访问该站点,文档在 GitHub 上也有镜像: + 如果你仍然无法访问该站点,文档也镜像在 GitHub 上: [https://github.com/openclaw/openclaw/tree/main/docs](https://github.com/openclaw/openclaw/tree/main/docs) - - **稳定版**和 **beta** 是 **npm dist-tags**,而不是不同的代码线: + + **稳定版**和 **beta** 是 **npm dist-tag**,不是两条独立的代码线: - `latest` = 稳定版 - `beta` = 用于测试的早期构建 - 通常,一个稳定版本会先发布到 **beta**,然后再通过明确的 - 提升步骤将同一版本移动到 `latest`。维护者也可以在必要时 - 直接发布到 `latest`。这就是为什么 beta 和稳定版在提升之后 + 通常,一个稳定版本会先发布到 **beta**,然后通过一次显式 + 提升步骤把同一个版本移动到 `latest`。维护者在需要时也可以 + 直接发布到 `latest`。这就是为什么 beta 和稳定版在提升后 可能指向**同一个版本**。 - 查看变更内容: + 查看更改内容: [https://github.com/openclaw/openclaw/blob/main/CHANGELOG.md](https://github.com/openclaw/openclaw/blob/main/CHANGELOG.md) 关于安装一行命令以及 beta 和 dev 的区别,请参阅下面的折叠项。 - + **Beta** 是 npm dist-tag `beta`(提升后可能与 `latest` 相同)。 - **Dev** 是 `main` 的移动头部(git);发布到 npm 时,它使用 npm dist-tag `dev`。 + **Dev** 是 `main` 的滚动头部版本(git);发布时使用 npm dist-tag `dev`。 一行命令(macOS/Linux): @@ -357,17 +357,17 @@ x-i18n: curl -fsSL --proto '=https' --tlsv1.2 https://openclaw.ai/install.sh | bash -s -- --install-method git ``` - Windows 安装器(PowerShell): + Windows 安装程序(PowerShell): [https://openclaw.ai/install.ps1](https://openclaw.ai/install.ps1) - 更多细节: [开发通道](/zh-CN/install/development-channels) 和 [Installer flags](/zh-CN/install/installer)。 + 更多细节:[Development channels](/zh-CN/install/development-channels) 和 [Installer flags](/zh-CN/install/installer)。 - + 有两个选项: - 1. **Dev 通道(git 检出):** + 1. **Dev 渠道(git 检出):** ```bash openclaw update --channel dev @@ -381,7 +381,7 @@ x-i18n: curl -fsSL https://openclaw.ai/install.sh | bash -s -- --install-method git ``` - 这样你会得到一个可本地编辑的仓库,然后通过 git 更新。 + 这样你会得到一个本地仓库,可以编辑,然后通过 git 更新。 如果你更喜欢手动进行干净克隆,请使用: @@ -392,24 +392,24 @@ x-i18n: pnpm build ``` - 文档: [Update](/cli/update), [开发通道](/zh-CN/install/development-channels), + 文档:[Update](/cli/update)、[Development channels](/zh-CN/install/development-channels)、 [Install](/zh-CN/install)。 - - 大致参考: + + 粗略参考: - - **安装:**2-5 分钟 - - **新手引导:**5-15 分钟,取决于你配置了多少渠道/模型 + - **安装:**2 - 5 分钟 + - **新手引导:**5 - 15 分钟,取决于你配置了多少渠道/模型 - 如果卡住了,请参考 [安装器卡住](#快速开始和首次运行设置) - 以及 [我卡住了](#快速开始和首次运行设置) 中的快速调试循环。 + 如果它卡住了,请使用 [Installer stuck](#quick-start-and-first-run-setup) + 以及 [我卡住了](#quick-start-and-first-run-setup) 中的快速调试循环。 - - 使用**详细输出**重新运行安装器: + + 重新运行安装程序,并启用**详细输出**: ```bash curl -fsSL https://openclaw.ai/install.sh | bash -s -- --verbose @@ -427,53 +427,53 @@ x-i18n: curl -fsSL https://openclaw.ai/install.sh | bash -s -- --install-method git --verbose ``` - Windows(PowerShell)等价方式: + Windows(PowerShell)等效方式: ```powershell - # install.ps1 has no dedicated -Verbose flag yet. + # install.ps1 目前还没有专用的 -Verbose 标志。 Set-PSDebug -Trace 1 & ([scriptblock]::Create((iwr -useb https://openclaw.ai/install.ps1))) -NoOnboard Set-PSDebug -Trace 0 ``` - 更多选项: [Installer flags](/zh-CN/install/installer)。 + 更多选项:[Installer flags](/zh-CN/install/installer)。 - + 两个常见的 Windows 问题: - **1)npm error spawn git / git not found** + **1)npm 错误 spawn git / git not found** - - 安装 **Git for Windows**,并确保 `git` 已加入你的 PATH。 - - 关闭并重新打开 PowerShell,然后重新运行安装器。 + - 安装 **Git for Windows**,并确保 `git` 在你的 PATH 中。 + - 关闭并重新打开 PowerShell,然后重新运行安装程序。 **2)安装后 openclaw is not recognized** - - 你的 npm 全局 bin 文件夹没有加入 PATH。 - - 检查该路径: + - 你的 npm 全局 bin 文件夹不在 PATH 中。 + - 检查路径: ```powershell npm config get prefix ``` - - 将该目录添加到你的用户 PATH 中(Windows 上不需要 `\bin` 后缀;在大多数系统中它是 `%AppData%\npm`)。 + - 将该目录添加到你的用户 PATH(Windows 上不需要 `\bin` 后缀;在大多数系统中它是 `%AppData%\npm`)。 - 更新 PATH 后,关闭并重新打开 PowerShell。 - 如果你想获得最顺畅的 Windows 设置体验,请使用 **WSL2** 而不是原生 Windows。 - 文档: [Windows](/zh-CN/platforms/windows)。 + 如果你想要最顺滑的 Windows 设置体验,请使用 **WSL2**,而不是原生 Windows。 + 文档:[Windows](/zh-CN/platforms/windows)。 - - 这通常是原生 Windows shell 的控制台代码页不匹配所致。 + + 这通常是原生 Windows shell 中控制台代码页不匹配导致的。 症状: - `system.run`/`exec` 输出中的中文显示为乱码 - 同一命令在另一个终端配置中显示正常 - 在 PowerShell 中的快速解决方法: + PowerShell 中的快速变通方法: ```powershell chcp 65001 @@ -488,66 +488,67 @@ x-i18n: openclaw gateway restart ``` - 如果你在最新的 OpenClaw 上仍能复现此问题,请在这里跟踪/报告: + 如果你在最新 OpenClaw 上仍能复现该问题,请在这里跟踪/报告: - [Issue #30640](https://github.com/openclaw/openclaw/issues/30640) - - 使用**可修改的(git)安装**,这样你就能在本地拥有完整源码和文档,然后在 - _该文件夹中_ 向你的机器人(或 Claude/Codex)提问,这样它就能读取仓库并准确回答。 + + 使用**可修改的(git)安装**,这样你就可以在本地拥有完整源码和文档,然后 + 从该文件夹中向你的机器人(或 Claude/Codex)提问, + 这样它就能读取仓库并给出精确回答。 ```bash curl -fsSL https://openclaw.ai/install.sh | bash -s -- --install-method git ``` - 更多细节: [Install](/zh-CN/install) 和 [Installer flags](/zh-CN/install/installer)。 + 更多细节:[Install](/zh-CN/install) 和 [Installer flags](/zh-CN/install/installer)。 - - 简短回答:按照 Linux 指南操作,然后运行新手引导。 + + 简短回答:按照 Linux 指南,然后运行新手引导。 - - Linux 快速路径 + 服务安装: [Linux](/zh-CN/platforms/linux)。 - - 完整演练: [入门指南](/zh-CN/start/getting-started)。 - - 安装器 + 更新: [Install & updates](/zh-CN/install/updating)。 + - Linux 快速路径 + 服务安装:[Linux](/zh-CN/platforms/linux)。 + - 完整演练:[入门指南](/zh-CN/start/getting-started)。 + - 安装程序 + 更新:[Install & updates](/zh-CN/install/updating)。 - - 任何 Linux VPS 都可以。安装在服务器上,然后使用 SSH/Tailscale 访问 Gateway 网关。 + + 任何 Linux VPS 都可以。先在服务器上安装,然后通过 SSH/Tailscale 访问 Gateway 网关。 - 指南: [exe.dev](/zh-CN/install/exe-dev), [Hetzner](/zh-CN/install/hetzner), [Fly.io](/zh-CN/install/fly)。 - 远程访问: [Gateway remote](/zh-CN/gateway/remote)。 + 指南:[exe.dev](/zh-CN/install/exe-dev)、[Hetzner](/zh-CN/install/hetzner)、[Fly.io](/zh-CN/install/fly)。 + 远程访问:[Gateway remote](/zh-CN/gateway/remote)。 - - 我们维护了一个**托管中心**,收录常见提供商。选择一个并按照指南操作: + + 我们提供一个**托管中心**,汇总常见提供商。选择一个并按照指南操作: - - [VPS hosting](/zh-CN/vps)(所有提供商集中在一个地方) + - [VPS hosting](/zh-CN/vps)(所有提供商集中在一处) - [Fly.io](/zh-CN/install/fly) - [Hetzner](/zh-CN/install/hetzner) - [exe.dev](/zh-CN/install/exe-dev) - 云端的工作方式:**Gateway 网关运行在服务器上**,而你通过 Control UI - (或 Tailscale/SSH)从笔记本/手机访问它。你的状态 + 工作区 - 都保存在服务器上,因此应将该主机视为事实来源并做好备份。 + 在云中它的工作方式是:**Gateway 网关运行在服务器上**,而你通过 + Control UI(或 Tailscale/SSH)从笔记本/手机访问它。你的状态 + 工作区 + 都保存在服务器上,因此请将主机视为唯一事实来源并做好备份。 - 你可以将 **nodes**(Mac/iOS/Android/headless)配对到这个云端 Gateway 网关, - 以访问本地屏幕/相机/canvas,或在保持 - Gateway 网关位于云端的同时,在你的笔记本上运行命令。 + 你可以将**节点**(Mac/iOS/Android/无头)配对到这个云端 Gateway 网关, + 以访问本地屏幕/摄像头/画布,或在笔记本上运行命令,同时让 + Gateway 网关保留在云中。 - 中心: [Platforms](/zh-CN/platforms)。远程访问: [Gateway remote](/zh-CN/gateway/remote)。 - Nodes: [Nodes](/zh-CN/nodes), [Nodes CLI](/cli/nodes)。 + 中心页:[Platforms](/zh-CN/platforms)。远程访问:[Gateway remote](/zh-CN/gateway/remote)。 + 节点:[Nodes](/zh-CN/nodes)、[Nodes CLI](/cli/nodes)。 - + 简短回答:**可以,但不推荐**。更新流程可能会重启 - Gateway 网关(这会中断当前会话),可能需要一个干净的 git 检出,并且 - 可能会要求确认。更安全的做法是由操作人员在 shell 中运行更新。 + Gateway 网关(这会中断当前会话),可能需要一个干净的 git 检出, + 还可能提示你确认。更安全的做法是由操作员在 shell 中执行更新。 使用 CLI: @@ -559,25 +560,25 @@ x-i18n: openclaw update --no-restart ``` - 如果你必须从智能体自动化执行: + 如果你必须从智能体中自动化: ```bash openclaw update --yes --no-restart openclaw gateway restart ``` - 文档: [Update](/cli/update), [Updating](/zh-CN/install/updating)。 + 文档:[Update](/cli/update)、[Updating](/zh-CN/install/updating)。 `openclaw onboard` 是推荐的设置路径。在**本地模式**下,它会引导你完成: - - **模型/认证设置**(提供商 OAuth、API 密钥、Anthropic 旧版 setup-token,以及 LM Studio 等本地模型选项) + - **模型/认证设置**(提供商 OAuth、API 密钥、Anthropic 旧版 setup-token,以及 LM Studio 之类的本地模型选项) - **工作区**位置 + 引导文件 - **Gateway 网关设置**(bind/port/auth/tailscale) - - **渠道**(WhatsApp、Telegram、Discord、Mattermost、Signal、iMessage,以及 QQ Bot 等内置渠道插件) - - **守护进程安装**(macOS 上为 LaunchAgent;Linux/WSL2 上为 systemd user unit) + - **渠道**(WhatsApp、Telegram、Discord、Mattermost、Signal、iMessage,以及像 QQ Bot 这样的内置渠道插件) + - **守护进程安装**(macOS 上为 LaunchAgent;Linux/WSL2 上为 systemd 用户单元) - **健康检查**和 **Skills** 选择 如果你配置的模型未知或缺少认证,它也会发出警告。 @@ -585,61 +586,60 @@ x-i18n: - 不需要。你可以通过 **API 密钥**(Anthropic/OpenAI/其他)运行 OpenClaw, - 或者使用**仅本地模型**,这样你的数据就保留在设备上。订阅(Claude - Pro/Max 或 OpenAI Codex)只是这些提供商的可选认证方式。 + 不需要。你可以通过 **API 密钥**(Anthropic/OpenAI/其他)来运行 OpenClaw, + 也可以使用**纯本地模型**,这样你的数据就会保留在设备上。订阅(Claude + Pro/Max 或 OpenAI Codex)只是认证这些提供商的可选方式。 - 对于 OpenClaw 中的 Anthropic,实际上的区别是: + 对于 OpenClaw 中的 Anthropic,实际区别是: - - **Anthropic API key**:标准 Anthropic API 计费 - - **OpenClaw 中的 Claude 订阅认证**:Anthropic 已在 - **2026 年 4 月 4 日 太平洋时间中午 12:00 / 英国夏令时晚上 8:00** - 告知 OpenClaw 用户,这需要 - **Extra Usage**,并且与订阅分开计费 + - **Anthropic API 密钥**:正常的 Anthropic API 计费 + - **OpenClaw 中的 Claude 订阅认证**:Anthropic 于 + **2026 年 4 月 4 日太平洋时间下午 12:00 / 英国夏令时晚上 8:00** 告知 OpenClaw 用户, + 这需要**Extra Usage**,并且会在订阅之外单独计费 - 我们在本地复现中还发现,`claude -p --append-system-prompt ...` 在附加的提示词表明 - 其来源是 OpenClaw 时,也会触发同样的 Extra Usage 限制; - 而在 Anthropic SDK + API key 路径中, - 使用相同的提示词字符串则**不会**复现该限制。OpenAI Codex OAuth 已明确 - 支持用于 OpenClaw 这类外部工具。 + 我们的本地复现还表明,`claude -p --append-system-prompt ...` 在附加提示中标识 + OpenClaw 时,也可能触发同样的 Extra Usage 限制; + 而在 Anthropic SDK + API 密钥路径中,使用相同的提示字符串 + 则**不会**复现这一阻断。OpenAI Codex OAuth 明确 + 支持在 OpenClaw 这样的外部工具中使用。 - OpenClaw 还支持其他托管型订阅方案,包括 + OpenClaw 还支持其他托管型订阅选项,包括 **Qwen Cloud Coding Plan**、**MiniMax Coding Plan** 和 **Z.AI / GLM Coding Plan**。 - 文档: [Anthropic](/zh-CN/providers/anthropic), [OpenAI](/zh-CN/providers/openai), - [Qwen Cloud](/zh-CN/providers/qwen), - [MiniMax](/zh-CN/providers/minimax), [GLM Models](/zh-CN/providers/glm), - [本地模型](/zh-CN/gateway/local-models), [Models](/zh-CN/concepts/models)。 + 文档:[Anthropic](/zh-CN/providers/anthropic)、[OpenAI](/zh-CN/providers/openai)、 + [Qwen Cloud](/zh-CN/providers/qwen)、 + [MiniMax](/zh-CN/providers/minimax)、[GLM Models](/zh-CN/providers/glm)、 + [Local models](/zh-CN/gateway/local-models)、[Models](/zh-CN/concepts/models)。 - - 可以,但应将其视为**带 Extra Usage 的 Claude 订阅认证**。 + + 可以,但请将其视为**带 Extra Usage 的 Claude 订阅认证**。 - Claude Pro/Max 订阅并不包含 API key。在 OpenClaw 中,这意味着 - Anthropic 针对 OpenClaw 的计费通知依然适用:订阅流量需要 - **Extra Usage**。如果你希望 Anthropic 流量不经过 - 该 Extra Usage 路径,请改用 Anthropic API key。 + Claude Pro/Max 订阅并不包含 API 密钥。在 OpenClaw 中,这 + 意味着 Anthropic 针对 OpenClaw 的计费通知仍然适用:订阅 + 流量需要 **Extra Usage**。如果你希望使用 Anthropic 且不经过 + 这条 Extra Usage 路径,请改用 Anthropic API 密钥。 - 支持,但当前支持的解释是: + 支持,但当前支持的理解方式是: - - OpenClaw 中的 Anthropic + 订阅意味着 **Extra Usage** - - OpenClaw 中的 Anthropic 若不走该路径,则意味着 **API key** + - 在 OpenClaw 中使用订阅认证 Anthropic,意味着 **Extra Usage** + - 在 OpenClaw 中不走这条路径使用 Anthropic,则意味着 **API 密钥** - Anthropic setup-token 仍然可作为旧版/手动的 OpenClaw 路径, - 并且 Anthropic 针对 OpenClaw 的计费通知仍然适用于该路径。我们 + Anthropic setup-token 仍然可作为 OpenClaw 中的旧版/手动路径使用, + Anthropic 针对 OpenClaw 的计费通知在该路径中仍然适用。我们 还在本地使用直接的 - `claude -p --append-system-prompt ...` 时复现了同样的计费限制,只要附加提示词 - 表明来源是 OpenClaw;而同样的提示词字符串在 - Anthropic SDK + API-key 路径下则**不会**复现。 + `claude -p --append-system-prompt ...` 时复现了相同的计费限制, + 条件是附加提示中明确标识了 OpenClaw,而相同的提示字符串在 + Anthropic SDK + API 密钥路径中则**不会**复现。 - 对于生产环境或多用户工作负载,Anthropic API key 认证是 - 更安全、推荐的选择。如果你想在 OpenClaw 中使用其他订阅式托管 - 方案,请参阅 [OpenAI](/zh-CN/providers/openai)、[Qwen / Model + 对于生产环境或多用户工作负载,Anthropic API 密钥认证是 + 更安全、更推荐的选择。如果你想在 OpenClaw 中使用其他订阅式托管 + 选项,请参阅 [OpenAI](/zh-CN/providers/openai)、[Qwen / Model Cloud](/zh-CN/providers/qwen)、[MiniMax](/zh-CN/providers/minimax) 和 [GLM Models](/zh-CN/providers/glm)。 @@ -647,137 +647,146 @@ x-i18n: -这意味着你当前时间窗口内的 **Anthropic 配额/速率限制**已耗尽。如果你 -使用 **Claude CLI**,请等待窗口重置或升级你的套餐。如果你 -使用 **Anthropic API key**,请检查 Anthropic Console -中的使用量/计费情况,并按需提高限额。 +这意味着你在当前时间窗口中的 **Anthropic 配额/速率限制** 已耗尽。如果你 +使用 **Claude CLI**,请等待该窗口重置,或升级你的套餐。如果你 +使用 **Anthropic API 密钥**,请检查 Anthropic Console +中的用量/计费情况,并按需提高限制。 - 如果消息具体是: + 如果消息明确写着: `Extra usage is required for long context requests`,说明该请求正在尝试使用 - Anthropic 的 1M 上下文 beta(`context1m: true`)。这仅在你的 - 凭据具备长上下文计费资格时才可用(API key 计费或 + Anthropic 的 1M 上下文 beta(`context1m: true`)。这只有在你的 + 凭据具备长上下文计费资格时才有效(API 密钥计费或 启用了 Extra Usage 的 OpenClaw Claude 登录路径)。 - 提示:设置一个**回退模型**,这样当某个提供商被速率限制时,OpenClaw 仍能继续回复。 - 参阅 [Models](/cli/models), [OAuth](/zh-CN/concepts/oauth), 和 + 提示:设置一个**后备模型**,这样在某个提供商被限流时,OpenClaw 仍能继续回复。 + 参阅 [Models](/cli/models)、[OAuth](/zh-CN/concepts/oauth) 和 [/gateway/troubleshooting#anthropic-429-extra-usage-required-for-long-context](/zh-CN/gateway/troubleshooting#anthropic-429-extra-usage-required-for-long-context)。 - 支持。OpenClaw 内置了 **Amazon Bedrock(Converse)**提供商。只要存在 AWS 环境标记,OpenClaw 就可以自动发现支持流式传输/文本的 Bedrock 目录,并将其作为隐式 `amazon-bedrock` 提供商合并;否则你也可以显式启用 `plugins.entries.amazon-bedrock.config.discovery.enabled` 或添加手动提供商条目。参阅 [Amazon Bedrock](/zh-CN/providers/bedrock) 和 [模型提供商](/zh-CN/providers/models)。如果你更喜欢托管式密钥流程,在 Bedrock 前加一个兼容 OpenAI 的代理仍然是可行方案。 + 支持。OpenClaw 内置了 **Amazon Bedrock(Converse)** 提供商。当存在 AWS 环境标记时,OpenClaw 可以自动发现 Bedrock 的流式/文本模型目录,并将其作为隐式 `amazon-bedrock` 提供商合并;否则你也可以显式启用 `plugins.entries.amazon-bedrock.config.discovery.enabled` 或手动添加一个提供商条目。参阅 [Amazon Bedrock](/zh-CN/providers/bedrock) 和 [Model providers](/zh-CN/providers/models)。如果你更偏好托管密钥流程,在 Bedrock 前面加一个兼容 OpenAI 的代理仍然是有效选项。 - OpenClaw 通过 OAuth(ChatGPT 登录)支持 **OpenAI Code(Codex)**。新手引导可以运行 OAuth 流程,并会在适当时将默认模型设置为 `openai-codex/gpt-5.4`。参阅 [模型提供商](/zh-CN/concepts/model-providers) 和 [新手引导(CLI)](/zh-CN/start/wizard)。 + OpenClaw 通过 OAuth(ChatGPT 登录)支持 **OpenAI Code(Codex)**。新手引导可以运行 OAuth 流程,并会在合适时将默认模型设置为 `openai-codex/gpt-5.4`。参阅 [Model providers](/zh-CN/concepts/model-providers) 和 [Onboarding(CLI)](/zh-CN/start/wizard)。 - + 支持。OpenClaw 完全支持 **OpenAI Code(Codex)订阅 OAuth**。 - OpenAI 已明确允许在 OpenClaw 这样的外部工具/工作流中 - 使用订阅 OAuth。新手引导可以为你运行 OAuth 流程。 + OpenAI 明确允许在 OpenClaw 这样的外部工具/工作流中 + 使用订阅 OAuth。新手引导可以为你运行该 OAuth 流程。 - 参阅 [OAuth](/zh-CN/concepts/oauth), [模型提供商](/zh-CN/concepts/model-providers), 和 [新手引导(CLI)](/zh-CN/start/wizard)。 + 参阅 [OAuth](/zh-CN/concepts/oauth)、[Model providers](/zh-CN/concepts/model-providers) 和 [Onboarding(CLI)](/zh-CN/start/wizard)。 - - Gemini CLI 使用的是**插件认证流程**,而不是在 `openclaw.json` 中设置 client id 或 secret。 + + Gemini CLI 使用的是**插件认证流程**,而不是在 `openclaw.json` 中填写 client id 或 secret。 - 请改用 Gemini API 提供商: + 步骤: - 1. 启用插件:`openclaw plugins enable google` - 2. 运行 `openclaw onboard --auth-choice gemini-api-key` - 3. 设置一个 Google 模型,例如 `google/gemini-3.1-pro-preview` + 1. 在本地安装 Gemini CLI,使 `gemini` 位于 `PATH` 中 + - Homebrew:`brew install gemini-cli` + - npm:`npm install -g @google/gemini-cli` + 2. 启用插件:`openclaw plugins enable google` + 3. 登录:`openclaw models auth login --provider google-gemini-cli --set-default` + 4. 登录后的默认模型:`google-gemini-cli/gemini-3.1-pro-preview` + 5. 如果请求失败,请在 gateway 主机上设置 `GOOGLE_CLOUD_PROJECT` 或 `GOOGLE_CLOUD_PROJECT_ID` + + 这会将 OAuth 令牌存储在 gateway 主机上的认证档案中。详情: [Model providers](/zh-CN/concepts/model-providers)。 - 通常不适合。OpenClaw 需要大上下文 + 强安全性;小模型会截断并泄漏。如果你非要用,请在本地(LM Studio)运行你能承载的**最大**模型构建,并参阅 [/gateway/local-models](/zh-CN/gateway/local-models)。更小/量化程度更高的模型会增加提示注入风险——参阅 [Security](/zh-CN/gateway/security)。 + 通常不适合。OpenClaw 需要较大的上下文 + 强安全性;小模型容易截断并泄漏信息。如果你一定要这样做,请在本地运行你能承载的**最大**模型构建(LM Studio),并参阅 [/gateway/local-models](/zh-CN/gateway/local-models)。更小/量化更重的模型会增加提示注入风险——参阅 [Security](/zh-CN/gateway/security)。 - - 选择区域固定的端点。OpenRouter 为 MiniMax、Kimi 和 GLM 提供美国托管选项;选择美国托管变体即可让数据留在该区域。你仍然可以通过 `models.mode: "merge"` 同时列出 Anthropic/OpenAI,从而在尊重你所选区域化提供商的同时保留回退能力。 + + 请选择固定区域的端点。OpenRouter 为 MiniMax、Kimi 和 GLM 提供了美国托管选项;选择美国托管变体即可将数据保留在该区域。你仍然可以通过使用 `models.mode: "merge"` 将 Anthropic/OpenAI 一起列出,这样在遵守所选区域提供商的前提下,也能保留后备选项。 - - 不需要。OpenClaw 可运行在 macOS 或 Linux 上(Windows 通过 WSL2)。Mac mini 是可选的——有些人 - 会买一台作为常开主机,但小型 VPS、家用服务器,或 Raspberry Pi 级别的盒子也可以。 + + 不需要。OpenClaw 可运行在 macOS 或 Linux 上(Windows 通过 WSL2)。Mac mini 是可选项——有些人 + 会买一台作为常开主机,但小型 VPS、家用服务器或 Raspberry Pi 级别的机器也能胜任。 - 你只有在需要 **仅限 macOS 的工具**时才必须要 Mac。对于 iMessage,请使用 [BlueBubbles](/zh-CN/channels/bluebubbles)(推荐)——BlueBubbles 服务器运行在任意 Mac 上,而 Gateway 网关可以运行在 Linux 或其他地方。如果你想使用其他仅限 macOS 的工具,请在 Mac 上运行 Gateway 网关或配对一个 macOS 节点。 + 你只在需要**仅限 macOS 的工具**时才需要 Mac。对于 iMessage,请使用 [BlueBubbles](/zh-CN/channels/bluebubbles)(推荐)——BlueBubbles 服务器可以运行在任何 Mac 上,而 Gateway 网关可以运行在 Linux 或其他地方。如果你需要其他仅限 macOS 的工具,请在 Mac 上运行 Gateway 网关,或配对一个 macOS 节点。 - 文档: [BlueBubbles](/zh-CN/channels/bluebubbles), [Nodes](/zh-CN/nodes), [Mac remote mode](/zh-CN/platforms/mac/remote)。 + 文档:[BlueBubbles](/zh-CN/channels/bluebubbles)、[Nodes](/zh-CN/nodes)、[Mac remote mode](/zh-CN/platforms/mac/remote)。 - - 你需要**某台已登录 Messages 的 macOS 设备**。它**不一定**是 Mac mini—— - 任何 Mac 都可以。对于 iMessage,**请使用 [BlueBubbles](/zh-CN/channels/bluebubbles)**(推荐)——BlueBubbles 服务器运行在 macOS 上,而 Gateway 网关可以运行在 Linux 或其他地方。 + + 你需要**某个已登录 Messages 的 macOS 设备**。它**不一定**要是 Mac mini—— + 任何 Mac 都可以。对于 iMessage,请**使用 [BlueBubbles](/zh-CN/channels/bluebubbles)**(推荐)——BlueBubbles 服务器运行在 macOS 上,而 Gateway 网关可以运行在 Linux 或其他地方。 常见设置: - - 在 Linux/VPS 上运行 Gateway 网关,并在任何已登录 Messages 的 Mac 上运行 BlueBubbles 服务器。 - - 如果你想要最简单的单机设置,也可以把所有内容都运行在 Mac 上。 + - 在 Linux/VPS 上运行 Gateway 网关,并在任意登录了 Messages 的 Mac 上运行 BlueBubbles 服务器。 + - 如果你想要最简单的单机设置,就把所有内容都运行在 Mac 上。 - 文档: [BlueBubbles](/zh-CN/channels/bluebubbles), [Nodes](/zh-CN/nodes), + 文档:[BlueBubbles](/zh-CN/channels/bluebubbles)、[Nodes](/zh-CN/nodes)、 [Mac remote mode](/zh-CN/platforms/mac/remote)。 - + 可以。**Mac mini 可以运行 Gateway 网关**,而你的 MacBook Pro 可以作为 - **node**(配套设备)连接。节点本身不运行 Gateway 网关——它们提供额外的 - 能力,例如该设备上的 screen/camera/canvas 和 `system.run`。 + **节点**(配套设备)连接。节点不运行 Gateway 网关——它们提供额外 + 的能力,比如该设备上的屏幕/摄像头/画布以及 `system.run`。 常见模式: - Gateway 网关运行在 Mac mini 上(始终在线)。 - - MacBook Pro 运行 macOS 应用或 node host,并与 Gateway 网关配对。 - - 使用 `openclaw nodes status` / `openclaw nodes list` 查看它。 + - MacBook Pro 运行 macOS 应用或节点主机,并与 Gateway 网关配对。 + - 使用 `openclaw nodes status` / `openclaw nodes list` 查看状态。 - 文档: [Nodes](/zh-CN/nodes), [Nodes CLI](/cli/nodes)。 + 文档:[Nodes](/zh-CN/nodes)、[Nodes CLI](/cli/nodes)。 - **不推荐**使用 Bun。我们看到了一些运行时 bug,尤其是与 WhatsApp 和 Telegram 相关的。 + **不推荐**使用 Bun。我们观察到运行时 bug,尤其是在 WhatsApp 和 Telegram 上。 稳定的 Gateway 网关请使用 **Node**。 - 如果你仍然想尝试 Bun,请只在非生产 Gateway 网关上使用, - 且不要启用 WhatsApp/Telegram。 + 如果你仍然想尝试 Bun,请仅在非生产 Gateway 网关上 + 且不要搭配 WhatsApp/Telegram 使用。 - - `channels.telegram.allowFrom` 是**人类发送者的 Telegram user ID**(数字),不是机器人用户名。 + + `channels.telegram.allowFrom` 填的是**人工发送者的 Telegram 用户 ID**(数字)。 + 它不是机器人用户名。 - 新手引导接受 `@username` 输入并将其解析为数字 ID,但 OpenClaw 授权只使用数字 ID。 + 新手引导接受 `@username` 输入,并会将其解析为数字 ID,但 OpenClaw 授权只使用数字 ID。 更安全的方式(无需第三方机器人): - - 给你的机器人发送私信,然后运行 `openclaw logs --follow` 并读取 `from.id`。 + - 给你的机器人发私信,然后运行 `openclaw logs --follow` 并读取 `from.id`。 官方 Bot API: - - 给你的机器人发送私信,然后调用 `https://api.telegram.org/bot/getUpdates` 并读取 `message.from.id`。 + - 给你的机器人发私信,然后调用 `https://api.telegram.org/bot/getUpdates` 并读取 `message.from.id`。 - 第三方方式(隐私性较差): + 第三方方式(隐私性较低): - - 私信 `@userinfobot` 或 `@getidsbot`。 + - 给 `@userinfobot` 或 `@getidsbot` 发私信。 参阅 [/channels/telegram](/zh-CN/channels/telegram#access-control-and-activation)。 - - 可以,通过**多智能体路由**实现。将每个发送者的 WhatsApp **私信**(peer `kind: "direct"`,发送者 E.164 例如 `+15551234567`)绑定到不同的 `agentId`,这样每个人都会拥有自己的工作区和会话存储。回复仍然来自**同一个 WhatsApp 账号**,而私信访问控制(`channels.whatsapp.dmPolicy` / `channels.whatsapp.allowFrom`)在同一个 WhatsApp 账号范围内是全局的。参阅 [多智能体路由](/zh-CN/concepts/multi-agent) 和 [WhatsApp](/zh-CN/channels/whatsapp)。 + + 可以,通过**多智能体路由**实现。将每个发送者的 WhatsApp **私信** + (peer `kind: "direct"`,发送者 E.164 例如 `+15551234567`)绑定到不同的 `agentId`, + 这样每个人都会拥有自己的工作区和会话存储。回复仍然来自**同一个 WhatsApp 账号**,而私信访问控制(`channels.whatsapp.dmPolicy` / `channels.whatsapp.allowFrom`)在整个 WhatsApp 账号层面是全局的。参阅 [Multi-Agent Routing](/zh-CN/concepts/multi-agent) 和 [WhatsApp](/zh-CN/channels/whatsapp)。 - - 可以。使用多智能体路由:为每个智能体设置各自的默认模型,然后将入站路由(提供商账号或特定 peers)绑定到对应智能体。示例配置见 [多智能体路由](/zh-CN/concepts/multi-agent)。另请参阅 [Models](/zh-CN/concepts/models) 和 [Configuration](/zh-CN/gateway/configuration)。 + + 可以。使用多智能体路由:为每个智能体设置其各自的默认模型,然后将入站路由(提供商账号或特定 peer)绑定到各个智能体。示例配置见 [Multi-Agent Routing](/zh-CN/concepts/multi-agent)。另请参阅 [Models](/zh-CN/concepts/models) 和 [Configuration](/zh-CN/gateway/configuration)。 - + 可以。Homebrew 支持 Linux(Linuxbrew)。快速设置: ```bash @@ -787,25 +796,25 @@ x-i18n: brew install ``` - 如果你通过 systemd 运行 OpenClaw,请确保服务的 PATH 包含 `/home/linuxbrew/.linuxbrew/bin`(或你的 brew prefix),以便 `brew` 安装的工具在非登录 shell 中可解析。 - 最近的构建还会在 Linux systemd 服务中预先加入常见用户 bin 目录(例如 `~/.local/bin`、`~/.npm-global/bin`、`~/.local/share/pnpm`、`~/.bun/bin`),并在设置时遵循 `PNPM_HOME`、`NPM_CONFIG_PREFIX`、`BUN_INSTALL`、`VOLTA_HOME`、`ASDF_DATA_DIR`、`NVM_DIR` 和 `FNM_DIR`。 + 如果你通过 systemd 运行 OpenClaw,请确保服务的 PATH 包含 `/home/linuxbrew/.linuxbrew/bin`(或你的 brew 前缀),这样 `brew` 安装的工具才能在非登录 shell 中被解析。 + 最近的构建也会在 Linux systemd 服务中预置常见用户 bin 目录(例如 `~/.local/bin`、`~/.npm-global/bin`、`~/.local/share/pnpm`、`~/.bun/bin`),并在设置时遵循 `PNPM_HOME`、`NPM_CONFIG_PREFIX`、`BUN_INSTALL`、`VOLTA_HOME`、`ASDF_DATA_DIR`、`NVM_DIR` 和 `FNM_DIR`。 - - **可修改的(git)安装:**完整源码检出,可编辑,最适合贡献者。 - 你在本地运行构建,也可以修改代码/文档。 - - **npm install:**全局 CLI 安装,没有仓库,最适合“只想运行”。 - 更新来自 npm dist-tags。 + - **可修改的(git)安装:**完整源码检出、可编辑,最适合贡献者。 + 你需要在本地构建,并可修改代码/文档。 + - **npm install:**全局 CLI 安装,没有仓库,最适合“直接运行”。 + 更新来自 npm dist-tag。 - 文档: [入门指南](/zh-CN/start/getting-started), [Updating](/zh-CN/install/updating)。 + 文档:[入门指南](/zh-CN/start/getting-started)、[Updating](/zh-CN/install/updating)。 - 可以。安装另一种形式后,运行 Doctor,让 gateway 服务指向新的入口点。 - 这**不会删除你的数据**——它只会更改 OpenClaw 的代码安装方式。你的状态 - (`~/.openclaw`)和工作区(`~/.openclaw/workspace`)都会保持不变。 + 可以。安装另一种形式后,运行 Doctor,使 gateway 服务指向新的入口点。 + 这**不会删除你的数据**——它只会更改 OpenClaw 代码安装。你的状态 + (`~/.openclaw`)和工作区(`~/.openclaw/workspace`)都不会被触碰。 从 npm 切换到 git: @@ -826,153 +835,153 @@ x-i18n: openclaw gateway restart ``` - Doctor 会检测 gateway 服务入口点不匹配,并提供重写服务配置以匹配当前安装方式的选项(在自动化场景下使用 `--repair`)。 + Doctor 会检测 gateway 服务入口点不匹配,并提供重写服务配置以匹配当前安装的选项(在自动化中使用 `--repair`)。 - 备份建议:参阅 [备份策略](#磁盘上的文件位置)。 + 备份建议:参阅 [备份策略](#where-things-live-on-disk)。 - - 简短回答:**如果你想要 24/7 可靠性,请使用 VPS**。如果你更在乎 - 最低摩擦,并且可以接受休眠/重启,那就在本地运行。 + + 简短回答:**如果你想要 24/7 的可靠性,就用 VPS**。如果你想要 + 最低使用门槛,并且能接受睡眠/重启,那么就在本地运行。 - **笔记本(本地 Gateway 网关)** + **笔记本电脑(本地 Gateway 网关)** - - **优点:**无服务器成本,直接访问本地文件,可见的浏览器窗口。 - - **缺点:**休眠/网络中断 = 断开连接,操作系统更新/重启会打断运行,必须保持唤醒。 + - **优点:**没有服务器成本,可直接访问本地文件,有可见的浏览器窗口。 + - **缺点:**睡眠/网络中断 = 断连,操作系统更新/重启会打断运行,必须保持唤醒。 - **VPS / 云** + **VPS / 云端** - - **优点:**始终在线,网络稳定,没有笔记本休眠问题,更容易长期保持运行。 - - **缺点:**通常是无头运行(使用截图),只能远程访问文件,更新需要 SSH。 + - **优点:**始终在线,网络稳定,没有笔记本睡眠问题,更容易长期运行。 + - **缺点:**通常是无头运行(使用截图),只能远程访问文件,更新时必须通过 SSH。 - **OpenClaw 特定说明:**WhatsApp/Telegram/Slack/Mattermost/Discord 在 VPS 上都能正常工作。唯一真正的权衡是**无头浏览器**还是可见窗口。参阅 [Browser](/zh-CN/tools/browser)。 + **OpenClaw 特定说明:**WhatsApp/Telegram/Slack/Mattermost/Discord 都可以在 VPS 上良好运行。真正的取舍只有**无头浏览器**与**可见窗口**。参阅 [Browser](/zh-CN/tools/browser)。 - **推荐默认方案:**如果你以前遇到过 gateway 断开连接,就选 VPS。本地运行非常适合你正在 активно 使用 Mac、并且想访问本地文件或使用带可见浏览器的 UI 自动化时。 + **推荐默认方案:**如果你之前遇到过 gateway 断连,优先用 VPS。本地运行非常适合你正在积极使用 Mac、并希望访问本地文件或通过可见浏览器进行 UI 自动化的场景。 - 不是必需的,但**为了可靠性和隔离性,推荐这样做**。 + 不是必须,但为了可靠性和隔离性,**推荐这样做**。 - - **专用主机(VPS/Mac mini/Pi):**始终在线,更少受休眠/重启打断,权限更清晰,更容易稳定运行。 - - **共享笔记本/台式机:**非常适合测试和主动使用,但要预期机器休眠或更新时会暂停。 + - **专用主机(VPS/Mac mini/Pi):**始终在线,更少睡眠/重启中断,权限更清晰,更容易持续运行。 + - **共享笔记本/台式机:**非常适合测试和活跃使用,但要预期机器睡眠或更新时会暂停。 - 如果你想兼得两者,把 Gateway 网关放在专用主机上,再把你的笔记本配对成 **node**,用于本地 screen/camera/exec 工具。参阅 [Nodes](/zh-CN/nodes)。 - 有关安全建议,请阅读 [Security](/zh-CN/gateway/security)。 + 如果你想兼顾两者,请把 Gateway 网关放在专用主机上,并把你的笔记本配对为一个**节点**,用于本地屏幕/摄像头/exec 工具。参阅 [Nodes](/zh-CN/nodes)。 + 关于安全指南,请阅读 [Security](/zh-CN/gateway/security)。 - + OpenClaw 很轻量。对于一个基础 Gateway 网关 + 一个聊天渠道: - - **绝对最低:**1 vCPU、1GB RAM、约 500MB 磁盘。 - - **推荐:**1-2 vCPU、2GB RAM 或更多,以留出余量(日志、媒体、多个渠道)。Node 工具和浏览器自动化可能比较吃资源。 + - **绝对最低配置:**1 vCPU、1 GB RAM、约 500 MB 磁盘。 + - **推荐配置:**1 - 2 vCPU、2 GB RAM 或更高,以留出余量(日志、媒体、多个渠道)。Node 工具和浏览器自动化可能更耗资源。 - 操作系统:使用 **Ubuntu LTS**(或任意现代 Debian/Ubuntu)。Linux 安装路径在这些系统上测试最充分。 + 操作系统:使用 **Ubuntu LTS**(或任何现代 Debian/Ubuntu)。Linux 安装路径在这些系统上测试最充分。 - 文档: [Linux](/zh-CN/platforms/linux), [VPS hosting](/zh-CN/vps)。 + 文档:[Linux](/zh-CN/platforms/linux)、[VPS hosting](/zh-CN/vps)。 - - 可以。将 VM 视为 VPS:它需要始终在线、可访问,并为 - Gateway 网关和你启用的任何渠道提供足够的 RAM。 + + 可以。请将虚拟机视为 VPS:它需要始终在线、可被访问,并且拥有足够的 + RAM 来运行 Gateway 网关和你启用的任何渠道。 - 基本参考: + 基线建议: - - **绝对最低:**1 vCPU、1GB RAM。 - - **推荐:**如果你运行多个渠道、浏览器自动化或媒体工具,建议 2GB RAM 或更多。 + - **绝对最低配置:**1 vCPU、1 GB RAM。 + - **推荐配置:**如果你运行多个渠道、浏览器自动化或媒体工具,则建议 2 GB RAM 或更多。 - **操作系统:**Ubuntu LTS 或其他现代 Debian/Ubuntu。 - 如果你使用 Windows,**WSL2 是最简单的 VM 风格设置**,工具兼容性也最好。 - 参阅 [Windows](/zh-CN/platforms/windows), [VPS hosting](/zh-CN/vps)。 - 如果你在 VM 中运行 macOS,请参阅 [macOS VM](/zh-CN/install/macos-vm)。 + 如果你使用 Windows,**WSL2 是最容易的虚拟机式设置**,并且工具兼容性最好。 + 参阅 [Windows](/zh-CN/platforms/windows)、[VPS hosting](/zh-CN/vps)。 + 如果你在虚拟机中运行 macOS,请参阅 [macOS VM](/zh-CN/install/macos-vm)。 -## OpenClaw 是什么? +## 什么是 OpenClaw? - - OpenClaw 是一个运行在你自己设备上的个人 AI 助手。它会在你已经使用的消息界面上回复你(WhatsApp、Telegram、Slack、Mattermost、Discord、Google Chat、Signal、iMessage、WebChat,以及 QQ Bot 等内置渠道插件),并且还可以在受支持的平台上提供语音 + 实时 Canvas。**Gateway 网关**是始终在线的控制平面;这个助手本身才是产品。 + + OpenClaw 是一个运行在你自己设备上的个人 AI 助手。它会在你已经使用的消息界面上回复你(WhatsApp、Telegram、Slack、Mattermost、Discord、Google Chat、Signal、iMessage、WebChat,以及像 QQ Bot 这样的内置渠道插件),并且在支持的平台上还可以提供语音 + 实时画布。**Gateway 网关**是始终在线的控制平面;助手本身才是产品。 - OpenClaw 不只是“Claude 的封装器”。它是一个**本地优先的控制平面**,让你能在**自己的硬件**上运行一个 - 有能力的助手,可通过你已在使用的聊天应用访问,并具备 - 有状态会话、记忆和工具——而无需把你的工作流控制权交给托管 + OpenClaw 不是“只是一个 Claude 包装器”。它是一个**本地优先的控制平面**,让你可以在**自己的硬件上** + 运行一个强大的助手,并通过你已经使用的聊天应用访问它,同时具备 + 有状态会话、记忆和工具——而不必把工作流控制权交给托管型 SaaS。 亮点: - - **你的设备,你的数据:**你可以把 Gateway 网关运行在任何地方(Mac、Linux、VPS),并让 + - **你的设备,你的数据:**在任何你想要的地方运行 Gateway 网关(Mac、Linux、VPS),并将 工作区 + 会话历史保留在本地。 - **真实渠道,而不是 Web 沙箱:**WhatsApp/Telegram/Slack/Discord/Signal/iMessage 等, - 以及受支持平台上的移动语音和 Canvas。 - - **模型无关:**使用 Anthropic、OpenAI、MiniMax、OpenRouter 等,并支持按智能体路由 - 和故障转移。 - - **仅本地选项:**运行本地模型,这样如果你愿意,**所有数据都可以保留在你的设备上**。 + 以及在受支持平台上的移动语音和 Canvas。 + - **与模型无关:**使用 Anthropic、OpenAI、MiniMax、OpenRouter 等,并支持按智能体路由 + 及故障切换。 + - **纯本地选项:**运行本地模型,这样**所有数据都可以保留在你的设备上**。 - **多智能体路由:**按渠道、账号或任务拆分不同智能体,每个都有自己的 - 工作区和默认值。 - - **开源且可修改:**可检查、扩展、自托管,无厂商锁定。 + 工作区和默认设置。 + - **开源且可改造:**可检查、扩展并自行托管,无供应商锁定。 - 文档: [Gateway 网关](/zh-CN/gateway), [Channels](/zh-CN/channels), [多智能体](/zh-CN/concepts/multi-agent), + 文档:[Gateway](/zh-CN/gateway)、[Channels](/zh-CN/channels)、[Multi-agent](/zh-CN/concepts/multi-agent)、 [Memory](/zh-CN/concepts/memory)。 - - 很适合作为起点的项目: + + 很适合作为第一个项目的内容: - - 搭建一个网站(WordPress、Shopify,或一个简单静态站点)。 - - 为移动应用制作原型(大纲、界面、API 计划)。 + - 搭建网站(WordPress、Shopify,或简单静态站点)。 + - 制作移动应用原型(大纲、界面、API 计划)。 - 整理文件和文件夹(清理、命名、打标签)。 - - 连接 Gmail 并自动生成摘要或跟进。 + - 连接 Gmail 并自动生成摘要或跟进事项。 - 它可以处理大型任务,但在你把它们拆分成多个阶段, - 并使用子智能体进行并行工作时,效果会最好。 + 它可以处理大型任务,但当你把任务拆分成多个阶段,并 + 使用子智能体并行工作时,效果通常最好。 - - 日常收益通常表现为: + + 日常收益通常体现在: - - **个人简报:**总结你关心的收件箱、日历和新闻。 - - **研究与起草:**快速调研、摘要,以及邮件或文档的初稿。 - - **提醒与跟进:**由 cron 或 heartbeat 驱动的提醒和检查清单。 + - **个人简报:**总结你的收件箱、日历以及你关心的新闻。 + - **研究和起草:**快速研究、总结,以及为邮件或文档生成初稿。 + - **提醒和跟进:**由 cron 或 heartbeat 驱动的提醒和清单。 - **浏览器自动化:**填写表单、收集数据、重复执行网页任务。 - - **跨设备协同:**从手机发送任务,让 Gateway 网关在服务器上运行,然后把结果返回到聊天中。 + - **跨设备协作:**从手机发送任务,让 Gateway 网关在服务器上运行,然后在聊天中收到结果。 - 可以用于**研究、筛选和起草**。它可以扫描网站、构建候选清单、 - 总结潜在客户情况,并撰写外联或广告文案草稿。 + 对于**研究、资格筛选和起草**,可以。它可以扫描网站、建立候选名单、 + 总结潜在客户,并撰写外联文案或广告文案草稿。 - 对于**外联或广告投放**,请保留人工参与。避免垃圾信息,遵守当地法律和 - 平台政策,并在任何内容发送前先审查。最安全的模式是让 - OpenClaw 起草,由你批准。 + 对于**外联或广告投放**,请保持人工参与。避免垃圾信息,遵守当地法律和 + 平台政策,并在发送前审查所有内容。最安全的模式是让 + OpenClaw 起草,由你审批。 - 文档: [Security](/zh-CN/gateway/security)。 + 文档:[Security](/zh-CN/gateway/security)。 - - OpenClaw 是一个**个人助理**和协同层,而不是 IDE 替代品。对于仓库内最快的直接编码循环,请使用 - Claude Code 或 Codex。使用 OpenClaw 则是在你 + + OpenClaw 是一个**个人助手**和协调层,而不是 IDE 替代品。对于仓库内最快的直接编码循环, + 请使用 Claude Code 或 Codex。使用 OpenClaw 的场景是,当你 需要持久记忆、跨设备访问和工具编排时。 优势: - - 跨会话的**持久记忆 + 工作区** + - **持久记忆 + 工作区**,跨会话保留 - **多平台访问**(WhatsApp、Telegram、TUI、WebChat) - **工具编排**(浏览器、文件、调度、hooks) - - **始终在线的 Gateway 网关**(运行在 VPS 上,随时随地交互) - - 用于本地 browser/screen/camera/exec 的 **Nodes** + - **始终在线的 Gateway 网关**(运行在 VPS 上,从任何地方交互) + - 通过 **Nodes** 实现本地浏览器/屏幕/摄像头/exec - 展示: [https://openclaw.ai/showcase](https://openclaw.ai/showcase) + 展示页:[https://openclaw.ai/showcase](https://openclaw.ai/showcase) @@ -980,69 +989,69 @@ x-i18n: ## Skills 和自动化 - - 使用托管覆盖,而不是直接编辑仓库里的副本。把你的修改放到 `~/.openclaw/skills//SKILL.md`(或者通过 `~/.openclaw/openclaw.json` 中的 `skills.load.extraDirs` 添加文件夹)。优先级顺序为 `/skills` → `/.agents/skills` → `~/.agents/skills` → `~/.openclaw/skills` → 内置 → `skills.load.extraDirs`,因此托管覆盖仍然会在不修改 git 的情况下覆盖内置 Skills。如果你需要全局安装某个 skill,但只让部分智能体可见,请把共享副本放在 `~/.openclaw/skills`,然后用 `agents.defaults.skills` 和 `agents.list[].skills` 控制可见性。只有值得上游合并的改动才应该放在仓库里并通过 PR 提交。 + + 使用托管覆盖,而不是编辑仓库副本。把你的修改放到 `~/.openclaw/skills//SKILL.md` 中(或通过 `~/.openclaw/openclaw.json` 中的 `skills.load.extraDirs` 添加一个文件夹)。优先级顺序为 `/skills` → `/.agents/skills` → `~/.agents/skills` → `~/.openclaw/skills` → 内置 → `skills.load.extraDirs`,因此托管覆盖仍然会优先于内置 Skills,而无需触碰 git。如果你需要全局安装某个 skill,但只希望某些智能体可见,请将共享副本保存在 `~/.openclaw/skills` 中,并通过 `agents.defaults.skills` 和 `agents.list[].skills` 控制可见性。只有真正值得上游合并的修改才应保存在仓库中并通过 PR 提交。 - 可以。通过 `~/.openclaw/openclaw.json` 中的 `skills.load.extraDirs` 添加额外目录(最低优先级)。默认优先级为 `/skills` → `/.agents/skills` → `~/.agents/skills` → `~/.openclaw/skills` → 内置 → `skills.load.extraDirs`。`clawhub` 默认安装到 `./skills`,OpenClaw 会在下一个会话中将其视为 `/skills`。如果该 skill 只应对特定智能体可见,请结合 `agents.defaults.skills` 或 `agents.list[].skills` 使用。 + 可以。通过 `~/.openclaw/openclaw.json` 中的 `skills.load.extraDirs` 添加额外目录(最低优先级)。默认优先级是 `/skills` → `/.agents/skills` → `~/.agents/skills` → `~/.openclaw/skills` → 内置 → `skills.load.extraDirs`。`clawhub` 默认安装到 `./skills`,OpenClaw 会在下一个会话中将其视为 `/skills`。如果某个 skill 只应对特定智能体可见,请搭配 `agents.defaults.skills` 或 `agents.list[].skills` 使用。 - + 当前支持的模式有: - - **Cron 作业**:隔离作业可以为每个作业设置 `model` 覆盖。 - - **子智能体**:将任务路由到拥有不同默认模型的独立智能体。 - - **按需切换**:随时使用 `/model` 切换当前会话模型。 + - **Cron 任务**:隔离作业可为每个作业设置 `model` 覆盖。 + - **子智能体**:将任务路由到默认模型不同的独立智能体。 + - **按需切换**:使用 `/model` 随时切换当前会话模型。 - 参阅 [Cron jobs](/zh-CN/automation/cron-jobs), [多智能体路由](/zh-CN/concepts/multi-agent), 和 [斜杠命令](/zh-CN/tools/slash-commands)。 + 参阅 [Cron jobs](/zh-CN/automation/cron-jobs)、[Multi-Agent Routing](/zh-CN/concepts/multi-agent) 和 [Slash commands](/zh-CN/tools/slash-commands)。 - - 对于长时间或并行任务,请使用**子智能体**。子智能体在自己的会话中运行, - 返回摘要,并保持主聊天响应。 + + 对长任务或并行任务,请使用**子智能体**。子智能体在自己的会话中运行, + 返回摘要,并保持主聊天保持响应。 - 告诉你的机器人“为这个任务启动一个子智能体”,或者使用 `/subagents`。 - 在聊天中使用 `/status` 查看 Gateway 网关当前正在执行什么(以及它是否繁忙)。 + 你可以让机器人“为这个任务启动一个子智能体”,或者使用 `/subagents`。 + 在聊天中使用 `/status` 可查看 Gateway 网关当前正在做什么(以及它是否繁忙)。 - 令牌提示:长任务和子智能体都会消耗令牌。如果成本是个问题,请通过 - `agents.defaults.subagents.model` 为子智能体设置一个更便宜的模型。 + Token 提示:长任务和子智能体都会消耗 token。如果你在意成本,请通过 `agents.defaults.subagents.model` + 为子智能体设置一个更便宜的模型。 - 文档: [子智能体](/zh-CN/tools/subagents), [后台任务](/zh-CN/automation/tasks)。 + 文档:[Sub-agents](/zh-CN/tools/subagents)、[Background Tasks](/zh-CN/automation/tasks)。 - - 使用线程绑定。你可以把 Discord 线程绑定到子智能体或会话目标,这样该线程中的后续消息就会保留在绑定的会话中。 + + 使用线程绑定。你可以将一个 Discord 线程绑定到某个子智能体或会话目标,这样该线程中的后续消息就会持续进入那个绑定的会话。 基本流程: - - 使用 `sessions_spawn` 并设置 `thread: true` 启动(可选再加 `mode: "session"` 以支持持久后续跟进)。 + - 使用 `sessions_spawn` 并设置 `thread: true` 启动(如果希望持续跟进,也可设置 `mode: "session"`)。 - 或者通过 `/focus ` 手动绑定。 - - 使用 `/agents` 查看绑定状态。 + - 使用 `/agents` 检查绑定状态。 - 使用 `/session idle ` 和 `/session max-age ` 控制自动取消聚焦。 - - 使用 `/unfocus` 解绑线程。 + - 使用 `/unfocus` 解除线程绑定。 - 必需配置: + 所需配置: - - 全局默认值:`session.threadBindings.enabled`, `session.threadBindings.idleHours`, `session.threadBindings.maxAgeHours`。 - - Discord 覆盖:`channels.discord.threadBindings.enabled`, `channels.discord.threadBindings.idleHours`, `channels.discord.threadBindings.maxAgeHours`。 - - 启动时自动绑定:设置 `channels.discord.threadBindings.spawnSubagentSessions: true`。 + - 全局默认:`session.threadBindings.enabled`、`session.threadBindings.idleHours`、`session.threadBindings.maxAgeHours`。 + - Discord 覆盖:`channels.discord.threadBindings.enabled`、`channels.discord.threadBindings.idleHours`、`channels.discord.threadBindings.maxAgeHours`。 + - 在 spawn 时自动绑定:设置 `channels.discord.threadBindings.spawnSubagentSessions: true`。 - 文档: [子智能体](/zh-CN/tools/subagents), [Discord](/zh-CN/channels/discord), [Configuration Reference](/zh-CN/gateway/configuration-reference), [斜杠命令](/zh-CN/tools/slash-commands)。 + 文档:[Sub-agents](/zh-CN/tools/subagents)、[Discord](/zh-CN/channels/discord)、[Configuration Reference](/zh-CN/gateway/configuration-reference)、[Slash commands](/zh-CN/tools/slash-commands)。 - - 先检查已解析的请求者路由: + + 先检查解析出的请求方路由: - - 完成模式的子智能体投递会优先使用任何已绑定的线程或对话路由(如果存在)。 - - 如果完成来源只携带了渠道,OpenClaw 会回退到请求者会话存储的路由(`lastChannel` / `lastTo` / `lastAccountId`),这样直接投递仍然可以成功。 - - 如果既没有绑定路由,也没有可用的存储路由,直接投递可能失败,结果会退回到排队会话投递,而不是立即发到聊天。 - - 无效或过期目标仍然可能强制回退到队列或导致最终投递失败。 - - 如果子智能体最后一条可见的 assistant 回复正好是静默令牌 `NO_REPLY` / `no_reply`,或正好是 `ANNOUNCE_SKIP`,OpenClaw 会有意抑制公告,而不是发布过时的较早进度。 - - 如果子智能体在只调用工具后超时,公告可能会将其折叠成一个简短的部分进度摘要,而不是回放原始工具输出。 + - 完成模式下的子智能体投递会优先使用任何已绑定的线程或会话路由(如果存在)。 + - 如果完成来源只携带了一个渠道,OpenClaw 会退回到请求方会话存储的路由(`lastChannel` / `lastTo` / `lastAccountId`),以便直接投递仍然可以成功。 + - 如果既没有绑定路由,也没有可用的存储路由,则直接投递可能失败,结果会退回到排队的会话投递,而不是立即发到聊天中。 + - 无效或过时的目标仍可能导致退回到队列,或最终投递失败。 + - 如果子任务最后一个可见的助手回复正好是静默令牌 `NO_REPLY` / `no_reply`,或正好是 `ANNOUNCE_SKIP`,OpenClaw 会有意抑制公告,而不是发布先前的陈旧进度。 + - 如果子任务在仅执行工具调用后超时,则公告可能会将其压缩成一个简短的部分进度摘要,而不是回放原始工具输出。 调试: @@ -1050,19 +1059,19 @@ x-i18n: openclaw tasks show ``` - 文档: [子智能体](/zh-CN/tools/subagents), [后台任务](/zh-CN/automation/tasks), [会话工具](/zh-CN/concepts/session-tool)。 + 文档:[Sub-agents](/zh-CN/tools/subagents)、[Background Tasks](/zh-CN/automation/tasks)、[Session Tools](/zh-CN/concepts/session-tool)。 - Cron 在 Gateway 网关进程内运行。如果 Gateway 网关没有持续运行, - 定时作业就不会执行。 + Cron 在 Gateway 网关进程内部运行。如果 Gateway 网关没有持续运行, + 定时任务就不会执行。 检查清单: - - 确认 cron 已启用(`cron.enabled`)且未设置 `OPENCLAW_SKIP_CRON`。 - - 检查 Gateway 网关是否 24/7 运行(没有休眠/重启)。 - - 验证作业的时区设置(`--tz` 与主机时区)。 + - 确认 cron 已启用(`cron.enabled`),并且未设置 `OPENCLAW_SKIP_CRON`。 + - 检查 Gateway 网关是否正在 24/7 持续运行(没有睡眠/重启)。 + - 验证任务的时区设置(`--tz` 与主机时区)。 调试: @@ -1071,22 +1080,22 @@ x-i18n: openclaw cron runs --id --limit 50 ``` - 文档: [Cron jobs](/zh-CN/automation/cron-jobs), [自动化与任务](/zh-CN/automation)。 + 文档:[Cron jobs](/zh-CN/automation/cron-jobs)、[Automation & Tasks](/zh-CN/automation)。 - + 先检查投递模式: - - `--no-deliver` / `delivery.mode: "none"` 表示预期不会有任何外部消息。 - - 缺失或无效的 announce 目标(`channel` / `to`)意味着运行器跳过了出站投递。 - - 渠道认证失败(`unauthorized`, `Forbidden`)表示运行器尝试投递了,但被凭据阻止。 - - 静默的隔离结果(仅 `NO_REPLY` / `no_reply`)会被视为有意不可投递,因此运行器也会抑制排队回退投递。 + - `--no-deliver` / `delivery.mode: "none"` 表示不期望任何外部消息。 + - 缺失或无效的公告目标(`channel` / `to`)意味着运行器跳过了对外投递。 + - 渠道认证失败(`unauthorized`、`Forbidden`)意味着运行器尝试投递了,但凭据阻止了它。 + - 静默的隔离结果(只有 `NO_REPLY` / `no_reply`)会被视为有意不投递,因此运行器也会抑制排队回退投递。 - 对于隔离的 cron 作业,最终投递由运行器负责。智能体 - 应返回纯文本摘要,供运行器发送。`--no-deliver` 会将 - 该结果保留为内部结果;它不会让智能体改用 - message 工具直接发送。 + 对于隔离的 cron 作业,最终投递由运行器负责。系统期望 + 智能体返回一段纯文本摘要供运行器发送。`--no-deliver` 会让 + 该结果只保留在内部;它并不会让智能体改为直接通过 + message 工具发送。 调试: @@ -1095,26 +1104,26 @@ x-i18n: openclaw tasks show ``` - 文档: [Cron jobs](/zh-CN/automation/cron-jobs), [后台任务](/zh-CN/automation/tasks)。 + 文档:[Cron jobs](/zh-CN/automation/cron-jobs)、[Background Tasks](/zh-CN/automation/tasks)。 - + 这通常是实时模型切换路径,而不是重复调度。 隔离的 cron 在活动运行抛出 `LiveSessionModelSwitchError` 时, - 可以持久化运行时模型交接并重试。重试会保留已切换的 - provider/model,如果该切换带来了新的认证配置覆盖,cron + 可以持久化一个运行时模型切换并重试。重试会保留切换后的 + 提供商/模型;如果切换中带有新的认证档案覆盖,cron 也会在重试前将其持久化。 相关选择规则: - - 如果适用,Gmail hook 的模型覆盖优先生效。 + - 如果适用,Gmail hook 模型覆盖优先级最高。 - 然后是每个作业的 `model`。 - - 然后是任何已存储的 cron-session 模型覆盖。 - - 然后是常规的智能体/默认模型选择。 + - 然后是任何已存储的 cron 会话模型覆盖。 + - 最后才是正常的智能体/默认模型选择。 - 重试循环是有界的。在初始尝试加 2 次切换重试之后, + 重试循环是有界的。在初始尝试加上 2 次切换重试之后, cron 会中止,而不是无限循环。 调试: @@ -1124,13 +1133,13 @@ x-i18n: openclaw tasks show ``` - 文档: [Cron jobs](/zh-CN/automation/cron-jobs), [cron CLI](/cli/cron)。 + 文档:[Cron jobs](/zh-CN/automation/cron-jobs)、[cron CLI](/cli/cron)。 - 使用原生 `openclaw skills` 命令,或者把 Skills 放到你的工作区。macOS Skills UI 在 Linux 上不可用。 - 你可以在 [https://clawhub.ai](https://clawhub.ai) 浏览 Skills。 + 使用原生 `openclaw skills` 命令,或直接将 Skills 放入你的工作区。macOS Skills UI 在 Linux 上不可用。 + 浏览 Skills: [https://clawhub.ai](https://clawhub.ai)。 ```bash openclaw skills search "calendar" @@ -1144,40 +1153,40 @@ x-i18n: ``` 原生 `openclaw skills install` 会写入当前工作区的 `skills/` - 目录。只有在你想发布或 - 同步自己的 Skills 时,才需要单独安装 `clawhub` CLI。对于跨智能体的共享安装,请将 skill 放在 - `~/.openclaw/skills` 下,并使用 `agents.defaults.skills` 或 - `agents.list[].skills` 来缩小可见范围。 + 目录。只有当你想发布或 + 同步你自己的 Skills 时,才需要另外安装 `clawhub` CLI。对于跨智能体共享安装,请把 skill 放到 + `~/.openclaw/skills` 下,并在你想缩小可见范围时使用 `agents.defaults.skills` 或 + `agents.list[].skills`。 可以。使用 Gateway 网关调度器: - - **Cron 作业**:用于计划任务或重复任务(重启后仍然保留)。 - - **Heartbeat**:用于“主会话”的定期检查。 - - **隔离作业**:用于自主智能体发布摘要或投递到聊天。 + - **Cron jobs** 用于定时或周期性任务(跨重启持久化)。 + - **Heartbeat** 用于“主会话”的周期性检查。 + - **隔离作业** 用于自主智能体,它们会发布摘要或投递到聊天中。 - 文档: [Cron jobs](/zh-CN/automation/cron-jobs), [自动化与任务](/zh-CN/automation), + 文档:[Cron jobs](/zh-CN/automation/cron-jobs)、[Automation & Tasks](/zh-CN/automation)、 [Heartbeat](/zh-CN/gateway/heartbeat)。 - - 不能直接运行。macOS Skills 受 `metadata.openclaw.os` 和所需二进制文件限制,并且 skill 只有在 **Gateway 网关主机** 上符合条件时才会出现在 system prompt 中。在 Linux 上,`darwin` 专用技能(如 `apple-notes`、`apple-reminders`、`things-mac`)不会加载,除非你覆盖这些限制。 + + 不能直接运行。macOS Skills 受 `metadata.openclaw.os` 和所需二进制文件控制,且只有在它们对**Gateway 主机**满足条件时,Skills 才会出现在系统提示中。在 Linux 上,仅限 `darwin` 的 Skills(如 `apple-notes`、`apple-reminders`、`things-mac`)不会加载,除非你覆盖这种限制。 你有三种受支持的模式: **选项 A - 在 Mac 上运行 Gateway 网关(最简单)。** - 在 macOS 二进制存在的地方运行 Gateway 网关,然后通过 [远程模式](#gateway-端口已在运行和远程模式) 或 Tailscale 从 Linux 连接。由于 Gateway 网关主机是 macOS,这些 Skills 会正常加载。 + 在 macOS 二进制文件所在的地方运行 Gateway 网关,然后从 Linux 通过 [remote mode](#gateway-ports-already-running-and-remote-mode) 或 Tailscale 连接。由于 Gateway 主机是 macOS,这些 Skills 会正常加载。 **选项 B - 使用 macOS 节点(无需 SSH)。** - 在 Linux 上运行 Gateway 网关,配对一个 macOS 节点(菜单栏应用),并将 Mac 上的 **Node Run Commands** 设置为 “Always Ask” 或 “Always Allow”。当节点上存在所需二进制时,OpenClaw 可以将仅限 macOS 的 Skills 视为符合条件。智能体会通过 `nodes` 工具运行这些 Skills。如果你选择 “Always Ask”,在提示中批准 “Always Allow” 会将该命令加入允许列表。 + 在 Linux 上运行 Gateway 网关,配对一个 macOS 节点(菜单栏应用),并将 Mac 上的**Node Run Commands** 设为 “Always Ask” 或 “Always Allow”。当节点上存在所需二进制文件时,OpenClaw 可以将这些仅限 macOS 的 Skills 视为可用。智能体会通过 `nodes` 工具运行这些 Skills。如果你选择 “Always Ask”,并在提示中批准 “Always Allow”,该命令就会被加入允许列表。 - **选项 C - 通过 SSH 代理 macOS 二进制(高级)。** - 保持 Gateway 网关运行在 Linux 上,但让所需 CLI 二进制解析为在 Mac 上运行的 SSH 包装器。然后覆盖 skill 以允许 Linux,使其保持可用。 + **选项 C - 通过 SSH 代理 macOS 二进制文件(高级)。** + Gateway 网关保留在 Linux 上,但让所需的 CLI 二进制文件解析为在 Mac 上执行的 SSH 包装器。然后覆盖该 skill,使其允许 Linux,从而保持其可用。 - 1. 为该二进制创建一个 SSH 包装器(示例:Apple Notes 的 `memo`): + 1. 为该二进制文件创建一个 SSH 包装器(示例:Apple Notes 的 `memo`): ```bash #!/usr/bin/env bash @@ -1185,7 +1194,7 @@ x-i18n: exec ssh -T user@mac-host /opt/homebrew/bin/memo "$@" ``` - 2. 将包装器放到 Linux 主机的 `PATH` 中(例如 `~/bin/memo`)。 + 2. 将该包装器放到 Linux 主机的 `PATH` 中(例如 `~/bin/memo`)。 3. 覆盖 skill 元数据(工作区或 `~/.openclaw/skills`)以允许 Linux: ```markdown @@ -1196,25 +1205,24 @@ x-i18n: --- ``` - 4. 开始一个新会话,以刷新 Skills 快照。 + 4. 启动一个新会话,以刷新 Skills 快照。 目前没有内置。 - 可选方案: + 选项: - - **自定义 skill / 插件:**最适合稳定可靠的 API 访问(Notion/HeyGen 都有 API)。 - - **浏览器自动化:**无需代码即可工作,但更慢、更脆弱。 + - **自定义 skill / plugin:**最适合可靠的 API 访问(Notion/HeyGen 都有 API)。 + - **浏览器自动化:**无需写代码,但速度更慢、脆弱性更高。 - 如果你想为每个客户保留上下文(代理/机构工作流),一个简单模式是: + 如果你想为每个客户保留上下文(例如代理机构工作流),一个简单模式是: - 每个客户一个 Notion 页面(上下文 + 偏好 + 当前工作)。 - - 让智能体在会话开始时获取该页面。 + - 让智能体在每次会话开始时获取该页面。 - 如果你想要原生集成,请提交功能请求,或者构建一个 - 面向这些 API 的 skill。 + 如果你想要原生集成,请提交功能请求,或者构建一个针对这些 API 的 skill。 安装 Skills: @@ -1223,32 +1231,32 @@ x-i18n: openclaw skills update --all ``` - 原生安装会落在当前工作区的 `skills/` 目录中。对于跨智能体共享的 skill,请将其放到 `~/.openclaw/skills//SKILL.md`。如果只有部分智能体应看到共享安装,请配置 `agents.defaults.skills` 或 `agents.list[].skills`。一些 skill 依赖通过 Homebrew 安装的二进制;在 Linux 上这意味着 Linuxbrew(见上方 Homebrew Linux FAQ 条目)。参阅 [Skills](/zh-CN/tools/skills), [Skills 配置](/zh-CN/tools/skills-config), 和 [ClawHub](/zh-CN/tools/clawhub)。 + 原生安装会落在当前工作区的 `skills/` 目录中。对于跨智能体共享的 Skills,请将它们放在 `~/.openclaw/skills//SKILL.md`。如果只有某些智能体应该看到共享安装,请配置 `agents.defaults.skills` 或 `agents.list[].skills`。某些 Skills 需要通过 Homebrew 安装二进制文件;在 Linux 上这意味着 Linuxbrew(参见上面的 Homebrew Linux FAQ 条目)。参阅 [Skills](/zh-CN/tools/skills)、[Skills 配置](/zh-CN/tools/skills-config) 和 [ClawHub](/zh-CN/tools/clawhub)。 - - 使用内置的 `user` 浏览器配置,它通过 Chrome DevTools MCP 进行附着: + + 使用内置的 `user` 浏览器配置,它会通过 Chrome DevTools MCP 进行连接: ```bash openclaw browser --browser-profile user tabs openclaw browser --browser-profile user snapshot ``` - 如果你想使用自定义名称,请创建显式 MCP 配置: + 如果你想使用自定义名称,请创建一个显式 MCP 配置: ```bash openclaw browser create-profile --name chrome-live --driver existing-session openclaw browser --browser-profile chrome-live tabs ``` - 该路径仅限本地主机。如果 Gateway 网关运行在其他地方,请在浏览器所在机器上运行一个 node host,或者改用远程 CDP。 + 这条路径仅适用于本地主机。如果 Gateway 网关运行在别处,那么要么在浏览器所在机器上运行一个节点主机,要么改用远程 CDP。 `existing-session` / `user` 当前限制: - - 操作基于 ref 驱动,而不是基于 CSS 选择器 - - 上传需要 `ref` / `inputRef`,并且目前一次仅支持一个文件 - - `responsebody`、PDF 导出、下载拦截和批量操作仍需要托管浏览器或原始 CDP 配置 + - 操作是基于 ref 驱动,而不是基于 CSS 选择器 + - 上传需要 `ref` / `inputRef`,并且当前一次只支持一个文件 + - `responsebody`、PDF 导出、下载拦截和批量操作仍然需要托管浏览器或原始 CDP 配置 @@ -1256,147 +1264,147 @@ x-i18n: ## 沙箱隔离和记忆 - - 有。参阅 [沙箱隔离](/zh-CN/gateway/sandboxing)。有关 Docker 特定设置(完整 Gateway 网关在 Docker 中运行或沙箱镜像),请参阅 [Docker](/zh-CN/install/docker)。 + + 有。参阅 [沙箱隔离](/zh-CN/gateway/sandboxing)。关于 Docker 特定设置(完整 Gateway 网关在 Docker 中运行或沙箱镜像),请参阅 [Docker](/zh-CN/install/docker)。 - - 默认镜像以安全优先,且以 `node` 用户运行,因此它不 - 包含系统包、Homebrew 或内置浏览器。若要获得更完整的设置: + + 默认镜像以安全优先方式运行,并使用 `node` 用户,因此它 + 不包含系统软件包、Homebrew 或内置浏览器。若要获得更完整的设置: - - 持久化 `/home/node`,使用 `OPENCLAW_HOME_VOLUME` 让缓存得以保留。 - - 使用 `OPENCLAW_DOCKER_APT_PACKAGES` 将系统依赖烘焙进镜像。 + - 通过 `OPENCLAW_HOME_VOLUME` 持久化 `/home/node`,使缓存得以保留。 + - 通过 `OPENCLAW_DOCKER_APT_PACKAGES` 将系统依赖烘焙进镜像。 - 通过内置 CLI 安装 Playwright 浏览器: `node /app/node_modules/playwright-core/cli.js install chromium` - - 设置 `PLAYWRIGHT_BROWSERS_PATH` 并确保该路径会被持久化。 + - 设置 `PLAYWRIGHT_BROWSERS_PATH`,并确保该路径已持久化。 - 文档: [Docker](/zh-CN/install/docker), [Browser](/zh-CN/tools/browser)。 + 文档:[Docker](/zh-CN/install/docker)、[Browser](/zh-CN/tools/browser)。 - - 可以——前提是你的私人流量是**私信**,而公开流量是**群组**。 + + 可以——前提是你的私密流量是**私信**,而公开流量是**群组**。 - 使用 `agents.defaults.sandbox.mode: "non-main"`,这样群组/渠道会话(非主键)会在 Docker 中运行,而主私信会话仍在主机上运行。然后通过 `tools.sandbox.tools` 限制沙箱隔离会话中可用的工具。 + 使用 `agents.defaults.sandbox.mode: "non-main"`,这样群组/渠道会话(非主键)会在 Docker 中运行,而主私信会话则保留在主机上。然后通过 `tools.sandbox.tools` 限制沙箱隔离会话中可用的工具。 - 设置演练 + 示例配置: [群组:私人私信 + 公开群组](/zh-CN/channels/groups#pattern-personal-dms-public-groups-single-agent) + 设置演练 + 示例配置:[Groups: personal DMs + public groups](/zh-CN/channels/groups#pattern-personal-dms-public-groups-single-agent) - 关键配置参考: [Gateway 配置](/zh-CN/gateway/configuration-reference#agentsdefaultssandbox) + 关键配置参考:[Gateway configuration](/zh-CN/gateway/configuration-reference#agentsdefaultssandbox) - - 将 `agents.defaults.sandbox.docker.binds` 设置为 `["host:path:mode"]`(例如 `"/home/user/src:/src:ro"`)。全局和每个智能体的绑定会合并;当 `scope: "shared"` 时,每个智能体的绑定会被忽略。对任何敏感内容都使用 `:ro`,并记住绑定会绕过沙箱文件系统边界。 + + 将 `agents.defaults.sandbox.docker.binds` 设置为 `["host:path:mode"]`(例如 `"/home/user/src:/src:ro"`)。全局和每智能体 bind 会合并;当 `scope: "shared"` 时,每智能体 bind 会被忽略。对任何敏感内容请使用 `:ro`,并记住 bind 会绕过沙箱文件系统边界。 - OpenClaw 会根据规范化路径和通过最深现有祖先解析的规范路径同时验证绑定源。这意味着即使最后一个路径段还不存在,通过父级符号链接逃逸的情况仍会被安全地拒绝,而且在符号链接解析后仍会应用允许根目录检查。 + OpenClaw 会同时依据规范化路径以及通过最深已存在祖先解析出来的规范路径来验证 bind 源。这意味着即便最后一个路径段尚不存在,通过符号链接父级逃逸也会被安全地失败关闭,而且在符号链接解析后,allowed-root 检查仍然会生效。 - 示例和安全说明请参阅 [沙箱隔离](/zh-CN/gateway/sandboxing#custom-bind-mounts) 和 [沙箱 vs 工具策略 vs 提权](/zh-CN/gateway/sandbox-vs-tool-policy-vs-elevated#bind-mounts-security-quick-check)。 + 关于示例和安全说明,请参阅 [沙箱隔离](/zh-CN/gateway/sandboxing#custom-bind-mounts) 和 [Sandbox vs Tool Policy vs Elevated](/zh-CN/gateway/sandbox-vs-tool-policy-vs-elevated#bind-mounts-security-quick-check)。 - OpenClaw 的记忆只是智能体工作区中的 Markdown 文件: + OpenClaw 的记忆其实就是智能体工作区中的 Markdown 文件: - `memory/YYYY-MM-DD.md` 中的每日笔记 - - `MEMORY.md` 中经过整理的长期笔记(仅主/私密会话) + - `MEMORY.md` 中整理过的长期笔记(仅主/私密会话) OpenClaw 还会运行一个**静默的预压缩记忆刷新**,提醒模型 - 在自动压缩前写下持久笔记。这个过程只会在工作区 - 可写时运行(只读沙箱会跳过)。参阅 [Memory](/zh-CN/concepts/memory)。 + 在自动压缩前写下持久笔记。这只会在工作区可写时运行 + (只读沙箱会跳过)。参阅 [Memory](/zh-CN/concepts/memory)。 - - 告诉机器人**把这个事实写入记忆**。长期笔记应写入 `MEMORY.md`, - 短期上下文则写入 `memory/YYYY-MM-DD.md`。 + + 让机器人**把事实写入记忆**。长期笔记应放在 `MEMORY.md` 中, + 短期上下文则放在 `memory/YYYY-MM-DD.md` 中。 这是我们仍在持续改进的领域。提醒模型存储记忆会有帮助; - 它会知道该怎么做。如果它仍然频繁忘记,请确认 Gateway 网关每次运行时使用的是同一个 + 它知道该怎么做。如果它仍然总忘记,请确认 Gateway 网关每次运行时都在使用同一个 工作区。 - 文档: [Memory](/zh-CN/concepts/memory), [智能体工作区](/zh-CN/concepts/agent-workspace)。 + 文档:[Memory](/zh-CN/concepts/memory)、[Agent workspace](/zh-CN/concepts/agent-workspace)。 - - 记忆文件存储在磁盘上,除非你删除它们,否则会一直保留。限制取决于你的 + + 记忆文件保存在磁盘上,会一直存在,直到你删除它们。限制来自你的 存储空间,而不是模型。**会话上下文** - 仍然受模型上下文窗口限制,因此长对话可能会压缩或截断。这也是 - 为什么存在记忆搜索——它只会把相关部分拉回上下文。 + 仍然受模型上下文窗口限制,因此长对话可能会被压缩或截断。这就是为什么 + 有记忆搜索——它只会把相关部分重新拉回到上下文中。 - 文档: [Memory](/zh-CN/concepts/memory), [Context](/zh-CN/concepts/context)。 + 文档:[Memory](/zh-CN/concepts/memory)、[Context](/zh-CN/concepts/context)。 - - 只有在你使用 **OpenAI embeddings** 时才需要。Codex OAuth 仅覆盖聊天/补全, + + 只有在你使用**OpenAI embeddings** 时才需要。Codex OAuth 仅涵盖聊天/补全, **不**授予 embeddings 访问权限,因此**使用 Codex 登录(OAuth 或 Codex CLI 登录)**对语义记忆搜索没有帮助。OpenAI embeddings - 仍然需要真实的 API key(`OPENAI_API_KEY` 或 `models.providers.openai.apiKey`)。 + 仍然需要真实的 API 密钥(`OPENAI_API_KEY` 或 `models.providers.openai.apiKey`)。 - 如果你没有显式设置提供商,OpenClaw 会在它 - 能解析出 API key 时自动选择提供商(认证配置文件、`models.providers.*.apiKey` 或环境变量)。 - 如果能解析到 OpenAI key,它会优先选择 OpenAI;否则如果能解析到 Gemini key, - 就选择 Gemini;然后是 Voyage,再然后是 Mistral。如果没有可用的远程 key,记忆 - 搜索会保持禁用状态,直到你完成配置。如果你已配置并存在本地模型路径,OpenClaw - 会优先选择 `local`。Ollama 也受支持,但需要你显式设置 - `memorySearch.provider = "ollama"`。 + 如果你没有显式设置提供商,只要它 + 能解析出 API 密钥,OpenClaw 就会自动选择一个提供商(认证档案、`models.providers.*.apiKey` 或环境变量)。 + 如果能解析出 OpenAI 密钥,它会优先选择 OpenAI;否则如果能解析出 Gemini 密钥, + 就选择 Gemini;然后是 Voyage,再然后是 Mistral。如果没有可用的远程密钥, + 记忆搜索会保持禁用状态,直到你完成配置。如果你已经配置并存在本地模型路径,OpenClaw + 会优先使用 `local`。只有在你显式设置 + `memorySearch.provider = "ollama"` 时,才支持 Ollama。 - 如果你希望完全留在本地,请设置 `memorySearch.provider = "local"`(可选再设置 + 如果你更倾向于保持本地化,请设置 `memorySearch.provider = "local"`(并可选设置 `memorySearch.fallback = "none"`)。如果你想使用 Gemini embeddings,请设置 `memorySearch.provider = "gemini"` 并提供 `GEMINI_API_KEY`(或 `memorySearch.remote.apiKey`)。我们支持 **OpenAI、Gemini、Voyage、Mistral、Ollama 或 local** embedding - 模型——有关设置细节,请参阅 [Memory](/zh-CN/concepts/memory)。 + 模型——设置细节参见 [Memory](/zh-CN/concepts/memory)。 -## 磁盘上的文件位置 +## 磁盘上的存储位置 - - 不是——**OpenClaw 的状态保存在本地**,但**外部服务仍然会看到你发给它们的内容**。 + + 不会——**OpenClaw 的状态保存在本地**,但**外部服务仍然会看到你发给它们的内容**。 - **默认本地:**会话、记忆文件、配置和工作区都保存在 Gateway 网关主机上 (`~/.openclaw` + 你的工作区目录)。 - - **必然远程:**你发送给模型提供商(Anthropic/OpenAI 等)的消息会进入 - 它们的 API,而聊天平台(WhatsApp/Telegram/Slack 等)会将消息数据存储在 - 它们的服务器上。 - - **你可以控制数据足迹:**使用本地模型可以让提示词保留在你的机器上,但渠道 - 流量仍然会通过该渠道的服务器。 + - **必须远程:**你发送给模型提供商(Anthropic/OpenAI 等)的消息会进入 + 它们的 API,而聊天平台(WhatsApp/Telegram/Slack 等)会在 + 它们的服务器上存储消息数据。 + - **你可以控制暴露范围:**使用本地模型会让提示保留在你的机器上,但渠道 + 流量仍然会通过对应渠道的服务器。 - 相关内容: [智能体工作区](/zh-CN/concepts/agent-workspace), [Memory](/zh-CN/concepts/memory)。 + 相关内容:[Agent workspace](/zh-CN/concepts/agent-workspace)、[Memory](/zh-CN/concepts/memory)。 - - 所有内容都位于 `$OPENCLAW_STATE_DIR`(默认:`~/.openclaw`)下: + + 所有内容都位于 `$OPENCLAW_STATE_DIR` 下(默认:`~/.openclaw`): - | Path | 用途 | - | --------------------------------------------------------------- | ------------------------------------------------------------------ | - | `$OPENCLAW_STATE_DIR/openclaw.json` | 主配置(JSON5) | - | `$OPENCLAW_STATE_DIR/credentials/oauth.json` | 旧版 OAuth 导入(首次使用时会复制到认证配置文件中) | - | `$OPENCLAW_STATE_DIR/agents//agent/auth-profiles.json` | 认证配置文件(OAuth、API 密钥,以及可选的 `keyRef`/`tokenRef`) | - | `$OPENCLAW_STATE_DIR/secrets.json` | 用于 `file` SecretRef 提供商的可选文件后备机密负载 | - | `$OPENCLAW_STATE_DIR/agents//agent/auth.json` | 旧版兼容文件(静态 `api_key` 条目会被清理) | - | `$OPENCLAW_STATE_DIR/credentials/` | 提供商状态(例如 `whatsapp//creds.json`) | - | `$OPENCLAW_STATE_DIR/agents/` | 每个智能体的状态(agentDir + sessions) | - | `$OPENCLAW_STATE_DIR/agents//sessions/` | 对话历史与状态(按智能体) | - | `$OPENCLAW_STATE_DIR/agents//sessions/sessions.json` | 会话元数据(按智能体) | + | 路径 | 用途 | + | --------------------------------------------------------------- | ----------------------------------------------------------------- | + | `$OPENCLAW_STATE_DIR/openclaw.json` | 主配置(JSON5) | + | `$OPENCLAW_STATE_DIR/credentials/oauth.json` | 旧版 OAuth 导入(首次使用时复制到认证档案中) | + | `$OPENCLAW_STATE_DIR/agents//agent/auth-profiles.json` | 认证档案(OAuth、API 密钥,以及可选的 `keyRef`/`tokenRef`) | + | `$OPENCLAW_STATE_DIR/secrets.json` | `file` SecretRef 提供商可选的基于文件的 secret 负载 | + | `$OPENCLAW_STATE_DIR/agents//agent/auth.json` | 旧版兼容文件(静态 `api_key` 条目已清理) | + | `$OPENCLAW_STATE_DIR/credentials/` | 提供商状态(例如 `whatsapp//creds.json`) | + | `$OPENCLAW_STATE_DIR/agents/` | 每智能体状态(agentDir + sessions) | + | `$OPENCLAW_STATE_DIR/agents//sessions/` | 对话历史和状态(按智能体区分) | + | `$OPENCLAW_STATE_DIR/agents//sessions/sessions.json` | 会话元数据(按智能体区分) | 旧版单智能体路径:`~/.openclaw/agent/*`(由 `openclaw doctor` 迁移)。 - 你的**工作区**(AGENTS.md、记忆文件、Skills 等)是单独存放的,并通过 `agents.defaults.workspace` 配置(默认:`~/.openclaw/workspace`)。 + 你的**工作区**(AGENTS.md、记忆文件、Skills 等)是分开的,通过 `agents.defaults.workspace` 配置(默认:`~/.openclaw/workspace`)。 - 这些文件位于**智能体工作区**,而不是 `~/.openclaw`。 + 这些文件位于**智能体工作区**中,而不是 `~/.openclaw`。 - - **工作区(每个智能体)**:`AGENTS.md`, `SOUL.md`, `IDENTITY.md`, `USER.md`, - `MEMORY.md`(当 `MEMORY.md` 不存在时,使用旧版回退 `memory.md`), - `memory/YYYY-MM-DD.md`,可选的 `HEARTBEAT.md`。 - - **状态目录(`~/.openclaw`)**:配置、渠道/提供商状态、认证配置文件、会话、日志, + - **工作区(按智能体):**`AGENTS.md`、`SOUL.md`、`IDENTITY.md`、`USER.md`、 + `MEMORY.md`(如果缺少 `MEMORY.md`,则使用旧版回退 `memory.md`)、 + `memory/YYYY-MM-DD.md`、可选的 `HEARTBEAT.md`。 + - **状态目录(`~/.openclaw`):**配置、渠道/提供商状态、认证档案、会话、日志, 以及共享 Skills(`~/.openclaw/skills`)。 默认工作区为 `~/.openclaw/workspace`,可通过以下方式配置: @@ -1407,32 +1415,32 @@ x-i18n: } ``` - 如果机器人在重启后“忘记”了内容,请确认 Gateway 网关每次启动时使用的都是同一个 - 工作区(并记住:远程模式使用的是 **gateway host** - 的工作区,而不是你的本地笔记本)。 + 如果机器人在重启后“忘记了”东西,请确认 Gateway 网关每次启动时都在使用同一个 + 工作区(并记住:远程模式使用的是**gateway 主机** + 的工作区,而不是你本地笔记本的工作区)。 - 提示:如果你想保留某个持久行为或偏好,请让机器人**将其写入 + 提示:如果你想保留某个持久行为或偏好,请让机器人**把它写进 AGENTS.md 或 MEMORY.md**,而不是依赖聊天历史。 - 参阅 [智能体工作区](/zh-CN/concepts/agent-workspace) 和 [Memory](/zh-CN/concepts/memory)。 + 参阅 [Agent workspace](/zh-CN/concepts/agent-workspace) 和 [Memory](/zh-CN/concepts/memory)。 - 将你的**智能体工作区**放入一个**私有** git 仓库,并备份到某个 - 私有位置(例如 GitHub 私有仓库)。这可以保留记忆 + AGENTS/SOUL/USER - 文件,并让你日后恢复这个助手的“思维”。 + 把你的**智能体工作区**放进一个**私有** git 仓库中,并备份到某个 + 私有位置(例如 GitHub 私有仓库)。这样可以保存记忆 + AGENTS/SOUL/USER + 文件,也让你以后可以恢复助手的“思维”。 - **不要**提交 `~/.openclaw` 下的任何内容(凭据、会话、令牌或加密机密负载)。 + **不要**提交 `~/.openclaw` 下的任何内容(凭据、会话、令牌或加密的 secret 负载)。 如果你需要完整恢复,请分别备份工作区和状态目录 (见上面的迁移问题)。 - 文档: [智能体工作区](/zh-CN/concepts/agent-workspace)。 + 文档:[Agent workspace](/zh-CN/concepts/agent-workspace)。 - 请参阅专门指南: [Uninstall](/zh-CN/install/uninstall)。 + 请参阅专门指南:[Uninstall](/zh-CN/install/uninstall)。 @@ -1440,11 +1448,11 @@ x-i18n: 相对路径会在工作区内解析,但绝对路径可以访问主机上的其他 位置,除非启用了沙箱隔离。如果你需要隔离,请使用 [`agents.defaults.sandbox`](/zh-CN/gateway/sandboxing) 或每个智能体的沙箱设置。如果你 - 希望某个仓库作为默认工作目录,请将该智能体的 - `workspace` 指向仓库根目录。OpenClaw 仓库只是源码;除非你有意让智能体在其中工作,否则请保持 - 工作区与仓库分离。 + 希望某个仓库成为默认工作目录,可以把该智能体的 + `workspace` 指向仓库根目录。OpenClaw 仓库只是源码;除非你明确想让智能体在其中工作, + 否则请让工作区与其分离。 - 示例(将仓库作为默认 cwd): + 示例(以仓库为默认 cwd): ```json5 { @@ -1459,29 +1467,29 @@ x-i18n: - 会话状态归**gateway host** 所有。如果你处于远程模式,你关心的会话存储位于远程机器上,而不是你的本地笔记本。参阅 [会话管理](/zh-CN/concepts/session)。 + 会话状态由**gateway 主机**持有。如果你处于远程模式,那么你关心的会话存储位于远程机器上,而不是你的本地笔记本。参阅 [Session management](/zh-CN/concepts/session)。 ## 配置基础 - - OpenClaw 会从 `$OPENCLAW_CONFIG_PATH`(默认:`~/.openclaw/openclaw.json`)读取可选的 **JSON5** 配置: + + OpenClaw 会从 `$OPENCLAW_CONFIG_PATH` 读取一个可选的 **JSON5** 配置(默认:`~/.openclaw/openclaw.json`): ``` $OPENCLAW_CONFIG_PATH ``` - 如果文件不存在,它会使用相对安全的默认值(包括默认工作区 `~/.openclaw/workspace`)。 + 如果该文件不存在,它会使用较为安全的默认值(包括默认工作区 `~/.openclaw/workspace`)。 - - 非 loopback bind **需要有效的 gateway auth 路径**。在实践中这意味着: + + 非 loopback 绑定**需要一个有效的 gateway 认证路径**。实际来说,这意味着: - 共享密钥认证:令牌或密码 - - 在正确配置的非 loopback 身份感知反向代理后使用 `gateway.auth.mode: "trusted-proxy"` + - 在配置正确的非 loopback 身份感知反向代理后使用 `gateway.auth.mode: "trusted-proxy"` ```json5 { @@ -1497,31 +1505,31 @@ x-i18n: 说明: - - `gateway.remote.token` / `.password` 本身**不会**启用本地 gateway auth。 - - 只有当 `gateway.auth.*` 未设置时,本地调用路径才会回退使用 `gateway.remote.*`。 - - 对于密码认证,请改为设置 `gateway.auth.mode: "password"` 加 `gateway.auth.password`(或 `OPENCLAW_GATEWAY_PASSWORD`)。 - - 如果 `gateway.auth.token` / `gateway.auth.password` 通过 SecretRef 显式配置但未解析成功,解析会以安全关闭的方式失败(不会被远程回退掩盖)。 - - 共享密钥 Control UI 设置通过 `connect.params.auth.token` 或 `connect.params.auth.password` 进行认证(存储在应用/UI 设置中)。像 Tailscale Serve 或 `trusted-proxy` 这样的身份承载模式则改用请求头。避免将共享密钥放进 URL。 - - 使用 `gateway.auth.mode: "trusted-proxy"` 时,同主机 loopback 反向代理**仍然不会**满足 trusted-proxy auth。可信代理必须是已配置的非 loopback 来源。 + - `gateway.remote.token` / `.password` **本身不会**启用本地 gateway 认证。 + - 仅当 `gateway.auth.*` 未设置时,本地调用路径才可以将 `gateway.remote.*` 作为回退。 + - 对于密码认证,请改为设置 `gateway.auth.mode: "password"` 加上 `gateway.auth.password`(或 `OPENCLAW_GATEWAY_PASSWORD`)。 + - 如果 `gateway.auth.token` / `gateway.auth.password` 通过 SecretRef 显式配置但无法解析,则解析会失败关闭(不会被远程回退掩盖)。 + - 共享密钥 Control UI 设置通过 `connect.params.auth.token` 或 `connect.params.auth.password` 进行认证(存储在应用/UI 设置中)。像 Tailscale Serve 或 `trusted-proxy` 这样的携带身份模式则使用请求头。避免把共享密钥放进 URL 中。 + - 使用 `gateway.auth.mode: "trusted-proxy"` 时,同主机上的 loopback 反向代理仍然**不能**满足 trusted-proxy 认证要求。trusted proxy 必须是一个已配置的非 loopback 来源。 - OpenClaw 默认强制执行 gateway auth,包括 loopback。在正常默认路径中,这意味着令牌认证:如果没有显式配置认证路径,gateway 启动时会解析为 token 模式并自动生成一个令牌,保存到 `gateway.auth.token`,因此**本地 WS 客户端也必须认证**。这可以阻止其他本地进程调用 Gateway 网关。 + OpenClaw 默认强制执行 gateway 认证,包括 loopback。在正常默认路径下,这意味着令牌认证:如果没有显式配置认证路径,gateway 启动时会解析为 token 模式并自动生成一个令牌,将其保存到 `gateway.auth.token` 中,因此**本地 WS 客户端也必须进行认证**。这样可以阻止其他本地进程调用 Gateway 网关。 - 如果你更喜欢其他认证路径,你可以显式选择密码模式(或者对于非 loopback 的身份感知反向代理,使用 `trusted-proxy`)。如果你**真的**想要开放的 loopback,请在配置中显式设置 `gateway.auth.mode: "none"`。Doctor 随时都可以为你生成令牌:`openclaw doctor --generate-gateway-token`。 + 如果你偏好其他认证路径,可以显式选择密码模式(或,对非 loopback 身份感知反向代理使用 `trusted-proxy`)。如果你**真的**想开放 loopback,请在配置中显式设置 `gateway.auth.mode: "none"`。Doctor 可以随时为你生成令牌:`openclaw doctor --generate-gateway-token`。 - Gateway 网关会监视配置并支持热重载: + Gateway 网关会监控配置并支持热重载: - - `gateway.reload.mode: "hybrid"`(默认):对安全变更热应用,对关键变更重启 + - `gateway.reload.mode: "hybrid"`(默认):安全改动热应用,关键改动则重启 - 也支持 `hot`、`restart`、`off` - + 在配置中设置 `cli.banner.taglineMode`: ```json5 @@ -1535,22 +1543,22 @@ x-i18n: ``` - `off`:隐藏标语文本,但保留横幅标题/版本行。 - - `default`:每次都使用 `All your chats, one OpenClaw.`。 - - `random`:轮换搞笑/季节性标语(默认行为)。 - - 如果你想完全隐藏横幅,请设置环境变量 `OPENCLAW_HIDE_BANNER=1`。 + - `default`:始终使用 `All your chats, one OpenClaw.`。 + - `random`:轮换有趣/季节性标语(默认行为)。 + - 如果你希望完全不显示横幅,请设置环境变量 `OPENCLAW_HIDE_BANNER=1`。 - - `web_fetch` 无需 API key 即可工作。`web_search` 取决于你选择的 - provider: + + `web_fetch` 无需 API 密钥即可使用。`web_search` 取决于你选择的 + 提供商: - - Brave、Exa、Firecrawl、Gemini、Grok、Kimi、MiniMax Search、Perplexity 和 Tavily 等基于 API 的提供商需要各自正常的 API key 设置。 - - Ollama Web 搜索不需要 key,但它会使用你配置的 Ollama host,并且需要 `ollama signin`。 - - DuckDuckGo 不需要 key,但它是一个非官方的基于 HTML 的集成。 - - SearXNG 不需要 key/可自托管;配置 `SEARXNG_BASE_URL` 或 `plugins.entries.searxng.config.webSearch.baseUrl`。 + - 基于 API 的提供商,如 Brave、Exa、Firecrawl、Gemini、Grok、Kimi、MiniMax Search、Perplexity 和 Tavily,需要按照正常方式配置 API 密钥。 + - Ollama Web 搜索 无需密钥,但它使用你配置的 Ollama 主机,并要求执行 `ollama signin`。 + - DuckDuckGo 无需密钥,但它是一个非官方的基于 HTML 的集成。 + - SearXNG 无需密钥/可自托管;请配置 `SEARXNG_BASE_URL` 或 `plugins.entries.searxng.config.webSearch.baseUrl`。 - **推荐:**运行 `openclaw configure --section web` 并选择一个 provider。 + **推荐:**运行 `openclaw configure --section web` 并选择一个提供商。 环境变量替代方式: - Brave:`BRAVE_API_KEY` @@ -1559,7 +1567,7 @@ x-i18n: - Gemini:`GEMINI_API_KEY` - Grok:`XAI_API_KEY` - Kimi:`KIMI_API_KEY` 或 `MOONSHOT_API_KEY` - - MiniMax Search:`MINIMAX_CODE_PLAN_KEY`, `MINIMAX_CODING_API_KEY`, 或 `MINIMAX_API_KEY` + - MiniMax Search:`MINIMAX_CODE_PLAN_KEY`、`MINIMAX_CODING_API_KEY` 或 `MINIMAX_API_KEY` - Perplexity:`PERPLEXITY_API_KEY` 或 `OPENROUTER_API_KEY` - SearXNG:`SEARXNG_BASE_URL` - Tavily:`TAVILY_API_KEY` @@ -1586,61 +1594,61 @@ x-i18n: }, fetch: { enabled: true, - provider: "firecrawl", // optional; omit for auto-detect + provider: "firecrawl", // 可选;省略则自动检测 }, }, }, } ``` - 提供商特定的 web-search 配置现在位于 `plugins.entries..config.webSearch.*` 下。 - 旧版 `tools.web.search.*` provider 路径仍会临时加载以保持兼容,但不应再用于新配置。 - Firecrawl web-fetch 回退配置位于 `plugins.entries.firecrawl.config.webFetch.*` 下。 + 提供商特定的 Web 搜索配置现在位于 `plugins.entries..config.webSearch.*` 下。 + 旧版 `tools.web.search.*` 提供商路径目前仍会为了兼容性而临时加载,但不应在新配置中继续使用。 + Firecrawl 的 web-fetch 回退配置位于 `plugins.entries.firecrawl.config.webFetch.*` 下。 说明: - - 如果你使用 allowlists,请添加 `web_search`/`web_fetch`/`x_search` 或 `group:web`。 - - `web_fetch` 默认启用(除非显式禁用)。 - - 如果省略 `tools.web.fetch.provider`,OpenClaw 会从可用凭据中自动检测第一个已准备好的抓取回退提供商。目前内置提供商是 Firecrawl。 + - 如果你使用允许列表,请添加 `web_search`/`web_fetch`/`x_search` 或 `group:web`。 + - `web_fetch` 默认启用(除非被显式禁用)。 + - 如果省略 `tools.web.fetch.provider`,OpenClaw 会从可用凭据中自动检测第一个已就绪的 fetch 回退提供商。目前内置提供商是 Firecrawl。 - 守护进程会从 `~/.openclaw/.env`(或服务环境)读取环境变量。 - 文档: [Web 工具](/zh-CN/tools/web)。 + 文档:[Web tools](/zh-CN/tools/web)。 - - `config.apply` 会替换**整个配置**。如果你发送的是部分对象,其余所有内容 + + `config.apply` 会替换**整个配置**。如果你发送的是部分对象,其他所有内容 都会被移除。 恢复方法: - - 从备份恢复(git 或复制过的 `~/.openclaw/openclaw.json`)。 - - 如果没有备份,重新运行 `openclaw doctor` 并重新配置渠道/模型。 - - 如果这不是你预期的行为,请提交 bug,并附上你最后已知的配置或任何备份。 - - 本地编码智能体通常可以根据日志或历史重建出可工作的配置。 + - 从备份恢复(git 或复制的 `~/.openclaw/openclaw.json`)。 + - 如果没有备份,请重新运行 `openclaw doctor` 并重新配置渠道/模型。 + - 如果这是意料之外的行为,请提交 bug,并附上你最后已知的配置或任何备份。 + - 本地编码智能体通常可以根据日志或历史重建一个可工作的配置。 - 避免方法: + 避免方式: - - 对小改动使用 `openclaw config set`。 - - 对交互式编辑使用 `openclaw configure`。 - - 当你不确定准确路径或字段形状时,先使用 `config.schema.lookup`;它会返回一个浅层 schema 节点以及直属子节点摘要,便于逐层钻取。 - - 对部分 RPC 编辑使用 `config.patch`;仅在需要完整替换配置时使用 `config.apply`。 - - 如果你是在智能体运行中使用仅限 owner 的 `gateway` 工具,它仍然会拒绝写入 `tools.exec.ask` / `tools.exec.security`(包括规范化到同一受保护 exec 路径的旧版 `tools.bash.*` 别名)。 + - 小改动使用 `openclaw config set`。 + - 交互式编辑使用 `openclaw configure`。 + - 当你不确定精确路径或字段结构时,先用 `config.schema.lookup`;它会返回一个浅层 schema 节点以及直接子项摘要,方便逐层钻取。 + - 对于部分 RPC 编辑,请使用 `config.patch`;仅在需要整体替换完整配置时才使用 `config.apply`。 + - 如果你是在智能体运行中使用仅所有者可用的 `gateway` 工具,它仍然会拒绝写入 `tools.exec.ask` / `tools.exec.security`(包括会被规范化到相同受保护 exec 路径的旧版 `tools.bash.*` 别名)。 - 文档: [Config](/cli/config), [Configure](/cli/configure), [Doctor](/zh-CN/gateway/doctor)。 + 文档:[Config](/cli/config)、[Configure](/cli/configure)、[Doctor](/zh-CN/gateway/doctor)。 - - 常见模式是**一个 Gateway 网关**(例如 Raspberry Pi)加上 **nodes** 和 **智能体**: + + 常见模式是**一个 Gateway 网关**(例如 Raspberry Pi)加上**节点**和**智能体**: - - **Gateway 网关(中心):**拥有渠道(Signal/WhatsApp)、路由和会话。 - - **Nodes(设备):**Mac/iOS/Android 作为外设连接,并暴露本地工具(`system.run`, `canvas`, `camera`)。 - - **智能体(工作者):**用于专门角色(例如“Hetzner 运维”、“个人数据”)的独立大脑/工作区。 - - **子智能体:**从主智能体中生成后台工作,以获得并行性。 + - **Gateway 网关(中央):**持有渠道(Signal/WhatsApp)、路由和会话。 + - **节点(设备):**Mac/iOS/Android 作为外设连接,并暴露本地工具(`system.run`、`canvas`、`camera`)。 + - **智能体(工作者):**不同职责的独立“大脑”/工作区(例如“Hetzner 运维”“个人数据”)。 + - **子智能体:**当你想并行处理时,从主智能体中派生后台工作。 - **TUI:**连接到 Gateway 网关并切换智能体/会话。 - 文档: [Nodes](/zh-CN/nodes), [远程访问](/zh-CN/gateway/remote), [多智能体路由](/zh-CN/concepts/multi-agent), [子智能体](/zh-CN/tools/subagents), [TUI](/web/tui)。 + 文档:[Nodes](/zh-CN/nodes)、[Remote access](/zh-CN/gateway/remote)、[Multi-Agent Routing](/zh-CN/concepts/multi-agent)、[Sub-agents](/zh-CN/tools/subagents)、[TUI](/web/tui)。 @@ -1658,18 +1666,18 @@ x-i18n: } ``` - 默认值是 `false`(有头模式)。无头模式更容易在某些网站上触发反机器人检查。参阅 [Browser](/zh-CN/tools/browser)。 + 默认值是 `false`(有头)。无头模式更容易触发某些网站的反机器人检查。参阅 [Browser](/zh-CN/tools/browser)。 - 无头模式使用**同一个 Chromium 引擎**,适用于大多数自动化(表单、点击、抓取、登录)。主要区别是: + 无头模式使用的是**相同的 Chromium 引擎**,适用于大多数自动化场景(表单、点击、抓取、登录)。主要区别是: - - 没有可见的浏览器窗口(如果需要视觉结果,请使用截图)。 - - 某些网站在无头模式下对自动化更严格(CAPTCHA、反机器人)。 - 例如,X/Twitter 经常会阻止无头会话。 + - 没有可见的浏览器窗口(如果需要视觉确认,请使用截图)。 + - 某些网站对无头模式下的自动化更严格(CAPTCHA、反机器人)。 + 例如,X/Twitter 通常会阻止无头会话。 - - 将 `browser.executablePath` 设置为你的 Brave 二进制(或任何基于 Chromium 的浏览器),然后重启 Gateway 网关。 + + 将 `browser.executablePath` 设置为你的 Brave 二进制文件(或任何基于 Chromium 的浏览器),然后重启 Gateway 网关。 完整配置示例请参阅 [Browser](/zh-CN/tools/browser#use-brave-or-another-chromium-based-browser)。 @@ -1679,26 +1687,26 @@ x-i18n: Telegram 消息由**gateway**处理。gateway 运行智能体, - 只有在需要 node 工具时才会通过 **Gateway WebSocket** + 只有在需要节点工具时才会通过**Gateway WebSocket** 调用节点: - Telegram → Gateway → 智能体 → `node.*` → 节点 → Gateway → Telegram + Telegram → Gateway → Agent → `node.*` → Node → Gateway → Telegram - 节点不会看到入站 provider 流量;它们只接收 node RPC 调用。 + 节点不会看到入站提供商流量;它们只接收节点 RPC 调用。 - - 简短回答:**把你的电脑配对为一个节点**。Gateway 网关运行在其他地方,但它可以 - 通过 Gateway WebSocket 在你的本地机器上调用 `node.*` 工具(screen、camera、system)。 + + 简短回答:**把你的电脑配对成一个节点**。Gateway 网关运行在别处,但它可以 + 通过 Gateway WebSocket 在你的本地机器上调用 `node.*` 工具(屏幕、摄像头、系统)。 典型设置: - 1. 在常开主机上运行 Gateway 网关(VPS/家庭服务器)。 - 2. 将 Gateway 网关主机和你的电脑接入同一个 tailnet。 - 3. 确保 Gateway WS 可访问(tailnet bind 或 SSH 隧道)。 - 4. 在本地打开 macOS 应用,并使用**通过 SSH 远程连接**模式(或直接 tailnet) - 进行连接,以便它注册为一个节点。 + 1. 在始终在线的主机(VPS/家庭服务器)上运行 Gateway 网关。 + 2. 让 Gateway 主机和你的电脑加入同一个 tailnet。 + 3. 确保 Gateway WS 可达(tailnet 绑定或 SSH 隧道)。 + 4. 在本地打开 macOS 应用,并以**Remote over SSH** 模式(或直接 tailnet) + 连接,使其可以注册为一个节点。 5. 在 Gateway 网关上批准该节点: ```bash @@ -1706,107 +1714,107 @@ x-i18n: openclaw devices approve ``` - 不需要单独的 TCP bridge;节点通过 Gateway WebSocket 连接。 + 不需要单独的 TCP bridge;节点通过 Gateway WebSocket 进行连接。 - 安全提醒:配对 macOS 节点允许在该机器上执行 `system.run`。只 - 配对你信任的设备,并查看 [Security](/zh-CN/gateway/security)。 + 安全提醒:配对一个 macOS 节点意味着该机器上允许 `system.run`。 + 只配对你信任的设备,并阅读 [Security](/zh-CN/gateway/security)。 - 文档: [Nodes](/zh-CN/nodes), [Gateway protocol](/zh-CN/gateway/protocol), [macOS remote mode](/zh-CN/platforms/mac/remote), [Security](/zh-CN/gateway/security)。 + 文档:[Nodes](/zh-CN/nodes)、[Gateway protocol](/zh-CN/gateway/protocol)、[macOS remote mode](/zh-CN/platforms/mac/remote)、[Security](/zh-CN/gateway/security)。 - + 先检查基础项: - - Gateway 网关正在运行:`openclaw gateway status` - - Gateway 网关健康:`openclaw status` - - 渠道健康:`openclaw channels status` + - Gateway 网关是否正在运行:`openclaw gateway status` + - Gateway 网关健康状况:`openclaw status` + - 渠道健康状况:`openclaw channels status` 然后验证认证和路由: - - 如果你使用 Tailscale Serve,请确认 `gateway.auth.allowTailscale` 设置正确。 - - 如果你通过 SSH 隧道连接,请确认本地隧道已启动并指向正确端口。 + - 如果你使用 Tailscale Serve,确保 `gateway.auth.allowTailscale` 设置正确。 + - 如果你通过 SSH 隧道连接,请确认本地隧道已建立并指向正确端口。 - 确认你的允许列表(私信或群组)包含你的账号。 - 文档: [Tailscale](/zh-CN/gateway/tailscale), [远程访问](/zh-CN/gateway/remote), [Channels](/zh-CN/channels)。 + 文档:[Tailscale](/zh-CN/gateway/tailscale)、[Remote access](/zh-CN/gateway/remote)、[Channels](/zh-CN/channels)。 - - 可以。虽然没有内置的“机器人到机器人”桥接,但你可以通过几种 - 可靠方式来实现: + + 可以。没有内置的“机器人对机器人”桥接,但你可以通过几种 + 可靠方式实现: - **最简单:**使用两个机器人都能访问的普通聊天渠道(Telegram/Slack/WhatsApp)。 - 让机器人 A 向机器人 B 发送消息,然后让机器人 B 像平常一样回复。 + **最简单的方式:**使用两个机器人都能访问的普通聊天渠道(Telegram/Slack/WhatsApp)。 + 让 Bot A 给 Bot B 发消息,然后让 Bot B 正常回复。 - **CLI bridge(通用):**运行一个脚本,通过 - `openclaw agent --message ... --deliver` 调用另一个 Gateway 网关,目标指向另一个机器人 + **CLI 桥接(通用):**运行一个脚本,调用另一个 Gateway 网关的 + `openclaw agent --message ... --deliver`,目标是另一个机器人 正在监听的聊天。如果其中一个机器人在远程 VPS 上,请让你的 CLI 指向那个远程 Gateway 网关, - 通过 SSH/Tailscale 访问(见 [远程访问](/zh-CN/gateway/remote))。 + 可通过 SSH/Tailscale(见 [Remote access](/zh-CN/gateway/remote))实现。 - 示例模式(在能访问目标 Gateway 网关的机器上运行): + 示例模式(从一台能访问目标 Gateway 网关的机器上运行): ```bash openclaw agent --message "Hello from local bot" --deliver --channel telegram --reply-to ``` - 提示:加上一个保护措施,避免两个机器人无限循环(仅提及时回复、渠道 - allowlists,或加一条“不要回复机器人消息”的规则)。 + 提示:添加一个保护措施,防止两个机器人无限循环(仅回应提及、渠道 + 允许列表,或“不要回复机器人消息”的规则)。 - 文档: [远程访问](/zh-CN/gateway/remote), [Agent CLI](/cli/agent), [智能体发送](/zh-CN/tools/agent-send)。 + 文档:[Remote access](/zh-CN/gateway/remote)、[Agent CLI](/cli/agent)、[Agent send](/zh-CN/tools/agent-send)。 - - 不需要。一个 Gateway 网关可以承载多个智能体,每个都有自己的工作区、模型默认值 - 和路由。这是正常设置,也比为每个智能体运行 - 一个 VPS 更便宜、更简单。 + + 不需要。一个 Gateway 网关可以托管多个智能体,每个智能体都有自己的工作区、默认模型 + 和路由。这是正常设置,也比 + 每个智能体一个 VPS 便宜且简单得多。 - 只有在你需要硬隔离(安全边界)或非常 - 不同且不想共享的配置时,才使用不同 VPS。否则,请保留一个 Gateway 网关,并 - 使用多个智能体或子智能体。 + 只有在你需要硬隔离(安全边界)或非常不同、你不想共享的配置时, + 才需要分别使用不同的 VPS。否则,保持一个 Gateway 网关, + 并使用多个智能体或子智能体即可。 - - 有——节点是从远程 Gateway 网关访问你笔记本的首选方式,而且 - 它们提供的不仅仅是 shell 访问。Gateway 网关可运行在 macOS/Linux 上(Windows 通过 WSL2),而且 - 很轻量(小型 VPS 或 Raspberry Pi 级别的机器就够;4 GB RAM 绰绰有余),所以常见 - 设置是一个始终在线的主机,再加上你的笔记本作为节点。 + + 有——节点是从远程 Gateway 网关访问你笔记本的首选方式,而且它们 + 不只是提供 shell 访问。Gateway 网关运行在 macOS/Linux(Windows 通过 WSL2)上,并且 + 非常轻量(小型 VPS 或 Raspberry Pi 级别机器就足够;4 GB RAM 已很充足),所以一种常见 + 设置是始终在线的主机 + 你的笔记本作为节点。 - - **无需入站 SSH。**节点主动连接到 Gateway WebSocket,并使用设备配对。 - - **更安全的执行控制。**`system.run` 受该笔记本上的节点允许列表/审批保护。 - - **更多设备工具。**节点除了 `system.run` 之外,还暴露 `canvas`、`camera` 和 `screen`。 - - **本地浏览器自动化。**将 Gateway 网关放在 VPS 上,但通过笔记本上的 node host 在本地运行 Chrome,或通过 Chrome MCP 附着到主机上的本地 Chrome。 + - **不需要入站 SSH。**节点主动连接到 Gateway WebSocket,并使用设备配对。 + - **更安全的执行控制。**`system.run` 在那台笔记本上会受到节点允许列表/审批控制。 + - **更多设备工具。**节点除 `system.run` 外,还暴露 `canvas`、`camera` 和 `screen`。 + - **本地浏览器自动化。**将 Gateway 网关放在 VPS 上,但通过笔记本上的节点主机在本地运行 Chrome,或通过 Chrome MCP 连接到主机上的本地 Chrome。 - 对于临时 shell 访问,SSH 完全可以;但对于持续性的智能体工作流和 - 设备自动化,节点更简单。 + SSH 适合临时 shell 访问,但节点对于持续性的智能体工作流和 + 设备自动化更简单。 - 文档: [Nodes](/zh-CN/nodes), [Nodes CLI](/cli/nodes), [Browser](/zh-CN/tools/browser)。 + 文档:[Nodes](/zh-CN/nodes)、[Nodes CLI](/cli/nodes)、[Browser](/zh-CN/tools/browser)。 - - 不会。每台主机通常只应运行**一个 gateway**,除非你有意运行隔离配置文件(参见 [多个 Gateway 网关](/zh-CN/gateway/multiple-gateways))。节点是连接到 - gateway 的外设(iOS/Android 节点,或菜单栏应用中的 macOS “node mode”)。有关无头 node - host 和 CLI 控制,请参阅 [Node host CLI](/cli/node)。 + + 不会。除非你是有意运行隔离配置文件(见 [Multiple gateways](/zh-CN/gateway/multiple-gateways)),否则每台主机只应运行**一个 gateway**。节点是连接到 + gateway 的外设(iOS/Android 节点,或菜单栏应用中的 macOS “node mode”)。关于无头节点 + 主机和 CLI 控制,请参阅 [Node host CLI](/cli/node)。 对 `gateway`、`discovery` 和 `canvasHost` 的更改需要完整重启。 - + 有。 - - `config.schema.lookup`:在写入前检查一个配置子树,包括其浅层 schema 节点、匹配的 UI 提示和直属子节点摘要 - - `config.get`:获取当前快照 + hash - - `config.patch`:安全的部分更新(大多数 RPC 编辑推荐使用) - - `config.apply`:验证 + 替换完整配置,然后重启 - - 仅限 owner 的 `gateway` 运行时工具仍然拒绝重写 `tools.exec.ask` / `tools.exec.security`;旧版 `tools.bash.*` 别名会规范化到同样受保护的 exec 路径 + - `config.schema.lookup`:在写入前检查一个配置子树,包括其浅层 schema 节点、匹配的 UI 提示和直接子项摘要 + - `config.get`:获取当前快照 + 哈希 + - `config.patch`:安全的局部更新(大多数 RPC 编辑的首选) + - `config.apply`:校验 + 替换完整配置,然后重启 + - 仅所有者可用的 `gateway` 运行时工具仍然拒绝重写 `tools.exec.ask` / `tools.exec.security`;旧版 `tools.bash.*` 别名会规范化到相同的受保护 exec 路径 - + ```json5 { agents: { defaults: { workspace: "~/.openclaw/workspace" } }, @@ -1818,31 +1826,31 @@ x-i18n: - + 最小步骤: - 1. **在 VPS 上安装 + 登录** + 1. **在 VPS 上安装并登录** ```bash curl -fsSL https://tailscale.com/install.sh | sh sudo tailscale up ``` - 2. **在你的 Mac 上安装 + 登录** - - 使用 Tailscale 应用并登录到同一个 tailnet。 + 2. **在你的 Mac 上安装并登录** + - 使用 Tailscale 应用,并登录到同一个 tailnet。 3. **启用 MagicDNS(推荐)** - - 在 Tailscale 管理控制台中启用 MagicDNS,这样 VPS 就会有一个稳定名称。 + - 在 Tailscale 管理控制台中启用 MagicDNS,这样 VPS 就有了稳定名称。 4. **使用 tailnet 主机名** - SSH:`ssh user@your-vps.tailnet-xxxx.ts.net` - Gateway WS:`ws://your-vps.tailnet-xxxx.ts.net:18789` - 如果你想在不使用 SSH 的情况下访问 Control UI,请在 VPS 上使用 Tailscale Serve: + 如果你希望无需 SSH 也能使用 Control UI,请在 VPS 上使用 Tailscale Serve: ```bash openclaw gateway --tailscale serve ``` - 这会让 gateway 保持绑定到 loopback,并通过 Tailscale 暴露 HTTPS。参阅 [Tailscale](/zh-CN/gateway/tailscale)。 + 这样会让 gateway 保持绑定 loopback,并通过 Tailscale 暴露 HTTPS。参阅 [Tailscale](/zh-CN/gateway/tailscale)。 @@ -1851,28 +1859,29 @@ x-i18n: 推荐设置: - 1. **确保 VPS 和 Mac 位于同一个 tailnet 上**。 - 2. **在远程模式下使用 macOS 应用**(SSH 目标可以是 tailnet 主机名)。 - 应用会对 Gateway 端口建立隧道并作为节点连接。 - 3. **在 gateway 上批准节点**: + 1. **确保 VPS 和 Mac 在同一个 tailnet 中**。 + 2. **在 Remote 模式下使用 macOS 应用**(SSH 目标可以是 tailnet 主机名)。 + 应用会将 Gateway 端口建立隧道,并作为一个节点连接。 + 3. **在 gateway 上批准该节点**: ```bash openclaw devices list openclaw devices approve ``` - 文档: [Gateway protocol](/zh-CN/gateway/protocol), [设备发现](/zh-CN/gateway/discovery), [macOS remote mode](/zh-CN/platforms/mac/remote)。 + 文档:[Gateway protocol](/zh-CN/gateway/protocol)、[Discovery](/zh-CN/gateway/discovery)、[macOS remote mode](/zh-CN/platforms/mac/remote)。 - 如果你只需要第二台笔记本上的**本地工具**(screen/camera/exec),就把它添加为 - **node**。这样可以保持单一 Gateway 网关,避免重复配置。当前本地节点工具 + 如果你只需要第二台笔记本上的**本地工具**(屏幕/摄像头/exec),就把它添加为 + **节点**。这样可以保持单个 Gateway 网关,并避免重复配置。当前本地节点工具 仅支持 macOS,但我们计划扩展到其他操作系统。 - 只有在你需要**硬隔离**或两个完全独立的机器人时,才安装第二个 Gateway 网关。 + 只有在你需要**硬隔离**或两个完全独立的机器人时, + 才应该安装第二个 Gateway 网关。 - 文档: [Nodes](/zh-CN/nodes), [Nodes CLI](/cli/nodes), [多个 Gateway 网关](/zh-CN/gateway/multiple-gateways)。 + 文档:[Nodes](/zh-CN/nodes)、[Nodes CLI](/cli/nodes)、[Multiple gateways](/zh-CN/gateway/multiple-gateways)。 @@ -1884,11 +1893,11 @@ x-i18n: OpenClaw 会从父进程(shell、launchd/systemd、CI 等)读取环境变量,并额外加载: - 当前工作目录中的 `.env` - - `~/.openclaw/.env`(即 `$OPENCLAW_STATE_DIR/.env`)中的全局回退 `.env` + - 来自 `~/.openclaw/.env`(即 `$OPENCLAW_STATE_DIR/.env`)的全局回退 `.env` 这两个 `.env` 文件都不会覆盖现有环境变量。 - 你也可以在配置中定义内联环境变量(仅在进程环境中缺失时生效): + 你还可以在配置中定义内联环境变量(仅在进程环境中缺失时应用): ```json5 { @@ -1899,14 +1908,14 @@ x-i18n: } ``` - 有关完整优先级和来源,请参阅 [/environment](/zh-CN/help/environment)。 + 关于完整优先级和来源,请参阅 [/environment](/zh-CN/help/environment)。 - + 两个常见修复方式: - 1. 把缺失的 key 放到 `~/.openclaw/.env` 中,这样即使服务没有继承你的 shell 环境也会被读取。 + 1. 将缺失的密钥放入 `~/.openclaw/.env`,这样即使服务没有继承你的 shell 环境,它们也会被读取。 2. 启用 shell 导入(可选的便捷功能): ```json5 @@ -1920,27 +1929,27 @@ x-i18n: } ``` - 这会运行你的登录 shell,并且只导入缺失的预期键名(绝不覆盖)。对应环境变量: - `OPENCLAW_LOAD_SHELL_ENV=1`, `OPENCLAW_SHELL_ENV_TIMEOUT_MS=15000`。 + 这会运行你的登录 shell,并且只导入缺失的预期键名(绝不覆盖已有值)。环境变量等价项: + `OPENCLAW_LOAD_SHELL_ENV=1`、`OPENCLAW_SHELL_ENV_TIMEOUT_MS=15000`。 - - `openclaw models status` 报告的是**shell 环境导入**是否已启用。“Shell env: off” - **不**表示你的环境变量缺失——它只是表示 OpenClaw 不会自动加载 - 你的登录 shell。 + + `openclaw models status` 显示的是是否启用了**shell 环境导入**。“Shell env: off” + **不**意味着你的环境变量缺失——它只是表示 OpenClaw 不会 + 自动加载你的登录 shell。 如果 Gateway 网关作为服务运行(launchd/systemd),它不会继承你的 shell - 环境。可以这样修复: + 环境。解决方式如下: - 1. 将令牌放到 `~/.openclaw/.env` 中: + 1. 把令牌放到 `~/.openclaw/.env` 中: ``` COPILOT_GITHUB_TOKEN=... ``` 2. 或启用 shell 导入(`env.shellEnv.enabled: true`)。 - 3. 或将其添加到你的配置 `env` 块中(仅在缺失时应用)。 + 3. 或将它添加到配置中的 `env` 块里(仅在缺失时应用)。 然后重启 gateway 并重新检查: @@ -1948,24 +1957,24 @@ x-i18n: openclaw models status ``` - Copilot 令牌会从 `COPILOT_GITHUB_TOKEN` 读取(也支持 `GH_TOKEN` / `GITHUB_TOKEN`)。 + Copilot 令牌从 `COPILOT_GITHUB_TOKEN` 读取(也支持 `GH_TOKEN` / `GITHUB_TOKEN`)。 参阅 [/concepts/model-providers](/zh-CN/concepts/model-providers) 和 [/environment](/zh-CN/help/environment)。 -## 会话和多个聊天 +## 会话和多聊天 - - 将 `/new` 或 `/reset` 作为独立消息发送。参阅 [会话管理](/zh-CN/concepts/session)。 + + 发送 `/new` 或 `/reset` 作为独立消息。参阅 [Session management](/zh-CN/concepts/session)。 会话可以在 `session.idleMinutes` 后过期,但这**默认是禁用的**(默认值为 **0**)。 - 将其设置为正值即可启用空闲过期。启用后,在空闲期之后的**下一条** + 将其设置为正值即可启用空闲过期。启用后,在空闲期之后收到的**下一条** 消息会为该聊天键启动一个新的会话 ID。 - 这不会删除记录——只是开始一个新会话。 + 这不会删除对话记录——它只会开启一个新会话。 ```json5 { @@ -1977,41 +1986,41 @@ x-i18n: - + 可以,通过**多智能体路由**和**子智能体**实现。你可以创建一个协调者 - 智能体和若干个拥有各自工作区和模型的工作智能体。 + 智能体,以及多个拥有各自工作区和模型的工作智能体。 - 不过,最好把这看作一个**有趣的实验**。它会消耗大量令牌,而且通常 - 不如使用一个机器人配合多个会话高效。我们更典型的设想是一个你与之交互的机器人, - 使用不同会话来并行处理工作。必要时,这个 - 机器人也可以生成子智能体。 + 不过,这更适合作为一个**有趣的实验**。它很耗 token,而且通常 + 不如一个机器人配多个会话高效。我们通常设想的模式是:一个你与之对话的机器人, + 通过不同会话处理并行工作。这个机器人 + 也可以在需要时启动子智能体。 - 文档: [多智能体路由](/zh-CN/concepts/multi-agent), [子智能体](/zh-CN/tools/subagents), [Agents CLI](/cli/agents)。 + 文档:[Multi-agent routing](/zh-CN/concepts/multi-agent)、[Sub-agents](/zh-CN/tools/subagents)、[Agents CLI](/cli/agents)。 - + 会话上下文受模型窗口限制。长聊天、大量工具输出或许多 文件都可能触发压缩或截断。 有帮助的做法: - 让机器人总结当前状态并将其写入文件。 - - 在长任务前使用 `/compact`,切换话题时使用 `/new`。 - - 将重要上下文保存在工作区中,并让机器人重新读取。 - - 对长时间或并行工作使用子智能体,这样主聊天能保持更小。 - - 如果这种情况经常发生,请选择上下文窗口更大的模型。 + - 在长任务前使用 `/compact`,切换主题时使用 `/new`。 + - 将重要上下文保存在工作区,并让机器人重新读取。 + - 对长任务或并行工作使用子智能体,这样主聊天会更小。 + - 如果这种情况经常出现,请选择上下文窗口更大的模型。 - + 使用 reset 命令: ```bash openclaw reset ``` - 非交互式完全重置: + 非交互式完整重置: ```bash openclaw reset --scope full --yes --non-interactive @@ -2025,14 +2034,14 @@ x-i18n: 说明: - - 如果新手引导检测到现有配置,也会提供**重置**选项。参阅 [新手引导(CLI)](/zh-CN/start/wizard)。 - - 如果你使用了配置文件(`--profile` / `OPENCLAW_PROFILE`),请重置每个状态目录(默认是 `~/.openclaw-`)。 - - 开发重置:`openclaw gateway --dev --reset`(仅开发模式;会清空开发配置 + 凭据 + 会话 + 工作区)。 + - 如果新手引导检测到已有配置,也会提供**重置**选项。参阅 [Onboarding(CLI)](/zh-CN/start/wizard)。 + - 如果你使用了 profile(`--profile` / `OPENCLAW_PROFILE`),请分别重置每个状态目录(默认是 `~/.openclaw-`)。 + - 开发重置:`openclaw gateway --dev --reset`(仅开发环境;会清空开发配置 + 凭据 + 会话 + 工作区)。 - - 使用以下任一方式: + + 使用以下方式之一: - **压缩**(保留对话,但总结较早轮次): @@ -2040,61 +2049,61 @@ x-i18n: /compact ``` - 或使用 `/compact ` 来指导摘要内容。 + 或使用 `/compact ` 来引导摘要方式。 - - **重置**(为同一个聊天键生成新的会话 ID): + - **重置**(为同一个聊天键创建新的会话 ID): ``` /new /reset ``` - 如果问题持续发生: + 如果这种情况持续发生: - - 启用或调整**会话裁剪**(`agents.defaults.contextPruning`)以裁减旧工具输出。 + - 启用或调整**会话修剪**(`agents.defaults.contextPruning`)以裁剪旧工具输出。 - 使用上下文窗口更大的模型。 - 文档: [压缩](/zh-CN/concepts/compaction), [会话裁剪](/zh-CN/concepts/session-pruning), [会话管理](/zh-CN/concepts/session)。 + 文档:[Compaction](/zh-CN/concepts/compaction)、[Session pruning](/zh-CN/concepts/session-pruning)、[Session management](/zh-CN/concepts/session)。 - - 这是 provider 验证错误:模型发出了一个缺少必需 - `input` 的 `tool_use` 块。通常表示会话历史陈旧或损坏(常见于长线程 + + 这是提供商的校验错误:模型发出了一个缺少必需 + `input` 的 `tool_use` 块。通常意味着会话历史陈旧或已损坏(常见于长线程 或工具/schema 变更之后)。 - 修复方法:使用 `/new`(独立消息)开始一个全新的会话。 + 解决方法:发送 `/new` 作为独立消息,开始一个新会话。 - Heartbeat 默认每 **30m** 运行一次(使用 OAuth auth 时为 **1h**)。可进行调整或禁用: + Heartbeat 默认每 **30m** 运行一次(使用 OAuth 认证时为 **1h**)。可以调整或禁用它: ```json5 { agents: { defaults: { heartbeat: { - every: "2h", // or "0m" to disable + every: "2h", // 或 "0m" 来禁用 }, }, }, } ``` - 如果 `HEARTBEAT.md` 存在但实际上是空的(只有空行和 Markdown + 如果 `HEARTBEAT.md` 存在但实际上为空(仅有空行和 markdown 标题如 `# Heading`),OpenClaw 会跳过 heartbeat 运行以节省 API 调用。 - 如果该文件不存在,heartbeat 仍会运行,并由模型决定该做什么。 + 如果文件不存在,heartbeat 仍会运行,并由模型决定要做什么。 - 每个智能体的覆盖配置使用 `agents.list[].heartbeat`。文档: [Heartbeat](/zh-CN/gateway/heartbeat)。 + 每智能体覆盖使用 `agents.list[].heartbeat`。文档:[Heartbeat](/zh-CN/gateway/heartbeat)。 - - 不需要。OpenClaw 运行在**你自己的账号**上,所以只要你在群里,OpenClaw 就能看到它。 - 默认情况下,在你允许发送者之前,群组回复会被阻止(`groupPolicy: "allowlist"`)。 + + 不需要。OpenClaw 运行在**你自己的账号**上,所以如果你在群组里,OpenClaw 就能看到它。 + 默认情况下,群组回复会被阻止,直到你允许发送者(`groupPolicy: "allowlist"`)。 - 如果你只想让**你自己**能触发群组回复: + 如果你只希望**你自己**能够触发群组回复: ```json5 { @@ -2110,7 +2119,7 @@ x-i18n: - 方式 1(最快):查看日志尾部,然后在群组中发送一条测试消息: + 选项 1(最快):跟踪日志,并在群组中发送一条测试消息: ```bash openclaw logs --follow --json @@ -2119,62 +2128,62 @@ x-i18n: 查找以 `@g.us` 结尾的 `chatId`(或 `from`),例如: `1234567890-1234567890@g.us`。 - 方式 2(如果已经配置/加入允许列表):从配置中列出群组: + 选项 2(如果已配置/加入允许列表):从配置中列出群组: ```bash openclaw directory groups list --channel whatsapp ``` - 文档: [WhatsApp](/zh-CN/channels/whatsapp), [Directory](/cli/directory), [Logs](/cli/logs)。 + 文档:[WhatsApp](/zh-CN/channels/whatsapp)、[Directory](/cli/directory)、[Logs](/cli/logs)。 两个常见原因: - - 提及门控已开启(默认)。你必须 @提及机器人(或匹配 `mentionPatterns`)。 - - 你配置了 `channels.whatsapp.groups` 但没有包含 `"*"`,而该群组并未加入允许列表。 + - 提及门控已开启(默认)。你必须 @ 提及机器人(或匹配 `mentionPatterns`)。 + - 你配置了 `channels.whatsapp.groups` 但没有包含 `"*"`,并且该群组不在允许列表中。 - 参阅 [Groups](/zh-CN/channels/groups) 和 [群组消息](/zh-CN/channels/group-messages)。 + 参阅 [Groups](/zh-CN/channels/groups) 和 [Group messages](/zh-CN/channels/group-messages)。 - - 直接聊天默认会收敛到主会话。群组/渠道拥有各自的会话键,Telegram 话题 / Discord 线程也是独立会话。参阅 [Groups](/zh-CN/channels/groups) 和 [群组消息](/zh-CN/channels/group-messages)。 + + 直接聊天默认会归并到主会话。群组/渠道有各自的会话键,而 Telegram 话题 / Discord 线程则是独立会话。参阅 [Groups](/zh-CN/channels/groups) 和 [Group messages](/zh-CN/channels/group-messages)。 - 没有硬性限制。几十个(甚至上百个)都没问题,但请注意: + 没有硬性上限。几十个(甚至几百个)都没问题,但请注意: - - **磁盘增长:**会话 + 转录内容位于 `~/.openclaw/agents//sessions/` 下。 - - **令牌成本:**更多智能体意味着更多并发模型使用。 - - **运维开销:**每个智能体的认证配置文件、工作区和渠道路由。 + - **磁盘增长:**会话 + 转录存放在 `~/.openclaw/agents//sessions/` 下。 + - **Token 成本:**智能体越多,模型并发使用越多。 + - **运维开销:**每智能体的认证档案、工作区和渠道路由。 提示: - - 每个智能体保持一个**活动**工作区(`agents.defaults.workspace`)。 - - 如果磁盘增长,请清理旧会话(删除 JSONL 或存储条目)。 - - 使用 `openclaw doctor` 发现杂散工作区和配置文件不匹配。 + - 每个智能体保持一个**活跃**工作区(`agents.defaults.workspace`)。 + - 如果磁盘增长,请修剪旧会话(删除 JSONL 或 store 条目)。 + - 使用 `openclaw doctor` 发现零散工作区和档案不匹配问题。 - - 可以。使用**多智能体路由**运行多个隔离智能体,并按 - 渠道/账号/peer 路由入站消息。Slack 作为渠道受支持,并可绑定到特定智能体。 + + 可以。使用**多智能体路由**来运行多个隔离的智能体,并按 + 渠道/账号/peer 路由入站消息。Slack 作为一个渠道受到支持,并且可以绑定到特定智能体。 - 浏览器访问很强大,但并不是“人类能做的都能做”——反机器人、CAPTCHA 和 MFA - 仍然可能阻止自动化。要获得最可靠的浏览器控制,请在主机上使用本地 Chrome MCP, + 浏览器访问能力很强,但并不等于“做人类能做的一切”——反机器人机制、CAPTCHA 和 MFA + 仍然可能阻止自动化。若要实现最可靠的浏览器控制,请使用主机上的本地 Chrome MCP, 或在实际运行浏览器的机器上使用 CDP。 最佳实践设置: - 始终在线的 Gateway 网关主机(VPS/Mac mini)。 - 每个角色一个智能体(bindings)。 - - Slack 渠道绑定到这些智能体。 - - 需要时通过 Chrome MCP 或节点访问本地浏览器。 + - 将 Slack 渠道绑定到这些智能体。 + - 需要时通过 Chrome MCP 或节点使用本地浏览器。 - 文档: [多智能体路由](/zh-CN/concepts/multi-agent), [Slack](/zh-CN/channels/slack), - [Browser](/zh-CN/tools/browser), [Nodes](/zh-CN/nodes)。 + 文档:[Multi-Agent Routing](/zh-CN/concepts/multi-agent)、[Slack](/zh-CN/channels/slack)、 + [Browser](/zh-CN/tools/browser)、[Nodes](/zh-CN/nodes)。 @@ -2189,32 +2198,32 @@ x-i18n: agents.defaults.model.primary ``` - 模型以 `provider/model` 的形式引用(例如:`openai/gpt-5.4`)。如果你省略 provider,OpenClaw 会先尝试别名,然后匹配一个已配置 provider 中对该精确模型 ID 的唯一匹配,只有之后才会退回到已配置默认 provider 这一已弃用的兼容路径。如果该 provider 不再暴露已配置的默认模型,OpenClaw 会退回到第一个已配置 provider/model,而不是继续暴露陈旧的已移除 provider 默认值。你仍然应该**显式**设置 `provider/model`。 + 模型以 `provider/model` 的形式引用(例如:`openai/gpt-5.4`)。如果你省略提供商,OpenClaw 会先尝试别名,然后尝试与该精确模型 ID 唯一匹配的已配置提供商,最后才会退回到已配置默认提供商这一已弃用的兼容路径。如果该提供商已不再暴露已配置的默认模型,OpenClaw 会退回到第一个已配置的提供商/模型,而不是暴露一个陈旧的、已被移除的提供商默认值。你仍然应该**显式**设置 `provider/model`。 - **推荐默认:**使用你提供商栈中最新一代、能力最强的模型。 - **对于启用了工具或处理不可信输入的智能体:**优先考虑模型能力而不是成本。 - **对于日常/低风险聊天:**使用更便宜的回退模型,并按智能体角色路由。 + **推荐默认选择:**使用你提供商栈中可用的最新一代最强模型。 + **对于启用了工具或要处理不可信输入的智能体:**优先考虑模型能力,而不是成本。 + **对于日常/低风险聊天:**使用更便宜的后备模型,并按智能体角色进行路由。 - MiniMax 有自己的文档: [MiniMax](/zh-CN/providers/minimax) 和 - [本地模型](/zh-CN/gateway/local-models)。 + MiniMax 有自己的文档:[MiniMax](/zh-CN/providers/minimax) 和 + [Local models](/zh-CN/gateway/local-models)。 - 经验法则:对高风险工作,使用你能负担得起的**最佳模型**;对日常 - 聊天或摘要,使用更便宜的模型。你可以按智能体路由模型,并使用子智能体来 - 并行处理长任务(每个子智能体都会消耗令牌)。参阅 [Models](/zh-CN/concepts/models) 和 - [子智能体](/zh-CN/tools/subagents)。 + 经验法则:对于高风险任务,使用**你能负担得起的最佳模型**;对于日常 + 聊天或总结,则使用更便宜的模型。你可以为每个智能体路由模型,并使用子智能体来 + 并行处理长任务(每个子智能体都会消耗 token)。参阅 [Models](/zh-CN/concepts/models) 和 + [Sub-agents](/zh-CN/tools/subagents)。 - 强烈警告:更弱/过度量化的模型更容易受到提示 - 注入和不安全行为影响。参阅 [Security](/zh-CN/gateway/security)。 + 强烈警告:较弱/过度量化的模型更容易受到提示 + 注入和不安全行为的影响。参阅 [Security](/zh-CN/gateway/security)。 - 更多背景: [Models](/zh-CN/concepts/models)。 + 更多背景:[Models](/zh-CN/concepts/models)。 - 使用**模型命令**,或只编辑**模型**字段。避免完整替换配置。 + 使用**模型命令**,或只编辑**模型**字段。避免整体替换配置。 安全选项: @@ -2223,46 +2232,46 @@ x-i18n: - `openclaw configure --section model`(交互式) - 编辑 `~/.openclaw/openclaw.json` 中的 `agents.defaults.model` - 除非你就是想替换整个配置,否则请避免用部分对象调用 `config.apply`。 - 对于 RPC 编辑,先用 `config.schema.lookup` 检查,再优先使用 `config.patch`。lookup 负载会提供规范化路径、浅层 schema 文档/约束,以及直属子节点摘要, - 以便进行部分更新。 - 如果你真的覆盖了配置,请从备份恢复,或重新运行 `openclaw doctor` 进行修复。 + 除非你确实打算替换整个配置,否则不要用部分对象调用 `config.apply`。 + 对于 RPC 编辑,请先用 `config.schema.lookup` 检查,并优先使用 `config.patch`。lookup 负载会提供规范化路径、浅层 schema 文档/约束以及直接子项摘要, + 适合做局部更新。 + 如果你已经覆盖了配置,请从备份恢复,或重新运行 `openclaw doctor` 进行修复。 - 文档: [Models](/zh-CN/concepts/models), [Configure](/cli/configure), [Config](/cli/config), [Doctor](/zh-CN/gateway/doctor)。 + 文档:[Models](/zh-CN/concepts/models)、[Configure](/cli/configure)、[Config](/cli/config)、[Doctor](/zh-CN/gateway/doctor)。 - 可以。对于本地模型,最简单的路径是 Ollama。 + 可以。对于本地模型,Ollama 是最简单的方案。 - 最快设置: + 最快捷的设置: 1. 从 `https://ollama.com/download` 安装 Ollama 2. 拉取一个本地模型,例如 `ollama pull glm-4.7-flash` - 3. 如果你还想用云模型,运行 `ollama signin` + 3. 如果你还想使用云模型,运行 `ollama signin` 4. 运行 `openclaw onboard` 并选择 `Ollama` 5. 选择 `Local` 或 `Cloud + Local` 说明: - - `Cloud + Local` 会提供云模型和你的本地 Ollama 模型 + - `Cloud + Local` 会同时给你云模型和本地 Ollama 模型 - 像 `kimi-k2.5:cloud` 这样的云模型不需要本地 pull - - 若要手动切换,请使用 `openclaw models list` 和 `openclaw models set ollama/` + - 如需手动切换,请使用 `openclaw models list` 和 `openclaw models set ollama/` - 安全说明:更小或高度量化的模型更容易受到提示 - 注入影响。对于任何可以使用工具的机器人,我们强烈推荐**大模型**。 - 如果你仍想使用小模型,请启用沙箱隔离和严格的工具允许列表。 + 安全说明:更小或量化程度很高的模型更容易受到提示 + 注入影响。对于任何可使用工具的机器人,我们都强烈建议使用**大模型**。 + 如果你仍然想使用小模型,请启用沙箱隔离和严格的工具允许列表。 - 文档: [Ollama](/zh-CN/providers/ollama), [本地模型](/zh-CN/gateway/local-models), - [模型提供商](/zh-CN/concepts/model-providers), [Security](/zh-CN/gateway/security), + 文档:[Ollama](/zh-CN/providers/ollama)、[Local models](/zh-CN/gateway/local-models)、 + [Model providers](/zh-CN/concepts/model-providers)、[Security](/zh-CN/gateway/security)、 [沙箱隔离](/zh-CN/gateway/sandboxing)。 - - 这些部署可能彼此不同,也可能随时间变化;没有固定的 provider 推荐。 - - 使用 `openclaw models status` 检查每个 gateway 的当前运行时设置。 - - 对于安全敏感/启用工具的智能体,请使用当前可用的最新一代最强模型。 + - 这些部署可能不同,而且会随时间变化;并不存在固定的提供商推荐。 + - 请在每个 gateway 上使用 `openclaw models status` 检查当前运行时设置。 + - 对于安全敏感/启用了工具的智能体,请使用当前可用的最新一代最强模型。 @@ -2278,7 +2287,7 @@ x-i18n: /model gemini-flash-lite ``` - 这些是内置别名。你也可以通过 `agents.defaults.models` 添加自定义别名。 + 这些是内置别名。可以通过 `agents.defaults.models` 添加自定义别名。 你可以使用 `/model`、`/model list` 或 `/model status` 列出可用模型。 @@ -2288,46 +2297,46 @@ x-i18n: /model 3 ``` - 你还可以为该 provider 强制指定特定的认证配置文件(按会话): + 你还可以为提供商强制指定某个认证档案(按会话): ``` /model opus@anthropic:default /model opus@anthropic:work ``` - 提示:`/model status` 会显示当前活跃的是哪个智能体、使用的是哪个 `auth-profiles.json` 文件,以及接下来会尝试哪个认证配置文件。 - 它还会在可用时显示已配置的 provider 端点(`baseUrl`)和 API 模式(`api`)。 + 提示:`/model status` 会显示当前哪个智能体处于活跃状态、正在使用哪个 `auth-profiles.json` 文件,以及下一个会尝试哪个认证档案。 + 还会在可用时显示已配置的提供商端点(`baseUrl`)和 API 模式(`api`)。 - **如何取消通过 @profile 设置的固定配置文件?** + **如何取消通过 @profile 设定的固定档案?** - 重新运行**不带** `@profile` 后缀的 `/model`: + 重新运行 `/model`,**不要**带 `@profile` 后缀: ``` /model anthropic/claude-opus-4-6 ``` - 如果你想恢复到默认值,可以从 `/model` 中选择(或发送 `/model `)。 - 使用 `/model status` 确认当前活跃的认证配置文件。 + 如果你想回到默认值,请从 `/model` 中选择它(或发送 `/model `)。 + 使用 `/model status` 确认当前激活的是哪个认证档案。 - - 可以。设置一个为默认值,按需切换另一个: + + 可以。将一个设为默认模型,并在需要时切换: - - **快速切换(按会话):**日常任务使用 `/model gpt-5.4`,通过 Codex OAuth 写代码时使用 `/model openai-codex/gpt-5.4`。 - - **默认值 + 切换:**将 `agents.defaults.model.primary` 设置为 `openai/gpt-5.4`,然后在编码时切换到 `openai-codex/gpt-5.4`(或者反过来)。 - - **子智能体:**将编码任务路由给拥有不同默认模型的子智能体。 + - **快速切换(按会话):**日常任务使用 `/model gpt-5.4`,编码时使用 `/model openai-codex/gpt-5.4` 配合 Codex OAuth。 + - **默认值 + 切换:**将 `agents.defaults.model.primary` 设为 `openai/gpt-5.4`,编码时切换到 `openai-codex/gpt-5.4`(或者反过来)。 + - **子智能体:**将编码任务路由到默认模型不同的子智能体。 - 参阅 [Models](/zh-CN/concepts/models) 和 [斜杠命令](/zh-CN/tools/slash-commands)。 + 参阅 [Models](/zh-CN/concepts/models) 和 [Slash commands](/zh-CN/tools/slash-commands)。 - 你可以使用会话开关或配置默认值: + 你可以使用会话切换或配置默认值: - - **按会话:**当会话使用 `openai/gpt-5.4` 或 `openai-codex/gpt-5.4` 时,发送 `/fast on`。 - - **按模型默认值:**设置 `agents.defaults.models["openai/gpt-5.4"].params.fastMode` 为 `true`。 - - **Codex OAuth 也一样:**如果你也使用 `openai-codex/gpt-5.4`,同样设置该标志。 + - **按会话:**当会话正在使用 `openai/gpt-5.4` 或 `openai-codex/gpt-5.4` 时,发送 `/fast on`。 + - **按模型默认值:**将 `agents.defaults.models["openai/gpt-5.4"].params.fastMode` 设为 `true`。 + - **Codex OAuth 也适用:**如果你也使用 `openai-codex/gpt-5.4`,请在该模型下设置相同标志。 示例: @@ -2352,38 +2361,38 @@ x-i18n: } ``` - 对于 OpenAI,fast mode 会在受支持的原生 Responses 请求中映射为 `service_tier = "priority"`。会话中的 `/fast` 覆盖优先于配置默认值。 + 对于 OpenAI,fast mode 会在支持的原生 Responses 请求上映射为 `service_tier = "priority"`。会话中的 `/fast` 覆盖优先于配置默认值。 - 参阅 [思考和 fast mode](/zh-CN/tools/thinking) 和 [OpenAI fast mode](/zh-CN/providers/openai#openai-fast-mode)。 + 参阅 [Thinking and fast mode](/zh-CN/tools/thinking) 和 [OpenAI fast mode](/zh-CN/providers/openai#openai-fast-mode)。 - + 如果设置了 `agents.defaults.models`,它就会成为 `/model` 和任何 - 会话覆盖的**允许列表**。选择不在该列表中的模型会返回: + 会话覆盖的**允许列表**。选择一个不在该列表中的模型会返回: ``` Model "provider/model" is not allowed. Use /model to list available models. ``` - 该错误会**替代**正常回复返回。修复方法:将该模型加入 - `agents.defaults.models`,移除该允许列表,或从 `/model list` 中选择模型。 + 该错误会**代替**正常回复返回。解决方法:将该模型加入 + `agents.defaults.models`,移除允许列表,或从 `/model list` 中选择一个模型。 - - 这意味着**提供商未配置**(未找到 MiniMax provider 配置或 auth - profile),因此无法解析该模型。 + + 这意味着**提供商未配置**(未找到 MiniMax 提供商配置或认证 + 档案),因此无法解析该模型。 修复清单: 1. 升级到当前 OpenClaw 版本(或从源码 `main` 运行),然后重启 gateway。 - 2. 确保已配置 MiniMax(通过向导或 JSON),或者存在 MiniMax 认证 - 于环境变量/auth profiles 中,以便注入匹配的 provider + 2. 确保已配置 MiniMax(通过向导或 JSON),或环境变量/认证档案中 + 已存在 MiniMax 认证,以便注入匹配提供商 (`minimax` 使用 `MINIMAX_API_KEY`,`minimax-portal` 使用 `MINIMAX_OAUTH_TOKEN` 或已存储的 MiniMax OAuth)。 - 3. 对应你的认证路径,使用精确模型 ID(区分大小写): - API key 设置使用 `minimax/MiniMax-M2.7` 或 `minimax/MiniMax-M2.7-highspeed`, + 3. 为你的认证路径使用精确模型 ID(区分大小写): + API 密钥设置使用 `minimax/MiniMax-M2.7` 或 `minimax/MiniMax-M2.7-highspeed`, OAuth 设置使用 `minimax-portal/MiniMax-M2.7` / `minimax-portal/MiniMax-M2.7-highspeed`。 4. 运行: @@ -2392,15 +2401,15 @@ x-i18n: openclaw models list ``` - 并从列表中选择(或在聊天中使用 `/model list`)。 + 然后从列表中选择(或在聊天中使用 `/model list`)。 参阅 [MiniMax](/zh-CN/providers/minimax) 和 [Models](/zh-CN/concepts/models)。 - - 可以。把 **MiniMax 设为默认值**,并在需要时**按会话**切换模型。 - 回退是针对**错误**的,不是针对“困难任务”,所以请使用 `/model` 或单独智能体。 + + 可以。将**MiniMax 设为默认值**,并在需要时**按会话**切换模型。 + 后备是为**错误**准备的,而不是“高难任务”,所以请使用 `/model` 或单独的智能体。 **选项 A:按会话切换** @@ -2425,18 +2434,18 @@ x-i18n: /model gpt ``` - **选项 B:独立智能体** + **选项 B:分开智能体** - - 智能体 A 默认值:MiniMax - - 智能体 B 默认值:OpenAI + - 智能体 A 默认:MiniMax + - 智能体 B 默认:OpenAI - 按智能体路由,或使用 `/agent` 切换 - 文档: [Models](/zh-CN/concepts/models), [多智能体路由](/zh-CN/concepts/multi-agent), [MiniMax](/zh-CN/providers/minimax), [OpenAI](/zh-CN/providers/openai)。 + 文档:[Models](/zh-CN/concepts/models)、[Multi-Agent Routing](/zh-CN/concepts/multi-agent)、[MiniMax](/zh-CN/providers/minimax)、[OpenAI](/zh-CN/providers/openai)。 - 是的。OpenClaw 提供了一些默认简写(仅当模型存在于 `agents.defaults.models` 中时才生效): + 是的。OpenClaw 附带了一些默认简写(仅当模型存在于 `agents.defaults.models` 中时才生效): - `opus` → `anthropic/claude-opus-4-6` - `sonnet` → `anthropic/claude-sonnet-4-6` @@ -2447,7 +2456,7 @@ x-i18n: - `gemini-flash` → `google/gemini-3-flash-preview` - `gemini-flash-lite` → `google/gemini-3.1-flash-lite-preview` - 如果你设置了同名自定义别名,则你的值优先。 + 如果你设置了同名自定义别名,则以你的值为准。 @@ -2474,7 +2483,7 @@ x-i18n: - OpenRouter(按令牌付费;支持许多模型): + OpenRouter(按 token 计费;模型很多): ```json5 { @@ -2502,12 +2511,12 @@ x-i18n: } ``` - 如果你引用了某个 provider/model,但缺少所需 provider key,你会收到运行时认证错误(例如 `No API key found for provider "zai"`)。 + 如果你引用了某个 provider/model,但缺少所需的提供商密钥,就会收到运行时认证错误(例如 `No API key found for provider "zai"`)。 - **添加新智能体后出现 No API key found for provider** + **添加新智能体后提示 No API key found for provider** - 这通常意味着**新智能体**的认证存储是空的。认证是按智能体区分的, - 存储在: + 这通常意味着**新智能体**的认证存储为空。认证是按智能体区分的, + 存储于: ``` ~/.openclaw/agents//agent/auth-profiles.json @@ -2515,115 +2524,95 @@ x-i18n: 修复选项: - - 运行 `openclaw agents add `,并在向导中配置认证。 - - 或者把主智能体 `agentDir` 中的 `auth-profiles.json` 复制到新智能体的 `agentDir`。 + - 运行 `openclaw agents add ` 并在向导中配置认证。 + - 或把主智能体 `agentDir` 中的 `auth-profiles.json` 复制到新智能体的 `agentDir` 中。 - **不要**在多个智能体之间复用 `agentDir`;这会造成认证/会话冲突。 + **不要**在多个智能体之间复用 `agentDir`;这会导致认证/会话冲突。 -## 模型故障转移和“所有模型都失败了” +## 模型故障切换和 “All models failed” - - 故障转移分两个阶段: + + 故障切换分两个阶段: - 1. 同一 provider 内的**认证配置文件轮换**。 - 2. 回退到 `agents.defaults.model.fallbacks` 中的下一个**模型回退**。 + 1. 同一提供商内的**认证档案轮换**。 + 2. **模型后备**到 `agents.defaults.model.fallbacks` 中的下一个模型。 - 对失败的配置文件会应用冷却时间(指数退避),因此即使某个 provider 被限速或暂时失败,OpenClaw 也能继续回复。 + 对失败的档案会应用冷却时间(指数退避),因此即便某个提供商被限流或暂时失败,OpenClaw 仍能继续响应。 - 速率限制桶不仅包括普通 `429` 响应。OpenClaw - 也会将诸如 `Too many concurrent requests`、 + 限流桶不仅包括普通的 `429` 响应。OpenClaw + 还会将诸如 `Too many concurrent requests`、 `ThrottlingException`、`concurrency limit reached`、 - `workers_ai ... quota limit exceeded`、`resource exhausted` 以及周期性的 - 使用窗口限制(`weekly/monthly limit reached`)等消息视为值得故障转移的 - rate limits。 + `workers_ai ... quota limit exceeded`、`resource exhausted` 以及周期性 + 用量窗口限制(`weekly/monthly limit reached`)之类的消息视为值得故障切换的 + 限流情况。 某些看似计费相关的响应并不是 `402`,而某些 HTTP `402` - 响应也仍会留在该瞬时错误桶中。如果 provider 在 `401` 或 `403` 上 - 返回明确的计费文本,OpenClaw 仍可将其保留在 - 计费通道中,但 provider 特定的文本匹配器仍然只作用于其所属的 - provider(例如 OpenRouter 的 `Key limit exceeded`)。如果 `402` - 消息看起来更像可重试的使用窗口或 - 组织/工作区支出限制(`daily limit reached, resets tomorrow`、 + 响应也仍会保留在该瞬时故障桶中。如果提供商在 `401` 或 `403` 上返回了 + 明确的计费文本,OpenClaw 仍可将其保留在 + 计费类别中,但提供商特定的文本匹配器会保持限定在 + 拥有该逻辑的提供商范围内(例如 OpenRouter 的 `Key limit exceeded`)。如果某个 `402` + 消息看起来更像是可重试的用量窗口限制或 + 组织/工作区支出上限(`daily limit reached, resets tomorrow`、 `organization spending limit exceeded`),OpenClaw 会将其视为 `rate_limit`,而不是长期计费禁用。 上下文溢出错误则不同:像 `request_too_large`、`input exceeds the maximum number of tokens`、 `input token count exceeds the maximum number of input tokens`、 - `input is too long for the model`,或 `ollama error: context length - exceeded` 这样的特征会停留在压缩/重试路径中,而不是推进模型 - 回退。 + `input is too long for the model` 或 `ollama error: context length + exceeded` 这样的特征会保留在压缩/重试路径中,而不会推进模型后备。 - 通用服务器错误文本的匹配范围有意地比“任何带 - unknown/error 的内容”更窄。OpenClaw 确实会在 provider 上下文 - 匹配时,将诸如 Anthropic 的裸 `An unknown error occurred`、OpenRouter 的裸 + 通用服务器错误文本的判断范围会刻意比“任何带 + unknown/error 的内容”更窄。OpenClaw 的确会把提供商上下文中的瞬时错误形态 + 视为值得故障切换的超时/过载信号,例如 Anthropic 的裸 + `An unknown error occurred`、OpenRouter 的裸 `Provider returned error`、停止原因错误如 `Unhandled stop reason: - error`、带有瞬时服务器文本的 JSON `api_error` 负载 + error`、带瞬时服务器文本的 JSON `api_error` 负载 (`internal server error`、`unknown error, 520`、`upstream error`、`backend - error`),以及 provider 繁忙错误如 `ModelNotReadyException` 视为值得故障转移的超时/过载信号。 - 而通用的内部回退文本,例如 `LLM request failed with an unknown - error.`,则保持保守,不会单独触发模型回退。 + error`),以及诸如 `ModelNotReadyException` 之类的提供商繁忙错误,只要提供商上下文匹配。 + 通用内部回退文本,比如 `LLM request failed with an unknown + error.`,本身会保持保守,不会单独触发模型后备。 - 这意味着系统尝试使用认证配置文件 ID `anthropic:default`,但无法在预期的认证存储中找到对应凭据。 + 这意味着系统尝试使用认证档案 ID `anthropic:default`,但无法在预期的认证存储中找到对应凭据。 **修复清单:** - - **确认 auth profiles 存放位置**(新旧路径) - - 当前路径:`~/.openclaw/agents//agent/auth-profiles.json` - - 旧版路径:`~/.openclaw/agent/*`(由 `openclaw doctor` 迁移) - - **确认你的环境变量已被 Gateway 网关加载** - - 如果你在 shell 中设置了 `ANTHROPIC_API_KEY`,但 Gateway 网关是通过 systemd/launchd 运行的,它可能不会继承该变量。请将它放入 `~/.openclaw/.env` 或启用 `env.shellEnv`。 + - **确认认证档案存放位置**(新路径与旧路径) + - 当前:`~/.openclaw/agents//agent/auth-profiles.json` + - 旧版:`~/.openclaw/agent/*`(由 `openclaw doctor` 迁移) + - **确认 Gateway 网关已加载你的环境变量** + - 如果你在 shell 中设置了 `ANTHROPIC_API_KEY`,但 Gateway 网关通过 systemd/launchd 运行,它可能不会继承。请将它放入 `~/.openclaw/.env` 或启用 `env.shellEnv`。 - **确保你编辑的是正确的智能体** - 多智能体设置意味着可能存在多个 `auth-profiles.json` 文件。 - - **进行模型/认证状态检查** - - 使用 `openclaw models status` 查看已配置模型以及 provider 是否已认证。 + - **做一次模型/认证状态检查** + - 使用 `openclaw models status` 查看已配置模型以及提供商是否已认证。 **针对 “No credentials found for profile anthropic” 的修复清单** - 这意味着当前运行被固定到一个 Anthropic auth profile,但 Gateway - 无法在其认证存储中找到它。 + 这意味着当前运行被固定到了一个 Anthropic 认证档案,但 Gateway 网关 + 在其认证存储中找不到它。 - **使用 Claude CLI** - - 在 gateway host 上运行 `openclaw models auth login --provider anthropic --method cli --set-default`。 - - **如果你想改用 API key** - - 将 `ANTHROPIC_API_KEY` 放入 **gateway host** 上的 `~/.openclaw/.env`。 - - 清除任何会强制使用缺失配置文件的固定顺序: + - 在 gateway 主机上运行 `openclaw models auth login --provider anthropic --method cli --set-default`。 + - **如果你想改用 API 密钥** + - 将 `ANTHROPIC_API_KEY` 放入**gateway 主机**上的 `~/.openclaw/.env`。 + - 清除任何强制使用缺失档案的固定顺序: ```bash openclaw models auth order clear --provider anthropic ``` - - **确认你是在 gateway host 上运行命令** - - 在远程模式下,auth profiles 位于 gateway 机器上,而不是你的笔记本上。 + - **确认你是在 gateway 主机上运行命令** + - 在远程模式下,认证档案位于 gateway 机器上,而不是你的笔记本上。 - - 如果你的模型配置中将 Google Gemini 设为回退项(或你切换到了 Gemini 简写),OpenClaw 会在模型回退期间尝试它。如果你尚未配置 Google 凭据,就会看到 `No API key found for provider "google"`。 - - 修复方法:要么提供 Google 认证,要么从 `agents.defaults.model.fallbacks` / 别名中移除或避免 Google 模型,以免回退路由到那里。 - - **LLM request rejected: thinking signature required(Google Antigravity)** - - 原因:会话历史中包含**没有签名的 thinking 块**(通常来自 - 被中止/不完整的流)。Google Antigravity 要求 thinking 块必须带签名。 - - 修复方法:OpenClaw 现在会为 Google Antigravity Claude 去除未签名的 thinking 块。如果仍然出现,请开始一个**新会话**,或为该智能体设置 `/thinking off`。 - - - - -## 认证配置文件:它们是什么以及如何管理 - -相关内容:[/concepts/oauth](/zh-CN/concepts/oauth)(OAuth 流程、令牌存储、多账号模式) - - - - 认证配置文件是与 provider 绑定的命名凭据记录(OAuth 或 API key)。配置文件 \ No newline at end of file + + 如果你的模型配置将 Google Gemini 作为后备(或你切 \ No newline at end of file diff --git a/docs/zh-CN/help/testing.md b/docs/zh-CN/help/testing.md index be158bbc3..68912ca7c 100644 --- a/docs/zh-CN/help/testing.md +++ b/docs/zh-CN/help/testing.md @@ -3,277 +3,317 @@ read_when: - 在本地或 CI 中运行测试时 - 为模型 / 提供商缺陷添加回归测试时 - 调试 Gateway 网关 + 智能体行为时 -summary: 测试工具包:单元 / e2e / 实时测试套件、Docker 运行器,以及各类测试覆盖的内容 +summary: 测试工具包:单元 / e2e / live 测试套件、Docker 运行器,以及每类测试覆盖的内容 title: 测试 x-i18n: - generated_at: "2026-04-06T01:02:40Z" + generated_at: "2026-04-06T12:44:29Z" model: gpt-5.4 provider: openai - source_hash: cfa174e565df5fdf957234b7909beaf1304aa026e731cc2c433ca7d931681b56 + source_hash: b18d68d08b851dea994af250f7cb833a34523601d04fd2f118def9777c961b55 source_path: help/testing.md workflow: 15 --- # 测试 -OpenClaw 有三个 Vitest 测试套件(单元 / 集成、e2e、实时)以及一小组 Docker 运行器。 +OpenClaw 有三个 Vitest 测试套件(单元 / 集成、e2e、live)以及一小组 Docker 运行器。 本文档是一份“我们如何测试”的指南: -- 每个测试套件覆盖什么内容(以及它刻意 _不_ 覆盖什么) -- 常见工作流应运行哪些命令(本地、推送前、调试) -- 实时测试如何发现凭证并选择模型 / 提供商 +- 每个测试套件覆盖什么(以及它刻意 _不_ 覆盖什么) +- 常见工作流该运行哪些命令(本地、推送前、调试) +- live 测试如何发现凭证并选择模型 / 提供商 - 如何为真实世界中的模型 / 提供商问题添加回归测试 ## 快速开始 大多数时候: -- 完整 gate(推送前预期应运行):`pnpm build && pnpm check && pnpm test` -- 在资源充足的机器上更快地运行本地完整测试套件:`pnpm test:max` +- 完整门槛检查(预期在推送前执行):`pnpm build && pnpm check && pnpm test` +- 在配置较充足的机器上更快地运行本地完整测试套件:`pnpm test:max` - 直接使用 Vitest 观察模式循环(现代 projects 配置):`pnpm test:watch` -- 现在也支持直接按文件路径定位扩展 / 渠道测试:`pnpm test extensions/discord/src/monitor/message-handler.preflight.test.ts` +- 现在直接指定文件也会路由扩展 / 渠道路径:`pnpm test extensions/discord/src/monitor/message-handler.preflight.test.ts` -当你修改了测试,或希望获得更高把握时: +当你修改了测试或想获得更多信心时: -- 覆盖率 gate:`pnpm test:coverage` +- 覆盖率门槛检查:`pnpm test:coverage` - E2E 测试套件:`pnpm test:e2e` 调试真实提供商 / 模型时(需要真实凭证): -- 实时测试套件(模型 + Gateway 网关工具 / 图像探测):`pnpm test:live` -- 安静地只运行一个实时测试文件:`pnpm test:live -- src/agents/models.profiles.live.test.ts` +- Live 测试套件(模型 + Gateway 网关 工具 / 图像探测):`pnpm test:live` +- 安静地只跑一个 live 文件:`pnpm test:live -- src/agents/models.profiles.live.test.ts` -提示:如果你只需要定位一个失败用例,优先使用下文介绍的 allowlist 环境变量来缩小实时测试范围。 +提示:如果你只需要一个失败用例,优先使用下面介绍的 allowlist 环境变量来缩小 live 测试范围。 -## 测试套件(各自运行在哪里) +## 测试套件(各自运行位置) -可以把这些测试套件理解为“真实程度逐步增加”(同时不稳定性 / 成本也逐步增加): +可以把这些测试套件理解为“真实度逐步增加”(同时不稳定性 / 成本也逐步增加): ### 单元 / 集成(默认) - 命令:`pnpm test` - 配置:通过 `vitest.config.ts` 使用原生 Vitest `projects` -- 文件:位于 `src/**/*.test.ts`、`packages/**/*.test.ts`、`test/**/*.test.ts` 的核心 / 单元测试清单,以及 `vitest.unit.config.ts` 覆盖的白名单 `ui` Node 测试 +- 文件:`src/**/*.test.ts`、`packages/**/*.test.ts`、`test/**/*.test.ts` 下的核心 / 单元测试清单,以及由 `vitest.unit.config.ts` 覆盖的白名单 `ui` Node 测试 - 范围: - 纯单元测试 - - 进程内集成测试(Gateway 网关认证、路由、工具、解析、配置) - - 针对已知缺陷的确定性回归测试 + - 进程内集成测试(Gateway 网关 身份验证、路由、工具、解析、配置) + - 已知缺陷的确定性回归测试 - 预期: - 在 CI 中运行 - 不需要真实密钥 - 应该快速且稳定 - Projects 说明: - - `pnpm test`、`pnpm test:watch` 和 `pnpm test:changed` 现在都使用同一个原生 Vitest 根级 `projects` 配置。 - - 直接文件过滤现在会通过根项目图原生路由,因此 `pnpm test extensions/discord/src/monitor/message-handler.preflight.test.ts` 无需自定义包装器即可工作。 + - `pnpm test`、`pnpm test:watch` 和 `pnpm test:changed` 现在都使用同一份原生 Vitest 根级 `projects` 配置。 + - 直接文件过滤现在会通过根项目图原生路由,因此 `pnpm test extensions/discord/src/monitor/message-handler.preflight.test.ts` 无需自定义包装器也能工作。 - 嵌入式运行器说明: - 当你修改消息工具发现输入或压缩运行时上下文时, - 要同时保持两个层级的覆盖。 - - 为纯路由 / 归一化边界添加聚焦的辅助函数回归测试。 + 请同时保留两个层级的覆盖。 + - 为纯路由 / 规范化边界添加有针对性的辅助函数回归测试。 - 同时也要保持嵌入式运行器集成测试套件健康: `src/agents/pi-embedded-runner/compact.hooks.test.ts`、 - `src/agents/pi-embedded-runner/run.overflow-compaction.test.ts` 和 + `src/agents/pi-embedded-runner/run.overflow-compaction.test.ts`,以及 `src/agents/pi-embedded-runner/run.overflow-compaction.loop.test.ts`。 - - 这些套件会验证作用域 id 和压缩行为是否仍然通过真实的 - `run.ts` / `compact.ts` 路径流转;仅有辅助函数级测试 + - 这些测试套件用于验证带作用域的 id 和压缩行为仍然会沿真实的 + `run.ts` / `compact.ts` 路径传递;仅有辅助函数测试 不能充分替代这些集成路径。 -- Pool 说明: +- 线程池说明: - 基础 Vitest 配置现在默认使用 `threads`。 - - 共享 Vitest 配置还固定了 `isolate: false`,并在根 projects、e2e 和实时配置中使用非隔离运行器。 - - 根 UI 通道仍保留其 `jsdom` 设置和优化器,但现在也运行在共享的非隔离运行器上。 - - `pnpm test` 现在从根 `vitest.config.ts` 的 projects 配置继承相同的 `threads` + `isolate: false` 默认值。 - - 共享的 `scripts/run-vitest.mjs` 启动器现在默认还会为 Vitest 子 Node 进程添加 `--no-maglev`,以减少大型本地运行期间的 V8 编译抖动。如果你需要与原生 V8 行为进行对比,设置 `OPENCLAW_VITEST_ENABLE_MAGLEV=1`。 -- 本地快速迭代说明: - - `pnpm test:changed` 现在使用原生 projects 配置并带上 `--changed origin/main`。 - - `pnpm test:max` 和 `pnpm test:changed:max` 保持相同的原生 projects 配置,只是提高了 worker 上限。 - - 本地 worker 自动缩放现在有意更保守,并且在主机负载平均值已经较高时也会回退,因此多个并发 Vitest 运行默认造成的影响更小。 - - 基础 Vitest 配置将 projects / config 文件标记为 `forceRerunTriggers`,因此 changed 模式在测试接线发生变化时仍能正确重跑。 - - 配置在支持的主机上保持启用 `OPENCLAW_VITEST_FS_MODULE_CACHE`;如果你希望为直接性能分析指定一个显式缓存位置,可设置 `OPENCLAW_VITEST_FS_MODULE_CACHE_PATH=/abs/path`。 + - 共享 Vitest 配置也固定了 `isolate: false`,并在根 projects、e2e 和 live 配置中使用非隔离运行器。 + - 根级 UI 通道保留其 `jsdom` 设置和优化器,但现在也运行在共享的非隔离运行器上。 + - `pnpm test` 从根级 `vitest.config.ts` projects 配置继承相同的 `threads` + `isolate: false` 默认值。 + - 共享的 `scripts/run-vitest.mjs` 启动器现在默认还会为 Vitest 子 Node 进程添加 `--no-maglev`,以减少大型本地运行期间的 V8 编译抖动。如果你需要与原生 V8 行为做对比,可设置 `OPENCLAW_VITEST_ENABLE_MAGLEV=1`。 +- 快速本地迭代说明: + - `pnpm test:changed` 会使用原生 projects 配置并带上 `--changed origin/main` 运行。 + - `pnpm test:max` 和 `pnpm test:changed:max` 保持相同的原生 projects 配置,只是使用更高的 worker 上限。 + - 本地 worker 自动缩放现在有意采取更保守策略,并且当主机平均负载已经较高时也会回退,因此默认情况下多个并发 Vitest 运行对系统的影响更小。 + - 基础 Vitest 配置会将 projects / config 文件标记为 `forceRerunTriggers`,以便在测试布线发生变化时 changed 模式的重跑仍然正确。 + - 在受支持的主机上,该配置保持启用 `OPENCLAW_VITEST_FS_MODULE_CACHE`;如果你想为直接性能分析指定一个明确的缓存位置,可设置 `OPENCLAW_VITEST_FS_MODULE_CACHE_PATH=/abs/path`。 - 性能调试说明: - `pnpm test:perf:imports` 会启用 Vitest 导入耗时报告以及导入明细输出。 - - `pnpm test:perf:imports:changed` 会将相同的性能分析视图限定到自 `origin/main` 以来发生变化的文件。 - - `pnpm test:perf:profile:main` 会为 Vitest / Vite 启动和转换开销写出主线程 CPU profile。 - - `pnpm test:perf:profile:runner` 会在禁用文件并行的情况下,为单元测试套件写出运行器 CPU + heap profile。 + - `pnpm test:perf:imports:changed` 会将相同的分析视图限制为自 `origin/main` 以来变更的文件。 + - `pnpm test:perf:profile:main` 会为 Vitest / Vite 启动和转换开销写入主线程 CPU profile。 + - `pnpm test:perf:profile:runner` 会在禁用文件并行的情况下,为单元测试套件写入运行器 CPU + 堆 profile。 -### E2E(Gateway 网关烟雾测试) +### E2E(Gateway 网关 冒烟测试) - 命令:`pnpm test:e2e` - 配置:`vitest.e2e.config.ts` - 文件:`src/**/*.e2e.test.ts`、`test/**/*.e2e.test.ts` - 运行时默认值: - - 使用 Vitest `threads` 与 `isolate: false`,与仓库其余部分保持一致。 - - 使用自适应 workers(CI:最多 2 个,本地:默认 1 个)。 + - 使用 Vitest `threads` 且 `isolate: false`,与仓库其余部分保持一致。 + - 使用自适应 worker(CI:最多 2 个,本地:默认 1 个)。 - 默认以静默模式运行,以减少控制台 I/O 开销。 - 常用覆盖项: - - `OPENCLAW_E2E_WORKERS=`:强制指定 worker 数量(上限为 16)。 - - `OPENCLAW_E2E_VERBOSE=1`:重新启用详细控制台输出。 + - `OPENCLAW_E2E_WORKERS=` 强制设置 worker 数量(上限为 16)。 + - `OPENCLAW_E2E_VERBOSE=1` 重新启用详细控制台输出。 - 范围: - - 多实例 Gateway 网关端到端行为 - - WebSocket / HTTP 接口、节点配对以及更重的网络交互 + - 多实例 Gateway 网关 端到端行为 + - WebSocket / HTTP 接口、节点配对以及更重的网络场景 - 预期: - - 在 CI 中运行(当流水线中启用时) + - 在 CI 中运行(当流水线启用时) - 不需要真实密钥 - - 比单元测试涉及更多活动部件(可能更慢) + - 比单元测试有更多可变因素(可能更慢) -### E2E:OpenShell 后端烟雾测试 +### E2E:OpenShell 后端冒烟测试 - 命令:`pnpm test:e2e:openshell` - 文件:`test/openshell-sandbox.e2e.test.ts` - 范围: - 通过 Docker 在主机上启动一个隔离的 OpenShell Gateway 网关 - - 基于临时本地 Dockerfile 创建一个沙箱 + - 从临时本地 Dockerfile 创建一个沙箱 - 通过真实的 `sandbox ssh-config` + SSH exec 运行 OpenClaw 的 OpenShell 后端 - - 通过沙箱 fs bridge 验证远端规范化文件系统行为 + - 通过沙箱 fs bridge 验证远端标准文件系统行为 - 预期: - - 仅在选择加入时运行;不属于默认 `pnpm test:e2e` 运行的一部分 - - 需要本地 `openshell` CLI 和一个可用的 Docker daemon - - 使用隔离的 `HOME` / `XDG_CONFIG_HOME`,然后销毁测试 Gateway 网关和沙箱 + - 仅在选择加入时运行;不属于默认的 `pnpm test:e2e` 执行内容 + - 需要本地 `openshell` CLI 和可用的 Docker daemon + - 使用隔离的 `HOME` / `XDG_CONFIG_HOME`,然后销毁测试 Gateway 网关 和沙箱 - 常用覆盖项: - - `OPENCLAW_E2E_OPENSHELL=1`:在手动运行更广泛的 e2e 套件时启用此测试 - - `OPENCLAW_E2E_OPENSHELL_COMMAND=/path/to/openshell`:指向非默认 CLI 二进制文件或包装脚本 + - `OPENCLAW_E2E_OPENSHELL=1`:在手动运行更广泛的 e2e 测试套件时启用该测试 + - `OPENCLAW_E2E_OPENSHELL_COMMAND=/path/to/openshell`:指向非默认 CLI 二进制或包装脚本 -### 实时(真实提供商 + 真实模型) +### Live(真实提供商 + 真实模型) - 命令:`pnpm test:live` - 配置:`vitest.live.config.ts` - 文件:`src/**/*.live.test.ts` -- 默认:由 `pnpm test:live` **启用**(会设置 `OPENCLAW_LIVE_TEST=1`) +- 默认:由 `pnpm test:live` **启用**(设置 `OPENCLAW_LIVE_TEST=1`) - 范围: - - “这个提供商 / 模型今天在真实凭证下是否真的可用?” - - 捕获提供商格式变更、工具调用怪癖、认证问题以及限流行为 + - “这个提供商 / 模型在 _今天_ 配合真实凭证是否真的能工作?” + - 捕捉提供商格式变化、工具调用怪癖、身份验证问题和限流行为 - 预期: - - 按设计不追求 CI 稳定性(真实网络、真实提供商策略、配额、故障) - - 会花钱 / 消耗限流额度 + - 设计上不以 CI 稳定为目标(真实网络、真实提供商策略、配额、故障) + - 需要花钱 / 消耗速率限制 - 优先运行缩小范围的子集,而不是“全部” -- 实时运行会 source `~/.profile` 以补齐缺失的 API 密钥。 -- 默认情况下,实时运行仍会隔离 `HOME`,并将配置 / 认证材料复制到临时测试 home 中,这样单元测试夹具就不会修改你真实的 `~/.openclaw`。 -- 只有当你明确需要实时测试使用真实 home 目录时,才设置 `OPENCLAW_LIVE_USE_REAL_HOME=1`。 -- `pnpm test:live` 现在默认使用更安静的模式:会保留 `[live] ...` 进度输出,但会抑制额外的 `~/.profile` 提示,并静默 Gateway 网关引导日志 / Bonjour 噪音。如果你希望恢复完整启动日志,可设置 `OPENCLAW_LIVE_TEST_QUIET=0`。 -- API 密钥轮换(提供商特定):设置 `*_API_KEYS`,使用逗号 / 分号格式,或设置 `*_API_KEY_1`、`*_API_KEY_2`(例如 `OPENAI_API_KEYS`、`ANTHROPIC_API_KEYS`、`GEMINI_API_KEYS`),也可通过 `OPENCLAW_LIVE_*_KEY` 为单次实时运行覆盖;测试会在遇到限流响应时重试。 +- Live 运行会读取 `~/.profile`,以补齐缺失的 API 密钥。 +- 默认情况下,live 运行仍然会隔离 `HOME`,并将配置 / 身份验证材料复制到临时测试 home 中,这样单元测试夹具就不会修改你真实的 `~/.openclaw`。 +- 仅当你明确需要 live 测试使用真实 home 目录时,才设置 `OPENCLAW_LIVE_USE_REAL_HOME=1`。 +- `pnpm test:live` 现在默认以更安静的模式运行:它会保留 `[live] ...` 进度输出,但会抑制额外的 `~/.profile` 提示,并静音 Gateway 网关 启动日志 / Bonjour 噪音。如果你想恢复完整启动日志,可设置 `OPENCLAW_LIVE_TEST_QUIET=0`。 +- API 密钥轮换(提供商专属):设置 `*_API_KEYS`,使用逗号 / 分号格式,或设置 `*_API_KEY_1`、`*_API_KEY_2`(例如 `OPENAI_API_KEYS`、`ANTHROPIC_API_KEYS`、`GEMINI_API_KEYS`),或者通过 `OPENCLAW_LIVE_*_KEY` 进行逐个 live 覆盖;测试在收到限流响应时会重试。 - 进度 / 心跳输出: - - 实时测试套件现在会将进度行输出到 stderr,因此即使 Vitest 控制台捕获较安静,长时间的提供商调用也能显示其仍在活动。 - - `vitest.live.config.ts` 会禁用 Vitest 控制台拦截,因此提供商 / Gateway 网关进度行会在实时运行期间立即流式输出。 - - 使用 `OPENCLAW_LIVE_HEARTBEAT_MS` 调整 direct-model 心跳。 + - Live 测试套件现在会将进度行输出到 stderr,因此即使 Vitest 控制台捕获较安静,较长时间的提供商调用也能显示为仍在活动。 + - `vitest.live.config.ts` 禁用了 Vitest 控制台拦截,因此在 live 运行期间,提供商 / Gateway 网关 进度行会立即流式输出。 + - 使用 `OPENCLAW_LIVE_HEARTBEAT_MS` 调整直接模型心跳。 - 使用 `OPENCLAW_LIVE_GATEWAY_HEARTBEAT_MS` 调整 Gateway 网关 / 探测心跳。 ## 我应该运行哪个测试套件? -使用下面这个决策表: +使用这个决策表: - 编辑逻辑 / 测试:运行 `pnpm test`(如果改动较多,再加上 `pnpm test:coverage`) -- 触及 Gateway 网关网络 / WS 协议 / 配对:再加跑 `pnpm test:e2e` -- 调试“我的 bot 挂了” / 提供商特定故障 / 工具调用:运行一个缩小范围的 `pnpm test:live` +- 触及 Gateway 网关 网络 / WS 协议 / 配对:加跑 `pnpm test:e2e` +- 调试“我的 bot 挂了” / 提供商专属失败 / 工具调用:运行缩小范围的 `pnpm test:live` -## 实时:Android 节点能力扫描 +## Live:Android 节点能力扫描 - 测试:`src/gateway/android-node.capabilities.live.test.ts` - 脚本:`pnpm android:test:integration` -- 目标:调用已连接 Android 节点当前**声明的每一个命令**,并断言命令契约行为。 +- 目标:调用连接的 Android 节点当前发布的**每一条命令**,并断言命令契约行为。 - 范围: - - 需要预设 / 手动设置(该套件不会安装 / 运行 / 配对应用)。 - - 针对所选 Android 节点逐命令验证 Gateway 网关 `node.invoke`。 -- 必需的预设步骤: - - Android 应用已连接并与 Gateway 网关配对。 - - 应用保持前台运行。 - - 已为你期望通过的能力授予权限 / 捕获同意。 -- 可选目标覆盖项: + - 需要预先满足条件 / 手动设置(该测试套件不会安装 / 运行 / 配对应用)。 + - 针对所选 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 App](/zh-CN/platforms/android) -## 实时:模型烟雾测试(profile keys) +## Live:模型冒烟测试(profile keys) -实时测试拆分为两层,以便隔离故障: +Live 测试分成两层,这样我们可以隔离失败原因: -- “Direct model” 用于告诉我们:给定的 key 下,该提供商 / 模型是否至少能响应。 -- “Gateway smoke” 用于告诉我们:该模型的完整 Gateway 网关 + 智能体管线是否工作正常(会话、历史、工具、沙箱策略等)。 +- “直接模型”告诉我们提供商 / 模型是否至少能用给定密钥正常响应。 +- “Gateway 网关 冒烟测试”告诉我们完整的 Gateway 网关 + 智能体流水线是否适用于该模型(会话、历史、工具、沙箱策略等)。 -### 第 1 层:Direct model completion(无 Gateway 网关) +### 第 1 层:直接模型补全(无 Gateway 网关) - 测试:`src/agents/models.profiles.live.test.ts` - 目标: - 枚举发现到的模型 - 使用 `getApiKeyForModel` 选择你有凭证的模型 - - 为每个模型运行一次小型 completion(并在需要时运行定向回归) + - 为每个模型运行一次小型补全(在需要时也运行有针对性的回归测试) - 启用方式: - `pnpm test:live`(或直接调用 Vitest 时设置 `OPENCLAW_LIVE_TEST=1`) -- 设置 `OPENCLAW_LIVE_MODELS=modern`(或 `all`,即 modern 的别名)后才会实际运行此套件;否则它会跳过,以便让 `pnpm test:live` 聚焦于 Gateway 网关烟雾测试 +- 设置 `OPENCLAW_LIVE_MODELS=modern`(或 `all`,它是 modern 的别名)才能真正运行该测试套件;否则它会跳过,以便让 `pnpm test:live` 聚焦于 Gateway 网关 冒烟测试 - 如何选择模型: - - `OPENCLAW_LIVE_MODELS=modern`:运行 modern allowlist(Opus / Sonnet 4.6+、GPT-5.x + Codex、Gemini 3、GLM 4.7、MiniMax M2.7、Grok 4) + - `OPENCLAW_LIVE_MODELS=modern` 运行 modern allowlist(Opus / Sonnet 4.6+、GPT-5.x + Codex、Gemini 3、GLM 4.7、MiniMax M2.7、Grok 4) - `OPENCLAW_LIVE_MODELS=all` 是 modern allowlist 的别名 - 或 `OPENCLAW_LIVE_MODELS="openai/gpt-5.4,anthropic/claude-opus-4-6,..."`(逗号分隔的 allowlist) - 如何选择提供商: - - `OPENCLAW_LIVE_PROVIDERS="google,google-antigravity"`(逗号分隔的 allowlist) + - `OPENCLAW_LIVE_PROVIDERS="google,google-antigravity,google-gemini-cli"`(逗号分隔的 allowlist) - 密钥来源: - 默认:profile 存储和环境变量回退 - - 设置 `OPENCLAW_LIVE_REQUIRE_PROFILE_KEYS=1` 可强制**仅使用 profile 存储** + - 设置 `OPENCLAW_LIVE_REQUIRE_PROFILE_KEYS=1` 以强制**仅使用 profile 存储** - 存在原因: - - 将“提供商 API 坏了 / key 无效”和“Gateway 网关智能体管线坏了”分离开来 - - 容纳小而隔离的回归场景(例如:OpenAI Responses / Codex Responses 的 reasoning replay + tool-call 流程) + - 将“提供商 API 坏了 / 密钥无效”与“Gateway 网关 智能体流水线坏了”分离 + - 容纳小而隔离的回归测试(例如:OpenAI Responses / Codex Responses 推理重放 + 工具调用流程) -### 第 2 层:Gateway 网关 + dev 智能体烟雾测试(也就是 “@openclaw” 实际做的事) +### 第 2 层:Gateway 网关 + dev 智能体冒烟测试(也就是 “@openclaw” 实际在做什么) - 测试:`src/gateway/gateway-models.profiles.live.test.ts` - 目标: - 启动一个进程内 Gateway 网关 - - 创建 / 修补一个 `agent:dev:*` 会话(每次运行按模型覆盖) - - 遍历有密钥的模型并断言: + - 创建 / 修补一个 `agent:dev:*` 会话(每次运行都覆盖模型) + - 迭代有密钥的模型,并断言: - “有意义的”响应(无工具) - - 一次真实工具调用可正常工作(read probe) - - 可选的额外工具探测可正常工作(exec+read probe) - - OpenAI 回归路径(仅 tool-call → 后续跟进)持续可用 -- 探测细节(这样你就能快速解释故障): - - `read` probe:测试会在工作区写入一个 nonce 文件,并要求智能体 `read` 它并把 nonce 回显回来。 - - `exec+read` probe:测试会要求智能体通过 `exec` 将一个 nonce 写入临时文件,然后再 `read` 回来。 - - image probe:测试会附加一个生成的 PNG(猫 + 随机代码),并期望模型返回 `cat `。 + - 真实工具调用可用(read 探测) + - 可选的额外工具探测(exec+read 探测) + - OpenAI 回归路径(仅工具调用 → 后续跟进)继续可用 +- 探测细节(这样你可以快速解释失败): + - `read` 探测:测试会在工作区写入一个 nonce 文件,并要求智能体 `read` 它并回显该 nonce。 + - `exec+read` 探测:测试要求智能体通过 `exec` 将一个 nonce 写入临时文件,然后再 `read` 回来。 + - 图像探测:测试会附加一个生成的 PNG(猫 + 随机代码),并期望模型返回 `cat `。 - 实现参考:`src/gateway/gateway-models.profiles.live.test.ts` 和 `src/gateway/live-image-probe.ts`。 - 启用方式: - `pnpm test:live`(或直接调用 Vitest 时设置 `OPENCLAW_LIVE_TEST=1`) - 如何选择模型: - 默认:modern allowlist(Opus / Sonnet 4.6+、GPT-5.x + Codex、Gemini 3、GLM 4.7、MiniMax M2.7、Grok 4) - `OPENCLAW_LIVE_GATEWAY_MODELS=all` 是 modern allowlist 的别名 - - 或设置 `OPENCLAW_LIVE_GATEWAY_MODELS="provider/model"`(或逗号列表)来缩小范围 -- 如何选择提供商(避免“OpenRouter 全家桶”): - - `OPENCLAW_LIVE_GATEWAY_PROVIDERS="google,google-antigravity,openai,anthropic,zai,minimax"`(逗号分隔的 allowlist) -- 工具 + 图像探测在此实时测试中始终开启: - - `read` probe + `exec+read` probe(工具压力测试) - - 当模型声明支持图像输入时,会运行 image probe - - 流程(高层说明): - - 测试生成一个包含 “CAT” + 随机代码的小型 PNG(`src/gateway/live-image-probe.ts`) + - 或设置 `OPENCLAW_LIVE_GATEWAY_MODELS="provider/model"`(或逗号分隔列表)来缩小范围 +- 如何选择提供商(避免“OpenRouter 全量”): + - `OPENCLAW_LIVE_GATEWAY_PROVIDERS="google,google-antigravity,google-gemini-cli,openai,anthropic,zai,minimax"`(逗号分隔的 allowlist) +- 工具 + 图像探测在这个 live 测试中始终启用: + - `read` 探测 + `exec+read` 探测(工具压力测试) + - 当模型声明支持图像输入时,会运行图像探测 + - 流程(高层级): + - 测试生成一个带有 “CAT” + 随机代码的小型 PNG(`src/gateway/live-image-probe.ts`) - 通过 `agent` `attachments: [{ mimeType: "image/png", content: "" }]` 发送 - - Gateway 网关会将附件解析到 `images[]` 中(`src/gateway/server-methods/agent.ts` + `src/gateway/chat-attachments.ts`) - - 嵌入式智能体将多模态用户消息转发给模型 - - 断言:回复包含 `cat` + 该代码(OCR 允许轻微误差) + - 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 openclaw models list --json ``` -## 实时:ACP bind 烟雾测试(`/acp spawn ... --bind here`) +## Live:CLI 后端冒烟测试(Codex CLI 或其他本地 CLI) + +- 测试:`src/gateway/gateway-cli-backend.live.test.ts` +- 目标:使用本地 CLI 后端验证 Gateway 网关 + 智能体流水线,而不触碰你的默认配置。 +- 启用: + - `pnpm test:live`(或直接调用 Vitest 时设置 `OPENCLAW_LIVE_TEST=1`) + - `OPENCLAW_LIVE_CLI_BACKEND=1` +- 默认值: + - 模型:`codex-cli/gpt-5.4` + - 命令:`codex` + - 参数:`["exec","--json","--color","never","--sandbox","read-only","--skip-git-repo-check"]` +- 覆盖项(可选): + - `OPENCLAW_LIVE_CLI_BACKEND_MODEL="codex-cli/gpt-5.4"` + - `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` 发送真实图像附件(路径会注入到提示词中)。 + - `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` 发送第二轮并验证恢复流程。 + +示例: + +```bash +OPENCLAW_LIVE_CLI_BACKEND=1 \ + OPENCLAW_LIVE_CLI_BACKEND_MODEL="codex-cli/gpt-5.4" \ + pnpm test:live src/gateway/gateway-cli-backend.live.test.ts +``` + +Docker 配方: + +```bash +pnpm test:docker:live-cli-backend +``` + +说明: + +- Docker 运行器位于 `scripts/test-live-cli-backend-docker.sh`。 +- 它会在仓库 Docker 镜像内,以非 root 的 `node` 用户身份运行 live CLI 后端冒烟测试。 +- 对于 `codex-cli`,它会将 Linux 版 `@openai/codex` 包安装到可缓存的可写前缀 `OPENCLAW_DOCKER_CLI_TOOLS_DIR`(默认:`~/.cache/openclaw/docker-cli-tools`)中。 + +## Live:ACP 绑定冒烟测试(`/acp spawn ... --bind here`) - 测试:`src/gateway/gateway-acp-bind.live.test.ts` -- 目标:使用实时 ACP 智能体验证真实 ACP conversation-bind 流程: +- 目标:使用 live ACP 智能体验证真实 ACP 会话绑定流程: - 发送 `/acp spawn --bind here` - - 原地绑定一个合成的消息渠道会话 - - 在同一个会话上发送一个普通跟进消息 - - 验证该跟进消息确实落入已绑定的 ACP 会话转录中 + - 就地绑定一个合成的消息渠道会话 + - 在同一会话上发送普通后续消息 + - 验证后续消息确实落入已绑定的 ACP 会话记录 - 启用: - `pnpm test:live src/gateway/gateway-acp-bind.live.test.ts` - `OPENCLAW_LIVE_ACP_BIND=1` - 默认值: - ACP 智能体:`claude` - - 合成渠道:Slack 私信风格的会话上下文 + - 合成渠道:类似 Slack 私信 的会话上下文 - ACP 后端:`acpx` - 覆盖项: - `OPENCLAW_LIVE_ACP_BIND_AGENT=claude` - `OPENCLAW_LIVE_ACP_BIND_AGENT=codex` - `OPENCLAW_LIVE_ACP_BIND_AGENT_COMMAND='npx -y @agentclientprotocol/claude-agent-acp@'` - 说明: - - 该测试通道使用 Gateway 网关 `chat.send` 接口,并带有仅管理员可用的合成 originating-route 字段,因此测试可以附加消息渠道上下文,而不必假装对外投递。 - - 当 `OPENCLAW_LIVE_ACP_BIND_AGENT_COMMAND` 未设置时,测试会使用内置 `acpx` 插件中的智能体注册表来选择 ACP harness 智能体。 + - 这个通道使用 Gateway 网关 `chat.send` 接口,并带有仅管理员可用的合成来源路由字段,这样测试就能附加消息渠道上下文,而无需假装对外投递。 + - 当未设置 `OPENCLAW_LIVE_ACP_BIND_AGENT_COMMAND` 时,测试会使用内置 `acpx` 插件的内建智能体注册表来选择 ACP 测试智能体。 示例: @@ -292,23 +332,23 @@ pnpm test:docker:live-acp-bind Docker 说明: - Docker 运行器位于 `scripts/test-live-acp-bind-docker.sh`。 -- 它会 source `~/.profile`,将匹配的 CLI 认证材料暂存到容器中,把 `acpx` 安装到可写 npm prefix,然后在缺失时安装所请求的实时 CLI(`@anthropic-ai/claude-code` 或 `@openai/codex`)。 -- 在 Docker 内,运行器会设置 `OPENCLAW_LIVE_ACP_BIND_ACPX_COMMAND=$HOME/.npm-global/bin/acpx`,这样 acpx 就能让来自已 source profile 的提供商环境变量继续对其子 harness CLI 可用。 +- 它会读取 `~/.profile`,将匹配的 CLI 身份验证材料暂存到容器中,把 `acpx` 安装到可写 npm 前缀,然后在缺失时安装请求的 live CLI(`@anthropic-ai/claude-code` 或 `@openai/codex`)。 +- 在 Docker 内部,运行器会设置 `OPENCLAW_LIVE_ACP_BIND_ACPX_COMMAND=$HOME/.npm-global/bin/acpx`,这样 acpx 就能保留从已读取 profile 中获得的提供商环境变量,以供子测试 CLI 使用。 -### 推荐的实时测试配方 +### 推荐的 live 配方 -范围窄、显式的 allowlist 最快,也最不容易出问题: +范围窄、明确的 allowlist 最快,也最不容易波动: -- 单模型,direct(无 Gateway 网关): +- 单模型,直接(无 Gateway 网关): - `OPENCLAW_LIVE_MODELS="openai/gpt-5.4" pnpm test:live src/agents/models.profiles.live.test.ts` -- 单模型,Gateway 网关烟雾测试: +- 单模型,Gateway 网关 冒烟测试: - `OPENCLAW_LIVE_GATEWAY_MODELS="openai/gpt-5.4" pnpm test:live src/gateway/gateway-models.profiles.live.test.ts` -- 跨多个提供商测试工具调用: +- 多个提供商上的工具调用: - `OPENCLAW_LIVE_GATEWAY_MODELS="openai/gpt-5.4,anthropic/claude-opus-4-6,google/gemini-3-flash-preview,zai/glm-4.7,minimax/MiniMax-M2.7" pnpm test:live src/gateway/gateway-models.profiles.live.test.ts` -- Google 聚焦(Gemini API key + Antigravity): +- 聚焦 Google(Gemini API key + Antigravity): - Gemini(API key):`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` @@ -316,14 +356,18 @@ Docker 说明: - `google/...` 使用 Gemini API(API key)。 - `google-antigravity/...` 使用 Antigravity OAuth bridge(Cloud Code Assist 风格的智能体端点)。 +- `google-gemini-cli/...` 使用你机器上的本地 Gemini CLI(单独的身份验证 + 工具行为差异)。 +- Gemini API 与 Gemini CLI: + - API:OpenClaw 通过 HTTP 调用 Google 托管的 Gemini API(API key / profile auth);这也是大多数用户提到 “Gemini” 时的含义。 + - CLI:OpenClaw 调用本地 `gemini` 二进制;它有自己的身份验证,并且行为可能不同(流式传输 / 工具支持 / 版本偏差)。 -## 实时:模型矩阵(我们覆盖什么) +## Live:模型矩阵(我们覆盖什么) -没有固定的“CI 模型列表”(实时测试是可选启用的),但下面这些是在拥有密钥的开发机上建议定期覆盖的**推荐**模型。 +这里没有固定的“CI 模型列表”(live 是可选加入的),但以下是建议在有密钥的开发机器上定期覆盖的**推荐**模型。 -### 现代烟雾测试集合(工具调用 + 图像) +### Modern 冒烟测试集(工具调用 + 图像) -这是我们期望持续可用的“常见模型”运行集: +这是我们预期应持续保持可用的“常用模型”运行: - OpenAI(非 Codex):`openai/gpt-5.4`(可选:`openai/gpt-5.4-mini`) - OpenAI Codex:`openai-codex/gpt-5.4` @@ -333,12 +377,12 @@ Docker 说明: - Z.AI(GLM):`zai/glm-4.7` - MiniMax:`minimax/MiniMax-M2.7` -运行带工具 + 图像的 Gateway 网关烟雾测试: +运行带工具 + 图像的 Gateway 网关 冒烟测试: `OPENCLAW_LIVE_GATEWAY_MODELS="openai/gpt-5.4,openai-codex/gpt-5.4,anthropic/claude-opus-4-6,google/gemini-3.1-pro-preview,google/gemini-3-flash-preview,google-antigravity/claude-opus-4-6-thinking,google-antigravity/gemini-3-flash,zai/glm-4.7,minimax/MiniMax-M2.7" pnpm test:live src/gateway/gateway-models.profiles.live.test.ts` ### 基线:工具调用(Read + 可选 Exec) -每个提供商家族至少选一个: +每个提供商系列至少选一个: - OpenAI:`openai/gpt-5.4`(或 `openai/gpt-5.4-mini`) - Anthropic:`anthropic/claude-opus-4-6`(或 `anthropic/claude-sonnet-4-6`) @@ -346,74 +390,74 @@ Docker 说明: - Z.AI(GLM):`zai/glm-4.7` - MiniMax:`minimax/MiniMax-M2.7` -可选附加覆盖(锦上添花): +可选的附加覆盖(有更好,没有也可以): -- xAI:`xai/grok-4`(或当前可用的最新版本) -- Mistral:`mistral/`…(选一个你已启用、支持工具的模型) +- xAI:`xai/grok-4`(或最新可用版本) +- Mistral:`mistral/`…(选择一个你已启用、具备 “tools” 能力的模型) - Cerebras:`cerebras/`…(如果你有访问权限) - LM Studio:`lmstudio/`…(本地;工具调用取决于 API 模式) -### Vision:图像发送(附件 → 多模态消息) +### 视觉:图像发送(附件 → 多模态消息) -在 `OPENCLAW_LIVE_GATEWAY_MODELS` 中至少包含一个支持图像的模型(Claude / Gemini / OpenAI 的支持视觉变体等),以触发 image probe。 +在 `OPENCLAW_LIVE_GATEWAY_MODELS` 中至少包含一个具备图像能力的模型(Claude / Gemini / OpenAI 支持视觉的变体等),以覆盖图像探测。 ### 聚合器 / 替代 Gateway 网关 -如果你启用了相应密钥,也支持通过以下方式测试: +如果你启用了相应密钥,我们也支持通过以下方式测试: -- OpenRouter:`openrouter/...`(数百个模型;使用 `openclaw models scan` 查找支持工具 + 图像的候选模型) -- OpenCode:`opencode/...` 用于 Zen,`opencode-go/...` 用于 Go(通过 `OPENCODE_API_KEY` / `OPENCODE_ZEN_API_KEY` 认证) +- OpenRouter:`openrouter/...`(数百个模型;使用 `openclaw models scan` 找出支持工具 + 图像的候选项) +- OpenCode:Zen 用 `opencode/...`,Go 用 `opencode-go/...`(通过 `OPENCODE_API_KEY` / `OPENCODE_ZEN_API_KEY` 身份验证) -你还可以将更多提供商纳入实时矩阵(如果你有凭证 / 配置): +你也可以在 live 矩阵中加入更多提供商(如果你有凭证 / 配置): -- 内置:`openai`、`openai-codex`、`anthropic`、`google`、`google-vertex`、`google-antigravity`、`zai`、`openrouter`、`opencode`、`opencode-go`、`xai`、`groq`、`cerebras`、`mistral`、`github-copilot` -- 通过 `models.providers`(自定义端点):`minimax`(云端 / API),以及任何兼容 OpenAI / Anthropic 的代理(LM Studio、vLLM、LiteLLM 等) +- 内置:`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 完全相同。实际含义如下: +Live 测试发现凭证的方式与 CLI 相同。实际含义如下: -- 如果 CLI 可用,实时测试也应能找到相同的密钥。 -- 如果实时测试提示“无凭证”,请像调试 `openclaw models list` / 模型选择那样进行调试。 +- 如果 CLI 能工作,live 测试通常也能找到相同的密钥。 +- 如果 live 测试提示“无凭证”,就像调试 `openclaw models list` / 模型选择那样去调试。 -- 每个智能体的认证 profile:`~/.openclaw/agents//agent/auth-profiles.json`(这就是实时测试里 “profile keys” 的含义) +- 按智能体划分的 auth profiles:`~/.openclaw/agents//agent/auth-profiles.json`(这就是 live 测试中 “profile keys” 的含义) - 配置:`~/.openclaw/openclaw.json`(或 `OPENCLAW_CONFIG_PATH`) -- 旧版状态目录:`~/.openclaw/credentials/`(存在时会复制进暂存的实时 home,但它不是主 profile-key 存储) -- 本地实时运行默认会将当前配置、每个智能体的 `auth-profiles.json` 文件、旧版 `credentials/` 以及受支持的外部 CLI 认证目录复制到临时测试 home 中;在该暂存配置中会去掉 `agents.*.workspace` / `agentDir` 路径覆盖,这样探测就不会落到你真实主机的工作区。 +- 旧版状态目录:`~/.openclaw/credentials/`(如存在,会复制进暂存的 live home,但它不是主 profile-key 存储) +- 默认情况下,live 本地运行会将当前活动配置、每个智能体的 `auth-profiles.json` 文件、旧版 `credentials/` 以及受支持的外部 CLI 身份验证目录复制到临时测试 home;暂存配置中的 `agents.*.workspace` / `agentDir` 路径覆盖会被去除,这样探测就不会落到你真实主机工作区上。 -如果你想依赖环境变量密钥(例如导出在你的 `~/.profile` 中),请在 `source ~/.profile` 后运行本地测试,或使用下方的 Docker 运行器(它们可以将 `~/.profile` 挂载到容器中)。 +如果你想依赖环境变量密钥(例如导出在你的 `~/.profile` 中),请在本地测试前运行 `source ~/.profile`,或者使用下面的 Docker 运行器(它们可以将 `~/.profile` 挂载到容器中)。 -## Deepgram 实时测试(音频转录) +## Deepgram live(音频转录) - 测试:`src/media-understanding/providers/deepgram/audio.live.test.ts` - 启用:`DEEPGRAM_API_KEY=... DEEPGRAM_LIVE_TEST=1 pnpm test:live src/media-understanding/providers/deepgram/audio.live.test.ts` -## BytePlus(国际版) 编码计划实时测试 +## BytePlus 编码计划 live - 测试:`src/agents/byteplus.live.test.ts` - 启用:`BYTEPLUS_API_KEY=... BYTEPLUS_LIVE_TEST=1 pnpm test:live src/agents/byteplus.live.test.ts` - 可选模型覆盖:`BYTEPLUS_CODING_MODEL=ark-code-latest` -## ComfyUI workflow 媒体实时测试 +## ComfyUI 工作流媒体 live - 测试:`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` 路径 - - 除非已配置 `models.providers.comfy.`,否则会跳过各项能力 - - 在修改 comfy workflow 提交、轮询、下载或插件注册后很有用 + - 覆盖内置 comfy 图像、视频和 `music_generate` 路径 + - 除非配置了 `models.providers.comfy.`,否则会跳过各项能力 + - 在修改 comfy 工作流提交、轮询、下载或插件注册后很有用 -## 图像生成实时测试 +## 图像生成 live - 测试:`src/image-generation/runtime.live.test.ts` - 命令:`pnpm test:live src/image-generation/runtime.live.test.ts` - 范围: - - 枚举每一个已注册的图像生成提供商插件 - - 在探测前从你的登录 shell(`~/.profile`)加载缺失的提供商环境变量 - - 默认优先使用实时 / 环境变量 API 密钥,而不是已存储的认证 profile,这样 `auth-profiles.json` 中过期的测试密钥不会掩盖真实的 shell 凭证 - - 跳过没有可用认证 / profile / 模型的提供商 + - 枚举每个已注册的图像生成提供商插件 + - 在探测前从你的登录 shell(`~/.profile`)中加载缺失的提供商环境变量 + - 默认优先使用 live / 环境变量 API 密钥,而不是已存储的 auth profiles,这样 `auth-profiles.json` 里的过期测试密钥就不会掩盖真实的 shell 凭证 + - 跳过没有可用 auth / profile / model 的提供商 - 通过共享运行时能力运行标准图像生成变体: - `google:flash-generate` - `google:pro-generate` @@ -422,179 +466,146 @@ Docker 说明: - 当前覆盖的内置提供商: - `openai` - `google` -- 可选缩小范围方式: +- 可选缩小范围: - `OPENCLAW_LIVE_IMAGE_GENERATION_PROVIDERS="openai,google"` - `OPENCLAW_LIVE_IMAGE_GENERATION_MODELS="openai/gpt-image-1,google/gemini-3.1-flash-image-preview"` - `OPENCLAW_LIVE_IMAGE_GENERATION_CASES="google:flash-generate,google:pro-edit"` -- 可选认证行为: - - `OPENCLAW_LIVE_REQUIRE_PROFILE_KEYS=1`:强制使用 profile 存储认证并忽略仅来自环境变量的覆盖 +- 可选身份验证行为: + - `OPENCLAW_LIVE_REQUIRE_PROFILE_KEYS=1` 强制使用 profile-store 身份验证并忽略仅环境变量的覆盖 -## 音乐生成实时测试 +## 音乐生成 live - 测试:`extensions/music-generation-providers.live.test.ts` - 启用:`OPENCLAW_LIVE_TEST=1 pnpm test:live -- extensions/music-generation-providers.live.test.ts` - 范围: - - 运行共享的内置音乐生成提供商路径 + - 覆盖共享内置 music-generation 提供商路径 - 当前覆盖 Google 和 MiniMax - - 在探测前从你的登录 shell(`~/.profile`)加载提供商环境变量 - - 跳过没有可用认证 / profile / 模型的提供商 -- 可选缩小范围方式: + - 在探测前从你的登录 shell(`~/.profile`)中加载提供商环境变量 + - 跳过没有可用 auth / profile / model 的提供商 +- 可选缩小范围: - `OPENCLAW_LIVE_MUSIC_GENERATION_PROVIDERS="google,minimax"` - `OPENCLAW_LIVE_MUSIC_GENERATION_MODELS="google/lyria-3-clip-preview,minimax/music-2.5+"` -## Docker 运行器(可选的“在 Linux 中可运行”检查) +## Docker 运行器(可选的“在 Linux 中可工作”检查) 这些 Docker 运行器分为两类: -- 实时模型运行器:`test:docker:live-models` 和 `test:docker:live-gateway` 只会在仓库 Docker 镜像中运行与各自匹配的 profile-key 实时测试文件(`src/agents/models.profiles.live.test.ts` 和 `src/gateway/gateway-models.profiles.live.test.ts`),并挂载你的本地配置目录与工作区(若已挂载,还会 source `~/.profile`)。对应的本地入口点是 `test:live:models-profiles` 和 `test:live:gateway-profiles`。 -- Docker 实时运行器默认使用更小的 smoke 上限,以便完整 Docker 扫描仍然切实可行: - `test:docker:live-models` 默认设置 `OPENCLAW_LIVE_MAX_MODELS=12`,而 +- Live 模型运行器:`test:docker:live-models` 和 `test:docker:live-gateway` 只会在仓库 Docker 镜像内运行各自匹配的 profile-key live 文件(`src/agents/models.profiles.live.test.ts` 和 `src/gateway/gateway-models.profiles.live.test.ts`),同时挂载你的本地配置目录和工作区(如果已挂载,也会读取 `~/.profile`)。对应的本地入口点是 `test:live:models-profiles` 和 `test:live:gateway-profiles`。 +- Docker live 运行器默认使用更小的冒烟测试上限,以便完整 Docker 扫描仍然具有可行性: + `test:docker:live-models` 默认设置 `OPENCLAW_LIVE_MAX_MODELS=12`,并且 `test:docker:live-gateway` 默认设置 `OPENCLAW_LIVE_GATEWAY_SMOKE=1`、 `OPENCLAW_LIVE_GATEWAY_MAX_MODELS=8`、 - `OPENCLAW_LIVE_GATEWAY_STEP_TIMEOUT_MS=45000` 和 + `OPENCLAW_LIVE_GATEWAY_STEP_TIMEOUT_MS=45000`,以及 `OPENCLAW_LIVE_GATEWAY_MODEL_TIMEOUT_MS=90000`。当你 - 明确想要更大的穷举扫描时,再覆盖这些环境变量。 -- `test:docker:all` 会先通过 `test:docker:live-build` 构建一次实时 Docker 镜像,然后在两个实时 Docker 通道中复用它。 -- 容器烟雾测试运行器:`test:docker:openwebui`、`test:docker:onboard`、`test:docker:gateway-network`、`test:docker:mcp-channels` 和 `test:docker:plugins` 会启动一个或多个真实容器,并验证更高层级的集成路径。 + 明确想进行更大的穷举扫描时,再覆盖这些环境变量。 +- `test:docker:all` 会先通过 `test:docker:live-build` 构建一次 live Docker 镜像,然后在两个 live Docker 通道中复用它。 +- 容器冒烟测试运行器:`test:docker:openwebui`、`test:docker:onboard`、`test:docker:gateway-network`、`test:docker:mcp-channels` 和 `test:docker:plugins` 会启动一个或多个真实容器,并验证更高层级的集成路径。 -实时模型 Docker 运行器还会仅绑定挂载所需的 CLI 认证 home(若运行未缩小范围,则挂载所有受支持项),然后在运行前将它们复制到容器 home 中,这样外部 CLI OAuth 就可以刷新令牌,而不会修改主机认证存储: +Live 模型 Docker 运行器还会只绑定挂载所需的 CLI auth home(若运行未缩小范围,则挂载所有受支持项),然后在运行前将它们复制到容器 home 中,这样外部 CLI OAuth 就可以刷新令牌,而不会修改主机 auth 存储: -- Direct models:`pnpm test:docker:live-models`(脚本:`scripts/test-live-models-docker.sh`) -- ACP bind 烟雾测试:`pnpm test:docker:live-acp-bind`(脚本:`scripts/test-live-acp-bind-docker.sh`) +- 直接模型:`pnpm test:docker:live-models`(脚本:`scripts/test-live-models-docker.sh`) +- ACP 绑定冒烟测试:`pnpm test:docker:live-acp-bind`(脚本:`scripts/test-live-acp-bind-docker.sh`) +- CLI 后端冒烟测试:`pnpm test:docker:live-cli-backend`(脚本:`scripts/test-live-cli-backend-docker.sh`) - Gateway 网关 + dev 智能体:`pnpm test:docker:live-gateway`(脚本:`scripts/test-live-gateway-models-docker.sh`) -- Open WebUI 实时烟雾测试:`pnpm test:docker:openwebui`(脚本:`scripts/e2e/openwebui-docker.sh`) +- Open WebUI live 冒烟测试:`pnpm test:docker:openwebui`(脚本:`scripts/e2e/openwebui-docker.sh`) - 新手引导向导(TTY,完整脚手架):`pnpm test:docker:onboard`(脚本:`scripts/e2e/onboard-docker.sh`) -- Gateway 网关网络(两个容器,WS 认证 + 健康检查):`pnpm test:docker:gateway-network`(脚本:`scripts/e2e/gateway-network-docker.sh`) -- MCP 渠道 bridge(带种子数据的 Gateway 网关 + stdio bridge + 原始 Claude notification-frame 烟雾测试):`pnpm test:docker:mcp-channels`(脚本:`scripts/e2e/mcp-channels-docker.sh`) -- 插件(安装烟雾测试 + `/plugin` 别名 + Claude bundle 重启语义):`pnpm test:docker:plugins`(脚本:`scripts/e2e/plugins-docker.sh`) +- Gateway 网关 网络(两个容器、WS 身份验证 + 健康检查):`pnpm test:docker:gateway-network`(脚本:`scripts/e2e/gateway-network-docker.sh`) +- MCP 渠道桥接(已播种的 Gateway 网关 + stdio bridge + 原始 Claude notification-frame 冒烟测试):`pnpm test:docker:mcp-channels`(脚本:`scripts/e2e/mcp-channels-docker.sh`) +- 插件(安装冒烟测试 + `/plugin` 别名 + Claude bundle 重启语义):`pnpm test:docker:plugins`(脚本:`scripts/e2e/plugins-docker.sh`) -实时模型 Docker 运行器还会将当前 checkout 以只读方式绑定挂载, -并将其暂存到容器内的临时工作目录中。这样可以在保持运行时镜像 -精简的同时,依然针对你当前本地源码 / 配置准确运行 Vitest。 -暂存步骤会跳过大型本地专用缓存和应用构建输出,例如 -`.pnpm-store`、`.worktrees`、`__openclaw_vitest__`,以及应用本地 `.build` 或 -Gradle 输出目录,因此 Docker 实时运行不会花几分钟去复制 -与机器相关的产物。 -它们还会设置 `OPENCLAW_SKIP_CHANNELS=1`,因此 Gateway 网关实时探测不会在容器中启动 -真实 Telegram / Discord / 等渠道 worker。 -`test:docker:live-models` 仍然运行 `pnpm test:live`,因此在你需要缩小范围 -或从该 Docker 通道中排除 Gateway 网关实时覆盖时,也请一并传入 -`OPENCLAW_LIVE_GATEWAY_*`。 -`test:docker:openwebui` 是一个更高层级的兼容性烟雾测试:它会启动一个 -启用了 OpenAI 兼容 HTTP 端点的 OpenClaw Gateway 网关容器, -再针对该 Gateway 网关启动一个固定版本的 Open WebUI 容器,通过 -Open WebUI 完成登录,验证 `/api/models` 暴露 `openclaw/default`,然后通过 -Open WebUI 的 `/api/chat/completions` 代理发送一次真实聊天请求。 -第一次运行可能会明显更慢,因为 Docker 可能需要拉取 -Open WebUI 镜像,而 Open WebUI 也可能需要完成自身冷启动设置。 -该通道需要一个可用的实时模型密钥,而 `OPENCLAW_PROFILE_FILE` -(默认 `~/.profile`)是在 Docker 化运行中提供该密钥的主要方式。 -成功运行会打印一个小型 JSON 载荷,例如 `{ "ok": true, "model": -"openclaw/default", ... }`。 -`test:docker:mcp-channels` 刻意保持确定性,不需要 -真实的 Telegram、Discord 或 iMessage 账号。它会启动一个带种子数据的 Gateway 网关 -容器,再启动第二个容器来运行 `openclaw mcp serve`,然后 -验证路由后的会话发现、转录读取、附件元数据、 -实时事件队列行为、出站发送路由,以及 Claude 风格的渠道 + -权限通知是否通过真实 stdio MCP bridge 正常工作。通知检查 -会直接检查原始 stdio MCP 帧,因此这个烟雾测试验证的是 -bridge 实际发出了什么,而不只是某个特定客户端 SDK 恰好暴露了什么。 +Live 模型 Docker 运行器还会以只读方式绑定挂载当前检出内容,并在容器内将其暂存到临时 workdir 中。这能让运行时镜像保持精简,同时仍然针对你本地的确切源码 / 配置运行 Vitest。暂存步骤会跳过大型本地专用缓存和应用构建产物,例如 `.pnpm-store`、`.worktrees`、`__openclaw_vitest__`,以及应用本地 `.build` 或 Gradle 输出目录,这样 Docker live 运行就不会花数分钟复制机器专属产物。它们还会设置 `OPENCLAW_SKIP_CHANNELS=1`,因此 Gateway 网关 live 探测不会在容器里启动真实的 Telegram / Discord / 等渠道 worker。`test:docker:live-models` 仍然运行 `pnpm test:live`,因此当你需要缩小或排除该 Docker 通道中的 Gateway 网关 live 覆盖时,也要一并传入 `OPENCLAW_LIVE_GATEWAY_*`。`test:docker:openwebui` 是一个更高层级的兼容性冒烟测试:它会启动一个启用了 OpenAI 兼容 HTTP 端点的 OpenClaw Gateway 网关 容器,启动一个指向该 Gateway 网关 的固定版 Open WebUI 容器,通过 Open WebUI 完成登录,验证 `/api/models` 暴露了 `openclaw/default`,然后通过 Open WebUI 的 `/api/chat/completions` 代理发送一条真实聊天请求。首次运行可能明显更慢,因为 Docker 可能需要拉取 Open WebUI 镜像,而 Open WebUI 也可能需要完成自身的冷启动设置。这个通道需要一个可用的 live 模型密钥,而 `OPENCLAW_PROFILE_FILE`(默认 `~/.profile`)是在 Docker 化运行中提供它的主要方式。成功运行会打印一个小型 JSON 负载,例如 `{ "ok": true, "model": "openclaw/default", ... }`。`test:docker:mcp-channels` 刻意保持确定性,不需要真实的 Telegram、Discord 或 iMessage 账号。它会启动一个已播种的 Gateway 网关 容器,启动第二个容器来运行 `openclaw mcp serve`,然后通过真实的 stdio MCP bridge 验证路由会话发现、记录读取、附件元数据、实时事件队列行为、出站发送路由,以及 Claude 风格的渠道 + 权限通知。通知检查会直接检查原始 stdio MCP 帧,因此该冒烟测试验证的是 bridge 实际发出了什么,而不只是某个特定客户端 SDK 恰好暴露了什么。 -手动 ACP 自然语言线程烟雾测试(非 CI): +手动 ACP 自然语言线程冒烟测试(不在 CI 中): - `bun scripts/dev/discord-acp-plain-language-smoke.ts --channel ...` -- 保留此脚本用于回归 / 调试工作流。后续可能仍会需要它来验证 ACP 线程路由,因此不要删除它。 +- 保留这个脚本以供回归 / 调试工作流使用。未来可能还需要它来验证 ACP 线程路由,因此不要删除它。 常用环境变量: - `OPENCLAW_CONFIG_DIR=...`(默认:`~/.openclaw`)挂载到 `/home/node/.openclaw` - `OPENCLAW_WORKSPACE_DIR=...`(默认:`~/.openclaw/workspace`)挂载到 `/home/node/.openclaw/workspace` -- `OPENCLAW_PROFILE_FILE=...`(默认:`~/.profile`)挂载到 `/home/node/.profile` 并在运行测试前 source -- `OPENCLAW_DOCKER_CLI_TOOLS_DIR=...`(默认:`~/.cache/openclaw/docker-cli-tools`)挂载到 `/home/node/.npm-global`,用于 Docker 内缓存 CLI 安装 -- `$HOME` 下的外部 CLI 认证目录 / 文件会以只读方式挂载到 `/host-auth...` 下,然后在测试开始前复制到 `/home/node/...` +- `OPENCLAW_PROFILE_FILE=...`(默认:`~/.profile`)挂载到 `/home/node/.profile`,并在运行测试前读取 +- `OPENCLAW_DOCKER_CLI_TOOLS_DIR=...`(默认:`~/.cache/openclaw/docker-cli-tools`)挂载到 `/home/node/.npm-global`,用于缓存 Docker 内部的 CLI 安装 +- `$HOME` 下的外部 CLI 身份验证目录 / 文件会以只读方式挂载到 `/host-auth...` 下,然后在测试开始前复制到 `/home/node/...` - 默认目录:`.minimax` - 默认文件:`~/.codex/auth.json`、`~/.codex/config.toml`、`.claude.json`、`~/.claude/.credentials.json`、`~/.claude/settings.json`、`~/.claude/settings.local.json` - - 缩小提供商范围的运行仅会挂载由 `OPENCLAW_LIVE_PROVIDERS` / `OPENCLAW_LIVE_GATEWAY_PROVIDERS` 推断出的必要目录 / 文件 - - 可手动覆盖为 `OPENCLAW_DOCKER_AUTH_DIRS=all`、`OPENCLAW_DOCKER_AUTH_DIRS=none`,或逗号列表,例如 `OPENCLAW_DOCKER_AUTH_DIRS=.claude,.codex` -- `OPENCLAW_LIVE_GATEWAY_MODELS=...` / `OPENCLAW_LIVE_MODELS=...`:缩小运行范围 -- `OPENCLAW_LIVE_GATEWAY_PROVIDERS=...` / `OPENCLAW_LIVE_PROVIDERS=...`:在容器内过滤提供商 -- `OPENCLAW_LIVE_REQUIRE_PROFILE_KEYS=1`:确保凭证来自 profile 存储(而非环境变量) -- `OPENCLAW_OPENWEBUI_MODEL=...`:选择由 Gateway 网关暴露给 Open WebUI 烟雾测试的模型 -- `OPENCLAW_OPENWEBUI_PROMPT=...`:覆盖 Open WebUI 烟雾测试使用的 nonce 检查提示词 -- `OPENWEBUI_IMAGE=...`:覆盖固定的 Open WebUI 镜像标签 + - 缩小提供商范围的运行只会挂载由 `OPENCLAW_LIVE_PROVIDERS` / `OPENCLAW_LIVE_GATEWAY_PROVIDERS` 推断出的所需目录 / 文件 + - 手动覆盖方式:`OPENCLAW_DOCKER_AUTH_DIRS=all`、`OPENCLAW_DOCKER_AUTH_DIRS=none`,或逗号列表,例如 `OPENCLAW_DOCKER_AUTH_DIRS=.claude,.codex` +- `OPENCLAW_LIVE_GATEWAY_MODELS=...` / `OPENCLAW_LIVE_MODELS=...` 缩小运行范围 +- `OPENCLAW_LIVE_GATEWAY_PROVIDERS=...` / `OPENCLAW_LIVE_PROVIDERS=...` 在容器内过滤提供商 +- `OPENCLAW_LIVE_REQUIRE_PROFILE_KEYS=1` 确保凭证来自 profile store(而不是环境变量) +- `OPENCLAW_OPENWEBUI_MODEL=...` 选择 Gateway 网关 为 Open WebUI 冒烟测试暴露的模型 +- `OPENCLAW_OPENWEBUI_PROMPT=...` 覆盖 Open WebUI 冒烟测试使用的 nonce 检查提示词 +- `OPENWEBUI_IMAGE=...` 覆盖固定的 Open WebUI 镜像标签 ## 文档完整性检查 -文档编辑后运行文档检查:`pnpm check:docs`。 -当你还需要完整的 Mintlify anchor 校验(包括页内标题检查)时,运行:`pnpm docs:check-links:anchors`。 +修改文档后运行文档检查:`pnpm check:docs`。 +如需同时检查页内标题锚点,运行完整 Mintlify 锚点验证:`pnpm docs:check-links:anchors`。 -## 离线回归(CI 安全) +## 离线回归测试(CI 安全) -这些是在不依赖真实提供商的情况下,针对“真实管线”的回归测试: +这些是不依赖真实提供商的“真实流水线”回归测试: -- Gateway 网关工具调用(mock OpenAI,真实 Gateway 网关 + 智能体循环):`src/gateway/gateway.test.ts`(用例:“runs a mock OpenAI tool call end-to-end via gateway agent loop”) -- Gateway 网关向导(WS `wizard.start` / `wizard.next`,强制写入 config + auth):`src/gateway/gateway.test.ts`(用例:“runs wizard over ws and writes auth token config”) +- Gateway 网关 工具调用(模拟 OpenAI,真实 Gateway 网关 + 智能体循环):`src/gateway/gateway.test.ts`(用例:“runs a mock OpenAI tool call end-to-end via gateway agent loop”) +- Gateway 网关 向导(WS `wizard.start` / `wizard.next`,写入配置 + 强制身份验证):`src/gateway/gateway.test.ts`(用例:“runs wizard over ws and writes auth token config”) ## 智能体可靠性评估(Skills) -我们已经有一些 CI 安全的测试,其行为类似“智能体可靠性评估”: +我们已经有一些 CI 安全的测试,它们的行为类似“智能体可靠性评估”: -- 通过真实 Gateway 网关 + 智能体循环进行 mock 工具调用(`src/gateway/gateway.test.ts`)。 -- 端到端向导流程,用于验证会话接线和配置效果(`src/gateway/gateway.test.ts`)。 +- 通过真实 Gateway 网关 + 智能体循环进行模拟工具调用(`src/gateway/gateway.test.ts`)。 +- 验证会话布线和配置效果的端到端向导流程(`src/gateway/gateway.test.ts`)。 -针对 Skills 目前仍缺少的内容(参见 [Skills](/zh-CN/tools/skills)): +对于 Skills,仍然缺少的内容(参见 [Skills](/zh-CN/tools/skills)): -- **决策能力:** 当 prompt 中列出了 skills 时,智能体是否会选择正确的 skill(或避开无关 skill)? -- **合规性:** 智能体是否会在使用前读取 `SKILL.md`,并遵循要求的步骤 / 参数? -- **工作流契约:** 断言工具顺序、会话历史延续和沙箱边界的多轮场景。 +- **决策能力:** 当提示词中列出 Skills 时,智能体是否会选择正确的技能(或避开无关技能)? +- **合规性:** 智能体是否会在使用前读取 `SKILL.md`,并遵守必需的步骤 / 参数? +- **工作流契约:** 断言工具顺序、会话历史延续以及沙箱边界的多轮场景。 未来的评估应优先保持确定性: -- 一个使用 mock 提供商的场景运行器,用于断言工具调用 + 顺序、skill 文件读取以及会话接线。 -- 一小组面向 skill 的场景(使用 vs 避免、gate、prompt 注入)。 -- 只有在 CI 安全套件就位后,才添加可选实时评估(显式启用、受环境变量控制)。 +- 一个使用模拟提供商的场景运行器,用于断言工具调用 + 顺序、技能文件读取和会话布线。 +- 一小组面向技能的场景测试(使用 vs 避免、门控、提示词注入)。 +- 只有在 CI 安全测试套件建立之后,才增加可选的 live 评估(选择加入、环境变量门控)。 ## 契约测试(插件和渠道形状) -契约测试用于验证每个已注册的插件和渠道都符合其 -接口契约。它们会遍历所有已发现的插件,并运行一组 -针对形状与行为的断言。默认的 `pnpm test` 单元通道会有意 -跳过这些共享接缝与烟雾测试文件;当你修改共享渠道或提供商表面时, -请显式运行契约测试命令。 +契约测试用于验证每个已注册插件和渠道都符合其接口契约。它们会遍历所有发现到的插件,并运行一组形状和行为断言。默认的 `pnpm test` 单元通道会刻意跳过这些共享接缝和冒烟测试文件;当你触及共享渠道或提供商接口时,请显式运行契约命令。 ### 命令 -- 所有契约测试:`pnpm test:contracts` -- 仅渠道契约测试:`pnpm test:contracts:channels` -- 仅提供商契约测试:`pnpm test:contracts:plugins` +- 所有契约:`pnpm test:contracts` +- 仅渠道契约:`pnpm test:contracts:channels` +- 仅提供商契约:`pnpm test:contracts:plugins` -### 渠道契约测试 +### 渠道契约 位于 `src/channels/plugins/contracts/*.contract.test.ts`: - **plugin** - 基本插件形状(id、名称、能力) - **setup** - 设置向导契约 - **session-binding** - 会话绑定行为 -- **outbound-payload** - 消息载荷结构 +- **outbound-payload** - 消息负载结构 - **inbound** - 入站消息处理 - **actions** - 渠道动作处理器 - **threading** - 线程 ID 处理 -- **directory** - 目录 / roster API +- **directory** - 目录 / 花名册 API - **group-policy** - 群组策略执行 -### 提供商状态契约测试 +### 提供商状态契约 位于 `src/plugins/contracts/*.contract.test.ts`。 - **status** - 渠道状态探测 - **registry** - 插件注册表形状 -### 提供商契约测试 +### 提供商契约 位于 `src/plugins/contracts/*.contract.test.ts`: -- **auth** - 认证流程契约 -- **auth-choice** - 认证方式 / 选择 +- **auth** - 身份验证流程契约 +- **auth-choice** - 身份验证选择 / 选择逻辑 - **catalog** - 模型目录 API - **discovery** - 插件发现 - **loader** - 插件加载 @@ -604,21 +615,21 @@ bridge 实际发出了什么,而不只是某个特定客户端 SDK 恰好暴 ### 何时运行 -- 修改 plugin-sdk 导出或子路径之后 -- 添加或修改某个渠道或提供商插件之后 -- 重构插件注册或发现逻辑之后 +- 在修改 plugin-sdk 导出或子路径之后 +- 在添加或修改渠道或提供商插件之后 +- 在重构插件注册或发现逻辑之后 契约测试会在 CI 中运行,不需要真实 API 密钥。 -## 添加回归测试(指导) +## 添加回归测试(指南) -当你修复了一个在实时测试中发现的提供商 / 模型问题时: +当你修复 live 中发现的提供商 / 模型问题时: -- 如果可能,添加一个 CI 安全的回归测试(mock / stub 提供商,或捕获精确的请求形状转换) -- 如果它天然只能通过实时测试捕获(限流、认证策略),就保持实时测试范围窄,并通过环境变量显式启用 -- 优先定位到能捕获此缺陷的最小层级: - - 提供商请求转换 / 回放缺陷 → direct models 测试 - - Gateway 网关会话 / 历史 / 工具管线缺陷 → Gateway 网关实时烟雾测试或 CI 安全的 Gateway 网关 mock 测试 -- SecretRef 遍历护栏: - - `src/secrets/exec-secret-ref-id-parity.test.ts` 会从注册表元数据(`listSecretTargetRegistryEntries()`)中为每个 SecretRef 类推导一个采样目标,然后断言遍历分段 exec id 会被拒绝。 - - 如果你在 `src/secrets/target-registry-data.ts` 中添加了新的 `includeInPlan` SecretRef 目标家族,请更新该测试中的 `classifyTargetClass`。该测试会故意在未分类目标 id 出现时失败,这样新类别就不会被悄悄跳过。 +- 如果可能,添加一个 CI 安全的回归测试(模拟 / 存根提供商,或捕获确切的请求形状转换) +- 如果它本质上只能通过 live 复现(限流、身份验证策略),让 live 测试保持范围小,并通过环境变量选择加入 +- 优先定位到能捕获该缺陷的最小层级: + - 提供商请求转换 / 重放缺陷 → 直接模型测试 + - Gateway 网关 会话 / 历史 / 工具流水线缺陷 → Gateway 网关 live 冒烟测试或 CI 安全的 Gateway 网关 模拟测试 +- SecretRef 遍历防护: + - `src/secrets/exec-secret-ref-id-parity.test.ts` 会从注册表元数据(`listSecretTargetRegistryEntries()`)中为每个 SecretRef 类派生一个示例目标,然后断言遍历段 exec id 会被拒绝。 + - 如果你在 `src/secrets/target-registry-data.ts` 中新增一个 `includeInPlan` SecretRef 目标族,请更新该测试中的 `classifyTargetClass`。该测试会在目标 id 未分类时故意失败,这样新类别就无法被悄悄跳过。 diff --git a/docs/zh-CN/plugins/architecture.md b/docs/zh-CN/plugins/architecture.md index db732e2d7..d8ba597dd 100644 --- a/docs/zh-CN/plugins/architecture.md +++ b/docs/zh-CN/plugins/architecture.md @@ -1,17 +1,17 @@ --- read_when: - - 构建或调试原生 OpenClaw 插件时 - - 理解插件能力模型或归属边界时 - - 处理插件加载流水线或注册表时 - - 实现提供商运行时钩子或渠道插件时 + - 构建或调试原生 OpenClaw 插件 + - 了解插件能力模型或归属边界 + - 处理插件加载流水线或注册表 + - 实现提供商运行时钩子或渠道插件 sidebarTitle: Internals -summary: 插件内部机制:能力模型、归属、契约、加载流水线和运行时辅助函数 +summary: 插件内部机制:能力模型、归属、契约、加载流水线和运行时辅助工具 title: 插件内部机制 x-i18n: - generated_at: "2026-04-06T12:35:22Z" + generated_at: "2026-04-06T12:45:34Z" model: gpt-5.4 provider: openai - source_hash: 44f8354fffab48f31dacc6b1c0e57ef35710d3312d8f79c0d56ae7e2a4530e8f + source_hash: b2f7f48bd5599b9897aa851fb25d501d9643d76f66084f5867b3866fec91cef6 source_path: plugins/architecture.md workflow: 15 --- @@ -22,127 +22,127 @@ x-i18n: 这是**深度架构参考**。如需实用指南,请参阅: - [安装和使用插件](/zh-CN/tools/plugin) — 用户指南 - [入门指南](/zh-CN/plugins/building-plugins) — 第一个插件教程 - - [渠道插件](/zh-CN/plugins/sdk-channel-plugins) — 构建消息渠道 - - [提供商插件](/zh-CN/plugins/sdk-provider-plugins) — 构建模型提供商 + - [渠道插件](/zh-CN/plugins/sdk-channel-plugins) — 构建一个消息渠道 + - [提供商插件](/zh-CN/plugins/sdk-provider-plugins) — 构建一个模型提供商 - [SDK 概览](/zh-CN/plugins/sdk-overview) — 导入映射和注册 API 本页介绍 OpenClaw 插件系统的内部架构。 -## 公共能力模型 +## 公开能力模型 -能力是 OpenClaw 内部公共的**原生插件**模型。每个原生 OpenClaw 插件都会针对一种或多种能力类型进行注册: +能力是 OpenClaw 内部公开的**原生插件**模型。每个原生 OpenClaw 插件都会针对一个或多个能力类型进行注册: -| 能力 | 注册方式 | 示例插件 | -| ---------------------- | ------------------------------------------------ | ------------------------------------ | -| 文本推理 | `api.registerProvider(...)` | `openai`, `anthropic` | -| 语音 | `api.registerSpeechProvider(...)` | `elevenlabs`, `microsoft` | -| 实时转写 | `api.registerRealtimeTranscriptionProvider(...)` | `openai` | -| 实时语音 | `api.registerRealtimeVoiceProvider(...)` | `openai` | -| 媒体理解 | `api.registerMediaUnderstandingProvider(...)` | `openai`, `google` | -| 图像生成 | `api.registerImageGenerationProvider(...)` | `openai`, `google`, `fal`, `minimax` | -| 音乐生成 | `api.registerMusicGenerationProvider(...)` | `google`, `minimax` | -| 视频生成 | `api.registerVideoGenerationProvider(...)` | `qwen` | -| Web 抓取 | `api.registerWebFetchProvider(...)` | `firecrawl` | -| Web 搜索 | `api.registerWebSearchProvider(...)` | `google` | -| 渠道 / 消息 | `api.registerChannel(...)` | `msteams`, `matrix` | +| 能力 | 注册方式 | 示例插件 | +| -------------------- | ------------------------------------------------ | ------------------------------------ | +| 文本推理 | `api.registerProvider(...)` | `openai`, `anthropic` | +| CLI 推理后端 | `api.registerCliBackend(...)` | `openai`, `anthropic` | +| 语音 | `api.registerSpeechProvider(...)` | `elevenlabs`, `microsoft` | +| 实时转写 | `api.registerRealtimeTranscriptionProvider(...)` | `openai` | +| 实时语音 | `api.registerRealtimeVoiceProvider(...)` | `openai` | +| 媒体理解 | `api.registerMediaUnderstandingProvider(...)` | `openai`, `google` | +| 图像生成 | `api.registerImageGenerationProvider(...)` | `openai`, `google`, `fal`, `minimax` | +| 音乐生成 | `api.registerMusicGenerationProvider(...)` | `google`, `minimax` | +| 视频生成 | `api.registerVideoGenerationProvider(...)` | `qwen` | +| Web 抓取 | `api.registerWebFetchProvider(...)` | `firecrawl` | +| Web 搜索 | `api.registerWebSearchProvider(...)` | `google` | +| 渠道 / 消息传递 | `api.registerChannel(...)` | `msteams`, `matrix` | -一个注册了零个能力、但提供钩子、工具或服务的插件,是**仅旧版钩子**插件。该模式目前仍然被完全支持。 +一个注册了零个能力、但提供钩子、工具或服务的插件,被称为**仅旧版 hook** 插件。这种模式仍然得到完整支持。 ### 外部兼容性立场 -能力模型已经在核心中落地,并已被当前的内置 / 原生插件使用,但外部插件兼容性仍需要比“已导出,因此已冻结”更严格的标准。 +能力模型已经落地到 core 中,并且当前已用于内置 / 原生插件,但外部插件兼容性仍需要比“它已导出,因此已冻结”更严格的标准。 当前指导如下: -- **现有外部插件:** 保持基于钩子的集成正常工作;将其视为兼容性基线 -- **新的内置 / 原生插件:** 优先使用显式能力注册,而不是供应商特定的深层访问或新的纯钩子设计 -- **采用能力注册的外部插件:** 允许,但除非文档明确将某个契约标记为稳定,否则应将能力专用辅助接口视为仍在演进中 +- **现有外部插件:** 保持基于 hook 的集成可用;将其视为兼容性的基准线 +- **新的内置 / 原生插件:** 优先使用显式能力注册,而不是特定厂商的直接深入访问或新的仅 hook 设计 +- **采用能力注册的外部插件:** 可以这样做,但在文档未明确将某个契约标记为稳定前,应将能力专用辅助工具接口视为仍在演进中 实用规则: - 能力注册 API 是预期的发展方向 -- 在过渡期间,对外部插件来说,旧版钩子仍是最安全、最不易破坏的路径 -- 并非所有导出的辅助子路径都同等稳定;优先使用文档说明的狭义契约,而不是偶然暴露的辅助导出 +- 在过渡期间,旧版 hooks 仍然是外部插件最安全、最不易破坏的路径 +- 并非所有已导出的辅助工具子路径都同等稳定;优先使用文档记录的精简契约,而不是顺带暴露的辅助导出 ### 插件形态 -OpenClaw 会根据插件的实际注册行为,而不是仅根据静态元数据,将每个已加载插件归类为一种形态: +OpenClaw 会根据每个已加载插件的实际注册行为(而不仅是静态元数据)将其分类为以下形态之一: -- **plain-capability** -- 恰好注册一种能力类型(例如仅提供商插件 `mistral`) -- **hybrid-capability** -- 注册多种能力类型(例如 `openai` 拥有文本推理、语音、媒体理解和图像生成) -- **hook-only** -- 仅注册钩子(类型化或自定义),不注册能力、工具、命令或服务 -- **non-capability** -- 注册工具、命令、服务或路由,但不注册能力 +- **plain-capability** -- 只注册一种能力类型(例如像 `mistral` 这样的仅提供商插件) +- **hybrid-capability** -- 注册多种能力类型(例如 `openai` 同时拥有文本推理、语音、媒体理解和图像生成) +- **hook-only** -- 仅注册 hooks(类型化或自定义),没有能力、工具、命令或服务 +- **non-capability** -- 注册工具、命令、服务或路由,但不注册任何能力 -使用 `openclaw plugins inspect ` 可查看插件的形态和能力细分。详情请参阅 [CLI 参考](/cli/plugins#inspect)。 +使用 `openclaw plugins inspect ` 可查看插件的形态和能力拆分。详见 [CLI 参考](/cli/plugins#inspect)。 -### 旧版钩子 +### 旧版 hooks -`before_agent_start` 钩子仍作为仅钩子插件的兼容路径受到支持。现实中的旧版插件仍依赖它。 +`before_agent_start` hook 仍作为仅 hook 插件的兼容路径继续受支持。现实中仍有旧版插件依赖它。 方向如下: -- 保持其正常工作 -- 将其文档标注为旧版 -- 模型 / 提供商覆盖工作优先使用 `before_model_resolve` -- 提示词变更工作优先使用 `before_prompt_build` -- 仅在真实使用量下降且夹具覆盖证明迁移安全后再移除 +- 保持它可用 +- 将其文档标记为旧版 +- 对模型 / 提供商覆盖工作,优先使用 `before_model_resolve` +- 对提示词变更工作,优先使用 `before_prompt_build` +- 只有在真实使用量下降,并且 fixture 覆盖证明迁移安全后,才考虑移除 ### 兼容性信号 当你运行 `openclaw doctor` 或 `openclaw plugins inspect ` 时,可能会看到以下标签之一: -| 信号 | 含义 | -| -------------------------- | ------------------------------------------------------------ | -| **config valid** | 配置解析正常且插件可解析 | -| **compatibility advisory** | 插件使用受支持但较旧的模式(例如 `hook-only`) | -| **legacy warning** | 插件使用 `before_agent_start`,该项已弃用 | -| **hard error** | 配置无效或插件加载失败 | +| 信号 | 含义 | +| ------------------------ | ---------------------------------------------------------- | +| **config valid** | 配置解析正常,插件可成功解析 | +| **compatibility advisory** | 插件使用受支持但较旧的模式(例如 `hook-only`) | +| **legacy warning** | 插件使用了 `before_agent_start`,该用法已弃用 | +| **hard error** | 配置无效或插件加载失败 | -目前,`hook-only` 和 `before_agent_start` 都不会导致你的插件损坏 —— `hook-only` 只是建议提示,而 `before_agent_start` 只会触发警告。这些信号也会显示在 `openclaw status --all` 和 `openclaw plugins doctor` 中。 +`hook-only` 和 `before_agent_start` 目前都不会导致你的插件中断——`hook-only` 只是提示性信息,而 `before_agent_start` 只会触发警告。这些信号也会显示在 `openclaw status --all` 和 `openclaw plugins doctor` 中。 ## 架构概览 -OpenClaw 的插件系统包含四层: +OpenClaw 的插件系统有四层: 1. **清单 + 发现** - OpenClaw 会从已配置路径、工作区根目录、全局扩展根目录和内置扩展中查找候选插件。发现阶段会先读取原生 `openclaw.plugin.json` 清单以及受支持的 bundle 清单。 -2. **启用 + 验证** - 核心会决定一个已发现插件是启用、禁用、阻止,还是被选中用于某个独占槽位(例如内存)。 + OpenClaw 会从配置路径、工作区根目录、全局扩展根目录以及内置扩展中查找候选插件。发现过程会先读取原生 `openclaw.plugin.json` 清单以及受支持的 bundle 清单。 +2. **启用 + 校验** + core 会决定某个已发现插件是启用、禁用、阻止,还是被选中用于某个独占槽位(例如 memory)。 3. **运行时加载** - 原生 OpenClaw 插件通过 jiti 在进程内加载,并将能力注册到中央注册表。兼容 bundle 会被规范化为注册表记录,而无需导入运行时代码。 + 原生 OpenClaw 插件会通过 jiti 在进程内加载,并将能力注册到中央注册表中。兼容 bundle 会被规范化为注册表记录,而无需导入运行时代码。 4. **接口消费** - OpenClaw 的其余部分读取注册表,以暴露工具、渠道、提供商设置、钩子、HTTP 路由、CLI 命令和服务。 + OpenClaw 的其余部分会读取注册表,以暴露工具、渠道、提供商设置、hooks、HTTP 路由、CLI 命令和服务。 -对于插件 CLI,根命令发现特别分为两个阶段: +对于插件 CLI 而言,根命令发现被拆分为两个阶段: -- 解析时元数据来自 `registerCli(..., { descriptors: [...] })` -- 真正的插件 CLI 模块可保持惰性,并在首次调用时注册 +- 解析阶段元数据来自 `registerCli(..., { descriptors: [...] })` +- 真正的插件 CLI 模块可以保持惰性加载,并在首次调用时注册 -这样既能将插件拥有的 CLI 代码保留在插件内部,又能让 OpenClaw 在解析前保留根命令名称。 +这样既能让插件自有的 CLI 代码留在插件内部,又能让 OpenClaw 在解析前预留根命令名称。 重要的设计边界: -- 发现 + 配置验证应仅依赖**清单 / 模式元数据**完成,而不执行插件代码 +- 发现 + 配置校验应当基于**清单 / schema 元数据**完成,而无需执行插件代码 - 原生运行时行为来自插件模块的 `register(api)` 路径 -这种拆分使 OpenClaw 能够在完整运行时尚未激活前,完成配置验证、解释缺失 / 禁用插件,并构建 UI / 模式提示。 +这种分离让 OpenClaw 能在完整运行时尚未激活前,就校验配置、解释缺失 / 禁用插件,并构建 UI / schema 提示。 -### 渠道插件与共享 message 工具 +### 渠道插件与共享消息工具 -渠道插件在常规聊天操作中不需要注册单独的发送 / 编辑 / 反应工具。OpenClaw 在核心中保留一个共享的 `message` 工具,而渠道插件负责其背后的渠道特定发现与执行。 +对于常规聊天操作,渠道插件不需要单独注册发送 / 编辑 / 响应工具。OpenClaw 在 core 中保留一个共享的 `message` 工具,而渠道插件负责其背后的渠道专属发现和执行。 当前边界如下: -- 核心拥有共享 `message` 工具宿主、提示词接线、会话 / 线程簿记以及执行分派 -- 渠道插件拥有作用域动作发现、能力发现,以及所有渠道特定的模式片段 -- 渠道插件拥有提供商特定的会话对话语法,例如会话 id 如何编码线程 id 或从父会话继承 -- 渠道插件通过其动作适配器执行最终动作 +- core 负责共享 `message` 工具宿主、提示词接线、会话 / 线程记录,以及执行分发 +- 渠道插件负责作用域操作发现、能力发现,以及任何渠道专属 schema 片段 +- 渠道插件负责提供商专属的会话会话语法,例如会话 id 如何编码线程 id,或如何从父会话继承 +- 渠道插件通过其 action adapter 执行最终操作 -对于渠道插件,SDK 接口为 -`ChannelMessageActionAdapter.describeMessageTool(...)`。这个统一发现调用允许插件一起返回其可见动作、能力和模式贡献,避免这些部分彼此漂移。 +对于渠道插件,SDK 接口为 `ChannelMessageActionAdapter.describeMessageTool(...)`。这个统一发现调用让插件可以将其可见操作、能力和 schema 扩展一起返回,从而避免这些部分彼此漂移。 -核心会将运行时作用域传入该发现步骤。重要字段包括: +core 会在发现步骤中传入运行时作用域。重要字段包括: - `accountId` - `currentChannelId` @@ -151,87 +151,87 @@ OpenClaw 的插件系统包含四层: - `sessionKey` - `sessionId` - `agentId` -- 可信入站 `requesterSenderId` +- 受信任入站 `requesterSenderId` -这对于上下文敏感型插件很重要。一个渠道可以根据当前活跃账户、当前房间 / 线程 / 消息或可信请求者身份,隐藏或暴露消息动作,而无需在核心 `message` 工具中硬编码渠道特定分支。 +这对于上下文敏感型插件很重要。渠道可以基于当前账户、当前房间 / 线程 / 消息,或受信任的请求方身份,来隐藏或暴露消息操作,而不需要在 core `message` 工具中硬编码渠道专属分支。 -这也是为什么嵌入式运行器路由变更仍然属于插件工作:运行器负责将当前聊天 / 会话身份转发到插件发现边界,以便共享 `message` 工具为当前轮次暴露正确的渠道拥有接口。 +这也是为什么嵌入式 runner 路由变更仍然属于插件工作:runner 负责将当前聊天 / 会话身份转发到插件发现边界,使共享 `message` 工具在当前轮次暴露正确的渠道自有接口。 -对于渠道拥有的执行辅助函数,内置插件应将执行运行时保留在自己的扩展模块中。核心不再在 `src/agents/tools` 下拥有 Discord、Slack、Telegram 或 WhatsApp 的消息动作运行时。我们不会发布单独的 `plugin-sdk/*-action-runtime` 子路径,内置插件应直接从自己的扩展模块导入本地运行时代码。 +对于渠道自有的执行辅助工具,内置插件应将执行运行时保留在它们自己的扩展模块中。core 不再拥有位于 `src/agents/tools` 下的 Discord、Slack、Telegram 或 WhatsApp 消息操作运行时。我们不会发布单独的 `plugin-sdk/*-action-runtime` 子路径,内置插件应直接从其扩展自有模块导入本地运行时代码。 -同样的边界也适用于一般的提供商命名 SDK 接缝:核心不应导入 Slack、Discord、Signal、WhatsApp 或类似扩展的渠道特定便捷 barrel。如果核心需要某种行为,应当消费该内置插件自己的 `api.ts` / `runtime-api.ts` barrel,或将该需求提升为共享 SDK 中的狭义通用能力。 +同样的边界也适用于一般意义上的提供商命名 SDK 接缝:core 不应导入面向 Slack、Discord、Signal、WhatsApp 或类似扩展的渠道专用便捷 barrel。如果 core 需要某种行为,要么消费内置插件自己的 `api.ts` / `runtime-api.ts` barrel,要么将该需求提升为共享 SDK 中一个精简的通用能力。 -对于投票,存在两条执行路径: +对于投票,当前有两条执行路径: -- `outbound.sendPoll` 是适用于符合通用投票模型渠道的共享基线 -- `actions.handleAction("poll")` 是用于渠道特定投票语义或额外投票参数的首选路径 +- `outbound.sendPoll` 是适用于符合通用投票模型的渠道的共享基线 +- `actions.handleAction("poll")` 是渠道专属投票语义或额外投票参数的首选路径 -核心现在会在插件投票分派拒绝该动作之后,才推迟执行共享投票解析,因此插件拥有的投票处理器可以接受渠道特定投票字段,而不会先被通用投票解析器拦住。 +现在,core 会先尝试插件投票分发,只有在插件拒绝处理该操作后,才会回退到共享投票解析。这使插件自有的投票处理器能够接受渠道专属投票字段,而不会先被通用投票解析器阻挡。 完整启动顺序请参阅[加载流水线](#load-pipeline)。 ## 能力归属模型 -OpenClaw 将一个原生插件视为**公司**或**功能**的归属边界,而不是无关集成的大杂烩。 +OpenClaw 将原生插件视为某个**公司**或某个**功能**的归属边界,而不是一堆无关集成的杂项集合。 这意味着: -- 一个公司插件通常应拥有该公司的所有面向 OpenClaw 的接口 -- 一个功能插件通常应拥有它所引入功能的完整接口 -- 渠道应消费共享核心能力,而不是临时重新实现提供商行为 +- 一个公司插件通常应拥有该公司的所有 OpenClaw 面向接口 +- 一个功能插件通常应拥有其引入的完整功能接口 +- 渠道应消费共享 core 能力,而不是临时重复实现提供商行为 -例如: +示例: -- 内置 `openai` 插件拥有 OpenAI 模型提供商行为,以及 OpenAI 语音 + 实时语音 + 媒体理解 + 图像生成行为 +- 内置 `openai` 插件拥有 OpenAI 模型提供商行为,以及 OpenAI 的语音 + 实时语音 + 媒体理解 + 图像生成行为 - 内置 `elevenlabs` 插件拥有 ElevenLabs 语音行为 - 内置 `microsoft` 插件拥有 Microsoft 语音行为 -- 内置 `google` 插件拥有 Google 模型提供商行为,以及 Google 媒体理解 + 图像生成 + Web 搜索行为 +- 内置 `google` 插件拥有 Google 模型提供商行为,以及 Google 的媒体理解 + 图像生成 + Web 搜索行为 - 内置 `firecrawl` 插件拥有 Firecrawl Web 抓取行为 -- 内置 `minimax`、`mistral`、`moonshot` 和 `zai` 插件拥有它们的媒体理解后端 +- 内置 `minimax`、`mistral`、`moonshot` 和 `zai` 插件拥有它们各自的媒体理解后端 - 内置 `qwen` 插件拥有 Qwen 文本提供商行为,以及媒体理解和视频生成行为 -- `voice-call` 插件是一个功能插件:它拥有通话传输、工具、CLI、路由和 Twilio 媒体流桥接,但它会消费共享的语音、实时转写和实时语音能力,而不是直接导入供应商插件 +- `voice-call` 插件是一个功能插件:它拥有呼叫传输、工具、CLI、路由和 Twilio 媒体流桥接,但它消费共享的语音以及实时转写和实时语音能力,而不是直接导入厂商插件 预期的最终状态是: -- OpenAI 存在于一个插件中,即使它横跨文本模型、语音、图像以及未来的视频 -- 其他供应商也可以用同样方式管理其自己的接口范围 -- 渠道不关心哪个供应商插件拥有该提供商;它们消费的是核心暴露的共享能力契约 +- 即使 OpenAI 同时覆盖文本模型、语音、图像和未来的视频,它也只存在于一个插件中 +- 其他厂商也可以为自己的接口范围采用同样方式 +- 渠道不需要关心哪个厂商插件拥有该提供商;它们只消费 core 暴露的共享能力契约 这是关键区别: -- **插件** = 归属边界 -- **能力** = 多个插件可以实现或消费的核心契约 +- **plugin** = 归属边界 +- **capability** = 多个插件都可以实现或消费的 core 契约 -因此,如果 OpenClaw 添加视频这样的新领域,首要问题不是“哪个提供商应硬编码视频处理?”而是“核心的视频能力契约是什么?”一旦该契约存在,供应商插件就可以针对它注册,渠道 / 功能插件也可以消费它。 +因此,如果 OpenClaw 新增一个如视频这样的领域,第一个问题不应该是“哪个提供商应硬编码视频处理?”而应该是“core 的视频能力契约是什么?”一旦该契约存在,厂商插件就可以针对它进行注册,渠道 / 功能插件也可以消费它。 -如果该能力尚不存在,正确做法通常是: +如果该能力尚不存在,通常正确的做法是: -1. 在核心中定义缺失的能力 +1. 在 core 中定义缺失的能力 2. 通过插件 API / 运行时以类型化方式暴露它 3. 让渠道 / 功能围绕该能力接线 -4. 让供应商插件注册其实现 +4. 允许厂商插件注册实现 -这样能保持归属关系明确,同时避免核心行为依赖某个单一供应商或某条一次性的插件特定代码路径。 +这样可以在保持明确归属的同时,避免 core 行为依赖某个单一厂商或某条一次性的插件专用代码路径。 ### 能力分层 -在决定代码归属位置时,可使用以下思维模型: +在决定代码归属位置时,请使用以下思维模型: -- **核心能力层**:共享编排、策略、回退、配置合并规则、交付语义和类型契约 -- **供应商插件层**:供应商特定 API、认证、模型目录、语音合成、图像生成、未来视频后端、使用量端点 -- **渠道 / 功能插件层**:Slack / Discord / voice-call 等集成,它们消费核心能力并在某个接口上呈现出来 +- **core 能力层**:共享编排、策略、回退、配置合并规则、传递语义和类型化契约 +- **厂商插件层**:厂商专属 API、认证、模型目录、语音合成、图像生成、未来的视频后端、用量端点 +- **渠道 / 功能插件层**:Slack / Discord / voice-call 等集成,它们消费 core 能力并在某个接口上呈现出来 -例如,TTS 遵循如下结构: +例如,TTS 采用以下形态: -- 核心拥有回复时 TTS 策略、回退顺序、偏好设置和渠道交付 +- core 拥有回复时 TTS 策略、回退顺序、偏好和渠道传递 - `openai`、`elevenlabs` 和 `microsoft` 拥有合成实现 -- `voice-call` 消费电话 TTS 运行时辅助函数 +- `voice-call` 消费电话场景的 TTS 运行时辅助工具 -未来能力也应优先采用相同模式。 +未来的能力也应优先遵循相同模式。 ### 多能力公司插件示例 -从外部看,一个公司插件应当具有内聚性。如果 OpenClaw 针对模型、语音、实时转写、实时语音、媒体理解、图像生成、视频生成、Web 抓取和 Web 搜索都有共享契约,那么一个供应商就可以在一个地方拥有它的全部接口: +一个公司插件从外部看应当是内聚的。如果 OpenClaw 对模型、语音、实时转写、实时语音、媒体理解、图像生成、视频生成、Web 抓取和 Web 搜索都有共享契约,那么某个厂商就可以在一个地方拥有其全部接口: ```ts import type { OpenClawPluginDefinition } from "openclaw/plugin-sdk/plugin-entry"; @@ -285,185 +285,177 @@ const plugin: OpenClawPluginDefinition = { export default plugin; ``` -重要的不是辅助函数名称是否完全一致,而是整体结构: +关键不在于精确的辅助工具名称,而在于其结构: -- 一个插件拥有供应商接口 -- 核心仍然拥有能力契约 -- 渠道和功能插件消费 `api.runtime.*` 辅助函数,而不是供应商代码 +- 一个插件拥有该厂商接口 +- core 仍然拥有能力契约 +- 渠道和功能插件消费 `api.runtime.*` 辅助工具,而不是厂商代码 - 契约测试可以断言插件注册了它声称拥有的能力 ### 能力示例:视频理解 -OpenClaw 已经将图像 / 音频 / 视频理解视为一种共享能力。相同的归属模型也适用于这里: +OpenClaw 已将图像 / 音频 / 视频理解视为一种共享能力。同样的归属模型也适用于这里: -1. 核心定义媒体理解契约 -2. 供应商插件按适用情况注册 `describeImage`、`transcribeAudio` 和 `describeVideo` -3. 渠道和功能插件消费共享核心行为,而不是直接接线到供应商代码 +1. core 定义媒体理解契约 +2. 厂商插件按需注册 `describeImage`、`transcribeAudio` 和 `describeVideo` +3. 渠道和功能插件消费共享 core 行为,而不是直接接线到厂商代码 -这样可以避免将某个提供商的视频假设烘焙进核心。插件拥有供应商接口;核心拥有能力契约和回退行为。 +这样可以避免把某个提供商对视频的假设固化进 core。插件拥有厂商接口;core 拥有能力契约和回退行为。 -视频生成已经采用相同顺序:核心拥有类型化能力契约和运行时辅助函数,供应商插件则针对它注册 `api.registerVideoGenerationProvider(...)` 实现。 +视频生成已经使用同样的顺序:core 拥有类型化能力契约和运行时辅助工具,厂商插件针对其注册 `api.registerVideoGenerationProvider(...)` 实现。 -需要具体的发布检查清单吗?请参阅 -[能力扩展手册](/zh-CN/plugins/architecture)。 +需要一个具体的发布清单?请参阅[能力扩展手册](/zh-CN/plugins/architecture)。 -## 契约与强制机制 +## 契约与约束执行 -插件 API 接口被有意设计为类型化并集中于 -`OpenClawPluginApi`。这个契约定义了受支持的注册点,以及插件可依赖的运行时辅助函数。 +插件 API 接口被有意设计为类型化并集中在 `OpenClawPluginApi` 中。该契约定义了受支持的注册点,以及插件可以依赖的运行时辅助工具。 这很重要,因为: -- 插件作者拥有一个稳定的内部标准 -- 核心可以拒绝重复归属,例如两个插件注册相同的 provider id -- 启动过程可以为错误注册暴露可执行诊断 -- 契约测试可以强制执行内置插件归属并防止静默漂移 +- 插件作者获得一个稳定的内部标准 +- core 可以拒绝重复归属,例如两个插件注册同一个 provider id +- 启动时可以为格式错误的注册提供可执行的诊断信息 +- 契约测试可以约束内置插件归属并防止静默漂移 -存在两层强制机制: +存在两层约束执行: -1. **运行时注册强制** - 插件注册表在插件加载时验证注册内容。例如:重复的 provider id、重复的语音提供商 id,以及格式错误的注册,都会生成插件诊断,而不是导致未定义行为。 +1. **运行时注册约束** + 插件注册表会在插件加载时校验注册。例如:重复的 provider id、重复的 speech provider id,以及格式错误的注册,都会产生插件诊断,而不是未定义行为。 2. **契约测试** - 内置插件会在测试运行期间捕获到契约注册表中,以便 OpenClaw 能显式断言归属。当前这用于模型提供商、语音提供商、Web 搜索提供商以及内置注册归属。 + 在测试运行期间,内置插件会被捕获到契约注册表中,以便 OpenClaw 显式断言归属。当前这被用于模型提供商、语音提供商、Web 搜索提供商和内置注册归属。 -实际效果是,OpenClaw 能预先知道哪个插件拥有哪个接口。这样核心和渠道就能无缝组合,因为归属是声明式、类型化且可测试的,而不是隐式的。 +实际效果是,OpenClaw 可以预先知道哪个插件拥有哪个接口。这使得 core 和渠道能够无缝组合,因为归属是声明式、类型化且可测试的,而不是隐式的。 -### 什么应该属于契约 +### 哪些内容应属于契约 好的插件契约应当是: - 类型化的 -- 小而精的 -- 能力特定的 -- 由核心拥有 +- 精简的 +- 能力专用的 +- 由 core 拥有 - 可被多个插件复用 -- 可被渠道 / 功能消费而无需了解供应商细节 +- 可被渠道 / 功能消费,而无需了解厂商细节 -不好的插件契约则是: +不好的插件契约包括: -- 隐藏在核心中的供应商特定策略 +- 隐藏在 core 中的厂商专属策略 - 绕过注册表的一次性插件逃生口 -- 渠道代码直接访问供应商实现 +- 渠道代码直接深入某个厂商实现 - 不属于 `OpenClawPluginApi` 或 `api.runtime` 的临时运行时对象 -如果有疑问,就提升抽象层级:先定义能力,再让插件接入它。 +如果有疑问,请提升抽象层级:先定义能力,再让插件接入。 ## 执行模型 -原生 OpenClaw 插件会与 Gateway 网关 **在同一进程内**运行。它们不处于沙箱隔离中。一个已加载的原生插件与核心代码处于相同的进程级信任边界。 +原生 OpenClaw 插件会与 Gateway 网关**在同一进程内**运行。它们**不**在沙箱中运行。一个已加载的原生插件与 core 代码具有相同的进程级信任边界。 -其含义包括: +影响如下: -- 原生插件可以注册工具、网络处理器、钩子和服务 -- 原生插件中的 bug 可能导致 Gateway 网关崩溃或不稳定 +- 原生插件可以注册工具、网络处理器、hooks 和服务 +- 原生插件中的 bug 可能导致 gateway 崩溃或不稳定 - 恶意原生插件等同于在 OpenClaw 进程内执行任意代码 兼容 bundle 默认更安全,因为 OpenClaw 当前将其视为元数据 / 内容包。在当前版本中,这主要意味着内置 Skills。 -对于非内置插件,应使用 allowlist 和显式的安装 / 加载路径。应将工作区插件视为开发期代码,而不是生产默认项。 +对于非内置插件,请使用 allowlist 和显式安装 / 加载路径。应将工作区插件视为开发时代码,而不是生产默认项。 -对于内置工作区包名,应让插件 id 锚定在 npm 名称中:默认是 `@openclaw/`,或者使用已批准的类型后缀,例如 -`-provider`、`-plugin`、`-speech`、`-sandbox` 或 `-media-understanding`,前提是该包有意暴露更窄的插件角色。 +对于内置工作区包名,请确保插件 id 锚定在 npm 名称中:默认使用 `@openclaw/`,或使用经批准的类型后缀,如 `-provider`、`-plugin`、`-speech`、`-sandbox` 或 `-media-understanding`,前提是该包刻意暴露更窄的插件角色。 重要信任说明: - `plugins.allow` 信任的是**插件 id**,而不是来源出处。 -- 与内置插件具有相同 id 的工作区插件,在启用 / 加入 allowlist 后,会有意遮蔽该内置副本。 -- 这很正常,也很有用,适用于本地开发、补丁测试和热修复。 +- 如果某个工作区插件与一个内置插件拥有相同 id,并且该工作区插件被启用 / 加入 allowlist,它会有意遮蔽内置副本。 +- 这属于正常且有用的行为,适用于本地开发、补丁测试和热修复。 ## 导出边界 OpenClaw 导出的是能力,而不是实现层面的便捷接口。 -保持能力注册公开。裁剪非契约辅助导出: +请保持能力注册为公开接口,同时收紧非契约辅助工具导出: -- 内置插件特定的辅助子路径 -- 不打算作为公共 API 的运行时管线子路径 -- 供应商特定的便捷辅助函数 -- 属于实现细节的设置 / 新手引导辅助函数 +- 内置插件专用辅助工具子路径 +- 不打算作为公开 API 的运行时管线子路径 +- 厂商专用便捷辅助工具 +- 属于实现细节的设置 / 新手引导辅助工具 -某些内置插件辅助子路径目前仍保留在生成的 SDK 导出映射中,以兼容现有行为和内置插件维护。当前示例包括 -`plugin-sdk/feishu`、`plugin-sdk/feishu-setup`、`plugin-sdk/zalo`、 -`plugin-sdk/zalo-setup`,以及若干 `plugin-sdk/matrix*` 接缝。应将它们视为保留的实现细节导出,而不是新第三方插件推荐使用的 SDK 模式。 +出于兼容性和内置插件维护需要,一些内置插件辅助工具子路径仍保留在生成的 SDK 导出映射中。当前示例包括 `plugin-sdk/feishu`、`plugin-sdk/feishu-setup`、`plugin-sdk/zalo`、`plugin-sdk/zalo-setup` 以及若干 `plugin-sdk/matrix*` 接缝。应将这些视为保留的实现细节导出,而不是新第三方插件推荐采用的 SDK 模式。 ## 加载流水线 在启动时,OpenClaw 大致会执行以下步骤: 1. 发现候选插件根目录 -2. 读取原生或兼容 bundle 清单和包元数据 -3. 拒绝不安全的候选项 -4. 规范化插件配置(`plugins.enabled`、`allow`、`deny`、`entries`、 - `slots`、`load.paths`) +2. 读取原生或兼容 bundle 的清单及包元数据 +3. 拒绝不安全候选项 +4. 规范化插件配置(`plugins.enabled`、`allow`、`deny`、`entries`、`slots`、`load.paths`) 5. 决定每个候选项的启用状态 6. 通过 jiti 加载已启用的原生模块 -7. 调用原生 `register(api)`(或 `activate(api)` —— 一个旧版别名)钩子,并将注册内容收集到插件注册表中 -8. 将注册表暴露给命令 / 运行时接口 +7. 调用原生 `register(api)`(或 `activate(api)` —— 旧版别名)hooks,并将注册收集到插件注册表中 +8. 向命令 / 运行时接口暴露注册表 -`activate` 是 `register` 的旧版别名 —— 加载器会解析当前存在的那个(`def.register ?? def.activate`),并在同一时机调用。所有内置插件都使用 `register`;新插件请优先使用 `register`。 +`activate` 是 `register` 的旧版别名——加载器会解析存在的那个(`def.register ?? def.activate`),并在相同位置调用它。所有内置插件都使用 `register`;新插件请优先使用 `register`。 -安全门槛发生在**运行时执行之前**。当入口逃出插件根目录、路径可被所有人写入,或对于非内置插件而言路径所有权看起来可疑时,候选项会被阻止。 +安全门禁发生在**运行时执行之前**。当入口逃逸出插件根目录、路径对所有人可写,或者对于非内置插件来说路径所有权看起来可疑时,候选项会被阻止。 -### 以清单为先的行为 +### 清单优先行为 清单是控制平面的事实来源。OpenClaw 用它来: - 标识插件 -- 发现声明的渠道 / Skills / 配置模式或 bundle 能力 -- 验证 `plugins.entries..config` -- 增强 Control UI 标签 / 占位符 +- 发现已声明的渠道 / Skills / 配置 schema 或 bundle 能力 +- 校验 `plugins.entries..config` +- 补充 Control UI 标签 / 占位文本 - 显示安装 / 目录元数据 -对于原生插件,运行时模块是数据平面部分。它负责注册实际行为,例如钩子、工具、命令或提供商流程。 +对于原生插件,运行时模块是数据平面部分。它会注册实际行为,例如 hooks、工具、命令或提供商流程。 ### 加载器会缓存什么 -OpenClaw 会保留短生命周期的进程内缓存,用于: +OpenClaw 会保留以下短生命周期的进程内缓存: - 发现结果 - 清单注册表数据 - 已加载的插件注册表 -这些缓存可减少突发启动和重复命令的开销。你可以将它们视为短暂的性能缓存,而不是持久化数据。 +这些缓存可减少突发启动和重复命令的开销。可以将它们视为短期性能缓存,而不是持久化机制。 性能说明: -- 设置 `OPENCLAW_DISABLE_PLUGIN_DISCOVERY_CACHE=1` 或 - `OPENCLAW_DISABLE_PLUGIN_MANIFEST_CACHE=1` 可禁用这些缓存。 -- 使用 `OPENCLAW_PLUGIN_DISCOVERY_CACHE_MS` 和 - `OPENCLAW_PLUGIN_MANIFEST_CACHE_MS` 调整缓存窗口。 +- 设置 `OPENCLAW_DISABLE_PLUGIN_DISCOVERY_CACHE=1` 或 `OPENCLAW_DISABLE_PLUGIN_MANIFEST_CACHE=1` 可禁用这些缓存。 +- 使用 `OPENCLAW_PLUGIN_DISCOVERY_CACHE_MS` 和 `OPENCLAW_PLUGIN_MANIFEST_CACHE_MS` 调整缓存窗口。 ## 注册表模型 -已加载插件不会直接随意修改核心全局状态。它们会注册到一个中央插件注册表中。 +已加载的插件不会直接修改任意 core 全局状态。它们会注册到一个中央插件注册表中。 -该注册表会跟踪: +注册表会跟踪: - 插件记录(身份、来源、起源、状态、诊断) - 工具 -- 旧版钩子和类型化钩子 +- 旧版 hooks 和类型化 hooks - 渠道 - 提供商 -- Gateway 网关 RPC 处理器 +- Gateway RPC 处理器 - HTTP 路由 - CLI 注册器 - 后台服务 -- 插件拥有的命令 +- 插件自有命令 -然后,核心功能会从这个注册表中读取,而不是直接与插件模块交互。这让加载保持单向: +随后,core 功能会从该注册表读取内容,而不是直接与插件模块通信。这样可保持加载为单向流: - 插件模块 -> 注册表注册 -- 核心运行时 -> 注册表消费 +- core 运行时 -> 注册表消费 -这种分离对于可维护性很重要。这意味着大多数核心接口只需要一个集成点:“读取注册表”,而不是“为每个插件模块写特例”。 +这种分离对可维护性很重要。它意味着大多数 core 接口只需要一个集成点:“读取注册表”,而不是“为每个插件模块单独特判”。 -## 对话绑定回调 +## 会话绑定回调 -绑定对话的插件可以在审批结果确定后作出响应。 +绑定会话的插件可以在批准被解决后做出反应。 -使用 `api.onConversationBindingResolved(...)` 可在绑定请求获批或被拒后接收回调: +使用 `api.onConversationBindingResolved(...)`,可在绑定请求获批或被拒后收到回调: ```ts export default { @@ -488,18 +480,17 @@ export default { - `status`:`"approved"` 或 `"denied"` - `decision`:`"allow-once"`、`"allow-always"` 或 `"deny"` - `binding`:针对已批准请求的已解析绑定 -- `request`:原始请求摘要、分离提示、发送者 id 和对话元数据 +- `request`:原始请求摘要、分离提示、发送者 id 和会话元数据 -该回调仅用于通知。它不会改变谁有权绑定对话,并且会在核心审批处理完成后运行。 +该回调仅用于通知。它不会改变谁被允许绑定会话,并且它会在 core 审批处理完成后运行。 -## 提供商运行时钩子 +## 提供商运行时 hooks 提供商插件现在有两层: -- 清单元数据:`providerAuthEnvVars` 用于在运行时加载前进行低成本环境认证查找,`providerAuthChoices` 用于在运行时加载前提供低成本的新手引导 / 认证选项标签和 CLI flag 元数据 -- 配置时钩子:`catalog` / 旧版 `discovery`,以及 `applyConfigDefaults` -- 运行时钩子:`normalizeModelId`、`normalizeTransport`、 - `normalizeConfig`、 +- 清单元数据:`providerAuthEnvVars` 用于在运行时加载前进行廉价的环境变量认证查找,`providerAuthChoices` 用于在运行时加载前提供廉价的新手引导 / 认证选项标签和 CLI flag 元数据 +- 配置时 hooks:`catalog` / 旧版 `discovery`,以及 `applyConfigDefaults` +- 运行时 hooks:`normalizeModelId`、`normalizeTransport`、`normalizeConfig`、 `applyNativeStreamingUsageCompat`、`resolveConfigApiKey`、 `resolveSyntheticAuth`、`resolveExternalOAuthProfiles`、 `shouldDeferSyntheticProfileAuth`、 @@ -518,66 +509,66 @@ export default { `buildReplayPolicy`、 `sanitizeReplayHistory`、`validateReplayTurns`、`onModelSelected` -OpenClaw 仍然拥有通用智能体循环、故障切换、转录处理和工具策略。这些钩子是供应商特定行为的扩展接口,无需为此实现一个完整的自定义推理传输层。 +OpenClaw 仍然拥有通用智能体循环、故障切换、转录处理和工具策略。这些 hooks 是提供商专属行为的扩展接口,而无需实现完整的自定义推理传输层。 -当提供商具有基于环境变量的凭证,且通用 auth / status / model-picker 路径需要在不加载插件运行时的情况下识别它们时,请使用清单中的 `providerAuthEnvVars`。当新手引导 / 认证选项 CLI 接口需要在不加载提供商运行时的情况下了解该提供商的 choice id、分组标签和简单单 flag 认证接线时,请使用清单中的 `providerAuthChoices`。保留提供商运行时中的 `envVars`,用于面向操作员的提示,例如新手引导标签或 OAuth client-id / client-secret 设置变量。 +当提供商有基于环境变量的凭据,并且通用认证 / 状态 / 模型选择器路径需要在不加载插件运行时的情况下看到它们时,请使用清单中的 `providerAuthEnvVars`。当新手引导 / 认证选项 CLI 接口需要在不加载提供商运行时的情况下知道该提供商的 choice id、分组标签和简单单 flag 认证接线时,请使用清单中的 `providerAuthChoices`。而提供商运行时中的 `envVars` 则应保留给面向运维者的提示,例如新手引导标签或 OAuth client id / client secret 设置变量。 -### 钩子顺序与用法 +### Hook 顺序与使用方式 -对于模型 / 提供商插件,OpenClaw 大致按以下顺序调用钩子。 +对于模型 / 提供商插件,OpenClaw 大致按以下顺序调用 hooks。 “何时使用”列是快速决策指南。 -| # | 钩子 | 作用 | 何时使用 | +| # | Hook | 作用 | 何时使用 | | --- | --------------------------------- | ------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------- | -| 1 | `catalog` | 在 `models.json` 生成期间,将提供商配置发布到 `models.providers` 中 | 提供商拥有目录或 base URL 默认值时 | -| 2 | `applyConfigDefaults` | 在配置具体化期间,应用提供商拥有的全局配置默认值 | 默认值依赖认证模式、环境或提供商模型族语义时 | -| -- | _(built-in model lookup)_ | OpenClaw 会先尝试正常的注册表 / 目录路径 | _(不是插件钩子)_ | -| 3 | `normalizeModelId` | 在查找前规范化旧版或预览版 model-id 别名 | 提供商拥有规范模型解析前的别名清理逻辑时 | -| 4 | `normalizeTransport` | 在通用模型组装前规范化提供商族 `api` / `baseUrl` | 提供商拥有同一传输族中自定义提供商 id 的传输清理逻辑时 | -| 5 | `normalizeConfig` | 在运行时 / 提供商解析前规范化 `models.providers.` | 提供商需要让配置清理逻辑与插件共存;内置 Google 系辅助函数也会为受支持的 Google 配置项提供兜底 | -| 6 | `applyNativeStreamingUsageCompat` | 对配置提供商应用原生流式使用量兼容改写 | 提供商需要基于端点的原生流式使用量元数据修复时 | -| 7 | `resolveConfigApiKey` | 在加载运行时认证前,为配置提供商解析 env-marker 认证 | 提供商拥有自己的 env-marker API key 解析逻辑;`amazon-bedrock` 也在这里内置了 AWS env-marker 解析器 | -| 8 | `resolveSyntheticAuth` | 在不持久化明文的情况下暴露本地 / 自托管或配置支持的认证 | 提供商可以使用 synthetic / 本地凭证标记运行时 | -| 9 | `resolveExternalOAuthProfiles` | 覆盖外部 OAuth 配置文件;CLI / app 拥有的凭证默认 `persistence` 为 `runtime-only` | 提供商复用外部 OAuth 凭证且不持久化复制的 refresh token 时 | -| 10 | `shouldDeferSyntheticProfileAuth` | 将已存储的 synthetic 配置文件占位符下调到 env / 配置支持认证之后 | 提供商存储了 synthetic 占位配置文件,且这些配置文件不应获得更高优先级时 | -| 11 | `resolveDynamicModel` | 为尚未存在于本地注册表中的提供商模型 id 提供同步回退解析 | 提供商接受任意上游模型 id 时 | -| 12 | `prepareDynamicModel` | 异步预热,然后再次运行 `resolveDynamicModel` | 提供商在解析未知 id 前需要网络元数据时 | -| 13 | `normalizeResolvedModel` | 在嵌入式运行器使用已解析模型前进行最终改写 | 提供商需要传输改写,但仍使用核心传输层时 | -| 14 | `contributeResolvedModelCompat` | 为另一种兼容传输背后的供应商模型提供兼容标志 | 提供商可在不接管该提供商的前提下,在代理传输上识别自己的模型时 | -| 15 | `capabilities` | 由提供商拥有、供共享核心逻辑使用的转录 / 工具元数据 | 提供商需要处理转录 / 提供商族特殊行为时 | -| 16 | `normalizeToolSchemas` | 在嵌入式运行器看到工具模式前先进行规范化 | 提供商需要对传输族模式进行清理时 | -| 17 | `inspectToolSchemas` | 在规范化后暴露由提供商拥有的模式诊断 | 提供商希望给出关键字警告,而无需将提供商特定规则教给核心时 | -| 18 | `resolveReasoningOutputMode` | 选择原生或带标签的 reasoning-output 契约 | 提供商需要带标签的 reasoning / final 输出,而不是原生字段时 | -| 19 | `prepareExtraParams` | 在通用流式选项包装器之前,对请求参数做规范化 | 提供商需要默认请求参数或逐提供商参数清理时 | -| 20 | `createStreamFn` | 使用自定义传输完全替换正常流路径 | 提供商需要自定义线路协议,而不仅是包装器时 | -| 21 | `wrapStreamFn` | 在应用通用包装器后再包装流 | 提供商需要请求头 / 请求体 / 模型兼容包装器,而不是自定义传输时 | -| 22 | `resolveTransportTurnState` | 附加原生每轮传输头或元数据 | 提供商希望通用传输发送提供商原生轮次身份时 | -| 23 | `resolveWebSocketSessionPolicy` | 附加原生 WebSocket 头或会话冷却策略 | 提供商希望通用 WS 传输微调会话头或回退策略时 | -| 24 | `formatApiKey` | 认证配置文件格式化器:已存储配置文件转换为运行时 `apiKey` 字符串 | 提供商存储了额外认证元数据,并需要自定义运行时令牌格式时 | -| 25 | `refreshOAuth` | 针对自定义刷新端点或刷新失败策略的 OAuth 刷新覆盖 | 提供商不适配共享 `pi-ai` 刷新器时 | -| 26 | `buildAuthDoctorHint` | 当 OAuth 刷新失败时追加修复提示 | 提供商在刷新失败后需要提供商拥有的认证修复指导时 | -| 27 | `matchesContextOverflowError` | 提供商拥有的上下文窗口溢出匹配器 | 提供商存在通用启发式无法识别的原始溢出错误时 | -| 28 | `classifyFailoverReason` | 提供商拥有的故障切换原因分类 | 提供商可将原始 API / 传输错误映射为限流 / 过载等分类时 | -| 29 | `isCacheTtlEligible` | 面向代理 / 回程提供商的提示词缓存策略 | 提供商需要代理特定的缓存 TTL 门控时 | -| 30 | `buildMissingAuthMessage` | 替代通用缺失认证恢复消息 | 提供商需要特定的缺失认证恢复提示时 | -| 31 | `suppressBuiltInModel` | 过时上游模型抑制及可选的面向用户错误提示 | 提供商需要隐藏过时上游目录项,或用供应商提示替代它们时 | -| 32 | `augmentModelCatalog` | 在发现后追加 synthetic / 最终目录项 | 提供商需要在 `models list` 和选择器中加入 synthetic 前向兼容目录项时 | -| 33 | `isBinaryThinking` | 面向 binary-thinking 提供商的 on/off 推理开关 | 提供商只暴露二元 thinking 开 / 关时 | -| 34 | `supportsXHighThinking` | 针对选定模型的 `xhigh` 推理支持 | 提供商希望仅让部分模型支持 `xhigh` 时 | -| 35 | `resolveDefaultThinkingLevel` | 针对特定模型族的默认 `/think` 级别 | 提供商拥有某个模型族的默认 `/think` 策略时 | -| 36 | `isModernModelRef` | 用于 live profile 过滤和 smoke 选择的现代模型匹配器 | 提供商拥有 live / smoke 首选模型匹配逻辑时 | -| 37 | `prepareRuntimeAuth` | 在推理前,将已配置凭证交换为实际运行时令牌 / key | 提供商需要令牌交换或短时请求凭证时 | -| 38 | `resolveUsageAuth` | 为 `/usage` 及相关状态接口解析使用量 / 计费凭证 | 提供商需要自定义使用量 / 配额令牌解析或不同的使用量凭证时 | -| 39 | `fetchUsageSnapshot` | 在认证解析后拉取并规范化提供商特定的使用量 / 配额快照 | 提供商需要提供商特定的使用量端点或负载解析器时 | -| 40 | `createEmbeddingProvider` | 为内存 / 搜索构建由提供商拥有的嵌入适配器 | 内存嵌入行为应与提供商插件共存时 | -| 41 | `buildReplayPolicy` | 返回一个控制提供商转录处理的重放策略 | 提供商需要自定义转录策略(例如移除 thinking block)时 | -| 42 | `sanitizeReplayHistory` | 在通用转录清理后改写重放历史 | 提供商需要共享压缩辅助函数之外的特定重放改写时 | -| 43 | `validateReplayTurns` | 在嵌入式运行器前对重放轮次做最终验证或重塑 | 提供商传输在通用清理后需要更严格的轮次验证时 | -| 44 | `onModelSelected` | 执行由提供商拥有的模型选定后副作用 | 当模型变为活动状态时,提供商需要遥测或提供商拥有状态时 | +| 1 | `catalog` | 在生成 `models.json` 时将提供商配置发布到 `models.providers` | 提供商拥有目录或 base URL 默认值 | +| 2 | `applyConfigDefaults` | 在配置实体化期间应用提供商自有的全局配置默认值 | 默认值依赖认证模式、环境或提供商模型家族语义 | +| -- | _(built-in model lookup)_ | OpenClaw 会先尝试正常的注册表 / 目录路径 | _(不是插件 hook)_ | +| 3 | `normalizeModelId` | 在查找前规范化旧版或预览 model id 别名 | 提供商拥有规范模型解析前的别名清理逻辑 | +| 4 | `normalizeTransport` | 在通用模型组装前规范化提供商家族的 `api` / `baseUrl` | 提供商拥有同一传输家族中自定义提供商 id 的传输清理逻辑 | +| 5 | `normalizeConfig` | 在运行时 / 提供商解析前规范化 `models.providers.` | 提供商需要将配置清理逻辑放在插件内;内置 Google 家族辅助工具也会为受支持的 Google 配置项提供兜底规范化 | +| 6 | `applyNativeStreamingUsageCompat` | 对配置提供商应用原生流式用量兼容性重写 | 提供商需要针对端点驱动的原生流式用量元数据修复 | +| 7 | `resolveConfigApiKey` | 在加载运行时认证前,为配置提供商解析环境标记认证 | 提供商拥有自己的环境标记 API key 解析逻辑;`amazon-bedrock` 也在这里内置了 AWS 环境标记解析器 | +| 8 | `resolveSyntheticAuth` | 在不持久化明文的前提下暴露本地 / 自托管或基于配置的认证 | 提供商可使用 synthetic / 本地凭据标记运行 | +| 9 | `resolveExternalOAuthProfiles` | 覆盖外部 OAuth 配置文件;默认 `persistence` 为 `runtime-only`,适用于 CLI / 应用自有凭据 | 提供商复用外部 OAuth 凭据,而不持久化复制的 refresh token | +| 10 | `shouldDeferSyntheticProfileAuth` | 在 env / 配置驱动认证之后降低已存储 synthetic profile 占位项的优先级 | 提供商存储了 synthetic 占位 profile,且不应让它们优先生效 | +| 11 | `resolveDynamicModel` | 为尚未存在于本地注册表中的提供商自有 model id 提供同步回退 | 提供商接受任意上游 model id | +| 12 | `prepareDynamicModel` | 先进行异步预热,然后再次运行 `resolveDynamicModel` | 提供商在解析未知 id 前需要网络元数据 | +| 13 | `normalizeResolvedModel` | 在嵌入式 runner 使用已解析模型前进行最终重写 | 提供商需要传输重写,但仍使用 core 传输 | +| 14 | `contributeResolvedModelCompat` | 为另一个兼容传输下的厂商模型贡献兼容标记 | 提供商能在代理传输上识别自己的模型,而不接管该提供商 | +| 15 | `capabilities` | 由共享 core 逻辑使用的提供商自有转录 / 工具元数据 | 提供商需要转录 / 提供商家族特有行为 | +| 16 | `normalizeToolSchemas` | 在嵌入式 runner 看到工具 schema 之前进行规范化 | 提供商需要传输家族级别的 schema 清理 | +| 17 | `inspectToolSchemas` | 在规范化后暴露提供商自有 schema 诊断 | 提供商希望给出关键字警告,而不把提供商专用规则教给 core | +| 18 | `resolveReasoningOutputMode` | 选择原生或带标签的推理输出契约 | 提供商需要使用带标签的 reasoning / final output,而不是原生字段 | +| 19 | `prepareExtraParams` | 在通用流式选项包装器前做请求参数规范化 | 提供商需要默认请求参数或每提供商参数清理 | +| 20 | `createStreamFn` | 用自定义传输完全替换正常流路径 | 提供商需要自定义线路协议,而不仅仅是包装器 | +| 21 | `wrapStreamFn` | 在应用通用包装器后进一步包装流函数 | 提供商需要请求头 / 请求体 / 模型兼容包装,而不是自定义传输 | +| 22 | `resolveTransportTurnState` | 附加原生的逐轮传输头或元数据 | 提供商希望通用传输发送提供商原生的轮次身份 | +| 23 | `resolveWebSocketSessionPolicy` | 附加原生 WebSocket 头或会话冷却策略 | 提供商希望通用 WS 传输调整会话头或回退策略 | +| 24 | `formatApiKey` | 认证 profile 格式化器:将已存储 profile 转为运行时 `apiKey` 字符串 | 提供商存储额外认证元数据,并需要自定义运行时 token 形态 | +| 25 | `refreshOAuth` | 为自定义刷新端点或刷新失败策略覆盖 OAuth 刷新逻辑 | 提供商不适配共享的 `pi-ai` 刷新器 | +| 26 | `buildAuthDoctorHint` | 当 OAuth 刷新失败时附加修复提示 | 提供商需要在刷新失败后提供自有认证修复指导 | +| 27 | `matchesContextOverflowError` | 提供商自有的上下文窗口溢出匹配器 | 提供商具有通用启发式无法识别的原始溢出错误 | +| 28 | `classifyFailoverReason` | 提供商自有的故障切换原因分类 | 提供商可以将原始 API / 传输错误映射为限流 / 过载等 | +| 29 | `isCacheTtlEligible` | 面向代理 / 回传提供商的提示词缓存策略 | 提供商需要代理专用的缓存 TTL 门控 | +| 30 | `buildMissingAuthMessage` | 替换通用缺失认证恢复消息 | 提供商需要提供商专属的缺失认证恢复提示 | +| 31 | `suppressBuiltInModel` | 抑制陈旧上游模型,并可选返回面向用户的错误提示 | 提供商需要隐藏陈旧的上游条目,或用厂商提示替换它们 | +| 32 | `augmentModelCatalog` | 在发现后附加 synthetic / 最终目录条目 | 提供商需要在 `models list` 和选择器中加入 synthetic 的前向兼容条目 | +| 33 | `isBinaryThinking` | 面向二值 thinking 提供商的开 / 关推理开关 | 提供商只暴露二值 thinking 开 / 关 | +| 34 | `supportsXHighThinking` | 为选定模型提供 `xhigh` 推理支持 | 提供商只想对部分模型启用 `xhigh` | +| 35 | `resolveDefaultThinkingLevel` | 为特定模型家族确定默认 `/think` 级别 | 提供商拥有某模型家族的默认 `/think` 策略 | +| 36 | `isModernModelRef` | 面向 live profile 过滤器和 smoke 选择的 modern model 匹配器 | 提供商拥有 live / smoke 首选模型匹配逻辑 | +| 37 | `prepareRuntimeAuth` | 在推理前立即将已配置凭据交换为实际运行时 token / key | 提供商需要 token 交换或短期请求凭据 | +| 38 | `resolveUsageAuth` | 为 `/usage` 及相关状态接口解析用量 / 计费凭据 | 提供商需要自定义的用量 / 配额 token 解析,或不同的用量凭据 | +| 39 | `fetchUsageSnapshot` | 在认证解析后抓取并规范化提供商专属用量 / 配额快照 | 提供商需要提供商专属的用量端点或负载解析器 | +| 40 | `createEmbeddingProvider` | 为 memory / 搜索构建提供商自有的 embedding adapter | memory embedding 行为应归属于提供商插件 | +| 41 | `buildReplayPolicy` | 返回一个控制提供商转录处理方式的 replay policy | 提供商需要自定义转录策略(例如去除 thinking block) | +| 42 | `sanitizeReplayHistory` | 在通用转录清理后重写 replay 历史 | 提供商需要超出共享压缩辅助工具之外的 replay 重写 | +| 43 | `validateReplayTurns` | 在嵌入式 runner 之前对 replay turn 做最终校验或重塑 | 提供商传输在通用净化后需要更严格的 turn 校验 | +| 44 | `onModelSelected` | 运行提供商自有的模型选中后副作用 | 当模型变为活动状态时,提供商需要遥测或自有状态处理 | -`normalizeModelId`、`normalizeTransport` 和 `normalizeConfig` 会先检查已匹配的提供商插件,然后继续回退到其他具备钩子能力的提供商插件,直到其中一个真正更改 model id 或 transport / config 为止。这样别名 / 兼容提供商 shim 就能继续工作,而无需让调用方知道哪个内置插件拥有该改写。如果没有任何提供商钩子改写受支持的 Google 系配置项,那么内置 Google 配置规范化器仍会应用该兼容性清理。 +`normalizeModelId`、`normalizeTransport` 和 `normalizeConfig` 会先检查匹配的提供商插件,然后回退到其他具备 hook 能力的提供商插件,直到其中一个真正修改 model id 或 transport / config 为止。这样可使别名 / 兼容提供商 shim 继续工作,而无需调用方知道哪个内置插件拥有该重写。如果没有提供商 hook 重写受支持的 Google 家族配置项,则内置 Google 配置规范化器仍会执行该兼容性清理。 -如果提供商需要完全自定义的线路协议或自定义请求执行器,那属于另一类扩展。这些钩子适用于仍运行在 OpenClaw 常规推理循环上的提供商行为。 +如果提供商需要完全自定义的线路协议或自定义请求执行器,那就是另一类扩展。这些 hooks 面向的是仍运行在 OpenClaw 正常推理循环上的提供商行为。 ### 提供商示例 @@ -637,115 +628,103 @@ api.registerProvider({ - Anthropic 使用 `resolveDynamicModel`、`capabilities`、`buildAuthDoctorHint`、 `resolveUsageAuth`、`fetchUsageSnapshot`、`isCacheTtlEligible`、 - `resolveDefaultThinkingLevel`、`applyConfigDefaults`、`isModernModelRef`、 + `resolveDefaultThinkingLevel`、`applyConfigDefaults`、`isModernModelRef` 和 `wrapStreamFn`,因为它拥有 Claude 4.6 前向兼容、 - 提供商族提示、认证修复指导、使用量端点集成、 - 提示词缓存适用性、感知认证的配置默认值、Claude - 默认 / 自适应 thinking 策略,以及面向 beta headers、 - `/fast` / `serviceTier` 和 `context1m` 的 Anthropic 特定流整形。 -- Anthropic 中 Claude 特定的流辅助函数目前保留在该内置插件自己的 - 公共 `api.ts` / `contract-api.ts` 接缝中。该包接口会导出 - `wrapAnthropicProviderStream`、`resolveAnthropicBetas`、 + 提供商家族提示、认证修复指导、用量端点集成、 + 提示词缓存资格、认证感知配置默认值、Claude + 默认 / 自适应 thinking 策略,以及 Anthropic 专属的流整形能力,用于 beta headers、`/fast` / `serviceTier` 和 `context1m`。 +- Anthropic 的 Claude 专属流辅助工具目前保留在内置插件自己的公开 `api.ts` / `contract-api.ts` 接缝中。该包接口 + 导出 `wrapAnthropicProviderStream`、`resolveAnthropicBetas`、 `resolveAnthropicFastMode`、`resolveAnthropicServiceTier` 以及更底层的 - Anthropic 包装器构建器,而不是为了某个提供商的 beta-header 规则 - 去扩宽通用 SDK。 + Anthropic 包装器构建器,而不是仅为某一个提供商的 beta header 规则去扩展通用 SDK。 - OpenAI 使用 `resolveDynamicModel`、`normalizeResolvedModel` 和 - `capabilities`,外加 `buildMissingAuthMessage`、`suppressBuiltInModel`、 + `capabilities`,以及 `buildMissingAuthMessage`、`suppressBuiltInModel`、 `augmentModelCatalog`、`supportsXHighThinking` 和 `isModernModelRef`, - 因为它拥有 GPT-5.4 前向兼容、直接的 OpenAI + 因为它拥有 GPT-5.4 前向兼容、直接 OpenAI `openai-completions` -> `openai-responses` 规范化、面向 Codex 的认证 - 提示、Spark 抑制、synthetic OpenAI 列表项以及 GPT-5 thinking / - live-model 策略;`openai-responses-defaults` 流家族则拥有共享的原生 - OpenAI Responses 包装器,用于 attribution headers、 - `/fast` / `serviceTier`、文本详细程度、原生 Codex Web 搜索、 - reasoning 兼容负载整形和 Responses 上下文管理。 -- OpenRouter 使用 `catalog`、`resolveDynamicModel` 和 - `prepareDynamicModel`,因为该提供商是透传型的,可能会在 OpenClaw - 的静态目录更新前就暴露新的模型 id;它还使用 - `capabilities`、`wrapStreamFn` 和 `isCacheTtlEligible`,以将 - 提供商特定请求头、路由元数据、reasoning 补丁和提示词缓存策略 - 保持在核心之外。它的 replay 策略来自 + 提示、Spark 抑制、synthetic OpenAI 列表条目,以及 GPT-5 的 thinking / + live model 策略;`openai-responses-defaults` 流家族拥有共享的原生 OpenAI Responses 包装器,用于 attribution headers、 + `/fast`/`serviceTier`、文本详细度、本地 Codex Web 搜索、 + reasoning 兼容负载整形以及 Responses 上下文管理。 +- OpenRouter 使用 `catalog`,以及 `resolveDynamicModel` 和 + `prepareDynamicModel`,因为该提供商是透传型的,可能在 OpenClaw 的静态目录更新前就暴露新的 + model id;它还使用 + `capabilities`、`wrapStreamFn` 和 `isCacheTtlEligible`,以便将 + 提供商专属请求头、路由元数据、reasoning 补丁和 + 提示词缓存策略留在 core 外部。它的 replay policy 来自 `passthrough-gemini` 家族,而 `openrouter-thinking` 流家族 - 则拥有代理推理注入以及不支持模型 / `auto` 跳过逻辑。 + 负责代理 reasoning 注入以及不支持模型 / `auto` 的跳过逻辑。 - GitHub Copilot 使用 `catalog`、`auth`、`resolveDynamicModel` 和 - `capabilities`,外加 `prepareRuntimeAuth` 和 `fetchUsageSnapshot`, - 因为它需要由提供商拥有的设备登录、模型回退行为、Claude 转录特殊性、 - GitHub token -> Copilot token 交换以及由提供商拥有的使用量端点。 + `capabilities`,以及 `prepareRuntimeAuth` 和 `fetchUsageSnapshot`,因为它 + 需要提供商自有的设备登录、模型回退行为、Claude 转录特性、 + GitHub token -> Copilot token 交换以及提供商自有的用量端点。 - OpenAI Codex 使用 `catalog`、`resolveDynamicModel`、 - `normalizeResolvedModel`、`refreshOAuth` 和 `augmentModelCatalog`,外加 - `prepareExtraParams`、`resolveUsageAuth` 和 `fetchUsageSnapshot`, - 因为它仍运行在核心 OpenAI 传输层上,但拥有自己的 transport / base URL - 规范化、OAuth 刷新回退策略、默认传输选择、synthetic Codex - 目录项以及 ChatGPT 使用量端点集成;它与直接 OpenAI 共用同一个 - `openai-responses-defaults` 流家族。 + `normalizeResolvedModel`、`refreshOAuth` 和 `augmentModelCatalog`,以及 + `prepareExtraParams`、`resolveUsageAuth` 和 `fetchUsageSnapshot`,因为它 + 仍运行在 core OpenAI 传输之上,但拥有自己的传输 / base URL + 规范化、OAuth 刷新回退策略、默认传输选择、 + synthetic Codex 目录条目以及 ChatGPT 用量端点集成;它与直接 OpenAI 共用相同的 `openai-responses-defaults` 流家族。 - Google AI Studio 和 Gemini CLI OAuth 使用 `resolveDynamicModel`、 `buildReplayPolicy`、`sanitizeReplayHistory`、 `resolveReasoningOutputMode`、`wrapStreamFn` 和 `isModernModelRef`,因为 `google-gemini` replay 家族拥有 Gemini 3.1 前向兼容回退、 - 原生 Gemini replay 验证、bootstrap replay 清理、带标签的 - reasoning-output 模式以及现代模型匹配,而 - `google-thinking` 流家族则拥有 Gemini thinking 负载规范化; + 原生 Gemini replay 校验、bootstrap replay 净化、带标签的 + reasoning 输出模式以及 modern model 匹配逻辑,而 + `google-thinking` 流家族拥有 Gemini thinking 负载规范化; Gemini CLI OAuth 还使用 `formatApiKey`、`resolveUsageAuth` 和 - `fetchUsageSnapshot` 用于令牌格式化、令牌解析和配额端点接线。 + `fetchUsageSnapshot` 来处理 token 格式化、token 解析和配额端点接线。 - Anthropic Vertex 通过 `anthropic-by-model` replay 家族使用 `buildReplayPolicy`, - 这样 Claude 特定的 replay 清理就能仅限于 Claude id, - 而不是所有 `anthropic-messages` 传输。 + 这样 Claude 专属 replay 清理就能仅作用于 Claude id,而不是所有 `anthropic-messages` 传输。 - Amazon Bedrock 使用 `buildReplayPolicy`、`matchesContextOverflowError`、 `classifyFailoverReason` 和 `resolveDefaultThinkingLevel`,因为它拥有 - Bedrock 特定的限流 / 未就绪 / 上下文溢出错误分类逻辑, - 适用于 Anthropic-on-Bedrock 流量;它的 replay 策略仍共享同一个 - 仅限 Claude 的 `anthropic-by-model` 防护。 -- OpenRouter、Kilocode、Opencode 和 Opencode Go 通过 - `passthrough-gemini` replay 家族使用 `buildReplayPolicy`, - 因为它们通过 OpenAI 兼容传输代理 Gemini 模型,并需要 Gemini - thought-signature 清理,而不是原生 Gemini replay 验证或 - bootstrap 改写。 + Bedrock 专属的 throttle / not-ready / context-overflow 错误分类能力, + 适用于 Anthropic-on-Bedrock 流量;其 replay policy 仍共享相同的 + 仅限 Claude 的 `anthropic-by-model` 保护。 +- OpenRouter、Kilocode、Opencode 和 Opencode Go 通过 `passthrough-gemini` replay 家族使用 `buildReplayPolicy`,因为它们通过 OpenAI 兼容传输代理 Gemini + 模型,需要进行 Gemini thought-signature 净化,但不需要原生 Gemini replay 校验或 + bootstrap 重写。 - MiniMax 通过 - `hybrid-anthropic-openai` replay 家族使用 `buildReplayPolicy`, - 因为一个提供商同时拥有 Anthropic-message 和 OpenAI 兼容语义; - 它在 Anthropic 侧保留仅限 Claude 的 thinking-block 丢弃逻辑, - 同时将 reasoning 输出模式改回原生,而 `minimax-fast-mode` 流家族 - 则拥有共享流路径上的 fast-mode 模型改写。 -- Moonshot 使用 `catalog` 加 `wrapStreamFn`,因为它仍使用共享的 - OpenAI 传输层,但需要由提供商拥有的 thinking 负载规范化; - `moonshot-thinking` 流家族会将 config 加 `/think` 状态映射到其原生 - binary thinking 负载。 + `hybrid-anthropic-openai` replay 家族使用 `buildReplayPolicy`,因为同一个提供商同时拥有 + Anthropic message 和 OpenAI 兼容语义;它会在 Anthropic 一侧保留仅限 Claude 的 + thinking block 丢弃逻辑,同时将 reasoning + 输出模式覆盖回原生,而 `minimax-fast-mode` 流家族则拥有共享流路径上的 + fast mode 模型重写能力。 +- Moonshot 使用 `catalog` 和 `wrapStreamFn`,因为它仍使用共享的 + OpenAI 传输,但需要提供商自有的 thinking 负载规范化;`moonshot-thinking` 流家族将配置和 `/think` 状态映射到其原生二值 thinking 负载。 - Kilocode 使用 `catalog`、`capabilities`、`wrapStreamFn` 和 - `isCacheTtlEligible`,因为它需要由提供商拥有的请求头、 + `isCacheTtlEligible`,因为它需要提供商自有请求头、 reasoning 负载规范化、Gemini 转录提示以及 Anthropic - cache-TTL 门控;`kilocode-thinking` 流家族将 Kilo thinking 注入 - 保持在共享代理流路径上,同时跳过 `kilo/auto` 和其他 - 不支持显式推理负载的代理模型 id。 + cache TTL 门控;`kilocode-thinking` 流家族负责在共享代理流路径中保留 Kilo thinking + 注入,同时跳过 `kilo/auto` 和其他不支持显式 reasoning 负载的代理模型 id。 - Z.AI 使用 `resolveDynamicModel`、`prepareExtraParams`、`wrapStreamFn`、 `isCacheTtlEligible`、`isBinaryThinking`、`isModernModelRef`、 `resolveUsageAuth` 和 `fetchUsageSnapshot`,因为它拥有 GLM-5 回退、 - `tool_stream` 默认值、binary thinking UX、现代模型匹配,以及使用量认证 - 与配额获取;`tool-stream-default-on` 流家族会将默认开启的 - `tool_stream` 包装器移出逐提供商手写胶水代码。 + `tool_stream` 默认值、二值 thinking UX、modern model 匹配,以及 + 用量认证 + 配额抓取;`tool-stream-default-on` 流家族将默认开启的 + `tool_stream` 包装器从各提供商手写胶水代码中抽离出来。 - xAI 使用 `normalizeResolvedModel`、`normalizeTransport`、 `contributeResolvedModelCompat`、`prepareExtraParams`、`wrapStreamFn`、 `resolveSyntheticAuth`、`resolveDynamicModel` 和 `isModernModelRef`, - 因为它拥有原生 xAI Responses 传输规范化、Grok fast-mode - 别名改写、默认 `tool_stream`、严格工具 / 推理负载清理、 - 面向插件拥有工具的回退认证复用、前向兼容 Grok 模型解析, - 以及由提供商拥有的兼容补丁,例如 xAI 工具模式配置、 - 不受支持的模式关键字、原生 `web_search` 和 HTML 实体形式的 + 因为它拥有原生 xAI Responses 传输规范化、Grok fast mode + 别名重写、默认 `tool_stream`、strict tool / reasoning payload + 清理、插件自有工具的回退认证复用、前向兼容 Grok + 模型解析,以及提供商自有的兼容性补丁,例如 xAI tool schema + profile、不受支持的 schema 关键字、原生 `web_search`,以及 HTML entity 工具调用参数解码。 -- Mistral、OpenCode Zen 和 OpenCode Go 仅使用 `capabilities`, - 以便将转录 / 工具特殊行为保持在核心之外。 -- 仅目录型的内置提供商,如 `byteplus`、`cloudflare-ai-gateway`、 +- Mistral、OpenCode Zen 和 OpenCode Go 仅使用 `capabilities`,以将 + 转录 / 工具特性留在 core 外部。 +- 仅目录型内置提供商,例如 `byteplus`、`cloudflare-ai-gateway`、 `huggingface`、`kimi-coding`、`nvidia`、`qianfan`、 - `synthetic`、`together`、`venice`、`vercel-ai-gateway` 和 `volcengine` - 仅使用 `catalog`。 -- Qwen 使用 `catalog` 处理其文本提供商,并为其多模态接口注册共享的 - 媒体理解和视频生成能力。 -- MiniMax 和 Xiaomi 使用 `catalog` 加使用量钩子,因为它们的 `/usage` - 行为由插件拥有,尽管推理仍通过共享传输层运行。 + `synthetic`、`together`、`venice`、`vercel-ai-gateway` 和 `volcengine`,仅使用 + `catalog`。 +- Qwen 将 `catalog` 用于其文本提供商,同时为其多模态接口注册共享的媒体理解和视频生成能力。 +- MiniMax 和 Xiaomi 使用 `catalog` 加上 usage hooks,因为它们的 `/usage` + 行为属于插件自有,即使推理仍通过共享传输运行。 -## 运行时辅助函数 +## 运行时辅助工具 -插件可以通过 `api.runtime` 访问部分选定的核心辅助函数。对于 TTS: +插件可以通过 `api.runtime` 访问部分选定的 core 辅助工具。以 TTS 为例: ```ts const clip = await api.runtime.tts.textToSpeech({ @@ -766,12 +745,12 @@ const voices = await api.runtime.tts.listVoices({ 说明: -- `textToSpeech` 返回用于文件 / 语音便笺接口的标准核心 TTS 输出负载。 -- 使用核心 `messages.tts` 配置和提供商选择逻辑。 -- 返回 PCM 音频缓冲区 + 采样率。插件必须为提供商重新采样 / 编码。 -- `listVoices` 对每个提供商来说是可选的。可用于供应商拥有的语音选择器或设置流程。 -- 语音列表可包含更丰富的元数据,例如语言区域、性别和 personality 标签,供感知提供商的选择器使用。 -- OpenAI 和 ElevenLabs 当前支持电话场景。Microsoft 不支持。 +- `textToSpeech` 返回常规 core TTS 输出负载,适用于文件 / 语音便笺接口。 +- 使用 core `messages.tts` 配置和提供商选择。 +- 返回 PCM 音频 buffer + sample rate。插件必须自行进行重采样 / 编码以适配提供商。 +- `listVoices` 对每个提供商来说是可选的。可将其用于厂商自有的语音选择器或设置流程。 +- 语音列表可以包含更丰富的元数据,例如语言区域、性别和个性标签,以支持提供商感知的选择器。 +- 当前 OpenAI 和 ElevenLabs 支持电话场景。Microsoft 不支持。 插件也可以通过 `api.registerSpeechProvider(...)` 注册语音提供商。 @@ -793,13 +772,14 @@ api.registerSpeechProvider({ 说明: -- 将 TTS 策略、回退和回复交付保留在核心中。 -- 使用语音提供商承载由供应商拥有的合成行为。 +- 将 TTS 策略、回退和回复投递保留在 core 中。 +- 对厂商自有合成行为使用语音提供商。 - 旧版 Microsoft `edge` 输入会被规范化为 `microsoft` provider id。 -- 推荐的归属模型是面向公司的:随着 OpenClaw 添加这些能力契约, - 一个供应商插件可以拥有文本、语音、图像和未来媒体提供商。 +- 推荐的归属模型是面向公司的:随着 OpenClaw 增加这些 + 能力契约,一个厂商插件可以同时拥有文本、语音、图像和未来媒体提供商。 -对于图像 / 音频 / 视频理解,插件注册的是一个类型化的媒体理解提供商,而不是通用 key / value 容器: +对于图像 / 音频 / 视频理解,插件会注册一个类型化的 +媒体理解提供商,而不是通用 key/value 包: ```ts api.registerMediaUnderstandingProvider({ @@ -813,15 +793,15 @@ api.registerMediaUnderstandingProvider({ 说明: -- 将编排、回退、配置和渠道接线保留在核心中。 -- 将供应商行为保留在提供商插件中。 +- 将编排、回退、配置和渠道接线保留在 core 中。 +- 将厂商行为保留在提供商插件中。 - 增量扩展应保持类型化:新的可选方法、新的可选结果字段、新的可选能力。 - 视频生成已经遵循相同模式: - - 核心拥有能力契约和运行时辅助函数 - - 供应商插件注册 `api.registerVideoGenerationProvider(...)` + - core 拥有能力契约和运行时辅助工具 + - 厂商插件注册 `api.registerVideoGenerationProvider(...)` - 功能 / 渠道插件消费 `api.runtime.videoGeneration.*` -对于媒体理解运行时辅助函数,插件可以调用: +对于媒体理解运行时辅助工具,插件可以调用: ```ts const image = await api.runtime.mediaUnderstanding.describeImageFile({ @@ -836,7 +816,7 @@ const video = await api.runtime.mediaUnderstanding.describeVideoFile({ }); ``` -对于音频转写,插件可以使用媒体理解运行时,或旧版 STT 别名: +对于音频转写,插件可以使用媒体理解运行时或较旧的 STT 别名: ```ts const { text } = await api.runtime.mediaUnderstanding.transcribeAudioFile({ @@ -850,11 +830,11 @@ const { text } = await api.runtime.mediaUnderstanding.transcribeAudioFile({ 说明: - `api.runtime.mediaUnderstanding.*` 是图像 / 音频 / 视频理解的首选共享接口。 -- 使用核心媒体理解音频配置(`tools.media.audio`)和提供商回退顺序。 -- 当没有生成转写输出时返回 `{ text: undefined }`(例如输入被跳过 / 不受支持)。 -- `api.runtime.stt.transcribeAudioFile(...)` 仍保留为兼容别名。 +- 使用 core 媒体理解音频配置(`tools.media.audio`)和提供商回退顺序。 +- 当没有产生转写输出时,返回 `{ text: undefined }`(例如输入被跳过 / 不受支持)。 +- `api.runtime.stt.transcribeAudioFile(...)` 仍保留为兼容性别名。 -插件还可以通过 `api.runtime.subagent` 启动后台 subagent 运行: +插件还可以通过 `api.runtime.subagent` 启动后台子智能体运行: ```ts const result = await api.runtime.subagent.run({ @@ -868,13 +848,14 @@ const result = await api.runtime.subagent.run({ 说明: -- `provider` 和 `model` 是每次运行可选覆盖项,而不是持久性会话变更。 -- OpenClaw 仅对可信调用方接受这些覆盖字段。 -- 对于插件拥有的回退运行,操作员必须通过 `plugins.entries..subagent.allowModelOverride: true` 明确选择启用。 -- 使用 `plugins.entries..subagent.allowedModels` 将可信插件限制到特定规范的 `provider/model` 目标,或设置为 `"*"` 以显式允许任意目标。 -- 不可信插件的 subagent 运行仍可工作,但覆盖请求会被拒绝,而不是静默回退。 +- `provider` 和 `model` 是按次运行覆盖项,不会持久改变会话设置。 +- OpenClaw 仅对受信任调用方接受这些覆盖字段。 +- 对于插件自有回退运行,运维者必须通过 `plugins.entries..subagent.allowModelOverride: true` 显式启用。 +- 使用 `plugins.entries..subagent.allowedModels` 将受信任插件限制到特定规范 `provider/model` 目标,或设置为 `"*"` 以显式允许任意目标。 +- 不受信任的插件子智能体运行仍可工作,但覆盖请求会被拒绝,而不是静默回退。 -对于 Web 搜索,插件可以消费共享运行时辅助函数,而不是直接访问智能体工具接线: +对于 Web 搜索,插件可以消费共享运行时辅助工具,而不是 +深入智能体工具接线: ```ts const providers = api.runtime.webSearch.listProviders({ @@ -895,9 +876,9 @@ const result = await api.runtime.webSearch.search({ 说明: -- 将提供商选择、凭证解析和共享请求语义保留在核心中。 -- 对于供应商特定搜索传输层,使用 Web 搜索提供商。 -- `api.runtime.webSearch.*` 是功能 / 渠道插件获取搜索能力的首选共享接口,而无需依赖智能体工具包装器。 +- 将提供商选择、凭据解析和共享请求语义保留在 core 中。 +- 对厂商专属搜索传输使用 Web 搜索提供商。 +- `api.runtime.webSearch.*` 是功能 / 渠道插件需要搜索行为但不依赖智能体工具包装器时的首选共享接口。 ### `api.runtime.imageGeneration` @@ -913,7 +894,7 @@ const providers = api.runtime.imageGeneration.listProviders({ ``` - `generate(...)`:使用已配置的图像生成提供商链生成图像。 -- `listProviders(...)`:列出可用的图像生成提供商及其能力。 +- `listProviders(...)`:列出可用图像生成提供商及其能力。 ## Gateway 网关 HTTP 路由 @@ -935,32 +916,32 @@ api.registerHttpRoute({ 路由字段: - `path`:Gateway 网关 HTTP 服务器下的路由路径。 -- `auth`:必填。使用 `"gateway"` 以要求常规 Gateway 网关认证,或使用 `"plugin"` 以启用插件管理的认证 / webhook 验证。 +- `auth`:必填。使用 `"gateway"` 以要求普通 Gateway 网关认证,或使用 `"plugin"` 以进行插件自主管理的认证 / webhook 校验。 - `match`:可选。`"exact"`(默认)或 `"prefix"`。 -- `replaceExisting`:可选。允许同一插件替换自己已有的路由注册。 +- `replaceExisting`:可选。允许同一个插件替换它自己现有的路由注册。 - `handler`:当路由处理了请求时返回 `true`。 说明: -- `api.registerHttpHandler(...)` 已移除,并会导致插件加载错误。请改用 `api.registerHttpRoute(...)`。 +- `api.registerHttpHandler(...)` 已被移除,并会导致插件加载错误。请改用 `api.registerHttpRoute(...)`。 - 插件路由必须显式声明 `auth`。 -- 除非设置 `replaceExisting: true`,否则精确的 `path + match` 冲突会被拒绝,而且一个插件不能替换另一个插件的路由。 -- `auth` 级别不同的重叠路由会被拒绝。`exact` / `prefix` 级联链只能保留在相同 auth 级别下。 -- `auth: "plugin"` 路由**不会**自动接收操作员运行时作用域。它们用于插件管理的 webhook / 签名验证,而不是特权 Gateway 网关辅助调用。 -- `auth: "gateway"` 路由会在 Gateway 网关请求运行时作用域中执行,但该作用域被有意设计得较为保守: - - 共享密钥 bearer auth(`gateway.auth.mode = "token"` / `"password"`)会将插件路由运行时作用域固定为 `operator.write`,即使调用方发送了 `x-openclaw-scopes` - - 可信的携带身份 HTTP 模式(例如 `trusted-proxy` 或私有入口上的 `gateway.auth.mode = "none"`)仅会在显式存在该头时遵循 `x-openclaw-scopes` - - 如果这些携带身份的插件路由请求中缺少 `x-openclaw-scopes`,运行时作用域会回退为 `operator.write` -- 实用规则:不要假设某个经过 gateway-auth 的插件路由就是隐式管理员接口。如果你的路由需要仅管理员行为,应要求使用携带身份的认证模式,并记录清楚显式 `x-openclaw-scopes` 头契约。 +- 除非 `replaceExisting: true`,否则精确 `path + match` 冲突会被拒绝,并且一个插件不能替换另一个插件的路由。 +- 不同 `auth` 级别的重叠路由会被拒绝。请仅在相同 auth 级别内保留 `exact` / `prefix` 的贯通链。 +- `auth: "plugin"` 路由**不会**自动获得运维者运行时作用域。它们用于插件自主管理的 webhook / 签名校验,而不是特权 Gateway 网关辅助调用。 +- `auth: "gateway"` 路由运行在 Gateway 网关请求运行时作用域内,但该作用域被有意设计得较为保守: + - 共享密钥 bearer 认证(`gateway.auth.mode = "token"` / `"password"`)会让插件路由运行时作用域固定为 `operator.write`,即使调用方发送了 `x-openclaw-scopes` + - 受信任的、带身份的 HTTP 模式(例如 `trusted-proxy` 或私有入口上的 `gateway.auth.mode = "none"`)仅在显式存在该 header 时才会尊重 `x-openclaw-scopes` + - 如果这些带身份的插件路由请求中缺少 `x-openclaw-scopes`,运行时作用域会回退到 `operator.write` +- 实用规则:不要假设一个经过 gateway 认证的插件路由天然就是管理员接口。如果你的路由需要仅管理员行为,请要求使用带身份的认证模式,并记录清楚显式 `x-openclaw-scopes` header 契约。 ## 插件 SDK 导入路径 -编写插件时,请使用 SDK 子路径,而不是单体的 `openclaw/plugin-sdk` 导入: +在编写插件时,请使用 SDK 子路径,而不是单体式的 `openclaw/plugin-sdk` 导入: -- 使用 `openclaw/plugin-sdk/plugin-entry` 获取插件注册原语。 -- 使用 `openclaw/plugin-sdk/core` 获取通用共享的插件侧契约。 -- 使用 `openclaw/plugin-sdk/config-schema` 获取根 `openclaw.json` Zod 模式导出 - (`OpenClawSchema`)。 +- `openclaw/plugin-sdk/plugin-entry` 用于插件注册原语。 +- `openclaw/plugin-sdk/core` 用于通用共享的面向插件契约。 +- `openclaw/plugin-sdk/config-schema` 用于根 `openclaw.json` Zod schema + 导出(`OpenClawSchema`)。 - 稳定的渠道原语,例如 `openclaw/plugin-sdk/channel-setup`、 `openclaw/plugin-sdk/setup-runtime`、 `openclaw/plugin-sdk/setup-adapter-runtime`、 @@ -974,12 +955,13 @@ api.registerHttpRoute({ `openclaw/plugin-sdk/command-auth`、 `openclaw/plugin-sdk/secret-input` 和 `openclaw/plugin-sdk/webhook-ingress`,用于共享设置 / 认证 / 回复 / webhook - 接线。`channel-inbound` 是防抖、提及匹配、信封格式化和入站信封上下文辅助函数的共享位置。 - `channel-setup` 是狭义可选安装设置接缝。 + 接线。`channel-inbound` 是 debounce、提及匹配、 + envelope 格式化以及入站 envelope 上下文辅助工具的共享归属位置。 + `channel-setup` 是精简的可选安装设置接缝。 `setup-runtime` 是 `setupEntry` / - 延迟启动使用的运行时安全设置接口,包括导入安全的设置补丁适配器。 - `setup-adapter-runtime` 是感知环境的账户设置适配器接缝。 - `setup-tools` 是小型 CLI / 归档 / 文档辅助接缝(`formatCliCommand`、 + 延迟启动所使用的运行时安全设置接口,包括导入安全的设置 patch adapters。 + `setup-adapter-runtime` 是感知环境的账户设置 adapter 接缝。 + `setup-tools` 是小型 CLI / archive / docs 辅助工具接缝(`formatCliCommand`、 `detectBinary`、`extractArchive`、`resolveBrewExecutable`、`formatDocsLink`、 `CONFIG_DIR`)。 - 领域子路径,例如 `openclaw/plugin-sdk/channel-config-helpers`、 @@ -997,159 +979,178 @@ api.registerHttpRoute({ `openclaw/plugin-sdk/status-helpers`、 `openclaw/plugin-sdk/text-runtime`、 `openclaw/plugin-sdk/runtime-store` 和 - `openclaw/plugin-sdk/directory-runtime`,用于共享运行时 / 配置辅助函数。 - `telegram-command-config` 是 Telegram 自定义命令规范化 / 验证的狭义公共接缝,即使内置 Telegram 契约接口暂时不可用,它也仍然可用。 + `openclaw/plugin-sdk/directory-runtime`,用于共享运行时 / 配置辅助工具。 + `telegram-command-config` 是 Telegram 自定义 + 命令规范化 / 校验的精简公开接缝,即使内置 + Telegram 契约接口暂时不可用,它也保持可用。 `text-runtime` 是共享的文本 / Markdown / 日志接缝,包括 - assistant-visible-text 剥离、Markdown 渲染 / 分块辅助函数、脱敏辅助函数、 - directive-tag 辅助函数和 safe-text 工具。 -- 面向审批的渠道接缝应优先使用插件上的单一 `approvalCapability` - 契约。然后核心会通过这一项能力读取审批认证、交付、渲染和原生路由行为,而不是将审批行为混入无关插件字段中。 -- `openclaw/plugin-sdk/channel-runtime` 已弃用,仅作为旧插件的兼容 shim 保留。 - 新代码应改为导入更狭义的通用原语,仓库代码也不应再新增对该 shim 的导入。 -- 内置扩展内部机制仍然是私有的。外部插件应仅使用 - `openclaw/plugin-sdk/*` 子路径。OpenClaw 核心 / 测试代码可以使用插件包根目录下的仓库公共入口点,例如 `index.js`、`api.js`、 - `runtime-api.js`、`setup-entry.js`,以及诸如 - `login-qr-api.js` 之类的狭义文件。绝不要从核心或其他扩展中导入插件包的 `src/*`。 + 面向 assistant 可见文本剥离、Markdown 渲染 / 分块辅助工具、脱敏 + 辅助工具、directive tag 辅助工具以及 safe-text 实用工具。 +- 审批专用的渠道接缝应优先使用插件上的单一 `approvalCapability` + 契约。然后 core 通过这一项能力读取审批认证、投递、渲染和 + 原生路由行为,而不是将审批行为混入无关的插件字段。 +- `openclaw/plugin-sdk/channel-runtime` 已弃用,仅作为 + 旧版插件的兼容性 shim 保留。新代码应导入更窄的通用原语,而仓库代码不应新增对该 shim 的导入。 +- 内置扩展内部实现仍然是私有的。外部插件应仅使用 + `openclaw/plugin-sdk/*` 子路径。OpenClaw core / 测试代码可以使用 + 某个插件包根目录下的仓库公开入口点,例如 `index.js`、`api.js`、 + `runtime-api.js`、`setup-entry.js` 以及更精细的文件,例如 + `login-qr-api.js`。绝不要从 core 或另一个扩展中导入某个插件包的 `src/*`。 - 仓库入口点拆分: - `/api.js` 是辅助函数 / 类型 barrel, - `/runtime-api.js` 是纯运行时 barrel, + `/api.js` 是辅助工具 / 类型 barrel, + `/runtime-api.js` 是仅运行时 barrel, `/index.js` 是内置插件入口, `/setup-entry.js` 是设置插件入口。 - 当前内置提供商示例: - - Anthropic 使用 `api.js` / `contract-api.js` 提供 Claude 流辅助函数,例如 - `wrapAnthropicProviderStream`、beta-header 辅助函数和 `service_tier` + - Anthropic 使用 `api.js` / `contract-api.js` 提供 Claude 流辅助工具,例如 + `wrapAnthropicProviderStream`、beta header 辅助工具以及 `service_tier` 解析。 - - OpenAI 使用 `api.js` 提供 provider 构建器、默认模型辅助函数和 - realtime provider 构建器。 - - OpenRouter 使用 `api.js` 提供其 provider 构建器及新手引导 / 配置 - 辅助函数,而 `register.runtime.js` 仍可为仓库本地用法重新导出通用 - `plugin-sdk/provider-stream` 辅助函数。 -- 通过 facade 加载的公共入口点,在存在活动运行时配置快照时会优先使用该快照;当 OpenClaw 尚未提供运行时快照时,则回退到磁盘上已解析的配置文件。 -- 通用共享原语仍然是首选公共 SDK 契约。当前仍保留一小组保留兼容集的内置渠道品牌化辅助接缝。应将这些视为内置维护 / 兼容接缝,而不是新的第三方导入目标;新的跨渠道契约仍应落在通用 `plugin-sdk/*` 子路径或插件本地 `api.js` / + - OpenAI 使用 `api.js` 提供提供商构建器、默认模型辅助工具以及 + 实时提供商构建器。 + - OpenRouter 使用 `api.js` 提供其提供商构建器以及新手引导 / 配置 + 辅助工具,而 `register.runtime.js` 仍可为仓库内使用重新导出通用 + `plugin-sdk/provider-stream` 辅助工具。 +- facade 加载的公开入口点会优先使用当前活动的运行时配置快照; + 当 OpenClaw 尚未提供运行时快照时,则回退到磁盘上的已解析配置文件。 +- 通用共享原语仍然是首选公开 SDK 契约。仍然存在一小部分保留的、兼容性用途的内置渠道品牌化辅助工具接缝。应将它们视为内置维护 / 兼容性接缝,而不是新的第三方导入目标;新的跨渠道契约仍应落在通用 `plugin-sdk/*` 子路径或插件本地 `api.js` / `runtime-api.js` barrel 上。 兼容性说明: -- 新代码应避免使用根 `openclaw/plugin-sdk` barrel。 -- 优先使用更狭义、稳定的原语。较新的 setup / pairing / reply / +- 新代码请避免使用根 `openclaw/plugin-sdk` barrel。 +- 优先使用精简稳定原语。更新的 setup / pairing / reply / feedback / contract / inbound / threading / command / secret-input / webhook / infra / - allowlist / status / message-tool 子路径,是新的内置和外部插件工作的预期契约。 - 目标解析 / 匹配应归于 `openclaw/plugin-sdk/channel-targets`。 - 消息动作 gate 和 reaction message-id 辅助函数应归于 + allowlist / status / message-tool 子路径是新内置和外部插件工作的预期契约。 + 目标解析 / 匹配应放在 `openclaw/plugin-sdk/channel-targets`。 + 消息操作门控和 reaction message id 辅助工具应放在 `openclaw/plugin-sdk/channel-actions`。 -- 默认情况下,内置扩展专用辅助 barrel 不稳定。如果某个辅助函数只被某个内置扩展需要,应将其保留在该扩展本地的 `api.js` 或 `runtime-api.js` 接缝后面,而不是提升到 +- 默认情况下,内置扩展专用辅助工具 barrel 并不稳定。如果某个 + 辅助工具只被某个内置扩展需要,请将它保留在扩展本地 + `api.js` 或 `runtime-api.js` 接缝后面,而不是提升为 `openclaw/plugin-sdk/`。 -- 新的共享辅助接缝应当是通用的,而不是带渠道品牌的。共享目标解析应归于 - `openclaw/plugin-sdk/channel-targets`;渠道特定内部机制应保留在归属插件本地的 `api.js` 或 `runtime-api.js` 接缝后面。 -- 能力特定子路径,如 `image-generation`、 - `media-understanding` 和 `speech`,之所以存在,是因为当前内置 / 原生插件正在使用它们。但这本身并不意味着其中每个导出的辅助函数都是长期冻结的外部契约。 +- 新的共享辅助工具接缝应当是通用的,而不是带渠道品牌的。共享目标 + 解析应归于 `openclaw/plugin-sdk/channel-targets`;渠道专属 + 内部实现则应保留在所属插件的本地 `api.js` 或 `runtime-api.js` + 接缝之后。 +- 像 `image-generation`、 + `media-understanding` 和 `speech` 这样的能力专用子路径之所以存在,是因为 + 当前内置 / 原生插件正在使用它们。但这并不自动意味着其中每个导出辅助工具 + 都是长期冻结的外部契约。 -## Message 工具模式 +## 消息工具 schema -插件应拥有渠道特定的 `describeMessageTool(...)` 模式贡献。请将提供商特定字段保留在插件中,而不是放入共享核心。 +插件应拥有渠道专属的 `describeMessageTool(...)` schema +扩展。请将提供商专属字段保留在插件中,而不要放入共享 core。 -对于共享的可移植模式片段,请复用通过 -`openclaw/plugin-sdk/channel-actions` 导出的通用辅助函数: +对于共享的可移植 schema 片段,请复用通过 +`openclaw/plugin-sdk/channel-actions` 导出的通用辅助工具: - `createMessageToolButtonsSchema()` 用于按钮网格式负载 - `createMessageToolCardSchema()` 用于结构化卡片负载 -如果某种模式结构只适用于某一个提供商,应在该插件自己的源码中定义,而不是将其提升到共享 SDK 中。 +如果某个 schema 形状只对一个提供商有意义,请在该插件自己的 +源码中定义它,而不要将其提升到共享 SDK 中。 ## 渠道目标解析 -渠道插件应拥有渠道特定的目标语义。保持共享出站宿主通用,并使用消息适配器接口处理提供商规则: +渠道插件应拥有渠道专属的目标语义。请保持共享 +outbound host 的通用性,并使用消息 adapter 接口处理提供商规则: -- `messaging.inferTargetChatType({ to })` 决定规范化目标在目录查找前应被视为 `direct`、`group` 还是 `channel`。 -- `messaging.targetResolver.looksLikeId(raw, normalized)` 告诉核心某个输入是否应直接跳到类 id 解析,而不是目录搜索。 -- `messaging.targetResolver.resolveTarget(...)` 是当核心在规范化后或目录未命中后需要最终提供商拥有解析结果时,插件侧的回退路径。 -- `messaging.resolveOutboundSessionRoute(...)` 拥有目标解析完成后提供商特定的会话路由构建逻辑。 +- `messaging.inferTargetChatType({ to })` 决定规范化目标在目录查找前 + 应被视为 `direct`、`group` 还是 `channel`。 +- `messaging.targetResolver.looksLikeId(raw, normalized)` 告诉 core 某个 + 输入是否应直接跳到类 id 解析,而不是目录搜索。 +- `messaging.targetResolver.resolveTarget(...)` 是在规范化之后或目录未命中后, + core 需要最终提供商自有解析时的插件回退。 +- `messaging.resolveOutboundSessionRoute(...)` 在目标解析完成后拥有 + 提供商专属的会话路由构建逻辑。 -推荐拆分: +推荐拆分方式: -- 对于应在搜索 peer / group 前发生的分类决策,使用 `inferTargetChatType`。 -- 对于“将其视为显式 / 原生目标 id”的检查,使用 `looksLikeId`。 -- 对于提供商特定的规范化回退,使用 `resolveTarget`,而不是广义目录搜索。 -- 将聊天 id、线程 id、JID、handle 和 room id 等提供商原生 id 保留在 `target` 值或提供商特定参数中,而不要放入通用 SDK 字段。 +- 使用 `inferTargetChatType` 处理应在搜索 peers / groups 之前发生的类别决策。 +- 使用 `looksLikeId` 处理“将其视为显式 / 原生 target id”的检查。 +- 使用 `resolveTarget` 处理提供商专属的规范化回退,而不是广泛的目录搜索。 +- 将提供商原生 id(例如 chat id、thread id、JID、handle 和 room id)保留在 `target` 值或提供商专属参数中,而不要放进通用 SDK 字段。 -## 配置支持的目录 +## 配置驱动目录 -从配置派生目录项的插件,应将该逻辑保留在插件中,并复用 -`openclaw/plugin-sdk/directory-runtime` 中的共享辅助函数。 +对于从配置派生目录条目的插件,请将该逻辑保留在插件中,并复用 +`openclaw/plugin-sdk/directory-runtime` 中的共享辅助工具。 -当某个渠道需要配置支持的 peer / group 时,请使用此方式,例如: +当某个渠道需要配置驱动的 peers / groups 时,请使用这种方式,例如: -- 由 allowlist 驱动的私信 peer +- 由 allowlist 驱动的私信 peers - 已配置的渠道 / 群组映射 -- 按账户范围的静态目录回退 +- 账户作用域的静态目录回退 -`directory-runtime` 中的共享辅助函数仅处理通用操作: +`directory-runtime` 中的共享辅助工具仅处理通用操作: - 查询过滤 - 限制应用 -- 去重 / 规范化辅助函数 +- 去重 / 规范化辅助工具 - 构建 `ChannelDirectoryEntry[]` -渠道特定的账户检查和 id 规范化应保留在插件实现中。 +渠道专属的账户检查和 id 规范化应保留在插件实现中。 ## 提供商目录 提供商插件可以通过 -`registerProvider({ catalog: { run(...) { ... } } })` -定义用于推理的模型目录。 +`registerProvider({ catalog: { run(...) { ... } } })` 定义用于推理的模型目录。 `catalog.run(...)` 返回与 OpenClaw 写入 -`models.providers` 相同的结构: +`models.providers` 的相同结构: -- `{ provider }` 表示单个提供商条目 -- `{ providers }` 表示多个提供商条目 +- `{ provider }` 表示一个 provider 条目 +- `{ providers }` 表示多个 provider 条目 -当插件拥有提供商特定 model id、base URL 默认值或认证门控模型元数据时,请使用 `catalog`。 +当插件拥有提供商专属 model id、base URL 默认值或受认证门控的模型元数据时,请使用 `catalog`。 -`catalog.order` 控制插件目录相对于 OpenClaw 内置隐式提供商的合并时机: +`catalog.order` 控制插件目录相对于 OpenClaw +内置隐式提供商的合并时机: -- `simple`:纯 API key 或环境变量驱动的提供商 -- `profile`:存在认证配置文件时出现的提供商 -- `paired`:合成多个相关提供商条目的提供商 +- `simple`:普通 API key 或环境变量驱动的提供商 +- `profile`:当存在 auth profiles 时出现的提供商 +- `paired`:会合成多个关联 provider 条目的提供商 - `late`:最后一轮,在其他隐式提供商之后 -较晚的提供商在键冲突时会获胜,因此插件可以有意用相同 provider id 覆盖内置提供商条目。 +后出现的提供商在 key 冲突时会获胜,因此插件可以有意用相同 provider id 覆盖内置 provider 条目。 -兼容性说明: +兼容性: -- `discovery` 仍可作为旧版别名使用 +- `discovery` 仍可用作旧版别名 - 如果同时注册了 `catalog` 和 `discovery`,OpenClaw 会使用 `catalog` ## 只读渠道检查 -如果你的插件注册了一个渠道,请优先实现 -`plugin.config.inspectAccount(cfg, accountId)`,并与 `resolveAccount(...)` 配套提供。 +如果你的插件注册了一个渠道,建议同时实现 +`plugin.config.inspectAccount(cfg, accountId)` 和 `resolveAccount(...)`。 -原因如下: +原因: -- `resolveAccount(...)` 是运行时路径。它可以假定凭证已完全具体化,并在缺少必需 secret 时快速失败。 -- 只读命令路径,例如 `openclaw status`、`openclaw status --all`、 - `openclaw channels status`、`openclaw channels resolve`,以及 doctor / config - 修复流程,不应仅为了描述配置就必须具体化运行时凭证。 +- `resolveAccount(...)` 是运行时路径。它可以假设凭据 + 已完全实体化,并在缺失必要 secret 时快速失败。 +- 像 `openclaw status`、`openclaw status --all`、 + `openclaw channels status`、`openclaw channels resolve` 以及 doctor / config + 修复流程这样的只读命令路径,不应为了描述配置就去实体化运行时凭据。 推荐的 `inspectAccount(...)` 行为: - 仅返回描述性的账户状态。 - 保留 `enabled` 和 `configured`。 -- 在相关时包含凭证来源 / 状态字段,例如: - - `tokenSource`、`tokenStatus` - - `botTokenSource`、`botTokenStatus` - - `appTokenSource`、`appTokenStatus` - - `signingSecretSource`、`signingSecretStatus` -- 你无需为了报告只读可用性而返回原始 token 值。返回 - `tokenStatus: "available"`(以及对应的 source 字段)就足以支持状态类命令。 -- 当凭证通过 SecretRef 配置、但在当前命令路径中不可用时,使用 `configured_unavailable`。 +- 在相关时包含凭据来源 / 状态字段,例如: + - `tokenSource`, `tokenStatus` + - `botTokenSource`, `botTokenStatus` + - `appTokenSource`, `appTokenStatus` + - `signingSecretSource`, `signingSecretStatus` +- 你不需要返回原始 token 值来报告只读可用性。返回 + `tokenStatus: "available"`(以及匹配的 source 字段)就足够用于状态类命令。 +- 当凭据通过 SecretRef 配置,但在当前命令路径中不可用时,请使用 `configured_unavailable`。 -这样一来,只读命令就能报告“已配置,但在该命令路径中不可用”,而不是崩溃或错误地报告该账户未配置。 +这样只读命令就能报告“已配置,但在当前命令路径中不可用”,而不是崩溃或错误地将账户报告为未配置。 -## Package packs +## 包集合 -插件目录可以包含一个带有 `openclaw.extensions` 的 `package.json`: +一个插件目录可以包含带有 `openclaw.extensions` 的 `package.json`: ```json { @@ -1161,47 +1162,56 @@ api.registerHttpRoute({ } ``` -每个条目都会成为一个插件。如果该 pack 列出了多个扩展,插件 id -将变为 `name/`。 +每个条目都会变成一个插件。如果该 pack 列出多个扩展,则插件 id +会变为 `name/`。 -如果你的插件导入了 npm 依赖,请在该目录中安装它们,以便 +如果你的插件导入了 npm 依赖,请在该目录中安装它们,以确保 `node_modules` 可用(`npm install` / `pnpm install`)。 -安全护栏:每个 `openclaw.extensions` 条目在解析符号链接后都必须保留在插件目录内。逃出包目录的条目会被拒绝。 +安全护栏:每个 `openclaw.extensions` 条目在解析 symlink 后都必须仍位于插件 +目录内部。任何逃逸出包目录的条目都会被拒绝。 -安全说明:`openclaw plugins install` 会使用 -`npm install --omit=dev --ignore-scripts` 安装插件依赖 -(运行时不执行生命周期脚本,也不安装 dev dependencies)。请保持插件依赖树为“纯 JS / TS”,并避免需要 `postinstall` 构建的包。 +安全说明:`openclaw plugins install` 安装插件依赖时使用 +`npm install --omit=dev --ignore-scripts`(无生命周期脚本,运行时无 dev dependencies)。请保持插件依赖树为“纯 JS / TS”,并避免依赖需要 `postinstall` 构建的包。 可选:`openclaw.setupEntry` 可以指向一个轻量级、仅用于设置的模块。 -当 OpenClaw 需要为已禁用的渠道插件提供设置接口,或者某个渠道插件已启用但尚未配置时,它会加载 `setupEntry`,而不是完整插件入口。这样在主插件入口还会接线工具、钩子或其他仅运行时代码的情况下,可让启动和设置更轻量。 +当 OpenClaw 需要为一个已禁用的渠道插件提供设置接口,或者 +当某个渠道插件已启用但尚未配置时,它会加载 `setupEntry`,而不是完整插件入口。这样在你的主插件入口同时接线工具、hooks 或其他仅运行时代码时, +可以让启动和设置更轻量。 可选:`openclaw.startup.deferConfiguredChannelFullLoadUntilAfterListen` -可以让一个渠道插件在 Gateway 网关预监听启动阶段也选择相同的 `setupEntry` -路径,即使该渠道已经配置完成。 +可以让渠道插件在 Gateway 网关监听前的启动阶段也使用相同的 `setupEntry` 路径, +即使该渠道已经配置完成。 -仅当 `setupEntry` 完全覆盖了网关开始监听前必须存在的启动接口时,才应使用此选项。实际而言,这意味着设置入口必须注册启动所依赖的每一种渠道拥有能力,例如: +仅当 `setupEntry` 完整覆盖了 Gateway 网关开始监听前必须存在的启动接口时才应使用此选项。实践中,这意味着设置入口 +必须注册启动所依赖的每一项渠道自有能力,例如: - 渠道注册本身 -- 在 Gateway 网关开始监听前必须可用的所有 HTTP 路由 -- 在同一窗口期必须存在的所有 Gateway 网关方法、工具或服务 +- 任何必须在 Gateway 网关开始监听前可用的 HTTP 路由 +- 任何在同一时间窗口内必须存在的 Gateway 网关方法、工具或服务 -如果你的完整入口仍拥有任何必需的启动能力,请不要启用该标志。应保持插件使用默认行为,并让 OpenClaw 在启动期间加载完整入口。 +如果你的完整入口仍然拥有任何必需的启动能力,请不要启用 +此标志。应保持默认行为,让 OpenClaw 在启动期间加载完整入口。 -内置渠道也可以发布仅设置用的契约接口辅助函数,以便核心在完整渠道运行时加载前进行咨询。当前设置提升接口包括: +内置渠道也可以发布仅设置用途的契约接口辅助工具,供 core 在完整 +渠道运行时加载前查询。当前设置提升接口包括: - `singleAccountKeysToMove` - `namedAccountPromotionKeys` - `resolveSingleAccountPromotionTarget(...)` -当核心需要在不加载完整插件入口的情况下,将旧版单账户渠道配置提升到 -`channels..accounts.*` 时,会使用该接口。Matrix 是当前的内置示例:当已存在命名账户时,它只会将认证 / bootstrap 键移动到某个命名提升账户中,并且可以保留一个已配置但非规范的 default-account 键,而不是总是创建 +当 core 需要将旧版单账户渠道配置提升到 +`channels..accounts.*`,且无需加载完整插件入口时,就会使用该接口。 +Matrix 是当前的内置示例:当已存在命名账户时,它只会将 auth / bootstrap 键迁移到一个已命名的提升账户中,并且可以保留已配置的非规范 default account key,而不是总是创建 `accounts.default`。 -这些设置补丁适配器可以让内置契约接口发现保持惰性。导入时仍然很轻量;提升接口仅在首次使用时加载,而不是在模块导入时重新进入内置渠道启动逻辑。 +这些设置 patch adapters 使内置契约接口发现保持惰性。导入 +时间保持轻量;提升接口只会在首次使用时加载,而不是在模块导入时重新进入内置渠道启动流程。 -当这些启动接口包含 Gateway 网关 RPC 方法时,应将它们保留在插件特定前缀下。核心管理命名空间(`config.*`、 -`exec.approvals.*`、`wizard.*`、`update.*`)仍是保留命名空间,并且始终解析为 `operator.admin`,即使插件请求更窄的作用域。 +当这些启动接口包含 Gateway 网关 RPC 方法时,请保持它们位于 +插件专属前缀下。core 管理命名空间(`config.*`、 +`exec.approvals.*`、`wizard.*`、`update.*`)仍然保留,并始终解析为 +`operator.admin`,即使某个插件请求了更窄的作用域。 示例: @@ -1220,7 +1230,7 @@ api.registerHttpRoute({ ### 渠道目录元数据 -渠道插件可以通过 `openclaw.channel` 宣传设置 / 发现元数据,并通过 `openclaw.install` 提供安装提示。这样可以让核心目录保持无数据化。 +渠道插件可以通过 `openclaw.channel` 宣传设置 / 发现元数据,并通过 `openclaw.install` 提供安装提示。这样可让 core 保持无数据。 示例: @@ -1250,36 +1260,35 @@ api.registerHttpRoute({ 除最小示例外,其他有用的 `openclaw.channel` 字段包括: -- `detailLabel`:用于更丰富目录 / 状态接口的次级标签 +- `detailLabel`:更丰富目录 / 状态接口中的次级标签 - `docsLabel`:覆盖文档链接文本 -- `preferOver`:当前目录项应优先于哪些低优先级插件 / 渠道 id -- `selectionDocsPrefix`、`selectionDocsOmitLabel`、`selectionExtras`:选择界面文案控制项 -- `markdownCapable`:将渠道标记为支持 Markdown,用于出站格式决策 +- `preferOver`:该目录条目应优先于的低优先级插件 / 渠道 id +- `selectionDocsPrefix`、`selectionDocsOmitLabel`、`selectionExtras`:用于选择界面文案控制 +- `markdownCapable`:将渠道标记为支持 Markdown,以供出站格式决策使用 - `exposure.configured`:设为 `false` 时,在已配置渠道列表接口中隐藏该渠道 - `exposure.setup`:设为 `false` 时,在交互式设置 / 配置选择器中隐藏该渠道 -- `exposure.docs`:在文档导航界面中将渠道标记为内部 / 私有 -- `showConfigured` / `showInSetup`:旧版兼容别名仍可接受;优先使用 `exposure` -- `quickstartAllowFrom`:让该渠道接入标准快速开始 `allowFrom` 流程 -- `forceAccountBinding`:即使仅存在一个账户,也要求显式账户绑定 -- `preferSessionLookupForAnnounceTarget`:在解析 announce 目标时优先使用会话查找 +- `exposure.docs`:将渠道标记为内部 / 私有,用于文档导航接口 +- `showConfigured` / `showInSetup`:仍接受的旧版兼容别名;优先使用 `exposure` +- `quickstartAllowFrom`:让渠道接入标准快速开始 `allowFrom` 流程 +- `forceAccountBinding`:即使只存在一个账户,也要求显式账户绑定 +- `preferSessionLookupForAnnounceTarget`:在解析 announce target 时优先进行会话查找 OpenClaw 还可以合并**外部渠道目录**(例如 MPM -注册表导出)。将一个 JSON 文件放到以下任一路径: +注册表导出)。将 JSON 文件放到以下任一位置: - `~/.openclaw/mpm/plugins.json` - `~/.openclaw/mpm/catalog.json` - `~/.openclaw/plugins/catalog.json` -或者将 `OPENCLAW_PLUGIN_CATALOG_PATHS`(或 `OPENCLAW_MPM_CATALOG_PATHS`)指向一个或多个 JSON 文件(使用逗号 / 分号 / `PATH` 分隔)。每个文件应包含 -`{ "entries": [ { "name": "@scope/pkg", "openclaw": { "channel": {...}, "install": {...} } } ] }`。解析器也接受 `"packages"` 或 `"plugins"` 作为 `"entries"` 键的旧版别名。 +或者将 `OPENCLAW_PLUGIN_CATALOG_PATHS`(或 `OPENCLAW_MPM_CATALOG_PATHS`)指向一个或多个 JSON 文件(使用逗号 / 分号 / `PATH` 分隔)。每个文件应包含 `{ "entries": [ { "name": "@scope/pkg", "openclaw": { "channel": {...}, "install": {...} } } ] }`。解析器也接受 `"packages"` 或 `"plugins"` 作为 `"entries"` 键的旧版别名。 ## 上下文引擎插件 -上下文引擎插件拥有会话上下文编排逻辑,负责摄取、组装和压缩。可在你的插件中通过 -`api.registerContextEngine(id, factory)` 注册它们,然后用 +上下文引擎插件拥有会话上下文编排能力,用于摄取、组装和压缩。请在你的插件中通过 +`api.registerContextEngine(id, factory)` 注册它们,然后通过 `plugins.slots.contextEngine` 选择活动引擎。 -当你的插件需要替换或扩展默认上下文流水线,而不是只添加内存搜索或钩子时,请使用这一机制。 +当你的插件需要替换或扩展默认上下文流水线,而不仅仅是增加 memory 搜索或 hooks 时,请使用此方式。 ```ts export default function (api) { @@ -1298,8 +1307,8 @@ export default function (api) { } ``` -如果你的引擎**不**拥有压缩算法,请保持 `compact()` -实现,并显式委托它: +如果你的引擎**并不**拥有压缩算法,请保持 `compact()` +已实现,并显式委托它: ```ts import { delegateCompactionToRuntime } from "openclaw/plugin-sdk/core"; @@ -1326,38 +1335,41 @@ export default function (api) { ## 添加新能力 -当插件需要当前 API 无法很好表达的行为时,不要通过私有深层访问绕过插件系统。应添加缺失的能力。 +当插件需要当前 API 无法适配的行为时,不要通过私有深入访问绕过 +插件系统。请添加缺失的能力。 推荐顺序: -1. 定义核心契约 - 明确哪些共享行为应由核心拥有:策略、回退、配置合并、 - 生命周期、面向渠道的语义和运行时辅助函数形态。 +1. 定义 core 契约 + 明确共享行为中哪些由 core 拥有:策略、回退、配置合并、 + 生命周期、面向渠道的语义,以及运行时辅助工具形状。 2. 添加类型化插件注册 / 运行时接口 - 用最小但有用的类型化能力接口扩展 `OpenClawPluginApi` 和 / 或 `api.runtime`。 -3. 接线核心 + 渠道 / 功能消费者 - 渠道和功能插件应通过核心消费新能力,而不是直接导入某个供应商实现。 -4. 注册供应商实现 - 然后由供应商插件针对该能力注册其后端。 + 以最小但有用的类型化能力接口扩展 `OpenClawPluginApi` 和 / 或 `api.runtime`。 +3. 接线 core + 渠道 / 功能消费者 + 渠道和功能插件应通过 core 消费新能力, + 而不是直接导入某个厂商实现。 +4. 注册厂商实现 + 厂商插件随后针对该能力注册自己的后端。 5. 添加契约覆盖 - 添加测试,以便归属和注册结构能够随着时间推移继续保持明确。 + 添加测试,以便随着时间推移,归属和注册形状保持明确。 -这就是 OpenClaw 在保持明确立场的同时,不会被某个单一提供商世界观硬编码的方式。具体文件清单和完整示例,请参阅[能力扩展手册](/zh-CN/plugins/architecture)。 +这就是 OpenClaw 如何在保持明确主张的同时,不会被硬编码到某一个 +提供商世界观中。具体的文件清单和完整示例,请参阅[能力扩展手册](/zh-CN/plugins/architecture)。 -### 能力检查清单 +### 能力清单 当你添加一个新能力时,实现通常应同时涉及以下接口: -- `src//types.ts` 中的核心契约类型 -- `src//runtime.ts` 中的核心运行器 / 运行时辅助函数 +- `src//types.ts` 中的 core 契约类型 +- `src//runtime.ts` 中的 core runner / 运行时辅助工具 - `src/plugins/types.ts` 中的插件 API 注册接口 - `src/plugins/registry.ts` 中的插件注册表接线 -- 当功能 / 渠道插件需要消费它时,`src/plugins/runtime/*` 中的插件运行时暴露 -- `src/test-utils/plugin-registration.ts` 中的捕获 / 测试辅助函数 +- 当功能 / 渠道插件需要消费它时,位于 `src/plugins/runtime/*` 的插件运行时暴露层 +- `src/test-utils/plugin-registration.ts` 中的捕获 / 测试辅助工具 - `src/plugins/contracts/registry.ts` 中的归属 / 契约断言 -- `docs/` 中面向操作员 / 插件的文档 +- `docs/` 中面向运维者 / 插件的文档 -如果其中某个接口缺失,通常意味着该能力尚未完全集成。 +如果这些接口中的某一个缺失,通常意味着该能力还没有真正完成集成。 ### 能力模板 @@ -1395,7 +1407,7 @@ expect(findVideoGenerationProviderIdsForPlugin("openai")).toEqual(["openai"]); 这样规则就很简单: -- 核心拥有能力契约 + 编排 -- 供应商插件拥有供应商实现 -- 功能 / 渠道插件消费运行时辅助函数 -- 契约测试让归属保持明确 +- core 拥有能力契约 + 编排 +- 厂商插件拥有厂商实现 +- 功能 / 渠道插件消费运行时辅助工具 +- 契约测试使归属保持明确 diff --git a/docs/zh-CN/plugins/building-plugins.md b/docs/zh-CN/plugins/building-plugins.md index 3cd368f8a..174c39a7b 100644 --- a/docs/zh-CN/plugins/building-plugins.md +++ b/docs/zh-CN/plugins/building-plugins.md @@ -1,51 +1,51 @@ --- read_when: - 你想创建一个新的 OpenClaw 插件 - - 你需要一个用于插件开发的快速开始指南 - - 你要为 OpenClaw 添加一个新的渠道、提供商、工具或其他能力 + - 你需要一个插件开发的快速开始指南 + - 你正在为 OpenClaw 添加新的渠道、提供商、工具或其他能力 sidebarTitle: Getting Started summary: 在几分钟内创建你的第一个 OpenClaw 插件 title: 构建插件 x-i18n: - generated_at: "2026-04-06T00:52:29Z" + generated_at: "2026-04-06T12:43:29Z" model: gpt-5.4 provider: openai - source_hash: 9be344cb300ecbcba08e593a95bcc93ab16c14b28a0ff0c29b26b79d8249146c + source_hash: 509c1f5abe1a0a74966054ed79b71a1a7ee637a43b1214c424acfe62ddf48eef source_path: plugins/building-plugins.md workflow: 15 --- # 构建插件 -插件可通过新增能力来扩展 OpenClaw:渠道、模型提供商、语音、实时转录、实时语音、媒体理解、图像生成、视频生成、网页抓取、网页搜索、智能体工具,或任意组合。 +插件可为 OpenClaw 扩展新能力:渠道、模型提供商、语音、实时转录、实时语音、媒体理解、图像生成、视频生成、网页抓取、网页搜索、智能体工具,或这些能力的任意组合。 -你不需要将你的插件添加到 OpenClaw 仓库中。发布到 [ClawHub](/zh-CN/tools/clawhub) 或 npm,用户即可使用 `openclaw plugins install ` 安装。OpenClaw 会先尝试 ClawHub,并自动回退到 npm。 +你不需要将你的插件添加到 OpenClaw 仓库中。发布到 [ClawHub](/zh-CN/tools/clawhub) 或 npm,用户即可通过 `openclaw plugins install ` 安装。OpenClaw 会优先尝试 ClawHub,并在需要时自动回退到 npm。 -## 先决条件 +## 前置条件 -- Node >= 22 和一个包管理器(npm 或 pnpm) +- Node >= 22,以及一个包管理器(npm 或 pnpm) - 熟悉 TypeScript(ESM) - 对于仓库内插件:已克隆仓库并完成 `pnpm install` -## 哪种类型的插件? +## 你要构建哪种插件? - 将 OpenClaw 连接到一个消息平台(Discord、IRC 等) + 将 OpenClaw 连接到消息平台(Discord、IRC 等) 添加一个模型提供商(LLM、代理或自定义端点) - - 注册智能体工具、事件钩子或服务 — 继续阅读下文 + + 注册智能体工具、事件 hook 或服务 —— 继续阅读下文 -如果某个渠道插件是可选的,并且在运行 onboarding/设置 时可能尚未安装,请使用 `openclaw/plugin-sdk/channel-setup` 中的 `createOptionalChannelSetupSurface(...)`。它会生成一个设置适配器 + 向导 组合,用于提示安装要求,并在插件安装完成之前,对实际配置写入采取默认拒绝策略。 +如果某个渠道插件是可选的,并且在新手引导/设置运行时可能尚未安装,请使用 `openclaw/plugin-sdk/channel-setup` 中的 `createOptionalChannelSetupSurface(...)`。它会生成一个设置适配器 + 向导组合,用于提示安装要求,并在插件安装完成前对真实配置写入进行失败关闭保护。 ## 快速开始:工具插件 -本演练将创建一个用于注册智能体工具的最小插件。渠道插件和提供商插件有上方链接的专门指南。 +本教程将创建一个用于注册智能体工具的最小插件。渠道插件和提供商插件有各自的专用指南,见上方链接。 @@ -82,7 +82,9 @@ x-i18n: ``` - 每个插件都需要一个清单,即使没有配置也是如此。完整 schema 请参见 [Manifest](/zh-CN/plugins/manifest)。规范的 ClawHub 发布片段位于 `docs/snippets/plugin-publish/`。 + 每个插件都需要一个清单,即使没有配置也是如此。完整 schema 请参见 + [Manifest](/zh-CN/plugins/manifest)。规范的 ClawHub + 发布片段位于 `docs/snippets/plugin-publish/`。 @@ -110,13 +112,15 @@ x-i18n: }); ``` - `definePluginEntry` 用于非渠道插件。对于渠道,请使用 `defineChannelPluginEntry` —— 参见 [渠道插件](/zh-CN/plugins/sdk-channel-plugins)。有关完整的入口点选项,请参见 [入口点](/zh-CN/plugins/sdk-entrypoints)。 + `definePluginEntry` 用于非渠道插件。对于渠道,请使用 + `defineChannelPluginEntry` —— 参见 [渠道插件](/zh-CN/plugins/sdk-channel-plugins)。 + 如需了解完整的入口点选项,请参见 [入口点](/zh-CN/plugins/sdk-entrypoints)。 - **外部插件:** 使用 ClawHub 验证并发布,然后安装: + **外部插件:** 通过 ClawHub 验证并发布,然后安装: ```bash clawhub package publish your-org/your-plugin --dry-run @@ -137,11 +141,12 @@ x-i18n: ## 插件能力 -一个插件可以通过 `api` 对象注册任意数量的能力: +单个插件可以通过 `api` 对象注册任意数量的能力: | 能力 | 注册方法 | 详细指南 | | ---------------------- | ------------------------------------------------ | ------------------------------------------------------------------------------- | | 文本推理(LLM) | `api.registerProvider(...)` | [提供商插件](/zh-CN/plugins/sdk-provider-plugins) | +| CLI 推理后端 | `api.registerCliBackend(...)` | [CLI 后端](/gateway/cli-backends) | | 渠道 / 消息 | `api.registerChannel(...)` | [渠道插件](/zh-CN/plugins/sdk-channel-plugins) | | 语音(TTS/STT) | `api.registerSpeechProvider(...)` | [提供商插件](/zh-CN/plugins/sdk-provider-plugins#step-5-add-extra-capabilities) | | 实时转录 | `api.registerRealtimeTranscriptionProvider(...)` | [提供商插件](/zh-CN/plugins/sdk-provider-plugins#step-5-add-extra-capabilities) | @@ -154,33 +159,33 @@ x-i18n: | 网页搜索 | `api.registerWebSearchProvider(...)` | [提供商插件](/zh-CN/plugins/sdk-provider-plugins#step-5-add-extra-capabilities) | | 智能体工具 | `api.registerTool(...)` | 下文 | | 自定义命令 | `api.registerCommand(...)` | [入口点](/zh-CN/plugins/sdk-entrypoints) | -| 事件钩子 | `api.registerHook(...)` | [入口点](/zh-CN/plugins/sdk-entrypoints) | +| 事件 hook | `api.registerHook(...)` | [入口点](/zh-CN/plugins/sdk-entrypoints) | | HTTP 路由 | `api.registerHttpRoute(...)` | [内部机制](/zh-CN/plugins/architecture#gateway-http-routes) | | CLI 子命令 | `api.registerCli(...)` | [入口点](/zh-CN/plugins/sdk-entrypoints) | -有关完整注册 API,请参见 [SDK 概览](/zh-CN/plugins/sdk-overview#registration-api)。 +完整注册 API 请参见 [SDK 概览](/zh-CN/plugins/sdk-overview#registration-api)。 -如果你的插件注册了自定义 Gateway 网关 RPC 方法,请将它们保留在插件专用前缀下。核心管理命名空间(`config.*`、`exec.approvals.*`、`wizard.*`、`update.*`)仍然保留,并且始终解析为 `operator.admin`,即使插件请求了更窄的作用域也是如此。 +如果你的插件注册了自定义 Gateway 网关 RPC 方法,请为它们使用插件专属前缀。核心管理命名空间(`config.*`、`exec.approvals.*`、`wizard.*`、`update.*`)保持保留状态,并且始终解析到 `operator.admin`,即使插件请求了更窄的作用域也是如此。 -需要注意的钩子守卫语义: +需要注意的 hook 守卫语义: -- `before_tool_call`: `{ block: true }` 是终态结果,会阻止更低优先级的处理器继续执行。 -- `before_tool_call`: `{ block: false }` 会被视为未作决定。 -- `before_tool_call`: `{ requireApproval: true }` 会暂停智能体执行,并通过 exec 审批覆盖层、Telegram 按钮、Discord 交互,或任意渠道上的 `/approve` 命令提示用户审批。 -- `before_install`: `{ block: true }` 是终态结果,会阻止更低优先级的处理器继续执行。 -- `before_install`: `{ block: false }` 会被视为未作决定。 -- `message_sending`: `{ cancel: true }` 是终态结果,会阻止更低优先级的处理器继续执行。 -- `message_sending`: `{ cancel: false }` 会被视为未作决定。 +- `before_tool_call`:`{ block: true }` 为终止结果,并会阻止更低优先级的处理器继续执行。 +- `before_tool_call`:`{ block: false }` 会被视为未作决定。 +- `before_tool_call`:`{ requireApproval: true }` 会暂停智能体执行,并通过 exec 审批覆盖层、Telegram 按钮、Discord 交互,或任意渠道上的 `/approve` 命令提示用户批准。 +- `before_install`:`{ block: true }` 为终止结果,并会阻止更低优先级的处理器继续执行。 +- `before_install`:`{ block: false }` 会被视为未作决定。 +- `message_sending`:`{ cancel: true }` 为终止结果,并会阻止更低优先级的处理器继续执行。 +- `message_sending`:`{ cancel: false }` 会被视为未作决定。 -`/approve` 命令同时处理 exec 审批和插件审批,并带有有界回退机制:当找不到 exec 审批 id 时,OpenClaw 会通过插件审批使用同一个 id 重试。插件审批转发可以通过配置中的 `approvals.plugin` 独立设置。 +`/approve` 命令会同时处理 exec 审批和插件审批,并带有有界回退:当找不到某个 exec 审批 ID 时,OpenClaw 会用同一个 ID 通过插件审批再次尝试。插件审批转发可通过配置中的 `approvals.plugin` 独立设置。 -如果自定义审批流程需要检测这个相同的有界回退场景,优先使用 `openclaw/plugin-sdk/error-runtime` 中的 `isApprovalNotFoundError`,而不是手动匹配审批过期字符串。 +如果自定义审批流程需要检测这一相同的有界回退场景,优先使用 `openclaw/plugin-sdk/error-runtime` 中的 `isApprovalNotFoundError`,而不要手动匹配审批过期字符串。 -详情请参见 [SDK 概览中的钩子决策语义](/zh-CN/plugins/sdk-overview#hook-decision-semantics)。 +详情请参见 [SDK 概览中的 hook 决策语义](/zh-CN/plugins/sdk-overview#hook-decision-semantics)。 ## 注册智能体工具 -工具是 LLM 可调用的类型化函数。它们可以是必需的(始终可用),也可以是可选的(用户选择启用): +工具是 LLM 可调用的类型化函数。它们可以是必需的(始终可用),也可以是可选的(用户主动启用): ```typescript register(api) { @@ -218,55 +223,55 @@ register(api) { ``` - 工具名称不得与核心工具冲突(冲突项会被跳过) -- 对具有副作用或需要额外二进制依赖的工具使用 `optional: true` -- 用户可以通过将插件 id 添加到 `tools.allow` 来启用某个插件中的所有工具 +- 对于具有副作用或需要额外二进制依赖的工具,请使用 `optional: true` +- 用户可通过将插件 ID 添加到 `tools.allow` 来启用某个插件的所有工具 ## 导入约定 -始终从精确的 `openclaw/plugin-sdk/` 路径导入: +始终从聚焦的 `openclaw/plugin-sdk/` 路径导入: ```typescript import { definePluginEntry } from "openclaw/plugin-sdk/plugin-entry"; import { createPluginRuntimeStore } from "openclaw/plugin-sdk/runtime-store"; -// 错误:单体根路径(已弃用,未来将移除) +// 错误:单体根入口(已弃用,将被移除) import { ... } from "openclaw/plugin-sdk"; ``` -完整的子路径参考请参见 [SDK 概览](/zh-CN/plugins/sdk-overview)。 +完整子路径参考请参见 [SDK 概览](/zh-CN/plugins/sdk-overview)。 -在你的插件内部,使用本地 barrel 文件(`api.ts`、`runtime-api.ts`)进行内部导入 —— 永远不要通过其 SDK 路径导入你自己的插件。 +在你的插件内部,请使用本地 barrel 文件(`api.ts`、`runtime-api.ts`)进行内部导入 —— 绝不要通过它自己的 SDK 路径导入你自己的插件。 -对于提供商插件,请将提供商专用辅助函数保留在这些包根级 barrel 中,除非该接口确实足够通用。当前内置示例包括: +对于提供商插件,除非该扩展点确实具有通用性,否则请将提供商特定的辅助函数保留在这些包根级 barrel 中。当前内置示例包括: -- Anthropic:Claude 流包装器,以及 `service_tier` / beta 辅助函数 +- Anthropic:Claude 流包装器以及 `service_tier` / beta 辅助函数 - OpenAI:提供商构建器、默认模型辅助函数、实时提供商 -- OpenRouter:提供商构建器,以及 onboarding/配置 辅助函数 +- OpenRouter:提供商构建器以及新手引导/配置辅助函数 -如果某个辅助函数只在一个内置提供商包中有用,请将其保留在该包根级接口上,而不是提升到 `openclaw/plugin-sdk/*` 中。 +如果某个辅助函数只在一个内置提供商包内部有用,请将其保留在该包根级扩展点上,而不是将其提升到 `openclaw/plugin-sdk/*` 中。 -一些生成的 `openclaw/plugin-sdk/` 辅助接口仍然存在,用于内置插件维护和兼容性,例如 `plugin-sdk/feishu-setup` 或 `plugin-sdk/zalo-setup`。请将这些视为保留接口,而不是新第三方插件的默认模式。 +一些生成的 `openclaw/plugin-sdk/` 辅助扩展点仍然存在,用于内置插件维护和兼容性,例如 `plugin-sdk/feishu-setup` 或 `plugin-sdk/zalo-setup`。请将这些视为保留接口,而不是新第三方插件的默认模式。 ## 提交前检查清单 **package.json** 具有正确的 `openclaw` 元数据 -**openclaw.plugin.json** 清单已存在且有效 +**openclaw.plugin.json** 清单存在且有效 入口点使用 `defineChannelPluginEntry` 或 `definePluginEntry` -所有导入都使用精确的 `plugin-sdk/` 路径 +所有导入都使用聚焦的 `plugin-sdk/` 路径 内部导入使用本地模块,而不是 SDK 自导入 测试通过(`pnpm test -- /my-plugin/`) `pnpm check` 通过(仓库内插件) ## Beta 版本测试 -1. 关注 [openclaw/openclaw](https://github.com/openclaw/openclaw/releases) 上的 GitHub 发布标签,并通过 `Watch` > `Releases` 订阅。Beta 标签格式类似 `v2026.3.N-beta.1`。你也可以为 OpenClaw 官方 X 账号 [@openclaw](https://x.com/openclaw) 开启通知,以接收发布公告。 -2. Beta 标签一出现,就尽快用它测试你的插件。正式版本发布前的窗口期通常只有几个小时。 -3. 测试后,在 `plugin-forum` Discord 渠道中你插件对应的主题里发帖,说明是 `all good` 还是哪里出了问题。如果你还没有主题,请创建一个。 -4. 如果出现问题,打开或更新一个标题为 `Beta blocker: - ` 的 issue,并添加 `beta-blocker` 标签。将该 issue 链接贴到你的主题中。 -5. 向 `main` 提交一个标题为 `fix(): beta blocker - ` 的 PR,并在 PR 和你的 Discord 主题中都关联该 issue。贡献者不能为 PR 添加标签,因此标题就是给维护者和自动化系统的 PR 侧信号。有 PR 的阻塞问题会被合并;没有 PR 的阻塞问题可能仍然会随版本发布。维护者会在 Beta 测试期间关注这些主题。 -6. 没有消息就表示一切正常。如果你错过了这个窗口,你的修复很可能会落到下一个周期。 +1. 关注 [openclaw/openclaw](https://github.com/openclaw/openclaw/releases) 上的 GitHub 发布标签,并通过 `Watch` > `Releases` 订阅。Beta 标签看起来像 `v2026.3.N-beta.1`。你也可以打开 OpenClaw 官方 X 账号 [@openclaw](https://x.com/openclaw) 的通知以接收发布公告。 +2. Beta 标签一出现,就尽快用它测试你的插件。稳定版发布前的窗口通常只有几个小时。 +3. 测试后,在 Discord 的 `plugin-forum` 渠道中你插件对应的线程里发布 `all good` 或说明出了什么问题。如果你还没有线程,就创建一个。 +4. 如果出现问题,打开或更新一个标题为 `Beta blocker: - ` 的 issue,并添加 `beta-blocker` 标签。把 issue 链接发到你的线程里。 +5. 向 `main` 提交一个标题为 `fix(): beta blocker - ` 的 PR,并在 PR 和你的 Discord 线程中都链接该 issue。贡献者无法为 PR 添加标签,因此标题就是供维护者和自动化识别的 PR 侧信号。有 PR 的 blocker 会被合并;没有 PR 的 blocker 也可能照样发布。维护者会在 Beta 测试期间关注这些线程。 +6. 没有消息就表示一切正常。如果你错过了这个窗口,你的修复很可能会在下一个周期落地。 -## 后续步骤 +## 下一步 @@ -278,7 +283,7 @@ import { ... } from "openclaw/plugin-sdk"; 导入映射和注册 API 参考 - + 通过 api.runtime 使用 TTS、搜索、子智能体 @@ -291,7 +296,7 @@ import { ... } from "openclaw/plugin-sdk"; ## 相关内容 -- [插件架构](/zh-CN/plugins/architecture) — 内部架构深入解析 +- [插件架构](/zh-CN/plugins/architecture) — 内部架构深度解析 - [SDK 概览](/zh-CN/plugins/sdk-overview) — 插件 SDK 参考 - [Manifest](/zh-CN/plugins/manifest) — 插件清单格式 - [渠道插件](/zh-CN/plugins/sdk-channel-plugins) — 构建渠道插件 diff --git a/docs/zh-CN/plugins/manifest.md b/docs/zh-CN/plugins/manifest.md index df3b04306..3403365d8 100644 --- a/docs/zh-CN/plugins/manifest.md +++ b/docs/zh-CN/plugins/manifest.md @@ -1,63 +1,67 @@ --- read_when: - - 你正在构建一个 OpenClaw 插件 - - 你需要发布一个插件配置 schema,或调试插件校验错误 + - 你正在构建 OpenClaw 插件 + - 你需要发布插件配置 schema,或调试插件校验错误 summary: 插件清单 + JSON Schema 要求(严格配置校验) title: 插件清单 x-i18n: - generated_at: "2026-04-06T00:52:42Z" + generated_at: "2026-04-06T12:44:05Z" model: gpt-5.4 provider: openai - source_hash: f6f915a761cdb5df77eba5d2ccd438c65445bd2ab41b0539d1200e63e8cf2c3a + source_hash: 15f70fd171d1aad334f01272e035e9a322a4c5c8a983180e6c38f4298b9e9158 source_path: plugins/manifest.md workflow: 15 --- -# 插件清单 (`openclaw.plugin.json`) +# 插件清单(openclaw.plugin.json) -本页面仅适用于**原生 OpenClaw 插件清单**。 +本页仅适用于**原生 OpenClaw 插件清单**。 -关于兼容的 bundle 布局,请参见 [插件 bundles](/zh-CN/plugins/bundles)。 +有关兼容的 bundle 布局,请参阅 [Plugin bundles](/zh-CN/plugins/bundles)。 兼容的 bundle 格式使用不同的清单文件: - Codex bundle:`.codex-plugin/plugin.json` -- Claude bundle:`.claude-plugin/plugin.json`,或不带清单的默认 Claude 组件 +- Claude bundle:`.claude-plugin/plugin.json` 或没有清单文件的默认 Claude 组件 布局 - Cursor bundle:`.cursor-plugin/plugin.json` -OpenClaw 也会自动检测这些 bundle 布局,但不会按照这里描述的 `openclaw.plugin.json` schema 对它们进行校验。 +OpenClaw 也会自动检测这些 bundle 布局,但它们不会按照此处描述的 `openclaw.plugin.json` schema 进行校验。 -对于兼容 bundles,OpenClaw 当前会在布局符合 OpenClaw 运行时预期时,读取 bundle 元数据、声明的 skill 根目录、Claude 命令根目录、Claude bundle `settings.json` 默认值、Claude bundle LSP 默认值,以及受支持的 hook packs。 +对于兼容 bundle,当布局符合 OpenClaw 运行时预期时,OpenClaw 当前会读取 +bundle 元数据,以及声明的 skill 根目录、Claude 命令根目录、Claude bundle 的 +`settings.json` 默认值、Claude bundle 的 LSP 默认值和受支持的 hook 包。 -每个原生 OpenClaw 插件**都必须**在**插件根目录**中提供一个 `openclaw.plugin.json` 文件。OpenClaw 使用这个清单在**不执行插件代码**的情况下校验配置。缺失或无效的清单会被视为插件错误,并阻止配置校验。 +每个原生 OpenClaw 插件都**必须**在**插件根目录**中包含一个 `openclaw.plugin.json` +文件。OpenClaw 使用此清单在**不执行插件代码的情况下**校验配置。缺失或无效的清单会被视为 +插件错误,并阻止配置校验。 -查看完整的插件系统指南:[插件](/zh-CN/tools/plugin)。 -关于原生能力模型和当前的外部兼容性指南,请参见: -[能力模型](/zh-CN/plugins/architecture#public-capability-model)。 +请参阅完整的插件系统指南:[Plugins](/zh-CN/tools/plugin)。 +关于原生能力模型和当前的外部兼容性指引,请参阅: +[Capability model](/zh-CN/plugins/architecture#public-capability-model)。 ## 这个文件的作用 `openclaw.plugin.json` 是 OpenClaw 在加载你的插件代码之前读取的元数据。 -用于: +它适用于: - 插件标识 - 配置校验 -- 无需启动插件运行时即可使用的认证和新手引导元数据 -- 在插件运行时加载前就应解析的别名和自动启用元数据 -- 在运行时加载前自动激活插件的 shorthand 模型族归属元数据 +- 无需启动插件运行时即可使用的凭证和新手引导元数据 +- 应在插件运行时加载前解析的别名和自动启用元数据 +- 应在运行时加载前自动激活插件的简写模型族归属元数据 - 用于内置兼容性接线和契约覆盖的静态能力归属快照 -- 无需加载运行时即可合并到目录和校验表面的渠道特定配置元数据 +- 无需加载运行时即可合并到目录和校验表面的渠道专用配置元数据 - 配置 UI 提示 -不要用于: +不要将它用于: - 注册运行时行为 - 声明代码入口点 - npm 安装元数据 -这些应该放在你的插件代码和 `package.json` 中。 +这些内容属于你的插件代码和 `package.json`。 ## 最小示例 @@ -72,7 +76,7 @@ OpenClaw 也会自动检测这些 bundle 布局,但不会按照这里描述的 } ``` -## 完整示例 +## 丰富示例 ```json { @@ -84,6 +88,7 @@ OpenClaw 也会自动检测这些 bundle 布局,但不会按照这里描述的 "modelSupport": { "modelPrefixes": ["router-"] }, + "cliBackends": ["openrouter-cli"], "providerAuthEnvVars": { "openrouter": ["OPENROUTER_API_KEY"] }, @@ -123,54 +128,55 @@ OpenClaw 也会自动检测这些 bundle 布局,但不会按照这里描述的 ## 顶层字段参考 -| 字段 | 必填 | 类型 | 含义 | -| ----------------------------------- | -------- | -------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `id` | 是 | `string` | 规范插件 id。这是在 `plugins.entries.` 中使用的 id。 | -| `configSchema` | 是 | `object` | 该插件配置的内联 JSON Schema。 | -| `enabledByDefault` | 否 | `true` | 将一个内置插件标记为默认启用。省略它,或设置为任何非 `true` 的值,即表示该插件默认禁用。 | -| `legacyPluginIds` | 否 | `string[]` | 会被规范化为当前规范插件 id 的旧版 id。 | -| `autoEnableWhenConfiguredProviders` | 否 | `string[]` | 当认证、配置或模型引用提到这些提供商 id 时,应自动启用此插件。 | -| `kind` | 否 | `"memory"` \| `"context-engine"` | 声明由 `plugins.slots.*` 使用的独占插件类型。 | -| `channels` | 否 | `string[]` | 由此插件拥有的渠道 id。用于设备发现和配置校验。 | -| `providers` | 否 | `string[]` | 由此插件拥有的提供商 id。 | -| `modelSupport` | 否 | `object` | 由清单拥有的 shorthand 模型族元数据,用于在运行时之前自动加载插件。 | -| `providerAuthEnvVars` | 否 | `Record` | OpenClaw 无需加载插件代码即可检查的轻量级提供商认证环境变量元数据。 | -| `providerAuthChoices` | 否 | `object[]` | 用于新手引导选择器、首选提供商解析和简单 CLI 标志接线的轻量级认证选项元数据。 | -| `contracts` | 否 | `object` | 用于语音、实时转录、实时语音、媒体理解、图像生成、音乐生成、视频生成、网页抓取、网页搜索和工具归属的静态内置能力快照。 | -| `channelConfigs` | 否 | `Record` | 在运行时加载前,合并到设备发现和校验表面的由清单拥有的渠道配置元数据。 | -| `skills` | 否 | `string[]` | 要加载的 Skills 目录,相对于插件根目录。 | -| `name` | 否 | `string` | 人类可读的插件名称。 | -| `description` | 否 | `string` | 显示在插件表面中的简短摘要。 | -| `version` | 否 | `string` | 信息性插件版本。 | -| `uiHints` | 否 | `Record` | 用于配置字段的 UI 标签、占位符和敏感性提示。 | +| Field | Required | Type | What it means | +| ----------------------------------- | -------- | -------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| `id` | 是 | `string` | 规范的插件 id。这是在 `plugins.entries.` 中使用的 id。 | +| `configSchema` | 是 | `object` | 该插件配置的内联 JSON Schema。 | +| `enabledByDefault` | 否 | `true` | 将一个内置插件标记为默认启用。省略它,或将其设置为任何非 `true` 的值,则该插件默认禁用。 | +| `legacyPluginIds` | 否 | `string[]` | 会被规范化到此标准插件 id 的旧版 id。 | +| `autoEnableWhenConfiguredProviders` | 否 | `string[]` | 当凭证、配置或模型引用提到这些提供商 id 时,应自动启用此插件。 | +| `kind` | 否 | `"memory"` \| `"context-engine"` | 声明一个由 `plugins.slots.*` 使用的排他性插件类型。 | +| `channels` | 否 | `string[]` | 由此插件拥有的渠道 id。用于设备发现和配置校验。 | +| `providers` | 否 | `string[]` | 由此插件拥有的提供商 id。 | +| `modelSupport` | 否 | `object` | 由清单拥有的简写模型族元数据,用于在运行时之前自动加载插件。 | +| `cliBackends` | 否 | `string[]` | 由此插件拥有的 CLI 推理后端 id。用于在启动时根据显式配置引用自动激活。 | +| `providerAuthEnvVars` | 否 | `Record` | OpenClaw 无需加载插件代码即可检查的轻量提供商凭证环境变量元数据。 | +| `providerAuthChoices` | 否 | `object[]` | 用于新手引导选择器、首选提供商解析和简单 CLI 标志接线的轻量凭证选择元数据。 | +| `contracts` | 否 | `object` | speech、实时转写、实时语音、媒体理解、图像生成、音乐生成、视频生成、网页抓取、网页搜索和工具归属的静态内置能力快照。 | +| `channelConfigs` | 否 | `Record` | 由清单拥有的渠道配置元数据,在运行时加载前合并到设备发现和校验表面。 | +| `skills` | 否 | `string[]` | 要加载的 Skills 目录,相对于插件根目录。 | +| `name` | 否 | `string` | 人类可读的插件名称。 | +| `description` | 否 | `string` | 在插件表面中显示的简短摘要。 | +| `version` | 否 | `string` | 仅供参考的插件版本。 | +| `uiHints` | 否 | `Record` | 配置字段的 UI 标签、占位文本和敏感性提示。 | -## `providerAuthChoices` 参考 +## providerAuthChoices 参考 -每个 `providerAuthChoices` 条目描述一个新手引导或认证选项。 +每个 `providerAuthChoices` 条目描述一个新手引导或凭证选择项。 OpenClaw 会在提供商运行时加载前读取它。 -| 字段 | 必填 | 类型 | 含义 | -| --------------------- | -------- | ----------------------------------------------- | ---------------------------------------------------------------------------------------- | -| `provider` | 是 | `string` | 此选项所属的提供商 id。 | -| `method` | 是 | `string` | 要分发到的认证方法 id。 | -| `choiceId` | 是 | `string` | 由新手引导和 CLI 流程使用的稳定认证选项 id。 | -| `choiceLabel` | 否 | `string` | 面向用户的标签。如省略,OpenClaw 会回退为 `choiceId`。 | -| `choiceHint` | 否 | `string` | 选择器中的简短辅助文本。 | -| `assistantPriority` | 否 | `number` | 在由助手驱动的交互式选择器中,值越小排序越靠前。 | -| `assistantVisibility` | 否 | `"visible"` \| `"manual-only"` | 在助手选择器中隐藏该选项,但仍允许手动通过 CLI 选择。 | -| `deprecatedChoiceIds` | 否 | `string[]` | 应将用户重定向到此替代选项的旧版选项 id。 | -| `groupId` | 否 | `string` | 用于对相关选项进行分组的可选分组 id。 | -| `groupLabel` | 否 | `string` | 该分组面向用户的标签。 | -| `groupHint` | 否 | `string` | 该分组的简短辅助文本。 | -| `optionKey` | 否 | `string` | 用于简单单标志认证流程的内部选项键。 | -| `cliFlag` | 否 | `string` | CLI 标志名称,例如 `--openrouter-api-key`。 | -| `cliOption` | 否 | `string` | 完整的 CLI 选项形式,例如 `--openrouter-api-key `。 | -| `cliDescription` | 否 | `string` | CLI 帮助中使用的说明。 | -| `onboardingScopes` | 否 | `Array<"text-inference" \| "image-generation">` | 该选项应出现在哪些新手引导表面中。如省略,默认值为 `["text-inference"]`。 | +| Field | Required | Type | What it means | +| --------------------- | -------- | ----------------------------------------------- | ------------------------------------------------------------------------------------------ | +| `provider` | 是 | `string` | 此选择项所属的提供商 id。 | +| `method` | 是 | `string` | 用于分发的凭证方法 id。 | +| `choiceId` | 是 | `string` | 供新手引导和 CLI 流程使用的稳定凭证选择 id。 | +| `choiceLabel` | 否 | `string` | 面向用户的标签。如果省略,OpenClaw 会回退到 `choiceId`。 | +| `choiceHint` | 否 | `string` | 选择器的简短帮助文本。 | +| `assistantPriority` | 否 | `number` | 在由 assistant 驱动的交互式选择器中,值越小排序越靠前。 | +| `assistantVisibility` | 否 | `"visible"` \| `"manual-only"` | 在 assistant 选择器中隐藏该选项,但仍允许通过手动 CLI 方式选择。 | +| `deprecatedChoiceIds` | 否 | `string[]` | 应将用户重定向到此替代选项的旧版 choice id。 | +| `groupId` | 否 | `string` | 用于对相关选项进行分组的可选组 id。 | +| `groupLabel` | 否 | `string` | 该分组的面向用户标签。 | +| `groupHint` | 否 | `string` | 该分组的简短帮助文本。 | +| `optionKey` | 否 | `string` | 用于简单单标志凭证流程的内部选项键。 | +| `cliFlag` | 否 | `string` | CLI 标志名称,例如 `--openrouter-api-key`。 | +| `cliOption` | 否 | `string` | 完整的 CLI 选项形式,例如 `--openrouter-api-key `。 | +| `cliDescription` | 否 | `string` | 在 CLI 帮助中使用的说明。 | +| `onboardingScopes` | 否 | `Array<"text-inference" \| "image-generation">` | 此选择项应出现在哪些新手引导表面中。如果省略,默认值为 `["text-inference"]`。 | -## `uiHints` 参考 +## uiHints 参考 -`uiHints` 是从配置字段名映射到小型渲染提示的映射表。 +`uiHints` 是一个从配置字段名映射到小型渲染提示的映射表。 ```json { @@ -185,20 +191,20 @@ OpenClaw 会在提供商运行时加载前读取它。 } ``` -每个字段提示可以包含: +每个字段提示可包含: -| 字段 | 类型 | 含义 | -| ------------- | ---------- | ------------------------------ | -| `label` | `string` | 面向用户的字段标签。 | -| `help` | `string` | 简短辅助文本。 | -| `tags` | `string[]` | 可选 UI 标签。 | -| `advanced` | `boolean` | 将该字段标记为高级项。 | -| `sensitive` | `boolean` | 将该字段标记为密钥或敏感项。 | -| `placeholder` | `string` | 表单输入的占位文本。 | +| Field | Type | What it means | +| ------------- | ---------- | ----------------------------- | +| `label` | `string` | 面向用户的字段标签。 | +| `help` | `string` | 简短帮助文本。 | +| `tags` | `string[]` | 可选的 UI 标签。 | +| `advanced` | `boolean` | 将该字段标记为高级项。 | +| `sensitive` | `boolean` | 将该字段标记为密钥或敏感项。 | +| `placeholder` | `string` | 表单输入的占位文本。 | -## `contracts` 参考 +## contracts 参考 -仅在 `contracts` 中放置 OpenClaw 可在不导入插件运行时的情况下读取的静态能力归属元数据。 +仅将 `contracts` 用于 OpenClaw 无需导入插件运行时即可读取的静态能力归属元数据。 ```json { @@ -218,21 +224,21 @@ OpenClaw 会在提供商运行时加载前读取它。 每个列表都是可选的: -| 字段 | 类型 | 含义 | -| -------------------------------- | ---------- | ------------------------------------------------------ | -| `speechProviders` | `string[]` | 该插件拥有的语音提供商 id。 | -| `realtimeTranscriptionProviders` | `string[]` | 该插件拥有的实时转录提供商 id。 | -| `realtimeVoiceProviders` | `string[]` | 该插件拥有的实时语音提供商 id。 | -| `mediaUnderstandingProviders` | `string[]` | 该插件拥有的媒体理解提供商 id。 | -| `imageGenerationProviders` | `string[]` | 该插件拥有的图像生成提供商 id。 | -| `videoGenerationProviders` | `string[]` | 该插件拥有的视频生成提供商 id。 | -| `webFetchProviders` | `string[]` | 该插件拥有的网页抓取提供商 id。 | -| `webSearchProviders` | `string[]` | 该插件拥有的网页搜索提供商 id。 | -| `tools` | `string[]` | 该插件拥有的智能体工具名称,用于内置契约检查。 | +| Field | Type | What it means | +| -------------------------------- | ---------- | ----------------------------------------- | +| `speechProviders` | `string[]` | 该插件拥有的语音提供商 id。 | +| `realtimeTranscriptionProviders` | `string[]` | 该插件拥有的实时转写提供商 id。 | +| `realtimeVoiceProviders` | `string[]` | 该插件拥有的实时语音提供商 id。 | +| `mediaUnderstandingProviders` | `string[]` | 该插件拥有的媒体理解提供商 id。 | +| `imageGenerationProviders` | `string[]` | 该插件拥有的图像生成提供商 id。 | +| `videoGenerationProviders` | `string[]` | 该插件拥有的视频生成提供商 id。 | +| `webFetchProviders` | `string[]` | 该插件拥有的网页抓取提供商 id。 | +| `webSearchProviders` | `string[]` | 该插件拥有的网页搜索提供商 id。 | +| `tools` | `string[]` | 该插件拥有的智能体工具名称,用于内置契约检查。 | -## `channelConfigs` 参考 +## channelConfigs 参考 -当渠道插件在运行时加载前需要轻量级配置元数据时,请使用 `channelConfigs`。 +当渠道插件在运行时加载前需要轻量配置元数据时,请使用 `channelConfigs`。 ```json { @@ -259,19 +265,20 @@ OpenClaw 会在提供商运行时加载前读取它。 } ``` -每个渠道条目可以包含: +每个渠道条目可包含: -| 字段 | 类型 | 含义 | -| ------------- | ------------------------ | ------------------------------------------------------------------------------------ | -| `schema` | `object` | `channels.` 的 JSON Schema。每个声明的渠道配置条目都必须提供。 | -| `uiHints` | `Record` | 该渠道配置部分的可选 UI 标签 / 占位符 / 敏感性提示。 | -| `label` | `string` | 当运行时元数据尚未准备好时,合并到选择器和检查表面的渠道标签。 | -| `description` | `string` | 用于检查和目录表面的简短渠道描述。 | -| `preferOver` | `string[]` | 在选择表面中,该渠道应优先于的旧版或较低优先级插件 id。 | +| Field | Type | What it means | +| ------------- | ------------------------ | ----------------------------------------------------------------------------- | +| `schema` | `object` | `channels.` 的 JSON Schema。每个声明的渠道配置条目都必须提供。 | +| `uiHints` | `Record` | 该渠道配置部分可选的 UI 标签 / 占位文本 / 敏感性提示。 | +| `label` | `string` | 当运行时元数据尚未就绪时,合并到选择器和检查表面的渠道标签。 | +| `description` | `string` | 用于检查和目录表面的简短渠道说明。 | +| `preferOver` | `string[]` | 在选择表面中,此渠道应优先于的旧版或较低优先级插件 id。 | -## `modelSupport` 参考 +## modelSupport 参考 -当 OpenClaw 应在运行时加载前根据 `gpt-5.4` 或 `claude-sonnet-4.6` 之类的 shorthand 模型 id 推断你的提供商插件时,请使用 `modelSupport`。 +当 OpenClaw 应该在插件运行时加载前,根据 `gpt-5.4` 或 `claude-sonnet-4.6` +这类简写模型 id 推断你的提供商插件时,请使用 `modelSupport`。 ```json { @@ -284,56 +291,67 @@ OpenClaw 会在提供商运行时加载前读取它。 OpenClaw 应用以下优先级: -- 显式 `provider/model` 引用使用拥有该模型的 `providers` 清单元数据 -- `modelPatterns` 的优先级高于 `modelPrefixes` -- 如果一个非内置插件和一个内置插件都匹配,则非内置插件胜出 -- 如果仍存在歧义,则在用户或配置明确指定提供商之前会忽略该歧义 +- 显式的 `provider/model` 引用使用所属 `providers` 清单元数据 +- `modelPatterns` 优先于 `modelPrefixes` +- 如果一个非内置插件和一个内置插件都匹配,则非内置 + 插件优先 +- 对于其余歧义,在用户或配置明确指定提供商之前会忽略 字段: -| 字段 | 类型 | 含义 | -| --------------- | ---------- | ---------------------------------------------------------------------------------- | -| `modelPrefixes` | `string[]` | 使用 `startsWith` 对 shorthand 模型 id 进行匹配的前缀。 | -| `modelPatterns` | `string[]` | 在移除 profile 后缀后,对 shorthand 模型 id 进行匹配的正则表达式源。 | +| Field | Type | What it means | +| --------------- | ---------- | ------------------------------------------------------------------------- | +| `modelPrefixes` | `string[]` | 使用 `startsWith` 与简写模型 id 进行匹配的前缀。 | +| `modelPatterns` | `string[]` | 在移除配置文件后缀后,与简写模型 id 匹配的正则表达式源码。 | -旧版顶层能力键已弃用。使用 `openclaw doctor --fix` 将 `speechProviders`、`realtimeTranscriptionProviders`、`realtimeVoiceProviders`、`mediaUnderstandingProviders`、`imageGenerationProviders`、`videoGenerationProviders`、`webFetchProviders` 和 `webSearchProviders` 移动到 `contracts` 下;常规清单加载不再将这些顶层字段视为能力归属。 +旧版顶层能力键已弃用。使用 `openclaw doctor --fix` 将 +`speechProviders`、`realtimeTranscriptionProviders`、 +`realtimeVoiceProviders`、`mediaUnderstandingProviders`、 +`imageGenerationProviders`、`videoGenerationProviders`、 +`webFetchProviders` 和 `webSearchProviders` 移动到 `contracts` 下; +常规清单加载不再将这些顶层字段视为能力归属信息。 -## 清单与 `package.json` 的区别 +## Manifest 与 package.json 的区别 这两个文件承担不同的职责: -| 文件 | 用途 | -| ---------------------- | --------------------------------------------------------------------------------------------------------------------------------------- | -| `openclaw.plugin.json` | 在插件代码运行前必须存在的设备发现、配置校验、认证选项元数据和 UI 提示 | -| `package.json` | npm 元数据、依赖安装,以及用于入口点、安装门控、设置或目录元数据的 `openclaw` 配置块 | +| File | Use it for | +| ---------------------- | ---------------------------------------------------------------------------------------------------------------------------- | +| `openclaw.plugin.json` | 设备发现、配置校验、凭证选择元数据,以及必须在插件代码运行前就存在的 UI 提示 | +| `package.json` | npm 元数据、依赖安装,以及用于入口点、安装门控、设置或目录元数据的 `openclaw` 配置块 | -如果你不确定某条元数据应放在哪里,请使用这个规则: +如果你不确定一条元数据应放在哪里,请使用以下规则: - 如果 OpenClaw 必须在加载插件代码前知道它,就放在 `openclaw.plugin.json` 中 - 如果它与打包、入口文件或 npm 安装行为有关,就放在 `package.json` 中 -### 会影响设备发现的 `package.json` 字段 +### 影响设备发现的 package.json 字段 -有些运行前插件元数据被有意放在 `package.json` 的 `openclaw` 配置块下,而不是 `openclaw.plugin.json` 中。 +某些运行时之前的插件元数据有意放在 `package.json` 的 +`openclaw` 配置块下,而不是 `openclaw.plugin.json` 中。 重要示例: -| 字段 | 含义 | -| ----------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------- | -| `openclaw.extensions` | 声明原生插件入口点。 | -| `openclaw.setupEntry` | 在新手引导和延迟渠道启动期间使用的轻量级仅设置入口点。 | -| `openclaw.channel` | 轻量级渠道目录元数据,例如标签、文档路径、别名和选择文案。 | -| `openclaw.channel.configuredState` | 轻量级已配置状态检查器元数据,可在不加载完整渠道运行时的情况下回答“是否已存在仅环境变量设置?” | -| `openclaw.channel.persistedAuthState` | 轻量级持久化认证状态检查器元数据,可在不加载完整渠道运行时的情况下回答“是否已有任何已登录状态?” | -| `openclaw.install.npmSpec` / `openclaw.install.localPath` | 用于内置插件和外部发布插件的安装 / 更新提示。 | -| `openclaw.install.defaultChoice` | 当有多个安装来源可用时的首选安装路径。 | -| `openclaw.install.minHostVersion` | 最低支持的 OpenClaw 主机版本,使用类似 `>=2026.3.22` 的 semver 下限。 | -| `openclaw.install.allowInvalidConfigRecovery` | 当配置无效时,允许一个范围很窄的内置插件重装恢复路径。 | -| `openclaw.startup.deferConfiguredChannelFullLoadUntilAfterListen` | 允许在启动期间先加载仅设置的渠道表面,再加载完整渠道插件。 | +| Field | What it means | +| ----------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ | +| `openclaw.extensions` | 声明原生插件入口点。 | +| `openclaw.setupEntry` | 在新手引导和延迟渠道启动期间使用的轻量级仅设置入口点。 | +| `openclaw.channel` | 轻量级渠道目录元数据,例如标签、文档路径、别名和选择文案。 | +| `openclaw.channel.configuredState` | 轻量级 configured-state 检查器元数据,可在不加载完整渠道运行时的情况下回答“是否已经存在仅环境变量配置的设置?”。 | +| `openclaw.channel.persistedAuthState` | 轻量级持久化凭证检查器元数据,可在不加载完整渠道运行时的情况下回答“是否已经有任何登录状态?”。 | +| `openclaw.install.npmSpec` / `openclaw.install.localPath` | 用于内置插件和外部发布插件的安装 / 更新提示。 | +| `openclaw.install.defaultChoice` | 当存在多个安装来源时的首选安装路径。 | +| `openclaw.install.minHostVersion` | 支持的最低 OpenClaw 主机版本,使用类似 `>=2026.3.22` 的 semver 下限。 | +| `openclaw.install.allowInvalidConfigRecovery` | 当配置无效时,允许一个范围受限的内置插件重新安装恢复路径。 | +| `openclaw.startup.deferConfiguredChannelFullLoadUntilAfterListen` | 允许仅设置的渠道表面在启动期间于完整渠道插件之前加载。 | -`openclaw.install.minHostVersion` 会在安装和清单注册表加载期间强制执行。无效值会被拒绝;合法但更高的新版本值会使插件在较旧主机上被跳过。 +`openclaw.install.minHostVersion` 会在安装期间和清单注册表加载期间强制执行。 +无效值会被拒绝;对于较旧主机,较新但有效的值会跳过该插件。 -`openclaw.install.allowInvalidConfigRecovery` 的设计范围刻意很窄。它不会让任意损坏的配置变得可安装。目前,它只允许安装流程从特定的陈旧内置插件升级失败中恢复,例如缺失的内置插件路径,或同一个内置插件对应的陈旧 `channels.` 条目。无关的配置错误仍会阻止安装,并将操作人员引导到 `openclaw doctor --fix`。 +`openclaw.install.allowInvalidConfigRecovery` 的范围有意保持很窄。它 +不会让任意损坏的配置也能被安装。当前它只允许安装流程从特定的陈旧内置插件升级失败中恢复,例如 +缺失的内置插件路径,或同一内置插件的陈旧 `channels.` 条目。 +无关的配置错误仍会阻止安装,并将操作员引导到 `openclaw doctor --fix`。 `openclaw.channel.persistedAuthState` 是一个微型检查器模块的包元数据: @@ -351,9 +369,11 @@ OpenClaw 应用以下优先级: } ``` -当设置、Doctor 或已配置状态流程需要在完整渠道插件加载前进行一个轻量级的是 / 否认证探测时,请使用它。目标导出应是一个只读取持久化状态的小函数;不要通过完整渠道运行时 barrel 暴露它。 +当 setup、Doctor 或 configured-state 流程需要在完整渠道插件加载前执行低成本的 +是 / 否凭证探测时,请使用它。目标导出应是一个仅读取持久化状态的小函数; +不要通过完整渠道运行时 barrel 来路由它。 -`openclaw.channel.configuredState` 采用相同的结构,用于轻量级的仅环境变量已配置检查: +`openclaw.channel.configuredState` 对低成本的仅环境变量配置检查使用相同结构: ```json { @@ -369,43 +389,57 @@ OpenClaw 应用以下优先级: } ``` -当一个渠道可以通过环境变量或其他微小的非运行时输入回答已配置状态时,请使用它。如果检查需要完整配置解析或真实渠道运行时,请将该逻辑保留在插件 `config.hasConfiguredState` hook 中。 +当渠道可以从环境变量或其他轻量非运行时输入回答 configured-state 时,请使用它。 +如果检查需要完整的配置解析或真实的渠道运行时,请将该逻辑保留在插件 +`config.hasConfiguredState` hook 中。 ## JSON Schema 要求 - **每个插件都必须提供一个 JSON Schema**,即使它不接受任何配置。 - 可以接受空 schema(例如 `{ "type": "object", "additionalProperties": false }`)。 -- Schema 在配置读写时校验,而不是在运行时校验。 +- schema 会在配置读取 / 写入时校验,而不是在运行时校验。 ## 校验行为 -- 未知的 `channels.*` 键是**错误**,除非该渠道 id 由某个插件清单声明。 +- 未知的 `channels.*` 键会被视为**错误**,除非该渠道 id 由某个 + 插件清单声明。 - `plugins.entries.`、`plugins.allow`、`plugins.deny` 和 `plugins.slots.*` - 必须引用**可发现的**插件 id。未知 id 是**错误**。 -- 如果插件已安装,但其清单或 schema 损坏或缺失,校验会失败,Doctor 会报告该插件错误。 -- 如果插件配置存在,但插件**已禁用**,配置会被保留,并且 Doctor + 日志中会显示一个**警告**。 + 必须引用**可发现的**插件 id。未知 id 会被视为**错误**。 +- 如果插件已安装,但其清单或 schema 损坏或缺失, + 校验将失败,Doctor 会报告该插件错误。 +- 如果插件配置存在,但插件处于**禁用**状态,该配置会被保留,并且 + Doctor + 日志中会显示**警告**。 -完整的 `plugins.*` schema 请参见 [配置参考](/zh-CN/gateway/configuration)。 +有关完整的 `plugins.*` schema,请参阅 [Configuration reference](/zh-CN/gateway/configuration)。 ## 说明 - 清单对于**原生 OpenClaw 插件**是**必需的**,包括本地文件系统加载。 -- 运行时仍会单独加载插件模块;清单仅用于设备发现 + 校验。 -- 原生清单使用 JSON5 解析,因此接受注释、尾随逗号和未加引号的键,只要最终值仍然是一个对象。 -- 清单加载器只读取已记录的清单字段。避免在这里添加自定义顶层键。 -- `providerAuthEnvVars` 是用于认证探测、环境变量标记校验以及类似提供商认证表面的轻量级元数据路径,这些场景不应仅为了检查环境变量名称而启动插件运行时。 -- `providerAuthChoices` 是用于认证选项选择器、`--auth-choice` 解析、首选提供商映射以及在提供商运行时加载前进行简单新手引导 CLI 标志注册的轻量级元数据路径。对于需要提供商代码的运行时向导元数据,请参见 - [提供商运行时 hooks](/zh-CN/plugins/architecture#provider-runtime-hooks)。 -- 独占插件类型通过 `plugins.slots.*` 选择。 - - `kind: "memory"` 通过 `plugins.slots.memory` 选择。 - - `kind: "context-engine"` 通过 `plugins.slots.contextEngine` - 选择(默认值:内置 `legacy`)。 -- 当插件不需要它们时,可以省略 `channels`、`providers` 和 `skills`。 -- 如果你的插件依赖原生模块,请记录构建步骤以及任何包管理器 allowlist 要求(例如 pnpm `allow-build-scripts` +- 运行时仍会单独加载插件模块;清单仅用于 + 设备发现 + 校验。 +- 原生清单使用 JSON5 解析,因此允许注释、尾随逗号和 + 不带引号的键,只要最终值仍然是一个对象即可。 +- 清单加载器只会读取文档中说明的清单字段。避免在这里添加 + 自定义顶层键。 +- `providerAuthEnvVars` 是用于凭证探测、环境变量标记校验 + 以及类似提供商凭证表面的轻量元数据路径,这些场景不应只为了检查环境变量名称而启动插件 + 运行时。 +- `providerAuthChoices` 是用于凭证选择器、 + `--auth-choice` 解析、首选提供商映射以及简单新手引导 + CLI 标志注册的轻量元数据路径,这些都发生在提供商运行时加载之前。对于需要提供商代码的运行时向导 + 元数据,请参阅 + [Provider runtime hooks](/zh-CN/plugins/architecture#provider-runtime-hooks)。 +- 排他性插件类型通过 `plugins.slots.*` 进行选择。 + - `kind: "memory"` 由 `plugins.slots.memory` 选择。 + - `kind: "context-engine"` 由 `plugins.slots.contextEngine` + 选择(默认:内置 `legacy`)。 +- 当插件不需要它们时,可以省略 `channels`、`providers`、`cliBackends` 和 `skills`。 +- 如果你的插件依赖原生模块,请记录构建步骤以及任何 + 包管理器允许列表要求(例如 pnpm `allow-build-scripts` - `pnpm rebuild `)。 ## 相关内容 -- [构建插件](/zh-CN/plugins/building-plugins) — 插件快速开始 -- [插件架构](/zh-CN/plugins/architecture) — 内部架构 -- [插件 SDK 概览](/zh-CN/plugins/sdk-overview) — 插件 SDK 参考 +- [Building Plugins](/zh-CN/plugins/building-plugins) — 插件开发入门 +- [Plugin Architecture](/zh-CN/plugins/architecture) — 内部架构 +- [SDK Overview](/zh-CN/plugins/sdk-overview) — 插件 SDK 概览 diff --git a/docs/zh-CN/plugins/sdk-overview.md b/docs/zh-CN/plugins/sdk-overview.md index 191de06b6..335c9437d 100644 --- a/docs/zh-CN/plugins/sdk-overview.md +++ b/docs/zh-CN/plugins/sdk-overview.md @@ -1,26 +1,26 @@ --- read_when: - 你需要知道应该从哪个 SDK 子路径导入 - - 你想查阅 OpenClawPluginApi 上所有注册方法的参考 + - 你想查看 OpenClawPluginApi 上所有注册方法的参考 - 你正在查找某个特定的 SDK 导出 sidebarTitle: SDK Overview summary: 导入映射、注册 API 参考和 SDK 架构 title: 插件 SDK 概览 x-i18n: - generated_at: "2026-04-06T12:16:48Z" + generated_at: "2026-04-06T12:44:55Z" model: gpt-5.4 provider: openai - source_hash: 6dfd7a632101c2f6da8ba43b3cb4e673794ebaed00908ae897059fe115782f54 + source_hash: e045097753f33d13d570f6ce5297d2a7c0f0ad8b31515d0d9021386c8004354c source_path: plugins/sdk-overview.md workflow: 15 --- # 插件 SDK 概览 -插件 SDK 是插件与核心之间的类型化契约。本页是关于**导入什么**以及**你可以注册什么**的参考。 +插件 SDK 是插件与核心之间的类型化契约。本页是关于 **该导入什么** 以及 **你可以注册什么** 的参考。 - **在找操作指南吗?** + **在找操作指南?** - 第一个插件?从 [入门指南](/zh-CN/plugins/building-plugins) 开始 - 渠道插件?参见 [渠道插件](/zh-CN/plugins/sdk-channel-plugins) - 提供商插件?参见 [提供商插件](/zh-CN/plugins/sdk-provider-plugins) @@ -28,33 +28,36 @@ x-i18n: ## 导入约定 -始终从具体的子路径导入: +始终从特定子路径导入: ```typescript import { definePluginEntry } from "openclaw/plugin-sdk/plugin-entry"; import { defineChannelPluginEntry } from "openclaw/plugin-sdk/channel-core"; ``` -每个子路径都是一个小型、独立的模块。这可以保持快速启动,并防止循环依赖问题。对于渠道特定的入口/构建辅助函数,优先使用 `openclaw/plugin-sdk/channel-core`;将 `openclaw/plugin-sdk/core` 保留给更广泛的总入口表面和共享辅助函数,例如 `buildChannelConfigSchema`。 +每个子路径都是一个小型、独立的模块。这可以保持快速启动,并防止循环依赖问题。对于渠道特定的入口/构建辅助工具,优先使用 `openclaw/plugin-sdk/channel-core`;将 `openclaw/plugin-sdk/core` 保留给更宽泛的汇总接口和共享辅助工具,例如 `buildChannelConfigSchema`。 -不要添加或依赖带提供商名称的便捷接缝,例如 `openclaw/plugin-sdk/slack`、`openclaw/plugin-sdk/discord`、`openclaw/plugin-sdk/signal`、`openclaw/plugin-sdk/whatsapp`,或带渠道品牌的辅助接缝。内置插件应在它们自己的 `api.ts` 或 `runtime-api.ts` barrel 文件中组合通用 SDK 子路径,而核心应当要么使用这些插件本地的 barrel 文件,要么在确实存在跨渠道需求时添加一个窄范围的通用 SDK 契约。 +不要添加或依赖以提供商命名的便捷扩展点,例如 +`openclaw/plugin-sdk/slack`、`openclaw/plugin-sdk/discord`、 +`openclaw/plugin-sdk/signal`、`openclaw/plugin-sdk/whatsapp`,或 +带有渠道品牌的辅助扩展点。内置插件应在它们自己的 `api.ts` 或 `runtime-api.ts` barrel 中组合通用 SDK 子路径,而核心则应使用这些插件本地 barrel,或在需求确实跨渠道时添加一个狭义的通用 SDK 契约。 -生成的导出映射仍然包含一小组内置插件辅助接缝,例如 `plugin-sdk/feishu`、`plugin-sdk/feishu-setup`、`plugin-sdk/zalo`、`plugin-sdk/zalo-setup` 和 `plugin-sdk/matrix*`。这些子路径仅用于内置插件维护和兼容性;它们在下方的常用表格中被有意省略,也不是新第三方插件的推荐导入路径。 +生成的导出映射中仍包含一小部分内置插件辅助扩展点,例如 `plugin-sdk/feishu`、`plugin-sdk/feishu-setup`、`plugin-sdk/zalo`、`plugin-sdk/zalo-setup` 和 `plugin-sdk/matrix*`。这些子路径仅为内置插件维护和兼容性而存在;它们有意未列入下方的常用表格中,也不是新的第三方插件推荐使用的导入路径。 ## 子路径参考 -最常用的子路径,按用途分组。包含 200 多个子路径的完整生成列表位于 `scripts/lib/plugin-sdk-entrypoints.json`。 +最常用的子路径,按用途分组。完整的 200+ 子路径生成列表位于 `scripts/lib/plugin-sdk-entrypoints.json`。 -保留的内置插件辅助子路径仍会出现在该生成列表中。除非某个文档页面明确将其宣传为公共接口,否则应将这些视为实现细节/兼容性表面。 +保留的内置插件辅助子路径仍会出现在该生成列表中。除非某个文档页面明确将其提升为公共接口,否则请将这些视为实现细节/兼容性接口。 ### 插件入口 -| 子路径 | 关键导出 | -| --------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- | -| `plugin-sdk/plugin-entry` | `definePluginEntry` | -| `plugin-sdk/core` | `defineChannelPluginEntry`, `createChatChannelPlugin`, `createChannelPluginBase`, `defineSetupPluginEntry`, `buildChannelConfigSchema` | -| `plugin-sdk/config-schema` | `OpenClawSchema` | -| `plugin-sdk/provider-entry` | `defineSingleProviderPluginEntry` | +| 子路径 | 关键导出 | +| --------------------------- | -------------------------------------------------------------------------------------------------------------------------------------- | +| `plugin-sdk/plugin-entry` | `definePluginEntry` | +| `plugin-sdk/core` | `defineChannelPluginEntry`, `createChatChannelPlugin`, `createChannelPluginBase`, `defineSetupPluginEntry`, `buildChannelConfigSchema` | +| `plugin-sdk/config-schema` | `OpenClawSchema` | +| `plugin-sdk/provider-entry` | `defineSingleProviderPluginEntry` | @@ -63,43 +66,43 @@ import { defineChannelPluginEntry } from "openclaw/plugin-sdk/channel-core"; | `plugin-sdk/channel-core` | `defineChannelPluginEntry`, `defineSetupPluginEntry`, `createChatChannelPlugin`, `createChannelPluginBase` | | `plugin-sdk/config-schema` | 根 `openclaw.json` Zod schema 导出(`OpenClawSchema`) | | `plugin-sdk/channel-setup` | `createOptionalChannelSetupSurface`, `createOptionalChannelSetupAdapter`, `createOptionalChannelSetupWizard`,以及 `DEFAULT_ACCOUNT_ID`, `createTopLevelChannelDmPolicy`, `setSetupChannelEnabled`, `splitSetupEntries` | - | `plugin-sdk/setup` | 共享的设置向导辅助函数、allowlist 提示、设置状态构建器 | + | `plugin-sdk/setup` | 共享设置向导辅助工具、allowlist 提示、设置状态构建器 | | `plugin-sdk/setup-runtime` | `createPatchedAccountSetupAdapter`, `createEnvPatchedAccountSetupAdapter`, `createSetupInputPresenceValidator`, `noteChannelLookupFailure`, `noteChannelLookupSummary`, `promptResolvedAllowFrom`, `splitSetupEntries`, `createAllowlistSetupWizardProxy`, `createDelegatedSetupWizardProxy` | | `plugin-sdk/setup-adapter-runtime` | `createEnvPatchedAccountSetupAdapter` | | `plugin-sdk/setup-tools` | `formatCliCommand`, `detectBinary`, `extractArchive`, `resolveBrewExecutable`, `formatDocsLink`, `CONFIG_DIR` | - | `plugin-sdk/account-core` | 多账户配置/操作门禁辅助函数、默认账户回退辅助函数 | - | `plugin-sdk/account-id` | `DEFAULT_ACCOUNT_ID`、account-id 规范化辅助函数 | - | `plugin-sdk/account-resolution` | 账户查找 + 默认回退辅助函数 | - | `plugin-sdk/account-helpers` | 窄范围的账户列表/账户操作辅助函数 | + | `plugin-sdk/account-core` | 多账户配置/操作门控辅助工具、默认账户回退辅助工具 | + | `plugin-sdk/account-id` | `DEFAULT_ACCOUNT_ID`、account-id 规范化辅助工具 | + | `plugin-sdk/account-resolution` | 账户查找 + 默认回退辅助工具 | + | `plugin-sdk/account-helpers` | 狭义账户列表/账户操作辅助工具 | | `plugin-sdk/channel-pairing` | `createChannelPairingController` | | `plugin-sdk/channel-reply-pipeline` | `createChannelReplyPipeline` | | `plugin-sdk/channel-config-helpers` | `createHybridChannelConfigAdapter` | | `plugin-sdk/channel-config-schema` | 渠道配置 schema 类型 | - | `plugin-sdk/telegram-command-config` | Telegram 自定义命令规范化/校验辅助函数,带内置契约回退 | + | `plugin-sdk/telegram-command-config` | 带内置契约回退的 Telegram 自定义命令规范化/验证辅助工具 | | `plugin-sdk/channel-policy` | `resolveChannelGroupRequireMention` | | `plugin-sdk/channel-lifecycle` | `createAccountStatusSink` | - | `plugin-sdk/inbound-envelope` | 共享的入站路由 + envelope 构建辅助函数 | - | `plugin-sdk/inbound-reply-dispatch` | 共享的入站记录与分发辅助函数 | - | `plugin-sdk/messaging-targets` | 目标解析/匹配辅助函数 | - | `plugin-sdk/outbound-media` | 共享的出站媒体加载辅助函数 | - | `plugin-sdk/outbound-runtime` | 出站身份/发送委托辅助函数 | - | `plugin-sdk/thread-bindings-runtime` | 线程绑定生命周期和适配器辅助函数 | + | `plugin-sdk/inbound-envelope` | 共享入站路由 + envelope 构建辅助工具 | + | `plugin-sdk/inbound-reply-dispatch` | 共享入站记录与分发辅助工具 | + | `plugin-sdk/messaging-targets` | 目标解析/匹配辅助工具 | + | `plugin-sdk/outbound-media` | 共享出站媒体加载辅助工具 | + | `plugin-sdk/outbound-runtime` | 出站身份/发送委托辅助工具 | + | `plugin-sdk/thread-bindings-runtime` | 线程绑定生命周期和适配器辅助工具 | | `plugin-sdk/agent-media-payload` | 旧版智能体媒体负载构建器 | - | `plugin-sdk/conversation-runtime` | 会话/线程绑定、配对以及已配置绑定辅助函数 | - | `plugin-sdk/runtime-config-snapshot` | 运行时配置快照辅助函数 | - | `plugin-sdk/runtime-group-policy` | 运行时群组策略解析辅助函数 | - | `plugin-sdk/channel-status` | 共享的渠道状态快照/摘要辅助函数 | - | `plugin-sdk/channel-config-primitives` | 窄范围的渠道配置 schema 原语 | - | `plugin-sdk/channel-config-writes` | 渠道配置写入授权辅助函数 | - | `plugin-sdk/channel-plugin-common` | 共享的渠道插件前导导出 | - | `plugin-sdk/allowlist-config-edit` | allowlist 配置编辑/读取辅助函数 | - | `plugin-sdk/group-access` | 共享的群组访问决策辅助函数 | - | `plugin-sdk/direct-dm` | 共享的直接私信认证/保护辅助函数 | - | `plugin-sdk/interactive-runtime` | 交互式回复负载规范化/归约辅助函数 | - | `plugin-sdk/channel-inbound` | 去抖动、提及匹配、envelope 辅助函数 | + | `plugin-sdk/conversation-runtime` | 对话/线程绑定、配对和已配置绑定辅助工具 | + | `plugin-sdk/runtime-config-snapshot` | 运行时配置快照辅助工具 | + | `plugin-sdk/runtime-group-policy` | 运行时群组策略解析辅助工具 | + | `plugin-sdk/channel-status` | 共享渠道状态快照/摘要辅助工具 | + | `plugin-sdk/channel-config-primitives` | 狭义渠道配置 schema 原语 | + | `plugin-sdk/channel-config-writes` | 渠道配置写入授权辅助工具 | + | `plugin-sdk/channel-plugin-common` | 共享渠道插件前导导出 | + | `plugin-sdk/allowlist-config-edit` | allowlist 配置编辑/读取辅助工具 | + | `plugin-sdk/group-access` | 共享群组访问决策辅助工具 | + | `plugin-sdk/direct-dm` | 共享直接私信认证/守卫辅助工具 | + | `plugin-sdk/interactive-runtime` | 交互式回复负载规范化/归约辅助工具 | + | `plugin-sdk/channel-inbound` | 防抖、提及匹配、envelope 辅助工具 | | `plugin-sdk/channel-send-result` | 回复结果类型 | | `plugin-sdk/channel-actions` | `createMessageToolButtonsSchema`, `createMessageToolCardSchema` | - | `plugin-sdk/channel-targets` | 目标解析/匹配辅助函数 | + | `plugin-sdk/channel-targets` | 目标解析/匹配辅助工具 | | `plugin-sdk/channel-contract` | 渠道契约类型 | | `plugin-sdk/channel-feedback` | 反馈/反应接线 | @@ -108,218 +111,221 @@ import { defineChannelPluginEntry } from "openclaw/plugin-sdk/channel-core"; | 子路径 | 关键导出 | | --- | --- | | `plugin-sdk/provider-entry` | `defineSingleProviderPluginEntry` | - | `plugin-sdk/provider-setup` | 精选的本地/自托管提供商设置辅助函数 | - | `plugin-sdk/self-hosted-provider-setup` | 聚焦于 OpenAI 兼容自托管提供商的设置辅助函数 | - | `plugin-sdk/provider-auth-runtime` | 提供商插件的运行时 API 密钥解析辅助函数 | - | `plugin-sdk/provider-auth-api-key` | API 密钥新手引导/配置文件写入辅助函数,例如 `upsertApiKeyProfile` | + | `plugin-sdk/provider-setup` | 精选的本地/自托管提供商设置辅助工具 | + | `plugin-sdk/self-hosted-provider-setup` | 聚焦于 OpenAI 兼容自托管提供商的设置辅助工具 | + | `plugin-sdk/cli-backend` | CLI 后端默认值 + watchdog 常量 | + | `plugin-sdk/provider-auth-runtime` | 提供商插件的运行时 API key 解析辅助工具 | + | `plugin-sdk/provider-auth-api-key` | API key 新手引导/profile 写入辅助工具,例如 `upsertApiKeyProfile` | | `plugin-sdk/provider-auth-result` | 标准 OAuth 认证结果构建器 | - | `plugin-sdk/provider-auth-login` | 提供商插件共享的交互式登录辅助函数 | - | `plugin-sdk/provider-env-vars` | 提供商认证环境变量查找辅助函数 | + | `plugin-sdk/provider-auth-login` | 提供商插件的共享交互式登录辅助工具 | + | `plugin-sdk/provider-env-vars` | 提供商认证环境变量查找辅助工具 | | `plugin-sdk/provider-auth` | `createProviderApiKeyAuthMethod`, `ensureApiKeyFromOptionEnvOrPrompt`, `upsertAuthProfile`, `upsertApiKeyProfile`, `writeOAuthCredentials` | - | `plugin-sdk/provider-model-shared` | `ProviderReplayFamily`, `buildProviderReplayFamilyHooks`, `normalizeModelCompat`、共享 replay-policy 构建器、provider-endpoint 辅助函数,以及 `normalizeNativeXaiModelId` 等 model-id 规范化辅助函数 | + | `plugin-sdk/provider-model-shared` | `ProviderReplayFamily`, `buildProviderReplayFamilyHooks`, `normalizeModelCompat`、共享 replay-policy 构建器、提供商端点辅助工具,以及如 `normalizeNativeXaiModelId` 之类的 model-id 规范化辅助工具 | | `plugin-sdk/provider-catalog-shared` | `findCatalogTemplate`, `buildSingleProviderApiKeyCatalog`, `supportsNativeStreamingUsageCompat`, `applyProviderNativeStreamingUsageCompat` | - | `plugin-sdk/provider-http` | 通用提供商 HTTP/端点能力辅助函数 | - | `plugin-sdk/provider-web-fetch` | Web-fetch 提供商注册/缓存辅助函数 | - | `plugin-sdk/provider-web-search` | Web 搜索提供商注册/缓存/配置辅助函数 | - | `plugin-sdk/provider-tools` | `ProviderToolCompatFamily`, `buildProviderToolCompatFamilyHooks`、Gemini schema 清理 + 诊断,以及 `resolveXaiModelCompatPatch` / `applyXaiModelCompat` 等 xAI 兼容辅助函数 | - | `plugin-sdk/provider-usage` | `fetchClaudeUsage` 及类似函数 | - | `plugin-sdk/provider-stream` | `ProviderStreamFamily`, `buildProviderStreamFamilyHooks`, `composeProviderStreamWrappers`、流包装器类型,以及共享的 Anthropic/Bedrock/Google/Kilocode/Moonshot/OpenAI/OpenRouter/Z.A.I/MiniMax/Copilot 包装器辅助函数 | - | `plugin-sdk/provider-onboard` | 新手引导配置补丁辅助函数 | - | `plugin-sdk/global-singleton` | 进程本地 singleton/map/cache 辅助函数 | + | `plugin-sdk/provider-http` | 通用提供商 HTTP/端点能力辅助工具 | + | `plugin-sdk/provider-web-fetch` | 网页抓取提供商注册/缓存辅助工具 | + | `plugin-sdk/provider-web-search` | 网页搜索提供商注册/缓存/配置辅助工具 | + | `plugin-sdk/provider-tools` | `ProviderToolCompatFamily`, `buildProviderToolCompatFamilyHooks`, Gemini schema 清理 + 诊断,以及如 `resolveXaiModelCompatPatch` / `applyXaiModelCompat` 之类的 xAI 兼容辅助工具 | + | `plugin-sdk/provider-usage` | `fetchClaudeUsage` 等 | + | `plugin-sdk/provider-stream` | `ProviderStreamFamily`, `buildProviderStreamFamilyHooks`, `composeProviderStreamWrappers`、流包装器类型,以及共享的 Anthropic/Bedrock/Google/Kilocode/Moonshot/OpenAI/OpenRouter/Z.A.I/MiniMax/Copilot 包装器辅助工具 | + | `plugin-sdk/provider-onboard` | 新手引导配置补丁辅助工具 | + | `plugin-sdk/global-singleton` | 进程本地 singleton/map/cache 辅助工具 | - + | 子路径 | 关键导出 | | --- | --- | - | `plugin-sdk/command-auth` | `resolveControlCommandGate`、命令注册表辅助函数、发送者授权辅助函数 | - | `plugin-sdk/approval-auth-runtime` | 审批人解析和同聊天操作认证辅助函数 | - | `plugin-sdk/approval-client-runtime` | 原生执行审批配置文件/过滤辅助函数 | + | `plugin-sdk/command-auth` | `resolveControlCommandGate`、命令注册表辅助工具、发送者授权辅助工具 | + | `plugin-sdk/approval-auth-runtime` | 审批人解析和同聊天操作认证辅助工具 | + | `plugin-sdk/approval-client-runtime` | 原生 exec 审批 profile/filter 辅助工具 | | `plugin-sdk/approval-delivery-runtime` | 原生审批能力/投递适配器 | - | `plugin-sdk/approval-native-runtime` | 原生审批目标 + 账户绑定辅助函数 | - | `plugin-sdk/approval-reply-runtime` | exec/plugin 审批回复负载辅助函数 | - | `plugin-sdk/command-auth-native` | 原生命令认证 + 原生会话目标辅助函数 | - | `plugin-sdk/command-detection` | 共享的命令检测辅助函数 | - | `plugin-sdk/command-surface` | 命令体规范化和命令表面辅助函数 | + | `plugin-sdk/approval-native-runtime` | 原生审批目标 + 账户绑定辅助工具 | + | `plugin-sdk/approval-reply-runtime` | exec/插件审批回复负载辅助工具 | + | `plugin-sdk/command-auth-native` | 原生命令认证 + 原生会话目标辅助工具 | + | `plugin-sdk/command-detection` | 共享命令检测辅助工具 | + | `plugin-sdk/command-surface` | 命令体规范化和命令接口辅助工具 | | `plugin-sdk/allow-from` | `formatAllowFromLowercase` | - | `plugin-sdk/security-runtime` | 共享的信任、私信门禁、外部内容和 secret 收集辅助函数 | - | `plugin-sdk/ssrf-policy` | 主机 allowlist 和私有网络 SSRF 策略辅助函数 | - | `plugin-sdk/ssrf-runtime` | pinned-dispatcher、受 SSRF 防护的 fetch 以及 SSRF 策略辅助函数 | - | `plugin-sdk/secret-input` | secret 输入解析辅助函数 | - | `plugin-sdk/webhook-ingress` | webhook 请求/目标辅助函数 | - | `plugin-sdk/webhook-request-guards` | 请求体大小/超时辅助函数 | + | `plugin-sdk/security-runtime` | 共享信任、私信门控、外部内容和秘密收集辅助工具 | + | `plugin-sdk/ssrf-policy` | 主机 allowlist 和私有网络 SSRF 策略辅助工具 | + | `plugin-sdk/ssrf-runtime` | pinned-dispatcher、受 SSRF 保护的 fetch,以及 SSRF 策略辅助工具 | + | `plugin-sdk/secret-input` | 秘密输入解析辅助工具 | + | `plugin-sdk/webhook-ingress` | webhook 请求/目标辅助工具 | + | `plugin-sdk/webhook-request-guards` | 请求体大小/超时辅助工具 | - + | 子路径 | 关键导出 | | --- | --- | - | `plugin-sdk/runtime` | 广泛的运行时/日志/备份/插件安装辅助函数 | - | `plugin-sdk/runtime-env` | 窄范围的运行时 env、logger、timeout、retry 和 backoff 辅助函数 | + | `plugin-sdk/runtime` | 宽泛的运行时/日志/备份/插件安装辅助工具 | + | `plugin-sdk/runtime-env` | 狭义运行时环境、logger、timeout、retry 和 backoff 辅助工具 | | `plugin-sdk/runtime-store` | `createPluginRuntimeStore` | - | `plugin-sdk/plugin-runtime` | 共享的插件命令/hook/http/交互式辅助函数 | - | `plugin-sdk/hook-runtime` | 共享的 webhook/内部 hook 管道辅助函数 | - | `plugin-sdk/lazy-runtime` | 延迟运行时导入/绑定辅助函数,例如 `createLazyRuntimeModule`、`createLazyRuntimeMethod` 和 `createLazyRuntimeSurface` | - | `plugin-sdk/process-runtime` | 进程执行辅助函数 | - | `plugin-sdk/cli-runtime` | CLI 格式化、等待和版本辅助函数 | - | `plugin-sdk/gateway-runtime` | Gateway 网关客户端和渠道状态补丁辅助函数 | - | `plugin-sdk/config-runtime` | 配置加载/写入辅助函数 | - | `plugin-sdk/telegram-command-config` | Telegram 命令名称/描述规范化以及重复/冲突检查,即使内置 Telegram 契约表面不可用也可以工作 | - | `plugin-sdk/approval-runtime` | exec/plugin 审批辅助函数、审批能力构建器、认证/配置文件辅助函数、原生路由/运行时辅助函数 | - | `plugin-sdk/reply-runtime` | 共享的入站/回复运行时辅助函数、分块、分发、心跳、回复规划器 | - | `plugin-sdk/reply-dispatch-runtime` | 窄范围的回复分发/完成辅助函数 | - | `plugin-sdk/reply-history` | 共享的短窗口回复历史辅助函数,例如 `buildHistoryContext`、`recordPendingHistoryEntry` 和 `clearHistoryEntriesIfEnabled` | + | `plugin-sdk/plugin-runtime` | 共享插件命令/hook/HTTP/交互式辅助工具 | + | `plugin-sdk/hook-runtime` | 共享 webhook/内部 hook 管道辅助工具 | + | `plugin-sdk/lazy-runtime` | 延迟运行时导入/绑定辅助工具,例如 `createLazyRuntimeModule`、`createLazyRuntimeMethod` 和 `createLazyRuntimeSurface` | + | `plugin-sdk/process-runtime` | 进程 exec 辅助工具 | + | `plugin-sdk/cli-runtime` | CLI 格式化、等待和版本辅助工具 | + | `plugin-sdk/gateway-runtime` | Gateway 网关客户端和渠道状态补丁辅助工具 | + | `plugin-sdk/config-runtime` | 配置加载/写入辅助工具 | + | `plugin-sdk/telegram-command-config` | 即使内置 Telegram 契约接口不可用,也可用的 Telegram 命令名/描述规范化及重复/冲突检查 | + | `plugin-sdk/approval-runtime` | exec/插件审批辅助工具、审批能力构建器、auth/profile 辅助工具、原生路由/运行时辅助工具 | + | `plugin-sdk/reply-runtime` | 共享入站/回复运行时辅助工具、分块、分发、heartbeat、回复规划器 | + | `plugin-sdk/reply-dispatch-runtime` | 狭义回复分发/最终化辅助工具 | + | `plugin-sdk/reply-history` | 共享短窗口回复历史辅助工具,例如 `buildHistoryContext`、`recordPendingHistoryEntry` 和 `clearHistoryEntriesIfEnabled` | | `plugin-sdk/reply-reference` | `createReplyReferencePlanner` | - | `plugin-sdk/reply-chunking` | 窄范围的文本/Markdown 分块辅助函数 | - | `plugin-sdk/session-store-runtime` | 会话存储路径 + updated-at 辅助函数 | - | `plugin-sdk/state-paths` | 状态/OAuth 目录路径辅助函数 | - | `plugin-sdk/routing` | 路由/会话键/账户绑定辅助函数,例如 `resolveAgentRoute`、`buildAgentSessionKey` 和 `resolveDefaultAgentBoundAccountId` | - | `plugin-sdk/status-helpers` | 共享的渠道/账户状态摘要辅助函数、运行时状态默认值以及问题元数据辅助函数 | - | `plugin-sdk/target-resolver-runtime` | 共享的目标解析器辅助函数 | - | `plugin-sdk/string-normalization-runtime` | slug/字符串规范化辅助函数 | + | `plugin-sdk/reply-chunking` | 狭义文本/markdown 分块辅助工具 | + | `plugin-sdk/session-store-runtime` | 会话存储路径 + updated-at 辅助工具 | + | `plugin-sdk/state-paths` | 状态/OAuth 目录路径辅助工具 | + | `plugin-sdk/routing` | 路由/会话键/账户绑定辅助工具,例如 `resolveAgentRoute`、`buildAgentSessionKey` 和 `resolveDefaultAgentBoundAccountId` | + | `plugin-sdk/status-helpers` | 共享渠道/账户状态摘要辅助工具、运行时状态默认值,以及问题元数据辅助工具 | + | `plugin-sdk/target-resolver-runtime` | 共享目标解析器辅助工具 | + | `plugin-sdk/string-normalization-runtime` | slug/字符串规范化辅助工具 | | `plugin-sdk/request-url` | 从 fetch/request 类输入中提取字符串 URL | - | `plugin-sdk/run-command` | 带计时的命令运行器,输出规范化的 stdout/stderr 结果 | - | `plugin-sdk/param-readers` | 通用工具/CLI 参数读取器 | + | `plugin-sdk/run-command` | 带定时功能的命令运行器,返回规范化的 stdout/stderr 结果 | + | `plugin-sdk/param-readers` | 常用工具/CLI 参数读取器 | | `plugin-sdk/tool-send` | 从工具参数中提取规范发送目标字段 | - | `plugin-sdk/temp-path` | 共享的临时下载路径辅助函数 | - | `plugin-sdk/logging-core` | 子系统 logger 和脱敏辅助函数 | - | `plugin-sdk/markdown-table-runtime` | Markdown 表格模式辅助函数 | - | `plugin-sdk/json-store` | 小型 JSON 状态读写辅助函数 | - | `plugin-sdk/file-lock` | 可重入文件锁辅助函数 | - | `plugin-sdk/persistent-dedupe` | 磁盘支持的去重缓存辅助函数 | - | `plugin-sdk/acp-runtime` | ACP 运行时/会话和回复分发辅助函数 | - | `plugin-sdk/agent-config-primitives` | 窄范围的智能体运行时配置 schema 原语 | + | `plugin-sdk/temp-path` | 共享临时下载路径辅助工具 | + | `plugin-sdk/logging-core` | 子系统 logger 和脱敏辅助工具 | + | `plugin-sdk/markdown-table-runtime` | Markdown 表格模式辅助工具 | + | `plugin-sdk/json-store` | 小型 JSON 状态读取/写入辅助工具 | + | `plugin-sdk/file-lock` | 可重入 file-lock 辅助工具 | + | `plugin-sdk/persistent-dedupe` | 磁盘支持的去重缓存辅助工具 | + | `plugin-sdk/acp-runtime` | ACP 运行时/会话和回复分发辅助工具 | + | `plugin-sdk/agent-config-primitives` | 狭义智能体运行时配置 schema 原语 | | `plugin-sdk/boolean-param` | 宽松布尔参数读取器 | - | `plugin-sdk/dangerous-name-runtime` | 危险名称匹配解析辅助函数 | - | `plugin-sdk/device-bootstrap` | 设备引导和配对令牌辅助函数 | - | `plugin-sdk/extension-shared` | 共享的被动渠道和状态辅助原语 | - | `plugin-sdk/models-provider-runtime` | `/models` 命令/提供商回复辅助函数 | - | `plugin-sdk/skill-commands-runtime` | Skills 命令列表辅助函数 | - | `plugin-sdk/native-command-registry` | 原生命令注册表/构建/序列化辅助函数 | - | `plugin-sdk/provider-zai-endpoint` | Z.AI 端点检测辅助函数 | - | `plugin-sdk/infra-runtime` | 系统事件/心跳辅助函数 | - | `plugin-sdk/collection-runtime` | 小型有界缓存辅助函数 | - | `plugin-sdk/diagnostic-runtime` | 诊断标志和事件辅助函数 | - | `plugin-sdk/error-runtime` | 错误图、格式化、共享错误分类辅助函数、`isApprovalNotFoundError` | - | `plugin-sdk/fetch-runtime` | 包装后的 fetch、代理和 pinned 查找辅助函数 | - | `plugin-sdk/host-runtime` | 主机名和 SCP 主机规范化辅助函数 | - | `plugin-sdk/retry-runtime` | retry 配置和 retry 运行器辅助函数 | - | `plugin-sdk/agent-runtime` | 智能体目录/身份/workspace 辅助函数 | + | `plugin-sdk/dangerous-name-runtime` | 危险名称匹配解析辅助工具 | + | `plugin-sdk/device-bootstrap` | 设备引导和配对 token 辅助工具 | + | `plugin-sdk/extension-shared` | 共享被动渠道和状态辅助原语 | + | `plugin-sdk/models-provider-runtime` | `/models` 命令/提供商回复辅助工具 | + | `plugin-sdk/skill-commands-runtime` | skill 命令列表辅助工具 | + | `plugin-sdk/native-command-registry` | 原生命令注册表构建/序列化辅助工具 | + | `plugin-sdk/provider-zai-endpoint` | Z.AI 端点检测辅助工具 | + | `plugin-sdk/infra-runtime` | 系统事件/heartbeat 辅助工具 | + | `plugin-sdk/collection-runtime` | 小型有界缓存辅助工具 | + | `plugin-sdk/diagnostic-runtime` | 诊断标志和事件辅助工具 | + | `plugin-sdk/error-runtime` | 错误图、格式化、共享错误分类辅助工具、`isApprovalNotFoundError` | + | `plugin-sdk/fetch-runtime` | 封装的 fetch、代理和 pinned 查找辅助工具 | + | `plugin-sdk/host-runtime` | 主机名和 SCP 主机规范化辅助工具 | + | `plugin-sdk/retry-runtime` | retry 配置和 retry 运行器辅助工具 | + | `plugin-sdk/agent-runtime` | 智能体目录/身份/工作区辅助工具 | | `plugin-sdk/directory-runtime` | 基于配置的目录查询/去重 | | `plugin-sdk/keyed-async-queue` | `KeyedAsyncQueue` | - + | 子路径 | 关键导出 | | --- | --- | - | `plugin-sdk/media-runtime` | 共享的媒体抓取/转换/存储辅助函数,以及媒体负载构建器 | - | `plugin-sdk/media-generation-runtime` | 共享的媒体生成故障转移辅助函数、候选项选择和缺失模型提示 | + | `plugin-sdk/media-runtime` | 共享媒体抓取/转换/存储辅助工具,以及媒体负载构建器 | + | `plugin-sdk/media-generation-runtime` | 共享媒体生成故障转移辅助工具、候选项选择和缺失模型提示 | | `plugin-sdk/media-understanding` | 媒体理解提供商类型,以及面向提供商的图像/音频辅助导出 | - | `plugin-sdk/text-runtime` | 共享的文本/Markdown/日志辅助函数,例如 assistant-visible-text 剥离、Markdown 渲染/分块/表格辅助函数、脱敏辅助函数、directive-tag 辅助函数和 safe-text 实用函数 | - | `plugin-sdk/text-chunking` | 出站文本分块辅助函数 | - | `plugin-sdk/speech` | 语音提供商类型,以及面向提供商的 directive、注册表和校验辅助函数 | - | `plugin-sdk/speech-core` | 共享的语音提供商类型、注册表、directive 和规范化辅助函数 | - | `plugin-sdk/realtime-transcription` | 实时转写提供商类型和注册表辅助函数 | - | `plugin-sdk/realtime-voice` | 实时语音提供商类型和注册表辅助函数 | + | `plugin-sdk/text-runtime` | 共享文本/markdown/日志辅助工具,例如助手可见文本剥离、markdown 渲染/分块/表格辅助工具、脱敏辅助工具、指令标签辅助工具和安全文本工具 | + | `plugin-sdk/text-chunking` | 出站文本分块辅助工具 | + | `plugin-sdk/speech` | 语音提供商类型,以及面向提供商的指令、注册表和验证辅助工具 | + | `plugin-sdk/speech-core` | 共享语音提供商类型、注册表、指令和规范化辅助工具 | + | `plugin-sdk/realtime-transcription` | 实时转录提供商类型和注册表辅助工具 | + | `plugin-sdk/realtime-voice` | 实时语音提供商类型和注册表辅助工具 | | `plugin-sdk/image-generation` | 图像生成提供商类型 | - | `plugin-sdk/image-generation-core` | 共享的图像生成类型、故障转移、认证和注册表辅助函数 | + | `plugin-sdk/image-generation-core` | 共享图像生成类型、故障转移、认证和注册表辅助工具 | | `plugin-sdk/music-generation` | 音乐生成提供商/请求/结果类型 | - | `plugin-sdk/music-generation-core` | 共享的音乐生成类型、故障转移辅助函数、提供商查找和 model-ref 解析 | + | `plugin-sdk/music-generation-core` | 共享音乐生成类型、故障转移辅助工具、提供商查找和 model-ref 解析 | | `plugin-sdk/video-generation` | 视频生成提供商/请求/结果类型 | - | `plugin-sdk/video-generation-core` | 共享的视频生成类型、故障转移辅助函数、提供商查找和 model-ref 解析 | - | `plugin-sdk/webhook-targets` | webhook 目标注册表和路由安装辅助函数 | - | `plugin-sdk/webhook-path` | webhook 路径规范化辅助函数 | - | `plugin-sdk/web-media` | 共享的远程/本地媒体加载辅助函数 | - | `plugin-sdk/zod` | 为插件 SDK 使用者重新导出的 `zod` | + | `plugin-sdk/video-generation-core` | 共享视频生成类型、故障转移辅助工具、提供商查找和 model-ref 解析 | + | `plugin-sdk/webhook-targets` | webhook 目标注册表和路由安装辅助工具 | + | `plugin-sdk/webhook-path` | webhook 路径规范化辅助工具 | + | `plugin-sdk/web-media` | 共享远程/本地媒体加载辅助工具 | + | `plugin-sdk/zod` | 为插件 SDK 使用方重新导出的 `zod` | | `plugin-sdk/testing` | `installCommonResolveTargetErrorCases`, `shouldAckReaction` | - + | 子路径 | 关键导出 | | --- | --- | - | `plugin-sdk/memory-core` | 内置 memory-core 辅助表面,用于 manager/config/file/CLI 辅助函数 | - | `plugin-sdk/memory-core-engine-runtime` | 记忆索引/搜索运行时外观 | - | `plugin-sdk/memory-core-host-engine-foundation` | 记忆主机基础引擎导出 | - | `plugin-sdk/memory-core-host-engine-embeddings` | 记忆主机嵌入引擎导出 | - | `plugin-sdk/memory-core-host-engine-qmd` | 记忆主机 QMD 引擎导出 | - | `plugin-sdk/memory-core-host-engine-storage` | 记忆主机存储引擎导出 | - | `plugin-sdk/memory-core-host-multimodal` | 记忆主机多模态辅助函数 | - | `plugin-sdk/memory-core-host-query` | 记忆主机查询辅助函数 | - | `plugin-sdk/memory-core-host-secret` | 记忆主机 secret 辅助函数 | - | `plugin-sdk/memory-core-host-events` | 记忆主机事件日志辅助函数 | - | `plugin-sdk/memory-core-host-status` | 记忆主机状态辅助函数 | - | `plugin-sdk/memory-core-host-runtime-cli` | 记忆主机 CLI 运行时辅助函数 | - | `plugin-sdk/memory-core-host-runtime-core` | 记忆主机核心运行时辅助函数 | - | `plugin-sdk/memory-core-host-runtime-files` | 记忆主机文件/运行时辅助函数 | - | `plugin-sdk/memory-host-core` | 面向供应商中立的记忆主机核心运行时辅助函数别名 | - | `plugin-sdk/memory-host-events` | 面向供应商中立的记忆主机事件日志辅助函数别名 | - | `plugin-sdk/memory-host-files` | 面向供应商中立的记忆主机文件/运行时辅助函数别名 | - | `plugin-sdk/memory-host-markdown` | 供记忆相关插件使用的共享托管 Markdown 辅助函数 | - | `plugin-sdk/memory-host-search` | 用于访问 search-manager 的活动记忆运行时外观 | - | `plugin-sdk/memory-host-status` | 面向供应商中立的记忆主机状态辅助函数别名 | - | `plugin-sdk/memory-lancedb` | 内置 memory-lancedb 辅助表面 | + | `plugin-sdk/memory-core` | 内置 memory-core 辅助接口,用于 manager/config/file/CLI 辅助工具 | + | `plugin-sdk/memory-core-engine-runtime` | Memory 索引/搜索运行时门面 | + | `plugin-sdk/memory-core-host-engine-foundation` | Memory host foundation engine 导出 | + | `plugin-sdk/memory-core-host-engine-embeddings` | Memory host embedding engine 导出 | + | `plugin-sdk/memory-core-host-engine-qmd` | Memory host QMD engine 导出 | + | `plugin-sdk/memory-core-host-engine-storage` | Memory host storage engine 导出 | + | `plugin-sdk/memory-core-host-multimodal` | Memory host 多模态辅助工具 | + | `plugin-sdk/memory-core-host-query` | Memory host 查询辅助工具 | + | `plugin-sdk/memory-core-host-secret` | Memory host secret 辅助工具 | + | `plugin-sdk/memory-core-host-events` | Memory host 事件日志辅助工具 | + | `plugin-sdk/memory-core-host-status` | Memory host 状态辅助工具 | + | `plugin-sdk/memory-core-host-runtime-cli` | Memory host CLI 运行时辅助工具 | + | `plugin-sdk/memory-core-host-runtime-core` | Memory host 核心运行时辅助工具 | + | `plugin-sdk/memory-core-host-runtime-files` | Memory host 文件/运行时辅助工具 | + | `plugin-sdk/memory-host-core` | Memory host 核心运行时辅助工具的供应商中立别名 | + | `plugin-sdk/memory-host-events` | Memory host 事件日志辅助工具的供应商中立别名 | + | `plugin-sdk/memory-host-files` | Memory host 文件/运行时辅助工具的供应商中立别名 | + | `plugin-sdk/memory-host-markdown` | 用于 memory 邻接插件的共享托管 markdown 辅助工具 | + | `plugin-sdk/memory-host-search` | 用于访问 search-manager 的活动 Memory 运行时门面 | + | `plugin-sdk/memory-host-status` | Memory host 状态辅助工具的供应商中立别名 | + | `plugin-sdk/memory-lancedb` | 内置 memory-lancedb 辅助接口 | - | 系列 | 当前子路径 | 预期用途 | + | 家族 | 当前子路径 | 预期用途 | | --- | --- | --- | - | Browser | `plugin-sdk/browser-cdp`, `plugin-sdk/browser-config-runtime`, `plugin-sdk/browser-config-support`, `plugin-sdk/browser-control-auth`, `plugin-sdk/browser-node-runtime`, `plugin-sdk/browser-profiles`, `plugin-sdk/browser-security-runtime`, `plugin-sdk/browser-setup-tools`, `plugin-sdk/browser-support` | 内置 Browser 插件支持辅助函数(`browser-support` 仍是兼容性 barrel) | - | Matrix | `plugin-sdk/matrix`, `plugin-sdk/matrix-helper`, `plugin-sdk/matrix-runtime-heavy`, `plugin-sdk/matrix-runtime-shared`, `plugin-sdk/matrix-runtime-surface`, `plugin-sdk/matrix-surface`, `plugin-sdk/matrix-thread-bindings` | 内置 Matrix 辅助/运行时表面 | - | Line | `plugin-sdk/line`, `plugin-sdk/line-core`, `plugin-sdk/line-runtime`, `plugin-sdk/line-surface` | 内置 LINE 辅助/运行时表面 | - | IRC | `plugin-sdk/irc`, `plugin-sdk/irc-surface` | 内置 IRC 辅助表面 | - | 渠道特定辅助函数 | `plugin-sdk/googlechat`, `plugin-sdk/zalouser`, `plugin-sdk/bluebubbles`, `plugin-sdk/bluebubbles-policy`, `plugin-sdk/mattermost`, `plugin-sdk/mattermost-policy`, `plugin-sdk/feishu-conversation`, `plugin-sdk/msteams`, `plugin-sdk/nextcloud-talk`, `plugin-sdk/nostr`, `plugin-sdk/tlon`, `plugin-sdk/twitch` | 内置渠道兼容性/辅助接缝 | - | 认证/插件特定辅助函数 | `plugin-sdk/github-copilot-login`, `plugin-sdk/github-copilot-token`, `plugin-sdk/diagnostics-otel`, `plugin-sdk/diffs`, `plugin-sdk/llm-task`, `plugin-sdk/thread-ownership`, `plugin-sdk/voice-call` | 内置功能/插件辅助接缝;`plugin-sdk/github-copilot-token` 当前导出 `DEFAULT_COPILOT_API_BASE_URL`、`deriveCopilotApiBaseUrlFromToken` 和 `resolveCopilotApiToken` | + | Browser | `plugin-sdk/browser-cdp`, `plugin-sdk/browser-config-runtime`, `plugin-sdk/browser-config-support`, `plugin-sdk/browser-control-auth`, `plugin-sdk/browser-node-runtime`, `plugin-sdk/browser-profiles`, `plugin-sdk/browser-security-runtime`, `plugin-sdk/browser-setup-tools`, `plugin-sdk/browser-support` | 内置浏览器插件支持辅助工具(`browser-support` 仍是兼容性 barrel) | + | Matrix | `plugin-sdk/matrix`, `plugin-sdk/matrix-helper`, `plugin-sdk/matrix-runtime-heavy`, `plugin-sdk/matrix-runtime-shared`, `plugin-sdk/matrix-runtime-surface`, `plugin-sdk/matrix-surface`, `plugin-sdk/matrix-thread-bindings` | 内置 Matrix 辅助/运行时接口 | + | Line | `plugin-sdk/line`, `plugin-sdk/line-core`, `plugin-sdk/line-runtime`, `plugin-sdk/line-surface` | 内置 LINE 辅助/运行时接口 | + | IRC | `plugin-sdk/irc`, `plugin-sdk/irc-surface` | 内置 IRC 辅助接口 | + | 渠道特定辅助工具 | `plugin-sdk/googlechat`, `plugin-sdk/zalouser`, `plugin-sdk/bluebubbles`, `plugin-sdk/bluebubbles-policy`, `plugin-sdk/mattermost`, `plugin-sdk/mattermost-policy`, `plugin-sdk/feishu-conversation`, `plugin-sdk/msteams`, `plugin-sdk/nextcloud-talk`, `plugin-sdk/nostr`, `plugin-sdk/tlon`, `plugin-sdk/twitch` | 内置渠道兼容性/辅助扩展点 | + | 认证/插件特定辅助工具 | `plugin-sdk/github-copilot-login`, `plugin-sdk/github-copilot-token`, `plugin-sdk/diagnostics-otel`, `plugin-sdk/diffs`, `plugin-sdk/llm-task`, `plugin-sdk/thread-ownership`, `plugin-sdk/voice-call` | 内置功能/插件辅助扩展点;`plugin-sdk/github-copilot-token` 当前导出 `DEFAULT_COPILOT_API_BASE_URL`、`deriveCopilotApiBaseUrlFromToken` 和 `resolveCopilotApiToken` | ## 注册 API -`register(api)` 回调会收到一个带有以下方法的 `OpenClawPluginApi` 对象: +`register(api)` 回调会收到一个 `OpenClawPluginApi` 对象,包含以下方法: ### 能力注册 -| 方法 | 注册内容 | -| ---------------------------------------------- | ------------------------ | -| `api.registerProvider(...)` | 文本推理(LLM) | -| `api.registerChannel(...)` | 消息渠道 | -| `api.registerSpeechProvider(...)` | 文本转语音 / STT 合成 | -| `api.registerRealtimeTranscriptionProvider(...)` | 流式实时转写 | -| `api.registerRealtimeVoiceProvider(...)` | 双工实时语音会话 | -| `api.registerMediaUnderstandingProvider(...)` | 图像/音频/视频分析 | -| `api.registerImageGenerationProvider(...)` | 图像生成 | -| `api.registerMusicGenerationProvider(...)` | 音乐生成 | -| `api.registerVideoGenerationProvider(...)` | 视频生成 | -| `api.registerWebFetchProvider(...)` | Web 抓取 / 抓取提供商 | -| `api.registerWebSearchProvider(...)` | Web 搜索 | +| 方法 | 注册内容 | +| ------------------------------------------------ | -------------------------------- | +| `api.registerProvider(...)` | 文本推理(LLM) | +| `api.registerCliBackend(...)` | 本地 CLI 推理后端 | +| `api.registerChannel(...)` | 消息渠道 | +| `api.registerSpeechProvider(...)` | 文本转语音 / STT 合成 | +| `api.registerRealtimeTranscriptionProvider(...)` | 流式实时转录 | +| `api.registerRealtimeVoiceProvider(...)` | 双工实时语音会话 | +| `api.registerMediaUnderstandingProvider(...)` | 图像/音频/视频分析 | +| `api.registerImageGenerationProvider(...)` | 图像生成 | +| `api.registerMusicGenerationProvider(...)` | 音乐生成 | +| `api.registerVideoGenerationProvider(...)` | 视频生成 | +| `api.registerWebFetchProvider(...)` | 网页抓取 / 爬取提供商 | +| `api.registerWebSearchProvider(...)` | 网页搜索 | -### 工具和命令 +### 工具与命令 -| 方法 | 注册内容 | -| ----------------------------- | ----------------------------------------- | -| `api.registerTool(tool, opts?)` | 智能体工具(必需或 `{ optional: true }`) | -| `api.registerCommand(def)` | 自定义命令(绕过 LLM) | +| 方法 | 注册内容 | +| ------------------------------- | --------------------------------------------- | +| `api.registerTool(tool, opts?)` | 智能体工具(必需,或 `{ optional: true }`) | +| `api.registerCommand(def)` | 自定义命令(绕过 LLM) | ### 基础设施 -| 方法 | 注册内容 | -| -------------------------------------------- | ----------------------------------- | -| `api.registerHook(events, handler, opts?)` | 事件 hook | -| `api.registerHttpRoute(params)` | Gateway 网关 HTTP 端点 | -| `api.registerGatewayMethod(name, handler)` | Gateway 网关 RPC 方法 | -| `api.registerCli(registrar, opts?)` | CLI 子命令 | -| `api.registerService(service)` | 后台服务 | -| `api.registerInteractiveHandler(registration)` | 交互式处理器 | -| `api.registerMemoryPromptSupplement(builder)` | 附加式记忆相关提示词段落 | -| `api.registerMemoryCorpusSupplement(adapter)` | 附加式记忆搜索/读取语料库 | +| 方法 | 注册内容 | +| ---------------------------------------------- | --------------------------------------- | +| `api.registerHook(events, handler, opts?)` | 事件 hook | +| `api.registerHttpRoute(params)` | Gateway 网关 HTTP 端点 | +| `api.registerGatewayMethod(name, handler)` | Gateway 网关 RPC 方法 | +| `api.registerCli(registrar, opts?)` | CLI 子命令 | +| `api.registerService(service)` | 后台服务 | +| `api.registerInteractiveHandler(registration)` | 交互式处理器 | +| `api.registerMemoryPromptSupplement(builder)` | 附加式 memory 邻接提示词部分 | +| `api.registerMemoryCorpusSupplement(adapter)` | 附加式 memory 搜索/读取语料 | -保留的核心管理命名空间(`config.*`、`exec.approvals.*`、`wizard.*`、`update.*`)始终保持为 `operator.admin`,即使插件尝试分配更窄的 Gateway 网关方法作用域也是如此。对于插件拥有的方法,优先使用插件特定的前缀。 +保留的核心管理命名空间(`config.*`、`exec.approvals.*`、`wizard.*`、 +`update.*`)始终保持为 `operator.admin`,即使某个插件尝试为 Gateway 网关 方法分配更窄的作用域也是如此。对于插件自有方法,优先使用插件专属前缀。 ### CLI 注册元数据 `api.registerCli(registrar, opts?)` 接受两类顶层元数据: -- `commands`:由 registrar 拥有的显式命令根 -- `descriptors`:用于根 CLI 帮助、路由和延迟插件 CLI 注册的解析时命令描述符 +- `commands`:由该 registrar 拥有的显式命令根 +- `descriptors`:用于根 CLI 帮助、路由和延迟插件 CLI 注册的解析期命令描述符 -如果你希望插件命令在正常根 CLI 路径中保持延迟加载,请提供覆盖该 registrar 暴露的每个顶层命令根的 `descriptors`。 +如果你希望某个插件命令在普通根 CLI 路径中保持延迟加载,请提供 `descriptors`,覆盖该 registrar 暴露的每一个顶层命令根。 ```typescript api.registerCli( @@ -331,7 +337,7 @@ api.registerCli( descriptors: [ { name: "matrix", - description: "管理 Matrix 账户、验证、设备和配置文件状态", + description: "Manage Matrix accounts, verification, devices, and profile state", hasSubcommands: true, }, ], @@ -339,60 +345,71 @@ api.registerCli( ); ``` -仅在你不需要延迟根 CLI 注册时,才单独使用 `commands`。这种急切兼容路径仍然受支持,但它不会为解析时延迟加载安装基于 descriptor 的占位符。 +仅在你不需要延迟根 CLI 注册时,才单独使用 `commands`。这种急切兼容路径仍然受支持,但它不会安装基于 descriptor 的占位符来实现解析期延迟加载。 -### 独占槽位 +### CLI 后端注册 -| 方法 | 注册内容 | -| ---------------------------------------- | ------------------------------ | -| `api.registerContextEngine(id, factory)` | 上下文引擎(一次仅一个处于活动状态) | -| `api.registerMemoryPromptSection(builder)` | 记忆提示词段落构建器 | -| `api.registerMemoryFlushPlan(resolver)` | 记忆刷新计划解析器 | -| `api.registerMemoryRuntime(runtime)` | 记忆运行时适配器 | +`api.registerCliBackend(...)` 允许插件拥有本地 AI CLI 后端(例如 `codex-cli`)的默认配置。 -### 记忆嵌入适配器 +- 后端 `id` 会成为模型引用中的提供商前缀,例如 `codex-cli/gpt-5`。 +- 后端 `config` 使用与 `agents.defaults.cliBackends.` 相同的结构。 +- 用户配置仍然优先。OpenClaw 会在运行 CLI 之前,将 `agents.defaults.cliBackends.` 合并覆盖到插件默认值之上。 +- 当某个后端在合并后需要兼容性重写时,使用 `normalizeConfig`(例如规范化旧的 flag 结构)。 -| 方法 | 注册内容 | -| -------------------------------------------- | ----------------------------------------- | -| `api.registerMemoryEmbeddingProvider(adapter)` | 活动插件的记忆嵌入适配器 | +### 独占插槽 -- `registerMemoryPromptSection`、`registerMemoryFlushPlan` 和 `registerMemoryRuntime` 对记忆插件是独占的。 -- `registerMemoryEmbeddingProvider` 允许活动记忆插件注册一个或多个嵌入适配器 id(例如 `openai`、`gemini` 或自定义插件定义的 id)。 -- 用户配置(例如 `agents.defaults.memorySearch.provider` 和 `agents.defaults.memorySearch.fallback`)会基于这些已注册的适配器 id 进行解析。 +| 方法 | 注册内容 | +| ------------------------------------------ | ------------------------------------- | +| `api.registerContextEngine(id, factory)` | 上下文引擎(一次只能激活一个) | +| `api.registerMemoryPromptSection(builder)` | Memory 提示词部分构建器 | +| `api.registerMemoryFlushPlan(resolver)` | Memory 刷新计划解析器 | +| `api.registerMemoryRuntime(runtime)` | Memory 运行时适配器 | -### 事件和生命周期 +### Memory embedding 适配器 -| 方法 | 作用 | -| ------------------------------------------ | -------------------- | -| `api.on(hookName, handler, opts?)` | 类型化生命周期 hook | -| `api.onConversationBindingResolved(handler)` | 会话绑定回调 | +| 方法 | 注册内容 | +| ---------------------------------------------- | ---------------------------------------------- | +| `api.registerMemoryEmbeddingProvider(adapter)` | 活动插件的 Memory embedding 适配器 | -### Hook 决策语义 +- `registerMemoryPromptSection`、`registerMemoryFlushPlan` 和 + `registerMemoryRuntime` 仅限 Memory 插件使用。 +- `registerMemoryEmbeddingProvider` 允许活动 Memory 插件注册一个或多个 embedding 适配器 ID(例如 `openai`、`gemini` 或插件自定义的 ID)。 +- 用户配置(例如 `agents.defaults.memorySearch.provider` 和 + `agents.defaults.memorySearch.fallback`)会解析为这些已注册的适配器 ID。 -- `before_tool_call`:返回 `{ block: true }` 是终止性决定。一旦任一处理器设置它,就会跳过较低优先级的处理器。 -- `before_tool_call`:返回 `{ block: false }` 会被视为没有做出决定(与省略 `block` 相同),而不是覆盖。 -- `before_install`:返回 `{ block: true }` 是终止性决定。一旦任一处理器设置它,就会跳过较低优先级的处理器。 -- `before_install`:返回 `{ block: false }` 会被视为没有做出决定(与省略 `block` 相同),而不是覆盖。 -- `reply_dispatch`:返回 `{ handled: true, ... }` 是终止性决定。一旦任一处理器声明接管分发,就会跳过较低优先级处理器和默认模型分发路径。 -- `message_sending`:返回 `{ cancel: true }` 是终止性决定。一旦任一处理器设置它,就会跳过较低优先级的处理器。 -- `message_sending`:返回 `{ cancel: false }` 会被视为没有做出决定(与省略 `cancel` 相同),而不是覆盖。 +### 事件与生命周期 + +| 方法 | 作用 | +| -------------------------------------------- | ----------------------------- | +| `api.on(hookName, handler, opts?)` | 类型化生命周期 hook | +| `api.onConversationBindingResolved(handler)` | 对话绑定回调 | + +### hook 决策语义 + +- `before_tool_call`:返回 `{ block: true }` 为终止结果。一旦任一处理器设置它,较低优先级的处理器将被跳过。 +- `before_tool_call`:返回 `{ block: false }` 会被视为未作决定(与省略 `block` 相同),而不是覆盖。 +- `before_install`:返回 `{ block: true }` 为终止结果。一旦任一处理器设置它,较低优先级的处理器将被跳过。 +- `before_install`:返回 `{ block: false }` 会被视为未作决定(与省略 `block` 相同),而不是覆盖。 +- `reply_dispatch`:返回 `{ handled: true, ... }` 为终止结果。一旦任一处理器声明已分发,较低优先级的处理器和默认模型分发路径将被跳过。 +- `message_sending`:返回 `{ cancel: true }` 为终止结果。一旦任一处理器设置它,较低优先级的处理器将被跳过。 +- `message_sending`:返回 `{ cancel: false }` 会被视为未作决定(与省略 `cancel` 相同),而不是覆盖。 ### API 对象字段 -| 字段 | 类型 | 说明 | -| ------------------------ | ------------------------- | ---------------------------------------------------------------------------------------------- | -| `api.id` | `string` | 插件 id | -| `api.name` | `string` | 显示名称 | -| `api.version` | `string?` | 插件版本(可选) | -| `api.description` | `string?` | 插件说明(可选) | -| `api.source` | `string` | 插件源路径 | -| `api.rootDir` | `string?` | 插件根目录(可选) | -| `api.config` | `OpenClawConfig` | 当前配置快照(可用时为活动中的内存运行时快照) | -| `api.pluginConfig` | `Record` | 来自 `plugins.entries..config` 的插件特定配置 | -| `api.runtime` | `PluginRuntime` | [运行时辅助函数](/zh-CN/plugins/sdk-runtime) | -| `api.logger` | `PluginLogger` | 作用域 logger(`debug`、`info`、`warn`、`error`) | -| `api.registrationMode` | `PluginRegistrationMode` | 当前加载模式;`"setup-runtime"` 是完整入口之前的轻量级启动/设置窗口 | -| `api.resolvePath(input)` | `(string) => string` | 解析相对于插件根目录的路径 | +| 字段 | 类型 | 描述 | +| ------------------------ | ------------------------- | ------------------------------------------------------------------------------------------- | +| `api.id` | `string` | 插件 ID | +| `api.name` | `string` | 显示名称 | +| `api.version` | `string?` | 插件版本(可选) | +| `api.description` | `string?` | 插件描述(可选) | +| `api.source` | `string` | 插件源路径 | +| `api.rootDir` | `string?` | 插件根目录(可选) | +| `api.config` | `OpenClawConfig` | 当前配置快照(如果可用,则为活动内存中运行时快照) | +| `api.pluginConfig` | `Record` | 来自 `plugins.entries..config` 的插件特定配置 | +| `api.runtime` | `PluginRuntime` | [插件运行时](/zh-CN/plugins/sdk-runtime) | +| `api.logger` | `PluginLogger` | 作用域 logger(`debug`, `info`, `warn`, `error`) | +| `api.registrationMode` | `PluginRegistrationMode` | 当前加载模式;`"setup-runtime"` 是完整入口启动/设置之前的轻量窗口 | +| `api.resolvePath(input)` | `(string) => string` | 解析相对于插件根目录的路径 | ## 内部模块约定 @@ -400,39 +417,42 @@ api.registerCli( ``` my-plugin/ - api.ts # 供外部使用者使用的公共导出 + api.ts # 供外部使用方使用的公共导出 runtime-api.ts # 仅供内部使用的运行时导出 index.ts # 插件入口点 setup-entry.ts # 仅设置用的轻量入口(可选) ``` - 永远不要在生产代码中通过 `openclaw/plugin-sdk/` + 不要在生产代码中通过 `openclaw/plugin-sdk/` 导入你自己的插件。内部导入应通过 `./api.ts` 或 - `./runtime-api.ts`。SDK 路径仅是外部契约。 + `./runtime-api.ts` 进行。SDK 路径仅是对外契约。 -通过外观加载的内置插件公共表面(`api.ts`、`runtime-api.ts`、`index.ts`、`setup-entry.ts` 以及类似的公共入口文件)现在会在 OpenClaw 已经运行时优先使用活动运行时配置快照。如果运行时快照尚不存在,它们会回退到磁盘上已解析的配置文件。 +通过门面加载的内置插件公共接口(`api.ts`、`runtime-api.ts`、 +`index.ts`、`setup-entry.ts` 以及类似公共入口文件)现在会在 OpenClaw 已经运行时优先使用活动运行时配置快照。如果尚不存在运行时快照,它们会回退到磁盘上的已解析配置文件。 -当某个辅助函数明确属于提供商特定、且尚不适合放入通用 SDK 子路径时,提供商插件也可以暴露一个窄范围的插件本地契约 barrel。当前的内置示例:Anthropic 提供商将其 Claude 流辅助函数保留在自己的公共 `api.ts` / `contract-api.ts` 接缝中,而不是将 Anthropic beta-header 和 `service_tier` 逻辑提升到通用 `plugin-sdk/*` 契约中。 +当某个辅助工具刻意属于提供商特定内容,且尚不适合放入通用 SDK 子路径时,提供商插件也可以暴露一个狭义的插件本地契约 barrel。当前内置示例:Anthropic 提供商将它的 Claude 流辅助工具保留在自己的公共 `api.ts` / `contract-api.ts` 接口中,而不是将 Anthropic beta-header 和 `service_tier` 逻辑提升为通用 `plugin-sdk/*` 契约。 -其他当前的内置示例: +其他当前内置示例: -- `@openclaw/openai-provider`:`api.ts` 导出提供商构建器、默认模型辅助函数和实时提供商构建器 -- `@openclaw/openrouter-provider`:`api.ts` 导出提供商构建器以及新手引导/配置辅助函数 +- `@openclaw/openai-provider`:`api.ts` 导出提供商构建器、 + 默认模型辅助工具和实时提供商构建器 +- `@openclaw/openrouter-provider`:`api.ts` 导出提供商构建器以及 + 新手引导/配置辅助工具 - 扩展生产代码同样应避免导入 `openclaw/plugin-sdk/`。 - 如果某个辅助函数确实是共享的,应将其提升到中立的 SDK 子路径, + 扩展生产代码也应避免导入 `openclaw/plugin-sdk/`。 + 如果某个辅助工具确实是共享的,请将其提升到中立的 SDK 子路径, 例如 `openclaw/plugin-sdk/speech`、`.../provider-model-shared` 或其他 - 面向能力的表面,而不是将两个插件耦合在一起。 + 面向能力的接口,而不是让两个插件彼此耦合。 ## 相关内容 - [入口点](/zh-CN/plugins/sdk-entrypoints) — `definePluginEntry` 和 `defineChannelPluginEntry` 选项 -- [运行时](/zh-CN/plugins/sdk-runtime) — 完整的 `api.runtime` 命名空间参考 -- [设置和配置](/zh-CN/plugins/sdk-setup) — 打包、manifest、配置 schema -- [测试](/zh-CN/plugins/sdk-testing) — 测试实用工具和 lint 规则 -- [SDK 迁移](/zh-CN/plugins/sdk-migration) — 从已弃用表面迁移 +- [插件运行时](/zh-CN/plugins/sdk-runtime) — 完整的 `api.runtime` 命名空间参考 +- [设置和配置](/zh-CN/plugins/sdk-setup) — 打包、清单、配置 schema +- [测试](/zh-CN/plugins/sdk-testing) — 测试工具和 lint 规则 +- [SDK 迁移](/zh-CN/plugins/sdk-migration) — 从已弃用接口迁移 - [插件内部机制](/zh-CN/plugins/architecture) — 深入的架构和能力模型 diff --git a/docs/zh-CN/plugins/sdk-provider-plugins.md b/docs/zh-CN/plugins/sdk-provider-plugins.md index 0ee86e4ec..a5f1a03b8 100644 --- a/docs/zh-CN/plugins/sdk-provider-plugins.md +++ b/docs/zh-CN/plugins/sdk-provider-plugins.md @@ -1,35 +1,37 @@ --- read_when: - 你正在构建一个新的模型提供商插件 - - 你想向 OpenClaw 添加一个兼容 OpenAI 的代理或自定义 LLM - - 你需要理解提供商凭证、目录和运行时 hooks + - 你想为 OpenClaw 添加一个兼容 OpenAI 的代理或自定义 LLM + - 你需要了解提供商认证、目录和运行时 hooks sidebarTitle: Provider Plugins -summary: 构建 OpenClaw 模型提供商插件的分步指南 +summary: 在 OpenClaw 中构建模型提供商插件的分步指南 title: 构建提供商插件 x-i18n: - generated_at: "2026-04-06T12:28:45Z" + generated_at: "2026-04-06T12:45:00Z" model: gpt-5.4 provider: openai - source_hash: 21c888a988f6128f2c77b73ee4962ae7ad7b8a6c1b7d302610788c81ad25b0db + source_hash: 89e7402742c87cb31265db1d98b34ca17ba57ad1c61952fa8c7da834306986f5 source_path: plugins/sdk-provider-plugins.md workflow: 15 --- # 构建提供商插件 -本指南将带你逐步构建一个提供商插件,为 OpenClaw 添加一个模型提供商 -(LLM)。完成后,你将拥有一个带有模型目录、API 密钥凭证和动态模型解析的提供商。 +本指南将带你构建一个提供商插件,为 OpenClaw 添加一个模型提供商 +(LLM)。完成后,你将拥有一个具备模型目录、 +API 密钥认证和动态模型解析能力的提供商。 如果你之前从未构建过任何 OpenClaw 插件,请先阅读 - [入门指南](/zh-CN/plugins/building-plugins),了解基础的软件包结构和清单设置。 + [入门指南](/zh-CN/plugins/building-plugins) 了解基本包 + 结构和清单设置。 -## 演练 +## 操作演练 - + ```json package.json { @@ -55,7 +57,7 @@ x-i18n: { "id": "acme-ai", "name": "Acme AI", - "description": "Acme AI 模型提供商", + "description": "Acme AI model provider", "providers": ["acme-ai"], "modelSupport": { "modelPrefixes": ["acme-"] @@ -68,12 +70,12 @@ x-i18n: "provider": "acme-ai", "method": "api-key", "choiceId": "acme-ai-api-key", - "choiceLabel": "Acme AI API 密钥", + "choiceLabel": "Acme AI API key", "groupId": "acme-ai", "groupLabel": "Acme AI", "cliFlag": "--acme-ai-api-key", "cliOption": "--acme-ai-api-key ", - "cliDescription": "Acme AI API 密钥" + "cliDescription": "Acme AI API key" } ], "configSchema": { @@ -84,10 +86,12 @@ x-i18n: ``` - 清单会声明 `providerAuthEnvVars`,这样 OpenClaw 就能在不加载你的插件运行时的情况下检测 - 凭证。`modelSupport` 是可选的,它允许 OpenClaw 根据简写模型 id - (例如 `acme-large`)自动加载你的提供商插件,此时甚至还没有运行时 hooks。如果你在 - ClawHub 上发布该提供商,那么 `package.json` 中的这些 `openclaw.compat` 和 `openclaw.build` 字段 + 清单声明了 `providerAuthEnvVars`,这样 OpenClaw 就可以在不加载你的插件运行时的情况下检测 + 凭证。`modelSupport` 是可选的, + 它让 OpenClaw 能够在运行时 hooks 存在之前,从像 + `acme-large` 这样的简写模型 id 自动加载你的提供商插件。如果你在 + ClawHub 上发布该提供商,那么 `package.json` 中的 + `openclaw.compat` 和 `openclaw.build` 字段 是必需的。 @@ -102,7 +106,7 @@ x-i18n: export default definePluginEntry({ id: "acme-ai", name: "Acme AI", - description: "Acme AI 模型提供商", + description: "Acme AI model provider", register(api) { api.registerProvider({ id: "acme-ai", @@ -114,12 +118,12 @@ x-i18n: createProviderApiKeyAuthMethod({ providerId: "acme-ai", methodId: "api-key", - label: "Acme AI API 密钥", - hint: "来自你的 Acme AI 控制台的 API 密钥", + label: "Acme AI API key", + hint: "API key from your Acme AI dashboard", optionKey: "acmeAiApiKey", flagName: "--acme-ai-api-key", envVar: "ACME_AI_API_KEY", - promptMessage: "输入你的 Acme AI API 密钥", + promptMessage: "Enter your Acme AI API key", defaultModel: "acme-ai/acme-large", }), ], @@ -164,13 +168,13 @@ x-i18n: }); ``` - 这就是一个可工作的提供商。现在用户可以运行 - `openclaw onboard --acme-ai-api-key `,并选择 + 这样就是一个可工作的提供商。用户现在可以 + `openclaw onboard --acme-ai-api-key ` 并选择 `acme-ai/acme-large` 作为他们的模型。 - 对于仅注册一个文本提供商、使用 API 密钥凭证,并且只有一个基于目录的运行时的内置提供商, - 优先使用更窄的 - `defineSingleProviderPluginEntry(...)` 辅助函数: + 对于只注册一个文本提供商、使用 API 密钥 + 认证且只有单个基于目录的运行时的内置提供商,优先使用更窄的 + `defineSingleProviderPluginEntry(...)` 帮助器: ```typescript import { defineSingleProviderPluginEntry } from "openclaw/plugin-sdk/provider-entry"; @@ -178,19 +182,19 @@ x-i18n: export default defineSingleProviderPluginEntry({ id: "acme-ai", name: "Acme AI", - description: "Acme AI 模型提供商", + description: "Acme AI model provider", provider: { label: "Acme AI", docsPath: "/providers/acme-ai", auth: [ { methodId: "api-key", - label: "Acme AI API 密钥", - hint: "来自你的 Acme AI 控制台的 API 密钥", + label: "Acme AI API key", + hint: "API key from your Acme AI dashboard", optionKey: "acmeAiApiKey", flagName: "--acme-ai-api-key", envVar: "ACME_AI_API_KEY", - promptMessage: "输入你的 Acme AI API 密钥", + promptMessage: "Enter your Acme AI API key", defaultModel: "acme-ai/acme-large", }, ], @@ -205,20 +209,18 @@ x-i18n: }); ``` - 如果你的凭证流程在新手引导期间还需要修补 `models.providers.*`、别名以及 - 智能体默认模型,请使用来自 - `openclaw/plugin-sdk/provider-onboard` 的预设辅助函数。最窄的辅助函数是 + 如果你的认证流程在新手引导期间还需要修补 `models.providers.*`、别名以及 + 智能体默认模型,请使用 + `openclaw/plugin-sdk/provider-onboard` 中的 preset 帮助器。最窄的帮助器是 `createDefaultModelPresetAppliers(...)`、 `createDefaultModelsPresetAppliers(...)` 和 `createModelCatalogPresetAppliers(...)`。 - 当某个提供商的原生端点在常规 `openai-completions` 传输协议上支持流式使用量块时, - 优先使用 `openclaw/plugin-sdk/provider-catalog-shared` 中的共享目录辅助函数, - 而不是硬编码提供商 id 检查。 - `supportsNativeStreamingUsageCompat(...)` 和 - `applyProviderNativeStreamingUsageCompat(...)` 会根据端点能力映射检测支持情况, - 因此像原生 Moonshot/DashScope 这类风格的端点,即使插件使用的是自定义提供商 id, - 也仍然可以选择启用。 + 当某个提供商的原生端点在普通 + `openai-completions` 传输上支持分块流式传输 usage blocks 时,优先使用 + `openclaw/plugin-sdk/provider-catalog-shared` 中的共享目录帮助器,而不是硬编码 + provider-id 检查。`supportsNativeStreamingUsageCompat(...)` 和 + `applyProviderNativeStreamingUsageCompat(...)` 会从端点 capability 映射中检测支持情况,因此即使插件使用自定义 provider id,原生 Moonshot/DashScope 风格的端点仍可选择启用。 @@ -228,7 +230,7 @@ x-i18n: ```typescript api.registerProvider({ - // ... 来自上面的 id、label、auth、catalog + // ... id, label, auth, catalog from above resolveDynamicModel: (ctx) => ({ id: ctx.modelId, @@ -245,8 +247,8 @@ x-i18n: }); ``` - 如果解析过程需要网络调用,请使用 `prepareDynamicModel` 进行异步 - 预热——在其完成后,`resolveDynamicModel` 会再次运行。 + 如果解析需要网络调用,请使用 `prepareDynamicModel` 进行异步 + 预热 —— 完成后会再次运行 `resolveDynamicModel`。 @@ -254,8 +256,8 @@ x-i18n: 大多数提供商只需要 `catalog` + `resolveDynamicModel`。随着你的提供商需求增加, 再逐步添加 hooks。 - 共享辅助构建器现在已覆盖最常见的回放/工具兼容性 - 系列,因此插件通常不需要再手动逐一接线每个 hook: + 共享帮助器构建器现在已经覆盖最常见的 replay/tool-compat + 系列,因此插件通常不需要手动逐个接线每个 hook: ```typescript import { buildProviderReplayFamilyHooks } from "openclaw/plugin-sdk/provider-model-shared"; @@ -275,39 +277,39 @@ x-i18n: }); ``` - 当前可用的回放系列: + 当前可用的 replay families: - | 系列 | 它会接入的内容 | + | Family | 它会接入什么 | | --- | --- | - | `openai-compatible` | 用于兼容 OpenAI 的传输协议的共享 OpenAI 风格回放策略,包括 tool-call-id 清理、assistant-first 顺序修复,以及在传输协议需要时进行通用 Gemini 轮次校验 | - | `anthropic-by-model` | 按 `modelId` 选择的 Claude 感知回放策略,因此 Anthropic message 传输协议只有在解析出的模型确实是 Claude id 时,才会获得 Claude 专用的 thinking block 清理 | - | `google-gemini` | 原生 Gemini 回放策略,以及 bootstrap 回放清理和带标记的 reasoning-output 模式 | - | `passthrough-gemini` | 用于通过兼容 OpenAI 的代理传输协议运行的 Gemini 模型的 Gemini thought-signature 清理;不会启用原生 Gemini 回放校验或 bootstrap 重写 | - | `hybrid-anthropic-openai` | 用于在一个插件中混合 Anthropic message 和兼容 OpenAI 模型面的提供商的混合策略;可选的仅 Claude thinking block 丢弃仍限制在 Anthropic 一侧 | + | `openai-compatible` | 面向 OpenAI 兼容传输的共享 OpenAI 风格 replay 策略,包括 tool-call-id 清理、assistant-first 顺序修复,以及在传输需要时启用通用 Gemini turn 验证 | + | `anthropic-by-model` | 按 `modelId` 选择的 Claude 感知 replay 策略,因此 Anthropic-message 传输仅在解析后的模型实际是 Claude id 时才会获得 Claude 特定的 thinking-block 清理 | + | `google-gemini` | 原生 Gemini replay 策略,加上 bootstrap replay 清理和带标签的 reasoning-output 模式 | + | `passthrough-gemini` | 针对通过 OpenAI 兼容代理传输运行的 Gemini 模型的 Gemini thought-signature 清理;不会启用原生 Gemini replay 验证或 bootstrap 重写 | + | `hybrid-anthropic-openai` | 适用于在一个插件中混合 Anthropic-message 和 OpenAI 兼容模型面的提供商的混合策略;可选的仅 Claude thinking-block 丢弃仍然限定在 Anthropic 一侧 | 真实的内置示例: - - `google`:`google-gemini` + - `google` 和 `google-gemini-cli`:`google-gemini` - `openrouter`、`kilocode`、`opencode` 和 `opencode-go`:`passthrough-gemini` - `amazon-bedrock` 和 `anthropic-vertex`:`anthropic-by-model` - `minimax`:`hybrid-anthropic-openai` - `moonshot`、`ollama`、`xai` 和 `zai`:`openai-compatible` - 当前可用的流式系列: + 当前可用的 stream families: - | 系列 | 它会接入的内容 | + | Family | 它会接入什么 | | --- | --- | - | `google-thinking` | 在共享流路径上进行 Gemini thinking 负载标准化 | - | `kilocode-thinking` | 在共享代理流路径上提供 Kilo reasoning 包装器,其中 `kilo/auto` 和不支持的代理 reasoning id 会跳过注入的 thinking | - | `moonshot-thinking` | 根据配置和 `/think` 级别,将 Moonshot 二进制 native-thinking 负载进行映射 | - | `minimax-fast-mode` | 在共享流路径上进行 MiniMax fast-mode 模型重写 | - | `openai-responses-defaults` | 共享的原生 OpenAI/Codex Responses 包装器:归属头、`/fast`/`serviceTier`、文本冗长度、原生 Codex web 搜索、reasoning 兼容性负载整形,以及 Responses 上下文管理 | - | `openrouter-thinking` | 用于代理路由的 OpenRouter reasoning 包装器,集中处理不支持模型和 `auto` 跳过 | - | `tool-stream-default-on` | 为像 Z.AI 这样希望默认启用工具流式传输、除非显式禁用的提供商提供默认开启的 `tool_stream` 包装器 | + | `google-thinking` | 共享流路径上的 Gemini thinking 负载规范化 | + | `kilocode-thinking` | 共享代理流路径上的 Kilo reasoning 包装器,其中 `kilo/auto` 和不受支持的代理 reasoning id 会跳过注入的 thinking | + | `moonshot-thinking` | 根据配置 + `/think` 级别进行 Moonshot 二进制原生 thinking 负载映射 | + | `minimax-fast-mode` | 共享流路径上的 MiniMax fast-mode 模型重写 | + | `openai-responses-defaults` | 共享的原生 OpenAI/Codex Responses 包装器:归因头、`/fast`/`serviceTier`、文本详细程度、原生 Codex web search、reasoning-compat 负载整形,以及 Responses 上下文管理 | + | `openrouter-thinking` | 面向代理路由的 OpenRouter reasoning 包装器,并由中心统一处理不支持的模型/`auto` 跳过 | + | `tool-stream-default-on` | 对于像 Z.AI 这类希望默认启用工具流式传输的提供商,在未显式禁用时默认开启 `tool_stream` 的包装器 | 真实的内置示例: - - `google`:`google-thinking` + - `google` 和 `google-gemini-cli`:`google-thinking` - `kilocode`:`kilocode-thinking` - `moonshot`:`moonshot-thinking` - `minimax` 和 `minimax-portal`:`minimax-fast-mode` @@ -316,22 +318,22 @@ x-i18n: - `zai`:`tool-stream-default-on` `openclaw/plugin-sdk/provider-model-shared` 还会导出 replay-family - 枚举以及这些系列所基于的共享辅助函数。常见的公共导出包括: + 枚举,以及这些 family 所构建于其上的共享帮助器。常见公开导出包括: - `ProviderReplayFamily` - `buildProviderReplayFamilyHooks(...)` - - 共享回放构建器,例如 `buildOpenAICompatibleReplayPolicy(...)`、 + - 共享 replay 构建器,例如 `buildOpenAICompatibleReplayPolicy(...)`、 `buildAnthropicReplayPolicyForModel(...)`、 `buildGoogleGeminiReplayPolicy(...)` 和 `buildHybridAnthropicOrOpenAIReplayPolicy(...)` - - Gemini 回放辅助函数,例如 `sanitizeGoogleGeminiReplayHistory(...)` + - Gemini replay 帮助器,例如 `sanitizeGoogleGeminiReplayHistory(...)` 和 `resolveTaggedReasoningOutputMode()` - - 端点/模型辅助函数,例如 `resolveProviderEndpoint(...)`、 + - 端点/模型帮助器,例如 `resolveProviderEndpoint(...)`、 `normalizeProviderId(...)`、`normalizeGooglePreviewModelId(...)` 和 `normalizeNativeXaiModelId(...)` - `openclaw/plugin-sdk/provider-stream` 同时公开 family 构建器以及这些 family 复用的公共包装辅助函数。 - 常见的公共导出包括: + `openclaw/plugin-sdk/provider-stream` 同时公开 family 构建器以及这些 family 复用的公共包装器帮助器。常见公开导出 + 包括: - `ProviderStreamFamily` - `buildProviderStreamFamilyHooks(...)` @@ -345,46 +347,46 @@ x-i18n: - 共享代理/提供商包装器,例如 `createOpenRouterWrapper(...)`、 `createToolStreamWrapper(...)` 和 `createMinimaxFastModeWrapper(...)` - 某些流式辅助函数有意保持为提供商本地。当前内置 - 示例:`@openclaw/anthropic-provider` 导出 + 一些 stream 帮助器会有意保持为 provider-local。当前内置 + 示例:`@openclaw/anthropic-provider` 从其公共 `api.ts` / + `contract-api.ts` 接缝导出 `wrapAnthropicProviderStream`、`resolveAnthropicBetas`、 - `resolveAnthropicFastMode`、`resolveAnthropicServiceTier`,以及来自其公共 `api.ts` / - `contract-api.ts` 接缝的更底层 Anthropic 包装器构建器。之所以这些辅助函数仍然保持为 Anthropic 专用, - 是因为它们还编码了 Claude OAuth beta 处理和 `context1m` 门控。 + `resolveAnthropicFastMode`、`resolveAnthropicServiceTier`,以及更底层的 Anthropic 包装器构建器。 + 这些帮助器仍保持 Anthropic 特定,因为 + 它们还编码了 Claude OAuth beta 处理和 `context1m` gating。 - 其他内置提供商也会在行为无法在 family 之间干净共享时,将传输协议专用包装器保留在本地。 - 当前示例:内置 xAI 插件将原生 xAI Responses 整形保留在它自己的 + 其他内置提供商也会在行为无法跨 family 清晰共享时,将 + transport-specific 包装器保留在本地。当前示例:内置 xAI 插件将原生 xAI Responses 整形保留在其自己的 `wrapStreamFn` 中,包括 `/fast` 别名重写、默认 `tool_stream`、 - 对不受支持 strict-tool 的清理,以及移除 xAI 专用的 reasoning 负载。 + 不支持的 strict-tool 清理,以及 xAI 特有的 reasoning-payload + 移除。 - `openclaw/plugin-sdk/provider-tools` 当前公开一个共享的 - 工具 schema 系列,以及共享的 schema/兼容性辅助函数: + `openclaw/plugin-sdk/provider-tools` 当前公开一个共享 + tool-schema family 以及共享 schema/compat 帮助器: - `ProviderToolCompatFamily` 记录了当前共享 family 清单。 - - `buildProviderToolCompatFamilyHooks("gemini")` 为需要 Gemini 安全工具 schema 的提供商接入 Gemini schema + - `buildProviderToolCompatFamilyHooks("gemini")` 会为需要 Gemini 安全工具 schema 的提供商接入 Gemini schema 清理 + 诊断。 - `normalizeGeminiToolSchemas(...)` 和 `inspectGeminiToolSchemas(...)` - 是底层的公共 Gemini schema 辅助函数。 - - `resolveXaiModelCompatPatch()` 返回内置的 xAI compat patch: + 是底层的公共 Gemini schema 帮助器。 + - `resolveXaiModelCompatPatch()` 返回内置 xAI compat patch: `toolSchemaProfile: "xai"`、不支持的 schema 关键字、原生 - `web_search` 支持,以及 HTML 实体形式 tool-call 参数的解码。 - - `applyXaiModelCompat(model)` 会在解析后的模型到达运行器之前, - 对其应用同样的 xAI compat patch。 + `web_search` 支持,以及 HTML 实体 tool-call 参数解码。 + - `applyXaiModelCompat(model)` 会在解析后的模型进入 runner 之前,对其应用同样的 xAI compat patch。 真实的内置示例:xAI 插件使用 `normalizeResolvedModel` 加上 - `contributeResolvedModelCompat`,使兼容性元数据由提供商自己持有, - 而不是在核心中硬编码 xAI 规则。 + `contributeResolvedModelCompat`,使 compat 元数据归提供商所有,而不是在 core 中硬编码 xAI 规则。 - 其他内置提供商也采用相同的软件包根模式: + 同样的 package-root 模式也支持其他内置提供商: - `@openclaw/openai-provider`:`api.ts` 导出提供商构建器、 - 默认模型辅助函数和 realtime 提供商构建器 + 默认模型帮助器和实时提供商构建器 - `@openclaw/openrouter-provider`:`api.ts` 导出提供商构建器 - 以及新手引导/配置辅助函数 + 以及 onboarding/配置帮助器 - 对于那些在每次推理调用之前都需要进行令牌交换的提供商: + 对于需要在每次推理调用前执行令牌交换的提供商: ```typescript prepareRuntimeAuth: async (ctx) => { @@ -398,10 +400,10 @@ x-i18n: ``` - 对于那些需要自定义请求头或请求体修改的提供商: + 对于需要自定义请求头或请求体修改的提供商: ```typescript - // wrapStreamFn 返回一个从 ctx.streamFn 派生的 StreamFn + // wrapStreamFn returns a StreamFn derived from ctx.streamFn wrapStreamFn: (ctx) => { if (!ctx.streamFn) return undefined; const inner = ctx.streamFn; @@ -415,8 +417,8 @@ x-i18n: }, ``` - - 对于那些在通用 HTTP 或 WebSocket 传输协议上需要原生请求/会话头或元数据的提供商: + + 对于在通用 HTTP 或 WebSocket 传输上需要原生请求/会话头或元数据的提供商: ```typescript resolveTransportTurnState: (ctx) => ({ @@ -436,8 +438,8 @@ x-i18n: }), ``` - - 对于那些公开用量/计费数据的提供商: + + 对于暴露 usage/计费数据的提供商: ```typescript resolveUsageAuth: async (ctx) => { @@ -452,83 +454,84 @@ x-i18n: - OpenClaw 会按照以下顺序调用 hooks。大多数提供商只会使用 2-3 个: + OpenClaw 会按以下顺序调用 hooks。大多数提供商只会使用 2-3 个: - | # | Hook | 适用场景 | + | # | Hook | 何时使用 | | --- | --- | --- | | 1 | `catalog` | 模型目录或默认 `baseUrl` | - | 2 | `applyConfigDefaults` | 在配置具体化期间应用由提供商持有的全局默认值 | - | 3 | `normalizeModelId` | 在查找前清理旧版/预览版模型 id 别名 | - | 4 | `normalizeTransport` | 在通用模型组装前清理 provider-family `api` / `baseUrl` | - | 5 | `normalizeConfig` | 标准化 `models.providers.` 配置 | - | 6 | `applyNativeStreamingUsageCompat` | 对配置提供商应用原生流式使用量兼容性重写 | - | 7 | `resolveConfigApiKey` | 由提供商持有的环境标记凭证解析 | - | 8 | `resolveSyntheticAuth` | 本地/自托管或基于配置的合成凭证 | - | 9 | `shouldDeferSyntheticProfileAuth` | 将合成的已存配置档占位符置于环境变量/配置凭证之后 | + | 2 | `applyConfigDefaults` | 配置物化期间由提供商拥有的全局默认值 | + | 3 | `normalizeModelId` | 查找前对旧版/预览模型 id 别名进行清理 | + | 4 | `normalizeTransport` | 通用模型组装前,对 provider-family 的 `api` / `baseUrl` 进行清理 | + | 5 | `normalizeConfig` | 规范化 `models.providers.` 配置 | + | 6 | `applyNativeStreamingUsageCompat` | 对配置提供商执行原生流式 usage compat 重写 | + | 7 | `resolveConfigApiKey` | 由提供商拥有的环境标记认证解析 | + | 8 | `resolveSyntheticAuth` | 本地/自托管或基于配置的 synthetic auth | + | 9 | `shouldDeferSyntheticProfileAuth` | 将 synthetic 存储配置文件占位符降级到 env/config auth 之后 | | 10 | `resolveDynamicModel` | 接受任意上游模型 ID | - | 11 | `prepareDynamicModel` | 解析前进行异步元数据获取 | - | 12 | `normalizeResolvedModel` | 运行器之前的传输协议重写 | + | 11 | `prepareDynamicModel` | 解析前异步获取元数据 | + | 12 | `normalizeResolvedModel` | runner 之前的传输重写 | 运行时回退说明: - - `normalizeConfig` 会先检查匹配的提供商,然后再检查其他 - 具备 hook 能力的提供商插件,直到某个插件确实改写了配置。 - 如果没有任何提供商 hook 重写受支持的 Google family 配置项, - 内置的 Google 配置标准化器仍会生效。 - - `resolveConfigApiKey` 在公开该 hook 时会使用提供商 hook。内置的 - `amazon-bedrock` 路径在这里还带有一个内建的 AWS 环境标记解析器, - 即使 Bedrock 运行时凭证本身仍然使用 AWS SDK 默认 + - `normalizeConfig` 会先检查匹配的提供商,然后检查其他 + 具备 hook 能力的提供商插件,直到其中某个插件实际更改配置。 + 如果没有任何提供商 hook 重写受支持的 Google-family 配置条目, + 内置 Google 配置规范化仍会应用。 + - `resolveConfigApiKey` 会在公开时使用提供商 hook。内置 + `amazon-bedrock` 路径在这里也有内建的 AWS 环境标记解析器, + 尽管 Bedrock 运行时认证本身仍使用 AWS SDK 默认 链。 - | 13 | `contributeResolvedModelCompat` | 为运行在另一个兼容传输协议之后的供应商模型提供兼容性标志 | - | 14 | `capabilities` | 旧版静态能力包;仅为兼容性保留 | - | 15 | `normalizeToolSchemas` | 在注册前由提供商持有的工具 schema 清理 | - | 16 | `inspectToolSchemas` | 由提供商持有的工具 schema 诊断 | - | 17 | `resolveReasoningOutputMode` | 标记型还是原生 reasoning-output 契约 | + | 13 | `contributeResolvedModelCompat` | 为另一个兼容传输背后的厂商模型提供 compat 标志 | + | 14 | `capabilities` | 旧版静态 capability 包;仅为兼容性保留 | + | 15 | `normalizeToolSchemas` | 注册前由提供商拥有的工具 schema 清理 | + | 16 | `inspectToolSchemas` | 由提供商拥有的工具 schema 诊断 | + | 17 | `resolveReasoningOutputMode` | 带标签与原生 reasoning-output 契约 | | 18 | `prepareExtraParams` | 默认请求参数 | - | 19 | `createStreamFn` | 完全自定义的 StreamFn 传输协议 | - | 20 | `wrapStreamFn` | 常规流路径上的自定义头/请求体包装器 | + | 19 | `createStreamFn` | 完全自定义的 `StreamFn` 传输 | + | 20 | `wrapStreamFn` | 普通流路径上的自定义头/请求体包装器 | | 21 | `resolveTransportTurnState` | 原生逐轮请求头/元数据 | - | 22 | `resolveWebSocketSessionPolicy` | 原生 WS 会话头/冷却 | + | 22 | `resolveWebSocketSessionPolicy` | 原生 WS 会话头/冷却时间 | | 23 | `formatApiKey` | 自定义运行时令牌形态 | | 24 | `refreshOAuth` | 自定义 OAuth 刷新 | - | 25 | `buildAuthDoctorHint` | 凭证修复指引 | - | 26 | `matchesContextOverflowError` | 由提供商持有的上下文溢出检测 | - | 27 | `classifyFailoverReason` | 由提供商持有的限流/过载分类 | - | 28 | `isCacheTtlEligible` | prompt cache TTL 门控 | - | 29 | `buildMissingAuthMessage` | 自定义缺失凭证提示 | - | 30 | `suppressBuiltInModel` | 隐藏过时的上游条目 | - | 31 | `augmentModelCatalog` | 合成的前向兼容条目 | + | 25 | `buildAuthDoctorHint` | 认证修复指导 | + | 26 | `matchesContextOverflowError` | 由提供商拥有的溢出检测 | + | 27 | `classifyFailoverReason` | 由提供商拥有的限流/过载分类 | + | 28 | `isCacheTtlEligible` | 提示缓存 TTL 门控 | + | 29 | `buildMissingAuthMessage` | 自定义缺失认证提示 | + | 30 | `suppressBuiltInModel` | 隐藏过时的上游行 | + | 31 | `augmentModelCatalog` | synthetic 前向兼容行 | | 32 | `isBinaryThinking` | 二进制 thinking 开/关 | | 33 | `supportsXHighThinking` | `xhigh` reasoning 支持 | | 34 | `resolveDefaultThinkingLevel` | 默认 `/think` 策略 | - | 35 | `isModernModelRef` | live/smoke 模型匹配 | - | 36 | `prepareRuntimeAuth` | 推理前的令牌交换 | - | 37 | `resolveUsageAuth` | 自定义用量凭证解析 | - | 38 | `fetchUsageSnapshot` | 自定义用量端点 | - | 39 | `createEmbeddingProvider` | 用于记忆/搜索的、由提供商持有的嵌入适配器 | - | 40 | `buildReplayPolicy` | 自定义转录回放/压缩策略 | - | 41 | `sanitizeReplayHistory` | 通用清理之后的提供商专用回放重写 | - | 42 | `validateReplayTurns` | 在嵌入式运行器之前进行严格的回放轮次校验 | - | 43 | `onModelSelected` | 选择模型后的回调(例如遥测) | + | 35 | `isModernModelRef` | 实时/smoke 模型匹配 | + | 36 | `prepareRuntimeAuth` | 推理前令牌交换 | + | 37 | `resolveUsageAuth` | 自定义 usage 凭证解析 | + | 38 | `fetchUsageSnapshot` | 自定义 usage 端点 | + | 39 | `createEmbeddingProvider` | 用于内存/搜索的由提供商拥有的嵌入适配器 | + | 40 | `buildReplayPolicy` | 自定义转录 replay/压缩策略 | + | 41 | `sanitizeReplayHistory` | 通用清理之后的 provider-specific replay 重写 | + | 42 | `validateReplayTurns` | 嵌入 runner 之前的严格 replay-turn 验证 | + | 43 | `onModelSelected` | 选择后的回调(例如遥测) | - Prompt 调优说明: + 提示词调优说明: - - `resolveSystemPromptContribution` 允许提供商为某个模型 family 注入具备缓存感知能力的 - system prompt 指引。当某个行为属于单个提供商/模型 family, - 并且应该保留稳定/动态缓存拆分时,优先使用它,而不是 + - `resolveSystemPromptContribution` 允许提供商为某个模型 family 注入缓存感知的 + system-prompt 指导。对于属于某个提供商/模型 + family 且应保留稳定/动态缓存拆分的行为, + 优先使用它,而不是 `before_prompt_build`。 - 有关详细说明和真实示例,请参见 - [内部机制:提供商运行时 Hooks](/zh-CN/plugins/architecture#provider-runtime-hooks)。 + 关于详细说明和真实示例,请参见 + [内部机制:提供商运行时 hooks](/zh-CN/plugins/architecture#provider-runtime-hooks)。 - 提供商插件除了文本推理外,还可以注册语音、实时转录、实时语音、 - 媒体理解、图像生成、视频生成、web 抓取 - 和 web 搜索: + 提供商插件除了文本推理之外,还可以注册语音、实时转录、实时 + 语音、媒体理解、图像生成、视频生成、网页抓取 + 和网页搜索: ```typescript register(api) { @@ -611,7 +614,7 @@ x-i18n: api.registerWebFetchProvider({ id: "acme-ai-fetch", label: "Acme Fetch", - hint: "通过 Acme 的渲染后端抓取页面。", + hint: "Fetch pages through Acme's rendering backend.", envVars: ["ACME_FETCH_API_KEY"], placeholder: "acme-...", signupUrl: "https://acme.example.com/fetch", @@ -622,7 +625,7 @@ x-i18n: acme.apiKey = value; }, createTool: () => ({ - description: "通过 Acme Fetch 抓取页面。", + description: "Fetch a page through Acme Fetch.", parameters: {}, execute: async (args) => ({ content: [] }), }), @@ -636,15 +639,15 @@ x-i18n: } ``` - OpenClaw 会将其归类为 **hybrid-capability** 插件。这是 - 公司插件(每个厂商一个插件)的推荐模式。请参见 + OpenClaw 会将其归类为**混合能力**插件。这是 + 公司级插件(每个厂商一个插件)的推荐模式。参见 [内部机制:能力归属](/zh-CN/plugins/architecture#capability-ownership-model)。 - 对于视频生成,优先使用上面展示的具备模式感知能力的能力结构: - `generate`、`imageToVideo` 和 `videoToVideo`。较旧的扁平字段, - 如 `maxInputImages`、`maxInputVideos` 和 `maxDurationSeconds` - 仍然可作为汇总回退上限使用,但它们无法同样清晰地描述按模式区分的限制 - 或已禁用的转换模式。 + 对于视频生成,优先使用上面展示的感知模式 capability 结构: + `generate`、`imageToVideo` 和 `videoToVideo`。较旧的扁平字段,如 + `maxInputImages`、`maxInputVideos` 和 `maxDurationSeconds` 仍可作为聚合回退上限使用, + 但它们无法同样清晰地描述每种模式的限制或 + 被禁用的转换模式。 @@ -652,7 +655,7 @@ x-i18n: ```typescript src/provider.test.ts import { describe, it, expect } from "vitest"; - // 从 index.ts 或单独文件中导出你的 provider 配置对象 + // Export your provider config object from index.ts or a dedicated file import { acmeProvider } from "./provider.js"; describe("acme-ai provider", () => { @@ -692,7 +695,7 @@ clawhub package publish your-org/your-plugin --dry-run clawhub package publish your-org/your-plugin ``` -这里不要使用旧版仅供 Skills 使用的发布别名;插件包应使用 +这里不要使用旧版仅 Skills 的发布别名;插件包应使用 `clawhub package publish`。 ## 文件结构 @@ -704,24 +707,24 @@ clawhub package publish your-org/your-plugin ├── index.ts # definePluginEntry + registerProvider └── src/ ├── provider.test.ts # 测试 - └── usage.ts # 用量端点(可选) + └── usage.ts # Usage 端点(可选) ``` ## 目录顺序参考 -`catalog.order` 用于控制你的目录相对于内置 -提供商的合并时机: +`catalog.order` 控制你的目录相对于内置 +提供商何时合并: -| 顺序 | 时机 | 用例 | +| Order | 时机 | 使用场景 | | --------- | ------------- | ----------------------------------------------- | -| `simple` | 第一轮 | 普通 API 密钥提供商 | -| `profile` | 在 simple 之后 | 受凭证配置档控制的提供商 | +| `simple` | 第一轮 | 纯 API 密钥提供商 | +| `profile` | 在 simple 之后 | 受 auth profiles 控制的提供商 | | `paired` | 在 profile 之后 | 合成多个相关条目 | -| `late` | 最后一轮 | 覆盖现有提供商(冲突时获胜) | +| `late` | 最后一轮 | 覆盖现有提供商(冲突时胜出) | ## 后续步骤 - [渠道插件](/zh-CN/plugins/sdk-channel-plugins) — 如果你的插件还提供一个渠道 -- [SDK 运行时](/zh-CN/plugins/sdk-runtime) — `api.runtime` 辅助函数(TTS、搜索、subagent) -- [SDK 概览](/zh-CN/plugins/sdk-overview) — 完整的子路径导入参考 +- [插件运行时](/zh-CN/plugins/sdk-runtime) — `api.runtime` 帮助器(TTS、搜索、subagent) +- [SDK 概览](/zh-CN/plugins/sdk-overview) — 完整子路径导入参考 - [插件内部机制](/zh-CN/plugins/architecture#provider-runtime-hooks) — hook 细节和内置示例 diff --git a/docs/zh-CN/providers/anthropic.md b/docs/zh-CN/providers/anthropic.md index f5cff2056..3b13378ef 100644 --- a/docs/zh-CN/providers/anthropic.md +++ b/docs/zh-CN/providers/anthropic.md @@ -1,13 +1,13 @@ --- read_when: - 你想在 OpenClaw 中使用 Anthropic 模型 -summary: 在 OpenClaw 中通过 API key 使用 Anthropic Claude +summary: 在 OpenClaw 中通过 API 密钥使用 Anthropic Claude title: Anthropic x-i18n: - generated_at: "2026-04-05T18:14:50Z" + generated_at: "2026-04-06T12:44:41Z" model: gpt-5.4 provider: openai - source_hash: bbc6c4938674aedf20ff944bc04e742c9a7e77a5ff10ae4f95b5718504c57c2d + source_hash: 6af35571debf5889b63e3b4f6a05aa4e046f39740287e6e1c492916ca00df44b source_path: providers/anthropic.md workflow: 15 --- @@ -15,29 +15,30 @@ x-i18n: # Anthropic(Claude) Anthropic 构建了 **Claude** 模型家族,并通过 API 提供访问。 -在 OpenClaw 中,新的 Anthropic 设置应使用 API key。现有的旧版 -Anthropic token 配置文件如果已经配置,运行时仍会继续支持。 +在 OpenClaw 中,新的 Anthropic 设置应使用 API 密钥。现有的旧版 +Anthropic token 配置文件如果已经完成配置,运行时仍会继续支持。 -在 OpenClaw 中使用 Anthropic 时,计费方式分为: +对于 OpenClaw 中的 Anthropic,计费拆分如下: -- **Anthropic API key**:标准 Anthropic API 计费。 -- **OpenClaw 内的 Claude 订阅认证**:Anthropic 于 - **2026 年 4 月 4 日太平洋时间中午 12:00 / 英国夏令时间晚上 8:00** - 告知 OpenClaw 用户,这属于第三方 harness 使用,因此需要 **Extra Usage**(按量付费, +- **Anthropic API 密钥**:标准 Anthropic API 计费。 +- **OpenClaw 内的 Claude 订阅凭证**:Anthropic 于 + **2026 年 4 月 4 日 PT 时间中午 12:00 / BST 时间晚上 8:00** + 告知 OpenClaw 用户,这会被视为 + 第三方 harness 使用,并需要 **Extra Usage**(按量计费, 与订阅分开计费)。 -我们的本地复现结果也符合这一划分: +我们的本地复现结果也符合这一拆分: -- 直接使用 `claude -p` 可能仍然可用 -- `claude -p --append-system-prompt ...` 在提示词表明 OpenClaw - 身份时,可能会触发 Extra Usage 限制 -- 相同的类 OpenClaw 系统提示词,在 Anthropic SDK + `ANTHROPIC_API_KEY` - 路径上**不会**复现该拦截 +- 直接执行 `claude -p` 可能仍然可用 +- `claude -p --append-system-prompt ...` 在提示词标识出 OpenClaw 时, + 可能触发 Extra Usage 保护 +- 在 Anthropic SDK + `ANTHROPIC_API_KEY` 路径上,相同的类 OpenClaw + 系统提示词**不会**复现该拦截 -所以实际规则是:**Anthropic API key,或启用了 -Extra Usage 的 Claude 订阅**。如果你想采用最明确的生产环境方案,请使用 Anthropic API -key。 +因此,实际规则是:**Anthropic API 密钥,或启用了 +Extra Usage 的 Claude 订阅**。如果你想要最清晰的生产环境路径,请使用 Anthropic API +密钥。 Anthropic 当前的公开文档: @@ -47,17 +48,17 @@ Anthropic 当前的公开文档: - [Using Claude Code with your Pro or Max plan](https://support.claude.com/en/articles/11145838-using-claude-code-with-your-pro-or-max-plan) - [Using Claude Code with your Team or Enterprise plan](https://support.anthropic.com/en/articles/11845131-using-claude-code-with-your-team-or-enterprise-plan/) -如果你希望采用最明确的计费路径,请改用 Anthropic API key。 +如果你想要最清晰的计费路径,请改用 Anthropic API 密钥。 OpenClaw 也支持其他订阅式选项,包括 [OpenAI Codex](/zh-CN/providers/openai)、[Qwen Cloud Coding Plan](/zh-CN/providers/qwen)、 [MiniMax Coding Plan](/zh-CN/providers/minimax) 和 [Z.AI / GLM Coding Plan](/zh-CN/providers/glm)。 -## 选项 A:Anthropic API key +## 选项 A:Anthropic API 密钥 **最适合:** 标准 API 访问和按量计费。 -请在 Anthropic Console 中创建你的 API key。 +请在 Anthropic Console 中创建你的 API 密钥。 ### CLI 设置 @@ -89,10 +90,10 @@ openclaw onboard --anthropic-api-key "$ANTHROPIC_API_KEY" ## 快速模式(Anthropic API) -OpenClaw 的共享 `/fast` 开关也支持直接面向公开 Anthropic 的流量,包括发送到 `api.anthropic.com` 的 API key 和 OAuth 认证请求。 +OpenClaw 的共享 `/fast` 开关也支持直连公开 Anthropic 流量,包括发送到 `api.anthropic.com` 的 API 密钥和 OAuth 认证请求。 -- `/fast on` 映射为 `service_tier: "auto"` -- `/fast off` 映射为 `service_tier: "standard_only"` +- `/fast on` 映射到 `service_tier: "auto"` +- `/fast off` 映射到 `service_tier: "standard_only"` - 配置默认值: ```json5 @@ -111,23 +112,23 @@ OpenClaw 的共享 `/fast` 开关也支持直接面向公开 Anthropic 的流量 重要限制: -- OpenClaw 仅会为直接发往 `api.anthropic.com` 的请求注入 Anthropic service tier。如果你通过代理或 Gateway 网关路由 `anthropic/*`,`/fast` 不会修改 `service_tier`。 -- 如果同时设置了显式 Anthropic `serviceTier` 或 `service_tier` 模型参数,则它们会覆盖 `/fast` 的默认值。 -- Anthropic 会在响应中的 `usage.service_tier` 报告实际生效的 tier。对于没有 Priority Tier 容量的账户,`service_tier: "auto"` 仍可能解析为 `standard`。 +- OpenClaw 只会为直连 `api.anthropic.com` 的请求注入 Anthropic service tier。如果你通过代理或 Gateway 网关路由 `anthropic/*`,`/fast` 不会修改 `service_tier`。 +- 如果同时设置了显式的 Anthropic `serviceTier` 或 `service_tier` 模型参数,它们会覆盖 `/fast` 默认值。 +- Anthropic 会在响应中的 `usage.service_tier` 返回实际生效的 tier。对于没有 Priority Tier 容量的账户,`service_tier: "auto"` 仍可能解析为 `standard`。 ## 提示词缓存(Anthropic API) -OpenClaw 支持 Anthropic 的提示词缓存功能。这**仅适用于 API**;旧版 Anthropic token 认证不会遵循缓存设置。 +OpenClaw 支持 Anthropic 的提示词缓存功能。这是**仅 API** 功能;旧版 Anthropic token 凭证不会应用缓存设置。 ### 配置 在你的模型配置中使用 `cacheRetention` 参数: -| 值 | 缓存时长 | 说明 | -| ------- | -------- | -------------------- | -| `none` | 不缓存 | 禁用提示词缓存 | -| `short` | 5 分钟 | API key 认证的默认值 | -| `long` | 1 小时 | 扩展缓存 | +| Value | Cache Duration | Description | +| ------- | -------------- | ------------------ | +| `none` | 不缓存 | 禁用提示词缓存 | +| `short` | 5 分钟 | API 密钥凭证的默认值 | +| `long` | 1 小时 | 扩展缓存 | ```json5 { @@ -145,11 +146,11 @@ OpenClaw 支持 Anthropic 的提示词缓存功能。这**仅适用于 API**; ### 默认值 -使用 Anthropic API Key 认证时,OpenClaw 会自动对所有 Anthropic 模型应用 `cacheRetention: "short"`(5 分钟缓存)。你可以通过在配置中显式设置 `cacheRetention` 来覆盖它。 +当使用 Anthropic API 密钥认证时,OpenClaw 会自动为所有 Anthropic 模型应用 `cacheRetention: "short"`(5 分钟缓存)。你可以在配置中显式设置 `cacheRetention` 来覆盖此行为。 -### 按智能体覆盖 `cacheRetention` +### 按智能体覆盖 cacheRetention -将模型级参数作为基线,然后通过 `agents.list[].params` 覆盖特定智能体。 +请将模型级参数作为基线,然后通过 `agents.list[].params` 覆盖特定智能体。 ```json5 { @@ -164,30 +165,29 @@ OpenClaw 支持 Anthropic 的提示词缓存功能。这**仅适用于 API**; }, list: [ { id: "research", default: true }, - { id: "alerts", params: { cacheRetention: "none" } }, // 仅覆盖此智能体 + { id: "alerts", params: { cacheRetention: "none" } }, // 仅覆盖这个智能体 ], }, } ``` -与缓存相关的配置合并顺序: +与缓存相关参数的配置合并顺序: 1. `agents.defaults.models["provider/model"].params` 2. `agents.list[].params`(匹配 `id`,按键覆盖) -这样就可以让一个智能体保留长期缓存,而另一个使用同一模型的智能体禁用缓存,以避免突发性/低复用流量带来的写入成本。 +这样,你就可以让一个智能体保留长期缓存,同时让同一模型上的另一个智能体禁用缓存,以避免在突发 / 低复用流量下产生写入成本。 ### Bedrock Claude 说明 -- Bedrock 上的 Anthropic Claude 模型(`amazon-bedrock/*anthropic.claude*`)在配置后可透传 `cacheRetention`。 -- 非 Anthropic 的 Bedrock 模型会在运行时被强制设为 `cacheRetention: "none"`。 -- 当未设置显式值时,Anthropic API key 的智能默认值也会为 Claude-on-Bedrock 模型引用填入 `cacheRetention: "short"`。 +- Bedrock 上的 Anthropic Claude 模型(`amazon-bedrock/*anthropic.claude*`)在配置时接受 `cacheRetention` 透传。 +- 非 Anthropic 的 Bedrock 模型在运行时会被强制设置为 `cacheRetention: "none"`。 +- 当未设置显式值时,Anthropic API 密钥的智能默认值也会为 Claude-on-Bedrock 模型引用填充 `cacheRetention: "short"`。 -## 100 万上下文窗口(Anthropic beta) +## 1M 上下文窗口(Anthropic beta) -Anthropic 的 100 万上下文窗口受 beta 权限控制。在 OpenClaw 中, -对受支持的 Opus/Sonnet 模型,可通过为每个模型设置 -`params.context1m: true` 启用。 +Anthropic 的 1M 上下文窗口仍处于 beta 限制阶段。在 OpenClaw 中, +请通过 `params.context1m: true` 为受支持的 Opus/Sonnet 模型逐个启用。 ```json5 { @@ -203,73 +203,74 @@ Anthropic 的 100 万上下文窗口受 beta 权限控制。在 OpenClaw 中, } ``` -OpenClaw 会将其映射为 Anthropic 请求中的 +OpenClaw 会将其映射为 Anthropic 请求上的 `anthropic-beta: context-1m-2025-08-07`。 -只有当该模型的 `params.context1m` 被显式设置为 `true` 时, -此功能才会启用。 +只有在该模型的 `params.context1m` 被显式设置为 `true` 时, +此功能才会激活。 要求:Anthropic 必须允许该凭证使用长上下文 -(通常是 API key 计费,或 OpenClaw 的 Claude 登录路径 / 启用了 -Extra Usage 的旧版 token 认证)。否则 Anthropic 会返回: +(通常是 API 密钥计费,或启用了 Extra Usage 的 OpenClaw Claude 登录路径 / 旧版 token 凭证)。 +否则 Anthropic 会返回: `HTTP 429: rate_limit_error: Extra usage is required for long context requests`。 -注意:Anthropic 当前在使用 -旧版 Anthropic token 认证(`sk-ant-oat-*`)时,会拒绝 `context-1m-*` -beta 请求。如果你在这种旧版认证模式下配置了 +注意:Anthropic 当前会在使用 +旧版 Anthropic token 凭证(`sk-ant-oat-*`)时拒绝 `context-1m-*` beta 请求。如果你在该旧版凭证模式下配置了 `context1m: true`,OpenClaw 会记录一条警告,并通过跳过 context1m beta -header 回退到标准上下文窗口,同时保留所需的 OAuth beta。 +header 回退到标准上下文窗口,同时保留必需的 OAuth beta。 ## 已移除:Claude CLI 后端 -内置的 Anthropic `claude-cli` 后端已被移除。 +内置 Anthropic `claude-cli` 后端已被移除。 - Anthropic 在 2026 年 4 月 4 日的通知中表示,由 OpenClaw 驱动的 Claude 登录流量属于 - 第三方 harness 使用,因此需要 **Extra Usage**。 -- 我们的本地复现也显示,直接使用 - `claude -p --append-system-prompt ...` 在附加提示词表明 OpenClaw - 身份时,也可能触发同样的限制。 -- 相同的类 OpenClaw 系统提示词,在 - Anthropic SDK + `ANTHROPIC_API_KEY` 路径上不会触发该限制。 -- 在 OpenClaw 中处理 Anthropic 流量时,请使用 Anthropic API key。 + 第三方 harness 使用,并需要 **Extra Usage**。 +- 我们的本地复现也表明,直接执行 + `claude -p --append-system-prompt ...` 在附加的提示词标识出 OpenClaw 时, + 也可能触发相同保护。 +- 在 Anthropic SDK + `ANTHROPIC_API_KEY` 路径上,相同的类 OpenClaw 提示词 + 不会触发该保护。 +- 在 OpenClaw 中处理 Anthropic 流量时,请使用 Anthropic API 密钥。 +- 如果你需要本地 CLI 回退运行时,请使用其他受支持的 CLI 后端, + 例如 Codex CLI。请参阅 [/gateway/cli-backends](/gateway/cli-backends)。 ## 说明 -- Anthropic 的公开 Claude Code 文档仍然记录了直接 CLI 用法,例如 - `claude -p`,但 Anthropic 面向 OpenClaw 用户的单独通知指出, - **OpenClaw** 的 Claude 登录路径属于第三方 harness 使用,因此需要 - **Extra Usage**(按量付费,与订阅分开计费)。 - 我们的本地复现也显示,直接使用 - `claude -p --append-system-prompt ...` 在附加提示词表明 OpenClaw - 身份时可能触发同样的限制,而相同形式的提示词在 - Anthropic SDK + `ANTHROPIC_API_KEY` 路径上不会复现该问题。对于生产环境,我们 - 建议改用 Anthropic API key。 -- Anthropic setup-token 已重新在 OpenClaw 中作为旧版/手动路径提供。Anthropic 针对 OpenClaw 的专用计费通知仍然适用,因此使用此路径时,应预期 Anthropic 会要求 **Extra Usage**。 -- 认证细节和复用规则见 [/concepts/oauth](/zh-CN/concepts/oauth)。 +- Anthropic 的公开 Claude Code 文档仍然记录了诸如 + `claude -p` 之类的直接 CLI 用法,但 Anthropic 单独发给 OpenClaw 用户的通知指出, + **OpenClaw** 的 Claude 登录路径属于第三方 harness 使用,并要求 + **Extra Usage**(按量计费,与订阅分开计费)。 + 我们的本地复现也表明,直接执行 + `claude -p --append-system-prompt ...` 在附加提示词标识出 OpenClaw 时 + 也可能触发相同保护,而相同的提示词形式在 Anthropic SDK + `ANTHROPIC_API_KEY` + 路径上不会复现该问题。对于生产环境,我们 + 改为推荐使用 Anthropic API 密钥。 +- Anthropic setup-token 现已在 OpenClaw 中重新提供,作为旧版 / 手动路径。Anthropic 针对 OpenClaw 的专用计费通知仍然适用,因此请在预期 Anthropic 会对此路径要求 **Extra Usage** 的前提下使用它。 +- 凭证详情和复用规则请参阅 [/concepts/oauth](/zh-CN/concepts/oauth)。 ## 故障排除 **401 错误 / token 突然失效** -- 旧版 Anthropic token 认证可能过期或被撤销。 -- 对于新的设置,请迁移到 Anthropic API key。 +- 旧版 Anthropic token 凭证可能会过期或被撤销。 +- 对于新的设置,请迁移到 Anthropic API 密钥。 -**未找到 provider "anthropic" 的 API key** +**提供商 “anthropic” 未找到 API 密钥** -- 认证是**按智能体**区分的。新智能体不会继承主智能体的 key。 -- 重新为该智能体运行新手引导,或在 Gateway 网关 - 主机上配置 API key,然后使用 `openclaw models status` 验证。 +- 凭证是**按智能体**区分的。新智能体不会继承主智能体的密钥。 +- 请重新为该智能体运行新手引导,或在 gateway host 上配置 API 密钥, + 然后使用 `openclaw models status` 进行验证。 **未找到配置文件 `anthropic:default` 的凭证** -- 运行 `openclaw models status` 查看当前激活的是哪个认证配置文件。 -- 重新运行新手引导,或为该配置文件路径配置 API key。 +- 运行 `openclaw models status` 以查看当前激活的是哪个凭证配置文件。 +- 重新运行新手引导,或为该配置文件路径配置 API 密钥。 -**没有可用的认证配置文件(全部处于冷却中/不可用)** +**没有可用的凭证配置文件(全部处于冷却 / 不可用)** - 检查 `openclaw models status --json` 中的 `auth.unusableProfiles`。 -- Anthropic 的速率限制冷却可能是按模型区分的,因此即使当前模型处于冷却中, - 同级的另一个 Anthropic 模型仍可能可用。 +- Anthropic 的速率限制冷却可能是按模型生效的,因此即使当前模型正在冷却, + 同级的其他 Anthropic 模型仍可能可用。 - 添加另一个 Anthropic 配置文件,或等待冷却结束。 更多内容:[/gateway/troubleshooting](/zh-CN/gateway/troubleshooting) 和 [/help/faq](/zh-CN/help/faq)。 diff --git a/docs/zh-CN/providers/google.md b/docs/zh-CN/providers/google.md index 63ea7778f..beadfe50b 100644 --- a/docs/zh-CN/providers/google.md +++ b/docs/zh-CN/providers/google.md @@ -1,26 +1,27 @@ --- read_when: - 你想在 OpenClaw 中使用 Google Gemini 模型 - - 你需要 API 密钥认证流程 -summary: Google Gemini 设置(API 密钥、图像生成、媒体理解、网页搜索) + - 你需要 API 密钥或 OAuth 凭证流程 +summary: Google Gemini 设置(API 密钥 + OAuth、图像生成、媒体理解、Web 搜索) title: Google(Gemini) x-i18n: - generated_at: "2026-04-06T00:51:57Z" + generated_at: "2026-04-06T12:44:23Z" model: gpt-5.4 provider: openai - source_hash: 358d33a68275b01ebd916a3621dd651619cb9a1d062e2fb6196a7f3c501c015a + source_hash: 36cc7c7d8d19f6d4a3fb223af36c8402364fc309d14ffe922bd004203ceb1754 source_path: providers/google.md workflow: 15 --- # Google(Gemini) -Google 插件通过 Google AI Studio 提供对 Gemini 模型的访问,并通过 -Gemini Grounding 提供图像生成、媒体理解(图像/音频/视频)和网页搜索功能。 +Google 插件通过 Google AI Studio 提供对 Gemini 模型的访问,另外还支持 +通过 Gemini Grounding 提供图像生成、媒体理解(图像/音频/视频)以及 Web 搜索。 - 提供商:`google` -- 认证:`GEMINI_API_KEY` 或 `GOOGLE_API_KEY` +- 凭证:`GEMINI_API_KEY` 或 `GOOGLE_API_KEY` - API:Google Gemini API +- 备选提供商:`google-gemini-cli`(OAuth) ## 快速开始 @@ -51,6 +52,46 @@ openclaw onboard --non-interactive \ --gemini-api-key "$GEMINI_API_KEY" ``` +## OAuth(Gemini CLI) + +备选提供商 `google-gemini-cli` 使用 PKCE OAuth,而不是 API +密钥。这是一个非官方集成;一些用户报告了账号 +限制。请自行承担风险。 + +- 默认模型:`google-gemini-cli/gemini-3.1-pro-preview` +- 别名:`gemini-cli` +- 安装前提:本地可用的 Gemini CLI,命令名为 `gemini` + - Homebrew:`brew install gemini-cli` + - npm:`npm install -g @google/gemini-cli` +- 登录: + +```bash +openclaw models auth login --provider google-gemini-cli --set-default +``` + +环境变量: + +- `OPENCLAW_GEMINI_OAUTH_CLIENT_ID` +- `OPENCLAW_GEMINI_OAUTH_CLIENT_SECRET` + +(或者使用 `GEMINI_CLI_*` 变体。) + +如果 Gemini CLI OAuth 请求在登录后失败,请在 Gateway 网关主机上设置 +`GOOGLE_CLOUD_PROJECT` 或 `GOOGLE_CLOUD_PROJECT_ID`,然后 +重试。 + +如果在浏览器流程开始之前登录失败,请确认本地 `gemini` +命令已安装并且位于 `PATH` 中。OpenClaw 同时支持 Homebrew 安装 +和全局 npm 安装,包括常见的 Windows/npm 布局。 + +Gemini CLI JSON 用量说明: + +- 回复文本来自 CLI JSON 的 `response` 字段。 +- 当 CLI 将 `usage` 留空时,用量会回退到 `stats`。 +- `stats.cached` 会被归一化为 OpenClaw `cacheRead`。 +- 如果缺少 `stats.input`,OpenClaw 会根据 + `stats.input_tokens - stats.cached` 推导输入 token 数。 + ## 功能 | 功能 | 支持情况 | @@ -59,22 +100,22 @@ openclaw onboard --non-interactive \ | 图像生成 | 是 | | 音乐生成 | 是 | | 图像理解 | 是 | -| 音频转写 | 是 | +| 音频转录 | 是 | | 视频理解 | 是 | -| 网页搜索(Grounding) | 是 | -| 思考/推理 | 是(Gemini 3.1+) | +| Web 搜索(Grounding) | 是 | +| Thinking/推理 | 是(Gemini 3.1+) | ## 直接复用 Gemini 缓存 -对于直接使用 Gemini API 的运行(`api: "google-generative-ai"`),OpenClaw 现在会 -将已配置的 `cachedContent` 句柄传递给 Gemini 请求。 +对于直接 Gemini API 运行(`api: "google-generative-ai"`),OpenClaw 现在会 +将已配置的 `cachedContent` 句柄透传到 Gemini 请求中。 -- 可通过 `cachedContent` 或旧版的 `cached_content` - 为每个模型或全局参数进行配置 -- 如果两者同时存在,则 `cachedContent` 优先 +- 可通过以下任一方式为每个模型或全局参数配置: + `cachedContent` 或旧版 `cached_content` +- 如果两者都存在,优先使用 `cachedContent` - 示例值:`cachedContents/prebuilt-context` -- Gemini 的缓存命中用量会从上游的 `cachedContentTokenCount` - 统一归一化到 OpenClaw 的 `cacheRead` +- Gemini 缓存命中的用量会根据上游 `cachedContentTokenCount` + 归一化为 OpenClaw `cacheRead` 示例: @@ -101,10 +142,11 @@ openclaw onboard --non-interactive \ - 也支持 `google/gemini-3-pro-image-preview` - 生成:每次请求最多 4 张图像 -- 编辑模式:已启用,最多支持 5 张输入图像 +- 编辑模式:已启用,最多 5 张输入图像 - 几何控制:`size`、`aspectRatio` 和 `resolution` -图像生成、媒体理解和 Gemini Grounding 都继续使用 +仅支持 OAuth 的 `google-gemini-cli` 提供商是一个独立的文本推理 +界面。图像生成、媒体理解和 Gemini Grounding 仍然使用 `google` 提供商 id。 要将 Google 用作默认图像提供商: @@ -121,16 +163,15 @@ openclaw onboard --non-interactive \ } ``` -参见 [图像生成](/zh-CN/tools/image-generation),了解共享工具参数、 -提供商选择和故障切换行为。 +关于共享工具参数、提供商选择和回退行为,请参见 [Image Generation](/zh-CN/tools/image-generation)。 ## 视频生成 -内置的 `google` 插件还通过共享的 -`video_generate` 工具注册了视频生成功能。 +内置的 `google` 插件还通过共享 +`video_generate` 工具注册了视频生成。 - 默认视频模型:`google/veo-3.1-fast-generate-preview` -- 模式:文生视频、图生视频,以及单视频参考流程 +- 模式:文生视频、图生视频和单视频参考流程 - 支持 `aspectRatio`、`resolution` 和 `audio` - 当前时长限制:**4 到 8 秒** @@ -148,20 +189,19 @@ openclaw onboard --non-interactive \ } ``` -参见 [视频生成](/zh-CN/tools/video-generation),了解共享工具参数、 -提供商选择和故障切换行为。 +关于共享工具参数、提供商选择和回退行为,请参见 [Video Generation](/zh-CN/tools/video-generation)。 ## 音乐生成 -内置的 `google` 插件还通过共享的 -`music_generate` 工具注册了音乐生成功能。 +内置的 `google` 插件还通过共享 +`music_generate` 工具注册了音乐生成。 - 默认音乐模型:`google/lyria-3-clip-preview` - 也支持 `google/lyria-3-pro-preview` - 提示词控制:`lyrics` 和 `instrumental` -- 输出格式:默认 `mp3`,此外 `google/lyria-3-pro-preview` 还支持 `wav` +- 输出格式:默认 `mp3`,另外在 `google/lyria-3-pro-preview` 上还支持 `wav` - 参考输入:最多 10 张图像 -- 基于会话的运行会通过共享的任务/状态流程分离执行,包括 `action: "status"` +- 基于会话的运行会通过共享任务/状态流程分离执行,包括 `action: "status"` 要将 Google 用作默认音乐提供商: @@ -177,11 +217,10 @@ openclaw onboard --non-interactive \ } ``` -参见 [音乐生成](/zh-CN/tools/music-generation),了解共享工具参数、 -提供商选择和故障切换行为。 +关于共享工具参数、提供商选择和回退行为,请参见 [Music Generation](/zh-CN/tools/music-generation)。 ## 环境说明 -如果 Gateway 网关 以守护进程方式运行(launchd/systemd),请确保 `GEMINI_API_KEY` +如果 Gateway 网关以守护进程方式运行(launchd/systemd),请确保 `GEMINI_API_KEY` 对该进程可用(例如放在 `~/.openclaw/.env` 中,或通过 `env.shellEnv` 提供)。 diff --git a/docs/zh-CN/providers/models.md b/docs/zh-CN/providers/models.md index a070f9061..d7ecb020f 100644 --- a/docs/zh-CN/providers/models.md +++ b/docs/zh-CN/providers/models.md @@ -1,25 +1,26 @@ --- read_when: - 你想选择一个模型提供商 - - 你想查看用于 LLM 凭证和模型选择的快速设置示例 + - 你想查看 LLM 凭证 + 模型选择的快速设置示例 summary: OpenClaw 支持的模型提供商(LLM) title: 模型提供商快速开始 x-i18n: - generated_at: "2026-04-06T00:47:10Z" + generated_at: "2026-04-06T12:44:31Z" model: gpt-5.4 provider: openai - source_hash: c0314fb1c754171e5fc252d30f7ba9bb6acdbb978d97e9249264d90351bac2e7 + source_hash: 500191bfe853241096f97928ced2327a13b6f7f62003cb7452b24886c272e6ba source_path: providers/models.md workflow: 15 --- # 模型提供商 -OpenClaw 可以使用许多 LLM 提供商。选择一个,完成身份验证,然后将默认模型设置为 `provider/model`。 +OpenClaw 可以使用许多 LLM 提供商。选择一个提供商,完成凭证配置,然后将默认 +模型设置为 `provider/model`。 ## 快速开始(两步) -1. 使用提供商完成身份验证(通常通过 `openclaw onboard`)。 +1. 使用该提供商完成凭证配置(通常通过 `openclaw onboard`)。 2. 设置默认模型: ```json5 @@ -30,16 +31,16 @@ OpenClaw 可以使用许多 LLM 提供商。选择一个,完成身份验证, ## 支持的提供商(入门集合) -- [阿里巴巴 Model Studio](/zh-CN/providers/alibaba) +- [Alibaba Model Studio](/zh-CN/providers/alibaba) - [Anthropic(API + Claude CLI)](/zh-CN/providers/anthropic) - [Amazon Bedrock](/zh-CN/providers/bedrock) - [BytePlus(国际版)](/zh-CN/concepts/model-providers#byteplus-international) - [Chutes](/zh-CN/providers/chutes) -- [ComfyUI](/providers/comfy) +- [ComfyUI](/zh-CN/providers/comfy) - [Cloudflare AI Gateway](/zh-CN/providers/cloudflare-ai-gateway) - [fal](/zh-CN/providers/fal) - [Fireworks](/zh-CN/providers/fireworks) -- [GLM 模型](/zh-CN/providers/glm) +- [GLM models](/zh-CN/providers/glm) - [MiniMax](/zh-CN/providers/minimax) - [Mistral](/zh-CN/providers/mistral) - [Moonshot AI(Kimi + Kimi Coding)](/zh-CN/providers/moonshot) @@ -56,9 +57,11 @@ OpenClaw 可以使用许多 LLM 提供商。选择一个,完成身份验证, - [xAI](/zh-CN/providers/xai) - [Z.AI](/zh-CN/providers/zai) -## 其他内置提供商变体 +## 其他内置变体 -- `anthropic-vertex` - 当 Vertex 凭证可用时,隐式支持 Google Vertex 上的 Anthropic;没有单独的新手引导身份验证选项 +- `anthropic-vertex` - 当 Vertex 凭证可用时,隐式提供基于 Google Vertex 的 Anthropic 支持;没有单独的新手引导凭证选项 - `copilot-proxy` - 本地 VS Code Copilot Proxy 桥接;使用 `openclaw onboard --auth-choice copilot-proxy` +- `google-gemini-cli` - 非官方的 Gemini CLI OAuth 流程;需要本地安装 `gemini`(`brew install gemini-cli` 或 `npm install -g @google/gemini-cli`);默认模型为 `google-gemini-cli/gemini-3.1-pro-preview`;使用 `openclaw onboard --auth-choice google-gemini-cli` 或 `openclaw models auth login --provider google-gemini-cli --set-default` -如需查看完整的提供商目录(xAI、Groq、Mistral 等)和高级配置,请参阅 [模型提供商](/zh-CN/concepts/model-providers)。 +如需完整的提供商目录(xAI、Groq、Mistral 等)和高级配置, +请参见 [模型提供商](/zh-CN/concepts/model-providers)。 diff --git a/docs/zh-CN/reference/session-management-compaction.md b/docs/zh-CN/reference/session-management-compaction.md index b734453f0..94e1d44f2 100644 --- a/docs/zh-CN/reference/session-management-compaction.md +++ b/docs/zh-CN/reference/session-management-compaction.md @@ -1,15 +1,15 @@ --- read_when: - - 你需要调试会话 id、转录 JSONL 或 sessions.json 字段 - - 你正在修改自动压缩行为,或添加“压缩前”维护逻辑 - - 你想实现记忆刷新或静默系统轮次 -summary: 深入解析:会话存储 + 转录、生命周期,以及(自动)压缩内部机制 + - 你需要调试 session id、transcript JSONL 或 sessions.json 字段 + - 你正在修改自动压缩行为,或添加“压缩前”清理逻辑 + - 你想实现 memory flush 或静默 system turn +summary: 深入解析:会话存储 + transcript、生命周期,以及(自动)压缩内部机制 title: 会话管理深入解析 x-i18n: - generated_at: "2026-04-05T18:15:37Z" + generated_at: "2026-04-06T12:45:16Z" model: gpt-5.4 provider: openai - source_hash: e0d8c2d30be773eac0424f7a4419ab055fdd50daac8bc654e7d250c891f2c3b8 + source_hash: e379d624dd7808d3af25ed011079268ce6a9da64bb3f301598884ad4c46ab091 source_path: reference/session-management-compaction.md workflow: 15 --- @@ -20,13 +20,13 @@ x-i18n: - **会话路由**(入站消息如何映射到 `sessionKey`) - **会话存储**(`sessions.json`)及其跟踪内容 -- **转录持久化**(`*.jsonl`)及其结构 -- **转录清理**(运行前的提供商专用修正) -- **上下文限制**(上下文窗口 vs 已跟踪 token) -- **压缩**(手动 + 自动压缩)以及在何处挂接压缩前逻辑 -- **静默维护**(例如不应产生用户可见输出的记忆写入) +- **Transcript 持久化**(`*.jsonl`)及其结构 +- **Transcript 清理**(运行前针对特定提供商的修正) +- **上下文限制**(上下文窗口与已跟踪 token 的区别) +- **压缩**(手动 + 自动压缩)以及应在何处挂接压缩前工作 +- **静默清理**(例如不应产生用户可见输出的 memory 写入) -如果你想先看更高层的概览,请从以下文档开始: +如果你想先看更高层级的概览,请从以下内容开始: - [/concepts/session](/zh-CN/concepts/session) - [/concepts/compaction](/zh-CN/concepts/compaction) @@ -37,37 +37,37 @@ x-i18n: --- -## 事实来源:Gateway 网关 +## 单一事实来源:Gateway 网关 -OpenClaw 的设计围绕一个拥有会话状态的单一 **Gateway 网关进程**。 +OpenClaw 的设计围绕单个**Gateway 网关 进程**展开,由它持有会话状态。 -- UI(macOS 应用、web Control UI、TUI)应向 Gateway 网关查询会话列表和 token 计数。 -- 在远程模式下,会话文件位于远程主机上;“检查你本地 Mac 上的文件”并不能反映 Gateway 网关实际使用的内容。 +- UI(macOS 应用、网页 Control UI、TUI)应向 Gateway 网关 查询会话列表和 token 计数。 +- 在远程模式下,会话文件位于远程主机上;“查看你本地 Mac 上的文件”并不能反映 Gateway 网关 实际使用的内容。 --- ## 两层持久化 -OpenClaw 通过两层持久化保存会话: +OpenClaw 以两层方式持久化会话: 1. **会话存储(`sessions.json`)** - - 键值映射:`sessionKey -> SessionEntry` - - 体积小、可变、安全,可编辑(或删除条目) - - 跟踪会话元数据(当前会话 id、最近活动时间、开关、token 计数器等) + - 键 / 值映射:`sessionKey -> SessionEntry` + - 体积小、可变、安全可编辑(或删除条目) + - 跟踪会话元数据(当前 session id、最近活动时间、开关、token 计数器等) -2. **转录(`.jsonl`)** - - 采用树结构的追加式转录(条目包含 `id` + `parentId`) +2. **Transcript(`.jsonl`)** + - 追加写入的 transcript,带树结构(条目具有 `id` + `parentId`) - 存储实际对话 + 工具调用 + 压缩摘要 - - 用于为未来轮次重建模型上下文 + - 用于为后续轮次重建模型上下文 --- -## 磁盘位置 +## 磁盘上的位置 -在 Gateway 网关主机上,按智能体区分: +每个智能体在 Gateway 网关 主机上的位置: - 存储:`~/.openclaw/agents//sessions/sessions.json` -- 转录:`~/.openclaw/agents//sessions/.jsonl` +- Transcripts:`~/.openclaw/agents//sessions/.jsonl` - Telegram 话题会话:`.../-topic-.jsonl` OpenClaw 通过 `src/config/sessions.ts` 解析这些路径。 @@ -76,23 +76,23 @@ OpenClaw 通过 `src/config/sessions.ts` 解析这些路径。 ## 存储维护和磁盘控制 -会话持久化为 `sessions.json` 和转录产物提供了自动维护控制(`session.maintenance`): +会话持久化为 `sessions.json` 和 transcript 工件提供了自动维护控制(`session.maintenance`): - `mode`:`warn`(默认)或 `enforce` -- `pruneAfter`:过期条目的年龄阈值(默认 `30d`) -- `maxEntries`:`sessions.json` 中的条目上限(默认 `500`) -- `rotateBytes`:当 `sessions.json` 过大时轮转(默认 `10mb`) -- `resetArchiveRetention`:`*.reset.` 转录归档的保留期(默认:与 `pruneAfter` 相同;`false` 表示禁用清理) -- `maxDiskBytes`:可选的会话目录磁盘预算 +- `pruneAfter`:陈旧条目的保留期限截止值(默认 `30d`) +- `maxEntries`:`sessions.json` 中条目上限(默认 `500`) +- `rotateBytes`:当 `sessions.json` 过大时进行轮转(默认 `10mb`) +- `resetArchiveRetention`:`*.reset.` transcript 归档的保留期(默认与 `pruneAfter` 相同;`false` 表示禁用清理) +- `maxDiskBytes`:可选的 sessions 目录预算 - `highWaterBytes`:清理后的可选目标值(默认是 `maxDiskBytes` 的 `80%`) 磁盘预算清理的执行顺序(`mode: "enforce"`): -1. 优先删除最旧的归档或孤立转录产物。 -2. 如果仍高于目标值,则驱逐最旧的会话条目及其转录文件。 -3. 持续执行,直到使用量小于等于 `highWaterBytes`。 +1. 先移除最旧的归档或孤立 transcript 工件。 +2. 如果仍高于目标值,则逐出最旧的会话条目及其 transcript 文件。 +3. 持续执行,直到占用量小于或等于 `highWaterBytes`。 -在 `mode: "warn"` 下,OpenClaw 会报告潜在驱逐项,但不会修改存储/文件。 +在 `mode: "warn"` 下,OpenClaw 会报告潜在的逐出项,但不会修改存储 / 文件。 按需运行维护: @@ -103,130 +103,127 @@ openclaw sessions cleanup --enforce --- -## 定时任务会话和运行日志 +## Cron 会话和运行日志 -隔离的 cron 运行也会创建会话条目/转录,并且它们有专门的保留控制: +隔离的 cron 运行也会创建会话条目 / transcript,并且它们有专门的保留控制: - `cron.sessionRetention`(默认 `24h`)会从会话存储中清理旧的隔离 cron 运行会话(`false` 表示禁用)。 -- `cron.runLog.maxBytes` + `cron.runLog.keepLines` 会清理 `~/.openclaw/cron/runs/.jsonl` 文件(默认:`2_000_000` 字节和 `2000` 行)。 +- `cron.runLog.maxBytes` + `cron.runLog.keepLines` 会裁剪 `~/.openclaw/cron/runs/.jsonl` 文件(默认:`2_000_000` 字节和 `2000` 行)。 --- ## 会话键(`sessionKey`) -`sessionKey` 用于标识你当前处于 _哪个对话桶_ 中(路由 + 隔离)。 +`sessionKey` 用于标识你所在的_哪个会话桶_(路由 + 隔离)。 常见模式: -- 主/直接聊天(每个智能体):`agent::`(默认 `main`) +- 主 / 直接聊天(每个智能体):`agent::`(默认 `main`) - 群组:`agent:::group:` -- 房间/渠道(Discord/Slack):`agent:::channel:` 或 `...:room:` +- 房间 / 渠道(Discord / Slack):`agent:::channel:` 或 `...:room:` - Cron:`cron:` - Webhook:`hook:`(除非被覆盖) -规范规则见 [/concepts/session](/zh-CN/concepts/session)。 +规范规则记录在 [/concepts/session](/zh-CN/concepts/session)。 --- ## 会话 id(`sessionId`) -每个 `sessionKey` 都指向当前的 `sessionId`(即继续该对话的转录文件)。 +每个 `sessionKey` 都会指向当前的 `sessionId`(用于延续对话的 transcript 文件)。 经验规则: - **重置**(`/new`、`/reset`)会为该 `sessionKey` 创建新的 `sessionId`。 -- **每日重置**(默认是 Gateway 网关主机本地时间凌晨 4:00)会在越过重置边界后的下一条消息上创建新的 `sessionId`。 -- **空闲过期**(`session.reset.idleMinutes` 或旧版 `session.idleMinutes`)会在消息于空闲窗口之后到达时创建新的 `sessionId`。当同时配置每日重置和空闲过期时,以先到者为准。 -- **线程父级分叉保护**(`session.parentForkMaxTokens`,默认 `100000`)会在父会话已过大时跳过父转录分叉;新线程将从空白开始。设为 `0` 可禁用。 +- **每日重置**(默认是 Gateway 网关 主机本地时间凌晨 4:00)会在越过重置边界后的下一条消息时创建新的 `sessionId`。 +- **空闲过期**(`session.reset.idleMinutes` 或旧版 `session.idleMinutes`)会在消息于空闲窗口之后到达时创建新的 `sessionId`。如果同时配置了 daily 和 idle,以先过期者为准。 +- **线程父级分叉保护**(`session.parentForkMaxTokens`,默认 `100000`)会在父会话已经过大时跳过父 transcript 分叉;新线程会从头开始。设置为 `0` 可禁用。 -实现细节:该决策发生在 `src/auto-reply/reply/session.ts` 的 `initSessionState()` 中。 +实现细节:这一决策发生在 `src/auto-reply/reply/session.ts` 中的 `initSessionState()`。 --- -## 会话存储 schema(`sessions.json`) +## 会话存储结构(`sessions.json`) 存储的值类型是 `src/config/sessions.ts` 中的 `SessionEntry`。 关键字段(非完整列表): -- `sessionId`:当前转录 id(除非设置了 `sessionFile`,否则文件名由它推导) +- `sessionId`:当前 transcript id(除非设置了 `sessionFile`,否则文件名从这里派生) - `updatedAt`:最近活动时间戳 -- `sessionFile`:可选的显式转录路径覆盖 +- `sessionFile`:可选的显式 transcript 路径覆盖 - `chatType`:`direct | group | room`(帮助 UI 和发送策略) -- `provider`、`subject`、`room`、`space`、`displayName`:用于群组/渠道标签的元数据 +- `provider`、`subject`、`room`、`space`、`displayName`:用于群组 / 渠道标签的元数据 - 开关: - `thinkingLevel`、`verboseLevel`、`reasoningLevel`、`elevatedLevel` - `sendPolicy`(按会话覆盖) - 模型选择: - `providerOverride`、`modelOverride`、`authProfileOverride` -- token 计数器(尽力而为 / 依赖提供商): +- Token 计数器(尽力而为 / 取决于提供商): - `inputTokens`、`outputTokens`、`totalTokens`、`contextTokens` -- `compactionCount`:此会话键完成自动压缩的次数 -- `memoryFlushAt`:最近一次压缩前记忆刷新的时间戳 -- `memoryFlushCompactionCount`:上一次刷新运行时的压缩计数 +- `compactionCount`:该会话键完成自动压缩的次数 +- `memoryFlushAt`:最近一次压缩前 memory flush 的时间戳 +- `memoryFlushCompactionCount`:最近一次 flush 运行时的压缩计数 -该存储可以安全编辑,但 Gateway 网关是权威来源:会话运行时它可能重写或重新填充条目。 +这个存储可以安全编辑,但 Gateway 网关 才是权威:随着会话运行,它可能会重写或重新填充条目。 --- -## 转录结构(`*.jsonl`) +## Transcript 结构(`*.jsonl`) -转录由 `@mariozechner/pi-coding-agent` 的 `SessionManager` 管理。 +Transcripts 由 `@mariozechner/pi-coding-agent` 的 `SessionManager` 管理。 -该文件为 JSONL 格式: +该文件采用 JSONL 格式: - 第一行:会话头(`type: "session"`,包含 `id`、`cwd`、`timestamp`、可选的 `parentSession`) -- 后续:带有 `id` + `parentId` 的会话条目(树结构) +- 后续内容:带 `id` + `parentId` 的会话条目(树结构) 值得注意的条目类型: -- `message`:用户/助手/`toolResult` 消息 -- `custom_message`:由扩展注入、_会_ 进入模型上下文的消息(可对 UI 隐藏) -- `custom`:_不会_ 进入模型上下文的扩展状态 -- `compaction`:持久化的压缩摘要,带有 `firstKeptEntryId` 和 `tokensBefore` -- `branch_summary`:导航树分支时持久化的摘要 +- `message`:用户 / 助手 / `toolResult` 消息 +- `custom_message`:由扩展注入的、_会_进入模型上下文的消息(可对 UI 隐藏) +- `custom`:_不会_进入模型上下文的扩展状态 +- `compaction`:持久化的压缩摘要,带 `firstKeptEntryId` 和 `tokensBefore` +- `branch_summary`:在导航树分支时持久化的摘要 -OpenClaw 有意**不会**“修正”转录;Gateway 网关使用 `SessionManager` 读写它们。 +OpenClaw 有意**不会**“修正” transcripts;Gateway 网关 使用 `SessionManager` 来读写它们。 --- -## 上下文窗口 vs 已跟踪 token +## 上下文窗口与已跟踪 token -这里有两个不同的概念: +有两个不同的概念很重要: -1. **模型上下文窗口**:每个模型的硬上限(模型可见的 token) -2. **会话存储计数器**:写入 `sessions.json` 的滚动统计(用于 `/status` 和仪表板) +1. **模型上下文窗口**:每个模型的硬性上限(模型可见的 token) +2. **会话存储计数器**:写入 `sessions.json` 的滚动统计值(用于 `/status` 和仪表盘) -如果你正在调整限制: +如果你要调优限制: -- 上下文窗口来自模型目录(也可通过配置覆盖)。 -- 存储中的 `contextTokens` 是运行时估算/报告值;不要把它当作严格保证。 +- 上下文窗口来自模型目录(并且可通过配置覆盖)。 +- 存储中的 `contextTokens` 是运行时估算 / 报告值;不要把它当作严格保证。 -更多信息请参见 [/token-use](/zh-CN/reference/token-use)。 +更多信息见 [/token-use](/zh-CN/reference/token-use)。 --- ## 压缩:它是什么 -压缩会将较早的对话总结成转录中的持久化 `compaction` 条目,并保留最近消息不变。 +压缩会将较早的对话总结为 transcript 中一个持久化的 `compaction` 条目,并保留最近的消息不变。 -压缩后,未来轮次会看到: +压缩之后,后续轮次会看到: - 压缩摘要 - `firstKeptEntryId` 之后的消息 -压缩是**持久的**(不同于会话裁剪)。参见 [/concepts/session-pruning](/zh-CN/concepts/session-pruning)。 +压缩是**持久化的**(不同于会话裁剪)。参见 [/concepts/session-pruning](/zh-CN/concepts/session-pruning)。 ## 压缩分块边界和工具配对 -当 OpenClaw 将长转录拆分为压缩分块时,它会保持 -助手工具调用与其对应 `toolResult` 条目配对。 +当 OpenClaw 将较长 transcript 拆分为压缩分块时,它会让助手工具调用与其匹配的 `toolResult` 条目保持配对。 -- 如果 token 占比分割点落在工具调用和其结果之间,OpenClaw - 会将边界移动到助手工具调用消息处,而不是拆散这一对。 -- 如果尾部的工具结果块原本会将分块推过目标大小,OpenClaw - 会保留这段待处理工具块,并保持未总结的尾部完整。 -- 已中止/报错的工具调用块不会让待处理分割持续保持打开状态。 +- 如果按 token 占比分割的边界落在工具调用和其结果之间,OpenClaw 会将边界移动到助手工具调用消息,而不是把这一对拆开。 +- 如果尾部的工具结果块原本会让分块超过目标大小,OpenClaw 会保留该待处理工具块,并保持未总结的尾部不变。 +- 已中止 / 出错的工具调用块不会让待处理分割一直保持打开状态。 --- @@ -238,7 +235,7 @@ OpenClaw 有意**不会**“修正”转录;Gateway 网关使用 `SessionManag (`request_too_large`、`context length exceeded`、`input exceeds the maximum number of tokens`、`input token count exceeds the maximum number of input tokens`、`input is too long for the model`、`ollama error: context length -exceeded`,以及类似的提供商形式变体)→ 压缩 → 重试。 +exceeded`,以及类似的提供商格式变体)→ 压缩 → 重试。 2. **阈值维护**:在一次成功轮次之后,当: `contextTokens > contextWindow - reserveTokens` @@ -246,9 +243,9 @@ exceeded`,以及类似的提供商形式变体)→ 压缩 → 重试。 其中: - `contextWindow` 是模型的上下文窗口 -- `reserveTokens` 是为提示词 + 下一次模型输出预留的余量 +- `reserveTokens` 是为提示词 + 下一次模型输出保留的余量 -这些是 Pi 运行时语义(OpenClaw 会消费这些事件,但由 Pi 决定何时压缩)。 +这些是 Pi 运行时语义(OpenClaw 会消费这些事件,但何时压缩由 Pi 决定)。 --- @@ -266,21 +263,21 @@ Pi 的压缩设置位于 Pi settings 中: } ``` -OpenClaw 还会为嵌入式运行施加一个安全下限: +OpenClaw 还会为嵌入式运行强制执行一个安全下限: -- 如果 `compaction.reserveTokens < reserveTokensFloor`,OpenClaw 会将其提高。 +- 如果 `compaction.reserveTokens < reserveTokensFloor`,OpenClaw 会提升它。 - 默认下限是 `20000` token。 - 设置 `agents.defaults.compaction.reserveTokensFloor: 0` 可禁用该下限。 - 如果它本来就更高,OpenClaw 不会改动。 -原因:在压缩变得不可避免之前,为多轮“维护”操作(例如记忆写入)预留足够余量。 +原因:在压缩变得不可避免之前,为多轮“清理”操作(例如 memory 写入)保留足够的余量。 实现:`src/agents/pi-settings.ts` 中的 `ensurePiCompactionReserveTokens()` (由 `src/agents/pi-embedded-runner.ts` 调用)。 --- -## 面向用户的可见表面 +## 用户可见界面 你可以通过以下方式观察压缩和会话状态: @@ -291,65 +288,62 @@ OpenClaw 还会为嵌入式运行施加一个安全下限: --- -## 静默维护(`NO_REPLY`) +## 静默清理(`NO_REPLY`) OpenClaw 支持“静默”轮次,用于用户不应看到中间输出的后台任务。 约定: - 助手以精确的静默 token `NO_REPLY` / - `no_reply` 开头输出,以表示“不要向用户发送回复”。 -- OpenClaw 会在交付层将其剥离/抑制。 + `no_reply` 开始其输出,以表示“不要向用户发送回复”。 +- OpenClaw 会在发送层剥离 / 抑制它。 - 对精确静默 token 的抑制不区分大小写,因此当整个负载仅为该静默 token 时,`NO_REPLY` 和 - `no_reply` 都算有效。 -- 这仅用于真正的后台/不交付轮次;它不是普通可执行用户请求的快捷方式。 + `no_reply` 都算。 +- 这仅用于真正的后台 / 不投递轮次;它不是普通可执行用户请求的快捷方式。 -自 `2026.1.10` 起,OpenClaw 还会在 -部分分块以 `NO_REPLY` 开头时抑制**草稿/输入中流式传输**,这样静默操作就不会在轮次中途泄露部分输出。 +自 `2026.1.10` 起,OpenClaw 在部分分块以 `NO_REPLY` 开头时,也会抑制**草稿 / 输入中流式传输**,这样静默操作就不会在轮次中途泄露部分输出。 --- -## 压缩前“记忆刷新”(已实现) +## 压缩前 “memory flush”(已实现) -目标:在自动压缩发生之前,运行一个静默的智能体轮次,将持久 -状态写入磁盘(例如智能体工作区中的 `memory/YYYY-MM-DD.md`),这样压缩就不会 -擦除关键上下文。 +目标:在自动压缩发生之前,运行一次静默的智能体轮次,将持久状态写入磁盘(例如智能体工作区中的 `memory/YYYY-MM-DD.md`),这样压缩就无法抹掉关键上下文。 -OpenClaw 使用**预阈值刷新**方案: +OpenClaw 使用**阈值前 flush** 方法: 1. 监控会话上下文使用量。 -2. 当它越过“软阈值”(低于 Pi 的压缩阈值)时,向智能体运行一个静默的 - “现在写入记忆”指令。 -3. 使用精确的静默 token `NO_REPLY` / `no_reply`,这样用户就看不到 - 任何内容。 +2. 当它越过一个“软阈值”(低于 Pi 的压缩阈值)时,向智能体运行一个静默的 + “立即写入 memory” 指令。 +3. 使用精确的静默 token `NO_REPLY` / `no_reply`,这样用户就 + 看不到任何内容。 配置(`agents.defaults.compaction.memoryFlush`): - `enabled`(默认:`true`) - `softThresholdTokens`(默认:`4000`) -- `prompt`(刷新轮次的用户消息) -- `systemPrompt`(附加到刷新轮次的额外系统提示词) +- `prompt`(用于 flush 轮次的用户消息) +- `systemPrompt`(附加到 flush 轮次的额外系统提示词) 说明: -- 默认的 prompt/system prompt 包含一个 `NO_REPLY` 提示,用于抑制 - 交付。 -- 每个压缩周期只运行一次刷新(在 `sessions.json` 中跟踪)。 -- 刷新仅对嵌入式 Pi 会话运行。 -- 当会话工作区为只读(`workspaceAccess: "ro"` 或 `"none"`)时,会跳过刷新。 +- 默认 prompt / system prompt 包含 `NO_REPLY` 提示,以抑制 + 发送。 +- 每个压缩周期只运行一次 flush(记录在 `sessions.json` 中)。 +- Flush 仅对嵌入式 Pi 会话运行(CLI 后端会跳过)。 +- 当会话工作区为只读时会跳过 flush(`workspaceAccess: "ro"` 或 `"none"`)。 - 关于工作区文件布局和写入模式,请参见 [Memory](/zh-CN/concepts/memory)。 -Pi 在扩展 API 中也暴露了一个 `session_before_compact` hook,但 OpenClaw 的 -刷新逻辑目前位于 Gateway 网关侧。 +Pi 也会在扩展 API 中暴露一个 `session_before_compact` hook,但 OpenClaw 的 +flush 逻辑目前位于 Gateway 网关 侧。 --- -## 故障排除检查清单 +## 故障排除清单 - 会话键不对?从 [/concepts/session](/zh-CN/concepts/session) 开始,并在 `/status` 中确认 `sessionKey`。 -- 存储与转录不匹配?确认 Gateway 网关主机和 `openclaw status` 显示的存储路径。 -- 压缩过于频繁?检查: - - 模型上下文窗口(是否过小) - - 压缩设置(对于模型窗口而言,`reserveTokens` 过高会导致更早压缩) - - 工具结果膨胀:启用/调整会话裁剪 -- 静默轮次泄露了输出?确认回复以 `NO_REPLY` 开头(大小写不敏感的精确 token),并且你使用的是包含流式传输抑制修复的构建版本。 +- 存储与 transcript 不匹配?确认 Gateway 网关 主机,以及 `openclaw status` 中的存储路径。 +- 压缩刷屏?检查: + - 模型上下文窗口(是否太小) + - 压缩设置(对于模型窗口来说,`reserveTokens` 过高会导致更早压缩) + - `toolResult` 膨胀:启用 / 调整会话裁剪 +- 静默轮次泄露了输出?确认回复以 `NO_REPLY` 开头(大小写不敏感的精确 token),并且你使用的是包含流式抑制修复的构建版本。 diff --git a/docs/zh-CN/tools/acp-agents.md b/docs/zh-CN/tools/acp-agents.md index abc314d01..c5fd8dd30 100644 --- a/docs/zh-CN/tools/acp-agents.md +++ b/docs/zh-CN/tools/acp-agents.md @@ -1,192 +1,198 @@ --- read_when: - 通过 ACP 运行编码 harness - - 在消息渠道上设置绑定到会话的 ACP 会话 - - 将消息渠道会话绑定到持久化 ACP 会话 + - 在消息渠道上设置绑定到对话的 ACP 会话 + - 将一个消息渠道对话绑定到持久化 ACP 会话 - 排查 ACP 后端和插件接线问题 - - 从聊天中操作 /acp 命令 -summary: 通过 ACP 运行时会话使用 Codex、Claude Code、Cursor、Gemini CLI、OpenClaw ACP 及其他 harness 智能体 + - 通过聊天操作 `/acp` 命令 +summary: 将 ACP 运行时会话用于 Codex、Claude Code、Cursor、Gemini CLI、OpenClaw ACP 和其他 harness 智能体 title: ACP 智能体 x-i18n: - generated_at: "2026-04-05T18:16:39Z" + generated_at: "2026-04-06T12:46:15Z" model: gpt-5.4 provider: openai - source_hash: 302f3fe25b1ffe0576592b6e0ad9e8a5781fa5702b31d508d9ba8908f7df33bd + source_hash: fb651ab39b05e537398623ee06cb952a5a07730fc75d3f7e0de20dd3128e72c6 source_path: tools/acp-agents.md workflow: 15 --- # ACP 智能体 -[Agent Client Protocol(ACP)](https://agentclientprotocol.com/) 会话让 OpenClaw 能够通过 ACP 后端插件运行外部编码 harness(例如 Pi、Claude Code、Codex、Cursor、Copilot、OpenClaw ACP、OpenCode、Gemini CLI,以及其他受支持的 ACPX harness)。 +[Agent Client Protocol (ACP)](https://agentclientprotocol.com/) 会话让 OpenClaw 能够通过 ACP 后端插件运行外部编码 harness(例如 Pi、Claude Code、Codex、Cursor、Copilot、OpenClaw ACP、OpenCode、Gemini CLI 以及其他受支持的 ACPX harness)。 -如果你用自然语言要求 OpenClaw “在 Codex 中运行这个”或“在一个线程中启动 Claude Code”,OpenClaw 应该把该请求路由到 ACP 运行时(而不是原生子智能体运行时)。每次 ACP 会话生成都会被跟踪为一个[后台任务](/zh-CN/automation/tasks)。 +如果你用自然语言要求 OpenClaw “在 Codex 里运行这个”或“在线程里启动 Claude Code”,OpenClaw 应该将该请求路由到 ACP 运行时(而不是原生子智能体运行时)。每次 ACP 会话启动都会被跟踪为一个[后台任务](/zh-CN/automation/tasks)。 -如果你希望 Codex 或 Claude Code 作为外部 MCP 客户端直接连接到现有的 OpenClaw 渠道会话,请使用 [`openclaw mcp serve`](/cli/mcp),而不是 ACP。 +如果你想让 Codex 或 Claude Code 作为外部 MCP 客户端直接连接 +到现有 OpenClaw 渠道对话,请使用 [`openclaw mcp serve`](/cli/mcp) +而不是 ACP。 -## 我需要哪个页面? +## 我该看哪个页面? -这里有三个相近的功能面,很容易混淆: +这里有三个相近但很容易混淆的界面: | 你想要... | 使用这个 | 说明 | -| ---------------------------------------------------------------------------------- | -------------------------- | ----------------------------------------------------------------------------------------------------------- | +| ---------------------------------------------------------------------------------- | ------------------------------------- | ----------------------------------------------------------------------------------------------------------- | | 通过 OpenClaw 运行 Codex、Claude Code、Gemini CLI 或其他外部 harness | 本页:ACP 智能体 | 聊天绑定会话、`/acp spawn`、`sessions_spawn({ runtime: "acp" })`、后台任务、运行时控制 | -| 将 OpenClaw Gateway 网关会话作为 ACP 服务器暴露给编辑器或客户端 | [`openclaw acp`](/cli/acp) | 桥接模式。IDE/客户端 通过 stdio/WebSocket 与 OpenClaw 进行 ACP 通信 | +| 将一个 OpenClaw Gateway 网关会话作为 ACP 服务器暴露给编辑器或客户端 | [`openclaw acp`](/cli/acp) | 桥接模式。IDE/客户端 通过 stdio/WebSocket 与 OpenClaw 使用 ACP 通信 | +| 将本地 AI CLI 复用为纯文本回退模型 | [CLI Backends](/gateway/cli-backends) | 不是 ACP。没有 OpenClaw 工具、没有 ACP 控制、没有 harness 运行时 | -## 这可以开箱即用吗? +## 开箱即用吗? 通常可以。 -- 全新安装现在默认启用内置的 `acpx` 运行时插件。 -- 内置 `acpx` 插件会优先使用其插件本地固定版本的 `acpx` 二进制文件。 -- 启动时,OpenClaw 会探测该二进制文件,并在需要时自我修复。 -- 如果你想快速检查就绪状态,请先从 `/acp doctor` 开始。 +- 全新安装现在默认启用了内置的 `acpx` 运行时插件。 +- 内置的 `acpx` 插件会优先使用其插件本地固定版本的 `acpx` 二进制文件。 +- 启动时,OpenClaw 会探测该二进制文件,并在需要时自行修复。 +- 如果你想快速检查是否就绪,请先运行 `/acp doctor`。 首次使用时仍然可能发生的情况: -- 第一次使用某个 harness 时,目标 harness 适配器可能会按需通过 `npx` 获取。 -- 该 harness 的供应商认证仍然必须已存在于主机上。 -- 如果主机没有 npm/网络访问权限,首次运行的适配器获取可能会失败,直到缓存被预热或适配器通过其他方式安装。 +- 目标 harness 适配器可能会在你第一次使用该 harness 时按需通过 `npx` 拉取。 +- 该 harness 对应的厂商凭证仍然必须存在于主机上。 +- 如果主机没有 npm/网络访问能力,首次运行的适配器拉取可能会失败,直到缓存预热完成或适配器通过其他方式安装。 示例: -- `/acp spawn codex`:OpenClaw 应已准备好引导 `acpx`,但 Codex ACP 适配器仍可能需要首次运行获取。 -- `/acp spawn claude`:Claude ACP 适配器也是同样情况,另外该主机上还需要 Claude 侧认证。 +- `/acp spawn codex`:OpenClaw 应该已经可以引导 `acpx`,但 Codex ACP 适配器仍可能需要首次运行时拉取。 +- `/acp spawn claude`:Claude ACP 适配器也是同样情况,另外还需要该主机上存在 Claude 侧凭证。 -## 面向操作员的快速流程 +## 面向操作者的快速流程 -当你想要一份实用的 `/acp` 操作手册时,请使用这个流程: +如果你想要一个实用的 `/acp` 操作手册,请使用这个流程: -1. 生成一个会话: +1. 启动一个会话: - `/acp spawn codex --bind here` - `/acp spawn codex --mode persistent --thread auto` -2. 在绑定的会话或线程中工作(或显式指定该会话键)。 +2. 在已绑定的对话或线程中工作(或者显式指定该会话键)。 3. 检查运行时状态: - `/acp status` 4. 按需调整运行时选项: - `/acp model ` - `/acp permissions ` - `/acp timeout ` -5. 在不替换上下文的情况下推动一个活跃会话: +5. 在不替换上下文的情况下推动一个活动会话继续前进: - `/acp steer tighten logging and continue` 6. 停止工作: - - `/acp cancel`(停止当前轮次),或 - - `/acp close`(关闭会话 + 移除绑定) + - `/acp cancel`(停止当前轮次),或者 + - `/acp close`(关闭会话并移除绑定) -## 面向人工用户的快速开始 +## 面向普通用户的快速开始 自然语言请求示例: -- “将这个 Discord 渠道绑定到 Codex。” -- “在这里的一个线程中启动一个持久化 Codex 会话,并保持聚焦。” -- “将这个作为一次性 Claude Code ACP 会话运行,并总结结果。” -- “将这个 iMessage 聊天绑定到 Codex,并让后续消息保持在同一个工作区。” -- “在一个线程中用 Gemini CLI 处理这个任务,然后让后续消息继续留在同一个线程中。” +- “把这个 Discord 渠道绑定到 Codex。” +- “在这里的一个线程里启动一个持久的 Codex 会话,并保持它专注。” +- “把这个作为一次性 Claude Code ACP 会话运行,并总结结果。” +- “把这个 iMessage 聊天绑定到 Codex,并让后续消息继续在同一个工作区中处理。” +- “在这个任务中使用 Gemini CLI 并放在线程里,然后让后续消息继续在同一个线程中处理。” -OpenClaw 应执行的操作: +OpenClaw 应该执行的操作: 1. 选择 `runtime: "acp"`。 -2. 解析请求的 harness 目标(`agentId`,例如 `codex`)。 -3. 如果请求绑定当前会话,并且当前活跃渠道支持此功能,则将 ACP 会话绑定到该会话。 -4. 否则,如果请求线程绑定,并且当前渠道支持此功能,则将 ACP 会话绑定到该线程。 -5. 将后续绑定消息继续路由到同一个 ACP 会话,直到失焦/关闭/过期。 +2. 解析所请求的 harness 目标(`agentId`,例如 `codex`)。 +3. 如果请求了当前对话绑定,且当前活动渠道支持该能力,则将 ACP 会话绑定到该对话。 +4. 否则,如果请求了线程绑定,且当前渠道支持该能力,则将 ACP 会话绑定到该线程。 +5. 将后续已绑定消息路由到同一个 ACP 会话,直到取消聚焦、关闭或过期。 -## ACP 与子智能体 +## ACP 与子智能体的区别 -如果你想要外部 harness 运行时,请使用 ACP。如果你想要 OpenClaw 原生委托运行,请使用子智能体。 +如果你想要外部 harness 运行时,请使用 ACP。如果你想要 OpenClaw 原生委派运行,请使用子智能体。 | 区域 | ACP 会话 | 子智能体运行 | | ------------- | ------------------------------------- | ---------------------------------- | | 运行时 | ACP 后端插件(例如 acpx) | OpenClaw 原生子智能体运行时 | | 会话键 | `agent::acp:` | `agent::subagent:` | | 主要命令 | `/acp ...` | `/subagents ...` | -| 生成工具 | `sessions_spawn` 搭配 `runtime:"acp"` | `sessions_spawn`(默认运行时) | +| 启动工具 | `sessions_spawn` 搭配 `runtime:"acp"` | `sessions_spawn`(默认运行时) | 另请参见 [Sub-agents](/zh-CN/tools/subagents)。 ## ACP 如何运行 Claude Code -对于通过 ACP 运行的 Claude Code,堆栈如下: +对于通过 ACP 运行的 Claude Code,栈结构如下: 1. OpenClaw ACP 会话控制平面 -2. 内置 `acpx` 运行时插件 +2. 内置的 `acpx` 运行时插件 3. Claude ACP 适配器 4. Claude 侧运行时/会话机制 重要区别: -- ACP Claude 是一个 harness 会话,具备 ACP 控制、会话恢复、后台任务跟踪,以及可选的会话/线程绑定。 - 对操作员来说,实用规则是: +- ACP Claude 是一个具有 ACP 控制、会话恢复、后台任务跟踪以及可选对话/线程绑定的 harness 会话。 +- CLI 后端是独立的纯文本本地回退运行时。请参见 [CLI Backends](/gateway/cli-backends)。 -- 想要 `/acp spawn`、可绑定会话、运行时控制或持久化 harness 工作:请使用 ACP +对于操作者来说,实用规则如下: -## 绑定会话 +- 如果你想要 `/acp spawn`、可绑定会话、运行时控制或持久化 harness 工作:使用 ACP +- 如果你只想通过原始 CLI 获得简单的本地文本回退:使用 CLI 后端 -### 当前会话绑定 +## 已绑定会话 -当你希望当前会话成为一个持久的 ACP 工作区,而不创建子线程时,请使用 `/acp spawn --bind here`。 +### 当前对话绑定 -行为: +当你希望当前对话成为一个持久的 ACP 工作区,而不创建子线程时,请使用 `/acp spawn --bind here`。 -- OpenClaw 继续拥有渠道传输、认证、安全和消息投递。 -- 当前会话会被固定到已生成的 ACP 会话键。 -- 该会话中的后续消息会被路由到同一个 ACP 会话。 -- `/new` 和 `/reset` 会在原地重置同一个已绑定的 ACP 会话。 -- `/acp close` 会关闭会话并移除当前会话绑定。 +行为如下: -这在实践中的含义: +- OpenClaw 继续负责渠道传输、凭证、安全和消息投递。 +- 当前对话会固定到已启动的 ACP 会话键。 +- 该对话中的后续消息会路由到同一个 ACP 会话。 +- `/new` 和 `/reset` 会就地重置同一个已绑定的 ACP 会话。 +- `/acp close` 会关闭会话并移除当前对话绑定。 -- `--bind here` 会保持同一个聊天界面。在 Discord 上,当前渠道仍然是当前渠道。 -- `--bind here` 在你生成全新工作时仍然可以创建一个新的 ACP 会话。该绑定会把该会话附加到当前会话。 -- `--bind here` 本身不会创建子 Discord 线程或 Telegram 话题。 -- ACP 运行时仍然可以拥有自己的工作目录(`cwd`)或后端管理的磁盘工作区。该运行时工作区与聊天界面是分离的,并不意味着会新建消息线程。 -- 如果你生成到另一个 ACP 智能体且没有传入 `--cwd`,OpenClaw 默认会继承**目标智能体的**工作区,而不是请求方的工作区。 -- 如果继承的工作区路径缺失(`ENOENT`/`ENOTDIR`),OpenClaw 会回退到后端默认 cwd,而不是默默复用错误的目录树。 -- 如果继承的工作区存在但无法访问(例如 `EACCES`),生成操作会返回真实的访问错误,而不是丢弃 `cwd`。 +其实际含义: -心智模型: +- `--bind here` 会保留相同的聊天界面。在 Discord 上,当前渠道仍然是当前渠道。 +- `--bind here` 在你启动新工作时仍然可以创建一个新的 ACP 会话。该绑定会将该会话附加到当前对话。 +- `--bind here` 本身不会创建子 Discord 线程或 Telegram 主题。 +- ACP 运行时仍然可以拥有自己的工作目录(`cwd`)或由后端管理的磁盘工作区。该运行时工作区与聊天界面分离,并不意味着会创建新的消息线程。 +- 如果你启动到另一个 ACP 智能体,并且没有传入 `--cwd`,OpenClaw 默认会继承**目标智能体的**工作区,而不是请求方的工作区。 +- 如果继承的工作区路径不存在(`ENOENT`/`ENOTDIR`),OpenClaw 会回退到后端默认 cwd,而不是静默复用错误的目录树。 +- 如果继承的工作区存在但无法访问(例如 `EACCES`),启动会返回真实的访问错误,而不是丢弃 `cwd`。 -- 聊天界面:人们继续交谈的地方(`Discord channel`、`Telegram topic`、`iMessage chat`) -- ACP 会话:OpenClaw 路由到的持久化 Codex/Claude/Gemini 运行时状态 -- 子线程/话题:仅在 `--thread ...` 时创建的可选额外消息界面 -- 运行时工作区:harness 运行所在的文件系统位置(`cwd`、仓库检出、后端工作区) +思维模型: + +- 聊天界面:人们继续交流的地方(`Discord channel`、`Telegram topic`、`iMessage chat`) +- ACP 会话:OpenClaw 路由到的持久 Codex/Claude/Gemini 运行时状态 +- 子线程/主题:仅在使用 `--thread ...` 时创建的可选额外消息界面 +- 运行时工作区:harness 运行所在的文件系统位置(`cwd`、仓库检出目录、后端工作区) 示例: -- `/acp spawn codex --bind here`:保留当前聊天,生成或附加一个 Codex ACP 会话,并将此处后续消息路由到它 -- `/acp spawn codex --thread auto`:OpenClaw 可能创建一个子线程/话题,并将 ACP 会话绑定到那里 +- `/acp spawn codex --bind here`:保留当前聊天,启动或附加一个 Codex ACP 会话,并将未来消息路由给它 +- `/acp spawn codex --thread auto`:OpenClaw 可能会创建一个子线程/主题,并将 ACP 会话绑定到那里 - `/acp spawn codex --bind here --cwd /workspace/repo`:与上面相同的聊天绑定,但 Codex 在 `/workspace/repo` 中运行 -当前会话绑定支持: +当前对话绑定支持: -- 声明支持当前会话绑定的聊天/消息渠道可以通过共享会话绑定路径使用 `--bind here`。 -- 具有自定义线程/话题语义的渠道仍可在相同共享接口之后提供渠道特定的规范化。 -- `--bind here` 始终表示“原地绑定当前会话”。 -- 通用当前会话绑定使用共享的 OpenClaw 绑定存储,并可在正常 Gateway 网关重启后保留。 +- 声明支持当前对话绑定的聊天/消息渠道可以通过共享对话绑定路径使用 `--bind here`。 +- 具有自定义线程/主题语义的渠道仍然可以在同一共享接口后提供渠道特定的规范化。 +- `--bind here` 始终表示“就地绑定当前对话”。 +- 通用的当前对话绑定使用共享的 OpenClaw 绑定存储,并且在 Gateway 网关正常重启后仍然保留。 说明: -- 在 `/acp spawn` 中,`--bind here` 与 `--thread ...` 互斥。 -- 在 Discord 上,`--bind here` 会原地绑定当前渠道或线程。只有当 OpenClaw 需要为 `--thread auto|here` 创建子线程时,才需要 `spawnAcpSessions`。 -- 如果活跃渠道不暴露当前会话 ACP 绑定,OpenClaw 会返回清晰的不支持消息。 -- `resume` 和“新建会话”问题是 ACP 会话问题,不是渠道问题。你可以复用或替换运行时状态,而无需更改当前聊天界面。 +- 在 `/acp spawn` 上,`--bind here` 与 `--thread ...` 互斥。 +- 在 Discord 上,`--bind here` 会就地绑定当前渠道或线程。只有当 OpenClaw 需要为 `--thread auto|here` 创建子线程时,才需要 `spawnAcpSessions`。 +- 如果当前活动渠道不支持当前对话 ACP 绑定,OpenClaw 会返回明确的不支持消息。 +- `resume` 和“新会话”问题是 ACP 会话问题,而不是渠道问题。你可以在不改变当前聊天界面的前提下复用或替换运行时状态。 ### 线程绑定会话 当某个渠道适配器启用了线程绑定时,ACP 会话可以绑定到线程: - OpenClaw 将一个线程绑定到目标 ACP 会话。 -- 该线程中的后续消息会被路由到已绑定的 ACP 会话。 -- ACP 输出会回送到同一个线程。 -- 失焦/关闭/归档/空闲超时或最长存活时间到期会移除绑定。 +- 该线程中的后续消息会路由到已绑定的 ACP 会话。 +- ACP 输出会回传到同一个线程。 +- 取消聚焦/关闭/归档/空闲超时或最大时长到期后,绑定会被移除。 -线程绑定支持取决于适配器。如果当前活跃渠道适配器不支持线程绑定,OpenClaw 会返回清晰的不支持/不可用消息。 +线程绑定支持是适配器特定的。如果当前渠道适配器不支持线程绑定,OpenClaw 会返回明确的不支持/不可用消息。 -线程绑定 ACP 所需功能开关: +线程绑定 ACP 所需的功能开关: - `acp.enabled=true` - `acp.dispatch.enabled` 默认开启(设为 `false` 可暂停 ACP 分发) -- 渠道适配器 ACP 线程生成开关已启用(特定于适配器) +- 启用渠道适配器的 ACP 线程启动开关(适配器特定) - Discord:`channels.discord.threadBindings.spawnAcpSessions=true` - Telegram:`channels.telegram.threadBindings.spawnAcpSessions=true` @@ -195,8 +201,8 @@ OpenClaw 应执行的操作: - 任何暴露会话/线程绑定能力的渠道适配器。 - 当前内置支持: - Discord 线程/渠道 - - Telegram 话题(群组/超级群组中的论坛话题和私信话题) -- 插件渠道也可以通过相同绑定接口增加支持。 + - Telegram 主题(群组/超级群组中的论坛主题和私信主题) +- 渠道插件可以通过同一绑定接口添加支持。 ## 渠道特定设置 @@ -204,16 +210,16 @@ OpenClaw 应执行的操作: ### 绑定模型 -- `bindings[].type="acp"` 表示持久化 ACP 会话绑定。 -- `bindings[].match` 标识目标会话: +- `bindings[].type="acp"` 将其标记为一个持久化 ACP 对话绑定。 +- `bindings[].match` 用于标识目标对话: - Discord 渠道或线程:`match.channel="discord"` + `match.peer.id=""` - - Telegram 论坛话题:`match.channel="telegram"` + `match.peer.id=":topic:"` - - BlueBubbles 私信/群聊:`match.channel="bluebubbles"` + `match.peer.id=""` + - Telegram 论坛主题:`match.channel="telegram"` + `match.peer.id=":topic:"` + - BlueBubbles 私信/群聊:`match.channel="bluebubbles"` + `match.peer.id=""` 对于稳定的群组绑定,优先使用 `chat_id:*` 或 `chat_identifier:*`。 - - iMessage 私信/群聊:`match.channel="imessage"` + `match.peer.id=""` + - iMessage 私信/群聊:`match.channel="imessage"` + `match.peer.id=""` 对于稳定的群组绑定,优先使用 `chat_id:*`。 -- `bindings[].agentId` 是所属的 OpenClaw 智能体 ID。 -- 可选 ACP 覆盖位于 `bindings[].acp` 下: +- `bindings[].agentId` 是拥有该绑定的 OpenClaw 智能体 id。 +- 可选的 ACP 覆盖位于 `bindings[].acp` 下: - `mode`(`persistent` 或 `oneshot`) - `label` - `cwd` @@ -224,7 +230,7 @@ OpenClaw 应执行的操作: 使用 `agents.list[].runtime` 为每个智能体一次性定义 ACP 默认值: - `agents.list[].runtime.type="acp"` -- `agents.list[].runtime.acp.agent`(harness ID,例如 `codex` 或 `claude`) +- `agents.list[].runtime.acp.agent`(harness id,例如 `codex` 或 `claude`) - `agents.list[].runtime.acp.backend` - `agents.list[].runtime.acp.mode` - `agents.list[].runtime.acp.cwd` @@ -317,18 +323,18 @@ ACP 绑定会话的覆盖优先级: 行为: -- OpenClaw 会在使用前确保配置的 ACP 会话存在。 -- 该渠道或话题中的消息会被路由到已配置的 ACP 会话。 -- 在已绑定会话中,`/new` 和 `/reset` 会原地重置同一个 ACP 会话键。 +- OpenClaw 会在使用前确保已配置的 ACP 会话存在。 +- 该渠道或主题中的消息会路由到已配置的 ACP 会话。 +- 在已绑定对话中,`/new` 和 `/reset` 会就地重置同一个 ACP 会话键。 - 临时运行时绑定(例如由线程聚焦流程创建的绑定)在存在时仍会生效。 -- 对于没有显式 `cwd` 的跨智能体 ACP 生成,OpenClaw 会从智能体配置继承目标智能体工作区。 -- 缺失的继承工作区路径会回退到后端默认 cwd;非缺失的访问失败会作为生成错误暴露出来。 +- 对于未显式指定 `cwd` 的跨智能体 ACP 启动,OpenClaw 会从智能体配置继承目标智能体工作区。 +- 缺失的继承工作区路径会回退到后端默认 cwd;非缺失的访问失败则会作为启动错误暴露出来。 ## 启动 ACP 会话(接口) ### 从 `sessions_spawn` 启动 -使用 `runtime: "acp"` 可从智能体轮次或工具调用中启动 ACP 会话。 +使用 `runtime: "acp"` 从一个智能体轮次或工具调用中启动 ACP 会话。 ```json { @@ -342,29 +348,29 @@ ACP 绑定会话的覆盖优先级: 说明: -- `runtime` 默认为 `subagent`,因此对于 ACP 会话需要显式设置 `runtime: "acp"`。 -- 如果省略 `agentId`,OpenClaw 会在配置了 `acp.defaultAgent` 时使用它。 -- `mode: "session"` 需要 `thread: true` 才能保持一个持久化绑定会话。 +- `runtime` 默认为 `subagent`,因此对于 ACP 会话请显式设置 `runtime: "acp"`。 +- 如果省略 `agentId`,OpenClaw 会在已配置时使用 `acp.defaultAgent`。 +- `mode: "session"` 需要 `thread: true` 才能保留一个持久的已绑定对话。 -接口详情: +接口细节: -- `task`(必填):发送到 ACP 会话的初始提示。 -- `runtime`(ACP 必填):必须为 `"acp"`。 -- `agentId`(可选):ACP 目标 harness ID。如果设置了 `acp.defaultAgent`,则回退到它。 +- `task`(必需):发送到 ACP 会话的初始提示词。 +- `runtime`(ACP 必需):必须为 `"acp"`。 +- `agentId`(可选):ACP 目标 harness id。如果已设置,则会回退到 `acp.defaultAgent`。 - `thread`(可选,默认 `false`):在支持时请求线程绑定流程。 - `mode`(可选):`run`(一次性)或 `session`(持久化)。 - - 默认值为 `run` - - 如果 `thread: true` 且省略 mode,OpenClaw 可能按运行时路径默认使用持久化行为 + - 默认为 `run` + - 如果 `thread: true` 且省略 `mode`,OpenClaw 可能会根据运行时路径默认采用持久化行为 - `mode: "session"` 需要 `thread: true` -- `cwd`(可选):请求的运行时工作目录(由后端/运行时策略验证)。如果省略,ACP 生成会在配置时继承目标智能体工作区;缺失的继承路径会回退到后端默认值,而真实访问错误会被返回。 -- `label`(可选):用于会话/横幅文本中的面向操作员标签。 -- `resumeSessionId`(可选):恢复一个现有 ACP 会话,而不是新建会话。该智能体会通过 `session/load` 重放其会话历史。需要 `runtime: "acp"`。 -- `streamTo`(可选):`"parent"` 会将初始 ACP 运行进度摘要作为系统事件流式返回给请求方会话。 - - 可用时,接受的响应可包含 `streamLogPath`,指向一个作用域为该会话的 JSONL 日志(`.acp-stream.jsonl`),你可以对其执行 tail 以查看完整转发历史。 +- `cwd`(可选):请求的运行时工作目录(由后端/运行时策略校验)。如果省略,在已配置时 ACP 启动会继承目标智能体工作区;缺失的继承路径会回退到后端默认值,而真实访问错误会被返回。 +- `label`(可选):用于会话/横幅文本中的面向操作者的标签。 +- `resumeSessionId`(可选):恢复一个现有 ACP 会话,而不是创建新会话。智能体会通过 `session/load` 重放其对话历史。需要 `runtime: "acp"`。 +- `streamTo`(可选):`"parent"` 会将初始 ACP 运行进度摘要以系统事件形式流式返回给请求方会话。 + - 在可用时,接受的响应中会包含 `streamLogPath`,指向一个按会话划分的 JSONL 日志(`.acp-stream.jsonl`),你可以对其执行 tail 以查看完整中继历史。 ### 恢复现有会话 -使用 `resumeSessionId` 继续先前的 ACP 会话,而不是重新开始。该智能体会通过 `session/load` 重放其会话历史,因此它会带着之前的完整上下文继续。 +使用 `resumeSessionId` 可以继续之前的 ACP 会话,而不是重新开始。智能体会通过 `session/load` 重放其对话历史,因此它会带着之前的完整上下文继续执行。 ```json { @@ -375,40 +381,43 @@ ACP 绑定会话的覆盖优先级: } ``` -常见用例: +常见使用场景: -- 将一个 Codex 会话从你的笔记本电脑切换到手机 —— 告诉你的智能体从你离开的地方继续 -- 继续一个你先前在 CLI 中以交互方式启动、现在通过智能体以无头方式继续的编码会话 -- 接着处理一个因 Gateway 网关重启或空闲超时而中断的工作 +- 将一个 Codex 会话从你的笔记本电脑交接到手机上 —— 告诉你的智能体从上次中断处继续 +- 继续一个你之前在 CLI 中交互式启动、现在要通过智能体无头运行的编码会话 +- 继续因 Gateway 网关重启或空闲超时而中断的工作 说明: - `resumeSessionId` 需要 `runtime: "acp"` —— 如果与子智能体运行时一起使用,会返回错误。 -- `resumeSessionId` 会恢复上游 ACP 会话历史;`thread` 和 `mode` 仍会正常应用到你正在创建的新 OpenClaw 会话,因此 `mode: "session"` 仍然需要 `thread: true`。 +- `resumeSessionId` 会恢复上游 ACP 对话历史;`thread` 和 `mode` 仍会正常应用于你正在创建的新 OpenClaw 会话,因此 `mode: "session"` 仍然需要 `thread: true`。 - 目标智能体必须支持 `session/load`(Codex 和 Claude Code 支持)。 -- 如果找不到该会话 ID,生成会以清晰错误失败 —— 不会静默回退为新会话。 +- 如果找不到该会话 id,启动会返回明确错误 —— 不会静默回退为新会话。 -### 面向操作员的 smoke 测试 +### 面向操作者的冒烟测试 -当你在 Gateway 网关部署后想进行一次快速 live 检查,确认 ACP 生成确实在端到端工作,而不只是通过了单元测试时,请使用这个流程。 +当你在 Gateway 网关部署后想快速进行一次在线检查,以确认 ACP 启动 +在端到端上确实可用,而不仅仅是通过了单元测试时,请使用这个方法。 -推荐门槛: +推荐 gate: 1. 在目标主机上验证已部署的 Gateway 网关版本/提交。 -2. 确认已部署源码在 `src/gateway/sessions-patch.ts` 中包含 ACP 血统接受逻辑(`subagent:* or acp:* sessions`)。 -3. 打开一个到 live 智能体的临时 ACPX 桥接会话(例如 `jpclawhq` 上的 `razor(main)`)。 -4. 要求该智能体调用 `sessions_spawn`,参数为: +2. 确认已部署源码在 + `src/gateway/sessions-patch.ts` 中包含 ACP 血缘接受逻辑(`subagent:* or acp:* sessions`)。 +3. 打开一个临时 ACPX 桥接会话,连接到一个在线智能体(例如 + `jpclawhq` 上的 `razor(main)`)。 +4. 要求该智能体使用以下参数调用 `sessions_spawn`: - `runtime: "acp"` - `agentId: "codex"` - `mode: "run"` - task:`Reply with exactly LIVE-ACP-SPAWN-OK` -5. 验证该智能体报告: +5. 验证该智能体报告了: - `accepted=yes` - 一个真实的 `childSessionKey` - 没有校验器错误 6. 清理该临时 ACPX 桥接会话。 -发送给 live 智能体的提示示例: +给在线智能体的示例提示词: ```text Use the sessions_spawn tool now with runtime: "acp", agentId: "codex", and mode: "run". @@ -418,26 +427,29 @@ Then report only: accepted=; childSessionKey=; error=` | +| `/acp cancel` | 取消目标会话当前进行中的轮次。 | `/acp cancel agent:codex:acp:` | | `/acp steer` | 向正在运行的会话发送引导指令。 | `/acp steer --session support inbox prioritize failing tests` | | `/acp close` | 关闭会话并解除线程目标绑定。 | `/acp close` | | `/acp status` | 显示后端、模式、状态、运行时选项、能力。 | `/acp status` | | `/acp set-mode` | 为目标会话设置运行时模式。 | `/acp set-mode plan` | -| `/acp set` | 写入通用运行时配置选项。 | `/acp set model openai/gpt-5.4` | +| `/acp set` | 通用运行时配置选项写入。 | `/acp set model openai/gpt-5.4` | | `/acp cwd` | 设置运行时工作目录覆盖值。 | `/acp cwd /Users/user/Projects/repo` | -| `/acp permissions` | 设置审批策略配置档。 | `/acp permissions strict` | +| `/acp permissions` | 设置批准策略配置。 | `/acp permissions strict` | | `/acp timeout` | 设置运行时超时(秒)。 | `/acp timeout 120` | | `/acp model` | 设置运行时模型覆盖值。 | `/acp model anthropic/claude-opus-4-6` | -| `/acp reset-options` | 移除会话运行时选项覆盖。 | `/acp reset-options` | +| `/acp reset-options` | 移除会话运行时选项覆盖值。 | `/acp reset-options` | | `/acp sessions` | 从存储中列出最近的 ACP 会话。 | `/acp sessions` | -| `/acp doctor` | 后端健康状态、能力、可执行修复。 | `/acp doctor` | +| `/acp doctor` | 后端健康状态、能力、可操作修复。 | `/acp doctor` | | `/acp install` | 打印确定性的安装和启用步骤。 | `/acp install` | -`/acp sessions` 会读取当前已绑定会话或请求方会话的存储。接受 `session-key`、`session-id` 或 `session-label` 标记的命令,会通过 Gateway 网关会话发现来解析目标,包括每个智能体自定义的 `session.store` 根目录。 +`/acp sessions` 会读取当前已绑定会话或请求方会话的存储。接受 `session-key`、`session-id` 或 `session-label` 令牌的命令,会通过 Gateway 网关会话发现来解析目标,其中包括自定义的按智能体划分的 `session.store` 根路径。 ## 运行时选项映射 -`/acp` 既有便捷命令,也有通用设置器。 +`/acp` 同时提供便捷命令和通用设置器。 等价操作: - `/acp model ` 映射到运行时配置键 `model`。 - `/acp permissions ` 映射到运行时配置键 `approval_policy`。 - `/acp timeout ` 映射到运行时配置键 `timeout`。 -- `/acp cwd ` 会直接更新运行时 cwd 覆盖值。 +- `/acp cwd ` 直接更新运行时 cwd 覆盖值。 - `/acp set ` 是通用路径。 - - 特殊情况:`key=cwd` 使用 cwd 覆盖路径。 + - 特例:`key=cwd` 使用 cwd 覆盖路径。 - `/acp reset-options` 会清除目标会话的所有运行时覆盖值。 ## acpx harness 支持(当前) @@ -586,10 +598,10 @@ ACP 会话当前运行在主机运行时上,而不是 OpenClaw 沙箱内。 - `pi` - `qwen` -当 OpenClaw 使用 acpx 后端时,除非你的 acpx 配置定义了自定义智能体别名,否则应优先将这些值用于 `agentId`。 -如果你本地安装的 Cursor 仍将 ACP 暴露为 `agent acp`,请在你的 acpx 配置中覆盖 `cursor` 智能体命令,而不是更改内置默认值。 +当 OpenClaw 使用 acpx 后端时,除非你的 acpx 配置定义了自定义智能体别名,否则优先将这些值用于 `agentId`。 +如果你的本地 Cursor 安装仍然将 ACP 暴露为 `agent acp`,请在你的 acpx 配置中覆盖 `cursor` 智能体命令,而不是修改内置默认值。 -直接使用 acpx CLI 也可以通过 `--agent ` 定位任意适配器,但这个原始逃生口是 acpx CLI 功能(不是 OpenClaw 正常的 `agentId` 路径)。 +直接使用 acpx CLI 也可以通过 `--agent ` 指向任意适配器,但这个原始逃生口是 acpx CLI 功能(不是正常的 OpenClaw `agentId` 路径)。 ## 必需配置 @@ -599,7 +611,7 @@ ACP 会话当前运行在主机运行时上,而不是 OpenClaw 沙箱内。 { acp: { enabled: true, - // 可选。默认是 true;设为 false 可暂停 ACP 分发,同时保留 /acp 控制。 + // 可选。默认为 true;设为 false 可暂停 ACP 分发,同时保留 /acp 控制。 dispatch: { enabled: true }, backend: "acpx", defaultAgent: "codex", @@ -631,7 +643,7 @@ ACP 会话当前运行在主机运行时上,而不是 OpenClaw 沙箱内。 } ``` -线程绑定配置取决于渠道适配器。Discord 示例: +线程绑定配置是渠道适配器特定的。Discord 示例: ```json5 { @@ -653,25 +665,27 @@ ACP 会话当前运行在主机运行时上,而不是 OpenClaw 沙箱内。 } ``` -如果线程绑定的 ACP 生成无法工作,请先验证适配器功能开关: +如果线程绑定 ACP 启动不起作用,请先验证适配器功能开关: - Discord:`channels.discord.threadBindings.spawnAcpSessions=true` -当前会话绑定不需要创建子线程。它们需要一个活跃会话上下文,以及一个暴露 ACP 会话绑定的渠道适配器。 +当前对话绑定不需要创建子线程。它们需要一个活动对话上下文,以及一个暴露 ACP 对话绑定能力的渠道适配器。 请参见 [Configuration Reference](/zh-CN/gateway/configuration-reference)。 ## acpx 后端的插件设置 -全新安装默认启用内置 `acpx` 运行时插件,因此 ACP 通常无需手动安装插件即可工作。 +全新安装默认启用了内置的 `acpx` 运行时插件,因此 ACP +通常无需手动安装插件即可使用。 -请先执行: +先从这里开始: ```text /acp doctor ``` -如果你禁用了 `acpx`、通过 `plugins.allow` / `plugins.deny` 拒绝了它,或者想切换到本地开发检出,请使用显式插件路径: +如果你禁用了 `acpx`、通过 `plugins.allow` / `plugins.deny` 拒绝了它,或者 +想切换到本地开发检出版本,请使用显式插件路径: ```bash openclaw plugins install acpx @@ -692,12 +706,12 @@ openclaw plugins install ./path/to/local/acpx-plugin ### acpx 命令和版本配置 -默认情况下,内置 acpx 后端插件(`acpx`)使用插件本地固定版本的二进制文件: +默认情况下,内置的 acpx 后端插件(`acpx`)使用插件本地固定版本的二进制文件: -1. 命令默认指向 ACPX 插件包中的插件本地 `node_modules/.bin/acpx`。 -2. 预期版本默认采用扩展固定版本。 -3. 启动时立即将 ACP 后端注册为未就绪。 -4. 一个后台 ensure 作业会验证 `acpx --version`。 +1. 命令默认指向 ACPX 插件包内插件本地的 `node_modules/.bin/acpx`。 +2. 预期版本默认使用扩展固定版本。 +3. 启动时会立即将 ACP 后端注册为未就绪。 +4. 一个后台确保任务会验证 `acpx --version`。 5. 如果插件本地二进制文件缺失或版本不匹配,它会运行: `npm install --omit=dev --no-save acpx@`,然后重新验证。 @@ -722,51 +736,59 @@ openclaw plugins install ./path/to/local/acpx-plugin 说明: - `command` 接受绝对路径、相对路径或命令名(`acpx`)。 -- 相对路径从 OpenClaw 工作区目录解析。 +- 相对路径相对于 OpenClaw 工作区目录解析。 - `expectedVersion: "any"` 会禁用严格版本匹配。 - 当 `command` 指向自定义二进制文件/路径时,插件本地自动安装会被禁用。 -- 在后端健康检查运行期间,OpenClaw 启动仍然是非阻塞的。 +- 后端健康检查运行期间,OpenClaw 启动仍然是非阻塞的。 请参见 [Plugins](/zh-CN/tools/plugin)。 -### 自动依赖安装 +### 自动安装依赖 -当你通过 `npm install -g openclaw` 全局安装 OpenClaw 时,acpx 运行时依赖(平台特定二进制文件)会通过 postinstall hook 自动安装。如果自动安装失败,Gateway 网关仍会正常启动,并通过 `openclaw acp doctor` 报告缺失依赖。 +当你通过 `npm install -g openclaw` 全局安装 OpenClaw 时,acpx +运行时依赖(与平台相关的二进制文件)会通过 postinstall hook 自动安装。 +如果自动安装失败,Gateway 网关 仍会正常启动,并通过 `openclaw acp doctor` 报告缺失依赖。 ### 插件工具 MCP 桥接 -默认情况下,ACPX 会话**不会**向 ACP harness 暴露 OpenClaw 插件注册的工具。 +默认情况下,ACPX 会话**不会**向 +ACP harness 暴露由 OpenClaw 插件注册的工具。 -如果你希望 Codex 或 Claude Code 之类的 ACP 智能体调用已安装的 OpenClaw 插件工具,例如 memory recall/store,请启用专用桥接: +如果你希望 Codex 或 Claude Code 等 ACP 智能体能够调用已安装的 +OpenClaw 插件工具(例如 memory recall/store),请启用专用桥接: ```bash openclaw config set plugins.entries.acpx.config.pluginToolsMcpBridge true ``` -其作用是: +作用如下: -- 将一个名为 `openclaw-plugin-tools` 的内置 MCP 服务器注入到 ACPX 会话引导中。 -- 暴露已安装并启用的 OpenClaw 插件已经注册的插件工具。 -- 保持该功能显式启用,且默认关闭。 +- 在 ACPX 会话 + bootstrap 中注入一个名为 `openclaw-plugin-tools` 的内置 MCP 服务器。 +- 暴露已安装并启用的 OpenClaw + 插件已经注册的插件工具。 +- 使该功能保持为显式启用,且默认关闭。 -安全与信任说明: +安全和信任说明: -- 这会扩展 ACP harness 的工具面。 -- ACP 智能体只能访问 Gateway 网关中已经活跃的插件工具。 -- 应将其视为与允许这些插件在 OpenClaw 本身中执行相同的信任边界。 -- 启用前请检查已安装的插件。 +- 这会扩展 ACP harness 的工具界面。 +- ACP 智能体只能访问 Gateway 网关中已激活的插件工具。 +- 应将这视为与你允许这些插件在 + OpenClaw 本身中执行相同的信任边界。 +- 在启用前,请检查已安装的插件。 -自定义 `mcpServers` 仍和以前一样可用。内置插件工具桥接只是一个额外的可选便利功能,不是通用 MCP 服务器配置的替代品。 +自定义 `mcpServers` 仍然照常可用。内置插件工具桥接是一个 +额外的可选便利功能,而不是通用 MCP 服务器配置的替代品。 ## 权限配置 -ACP 会话以非交互方式运行 —— 没有 TTY 可以批准或拒绝文件写入和 shell 执行权限提示。acpx 插件提供两个控制权限处理方式的配置键: +ACP 会话以非交互方式运行 —— 没有 TTY 可用于批准或拒绝文件写入和 shell 执行权限提示。acpx 插件提供两个配置键来控制权限处理方式: -这些 ACPX harness 权限与 OpenClaw exec 审批分离,也与 CLI 后端供应商绕过标志(例如 Claude CLI `--permission-mode bypassPermissions`)分离。ACPX `approve-all` 是 ACP 会话在 harness 层级的紧急开关。 +这些 ACPX harness 权限与 OpenClaw exec 批准是分离的,也与 CLI 后端的厂商绕过标志(例如 Claude CLI `--permission-mode bypassPermissions`)分离。ACPX 的 `approve-all` 是 ACP 会话在 harness 层面的紧急放开开关。 ### `permissionMode` -控制 harness 智能体在无需提示的情况下可执行哪些操作。 +控制 harness 智能体在不提示的情况下可以执行哪些操作。 | 值 | 行为 | | --------------- | --------------------------------------------------------- | @@ -776,7 +798,7 @@ ACP 会话以非交互方式运行 —— 没有 TTY 可以批准或拒绝文件 ### `nonInteractivePermissions` -控制当本应显示权限提示但没有可用的交互式 TTY 时(ACP 会话始终如此)会发生什么。 +控制当本应显示权限提示、但没有可交互 TTY 可用时会发生什么(ACP 会话始终如此)。 | 值 | 行为 | | ------ | ----------------------------------------------------------------- | @@ -785,36 +807,36 @@ ACP 会话以非交互方式运行 —— 没有 TTY 可以批准或拒绝文件 ### 配置 -通过插件配置设置: +通过插件配置进行设置: ```bash openclaw config set plugins.entries.acpx.config.permissionMode approve-all openclaw config set plugins.entries.acpx.config.nonInteractivePermissions fail ``` -更改这些值后重启 Gateway 网关。 +修改这些值后,重启 Gateway 网关。 -> **重要:** OpenClaw 当前默认使用 `permissionMode=approve-reads` 和 `nonInteractivePermissions=fail`。在非交互式 ACP 会话中,任何触发权限提示的写入或执行操作都可能因 `AcpRuntimeError: Permission prompt unavailable in non-interactive mode` 而失败。 +> **重要:** OpenClaw 当前默认使用 `permissionMode=approve-reads` 和 `nonInteractivePermissions=fail`。在非交互 ACP 会话中,任何触发权限提示的写入或执行操作都可能失败,并报错 `AcpRuntimeError: Permission prompt unavailable in non-interactive mode`。 > -> 如果你需要限制权限,请将 `nonInteractivePermissions` 设为 `deny`,这样会话会优雅降级,而不是崩溃。 +> 如果你需要限制权限,请将 `nonInteractivePermissions` 设为 `deny`,这样会话会优雅降级,而不是直接崩溃。 ## 故障排除 -| 症状 | 可能原因 | 修复 | +| 症状 | 可能原因 | 修复方法 | | --------------------------------------------------------------------------- | ------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `ACP runtime backend is not configured` | 后端插件缺失或已禁用。 | 安装并启用后端插件,然后运行 `/acp doctor`。 | -| `ACP is disabled by policy (acp.enabled=false)` | ACP 已被全局禁用。 | 设置 `acp.enabled=true`。 | +| `ACP is disabled by policy (acp.enabled=false)` | ACP 被全局禁用。 | 设置 `acp.enabled=true`。 | | `ACP dispatch is disabled by policy (acp.dispatch.enabled=false)` | 来自普通线程消息的分发已禁用。 | 设置 `acp.dispatch.enabled=true`。 | -| `ACP agent "" is not allowed by policy` | 智能体不在允许列表中。 | 使用允许的 `agentId`,或更新 `acp.allowedAgents`。 | -| `Unable to resolve session target: ...` | 错误的键/ID/标签标记。 | 运行 `/acp sessions`,复制精确的键/标签,然后重试。 | -| `--bind here requires running /acp spawn inside an active ... conversation` | 在没有活跃可绑定会话的情况下使用了 `--bind here`。 | 移动到目标聊天/渠道后重试,或使用未绑定生成。 | -| `Conversation bindings are unavailable for .` | 适配器缺少当前会话 ACP 绑定能力。 | 在支持时使用 `/acp spawn ... --thread ...`、配置顶层 `bindings[]`,或切换到受支持的渠道。 | -| `--thread here requires running /acp spawn inside an active ... thread` | 在线程上下文之外使用了 `--thread here`。 | 移动到目标线程,或使用 `--thread auto`/`off`。 | -| `Only can rebind this channel/conversation/thread.` | 另一个用户拥有当前活跃绑定目标。 | 由所有者重新绑定,或使用其他会话或线程。 | +| `ACP agent "" is not allowed by policy` | 智能体不在允许列表中。 | 使用允许的 `agentId` 或更新 `acp.allowedAgents`。 | +| `Unable to resolve session target: ...` | 键/id/标签令牌错误。 | 运行 `/acp sessions`,复制精确的键/标签,然后重试。 | +| `--bind here requires running /acp spawn inside an active ... conversation` | 在没有活动可绑定对话的情况下使用了 `--bind here`。 | 移动到目标聊天/渠道后重试,或使用不绑定的启动。 | +| `Conversation bindings are unavailable for .` | 适配器缺少当前对话 ACP 绑定能力。 | 在支持时使用 `/acp spawn ... --thread ...`、配置顶层 `bindings[]`,或切换到受支持的渠道。 | +| `--thread here requires running /acp spawn inside an active ... thread` | 在线程上下文之外使用了 `--thread here`。 | 切换到目标线程,或使用 `--thread auto`/`off`。 | +| `Only can rebind this channel/conversation/thread.` | 另一个用户拥有当前活动绑定目标。 | 由拥有者重新绑定,或使用其他对话或线程。 | | `Thread bindings are unavailable for .` | 适配器缺少线程绑定能力。 | 使用 `--thread off`,或切换到受支持的适配器/渠道。 | -| `Sandboxed sessions cannot spawn ACP sessions ...` | ACP 运行时位于主机侧;请求方会话处于沙箱隔离状态。 | 在沙箱会话中使用 `runtime="subagent"`,或从非沙箱会话运行 ACP 生成。 | -| `sessions_spawn sandbox="require" is unsupported for runtime="acp" ...` | 为 ACP 运行时请求了 `sandbox="require"`。 | 如需强制沙箱隔离,请使用 `runtime="subagent"`,或从非沙箱会话使用带 `sandbox="inherit"` 的 ACP。 | -| 绑定会话缺少 ACP 元数据 | ACP 会话元数据已过时/被删除。 | 使用 `/acp spawn` 重新创建,然后重新绑定/聚焦线程。 | -| `AcpRuntimeError: Permission prompt unavailable in non-interactive mode` | `permissionMode` 在非交互式 ACP 会话中阻止了写入/执行。 | 将 `plugins.entries.acpx.config.permissionMode` 设为 `approve-all` 并重启 Gateway 网关。请参见[权限配置](#permission-configuration)。 | -| ACP 会话在很早阶段失败且几乎没有输出 | 权限提示被 `permissionMode`/`nonInteractivePermissions` 阻止。 | 检查 Gateway 网关日志中的 `AcpRuntimeError`。如需完整权限,设置 `permissionMode=approve-all`;如需优雅降级,设置 `nonInteractivePermissions=deny`。 | -| ACP 会话在完成工作后无限期卡住 | harness 进程已结束,但 ACP 会话未报告完成。 | 使用 `ps aux \| grep acpx` 监控;手动终止陈旧进程。 | +| `Sandboxed sessions cannot spawn ACP sessions ...` | ACP 运行时在主机侧运行;请求方会话处于沙箱隔离状态。 | 从沙箱隔离会话中使用 `runtime="subagent"`,或从非沙箱会话中执行 ACP 启动。 | +| `sessions_spawn sandbox="require" is unsupported for runtime="acp" ...` | 对 ACP 运行时请求了 `sandbox="require"`。 | 对必需沙箱隔离使用 `runtime="subagent"`,或从非沙箱会话中将 ACP 与 `sandbox="inherit"` 一起使用。 | +| 已绑定会话缺少 ACP 元数据 | ACP 会话元数据过期/被删除。 | 使用 `/acp spawn` 重新创建,然后重新绑定/聚焦线程。 | +| `AcpRuntimeError: Permission prompt unavailable in non-interactive mode` | `permissionMode` 阻止了非交互 ACP 会话中的写入/执行。 | 将 `plugins.entries.acpx.config.permissionMode` 设置为 `approve-all` 并重启 Gateway 网关。请参见 [权限配置](#permission-configuration)。 | +| ACP 会话很早失败且输出很少 | 权限提示被 `permissionMode`/`nonInteractivePermissions` 阻止。 | 检查 Gateway 网关日志中的 `AcpRuntimeError`。如需完整权限,设置 `permissionMode=approve-all`;如需优雅降级,设置 `nonInteractivePermissions=deny`。 | +| ACP 会话在完成工作后无限期停滞 | harness 进程已结束,但 ACP 会话未报告完成。 | 使用 `ps aux \| grep acpx` 监控;手动杀掉陈旧进程。 |