chore(i18n): refresh zh-CN translations
This commit is contained in:
parent
589d3c593c
commit
a344388b2a
@ -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) — 完整的智能体执行周期
|
||||
|
||||
@ -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 <provider/model>`。
|
||||
- 运行时回退规则、冷却探测和会话覆盖持久化记录在 [/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.<id>` 配置;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.<id>` 配置;
|
||||
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_<PROVIDER>_KEY`(单个实时覆盖,最高优先级)
|
||||
- `<PROVIDER>_API_KEYS`(逗号或分号分隔列表)
|
||||
- `<PROVIDER>_API_KEY`(主密钥)
|
||||
- `<PROVIDER>_API_KEY_*`(编号列表,例如 `<PROVIDER>_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/<model>"].params.transport` 为每个模型覆盖(`"sse"`、`"websocket"` 或 `"auto"`)
|
||||
- OpenAI Responses WebSocket 预热默认通过 `params.openaiWsWarmup`(`true`/`false`)启用
|
||||
- 可以通过 `agents.defaults.models["openai/<model>"].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/<model>"].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/<model>"].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/<model>"].params.cachedContent`
|
||||
(或旧版 `cached_content`)以透传提供商原生的
|
||||
`cachedContents/...` 句柄;Gemini 缓存命中会作为 OpenClaw `cacheRead` 显示
|
||||
- 直连 Gemini 运行还接受 `agents.defaults.models["google/<model>"].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/<model>"].params.tool_stream` 为 `false` 可禁用
|
||||
- `tool_stream` 默认开启;设置
|
||||
`agents.defaults.models["xai/<model>"].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.<id>` 条目。
|
||||
下方许多内置提供商插件已经发布了默认目录。
|
||||
只有当你想覆盖默认 base URL、请求头或模型列表时,
|
||||
才需要显式使用 `models.providers.<id>` 条目。
|
||||
|
||||
### 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) 了解完整配置示例。
|
||||
|
||||
## 相关内容
|
||||
|
||||
|
||||
289
docs/zh-CN/gateway/cli-backends.md
Normal file
289
docs/zh-CN/gateway/cli-backends.md
Normal file
@ -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 会成为你的模型引用左侧部分:
|
||||
|
||||
```
|
||||
<provider>/<model>
|
||||
```
|
||||
|
||||
### 配置示例
|
||||
|
||||
```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 会话。
|
||||
|
||||
<Warning>
|
||||
内置的 Anthropic `claude-cli` 后端已被移除,因为 Anthropic 的
|
||||
OpenClaw 计费边界发生了变化。OpenClaw 仍然支持通用 CLI
|
||||
后端,但 Anthropic API 流量应当直接使用 Anthropic 提供商,
|
||||
而不是已移除的本地 Claude CLI 路径。
|
||||
</Warning>
|
||||
|
||||
## 会话
|
||||
|
||||
- 如果 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.<id>` 中的配置仍会覆盖插件默认值。
|
||||
- 后端特定的配置清理由插件通过可选的
|
||||
`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 <generated-file>`
|
||||
|
||||
如果没有启用任何 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 支持文件路径)。
|
||||
File diff suppressed because it is too large
Load Diff
@ -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.<provider>` 的 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.<provider>`。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.<channel>.accounts` 条目,但没有设置 `channels.<channel>.defaultAccount` 或 `accounts.default`,doctor 会警告回退路由可能会选中意外的账户。
|
||||
- 如果配置了两个或更多 `channels.<channel>.accounts` 条目,但没有 `channels.<channel>.defaultAccount` 或 `accounts.default`,doctor 会警告回退路由可能会选择意外的账户。
|
||||
- 如果 `channels.<channel>.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/<agentId>/agent/`
|
||||
- WhatsApp 认证状态(Baileys):
|
||||
- 从旧版 `~/.openclaw/credentials/*.json`(不包括 `oauth.json`)
|
||||
- 到 `~/.openclaw/credentials/whatsapp/<accountId>/...`(默认账户 ID:`default`)
|
||||
- 从旧版 `~/.openclaw/credentials/*.json`(`oauth.json` 除外)
|
||||
- 到 `~/.openclaw/credentials/whatsapp/<accountId>/...`(默认账户 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)的完整指南。
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -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=<n>`:强制指定 worker 数量(上限为 16)。
|
||||
- `OPENCLAW_E2E_VERBOSE=1`:重新启用详细控制台输出。
|
||||
- `OPENCLAW_E2E_WORKERS=<n>` 强制设置 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 <CODE>`。
|
||||
- 真实工具调用可用(read 探测)
|
||||
- 可选的额外工具探测(exec+read 探测)
|
||||
- OpenAI 回归路径(仅工具调用 → 后续跟进)继续可用
|
||||
- 探测细节(这样你可以快速解释失败):
|
||||
- `read` 探测:测试会在工作区写入一个 nonce 文件,并要求智能体 `read` 它并回显该 nonce。
|
||||
- `exec+read` 探测:测试要求智能体通过 `exec` 将一个 nonce 写入临时文件,然后再 `read` 回来。
|
||||
- 图像探测:测试会附加一个生成的 PNG(猫 + 随机代码),并期望模型返回 `cat <CODE>`。
|
||||
- 实现参考:`src/gateway/gateway-models.profiles.live.test.ts` 和 `src/gateway/live-image-probe.ts`。
|
||||
- 启用方式:
|
||||
- `pnpm test:live`(或直接调用 Vitest 时设置 `OPENCLAW_LIVE_TEST=1`)
|
||||
- 如何选择模型:
|
||||
- 默认: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: "<base64>" }]` 发送
|
||||
- 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 <agent> --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@<version>'`
|
||||
- 说明:
|
||||
- 该测试通道使用 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/<agentId>/agent/auth-profiles.json`(这就是实时测试里 “profile keys” 的含义)
|
||||
- 按智能体划分的 auth profiles:`~/.openclaw/agents/<agentId>/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.<capability>`,否则会跳过各项能力
|
||||
- 在修改 comfy workflow 提交、轮询、下载或插件注册后很有用
|
||||
- 覆盖内置 comfy 图像、视频和 `music_generate` 路径
|
||||
- 除非配置了 `models.providers.comfy.<capability>`,否则会跳过各项能力
|
||||
- 在修改 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 <discord-channel-id> ...`
|
||||
- 保留此脚本用于回归 / 调试工作流。后续可能仍会需要它来验证 ACP 线程路由,因此不要删除它。
|
||||
- 保留这个脚本以供回归 / 调试工作流使用。未来可能还需要它来验证 ACP 线程路由,因此不要删除它。
|
||||
|
||||
常用环境变量:
|
||||
|
||||
- `OPENCLAW_CONFIG_DIR=...`(默认:`~/.openclaw`)挂载到 `/home/node/.openclaw`
|
||||
- `OPENCLAW_WORKSPACE_DIR=...`(默认:`~/.openclaw/workspace`)挂载到 `/home/node/.openclaw/workspace`
|
||||
- `OPENCLAW_PROFILE_FILE=...`(默认:`~/.profile`)挂载到 `/home/node/.profile` 并在运行测试前 source
|
||||
- `OPENCLAW_DOCKER_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 未分类时故意失败,这样新类别就无法被悄悄跳过。
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -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 <package-name>` 安装。OpenClaw 会先尝试 ClawHub,并自动回退到 npm。
|
||||
你不需要将你的插件添加到 OpenClaw 仓库中。发布到 [ClawHub](/zh-CN/tools/clawhub) 或 npm,用户即可通过 `openclaw plugins install <package-name>` 安装。OpenClaw 会优先尝试 ClawHub,并在需要时自动回退到 npm。
|
||||
|
||||
## 先决条件
|
||||
## 前置条件
|
||||
|
||||
- Node >= 22 和一个包管理器(npm 或 pnpm)
|
||||
- Node >= 22,以及一个包管理器(npm 或 pnpm)
|
||||
- 熟悉 TypeScript(ESM)
|
||||
- 对于仓库内插件:已克隆仓库并完成 `pnpm install`
|
||||
|
||||
## 哪种类型的插件?
|
||||
## 你要构建哪种插件?
|
||||
|
||||
<CardGroup cols={3}>
|
||||
<Card title="渠道插件" icon="messages-square" href="/zh-CN/plugins/sdk-channel-plugins">
|
||||
将 OpenClaw 连接到一个消息平台(Discord、IRC 等)
|
||||
将 OpenClaw 连接到消息平台(Discord、IRC 等)
|
||||
</Card>
|
||||
<Card title="提供商插件" icon="cpu" href="/zh-CN/plugins/sdk-provider-plugins">
|
||||
添加一个模型提供商(LLM、代理或自定义端点)
|
||||
</Card>
|
||||
<Card title="工具 / 钩子插件" icon="wrench">
|
||||
注册智能体工具、事件钩子或服务 — 继续阅读下文
|
||||
<Card title="工具 / hook 插件" icon="wrench">
|
||||
注册智能体工具、事件 hook 或服务 —— 继续阅读下文
|
||||
</Card>
|
||||
</CardGroup>
|
||||
|
||||
如果某个渠道插件是可选的,并且在运行 onboarding/设置 时可能尚未安装,请使用 `openclaw/plugin-sdk/channel-setup` 中的 `createOptionalChannelSetupSurface(...)`。它会生成一个设置适配器 + 向导 组合,用于提示安装要求,并在插件安装完成之前,对实际配置写入采取默认拒绝策略。
|
||||
如果某个渠道插件是可选的,并且在新手引导/设置运行时可能尚未安装,请使用 `openclaw/plugin-sdk/channel-setup` 中的 `createOptionalChannelSetupSurface(...)`。它会生成一个设置适配器 + 向导组合,用于提示安装要求,并在插件安装完成前对真实配置写入进行失败关闭保护。
|
||||
|
||||
## 快速开始:工具插件
|
||||
|
||||
本演练将创建一个用于注册智能体工具的最小插件。渠道插件和提供商插件有上方链接的专门指南。
|
||||
本教程将创建一个用于注册智能体工具的最小插件。渠道插件和提供商插件有各自的专用指南,见上方链接。
|
||||
|
||||
<Steps>
|
||||
<Step title="创建包和清单">
|
||||
@ -82,7 +82,9 @@ x-i18n:
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
每个插件都需要一个清单,即使没有配置也是如此。完整 schema 请参见 [Manifest](/zh-CN/plugins/manifest)。规范的 ClawHub 发布片段位于 `docs/snippets/plugin-publish/`。
|
||||
每个插件都需要一个清单,即使没有配置也是如此。完整 schema 请参见
|
||||
[Manifest](/zh-CN/plugins/manifest)。规范的 ClawHub
|
||||
发布片段位于 `docs/snippets/plugin-publish/`。
|
||||
|
||||
</Step>
|
||||
|
||||
@ -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)。
|
||||
|
||||
</Step>
|
||||
|
||||
<Step title="测试并发布">
|
||||
|
||||
**外部插件:** 使用 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/<subpath>` 路径导入:
|
||||
始终从聚焦的 `openclaw/plugin-sdk/<subpath>` 路径导入:
|
||||
|
||||
```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/<bundled-id>` 辅助接口仍然存在,用于内置插件维护和兼容性,例如 `plugin-sdk/feishu-setup` 或 `plugin-sdk/zalo-setup`。请将这些视为保留接口,而不是新第三方插件的默认模式。
|
||||
一些生成的 `openclaw/plugin-sdk/<bundled-id>` 辅助扩展点仍然存在,用于内置插件维护和兼容性,例如 `plugin-sdk/feishu-setup` 或 `plugin-sdk/zalo-setup`。请将这些视为保留接口,而不是新第三方插件的默认模式。
|
||||
|
||||
## 提交前检查清单
|
||||
|
||||
<Check>**package.json** 具有正确的 `openclaw` 元数据</Check>
|
||||
<Check>**openclaw.plugin.json** 清单已存在且有效</Check>
|
||||
<Check>**openclaw.plugin.json** 清单存在且有效</Check>
|
||||
<Check>入口点使用 `defineChannelPluginEntry` 或 `definePluginEntry`</Check>
|
||||
<Check>所有导入都使用精确的 `plugin-sdk/<subpath>` 路径</Check>
|
||||
<Check>所有导入都使用聚焦的 `plugin-sdk/<subpath>` 路径</Check>
|
||||
<Check>内部导入使用本地模块,而不是 SDK 自导入</Check>
|
||||
<Check>测试通过(`pnpm test -- <bundled-plugin-root>/my-plugin/`)</Check>
|
||||
<Check>`pnpm check` 通过(仓库内插件)</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: <plugin-name> - <summary>` 的 issue,并添加 `beta-blocker` 标签。将该 issue 链接贴到你的主题中。
|
||||
5. 向 `main` 提交一个标题为 `fix(<plugin-id>): beta blocker - <summary>` 的 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: <plugin-name> - <summary>` 的 issue,并添加 `beta-blocker` 标签。把 issue 链接发到你的线程里。
|
||||
5. 向 `main` 提交一个标题为 `fix(<plugin-id>): beta blocker - <summary>` 的 PR,并在 PR 和你的 Discord 线程中都链接该 issue。贡献者无法为 PR 添加标签,因此标题就是供维护者和自动化识别的 PR 侧信号。有 PR 的 blocker 会被合并;没有 PR 的 blocker 也可能照样发布。维护者会在 Beta 测试期间关注这些线程。
|
||||
6. 没有消息就表示一切正常。如果你错过了这个窗口,你的修复很可能会在下一个周期落地。
|
||||
|
||||
## 后续步骤
|
||||
## 下一步
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="渠道插件" icon="messages-square" href="/zh-CN/plugins/sdk-channel-plugins">
|
||||
@ -278,7 +283,7 @@ import { ... } from "openclaw/plugin-sdk";
|
||||
<Card title="SDK 概览" icon="book-open" href="/zh-CN/plugins/sdk-overview">
|
||||
导入映射和注册 API 参考
|
||||
</Card>
|
||||
<Card title="运行时辅助函数" icon="settings" href="/zh-CN/plugins/sdk-runtime">
|
||||
<Card title="运行时辅助工具" icon="settings" href="/zh-CN/plugins/sdk-runtime">
|
||||
通过 api.runtime 使用 TTS、搜索、子智能体
|
||||
</Card>
|
||||
<Card title="测试" icon="test-tubes" href="/zh-CN/plugins/sdk-testing">
|
||||
@ -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) — 构建渠道插件
|
||||
|
||||
@ -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>` 中使用的 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<string, string[]>` | OpenClaw 无需加载插件代码即可检查的轻量级提供商认证环境变量元数据。 |
|
||||
| `providerAuthChoices` | 否 | `object[]` | 用于新手引导选择器、首选提供商解析和简单 CLI 标志接线的轻量级认证选项元数据。 |
|
||||
| `contracts` | 否 | `object` | 用于语音、实时转录、实时语音、媒体理解、图像生成、音乐生成、视频生成、网页抓取、网页搜索和工具归属的静态内置能力快照。 |
|
||||
| `channelConfigs` | 否 | `Record<string, object>` | 在运行时加载前,合并到设备发现和校验表面的由清单拥有的渠道配置元数据。 |
|
||||
| `skills` | 否 | `string[]` | 要加载的 Skills 目录,相对于插件根目录。 |
|
||||
| `name` | 否 | `string` | 人类可读的插件名称。 |
|
||||
| `description` | 否 | `string` | 显示在插件表面中的简短摘要。 |
|
||||
| `version` | 否 | `string` | 信息性插件版本。 |
|
||||
| `uiHints` | 否 | `Record<string, object>` | 用于配置字段的 UI 标签、占位符和敏感性提示。 |
|
||||
| Field | Required | Type | What it means |
|
||||
| ----------------------------------- | -------- | -------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
||||
| `id` | 是 | `string` | 规范的插件 id。这是在 `plugins.entries.<id>` 中使用的 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<string, string[]>` | OpenClaw 无需加载插件代码即可检查的轻量提供商凭证环境变量元数据。 |
|
||||
| `providerAuthChoices` | 否 | `object[]` | 用于新手引导选择器、首选提供商解析和简单 CLI 标志接线的轻量凭证选择元数据。 |
|
||||
| `contracts` | 否 | `object` | speech、实时转写、实时语音、媒体理解、图像生成、音乐生成、视频生成、网页抓取、网页搜索和工具归属的静态内置能力快照。 |
|
||||
| `channelConfigs` | 否 | `Record<string, object>` | 由清单拥有的渠道配置元数据,在运行时加载前合并到设备发现和校验表面。 |
|
||||
| `skills` | 否 | `string[]` | 要加载的 Skills 目录,相对于插件根目录。 |
|
||||
| `name` | 否 | `string` | 人类可读的插件名称。 |
|
||||
| `description` | 否 | `string` | 在插件表面中显示的简短摘要。 |
|
||||
| `version` | 否 | `string` | 仅供参考的插件版本。 |
|
||||
| `uiHints` | 否 | `Record<string, object>` | 配置字段的 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 <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 <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.<id>` 的 JSON Schema。每个声明的渠道配置条目都必须提供。 |
|
||||
| `uiHints` | `Record<string, object>` | 该渠道配置部分的可选 UI 标签 / 占位符 / 敏感性提示。 |
|
||||
| `label` | `string` | 当运行时元数据尚未准备好时,合并到选择器和检查表面的渠道标签。 |
|
||||
| `description` | `string` | 用于检查和目录表面的简短渠道描述。 |
|
||||
| `preferOver` | `string[]` | 在选择表面中,该渠道应优先于的旧版或较低优先级插件 id。 |
|
||||
| Field | Type | What it means |
|
||||
| ------------- | ------------------------ | ----------------------------------------------------------------------------- |
|
||||
| `schema` | `object` | `channels.<id>` 的 JSON Schema。每个声明的渠道配置条目都必须提供。 |
|
||||
| `uiHints` | `Record<string, object>` | 该渠道配置部分可选的 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.<id>` 条目。无关的配置错误仍会阻止安装,并将操作人员引导到 `openclaw doctor --fix`。
|
||||
`openclaw.install.allowInvalidConfigRecovery` 的范围有意保持很窄。它
|
||||
不会让任意损坏的配置也能被安装。当前它只允许安装流程从特定的陈旧内置插件升级失败中恢复,例如
|
||||
缺失的内置插件路径,或同一内置插件的陈旧 `channels.<id>` 条目。
|
||||
无关的配置错误仍会阻止安装,并将操作员引导到 `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.<id>`、`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 <package>`)。
|
||||
|
||||
## 相关内容
|
||||
|
||||
- [构建插件](/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 概览
|
||||
|
||||
@ -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 是插件与核心之间的类型化契约。本页是关于 **该导入什么** 以及 **你可以注册什么** 的参考。
|
||||
|
||||
<Tip>
|
||||
**在找操作指南吗?**
|
||||
**在找操作指南?**
|
||||
- 第一个插件?从 [入门指南](/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` |
|
||||
|
||||
<AccordionGroup>
|
||||
<Accordion title="渠道子路径">
|
||||
@ -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` | 反馈/反应接线 |
|
||||
</Accordion>
|
||||
@ -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 辅助工具 |
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="认证和安全子路径">
|
||||
<Accordion title="认证与安全子路径">
|
||||
| 子路径 | 关键导出 |
|
||||
| --- | --- |
|
||||
| `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` | 请求体大小/超时辅助工具 |
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="运行时和存储子路径">
|
||||
<Accordion title="运行时与存储子路径">
|
||||
| 子路径 | 关键导出 |
|
||||
| --- | --- |
|
||||
| `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` |
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="能力和测试子路径">
|
||||
<Accordion title="能力与测试子路径">
|
||||
| 子路径 | 关键导出 |
|
||||
| --- | --- |
|
||||
| `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` |
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="记忆子路径">
|
||||
<Accordion title="Memory 子路径">
|
||||
| 子路径 | 关键导出 |
|
||||
| --- | --- |
|
||||
| `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 辅助接口 |
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="保留的内置辅助子路径">
|
||||
| 系列 | 当前子路径 | 预期用途 |
|
||||
| 家族 | 当前子路径 | 预期用途 |
|
||||
| --- | --- | --- |
|
||||
| Browser | `plugin-sdk/browser-cdp`, `plugin-sdk/browser-config-runtime`, `plugin-sdk/browser-config-support`, `plugin-sdk/browser-control-auth`, `plugin-sdk/browser-node-runtime`, `plugin-sdk/browser-profiles`, `plugin-sdk/browser-security-runtime`, `plugin-sdk/browser-setup-tools`, `plugin-sdk/browser-support` | 内置 Browser 插件支持辅助函数(`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` |
|
||||
</Accordion>
|
||||
</AccordionGroup>
|
||||
|
||||
## 注册 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.<id>` 相同的结构。
|
||||
- 用户配置仍然优先。OpenClaw 会在运行 CLI 之前,将 `agents.defaults.cliBackends.<id>` 合并覆盖到插件默认值之上。
|
||||
- 当某个后端在合并后需要兼容性重写时,使用 `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<string, unknown>` | 来自 `plugins.entries.<id>.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<string, unknown>` | 来自 `plugins.entries.<id>.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 # 仅设置用的轻量入口(可选)
|
||||
```
|
||||
|
||||
<Warning>
|
||||
永远不要在生产代码中通过 `openclaw/plugin-sdk/<your-plugin>`
|
||||
不要在生产代码中通过 `openclaw/plugin-sdk/<your-plugin>`
|
||||
导入你自己的插件。内部导入应通过 `./api.ts` 或
|
||||
`./runtime-api.ts`。SDK 路径仅是外部契约。
|
||||
`./runtime-api.ts` 进行。SDK 路径仅是对外契约。
|
||||
</Warning>
|
||||
|
||||
通过外观加载的内置插件公共表面(`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` 导出提供商构建器以及
|
||||
新手引导/配置辅助工具
|
||||
|
||||
<Warning>
|
||||
扩展生产代码同样应避免导入 `openclaw/plugin-sdk/<other-plugin>`。
|
||||
如果某个辅助函数确实是共享的,应将其提升到中立的 SDK 子路径,
|
||||
扩展生产代码也应避免导入 `openclaw/plugin-sdk/<other-plugin>`。
|
||||
如果某个辅助工具确实是共享的,请将其提升到中立的 SDK 子路径,
|
||||
例如 `openclaw/plugin-sdk/speech`、`.../provider-model-shared` 或其他
|
||||
面向能力的表面,而不是将两个插件耦合在一起。
|
||||
面向能力的接口,而不是让两个插件彼此耦合。
|
||||
</Warning>
|
||||
|
||||
## 相关内容
|
||||
|
||||
- [入口点](/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) — 深入的架构和能力模型
|
||||
|
||||
@ -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 密钥认证和动态模型解析能力的提供商。
|
||||
|
||||
<Info>
|
||||
如果你之前从未构建过任何 OpenClaw 插件,请先阅读
|
||||
[入门指南](/zh-CN/plugins/building-plugins),了解基础的软件包结构和清单设置。
|
||||
[入门指南](/zh-CN/plugins/building-plugins) 了解基本包
|
||||
结构和清单设置。
|
||||
</Info>
|
||||
|
||||
## 演练
|
||||
## 操作演练
|
||||
|
||||
<Steps>
|
||||
<a id="step-1-package-and-manifest"></a>
|
||||
<Step title="软件包和清单">
|
||||
<Step title="包和清单">
|
||||
<CodeGroup>
|
||||
```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 <key>",
|
||||
"cliDescription": "Acme AI API 密钥"
|
||||
"cliDescription": "Acme AI API key"
|
||||
}
|
||||
],
|
||||
"configSchema": {
|
||||
@ -84,10 +86,12 @@ x-i18n:
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
清单会声明 `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` 字段
|
||||
是必需的。
|
||||
|
||||
</Step>
|
||||
@ -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 <key>`,并选择
|
||||
这样就是一个可工作的提供商。用户现在可以
|
||||
`openclaw onboard --acme-ai-api-key <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 风格的端点仍可选择启用。
|
||||
|
||||
</Step>
|
||||
|
||||
@ -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`。
|
||||
|
||||
</Step>
|
||||
|
||||
@ -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/配置帮助器
|
||||
|
||||
<Tabs>
|
||||
<Tab title="令牌交换">
|
||||
对于那些在每次推理调用之前都需要进行令牌交换的提供商:
|
||||
对于需要在每次推理调用前执行令牌交换的提供商:
|
||||
|
||||
```typescript
|
||||
prepareRuntimeAuth: async (ctx) => {
|
||||
@ -398,10 +400,10 @@ x-i18n:
|
||||
```
|
||||
</Tab>
|
||||
<Tab title="自定义请求头">
|
||||
对于那些需要自定义请求头或请求体修改的提供商:
|
||||
对于需要自定义请求头或请求体修改的提供商:
|
||||
|
||||
```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:
|
||||
},
|
||||
```
|
||||
</Tab>
|
||||
<Tab title="原生传输协议标识">
|
||||
对于那些在通用 HTTP 或 WebSocket 传输协议上需要原生请求/会话头或元数据的提供商:
|
||||
<Tab title="原生传输身份">
|
||||
对于在通用 HTTP 或 WebSocket 传输上需要原生请求/会话头或元数据的提供商:
|
||||
|
||||
```typescript
|
||||
resolveTransportTurnState: (ctx) => ({
|
||||
@ -436,8 +438,8 @@ x-i18n:
|
||||
}),
|
||||
```
|
||||
</Tab>
|
||||
<Tab title="用量和计费">
|
||||
对于那些公开用量/计费数据的提供商:
|
||||
<Tab title="Usage 和计费">
|
||||
对于暴露 usage/计费数据的提供商:
|
||||
|
||||
```typescript
|
||||
resolveUsageAuth: async (ctx) => {
|
||||
@ -452,83 +454,84 @@ x-i18n:
|
||||
</Tabs>
|
||||
|
||||
<Accordion title="所有可用的提供商 hooks">
|
||||
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.<id>` 配置 |
|
||||
| 6 | `applyNativeStreamingUsageCompat` | 对配置提供商应用原生流式使用量兼容性重写 |
|
||||
| 7 | `resolveConfigApiKey` | 由提供商持有的环境标记凭证解析 |
|
||||
| 8 | `resolveSyntheticAuth` | 本地/自托管或基于配置的合成凭证 |
|
||||
| 9 | `shouldDeferSyntheticProfileAuth` | 将合成的已存配置档占位符置于环境变量/配置凭证之后 |
|
||||
| 2 | `applyConfigDefaults` | 配置物化期间由提供商拥有的全局默认值 |
|
||||
| 3 | `normalizeModelId` | 查找前对旧版/预览模型 id 别名进行清理 |
|
||||
| 4 | `normalizeTransport` | 通用模型组装前,对 provider-family 的 `api` / `baseUrl` 进行清理 |
|
||||
| 5 | `normalizeConfig` | 规范化 `models.providers.<id>` 配置 |
|
||||
| 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)。
|
||||
</Accordion>
|
||||
|
||||
</Step>
|
||||
|
||||
<Step title="添加额外能力(可选)">
|
||||
<a id="step-5-add-extra-capabilities"></a>
|
||||
提供商插件除了文本推理外,还可以注册语音、实时转录、实时语音、
|
||||
媒体理解、图像生成、视频生成、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` 仍可作为聚合回退上限使用,
|
||||
但它们无法同样清晰地描述每种模式的限制或
|
||||
被禁用的转换模式。
|
||||
|
||||
</Step>
|
||||
|
||||
@ -652,7 +655,7 @@ x-i18n:
|
||||
<a id="step-6-test"></a>
|
||||
```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 细节和内置示例
|
||||
|
||||
@ -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 配置文件如果已经完成配置,运行时仍会继续支持。
|
||||
|
||||
<Warning>
|
||||
在 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)。
|
||||
</Warning>
|
||||
|
||||
## 选项 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)。
|
||||
|
||||
@ -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` 提供)。
|
||||
|
||||
@ -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)。
|
||||
|
||||
@ -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. **转录(`<sessionId>.jsonl`)**
|
||||
- 采用树结构的追加式转录(条目包含 `id` + `parentId`)
|
||||
2. **Transcript(`<sessionId>.jsonl`)**
|
||||
- 追加写入的 transcript,带树结构(条目具有 `id` + `parentId`)
|
||||
- 存储实际对话 + 工具调用 + 压缩摘要
|
||||
- 用于为未来轮次重建模型上下文
|
||||
- 用于为后续轮次重建模型上下文
|
||||
|
||||
---
|
||||
|
||||
## 磁盘位置
|
||||
## 磁盘上的位置
|
||||
|
||||
在 Gateway 网关主机上,按智能体区分:
|
||||
每个智能体在 Gateway 网关 主机上的位置:
|
||||
|
||||
- 存储:`~/.openclaw/agents/<agentId>/sessions/sessions.json`
|
||||
- 转录:`~/.openclaw/agents/<agentId>/sessions/<sessionId>.jsonl`
|
||||
- Transcripts:`~/.openclaw/agents/<agentId>/sessions/<sessionId>.jsonl`
|
||||
- Telegram 话题会话:`.../<sessionId>-topic-<threadId>.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.<timestamp>` 转录归档的保留期(默认:与 `pruneAfter` 相同;`false` 表示禁用清理)
|
||||
- `maxDiskBytes`:可选的会话目录磁盘预算
|
||||
- `pruneAfter`:陈旧条目的保留期限截止值(默认 `30d`)
|
||||
- `maxEntries`:`sessions.json` 中条目上限(默认 `500`)
|
||||
- `rotateBytes`:当 `sessions.json` 过大时进行轮转(默认 `10mb`)
|
||||
- `resetArchiveRetention`:`*.reset.<timestamp>` 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/<jobId>.jsonl` 文件(默认:`2_000_000` 字节和 `2000` 行)。
|
||||
- `cron.runLog.maxBytes` + `cron.runLog.keepLines` 会裁剪 `~/.openclaw/cron/runs/<jobId>.jsonl` 文件(默认:`2_000_000` 字节和 `2000` 行)。
|
||||
|
||||
---
|
||||
|
||||
## 会话键(`sessionKey`)
|
||||
|
||||
`sessionKey` 用于标识你当前处于 _哪个对话桶_ 中(路由 + 隔离)。
|
||||
`sessionKey` 用于标识你所在的_哪个会话桶_(路由 + 隔离)。
|
||||
|
||||
常见模式:
|
||||
|
||||
- 主/直接聊天(每个智能体):`agent:<agentId>:<mainKey>`(默认 `main`)
|
||||
- 主 / 直接聊天(每个智能体):`agent:<agentId>:<mainKey>`(默认 `main`)
|
||||
- 群组:`agent:<agentId>:<channel>:group:<id>`
|
||||
- 房间/渠道(Discord/Slack):`agent:<agentId>:<channel>:channel:<id>` 或 `...:room:<id>`
|
||||
- 房间 / 渠道(Discord / Slack):`agent:<agentId>:<channel>:channel:<id>` 或 `...:room:<id>`
|
||||
- Cron:`cron:<job.id>`
|
||||
- Webhook:`hook:<uuid>`(除非被覆盖)
|
||||
|
||||
规范规则见 [/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),并且你使用的是包含流式抑制修复的构建版本。
|
||||
|
||||
@ -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 <provider/model>`
|
||||
- `/acp permissions <profile>`
|
||||
- `/acp timeout <seconds>`
|
||||
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:<agentId>:acp:<uuid>` | `agent:<agentId>:subagent:<uuid>` |
|
||||
| 主要命令 | `/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 <harness> --bind here`。
|
||||
### 当前对话绑定
|
||||
|
||||
行为:
|
||||
当你希望当前对话成为一个持久的 ACP 工作区,而不创建子线程时,请使用 `/acp spawn <harness> --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="<channelOrThreadId>"`
|
||||
- Telegram 论坛话题:`match.channel="telegram"` + `match.peer.id="<chatId>:topic:<topicId>"`
|
||||
- BlueBubbles 私信/群聊:`match.channel="bluebubbles"` + `match.peer.id="<handle|chat_id:*|chat_guid:*|chat_identifier:*>"`
|
||||
- Telegram 论坛主题:`match.channel="telegram"` + `match.peer.id="<chatId>:topic:<topicId>"`
|
||||
- BlueBubbles 私信/群聊:`match.channel="bluebubbles"` + `match.peer.id="<handle|chat_id:*|chat_guid:*|chat_identifier:*>"`
|
||||
对于稳定的群组绑定,优先使用 `chat_id:*` 或 `chat_identifier:*`。
|
||||
- iMessage 私信/群聊:`match.channel="imessage"` + `match.peer.id="<handle|chat_id:*|chat_guid:*|chat_identifier:*>"`
|
||||
- iMessage 私信/群聊:`match.channel="imessage"` + `match.peer.id="<handle|chat_id:*|chat_guid:*|chat_identifier:*>"`
|
||||
对于稳定的群组绑定,优先使用 `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 日志(`<sessionId>.acp-stream.jsonl`),你可以对其执行 tail 以查看完整转发历史。
|
||||
- `cwd`(可选):请求的运行时工作目录(由后端/运行时策略校验)。如果省略,在已配置时 ACP 启动会继承目标智能体工作区;缺失的继承路径会回退到后端默认值,而真实访问错误会被返回。
|
||||
- `label`(可选):用于会话/横幅文本中的面向操作者的标签。
|
||||
- `resumeSessionId`(可选):恢复一个现有 ACP 会话,而不是创建新会话。智能体会通过 `session/load` 重放其对话历史。需要 `runtime: "acp"`。
|
||||
- `streamTo`(可选):`"parent"` 会将初始 ACP 运行进度摘要以系统事件形式流式返回给请求方会话。
|
||||
- 在可用时,接受的响应中会包含 `streamLogPath`,指向一个按会话划分的 JSONL 日志(`<sessionId>.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=<yes/no>; childSessionKey=<value or none>; error=<exa
|
||||
|
||||
说明:
|
||||
|
||||
- 除非你有意测试线程绑定的持久化 ACP 会话,否则请将此 smoke 测试保持在 `mode: "run"`。
|
||||
- 基础门槛不要要求 `streamTo: "parent"`。该路径依赖请求方/会话能力,是单独的集成检查。
|
||||
- 将线程绑定的 `mode: "session"` 测试视为来自真实 Discord 线程或 Telegram 话题的第二阶段、更丰富的集成验证。
|
||||
- 除非你是有意测试
|
||||
线程绑定的持久化 ACP 会话,否则请将这个冒烟测试保持在 `mode: "run"`。
|
||||
- 对于基础 gate,不要要求 `streamTo: "parent"`。该路径依赖于
|
||||
请求方/会话能力,是一个单独的集成检查。
|
||||
- 将线程绑定的 `mode: "session"` 测试视为第二阶段、更丰富的集成
|
||||
检查,并从真实 Discord 线程或 Telegram 主题中进行。
|
||||
|
||||
## 沙箱兼容性
|
||||
|
||||
ACP 会话当前运行在主机运行时上,而不是 OpenClaw 沙箱内。
|
||||
ACP 会话当前运行在主机运行时上,而不是 OpenClaw 沙箱内部。
|
||||
|
||||
当前限制:
|
||||
|
||||
- 如果请求方会话处于沙箱隔离状态,则 `sessions_spawn({ runtime: "acp" })` 和 `/acp spawn` 的 ACP 生成都会被阻止。
|
||||
- 如果请求方会话处于沙箱隔离状态,那么对于 `sessions_spawn({ runtime: "acp" })` 和 `/acp spawn`,ACP 启动都会被阻止。
|
||||
- 错误:`Sandboxed sessions cannot spawn ACP sessions because runtime="acp" runs on the host. Use runtime="subagent" from sandboxed sessions.`
|
||||
- `runtime: "acp"` 的 `sessions_spawn` 不支持 `sandbox: "require"`。
|
||||
- 使用 `runtime: "acp"` 的 `sessions_spawn` 不支持 `sandbox: "require"`。
|
||||
- 错误:`sessions_spawn sandbox="require" is unsupported for runtime="acp" because ACP sessions run outside the sandbox. Use runtime="subagent" or sandbox="inherit".`
|
||||
|
||||
当你需要由沙箱强制执行时,请使用 `runtime: "subagent"`。
|
||||
当你需要强制沙箱执行时,请使用 `runtime: "subagent"`。
|
||||
|
||||
### 从 `/acp` 命令启动
|
||||
|
||||
当你需要从聊天中进行显式操作员控制时,请使用 `/acp spawn`。
|
||||
在需要时,使用 `/acp spawn` 从聊天中进行显式操作者控制。
|
||||
|
||||
```text
|
||||
/acp spawn codex --mode persistent --thread auto
|
||||
@ -458,54 +470,54 @@ ACP 会话当前运行在主机运行时上,而不是 OpenClaw 沙箱内。
|
||||
|
||||
## 会话目标解析
|
||||
|
||||
大多数 `/acp` 操作接受一个可选的会话目标(`session-key`、`session-id` 或 `session-label`)。
|
||||
大多数 `/acp` 操作都接受一个可选的会话目标(`session-key`、`session-id` 或 `session-label`)。
|
||||
|
||||
解析顺序:
|
||||
|
||||
1. 显式目标参数(或 `/acp steer` 的 `--session`)
|
||||
- 先尝试键
|
||||
- 然后尝试 UUID 形状的会话 ID
|
||||
- 再尝试标签
|
||||
2. 当前线程绑定(如果此会话/线程已绑定到某个 ACP 会话)
|
||||
- 再尝试 UUID 形状的会话 id
|
||||
- 然后尝试标签
|
||||
2. 当前线程绑定(如果这个对话/线程已绑定到某个 ACP 会话)
|
||||
3. 当前请求方会话回退
|
||||
|
||||
当前会话绑定和线程绑定都会参与第 2 步。
|
||||
当前对话绑定和线程绑定都会参与第 2 步。
|
||||
|
||||
如果无法解析任何目标,OpenClaw 会返回清晰错误(`Unable to resolve session target: ...`)。
|
||||
如果无法解析任何目标,OpenClaw 会返回明确错误(`Unable to resolve session target: ...`)。
|
||||
|
||||
## 生成绑定模式
|
||||
## 启动绑定模式
|
||||
|
||||
`/acp spawn` 支持 `--bind here|off`。
|
||||
|
||||
| 模式 | 行为 |
|
||||
| ------ | ---------------------------------------------------------------------- |
|
||||
| `here` | 原地绑定当前活跃会话;如果没有活跃会话则失败。 |
|
||||
| `off` | 不创建当前会话绑定。 |
|
||||
| `here` | 就地绑定当前活动对话;如果当前没有活动对话则失败。 |
|
||||
| `off` | 不创建当前对话绑定。 |
|
||||
|
||||
说明:
|
||||
|
||||
- `--bind here` 是“让这个渠道或聊天由 Codex 提供支持”的最简单操作员路径。
|
||||
- `--bind here` 是“让这个渠道或聊天由 Codex 驱动”的最简单操作者路径。
|
||||
- `--bind here` 不会创建子线程。
|
||||
- `--bind here` 仅适用于暴露当前会话绑定支持的渠道。
|
||||
- `--bind` 与 `--thread` 不能在同一个 `/acp spawn` 调用中组合使用。
|
||||
- `--bind here` 仅适用于暴露当前对话绑定支持的渠道。
|
||||
- `--bind` 和 `--thread` 不能在同一个 `/acp spawn` 调用中组合使用。
|
||||
|
||||
## 生成线程模式
|
||||
## 启动线程模式
|
||||
|
||||
`/acp spawn` 支持 `--thread auto|here|off`。
|
||||
|
||||
| 模式 | 行为 |
|
||||
| ------ | --------------------------------------------------------------------------------------------------- |
|
||||
| `auto` | 在活跃线程中:绑定该线程。在线程外:在支持时创建/绑定一个子线程。 |
|
||||
| `here` | 要求当前处于活跃线程中;否则失败。 |
|
||||
| `off` | 不绑定。会话以未绑定方式启动。 |
|
||||
| `auto` | 如果当前在一个活动线程中:绑定该线程。如果不在线程中:在支持时创建/绑定一个子线程。 |
|
||||
| `here` | 要求当前处于活动线程中;如果不在线程中则失败。 |
|
||||
| `off` | 不绑定。会话以未绑定状态启动。 |
|
||||
|
||||
说明:
|
||||
|
||||
- 在不支持线程绑定的界面上,默认行为实际上等同于 `off`。
|
||||
- 线程绑定生成需要渠道策略支持:
|
||||
- 线程绑定启动需要渠道策略支持:
|
||||
- Discord:`channels.discord.threadBindings.spawnAcpSessions=true`
|
||||
- Telegram:`channels.telegram.threadBindings.spawnAcpSessions=true`
|
||||
- 当你想固定当前会话而不创建子线程时,请使用 `--bind here`。
|
||||
- 如果你想固定当前对话而不创建子线程,请使用 `--bind here`。
|
||||
|
||||
## ACP 控制
|
||||
|
||||
@ -527,44 +539,44 @@ ACP 会话当前运行在主机运行时上,而不是 OpenClaw 沙箱内。
|
||||
- `/acp doctor`
|
||||
- `/acp install`
|
||||
|
||||
`/acp status` 会显示生效的运行时选项,并在可用时同时显示运行时级和后端级会话标识符。
|
||||
`/acp status` 会显示实际运行时选项,并在可用时显示运行时级别和后端级别的会话标识符。
|
||||
|
||||
某些控制依赖后端能力。如果后端不支持某个控制,OpenClaw 会返回清晰的“不支持该控制”错误。
|
||||
某些控制取决于后端能力。如果某个后端不支持某项控制,OpenClaw 会返回明确的不支持控制错误。
|
||||
|
||||
## ACP 命令手册
|
||||
|
||||
| 命令 | 作用 | 示例 |
|
||||
| -------------------- | --------------------------------------------------------- | ------------------------------------------------------------- |
|
||||
| `/acp spawn` | 创建 ACP 会话;可选当前绑定或线程绑定。 | `/acp spawn codex --bind here --cwd /repo` |
|
||||
| `/acp cancel` | 取消目标会话的进行中轮次。 | `/acp cancel agent:codex:acp:<uuid>` |
|
||||
| `/acp cancel` | 取消目标会话当前进行中的轮次。 | `/acp cancel agent:codex:acp:<uuid>` |
|
||||
| `/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 <id>` 映射到运行时配置键 `model`。
|
||||
- `/acp permissions <profile>` 映射到运行时配置键 `approval_policy`。
|
||||
- `/acp timeout <seconds>` 映射到运行时配置键 `timeout`。
|
||||
- `/acp cwd <path>` 会直接更新运行时 cwd 覆盖值。
|
||||
- `/acp cwd <path>` 直接更新运行时 cwd 覆盖值。
|
||||
- `/acp set <key> <value>` 是通用路径。
|
||||
- 特殊情况:`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 <command>` 定位任意适配器,但这个原始逃生口是 acpx CLI 功能(不是 OpenClaw 正常的 `agentId` 路径)。
|
||||
直接使用 acpx CLI 也可以通过 `--agent <command>` 指向任意适配器,但这个原始逃生口是 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@<pinned>`,然后重新验证。
|
||||
|
||||
@ -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 "<id>" 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 <channel>.` | 适配器缺少当前会话 ACP 绑定能力。 | 在支持时使用 `/acp spawn ... --thread ...`、配置顶层 `bindings[]`,或切换到受支持的渠道。 |
|
||||
| `--thread here requires running /acp spawn inside an active ... thread` | 在线程上下文之外使用了 `--thread here`。 | 移动到目标线程,或使用 `--thread auto`/`off`。 |
|
||||
| `Only <user-id> can rebind this channel/conversation/thread.` | 另一个用户拥有当前活跃绑定目标。 | 由所有者重新绑定,或使用其他会话或线程。 |
|
||||
| `ACP agent "<id>" 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 <channel>.` | 适配器缺少当前对话 ACP 绑定能力。 | 在支持时使用 `/acp spawn ... --thread ...`、配置顶层 `bindings[]`,或切换到受支持的渠道。 |
|
||||
| `--thread here requires running /acp spawn inside an active ... thread` | 在线程上下文之外使用了 `--thread here`。 | 切换到目标线程,或使用 `--thread auto`/`off`。 |
|
||||
| `Only <user-id> can rebind this channel/conversation/thread.` | 另一个用户拥有当前活动绑定目标。 | 由拥有者重新绑定,或使用其他对话或线程。 |
|
||||
| `Thread bindings are unavailable for <channel>.` | 适配器缺少线程绑定能力。 | 使用 `--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` 监控;手动杀掉陈旧进程。 |
|
||||
|
||||
Loading…
Reference in New Issue
Block a user