chore(i18n): refresh zh-CN translations
This commit is contained in:
parent
ed42a0bfb2
commit
d6163d1a66
@ -1,37 +1,37 @@
|
||||
---
|
||||
read_when:
|
||||
- 更改群聊行为或提及门控时
|
||||
summary: 跨平台界面的群聊行为(Discord/iMessage/Matrix/Microsoft Teams/Signal/Slack/Telegram/WhatsApp/Zalo)
|
||||
- 修改群聊行为或提及门控时
|
||||
summary: 跨界面群聊行为(Discord/iMessage/Matrix/Microsoft Teams/Signal/Slack/Telegram/WhatsApp/Zalo)
|
||||
title: 群组
|
||||
x-i18n:
|
||||
generated_at: "2026-04-05T17:47:15Z"
|
||||
generated_at: "2026-04-06T15:28:01Z"
|
||||
model: gpt-5.4
|
||||
provider: openai
|
||||
source_hash: 8620de6f7f0b866bf43a307fdbec3399790f09f22a87703704b0522caba80b18
|
||||
source_hash: 83d20f2958ed6ad3354f0078553b3c6a38643ea8ef38573c40e89ebef2fa8421
|
||||
source_path: channels/groups.md
|
||||
workflow: 15
|
||||
---
|
||||
|
||||
# 群组
|
||||
|
||||
OpenClaw 会在各个平台界面上一致地处理群聊:Discord、iMessage、Matrix、Microsoft Teams、Signal、Slack、Telegram、WhatsApp、Zalo。
|
||||
OpenClaw 会在各个界面上一致地处理群聊:Discord、iMessage、Matrix、Microsoft Teams、Signal、Slack、Telegram、WhatsApp、Zalo。
|
||||
|
||||
## 新手简介(2 分钟)
|
||||
|
||||
OpenClaw “运行”在你自己的消息账号上。没有单独的 WhatsApp 机器人用户。
|
||||
如果**你**在某个群里,OpenClaw 就可以看到该群并在其中回复。
|
||||
OpenClaw “运行”在你自己的消息账号上。它不是一个单独的 WhatsApp 机器人用户。
|
||||
如果**你**在某个群里,OpenClaw 就可以看到那个群并在那里回复。
|
||||
|
||||
默认行为:
|
||||
|
||||
- 群组受限(`groupPolicy: "allowlist"`)。
|
||||
- 群组是受限的(`groupPolicy: "allowlist"`)。
|
||||
- 回复需要提及,除非你明确禁用提及门控。
|
||||
|
||||
也就是说:在允许名单中的发送者可以通过提及 OpenClaw 来触发它。
|
||||
换句话说:在允许列表中的发送者可以通过提及 OpenClaw 来触发它。
|
||||
|
||||
> 简而言之
|
||||
>
|
||||
> - **私信访问**由 `*.allowFrom` 控制。
|
||||
> - **群组访问**由 `*.groupPolicy` + 允许名单(`*.groups`、`*.groupAllowFrom`)控制。
|
||||
> - **群组访问**由 `*.groupPolicy` + 允许列表(`*.groups`、`*.groupAllowFrom`)控制。
|
||||
> - **回复触发**由提及门控(`requireMention`、`/activation`)控制。
|
||||
|
||||
快速流程(群消息会发生什么):
|
||||
@ -43,62 +43,62 @@ requireMention? yes -> mentioned? no -> store for context only
|
||||
otherwise -> reply
|
||||
```
|
||||
|
||||
## 上下文可见性与允许名单
|
||||
## 上下文可见性与允许列表
|
||||
|
||||
群组安全性涉及两种不同的控制:
|
||||
群组安全涉及两种不同的控制:
|
||||
|
||||
- **触发授权**:谁可以触发智能体(`groupPolicy`、`groups`、`groupAllowFrom`、渠道特定允许名单)。
|
||||
- **上下文可见性**:哪些补充上下文会被注入到模型中(回复文本、引用、线程历史、转发元数据)。
|
||||
- **触发授权**:谁可以触发智能体(`groupPolicy`、`groups`、`groupAllowFrom`、渠道特定允许列表)。
|
||||
- **上下文可见性**:哪些补充上下文会注入到模型中(回复文本、引用、线程历史、转发元数据)。
|
||||
|
||||
默认情况下,OpenClaw 优先保证正常聊天行为,并尽量按接收到的原样保留上下文。这意味着,允许名单主要决定谁可以触发操作,而不是对每一段引用或历史片段都应用的通用脱敏边界。
|
||||
默认情况下,OpenClaw 优先保持正常聊天行为,并尽量按接收到的原样保留上下文。这意味着允许列表主要决定谁可以触发操作,而不是对每一段引用或历史片段都进行统一脱敏的边界。
|
||||
|
||||
当前行为因渠道而异:
|
||||
|
||||
- 某些渠道已经在特定路径中对补充上下文应用基于发送者的过滤(例如 Slack 线程预置上下文、Matrix 回复/线程查询)。
|
||||
- 其他渠道仍会按接收到的原样传递引用/回复/转发上下文。
|
||||
- 某些渠道已经在特定路径上对补充上下文应用基于发送者的过滤(例如 Slack 线程预载、Matrix 回复/线程查询)。
|
||||
- 其他渠道仍然会按接收到的原样传递引用/回复/转发上下文。
|
||||
|
||||
加固方向(计划中):
|
||||
|
||||
- `contextVisibility: "all"`(默认)保留当前“按接收原样”的行为。
|
||||
- `contextVisibility: "allowlist"` 将补充上下文过滤为仅允许名单中的发送者。
|
||||
- `contextVisibility: "allowlist_quote"` 等同于 `allowlist`,再加上一个明确的引用/回复例外。
|
||||
- `contextVisibility: "all"`(默认)保持当前“按接收原样处理”的行为。
|
||||
- `contextVisibility: "allowlist"` 会将补充上下文过滤为仅限允许列表中的发送者。
|
||||
- `contextVisibility: "allowlist_quote"` 等于 `allowlist`,再加上一条显式的引用/回复例外规则。
|
||||
|
||||
在这一加固模型尚未在各渠道中一致实现之前,不同平台界面间的行为差异仍然是预期之内的。
|
||||
在这一加固模型尚未在所有渠道中一致实现之前,不同界面的行为仍会有所差异。
|
||||
|
||||

|
||||

|
||||
|
||||
如果你想要……
|
||||
|
||||
| 目标 | 应设置的内容 |
|
||||
| 目标 | 需要设置什么 |
|
||||
| -------------------------------------------- | ---------------------------------------------------------- |
|
||||
| 允许所有群组,但仅在 @提及时回复 | `groups: { "*": { requireMention: true } }` |
|
||||
| 允许所有群组,但只在 @提及时回复 | `groups: { "*": { requireMention: true } }` |
|
||||
| 禁用所有群组回复 | `groupPolicy: "disabled"` |
|
||||
| 仅允许特定群组 | `groups: { "<group-id>": { ... } }`(不使用 `"*"` 键) |
|
||||
| 只有你能在群组中触发 | `groupPolicy: "allowlist"`,`groupAllowFrom: ["+1555..."]` |
|
||||
| 只允许特定群组 | `groups: { "<group-id>": { ... } }`(不使用 `"*"` 键) |
|
||||
| 只有你可以在群组中触发 OpenClaw | `groupPolicy: "allowlist"`, `groupAllowFrom: ["+1555..."]` |
|
||||
|
||||
## 会话键
|
||||
|
||||
- 群组会话使用 `agent:<agentId>:<channel>:group:<id>` 会话键(房间/渠道使用 `agent:<agentId>:<channel>:channel:<id>`)。
|
||||
- 群组会话使用 `agent:<agentId>:<channel>:group:<id>` 会话键(房间/频道使用 `agent:<agentId>:<channel>:channel:<id>`)。
|
||||
- Telegram 论坛主题会在群组 id 后附加 `:topic:<threadId>`,因此每个主题都有自己的会话。
|
||||
- 直接聊天使用主会话(或按配置为每个发送者分别使用)。
|
||||
- 私聊使用主会话(或在已配置时按发送者分开)。
|
||||
- 群组会话会跳过心跳。
|
||||
|
||||
<a id="pattern-personal-dms-public-groups-single-agent"></a>
|
||||
|
||||
## 模式:个人私信 + 公开群组(单个智能体)
|
||||
## 模式:个人私信 + 公开群组(单智能体)
|
||||
|
||||
可以——如果你的“个人”流量是**私信**,而你的“公开”流量是**群组**,这种方式效果很好。
|
||||
可以——如果你的“个人”流量是**私信**,而“公开”流量是**群组**,这个模式效果很好。
|
||||
|
||||
原因是:在单智能体模式下,私信通常会进入**主**会话键(`agent:main:main`),而群组始终使用**非主**会话键(`agent:main:<channel>:group:<id>`)。如果你启用 `mode: "non-main"` 的沙箱隔离,这些群组会话会在 Docker 中运行,而你的主私信会话仍在主机上运行。
|
||||
原因是:在单智能体模式下,私信通常会进入**主**会话键(`agent:main:main`),而群组始终使用**非主**会话键(`agent:main:<channel>:group:<id>`)。如果你启用沙箱隔离并设置 `mode: "non-main"`,这些群组会话就会在 Docker 中运行,而你的主私信会话仍然留在主机上运行。
|
||||
|
||||
这会给你一个智能体“脑”(共享工作区 + 记忆),但有两种不同的执行姿态:
|
||||
这样你就拥有一个智能体“脑”(共享工作区 + 记忆),但两种执行姿态:
|
||||
|
||||
- **私信**:完整工具(主机)
|
||||
- **群组**:沙箱 + 受限工具(Docker)
|
||||
|
||||
> 如果你需要真正分离的工作区/人格(“个人”和“公开”绝不能混用),请使用第二个智能体 + 绑定。参见 [多智能体路由](/zh-CN/concepts/multi-agent)。
|
||||
> 如果你需要真正独立的工作区/角色(“个人”和“公开”绝不能混在一起),请使用第二个智能体 + 绑定。参见 [Multi-Agent Routing](/zh-CN/concepts/multi-agent)。
|
||||
|
||||
示例(私信在主机上运行,群组启用沙箱隔离 + 仅限消息工具):
|
||||
示例(私信在主机上,群组使用沙箱隔离且仅允许消息类工具):
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -123,7 +123,7 @@ otherwise -> reply
|
||||
}
|
||||
```
|
||||
|
||||
想要“群组只能看到文件夹 X”,而不是“完全不能访问主机”?保留 `workspaceAccess: "none"`,并只将允许名单中的路径挂载到沙箱中:
|
||||
想要实现“群组只能看到文件夹 X”而不是“完全不能访问主机”?保留 `workspaceAccess: "none"`,然后只把允许列表中的路径挂载进沙箱:
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -147,18 +147,18 @@ otherwise -> reply
|
||||
|
||||
相关内容:
|
||||
|
||||
- 配置键和默认值:[Gateway 网关配置](/zh-CN/gateway/configuration-reference#agentsdefaultssandbox)
|
||||
- 调试某个工具为何被阻止:[沙箱 vs 工具策略 vs 提权](/zh-CN/gateway/sandbox-vs-tool-policy-vs-elevated)
|
||||
- 配置键与默认值:[Gateway 配置](/zh-CN/gateway/configuration-reference#agentsdefaultssandbox)
|
||||
- 调试为什么某个工具被阻止:[沙箱隔离 vs Tool Policy vs Elevated](/zh-CN/gateway/sandbox-vs-tool-policy-vs-elevated)
|
||||
- 绑定挂载详情:[沙箱隔离](/zh-CN/gateway/sandboxing#custom-bind-mounts)
|
||||
|
||||
## 显示标签
|
||||
|
||||
- UI 标签在可用时使用 `displayName`,格式为 `<channel>:<token>`。
|
||||
- `#room` 保留给房间/渠道;群聊使用 `g-<slug>`(小写,空格转为 `-`,保留 `#@+._-`)。
|
||||
- `#room` 保留给房间/频道;群聊使用 `g-<slug>`(小写,空格转为 `-`,保留 `#@+._-`)。
|
||||
|
||||
## 群组策略
|
||||
|
||||
控制每个渠道如何处理群组/房间消息:
|
||||
按渠道控制如何处理群组/房间消息:
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -197,8 +197,8 @@ otherwise -> reply
|
||||
groupPolicy: "allowlist",
|
||||
groupAllowFrom: ["@owner:example.org"],
|
||||
groups: {
|
||||
"!roomId:example.org": { allow: true },
|
||||
"#alias:example.org": { allow: true },
|
||||
"!roomId:example.org": { enabled: true },
|
||||
"#alias:example.org": { enabled: true },
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -207,34 +207,34 @@ otherwise -> reply
|
||||
|
||||
| 策略 | 行为 |
|
||||
| ------------- | ------------------------------------------------------------ |
|
||||
| `"open"` | 群组绕过允许名单;提及门控仍然适用。 |
|
||||
| `"open"` | 群组会绕过允许列表;但提及门控仍然生效。 |
|
||||
| `"disabled"` | 完全阻止所有群组消息。 |
|
||||
| `"allowlist"` | 仅允许与配置的允许名单匹配的群组/房间。 |
|
||||
| `"allowlist"` | 仅允许与已配置允许列表匹配的群组/房间。 |
|
||||
|
||||
说明:
|
||||
|
||||
- `groupPolicy` 与提及门控是分开的(后者要求使用 @提及)。
|
||||
- WhatsApp/Telegram/Signal/iMessage/Microsoft Teams/Zalo:使用 `groupAllowFrom`(回退为显式 `allowFrom`)。
|
||||
- 私信配对批准(`*-allowFrom` 存储条目)仅适用于私信访问;群组发送者授权仍需通过群组允许名单显式配置。
|
||||
- Discord:允许名单使用 `channels.discord.guilds.<id>.channels`。
|
||||
- Slack:允许名单使用 `channels.slack.channels`。
|
||||
- Matrix:允许名单使用 `channels.matrix.groups`。优先使用房间 ID 或别名;已加入房间的名称查询仅尽力而为,运行时无法解析的名称会被忽略。使用 `channels.matrix.groupAllowFrom` 来限制发送者;也支持按房间配置的 `users` 允许名单。
|
||||
- 群组私信是单独控制的(`channels.discord.dm.*`、`channels.slack.dm.*`)。
|
||||
- Telegram 允许名单可以匹配用户 ID(`"123456789"`、`"telegram:123456789"`、`"tg:123456789"`)或用户名(`"@alice"` 或 `"alice"`);前缀大小写不敏感。
|
||||
- 默认值为 `groupPolicy: "allowlist"`;如果你的群组允许名单为空,群组消息将被阻止。
|
||||
- 运行时安全性:当某个提供商配置块完全缺失(没有 `channels.<provider>`)时,群组策略会回退到故障关闭模式(通常为 `allowlist`),而不是继承 `channels.defaults.groupPolicy`。
|
||||
- `groupPolicy` 与提及门控是分开的(提及门控要求 @提及)。
|
||||
- WhatsApp/Telegram/Signal/iMessage/Microsoft Teams/Zalo:使用 `groupAllowFrom`(回退:显式 `allowFrom`)。
|
||||
- 私信配对审批(`*-allowFrom` 存储项)只适用于私信访问;群组发送者授权仍需要在群组允许列表中显式配置。
|
||||
- Discord:允许列表使用 `channels.discord.guilds.<id>.channels`。
|
||||
- Slack:允许列表使用 `channels.slack.channels`。
|
||||
- Matrix:允许列表使用 `channels.matrix.groups`。优先使用房间 ID 或别名;已加入房间的名称查询是尽力而为,运行时无法解析的名称会被忽略。使用 `channels.matrix.groupAllowFrom` 来限制发送者;也支持按房间配置的 `users` 允许列表。
|
||||
- 群组私信单独控制(`channels.discord.dm.*`、`channels.slack.dm.*`)。
|
||||
- Telegram 允许列表可以匹配用户 ID(`"123456789"`、`"telegram:123456789"`、`"tg:123456789"`)或用户名(`"@alice"` 或 `"alice"`);前缀大小写不敏感。
|
||||
- 默认值是 `groupPolicy: "allowlist"`;如果你的群组允许列表为空,群组消息会被阻止。
|
||||
- 运行时安全:当某个提供商配置块完全缺失(`channels.<provider>` 不存在)时,群组策略会回退到故障关闭模式(通常是 `allowlist`),而不是继承 `channels.defaults.groupPolicy`。
|
||||
|
||||
快速心智模型(群组消息的评估顺序):
|
||||
|
||||
1. `groupPolicy`(open/disabled/allowlist)
|
||||
2. 群组允许名单(`*.groups`、`*.groupAllowFrom`、渠道特定允许名单)
|
||||
2. 群组允许列表(`*.groups`、`*.groupAllowFrom`、渠道特定允许列表)
|
||||
3. 提及门控(`requireMention`、`/activation`)
|
||||
|
||||
## 提及门控(默认)
|
||||
|
||||
群组消息默认需要提及,除非按群组覆盖。默认值按子系统存放在 `*.groups."*"` 下。
|
||||
|
||||
回复机器人消息会被视为隐式提及(前提是该渠道支持回复元数据)。这适用于 Telegram、WhatsApp、Slack、Discord 和 Microsoft Teams。
|
||||
回复机器人消息会被视为隐式提及(当渠道支持回复元数据时)。这适用于 Telegram、WhatsApp、Slack、Discord 和 Microsoft Teams。
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -275,26 +275,26 @@ otherwise -> reply
|
||||
说明:
|
||||
|
||||
- `mentionPatterns` 是大小写不敏感的安全正则模式;无效模式和不安全的嵌套重复形式会被忽略。
|
||||
- 提供显式提及的平台界面仍然会通过;这些模式只是回退方案。
|
||||
- 提供显式提及的界面仍然会通过;这些模式只是回退方案。
|
||||
- 按智能体覆盖:`agents.list[].groupChat.mentionPatterns`(当多个智能体共享一个群组时很有用)。
|
||||
- 只有在可以进行提及检测时,才会强制执行提及门控(存在原生提及或已配置 `mentionPatterns`)。
|
||||
- Discord 的默认值位于 `channels.discord.guilds."*"`(可按 guild/channel 覆盖)。
|
||||
- 群组历史上下文会在各渠道间统一包装,并且仅限于**待处理消息**(即因提及门控而被跳过的消息);全局默认值使用 `messages.groupChat.historyLimit`,覆盖项使用 `channels.<channel>.historyLimit`(或 `channels.<channel>.accounts.*.historyLimit`)。设为 `0` 可禁用。
|
||||
- 只有在能够检测提及时,才会强制执行提及门控(原生提及或已配置 `mentionPatterns`)。
|
||||
- Discord 默认值位于 `channels.discord.guilds."*"`(可按 guild/channel 覆盖)。
|
||||
- 群组历史上下文会在各个渠道中统一包装,并且仅包含**待处理消息**(即因提及门控而跳过的消息);全局默认值使用 `messages.groupChat.historyLimit`,覆盖项使用 `channels.<channel>.historyLimit`(或 `channels.<channel>.accounts.*.historyLimit`)。设为 `0` 可禁用。
|
||||
|
||||
## 群组/渠道工具限制(可选)
|
||||
## 群组/频道工具限制(可选)
|
||||
|
||||
某些渠道配置支持限制**特定群组/房间/渠道内部**可用的工具。
|
||||
某些渠道配置支持限制**特定群组/房间/频道内**可用的工具。
|
||||
|
||||
- `tools`:为整个群组允许/拒绝工具。
|
||||
- `toolsBySender`:群组内按发送者覆盖。
|
||||
使用显式键前缀:
|
||||
`id:<senderId>`、`e164:<phone>`、`username:<handle>`、`name:<displayName>` 以及 `"*"` 通配符。
|
||||
旧版无前缀键仍然接受,但仅按 `id:` 匹配。
|
||||
`id:<senderId>`、`e164:<phone>`、`username:<handle>`、`name:<displayName>` 和 `"*"` 通配符。
|
||||
旧版无前缀键仍然被接受,但只会按 `id:` 匹配。
|
||||
|
||||
解析顺序(越具体优先级越高):
|
||||
|
||||
1. 群组/渠道 `toolsBySender` 匹配
|
||||
2. 群组/渠道 `tools`
|
||||
1. 群组/频道 `toolsBySender` 匹配
|
||||
2. 群组/频道 `tools`
|
||||
3. 默认(`"*"`)`toolsBySender` 匹配
|
||||
4. 默认(`"*"`)`tools`
|
||||
|
||||
@ -320,15 +320,15 @@ otherwise -> reply
|
||||
|
||||
说明:
|
||||
|
||||
- 群组/渠道工具限制会与全局/智能体工具策略叠加应用(拒绝仍然优先)。
|
||||
- 某些渠道对房间/渠道使用不同的嵌套结构(例如 Discord `guilds.*.channels.*`、Slack `channels.*`、Microsoft Teams `teams.*.channels.*`)。
|
||||
- 群组/频道工具限制是在全局/智能体工具策略之外额外应用的(deny 仍然优先)。
|
||||
- 某些渠道对房间/频道使用不同的嵌套结构(例如 Discord `guilds.*.channels.*`、Slack `channels.*`、Microsoft Teams `teams.*.channels.*`)。
|
||||
|
||||
## 群组允许名单
|
||||
## 群组允许列表
|
||||
|
||||
当配置了 `channels.whatsapp.groups`、`channels.telegram.groups` 或 `channels.imessage.groups` 时,这些键会作为群组允许名单。使用 `"*"` 可允许所有群组,同时仍设置默认提及行为。
|
||||
当配置了 `channels.whatsapp.groups`、`channels.telegram.groups` 或 `channels.imessage.groups` 时,这些键会充当群组允许列表。使用 `"*"` 可允许所有群组,同时仍然设置默认提及行为。
|
||||
|
||||
一个常见误解是:私信配对批准并不等同于群组授权。
|
||||
对于支持私信配对的渠道,配对存储仅解锁私信。群组命令仍然需要通过配置允许名单显式授权群组发送者,例如 `groupAllowFrom` 或该渠道文档中说明的配置回退项。
|
||||
常见困惑:私信配对审批并不等同于群组授权。
|
||||
对于支持私信配对的渠道,配对存储只会解锁私信。群组命令仍然需要通过配置允许列表显式授权群组发送者,例如 `groupAllowFrom` 或该渠道文档说明的回退配置。
|
||||
|
||||
常见意图(可直接复制粘贴):
|
||||
|
||||
@ -383,35 +383,35 @@ otherwise -> reply
|
||||
|
||||
## 激活(仅所有者)
|
||||
|
||||
群组所有者可以切换每个群组的激活方式:
|
||||
群组所有者可以按群组切换激活模式:
|
||||
|
||||
- `/activation mention`
|
||||
- `/activation always`
|
||||
|
||||
所有者由 `channels.whatsapp.allowFrom` 决定(未设置时则为机器人的自身 E.164)。请将命令作为单独一条消息发送。其他平台界面当前会忽略 `/activation`。
|
||||
所有者由 `channels.whatsapp.allowFrom` 决定(如果未设置,则使用机器人自身的 E.164)。请将命令作为单独一条消息发送。其他界面当前会忽略 `/activation`。
|
||||
|
||||
## 上下文字段
|
||||
|
||||
群组入站载荷会设置:
|
||||
群组入站负载会设置:
|
||||
|
||||
- `ChatType=group`
|
||||
- `GroupSubject`(如果已知)
|
||||
- `GroupMembers`(如果已知)
|
||||
- `WasMentioned`(提及门控结果)
|
||||
- Telegram 论坛主题还会包含 `MessageThreadId` 和 `IsForum`
|
||||
- Telegram 论坛主题还会包含 `MessageThreadId` 和 `IsForum`。
|
||||
|
||||
渠道特定说明:
|
||||
|
||||
- BlueBubbles 可以选择在填充 `GroupMembers` 之前,先从本地通讯录数据库中补全未命名的 macOS 群组参与者信息。该功能默认关闭,并且只会在正常群组门控通过后运行。
|
||||
- BlueBubbles 可以在填充 `GroupMembers` 之前,选择性地从本地 Contacts 数据库中补充未命名的 macOS 群组参与者信息。此功能默认关闭,并且只会在常规群组门控通过后运行。
|
||||
|
||||
智能体系统提示会在新群组会话的第一轮包含一段群组简介。它会提醒模型像人类一样回复、避免使用 Markdown 表格、尽量减少空行并遵循正常聊天间距,同时避免输入字面量 `\n` 序列。
|
||||
智能体系统提示会在新群组会话的第一轮加入群组说明。它会提醒模型像人类一样回复、避免使用 Markdown 表格、尽量减少空行、遵循正常聊天间距,并避免输入字面量 `\n` 序列。
|
||||
|
||||
## iMessage 细节
|
||||
|
||||
- 在路由或加入允许名单时,优先使用 `chat_id:<id>`。
|
||||
- 在路由或允许列表中优先使用 `chat_id:<id>`。
|
||||
- 列出聊天:`imsg chats --limit 20`。
|
||||
- 群组回复始终会发回相同的 `chat_id`。
|
||||
|
||||
## WhatsApp 细节
|
||||
|
||||
有关 WhatsApp 专属行为(历史注入、提及处理细节),请参见 [群组消息](/zh-CN/channels/group-messages)。
|
||||
有关 WhatsApp 专属行为(历史注入、提及处理细节),请参见 [群消息](/zh-CN/channels/group-messages)。
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -1,20 +1,20 @@
|
||||
---
|
||||
read_when:
|
||||
- 处理 WhatsApp / web 渠道行为或收件箱路由时
|
||||
summary: WhatsApp 渠道支持、访问控制、传递行为和运维
|
||||
- 处理 WhatsApp/web 渠道行为或收件箱路由时
|
||||
summary: WhatsApp 渠道支持、访问控制、消息传递行为和运维
|
||||
title: WhatsApp
|
||||
x-i18n:
|
||||
generated_at: "2026-04-05T08:19:07Z"
|
||||
generated_at: "2026-04-06T15:28:05Z"
|
||||
model: gpt-5.4
|
||||
provider: openai
|
||||
source_hash: c16a468b3f47fdf7e4fc3fd745b5c49c7ccebb7af0e8c87c632b78b04c583e49
|
||||
source_hash: 9e2ce84d869ace6c0bebd9ec17bdbbef997a5c31e5da410b02a19a0f103f7359
|
||||
source_path: channels/whatsapp.md
|
||||
workflow: 15
|
||||
---
|
||||
|
||||
# WhatsApp(Web 渠道)
|
||||
|
||||
状态:通过 WhatsApp Web(Baileys)已可用于生产环境。Gateway 网关拥有已关联的会话。
|
||||
状态:通过 WhatsApp Web(Baileys)可用于生产环境。Gateway 网关拥有已关联的会话。
|
||||
|
||||
## 安装(按需)
|
||||
|
||||
@ -23,7 +23,7 @@ x-i18n:
|
||||
- `openclaw channels login --channel whatsapp` 也会在
|
||||
插件尚未安装时提供安装流程。
|
||||
- 开发渠道 + git 检出:默认使用本地插件路径。
|
||||
- Stable / Beta:默认使用 npm 包 `@openclaw/whatsapp`。
|
||||
- 稳定版/Beta 版:默认使用 npm 包 `@openclaw/whatsapp`。
|
||||
|
||||
你仍然可以手动安装:
|
||||
|
||||
@ -32,13 +32,13 @@ openclaw plugins install @openclaw/whatsapp
|
||||
```
|
||||
|
||||
<CardGroup cols={3}>
|
||||
<Card title="配对" icon="link" href="/channels/pairing">
|
||||
对未知发件人的默认私信策略是配对。
|
||||
<Card title="配对" icon="link" href="/zh-CN/channels/pairing">
|
||||
未知发件人的默认私信策略是配对。
|
||||
</Card>
|
||||
<Card title="渠道故障排除" icon="wrench" href="/channels/troubleshooting">
|
||||
跨渠道诊断和修复操作手册。
|
||||
<Card title="渠道故障排除" icon="wrench" href="/zh-CN/channels/troubleshooting">
|
||||
跨渠道诊断与修复操作手册。
|
||||
</Card>
|
||||
<Card title="Gateway 网关配置" icon="settings" href="/gateway/configuration">
|
||||
<Card title="Gateway 网关配置" icon="settings" href="/zh-CN/gateway/configuration">
|
||||
完整的渠道配置模式和示例。
|
||||
</Card>
|
||||
</CardGroup>
|
||||
@ -69,7 +69,7 @@ openclaw plugins install @openclaw/whatsapp
|
||||
openclaw channels login --channel whatsapp
|
||||
```
|
||||
|
||||
对于特定账户:
|
||||
对于特定账号:
|
||||
|
||||
```bash
|
||||
openclaw channels login --channel whatsapp --account work
|
||||
@ -98,7 +98,7 @@ openclaw pairing approve whatsapp <CODE>
|
||||
</Steps>
|
||||
|
||||
<Note>
|
||||
OpenClaw 建议尽可能为 WhatsApp 使用单独的号码。(渠道元数据和设置流程都针对这种设置进行了优化,但也支持个人号码设置。)
|
||||
OpenClaw 建议在条件允许时为 WhatsApp 使用单独的号码。(渠道元数据和设置流程已针对这种设置进行了优化,但也支持个人号码设置。)
|
||||
</Note>
|
||||
|
||||
## 部署模式
|
||||
@ -107,7 +107,7 @@ OpenClaw 建议尽可能为 WhatsApp 使用单独的号码。(渠道元数据
|
||||
<Accordion title="专用号码(推荐)">
|
||||
这是最清晰的运维模式:
|
||||
|
||||
- 为 OpenClaw 使用独立的 WhatsApp 身份
|
||||
- OpenClaw 使用单独的 WhatsApp 身份
|
||||
- 更清晰的私信允许列表和路由边界
|
||||
- 更低的自聊混淆概率
|
||||
|
||||
@ -127,18 +127,18 @@ OpenClaw 建议尽可能为 WhatsApp 使用单独的号码。(渠道元数据
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="个人号码回退方案">
|
||||
新手引导支持个人号码模式,并会写入适合自聊的基线配置:
|
||||
新手引导支持个人号码模式,并会写入适合自聊的基础配置:
|
||||
|
||||
- `dmPolicy: "allowlist"`
|
||||
- `allowFrom` 包含你的个人号码
|
||||
- `selfChatMode: true`
|
||||
|
||||
在运行时,自聊保护基于已关联的自身号码和 `allowFrom` 生效。
|
||||
在运行时,自聊保护会依据已关联的自身号码和 `allowFrom` 生效。
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="仅限 WhatsApp Web 的渠道范围">
|
||||
在当前的 OpenClaw 渠道架构中,该消息平台渠道基于 WhatsApp Web(`Baileys`)。
|
||||
<Accordion title="仅 WhatsApp Web 的渠道范围">
|
||||
在当前 OpenClaw 渠道架构中,该消息平台渠道基于 WhatsApp Web(`Baileys`)。
|
||||
|
||||
内置聊天渠道注册表中没有单独的 Twilio WhatsApp 消息渠道。
|
||||
|
||||
@ -148,12 +148,13 @@ OpenClaw 建议尽可能为 WhatsApp 使用单独的号码。(渠道元数据
|
||||
## 运行时模型
|
||||
|
||||
- Gateway 网关拥有 WhatsApp socket 和重连循环。
|
||||
- 出站发送要求目标账户存在活动中的 WhatsApp 监听器。
|
||||
- 出站发送要求目标账号存在活动中的 WhatsApp 监听器。
|
||||
- 状态和广播聊天会被忽略(`@status`、`@broadcast`)。
|
||||
- 私聊使用私信会话规则(`session.dmScope`;默认 `main` 会将私信折叠到智能体主会话)。
|
||||
- 群组会话彼此隔离(`agent:<agentId>:whatsapp:group:<jid>`)。
|
||||
- WhatsApp Web 传输遵循 Gateway 网关主机上的标准代理环境变量(`HTTPS_PROXY`、`HTTP_PROXY`、`NO_PROXY` 及其小写变体)。优先使用主机级代理配置,而不是渠道专用的 WhatsApp 代理设置。
|
||||
|
||||
## 访问控制和激活
|
||||
## 访问控制与激活
|
||||
|
||||
<Tabs>
|
||||
<Tab title="私信策略">
|
||||
@ -164,14 +165,14 @@ OpenClaw 建议尽可能为 WhatsApp 使用单独的号码。(渠道元数据
|
||||
- `open`(要求 `allowFrom` 包含 `"*"`)
|
||||
- `disabled`
|
||||
|
||||
`allowFrom` 接受 E.164 风格的号码(内部会标准化)。
|
||||
`allowFrom` 接受 E.164 风格号码(内部会标准化)。
|
||||
|
||||
多账户覆盖:`channels.whatsapp.accounts.<id>.dmPolicy`(以及 `allowFrom`)会优先于该账户的渠道级默认值。
|
||||
多账号覆盖:`channels.whatsapp.accounts.<id>.dmPolicy`(以及 `allowFrom`)会优先于该账号的渠道级默认值。
|
||||
|
||||
运行时行为细节:
|
||||
|
||||
- 配对关系会持久化到渠道允许存储中,并与已配置的 `allowFrom` 合并
|
||||
- 如果未配置允许列表,则默认允许已关联的自身号码
|
||||
- 配对会持久化到渠道允许存储中,并与已配置的 `allowFrom` 合并
|
||||
- 如果未配置任何允许列表,则默认允许已关联的自身号码
|
||||
- 出站 `fromMe` 私信永远不会自动配对
|
||||
|
||||
</Tab>
|
||||
@ -179,9 +180,9 @@ OpenClaw 建议尽可能为 WhatsApp 使用单独的号码。(渠道元数据
|
||||
<Tab title="群组策略 + 允许列表">
|
||||
群组访问有两层:
|
||||
|
||||
1. **群组成员资格允许列表**(`channels.whatsapp.groups`)
|
||||
- 如果省略 `groups`,则所有群组都符合条件
|
||||
- 如果存在 `groups`,它会作为群组允许列表(允许 `"*"`)
|
||||
1. **群组成员允许列表**(`channels.whatsapp.groups`)
|
||||
- 如果省略 `groups`,则所有群组都有资格
|
||||
- 如果存在 `groups`,它会作为群组允许列表使用(允许 `"*"`)
|
||||
|
||||
2. **群组发件人策略**(`channels.whatsapp.groupPolicy` + `groupAllowFrom`)
|
||||
- `open`:绕过发件人允许列表
|
||||
@ -191,51 +192,51 @@ OpenClaw 建议尽可能为 WhatsApp 使用单独的号码。(渠道元数据
|
||||
发件人允许列表回退规则:
|
||||
|
||||
- 如果未设置 `groupAllowFrom`,运行时会在可用时回退到 `allowFrom`
|
||||
- 在评估提及 / 回复激活之前,会先评估发件人允许列表
|
||||
- 发件人允许列表会在提及/回复激活之前进行评估
|
||||
|
||||
注意:如果根本不存在 `channels.whatsapp` 配置块,即使设置了 `channels.defaults.groupPolicy`,运行时的群组策略回退值仍是 `allowlist`(并会记录警告日志)。
|
||||
注意:如果根本不存在 `channels.whatsapp` 配置块,运行时群组策略回退值为 `allowlist`(并记录警告日志),即使设置了 `channels.defaults.groupPolicy` 也是如此。
|
||||
|
||||
</Tab>
|
||||
|
||||
<Tab title="提及 + /activation">
|
||||
群组回复默认需要被提及。
|
||||
群组回复默认要求被提及。
|
||||
|
||||
提及检测包括:
|
||||
|
||||
- 明确提及机器人的 WhatsApp 提及
|
||||
- 已配置的提及正则模式(`agents.list[].groupChat.mentionPatterns`,回退到 `messages.groupChat.mentionPatterns`)
|
||||
- 隐式回复机器人检测(回复发送者与机器人身份匹配)
|
||||
- 对机器人身份的显式 WhatsApp 提及
|
||||
- 已配置的提及正则模式(`agents.list[].groupChat.mentionPatterns`,回退为 `messages.groupChat.mentionPatterns`)
|
||||
- 隐式回复给机器人的检测(回复发送者与机器人身份匹配)
|
||||
|
||||
安全说明:
|
||||
|
||||
- 引用 / 回复只会满足提及门控;**不会**授予发件人授权
|
||||
- 当 `groupPolicy: "allowlist"` 时,即使非允许列表中的发件人回复允许列表用户的消息,仍然会被阻止
|
||||
- 引用/回复只会满足提及门控;它**不会**授予发件人授权
|
||||
- 使用 `groupPolicy: "allowlist"` 时,未在允许列表中的发件人即使回复了允许列表用户的消息,仍然会被阻止
|
||||
|
||||
会话级激活命令:
|
||||
|
||||
- `/activation mention`
|
||||
- `/activation always`
|
||||
|
||||
`activation` 会更新会话状态(不是全局配置)。它受 owner 门控控制。
|
||||
`activation` 会更新会话状态(而不是全局配置)。它受所有者权限控制。
|
||||
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
## 个人号码和自聊行为
|
||||
|
||||
当已关联的自身号码也存在于 `allowFrom` 中时,WhatsApp 自聊保护会激活:
|
||||
当已关联的自身号码也存在于 `allowFrom` 中时,WhatsApp 自聊保护会启用:
|
||||
|
||||
- 跳过自聊轮次的已读回执
|
||||
- 忽略本会导致你自己被 ping 的 mention-JID 自动触发行为
|
||||
- 跳过自聊回合的已读回执
|
||||
- 忽略原本会提醒你自己的 mention-JID 自动触发行为
|
||||
- 如果未设置 `messages.responsePrefix`,自聊回复默认使用 `[{identity.name}]` 或 `[openclaw]`
|
||||
|
||||
## 消息标准化和上下文
|
||||
|
||||
<AccordionGroup>
|
||||
<Accordion title="入站封装 + 回复上下文">
|
||||
传入的 WhatsApp 消息会包装到共享入站封装中。
|
||||
<Accordion title="入站信封 + 回复上下文">
|
||||
传入的 WhatsApp 消息会被包装进共享的入站信封中。
|
||||
|
||||
如果存在引用回复,上下文会以如下形式附加:
|
||||
如果存在引用回复,上下文会按以下形式附加:
|
||||
|
||||
```text
|
||||
[Replying to <sender> id:<stanzaId>]
|
||||
@ -243,12 +244,12 @@ OpenClaw 建议尽可能为 WhatsApp 使用单独的号码。(渠道元数据
|
||||
[/Replying]
|
||||
```
|
||||
|
||||
可用时还会填充回复元数据字段(`ReplyToId`、`ReplyToBody`、`ReplyToSender`、发件人 JID / E.164)。
|
||||
回复元数据字段也会在可用时填充(`ReplyToId`、`ReplyToBody`、`ReplyToSender`、发送者 JID/E.164)。
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="媒体占位符和位置 / 联系人提取">
|
||||
仅媒体的入站消息会使用如下占位符标准化:
|
||||
<Accordion title="媒体占位符以及位置/联系人提取">
|
||||
仅含媒体的入站消息会被标准化为如下占位符:
|
||||
|
||||
- `<media:image>`
|
||||
- `<media:video>`
|
||||
@ -261,7 +262,7 @@ OpenClaw 建议尽可能为 WhatsApp 使用单独的号码。(渠道元数据
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="待处理群组历史注入">
|
||||
对于群组,当机器人最终被触发时,未处理的消息可以先缓冲并作为上下文注入。
|
||||
对于群组,当机器人最终被触发时,未处理消息可以被缓冲并作为上下文注入。
|
||||
|
||||
- 默认上限:`50`
|
||||
- 配置:`channels.whatsapp.historyLimit`
|
||||
@ -276,7 +277,7 @@ OpenClaw 建议尽可能为 WhatsApp 使用单独的号码。(渠道元数据
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="已读回执">
|
||||
已接受的入站 WhatsApp 消息默认启用已读回执。
|
||||
对于已接受的入站 WhatsApp 消息,默认启用已读回执。
|
||||
|
||||
全局禁用:
|
||||
|
||||
@ -290,7 +291,7 @@ OpenClaw 建议尽可能为 WhatsApp 使用单独的号码。(渠道元数据
|
||||
}
|
||||
```
|
||||
|
||||
按账户覆盖:
|
||||
按账号覆盖:
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -306,7 +307,7 @@ OpenClaw 建议尽可能为 WhatsApp 使用单独的号码。(渠道元数据
|
||||
}
|
||||
```
|
||||
|
||||
即使全局启用,自聊轮次也会跳过已读回执。
|
||||
即使全局已启用,自聊回合也会跳过已读回执。
|
||||
|
||||
</Accordion>
|
||||
</AccordionGroup>
|
||||
@ -323,7 +324,7 @@ OpenClaw 建议尽可能为 WhatsApp 使用单独的号码。(渠道元数据
|
||||
<Accordion title="出站媒体行为">
|
||||
- 支持图片、视频、音频(PTT 语音便笺)和文档载荷
|
||||
- `audio/ogg` 会被改写为 `audio/ogg; codecs=opus` 以兼容语音便笺
|
||||
- 通过在视频发送中设置 `gifPlayback: true` 支持动画 GIF 播放
|
||||
- 通过在视频发送时设置 `gifPlayback: true` 支持动态 GIF 播放
|
||||
- 发送多媒体回复载荷时,说明文字会应用到第一个媒体项
|
||||
- 媒体来源可以是 HTTP(S)、`file://` 或本地路径
|
||||
</Accordion>
|
||||
@ -331,26 +332,26 @@ OpenClaw 建议尽可能为 WhatsApp 使用单独的号码。(渠道元数据
|
||||
<Accordion title="媒体大小限制和回退行为">
|
||||
- 入站媒体保存上限:`channels.whatsapp.mediaMaxMb`(默认 `50`)
|
||||
- 出站媒体发送上限:`channels.whatsapp.mediaMaxMb`(默认 `50`)
|
||||
- 按账户覆盖使用 `channels.whatsapp.accounts.<accountId>.mediaMaxMb`
|
||||
- 图片会自动优化(调整尺寸 / 质量扫描)以满足限制
|
||||
- 按账号覆盖使用 `channels.whatsapp.accounts.<accountId>.mediaMaxMb`
|
||||
- 图片会自动优化(调整尺寸/质量扫描)以适配限制
|
||||
- 媒体发送失败时,首项回退会发送文本警告,而不是静默丢弃响应
|
||||
</Accordion>
|
||||
</AccordionGroup>
|
||||
|
||||
## Reaction 级别
|
||||
## 反应级别
|
||||
|
||||
`channels.whatsapp.reactionLevel` 控制智能体在 WhatsApp 上使用 emoji reaction 的广泛程度:
|
||||
`channels.whatsapp.reactionLevel` 控制智能体在 WhatsApp 上使用表情反应的范围:
|
||||
|
||||
| 级别 | 确认 reaction | 智能体主动发起的 reaction | 说明 |
|
||||
| ------------ | ------------- | ------------------------- | ------------------------------------- |
|
||||
| `"off"` | 否 | 否 | 完全不使用 reaction |
|
||||
| `"ack"` | 是 | 否 | 仅确认 reaction(回复前确认) |
|
||||
| `"minimal"` | 是 | 是(保守) | 确认 + 带保守引导的智能体 reaction |
|
||||
| `"extensive"`| 是 | 是(鼓励) | 确认 + 带鼓励性引导的智能体 reaction |
|
||||
| 级别 | 确认反应 | 智能体主动发起的反应 | 描述 |
|
||||
| ------------- | ------------- | ------------------------- | ------------------------------------------------ |
|
||||
| `"off"` | 否 | 否 | 完全不使用反应 |
|
||||
| `"ack"` | 是 | 否 | 仅确认反应(回复前确认已收到) |
|
||||
| `"minimal"` | 是 | 是(保守) | 确认 + 智能体反应,采用保守指引 |
|
||||
| `"extensive"` | 是 | 是(鼓励) | 确认 + 智能体反应,采用鼓励性指引 |
|
||||
|
||||
默认值:`"minimal"`。
|
||||
|
||||
按账户覆盖使用 `channels.whatsapp.accounts.<id>.reactionLevel`。
|
||||
按账号覆盖使用 `channels.whatsapp.accounts.<id>.reactionLevel`。
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -362,10 +363,10 @@ OpenClaw 建议尽可能为 WhatsApp 使用单独的号码。(渠道元数据
|
||||
}
|
||||
```
|
||||
|
||||
## 确认 reaction
|
||||
## 确认反应
|
||||
|
||||
WhatsApp 支持通过 `channels.whatsapp.ackReaction` 在接收入站消息时立即发送确认 reaction。
|
||||
确认 reaction 受 `reactionLevel` 门控控制 —— 当 `reactionLevel` 为 `"off"` 时会被抑制。
|
||||
WhatsApp 支持通过 `channels.whatsapp.ackReaction` 在接收入站消息时立即发送确认反应。
|
||||
确认反应受 `reactionLevel` 控制 —— 当 `reactionLevel` 为 `"off"` 时会被抑制。
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -384,36 +385,36 @@ WhatsApp 支持通过 `channels.whatsapp.ackReaction` 在接收入站消息时
|
||||
行为说明:
|
||||
|
||||
- 在接受入站消息后立即发送(回复前)
|
||||
- 失败会被记录到日志中,但不会阻止正常回复传递
|
||||
- 群组模式 `mentions` 会在由提及触发的轮次中发送 reaction;群组激活 `always` 可绕过此检查
|
||||
- WhatsApp 使用 `channels.whatsapp.ackReaction`(这里不使用旧版 `messages.ackReaction`)
|
||||
- 失败会被记录日志,但不会阻止正常回复投递
|
||||
- 群组模式 `mentions` 会在由提及触发的回合中发送反应;群组激活 `always` 会绕过此检查
|
||||
- WhatsApp 使用 `channels.whatsapp.ackReaction`(这里不会使用旧版 `messages.ackReaction`)
|
||||
|
||||
## 多账户和凭证
|
||||
## 多账号和凭证
|
||||
|
||||
<AccordionGroup>
|
||||
<Accordion title="账户选择和默认值">
|
||||
- 账户 id 来自 `channels.whatsapp.accounts`
|
||||
- 默认账户选择:如果存在则为 `default`,否则为第一个已配置的账户 id(已排序)
|
||||
- 账户 id 会在内部标准化后用于查找
|
||||
<Accordion title="账号选择和默认值">
|
||||
- 账号 id 来自 `channels.whatsapp.accounts`
|
||||
- 默认账号选择:如果存在则为 `default`,否则为第一个已配置的账号 id(已排序)
|
||||
- 账号 id 会在内部标准化以供查找
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="凭证路径和旧版兼容性">
|
||||
- 当前认证路径:`~/.openclaw/credentials/whatsapp/<accountId>/creds.json`
|
||||
- 备份文件:`creds.json.bak`
|
||||
- `~/.openclaw/credentials/` 中的旧版默认认证在默认账户流程中仍会被识别 / 迁移
|
||||
- `~/.openclaw/credentials/` 中的旧版默认认证仍会被识别/迁移,用于默认账号流程
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="登出行为">
|
||||
`openclaw channels logout --channel whatsapp [--account <id>]` 会清除此账户的 WhatsApp 认证状态。
|
||||
`openclaw channels logout --channel whatsapp [--account <id>]` 会清除该账号的 WhatsApp 认证状态。
|
||||
|
||||
在旧版认证目录中,会保留 `oauth.json`,同时删除 Baileys 认证文件。
|
||||
在旧版认证目录中,`oauth.json` 会被保留,而 Baileys 认证文件会被移除。
|
||||
|
||||
</Accordion>
|
||||
</AccordionGroup>
|
||||
|
||||
## 工具、操作和配置写入
|
||||
|
||||
- 智能体工具支持包括 WhatsApp reaction 操作(`react`)。
|
||||
- 智能体工具支持包括 WhatsApp 反应操作(`react`)。
|
||||
- 操作门控:
|
||||
- `channels.whatsapp.actions.reactions`
|
||||
- `channels.whatsapp.actions.polls`
|
||||
@ -423,7 +424,7 @@ WhatsApp 支持通过 `channels.whatsapp.ackReaction` 在接收入站消息时
|
||||
|
||||
<AccordionGroup>
|
||||
<Accordion title="未关联(需要 QR 码)">
|
||||
症状:渠道状态显示未关联。
|
||||
症状:渠道状态报告显示未关联。
|
||||
|
||||
修复方法:
|
||||
|
||||
@ -435,7 +436,7 @@ WhatsApp 支持通过 `channels.whatsapp.ackReaction` 在接收入站消息时
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="已关联但已断开 / 重连循环">
|
||||
症状:账户已关联,但反复断开或尝试重连。
|
||||
症状:已关联账号反复断开或重复尝试重连。
|
||||
|
||||
修复方法:
|
||||
|
||||
@ -449,25 +450,25 @@ WhatsApp 支持通过 `channels.whatsapp.ackReaction` 在接收入站消息时
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="发送时没有活动监听器">
|
||||
当目标账户不存在活动中的 Gateway 网关监听器时,出站发送会快速失败。
|
||||
当目标账号不存在活动中的 Gateway 网关监听器时,出站发送会快速失败。
|
||||
|
||||
请确保 Gateway 网关正在运行,并且该账户已关联。
|
||||
请确保 Gateway 网关正在运行且该账号已关联。
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="群组消息意外被忽略">
|
||||
<Accordion title="群组消息被意外忽略">
|
||||
按以下顺序检查:
|
||||
|
||||
- `groupPolicy`
|
||||
- `groupAllowFrom` / `allowFrom`
|
||||
- `groups` 允许列表项
|
||||
- `groups` 允许列表条目
|
||||
- 提及门控(`requireMention` + 提及模式)
|
||||
- `openclaw.json`(JSON5)中的重复键:后面的条目会覆盖前面的条目,因此每个作用域只保留一个 `groupPolicy`
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Bun 运行时警告">
|
||||
WhatsApp Gateway 网关运行时应使用 Node。Bun 被标记为不兼容稳定的 WhatsApp / Telegram Gateway 网关运行。
|
||||
WhatsApp Gateway 网关运行时应使用 Node。Bun 被标记为不兼容稳定的 WhatsApp/Telegram Gateway 网关运行。
|
||||
</Accordion>
|
||||
</AccordionGroup>
|
||||
|
||||
@ -475,21 +476,21 @@ WhatsApp 支持通过 `channels.whatsapp.ackReaction` 在接收入站消息时
|
||||
|
||||
主要参考:
|
||||
|
||||
- [配置参考 - WhatsApp](/gateway/configuration-reference#whatsapp)
|
||||
- [配置参考 - WhatsApp](/zh-CN/gateway/configuration-reference#whatsapp)
|
||||
|
||||
高信号的 WhatsApp 字段:
|
||||
高信号 WhatsApp 字段:
|
||||
|
||||
- 访问:`dmPolicy`、`allowFrom`、`groupPolicy`、`groupAllowFrom`、`groups`
|
||||
- 访问控制:`dmPolicy`、`allowFrom`、`groupPolicy`、`groupAllowFrom`、`groups`
|
||||
- 传递:`textChunkLimit`、`chunkMode`、`mediaMaxMb`、`sendReadReceipts`、`ackReaction`、`reactionLevel`
|
||||
- 多账户:`accounts.<id>.enabled`、`accounts.<id>.authDir`、账户级覆盖
|
||||
- 多账号:`accounts.<id>.enabled`、`accounts.<id>.authDir`、账号级覆盖
|
||||
- 运维:`configWrites`、`debounceMs`、`web.enabled`、`web.heartbeatSeconds`、`web.reconnect.*`
|
||||
- 会话行为:`session.dmScope`、`historyLimit`、`dmHistoryLimit`、`dms.<id>.historyLimit`
|
||||
|
||||
## 相关内容
|
||||
|
||||
- [配对](/channels/pairing)
|
||||
- [群组](/channels/groups)
|
||||
- [安全](/gateway/security)
|
||||
- [渠道路由](/channels/channel-routing)
|
||||
- [多智能体路由](/concepts/multi-agent)
|
||||
- [故障排除](/channels/troubleshooting)
|
||||
- [配对](/zh-CN/channels/pairing)
|
||||
- [群组](/zh-CN/channels/groups)
|
||||
- [安全](/zh-CN/gateway/security)
|
||||
- [渠道路由](/zh-CN/channels/channel-routing)
|
||||
- [多智能体路由](/zh-CN/concepts/multi-agent)
|
||||
- [故障排除](/zh-CN/channels/troubleshooting)
|
||||
|
||||
@ -1,15 +1,15 @@
|
||||
---
|
||||
read_when:
|
||||
- 诊断认证配置档案轮换、冷却期或模型回退行为
|
||||
- 更新认证配置档案或模型的故障切换规则
|
||||
- 理解会话模型覆盖如何与回退重试交互
|
||||
summary: OpenClaw 如何轮换认证配置档案并在模型之间回退
|
||||
- 诊断凭证配置文件轮换、冷却时间或模型回退行为
|
||||
- 更新凭证配置文件或模型的故障切换规则
|
||||
- 了解会话模型覆盖如何与回退重试交互
|
||||
summary: OpenClaw 如何轮换凭证配置文件,并在模型之间执行回退
|
||||
title: 模型故障切换
|
||||
x-i18n:
|
||||
generated_at: "2026-04-05T08:22:10Z"
|
||||
generated_at: "2026-04-06T15:28:05Z"
|
||||
model: gpt-5.4
|
||||
provider: openai
|
||||
source_hash: 899041aa0854e4f347343797649fd11140a01e069e88b1fbc0a76e6b375f6c96
|
||||
source_hash: d88821e229610f236bdab3f798d5e8c173f61a77c01017cc87431126bf465e32
|
||||
source_path: concepts/model-failover.md
|
||||
workflow: 15
|
||||
---
|
||||
@ -18,10 +18,10 @@ x-i18n:
|
||||
|
||||
OpenClaw 分两个阶段处理失败:
|
||||
|
||||
1. 在当前提供商内进行**认证配置档案轮换**。
|
||||
2. **模型回退**到 `agents.defaults.model.fallbacks` 中的下一个模型。
|
||||
1. 当前提供商内的**凭证配置文件轮换**。
|
||||
2. 回退到 `agents.defaults.model.fallbacks` 中的下一个模型,即**模型回退**。
|
||||
|
||||
本文档解释运行时规则以及支撑这些规则的数据。
|
||||
本文档说明支撑这些行为的运行时规则和数据。
|
||||
|
||||
## 运行时流程
|
||||
|
||||
@ -29,26 +29,23 @@ OpenClaw 分两个阶段处理失败:
|
||||
|
||||
1. 当前选中的会话模型。
|
||||
2. 按顺序配置的 `agents.defaults.model.fallbacks`。
|
||||
3. 如果此次运行是从覆盖开始的,则最后回到已配置的主模型。
|
||||
3. 如果本次运行起始于某个覆盖设置,则最后再使用已配置的主模型。
|
||||
|
||||
在每个候选项内部,OpenClaw 会先尝试认证配置档案故障切换,然后才前进到
|
||||
在每个候选项内部,OpenClaw 会先尝试凭证配置文件故障切换,再进入
|
||||
下一个模型候选项。
|
||||
|
||||
高层顺序如下:
|
||||
高级别流程如下:
|
||||
|
||||
1. 解析活动的会话模型和认证配置档案偏好。
|
||||
1. 解析当前激活的会话模型和凭证配置文件偏好。
|
||||
2. 构建模型候选链。
|
||||
3. 使用认证配置档案轮换/冷却规则尝试当前提供商。
|
||||
4. 如果该提供商因值得触发故障切换的错误而耗尽,则转到下一个
|
||||
3. 按照凭证配置文件轮换 / 冷却规则尝试当前提供商。
|
||||
4. 如果该提供商因值得故障切换的错误而耗尽可用项,则移动到下一个
|
||||
模型候选项。
|
||||
5. 在重试开始前持久化选中的回退覆盖,以便其他
|
||||
会话读取方看到运行器即将使用的相同提供商/模型。
|
||||
6. 如果回退候选项失败,则仅回滚由该回退拥有的会话
|
||||
覆盖字段,且仅当它们仍然匹配该失败候选项时才会这样做。
|
||||
7. 如果所有候选项都失败,则抛出一个带有逐次尝试
|
||||
细节的 `FallbackSummaryError`,并在已知时包含最早的冷却过期时间。
|
||||
5. 在重试开始前持久化选中的回退覆盖,这样其他会话读取方会看到运行器即将使用的同一提供商 / 模型。
|
||||
6. 如果回退候选项失败,则仅回滚那些由回退拥有的会话覆盖字段,并且仅当它们仍匹配该失败候选项时才回滚。
|
||||
7. 如果所有候选项都失败,则抛出带有每次尝试详情及最早冷却到期时间(如果已知)的 `FallbackSummaryError`。
|
||||
|
||||
这有意比“保存并恢复整个会话”更窄。回复运行器只会持久化它为回退所拥有的模型选择字段:
|
||||
这刻意比“保存并恢复整个会话”更窄。回复运行器只会持久化它为回退所拥有的模型选择字段:
|
||||
|
||||
- `providerOverride`
|
||||
- `modelOverride`
|
||||
@ -56,108 +53,110 @@ OpenClaw 分两个阶段处理失败:
|
||||
- `authProfileOverrideSource`
|
||||
- `authProfileOverrideCompactionCount`
|
||||
|
||||
这样可以防止一次失败的回退重试覆盖掉更新的无关会话变更,
|
||||
例如在尝试运行期间发生的手动 `/model` 更改或会话轮换更新。
|
||||
这样可以防止一次失败的回退重试覆盖更新较新的、无关的会话变更,
|
||||
例如手动 `/model` 更改或在尝试运行期间发生的会话轮换更新。
|
||||
|
||||
## 认证存储(keys + OAuth)
|
||||
## 凭证存储(密钥 + OAuth)
|
||||
|
||||
OpenClaw 对 API key 和 OAuth token 都使用**认证配置档案**。
|
||||
OpenClaw 对 API 密钥和 OAuth 令牌都使用**凭证配置文件**。
|
||||
|
||||
- 密钥存储在 `~/.openclaw/agents/<agentId>/agent/auth-profiles.json`(旧版位置:`~/.openclaw/agent/auth-profiles.json`)。
|
||||
- 配置 `auth.profiles` / `auth.order` **仅用于元数据 + 路由**(不包含密钥)。
|
||||
- 旧版仅导入 OAuth 文件:`~/.openclaw/credentials/oauth.json`(首次使用时会导入到 `auth-profiles.json`)。
|
||||
- 密钥存储在 `~/.openclaw/agents/<agentId>/agent/auth-profiles.json`(旧版:`~/.openclaw/agent/auth-profiles.json`)。
|
||||
- 运行时凭证路由状态存储在 `~/.openclaw/agents/<agentId>/agent/auth-state.json`。
|
||||
- 配置 `auth.profiles` / `auth.order` **仅用于元数据 + 路由**(不存储密钥)。
|
||||
- 仅用于旧版导入的 OAuth 文件:`~/.openclaw/credentials/oauth.json`(首次使用时会导入到 `auth-profiles.json`)。
|
||||
|
||||
更多细节:[/concepts/oauth](/concepts/oauth)
|
||||
更多细节:[/concepts/oauth](/zh-CN/concepts/oauth)
|
||||
|
||||
凭证类型:
|
||||
|
||||
- `type: "api_key"` → `{ provider, key }`
|
||||
- `type: "oauth"` → `{ provider, access, refresh, expires, email? }`(某些提供商还包括 `projectId`/`enterpriseUrl`)
|
||||
- `type: "oauth"` → `{ provider, access, refresh, expires, email? }`(某些提供商还会包含 `projectId` / `enterpriseUrl`)
|
||||
|
||||
## 配置档案 ID
|
||||
## 配置文件 ID
|
||||
|
||||
OAuth 登录会创建不同的配置档案,以便多个账号可以共存。
|
||||
OAuth 登录会创建不同的配置文件,以便多个账户可以共存。
|
||||
|
||||
- 默认:当没有 email 可用时使用 `provider:default`。
|
||||
- 带 email 的 OAuth:`provider:<email>`(例如 `google-antigravity:user@gmail.com`)。
|
||||
- 默认值:当没有可用邮箱时为 `provider:default`。
|
||||
- 带邮箱的 OAuth:`provider:<email>`(例如 `google-antigravity:user@gmail.com`)。
|
||||
|
||||
配置档案位于 `~/.openclaw/agents/<agentId>/agent/auth-profiles.json` 的 `profiles` 下。
|
||||
配置文件位于 `~/.openclaw/agents/<agentId>/agent/auth-profiles.json` 的 `profiles` 下。
|
||||
|
||||
## 轮换顺序
|
||||
|
||||
当一个提供商拥有多个配置档案时,OpenClaw 会按如下方式选择顺序:
|
||||
当一个提供商有多个配置文件时,OpenClaw 会按如下方式决定顺序:
|
||||
|
||||
1. **显式配置**:`auth.order[provider]`(如果已设置)。
|
||||
2. **已配置配置档案**:按提供商过滤后的 `auth.profiles`。
|
||||
3. **已存储配置档案**:`auth-profiles.json` 中该提供商的条目。
|
||||
2. **已配置的配置文件**:按提供商过滤后的 `auth.profiles`。
|
||||
3. **已存储的配置文件**:`auth-profiles.json` 中该提供商对应的条目。
|
||||
|
||||
如果没有配置显式顺序,OpenClaw 会使用轮询顺序:
|
||||
|
||||
- **主排序键:** 配置档案类型(**OAuth 优先于 API key**)。
|
||||
- **次排序键:** `usageStats.lastUsed`(在每种类型内,最久未使用的优先)。
|
||||
- **冷却中/已禁用配置档案** 会移到末尾,并按最早到期时间排序。
|
||||
- **主排序键:** 配置文件类型(**OAuth 优先于 API 密钥**)。
|
||||
- **次排序键:** `usageStats.lastUsed`(越久未使用越靠前,同类型内排序)。
|
||||
- **处于冷却 / 已禁用的配置文件** 会被移到末尾,并按最早到期时间排序。
|
||||
|
||||
### 会话粘性(有利于缓存)
|
||||
### 会话粘性(对缓存更友好)
|
||||
|
||||
OpenClaw 会**按会话固定所选认证配置档案**,以保持提供商缓存处于热状态。
|
||||
它**不会**对每个请求都进行轮换。固定的配置档案会一直复用,直到:
|
||||
OpenClaw 会**为每个会话固定所选的凭证配置文件**,以保持提供商缓存处于预热状态。
|
||||
它**不会**在每次请求时轮换。固定的配置文件会被重复使用,直到:
|
||||
|
||||
- 会话被重置(`/new` / `/reset`)
|
||||
- 一次压缩完成(压缩计数递增)
|
||||
- 该配置档案处于冷却中/已禁用
|
||||
- 一次压缩完成(压缩计数增加)
|
||||
- 该配置文件处于冷却 / 已禁用状态
|
||||
|
||||
通过 `/model …@<profileId>` 手动选择会为该会话设置一个**用户覆盖**,
|
||||
通过 `/model …@<profileId>` 进行手动选择会为该会话设置一个**用户覆盖**,
|
||||
在新会话开始前不会自动轮换。
|
||||
|
||||
自动固定的配置档案(由会话路由器选择)会被视为一种**偏好**:
|
||||
它们会被优先尝试,但在遭遇限流/超时时,OpenClaw 可以轮换到其他配置档案。
|
||||
用户固定的配置档案会锁定在该配置档案上;如果它失败,并且配置了模型回退,
|
||||
OpenClaw 会转到下一个模型,而不是切换配置档案。
|
||||
自动固定的配置文件(由会话路由器选中)被视为一种**偏好**:
|
||||
它们会被优先尝试,但 OpenClaw 可能会在遇到速率限制 / 超时时轮换到其他配置文件。
|
||||
用户固定的配置文件会保持锁定在该配置文件;如果它失败且已配置模型回退,
|
||||
OpenClaw 会移动到下一个模型,而不是切换配置文件。
|
||||
|
||||
### 为什么 OAuth 看起来会“丢失”
|
||||
### 为什么 OAuth 可能“看起来丢了”
|
||||
|
||||
如果同一提供商下同时存在 OAuth 配置档案和 API key 配置档案,轮询可能会在消息之间来回切换它们,除非已固定。要强制使用单一配置档案:
|
||||
如果你对同一个提供商同时拥有一个 OAuth 配置文件和一个 API 密钥配置文件,在未固定时,轮询可能会在不同消息之间切换它们。若要强制使用单一配置文件:
|
||||
|
||||
- 使用 `auth.order[provider] = ["provider:profileId"]` 固定,或
|
||||
- 使用每会话覆盖,通过带配置档案覆盖的 `/model …`(当你的 UI/聊天界面支持时)。
|
||||
- 通过 `/model …` 使用带配置文件覆盖的按会话覆盖(当你的 UI / 聊天界面支持时)。
|
||||
|
||||
## 冷却期
|
||||
## 冷却时间
|
||||
|
||||
当某个配置档案因认证/限流错误失败时(或者看起来像
|
||||
限流的超时),OpenClaw 会将其标记为进入冷却期,并切换到下一个配置档案。
|
||||
这个限流桶不仅包括普通的 `429`:还包括提供商
|
||||
消息,例如 `Too many concurrent requests`、`ThrottlingException`、
|
||||
当某个配置文件因凭证 / 速率限制错误(或看起来像速率限制的超时)
|
||||
而失败时,OpenClaw 会将其标记为冷却中,并切换到下一个配置文件。
|
||||
这个速率限制分类比单纯的 `429` 更宽:它还包括提供商消息,
|
||||
例如 `Too many concurrent requests`、`ThrottlingException`、
|
||||
`concurrency limit reached`、`workers_ai ... quota limit exceeded`、
|
||||
`throttled`、`resource exhausted`,以及周期性的用量窗口限制,例如
|
||||
`weekly/monthly limit reached`。
|
||||
格式/无效请求错误(例如 Cloud Code Assist 工具调用 ID
|
||||
校验失败)会被视为值得触发故障切换,并使用相同的冷却期。
|
||||
兼容 OpenAI 的 stop-reason 错误,例如 `Unhandled stop reason: error`、
|
||||
`stop reason: error` 和 `reason: error`,会被归类为超时/故障切换
|
||||
`throttled`、`resource exhausted`,以及周期性使用窗口限制,
|
||||
例如 `weekly/monthly limit reached`。
|
||||
格式 / 无效请求错误(例如 Cloud Code Assist 工具调用 ID
|
||||
校验失败)也会被视为值得故障切换,并使用相同的冷却时间。
|
||||
OpenAI 兼容的停止原因错误,例如 `Unhandled stop reason: error`、
|
||||
`stop reason: error` 和 `reason: error`,会被归类为超时 / 故障切换
|
||||
信号。
|
||||
提供商作用域的通用服务器文本在源头匹配已知瞬时模式时,也可能归入该超时桶。例如,Anthropic 的裸
|
||||
`An unknown error occurred` 以及带有瞬时服务器文本的 JSON `api_error`
|
||||
负载,例如 `internal server error`、`unknown error, 520`、`upstream error`
|
||||
或 `backend error`,都会被视为值得触发故障切换的超时。
|
||||
OpenRouter 特有的通用上游文本,例如裸 `Provider returned error`,也仅在
|
||||
提供商上下文确实是 OpenRouter 时才会被视为超时。
|
||||
当来源匹配已知瞬态模式时,提供商范围的通用服务器文本也会归入该超时分类。
|
||||
例如,Anthropic 的裸文本
|
||||
`An unknown error occurred` 以及带有瞬态服务器文本的 JSON `api_error`
|
||||
载荷,例如 `internal server error`、`unknown error, 520`、`upstream error`
|
||||
或 `backend error`,都会被视为值得故障切换的超时。
|
||||
OpenRouter 特有的通用上游文本,例如裸文本 `Provider returned error`,
|
||||
只有在提供商上下文确实是 OpenRouter 时才会被视为超时。
|
||||
通用的内部回退文本,例如 `LLM request failed with an unknown error.`,
|
||||
则保持保守,不会单独触发故障切换。
|
||||
|
||||
限流冷却期也可以是模型作用域的:
|
||||
速率限制冷却也可以按模型划分范围:
|
||||
|
||||
- 当已知失败模型 id 时,对于限流失败,OpenClaw 会记录 `cooldownModel`。
|
||||
- 同一提供商上的兄弟模型如果冷却期被限制在另一个模型上,仍然可以尝试。
|
||||
- 计费/禁用窗口仍会跨模型阻止整个配置档案。
|
||||
- 当已知失败的模型 ID 时,OpenClaw 会为速率限制失败记录 `cooldownModel`。
|
||||
- 当冷却限定在不同模型上时,同一提供商上的兄弟模型仍可被尝试。
|
||||
- 计费 / 已禁用窗口仍会在所有模型上阻止整个配置文件。
|
||||
|
||||
冷却期使用指数退避:
|
||||
冷却时间使用指数退避:
|
||||
|
||||
- 1 分钟
|
||||
- 5 分钟
|
||||
- 25 分钟
|
||||
- 1 小时(上限)
|
||||
|
||||
状态存储在 `auth-profiles.json` 的 `usageStats` 下:
|
||||
状态存储在 `auth-state.json` 的 `usageStats` 下:
|
||||
|
||||
```json
|
||||
{
|
||||
@ -173,17 +172,15 @@ OpenRouter 特有的通用上游文本,例如裸 `Provider returned error`,
|
||||
|
||||
## 计费禁用
|
||||
|
||||
计费/额度失败(例如“insufficient credits” / “credit balance too low”)会被视为值得触发故障切换,但它们通常不是瞬时错误。OpenClaw 不会使用短冷却期,而是将该配置档案标记为**已禁用**(采用更长退避),然后轮换到下一个配置档案/提供商。
|
||||
计费 / 额度失败(例如“insufficient credits” / “credit balance too low”)会被视为值得故障切换,但它们通常不是瞬态错误。OpenClaw 不会设置短暂冷却,而是会将该配置文件标记为**已禁用**(使用更长的退避时间),并轮换到下一个配置文件 / 提供商。
|
||||
|
||||
并不是每个看起来像计费问题的响应都是 `402`,也不是每个 HTTP `402` 都会落到
|
||||
这里。即使提供商返回的是 `401` 或 `403`,OpenClaw 也会将明确的计费文本保留在计费通道中,但提供商特定匹配器仍然局限于拥有它们的提供商(例如 OpenRouter 的 `403 Key limit
|
||||
exceeded`)。与此同时,临时性的 `402` 用量窗口和
|
||||
组织/工作区支出上限错误,如果消息看起来可以重试(例如 `weekly usage limit exhausted`、`daily
|
||||
limit reached, resets tomorrow` 或 `organization spending limit exceeded`),则会被归类为 `rate_limit`。
|
||||
这些情况会走短冷却/故障切换路径,而不是长时间的
|
||||
计费禁用路径。
|
||||
并非每个看起来像计费问题的响应都是 `402`,也并非每个 HTTP `402`
|
||||
都会归入这里。即使提供商返回的是 `401` 或 `403`,OpenClaw 仍会将明确的计费文本保留在计费分类中,但提供商特定匹配器仍仅限于拥有它们的提供商(例如 OpenRouter 的 `403 Key limit exceeded`)。
|
||||
与此同时,临时性的 `402` 使用窗口和组织 / 工作区支出限制错误,如果消息看起来可重试(例如 `weekly usage limit exhausted`、`daily limit reached, resets tomorrow` 或 `organization spending limit exceeded`),则会被归类为 `rate_limit`。
|
||||
这些情况会继续走短冷却 / 故障切换路径,而不是长时间的
|
||||
计费禁用途径。
|
||||
|
||||
状态存储在 `auth-profiles.json` 中:
|
||||
状态存储在 `auth-state.json` 中:
|
||||
|
||||
```json
|
||||
{
|
||||
@ -198,63 +195,54 @@ limit reached, resets tomorrow` 或 `organization spending limit exceeded`),
|
||||
|
||||
默认值:
|
||||
|
||||
- 计费退避从 **5 小时**开始,每次计费失败翻倍,并在 **24 小时**封顶。
|
||||
- 如果某个配置档案在 **24 小时**内没有失败,退避计数器会重置(可配置)。
|
||||
- 过载重试允许在模型回退前进行 **1 次同提供商配置档案轮换**。
|
||||
- 过载重试默认使用 **0 ms 退避**。
|
||||
- 计费退避从 **5 小时**开始,每次计费失败后翻倍,并在 **24 小时**封顶。
|
||||
- 如果配置文件在 **24 小时**内未再失败,退避计数器会重置(可配置)。
|
||||
- 过载重试在模型回退前允许进行 **1 次同提供商配置文件轮换**。
|
||||
- 过载重试默认使用 **0 毫秒退避**。
|
||||
|
||||
## 模型回退
|
||||
|
||||
如果某个提供商的所有配置档案都失败,OpenClaw 会转到
|
||||
`agents.defaults.model.fallbacks` 中的下一个模型。这适用于认证失败、限流,以及
|
||||
耗尽配置档案轮换的超时(其他错误不会推进回退)。
|
||||
如果某个提供商的所有配置文件都失败,OpenClaw 会移动到
|
||||
`agents.defaults.model.fallbacks` 中的下一个模型。这适用于凭证失败、速率限制,以及耗尽配置文件轮换后的超时(其他错误不会推进回退)。
|
||||
|
||||
与计费冷却相比,过载和限流错误处理得更激进。
|
||||
默认情况下,OpenClaw 允许一次同提供商认证配置档案重试,
|
||||
然后立即切换到下一个已配置模型回退,无需等待。
|
||||
提供商繁忙信号,例如 `ModelNotReadyException`,会落入该过载
|
||||
桶。可通过 `auth.cooldowns.overloadedProfileRotations`、
|
||||
过载和速率限制错误的处理比计费冷却更激进。默认情况下,
|
||||
OpenClaw 允许一次同提供商凭证配置文件重试,然后立即切换到下一个已配置的模型回退,无需等待。
|
||||
提供商繁忙信号,例如 `ModelNotReadyException`,会归入该过载分类。
|
||||
你可以使用 `auth.cooldowns.overloadedProfileRotations`、
|
||||
`auth.cooldowns.overloadedBackoffMs` 和
|
||||
`auth.cooldowns.rateLimitedProfileRotations` 调整此行为。
|
||||
`auth.cooldowns.rateLimitedProfileRotations` 进行调整。
|
||||
|
||||
当一次运行以模型覆盖开始时(hooks 或 CLI),在尝试完任何已配置回退后,
|
||||
回退仍会以 `agents.defaults.model.primary` 结束。
|
||||
|
||||
### 候选链规则
|
||||
|
||||
OpenClaw 会根据当前请求的 `provider/model`
|
||||
和已配置回退构建候选列表。
|
||||
OpenClaw 会根据当前请求的 `provider/model` 与已配置回退构建候选列表。
|
||||
|
||||
规则:
|
||||
|
||||
- 请求的模型始终位于第一位。
|
||||
- 显式配置的回退会去重,但不会按模型
|
||||
allowlist 过滤。它们被视为显式的操作员意图。
|
||||
- 如果当前运行已经位于同一提供商家族中的某个已配置回退上,
|
||||
OpenClaw 会继续使用完整的已配置链。
|
||||
- 如果当前运行所在的提供商与配置不同,并且当前
|
||||
模型尚未成为已配置回退链的一部分,OpenClaw 不会
|
||||
追加来自其他提供商的无关已配置回退。
|
||||
- 当运行从覆盖开始时,已配置的主模型会追加到
|
||||
末尾,以便在前面的候选项耗尽后,候选链可以回到正常默认值。
|
||||
- 请求的模型始终排在第一位。
|
||||
- 显式配置的回退会去重,但不会按模型允许列表过滤。它们被视为运维方的显式意图。
|
||||
- 如果当前运行已经在同一提供商家族中的某个已配置回退上,OpenClaw 会继续使用完整的已配置链。
|
||||
- 如果当前运行所在的提供商与配置不同,并且该当前模型尚未包含在已配置回退链中,OpenClaw 不会附加来自其他提供商的无关已配置回退。
|
||||
- 当运行起始于某个覆盖设置时,已配置的主模型会附加到末尾,这样在较早候选项耗尽后,候选链可以回到正常默认值。
|
||||
|
||||
### 哪些错误会推进回退
|
||||
|
||||
模型回退会在以下情况继续:
|
||||
|
||||
- 认证失败
|
||||
- 限流和冷却期耗尽
|
||||
- 过载/提供商繁忙错误
|
||||
- 看起来像超时的故障切换错误
|
||||
- 凭证失败
|
||||
- 速率限制和冷却耗尽
|
||||
- 过载 / 提供商繁忙错误
|
||||
- 类超时的故障切换错误
|
||||
- 计费禁用
|
||||
- `LiveSessionModelSwitchError`,它会被规范化为故障切换路径,因此
|
||||
过时的持久化模型不会产生外层重试循环
|
||||
- 当仍有剩余候选项时,其他未识别错误
|
||||
- `LiveSessionModelSwitchError`,它会被规范化为故障切换路径,这样过时的持久化模型就不会形成外层重试循环
|
||||
- 当仍有剩余候选项时,其他无法识别的错误
|
||||
|
||||
模型回退不会在以下情况继续:
|
||||
|
||||
- 非超时/非故障切换形态的显式中止
|
||||
- 应留在压缩/重试逻辑中的上下文溢出错误
|
||||
- 不属于超时 / 故障切换形态的显式中止
|
||||
- 应保留在压缩 / 重试逻辑内部的上下文溢出错误
|
||||
(例如 `request_too_large`、`INVALID_ARGUMENT: input exceeds the maximum
|
||||
number of tokens`、`input token count exceeds the maximum number of input
|
||||
tokens`、`The input is too long for the model` 或 `ollama error: context
|
||||
@ -263,73 +251,56 @@ length exceeded`)
|
||||
|
||||
### 冷却跳过与探测行为
|
||||
|
||||
当某个提供商的所有认证配置档案都已经处于冷却期时,OpenClaw 并不会
|
||||
自动永远跳过该提供商。它会按每个候选项做决定:
|
||||
当某个提供商的所有凭证配置文件都已经处于冷却中时,OpenClaw 不会自动永久跳过该提供商。它会针对每个候选项单独决策:
|
||||
|
||||
- 持久性认证失败会立即跳过整个提供商。
|
||||
- 计费禁用通常会跳过,但主候选项仍可能在节流条件下被探测,
|
||||
以便无需重启即可恢复。
|
||||
- 主候选项可能会在冷却期接近到期时被探测,并带有按提供商划分的节流。
|
||||
- 即使处于冷却期,同提供商的回退兄弟项也可以尝试,只要
|
||||
失败看起来是瞬时的(`rate_limit`、`overloaded` 或 unknown)。
|
||||
当限流是模型作用域且某个兄弟模型仍可能立即恢复时,这一点尤其相关。
|
||||
- 瞬时冷却探测在每次回退运行中每个提供商最多仅限一次,因此
|
||||
单个提供商不会拖慢跨提供商回退。
|
||||
- 持续性的凭证失败会立即跳过整个提供商。
|
||||
- 计费禁用通常会跳过,但主候选项仍可能在节流条件下被探测,以便无需重启也能恢复。
|
||||
- 在接近冷却到期时,主候选项可能会被探测,并带有按提供商区分的节流限制。
|
||||
- 即使存在冷却,同提供商的回退兄弟项在失败看起来是瞬态时(`rate_limit`、`overloaded` 或未知)仍可被尝试。当速率限制是模型范围时,而兄弟模型可能仍可立即恢复,这一点尤其重要。
|
||||
- 瞬态冷却探测在每次回退运行中每个提供商最多仅允许一次,因此单个提供商不会拖慢跨提供商回退。
|
||||
|
||||
## 会话覆盖与实时模型切换
|
||||
|
||||
会话模型更改是共享状态。活动运行器、`/model` 命令、
|
||||
压缩/会话更新,以及实时会话协调,都会读取或写入同一个会话条目的不同部分。
|
||||
会话模型更改属于共享状态。活动运行器、`/model` 命令、
|
||||
压缩 / 会话更新,以及实时会话协调逻辑都会读取或写入同一个会话条目的不同部分。
|
||||
|
||||
这意味着回退重试必须与实时模型切换协调:
|
||||
|
||||
- 只有显式的用户驱动模型更改才会标记待处理的实时切换。包括
|
||||
`/model`、`session_status(model=...)` 和 `sessions.patch`。
|
||||
- 系统驱动的模型更改,例如回退轮换、heartbeat 覆盖,
|
||||
或压缩,本身不会标记待处理的实时切换。
|
||||
- 在回退重试开始前,回复运行器会将选中的
|
||||
回退覆盖字段持久化到会话条目。
|
||||
- 实时会话协调会优先采用持久化的会话覆盖,而不是过时的
|
||||
运行时模型字段。
|
||||
- 如果回退尝试失败,运行器只会回滚它写入的覆盖字段,
|
||||
并且仅在这些字段仍然与该失败候选项匹配时才会回滚。
|
||||
- 只有显式的用户驱动模型更改才会标记待处理的实时切换。这包括 `/model`、`session_status(model=...)` 和 `sessions.patch`。
|
||||
- 由系统驱动的模型更改,例如回退轮换、心跳覆盖或压缩,不会自行标记待处理的实时切换。
|
||||
- 在回退重试开始前,回复运行器会将选中的回退覆盖字段持久化到会话条目中。
|
||||
- 实时会话协调会优先使用持久化的会话覆盖,而不是过时的运行时模型字段。
|
||||
- 如果回退尝试失败,运行器只会回滚它写入的覆盖字段,并且仅当这些字段仍匹配该失败候选项时才会回滚。
|
||||
|
||||
这可以防止经典竞态:
|
||||
这可以防止经典竞争条件:
|
||||
|
||||
1. 主模型失败。
|
||||
2. 在内存中选中了回退候选项。
|
||||
3. 会话存储仍然显示旧的主模型。
|
||||
2. 回退候选项在内存中被选中。
|
||||
3. 会话存储仍显示旧的主模型。
|
||||
4. 实时会话协调读取了过时的会话状态。
|
||||
5. 在回退尝试开始前,重试被拉回到旧模型。
|
||||
5. 在回退尝试开始前,重试又被拉回旧模型。
|
||||
|
||||
持久化的回退覆盖封闭了这个窗口,而窄范围回滚
|
||||
则能保持较新的手动或运行时会话更改不被破坏。
|
||||
持久化的回退覆盖封住了这个窗口,而范围收窄的回滚则能保持更新的手动或运行时会话更改不受影响。
|
||||
|
||||
## 可观测性与失败摘要
|
||||
|
||||
`runWithModelFallback(...)` 会记录逐次尝试的细节,用于日志和
|
||||
面向用户的冷却期消息:
|
||||
`runWithModelFallback(...)` 会记录每次尝试的详细信息,以供日志记录和面向用户的冷却消息使用:
|
||||
|
||||
- 尝试的提供商/模型
|
||||
- 原因(`rate_limit`、`overloaded`、`billing`、`auth`、`model_not_found` 以及
|
||||
类似的故障切换原因)
|
||||
- 可选的状态/代码
|
||||
- 尝试过的提供商 / 模型
|
||||
- 原因(`rate_limit`、`overloaded`、`billing`、`auth`、`model_not_found` 以及类似的故障切换原因)
|
||||
- 可选的状态 / 代码
|
||||
- 人类可读的错误摘要
|
||||
|
||||
当所有候选项都失败时,OpenClaw 会抛出 `FallbackSummaryError`。外层
|
||||
回复运行器可利用它构建更具体的消息,例如“所有模型
|
||||
暂时都受到限流”,并在已知时包含最早的冷却过期时间。
|
||||
当所有候选项都失败时,OpenClaw 会抛出 `FallbackSummaryError`。外层回复运行器可以据此构建更具体的消息,例如“所有模型当前都受到临时速率限制”,并在已知时包含最早的冷却到期时间。
|
||||
|
||||
该冷却摘要是模型感知的:
|
||||
|
||||
- 与所尝试的
|
||||
提供商/模型链无关的模型作用域限流会被忽略
|
||||
- 如果剩余阻塞是匹配的模型作用域限流,OpenClaw
|
||||
会报告最后一个仍然阻止该模型的匹配到期时间
|
||||
- 对于已尝试的提供商 / 模型链,无关的模型范围速率限制会被忽略
|
||||
- 如果剩余阻塞是匹配的模型范围速率限制,OpenClaw 会报告仍阻止该模型的最后一个匹配到期时间
|
||||
|
||||
## 相关配置
|
||||
|
||||
参见 [Gateway 网关配置](/gateway/configuration) 了解:
|
||||
有关以下内容,请参见 [Gateway 网关配置](/zh-CN/gateway/configuration):
|
||||
|
||||
- `auth.profiles` / `auth.order`
|
||||
- `auth.cooldowns.billingBackoffHours` / `auth.cooldowns.billingBackoffHoursByProvider`
|
||||
@ -339,4 +310,4 @@ length exceeded`)
|
||||
- `agents.defaults.model.primary` / `agents.defaults.model.fallbacks`
|
||||
- `agents.defaults.imageModel` 路由
|
||||
|
||||
参见 [Models](/concepts/models) 了解更广泛的模型选择和回退概览。
|
||||
有关更广泛的模型选择与回退概览,请参见 [模型](/zh-CN/concepts/models)。
|
||||
|
||||
@ -5,10 +5,10 @@ read_when:
|
||||
summary: 模型提供商概览,包含示例配置和 CLI 流程
|
||||
title: 模型提供商
|
||||
x-i18n:
|
||||
generated_at: "2026-04-06T12:44:06Z"
|
||||
generated_at: "2026-04-06T15:29:17Z"
|
||||
model: gpt-5.4
|
||||
provider: openai
|
||||
source_hash: ec33cbfeec86c3f79ea0ec38932eebb819eba5932024b73fcf3acbc41fbce203
|
||||
source_hash: a9c1f7f8cf09b6047a64189f7440811aafc93d01335f76969afd387cc54c7ab5
|
||||
source_path: concepts/model-providers.md
|
||||
workflow: 15
|
||||
---
|
||||
@ -20,21 +20,16 @@ x-i18n:
|
||||
|
||||
## 快速规则
|
||||
|
||||
- 模型引用使用 `provider/model`(例如:`opencode/claude-opus-4-6`)。
|
||||
- 如果你设置了 `agents.defaults.models`,它就会成为允许列表。
|
||||
- 模型引用使用 `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)。
|
||||
- 运行时回退规则、冷却探测和会话覆盖持久化已在 [/concepts/model-failover](/zh-CN/concepts/model-failover) 中说明。
|
||||
- `models.providers.*.models[].contextWindow` 是原生模型元数据;
|
||||
`models.providers.*.models[].contextTokens` 是实际运行时上限。
|
||||
`models.providers.*.models[].contextTokens` 是运行时生效上限。
|
||||
- 提供商插件可以通过 `registerProvider({ catalog })` 注入模型目录;
|
||||
OpenClaw 会在写入
|
||||
`models.json` 之前将该输出合并到 `models.providers` 中。
|
||||
- 提供商清单可以声明 `providerAuthEnvVars`,这样通用的基于环境变量的
|
||||
凭证探测就不需要加载插件运行时。剩余的核心环境变量
|
||||
映射现在只用于非插件/核心提供商以及少数通用优先级
|
||||
场景,例如 Anthropic 以 API 密钥优先的新手引导。
|
||||
- 提供商插件还可以通过以下方式拥有提供商运行时行为:
|
||||
OpenClaw 会在写入 `models.json` 之前将该输出合并到 `models.providers` 中。
|
||||
- 提供商清单可以声明 `providerAuthEnvVars`,这样基于通用环境变量的凭证探测就不需要加载插件运行时。剩余的核心环境变量映射现在仅用于非插件/核心提供商,以及少数通用优先级场景,例如 Anthropic 以 API 密钥优先的新手引导。
|
||||
- 提供商插件还可以通过
|
||||
`normalizeModelId`、`normalizeTransport`、`normalizeConfig`、
|
||||
`applyNativeStreamingUsageCompat`、`resolveConfigApiKey`、
|
||||
`resolveSyntheticAuth`、`shouldDeferSyntheticProfileAuth`、
|
||||
@ -50,196 +45,110 @@ x-i18n:
|
||||
`isCacheTtlEligible`、`buildMissingAuthMessage`、`suppressBuiltInModel`、
|
||||
`augmentModelCatalog`、`isBinaryThinking`、`supportsXHighThinking`、
|
||||
`resolveDefaultThinkingLevel`、`applyConfigDefaults`、`isModernModelRef`、
|
||||
`prepareRuntimeAuth`、`resolveUsageAuth`、`fetchUsageSnapshot`,以及
|
||||
`onModelSelected`。
|
||||
- 注意:提供商运行时 `capabilities` 是共享运行器元数据(提供商
|
||||
家族、转录/工具怪癖、传输/缓存提示)。它不同于
|
||||
[公开能力模型](/zh-CN/plugins/architecture#public-capability-model),
|
||||
后者描述的是插件注册了什么能力(文本推理、语音等)。
|
||||
`prepareRuntimeAuth`、`resolveUsageAuth`、`fetchUsageSnapshot` 以及
|
||||
`onModelSelected`
|
||||
来管理提供商运行时行为。
|
||||
- 注意:提供商运行时 `capabilities` 是共享执行器元数据(提供商家族、转录/工具特性、传输/缓存提示)。它与[公共能力模型](/zh-CN/plugins/architecture#public-capability-model)不同,后者描述的是插件注册了什么能力(文本推理、语音等)。
|
||||
|
||||
## 插件拥有的提供商行为
|
||||
|
||||
提供商插件现在可以拥有大多数提供商特定逻辑,而 OpenClaw 保持
|
||||
通用推理循环。
|
||||
提供商插件现在可以拥有大多数提供商特定逻辑,而 OpenClaw 保留通用推理循环。
|
||||
|
||||
典型划分:
|
||||
|
||||
- `auth[].run` / `auth[].runNonInteractive`:提供商拥有 `openclaw onboard`、`openclaw models auth` 和无头设置的
|
||||
新手引导/登录流程
|
||||
- `wizard.setup` / `wizard.modelPicker`:提供商拥有凭证选择标签、
|
||||
旧别名、新手引导允许列表提示,以及新手引导/模型选择器中的设置条目
|
||||
- `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`:提供商用完全
|
||||
自定义的传输替换正常流式路径
|
||||
- `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
|
||||
错误映射为回退原因,例如速率限制或过载
|
||||
- `resolveTransportTurnState`:提供商提供每轮原生传输头或元数据
|
||||
- `resolveWebSocketSessionPolicy`:提供商提供原生 WebSocket 会话头或会话冷却策略
|
||||
- `createEmbeddingProvider`:当内存嵌入行为更适合归属提供商插件而不是核心嵌入切换板时,由提供商拥有它
|
||||
- `formatApiKey`:提供商将已存储的凭证配置文件格式化为传输所需的运行时 `apiKey` 字符串
|
||||
- `refreshOAuth`:当共享的 `pi-ai` 刷新器不足时,由提供商负责 OAuth 刷新
|
||||
- `buildAuthDoctorHint`:当 OAuth 刷新失败时,提供商附加修复指导
|
||||
- `matchesContextOverflowError`:提供商识别通用启发式会漏掉的提供商特定上下文窗口溢出错误
|
||||
- `classifyFailoverReason`:提供商将提供商特定的原始传输/API 错误映射为速率限制或过载等回退原因
|
||||
- `isCacheTtlEligible`:提供商决定哪些上游模型 id 支持提示缓存 TTL
|
||||
- `buildMissingAuthMessage`:提供商用提供商特定的恢复提示
|
||||
替换通用的凭证存储错误
|
||||
- `suppressBuiltInModel`:提供商隐藏过时的上游条目,并且可以在
|
||||
直接解析失败时返回厂商拥有的错误
|
||||
- `augmentModelCatalog`:提供商在
|
||||
发现和配置合并之后追加合成/最终目录条目
|
||||
- `buildMissingAuthMessage`:提供商用提供商特定的恢复提示替换通用凭证存储错误
|
||||
- `suppressBuiltInModel`:提供商隐藏陈旧的上游条目,并可在直接解析失败时返回厂商拥有的错误
|
||||
- `augmentModelCatalog`:在发现和配置合并后,提供商附加合成/最终目录条目
|
||||
- `isBinaryThinking`:提供商拥有二元开/关思考 UX
|
||||
- `supportsXHighThinking`:提供商让选定模型支持 `xhigh`
|
||||
- `resolveDefaultThinkingLevel`:提供商拥有某个
|
||||
模型家族的默认 `/think` 策略
|
||||
- `applyConfigDefaults`:提供商在配置具体化期间,根据凭证模式、
|
||||
环境变量或模型家族应用提供商特定的全局默认值
|
||||
- `isModernModelRef`:提供商拥有实时/冒烟优选模型匹配
|
||||
- `prepareRuntimeAuth`:提供商将已配置的凭证转换为短期
|
||||
运行时令牌
|
||||
- `resolveUsageAuth`:提供商为 `/usage`
|
||||
及相关状态/报告界面解析用量/配额凭证
|
||||
- `fetchUsageSnapshot`:提供商拥有用量端点的抓取/解析逻辑,
|
||||
而核心仍然拥有摘要外壳与格式化
|
||||
- `onModelSelected`:提供商运行选择模型后的副作用,例如
|
||||
遥测或由提供商拥有的会话记账
|
||||
- `resolveDefaultThinkingLevel`:提供商拥有某个模型家族的默认 `/think` 策略
|
||||
- `applyConfigDefaults`:提供商根据凭证模式、环境变量或模型家族,在配置具体化期间应用提供商特定的全局默认值
|
||||
- `isModernModelRef`:提供商拥有 live/smoke 首选模型匹配
|
||||
- `prepareRuntimeAuth`:提供商把已配置的凭证转换为短时效运行时令牌
|
||||
- `resolveUsageAuth`:提供商为 `/usage` 及相关状态/报告界面解析使用量/配额凭证
|
||||
- `fetchUsageSnapshot`:提供商拥有使用量端点的获取/解析逻辑,而核心仍拥有摘要外壳和格式化
|
||||
- `onModelSelected`:提供商运行选择模型后的副作用,例如遥测或提供商拥有的会话记账
|
||||
|
||||
当前内置示例:
|
||||
|
||||
- `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 图像模型;以及为托管第三方视频模型注册的内置
|
||||
视频生成提供商
|
||||
- `anthropic`:Claude 4.6 前向兼容回退、凭证修复提示、使用量端点获取、缓存 TTL/提供商家族元数据,以及具备凭证感知能力的全局配置默认值
|
||||
- `amazon-bedrock`:提供商拥有的上下文溢出匹配,以及对 Bedrock 特定节流/未就绪错误的回退原因分类,外加共享的 `anthropic-by-model` 重放家族,用于 Claude 专属的 Anthropic 流量重放策略保护
|
||||
- `anthropic-vertex`:Anthropic 消息流量上的 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`:共享传输、插件拥有的 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 特定工具 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`:文本模型的由插件拥有目录,加上为其
|
||||
多模态界面注册的共享 media-understanding 和视频生成提供商;Qwen 视频生成使用
|
||||
标准 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`(单个实时覆盖,最高优先级)
|
||||
- `OPENCLAW_LIVE_<PROVIDER>_KEY`(单个 live 覆盖,优先级最高)
|
||||
- `<PROVIDER>_API_KEYS`(逗号或分号分隔列表)
|
||||
- `<PROVIDER>_API_KEY`(主密钥)
|
||||
- `<PROVIDER>_API_KEY_*`(编号列表,例如 `<PROVIDER>_API_KEY_1`)
|
||||
- 对于 Google 提供商,还会将 `GOOGLE_API_KEY` 作为回退包含在内。
|
||||
- 密钥选择顺序会保留优先级并去重。
|
||||
- 仅在速率限制响应时,请求才会使用下一个密钥重试(例如
|
||||
`429`、`rate_limit`、`quota`、`resource exhausted`、`Too many
|
||||
concurrent requests`、`ThrottlingException`、`concurrency limit reached`、
|
||||
`workers_ai ... quota limit exceeded` 或周期性的用量上限消息)。
|
||||
- 密钥选择顺序会保留优先级并去重值。
|
||||
- 仅在速率限制响应时,才会使用下一个密钥重试请求(例如 `429`、`rate_limit`、`quota`、`resource exhausted`、`Too many concurrent requests`、`ThrottlingException`、`concurrency limit reached`、`workers_ai ... quota limit exceeded` 或周期性的使用量限制消息)。
|
||||
- 非速率限制失败会立即失败;不会尝试密钥轮换。
|
||||
- 当所有候选密钥都失败时,将返回最后一次尝试的最终错误。
|
||||
|
||||
## 内置提供商(pi-ai 目录)
|
||||
|
||||
OpenClaw 附带 pi‑ai 目录。这些提供商**不需要**
|
||||
`models.providers` 配置;只需设置凭证并选择模型即可。
|
||||
OpenClaw 内置了 pi‑ai 目录。这些提供商**不需要**
|
||||
`models.providers` 配置;只需设置凭证并选择一个模型。
|
||||
|
||||
### OpenAI
|
||||
|
||||
@ -248,18 +157,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 回退)
|
||||
- 可通过 `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`
|
||||
- 如果你想使用显式 tier,而不是共享的 `/fast` 开关,请使用 `params.serviceTier`
|
||||
- 默认传输为 `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/gpt-5.3-codex-spark` 在 OpenClaw 中被有意抑制,因为实时 OpenAI API 会拒绝它;Spark 被视为仅限 Codex
|
||||
`User-Agent`)仅适用于发往 `api.openai.com` 的原生 OpenAI 流量,不适用于通用 OpenAI 兼容代理
|
||||
- 原生 OpenAI 路由还会保留 Responses `store`、提示缓存提示以及
|
||||
OpenAI 推理兼容负载整形;代理路由则不会
|
||||
- `openai/gpt-5.3-codex-spark` 在 OpenClaw 中被有意屏蔽,因为 live OpenAI API 会拒绝它;Spark 被视为仅限 Codex
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -274,9 +182,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 日太平洋时间中午 12:00 / 英国夏令时晚上 8:00** 通知 OpenClaw 用户,**OpenClaw** 的 Claude 登录路径被视为第三方 harness 用法,因此需要**额外用量**,并与订阅分开计费。我们的本地复现还显示,OpenClaw 标识提示字符串不会在 Anthropic SDK + API 密钥路径上复现。
|
||||
- Anthropic setup-token 现已再次作为旧版/手动 OpenClaw 路径可用。使用时请预期 Anthropic 已告知 OpenClaw 用户,此路径需要**额外用量**。
|
||||
- 直接公共 Anthropic 请求支持共享的 `/fast` 开关和 `params.fastMode`,包括发送到 `api.anthropic.com` 的 API 密钥和 OAuth 认证流量;OpenClaw 会将其映射到 Anthropic `service_tier`(`auto` 与 `standard_only`)
|
||||
- Anthropic 说明:Anthropic 员工告诉我们,OpenClaw 风格的 Claude CLI 用法再次被允许,因此 OpenClaw 将 Claude CLI 复用和 `claude -p` 用法视为此集成下被认可的方式,除非 Anthropic 发布新政策。
|
||||
- Anthropic setup-token 仍作为受支持的 OpenClaw 令牌路径保留,但 OpenClaw 现在在可用时优先选择 Claude CLI 复用和 `claude -p`。
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -290,16 +198,16 @@ 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 回退)
|
||||
- 可通过 `agents.defaults.models["openai-codex/<model>"].params.transport` 为每个模型覆盖(`"sse"`、`"websocket"` 或 `"auto"`)
|
||||
- `params.serviceTier` 也会在原生 Codex Responses 请求(`chatgpt.com/backend-api`)上传递
|
||||
- 默认传输为 `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`)仅附加到发送到
|
||||
`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` 时,它仍然可用;取决于权限
|
||||
- 与直接 `openai/*` 共享相同的 `/fast` 开关和 `params.fastMode` 配置;OpenClaw 会将其映射到 `service_tier=priority`
|
||||
- 当 Codex OAuth 目录暴露 `openai-codex/gpt-5.3-codex-spark` 时,它仍然可用;取决于 entitlement
|
||||
- `openai-codex/gpt-5.4` 保留原生 `contextWindow = 1050000` 和默认运行时 `contextTokens = 272000`;可通过 `models.providers.openai-codex.models[].contextTokens` 覆盖运行时上限
|
||||
- 策略说明:OpenAI Codex OAuth 明确支持用于 OpenClaw 之类的外部工具/工作流。
|
||||
- 策略说明:OpenAI Codex OAuth 明确支持像 OpenClaw 这样的外部工具/工作流。
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -321,7 +229,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 端点
|
||||
|
||||
@ -345,17 +253,17 @@ 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 和 Gemini CLI
|
||||
|
||||
- 提供商:`google-vertex`、`google-gemini-cli`
|
||||
- 凭证:Vertex 使用 gcloud ADC;Gemini CLI 使用其 OAuth 流程
|
||||
- 注意:OpenClaw 中的 Gemini CLI OAuth 是非官方集成。一些用户报告在使用第三方客户端后遭到 Google 账号限制。若你选择继续,请先查看 Google 条款,并使用非关键账号。
|
||||
- 注意:OpenClaw 中的 Gemini CLI OAuth 属于非官方集成。有用户报告在使用第三方客户端后 Google 账户受到限制。若你选择继续,请查看 Google 条款并使用非关键账户。
|
||||
- Gemini CLI OAuth 作为内置 `google` 插件的一部分提供。
|
||||
- 先安装 Gemini CLI:
|
||||
- `brew install gemini-cli`
|
||||
@ -363,11 +271,10 @@ OpenClaw 附带 pi‑ai 目录。这些提供商**不需要**
|
||||
- 启用:`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 网关主机上的凭证配置档中。
|
||||
- 注意:你**不需要**将 client id 或 secret 粘贴到 `openclaw.json` 中。CLI 登录流程会将令牌存储在 Gateway 网关主机上的凭证配置文件中。
|
||||
- 如果登录后请求失败,请在 Gateway 网关主机上设置 `GOOGLE_CLOUD_PROJECT` 或 `GOOGLE_CLOUD_PROJECT_ID`。
|
||||
- Gemini CLI JSON 回复会从 `response` 解析;用量会回退到
|
||||
`stats`,其中 `stats.cached` 会被归一化为 OpenClaw `cacheRead`。
|
||||
- Gemini CLI JSON 回复从 `response` 解析;使用量会回退到
|
||||
`stats`,其中 `stats.cached` 会被标准化为 OpenClaw `cacheRead`。
|
||||
|
||||
### Z.AI(GLM)
|
||||
|
||||
@ -375,8 +282,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
|
||||
|
||||
@ -392,11 +299,10 @@ OpenClaw 附带 pi‑ai 目录。这些提供商**不需要**
|
||||
- 示例模型:`kilocode/kilo/auto`
|
||||
- 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 中硬编码。
|
||||
- 静态回退目录内置了 `kilocode/kilo/auto`;live
|
||||
`https://api.kilo.ai/api/gateway/models` 发现可以进一步扩展运行时目录。
|
||||
- `kilocode/kilo/auto` 背后的精确上游路由由 Kilo Gateway 拥有,
|
||||
并非在 OpenClaw 中硬编码。
|
||||
|
||||
设置详情请参见 [/providers/kilocode](/zh-CN/providers/kilocode)。
|
||||
|
||||
@ -404,25 +310,20 @@ 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_API_KEY`;`minimax-portal` 使用 `MINIMAX_OAUTH_TOKEN` 或 `MINIMAX_API_KEY`
|
||||
- 示例模型:`minimax/MiniMax-M2.7` 或 `minimax-portal/MiniMax-M2.7`
|
||||
- MiniMax 新手引导/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`)
|
||||
@ -450,10 +351,9 @@ OpenClaw 附带 pi‑ai 目录。这些提供商**不需要**
|
||||
- xAI:`xai`(`XAI_API_KEY`)
|
||||
- 原生内置 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` 可
|
||||
关闭它
|
||||
`grok-4` 和 `grok-4-0709` 重写为它们的 `*-fast` 变体
|
||||
- 默认启用 `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`
|
||||
@ -466,24 +366,22 @@ OpenClaw 附带 pi‑ai 目录。这些提供商**不需要**
|
||||
|
||||
## 通过 `models.providers` 配置的提供商(自定义/base URL)
|
||||
|
||||
使用 `models.providers`(或 `models.json`)来添加**自定义**提供商或
|
||||
使用 `models.providers`(或 `models.json`)添加**自定义**提供商或
|
||||
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`
|
||||
- 示例模型:`moonshot/kimi-k2.5`
|
||||
- CLI:`openclaw onboard --auth-choice moonshot-api-key` 或 `openclaw onboard --auth-choice moonshot-api-key-cn`
|
||||
|
||||
Kimi K2 模型 ID:
|
||||
Kimi K2 模型 id:
|
||||
|
||||
[//]: # "moonshot-kimi-k2-model-refs:start"
|
||||
|
||||
@ -530,11 +428,11 @@ Kimi Coding 使用 Moonshot AI 的 Anthropic 兼容端点:
|
||||
}
|
||||
```
|
||||
|
||||
旧版 `kimi/k2p5` 仍然作为兼容模型 id 被接受。
|
||||
旧版 `kimi/k2p5` 仍作为兼容模型 id 被接受。
|
||||
|
||||
### Volcano Engine(Doubao)
|
||||
|
||||
Volcano Engine(火山引擎)为中国用户提供对 Doubao 及其他模型的访问。
|
||||
Volcano Engine(火山引擎)为中国用户提供 Doubao 和其他模型的访问。
|
||||
|
||||
- 提供商:`volcengine`(编码:`volcengine-plan`)
|
||||
- 凭证:`VOLCANO_ENGINE_API_KEY`
|
||||
@ -549,13 +447,11 @@ Volcano Engine(火山引擎)为中国用户提供对 Doubao 及其他模型
|
||||
}
|
||||
```
|
||||
|
||||
新手引导默认使用编码界面,但通用 `volcengine/*`
|
||||
新手引导默认使用 coding 界面,但通用 `volcengine/*`
|
||||
目录也会同时注册。
|
||||
|
||||
在新手引导/配置模型选择器中,Volcengine 凭证选择会优先显示
|
||||
`volcengine/*` 和 `volcengine-plan/*` 两类条目。如果这些模型尚未加载,
|
||||
OpenClaw 会回退到未过滤目录,而不是显示一个空的
|
||||
提供商范围选择器。
|
||||
在新手引导/配置模型选择器中,Volcengine 凭证选项会优先显示 `volcengine/*` 和 `volcengine-plan/*` 两类条目。如果这些模型尚未加载,
|
||||
OpenClaw 会回退到未过滤目录,而不是显示一个空的提供商范围选择器。
|
||||
|
||||
可用模型:
|
||||
|
||||
@ -575,7 +471,7 @@ OpenClaw 会回退到未过滤目录,而不是显示一个空的
|
||||
|
||||
### BytePlus(国际版)
|
||||
|
||||
BytePlus ARK 为国际用户提供对与 Volcano Engine 相同模型的访问。
|
||||
BytePlus ARK 为国际用户提供与 Volcano Engine 相同模型的访问。
|
||||
|
||||
- 提供商:`byteplus`(编码:`byteplus-plan`)
|
||||
- 凭证:`BYTEPLUS_API_KEY`
|
||||
@ -590,13 +486,11 @@ BytePlus ARK 为国际用户提供对与 Volcano Engine 相同模型的访问。
|
||||
}
|
||||
```
|
||||
|
||||
新手引导默认使用编码界面,但通用 `byteplus/*`
|
||||
新手引导默认使用 coding 界面,但通用 `byteplus/*`
|
||||
目录也会同时注册。
|
||||
|
||||
在新手引导/配置模型选择器中,BytePlus 凭证选择会优先显示
|
||||
`byteplus/*` 和 `byteplus-plan/*` 两类条目。如果这些模型尚未加载,
|
||||
OpenClaw 会回退到未过滤目录,而不是显示一个空的
|
||||
提供商范围选择器。
|
||||
在新手引导/配置模型选择器中,BytePlus(国际版)凭证选项会优先显示 `byteplus/*` 和 `byteplus-plan/*` 两类条目。如果这些模型尚未加载,
|
||||
OpenClaw 会回退到未过滤目录,而不是显示一个空的提供商范围选择器。
|
||||
|
||||
可用模型:
|
||||
|
||||
@ -648,25 +542,24 @@ MiniMax 通过 `models.providers` 配置,因为它使用自定义端点:
|
||||
- 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`
|
||||
- 凭证:`minimax` 使用 `MINIMAX_API_KEY`;`minimax-portal` 使用 `MINIMAX_OAUTH_TOKEN` 或
|
||||
`MINIMAX_API_KEY`
|
||||
|
||||
设置详情、模型选项和配置片段请参见 [/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 凭证路径上都由插件拥有的 `MiniMax-VL-01`
|
||||
- Web 搜索保持使用提供商 id `minimax`
|
||||
|
||||
### Ollama
|
||||
|
||||
Ollama 作为内置提供商插件提供,并使用 Ollama 的原生 API:
|
||||
Ollama 作为内置提供商插件提供,并使用 Ollama 原生 API:
|
||||
|
||||
- 提供商:`ollama`
|
||||
- 凭证:无需(本地服务器)
|
||||
@ -686,20 +579,18 @@ ollama pull llama3.3
|
||||
}
|
||||
```
|
||||
|
||||
当你通过 `OLLAMA_API_KEY` 选择加入时,Ollama 会在本地 `http://127.0.0.1:11434` 被检测到,
|
||||
并且内置提供商插件会将 Ollama 直接添加到
|
||||
`openclaw onboard` 和模型选择器中。关于新手引导、云端/本地模式以及自定义配置,请参见 [/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"
|
||||
@ -719,15 +610,14 @@ 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"
|
||||
@ -754,7 +644,7 @@ export SGLANG_API_KEY="sglang-local"
|
||||
agents: {
|
||||
defaults: {
|
||||
model: { primary: "lmstudio/my-local-model" },
|
||||
models: { "lmstudio/my-local-model": { alias: "Local" } },
|
||||
models: { "lmstudio/my-local-model": { alias: "本地" } },
|
||||
},
|
||||
},
|
||||
models: {
|
||||
@ -766,7 +656,7 @@ export SGLANG_API_KEY="sglang-local"
|
||||
models: [
|
||||
{
|
||||
id: "my-local-model",
|
||||
name: "Local Model",
|
||||
name: "本地模型",
|
||||
reasoning: false,
|
||||
input: ["text"],
|
||||
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
|
||||
@ -789,14 +679,11 @@ export SGLANG_API_KEY="sglang-local"
|
||||
- `cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }`
|
||||
- `contextWindow: 200000`
|
||||
- `maxTokens: 8192`
|
||||
- 建议:设置与你的代理/模型限制匹配的显式值。
|
||||
- 对于非原生端点上的 `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` 端点上仍会被覆盖。
|
||||
- 建议:设置与代理/模型限制相匹配的显式值。
|
||||
- 对于非原生端点上的 `api: "openai-completions"`(任何 host 不是 `api.openai.com` 的非空 `baseUrl`),OpenClaw 会强制 `compat.supportsDeveloperRole: false`,以避免提供商因不支持 `developer` 角色而返回 400 错误。
|
||||
- 代理风格的 OpenAI 兼容路由也会跳过原生 OpenAI 专用请求整形:没有 `service_tier`、没有 Responses `store`、没有提示缓存提示、没有 OpenAI 推理兼容负载整形,也没有隐藏的 OpenClaw 归因请求头。
|
||||
- 如果 `baseUrl` 为空/省略,OpenClaw 会保留默认 OpenAI 行为(解析为 `api.openai.com`)。
|
||||
- 出于安全考虑,在非原生 `openai-completions` 端点上,显式的 `compat.supportsDeveloperRole: true` 仍会被覆盖。
|
||||
|
||||
## CLI 示例
|
||||
|
||||
@ -806,7 +693,7 @@ openclaw models set opencode/claude-opus-4-6
|
||||
openclaw models list
|
||||
```
|
||||
|
||||
另请参见:[/gateway/configuration](/zh-CN/gateway/configuration) 了解完整配置示例。
|
||||
另请参见:[/gateway/configuration](/zh-CN/gateway/configuration) 获取完整配置示例。
|
||||
|
||||
## 相关内容
|
||||
|
||||
|
||||
@ -2,56 +2,57 @@
|
||||
read_when:
|
||||
- 你想端到端了解 OpenClaw OAuth
|
||||
- 你遇到了令牌失效 / 登出问题
|
||||
- 你想使用 Claude CLI 或 OAuth 认证流程
|
||||
- 你想使用多个账户或配置文件路由
|
||||
summary: OpenClaw 中的 OAuth:令牌交换、存储与多账户模式
|
||||
- 你想了解 Claude CLI 或 OAuth 认证流程
|
||||
- 你想使用多个账号或配置文件路由
|
||||
summary: OpenClaw 中的 OAuth:令牌交换、存储与多账号模式
|
||||
title: OAuth
|
||||
x-i18n:
|
||||
generated_at: "2026-04-05T17:46:55Z"
|
||||
generated_at: "2026-04-06T15:27:43Z"
|
||||
model: gpt-5.4
|
||||
provider: openai
|
||||
source_hash: 402e20dfeb6ae87a90cba5824a56a7ba3b964f3716508ea5cc48a47e5affdd73
|
||||
source_hash: 4117fee70e3e64fd3a762403454ac2b78de695d2b85a7146750c6de615921e02
|
||||
source_path: concepts/oauth.md
|
||||
workflow: 15
|
||||
---
|
||||
|
||||
# OAuth
|
||||
|
||||
OpenClaw 支持通过 OAuth 使用“订阅认证”,适用于提供此能力的提供商
|
||||
(尤其是 **OpenAI Codex(ChatGPT OAuth)**)。对于 Anthropic,目前实际情况
|
||||
OpenClaw 支持通过 OAuth 实现“订阅认证”,适用于提供该能力的提供商
|
||||
(尤其是 **OpenAI Codex(ChatGPT OAuth)**)。对于 Anthropic,目前实际上的区分
|
||||
是:
|
||||
|
||||
- **Anthropic API 密钥**:标准 Anthropic API 计费
|
||||
- **OpenClaw 中的 Anthropic 订阅认证**:Anthropic 已于 **2026 年 4 月 4 日太平洋时间下午 12:00 / 英国夏令时晚上 8:00** 通知 OpenClaw
|
||||
用户,这现在需要 **Extra Usage**
|
||||
- **Anthropic API key**:常规 Anthropic API 计费
|
||||
- **Anthropic Claude CLI / OpenClaw 内的订阅认证**:Anthropic 员工
|
||||
告诉我们这种用法再次被允许
|
||||
|
||||
OpenAI Codex OAuth 明确支持在 OpenClaw 这类外部工具中使用。本文说明:
|
||||
OpenAI Codex OAuth 已明确支持在 OpenClaw 这类外部工具中使用。本页说明:
|
||||
|
||||
对于生产环境中的 Anthropic,API 密钥认证是更安全、推荐的方案。
|
||||
对于生产环境中的 Anthropic,API key 认证仍是更安全、也更推荐的路径。
|
||||
|
||||
- OAuth **令牌交换**如何工作(PKCE)
|
||||
- 令牌**存储**在哪里(以及原因)
|
||||
- 如何处理**多个账户**(配置文件 + 每会话覆盖)
|
||||
- OAuth **令牌交换** 的工作方式(PKCE)
|
||||
- 令牌**存储** 在哪里(以及原因)
|
||||
- 如何处理**多个账号**(配置文件 + 每会话覆盖)
|
||||
|
||||
OpenClaw 还支持自带 OAuth 或 API 密钥流程的**提供商插件**。可通过以下命令运行:
|
||||
OpenClaw 还支持自带 OAuth 或 API‑key
|
||||
流程的**提供商插件**。可通过以下命令运行:
|
||||
|
||||
```bash
|
||||
openclaw models auth login --provider <id>
|
||||
```
|
||||
|
||||
## 令牌汇聚点(为什么存在)
|
||||
## 令牌汇集点(为什么存在)
|
||||
|
||||
OAuth 提供商通常会在登录 / 刷新流程中签发**新的刷新令牌**。某些提供商(或 OAuth 客户端)可能会在为同一用户 / 应用签发新令牌时使旧的刷新令牌失效。
|
||||
OAuth 提供商通常会在登录 / 刷新流程中签发**新的刷新令牌**。某些提供商(或 OAuth 客户端)会在为同一用户 / 应用签发新令牌时,使旧的刷新令牌失效。
|
||||
|
||||
实际症状:
|
||||
|
||||
- 你同时通过 OpenClaw _以及_ Claude Code / Codex CLI 登录 → 之后其中一个会随机“被登出”
|
||||
- 你同时通过 OpenClaw _和_ Claude Code / Codex CLI 登录 → 之后其中一个会随机出现“已登出”
|
||||
|
||||
为减少这种情况,OpenClaw 将 `auth-profiles.json` 视为一个**令牌汇聚点**:
|
||||
为减少这种情况,OpenClaw 将 `auth-profiles.json` 视为**令牌汇集点**:
|
||||
|
||||
- 运行时从**同一个位置**读取凭证
|
||||
- 我们可以保留多个配置文件并以确定性的方式进行路由
|
||||
- 当凭证复用自 Codex CLI 之类的外部 CLI 时,OpenClaw
|
||||
- 运行时从**一个位置**读取凭证
|
||||
- 我们可以保留多个配置文件,并以确定性的方式进行路由
|
||||
- 当凭证复用自 Codex CLI 这类外部 CLI 时,OpenClaw
|
||||
会带着来源信息镜像这些凭证,并重新读取该外部来源,而不是
|
||||
自己轮换刷新令牌
|
||||
|
||||
@ -59,72 +60,70 @@ OAuth 提供商通常会在登录 / 刷新流程中签发**新的刷新令牌**
|
||||
|
||||
密钥按**每个智能体**存储:
|
||||
|
||||
- 认证配置文件(OAuth + API 密钥 + 可选的值级别引用):`~/.openclaw/agents/<agentId>/agent/auth-profiles.json`
|
||||
- 认证配置文件(OAuth + API keys + 可选的值级引用):`~/.openclaw/agents/<agentId>/agent/auth-profiles.json`
|
||||
- 旧版兼容文件:`~/.openclaw/agents/<agentId>/agent/auth.json`
|
||||
(发现静态 `api_key` 条目时会清理掉)
|
||||
(发现静态 `api_key` 条目时会被清理)
|
||||
|
||||
仅用于旧版导入的文件(仍受支持,但不是主存储):
|
||||
仅用于旧版导入的文件(仍受支持,但不是主要存储):
|
||||
|
||||
- `~/.openclaw/credentials/oauth.json`(首次使用时会导入到 `auth-profiles.json` 中)
|
||||
- `~/.openclaw/credentials/oauth.json`(首次使用时导入到 `auth-profiles.json`)
|
||||
|
||||
以上所有路径也都遵循 `$OPENCLAW_STATE_DIR`(状态目录覆盖)。完整参考:[/gateway/configuration](/zh-CN/gateway/configuration-reference#auth-storage)
|
||||
以上所有路径同样遵循 `$OPENCLAW_STATE_DIR`(状态目录覆盖)。完整参考:[/gateway/configuration](/zh-CN/gateway/configuration-reference#auth-storage)
|
||||
|
||||
关于静态 SecretRef 和运行时快照激活行为,请参见[密钥管理](/zh-CN/gateway/secrets)。
|
||||
关于静态密钥引用和运行时快照激活行为,请参见 [Secrets Management](/zh-CN/gateway/secrets)。
|
||||
|
||||
## Anthropic 旧版令牌兼容性
|
||||
|
||||
<Warning>
|
||||
Anthropic 的公开 Claude Code 文档说明,直接使用 Claude Code 会保持在
|
||||
Claude 订阅限额内。另一个层面上,Anthropic 已于 **2026 年 4 月 4 日太平洋时间下午 12:00 / 英国夏令时晚上 8:00** 告知 OpenClaw 用户,**OpenClaw 被视为第三方封装工具**。现有的 Anthropic 令牌配置文件在 OpenClaw 中在技术上仍可使用,但 Anthropic 表示,OpenClaw 路径现在要求该流量使用 **Extra
|
||||
Usage**(按量付费,独立于订阅单独计费)。
|
||||
Anthropic 的公开 Claude Code 文档说明,直接使用 Claude Code 仍受
|
||||
Claude 订阅限制约束,而 Anthropic 员工告诉我们,OpenClaw 风格的 Claude
|
||||
CLI 用法再次被允许。因此,OpenClaw 目前将 Claude CLI 复用和
|
||||
`claude -p` 用法视为该集成的许可方式,除非 Anthropic
|
||||
发布新的政策。
|
||||
|
||||
关于 Anthropic 当前的直接 Claude Code 套餐文档,请参见 [Using Claude Code
|
||||
关于 Anthropic 当前直接使用 Claude Code 的套餐文档,请参见 [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/)。
|
||||
plan](https://support.anthropic.com/en/articles/11845131-using-claude-code-with-your-team-or-enterprise-plan/).
|
||||
|
||||
如果你想在 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)。
|
||||
以及 [Z.AI / GLM Coding Plan](/zh-CN/providers/glm)。
|
||||
</Warning>
|
||||
|
||||
OpenClaw 现在再次开放 Anthropic setup-token,作为旧版 / 手动路径。
|
||||
Anthropic 针对 OpenClaw 的计费通知仍适用于该路径,因此
|
||||
使用时请预期 Anthropic 会对
|
||||
OpenClaw 驱动的 Claude 登录流量要求 **Extra Usage**。
|
||||
OpenClaw 也将 Anthropic setup-token 作为受支持的基于令牌的认证路径提供,但现在在可用时更优先使用 Claude CLI 复用和 `claude -p`。
|
||||
|
||||
## Anthropic Claude CLI 迁移
|
||||
|
||||
Anthropic 在 OpenClaw 中已不再提供受支持的本地 Claude CLI 迁移路径。
|
||||
对于 Anthropic 流量,请使用 Anthropic API 密钥;或者仅在
|
||||
已经配置好的情况下继续使用旧版基于令牌的认证,并接受 Anthropic 将该 OpenClaw 路径视为 **Extra Usage** 的前提。
|
||||
OpenClaw 再次支持复用 Anthropic Claude CLI。如果你在主机上已经有本地
|
||||
Claude 登录,新手引导 / 配置过程可以直接复用它。
|
||||
|
||||
## OAuth 交换(登录如何工作)
|
||||
|
||||
OpenClaw 的交互式登录流程由 `@mariozechner/pi-ai` 实现,并接入各类向导 / 命令。
|
||||
OpenClaw 的交互式登录流程由 `@mariozechner/pi-ai` 实现,并接入到向导 / 命令中。
|
||||
|
||||
### Anthropic setup-token
|
||||
|
||||
流程形态:
|
||||
流程形式:
|
||||
|
||||
1. 从 OpenClaw 启动 Anthropic setup-token 或 paste-token
|
||||
2. OpenClaw 将生成的 Anthropic 凭证存储到认证配置文件中
|
||||
3. 模型选择保持为 `anthropic/...`
|
||||
4. 现有的 Anthropic 认证配置文件仍可用于回滚 / 顺序控制
|
||||
4. 现有 Anthropic 认证配置文件仍然可用于回滚 / 顺序控制
|
||||
|
||||
### OpenAI Codex(ChatGPT OAuth)
|
||||
|
||||
OpenAI Codex OAuth 明确支持在 Codex CLI 之外使用,包括 OpenClaw 工作流。
|
||||
OpenAI Codex OAuth 已明确支持在 Codex CLI 之外使用,包括 OpenClaw 工作流。
|
||||
|
||||
流程形态(PKCE):
|
||||
流程形式(PKCE):
|
||||
|
||||
1. 生成 PKCE verifier / challenge + 随机 `state`
|
||||
1. 生成 PKCE verifier/challenge + 随机 `state`
|
||||
2. 打开 `https://auth.openai.com/oauth/authorize?...`
|
||||
3. 尝试在 `http://127.0.0.1:1455/auth/callback` 捕获回调
|
||||
4. 如果回调无法绑定(或者你处于远程 / 无头环境),则粘贴重定向 URL / 代码
|
||||
5. 在 `https://auth.openai.com/oauth/token` 执行交换
|
||||
4. 如果无法绑定回调(或你处于远程 / 无头环境),粘贴重定向 URL / 代码
|
||||
5. 在 `https://auth.openai.com/oauth/token` 进行交换
|
||||
6. 从访问令牌中提取 `accountId`,并存储 `{ access, refresh, expires, accountId }`
|
||||
|
||||
向导路径为 `openclaw onboard` → 认证选项 `openai-codex`。
|
||||
@ -135,36 +134,36 @@ OpenAI Codex OAuth 明确支持在 Codex CLI 之外使用,包括 OpenClaw 工
|
||||
|
||||
在运行时:
|
||||
|
||||
- 如果 `expires` 在未来 → 使用已存储的访问令牌
|
||||
- 如果已过期 → 刷新(在文件锁保护下)并覆盖已存储的凭证
|
||||
- 如果 `expires` 还在未来 → 使用已存储的访问令牌
|
||||
- 如果已过期 → 刷新(在文件锁下进行)并覆盖已存储的凭证
|
||||
- 例外:复用的外部 CLI 凭证仍由外部管理;OpenClaw
|
||||
会重新读取 CLI 认证存储,而不会自行使用复制来的刷新令牌
|
||||
会重新读取 CLI 认证存储,绝不会自己使用复制来的刷新令牌
|
||||
|
||||
刷新流程是自动的;通常你不需要手动管理令牌。
|
||||
|
||||
## 多个账户(配置文件)+ 路由
|
||||
## 多个账号(配置文件)+ 路由
|
||||
|
||||
有两种模式:
|
||||
|
||||
### 1)首选:分离智能体
|
||||
### 1)首选:分离的智能体
|
||||
|
||||
如果你希望“个人”和“工作”永不互相影响,请使用隔离的智能体(独立会话 + 凭证 + 工作区):
|
||||
如果你希望“个人”和“工作”永不互相影响,请使用隔离的智能体(独立的会话 + 凭证 + 工作区):
|
||||
|
||||
```bash
|
||||
openclaw agents add work
|
||||
openclaw agents add personal
|
||||
```
|
||||
|
||||
然后按每个智能体配置认证(通过向导),并将聊天路由到正确的智能体。
|
||||
然后按智能体分别配置认证(通过向导),并将聊天路由到正确的智能体。
|
||||
|
||||
### 2)高级:在一个智能体中使用多个配置文件
|
||||
### 2)高级:一个智能体内的多个配置文件
|
||||
|
||||
`auth-profiles.json` 支持同一提供商的多个配置文件 ID。
|
||||
`auth-profiles.json` 支持同一提供商下的多个配置文件 ID。
|
||||
|
||||
选择使用哪个配置文件:
|
||||
|
||||
- 通过配置顺序全局选择(`auth.order`)
|
||||
- 通过 `/model ...@<profileId>` 按会话选择
|
||||
- 通过配置排序全局指定(`auth.order`)
|
||||
- 通过 `/model ...@<profileId>` 按会话指定
|
||||
|
||||
示例(会话覆盖):
|
||||
|
||||
@ -181,6 +180,6 @@ openclaw agents add personal
|
||||
|
||||
## 相关内容
|
||||
|
||||
- [认证](/zh-CN/gateway/authentication) — 模型提供商认证概览
|
||||
- [密钥](/zh-CN/gateway/secrets) — 凭证存储与 SecretRef
|
||||
- [配置参考](/zh-CN/gateway/configuration-reference#auth-storage) — 认证配置键
|
||||
- [Authentication](/zh-CN/gateway/authentication) — 模型提供商认证概览
|
||||
- [Secrets](/zh-CN/gateway/secrets) — 凭证存储与 SecretRef
|
||||
- [Configuration Reference](/zh-CN/gateway/configuration-reference#auth-storage) — 认证配置键名
|
||||
|
||||
@ -1,14 +1,14 @@
|
||||
---
|
||||
read_when:
|
||||
- 调试模型认证或 OAuth 过期问题
|
||||
- 编写关于认证或凭证存储的文档
|
||||
summary: 模型认证:OAuth、API 密钥以及旧版 Anthropic setup-token
|
||||
- 编写认证或凭证存储相关文档
|
||||
summary: 模型认证:OAuth、API 密钥、Claude CLI 复用,以及 Anthropic setup-token
|
||||
title: 认证
|
||||
x-i18n:
|
||||
generated_at: "2026-04-05T17:47:10Z"
|
||||
generated_at: "2026-04-06T15:27:45Z"
|
||||
model: gpt-5.4
|
||||
provider: openai
|
||||
source_hash: f59ede3fcd7e692ad4132287782a850526acf35474b5bfcea29e0e23610636c2
|
||||
source_hash: 9db0ad9eccd7e3e3ca328adaad260bc4288a8ccdbe2dc0c24d9fd049b7ab9231
|
||||
source_path: gateway/authentication.md
|
||||
workflow: 15
|
||||
---
|
||||
@ -16,31 +16,31 @@ x-i18n:
|
||||
# 认证(模型提供商)
|
||||
|
||||
<Note>
|
||||
本页介绍的是**模型提供商**认证(API 密钥、OAuth,以及旧版 Anthropic setup-token)。关于**Gateway 网关连接**认证(token、password、trusted-proxy),请参阅 [配置](/zh-CN/gateway/configuration) 和 [Trusted Proxy Auth](/zh-CN/gateway/trusted-proxy-auth)。
|
||||
本页介绍**模型提供商**认证(API 密钥、OAuth、Claude CLI 复用,以及 Anthropic setup-token)。关于 **Gateway 网关连接** 认证(令牌、密码、trusted-proxy),请参阅 [Configuration](/zh-CN/gateway/configuration) 和 [Trusted Proxy Auth](/zh-CN/gateway/trusted-proxy-auth)。
|
||||
</Note>
|
||||
|
||||
OpenClaw 支持模型提供商使用 OAuth 和 API 密钥。对于始终在线的 Gateway 网关主机,API 密钥通常是最可预测的选择。当它与你的提供商账户模型匹配时,也支持订阅制 / OAuth 流程。
|
||||
OpenClaw 支持模型提供商使用 OAuth 和 API 密钥。对于长期运行的 Gateway 网关主机,API 密钥通常是最可预测的选项。当订阅 / OAuth 流程与你的提供商账户模型匹配时,也支持这类流程。
|
||||
|
||||
完整的 OAuth 流程和存储布局,请参阅 [/concepts/oauth](/zh-CN/concepts/oauth)。
|
||||
关于基于 SecretRef 的认证(`env`/`file`/`exec` 提供商),请参阅 [Secrets Management](/zh-CN/gateway/secrets)。
|
||||
关于 `models status --probe` 使用的凭证适用性 / 原因代码规则,请参阅
|
||||
[Auth Credential Semantics](/zh-CN/auth-credential-semantics)。
|
||||
|
||||
## 推荐设置(API 密钥,任意提供商)
|
||||
## 推荐设置(API 密钥,适用于任何提供商)
|
||||
|
||||
如果你正在运行长期存活的 Gateway 网关,请先为你选择的提供商配置 API 密钥。
|
||||
对于 Anthropic,API 密钥认证是稳妥方案。OpenClaw 中 Anthropic 的订阅式认证属于旧版 setup-token 路径,应被视为**额外用量**路径,而不是套餐限额路径。
|
||||
如果你正在运行一个长期存在的 Gateway 网关,请先为你选择的提供商使用 API 密钥。
|
||||
对于 Anthropic 而言,API 密钥认证仍然是最可预测的服务器端设置,但 OpenClaw 也支持复用本地 Claude CLI 登录。
|
||||
|
||||
1. 在你的提供商控制台中创建一个 API 密钥。
|
||||
2. 将其放到**Gateway 网关主机**上(也就是运行 `openclaw gateway` 的机器)。
|
||||
2. 将其放在**Gateway 网关主机**上(运行 `openclaw gateway` 的机器)。
|
||||
|
||||
```bash
|
||||
export <PROVIDER>_API_KEY="..."
|
||||
openclaw models status
|
||||
```
|
||||
|
||||
3. 如果 Gateway 网关运行在 systemd/launchd 下,建议将密钥放入
|
||||
`~/.openclaw/.env`,这样守护进程就可以读取:
|
||||
3. 如果 Gateway 在 systemd/launchd 下运行,建议将密钥放在
|
||||
`~/.openclaw/.env` 中,以便守护进程可以读取:
|
||||
|
||||
```bash
|
||||
cat >> ~/.openclaw/.env <<'EOF'
|
||||
@ -48,35 +48,35 @@ cat >> ~/.openclaw/.env <<'EOF'
|
||||
EOF
|
||||
```
|
||||
|
||||
然后重启守护进程(或重启你的 Gateway 网关进程),并再次检查:
|
||||
然后重启守护进程(或重启你的 Gateway 网关进程)并重新检查:
|
||||
|
||||
```bash
|
||||
openclaw models status
|
||||
openclaw doctor
|
||||
```
|
||||
|
||||
如果你不想自行管理环境变量,新手引导也可以为守护进程存储
|
||||
如果你不想自己管理环境变量,新手引导可以为守护进程使用存储
|
||||
API 密钥:`openclaw onboard`。
|
||||
|
||||
有关环境继承(`env.shellEnv`、`~/.openclaw/.env`、systemd/launchd)的详细信息,请参阅 [帮助](/zh-CN/help)。
|
||||
关于环境继承(`env.shellEnv`、`~/.openclaw/.env`、systemd/launchd)的详细信息,请参阅 [Help](/zh-CN/help)。
|
||||
|
||||
## Anthropic:旧版令牌兼容性
|
||||
## Anthropic:Claude CLI 和令牌兼容性
|
||||
|
||||
Anthropic setup-token 认证在 OpenClaw 中仍可作为旧版 / 手动路径使用。Anthropic 的公开 Claude Code 文档仍然涵盖 Claude 套餐下直接在终端中使用 Claude Code,但 Anthropic 也单独告知 OpenClaw 用户,**OpenClaw** 的 Claude 登录路径会被视为第三方 harness 用法,并且需要按**额外用量**单独计费,而不包含在订阅内。
|
||||
Anthropic setup-token 认证在 OpenClaw 中仍然作为受支持的令牌路径提供。此后,Anthropic 工作人员告知我们,允许再次使用 OpenClaw 风格的 Claude CLI 用法,因此 OpenClaw 将 Claude CLI 复用和 `claude -p` 用法视为此集成的认可方式,除非 Anthropic 发布新的政策。当主机上可用 Claude CLI 复用时,这现在是首选路径。
|
||||
|
||||
若要采用最清晰的设置路径,请使用 Anthropic API 密钥。如果你必须在 OpenClaw 中保留 Anthropic 的订阅式路径,请使用旧版 setup-token 路径,并预期 Anthropic 会将其视为**额外用量**。
|
||||
对于长期运行的 Gateway 网关主机,Anthropic API 密钥仍然是最可预测的设置。如果你想在同一台主机上复用现有的 Claude 登录,请在新手引导 / 配置中使用 Anthropic Claude CLI 路径。
|
||||
|
||||
手动输入令牌(任意提供商;写入 `auth-profiles.json` 并更新配置):
|
||||
手动输入令牌(适用于任何提供商;会写入 `auth-profiles.json` 并更新配置):
|
||||
|
||||
```bash
|
||||
openclaw models auth paste-token --provider openrouter
|
||||
```
|
||||
|
||||
静态凭证也支持 auth profile 引用:
|
||||
静态凭证也支持认证配置文件引用:
|
||||
|
||||
- `api_key` 凭证可以使用 `keyRef: { source, provider, id }`
|
||||
- `token` 凭证可以使用 `tokenRef: { source, provider, id }`
|
||||
- OAuth 模式的 profile 不支持 SecretRef 凭证;如果 `auth.profiles.<id>.mode` 被设置为 `"oauth"`,则会拒绝该 profile 使用由 SecretRef 支持的 `keyRef`/`tokenRef` 输入。
|
||||
- OAuth 模式的配置文件不支持 SecretRef 凭证;如果 `auth.profiles.<id>.mode` 设置为 `"oauth"`,则会拒绝该配置文件中由 SecretRef 支持的 `keyRef`/`tokenRef` 输入。
|
||||
|
||||
适合自动化的检查(过期 / 缺失时退出码为 `1`,即将过期时为 `2`):
|
||||
|
||||
@ -92,24 +92,25 @@ openclaw models status --probe
|
||||
|
||||
说明:
|
||||
|
||||
- 探测结果行可以来自 auth profile、环境变量凭证或 `models.json`。
|
||||
- 如果显式的 `auth.order.<provider>` 省略了某个已存储 profile,探测会为该 profile 报告
|
||||
- 探测行可来自认证配置文件、环境凭证或 `models.json`。
|
||||
- 如果显式的 `auth.order.<provider>` 省略了已存储的配置文件,探测会为该配置文件报告
|
||||
`excluded_by_auth_order`,而不是尝试使用它。
|
||||
- 如果认证存在,但 OpenClaw 无法为该提供商解析出可探测的模型候选项,探测会报告 `status: no_model`。
|
||||
- 限流冷却可以按模型范围生效。某个 profile 对一个模型处于冷却状态时,仍可能可用于同一提供商下的兄弟模型。
|
||||
- 如果认证存在,但 OpenClaw 无法为该提供商解析出可探测的候选模型,探测会报告
|
||||
`status: no_model`。
|
||||
- 限流冷却期可以按模型范围生效。对某个模型处于冷却中的配置文件,仍然可能可用于同一提供商下的同级模型。
|
||||
|
||||
可选的运维脚本文档(systemd/Termux)见这里:
|
||||
[认证监控脚本](/zh-CN/help/scripts#auth-monitoring-scripts)
|
||||
可选运维脚本(systemd/Termux)文档在这里:
|
||||
[Auth monitoring scripts](/zh-CN/help/scripts#auth-monitoring-scripts)
|
||||
|
||||
## Anthropic 说明
|
||||
|
||||
Anthropic `claude-cli` 后端已被移除。
|
||||
Anthropic `claude-cli` 后端现已再次受支持。
|
||||
|
||||
- 在 OpenClaw 中处理 Anthropic 流量时,请使用 Anthropic API 密钥。
|
||||
- Anthropic setup-token 仍保留为旧版 / 手动路径,使用时应预期按照 Anthropic 向 OpenClaw 用户说明的**额外用量**计费。
|
||||
- `openclaw doctor` 现在会检测已移除但残留的 Anthropic Claude CLI 状态。如果存储的凭证字节仍然存在,doctor 会将它们转换回
|
||||
Anthropic token/OAuth profile。否则,doctor 会移除陈旧的 Claude CLI
|
||||
配置,并引导你使用 API 密钥或 setup-token 进行恢复。
|
||||
- Anthropic 工作人员告诉我们,这条 OpenClaw 集成路径已再次被允许。
|
||||
- 因此,OpenClaw 将 Claude CLI 复用和 `claude -p` 用法视为
|
||||
Anthropic 支持运行中的认可方式,除非 Anthropic 发布新的政策。
|
||||
- 对于长期运行的 Gateway 网关主机,以及需要明确服务器端计费控制的场景,
|
||||
Anthropic API 密钥仍然是最可预测的选择。
|
||||
|
||||
## 检查模型认证状态
|
||||
|
||||
@ -123,29 +124,30 @@ openclaw doctor
|
||||
某些提供商支持在 API 调用触发提供商限流时,使用其他密钥重试请求。
|
||||
|
||||
- 优先级顺序:
|
||||
- `OPENCLAW_LIVE_<PROVIDER>_KEY`(单个覆盖)
|
||||
- `OPENCLAW_LIVE_<PROVIDER>_KEY`(单个覆盖项)
|
||||
- `<PROVIDER>_API_KEYS`
|
||||
- `<PROVIDER>_API_KEY`
|
||||
- `<PROVIDER>_API_KEY_*`
|
||||
- Google 提供商还会将 `GOOGLE_API_KEY` 作为额外回退项。
|
||||
- 同一个密钥列表在使用前会先去重。
|
||||
- OpenClaw 仅会在限流错误时使用下一个密钥重试(例如
|
||||
`429`、`rate_limit`、`quota`、`resource exhausted`、`Too many concurrent requests`、`ThrottlingException`、`concurrency limit reached`,或
|
||||
- Google 提供商还会额外将 `GOOGLE_API_KEY` 作为回退项。
|
||||
- 相同的密钥列表在使用前会去重。
|
||||
- 只有在限流错误时,OpenClaw 才会使用下一个密钥重试(例如
|
||||
`429`、`rate_limit`、`quota`、`resource exhausted`、`Too many concurrent
|
||||
requests`、`ThrottlingException`、`concurrency limit reached`,或
|
||||
`workers_ai ... quota limit exceeded`)。
|
||||
- 非限流错误不会使用备用密钥重试。
|
||||
- 如果所有密钥都失败,则返回最后一次尝试的最终错误。
|
||||
- 如果所有密钥都失败,将返回最后一次尝试产生的最终错误。
|
||||
|
||||
## 控制使用哪个凭证
|
||||
|
||||
### 按会话控制(聊天命令)
|
||||
### 按会话(聊天命令)
|
||||
|
||||
使用 `/model <alias-or-id>@<profileId>` 为当前会话固定指定某个提供商凭证(示例 profile id:`anthropic:default`、`anthropic:work`)。
|
||||
使用 `/model <alias-or-id>@<profileId>` 可为当前会话固定使用特定的提供商凭证(示例配置文件 id:`anthropic:default`、`anthropic:work`)。
|
||||
|
||||
使用 `/model`(或 `/model list`)可打开精简选择器;使用 `/model status` 可查看完整视图(候选项 + 下一个 auth profile,以及在已配置时显示的提供商端点详情)。
|
||||
使用 `/model`(或 `/model list`)可打开紧凑选择器;使用 `/model status` 可查看完整视图(候选项 + 下一个认证配置文件,以及配置后显示的提供商端点详情)。
|
||||
|
||||
### 按智能体控制(CLI 覆盖)
|
||||
### 按智能体(CLI 覆盖)
|
||||
|
||||
为某个智能体设置显式的 auth profile 顺序覆盖(存储在该智能体的 `auth-profiles.json` 中):
|
||||
为某个智能体设置显式的认证配置文件顺序覆盖(存储在该智能体的 `auth-state.json` 中):
|
||||
|
||||
```bash
|
||||
openclaw models auth order get --provider anthropic
|
||||
@ -153,16 +155,17 @@ openclaw models auth order set --provider anthropic anthropic:default
|
||||
openclaw models auth order clear --provider anthropic
|
||||
```
|
||||
|
||||
使用 `--agent <id>` 可指定某个智能体;省略时则使用已配置的默认智能体。
|
||||
调试顺序问题时,`openclaw models status --probe` 会将被省略的已存储
|
||||
profile 显示为 `excluded_by_auth_order`,而不是静默跳过。
|
||||
调试冷却问题时,请记住限流冷却可能只绑定到某个模型 id,而不是整个提供商 profile。
|
||||
使用 `--agent <id>` 可指定特定智能体;省略时则使用已配置的默认智能体。
|
||||
当你调试顺序问题时,`openclaw models status --probe` 会将被省略的
|
||||
已存储配置文件显示为 `excluded_by_auth_order`,而不是静默跳过它们。
|
||||
当你调试冷却问题时,请记住限流冷却期可能只绑定到某个模型 id,
|
||||
而不是整个提供商配置文件。
|
||||
|
||||
## 故障排除
|
||||
|
||||
### “未找到凭证”
|
||||
|
||||
如果 Anthropic profile 缺失,请在**Gateway 网关主机**上配置 Anthropic API 密钥,或设置旧版 Anthropic setup-token 路径,然后重新检查:
|
||||
如果缺少 Anthropic 配置文件,请在**Gateway 网关主机**上配置 Anthropic API 密钥,或设置 Anthropic setup-token 路径,然后重新检查:
|
||||
|
||||
```bash
|
||||
openclaw models status
|
||||
@ -170,15 +173,6 @@ openclaw models status
|
||||
|
||||
### 令牌即将过期 / 已过期
|
||||
|
||||
运行 `openclaw models status` 以确认是哪个 profile 即将过期。如果旧版
|
||||
Anthropic token profile 缺失或已过期,请通过
|
||||
运行 `openclaw models status` 以确认哪个配置文件即将过期。如果某个
|
||||
Anthropic 令牌配置文件缺失或已过期,请通过
|
||||
setup-token 刷新该设置,或迁移到 Anthropic API 密钥。
|
||||
|
||||
如果这台机器仍保留旧构建遗留的、已移除的 Anthropic Claude CLI 状态,请运行:
|
||||
|
||||
```bash
|
||||
openclaw doctor --yes
|
||||
```
|
||||
|
||||
如果存储的凭证字节仍然存在,Doctor 会将 `anthropic:claude-cli` 转换回 Anthropic token/OAuth。否则,它会移除陈旧的 Claude CLI
|
||||
profile/config/model 引用,并保留下一步操作指引。
|
||||
|
||||
@ -3,42 +3,39 @@ read_when:
|
||||
- 当 API 提供商失败时,你想要一个可靠的回退方案
|
||||
- 你正在运行 Codex CLI 或其他本地 AI CLI,并且想要复用它们
|
||||
- 你想了解用于 CLI 后端工具访问的 MCP loopback 桥接
|
||||
summary: CLI 后端:带可选 MCP 工具桥接的本地 AI CLI 回退方案
|
||||
summary: CLI 后端:带可选 MCP 工具桥接的本地 AI CLI 回退
|
||||
title: CLI 后端
|
||||
x-i18n:
|
||||
generated_at: "2026-04-06T12:42:54Z"
|
||||
generated_at: "2026-04-06T15:27:53Z"
|
||||
model: gpt-5.4
|
||||
provider: openai
|
||||
source_hash: fe30bb4d5f51adcda53bf69a4f88e27832e78630ed5bfd8a33a66b6412b66f2d
|
||||
source_hash: f061357f420455ad6ffaabe7fe28f1fb1b1769d73a4eb2e6f45c6eb3c2e36667
|
||||
source_path: gateway/cli-backends.md
|
||||
workflow: 15
|
||||
---
|
||||
|
||||
# CLI 后端(回退运行时)
|
||||
|
||||
当 API 提供商不可用、受到速率限制或暂时行为异常时,OpenClaw 可以将**本地 AI CLI** 作为**纯文本回退方案**运行。这种设计有意保持保守:
|
||||
当 API 提供商不可用、受到速率限制或暂时行为异常时,OpenClaw 可以运行**本地 AI CLI** 作为**纯文本回退**。这是有意采取的保守设计:
|
||||
|
||||
- **OpenClaw 工具不会被直接注入**,但设置了 `bundleMcp: true` 的后端
|
||||
可以通过 loopback MCP 桥接接收 Gateway 网关工具。
|
||||
- **JSONL 流式传输**,适用于支持该能力的 CLI。
|
||||
- **支持会话**(因此后续轮次可以保持连贯)。
|
||||
- 如果 CLI 接受图片路径,**图片也可以透传**。
|
||||
- **不会直接注入 OpenClaw 工具**,但设置了 `bundleMcp: true` 的后端可以通过 loopback MCP 桥接接收 Gateway 网关工具。
|
||||
- 支持 **JSONL 流式传输**,适用于支持它的 CLI。
|
||||
- 支持**会话**(因此后续轮次可以保持连贯)。
|
||||
- 如果 CLI 接受图片路径,**图片可以透传**。
|
||||
|
||||
这被设计为一种**安全兜底机制**,而不是主要路径。当你希望获得“不管怎样都能工作”的文本回复、而不依赖外部 API 时,可以使用它。
|
||||
它的设计目标是作为**安全兜底方案**,而不是主要路径。当你希望在不依赖外部 API 的情况下获得“始终可用”的文本响应时,可以使用它。
|
||||
|
||||
如果你想使用带有 ACP 会话控制、后台任务、线程/对话绑定以及持久化外部编码会话的完整 harness 运行时,请改用
|
||||
[ACP Agents](/zh-CN/tools/acp-agents)。CLI 后端不是 ACP。
|
||||
如果你想要一个具备 ACP 会话控制、后台任务、线程/对话绑定以及持久化外部编码会话的完整 harness 运行时,请改用 [ACP Agents](/zh-CN/tools/acp-agents)。CLI 后端不是 ACP。
|
||||
|
||||
## 面向初学者的快速开始
|
||||
|
||||
你可以**无需任何配置**使用 Codex CLI(内置的 OpenAI 插件会注册一个默认后端):
|
||||
你可以在**无需任何配置**的情况下使用 Codex CLI(内置 OpenAI 插件会注册一个默认后端):
|
||||
|
||||
```bash
|
||||
openclaw agent --message "hi" --model codex-cli/gpt-5.4
|
||||
```
|
||||
|
||||
如果你的 Gateway 网关运行在 launchd/systemd 下,且 `PATH` 很精简,只需添加
|
||||
命令路径:
|
||||
如果你的 Gateway 网关运行在 launchd/systemd 下,且 PATH 非常精简,只需添加命令路径:
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -54,16 +51,13 @@ openclaw agent --message "hi" --model codex-cli/gpt-5.4
|
||||
}
|
||||
```
|
||||
|
||||
就是这样。除了 CLI 本身之外,不需要密钥,也不需要额外的凭证配置。
|
||||
就是这样。除了 CLI 本身之外,不需要密钥,也不需要额外的身份验证配置。
|
||||
|
||||
如果你在 gateway host 上将某个内置 CLI 后端用作**主要消息提供商**,当你的配置
|
||||
在模型引用中或在
|
||||
`agents.defaults.cliBackends`
|
||||
下明确引用了该后端时,OpenClaw 现在会自动加载其所属的内置插件。
|
||||
如果你在 Gateway 网关主机上将内置 CLI 后端用作**主要消息提供商**,现在只要你的配置在模型引用中或在 `agents.defaults.cliBackends` 下显式引用了该后端,OpenClaw 就会自动加载对应的内置插件。
|
||||
|
||||
## 将其用作回退方案
|
||||
## 将其用作回退
|
||||
|
||||
将某个 CLI 后端添加到你的回退列表中,这样它只会在主要模型失败时运行:
|
||||
把一个 CLI 后端添加到你的回退列表中,这样它只会在主要模型失败时运行:
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -84,9 +78,8 @@ openclaw agent --message "hi" --model codex-cli/gpt-5.4
|
||||
|
||||
说明:
|
||||
|
||||
- 如果你使用 `agents.defaults.models`(允许列表),你也必须将你的 CLI 后端模型包含在其中。
|
||||
- 如果主要提供商失败(凭证、速率限制、超时),OpenClaw 将会
|
||||
接着尝试 CLI 后端。
|
||||
- 如果你使用 `agents.defaults.models`(允许列表),你也必须把 CLI 后端模型包含进去。
|
||||
- 如果主要提供商失败(身份验证、速率限制、超时),OpenClaw 会接着尝试 CLI 后端。
|
||||
|
||||
## 配置概览
|
||||
|
||||
@ -96,8 +89,8 @@ openclaw agent --message "hi" --model codex-cli/gpt-5.4
|
||||
agents.defaults.cliBackends
|
||||
```
|
||||
|
||||
每个条目都由一个**提供商 id** 作为键(例如 `codex-cli`、`my-cli`)。
|
||||
这个提供商 id 会成为你的模型引用左侧部分:
|
||||
每个条目都以一个**提供商 id** 为键(例如 `codex-cli`、`my-cli`)。
|
||||
该提供商 id 会成为你的模型引用左侧部分:
|
||||
|
||||
```
|
||||
<provider>/<model>
|
||||
@ -142,35 +135,31 @@ agents.defaults.cliBackends
|
||||
|
||||
1. 根据提供商前缀(`codex-cli/...`)**选择一个后端**。
|
||||
2. 使用相同的 OpenClaw 提示词和工作区上下文**构建系统提示词**。
|
||||
3. 使用会话 id(如果支持)**执行 CLI**,以保持历史记录一致。
|
||||
4. **解析输出**(JSON 或纯文本),并返回最终文本。
|
||||
5. 按后端**持久化会话 id**,使后续轮次复用同一个 CLI 会话。
|
||||
3. 如果支持,则带着会话 id **执行 CLI**,以便保持历史一致。
|
||||
4. **解析输出**(JSON 或纯文本)并返回最终文本。
|
||||
5. 按后端**持久化会话 id**,这样后续轮次就会复用同一个 CLI 会话。
|
||||
|
||||
<Warning>
|
||||
内置的 Anthropic `claude-cli` 后端已被移除,因为 Anthropic 的
|
||||
OpenClaw 计费边界发生了变化。OpenClaw 仍然支持通用 CLI
|
||||
后端,但 Anthropic API 流量应当直接使用 Anthropic 提供商,
|
||||
而不是已移除的本地 Claude CLI 路径。
|
||||
</Warning>
|
||||
<Note>
|
||||
内置 Anthropic `claude-cli` 后端现已再次受支持。Anthropic 工作人员告诉我们,OpenClaw 风格的 Claude CLI 用法现在再次被允许,因此除非 Anthropic 发布新政策,否则 OpenClaw 会将 `claude -p` 用法视为此集成的许可方式。
|
||||
</Note>
|
||||
|
||||
## 会话
|
||||
|
||||
- 如果 CLI 支持会话,请设置 `sessionArg`(例如 `--session-id`)或
|
||||
`sessionArgs`(占位符 `{sessionId}`),用于在需要将该 ID 插入
|
||||
到多个标志位时使用。
|
||||
- 如果 CLI 使用带有不同标志位的**恢复子命令**,请设置
|
||||
`sessionArgs`(占位符 `{sessionId}`),用于在需要将该 ID 插入多个标志时使用。
|
||||
- 如果 CLI 使用带有不同标志的**恢复子命令**,请设置
|
||||
`resumeArgs`(恢复时替换 `args`),并可选设置 `resumeOutput`
|
||||
(用于非 JSON 的恢复输出)。
|
||||
(用于非 JSON 恢复)。
|
||||
- `sessionMode`:
|
||||
- `always`:始终发送会话 id(如果没有已存储值,则使用新的 UUID)。
|
||||
- `existing`:仅当之前已存储会话 id 时才发送。
|
||||
- `always`:始终发送会话 id(如果没有已存储值,则生成新的 UUID)。
|
||||
- `existing`:仅在之前存储过会话 id 时发送。
|
||||
- `none`:从不发送会话 id。
|
||||
|
||||
序列化说明:
|
||||
|
||||
- `serialize: true` 会保持同一通道运行按顺序执行。
|
||||
- 大多数 CLI 会在一个提供商通道上串行执行。
|
||||
- 当后端凭证状态发生变化时,包括重新登录、令牌轮换或凭证配置发生变化,OpenClaw 会丢弃已存储的 CLI 会话复用信息。
|
||||
- 大多数 CLI 会在单个提供商通道上串行化。
|
||||
- 当后端身份验证状态发生变化时,包括重新登录、令牌轮换或身份验证配置文件凭据变更,OpenClaw 会丢弃已存储的 CLI 会话复用。
|
||||
|
||||
## 图片(透传)
|
||||
|
||||
@ -181,29 +170,24 @@ imageArg: "--image",
|
||||
imageMode: "repeat"
|
||||
```
|
||||
|
||||
OpenClaw 会将 base64 图片写入临时文件。如果设置了 `imageArg`,这些
|
||||
路径会作为 CLI 参数传递。如果缺少 `imageArg`,OpenClaw 会将
|
||||
这些文件路径附加到提示词中(路径注入),这对于那些可以从普通路径中自动
|
||||
加载本地文件的 CLI 来说已经足够。
|
||||
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: "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。
|
||||
- 如果提示词非常长且设置了 `maxPromptArgChars`,则会改用 stdin。
|
||||
|
||||
## 默认值(插件所有)
|
||||
## 默认值(插件拥有)
|
||||
|
||||
内置的 OpenAI 插件也为 `codex-cli` 注册了一个默认值:
|
||||
内置 OpenAI 插件还为 `codex-cli` 注册了一个默认值:
|
||||
|
||||
- `command: "codex"`
|
||||
- `args: ["exec","--json","--color","never","--sandbox","workspace-write","--skip-git-repo-check"]`
|
||||
@ -214,7 +198,7 @@ OpenClaw 会将 base64 图片写入临时文件。如果设置了 `imageArg`,
|
||||
- `imageArg: "--image"`
|
||||
- `sessionMode: "existing"`
|
||||
|
||||
内置的 Google 插件也为 `google-gemini-cli` 注册了一个默认值:
|
||||
内置 Google 插件也为 `google-gemini-cli` 注册了一个默认值:
|
||||
|
||||
- `command: "gemini"`
|
||||
- `args: ["--prompt", "--output-format", "json"]`
|
||||
@ -223,67 +207,63 @@ OpenClaw 会将 base64 图片写入临时文件。如果设置了 `imageArg`,
|
||||
- `sessionMode: "existing"`
|
||||
- `sessionIdFields: ["session_id", "sessionId"]`
|
||||
|
||||
前提条件:本地 Gemini CLI 必须已安装,并且可以作为
|
||||
`gemini` 在 `PATH` 中使用(`brew install gemini-cli` 或
|
||||
前提条件:本地 Gemini CLI 必须已安装,并且能通过 `PATH` 中的
|
||||
`gemini` 使用(`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.cached` 会被标准化为 OpenClaw `cacheRead`。
|
||||
- 如果 `stats.input` 缺失,OpenClaw 会根据
|
||||
`stats.input_tokens - stats.cached` 推导输入 token 数。
|
||||
|
||||
只在需要时覆盖这些默认值(常见情况:使用绝对 `command` 路径)。
|
||||
仅在需要时覆盖(常见情况:使用绝对 `command` 路径)。
|
||||
|
||||
## 插件所有的默认值
|
||||
## 插件拥有的默认值
|
||||
|
||||
CLI 后端默认值现在已成为插件表面的一部分:
|
||||
CLI 后端默认值现在属于插件表面的一部分:
|
||||
|
||||
- 插件使用 `api.registerCliBackend(...)` 注册它们。
|
||||
- 后端 `id` 会成为模型引用中的提供商前缀。
|
||||
- 用户在 `agents.defaults.cliBackends.<id>` 中的配置仍会覆盖插件默认值。
|
||||
- 插件通过 `api.registerCliBackend(...)` 注册它们。
|
||||
- 后端的 `id` 会成为模型引用中的提供商前缀。
|
||||
- `agents.defaults.cliBackends.<id>` 中的用户配置仍然会覆盖插件默认值。
|
||||
- 后端特定的配置清理由插件通过可选的
|
||||
`normalizeConfig` hook 保持所有权。
|
||||
`normalizeConfig` hook 继续拥有。
|
||||
|
||||
## Bundle MCP 覆盖层
|
||||
|
||||
CLI 后端**不会**直接接收 OpenClaw 工具调用,但某个后端可以通过
|
||||
`bundleMcp: true` 选择启用自动生成的 MCP 配置覆盖层。
|
||||
CLI 后端**不会**直接接收 OpenClaw 工具调用,但后端可以通过设置
|
||||
`bundleMcp: true` 选择加入自动生成的 MCP 配置覆盖层。
|
||||
|
||||
当前内置行为:
|
||||
|
||||
- `codex-cli`:不提供 bundle MCP 覆盖层
|
||||
- `google-gemini-cli`:不提供 bundle MCP 覆盖层
|
||||
- `codex-cli`:无 bundle MCP 覆盖层
|
||||
- `google-gemini-cli`:无 bundle MCP 覆盖层
|
||||
|
||||
启用 bundle MCP 时,OpenClaw 会:
|
||||
启用 bundle MCP 后,OpenClaw 会:
|
||||
|
||||
- 启动一个 loopback HTTP MCP 服务器,将 Gateway 网关工具暴露给 CLI 进程
|
||||
- 使用每会话令牌(`OPENCLAW_MCP_TOKEN`)对桥接进行身份验证
|
||||
- 将工具访问范围限定在当前会话、账户和渠道上下文内
|
||||
- 将工具访问范围限定到当前会话、账户和渠道上下文
|
||||
- 为当前工作区加载已启用的 bundle-MCP 服务器
|
||||
- 将它们与任何现有的后端 `--mcp-config` 合并
|
||||
- 重写 CLI 参数,传入 `--strict-mcp-config --mcp-config <generated-file>`
|
||||
- 将它们与任何现有后端 `--mcp-config` 合并
|
||||
- 重写 CLI 参数以传递 `--strict-mcp-config --mcp-config <generated-file>`
|
||||
|
||||
如果没有启用任何 MCP 服务器,当后端选择启用 bundle MCP 时,OpenClaw 仍会注入严格配置,以便后台运行保持隔离。
|
||||
如果没有启用任何 MCP 服务器,那么当后端选择加入 bundle MCP 时,OpenClaw 仍会注入严格配置,以便后台运行保持隔离。
|
||||
|
||||
## 限制
|
||||
|
||||
- **没有直接的 OpenClaw 工具调用。** OpenClaw 不会将工具调用直接注入
|
||||
到 CLI 后端协议中。只有当后端启用
|
||||
`bundleMcp: true` 时,它们才会看到 Gateway 网关工具。
|
||||
- **流式传输是后端特定的。** 某些后端会流式输出 JSONL;其他后端则会
|
||||
缓冲到退出时再输出。
|
||||
- **没有直接的 OpenClaw 工具调用。** OpenClaw 不会把工具调用注入到
|
||||
CLI 后端协议中。只有当后端选择加入 `bundleMcp: true` 时,它们才能看到 Gateway 网关工具。
|
||||
- **流式传输取决于后端。** 有些后端会流式输出 JSONL;其他后端则会一直缓冲到退出。
|
||||
- **结构化输出** 取决于 CLI 的 JSON 格式。
|
||||
- **Codex CLI 会话** 通过文本输出恢复(没有 JSONL),其结构化程度
|
||||
低于初始的 `--json` 运行。但 OpenClaw 会话仍然可以
|
||||
正常工作。
|
||||
- **Codex CLI 会话** 通过文本输出恢复(没有 JSONL),其结构性弱于初始的 `--json` 运行。不过 OpenClaw 会话仍然可以正常工作。
|
||||
|
||||
## 故障排除
|
||||
|
||||
- **找不到 CLI**:将 `command` 设置为完整路径。
|
||||
- **模型名称错误**:使用 `modelAliases` 将 `provider/model` 映射到 CLI 模型。
|
||||
- **模型名称错误**:使用 `modelAliases` 将 `provider/model` 映射为 CLI 模型。
|
||||
- **没有会话连续性**:确保已设置 `sessionArg`,并且 `sessionMode` 不是
|
||||
`none`(Codex CLI 当前无法使用 JSON 输出进行恢复)。
|
||||
`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-06T12:43:39Z"
|
||||
generated_at: "2026-04-06T15:29:03Z"
|
||||
model: gpt-5.4
|
||||
provider: openai
|
||||
source_hash: f20637d373c3b1be7c4a3d5424228908b5639cfded8ad5acb9c29f882d0f8d2b
|
||||
source_hash: a834dc7aec79c20d17bc23d37fb5f5e99e628d964d55bd8cf24525a7ee57130c
|
||||
source_path: gateway/doctor.md
|
||||
workflow: 15
|
||||
---
|
||||
|
||||
# Doctor
|
||||
|
||||
`openclaw doctor` 是 OpenClaw 的修复 + 迁移工具。它会修复过时的配置/状态,执行健康检查,并提供可操作的修复步骤。
|
||||
`openclaw doctor` 是 OpenClaw 的修复 + 迁移工具。它会修复过时的配置 / 状态、检查健康状况,并提供可执行的修复步骤。
|
||||
|
||||
## 快速开始
|
||||
|
||||
@ -29,13 +29,13 @@ openclaw doctor
|
||||
openclaw doctor --yes
|
||||
```
|
||||
|
||||
接受默认值而不提示(包括在适用时的重启/服务/沙箱修复步骤)。
|
||||
接受默认选项而不提示(包括在适用时的重启 / 服务 / 沙箱修复步骤)。
|
||||
|
||||
```bash
|
||||
openclaw doctor --repair
|
||||
```
|
||||
|
||||
不经提示直接应用推荐修复(在安全的情况下进行修复 + 重启)。
|
||||
不经提示应用推荐修复(在安全情况下执行修复 + 重启)。
|
||||
|
||||
```bash
|
||||
openclaw doctor --repair --force
|
||||
@ -47,16 +47,16 @@ openclaw doctor --repair --force
|
||||
openclaw doctor --non-interactive
|
||||
```
|
||||
|
||||
在无提示的情况下运行,并且仅应用安全迁移(配置规范化 + 磁盘状态移动)。跳过需要人工确认的重启/服务/沙箱操作。
|
||||
无提示运行,并且只应用安全迁移(配置规范化 + 磁盘状态迁移)。跳过需要人工确认的重启 / 服务 / 沙箱操作。
|
||||
检测到旧状态迁移时会自动运行。
|
||||
|
||||
```bash
|
||||
openclaw doctor --deep
|
||||
```
|
||||
|
||||
扫描系统服务以查找额外的 Gateway 网关安装(`launchd`/`systemd`/`schtasks`)。
|
||||
扫描系统服务中的额外 Gateway 网关安装(launchd/systemd/schtasks)。
|
||||
|
||||
如果你想在写入前查看更改,先打开配置文件:
|
||||
如果你想在写入前先查看变更,请先打开配置文件:
|
||||
|
||||
```bash
|
||||
cat ~/.openclaw/openclaw.json
|
||||
@ -64,67 +64,67 @@ cat ~/.openclaw/openclaw.json
|
||||
|
||||
## 它会做什么(摘要)
|
||||
|
||||
- 针对 git 安装的可选飞行前更新(仅交互式)。
|
||||
- git 安装的可选预检更新(仅交互模式)。
|
||||
- UI 协议新鲜度检查(当协议 schema 更新时重建 Control UI)。
|
||||
- 健康检查 + 重启提示。
|
||||
- Skills 状态摘要(可用/缺失/被阻止)和插件状态。
|
||||
- 对旧版值执行配置规范化。
|
||||
- 将旧版扁平 `talk.*` 字段迁移到 `talk.provider` + `talk.providers.<provider>` 的 Talk 配置迁移。
|
||||
- 针对旧版 Chrome 扩展配置和 Chrome MCP 就绪情况的浏览器迁移检查。
|
||||
- Skills 状态摘要(可用 / 缺失 / 被阻止)和插件状态。
|
||||
- 旧版值的配置规范化。
|
||||
- 将旧版扁平 `talk.*` 字段迁移为 `talk.provider` + `talk.providers.<provider>` 的 Talk 配置迁移。
|
||||
- 针对旧版 Chrome 扩展配置和 Chrome MCP 就绪状态的浏览器迁移检查。
|
||||
- OpenCode 提供商覆盖警告(`models.providers.opencode` / `models.providers.opencode-go`)。
|
||||
- 针对 OpenAI Codex OAuth 配置文件的 OAuth TLS 前置条件检查。
|
||||
- 旧版磁盘状态迁移(会话/智能体目录/WhatsApp 认证)。
|
||||
- 旧版插件清单 contract 键迁移(`speechProviders`、`realtimeTranscriptionProviders`、`realtimeVoiceProviders`、`mediaUnderstandingProviders`、`imageGenerationProviders`、`videoGenerationProviders`、`webFetchProviders`、`webSearchProviders` → `contracts`)。
|
||||
- 旧版 cron 存储迁移(`jobId`、`schedule.cron`、顶层 delivery/payload 字段、payload `provider`、简单的 `notify: true` webhook 回退任务)。
|
||||
- 会话锁文件检查和过期锁清理。
|
||||
- 状态完整性和权限检查(会话、转录、状态目录)。
|
||||
- OpenAI Codex OAuth 配置文件的 OAuth TLS 前提条件检查。
|
||||
- 旧版磁盘状态迁移(sessions / agent 目录 / WhatsApp 认证)。
|
||||
- 旧版插件清单契约键迁移(`speechProviders`、`realtimeTranscriptionProviders`、`realtimeVoiceProviders`、`mediaUnderstandingProviders`、`imageGenerationProviders`、`videoGenerationProviders`、`webFetchProviders`、`webSearchProviders` → `contracts`)。
|
||||
- 旧版 cron 存储迁移(`jobId`、`schedule.cron`、顶层 delivery / payload 字段、payload `provider`、简单的 `notify: true` webhook 回退任务)。
|
||||
- 会话锁文件检查和过时锁清理。
|
||||
- 状态完整性和权限检查(sessions、transcripts、状态目录)。
|
||||
- 本地运行时的配置文件权限检查(`chmod 600`)。
|
||||
- 模型认证健康状态:检查 OAuth 过期情况,可刷新即将过期的令牌,并报告认证配置文件的冷却/禁用状态。
|
||||
- 模型认证健康检查:检查 OAuth 过期、可刷新即将过期的令牌,并报告 auth-profile 冷却 / 禁用状态。
|
||||
- 额外工作区目录检测(`~/openclaw`)。
|
||||
- 启用沙箱隔离时执行沙箱镜像修复。
|
||||
- 启用沙箱隔离时的沙箱镜像修复。
|
||||
- 旧版服务迁移和额外 Gateway 网关检测。
|
||||
- Matrix 渠道旧版状态迁移(在 `--fix` / `--repair` 模式下)。
|
||||
- Gateway 网关运行时检查(服务已安装但未运行;缓存的 `launchd` 标签)。
|
||||
- Gateway 网关运行时检查(服务已安装但未运行;缓存的 launchd 标签)。
|
||||
- 渠道状态警告(从正在运行的 Gateway 网关探测)。
|
||||
- supervisor 配置审计(`launchd`/`systemd`/`schtasks`)及可选修复。
|
||||
- supervisor 配置审计(launchd/systemd/schtasks)并可选修复。
|
||||
- Gateway 网关运行时最佳实践检查(Node 与 Bun、版本管理器路径)。
|
||||
- Gateway 网关端口冲突诊断(默认 `18789`)。
|
||||
- 针对开放私信策略的安全警告。
|
||||
- 本地令牌模式下的 Gateway 网关认证检查(当不存在令牌来源时提供生成令牌;不会覆盖令牌 SecretRef 配置)。
|
||||
- Linux 上的 `systemd linger` 检查。
|
||||
- 工作区 bootstrap 文件大小检查(上下文文件的截断/接近上限警告)。
|
||||
- Shell 补全状态检查和自动安装/升级。
|
||||
- 内存搜索嵌入提供商就绪情况检查(本地模型、远程 API 密钥或 QMD 二进制文件)。
|
||||
- 源码安装检查(`pnpm` 工作区不匹配、缺失 UI 资源、缺失 `tsx` 二进制文件)。
|
||||
- 本地令牌模式下的 Gateway 网关认证检查(当没有令牌来源时提供生成令牌;不会覆盖令牌 SecretRef 配置)。
|
||||
- Linux 上的 systemd linger 检查。
|
||||
- 工作区 bootstrap 文件大小检查(针对上下文文件的截断 / 接近上限警告)。
|
||||
- Shell 补全状态检查和自动安装 / 升级。
|
||||
- Memory search embedding 提供商就绪状态检查(本地模型、远程 API 密钥或 QMD 二进制文件)。
|
||||
- 源码安装检查(pnpm workspace 不匹配、缺失 UI 资源、缺失 tsx 二进制文件)。
|
||||
- 写入更新后的配置 + 向导元数据。
|
||||
|
||||
## 详细行为和原理说明
|
||||
## 详细行为和原理
|
||||
|
||||
### 0)可选更新(git 安装)
|
||||
### 0) 可选更新(git 安装)
|
||||
|
||||
如果这是一个 git 检出副本,并且 doctor 以交互方式运行,它会在运行 doctor 之前提供更新选项(fetch/rebase/build)。
|
||||
如果这是一个 git 检出,并且 Doctor 正在以交互模式运行,它会先提供更新(fetch / rebase / build),然后再运行 Doctor。
|
||||
|
||||
### 1)配置规范化
|
||||
### 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` 形式重写到 provider 映射中。
|
||||
`talk.apiKey` 形状重写到提供商映射中。
|
||||
|
||||
### 2)旧版配置键迁移
|
||||
### 2) 旧版配置键迁移
|
||||
|
||||
当配置中包含已弃用键时,其他命令会拒绝运行,并要求你运行
|
||||
当配置包含已弃用的键时,其他命令会拒绝运行,并要求你运行
|
||||
`openclaw doctor`。
|
||||
|
||||
Doctor 将会:
|
||||
|
||||
- 说明发现了哪些旧版键。
|
||||
- 显示它应用的迁移。
|
||||
- 显示它所应用的迁移。
|
||||
- 使用更新后的 schema 重写 `~/.openclaw/openclaw.json`。
|
||||
|
||||
Gateway 网关 在启动时检测到旧版配置格式时,也会自动运行 doctor 迁移,因此过时配置无需手动干预即可被修复。
|
||||
当 Gateway 网关在启动时检测到旧版配置格式,也会自动运行 Doctor 迁移,因此无需手动干预就能修复过时配置。
|
||||
Cron 任务存储迁移由 `openclaw doctor --fix` 处理。
|
||||
|
||||
当前迁移包括:
|
||||
@ -139,100 +139,97 @@ Cron 任务存储迁移由 `openclaw doctor --fix` 处理。
|
||||
- 旧版 `talk.voiceId`/`talk.voiceAliases`/`talk.modelId`/`talk.outputFormat`/`talk.apiKey` → `talk.provider` + `talk.providers.<provider>`
|
||||
- `routing.agentToAgent` → `tools.agentToAgent`
|
||||
- `routing.transcribeAudio` → `tools.media.audio.models`
|
||||
- `messages.tts.<provider>`(`openai`/`elevenlabs`/`microsoft`/`edge`)→ `messages.tts.providers.<provider>`
|
||||
- `channels.discord.voice.tts.<provider>`(`openai`/`elevenlabs`/`microsoft`/`edge`)→ `channels.discord.voice.tts.providers.<provider>`
|
||||
- `channels.discord.accounts.<id>.voice.tts.<provider>`(`openai`/`elevenlabs`/`microsoft`/`edge`)→ `channels.discord.accounts.<id>.voice.tts.providers.<provider>`
|
||||
- `plugins.entries.voice-call.config.tts.<provider>`(`openai`/`elevenlabs`/`microsoft`/`edge`)→ `plugins.entries.voice-call.config.tts.providers.<provider>`
|
||||
- `messages.tts.<provider>` (`openai`/`elevenlabs`/`microsoft`/`edge`) → `messages.tts.providers.<provider>`
|
||||
- `channels.discord.voice.tts.<provider>` (`openai`/`elevenlabs`/`microsoft`/`edge`) → `channels.discord.voice.tts.providers.<provider>`
|
||||
- `channels.discord.accounts.<id>.voice.tts.<provider>` (`openai`/`elevenlabs`/`microsoft`/`edge`) → `channels.discord.accounts.<id>.voice.tts.providers.<provider>`
|
||||
- `plugins.entries.voice-call.config.tts.<provider>` (`openai`/`elevenlabs`/`microsoft`/`edge`) → `plugins.entries.voice-call.config.tts.providers.<provider>`
|
||||
- `plugins.entries.voice-call.config.provider: "log"` → `"mock"`
|
||||
- `plugins.entries.voice-call.config.twilio.from` → `plugins.entries.voice-call.config.fromNumber`
|
||||
- `plugins.entries.voice-call.config.streaming.sttProvider` → `plugins.entries.voice-call.config.streaming.provider`
|
||||
- `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.*` → `agents.defaults` + `tools.*`(tools / elevated / exec / sandbox / subagents)
|
||||
- `agent.model`/`allowedModels`/`modelAliases`/`modelFallbacks`/`imageModelFallbacks`
|
||||
→ `agents.defaults.models` + `agents.defaults.model.primary/fallbacks` + `agents.defaults.imageModel.primary/fallbacks`
|
||||
- `browser.ssrfPolicy.allowPrivateNetwork` → `browser.ssrfPolicy.dangerouslyAllowPrivateNetwork`
|
||||
- `browser.profiles.*.driver: "extension"` → `"existing-session"`
|
||||
- 删除 `browser.relayBindHost`(旧版扩展 relay 设置)
|
||||
|
||||
Doctor 警告还包括针对多账户渠道的默认账户指导:
|
||||
Doctor 警告还包括针对多账户渠道的账户默认值指导:
|
||||
|
||||
- 如果配置了两个或更多 `channels.<channel>.accounts` 条目,但没有 `channels.<channel>.defaultAccount` 或 `accounts.default`,doctor 会警告回退路由可能会选择意外的账户。
|
||||
- 如果 `channels.<channel>.defaultAccount` 设置为未知账户 ID,doctor 会发出警告并列出已配置的账户 ID。
|
||||
- 如果配置了两个或更多 `channels.<channel>.accounts` 条目,但没有 `channels.<channel>.defaultAccount` 或 `accounts.default`,Doctor 会警告回退路由可能会选择意外的账户。
|
||||
- 如果 `channels.<channel>.defaultAccount` 设置为未知账户 ID,Doctor 会发出警告并列出已配置的账户 ID。
|
||||
|
||||
### 2b)OpenCode 提供商覆盖
|
||||
### 2b) OpenCode 提供商覆盖
|
||||
|
||||
如果你手动添加了 `models.providers.opencode`、`opencode-zen` 或 `opencode-go`,
|
||||
它会覆盖来自 `@mariozechner/pi-ai` 的内置 OpenCode 目录。
|
||||
这可能会将模型强制路由到错误的 API,或将成本归零。Doctor 会发出警告,以便你删除该覆盖并恢复按模型的 API 路由 + 成本。
|
||||
这可能会把模型强制路由到错误的 API,或将成本清零。Doctor 会发出警告,以便你移除覆盖并恢复按模型的 API 路由 + 成本。
|
||||
|
||||
### 2c)浏览器迁移和 Chrome MCP 就绪情况
|
||||
### 2c) 浏览器迁移和 Chrome MCP 就绪状态
|
||||
|
||||
如果你的浏览器配置仍指向已移除的 Chrome 扩展路径,doctor 会将其规范化为当前的主机本地 Chrome MCP 连接模型:
|
||||
如果你的浏览器配置仍然指向已移除的 Chrome 扩展路径,Doctor 会将其规范化为当前的主机本地 Chrome MCP 附加模型:
|
||||
|
||||
- `browser.profiles.*.driver: "extension"` 变为 `"existing-session"`
|
||||
- 删除 `browser.relayBindHost`
|
||||
- `browser.profiles.*.driver: "extension"` 会变为 `"existing-session"`
|
||||
- `browser.relayBindHost` 会被移除
|
||||
|
||||
当你使用 `defaultProfile:
|
||||
"user"` 或已配置的 `existing-session` 配置文件时,doctor 还会审计主机本地的 Chrome MCP 路径:
|
||||
"user"` 或已配置的 `existing-session` 配置文件时,Doctor 还会审计主机本地 Chrome MCP 路径:
|
||||
|
||||
- 检查默认自动连接配置文件是否在同一主机上安装了 Google Chrome
|
||||
- 检查检测到的 Chrome 版本,并在其低于 Chrome 144 时发出警告
|
||||
- 提醒你在浏览器检查页面中启用远程调试(例如
|
||||
- 检查默认自动连接配置文件所在的同一主机上是否安装了 Google Chrome
|
||||
- 检查检测到的 Chrome 版本,并在低于 Chrome 144 时发出警告
|
||||
- 提醒你在浏览器 inspect 页面启用远程调试(例如
|
||||
`chrome://inspect/#remote-debugging`、`brave://inspect/#remote-debugging`,
|
||||
或 `edge://inspect/#remote-debugging`)
|
||||
|
||||
Doctor 无法为你启用 Chrome 侧设置。主机本地 Chrome MCP
|
||||
仍然需要:
|
||||
Doctor 无法替你启用 Chrome 侧设置。主机本地 Chrome MCP 仍然需要:
|
||||
|
||||
- Gateway 网关/节点主机上的 Chromium 内核浏览器 144+
|
||||
- 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 前置条件
|
||||
### 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 会打印平台专用修复指引。在 macOS 上,如果使用 Homebrew Node,修复通常是 `brew postinstall ca-certificates`。使用 `--deep` 时,即使 Gateway 网关健康,该探测也会运行。
|
||||
|
||||
### 3)旧版状态迁移(磁盘布局)
|
||||
### 3) 旧版状态迁移(磁盘布局)
|
||||
|
||||
Doctor 可以将旧版磁盘布局迁移到当前结构:
|
||||
|
||||
- 会话存储 + 转录:
|
||||
- Sessions 存储 + transcripts:
|
||||
- 从 `~/.openclaw/sessions/` 到 `~/.openclaw/agents/<agentId>/sessions/`
|
||||
- 智能体目录:
|
||||
- Agent 目录:
|
||||
- 从 `~/.openclaw/agent/` 到 `~/.openclaw/agents/<agentId>/agent/`
|
||||
- WhatsApp 认证状态(Baileys):
|
||||
- 从旧版 `~/.openclaw/credentials/*.json`(`oauth.json` 除外)
|
||||
- 从旧版 `~/.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 也会在启动时自动迁移旧版 sessions + agent 目录,因此历史记录 / 认证 / 模型会落到按智能体划分的路径中,而无需手动运行 Doctor。WhatsApp 认证有意只通过 `openclaw doctor` 迁移。Talk provider / provider-map 规范化现在按结构相等性比较,因此仅键顺序不同的差异不再触发重复的无操作 `doctor --fix` 变更。
|
||||
|
||||
### 3a)旧版插件清单迁移
|
||||
### 3a) 旧版插件清单迁移
|
||||
|
||||
Doctor 会扫描所有已安装插件清单中的已弃用顶层 capability
|
||||
键(`speechProviders`、`realtimeTranscriptionProviders`、
|
||||
Doctor 会扫描所有已安装插件清单中已弃用的顶层能力键
|
||||
(`speechProviders`、`realtimeTranscriptionProviders`、
|
||||
`realtimeVoiceProviders`、`mediaUnderstandingProviders`、
|
||||
`imageGenerationProviders`、`videoGenerationProviders`、`webFetchProviders`、
|
||||
`webSearchProviders`)。发现后,它会提供将它们移动到 `contracts`
|
||||
对象并原地重写清单文件。此迁移是幂等的;
|
||||
如果 `contracts` 键已经具有相同的值,则会删除旧版键,而不会重复数据。
|
||||
`webSearchProviders`)。发现后,它会提示将它们移动到 `contracts`
|
||||
对象中,并原地重写清单文件。此迁移是幂等的;
|
||||
如果 `contracts` 键中已经有相同值,就会删除旧版键,
|
||||
而不会重复数据。
|
||||
|
||||
### 3b)旧版 cron 存储迁移
|
||||
### 3b) 旧版 cron 存储迁移
|
||||
|
||||
Doctor 还会检查 cron 任务存储(默认是 `~/.openclaw/cron/jobs.json`,
|
||||
或者在覆盖时使用 `cron.store`)中调度器仍为兼容性而接受的旧任务形态。
|
||||
Doctor 还会检查 cron 任务存储(默认为 `~/.openclaw/cron/jobs.json`,
|
||||
若有覆盖则使用 `cron.store`)中旧版任务形状,这些形状调度器仍为兼容性而接受。
|
||||
|
||||
当前 cron 清理包括:
|
||||
|
||||
@ -241,231 +238,189 @@ 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 传递模式结合使用,Doctor 会发出警告,并将该任务留待手动审查。
|
||||
|
||||
### 3c)会话锁清理
|
||||
### 3c) 会话锁清理
|
||||
|
||||
Doctor 会扫描每个智能体会话目录中的过期写锁文件——即会话异常退出后遗留的文件。对于发现的每个锁文件,它会报告:
|
||||
路径、PID、PID 是否仍存活、锁的年龄,以及它是否被视为过期(PID 已死亡或超过 30 分钟)。在 `--fix` / `--repair`
|
||||
模式下,它会自动删除过期锁文件;否则会打印说明,并指示你使用 `--fix` 重新运行。
|
||||
Doctor 会扫描每个智能体会话目录中的过时写锁文件 —— 这些文件是会话异常退出时残留的。对每个找到的锁文件,它会报告:
|
||||
路径、PID、PID 是否仍存活、锁龄,以及是否被视为过时(PID 已死或已超过 30 分钟)。在 `--fix` / `--repair`
|
||||
模式下,它会自动移除过时锁文件;否则它会打印说明,并指导你使用 `--fix` 重新运行。
|
||||
|
||||
### 4)状态完整性检查(会话持久化、路由和安全)
|
||||
### 4) 状态完整性检查(会话持久化、路由和安全)
|
||||
|
||||
状态目录是运行中的核心中枢。如果它消失了,你将失去
|
||||
会话、凭证、日志和配置(除非你在别处有备份)。
|
||||
状态目录是运行时的中枢神经。如果它消失了,你会丢失
|
||||
sessions、凭证、日志和配置(除非你在其他地方有备份)。
|
||||
|
||||
Doctor 会检查:
|
||||
|
||||
- **状态目录缺失**:警告灾难性的状态丢失,提示重新创建
|
||||
目录,并提醒你它无法恢复丢失的数据。
|
||||
- **状态目录权限**:验证可写性;提供修复权限选项
|
||||
(检测到所有者/组不匹配时会给出 `chown` 提示)。
|
||||
- **状态目录缺失**:警告灾难性的状态丢失,提示重新创建目录,并提醒你它无法恢复缺失数据。
|
||||
- **状态目录权限**:验证可写性;提供修复权限的选项
|
||||
(并在检测到 owner / group 不匹配时给出 `chown` 提示)。
|
||||
- **macOS 云同步状态目录**:当状态路径解析到 iCloud Drive
|
||||
(`~/Library/Mobile Documents/com~apple~CloudDocs/...`)或
|
||||
`~/Library/CloudStorage/...` 下时发出警告,因为由同步支持的路径可能导致更慢的 I/O
|
||||
和锁/同步竞争。
|
||||
- **Linux SD 或 eMMC 状态目录**:当状态路径解析到 `mmcblk*`
|
||||
挂载源时发出警告,因为基于 SD 或 eMMC 的随机 I/O 在会话和凭证写入下可能更慢且磨损更快。
|
||||
- **会话目录缺失**:`sessions/` 和会话存储目录是
|
||||
持久保存历史记录并避免 `ENOENT` 崩溃所必需的。
|
||||
- **转录不匹配**:当最近的会话条目缺少
|
||||
转录文件时发出警告。
|
||||
- **主会话“1 行 JSONL”**:当主转录文件只有一行时标记出来(历史没有持续累积)。
|
||||
- **多个状态目录**:当不同 home 目录下存在多个 `~/.openclaw` 文件夹,
|
||||
或 `OPENCLAW_STATE_DIR` 指向其他位置时发出警告(历史可能在多个安装之间分裂)。
|
||||
- **远程模式提醒**:如果 `gateway.mode=remote`,doctor 会提醒你在
|
||||
远程主机上运行它(状态存储在那里)。
|
||||
- **配置文件权限**:如果 `~/.openclaw/openclaw.json` 对
|
||||
组/所有人可读,则会发出警告并提供收紧到 `600` 的选项。
|
||||
`~/Library/CloudStorage/...` 下时发出警告,因为同步支持路径可能导致更慢的 I/O
|
||||
以及锁 / 同步竞争。
|
||||
- **Linux SD 或 eMMC 状态目录**:当状态路径解析为 `mmcblk*`
|
||||
挂载源时发出警告,因为由 SD 或 eMMC 支持的随机 I/O 在 session 和凭证写入下可能更慢且磨损更快。
|
||||
- **Session 目录缺失**:`sessions/` 和 session 存储目录是持久化历史记录并避免 `ENOENT` 崩溃所必需的。
|
||||
- **Transcript 不匹配**:当最近的 session 条目缺少 transcript 文件时发出警告。
|
||||
- **主 Session “单行 JSONL”**:当主 transcript 只有一行时标记出来(历史没有持续累积)。
|
||||
- **多个状态目录**:当不同 home 目录中存在多个 `~/.openclaw` 文件夹,或 `OPENCLAW_STATE_DIR` 指向其他位置时发出警告(历史可能会在不同安装之间拆分)。
|
||||
- **远程模式提醒**:如果 `gateway.mode=remote`,Doctor 会提醒你在远程主机上运行它(状态保存在那里)。
|
||||
- **配置文件权限**:如果 `~/.openclaw/openclaw.json`
|
||||
对组 / 所有人可读,会发出警告并提供收紧到 `600` 的选项。
|
||||
|
||||
### 5)模型认证健康状态(OAuth 过期)
|
||||
### 5) 模型认证健康状态(OAuth 过期)
|
||||
|
||||
Doctor 会检查认证存储中的 OAuth 配置文件,在令牌
|
||||
即将过期/已过期时发出警告,并在安全时进行刷新。如果 Anthropic
|
||||
OAuth/令牌配置文件已过期,它会建议使用 Anthropic API 密钥或旧版
|
||||
Doctor 会检查认证存储中的 OAuth 配置文件,在令牌即将过期 / 已过期时发出警告,并在安全时刷新它们。如果 Anthropic
|
||||
OAuth / 令牌配置文件已过时,它会建议使用 Anthropic API 密钥或
|
||||
Anthropic setup-token 路径。
|
||||
只有在交互式运行(TTY)时才会出现刷新提示;`--non-interactive`
|
||||
刷新提示仅在交互模式(TTY)下出现;`--non-interactive`
|
||||
会跳过刷新尝试。
|
||||
|
||||
Doctor 还会检测过时且已移除的 Anthropic Claude CLI 状态。如果旧的
|
||||
`anthropic:claude-cli` 凭证字节仍存在于 `auth-profiles.json` 中,
|
||||
doctor 会将其转换回 Anthropic 令牌/OAuth 配置文件,并重写过时的
|
||||
`claude-cli/...` 模型引用以及 `agents.defaults.cliBackends.claude-cli`。
|
||||
如果这些字节已不存在,doctor 会删除过时配置并输出恢复命令。
|
||||
Doctor 还会报告因以下原因而暂时不可用的认证配置文件:
|
||||
|
||||
Doctor 还会报告由于以下原因而暂时不可用的认证配置文件:
|
||||
- 短期冷却(限流 / 超时 / 认证失败)
|
||||
- 较长时间禁用(计费 / 额度失败)
|
||||
|
||||
- 短暂冷却(速率限制/超时/认证失败)
|
||||
- 较长时间禁用(计费/额度失败)
|
||||
### 6) Hooks 模型校验
|
||||
|
||||
### 6)Hooks 模型验证
|
||||
如果设置了 `hooks.gmail.model`,Doctor 会根据目录和 allowlist 校验模型引用,并在其无法解析或不被允许时发出警告。
|
||||
|
||||
如果设置了 `hooks.gmail.model`,doctor 会根据
|
||||
目录和 allowlist 验证该模型引用,并在无法解析或被禁止时发出警告。
|
||||
### 7) 沙箱镜像修复
|
||||
|
||||
### 7)沙箱镜像修复
|
||||
启用沙箱隔离时,Doctor 会检查 Docker 镜像,并在当前镜像缺失时提供构建或切换到旧版名称的选项。
|
||||
|
||||
启用沙箱隔离时,doctor 会检查 Docker 镜像,并在当前镜像缺失时提供构建或切换到旧版名称的选项。
|
||||
|
||||
### 7b)内置插件运行时依赖
|
||||
### 7b) 内置插件运行时依赖
|
||||
|
||||
Doctor 会验证内置插件运行时依赖(例如
|
||||
Discord 插件运行时包)是否存在于 OpenClaw 安装根目录中。
|
||||
如果有任何缺失,doctor 会报告这些包,并在
|
||||
如果有缺失,Doctor 会报告这些包,并在
|
||||
`openclaw doctor --fix` / `openclaw doctor --repair` 模式下安装它们。
|
||||
|
||||
### 8)Gateway 网关服务迁移和清理提示
|
||||
### 8) Gateway 网关服务迁移和清理提示
|
||||
|
||||
Doctor 会检测旧版 Gateway 网关服务(`launchd`/`systemd`/`schtasks`),
|
||||
Doctor 会检测旧版 Gateway 网关服务(launchd/systemd/schtasks),
|
||||
并提供移除它们以及使用当前 Gateway 网关端口安装 OpenClaw 服务的选项。
|
||||
它还可以扫描额外的类 Gateway 网关服务并输出清理提示。
|
||||
带有配置文件名称的 OpenClaw Gateway 网关服务被视为一等公民,不会
|
||||
被标记为“额外”。
|
||||
它还可以扫描额外的类似 Gateway 网关服务并打印清理提示。
|
||||
带 profile 名称的 OpenClaw Gateway 网关服务被视为一等公民,不会被标记为“额外”。
|
||||
|
||||
### 8b)启动 Matrix 迁移
|
||||
### 8b) 启动时 Matrix 迁移
|
||||
|
||||
当 Matrix 渠道账户存在待处理或可执行的旧版状态迁移时,
|
||||
doctor(在 `--fix` / `--repair` 模式下)会先创建迁移前快照,
|
||||
然后运行尽力而为的迁移步骤:旧版 Matrix 状态迁移和旧版
|
||||
加密状态准备。这两个步骤都不是致命的;错误会被记录,启动会继续进行。在只读模式下(`openclaw doctor` 不带 `--fix`)此检查会被完全跳过。
|
||||
Doctor(在 `--fix` / `--repair` 模式下)会先创建迁移前快照,
|
||||
然后运行尽力而为的迁移步骤:旧版 Matrix 状态迁移和旧版加密状态准备。这两步都不是致命的;错误会被记录,启动会继续进行。在只读模式下(不带 `--fix` 的 `openclaw doctor`),此检查会被完全跳过。
|
||||
|
||||
### 9)安全警告
|
||||
### 9) 安全警告
|
||||
|
||||
当某个提供商对私信开放但没有 allowlist,或
|
||||
当某个策略以危险方式配置时,doctor 会发出警告。
|
||||
当某个提供商对私信开放但没有 allowlist,或某项策略配置方式存在危险时,Doctor 会发出警告。
|
||||
|
||||
### 10)systemd linger(Linux)
|
||||
### 10) systemd linger(Linux)
|
||||
|
||||
如果作为 `systemd` 用户服务运行,doctor 会确保启用 lingering,以便
|
||||
Gateway 网关在注销后仍保持运行。
|
||||
如果作为 systemd 用户服务运行,Doctor 会确保启用了 lingering,这样 Gateway 网关在注销后仍能保持运行。
|
||||
|
||||
### 11)工作区状态(Skills、插件和旧版目录)
|
||||
### 11) 工作区状态(Skills、插件和旧版目录)
|
||||
|
||||
Doctor 会输出默认智能体的工作区状态摘要:
|
||||
Doctor 会打印默认智能体的工作区状态摘要:
|
||||
|
||||
- **Skills 状态**:统计可用、缺少要求和被 allowlist 阻止的 Skills 数量。
|
||||
- **旧版工作区目录**:当 `~/openclaw` 或其他旧版工作区目录
|
||||
与当前工作区并存时发出警告。
|
||||
- **插件状态**:统计已加载/已禁用/出错的插件;列出任意
|
||||
错误对应的插件 ID;报告 bundle 插件 capability。
|
||||
- **插件兼容性警告**:标记与
|
||||
当前运行时存在兼容性问题的插件。
|
||||
- **插件诊断**:展示由
|
||||
插件注册表在加载时发出的任何警告或错误。
|
||||
- **旧版工作区目录**:当 `~/openclaw` 或其他旧版工作区目录与当前工作区并存时发出警告。
|
||||
- **插件状态**:统计已加载 / 已禁用 / 出错的插件;列出所有错误对应的插件 ID;报告内置插件能力。
|
||||
- **插件兼容性警告**:标记与当前运行时存在兼容性问题的插件。
|
||||
- **插件诊断信息**:展示插件注册表在加载时发出的任何警告或错误。
|
||||
|
||||
### 11b)Bootstrap 文件大小
|
||||
### 11b) Bootstrap 文件大小
|
||||
|
||||
Doctor 会检查工作区 bootstrap 文件(例如 `AGENTS.md`、
|
||||
`CLAUDE.md` 或其他注入的上下文文件)是否接近或超过已配置的
|
||||
字符预算。它会报告每个文件的原始字符数与注入后字符数、截断
|
||||
百分比、截断原因(`max/file` 或 `max/total`),以及总注入
|
||||
字符数占总预算的比例。当文件被截断或接近限制时,doctor 会输出调优 `agents.defaults.bootstrapMaxChars`
|
||||
和 `agents.defaults.bootstrapTotalMaxChars` 的建议。
|
||||
`CLAUDE.md` 或其他注入的上下文文件)是否接近或超过已配置的字符预算。它会报告每个文件的原始字符数与注入字符数、截断百分比、截断原因(`max/file` 或 `max/total`),以及总注入字符数占总预算的比例。当文件被截断或接近上限时,Doctor 会打印关于调整 `agents.defaults.bootstrapMaxChars`
|
||||
和 `agents.defaults.bootstrapTotalMaxChars` 的提示。
|
||||
|
||||
### 11c)Shell 补全
|
||||
### 11c) Shell 补全
|
||||
|
||||
Doctor 会检查当前 shell
|
||||
(zsh、bash、fish 或 PowerShell)是否已安装 Tab 补全:
|
||||
|
||||
- 如果 shell 配置文件使用较慢的动态补全模式
|
||||
(`source <(openclaw completion ...)`),doctor 会将其升级为更快的
|
||||
缓存文件变体。
|
||||
- 如果补全已在配置文件中配置,但缓存文件缺失,
|
||||
doctor 会自动重新生成缓存。
|
||||
- 如果完全未配置补全,
|
||||
doctor 会提示安装它
|
||||
(仅交互模式;使用 `--non-interactive` 时跳过)。
|
||||
(`source <(openclaw completion ...)`),Doctor 会将其升级为更快的缓存文件变体。
|
||||
- 如果配置文件中已配置补全,但缓存文件缺失,
|
||||
Doctor 会自动重新生成缓存。
|
||||
- 如果根本未配置补全,Doctor 会提示安装它
|
||||
(仅交互模式;`--non-interactive` 时跳过)。
|
||||
|
||||
运行 `openclaw completion --write-state` 可手动重新生成缓存。
|
||||
|
||||
### 12)Gateway 网关认证检查(本地令牌)
|
||||
### 12) Gateway 网关认证检查(本地令牌)
|
||||
|
||||
Doctor 会检查本地 Gateway 网关令牌认证就绪情况。
|
||||
Doctor 会检查本地 Gateway 网关令牌认证的就绪状态。
|
||||
|
||||
- 如果令牌模式需要令牌但不存在令牌来源,doctor 会提供生成令牌的选项。
|
||||
- 如果 `gateway.auth.token` 由 SecretRef 管理但不可用,doctor 会发出警告,并且不会用明文覆盖它。
|
||||
- `openclaw doctor --generate-gateway-token` 仅会在未配置令牌 SecretRef 时强制生成。
|
||||
- 如果令牌模式需要令牌且没有令牌来源,Doctor 会提供生成令牌的选项。
|
||||
- 如果 `gateway.auth.token` 由 SecretRef 管理但不可用,Doctor 会发出警告,并且不会用明文覆盖它。
|
||||
- `openclaw doctor --generate-gateway-token` 仅在未配置令牌 SecretRef 时强制生成。
|
||||
|
||||
### 12b)只读且感知 SecretRef 的修复
|
||||
### 12b) 只读 SecretRef 感知修复
|
||||
|
||||
某些修复流程需要检查已配置的凭证,同时又不能削弱运行时快速失败行为。
|
||||
某些修复流程需要检查已配置凭证,而不削弱运行时快速失败行为。
|
||||
|
||||
- `openclaw doctor --fix` 现在使用与 status 系列命令相同的只读 SecretRef 摘要模型来执行有针对性的配置修复。
|
||||
- 示例:Telegram `allowFrom` / `groupAllowFrom` `@username` 修复会在可用时尝试使用已配置的机器人凭证。
|
||||
- 如果 Telegram 机器人令牌通过 SecretRef 配置,但在当前命令路径中不可用,doctor 会报告该凭证“已配置但不可用”,并跳过自动解析,而不是崩溃或误报令牌缺失。
|
||||
- `openclaw doctor --fix` 现在使用与 status 系列命令相同的只读 SecretRef 摘要模型,以执行定向配置修复。
|
||||
- 例如:Telegram `allowFrom` / `groupAllowFrom` 的 `@username` 修复会在可用时尝试使用已配置的 bot 凭证。
|
||||
- 如果 Telegram bot 令牌通过 SecretRef 配置,但在当前命令路径中不可用,Doctor 会报告该凭证为“已配置但不可用”,并跳过自动解析,而不是崩溃或错误地将令牌报告为缺失。
|
||||
|
||||
### 13)Gateway 网关健康检查 + 重启
|
||||
### 13) Gateway 网关健康检查 + 重启
|
||||
|
||||
Doctor 会运行健康检查,并在 Gateway 网关看起来
|
||||
不健康时提供重启选项。
|
||||
Doctor 会运行健康检查,并在 Gateway 网关看起来不健康时提供重启选项。
|
||||
|
||||
### 13b)内存搜索就绪情况
|
||||
### 13b) Memory search 就绪状态
|
||||
|
||||
Doctor 会检查为默认智能体配置的内存搜索嵌入提供商是否已就绪。
|
||||
行为取决于已配置的 backend 和 provider:
|
||||
Doctor 会检查默认智能体配置的 memory search embedding 提供商是否就绪。其行为取决于配置的后端和提供商:
|
||||
|
||||
- **QMD backend**:探测 `qmd` 二进制文件是否可用且可启动。
|
||||
如果不可用,会输出修复指导,包括 npm 包和手动二进制路径选项。
|
||||
- **显式本地 provider**:检查本地模型文件或可识别的
|
||||
远程/可下载模型 URL 是否存在。如果缺失,会建议切换到远程提供商。
|
||||
- **显式远程 provider**(`openai`、`voyage` 等):验证 API 密钥是否
|
||||
存在于环境或认证存储中。如果缺失,会输出可操作的修复提示。
|
||||
- **自动 provider**:先检查本地模型可用性,然后按自动选择顺序尝试每个远程
|
||||
provider。
|
||||
- **QMD 后端**:探测 `qmd` 二进制文件是否可用且可启动。
|
||||
如果不可用,会打印修复指引,包括 npm 包和手动二进制路径选项。
|
||||
- **显式本地提供商**:检查本地模型文件或可识别的远程 / 可下载模型 URL。
|
||||
如果缺失,会建议切换到远程提供商。
|
||||
- **显式远程提供商**(`openai`、`voyage` 等):验证环境中或认证存储中是否存在 API 密钥。若缺失,会打印可执行的修复提示。
|
||||
- **自动提供商**:先检查本地模型可用性,再按自动选择顺序尝试各个远程提供商。
|
||||
|
||||
当 Gateway 网关探测结果可用时(即检查时 Gateway 网关健康),doctor 会将其结果与 CLI 可见配置进行交叉比对,并注明
|
||||
任何差异。
|
||||
当 Gateway 网关探测结果可用时(检查时 Gateway 网关健康),Doctor 会将其结果与 CLI 可见配置交叉比对,并指出任何差异。
|
||||
|
||||
使用 `openclaw memory status --deep` 可在运行时验证嵌入就绪情况。
|
||||
使用 `openclaw memory status --deep` 可在运行时验证 embedding 就绪状态。
|
||||
|
||||
### 14)渠道状态警告
|
||||
### 14) 渠道状态警告
|
||||
|
||||
如果 Gateway 网关健康,doctor 会运行渠道状态探测,并报告
|
||||
带有建议修复方式的警告。
|
||||
如果 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 --force` 会覆盖自定义 supervisor 配置。
|
||||
- 如果令牌认证需要令牌,并且 `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` 强制完整重写。
|
||||
- 如果令牌认证需要令牌且 `gateway.auth.token` 由 SecretRef 管理,Doctor 在服务安装 / 修复时会校验 SecretRef,但不会把解析出的明文令牌值持久化到 supervisor 服务环境元数据中。
|
||||
- 如果令牌认证需要令牌且配置的令牌 SecretRef 未解析,Doctor 会阻止安装 / 修复路径,并提供可执行的指引。
|
||||
- 如果同时配置了 `gateway.auth.token` 和 `gateway.auth.password`,但未设置 `gateway.auth.mode`,Doctor 会阻止安装 / 修复,直到显式设置模式。
|
||||
- 对于 Linux user-systemd 单元,Doctor 的令牌漂移检查现在同时包括 `Environment=` 和 `EnvironmentFile=` 来源,以比较服务认证元数据。
|
||||
- 你始终可以通过 `openclaw gateway install --force` 强制执行完整重写。
|
||||
|
||||
### 16)Gateway 网关运行时 + 端口诊断
|
||||
### 16) Gateway 网关运行时 + 端口诊断
|
||||
|
||||
Doctor 会检查服务运行时(PID、上次退出状态),并在
|
||||
服务已安装但实际上未运行时发出警告。它还会检查
|
||||
Gateway 网关端口(默认 `18789`)上的端口冲突,并报告可能原因(Gateway 网关已在运行、SSH 隧道)。
|
||||
Doctor 会检查服务运行时(PID、上次退出状态),并在服务已安装但实际上未运行时发出警告。它还会检查 Gateway 网关端口(默认 `18789`)上的端口冲突,并报告可能原因(Gateway 网关已在运行、SSH 隧道)。
|
||||
|
||||
### 17)Gateway 网关运行时最佳实践
|
||||
### 17) Gateway 网关运行时最佳实践
|
||||
|
||||
当 Gateway 网关服务运行在 Bun 上,或运行在版本管理的 Node 路径
|
||||
(`nvm`、`fnm`、`volta`、`asdf` 等)上时,doctor 会发出警告。WhatsApp + Telegram 渠道需要 Node,
|
||||
而版本管理器路径可能会在升级后失效,因为服务不会
|
||||
加载你的 shell 初始化。Doctor 会在系统 Node 安装可用时提供迁移到它的选项(Homebrew/apt/choco)。
|
||||
当 Gateway 网关服务运行在 Bun 上,或使用版本管理的 Node 路径
|
||||
(`nvm`、`fnm`、`volta`、`asdf` 等)时,Doctor 会发出警告。WhatsApp + Telegram 渠道需要 Node,而版本管理器路径可能会在升级后失效,因为服务不会加载你的 shell init。Doctor 会在系统 Node 安装可用时提供迁移到该安装的选项(Homebrew / apt / choco)。
|
||||
|
||||
### 18)配置写入 + 向导元数据
|
||||
### 18) 配置写入 + 向导元数据
|
||||
|
||||
Doctor 会持久化任何配置更改,并写入向导元数据以记录此次
|
||||
doctor 运行。
|
||||
Doctor 会持久化所有配置变更,并写入向导元数据以记录此次 Doctor 运行。
|
||||
|
||||
### 19)工作区提示(备份 + 内存系统)
|
||||
### 19) 工作区提示(备份 + memory system)
|
||||
|
||||
Doctor 会在缺失时建议设置工作区内存系统,并在工作区尚未纳入 git 管理时输出备份提示。
|
||||
当工作区缺少 memory system 时,Doctor 会建议添加;如果工作区尚未纳入 git,它还会打印备份提示。
|
||||
|
||||
参见 [/concepts/agent-workspace](/zh-CN/concepts/agent-workspace),获取有关
|
||||
工作区结构和 git 备份(推荐使用私有 GitHub 或 GitLab)的完整指南。
|
||||
有关工作区结构和 git 备份(推荐使用私有 GitHub 或 GitLab)的完整指南,请参阅 [/concepts/agent-workspace](/zh-CN/concepts/agent-workspace)。
|
||||
|
||||
@ -4,29 +4,29 @@ read_when:
|
||||
summary: Gateway 网关服务、生命周期和运维的运行手册
|
||||
title: Gateway 网关运行手册
|
||||
x-i18n:
|
||||
generated_at: "2026-04-05T08:23:51Z"
|
||||
generated_at: "2026-04-06T15:28:29Z"
|
||||
model: gpt-5.4
|
||||
provider: openai
|
||||
source_hash: 0ec17674370de4e171779389c83580317308a4f07ebf335ad236a47238af18e1
|
||||
source_hash: fd2c21036e88612861ef2195b8ff7205aca31386bb11558614ade8d1a54fdebd
|
||||
source_path: gateway/index.md
|
||||
workflow: 15
|
||||
---
|
||||
|
||||
# Gateway 网关运行手册
|
||||
|
||||
使用本页处理 Gateway 网关服务的 day-1 启动和 day-2 运维。
|
||||
将此页面用于 Gateway 网关服务的首日启动和后续运维。
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="深度故障排除" icon="siren" href="/gateway/troubleshooting">
|
||||
按症状组织的诊断,包含精确的命令阶梯和日志特征。
|
||||
<Card title="深度故障排除" icon="siren" href="/zh-CN/gateway/troubleshooting">
|
||||
按症状优先的诊断,附带精确的命令步骤和日志特征。
|
||||
</Card>
|
||||
<Card title="配置" icon="sliders" href="/gateway/configuration">
|
||||
<Card title="配置" icon="sliders" href="/zh-CN/gateway/configuration">
|
||||
面向任务的设置指南 + 完整配置参考。
|
||||
</Card>
|
||||
<Card title="密钥管理" icon="key-round" href="/gateway/secrets">
|
||||
SecretRef 契约、运行时快照行为,以及迁移/重载操作。
|
||||
<Card title="密钥管理" icon="key-round" href="/zh-CN/gateway/secrets">
|
||||
SecretRef 合约、运行时快照行为,以及迁移/重载操作。
|
||||
</Card>
|
||||
<Card title="密钥计划契约" icon="shield-check" href="/gateway/secrets-plan-contract">
|
||||
<Card title="密钥计划合约" icon="shield-check" href="/zh-CN/gateway/secrets-plan-contract">
|
||||
精确的 `secrets apply` 目标/路径规则,以及仅 ref 的 auth-profile 行为。
|
||||
</Card>
|
||||
</CardGroup>
|
||||
@ -64,34 +64,33 @@ openclaw logs --follow
|
||||
openclaw channels status --probe
|
||||
```
|
||||
|
||||
当 Gateway 网关可访问时,这会运行按账户划分的实时渠道探测和可选审计。
|
||||
如果 Gateway 网关不可访问,CLI 会回退到仅基于配置的渠道摘要,而不是实时探测输出。
|
||||
当 Gateway 网关可达时,这会运行按账户划分的实时渠道探测和可选审计。
|
||||
如果 Gateway 网关不可达,CLI 会回退为仅基于配置的渠道摘要,而不是实时探测输出。
|
||||
|
||||
</Step>
|
||||
</Steps>
|
||||
|
||||
<Note>
|
||||
Gateway 网关配置重载会监视活动配置文件路径(从 profile/状态默认值解析,或在设置了 `OPENCLAW_CONFIG_PATH` 时使用它)。
|
||||
默认模式是 `gateway.reload.mode="hybrid"`。
|
||||
首次成功加载后,运行中的进程会提供活动的内存配置快照;成功重载会以原子方式替换该快照。
|
||||
Gateway 网关配置重载会监听活动配置文件路径(从 profile/state 默认值解析,或在设置了 `OPENCLAW_CONFIG_PATH` 时使用该值)。
|
||||
默认模式为 `gateway.reload.mode="hybrid"`。
|
||||
首次成功加载后,运行中的进程会提供当前内存中的活动配置快照;成功重载后会以原子方式替换该快照。
|
||||
</Note>
|
||||
|
||||
## 运行时模型
|
||||
|
||||
- 一个始终在线的进程,用于路由、控制平面和渠道连接。
|
||||
- 单个复用端口用于:
|
||||
- 一个复用的单端口,用于:
|
||||
- WebSocket 控制/RPC
|
||||
- HTTP API、OpenAI 兼容接口(`/v1/models`、`/v1/embeddings`、`/v1/chat/completions`、`/v1/responses`、`/tools/invoke`)
|
||||
- 控制 UI 和 hooks
|
||||
- HTTP API、与 OpenAI 兼容(`/v1/models`、`/v1/embeddings`、`/v1/chat/completions`、`/v1/responses`、`/tools/invoke`)
|
||||
- Control UI 和 hooks
|
||||
- 默认绑定模式:`loopback`。
|
||||
- 默认要求鉴权。共享密钥部署使用
|
||||
- 默认要求身份验证。共享密钥设置使用
|
||||
`gateway.auth.token` / `gateway.auth.password`(或
|
||||
`OPENCLAW_GATEWAY_TOKEN` / `OPENCLAW_GATEWAY_PASSWORD`),而非 loopback 的
|
||||
反向代理部署可使用 `gateway.auth.mode: "trusted-proxy"`。
|
||||
`OPENCLAW_GATEWAY_TOKEN` / `OPENCLAW_GATEWAY_PASSWORD`),非 loopback 的反向代理设置可以使用 `gateway.auth.mode: "trusted-proxy"`。
|
||||
|
||||
## OpenAI 兼容端点
|
||||
## 与 OpenAI 兼容的端点
|
||||
|
||||
OpenClaw 当前最有杠杆效应的兼容接口集是:
|
||||
OpenClaw 当前最有价值的兼容性接口是:
|
||||
|
||||
- `GET /v1/models`
|
||||
- `GET /v1/models/{id}`
|
||||
@ -99,34 +98,34 @@ OpenClaw 当前最有杠杆效应的兼容接口集是:
|
||||
- `POST /v1/chat/completions`
|
||||
- `POST /v1/responses`
|
||||
|
||||
为什么这组接口重要:
|
||||
为什么这组接口很重要:
|
||||
|
||||
- 大多数 Open WebUI、LobeChat 和 LibreChat 集成会首先探测 `/v1/models`。
|
||||
- 许多 RAG 和记忆流水线依赖 `/v1/embeddings`。
|
||||
- 原生智能体客户端越来越倾向于使用 `/v1/responses`。
|
||||
- 大多数 Open WebUI、LobeChat 和 LibreChat 集成都会先探测 `/v1/models`。
|
||||
- 许多 RAG 和记忆管道都依赖 `/v1/embeddings`。
|
||||
- 原生面向智能体的客户端越来越倾向于使用 `/v1/responses`。
|
||||
|
||||
规划说明:
|
||||
|
||||
- `/v1/models` 是智能体优先的:它返回 `openclaw`、`openclaw/default` 和 `openclaw/<agentId>`。
|
||||
- `openclaw/default` 是稳定别名,始终映射到配置的默认智能体。
|
||||
- 当你想覆盖后端 provider/model 时,请使用 `x-openclaw-model`;否则所选智能体的常规模型和嵌入设置仍将保持控制。
|
||||
- `/v1/models` 以智能体优先:它会返回 `openclaw`、`openclaw/default` 和 `openclaw/<agentId>`。
|
||||
- `openclaw/default` 是稳定别名,始终映射到已配置的默认智能体。
|
||||
- 当你想覆盖后端提供商/模型时,请使用 `x-openclaw-model`;否则,选定智能体的常规模型和嵌入设置仍然会保持控制权。
|
||||
|
||||
所有这些都运行在主 Gateway 网关端口上,并使用与 Gateway 网关其余 HTTP API 相同的受信任操作员鉴权边界。
|
||||
所有这些都运行在主 Gateway 网关端口上,并与 Gateway 网关其余 HTTP API 共享同一个受信任操作员身份验证边界。
|
||||
|
||||
### 端口和绑定优先级
|
||||
|
||||
| Setting | 解析顺序 |
|
||||
| ------------ | ----------------------------------------------------- |
|
||||
| Gateway port | `--port` → `OPENCLAW_GATEWAY_PORT` → `gateway.port` → `18789` |
|
||||
| Bind mode | CLI/覆盖值 → `gateway.bind` → `loopback` |
|
||||
| 设置 | 解析顺序 |
|
||||
| ------------ | ------------------------------------------------------------- |
|
||||
| Gateway 网关端口 | `--port` → `OPENCLAW_GATEWAY_PORT` → `gateway.port` → `18789` |
|
||||
| 绑定模式 | CLI/override → `gateway.bind` → `loopback` |
|
||||
|
||||
### 热重载模式
|
||||
|
||||
| `gateway.reload.mode` | 行为 |
|
||||
| --------------------- | -------------------------------------- |
|
||||
| `off` | 不重载配置 |
|
||||
| `hot` | 仅应用热安全更改 |
|
||||
| `restart` | 遇到需要重启的更改时重启 |
|
||||
| `gateway.reload.mode` | 行为 |
|
||||
| --------------------- | ------------------------------------------ |
|
||||
| `off` | 不进行配置重载 |
|
||||
| `hot` | 仅应用热安全变更 |
|
||||
| `restart` | 遇到需要重载的变更时重启 |
|
||||
| `hybrid`(默认) | 安全时热应用,需要时重启 |
|
||||
|
||||
## 操作员命令集
|
||||
@ -143,36 +142,36 @@ openclaw logs --follow
|
||||
openclaw doctor
|
||||
```
|
||||
|
||||
`gateway status --deep` 用于额外的服务发现(LaunchDaemons/systemd system
|
||||
units/schtasks),而不是更深层的 RPC 健康探测。
|
||||
`gateway status --deep` 用于额外的服务发现(LaunchDaemons/systemd 系统
|
||||
单元/schtasks),而不是更深入的 RPC 健康探测。
|
||||
|
||||
## 多个 Gateway 网关(同一主机)
|
||||
|
||||
大多数安装应每台机器运行一个 Gateway 网关。单个 Gateway 网关可以托管多个
|
||||
大多数安装应当每台机器运行一个 Gateway 网关。单个 Gateway 网关可以托管多个
|
||||
智能体和渠道。
|
||||
|
||||
只有当你明确需要隔离或救援机器人时,才需要多个 Gateway 网关。
|
||||
只有当你有意需要隔离或救援机器人时,才需要多个 Gateway 网关。
|
||||
|
||||
实用检查:
|
||||
有用的检查:
|
||||
|
||||
```bash
|
||||
openclaw gateway status --deep
|
||||
openclaw gateway probe
|
||||
```
|
||||
|
||||
预期行为:
|
||||
预期结果:
|
||||
|
||||
- `gateway status --deep` 可能报告 `Other gateway-like services detected (best effort)`
|
||||
并在仍存在陈旧 launchd/systemd/schtasks 安装时打印清理提示。
|
||||
- 当多个目标都有响应时,`gateway probe` 可能警告 `multiple reachable gateways`。
|
||||
- 如果这是有意为之,请为每个 Gateway 网关隔离端口、配置/状态和工作区根目录。
|
||||
- `gateway status --deep` 可能会报告 `Other gateway-like services detected (best effort)`
|
||||
并在仍然存在陈旧的 launchd/systemd/schtasks 安装时打印清理提示。
|
||||
- 当有多个目标响应时,`gateway probe` 可能会警告 `multiple reachable gateways`。
|
||||
- 如果这是有意的,请为每个 Gateway 网关隔离端口、配置/state 和工作区根目录。
|
||||
|
||||
详细设置:[/gateway/multiple-gateways](/gateway/multiple-gateways)。
|
||||
详细设置:[/gateway/multiple-gateways](/zh-CN/gateway/multiple-gateways)。
|
||||
|
||||
## 远程访问
|
||||
|
||||
首选:Tailscale/VPN。
|
||||
回退:SSH 隧道。
|
||||
备选:SSH 隧道。
|
||||
|
||||
```bash
|
||||
ssh -N -L 18789:127.0.0.1:18789 user@host
|
||||
@ -181,16 +180,15 @@ ssh -N -L 18789:127.0.0.1:18789 user@host
|
||||
然后在本地将客户端连接到 `ws://127.0.0.1:18789`。
|
||||
|
||||
<Warning>
|
||||
SSH 隧道不会绕过 Gateway 网关鉴权。对于共享密钥鉴权,客户端即使通过隧道
|
||||
仍然必须发送 `token`/`password`。对于带身份模式,
|
||||
请求仍然必须满足该鉴权路径。
|
||||
SSH 隧道不会绕过 Gateway 网关身份验证。对于共享密钥身份验证,即使通过隧道,客户端仍然
|
||||
必须发送 `token`/`password`。对于带身份模式,请求仍然必须满足该身份验证路径。
|
||||
</Warning>
|
||||
|
||||
参见:[Remote Gateway](/gateway/remote)、[Authentication](/gateway/authentication)、[Tailscale](/gateway/tailscale)。
|
||||
参见:[Remote Gateway](/zh-CN/gateway/remote)、[Authentication](/zh-CN/gateway/authentication)、[Tailscale](/zh-CN/gateway/tailscale)。
|
||||
|
||||
## 监管和服务生命周期
|
||||
## 监督与服务生命周期
|
||||
|
||||
对于接近生产环境的可靠性,请使用受监管运行。
|
||||
对于接近生产环境的可靠性,请使用受监督的运行方式。
|
||||
|
||||
<Tabs>
|
||||
<Tab title="macOS(launchd)">
|
||||
@ -202,11 +200,11 @@ openclaw gateway restart
|
||||
openclaw gateway stop
|
||||
```
|
||||
|
||||
LaunchAgent 标签为 `ai.openclaw.gateway`(默认)或 `ai.openclaw.<profile>`(命名 profile)。`openclaw doctor` 会审计并修复服务配置漂移。
|
||||
LaunchAgent 标签是 `ai.openclaw.gateway`(默认)或 `ai.openclaw.<profile>`(命名 profile)。`openclaw doctor` 会审计并修复服务配置漂移。
|
||||
|
||||
</Tab>
|
||||
|
||||
<Tab title="Linux(systemd user)">
|
||||
<Tab title="Linux(systemd 用户服务)">
|
||||
|
||||
```bash
|
||||
openclaw gateway install
|
||||
@ -214,13 +212,13 @@ systemctl --user enable --now openclaw-gateway[-<profile>].service
|
||||
openclaw gateway status
|
||||
```
|
||||
|
||||
如需在注销后持续运行,请启用 lingering:
|
||||
要在注销后继续持久运行,请启用 lingering:
|
||||
|
||||
```bash
|
||||
sudo loginctl enable-linger <user>
|
||||
```
|
||||
|
||||
当你需要自定义安装路径时,可使用手动 user unit 示例:
|
||||
当你需要自定义安装路径时,可使用以下手动用户单元示例:
|
||||
|
||||
```ini
|
||||
[Unit]
|
||||
@ -253,30 +251,30 @@ openclaw gateway stop
|
||||
```
|
||||
|
||||
原生 Windows 托管启动使用名为 `OpenClaw Gateway`
|
||||
的 Scheduled Task(命名 profile 时为 `OpenClaw Gateway (<profile>)`)。如果创建 Scheduled Task
|
||||
被拒绝,OpenClaw 会回退到按用户的 Startup 文件夹启动器,该启动器指向状态目录中的 `gateway.cmd`。
|
||||
的计划任务(命名 profile 则为 `OpenClaw Gateway (<profile>)`)。如果计划任务
|
||||
创建被拒绝,OpenClaw 会回退到每用户 Startup 文件夹启动器,该启动器指向 state 目录中的 `gateway.cmd`。
|
||||
|
||||
</Tab>
|
||||
|
||||
<Tab title="Linux(系统服务)">
|
||||
|
||||
对于多用户/始终在线主机,请使用 system unit。
|
||||
对多用户/始终在线的主机,请使用系统单元。
|
||||
|
||||
```bash
|
||||
sudo systemctl daemon-reload
|
||||
sudo systemctl enable --now openclaw-gateway[-<profile>].service
|
||||
```
|
||||
|
||||
使用与 user unit 相同的服务主体,但将其安装到
|
||||
`/etc/systemd/system/openclaw-gateway[-<profile>].service` 下,并在
|
||||
你的 `openclaw` 二进制文件位于其他位置时调整 `ExecStart=`。
|
||||
使用与用户单元相同的服务主体,但将其安装到
|
||||
`/etc/systemd/system/openclaw-gateway[-<profile>].service` 下,并在你的 `openclaw` 二进制位于其他位置时调整
|
||||
`ExecStart=`。
|
||||
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
## 一台主机上的多个 Gateway 网关
|
||||
|
||||
大多数部署应只运行**一个** Gateway 网关。
|
||||
大多数设置应该只运行**一个** Gateway 网关。
|
||||
只有在需要严格隔离/冗余时才使用多个(例如救援 profile)。
|
||||
|
||||
每个实例的检查清单:
|
||||
@ -293,7 +291,7 @@ OPENCLAW_CONFIG_PATH=~/.openclaw/a.json OPENCLAW_STATE_DIR=~/.openclaw-a opencla
|
||||
OPENCLAW_CONFIG_PATH=~/.openclaw/b.json OPENCLAW_STATE_DIR=~/.openclaw-b openclaw gateway --port 19002
|
||||
```
|
||||
|
||||
参见:[多个 Gateway 网关](/gateway/multiple-gateways)。
|
||||
参见:[Multiple gateways](/zh-CN/gateway/multiple-gateways)。
|
||||
|
||||
### 开发 profile 快速路径
|
||||
|
||||
@ -303,25 +301,25 @@ openclaw --dev gateway --allow-unconfigured
|
||||
openclaw --dev status
|
||||
```
|
||||
|
||||
默认值包括隔离的状态/配置以及基础 Gateway 网关端口 `19001`。
|
||||
默认值包括隔离的 state/config 和基础 Gateway 网关端口 `19001`。
|
||||
|
||||
## 协议快速参考(操作员视角)
|
||||
|
||||
- 客户端第一帧必须是 `connect`。
|
||||
- 第一个客户端帧必须是 `connect`。
|
||||
- Gateway 网关返回 `hello-ok` 快照(`presence`、`health`、`stateVersion`、`uptimeMs`、limits/policy)。
|
||||
- `hello-ok.features.methods` / `events` 是保守的发现列表,而不是
|
||||
所有可调用辅助路由的自动生成清单。
|
||||
对每个可调用辅助路由的自动生成完整导出。
|
||||
- 请求:`req(method, params)` → `res(ok/payload|error)`。
|
||||
- 常见事件包括 `connect.challenge`、`agent`、`chat`、
|
||||
`session.message`、`session.tool`、`sessions.changed`、`presence`、`tick`、
|
||||
`health`、`heartbeat`、配对/批准生命周期事件,以及 `shutdown`。
|
||||
`health`、`heartbeat`、配对/审批生命周期事件,以及 `shutdown`。
|
||||
|
||||
智能体运行分两阶段:
|
||||
智能体运行分两个阶段:
|
||||
|
||||
1. 立即接受确认(`status:"accepted"`)
|
||||
2. 最终完成响应(`status:"ok"|"error"`),期间会穿插流式 `agent` 事件。
|
||||
2. 最终完成响应(`status:"ok"|"error"`),中间会流式发送 `agent` 事件。
|
||||
|
||||
完整协议文档见:[Gateway Protocol](/gateway/protocol)。
|
||||
完整协议文档参见:[Gateway Protocol](/zh-CN/gateway/protocol)。
|
||||
|
||||
## 运维检查
|
||||
|
||||
@ -330,7 +328,7 @@ openclaw --dev status
|
||||
- 打开 WS 并发送 `connect`。
|
||||
- 预期收到带快照的 `hello-ok` 响应。
|
||||
|
||||
### 就绪状态
|
||||
### 就绪性
|
||||
|
||||
```bash
|
||||
openclaw gateway status
|
||||
@ -340,32 +338,32 @@ openclaw health
|
||||
|
||||
### 间隙恢复
|
||||
|
||||
事件不会重放。若出现序列间隙,请先刷新状态(`health`、`system-presence`),然后再继续。
|
||||
事件不会重放。遇到序列缺口时,请先刷新状态(`health`、`system-presence`)再继续。
|
||||
|
||||
## 常见故障特征
|
||||
|
||||
| Signature | Likely issue |
|
||||
| 特征 | 可能问题 |
|
||||
| -------------------------------------------------------------- | ------------------------------------------------------------------------------- |
|
||||
| `refusing to bind gateway ... without auth` | 非 loopback 绑定但没有有效的 Gateway 网关鉴权路径 |
|
||||
| `another gateway instance is already listening` / `EADDRINUSE` | 端口冲突 |
|
||||
| `Gateway start blocked: set gateway.mode=local` | 配置被设为远程模式,或受损配置中缺少本地模式标记 |
|
||||
| `unauthorized` during connect | 客户端与 Gateway 网关之间的鉴权不匹配 |
|
||||
| `refusing to bind gateway ... without auth` | 非 loopback 绑定且没有有效的 Gateway 网关身份验证路径 |
|
||||
| `another gateway instance is already listening` / `EADDRINUSE` | 端口冲突 |
|
||||
| `Gateway start blocked: set gateway.mode=local` | 配置被设为远程模式,或损坏配置中缺少本地模式标记 |
|
||||
| `unauthorized` during connect | 客户端与 Gateway 网关之间的身份验证不匹配 |
|
||||
|
||||
如需完整诊断阶梯,请使用 [Gateway 故障排除](/gateway/troubleshooting)。
|
||||
如需完整诊断步骤,请使用 [Gateway 故障排除](/zh-CN/gateway/troubleshooting)。
|
||||
|
||||
## 安全保证
|
||||
|
||||
- 当 Gateway 网关不可用时,Gateway protocol 客户端会快速失败(不会隐式回退到直连渠道)。
|
||||
- 非法/非 connect 的首帧会被拒绝并关闭连接。
|
||||
- 优雅关闭会在 socket 关闭前发出 `shutdown` 事件。
|
||||
- 当 Gateway 网关不可用时,Gateway 网关协议客户端会快速失败(不会隐式回退到直接渠道)。
|
||||
- 无效的首帧或非 `connect` 首帧会被拒绝并关闭连接。
|
||||
- 优雅关闭会在 socket 关闭前发送 `shutdown` 事件。
|
||||
|
||||
---
|
||||
|
||||
相关内容:
|
||||
|
||||
- [故障排除](/gateway/troubleshooting)
|
||||
- [后台进程](/gateway/background-process)
|
||||
- [配置](/gateway/configuration)
|
||||
- [健康状态](/gateway/health)
|
||||
- [Doctor](/gateway/doctor)
|
||||
- [鉴权](/gateway/authentication)
|
||||
- [故障排除](/zh-CN/gateway/troubleshooting)
|
||||
- [后台进程](/zh-CN/gateway/background-process)
|
||||
- [配置](/zh-CN/gateway/configuration)
|
||||
- [健康状态](/zh-CN/gateway/health)
|
||||
- [Doctor](/zh-CN/gateway/doctor)
|
||||
- [身份验证](/zh-CN/gateway/authentication)
|
||||
|
||||
@ -1,22 +1,22 @@
|
||||
---
|
||||
read_when:
|
||||
- 故障排除中心将你引导到这里进行更深入的诊断
|
||||
- 你需要带有精确命令的稳定、按症状分类的操作手册章节
|
||||
summary: 针对 Gateway 网关、渠道、自动化、节点和浏览器的深入故障排除操作手册
|
||||
- 故障排除中心将你引导到这里以进行更深入的诊断
|
||||
- 你需要按症状组织且带有精确命令的稳定操作手册章节
|
||||
summary: 针对 Gateway 网关、渠道、自动化、节点和浏览器的深度故障排除操作手册
|
||||
title: 故障排除
|
||||
x-i18n:
|
||||
generated_at: "2026-04-05T08:25:42Z"
|
||||
generated_at: "2026-04-06T15:28:55Z"
|
||||
model: gpt-5.4
|
||||
provider: openai
|
||||
source_hash: 028226726e6adc45ca61d41510a953c4e21a3e85f3082af9e8085745c6ac3ec1
|
||||
source_hash: e0202e8858310a0bfc1c994cd37b01c3b2d6c73c8a74740094e92dc3c4c36729
|
||||
source_path: gateway/troubleshooting.md
|
||||
workflow: 15
|
||||
---
|
||||
|
||||
# Gateway 网关故障排除
|
||||
|
||||
本页面是深入操作手册。
|
||||
如果你想先走快速分诊流程,请从 [/help/troubleshooting](/help/troubleshooting) 开始。
|
||||
本页是深度操作手册。
|
||||
如果你想先使用快速分诊流程,请先从 [/help/troubleshooting](/zh-CN/help/troubleshooting) 开始。
|
||||
|
||||
## 命令阶梯
|
||||
|
||||
@ -34,11 +34,11 @@ openclaw channels status --probe
|
||||
|
||||
- `openclaw gateway status` 显示 `Runtime: running` 和 `RPC probe: ok`。
|
||||
- `openclaw doctor` 报告没有阻塞性的配置/服务问题。
|
||||
- `openclaw channels status --probe` 显示实时的逐账号传输状态,并且在支持的情况下显示探测/审计结果,例如 `works` 或 `audit ok`。
|
||||
- `openclaw channels status --probe` 显示每个账号的实时传输状态,并在支持的情况下显示探测/审计结果,例如 `works` 或 `audit ok`。
|
||||
|
||||
## Anthropic 429 需要额外用量以支持长上下文
|
||||
## Anthropic 429:长上下文需要额外用量权限
|
||||
|
||||
当日志/错误中包含以下内容时使用本节:
|
||||
当日志/错误中包含以下内容时,请使用本节:
|
||||
`HTTP 429: rate_limit_error: Extra usage is required for long context requests`。
|
||||
|
||||
```bash
|
||||
@ -47,27 +47,27 @@ openclaw models status
|
||||
openclaw config get agents.defaults.models
|
||||
```
|
||||
|
||||
检查:
|
||||
检查以下内容:
|
||||
|
||||
- 选中的 Anthropic Opus/Sonnet 模型启用了 `params.context1m: true`。
|
||||
- 当前的 Anthropic 凭证不具备长上下文用量资格。
|
||||
- 请求仅在需要 1M beta 路径的长会话/模型运行中失败。
|
||||
- 选定的 Anthropic Opus/Sonnet 模型设置了 `params.context1m: true`。
|
||||
- 当前的 Anthropic 凭证没有长上下文用量资格。
|
||||
- 请求只会在需要走 1M beta 路径的长会话/模型运行中失败。
|
||||
|
||||
修复选项:
|
||||
|
||||
1. 为该模型禁用 `context1m`,回退到普通上下文窗口。
|
||||
2. 使用带计费的 Anthropic API key,或在 Anthropic OAuth/订阅账号上启用 Anthropic Extra Usage。
|
||||
2. 使用有资格发起长上下文请求的 Anthropic 凭证,或切换为 Anthropic API key。
|
||||
3. 配置回退模型,以便在 Anthropic 长上下文请求被拒绝时,运行仍可继续。
|
||||
|
||||
相关内容:
|
||||
|
||||
- [/providers/anthropic](/providers/anthropic)
|
||||
- [/reference/token-use](/reference/token-use)
|
||||
- [/help/faq#why-am-i-seeing-http-429-ratelimiterror-from-anthropic](/help/faq#why-am-i-seeing-http-429-ratelimiterror-from-anthropic)
|
||||
- [/providers/anthropic](/zh-CN/providers/anthropic)
|
||||
- [/reference/token-use](/zh-CN/reference/token-use)
|
||||
- [/help/faq#why-am-i-seeing-http-429-ratelimiterror-from-anthropic](/zh-CN/help/faq#why-am-i-seeing-http-429-ratelimiterror-from-anthropic)
|
||||
|
||||
## 没有回复
|
||||
|
||||
如果渠道已连接但没有任何响应,请在重新连接任何内容之前先检查路由和策略。
|
||||
如果渠道已连通但没有任何响应,在重新连接任何内容之前,请先检查路由和策略。
|
||||
|
||||
```bash
|
||||
openclaw status
|
||||
@ -77,27 +77,27 @@ openclaw config get channels
|
||||
openclaw logs --follow
|
||||
```
|
||||
|
||||
检查:
|
||||
检查以下内容:
|
||||
|
||||
- 私信发送者是否仍在等待配对批准。
|
||||
- 私信发送者的配对是否仍在等待中。
|
||||
- 群组提及门控(`requireMention`、`mentionPatterns`)。
|
||||
- 渠道/群组允许列表是否不匹配。
|
||||
|
||||
常见特征:
|
||||
|
||||
- `drop guild message (mention required` → 群组消息被忽略,直到出现提及。
|
||||
- `drop guild message (mention required` → 群组消息会被忽略,直到出现提及。
|
||||
- `pairing request` → 发送者需要批准。
|
||||
- `blocked` / `allowlist` → 发送者/渠道被策略过滤。
|
||||
|
||||
相关内容:
|
||||
|
||||
- [/channels/troubleshooting](/channels/troubleshooting)
|
||||
- [/channels/pairing](/channels/pairing)
|
||||
- [/channels/groups](/channels/groups)
|
||||
- [/channels/troubleshooting](/zh-CN/channels/troubleshooting)
|
||||
- [/channels/pairing](/zh-CN/channels/pairing)
|
||||
- [/channels/groups](/zh-CN/channels/groups)
|
||||
|
||||
## Dashboard Control UI 连接问题
|
||||
## 仪表板 Control UI 连接问题
|
||||
|
||||
当 dashboard/Control UI 无法连接时,请验证 URL、认证模式和安全上下文假设。
|
||||
当仪表板/Control UI 无法连接时,请验证 URL、认证模式和安全上下文假设。
|
||||
|
||||
```bash
|
||||
openclaw gateway status
|
||||
@ -107,45 +107,36 @@ openclaw doctor
|
||||
openclaw gateway status --json
|
||||
```
|
||||
|
||||
检查:
|
||||
检查以下内容:
|
||||
|
||||
- 正确的探测 URL 和 dashboard URL。
|
||||
- 正确的探测 URL 和仪表板 URL。
|
||||
- 客户端与 Gateway 网关之间的认证模式/token 是否不匹配。
|
||||
- 是否在需要设备身份的场景下使用了 HTTP。
|
||||
- 在需要设备身份时是否仍在使用 HTTP。
|
||||
|
||||
常见特征:
|
||||
|
||||
- `device identity required` → 非安全上下文或缺少设备认证。
|
||||
- `origin not allowed` → 浏览器 `Origin` 不在 `gateway.controlUi.allowedOrigins` 中
|
||||
(或者你正从非 loopback 浏览器 origin 连接,但未显式
|
||||
添加允许列表)。
|
||||
- `device nonce required` / `device nonce mismatch` → 客户端未完成
|
||||
基于 challenge 的设备认证流程(`connect.challenge` + `device.nonce`)。
|
||||
- `device signature invalid` / `device signature expired` → 客户端为当前握手签署了错误的
|
||||
负载(或使用了过期时间戳)。
|
||||
- 带有 `canRetryWithDeviceToken=true` 的 `AUTH_TOKEN_MISMATCH` → 客户端可以使用缓存设备 token 进行一次可信重试。
|
||||
- 该缓存 token 重试会复用与已配对
|
||||
设备 token 一起存储的缓存作用域集合。显式 `deviceToken` / 显式 `scopes` 调用方则保留其
|
||||
请求的作用域集合。
|
||||
- 除该重试路径外,连接认证优先级依次为:显式共享
|
||||
token/password、显式 `deviceToken`、存储的设备 token、
|
||||
引导 token。
|
||||
- 在异步 Tailscale Serve Control UI 路径上,同一
|
||||
`{scope, ip}` 的失败尝试会在限流器记录失败之前串行化。因此,同一客户端的两个错误并发重试,第二次尝试可能显示 `retry later`,而不是两个普通的不匹配错误。
|
||||
- 来自浏览器 origin loopback 客户端的 `too many failed authentication attempts (retry later)` → 来自同一规范化 `Origin` 的重复失败会被暂时锁定;另一个 localhost origin 会使用单独的桶。
|
||||
- 在该重试之后重复出现 `unauthorized` → 共享 token/设备 token 漂移;请刷新 token 配置,并在需要时重新批准/轮换设备 token。
|
||||
- `gateway connect failed:` → host/port/url 目标错误。
|
||||
- `origin not allowed` → 浏览器 `Origin` 不在 `gateway.controlUi.allowedOrigins` 中(或者你正从非 loopback 的浏览器 origin 连接,但没有显式允许列表)。
|
||||
- `device nonce required` / `device nonce mismatch` → 客户端没有完成基于挑战的设备认证流程(`connect.challenge` + `device.nonce`)。
|
||||
- `device signature invalid` / `device signature expired` → 客户端为当前握手签署了错误的负载(或使用了过期时间戳)。
|
||||
- `AUTH_TOKEN_MISMATCH` 且 `canRetryWithDeviceToken=true` → 客户端可以使用缓存的设备 token 执行一次受信任重试。
|
||||
- 该缓存 token 重试会复用与已配对设备 token 一起存储的缓存 scope 集合。显式 `deviceToken` / 显式 `scopes` 调用方则会保留自己请求的 scope 集合。
|
||||
- 除该重试路径外,连接认证优先级依次为:显式共享 token/password、然后显式 `deviceToken`、然后存储的设备 token、最后是引导 token。
|
||||
- 在异步 Tailscale Serve Control UI 路径上,同一 `{scope, ip}` 的失败尝试会在限流器记录失败之前串行化。因此,同一客户端的两个错误并发重试,第二次可能会显示 `retry later`,而不是两个普通的不匹配。
|
||||
- 来自浏览器 origin loopback 客户端的 `too many failed authentication attempts (retry later)` → 来自同一归一化 `Origin` 的重复失败会被临时锁定;另一个 localhost origin 会使用独立的桶。
|
||||
- 在那次重试后仍反复出现 `unauthorized` → 共享 token/设备 token 已漂移;如有需要,请刷新 token 配置并重新批准/轮换设备 token。
|
||||
- `gateway connect failed:` → 主机/端口/url 目标错误。
|
||||
|
||||
### 认证详情代码速查表
|
||||
|
||||
使用失败 `connect` 响应中的 `error.details.code` 来选择下一步操作:
|
||||
使用失败的 `connect` 响应中的 `error.details.code` 来选择下一步操作:
|
||||
|
||||
| Detail code | 含义 | 建议操作 |
|
||||
| ---------------------------- | ---- | -------- |
|
||||
| `AUTH_TOKEN_MISSING` | 客户端未发送所需的共享 token。 | 在客户端中粘贴/设置 token 后重试。对于 dashboard 路径:运行 `openclaw config get gateway.auth.token`,然后粘贴到 Control UI 设置中。 |
|
||||
| `AUTH_TOKEN_MISMATCH` | 共享 token 与 Gateway 网关认证 token 不匹配。 | 如果 `canRetryWithDeviceToken=true`,允许一次可信重试。缓存 token 重试会复用已存储的批准作用域;显式 `deviceToken` / `scopes` 调用方保留所请求的作用域。如果仍失败,请运行 [令牌漂移恢复清单](/cli/devices#token-drift-recovery-checklist)。 |
|
||||
| `AUTH_DEVICE_TOKEN_MISMATCH` | 缓存的每设备 token 已过期或被撤销。 | 使用 [devices CLI](/cli/devices) 轮换/重新批准设备 token,然后重新连接。 |
|
||||
| `PAIRING_REQUIRED` | 设备身份已知,但尚未针对该角色获得批准。 | 批准待处理请求:`openclaw devices list` 然后执行 `openclaw devices approve <requestId>`。 |
|
||||
| 详情代码 | 含义 | 建议操作 |
|
||||
| ---------------------------- | -------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `AUTH_TOKEN_MISSING` | 客户端没有发送所需的共享 token。 | 在客户端中粘贴/设置 token 后重试。对于仪表板路径:`openclaw config get gateway.auth.token`,然后将其粘贴到 Control UI 设置中。 |
|
||||
| `AUTH_TOKEN_MISMATCH` | 共享 token 与 Gateway 网关认证 token 不匹配。 | 如果 `canRetryWithDeviceToken=true`,允许一次受信任重试。缓存 token 重试会复用已存储且批准的 scopes;显式 `deviceToken` / `scopes` 调用方保留请求的 scopes。如果仍失败,请运行 [token 漂移恢复检查清单](/cli/devices#token-drift-recovery-checklist)。 |
|
||||
| `AUTH_DEVICE_TOKEN_MISMATCH` | 缓存的按设备 token 已过期或被撤销。 | 使用 [devices CLI](/cli/devices) 轮换/重新批准设备 token,然后重新连接。 |
|
||||
| `PAIRING_REQUIRED` | 设备身份已知,但尚未为此角色批准。 | 批准待处理请求:`openclaw devices list`,然后 `openclaw devices approve <requestId>`。 |
|
||||
|
||||
设备认证 v2 迁移检查:
|
||||
|
||||
@ -155,30 +146,28 @@ openclaw doctor
|
||||
openclaw gateway status
|
||||
```
|
||||
|
||||
如果日志显示 nonce/signature 错误,请更新正在连接的客户端并验证它:
|
||||
如果日志显示 nonce/signature 错误,请更新正在连接的客户端,并确认它:
|
||||
|
||||
1. 等待 `connect.challenge`
|
||||
2. 对绑定 challenge 的负载进行签名
|
||||
2. 对绑定该 challenge 的负载进行签名
|
||||
3. 使用相同的 challenge nonce 发送 `connect.params.device.nonce`
|
||||
|
||||
如果 `openclaw devices rotate` / `revoke` / `remove` 被意外拒绝:
|
||||
|
||||
- 已配对设备 token 会话只能管理**自己的**设备,除非
|
||||
调用方还具有 `operator.admin`
|
||||
- `openclaw devices rotate --scope ...` 只能请求
|
||||
调用方当前会话已拥有的 operator 作用域
|
||||
- 已配对设备 token 会话只能管理**它们自己的**设备,除非调用方还拥有 `operator.admin`
|
||||
- `openclaw devices rotate --scope ...` 只能请求调用方会话已持有的 operator scopes
|
||||
|
||||
相关内容:
|
||||
|
||||
- [/web/control-ui](/web/control-ui)
|
||||
- [/gateway/configuration](/gateway/configuration)(gateway 认证模式)
|
||||
- [/gateway/trusted-proxy-auth](/gateway/trusted-proxy-auth)
|
||||
- [/gateway/remote](/gateway/remote)
|
||||
- [/gateway/configuration](/zh-CN/gateway/configuration)(Gateway 网关认证模式)
|
||||
- [/gateway/trusted-proxy-auth](/zh-CN/gateway/trusted-proxy-auth)
|
||||
- [/gateway/remote](/zh-CN/gateway/remote)
|
||||
- [/cli/devices](/cli/devices)
|
||||
|
||||
## Gateway 网关服务未运行
|
||||
|
||||
当服务已安装但进程无法持续运行时,请使用本节。
|
||||
当服务已安装但进程无法保持运行时,请使用本节。
|
||||
|
||||
```bash
|
||||
openclaw gateway status
|
||||
@ -188,30 +177,30 @@ openclaw doctor
|
||||
openclaw gateway status --deep # also scan system-level services
|
||||
```
|
||||
|
||||
检查:
|
||||
检查以下内容:
|
||||
|
||||
- 带退出提示的 `Runtime: stopped`。
|
||||
- 服务配置不匹配(`Config (cli)` 与 `Config (service)`)。
|
||||
- `Runtime: stopped` 以及退出提示。
|
||||
- 服务配置不匹配(`Config (cli)` vs `Config (service)`)。
|
||||
- 端口/监听器冲突。
|
||||
- 使用 `--deep` 时,是否存在额外的 launchd/systemd/schtasks 安装。
|
||||
- 使用 `--deep` 时,是否存在多余的 launchd/systemd/schtasks 安装。
|
||||
- `Other gateway-like services detected (best effort)` 清理提示。
|
||||
|
||||
常见特征:
|
||||
|
||||
- `Gateway start blocked: set gateway.mode=local` 或 `existing config is missing gateway.mode` → 未启用本地 gateway 模式,或配置文件被覆盖导致丢失了 `gateway.mode`。修复方法:在你的配置中设置 `gateway.mode="local"`,或重新运行 `openclaw onboard --mode local` / `openclaw setup` 以重新写入预期的本地模式配置。如果你通过 Podman 运行 OpenClaw,默认配置路径是 `~/.openclaw/openclaw.json`。
|
||||
- `refusing to bind gateway ... without auth` → 非 loopback 绑定,且没有有效的 gateway 认证路径(token/password,或在配置正确时使用 trusted-proxy)。
|
||||
- `Gateway start blocked: set gateway.mode=local` 或 `existing config is missing gateway.mode` → 未启用本地 Gateway 网关模式,或者配置文件被覆盖导致丢失了 `gateway.mode`。修复方法:在你的配置中设置 `gateway.mode="local"`,或重新运行 `openclaw onboard --mode local` / `openclaw setup` 以重新写入预期的本地模式配置。如果你通过 Podman 运行 OpenClaw,默认配置路径是 `~/.openclaw/openclaw.json`。
|
||||
- `refusing to bind gateway ... without auth` → 非 loopback 绑定,但没有有效的 Gateway 网关认证路径(token/password,或在已配置时使用 trusted-proxy)。
|
||||
- `another gateway instance is already listening` / `EADDRINUSE` → 端口冲突。
|
||||
- `Other gateway-like services detected (best effort)` → 存在过期或并行的 launchd/systemd/schtasks 单元。大多数部署应保持每台机器一个 gateway;如果你确实需要多个,请隔离端口 + 配置/状态/工作区。参见 [/gateway#multiple-gateways-same-host](/gateway#multiple-gateways-same-host)。
|
||||
- `Other gateway-like services detected (best effort)` → 存在过期或并行的 launchd/systemd/schtasks 单元。大多数配置应保持每台机器一个 Gateway 网关;如果你确实需要多个,请隔离端口 + 配置/状态/工作区。参见 [/gateway#multiple-gateways-same-host](/zh-CN/gateway#multiple-gateways-same-host)。
|
||||
|
||||
相关内容:
|
||||
|
||||
- [/gateway/background-process](/gateway/background-process)
|
||||
- [/gateway/configuration](/gateway/configuration)
|
||||
- [/gateway/doctor](/gateway/doctor)
|
||||
- [/gateway/background-process](/zh-CN/gateway/background-process)
|
||||
- [/gateway/configuration](/zh-CN/gateway/configuration)
|
||||
- [/gateway/doctor](/zh-CN/gateway/doctor)
|
||||
|
||||
## Gateway 网关探测警告
|
||||
|
||||
当 `openclaw gateway probe` 能连接到某个目标,但仍打印警告块时,请使用本节。
|
||||
当 `openclaw gateway probe` 确实探测到某个目标,但仍输出警告块时,请使用本节。
|
||||
|
||||
```bash
|
||||
openclaw gateway probe
|
||||
@ -219,27 +208,27 @@ openclaw gateway probe --json
|
||||
openclaw gateway probe --ssh user@gateway-host
|
||||
```
|
||||
|
||||
检查:
|
||||
检查以下内容:
|
||||
|
||||
- JSON 输出中的 `warnings[].code` 和 `primaryTargetId`。
|
||||
- 该警告是否与 SSH 回退、多个 Gateway 网关、缺失作用域或未解析认证引用有关。
|
||||
- 警告是否与 SSH 回退、多个 Gateway 网关、缺少 scopes 或未解析的 auth 引用有关。
|
||||
|
||||
常见特征:
|
||||
|
||||
- `SSH tunnel failed to start; falling back to direct probes.` → SSH 设置失败,但命令仍尝试了直接的已配置/loopback 目标。
|
||||
- `multiple reachable gateways detected` → 有多个目标响应。通常意味着有意的多 Gateway 网关部署,或存在过期/重复监听器。
|
||||
- `Probe diagnostics are limited by gateway scopes (missing operator.read)` → 连接成功,但详细 RPC 受作用域限制;请配对设备身份或使用带有 `operator.read` 的凭证。
|
||||
- 未解析的 `gateway.auth.*` / `gateway.remote.*` SecretRef 警告文本 → 在当前命令路径中,该目标失败时认证材料不可用。
|
||||
- `SSH tunnel failed to start; falling back to direct probes.` → SSH 设置失败,但命令仍尝试了直接配置的/loopback 目标。
|
||||
- `multiple reachable gateways detected` → 有多个目标做出了响应。这通常意味着你有意配置了多个 Gateway 网关,或者存在过期/重复监听器。
|
||||
- `Probe diagnostics are limited by gateway scopes (missing operator.read)` → 连接成功,但详细 RPC 受 scope 限制;请配对设备身份或使用带有 `operator.read` 的凭证。
|
||||
- 未解析的 `gateway.auth.*` / `gateway.remote.*` SecretRef 警告文本 → 在该命令路径中,失败目标的认证材料不可用。
|
||||
|
||||
相关内容:
|
||||
|
||||
- [/cli/gateway](/cli/gateway)
|
||||
- [/gateway#multiple-gateways-same-host](/gateway#multiple-gateways-same-host)
|
||||
- [/gateway/remote](/gateway/remote)
|
||||
- [/gateway#multiple-gateways-same-host](/zh-CN/gateway#multiple-gateways-same-host)
|
||||
- [/gateway/remote](/zh-CN/gateway/remote)
|
||||
|
||||
## 渠道已连接但消息不流动
|
||||
## 渠道已连接但消息不流转
|
||||
|
||||
如果渠道状态显示已连接,但消息流已停止,请重点检查策略、权限和渠道特定投递规则。
|
||||
如果渠道状态显示已连接,但消息流转中断,请重点检查策略、权限和渠道特定的投递规则。
|
||||
|
||||
```bash
|
||||
openclaw channels status --probe
|
||||
@ -249,28 +238,28 @@ openclaw logs --follow
|
||||
openclaw config get channels
|
||||
```
|
||||
|
||||
检查:
|
||||
检查以下内容:
|
||||
|
||||
- 私信策略(`pairing`、`allowlist`、`open`、`disabled`)。
|
||||
- 群组允许列表和提及要求。
|
||||
- 缺失的渠道 API 权限/作用域。
|
||||
- 是否缺少渠道 API 权限/scopes。
|
||||
|
||||
常见特征:
|
||||
|
||||
- `mention required` → 消息因群组提及策略而被忽略。
|
||||
- `pairing` / 待批准痕迹 → 发送者尚未获批。
|
||||
- `pairing` / 待批准跟踪 → 发送者尚未获批。
|
||||
- `missing_scope`, `not_in_channel`, `Forbidden`, `401/403` → 渠道认证/权限问题。
|
||||
|
||||
相关内容:
|
||||
|
||||
- [/channels/troubleshooting](/channels/troubleshooting)
|
||||
- [/channels/whatsapp](/channels/whatsapp)
|
||||
- [/channels/telegram](/channels/telegram)
|
||||
- [/channels/discord](/channels/discord)
|
||||
- [/channels/troubleshooting](/zh-CN/channels/troubleshooting)
|
||||
- [/channels/whatsapp](/zh-CN/channels/whatsapp)
|
||||
- [/channels/telegram](/zh-CN/channels/telegram)
|
||||
- [/channels/discord](/zh-CN/channels/discord)
|
||||
|
||||
## Cron 和 heartbeat 投递
|
||||
## Cron 和心跳投递
|
||||
|
||||
如果 cron 或 heartbeat 未运行或未投递,请先验证调度器状态,然后检查投递目标。
|
||||
如果 cron 或心跳没有运行,或者运行了但未投递,请先验证调度器状态,再检查投递目标。
|
||||
|
||||
```bash
|
||||
openclaw cron status
|
||||
@ -280,31 +269,31 @@ openclaw system heartbeat last
|
||||
openclaw logs --follow
|
||||
```
|
||||
|
||||
检查:
|
||||
检查以下内容:
|
||||
|
||||
- 是否启用了 cron,且存在下次唤醒时间。
|
||||
- 作业运行历史状态(`ok`、`skipped`、`error`)。
|
||||
- heartbeat 跳过原因(`quiet-hours`、`requests-in-flight`、`alerts-disabled`、`empty-heartbeat-file`、`no-tasks-due`)。
|
||||
- Cron 已启用,并且存在下一次唤醒时间。
|
||||
- 任务运行历史状态(`ok`、`skipped`、`error`)。
|
||||
- 心跳跳过原因(`quiet-hours`、`requests-in-flight`、`alerts-disabled`、`empty-heartbeat-file`、`no-tasks-due`)。
|
||||
|
||||
常见特征:
|
||||
|
||||
- `cron: scheduler disabled; jobs will not run automatically` → cron 已禁用。
|
||||
- `cron: timer tick failed` → 调度器 tick 失败;请检查文件/日志/运行时错误。
|
||||
- 带有 `reason=quiet-hours` 的 `heartbeat skipped` → 当前不在活跃时间窗口内。
|
||||
- 带有 `reason=empty-heartbeat-file` 的 `heartbeat skipped` → `HEARTBEAT.md` 存在,但仅包含空行 / Markdown 标题,因此 OpenClaw 会跳过模型调用。
|
||||
- 带有 `reason=no-tasks-due` 的 `heartbeat skipped` → `HEARTBEAT.md` 包含 `tasks:` 块,但在本次 tick 中没有任何任务到期。
|
||||
- `heartbeat: unknown accountId` → heartbeat 投递目标使用了无效的账号 id。
|
||||
- 带有 `reason=dm-blocked` 的 `heartbeat skipped` → heartbeat 目标被解析为私信式目标,而 `agents.defaults.heartbeat.directPolicy`(或每智能体覆盖)设置为 `block`。
|
||||
- `heartbeat skipped` 且 `reason=quiet-hours` → 当前不在活跃时间窗口内。
|
||||
- `heartbeat skipped` 且 `reason=empty-heartbeat-file` → `HEARTBEAT.md` 存在,但只包含空行 / Markdown 标题,因此 OpenClaw 会跳过模型调用。
|
||||
- `heartbeat skipped` 且 `reason=no-tasks-due` → `HEARTBEAT.md` 包含 `tasks:` 块,但这一轮 tick 中没有任务到期。
|
||||
- `heartbeat: unknown accountId` → 心跳投递目标的 account id 无效。
|
||||
- `heartbeat skipped` 且 `reason=dm-blocked` → 心跳目标被解析为私信式目标,而 `agents.defaults.heartbeat.directPolicy`(或按智能体覆盖项)设置为 `block`。
|
||||
|
||||
相关内容:
|
||||
|
||||
- [/automation/cron-jobs#troubleshooting](/automation/cron-jobs#troubleshooting)
|
||||
- [/automation/cron-jobs](/automation/cron-jobs)
|
||||
- [/gateway/heartbeat](/gateway/heartbeat)
|
||||
- [/automation/cron-jobs#troubleshooting](/zh-CN/automation/cron-jobs#troubleshooting)
|
||||
- [/automation/cron-jobs](/zh-CN/automation/cron-jobs)
|
||||
- [/gateway/heartbeat](/zh-CN/gateway/heartbeat)
|
||||
|
||||
## 节点已配对但工具失败
|
||||
## 已配对节点的工具失败
|
||||
|
||||
如果节点已配对但工具调用失败,请分别排查前台状态、权限和审批状态。
|
||||
如果节点已配对,但工具仍然失败,请分别检查前台状态、权限和批准状态。
|
||||
|
||||
```bash
|
||||
openclaw nodes status
|
||||
@ -314,28 +303,28 @@ openclaw logs --follow
|
||||
openclaw status
|
||||
```
|
||||
|
||||
检查:
|
||||
检查以下内容:
|
||||
|
||||
- 节点是否在线并具有预期能力。
|
||||
- 相机/麦克风/定位/屏幕的操作系统权限是否已授予。
|
||||
- Exec 审批和允许列表状态。
|
||||
- 节点在线,并具有预期能力。
|
||||
- 相机/麦克风/定位/屏幕的 OS 权限已授予。
|
||||
- exec 批准和允许列表状态。
|
||||
|
||||
常见特征:
|
||||
|
||||
- `NODE_BACKGROUND_UNAVAILABLE` → 节点应用必须处于前台。
|
||||
- `*_PERMISSION_REQUIRED` / `LOCATION_PERMISSION_REQUIRED` → 缺少操作系统权限。
|
||||
- `SYSTEM_RUN_DENIED: approval required` → exec 审批待处理。
|
||||
- `NODE_BACKGROUND_UNAVAILABLE` → 节点应用必须位于前台。
|
||||
- `*_PERMISSION_REQUIRED` / `LOCATION_PERMISSION_REQUIRED` → 缺少 OS 权限。
|
||||
- `SYSTEM_RUN_DENIED: approval required` → exec 批准仍在等待。
|
||||
- `SYSTEM_RUN_DENIED: allowlist miss` → 命令被允许列表阻止。
|
||||
|
||||
相关内容:
|
||||
|
||||
- [/nodes/troubleshooting](/nodes/troubleshooting)
|
||||
- [/nodes/index](/nodes/index)
|
||||
- [/tools/exec-approvals](/tools/exec-approvals)
|
||||
- [/nodes/troubleshooting](/zh-CN/nodes/troubleshooting)
|
||||
- [/nodes/index](/zh-CN/nodes/index)
|
||||
- [/tools/exec-approvals](/zh-CN/tools/exec-approvals)
|
||||
|
||||
## 浏览器工具失败
|
||||
|
||||
当浏览器工具操作失败,但 gateway 本身是健康的时,请使用本节。
|
||||
当浏览器工具操作失败,但 Gateway 网关本身是健康的,请使用本节。
|
||||
|
||||
```bash
|
||||
openclaw browser status
|
||||
@ -345,43 +334,43 @@ openclaw logs --follow
|
||||
openclaw doctor
|
||||
```
|
||||
|
||||
检查:
|
||||
检查以下内容:
|
||||
|
||||
- 是否设置了 `plugins.allow` 且其中包含 `browser`。
|
||||
- 浏览器可执行文件路径是否有效。
|
||||
- CDP 配置档案是否可达。
|
||||
- 对于 `existing-session` / `user` 配置档案,本地 Chrome 是否可用。
|
||||
- CDP profile 是否可达。
|
||||
- `existing-session` / `user` profiles 是否有本地 Chrome 可用。
|
||||
|
||||
常见特征:
|
||||
|
||||
- `unknown command "browser"` 或 `unknown command 'browser'` → 内置 browser 插件被 `plugins.allow` 排除了。
|
||||
- 在 `browser.enabled=true` 的情况下 browser 工具缺失 / 不可用 → `plugins.allow` 排除了 `browser`,因此插件从未加载。
|
||||
- `unknown command "browser"` 或 `unknown command 'browser'` → 内置 browser 插件被 `plugins.allow` 排除。
|
||||
- 在 `browser.enabled=true` 时 browser 工具缺失 / 不可用 → `plugins.allow` 排除了 `browser`,因此插件从未加载。
|
||||
- `Failed to start Chrome CDP on port` → 浏览器进程启动失败。
|
||||
- `browser.executablePath not found` → 配置的路径无效。
|
||||
- `browser.cdpUrl must be http(s) or ws(s)` → 配置的 CDP URL 使用了不受支持的协议,例如 `file:` 或 `ftp:`。
|
||||
- `browser.cdpUrl has invalid port` → 配置的 CDP URL 具有错误或超出范围的端口。
|
||||
- `No Chrome tabs found for profile="user"` → Chrome MCP 附加配置档案没有打开的本地 Chrome 标签页。
|
||||
- `Remote CDP for profile "<name>" is not reachable` → 从 gateway 主机无法访问配置的远程 CDP 端点。
|
||||
- `Browser attachOnly is enabled ... not reachable` 或 `Browser attachOnly is enabled and CDP websocket ... is not reachable` → attach-only 配置档案没有可达目标,或者 HTTP 端点虽有响应,但 CDP WebSocket 仍无法打开。
|
||||
- `Playwright is not available in this gateway build; '<feature>' is unsupported.` → 当前 gateway 安装缺少完整的 Playwright 包;ARIA 快照和基础页面截图仍可工作,但导航、AI 快照、基于 CSS 选择器的元素截图和 PDF 导出仍不可用。
|
||||
- `fullPage is not supported for element screenshots` → 截图请求同时混用了 `--full-page` 与 `--ref` 或 `--element`。
|
||||
- `element screenshots are not supported for existing-session profiles; use ref from snapshot.` → Chrome MCP / `existing-session` 截图调用必须使用页面捕获或快照 `--ref`,不能使用 CSS `--element`。
|
||||
- `existing-session file uploads do not support element selectors; use ref/inputRef.` → Chrome MCP 上传 hook 需要使用快照引用,而不是 CSS 选择器。
|
||||
- `existing-session file uploads currently support one file at a time.` → 在 Chrome MCP 配置档案上每次调用只发送一个上传文件。
|
||||
- `existing-session dialog handling does not support timeoutMs.` → Chrome MCP 配置档案上的对话框 hook 不支持超时覆盖。
|
||||
- `response body is not supported for existing-session profiles yet.` → `responsebody` 仍需要托管浏览器或原始 CDP 配置档案。
|
||||
- attach-only 或远程 CDP 配置档案上的过期 viewport / dark-mode / locale / offline 覆盖 → 运行 `openclaw browser stop --browser-profile <name>` 以关闭当前活动控制会话,并释放 Playwright/CDP 仿真状态,而无需重启整个 gateway。
|
||||
- `browser.cdpUrl has invalid port` → 配置的 CDP URL 端口错误或超出范围。
|
||||
- `No Chrome tabs found for profile="user"` → Chrome MCP attach profile 没有打开的本地 Chrome 标签页。
|
||||
- `Remote CDP for profile "<name>" is not reachable` → 从 Gateway 网关主机无法访问配置的远程 CDP 端点。
|
||||
- `Browser attachOnly is enabled ... not reachable` 或 `Browser attachOnly is enabled and CDP websocket ... is not reachable` → attach-only profile 没有可达目标,或者 HTTP 端点虽然响应了,但 CDP WebSocket 仍无法打开。
|
||||
- `Playwright is not available in this gateway build; '<feature>' is unsupported.` → 当前 Gateway 网关安装缺少完整的 Playwright 包;ARIA 快照和基础页面截图仍可能可用,但导航、AI 快照、基于 CSS 选择器的元素截图和 PDF 导出仍不可用。
|
||||
- `fullPage is not supported for element screenshots` → 截图请求同时使用了 `--full-page` 和 `--ref` 或 `--element`。
|
||||
- `element screenshots are not supported for existing-session profiles; use ref from snapshot.` → Chrome MCP / `existing-session` 截图调用必须使用页面捕获或快照 `--ref`,而不是 CSS `--element`。
|
||||
- `existing-session file uploads do not support element selectors; use ref/inputRef.` → Chrome MCP 上传钩子需要使用快照引用,而不是 CSS 选择器。
|
||||
- `existing-session file uploads currently support one file at a time.` → 在 Chrome MCP profiles 上,每次调用只能发送一个上传文件。
|
||||
- `existing-session dialog handling does not support timeoutMs.` → Chrome MCP profiles 上的对话框钩子不支持超时覆盖。
|
||||
- `response body is not supported for existing-session profiles yet.` → `responsebody` 仍然需要托管浏览器或原始 CDP profile。
|
||||
- attach-only 或远程 CDP profiles 上出现陈旧的视口 / 深色模式 / 语言环境 / 离线覆盖 → 运行 `openclaw browser stop --browser-profile <name>` 关闭活动控制会话,并释放 Playwright/CDP 模拟状态,而无需重启整个 Gateway 网关。
|
||||
|
||||
相关内容:
|
||||
|
||||
- [/tools/browser-linux-troubleshooting](/tools/browser-linux-troubleshooting)
|
||||
- [/tools/browser](/tools/browser)
|
||||
- [/tools/browser-linux-troubleshooting](/zh-CN/tools/browser-linux-troubleshooting)
|
||||
- [/tools/browser](/zh-CN/tools/browser)
|
||||
|
||||
## 如果你升级后突然出现故障
|
||||
## 如果你升级后突然出现问题
|
||||
|
||||
大多数升级后的故障都是配置漂移,或之前宽松、现在开始强制执行的默认值所致。
|
||||
大多数升级后的故障都源于配置漂移,或是现在开始强制执行更严格的默认值。
|
||||
|
||||
### 1) 认证和 URL 覆盖行为已改变
|
||||
### 1) 认证和 URL 覆盖行为发生了变化
|
||||
|
||||
```bash
|
||||
openclaw gateway status
|
||||
@ -390,17 +379,17 @@ openclaw config get gateway.remote.url
|
||||
openclaw config get gateway.auth.mode
|
||||
```
|
||||
|
||||
检查要点:
|
||||
检查什么:
|
||||
|
||||
- 如果 `gateway.mode=remote`,CLI 调用可能指向远程目标,而你的本地服务其实是正常的。
|
||||
- 显式 `--url` 调用不会回退到已存储凭证。
|
||||
- 如果 `gateway.mode=remote`,CLI 调用可能会指向远程,而你的本地服务本身其实没问题。
|
||||
- 显式 `--url` 调用不会回退到已存储的凭证。
|
||||
|
||||
常见特征:
|
||||
|
||||
- `gateway connect failed:` → URL 目标错误。
|
||||
- `unauthorized` → 端点可达,但认证错误。
|
||||
|
||||
### 2) 绑定和认证护栏更严格了
|
||||
### 2) 绑定和认证防护更严格了
|
||||
|
||||
```bash
|
||||
openclaw config get gateway.bind
|
||||
@ -410,17 +399,17 @@ openclaw gateway status
|
||||
openclaw logs --follow
|
||||
```
|
||||
|
||||
检查要点:
|
||||
检查什么:
|
||||
|
||||
- 非 loopback 绑定(`lan`、`tailnet`、`custom`)需要有效的 gateway 认证路径:共享 token/password 认证,或正确配置的非 loopback `trusted-proxy` 部署。
|
||||
- `gateway.token` 之类的旧键不能替代 `gateway.auth.token`。
|
||||
- 非 loopback 绑定(`lan`、`tailnet`、`custom`)需要有效的 Gateway 网关认证路径:共享 token/password 认证,或正确配置的非 loopback `trusted-proxy` 部署。
|
||||
- 像 `gateway.token` 这样的旧键不能替代 `gateway.auth.token`。
|
||||
|
||||
常见特征:
|
||||
|
||||
- `refusing to bind gateway ... without auth` → 非 loopback 绑定,但没有有效的 gateway 认证路径。
|
||||
- `RPC probe: failed` 且运行时显示为 running → gateway 存活,但使用当前 auth/url 无法访问。
|
||||
- `refusing to bind gateway ... without auth` → 非 loopback 绑定,但没有有效的 Gateway 网关认证路径。
|
||||
- `RPC probe: failed` 且运行时正在运行 → Gateway 网关是活的,但以当前 auth/url 无法访问。
|
||||
|
||||
### 3) 配对和设备身份状态已改变
|
||||
### 3) 配对和设备身份状态发生了变化
|
||||
|
||||
```bash
|
||||
openclaw devices list
|
||||
@ -429,17 +418,17 @@ openclaw logs --follow
|
||||
openclaw doctor
|
||||
```
|
||||
|
||||
检查要点:
|
||||
检查什么:
|
||||
|
||||
- dashboard/节点是否存在待批准设备。
|
||||
- 在策略或身份变更后,私信配对批准是否待处理。
|
||||
- 仪表板/节点是否存在待批准的设备审批。
|
||||
- 策略或身份变更后,是否存在待批准的私信配对审批。
|
||||
|
||||
常见特征:
|
||||
|
||||
- `device identity required` → 设备认证未满足。
|
||||
- `pairing required` → 发送者/设备必须获得批准。
|
||||
- `pairing required` → 发送者/设备必须先获批。
|
||||
|
||||
如果检查之后服务配置与运行时仍不一致,请从同一个配置档案/状态目录重新安装服务元数据:
|
||||
如果检查后服务配置和运行时仍不一致,请使用相同的 profile/state 目录重新安装服务元数据:
|
||||
|
||||
```bash
|
||||
openclaw gateway install --force
|
||||
@ -448,6 +437,6 @@ openclaw gateway restart
|
||||
|
||||
相关内容:
|
||||
|
||||
- [/gateway/pairing](/gateway/pairing)
|
||||
- [/gateway/authentication](/gateway/authentication)
|
||||
- [/gateway/background-process](/gateway/background-process)
|
||||
- [/gateway/pairing](/zh-CN/gateway/pairing)
|
||||
- [/gateway/authentication](/zh-CN/gateway/authentication)
|
||||
- [/gateway/background-process](/zh-CN/gateway/background-process)
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -1,135 +1,136 @@
|
||||
---
|
||||
read_when:
|
||||
- 在本地或 CI 中运行测试时
|
||||
- 为模型 / 提供商缺陷添加回归测试时
|
||||
- 为模型/提供商 bug 添加回归测试时
|
||||
- 调试 Gateway 网关 + 智能体行为时
|
||||
summary: 测试工具包:单元 / e2e / live 测试套件、Docker 运行器,以及每类测试覆盖的内容
|
||||
summary: 测试套件:单元/e2e/live 套件、Docker 运行器,以及各类测试覆盖内容
|
||||
title: 测试
|
||||
x-i18n:
|
||||
generated_at: "2026-04-06T12:44:29Z"
|
||||
generated_at: "2026-04-06T15:30:41Z"
|
||||
model: gpt-5.4
|
||||
provider: openai
|
||||
source_hash: b18d68d08b851dea994af250f7cb833a34523601d04fd2f118def9777c961b55
|
||||
source_hash: a2c8af6ff9cbef3d148f9d51016d9bc35b069a4467fb72874be265872ca13da1
|
||||
source_path: help/testing.md
|
||||
workflow: 15
|
||||
---
|
||||
|
||||
# 测试
|
||||
|
||||
OpenClaw 有三个 Vitest 测试套件(单元 / 集成、e2e、live)以及一小组 Docker 运行器。
|
||||
OpenClaw 有三类 Vitest 套件(单元/集成、e2e、live)以及少量 Docker 运行器。
|
||||
|
||||
本文档是一份“我们如何测试”的指南:
|
||||
|
||||
- 每个测试套件覆盖什么(以及它刻意 _不_ 覆盖什么)
|
||||
- 常见工作流该运行哪些命令(本地、推送前、调试)
|
||||
- live 测试如何发现凭证并选择模型 / 提供商
|
||||
- 如何为真实世界中的模型 / 提供商问题添加回归测试
|
||||
- 每个套件覆盖什么内容(以及它刻意**不**覆盖什么)
|
||||
- 常见工作流应运行哪些命令(本地、推送前、调试)
|
||||
- live 测试如何发现凭证并选择模型/提供商
|
||||
- 如何为真实世界中的模型/提供商问题添加回归测试
|
||||
|
||||
## 快速开始
|
||||
|
||||
大多数时候:
|
||||
大多数情况下:
|
||||
|
||||
- 完整门槛检查(预期在推送前执行):`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`
|
||||
- 完整 gate(推送前预期要运行):`pnpm build && pnpm check && pnpm test`
|
||||
- 在配置较好的机器上更快地运行本地完整套件:`pnpm test:max`
|
||||
- 直接进入 Vitest watch 循环:`pnpm test:watch`
|
||||
- 现在直接指定文件也会路由扩展/渠道路径:`pnpm test extensions/discord/src/monitor/message-handler.preflight.test.ts`
|
||||
|
||||
当你修改了测试或想获得更多信心时:
|
||||
当你修改了测试或希望获得更高信心时:
|
||||
|
||||
- 覆盖率门槛检查:`pnpm test:coverage`
|
||||
- E2E 测试套件:`pnpm test:e2e`
|
||||
- 覆盖率 gate:`pnpm test:coverage`
|
||||
- E2E 套件:`pnpm test:e2e`
|
||||
|
||||
调试真实提供商 / 模型时(需要真实凭证):
|
||||
当你调试真实提供商/模型时(需要真实凭证):
|
||||
|
||||
- Live 测试套件(模型 + Gateway 网关 工具 / 图像探测):`pnpm test:live`
|
||||
- 安静地只跑一个 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 环境变量来缩小 live 测试范围。
|
||||
提示:当你只需要定位一个失败用例时,优先通过下面描述的允许列表环境变量缩小 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` 下的 core/unit 测试清单,以及 `vitest.unit.config.ts` 覆盖的白名单 `ui` Node 测试
|
||||
- 范围:
|
||||
- 纯单元测试
|
||||
- 进程内集成测试(Gateway 网关 身份验证、路由、工具、解析、配置)
|
||||
- 已知缺陷的确定性回归测试
|
||||
- 进程内集成测试(Gateway 网关认证、路由、工具、解析、配置)
|
||||
- 已知 bug 的确定性回归测试
|
||||
- 预期:
|
||||
- 在 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` 仍然使用原生 Vitest 根 `projects` 配置。
|
||||
- `pnpm test`、`pnpm test:watch` 和 `pnpm test:perf:imports` 会先将显式文件/目录目标路由到作用域更小的 lane,因此 `pnpm test extensions/discord/src/monitor/message-handler.preflight.test.ts` 不必承担完整根项目启动开销。
|
||||
- `pnpm test:changed` 会在 diff 仅涉及可路由的源文件/测试文件时,把变更的 git 路径展开到相同的 scoped lane;若修改了配置/设置,则仍会回退到更宽泛的根项目重跑。
|
||||
- 选定的 `plugin-sdk` 和 `commands` 测试也会路由到专门的轻量 lane,跳过 `test/setup-openclaw-runtime.ts`;有状态/运行时较重的文件仍保留在现有 lane 上。
|
||||
- 选定的 `plugin-sdk` 和 `commands` 辅助源文件也会在 changed 模式运行时映射到这些轻量 lane 中的显式同级测试,因此辅助文件变更不会导致该目录下整个重型套件重跑。
|
||||
- 嵌入式运行器说明:
|
||||
- 当你修改消息工具发现输入或压缩运行时上下文时,
|
||||
请同时保留两个层级的覆盖。
|
||||
- 为纯路由 / 规范化边界添加有针对性的辅助函数回归测试。
|
||||
- 同时也要保持嵌入式运行器集成测试套件健康:
|
||||
需要同时保持两层覆盖。
|
||||
- 为纯路由/标准化边界添加聚焦的辅助回归测试。
|
||||
- 同时还要确保嵌入式运行器集成套件保持健康:
|
||||
`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` 路径流动;仅辅助层测试并不足以替代这些集成路径。
|
||||
- 池说明:
|
||||
- 基础 Vitest 配置现在默认使用 `threads`。
|
||||
- 共享 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`。
|
||||
- 共享 Vitest 配置还固定了 `isolate: false`,并在根项目、e2e 和 live 配置中使用非隔离运行器。
|
||||
- 根 UI lane 保留了其 `jsdom` 设置和优化器,但现在也运行在共享的非隔离运行器上。
|
||||
- `pnpm test` 继承了根 `vitest.config.ts` 项目配置中的相同 `threads` + `isolate: false` 默认值。
|
||||
- 共享的 `scripts/run-vitest.mjs` 启动器现在还会默认给 Vitest 子 Node 进程添加 `--no-maglev`,以减少大型本地运行期间的 V8 编译抖动。如果你需要与原生 V8 行为对比,请设置 `OPENCLAW_VITEST_ENABLE_MAGLEV=1`。
|
||||
- 本地快速迭代说明:
|
||||
- `pnpm test:changed` 会在变更路径可清晰映射到更小套件时路由到 scoped lane。
|
||||
- `pnpm test:max` 和 `pnpm test:changed:max` 保持相同的路由行为,只是提高了 worker 上限。
|
||||
- 本地 worker 自动缩放现在有意更保守,并且在主机平均负载已较高时也会退避,因此默认情况下多个并发 Vitest 运行对机器的影响会更小。
|
||||
- 基础 Vitest 配置将项目/配置文件标记为 `forceRerunTriggers`,从而在测试接线发生变化时保证 changed 模式的重跑仍然正确。
|
||||
- 在受支持主机上,该配置会保持 `OPENCLAW_VITEST_FS_MODULE_CACHE` 启用;如果你想为直接分析指定一个明确的缓存位置,请设置 `OPENCLAW_VITEST_FS_MODULE_CACHE_PATH=/abs/path`。
|
||||
- 性能调试说明:
|
||||
- `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 + 堆 profile。
|
||||
- `pnpm test:perf:imports` 会启用 Vitest 导入时长报告以及导入拆解输出。
|
||||
- `pnpm test:perf:imports:changed` 会将同样的分析视图限定到自 `origin/main` 以来发生变化的文件。
|
||||
- `pnpm test:perf:profile:main` 会为 Vitest/Vite 启动和 transform 开销写出主线程 CPU profile。
|
||||
- `pnpm test:perf:profile:runner` 会在禁用文件并行的情况下,为单元测试套件写出运行器 CPU + heap profile。
|
||||
|
||||
### E2E(Gateway 网关 冒烟测试)
|
||||
### E2E(Gateway 网关冒烟)
|
||||
|
||||
- 命令:`pnpm test:e2e`
|
||||
- 配置:`vitest.e2e.config.ts`
|
||||
- 文件:`src/**/*.e2e.test.ts`、`test/**/*.e2e.test.ts`
|
||||
- 运行时默认值:
|
||||
- 使用 Vitest `threads` 且 `isolate: false`,与仓库其余部分保持一致。
|
||||
- 使用 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 中运行(当流水线启用时)
|
||||
- 不需要真实密钥
|
||||
- 比单元测试有更多可变因素(可能更慢)
|
||||
- 比单元测试有更多运动部件(可能更慢)
|
||||
|
||||
### E2E:OpenShell 后端冒烟测试
|
||||
### E2E:OpenShell 后端冒烟
|
||||
|
||||
- 命令:`pnpm test:e2e:openshell`
|
||||
- 文件:`test/openshell-sandbox.e2e.test.ts`
|
||||
- 范围:
|
||||
- 通过 Docker 在主机上启动一个隔离的 OpenShell Gateway 网关
|
||||
- 从临时本地 Dockerfile 创建一个沙箱
|
||||
- 通过真实的 `sandbox ssh-config` + SSH exec 运行 OpenClaw 的 OpenShell 后端
|
||||
- 通过沙箱 fs bridge 验证远端标准文件系统行为
|
||||
- 从一个临时本地 Dockerfile 创建沙箱
|
||||
- 通过真实的 `sandbox ssh-config` + SSH exec 测试 OpenClaw 的 OpenShell 后端
|
||||
- 通过沙箱 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=1`:在手动运行更宽泛 e2e 套件时启用该测试
|
||||
- `OPENCLAW_E2E_OPENSHELL_COMMAND=/path/to/openshell`:指向非默认 CLI 二进制或包装脚本
|
||||
|
||||
### Live(真实提供商 + 真实模型)
|
||||
@ -137,127 +138,127 @@ OpenClaw 有三个 Vitest 测试套件(单元 / 集成、e2e、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 稳定为目标(真实网络、真实提供商策略、配额、故障)
|
||||
- 需要花钱 / 消耗速率限制
|
||||
- 优先运行缩小范围的子集,而不是“全部”
|
||||
- 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 覆盖;测试在收到限流响应时会重试。
|
||||
- 进度 / 心跳输出:
|
||||
- Live 测试套件现在会将进度行输出到 stderr,因此即使 Vitest 控制台捕获较安静,较长时间的提供商调用也能显示为仍在活动。
|
||||
- `vitest.live.config.ts` 禁用了 Vitest 控制台拦截,因此在 live 运行期间,提供商 / Gateway 网关 进度行会立即流式输出。
|
||||
- 使用 `OPENCLAW_LIVE_HEARTBEAT_MS` 调整直接模型心跳。
|
||||
- 使用 `OPENCLAW_LIVE_GATEWAY_HEARTBEAT_MS` 调整 Gateway 网关 / 探测心跳。
|
||||
- 设计上不是 CI 稳定项(真实网络、真实提供商策略、配额、故障)
|
||||
- 会花钱 / 消耗速率限制
|
||||
- 优先运行缩小后的子集,而不是“全部”
|
||||
- Live 运行会读取 `~/.profile` 以获取缺失的 API 密钥。
|
||||
- 默认情况下,live 运行仍会隔离 `HOME`,并将配置/认证材料复制到临时测试 home 中,这样单元测试 fixture 不会改动你真实的 `~/.openclaw`。
|
||||
- 仅当你明确需要让 live 测试使用真实 home 目录时,才设置 `OPENCLAW_LIVE_USE_REAL_HOME=1`。
|
||||
- `pnpm test:live` 现在默认使用更安静的模式:保留 `[live] ...` 进度输出,但会抑制额外的 `~/.profile` 提示,并静音 Gateway 网关引导日志/Bonjour 噪声。如果你希望恢复完整启动日志,请设置 `OPENCLAW_LIVE_TEST_QUIET=0`。
|
||||
- API 密钥轮换(提供商特定):设置逗号/分号格式的 `*_API_KEYS`,或 `*_API_KEY_1`、`*_API_KEY_2`(例如 `OPENAI_API_KEYS`、`ANTHROPIC_API_KEYS`、`GEMINI_API_KEYS`),也可以通过 `OPENCLAW_LIVE_*_KEY` 做每个 live 运行的覆盖;测试会在遇到限流响应时重试。
|
||||
- 进度/心跳输出:
|
||||
- Live 套件现在会向 stderr 输出进度行,因此即使 Vitest 控制台捕获处于安静模式,长时间的提供商调用也能显示正在运行。
|
||||
- `vitest.live.config.ts` 禁用了 Vitest 控制台拦截,因此提供商/Gateway 网关进度行会在 live 运行期间立即流出。
|
||||
- 用 `OPENCLAW_LIVE_HEARTBEAT_MS` 调整 direct-model 心跳。
|
||||
- 用 `OPENCLAW_LIVE_GATEWAY_HEARTBEAT_MS` 调整 Gateway 网关/探测心跳。
|
||||
|
||||
## 我应该运行哪个测试套件?
|
||||
## 我应该运行哪个套件?
|
||||
|
||||
使用这个决策表:
|
||||
请使用下面这张决策表:
|
||||
|
||||
- 编辑逻辑 / 测试:运行 `pnpm test`(如果改动较多,再加上 `pnpm test:coverage`)
|
||||
- 触及 Gateway 网关 网络 / WS 协议 / 配对:加跑 `pnpm test:e2e`
|
||||
- 调试“我的 bot 挂了” / 提供商专属失败 / 工具调用:运行缩小范围的 `pnpm test:live`
|
||||
- 编辑逻辑/测试:运行 `pnpm test`(如果改动较多,也运行 `pnpm test:coverage`)
|
||||
- 涉及 Gateway 网关网络 / WS 协议 / 配对:增加 `pnpm test:e2e`
|
||||
- 调试“我的 bot 挂了” / 提供商特定失败 / 工具调用:运行缩小后的 `pnpm test:live`
|
||||
|
||||
## 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)
|
||||
|
||||
## Live:模型冒烟测试(profile keys)
|
||||
## Live:模型冒烟(profile keys)
|
||||
|
||||
Live 测试分成两层,这样我们可以隔离失败原因:
|
||||
Live 测试分成两层,以便隔离失败点:
|
||||
|
||||
- “直接模型”告诉我们提供商 / 模型是否至少能用给定密钥正常响应。
|
||||
- “Gateway 网关 冒烟测试”告诉我们完整的 Gateway 网关 + 智能体流水线是否适用于该模型(会话、历史、工具、沙箱策略等)。
|
||||
- “Direct model” 告诉我们:在给定密钥下,提供商/模型是否至少能响应。
|
||||
- “Gateway smoke” 告诉我们:该模型在完整 Gateway 网关 + 智能体流水线中是否工作正常(会话、历史、工具、沙箱策略等)。
|
||||
|
||||
### 第 1 层:直接模型补全(无 Gateway 网关)
|
||||
|
||||
- 测试:`src/agents/models.profiles.live.test.ts`
|
||||
- 目标:
|
||||
- 枚举发现到的模型
|
||||
- 使用 `getApiKeyForModel` 选择你有凭证的模型
|
||||
- 为每个模型运行一次小型补全(在需要时也运行有针对性的回归测试)
|
||||
- 枚举已发现的模型
|
||||
- 使用 `getApiKeyForModel` 选择你具有凭证的模型
|
||||
- 对每个模型执行一个小型补全(并在需要时执行针对性回归)
|
||||
- 启用方式:
|
||||
- `pnpm test:live`(或直接调用 Vitest 时设置 `OPENCLAW_LIVE_TEST=1`)
|
||||
- 设置 `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)
|
||||
- `pnpm test:live`(或在直接调用 Vitest 时设置 `OPENCLAW_LIVE_TEST=1`)
|
||||
- 设置 `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=all` 是 modern allowlist 的别名
|
||||
- 或 `OPENCLAW_LIVE_MODELS="openai/gpt-5.4,anthropic/claude-opus-4-6,..."`(逗号分隔的 allowlist)
|
||||
- 如何选择提供商:
|
||||
- `OPENCLAW_LIVE_PROVIDERS="google,google-antigravity,google-gemini-cli"`(逗号分隔的 allowlist)
|
||||
- 或 `OPENCLAW_LIVE_MODELS="openai/gpt-5.4,anthropic/claude-opus-4-6,..."`(逗号分隔允许列表)
|
||||
- 选择提供商的方法:
|
||||
- `OPENCLAW_LIVE_PROVIDERS="google,google-antigravity,google-gemini-cli"`(逗号分隔允许列表)
|
||||
- 密钥来源:
|
||||
- 默认:profile 存储和环境变量回退
|
||||
- 设置 `OPENCLAW_LIVE_REQUIRE_PROFILE_KEYS=1` 以强制**仅使用 profile 存储**
|
||||
- 存在原因:
|
||||
- 将“提供商 API 坏了 / 密钥无效”与“Gateway 网关 智能体流水线坏了”分离
|
||||
- 容纳小而隔离的回归测试(例如:OpenAI Responses / Codex Responses 推理重放 + 工具调用流程)
|
||||
- 设置 `OPENCLAW_LIVE_REQUIRE_PROFILE_KEYS=1` 可强制**仅使用 profile 存储**
|
||||
- 该层存在的原因:
|
||||
- 将“提供商 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 探测)
|
||||
- 可选的额外工具探测(exec+read 探测)
|
||||
- OpenAI 回归路径(仅工具调用 → 后续跟进)继续可用
|
||||
- 探测细节(这样你可以快速解释失败):
|
||||
- `read` 探测:测试会在工作区写入一个 nonce 文件,并要求智能体 `read` 它并回显该 nonce。
|
||||
- `exec+read` 探测:测试要求智能体通过 `exec` 将一个 nonce 写入临时文件,然后再 `read` 回来。
|
||||
- 图像探测:测试会附加一个生成的 PNG(猫 + 随机代码),并期望模型返回 `cat <CODE>`。
|
||||
- 真实工具调用可用(read probe)
|
||||
- 可选的额外工具探测可用(exec+read probe)
|
||||
- OpenAI 回归路径(仅工具调用 → 后续跟进)仍然有效
|
||||
- Probe 细节(这样你可以快速解释失败):
|
||||
- `read` probe:测试会在工作区写入一个 nonce 文件,并要求智能体 `read` 该文件后回显 nonce。
|
||||
- `exec+read` probe:测试会要求智能体用 `exec` 将 nonce 写入一个临时文件,然后再 `read` 读回。
|
||||
- 图像 probe:测试会附加一个生成的 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)
|
||||
- `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,google-gemini-cli,openai,anthropic,zai,minimax"`(逗号分隔的 allowlist)
|
||||
- 工具 + 图像探测在这个 live 测试中始终启用:
|
||||
- `read` 探测 + `exec+read` 探测(工具压力测试)
|
||||
- 当模型声明支持图像输入时,会运行图像探测
|
||||
- 流程(高层级):
|
||||
- 测试生成一个带有 “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"`(逗号分隔允许列表)
|
||||
- 在这个 live 测试中,工具 + 图像探测始终开启:
|
||||
- `read` probe + `exec+read` probe(工具压力测试)
|
||||
- 当模型宣告支持图像输入时会运行 image probe
|
||||
- 流程(高层概览):
|
||||
- 测试生成一个带有 “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
|
||||
```
|
||||
|
||||
## Live:CLI 后端冒烟测试(Codex CLI 或其他本地 CLI)
|
||||
## Live:CLI 后端冒烟(Codex CLI 或其他本地 CLI)
|
||||
|
||||
- 测试:`src/gateway/gateway-cli-backend.live.test.ts`
|
||||
- 目标:使用本地 CLI 后端验证 Gateway 网关 + 智能体流水线,而不触碰你的默认配置。
|
||||
- 目标:在不触碰你的默认配置的情况下,使用本地 CLI 后端验证 Gateway 网关 + 智能体流水线。
|
||||
- 启用:
|
||||
- `pnpm test:live`(或直接调用 Vitest 时设置 `OPENCLAW_LIVE_TEST=1`)
|
||||
- `pnpm test:live`(或在直接调用 Vitest 时设置 `OPENCLAW_LIVE_TEST=1`)
|
||||
- `OPENCLAW_LIVE_CLI_BACKEND=1`
|
||||
- 默认值:
|
||||
- 模型:`codex-cli/gpt-5.4`
|
||||
@ -267,10 +268,10 @@ openclaw models list --json
|
||||
- `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` 发送第二轮并验证恢复流程。
|
||||
- `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` 发送第二轮消息并验证 resume 流程。
|
||||
|
||||
示例:
|
||||
|
||||
@ -289,31 +290,31 @@ 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`)中。
|
||||
- 它会在仓库 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`)
|
||||
## Live:ACP 绑定冒烟(`/acp spawn ... --bind here`)
|
||||
|
||||
- 测试:`src/gateway/gateway-acp-bind.live.test.ts`
|
||||
- 目标:使用 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` 接口,并带有仅管理员可用的合成来源路由字段,这样测试就能附加消息渠道上下文,而无需假装对外投递。
|
||||
- 当未设置 `OPENCLAW_LIVE_ACP_BIND_AGENT_COMMAND` 时,测试会使用内置 `acpx` 插件的内建智能体注册表来选择 ACP 测试智能体。
|
||||
- 该 lane 使用 Gateway 网关 `chat.send` 接口,并通过仅管理员可用的合成 originating-route 字段附加消息渠道上下文,而不是假装对外发送。
|
||||
- 当未设置 `OPENCLAW_LIVE_ACP_BIND_AGENT_COMMAND` 时,测试会使用嵌入式 `acpx` 插件内建的智能体注册表来选择对应 ACP harness 智能体。
|
||||
|
||||
示例:
|
||||
|
||||
@ -332,42 +333,42 @@ pnpm test:docker:live-acp-bind
|
||||
Docker 说明:
|
||||
|
||||
- Docker 运行器位于 `scripts/test-live-acp-bind-docker.sh`。
|
||||
- 它会读取 `~/.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 使用。
|
||||
- 它会读取 `~/.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 的提供商环境变量继续对其子 harness CLI 可见。
|
||||
|
||||
### 推荐的 live 配方
|
||||
|
||||
范围窄、明确的 allowlist 最快,也最不容易波动:
|
||||
范围小且显式的允许列表速度最快,也最不容易波动:
|
||||
|
||||
- 单模型,直接(无 Gateway 网关):
|
||||
- 单个模型,direct(无 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):
|
||||
- Gemini(API key):`OPENCLAW_LIVE_GATEWAY_MODELS="google/gemini-3-flash-preview" pnpm test:live src/gateway/gateway-models.profiles.live.test.ts`
|
||||
- 聚焦 Google(Gemini API 密钥 + Antigravity):
|
||||
- Gemini(API 密钥):`OPENCLAW_LIVE_GATEWAY_MODELS="google/gemini-3-flash-preview" pnpm test:live src/gateway/gateway-models.profiles.live.test.ts`
|
||||
- Antigravity(OAuth):`OPENCLAW_LIVE_GATEWAY_MODELS="google-antigravity/claude-opus-4-6-thinking,google-antigravity/gemini-3-pro-high" pnpm test:live src/gateway/gateway-models.profiles.live.test.ts`
|
||||
|
||||
说明:
|
||||
|
||||
- `google/...` 使用 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` 二进制;它有自己的身份验证,并且行为可能不同(流式传输 / 工具支持 / 版本偏差)。
|
||||
- `google/...` 使用 Gemini API(API 密钥)。
|
||||
- `google-antigravity/...` 使用 Antigravity OAuth bridge(类似 Cloud Code Assist 风格的智能体端点)。
|
||||
- `google-gemini-cli/...` 使用你机器上的本地 Gemini CLI(单独的认证 + 工具行为差异)。
|
||||
- Gemini API 与 Gemini CLI 的区别:
|
||||
- API:OpenClaw 通过 HTTP 调用 Google 托管的 Gemini API(API 密钥 / profile 认证);大多数用户说的 “Gemini” 指的就是这个。
|
||||
- CLI:OpenClaw 会调用本地 `gemini` 二进制;它有自己的认证,并且行为可能不同(流式传输/工具支持/版本偏差)。
|
||||
|
||||
## Live:模型矩阵(我们覆盖什么)
|
||||
|
||||
这里没有固定的“CI 模型列表”(live 是可选加入的),但以下是建议在有密钥的开发机器上定期覆盖的**推荐**模型。
|
||||
没有固定的“CI 模型列表”(live 为按需启用),但以下是**推荐**在有密钥的开发机器上定期覆盖的模型。
|
||||
|
||||
### Modern 冒烟测试集(工具调用 + 图像)
|
||||
### Modern 冒烟集合(工具调用 + 图像)
|
||||
|
||||
这是我们预期应持续保持可用的“常用模型”运行:
|
||||
这是我们期望持续保持可用的“常见模型”运行集合:
|
||||
|
||||
- OpenAI(非 Codex):`openai/gpt-5.4`(可选:`openai/gpt-5.4-mini`)
|
||||
- OpenAI Codex:`openai-codex/gpt-5.4`
|
||||
@ -377,12 +378,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`)
|
||||
@ -390,51 +391,51 @@ Docker 说明:
|
||||
- Z.AI(GLM):`zai/glm-4.7`
|
||||
- MiniMax:`minimax/MiniMax-M2.7`
|
||||
|
||||
可选的附加覆盖(有更好,没有也可以):
|
||||
可选额外覆盖(有更好,没有也可以):
|
||||
|
||||
- xAI:`xai/grok-4`(或最新可用版本)
|
||||
- Mistral:`mistral/`…(选择一个你已启用、具备 “tools” 能力的模型)
|
||||
- Mistral:`mistral/`…(选择一个你已启用、支持工具的模型)
|
||||
- Cerebras:`cerebras/`…(如果你有访问权限)
|
||||
- LM Studio:`lmstudio/`…(本地;工具调用取决于 API 模式)
|
||||
|
||||
### 视觉:图像发送(附件 → 多模态消息)
|
||||
|
||||
在 `OPENCLAW_LIVE_GATEWAY_MODELS` 中至少包含一个具备图像能力的模型(Claude / Gemini / OpenAI 支持视觉的变体等),以覆盖图像探测。
|
||||
在 `OPENCLAW_LIVE_GATEWAY_MODELS` 中至少包含一个支持图像的模型(Claude/Gemini/支持视觉的 OpenAI 变体等),以覆盖图像 probe。
|
||||
|
||||
### 聚合器 / 替代 Gateway 网关
|
||||
|
||||
如果你启用了相应密钥,我们也支持通过以下方式测试:
|
||||
如果你启用了对应密钥,我们也支持通过以下方式测试:
|
||||
|
||||
- OpenRouter:`openrouter/...`(数百个模型;使用 `openclaw models scan` 找出支持工具 + 图像的候选项)
|
||||
- OpenCode:Zen 用 `opencode/...`,Go 用 `opencode-go/...`(通过 `OPENCODE_API_KEY` / `OPENCODE_ZEN_API_KEY` 身份验证)
|
||||
- OpenRouter:`openrouter/...`(数百个模型;使用 `openclaw models scan` 查找支持工具 + 图像的候选)
|
||||
- OpenCode:Zen 使用 `opencode/...`,Go 使用 `opencode-go/...`(通过 `OPENCODE_API_KEY` / `OPENCODE_ZEN_API_KEY` 认证)
|
||||
|
||||
你也可以在 live 矩阵中加入更多提供商(如果你有凭证 / 配置):
|
||||
你还可以将更多提供商纳入 live 矩阵(如果你有凭证/配置):
|
||||
|
||||
- 内置:`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 等)
|
||||
- 通过 `models.providers`(自定义端点):`minimax`(云/API),以及任何 OpenAI/Anthropic 兼容代理(LM Studio、vLLM、LiteLLM 等)
|
||||
|
||||
提示:不要试图在文档中硬编码“所有模型”。权威列表始终是你机器上的 `discoverModels(...)` 返回结果 + 当前可用的密钥。
|
||||
提示:不要试图在文档里硬编码“所有模型”。权威列表始终是你机器上 `discoverModels(...)` 的返回结果 + 当前可用的密钥。
|
||||
|
||||
## 凭证(切勿提交)
|
||||
## 凭证(绝不提交)
|
||||
|
||||
Live 测试发现凭证的方式与 CLI 相同。实际含义如下:
|
||||
|
||||
- 如果 CLI 能工作,live 测试通常也能找到相同的密钥。
|
||||
- 如果 live 测试提示“无凭证”,就像调试 `openclaw models list` / 模型选择那样去调试。
|
||||
- 如果 CLI 可用,live 测试也应该能找到相同的密钥。
|
||||
- 如果 live 测试提示“无凭证”,排查方式应与排查 `openclaw models list` / 模型选择相同。
|
||||
|
||||
- 按智能体划分的 auth profiles:`~/.openclaw/agents/<agentId>/agent/auth-profiles.json`(这就是 live 测试中 “profile keys” 的含义)
|
||||
- 每个智能体的认证 profile:`~/.openclaw/agents/<agentId>/agent/auth-profiles.json`(这就是 live 测试里 “profile keys” 的含义)
|
||||
- 配置:`~/.openclaw/openclaw.json`(或 `OPENCLAW_CONFIG_PATH`)
|
||||
- 旧版状态目录:`~/.openclaw/credentials/`(如存在,会复制进暂存的 live home,但它不是主 profile-key 存储)
|
||||
- 默认情况下,live 本地运行会将当前活动配置、每个智能体的 `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` 路径覆盖,这样 probe 就不会落到你真实主机工作区上。
|
||||
|
||||
如果你想依赖环境变量密钥(例如导出在你的 `~/.profile` 中),请在本地测试前运行 `source ~/.profile`,或者使用下面的 Docker 运行器(它们可以将 `~/.profile` 挂载到容器中)。
|
||||
如果你想依赖环境变量中的密钥(例如在你的 `~/.profile` 中导出),请在本地测试前运行 `source ~/.profile`,或者使用下面的 Docker 运行器(它们可以将 `~/.profile` 挂载到容器中)。
|
||||
|
||||
## 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 编码计划 live
|
||||
## BytePlus 编码规划 live
|
||||
|
||||
- 测试:`src/agents/byteplus.live.test.ts`
|
||||
- 启用:`BYTEPLUS_API_KEY=... BYTEPLUS_LIVE_TEST=1 pnpm test:live src/agents/byteplus.live.test.ts`
|
||||
@ -445,9 +446,9 @@ Live 测试发现凭证的方式与 CLI 相同。实际含义如下:
|
||||
- 测试:`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 工作流提交、轮询、下载或插件注册后很有用
|
||||
- 测试内置 comfy 图像、视频和 `music_generate` 路径
|
||||
- 若未配置 `models.providers.comfy.<capability>`,则会跳过对应能力
|
||||
- 在修改 comfy 工作流提交、轮询、下载或插件注册后特别有用
|
||||
|
||||
## 图像生成 live
|
||||
|
||||
@ -456,8 +457,8 @@ Live 测试发现凭证的方式与 CLI 相同。实际含义如下:
|
||||
- 范围:
|
||||
- 枚举每个已注册的图像生成提供商插件
|
||||
- 在探测前从你的登录 shell(`~/.profile`)中加载缺失的提供商环境变量
|
||||
- 默认优先使用 live / 环境变量 API 密钥,而不是已存储的 auth profiles,这样 `auth-profiles.json` 里的过期测试密钥就不会掩盖真实的 shell 凭证
|
||||
- 跳过没有可用 auth / profile / model 的提供商
|
||||
- 默认优先使用 live/env API 密钥,而不是已存储的认证 profile,因此 `auth-profiles.json` 中过期的测试密钥不会掩盖你 shell 中真实可用的凭证
|
||||
- 跳过没有可用认证/profile/模型的提供商
|
||||
- 通过共享运行时能力运行标准图像生成变体:
|
||||
- `google:flash-generate`
|
||||
- `google:pro-generate`
|
||||
@ -470,108 +471,177 @@ Live 测试发现凭证的方式与 CLI 相同。实际含义如下:
|
||||
- `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-store 身份验证并忽略仅环境变量的覆盖
|
||||
- 可选认证行为:
|
||||
- `OPENCLAW_LIVE_REQUIRE_PROFILE_KEYS=1` 强制使用 profile 存储认证并忽略仅环境变量的覆盖
|
||||
|
||||
## 音乐生成 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`)中加载提供商环境变量
|
||||
- 跳过没有可用 auth / profile / model 的提供商
|
||||
- 默认优先使用 live/env API 密钥,而不是已存储的认证 profile,因此 `auth-profiles.json` 中过期的测试密钥不会掩盖你 shell 中真实可用的凭证
|
||||
- 跳过没有可用认证/profile/模型的提供商
|
||||
- 在可用时运行两个已声明的运行时模式:
|
||||
- `generate`:仅使用提示词输入
|
||||
- `edit`:当提供商声明 `capabilities.edit.enabled` 时
|
||||
- 当前共享 lane 覆盖:
|
||||
- `google`:`generate`、`edit`
|
||||
- `minimax`:`generate`
|
||||
- `comfy`:使用单独的 Comfy live 文件,不在这个共享扫描中
|
||||
- 可选缩小范围:
|
||||
- `OPENCLAW_LIVE_MUSIC_GENERATION_PROVIDERS="google,minimax"`
|
||||
- `OPENCLAW_LIVE_MUSIC_GENERATION_MODELS="google/lyria-3-clip-preview,minimax/music-2.5+"`
|
||||
- 可选认证行为:
|
||||
- `OPENCLAW_LIVE_REQUIRE_PROFILE_KEYS=1` 强制使用 profile 存储认证并忽略仅环境变量的覆盖
|
||||
|
||||
## Docker 运行器(可选的“在 Linux 中可工作”检查)
|
||||
## 视频生成 live
|
||||
|
||||
这些 Docker 运行器分为两类:
|
||||
- 测试:`extensions/video-generation-providers.live.test.ts`
|
||||
- 启用:`OPENCLAW_LIVE_TEST=1 pnpm test:live -- extensions/video-generation-providers.live.test.ts`
|
||||
- 范围:
|
||||
- 测试共享的内置视频生成提供商路径
|
||||
- 在探测前从你的登录 shell(`~/.profile`)中加载提供商环境变量
|
||||
- 默认优先使用 live/env API 密钥,而不是已存储的认证 profile,因此 `auth-profiles.json` 中过期的测试密钥不会掩盖你 shell 中真实可用的凭证
|
||||
- 跳过没有可用认证/profile/模型的提供商
|
||||
- 在可用时运行两个已声明的运行时模式:
|
||||
- `generate`:仅使用提示词输入
|
||||
- `imageToVideo`:当提供商声明 `capabilities.imageToVideo.enabled` 时
|
||||
- `videoToVideo`:当提供商声明 `capabilities.videoToVideo.enabled` 且所选提供商/模型在共享扫描中接受基于 buffer 的本地视频输入时
|
||||
- 当前 `videoToVideo` live 覆盖:
|
||||
- `google`
|
||||
- `openai`
|
||||
- 仅当所选模型是 `runway/gen4_aleph` 时包含 `runway`
|
||||
- 当前在共享扫描中已声明但跳过的 `videoToVideo` 提供商:
|
||||
- `alibaba`、`qwen`、`xai`,因为这些路径目前要求远程 `http(s)` / MP4 参考 URL
|
||||
- 可选缩小范围:
|
||||
- `OPENCLAW_LIVE_VIDEO_GENERATION_PROVIDERS="google,openai,runway"`
|
||||
- `OPENCLAW_LIVE_VIDEO_GENERATION_MODELS="google/veo-3.1-fast-generate-preview,openai/sora-2,runway/gen4_aleph"`
|
||||
- 可选认证行为:
|
||||
- `OPENCLAW_LIVE_REQUIRE_PROFILE_KEYS=1` 强制使用 profile 存储认证并忽略仅环境变量的覆盖
|
||||
|
||||
- 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 扫描仍然具有可行性:
|
||||
## Docker 运行器(可选的“在 Linux 中可用”检查)
|
||||
|
||||
这些 Docker 运行器分成两类:
|
||||
|
||||
- Live 模型运行器:`test:docker:live-models` 和 `test:docker:live-gateway` 只会在仓库 Docker 镜像中运行各自匹配的 profile-key live 文件(`src/agents/models.profiles.live.test.ts` 和 `src/gateway/gateway-models.profiles.live.test.ts`),并挂载你的本地配置目录和工作区(如果挂载了 `~/.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` 构建一次 live Docker 镜像,然后在两个 live 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 lane 中复用它。
|
||||
- 容器冒烟运行器:`test:docker:openwebui`、`test:docker:onboard`、`test:docker:gateway-network`、`test:docker:mcp-channels` 和 `test:docker:plugins` 会启动一个或多个真实容器,并验证更高层的集成路径。
|
||||
|
||||
Live 模型 Docker 运行器还会只绑定挂载所需的 CLI auth home(若运行未缩小范围,则挂载所有受支持项),然后在运行前将它们复制到容器 home 中,这样外部 CLI OAuth 就可以刷新令牌,而不会修改主机 auth 存储:
|
||||
Live 模型 Docker 运行器还会只绑定挂载所需的 CLI 认证 home(如果运行未缩小范围,则挂载所有支持的 home),然后在运行前将其复制到容器 home 中,以便外部 CLI OAuth 可以刷新令牌而不修改主机认证存储:
|
||||
|
||||
- 直接模型:`pnpm test:docker:live-models`(脚本:`scripts/test-live-models-docker.sh`)
|
||||
- ACP 绑定冒烟测试:`pnpm test:docker:live-acp-bind`(脚本:`scripts/test-live-acp-bind-docker.sh`)
|
||||
- CLI 后端冒烟测试:`pnpm test:docker:live-cli-backend`(脚本:`scripts/test-live-cli-backend-docker.sh`)
|
||||
- Direct models:`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 live 冒烟测试:`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 渠道桥接(已播种的 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 通知帧冒烟):`pnpm test:docker:mcp-channels`(脚本:`scripts/e2e/mcp-channels-docker.sh`)
|
||||
- 插件(安装冒烟 + `/plugin` 别名 + Claude bundle 重启语义):`pnpm test:docker:plugins`(脚本:`scripts/e2e/plugins-docker.sh`)
|
||||
|
||||
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 恰好暴露了什么。
|
||||
Live 模型 Docker 运行器还会以只读方式绑定挂载当前检出,
|
||||
并将其暂存到容器内的临时 workdir 中。这样既能保持运行时
|
||||
镜像精简,又能让 Vitest 针对你当前本地的源文件/配置准确运行。
|
||||
暂存步骤会跳过大型本地专用缓存和应用构建输出,例如
|
||||
`.pnpm-store`、`.worktrees`、`__openclaw_vitest__` 以及应用本地 `.build` 或
|
||||
Gradle 输出目录,因此 Docker live 运行不会花上数分钟去复制
|
||||
机器专属产物。
|
||||
它们还会设置 `OPENCLAW_SKIP_CHANNELS=1`,这样 Gateway 网关 live probe 就不会在容器内启动
|
||||
真实的 Telegram/Discord 等渠道 worker。
|
||||
`test:docker:live-models` 仍会运行 `pnpm test:live`,因此当你需要缩小范围或排除该 Docker lane 中的 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 也可能需要完成其自身的冷启动设置。
|
||||
这个 lane 需要一个可用的 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 验证路由会话发现、转录读取、附件元数据、
|
||||
live 事件队列行为、出站发送路由,以及 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`,并在运行测试前读取
|
||||
- `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 store(而不是环境变量)
|
||||
- `OPENCLAW_OPENWEBUI_MODEL=...` 选择 Gateway 网关 为 Open WebUI 冒烟测试暴露的模型
|
||||
- `OPENCLAW_OPENWEBUI_PROMPT=...` 覆盖 Open WebUI 冒烟测试使用的 nonce 检查提示词
|
||||
- 缩小到特定提供商的运行只会挂载由 `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 镜像标签
|
||||
|
||||
## 文档完整性检查
|
||||
|
||||
修改文档后运行文档检查:`pnpm check:docs`。
|
||||
如需同时检查页内标题锚点,运行完整 Mintlify 锚点验证:`pnpm docs:check-links:anchors`。
|
||||
当你还需要完整的 Mintlify 锚点校验(包括页内标题检查)时,运行:`pnpm docs:check-links:anchors`。
|
||||
|
||||
## 离线回归测试(CI 安全)
|
||||
## 离线回归(CI 安全)
|
||||
|
||||
这些是不依赖真实提供商的“真实流水线”回归测试:
|
||||
这些是在不接入真实提供商的情况下,覆盖“真实流水线”的回归测试:
|
||||
|
||||
- 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”)
|
||||
- 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`,强制写入 config + auth):`src/gateway/gateway.test.ts`(用例:“runs wizard over ws and writes auth token config”)
|
||||
|
||||
## 智能体可靠性评估(Skills)
|
||||
|
||||
我们已经有一些 CI 安全的测试,它们的行为类似“智能体可靠性评估”:
|
||||
我们已经有一些 CI 安全的测试,其行为类似“智能体可靠性评估”:
|
||||
|
||||
- 通过真实 Gateway 网关 + 智能体循环进行模拟工具调用(`src/gateway/gateway.test.ts`)。
|
||||
- 验证会话布线和配置效果的端到端向导流程(`src/gateway/gateway.test.ts`)。
|
||||
- 验证会话接线和配置效果的端到端向导流程(`src/gateway/gateway.test.ts`)。
|
||||
|
||||
对于 Skills,仍然缺少的内容(参见 [Skills](/zh-CN/tools/skills)):
|
||||
对于 Skills(参见 [Skills](/zh-CN/tools/skills)),当前仍缺少:
|
||||
|
||||
- **决策能力:** 当提示词中列出 Skills 时,智能体是否会选择正确的技能(或避开无关技能)?
|
||||
- **合规性:** 智能体是否会在使用前读取 `SKILL.md`,并遵守必需的步骤 / 参数?
|
||||
- **决策能力:** 当提示词中列出 Skills 时,智能体是否会选择正确的 Skill(或避开无关 Skill)?
|
||||
- **合规性:** 智能体在使用前是否会读取 `SKILL.md`,并遵循要求的步骤/参数?
|
||||
- **工作流契约:** 断言工具顺序、会话历史延续以及沙箱边界的多轮场景。
|
||||
|
||||
未来的评估应优先保持确定性:
|
||||
|
||||
- 一个使用模拟提供商的场景运行器,用于断言工具调用 + 顺序、技能文件读取和会话布线。
|
||||
- 一小组面向技能的场景测试(使用 vs 避免、门控、提示词注入)。
|
||||
- 只有在 CI 安全测试套件建立之后,才增加可选的 live 评估(选择加入、环境变量门控)。
|
||||
- 一个使用模拟提供商的场景运行器,用于断言工具调用 + 顺序、Skill 文件读取以及会话接线。
|
||||
- 一小组面向 Skill 的场景(使用 vs 避免、门控、提示注入)。
|
||||
- 只有在 CI 安全套件到位后,再提供可选的 live 评估(按需启用、受环境变量控制)。
|
||||
|
||||
## 契约测试(插件和渠道形状)
|
||||
|
||||
契约测试用于验证每个已注册插件和渠道都符合其接口契约。它们会遍历所有发现到的插件,并运行一组形状和行为断言。默认的 `pnpm test` 单元通道会刻意跳过这些共享接缝和冒烟测试文件;当你触及共享渠道或提供商接口时,请显式运行契约命令。
|
||||
契约测试用于验证每个已注册插件和渠道是否符合其
|
||||
接口契约。它们会遍历所有已发现插件,并运行一套
|
||||
形状和行为断言。默认的 `pnpm test` 单元 lane 会刻意
|
||||
跳过这些共享接缝和冒烟文件;当你修改共享渠道或提供商接口时,
|
||||
请显式运行契约命令。
|
||||
|
||||
### 命令
|
||||
|
||||
@ -586,11 +656,11 @@ Live 模型 Docker 运行器还会以只读方式绑定挂载当前检出内容
|
||||
- **plugin** - 基本插件形状(id、名称、能力)
|
||||
- **setup** - 设置向导契约
|
||||
- **session-binding** - 会话绑定行为
|
||||
- **outbound-payload** - 消息负载结构
|
||||
- **outbound-payload** - 消息载荷结构
|
||||
- **inbound** - 入站消息处理
|
||||
- **actions** - 渠道动作处理器
|
||||
- **actions** - 渠道操作处理器
|
||||
- **threading** - 线程 ID 处理
|
||||
- **directory** - 目录 / 花名册 API
|
||||
- **directory** - 目录/成员列表 API
|
||||
- **group-policy** - 群组策略执行
|
||||
|
||||
### 提供商状态契约
|
||||
@ -604,32 +674,32 @@ Live 模型 Docker 运行器还会以只读方式绑定挂载当前检出内容
|
||||
|
||||
位于 `src/plugins/contracts/*.contract.test.ts`:
|
||||
|
||||
- **auth** - 身份验证流程契约
|
||||
- **auth-choice** - 身份验证选择 / 选择逻辑
|
||||
- **auth** - 认证流程契约
|
||||
- **auth-choice** - 认证方式/选择
|
||||
- **catalog** - 模型目录 API
|
||||
- **discovery** - 插件发现
|
||||
- **loader** - 插件加载
|
||||
- **runtime** - 提供商运行时
|
||||
- **shape** - 插件形状 / 接口
|
||||
- **shape** - 插件形状/接口
|
||||
- **wizard** - 设置向导
|
||||
|
||||
### 何时运行
|
||||
|
||||
- 在修改 plugin-sdk 导出或子路径之后
|
||||
- 在添加或修改渠道或提供商插件之后
|
||||
- 在重构插件注册或发现逻辑之后
|
||||
- 修改 `plugin-sdk` 导出或子路径之后
|
||||
- 新增或修改渠道插件或提供商插件之后
|
||||
- 重构插件注册或发现逻辑之后
|
||||
|
||||
契约测试会在 CI 中运行,不需要真实 API 密钥。
|
||||
|
||||
## 添加回归测试(指南)
|
||||
|
||||
当你修复 live 中发现的提供商 / 模型问题时:
|
||||
当你修复了一个在 live 中发现的提供商/模型问题时:
|
||||
|
||||
- 如果可能,添加一个 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 未分类时故意失败,这样新类别就无法被悄悄跳过。
|
||||
- 如果可能,添加一个 CI 安全的回归测试(模拟/存根提供商,或捕获确切的请求形状转换)
|
||||
- 如果问题天然只能在 live 中复现(限流、认证策略),请让 live 测试保持范围小,并通过环境变量按需启用
|
||||
- 优先瞄准能捕获该 bug 的最小层级:
|
||||
- 提供商请求转换/回放 bug → direct models 测试
|
||||
- Gateway 网关会话/历史/工具流水线 bug → Gateway 网关 live 冒烟或 CI 安全的 Gateway 网关模拟测试
|
||||
- SecretRef 遍历防护规则:
|
||||
- `src/secrets/exec-secret-ref-id-parity.test.ts` 会从注册表元数据(`listSecretTargetRegistryEntries()`)中为每个 SecretRef 类推导出一个采样目标,然后断言会拒绝 traversal-segment exec id。
|
||||
- 如果你在 `src/secrets/target-registry-data.ts` 中添加了新的 `includeInPlan` SecretRef 目标家族,请更新该测试中的 `classifyTargetClass`。该测试会在遇到未分类目标 id 时有意失败,以防新的类别被静默跳过。
|
||||
|
||||
@ -0,0 +1,509 @@
|
||||
---
|
||||
date: 2026-04-05T00:00:00Z
|
||||
status: active
|
||||
title: 重构:逐步将 plugin-sdk 变成真正的工作区包
|
||||
type: refactor
|
||||
x-i18n:
|
||||
generated_at: "2026-04-06T15:29:40Z"
|
||||
model: gpt-5.4
|
||||
provider: openai
|
||||
source_hash: ea1ca41846363c506a0db6dbca746e840d7c71ca82bbfc5277af9e2ae7f6b070
|
||||
source_path: plans/2026-04-05-002-refactor-real-plugin-sdk-workspace-plan.md
|
||||
workflow: 15
|
||||
---
|
||||
|
||||
# 重构:逐步将 plugin-sdk 变成真正的工作区包
|
||||
|
||||
## 概述
|
||||
|
||||
该计划在 `packages/plugin-sdk` 下为插件 SDK 引入一个真正的工作区包,并用它让第一批少量扩展选择性地接入由编译器强制执行的包边界。目标是让非法相对导入在普通 `tsc` 下对选定的一组内置 provider 扩展直接失败,而不强制进行全仓库迁移,也不制造一个巨大的合并冲突面。
|
||||
|
||||
关键的渐进式动作是在一段时间内并行运行两种模式:
|
||||
|
||||
| 模式 | 导入形态 | 使用者 | 强制机制 |
|
||||
| ----------- | ------------------------ | ------------------------------------ | -------------------------------------------- |
|
||||
| 旧模式 | `openclaw/plugin-sdk/*` | 所有现有未选择接入的扩展 | 保持当前宽松行为 |
|
||||
| 选择接入模式 | `@openclaw/plugin-sdk/*` | 仅第一批扩展 | 包本地 `rootDir` + 项目引用 |
|
||||
|
||||
## 问题框架
|
||||
|
||||
当前仓库导出了一个庞大的公共插件 SDK 表面,但它并不是真正的工作区包。而是:
|
||||
|
||||
- 根 `tsconfig.json` 将 `openclaw/plugin-sdk/*` 直接映射到
|
||||
`src/plugin-sdk/*.ts`
|
||||
- 未选择接入先前实验的扩展仍然共享这种
|
||||
全局源码别名行为
|
||||
- 只有在允许的 SDK 导入不再解析到扩展包之外的原始仓库源码后,添加 `rootDir` 才会生效
|
||||
|
||||
这意味着仓库可以描述期望的边界策略,但 TypeScript 无法对大多数扩展清晰地强制执行它。
|
||||
|
||||
你需要一条渐进式路径,以便:
|
||||
|
||||
- 让 `plugin-sdk` 变得真实
|
||||
- 将 SDK 迁移为名为 `@openclaw/plugin-sdk` 的工作区包
|
||||
- 在第一个 PR 中只改动大约 10 个扩展
|
||||
- 暂时让其余扩展树继续使用旧方案,等待后续清理
|
||||
- 避免把 `tsconfig.plugin-sdk.dts.json` + postinstall 生成声明文件的流程作为第一批 rollout 的主要机制
|
||||
|
||||
## 需求追踪
|
||||
|
||||
- R1. 在 `packages/` 下为插件 SDK 创建一个真正的工作区包。
|
||||
- R2. 将新包命名为 `@openclaw/plugin-sdk`。
|
||||
- R3. 为新的 SDK 包提供独立的 `package.json` 和 `tsconfig.json`。
|
||||
- R4. 在迁移窗口期间,为未选择接入的扩展保留旧的
|
||||
`openclaw/plugin-sdk/*` 导入可用。
|
||||
- R5. 在第一个 PR 中只让少量第一批扩展选择接入。
|
||||
- R6. 对第一批扩展,离开其包根目录的相对导入必须以失败关闭。
|
||||
- R7. 第一批扩展必须通过包依赖和 TS 项目引用来使用 SDK,
|
||||
而不是通过根 `paths` 别名。
|
||||
- R8. 该计划必须避免为编辑器正确性引入全仓库强制性的 postinstall 生成步骤。
|
||||
- R9. 第一批 rollout 必须能以中等规模 PR 的形式审阅和合并,
|
||||
而不是一次全仓库 300+ 文件的重构。
|
||||
|
||||
## 范围边界
|
||||
|
||||
- 第一个 PR 不进行所有内置扩展的完整迁移。
|
||||
- 第一个 PR 不要求删除 `src/plugin-sdk`。
|
||||
- 第一个 PR 不要求立即将每个根构建或测试路径都改为使用新包。
|
||||
- 不尝试为每个未选择接入的扩展都强制提供 VS Code 红线提示。
|
||||
- 不为扩展树其余部分做大范围 lint 清理。
|
||||
- 除了导入解析、包归属和对选择接入扩展的边界强制之外,不引入大的运行时行为变化。
|
||||
|
||||
## 上下文与研究
|
||||
|
||||
### 相关代码和模式
|
||||
|
||||
- `pnpm-workspace.yaml` 已经包含 `packages/*` 和 `extensions/*`,因此在 `packages/plugin-sdk` 下添加新的工作区包符合现有仓库布局。
|
||||
- 现有工作区包,例如 `packages/memory-host-sdk/package.json`
|
||||
和 `packages/plugin-package-contract/package.json`,已经使用以 `src/*.ts` 为根的包本地 `exports` 映射。
|
||||
- 根 `package.json` 当前通过 `./plugin-sdk`
|
||||
和 `./plugin-sdk/*` 导出 SDK 表面,其后端为 `dist/plugin-sdk/*.js` 和
|
||||
`dist/plugin-sdk/*.d.ts`。
|
||||
- `src/plugin-sdk/entrypoints.ts` 和 `scripts/lib/plugin-sdk-entrypoints.json`
|
||||
已经充当 SDK 表面的规范入口点清单。
|
||||
- 根 `tsconfig.json` 当前映射:
|
||||
- `openclaw/plugin-sdk` -> `src/plugin-sdk/index.ts`
|
||||
- `openclaw/plugin-sdk/*` -> `src/plugin-sdk/*.ts`
|
||||
- 先前的边界实验表明,只有在允许的 SDK 导入不再解析到扩展包之外的原始源码后,包本地 `rootDir` 才会对非法相对导入生效。
|
||||
|
||||
### 第一批扩展集合
|
||||
|
||||
该计划假定第一批是 provider 较重的一组,因为它们最不容易牵涉复杂的渠道运行时边缘情况:
|
||||
|
||||
- `extensions/anthropic`
|
||||
- `extensions/exa`
|
||||
- `extensions/firecrawl`
|
||||
- `extensions/groq`
|
||||
- `extensions/mistral`
|
||||
- `extensions/openai`
|
||||
- `extensions/perplexity`
|
||||
- `extensions/tavily`
|
||||
- `extensions/together`
|
||||
- `extensions/xai`
|
||||
|
||||
### 第一批 SDK 表面清单
|
||||
|
||||
第一批扩展当前导入的是一组可控的 SDK 子路径。初始的 `@openclaw/plugin-sdk` 包只需要覆盖这些:
|
||||
|
||||
- `agent-runtime`
|
||||
- `cli-runtime`
|
||||
- `config-runtime`
|
||||
- `core`
|
||||
- `image-generation`
|
||||
- `media-runtime`
|
||||
- `media-understanding`
|
||||
- `plugin-entry`
|
||||
- `plugin-runtime`
|
||||
- `provider-auth`
|
||||
- `provider-auth-api-key`
|
||||
- `provider-auth-login`
|
||||
- `provider-auth-runtime`
|
||||
- `provider-catalog-shared`
|
||||
- `provider-entry`
|
||||
- `provider-http`
|
||||
- `provider-model-shared`
|
||||
- `provider-onboard`
|
||||
- `provider-stream-family`
|
||||
- `provider-stream-shared`
|
||||
- `provider-tools`
|
||||
- `provider-usage`
|
||||
- `provider-web-fetch`
|
||||
- `provider-web-search`
|
||||
- `realtime-transcription`
|
||||
- `realtime-voice`
|
||||
- `runtime-env`
|
||||
- `secret-input`
|
||||
- `security-runtime`
|
||||
- `speech`
|
||||
- `testing`
|
||||
|
||||
### 制度性经验
|
||||
|
||||
- 该工作树中没有相关的 `docs/solutions/` 条目。
|
||||
|
||||
### 外部参考
|
||||
|
||||
- 该计划不需要外部研究。仓库中已经包含相关的工作区包和 SDK 导出模式。
|
||||
|
||||
## 关键技术决策
|
||||
|
||||
- 在迁移期间引入 `@openclaw/plugin-sdk` 作为新的工作区包,同时保留旧的根 `openclaw/plugin-sdk/*` 表面。
|
||||
理由:这样可以让第一批扩展集合迁移到真正的包解析方式,而无需同时更改所有扩展和所有根构建路径。
|
||||
|
||||
- 使用专门的选择接入边界基础配置,例如
|
||||
`extensions/tsconfig.package-boundary.base.json`,而不是替换所有人现有的扩展基础配置。
|
||||
理由:仓库在迁移期间需要同时支持旧模式和选择接入模式两种扩展模式。
|
||||
|
||||
- 对第一批扩展使用指向
|
||||
`packages/plugin-sdk/tsconfig.json` 的 TS 项目引用,并为选择接入边界模式设置
|
||||
`disableSourceOfProjectReferenceRedirect`。
|
||||
理由:这为 `tsc` 提供了真实的包图,同时抑制编辑器和编译器回退到原始源码遍历。
|
||||
|
||||
- 在第一批中保持 `@openclaw/plugin-sdk` 为私有。
|
||||
理由:眼下的目标是内部边界强制与迁移安全,而不是在表面尚未稳定之前就发布第二份外部 SDK 合约。
|
||||
|
||||
- 第一轮实现只迁移第一批 SDK 子路径,其余部分保留兼容桥接。
|
||||
理由:在一个 PR 中物理移动 `src/plugin-sdk/*.ts` 下全部 315 个文件,正是这个计划试图避免的合并冲突面。
|
||||
|
||||
- 第一批不要依赖 `scripts/postinstall-bundled-plugins.mjs` 来构建 SDK 声明文件。
|
||||
理由:显式的构建/引用流程更容易理解,也能让仓库行为更可预测。
|
||||
|
||||
## 开放问题
|
||||
|
||||
### 规划期间已解决
|
||||
|
||||
- 哪些扩展应纳入第一批?
|
||||
使用上面列出的 10 个 provider/web-search 扩展,因为它们在结构上比更重的渠道包更独立。
|
||||
|
||||
- 第一个 PR 是否应替换整个扩展树?
|
||||
不。第一个 PR 应并行支持两种模式,并且只让第一批选择接入。
|
||||
|
||||
- 第一批是否应要求 postinstall 声明构建?
|
||||
不。包/引用图应显式可见,CI 应有意运行相关的包本地 typecheck。
|
||||
|
||||
### 延后到实现阶段
|
||||
|
||||
- 第一批包是否可以仅通过项目引用直接指向包本地 `src/*.ts`,还是
|
||||
`@openclaw/plugin-sdk` 包仍需要一个小型声明文件发射步骤。
|
||||
这是一个由实现阶段决定的 TS 图验证问题。
|
||||
|
||||
- 根 `openclaw` 包是否应立即将第一批 SDK 子路径代理到
|
||||
`packages/plugin-sdk` 的输出,还是继续使用
|
||||
`src/plugin-sdk` 下生成的兼容 shim。
|
||||
这是一个兼容性和构建形态细节问题,取决于哪种最小实现路径能保持 CI 绿色。
|
||||
|
||||
## 高层技术设计
|
||||
|
||||
> 此处用于说明预期方法,属于供审阅参考的方向性指导,而不是实现规范。实施该变更的智能体应将其视为上下文,而不是需要照抄的代码。
|
||||
|
||||
```mermaid
|
||||
flowchart TB
|
||||
subgraph Legacy["旧模式扩展(不变)"]
|
||||
L1["extensions/*\nopenclaw/plugin-sdk/*"]
|
||||
L2["根 tsconfig paths"]
|
||||
L1 --> L2
|
||||
L2 --> L3["src/plugin-sdk/*"]
|
||||
end
|
||||
|
||||
subgraph OptIn["第一批扩展"]
|
||||
O1["10 个选择接入的扩展"]
|
||||
O2["extensions/tsconfig.package-boundary.base.json"]
|
||||
O3["rootDir = '.'\n项目引用"]
|
||||
O4["@openclaw/plugin-sdk"]
|
||||
O1 --> O2
|
||||
O2 --> O3
|
||||
O3 --> O4
|
||||
end
|
||||
|
||||
subgraph SDK["新的工作区包"]
|
||||
P1["packages/plugin-sdk/package.json"]
|
||||
P2["packages/plugin-sdk/tsconfig.json"]
|
||||
P3["packages/plugin-sdk/src/<first-wave-subpaths>.ts"]
|
||||
P1 --> P2
|
||||
P2 --> P3
|
||||
end
|
||||
|
||||
O4 --> SDK
|
||||
```
|
||||
|
||||
## 实施单元
|
||||
|
||||
- [ ] **单元 1:引入真正的 `@openclaw/plugin-sdk` 工作区包**
|
||||
|
||||
**目标:** 为 SDK 创建一个真正的工作区包,使其能够拥有第一批子路径表面,而不强制进行全仓库迁移。
|
||||
|
||||
**需求:** R1、R2、R3、R8、R9
|
||||
|
||||
**依赖:** 无
|
||||
|
||||
**文件:**
|
||||
|
||||
- 创建:`packages/plugin-sdk/package.json`
|
||||
- 创建:`packages/plugin-sdk/tsconfig.json`
|
||||
- 创建:`packages/plugin-sdk/src/index.ts`
|
||||
- 创建:第一批 SDK 子路径对应的 `packages/plugin-sdk/src/*.ts`
|
||||
- 修改:仅在需要调整包 glob 时修改 `pnpm-workspace.yaml`
|
||||
- 修改:`package.json`
|
||||
- 修改:`src/plugin-sdk/entrypoints.ts`
|
||||
- 修改:`scripts/lib/plugin-sdk-entrypoints.json`
|
||||
- 测试:`src/plugins/contracts/plugin-sdk-workspace-package.contract.test.ts`
|
||||
|
||||
**方法:**
|
||||
|
||||
- 添加一个名为 `@openclaw/plugin-sdk` 的新工作区包。
|
||||
- 初始只包含第一批 SDK 子路径,而不是整个 315 文件树。
|
||||
- 如果直接移动某个第一批入口点会导致 diff 过大,那么第一个 PR
|
||||
可以先在 `packages/plugin-sdk/src` 中以薄包装器的形式引入该子路径,
|
||||
然后在后续 PR 中再把该子路径簇的真正规范源码切换到该包。
|
||||
- 复用现有入口点清单机制,以便在一个规范位置声明第一批包表面。
|
||||
- 在工作区包成为新的选择接入合约时,继续保留根包导出供旧用户使用。
|
||||
|
||||
**应遵循的模式:**
|
||||
|
||||
- `packages/memory-host-sdk/package.json`
|
||||
- `packages/plugin-package-contract/package.json`
|
||||
- `src/plugin-sdk/entrypoints.ts`
|
||||
|
||||
**测试场景:**
|
||||
|
||||
- 正常路径:工作区包导出计划中列出的每个第一批子路径,且没有缺失任何所需的第一批导出。
|
||||
- 边缘情况:当重新生成第一批入口列表或将其与规范清单比较时,包导出元数据保持稳定。
|
||||
- 集成:引入新的工作区包后,根包中的旧版 SDK 导出仍然存在。
|
||||
|
||||
**验证:**
|
||||
|
||||
- 仓库中存在一个有效的 `@openclaw/plugin-sdk` 工作区包,
|
||||
具有稳定的第一批导出映射,并且根 `package.json`
|
||||
中没有旧版导出回归。
|
||||
|
||||
- [ ] **单元 2:为包级强制边界扩展添加选择接入的 TS 边界模式**
|
||||
|
||||
**目标:** 定义选择接入扩展将使用的 TS 配置模式,同时为其他所有扩展保留现有扩展 TS 行为不变。
|
||||
|
||||
**需求:** R4、R6、R7、R8、R9
|
||||
|
||||
**依赖:** 单元 1
|
||||
|
||||
**文件:**
|
||||
|
||||
- 创建:`extensions/tsconfig.package-boundary.base.json`
|
||||
- 创建:`tsconfig.boundary-optin.json`
|
||||
- 修改:`extensions/xai/tsconfig.json`
|
||||
- 修改:`extensions/openai/tsconfig.json`
|
||||
- 修改:`extensions/anthropic/tsconfig.json`
|
||||
- 修改:`extensions/mistral/tsconfig.json`
|
||||
- 修改:`extensions/groq/tsconfig.json`
|
||||
- 修改:`extensions/together/tsconfig.json`
|
||||
- 修改:`extensions/perplexity/tsconfig.json`
|
||||
- 修改:`extensions/tavily/tsconfig.json`
|
||||
- 修改:`extensions/exa/tsconfig.json`
|
||||
- 修改:`extensions/firecrawl/tsconfig.json`
|
||||
- 测试:`src/plugins/contracts/extension-package-project-boundaries.test.ts`
|
||||
- 测试:`test/extension-package-tsc-boundary.test.ts`
|
||||
|
||||
**方法:**
|
||||
|
||||
- 为旧模式扩展保留 `extensions/tsconfig.base.json`。
|
||||
- 添加一个新的选择接入基础配置,它:
|
||||
- 设置 `rootDir: "."`
|
||||
- 引用 `packages/plugin-sdk`
|
||||
- 启用 `composite`
|
||||
- 在需要时禁用项目引用源码重定向
|
||||
- 添加一个专用的第一批 typecheck 解决方案配置,而不是在同一个 PR 中重塑根仓库 TS 项目。
|
||||
|
||||
**执行说明:** 在把模式扩展到全部 10 个扩展前,先从一个已选择接入扩展的失败包本地 canary typecheck 开始。
|
||||
|
||||
**应遵循的模式:**
|
||||
|
||||
- 先前边界工作中的现有包本地扩展 `tsconfig.json` 模式
|
||||
- 来自 `packages/memory-host-sdk` 的工作区包模式
|
||||
|
||||
**测试场景:**
|
||||
|
||||
- 正常路径:每个已选择接入的扩展都能通过包边界 TS 配置成功 typecheck。
|
||||
- 错误路径:对于已选择接入扩展,来自 `../../src/cli/acp-cli.ts` 的 canary 非法相对导入会以 `TS6059` 失败。
|
||||
- 集成:未选择接入的扩展保持不变,不需要参与新的解决方案配置。
|
||||
|
||||
**验证:**
|
||||
|
||||
- 针对这 10 个已选择接入扩展有一个专用的 typecheck 图,而且其中之一的错误相对导入会通过普通 `tsc` 失败。
|
||||
|
||||
- [ ] **单元 3:将第一批扩展迁移到 `@openclaw/plugin-sdk`**
|
||||
|
||||
**目标:** 让第一批扩展通过依赖元数据、项目引用和包名导入来使用真正的 SDK 包。
|
||||
|
||||
**需求:** R5、R6、R7、R9
|
||||
|
||||
**依赖:** 单元 2
|
||||
|
||||
**文件:**
|
||||
|
||||
- 修改:`extensions/anthropic/package.json`
|
||||
- 修改:`extensions/exa/package.json`
|
||||
- 修改:`extensions/firecrawl/package.json`
|
||||
- 修改:`extensions/groq/package.json`
|
||||
- 修改:`extensions/mistral/package.json`
|
||||
- 修改:`extensions/openai/package.json`
|
||||
- 修改:`extensions/perplexity/package.json`
|
||||
- 修改:`extensions/tavily/package.json`
|
||||
- 修改:`extensions/together/package.json`
|
||||
- 修改:`extensions/xai/package.json`
|
||||
- 修改:上述 10 个扩展根目录下当前引用 `openclaw/plugin-sdk/*`
|
||||
的生产与测试导入
|
||||
|
||||
**方法:**
|
||||
|
||||
- 将 `@openclaw/plugin-sdk: workspace:*` 添加到第一批扩展的
|
||||
`devDependencies`。
|
||||
- 将这些包中的 `openclaw/plugin-sdk/*` 导入替换为
|
||||
`@openclaw/plugin-sdk/*`。
|
||||
- 保持扩展内部本地导入通过诸如 `./api.ts` 和 `./runtime-api.ts` 这样的本地 barrel。
|
||||
- 本 PR 中不修改未选择接入的扩展。
|
||||
|
||||
**应遵循的模式:**
|
||||
|
||||
- 现有扩展本地导入 barrel(`api.ts`、`runtime-api.ts`)
|
||||
- 其他 `@openclaw/*` 工作区包所使用的包依赖形态
|
||||
|
||||
**测试场景:**
|
||||
|
||||
- 正常路径:每个已迁移扩展在导入改写后,仍然能通过其现有插件测试完成注册/加载。
|
||||
- 边缘情况:已选择接入扩展集合中的仅测试用 SDK 导入,仍然可以通过新包正确解析。
|
||||
- 集成:已迁移扩展在 typecheck 时不再依赖根 `openclaw/plugin-sdk/*`
|
||||
别名路径。
|
||||
|
||||
**验证:**
|
||||
|
||||
- 第一批扩展可以基于 `@openclaw/plugin-sdk` 构建和测试,
|
||||
不需要旧的根 SDK 别名路径。
|
||||
|
||||
- [ ] **单元 4:在部分迁移期间保留旧版兼容性**
|
||||
|
||||
**目标:** 在 SDK 以旧版和新包两种形式同时存在的迁移期间,让仓库其余部分继续正常工作。
|
||||
|
||||
**需求:** R4、R8、R9
|
||||
|
||||
**依赖:** 单元 1-3
|
||||
|
||||
**文件:**
|
||||
|
||||
- 修改:根据需要修改第一批兼容 shim 对应的 `src/plugin-sdk/*.ts`
|
||||
- 修改:`package.json`
|
||||
- 修改:组装 SDK 工件的构建或导出管线
|
||||
- 测试:`src/plugins/contracts/plugin-sdk-runtime-api-guardrails.test.ts`
|
||||
- 测试:`src/plugins/contracts/plugin-sdk-index.bundle.test.ts`
|
||||
|
||||
**方法:**
|
||||
|
||||
- 保留根 `openclaw/plugin-sdk/*` 作为未迁移旧扩展以及尚未迁移的外部使用者的兼容性表面。
|
||||
- 对已移动到 `packages/plugin-sdk` 的第一批子路径,使用生成的 shim 或根导出代理接线。
|
||||
- 在这个阶段不要尝试淘汰根 SDK 表面。
|
||||
|
||||
**应遵循的模式:**
|
||||
|
||||
- 通过 `src/plugin-sdk/entrypoints.ts` 生成现有根 SDK 导出
|
||||
- 根 `package.json` 中现有的包导出兼容性
|
||||
|
||||
**测试场景:**
|
||||
|
||||
- 正常路径:在新包存在后,非选择接入扩展的旧版根 SDK 导入仍然可以解析。
|
||||
- 边缘情况:迁移窗口期间,第一批某个子路径可以同时通过旧的根表面和新的包表面工作。
|
||||
- 集成:plugin-sdk index/bundle 合约测试继续看到一致的公共表面。
|
||||
|
||||
**验证:**
|
||||
|
||||
- 仓库同时支持旧模式和选择接入模式两种 SDK 使用方式,而不会破坏未变更的扩展。
|
||||
|
||||
- [ ] **单元 5:添加有范围限制的强制机制并记录迁移合约**
|
||||
|
||||
**目标:** 落地 CI 和贡献者指南,以便对第一批强制执行新行为,而不假装整个扩展树都已迁移。
|
||||
|
||||
**需求:** R5、R6、R8、R9
|
||||
|
||||
**依赖:** 单元 1-4
|
||||
|
||||
**文件:**
|
||||
|
||||
- 修改:`package.json`
|
||||
- 修改:应运行选择接入边界 typecheck 的 CI 工作流文件
|
||||
- 修改:`AGENTS.md`
|
||||
- 修改:`docs/plugins/sdk-overview.md`
|
||||
- 修改:`docs/plugins/sdk-entrypoints.md`
|
||||
- 修改:`docs/plans/2026-04-05-001-refactor-extension-package-resolution-boundary-plan.md`
|
||||
|
||||
**方法:**
|
||||
|
||||
- 添加一个显式的第一批 gate,例如为
|
||||
`packages/plugin-sdk` 加上 10 个已选择接入扩展运行专用的 `tsc -b` 解决方案。
|
||||
- 记录仓库现在同时支持旧模式和选择接入模式两种扩展模式,以及新的扩展边界工作应优先采用新包路径。
|
||||
- 记录下一批迁移规则,以便后续 PR 能在不重新争论架构的前提下添加更多扩展。
|
||||
|
||||
**应遵循的模式:**
|
||||
|
||||
- `src/plugins/contracts/` 下现有的合约测试
|
||||
- 解释分阶段迁移的现有文档更新方式
|
||||
|
||||
**测试场景:**
|
||||
|
||||
- 正常路径:新的第一批 typecheck gate 对工作区包和已选择接入扩展通过。
|
||||
- 错误路径:在某个已选择接入扩展中引入新的非法相对导入,会导致有范围限制的 typecheck gate 失败。
|
||||
- 集成:CI 尚不要求未选择接入扩展满足新的包边界模式。
|
||||
|
||||
**验证:**
|
||||
|
||||
- 第一批强制路径已有文档、测试且可运行,而不会强制整个扩展树迁移。
|
||||
|
||||
## 全系统影响
|
||||
|
||||
- **交互图:** 该工作会影响 SDK 规范源码、根包导出、扩展包元数据、TS 图布局和 CI 验证。
|
||||
- **错误传播:** 主要的预期失败模式将变成已选择接入扩展中的编译期 TS
|
||||
错误(`TS6059`),而不是仅靠自定义脚本失败。
|
||||
- **状态生命周期风险:** 双表面迁移会引入根兼容导出与新工作区包之间的漂移风险。
|
||||
- **API 表面一致性:** 在过渡期间,第一批子路径必须通过
|
||||
`openclaw/plugin-sdk/*` 和 `@openclaw/plugin-sdk/*`
|
||||
两种方式保持语义完全一致。
|
||||
- **集成覆盖:** 仅靠单元测试不够;必须有具备范围限制的包图 typecheck 才能证明边界成立。
|
||||
- **未改变的不变量:** 未选择接入的扩展在 PR 1 中保持当前行为。该计划并不声称实现了全仓库导入边界强制。
|
||||
|
||||
## 风险与依赖
|
||||
|
||||
| 风险 | 缓解措施 |
|
||||
| ------------------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------- |
|
||||
| 第一批包仍然会解析回原始源码,导致 `rootDir` 实际上没有以失败关闭 | 将首个实现步骤设为对一个已选择接入扩展进行包引用 canary 验证,在扩展到整个集合前先验证 |
|
||||
| 一次移动过多 SDK 源码会重现最初的合并冲突问题 | 第一个 PR 只移动第一批子路径,并保留根兼容桥接 |
|
||||
| 旧版和新 SDK 表面在语义上发生漂移 | 保持单一入口点清单,添加兼容性合约测试,并明确双表面一致性要求 |
|
||||
| 根仓库的构建/测试路径意外以不可控方式开始依赖新包 | 使用专用的选择接入解决方案配置,并将全仓库 TS 拓扑变更排除在第一个 PR 之外 |
|
||||
|
||||
## 分阶段交付
|
||||
|
||||
### 第一阶段
|
||||
|
||||
- 引入 `@openclaw/plugin-sdk`
|
||||
- 定义第一批子路径表面
|
||||
- 证明一个已选择接入扩展可以通过 `rootDir` 以失败关闭
|
||||
|
||||
### 第二阶段
|
||||
|
||||
- 让 10 个第一批扩展选择接入
|
||||
- 为其他所有扩展保留根兼容性
|
||||
|
||||
### 第三阶段
|
||||
|
||||
- 在后续 PR 中添加更多扩展
|
||||
- 将更多 SDK 子路径迁移到工作区包
|
||||
- 仅在旧扩展集合消失后再淘汰根兼容性
|
||||
|
||||
## 文档 / 运维说明
|
||||
|
||||
- 第一个 PR 应明确说明自己是双模式迁移,而不是全仓库强制完成。
|
||||
- 迁移指南应让后续 PR 可以轻松通过相同的包/依赖/引用模式添加更多扩展。
|
||||
|
||||
## 来源与参考
|
||||
|
||||
- 先前计划:`docs/plans/2026-04-05-001-refactor-extension-package-resolution-boundary-plan.md`
|
||||
- 工作区配置:`pnpm-workspace.yaml`
|
||||
- 现有 SDK 入口点清单:`src/plugin-sdk/entrypoints.ts`
|
||||
- 现有根 SDK 导出:`package.json`
|
||||
- 现有工作区包模式:
|
||||
- `packages/memory-host-sdk/package.json`
|
||||
- `packages/plugin-package-contract/package.json`
|
||||
@ -1,15 +1,15 @@
|
||||
---
|
||||
read_when:
|
||||
- 配对或重新连接 iOS 节点
|
||||
- 从源码运行 iOS 应用
|
||||
- 调试 gateway 发现或 canvas 命令
|
||||
- 配对或重新连接 iOS 节点时
|
||||
- 从源码运行 iOS 应用时
|
||||
- 调试 Gateway 网关发现或 canvas 命令时
|
||||
summary: iOS 节点应用:连接到 Gateway 网关、配对、canvas 和故障排除
|
||||
title: iOS 应用
|
||||
x-i18n:
|
||||
generated_at: "2026-04-05T08:37:38Z"
|
||||
generated_at: "2026-04-06T15:29:25Z"
|
||||
model: gpt-5.4
|
||||
provider: openai
|
||||
source_hash: 1e9d9cec58afd4003dff81d3e367bfbc6a634c1b229e433e08fd78fbb5f2e5a9
|
||||
source_hash: f3e0a6e33e72d4c9f1f17ef70a1b67bae9ebe4a2dca16677ea6b28d0ddac1b4e
|
||||
source_path: platforms/ios.md
|
||||
workflow: 15
|
||||
---
|
||||
@ -21,16 +21,16 @@ x-i18n:
|
||||
## 它的作用
|
||||
|
||||
- 通过 WebSocket 连接到 Gateway 网关(LAN 或 tailnet)。
|
||||
- 提供节点能力:Canvas、屏幕快照、摄像头捕获、位置、对话模式、语音唤醒。
|
||||
- 提供节点能力:Canvas、屏幕快照、相机采集、位置、对讲模式、语音唤醒。
|
||||
- 接收 `node.invoke` 命令并上报节点状态事件。
|
||||
|
||||
## 要求
|
||||
|
||||
- 在另一台设备上运行的 Gateway 网关(macOS、Linux,或通过 WSL2 运行的 Windows)。
|
||||
- Gateway 网关运行在另一台设备上(macOS、Linux,或通过 WSL2 运行的 Windows)。
|
||||
- 网络路径:
|
||||
- 通过 Bonjour 处于同一 LAN,**或**
|
||||
- 通过单播 DNS-SD 的 tailnet(示例域名:`openclaw.internal.`),**或**
|
||||
- 手动输入主机 / 端口(回退方案)。
|
||||
- 通过 tailnet 使用单播 DNS-SD(示例域名:`openclaw.internal.`),**或**
|
||||
- 手动输入主机/端口(回退方案)。
|
||||
|
||||
## 快速开始(配对 + 连接)
|
||||
|
||||
@ -40,17 +40,17 @@ x-i18n:
|
||||
openclaw gateway --port 18789
|
||||
```
|
||||
|
||||
2. 在 iOS 应用中,打开设置并选择一个已发现的 gateway,或者启用 Manual Host 并输入主机 / 端口。
|
||||
2. 在 iOS 应用中,打开 Settings 并选择一个已发现的 Gateway 网关(或者启用 Manual Host 并输入主机/端口)。
|
||||
|
||||
3. 在 gateway 主机上批准配对请求:
|
||||
3. 在 Gateway 网关主机上批准配对请求:
|
||||
|
||||
```bash
|
||||
openclaw devices list
|
||||
openclaw devices approve <requestId>
|
||||
```
|
||||
|
||||
如果应用在认证详情(角色 / scopes / 公钥)变更后重试配对,
|
||||
之前处于待处理状态的请求会被替换,并创建新的 `requestId`。
|
||||
如果应用在认证详情(角色/scopes/公钥)变更后重试配对,
|
||||
之前待处理的请求会被新请求取代,并创建新的 `requestId`。
|
||||
请在批准前再次运行 `openclaw devices list`。
|
||||
|
||||
4. 验证连接:
|
||||
@ -60,10 +60,10 @@ openclaw nodes status
|
||||
openclaw gateway call node.list --params "{}"
|
||||
```
|
||||
|
||||
## 官方构建的基于中继的推送
|
||||
## 官方构建使用基于 relay 的推送
|
||||
|
||||
官方发布的 iOS 构建使用外部推送中继,而不是将原始 APNs
|
||||
令牌直接发布到 gateway。
|
||||
官方发布的 iOS 构建会使用外部推送 relay,而不是将原始 APNs
|
||||
token 直接发布到 Gateway 网关。
|
||||
|
||||
Gateway 网关侧要求:
|
||||
|
||||
@ -81,78 +81,78 @@ Gateway 网关侧要求:
|
||||
}
|
||||
```
|
||||
|
||||
流程工作方式如下:
|
||||
流程工作方式:
|
||||
|
||||
- iOS 应用使用 App Attest 和应用回执向中继注册。
|
||||
- 中继返回一个不透明的 relay handle,以及一个按注册范围限定的发送授权。
|
||||
- iOS 应用会获取已配对 gateway 的身份,并将其包含在中继注册中,因此该基于中继的注册会委托给那个特定的 gateway。
|
||||
- 应用会通过 `push.apns.register` 将该基于中继的注册转发给已配对的 gateway。
|
||||
- gateway 会将该已存储的 relay handle 用于 `push.test`、后台唤醒和唤醒提醒。
|
||||
- gateway 的中继 base URL 必须与官方 / TestFlight iOS 构建中内置的中继 URL 一致。
|
||||
- 如果应用之后连接到不同的 gateway,或者连接到内置了不同中继 base URL 的构建,它会刷新中继注册,而不是复用旧绑定。
|
||||
- iOS 应用使用 App Attest 和应用收据向 relay 注册。
|
||||
- relay 返回一个不透明的 relay handle 以及一个按注册范围授予的发送许可。
|
||||
- iOS 应用会获取已配对 Gateway 网关的身份,并将其包含在 relay 注册中,因此这个基于 relay 的注册会委托给该特定 Gateway 网关。
|
||||
- 应用通过 `push.apns.register` 将该基于 relay 的注册转发给已配对的 Gateway 网关。
|
||||
- Gateway 网关将使用这个已存储的 relay handle 来执行 `push.test`、后台唤醒和唤醒提示。
|
||||
- Gateway 网关的 relay 基础 URL 必须与官方/TestFlight iOS 构建中固化的 relay URL 一致。
|
||||
- 如果应用之后连接到不同的 Gateway 网关,或者连接到使用不同 relay 基础 URL 的构建,它会刷新 relay 注册,而不是复用旧绑定。
|
||||
|
||||
对于此路径,gateway **不**需要的内容:
|
||||
对于这一路径,Gateway 网关**不**需要:
|
||||
|
||||
- 不需要部署范围的中继令牌。
|
||||
- 对于官方 / TestFlight 的基于中继发送,不需要直接的 APNs 密钥。
|
||||
- 不需要全局部署级 relay token。
|
||||
- 对于官方/TestFlight 的 relay 转发发送,不需要直接 APNs key。
|
||||
|
||||
预期的运维流程:
|
||||
预期的操作流程:
|
||||
|
||||
1. 安装官方 / TestFlight iOS 构建。
|
||||
2. 在 gateway 上设置 `gateway.push.apns.relay.baseUrl`。
|
||||
3. 将应用与 gateway 配对,并让它完成连接。
|
||||
4. 在应用拿到 APNs 令牌、运维会话已连接且中继注册成功后,应用会自动发布 `push.apns.register`。
|
||||
5. 之后,`push.test`、重连唤醒和唤醒提醒就可以使用已存储的基于中继的注册。
|
||||
1. 安装官方/TestFlight iOS 构建。
|
||||
2. 在 Gateway 网关上设置 `gateway.push.apns.relay.baseUrl`。
|
||||
3. 将应用与 Gateway 网关配对,并让它完成连接。
|
||||
4. 当应用已经拿到 APNs token、operator 会话已连接且 relay 注册成功后,它会自动发布 `push.apns.register`。
|
||||
5. 之后,`push.test`、重连唤醒和唤醒提示就可以使用这个已存储的基于 relay 的注册。
|
||||
|
||||
兼容性说明:
|
||||
|
||||
- `OPENCLAW_APNS_RELAY_BASE_URL` 仍可作为 gateway 的临时环境变量覆盖项使用。
|
||||
- `OPENCLAW_APNS_RELAY_BASE_URL` 仍可作为 Gateway 网关的临时环境变量覆盖项使用。
|
||||
|
||||
## 认证与信任流程
|
||||
|
||||
中继的存在是为了强制执行两个约束,而这些约束是官方 iOS 构建在直接由 gateway 发送 APNs 时无法提供的:
|
||||
之所以引入 relay,是为了强制执行两个“在官方 iOS 构建上直接由 Gateway 网关连接 APNs 无法提供”的约束:
|
||||
|
||||
- 只有通过 Apple 分发的真实 OpenClaw iOS 构建才能使用托管中继。
|
||||
- gateway 只能向与该特定 gateway 配对的 iOS 设备发送基于中继的推送。
|
||||
- 只有通过 Apple 分发的真实 OpenClaw iOS 构建才能使用托管 relay。
|
||||
- Gateway 网关只能为与该特定 Gateway 网关配对过的 iOS 设备发送基于 relay 的推送。
|
||||
|
||||
逐跳说明:
|
||||
|
||||
1. `iOS app -> gateway`
|
||||
- 应用首先通过常规 Gateway 网关认证流程与 gateway 配对。
|
||||
- 这会给应用一个已认证的节点会话,以及一个已认证的运维会话。
|
||||
- 运维会话用于调用 `gateway.identity.get`。
|
||||
- 应用首先通过正常的 Gateway 网关认证流程与 Gateway 网关配对。
|
||||
- 这会给应用一个已认证的节点会话以及一个已认证的 operator 会话。
|
||||
- operator 会话用于调用 `gateway.identity.get`。
|
||||
|
||||
2. `iOS app -> relay`
|
||||
- 应用通过 HTTPS 调用中继注册端点。
|
||||
- 注册包含 App Attest 证明和应用回执。
|
||||
- 中继会验证 bundle ID、App Attest 证明和 Apple 回执,并要求使用官方 / 生产分发路径。
|
||||
- 这就是为什么本地 Xcode / 开发构建无法使用托管中继。本地构建可能是已签名的,但不满足中继所要求的官方 Apple 分发证明。
|
||||
- 应用通过 HTTPS 调用 relay 注册端点。
|
||||
- 注册内容包括 App Attest 证明和应用收据。
|
||||
- relay 会验证 bundle ID、App Attest 证明和 Apple 收据,并要求使用官方/生产分发路径。
|
||||
- 这就是为什么本地 Xcode/dev 构建无法使用托管 relay。虽然本地构建可以签名,但它不满足 relay 所要求的官方 Apple 分发证明。
|
||||
|
||||
3. `gateway identity delegation`
|
||||
- 在中继注册之前,应用会通过 `gateway.identity.get` 获取已配对 gateway 的身份。
|
||||
- 应用会在中继注册载荷中包含该 gateway 身份。
|
||||
- 中继返回一个 relay handle 和一个按注册范围限定的发送授权,并将其委托给该 gateway 身份。
|
||||
- 在 relay 注册前,应用会通过 `gateway.identity.get` 获取已配对 Gateway 网关的身份。
|
||||
- 应用会将这个 Gateway 网关身份包含到 relay 注册负载中。
|
||||
- relay 返回一个 relay handle 和一个按注册范围授予的发送许可,这些都被委托给该 Gateway 网关身份。
|
||||
|
||||
4. `gateway -> relay`
|
||||
- gateway 会存储来自 `push.apns.register` 的 relay handle 和发送授权。
|
||||
- 在执行 `push.test`、重连唤醒和唤醒提醒时,gateway 会使用它自己的设备身份对发送请求进行签名。
|
||||
- 中继会根据注册时委托的 gateway 身份,验证已存储的发送授权以及 gateway 签名。
|
||||
- 即使另一个 gateway 以某种方式获得了该 handle,也无法复用这个已存储的注册。
|
||||
- Gateway 网关会存储来自 `push.apns.register` 的 relay handle 和发送许可。
|
||||
- 在执行 `push.test`、重连唤醒和唤醒提示时,Gateway 网关会使用它自己的设备身份对发送请求签名。
|
||||
- relay 会依据注册时委托的 Gateway 网关身份,同时验证已存储的发送许可和 Gateway 网关签名。
|
||||
- 即使其他 Gateway 网关设法拿到了这个 handle,也不能复用该已存储注册。
|
||||
|
||||
5. `relay -> APNs`
|
||||
- 中继持有用于官方构建的生产 APNs 凭证和原始 APNs 令牌。
|
||||
- 对于基于中继的官方构建,gateway 永远不会存储原始 APNs 令牌。
|
||||
- 中继会代表已配对的 gateway 将最终推送发送到 APNs。
|
||||
- relay 持有生产 APNs 凭证以及官方构建的原始 APNs token。
|
||||
- 对于基于 relay 的官方构建,Gateway 网关永远不会存储原始 APNs token。
|
||||
- relay 代表已配对的 Gateway 网关向 APNs 发送最终推送。
|
||||
|
||||
创建此设计的原因:
|
||||
为什么要这样设计:
|
||||
|
||||
- 让生产 APNs 凭证不出现在用户的 gateway 中。
|
||||
- 避免在 gateway 上存储官方构建的原始 APNs 令牌。
|
||||
- 仅允许官方 / TestFlight OpenClaw 构建使用托管中继。
|
||||
- 防止一个 gateway 向属于另一个 gateway 的 iOS 设备发送唤醒推送。
|
||||
- 让生产 APNs 凭证不落到用户 Gateway 网关上。
|
||||
- 避免在 Gateway 网关上存储官方构建的原始 APNs token。
|
||||
- 仅允许官方/TestFlight OpenClaw 构建使用托管 relay。
|
||||
- 防止某个 Gateway 网关向属于另一个 Gateway 网关的 iOS 设备发送唤醒推送。
|
||||
|
||||
本地 / 手动构建仍然使用直接 APNs。如果你在不使用中继的情况下测试这些构建,
|
||||
gateway 仍然需要直接 APNs 凭证:
|
||||
本地/手动构建仍然使用直连 APNs。如果你在不使用 relay 的情况下测试这些构建,
|
||||
Gateway 网关仍然需要直连 APNs 凭证:
|
||||
|
||||
```bash
|
||||
export OPENCLAW_APNS_TEAM_ID="TEAMID"
|
||||
@ -160,23 +160,39 @@ export OPENCLAW_APNS_KEY_ID="KEYID"
|
||||
export OPENCLAW_APNS_PRIVATE_KEY_P8="$(cat /path/to/AuthKey_KEYID.p8)"
|
||||
```
|
||||
|
||||
这些是 Gateway 网关主机运行时环境变量,不是 Fastlane 设置。`apps/ios/fastlane/.env` 只存储
|
||||
App Store Connect / TestFlight 认证信息,例如 `ASC_KEY_ID` 和 `ASC_ISSUER_ID`;它不会为本地 iOS 构建配置
|
||||
直连 APNs 投递。
|
||||
|
||||
推荐的 Gateway 网关主机存储方式:
|
||||
|
||||
```bash
|
||||
mkdir -p ~/.openclaw/credentials/apns
|
||||
chmod 700 ~/.openclaw/credentials/apns
|
||||
mv /path/to/AuthKey_KEYID.p8 ~/.openclaw/credentials/apns/AuthKey_KEYID.p8
|
||||
chmod 600 ~/.openclaw/credentials/apns/AuthKey_KEYID.p8
|
||||
export OPENCLAW_APNS_PRIVATE_KEY_PATH="$HOME/.openclaw/credentials/apns/AuthKey_KEYID.p8"
|
||||
```
|
||||
|
||||
不要提交 `.p8` 文件,也不要将它放在仓库检出目录下。
|
||||
|
||||
## 发现路径
|
||||
|
||||
### Bonjour(LAN)
|
||||
|
||||
iOS 应用会在 `local.` 上浏览 `_openclaw-gw._tcp`,并在已配置时浏览相同的
|
||||
广域 DNS-SD 发现域。同一 LAN 上的 gateways 会自动通过 `local.` 出现;
|
||||
跨网络发现可以使用已配置的广域域名,而无需更改 beacon 类型。
|
||||
iOS 应用会在 `local.` 上浏览 `_openclaw-gw._tcp`,并在已配置时浏览同一个
|
||||
广域 DNS-SD 发现域。同一 LAN 上的 Gateway 网关会通过 `local.` 自动出现;
|
||||
跨网络发现则可以使用已配置的广域域名,而无需更改 beacon 类型。
|
||||
|
||||
### Tailnet(跨网络)
|
||||
|
||||
如果 mDNS 被阻止,请使用单播 DNS-SD 区域(选择一个域名;示例:
|
||||
如果 mDNS 被阻止,请使用单播 DNS-SD 区域(选择一个域名;例如:
|
||||
`openclaw.internal.`)和 Tailscale split DNS。
|
||||
CoreDNS 示例请参见 [Bonjour](/gateway/bonjour)。
|
||||
CoreDNS 示例请参见 [Bonjour](/zh-CN/gateway/bonjour)。
|
||||
|
||||
### 手动主机 / 端口
|
||||
### 手动主机/端口
|
||||
|
||||
在设置中,启用 **Manual Host** 并输入 gateway 主机 + 端口(默认 `18789`)。
|
||||
在 Settings 中启用 **Manual Host**,然后输入 Gateway 网关主机 + 端口(默认 `18789`)。
|
||||
|
||||
## Canvas + A2UI
|
||||
|
||||
@ -188,10 +204,10 @@ openclaw nodes invoke --node "iOS Node" --command canvas.navigate --params '{"ur
|
||||
|
||||
说明:
|
||||
|
||||
- Gateway 网关的 canvas host 提供 `/__openclaw__/canvas/` 和 `/__openclaw__/a2ui/`。
|
||||
- 它由 Gateway 网关 HTTP 服务器提供(与 `gateway.port` 相同的端口,默认 `18789`)。
|
||||
- 当广播了 canvas host URL 时,iOS 节点会在连接时自动导航到 A2UI。
|
||||
- 使用 `canvas.navigate` 和 `{"url":""}` 可返回内置 scaffold。
|
||||
- Gateway 网关 canvas host 提供 `/__openclaw__/canvas/` 和 `/__openclaw__/a2ui/`。
|
||||
- 它由 Gateway 网关 HTTP 服务器提供(与 `gateway.port` 使用同一个端口,默认 `18789`)。
|
||||
- 当广播了 canvas host URL 时,iOS 节点会在连接后自动跳转到 A2UI。
|
||||
- 使用 `canvas.navigate` 和 `{"url":""}` 可返回内置脚手架。
|
||||
|
||||
### Canvas eval / snapshot
|
||||
|
||||
@ -203,20 +219,20 @@ openclaw nodes invoke --node "iOS Node" --command canvas.eval --params '{"javaSc
|
||||
openclaw nodes invoke --node "iOS Node" --command canvas.snapshot --params '{"maxWidth":900,"format":"jpeg"}'
|
||||
```
|
||||
|
||||
## 语音唤醒 + 对话模式
|
||||
## 语音唤醒 + 对讲模式
|
||||
|
||||
- 设置中提供语音唤醒和对话模式。
|
||||
- iOS 可能会挂起后台音频;当应用未处于活动状态时,应将语音功能视为尽力而为。
|
||||
- 语音唤醒和对讲模式可在 Settings 中启用。
|
||||
- iOS 可能会暂停后台音频;当应用不处于活动状态时,语音功能应视为尽力而为。
|
||||
|
||||
## 常见错误
|
||||
|
||||
- `NODE_BACKGROUND_UNAVAILABLE`:请将 iOS 应用切换到前台(canvas / camera / screen 命令需要它处于前台)。
|
||||
- `A2UI_HOST_NOT_CONFIGURED`:Gateway 网关未广播 canvas host URL;请检查 [Gateway 配置](/gateway/configuration) 中的 `canvasHost`。
|
||||
- `NODE_BACKGROUND_UNAVAILABLE`:请将 iOS 应用切到前台(canvas/相机/屏幕命令需要前台状态)。
|
||||
- `A2UI_HOST_NOT_CONFIGURED`:Gateway 网关没有广播 canvas host URL;请检查 [Gateway 配置](/zh-CN/gateway/configuration) 中的 `canvasHost`。
|
||||
- 配对提示始终不出现:运行 `openclaw devices list` 并手动批准。
|
||||
- 重装后重连失败:Keychain 配对令牌已被清除;请重新配对节点。
|
||||
- 重装后重连失败:Keychain 配对 token 已被清除;请重新配对节点。
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [配对](/channels/pairing)
|
||||
- [设备发现](/gateway/discovery)
|
||||
- [Bonjour](/gateway/bonjour)
|
||||
- [配对](/zh-CN/channels/pairing)
|
||||
- [设备发现](/zh-CN/gateway/discovery)
|
||||
- [Bonjour](/zh-CN/gateway/bonjour)
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -1,63 +1,72 @@
|
||||
---
|
||||
read_when:
|
||||
- 你看到了 `OPENCLAW_PLUGIN_SDK_COMPAT_DEPRECATED` 警告
|
||||
- 你看到了 `OPENCLAW_EXTENSION_API_DEPRECATED` 警告
|
||||
- 你看到了 OPENCLAW_PLUGIN_SDK_COMPAT_DEPRECATED 警告
|
||||
- 你看到了 OPENCLAW_EXTENSION_API_DEPRECATED 警告
|
||||
- 你正在将插件更新到现代插件架构
|
||||
- 你在维护一个外部 OpenClaw 插件
|
||||
- 你在维护外部 OpenClaw 插件
|
||||
sidebarTitle: Migrate to SDK
|
||||
summary: 从旧版向后兼容层迁移到现代插件 SDK
|
||||
title: 插件 SDK 迁移
|
||||
x-i18n:
|
||||
generated_at: "2026-04-06T04:10:54Z"
|
||||
generated_at: "2026-04-06T15:30:36Z"
|
||||
model: gpt-5.4
|
||||
provider: openai
|
||||
source_hash: 94f12d1376edd8184714cc4dbea4a88fa8ed652f65e9365ede6176f3bf441b33
|
||||
source_hash: 770eca214dcd7c7c22ee507d4bb4359b505a29c9ecd4458f7b5e1362c5cd0d6e
|
||||
source_path: plugins/sdk-migration.md
|
||||
workflow: 15
|
||||
---
|
||||
|
||||
# 插件 SDK 迁移
|
||||
|
||||
OpenClaw 已从宽泛的向后兼容层迁移到现代插件架构,采用聚焦且有文档说明的导入方式。如果你的插件是在新架构之前构建的,本指南将帮助你完成迁移。
|
||||
OpenClaw 已从宽泛的向后兼容层迁移到现代插件架构,采用聚焦且有文档记录的导入方式。如果你的插件是在新架构之前构建的,本指南将帮助你完成迁移。
|
||||
|
||||
## 正在发生什么变化
|
||||
|
||||
旧版插件系统提供了两个高度开放的接口,使插件能够从单一入口点导入所需的任何内容:
|
||||
旧版插件系统提供了两个高度开放的接口,使插件可以通过单一入口点导入所需的任何内容:
|
||||
|
||||
- **`openclaw/plugin-sdk/compat`** — 一个单一导入入口,会重新导出数十个辅助工具。它的引入是为了在新插件架构构建期间,让较旧的基于 hook 的插件继续工作。
|
||||
- **`openclaw/extension-api`** — 一个桥接层,让插件可以直接访问宿主端辅助工具,例如嵌入式智能体运行器。
|
||||
- **`openclaw/plugin-sdk/compat`** — 一个单一导入点,重新导出数十个辅助函数。它的引入是为了在新插件架构构建期间,让旧版基于 hook 的插件继续工作。
|
||||
- **`openclaw/extension-api`** — 一个桥接层,让插件可以直接访问宿主侧辅助函数,例如嵌入式智能体执行器。
|
||||
|
||||
这两个接口现在都已被**弃用**。它们在运行时仍然可用,但新插件不得再使用它们,现有插件也应在下一个主版本移除它们之前完成迁移。
|
||||
这两个接口现在都已**弃用**。它们在运行时仍然可用,但新插件不得再使用它们,现有插件也应在下一个主版本移除它们之前完成迁移。
|
||||
|
||||
<Warning>
|
||||
向后兼容层将在未来的一个主版本中移除。
|
||||
仍然从这些接口导入的插件届时将会中断。
|
||||
向后兼容层将在未来的主版本中移除。
|
||||
仍从这些接口导入的插件届时将会失效。
|
||||
</Warning>
|
||||
|
||||
## 为什么会有这个变化
|
||||
|
||||
旧方法会带来一些问题:
|
||||
旧方法带来了很多问题:
|
||||
|
||||
- **启动缓慢** — 导入一个辅助工具会加载数十个无关模块
|
||||
- **循环依赖** — 宽泛的重新导出很容易造成导入环
|
||||
- **API 接口不清晰** — 无法区分哪些导出是稳定的,哪些是内部实现
|
||||
- **启动缓慢** — 导入一个辅助函数会加载数十个无关模块
|
||||
- **循环依赖** — 宽泛的重新导出让导入环路更容易出现
|
||||
- **API 接口不清晰** — 无法判断哪些导出是稳定的,哪些属于内部实现
|
||||
|
||||
现代插件 SDK 解决了这些问题:每个导入路径(`openclaw/plugin-sdk/\<subpath\>`)都是一个小型、自包含的模块,具有清晰的用途和有文档说明的契约。
|
||||
现代插件 SDK 解决了这些问题:每个导入路径(`openclaw/plugin-sdk/\<subpath\>`)
|
||||
都是一个小型、自包含模块,拥有明确用途和文档化契约。
|
||||
|
||||
用于内置渠道的旧版提供商便捷接口也已移除。像 `openclaw/plugin-sdk/slack`、`openclaw/plugin-sdk/discord`、`openclaw/plugin-sdk/signal`、`openclaw/plugin-sdk/whatsapp`、带有渠道品牌的辅助接口以及 `openclaw/plugin-sdk/telegram-core` 这样的导入,都是私有 mono-repo 快捷方式,而不是稳定的插件契约。请改用更窄、更通用的 SDK 子路径。在内置插件工作区中,请将提供商自有的辅助工具保留在该插件自己的 `api.ts` 或 `runtime-api.ts` 中。
|
||||
面向内置渠道的旧版提供商便捷接口也已经移除。类似
|
||||
`openclaw/plugin-sdk/slack`、`openclaw/plugin-sdk/discord`、
|
||||
`openclaw/plugin-sdk/signal`、`openclaw/plugin-sdk/whatsapp`、
|
||||
带渠道品牌的辅助接口,以及
|
||||
`openclaw/plugin-sdk/telegram-core`
|
||||
这类导入路径,都是私有 mono-repo 快捷方式,而不是稳定的插件契约。请改用更窄、更通用的 SDK 子路径。在内置插件工作区内部,请将提供商拥有的辅助函数保存在该插件自己的
|
||||
`api.ts` 或 `runtime-api.ts` 中。
|
||||
|
||||
当前内置提供商示例:
|
||||
|
||||
- Anthropic 将 Claude 专用的流式辅助工具保留在自己的 `api.ts` / `contract-api.ts` 接口中
|
||||
- OpenAI 将提供商构建器、默认模型辅助工具以及 realtime 提供商构建器保留在自己的 `api.ts` 中
|
||||
- OpenRouter 将提供商构建器以及新手引导 / 配置辅助工具保留在自己的 `api.ts` 中
|
||||
- Anthropic 将 Claude 专用流辅助函数保存在其自己的 `api.ts` /
|
||||
`contract-api.ts` 接口中
|
||||
- OpenAI 将提供商构建器、默认模型辅助函数和实时提供商构建器保存在其自己的 `api.ts` 中
|
||||
- OpenRouter 将提供商构建器以及新手引导/配置辅助函数保存在其自己的
|
||||
`api.ts` 中
|
||||
|
||||
## 如何迁移
|
||||
|
||||
<Steps>
|
||||
<Step title="审查 Windows 包装器回退行为">
|
||||
如果你的插件使用 `openclaw/plugin-sdk/windows-spawn`,现在未解析的 Windows
|
||||
`.cmd`/`.bat` 包装器会默认以失败关闭,除非你显式传入
|
||||
`.cmd`/`.bat` 包装器将默认以失败关闭,除非你显式传入
|
||||
`allowShellFallback: true`。
|
||||
|
||||
```typescript
|
||||
@ -73,13 +82,13 @@ OpenClaw 已从宽泛的向后兼容层迁移到现代插件架构,采用聚
|
||||
});
|
||||
```
|
||||
|
||||
如果你的调用方并非有意依赖 shell 回退,请不要设置
|
||||
如果你的调用方并不有意依赖 shell 回退,请不要设置
|
||||
`allowShellFallback`,而应改为处理抛出的错误。
|
||||
|
||||
</Step>
|
||||
|
||||
<Step title="查找已弃用的导入">
|
||||
在你的插件中搜索来自这两个已弃用接口的导入:
|
||||
在你的插件中搜索来自以下任一已弃用接口的导入:
|
||||
|
||||
```bash
|
||||
grep -r "plugin-sdk/compat" my-plugin/
|
||||
@ -89,7 +98,7 @@ OpenClaw 已从宽泛的向后兼容层迁移到现代插件架构,采用聚
|
||||
</Step>
|
||||
|
||||
<Step title="替换为聚焦导入">
|
||||
旧接口中的每个导出都映射到一个特定的现代导入路径:
|
||||
旧接口中的每个导出,都映射到一个特定的现代导入路径:
|
||||
|
||||
```typescript
|
||||
// Before (deprecated backwards-compatibility layer)
|
||||
@ -105,7 +114,7 @@ OpenClaw 已从宽泛的向后兼容层迁移到现代插件架构,采用聚
|
||||
import { resolveControlCommandGate } from "openclaw/plugin-sdk/command-auth";
|
||||
```
|
||||
|
||||
对于宿主端辅助工具,请使用注入的插件运行时,而不是直接导入:
|
||||
对于宿主侧辅助函数,请使用注入的插件运行时,而不是直接导入:
|
||||
|
||||
```typescript
|
||||
// Before (deprecated extension-api bridge)
|
||||
@ -116,9 +125,9 @@ OpenClaw 已从宽泛的向后兼容层迁移到现代插件架构,采用聚
|
||||
const result = await api.runtime.agent.runEmbeddedPiAgent({ sessionId, prompt });
|
||||
```
|
||||
|
||||
其他旧版桥接辅助工具同样适用这一模式:
|
||||
相同模式也适用于其他旧版桥接辅助函数:
|
||||
|
||||
| 旧导入 | 现代等价项 |
|
||||
| 旧导入 | 现代等价写法 |
|
||||
| --- | --- |
|
||||
| `resolveAgentDir` | `api.runtime.agent.resolveAgentDir` |
|
||||
| `resolveAgentWorkspaceDir` | `api.runtime.agent.resolveAgentWorkspaceDir` |
|
||||
@ -126,7 +135,7 @@ OpenClaw 已从宽泛的向后兼容层迁移到现代插件架构,采用聚
|
||||
| `resolveThinkingDefault` | `api.runtime.agent.resolveThinkingDefault` |
|
||||
| `resolveAgentTimeoutMs` | `api.runtime.agent.resolveAgentTimeoutMs` |
|
||||
| `ensureAgentWorkspace` | `api.runtime.agent.ensureAgentWorkspace` |
|
||||
| session store helpers | `api.runtime.agent.session.*` |
|
||||
| 会话存储辅助函数 | `api.runtime.agent.session.*` |
|
||||
|
||||
</Step>
|
||||
|
||||
@ -143,195 +152,198 @@ OpenClaw 已从宽泛的向后兼容层迁移到现代插件架构,采用聚
|
||||
<Accordion title="常用导入路径表">
|
||||
| 导入路径 | 用途 | 关键导出 |
|
||||
| --- | --- | --- |
|
||||
| `plugin-sdk/plugin-entry` | 规范的插件入口辅助工具 | `definePluginEntry` |
|
||||
| `plugin-sdk/core` | 用于渠道入口定义 / 构建器的旧版总括式重新导出 | `defineChannelPluginEntry`, `createChatChannelPlugin` |
|
||||
| `plugin-sdk/plugin-entry` | 规范插件入口辅助函数 | `definePluginEntry` |
|
||||
| `plugin-sdk/core` | 用于渠道入口定义/构建器的旧版总入口重新导出 | `defineChannelPluginEntry`, `createChatChannelPlugin` |
|
||||
| `plugin-sdk/config-schema` | 根配置 schema 导出 | `OpenClawSchema` |
|
||||
| `plugin-sdk/provider-entry` | 单一提供商入口辅助工具 | `defineSingleProviderPluginEntry` |
|
||||
| `plugin-sdk/provider-entry` | 单提供商入口辅助函数 | `defineSingleProviderPluginEntry` |
|
||||
| `plugin-sdk/channel-core` | 聚焦的渠道入口定义和构建器 | `defineChannelPluginEntry`, `defineSetupPluginEntry`, `createChatChannelPlugin`, `createChannelPluginBase` |
|
||||
| `plugin-sdk/setup` | 共享的设置向导辅助工具 | allowlist 提示、设置状态构建器 |
|
||||
| `plugin-sdk/setup-runtime` | 设置阶段运行时辅助工具 | 可安全导入的设置补丁适配器、lookup-note 辅助工具、`promptResolvedAllowFrom`、`splitSetupEntries`、委托式设置代理 |
|
||||
| `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` | account-id 辅助工具 | `DEFAULT_ACCOUNT_ID`,account-id 规范化 |
|
||||
| `plugin-sdk/account-resolution` | 账户查找辅助工具 | 账户查找 + 默认回退辅助工具 |
|
||||
| `plugin-sdk/account-helpers` | 窄范围账户辅助工具 | 账户列表 / 账户操作辅助工具 |
|
||||
| `plugin-sdk/channel-setup` | 设置向导适配器 | `createOptionalChannelSetupSurface`, `createOptionalChannelSetupAdapter`, `createOptionalChannelSetupWizard`,以及 `DEFAULT_ACCOUNT_ID`, `createTopLevelChannelDmPolicy`, `setSetupChannelEnabled`, `splitSetupEntries` |
|
||||
| `plugin-sdk/setup` | 共享设置向导辅助函数 | 允许列表提示、设置状态构建器 |
|
||||
| `plugin-sdk/setup-runtime` | 设置时运行时辅助函数 | 导入安全的设置补丁适配器、查找说明辅助函数、`promptResolvedAllowFrom`、`splitSetupEntries`、委托设置代理 |
|
||||
| `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` | 账户 id 辅助函数 | `DEFAULT_ACCOUNT_ID`、账户 id 标准化 |
|
||||
| `plugin-sdk/account-resolution` | 账户查找辅助函数 | 账户查找 + 默认回退辅助函数 |
|
||||
| `plugin-sdk/account-helpers` | 窄接口账户辅助函数 | 账户列表/账户动作辅助函数 |
|
||||
| `plugin-sdk/channel-setup` | 设置向导适配器 | `createOptionalChannelSetupSurface`, `createOptionalChannelSetupAdapter`, `createOptionalChannelSetupWizard`, 以及 `DEFAULT_ACCOUNT_ID`, `createTopLevelChannelDmPolicy`, `setSetupChannelEnabled`, `splitSetupEntries` |
|
||||
| `plugin-sdk/channel-pairing` | 私信配对原语 | `createChannelPairingController` |
|
||||
| `plugin-sdk/channel-reply-pipeline` | 回复前缀 + 输入中状态联动 | `createChannelReplyPipeline` |
|
||||
| `plugin-sdk/channel-reply-pipeline` | 回复前缀 + 输入中状态布线 | `createChannelReplyPipeline` |
|
||||
| `plugin-sdk/channel-config-helpers` | 配置适配器工厂 | `createHybridChannelConfigAdapter` |
|
||||
| `plugin-sdk/channel-config-schema` | 配置 schema 构建器 | 渠道配置 schema 类型 |
|
||||
| `plugin-sdk/telegram-command-config` | Telegram 命令配置辅助工具 | 命令名规范化、描述裁剪、重复 / 冲突校验 |
|
||||
| `plugin-sdk/channel-policy` | 群组 / 私信策略解析 | `resolveChannelGroupRequireMention` |
|
||||
| `plugin-sdk/telegram-command-config` | Telegram 命令配置辅助函数 | 命令名称标准化、描述裁剪、重复/冲突校验 |
|
||||
| `plugin-sdk/channel-policy` | 群组/私信策略解析 | `resolveChannelGroupRequireMention` |
|
||||
| `plugin-sdk/channel-lifecycle` | 账户状态跟踪 | `createAccountStatusSink` |
|
||||
| `plugin-sdk/inbound-envelope` | 入站 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/channel-runtime` | 已弃用的兼容性 shim | 仅限旧版渠道运行时工具 |
|
||||
| `plugin-sdk/inbound-envelope` | 入站 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/channel-runtime` | 已弃用兼容 shim | 仅旧版渠道运行时工具 |
|
||||
| `plugin-sdk/channel-send-result` | 发送结果类型 | 回复结果类型 |
|
||||
| `plugin-sdk/runtime-store` | 持久化插件存储 | `createPluginRuntimeStore` |
|
||||
| `plugin-sdk/runtime` | 宽泛的运行时辅助工具 | 运行时 / 日志 / 备份 / 插件安装辅助工具 |
|
||||
| `plugin-sdk/runtime-env` | 窄范围运行时环境辅助工具 | logger / runtime env、超时、重试和退避辅助工具 |
|
||||
| `plugin-sdk/plugin-runtime` | 共享插件运行时辅助工具 | 插件命令 / hooks / http / 交互辅助工具 |
|
||||
| `plugin-sdk/hook-runtime` | Hook 管道辅助工具 | 共享 webhook / 内部 hook 管道辅助工具 |
|
||||
| `plugin-sdk/lazy-runtime` | 惰性运行时辅助工具 | `createLazyRuntimeModule`, `createLazyRuntimeMethod`, `createLazyRuntimeMethodBinder`, `createLazyRuntimeNamedExport`, `createLazyRuntimeSurface` |
|
||||
| `plugin-sdk/process-runtime` | 进程辅助工具 | 共享 exec 辅助工具 |
|
||||
| `plugin-sdk/cli-runtime` | CLI 运行时辅助工具 | 命令格式化、等待、版本辅助工具 |
|
||||
| `plugin-sdk/gateway-runtime` | Gateway 网关辅助工具 | Gateway 网关客户端和渠道状态补丁辅助工具 |
|
||||
| `plugin-sdk/config-runtime` | 配置辅助工具 | 配置加载 / 写入辅助工具 |
|
||||
| `plugin-sdk/telegram-command-config` | Telegram 命令辅助工具 | 当内置 Telegram 契约接口不可用时,提供具备稳定回退的 Telegram 命令校验辅助工具 |
|
||||
| `plugin-sdk/approval-runtime` | 审批提示辅助工具 | exec / 插件审批负载、审批能力 / 配置文件辅助工具、本地审批路由 / 运行时辅助工具 |
|
||||
| `plugin-sdk/approval-auth-runtime` | 审批认证辅助工具 | 审批人解析、同聊天操作认证 |
|
||||
| `plugin-sdk/approval-client-runtime` | 审批客户端辅助工具 | 原生 exec 审批配置文件 / 过滤辅助工具 |
|
||||
| `plugin-sdk/approval-delivery-runtime` | 审批投递辅助工具 | 原生审批能力 / 投递适配器 |
|
||||
| `plugin-sdk/approval-native-runtime` | 审批目标辅助工具 | 原生审批目标 / 账户绑定辅助工具 |
|
||||
| `plugin-sdk/approval-reply-runtime` | 审批回复辅助工具 | exec / 插件审批回复负载辅助工具 |
|
||||
| `plugin-sdk/security-runtime` | 安全辅助工具 | 共享信任、私信门控、外部内容和密钥收集辅助工具 |
|
||||
| `plugin-sdk/ssrf-policy` | SSRF 策略辅助工具 | 主机 allowlist 和私有网络策略辅助工具 |
|
||||
| `plugin-sdk/ssrf-runtime` | SSRF 运行时辅助工具 | pinned-dispatcher、受保护 fetch、SSRF 策略辅助工具 |
|
||||
| `plugin-sdk/collection-runtime` | 有界缓存辅助工具 | `pruneMapToMaxSize` |
|
||||
| `plugin-sdk/diagnostic-runtime` | 诊断门控辅助工具 | `isDiagnosticFlagEnabled`, `isDiagnosticsEnabled` |
|
||||
| `plugin-sdk/error-runtime` | 错误格式化辅助工具 | `formatUncaughtError`, `isApprovalNotFoundError`、错误图辅助工具 |
|
||||
| `plugin-sdk/fetch-runtime` | 包装后的 fetch / 代理辅助工具 | `resolveFetch`、代理辅助工具 |
|
||||
| `plugin-sdk/host-runtime` | 主机规范化辅助工具 | `normalizeHostname`, `normalizeScpRemoteHost` |
|
||||
| `plugin-sdk/retry-runtime` | 重试辅助工具 | `RetryConfig`, `retryAsync`、策略运行器 |
|
||||
| `plugin-sdk/allow-from` | allowlist 格式化 | `formatAllowFromLowercase` |
|
||||
| `plugin-sdk/allowlist-resolution` | allowlist 输入映射 | `mapAllowlistResolutionInputs` |
|
||||
| `plugin-sdk/command-auth` | 命令门控和命令接口辅助工具 | `resolveControlCommandGate`、发送方授权辅助工具、命令注册表辅助工具 |
|
||||
| `plugin-sdk/secret-input` | 密钥输入解析 | 密钥输入辅助工具 |
|
||||
| `plugin-sdk/webhook-ingress` | webhook 请求辅助工具 | webhook 目标工具 |
|
||||
| `plugin-sdk/webhook-request-guards` | webhook 请求体守卫辅助工具 | 请求体读取 / 限制辅助工具 |
|
||||
| `plugin-sdk/runtime` | 宽接口运行时辅助函数 | 运行时/日志/备份/插件安装辅助函数 |
|
||||
| `plugin-sdk/runtime-env` | 窄接口运行时环境辅助函数 | Logger/运行时环境、超时、重试和退避辅助函数 |
|
||||
| `plugin-sdk/plugin-runtime` | 共享插件运行时辅助函数 | 插件命令/hooks/http/交互式辅助函数 |
|
||||
| `plugin-sdk/hook-runtime` | Hook 管道辅助函数 | 共享 webhook/内部 hook 管道辅助函数 |
|
||||
| `plugin-sdk/lazy-runtime` | 延迟运行时辅助函数 | `createLazyRuntimeModule`, `createLazyRuntimeMethod`, `createLazyRuntimeMethodBinder`, `createLazyRuntimeNamedExport`, `createLazyRuntimeSurface` |
|
||||
| `plugin-sdk/process-runtime` | 进程辅助函数 | 共享 exec 辅助函数 |
|
||||
| `plugin-sdk/cli-runtime` | CLI 运行时辅助函数 | 命令格式化、等待、版本辅助函数 |
|
||||
| `plugin-sdk/gateway-runtime` | Gateway 网关辅助函数 | Gateway 网关客户端和渠道状态补丁辅助函数 |
|
||||
| `plugin-sdk/config-runtime` | 配置辅助函数 | 配置加载/写入辅助函数 |
|
||||
| `plugin-sdk/telegram-command-config` | Telegram 命令辅助函数 | 当内置 Telegram 契约接口不可用时,提供稳定回退的 Telegram 命令校验辅助函数 |
|
||||
| `plugin-sdk/approval-runtime` | 审批提示辅助函数 | exec/插件审批负载、审批能力/配置文件辅助函数、原生审批路由/运行时辅助函数 |
|
||||
| `plugin-sdk/approval-auth-runtime` | 审批凭证辅助函数 | 审批人解析、同聊天动作凭证 |
|
||||
| `plugin-sdk/approval-client-runtime` | 审批客户端辅助函数 | 原生 exec 审批配置文件/过滤辅助函数 |
|
||||
| `plugin-sdk/approval-delivery-runtime` | 审批投递辅助函数 | 原生审批能力/投递适配器 |
|
||||
| `plugin-sdk/approval-native-runtime` | 审批目标辅助函数 | 原生审批目标/账户绑定辅助函数 |
|
||||
| `plugin-sdk/approval-reply-runtime` | 审批回复辅助函数 | exec/插件审批回复负载辅助函数 |
|
||||
| `plugin-sdk/security-runtime` | 安全辅助函数 | 共享信任、私信门控、外部内容和密钥收集辅助函数 |
|
||||
| `plugin-sdk/ssrf-policy` | SSRF 策略辅助函数 | 主机允许列表和私有网络策略辅助函数 |
|
||||
| `plugin-sdk/ssrf-runtime` | SSRF 运行时辅助函数 | 固定 dispatcher、受保护 fetch、SSRF 策略辅助函数 |
|
||||
| `plugin-sdk/collection-runtime` | 有界缓存辅助函数 | `pruneMapToMaxSize` |
|
||||
| `plugin-sdk/diagnostic-runtime` | 诊断门控辅助函数 | `isDiagnosticFlagEnabled`, `isDiagnosticsEnabled` |
|
||||
| `plugin-sdk/error-runtime` | 错误格式化辅助函数 | `formatUncaughtError`, `isApprovalNotFoundError`、错误图辅助函数 |
|
||||
| `plugin-sdk/fetch-runtime` | 包装过的 fetch/代理辅助函数 | `resolveFetch`、代理辅助函数 |
|
||||
| `plugin-sdk/host-runtime` | 主机标准化辅助函数 | `normalizeHostname`, `normalizeScpRemoteHost` |
|
||||
| `plugin-sdk/retry-runtime` | 重试辅助函数 | `RetryConfig`, `retryAsync`、策略执行器 |
|
||||
| `plugin-sdk/allow-from` | 允许列表格式化 | `formatAllowFromLowercase` |
|
||||
| `plugin-sdk/allowlist-resolution` | 允许列表输入映射 | `mapAllowlistResolutionInputs` |
|
||||
| `plugin-sdk/command-auth` | 命令门控和命令接口辅助函数 | `resolveControlCommandGate`、发送者授权辅助函数、命令注册表辅助函数 |
|
||||
| `plugin-sdk/secret-input` | Secret 输入解析 | Secret 输入辅助函数 |
|
||||
| `plugin-sdk/webhook-ingress` | webhook 请求辅助函数 | webhook 目标工具函数 |
|
||||
| `plugin-sdk/webhook-request-guards` | webhook 请求体防护辅助函数 | 请求体读取/限制辅助函数 |
|
||||
| `plugin-sdk/reply-runtime` | 共享回复运行时 | 入站分发、心跳、回复规划器、分块 |
|
||||
| `plugin-sdk/reply-dispatch-runtime` | 窄范围回复分发辅助工具 | finalize + provider 分发辅助工具 |
|
||||
| `plugin-sdk/reply-history` | 回复历史辅助工具 | `buildHistoryContext`, `buildPendingHistoryContextFromMap`, `recordPendingHistoryEntry`, `clearHistoryEntriesIfEnabled` |
|
||||
| `plugin-sdk/reply-dispatch-runtime` | 窄接口回复分发辅助函数 | 最终化 + 提供商分发辅助函数 |
|
||||
| `plugin-sdk/reply-history` | 回复历史辅助函数 | `buildHistoryContext`, `buildPendingHistoryContextFromMap`, `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` | 路由 / session-key 辅助工具 | `resolveAgentRoute`, `buildAgentSessionKey`, `resolveDefaultAgentBoundAccountId`、session-key 规范化辅助工具 |
|
||||
| `plugin-sdk/status-helpers` | 渠道状态辅助工具 | 渠道 / 账户状态摘要构建器、运行时状态默认值、问题元数据辅助工具 |
|
||||
| `plugin-sdk/target-resolver-runtime` | 目标解析器辅助工具 | 共享目标解析器辅助工具 |
|
||||
| `plugin-sdk/string-normalization-runtime` | 字符串规范化辅助工具 | slug / 字符串规范化辅助工具 |
|
||||
| `plugin-sdk/request-url` | 请求 URL 辅助工具 | 从类似请求的输入中提取字符串 URL |
|
||||
| `plugin-sdk/run-command` | 定时命令辅助工具 | 带标准化 stdout / stderr 的定时命令运行器 |
|
||||
| `plugin-sdk/param-readers` | 参数读取器 | 通用工具 / CLI 参数读取器 |
|
||||
| `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` | 请求 URL 辅助函数 | 从类请求输入中提取字符串 URL |
|
||||
| `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 表格辅助工具 | Markdown 表格模式辅助工具 |
|
||||
| `plugin-sdk/temp-path` | 临时路径辅助函数 | 共享临时下载路径辅助函数 |
|
||||
| `plugin-sdk/logging-core` | 日志辅助函数 | 子系统 logger 和脱敏辅助函数 |
|
||||
| `plugin-sdk/markdown-table-runtime` | Markdown 表格辅助函数 | Markdown 表格模式辅助函数 |
|
||||
| `plugin-sdk/reply-payload` | 消息回复类型 | 回复负载类型 |
|
||||
| `plugin-sdk/provider-setup` | 精选的本地 / 自托管提供商设置辅助工具 | 自托管提供商发现 / 配置辅助工具 |
|
||||
| `plugin-sdk/self-hosted-provider-setup` | 聚焦的 OpenAI 兼容自托管提供商设置辅助工具 | 同样的自托管提供商发现 / 配置辅助工具 |
|
||||
| `plugin-sdk/provider-auth-runtime` | 提供商运行时认证辅助工具 | 运行时 API key 解析辅助工具 |
|
||||
| `plugin-sdk/provider-auth-api-key` | 提供商 API key 设置辅助工具 | API key 新手引导 / 配置文件写入辅助工具 |
|
||||
| `plugin-sdk/provider-auth-result` | 提供商 auth-result 辅助工具 | 标准 OAuth auth-result 构建器 |
|
||||
| `plugin-sdk/provider-auth-login` | 提供商交互式登录辅助工具 | 共享交互式登录辅助工具 |
|
||||
| `plugin-sdk/provider-env-vars` | 提供商环境变量辅助工具 | 提供商认证环境变量查找辅助工具 |
|
||||
| `plugin-sdk/provider-model-shared` | 共享提供商 model / replay 辅助工具 | `ProviderReplayFamily`, `buildProviderReplayFamilyHooks`, `normalizeModelCompat`、共享 replay-policy 构建器、provider-endpoint 辅助工具以及 model-id 规范化辅助工具 |
|
||||
| `plugin-sdk/provider-catalog-shared` | 共享提供商目录辅助工具 | `findCatalogTemplate`, `buildSingleProviderApiKeyCatalog`, `supportsNativeStreamingUsageCompat`, `applyProviderNativeStreamingUsageCompat` |
|
||||
| `plugin-sdk/provider-onboard` | 提供商新手引导补丁 | 新手引导配置辅助工具 |
|
||||
| `plugin-sdk/provider-http` | 提供商 HTTP 辅助工具 | 通用提供商 HTTP / endpoint 能力辅助工具 |
|
||||
| `plugin-sdk/provider-web-fetch` | 提供商 web-fetch 辅助工具 | web-fetch 提供商注册 / 缓存辅助工具 |
|
||||
| `plugin-sdk/provider-web-search` | 提供商 web-search 辅助工具 | web-search 提供商注册 / 缓存 / 配置辅助工具 |
|
||||
| `plugin-sdk/provider-tools` | 提供商工具 / schema 兼容辅助工具 | `ProviderToolCompatFamily`, `buildProviderToolCompatFamilyHooks`、Gemini schema 清理 + 诊断,以及 xAI 兼容辅助工具,例如 `resolveXaiModelCompatPatch` / `applyXaiModelCompat` |
|
||||
| `plugin-sdk/provider-usage` | 提供商用量辅助工具 | `fetchClaudeUsage`, `fetchGeminiUsage`, `fetchGithubCopilotUsage` 以及其他提供商用量辅助工具 |
|
||||
| `plugin-sdk/provider-stream` | 提供商流包装辅助工具 | `ProviderStreamFamily`, `buildProviderStreamFamilyHooks`, `composeProviderStreamWrappers`、流包装器类型,以及共享的 Anthropic / Bedrock / Google / Kilocode / Moonshot / OpenAI / OpenRouter / Z.A.I / MiniMax / Copilot 包装辅助工具 |
|
||||
| `plugin-sdk/provider-setup` | 精选本地/自托管提供商设置辅助函数 | 自托管提供商发现/配置辅助函数 |
|
||||
| `plugin-sdk/self-hosted-provider-setup` | 聚焦的 OpenAI 兼容自托管提供商设置辅助函数 | 相同的自托管提供商发现/配置辅助函数 |
|
||||
| `plugin-sdk/provider-auth-runtime` | 提供商运行时凭证辅助函数 | 运行时 API 密钥解析辅助函数 |
|
||||
| `plugin-sdk/provider-auth-api-key` | 提供商 API 密钥设置辅助函数 | API 密钥新手引导/配置文件写入辅助函数 |
|
||||
| `plugin-sdk/provider-auth-result` | 提供商 auth-result 辅助函数 | 标准 OAuth auth-result 构建器 |
|
||||
| `plugin-sdk/provider-auth-login` | 提供商交互式登录辅助函数 | 共享交互式登录辅助函数 |
|
||||
| `plugin-sdk/provider-env-vars` | 提供商环境变量辅助函数 | 提供商凭证环境变量查找辅助函数 |
|
||||
| `plugin-sdk/provider-model-shared` | 共享提供商模型/重放辅助函数 | `ProviderReplayFamily`, `buildProviderReplayFamilyHooks`, `normalizeModelCompat`、共享重放策略构建器、提供商端点辅助函数和模型 id 标准化辅助函数 |
|
||||
| `plugin-sdk/provider-catalog-shared` | 共享提供商目录辅助函数 | `findCatalogTemplate`, `buildSingleProviderApiKeyCatalog`, `supportsNativeStreamingUsageCompat`, `applyProviderNativeStreamingUsageCompat` |
|
||||
| `plugin-sdk/provider-onboard` | 提供商新手引导补丁 | 新手引导配置辅助函数 |
|
||||
| `plugin-sdk/provider-http` | 提供商 HTTP 辅助函数 | 通用提供商 HTTP/端点能力辅助函数 |
|
||||
| `plugin-sdk/provider-web-fetch` | 提供商 web-fetch 辅助函数 | web-fetch 提供商注册/缓存辅助函数 |
|
||||
| `plugin-sdk/provider-web-search` | 提供商 web-search 辅助函数 | Web 搜索提供商注册/缓存/配置辅助函数 |
|
||||
| `plugin-sdk/provider-tools` | 提供商工具/schema 兼容辅助函数 | `ProviderToolCompatFamily`, `buildProviderToolCompatFamilyHooks`、Gemini schema 清理 + 诊断,以及 xAI 兼容辅助函数,如 `resolveXaiModelCompatPatch` / `applyXaiModelCompat` |
|
||||
| `plugin-sdk/provider-usage` | 提供商使用量辅助函数 | `fetchClaudeUsage`, `fetchGeminiUsage`, `fetchGithubCopilotUsage` 以及其他提供商使用量辅助函数 |
|
||||
| `plugin-sdk/provider-stream` | 提供商流包装辅助函数 | `ProviderStreamFamily`, `buildProviderStreamFamilyHooks`, `composeProviderStreamWrappers`、流包装器类型,以及共享的 Anthropic/Bedrock/Google/Kilocode/Moonshot/OpenAI/OpenRouter/Z.A.I/MiniMax/Copilot 包装辅助函数 |
|
||||
| `plugin-sdk/keyed-async-queue` | 有序异步队列 | `KeyedAsyncQueue` |
|
||||
| `plugin-sdk/media-runtime` | 共享媒体辅助工具 | 媒体获取 / 转换 / 存储辅助工具以及媒体负载构建器 |
|
||||
| `plugin-sdk/media-generation-runtime` | 共享 media-generation 辅助工具 | 图像 / 视频 / 音乐生成的共享故障切换辅助工具、候选项选择和缺失模型提示 |
|
||||
| `plugin-sdk/media-understanding` | media-understanding 辅助工具 | media understanding 提供商类型以及面向提供商的图像 / 音频辅助导出 |
|
||||
| `plugin-sdk/text-runtime` | 共享文本辅助工具 | 对智能体可见文本的剥离、markdown 渲染 / 分块 / 表格辅助工具、脱敏辅助工具、directive-tag 辅助工具、安全文本工具以及相关文本 / 日志辅助工具 |
|
||||
| `plugin-sdk/text-chunking` | 文本分块辅助工具 | 出站文本分块辅助工具 |
|
||||
| `plugin-sdk/speech` | 语音辅助工具 | 语音提供商类型以及面向提供商的 directive、注册表和校验辅助工具 |
|
||||
| `plugin-sdk/speech-core` | 共享语音核心 | 语音提供商类型、注册表、指令、规范化 |
|
||||
| `plugin-sdk/realtime-transcription` | 实时转写辅助工具 | 提供商类型和注册表辅助工具 |
|
||||
| `plugin-sdk/realtime-voice` | 实时语音辅助工具 | 提供商类型和注册表辅助工具 |
|
||||
| `plugin-sdk/image-generation-core` | 共享图像生成核心 | 图像生成类型、故障切换、认证和注册表辅助工具 |
|
||||
| `plugin-sdk/music-generation` | 音乐生成辅助工具 | 音乐生成 provider / request / result 类型 |
|
||||
| `plugin-sdk/music-generation-core` | 共享音乐生成核心 | 音乐生成类型、故障切换辅助工具、provider 查找和 model-ref 解析 |
|
||||
| `plugin-sdk/video-generation` | 视频生成辅助工具 | 视频生成 provider / request / result 类型 |
|
||||
| `plugin-sdk/video-generation-core` | 共享视频生成核心 | 视频生成类型、故障切换辅助工具、provider 查找和 model-ref 解析 |
|
||||
| `plugin-sdk/interactive-runtime` | 交互式回复辅助工具 | 交互式回复负载规范化 / 归约 |
|
||||
| `plugin-sdk/channel-config-primitives` | 渠道配置原语 | 窄范围渠道 config-schema 原语 |
|
||||
| `plugin-sdk/channel-config-writes` | 渠道配置写入辅助工具 | 渠道配置写入授权辅助工具 |
|
||||
| `plugin-sdk/channel-plugin-common` | 共享渠道前导模块 | 共享渠道插件前导导出 |
|
||||
| `plugin-sdk/channel-status` | 渠道状态辅助工具 | 共享渠道状态快照 / 摘要辅助工具 |
|
||||
| `plugin-sdk/allowlist-config-edit` | allowlist 配置辅助工具 | allowlist 配置编辑 / 读取辅助工具 |
|
||||
| `plugin-sdk/group-access` | 群组访问辅助工具 | 共享群组访问决策辅助工具 |
|
||||
| `plugin-sdk/direct-dm` | 直接私信辅助工具 | 共享直接私信认证 / 守卫辅助工具 |
|
||||
| `plugin-sdk/extension-shared` | 共享扩展辅助工具 | 被动渠道 / 状态辅助原语 |
|
||||
| `plugin-sdk/webhook-targets` | webhook 目标辅助工具 | webhook 目标注册表和路由安装辅助工具 |
|
||||
| `plugin-sdk/webhook-path` | webhook 路径辅助工具 | webhook 路径规范化辅助工具 |
|
||||
| `plugin-sdk/web-media` | 共享 web 媒体辅助工具 | 远程 / 本地媒体加载辅助工具 |
|
||||
| `plugin-sdk/media-runtime` | 共享媒体辅助函数 | 媒体获取/转换/存储辅助函数,以及媒体负载构建器 |
|
||||
| `plugin-sdk/media-generation-runtime` | 共享媒体生成辅助函数 | 图像/视频/音乐生成的共享回退辅助函数、候选选择和缺失模型提示 |
|
||||
| `plugin-sdk/media-understanding` | 媒体理解辅助函数 | 媒体理解提供商类型,以及面向提供商的图像/音频辅助函数导出 |
|
||||
| `plugin-sdk/text-runtime` | 共享文本辅助函数 | 助手可见文本剥离、markdown 渲染/分块/表格辅助函数、脱敏辅助函数、directive-tag 辅助函数、安全文本工具函数,以及相关文本/日志辅助函数 |
|
||||
| `plugin-sdk/text-chunking` | 文本分块辅助函数 | 出站文本分块辅助函数 |
|
||||
| `plugin-sdk/speech` | 语音辅助函数 | 语音提供商类型,以及面向提供商的 directive、注册表和校验辅助函数 |
|
||||
| `plugin-sdk/speech-core` | 共享语音核心 | 语音提供商类型、注册表、指令、标准化 |
|
||||
| `plugin-sdk/realtime-transcription` | 实时转录辅助函数 | 提供商类型和注册表辅助函数 |
|
||||
| `plugin-sdk/realtime-voice` | 实时语音辅助函数 | 提供商类型和注册表辅助函数 |
|
||||
| `plugin-sdk/image-generation-core` | 共享图像生成核心 | 图像生成类型、回退、凭证和注册表辅助函数 |
|
||||
| `plugin-sdk/music-generation` | 音乐生成辅助函数 | 音乐生成提供商/请求/结果类型 |
|
||||
| `plugin-sdk/music-generation-core` | 共享音乐生成核心 | 音乐生成类型、回退辅助函数、提供商查找和模型引用解析 |
|
||||
| `plugin-sdk/video-generation` | 视频生成辅助函数 | 视频生成提供商/请求/结果类型 |
|
||||
| `plugin-sdk/video-generation-core` | 共享视频生成核心 | 视频生成类型、回退辅助函数、提供商查找和模型引用解析 |
|
||||
| `plugin-sdk/interactive-runtime` | 交互式回复辅助函数 | 交互式回复负载标准化/归并 |
|
||||
| `plugin-sdk/channel-config-primitives` | 渠道配置原语 | 窄接口渠道 config-schema 原语 |
|
||||
| `plugin-sdk/channel-config-writes` | 渠道配置写入辅助函数 | 渠道配置写入授权辅助函数 |
|
||||
| `plugin-sdk/channel-plugin-common` | 共享渠道前导层 | 共享渠道插件前导导出 |
|
||||
| `plugin-sdk/channel-status` | 渠道状态辅助函数 | 共享渠道状态快照/摘要辅助函数 |
|
||||
| `plugin-sdk/allowlist-config-edit` | 允许列表配置辅助函数 | 允许列表配置编辑/读取辅助函数 |
|
||||
| `plugin-sdk/group-access` | 群组访问辅助函数 | 共享群组访问决策辅助函数 |
|
||||
| `plugin-sdk/direct-dm` | 直接私信辅助函数 | 共享直接私信凭证/防护辅助函数 |
|
||||
| `plugin-sdk/extension-shared` | 共享扩展辅助函数 | 被动渠道/状态和环境代理辅助原语 |
|
||||
| `plugin-sdk/webhook-targets` | webhook 目标辅助函数 | webhook 目标注册表和路由安装辅助函数 |
|
||||
| `plugin-sdk/webhook-path` | webhook 路径辅助函数 | webhook 路径标准化辅助函数 |
|
||||
| `plugin-sdk/web-media` | 共享 Web 媒体辅助函数 | 远程/本地媒体加载辅助函数 |
|
||||
| `plugin-sdk/zod` | Zod 重新导出 | 为插件 SDK 使用方重新导出的 `zod` |
|
||||
| `plugin-sdk/memory-core` | 内置 memory-core 辅助工具 | memory manager / config / file / CLI 辅助接口 |
|
||||
| `plugin-sdk/memory-core-engine-runtime` | memory engine 运行时门面 | memory index / search 运行时门面 |
|
||||
| `plugin-sdk/memory-core-host-engine-foundation` | memory host foundation engine | memory host foundation engine 导出 |
|
||||
| `plugin-sdk/memory-core-host-engine-embeddings` | memory host embedding engine | memory host embedding engine 导出 |
|
||||
| `plugin-sdk/memory-core-host-engine-qmd` | memory host QMD engine | memory host QMD engine 导出 |
|
||||
| `plugin-sdk/memory-core-host-engine-storage` | memory host storage engine | memory host storage engine 导出 |
|
||||
| `plugin-sdk/memory-core-host-multimodal` | memory host multimodal 辅助工具 | memory host multimodal 辅助工具 |
|
||||
| `plugin-sdk/memory-core-host-query` | memory host query 辅助工具 | memory host query 辅助工具 |
|
||||
| `plugin-sdk/memory-core-host-secret` | memory host secret 辅助工具 | memory host secret 辅助工具 |
|
||||
| `plugin-sdk/memory-core-host-events` | memory host 事件日志辅助工具 | memory host 事件日志辅助工具 |
|
||||
| `plugin-sdk/memory-core-host-status` | memory host 状态辅助工具 | memory host 状态辅助工具 |
|
||||
| `plugin-sdk/memory-core-host-runtime-cli` | memory host CLI 运行时 | memory host CLI 运行时辅助工具 |
|
||||
| `plugin-sdk/memory-core-host-runtime-core` | memory host 核心运行时 | memory host 核心运行时辅助工具 |
|
||||
| `plugin-sdk/memory-core-host-runtime-files` | memory host 文件 / 运行时辅助工具 | memory host 文件 / 运行时辅助工具 |
|
||||
| `plugin-sdk/memory-host-core` | memory host 核心运行时别名 | 面向厂商中立的 memory host 核心运行时辅助工具别名 |
|
||||
| `plugin-sdk/memory-host-events` | memory host 事件日志别名 | 面向厂商中立的 memory host 事件日志辅助工具别名 |
|
||||
| `plugin-sdk/memory-host-files` | memory host 文件 / 运行时别名 | 面向厂商中立的 memory host 文件 / 运行时辅助工具别名 |
|
||||
| `plugin-sdk/memory-host-markdown` | 托管 markdown 辅助工具 | 面向 memory 邻接插件的共享托管 markdown 辅助工具 |
|
||||
| `plugin-sdk/memory-host-search` | 活跃 memory 搜索门面 | 惰性 active-memory search-manager 运行时门面 |
|
||||
| `plugin-sdk/memory-host-status` | memory host 状态别名 | 面向厂商中立的 memory host 状态辅助工具别名 |
|
||||
| `plugin-sdk/memory-lancedb` | 内置 memory-lancedb 辅助工具 | memory-lancedb 辅助接口 |
|
||||
| `plugin-sdk/testing` | 测试工具 | 测试辅助工具和 mocks |
|
||||
| `plugin-sdk/memory-core` | 内置 memory-core 辅助函数 | 内存管理器/配置/文件/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 引擎 | 内存宿主 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 辅助函数 | 内存宿主 secret 辅助函数 |
|
||||
| `plugin-sdk/memory-core-host-events` | 内存宿主事件日志辅助函数 | 内存宿主事件日志辅助函数 |
|
||||
| `plugin-sdk/memory-core-host-status` | 内存宿主状态辅助函数 | 内存宿主状态辅助函数 |
|
||||
| `plugin-sdk/memory-core-host-runtime-cli` | 内存宿主 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 辅助函数 | 适用于 memory 邻接插件的共享托管 markdown 辅助函数 |
|
||||
| `plugin-sdk/memory-host-search` | 活跃内存搜索门面 | 惰性活跃内存 search-manager 运行时门面 |
|
||||
| `plugin-sdk/memory-host-status` | 内存宿主状态别名 | 面向厂商中立的内存宿主状态辅助函数别名 |
|
||||
| `plugin-sdk/memory-lancedb` | 内置 memory-lancedb 辅助函数 | memory-lancedb 辅助接口 |
|
||||
| `plugin-sdk/testing` | 测试工具 | 测试辅助函数和 mocks |
|
||||
</Accordion>
|
||||
|
||||
此表有意只包含常见迁移子集,而非完整的 SDK 接口。完整的 200+ 入口点列表位于
|
||||
此表刻意只列出常见迁移子集,而不是完整 SDK 接口。
|
||||
完整的 200+ 入口点列表位于
|
||||
`scripts/lib/plugin-sdk-entrypoints.json`。
|
||||
|
||||
该列表仍然包含一些内置插件辅助接口,例如
|
||||
该列表仍包含一些内置插件辅助接口,例如
|
||||
`plugin-sdk/feishu`、`plugin-sdk/feishu-setup`、`plugin-sdk/zalo`、
|
||||
`plugin-sdk/zalo-setup` 和 `plugin-sdk/matrix*`。这些接口仍然会导出,以便支持内置插件维护和兼容性,但它们被有意排除在常见迁移表之外,也不是新插件代码的推荐目标。
|
||||
`plugin-sdk/zalo-setup` 和 `plugin-sdk/matrix*`。这些接口仍会导出,
|
||||
用于内置插件维护和兼容性,但它们被刻意从常见迁移表中省略,也不是新插件代码的推荐目标。
|
||||
|
||||
同样的规则也适用于其他内置辅助工具家族,例如:
|
||||
同样的规则也适用于其他内置辅助函数家族,例如:
|
||||
|
||||
- 浏览器支持辅助工具:`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`
|
||||
- 浏览器支持辅助函数:`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`
|
||||
- Matrix:`plugin-sdk/matrix*`
|
||||
- LINE:`plugin-sdk/line*`
|
||||
- IRC:`plugin-sdk/irc*`
|
||||
- 内置辅助 / 插件接口,例如 `plugin-sdk/googlechat`,
|
||||
`plugin-sdk/zalouser`, `plugin-sdk/bluebubbles*`,
|
||||
`plugin-sdk/mattermost*`, `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/googlechat`、
|
||||
`plugin-sdk/zalouser`、`plugin-sdk/bluebubbles*`、
|
||||
`plugin-sdk/mattermost*`、`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` 当前公开的窄范围 token 辅助接口为
|
||||
`plugin-sdk/github-copilot-token` 目前公开了窄接口令牌辅助接口:
|
||||
`DEFAULT_COPILOT_API_BASE_URL`、
|
||||
`deriveCopilotApiBaseUrlFromToken` 和 `resolveCopilotApiToken`。
|
||||
|
||||
请使用与任务最匹配的最窄导入路径。如果你找不到某个导出,请查看 `src/plugin-sdk/` 中的源代码,或在 Discord 中提问。
|
||||
请使用与任务最匹配的最窄导入路径。如果你找不到某个导出,请查看
|
||||
`src/plugin-sdk/` 中的源码,或在 Discord 中提问。
|
||||
|
||||
## 移除时间线
|
||||
|
||||
| 时间 | 会发生什么 |
|
||||
| ---------------------- | ----------------------------------------------------------------------- |
|
||||
| **现在** | 已弃用接口会发出运行时警告 |
|
||||
| **下一个主版本** | 已弃用接口将被移除;仍在使用它们的插件将会失败 |
|
||||
| **下一个主版本** | 已弃用接口将被移除;仍在使用它们的插件将会失效 |
|
||||
|
||||
所有核心插件都已经完成迁移。外部插件应在下一个主版本之前完成迁移。
|
||||
所有核心插件都已完成迁移。外部插件应在下一个主版本之前完成迁移。
|
||||
|
||||
## 临时抑制警告
|
||||
|
||||
在迁移期间,你可以设置这些环境变量:
|
||||
在你迁移期间,可以设置以下环境变量:
|
||||
|
||||
```bash
|
||||
OPENCLAW_SUPPRESS_PLUGIN_SDK_COMPAT_WARNING=1 openclaw gateway run
|
||||
@ -343,7 +355,7 @@ OPENCLAW_SUPPRESS_EXTENSION_API_WARNING=1 openclaw gateway run
|
||||
## 相关内容
|
||||
|
||||
- [入门指南](/zh-CN/plugins/building-plugins) — 构建你的第一个插件
|
||||
- [SDK 概览](/zh-CN/plugins/sdk-overview) — 完整的子路径导入参考
|
||||
- [SDK 概览](/zh-CN/plugins/sdk-overview) — 完整子路径导入参考
|
||||
- [渠道插件](/zh-CN/plugins/sdk-channel-plugins) — 构建渠道插件
|
||||
- [提供商插件](/zh-CN/plugins/sdk-provider-plugins) — 构建提供商插件
|
||||
- [插件内部机制](/zh-CN/plugins/architecture) — 架构深入解析
|
||||
|
||||
@ -1,26 +1,26 @@
|
||||
---
|
||||
read_when:
|
||||
- 你需要知道应该从哪个 SDK 子路径导入
|
||||
- 你想查看 OpenClawPluginApi 上所有注册方法的参考
|
||||
- 你正在查找某个特定的 SDK 导出
|
||||
- 你需要了解应该从哪个 SDK 子路径导入
|
||||
- 你想查阅 OpenClawPluginApi 上所有注册方法的参考说明
|
||||
- 你正在查找某个特定的 SDK 导出项
|
||||
sidebarTitle: SDK Overview
|
||||
summary: 导入映射、注册 API 参考和 SDK 架构
|
||||
title: 插件 SDK 概览
|
||||
x-i18n:
|
||||
generated_at: "2026-04-06T12:44:55Z"
|
||||
generated_at: "2026-04-06T15:30:53Z"
|
||||
model: gpt-5.4
|
||||
provider: openai
|
||||
source_hash: e045097753f33d13d570f6ce5297d2a7c0f0ad8b31515d0d9021386c8004354c
|
||||
source_hash: a08fa2d63e82ec921d63310eeede4ef868c452471402a55a1133deeaf78db0a8
|
||||
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)
|
||||
@ -35,22 +35,29 @@ 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 契约。
|
||||
带渠道品牌的辅助接缝。内置插件应在其自己的 `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`。
|
||||
|
||||
保留的内置插件辅助子路径仍会出现在该生成列表中。除非某个文档页面明确将其提升为公共接口,否则请将这些视为实现细节/兼容性接口。
|
||||
保留的内置插件辅助子路径仍会出现在该生成列表中。
|
||||
除非某个文档页面明确将其提升为公开接口,否则应将其视为实现细节/兼容性表面。
|
||||
|
||||
### 插件入口
|
||||
### 插件入口点
|
||||
|
||||
| 子路径 | 关键导出 |
|
||||
| --------------------------- | -------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
@ -66,43 +73,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` | 共享的设置向导辅助函数、允许列表提示、设置状态构建器 |
|
||||
| `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/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/allowlist-config-edit` | 允许列表配置编辑/读取辅助函数 |
|
||||
| `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>
|
||||
@ -111,102 +118,102 @@ 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-setup` | 精选的本地/self-hosted 提供商设置辅助函数 |
|
||||
| `plugin-sdk/self-hosted-provider-setup` | 聚焦 OpenAI 兼容 self-hosted 提供商设置辅助函数 |
|
||||
| `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-runtime` | 提供商插件的运行时 API key 解析辅助函数 |
|
||||
| `plugin-sdk/provider-auth-api-key` | API key 新手引导/profile 写入辅助函数,例如 `upsertApiKeyProfile` |
|
||||
| `plugin-sdk/provider-auth-result` | 标准 OAuth auth-result 构建器 |
|
||||
| `plugin-sdk/provider-auth-login` | 提供商插件的共享交互式登录辅助函数 |
|
||||
| `plugin-sdk/provider-env-vars` | 提供商认证环境变量查找辅助函数 |
|
||||
| `plugin-sdk/provider-auth` | `createProviderApiKeyAuthMethod`, `ensureApiKeyFromOptionEnvOrPrompt`, `upsertAuthProfile`, `upsertApiKeyProfile`, `writeOAuthCredentials` |
|
||||
| `plugin-sdk/provider-model-shared` | `ProviderReplayFamily`, `buildProviderReplayFamilyHooks`, `normalizeModelCompat`、共享 replay-policy 构建器、提供商端点辅助工具,以及如 `normalizeNativeXaiModelId` 之类的 model-id 规范化辅助工具 |
|
||||
| `plugin-sdk/provider-model-shared` | `ProviderReplayFamily`, `buildProviderReplayFamilyHooks`, `normalizeModelCompat`、共享 replay-policy 构建器、provider-endpoint 辅助函数,以及 `normalizeNativeXaiModelId` 等 model-id 归一化辅助函数 |
|
||||
| `plugin-sdk/provider-catalog-shared` | `findCatalogTemplate`, `buildSingleProviderApiKeyCatalog`, `supportsNativeStreamingUsageCompat`, `applyProviderNativeStreamingUsageCompat` |
|
||||
| `plugin-sdk/provider-http` | 通用提供商 HTTP/端点能力辅助工具 |
|
||||
| `plugin-sdk/provider-web-fetch` | 网页抓取提供商注册/缓存辅助工具 |
|
||||
| `plugin-sdk/provider-web-search` | 网页搜索提供商注册/缓存/配置辅助工具 |
|
||||
| `plugin-sdk/provider-tools` | `ProviderToolCompatFamily`, `buildProviderToolCompatFamilyHooks`, Gemini schema 清理 + 诊断,以及如 `resolveXaiModelCompatPatch` / `applyXaiModelCompat` 之类的 xAI 兼容辅助工具 |
|
||||
| `plugin-sdk/provider-usage` | `fetchClaudeUsage` 等 |
|
||||
| `plugin-sdk/provider-stream` | `ProviderStreamFamily`, `buildProviderStreamFamilyHooks`, `composeProviderStreamWrappers`、流包装器类型,以及共享的 Anthropic/Bedrock/Google/Kilocode/Moonshot/OpenAI/OpenRouter/Z.A.I/MiniMax/Copilot 包装器辅助工具 |
|
||||
| `plugin-sdk/provider-onboard` | 新手引导配置补丁辅助工具 |
|
||||
| `plugin-sdk/global-singleton` | 进程本地 singleton/map/cache 辅助工具 |
|
||||
| `plugin-sdk/provider-http` | 通用提供商 HTTP/端点能力辅助函数 |
|
||||
| `plugin-sdk/provider-web-fetch` | Web-fetch 提供商注册/缓存辅助函数 |
|
||||
| `plugin-sdk/provider-web-search` | Web 搜索提供商注册/缓存/配置辅助函数 |
|
||||
| `plugin-sdk/provider-tools` | `ProviderToolCompatFamily`, `buildProviderToolCompatFamilyHooks`、Gemini schema 清理 + 诊断,以及 xAI 兼容辅助函数,例如 `resolveXaiModelCompatPatch` / `applyXaiModelCompat` |
|
||||
| `plugin-sdk/provider-usage` | `fetchClaudeUsage` 及类似函数 |
|
||||
| `plugin-sdk/provider-stream` | `ProviderStreamFamily`, `buildProviderStreamFamilyHooks`, `composeProviderStreamWrappers`、流包装器类型,以及共享 Anthropic/Bedrock/Google/Kilocode/Moonshot/OpenAI/OpenRouter/Z.A.I/MiniMax/Copilot 包装辅助函数 |
|
||||
| `plugin-sdk/provider-onboard` | 新手引导配置补丁辅助函数 |
|
||||
| `plugin-sdk/global-singleton` | 进程本地 singleton/map/cache 辅助函数 |
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="认证与安全子路径">
|
||||
| 子路径 | 关键导出 |
|
||||
| --- | --- |
|
||||
| `plugin-sdk/command-auth` | `resolveControlCommandGate`、命令注册表辅助工具、发送者授权辅助工具 |
|
||||
| `plugin-sdk/approval-auth-runtime` | 审批人解析和同聊天操作认证辅助工具 |
|
||||
| `plugin-sdk/approval-client-runtime` | 原生 exec 审批 profile/filter 辅助工具 |
|
||||
| `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-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` | 共享信任、私信门控、外部内容和秘密收集辅助工具 |
|
||||
| `plugin-sdk/ssrf-policy` | 主机 allowlist 和私有网络 SSRF 策略辅助工具 |
|
||||
| `plugin-sdk/ssrf-runtime` | pinned-dispatcher、受 SSRF 保护的 fetch,以及 SSRF 策略辅助工具 |
|
||||
| `plugin-sdk/secret-input` | 秘密输入解析辅助工具 |
|
||||
| `plugin-sdk/webhook-ingress` | webhook 请求/目标辅助工具 |
|
||||
| `plugin-sdk/webhook-request-guards` | 请求体大小/超时辅助工具 |
|
||||
| `plugin-sdk/security-runtime` | 共享信任、私信门控、外部内容和 secret 收集辅助函数 |
|
||||
| `plugin-sdk/ssrf-policy` | 主机允许列表和私有网络 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` | 请求体大小/超时辅助函数 |
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="运行时与存储子路径">
|
||||
| 子路径 | 关键导出 |
|
||||
| --- | --- |
|
||||
| `plugin-sdk/runtime` | 宽泛的运行时/日志/备份/插件安装辅助工具 |
|
||||
| `plugin-sdk/runtime-env` | 狭义运行时环境、logger、timeout、retry 和 backoff 辅助工具 |
|
||||
| `plugin-sdk/runtime` | 广义运行时/日志/备份/插件安装辅助函数 |
|
||||
| `plugin-sdk/runtime-env` | 窄范围运行时环境、logger、超时、重试和退避辅助函数 |
|
||||
| `plugin-sdk/runtime-store` | `createPluginRuntimeStore` |
|
||||
| `plugin-sdk/plugin-runtime` | 共享插件命令/hook/HTTP/交互式辅助工具 |
|
||||
| `plugin-sdk/hook-runtime` | 共享 webhook/内部 hook 管道辅助工具 |
|
||||
| `plugin-sdk/lazy-runtime` | 延迟运行时导入/绑定辅助工具,例如 `createLazyRuntimeModule`、`createLazyRuntimeMethod` 和 `createLazyRuntimeSurface` |
|
||||
| `plugin-sdk/process-runtime` | 进程 exec 辅助工具 |
|
||||
| `plugin-sdk/cli-runtime` | CLI 格式化、等待和版本辅助工具 |
|
||||
| `plugin-sdk/gateway-runtime` | Gateway 网关客户端和渠道状态补丁辅助工具 |
|
||||
| `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/plugin-runtime` | 共享插件命令/hook/http/交互式辅助函数 |
|
||||
| `plugin-sdk/hook-runtime` | 共享 webhook/internal 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/插件审批辅助函数、审批能力构建器、认证/profile 辅助函数、原生路由/运行时辅助函数 |
|
||||
| `plugin-sdk/reply-runtime` | 共享入站/回复运行时辅助函数、分块、分发、心跳、回复规划器 |
|
||||
| `plugin-sdk/reply-dispatch-runtime` | 窄范围回复分发/完成辅助函数 |
|
||||
| `plugin-sdk/reply-history` | 共享短窗口回复历史辅助函数,例如 `buildHistoryContext`, `recordPendingHistoryEntry`, `clearHistoryEntriesIfEnabled` |
|
||||
| `plugin-sdk/reply-reference` | `createReplyReferencePlanner` |
|
||||
| `plugin-sdk/reply-chunking` | 狭义文本/markdown 分块辅助工具 |
|
||||
| `plugin-sdk/session-store-runtime` | 会话存储路径 + updated-at 辅助工具 |
|
||||
| `plugin-sdk/state-paths` | 状态/OAuth 目录路径辅助工具 |
|
||||
| `plugin-sdk/routing` | 路由/会话键/账户绑定辅助工具,例如 `resolveAgentRoute`、`buildAgentSessionKey` 和 `resolveDefaultAgentBoundAccountId` |
|
||||
| `plugin-sdk/status-helpers` | 共享渠道/账户状态摘要辅助工具、运行时状态默认值,以及问题元数据辅助工具 |
|
||||
| `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` | 可重入 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` | 可重入文件锁辅助函数 |
|
||||
| `plugin-sdk/persistent-dedupe` | 磁盘支持的去重缓存辅助函数 |
|
||||
| `plugin-sdk/acp-runtime` | ACP 运行时/会话和回复分发辅助函数 |
|
||||
| `plugin-sdk/agent-config-primitives` | 窄范围智能体运行时 config-schema 基元 |
|
||||
| `plugin-sdk/boolean-param` | 宽松布尔参数读取器 |
|
||||
| `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/dangerous-name-runtime` | 危险名称匹配解析辅助函数 |
|
||||
| `plugin-sdk/device-bootstrap` | 设备引导和配对 token 辅助函数 |
|
||||
| `plugin-sdk/extension-shared` | 共享被动渠道、状态和环境代理辅助基元 |
|
||||
| `plugin-sdk/models-provider-runtime` | `/models` 命令/提供商回复辅助函数 |
|
||||
| `plugin-sdk/skill-commands-runtime` | Skills 命令列表辅助函数 |
|
||||
| `plugin-sdk/native-command-registry` | 原生命令注册表/build/serialize 辅助函数 |
|
||||
| `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、代理和固定查找辅助函数 |
|
||||
| `plugin-sdk/host-runtime` | 主机名和 SCP 主机归一化辅助函数 |
|
||||
| `plugin-sdk/retry-runtime` | 重试配置和重试执行器辅助函数 |
|
||||
| `plugin-sdk/agent-runtime` | 智能体目录/身份/工作区辅助函数 |
|
||||
| `plugin-sdk/directory-runtime` | 基于配置的目录查询/去重 |
|
||||
| `plugin-sdk/keyed-async-queue` | `KeyedAsyncQueue` |
|
||||
</Accordion>
|
||||
@ -214,73 +221,73 @@ import { defineChannelPluginEntry } from "openclaw/plugin-sdk/channel-core";
|
||||
<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/日志辅助工具,例如助手可见文本剥离、markdown 渲染/分块/表格辅助工具、脱敏辅助工具、指令标签辅助工具和安全文本工具 |
|
||||
| `plugin-sdk/text-chunking` | 出站文本分块辅助工具 |
|
||||
| `plugin-sdk/speech` | 语音提供商类型,以及面向提供商的指令、注册表和验证辅助工具 |
|
||||
| `plugin-sdk/speech-core` | 共享语音提供商类型、注册表、指令和规范化辅助工具 |
|
||||
| `plugin-sdk/realtime-transcription` | 实时转录提供商类型和注册表辅助工具 |
|
||||
| `plugin-sdk/realtime-voice` | 实时语音提供商类型和注册表辅助工具 |
|
||||
| `plugin-sdk/text-runtime` | 共享文本/Markdown/日志辅助函数,例如 assistant 可见文本剥离、Markdown 渲染/分块/表格辅助函数、脱敏辅助函数、directive-tag 辅助函数和安全文本工具 |
|
||||
| `plugin-sdk/text-chunking` | 出站文本分块辅助函数 |
|
||||
| `plugin-sdk/speech` | 语音提供商类型,以及面向提供商的 directive、注册表和校验辅助函数 |
|
||||
| `plugin-sdk/speech-core` | 共享语音提供商类型、注册表、directive 和归一化辅助函数 |
|
||||
| `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/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="Memory 子路径">
|
||||
<Accordion title="内存子路径">
|
||||
| 子路径 | 关键导出 |
|
||||
| --- | --- |
|
||||
| `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 辅助接口 |
|
||||
| `plugin-sdk/memory-core` | 内置 memory-core 辅助表面,用于 manager/config/file/CLI 辅助函数 |
|
||||
| `plugin-sdk/memory-core-engine-runtime` | 内存索引/搜索运行时门面 |
|
||||
| `plugin-sdk/memory-core-host-engine-foundation` | 内存 host foundation 引擎导出 |
|
||||
| `plugin-sdk/memory-core-host-engine-embeddings` | 内存 host embedding 引擎导出 |
|
||||
| `plugin-sdk/memory-core-host-engine-qmd` | 内存 host QMD 引擎导出 |
|
||||
| `plugin-sdk/memory-core-host-engine-storage` | 内存 host storage 引擎导出 |
|
||||
| `plugin-sdk/memory-core-host-multimodal` | 内存 host 多模态辅助函数 |
|
||||
| `plugin-sdk/memory-core-host-query` | 内存 host 查询辅助函数 |
|
||||
| `plugin-sdk/memory-core-host-secret` | 内存 host secret 辅助函数 |
|
||||
| `plugin-sdk/memory-core-host-events` | 内存 host 事件日志辅助函数 |
|
||||
| `plugin-sdk/memory-core-host-status` | 内存 host 状态辅助函数 |
|
||||
| `plugin-sdk/memory-core-host-runtime-cli` | 内存 host CLI 运行时辅助函数 |
|
||||
| `plugin-sdk/memory-core-host-runtime-core` | 内存 host 核心运行时辅助函数 |
|
||||
| `plugin-sdk/memory-core-host-runtime-files` | 内存 host 文件/运行时辅助函数 |
|
||||
| `plugin-sdk/memory-host-core` | 面向厂商中立的 memory host 核心运行时辅助函数别名 |
|
||||
| `plugin-sdk/memory-host-events` | 面向厂商中立的内存 host 事件日志辅助函数别名 |
|
||||
| `plugin-sdk/memory-host-files` | 面向厂商中立的内存 host 文件/运行时辅助函数别名 |
|
||||
| `plugin-sdk/memory-host-markdown` | 用于内存相邻插件的共享托管 Markdown 辅助函数 |
|
||||
| `plugin-sdk/memory-host-search` | 用于访问 search-manager 的活跃内存运行时门面 |
|
||||
| `plugin-sdk/memory-host-status` | 面向厂商中立的内存 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-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 插件支持辅助函数(`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.registerCliBackend(...)` | 本地 CLI 推理后端 |
|
||||
@ -292,19 +299,19 @@ import { defineChannelPluginEntry } from "openclaw/plugin-sdk/channel-core";
|
||||
| `api.registerImageGenerationProvider(...)` | 图像生成 |
|
||||
| `api.registerMusicGenerationProvider(...)` | 音乐生成 |
|
||||
| `api.registerVideoGenerationProvider(...)` | 视频生成 |
|
||||
| `api.registerWebFetchProvider(...)` | 网页抓取 / 爬取提供商 |
|
||||
| `api.registerWebSearchProvider(...)` | 网页搜索 |
|
||||
| `api.registerWebFetchProvider(...)` | Web 获取 / 抓取提供商 |
|
||||
| `api.registerWebSearchProvider(...)` | Web 搜索 |
|
||||
|
||||
### 工具与命令
|
||||
|
||||
| 方法 | 注册内容 |
|
||||
| 方法 | 注册的内容 |
|
||||
| ------------------------------- | --------------------------------------------- |
|
||||
| `api.registerTool(tool, opts?)` | 智能体工具(必需,或 `{ optional: true }`) |
|
||||
| `api.registerTool(tool, opts?)` | 智能体工具(必需或 `{ optional: true }`) |
|
||||
| `api.registerCommand(def)` | 自定义命令(绕过 LLM) |
|
||||
|
||||
### 基础设施
|
||||
|
||||
| 方法 | 注册内容 |
|
||||
| 方法 | 注册的内容 |
|
||||
| ---------------------------------------------- | --------------------------------------- |
|
||||
| `api.registerHook(events, handler, opts?)` | 事件 hook |
|
||||
| `api.registerHttpRoute(params)` | Gateway 网关 HTTP 端点 |
|
||||
@ -312,20 +319,22 @@ import { defineChannelPluginEntry } from "openclaw/plugin-sdk/channel-core";
|
||||
| `api.registerCli(registrar, opts?)` | CLI 子命令 |
|
||||
| `api.registerService(service)` | 后台服务 |
|
||||
| `api.registerInteractiveHandler(registration)` | 交互式处理器 |
|
||||
| `api.registerMemoryPromptSupplement(builder)` | 附加式 memory 邻接提示词部分 |
|
||||
| `api.registerMemoryCorpusSupplement(adapter)` | 附加式 memory 搜索/读取语料 |
|
||||
| `api.registerMemoryPromptSupplement(builder)` | 附加型内存相邻提示区段 |
|
||||
| `api.registerMemoryCorpusSupplement(adapter)` | 附加型内存搜索/读取语料 |
|
||||
|
||||
保留的核心管理命名空间(`config.*`、`exec.approvals.*`、`wizard.*`、
|
||||
`update.*`)始终保持为 `operator.admin`,即使某个插件尝试为 Gateway 网关 方法分配更窄的作用域也是如此。对于插件自有方法,优先使用插件专属前缀。
|
||||
`update.*`)始终保持为 `operator.admin`,即使插件尝试分配更窄的
|
||||
Gateway 网关方法 scope 也是如此。对于插件自有方法,优先使用特定于插件的前缀。
|
||||
|
||||
### CLI 注册元数据
|
||||
|
||||
`api.registerCli(registrar, opts?)` 接受两类顶层元数据:
|
||||
|
||||
- `commands`:由该 registrar 拥有的显式命令根
|
||||
- `descriptors`:用于根 CLI 帮助、路由和延迟插件 CLI 注册的解析期命令描述符
|
||||
- `commands`:由 registrar 拥有的显式命令根
|
||||
- `descriptors`:用于根 CLI 帮助、路由和惰性插件 CLI 注册的解析期命令描述符
|
||||
|
||||
如果你希望某个插件命令在普通根 CLI 路径中保持延迟加载,请提供 `descriptors`,覆盖该 registrar 暴露的每一个顶层命令根。
|
||||
如果你希望插件命令在普通根 CLI 路径中保持惰性加载,
|
||||
请提供覆盖该 registrar 暴露的每个顶层命令根的 `descriptors`。
|
||||
|
||||
```typescript
|
||||
api.registerCli(
|
||||
@ -337,7 +346,7 @@ api.registerCli(
|
||||
descriptors: [
|
||||
{
|
||||
name: "matrix",
|
||||
description: "Manage Matrix accounts, verification, devices, and profile state",
|
||||
description: "管理 Matrix 账号、验证、设备和 profile 状态",
|
||||
hasSubcommands: true,
|
||||
},
|
||||
],
|
||||
@ -345,114 +354,126 @@ api.registerCli(
|
||||
);
|
||||
```
|
||||
|
||||
仅在你不需要延迟根 CLI 注册时,才单独使用 `commands`。这种急切兼容路径仍然受支持,但它不会安装基于 descriptor 的占位符来实现解析期延迟加载。
|
||||
只有在你不需要惰性根 CLI 注册时,才单独使用 `commands`。
|
||||
这种预加载兼容路径仍受支持,但它不会为解析期惰性加载安装基于
|
||||
descriptor 的占位符。
|
||||
|
||||
### CLI 后端注册
|
||||
|
||||
`api.registerCliBackend(...)` 允许插件拥有本地 AI CLI 后端(例如 `codex-cli`)的默认配置。
|
||||
`api.registerCliBackend(...)` 允许插件拥有本地
|
||||
AI CLI 后端(例如 `codex-cli`)的默认配置。
|
||||
|
||||
- 后端 `id` 会成为模型引用中的提供商前缀,例如 `codex-cli/gpt-5`。
|
||||
- 后端 `id` 会成为模型引用中像 `codex-cli/gpt-5` 这样的提供商前缀。
|
||||
- 后端 `config` 使用与 `agents.defaults.cliBackends.<id>` 相同的结构。
|
||||
- 用户配置仍然优先。OpenClaw 会在运行 CLI 之前,将 `agents.defaults.cliBackends.<id>` 合并覆盖到插件默认值之上。
|
||||
- 当某个后端在合并后需要兼容性重写时,使用 `normalizeConfig`(例如规范化旧的 flag 结构)。
|
||||
- 用户配置仍然优先。OpenClaw 会在运行 CLI 之前,将 `agents.defaults.cliBackends.<id>` 合并到插件默认值之上。
|
||||
- 当某个后端在合并后需要兼容性重写时,请使用 `normalizeConfig`
|
||||
(例如归一化旧的 flag 结构)。
|
||||
|
||||
### 独占插槽
|
||||
### 独占槽位
|
||||
|
||||
| 方法 | 注册内容 |
|
||||
| 方法 | 注册的内容 |
|
||||
| ------------------------------------------ | ------------------------------------- |
|
||||
| `api.registerContextEngine(id, factory)` | 上下文引擎(一次只能激活一个) |
|
||||
| `api.registerMemoryPromptSection(builder)` | Memory 提示词部分构建器 |
|
||||
| `api.registerMemoryFlushPlan(resolver)` | Memory 刷新计划解析器 |
|
||||
| `api.registerMemoryRuntime(runtime)` | Memory 运行时适配器 |
|
||||
| `api.registerContextEngine(id, factory)` | 上下文引擎(一次仅一个活动实例) |
|
||||
| `api.registerMemoryPromptSection(builder)` | 内存提示区段构建器 |
|
||||
| `api.registerMemoryFlushPlan(resolver)` | 内存刷新计划解析器 |
|
||||
| `api.registerMemoryRuntime(runtime)` | 内存运行时适配器 |
|
||||
|
||||
### Memory embedding 适配器
|
||||
### 内存嵌入适配器
|
||||
|
||||
| 方法 | 注册内容 |
|
||||
| 方法 | 注册的内容 |
|
||||
| ---------------------------------------------- | ---------------------------------------------- |
|
||||
| `api.registerMemoryEmbeddingProvider(adapter)` | 活动插件的 Memory embedding 适配器 |
|
||||
| `api.registerMemoryEmbeddingProvider(adapter)` | 活动插件的内存嵌入适配器 |
|
||||
|
||||
- `registerMemoryPromptSection`、`registerMemoryFlushPlan` 和
|
||||
`registerMemoryRuntime` 仅限 Memory 插件使用。
|
||||
- `registerMemoryEmbeddingProvider` 允许活动 Memory 插件注册一个或多个 embedding 适配器 ID(例如 `openai`、`gemini` 或插件自定义的 ID)。
|
||||
`registerMemoryRuntime` 是内存插件的独占能力。
|
||||
- `registerMemoryEmbeddingProvider` 允许活动内存插件注册一个
|
||||
或多个嵌入适配器 id(例如 `openai`、`gemini` 或插件自定义 id)。
|
||||
- 用户配置(例如 `agents.defaults.memorySearch.provider` 和
|
||||
`agents.defaults.memorySearch.fallback`)会解析为这些已注册的适配器 ID。
|
||||
`agents.defaults.memorySearch.fallback`)会基于这些已注册
|
||||
的适配器 id 进行解析。
|
||||
|
||||
### 事件与生命周期
|
||||
|
||||
| 方法 | 作用 |
|
||||
| 方法 | 功能 |
|
||||
| -------------------------------------------- | ----------------------------- |
|
||||
| `api.on(hookName, handler, opts?)` | 类型化生命周期 hook |
|
||||
| `api.onConversationBindingResolved(handler)` | 对话绑定回调 |
|
||||
| `api.onConversationBindingResolved(handler)` | 会话绑定回调 |
|
||||
|
||||
### hook 决策语义
|
||||
### 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` 相同),而不是覆盖。
|
||||
- `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.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.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` | 解析相对于插件根目录的路径 |
|
||||
|
||||
## 内部模块约定
|
||||
|
||||
在你的插件内部,使用本地 barrel 文件进行内部导入:
|
||||
在你的插件内部,请使用本地 barrel 文件进行内部导入:
|
||||
|
||||
```
|
||||
my-plugin/
|
||||
api.ts # 供外部使用方使用的公共导出
|
||||
runtime-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` 导出提供商构建器以及
|
||||
新手引导/配置辅助工具
|
||||
新手引导/配置辅助函数
|
||||
|
||||
<Warning>
|
||||
扩展生产代码也应避免导入 `openclaw/plugin-sdk/<other-plugin>`。
|
||||
如果某个辅助工具确实是共享的,请将其提升到中立的 SDK 子路径,
|
||||
如果某个辅助函数确实需要共享,请将其提升到中立的 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-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) — 深入的架构和能力模型
|
||||
- [SDK 迁移](/zh-CN/plugins/sdk-migration) — 从已弃用表面迁移
|
||||
- [插件内部机制](/zh-CN/plugins/architecture) — 深度架构和能力模型
|
||||
|
||||
@ -1,33 +1,31 @@
|
||||
---
|
||||
read_when:
|
||||
- 你正在构建一个新的模型提供商插件
|
||||
- 你想为 OpenClaw 添加一个兼容 OpenAI 的代理或自定义 LLM
|
||||
- 你需要了解提供商认证、目录和运行时 hooks
|
||||
- 你正在构建一个新的模型 provider 插件
|
||||
- 你想为 OpenClaw 添加一个与 OpenAI 兼容的代理或自定义 LLM
|
||||
- 你需要了解 provider 身份验证、目录和运行时 hooks
|
||||
sidebarTitle: Provider Plugins
|
||||
summary: 在 OpenClaw 中构建模型提供商插件的分步指南
|
||||
summary: 构建 OpenClaw 模型 provider 插件的分步指南
|
||||
title: 构建提供商插件
|
||||
x-i18n:
|
||||
generated_at: "2026-04-06T12:45:00Z"
|
||||
generated_at: "2026-04-06T15:30:57Z"
|
||||
model: gpt-5.4
|
||||
provider: openai
|
||||
source_hash: 89e7402742c87cb31265db1d98b34ca17ba57ad1c61952fa8c7da834306986f5
|
||||
source_hash: 4da82a353e1bf4fe6dc09e14b8614133ac96565679627de51415926014bd3990
|
||||
source_path: plugins/sdk-provider-plugins.md
|
||||
workflow: 15
|
||||
---
|
||||
|
||||
# 构建提供商插件
|
||||
|
||||
本指南将带你构建一个提供商插件,为 OpenClaw 添加一个模型提供商
|
||||
(LLM)。完成后,你将拥有一个具备模型目录、
|
||||
API 密钥认证和动态模型解析能力的提供商。
|
||||
本指南将带你构建一个 provider 插件,为 OpenClaw 添加一个模型 provider
|
||||
(LLM)。完成后,你将拥有一个具备模型目录、API 密钥身份验证和动态模型解析的 provider。
|
||||
|
||||
<Info>
|
||||
如果你之前从未构建过任何 OpenClaw 插件,请先阅读
|
||||
[入门指南](/zh-CN/plugins/building-plugins) 了解基本包
|
||||
结构和清单设置。
|
||||
[入门指南](/zh-CN/plugins/building-plugins) 以了解基本包结构和清单设置。
|
||||
</Info>
|
||||
|
||||
## 操作演练
|
||||
## 演练
|
||||
|
||||
<Steps>
|
||||
<a id="step-1-package-and-manifest"></a>
|
||||
@ -86,18 +84,12 @@ API 密钥认证和动态模型解析能力的提供商。
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
清单声明了 `providerAuthEnvVars`,这样 OpenClaw 就可以在不加载你的插件运行时的情况下检测
|
||||
凭证。`modelSupport` 是可选的,
|
||||
它让 OpenClaw 能够在运行时 hooks 存在之前,从像
|
||||
`acme-large` 这样的简写模型 id 自动加载你的提供商插件。如果你在
|
||||
ClawHub 上发布该提供商,那么 `package.json` 中的
|
||||
`openclaw.compat` 和 `openclaw.build` 字段
|
||||
是必需的。
|
||||
清单声明了 `providerAuthEnvVars`,这样 OpenClaw 就可以在不加载你的插件运行时的情况下检测凭证。`modelSupport` 是可选的,它允许 OpenClaw 在运行时 hooks 存在之前,就根据像 `acme-large` 这样的简写模型 id 自动加载你的 provider 插件。如果你要在 ClawHub 上发布 provider,那么 `package.json` 中的这些 `openclaw.compat` 和 `openclaw.build` 字段是必需的。
|
||||
|
||||
</Step>
|
||||
|
||||
<Step title="注册提供商">
|
||||
一个最小可用的提供商需要 `id`、`label`、`auth` 和 `catalog`:
|
||||
<Step title="注册 provider">
|
||||
一个最小可用的 provider 需要 `id`、`label`、`auth` 和 `catalog`:
|
||||
|
||||
```typescript index.ts
|
||||
import { definePluginEntry } from "openclaw/plugin-sdk/plugin-entry";
|
||||
@ -168,13 +160,12 @@ API 密钥认证和动态模型解析能力的提供商。
|
||||
});
|
||||
```
|
||||
|
||||
这样就是一个可工作的提供商。用户现在可以
|
||||
这就是一个可工作的 provider。用户现在可以
|
||||
`openclaw onboard --acme-ai-api-key <key>` 并选择
|
||||
`acme-ai/acme-large` 作为他们的模型。
|
||||
|
||||
对于只注册一个文本提供商、使用 API 密钥
|
||||
认证且只有单个基于目录的运行时的内置提供商,优先使用更窄的
|
||||
`defineSingleProviderPluginEntry(...)` 帮助器:
|
||||
对于只注册一个文本 provider、使用 API 密钥身份验证并带有单个目录支持运行时的内置 provider,优先使用更窄的
|
||||
`defineSingleProviderPluginEntry(...)` 辅助函数:
|
||||
|
||||
```typescript
|
||||
import { defineSingleProviderPluginEntry } from "openclaw/plugin-sdk/provider-entry";
|
||||
@ -209,28 +200,23 @@ API 密钥认证和动态模型解析能力的提供商。
|
||||
});
|
||||
```
|
||||
|
||||
如果你的认证流程在新手引导期间还需要修补 `models.providers.*`、别名以及
|
||||
智能体默认模型,请使用
|
||||
`openclaw/plugin-sdk/provider-onboard` 中的 preset 帮助器。最窄的帮助器是
|
||||
如果你的身份验证流程在新手引导期间还需要修补 `models.providers.*`、别名以及智能体默认模型,请使用 `openclaw/plugin-sdk/provider-onboard` 中的预设辅助函数。最窄的辅助函数是
|
||||
`createDefaultModelPresetAppliers(...)`、
|
||||
`createDefaultModelsPresetAppliers(...)` 和
|
||||
`createModelCatalogPresetAppliers(...)`。
|
||||
|
||||
当某个提供商的原生端点在普通
|
||||
`openai-completions` 传输上支持分块流式传输 usage blocks 时,优先使用
|
||||
`openclaw/plugin-sdk/provider-catalog-shared` 中的共享目录帮助器,而不是硬编码
|
||||
provider-id 检查。`supportsNativeStreamingUsageCompat(...)` 和
|
||||
`applyProviderNativeStreamingUsageCompat(...)` 会从端点 capability 映射中检测支持情况,因此即使插件使用自定义 provider id,原生 Moonshot/DashScope 风格的端点仍可选择启用。
|
||||
当 provider 的原生端点在常规 `openai-completions` 传输上支持流式 usage 块时,优先使用
|
||||
`openclaw/plugin-sdk/provider-catalog-shared` 中的共享目录辅助函数,而不是硬编码 provider-id 检查。`supportsNativeStreamingUsageCompat(...)` 和
|
||||
`applyProviderNativeStreamingUsageCompat(...)` 会从端点能力映射中检测支持情况,因此即使插件使用的是自定义 provider id,原生 Moonshot/DashScope 风格端点也仍然可以选择接入。
|
||||
|
||||
</Step>
|
||||
|
||||
<Step title="添加动态模型解析">
|
||||
如果你的提供商接受任意模型 ID(例如代理或路由器),
|
||||
请添加 `resolveDynamicModel`:
|
||||
如果你的 provider 接受任意模型 ID(例如代理或路由器),请添加 `resolveDynamicModel`:
|
||||
|
||||
```typescript
|
||||
api.registerProvider({
|
||||
// ... id, label, auth, catalog from above
|
||||
// ... 上面的 id、label、auth、catalog
|
||||
|
||||
resolveDynamicModel: (ctx) => ({
|
||||
id: ctx.modelId,
|
||||
@ -247,17 +233,15 @@ API 密钥认证和动态模型解析能力的提供商。
|
||||
});
|
||||
```
|
||||
|
||||
如果解析需要网络调用,请使用 `prepareDynamicModel` 进行异步
|
||||
预热 —— 完成后会再次运行 `resolveDynamicModel`。
|
||||
如果解析需要网络调用,请使用 `prepareDynamicModel` 进行异步预热——在它完成后,`resolveDynamicModel` 会再次运行。
|
||||
|
||||
</Step>
|
||||
|
||||
<Step title="按需添加运行时 hooks">
|
||||
大多数提供商只需要 `catalog` + `resolveDynamicModel`。随着你的提供商需求增加,
|
||||
再逐步添加 hooks。
|
||||
<Step title="添加运行时 hooks(按需)">
|
||||
大多数 provider 只需要 `catalog` + `resolveDynamicModel`。根据你的 provider 需求逐步添加 hooks。
|
||||
|
||||
共享帮助器构建器现在已经覆盖最常见的 replay/tool-compat
|
||||
系列,因此插件通常不需要手动逐个接线每个 hook:
|
||||
共享辅助构建器现在已经覆盖了最常见的 replay/tool-compat
|
||||
家族,因此插件通常不需要再逐个手工接线每个 hook:
|
||||
|
||||
```typescript
|
||||
import { buildProviderReplayFamilyHooks } from "openclaw/plugin-sdk/provider-model-shared";
|
||||
@ -277,15 +261,15 @@ API 密钥认证和动态模型解析能力的提供商。
|
||||
});
|
||||
```
|
||||
|
||||
当前可用的 replay families:
|
||||
当前可用的 replay 家族:
|
||||
|
||||
| Family | 它会接入什么 |
|
||||
| Family | 接入内容 |
|
||||
| --- | --- |
|
||||
| `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 清理 |
|
||||
| `openai-compatible` | 面向与 OpenAI 兼容传输的共享 OpenAI 风格 replay 策略,包括 tool-call-id 清理、assistant 优先顺序修正,以及在传输需要时的通用 Gemini 轮次校验 |
|
||||
| `anthropic-by-model` | 按 `modelId` 选择的 Claude 感知 replay 策略,因此 Anthropic-message 传输只有在解析出的模型实际是 Claude id 时,才会获得 Claude 专属的 thinking 块清理 |
|
||||
| `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 一侧 |
|
||||
| `passthrough-gemini` | 针对通过与 OpenAI 兼容代理传输运行的 Gemini 模型的 Gemini thought-signature 清理;不会启用原生 Gemini replay 校验或 bootstrap 重写 |
|
||||
| `hybrid-anthropic-openai` | 适用于在单个插件中混合 Anthropic-message 和与 OpenAI 兼容模型表面的 provider 的混合策略;可选的仅 Claude thinking-block 丢弃仍然限定在 Anthropic 一侧 |
|
||||
|
||||
真实的内置示例:
|
||||
|
||||
@ -295,17 +279,17 @@ API 密钥认证和动态模型解析能力的提供商。
|
||||
- `minimax`:`hybrid-anthropic-openai`
|
||||
- `moonshot`、`ollama`、`xai` 和 `zai`:`openai-compatible`
|
||||
|
||||
当前可用的 stream families:
|
||||
当前可用的流式家族:
|
||||
|
||||
| Family | 它会接入什么 |
|
||||
| Family | 接入内容 |
|
||||
| --- | --- |
|
||||
| `google-thinking` | 共享流路径上的 Gemini thinking 负载规范化 |
|
||||
| `kilocode-thinking` | 共享代理流路径上的 Kilo reasoning 包装器,其中 `kilo/auto` 和不受支持的代理 reasoning id 会跳过注入的 thinking |
|
||||
| `moonshot-thinking` | 根据配置 + `/think` 级别进行 Moonshot 二进制原生 thinking 负载映射 |
|
||||
| `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` 的包装器 |
|
||||
| `openai-responses-defaults` | 共享的原生 OpenAI/Codex Responses 包装器:归属标头、`/fast`/`serviceTier`、文本详细度、原生 Codex Web 搜索、reasoning 兼容负载整形,以及 Responses 上下文管理 |
|
||||
| `openrouter-thinking` | 面向代理路由的 OpenRouter reasoning 包装器,其中不支持模型/`auto` 跳过由中心统一处理 |
|
||||
| `tool-stream-default-on` | 针对像 Z.AI 这类 provider 的默认开启 `tool_stream` 包装器,除非显式禁用 |
|
||||
|
||||
真实的内置示例:
|
||||
|
||||
@ -317,8 +301,8 @@ API 密钥认证和动态模型解析能力的提供商。
|
||||
- `openrouter`:`openrouter-thinking`
|
||||
- `zai`:`tool-stream-default-on`
|
||||
|
||||
`openclaw/plugin-sdk/provider-model-shared` 还会导出 replay-family
|
||||
枚举,以及这些 family 所构建于其上的共享帮助器。常见公开导出包括:
|
||||
`openclaw/plugin-sdk/provider-model-shared` 还导出了 replay-family
|
||||
枚举,以及这些家族构建所复用的共享辅助函数。常见公共导出包括:
|
||||
|
||||
- `ProviderReplayFamily`
|
||||
- `buildProviderReplayFamilyHooks(...)`
|
||||
@ -326,14 +310,13 @@ API 密钥认证和动态模型解析能力的提供商。
|
||||
`buildAnthropicReplayPolicyForModel(...)`、
|
||||
`buildGoogleGeminiReplayPolicy(...)` 和
|
||||
`buildHybridAnthropicOrOpenAIReplayPolicy(...)`
|
||||
- Gemini replay 帮助器,例如 `sanitizeGoogleGeminiReplayHistory(...)`
|
||||
- Gemini replay 辅助函数,例如 `sanitizeGoogleGeminiReplayHistory(...)`
|
||||
和 `resolveTaggedReasoningOutputMode()`
|
||||
- 端点/模型帮助器,例如 `resolveProviderEndpoint(...)`、
|
||||
- 端点/模型辅助函数,例如 `resolveProviderEndpoint(...)`、
|
||||
`normalizeProviderId(...)`、`normalizeGooglePreviewModelId(...)` 和
|
||||
`normalizeNativeXaiModelId(...)`
|
||||
|
||||
`openclaw/plugin-sdk/provider-stream` 同时公开 family 构建器以及这些 family 复用的公共包装器帮助器。常见公开导出
|
||||
包括:
|
||||
`openclaw/plugin-sdk/provider-stream` 同时暴露家族构建器和这些家族复用的公共包装辅助函数。常见公共导出包括:
|
||||
|
||||
- `ProviderStreamFamily`
|
||||
- `buildProviderStreamFamilyHooks(...)`
|
||||
@ -344,49 +327,44 @@ API 密钥认证和动态模型解析能力的提供商。
|
||||
`createOpenAIServiceTierWrapper(...)`、
|
||||
`createOpenAIResponsesContextManagementWrapper(...)` 和
|
||||
`createCodexNativeWebSearchWrapper(...)`
|
||||
- 共享代理/提供商包装器,例如 `createOpenRouterWrapper(...)`、
|
||||
- 共享代理/provider 包装器,例如 `createOpenRouterWrapper(...)`、
|
||||
`createToolStreamWrapper(...)` 和 `createMinimaxFastModeWrapper(...)`
|
||||
|
||||
一些 stream 帮助器会有意保持为 provider-local。当前内置
|
||||
某些流式辅助函数会有意保留为 provider 本地。当前内置
|
||||
示例:`@openclaw/anthropic-provider` 从其公共 `api.ts` /
|
||||
`contract-api.ts` 接缝导出
|
||||
`contract-api.ts` 接缝中导出
|
||||
`wrapAnthropicProviderStream`、`resolveAnthropicBetas`、
|
||||
`resolveAnthropicFastMode`、`resolveAnthropicServiceTier`,以及更底层的 Anthropic 包装器构建器。
|
||||
这些帮助器仍保持 Anthropic 特定,因为
|
||||
它们还编码了 Claude OAuth beta 处理和 `context1m` gating。
|
||||
`resolveAnthropicFastMode`、`resolveAnthropicServiceTier` 以及更底层的 Anthropic 包装器构建器。这些辅助函数仍然保持 Anthropic 专属,因为它们还编码了 Claude OAuth beta 处理和 `context1m` gating。
|
||||
|
||||
其他内置提供商也会在行为无法跨 family 清晰共享时,将
|
||||
transport-specific 包装器保留在本地。当前示例:内置 xAI 插件将原生 xAI Responses 整形保留在其自己的
|
||||
其他内置 provider 也会在行为无法在家族间干净共享时,将传输专属包装器保留为本地。当前示例:内置 xAI 插件将原生 xAI Responses 整形保留在自己的
|
||||
`wrapStreamFn` 中,包括 `/fast` 别名重写、默认 `tool_stream`、
|
||||
不支持的 strict-tool 清理,以及 xAI 特有的 reasoning-payload
|
||||
移除。
|
||||
不支持的 strict-tool 清理,以及 xAI 专属 reasoning 负载移除。
|
||||
|
||||
`openclaw/plugin-sdk/provider-tools` 当前公开一个共享
|
||||
tool-schema family 以及共享 schema/compat 帮助器:
|
||||
`openclaw/plugin-sdk/provider-tools` 当前暴露一个共享
|
||||
tool-schema 家族,以及共享的 schema/compat 辅助函数:
|
||||
|
||||
- `ProviderToolCompatFamily` 记录了当前共享 family 清单。
|
||||
- `buildProviderToolCompatFamilyHooks("gemini")` 会为需要 Gemini 安全工具 schema 的提供商接入 Gemini schema
|
||||
清理 + 诊断。
|
||||
- `ProviderToolCompatFamily` 记录当前共享家族清单。
|
||||
- `buildProviderToolCompatFamilyHooks("gemini")` 为需要 Gemini 安全工具 schema 的 provider 接入 Gemini schema 清理 + 诊断。
|
||||
- `normalizeGeminiToolSchemas(...)` 和 `inspectGeminiToolSchemas(...)`
|
||||
是底层的公共 Gemini schema 帮助器。
|
||||
- `resolveXaiModelCompatPatch()` 返回内置 xAI compat patch:
|
||||
是底层公开的 Gemini schema 辅助函数。
|
||||
- `resolveXaiModelCompatPatch()` 返回内置 xAI compat 补丁:
|
||||
`toolSchemaProfile: "xai"`、不支持的 schema 关键字、原生
|
||||
`web_search` 支持,以及 HTML 实体 tool-call 参数解码。
|
||||
- `applyXaiModelCompat(model)` 会在解析后的模型进入 runner 之前,对其应用同样的 xAI compat patch。
|
||||
- `applyXaiModelCompat(model)` 会在模型进入运行器前,将同一份 xAI compat 补丁应用到已解析模型上。
|
||||
|
||||
真实的内置示例:xAI 插件使用 `normalizeResolvedModel` 加上
|
||||
`contributeResolvedModelCompat`,使 compat 元数据归提供商所有,而不是在 core 中硬编码 xAI 规则。
|
||||
`contributeResolvedModelCompat`,以保持该 compat 元数据由 provider 自己拥有,而不是在核心中硬编码 xAI 规则。
|
||||
|
||||
同样的 package-root 模式也支持其他内置提供商:
|
||||
同样的包根模式也支撑其他内置 provider:
|
||||
|
||||
- `@openclaw/openai-provider`:`api.ts` 导出提供商构建器、
|
||||
默认模型帮助器和实时提供商构建器
|
||||
- `@openclaw/openrouter-provider`:`api.ts` 导出提供商构建器
|
||||
以及 onboarding/配置帮助器
|
||||
- `@openclaw/openai-provider`:`api.ts` 导出 provider 构建器、
|
||||
默认模型辅助函数和 realtime provider 构建器
|
||||
- `@openclaw/openrouter-provider`:`api.ts` 导出 provider 构建器
|
||||
以及新手引导/配置辅助函数
|
||||
|
||||
<Tabs>
|
||||
<Tab title="令牌交换">
|
||||
对于需要在每次推理调用前执行令牌交换的提供商:
|
||||
对于需要在每次推理调用前进行令牌交换的 provider:
|
||||
|
||||
```typescript
|
||||
prepareRuntimeAuth: async (ctx) => {
|
||||
@ -399,8 +377,8 @@ API 密钥认证和动态模型解析能力的提供商。
|
||||
},
|
||||
```
|
||||
</Tab>
|
||||
<Tab title="自定义请求头">
|
||||
对于需要自定义请求头或请求体修改的提供商:
|
||||
<Tab title="自定义标头">
|
||||
对于需要自定义请求标头或请求体修改的 provider:
|
||||
|
||||
```typescript
|
||||
// wrapStreamFn returns a StreamFn derived from ctx.streamFn
|
||||
@ -417,8 +395,8 @@ API 密钥认证和动态模型解析能力的提供商。
|
||||
},
|
||||
```
|
||||
</Tab>
|
||||
<Tab title="原生传输身份">
|
||||
对于在通用 HTTP 或 WebSocket 传输上需要原生请求/会话头或元数据的提供商:
|
||||
<Tab title="原生传输标识">
|
||||
对于需要在通用 HTTP 或 WebSocket 传输上附加原生请求/会话标头或元数据的 provider:
|
||||
|
||||
```typescript
|
||||
resolveTransportTurnState: (ctx) => ({
|
||||
@ -438,8 +416,8 @@ API 密钥认证和动态模型解析能力的提供商。
|
||||
}),
|
||||
```
|
||||
</Tab>
|
||||
<Tab title="Usage 和计费">
|
||||
对于暴露 usage/计费数据的提供商:
|
||||
<Tab title="用量和计费">
|
||||
对于暴露用量/计费数据的 provider:
|
||||
|
||||
```typescript
|
||||
resolveUsageAuth: async (ctx) => {
|
||||
@ -453,85 +431,81 @@ API 密钥认证和动态模型解析能力的提供商。
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
<Accordion title="所有可用的提供商 hooks">
|
||||
OpenClaw 会按以下顺序调用 hooks。大多数提供商只会使用 2-3 个:
|
||||
<Accordion title="所有可用的 provider hooks">
|
||||
OpenClaw 按以下顺序调用 hooks。大多数 provider 只会使用 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` | 对配置提供商执行原生流式 usage compat 重写 |
|
||||
| 7 | `resolveConfigApiKey` | 由提供商拥有的环境标记认证解析 |
|
||||
| 8 | `resolveSyntheticAuth` | 本地/自托管或基于配置的 synthetic auth |
|
||||
| 9 | `shouldDeferSyntheticProfileAuth` | 将 synthetic 存储配置文件占位符降级到 env/config auth 之后 |
|
||||
| 1 | `catalog` | 模型目录或 base URL 默认值 |
|
||||
| 2 | `applyConfigDefaults` | 在配置实体化期间应用 provider 自有的全局默认值 |
|
||||
| 3 | `normalizeModelId` | 在查找前清理旧版/预览版模型 id 别名 |
|
||||
| 4 | `normalizeTransport` | 在通用模型组装前清理 provider-family 的 `api` / `baseUrl` |
|
||||
| 5 | `normalizeConfig` | 标准化 `models.providers.<id>` 配置 |
|
||||
| 6 | `applyNativeStreamingUsageCompat` | 面向配置 provider 的原生流式 usage compat 重写 |
|
||||
| 7 | `resolveConfigApiKey` | provider 自有的环境变量标记身份验证解析 |
|
||||
| 8 | `resolveSyntheticAuth` | 本地/自托管或配置支持的 synthetic auth |
|
||||
| 9 | `shouldDeferSyntheticProfileAuth` | 将 synthetic 的已存储 profile 占位符降到 env/config auth 之后 |
|
||||
| 10 | `resolveDynamicModel` | 接受任意上游模型 ID |
|
||||
| 11 | `prepareDynamicModel` | 解析前异步获取元数据 |
|
||||
| 12 | `normalizeResolvedModel` | runner 之前的传输重写 |
|
||||
| 11 | `prepareDynamicModel` | 在解析前异步获取元数据 |
|
||||
| 12 | `normalizeResolvedModel` | 在运行器前进行传输重写 |
|
||||
|
||||
运行时回退说明:
|
||||
运行时回退说明:
|
||||
|
||||
- `normalizeConfig` 会先检查匹配的提供商,然后检查其他
|
||||
具备 hook 能力的提供商插件,直到其中某个插件实际更改配置。
|
||||
如果没有任何提供商 hook 重写受支持的 Google-family 配置条目,
|
||||
内置 Google 配置规范化仍会应用。
|
||||
- `resolveConfigApiKey` 会在公开时使用提供商 hook。内置
|
||||
`amazon-bedrock` 路径在这里也有内建的 AWS 环境标记解析器,
|
||||
尽管 Bedrock 运行时认证本身仍使用 AWS SDK 默认
|
||||
链。
|
||||
| 13 | `contributeResolvedModelCompat` | 为另一个兼容传输背后的厂商模型提供 compat 标志 |
|
||||
| 14 | `capabilities` | 旧版静态 capability 包;仅为兼容性保留 |
|
||||
| 15 | `normalizeToolSchemas` | 注册前由提供商拥有的工具 schema 清理 |
|
||||
| 16 | `inspectToolSchemas` | 由提供商拥有的工具 schema 诊断 |
|
||||
| 17 | `resolveReasoningOutputMode` | 带标签与原生 reasoning-output 契约 |
|
||||
- `normalizeConfig` 会先检查匹配的 provider,然后再检查其他
|
||||
具备 hook 能力的 provider 插件,直到其中一个实际修改了配置。
|
||||
如果没有任何 provider hook 重写受支持的 Google-family 配置条目,
|
||||
则仍会应用内置 Google 配置标准化器。
|
||||
- `resolveConfigApiKey` 在暴露该 hook 时会使用 provider hook。内置的
|
||||
`amazon-bedrock` 路径在这里也有一个内建 AWS 环境变量标记解析器,
|
||||
即便 Bedrock 运行时身份验证本身仍然使用 AWS SDK 默认链。
|
||||
| 13 | `contributeResolvedModelCompat` | 面向运行在另一种兼容传输后的厂商模型的 compat 标志 |
|
||||
| 14 | `capabilities` | 旧版静态能力包;仅为兼容性保留 |
|
||||
| 15 | `normalizeToolSchemas` | 在注册前由 provider 自有进行工具 schema 清理 |
|
||||
| 16 | `inspectToolSchemas` | 由 provider 自有进行工具 schema 诊断 |
|
||||
| 17 | `resolveReasoningOutputMode` | 带标签与原生 reasoning-output 合约 |
|
||||
| 18 | `prepareExtraParams` | 默认请求参数 |
|
||||
| 19 | `createStreamFn` | 完全自定义的 `StreamFn` 传输 |
|
||||
| 20 | `wrapStreamFn` | 普通流路径上的自定义头/请求体包装器 |
|
||||
| 21 | `resolveTransportTurnState` | 原生逐轮请求头/元数据 |
|
||||
| 22 | `resolveWebSocketSessionPolicy` | 原生 WS 会话头/冷却时间 |
|
||||
| 19 | `createStreamFn` | 完全自定义的 StreamFn 传输 |
|
||||
| 20 | `wrapStreamFn` | 常规流路径上的自定义标头/请求体包装器 |
|
||||
| 21 | `resolveTransportTurnState` | 原生逐轮标头/元数据 |
|
||||
| 22 | `resolveWebSocketSessionPolicy` | 原生 WS 会话标头/冷却策略 |
|
||||
| 23 | `formatApiKey` | 自定义运行时令牌形态 |
|
||||
| 24 | `refreshOAuth` | 自定义 OAuth 刷新 |
|
||||
| 25 | `buildAuthDoctorHint` | 认证修复指导 |
|
||||
| 26 | `matchesContextOverflowError` | 由提供商拥有的溢出检测 |
|
||||
| 27 | `classifyFailoverReason` | 由提供商拥有的限流/过载分类 |
|
||||
| 28 | `isCacheTtlEligible` | 提示缓存 TTL 门控 |
|
||||
| 29 | `buildMissingAuthMessage` | 自定义缺失认证提示 |
|
||||
| 30 | `suppressBuiltInModel` | 隐藏过时的上游行 |
|
||||
| 31 | `augmentModelCatalog` | synthetic 前向兼容行 |
|
||||
| 25 | `buildAuthDoctorHint` | 身份验证修复指引 |
|
||||
| 26 | `matchesContextOverflowError` | provider 自有的上下文溢出检测 |
|
||||
| 27 | `classifyFailoverReason` | provider 自有的速率限制/过载分类 |
|
||||
| 28 | `isCacheTtlEligible` | 提示词缓存 TTL gating |
|
||||
| 29 | `buildMissingAuthMessage` | 自定义缺失身份验证提示 |
|
||||
| 30 | `suppressBuiltInModel` | 隐藏过时的上游条目 |
|
||||
| 31 | `augmentModelCatalog` | synthetic 前向兼容条目 |
|
||||
| 32 | `isBinaryThinking` | 二进制 thinking 开/关 |
|
||||
| 33 | `supportsXHighThinking` | `xhigh` reasoning 支持 |
|
||||
| 34 | `resolveDefaultThinkingLevel` | 默认 `/think` 策略 |
|
||||
| 35 | `isModernModelRef` | 实时/smoke 模型匹配 |
|
||||
| 36 | `prepareRuntimeAuth` | 推理前令牌交换 |
|
||||
| 37 | `resolveUsageAuth` | 自定义 usage 凭证解析 |
|
||||
| 38 | `fetchUsageSnapshot` | 自定义 usage 端点 |
|
||||
| 39 | `createEmbeddingProvider` | 用于内存/搜索的由提供商拥有的嵌入适配器 |
|
||||
| 36 | `prepareRuntimeAuth` | 推理前的令牌交换 |
|
||||
| 37 | `resolveUsageAuth` | 自定义用量凭证解析 |
|
||||
| 38 | `fetchUsageSnapshot` | 自定义用量端点 |
|
||||
| 39 | `createEmbeddingProvider` | 面向 memory/search 的 provider 自有嵌入适配器 |
|
||||
| 40 | `buildReplayPolicy` | 自定义转录 replay/压缩策略 |
|
||||
| 41 | `sanitizeReplayHistory` | 通用清理之后的 provider-specific replay 重写 |
|
||||
| 42 | `validateReplayTurns` | 嵌入 runner 之前的严格 replay-turn 验证 |
|
||||
| 43 | `onModelSelected` | 选择后的回调(例如遥测) |
|
||||
| 41 | `sanitizeReplayHistory` | 通用清理后的 provider 专属 replay 重写 |
|
||||
| 42 | `validateReplayTurns` | 嵌入式运行器前的严格 replay 轮次校验 |
|
||||
| 43 | `onModelSelected` | 选择模型后的回调(例如遥测) |
|
||||
|
||||
提示词调优说明:
|
||||
|
||||
- `resolveSystemPromptContribution` 允许提供商为某个模型 family 注入缓存感知的
|
||||
system-prompt 指导。对于属于某个提供商/模型
|
||||
family 且应保留稳定/动态缓存拆分的行为,
|
||||
优先使用它,而不是
|
||||
- `resolveSystemPromptContribution` 允许 provider 为某个模型家族注入缓存感知的系统提示词指导。对于属于某个 provider/模型家族并且应该保留稳定/动态缓存拆分的行为,优先使用它,而不是
|
||||
`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>
|
||||
提供商插件除了文本推理之外,还可以注册语音、实时转录、实时
|
||||
语音、媒体理解、图像生成、视频生成、网页抓取
|
||||
和网页搜索:
|
||||
provider 插件除了文本推理外,还可以注册 speech、realtime transcription、realtime
|
||||
voice、media understanding、image generation、video generation、web fetch
|
||||
和 web search:
|
||||
|
||||
```typescript
|
||||
register(api) {
|
||||
@ -639,15 +613,16 @@ API 密钥认证和动态模型解析能力的提供商。
|
||||
}
|
||||
```
|
||||
|
||||
OpenClaw 会将其归类为**混合能力**插件。这是
|
||||
公司级插件(每个厂商一个插件)的推荐模式。参见
|
||||
OpenClaw 会将其归类为**混合能力**插件。这是公司级插件(每个厂商一个插件)的推荐模式。参见
|
||||
[内部机制:能力归属](/zh-CN/plugins/architecture#capability-ownership-model)。
|
||||
|
||||
对于视频生成,优先使用上面展示的感知模式 capability 结构:
|
||||
`generate`、`imageToVideo` 和 `videoToVideo`。较旧的扁平字段,如
|
||||
`maxInputImages`、`maxInputVideos` 和 `maxDurationSeconds` 仍可作为聚合回退上限使用,
|
||||
但它们无法同样清晰地描述每种模式的限制或
|
||||
被禁用的转换模式。
|
||||
对于视频生成,优先使用上面展示的模式感知能力形态:
|
||||
`generate`、`imageToVideo` 和 `videoToVideo`。像
|
||||
`maxInputImages`、`maxInputVideos` 和 `maxDurationSeconds` 这样的扁平聚合字段,不足以干净地表达变换模式支持或已禁用模式。
|
||||
|
||||
音乐生成 provider 也应遵循同样的模式:
|
||||
`generate` 用于仅提示词生成,`edit` 用于基于参考图像的生成。像 `maxInputImages`、
|
||||
`supportsLyrics` 和 `supportsFormat` 这样的扁平聚合字段,不足以表达 edit 支持;显式的 `generate` / `edit` 块才是预期合约。
|
||||
|
||||
</Step>
|
||||
|
||||
@ -655,7 +630,7 @@ API 密钥认证和动态模型解析能力的提供商。
|
||||
<a id="step-6-test"></a>
|
||||
```typescript src/provider.test.ts
|
||||
import { describe, it, expect } from "vitest";
|
||||
// Export your provider config object from index.ts or a dedicated file
|
||||
// 从 index.ts 或单独文件导出你的 provider 配置对象
|
||||
import { acmeProvider } from "./provider.js";
|
||||
|
||||
describe("acme-ai provider", () => {
|
||||
@ -688,7 +663,7 @@ API 密钥认证和动态模型解析能力的提供商。
|
||||
|
||||
## 发布到 ClawHub
|
||||
|
||||
提供商插件的发布方式与任何其他外部代码插件相同:
|
||||
Provider 插件的发布方式与任何其他外部代码插件相同:
|
||||
|
||||
```bash
|
||||
clawhub package publish your-org/your-plugin --dry-run
|
||||
@ -707,24 +682,23 @@ clawhub package publish your-org/your-plugin
|
||||
├── index.ts # definePluginEntry + registerProvider
|
||||
└── src/
|
||||
├── provider.test.ts # 测试
|
||||
└── usage.ts # Usage 端点(可选)
|
||||
└── usage.ts # 用量端点(可选)
|
||||
```
|
||||
|
||||
## 目录顺序参考
|
||||
|
||||
`catalog.order` 控制你的目录相对于内置
|
||||
提供商何时合并:
|
||||
`catalog.order` 控制你的目录相对于内置 provider 的合并时机:
|
||||
|
||||
| Order | 时机 | 使用场景 |
|
||||
| Order | 时机 | 使用场景 |
|
||||
| --------- | ------------- | ----------------------------------------------- |
|
||||
| `simple` | 第一轮 | 纯 API 密钥提供商 |
|
||||
| `profile` | 在 simple 之后 | 受 auth profiles 控制的提供商 |
|
||||
| `simple` | 第一轮 | 纯 API 密钥 provider |
|
||||
| `profile` | 在 simple 之后 | 由 auth profile 控制的 provider |
|
||||
| `paired` | 在 profile 之后 | 合成多个相关条目 |
|
||||
| `late` | 最后一轮 | 覆盖现有提供商(冲突时胜出) |
|
||||
| `late` | 最后一轮 | 覆盖现有 provider(冲突时胜出) |
|
||||
|
||||
## 后续步骤
|
||||
|
||||
- [渠道插件](/zh-CN/plugins/sdk-channel-plugins) — 如果你的插件还提供一个渠道
|
||||
- [插件运行时](/zh-CN/plugins/sdk-runtime) — `api.runtime` 帮助器(TTS、搜索、subagent)
|
||||
- [插件运行时](/zh-CN/plugins/sdk-runtime) — `api.runtime` 辅助函数(TTS、搜索、子智能体)
|
||||
- [SDK 概览](/zh-CN/plugins/sdk-overview) — 完整子路径导入参考
|
||||
- [插件内部机制](/zh-CN/plugins/architecture#provider-runtime-hooks) — hook 细节和内置示例
|
||||
|
||||
194
docs/zh-CN/plugins/webhooks.md
Normal file
194
docs/zh-CN/plugins/webhooks.md
Normal file
@ -0,0 +1,194 @@
|
||||
---
|
||||
read_when:
|
||||
- 你希望从外部系统触发或驱动 TaskFlows
|
||||
- 你正在配置内置的 Webhooks 插件
|
||||
summary: Webhooks 插件:面向受信任外部自动化的已认证 TaskFlow 入口
|
||||
title: Webhooks 插件
|
||||
x-i18n:
|
||||
generated_at: "2026-04-06T15:30:37Z"
|
||||
model: gpt-5.4
|
||||
provider: openai
|
||||
source_hash: a5da12a887752ec6ee853cfdb912db0ae28512a0ffed06fe3828ef2eee15bc9d
|
||||
source_path: plugins/webhooks.md
|
||||
workflow: 15
|
||||
---
|
||||
|
||||
# Webhooks(插件)
|
||||
|
||||
Webhooks 插件会添加已认证的 HTTP 路由,将外部自动化绑定到 OpenClaw TaskFlows。
|
||||
|
||||
当你希望让一个受信任的系统,例如 Zapier、n8n、CI 作业或内部服务,在不先编写自定义插件的情况下创建并驱动受管 TaskFlows 时,请使用它。
|
||||
|
||||
## 运行位置
|
||||
|
||||
Webhooks 插件运行在 Gateway 网关进程内。
|
||||
|
||||
如果你的 Gateway 网关运行在另一台机器上,请在该 Gateway 网关主机上安装并配置此插件,然后重启 Gateway 网关。
|
||||
|
||||
## 配置路由
|
||||
|
||||
在 `plugins.entries.webhooks.config` 下设置配置:
|
||||
|
||||
```json5
|
||||
{
|
||||
plugins: {
|
||||
entries: {
|
||||
webhooks: {
|
||||
enabled: true,
|
||||
config: {
|
||||
routes: {
|
||||
zapier: {
|
||||
path: "/plugins/webhooks/zapier",
|
||||
sessionKey: "agent:main:main",
|
||||
secret: {
|
||||
source: "env",
|
||||
provider: "default",
|
||||
id: "OPENCLAW_WEBHOOK_SECRET",
|
||||
},
|
||||
controllerId: "webhooks/zapier",
|
||||
description: "Zapier TaskFlow bridge",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
路由字段:
|
||||
|
||||
- `enabled`:可选,默认为 `true`
|
||||
- `path`:可选,默认为 `/plugins/webhooks/<routeId>`
|
||||
- `sessionKey`:必填,拥有绑定 TaskFlows 的会话
|
||||
- `secret`:必填,共享密钥或 SecretRef
|
||||
- `controllerId`:可选,用于已创建受管流程的 controller id
|
||||
- `description`:可选,供操作员使用的备注
|
||||
|
||||
支持的 `secret` 输入:
|
||||
|
||||
- 纯字符串
|
||||
- 带 `source: "env" | "file" | "exec"` 的 SecretRef
|
||||
|
||||
如果某个基于 secret 的路由在启动时无法解析其 secret,插件会跳过该路由,并记录一条警告,而不是暴露一个损坏的端点。
|
||||
|
||||
## 安全模型
|
||||
|
||||
每条路由都被信任为能够使用其配置的 `sessionKey` 所拥有的 TaskFlow 权限进行操作。
|
||||
|
||||
这意味着该路由可以检查和修改该会话拥有的 TaskFlows,因此你应该:
|
||||
|
||||
- 为每条路由使用强且唯一的密钥
|
||||
- 优先使用 secret 引用,而不是内联明文密钥
|
||||
- 将路由绑定到最适合该工作流的最小会话范围
|
||||
- 只暴露你需要的特定 webhook 路径
|
||||
|
||||
该插件会应用:
|
||||
|
||||
- 共享密钥认证
|
||||
- 请求体大小和超时保护
|
||||
- 固定窗口限流
|
||||
- 进行中请求数量限制
|
||||
- 通过 `api.runtime.taskFlow.bindSession(...)` 实现按所有者绑定的 TaskFlow 访问
|
||||
|
||||
## 请求格式
|
||||
|
||||
发送 `POST` 请求时使用:
|
||||
|
||||
- `Content-Type: application/json`
|
||||
- `Authorization: Bearer <secret>` 或 `x-openclaw-webhook-secret: <secret>`
|
||||
|
||||
示例:
|
||||
|
||||
```bash
|
||||
curl -X POST https://gateway.example.com/plugins/webhooks/zapier \
|
||||
-H 'Content-Type: application/json' \
|
||||
-H 'Authorization: Bearer YOUR_SHARED_SECRET' \
|
||||
-d '{"action":"create_flow","goal":"Review inbound queue"}'
|
||||
```
|
||||
|
||||
## 支持的操作
|
||||
|
||||
该插件当前接受以下 JSON `action` 值:
|
||||
|
||||
- `create_flow`
|
||||
- `get_flow`
|
||||
- `list_flows`
|
||||
- `find_latest_flow`
|
||||
- `resolve_flow`
|
||||
- `get_task_summary`
|
||||
- `set_waiting`
|
||||
- `resume_flow`
|
||||
- `finish_flow`
|
||||
- `fail_flow`
|
||||
- `request_cancel`
|
||||
- `cancel_flow`
|
||||
- `run_task`
|
||||
|
||||
### `create_flow`
|
||||
|
||||
为该路由绑定的会话创建一个受管 TaskFlow。
|
||||
|
||||
示例:
|
||||
|
||||
```json
|
||||
{
|
||||
"action": "create_flow",
|
||||
"goal": "Review inbound queue",
|
||||
"status": "queued",
|
||||
"notifyPolicy": "done_only"
|
||||
}
|
||||
```
|
||||
|
||||
### `run_task`
|
||||
|
||||
在现有受管 TaskFlow 内创建一个受管子任务。
|
||||
|
||||
允许的运行时有:
|
||||
|
||||
- `subagent`
|
||||
- `acp`
|
||||
|
||||
示例:
|
||||
|
||||
```json
|
||||
{
|
||||
"action": "run_task",
|
||||
"flowId": "flow_123",
|
||||
"runtime": "acp",
|
||||
"childSessionKey": "agent:main:acp:worker",
|
||||
"task": "Inspect the next message batch"
|
||||
}
|
||||
```
|
||||
|
||||
## 响应结构
|
||||
|
||||
成功响应返回:
|
||||
|
||||
```json
|
||||
{
|
||||
"ok": true,
|
||||
"routeId": "zapier",
|
||||
"result": {}
|
||||
}
|
||||
```
|
||||
|
||||
被拒绝的请求返回:
|
||||
|
||||
```json
|
||||
{
|
||||
"ok": false,
|
||||
"routeId": "zapier",
|
||||
"code": "not_found",
|
||||
"error": "TaskFlow not found.",
|
||||
"result": {}
|
||||
}
|
||||
```
|
||||
|
||||
该插件会有意从 webhook 响应中清除 owner/session 元数据。
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [插件运行时 SDK](/zh-CN/plugins/sdk-runtime)
|
||||
- [Hooks 和 Webhooks 概览](/zh-CN/automation/hooks)
|
||||
- [CLI Webhooks](/cli/webhooks)
|
||||
@ -1,46 +1,28 @@
|
||||
---
|
||||
read_when:
|
||||
- 你想在 OpenClaw 中使用 Anthropic 模型
|
||||
summary: 在 OpenClaw 中通过 API 密钥使用 Anthropic Claude
|
||||
summary: 在 OpenClaw 中通过 API 密钥或 Claude CLI 使用 Anthropic Claude
|
||||
title: Anthropic
|
||||
x-i18n:
|
||||
generated_at: "2026-04-06T12:44:41Z"
|
||||
generated_at: "2026-04-06T15:31:06Z"
|
||||
model: gpt-5.4
|
||||
provider: openai
|
||||
source_hash: 6af35571debf5889b63e3b4f6a05aa4e046f39740287e6e1c492916ca00df44b
|
||||
source_hash: 423928fd36c66729985208d4d3f53aff1f94f63b908df85072988bdc41d5cf46
|
||||
source_path: providers/anthropic.md
|
||||
workflow: 15
|
||||
---
|
||||
|
||||
# Anthropic(Claude)
|
||||
|
||||
Anthropic 构建了 **Claude** 模型家族,并通过 API 提供访问。
|
||||
在 OpenClaw 中,新的 Anthropic 设置应使用 API 密钥。现有的旧版
|
||||
Anthropic token 配置文件如果已经完成配置,运行时仍会继续支持。
|
||||
Anthropic 构建了 **Claude** 模型家族,并通过 API 和
|
||||
Claude CLI 提供访问。在 OpenClaw 中,Anthropic API 密钥和 Claude CLI 复用都受支持。如果现有的旧版 Anthropic 令牌配置文件已经配置好,运行时仍会继续使用它们。
|
||||
|
||||
<Warning>
|
||||
对于 OpenClaw 中的 Anthropic,计费拆分如下:
|
||||
Anthropic 员工告诉我们,OpenClaw 风格的 Claude CLI 用法再次被允许,因此只要 Anthropic 没有发布新的政策,OpenClaw 就会将 Claude CLI 复用和 `claude -p` 用法视为此集成下被认可的方式。
|
||||
|
||||
- **Anthropic API 密钥**:标准 Anthropic API 计费。
|
||||
- **OpenClaw 内的 Claude 订阅凭证**:Anthropic 于
|
||||
**2026 年 4 月 4 日 PT 时间中午 12:00 / BST 时间晚上 8:00**
|
||||
告知 OpenClaw 用户,这会被视为
|
||||
第三方 harness 使用,并需要 **Extra Usage**(按量计费,
|
||||
与订阅分开计费)。
|
||||
对于长期运行的 Gateway 网关主机,Anthropic API 密钥仍然是最清晰、最可预测的生产路径。如果你已经在主机上使用 Claude CLI,OpenClaw 可以直接复用该登录状态。
|
||||
|
||||
我们的本地复现结果也符合这一拆分:
|
||||
|
||||
- 直接执行 `claude -p` 可能仍然可用
|
||||
- `claude -p --append-system-prompt ...` 在提示词标识出 OpenClaw 时,
|
||||
可能触发 Extra Usage 保护
|
||||
- 在 Anthropic SDK + `ANTHROPIC_API_KEY` 路径上,相同的类 OpenClaw
|
||||
系统提示词**不会**复现该拦截
|
||||
|
||||
因此,实际规则是:**Anthropic API 密钥,或启用了
|
||||
Extra Usage 的 Claude 订阅**。如果你想要最清晰的生产环境路径,请使用 Anthropic API
|
||||
密钥。
|
||||
|
||||
Anthropic 当前的公开文档:
|
||||
Anthropic 当前公开文档:
|
||||
|
||||
- [Claude Code CLI reference](https://code.claude.com/docs/en/cli-reference)
|
||||
- [Claude Agent SDK overview](https://platform.claude.com/docs/en/agent-sdk/overview)
|
||||
@ -57,7 +39,7 @@ Plan](/zh-CN/providers/glm)。
|
||||
|
||||
## 选项 A:Anthropic API 密钥
|
||||
|
||||
**最适合:** 标准 API 访问和按量计费。
|
||||
**最适合:** 标准 API 访问和按使用量计费。
|
||||
请在 Anthropic Console 中创建你的 API 密钥。
|
||||
|
||||
### CLI 设置
|
||||
@ -82,7 +64,7 @@ openclaw onboard --anthropic-api-key "$ANTHROPIC_API_KEY"
|
||||
## Thinking 默认值(Claude 4.6)
|
||||
|
||||
- 当未设置显式 thinking 级别时,Anthropic Claude 4.6 模型在 OpenClaw 中默认使用 `adaptive` thinking。
|
||||
- 你可以按消息覆盖(`/think:<level>`),或在模型参数中覆盖:
|
||||
- 你可以按消息覆盖(`/think:<level>`),或在模型参数中设置:
|
||||
`agents.defaults.models["anthropic/<model>"].params.thinking`。
|
||||
- 相关 Anthropic 文档:
|
||||
- [Adaptive thinking](https://platform.claude.com/docs/en/build-with-claude/adaptive-thinking)
|
||||
@ -90,10 +72,10 @@ openclaw onboard --anthropic-api-key "$ANTHROPIC_API_KEY"
|
||||
|
||||
## 快速模式(Anthropic API)
|
||||
|
||||
OpenClaw 的共享 `/fast` 开关也支持直连公开 Anthropic 流量,包括发送到 `api.anthropic.com` 的 API 密钥和 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
|
||||
@ -112,23 +94,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` 下报告实际生效的层级。对于没有 Priority Tier 容量的账户,`service_tier: "auto"` 仍可能解析为 `standard`。
|
||||
|
||||
## 提示词缓存(Anthropic API)
|
||||
## 提示缓存(Anthropic API)
|
||||
|
||||
OpenClaw 支持 Anthropic 的提示词缓存功能。这是**仅 API** 功能;旧版 Anthropic token 凭证不会应用缓存设置。
|
||||
OpenClaw 支持 Anthropic 的提示缓存功能。这是**仅限 API**的;旧版 Anthropic 令牌凭证不会遵循缓存设置。
|
||||
|
||||
### 配置
|
||||
|
||||
在你的模型配置中使用 `cacheRetention` 参数:
|
||||
在模型配置中使用 `cacheRetention` 参数:
|
||||
|
||||
| Value | Cache Duration | Description |
|
||||
| ------- | -------------- | ------------------ |
|
||||
| `none` | 不缓存 | 禁用提示词缓存 |
|
||||
| `short` | 5 分钟 | API 密钥凭证的默认值 |
|
||||
| `long` | 1 小时 | 扩展缓存 |
|
||||
| 值 | 缓存时长 | 说明 |
|
||||
| ------- | -------------- | ------------------------ |
|
||||
| `none` | 不缓存 | 禁用提示缓存 |
|
||||
| `short` | 5 分钟 | API 密钥凭证的默认值 |
|
||||
| `long` | 1 小时 | 扩展缓存 |
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -146,11 +128,11 @@ OpenClaw 支持 Anthropic 的提示词缓存功能。这是**仅 API** 功能;
|
||||
|
||||
### 默认值
|
||||
|
||||
当使用 Anthropic API 密钥认证时,OpenClaw 会自动为所有 Anthropic 模型应用 `cacheRetention: "short"`(5 分钟缓存)。你可以在配置中显式设置 `cacheRetention` 来覆盖此行为。
|
||||
当使用 Anthropic API 密钥凭证时,OpenClaw 会自动对所有 Anthropic 模型应用 `cacheRetention: "short"`(5 分钟缓存)。你可以通过在配置中显式设置 `cacheRetention` 来覆盖此值。
|
||||
|
||||
### 按智能体覆盖 cacheRetention
|
||||
|
||||
请将模型级参数作为基线,然后通过 `agents.list[].params` 覆盖特定智能体。
|
||||
将模型级参数作为基线,然后通过 `agents.list[].params` 覆盖特定智能体。
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -165,29 +147,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` 透传。
|
||||
- Bedrock 上的 Anthropic Claude 模型(`amazon-bedrock/*anthropic.claude*`)在配置后接受 `cacheRetention` 透传。
|
||||
- 非 Anthropic 的 Bedrock 模型在运行时会被强制设置为 `cacheRetention: "none"`。
|
||||
- 当未设置显式值时,Anthropic API 密钥的智能默认值也会为 Claude-on-Bedrock 模型引用填充 `cacheRetention: "short"`。
|
||||
- 当未设置显式值时,Anthropic API 密钥的智能默认值也会为 Claude-on-Bedrock 模型引用注入 `cacheRetention: "short"`。
|
||||
|
||||
## 1M 上下文窗口(Anthropic beta)
|
||||
## 100 万上下文窗口(Anthropic beta)
|
||||
|
||||
Anthropic 的 1M 上下文窗口仍处于 beta 限制阶段。在 OpenClaw 中,
|
||||
请通过 `params.context1m: true` 为受支持的 Opus/Sonnet 模型逐个启用。
|
||||
Anthropic 的 100 万上下文窗口受 beta 限制。在 OpenClaw 中,可通过
|
||||
`params.context1m: true` 为受支持的 Opus/Sonnet 模型按模型启用。
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -203,74 +185,54 @@ Anthropic 的 1M 上下文窗口仍处于 beta 限制阶段。在 OpenClaw 中
|
||||
}
|
||||
```
|
||||
|
||||
OpenClaw 会将其映射为 Anthropic 请求上的
|
||||
OpenClaw 会将其映射为 Anthropic 请求中的
|
||||
`anthropic-beta: context-1m-2025-08-07`。
|
||||
|
||||
只有在该模型的 `params.context1m` 被显式设置为 `true` 时,
|
||||
此功能才会激活。
|
||||
只有当该模型的 `params.context1m` 被显式设置为 `true` 时,才会启用此功能。
|
||||
|
||||
要求:Anthropic 必须允许该凭证使用长上下文
|
||||
(通常是 API 密钥计费,或启用了 Extra Usage 的 OpenClaw Claude 登录路径 / 旧版 token 凭证)。
|
||||
否则 Anthropic 会返回:
|
||||
`HTTP 429: rate_limit_error: Extra usage is required for long context requests`。
|
||||
要求:Anthropic 必须允许该凭证使用长上下文。
|
||||
|
||||
注意:Anthropic 当前会在使用
|
||||
旧版 Anthropic token 凭证(`sk-ant-oat-*`)时拒绝 `context-1m-*` beta 请求。如果你在该旧版凭证模式下配置了
|
||||
`context1m: true`,OpenClaw 会记录一条警告,并通过跳过 context1m beta
|
||||
header 回退到标准上下文窗口,同时保留必需的 OAuth beta。
|
||||
注意:Anthropic 目前在使用旧版 Anthropic 令牌凭证(`sk-ant-oat-*`)时会拒绝 `context-1m-*` beta 请求。如果你在该旧版凭证模式下配置
|
||||
`context1m: true`,OpenClaw 会记录警告,并通过跳过 context1m beta
|
||||
请求头、同时保留必需的 OAuth beta,请求回退到标准上下文窗口。
|
||||
|
||||
## 已移除:Claude CLI 后端
|
||||
## Claude CLI 后端
|
||||
|
||||
内置 Anthropic `claude-cli` 后端已被移除。
|
||||
内置的 Anthropic `claude-cli` 后端在 OpenClaw 中受支持。
|
||||
|
||||
- Anthropic 在 2026 年 4 月 4 日的通知中表示,由 OpenClaw 驱动的 Claude 登录流量属于
|
||||
第三方 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 员工告诉我们这种用法再次被允许。
|
||||
- 因此,只要 Anthropic 没有发布新的政策,OpenClaw 就会将 Claude CLI 复用和 `claude -p` 用法视为此集成下被认可的方式。
|
||||
- 对于始终在线的 Gateway 网关主机,Anthropic API 密钥仍然是最清晰的生产路径,也更便于进行显式服务端计费控制。
|
||||
- 设置和运行时详情请参见 [/gateway/cli-backends](/zh-CN/gateway/cli-backends)。
|
||||
|
||||
## 说明
|
||||
|
||||
- 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)。
|
||||
- Anthropic 的公开 Claude Code 文档仍然记录了类似
|
||||
`claude -p` 的直接 CLI 用法,而 Anthropic 员工也告诉我们 OpenClaw 风格的 Claude CLI 用法再次被允许。除非 Anthropic 发布新的政策变更,否则我们将这一指导视为已确定。
|
||||
- Anthropic setup-token 仍在 OpenClaw 中作为受支持的令牌凭证路径保留,但 OpenClaw 现在在可用时优先使用 Claude CLI 复用和 `claude -p`。
|
||||
- 凭证详情和复用规则请参见 [/concepts/oauth](/zh-CN/concepts/oauth)。
|
||||
|
||||
## 故障排除
|
||||
|
||||
**401 错误 / token 突然失效**
|
||||
**401 错误 / 令牌突然失效**
|
||||
|
||||
- 旧版 Anthropic token 凭证可能会过期或被撤销。
|
||||
- Anthropic 令牌凭证可能会过期或被撤销。
|
||||
- 对于新的设置,请迁移到 Anthropic API 密钥。
|
||||
|
||||
**提供商 “anthropic” 未找到 API 密钥**
|
||||
**未找到提供商 “anthropic” 的 API 密钥**
|
||||
|
||||
- 凭证是**按智能体**区分的。新智能体不会继承主智能体的密钥。
|
||||
- 请重新为该智能体运行新手引导,或在 gateway host 上配置 API 密钥,
|
||||
然后使用 `openclaw models status` 进行验证。
|
||||
- 凭证是**按智能体**管理的。新智能体不会继承主智能体的密钥。
|
||||
- 请为该智能体重新运行新手引导,或者在 Gateway 网关主机上配置 API 密钥,然后使用 `openclaw models status` 验证。
|
||||
|
||||
**未找到配置文件 `anthropic:default` 的凭证**
|
||||
|
||||
- 运行 `openclaw models status` 以查看当前激活的是哪个凭证配置文件。
|
||||
- 重新运行新手引导,或为该配置文件路径配置 API 密钥。
|
||||
- 运行 `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,25 +1,31 @@
|
||||
---
|
||||
read_when:
|
||||
- 你想在 OpenClaw 中使用 OpenAI 模型
|
||||
- 你想使用 Codex 订阅凭证而不是 API 密钥
|
||||
- 你希望在 OpenClaw 中使用 OpenAI 模型
|
||||
- 你希望使用 Codex 订阅认证而不是 API 密钥
|
||||
summary: 在 OpenClaw 中通过 API 密钥或 Codex 订阅使用 OpenAI
|
||||
title: OpenAI
|
||||
x-i18n:
|
||||
generated_at: "2026-04-06T00:33:49Z"
|
||||
generated_at: "2026-04-06T15:31:36Z"
|
||||
model: gpt-5.4
|
||||
provider: openai
|
||||
source_hash: 9e04db5787f6ed7b1eda04d965c10febae10809fc82ae4d9769e7163234471f5
|
||||
source_hash: 736ad34671584665674515aee76e2670b14b22bb3cc0bf0ab3ae2388ac136598
|
||||
source_path: providers/openai.md
|
||||
workflow: 15
|
||||
---
|
||||
|
||||
# OpenAI
|
||||
|
||||
OpenAI 为 GPT 模型提供开发者 API。Codex 支持通过 **ChatGPT 登录** 使用订阅访问,或通过 **API 密钥** 登录使用按量计费访问。Codex cloud 需要 ChatGPT 登录。OpenAI 明确支持在 OpenClaw 这类外部工具/工作流中使用订阅 OAuth。
|
||||
OpenAI 为 GPT 模型提供开发者 API。Codex 支持**ChatGPT 登录**用于订阅访问,或支持**API 密钥**登录用于按量计费访问。Codex cloud 需要 ChatGPT 登录。
|
||||
OpenAI 明确支持在 OpenClaw 这样的外部工具/工作流中使用订阅 OAuth。
|
||||
|
||||
## 默认交互风格
|
||||
|
||||
OpenClaw 可以为 `openai/*` 和 `openai-codex/*` 运行添加一个小型 OpenAI 专用提示词叠加层。默认情况下,这个叠加层会让助手保持更温暖、协作、简洁、直接,并带有一点更丰富的情感表达,同时不会替换 OpenClaw 的基础系统提示词。这个友好叠加层也允许在自然合适时偶尔使用 emoji,同时保持整体输出简洁。
|
||||
OpenClaw 可以为 `openai/*` 和
|
||||
`openai-codex/*` 运行添加一个小型 OpenAI 专属提示叠加层。默认情况下,该叠加层会让 assistant 保持温和、
|
||||
协作、简洁、直接,并带有一点更丰富的情感表达,
|
||||
同时不会替换 OpenClaw 的基础系统提示。这个友好的叠加层还
|
||||
允许在自然合适时偶尔使用 emoji,同时保持整体
|
||||
输出简洁。
|
||||
|
||||
配置键:
|
||||
|
||||
@ -27,8 +33,8 @@ OpenClaw 可以为 `openai/*` 和 `openai-codex/*` 运行添加一个小型 Open
|
||||
|
||||
允许的值:
|
||||
|
||||
- `"friendly"`:默认;启用 OpenAI 专用叠加层。
|
||||
- `"off"`:禁用叠加层,仅使用基础 OpenClaw 提示词。
|
||||
- `"friendly"`:默认;启用 OpenAI 专属叠加层。
|
||||
- `"off"`:禁用叠加层,仅使用基础 OpenClaw 提示。
|
||||
|
||||
作用范围:
|
||||
|
||||
@ -36,7 +42,8 @@ OpenClaw 可以为 `openai/*` 和 `openai-codex/*` 运行添加一个小型 Open
|
||||
- 适用于 `openai-codex/*` 模型。
|
||||
- 不影响其他提供商。
|
||||
|
||||
此行为默认开启。如果你希望它在未来本地配置变动后仍然保留,请显式保留 `"friendly"`:
|
||||
此行为默认开启。如果你希望它
|
||||
在未来本地配置变动中仍然保留,请显式保留 `"friendly"`:
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -52,9 +59,9 @@ OpenClaw 可以为 `openai/*` 和 `openai-codex/*` 运行添加一个小型 Open
|
||||
}
|
||||
```
|
||||
|
||||
### 禁用 OpenAI 提示词叠加层
|
||||
### 禁用 OpenAI 提示叠加层
|
||||
|
||||
如果你想使用未修改的基础 OpenClaw 提示词,请将叠加层设置为 `"off"`:
|
||||
如果你希望使用未修改的基础 OpenClaw 提示,请将叠加层设置为 `"off"`:
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -70,7 +77,7 @@ OpenClaw 可以为 `openai/*` 和 `openai-codex/*` 运行添加一个小型 Open
|
||||
}
|
||||
```
|
||||
|
||||
你也可以直接使用配置 CLI 设置:
|
||||
你也可以直接使用配置 CLI 设置它:
|
||||
|
||||
```bash
|
||||
openclaw config set plugins.entries.openai.config.personality off
|
||||
@ -79,13 +86,19 @@ openclaw config set plugins.entries.openai.config.personality off
|
||||
## 选项 A:OpenAI API 密钥(OpenAI Platform)
|
||||
|
||||
**最适合:** 直接 API 访问和按量计费。
|
||||
从 OpenAI 控制台获取你的 API 密钥。
|
||||
请从 OpenAI 控制台获取你的 API 密钥。
|
||||
|
||||
路由摘要:
|
||||
|
||||
- `openai/gpt-5.4` = 直接 OpenAI Platform API 路由
|
||||
- 需要 `OPENAI_API_KEY`(或等效的 OpenAI 提供商配置)
|
||||
- 在 OpenClaw 中,ChatGPT/Codex 登录通过 `openai-codex/*` 路由,而不是 `openai/*`
|
||||
|
||||
### CLI 设置
|
||||
|
||||
```bash
|
||||
openclaw onboard --auth-choice openai-api-key
|
||||
# 或非交互式
|
||||
# 或非交互方式
|
||||
openclaw onboard --openai-api-key "$OPENAI_API_KEY"
|
||||
```
|
||||
|
||||
@ -98,21 +111,28 @@ openclaw onboard --openai-api-key "$OPENAI_API_KEY"
|
||||
}
|
||||
```
|
||||
|
||||
OpenAI 当前的 API 模型文档列出了可直接通过 OpenAI API 使用的 `gpt-5.4` 和 `gpt-5.4-pro`。OpenClaw 通过 `openai/*` Responses 路径转发这两个模型。OpenClaw 会有意隐藏过时的 `openai/gpt-5.3-codex-spark` 条目,因为直接 OpenAI API 调用在真实流量中会拒绝它。
|
||||
OpenAI 当前的 API 模型文档将 `gpt-5.4` 和 `gpt-5.4-pro` 列为可直接
|
||||
通过 OpenAI API 使用的模型。OpenClaw 会通过 `openai/*` Responses 路径转发这两个模型。
|
||||
OpenClaw 会有意隐藏过时的 `openai/gpt-5.3-codex-spark` 条目,
|
||||
因为直接 OpenAI API 调用在真实流量中会拒绝它。
|
||||
|
||||
OpenClaw **不会** 在直接 OpenAI API 路径上暴露 `openai/gpt-5.3-codex-spark`。`pi-ai` 仍然为该模型内置了一个条目,但当前真实的 OpenAI API 请求会拒绝它。在 OpenClaw 中,Spark 被视为仅限 Codex。
|
||||
OpenClaw **不会**在直接 OpenAI
|
||||
API 路径上公开 `openai/gpt-5.3-codex-spark`。`pi-ai` 仍然内置该模型的一条记录,但当前真实 OpenAI API
|
||||
请求会拒绝它。在 OpenClaw 中,Spark 被视为仅限 Codex。
|
||||
|
||||
## 图像生成
|
||||
|
||||
内置的 `openai` 插件还会通过共享的 `image_generate` 工具注册图像生成功能。
|
||||
内置的 `openai` 插件也会通过共享的
|
||||
`image_generate` 工具注册图像生成功能。
|
||||
|
||||
- 默认图像模型:`openai/gpt-image-1`
|
||||
- 生成:每次请求最多 4 张图像
|
||||
- 编辑模式:已启用,最多支持 5 张参考图像
|
||||
- 支持 `size`
|
||||
- 当前 OpenAI 专属注意事项:OpenClaw 目前不会将 `aspectRatio` 或 `resolution` 覆盖值转发到 OpenAI Images API
|
||||
- 当前 OpenAI 特定限制:OpenClaw 目前不会将 `aspectRatio` 或
|
||||
`resolution` 覆盖值转发到 OpenAI Images API
|
||||
|
||||
要将 OpenAI 用作默认图像提供商:
|
||||
如需将 OpenAI 用作默认图像提供商:
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -126,18 +146,21 @@ OpenClaw **不会** 在直接 OpenAI API 路径上暴露 `openai/gpt-5.3-codex-s
|
||||
}
|
||||
```
|
||||
|
||||
有关共享工具参数、提供商选择和故障切换行为,请参见 [图像生成](/zh-CN/tools/image-generation)。
|
||||
有关共享工具参数、提供商选择和故障转移行为,请参阅 [图像生成](/zh-CN/tools/image-generation)。
|
||||
|
||||
## 视频生成
|
||||
|
||||
内置的 `openai` 插件还会通过共享的 `video_generate` 工具注册视频生成功能。
|
||||
内置的 `openai` 插件也会通过共享的
|
||||
`video_generate` 工具注册视频生成功能。
|
||||
|
||||
- 默认视频模型:`openai/sora-2`
|
||||
- 模式:文生视频、图生视频,以及单视频参考/编辑流程
|
||||
- 当前限制:仅支持 1 张图像或 1 个视频参考输入
|
||||
- 当前 OpenAI 专属注意事项:OpenClaw 当前仅会为原生 OpenAI 视频生成转发 `size` 覆盖值。不支持的可选覆盖值,如 `aspectRatio`、`resolution`、`audio` 和 `watermark` 会被忽略,并作为工具警告返回。
|
||||
- 当前限制:1 张图像或 1 个视频参考输入
|
||||
- 当前 OpenAI 特定限制:OpenClaw 目前只会为原生 OpenAI 视频生成转发 `size`
|
||||
覆盖值。不支持的可选覆盖值,例如 `aspectRatio`、`resolution`、`audio` 和 `watermark`,会被忽略,
|
||||
并作为工具警告返回。
|
||||
|
||||
要将 OpenAI 用作默认视频提供商:
|
||||
如需将 OpenAI 用作默认视频提供商:
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -151,13 +174,19 @@ OpenClaw **不会** 在直接 OpenAI API 路径上暴露 `openai/gpt-5.3-codex-s
|
||||
}
|
||||
```
|
||||
|
||||
有关共享工具参数、提供商选择和故障切换行为,请参见 [视频生成](/zh-CN/tools/video-generation)。
|
||||
有关共享工具参数、提供商选择和故障转移行为,请参阅 [视频生成](/zh-CN/tools/video-generation)。
|
||||
|
||||
## 选项 B:OpenAI Code(Codex)订阅
|
||||
|
||||
**最适合:** 使用 ChatGPT/Codex 订阅访问,而不是 API 密钥。
|
||||
Codex cloud 需要 ChatGPT 登录,而 Codex CLI 支持 ChatGPT 或 API 密钥登录。
|
||||
|
||||
路由摘要:
|
||||
|
||||
- `openai-codex/gpt-5.4` = ChatGPT/Codex OAuth 路由
|
||||
- 使用 ChatGPT/Codex 登录,而不是直接 OpenAI Platform API 密钥
|
||||
- `openai-codex/*` 的提供商侧限制可能与 ChatGPT 网页版/应用版体验不同
|
||||
|
||||
### CLI 设置(Codex OAuth)
|
||||
|
||||
```bash
|
||||
@ -176,30 +205,43 @@ openclaw models auth login --provider openai-codex
|
||||
}
|
||||
```
|
||||
|
||||
OpenAI 当前的 Codex 文档将 `gpt-5.4` 列为当前 Codex 模型。OpenClaw 将其映射为 `openai-codex/gpt-5.4`,用于 ChatGPT/Codex OAuth 访问。
|
||||
OpenAI 当前的 Codex 文档将 `gpt-5.4` 列为当前 Codex 模型。OpenClaw
|
||||
会将其映射为 `openai-codex/gpt-5.4`,用于 ChatGPT/Codex OAuth。
|
||||
|
||||
如果新手引导复用了现有的 Codex CLI 登录,这些凭证将继续由 Codex CLI 管理。凭证过期时,OpenClaw 会先重新读取外部 Codex 来源;当提供商可以刷新它时,会将刷新后的凭证写回 Codex 存储,而不是在单独的 OpenClaw 专用副本中接管管理。
|
||||
这一路由与 `openai/gpt-5.4` 是有意分开的。如果你想使用
|
||||
直接 OpenAI Platform API 路径,请使用带 API 密钥的 `openai/*`。如果你想使用
|
||||
ChatGPT/Codex 登录,请使用 `openai-codex/*`。
|
||||
|
||||
如果你的 Codex 账户具有 Codex Spark 权限,OpenClaw 还支持:
|
||||
如果新手引导复用了现有的 Codex CLI 登录,这些凭证
|
||||
仍由 Codex CLI 管理。过期时,OpenClaw 会先重新读取外部 Codex 来源,
|
||||
并且当提供商可以刷新它时,会将刷新后的凭证写回 Codex 存储,
|
||||
而不是通过单独的 OpenClaw 专用副本接管它。
|
||||
|
||||
如果你的 Codex 账户拥有 Codex Spark 权限,OpenClaw 还支持:
|
||||
|
||||
- `openai-codex/gpt-5.3-codex-spark`
|
||||
|
||||
OpenClaw 将 Codex Spark 视为仅限 Codex。它不会暴露直接的 `openai/gpt-5.3-codex-spark` API 密钥路径。
|
||||
OpenClaw 将 Codex Spark 视为仅限 Codex。它不会公开直接的
|
||||
`openai/gpt-5.3-codex-spark` API 密钥路径。
|
||||
|
||||
当 `pi-ai` 发现 `openai-codex/gpt-5.3-codex-spark` 时,OpenClaw 也会保留它。请将其视为依赖权限且带有实验性质:Codex Spark 独立于 GPT-5.4 `/fast`,其可用性取决于已登录的 Codex / ChatGPT 账户。
|
||||
当 `pi-ai`
|
||||
发现 `openai-codex/gpt-5.3-codex-spark` 时,OpenClaw 也会保留它。请将其视为依赖权限且具有实验性:Codex Spark 与 GPT-5.4 `/fast` 是
|
||||
分开的,其可用性取决于已登录的 Codex / ChatGPT 账户。
|
||||
|
||||
### Codex 上下文窗口上限
|
||||
|
||||
OpenClaw 将 Codex 模型元数据和运行时上下文上限视为两个独立的值。
|
||||
OpenClaw 将 Codex 模型元数据和运行时上下文上限视为彼此独立的
|
||||
值。
|
||||
|
||||
对于 `openai-codex/gpt-5.4`:
|
||||
|
||||
- 原生 `contextWindow`:`1050000`
|
||||
- 默认运行时 `contextTokens` 上限:`272000`
|
||||
|
||||
这样既能保持模型元数据真实准确,又能保留在实践中具有更好延迟和质量特性的较小默认运行时窗口。
|
||||
这样既保证模型元数据真实,又保留了在实践中具有更好延迟和质量特征的较小默认运行时
|
||||
窗口。
|
||||
|
||||
如果你想使用不同的实际上限,请设置 `models.providers.<provider>.models[].contextTokens`:
|
||||
如果你想要不同的实际上限,请设置 `models.providers.<provider>.models[].contextTokens`:
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -218,19 +260,33 @@ OpenClaw 将 Codex 模型元数据和运行时上下文上限视为两个独立
|
||||
}
|
||||
```
|
||||
|
||||
仅当你要声明或覆盖原生模型元数据时,才使用 `contextWindow`。当你想限制运行时上下文预算时,请使用 `contextTokens`。
|
||||
只有当你在声明或覆盖原生模型
|
||||
元数据时才使用 `contextWindow`。当你希望限制运行时上下文预算时,请使用 `contextTokens`。
|
||||
|
||||
### 默认传输方式
|
||||
### 传输默认值
|
||||
|
||||
OpenClaw 使用 `pi-ai` 进行模型流式传输。对于 `openai/*` 和 `openai-codex/*`,默认传输方式是 `"auto"`(优先 WebSocket,然后回退到 SSE)。
|
||||
OpenClaw 使用 `pi-ai` 进行模型流式传输。对于 `openai/*` 和
|
||||
`openai-codex/*`,默认传输方式都是 `"auto"`(WebSocket 优先,然后回退到 SSE)。
|
||||
|
||||
在 `"auto"` 模式下,OpenClaw 还会在回退到 SSE 之前,对一次早期且可重试的 WebSocket 失败进行重试。强制使用 `"websocket"` 模式时,传输错误会直接显示,而不会被回退逻辑掩盖。
|
||||
在 `"auto"` 模式下,OpenClaw 还会在回退到 SSE 之前
|
||||
对一次早期、可重试的 WebSocket 失败进行重试。
|
||||
强制 `"websocket"` 模式仍会直接暴露传输错误,而不是用回退隐藏它们。
|
||||
|
||||
在 `"auto"` 模式下,如果连接或会话早期轮次发生 WebSocket 失败,OpenClaw 会将该会话的 WebSocket 路径标记为降级状态,持续大约 60 秒,并在冷却期间通过 SSE 发送后续轮次,而不是在不同传输方式之间来回抖动。
|
||||
在 `"auto"` 模式下,如果发生连接失败或回合早期 WebSocket 失败,OpenClaw 会将
|
||||
该会话的 WebSocket 路径标记为降级状态约 60 秒,并在冷却期间通过 SSE 发送
|
||||
后续回合,而不是在多种传输方式之间来回抖动。
|
||||
|
||||
对于原生 OpenAI 系列端点(`openai/*`、`openai-codex/*` 以及 Azure OpenAI Responses),OpenClaw 还会为请求附加稳定的会话和轮次身份状态,以便重试、重连和 SSE 回退都能与同一会话身份保持一致。在原生 OpenAI 系列路由上,这包括稳定的会话/轮次请求身份标头以及匹配的传输元数据。
|
||||
对于原生 OpenAI 系列端点(`openai/*`、`openai-codex/*` 和 Azure
|
||||
OpenAI Responses),OpenClaw 还会将稳定的会话和回合身份状态附加到请求中,
|
||||
以便重试、重连和 SSE 回退都保持与同一个
|
||||
对话身份一致。在原生 OpenAI 系列路由上,这包括稳定的
|
||||
会话/回合请求身份头以及匹配的传输元数据。
|
||||
|
||||
OpenClaw 还会在 OpenAI 使用量计数器到达会话/状态界面之前,先跨不同传输变体对它们进行归一化。原生 OpenAI/Codex Responses 流量可能会将使用量报告为 `input_tokens` / `output_tokens`,也可能报告为 `prompt_tokens` / `completion_tokens`;OpenClaw 会将它们视为相同的输入和输出计数器,用于 `/status`、`/usage` 和会话日志。当原生 WebSocket 流量省略 `total_tokens`(或报告为 `0`)时,OpenClaw 会回退为归一化后的输入 + 输出总数,以确保会话/状态显示仍然有值。
|
||||
OpenClaw 还会在 OpenAI 使用量计数器到达会话/状态界面之前,跨不同传输变体对其进行标准化。原生 OpenAI/Codex Responses 流量可能会将使用量报告为 `input_tokens` / `output_tokens` 或
|
||||
`prompt_tokens` / `completion_tokens`;OpenClaw 会在 `/status`、`/usage` 和会话日志中将它们视为相同的输入
|
||||
和输出计数器。当原生
|
||||
WebSocket 流量省略 `total_tokens`(或报告为 `0`)时,OpenClaw 会回退为
|
||||
标准化后的输入 + 输出总和,以便会话/状态显示保持有值。
|
||||
|
||||
你可以设置 `agents.defaults.models.<provider/model>.params.transport`:
|
||||
|
||||
@ -238,7 +294,8 @@ OpenClaw 还会在 OpenAI 使用量计数器到达会话/状态界面之前,
|
||||
- `"websocket"`:强制使用 WebSocket
|
||||
- `"auto"`:先尝试 WebSocket,然后回退到 SSE
|
||||
|
||||
对于 `openai/*`(Responses API),当使用 WebSocket 传输时,OpenClaw 还会默认启用 WebSocket 预热(`openaiWsWarmup: true`)。
|
||||
对于 `openai/*`(Responses API),当使用 WebSocket 传输时,OpenClaw 还会默认启用
|
||||
WebSocket 预热(`openaiWsWarmup: true`)。
|
||||
|
||||
相关 OpenAI 文档:
|
||||
|
||||
@ -264,7 +321,8 @@ OpenClaw 还会在 OpenAI 使用量计数器到达会话/状态界面之前,
|
||||
|
||||
### OpenAI WebSocket 预热
|
||||
|
||||
OpenAI 文档将预热描述为可选功能。OpenClaw 默认会为 `openai/*` 启用它,以减少使用 WebSocket 传输时首轮请求的延迟。
|
||||
OpenAI 文档将预热描述为可选。对于
|
||||
`openai/*`,OpenClaw 默认启用它,以便在使用 WebSocket 传输时降低首轮延迟。
|
||||
|
||||
### 禁用预热
|
||||
|
||||
@ -304,7 +362,9 @@ OpenAI 文档将预热描述为可选功能。OpenClaw 默认会为 `openai/*`
|
||||
|
||||
### OpenAI 和 Codex 优先级处理
|
||||
|
||||
OpenAI 的 API 通过 `service_tier=priority` 提供优先级处理。在 OpenClaw 中,设置 `agents.defaults.models["<provider>/<model>"].params.serviceTier` 即可在原生 OpenAI/Codex Responses 端点上透传该字段。
|
||||
OpenAI 的 API 通过 `service_tier=priority` 暴露优先级处理能力。在
|
||||
OpenClaw 中,设置 `agents.defaults.models["<provider>/<model>"].params.serviceTier`
|
||||
即可在原生 OpenAI/Codex Responses 端点上传递该字段。
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -327,35 +387,37 @@ OpenAI 的 API 通过 `service_tier=priority` 提供优先级处理。在 OpenCl
|
||||
}
|
||||
```
|
||||
|
||||
支持的值有 `auto`、`default`、`flex` 和 `priority`。
|
||||
支持的值为 `auto`、`default`、`flex` 和 `priority`。
|
||||
|
||||
当这些模型指向原生 OpenAI/Codex 端点时,OpenClaw 会将 `params.serviceTier` 同时转发到直接的 `openai/*` Responses 请求和 `openai-codex/*` Codex Responses 请求。
|
||||
当这些模型指向原生 OpenAI/Codex 端点时,OpenClaw 会将 `params.serviceTier` 同时转发到直接 `openai/*` Responses
|
||||
请求和 `openai-codex/*` Codex Responses 请求。
|
||||
|
||||
重要行为:
|
||||
|
||||
- 直接 `openai/*` 必须指向 `api.openai.com`
|
||||
- `openai-codex/*` 必须指向 `chatgpt.com/backend-api`
|
||||
- 如果你通过其他 base URL 或代理转发任一提供商,OpenClaw 会保持 `service_tier` 不变
|
||||
- 如果你通过其他 base URL 或代理路由其中任一提供商,OpenClaw 会保持 `service_tier` 原样不动
|
||||
|
||||
### OpenAI 快速模式
|
||||
|
||||
OpenClaw 为 `openai/*` 和 `openai-codex/*` 会话提供了共享的快速模式开关:
|
||||
OpenClaw 为 `openai/*` 和
|
||||
`openai-codex/*` 会话都提供了共享的快速模式开关:
|
||||
|
||||
- 聊天/UI:`/fast status|on|off`
|
||||
- 配置:`agents.defaults.models["<provider>/<model>"].params.fastMode`
|
||||
|
||||
启用快速模式后,OpenClaw 会将其映射为 OpenAI 优先级处理:
|
||||
启用快速模式后,OpenClaw 会将其映射到 OpenAI 优先级处理:
|
||||
|
||||
- 发往 `api.openai.com` 的直接 `openai/*` Responses 调用会发送 `service_tier = "priority"`
|
||||
- 发往 `chatgpt.com/backend-api` 的 `openai-codex/*` Responses 调用也会发送 `service_tier = "priority"`
|
||||
- 指向 `api.openai.com` 的直接 `openai/*` Responses 调用会发送 `service_tier = "priority"`
|
||||
- 指向 `chatgpt.com/backend-api` 的 `openai-codex/*` Responses 调用也会发送 `service_tier = "priority"`
|
||||
- 现有负载中的 `service_tier` 值会被保留
|
||||
- 快速模式不会改写 `reasoning` 或 `text.verbosity`
|
||||
- 快速模式不会重写 `reasoning` 或 `text.verbosity`
|
||||
|
||||
对于 GPT 5.4,最常见的配置是:
|
||||
对于 GPT 5.4,最常见的设置是:
|
||||
|
||||
- 在使用 `openai/gpt-5.4` 或 `openai-codex/gpt-5.4` 的会话中发送 `/fast on`
|
||||
- 或设置 `agents.defaults.models["openai/gpt-5.4"].params.fastMode = true`
|
||||
- 如果你也使用 Codex OAuth,请同时设置 `agents.defaults.models["openai-codex/gpt-5.4"].params.fastMode = true`
|
||||
- 如果你也使用 Codex OAuth,也要设置 `agents.defaults.models["openai-codex/gpt-5.4"].params.fastMode = true`
|
||||
|
||||
示例:
|
||||
|
||||
@ -380,34 +442,48 @@ OpenClaw 为 `openai/*` 和 `openai-codex/*` 会话提供了共享的快速模
|
||||
}
|
||||
```
|
||||
|
||||
会话级覆盖优先于配置。在 Sessions UI 中清除此会话覆盖后,会话将恢复为配置的默认值。
|
||||
会话覆盖优先于配置。在 Sessions UI
|
||||
中清除会话覆盖会让该会话恢复为配置的默认值。
|
||||
|
||||
### 原生 OpenAI 与 OpenAI-compatible 路由的区别
|
||||
### 原生 OpenAI 与 OpenAI 兼容路由
|
||||
|
||||
OpenClaw 对直接 OpenAI、Codex 和 Azure OpenAI 端点的处理方式,与通用的 OpenAI-compatible `/v1` 代理不同:
|
||||
OpenClaw 对直接 OpenAI、Codex 和 Azure OpenAI 端点的处理方式
|
||||
与通用 OpenAI 兼容 `/v1` 代理不同:
|
||||
|
||||
- 原生 `openai/*`、`openai-codex/*` 和 Azure OpenAI 路由会在你显式禁用推理时,保留 `reasoning: { effort: "none" }`
|
||||
- 原生 OpenAI 系列路由默认将工具 schema 设为严格模式
|
||||
- 隐藏的 OpenClaw 归因标头(`originator`、`version` 和 `User-Agent`)只会附加到已验证的原生 OpenAI 主机(`api.openai.com`)和原生 Codex 主机(`chatgpt.com/backend-api`)上
|
||||
- 原生 OpenAI/Codex 路由会保留 OpenAI 专属请求整形能力,例如 `service_tier`、Responses `store`、OpenAI 推理兼容负载以及提示词缓存提示
|
||||
- 代理风格的 OpenAI-compatible 路由会保留更宽松的兼容行为,不会强制严格工具 schema、原生专属请求整形或隐藏的 OpenAI/Codex 归因标头
|
||||
- 原生 `openai/*`、`openai-codex/*` 和 Azure OpenAI 路由会在你显式禁用 reasoning 时保留
|
||||
`reasoning: { effort: "none" }`
|
||||
- 原生 OpenAI 系列路由默认将工具 schema 设为 strict 模式
|
||||
- 隐藏的 OpenClaw 标识头(`originator`、`version` 和
|
||||
`User-Agent`)只会附加到经过验证的原生 OpenAI 主机
|
||||
(`api.openai.com`)和原生 Codex 主机(`chatgpt.com/backend-api`)上
|
||||
- 原生 OpenAI/Codex 路由会保留 OpenAI 专属请求整形,例如
|
||||
`service_tier`、Responses `store`、OpenAI reasoning 兼容负载以及
|
||||
prompt-cache 提示
|
||||
- 代理式 OpenAI 兼容路由会保留更宽松的兼容行为,并且
|
||||
不会强制 strict 工具 schema、原生专属请求整形或隐藏的
|
||||
OpenAI/Codex 标识头
|
||||
|
||||
Azure OpenAI 在传输和兼容行为方面仍属于原生路由类别,但不会收到隐藏的 OpenAI/Codex 归因标头。
|
||||
Azure OpenAI 在传输和兼容行为上仍属于原生路由类别,
|
||||
但不会接收隐藏的 OpenAI/Codex 标识头。
|
||||
|
||||
这样可以保留当前原生 OpenAI Responses 行为,同时不会把较旧的 OpenAI-compatible 适配逻辑强加到第三方 `/v1` 后端上。
|
||||
这样可以保留当前原生 OpenAI Responses 行为,而不会将旧式
|
||||
OpenAI 兼容 shim 强加给第三方 `/v1` 后端。
|
||||
|
||||
### OpenAI Responses 服务端压缩
|
||||
|
||||
对于直接 OpenAI Responses 模型(`openai/*` 使用 `api: "openai-responses"` 且 `baseUrl` 为 `api.openai.com`),OpenClaw 现在会自动启用 OpenAI 服务端压缩负载提示:
|
||||
对于直接 OpenAI Responses 模型(`openai/*` 使用 `api: "openai-responses"`,且
|
||||
`baseUrl` 为 `api.openai.com`),OpenClaw 现在会自动启用 OpenAI 服务端
|
||||
压缩负载提示:
|
||||
|
||||
- 强制设置 `store: true`(除非模型兼容性设置 `supportsStore: false`)
|
||||
- 强制 `store: true`(除非模型兼容层将 `supportsStore: false`)
|
||||
- 注入 `context_management: [{ type: "compaction", compact_threshold: ... }]`
|
||||
|
||||
默认情况下,`compact_threshold` 为模型 `contextWindow` 的 `70%`(如果不可用,则为 `80000`)。
|
||||
|
||||
### 显式启用服务端压缩
|
||||
|
||||
当你想在兼容的 Responses 模型上强制注入 `context_management` 时使用此项(例如 Azure OpenAI Responses):
|
||||
当你希望在兼容的
|
||||
Responses 模型(例如 Azure OpenAI Responses)上强制注入 `context_management` 时,请使用此设置:
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -462,9 +538,11 @@ Azure OpenAI 在传输和兼容行为方面仍属于原生路由类别,但不
|
||||
}
|
||||
```
|
||||
|
||||
`responsesServerCompaction` 只控制 `context_management` 注入。直接 OpenAI Responses 模型仍会强制设置 `store: true`,除非兼容性设置了 `supportsStore: false`。
|
||||
`responsesServerCompaction` 只控制 `context_management` 注入。
|
||||
直接 OpenAI Responses 模型仍会强制 `store: true`,除非兼容层设置
|
||||
`supportsStore: false`。
|
||||
|
||||
## 备注
|
||||
## 说明
|
||||
|
||||
- 模型引用始终使用 `provider/model`(见 [/concepts/models](/zh-CN/concepts/models))。
|
||||
- 凭证详情和复用规则见 [/concepts/oauth](/zh-CN/concepts/oauth)。
|
||||
- 模型引用始终使用 `provider/model`(参见 [/concepts/models](/zh-CN/concepts/models))。
|
||||
- 认证详情和复用规则见 [/concepts/oauth](/zh-CN/concepts/oauth)。
|
||||
|
||||
@ -2,64 +2,61 @@
|
||||
read_when:
|
||||
- 你想了解哪些功能可能会调用付费 API
|
||||
- 你需要审计密钥、成本和用量可见性
|
||||
- 你在解释 /status 或 /usage 成本报告
|
||||
summary: 审计哪些功能会花钱、使用了哪些密钥,以及如何查看用量
|
||||
title: API 用量与成本
|
||||
- 你正在解释 /status 或 /usage 成本报告
|
||||
summary: 审计哪些功能会花钱、使用哪些密钥,以及如何查看用量
|
||||
title: API 使用与成本
|
||||
x-i18n:
|
||||
generated_at: "2026-04-05T10:07:46Z"
|
||||
generated_at: "2026-04-06T15:31:12Z"
|
||||
model: gpt-5.4
|
||||
provider: openai
|
||||
source_hash: 71789950fe54dcdcd3e34c8ad6e3143f749cdfff5bbc2f14be4b85aaa467b14c
|
||||
source_hash: ab6eefcde9ac014df6cdda7aaa77ef48f16936ab12eaa883d9fe69425a31a2dd
|
||||
source_path: reference/api-usage-costs.md
|
||||
workflow: 15
|
||||
---
|
||||
|
||||
# API 用量与成本
|
||||
# API 使用与成本
|
||||
|
||||
本文档列出了**可能调用 API 密钥的功能**以及它们的成本会显示在哪里。它重点说明
|
||||
OpenClaw 中可能产生提供商用量或付费 API 调用的功能。
|
||||
本文档列出了**可能调用 API 密钥的功能**以及它们的成本会显示在哪里。重点关注
|
||||
可能产生提供商用量或付费 API 调用的 OpenClaw 功能。
|
||||
|
||||
## 成本显示位置(聊天 + CLI)
|
||||
|
||||
**按会话的成本快照**
|
||||
|
||||
- `/status` 会显示当前会话模型、上下文用量以及上一次响应的 token 数。
|
||||
- 如果模型使用**API 密钥认证**,`/status` 还会显示上一次回复的**估算成本**。
|
||||
- 如果实时会话元数据较少,`/status` 可以从最新转录中的用量
|
||||
条目恢复 token/缓存计数器和当前活动运行时模型标签。
|
||||
现有的非零实时值仍然优先,如果存储的总量缺失或更小,
|
||||
按提示大小统计的转录总量也可以优先生效。
|
||||
- `/status` 会显示当前会话模型、上下文用量和上一条回复的 token 数。
|
||||
- 如果模型使用的是 **API 密钥认证**,`/status` 还会显示上一条回复的**估算成本**。
|
||||
- 如果 live 会话元数据较少,`/status` 可以从最新的转录用量条目中恢复 token/缓存
|
||||
计数器以及当前活动运行时模型标签。现有的非零 live 值仍然优先,
|
||||
当已存储总量缺失或更小时,按提示词大小计算的转录总量可以胜出。
|
||||
|
||||
**按消息的成本页脚**
|
||||
|
||||
- `/usage full` 会在每条回复后附加一个用量页脚,其中包括**估算成本**(仅限 API 密钥)。
|
||||
- `/usage tokens` 仅显示 token;基于订阅的 OAuth/token 和 CLI 流程会隐藏美元成本。
|
||||
- `/usage full` 会在每条回复后追加用量页脚,其中包括**估算成本**(仅 API 密钥)。
|
||||
- `/usage tokens` 仅显示 token;订阅式 OAuth/token 和 CLI 流程会隐藏美元成本。
|
||||
- Gemini CLI 说明:当 CLI 返回 JSON 输出时,OpenClaw 会从
|
||||
`stats` 读取用量,将 `stats.cached` 规范化为 `cacheRead`,并在需要时从
|
||||
`stats` 中读取用量,将 `stats.cached` 标准化为 `cacheRead`,并在需要时从
|
||||
`stats.input_tokens - stats.cached` 推导输入 token。
|
||||
|
||||
Anthropic 说明:Anthropic 公开的 Claude Code 文档仍将直接 Claude
|
||||
Code 终端用量计入 Claude 套餐限制。另一方面,Anthropic 已告知 OpenClaw
|
||||
用户,从 **2026 年 4 月 4 日太平洋时间下午 12:00 / 英国夏令时晚上 8:00** 起,
|
||||
**OpenClaw** 的 Claude 登录路径将被视为第三方 harness 用法,
|
||||
并且需要单独于订阅计费的 **Extra Usage**。Anthropic
|
||||
并未提供 OpenClaw 可在
|
||||
`/usage full` 中显示的逐条消息美元估算值。
|
||||
Anthropic 说明:Anthropic 员工告诉我们,OpenClaw 风格的 Claude CLI 用量
|
||||
现在再次被允许,因此 OpenClaw 将 Claude CLI 复用和 `claude -p` 用法
|
||||
视为此集成的许可方式,除非 Anthropic 发布新的政策。
|
||||
Anthropic 仍然没有提供 OpenClaw 可以在 `/usage full` 中
|
||||
显示的逐消息美元估算。
|
||||
|
||||
**CLI 用量窗口(提供商配额)**
|
||||
|
||||
- `openclaw status --usage` 和 `openclaw channels list` 会显示提供商**用量窗口**
|
||||
(配额快照,而不是逐条消息成本)。
|
||||
- 人类可读输出会在各提供商之间统一规范为 `X% left`。
|
||||
- `openclaw status --usage` 和 `openclaw channels list` 会显示提供商的**用量窗口**
|
||||
(配额快照,而不是逐消息成本)。
|
||||
- 面向人的输出会在各提供商之间标准化为 `X% left`。
|
||||
- 当前支持用量窗口的提供商:Anthropic、GitHub Copilot、Gemini CLI、
|
||||
OpenAI Codex、MiniMax、Xiaomi 和 z.ai。
|
||||
- MiniMax 说明:其原始 `usage_percent` / `usagePercent` 字段表示剩余
|
||||
配额,因此 OpenClaw 会在显示前将其取反。如果存在基于计数的字段,
|
||||
这些字段仍然优先生效。如果提供商返回 `model_remains`,OpenClaw 会优先选择
|
||||
聊天模型条目,必要时从时间戳推导窗口标签,
|
||||
并在套餐标签中包含模型名称。
|
||||
- 这些配额窗口的用量认证会在可用时优先来自提供商特定 hooks;
|
||||
否则 OpenClaw 会回退到从认证配置文件、环境变量或配置中匹配 OAuth/API 密钥
|
||||
- MiniMax 说明:其原始 `usage_percent` / `usagePercent` 字段表示的是剩余
|
||||
配额,因此 OpenClaw 会在显示前将其反转。如果存在基于计数的字段,
|
||||
仍然优先使用计数字段。如果提供商返回 `model_remains`,OpenClaw 会优先使用
|
||||
聊天模型条目,必要时从时间戳推导窗口标签,并在套餐标签中
|
||||
包含模型名称。
|
||||
- 这些配额窗口的用量认证会在可用时来自提供商特定钩子;否则 OpenClaw 会回退到从
|
||||
认证 profile、环境变量或配置中匹配 OAuth/API 密钥
|
||||
凭证。
|
||||
|
||||
详情和示例参见 [Token 使用与成本](/zh-CN/reference/token-use)。
|
||||
@ -68,94 +65,94 @@ Code 终端用量计入 Claude 套餐限制。另一方面,Anthropic 已告知
|
||||
|
||||
OpenClaw 可以从以下位置获取凭证:
|
||||
|
||||
- **认证配置文件**(按智能体划分,存储在 `auth-profiles.json` 中)。
|
||||
- **认证 profile**(每个智能体单独存储在 `auth-profiles.json` 中)。
|
||||
- **环境变量**(例如 `OPENAI_API_KEY`、`BRAVE_API_KEY`、`FIRECRAWL_API_KEY`)。
|
||||
- **配置**(`models.providers.*.apiKey`、`plugins.entries.*.config.webSearch.apiKey`、
|
||||
`plugins.entries.firecrawl.config.webFetch.apiKey`、`memorySearch.*`、
|
||||
`talk.providers.*.apiKey`)。
|
||||
- **Skills**(`skills.entries.<name>.apiKey`),它们可能会将密钥导出到 Skill 进程环境中。
|
||||
- **Skills**(`skills.entries.<name>.apiKey`),它们可能会将密钥导出到 Skill 进程环境变量中。
|
||||
|
||||
## 会消耗密钥的功能
|
||||
|
||||
### 1) 核心模型响应(聊天 + 工具)
|
||||
### 1)核心模型回复(聊天 + 工具)
|
||||
|
||||
每次回复或工具调用都会使用**当前模型提供商**(OpenAI、Anthropic 等)。这是
|
||||
每条回复或工具调用都会使用**当前模型提供商**(OpenAI、Anthropic 等)。这是
|
||||
用量和成本的主要来源。
|
||||
|
||||
这也包括那些仍在 OpenClaw 本地 UI 之外计费的订阅式托管提供商,
|
||||
这也包括仍在 OpenClaw 本地 UI 之外计费的订阅式托管提供商,
|
||||
例如 **OpenAI Codex**、**Alibaba Cloud Model Studio
|
||||
Coding Plan**、**MiniMax Coding Plan**、**Z.AI / GLM Coding Plan**,以及
|
||||
启用了 **Extra Usage** 的 Anthropic OpenClaw Claude 登录路径。
|
||||
|
||||
关于定价配置参见 [模型](/zh-CN/providers/models),关于显示方式参见 [Token 使用与成本](/zh-CN/reference/token-use)。
|
||||
定价配置参见 [模型](/zh-CN/providers/models),显示方式参见 [Token 使用与成本](/zh-CN/reference/token-use)。
|
||||
|
||||
### 2) 媒体理解(音频/图像/视频)
|
||||
### 2)媒体理解(音频/图像/视频)
|
||||
|
||||
在运行回复之前,可以先对输入媒体进行摘要或转录。这会使用模型/提供商 API。
|
||||
在执行回复之前,入站媒体可能会先被摘要/转录。这会使用模型/提供商 API。
|
||||
|
||||
- 音频:OpenAI / Groq / Deepgram / Google / Mistral。
|
||||
- 图像:OpenAI / OpenRouter / Anthropic / Google / MiniMax / Moonshot / Qwen / Z.AI。
|
||||
- 视频:Google / Qwen / Moonshot。
|
||||
- 图像:OpenAI / OpenRouter / Anthropic / Google / MiniMax / Moonshot AI / Qwen / Z.AI。
|
||||
- 视频:Google / Qwen / Moonshot AI。
|
||||
|
||||
参见 [媒体理解](/zh-CN/nodes/media-understanding)。
|
||||
|
||||
### 3) 图像和视频生成
|
||||
### 3)图像和视频生成
|
||||
|
||||
共享生成能力也可能消耗提供商密钥:
|
||||
共享的生成能力也可能消耗提供商密钥:
|
||||
|
||||
- 图像生成:OpenAI / Google / fal / MiniMax
|
||||
- 视频生成:Qwen
|
||||
|
||||
当
|
||||
`agents.defaults.imageGenerationModel` 未设置时,图像生成可以推断一个基于认证的提供商默认值。视频生成目前
|
||||
需要显式设置 `agents.defaults.videoGenerationModel`,例如
|
||||
`agents.defaults.imageGenerationModel` 未设置时,图像生成可以推断出一个基于认证的默认提供商。视频生成当前
|
||||
要求显式设置 `agents.defaults.videoGenerationModel`,例如
|
||||
`qwen/wan2.6-t2v`。
|
||||
|
||||
参见 [图像生成](/tools/image-generation)、[Qwen Cloud](/zh-CN/providers/qwen)
|
||||
参见 [图像生成](/zh-CN/tools/image-generation)、[Qwen Cloud](/zh-CN/providers/qwen)
|
||||
和 [模型](/zh-CN/concepts/models)。
|
||||
|
||||
### 4) 记忆嵌入 + 语义搜索
|
||||
### 4)记忆嵌入 + 语义搜索
|
||||
|
||||
语义记忆搜索在配置为远程提供商时会使用**嵌入 API**:
|
||||
配置为远程提供商时,语义记忆搜索会使用**嵌入 API**:
|
||||
|
||||
- `memorySearch.provider = "openai"` → OpenAI 嵌入
|
||||
- `memorySearch.provider = "gemini"` → Gemini 嵌入
|
||||
- `memorySearch.provider = "voyage"` → Voyage 嵌入
|
||||
- `memorySearch.provider = "mistral"` → Mistral 嵌入
|
||||
- `memorySearch.provider = "ollama"` → Ollama 嵌入(本地/自托管;通常没有托管 API 计费)
|
||||
- 如果本地嵌入失败,可选择回退到远程提供商
|
||||
- `memorySearch.provider = "openai"` → OpenAI embeddings
|
||||
- `memorySearch.provider = "gemini"` → Gemini embeddings
|
||||
- `memorySearch.provider = "voyage"` → Voyage embeddings
|
||||
- `memorySearch.provider = "mistral"` → Mistral embeddings
|
||||
- `memorySearch.provider = "ollama"` → Ollama embeddings(本地/自托管;通常不会产生托管 API 计费)
|
||||
- 如果本地 embeddings 失败,可选择回退到远程提供商
|
||||
|
||||
你可以通过设置 `memorySearch.provider = "local"` 保持本地运行(不使用 API)。
|
||||
你可以通过 `memorySearch.provider = "local"` 保持本地运行(不使用 API)。
|
||||
|
||||
参见 [记忆](/zh-CN/concepts/memory)。
|
||||
参见 [Memory](/zh-CN/concepts/memory)。
|
||||
|
||||
### 5) Web 搜索工具
|
||||
### 5)Web 搜索工具
|
||||
|
||||
`web_search` 可能会根据你的提供商产生用量费用:
|
||||
|
||||
- **Brave Search API**:`BRAVE_API_KEY` 或 `plugins.entries.brave.config.webSearch.apiKey`
|
||||
- **Exa**:`EXA_API_KEY` 或 `plugins.entries.exa.config.webSearch.apiKey`
|
||||
- **Firecrawl**:`FIRECRAWL_API_KEY` 或 `plugins.entries.firecrawl.config.webSearch.apiKey`
|
||||
- **Gemini(Google Search)**:`GEMINI_API_KEY` 或 `plugins.entries.google.config.webSearch.apiKey`
|
||||
- **Gemini(Google 搜索)**:`GEMINI_API_KEY` 或 `plugins.entries.google.config.webSearch.apiKey`
|
||||
- **Grok(xAI)**:`XAI_API_KEY` 或 `plugins.entries.xai.config.webSearch.apiKey`
|
||||
- **Kimi(Moonshot)**:`KIMI_API_KEY`、`MOONSHOT_API_KEY` 或 `plugins.entries.moonshot.config.webSearch.apiKey`
|
||||
- **Kimi(Moonshot AI)**:`KIMI_API_KEY`、`MOONSHOT_API_KEY` 或 `plugins.entries.moonshot.config.webSearch.apiKey`
|
||||
- **MiniMax Search**:`MINIMAX_CODE_PLAN_KEY`、`MINIMAX_CODING_API_KEY`、`MINIMAX_API_KEY` 或 `plugins.entries.minimax.config.webSearch.apiKey`
|
||||
- **Ollama Web 搜索**:默认不需要密钥,但需要可访问的 Ollama 主机以及 `ollama signin`;当主机要求认证时,也可以复用普通 Ollama 提供商 bearer 认证
|
||||
- **Ollama Web 搜索**:默认不需要密钥,但要求可访问的 Ollama 主机以及 `ollama signin`;当主机要求时,也可以复用普通的 Ollama 提供商 bearer 认证
|
||||
- **Perplexity Search API**:`PERPLEXITY_API_KEY`、`OPENROUTER_API_KEY` 或 `plugins.entries.perplexity.config.webSearch.apiKey`
|
||||
- **Tavily**:`TAVILY_API_KEY` 或 `plugins.entries.tavily.config.webSearch.apiKey`
|
||||
- **DuckDuckGo**:无密钥回退(不产生 API 计费,但属于非官方且基于 HTML)
|
||||
- **SearXNG**:`SEARXNG_BASE_URL` 或 `plugins.entries.searxng.config.webSearch.baseUrl`(无密钥/自托管;无托管 API 计费)
|
||||
- **DuckDuckGo**:无密钥回退方案(不产生 API 计费,但属于非官方且基于 HTML)
|
||||
- **SearXNG**:`SEARXNG_BASE_URL` 或 `plugins.entries.searxng.config.webSearch.baseUrl`(无密钥/自托管;不产生托管 API 计费)
|
||||
|
||||
旧版 `tools.web.search.*` 提供商路径仍会通过临时兼容层加载,但它们已不再是推荐的配置入口。
|
||||
旧版 `tools.web.search.*` 提供商路径仍会通过临时兼容层加载,但它们已不再是推荐的配置接口。
|
||||
|
||||
**Brave Search 免费额度:** 每个 Brave 套餐都包含每月 \$5 的可续期
|
||||
免费额度。Search 套餐费用为每 1,000 次请求 \$5,因此该额度可覆盖
|
||||
每月 1,000 次请求且无需付费。请在 Brave 控制台中设置用量上限,
|
||||
以避免意外收费。
|
||||
免费额度。Search 套餐价格为每 1,000 次请求 \$5,因此该额度可覆盖
|
||||
每月 1,000 次免费请求。请在 Brave 控制台中设置用量上限,
|
||||
以避免意外费用。
|
||||
|
||||
参见 [Web 工具](/zh-CN/tools/web)。
|
||||
|
||||
### 5) Web 抓取工具(Firecrawl)
|
||||
### 5)Web 抓取工具(Firecrawl)
|
||||
|
||||
当存在 API 密钥时,`web_fetch` 可以调用 **Firecrawl**:
|
||||
|
||||
@ -165,40 +162,40 @@ Coding Plan**、**MiniMax Coding Plan**、**Z.AI / GLM Coding Plan**,以及
|
||||
|
||||
参见 [Web 工具](/zh-CN/tools/web)。
|
||||
|
||||
### 6) 提供商用量快照(status/health)
|
||||
### 6)提供商用量快照(状态/健康)
|
||||
|
||||
某些状态命令会调用**提供商用量端点**来显示配额窗口或认证健康状态。
|
||||
这些通常是低频调用,但仍会访问提供商 API:
|
||||
某些状态命令会调用**提供商用量端点**以显示配额窗口或认证健康状态。
|
||||
这些通常是低频调用,但仍会命中提供商 API:
|
||||
|
||||
- `openclaw status --usage`
|
||||
- `openclaw models status --json`
|
||||
|
||||
参见 [Models CLI](/cli/models)。
|
||||
|
||||
### 7) 压缩保护摘要
|
||||
### 7)压缩保护摘要
|
||||
|
||||
压缩保护可以使用**当前模型**对会话历史进行摘要,
|
||||
因此运行时会调用提供商 API。
|
||||
压缩保护机制可以使用**当前模型**对会话历史进行摘要,
|
||||
运行时会调用提供商 API。
|
||||
|
||||
参见 [会话管理 + 压缩](/zh-CN/reference/session-management-compaction)。
|
||||
|
||||
### 8) 模型扫描 / 探测
|
||||
### 8)模型扫描 / 探测
|
||||
|
||||
`openclaw models scan` 在启用探测时可以探测 OpenRouter 模型,并使用 `OPENROUTER_API_KEY`。
|
||||
在启用探测时,`openclaw models scan` 可以探测 OpenRouter 模型,并使用 `OPENROUTER_API_KEY`。
|
||||
|
||||
参见 [Models CLI](/cli/models)。
|
||||
|
||||
### 9) Talk(语音)
|
||||
### 9)Talk(语音)
|
||||
|
||||
Talk 模式在配置后可以调用 **ElevenLabs**:
|
||||
配置后,Talk 模式可以调用 **ElevenLabs**:
|
||||
|
||||
- `ELEVENLABS_API_KEY` 或 `talk.providers.elevenlabs.apiKey`
|
||||
|
||||
参见 [Talk 模式](/zh-CN/nodes/talk)。
|
||||
|
||||
### 10) Skills(第三方 API)
|
||||
### 10)Skills(第三方 API)
|
||||
|
||||
Skills 可以将 `apiKey` 存储在 `skills.entries.<name>.apiKey` 中。如果某个 Skill 使用该密钥访问外部
|
||||
API,则可能根据该 Skill 的提供商产生费用。
|
||||
Skills 可以在 `skills.entries.<name>.apiKey` 中存储 `apiKey`。如果某个 Skill 使用该密钥访问外部
|
||||
API,它就可能按该 Skill 提供商的规则产生费用。
|
||||
|
||||
参见 [Skills](/zh-CN/tools/skills)。
|
||||
|
||||
@ -1,13 +1,13 @@
|
||||
---
|
||||
read_when:
|
||||
- 运行或修复测试
|
||||
summary: 如何在本地运行测试(vitest),以及何时使用 force/coverage 模式
|
||||
- 运行或修复测试时
|
||||
summary: 如何在本地运行测试(Vitest),以及何时使用 force/coverage 模式
|
||||
title: 测试
|
||||
x-i18n:
|
||||
generated_at: "2026-04-05T10:09:00Z"
|
||||
generated_at: "2026-04-06T15:31:19Z"
|
||||
model: gpt-5.4
|
||||
provider: openai
|
||||
source_hash: 78390107a9ac2bdc4294d4d0204467c5efdd98faebaf308f3a4597ab966a6d26
|
||||
source_hash: f47eef441b9dc700b0f7182ebf1b494303cd1dab85aefdea414a0fae12f51963
|
||||
source_path: reference/test.md
|
||||
workflow: 15
|
||||
---
|
||||
@ -16,40 +16,42 @@ x-i18n:
|
||||
|
||||
- 完整测试套件(测试集、live、Docker):[测试](/zh-CN/help/testing)
|
||||
|
||||
- `pnpm test:force`:终止所有仍占用默认控制端口的残留 Gateway 网关进程,然后使用隔离的 Gateway 网关端口运行完整的 Vitest 测试套件,避免服务端测试与正在运行的实例冲突。当先前的 Gateway 网关运行导致端口 `18789` 仍被占用时,请使用此命令。
|
||||
- `pnpm test:coverage`:使用 V8 覆盖率运行单元测试集(通过 `vitest.unit.config.ts`)。全局阈值为 70% 的行数/分支/函数/语句覆盖率。覆盖率会排除集成较重的入口点(CLI 接线、gateway/telegram 桥接、webchat 静态服务器),以便将目标聚焦于适合单元测试的逻辑。
|
||||
- `pnpm test:coverage:changed`:仅对自 `origin/main` 以来变更的文件运行单元覆盖率。
|
||||
- `pnpm test:changed`:使用 `--changed origin/main` 运行原生 Vitest projects 配置。基础配置将 projects/config 文件视为 `forceRerunTriggers`,因此当这些接线发生变化时,仍会在需要时更广泛地重新运行测试。
|
||||
- `pnpm test`:直接运行原生 Vitest 根 projects 配置。文件过滤器可在已配置的 projects 间原生生效。
|
||||
- 基础 Vitest 配置现在默认使用 `pool: "threads"` 和 `isolate: false`,并在整个仓库配置中启用共享的非隔离运行器。
|
||||
- `pnpm test:force`:终止任何仍占用默认控制端口的残留 Gateway 网关进程,然后使用隔离的 Gateway 网关端口运行完整的 Vitest 测试套件,以避免服务端测试与正在运行的实例发生冲突。如果之前某次 Gateway 网关运行导致端口 `18789` 仍被占用,请使用此命令。
|
||||
- `pnpm test:coverage`:使用 V8 覆盖率运行单元测试套件(通过 `vitest.unit.config.ts`)。全局阈值为 70% 的 lines/branches/functions/statements。覆盖率会排除集成程度较高的入口点(CLI 接线、gateway/telegram 桥接、webchat 静态服务器),以便将目标聚焦在适合单元测试的逻辑上。
|
||||
- `pnpm test:coverage:changed`:仅对自 `origin/main` 以来变更的文件运行单元测试覆盖率。
|
||||
- `pnpm test:changed`:当差异只涉及可路由的源码/测试文件时,会将变更的 git 路径展开为有范围的 Vitest 测试 lane。配置/设置变更仍会回退为原生根项目运行,以便在需要时让接线改动触发更广泛的重跑。
|
||||
- `pnpm test`:会将显式的文件/目录目标路由到有范围的 Vitest 测试 lane,但在你执行完整、无目标限制的扫描时,仍会回退为原生根项目运行。
|
||||
- 选定的 `plugin-sdk` 和 `commands` 测试文件现在会通过专用的轻量 lane 路由,这些 lane 只保留 `test/setup.ts`,而运行时负担较重的用例仍保留在原有 lane 上。
|
||||
- 选定的 `plugin-sdk` 和 `commands` 辅助源码文件也会将 `pnpm test:changed` 映射到这些轻量 lane 中对应的同级测试,因此对小型辅助函数的修改无需重跑那些依赖重量级运行时的测试套件。
|
||||
- 基础 Vitest 配置现在默认使用 `pool: "threads"` 和 `isolate: false`,并在整个仓库配置中启用了共享的非隔离运行器。
|
||||
- `pnpm test:channels` 运行 `vitest.channels.config.ts`。
|
||||
- `pnpm test:extensions` 运行 `vitest.extensions.config.ts`。
|
||||
- `pnpm test:extensions`:运行扩展/插件测试集。
|
||||
- `pnpm test:perf:imports`:为原生根 projects 运行启用 Vitest 导入耗时 + 导入明细报告。
|
||||
- `pnpm test:perf:imports:changed`:同样的导入性能分析,但仅针对自 `origin/main` 以来变更的文件。
|
||||
- `pnpm test:extensions`:运行扩展/插件测试套件。
|
||||
- `pnpm test:perf:imports`:启用 Vitest 导入耗时 + 导入明细报告,同时对显式文件/目录目标仍使用有范围的 lane 路由。
|
||||
- `pnpm test:perf:imports:changed`:与上面相同的导入分析,但只针对自 `origin/main` 以来变更的文件。
|
||||
- `pnpm test:perf:profile:main`:为 Vitest 主线程写入 CPU profile(`.artifacts/vitest-main-profile`)。
|
||||
- `pnpm test:perf:profile:runner`:为单元测试运行器写入 CPU + 堆 profile(`.artifacts/vitest-runner-profile`)。
|
||||
- `pnpm test:perf:profile:runner`:为单元测试运行器写入 CPU + heap profiles(`.artifacts/vitest-runner-profile`)。
|
||||
- Gateway 网关集成测试:通过 `OPENCLAW_TEST_INCLUDE_GATEWAY=1 pnpm test` 或 `pnpm test:gateway` 选择启用。
|
||||
- `pnpm test:e2e`:运行 Gateway 网关端到端 smoke 测试(多实例 WS/HTTP/节点配对)。在 `vitest.e2e.config.ts` 中默认使用 `threads` + `isolate: false` 和自适应 worker;可通过 `OPENCLAW_E2E_WORKERS=<n>` 调整,并设置 `OPENCLAW_E2E_VERBOSE=1` 以输出详细日志。
|
||||
- `pnpm test:live`:运行 provider live 测试(minimax/zai)。需要 API 密钥和 `LIVE=1`(或 provider 专用的 `*_LIVE_TEST=1`)才能取消跳过。
|
||||
- `pnpm test:docker:openwebui`:启动 Docker 化的 OpenClaw + Open WebUI,通过 Open WebUI 登录,检查 `/api/models`,然后通过 `/api/chat/completions` 运行一次真实的代理聊天。需要一个可用的 live 模型密钥(例如 `~/.profile` 中的 OpenAI),会拉取外部 Open WebUI 镜像,且不像常规单元/e2e 测试集那样预期具备 CI 稳定性。
|
||||
- `pnpm test:docker:mcp-channels`:启动一个带种子数据的 Gateway 网关容器和第二个客户端容器,后者会启动 `openclaw mcp serve`,然后通过真实的 stdio 桥接验证路由对话发现、转录读取、附件元数据、live 事件队列行为、出站发送路由,以及 Claude 风格的渠道 + 权限通知。Claude 通知断言会直接读取原始 stdio MCP 帧,因此该 smoke 测试反映的就是桥接实际发出的内容。
|
||||
- `pnpm test:e2e`:运行 Gateway 网关端到端冒烟测试(多实例 WS/HTTP/节点配对)。默认在 `vitest.e2e.config.ts` 中使用 `threads` + `isolate: false` 和自适应 worker;可通过 `OPENCLAW_E2E_WORKERS=<n>` 调整,并设置 `OPENCLAW_E2E_VERBOSE=1` 以获得详细日志。
|
||||
- `pnpm test:live`:运行提供商 live 测试(minimax/zai)。需要 API keys,并设置 `LIVE=1`(或特定提供商的 `*_LIVE_TEST=1`)以取消跳过。
|
||||
- `pnpm test:docker:openwebui`:启动 Docker 化的 OpenClaw + Open WebUI,通过 Open WebUI 登录,检查 `/api/models`,然后通过 `/api/chat/completions` 运行真实的代理聊天。需要可用的 live 模型 key(例如 `~/.profile` 中的 OpenAI),会拉取外部 Open WebUI 镜像,并不期望像常规单元/e2e 测试套件那样具有 CI 稳定性。
|
||||
- `pnpm test:docker:mcp-channels`:启动一个预置数据的 Gateway 网关容器和第二个客户端容器,后者会启动 `openclaw mcp serve`,然后通过真实的 stdio bridge 验证路由会话发现、转录读取、附件元数据、实时事件队列行为、出站发送路由,以及 Claude 风格的渠道 + 权限通知。Claude 通知断言会直接读取原始 stdio MCP frames,因此该冒烟测试能反映桥接实际发出的内容。
|
||||
|
||||
## 本地 PR 门禁
|
||||
## 本地 PR gate
|
||||
|
||||
对于本地 PR 落地/门禁检查,请运行:
|
||||
对于本地 PR 落地/gate 检查,请运行:
|
||||
|
||||
- `pnpm check`
|
||||
- `pnpm build`
|
||||
- `pnpm test`
|
||||
- `pnpm check:docs`
|
||||
|
||||
如果 `pnpm test` 在负载较高的主机上偶发失败,请先重新运行一次,再将其视为回归问题;然后使用 `pnpm test <path/to/test>` 进行定位。对于内存受限的主机,请使用:
|
||||
如果 `pnpm test` 在高负载主机上出现偶发失败,请先重跑一次,再判断是否是回归问题;然后用 `pnpm test <path/to/test>` 进行隔离。对于内存受限的主机,请使用:
|
||||
|
||||
- `OPENCLAW_VITEST_MAX_WORKERS=1 pnpm test`
|
||||
- `OPENCLAW_VITEST_FS_MODULE_CACHE_PATH=/tmp/openclaw-vitest-cache pnpm test:changed`
|
||||
|
||||
## 模型延迟基准(本地密钥)
|
||||
## 模型延迟基准测试(本地 keys)
|
||||
|
||||
脚本:[`scripts/bench-model.ts`](https://github.com/openclaw/openclaw/blob/main/scripts/bench-model.ts)
|
||||
|
||||
@ -57,14 +59,14 @@ x-i18n:
|
||||
|
||||
- `source ~/.profile && pnpm tsx scripts/bench-model.ts --runs 10`
|
||||
- 可选环境变量:`MINIMAX_API_KEY`、`MINIMAX_BASE_URL`、`MINIMAX_MODEL`、`ANTHROPIC_API_KEY`
|
||||
- 默认提示词:“Reply with a single word: ok. No punctuation or extra text.”
|
||||
- 默认提示词:“用一个单词回复:ok。不要标点,也不要额外文本。”
|
||||
|
||||
最近一次运行(2025-12-31,20 次运行):
|
||||
最近一次运行(2025-12-31,20 次):
|
||||
|
||||
- minimax 中位数 1279ms(最小 1114,最大 2431)
|
||||
- opus 中位数 2454ms(最小 1224,最大 3170)
|
||||
|
||||
## CLI 启动基准
|
||||
## CLI 启动基准测试
|
||||
|
||||
脚本:[`scripts/bench-cli-startup.ts`](https://github.com/openclaw/openclaw/blob/main/scripts/bench-cli-startup.ts)
|
||||
|
||||
@ -89,37 +91,37 @@ x-i18n:
|
||||
|
||||
- `startup`:`--version`、`--help`、`health`、`health --json`、`status --json`、`status`
|
||||
- `real`:`health`、`status`、`status --json`、`sessions`、`sessions --json`、`agents list --json`、`gateway status`、`gateway status --json`、`gateway health --json`、`config get gateway.port`
|
||||
- `all`:同时包含这两个预设
|
||||
- `all`:两个预设都包含
|
||||
|
||||
输出包括每个命令的 `sampleCount`、平均值、p50、p95、最小/最大值、退出码/信号分布,以及最大 RSS 摘要。可选的 `--cpu-prof-dir` / `--heap-prof-dir` 会为每次运行写入 V8 profile,从而让计时与 profile 采集使用相同的测试框架。
|
||||
输出包括每个命令的 `sampleCount`、avg、p50、p95、min/max、exit-code/signal 分布,以及最大 RSS 摘要。可选的 `--cpu-prof-dir` / `--heap-prof-dir` 会为每次运行写入 V8 profile,因此计时和 profile 捕获使用同一个测试 harness。
|
||||
|
||||
已保存输出约定:
|
||||
保存输出约定:
|
||||
|
||||
- `pnpm test:startup:bench:smoke` 会将目标 smoke 产物写入 `.artifacts/cli-startup-bench-smoke.json`
|
||||
- `pnpm test:startup:bench:save` 会使用 `runs=5` 和 `warmup=1` 将完整测试集产物写入 `.artifacts/cli-startup-bench-all.json`
|
||||
- `pnpm test:startup:bench:update` 会使用 `runs=5` 和 `warmup=1` 刷新已纳入版本控制的基线夹具 `test/fixtures/cli-startup-bench.json`
|
||||
- `pnpm test:startup:bench:smoke` 会将目标冒烟产物写入 `.artifacts/cli-startup-bench-smoke.json`
|
||||
- `pnpm test:startup:bench:save` 会使用 `runs=5` 和 `warmup=1` 将完整测试套件产物写入 `.artifacts/cli-startup-bench-all.json`
|
||||
- `pnpm test:startup:bench:update` 会使用 `runs=5` 和 `warmup=1` 刷新已提交的基线 fixture:`test/fixtures/cli-startup-bench.json`
|
||||
|
||||
已纳入版本控制的夹具:
|
||||
已提交的 fixture:
|
||||
|
||||
- `test/fixtures/cli-startup-bench.json`
|
||||
- 使用 `pnpm test:startup:bench:update` 刷新
|
||||
- 使用 `pnpm test:startup:bench:check` 将当前结果与该夹具进行比较
|
||||
- 使用 `pnpm test:startup:bench:check` 将当前结果与该 fixture 进行比较
|
||||
|
||||
## 新手引导 E2E(Docker)
|
||||
|
||||
Docker 是可选的;只有在进行容器化新手引导 smoke 测试时才需要。
|
||||
Docker 是可选的;只有在进行容器化新手引导冒烟测试时才需要它。
|
||||
|
||||
在干净的 Linux 容器中的完整冷启动流程:
|
||||
在干净的 Linux 容器中执行完整冷启动流程:
|
||||
|
||||
```bash
|
||||
scripts/e2e/onboard-docker.sh
|
||||
```
|
||||
|
||||
该脚本通过伪 TTY 驱动交互式向导,验证配置/工作区/会话文件,然后启动 Gateway 网关并运行 `openclaw health`。
|
||||
此脚本会通过伪终端驱动交互式向导,验证 config/workspace/session 文件,然后启动 Gateway 网关并运行 `openclaw health`。
|
||||
|
||||
## 二维码导入 smoke 测试(Docker)
|
||||
## 二维码导入冒烟测试(Docker)
|
||||
|
||||
确保 `qrcode-terminal` 可在受支持的 Docker Node 运行时中加载(默认 Node 24,兼容 Node 22):
|
||||
确保 `qrcode-terminal` 能在受支持的 Docker Node 运行时下加载(默认 Node 24,兼容 Node 22):
|
||||
|
||||
```bash
|
||||
pnpm test:docker:qr
|
||||
|
||||
@ -1,121 +1,109 @@
|
||||
---
|
||||
read_when:
|
||||
- 解释 token 使用量、成本或上下文窗口时
|
||||
- 调试上下文增长或压缩行为时
|
||||
summary: OpenClaw 如何构建提示词上下文,以及如何报告 token 使用量和成本
|
||||
title: Token 使用量和成本
|
||||
- 解释 token 用量、成本或上下文窗口
|
||||
- 调试上下文增长或压缩行为
|
||||
summary: OpenClaw 如何构建提示词上下文并报告 token 用量与成本
|
||||
title: Token 用量与成本
|
||||
x-i18n:
|
||||
generated_at: "2026-04-05T10:09:10Z"
|
||||
generated_at: "2026-04-06T15:31:22Z"
|
||||
model: gpt-5.4
|
||||
provider: openai
|
||||
source_hash: 14e7a0ac0311298cf1484d663799a3f5a9687dd5afc9702233e983aba1979f1d
|
||||
source_hash: 0683693d6c6fcde7d5fba236064ba97dd4b317ae6bea3069db969fcd178119d9
|
||||
source_path: reference/token-use.md
|
||||
workflow: 15
|
||||
---
|
||||
|
||||
# Token 使用量和成本
|
||||
# Token 用量与成本
|
||||
|
||||
OpenClaw 跟踪的是 **token**,而不是字符。token 因模型而异,但大多数
|
||||
OpenAI 风格模型对英文文本的平均值约为每个 token 4 个字符。
|
||||
OpenClaw 跟踪的是 **token**,而不是字符。Token 是模型特定的,但大多数 OpenAI 风格模型对英文文本的平均值约为每个 token 4 个字符。
|
||||
|
||||
## 系统提示词是如何构建的
|
||||
|
||||
OpenClaw 会在每次运行时组装自己的系统提示词。其中包括:
|
||||
OpenClaw 会在每次运行时组装自己的系统提示词。它包括:
|
||||
|
||||
- 工具列表 + 简短说明
|
||||
- 工具列表 + 简短描述
|
||||
- Skills 列表(仅元数据;说明会按需通过 `read` 加载)
|
||||
- 自更新说明
|
||||
- 工作区 + bootstrap 文件(`AGENTS.md`、`SOUL.md`、`TOOLS.md`、`IDENTITY.md`、`USER.md`、`HEARTBEAT.md`、新建时的 `BOOTSTRAP.md`,以及存在时的 `MEMORY.md` 或作为小写回退的 `memory.md`)。大文件会被 `agents.defaults.bootstrapMaxChars` 截断(默认值:20000),而 bootstrap 注入总量受 `agents.defaults.bootstrapTotalMaxChars` 限制(默认值:150000)。`memory/*.md` 文件通过 memory 工具按需加载,不会自动注入。
|
||||
- 自我更新说明
|
||||
- 工作区 + bootstrap 文件(`AGENTS.md`、`SOUL.md`、`TOOLS.md`、`IDENTITY.md`、`USER.md`、`HEARTBEAT.md`、新建时的 `BOOTSTRAP.md`,以及在存在时的 `MEMORY.md` 或作为小写回退的 `memory.md`)。大文件会被 `agents.defaults.bootstrapMaxChars` 截断(默认:20000),bootstrap 注入总量受 `agents.defaults.bootstrapTotalMaxChars` 限制(默认:150000)。`memory/*.md` 文件通过 memory 工具按需加载,不会自动注入。
|
||||
- 时间(UTC + 用户时区)
|
||||
- 回复标签 + heartbeat 行为
|
||||
- 运行时元数据(主机/操作系统/模型/thinking)
|
||||
- 运行时元数据(主机/OS/模型/thinking)
|
||||
|
||||
完整拆解请参见 [System Prompt](/zh-CN/concepts/system-prompt)。
|
||||
完整拆分请参见 [System Prompt](/zh-CN/concepts/system-prompt)。
|
||||
|
||||
## 什么会计入上下文窗口
|
||||
|
||||
模型接收到的所有内容都会计入上下文限制:
|
||||
|
||||
- 系统提示词(上面列出的所有部分)
|
||||
- 对话历史(用户 + 助手消息)
|
||||
- 对话历史(用户 + assistant 消息)
|
||||
- 工具调用和工具结果
|
||||
- 附件/transcript(图像、音频、文件)
|
||||
- 压缩摘要和剪枝产物
|
||||
- 提供商包装层或安全标头(不可见,但仍会计入)
|
||||
- 附件/转录内容(图片、音频、文件)
|
||||
- 压缩摘要和裁剪产物
|
||||
- provider 包装器或安全标头(不可见,但仍会计入)
|
||||
|
||||
对于图像,OpenClaw 会在调用提供商之前下采样 transcript/工具图像载荷。
|
||||
请使用 `agents.defaults.imageMaxDimensionPx`(默认值:`1200`)进行调节:
|
||||
对于图片,OpenClaw 会在调用 provider 之前对转录/工具图片负载进行缩放。使用 `agents.defaults.imageMaxDimensionPx`(默认:`1200`)来调整:
|
||||
|
||||
- 较低的值通常会减少视觉 token 用量和载荷大小。
|
||||
- 较高的值会保留更多视觉细节,适用于 OCR/UI 密集型截图。
|
||||
- 较低的值通常会减少视觉 token 用量和负载大小。
|
||||
- 较高的值会为 OCR/UI 密集型截图保留更多视觉细节。
|
||||
|
||||
如需查看实用拆解(按每个注入文件、工具、Skills 和系统提示词大小),请使用 `/context list` 或 `/context detail`。参见 [Context](/zh-CN/concepts/context)。
|
||||
如需查看实用拆分(按注入文件、工具、Skills 和系统提示词大小),请使用 `/context list` 或 `/context detail`。参见 [Context](/zh-CN/concepts/context)。
|
||||
|
||||
## 如何查看当前 token 使用量
|
||||
## 如何查看当前 token 用量
|
||||
|
||||
在聊天中使用以下命令:
|
||||
在聊天中使用这些命令:
|
||||
|
||||
- `/status` → **富含 emoji 的状态卡片**,显示会话模型、上下文使用量、
|
||||
上次响应的输入/输出 token,以及**估算成本**(仅 API 密钥)。
|
||||
- `/usage off|tokens|full` → 在每条回复后附加一个**按响应统计的使用量页脚**。
|
||||
- `/status` → 显示**富含 emoji 的状态卡片**,包含会话模型、上下文用量、上次响应的输入/输出 token,以及**估算成本**(仅 API 密钥)。
|
||||
- `/usage off|tokens|full` → 在每条回复后附加**按响应统计的用量页脚**。
|
||||
- 按会话持久化(存储为 `responseUsage`)。
|
||||
- OAuth 认证**会隐藏成本**(仅显示 token)。
|
||||
- `/usage cost` → 从 OpenClaw 会话日志中显示本地成本汇总。
|
||||
- OAuth 身份验证**隐藏成本**(仅显示 token)。
|
||||
- `/usage cost` → 显示基于 OpenClaw 会话日志的本地成本摘要。
|
||||
|
||||
其他界面:
|
||||
|
||||
- **TUI/Web TUI:** 支持 `/status` + `/usage`。
|
||||
- **CLI:** `openclaw status --usage` 和 `openclaw channels list` 会显示
|
||||
规范化后的提供商配额窗口(`X% left`,而不是按响应成本)。
|
||||
当前支持使用量窗口的提供商有:Anthropic、GitHub Copilot、Gemini CLI、
|
||||
- **CLI:** `openclaw status --usage` 和 `openclaw channels list` 显示
|
||||
标准化后的 provider 配额窗口(`X% left`,而不是按响应成本)。
|
||||
当前支持用量窗口的 provider:Anthropic、GitHub Copilot、Gemini CLI、
|
||||
OpenAI Codex、MiniMax、Xiaomi 和 z.ai。
|
||||
|
||||
使用量界面在显示前会规范化常见的提供商原生字段别名。
|
||||
用量界面会在显示前标准化常见的 provider 原生字段别名。
|
||||
对于 OpenAI 系列 Responses 流量,这包括 `input_tokens` /
|
||||
`output_tokens` 以及 `prompt_tokens` / `completion_tokens`,因此传输层特定的
|
||||
字段名不会改变 `/status`、`/usage` 或会话摘要。
|
||||
Gemini CLI JSON 使用量也会被规范化:回复文本来自 `response`,而
|
||||
`stats.cached` 会映射到 `cacheRead`;当 CLI 省略显式的 `stats.input`
|
||||
字段时,会使用 `stats.input_tokens - stats.cached`。
|
||||
对于原生 OpenAI 系列 Responses 流量,WebSocket/SSE 的使用量别名也会以相同方式规范化,并且当
|
||||
`total_tokens` 缺失或为 `0` 时,总量会回退到规范化后的输入 + 输出。
|
||||
当当前会话快照较为稀疏时,`/status` 和 `session_status` 还可以
|
||||
从最近的 transcript 使用日志中恢复 token/cache 计数器和当前运行时模型标签。现有的非零实时值仍优先于 transcript 回退值,而当存储总量缺失或更小时,较大的面向提示词的 transcript
|
||||
总量可以胜出。
|
||||
提供商配额窗口的使用量认证在可用时来自提供商专用 hook;否则 OpenClaw 会回退到从认证配置文件、环境或配置中匹配 OAuth/API 密钥凭据。
|
||||
`output_tokens` 和 `prompt_tokens` / `completion_tokens`,因此特定传输的字段名不会改变 `/status`、`/usage` 或会话摘要。
|
||||
Gemini CLI JSON 用量也会被标准化:回复文本来自 `response`,并且 `stats.cached` 会映射为 `cacheRead`,当 CLI 省略显式 `stats.input` 字段时,会使用 `stats.input_tokens - stats.cached`。
|
||||
对于原生 OpenAI 系列 Responses 流量,WebSocket/SSE 用量别名也会以相同方式标准化,当 `total_tokens` 缺失或为 `0` 时,总量会回退到标准化后的输入 + 输出。
|
||||
当当前会话快照信息较少时,`/status` 和 `session_status` 还可以从最近的转录用量日志中恢复 token/缓存计数器和活动运行时模型标签。现有的非零实时值仍然优先于转录回退值,而当存储总量缺失或更小时,较大的面向提示词的转录总量可以胜出。
|
||||
用于 provider 配额窗口的用量身份验证优先来自 provider 特定 hooks;否则 OpenClaw 会回退为使用来自 auth profile、环境变量或配置中匹配的 OAuth/API 密钥凭证。
|
||||
|
||||
## 成本估算(显示时)
|
||||
|
||||
成本根据你的模型定价配置进行估算:
|
||||
成本是根据你的模型定价配置估算的:
|
||||
|
||||
```
|
||||
models.providers.<provider>.models[].cost
|
||||
```
|
||||
|
||||
这些值表示 `input`、`output`、`cacheRead` 和
|
||||
`cacheWrite` 的**每 100 万 token 美元价格**。如果缺少定价信息,OpenClaw 只显示 token。OAuth token
|
||||
永远不会显示美元成本。
|
||||
`cacheWrite` 的**每 100 万 token 的美元价格**。如果缺少定价,OpenClaw 只显示 token。OAuth token 永远不会显示美元成本。
|
||||
|
||||
## 缓存 TTL 和剪枝影响
|
||||
## 缓存 TTL 和裁剪的影响
|
||||
|
||||
提供商提示词缓存仅在缓存 TTL 窗口内生效。OpenClaw 可选运行**cache-ttl 剪枝**:当缓存 TTL 过期后,它会剪枝会话,然后重置缓存窗口,这样后续请求就可以复用刚刚重新缓存的上下文,而不必对完整历史重新缓存。这样在会话空闲超过 TTL 后,可以保持较低的缓存写入成本。
|
||||
Provider 提示词缓存只会在缓存 TTL 窗口内生效。OpenClaw 可以选择运行**缓存 TTL 裁剪**:一旦缓存 TTL 过期,它就会裁剪会话,然后重置缓存窗口,这样后续请求就能重用刚刚重新缓存的上下文,而不是重新缓存完整历史。这可以在会话空闲超过 TTL 时降低缓存写入成本。
|
||||
|
||||
请在 [Gateway 网关配置](/zh-CN/gateway/configuration) 中进行配置,并在
|
||||
[Session pruning](/zh-CN/concepts/session-pruning) 中查看行为细节。
|
||||
[会话裁剪](/zh-CN/concepts/session-pruning) 中查看行为细节。
|
||||
|
||||
Heartbeat 可以在空闲间隔之间保持缓存**温热**。如果你的模型缓存 TTL
|
||||
是 `1h`,将 heartbeat 间隔设置为略低于该值(例如 `55m`)可以避免重新缓存完整提示词,从而降低缓存写入成本。
|
||||
Heartbeat 可以在空闲间隔期间保持缓存**预热**。如果你的模型缓存 TTL
|
||||
是 `1h`,将 heartbeat 间隔设置为略低于该值(例如 `55m`)可以避免重新缓存完整提示词,从而减少缓存写入成本。
|
||||
|
||||
在多智能体设置中,你可以保留一个共享模型配置,并通过
|
||||
`agents.list[].params.cacheRetention` 按智能体调节缓存行为。
|
||||
在多智能体设置中,你可以保留一个共享模型配置,并通过 `agents.list[].params.cacheRetention` 为每个智能体调整缓存行为。
|
||||
|
||||
如需查看逐项配置指南,请参见 [Prompt Caching](/reference/prompt-caching)。
|
||||
如需完整的逐项参数指南,请参见 [Prompt Caching](/zh-CN/reference/prompt-caching)。
|
||||
|
||||
对于 Anthropic API 定价,缓存读取显著便宜于输入
|
||||
token,而缓存写入则按更高倍数计费。最新费率和 TTL 倍率请参见 Anthropic 的提示词缓存定价:
|
||||
对于 Anthropic API 定价,缓存读取比输入 token 便宜得多,而缓存写入则按更高倍数计费。最新费率和 TTL 倍数请参见 Anthropic 的提示词缓存定价:
|
||||
[https://docs.anthropic.com/docs/build-with-claude/prompt-caching](https://docs.anthropic.com/docs/build-with-claude/prompt-caching)
|
||||
|
||||
### 示例:使用 heartbeat 保持 1 小时缓存温热
|
||||
### 示例:使用 heartbeat 保持 1 小时缓存预热
|
||||
|
||||
```yaml
|
||||
agents:
|
||||
@ -130,7 +118,7 @@ agents:
|
||||
every: "55m"
|
||||
```
|
||||
|
||||
### 示例:按智能体使用不同缓存策略的混合流量
|
||||
### 示例:带有按智能体缓存策略的混合流量
|
||||
|
||||
```yaml
|
||||
agents:
|
||||
@ -145,19 +133,18 @@ agents:
|
||||
- id: "research"
|
||||
default: true
|
||||
heartbeat:
|
||||
every: "55m" # 为深度会话保持长期缓存温热
|
||||
every: "55m" # 为深度会话保持长缓存预热
|
||||
- id: "alerts"
|
||||
params:
|
||||
cacheRetention: "none" # 避免为突发通知写入缓存
|
||||
```
|
||||
|
||||
`agents.list[].params` 会合并到所选模型的 `params` 之上,因此你可以
|
||||
只覆盖 `cacheRetention`,并保持其他模型默认值不变。
|
||||
`agents.list[].params` 会在所选模型的 `params` 之上合并,因此你可以只覆盖 `cacheRetention`,而让其他模型默认值保持不变。
|
||||
|
||||
### 示例:启用 Anthropic 1M 上下文 beta 标头
|
||||
|
||||
Anthropic 的 1M 上下文窗口当前受 beta 限制。在受支持的 Opus
|
||||
或 Sonnet 模型上启用 `context1m` 后,OpenClaw 可以注入所需的
|
||||
Anthropic 的 1M 上下文窗口当前仍受 beta 限制。启用受支持的 Opus
|
||||
或 Sonnet 模型上的 `context1m` 后,OpenClaw 可以注入所需的
|
||||
`anthropic-beta` 值。
|
||||
|
||||
```yaml
|
||||
@ -171,23 +158,18 @@ agents:
|
||||
|
||||
这会映射到 Anthropic 的 `context-1m-2025-08-07` beta 标头。
|
||||
|
||||
仅当该模型条目上设置了 `context1m: true` 时,这一行为才会生效。
|
||||
这仅在该模型条目上设置了 `context1m: true` 时生效。
|
||||
|
||||
要求:该凭据必须有资格使用长上下文(API 密钥
|
||||
计费,或启用了 Extra Usage 的 OpenClaw Claude 登录路径)。否则,
|
||||
Anthropic 会响应
|
||||
`HTTP 429: rate_limit_error: Extra usage is required for long context requests`。
|
||||
要求:该凭证必须具备长上下文使用资格。否则,Anthropic 会对该请求返回 provider 侧速率限制错误。
|
||||
|
||||
如果你使用 OAuth/订阅 token(`sk-ant-oat-*`)对 Anthropic 进行认证,
|
||||
OpenClaw 会跳过 `context-1m-*` beta 标头,因为 Anthropic 当前
|
||||
会以 HTTP 401 拒绝这种组合。
|
||||
如果你使用 OAuth/订阅 token(`sk-ant-oat-*`)对 Anthropic 进行身份验证,OpenClaw 会跳过 `context-1m-*` beta 标头,因为 Anthropic 当前会以 HTTP 401 拒绝这种组合。
|
||||
|
||||
## 减少 token 压力的建议
|
||||
## 减少 token 压力的技巧
|
||||
|
||||
- 使用 `/compact` 总结长会话。
|
||||
- 在你的工作流中裁剪大型工具输出。
|
||||
- 对于截图较多的会话,降低 `agents.defaults.imageMaxDimensionPx`。
|
||||
- 使用 `/compact` 总结较长的会话。
|
||||
- 在你的工作流中裁剪较大的工具输出。
|
||||
- 对截图密集型会话降低 `agents.defaults.imageMaxDimensionPx`。
|
||||
- 保持 skill 描述简短(skill 列表会被注入到提示词中)。
|
||||
- 对于冗长、探索性的工作,优先使用较小模型。
|
||||
- 对冗长、探索性工作优先使用更小的模型。
|
||||
|
||||
确切的 skill 列表开销公式请参见 [Skills](/zh-CN/tools/skills)。
|
||||
精确的 skill 列表开销公式请参见 [Skills](/zh-CN/tools/skills)。
|
||||
|
||||
@ -4,13 +4,13 @@ read_when:
|
||||
- 使用非交互模式自动化新手引导
|
||||
- 调试新手引导行为
|
||||
sidebarTitle: Onboarding Reference
|
||||
summary: CLI 新手引导完整参考:每一步、每个标志与每个配置字段
|
||||
summary: CLI 新手引导的完整参考:每一步、每个标志和每个配置字段
|
||||
title: 新手引导参考
|
||||
x-i18n:
|
||||
generated_at: "2026-04-05T17:49:36Z"
|
||||
generated_at: "2026-04-06T15:31:48Z"
|
||||
model: gpt-5.4
|
||||
provider: openai
|
||||
source_hash: e02a4da4a39ba335199095723f5d3b423671eb12efc2d9e4f9e48c1e8ee18419
|
||||
source_hash: a142b9ec4323fabb9982d05b64375d2b4a4007dffc910acbee3a38ff871a7236
|
||||
source_path: reference/wizard.md
|
||||
workflow: 15
|
||||
---
|
||||
@ -20,136 +20,136 @@ x-i18n:
|
||||
这是 `openclaw onboard` 的完整参考。
|
||||
如需高层概览,请参见 [新手引导(CLI)](/zh-CN/start/wizard)。
|
||||
|
||||
## 流程细节(本地模式)
|
||||
## 流程详情(本地模式)
|
||||
|
||||
<Steps>
|
||||
<Step title="现有配置检测">
|
||||
- 如果存在 `~/.openclaw/openclaw.json`,请选择 **保留 / 修改 / 重置**。
|
||||
- 如果 `~/.openclaw/openclaw.json` 存在,可选择 **保留 / 修改 / 重置**。
|
||||
- 重新运行新手引导**不会**清除任何内容,除非你明确选择 **重置**
|
||||
(或传入 `--reset`)。
|
||||
- CLI `--reset` 默认作用于 `config+creds+sessions`;使用 `--reset-scope full`
|
||||
可额外移除工作区。
|
||||
- 如果配置无效或包含旧版键,向导会停止并要求
|
||||
你先运行 `openclaw doctor`,然后才能继续。
|
||||
- CLI `--reset` 默认范围是 `config+creds+sessions`;使用 `--reset-scope full`
|
||||
还会删除工作区。
|
||||
- 如果配置无效或包含旧版键名,向导会停止并要求
|
||||
你先运行 `openclaw doctor` 再继续。
|
||||
- 重置使用 `trash`(绝不使用 `rm`),并提供以下范围:
|
||||
- 仅配置
|
||||
- 配置 + 凭证 + 会话
|
||||
- 完全重置(也会移除工作区)
|
||||
- 完全重置(也会删除工作区)
|
||||
</Step>
|
||||
<Step title="模型 / 认证">
|
||||
- **Anthropic API 密钥**:如果存在则使用 `ANTHROPIC_API_KEY`,否则提示输入密钥,然后保存供守护进程使用。
|
||||
- **Anthropic API 密钥**:是新手引导 / 配置中推荐的 Anthropic 助手选择。
|
||||
- **Anthropic setup-token(旧版 / 手动)**:已重新在新手引导 / 配置中提供,但 Anthropic 已通知 OpenClaw 用户,OpenClaw 的 Claude 登录路径被视为第三方封装工具用法,并且 Claude 账户需要启用 **Extra Usage**。
|
||||
- **OpenAI Code(Codex)订阅(Codex CLI)**:如果存在 `~/.codex/auth.json`,新手引导可以复用它。被复用的 Codex CLI 凭证仍由 Codex CLI 管理;过期时,OpenClaw 会优先重新读取该来源,并且当提供商可以刷新它时,会将刷新后的凭证写回 Codex 存储,而不是自行接管。
|
||||
<Step title="模型/凭证">
|
||||
- **Anthropic API 密钥**:如果存在则使用 `ANTHROPIC_API_KEY`,否则提示输入密钥,然后保存以供守护进程使用。
|
||||
- **Anthropic API 密钥**:在新手引导/配置中是 Anthropic 助手的首选选项。
|
||||
- **Anthropic setup-token**:在新手引导/配置中仍然可用,不过 OpenClaw 现在在可用时更倾向于复用 Claude CLI。
|
||||
- **OpenAI Code(Codex)订阅(Codex CLI)**:如果 `~/.codex/auth.json` 存在,新手引导可以复用它。被复用的 Codex CLI 凭证仍由 Codex CLI 管理;过期时,OpenClaw 会先重新读取该来源,并在提供商能够刷新时,将刷新后的凭证写回 Codex 存储,而不是自行接管。
|
||||
- **OpenAI Code(Codex)订阅(OAuth)**:浏览器流程;粘贴 `code#state`。
|
||||
- 当模型未设置或为 `openai/*` 时,将 `agents.defaults.model` 设置为 `openai-codex/gpt-5.4`。
|
||||
- **OpenAI API 密钥**:如果存在则使用 `OPENAI_API_KEY`,否则提示输入密钥,然后将其存储到认证配置文件中。
|
||||
- **OpenAI API 密钥**:如果存在则使用 `OPENAI_API_KEY`,否则提示输入密钥,然后将其存储到凭证配置文件中。
|
||||
- 当模型未设置、为 `openai/*` 或 `openai-codex/*` 时,将 `agents.defaults.model` 设置为 `openai/gpt-5.4`。
|
||||
- **xAI(Grok)API 密钥**:提示输入 `XAI_API_KEY`,并将 xAI 配置为模型提供商。
|
||||
- **xAI(Grok)API 密钥**:提示输入 `XAI_API_KEY` 并将 xAI 配置为模型提供商。
|
||||
- **OpenCode**:提示输入 `OPENCODE_API_KEY`(或 `OPENCODE_ZEN_API_KEY`,可在 https://opencode.ai/auth 获取),并让你选择 Zen 或 Go 目录。
|
||||
- **Ollama**:提示输入 Ollama 基础 URL,提供 **Cloud + Local** 或 **Local** 模式,发现可用模型,并在需要时自动拉取所选本地模型。
|
||||
- **Ollama**:提示输入 Ollama base URL,提供 **Cloud + Local** 或 **Local** 模式,发现可用模型,并在需要时自动拉取所选本地模型。
|
||||
- 更多细节:[Ollama](/zh-CN/providers/ollama)
|
||||
- **API 密钥**:为你存储该密钥。
|
||||
- **Vercel AI Gateway(多模型代理)**:提示输入 `AI_GATEWAY_API_KEY`。
|
||||
- 更多细节:[Vercel AI Gateway](/zh-CN/providers/vercel-ai-gateway)
|
||||
- **Cloudflare AI Gateway**:提示输入 Account ID、Gateway ID 和 `CLOUDFLARE_AI_GATEWAY_API_KEY`。
|
||||
- 更多细节:[Cloudflare AI Gateway](/zh-CN/providers/cloudflare-ai-gateway)
|
||||
- **MiniMax**:配置会自动写入;托管默认值为 `MiniMax-M2.7`。
|
||||
- **MiniMax**:会自动写入配置;托管默认模型是 `MiniMax-M2.7`。
|
||||
API 密钥设置使用 `minimax/...`,而 OAuth 设置使用
|
||||
`minimax-portal/...`。
|
||||
- 更多细节:[MiniMax](/zh-CN/providers/minimax)
|
||||
- **StepFun**:会为中国区或全球端点的 StepFun 标准版或 Step Plan 自动写入配置。
|
||||
- **StepFun**:会为中国或全球端点上的 StepFun standard 或 Step Plan 自动写入配置。
|
||||
- 标准版当前包含 `step-3.5-flash`,Step Plan 还包含 `step-3.5-flash-2603`。
|
||||
- 更多细节:[StepFun](/zh-CN/providers/stepfun)
|
||||
- **Synthetic(兼容 Anthropic)**:提示输入 `SYNTHETIC_API_KEY`。
|
||||
- **Synthetic(Anthropic 兼容)**:提示输入 `SYNTHETIC_API_KEY`。
|
||||
- 更多细节:[Synthetic](/zh-CN/providers/synthetic)
|
||||
- **Moonshot(Kimi K2)**:配置会自动写入。
|
||||
- **Kimi Coding**:配置会自动写入。
|
||||
- **Moonshot(Kimi K2)**:会自动写入配置。
|
||||
- **Kimi Coding**:会自动写入配置。
|
||||
- 更多细节:[Moonshot AI(Kimi + Kimi Coding)](/zh-CN/providers/moonshot)
|
||||
- **跳过**:暂不配置认证。
|
||||
- 从检测到的选项中选择一个默认模型(或手动输入 provider/model)。为了获得最佳质量并降低提示词注入风险,请选择你提供商栈中可用的最新一代最强模型。
|
||||
- 新手引导会执行模型检查,并在已配置模型未知或缺少认证时发出警告。
|
||||
- **跳过**:暂不配置凭证。
|
||||
- 从检测到的选项中选择一个默认模型(或手动输入 provider/model)。为了获得最佳质量并降低提示注入风险,请选择你提供商栈中可用的最强最新一代模型。
|
||||
- 新手引导会执行模型检查,并在配置的模型未知或缺少凭证时发出警告。
|
||||
- API 密钥存储模式默认使用明文 auth-profile 值。使用 `--secret-input-mode ref` 可改为存储基于环境变量的引用(例如 `keyRef: { source: "env", provider: "default", id: "OPENAI_API_KEY" }`)。
|
||||
- 认证配置文件位于 `~/.openclaw/agents/<agentId>/agent/auth-profiles.json`(API 密钥 + OAuth)。`~/.openclaw/credentials/oauth.json` 仅用于旧版导入。
|
||||
- 凭证配置文件位于 `~/.openclaw/agents/<agentId>/agent/auth-profiles.json`(API 密钥 + OAuth)。`~/.openclaw/credentials/oauth.json` 仅用于导入旧版数据。
|
||||
- 更多细节:[/concepts/oauth](/zh-CN/concepts/oauth)
|
||||
<Note>
|
||||
无头 / 服务器提示:请在有浏览器的机器上完成 OAuth,然后复制
|
||||
无头/服务器提示:可先在有浏览器的机器上完成 OAuth,然后复制
|
||||
该智能体的 `auth-profiles.json`(例如
|
||||
`~/.openclaw/agents/<agentId>/agent/auth-profiles.json`,或对应的
|
||||
`$OPENCLAW_STATE_DIR/...` 路径)到 Gateway 网关主机上。`credentials/oauth.json`
|
||||
仅是旧版导入来源。
|
||||
只是旧版导入来源。
|
||||
</Note>
|
||||
</Step>
|
||||
<Step title="工作区">
|
||||
- 默认值为 `~/.openclaw/workspace`(可配置)。
|
||||
- 会为智能体 bootstrap 仪式预置所需的工作区文件。
|
||||
- 完整工作区布局与备份指南:[智能体工作区](/zh-CN/concepts/agent-workspace)
|
||||
- 默认是 `~/.openclaw/workspace`(可配置)。
|
||||
- 会初始化智能体 bootstrap ritual 所需的工作区文件。
|
||||
- 完整工作区布局和备份指南:[智能体工作区](/zh-CN/concepts/agent-workspace)
|
||||
</Step>
|
||||
<Step title="Gateway 网关">
|
||||
- 端口、绑定、认证模式、Tailscale 暴露。
|
||||
- 认证建议:即使在 loopback 模式下也保留 **Token**,这样本地 WS 客户端也必须认证。
|
||||
- 端口、绑定、凭证模式、Tailscale 暴露。
|
||||
- 凭证建议:即使是 loopback,也请保留 **Token**,这样本地 WS 客户端仍必须进行身份验证。
|
||||
- 在 token 模式下,交互式设置提供:
|
||||
- **生成 / 存储明文 token**(默认)
|
||||
- **生成/存储明文 token**(默认)
|
||||
- **使用 SecretRef**(可选启用)
|
||||
- 快速开始会在新手引导探测 / 仪表板 bootstrap 期间,复用 `env`、`file` 和 `exec` 提供商中现有的 `gateway.auth.token` SecretRef。
|
||||
- 如果该 SecretRef 已配置但无法解析,新手引导会尽早失败并给出明确修复信息,而不是静默降级运行时认证。
|
||||
- 在 password 模式下,交互式设置也支持明文或 SecretRef 存储。
|
||||
- 非交互式 token SecretRef 路径:`--gateway-token-ref-env <ENV_VAR>`。
|
||||
- 快速开始会在新手引导探测/仪表板 bootstrap 过程中复用现有的 `gateway.auth.token` SecretRef,支持 `env`、`file` 和 `exec` 提供商。
|
||||
- 如果已配置该 SecretRef 但无法解析,新手引导会尽早失败并给出清晰的修复信息,而不是静默降级运行时凭证。
|
||||
- 在密码模式下,交互式设置也支持明文或 SecretRef 存储。
|
||||
- 非交互 token SecretRef 路径:`--gateway-token-ref-env <ENV_VAR>`。
|
||||
- 要求新手引导进程环境中存在非空环境变量。
|
||||
- 不能与 `--gateway-token` 同时使用。
|
||||
- 仅当你完全信任每个本地进程时才禁用认证。
|
||||
- 非 loopback 绑定仍然需要认证。
|
||||
- 不能与 `--gateway-token` 一起使用。
|
||||
- 仅当你完全信任所有本地进程时才禁用凭证。
|
||||
- 非 loopback 绑定仍然需要凭证。
|
||||
</Step>
|
||||
<Step title="渠道">
|
||||
- [WhatsApp](/zh-CN/channels/whatsapp):可选 QR 登录。
|
||||
- [Telegram](/zh-CN/channels/telegram):机器人 token。
|
||||
- [Discord](/zh-CN/channels/discord):机器人 token。
|
||||
- [Google Chat](/zh-CN/channels/googlechat):服务账户 JSON + webhook audience。
|
||||
- [Mattermost](/zh-CN/channels/mattermost)(插件):机器人 token + 基础 URL。
|
||||
- [Signal](/zh-CN/channels/signal):可选安装 `signal-cli` + 账户配置。
|
||||
- [BlueBubbles](/zh-CN/channels/bluebubbles):**iMessage 的推荐方案**;服务器 URL + 密码 + webhook。
|
||||
- [Telegram](/zh-CN/channels/telegram):机器人令牌。
|
||||
- [Discord](/zh-CN/channels/discord):机器人令牌。
|
||||
- [Google Chat](/zh-CN/channels/googlechat):服务账号 JSON + webhook audience。
|
||||
- [Mattermost](/zh-CN/channels/mattermost)(插件):机器人令牌 + base URL。
|
||||
- [Signal](/zh-CN/channels/signal):可选 `signal-cli` 安装 + 账户配置。
|
||||
- [BlueBubbles](/zh-CN/channels/bluebubbles):**推荐用于 iMessage**;服务器 URL + 密码 + webhook。
|
||||
- [iMessage](/zh-CN/channels/imessage):旧版 `imsg` CLI 路径 + DB 访问。
|
||||
- 私信安全:默认使用配对。首次私信会发送验证码;通过 `openclaw pairing approve <channel> <code>` 批准,或使用允许列表。
|
||||
- 私信安全:默认启用配对。首次私信会发送一个代码;通过 `openclaw pairing approve <channel> <code>` 批准,或使用允许列表。
|
||||
</Step>
|
||||
<Step title="Web 搜索">
|
||||
- 选择受支持的提供商,例如 Brave、DuckDuckGo、Exa、Firecrawl、Gemini、Grok、Kimi、MiniMax Search、Ollama Web 搜索、Perplexity、SearXNG 或 Tavily(或跳过)。
|
||||
- 基于 API 的提供商可使用环境变量或现有配置进行快速设置;无密钥提供商则使用其提供商特定的前置条件。
|
||||
- 选择一个受支持的提供商,例如 Brave、DuckDuckGo、Exa、Firecrawl、Gemini、Grok、Kimi、MiniMax Search、Ollama Web 搜索、Perplexity、SearXNG 或 Tavily(也可以跳过)。
|
||||
- 基于 API 的提供商可以使用环境变量或现有配置快速设置;无需密钥的提供商则使用其各自的前置条件。
|
||||
- 使用 `--skip-search` 跳过。
|
||||
- 稍后配置:`openclaw configure --section web`。
|
||||
</Step>
|
||||
<Step title="安装守护进程">
|
||||
<Step title="守护进程安装">
|
||||
- macOS:LaunchAgent
|
||||
- 需要已登录的用户会话;对于无头环境,请使用自定义 LaunchDaemon(未内置提供)。
|
||||
- 需要已登录的用户会话;对于无头场景,请使用自定义 LaunchDaemon(未内置)。
|
||||
- Linux(以及通过 WSL2 的 Windows):systemd 用户单元
|
||||
- 新手引导会尝试启用 `loginctl enable-linger <user>`,以便 Gateway 网关在登出后继续运行。
|
||||
- 可能会提示输入 sudo(写入 `/var/lib/systemd/linger`);它会先尝试不使用 sudo。
|
||||
- **运行时选择:** Node(推荐;WhatsApp / Telegram 必需)。**不推荐** Bun。
|
||||
- 如果 token 认证需要 token 且 `gateway.auth.token` 由 SecretRef 管理,守护进程安装会验证它,但不会将解析后的明文 token 值持久化到 supervisor 服务环境元数据中。
|
||||
- 如果 token 认证需要 token 且已配置的 token SecretRef 未解析,守护进程安装会被阻止,并给出可操作的指导。
|
||||
- 如果同时配置了 `gateway.auth.token` 和 `gateway.auth.password`,而 `gateway.auth.mode` 未设置,则在显式设置模式之前会阻止守护进程安装。
|
||||
- 新手引导会尝试通过 `loginctl enable-linger <user>` 启用 lingering,这样 Gateway 网关在登出后仍能保持运行。
|
||||
- 可能会提示 sudo(会写入 `/var/lib/systemd/linger`);会先尝试不使用 sudo。
|
||||
- **运行时选择:** Node(推荐;WhatsApp/Telegram 必需)。**不推荐** Bun。
|
||||
- 如果 token 凭证需要 token 且 `gateway.auth.token` 由 SecretRef 管理,守护进程安装会验证它,但不会把解析后的明文 token 值持久化到 supervisor 服务环境元数据中。
|
||||
- 如果 token 凭证需要 token 且配置的 token SecretRef 未解析,守护进程安装会被阻止,并给出可操作的指导。
|
||||
- 如果同时配置了 `gateway.auth.token` 和 `gateway.auth.password`,而 `gateway.auth.mode` 未设置,则会阻止守护进程安装,直到明确设置 mode。
|
||||
</Step>
|
||||
<Step title="健康检查">
|
||||
- 启动 Gateway 网关(如有需要)并运行 `openclaw health`。
|
||||
- 提示:`openclaw status --deep` 会将在线 Gateway 网关健康探测添加到状态输出中,包括受支持时的渠道探测(需要可访问的 Gateway 网关)。
|
||||
- 提示:`openclaw status --deep` 会将 live Gateway 网关健康探测添加到状态输出中,在支持时也包括渠道探测(需要能访问到 Gateway 网关)。
|
||||
</Step>
|
||||
<Step title="Skills(推荐)">
|
||||
- 读取可用 Skills 并检查要求。
|
||||
- 让你选择一个节点管理器:**npm / pnpm**(不推荐 bun)。
|
||||
- 安装可选依赖(某些在 macOS 上使用 Homebrew)。
|
||||
- 读取可用的 Skills 并检查要求。
|
||||
- 让你选择一个 node 管理器:**npm / pnpm**(不推荐 bun)。
|
||||
- 安装可选依赖(有些会在 macOS 上使用 Homebrew)。
|
||||
</Step>
|
||||
<Step title="完成">
|
||||
- 摘要 + 后续步骤,包括 iOS / Android / macOS 应用以启用额外功能。
|
||||
- 显示摘要和后续步骤,包括 iOS/Android/macOS 应用以启用更多功能。
|
||||
</Step>
|
||||
</Steps>
|
||||
|
||||
<Note>
|
||||
如果未检测到 GUI,新手引导会打印用于访问 Control UI 的 SSH 端口转发说明,而不是打开浏览器。
|
||||
如果缺少 Control UI 资源,新手引导会尝试构建它们;回退命令为 `pnpm ui:build`(会自动安装 UI 依赖)。
|
||||
如果未检测到 GUI,新手引导会打印用于 Control UI 的 SSH 端口转发说明,而不是打开浏览器。
|
||||
如果缺少 Control UI 资源,新手引导会尝试构建它们;回退命令是 `pnpm ui:build`(会自动安装 UI 依赖)。
|
||||
</Note>
|
||||
|
||||
## 非交互模式
|
||||
|
||||
使用 `--non-interactive` 可自动化或脚本化新手引导:
|
||||
使用 `--non-interactive` 来自动化或脚本化新手引导:
|
||||
|
||||
```bash
|
||||
openclaw onboard --non-interactive \
|
||||
@ -163,7 +163,7 @@ openclaw onboard --non-interactive \
|
||||
--skip-skills
|
||||
```
|
||||
|
||||
添加 `--json` 可获得机器可读摘要。
|
||||
添加 `--json` 可获得机器可读的摘要。
|
||||
|
||||
非交互模式中的 Gateway 网关 token SecretRef:
|
||||
|
||||
@ -182,7 +182,7 @@ openclaw onboard --non-interactive \
|
||||
`--json` **不**意味着非交互模式。脚本中请使用 `--non-interactive`(以及 `--workspace`)。
|
||||
</Note>
|
||||
|
||||
提供商特定命令示例位于 [CLI 自动化](/zh-CN/start/wizard-cli-automation#provider-specific-examples)。
|
||||
提供商专用命令示例位于 [CLI 自动化](/zh-CN/start/wizard-cli-automation#provider-specific-examples)。
|
||||
本参考页用于说明标志语义和步骤顺序。
|
||||
|
||||
### 添加智能体(非交互)
|
||||
@ -196,23 +196,23 @@ openclaw agents add work \
|
||||
--json
|
||||
```
|
||||
|
||||
## Gateway 向导 RPC
|
||||
## Gateway 网关向导 RPC
|
||||
|
||||
Gateway 网关通过 RPC 公开新手引导流程(`wizard.start`、`wizard.next`、`wizard.cancel`、`wizard.status`)。
|
||||
客户端(macOS 应用、Control UI)可以渲染各步骤,而无需重新实现新手引导逻辑。
|
||||
Gateway 网关通过 RPC 暴露新手引导流程(`wizard.start`、`wizard.next`、`wizard.cancel`、`wizard.status`)。
|
||||
客户端(macOS 应用、Control UI)可以渲染步骤,而无需重新实现新手引导逻辑。
|
||||
|
||||
## Signal 设置(signal-cli)
|
||||
|
||||
新手引导可以从 GitHub releases 安装 `signal-cli`:
|
||||
|
||||
- 下载适当的发布资源。
|
||||
- 将其存储到 `~/.openclaw/tools/signal-cli/<version>/` 下。
|
||||
- 下载合适的发布资源。
|
||||
- 将其存储到 `~/.openclaw/tools/signal-cli/<version>/`。
|
||||
- 将 `channels.signal.cliPath` 写入你的配置。
|
||||
|
||||
说明:
|
||||
|
||||
- JVM 构建需要 **Java 21**。
|
||||
- 如可用,则使用原生构建。
|
||||
- 在可用时会使用原生构建。
|
||||
- Windows 使用 WSL2;`signal-cli` 安装会在 WSL 内遵循 Linux 流程。
|
||||
|
||||
## 向导会写入什么
|
||||
@ -221,14 +221,14 @@ Gateway 网关通过 RPC 公开新手引导流程(`wizard.start`、`wizard.nex
|
||||
|
||||
- `agents.defaults.workspace`
|
||||
- `agents.defaults.model` / `models.providers`(如果选择了 Minimax)
|
||||
- `tools.profile`(本地新手引导在未设置时默认为 `"coding"`;现有显式值会被保留)
|
||||
- `gateway.*`(模式、绑定、认证、tailscale)
|
||||
- `tools.profile`(本地新手引导在未设置时默认使用 `"coding"`;现有的显式值会被保留)
|
||||
- `gateway.*`(mode、bind、auth、tailscale)
|
||||
- `session.dmScope`(行为细节:[CLI 设置参考](/zh-CN/start/wizard-cli-reference#outputs-and-internals))
|
||||
- `channels.telegram.botToken`、`channels.discord.token`、`channels.matrix.*`、`channels.signal.*`、`channels.imessage.*`
|
||||
- 当你在提示中选择启用时,写入渠道允许列表(Slack / Discord / Matrix / Microsoft Teams)(名称会在可能时解析为 ID)。
|
||||
- 当你在提示中选择启用时,会写入渠道允许列表(Slack/Discord/Matrix/Microsoft Teams)(在可能时会将名称解析为 ID)。
|
||||
- `skills.install.nodeManager`
|
||||
- `setup --node-manager` 接受 `npm`、`pnpm` 或 `bun`。
|
||||
- 手动配置仍可通过直接设置 `skills.install.nodeManager` 来使用 `yarn`。
|
||||
- 手动配置仍可通过直接设置 `skills.install.nodeManager` 使用 `yarn`。
|
||||
- `wizard.lastRunAt`
|
||||
- `wizard.lastRunVersion`
|
||||
- `wizard.lastRunCommit`
|
||||
@ -237,16 +237,16 @@ Gateway 网关通过 RPC 公开新手引导流程(`wizard.start`、`wizard.nex
|
||||
|
||||
`openclaw agents add` 会写入 `agents.list[]` 和可选的 `bindings`。
|
||||
|
||||
WhatsApp 凭证位于 `~/.openclaw/credentials/whatsapp/<accountId>/` 下。
|
||||
WhatsApp 凭证位于 `~/.openclaw/credentials/whatsapp/<accountId>/`。
|
||||
会话存储在 `~/.openclaw/agents/<agentId>/sessions/` 下。
|
||||
|
||||
某些渠道以插件形式提供。当你在设置期间选择其中之一时,新手引导
|
||||
会先提示安装它(npm 或本地路径),然后才能配置。
|
||||
某些渠道以插件形式交付。当你在设置期间选择其中一个时,新手引导
|
||||
会先提示安装它(npm 或本地路径),然后才能进行配置。
|
||||
|
||||
## 相关文档
|
||||
|
||||
- 新手引导概览:[新手引导(CLI)](/zh-CN/start/wizard)
|
||||
- macOS 应用新手引导:[新手引导](/zh-CN/start/onboarding)
|
||||
- 配置参考:[Gateway 配置](/zh-CN/gateway/configuration)
|
||||
- 配置参考:[Gateway 网关配置](/zh-CN/gateway/configuration)
|
||||
- 提供商:[WhatsApp](/zh-CN/channels/whatsapp)、[Telegram](/zh-CN/channels/telegram)、[Discord](/zh-CN/channels/discord)、[Google Chat](/zh-CN/channels/googlechat)、[Signal](/zh-CN/channels/signal)、[BlueBubbles](/zh-CN/channels/bluebubbles)(iMessage)、[iMessage](/zh-CN/channels/imessage)(旧版)
|
||||
- Skills:[Skills](/zh-CN/tools/skills)、[Skills 配置](/zh-CN/tools/skills-config)
|
||||
|
||||
@ -1,15 +1,15 @@
|
||||
---
|
||||
read_when:
|
||||
- 你正在脚本或 CI 中自动化新手引导
|
||||
- 你需要特定提供商的非交互式示例
|
||||
- 你需要针对特定提供商的非交互式示例
|
||||
sidebarTitle: CLI automation
|
||||
summary: 用于 OpenClaw CLI 的脚本化新手引导和智能体设置
|
||||
title: CLI 自动化
|
||||
x-i18n:
|
||||
generated_at: "2026-04-05T17:49:19Z"
|
||||
generated_at: "2026-04-06T15:31:32Z"
|
||||
model: gpt-5.4
|
||||
provider: openai
|
||||
source_hash: 878ea3fa9f2a75cff9f1a803ccb8a52a1219102e2970883ad18e3aaec5967fd2
|
||||
source_hash: bca2dd6e482a16b27284fc76319e936e8df0ff5558134827c19f6875436cc652
|
||||
source_path: start/wizard-cli-automation.md
|
||||
workflow: 15
|
||||
---
|
||||
@ -37,13 +37,13 @@ openclaw onboard --non-interactive \
|
||||
--skip-skills
|
||||
```
|
||||
|
||||
添加 `--json` 可获得机器可读的摘要。
|
||||
添加 `--json` 以获得机器可读的摘要。
|
||||
|
||||
使用 `--secret-input-mode ref` 可在认证配置文件中存储由环境变量支持的引用,而不是明文值。
|
||||
使用 `--secret-input-mode ref` 可将基于环境变量的引用存储到认证 profile 中,而不是存储明文值。
|
||||
在新手引导流程中,支持在环境变量引用和已配置的提供商引用(`file` 或 `exec`)之间进行交互式选择。
|
||||
|
||||
在非交互式 `ref` 模式下,提供商环境变量必须在进程环境中设置。
|
||||
如果传入内联密钥 flag,但没有对应的环境变量,现在会快速失败。
|
||||
传入内联密钥标志但未设置对应环境变量时,现在会快速失败。
|
||||
|
||||
示例:
|
||||
|
||||
@ -55,10 +55,10 @@ openclaw onboard --non-interactive \
|
||||
--accept-risk
|
||||
```
|
||||
|
||||
## 特定提供商示例
|
||||
## 提供商特定示例
|
||||
|
||||
<AccordionGroup>
|
||||
<Accordion title="Anthropic API key 示例">
|
||||
<Accordion title="Anthropic API 密钥示例">
|
||||
```bash
|
||||
openclaw onboard --non-interactive \
|
||||
--mode local \
|
||||
@ -149,7 +149,7 @@ openclaw onboard --non-interactive \
|
||||
--gateway-port 18789 \
|
||||
--gateway-bind loopback
|
||||
```
|
||||
如需使用 Go 目录,请改为 `--auth-choice opencode-go --opencode-go-api-key "$OPENCODE_API_KEY"`。
|
||||
如果要使用 Go catalog,请改为 `--auth-choice opencode-go --opencode-go-api-key "$OPENCODE_API_KEY"`。
|
||||
</Accordion>
|
||||
<Accordion title="Ollama 示例">
|
||||
```bash
|
||||
@ -176,7 +176,7 @@ openclaw onboard --non-interactive \
|
||||
--gateway-bind loopback
|
||||
```
|
||||
|
||||
`--custom-api-key` 是可选的。如果省略,新手引导会检查 `CUSTOM_API_KEY`。
|
||||
`--custom-api-key` 是可选项。如果省略,新手引导会检查 `CUSTOM_API_KEY`。
|
||||
|
||||
ref 模式变体:
|
||||
|
||||
@ -194,17 +194,18 @@ openclaw onboard --non-interactive \
|
||||
--gateway-bind loopback
|
||||
```
|
||||
|
||||
在此模式下,新手引导会将 `apiKey` 存储为 `{ source: "env", provider: "default", id: "CUSTOM_API_KEY" }`。
|
||||
在该模式下,新手引导会将 `apiKey` 存储为 `{ source: "env", provider: "default", id: "CUSTOM_API_KEY" }`。
|
||||
|
||||
</Accordion>
|
||||
</AccordionGroup>
|
||||
|
||||
Anthropic setup-token 再次作为一种旧版 / 手动新手引导路径可用。
|
||||
使用它时,请预期 Anthropic 已告知 OpenClaw 用户,OpenClaw 的 Claude 登录路径需要 **Extra Usage**。在生产环境中,优先使用 Anthropic API key。
|
||||
Anthropic setup-token 仍然可作为受支持的新手引导令牌路径使用,但 OpenClaw 现在在可用时更优先使用 Claude CLI 复用。
|
||||
在生产环境中,优先使用 Anthropic API 密钥。
|
||||
|
||||
## 添加另一个智能体
|
||||
|
||||
使用 `openclaw agents add <name>` 创建一个具有独立工作区、会话和认证配置文件的单独智能体。不带 `--workspace` 运行会启动向导。
|
||||
使用 `openclaw agents add <name>` 创建一个单独的智能体,它拥有自己的工作区、
|
||||
会话和认证 profile。不带 `--workspace` 运行会启动向导。
|
||||
|
||||
```bash
|
||||
openclaw agents add work \
|
||||
@ -224,8 +225,8 @@ openclaw agents add work \
|
||||
说明:
|
||||
|
||||
- 默认工作区遵循 `~/.openclaw/workspace-<agentId>`。
|
||||
- 添加 `bindings` 可路由入站消息(向导可以处理这个)。
|
||||
- 非交互式 flag:`--model`、`--agent-dir`、`--bind`、`--non-interactive`。
|
||||
- 添加 `bindings` 以路由入站消息(向导可以完成此操作)。
|
||||
- 非交互式标志:`--model`、`--agent-dir`、`--bind`、`--non-interactive`。
|
||||
|
||||
## 相关文档
|
||||
|
||||
|
||||
@ -1,15 +1,15 @@
|
||||
---
|
||||
read_when:
|
||||
- 运行或配置 CLI 新手引导时
|
||||
- 设置新机器时
|
||||
- 设置一台新机器时
|
||||
sidebarTitle: 'Onboarding: CLI'
|
||||
summary: CLI 新手引导:为 Gateway 网关、工作区、渠道和 Skills 提供引导式设置
|
||||
summary: CLI 新手引导:用于 Gateway 网关、工作区、渠道和 Skills 的引导式设置
|
||||
title: 设置向导(CLI)
|
||||
x-i18n:
|
||||
generated_at: "2026-04-05T10:10:16Z"
|
||||
generated_at: "2026-04-06T15:31:42Z"
|
||||
model: gpt-5.4
|
||||
provider: openai
|
||||
source_hash: 81e33fb4f8be30e7c2c6e0024bf9bdcf48583ca58eaf5fff5afd37a1cd628523
|
||||
source_hash: 6773b07afa8babf1b5ac94d857063d08094a962ee21ec96ca966e99ad57d107d
|
||||
source_path: start/wizard.md
|
||||
workflow: 15
|
||||
---
|
||||
@ -17,8 +17,8 @@ x-i18n:
|
||||
# 设置向导(CLI)
|
||||
|
||||
CLI 新手引导是在 macOS、
|
||||
Linux 或 Windows(通过 WSL2;强烈推荐)上设置 OpenClaw 的**推荐**方式。
|
||||
它会在一个引导式流程中配置本地 Gateway 网关或远程 Gateway 网关连接,以及渠道、Skills
|
||||
Linux 或 Windows(通过 WSL2,强烈推荐)上设置 OpenClaw 的**推荐**方式。
|
||||
它会通过一个引导式流程一次性配置本地 Gateway 网关或远程 Gateway 网关连接,以及渠道、Skills
|
||||
和工作区默认值。
|
||||
|
||||
```bash
|
||||
@ -26,11 +26,11 @@ openclaw onboard
|
||||
```
|
||||
|
||||
<Info>
|
||||
最快开始首次聊天的方式:打开控制 UI(无需设置任何渠道)。运行
|
||||
`openclaw dashboard` 并在浏览器中聊天。文档:[Dashboard](/web/dashboard)。
|
||||
最快开始第一次聊天的方法:打开 Control UI(无需设置任何渠道)。运行
|
||||
`openclaw dashboard` 并在浏览器中聊天。文档: [Dashboard](/web/dashboard)。
|
||||
</Info>
|
||||
|
||||
稍后若要重新配置:
|
||||
如果之后要重新配置:
|
||||
|
||||
```bash
|
||||
openclaw configure
|
||||
@ -38,34 +38,34 @@ openclaw agents add <name>
|
||||
```
|
||||
|
||||
<Note>
|
||||
`--json` 不意味着非交互模式。对于脚本,请使用 `--non-interactive`。
|
||||
`--json` 不代表非交互模式。对于脚本,请使用 `--non-interactive`。
|
||||
</Note>
|
||||
|
||||
<Tip>
|
||||
CLI 新手引导包含一个 Web 搜索步骤,你可以在其中选择提供商,
|
||||
例如 Brave、DuckDuckGo、Exa、Firecrawl、Gemini、Grok、Kimi、MiniMax Search、
|
||||
Ollama Web 搜索、Perplexity、SearXNG 或 Tavily。某些提供商需要
|
||||
API 密钥,而另一些不需要密钥。你也可以稍后使用
|
||||
`openclaw configure --section web` 进行配置。文档:[Web 工具](/zh-CN/tools/web)。
|
||||
Ollama Web 搜索、Perplexity、SearXNG 或 Tavily。有些提供商需要
|
||||
API key,而另一些不需要。你也可以之后再用
|
||||
`openclaw configure --section web` 进行配置。文档: [Web 工具](/zh-CN/tools/web)。
|
||||
</Tip>
|
||||
|
||||
## 快速开始 vs 高级
|
||||
|
||||
新手引导会先从**快速开始**(默认值)和**高级**(完全控制)之间开始选择。
|
||||
新手引导一开始会让你选择**快速开始**(默认值)还是**高级**(完全控制)。
|
||||
|
||||
<Tabs>
|
||||
<Tab title="快速开始(默认值)">
|
||||
- 本地 Gateway 网关(loopback)
|
||||
- 默认工作区(或现有工作区)
|
||||
- Gateway 网关端口 **18789**
|
||||
- Gateway 网关认证 **Token**(自动生成,即使在 loopback 上也是如此)
|
||||
- 新本地设置的默认工具策略:`tools.profile: "coding"`(现有显式 profile 会被保留)
|
||||
- 私信隔离默认值:本地新手引导在未设置时写入 `session.dmScope: "per-channel-peer"`。详情参见:[CLI 设置参考](/zh-CN/start/wizard-cli-reference#outputs-and-internals)
|
||||
- Gateway 网关认证 **Token**(即使在 loopback 上也会自动生成)
|
||||
- 新本地设置的默认工具策略:`tools.profile: "coding"`(已有的显式 profile 会被保留)
|
||||
- 私信隔离默认值:本地新手引导会在未设置时写入 `session.dmScope: "per-channel-peer"`。详情: [CLI 设置参考](/zh-CN/start/wizard-cli-reference#outputs-and-internals)
|
||||
- Tailscale 暴露 **关闭**
|
||||
- Telegram 和 WhatsApp 私信默认使用 **allowlist**(会提示你输入你的电话号码)
|
||||
- Telegram + WhatsApp 私信默认使用 **allowlist**(系统会提示你输入手机号)
|
||||
</Tab>
|
||||
<Tab title="高级(完全控制)">
|
||||
- 暴露每一个步骤(mode、workspace、gateway、channels、daemon、skills)。
|
||||
- 显示所有步骤(模式、工作区、Gateway 网关、渠道、守护进程、Skills)。
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
@ -73,38 +73,38 @@ API 密钥,而另一些不需要密钥。你也可以稍后使用
|
||||
|
||||
**本地模式(默认)**会引导你完成以下步骤:
|
||||
|
||||
1. **模型/认证** —— 选择任意受支持的提供商/认证流程(API 密钥、OAuth 或提供商特定的手动认证),包括 Custom Provider
|
||||
(OpenAI 兼容、Anthropic 兼容或 Unknown 自动检测)。选择一个默认模型。
|
||||
安全说明:如果该智能体将运行工具或处理 webhook/hooks 内容,请优先选择可用的最新一代最强模型,并保持严格的工具策略。较弱/较旧的层级更容易受到 prompt injection 影响。
|
||||
对于非交互式运行,`--secret-input-mode ref` 会在认证配置文件中存储由环境变量支持的引用,而不是明文 API 密钥值。
|
||||
在非交互 `ref` 模式下,必须设置提供商环境变量;如果未设置该环境变量却传入内联密钥标志,则会快速失败。
|
||||
在交互式运行中,选择密钥引用模式后,你可以选择指向环境变量或已配置的提供商引用(`file` 或 `exec`),并在保存前执行快速预检验证。
|
||||
对于 Anthropic,交互式新手引导/配置会提供 **Anthropic Claude CLI** 作为本地回退方案,并将 **Anthropic API 密钥** 作为推荐的生产路径。Anthropic setup-token 也再次作为旧版/手动 OpenClaw 路径提供,并遵循 Anthropic 针对 OpenClaw 的 **Extra Usage** 计费预期。
|
||||
2. **工作区** —— 智能体文件的位置(默认 `~/.openclaw/workspace`)。会初始化 bootstrap 文件。
|
||||
3. **Gateway 网关** —— 端口、绑定地址、认证模式、Tailscale 暴露。
|
||||
在交互式 token 模式下,可以选择默认的明文 token 存储,或选择使用 SecretRef。
|
||||
1. **模型/认证** — 选择任意受支持的提供商/认证流程(API key、OAuth 或提供商专用手动认证),包括 Custom Provider
|
||||
(兼容 OpenAI、兼容 Anthropic,或 Unknown 自动检测)。选择一个默认模型。
|
||||
安全说明:如果此智能体将运行工具或处理 webhook/hooks 内容,请优先选择当前最强的新一代模型,并保持严格的工具策略。较弱/较旧的层级更容易受到提示注入攻击。
|
||||
对于非交互式运行,`--secret-input-mode ref` 会在认证 profile 中存储基于环境变量的引用,而不是明文 API key 值。
|
||||
在非交互式 `ref` 模式下,必须设置提供商环境变量;如果传入内联 key flags 但未设置相应环境变量,将会快速失败。
|
||||
在交互式运行中,选择 secret 引用模式后,你可以指向环境变量或已配置的提供商引用(`file` 或 `exec`),并在保存前进行快速预检验证。
|
||||
对于 Anthropic,交互式新手引导/配置会将 **Anthropic Claude CLI** 作为首选本地路径,并将 **Anthropic API key** 作为推荐的生产路径。Anthropic setup-token 也仍然可作为受支持的 token 认证路径。
|
||||
2. **工作区** — 智能体文件的位置(默认 `~/.openclaw/workspace`)。会植入引导文件。
|
||||
3. **Gateway 网关** — 端口、绑定地址、认证模式、Tailscale 暴露。
|
||||
在交互式 token 模式中,你可以选择默认的明文 token 存储,或改用 SecretRef。
|
||||
非交互式 token SecretRef 路径:`--gateway-token-ref-env <ENV_VAR>`。
|
||||
4. **渠道** —— 内置和内置打包的聊天渠道,例如 BlueBubbles、Discord、Feishu、Google Chat、Mattermost、Microsoft Teams、QQ Bot、Signal、Slack、Telegram、WhatsApp 等。
|
||||
5. **守护进程** —— 安装 LaunchAgent(macOS)、systemd 用户单元(Linux/WSL2),或原生 Windows Scheduled Task,并提供按用户 Startup-folder 回退方案。
|
||||
如果 token 认证需要 token 且 `gateway.auth.token` 由 SecretRef 管理,守护进程安装会验证它,但不会将解析出的 token 持久化到 supervisor 服务环境元数据中。
|
||||
如果 token 认证需要 token 且已配置的 token SecretRef 未解析,守护进程安装会被阻止,并给出可操作的指导。
|
||||
如果 `gateway.auth.token` 和 `gateway.auth.password` 都已配置,而 `gateway.auth.mode` 未设置,守护进程安装会被阻止,直到显式设置 mode。
|
||||
6. **健康检查** —— 启动 Gateway 网关并验证其正在运行。
|
||||
7. **Skills** —— 安装推荐的 Skills 和可选依赖。
|
||||
4. **渠道** — 内置和内置打包的聊天渠道,例如 BlueBubbles、Discord、Feishu、Google Chat、Mattermost、Microsoft Teams、QQ Bot、Signal、Slack、Telegram、WhatsApp 等。
|
||||
5. **守护进程** — 安装 LaunchAgent(macOS)、systemd 用户单元(Linux/WSL2),或原生 Windows 计划任务,并提供按用户 Startup 文件夹回退方案。
|
||||
如果 token 认证需要 token 且 `gateway.auth.token` 由 SecretRef 管理,守护进程安装会验证它,但不会将解析后的 token 持久化到 supervisor 服务环境元数据中。
|
||||
如果 token 认证需要 token 且已配置的 token SecretRef 无法解析,守护进程安装将被阻止,并给出可执行的指引。
|
||||
如果同时配置了 `gateway.auth.token` 和 `gateway.auth.password`,但 `gateway.auth.mode` 未设置,守护进程安装将被阻止,直到显式设置 mode。
|
||||
6. **健康检查** — 启动 Gateway 网关并验证它是否正在运行。
|
||||
7. **Skills** — 安装推荐的 Skills 和可选依赖。
|
||||
|
||||
<Note>
|
||||
重新运行新手引导**不会**清除任何内容,除非你明确选择**重置**(或传入 `--reset`)。
|
||||
CLI `--reset` 默认重置配置、凭证和会话;使用 `--reset-scope full` 可将工作区也包含在内。
|
||||
如果配置无效或包含旧版键,新手引导会要求你先运行 `openclaw doctor`。
|
||||
重新运行新手引导**不会**清除任何内容,除非你明确选择 **Reset**(或传入 `--reset`)。
|
||||
CLI `--reset` 默认会重置 config、credentials 和 sessions;使用 `--reset-scope full` 可将 workspace 也包括进去。
|
||||
如果配置无效或包含旧版键名,新手引导会要求你先运行 `openclaw doctor`。
|
||||
</Note>
|
||||
|
||||
**远程模式**只会配置本地客户端去连接其他地方的 Gateway 网关。
|
||||
**远程模式**只会配置本地客户端去连接另一处的 Gateway 网关。
|
||||
它**不会**在远程主机上安装或更改任何内容。
|
||||
|
||||
## 添加另一个智能体
|
||||
|
||||
使用 `openclaw agents add <name>` 可创建一个独立的智能体,拥有自己的工作区、
|
||||
会话和认证配置文件。运行时不带 `--workspace` 会启动新手引导。
|
||||
使用 `openclaw agents add <name>` 创建一个拥有独立工作区、
|
||||
会话和认证 profile 的单独智能体。不带 `--workspace` 运行时会启动新手引导。
|
||||
|
||||
它会设置:
|
||||
|
||||
@ -115,15 +115,15 @@ CLI `--reset` 默认重置配置、凭证和会话;使用 `--reset-scope full`
|
||||
说明:
|
||||
|
||||
- 默认工作区遵循 `~/.openclaw/workspace-<agentId>`。
|
||||
- 可添加 `bindings` 来路由入站消息(新手引导可以执行此操作)。
|
||||
- 非交互式标志:`--model`、`--agent-dir`、`--bind`、`--non-interactive`。
|
||||
- 添加 `bindings` 可路由入站消息(新手引导可以完成此操作)。
|
||||
- 非交互式 flags:`--model`、`--agent-dir`、`--bind`、`--non-interactive`。
|
||||
|
||||
## 完整参考
|
||||
|
||||
如需详细的逐步拆解和配置输出,请参见
|
||||
有关详细的分步骤说明和配置输出,请参见
|
||||
[CLI 设置参考](/zh-CN/start/wizard-cli-reference)。
|
||||
如需非交互示例,请参见 [CLI 自动化](/zh-CN/start/wizard-cli-automation)。
|
||||
如需更深入的技术参考(包括 RPC 详情),请参见
|
||||
有关非交互式示例,请参见 [CLI 自动化](/zh-CN/start/wizard-cli-automation)。
|
||||
有关更深入的技术参考(包括 RPC 细节),请参见
|
||||
[新手引导参考](/zh-CN/reference/wizard)。
|
||||
|
||||
## 相关文档
|
||||
@ -131,4 +131,4 @@ CLI `--reset` 默认重置配置、凭证和会话;使用 `--reset-scope full`
|
||||
- CLI 命令参考:[`openclaw onboard`](/cli/onboard)
|
||||
- 新手引导概览:[新手引导概览](/zh-CN/start/onboarding-overview)
|
||||
- macOS 应用新手引导:[新手引导](/zh-CN/start/onboarding)
|
||||
- 智能体首次运行流程:[智能体引导初始化](/zh-CN/start/bootstrapping)
|
||||
- 智能体首次运行仪式:[智能体引导](/zh-CN/start/bootstrapping)
|
||||
|
||||
67
docs/zh-CN/tools/media-overview.md
Normal file
67
docs/zh-CN/tools/media-overview.md
Normal file
@ -0,0 +1,67 @@
|
||||
---
|
||||
read_when:
|
||||
- 正在查找媒体能力概览
|
||||
- 正在决定应配置哪个媒体 provider
|
||||
- 想了解异步媒体生成是如何工作的
|
||||
summary: 媒体生成、理解和语音能力的统一落地页
|
||||
title: 媒体概览
|
||||
x-i18n:
|
||||
generated_at: "2026-04-06T15:31:36Z"
|
||||
model: gpt-5.4
|
||||
provider: openai
|
||||
source_hash: cfee08eb91ec3e827724c8fa99bff7465356f6f1ac1b146562f35651798e3fd6
|
||||
source_path: tools/media-overview.md
|
||||
workflow: 15
|
||||
---
|
||||
|
||||
# 媒体生成与理解
|
||||
|
||||
OpenClaw 可以生成图像、视频和音乐,理解传入媒体(图像、音频、视频),并通过文本转语音将回复朗读出来。所有媒体能力都由工具驱动:智能体会根据对话决定何时使用它们,并且只有在至少配置了一个对应 provider 时,相应工具才会出现。
|
||||
|
||||
## 能力一览
|
||||
|
||||
| 能力 | 工具 | Providers | 功能说明 |
|
||||
| -------------------- | ---------------- | -------------------------------------------------------------------------------------------- | ------------------------------------------------------- |
|
||||
| 图像生成 | `image_generate` | ComfyUI、fal、Google、MiniMax、OpenAI、Vydra | 根据文本提示词或参考内容创建或编辑图像 |
|
||||
| 视频生成 | `video_generate` | Alibaba、BytePlus(国际版)、ComfyUI、fal、Google、MiniMax、OpenAI、Qwen、Runway、Together、Vydra、xAI | 根据文本、图像或现有视频创建视频 |
|
||||
| 音乐生成 | `music_generate` | ComfyUI、Google、MiniMax | 根据文本提示词创建音乐或音轨 |
|
||||
| 文本转语音(TTS) | `tts` | ElevenLabs、Microsoft、MiniMax、OpenAI | 将输出回复转换为语音音频 |
|
||||
| 媒体理解 | (自动) | 任何具备视觉/音频能力的模型 provider,以及 CLI 回退 | 总结传入的图像、音频和视频 |
|
||||
|
||||
## Provider 能力矩阵
|
||||
|
||||
此表展示了各 provider 在整个平台上支持哪些媒体能力。
|
||||
|
||||
| Provider | 图像 | 视频 | 音乐 | TTS | STT / 转录 | 媒体理解 |
|
||||
| ---------- | ----- | ----- | ----- | --- | ------------------- | ------------------- |
|
||||
| Alibaba | | Yes | | | | |
|
||||
| BytePlus | | Yes | | | | |
|
||||
| ComfyUI | Yes | Yes | Yes | | | |
|
||||
| Deepgram | | | | | Yes | |
|
||||
| ElevenLabs | | | | Yes | | |
|
||||
| fal | Yes | Yes | | | | |
|
||||
| Google | Yes | Yes | Yes | | | Yes |
|
||||
| Microsoft | | | | Yes | | |
|
||||
| MiniMax | Yes | Yes | Yes | Yes | | |
|
||||
| OpenAI | Yes | Yes | | Yes | Yes | Yes |
|
||||
| Qwen | | Yes | | | | |
|
||||
| Runway | | Yes | | | | |
|
||||
| Together | | Yes | | | | |
|
||||
| Vydra | Yes | Yes | | | | |
|
||||
| xAI | | Yes | | | | |
|
||||
|
||||
<Note>
|
||||
媒体理解会使用你在 provider 配置中注册的任何具备视觉能力或音频能力的模型。上表重点标出了具备专用媒体理解支持的 provider;大多数带有多模态模型的 LLM provider(Anthropic、Google、OpenAI 等)在被配置为当前活动回复模型时,也能够理解传入媒体。
|
||||
</Note>
|
||||
|
||||
## 异步生成如何工作
|
||||
|
||||
视频和音乐生成会作为后台任务运行,因为 provider 处理通常需要 30 秒到数分钟。当智能体调用 `video_generate` 或 `music_generate` 时,OpenClaw 会将请求提交给 provider,立即返回任务 ID,并在任务账本中跟踪该作业。作业运行期间,智能体会继续响应其他消息。当 provider 完成后,OpenClaw 会唤醒智能体,使其能够将完成的媒体发布回原始渠道。图像生成和 TTS 是同步的,会在回复过程中内联完成。
|
||||
|
||||
## 快速链接
|
||||
|
||||
- [图像生成](/zh-CN/tools/image-generation) -- 生成和编辑图像
|
||||
- [视频生成](/zh-CN/tools/video-generation) -- text-to-video、image-to-video 和 video-to-video
|
||||
- [音乐生成](/zh-CN/tools/music-generation) -- 创建音乐和音轨
|
||||
- [文本转语音](/zh-CN/tools/tts) -- 将回复转换为语音音频
|
||||
- [媒体理解](/zh-CN/nodes/media-understanding) -- 理解传入的图像、音频和视频
|
||||
@ -1,35 +1,40 @@
|
||||
---
|
||||
read_when:
|
||||
- 通过智能体生成音乐或音频
|
||||
- 配置音乐生成提供商和模型
|
||||
- 理解 `music_generate` 工具参数
|
||||
- 通过智能体生成音乐或音频时
|
||||
- 配置音乐生成提供商和模型时
|
||||
- 了解 `music_generate` 工具参数时
|
||||
summary: 使用共享提供商生成音乐,包括基于工作流的插件
|
||||
title: 音乐生成
|
||||
x-i18n:
|
||||
generated_at: "2026-04-06T01:46:14Z"
|
||||
generated_at: "2026-04-06T15:32:12Z"
|
||||
model: gpt-5.4
|
||||
provider: openai
|
||||
source_hash: a03de8aa75cfb7248eb0c1d969fb2a6da06117967d097e6f6e95771d0f017ae1
|
||||
source_hash: 5a2c95d087d6d0b5f4aaaae2fc1f98d683cbb4991d08ed6cabae45c90519ec0c
|
||||
source_path: tools/music-generation.md
|
||||
workflow: 15
|
||||
---
|
||||
|
||||
# 音乐生成
|
||||
|
||||
`music_generate` 工具让智能体能够通过共享音乐生成能力,使用已配置的提供商来创建音乐或音频,例如 Google、MiniMax 和通过工作流配置的 ComfyUI。
|
||||
`music_generate` 工具允许智能体通过共享的音乐生成能力来创建音乐或音频,
|
||||
可使用已配置的提供商,例如 Google、
|
||||
MiniMax,以及通过工作流配置的 ComfyUI。
|
||||
|
||||
对于由共享提供商支持的智能体会话,OpenClaw 会将音乐生成作为后台任务启动,在任务账本中跟踪它,然后在音轨准备就绪时再次唤醒智能体,以便智能体将完成的音频发布回原始渠道。
|
||||
对于基于共享提供商的智能体会话,OpenClaw 会将音乐生成启动为后台任务,
|
||||
在任务账本中跟踪它,然后在音轨准备好后再次唤醒智能体,
|
||||
这样智能体就可以把最终音频发回原始渠道。
|
||||
|
||||
<Note>
|
||||
仅当至少有一个音乐生成提供商可用时,内置共享工具才会显示。如果你在智能体工具中看不到 `music_generate`,请配置 `agents.defaults.musicGenerationModel` 或设置提供商 API 密钥。
|
||||
只有在至少有一个音乐生成提供商可用时,内置共享工具才会出现。如果你在智能体工具中看不到 `music_generate`,请配置 `agents.defaults.musicGenerationModel` 或设置提供商 API 密钥。
|
||||
</Note>
|
||||
|
||||
## 快速开始
|
||||
|
||||
### 由共享提供商支持的生成
|
||||
### 基于共享提供商的生成
|
||||
|
||||
1. 为至少一个提供商设置 API 密钥,例如 `GEMINI_API_KEY` 或 `MINIMAX_API_KEY`。
|
||||
2. 你也可以选择设置首选模型:
|
||||
1. 为至少一个提供商设置 API 密钥,例如 `GEMINI_API_KEY` 或
|
||||
`MINIMAX_API_KEY`。
|
||||
2. 可选地设置你的首选模型:
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -43,11 +48,12 @@ x-i18n:
|
||||
}
|
||||
```
|
||||
|
||||
3. 向智能体发出请求:_“生成一首关于夜间驾车穿越霓虹城市的欢快 synthpop 音轨。”_
|
||||
3. 向智能体提问:_“生成一段关于夜晚驾车穿过霓虹都市的轻快 synthpop 音轨。”_
|
||||
|
||||
智能体会自动调用 `music_generate`。无需配置工具允许列表。
|
||||
智能体会自动调用 `music_generate`。不需要工具允许列表。
|
||||
|
||||
对于没有会话支持智能体运行的直接同步上下文,内置工具仍会回退到内联生成,并在工具结果中返回最终媒体路径。
|
||||
对于没有基于会话的智能体运行的直接同步上下文,内置
|
||||
工具仍会回退为内联生成,并在工具结果中返回最终媒体路径。
|
||||
|
||||
示例提示词:
|
||||
|
||||
@ -59,11 +65,13 @@ Generate a cinematic piano track with soft strings and no vocals.
|
||||
Generate an energetic chiptune loop about launching a rocket at sunrise.
|
||||
```
|
||||
|
||||
### 由工作流驱动的 Comfy 生成
|
||||
### 基于工作流的 Comfy 生成
|
||||
|
||||
内置的 `comfy` 插件通过音乐生成提供商注册表接入共享 `music_generate` 工具。
|
||||
内置的 `comfy` 插件通过
|
||||
音乐生成提供商注册表接入共享的 `music_generate` 工具。
|
||||
|
||||
1. 使用工作流 JSON 以及提示词/输出节点配置 `models.providers.comfy.music`。
|
||||
1. 配置 `models.providers.comfy.music`,包含工作流 JSON 以及
|
||||
prompt/output 节点。
|
||||
2. 如果你使用 Comfy Cloud,请设置 `COMFY_API_KEY` 或 `COMFY_CLOUD_API_KEY`。
|
||||
3. 请求智能体生成音乐,或直接调用该工具。
|
||||
|
||||
@ -75,19 +83,30 @@ Generate an energetic chiptune loop about launching a rocket at sunrise.
|
||||
|
||||
## 共享内置提供商支持
|
||||
|
||||
| 提供商 | 默认模型 | 参考输入 | 支持的控制项 | API 密钥 |
|
||||
| ------ | ---------------------- | -------------- | --------------------------------------------------------- | -------------------------------------- |
|
||||
| ComfyUI | `workflow` | 最多 1 张图像 | 由工作流定义的音乐或音频 | `COMFY_API_KEY`, `COMFY_CLOUD_API_KEY` |
|
||||
| Google | `lyria-3-clip-preview` | 最多 10 张图像 | `lyrics`、`instrumental`、`format` | `GEMINI_API_KEY`, `GOOGLE_API_KEY` |
|
||||
| 提供商 | 默认模型 | 参考输入 | 支持的控制项 | API 密钥 |
|
||||
| -------- | ---------------------- | ---------------- | --------------------------------------------------------- | -------------------------------------- |
|
||||
| ComfyUI | `workflow` | 最多 1 张图像 | 由工作流定义的音乐或音频 | `COMFY_API_KEY`, `COMFY_CLOUD_API_KEY` |
|
||||
| Google | `lyria-3-clip-preview` | 最多 10 张图像 | `lyrics`、`instrumental`、`format` | `GEMINI_API_KEY`, `GOOGLE_API_KEY` |
|
||||
| MiniMax | `music-2.5+` | 无 | `lyrics`、`instrumental`、`durationSeconds`、`format=mp3` | `MINIMAX_API_KEY` |
|
||||
|
||||
### 已声明的能力矩阵
|
||||
|
||||
这是 `music_generate`、契约测试
|
||||
和共享 live 扫描使用的显式模式契约。
|
||||
|
||||
| 提供商 | `generate` | `edit` | 编辑上限 | 共享 live lane |
|
||||
| -------- | ---------- | ------ | ---------- | ------------------------------------------------------------------------- |
|
||||
| ComfyUI | 是 | 是 | 1 张图像 | 不在共享扫描中;由 `extensions/comfy/comfy.live.test.ts` 覆盖 |
|
||||
| Google | 是 | 是 | 10 张图像 | `generate`、`edit` |
|
||||
| MiniMax | 是 | 否 | 无 | `generate` |
|
||||
|
||||
使用 `action: "list"` 可在运行时查看可用的共享提供商和模型:
|
||||
|
||||
```text
|
||||
/tool music_generate action=list
|
||||
```
|
||||
|
||||
使用 `action: "status"` 可查看当前由会话支持的活动音乐任务:
|
||||
使用 `action: "status"` 可查看当前基于会话的音乐任务:
|
||||
|
||||
```text
|
||||
/tool music_generate action=status
|
||||
@ -101,30 +120,50 @@ Generate an energetic chiptune loop about launching a rocket at sunrise.
|
||||
|
||||
## 内置工具参数
|
||||
|
||||
| 参数 | 类型 | 说明 |
|
||||
| 参数 | 类型 | 描述 |
|
||||
| ----------------- | -------- | ------------------------------------------------------------------------------------------------- |
|
||||
| `prompt` | string | 音乐生成提示词(`action: "generate"` 时必填) |
|
||||
| `action` | string | `"generate"`(默认)、用于当前会话任务的 `"status"`,或用于查看提供商的 `"list"` |
|
||||
| `model` | string | 提供商/模型覆盖值,例如 `google/lyria-3-pro-preview` 或 `comfy/workflow` |
|
||||
| `lyrics` | string | 当提供商支持显式歌词输入时,可选的歌词内容 |
|
||||
| `instrumental` | boolean | 当提供商支持时,请求仅器乐输出 |
|
||||
| `image` | string | 单个参考图像路径或 URL |
|
||||
| `images` | string[] | 多个参考图像(最多 10 张) |
|
||||
| `durationSeconds` | number | 当提供商支持时,目标时长(秒)提示 |
|
||||
| `format` | string | 当提供商支持时,输出格式提示(`mp3` 或 `wav`) |
|
||||
| `filename` | string | 输出文件名提示 |
|
||||
| `prompt` | string | 音乐生成提示词(`action: "generate"` 时必填) |
|
||||
| `action` | string | `"generate"`(默认)、`"status"`(当前会话任务)或 `"list"`(查看提供商) |
|
||||
| `model` | string | 提供商/模型覆盖,例如 `google/lyria-3-pro-preview` 或 `comfy/workflow` |
|
||||
| `lyrics` | string | 当提供商支持显式歌词输入时使用的可选歌词 |
|
||||
| `instrumental` | boolean | 当提供商支持时,请求仅器乐输出 |
|
||||
| `image` | string | 单张参考图像路径或 URL |
|
||||
| `images` | string[] | 多张参考图像(最多 10 张) |
|
||||
| `durationSeconds` | number | 当提供商支持时长提示时,目标时长(秒) |
|
||||
| `format` | string | 当提供商支持时的输出格式提示(`mp3` 或 `wav`) |
|
||||
| `filename` | string | 输出文件名提示 |
|
||||
|
||||
并非所有提供商都支持所有参数。OpenClaw 仍会在提交前验证硬性限制,例如输入数量,但对于所选提供商或模型无法满足的不受支持可选提示,会在发出警告后忽略。
|
||||
并非所有提供商都支持所有参数。OpenClaw 仍会在提交前验证诸如输入数量之类的硬性限制,
|
||||
但如果所选提供商或模型无法满足某些可选提示,这些提示会被忽略,并给出警告。
|
||||
|
||||
## 共享提供商支持路径的异步行为
|
||||
## 共享提供商路径的异步行为
|
||||
|
||||
- 由会话支持的智能体运行:`music_generate` 会创建一个后台任务,立即返回 started/task 响应,并在稍后的智能体跟进消息中发布完成的音轨。
|
||||
- 防止重复:当该后台任务仍处于 `queued` 或 `running` 状态时,同一会话中后续的 `music_generate` 调用会返回任务状态,而不是启动新的生成。
|
||||
- 状态查询:使用 `action: "status"` 可在不启动新任务的情况下查看当前由会话支持的活动音乐任务。
|
||||
- 任务跟踪:使用 `openclaw tasks list` 或 `openclaw tasks show <taskId>` 可查看该生成任务的排队中、运行中和终态状态。
|
||||
- 完成唤醒:OpenClaw 会将一个内部完成事件注入回同一会话,以便模型自行编写面向用户的跟进内容。
|
||||
- 提示词提示:当音乐任务已在进行中时,同一会话中的后续用户/手动轮次会收到一个较小的运行时提示,这样模型就不会盲目再次调用 `music_generate`。
|
||||
- 无会话回退:没有真实智能体会话的直接/本地上下文仍会以内联方式运行,并在同一轮中返回最终音频结果。
|
||||
- 基于会话的智能体运行:`music_generate` 会创建后台任务,立即返回已启动/任务响应,并在稍后的后续智能体消息中发送完成的音轨。
|
||||
- 重复防护:当该后台任务仍处于 `queued` 或 `running` 状态时,同一会话中的后续 `music_generate` 调用会返回任务状态,而不是再次启动生成。
|
||||
- 状态查询:使用 `action: "status"` 可在不启动新生成的情况下查看当前基于会话的音乐任务。
|
||||
- 任务跟踪:使用 `openclaw tasks list` 或 `openclaw tasks show <taskId>` 查看生成任务的排队、运行和终态状态。
|
||||
- 完成唤醒:OpenClaw 会将内部完成事件注入回同一会话,以便模型自行编写面向用户的后续消息。
|
||||
- 提示词提示:如果同一会话中已有音乐任务在进行,后续用户/手动回合会收到一个小型运行时提示,避免模型再次盲目调用 `music_generate`。
|
||||
- 无会话回退:没有真实智能体会话的直接/本地上下文仍会以内联方式运行,并在同一回合返回最终音频结果。
|
||||
|
||||
### 任务生命周期
|
||||
|
||||
每个 `music_generate` 请求会经历四个状态:
|
||||
|
||||
1. **queued** —— 任务已创建,等待提供商接受。
|
||||
2. **running** —— 提供商正在处理(通常为 30 秒到 3 分钟,取决于提供商和时长)。
|
||||
3. **succeeded** —— 音轨已就绪;智能体被唤醒并将其发布到会话中。
|
||||
4. **failed** —— 提供商错误或超时;智能体会带着错误详情被唤醒。
|
||||
|
||||
从 CLI 检查状态:
|
||||
|
||||
```bash
|
||||
openclaw tasks list
|
||||
openclaw tasks show <taskId>
|
||||
openclaw tasks cancel <taskId>
|
||||
```
|
||||
|
||||
重复防护:如果当前会话已有音乐任务处于 `queued` 或 `running` 状态,`music_generate` 会返回现有任务状态,而不是启动新任务。使用 `action: "status"` 可显式检查,而不会触发新生成。
|
||||
|
||||
## 配置
|
||||
|
||||
@ -147,42 +186,87 @@ Generate an energetic chiptune loop about launching a rocket at sunrise.
|
||||
|
||||
生成音乐时,OpenClaw 会按以下顺序尝试提供商:
|
||||
|
||||
1. 工具调用中的 `model` 参数(如果智能体指定了)
|
||||
1. 工具调用中的 `model` 参数(如果智能体显式指定)
|
||||
2. 配置中的 `musicGenerationModel.primary`
|
||||
3. 按顺序使用 `musicGenerationModel.fallbacks`
|
||||
4. 仅使用基于凭证的提供商默认值进行自动检测:
|
||||
- 先使用当前默认提供商
|
||||
- 再按提供商 ID 顺序使用其余已注册的音乐生成提供商
|
||||
4. 仅使用基于认证的提供商默认值进行自动检测:
|
||||
- 先尝试当前默认提供商
|
||||
- 再按提供商 id 顺序尝试其余已注册的音乐生成提供商
|
||||
|
||||
如果某个提供商失败,会自动尝试下一个候选项。如果全部失败,错误信息会包含每次尝试的详细信息。
|
||||
如果某个提供商失败,会自动尝试下一个候选项。如果全部失败,
|
||||
错误中会包含每次尝试的详细信息。
|
||||
|
||||
## 提供商说明
|
||||
|
||||
- Google 使用 Lyria 3 批量生成。当前内置流程支持提示词、可选歌词文本和可选参考图像。
|
||||
- MiniMax 使用批量 `music_generation` 端点。当前内置流程支持提示词、可选歌词、器乐模式、时长控制和 mp3 输出。
|
||||
- ComfyUI 支持由工作流驱动,并取决于已配置的图以及提示词/输出字段的节点映射。
|
||||
- Google 使用 Lyria 3 批量生成。当前内置流程支持
|
||||
prompt、可选歌词文本和可选参考图像。
|
||||
- MiniMax 使用批量 `music_generation` 端点。当前内置流程
|
||||
支持 prompt、可选歌词、器乐模式、时长引导以及
|
||||
mp3 输出。
|
||||
- ComfyUI 支持基于工作流驱动,并取决于所配置的图以及
|
||||
prompt/output 字段的节点映射。
|
||||
|
||||
## 选择合适的路径
|
||||
## 提供商能力模式
|
||||
|
||||
- 当你需要模型选择、提供商故障转移以及内置异步任务/状态流程时,请使用共享提供商支持路径。
|
||||
- 当你需要自定义工作流图,或需要不属于共享内置音乐能力的提供商时,请使用插件路径,例如 ComfyUI。
|
||||
- 如果你正在调试 ComfyUI 特定行为,请参阅 [ComfyUI](/zh-CN/providers/comfy)。如果你正在调试共享提供商行为,请先查看 [Google(Gemini)](/zh-CN/providers/google) 或 [MiniMax](/zh-CN/providers/minimax)。
|
||||
共享音乐生成契约现在支持显式模式声明:
|
||||
|
||||
## 实时测试
|
||||
- `generate` 用于仅基于提示词的生成
|
||||
- 当请求包含一张或多张参考图像时,使用 `edit`
|
||||
|
||||
共享内置提供商的选择加入式实时覆盖:
|
||||
新的提供商实现应优先使用显式模式块:
|
||||
|
||||
```typescript
|
||||
capabilities: {
|
||||
generate: {
|
||||
maxTracks: 1,
|
||||
supportsLyrics: true,
|
||||
supportsFormat: true,
|
||||
},
|
||||
edit: {
|
||||
enabled: true,
|
||||
maxTracks: 1,
|
||||
maxInputImages: 1,
|
||||
supportsFormat: true,
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
旧版平铺字段,例如 `maxInputImages`、`supportsLyrics` 和
|
||||
`supportsFormat`,不足以宣告编辑支持。提供商应
|
||||
显式声明 `generate` 和 `edit`,这样 live 测试、契约测试以及
|
||||
共享的 `music_generate` 工具才能以确定性的方式验证模式支持。
|
||||
|
||||
## 选择正确的路径
|
||||
|
||||
- 当你需要模型选择、提供商故障切换和内置异步任务/状态流时,请使用共享提供商路径。
|
||||
- 当你需要自定义工作流图,或需要使用不属于共享内置音乐能力的提供商时,请使用插件路径,例如 ComfyUI。
|
||||
- 如果你正在调试 ComfyUI 特定行为,请参见 [ComfyUI](/zh-CN/providers/comfy)。如果你正在调试共享提供商行为,请先从 [Google(Gemini)](/zh-CN/providers/google) 或 [MiniMax](/zh-CN/providers/minimax) 开始。
|
||||
|
||||
## Live 测试
|
||||
|
||||
针对共享内置提供商的按需启用 live 覆盖:
|
||||
|
||||
```bash
|
||||
OPENCLAW_LIVE_TEST=1 pnpm test:live -- extensions/music-generation-providers.live.test.ts
|
||||
```
|
||||
|
||||
内置 ComfyUI 音乐路径的选择加入式实时覆盖:
|
||||
该 live 文件会从 `~/.profile` 加载缺失的提供商环境变量,默认优先使用
|
||||
live/env API 密钥而不是已存储的认证 profile,并在提供商启用编辑模式时同时运行
|
||||
`generate` 和已声明的 `edit` 覆盖。
|
||||
|
||||
当前这意味着:
|
||||
|
||||
- `google`:`generate` 加 `edit`
|
||||
- `minimax`:仅 `generate`
|
||||
- `comfy`:单独的 Comfy live 覆盖,不属于共享提供商扫描
|
||||
|
||||
针对内置 ComfyUI 音乐路径的按需启用 live 覆盖:
|
||||
|
||||
```bash
|
||||
OPENCLAW_LIVE_TEST=1 COMFY_LIVE_TEST=1 pnpm test:live -- extensions/comfy/comfy.live.test.ts
|
||||
```
|
||||
|
||||
当这些部分已配置时,Comfy 实时文件还会覆盖 comfy 图像和视频工作流。
|
||||
当这些部分已配置时,Comfy live 文件也会覆盖 comfy 图像和视频工作流。
|
||||
|
||||
## 相关内容
|
||||
|
||||
@ -191,5 +275,5 @@ OPENCLAW_LIVE_TEST=1 COMFY_LIVE_TEST=1 pnpm test:live -- extensions/comfy/comfy.
|
||||
- [ComfyUI](/zh-CN/providers/comfy)
|
||||
- [Google(Gemini)](/zh-CN/providers/google)
|
||||
- [MiniMax](/zh-CN/providers/minimax)
|
||||
- [模型](/zh-CN/concepts/models) - 模型配置和故障转移
|
||||
- [模型](/zh-CN/concepts/models) - 模型配置和故障切换
|
||||
- [工具概览](/zh-CN/tools)
|
||||
|
||||
@ -1,152 +1,192 @@
|
||||
---
|
||||
read_when:
|
||||
- 通过智能体生成视频时
|
||||
- 配置视频生成提供商和模型时
|
||||
- 了解 `video_generate` 工具参数时
|
||||
summary: 使用 12 个提供商后端,从文本、图像或现有视频生成视频
|
||||
- 通过智能体生成视频
|
||||
- 配置视频生成 provider 和模型
|
||||
- 了解 `video_generate` 工具参数
|
||||
summary: 使用 12 个 provider 后端根据文本、图像或现有视频生成视频
|
||||
title: 视频生成
|
||||
x-i18n:
|
||||
generated_at: "2026-04-06T12:28:04Z"
|
||||
generated_at: "2026-04-06T15:32:14Z"
|
||||
model: gpt-5.4
|
||||
provider: openai
|
||||
source_hash: a224c0a1bd6fe61592ac22ad9a65f0ae25a378a12b79c1210f2e7101886798bb
|
||||
source_hash: 7d995d91f86f863f5a69c6945043dc430eb186830348a09eeaaad94620767f7d
|
||||
source_path: tools/video-generation.md
|
||||
workflow: 15
|
||||
---
|
||||
|
||||
# 视频生成
|
||||
|
||||
OpenClaw 智能体可以根据文本提示、参考图像或现有视频生成视频。支持 12 个提供商后端,每个后端具有不同的模型选项、输入模式和功能集。智能体会根据你的配置和可用的 API 密钥自动选择合适的提供商。
|
||||
OpenClaw 智能体可以根据文本提示词、参考图像或现有视频生成视频。支持 12 个 provider 后端,每个后端都有不同的模型选项、输入模式和功能集。智能体会根据你的配置和可用的 API 密钥自动选择合适的 provider。
|
||||
|
||||
<Note>
|
||||
只有在至少有一个视频生成提供商可用时,`video_generate` 工具才会出现。如果你没有在智能体工具中看到它,请设置提供商 API 密钥,或配置 `agents.defaults.videoGenerationModel`。
|
||||
只有在至少有一个视频生成 provider 可用时,`video_generate` 工具才会出现。如果你没有在智能体工具中看到它,请设置 provider API 密钥或配置 `agents.defaults.videoGenerationModel`。
|
||||
</Note>
|
||||
|
||||
OpenClaw 将视频生成视为三种运行时模式:
|
||||
|
||||
- `generate`:用于没有参考媒体的文生视频请求
|
||||
- `generate`:用于没有参考媒体的 text-to-video 请求
|
||||
- `imageToVideo`:当请求包含一个或多个参考图像时使用
|
||||
- `videoToVideo`:当请求包含一个或多个参考视频时使用
|
||||
|
||||
提供商可以支持这些模式中的任意子集。工具会在提交前验证当前模式,并在 `action=list` 中报告支持的模式。
|
||||
Providers 可以支持这些模式中的任意子集。工具会在提交前验证当前
|
||||
模式,并在 `action=list` 中报告支持的模式。
|
||||
|
||||
## 快速开始
|
||||
|
||||
1. 为任一受支持的提供商设置 API 密钥:
|
||||
1. 为任意受支持的 provider 设置 API 密钥:
|
||||
|
||||
```bash
|
||||
export GEMINI_API_KEY="your-key"
|
||||
```
|
||||
|
||||
2. 可选:固定一个默认模型:
|
||||
2. 可选地固定一个默认模型:
|
||||
|
||||
```bash
|
||||
openclaw config set agents.defaults.videoGenerationModel.primary "google/veo-3.1-fast-generate-preview"
|
||||
```
|
||||
|
||||
3. 向智能体提出请求:
|
||||
3. 向智能体发出请求:
|
||||
|
||||
> 生成一个 5 秒长、具有电影感的友善龙虾在日落时冲浪的视频。
|
||||
> 生成一个 5 秒钟的电影感视频:一只友好的龙虾在日落时冲浪。
|
||||
|
||||
智能体会自动调用 `video_generate`。无需对工具进行 allowlist 配置。
|
||||
智能体会自动调用 `video_generate`。不需要工具 allowlist。
|
||||
|
||||
## 生成视频时会发生什么
|
||||
|
||||
视频生成是异步的。当智能体在一个会话中调用 `video_generate` 时:
|
||||
视频生成是异步的。当智能体在会话中调用 `video_generate` 时:
|
||||
|
||||
1. OpenClaw 会将请求提交给提供商,并立即返回一个任务 ID。
|
||||
2. 提供商会在后台处理该任务(通常需要 30 秒到 5 分钟,具体取决于提供商和分辨率)。
|
||||
3. 当视频准备就绪时,OpenClaw 会通过内部完成事件唤醒同一个会话。
|
||||
4. 智能体会将完成的视频发布回原始对话中。
|
||||
1. OpenClaw 将请求提交给 provider,并立即返回一个任务 ID。
|
||||
2. Provider 在后台处理该任务(通常需要 30 秒到 5 分钟,取决于 provider 和分辨率)。
|
||||
3. 当视频准备就绪后,OpenClaw 会通过内部完成事件唤醒同一个会话。
|
||||
4. 智能体会将生成完成的视频发布回原始对话中。
|
||||
|
||||
当同一会话中已有任务正在进行时,重复调用 `video_generate` 不会启动新的生成,而是返回当前任务状态。使用 `openclaw tasks list` 或 `openclaw tasks show <taskId>` 可在 CLI 中检查进度。
|
||||
当同一会话中已有任务正在进行时,重复调用 `video_generate` 不会启动新的生成,而是返回当前任务状态。使用 `openclaw tasks list` 或 `openclaw tasks show <taskId>` 可以在 CLI 中检查进度。
|
||||
|
||||
在不依赖会话支持的智能体运行场景之外(例如直接调用工具),该工具会回退为内联生成,并在同一轮中返回最终媒体路径。
|
||||
在没有会话支持的智能体运行之外(例如直接工具调用),该工具会回退为内联生成,并在同一轮中返回最终媒体路径。
|
||||
|
||||
## 支持的提供商
|
||||
### 任务生命周期
|
||||
|
||||
| 提供商 | 默认模型 | 文本 | 图像参考 | 视频参考 | API 密钥 |
|
||||
| ------ | ------------------------------- | ---- | ----------------- | ---------------- | ---------------------------------------- |
|
||||
| Alibaba | `wan2.6-t2v` | 是 | 是(远程 URL) | 是(远程 URL) | `MODELSTUDIO_API_KEY` |
|
||||
| BytePlus | `seedance-1-0-lite-t2v-250428` | 是 | 1 张图像 | 否 | `BYTEPLUS_API_KEY` |
|
||||
| ComfyUI | `workflow` | 是 | 1 张图像 | 否 | `COMFY_API_KEY` 或 `COMFY_CLOUD_API_KEY` |
|
||||
| fal | `fal-ai/minimax/video-01-live` | 是 | 1 张图像 | 否 | `FAL_KEY` |
|
||||
| Google | `veo-3.1-fast-generate-preview` | 是 | 1 张图像 | 1 个视频 | `GEMINI_API_KEY` |
|
||||
| MiniMax | `MiniMax-Hailuo-2.3` | 是 | 1 张图像 | 否 | `MINIMAX_API_KEY` |
|
||||
| OpenAI | `sora-2` | 是 | 1 张图像 | 1 个视频 | `OPENAI_API_KEY` |
|
||||
| Qwen | `wan2.6-t2v` | 是 | 是(远程 URL) | 是(远程 URL) | `QWEN_API_KEY` |
|
||||
| Runway | `gen4.5` | 是 | 1 张图像 | 1 个视频 | `RUNWAYML_API_SECRET` |
|
||||
| Together | `Wan-AI/Wan2.2-T2V-A14B` | 是 | 1 张图像 | 否 | `TOGETHER_API_KEY` |
|
||||
| Vydra | `veo3` | 是 | 1 张图像(`kling`) | 否 | `VYDRA_API_KEY` |
|
||||
| xAI | `grok-imagine-video` | 是 | 1 张图像 | 1 个视频 | `XAI_API_KEY` |
|
||||
每个 `video_generate` 请求都会经历四种状态:
|
||||
|
||||
某些提供商接受额外或替代的 API 密钥环境变量。详见各个[提供商页面](#related)。
|
||||
1. **queued** -- 任务已创建,等待 provider 接受。
|
||||
2. **running** -- provider 正在处理(通常需要 30 秒到 5 分钟,取决于 provider 和分辨率)。
|
||||
3. **succeeded** -- 视频已准备好;智能体会被唤醒并将其发布到对话中。
|
||||
4. **failed** -- provider 错误或超时;智能体会带着错误详情被唤醒。
|
||||
|
||||
运行 `video_generate action=list` 可在运行时检查可用的提供商、模型和运行时模式。
|
||||
从 CLI 检查状态:
|
||||
|
||||
```bash
|
||||
openclaw tasks list
|
||||
openclaw tasks show <taskId>
|
||||
openclaw tasks cancel <taskId>
|
||||
```
|
||||
|
||||
防止重复:如果当前会话已有视频任务处于 `queued` 或 `running` 状态,`video_generate` 会返回现有任务状态,而不是启动新任务。使用 `action: "status"` 可以显式检查状态,而不触发新的生成。
|
||||
|
||||
## 支持的 providers
|
||||
|
||||
| Provider | 默认模型 | 文本 | 图像参考 | 视频参考 | API 密钥 |
|
||||
| -------- | ------------------------------- | ---- | ----------------- | ---------------- | ---------------------------------------- |
|
||||
| Alibaba | `wan2.6-t2v` | Yes | Yes(远程 URL) | Yes(远程 URL) | `MODELSTUDIO_API_KEY` |
|
||||
| BytePlus(国际版) | `seedance-1-0-lite-t2v-250428` | Yes | 1 张图像 | No | `BYTEPLUS_API_KEY` |
|
||||
| ComfyUI | `workflow` | Yes | 1 张图像 | No | `COMFY_API_KEY` 或 `COMFY_CLOUD_API_KEY` |
|
||||
| fal | `fal-ai/minimax/video-01-live` | Yes | 1 张图像 | No | `FAL_KEY` |
|
||||
| Google | `veo-3.1-fast-generate-preview` | Yes | 1 张图像 | 1 个视频 | `GEMINI_API_KEY` |
|
||||
| MiniMax | `MiniMax-Hailuo-2.3` | Yes | 1 张图像 | No | `MINIMAX_API_KEY` |
|
||||
| OpenAI | `sora-2` | Yes | 1 张图像 | 1 个视频 | `OPENAI_API_KEY` |
|
||||
| Qwen | `wan2.6-t2v` | Yes | Yes(远程 URL) | Yes(远程 URL) | `QWEN_API_KEY` |
|
||||
| Runway | `gen4.5` | Yes | 1 张图像 | 1 个视频 | `RUNWAYML_API_SECRET` |
|
||||
| Together | `Wan-AI/Wan2.2-T2V-A14B` | Yes | 1 张图像 | No | `TOGETHER_API_KEY` |
|
||||
| Vydra | `veo3` | Yes | 1 张图像(`kling`) | No | `VYDRA_API_KEY` |
|
||||
| xAI | `grok-imagine-video` | Yes | 1 张图像 | 1 个视频 | `XAI_API_KEY` |
|
||||
|
||||
某些 provider 接受额外的或替代的 API 密钥环境变量。详情请参见各个[provider 页面](#related)。
|
||||
|
||||
运行 `video_generate action=list` 可在运行时检查可用的 provider、模型和
|
||||
运行时模式。
|
||||
|
||||
### 声明的能力矩阵
|
||||
|
||||
这是 `video_generate`、合约测试和共享 live sweep 所使用的显式模式合约。
|
||||
|
||||
| Provider | `generate` | `imageToVideo` | `videoToVideo` | 当前共享 live lanes |
|
||||
| -------- | ---------- | -------------- | -------------- | ---------------------------------------------------------------------------------------------------------- |
|
||||
| Alibaba | Yes | Yes | Yes | `generate`、`imageToVideo`;跳过 `videoToVideo`,因为此 provider 需要远程 `http(s)` 视频 URL |
|
||||
| BytePlus(国际版) | Yes | Yes | No | `generate`、`imageToVideo` |
|
||||
| ComfyUI | Yes | Yes | No | 不在共享 sweep 中;特定 workflow 的覆盖由 Comfy 测试负责 |
|
||||
| fal | Yes | Yes | No | `generate`、`imageToVideo` |
|
||||
| Google | Yes | Yes | Yes | `generate`、`imageToVideo`、`videoToVideo` |
|
||||
| MiniMax | Yes | Yes | No | `generate`、`imageToVideo` |
|
||||
| OpenAI | Yes | Yes | Yes | `generate`、`imageToVideo`、`videoToVideo` |
|
||||
| Qwen | Yes | Yes | Yes | `generate`、`imageToVideo`;跳过 `videoToVideo`,因为此 provider 需要远程 `http(s)` 视频 URL |
|
||||
| Runway | Yes | Yes | Yes | `generate`、`imageToVideo`;仅当所选模型为 `runway/gen4_aleph` 时运行 `videoToVideo` |
|
||||
| Together | Yes | Yes | No | `generate`、`imageToVideo` |
|
||||
| Vydra | Yes | Yes | No | `generate`、`imageToVideo` |
|
||||
| xAI | Yes | Yes | Yes | `generate`、`imageToVideo`;跳过 `videoToVideo`,因为此 provider 当前需要远程 MP4 URL |
|
||||
|
||||
## 工具参数
|
||||
|
||||
### 必填
|
||||
|
||||
| 参数 | 类型 | 说明 |
|
||||
| -------- | ------ | --------------------------------------------------------------------------- |
|
||||
| `prompt` | string | 要生成视频的文本描述(对于 `action: "generate"` 为必填) |
|
||||
| 参数 | 类型 | 描述 |
|
||||
| --------- | ------ | ----------------------------------------------------------------------------- |
|
||||
| `prompt` | string | 要生成的视频文本描述(`action: "generate"` 时必填) |
|
||||
|
||||
### 内容输入
|
||||
|
||||
| 参数 | 类型 | 说明 |
|
||||
| -------- | -------- | ---------------------------- |
|
||||
| `image` | string | 单个参考图像(路径或 URL) |
|
||||
| `images` | string[] | 多个参考图像(最多 5 个) |
|
||||
| `video` | string | 单个参考视频(路径或 URL) |
|
||||
| `videos` | string[] | 多个参考视频(最多 4 个) |
|
||||
| 参数 | 类型 | 描述 |
|
||||
| --------- | -------- | ------------------------------------ |
|
||||
| `image` | string | 单个参考图像(路径或 URL) |
|
||||
| `images` | string[] | 多个参考图像(最多 5 个) |
|
||||
| `video` | string | 单个参考视频(路径或 URL) |
|
||||
| `videos` | string[] | 多个参考视频(最多 4 个) |
|
||||
|
||||
### 风格控制
|
||||
|
||||
| 参数 | 类型 | 说明 |
|
||||
| 参数 | 类型 | 描述 |
|
||||
| ----------------- | ------- | ------------------------------------------------------------------------ |
|
||||
| `aspectRatio` | string | `1:1`、`2:3`、`3:2`、`3:4`、`4:3`、`4:5`、`5:4`、`9:16`、`16:9`、`21:9` |
|
||||
| `resolution` | string | `480P`、`720P` 或 `1080P` |
|
||||
| `durationSeconds` | number | 目标时长(秒,四舍五入到提供商支持的最接近值) |
|
||||
| `size` | string | 当提供商支持时的尺寸提示 |
|
||||
| `audio` | boolean | 在支持时启用生成音频 |
|
||||
| `watermark` | boolean | 在支持时切换提供商水印 |
|
||||
| `resolution` | string | `480P`、`720P` 或 `1080P` |
|
||||
| `durationSeconds` | number | 目标时长(秒,会四舍五入到 provider 支持的最近值) |
|
||||
| `size` | string | 当 provider 支持时使用的尺寸提示 |
|
||||
| `audio` | boolean | 在支持时启用生成音频 |
|
||||
| `watermark` | boolean | 在支持时切换 provider 水印 |
|
||||
|
||||
### 高级
|
||||
|
||||
| 参数 | 类型 | 说明 |
|
||||
| ---------- | ------ | ------------------------------------------------- |
|
||||
| `action` | string | `"generate"`(默认)、`"status"` 或 `"list"` |
|
||||
| `model` | string | 提供商/模型覆盖(例如 `runway/gen4.5`) |
|
||||
| `filename` | string | 输出文件名提示 |
|
||||
| 参数 | 类型 | 描述 |
|
||||
| ---------- | ------ | ----------------------------------------------- |
|
||||
| `action` | string | `"generate"`(默认)、`"status"` 或 `"list"` |
|
||||
| `model` | string | provider/model 覆盖(例如 `runway/gen4.5`) |
|
||||
| `filename` | string | 输出文件名提示 |
|
||||
|
||||
并非所有提供商都支持全部参数。不支持的覆盖项会以尽力而为的方式被忽略,并在工具结果中报告为警告。硬性能力限制(例如参考输入过多)会在提交前直接失败。
|
||||
并非所有 provider 都支持所有参数。不支持的覆盖会尽力忽略,并在工具结果中报告为警告。硬性能力限制(例如参考输入过多)会在提交前直接失败。
|
||||
|
||||
参考输入也会决定运行时模式:
|
||||
参考输入还会决定运行时模式:
|
||||
|
||||
- 无参考媒体:`generate`
|
||||
- 任意图像参考:`imageToVideo`
|
||||
- 任意视频参考:`videoToVideo`
|
||||
|
||||
混合使用图像和视频参考并不是稳定的共享能力接口。
|
||||
建议每次请求只使用一种参考类型。
|
||||
混合图像与视频参考不是稳定的共享能力表面。
|
||||
每个请求优先只使用一种参考类型。
|
||||
|
||||
## 操作
|
||||
|
||||
- **generate**(默认)-- 根据给定提示和可选参考输入创建视频。
|
||||
- **generate**(默认)-- 根据给定提示词和可选参考输入创建视频。
|
||||
- **status** -- 检查当前会话中正在进行的视频任务状态,而不启动新的生成。
|
||||
- **list** -- 显示可用的提供商、模型及其能力。
|
||||
- **list** -- 显示可用的 provider、模型及其能力。
|
||||
|
||||
## 模型选择
|
||||
|
||||
生成视频时,OpenClaw 会按以下顺序解析模型:
|
||||
生成视频时,OpenClaw 按以下顺序解析模型:
|
||||
|
||||
1. **`model` 工具参数** -- 如果智能体在调用中指定了该参数。
|
||||
1. **`model` 工具参数** -- 如果智能体在调用中指定了它。
|
||||
2. **`videoGenerationModel.primary`** -- 来自配置。
|
||||
3. **`videoGenerationModel.fallbacks`** -- 按顺序尝试。
|
||||
4. **自动检测** -- 使用具有有效认证的提供商,先从当前默认提供商开始,然后按字母顺序尝试其余提供商。
|
||||
4. **自动检测** -- 使用具有有效身份验证的 providers,先从当前默认 provider 开始,然后按字母顺序尝试其余 providers。
|
||||
|
||||
如果某个提供商失败,会自动尝试下一个候选项。如果所有候选项都失败,错误中会包含每次尝试的详细信息。
|
||||
如果某个 provider 失败,会自动尝试下一个候选项。如果所有候选项都失败,错误中会包含每次尝试的详情。
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -161,26 +201,28 @@ openclaw config set agents.defaults.videoGenerationModel.primary "google/veo-3.1
|
||||
}
|
||||
```
|
||||
|
||||
## 提供商说明
|
||||
## Provider 说明
|
||||
|
||||
| 提供商 | 说明 |
|
||||
| ------ | ----------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| Alibaba | 使用 DashScope/Model Studio 异步端点。参考图像和视频必须是远程 `http(s)` URL。 |
|
||||
| BytePlus | 仅支持单张参考图像。 |
|
||||
| ComfyUI | 由工作流驱动的本地或云端执行。通过已配置图形支持文生视频和图生视频。 |
|
||||
| fal | 对长时间运行任务使用基于队列的流程。仅支持单张参考图像。 |
|
||||
| Google | 使用 Gemini/Veo。支持一个图像参考或一个视频参考。 |
|
||||
| MiniMax | 仅支持单张参考图像。 |
|
||||
| OpenAI | 仅转发 `size` 覆盖项。其他风格覆盖项(`aspectRatio`、`resolution`、`audio`、`watermark`)会被忽略,并附带警告。 |
|
||||
| Qwen | 与 Alibaba 使用相同的 DashScope 后端。参考输入必须是远程 `http(s)` URL;本地文件会在前期直接被拒绝。 |
|
||||
| Runway | 支持通过数据 URI 使用本地文件。视频转视频需要 `runway/gen4_aleph`。纯文本运行提供 `16:9` 和 `9:16` 宽高比。 |
|
||||
| Together | 仅支持单张参考图像。 |
|
||||
| Vydra | 直接使用 `https://www.vydra.ai/api/v1`,以避免认证在重定向中丢失。`veo3` 内置为仅文生视频;`kling` 需要远程图像 URL。 |
|
||||
| xAI | 支持文生视频、图生视频,以及远程视频编辑/扩展流程。 |
|
||||
| Provider | 说明 |
|
||||
| -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| Alibaba | 使用 DashScope/Model Studio 异步端点。参考图像和视频必须是远程 `http(s)` URL。 |
|
||||
| BytePlus(国际版) | 仅支持单张参考图像。 |
|
||||
| ComfyUI | 由 workflow 驱动的本地或云端执行。通过已配置图支持 text-to-video 和 image-to-video。 |
|
||||
| fal | 对长时间运行任务使用基于队列的流程。仅支持单张参考图像。 |
|
||||
| Google | 使用 Gemini/Veo。支持一张参考图像或一个参考视频。 |
|
||||
| MiniMax | 仅支持单张参考图像。 |
|
||||
| OpenAI | 只会转发 `size` 覆盖。其他风格覆盖(`aspectRatio`、`resolution`、`audio`、`watermark`)会被忽略并附带警告。 |
|
||||
| Qwen | 与 Alibaba 使用相同的 DashScope 后端。参考输入必须是远程 `http(s)` URL;本地文件会在一开始就被拒绝。 |
|
||||
| Runway | 通过 data URI 支持本地文件。video-to-video 需要 `runway/gen4_aleph`。纯文本运行暴露 `16:9` 和 `9:16` 宽高比。 |
|
||||
| Together | 仅支持单张参考图像。 |
|
||||
| Vydra | 直接使用 `https://www.vydra.ai/api/v1` 以避免丢失身份验证的重定向。`veo3` 内置为仅 text-to-video;`kling` 需要远程图像 URL。 |
|
||||
| xAI | 支持 text-to-video、image-to-video,以及远程视频编辑/扩展流程。 |
|
||||
|
||||
## 提供商能力模式
|
||||
## Provider 能力模式
|
||||
|
||||
共享的视频生成契约现在允许提供商声明按模式划分的能力,而不只是扁平的聚合限制。新的提供商实现应优先使用显式模式块:
|
||||
共享视频生成合约现在允许 providers 声明特定模式的
|
||||
能力,而不是只声明扁平的聚合限制。新的 provider
|
||||
实现应优先使用显式模式块:
|
||||
|
||||
```typescript
|
||||
capabilities: {
|
||||
@ -204,7 +246,31 @@ capabilities: {
|
||||
}
|
||||
```
|
||||
|
||||
旧的扁平字段,如 `maxInputImages` 和 `maxInputVideos`,仍可作为向后兼容的聚合上限使用,但它们无法同样精确地表达按模式划分的限制。
|
||||
像 `maxInputImages` 和 `maxInputVideos` 这样的扁平聚合字段,不足以表达变换模式支持。Providers 应显式声明
|
||||
`generate`、`imageToVideo` 和 `videoToVideo`,这样 live tests、
|
||||
合约测试和共享 `video_generate` 工具才能以确定性的方式验证模式支持。
|
||||
|
||||
## Live tests
|
||||
|
||||
针对共享内置 providers 的选择接入 live 覆盖:
|
||||
|
||||
```bash
|
||||
OPENCLAW_LIVE_TEST=1 pnpm test:live -- extensions/video-generation-providers.live.test.ts
|
||||
```
|
||||
|
||||
该 live 文件会从 `~/.profile` 加载缺失的 provider 环境变量,默认优先使用
|
||||
live/env API 密钥而不是已存储的 auth profiles,并运行它能够用本地媒体安全执行的已声明模式:
|
||||
|
||||
- 对 sweep 中每个 provider 执行 `generate`
|
||||
- 当 `capabilities.imageToVideo.enabled` 时执行 `imageToVideo`
|
||||
- 当 `capabilities.videoToVideo.enabled` 且 provider/model
|
||||
在共享 sweep 中接受基于缓冲区的本地视频输入时执行 `videoToVideo`
|
||||
|
||||
目前共享 `videoToVideo` live lane 覆盖:
|
||||
|
||||
- `google`
|
||||
- `openai`
|
||||
- `runway`,仅当你选择 `runway/gen4_aleph`
|
||||
|
||||
## 配置
|
||||
|
||||
@ -223,7 +289,7 @@ capabilities: {
|
||||
}
|
||||
```
|
||||
|
||||
或通过 CLI:
|
||||
或者通过 CLI:
|
||||
|
||||
```bash
|
||||
openclaw config set agents.defaults.videoGenerationModel.primary "qwen/wan2.6-t2v"
|
||||
|
||||
@ -1,456 +1,13 @@
|
||||
---
|
||||
read_when:
|
||||
- 启用回复文本转语音
|
||||
- 配置 TTS 提供商或限制
|
||||
- 使用 `/tts` 命令
|
||||
summary: 用于出站回复的文本转语音(TTS)
|
||||
title: 文本转语音(TTS)(旧版路径)
|
||||
redirect: /tools/tts
|
||||
title: 文本转语音
|
||||
x-i18n:
|
||||
generated_at: "2026-04-05T10:13:31Z"
|
||||
generated_at: "2026-04-06T15:31:37Z"
|
||||
model: gpt-5.4
|
||||
provider: openai
|
||||
source_hash: acca61773996299a582ab88e5a5db12d8f22ce8a28292ce97cc5dd5fdc2d3b83
|
||||
source_hash: 0c9ace272aa9adff93c946ee6275f6eb314dc1fa5043e0a26ecb164c990c0c59
|
||||
source_path: tts.md
|
||||
workflow: 15
|
||||
---
|
||||
|
||||
# 文本转语音(TTS)
|
||||
|
||||
OpenClaw 可以使用 ElevenLabs、Microsoft、MiniMax 或 OpenAI 将出站回复转换为音频。
|
||||
凡是 OpenClaw 能发送音频的地方,它都可以工作。
|
||||
|
||||
## 支持的服务
|
||||
|
||||
- **ElevenLabs**(主提供商或回退提供商)
|
||||
- **Microsoft**(主提供商或回退提供商;当前内置实现使用 `node-edge-tts`)
|
||||
- **MiniMax**(主提供商或回退提供商;使用 T2A v2 API)
|
||||
- **OpenAI**(主提供商或回退提供商;也用于摘要)
|
||||
|
||||
### Microsoft speech 说明
|
||||
|
||||
当前内置的 Microsoft speech 提供商通过 `node-edge-tts` 库使用 Microsoft Edge 的在线
|
||||
神经 TTS 服务。这是一项托管服务(不是本地服务),使用 Microsoft 端点,并且不需要 API 密钥。
|
||||
`node-edge-tts` 暴露了语音配置选项和输出格式,但并非所有选项都受到该服务支持。使用 `edge` 的旧版配置和指令输入
|
||||
仍然有效,并会被规范化为 `microsoft`。
|
||||
|
||||
由于这一路径是公开 Web 服务,没有已发布的 SLA 或配额,
|
||||
请将其视为尽力而为。如果你需要有保障的限制和支持,请使用 OpenAI
|
||||
或 ElevenLabs。
|
||||
|
||||
## 可选密钥
|
||||
|
||||
如果你想使用 OpenAI、ElevenLabs 或 MiniMax:
|
||||
|
||||
- `ELEVENLABS_API_KEY`(或 `XI_API_KEY`)
|
||||
- `MINIMAX_API_KEY`
|
||||
- `OPENAI_API_KEY`
|
||||
|
||||
Microsoft speech **不**需要 API 密钥。
|
||||
|
||||
如果配置了多个提供商,则会先使用已选提供商,其他提供商会作为回退选项。
|
||||
自动摘要会使用已配置的 `summaryModel`(或 `agents.defaults.model.primary`),
|
||||
因此如果你启用了摘要,该提供商也必须已完成认证。
|
||||
|
||||
## 服务链接
|
||||
|
||||
- [OpenAI 文本转语音指南](https://platform.openai.com/docs/guides/text-to-speech)
|
||||
- [OpenAI Audio API 参考](https://platform.openai.com/docs/api-reference/audio)
|
||||
- [ElevenLabs 文本转语音](https://elevenlabs.io/docs/api-reference/text-to-speech)
|
||||
- [ElevenLabs 认证](https://elevenlabs.io/docs/api-reference/authentication)
|
||||
- [MiniMax T2A v2 API](https://platform.minimaxi.com/document/T2A%20V2)
|
||||
- [node-edge-tts](https://github.com/SchneeHertz/node-edge-tts)
|
||||
- [Microsoft Speech 输出格式](https://learn.microsoft.com/azure/ai-services/speech-service/rest-text-to-speech#audio-outputs)
|
||||
|
||||
## 默认启用吗?
|
||||
|
||||
不是。自动 TTS 默认**关闭**。可在配置中通过
|
||||
`messages.tts.auto` 启用,或按会话使用 `/tts always`(别名:`/tts on`)启用。
|
||||
|
||||
当未设置 `messages.tts.provider` 时,OpenClaw 会按照注册表自动选择顺序选取第一个已配置的
|
||||
speech 提供商。
|
||||
|
||||
## 配置
|
||||
|
||||
TTS 配置位于 `openclaw.json` 中的 `messages.tts` 下。
|
||||
完整 schema 见 [Gateway 网关配置](/zh-CN/gateway/configuration)。
|
||||
|
||||
### 最小配置(启用 + 提供商)
|
||||
|
||||
```json5
|
||||
{
|
||||
messages: {
|
||||
tts: {
|
||||
auto: "always",
|
||||
provider: "elevenlabs",
|
||||
},
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
### OpenAI 主提供商,ElevenLabs 回退
|
||||
|
||||
```json5
|
||||
{
|
||||
messages: {
|
||||
tts: {
|
||||
auto: "always",
|
||||
provider: "openai",
|
||||
summaryModel: "openai/gpt-4.1-mini",
|
||||
modelOverrides: {
|
||||
enabled: true,
|
||||
},
|
||||
providers: {
|
||||
openai: {
|
||||
apiKey: "openai_api_key",
|
||||
baseUrl: "https://api.openai.com/v1",
|
||||
model: "gpt-4o-mini-tts",
|
||||
voice: "alloy",
|
||||
},
|
||||
elevenlabs: {
|
||||
apiKey: "elevenlabs_api_key",
|
||||
baseUrl: "https://api.elevenlabs.io",
|
||||
voiceId: "voice_id",
|
||||
modelId: "eleven_multilingual_v2",
|
||||
seed: 42,
|
||||
applyTextNormalization: "auto",
|
||||
languageCode: "en",
|
||||
voiceSettings: {
|
||||
stability: 0.5,
|
||||
similarityBoost: 0.75,
|
||||
style: 0.0,
|
||||
useSpeakerBoost: true,
|
||||
speed: 1.0,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
### Microsoft 主提供商(无 API 密钥)
|
||||
|
||||
```json5
|
||||
{
|
||||
messages: {
|
||||
tts: {
|
||||
auto: "always",
|
||||
provider: "microsoft",
|
||||
providers: {
|
||||
microsoft: {
|
||||
enabled: true,
|
||||
voice: "en-US-MichelleNeural",
|
||||
lang: "en-US",
|
||||
outputFormat: "audio-24khz-48kbitrate-mono-mp3",
|
||||
rate: "+10%",
|
||||
pitch: "-5%",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
### MiniMax 主提供商
|
||||
|
||||
```json5
|
||||
{
|
||||
messages: {
|
||||
tts: {
|
||||
auto: "always",
|
||||
provider: "minimax",
|
||||
providers: {
|
||||
minimax: {
|
||||
apiKey: "minimax_api_key",
|
||||
baseUrl: "https://api.minimax.io",
|
||||
model: "speech-2.8-hd",
|
||||
voiceId: "English_expressive_narrator",
|
||||
speed: 1.0,
|
||||
vol: 1.0,
|
||||
pitch: 0,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
### 禁用 Microsoft speech
|
||||
|
||||
```json5
|
||||
{
|
||||
messages: {
|
||||
tts: {
|
||||
providers: {
|
||||
microsoft: {
|
||||
enabled: false,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
### 自定义限制 + prefs 路径
|
||||
|
||||
```json5
|
||||
{
|
||||
messages: {
|
||||
tts: {
|
||||
auto: "always",
|
||||
maxTextLength: 4000,
|
||||
timeoutMs: 30000,
|
||||
prefsPath: "~/.openclaw/settings/tts.json",
|
||||
},
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
### 仅在收到入站语音消息后以音频回复
|
||||
|
||||
```json5
|
||||
{
|
||||
messages: {
|
||||
tts: {
|
||||
auto: "inbound",
|
||||
},
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
### 为长回复禁用自动摘要
|
||||
|
||||
```json5
|
||||
{
|
||||
messages: {
|
||||
tts: {
|
||||
auto: "always",
|
||||
},
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
然后运行:
|
||||
|
||||
```
|
||||
/tts summary off
|
||||
```
|
||||
|
||||
### 字段说明
|
||||
|
||||
- `auto`:自动 TTS 模式(`off`、`always`、`inbound`、`tagged`)。
|
||||
- `inbound` 仅在收到入站语音消息后发送音频。
|
||||
- `tagged` 仅在回复包含 `[[tts]]` 标签时发送音频。
|
||||
- `enabled`:旧版开关(Doctor 会将其迁移到 `auto`)。
|
||||
- `mode`:`"final"`(默认)或 `"all"`(包括工具/块回复)。
|
||||
- `provider`:speech 提供商 id,例如 `"elevenlabs"`、`"microsoft"`、`"minimax"` 或 `"openai"`(回退自动处理)。
|
||||
- 如果**未设置** `provider`,OpenClaw 会按注册表自动选择顺序使用第一个已配置的 speech 提供商。
|
||||
- 旧版 `provider: "edge"` 仍然有效,并会被规范化为 `microsoft`。
|
||||
- `summaryModel`:用于自动摘要的可选低成本模型;默认使用 `agents.defaults.model.primary`。
|
||||
- 接受 `provider/model` 或已配置的模型别名。
|
||||
- `modelOverrides`:允许模型发出 TTS 指令(默认开启)。
|
||||
- `allowProvider` 默认为 `false`(提供商切换需显式启用)。
|
||||
- `providers.<id>`:由提供商拥有的设置,以 speech 提供商 id 作为键。
|
||||
- 旧版直接提供商块(`messages.tts.openai`、`messages.tts.elevenlabs`、`messages.tts.microsoft`、`messages.tts.edge`)会在加载时自动迁移到 `messages.tts.providers.<id>`。
|
||||
- `maxTextLength`:TTS 输入的硬上限(字符数)。超出时 `/tts audio` 会失败。
|
||||
- `timeoutMs`:请求超时(毫秒)。
|
||||
- `prefsPath`:覆盖本地 prefs JSON 路径(提供商/限制/摘要)。
|
||||
- `apiKey` 值会回退到环境变量(`ELEVENLABS_API_KEY`/`XI_API_KEY`、`MINIMAX_API_KEY`、`OPENAI_API_KEY`)。
|
||||
- `providers.elevenlabs.baseUrl`:覆盖 ElevenLabs API base URL。
|
||||
- `providers.openai.baseUrl`:覆盖 OpenAI TTS 端点。
|
||||
- 解析顺序:`messages.tts.providers.openai.baseUrl` -> `OPENAI_TTS_BASE_URL` -> `https://api.openai.com/v1`
|
||||
- 非默认值会被视为 OpenAI-compatible TTS 端点,因此接受自定义模型名和语音名。
|
||||
- `providers.elevenlabs.voiceSettings`:
|
||||
- `stability`、`similarityBoost`、`style`:`0..1`
|
||||
- `useSpeakerBoost`:`true|false`
|
||||
- `speed`:`0.5..2.0`(1.0 = 正常)
|
||||
- `providers.elevenlabs.applyTextNormalization`:`auto|on|off`
|
||||
- `providers.elevenlabs.languageCode`:双字母 ISO 639-1(例如 `en`、`de`)
|
||||
- `providers.elevenlabs.seed`:整数 `0..4294967295`(尽力保证确定性)
|
||||
- `providers.minimax.baseUrl`:覆盖 MiniMax API base URL(默认 `https://api.minimax.io`,环境变量:`MINIMAX_API_HOST`)。
|
||||
- `providers.minimax.model`:TTS 模型(默认 `speech-2.8-hd`,环境变量:`MINIMAX_TTS_MODEL`)。
|
||||
- `providers.minimax.voiceId`:语音标识符(默认 `English_expressive_narrator`,环境变量:`MINIMAX_TTS_VOICE_ID`)。
|
||||
- `providers.minimax.speed`:播放速度 `0.5..2.0`(默认 1.0)。
|
||||
- `providers.minimax.vol`:音量 `(0, 10]`(默认 1.0;必须大于 0)。
|
||||
- `providers.minimax.pitch`:音高偏移 `-12..12`(默认 0)。
|
||||
- `providers.microsoft.enabled`:允许使用 Microsoft speech(默认 `true`;无 API 密钥)。
|
||||
- `providers.microsoft.voice`:Microsoft 神经语音名称(例如 `en-US-MichelleNeural`)。
|
||||
- `providers.microsoft.lang`:语言代码(例如 `en-US`)。
|
||||
- `providers.microsoft.outputFormat`:Microsoft 输出格式(例如 `audio-24khz-48kbitrate-mono-mp3`)。
|
||||
- 有效值请参见 Microsoft Speech 输出格式;并非所有格式都受内置的 Edge 支持传输支持。
|
||||
- `providers.microsoft.rate` / `providers.microsoft.pitch` / `providers.microsoft.volume`:百分比字符串(例如 `+10%`、`-5%`)。
|
||||
- `providers.microsoft.saveSubtitles`:在音频文件旁边写入 JSON 字幕。
|
||||
- `providers.microsoft.proxy`:Microsoft speech 请求的代理 URL。
|
||||
- `providers.microsoft.timeoutMs`:请求超时覆盖(毫秒)。
|
||||
- `edge.*`:同一组 Microsoft 设置的旧版别名。
|
||||
|
||||
## 模型驱动覆盖(默认开启)
|
||||
|
||||
默认情况下,模型**可以**为单条回复发出 TTS 指令。
|
||||
当 `messages.tts.auto` 为 `tagged` 时,这些指令是触发音频所必需的。
|
||||
|
||||
启用后,模型可以发出 `[[tts:...]]` 指令来覆盖单条回复的语音,
|
||||
还可以附加一个可选的 `[[tts:text]]...[[/tts:text]]` 块,
|
||||
用于提供表达性标签(笑声、歌唱提示等),这些内容应仅出现在
|
||||
音频中。
|
||||
|
||||
除非设置 `modelOverrides.allowProvider: true`,否则 `provider=...` 指令会被忽略。
|
||||
|
||||
回复载荷示例:
|
||||
|
||||
```
|
||||
Here you go.
|
||||
|
||||
[[tts:voiceId=pMsXgVXv3BLzUgSXRplE model=eleven_v3 speed=1.1]]
|
||||
[[tts:text]](laughs) Read the song once more.[[/tts:text]]
|
||||
```
|
||||
|
||||
可用指令键(启用时):
|
||||
|
||||
- `provider`(已注册的 speech 提供商 id,例如 `openai`、`elevenlabs`、`minimax` 或 `microsoft`;需要 `allowProvider: true`)
|
||||
- `voice`(OpenAI 语音)或 `voiceId`(ElevenLabs / MiniMax)
|
||||
- `model`(OpenAI TTS 模型、ElevenLabs model id 或 MiniMax 模型)
|
||||
- `stability`、`similarityBoost`、`style`、`speed`、`useSpeakerBoost`
|
||||
- `vol` / `volume`(MiniMax 音量,0-10)
|
||||
- `pitch`(MiniMax 音高,-12 到 12)
|
||||
- `applyTextNormalization`(`auto|on|off`)
|
||||
- `languageCode`(ISO 639-1)
|
||||
- `seed`
|
||||
|
||||
禁用所有模型覆盖:
|
||||
|
||||
```json5
|
||||
{
|
||||
messages: {
|
||||
tts: {
|
||||
modelOverrides: {
|
||||
enabled: false,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
可选允许列表(启用提供商切换,同时保持其他参数可配置):
|
||||
|
||||
```json5
|
||||
{
|
||||
messages: {
|
||||
tts: {
|
||||
modelOverrides: {
|
||||
enabled: true,
|
||||
allowProvider: true,
|
||||
allowSeed: false,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
## 按用户偏好
|
||||
|
||||
Slash Commands 会将本地覆盖写入 `prefsPath`(默认:
|
||||
`~/.openclaw/settings/tts.json`,可通过 `OPENCLAW_TTS_PREFS` 或
|
||||
`messages.tts.prefsPath` 覆盖)。
|
||||
|
||||
存储字段:
|
||||
|
||||
- `enabled`
|
||||
- `provider`
|
||||
- `maxLength`(摘要阈值;默认 1500 字符)
|
||||
- `summarize`(默认 `true`)
|
||||
|
||||
这些值会覆盖该主机上的 `messages.tts.*`。
|
||||
|
||||
## 输出格式(固定)
|
||||
|
||||
- **Feishu / Matrix / Telegram / WhatsApp**:Opus 语音消息(ElevenLabs 使用 `opus_48000_64`,OpenAI 使用 `opus`)。
|
||||
- 48 kHz / 64 kbps 是语音消息的良好折中。
|
||||
- **其他渠道**:MP3(ElevenLabs 使用 `mp3_44100_128`,OpenAI 使用 `mp3`)。
|
||||
- 44.1 kHz / 128 kbps 是语音清晰度的默认平衡点。
|
||||
- **MiniMax**:MP3(`speech-2.8-hd` 模型,32 kHz 采样率)。原生不支持语音便笺格式;如果你需要有保障的 Opus 语音消息,请使用 OpenAI 或 ElevenLabs。
|
||||
- **Microsoft**:使用 `microsoft.outputFormat`(默认 `audio-24khz-48kbitrate-mono-mp3`)。
|
||||
- 内置传输接受 `outputFormat`,但该服务并不提供所有格式。
|
||||
- 输出格式值遵循 Microsoft Speech 输出格式(包括 Ogg/WebM Opus)。
|
||||
- Telegram `sendVoice` 接受 OGG/MP3/M4A;如果你需要
|
||||
有保障的 Opus 语音消息,请使用 OpenAI/ElevenLabs。
|
||||
- 如果已配置的 Microsoft 输出格式失败,OpenClaw 会重试 MP3。
|
||||
|
||||
OpenAI/ElevenLabs 的输出格式按渠道固定(见上文)。
|
||||
|
||||
## 自动 TTS 行为
|
||||
|
||||
启用后,OpenClaw 会:
|
||||
|
||||
- 如果回复已经包含媒体或 `MEDIA:` 指令,则跳过 TTS。
|
||||
- 跳过过短回复(少于 10 个字符)。
|
||||
- 在启用时使用 `agents.defaults.model.primary`(或 `summaryModel`)对长回复进行摘要。
|
||||
- 将生成的音频附加到回复上。
|
||||
|
||||
如果回复超过 `maxLength` 且摘要已关闭(或摘要模型没有 API 密钥),则会跳过音频,
|
||||
发送普通文本回复。
|
||||
|
||||
## 流程图
|
||||
|
||||
```
|
||||
Reply -> TTS enabled?
|
||||
no -> send text
|
||||
yes -> has media / MEDIA: / short?
|
||||
yes -> send text
|
||||
no -> length > limit?
|
||||
no -> TTS -> attach audio
|
||||
yes -> summary enabled?
|
||||
no -> send text
|
||||
yes -> summarize (summaryModel or agents.defaults.model.primary)
|
||||
-> TTS -> attach audio
|
||||
```
|
||||
|
||||
## Slash Commands 用法
|
||||
|
||||
只有一个命令:`/tts`。
|
||||
启用细节见 [Slash Commands](/zh-CN/tools/slash-commands)。
|
||||
|
||||
Discord 说明:`/tts` 是 Discord 内置命令,因此 OpenClaw 会在那里注册
|
||||
`/voice` 作为原生命令。文本形式的 `/tts ...` 仍然有效。
|
||||
|
||||
```
|
||||
/tts off
|
||||
/tts always
|
||||
/tts inbound
|
||||
/tts tagged
|
||||
/tts status
|
||||
/tts provider openai
|
||||
/tts limit 2000
|
||||
/tts summary off
|
||||
/tts audio Hello from OpenClaw
|
||||
```
|
||||
|
||||
说明:
|
||||
|
||||
- 这些命令需要授权发送者(允许列表/所有者规则仍然适用)。
|
||||
- 必须启用 `commands.text` 或原生命令注册。
|
||||
- `off|always|inbound|tagged` 是按会话切换(`/tts on` 是 `/tts always` 的别名)。
|
||||
- `limit` 和 `summary` 存储在本地 prefs 中,而不是主配置中。
|
||||
- `/tts audio` 会生成一次性音频回复(不会开启 TTS)。
|
||||
- `/tts status` 包含最近一次尝试的回退可见性:
|
||||
- 成功回退:`Fallback: <primary> -> <used>` 加 `Attempts: ...`
|
||||
- 失败:`Error: ...` 加 `Attempts: ...`
|
||||
- 详细诊断:`Attempt details: provider:outcome(reasonCode) latency`
|
||||
- OpenAI 和 ElevenLabs API 失败现在会包含已解析的提供商错误详情和请求 id(当提供商返回时),这些信息会体现在 TTS 错误/日志中。
|
||||
|
||||
## 智能体工具
|
||||
|
||||
`tts` 工具会将文本转换为语音,并返回一个用于
|
||||
回复投递的音频附件。当渠道为 Feishu、Matrix、Telegram 或 WhatsApp 时,
|
||||
音频会作为语音消息而不是文件附件进行投递。
|
||||
|
||||
## Gateway 网关 RPC
|
||||
|
||||
Gateway 网关方法:
|
||||
|
||||
- `tts.status`
|
||||
- `tts.enable`
|
||||
- `tts.disable`
|
||||
- `tts.convert`
|
||||
- `tts.setProvider`
|
||||
- `tts.providers`
|
||||
此页面已迁移至 [文本转语音](/zh-CN/tools/tts)。
|
||||
|
||||
Loading…
Reference in New Issue
Block a user