From abb5be6c9d164bb80eb8deec06ce927d0e4c1763 Mon Sep 17 00:00:00 2001 From: "openclaw-docs-i18n[bot]" Date: Thu, 23 Apr 2026 06:50:19 +0000 Subject: [PATCH] chore(i18n): refresh zh-CN translations --- docs/zh-CN/AGENTS.md | 32 +- docs/zh-CN/automation/poll.md | 8 +- docs/zh-CN/channels/bluebubbles.md | 277 +-- docs/zh-CN/channels/channel-routing.md | 62 +- docs/zh-CN/channels/feishu.md | 144 +- docs/zh-CN/channels/irc.md | 84 +- docs/zh-CN/channels/mattermost.md | 268 +-- docs/zh-CN/channels/msteams.md | 410 ++--- docs/zh-CN/cli/plugins.md | 119 +- docs/zh-CN/cli/security.md | 59 +- docs/zh-CN/cli/update.md | 96 +- docs/zh-CN/concepts/dreaming.md | 143 +- docs/zh-CN/gateway/configuration-reference.md | 1531 +++++++++-------- docs/zh-CN/help/testing.md | 939 +++++----- docs/zh-CN/install/docker.md | 201 +-- docs/zh-CN/install/hostinger.md | 48 +- docs/zh-CN/install/northflank.mdx | 44 +- docs/zh-CN/install/podman.md | 126 +- docs/zh-CN/install/railway.mdx | 60 +- docs/zh-CN/install/render.mdx | 102 +- docs/zh-CN/plugins/architecture.md | 1196 ++++++++----- docs/zh-CN/providers/anthropic.md | 138 +- docs/zh-CN/providers/bedrock-mantle.md | 94 +- docs/zh-CN/providers/deepgram.md | 48 +- docs/zh-CN/providers/index.md | 27 +- docs/zh-CN/providers/litellm.md | 53 +- docs/zh-CN/providers/lmstudio.md | 66 +- docs/zh-CN/providers/mistral.md | 68 +- docs/zh-CN/providers/moonshot.md | 128 +- docs/zh-CN/providers/openai.md | 166 +- docs/zh-CN/providers/qwen.md | 151 +- docs/zh-CN/providers/tencent.md | 23 +- docs/zh-CN/providers/volcengine.md | 87 +- ...exec-duplicate-completion-investigation.md | 103 +- docs/zh-CN/refactor/qa.md | 286 +-- docs/zh-CN/reference/rich-output-protocol.md | 33 +- docs/zh-CN/reference/transcript-hygiene.md | 109 +- docs/zh-CN/start/hubs.md | 94 +- docs/zh-CN/start/showcase.md | 176 +- docs/zh-CN/tools/index.md | 183 +- docs/zh-CN/tools/plugin.md | 219 ++- docs/zh-CN/tools/skills-config.md | 80 +- docs/zh-CN/tools/slash-commands.md | 257 +-- docs/zh-CN/tts.md | 7 +- docs/zh-CN/web/control-ui.md | 300 ++-- 45 files changed, 4704 insertions(+), 4141 deletions(-) diff --git a/docs/zh-CN/AGENTS.md b/docs/zh-CN/AGENTS.md index 94ae54356..e5c4ed3de 100644 --- a/docs/zh-CN/AGENTS.md +++ b/docs/zh-CN/AGENTS.md @@ -1,38 +1,38 @@ --- x-i18n: - generated_at: "2026-04-12T08:32:18Z" + generated_at: "2026-04-23T06:39:57Z" model: gpt-5.4 provider: openai - source_hash: 6805814012caac6ff64f17f44f393975510c5af3421fae9651ed9033e5861784 + source_hash: 8b046833f9a15dc61894ab9e808a09a9fb055ef7ada5c3d4893fbe5f70dec126 source_path: AGENTS.md workflow: 15 --- # 文档指南 -本目录负责文档编写、Mintlify 链接规则以及文档 i18n 策略。 +此目录负责文档编写、Mintlify 链接规则以及文档 i18n 策略。 ## Mintlify 规则 -- 文档托管在 Mintlify(`https://docs.openclaw.ai`)。 -- `docs/**/*.md` 中的内部文档链接必须保持为根相对路径,且不带 `.md` 或 `.mdx` 后缀(例如:`[Config](/configuration)`)。 -- 章节交叉引用应在根相对路径上使用锚点(例如:`[Hooks](/configuration#hooks)`)。 +- 文档托管在 Mintlify(`https://docs.openclaw.ai`)上。 +- `docs/**/*.md` 中的内部文档链接必须保持为根相对路径,且不带 `.md` 或 `.mdx` 后缀(示例:`[配置](/gateway/configuration)`)。 +- 章节交叉引用应在根相对路径上使用锚点(示例:`[Hooks](/gateway/configuration-reference#hooks)`)。 - 文档标题应避免使用长破折号和撇号,因为 Mintlify 的锚点生成在这些情况下不稳定。 -- README 和其他在 GitHub 上渲染的文档应保留绝对文档 URL,这样链接在 Mintlify 之外也能正常工作。 +- README 和其他在 GitHub 上渲染的文档应保留绝对文档 URL,以确保链接在 Mintlify 之外也能正常工作。 - 文档内容必须保持通用:不要使用个人设备名称、主机名或本地路径;请使用类似 `user@gateway-host` 的占位符。 ## 文档内容规则 -- 对于文档、UI 文案和选择器列表,服务 / 提供商应按字母顺序排列,除非该部分明确是在描述运行时顺序或自动检测顺序。 -- 保持内置插件命名与根目录 `AGENTS.md` 中的全仓库插件术语规则一致。 +- 对于文档、UI 文案和选择器列表,服务/提供商应按字母顺序排列,除非该部分明确是在描述运行时顺序或自动检测顺序。 +- 保持内置 plugin 的命名与根 `AGENTS.md` 中的全仓库 plugin 术语规则一致。 ## 文档 i18n -- 本仓库不维护外语文档。生成后的发布输出位于单独的 `openclaw/docs` 仓库中(本地通常克隆为 `../openclaw-docs`)。 -- 不要在此处新增或编辑 `docs//**` 下的本地化文档。 -- 将本仓库中的英文文档和术语表文件视为事实来源。 -- 流程:先在这里更新英文文档,再按需更新 `docs/.i18n/glossary..json`,然后让发布仓库同步,并在 `openclaw/docs` 中运行 `scripts/docs-i18n`。 -- 在重新运行 `scripts/docs-i18n` 之前,为任何新的技术术语、页面标题或必须保持英文或使用固定译法的简短导航标签添加术语表条目。 -- `pnpm docs:check-i18n-glossary` 是用于检查英文文档标题和简短内部文档标签变更的守卫命令。 -- 翻译记忆存储在发布仓库中生成的 `docs/.i18n/*.tm.jsonl` 文件里。 +- 此仓库不维护外语文档。生成后的发布输出位于单独的 `openclaw/docs` 仓库中(本地通常克隆为 `../openclaw-docs`)。 +- 不要在此仓库中的 `docs//**` 下添加或编辑本地化文档。 +- 将此仓库中的英文文档以及术语表文件视为唯一事实来源。 +- 流程:先在此处更新英文文档,再按需要更新 `docs/.i18n/glossary..json`,然后让发布仓库同步,并在 `openclaw/docs` 中运行 `scripts/docs-i18n`。 +- 在重新运行 `scripts/docs-i18n` 之前,为任何必须保留英文或需要固定译法的新技术术语、页面标题或简短导航标签添加术语表条目。 +- `pnpm docs:check-i18n-glossary` 是用于检查已变更英文文档标题和简短内部文档标签的守卫命令。 +- 翻译记忆库存储在发布仓库中生成的 `docs/.i18n/*.tm.jsonl` 文件里。 - 参见 `docs/.i18n/README.md`。 diff --git a/docs/zh-CN/automation/poll.md b/docs/zh-CN/automation/poll.md index 3a6ae0bf2..c7bd9da7d 100644 --- a/docs/zh-CN/automation/poll.md +++ b/docs/zh-CN/automation/poll.md @@ -1,15 +1,15 @@ --- -summary: 重定向到 /tools/message +summary: 重定向到 /cli/message title: 投票 x-i18n: - generated_at: "2026-04-05T08:12:47Z" + generated_at: "2026-04-23T06:40:04Z" model: gpt-5.4 provider: openai - source_hash: 8d69432ad8ba5fd80b59f8df779a1105ce0a2ff767d7dd5dc9d8e3ac1cb1ff1f + source_hash: 0639c4d35678e5cb0d3a262e2db9cd8db1e25e3eb26adc28bf76b5df14e5446f source_path: automation/poll.md workflow: 15 --- # 投票 -本页已迁移至 [消息工具](/cli/message)。有关投票文档,请参见 [消息工具](/cli/message)。 +本页已移至 [消息工具](/zh-CN/cli/message)。有关投票文档,请参阅 [消息工具](/zh-CN/cli/message)。 diff --git a/docs/zh-CN/channels/bluebubbles.md b/docs/zh-CN/channels/bluebubbles.md index ff76acf55..df27a2efd 100644 --- a/docs/zh-CN/channels/bluebubbles.md +++ b/docs/zh-CN/channels/bluebubbles.md @@ -1,37 +1,38 @@ --- read_when: - 设置 BlueBubbles 渠道 - - Webhook 配对故障排除 + - 故障排除 webhook 配对 - 在 macOS 上配置 iMessage -summary: 通过 BlueBubbles macOS 服务器接入 iMessage(REST 发送/接收、正在输入、表情回应、配对、高级操作)。 +summary: 通过 BlueBubbles macOS 服务器使用 iMessage(REST 发送/接收、正在输入、回应、配对、高级操作)。 title: BlueBubbles x-i18n: - generated_at: "2026-04-21T20:11:29Z" + generated_at: "2026-04-23T06:40:08Z" model: gpt-5.4 provider: openai - source_hash: db2e193db3fbcea22748187c21d0493037f59d4f1af163725530d5572b06e8b4 + source_hash: a1c1670bb453a1f78bb8e35e4b7065ceeba46ce93180e1288745621f8c4179c9 source_path: channels/bluebubbles.md workflow: 15 --- # BlueBubbles(macOS REST) -状态:一个通过 HTTP 与 BlueBubbles macOS 服务器通信的内置插件。由于其 API 更丰富、设置也比旧版 `imsg` 渠道更简单,**推荐用于 iMessage 集成**。 +状态:通过 HTTP 与 BlueBubbles macOS 服务器通信的内置插件。由于相比旧版 imsg 渠道拥有更丰富的 API 和更简单的设置流程,**推荐用于 iMessage 集成**。 ## 内置插件 -当前的 OpenClaw 版本内置了 BlueBubbles,因此常规打包构建**不需要**单独执行 `openclaw plugins install` 步骤。 +当前的 OpenClaw 发行版已内置 BlueBubbles,因此普通打包构建 +不需要单独执行 `openclaw plugins install` 步骤。 ## 概览 - 通过 BlueBubbles 辅助应用在 macOS 上运行([bluebubbles.app](https://bluebubbles.app))。 -- 推荐/已测试:macOS Sequoia(15)。macOS Tahoe(26)可用;但当前在 Tahoe 上编辑功能不可用,群组图标更新也可能显示成功但不会同步。 -- OpenClaw 通过它的 REST API 与其通信(`GET /api/v1/ping`、`POST /message/text`、`POST /chat/:id/*`)。 +- 推荐/已测试:macOS Sequoia(15)。macOS Tahoe(26)可用;目前在 Tahoe 上编辑功能失效,群组图标更新可能会显示成功但不会同步。 +- OpenClaw 通过其 REST API 与之通信(`GET /api/v1/ping`、`POST /message/text`、`POST /chat/:id/*`)。 - 传入消息通过 webhook 到达;传出回复、正在输入指示、已读回执和 tapback 都通过 REST 调用完成。 -- 附件和贴纸会作为入站媒体摄取(并在可能时暴露给智能体)。 -- 配对/允许列表的工作方式与其他渠道相同(`/channels/pairing` 等),使用 `channels.bluebubbles.allowFrom` + 配对码。 -- 表情回应会像 Slack/Telegram 一样作为系统事件暴露,因此智能体可以在回复前“提及”它们。 -- 高级功能:编辑、撤回、回复线程、消息效果、群组管理。 +- 附件和贴纸会作为入站媒体接收(并在可能时提供给智能体)。 +- 配对/allowlist 的工作方式与其他渠道相同(`/channels/pairing` 等),使用 `channels.bluebubbles.allowFrom` + 配对码。 +- Reactions 会像 Slack/Telegram 一样作为系统事件呈现,因此智能体可以在回复前“提及”它们。 +- 高级功能:编辑、撤回发送、回复线程、消息效果、群组管理。 ## 快速开始 @@ -58,16 +59,16 @@ x-i18n: 安全说明: - 始终设置 webhook 密码。 -- 始终要求进行 webhook 身份验证。无论 loopback/代理拓扑如何,除非 BlueBubbles webhook 请求包含与 `channels.bluebubbles.password` 匹配的 password/guid(例如 `?password=` 或 `x-password`),否则 OpenClaw 会拒绝该请求。 -- 在读取/解析完整 webhook 请求体之前,会先检查密码认证。 +- 始终要求 webhook 身份验证。无论 local loopback/proxy 拓扑如何,除非 BlueBubbles webhook 请求包含与 `channels.bluebubbles.password` 匹配的 password/guid(例如 `?password=` 或 `x-password`),否则 OpenClaw 会拒绝该请求。 +- 密码身份验证会在读取/解析完整 webhook 请求体之前检查。 ## 保持 Messages.app 处于活动状态(VM / 无头设置) -某些 macOS VM / 常开环境可能会出现 Messages.app 进入“空闲”状态的情况(传入事件会停止,直到应用被打开/切到前台)。一个简单的变通办法是使用 AppleScript + LaunchAgent **每 5 分钟轻触一次 Messages**。 +某些 macOS VM / 常开设置可能会导致 Messages.app 进入“空闲”状态(在应用被打开/置于前台之前,传入事件会停止)。一个简单的解决办法是使用 AppleScript + LaunchAgent **每 5 分钟轻触一次 Messages**。 ### 1)保存 AppleScript -将其保存为: +将以下内容保存为: - `~/Scripts/poke-messages.scpt` @@ -90,7 +91,7 @@ end try ### 2)安装 LaunchAgent -将其保存为: +将以下内容保存为: - `~/Library/LaunchAgents/com.user.poke-messages.plist` @@ -126,7 +127,7 @@ end try 说明: - 该任务会**每 300 秒**运行一次,并且会**在登录时**运行。 -- 首次运行时可能会触发 macOS 的**自动化**提示(`osascript` → Messages)。请在运行该 LaunchAgent 的同一用户会话中批准这些提示。 +- 首次运行可能会触发 macOS 的**自动化**权限提示(`osascript` → Messages)。请在运行该 LaunchAgent 的同一用户会话中批准这些提示。 加载它: @@ -139,21 +140,21 @@ launchctl load ~/Library/LaunchAgents/com.user.poke-messages.plist BlueBubbles 可在交互式新手引导中使用: -``` +```text openclaw onboard ``` 向导会提示你输入: - **Server URL**(必填):BlueBubbles 服务器地址(例如 `http://192.168.1.100:1234`) -- **Password**(必填):来自 BlueBubbles Server 设置的 API 密码 +- **Password**(必填):BlueBubbles Server 设置中的 API 密码 - **Webhook path**(可选):默认为 `/bluebubbles-webhook` -- **DM policy**:pairing、allowlist、open 或 disabled -- **Allow list**:电话号码、电子邮件或聊天目标 +- **私信策略**:pairing、allowlist、open 或 disabled +- **允许列表**:电话号码、电子邮件地址或聊天目标 你也可以通过 CLI 添加 BlueBubbles: -``` +```text openclaw channels add bluebubbles --http-url http://192.168.1.100:1234 --password ``` @@ -162,25 +163,25 @@ openclaw channels add bluebubbles --http-url http://192.168.1.100:1234 --passwor 私信: - 默认值:`channels.bluebubbles.dmPolicy = "pairing"`。 -- 未知发送者会收到一个配对码;在获得批准之前,消息会被忽略(配对码 1 小时后过期)。 -- 通过以下方式批准: +- 未知发送者会收到一个配对码;在批准之前,其消息会被忽略(代码在 1 小时后过期)。 +- 通过以下命令批准: - `openclaw pairing list bluebubbles` - `openclaw pairing approve bluebubbles ` -- 配对是默认的令牌交换方式。详情参见:[Pairing](/zh-CN/channels/pairing) +- 配对是默认的令牌交换方式。详情请参见:[Pairing](/zh-CN/channels/pairing) 群组: - `channels.bluebubbles.groupPolicy = open | allowlist | disabled`(默认:`allowlist`)。 -- 当设置为 `allowlist` 时,`channels.bluebubbles.groupAllowFrom` 控制谁可以在群组中触发。 +- 当设置为 `allowlist` 时,`channels.bluebubbles.groupAllowFrom` 用于控制群组中谁可以触发。 -### 联系人姓名增强(macOS,可选) +### 联系人名称增强(macOS,可选) -BlueBubbles 的群组 webhook 通常只包含原始参与者地址。如果你希望 `GroupMembers` 上下文改为显示本地联系人姓名,可以选择在 macOS 上启用本地通讯录增强: +BlueBubbles 群组 webhook 通常只包含原始参与者地址。如果你希望 `GroupMembers` 上下文显示本地联系人名称而不是原始值,可以选择在 macOS 上启用本地通讯录增强: -- `channels.bluebubbles.enrichGroupParticipantsFromContacts = true` 启用该查找。默认值:`false`。 -- 只有在群组访问、命令授权和提及门控都允许该消息通过之后,才会执行查找。 -- 只有未命名的电话参与者会被增强。 -- 如果未找到本地匹配项,则原始电话号码仍会作为回退值保留。 +- `channels.bluebubbles.enrichGroupParticipantsFromContacts = true` 启用查找。默认值:`false`。 +- 只有在群组访问、命令授权和提及门控允许消息通过后,才会执行查找。 +- 仅对未命名的电话参与者进行增强。 +- 如果找不到本地匹配项,则仍会使用原始电话号码作为回退值。 ```json5 { @@ -197,10 +198,10 @@ BlueBubbles 的群组 webhook 通常只包含原始参与者地址。如果你 BlueBubbles 支持群聊的提及门控,与 iMessage/WhatsApp 的行为一致: - 使用 `agents.list[].groupChat.mentionPatterns`(或 `messages.groupChat.mentionPatterns`)检测提及。 -- 当为某个群组启用 `requireMention` 时,智能体只有在被提及时才会响应。 +- 当某个群组启用 `requireMention` 时,智能体仅在被提及后才会响应。 - 来自已授权发送者的控制命令会绕过提及门控。 -按群组配置: +每个群组的配置: ```json5 { @@ -210,7 +211,7 @@ BlueBubbles 支持群聊的提及门控,与 iMessage/WhatsApp 的行为一致 groupAllowFrom: ["+15555550123"], groups: { "*": { requireMention: true }, // 所有群组的默认值 - "iMessage;-;chat123": { requireMention: false }, // 特定群组的覆盖值 + "iMessage;-;chat123": { requireMention: false }, // 覆盖特定群组 }, }, }, @@ -220,12 +221,12 @@ BlueBubbles 支持群聊的提及门控,与 iMessage/WhatsApp 的行为一致 ### 命令门控 - 控制命令(例如 `/config`、`/model`)需要授权。 -- 使用 `allowFrom` 和 `groupAllowFrom` 来确定命令授权。 -- 已授权发送者即使在群组中未提及,也可以运行控制命令。 +- 使用 `allowFrom` 和 `groupAllowFrom` 判定命令授权。 +- 已授权的发送者即使在群组中未提及,也可以运行控制命令。 -### 按群组设置 system prompt +### 每个群组的系统提示词 -`channels.bluebubbles.groups.*` 下的每个条目都接受一个可选的 `systemPrompt` 字符串。每当处理该群组中的消息时,该值都会注入到智能体的 system prompt 中,因此你可以为每个群组设置特定人格或行为规则,而无需编辑智能体提示词: +`channels.bluebubbles.groups.*` 下的每个条目都接受一个可选的 `systemPrompt` 字符串。每次处理该群组中的消息时,这个值都会注入到智能体的系统提示词中,因此你可以为每个群组设置独立的人设或行为规则,而无需编辑智能体提示词: ```json5 { @@ -233,7 +234,7 @@ BlueBubbles 支持群聊的提及门控,与 iMessage/WhatsApp 的行为一致 bluebubbles: { groups: { "iMessage;-;chat123": { - systemPrompt: "将回复控制在 3 句话以内。模仿群组的随意语气。", + systemPrompt: "将回复控制在 3 句话以内。模仿该群组的轻松语气。", }, }, }, @@ -241,11 +242,11 @@ BlueBubbles 支持群聊的提及门控,与 iMessage/WhatsApp 的行为一致 } ``` -该键与 BlueBubbles 为该群组报告的 `chatGuid` / `chatIdentifier` / 数字 `chatId` 相匹配,而 `"*"` 通配符条目则为每个没有精确匹配的群组提供默认值(与 `requireMention` 和按群组工具策略使用的模式相同)。精确匹配始终优先于通配符。私信会忽略此字段;请改用智能体级或账户级提示词自定义。 +该键会匹配 BlueBubbles 报告的群组 `chatGuid` / `chatIdentifier` / 数值型 `chatId` 中的任意一种;而 `"*"` 通配符条目会为所有没有精确匹配的群组提供默认值(与 `requireMention` 和每个群组工具策略使用相同模式)。精确匹配始终优先于通配符。私信会忽略此字段;请改用智能体级或账户级提示词定制。 -#### 示例:线程回复和 tapback 表情回应(Private API) +#### 示例:线程回复与 tapback 反应(Private API) -启用 BlueBubbles Private API 后,传入消息会带有简短消息 ID(例如 `[[reply_to:5]]`),智能体可以调用 `action=reply` 将回复串接到特定消息,或调用 `action=react` 添加 tapback。按群组设置 `systemPrompt` 是让智能体稳定选择正确工具的可靠方法: +启用 BlueBubbles Private API 后,入站消息会携带短消息 ID(例如 `[[reply_to:5]]`),并且智能体可以调用 `action=reply` 以线程方式回复特定消息,或调用 `action=react` 添加 tapback。每个群组的 `systemPrompt` 是让智能体持续选择正确工具的一种可靠方式: ```json5 { @@ -254,9 +255,9 @@ BlueBubbles 支持群聊的提及门控,与 iMessage/WhatsApp 的行为一致 groups: { "iMessage;+;chat-family": { systemPrompt: [ - "在此群组中回复时,始终使用上下文中的", - "[[reply_to:N]] messageId 调用 action=reply,这样你的回复会串接到", - "触发消息下方。绝不要发送新的未关联消息。", + "在这个群组中回复时,始终调用 action=reply,并使用", + "上下文中的 [[reply_to:N]] messageId,这样你的回复会在线程中", + "显示在触发消息下方。绝不要发送新的未关联消息。", "", "对于简短确认('ok'、'got it'、'on it'),请使用", "action=react 并选择合适的 tapback 表情(❤️、👍、😂、‼️、❓),", @@ -269,24 +270,24 @@ BlueBubbles 支持群聊的提及门控,与 iMessage/WhatsApp 的行为一致 } ``` -tapback 表情回应和线程回复都需要 BlueBubbles Private API;相关底层机制参见 [Advanced actions](#advanced-actions) 和 [Message IDs](#message-ids-short-vs-full)。 +Tapback 反应和线程回复都需要 BlueBubbles Private API;其底层机制请参见 [Advanced actions](#advanced-actions) 和 [Message IDs](#message-ids-short-vs-full)。 ## ACP 会话绑定 -BlueBubbles 聊天可以在不改变传输层的情况下转变为持久 ACP 工作区。 +BlueBubbles 聊天可以转换为持久化 ACP 工作区,而无需更改传输层。 快速操作流程: - 在私信或允许的群聊中运行 `/acp spawn codex --bind here`。 -- 在同一个 BlueBubbles 会话中,后续消息会路由到生成的 ACP 会话。 -- `/new` 和 `/reset` 会在原地重置同一个已绑定 ACP 会话。 +- 之后在同一个 BlueBubbles 会话中的消息会路由到已启动的 ACP 会话。 +- `/new` 和 `/reset` 会在原位置重置同一个已绑定的 ACP 会话。 - `/acp close` 会关闭 ACP 会话并移除绑定。 -也支持通过顶层 `bindings[]` 条目配置持久绑定,使用 `type: "acp"` 和 `match.channel: "bluebubbles"`。 +还支持通过顶层 `bindings[]` 条目配置持久化绑定,其中 `type: "acp"` 且 `match.channel: "bluebubbles"`。 `match.peer.id` 可以使用任意受支持的 BlueBubbles 目标形式: -- 标准化私信句柄,例如 `+15555550123` 或 `user@example.com` +- 规范化的私信句柄,例如 `+15555550123` 或 `user@example.com` - `chat_id:` - `chat_guid:` - `chat_identifier:` @@ -323,13 +324,13 @@ BlueBubbles 聊天可以在不改变传输层的情况下转变为持久 ACP 工 } ``` -共享的 ACP 绑定行为参见 [ACP Agents](/zh-CN/tools/acp-agents)。 +共享的 ACP 绑定行为请参见 [ACP Agents](/zh-CN/tools/acp-agents)。 ## 正在输入 + 已读回执 - **正在输入指示**:会在生成回复之前和期间自动发送。 - **已读回执**:由 `channels.bluebubbles.sendReadReceipts` 控制(默认:`true`)。 -- **正在输入指示**:OpenClaw 会发送开始输入事件;BlueBubbles 会在发送后或超时后自动清除输入状态(通过 DELETE 手动停止并不可靠)。 +- **正在输入指示**:OpenClaw 会发送开始输入事件;BlueBubbles 会在发送消息后或超时后自动清除输入状态(通过 DELETE 手动停止并不可靠)。 ```json5 { @@ -350,8 +351,8 @@ BlueBubbles 聊天可以在不改变传输层的情况下转变为持久 ACP 工 channels: { bluebubbles: { actions: { - reactions: true, // tapback 表情回应(默认:true) - edit: true, // 编辑已发送消息(macOS 13+,在 macOS 26 Tahoe 上不可用) + reactions: true, // tapback(默认:true) + edit: true, // 编辑已发送消息(macOS 13+,在 macOS 26 Tahoe 上失效) unsend: true, // 撤回消息(macOS 13+) reply: true, // 按消息 GUID 进行线程回复 sendWithEffect: true, // 消息效果(slam、loud 等) @@ -369,19 +370,19 @@ BlueBubbles 聊天可以在不改变传输层的情况下转变为持久 ACP 工 可用操作: -- **react**:添加/移除 tapback 表情回应(`messageId`、`emoji`、`remove`)。iMessage 原生的 tapback 集合是 `love`、`like`、`dislike`、`laugh`、`emphasize` 和 `question`。当智能体选择了该集合之外的 emoji(例如 `👀`)时,reaction 工具会回退为 `love`,这样 tapback 仍然会渲染,而不会导致整个请求失败。已配置的确认表情回应仍会严格校验,遇到未知值时会报错。 +- **react**:添加/移除 tapback 反应(`messageId`、`emoji`、`remove`)。iMessage 原生的 tapback 集合为 `love`、`like`、`dislike`、`laugh`、`emphasize` 和 `question`。当智能体选择了不在该集合中的 emoji(例如 `👀`)时,反应工具会回退到 `love`,这样 tapback 仍能正常渲染,而不会导致整个请求失败。已配置的确认反应仍会严格校验,并在值未知时报错。 - **edit**:编辑已发送消息(`messageId`、`text`) -- **unsend**:撤回消息(`messageId`) -- **reply**:回复特定消息(`messageId`、`text`、`to`) +- **unsend**:撤回一条消息(`messageId`) +- **reply**:回复某条特定消息(`messageId`、`text`、`to`) - **sendWithEffect**:使用 iMessage 效果发送(`text`、`to`、`effectId`) - **renameGroup**:重命名群聊(`chatGuid`、`displayName`) - **setGroupIcon**:设置群聊图标/照片(`chatGuid`、`media`)—— 在 macOS 26 Tahoe 上不稳定(API 可能返回成功,但图标不会同步)。 -- **addParticipant**:向群组添加成员(`chatGuid`、`address`) -- **removeParticipant**:从群组移除成员(`chatGuid`、`address`) +- **addParticipant**:向群组添加某人(`chatGuid`、`address`) +- **removeParticipant**:将某人从群组中移除(`chatGuid`、`address`) - **leaveGroup**:退出群聊(`chatGuid`) - **upload-file**:发送媒体/文件(`to`、`buffer`、`filename`、`asVoice`) - - 语音备忘录:将 **MP3** 或 **CAF** 音频与 `asVoice: true` 一起设置,即可作为 iMessage 语音消息发送。BlueBubbles 在发送语音备忘录时会将 MP3 转换为 CAF。 -- 旧别名:`sendAttachment` 仍然可用,但 `upload-file` 才是规范操作名称。 + - 语音备忘录:将 **MP3** 或 **CAF** 音频与 `asVoice: true` 一起设置,以作为 iMessage 语音消息发送。BlueBubbles 在发送语音备忘录时会将 MP3 转换为 CAF。 +- 旧别名:`sendAttachment` 仍可用,但 `upload-file` 是规范操作名称。 ### 消息 ID(短 ID 与完整 ID) @@ -389,41 +390,43 @@ OpenClaw 可能会暴露_短_消息 ID(例如 `1`、`2`)以节省 token。 - `MessageSid` / `ReplyToId` 可以是短 ID。 - `MessageSidFull` / `ReplyToIdFull` 包含提供商的完整 ID。 -- 短 ID 保存在内存中;重启或缓存清除后可能失效。 +- 短 ID 存储在内存中;它们可能会在重启或缓存逐出后失效。 - 操作接受短 ID 或完整 `messageId`,但如果短 ID 已不可用,就会报错。 -对于持久自动化和存储,请使用完整 ID: +对于持久化自动化和存储,请使用完整 ID: - 模板:`{{MessageSidFull}}`、`{{ReplyToIdFull}}` -- 上下文:入站载荷中的 `MessageSidFull` / `ReplyToIdFull` +- 上下文:入站负载中的 `MessageSidFull` / `ReplyToIdFull` -模板变量参见 [Configuration](/zh-CN/gateway/configuration)。 +模板变量请参见 [配置](/zh-CN/gateway/configuration)。 -## 合并拆分发送的私信(一次编辑中同时包含命令 + URL) + -当用户在 iMessage 中同时输入命令和 URL 时——例如 `Dump https://example.com/article`——Apple 会把这次发送拆成**两个独立的 webhook 投递**: +## 合并拆分发送的私信(同一次输入中的命令 + URL) + +当用户在 iMessage 中同时输入命令和 URL 时——例如 `Dump https://example.com/article`——Apple 会将这次发送拆分为**两个独立的 webhook 投递**: 1. 一条文本消息(`"Dump"`)。 -2. 一个 URL 预览气泡(`"https://..."`),并带有 OG 预览图片作为附件。 +2. 一个 URL 预览气泡(`"https://..."`),并附带 OG 预览图片作为附件。 -在大多数环境中,这两个 webhook 会相隔约 0.8 - 2.0 秒到达 OpenClaw。如果不进行合并,智能体会在第 1 轮只收到命令本身,然后回复(通常是“把 URL 发给我”),等到第 2 轮才看到 URL——此时命令上下文已经丢失。 +在大多数设置中,这两个 webhook 会以约 0.8 - 2.0 秒的间隔到达 OpenClaw。如果不进行合并,智能体在第 1 轮只会收到命令本身并作出回复(通常是“把 URL 发给我”),而直到第 2 轮才看到 URL——此时命令上下文已经丢失。 -`channels.bluebubbles.coalesceSameSenderDms` 可让私信选择启用:将同一发送者连续发来的 webhook 合并为一次智能体轮次。群聊则继续按单条消息作为键,以保留多用户轮次结构。 +`channels.bluebubbles.coalesceSameSenderDms` 可选择为私信启用连续同一发送者 webhook 的合并,使其进入同一个智能体轮次。群聊仍按每条消息单独分键,以保留多用户轮次结构。 ### 何时启用 -在以下情况下启用: +在以下情况启用: -- 你提供的 Skills 期望在一条消息中接收 `命令 + 负载`(dump、paste、save、queue 等)。 -- 你的用户会把 URL、图片或长内容与命令一起粘贴发送。 -- 你可以接受额外增加的私信轮次延迟(见下文)。 +- 你提供的 Skills 预期 `command + payload` 在同一条消息中出现(dump、paste、save、queue 等)。 +- 你的用户会将 URL、图片或长内容与命令一起粘贴发送。 +- 你可以接受私信轮次增加的延迟(见下文)。 -在以下情况下保持关闭: +在以下情况保持禁用: -- 你需要单词私信触发命令的最低延迟。 +- 你需要单词级私信触发命令的最低延迟。 - 你的所有流程都是不带后续负载的一次性命令。 -### 启用方式 +### 启用方法 ```json5 { @@ -435,17 +438,17 @@ OpenClaw 可能会暴露_短_消息 ID(例如 `1`、`2`)以节省 token。 } ``` -当此标志开启,且未显式设置 `messages.inbound.byChannel.bluebubbles` 时,去抖窗口会扩大到 **2500 ms**(未启用合并时默认是 500 ms)。必须使用更宽的窗口——Apple 0.8 - 2.0 秒的拆分发送节奏无法落入更紧的默认窗口中。 +启用该标志后,如果没有显式设置 `messages.inbound.byChannel.bluebubbles`,防抖窗口会扩展到 **2500 ms**(非合并模式默认值为 500 ms)。之所以需要更宽的窗口,是因为 Apple 的拆分发送节奏为 0.8 - 2.0 秒,无法适配更紧的默认窗口。 -如果你要自行调整窗口: +如果你想自行调整该窗口: ```json5 { messages: { inbound: { byChannel: { - // 2500 ms 适用于大多数环境;如果你的 Mac 较慢 - // 或存在内存压力(观察到的间隔可能超过 2 秒),可提高到 4000 ms。 + // 对大多数设置来说,2500 ms 可用;如果你的 Mac 较慢 + // 或处于内存压力下(此时观察到的间隔可能会超过 2 秒),可提高到 4000 ms。 bluebubbles: 2500, }, }, @@ -455,60 +458,60 @@ OpenClaw 可能会暴露_短_消息 ID(例如 `1`、`2`)以节省 token。 ### 权衡 -- **私信控制命令会增加延迟。** 启用该标志后,私信控制命令消息(如 `Dump`、`Save` 等)现在会在分发前最多等待整个去抖窗口,以防后续还有负载 webhook 到来。群聊命令仍然会立即分发。 -- **合并输出有上限**——合并文本最多 4000 个字符,超出时会带有显式的 `…[truncated]` 标记;附件上限为 20;来源条目上限为 10(超过后保留“第一条 + 最新条目”)。每个来源 `messageId` 仍然会进入入站去重,因此如果之后 MessagePoller 重放其中任意单个事件,系统仍会识别它是重复事件。 -- **按渠道选择启用。** 其他渠道(Telegram、WhatsApp、Slack、……)不受影响。 +- **私信控制命令会增加延迟。** 启用该标志后,私信控制命令消息(如 `Dump`、`Save` 等)现在会最多等待一个防抖窗口后再分发,以防后续还有负载 webhook 到来。群聊命令仍保持即时分发。 +- **合并后的输出有边界限制**——合并文本上限为 4000 个字符,并带有明确的 `…[truncated]` 标记;附件上限为 20 个;源条目上限为 10 个(超出后保留首条和最新条目)。每个源 `messageId` 仍会进入入站去重,因此后续任何单独事件的 MessagePoller 重放都会被识别为重复。 +- **按渠道选择启用。** 其他渠道(Telegram、WhatsApp、Slack……)不受影响。 ### 场景与智能体实际看到的内容 | 用户输入内容 | Apple 投递内容 | 标志关闭(默认) | 标志开启 + 2500 ms 窗口 | | ------------------------------------------------------------------ | ------------------------- | --------------------------------------- | ----------------------------------------------------------------------- | -| `Dump https://example.com`(一次发送) | 2 个 webhook,相隔约 1 秒 | 两个智能体轮次:“Dump” 单独一轮,然后是 URL | 一轮:合并文本 `Dump https://example.com` | -| `Save this 📎image.jpg caption`(附件 + 文本) | 2 个 webhook | 两轮 | 一轮:文本 + 图片 | -| `/status`(独立命令) | 1 个 webhook | 立即分发 | **最多等待整个窗口后再分发** | -| 单独粘贴 URL | 1 个 webhook | 立即分发 | 立即分发(bucket 中只有一个条目) | -| 文本 + URL 分几分钟作为两条独立消息刻意发送 | 窗口之外的 2 个 webhook | 两轮 | 两轮(窗口在两者之间到期) | -| 快速洪泛(窗口内 >10 条小型私信) | N 个 webhook | N 轮 | 一轮,带有上限输出(应用“第一条 + 最新条目”、文本/附件上限) | +| `Dump https://example.com`(一次发送) | 2 个 webhook,间隔约 1 秒 | 两个智能体轮次:先只有 “Dump”,再是 URL | 一个轮次:合并后的文本为 `Dump https://example.com` | +| `Save this 📎image.jpg caption`(附件 + 文本) | 2 个 webhook | 两个轮次 | 一个轮次:文本 + 图片 | +| `/status`(独立命令) | 1 个 webhook | 即时分发 | **最多等待窗口时长后再分发** | +| 单独粘贴一个 URL | 1 个 webhook | 即时分发 | 即时分发(桶中只有一个条目) | +| 文本 + URL 作为两条刻意分开发送的消息,间隔数分钟 | 窗口外的 2 个 webhook | 两个轮次 | 两个轮次(窗口已在它们之间过期) | +| 快速洪泛(窗口内超过 10 条小私信) | N 个 webhook | N 个轮次 | 一个轮次,带边界限制的输出(保留首条 + 最新条目,并应用文本/附件上限) | ### 拆分发送合并的故障排除 -如果标志已开启,但拆分发送仍然作为两轮到达,请逐层检查: +如果标志已开启,但拆分发送仍然以两个轮次到达,请逐层检查: -1. **配置是否实际已加载。** +1. **确认配置已实际加载。** - ``` + ```text grep coalesceSameSenderDms ~/.openclaw/openclaw.json ``` - 然后执行 `openclaw gateway restart`——该标志会在 debouncer 注册表创建时读取。 + 然后执行 `openclaw gateway restart`——该标志会在 debouncer-registry 创建时读取。 -2. **你的环境的去抖窗口是否足够宽。** 查看 BlueBubbles 服务器日志 `~/Library/Logs/bluebubbles-server/main.log`: +2. **你的设置的防抖窗口是否足够宽。** 查看位于 `~/Library/Logs/bluebubbles-server/main.log` 的 BlueBubbles 服务器日志: - ``` + ```text grep -E "Dispatching event to webhook" main.log | tail -20 ``` - 测量 `"Dump"` 这类文本分发与后续 `"https://..."`; Attachments:` 分发之间的间隔。将 `messages.inbound.byChannel.bluebubbles` 提高到足以覆盖该间隔。 + 测量 `"Dump"` 这类文本分发与其后 `"https://..."`; Attachments:` 分发之间的间隔。将 `messages.inbound.byChannel.bluebubbles` 调高到能从容覆盖该间隔的值。 -3. **会话 JSONL 时间戳 ≠ webhook 到达时间。** 会话事件时间戳(`~/.openclaw/agents//sessions/*.jsonl`)反映的是 Gateway 网关何时将消息交给智能体,**不是** webhook 何时到达。如果排队中的第二条消息被标记为 `[Queued messages while agent was busy]`,说明第二个 webhook 到达时,第一轮仍在运行——合并 bucket 已经刷新。请根据 BB 服务器日志而不是会话日志来调整窗口。 +3. **会话 JSONL 时间戳 ≠ webhook 到达时间。** 会话事件时间戳(`~/.openclaw/agents//sessions/*.jsonl`)反映的是 Gateway 网关将消息交给智能体的时间,**而不是** webhook 到达时间。带有 `[Queued messages while agent was busy]` 标记的排队第二条消息,意味着第二个 webhook 到达时第一轮仍在运行——合并桶此时已经冲刷。请根据 BB 服务器日志而不是会话日志来调整窗口。 -4. **内存压力拖慢了回复分发。** 在较小的机器(8 GB)上,智能体轮次可能耗时较长,以至于在回复完成前合并 bucket 就已刷新,结果 URL 作为排队的第二轮到达。检查 `memory_pressure` 和 `ps -o rss -p $(pgrep openclaw-gateway)`;如果 Gateway 网关的 RSS 超过约 500 MB 且压缩器处于活跃状态,请关闭其他重型进程或升级到更大的主机。 +4. **内存压力导致回复分发变慢。** 在较小的机器(8 GB)上,智能体轮次可能耗时足够长,以至于在回复完成前合并桶就已冲刷,URL 因而作为排队的第二轮到达。检查 `memory_pressure` 以及 `ps -o rss -p $(pgrep openclaw-gateway)`;如果 Gateway 网关的 RSS 超过约 500 MB,且压缩器处于活动状态,请关闭其他高负载进程,或迁移到更大的主机。 -5. **回复引用发送走的是另一条路径。** 如果用户把 `Dump` 作为对现有 URL 预览气泡的**回复**发出(iMessage 会在 Dump 气泡上显示 “1 Reply” 标记),那么 URL 位于 `replyToBody` 中,而不是第二个 webhook 中。这时不适用合并——这是 Skills/提示词层面的问题,而不是 debouncer 层面的问题。 +5. **回复引用发送走的是另一条路径。** 如果用户是将 `Dump` 作为对已有 URL 气泡的**回复**发送(iMessage 会在 Dump 气泡上显示 “1 Reply” 标记),那么 URL 位于 `replyToBody` 中,而不是第二个 webhook 中。此时不适用合并——这属于 Skills/提示词问题,而不是去抖器问题。 ## 分块流式传输 -控制是将回复作为单条消息发送,还是按块流式发送: +控制响应是作为单条消息发送,还是按块流式发送: __OC_I18N_900017__ ## 媒体 + 限制 -- 入站附件会被下载并存储在媒体缓存中。 -- 入站和出站媒体的大小上限由 `channels.bluebubbles.mediaMaxMb` 控制(默认:8 MB)。 +- 入站附件会被下载并存储到媒体缓存中。 +- 通过 `channels.bluebubbles.mediaMaxMb` 控制入站和出站媒体大小上限(默认:8 MB)。 - 出站文本会按 `channels.bluebubbles.textChunkLimit` 分块(默认:4000 个字符)。 ## 配置参考 -完整配置: [Configuration](/gateway/configuration) +完整配置: [配置](/gateway/configuration) 提供商选项: @@ -517,20 +520,20 @@ __OC_I18N_900017__ - `channels.bluebubbles.password`:API 密码。 - `channels.bluebubbles.webhookPath`:webhook 端点路径(默认:`/bluebubbles-webhook`)。 - `channels.bluebubbles.dmPolicy`:`pairing | allowlist | open | disabled`(默认:`pairing`)。 -- `channels.bluebubbles.allowFrom`:私信允许列表(handles、电子邮件、E.164 号码、`chat_id:*`、`chat_guid:*`)。 +- `channels.bluebubbles.allowFrom`:私信 allowlist(handles、邮箱、E.164 号码、`chat_id:*`、`chat_guid:*`)。 - `channels.bluebubbles.groupPolicy`:`open | allowlist | disabled`(默认:`allowlist`)。 -- `channels.bluebubbles.groupAllowFrom`:群组发送者允许列表。 -- `channels.bluebubbles.enrichGroupParticipantsFromContacts`:在 macOS 上,在门控通过后,可选择从本地通讯录增强未命名的群组参与者。默认:`false`。 -- `channels.bluebubbles.groups`:按群组配置(`requireMention` 等)。 +- `channels.bluebubbles.groupAllowFrom`:群组发送者 allowlist。 +- `channels.bluebubbles.enrichGroupParticipantsFromContacts`:在 macOS 上,可在门控通过后选择从本地通讯录中补全未命名群组参与者。默认:`false`。 +- `channels.bluebubbles.groups`:每个群组的配置(`requireMention` 等)。 - `channels.bluebubbles.sendReadReceipts`:发送已读回执(默认:`true`)。 -- `channels.bluebubbles.blockStreaming`:启用分块流式传输(默认:`false`;流式回复所必需)。 +- `channels.bluebubbles.blockStreaming`:启用分块流式传输(默认:`false`;流式回复必需)。 - `channels.bluebubbles.textChunkLimit`:出站分块字符数上限(默认:4000)。 -- `channels.bluebubbles.sendTimeoutMs`:通过 `/api/v1/message/text` 发送出站文本时每个请求的超时时间(毫秒)(默认:30000)。在 macOS 26 环境中,如果 Private API 的 iMessage 发送可能在 iMessage 框架内部停滞 60 秒以上,请调高此值;例如设为 `45000` 或 `60000`。探测、聊天查找、表情回应、编辑和健康检查当前仍保留较短的 10 秒默认值;后续计划将更宽的超时覆盖到表情回应和编辑。按账户覆盖:`channels.bluebubbles.accounts..sendTimeoutMs`。 -- `channels.bluebubbles.chunkMode`:`length`(默认)仅在超过 `textChunkLimit` 时拆分;`newline` 会先按空行(段落边界)拆分,再按长度分块。 -- `channels.bluebubbles.mediaMaxMb`:入站/出站媒体大小上限(MB)(默认:8)。 -- `channels.bluebubbles.mediaLocalRoots`:允许用于出站本地媒体路径的绝对本地目录显式允许列表。默认会拒绝发送本地路径,除非配置了此项。按账户覆盖:`channels.bluebubbles.accounts..mediaLocalRoots`。 -- `channels.bluebubbles.coalesceSameSenderDms`:将同一发送者连续发来的私信 webhook 合并为一次智能体轮次,使 Apple 拆分的“文本 + URL”发送能够作为一条消息到达(默认:`false`)。场景、窗口调优和权衡取舍参见 [合并拆分发送的私信](#coalescing-split-send-dms-command--url-in-one-composition)。当启用且未显式设置 `messages.inbound.byChannel.bluebubbles` 时,会将默认入站去抖窗口从 500 ms 扩大到 2500 ms。 -- `channels.bluebubbles.historyLimit`:用于上下文的群组消息最大数量(0 表示禁用)。 +- `channels.bluebubbles.sendTimeoutMs`:通过 `/api/v1/message/text` 发送出站文本时每个请求的超时时间(毫秒,默认:30000)。在 macOS 26 设置中,如果 Private API 的 iMessage 发送可能在 iMessage 框架内部卡住 60 秒以上,可将其调高,例如 `45000` 或 `60000`。探测、聊天查找、反应、编辑和健康检查目前仍保持较短的 10 秒默认值;后续计划将更长超时覆盖到反应和编辑。每账户覆盖:`channels.bluebubbles.accounts..sendTimeoutMs`。 +- `channels.bluebubbles.chunkMode`:`length`(默认)仅在超过 `textChunkLimit` 时拆分;`newline` 则先按空行(段落边界)拆分,再按长度分块。 +- `channels.bluebubbles.mediaMaxMb`:入站/出站媒体大小上限(MB,默认:8)。 +- `channels.bluebubbles.mediaLocalRoots`:允许出站本地媒体路径使用的绝对本地目录显式 allowlist。默认情况下,除非配置了此项,否则会拒绝本地路径发送。每账户覆盖:`channels.bluebubbles.accounts..mediaLocalRoots`。 +- `channels.bluebubbles.coalesceSameSenderDms`:将连续来自同一发送者的私信 webhook 合并为一个智能体轮次,从而让 Apple 的文本 + URL 拆分发送以单条消息到达(默认:`false`)。有关场景、窗口调优和权衡,请参见[合并拆分发送的私信](#coalescing-split-send-dms-command--url-in-one-composition)。当启用且未显式设置 `messages.inbound.byChannel.bluebubbles` 时,会将默认入站防抖窗口从 500 ms 扩大到 2500 ms。 +- `channels.bluebubbles.historyLimit`:用于上下文的最大群组消息数(0 表示禁用)。 - `channels.bluebubbles.dmHistoryLimit`:私信历史记录上限。 - `channels.bluebubbles.actions`:启用/禁用特定操作。 - `channels.bluebubbles.accounts`:多账户配置。 @@ -542,42 +545,42 @@ __OC_I18N_900017__ ## 寻址 / 投递目标 -为了获得稳定路由,优先使用 `chat_guid`: +为获得稳定路由,优先使用 `chat_guid`: - `chat_guid:iMessage;-;+15555550123`(群组首选) - `chat_id:123` - `chat_identifier:...` -- 直接 handle:`+15555550123`、`user@example.com` - - 如果某个直接 handle 没有现有的私信聊天,OpenClaw 会通过 `POST /api/v1/chat/new` 创建一个。这要求启用 BlueBubbles Private API。 +- 直接 handles:`+15555550123`、`user@example.com` + - 如果直接 handle 没有现有私信聊天,OpenClaw 会通过 `POST /api/v1/chat/new` 创建一个。此功能要求启用 BlueBubbles Private API。 ### iMessage 与 SMS 路由 -当同一个 handle 在 Mac 上同时存在 iMessage 聊天和 SMS 聊天时(例如某个已注册 iMessage 的电话号码,同时也收过绿色气泡的回退消息),OpenClaw 会优先选择 iMessage 聊天,绝不会静默降级到 SMS。要强制使用 SMS 聊天,请使用显式的 `sms:` 目标前缀(例如 `sms:+15555550123`)。如果某个 handle 没有匹配的 iMessage 聊天,则仍会通过 BlueBubbles 报告的相应聊天发送。 +当同一个 handle 在 Mac 上同时存在 iMessage 聊天和 SMS 聊天时(例如某个已注册 iMessage 的手机号也曾接收过绿气泡回退消息),OpenClaw 会优先使用 iMessage 聊天,绝不会静默降级为 SMS。若要强制使用 SMS 聊天,请使用显式 `sms:` 目标前缀(例如 `sms:+15555550123`)。对于没有匹配 iMessage 聊天的 handle,仍会通过 BlueBubbles 报告的对应聊天发送。 ## 安全 - webhook 请求通过将查询参数或请求头中的 `guid`/`password` 与 `channels.bluebubbles.password` 进行比较来完成身份验证。 -- 请妥善保管 API 密码和 webhook 端点(将它们视为凭据)。 -- BlueBubbles webhook 身份验证没有 localhost 绕过。如果你代理 webhook 流量,请在整个请求链路中保留 BlueBubbles 密码。这里的 `gateway.trustedProxies` 不能替代 `channels.bluebubbles.password`。参见 [Gateway 网关安全](/gateway/security#reverse-proxy-configuration)。 -- 如果要在局域网之外暴露 BlueBubbles 服务器,请启用 HTTPS 和防火墙规则。 +- 请妥善保管 API 密码和 webhook 端点(将它们视为凭证)。 +- BlueBubbles webhook 身份验证没有 localhost 绕过。如果你代理 webhook 流量,请在整个请求链路中保留 BlueBubbles 密码。这里的 `gateway.trustedProxies` 不能替代 `channels.bluebubbles.password`。请参见 [Gateway 网关安全](/gateway/security#reverse-proxy-configuration)。 +- 如果要在 LAN 之外暴露 BlueBubbles 服务器,请启用 HTTPS 和防火墙规则。 ## 故障排除 -- 如果“正在输入”/已读事件停止工作,请检查 BlueBubbles webhook 日志,并验证 Gateway 网关路径与 `channels.bluebubbles.webhookPath` 一致。 +- 如果正在输入/已读事件停止工作,请检查 BlueBubbles webhook 日志,并确认 Gateway 网关路径与 `channels.bluebubbles.webhookPath` 匹配。 - 配对码会在一小时后过期;请使用 `openclaw pairing list bluebubbles` 和 `openclaw pairing approve bluebubbles `。 -- 表情回应需要 BlueBubbles private API(`POST /api/v1/message/react`);请确认服务器版本提供了该接口。 -- 编辑/撤回需要 macOS 13+ 和兼容的 BlueBubbles 服务器版本。在 macOS 26(Tahoe)上,由于 private API 变更,编辑当前不可用。 -- 群组图标更新在 macOS 26(Tahoe)上可能不稳定:API 可能返回成功,但新图标不会同步。 -- OpenClaw 会根据 BlueBubbles 服务器的 macOS 版本自动隐藏已知有问题的操作。如果在 macOS 26(Tahoe)上仍然显示 edit,请手动使用 `channels.bluebubbles.actions.edit=false` 禁用它。 -- 已启用 `coalesceSameSenderDms`,但拆分发送(例如 `Dump` + URL)仍然作为两轮到达:请参阅[拆分发送合并的故障排除](#split-send-coalescing-troubleshooting)检查清单——常见原因包括去抖窗口过窄、将会话日志时间戳误读为 webhook 到达时间,或发送的是回复引用(它使用的是 `replyToBody`,而不是第二个 webhook)。 +- Reactions 需要 BlueBubbles private API(`POST /api/v1/message/react`);请确保服务器版本已提供该接口。 +- 编辑/撤回需要 macOS 13+ 和兼容的 BlueBubbles 服务器版本。在 macOS 26(Tahoe)上,由于 private API 变更,编辑目前已失效。 +- 在 macOS 26(Tahoe)上,群组图标更新可能不稳定:API 可能返回成功,但新图标不会同步。 +- OpenClaw 会根据 BlueBubbles 服务器的 macOS 版本自动隐藏已知损坏的操作。如果在 macOS 26(Tahoe)上仍然显示编辑,请使用 `channels.bluebubbles.actions.edit=false` 手动禁用。 +- 已启用 `coalesceSameSenderDms`,但拆分发送(例如 `Dump` + URL)仍然以两个轮次到达:请参阅[拆分发送合并的故障排除](#split-send-coalescing-troubleshooting)检查清单——常见原因包括防抖窗口过短、误将会话日志时间戳当作 webhook 到达时间,或使用了回复引用发送(其使用的是 `replyToBody`,而不是第二个 webhook)。 - 查看状态/健康信息:`openclaw status --all` 或 `openclaw status --deep`。 -有关通用渠道工作流的参考,请参见 [Channels](/zh-CN/channels) 和 [Plugins](/zh-CN/tools/plugin) 指南。 +有关通用渠道工作流参考,请参见 [Channels](/zh-CN/channels) 和 [Plugins](/zh-CN/tools/plugin) 指南。 ## 相关内容 -- [Channels Overview](/zh-CN/channels) —— 所有受支持的渠道 -- [Pairing](/zh-CN/channels/pairing) —— 私信认证和配对流程 -- [Groups](/zh-CN/channels/groups) —— 群聊行为和提及门控 -- [Channel Routing](/zh-CN/channels/channel-routing) —— 消息的会话路由 -- [Security](/zh-CN/gateway/security) —— 访问模型与加固 +- [Channels Overview](/zh-CN/channels) — 所有受支持的渠道 +- [Pairing](/zh-CN/channels/pairing) — 私信身份验证与配对流程 +- [Groups](/zh-CN/channels/groups) — 群聊行为与提及门控 +- [Channel Routing](/zh-CN/channels/channel-routing) — 消息的会话路由 +- [Security](/zh-CN/gateway/security) — 访问模型与加固 diff --git a/docs/zh-CN/channels/channel-routing.md b/docs/zh-CN/channels/channel-routing.md index 54a6bf0d4..47f8f65d2 100644 --- a/docs/zh-CN/channels/channel-routing.md +++ b/docs/zh-CN/channels/channel-routing.md @@ -4,43 +4,43 @@ read_when: summary: 各渠道(WhatsApp、Telegram、Discord、Slack)的路由规则和共享上下文 title: 渠道路由 x-i18n: - generated_at: "2026-04-23T00:41:51Z" + generated_at: "2026-04-23T06:40:05Z" model: gpt-5.4 provider: openai - source_hash: e7d437d85d5edd3a0157fd683c6ec63d5d7e905e3e6bdce9a3ba11ddab97d3c2 + source_hash: ad1101d9d3411d9e9f48efd14c0dab09d76e83a6bd93c713d38efc01a14c8391 source_path: channels/channel-routing.md workflow: 15 --- # 渠道与路由 -OpenClaw 会将回复**路由回消息来源的那个渠道**。模型不会选择渠道;路由是确定性的,并由主机配置控制。 +OpenClaw 会将回复**发回消息来源的那个渠道**。模型不会选择渠道;路由是确定性的,并由宿主配置控制。 ## 关键术语 -- **渠道**:`telegram`、`whatsapp`、`discord`、`irc`、`googlechat`、`slack`、`signal`、`imessage`、`line`,以及扩展渠道。`webchat` 是内部的 WebChat UI 渠道,不是可配置的出站渠道。 +- **渠道**:`telegram`、`whatsapp`、`discord`、`irc`、`googlechat`、`slack`、`signal`、`imessage`、`line`,以及插件渠道。`webchat` 是内部 WebChat UI 渠道,不是可配置的出站渠道。 - **AccountId**:每个渠道的账户实例(在支持时)。 -- 可选的渠道默认账户:`channels..defaultAccount` 用于选择在出站路径未指定 `accountId` 时使用哪个账户。 - - 在多账户配置中,当配置了两个或更多账户时,请设置显式默认值(`defaultAccount` 或 `accounts.default`)。否则,回退路由可能会选择第一个标准化后的账户 ID。 +- 可选的渠道默认账户:`channels..defaultAccount` 用于选择当出站路径未指定 `accountId` 时应使用哪个账户。 + - 在多账户配置中,当配置了两个或更多账户时,请设置一个显式默认值(`defaultAccount` 或 `accounts.default`)。否则,回退路由可能会选择第一个规范化后的账户 ID。 - **AgentId**:隔离的工作区 + 会话存储(“大脑”)。 - **SessionKey**:用于存储上下文并控制并发的桶键。 ## 会话键形状(示例) -默认情况下,私信会折叠到智能体的 **main** 会话: +默认情况下,私信会收敛到智能体的**主**会话: - `agent::`(默认:`agent:main:main`) -即使私信会话历史与 main 共享,针对外部私信,沙箱和工具策略仍会使用派生出的按账户区分的私聊运行时键,这样来自渠道的消息就不会被当作本地 main 会话运行处理。 +即使私信会话历史与主会话共享,沙箱和工具策略仍会为外部私信使用派生的、按账户区分的私聊运行时键,这样来自渠道的消息就不会被当作本地主会话运行来处理。 -群组和频道在每个渠道内仍然保持隔离: +群组和频道在每个渠道内仍保持隔离: - 群组:`agent:::group:` - 频道/房间:`agent:::channel:` 线程: -- Slack/Discord 线程会将 `:thread:` 追加到基础键后面。 +- Slack/Discord 线程会在基础键后追加 `:thread:`。 - Telegram 论坛话题会将 `:topic:` 嵌入群组键中。 示例: @@ -48,36 +48,37 @@ OpenClaw 会将回复**路由回消息来源的那个渠道**。模型不会选 - `agent:main:telegram:group:-1001234567890:topic:42` - `agent:main:discord:channel:123456:thread:987654` -## main 私信路由固定 +## 主私信路由固定 -当 `session.dmScope` 为 `main` 时,私信可能共享一个 main 会话。为了防止会话的 `lastRoute` 被非所有者私信覆盖,OpenClaw 会在以下条件全部满足时,从 `allowFrom` 推断出一个固定所有者: +当 `session.dmScope` 为 `main` 时,私信可以共享同一个主会话。 +为防止会话的 `lastRoute` 被非所有者私信覆盖,若以下条件全部满足,OpenClaw 会根据 `allowFrom` 推断一个固定所有者: -- `allowFrom` 恰好有一个非通配符条目。 -- 该条目可被标准化为该渠道中的具体发送者 ID。 +- `allowFrom` 恰好包含一个非通配符条目。 +- 该条目可以规范化为该渠道中的具体发送者 ID。 - 入站私信发送者与该固定所有者不匹配。 -在这种不匹配情况下,OpenClaw 仍会记录入站会话元数据,但会跳过更新 main 会话的 `lastRoute`。 +在这种不匹配的情况下,OpenClaw 仍会记录入站会话元数据,但会跳过更新主会话的 `lastRoute`。 -## 路由规则(如何选择一个智能体) +## 路由规则(如何选择智能体) 路由会为每条入站消息选择**一个智能体**: -1. **精确对等方匹配**(带 `peer.kind` + `peer.id` 的 `bindings`)。 +1. **精确对等方匹配**(带有 `peer.kind` + `peer.id` 的 `bindings`)。 2. **父对等方匹配**(线程继承)。 -3. **服务器 + 角色匹配**(Discord),通过 `guildId` + `roles`。 -4. **服务器匹配**(Discord),通过 `guildId`。 +3. **公会 + 角色匹配**(Discord),通过 `guildId` + `roles`。 +4. **公会匹配**(Discord),通过 `guildId`。 5. **团队匹配**(Slack),通过 `teamId`。 6. **账户匹配**(渠道上的 `accountId`)。 7. **渠道匹配**(该渠道上的任意账户,`accountId: "*"`)。 -8. **默认智能体**(`agents.list[].default`,否则为列表中的第一项,回退到 `main`)。 +8. **默认智能体**(`agents.list[].default`,否则为列表中的第一项,回退为 `main`)。 -当一个绑定包含多个匹配字段(`peer`、`guildId`、`teamId`、`roles`)时,**所有已提供的字段都必须匹配**,该绑定才会生效。 +当一个绑定包含多个匹配字段(`peer`、`guildId`、`teamId`、`roles`)时,**所有已提供字段都必须匹配**,该绑定才会生效。 匹配到的智能体决定使用哪个工作区和会话存储。 ## 广播组(运行多个智能体) -广播组允许你针对同一个对等方运行**多个智能体**,前提是 **OpenClaw 本来就会回复**(例如:在 WhatsApp 群组中,通过提及/激活门控之后)。 +广播组让你可以在同一个对等方上运行**多个智能体**,前提是 **OpenClaw 原本会进行回复**(例如:在 WhatsApp 群组中,通过提及/激活门控之后)。 配置: @@ -91,7 +92,7 @@ OpenClaw 会将回复**路由回消息来源的那个渠道**。模型不会选 } ``` -参见:[Broadcast Groups](/zh-CN/channels/broadcast-groups)。 +参见:[广播组](/zh-CN/channels/broadcast-groups)。 ## 配置概览 @@ -117,21 +118,22 @@ OpenClaw 会将回复**路由回消息来源的那个渠道**。模型不会选 会话存储位于状态目录下(默认 `~/.openclaw`): - `~/.openclaw/agents//sessions/sessions.json` -- JSONL 转录文件与该存储文件位于同一目录 +- JSONL 转录文件与该存储并列保存 你可以通过 `session.store` 和 `{agentId}` 模板覆盖存储路径。 -Gateway 网关 和 ACP 会话发现也会扫描默认 `agents/` 根目录下以及模板化 `session.store` 根目录下的磁盘后备智能体存储。发现到的存储必须保持在解析后的智能体根目录内,并使用常规的 `sessions.json` 文件。符号链接和根目录外路径会被忽略。 +Gateway 网关 和 ACP 会话发现也会扫描默认 `agents/` 根目录下以及模板化 `session.store` 根目录下、由磁盘支持的智能体存储。发现到的存储必须保持在解析后的智能体根目录内,并使用常规的 `sessions.json` 文件。符号链接和根目录外路径会被忽略。 ## WebChat 行为 -WebChat 会附加到**所选智能体**,并默认使用该智能体的 main 会话。因此,WebChat 让你可以在一个地方查看该智能体的跨渠道上下文。 +WebChat 会附加到**所选智能体**,并默认使用该智能体的主会话。 +因此,WebChat 让你能够在一个地方查看该智能体的跨渠道上下文。 ## 回复上下文 -入站回复包含: +入站回复在可用时会包含: -- 在可用时包含 `ReplyToId`、`ReplyToBody` 和 `ReplyToSender`。 -- 引用上下文会作为一个 `[Replying to ...]` 块追加到 `Body` 中。 +- `ReplyToId`、`ReplyToBody` 和 `ReplyToSender`。 +- 引用上下文会作为 `[Replying to ...]` 块追加到 `Body` 中。 -这在各个渠道之间保持一致。 +这一行为在各渠道之间保持一致。 diff --git a/docs/zh-CN/channels/feishu.md b/docs/zh-CN/channels/feishu.md index 2044737c9..5a3f5c246 100644 --- a/docs/zh-CN/channels/feishu.md +++ b/docs/zh-CN/channels/feishu.md @@ -5,10 +5,10 @@ read_when: summary: Feishu 机器人概览、功能和配置 title: Feishu x-i18n: - generated_at: "2026-04-13T10:05:19Z" + generated_at: "2026-04-23T06:40:05Z" model: gpt-5.4 provider: openai - source_hash: 77fcf95a3fab534ed898bc157d76bf8bdfa8bf8a918d6af84c0db19890916c1a + source_hash: 11bf136cecb26dc939c5e78e020c0e6aa3312d9f143af0cab7568743c728cf13 source_path: channels/feishu.md workflow: 15 --- @@ -30,7 +30,7 @@ Feishu/Lark 是一个一体化协作平台,团队可以在其中聊天、共 ```bash openclaw channels login --channel feishu ``` - 使用你的 Feishu/Lark 移动应用扫描二维码,以自动创建一个 Feishu/Lark 机器人。 + 使用你的 Feishu/Lark 移动应用扫描二维码,自动创建一个 Feishu/Lark 机器人。 @@ -48,7 +48,7 @@ Feishu/Lark 是一个一体化协作平台,团队可以在其中聊天、共 配置 `dmPolicy` 以控制谁可以向机器人发送私信: -- `"pairing"` — 未知用户会收到配对码;通过 CLI 批准 +- `"pairing"` — 未知用户会收到一个配对码;通过 CLI 批准 - `"allowlist"` — 只有列在 `allowFrom` 中的用户可以聊天(默认:仅机器人所有者) - `"open"` — 允许所有用户 - `"disabled"` — 禁用所有私信 @@ -64,25 +64,25 @@ openclaw pairing approve feishu **群组策略**(`channels.feishu.groupPolicy`): -| Value | 行为 | -| ------------- | ---------------------------------- | -| `"open"` | 响应群组中的所有消息 | -| `"allowlist"` | 仅响应 `groupAllowFrom` 中的群组 | -| `"disabled"` | 禁用所有群组消息 | +| Value | 行为 | +| ------------- | ------------------------------------------ | +| `"open"` | 响应群组中的所有消息 | +| `"allowlist"` | 仅响应 `groupAllowFrom` 中的群组 | +| `"disabled"` | 禁用所有群组消息 | 默认值:`allowlist` **提及要求**(`channels.feishu.requireMention`): -- `true` — 必须 @提及(默认) -- `false` — 无需 @提及也会响应 +- `true` — 需要 @mention(默认) +- `false` — 无需 @mention 也会响应 - 按群组覆盖:`channels.feishu.groups..requireMention` --- ## 群组配置示例 -### 允许所有群组,不需要 @提及 +### 允许所有群组,无需 @mention ```json5 { @@ -94,7 +94,7 @@ openclaw pairing approve feishu } ``` -### 允许所有群组,但仍然要求 @提及 +### 允许所有群组,但仍要求 @mention ```json5 { @@ -114,7 +114,7 @@ openclaw pairing approve feishu channels: { feishu: { groupPolicy: "allowlist", - // 群组 ID 类似于:oc_xxx + // 群组 ID 形如:oc_xxx groupAllowFrom: ["oc_xxx", "oc_yyy"], }, }, @@ -131,7 +131,7 @@ openclaw pairing approve feishu groupAllowFrom: ["oc_xxx"], groups: { oc_xxx: { - // 用户 open_id 类似于:ou_xxx + // 用户 open_id 形如:ou_xxx allowFrom: ["ou_user1", "ou_user2"], }, }, @@ -142,11 +142,13 @@ openclaw pairing approve feishu --- + + ## 获取群组/用户 ID ### 群组 ID(`chat_id`,格式:`oc_xxx`) -在 Feishu/Lark 中打开群组,点击右上角的菜单图标,然后进入**设置**。群组 ID(`chat_id`)会显示在设置页面中。 +在 Feishu/Lark 中打开群组,点击右上角的菜单图标,然后进入 **设置**。群组 ID(`chat_id`)会显示在设置页面中。 ![Get Group ID](/images/feishu-get-group-id.png) @@ -168,11 +170,11 @@ openclaw pairing list feishu ## 常用命令 -| Command | 说明 | -| --------- | ----------------------- | -| `/status` | 显示机器人状态 | -| `/reset` | 重置当前会话 | -| `/model` | 显示或切换 AI 模型 | +| Command | 说明 | +| --------- | --------------------------- | +| `/status` | 显示机器人状态 | +| `/reset` | 重置当前会话 | +| `/model` | 显示或切换 AI 模型 | > Feishu/Lark 不支持原生斜杠命令菜单,因此请将这些命令作为普通文本消息发送。 @@ -182,16 +184,16 @@ openclaw pairing list feishu ### 机器人在群聊中没有响应 -1. 确保机器人已加入群组 -2. 确保你已 @提及机器人(默认必需) +1. 确保机器人已被添加到群组中 +2. 确保你已 @mention 机器人(默认要求) 3. 验证 `groupPolicy` 不是 `"disabled"` 4. 检查日志:`openclaw logs --follow` -### 机器人未收到消息 +### 机器人没有收到消息 -1. 确保机器人应用已在 Feishu Open Platform / Lark Developer 中发布并通过审核 +1. 确保机器人已在 Feishu Open Platform / Lark Developer 中发布并通过审核 2. 确保事件订阅包含 `im.message.receive_v1` -3. 确保已选择**持久连接**(WebSocket) +3. 确保已选择 **persistent connection**(WebSocket) 4. 确保已授予所有必需的权限范围 5. 确保 Gateway 网关正在运行:`openclaw gateway status` 6. 检查日志:`openclaw logs --follow` @@ -199,14 +201,14 @@ openclaw pairing list feishu ### App Secret 泄露 1. 在 Feishu Open Platform / Lark Developer 中重置 App Secret -2. 更新配置中的值 +2. 更新你配置中的值 3. 重启 Gateway 网关:`openclaw gateway restart` --- ## 高级配置 -### 多账号 +### 多账户 ```json5 { @@ -231,7 +233,7 @@ openclaw pairing list feishu } ``` -`defaultAccount` 用于控制当出站 API 未指定 `accountId` 时使用哪个账号。 +`defaultAccount` 用于控制当出站 API 未指定 `accountId` 时使用哪个账户。 ### 消息限制 @@ -247,20 +249,20 @@ Feishu/Lark 支持通过交互式卡片进行流式回复。启用后,机器 channels: { feishu: { streaming: true, // 启用流式卡片输出(默认:true) - blockStreaming: true, // 启用块级分块流式传输(默认:true) + blockStreaming: true, // 启用块级流式传输(默认:true) }, }, } ``` -将 `streaming: false` 设为关闭后,会一次性发送完整回复。 +将 `streaming: false` 设为关闭后,会以一条完整消息发送完整回复。 ### 配额优化 -使用两个可选标志减少 Feishu/Lark API 调用次数: +使用两个可选标志来减少 Feishu/Lark API 调用次数: -- `typingIndicator`(默认 `true`):设为 `false` 以跳过“正在输入”反应调用 -- `resolveSenderNames`(默认 `true`):设为 `false` 以跳过发送者资料查找 +- `typingIndicator`(默认 `true`):设为 `false` 以跳过正在输入反应调用 +- `resolveSenderNames`(默认 `true`):设为 `false` 以跳过发送者资料查询 ```json5 { @@ -329,7 +331,7 @@ Feishu/Lark 支持用于私信和群组话题消息的 ACP。Feishu/Lark ACP 由 /acp spawn codex --thread here ``` -`--thread here` 可用于私信和 Feishu/Lark 话题消息。后续消息会在已绑定的会话中直接路由到该 ACP 会话。 +`--thread here` 适用于私信和 Feishu/Lark 话题消息。绑定会话中的后续消息会直接路由到该 ACP 会话。 ### 多智能体路由 @@ -365,45 +367,45 @@ Feishu/Lark 支持用于私信和群组话题消息的 ACP。Feishu/Lark ACP 由 路由字段: -- `match.channel`: `"feishu"` -- `match.peer.kind`: `"direct"`(私信)或 `"group"`(群聊) -- `match.peer.id`: 用户 Open ID(`ou_xxx`)或群组 ID(`oc_xxx`) +- `match.channel`:`"feishu"` +- `match.peer.kind`:`"direct"`(私信)或 `"group"`(群聊) +- `match.peer.id`:用户 Open ID(`ou_xxx`)或群组 ID(`oc_xxx`) -查找提示请参见 [获取群组/用户 ID](#get-groupuser-ids)。 +有关查找提示,请参见[获取群组/用户 ID](#get-groupuser-ids)。 --- ## 配置参考 -完整配置:[Gateway configuration](/zh-CN/gateway/configuration) +完整配置:[Gateway 网关配置](/zh-CN/gateway/configuration) -| Setting | 说明 | 默认值 | -| ------------------------------------------------- | ------------------------------------ | ---------------- | -| `channels.feishu.enabled` | 启用/禁用该渠道 | `true` | -| `channels.feishu.domain` | API 域名(`feishu` 或 `lark`) | `feishu` | +| Setting | 说明 | 默认值 | +| ------------------------------------------------- | ------------------------------------------ | ---------------- | +| `channels.feishu.enabled` | 启用/禁用该渠道 | `true` | +| `channels.feishu.domain` | API 域(`feishu` 或 `lark`) | `feishu` | | `channels.feishu.connectionMode` | 事件传输方式(`websocket` 或 `webhook`) | `websocket` | -| `channels.feishu.defaultAccount` | 出站路由的默认账号 | `default` | -| `channels.feishu.verificationToken` | webhook 模式必需 | — | -| `channels.feishu.encryptKey` | webhook 模式必需 | — | -| `channels.feishu.webhookPath` | webhook 路由路径 | `/feishu/events` | -| `channels.feishu.webhookHost` | webhook 绑定主机 | `127.0.0.1` | -| `channels.feishu.webhookPort` | webhook 绑定端口 | `3000` | -| `channels.feishu.accounts..appId` | App ID | — | -| `channels.feishu.accounts..appSecret` | App Secret | — | -| `channels.feishu.accounts..domain` | 按账号覆盖域名 | `feishu` | -| `channels.feishu.dmPolicy` | 私信策略 | `allowlist` | -| `channels.feishu.allowFrom` | 私信允许列表(`open_id` 列表) | [BotOwnerId] | -| `channels.feishu.groupPolicy` | 群组策略 | `allowlist` | -| `channels.feishu.groupAllowFrom` | 群组允许列表 | — | -| `channels.feishu.requireMention` | 群组中需要 @提及 | `true` | -| `channels.feishu.groups..requireMention` | 按群组覆盖 @提及要求 | 继承 | -| `channels.feishu.groups..enabled` | 启用/禁用特定群组 | `true` | -| `channels.feishu.textChunkLimit` | 消息分块大小 | `2000` | -| `channels.feishu.mediaMaxMb` | 媒体大小限制 | `30` | -| `channels.feishu.streaming` | 流式卡片输出 | `true` | -| `channels.feishu.blockStreaming` | 分块流式传输 | `true` | -| `channels.feishu.typingIndicator` | 发送“正在输入”反应 | `true` | -| `channels.feishu.resolveSenderNames` | 解析发送者显示名称 | `true` | +| `channels.feishu.defaultAccount` | 用于出站路由的默认账户 | `default` | +| `channels.feishu.verificationToken` | webhook 模式必需 | — | +| `channels.feishu.encryptKey` | webhook 模式必需 | — | +| `channels.feishu.webhookPath` | Webhook 路由路径 | `/feishu/events` | +| `channels.feishu.webhookHost` | Webhook 绑定主机 | `127.0.0.1` | +| `channels.feishu.webhookPort` | Webhook 绑定端口 | `3000` | +| `channels.feishu.accounts..appId` | App ID | — | +| `channels.feishu.accounts..appSecret` | App Secret | — | +| `channels.feishu.accounts..domain` | 按账户覆盖域设置 | `feishu` | +| `channels.feishu.dmPolicy` | 私信策略 | `allowlist` | +| `channels.feishu.allowFrom` | 私信允许列表(`open_id` 列表) | [BotOwnerId] | +| `channels.feishu.groupPolicy` | 群组策略 | `allowlist` | +| `channels.feishu.groupAllowFrom` | 群组允许列表 | — | +| `channels.feishu.requireMention` | 在群组中要求 @mention | `true` | +| `channels.feishu.groups..requireMention` | 按群组覆盖 @mention 要求 | inherited | +| `channels.feishu.groups..enabled` | 启用/禁用特定群组 | `true` | +| `channels.feishu.textChunkLimit` | 消息分块大小 | `2000` | +| `channels.feishu.mediaMaxMb` | 媒体大小限制 | `30` | +| `channels.feishu.streaming` | 流式卡片输出 | `true` | +| `channels.feishu.blockStreaming` | 分块流式传输 | `true` | +| `channels.feishu.typingIndicator` | 发送正在输入反应 | `true` | +| `channels.feishu.resolveSenderNames` | 解析发送者显示名称 | `true` | --- @@ -427,11 +429,11 @@ Feishu/Lark 支持用于私信和群组话题消息的 ACP。Feishu/Lark ACP 由 - ✅ 音频 - ✅ 视频/媒体 - ✅ 交互式卡片(包括流式更新) -- ⚠️ 富文本(post 风格格式;不支持完整的 Feishu/Lark 创作能力) +- ⚠️ 富文本(post 样式格式;不支持完整的 Feishu/Lark 编辑能力) ### 话题和回复 -- ✅ 行内回复 +- ✅ 内联回复 - ✅ 话题回复 - ✅ 回复话题消息时,媒体回复会保持话题感知 @@ -440,7 +442,7 @@ Feishu/Lark 支持用于私信和群组话题消息的 ACP。Feishu/Lark ACP 由 ## 相关内容 - [渠道概览](/zh-CN/channels) — 所有受支持的渠道 -- [配对](/zh-CN/channels/pairing) — 私信身份验证和配对流程 -- [群组](/zh-CN/channels/groups) — 群聊行为和提及门控 +- [配对](/zh-CN/channels/pairing) — 私信身份验证与配对流程 +- [群组](/zh-CN/channels/groups) — 群聊行为与提及门控 - [渠道路由](/zh-CN/channels/channel-routing) — 消息的会话路由 -- [安全](/zh-CN/gateway/security) — 访问模型和加固措施 +- [安全](/zh-CN/gateway/security) — 访问模型与加固措施 diff --git a/docs/zh-CN/channels/irc.md b/docs/zh-CN/channels/irc.md index 961b9af89..037a7c8e3 100644 --- a/docs/zh-CN/channels/irc.md +++ b/docs/zh-CN/channels/irc.md @@ -1,27 +1,27 @@ --- read_when: - 你想将 OpenClaw 连接到 IRC 频道或私信 - - 你正在配置 IRC 允许列表、群组策略或提及门控 + - 你正在配置 IRC allowlist、群组策略或提及门控 summary: IRC 插件设置、访问控制和故障排除 title: IRC x-i18n: - generated_at: "2026-04-05T12:34:26Z" + generated_at: "2026-04-23T06:40:06Z" model: gpt-5.4 provider: openai - source_hash: fceab2979db72116689c6c774d6736a8a2eee3559e3f3cf8969e673d317edd94 + source_hash: 89c788a2be95b43420a5324ed30cada32626b72b2feb77df62aeb928fc0a386c source_path: channels/irc.md workflow: 15 --- # IRC -当你想让 OpenClaw 进入经典频道(`#room`)和私信时,请使用 IRC。 -IRC 作为扩展插件提供,但它在主配置中的 `channels.irc` 下进行配置。 +当你希望 OpenClaw 出现在传统频道(`#room`)和私信中时,请使用 IRC。 +IRC 作为内置插件提供,但需在主配置中的 `channels.irc` 下进行配置。 ## 快速开始 1. 在 `~/.openclaw/openclaw.json` 中启用 IRC 配置。 -2. 至少设置以下内容: +2. 至少设置: ```json5 { @@ -38,9 +38,9 @@ IRC 作为扩展插件提供,但它在主配置中的 `channels.irc` 下进行 } ``` -建议使用私有 IRC 服务器进行机器人协调。如果你有意使用公共 IRC 网络,常见选择包括 Libera.Chat、OFTC 和 Snoonet。避免将可预测的公共频道用于机器人或 swarm 的回传通道流量。 +优先使用私有 IRC 服务器进行机器人协作。如果你有意使用公共 IRC 网络,常见选择包括 Libera.Chat、OFTC 和 Snoonet。避免将可预测的公共频道用于机器人或 swarm 的回传流量。 -3. 启动或重启 Gateway 网关: +3. 启动/重启 Gateway 网关: ```bash openclaw gateway run @@ -50,25 +50,25 @@ openclaw gateway run - `channels.irc.dmPolicy` 默认为 `"pairing"`。 - `channels.irc.groupPolicy` 默认为 `"allowlist"`。 -- 当 `groupPolicy="allowlist"` 时,设置 `channels.irc.groups` 来定义允许的频道。 -- 除非你明确接受明文传输,否则请使用 TLS(`channels.irc.tls=true`)。 +- 当 `groupPolicy="allowlist"` 时,设置 `channels.irc.groups` 以定义允许的频道。 +- 使用 TLS(`channels.irc.tls=true`),除非你明确接受明文传输。 ## 访问控制 -IRC 频道有两个独立的“门控”: +IRC 频道有两个彼此独立的“门”: 1. **频道访问**(`groupPolicy` + `groups`):机器人是否完全接受来自某个频道的消息。 -2. **发送者访问**(`groupAllowFrom` / 每频道 `groups["#channel"].allowFrom`):谁被允许在该频道内触发机器人。 +2. **发送者访问**(`groupAllowFrom` / 每频道 `groups["#channel"].allowFrom`):在该频道内,谁被允许触发机器人。 配置键: -- 私信允许列表(私信发送者访问):`channels.irc.allowFrom` -- 群组发送者允许列表(频道发送者访问):`channels.irc.groupAllowFrom` -- 每频道控制项(频道 + 发送者 + 提及规则):`channels.irc.groups["#channel"]` +- 私信 allowlist(私信发送者访问):`channels.irc.allowFrom` +- 群组发送者 allowlist(频道发送者访问):`channels.irc.groupAllowFrom` +- 每频道控制(频道 + 发送者 + 提及规则):`channels.irc.groups["#channel"]` - `channels.irc.groupPolicy="open"` 允许未配置的频道(**默认仍然受提及门控限制**) -允许列表条目应使用稳定的发送者身份(`nick!user@host`)。 -裸 nick 匹配是可变的,并且只有在 `channels.irc.dangerouslyAllowNameMatching: true` 时才会启用。 +allowlist 条目应使用稳定的发送者身份(`nick!user@host`)。 +仅昵称匹配是可变的,并且只有在 `channels.irc.dangerouslyAllowNameMatching: true` 时才会启用。 ### 常见陷阱:`allowFrom` 用于私信,不用于频道 @@ -76,10 +76,10 @@ IRC 频道有两个独立的“门控”: - `irc: drop group sender alice!ident@host (policy=allowlist)` -……这表示该发送者未被允许发送 **群组/频道** 消息。可通过以下任一方式修复: +……这意味着发送者没有被允许发送**群组/频道**消息。可通过以下方式修复: - 设置 `channels.irc.groupAllowFrom`(对所有频道全局生效),或 -- 设置每频道发送者允许列表:`channels.irc.groups["#channel"].allowFrom` +- 设置每频道发送者 allowlist:`channels.irc.groups["#channel"].allowFrom` 示例(允许 `#tuirc-dev` 中的任何人与机器人对话): @@ -96,13 +96,13 @@ IRC 频道有两个独立的“门控”: } ``` -## 回复触发方式(提及) +## 回复触发(提及) -即使某个频道已被允许(通过 `groupPolicy` + `groups`)且发送者已被允许,OpenClaw 在群组上下文中默认仍会启用 **提及门控**。 +即使频道已被允许(通过 `groupPolicy` + `groups`),且发送者也已被允许,OpenClaw 在群组上下文中默认仍会启用**提及门控**。 -这意味着,除非消息中包含与机器人匹配的提及模式,否则你可能会看到类似 `drop channel … (missing-mention)` 的日志。 +这意味着,除非消息中包含与机器人匹配的提及模式,否则你可能会看到如 `drop channel … (missing-mention)` 这样的日志。 -如果你希望机器人在 IRC 频道中 **无需提及即可回复**,请为该频道禁用提及门控: +如果你希望机器人在 IRC 频道中**无需提及也能回复**,请为该频道禁用提及门控: ```json5 { @@ -120,7 +120,7 @@ IRC 频道有两个独立的“门控”: } ``` -或者,要允许 **所有** IRC 频道(不使用每频道允许列表),并且仍然无需提及即可回复: +或者,如果要允许**所有** IRC 频道(不使用每频道 allowlist),同时仍然无需提及即可回复: ```json5 { @@ -138,9 +138,9 @@ IRC 频道有两个独立的“门控”: ## 安全说明(建议用于公共频道) 如果你在公共频道中允许 `allowFrom: ["*"]`,任何人都可以向机器人发出提示。 -为降低风险,请为该频道限制工具。 +为降低风险,请限制该频道可用的工具。 -### 频道中所有人使用相同工具 +### 频道中所有人使用相同的工具 ```json5 { @@ -159,9 +159,9 @@ IRC 频道有两个独立的“门控”: } ``` -### 按发送者区分工具(所有者拥有更多权限) +### 按发送者使用不同的工具(所有者拥有更高权限) -使用 `toolsBySender` 对 `"*"` 应用更严格的策略,而对你的 nick 应用更宽松的策略: +使用 `toolsBySender`,对 `"*"` 应用更严格的策略,而对你的昵称应用更宽松的策略: ```json5 { @@ -189,14 +189,14 @@ IRC 频道有两个独立的“门控”: - `toolsBySender` 键应对 IRC 发送者身份值使用 `id:`: `id:eigen` 或 `id:eigen!~eigen@174.127.248.171`,后者匹配更强。 -- 旧版未加前缀的键仍然被接受,但只会按 `id:` 进行匹配。 -- 首个匹配到的发送者策略优先;`"*"` 是通配回退项。 +- 旧版不带前缀的键仍然可接受,但只会按 `id:` 进行匹配。 +- 首个匹配到的发送者策略会生效;`"*"` 是通配回退项。 -有关群组访问与提及门控(以及它们如何交互)的更多信息,请参阅:[/channels/groups](/zh-CN/channels/groups)。 +有关群组访问与提及门控(以及它们如何交互)的更多内容,请参阅:[/channels/groups](/zh-CN/channels/groups)。 ## NickServ -要在连接后使用 NickServ 进行身份识别: +要在连接后通过 NickServ 进行身份识别: ```json5 { @@ -212,7 +212,7 @@ IRC 频道有两个独立的“门控”: } ``` -连接时可选的一次性注册: +可选:连接时执行一次性注册: ```json5 { @@ -227,7 +227,7 @@ IRC 频道有两个独立的“门控”: } ``` -在 nick 注册完成后禁用 `register`,以避免重复尝试 REGISTER。 +昵称注册完成后,请禁用 `register`,以避免重复尝试 REGISTER。 ## 环境变量 @@ -240,20 +240,20 @@ IRC 频道有两个独立的“门控”: - `IRC_USERNAME` - `IRC_REALNAME` - `IRC_PASSWORD` -- `IRC_CHANNELS`(以逗号分隔) +- `IRC_CHANNELS`(逗号分隔) - `IRC_NICKSERV_PASSWORD` - `IRC_NICKSERV_REGISTER_EMAIL` ## 故障排除 -- 如果机器人已连接但在频道中始终不回复,请检查 `channels.irc.groups`,**以及** 提及门控是否因 `missing-mention` 而丢弃消息。如果你希望它在不被 ping 的情况下回复,请为该频道设置 `requireMention:false`。 -- 如果登录失败,请检查 nick 是否可用以及服务器密码是否正确。 -- 如果在自定义网络上 TLS 失败,请检查 host/port 和证书配置。 +- 如果机器人已连接,但在频道中始终不回复,请检查 `channels.irc.groups`,**以及** 是否因提及门控而丢弃消息(`missing-mention`)。如果你希望它无需 ping 就能回复,请为该频道设置 `requireMention:false`。 +- 如果登录失败,请检查昵称是否可用以及服务器密码是否正确。 +- 如果在自定义网络上 TLS 失败,请检查主机/端口和证书设置。 ## 相关内容 -- [渠道概览](/zh-CN/channels) — 所有支持的渠道 -- [配对](/zh-CN/channels/pairing) — 私信身份验证和配对流程 -- [群组](/zh-CN/channels/groups) — 群聊行为和提及门控 +- [渠道概览](/zh-CN/channels) — 所有受支持的渠道 +- [Pairing](/zh-CN/channels/pairing) — 私信认证和配对流程 +- [Groups](/zh-CN/channels/groups) — 群聊行为与提及门控 - [渠道路由](/zh-CN/channels/channel-routing) — 消息的会话路由 -- [安全](/zh-CN/gateway/security) — 访问模型和加固措施 +- [安全](/zh-CN/gateway/security) — 访问模型与加固措施 diff --git a/docs/zh-CN/channels/mattermost.md b/docs/zh-CN/channels/mattermost.md index 4a6208cce..115a44764 100644 --- a/docs/zh-CN/channels/mattermost.md +++ b/docs/zh-CN/channels/mattermost.md @@ -5,10 +5,10 @@ read_when: summary: Mattermost 机器人设置和 OpenClaw 配置 title: Mattermost x-i18n: - generated_at: "2026-04-22T01:34:42Z" + generated_at: "2026-04-23T06:40:05Z" model: gpt-5.4 provider: openai - source_hash: dd3059c5e64f417edc02c3e850ddd066e38decda0cbdcea31e1c57136e6bcb1d + source_hash: 7288378af9a3b58d51be19cdeee827350f6a4cbd80031d10ef467d482f3259e5 source_path: channels/mattermost.md workflow: 15 --- @@ -16,14 +16,15 @@ x-i18n: # Mattermost 状态:内置插件(bot token + WebSocket 事件)。支持渠道、群组和私信。 -Mattermost 是一个可自托管的团队消息平台;产品详情和下载请参见官方站点 +Mattermost 是一个可自行托管的团队消息平台;产品详情和下载请参见官方网站 [mattermost.com](https://mattermost.com)。 ## 内置插件 -Mattermost 在当前的 OpenClaw 版本中作为内置插件提供,因此常规打包构建无需单独安装。 +Mattermost 在当前的 OpenClaw 版本中作为内置插件提供,因此普通的 +打包构建不需要单独安装。 -如果你使用的是较旧版本,或是不包含 Mattermost 的自定义安装, +如果你使用的是较旧的构建,或排除了 Mattermost 的自定义安装, 请手动安装: 通过 CLI 安装(npm 注册表): @@ -32,21 +33,21 @@ Mattermost 在当前的 OpenClaw 版本中作为内置插件提供,因此常 openclaw plugins install @openclaw/mattermost ``` -本地 checkout(从 git 仓库运行时): +本地检出(从 git 仓库运行时): ```bash openclaw plugins install ./path/to/local/mattermost-plugin ``` -详情: [Plugins](/zh-CN/tools/plugin) +详情:[Plugins](/zh-CN/tools/plugin) ## 快速设置 1. 确保 Mattermost 插件可用。 - - 当前打包发布的 OpenClaw 版本已内置该插件。 - - 较旧版本 / 自定义安装可使用上面的命令手动添加。 -2. 创建一个 Mattermost bot 账户,并复制 **bot token**。 -3. 复制 Mattermost **base URL**(例如 `https://chat.example.com`)。 + - 当前打包的 OpenClaw 版本已内置它。 + - 较旧/自定义安装可以使用上面的命令手动添加。 +2. 创建一个 Mattermost 机器人账户并复制 **bot token**。 +3. 复制 Mattermost 的 **base URL**(例如 `https://chat.example.com`)。 4. 配置 OpenClaw 并启动 Gateway 网关。 最小配置: @@ -77,7 +78,7 @@ Mattermost API 注册 `oc_*` 斜杠命令,并在 Gateway 网关 HTTP 服务器 native: true, nativeSkills: true, callbackPath: "/api/channels/mattermost/command", - // 当 Mattermost 无法直接访问 Gateway 网关时使用(反向代理 / 公网 URL)。 + // 当 Mattermost 无法直接访问 Gateway 网关时使用(反向代理/公共 URL)。 callbackUrl: "https://gateway.example.com/api/channels/mattermost/command", }, }, @@ -88,38 +89,39 @@ Mattermost API 注册 `oc_*` 斜杠命令,并在 Gateway 网关 HTTP 服务器 说明: - `native: "auto"` 对 Mattermost 默认为禁用。设置 `native: true` 以启用。 -- 如果省略 `callbackUrl`,OpenClaw 会根据 Gateway 网关 host / port 和 `callbackPath` 自动推导。 -- 对于多账户配置,`commands` 可以设置在顶层,也可以设置在 - `channels.mattermost.accounts..commands` 下(账户级值会覆盖顶层字段)。 -- 命令回调会使用 Mattermost 在 OpenClaw 注册 `oc_*` 命令时返回的每命令 token 进行校验。 -- 当注册失败、启动不完整,或回调 token 与任一已注册命令都不匹配时, - 斜杠命令回调会以失败关闭方式拒绝处理。 +- 如果省略 `callbackUrl`,OpenClaw 会根据 Gateway 网关 host/port 和 `callbackPath` 自动推导。 +- 对于多账户设置,`commands` 可以设置在顶层,或设置在 + `channels.mattermost.accounts..commands` 下(账户值会覆盖顶层字段)。 +- 命令回调会使用 Mattermost 在 OpenClaw 注册 `oc_*` 命令时 + 返回的每个命令 token 进行校验。 +- 当注册失败、启动不完整,或回调 token 与任何已注册命令都不匹配时, + 斜杠命令回调会以默认拒绝的方式失败。 - 可达性要求:回调端点必须可从 Mattermost 服务器访问。 - - 除非 Mattermost 与 OpenClaw 运行在同一主机 / 网络命名空间中,否则不要将 `callbackUrl` 设置为 `localhost`。 + - 除非 Mattermost 与 OpenClaw 运行在同一主机/网络命名空间中,否则不要将 `callbackUrl` 设置为 `localhost`。 - 除非该 URL 会将 `/api/channels/mattermost/command` 反向代理到 OpenClaw,否则不要将 `callbackUrl` 设置为你的 Mattermost base URL。 - 一个快速检查方法是运行 `curl https:///api/channels/mattermost/command`;GET 请求应返回来自 OpenClaw 的 `405 Method Not Allowed`,而不是 `404`。 - Mattermost 出站允许列表要求: - - 如果你的回调目标是私有地址 / tailnet / 内网地址,请设置 Mattermost - `ServiceSettings.AllowedUntrustedInternalConnections` 以包含回调 host / domain。 - - 使用 host / domain 条目,而不是完整 URL。 + - 如果你的回调目标是私有/tailnet/内部地址,请设置 Mattermost + `ServiceSettings.AllowedUntrustedInternalConnections` 以包含回调 host/domain。 + - 使用 host/domain 条目,不要使用完整 URL。 - 正确:`gateway.tailnet-name.ts.net` - 错误:`https://gateway.tailnet-name.ts.net` ## 环境变量(默认账户) -如果你更倾向于使用环境变量,请在 Gateway 网关主机上设置以下内容: +如果你更喜欢使用环境变量,请在 Gateway 网关主机上设置这些变量: - `MATTERMOST_BOT_TOKEN=...` - `MATTERMOST_URL=https://chat.example.com` -环境变量仅适用于 **默认** 账户(`default`)。其他账户必须使用配置值。 +环境变量仅适用于**默认**账户(`default`)。其他账户必须使用配置值。 ## 聊天模式 Mattermost 会自动响应私信。渠道行为由 `chatmode` 控制: - `oncall`(默认):仅在渠道中被 @提及时响应。 -- `onmessage`:响应每条渠道消息。 +- `onmessage`:响应每一条渠道消息。 - `onchar`:当消息以触发前缀开头时响应。 配置示例: @@ -138,17 +140,17 @@ Mattermost 会自动响应私信。渠道行为由 `chatmode` 控制: 说明: - `onchar` 仍会响应显式的 @提及。 -- `channels.mattermost.requireMention` 仍会兼容旧版配置,但更推荐使用 `chatmode`。 +- `channels.mattermost.requireMention` 会兼容旧版配置,但更推荐使用 `chatmode`。 -## 线程与会话 +## 线程和会话 -使用 `channels.mattermost.replyToMode` 来控制渠道和群组回复是保留在主渠道中, -还是在触发消息下启动一个线程。 +使用 `channels.mattermost.replyToMode` 控制渠道和群组回复是保留在 +主渠道中,还是在触发消息下开启线程。 -- `off`(默认):仅当传入消息本身已经在线程中时,才在线程中回复。 -- `first`:对于渠道 / 群组中的顶层消息,在该消息下启动线程,并将对话路由到一个线程作用域的会话。 -- `all`:在当前 Mattermost 中,其行为与 `first` 相同。 -- 私信会忽略该设置,并保持非线程模式。 +- `off`(默认):仅当传入帖子本身已经在线程中时,才在线程中回复。 +- `first`:对于顶层渠道/群组帖子,在该帖子下开启线程,并将对话路由到线程范围的会话。 +- `all`:对 Mattermost 当前的行为与 `first` 相同。 +- 私信会忽略此设置,并保持非线程模式。 配置示例: @@ -164,27 +166,27 @@ Mattermost 会自动响应私信。渠道行为由 `chatmode` 控制: 说明: -- 线程作用域会话使用触发消息的 post id 作为线程根节点。 -- `first` 和 `all` 当前等价,因为一旦 Mattermost 已经有线程根节点, - 后续分块和媒体内容都会继续发送到同一线程中。 +- 线程范围的会话使用触发帖子的 id 作为线程根。 +- `first` 和 `all` 当前等价,因为一旦 Mattermost 有了线程根, + 后续分块和媒体内容都会继续发布到同一线程中。 ## 访问控制(私信) - 默认:`channels.mattermost.dmPolicy = "pairing"`(未知发送者会收到一个配对码)。 -- 通过以下命令批准: +- 通过以下方式批准: - `openclaw pairing list mattermost` - `openclaw pairing approve mattermost ` -- 公开私信:`channels.mattermost.dmPolicy="open"` 加 `channels.mattermost.allowFrom=["*"]`。 +- 公开私信:`channels.mattermost.dmPolicy="open"` 加上 `channels.mattermost.allowFrom=["*"]`。 -## 渠道(群组) +## Channels(群组) -- 默认:`channels.mattermost.groupPolicy = "allowlist"`(受提及门控)。 +- 默认:`channels.mattermost.groupPolicy = "allowlist"`(提及门控)。 - 使用 `channels.mattermost.groupAllowFrom` 将发送者加入允许列表(推荐使用用户 ID)。 -- 每渠道提及覆盖项位于 `channels.mattermost.groups..requireMention` +- 每个渠道的提及覆盖配置位于 `channels.mattermost.groups..requireMention` 或 `channels.mattermost.groups["*"].requireMention`(作为默认值)。 - `@username` 匹配是可变的,且仅在 `channels.mattermost.dangerouslyAllowNameMatching: true` 时启用。 -- 开放渠道:`channels.mattermost.groupPolicy="open"`(受提及门控)。 -- 运行时说明:如果完全缺少 `channels.mattermost`,运行时在进行群组检查时会回退为 `groupPolicy="allowlist"`(即使已设置 `channels.defaults.groupPolicy` 也是如此)。 +- 开放渠道:`channels.mattermost.groupPolicy="open"`(提及门控)。 +- 运行时说明:如果 `channels.mattermost` 完全缺失,运行时在群组检查中会回退到 `groupPolicy="allowlist"`(即使设置了 `channels.defaults.groupPolicy` 也是如此)。 示例: @@ -202,31 +204,30 @@ Mattermost 会自动响应私信。渠道行为由 `chatmode` 控制: } ``` -## 出站投递的 target 格式 +## 出站投递目标 -在 `openclaw message send` 或 cron / webhook 中使用以下 target 格式: +将以下目标格式与 `openclaw message send` 或 cron/webhooks 搭配使用: - `channel:` 表示渠道 - `user:` 表示私信 - `@username` 表示私信(通过 Mattermost API 解析) -裸的不透明 ID(如 `64ifufp...`)在 Mattermost 中是 **有歧义的** -(可能是用户 ID,也可能是渠道 ID)。 +裸的不透明 ID(如 `64ifufp...`)在 Mattermost 中是**有歧义的**(用户 ID 或渠道 ID)。 -OpenClaw 会按 **用户优先** 进行解析: +OpenClaw 会按**用户优先**进行解析: -- 如果该 ID 作为用户存在(`GET /api/v4/users/` 成功),OpenClaw 会通过 `/api/v4/channels/direct` 解析直连渠道并发送 **私信**。 -- 否则,该 ID 会被视为 **渠道 ID**。 +- 如果该 ID 作为用户存在(`GET /api/v4/users/` 成功),OpenClaw 会通过 `/api/v4/channels/direct` 解析直连渠道后发送**私信**。 +- 否则该 ID 会被视为**渠道 ID**。 -如果你需要确定性的行为,请始终使用显式前缀(`user:` / `channel:`)。 +如果你需要确定性行为,请始终使用显式前缀(`user:` / `channel:`)。 ## 私信渠道重试 -当 OpenClaw 向 Mattermost 私信 target 发送消息且需要先解析直连渠道时, -默认会对瞬时性的直连渠道创建失败进行重试。 +当 OpenClaw 向 Mattermost 私信目标发送消息,且需要先解析直连渠道时, +默认会重试瞬时性的直连渠道创建失败。 -使用 `channels.mattermost.dmChannelRetry` 可全局调整 Mattermost 插件的此行为, -或使用 `channels.mattermost.accounts..dmChannelRetry` 为某个账户单独设置。 +使用 `channels.mattermost.dmChannelRetry` 为 Mattermost 插件全局调整该行为, +或使用 `channels.mattermost.accounts..dmChannelRetry` 为单个账户调整。 ```json5 { @@ -245,13 +246,13 @@ OpenClaw 会按 **用户优先** 进行解析: 说明: -- 这仅适用于私信渠道创建(`/api/v4/channels/direct`),而不是每一次 Mattermost API 调用。 -- 重试适用于限流、5xx 响应,以及网络或超时错误等瞬时性失败。 -- 除 `429` 之外的 4xx 客户端错误会被视为永久性错误,不会重试。 +- 这仅适用于私信渠道创建(`/api/v4/channels/direct`),而不是每一个 Mattermost API 调用。 +- 重试适用于限流、5xx 响应以及网络或超时错误等瞬时故障。 +- 除 `429` 外的 4xx 客户端错误会被视为永久性错误,不会重试。 ## 预览流式传输 -Mattermost 会将思考内容、工具活动和部分回复文本流式写入同一个**草稿预览消息**,当最终答案可以安全发送时,会原地完成定稿。预览会在同一个 post id 上更新,而不会用逐块消息刷屏。媒体 / 错误类最终结果会取消待处理的预览编辑,并改用常规投递,而不是刷新一个临时的预览消息。 +Mattermost 会将思考过程、工具活动和部分回复文本流式写入同一个**草稿预览帖子**,并在最终答案可安全发送时就地完成。预览会在同一个帖子 id 上更新,而不会用逐块消息刷屏。媒体/错误类最终结果会取消待处理的预览编辑,并改用常规投递,而不是刷新一个一次性的预览帖子。 通过 `channels.mattermost.streaming` 启用: @@ -267,20 +268,20 @@ Mattermost 会将思考内容、工具活动和部分回复文本流式写入同 说明: -- `partial` 是通常的选择:使用一条预览消息,随着回复增长不断编辑,最后以完整答案定稿。 -- `block` 会在预览消息内使用追加式草稿分块。 -- `progress` 会在生成期间显示状态预览,并仅在完成时发布最终答案。 +- `partial` 是常见选择:使用一个预览帖子,随着回复增长不断编辑,最后以完整答案完成。 +- `block` 会在预览帖子中使用追加式草稿分块。 +- `progress` 会在生成时显示状态预览,并仅在完成时发布最终答案。 - `off` 会禁用预览流式传输。 -- 如果流无法原地定稿(例如消息在流过程中被删除),OpenClaw 会回退为发送一条新的最终消息,以确保回复不会丢失。 -- 参见 [Streaming](/zh-CN/concepts/streaming#preview-streaming-modes) 了解渠道映射矩阵。 +- 如果流无法就地完成(例如帖子在流式过程中被删除),OpenClaw 会回退为发送一个新的最终帖子,以确保回复绝不会丢失。 +- 参见 [Streaming](/zh-CN/concepts/streaming#preview-streaming-modes) 查看渠道映射矩阵。 ## Reactions(消息工具) - 使用 `message action=react`,并设置 `channel=mattermost`。 -- `messageId` 是 Mattermost 的 post id。 -- `emoji` 接受如 `thumbsup` 或 `:+1:` 这样的名称(冒号可选)。 -- 设置 `remove=true`(布尔值)可移除一个 reaction。 -- Reaction 添加 / 移除事件会作为系统事件转发到已路由的智能体会话。 +- `messageId` 是 Mattermost 帖子 id。 +- `emoji` 接受 `thumbsup` 或 `:+1:` 这类名称(冒号可选)。 +- 设置 `remove=true`(布尔值)以移除 reaction。 +- reaction 添加/移除事件会作为系统事件转发到已路由的智能体会话。 示例: @@ -291,7 +292,7 @@ message action=react channel=mattermost target=channel: messageId=.actions.reactions`。 ## 交互式按钮(消息工具) @@ -311,7 +312,7 @@ message action=react channel=mattermost target=channel: messageId= buttons=[[{"text":"Yes","callback_data":"yes"},{"text":"No","callback_data":"no"}]] @@ -320,40 +321,42 @@ message action=send channel=mattermost target=channel: buttons=[[{"te 按钮字段: - `text`(必填):显示标签。 -- `callback_data`(必填):点击后回传的值(作为 action ID 使用)。 +- `callback_data`(必填):点击后回传的值(用作 action ID)。 - `style`(可选):`"default"`、`"primary"` 或 `"danger"`。 当用户点击按钮时: -1. 所有按钮都会被替换为一行确认文本(例如,“✓ **Yes** selected by @user”)。 -2. 智能体会将该选择作为一条传入消息接收,并作出响应。 +1. 所有按钮都会被替换为一行确认文本(例如:“✓ **Yes** selected by @user”)。 +2. 智能体会将该选择作为一条入站消息接收,并作出响应。 说明: - 按钮回调使用 HMAC-SHA256 校验(自动完成,无需配置)。 -- Mattermost 会从其 API 响应中剥离回调数据(安全特性),因此点击后所有按钮 - 都会被移除——无法实现部分移除。 +- Mattermost 会从其 API 响应中去除 callback data(安全特性),因此点击后所有按钮 + 都会被移除——无法只移除部分按钮。 - 包含连字符或下划线的 action ID 会被自动清理 (Mattermost 路由限制)。 配置: -- `channels.mattermost.capabilities`:能力字符串数组。添加 `"inlineButtons"` 以在智能体系统提示中启用按钮工具说明。 -- `channels.mattermost.interactions.callbackBaseUrl`:按钮回调的可选外部基础 URL - (例如 `https://gateway.example.com`)。当 Mattermost 无法直接通过 Gateway 网关绑定的 host 访问时,请使用此项。 -- 在多账户配置中,你也可以在 +- `channels.mattermost.capabilities`:能力字符串数组。添加 `"inlineButtons"` 以 + 在智能体系统提示中启用按钮工具说明。 +- `channels.mattermost.interactions.callbackBaseUrl`:可选的外部基础 URL,用于按钮 + 回调(例如 `https://gateway.example.com`)。当 Mattermost 无法 + 直接通过 Gateway 网关的绑定主机访问它时,请使用此项。 +- 在多账户设置中,你也可以在 `channels.mattermost.accounts..interactions.callbackBaseUrl` 下设置相同字段。 - 如果省略 `interactions.callbackBaseUrl`,OpenClaw 会根据 `gateway.customBindHost` + `gateway.port` 推导回调 URL,然后回退到 `http://localhost:`。 - 可达性规则:按钮回调 URL 必须可从 Mattermost 服务器访问。 - `localhost` 仅在 Mattermost 和 OpenClaw 运行在同一主机 / 网络命名空间时有效。 -- 如果你的回调目标是私有地址 / tailnet / 内网地址,请将其 host / domain 添加到 Mattermost 的 - `ServiceSettings.AllowedUntrustedInternalConnections`。 + `localhost` 仅在 Mattermost 和 OpenClaw 运行于同一主机/网络命名空间时可用。 +- 如果你的回调目标是私有/tailnet/内部地址,请将其 host/domain 添加到 Mattermost + `ServiceSettings.AllowedUntrustedInternalConnections` 中。 ### 直接 API 集成(外部脚本) -外部脚本和 webhook 可以直接通过 Mattermost REST API 发送按钮, -而不必经过智能体的 `message` 工具。尽可能使用扩展中的 `buildButtonAttachments()`;如果发送原始 JSON,请遵循以下规则: +外部脚本和 webhook 可以直接通过 Mattermost REST API 发布按钮, +而不必通过智能体的 `message` 工具。尽可能使用插件中的 `buildButtonAttachments()`;如果发布原始 JSON,请遵循以下规则: **负载结构:** @@ -366,17 +369,17 @@ message action=send channel=mattermost target=channel: buttons=[[{"te { actions: [ { - id: "mybutton01", // alphanumeric only — see below - type: "button", // required, or clicks are silently ignored - name: "Approve", // display label - style: "primary", // optional: "default", "primary", "danger" + id: "mybutton01", // 仅限字母数字字符 —— 见下文 + type: "button", // 必填,否则点击会被静默忽略 + name: "Approve", // 显示标签 + style: "primary", // 可选:"default"、"primary"、"danger" integration: { url: "https://gateway.example.com/mattermost/interactions/default", context: { - action_id: "mybutton01", // must match button id (for name lookup) + action_id: "mybutton01", // 必须与按钮 id 匹配(用于名称查找) action: "approve", - // ... any custom fields ... - _token: "", // see HMAC section below + // ... 任何自定义字段 ... + _token: "", // 参见下方 HMAC 章节 }, }, }, @@ -389,27 +392,27 @@ message action=send channel=mattermost target=channel: buttons=[[{"te **关键规则:** -1. Attachments 应放在 `props.attachments` 中,而不是顶层 `attachments`(否则会被静默忽略)。 -2. 每个 action 都需要 `type: "button"` —— 缺少它时,点击会被静默吞掉。 -3. 每个 action 都需要一个 `id` 字段 —— 没有 ID 的 action 会被 Mattermost 忽略。 -4. Action `id` 必须是**仅字母数字**(`[a-zA-Z0-9]`)。连字符和下划线会破坏 - Mattermost 服务端的 action 路由(返回 404)。使用前请将它们移除。 -5. `context.action_id` 必须与按钮的 `id` 一致,这样确认消息才会显示按钮名称 - (例如 “Approve”),而不是原始 ID。 +1. Attachments 必须放在 `props.attachments` 中,而不是顶层 `attachments`(否则会被静默忽略)。 +2. 每个 action 都需要 `type: "button"` —— 没有它,点击会被静默吞掉。 +3. 每个 action 都需要 `id` 字段 —— Mattermost 会忽略没有 ID 的 action。 +4. Action `id` 必须**只包含字母数字字符**(`[a-zA-Z0-9]`)。连字符和下划线会破坏 + Mattermost 服务端的 action 路由(返回 404)。使用前请去掉它们。 +5. `context.action_id` 必须与按钮的 `id` 匹配,这样确认消息才会显示 + 按钮名称(例如 “Approve”),而不是原始 ID。 6. `context.action_id` 是必填项 —— 没有它,交互处理器会返回 400。 **HMAC token 生成:** -Gateway 网关使用 HMAC-SHA256 校验按钮点击。外部脚本必须生成 -与 Gateway 网关校验逻辑一致的 token: +Gateway 网关使用 HMAC-SHA256 校验按钮点击。外部脚本必须生成与 +Gateway 网关校验逻辑匹配的 token: 1. 从 bot token 派生 secret: `HMAC-SHA256(key="openclaw-mattermost-interactions", data=botToken)` -2. 构建 context 对象,包含除 `_token` 之外的所有字段。 -3. 使用**排序后的键**和**无空格**进行序列化(Gateway 网关使用 - 带排序键的 `JSON.stringify`,会产生紧凑输出)。 +2. 构建包含所有字段但**不含** `_token` 的 context 对象。 +3. 使用**排序后的键**和**无空格**进行序列化(Gateway 网关使用带排序键的 `JSON.stringify` + ,会生成紧凑输出)。 4. 签名:`HMAC-SHA256(key=secret, data=serializedContext)` -5. 将得到的十六进制摘要作为 `_token` 加入 context。 +5. 将生成的十六进制摘要作为 `_token` 添加到 context 中。 Python 示例: @@ -432,20 +435,20 @@ context = {**ctx, "_token": token} - Python 的 `json.dumps` 默认会添加空格(`{"key": "val"}`)。请使用 `separators=(",", ":")` 以匹配 JavaScript 的紧凑输出(`{"key":"val"}`)。 -- 始终对**所有** context 字段(不含 `_token`)进行签名。Gateway 网关会先移除 `_token`, - 然后对剩余所有内容签名。只签名子集会导致静默校验失败。 -- 使用 `sort_keys=True` —— Gateway 网关在签名前会对键排序,而 Mattermost 在存储负载时 +- 始终对**所有** context 字段(除 `_token` 外)进行签名。Gateway 网关会去掉 `_token`,然后 + 对剩余的全部内容签名。只签名子集会导致静默校验失败。 +- 使用 `sort_keys=True` —— Gateway 网关会在签名前对键进行排序,而 Mattermost 在存储负载时 可能会重排 context 字段。 -- 从 bot token 派生 secret(确定性),而不是使用随机字节。创建按钮的进程与负责校验的 Gateway 网关 - 必须使用相同的 secret。 +- 使用 bot token 派生 secret(确定性),而不是随机字节。这个 secret + 必须在创建按钮的进程与执行校验的 Gateway 网关之间保持一致。 ## 目录适配器 -Mattermost 插件包含一个目录适配器,可通过 Mattermost API 解析渠道名和用户名。 -这样就能在 `openclaw message send` 和 cron / webhook 投递中使用 -`#channel-name` 和 `@username` 作为 target。 +Mattermost 插件包含一个目录适配器,可通过 Mattermost API 解析渠道和用户名。 +这使得在 +`openclaw message send` 和 cron/webhook 投递中可以使用 `#channel-name` 和 `@username` 目标。 -无需配置 —— 该适配器会使用账户配置中的 bot token。 +无需配置——该适配器会使用账户配置中的 bot token。 ## 多账户 @@ -466,33 +469,34 @@ Mattermost 支持在 `channels.mattermost.accounts` 下配置多个账户: ## 故障排除 -- 渠道中没有回复:确认 bot 已加入该渠道,并提及它(oncall),使用触发前缀(onchar),或设置 `chatmode: "onmessage"`。 -- 认证错误:检查 bot token、base URL,以及账户是否已启用。 +- 渠道中没有回复:确认机器人已加入该渠道,并 @提及它(oncall)、使用触发前缀(onchar),或设置 `chatmode: "onmessage"`。 +- 认证错误:检查 bot token、base URL,以及该账户是否已启用。 - 多账户问题:环境变量仅适用于 `default` 账户。 - 原生斜杠命令返回 `Unauthorized: invalid command token.`:OpenClaw - 未接受该回调 token。常见原因包括: - - 斜杠命令注册在启动时失败,或仅部分完成 - - 回调打到了错误的 Gateway 网关 / 账户 + 没有接受该回调 token。常见原因: + - 启动时斜杠命令注册失败,或只完成了部分注册 + - 回调命中了错误的 Gateway 网关/账户 - Mattermost 仍保留指向旧回调目标的旧命令 - - Gateway 网关重启后未重新激活斜杠命令 + - Gateway 网关重启后没有重新激活斜杠命令 - 如果原生斜杠命令停止工作,请检查日志中是否有 `mattermost: failed to register slash commands` 或 `mattermost: native slash commands enabled but no commands could be registered`。 -- 如果省略了 `callbackUrl`,且日志警告回调被解析为 - `http://127.0.0.1:18789/...`,那么该 URL 很可能仅在 - Mattermost 与 OpenClaw 运行于同一主机 / 网络命名空间时可达。请改为显式设置一个外部可达的 `commands.callbackUrl`。 -- 按钮显示为空白框:智能体可能发送了格式错误的按钮数据。检查每个按钮是否同时包含 `text` 和 `callback_data` 字段。 +- 如果省略了 `callbackUrl`,且日志警告回调解析为 + `http://127.0.0.1:18789/...`,该 URL 很可能只有在 + Mattermost 与 OpenClaw 运行于同一主机/网络命名空间时才可访问。请改为设置一个 + 明确的、外部可访问的 `commands.callbackUrl`。 +- 按钮显示为白色方框:智能体可能发送了格式错误的按钮数据。检查每个按钮是否同时具有 `text` 和 `callback_data` 字段。 - 按钮能渲染但点击无效:确认 Mattermost 服务器配置中的 `AllowedUntrustedInternalConnections` 包含 `127.0.0.1 localhost`,并且 `ServiceSettings` 中的 `EnablePostActionIntegration` 为 `true`。 -- 按钮点击返回 404:按钮的 `id` 很可能包含连字符或下划线。Mattermost 的 action 路由器无法处理非字母数字 ID。仅使用 `[a-zA-Z0-9]`。 -- Gateway 网关日志显示 `invalid _token`:HMAC 不匹配。请检查你是否对所有 context 字段签名(而不是子集)、使用了排序键,并使用紧凑 JSON(无空格)。参见上方 HMAC 部分。 -- Gateway 网关日志显示 `missing _token in context`:按钮的 context 中缺少 `_token` 字段。构建集成负载时请确保包含它。 -- 确认信息显示的是原始 ID 而不是按钮名称:`context.action_id` 与按钮的 `id` 不一致。请将二者设置为相同的清洗后值。 +- 按钮点击返回 404:按钮的 `id` 很可能包含连字符或下划线。Mattermost 的 action 路由器在非字母数字 ID 上会失效。仅使用 `[a-zA-Z0-9]`。 +- Gateway 网关日志出现 `invalid _token`:HMAC 不匹配。请检查你是否对所有 context 字段进行了签名(而不是子集)、是否使用了排序后的键,以及是否使用了紧凑 JSON(无空格)。参见上面的 HMAC 章节。 +- Gateway 网关日志出现 `missing _token in context`:按钮的 context 中没有 `_token` 字段。请确保在构建集成负载时包含它。 +- 确认消息显示原始 ID 而不是按钮名称:`context.action_id` 与按钮的 `id` 不匹配。请将两者设置为同一个已清理的值。 - 智能体不知道按钮功能:在 Mattermost 渠道配置中添加 `capabilities: ["inlineButtons"]`。 ## 相关内容 -- [Channels Overview](/zh-CN/channels) — 所有支持的渠道 -- [Pairing](/zh-CN/channels/pairing) — 私信认证与配对流程 -- [Groups](/zh-CN/channels/groups) — 群组聊天行为与提及门控 -- [Channel Routing](/zh-CN/channels/channel-routing) — 消息的会话路由 -- [Security](/zh-CN/gateway/security) — 访问模型与加固 +- [Channels Overview](/zh-CN/channels) —— 所有支持的渠道 +- [Pairing](/zh-CN/channels/pairing) —— 私信认证和配对流程 +- [Groups](/zh-CN/channels/groups) —— 群聊行为和提及门控 +- [Channel Routing](/zh-CN/channels/channel-routing) —— 消息的会话路由 +- [Security](/zh-CN/gateway/security) —— 访问模型与加固 diff --git a/docs/zh-CN/channels/msteams.md b/docs/zh-CN/channels/msteams.md index 9e31b98cd..470965935 100644 --- a/docs/zh-CN/channels/msteams.md +++ b/docs/zh-CN/channels/msteams.md @@ -4,23 +4,23 @@ read_when: summary: Microsoft Teams 机器人支持状态、功能和配置 title: Microsoft Teams x-i18n: - generated_at: "2026-04-21T21:27:19Z" + generated_at: "2026-04-23T06:40:10Z" model: gpt-5.4 provider: openai - source_hash: ee9d52fb2cc7801e84249a705e0fa2052d4afbb7ef58cee2d3362b3e7012348c + source_hash: c1f093cbb9aed7d7f7348ec796b00f05ef66c601b5345214a08986940020d28e source_path: channels/msteams.md workflow: 15 --- # Microsoft Teams -> “进入此地者,放弃一切希望。” +> “进入此处者,放弃一切希望。” -状态:支持文本和私信附件;渠道/群组文件发送需要 `sharePointSiteId` + Graph 权限(参见[在群聊中发送文件](#sending-files-in-group-chats))。投票通过 Adaptive Cards 发送。消息操作会暴露显式的 `upload-file`,用于以文件为先的发送。 +状态:支持文本和私信附件;渠道/群组文件发送需要 `sharePointSiteId` + Graph 权限(见[在群组聊天中发送文件](#sending-files-in-group-chats))。投票通过 Adaptive Cards 发送。消息操作会暴露显式的 `upload-file`,用于以文件为主的发送。 ## 内置插件 -Microsoft Teams 在当前的 OpenClaw 版本中作为内置插件提供,因此在常规打包构建中不需要单独安装。 +Microsoft Teams 在当前的 OpenClaw 版本中作为内置插件提供,因此在常规打包构建中无需单独安装。 如果你使用的是较旧的构建版本,或是不包含内置 Teams 的自定义安装,请手动安装: @@ -28,22 +28,22 @@ Microsoft Teams 在当前的 OpenClaw 版本中作为内置插件提供,因此 openclaw plugins install @openclaw/msteams ``` -本地检出版本(从 git 仓库运行时): +本地检出(从 git 仓库运行时): ```bash openclaw plugins install ./path/to/local/msteams-plugin ``` -详情:[Plugins](/zh-CN/tools/plugin) +详情参见:[Plugins](/zh-CN/tools/plugin) -## 快速设置(初学者) +## 快速设置(新手) 1. 确保 Microsoft Teams 插件可用。 - - 当前打包发布的 OpenClaw 版本已默认内置该插件。 - - 较旧/自定义安装可通过上面的命令手动添加。 -2. 创建一个 **Azure Bot**(App ID + 客户端密钥 + tenant ID)。 + - 当前打包发布的 OpenClaw 版本已内置该插件。 + - 较旧/自定义安装可使用上面的命令手动添加。 +2. 创建一个 **Azure Bot**(App ID + 客户端密钥 + 租户 ID)。 3. 使用这些凭证配置 OpenClaw。 -4. 通过公共 URL 或隧道暴露 `/api/messages`(默认端口为 3978)。 +4. 通过公开 URL 或隧道暴露 `/api/messages`(默认端口为 3978)。 5. 安装 Teams 应用包并启动 Gateway 网关。 最小配置(客户端密钥): @@ -62,15 +62,15 @@ openclaw plugins install ./path/to/local/msteams-plugin } ``` -对于生产部署,建议考虑使用[联合身份验证](#federated-authentication-certificate--managed-identity)(证书或托管身份),而不是客户端密钥。 +对于生产部署,建议考虑使用[联邦身份验证](#federated-authentication-certificate--managed-identity)(证书或托管身份)来替代客户端密钥。 -注意:默认会阻止群聊(`channels.msteams.groupPolicy: "allowlist"`)。如需允许群组回复,请设置 `channels.msteams.groupAllowFrom`(或使用 `groupPolicy: "open"` 以允许任何成员,默认仍需提及门控)。 +注意:默认会阻止群组聊天(`channels.msteams.groupPolicy: "allowlist"`)。若要允许群组回复,请设置 `channels.msteams.groupAllowFrom`(或使用 `groupPolicy: "open"` 以允许任意成员,但默认仍需提及)。 ## 目标 -- 通过 Teams 私信、群聊或渠道与 OpenClaw 交流。 -- 保持路由确定性:回复始终返回消息到达时所在的渠道。 -- 默认采用安全的渠道行为(除非另有配置,否则必须提及)。 +- 通过 Teams 私信、群组聊天或渠道与 OpenClaw 交互。 +- 保持路由确定性:回复始终返回到消息来源的渠道。 +- 默认采用安全的渠道行为(除非已配置,否则必须提及)。 ## 配置写入 @@ -88,16 +88,16 @@ openclaw plugins install ./path/to/local/msteams-plugin **私信访问** -- 默认:`channels.msteams.dmPolicy = "pairing"`。未知发送者在获得批准前会被忽略。 +- 默认:`channels.msteams.dmPolicy = "pairing"`。未知发送者在获准前会被忽略。 - `channels.msteams.allowFrom` 应使用稳定的 AAD 对象 ID。 -- UPN/显示名称是可变的;默认禁用直接匹配,只有在启用 `channels.msteams.dangerouslyAllowNameMatching: true` 时才会启用。 +- UPN/显示名称是可变的;默认禁用直接匹配,只有启用 `channels.msteams.dangerouslyAllowNameMatching: true` 时才会启用。 - 当凭证允许时,向导可以通过 Microsoft Graph 将名称解析为 ID。 **群组访问** - 默认:`channels.msteams.groupPolicy = "allowlist"`(除非你添加 `groupAllowFrom`,否则会被阻止)。未设置时,可使用 `channels.defaults.groupPolicy` 覆盖默认值。 -- `channels.msteams.groupAllowFrom` 控制哪些发送者可以在群聊/渠道中触发(回退到 `channels.msteams.allowFrom`)。 -- 设置 `groupPolicy: "open"` 可允许任何成员(默认仍需提及门控)。 +- `channels.msteams.groupAllowFrom` 控制哪些发送者可以在群组聊天/渠道中触发(回退到 `channels.msteams.allowFrom`)。 +- 设置 `groupPolicy: "open"` 以允许任意成员(默认仍需提及)。 - 若要**不允许任何渠道**,请设置 `channels.msteams.groupPolicy: "disabled"`。 示例: @@ -115,11 +115,11 @@ openclaw plugins install ./path/to/local/msteams-plugin **Teams + 渠道允许列表** -- 通过在 `channels.msteams.teams` 下列出团队和渠道,限定群组/渠道回复范围。 +- 通过在 `channels.msteams.teams` 下列出团队和渠道来限定群组/渠道回复范围。 - 键应使用稳定的团队 ID 和渠道会话 ID。 -- 当 `groupPolicy="allowlist"` 且存在 teams 允许列表时,只接受列出的团队/渠道(需提及门控)。 -- 配置向导接受 `Team/Channel` 条目,并会为你存储它们。 -- 在启动时,OpenClaw 会将团队/渠道和用户允许列表中的名称解析为 ID(当 Graph 权限允许时),并记录映射;未解析的团队/渠道名称会按原样保留,但默认会在路由中被忽略,除非启用 `channels.msteams.dangerouslyAllowNameMatching: true`。 +- 当 `groupPolicy="allowlist"` 且存在 teams 允许列表时,仅接受已列出的团队/渠道(默认需提及)。 +- 配置向导接受 `Team/Channel` 条目,并会为你保存。 +- 启动时,OpenClaw 会将团队/渠道和用户允许列表中的名称解析为 ID(当 Graph 权限允许时),并记录映射;无法解析的团队/渠道名称会按输入保留,但默认会在路由时忽略,除非启用 `channels.msteams.dangerouslyAllowNameMatching: true`。 示例: @@ -143,17 +143,17 @@ openclaw plugins install ./path/to/local/msteams-plugin ## 工作原理 1. 确保 Microsoft Teams 插件可用。 - - 当前打包发布的 OpenClaw 版本已默认内置该插件。 - - 较旧/自定义安装可通过上面的命令手动添加。 -2. 创建一个 **Azure Bot**(App ID + 密钥 + tenant ID)。 -3. 构建一个 **Teams 应用包**,引用该 bot 并包含下面的 RSC 权限。 -4. 将 Teams 应用上传/安装到团队中(或用于私信的个人作用域)。 -5. 在 `~/.openclaw/openclaw.json`(或环境变量)中配置 `msteams`,并启动 Gateway 网关。 -6. Gateway 网关默认在 `/api/messages` 上监听 Bot Framework webhook 流量。 + - 当前打包发布的 OpenClaw 版本已内置该插件。 + - 较旧/自定义安装可使用上面的命令手动添加。 +2. 创建一个 **Azure Bot**(App ID + 密钥 + 租户 ID)。 +3. 构建一个 **Teams 应用包**,引用该机器人并包含下方的 RSC 权限。 +4. 将 Teams 应用上传/安装到团队中(或安装到个人范围用于私信)。 +5. 在 `~/.openclaw/openclaw.json`(或环境变量)中配置 `msteams`,然后启动 Gateway 网关。 +6. Gateway 网关默认会在 `/api/messages` 上监听 Bot Framework webhook 流量。 ## Azure Bot 设置(前置条件) -在配置 OpenClaw 之前,你需要创建一个 Azure Bot 资源。 +在配置 OpenClaw 之前,你需要先创建一个 Azure Bot 资源。 ### 第 1 步:创建 Azure Bot @@ -162,14 +162,14 @@ openclaw plugins install ./path/to/local/msteams-plugin | 字段 | 值 | | ------------------ | -------------------------------------------------------- | - | **Bot handle** | 你的 bot 名称,例如 `openclaw-msteams`(必须唯一) | + | **Bot handle** | 你的机器人名称,例如 `openclaw-msteams`(必须唯一) | | **Subscription** | 选择你的 Azure 订阅 | | **Resource group** | 新建或使用现有资源组 | | **Pricing tier** | 开发/测试使用 **Free** | - | **Type of App** | **Single Tenant**(推荐——见下方说明) | + | **Type of App** | **Single Tenant**(推荐,见下方说明) | | **Creation type** | **Create new Microsoft App ID** | -> **弃用通知:** 创建新的多租户 bot 已在 2025-07-31 后弃用。新 bot 请使用 **Single Tenant**。 +> **弃用通知:** 新建多租户机器人的功能已在 2025-07-31 后弃用。新机器人请使用 **Single Tenant**。 3. 点击 **Review + create** → **Create**(等待约 1–2 分钟) @@ -177,28 +177,30 @@ openclaw plugins install ./path/to/local/msteams-plugin 1. 前往你的 Azure Bot 资源 → **Configuration** 2. 复制 **Microsoft App ID** → 这就是你的 `appId` -3. 点击 **Manage Password** → 进入 App Registration -4. 在 **Certificates & secrets** 下点击 **New client secret** → 复制 **Value** → 这就是你的 `appPassword` +3. 点击 **Manage Password** → 前往 App Registration +4. 在 **Certificates & secrets** 下 → **New client secret** → 复制 **Value** → 这就是你的 `appPassword` 5. 前往 **Overview** → 复制 **Directory (tenant) ID** → 这就是你的 `tenantId` ### 第 3 步:配置消息端点 -1. 在 Azure Bot 中进入 **Configuration** +1. 在 Azure Bot 中前往 **Configuration** 2. 将 **Messaging endpoint** 设置为你的 webhook URL: - 生产环境:`https://your-domain.com/api/messages` - - 本地开发:使用隧道(参见下方[本地开发](#local-development-tunneling)) + - 本地开发:使用隧道(见下方[本地开发](#local-development-tunneling)) ### 第 4 步:启用 Teams 渠道 -1. 在 Azure Bot 中进入 **Channels** +1. 在 Azure Bot 中前往 **Channels** 2. 点击 **Microsoft Teams** → Configure → Save 3. 接受服务条款 -## 联合身份验证(证书 + 托管身份) + + +## 联邦身份验证(证书 + 托管身份) > 添加于 2026.3.24 -对于生产部署,OpenClaw 支持**联合身份验证**,作为比客户端密钥更安全的替代方案。提供两种方式: +对于生产部署,OpenClaw 支持将**联邦身份验证**作为比客户端密钥更安全的替代方案。提供两种方式: ### 选项 A:基于证书的身份验证 @@ -206,7 +208,7 @@ openclaw plugins install ./path/to/local/msteams-plugin **设置:** -1. 生成或获取一个证书(包含私钥的 PEM 格式)。 +1. 生成或获取一个证书(带私钥的 PEM 格式)。 2. 在 Entra ID → App Registration → **Certificates & secrets** → **Certificates** 中上传公钥证书。 **配置:** @@ -231,24 +233,24 @@ openclaw plugins install ./path/to/local/msteams-plugin - `MSTEAMS_AUTH_TYPE=federated` - `MSTEAMS_CERTIFICATE_PATH=/path/to/cert.pem` -### 选项 B:Azure 托管身份 +### 选项 B:Azure Managed Identity -使用 Azure 托管身份实现无密码身份验证。这非常适合部署在 Azure 基础设施上的场景(AKS、App Service、Azure VM),即存在可用托管身份时。 +使用 Azure Managed Identity 实现免密身份验证。这非常适合部署在 Azure 基础设施上的场景(AKS、App Service、Azure VM),前提是存在可用的托管身份。 **工作原理:** -1. bot 所在的 pod/VM 拥有一个托管身份(系统分配或用户分配)。 -2. 一个**联合身份凭证**将该托管身份连接到 Entra ID 应用注册。 -3. 在运行时,OpenClaw 使用 `@azure/identity` 从 Azure IMDS 端点(`169.254.169.254`)获取令牌。 -4. 该令牌会传递给 Teams SDK,用于 bot 身份验证。 +1. 机器人 pod/VM 具有托管身份(系统分配或用户分配)。 +2. 一个**联邦身份凭证**将托管身份链接到 Entra ID 应用注册。 +3. 运行时,OpenClaw 使用 `@azure/identity` 从 Azure IMDS 端点(`169.254.169.254`)获取令牌。 +4. 该令牌会传递给 Teams SDK 用于机器人身份验证。 **前置条件:** - 已启用托管身份的 Azure 基础设施(AKS workload identity、App Service、VM) -- 已在 Entra ID 应用注册上创建联合身份凭证 -- pod/VM 可通过网络访问 IMDS(`169.254.169.254:80`) +- 已在 Entra ID 应用注册上创建联邦身份凭证 +- pod/VM 能够通过网络访问 IMDS(`169.254.169.254:80`) -**配置(系统分配托管身份):** +**配置(系统分配的托管身份):** ```json5 { @@ -265,7 +267,7 @@ openclaw plugins install ./path/to/local/msteams-plugin } ``` -**配置(用户分配托管身份):** +**配置(用户分配的托管身份):** ```json5 { @@ -287,14 +289,14 @@ openclaw plugins install ./path/to/local/msteams-plugin - `MSTEAMS_AUTH_TYPE=federated` - `MSTEAMS_USE_MANAGED_IDENTITY=true` -- `MSTEAMS_MANAGED_IDENTITY_CLIENT_ID=`(仅适用于用户分配) +- `MSTEAMS_MANAGED_IDENTITY_CLIENT_ID=`(仅用于用户分配) ### AKS Workload Identity 设置 对于使用 workload identity 的 AKS 部署: 1. 在你的 AKS 集群上**启用 workload identity**。 -2. 在 Entra ID 应用注册上**创建联合身份凭证**: +2. 在 Entra ID 应用注册上**创建联邦身份凭证**: ```bash az ad app federated-credential create --id --parameters '{ @@ -324,17 +326,17 @@ openclaw plugins install ./path/to/local/msteams-plugin azure.workload.identity/use: "true" ``` -5. **确保网络可访问** IMDS(`169.254.169.254`)——如果你使用 NetworkPolicy,请添加一条出口规则,允许到 `169.254.169.254/32` 的 80 端口流量。 +5. **确保可通过网络访问** IMDS(`169.254.169.254`)——如果你使用 NetworkPolicy,请添加一条出口规则,允许访问 `169.254.169.254/32` 的 80 端口流量。 ### 身份验证类型对比 | 方式 | 配置 | 优点 | 缺点 | | -------------------- | ---------------------------------------------- | ---------------------------------- | ------------------------------------- | | **客户端密钥** | `appPassword` | 设置简单 | 需要轮换密钥,安全性较低 | -| **证书** | `authType: "federated"` + `certificatePath` | 无需通过网络共享密钥 | 证书管理有额外成本 | -| **托管身份** | `authType: "federated"` + `useManagedIdentity` | 无密码,无需管理密钥 | 需要 Azure 基础设施 | +| **证书** | `authType: "federated"` + `certificatePath` | 网络中无需共享密钥 | 证书管理有额外开销 | +| **Managed Identity** | `authType: "federated"` + `useManagedIdentity` | 免密,无需管理密钥 | 需要 Azure 基础设施 | -**默认行为:** 当未设置 `authType` 时,OpenClaw 默认使用客户端密钥身份验证。现有配置无需修改即可继续使用。 +**默认行为:** 当未设置 `authType` 时,OpenClaw 默认使用客户端密钥身份验证。现有配置无需修改即可继续工作。 ## 本地开发(隧道) @@ -357,7 +359,7 @@ tailscale funnel 3978 ## Teams Developer Portal(替代方式) -你可以不手动创建 manifest ZIP,而是使用 [Teams Developer Portal](https://dev.teams.microsoft.com/apps): +除了手动创建 manifest ZIP 外,你也可以使用 [Teams Developer Portal](https://dev.teams.microsoft.com/apps): 1. 点击 **+ New app** 2. 填写基本信息(名称、描述、开发者信息) @@ -367,31 +369,31 @@ tailscale funnel 3978 6. 点击 **Distribute** → **Download app package** 7. 在 Teams 中:**Apps** → **Manage your apps** → **Upload a custom app** → 选择该 ZIP -这通常比手动编辑 JSON manifest 更容易。 +这通常比手动编辑 JSON manifest 更简单。 -## 测试 Bot +## 测试机器人 **选项 A:Azure Web Chat(先验证 webhook)** -1. 在 Azure Portal 中进入你的 Azure Bot 资源 → **Test in Web Chat** -2. 发送一条消息——你应该能看到响应 -3. 这可以在设置 Teams 之前确认你的 webhook 端点正常工作 +1. 在 Azure Portal 中 → 你的 Azure Bot 资源 → **Test in Web Chat** +2. 发送一条消息 —— 你应该能看到回复 +3. 这可以确认你的 webhook 端点在配置 Teams 之前已正常工作 **选项 B:Teams(安装应用后)** -1. 安装 Teams 应用(侧载或组织目录) -2. 在 Teams 中找到该 bot 并发送一条私信 -3. 检查 Gateway 网关日志中的传入活动 +1. 安装 Teams 应用(侧载或通过组织目录) +2. 在 Teams 中找到该机器人并发送私信 +3. 检查 Gateway 网关日志中的传入 activity -## 设置(最小文本模式) +## 设置(仅最小文本支持) 1. **确保 Microsoft Teams 插件可用** - - 当前打包发布的 OpenClaw 版本已默认内置该插件。 + - 当前打包发布的 OpenClaw 版本已内置该插件。 - 较旧/自定义安装可手动添加: - 从 npm:`openclaw plugins install @openclaw/msteams` - 从本地检出:`openclaw plugins install ./path/to/local/msteams-plugin` -2. **Bot 注册** +2. **机器人注册** - 创建一个 Azure Bot(见上文),并记录: - App ID - 客户端密钥(App password) @@ -400,10 +402,10 @@ tailscale funnel 3978 3. **Teams 应用 manifest** - 包含一个 `bot` 条目,其中 `botId = `。 - 作用域:`personal`、`team`、`groupChat`。 - - `supportsFiles: true`(个人作用域文件处理必需)。 + - `supportsFiles: true`(个人作用域文件处理所必需)。 - 添加 RSC 权限(见下文)。 - 创建图标:`outline.png`(32x32)和 `color.png`(192x192)。 - - 将这三个文件一起打包为 ZIP:`manifest.json`、`outline.png`、`color.png`。 + - 将这三个文件一起打包成 zip:`manifest.json`、`outline.png`、`color.png`。 4. **配置 OpenClaw** @@ -421,46 +423,46 @@ tailscale funnel 3978 } ``` - 你也可以使用环境变量来代替配置键: + 你也可以使用环境变量代替配置键: - `MSTEAMS_APP_ID` - `MSTEAMS_APP_PASSWORD` - `MSTEAMS_TENANT_ID` - `MSTEAMS_AUTH_TYPE`(可选:`"secret"` 或 `"federated"`) - - `MSTEAMS_CERTIFICATE_PATH`(联合身份验证 + 证书) + - `MSTEAMS_CERTIFICATE_PATH`(联邦身份验证 + 证书) - `MSTEAMS_CERTIFICATE_THUMBPRINT`(可选,身份验证不要求) - - `MSTEAMS_USE_MANAGED_IDENTITY`(联合身份验证 + 托管身份) + - `MSTEAMS_USE_MANAGED_IDENTITY`(联邦身份验证 + 托管身份) - `MSTEAMS_MANAGED_IDENTITY_CLIENT_ID`(仅用户分配的 MI) -5. **Bot 端点** - - 将 Azure Bot Messaging Endpoint 设置为: - - `https://:3978/api/messages`(或你自定义的路径/端口)。 +5. **机器人端点** + - 将 Azure Bot 消息端点设置为: + - `https://:3978/api/messages`(或你选择的路径/端口)。 6. **运行 Gateway 网关** - 当内置或手动安装的插件可用,且存在带凭证的 `msteams` 配置时,Teams 渠道会自动启动。 ## 成员信息操作 -OpenClaw 为 Microsoft Teams 提供了由 Graph 支持的 `member-info` 操作,因此智能体和自动化流程可以直接从 Microsoft Graph 解析渠道成员详情(显示名称、电子邮件、角色)。 +OpenClaw 为 Microsoft Teams 提供基于 Graph 的 `member-info` 操作,因此智能体和自动化可以直接从 Microsoft Graph 解析渠道成员详情(显示名称、邮箱、角色)。 要求: -- `Member.Read.Group` RSC 权限(已包含在推荐的 manifest 中) -- 对于跨团队查询:具有管理员同意的 `User.Read.All` Graph 应用程序权限 +- `Member.Read.Group` RSC 权限(已包含在推荐 manifest 中) +- 对于跨团队查找:`User.Read.All` Graph Application 权限,并已授予管理员同意 该操作受 `channels.msteams.actions.memberInfo` 控制(默认:当 Graph 凭证可用时启用)。 ## 历史上下文 -- `channels.msteams.historyLimit` 控制会包装进提示中的最近渠道/群组消息数量。 -- 回退到 `messages.groupChat.historyLimit`。设置为 `0` 可禁用(默认 50)。 -- 获取到的线程历史会按发送者允许列表(`allowFrom` / `groupAllowFrom`)进行过滤,因此线程上下文预填充目前只包含来自允许发送者的消息。 -- 引用的附件上下文(从 Teams 回复 HTML 派生的 `ReplyTo*`)目前会按接收时的原样传递。 +- `channels.msteams.historyLimit` 控制会封装到提示词中的最近渠道/群组消息数量。 +- 回退到 `messages.groupChat.historyLimit`。设为 `0` 可禁用(默认 50)。 +- 获取到的线程历史会按发送者允许列表(`allowFrom` / `groupAllowFrom`)过滤,因此线程上下文预填充目前只包含允许的发送者消息。 +- 引用的附件上下文(由 Teams 回复 HTML 派生的 `ReplyTo*`)当前会按接收原样传递。 - 换句话说,允许列表控制谁可以触发智能体;目前只有特定的补充上下文路径会被过滤。 -- 私信历史可通过 `channels.msteams.dmHistoryLimit`(用户轮次)限制。每用户覆盖:`channels.msteams.dms[""].historyLimit`。 +- 私信历史可通过 `channels.msteams.dmHistoryLimit`(用户轮次)限制。按用户覆盖:`channels.msteams.dms[""].historyLimit`。 ## 当前 Teams RSC 权限(Manifest) -这些是我们的 Teams 应用 manifest 中**现有的 resourceSpecific 权限**。它们仅在安装了该应用的团队/聊天内生效。 +这些是我们 Teams 应用 manifest 中**现有的 resourceSpecific 权限**。它们仅适用于安装了该应用的团队/聊天内部。 **用于渠道(团队作用域):** @@ -472,13 +474,13 @@ OpenClaw 为 Microsoft Teams 提供了由 Graph 支持的 `member-info` 操作 - `TeamMember.Read.Group`(Application) - `TeamSettings.Read.Group`(Application) -**用于群聊:** +**用于群组聊天:** -- `ChatMessage.Read.Chat`(Application)- 无需 @mention 即可接收所有群聊消息 +- `ChatMessage.Read.Chat`(Application)- 无需 @mention 即可接收所有群组聊天消息 ## Teams Manifest 示例(已脱敏) -这是一个包含必需字段的最小有效示例。请替换其中的 ID 和 URL。 +包含所需字段的最小有效示例。请替换其中的 ID 和 URL。 ```json5 { @@ -526,7 +528,7 @@ OpenClaw 为 Microsoft Teams 提供了由 Graph 支持的 `member-info` 操作 } ``` -### Manifest 注意事项(必需字段) +### Manifest 注意事项(必填字段) - `bots[].botId` **必须**与 Azure Bot App ID 一致。 - `webApplicationInfo.id` **必须**与 Azure Bot App ID 一致。 @@ -539,13 +541,13 @@ OpenClaw 为 Microsoft Teams 提供了由 Graph 支持的 `member-info` 操作 要更新一个已安装的 Teams 应用(例如添加 RSC 权限): 1. 使用新设置更新你的 `manifest.json` -2. **增加 `version` 字段**(例如 `1.0.0` → `1.1.0`) -3. **重新打包为 ZIP**,包含 manifest 和图标(`manifest.json`、`outline.png`、`color.png`) +2. **递增 `version` 字段**(例如 `1.0.0` → `1.1.0`) +3. **重新打包 zip**,包含 manifest 和图标(`manifest.json`、`outline.png`、`color.png`) 4. 上传新的 zip: - **选项 A(Teams Admin Center):** Teams Admin Center → Teams apps → Manage apps → 找到你的应用 → Upload new version - **选项 B(侧载):** 在 Teams 中 → Apps → Manage your apps → Upload a custom app -5. **对于团队渠道:** 在每个团队中重新安装应用,以使新权限生效 -6. **完全退出并重新启动 Teams**(不只是关闭窗口),以清除缓存的应用元数据 +5. **对于团队渠道:** 在每个团队中重新安装应用,新的权限才会生效 +6. **完全退出并重新启动 Teams**(而不是只关闭窗口),以清除缓存的应用元数据 ## 功能:仅 RSC 与 Graph @@ -559,41 +561,41 @@ OpenClaw 为 Microsoft Teams 提供了由 Graph 支持的 `member-info` 操作 不可用: -- 渠道/群组**图片或文件内容**(负载仅包含 HTML 占位内容)。 +- 渠道/群组中的**图片或文件内容**(payload 仅包含 HTML 占位内容)。 - 下载存储在 SharePoint/OneDrive 中的附件。 -- 读取消息历史(超出实时 webhook 事件之外)。 +- 读取消息历史记录(实时 webhook 事件之外的内容)。 -### 使用**Teams RSC + Microsoft Graph 应用程序权限** +### 使用**Teams RSC + Microsoft Graph Application 权限** -额外支持: +额外提供: - 下载托管内容(粘贴到消息中的图片)。 - 下载存储在 SharePoint/OneDrive 中的文件附件。 - 通过 Graph 读取渠道/聊天消息历史。 -### RSC 与 Graph API +### RSC 与 Graph API 对比 -| 能力 | RSC 权限 | Graph API | +| 功能 | RSC 权限 | Graph API | | ----------------------- | -------------------- | ----------------------------------- | | **实时消息** | 是(通过 webhook) | 否(仅轮询) | | **历史消息** | 否 | 是(可查询历史) | -| **设置复杂度** | 仅应用 manifest | 需要管理员同意 + 令牌流 | -| **离线可用** | 否(必须在运行) | 是(可随时查询) | +| **设置复杂度** | 仅应用 manifest | 需要管理员同意 + 令牌流程 | +| **离线可用** | 否(必须正在运行) | 是(可随时查询) | -**结论:** RSC 用于实时监听;Graph API 用于历史访问。如果你希望在离线期间补收错过的消息,你需要启用带 `ChannelMessage.Read.All` 的 Graph API(需要管理员同意)。 +**结论:** RSC 用于实时监听;Graph API 用于历史访问。如果你想在离线期间补抓错过的消息,就需要使用带 `ChannelMessage.Read.All` 的 Graph API(需要管理员同意)。 -## 启用 Graph 的媒体 + 历史(渠道必需) +## 启用 Graph 的媒体 + 历史记录(渠道必需) -如果你需要**渠道**中的图片/文件,或想要获取**消息历史**,则必须启用 Microsoft Graph 权限并授予管理员同意。 +如果你需要在**渠道**中处理图片/文件,或想获取**消息历史**,则必须启用 Microsoft Graph 权限并授予管理员同意。 -1. 在 Entra ID(Azure AD)的 **App Registration** 中,添加 Microsoft Graph **Application permissions**: +1. 在 Entra ID(Azure AD)**App Registration** 中,添加 Microsoft Graph **Application permissions**: - `ChannelMessage.Read.All`(渠道附件 + 历史) - - `Chat.Read.All` 或 `ChatMessage.Read.All`(群聊) -2. **为租户授予管理员同意**。 -3. 提升 Teams 应用 **manifest 版本**,重新上传,并在 **Teams 中重新安装该应用**。 + - `Chat.Read.All` 或 `ChatMessage.Read.All`(群组聊天) +2. 为租户**授予管理员同意**。 +3. 提升 Teams 应用 **manifest version**,重新上传,并在 **Teams 中重新安装应用**。 4. **完全退出并重新启动 Teams**,以清除缓存的应用元数据。 -**用户提及的额外权限:** 对于当前会话中的用户,用户 @mention 可直接使用。但是,如果你希望动态搜索并提及**不在当前会话中**的用户,请添加 `User.Read.All`(Application)权限并授予管理员同意。 +**用户提及所需的额外权限:** 对于对话中的用户,用户 @mentions 开箱即用。但是,如果你想动态搜索并提及**不在当前对话中**的用户,请添加 `User.Read.All`(Application)权限并授予管理员同意。 ## 已知限制 @@ -602,57 +604,57 @@ OpenClaw 为 Microsoft Teams 提供了由 Graph 支持的 `member-info` 操作 Teams 通过 HTTP webhook 传递消息。如果处理耗时过长(例如 LLM 响应较慢),你可能会看到: - Gateway 网关超时 -- Teams 重试消息(导致重复) +- Teams 重试该消息(导致重复) - 回复丢失 -OpenClaw 通过快速返回并主动发送回复来处理这种情况,但响应非常慢时仍可能出现问题。 +OpenClaw 通过快速返回并主动发送回复来处理这个问题,但响应非常慢时仍可能出现问题。 ### 格式化 -Teams 的 Markdown 支持比 Slack 或 Discord 更有限: +Teams 的 markdown 能力比 Slack 或 Discord 更有限: -- 基本格式可用:**粗体**、_斜体_、`code`、链接 -- 复杂 Markdown(表格、嵌套列表)可能无法正确渲染 -- 支持用于投票和语义化展示发送的 Adaptive Cards(见下文) +- 基本格式可用:**加粗**、_斜体_、`code`、链接 +- 复杂 markdown(表格、嵌套列表)可能无法正确渲染 +- 投票和语义化展示发送支持 Adaptive Cards(见下文) ## 配置 -关键设置(共享渠道模式请参见 `/gateway/configuration`): +关键设置(共享渠道模式参见 `/gateway/configuration`): - `channels.msteams.enabled`:启用/禁用该渠道。 -- `channels.msteams.appId`、`channels.msteams.appPassword`、`channels.msteams.tenantId`:bot 凭证。 +- `channels.msteams.appId`、`channels.msteams.appPassword`、`channels.msteams.tenantId`:机器人凭证。 - `channels.msteams.webhook.port`(默认 `3978`) - `channels.msteams.webhook.path`(默认 `/api/messages`) - `channels.msteams.dmPolicy`:`pairing | allowlist | open | disabled`(默认:pairing) -- `channels.msteams.allowFrom`:私信允许列表(推荐使用 AAD 对象 ID)。当 Graph 访问可用时,向导会在设置期间将名称解析为 ID。 -- `channels.msteams.dangerouslyAllowNameMatching`:紧急开关,用于重新启用可变的 UPN/显示名匹配,以及直接按团队/渠道名称进行路由。 +- `channels.msteams.allowFrom`:私信允许列表(建议使用 AAD 对象 ID)。当 Graph 访问可用时,向导会在设置过程中将名称解析为 ID。 +- `channels.msteams.dangerouslyAllowNameMatching`:紧急开关,用于重新启用可变 UPN/显示名称匹配,以及直接的团队/渠道名称路由。 - `channels.msteams.textChunkLimit`:出站文本分块大小。 -- `channels.msteams.chunkMode`:`length`(默认)或 `newline`,会在按长度分块前先按空行(段落边界)拆分。 -- `channels.msteams.mediaAllowHosts`:入站附件主机允许列表(默认包含 Microsoft/Teams 域名)。 -- `channels.msteams.mediaAuthAllowHosts`:媒体重试时附加 Authorization 标头的主机允许列表(默认包含 Graph + Bot Framework 主机)。 +- `channels.msteams.chunkMode`:`length`(默认)或 `newline`,在按长度分块前先按空行(段落边界)拆分。 +- `channels.msteams.mediaAllowHosts`:传入附件主机的允许列表(默认是 Microsoft/Teams 域名)。 +- `channels.msteams.mediaAuthAllowHosts`:媒体重试时允许附加 Authorization 头的主机允许列表(默认是 Graph + Bot Framework 主机)。 - `channels.msteams.requireMention`:在渠道/群组中要求 @mention(默认 true)。 -- `channels.msteams.replyStyle`:`thread | top-level`(参见[回复样式](#reply-style-threads-vs-posts))。 +- `channels.msteams.replyStyle`:`thread | top-level`(见[回复样式](#reply-style-threads-vs-posts))。 - `channels.msteams.teams..replyStyle`:按团队覆盖。 - `channels.msteams.teams..requireMention`:按团队覆盖。 -- `channels.msteams.teams..tools`:默认的按团队工具策略覆盖(`allow`/`deny`/`alsoAllow`),当缺少渠道覆盖时使用。 -- `channels.msteams.teams..toolsBySender`:默认的按团队、按发送者工具策略覆盖(支持 `"*"` 通配符)。 +- `channels.msteams.teams..tools`:按团队的默认工具策略覆盖(`allow`/`deny`/`alsoAllow`),当缺少渠道级覆盖时使用。 +- `channels.msteams.teams..toolsBySender`:按团队、按发送者的默认工具策略覆盖(支持 `"*"` 通配符)。 - `channels.msteams.teams..channels..replyStyle`:按渠道覆盖。 - `channels.msteams.teams..channels..requireMention`:按渠道覆盖。 -- `channels.msteams.teams..channels..tools`:按渠道工具策略覆盖(`allow`/`deny`/`alsoAllow`)。 -- `channels.msteams.teams..channels..toolsBySender`:按渠道、按发送者工具策略覆盖(支持 `"*"` 通配符)。 +- `channels.msteams.teams..channels..tools`:按渠道的工具策略覆盖(`allow`/`deny`/`alsoAllow`)。 +- `channels.msteams.teams..channels..toolsBySender`:按渠道、按发送者的工具策略覆盖(支持 `"*"` 通配符)。 - `toolsBySender` 键应使用显式前缀: `id:`、`e164:`、`username:`、`name:`(旧版无前缀键仍只会映射到 `id:`)。 -- `channels.msteams.actions.memberInfo`:启用或禁用由 Graph 支持的成员信息操作(默认:当 Graph 凭证可用时启用)。 -- `channels.msteams.authType`:身份验证类型——`"secret"`(默认)或 `"federated"`。 -- `channels.msteams.certificatePath`:PEM 证书文件路径(联合身份验证 + 证书身份验证)。 +- `channels.msteams.actions.memberInfo`:启用或禁用基于 Graph 的成员信息操作(默认:当 Graph 凭证可用时启用)。 +- `channels.msteams.authType`:身份验证类型 —— `"secret"`(默认)或 `"federated"`。 +- `channels.msteams.certificatePath`:PEM 证书文件路径(联邦身份验证 + 证书认证)。 - `channels.msteams.certificateThumbprint`:证书指纹(可选,身份验证不要求)。 -- `channels.msteams.useManagedIdentity`:启用托管身份身份验证(联合模式)。 +- `channels.msteams.useManagedIdentity`:启用托管身份认证(联邦模式)。 - `channels.msteams.managedIdentityClientId`:用户分配托管身份的客户端 ID。 -- `channels.msteams.sharePointSiteId`:用于群聊/渠道中文件上传的 SharePoint 站点 ID(参见[在群聊中发送文件](#sending-files-in-group-chats))。 +- `channels.msteams.sharePointSiteId`:用于群组聊天/渠道文件上传的 SharePoint 站点 ID(见[在群组聊天中发送文件](#sending-files-in-group-chats))。 ## 路由与会话 -- 会话键遵循标准智能体格式(参见 [/concepts/session](/zh-CN/concepts/session)): +- 会话键遵循标准智能体格式(见 [/concepts/session](/zh-CN/concepts/session)): - 私信共享主会话(`agent::`)。 - 渠道/群组消息使用会话 ID: - `agent::msteams:channel:` @@ -660,19 +662,19 @@ Teams 的 Markdown 支持比 Slack 或 Discord 更有限: ## 回复样式:线程 vs 帖子 -Teams 最近在相同底层数据模型之上引入了两种渠道 UI 样式: +Teams 最近在相同的底层数据模型之上引入了两种渠道 UI 样式: | 样式 | 描述 | 推荐的 `replyStyle` | | ------------------------ | --------------------------------------------------------- | ------------------------ | -| **Posts**(经典) | 消息显示为卡片,下方带线程回复 | `thread`(默认) | +| **Posts**(经典) | 消息显示为卡片,下面附带线程式回复 | `thread`(默认) | | **Threads**(类似 Slack) | 消息线性流动,更像 Slack | `top-level` | -**问题:** Teams API 不会暴露某个渠道使用的是哪种 UI 样式。如果你使用了错误的 `replyStyle`: +**问题在于:** Teams API 不会暴露某个渠道使用的是哪种 UI 样式。如果你使用了错误的 `replyStyle`: -- 在线程式渠道中使用 `thread` → 回复会以不自然的嵌套方式显示 -- 在 Posts 样式渠道中使用 `top-level` → 回复会显示为独立的顶层帖子,而不是在线程内 +- 在线程式渠道中使用 `thread` → 回复会以别扭的嵌套方式显示 +- 在帖子式渠道中使用 `top-level` → 回复会显示为单独的顶层帖子,而不是线程内回复 -**解决方案:** 根据渠道的设置,按渠道配置 `replyStyle`: +**解决方案:** 根据渠道的实际设置,为每个渠道配置 `replyStyle`: ```json5 { @@ -697,40 +699,40 @@ Teams 最近在相同底层数据模型之上引入了两种渠道 UI 样式: **当前限制:** -- **私信:** 图片和文件附件可通过 Teams bot 文件 API 工作。 -- **渠道/群组:** 附件保存在 M365 存储中(SharePoint/OneDrive)。webhook 负载仅包含 HTML 占位内容,不包含实际文件字节。**下载渠道附件需要 Graph API 权限。** -- 对于显式的文件优先发送,请使用 `action=upload-file`,并配合 `media` / `filePath` / `path`;可选的 `message` 会成为附带文本/评论,而 `filename` 会覆盖上传名称。 +- **私信:** 图片和文件附件通过 Teams 机器人文件 API 工作。 +- **渠道/群组:** 附件存放在 M365 存储中(SharePoint/OneDrive)。webhook payload 只包含 HTML 占位内容,不包含实际文件字节。**下载渠道附件需要 Graph API 权限**。 +- 对于显式的文件优先发送,请使用 `action=upload-file`,搭配 `media` / `filePath` / `path`;可选的 `message` 会作为附带文本/评论,`filename` 会覆盖上传名称。 -如果没有 Graph 权限,包含图片的渠道消息将仅以文本形式接收(bot 无法访问图片内容)。 -默认情况下,OpenClaw 只会从 Microsoft/Teams 主机名下载媒体。可通过 `channels.msteams.mediaAllowHosts` 覆盖(使用 `["*"]` 可允许任意主机)。 -Authorization 标头仅会附加到 `channels.msteams.mediaAuthAllowHosts` 中的主机(默认包含 Graph + Bot Framework 主机)。请保持该列表严格受限(避免多租户后缀)。 +如果没有 Graph 权限,包含图片的渠道消息将仅作为文本接收(机器人无法访问图片内容)。 +默认情况下,OpenClaw 只会从 Microsoft/Teams 主机名下载媒体。你可以使用 `channels.msteams.mediaAllowHosts` 覆盖(使用 `["*"]` 允许任意主机)。 +Authorization 头仅会附加到 `channels.msteams.mediaAuthAllowHosts` 中的主机(默认为 Graph + Bot Framework 主机)。请保持该列表严格受限(避免使用多租户后缀)。 -## 在群聊中发送文件 +## 在群组聊天中发送文件 -bot 可以在私信中通过 FileConsentCard 流程发送文件(内置支持)。但是,**在群聊/渠道中发送文件**需要额外设置: +机器人可以在私信中使用 FileConsentCard 流程发送文件(内置支持)。但是,**在群组聊天/渠道中发送文件**需要额外设置: -| 上下文 | 文件发送方式 | 所需设置 | +| 场景 | 文件发送方式 | 所需设置 | | ------------------------ | -------------------------------------------- | ----------------------------------------------- | -| **私信** | FileConsentCard → 用户接受 → bot 上传 | 开箱即用 | -| **群聊/渠道** | 上传到 SharePoint → 分享链接 | 需要 `sharePointSiteId` + Graph 权限 | -| **图片(任意上下文)** | Base64 编码内联 | 开箱即用 | +| **私信** | FileConsentCard → 用户接受 → 机器人上传 | 开箱即用 | +| **群组聊天/渠道** | 上传到 SharePoint → 分享链接 | 需要 `sharePointSiteId` + Graph 权限 | +| **图片(任意场景)** | Base64 编码内联 | 开箱即用 | -### 为什么群聊需要 SharePoint +### 为什么群组聊天需要 SharePoint -bot 没有个人 OneDrive 驱动器(`/me/drive` Graph API 端点不适用于应用身份)。要在群聊/渠道中发送文件,bot 需要上传到一个 **SharePoint 站点** 并创建共享链接。 +机器人没有个人 OneDrive 驱动器(`/me/drive` Graph API 端点对应用身份无效)。要在群组聊天/渠道中发送文件,机器人需要上传到 **SharePoint 站点** 并创建共享链接。 ### 设置 -1. 在 Entra ID(Azure AD)→ App Registration 中添加 **Graph API 权限**: - - `Sites.ReadWrite.All`(Application)- 将文件上传到 SharePoint +1. 在 Entra ID(Azure AD)→ App Registration 中添加 Graph API 权限: + - `Sites.ReadWrite.All`(Application)- 上传文件到 SharePoint - `Chat.Read.All`(Application)- 可选,启用按用户共享链接 -2. **为租户授予管理员同意**。 +2. 为租户**授予管理员同意**。 3. **获取你的 SharePoint 站点 ID:** ```bash - # 通过 Graph Explorer,或使用带有效令牌的 curl: + # 通过 Graph Explorer 或使用有效令牌的 curl: curl -H "Authorization: Bearer $TOKEN" \ "https://graph.microsoft.com/v1.0/sites/{hostname}:/{site-path}" @@ -738,7 +740,7 @@ bot 没有个人 OneDrive 驱动器(`/me/drive` Graph API 端点不适用于 curl -H "Authorization: Bearer $TOKEN" \ "https://graph.microsoft.com/v1.0/sites/contoso.sharepoint.com:/sites/BotFiles" - # 响应包含:"id": "contoso.sharepoint.com,guid1,guid2" + # 响应中包含:"id": "contoso.sharepoint.com,guid1,guid2" ``` 4. **配置 OpenClaw:** @@ -761,35 +763,35 @@ bot 没有个人 OneDrive 驱动器(`/me/drive` Graph API 端点不适用于 | `Sites.ReadWrite.All` only | 组织范围共享链接(组织内任何人都可访问) | | `Sites.ReadWrite.All` + `Chat.Read.All` | 按用户共享链接(仅聊天成员可访问) | -按用户共享更安全,因为只有聊天参与者可以访问该文件。如果缺少 `Chat.Read.All` 权限,bot 会回退到组织范围共享。 +按用户共享更安全,因为只有聊天参与者能够访问该文件。如果缺少 `Chat.Read.All` 权限,机器人会回退到组织范围共享。 ### 回退行为 | 场景 | 结果 | | ------------------------------------------------- | -------------------------------------------------- | -| 群聊 + 文件 + 已配置 `sharePointSiteId` | 上传到 SharePoint,发送共享链接 | -| 群聊 + 文件 + 未配置 `sharePointSiteId` | 尝试上传到 OneDrive(可能失败),仅发送文本 | +| 群组聊天 + 文件 + 已配置 `sharePointSiteId` | 上传到 SharePoint,发送共享链接 | +| 群组聊天 + 文件 + 未配置 `sharePointSiteId` | 尝试上传到 OneDrive(可能失败),仅发送文本 | | 个人聊天 + 文件 | FileConsentCard 流程(无需 SharePoint 也可工作) | -| 任意上下文 + 图片 | Base64 编码内联(无需 SharePoint 也可工作) | +| 任意场景 + 图片 | Base64 编码内联(无需 SharePoint 也可工作) | ### 文件存储位置 -上传的文件会存储在已配置 SharePoint 站点默认文档库中的 `/OpenClawShared/` 文件夹里。 +上传的文件会存储在已配置 SharePoint 站点默认文档库中的 `/OpenClawShared/` 文件夹内。 ## 投票(Adaptive Cards) -OpenClaw 通过 Adaptive Cards 发送 Teams 投票(Teams 没有原生投票 API)。 +OpenClaw 将 Teams 投票作为 Adaptive Cards 发送(Teams 没有原生投票 API)。 - CLI:`openclaw message poll --channel msteams --target conversation: ...` -- 投票由 Gateway 网关记录到 `~/.openclaw/msteams-polls.json`。 +- 投票由 Gateway 网关记录在 `~/.openclaw/msteams-polls.json` 中。 - Gateway 网关必须保持在线才能记录投票。 -- 投票尚不会自动发布结果摘要(如有需要,请检查存储文件)。 +- 投票目前不会自动发布结果摘要(如有需要,请检查存储文件)。 ## 展示卡片 -使用 `message` 工具或 CLI,将语义化展示负载发送给 Teams 用户或会话。OpenClaw 会基于通用展示契约将其渲染为 Teams Adaptive Cards。 +使用 `message` 工具或 CLI,将语义化展示 payload 发送给 Teams 用户或会话。OpenClaw 会根据通用展示契约,将其渲染为 Teams Adaptive Cards。 -`presentation` 参数接受语义块。提供 `presentation` 时,消息文本为可选项。 +`presentation` 参数接受语义化区块。提供 `presentation` 时,消息文本是可选的。 **智能体工具:** @@ -813,11 +815,11 @@ openclaw message send --channel msteams \ --presentation '{"title":"Hello","blocks":[{"type":"text","text":"Hello!"}]}' ``` -关于目标格式的详情,请参见下方[目标格式](#target-formats)。 +有关 target 格式的详细信息,见下方[目标格式](#target-formats)。 ## 目标格式 -MSTeams 目标使用前缀来区分用户和会话: +MSTeams target 使用前缀来区分用户和会话: | 目标类型 | 格式 | 示例 | | ------------------- | -------------------------------- | --------------------------------------------------- | @@ -835,10 +837,10 @@ openclaw message send --channel msteams --target "user:40a1a0ed-..." --message " # 按显示名称向用户发送(会触发 Graph API 查找) openclaw message send --channel msteams --target "user:John Smith" --message "Hello" -# 向群聊或渠道发送 +# 发送到群组聊天或渠道 openclaw message send --channel msteams --target "conversation:19:abc...@thread.tacv2" --message "Hello" -# 向会话发送展示卡片 +# 向某个会话发送展示卡片 openclaw message send --channel msteams --target "conversation:19:abc...@thread.tacv2" \ --presentation '{"title":"Hello","blocks":[{"type":"text","text":"Hello"}]}' ``` @@ -866,23 +868,23 @@ openclaw message send --channel msteams --target "conversation:19:abc...@thread. } ``` -注意:如果没有 `user:` 前缀,名称默认会按群组/团队解析。按显示名称定位个人时,请始终使用 `user:`。 +注意:如果没有 `user:` 前缀,名称默认会按群组/团队解析。按显示名称定位人员时,务必使用 `user:`。 ## 主动消息 -- 只有在用户已经互动**之后**,才可以发送主动消息,因为我们会在那时存储会话引用。 -- 有关 `dmPolicy` 和允许列表门控,请参见 `/gateway/configuration`。 +- 只有在用户已经发生过交互之后,才可以发送**主动消息**,因为我们会在那时存储会话引用。 +- 有关 `dmPolicy` 和允许列表门控,参见 `/gateway/configuration`。 ## 团队和渠道 ID(常见陷阱) -Teams URL 中的 `groupId` 查询参数**不是**用于配置的团队 ID。请从 URL 路径中提取 ID: +Teams URL 中的 `groupId` 查询参数**不是**用于配置的团队 ID。请改为从 URL 路径中提取 ID: **团队 URL:** ``` https://teams.microsoft.com/l/team/19%3ABk4j...%40thread.tacv2/conversations?groupId=... └────────────────────────────┘ - 团队 ID(对其进行 URL 解码) + 团队 ID(对此进行 URL 解码) ``` **渠道 URL:** @@ -890,7 +892,7 @@ https://teams.microsoft.com/l/team/19%3ABk4j...%40thread.tacv2/conversations?gro ``` https://teams.microsoft.com/l/channel/19%3A15bc...%40thread.tacv2/ChannelName?groupId=... └─────────────────────────┘ - 渠道 ID(对其进行 URL 解码) + 渠道 ID(对此进行 URL 解码) ``` **用于配置时:** @@ -901,44 +903,44 @@ https://teams.microsoft.com/l/channel/19%3A15bc...%40thread.tacv2/ChannelName?gr ## 私有渠道 -bot 在私有渠道中的支持有限: +机器人在私有渠道中的支持有限: | 功能 | 标准渠道 | 私有渠道 | | ---------------------------- | ----------------- | ---------------------- | -| bot 安装 | 是 | 有限 | +| 机器人安装 | 是 | 有限 | | 实时消息(webhook) | 是 | 可能不可用 | | RSC 权限 | 是 | 行为可能不同 | -| @mentions | 是 | 如果 bot 可访问 | -| Graph API 历史记录 | 是 | 是(需要权限) | +| @mentions | 是 | 如果机器人可访问 | +| Graph API 历史记录 | 是 | 是(有权限时) | -**如果私有渠道无法工作,可使用以下变通方法:** +**如果私有渠道不可用,可尝试以下变通方法:** -1. 使用标准渠道进行 bot 交互 -2. 使用私信——用户始终可以直接向 bot 发消息 -3. 使用 Graph API 进行历史访问(需要 `ChannelMessage.Read.All`) +1. 使用标准渠道进行机器人交互 +2. 使用私信 —— 用户始终可以直接向机器人发送消息 +3. 使用 Graph API 访问历史记录(需要 `ChannelMessage.Read.All`) ## 故障排除 ### 常见问题 -- **渠道中不显示图片:** 缺少 Graph 权限或管理员同意。请重新安装 Teams 应用,并完全退出/重新打开 Teams。 -- **渠道中没有响应:** 默认要求提及;请设置 `channels.msteams.requireMention=false` 或按团队/渠道配置。 -- **版本不匹配(Teams 仍显示旧 manifest):** 删除并重新添加该应用,然后完全退出 Teams 以刷新。 -- **webhook 返回 401 Unauthorized:** 在未使用 Azure JWT 时手动测试会出现该情况——这表示端点可达,但身份验证失败。请使用 Azure Web Chat 进行正确测试。 +- **渠道中不显示图片:** 缺少 Graph 权限或管理员同意。重新安装 Teams 应用,并彻底退出/重新打开 Teams。 +- **渠道中没有响应:** 默认要求提及;请设置 `channels.msteams.requireMention=false`,或按团队/渠道进行配置。 +- **版本不匹配(Teams 仍显示旧 manifest):** 移除后重新添加应用,并彻底退出 Teams 以刷新。 +- **webhook 返回 401 Unauthorized:** 在没有 Azure JWT 的情况下手动测试时这是预期行为 —— 说明端点可达,但身份验证失败。请使用 Azure Web Chat 正确测试。 ### Manifest 上传错误 -- **“Icon file cannot be empty”:“** manifest 引用了大小为 0 字节的图标文件。请创建有效的 PNG 图标(`outline.png` 为 32x32,`color.png` 为 192x192)。 -- **“webApplicationInfo.Id already in use”:“** 该应用仍安装在其他团队/聊天中。请先找到并卸载,或等待 5–10 分钟让变更传播。 -- **上传时出现 “Something went wrong”:** 请改为通过 [https://admin.teams.microsoft.com](https://admin.teams.microsoft.com) 上传,打开浏览器 DevTools(F12)→ Network 选项卡,并检查响应体中的实际错误。 -- **侧载失败:** 尝试使用 “Upload an app to your org's app catalog” 而不是 “Upload a custom app”——这通常可以绕过侧载限制。 +- **“Icon file cannot be empty”:** manifest 引用了大小为 0 字节的图标文件。请创建有效的 PNG 图标(`outline.png` 为 32x32,`color.png` 为 192x192)。 +- **“webApplicationInfo.Id already in use”:** 该应用仍安装在其他团队/聊天中。请先找到并卸载,或等待 5–10 分钟完成传播。 +- **上传时出现 “Something went wrong”:** 请改用 [https://admin.teams.microsoft.com](https://admin.teams.microsoft.com) 上传,打开浏览器 DevTools(F12)→ Network 选项卡,并检查响应体中的实际错误。 +- **侧载失败:** 试试使用 “Upload an app to your org's app catalog” 而不是 “Upload a custom app” —— 这通常可以绕过侧载限制。 -### RSC 权限不起作用 +### RSC 权限不生效 -1. 确认 `webApplicationInfo.id` 与你的 bot App ID 完全一致 +1. 验证 `webApplicationInfo.id` 与你的机器人 App ID 完全一致 2. 重新上传应用,并在团队/聊天中重新安装 3. 检查你的组织管理员是否阻止了 RSC 权限 -4. 确认你使用了正确的作用域:团队使用 `ChannelMessage.Read.Group`,群聊使用 `ChatMessage.Read.Chat` +4. 确认你使用了正确的作用域:团队使用 `ChannelMessage.Read.Group`,群组聊天使用 `ChatMessage.Read.Chat` ## 参考资料 @@ -953,7 +955,7 @@ bot 在私有渠道中的支持有限: ## 相关内容 - [Channels Overview](/zh-CN/channels) — 所有支持的渠道 -- [Pairing](/zh-CN/channels/pairing) — 私信身份验证和配对流程 -- [Groups](/zh-CN/channels/groups) — 群聊行为和提及门控 +- [Pairing](/zh-CN/channels/pairing) — 私信身份验证与配对流程 +- [Groups](/zh-CN/channels/groups) — 群组聊天行为与提及门控 - [Channel Routing](/zh-CN/channels/channel-routing) — 消息的会话路由 -- [Security](/zh-CN/gateway/security) — 访问模型和安全加固 +- [Security](/zh-CN/gateway/security) — 访问模型与加固 diff --git a/docs/zh-CN/cli/plugins.md b/docs/zh-CN/cli/plugins.md index f8bab98c6..941937cc0 100644 --- a/docs/zh-CN/cli/plugins.md +++ b/docs/zh-CN/cli/plugins.md @@ -1,14 +1,14 @@ --- read_when: - 你想安装或管理 Gateway 网关插件或兼容的捆绑包 - - 你想调试插件加载失败 -summary: '`openclaw plugins` 的 CLI 参考(列出、安装、市场、卸载、启用 / 禁用、Doctor)' + - 你想调试插件加载失败问题 +summary: '`openclaw plugins` 的 CLI 设置参考(list、install、marketplace、uninstall、enable/disable、doctor)' title: 插件 x-i18n: - generated_at: "2026-04-23T06:18:15Z" + generated_at: "2026-04-23T06:40:17Z" model: gpt-5.4 provider: openai - source_hash: ad76a8068054d145db578ed01f1fb0726fff884c48d256ad8c0b708a516cd727 + source_hash: 80e324995fa2dbb5babb9631714eb2449a1c8c00411bf6bf44c4c74bc9a3e2b8 source_path: cli/plugins.md workflow: 15 --- @@ -19,7 +19,7 @@ x-i18n: 相关内容: -- 插件系统:[插件](/zh-CN/tools/plugin) +- 插件系统:[Plugins](/zh-CN/tools/plugin) - 捆绑包兼容性:[插件捆绑包](/zh-CN/plugins/bundles) - 插件清单 + schema:[插件清单](/zh-CN/plugins/manifest) - 安全加固:[安全](/zh-CN/gateway/security) @@ -46,49 +46,49 @@ openclaw plugins marketplace list openclaw plugins marketplace list --json ``` -内置插件随 OpenClaw 一起提供。其中一些默认启用(例如内置模型提供商、内置语音提供商和内置浏览器插件);另一些则需要执行 `plugins enable`。 +内置插件随 OpenClaw 一起发布。其中一些默认启用(例如内置模型提供商、内置语音提供商以及内置浏览器插件);另一些则需要运行 `plugins enable`。 -原生 OpenClaw 插件必须提供带有内联 JSON Schema 的 `openclaw.plugin.json`(即使为空也要有 `configSchema`)。兼容捆绑包则使用它们自己的捆绑包清单。 +原生 OpenClaw 插件必须随附 `openclaw.plugin.json`,并包含内联 JSON Schema(`configSchema`,即使为空也需要提供)。兼容捆绑包则改用它们自己的 bundle manifest。 -`plugins list` 会显示 `Format: openclaw` 或 `Format: bundle`。详细列表 / info 输出还会显示捆绑包子类型(`codex`、`claude` 或 `cursor`)以及检测到的捆绑包能力。 +`plugins list` 会显示 `Format: openclaw` 或 `Format: bundle`。详细列表 / 信息输出还会显示 bundle 子类型(`codex`、`claude` 或 `cursor`),以及检测到的 bundle 能力。 ### 安装 ```bash -openclaw plugins install # 先查 ClawHub,再查 npm +openclaw plugins install # 先 ClawHub,后 npm openclaw plugins install clawhub: # 仅 ClawHub openclaw plugins install --force # 覆盖现有安装 openclaw plugins install --pin # 固定版本 openclaw plugins install --dangerously-force-unsafe-install openclaw plugins install # 本地路径 -openclaw plugins install @ # 市场 -openclaw plugins install --marketplace # 市场(显式) +openclaw plugins install @ # marketplace +openclaw plugins install --marketplace # marketplace(显式) openclaw plugins install --marketplace https://github.com// ``` -不带前缀的包名会先在 ClawHub 中查找,再回退到 npm。安全提示:请像对待可执行代码一样对待插件安装。优先固定版本。 +裸包名会先在 ClawHub 中查找,然后再查找 npm。安全提示:请将插件安装视为执行代码。优先使用固定版本。 -如果配置无效,`plugins install` 通常会以失败关闭,并提示你先运行 `openclaw doctor --fix`。唯一记录在案的例外,是针对显式选择加入 `openclaw.install.allowInvalidConfigRecovery` 的插件所提供的一条受限的内置插件恢复路径。 +如果配置无效,`plugins install` 通常会以安全关闭方式失败,并提示你先运行 `openclaw doctor --fix`。唯一有文档说明的例外,是一个针对内置插件的窄范围恢复路径,用于那些显式选择加入 `openclaw.install.allowInvalidConfigRecovery` 的插件。 -`--force` 会复用现有安装目标,并原地覆盖已安装的插件或 hook 包。当你有意从新的本地路径、归档文件、ClawHub 包或 npm 工件重新安装相同 id 时,请使用它。对于已跟踪 npm 插件的常规升级,优先使用 `openclaw plugins update `。 +`--force` 会复用现有安装目标,并原地覆盖已安装的插件或 hook 包。当你明确要从新的本地路径、归档、ClawHub 包或 npm 制品重新安装同一 id 时,请使用它。对于已跟踪 npm 插件的常规升级,优先使用 `openclaw plugins update `。 -`--pin` 仅适用于 npm 安装。它不支持与 `--marketplace` 一起使用,因为市场安装会保存市场来源元数据,而不是 npm spec。 +`--pin` 仅适用于 npm 安装。不支持与 `--marketplace` 一起使用,因为 marketplace 安装会保存 marketplace 源元数据,而不是 npm spec。 -`--dangerously-force-unsafe-install` 是一个紧急破玻璃选项,用于处理内置危险代码扫描器的误报。即使内置扫描器报告 `critical` 级别发现,它也允许安装继续,但它**不会**绕过插件 `before_install` hook 策略拦截,也**不会**绕过扫描失败。 +`--dangerously-force-unsafe-install` 是一个紧急兜底选项,用于处理内置危险代码扫描器的误报。即使内置扫描器报告 `critical` 级发现,它也允许继续安装,但它**不会**绕过插件 `before_install` hook 的策略阻止,也**不会**绕过扫描失败。 -这个 CLI 标志适用于插件安装 / 更新流程。由 Gateway 网关支持的 skill 依赖安装使用对应的 `dangerouslyForceUnsafeInstall` 请求覆盖,而 `openclaw skills install` 仍然是独立的 ClawHub skill 下载 / 安装流程。 +这个 CLI 标志适用于插件 install / update 流程。由 Gateway 网关支持的技能依赖安装使用对应的 `dangerouslyForceUnsafeInstall` 请求覆盖项,而 `openclaw skills install` 仍然是独立的 ClawHub Skills 下载 / 安装流程。 -`plugins install` 也是安装在 `package.json` 中暴露 `openclaw.hooks` 的 hook 包的安装界面。对于过滤后的 hook 可见性和按 hook 启用,请使用 `openclaw hooks`,而不是包安装。 +`plugins install` 也是暴露了 `openclaw.hooks` 的 hook 包在 `package.json` 中的安装入口。请使用 `openclaw hooks` 来查看经过筛选的 hook 可见性以及按 hook 启用,而不是用于包安装。 -npm spec **仅限 registry**(包名 + 可选的**精确版本**或 **dist-tag**)。Git / URL / 文件 spec 和 semver 范围都会被拒绝。出于安全考虑,依赖安装会使用 `--ignore-scripts` 运行。 +npm spec **仅支持 registry**(包名 + 可选的**精确版本**或 **dist-tag**)。Git / URL / file spec 和 semver 范围都会被拒绝。为确保安全,依赖安装会使用 `--ignore-scripts` 运行。 -不带版本的 spec 和 `@latest` 会停留在稳定通道上。如果 npm 将其中任意一种解析为预发布版本,OpenClaw 会停止并要求你通过预发布标签(例如 `@beta` / `@rc`)或精确的预发布版本(例如 `@1.2.3-beta.4`)显式选择加入。 +裸 spec 和 `@latest` 会停留在稳定轨道上。如果 npm 将其中任一项解析为预发布版本,OpenClaw 会停止,并要求你通过预发布 tag(例如 `@beta` / `@rc`)或精确的预发布版本(例如 `@1.2.3-beta.4`)显式选择加入。 -如果一个不带前缀的安装 spec 与某个内置插件 id 匹配(例如 `diffs`),OpenClaw 会直接安装该内置插件。要安装同名的 npm 包,请使用显式带作用域的 spec(例如 `@scope/diffs`)。 +如果一个裸安装 spec 与某个内置插件 id 匹配(例如 `diffs`),OpenClaw 会直接安装该内置插件。若要安装同名的 npm 包,请使用显式的带作用域 spec(例如 `@scope/diffs`)。 支持的归档格式:`.zip`、`.tgz`、`.tar.gz`、`.tar`。 -也支持 Claude 市场安装。 +也支持 Claude marketplace 安装。 ClawHub 安装使用显式的 `clawhub:` 定位符: @@ -97,22 +97,22 @@ openclaw plugins install clawhub:openclaw-codex-app-server openclaw plugins install clawhub:openclaw-codex-app-server@1.2.3 ``` -OpenClaw 现在也会优先为安全的裸 npm 插件 spec 使用 ClawHub。只有当 ClawHub 没有该包或该版本时,才会回退到 npm: +OpenClaw 现在也会优先为裸 npm-safe 插件 spec 使用 ClawHub。只有当 ClawHub 中没有该包或该版本时,才会回退到 npm: ```bash openclaw plugins install openclaw-codex-app-server ``` -OpenClaw 会从 ClawHub 下载包归档,检查声明的插件 API / 最低 Gateway 网关兼容性,然后通过常规归档路径进行安装。记录的安装会保留其 ClawHub 来源元数据,以供后续更新使用。 +OpenClaw 会从 ClawHub 下载包归档,检查声明的插件 API / 最低 Gateway 网关兼容性,然后通过常规归档路径安装。已记录的安装会保留其 ClawHub 源元数据,以便后续更新。 -当市场名称存在于 Claude 的本地注册表缓存 `~/.claude/plugins/known_marketplaces.json` 中时,使用 `plugin@marketplace` 简写: +当 marketplace 名称存在于 Claude 的本地注册表缓存 `~/.claude/plugins/known_marketplaces.json` 中时,可使用 `plugin@marketplace` 简写: ```bash openclaw plugins marketplace list openclaw plugins install @ ``` -当你想显式传递市场来源时,请使用 `--marketplace`: +如果你想显式传递 marketplace 源,请使用 `--marketplace`: ```bash openclaw plugins install --marketplace @@ -121,24 +121,24 @@ openclaw plugins install --marketplace https://github.com// openclaw plugins install --marketplace ./my-marketplace ``` -市场来源可以是: +Marketplace 源可以是: -- 来自 `~/.claude/plugins/known_marketplaces.json` 的 Claude 已知市场名称 -- 本地市场根目录或 `marketplace.json` 路径 -- 形如 `owner/repo` 的 GitHub 仓库简写 -- 形如 `https://github.com/owner/repo` 的 GitHub 仓库 URL +- `~/.claude/plugins/known_marketplaces.json` 中 Claude 已知 marketplace 名称 +- 本地 marketplace 根目录或 `marketplace.json` 路径 +- GitHub 仓库简写,例如 `owner/repo` +- GitHub 仓库 URL,例如 `https://github.com/owner/repo` - git URL -对于从 GitHub 或 git 加载的远程市场,插件条目必须保留在克隆下来的市场仓库内部。OpenClaw 接受该仓库中的相对路径来源,并拒绝远程清单中的 HTTP(S)、绝对路径、git、GitHub 和其他非路径插件来源。 +对于从 GitHub 或 git 加载的远程 marketplace,插件条目必须保持在克隆后的 marketplace 仓库内。OpenClaw 接受来自该仓库的相对路径源,并拒绝远程 manifest 中的 HTTP(S)、绝对路径、git、GitHub 以及其他非路径插件源。 对于本地路径和归档,OpenClaw 会自动检测: - 原生 OpenClaw 插件(`openclaw.plugin.json`) -- 兼容 Codex 的捆绑包(`.codex-plugin/plugin.json`) -- 兼容 Claude 的捆绑包(`.claude-plugin/plugin.json` 或默认的 Claude 组件布局) -- 兼容 Cursor 的捆绑包(`.cursor-plugin/plugin.json`) +- Codex 兼容捆绑包(`.codex-plugin/plugin.json`) +- Claude 兼容捆绑包(`.claude-plugin/plugin.json` 或默认的 Claude 组件布局) +- Cursor 兼容捆绑包(`.cursor-plugin/plugin.json`) -兼容捆绑包会安装到常规扩展根目录中,并参与相同的 list / info / enable / disable 流程。目前,支持捆绑包 Skills、Claude command-skills、Claude `settings.json` 默认值、Claude `.lsp.json` / 清单声明的 `lspServers` 默认值、Cursor command-skills,以及兼容的 Codex hook 目录;其他检测到的捆绑包能力会显示在诊断 / info 中,但尚未接入运行时执行。 +兼容捆绑包会安装到常规插件根目录中,并参与相同的 list / info / enable / disable 流程。目前,已支持 bundle Skills、Claude command-skills、Claude `settings.json` 默认值、Claude `.lsp.json` / manifest 声明的 `lspServers` 默认值、Cursor command-skills,以及兼容的 Codex hook 目录;其他已检测到的 bundle 能力会在诊断 / 信息中显示,但尚未接入运行时执行。 ### 列表 @@ -149,17 +149,17 @@ openclaw plugins list --verbose openclaw plugins list --json ``` -使用 `--enabled` 仅显示已加载的插件。使用 `--verbose` 可从表格视图切换到按插件显示详细行,包括来源 / 起源 / 版本 / 激活元数据。使用 `--json` 获取机器可读的清单和注册表诊断。 +使用 `--enabled` 仅显示已加载的插件。使用 `--verbose` 可从表格视图切换到按插件显示的详细行,其中包含 source / origin / version / activation 元数据。使用 `--json` 可获取机器可读的清单以及注册表诊断信息。 -使用 `--link` 避免复制本地目录(会添加到 `plugins.load.paths`): +使用 `--link` 可避免复制本地目录(会添加到 `plugins.load.paths`): ```bash openclaw plugins install -l ./my-plugin ``` -`--force` 不支持与 `--link` 一起使用,因为链接安装会复用源路径,而不是复制到受管理的安装目标上。 +`--force` 不支持与 `--link` 一起使用,因为链接安装会复用源路径,而不是复制到受管安装目标上。 -在 npm 安装中使用 `--pin`,可将解析得到的精确 spec(`name@version`)保存到 `plugins.installs` 中,而默认行为则保持不固定版本。 +在 npm 安装中使用 `--pin`,可将解析出的精确 spec(`name@version`)保存到 `plugins.installs` 中,同时保持默认行为为不固定版本。 ### 卸载 @@ -169,11 +169,11 @@ openclaw plugins uninstall --dry-run openclaw plugins uninstall --keep-files ``` -`uninstall` 会从 `plugins.entries`、`plugins.installs`、插件允许列表以及链接的 `plugins.load.paths` 条目中移除插件记录(如适用)。对于活跃的内存插件,memory 槽位会重置为 `memory-core`。 +`uninstall` 会从 `plugins.entries`、`plugins.installs`、插件 allowlist,以及在适用时的已链接 `plugins.load.paths` 条目中移除插件记录。对于活动中的 memory 插件,memory 槽位会重置为 `memory-core`。 默认情况下,卸载还会删除活动 state-dir 插件根目录下的插件安装目录。使用 `--keep-files` 可保留磁盘上的文件。 -`--keep-config` 作为 `--keep-files` 的废弃别名仍然受支持。 +`--keep-config` 作为 `--keep-files` 的已弃用别名仍受支持。 ### 更新 @@ -185,19 +185,19 @@ openclaw plugins update @openclaw/voice-call@beta openclaw plugins update openclaw-codex-app-server --dangerously-force-unsafe-install ``` -更新会应用到 `plugins.installs` 中已跟踪的安装,以及 `hooks.internal.installs` 中已跟踪的 hook 包安装。 +更新会应用于 `plugins.installs` 中跟踪的安装,以及 `hooks.internal.installs` 中跟踪的 hook 包安装。 -当你传入插件 id 时,OpenClaw 会复用为该插件记录的安装 spec。这意味着先前保存的 dist-tag(例如 `@beta`)和精确固定版本在后续执行 `update ` 时会继续被使用。 +当你传入插件 id 时,OpenClaw 会复用为该插件记录的安装 spec。这意味着此前保存的 dist-tag(例如 `@beta`)和固定的精确版本,之后在运行 `update ` 时仍会继续使用。 -对于 npm 安装,你也可以传入带有 dist-tag 或精确版本的显式 npm 包 spec。OpenClaw 会将该包名解析回已跟踪的插件记录,更新该已安装插件,并为未来基于 id 的更新记录新的 npm spec。 +对于 npm 安装,你也可以传入带有 dist-tag 或精确版本的显式 npm 包 spec。OpenClaw 会将该包名回溯解析到已跟踪的插件记录,更新那个已安装插件,并为将来基于 id 的更新记录新的 npm spec。 -传入不带版本或标签的 npm 包名,同样会解析回已跟踪的插件记录。当某个插件被固定到精确版本,而你想让它回到 registry 的默认发布线时,请使用这种方式。 +仅传入不带版本或 tag 的 npm 包名,也会回溯解析到已跟踪的插件记录。当某个插件被固定到精确版本,而你想把它移回 registry 的默认发布线时,可使用这种方式。 -在执行实际的 npm 更新之前,OpenClaw 会根据 npm registry 元数据检查已安装包版本。如果已安装版本和记录的工件标识已经与解析后的目标一致,则会跳过更新,不会下载、重新安装,也不会重写 `openclaw.json`。 +在实际执行 npm 更新之前,OpenClaw 会将已安装包版本与 npm registry 元数据进行检查。如果已安装版本与记录的制品标识已经匹配解析出的目标版本,则会跳过更新,不会下载、重新安装,也不会重写 `openclaw.json`。 -当存在已保存的完整性哈希,而获取到的工件哈希发生变化时,OpenClaw 会将其视为 npm 工件漂移。交互式 `openclaw plugins update` 命令会打印预期和实际哈希,并在继续之前请求确认。非交互式更新辅助工具会以失败关闭,除非调用方提供显式的继续策略。 +当存在已存储的完整性哈希,而获取到的制品哈希发生变化时,OpenClaw 会将其视为 npm 制品漂移。交互式 `openclaw plugins update` 命令会打印预期哈希和实际哈希,并在继续前请求确认。非交互式更新辅助流程会以安全关闭方式失败,除非调用方提供显式的继续策略。 -`--dangerously-force-unsafe-install` 也可用于 `plugins update`,作为在插件更新期间处理内置危险代码扫描误报的紧急覆盖选项。它仍然不会绕过插件 `before_install` 策略拦截或扫描失败拦截,并且它只适用于插件更新,不适用于 hook 包更新。 +`--dangerously-force-unsafe-install` 也可用于 `plugins update`,作为处理插件更新期间内置危险代码扫描误报的紧急覆盖项。它仍然不会绕过插件 `before_install` 策略阻止或扫描失败阻止,并且只适用于插件更新,不适用于 hook 包更新。 ### 检查 @@ -206,20 +206,20 @@ openclaw plugins inspect openclaw plugins inspect --json ``` -用于单个插件的深度内省。显示身份信息、加载状态、来源、已注册能力、hooks、工具、命令、服务、Gateway 网关方法、HTTP 路由、策略标志、诊断、安装元数据、捆绑包能力,以及任何检测到的 MCP 或 LSP 服务器支持。 +对单个插件进行深度检查。显示标识、加载状态、来源、已注册能力、hooks、工具、命令、服务、Gateway 网关方法、HTTP 路由、策略标志、诊断信息、安装元数据、bundle 能力,以及任何检测到的 MCP 或 LSP 服务器支持。 每个插件都会根据其在运行时实际注册的内容进行分类: -- **plain-capability** — 一种能力类型(例如仅提供商插件) +- **plain-capability** — 一种能力类型(例如仅 provider 插件) - **hybrid-capability** — 多种能力类型(例如文本 + 语音 + 图像) -- **hook-only** — 只有 hooks,没有能力或界面 +- **hook-only** — 只有 hooks,没有能力或表面 - **non-capability** — 有工具 / 命令 / 服务,但没有能力 -关于能力模型的更多信息,请参见 [插件形态](/zh-CN/plugins/architecture#plugin-shapes)。 +有关能力模型的更多信息,请参阅 [Plugin shapes](/zh-CN/plugins/architecture#plugin-shapes)。 -`--json` 标志会输出适合脚本和审计使用的机器可读报告。 +`--json` 标志会输出适用于脚本处理和审计的机器可读报告。 -`inspect --all` 会渲染一个面向整个集群的表格,其中包含形态、能力种类、兼容性提示、捆绑包能力和 hook 摘要列。 +`inspect --all` 会渲染一个全局表格,其中包含 shape、capability kinds、compatibility notices、bundle capabilities 和 hook summary 列。 `info` 是 `inspect` 的别名。 @@ -229,16 +229,15 @@ openclaw plugins inspect --json openclaw plugins doctor ``` -`doctor` 会报告插件加载错误、清单 / 发现诊断以及兼容性提示。当一切正常时,它会打印 `No plugin issues -detected.` +`doctor` 会报告插件加载错误、manifest / 发现诊断信息以及兼容性提示。当一切正常时,它会输出 `No plugin issues detected.` -对于诸如缺少 `register` / `activate` 导出之类的模块形态失败,请使用 `OPENCLAW_PLUGIN_LOAD_DEBUG=1` 重新运行,以在诊断输出中包含精简的导出形态摘要。 +对于缺少 `register` / `activate` 导出之类的模块形状失败问题,请使用 `OPENCLAW_PLUGIN_LOAD_DEBUG=1` 重新运行,以便在诊断输出中包含紧凑的导出形状摘要。 -### 市场 +### Marketplace ```bash openclaw plugins marketplace list openclaw plugins marketplace list --json ``` -市场列表接受本地市场路径、`marketplace.json` 路径、形如 `owner/repo` 的 GitHub 简写、GitHub 仓库 URL 或 git URL。`--json` 会打印解析后的来源标签,以及已解析的市场清单和插件条目。 +Marketplace list 接受本地 marketplace 路径、`marketplace.json` 路径、如 `owner/repo` 这样的 GitHub 简写、GitHub 仓库 URL 或 git URL。`--json` 会输出解析后的源标签,以及已解析的 marketplace manifest 和插件条目。 diff --git a/docs/zh-CN/cli/security.md b/docs/zh-CN/cli/security.md index 5e7297854..857cc5fe3 100644 --- a/docs/zh-CN/cli/security.md +++ b/docs/zh-CN/cli/security.md @@ -1,14 +1,14 @@ --- read_when: - - 你想对配置/状态运行快速安全审计 + - 你想对配置/状态运行一次快速安全审计 - 你想应用安全的“修复”建议(权限、收紧默认值) summary: '`openclaw security` 的 CLI 参考(审计并修复常见安全陷阱)' -title: security +title: 安全 x-i18n: - generated_at: "2026-04-05T08:20:23Z" + generated_at: "2026-04-23T06:40:18Z" model: gpt-5.4 provider: openai - source_hash: e5a3e4ab8e0dfb6c10763097cb4483be2431985f16de877523eb53e2122239ae + source_hash: 92b80468403b7d329391c40add9ae9c0e2423f5c6ff162291fa13ab91ace985d source_path: cli/security.md workflow: 15 --- @@ -19,7 +19,7 @@ x-i18n: 相关内容: -- 安全指南:[安全性](/gateway/security) +- 安全指南:[安全](/zh-CN/gateway/security) ## 审计 @@ -32,27 +32,28 @@ openclaw security audit --fix openclaw security audit --json ``` -当多个私信发送者共享主会话时,审计会发出警告,并推荐使用**安全私信模式**:`session.dmScope="per-channel-peer"`(对于多账户渠道则使用 `per-account-channel-peer`)。这适用于协作式/共享收件箱的加固。由相互不信任/对抗性的操作员共享同一个 Gateway 网关并不是推荐的设置;请使用单独的 Gateway 网关(或单独的 OS 用户/主机)来拆分信任边界。 -当配置暗示可能存在共享用户入口时(例如开放的私信/群组策略、已配置的群组目标,或通配符发送者规则),它还会发出 `security.trust_model.multi_user_heuristic`,并提醒你 OpenClaw 默认采用个人助理信任模型。 -对于有意的共享用户设置,审计建议对所有会话启用沙箱隔离、将文件系统访问限制在工作区范围内,并且不要在该运行时上放置个人/私有身份或凭证。 -当小模型(`<=300B`)在未启用沙箱隔离的情况下使用,且启用了 web/browser 工具时,它也会发出警告。 -对于 webhook 入口,当 `hooks.token` 重用了 Gateway 网关令牌、`hooks.token` 过短、`hooks.path="/"`、`hooks.defaultSessionKey` 未设置、`hooks.allowedAgentIds` 未受限制、启用了请求 `sessionKey` 覆盖,以及在未设置 `hooks.allowedSessionKeyPrefixes` 的情况下启用了覆盖时,它也会发出警告。 -当 sandbox Docker 设置已配置但沙箱模式关闭时、当 `gateway.nodes.denyCommands` 使用了无效的类模式/未知条目时(仅支持精确的节点命令名匹配,不支持 shell 文本过滤)、当 `gateway.nodes.allowCommands` 显式启用了危险的节点命令时、当全局 `tools.profile="minimal"` 被智能体工具配置文件覆盖时、当开放群组在没有沙箱/工作区保护的情况下暴露运行时/文件系统工具时,以及当已安装的扩展插件工具在宽松工具策略下可能可达时,它也会发出警告。 -它还会标记 `gateway.allowRealIpFallback=true`(如果代理配置错误,存在请求头伪造风险)和 `discovery.mdns.mode="full"`(通过 mDNS TXT 记录泄露元数据)。 -当沙箱浏览器使用 Docker `bridge` 网络而未设置 `sandbox.browser.cdpSourceRange` 时,它也会发出警告。 +当多个私信发送者共享主会话时,审计会发出警告,并建议使用 **安全私信模式**:`session.dmScope="per-channel-peer"`(对于多账号渠道,则使用 `per-account-channel-peer`),适用于共享收件箱。 +这是为了加固协作式/共享式收件箱。由彼此不信任或存在对抗关系的操作人员共享同一个 Gateway 网关,并不是推荐的设置;应通过单独的 Gateway 网关(或单独的操作系统用户/主机)来划分信任边界。 +当配置表明很可能存在共享用户入口时,它还会输出 `security.trust_model.multi_user_heuristic`(例如开放的私信/群组策略、已配置的群组目标,或通配符发送者规则),并提醒你 OpenClaw 默认采用个人助理信任模型。 +对于有意的共享用户设置,审计建议对所有会话启用沙箱隔离,将文件系统访问限制在工作区范围内,并且不要在该运行时中放入个人/私有身份或凭证。 +当使用小模型(`<=300B`)且未启用沙箱隔离,同时启用了 web/browser 工具时,它也会发出警告。 +对于 webhook 入口,它会在以下情况下发出警告:`hooks.token` 复用 Gateway 网关 token、`hooks.token` 过短、`hooks.path="/"`、未设置 `hooks.defaultSessionKey`、`hooks.allowedAgentIds` 未受限制、启用了请求 `sessionKey` 覆盖,以及启用了覆盖但未设置 `hooks.allowedSessionKeyPrefixes`。 +当配置了沙箱 Docker 设置但沙箱模式处于关闭状态时,它也会发出警告;当 `gateway.nodes.denyCommands` 使用无效的类模式/未知条目时也会发出警告(这里只支持精确的节点命令名匹配,不支持 shell 文本过滤);当 `gateway.nodes.allowCommands` 显式启用危险节点命令时会发出警告;当全局 `tools.profile="minimal"` 被智能体工具配置文件覆盖时会发出警告;当开放群组在没有沙箱/工作区防护的情况下暴露运行时/文件系统工具时会发出警告;当已安装的 plugin 工具可能在宽松工具策略下可被访问时也会发出警告。 +它还会将 `gateway.allowRealIpFallback=true` 标记为风险项(如果代理配置错误,会有 header 伪造风险),并将 `discovery.mdns.mode="full"` 标记为风险项(通过 mDNS TXT 记录泄露元数据)。 +当沙箱浏览器使用 Docker `bridge` 网络但未设置 `sandbox.browser.cdpSourceRange` 时,它也会发出警告。 它还会标记危险的沙箱 Docker 网络模式(包括 `host` 和 `container:*` 命名空间加入)。 -当现有沙箱浏览器 Docker 容器缺少或使用了过时的哈希标签时(例如迁移前的容器缺少 `openclaw.browserConfigEpoch`),它也会发出警告,并建议运行 `openclaw sandbox recreate --browser --all`。 -当基于 npm 的插件/hook 安装记录未固定版本、缺少完整性元数据,或与当前已安装的软件包版本不一致时,它也会发出警告。 -当渠道允许列表依赖可变的名称/邮箱/标签而非稳定 ID 时(适用于 Discord、Slack、Google Chat、Microsoft Teams、Mattermost,以及适用的 IRC 范围),它也会发出警告。 -当 `gateway.auth.mode="none"` 导致 Gateway 网关 HTTP API 在没有共享密钥的情况下可被访问时(`/tools/invoke` 加上任何已启用的 `/v1/*` 端点),它也会发出警告。 -以 `dangerous`/`dangerously` 为前缀的设置是明确的 break-glass 操作员覆盖项;启用其中某一项本身并不自动构成安全漏洞报告。 -完整的危险参数清单,请参阅[安全性](/gateway/security)中的“非安全或危险标志摘要”部分。 +当现有的沙箱浏览器 Docker 容器缺少或使用了过期的哈希标签时(例如迁移前容器缺少 `openclaw.browserConfigEpoch`),它也会发出警告,并建议运行 `openclaw sandbox recreate --browser --all`。 +当基于 npm 的 plugin/hook 安装记录未固定版本、缺少完整性元数据,或与当前已安装的软件包版本不一致时,它也会发出警告。 +当渠道 allowlist 依赖可变名称/邮箱/标签而不是稳定 ID 时,它会发出警告(适用于 Discord、Slack、Google Chat、Microsoft Teams、Mattermost,以及适用范围内的 IRC)。 +当 `gateway.auth.mode="none"` 使 Gateway 网关 HTTP API 在没有共享密钥的情况下可访问时,它也会发出警告(`/tools/invoke` 以及任何已启用的 `/v1/*` 端点)。 +以 `dangerous`/`dangerously` 为前缀的设置,是明确的紧急破玻璃式操作员覆盖项;启用其中某一项本身并不自动构成安全漏洞报告。 +如需查看完整的危险参数清单,请参见[安全](/zh-CN/gateway/security)中的“`Insecure or dangerous flags summary`”章节。 SecretRef 行为: - `security audit` 会以只读模式解析其目标路径中受支持的 SecretRef。 - 如果当前命令路径中某个 SecretRef 不可用,审计会继续进行,并报告 `secretDiagnostics`(而不是崩溃)。 -- `--token` 和 `--password` 仅覆盖该次命令调用的深度探测认证;它们不会重写配置或 SecretRef 映射。 +- `--token` 和 `--password` 只会覆盖本次命令调用的深度探测认证;它们不会重写配置或 SecretRef 映射。 ## JSON 输出 @@ -63,7 +64,7 @@ openclaw security audit --json | jq '.summary' openclaw security audit --deep --json | jq '.findings[] | select(.severity=="critical") | .checkId' ``` -如果组合使用 `--fix` 和 `--json`,输出将同时包含修复操作和最终报告: +如果同时使用 `--fix` 和 `--json`,输出会同时包含修复操作和最终报告: ```bash openclaw security audit --fix --json | jq '{fix: .fix.ok, summary: .report.summary}' @@ -71,20 +72,20 @@ openclaw security audit --fix --json | jq '{fix: .fix.ok, summary: .report.summa ## `--fix` 会修改什么 -`--fix` 会应用安全、确定性的修复措施: +`--fix` 会应用安全且确定性的修复措施: -- 将常见的 `groupPolicy="open"` 切换为 `groupPolicy="allowlist"`(包括受支持渠道中的账户变体) -- 当 WhatsApp 群组策略切换为 `allowlist` 时,如果已存在存储的 `allowFrom` 文件且配置中尚未定义 `allowFrom`,则会从该文件为 `groupAllowFrom` 设定初始值 +- 将常见的 `groupPolicy="open"` 切换为 `groupPolicy="allowlist"`(包括受支持渠道中的账号变体) +- 当 WhatsApp 群组策略切换为 `allowlist` 时,如果已存在存储的 `allowFrom` 文件且配置中尚未定义 `allowFrom`,则从该文件为 `groupAllowFrom` 设定初始值 - 将 `logging.redactSensitive` 从 `"off"` 设置为 `"tools"` - 收紧状态/配置以及常见敏感文件的权限 (`credentials/*.json`、`auth-profiles.json`、`sessions.json`、会话 `*.jsonl`) -- 也会收紧 `openclaw.json` 中引用的配置 include 文件 -- 在 POSIX 主机上使用 `chmod`,在 Windows 上使用 `icacls` 重置 +- 也会收紧从 `openclaw.json` 引用的配置 include 文件的权限 +- 在 POSIX 主机上使用 `chmod`,在 Windows 上使用 `icacls` 重置权限 `--fix` **不会**: -- 轮换令牌/密码/API 密钥 +- 轮换 token/password/API key - 禁用工具(`gateway`、`cron`、`exec` 等) -- 更改 Gateway 网关绑定/认证/网络暴露选择 -- 删除或重写插件/Skills +- 更改 Gateway 网关的绑定/认证/网络暴露选择 +- 删除或重写 plugins/Skills diff --git a/docs/zh-CN/cli/update.md b/docs/zh-CN/cli/update.md index 90fe03c23..218030ebe 100644 --- a/docs/zh-CN/cli/update.md +++ b/docs/zh-CN/cli/update.md @@ -1,24 +1,24 @@ --- read_when: - - 你想安全地更新源码检出副本 - - 你需要了解 `--update` 简写行为 -summary: '`openclaw update` 的 CLI 参考(相对安全的源码更新 + Gateway 网关自动重启)' -title: update + - 你想相对安全地更新源码检出副本 + - 你需要理解 `--update` 简写行为 +summary: '`openclaw update` 的 CLI 参考(相对安全的源更新 + Gateway 网关 自动重启)' +title: 更新 x-i18n: - generated_at: "2026-04-23T06:18:33Z" + generated_at: "2026-04-23T06:40:28Z" model: gpt-5.4 provider: openai - source_hash: dc049ecf3d35fe276a1e5962bb8e5316dbbc3219ef0b91ee64d41cbbea20f9ae + source_hash: abcfbd2fb66f560f2c6e9d78d37355510d78946eaeafa17d67fe36bc158ad5cd source_path: cli/update.md workflow: 15 --- # `openclaw update` -安全更新 OpenClaw,并在 stable/beta/dev 渠道之间切换。 +安全地更新 OpenClaw,并在 stable/beta/dev 渠道之间切换。 如果你通过 **npm/pnpm/bun** 安装(全局安装,无 git 元数据), -更新会通过 [Updating](/zh-CN/install/updating) 中的包管理器流程进行。 +更新会通过 [Updating](/zh-CN/install/updating) 中的软件包管理器流程进行。 ## 用法 @@ -39,21 +39,19 @@ openclaw --update ## 选项 -- `--no-restart`:成功更新后跳过重启 Gateway 网关服务。 +- `--no-restart`:成功更新后跳过重启 Gateway 网关 服务。 - `--channel `:设置更新渠道(git + npm;会持久化到配置中)。 -- `--tag `:仅为本次更新覆盖包目标。对于包安装,`main` 会映射为 `github:openclaw/openclaw#main`。 -- `--dry-run`:预览计划中的更新操作(渠道/tag/目标/重启流程),但不写入配置、不安装、不同步插件,也不重启。 -- `--json`:打印机器可读的 `UpdateRunResult` JSON,包括 - 当在更新后插件同步期间检测到 npm 插件产物漂移时的 - `postUpdate.plugins.integrityDrifts`。 -- `--timeout `:每一步的超时时间(默认 1200 秒)。 +- `--tag `:仅为本次更新覆盖软件包目标。对于软件包安装,`main` 映射到 `github:openclaw/openclaw#main`。 +- `--dry-run`:预览计划中的更新操作(渠道/标签/目标/重启流程),但不会写入配置、安装、同步插件或重启。 +- `--json`:输出机器可读的 `UpdateRunResult` JSON,包括在更新后插件同步期间检测到 npm 插件产物漂移时的 `postUpdate.plugins.integrityDrifts`。 +- `--timeout `:每个步骤的超时时间(默认 1200 秒)。 - `--yes`:跳过确认提示(例如降级确认) 注意:降级需要确认,因为旧版本可能会破坏配置。 ## `update status` -显示当前激活的更新渠道 + git tag/branch/SHA(对于源码检出副本),以及更新可用性。 +显示当前活动的更新渠道 + git 标签/分支/SHA(适用于源码检出),以及更新可用性。 ```bash openclaw update status @@ -63,14 +61,14 @@ openclaw update status --timeout 10 选项: -- `--json`:打印机器可读的状态 JSON。 +- `--json`:输出机器可读的状态 JSON。 - `--timeout `:检查超时时间(默认 3 秒)。 ## `update wizard` -用于选择更新渠道并确认更新后是否重启 Gateway 网关的交互式流程 -(默认会重启)。如果你在没有 git 检出副本的情况下选择 `dev`, -它会提供创建检出副本的选项。 +交互式流程,用于选择更新渠道并确认更新后是否重启 Gateway 网关 +(默认会重启)。如果你在没有 git 检出的情况下选择 `dev`,它会 +提供创建检出的选项。 选项: @@ -78,58 +76,54 @@ openclaw update status --timeout 10 ## 它会做什么 -当你显式切换渠道时(`--channel ...`),OpenClaw 也会保持 -安装方式与之对齐: +当你显式切换渠道(`--channel ...`)时,OpenClaw 也会保持安装方式一致: -- `dev` → 确保存在一个 git 检出副本(默认:`~/openclaw`,可通过 `OPENCLAW_GIT_DIR` 覆盖), - 对其进行更新,并从该检出副本安装全局 CLI。 +- `dev` → 确保存在一个 git 检出(默认:`~/openclaw`,可通过 `OPENCLAW_GIT_DIR`` 覆盖), + 更新它,并从该检出安装全局 CLI。 - `stable` → 使用 `latest` 从 npm 安装。 -- `beta` → 优先使用 npm dist-tag `beta`,但当 beta 不存在 - 或比当前 stable 发布更旧时,会回退到 `latest`。 +- `beta` → 优先使用 npm dist-tag `beta`,但当 beta 不存在或比当前 stable 版本更旧时,会回退到 `latest`。 -Gateway 网关核心自动更新器(在配置中启用时)会复用相同的更新路径。 +Gateway 网关 核心自动更新器(在配置中启用时)会复用同一条更新路径。 -对于包管理器安装,`openclaw update` 会先解析目标包 -版本,然后再调用包管理器。如果已安装版本与目标版本完全 -匹配,并且不需要持久化任何更新渠道变更,则该 -命令会在执行包安装、插件同步、补全刷新 -或 Gateway 网关重启之前,以跳过状态退出。 +对于软件包管理器安装,`openclaw update` 会在调用软件包管理器之前解析目标软件包 +版本。如果已安装版本与目标完全一致,且不需要持久化更新渠道变更, +命令会在软件包安装、插件同步、补全刷新或 Gateway 网关 重启之前以跳过状态退出。 -## Git 检出副本流程 +## Git 检出流程 渠道: -- `stable`:检出最新的非 beta tag,然后 build + doctor。 -- `beta`:优先使用最新的 `-beta` tag,但当 beta 不存在或更旧时, - 会回退到最新的 stable tag。 -- `dev`:检出 `main`,然后 fetch + rebase。 +- `stable`:检出最新的非 beta 标签,然后执行构建 + doctor。 +- `beta`:优先使用最新的 `-beta` 标签,但当 beta 不存在或更旧时, + 回退到最新 stable 标签。 +- `dev`:检出 `main`,然后执行 fetch + rebase。 高级流程: -1. 需要一个干净的工作树(没有未提交的更改)。 -2. 切换到所选渠道(tag 或 branch)。 -3. 获取上游更新(仅 `dev`)。 -4. 仅 `dev`:在临时工作树中执行预检 lint + TypeScript build;如果最新提交失败,则向后回退最多 10 个提交,以找到最新的可干净构建版本。 -5. 变基到所选提交(仅 `dev`)。 -6. 使用仓库包管理器安装依赖。对于 pnpm 检出副本,更新器会按需引导安装 `pnpm`(优先通过 `corepack`,然后回退到临时 `npm install pnpm@10`),而不是在 pnpm workspace 中运行 `npm run build`。 -7. 执行 build,并构建 Control UI。 +1. 要求工作树干净(没有未提交的更改)。 +2. 切换到所选渠道(标签或分支)。 +3. 拉取上游(仅 dev)。 +4. 仅 dev:在临时工作树中执行预检 lint + TypeScript 构建;如果最新提交失败,则最多回退 10 个提交,以找到最新的可干净构建版本。 +5. 变基到所选提交(仅 dev)。 +6. 使用仓库的软件包管理器安装依赖。对于 pnpm 检出,更新器会按需引导 `pnpm`(优先通过 `corepack`,然后回退到临时 `npm install pnpm@10`),而不是在 pnpm 工作区内运行 `npm run build`。 +7. 构建 + 构建 Control UI。 8. 运行 `openclaw doctor` 作为最终的“安全更新”检查。 -9. 将插件同步到当前渠道(`dev` 使用内置 extensions;`stable`/`beta` 使用 npm),并更新通过 npm 安装的插件。 +9. 将插件同步到当前渠道(dev 使用内置插件;stable/beta 使用 npm),并更新通过 npm 安装的插件。 -如果某个精确固定版本的 npm 插件更新解析到的产物,其完整性 -与已存储安装记录不同,`openclaw update` 会中止该插件 -产物更新,而不是安装它。只有在验证你信任该新产物之后, +如果一个精确固定版本的 npm 插件更新解析到的产物,其完整性与已存储的安装记录不同, +`openclaw update` 会中止该插件产物更新,而不是安装它。只有在确认你信任该新产物之后, 才应显式重新安装或更新该插件。 -如果 pnpm 引导安装仍然失败,更新器现在会提前停止,并给出包管理器特定错误,而不是尝试在检出副本中运行 `npm run build`。 +如果 pnpm 引导仍然失败,更新器现在会尽早停止,并报告针对该软件包管理器的特定错误, +而不是尝试在检出中运行 `npm run build`。 ## `--update` 简写 `openclaw --update` 会重写为 `openclaw update`(对 shell 和启动脚本很有用)。 -## 另请参阅 +## 另请参见 -- `openclaw doctor`(对于 git 检出副本,会先提供运行更新的选项) +- `openclaw doctor`(在 git 检出上会先提供运行更新) - [Development channels](/zh-CN/install/development-channels) - [Updating](/zh-CN/install/updating) - [CLI reference](/zh-CN/cli) diff --git a/docs/zh-CN/concepts/dreaming.md b/docs/zh-CN/concepts/dreaming.md index 3f3f6d1cc..318db8a84 100644 --- a/docs/zh-CN/concepts/dreaming.md +++ b/docs/zh-CN/concepts/dreaming.md @@ -2,14 +2,14 @@ read_when: - 你希望记忆提升能够自动运行 - 你想了解每个 Dreaming 阶段的作用 - - 你想在不污染 `MEMORY.md` 的情况下调整整合过程 -summary: 通过轻度、深度和 REM 阶段进行后台记忆整合,并附带 Dream Diary + - 你想在不污染 `MEMORY.md` 的情况下调整整合机制 +summary: 通过浅层、深层和 REM 阶段进行后台记忆整合,并配有 Dream Diary title: Dreaming x-i18n: - generated_at: "2026-04-22T01:53:20Z" + generated_at: "2026-04-23T06:40:32Z" model: gpt-5.4 provider: openai - source_hash: 050e99bd2b3a18d7d2f02747e3010a7679515098369af5061d0a97b5703fc581 + source_hash: 1a44c7568992e60d249d7e424a585318401f678767b9feb7d75c830b01de1cf6 source_path: concepts/dreaming.md workflow: 15 --- @@ -18,112 +18,110 @@ x-i18n: Dreaming 是 `memory-core` 中的后台记忆整合系统。 它帮助 OpenClaw 将强烈的短期信号转移到持久记忆中,同时 -保持整个过程可解释且可审查。 +让整个过程可解释、可审查。 -Dreaming 是**可选启用**的,默认禁用。 +Dreaming 是**可选启用**功能,默认禁用。 ## Dreaming 会写入什么 Dreaming 会保留两类输出: - `memory/.dreams/` 中的**机器状态**(召回存储、阶段信号、摄取检查点、锁)。 -- `DREAMS.md`(或现有的 `dreams.md`)中的**人类可读输出**,以及位于 `memory/dreaming//YYYY-MM-DD.md` 下的可选阶段报告文件。 +- `DREAMS.md`(或已有的 `dreams.md`)中的**人类可读输出**,以及可选的阶段报告文件,位于 `memory/dreaming//YYYY-MM-DD.md`。 长期提升仍然只会写入 `MEMORY.md`。 ## 阶段模型 -Dreaming 使用三个协同工作的阶段: +Dreaming 使用三个协作阶段: | 阶段 | 目的 | 持久写入 | -| ----- | ----------------------------------------- | ----------------- | -| Light | 整理并暂存近期短期材料 | 否 | -| Deep | 评分并提升持久候选项 | 是(`MEMORY.md`) | -| REM | 反思主题和反复出现的想法 | 否 | +| ----- | ----- | ----- | +| Light | 对近期短期材料进行整理和暂存 | 否 | +| Deep | 对持久候选项进行评分和提升 | 是(`MEMORY.md`) | +| REM | 反思主题和重复出现的想法 | 否 | -这些阶段是内部实现细节,不是单独的用户可配置“模式”。 +这些阶段是内部实现细节,并不是单独供用户配置的“模式”。 ### Light 阶段 Light 阶段会摄取近期的每日记忆信号和召回轨迹,对其去重, -并暂存候选条目。 +并暂存候选行。 -- 从短期召回状态、近期每日记忆文件,以及可用时已脱敏的会话转录中读取。 -- 当存储包含内联输出时,写入一个受管的 `## Light Sleep` 区块。 -- 记录强化信号,供后续 Deep 排名使用。 +- 在可用时,从短期召回状态、近期每日记忆文件以及已脱敏的会话转录中读取。 +- 当存储包含内联输出时,写入受管理的 `## Light Sleep` 区块。 +- 记录强化信号,供后续 Deep 排序使用。 - 绝不会写入 `MEMORY.md`。 ### Deep 阶段 -Deep 阶段决定哪些内容会成为长期记忆。 +Deep 阶段决定什么会成为长期记忆。 - 使用加权评分和阈值门槛对候选项进行排序。 -- 需要通过 `minScore`、`minRecallCount` 和 `minUniqueQueries`。 -- 在写入前会从实时每日文件中重新提取片段,因此过时或已删除的片段会被跳过。 -- 将已提升的条目追加到 `MEMORY.md`。 -- 将 `## Deep Sleep` 摘要写入 `DREAMS.md`,并可选择写入 `memory/dreaming/deep/YYYY-MM-DD.md`。 +- 要求通过 `minScore`、`minRecallCount` 和 `minUniqueQueries`。 +- 在写入前,会从实时每日文件中重新提取片段,因此陈旧或已删除的片段会被跳过。 +- 将提升后的条目追加到 `MEMORY.md`。 +- 将 `## Deep Sleep` 摘要写入 `DREAMS.md`,并可选写入 `memory/dreaming/deep/YYYY-MM-DD.md`。 ### REM 阶段 REM 阶段提取模式和反思信号。 - 根据近期短期轨迹构建主题和反思摘要。 -- 当存储包含内联输出时,写入一个受管的 `## REM Sleep` 区块。 -- 记录供 Deep 排名使用的 REM 强化信号。 +- 当存储包含内联输出时,写入受管理的 `## REM Sleep` 区块。 +- 记录供 Deep 排序使用的 REM 强化信号。 - 绝不会写入 `MEMORY.md`。 ## 会话转录摄取 Dreaming 可以将已脱敏的会话转录摄取到 Dreaming 语料中。当 -转录可用时,它们会与每日记忆信号和召回轨迹一起被送入 Light 阶段。个人和敏感内容会在摄取前被脱敏。 +转录可用时,它们会与每日记忆信号和召回轨迹一起输入到 Light 阶段。个人和敏感内容会在摄取前被脱敏。 ## Dream Diary Dreaming 还会在 `DREAMS.md` 中保留一份叙事性的 **Dream Diary**。 -当每个阶段积累了足够的材料后,`memory-core` 会尽力运行一次后台 +每当某个阶段积累了足够的材料后,`memory-core` 就会运行一次尽力而为的后台 子智能体轮次(使用默认运行时模型),并追加一条简短的日记条目。 -这份日记用于在 Dreams UI 中供人阅读,而不是作为提升来源。 -由 Dreaming 生成的日记/报告产物会从短期 -提升中排除。只有有依据的记忆片段才有资格被提升到 -`MEMORY.md` 中。 +这份日记用于人在 Dreams UI 中阅读,而不是作为提升来源。 +由 Dreaming 生成的日记/报告产物会被排除在短期 +提升之外。只有有据可依的记忆片段才有资格提升到 +`MEMORY.md`。 -此外,还有一条有依据的历史回填通道,用于审查和恢复工作: +此外,还有一条基于事实依据的历史回填通道,用于审查和恢复工作: -- `memory rem-harness --path ... --grounded` 可从历史 `YYYY-MM-DD.md` 记录中预览有依据的日记输出。 -- `memory rem-backfill --path ...` 会将可逆的、有依据的日记条目写入 `DREAMS.md`。 -- `memory rem-backfill --path ... --stage-short-term` 会将有依据的持久候选项暂存到与常规 Deep 阶段已使用的同一短期证据存储中。 -- `memory rem-backfill --rollback` 和 `--rollback-short-term` 会移除这些已暂存的回填产物,而不会触及普通日记条目或实时短期召回。 +- `memory rem-harness --path ... --grounded` 可从历史 `YYYY-MM-DD.md` 笔记中预览基于事实依据的日记输出。 +- `memory rem-backfill --path ...` 会将可回滚的、基于事实依据的日记条目写入 `DREAMS.md`。 +- `memory rem-backfill --path ... --stage-short-term` 会将基于事实依据的持久候选项暂存到与常规 Deep 阶段相同的短期证据存储中。 +- `memory rem-backfill --rollback` 和 `--rollback-short-term` 会移除这些暂存的回填产物,而不会影响普通日记条目或实时短期召回。 -Control UI 也暴露了相同的日记回填/重置流程,这样你就可以先在 Dreams 场景中检查 -结果,再决定这些有依据的候选项 -是否值得提升。该场景还会显示一条独立的有依据通道,以便你查看 -哪些已暂存的短期条目来自历史回放、哪些已提升 -项目由 grounded 流程引导,以及只清除仅基于 grounded 的已暂存条目,而不 -触及普通的实时短期状态。 +Control UI 也暴露了相同的日记回填/重置流程,因此你可以先在 +Dreams 场景中检查结果,再决定这些基于事实依据的候选项 +是否值得提升。该场景还会显示一条单独的基于事实依据通道,这样你就可以看到 +哪些暂存的短期条目来自历史回放、哪些提升项由 grounded 通道驱动,并且仅清除基于事实依据的暂存条目,而不影响普通实时短期状态。 -## Deep 排名信号 +## Deep 排序信号 -Deep 排名使用六个加权基础信号,再加上阶段强化: +Deep 排序使用六个带权重的基础信号,再加上阶段强化: | 信号 | 权重 | 说明 | | ------------------- | ------ | ------------------------------------------------- | -| 频率 | 0.24 | 该条目累积了多少短期信号 | -| 相关性 | 0.30 | 该条目的平均检索质量 | -| 查询多样性 | 0.15 | 让它浮现出来的不同查询/日期上下文 | -| 近期性 | 0.15 | 基于时间衰减的新鲜度分数 | -| 整合度 | 0.10 | 跨日重复出现的强度 | -| 概念丰富度 | 0.06 | 来自片段/路径的概念标签密度 | +| Frequency | 0.24 | 条目累计了多少短期信号 | +| Relevance | 0.30 | 条目的平均检索质量 | +| Query diversity | 0.15 | 使其浮现的不同查询/日期上下文 | +| Recency | 0.15 | 带时间衰减的新鲜度分数 | +| Consolidation | 0.10 | 跨日重复出现的强度 | +| Conceptual richness | 0.06 | 来自片段/路径的概念标签密度 | -来自 Light 和 REM 阶段的命中会基于 -`memory/.dreams/phase-signals.json` 增加一个小幅的、按近期性衰减的提升。 +Light 和 REM 阶段命中会从 +`memory/.dreams/phase-signals.json` 中增加一个带轻微时间衰减的提升值。 ## 调度 -启用后,`memory-core` 会自动管理一个用于完整 Dreaming -扫描的 cron 任务。每次扫描会按顺序运行各阶段:light -> REM -> deep。 +启用后,`memory-core` 会自动管理一个 cron 任务,用于执行完整的 Dreaming +扫描。每次扫描都会按顺序运行各阶段:light -> REM -> deep。 -默认频率行为: +默认调度频率行为: | 设置 | 默认值 | | -------------------- | ----------- | @@ -149,7 +147,7 @@ Deep 排名使用六个加权基础信号,再加上阶段强化: } ``` -使用自定义扫描频率启用 Dreaming: +启用 Dreaming 并设置自定义扫描频率: ```json { @@ -189,18 +187,17 @@ openclaw memory promote --limit 5 openclaw memory status --deep ``` -手动 `memory promote` 默认使用 Deep 阶段阈值,除非通过 -CLI 标志覆盖。 +手动执行 `memory promote` 时,默认使用 Deep 阶段阈值,除非通过 +CLI 标志进行覆盖。 -解释某个特定候选项为什么会或不会被提升: +解释某个特定候选项为何会或不会被提升: ```bash openclaw memory promote-explain "router vlan" openclaw memory promote-explain "router vlan" --json ``` -预览 REM 反思、候选事实以及 Deep 提升输出,而不 -写入任何内容: +在不写入任何内容的情况下,预览 REM 反思、候选事实以及 Deep 提升输出: ```bash openclaw memory rem-harness @@ -211,42 +208,42 @@ openclaw memory rem-harness --json 所有设置都位于 `plugins.entries.memory-core.config.dreaming` 下。 -| 键名 | 默认值 | +| 键 | 默认值 | | ----------- | ----------- | | `enabled` | `false` | | `frequency` | `0 3 * * *` | -阶段策略、阈值和存储行为都是内部实现 +阶段策略、阈值和存储行为属于内部实现 细节(不是面向用户的配置)。 -完整键名列表请参见 [记忆配置参考](/zh-CN/reference/memory-config#dreaming)。 +完整键列表请参见 [记忆配置参考](/zh-CN/reference/memory-config#dreaming)。 ## Dreams UI -启用后,Gateway 网关中的 **Dreams** 选项卡会显示: +启用后,Gateway 网关的 **Dreams** 标签页会显示: - 当前 Dreaming 启用状态 -- 阶段级状态和受管扫描是否存在 -- 短期、有依据、信号以及今日已提升数量 -- 下一次计划运行时间 -- 用于已暂存历史回放条目的独立 grounded 场景通道 -- 由 `doctor.memory.dreamDiary` 提供支持的可展开 Dream Diary 阅读器 +- 阶段级状态和受管理扫描是否存在 +- 短期、grounded、信号以及今日已提升计数 +- 下次计划运行时间 +- 一条单独的 grounded 场景通道,用于显示暂存的历史回放条目 +- 一个可展开的 Dream Diary 阅读器,由 `doctor.memory.dreamDiary` 提供支持 ## 故障排除 ### Dreaming 从不运行(状态显示为 blocked) -受管 Dreaming cron 依赖默认智能体的 heartbeat。如果该智能体的 heartbeat 没有触发,cron 就会排入一个无人消费的系统事件,而 Dreaming 就会静默地不运行。在这种情况下,`openclaw memory status` 和 `/dreaming status` 都会报告 `blocked`,并指出哪个智能体的 heartbeat 是阻塞源。 +受管理的 Dreaming cron 依赖默认智能体的心跳。如果该智能体的心跳没有触发,cron 就会排入一个无人消费的系统事件,而 Dreaming 就会静默不运行。在这种情况下,`openclaw memory status` 和 `/dreaming status` 都会报告 `blocked`,并指出是哪一个智能体的心跳导致了阻塞。 两个常见原因: -- 另一个智能体声明了显式的 `heartbeat:` 区块。当 `agents.list` 中任一条目拥有自己的 `heartbeat` 区块时,只有那些智能体会发送 heartbeat —— 默认设置将不再应用于所有智能体,因此默认智能体可能会静默。请将 heartbeat 设置移动到 `agents.defaults.heartbeat`,或在默认智能体上添加显式的 `heartbeat` 区块。参见 [作用域与优先级](/zh-CN/gateway/heartbeat#scope-and-precedence)。 -- `heartbeat.every` 为 `0`、为空,或无法解析。cron 没有可用于调度的间隔,因此 heartbeat 实际上已被禁用。请将 `every` 设置为一个正时长,例如 `30m`。参见 [默认值](/zh-CN/gateway/heartbeat#defaults)。 +- 另一个智能体声明了显式的 `heartbeat:` 区块。当 `agents.list` 中任意条目拥有自己的 `heartbeat` 区块时,只有这些智能体会发送心跳——默认值不再应用于其他所有智能体,因此默认智能体可能会静默。请将心跳设置移动到 `agents.defaults.heartbeat`,或在默认智能体上添加显式的 `heartbeat` 区块。参见 [作用域与优先级](/zh-CN/gateway/heartbeat#scope-and-precedence)。 +- `heartbeat.every` 为 `0`、空值或无法解析。cron 没有可用于调度的间隔,因此心跳实际上被禁用了。请将 `every` 设置为正时长,例如 `30m`。参见 [默认值](/zh-CN/gateway/heartbeat#defaults)。 ## 相关内容 - [Heartbeat](/zh-CN/gateway/heartbeat) - [记忆](/zh-CN/concepts/memory) - [Memory Search](/zh-CN/concepts/memory-search) -- [memory CLI](/cli/memory) +- [memory CLI](/zh-CN/cli/memory) - [记忆配置参考](/zh-CN/reference/memory-config) diff --git a/docs/zh-CN/gateway/configuration-reference.md b/docs/zh-CN/gateway/configuration-reference.md index 13ae9da35..78cfc386a 100644 --- a/docs/zh-CN/gateway/configuration-reference.md +++ b/docs/zh-CN/gateway/configuration-reference.md @@ -2,36 +2,36 @@ read_when: - 你需要精确到字段级别的配置语义或默认值 - 你正在验证渠道、模型、Gateway 网关或工具配置块 -summary: Gateway 网关配置参考,涵盖核心 OpenClaw 键名、默认值,以及指向专用子系统参考文档的链接 +summary: 核心 OpenClaw 键、默认值及专用子系统参考链接的 Gateway 网关配置参考 title: 配置参考 x-i18n: - generated_at: "2026-04-22T23:04:29Z" + generated_at: "2026-04-23T06:40:45Z" model: gpt-5.4 provider: openai - source_hash: aabe366a2dcbf1989890016b20d63e4799a952ec57cea99cdc00f8ca26711e2d + source_hash: 75c7e0d88ea6eacb8a2dd41f83033da853130dc2a689950c1a188d7c4ca8f977 source_path: gateway/configuration-reference.md workflow: 15 --- # 配置参考 -`~/.openclaw/openclaw.json` 的核心配置参考。若需按任务组织的概览,请参见 [配置](/zh-CN/gateway/configuration)。 +`~/.openclaw/openclaw.json` 的核心配置参考。若想查看面向任务的概览,请参见[配置](/zh-CN/gateway/configuration)。 -本页介绍 OpenClaw 的主要配置面,并在某个子系统有自己更深入的参考文档时提供外链。它**不会**尝试在单个页面内联列出每个由渠道/插件拥有的命令目录,或所有深层 Memory/QMD 细项。 +本页涵盖 OpenClaw 的主要配置面,并在某个子系统拥有更深入的独立参考时提供相应链接。它**不会**尝试在单个页面中内联所有由渠道/plugin 拥有的命令目录,或所有深层 memory/QMD 调节项。 -代码事实依据: +代码事实来源: -- `openclaw config schema` 会输出用于验证和 Control UI 的实时 JSON Schema,并在可用时合并内置/插件/渠道元数据 -- `config.schema.lookup` 会返回一个按路径范围限定的 schema 节点,供钻取式工具使用 -- `pnpm config:docs:check` / `pnpm config:docs:gen` 会根据当前 schema 表面对配置文档基线哈希进行校验 +- `openclaw config schema` 会输出用于验证和 Control UI 的实时 JSON Schema,并在可用时合并内置/plugin/渠道元数据 +- `config.schema.lookup` 会返回一个按路径限定的 schema 节点,供向下钻取工具使用 +- `pnpm config:docs:check` / `pnpm config:docs:gen` 会根据当前 schema 表面校验配置文档基线哈希 -专门的深度参考: +专用深度参考: -- [Memory 配置参考](/zh-CN/reference/memory-config),适用于 `agents.defaults.memorySearch.*`、`memory.qmd.*`、`memory.citations`,以及位于 `plugins.entries.memory-core.config.dreaming` 下的 Dreaming 配置 -- [斜杠命令](/zh-CN/tools/slash-commands),用于查看当前内置 + 内置插件命令目录 -- 对应渠道/插件页面,用于查看渠道特定的命令面 +- [Memory 配置参考](/zh-CN/reference/memory-config),适用于 `agents.defaults.memorySearch.*`、`memory.qmd.*`、`memory.citations`,以及位于 `plugins.entries.memory-core.config.dreaming` 下的 dreaming 配置 +- [Slash Commands](/zh-CN/tools/slash-commands),适用于当前内置 + 内置 plugin 命令目录 +- 各自所属的渠道/plugin 页面,适用于特定渠道的命令面 -配置格式为 **JSON5**(允许注释和尾随逗号)。所有字段均为可选——OpenClaw 在省略时会使用安全默认值。 +配置格式为 **JSON5**(允许注释和尾随逗号)。所有字段都是可选的——省略时,OpenClaw 会使用安全默认值。 --- @@ -43,28 +43,28 @@ x-i18n: 所有渠道都支持私信策略和群组策略: -| 私信策略 | 行为 | -| ------------------- | ------------------------------------------------------------ | -| `pairing`(默认) | 未知发送者会收到一次性配对码;必须由 owner 批准 | -| `allowlist` | 仅允许 `allowFrom` 中的发送者(或已配对的允许存储中的发送者) | -| `open` | 允许所有入站私信(需要 `allowFrom: ["*"]`) | -| `disabled` | 忽略所有入站私信 | +| 私信策略 | 行为 | +| ------------------- | ----------------------------------------- | +| `pairing`(默认) | 未知发送者会收到一次性配对码;必须由所有者批准 | +| `allowlist` | 仅允许 `allowFrom` 中的发送者(或已配对允许存储中的发送者) | +| `open` | 允许所有传入私信(要求 `allowFrom: ["*"]`) | +| `disabled` | 忽略所有传入私信 | | 群组策略 | 行为 | | --------------------- | ---------------------------------------------- | -| `allowlist`(默认) | 仅允许匹配已配置允许列表的群组 | -| `open` | 绕过群组允许列表(仍会应用提及门控) | -| `disabled` | 阻止所有群组/房间消息 | +| `allowlist`(默认) | 仅允许匹配已配置 allowlist 的群组 | +| `open` | 绕过群组 allowlist(但仍适用提及门控) | +| `disabled` | 屏蔽所有群组/房间消息 | -当某个提供商的 `groupPolicy` 未设置时,`channels.defaults.groupPolicy` 会设置默认值。 +`channels.defaults.groupPolicy` 会在提供商的 `groupPolicy` 未设置时作为默认值。 配对码会在 1 小时后过期。待处理的私信配对请求上限为**每个渠道 3 个**。 -如果整个提供商块缺失(`channels.` 不存在),运行时群组策略会回退为 `allowlist`(失败时默认关闭),并在启动时发出警告。 +如果某个提供商配置块完全缺失(`channels.` 不存在),运行时群组策略会回退为 `allowlist`(默认拒绝),并在启动时发出警告。 ### 渠道模型覆盖 -使用 `channels.modelByChannel` 可将特定渠道 ID 固定到某个模型。值可接受 `provider/model` 或已配置的模型别名。当会话尚未设置模型覆盖时(例如通过 `/model` 设置),将应用该渠道映射。 +使用 `channels.modelByChannel` 将特定渠道 ID 固定到某个模型。值可接受 `provider/model` 或已配置的模型别名。只有当某个会话尚未拥有模型覆盖时(例如通过 `/model` 设置),才会应用渠道映射。 ```json5 { @@ -85,9 +85,9 @@ x-i18n: } ``` -### 渠道默认值和心跳 +### 渠道默认值和 heartbeat -使用 `channels.defaults` 为各提供商共享群组策略和心跳行为: +使用 `channels.defaults` 为各提供商共享群组策略和 heartbeat 行为: ```json5 { @@ -105,15 +105,15 @@ x-i18n: } ``` -- `channels.defaults.groupPolicy`:当提供商级别的 `groupPolicy` 未设置时使用的后备群组策略。 +- `channels.defaults.groupPolicy`:当提供商级别的 `groupPolicy` 未设置时使用的回退群组策略。 - `channels.defaults.contextVisibility`:所有渠道的默认补充上下文可见性模式。取值:`all`(默认,包含所有引用/线程/历史上下文)、`allowlist`(仅包含来自 allowlist 发送者的上下文)、`allowlist_quote`(与 allowlist 相同,但保留显式引用/回复上下文)。每渠道覆盖:`channels..contextVisibility`。 -- `channels.defaults.heartbeat.showOk`:在心跳输出中包含健康渠道状态。 -- `channels.defaults.heartbeat.showAlerts`:在心跳输出中包含降级/错误状态。 -- `channels.defaults.heartbeat.useIndicator`:以紧凑的指示器样式渲染心跳输出。 +- `channels.defaults.heartbeat.showOk`:在 heartbeat 输出中包含健康的渠道状态。 +- `channels.defaults.heartbeat.showAlerts`:在 heartbeat 输出中包含降级/错误状态。 +- `channels.defaults.heartbeat.useIndicator`:以紧凑的指示器样式渲染 heartbeat 输出。 ### WhatsApp -WhatsApp 通过 Gateway 网关的 web 渠道(Baileys Web)运行。有已链接会话存在时会自动启动。 +WhatsApp 通过 Gateway 网关的 web 渠道(Baileys Web)运行。当存在已关联会话时会自动启动。 ```json5 { @@ -124,7 +124,7 @@ WhatsApp 通过 Gateway 网关的 web 渠道(Baileys Web)运行。有已链 textChunkLimit: 4000, chunkMode: "length", // length | newline mediaMaxMb: 50, - sendReadReceipts: true, // 蓝色对勾(self-chat 模式下为 false) + sendReadReceipts: true, // 蓝色对勾(在 self-chat 模式下为 false) groups: { "*": { requireMention: true }, }, @@ -164,10 +164,10 @@ WhatsApp 通过 Gateway 网关的 web 渠道(Baileys Web)运行。有已链 } ``` -- 出站命令默认使用账号 `default`(若存在);否则使用首个已配置账号 ID(按排序顺序)。 -- 可选的 `channels.whatsapp.defaultAccount` 会在其匹配某个已配置账号 ID 时,覆盖该后备默认账号选择。 -- 旧版单账号 Baileys auth 目录会由 `openclaw doctor` 迁移到 `whatsapp/default`。 -- 每账号覆盖:`channels.whatsapp.accounts..sendReadReceipts`、`channels.whatsapp.accounts..dmPolicy`、`channels.whatsapp.accounts..allowFrom`。 +- 出站命令默认使用 `default` 账号(如果存在);否则使用第一个已配置的账号 ID(排序后)。 +- 可选的 `channels.whatsapp.defaultAccount` 会在其匹配某个已配置账号 ID 时,覆盖该回退默认账号选择。 +- 旧版单账号 Baileys 认证目录会由 `openclaw doctor` 迁移到 `whatsapp/default`。 +- 每账号覆盖项:`channels.whatsapp.accounts..sendReadReceipts`、`channels.whatsapp.accounts..dmPolicy`、`channels.whatsapp.accounts..allowFrom`。 @@ -202,7 +202,7 @@ WhatsApp 通过 Gateway 网关的 web 渠道(Baileys Web)运行。有已链 historyLimit: 50, replyToMode: "first", // off | first | all | batched linkPreview: true, - streaming: "partial", // off | partial | block | progress(默认:off;显式选择加入以避免预览编辑速率限制) + streaming: "partial", // off | partial | block | progress(默认:off;请显式选择启用,以避免预览编辑速率限制) actions: { reactions: true, sendMessage: true }, reactionNotifications: "own", // off | own | all mediaMaxMb: 100, @@ -225,13 +225,13 @@ WhatsApp 通过 Gateway 网关的 web 渠道(Baileys Web)运行。有已链 } ``` -- Bot token:`channels.telegram.botToken` 或 `channels.telegram.tokenFile`(仅允许普通文件;拒绝符号链接),默认账号还可回退使用 `TELEGRAM_BOT_TOKEN`。 +- Bot token:`channels.telegram.botToken` 或 `channels.telegram.tokenFile`(仅支持常规文件;拒绝符号链接),默认账号还可回退使用 `TELEGRAM_BOT_TOKEN`。 - 可选的 `channels.telegram.defaultAccount` 会在其匹配某个已配置账号 ID 时,覆盖默认账号选择。 -- 在多账号配置(2 个及以上账号 ID)中,请设置显式默认值(`channels.telegram.defaultAccount` 或 `channels.telegram.accounts.default`),以避免回退路由;若缺失或无效,`openclaw doctor` 会发出警告。 +- 在多账号设置(2 个或更多账号 ID)中,请设置显式默认值(`channels.telegram.defaultAccount` 或 `channels.telegram.accounts.default`)以避免回退路由;若缺失或无效,`openclaw doctor` 会发出警告。 - `configWrites: false` 会阻止由 Telegram 发起的配置写入(supergroup ID 迁移、`/config set|unset`)。 -- 顶层 `bindings[]` 中 `type: "acp"` 的条目可为论坛主题配置持久化 ACP 绑定(在 `match.peer.id` 中使用规范形式 `chatId:topic:topicId`)。字段语义共享于 [ACP 智能体](/zh-CN/tools/acp-agents#channel-specific-settings)。 -- Telegram 流式预览使用 `sendMessage` + `editMessageText`(在私聊和群聊中都可用)。 -- 重试策略:参见 [重试策略](/zh-CN/concepts/retry)。 +- 顶层 `bindings[]` 中 `type: "acp"` 的条目会为论坛话题配置持久 ACP 绑定(在 `match.peer.id` 中使用规范的 `chatId:topic:topicId`)。字段语义与 [ACP Agents](/zh-CN/tools/acp-agents#channel-specific-settings) 共享。 +- Telegram 流式预览使用 `sendMessage` + `editMessageText`(可在私聊和群聊中工作)。 +- 重试策略:参见[重试策略](/zh-CN/concepts/retry)。 ### Discord @@ -297,7 +297,7 @@ WhatsApp 通过 Gateway 网关的 web 渠道(Baileys Web)运行。有已链 enabled: true, idleHours: 24, maxAgeHours: 0, - spawnSubagentSessions: false, // 对 `sessions_spawn({ thread: true })` 的显式选择加入 + spawnSubagentSessions: false, // 对 `sessions_spawn({ thread: true })` 的显式启用项 }, voice: { enabled: true, @@ -334,35 +334,35 @@ WhatsApp 通过 Gateway 网关的 web 渠道(Baileys Web)运行。有已链 ``` - Token:`channels.discord.token`,默认账号还可回退使用 `DISCORD_BOT_TOKEN`。 -- 直接出站调用如果提供了显式的 Discord `token`,则该次调用会使用该 token;账号的重试/策略设置仍来自活动运行时快照中选定的账号。 +- 直接出站调用如果显式提供 Discord `token`,则该次调用会使用该 token;账号重试/策略设置仍来自活动运行时快照中选定的账号。 - 可选的 `channels.discord.defaultAccount` 会在其匹配某个已配置账号 ID 时,覆盖默认账号选择。 - 交付目标请使用 `user:`(私信)或 `channel:`(guild 渠道);裸数字 ID 会被拒绝。 -- Guild slug 会转换为小写,并将空格替换为 `-`;渠道键使用 slug 化后的名称(不带 `#`)。优先使用 guild ID。 -- 默认会忽略由 bot 自己发送的消息。`allowBots: true` 会启用这些消息;使用 `allowBots: "mentions"` 则只接受提及该 bot 的 bot 消息(bot 自己的消息仍会被过滤)。 -- `channels.discord.guilds..ignoreOtherMentions`(以及渠道级覆盖)会丢弃那些提及了其他用户或角色但未提及该 bot 的消息(不包括 @everyone/@here)。 -- `maxLinesPerMessage`(默认 17)即使在消息少于 2000 个字符时,也会拆分过高的消息。 +- Guild slug 使用小写,并将空格替换为 `-`;渠道键使用 slug 化后的名称(不带 `#`)。优先使用 guild ID。 +- 默认会忽略由 bot 编写的消息。`allowBots: true` 会启用它们;使用 `allowBots: "mentions"` 则只接受提及该 bot 的 bot 消息(仍会过滤 bot 自己的消息)。 +- `channels.discord.guilds..ignoreOtherMentions`(以及渠道级覆盖)会丢弃提及了其他用户或角色但未提及 bot 的消息(不包括 @everyone/@here)。 +- `maxLinesPerMessage`(默认 17)会拆分过高的消息,即使它们未超过 2000 个字符。 - `channels.discord.threadBindings` 控制 Discord 线程绑定路由: - - `enabled`:线程绑定会话功能的 Discord 覆盖项(`/focus`、`/unfocus`、`/agents`、`/session idle`、`/session max-age`,以及绑定式交付/路由) - - `idleHours`:按小时计的无活动自动取消聚焦的 Discord 覆盖项(`0` 表示禁用) - - `maxAgeHours`:按小时计的硬性最大时长 Discord 覆盖项(`0` 表示禁用) - - `spawnSubagentSessions`:为 `sessions_spawn({ thread: true })` 自动创建/绑定线程的显式选择加入开关 -- 顶层 `bindings[]` 中 `type: "acp"` 的条目可为渠道和线程配置持久化 ACP 绑定(在 `match.peer.id` 中使用渠道/线程 ID)。字段语义共享于 [ACP 智能体](/zh-CN/tools/acp-agents#channel-specific-settings)。 -- `channels.discord.ui.components.accentColor` 设置 Discord components v2 容器的强调色。 + - `enabled`:用于线程绑定会话功能的 Discord 覆盖项(`/focus`、`/unfocus`、`/agents`、`/session idle`、`/session max-age`,以及绑定交付/路由) + - `idleHours`:用于按小时计算的不活动自动取消聚焦的 Discord 覆盖项(`0` 表示禁用) + - `maxAgeHours`:用于按小时计算的硬性最大存续时间的 Discord 覆盖项(`0` 表示禁用) + - `spawnSubagentSessions`:为 `sessions_spawn({ thread: true })` 自动创建/绑定线程的显式启用开关 +- 顶层 `bindings[]` 中 `type: "acp"` 的条目会为渠道和线程配置持久 ACP 绑定(在 `match.peer.id` 中使用渠道/线程 ID)。字段语义与 [ACP Agents](/zh-CN/tools/acp-agents#channel-specific-settings) 共享。 +- `channels.discord.ui.components.accentColor` 用于设置 Discord components v2 容器的强调色。 - `channels.discord.voice` 启用 Discord 语音频道对话,以及可选的自动加入 + TTS 覆盖。 -- `channels.discord.voice.daveEncryption` 和 `channels.discord.voice.decryptionFailureTolerance` 会透传给 `@discordjs/voice` 的 DAVE 选项(默认分别为 `true` 和 `24`)。 -- OpenClaw 还会在重复解密失败后,通过离开/重新加入语音会话来尝试恢复语音接收。 -- `channels.discord.streaming` 是规范的流式模式键。旧版 `streamMode` 和布尔型 `streaming` 值会被自动迁移。 -- `channels.discord.autoPresence` 会将运行时可用性映射为 bot 在线状态(健康 => online,降级 => idle,耗尽 => dnd),并允许可选的状态文本覆盖。 -- `channels.discord.dangerouslyAllowNameMatching` 会重新启用可变的名称/tag 匹配(紧急兼容模式)。 -- `channels.discord.execApprovals`:Discord 原生的 exec 审批交付和审批人授权。 - - `enabled`:`true`、`false` 或 `"auto"`(默认)。在自动模式下,当可以从 `approvers` 或 `commands.ownerAllowFrom` 解析出审批人时,exec 审批会激活。 +- `channels.discord.voice.daveEncryption` 和 `channels.discord.voice.decryptionFailureTolerance` 会直通传递给 `@discordjs/voice` 的 DAVE 选项(默认分别为 `true` 和 `24`)。 +- OpenClaw 还会在重复解密失败后,通过离开并重新加入语音会话来尝试恢复语音接收。 +- `channels.discord.streaming` 是规范的流式传输模式键。旧版 `streamMode` 和布尔型 `streaming` 值会被自动迁移。 +- `channels.discord.autoPresence` 会将运行时可用性映射为 bot 在线状态(healthy => online,degraded => idle,exhausted => dnd),并允许可选的状态文本覆盖。 +- `channels.discord.dangerouslyAllowNameMatching` 会重新启用可变名称/tag 匹配(紧急破玻璃兼容模式)。 +- `channels.discord.execApprovals`:原生 Discord 的 exec 审批交付和审批者授权。 + - `enabled`:`true`、`false` 或 `"auto"`(默认)。在自动模式下,当可以从 `approvers` 或 `commands.ownerAllowFrom` 解析出审批者时,exec 审批会被激活。 - `approvers`:允许批准 exec 请求的 Discord 用户 ID。省略时回退到 `commands.ownerAllowFrom`。 - - `agentFilter`:可选的智能体 ID allowlist。省略时会为所有智能体转发审批。 - - `sessionFilter`:可选的会话键模式(子串或正则表达式)。 - - `target`:审批提示发送位置。`"dm"`(默认)发送到审批人的私信,`"channel"` 发送到发起渠道,`"both"` 两者都发送。当目标包含 `"channel"` 时,按钮仅对已解析出的审批人可用。 - - `cleanupAfterResolve`:为 `true` 时,在批准、拒绝或超时后删除审批私信。 + - `agentFilter`:可选的智能体 ID allowlist。省略时会为所有智能体转发审批请求。 + - `sessionFilter`:可选的会话键模式(子串或正则)。 + - `target`:审批提示的发送位置。`"dm"`(默认)发送到审批者私信,`"channel"` 发送到原始渠道,`"both"` 同时发送到两处。当 target 包含 `"channel"` 时,按钮仅对已解析的审批者可用。 + - `cleanupAfterResolve`:为 `true` 时,会在批准、拒绝或超时后删除审批私信。 -**Reaction notification 模式:** `off`(无)、`own`(bot 自己的消息,默认)、`all`(所有消息)、`allowlist`(对所有消息中来自 `guilds..users` 的用户)。 +**Reaction notification 模式:** `off`(无)、`own`(bot 自己的消息,默认)、`all`(所有消息)、`allowlist`(来自 `guilds..users` 的所有消息)。 ### Google Chat @@ -393,11 +393,11 @@ WhatsApp 通过 Gateway 网关的 web 渠道(Baileys Web)运行。有已链 } ``` -- Service account JSON:支持内联(`serviceAccount`)或基于文件(`serviceAccountFile`)。 -- 也支持 service account SecretRef(`serviceAccountRef`)。 +- 服务账号 JSON:可内联(`serviceAccount`)或基于文件(`serviceAccountFile`)。 +- 也支持服务账号 SecretRef(`serviceAccountRef`)。 - 环境变量回退:`GOOGLE_CHAT_SERVICE_ACCOUNT` 或 `GOOGLE_CHAT_SERVICE_ACCOUNT_FILE`。 - 交付目标请使用 `spaces/` 或 `users/`。 -- `channels.googlechat.dangerouslyAllowNameMatching` 会重新启用可变的电子邮件主体匹配(紧急兼容模式)。 +- `channels.googlechat.dangerouslyAllowNameMatching` 会重新启用可变邮箱主体匹配(紧急破玻璃兼容模式)。 ### Slack @@ -449,7 +449,7 @@ WhatsApp 通过 Gateway 网关的 web 渠道(Baileys Web)运行。有已链 chunkMode: "length", streaming: { mode: "partial", // off | partial | block | progress - nativeTransport: true, // 当 mode=partial 时使用 Slack 原生流式 API + nativeTransport: true, // 当 mode=partial 时使用 Slack 原生流式传输 API }, mediaMaxMb: 20, execApprovals: { @@ -464,34 +464,38 @@ WhatsApp 通过 Gateway 网关的 web 渠道(Baileys Web)运行。有已链 } ``` -- **Socket mode** 需要同时提供 `botToken` 和 `appToken`(默认账号的环境变量回退为 `SLACK_BOT_TOKEN` + `SLACK_APP_TOKEN`)。 -- **HTTP mode** 需要 `botToken` 加 `signingSecret`(可配置在根级或每账号级别)。 -- `botToken`、`appToken`、`signingSecret` 和 `userToken` 接受明文字符串或 SecretRef 对象。 -- Slack 账号快照会暴露每项凭证的来源/状态字段,例如 `botTokenSource`、`botTokenStatus`、`appTokenStatus`,以及在 HTTP mode 下的 `signingSecretStatus`。`configured_unavailable` 表示该账号通过 SecretRef 配置,但当前命令/运行时路径无法解析出该 secret 值。 +- **Socket mode** 同时要求 `botToken` 和 `appToken`(默认账号的环境变量回退为 `SLACK_BOT_TOKEN` + `SLACK_APP_TOKEN`)。 +- **HTTP mode** 要求 `botToken` 加 `signingSecret`(可位于根级或按账号配置)。 +- `botToken`、`appToken`、`signingSecret` 和 `userToken` 接受明文 + 字符串或 SecretRef 对象。 +- Slack 账号快照会暴露每项凭证的来源/状态字段,例如 + `botTokenSource`、`botTokenStatus`、`appTokenStatus`,以及在 HTTP 模式下的 + `signingSecretStatus`。`configured_unavailable` 表示该账号通过 + SecretRef 完成配置,但当前命令/运行时路径无法解析出对应的密钥值。 - `configWrites: false` 会阻止由 Slack 发起的配置写入。 - 可选的 `channels.slack.defaultAccount` 会在其匹配某个已配置账号 ID 时,覆盖默认账号选择。 -- `channels.slack.streaming.mode` 是规范的 Slack 流式模式键。`channels.slack.streaming.nativeTransport` 控制 Slack 的原生流式传输。旧版 `streamMode`、布尔型 `streaming` 和 `nativeStreaming` 值会被自动迁移。 -- 交付目标请使用 `user:`(私信)或 `channel:`(渠道)。 +- `channels.slack.streaming.mode` 是规范的 Slack 流式传输模式键。`channels.slack.streaming.nativeTransport` 控制 Slack 的原生流式传输协议。旧版 `streamMode`、布尔型 `streaming` 和 `nativeStreaming` 值会被自动迁移。 +- 交付目标请使用 `user:`(私信)或 `channel:`。 **Reaction notification 模式:** `off`、`own`(默认)、`all`、`allowlist`(来自 `reactionAllowlist`)。 -**线程会话隔离:** `thread.historyScope` 可设为按线程(默认)或在渠道间共享。`thread.inheritParent` 会将父渠道的转录复制到新线程中。 +**线程会话隔离:** `thread.historyScope` 可以是按线程隔离(默认)或在渠道内共享。`thread.inheritParent` 会将父渠道对话记录复制到新线程中。 -- Slack 原生流式传输以及 Slack 助手风格的“正在输入...”线程状态都需要回复线程目标。顶层私信默认保持非线程,因此会使用 `typingReaction` 或普通交付,而不是线程式预览。 -- `typingReaction` 会在回复进行期间为入站 Slack 消息添加一个临时 reaction,并在完成后移除。请使用 Slack emoji 简码,例如 `"hourglass_flowing_sand"`。 -- `channels.slack.execApprovals`:Slack 原生的 exec 审批交付和审批人授权。schema 与 Discord 相同:`enabled`(`true`/`false`/`"auto"`)、`approvers`(Slack 用户 ID)、`agentFilter`、`sessionFilter` 和 `target`(`"dm"`、`"channel"` 或 `"both"`)。 +- Slack 原生流式传输加上 Slack 助手风格的 “is typing...” 线程状态,需要一个回复线程目标。顶层私信默认保持在线程之外,因此它们会使用 `typingReaction` 或常规交付,而不是线程样式预览。 +- `typingReaction` 会在回复运行期间,向传入的 Slack 消息添加一个临时 reaction,并在完成后移除。请使用 Slack emoji 简码,例如 `"hourglass_flowing_sand"`。 +- `channels.slack.execApprovals`:原生 Slack 的 exec 审批交付和审批者授权。Schema 与 Discord 相同:`enabled`(`true`/`false`/`"auto"`)、`approvers`(Slack 用户 ID)、`agentFilter`、`sessionFilter` 和 `target`(`"dm"`、`"channel"` 或 `"both"`)。 -| 操作组 | 默认值 | 说明 | -| ------------ | ------ | ------------------ | -| reactions | 启用 | 添加 reaction + 列出 reactions | -| messages | 启用 | 读取/发送/编辑/删除 | -| pins | 启用 | 固定/取消固定/列出 | -| memberInfo | 启用 | 成员信息 | -| emojiList | 启用 | 自定义 emoji 列表 | +| 操作组 | 默认值 | 说明 | +| ----------- | ------ | -------------------- | +| reactions | 启用 | 添加 reaction + 列出 reactions | +| messages | 启用 | 读取/发送/编辑/删除 | +| pins | 启用 | 置顶/取消置顶/列出 | +| memberInfo | 启用 | 成员信息 | +| emojiList | 启用 | 自定义 emoji 列表 | ### Mattermost -Mattermost 作为插件提供:`openclaw plugins install @openclaw/mattermost`。 +Mattermost 作为一个 plugin 提供:`openclaw plugins install @openclaw/mattermost`。 ```json5 { @@ -508,10 +512,10 @@ Mattermost 作为插件提供:`openclaw plugins install @openclaw/mattermost` "team-channel-id": { requireMention: false }, }, commands: { - native: true, // 显式选择加入 + native: true, // 显式启用 nativeSkills: true, callbackPath: "/api/channels/mattermost/command", - // 可选的显式 URL,用于反向代理/公网部署 + // 面向反向代理/公网部署的可选显式 URL callbackUrl: "https://gateway.example.com/api/channels/mattermost/command", }, textChunkLimit: 4000, @@ -526,12 +530,16 @@ Mattermost 作为插件提供:`openclaw plugins install @openclaw/mattermost` 启用 Mattermost 原生命令时: - `commands.callbackPath` 必须是路径(例如 `/api/channels/mattermost/command`),不能是完整 URL。 -- `commands.callbackUrl` 必须解析到 OpenClaw Gateway 网关端点,并且 Mattermost 服务器能够访问。 -- 原生斜杠回调使用 Mattermost 在注册斜杠命令时返回的每命令 token 进行认证。如果注册失败,或没有任何命令被激活,OpenClaw 会拒绝回调,并返回 `Unauthorized: invalid command token.`。 -- 对于私有 / tailnet / 内部回调主机,Mattermost 可能要求 `ServiceSettings.AllowedUntrustedInternalConnections` 包含该回调主机/域名。请使用主机/域名值,而不是完整 URL。 +- `commands.callbackUrl` 必须解析到 OpenClaw Gateway 网关端点,并且 Mattermost 服务器必须能够访问它。 +- 原生斜杠命令回调使用 Mattermost 在斜杠命令注册期间返回的每命令 token + 进行认证。如果注册失败,或没有命令被激活,OpenClaw 会拒绝回调,并返回 + `Unauthorized: invalid command token.`。 +- 对于私有/tailnet/内部回调主机,Mattermost 可能要求 + `ServiceSettings.AllowedUntrustedInternalConnections` 包含回调主机/域名。 + 请使用主机/域名值,而不是完整 URL。 - `channels.mattermost.configWrites`:允许或拒绝由 Mattermost 发起的配置写入。 - `channels.mattermost.requireMention`:在渠道中回复前要求 `@mention`。 -- `channels.mattermost.groups..requireMention`:每渠道的 mention 门控覆盖(`"*"` 为默认值)。 +- `channels.mattermost.groups..requireMention`:按渠道设置的提及门控覆盖(`"*"` 表示默认值)。 - 可选的 `channels.mattermost.defaultAccount` 会在其匹配某个已配置账号 ID 时,覆盖默认账号选择。 ### Signal @@ -561,7 +569,7 @@ Mattermost 作为插件提供:`openclaw plugins install @openclaw/mattermost` ### BlueBubbles -BlueBubbles 是推荐的 iMessage 路径(由插件支持,配置位于 `channels.bluebubbles` 下)。 +BlueBubbles 是推荐的 iMessage 接入路径(由 plugin 提供支持,配置位于 `channels.bluebubbles` 下)。 ```json5 { @@ -569,7 +577,7 @@ BlueBubbles 是推荐的 iMessage 路径(由插件支持,配置位于 `chann bluebubbles: { enabled: true, dmPolicy: "pairing", - // serverUrl、password、webhookPath、群组控制项和高级 actions: + // serverUrl、password、webhookPath、群组控制以及高级 actions: // 参见 /channels/bluebubbles }, }, @@ -578,12 +586,12 @@ BlueBubbles 是推荐的 iMessage 路径(由插件支持,配置位于 `chann - 此处涵盖的核心键路径:`channels.bluebubbles`、`channels.bluebubbles.dmPolicy`。 - 可选的 `channels.bluebubbles.defaultAccount` 会在其匹配某个已配置账号 ID 时,覆盖默认账号选择。 -- 顶层 `bindings[]` 中 `type: "acp"` 的条目可将 BlueBubbles 会话绑定到持久化 ACP 会话。请在 `match.peer.id` 中使用 BlueBubbles handle 或目标字符串(`chat_id:*`、`chat_guid:*`、`chat_identifier:*`)。共享字段语义: [ACP 智能体](/zh-CN/tools/acp-agents#channel-specific-settings)。 +- 顶层 `bindings[]` 中 `type: "acp"` 的条目可以将 BlueBubbles 对话绑定到持久 ACP 会话。在 `match.peer.id` 中使用 BlueBubbles handle 或目标字符串(`chat_id:*`、`chat_guid:*`、`chat_identifier:*`)。共享字段语义: [ACP Agents](/zh-CN/tools/acp-agents#channel-specific-settings)。 - 完整的 BlueBubbles 渠道配置记录在 [BlueBubbles](/zh-CN/channels/bluebubbles) 中。 ### iMessage -OpenClaw 会启动 `imsg rpc`(通过 stdio 进行 JSON-RPC)。无需 daemon 或端口。 +OpenClaw 会生成 `imsg rpc`(通过 stdio 的 JSON-RPC)。不需要守护进程或端口。 ```json5 { @@ -609,13 +617,13 @@ OpenClaw 会启动 `imsg rpc`(通过 stdio 进行 JSON-RPC)。无需 daemon - 可选的 `channels.imessage.defaultAccount` 会在其匹配某个已配置账号 ID 时,覆盖默认账号选择。 -- 需要对 Messages DB 拥有 Full Disk Access。 -- 优先使用 `chat_id:` 目标。使用 `imsg chats --limit 20` 可列出聊天。 -- `cliPath` 可以指向一个 SSH 包装器;设置 `remoteHost`(`host` 或 `user@host`)以便通过 SCP 获取附件。 -- `attachmentRoots` 和 `remoteAttachmentRoots` 会限制入站附件路径(默认值:`/Users/*/Library/Messages/Attachments`)。 -- SCP 使用严格主机密钥检查,因此请确保中继主机密钥已存在于 `~/.ssh/known_hosts` 中。 +- 需要对 Messages 数据库授予完全磁盘访问权限。 +- 优先使用 `chat_id:` 目标。可使用 `imsg chats --limit 20` 列出聊天。 +- `cliPath` 可以指向 SSH 包装器;设置 `remoteHost`(`host` 或 `user@host`)可用于通过 SCP 获取附件。 +- `attachmentRoots` 和 `remoteAttachmentRoots` 会限制传入附件路径(默认:`/Users/*/Library/Messages/Attachments`)。 +- SCP 使用严格的主机密钥检查,因此请确保中继主机密钥已存在于 `~/.ssh/known_hosts` 中。 - `channels.imessage.configWrites`:允许或拒绝由 iMessage 发起的配置写入。 -- 顶层 `bindings[]` 中 `type: "acp"` 的条目可将 iMessage 会话绑定到持久化 ACP 会话。请在 `match.peer.id` 中使用规范化 handle 或显式聊天目标(`chat_id:*`、`chat_guid:*`、`chat_identifier:*`)。共享字段语义: [ACP 智能体](/zh-CN/tools/acp-agents#channel-specific-settings)。 +- 顶层 `bindings[]` 中 `type: "acp"` 的条目可以将 iMessage 对话绑定到持久 ACP 会话。在 `match.peer.id` 中使用规范化 handle 或显式聊天目标(`chat_id:*`、`chat_guid:*`、`chat_identifier:*`)。共享字段语义: [ACP Agents](/zh-CN/tools/acp-agents#channel-specific-settings)。 @@ -628,7 +636,7 @@ exec ssh -T gateway-host imsg "$@" ### Matrix -Matrix 由插件支持,配置位于 `channels.matrix` 下。 +Matrix 由 plugin 提供支持,配置位于 `channels.matrix` 下。 ```json5 { @@ -659,24 +667,24 @@ Matrix 由插件支持,配置位于 `channels.matrix` 下。 ``` - Token 认证使用 `accessToken`;密码认证使用 `userId` + `password`。 -- `channels.matrix.proxy` 会通过显式的 HTTP(S) 代理转发 Matrix HTTP 流量。命名账号可通过 `channels.matrix.accounts..proxy` 覆盖。 -- `channels.matrix.network.dangerouslyAllowPrivateNetwork` 允许私有/内部 homeserver。`proxy` 与该网络选择加入项是彼此独立的控制项。 -- `channels.matrix.defaultAccount` 在多账号配置中选择首选账号。 -- `channels.matrix.autoJoin` 默认为 `off`,因此被邀请的房间和新的私信式邀请都会被忽略,直到你设置 `autoJoin: "allowlist"` 并配合 `autoJoinAllowlist`,或设置 `autoJoin: "always"`。 -- `channels.matrix.execApprovals`:Matrix 原生的 exec 审批交付和审批人授权。 - - `enabled`:`true`、`false` 或 `"auto"`(默认)。在自动模式下,当可以从 `approvers` 或 `commands.ownerAllowFrom` 解析出审批人时,exec 审批会激活。 +- `channels.matrix.proxy` 会通过显式 HTTP(S) 代理路由 Matrix HTTP 流量。命名账号可使用 `channels.matrix.accounts..proxy` 覆盖它。 +- `channels.matrix.network.dangerouslyAllowPrivateNetwork` 允许私有/内部 homeserver。`proxy` 与此网络显式启用项是相互独立的控制项。 +- `channels.matrix.defaultAccount` 用于在多账号设置中选择首选账号。 +- `channels.matrix.autoJoin` 默认为 `off`,因此受邀房间和新的私信式邀请会被忽略,直到你设置 `autoJoin: "allowlist"` 并配合 `autoJoinAllowlist`,或设置 `autoJoin: "always"`。 +- `channels.matrix.execApprovals`:原生 Matrix 的 exec 审批交付和审批者授权。 + - `enabled`:`true`、`false` 或 `"auto"`(默认)。在自动模式下,当可以从 `approvers` 或 `commands.ownerAllowFrom` 解析出审批者时,exec 审批会被激活。 - `approvers`:允许批准 exec 请求的 Matrix 用户 ID(例如 `@owner:example.org`)。 - - `agentFilter`:可选的智能体 ID allowlist。省略时会为所有智能体转发审批。 - - `sessionFilter`:可选的会话键模式(子串或正则表达式)。 - - `target`:审批提示发送位置。`"dm"`(默认)、`"channel"`(发起房间)或 `"both"`。 - - 每账号覆盖:`channels.matrix.accounts..execApprovals`。 -- `channels.matrix.dm.sessionScope` 控制 Matrix 私信如何归组到会话中:`per-user`(默认)按路由对端共享,而 `per-room` 会隔离每个私信房间。 -- Matrix 状态探测和实时目录查找与运行时流量使用相同的代理策略。 + - `agentFilter`:可选的智能体 ID allowlist。省略时会为所有智能体转发审批请求。 + - `sessionFilter`:可选的会话键模式(子串或正则)。 + - `target`:审批提示的发送位置。`"dm"`(默认)、`"channel"`(原始房间)或 `"both"`。 + - 按账号覆盖:`channels.matrix.accounts..execApprovals`。 +- `channels.matrix.dm.sessionScope` 控制 Matrix 私信如何归组为会话:`per-user`(默认)按路由对端共享,而 `per-room` 则隔离每个私信房间。 +- Matrix 状态探测和实时目录查找使用与运行时流量相同的代理策略。 - 完整的 Matrix 配置、目标规则和设置示例记录在 [Matrix](/zh-CN/channels/matrix) 中。 ### Microsoft Teams -Microsoft Teams 由插件支持,配置位于 `channels.msteams` 下。 +Microsoft Teams 由 plugin 提供支持,配置位于 `channels.msteams` 下。 ```json5 { @@ -696,7 +704,7 @@ Microsoft Teams 由插件支持,配置位于 `channels.msteams` 下。 ### IRC -IRC 由插件支持,配置位于 `channels.irc` 下。 +IRC 由 plugin 提供支持,配置位于 `channels.irc` 下。 ```json5 { @@ -719,11 +727,11 @@ IRC 由插件支持,配置位于 `channels.irc` 下。 - 此处涵盖的核心键路径:`channels.irc`、`channels.irc.dmPolicy`、`channels.irc.configWrites`、`channels.irc.nickserv.*`。 - 可选的 `channels.irc.defaultAccount` 会在其匹配某个已配置账号 ID 时,覆盖默认账号选择。 -- 完整的 IRC 渠道配置(host/port/TLS/channels/allowlists/mention 门控)记录在 [IRC](/zh-CN/channels/irc) 中。 +- 完整的 IRC 渠道配置(host/port/TLS/channels/allowlists/提及门控)记录在 [IRC](/zh-CN/channels/irc) 中。 ### 多账号(所有渠道) -每个渠道可运行多个账号(每个账号都有自己的 `accountId`): +为每个渠道运行多个账号(每个账号都有自己的 `accountId`): ```json5 { @@ -744,28 +752,28 @@ IRC 由插件支持,配置位于 `channels.irc` 下。 } ``` -- 省略 `accountId` 时使用 `default`(CLI + 路由)。 -- 环境变量 token 仅适用于**默认**账号。 -- 基础渠道设置适用于所有账号,除非被每账号配置覆盖。 -- 使用 `bindings[].match.accountId` 可将每个账号路由到不同的智能体。 -- 如果你在仍为单账号顶层渠道配置的情况下,通过 `openclaw channels add`(或渠道新手引导)添加非默认账号,OpenClaw 会先将按账号划分的顶层单账号值提升到渠道账号映射中,以便原账号继续工作。大多数渠道会将其移动到 `channels..accounts.default`;Matrix 则可以保留现有匹配的命名/default 目标。 -- 现有仅渠道级的绑定(没有 `accountId`)会继续匹配默认账号;按账号划分的绑定仍然是可选的。 -- `openclaw doctor --fix` 也会修复混合形态:将按账号划分的顶层单账号值移动到该渠道所选的提升账号中。大多数渠道使用 `accounts.default`;Matrix 则可以保留现有匹配的命名/default 目标。 +- 当省略 `accountId` 时,会使用 `default`(CLI + 路由)。 +- 环境变量 token 只适用于**默认**账号。 +- 基础渠道设置适用于所有账号,除非在各账号中单独覆盖。 +- 使用 `bindings[].match.accountId` 将每个账号路由到不同的智能体。 +- 如果你通过 `openclaw channels add`(或渠道新手引导)添加非默认账号,而当前仍处于单账号顶层渠道配置,OpenClaw 会先将按账号作用域划分的顶层单账号值提升到该渠道的账号映射中,以确保原始账号继续可用。大多数渠道会将它们移到 `channels..accounts.default`;而 Matrix 则可以改为保留现有的匹配命名/默认目标。 +- 现有仅渠道级的绑定(无 `accountId`)将继续匹配默认账号;按账号作用域的绑定仍然是可选的。 +- `openclaw doctor --fix` 也会修复混合形态,方法是将按账号作用域划分的顶层单账号值移动到为该渠道选定的提升账号中。大多数渠道使用 `accounts.default`;Matrix 则可以改为保留现有的匹配命名/默认目标。 -### 其他渠道插件 +### 其他插件渠道 -许多渠道插件都配置为 `channels.`,并记录在各自专属的渠道页面中(例如 Feishu、Matrix、LINE、Nostr、Zalo、Nextcloud Talk、Synology Chat 和 Twitch)。 -请参见完整渠道索引:[渠道](/zh-CN/channels)。 +许多 plugin 渠道都配置为 `channels.`,并在各自专属的渠道页面中记录(例如 Feishu、Matrix、LINE、Nostr、Zalo、Nextcloud Talk、Synology Chat 和 Twitch)。 +请参见完整的渠道索引:[渠道](/zh-CN/channels)。 -### 群聊 mention 门控 +### 群聊提及门控 -群组消息默认**要求 mention**(元数据 mention 或安全正则模式)。适用于 WhatsApp、Telegram、Discord、Google Chat 和 iMessage 群聊。 +群组消息默认**要求提及**(元数据提及或安全正则模式)。适用于 WhatsApp、Telegram、Discord、Google Chat 和 iMessage 群聊。 -**Mention 类型:** +**提及类型:** -- **元数据 mentions**:平台原生 @mentions。在 WhatsApp self-chat 模式中会被忽略。 +- **元数据提及**:平台原生 @ 提及。在 WhatsApp self-chat 模式下会被忽略。 - **文本模式**:位于 `agents.list[].groupChat.mentionPatterns` 中的安全正则模式。无效模式和不安全的嵌套重复会被忽略。 -- 仅当检测可行时(原生 mentions 或至少存在一个模式),才会执行 mention 门控。 +- 仅当可以进行检测时(原生提及或至少存在一个模式)才会强制执行提及门控。 ```json5 { @@ -778,9 +786,9 @@ IRC 由插件支持,配置位于 `channels.irc` 下。 } ``` -`messages.groupChat.historyLimit` 设置全局默认值。渠道可通过 `channels..historyLimit`(或每账号配置)覆盖。设为 `0` 可禁用。 +`messages.groupChat.historyLimit` 设置全局默认值。各渠道可通过 `channels..historyLimit`(或按账号)进行覆盖。设为 `0` 可禁用。 -#### 私信历史记录上限 +#### 私信历史记录限制 ```json5 { @@ -795,13 +803,13 @@ IRC 由插件支持,配置位于 `channels.irc` 下。 } ``` -解析顺序:每私信覆盖 → 提供商默认值 → 不限(全部保留)。 +解析顺序:按私信覆盖 → 提供商默认值 → 不限制(全部保留)。 支持:`telegram`、`whatsapp`、`discord`、`slack`、`signal`、`imessage`、`msteams`。 #### self-chat 模式 -在 `allowFrom` 中包含你自己的号码即可启用 self-chat 模式(忽略原生 @mentions,只响应文本模式): +将你自己的号码包含在 `allowFrom` 中以启用 self-chat 模式(忽略原生 @ 提及,仅响应文本模式): ```json5 { @@ -851,32 +859,32 @@ IRC 由插件支持,配置位于 `channels.irc` 下。 -- 此配置块用于配置命令面。当前内置 + 内置插件命令目录请参见 [斜杠命令](/zh-CN/tools/slash-commands)。 -- 本页是**配置键参考**,不是完整命令目录。由渠道/插件拥有的命令,例如 QQ Bot `/bot-ping` `/bot-help` `/bot-logs`、LINE `/card`、device-pair `/pair`、memory `/dreaming`、phone-control `/phone` 和 Talk `/voice`,记录在各自的渠道/插件页面以及 [斜杠命令](/zh-CN/tools/slash-commands) 中。 +- 此块配置命令面。当前内置 + 内置 plugin 命令目录请参见 [Slash Commands](/zh-CN/tools/slash-commands)。 +- 本页是**配置键参考**,不是完整的命令目录。诸如 QQ Bot `/bot-ping` `/bot-help` `/bot-logs`、LINE `/card`、设备配对 `/pair`、memory `/dreaming`、phone-control `/phone` 以及 Talk `/voice` 这类由渠道/plugin 拥有的命令,记录在它们各自的渠道/plugin 页面以及 [Slash Commands](/zh-CN/tools/slash-commands) 中。 - 文本命令必须是带前导 `/` 的**独立**消息。 -- `native: "auto"` 会为 Discord/Telegram 启用原生命令,对 Slack 保持关闭。 -- `nativeSkills: "auto"` 会为 Discord/Telegram 启用原生 Skills 命令,对 Slack 保持关闭。 -- 按渠道覆盖:`channels.discord.commands.native`(布尔值或 `"auto"`)。`false` 会清除先前已注册的命令。 -- 使用 `channels..commands.nativeSkills` 可按渠道覆盖原生 Skills 注册。 +- `native: "auto"` 会为 Discord/Telegram 打开原生命令,对 Slack 保持关闭。 +- `nativeSkills: "auto"` 会为 Discord/Telegram 打开原生 Skills 命令,对 Slack 保持关闭。 +- 可按渠道覆盖:`channels.discord.commands.native`(布尔值或 `"auto"`)。`false` 会清除之前已注册的命令。 +- 可通过 `channels..commands.nativeSkills` 按渠道覆盖原生 Skills 注册。 - `channels.telegram.customCommands` 会添加额外的 Telegram bot 菜单项。 -- `bash: true` 会为主机 shell 启用 `! `。需要 `tools.elevated.enabled`,且发送者位于 `tools.elevated.allowFrom.` 中。 -- `config: true` 会启用 `/config`(读取/写入 `openclaw.json`)。对于 Gateway 网关 `chat.send` 客户端,持久化的 `/config set|unset` 写入还需要 `operator.admin`;只读的 `/config show` 对普通写作用域的 operator 客户端仍然可用。 +- `bash: true` 会为主机 shell 启用 `! `。要求 `tools.elevated.enabled` 已启用,且发送者位于 `tools.elevated.allowFrom.` 中。 +- `config: true` 会启用 `/config`(读取/写入 `openclaw.json`)。对于 Gateway 网关 `chat.send` 客户端,持久化的 `/config set|unset` 写入还要求 `operator.admin`;只读的 `/config show` 仍对普通写作用域的 operator 客户端可用。 - `mcp: true` 会为 `mcp.servers` 下由 OpenClaw 管理的 MCP 服务器配置启用 `/mcp`。 -- `plugins: true` 会启用 `/plugins`,用于插件发现、安装和启用/禁用控制。 +- `plugins: true` 会为 plugin 发现、安装以及启用/禁用控制启用 `/plugins`。 - `channels..configWrites` 会按渠道控制配置变更(默认:true)。 -- 对于多账号渠道,`channels..accounts..configWrites` 也会控制针对该账号的写入(例如 `/allowlist --config --account ` 或 `/config set channels..accounts....`)。 +- 对于多账号渠道,`channels..accounts..configWrites` 也会控制以该账号为目标的写入(例如 `/allowlist --config --account ` 或 `/config set channels..accounts....`)。 - `restart: false` 会禁用 `/restart` 和 gateway restart 工具操作。默认值:`true`。 -- `ownerAllowFrom` 是仅限 owner 命令/工具的显式 owner allowlist。它与 `allowFrom` 分开。 -- `ownerDisplay: "hash"` 会在系统提示中对 owner ID 进行哈希。设置 `ownerDisplaySecret` 可控制哈希方式。 -- `allowFrom` 按提供商设置。设置后,它将成为**唯一**授权来源(渠道 allowlists/配对以及 `useAccessGroups` 都会被忽略)。 -- 当未设置 `allowFrom` 时,`useAccessGroups: false` 允许命令绕过访问组策略。 +- `ownerAllowFrom` 是 owner 专用命令/工具的显式 owner allowlist。它与 `allowFrom` 分开。 +- `ownerDisplay: "hash"` 会在系统提示中对 owner id 进行哈希处理。设置 `ownerDisplaySecret` 可控制哈希方式。 +- `allowFrom` 按提供商生效。设置后,它将成为**唯一**的授权来源(渠道 allowlist/配对以及 `useAccessGroups` 都会被忽略)。 +- `useAccessGroups: false` 会在未设置 `allowFrom` 时,允许命令绕过访问组策略。 - 命令文档映射: - - 内置 + 内置插件目录:[斜杠命令](/zh-CN/tools/slash-commands) - - 渠道特定命令面:[渠道](/zh-CN/channels) + - 内置 + 内置变体目录:[Slash Commands](/zh-CN/tools/slash-commands) + - 渠道专属命令面:[渠道](/zh-CN/channels) - QQ Bot 命令:[QQ Bot](/zh-CN/channels/qqbot) - 配对命令:[配对](/zh-CN/channels/pairing) - LINE 卡片命令:[LINE](/zh-CN/channels/line) - - memory Dreaming:[Dreaming](/zh-CN/concepts/dreaming) + - memory dreaming:[Dreaming](/zh-CN/concepts/dreaming) @@ -896,7 +904,7 @@ IRC 由插件支持,配置位于 `channels.irc` 下。 ### `agents.defaults.repoRoot` -可选的仓库根目录,会显示在系统提示的 Runtime 行中。如果未设置,OpenClaw 会从工作区向上遍历自动检测。 +可选的仓库根目录,会显示在系统提示的 Runtime 行中。如果未设置,OpenClaw 会从 workspace 向上遍历并自动检测。 ```json5 { @@ -906,7 +914,9 @@ IRC 由插件支持,配置位于 `channels.irc` 下。 ### `agents.defaults.skills` -适用于未设置 `agents.list[].skills` 的智能体的可选默认 Skills allowlist。 +为未设置 +`agents.list[].skills` +的智能体提供可选的默认 Skills allowlist。 ```json5 { @@ -921,15 +931,15 @@ IRC 由插件支持,配置位于 `channels.irc` 下。 } ``` -- 省略 `agents.defaults.skills` 可使默认 Skills 不受限制。 -- 省略 `agents.list[].skills` 可继承默认值。 -- 设置 `agents.list[].skills: []` 表示无 Skills。 +- 省略 `agents.defaults.skills` 表示默认 Skills 不受限制。 +- 省略 `agents.list[].skills` 表示继承默认值。 +- 设置 `agents.list[].skills: []` 表示不使用 Skills。 - 非空的 `agents.list[].skills` 列表就是该智能体的最终集合;它 不会与默认值合并。 ### `agents.defaults.skipBootstrap` -禁用工作区 bootstrap 文件的自动创建(`AGENTS.md`、`SOUL.md`、`TOOLS.md`、`IDENTITY.md`、`USER.md`、`HEARTBEAT.md`、`BOOTSTRAP.md`)。 +禁用自动创建 workspace bootstrap 文件(`AGENTS.md`、`SOUL.md`、`TOOLS.md`、`IDENTITY.md`、`USER.md`、`HEARTBEAT.md`、`BOOTSTRAP.md`)。 ```json5 { @@ -939,9 +949,9 @@ IRC 由插件支持,配置位于 `channels.irc` 下。 ### `agents.defaults.contextInjection` -控制何时将工作区 bootstrap 文件注入系统提示。默认值:`"always"`。 +控制何时将 workspace bootstrap 文件注入系统提示。默认值:`"always"`。 -- `"continuation-skip"`:安全续接轮次(在助手已完成响应之后)会跳过工作区 bootstrap 的重新注入,从而减小提示大小。Heartbeat 运行和压缩后重试仍会重建上下文。 +- `"continuation-skip"`:安全续接轮次(在 assistant 已完成一次响应之后)会跳过重新注入 workspace bootstrap,从而减小提示大小。Heartbeat 运行和压缩后重试仍会重建上下文。 ```json5 { @@ -951,7 +961,7 @@ IRC 由插件支持,配置位于 `channels.irc` 下。 ### `agents.defaults.bootstrapMaxChars` -单个工作区 bootstrap 文件在截断前的最大字符数。默认值:`12000`。 +每个 workspace bootstrap 文件在截断前允许的最大字符数。默认值:`12000`。 ```json5 { @@ -961,7 +971,7 @@ IRC 由插件支持,配置位于 `channels.irc` 下。 ### `agents.defaults.bootstrapTotalMaxChars` -所有工作区 bootstrap 文件合计可注入的最大字符数。默认值:`60000`。 +跨所有 workspace bootstrap 文件注入的最大总字符数。默认值:`60000`。 ```json5 { @@ -971,12 +981,12 @@ IRC 由插件支持,配置位于 `channels.irc` 下。 ### `agents.defaults.bootstrapPromptTruncationWarning` -控制当 bootstrap 上下文被截断时,向智能体显示的警告文本。 +控制 bootstrap 上下文被截断时,对智能体可见的警告文本。 默认值:`"once"`。 -- `"off"`:绝不向系统提示中注入警告文本。 -- `"once"`:每个唯一的截断签名仅注入一次警告(推荐)。 -- `"always"`:只要存在截断,每次运行都注入警告。 +- `"off"`:绝不在系统提示中注入警告文本。 +- `"once"`:对每个唯一的截断签名仅注入一次警告(推荐)。 +- `"always"`:只要存在截断,就在每次运行时都注入警告。 ```json5 { @@ -986,25 +996,24 @@ IRC 由插件支持,配置位于 `channels.irc` 下。 ### 上下文预算归属映射 -OpenClaw 有多个高容量的提示/上下文预算,并且它们被 -有意按子系统拆分,而不是全部流经一个通用 +OpenClaw 有多个高容量的提示/上下文预算,它们 +被有意按子系统拆分,而不是全部流经一个通用 旋钮。 - `agents.defaults.bootstrapMaxChars` / `agents.defaults.bootstrapTotalMaxChars`: - 常规工作区 bootstrap 注入。 + 常规 workspace bootstrap 注入。 - `agents.defaults.startupContext.*`: 一次性的 `/new` 和 `/reset` 启动前导内容,包括最近的每日 `memory/*.md` 文件。 - `skills.limits.*`: - 注入系统提示中的紧凑 Skills 列表。 + 注入系统提示中的精简 Skills 列表。 - `agents.defaults.contextLimits.*`: - 有界运行时摘录和注入的运行时所属块。 + 有边界的运行时摘录和由运行时拥有的注入块。 - `memory.qmd.limits.*`: - 已索引 memory 搜索片段和注入大小控制。 + 已索引 memory 搜索片段和注入大小。 -仅当某个智能体需要不同 -预算时,才使用对应的每智能体覆盖: +仅当某个智能体需要不同预算时,才使用匹配的按智能体覆盖项: - `agents.list[].skillsLimits.maxSkillsPromptChars` - `agents.list[].contextLimits.*` @@ -1033,7 +1042,7 @@ OpenClaw 有多个高容量的提示/上下文预算,并且它们被 #### `agents.defaults.contextLimits` -有界运行时上下文面的共享默认值。 +为有边界的运行时上下文面提供共享默认值。 ```json5 { @@ -1050,19 +1059,19 @@ OpenClaw 有多个高容量的提示/上下文预算,并且它们被 } ``` -- `memoryGetMaxChars`:在添加截断元数据 - 和续接提示之前,`memory_get` 摘录的默认上限。 -- `memoryGetDefaultLines`:省略 `lines` 时, - `memory_get` 的默认行窗口。 +- `memoryGetMaxChars`:`memory_get` 摘录的默认上限;超过后会添加截断 + 元数据和续接提示。 +- `memoryGetDefaultLines`:当省略 `lines` 时,`memory_get` 的默认 + 行窗口。 - `toolResultMaxChars`:用于持久化结果和 溢出恢复的实时工具结果上限。 -- `postCompactionMaxChars`:用于压缩后刷新注入期间 +- `postCompactionMaxChars`:在压缩后刷新注入期间使用的 `AGENTS.md` 摘录上限。 #### `agents.list[].contextLimits` -共享 `contextLimits` 旋钮的每智能体覆盖。省略的字段会继承 -自 `agents.defaults.contextLimits`。 +共享 `contextLimits` 旋钮的按智能体覆盖项。省略的字段会继承 +`agents.defaults.contextLimits`。 ```json5 { @@ -1088,7 +1097,7 @@ OpenClaw 有多个高容量的提示/上下文预算,并且它们被 #### `skills.limits.maxSkillsPromptChars` -注入系统提示中的紧凑 Skills 列表的全局上限。此项 +注入系统提示中的精简 Skills 列表的全局上限。这 不会影响按需读取 `SKILL.md` 文件。 ```json5 @@ -1103,7 +1112,7 @@ OpenClaw 有多个高容量的提示/上下文预算,并且它们被 #### `agents.list[].skillsLimits.maxSkillsPromptChars` -Skills 提示预算的每智能体覆盖。 +Skills 提示预算的按智能体覆盖项。 ```json5 { @@ -1125,8 +1134,8 @@ Skills 提示预算的每智能体覆盖。 在调用提供商之前,转录/工具图像块中图像最长边的最大像素尺寸。 默认值:`1200`。 -较低的值通常会减少视觉 token 使用量以及以截图为主的运行中的请求负载大小。 -较高的值会保留更多视觉细节。 +较低的值通常会降低 vision token 使用量,并减小以截图为主运行时的请求负载大小。 +较高的值则能保留更多视觉细节。 ```json5 { @@ -1136,7 +1145,7 @@ Skills 提示预算的每智能体覆盖。 ### `agents.defaults.userTimezone` -用于系统提示上下文的时区(不影响消息时间戳)。未设置时回退到主机时区。 +系统提示上下文所用的时区(不是消息时间戳)。会回退到主机时区。 ```json5 { @@ -1146,7 +1155,7 @@ Skills 提示预算的每智能体覆盖。 ### `agents.defaults.timeFormat` -系统提示中的时间格式。默认值:`auto`(OS 偏好)。 +系统提示中的时间格式。默认值:`auto`(操作系统偏好)。 ```json5 { @@ -1186,7 +1195,7 @@ Skills 提示预算的每智能体覆盖。 }, params: { cacheRetention: "long" }, // 全局默认提供商参数 embeddedHarness: { - runtime: "auto", // auto | pi | 已注册的 harness id,例如 codex + runtime: "auto", // auto | pi | 已注册 harness id,例如 codex fallback: "pi", // pi | none }, pdfMaxBytesMb: 10, @@ -1203,50 +1212,50 @@ Skills 提示预算的每智能体覆盖。 } ``` -- `model`:接受字符串(`"provider/model"`)或对象(`{ primary, fallbacks }`)。 - - 字符串形式仅设置主模型。 - - 对象形式设置主模型以及按顺序的故障转移模型。 -- `imageModel`:接受字符串(`"provider/model"`)或对象(`{ primary, fallbacks }`)。 - - 作为 `image` 工具路径的视觉模型配置使用。 - - 当所选/默认模型无法接受图像输入时,也会用作后备路由。 -- `imageGenerationModel`:接受字符串(`"provider/model"`)或对象(`{ primary, fallbacks }`)。 - - 用于共享图像生成能力,以及任何未来会生成图像的工具/插件面。 - - 典型值:用于原生 Gemini 图像生成的 `google/gemini-3.1-flash-image-preview`、用于 fal 的 `fal/fal-ai/flux/dev`,或用于 OpenAI Images 的 `openai/gpt-image-2`。 - - 如果你直接选择某个 provider/model,也请配置匹配的提供商认证/API key(例如 `google/*` 使用 `GEMINI_API_KEY` 或 `GOOGLE_API_KEY`,`openai/*` 使用 `OPENAI_API_KEY`,`fal/*` 使用 `FAL_KEY`)。 - - 如果省略,`image_generate` 仍可推断出一个具备认证的提供商默认值。它会先尝试当前默认提供商,然后再按 provider-id 顺序尝试其余已注册的图像生成提供商。 -- `musicGenerationModel`:接受字符串(`"provider/model"`)或对象(`{ primary, fallbacks }`)。 - - 用于共享音乐生成能力和内置 `music_generate` 工具。 - - 典型值:`google/lyria-3-clip-preview`、`google/lyria-3-pro-preview` 或 `minimax/music-2.5+`。 - - 如果省略,`music_generate` 仍可推断出一个具备认证的提供商默认值。它会先尝试当前默认提供商,然后再按 provider-id 顺序尝试其余已注册的音乐生成提供商。 - - 如果你直接选择某个 provider/model,也请配置匹配的提供商认证/API key。 -- `videoGenerationModel`:接受字符串(`"provider/model"`)或对象(`{ primary, fallbacks }`)。 - - 用于共享视频生成能力和内置 `video_generate` 工具。 - - 典型值:`qwen/wan2.6-t2v`、`qwen/wan2.6-i2v`、`qwen/wan2.6-r2v`、`qwen/wan2.6-r2v-flash` 或 `qwen/wan2.7-r2v`。 - - 如果省略,`video_generate` 仍可推断出一个具备认证的提供商默认值。它会先尝试当前默认提供商,然后再按 provider-id 顺序尝试其余已注册的视频生成提供商。 - - 如果你直接选择某个 provider/model,也请配置匹配的提供商认证/API key。 +- `model`:接受字符串(`"provider/model"`)或对象(`{ primary, fallbacks }`)两种形式。 + - 字符串形式只设置主模型。 + - 对象形式设置主模型以及有序故障切换模型。 +- `imageModel`:接受字符串(`"provider/model"`)或对象(`{ primary, fallbacks }`)两种形式。 + - 用作 `image` 工具路径的 vision 模型配置。 + - 当所选/默认模型无法接受图像输入时,也会用作回退路由。 +- `imageGenerationModel`:接受字符串(`"provider/model"`)或对象(`{ primary, fallbacks }`)两种形式。 + - 用于共享图像生成能力,以及任何未来会生成图像的工具/plugin 表面。 + - 常见取值:用于原生 Gemini 图像生成的 `google/gemini-3.1-flash-image-preview`、用于 fal 的 `fal/fal-ai/flux/dev`,或用于 OpenAI Images 的 `openai/gpt-image-2`。 + - 如果你直接选择某个提供商/模型,也要配置匹配的提供商认证/API key(例如 `google/*` 对应的 `GEMINI_API_KEY` 或 `GOOGLE_API_KEY`,`openai/*` 对应的 `OPENAI_API_KEY`,`fal/*` 对应的 `FAL_KEY`)。 + - 如果省略,`image_generate` 仍可推断出带认证支持的提供商默认值。它会先尝试当前默认提供商,然后按提供商 ID 顺序尝试其余已注册的图像生成提供商。 +- `musicGenerationModel`:接受字符串(`"provider/model"`)或对象(`{ primary, fallbacks }`)两种形式。 + - 用于共享音乐生成能力和内置的 `music_generate` 工具。 + - 常见取值:`google/lyria-3-clip-preview`、`google/lyria-3-pro-preview` 或 `minimax/music-2.5+`。 + - 如果省略,`music_generate` 仍可推断出带认证支持的提供商默认值。它会先尝试当前默认提供商,然后按提供商 ID 顺序尝试其余已注册的音乐生成提供商。 + - 如果你直接选择某个提供商/模型,也要配置匹配的提供商认证/API key。 +- `videoGenerationModel`:接受字符串(`"provider/model"`)或对象(`{ primary, fallbacks }`)两种形式。 + - 用于共享视频生成能力和内置的 `video_generate` 工具。 + - 常见取值:`qwen/wan2.6-t2v`、`qwen/wan2.6-i2v`、`qwen/wan2.6-r2v`、`qwen/wan2.6-r2v-flash` 或 `qwen/wan2.7-r2v`。 + - 如果省略,`video_generate` 仍可推断出带认证支持的提供商默认值。它会先尝试当前默认提供商,然后按提供商 ID 顺序尝试其余已注册的视频生成提供商。 + - 如果你直接选择某个提供商/模型,也要配置匹配的提供商认证/API key。 - 内置的 Qwen 视频生成提供商最多支持 1 个输出视频、1 张输入图像、4 个输入视频、10 秒时长,以及提供商级别的 `size`、`aspectRatio`、`resolution`、`audio` 和 `watermark` 选项。 -- `pdfModel`:接受字符串(`"provider/model"`)或对象(`{ primary, fallbacks }`)。 +- `pdfModel`:接受字符串(`"provider/model"`)或对象(`{ primary, fallbacks }`)两种形式。 - 用于 `pdf` 工具的模型路由。 - - 如果省略,PDF 工具会先回退到 `imageModel`,再回退到已解析的会话/默认模型。 -- `pdfMaxBytesMb`:`pdf` 工具在调用时未传入 `maxBytesMb` 时使用的默认 PDF 大小上限。 -- `pdfMaxPages`:`pdf` 工具中提取回退模式默认考虑的最大页数。 -- `verboseDefault`:智能体的默认 verbose 级别。取值:`"off"`、`"on"`、`"full"`。默认值:`"off"`。 -- `elevatedDefault`:智能体的默认 elevated-output 级别。取值:`"off"`、`"on"`、`"ask"`、`"full"`。默认值:`"on"`。 -- `model.primary`:格式为 `provider/model`(例如 `openai/gpt-5.4`)。如果你省略 provider,OpenClaw 会先尝试别名,然后尝试与该精确模型 id 唯一匹配的已配置提供商,最后才回退到已配置的默认提供商(这是已弃用的兼容行为,因此建议优先使用显式 `provider/model`)。如果该提供商已不再提供配置中的默认模型,OpenClaw 会回退到第一个已配置的 provider/model,而不是继续暴露一个陈旧的已移除提供商默认值。 -- `models`:已配置的模型目录和 `/model` 的 allowlist。每个条目可包含 `alias`(快捷方式)和 `params`(提供商特定参数,例如 `temperature`、`maxTokens`、`cacheRetention`、`context1m`)。 - - 安全编辑方式:使用 `openclaw config set agents.defaults.models '' --strict-json --merge` 添加条目。`config set` 会拒绝会移除现有 allowlist 条目的替换操作,除非你传入 `--replace`。 - - 按提供商划分的配置/新手引导流程会将选中的提供商模型合并到该映射中,并保留其他已配置且不相关的提供商。 -- `params`:应用到所有模型的全局默认提供商参数。设置位置为 `agents.defaults.params`(例如 `{ cacheRetention: "long" }`)。 -- `params` 合并优先级(配置):`agents.defaults.params`(全局基础)会被 `agents.defaults.models["provider/model"].params`(每模型)覆盖,然后再由 `agents.list[].params`(匹配的智能体 id)按键覆盖。详见 [提示缓存](/zh-CN/reference/prompt-caching)。 -- `embeddedHarness`:默认的低层嵌入式智能体运行时策略。使用 `runtime: "auto"` 可让已注册的插件 harness 接管其支持的模型,使用 `runtime: "pi"` 可强制使用内置 PI harness,或使用已注册的 harness id,例如 `runtime: "codex"`。设置 `fallback: "none"` 可禁用自动 PI 回退。 -- 会修改这些字段的配置写入器(例如 `/models set`、`/models set-image` 以及后备模型 add/remove 命令)会保存为规范对象形式,并尽可能保留现有后备列表。 -- `maxConcurrent`:跨会话的最大并行智能体运行数(每个会话本身仍然串行)。默认值:4。 + - 如果省略,PDF 工具会先回退到 `imageModel`,再回退到解析后的会话/默认模型。 +- `pdfMaxBytesMb`:当调用时未传入 `maxBytesMb` 时,`pdf` 工具使用的默认 PDF 大小限制。 +- `pdfMaxPages`:`pdf` 工具在提取回退模式下默认考虑的最大页数。 +- `verboseDefault`:智能体的默认详细级别。取值:`"off"`、`"on"`、`"full"`。默认值:`"off"`。 +- `elevatedDefault`:智能体的默认高级输出级别。取值:`"off"`、`"on"`、`"ask"`、`"full"`。默认值:`"on"`。 +- `model.primary`:格式为 `provider/model`(例如 `openai/gpt-5.4`)。如果你省略提供商,OpenClaw 会先尝试别名,然后尝试与该精确模型 ID 唯一匹配的已配置提供商,最后才回退到已配置的默认提供商(这是已弃用的兼容行为,因此更推荐显式使用 `provider/model`)。如果该提供商不再暴露已配置的默认模型,OpenClaw 会回退到第一个已配置的提供商/模型,而不是继续暴露一个过时的、已移除提供商默认值。 +- `models`:供 `/model` 使用的已配置模型目录和 allowlist。每个条目都可包含 `alias`(快捷方式)和 `params`(提供商特定参数,例如 `temperature`、`maxTokens`、`cacheRetention`、`context1m`)。 + - 安全编辑:使用 `openclaw config set agents.defaults.models '' --strict-json --merge` 来添加条目。`config set` 会拒绝会移除现有 allowlist 条目的替换操作,除非你传入 `--replace`。 + - 按提供商作用域的配置/新手引导流程会将选定提供商的模型合并到此映射中,并保留已配置的无关提供商。 +- `params`:应用于所有模型的全局默认提供商参数。设置位置为 `agents.defaults.params`(例如 `{ cacheRetention: "long" }`)。 +- `params` 合并优先级(配置):`agents.defaults.params`(全局基础)会被 `agents.defaults.models["provider/model"].params`(按模型)覆盖,然后 `agents.list[].params`(匹配的智能体 ID)再按键覆盖。详情请参见 [Prompt Caching](/zh-CN/reference/prompt-caching)。 +- `embeddedHarness`:默认的底层嵌入式智能体运行时策略。使用 `runtime: "auto"` 可让已注册的 plugin harness 接管受支持模型,使用 `runtime: "pi"` 可强制使用内置 PI harness,或使用已注册 harness id,如 `runtime: "codex"`。设置 `fallback: "none"` 可禁用自动 PI 回退。 +- 会修改这些字段的配置写入器(例如 `/models set`、`/models set-image` 以及回退 add/remove 命令)会保存规范的对象形式,并在可能时保留现有回退列表。 +- `maxConcurrent`:跨会话的最大并行智能体运行数(每个会话本身仍是串行的)。默认值:4。 ### `agents.defaults.embeddedHarness` -`embeddedHarness` 控制哪个低层执行器运行嵌入式智能体轮次。 +`embeddedHarness` 控制哪种底层执行器来运行嵌入式智能体轮次。 大多数部署应保持默认值 `{ runtime: "auto", fallback: "pi" }`。 -当受信任的插件提供原生 harness 时可使用它,例如内置的 +当受信任的 plugin 提供原生 harness 时可以使用它,例如内置的 Codex app-server harness。 ```json5 @@ -1263,13 +1272,13 @@ Codex app-server harness。 } ``` -- `runtime`:`"auto"`、`"pi"` 或已注册的插件 harness id。内置 Codex 插件注册的 id 为 `codex`。 -- `fallback`:`"pi"` 或 `"none"`。`"pi"` 会在未选择插件 harness 时,将内置 PI harness 保留为兼容性回退。`"none"` 则会在插件 harness 选择缺失或不受支持时直接失败,而不是静默使用 PI。所选插件 harness 的失败始终会直接暴露。 +- `runtime`:`"auto"`、`"pi"` 或已注册的 plugin harness id。内置 Codex plugin 注册的是 `codex`。 +- `fallback`:`"pi"` 或 `"none"`。当未选择 plugin harness 时,`"pi"` 会保留内置 PI harness 作为兼容回退;`"none"` 则会在缺少或不支持所选 plugin harness 时直接失败,而不是静默使用 PI。所选 plugin harness 的失败始终会直接暴露。 - 环境变量覆盖:`OPENCLAW_AGENT_RUNTIME=` 会覆盖 `runtime`;`OPENCLAW_AGENT_HARNESS_FALLBACK=none` 会为该进程禁用 PI 回退。 -- 对于仅 Codex 的部署,请设置 `model: "codex/gpt-5.4"`、`embeddedHarness.runtime: "codex"` 和 `embeddedHarness.fallback: "none"`。 -- 这只控制嵌入式聊天 harness。媒体生成、视觉、PDF、音乐、视频和 TTS 仍使用各自的 provider/model 设置。 +- 对于仅使用 Codex 的部署,设置 `model: "codex/gpt-5.4"`、`embeddedHarness.runtime: "codex"` 和 `embeddedHarness.fallback: "none"`。 +- 这只控制嵌入式聊天 harness。媒体生成、vision、PDF、音乐、视频和 TTS 仍使用各自的提供商/模型设置。 -**内置别名简写**(仅在模型存在于 `agents.defaults.models` 中时生效): +**内置别名简写**(仅当模型位于 `agents.defaults.models` 中时适用): | 别名 | 模型 | | ------------------- | -------------------------------------- | @@ -1282,15 +1291,15 @@ Codex app-server harness。 | `gemini-flash` | `google/gemini-3-flash-preview` | | `gemini-flash-lite` | `google/gemini-3.1-flash-lite-preview` | -你配置的别名始终优先生效。 +你配置的别名始终优先于默认值。 -Z.AI 的 GLM-4.x 模型会自动启用 thinking 模式,除非你设置 `--thinking off`,或自行定义 `agents.defaults.models["zai/"].params.thinking`。 -Z.AI 模型默认启用 `tool_stream` 以进行工具调用流式传输。将 `agents.defaults.models["zai/"].params.tool_stream` 设为 `false` 可禁用它。 +Z.AI GLM-4.x 模型会自动启用 thinking 模式,除非你设置 `--thinking off`,或自行定义 `agents.defaults.models["zai/"].params.thinking`。 +Z.AI 模型默认启用 `tool_stream` 用于工具调用流式传输。将 `agents.defaults.models["zai/"].params.tool_stream` 设为 `false` 可将其禁用。 Anthropic Claude 4.6 模型在未设置显式 thinking 级别时,默认使用 `adaptive` thinking。 ### `agents.defaults.cliBackends` -用于纯文本回退运行(无工具调用)的可选 CLI 后端。当 API 提供商失败时,它可作为备用方案。 +用于纯文本回退运行(无工具调用)的可选 CLI 后端。在 API 提供商失败时,可作为备用方案。 ```json5 { @@ -1320,11 +1329,11 @@ Anthropic Claude 4.6 模型在未设置显式 thinking 级别时,默认使用 - CLI 后端以文本为主;工具始终禁用。 - 设置了 `sessionArg` 时支持会话。 -- 当 `imageArg` 接受文件路径时,支持图像透传。 +- 如果 `imageArg` 接受文件路径,则支持图像透传。 ### `agents.defaults.systemPromptOverride` -用固定字符串替换 OpenClaw 组装的整个系统提示。可设置在默认级别(`agents.defaults.systemPromptOverride`)或每智能体级别(`agents.list[].systemPromptOverride`)。每智能体值优先生效;空值或仅空白的值会被忽略。适用于受控的提示实验。 +用固定字符串替换由 OpenClaw 组装的整个系统提示。可在默认级别(`agents.defaults.systemPromptOverride`)或按智能体(`agents.list[].systemPromptOverride`)设置。按智能体的值优先;空值或仅包含空白字符的值会被忽略。适用于受控的提示实验。 ```json5 { @@ -1338,7 +1347,7 @@ Anthropic Claude 4.6 模型在未设置显式 thinking 级别时,默认使用 ### `agents.defaults.promptOverlays` -按模型家族应用、与提供商无关的提示覆盖。GPT-5 家族模型 id 会在不同提供商间接收共享的行为契约;`personality` 仅控制友好的交互风格层。 +按模型家族应用、与提供商无关的提示覆盖。GPT-5 系列模型 ID 会跨提供商接收共享行为契约;`personality` 仅控制友好交互风格这一层。 ```json5 { @@ -1354,13 +1363,13 @@ Anthropic Claude 4.6 模型在未设置显式 thinking 级别时,默认使用 } ``` -- `"friendly"`(默认)和 `"on"` 会启用友好的交互风格层。 -- `"off"` 仅禁用友好层;带标签的 GPT-5 行为契约仍然启用。 -- 当该共享设置未设置时,仍会读取旧版 `plugins.entries.openai.config.personality`。 +- `"friendly"`(默认)和 `"on"` 会启用友好交互风格层。 +- `"off"` 只会禁用友好层;带标签的 GPT-5 行为契约仍然启用。 +- 当此共享设置未设置时,仍会读取旧版 `plugins.entries.openai.config.personality`。 ### `agents.defaults.heartbeat` -周期性 heartbeat 运行。 +定期 heartbeat 运行。 ```json5 { @@ -1371,12 +1380,12 @@ Anthropic Claude 4.6 模型在未设置显式 thinking 级别时,默认使用 model: "openai/gpt-5.4-mini", includeReasoning: false, includeSystemPromptSection: true, // 默认:true;false 会从系统提示中省略 Heartbeat 部分 - lightContext: false, // 默认:false;true 仅保留工作区 bootstrap 文件中的 HEARTBEAT.md + lightContext: false, // 默认:false;true 仅保留 workspace bootstrap 文件中的 HEARTBEAT.md isolatedSession: false, // 默认:false;true 会在全新会话中运行每次 heartbeat(无对话历史) session: "main", to: "+15555550123", directPolicy: "allow", // allow(默认)| block - target: "none", // 默认:none | 可选值:last | whatsapp | telegram | discord | ... + target: "none", // 默认:none | 可选:last | whatsapp | telegram | discord | ... prompt: "Read HEARTBEAT.md if it exists...", ackMaxChars: 300, suppressToolErrorWarnings: false, @@ -1388,13 +1397,13 @@ Anthropic Claude 4.6 模型在未设置显式 thinking 级别时,默认使用 ``` - `every`:时长字符串(ms/s/m/h)。默认值:`30m`(API key 认证)或 `1h`(OAuth 认证)。设为 `0m` 可禁用。 -- `includeSystemPromptSection`:设为 false 时,会从系统提示中省略 Heartbeat 部分,并跳过将 `HEARTBEAT.md` 注入 bootstrap 上下文。默认值:`true`。 -- `suppressToolErrorWarnings`:设为 true 时,会在 heartbeat 运行期间抑制工具错误警告负载。 -- `timeoutSeconds`:heartbeat 智能体轮次在被中止前允许的最大秒数。未设置时使用 `agents.defaults.timeoutSeconds`。 -- `directPolicy`:直接/私信交付策略。`allow`(默认)允许直接目标交付。`block` 会抑制直接目标交付,并发出 `reason=dm-blocked`。 -- `lightContext`:设为 true 时,heartbeat 运行使用轻量级 bootstrap 上下文,并且只保留工作区 bootstrap 文件中的 `HEARTBEAT.md`。 -- `isolatedSession`:设为 true 时,每次 heartbeat 都会在一个全新会话中运行,不带任何先前对话历史。与 cron `sessionTarget: "isolated"` 使用相同的隔离模式。可将每次 heartbeat 的 token 成本从约 100K 降低到约 2–5K。 -- 每智能体:设置 `agents.list[].heartbeat`。当任意智能体定义了 `heartbeat` 时,**只有这些智能体**会运行 heartbeat。 +- `includeSystemPromptSection`:为 false 时,会从系统提示中省略 Heartbeat 部分,并跳过将 `HEARTBEAT.md` 注入 bootstrap 上下文。默认值:`true`。 +- `suppressToolErrorWarnings`:为 true 时,会在 heartbeat 运行期间抑制工具错误警告负载。 +- `timeoutSeconds`:heartbeat 智能体轮次在被中止前允许的最长秒数。留空则使用 `agents.defaults.timeoutSeconds`。 +- `directPolicy`:直接/私信交付策略。`allow`(默认)允许直接目标交付。`block` 会抑制直接目标交付,并输出 `reason=dm-blocked`。 +- `lightContext`:为 true 时,heartbeat 运行会使用轻量 bootstrap 上下文,并且只保留 workspace bootstrap 文件中的 `HEARTBEAT.md`。 +- `isolatedSession`:为 true 时,每次 heartbeat 都会在一个没有任何先前对话历史的全新会话中运行。隔离模式与 cron `sessionTarget: "isolated"` 相同。可将每次 heartbeat 的 token 成本从约 100K 降到约 2-5K token。 +- 按智能体:设置 `agents.list[].heartbeat`。当任意智能体定义了 `heartbeat` 时,**只有这些智能体**会运行 heartbeat。 - Heartbeat 会运行完整的智能体轮次——更短的间隔会消耗更多 token。 ### `agents.defaults.compaction` @@ -1405,14 +1414,14 @@ Anthropic Claude 4.6 模型在未设置显式 thinking 级别时,默认使用 defaults: { compaction: { mode: "safeguard", // default | safeguard - provider: "my-provider", // 已注册 compaction 提供商插件的 id(可选) + provider: "my-provider", // 已注册 compaction provider plugin 的 id(可选) timeoutSeconds: 900, reserveTokensFloor: 24000, identifierPolicy: "strict", // strict | off | custom identifierInstructions: "Preserve deployment IDs, ticket IDs, and host:port pairs exactly.", // 当 identifierPolicy=custom 时使用 postCompactionSections: ["Session Startup", "Red Lines"], // [] 表示禁用重新注入 - model: "openrouter/anthropic/claude-sonnet-4-6", // 仅用于 compaction 的可选模型覆盖 - notifyUser: true, // compaction 开始和完成时发送简短通知(默认:false) + model: "openrouter/anthropic/claude-sonnet-4-6", // 可选,仅用于 compaction 的模型覆盖 + notifyUser: true, // 在 compaction 开始和完成时向用户发送简短通知(默认:false) memoryFlush: { enabled: true, softThresholdTokens: 6000, @@ -1425,19 +1434,19 @@ Anthropic Claude 4.6 模型在未设置显式 thinking 级别时,默认使用 } ``` -- `mode`:`default` 或 `safeguard`(针对长历史的分块摘要)。参见 [Compaction](/zh-CN/concepts/compaction)。 -- `provider`:已注册 compaction 提供商插件的 id。设置后,会调用该提供商的 `summarize()`,而不是使用内置 LLM 摘要。失败时回退到内置实现。设置提供商会强制使用 `mode: "safeguard"`。参见 [Compaction](/zh-CN/concepts/compaction)。 -- `timeoutSeconds`:OpenClaw 中止单次 compaction 操作前允许的最长秒数。默认值:`900`。 -- `identifierPolicy`:`strict`(默认)、`off` 或 `custom`。`strict` 会在 compaction 摘要时预置内建的 opaque 标识符保留指引。 +- `mode`:`default` 或 `safeguard`(对长历史进行分块摘要)。参见[Compaction](/zh-CN/concepts/compaction)。 +- `provider`:已注册 compaction provider plugin 的 id。设置后,会调用该提供商的 `summarize()`,而不是使用内置 LLM 摘要。失败时会回退到内置实现。设置提供商会强制使用 `mode: "safeguard"`。参见[Compaction](/zh-CN/concepts/compaction)。 +- `timeoutSeconds`:OpenClaw 在中止单次 compaction 操作前允许的最长秒数。默认值:`900`。 +- `identifierPolicy`:`strict`(默认)、`off` 或 `custom`。`strict` 会在 compaction 摘要时预置内置的不透明标识符保留指导。 - `identifierInstructions`:当 `identifierPolicy=custom` 时使用的可选自定义标识符保留文本。 -- `postCompactionSections`:compaction 后可选的 AGENTS.md H2/H3 章节名重新注入列表。默认值为 `["Session Startup", "Red Lines"]`;设为 `[]` 可禁用重新注入。未设置或显式设置为该默认对时,也会接受旧版 `Every Session`/`Safety` 标题作为兼容性回退。 -- `model`:仅用于 compaction 摘要的可选 `provider/model-id` 覆盖。当主会话需要保留一个模型,而 compaction 摘要应在另一个模型上运行时使用;未设置时,compaction 使用会话的主模型。 -- `notifyUser`:设为 `true` 时,会在 compaction 开始和完成时向用户发送简短通知(例如“Compacting context...” 和 “Compaction complete”)。默认禁用,以保持 compaction 静默。 -- `memoryFlush`:在自动 compaction 前执行一次静默的智能体轮次,以存储持久记忆。工作区为只读时会跳过。 +- `postCompactionSections`:compaction 后重新注入的可选 `AGENTS.md` H2/H3 章节名。默认值为 `["Session Startup", "Red Lines"]`;设为 `[]` 可禁用重新注入。当未设置,或显式设为这对默认值时,旧版 `Every Session`/`Safety` 标题也会作为兼容回退被接受。 +- `model`:可选的 `provider/model-id` 覆盖,仅用于 compaction 摘要。当主会话应继续使用某个模型,但 compaction 摘要应改用另一个模型时可使用;未设置时,compaction 使用会话的主模型。 +- `notifyUser`:为 `true` 时,会在 compaction 开始和完成时向用户发送简短通知(例如 “Compacting context...” 和 “Compaction complete”)。默认禁用,以保持 compaction 静默。 +- `memoryFlush`:在自动 compaction 之前执行一次静默的智能体轮次,以存储持久 memory。若 workspace 为只读则会跳过。 ### `agents.defaults.contextPruning` -在发送给 LLM 之前,从内存上下文中修剪**旧的工具结果**。**不会**修改磁盘上的会话历史。 +在将内容发送到 LLM 之前,从内存上下文中修剪**旧工具结果**。**不会**修改磁盘上的会话历史。 ```json5 { @@ -1461,23 +1470,23 @@ Anthropic Claude 4.6 模型在未设置显式 thinking 级别时,默认使用 -- `mode: "cache-ttl"` 会启用修剪过程。 -- `ttl` 控制在上次缓存触碰之后,过多久才能再次运行修剪。 -- 如有需要,修剪会先对过大的工具结果进行软截断,然后再对更旧的工具结果执行硬清除。 +- `mode: "cache-ttl"` 会启用修剪流程。 +- `ttl` 控制下一次允许再次运行修剪的时间(自上次缓存触达之后)。 +- 修剪会先对过大的工具结果执行软截断,然后在需要时对更旧的工具结果执行硬清除。 -**软截断**会保留开头 + 结尾,并在中间插入 `...`。 +**软截断**会保留开头和结尾,并在中间插入 `...`。 **硬清除**会用占位符替换整个工具结果。 注意: - 图像块永远不会被截断/清除。 -- 比例基于字符数(近似),不是精确 token 数。 -- 如果 assistant 消息少于 `keepLastAssistants` 条,则跳过修剪。 +- 比例基于字符数(近似),而不是精确 token 数。 +- 如果 assistant 消息少于 `keepLastAssistants` 条,则会跳过修剪。 -行为详情请参见 [会话修剪](/zh-CN/concepts/session-pruning)。 +行为细节请参见[会话修剪](/zh-CN/concepts/session-pruning)。 ### 分块流式传输 @@ -1496,10 +1505,10 @@ Anthropic Claude 4.6 模型在未设置显式 thinking 级别时,默认使用 ``` - 非 Telegram 渠道需要显式设置 `*.blockStreaming: true` 才会启用分块回复。 -- 渠道覆盖:`channels..blockStreamingCoalesce`(以及每账号变体)。Signal/Slack/Discord/Google Chat 默认 `minChars: 1500`。 -- `humanDelay`:分块回复之间的随机暂停。`natural` = 800–2500 ms。每智能体覆盖:`agents.list[].humanDelay`。 +- 渠道覆盖:`channels..blockStreamingCoalesce`(以及按账号变体)。Signal/Slack/Discord/Google Chat 默认 `minChars: 1500`。 +- `humanDelay`:分块回复之间的随机暂停。`natural` = 800–2500ms。按智能体覆盖:`agents.list[].humanDelay`。 -行为和分块细节请参见 [流式传输](/zh-CN/concepts/streaming)。 +行为和分块细节请参见[流式传输](/zh-CN/concepts/streaming)。 ### 输入中指示器 @@ -1514,16 +1523,16 @@ Anthropic Claude 4.6 模型在未设置显式 thinking 级别时,默认使用 } ``` -- 默认值:私聊/被提及时使用 `instant`,未被提及的群聊使用 `message`。 -- 每会话覆盖:`session.typingMode`、`session.typingIntervalSeconds`。 +- 默认值:私聊/提及使用 `instant`,未被提及的群聊使用 `message`。 +- 按会话覆盖:`session.typingMode`、`session.typingIntervalSeconds`。 -参见 [输入中指示器](/zh-CN/concepts/typing-indicators)。 +参见[输入中指示器](/zh-CN/concepts/typing-indicators)。 ### `agents.defaults.sandbox` -嵌入式智能体的可选沙箱隔离配置。完整指南请参见 [沙箱隔离](/zh-CN/gateway/sandboxing)。 +嵌入式智能体的可选沙箱隔离。完整指南请参见[沙箱隔离](/zh-CN/gateway/sandboxing)。 ```json5 { @@ -1626,46 +1635,46 @@ Anthropic Claude 4.6 模型在未设置显式 thinking 级别时,默认使用 - `ssh`:通用的 SSH 支持远程运行时 - `openshell`:OpenShell 运行时 -当选择 `backend: "openshell"` 时,运行时特定设置会移动到 +当选择 `backend: "openshell"` 时,运行时特定设置会移到 `plugins.entries.openshell.config`。 **SSH 后端配置:** - `target`:`user@host[:port]` 形式的 SSH 目标 - `command`:SSH 客户端命令(默认:`ssh`) -- `workspaceRoot`:用于每作用域工作区的远程绝对根路径 +- `workspaceRoot`:用于按作用域 workspace 的远程绝对根路径 - `identityFile` / `certificateFile` / `knownHostsFile`:传递给 OpenSSH 的现有本地文件 -- `identityData` / `certificateData` / `knownHostsData`:OpenClaw 会在运行时将其物化为临时文件的内联内容或 SecretRef -- `strictHostKeyChecking` / `updateHostKeys`:OpenSSH 主机密钥策略旋钮 +- `identityData` / `certificateData` / `knownHostsData`:内联内容或 SecretRef,OpenClaw 会在运行时将其物化为临时文件 +- `strictHostKeyChecking` / `updateHostKeys`:OpenSSH 主机密钥策略开关 **SSH 认证优先级:** - `identityData` 优先于 `identityFile` - `certificateData` 优先于 `certificateFile` - `knownHostsData` 优先于 `knownHostsFile` -- 基于 SecretRef 的 `*Data` 值会在沙箱会话启动前,从活动 secrets 运行时快照中解析 +- 由 SecretRef 支持的 `*Data` 值会在沙箱会话开始前,从活动 secrets 运行时快照中解析 **SSH 后端行为:** -- 在创建或重建后对远程工作区进行一次初始化填充 -- 之后保持远程 SSH 工作区为规范状态 +- 在 create 或 recreate 后对远程 workspace 执行一次初始化 +- 然后保持远程 SSH workspace 为规范版本 - 通过 SSH 路由 `exec`、文件工具和媒体路径 - 不会自动将远程更改同步回主机 - 不支持沙箱浏览器容器 -**工作区访问:** +**Workspace 访问:** -- `none`:每作用域的沙箱工作区位于 `~/.openclaw/sandboxes` 下 -- `ro`:沙箱工作区位于 `/workspace`,智能体工作区以只读方式挂载到 `/agent` -- `rw`:智能体工作区以读写方式挂载到 `/workspace` +- `none`:按作用域在 `~/.openclaw/sandboxes` 下创建沙箱 workspace +- `ro`:沙箱 workspace 位于 `/workspace`,智能体 workspace 以只读方式挂载到 `/agent` +- `rw`:智能体 workspace 以读写方式挂载到 `/workspace` **作用域:** -- `session`:每会话一个容器 + 工作区 -- `agent`:每个智能体一个容器 + 工作区(默认) -- `shared`:共享容器和工作区(无跨会话隔离) +- `session`:按会话划分的容器 + workspace +- `agent`:每个智能体一个容器 + workspace(默认) +- `shared`:共享容器和 workspace(无跨会话隔离) -**OpenShell 插件配置:** +**OpenShell plugin 配置:** ```json5 { @@ -1680,7 +1689,7 @@ Anthropic Claude 4.6 模型在未设置显式 thinking 级别时,默认使用 remoteAgentWorkspaceDir: "/agent", gateway: "lab", // 可选 gatewayEndpoint: "https://lab.example", // 可选 - policy: "strict", // 可选的 OpenShell policy id + policy: "strict", // 可选 OpenShell policy id providers: ["openai"], // 可选 autoProviders: true, timeoutSeconds: 120, @@ -1693,29 +1702,29 @@ Anthropic Claude 4.6 模型在未设置显式 thinking 级别时,默认使用 **OpenShell 模式:** -- `mirror`:在执行前从本地为远程播种,执行后再同步回来;本地工作区保持为规范状态 -- `remote`:在创建沙箱时仅为远程播种一次,之后保持远程工作区为规范状态 +- `mirror`:在 exec 前从本地播种到远程,在 exec 后同步回本地;本地 workspace 保持为规范版本 +- `remote`:在创建沙箱时只向远程播种一次,然后保持远程 workspace 为规范版本 -在 `remote` 模式下,播种步骤之后,在 OpenClaw 外部进行的主机本地编辑不会自动同步到沙箱中。 -传输方式是通过 SSH 进入 OpenShell 沙箱,但沙箱生命周期以及可选的镜像同步由插件负责。 +在 `remote` 模式下,播种步骤之后,在 OpenClaw 外部对主机本地所做的编辑不会自动同步到沙箱中。 +传输方式是通过 SSH 进入 OpenShell 沙箱,但 sandbox 生命周期和可选的镜像同步由 plugin 负责。 **`setupCommand`** 会在容器创建后运行一次(通过 `sh -lc`)。需要网络出口、可写根文件系统以及 root 用户。 -**容器默认使用 `network: "none"`** —— 如果智能体需要出站访问,请设置为 `"bridge"`(或自定义桥接网络)。 +**容器默认使用 `network: "none"`** —— 如果智能体需要出站访问,请将其设置为 `"bridge"`(或自定义 bridge 网络)。 `"host"` 会被阻止。默认情况下,`"container:"` 也会被阻止,除非你显式设置 -`sandbox.docker.dangerouslyAllowContainerNamespaceJoin: true`(紧急兜底模式)。 +`sandbox.docker.dangerouslyAllowContainerNamespaceJoin: true`(紧急破玻璃)。 -**入站附件** 会被暂存到活动工作区中的 `media/inbound/*`。 +**传入附件** 会被暂存到活动 workspace 中的 `media/inbound/*`。 -**`docker.binds`** 会挂载额外的主机目录;全局和每智能体的 binds 会合并。 +**`docker.binds`** 会挂载额外的主机目录;全局和按智能体的 binds 会被合并。 -**沙箱隔离浏览器**(`sandbox.browser.enabled`):运行在容器中的 Chromium + CDP。noVNC URL 会注入到系统提示中。不需要在 `openclaw.json` 中启用 `browser.enabled`。 -noVNC 观察者访问默认使用 VNC 认证,OpenClaw 会发出一个短时有效的 token URL(而不是在共享 URL 中暴露密码)。 +**沙箱隔离浏览器**(`sandbox.browser.enabled`):在容器中运行 Chromium + CDP。noVNC URL 会注入系统提示。它不要求在 `openclaw.json` 中启用 `browser.enabled`。 +默认情况下,noVNC 观察者访问使用 VNC 认证,OpenClaw 会发出一个短期有效的 token URL(而不是在共享 URL 中暴露密码)。 -- `allowHostControl: false`(默认)会阻止沙箱隔离会话将主机浏览器作为目标。 -- `network` 默认值为 `openclaw-sandbox-browser`(专用桥接网络)。只有在你明确希望使用全局桥接连接时,才设置为 `bridge`。 -- `cdpSourceRange` 可选地将容器边缘的 CDP 入站限制到某个 CIDR 范围(例如 `172.21.0.1/32`)。 -- `sandbox.browser.binds` 仅会将额外的主机目录挂载到沙箱浏览器容器中。设置后(包括 `[]`),它会为浏览器容器替换 `docker.binds`。 +- `allowHostControl: false`(默认)会阻止沙箱隔离会话以主机浏览器为目标。 +- `network` 默认为 `openclaw-sandbox-browser`(专用 bridge 网络)。只有在你明确希望获得全局 bridge 连通性时,才设置为 `bridge`。 +- `cdpSourceRange` 可选,用于在容器边界将 CDP 入口限制到某个 CIDR 范围(例如 `172.21.0.1/32`)。 +- `sandbox.browser.binds` 只会将额外的主机目录挂载到沙箱浏览器容器中。设置后(包括 `[]`),它会替换浏览器容器的 `docker.binds`。 - 启动默认值定义在 `scripts/sandbox-browser-entrypoint.sh` 中,并针对容器主机进行了调优: - `--remote-debugging-address=127.0.0.1` - `--remote-debugging-port=` @@ -1734,16 +1743,16 @@ noVNC 观察者访问默认使用 VNC 认证,OpenClaw 会发出一个短时有 - `--no-zygote` - `--metrics-recording-only` - `--disable-extensions`(默认启用) - - `--disable-3d-apis`、`--disable-software-rasterizer` 和 `--disable-gpu` 默认 - 启用;如果 WebGL/3D 使用场景需要它们,可通过 - `OPENCLAW_BROWSER_DISABLE_GRAPHICS_FLAGS=0` 禁用这些默认标志。 - - 如果你的工作流依赖扩展,可通过 - `OPENCLAW_BROWSER_DISABLE_EXTENSIONS=0` 重新启用扩展。 + - `--disable-3d-apis`、`--disable-software-rasterizer` 和 `--disable-gpu` + 默认启用;如果你的 WebGL/3D 使用场景需要它们,可通过 + `OPENCLAW_BROWSER_DISABLE_GRAPHICS_FLAGS=0` 禁用这些默认项。 + - `OPENCLAW_BROWSER_DISABLE_EXTENSIONS=0` 可重新启用扩展,如果你的工作流 + 依赖这些扩展。 - `--renderer-process-limit=2` 可通过 - `OPENCLAW_BROWSER_RENDERER_PROCESS_LIMIT=` 修改;设置为 `0` 则使用 Chromium 的 + `OPENCLAW_BROWSER_RENDERER_PROCESS_LIMIT=` 修改;设为 `0` 将使用 Chromium 的 默认进程上限。 - - 此外,在启用 `noSandbox` 时还会加上 `--no-sandbox` 和 `--disable-setuid-sandbox`。 - - 这些默认值是容器镜像的基线;若要更改容器默认值,请使用带自定义 + - 此外,当启用 `noSandbox` 时,还会加上 `--no-sandbox` 和 `--disable-setuid-sandbox`。 + - 这些默认值属于容器镜像基线;如需更改容器默认值,请使用带有自定义 entrypoint 的自定义浏览器镜像。 @@ -1757,7 +1766,7 @@ scripts/sandbox-setup.sh # 主沙箱镜像 scripts/sandbox-browser-setup.sh # 可选浏览器镜像 ``` -### `agents.list`(每智能体覆盖) +### `agents.list`(按智能体覆盖) ```json5 { @@ -1770,12 +1779,12 @@ scripts/sandbox-browser-setup.sh # 可选浏览器镜像 workspace: "~/.openclaw/workspace", agentDir: "~/.openclaw/agents/main/agent", model: "anthropic/claude-opus-4-6", // 或 { primary, fallbacks } - thinkingDefault: "high", // 每智能体 thinking 级别覆盖 - reasoningDefault: "on", // 每智能体 reasoning 可见性覆盖 - fastModeDefault: false, // 每智能体 fast mode 覆盖 + thinkingDefault: "high", // 按智能体的 thinking 级别覆盖 + reasoningDefault: "on", // 按智能体的 reasoning 可见性覆盖 + fastModeDefault: false, // 按智能体的 fast mode 覆盖 embeddedHarness: { runtime: "auto", fallback: "pi" }, - params: { cacheRetention: "none" }, // 按键覆盖匹配 defaults.models params - skills: ["docs-search"], // 设置后替换 agents.defaults.skills + params: { cacheRetention: "none" }, // 按键覆盖匹配的 defaults.models params + skills: ["docs-search"], // 设置后会替换 agents.defaults.skills identity: { name: "Samantha", theme: "helpful sloth", @@ -1807,26 +1816,26 @@ scripts/sandbox-browser-setup.sh # 可选浏览器镜像 ``` - `id`:稳定的智能体 id(必填)。 -- `default`:若设置了多个,则第一个生效(会记录警告)。若一个都未设置,则列表第一项为默认值。 -- `model`:字符串形式仅覆盖 `primary`;对象形式 `{ primary, fallbacks }` 同时覆盖两者(`[]` 会禁用全局后备模型)。仅覆盖 `primary` 的 cron 作业仍会继承默认后备模型,除非你设置 `fallbacks: []`。 -- `params`:按智能体合并到 `agents.defaults.models` 中所选模型条目之上的流式参数。用于针对特定智能体覆盖 `cacheRetention`、`temperature` 或 `maxTokens` 等,而无需复制整个模型目录。 -- `skills`:可选的每智能体 Skills allowlist。若省略,则在已设置时继承 `agents.defaults.skills`;显式列表会替换默认值而不是合并,`[]` 表示无 Skills。 -- `thinkingDefault`:可选的每智能体默认 thinking 级别(`off | minimal | low | medium | high | xhigh | adaptive | max`)。当未设置每消息或会话覆盖时,会覆盖该智能体的 `agents.defaults.thinkingDefault`。 -- `reasoningDefault`:可选的每智能体默认 reasoning 可见性(`on | off | stream`)。当未设置每消息或会话 reasoning 覆盖时生效。 -- `fastModeDefault`:可选的每智能体默认 fast mode(`true | false`)。当未设置每消息或会话 fast-mode 覆盖时生效。 -- `embeddedHarness`:可选的每智能体低层 harness 策略覆盖。使用 `{ runtime: "codex", fallback: "none" }` 可让某个智能体仅使用 Codex,而其他智能体保留默认的 PI 回退。 -- `runtime`:可选的每智能体运行时描述符。当智能体应默认使用 ACP harness 会话时,可使用 `type: "acp"` 并设置 `runtime.acp` 默认值(`agent`、`backend`、`mode`、`cwd`)。 -- `identity.avatar`:工作区相对路径、`http(s)` URL 或 `data:` URI。 +- `default`:当设置了多个时,第一个生效(会记录警告)。如果一个都没设置,则列表中的第一个条目为默认值。 +- `model`:字符串形式只覆盖 `primary`;对象形式 `{ primary, fallbacks }` 会同时覆盖两者(`[]` 会禁用全局回退)。只覆盖 `primary` 的 cron 任务仍会继承默认回退,除非你设置 `fallbacks: []`。 +- `params`:按智能体的流参数,会合并到 `agents.defaults.models` 中选定的模型条目之上。可用于设置智能体特定的覆盖项,例如 `cacheRetention`、`temperature` 或 `maxTokens`,而无需复制整个模型目录。 +- `skills`:可选的按智能体 Skills allowlist。若省略,当 `agents.defaults.skills` 已设置时,智能体会继承它;显式列表会替换默认值而不是合并,`[]` 表示无 Skills。 +- `thinkingDefault`:可选的按智能体默认 thinking 级别(`off | minimal | low | medium | high | xhigh | adaptive | max`)。当未设置按消息或按会话的覆盖时,它会覆盖该智能体的 `agents.defaults.thinkingDefault`。 +- `reasoningDefault`:可选的按智能体默认 reasoning 可见性(`on | off | stream`)。在未设置按消息或按会话的 reasoning 覆盖时生效。 +- `fastModeDefault`:可选的按智能体 fast mode 默认值(`true | false`)。在未设置按消息或按会话的 fast mode 覆盖时生效。 +- `embeddedHarness`:可选的按智能体底层 harness 策略覆盖。使用 `{ runtime: "codex", fallback: "none" }` 可让某一个智能体仅使用 Codex,而其他智能体仍保留默认的 PI 回退。 +- `runtime`:可选的按智能体运行时描述符。当该智能体应默认使用 ACP harness 会话时,请使用带有 `runtime.acp` 默认值(`agent`、`backend`、`mode`、`cwd`)的 `type: "acp"`。 +- `identity.avatar`:相对于 workspace 的路径、`http(s)` URL,或 `data:` URI。 - `identity` 会派生默认值:`ackReaction` 来自 `emoji`,`mentionPatterns` 来自 `name`/`emoji`。 -- `subagents.allowAgents`:`sessions_spawn` 的智能体 id allowlist(`["*"]` = 任意;默认:仅同一智能体)。 -- 沙箱继承保护:如果请求方会话已处于沙箱隔离中,`sessions_spawn` 会拒绝那些会以非沙箱方式运行的目标。 -- `subagents.requireAgentId`:设为 true 时,阻止省略 `agentId` 的 `sessions_spawn` 调用(强制显式选择配置文件;默认:false)。 +- `subagents.allowAgents`:用于 `sessions_spawn` 的智能体 id allowlist(`["*"]` = 任意;默认:仅同一智能体)。 +- 沙箱继承保护:如果请求方会话处于沙箱隔离中,`sessions_spawn` 会拒绝那些会以非沙箱方式运行的目标。 +- `subagents.requireAgentId`:为 true 时,阻止省略 `agentId` 的 `sessions_spawn` 调用(强制显式选择配置文件;默认:false)。 --- ## 多智能体路由 -在一个 Gateway 网关内运行多个隔离的智能体。参见 [多智能体](/zh-CN/concepts/multi-agent)。 +在一个 Gateway 网关中运行多个彼此隔离的智能体。参见[多智能体](/zh-CN/concepts/multi-agent)。 ```json5 { @@ -1845,14 +1854,14 @@ scripts/sandbox-browser-setup.sh # 可选浏览器镜像 ### 绑定匹配字段 -- `type`(可选):普通路由使用 `route`(缺失时默认是 route),持久化 ACP 会话绑定使用 `acp` +- `type`(可选):普通路由用 `route`(缺失时默认为 route),持久 ACP 对话绑定用 `acp`。 - `match.channel`(必填) - `match.accountId`(可选;`*` = 任意账号;省略 = 默认账号) - `match.peer`(可选;`{ kind: direct|group|channel, id }`) - `match.guildId` / `match.teamId`(可选;渠道特定) -- `acp`(可选;仅用于 `type: "acp"`):`{ mode, label, cwd, backend }` +- `acp`(可选;仅限 `type: "acp"`):`{ mode, label, cwd, backend }` -**确定性匹配顺序:** +**确定性的匹配顺序:** 1. `match.peer` 2. `match.guildId` @@ -1861,11 +1870,11 @@ scripts/sandbox-browser-setup.sh # 可选浏览器镜像 5. `match.accountId: "*"`(渠道范围) 6. 默认智能体 -在每一层内,第一个匹配的 `bindings` 条目生效。 +在每一层级内,第一个匹配的 `bindings` 条目胜出。 -对于 `type: "acp"` 条目,OpenClaw 会按精确会话身份(`match.channel` + 账号 + `match.peer.id`)解析,不使用上述 route 绑定分层顺序。 +对于 `type: "acp"` 条目,OpenClaw 会按精确对话身份(`match.channel` + 账号 + `match.peer.id`)解析,不使用上述 route 绑定层级顺序。 -### 每智能体访问配置 +### 按智能体访问配置文件 @@ -1885,7 +1894,7 @@ scripts/sandbox-browser-setup.sh # 可选浏览器镜像 - + ```json5 { @@ -1960,7 +1969,7 @@ scripts/sandbox-browser-setup.sh # 可选浏览器镜像 -优先级细节请参见 [多智能体沙箱隔离与工具](/zh-CN/tools/multi-agent-sandbox-tools)。 +优先级细节请参见[多智能体沙箱隔离与工具](/zh-CN/tools/multi-agent-sandbox-tools)。 --- @@ -1986,20 +1995,20 @@ scripts/sandbox-browser-setup.sh # 可选浏览器镜像 }, resetTriggers: ["/new", "/reset"], store: "~/.openclaw/agents/{agentId}/sessions/sessions.json", - parentForkMaxTokens: 100000, // 当超过此 token 数时跳过父线程分叉(0 表示禁用) + parentForkMaxTokens: 100000, // 父线程 token 数高于此值时跳过父线程分叉(0 表示禁用) maintenance: { mode: "warn", // warn | enforce pruneAfter: "30d", maxEntries: 500, rotateBytes: "10mb", resetArchiveRetention: "30d", // 时长或 false - maxDiskBytes: "500mb", // 可选的硬性预算 - highWaterBytes: "400mb", // 可选的清理目标 + maxDiskBytes: "500mb", // 可选硬预算 + highWaterBytes: "400mb", // 可选清理目标 }, threadBindings: { enabled: true, - idleHours: 24, // 默认按小时计的无活动自动取消聚焦(`0` 表示禁用) - maxAgeHours: 0, // 默认按小时计的硬性最大时长(`0` 表示禁用) + idleHours: 24, // 默认按小时计算的不活动自动取消聚焦(`0` 表示禁用) + maxAgeHours: 0, // 默认按小时计算的硬性最大存续时间(`0` 表示禁用) }, mainKey: "main", // 旧版字段(运行时始终使用 "main") agentToAgent: { maxPingPongTurns: 5 }, @@ -2014,34 +2023,34 @@ scripts/sandbox-browser-setup.sh # 可选浏览器镜像 - **`scope`**:群聊上下文的基础会话分组策略。 - - `per-sender`(默认):在一个渠道上下文内,每个发送者都有独立会话。 - - `global`:一个渠道上下文中的所有参与者共享同一个会话(仅在确实需要共享上下文时使用)。 + - `per-sender`(默认):在渠道上下文内,每个发送者都获得独立会话。 + - `global`:渠道上下文中的所有参与者共享一个会话(仅在明确需要共享上下文时使用)。 - **`dmScope`**:私信的分组方式。 - `main`:所有私信共享主会话。 - - `per-peer`:按发送者 id 跨渠道隔离。 + - `per-peer`:按跨渠道的发送者 ID 隔离。 - `per-channel-peer`:按渠道 + 发送者隔离(推荐用于多用户收件箱)。 - `per-account-channel-peer`:按账号 + 渠道 + 发送者隔离(推荐用于多账号)。 -- **`identityLinks`**:将规范 id 映射到带提供商前缀的对端,用于跨渠道共享会话。 -- **`reset`**:主重置策略。`daily` 会在本地时间 `atHour` 重置;`idle` 会在 `idleMinutes` 后重置。两者都配置时,以先到期者为准。 +- **`identityLinks`**:将规范 ID 映射到带提供商前缀的对端,以实现跨渠道会话共享。 +- **`reset`**:主重置策略。`daily` 会在本地时间的 `atHour` 重置;`idle` 会在 `idleMinutes` 后重置。当两者都已配置时,哪个先到期就以哪个为准。 - **`resetByType`**:按类型覆盖(`direct`、`group`、`thread`)。旧版 `dm` 可作为 `direct` 的别名。 -- **`parentForkMaxTokens`**:创建分叉线程会话时允许的父会话最大 `totalTokens`(默认 `100000`)。 - - 如果父会话的 `totalTokens` 高于该值,OpenClaw 会启动一个全新的线程会话,而不是继承父级转录历史。 - - 设为 `0` 可禁用此保护,并始终允许父级分叉。 +- **`parentForkMaxTokens`**:创建分叉线程会话时允许的父会话 `totalTokens` 最大值(默认 `100000`)。 + - 如果父会话 `totalTokens` 高于此值,OpenClaw 会启动一个新的线程会话,而不是继承父会话对话历史。 + - 设为 `0` 可禁用此保护,并始终允许父会话分叉。 - **`mainKey`**:旧版字段。运行时始终对主私聊桶使用 `"main"`。 -- **`agentToAgent.maxPingPongTurns`**:智能体之间相互通信时允许的最大往返回复轮次(整数,范围:`0`–`5`)。`0` 会禁用乒乓式链路。 -- **`sendPolicy`**:按 `channel`、`chatType`(`direct|group|channel`,旧版 `dm` 为别名)、`keyPrefix` 或 `rawKeyPrefix` 匹配。第一个 deny 生效。 +- **`agentToAgent.maxPingPongTurns`**:智能体之间在智能体对智能体交换期间允许的最大来回回复轮次(整数,范围:`0`–`5`)。`0` 会禁用 ping-pong 链式往返。 +- **`sendPolicy`**:按 `channel`、`chatType`(`direct|group|channel`,旧版 `dm` 为别名)、`keyPrefix` 或 `rawKeyPrefix` 匹配。第一个 deny 优先生效。 - **`maintenance`**:会话存储清理 + 保留控制。 - - `mode`:`warn` 仅发出警告;`enforce` 会执行清理。 - - `pruneAfter`:陈旧条目的时间截止(默认 `30d`)。 - - `maxEntries`:`sessions.json` 中的最大条目数(默认 `500`)。 - - `rotateBytes`:当 `sessions.json` 超过该大小时进行轮转(默认 `10mb`)。 - - `resetArchiveRetention`:`*.reset.` 转录归档的保留时长。默认继承 `pruneAfter`;设为 `false` 可禁用。 - - `maxDiskBytes`:可选的 sessions 目录磁盘预算。在 `warn` 模式下会记录警告;在 `enforce` 模式下会优先删除最旧的制品/会话。 - - `highWaterBytes`:预算清理后的可选目标值。默认是 `maxDiskBytes` 的 `80%`。 + - `mode`:`warn` 仅发出警告;`enforce` 会实际执行清理。 + - `pruneAfter`:陈旧条目的年龄截止值(默认 `30d`)。 + - `maxEntries`:`sessions.json` 中允许的最大条目数(默认 `500`)。 + - `rotateBytes`:当 `sessions.json` 超过此大小时进行轮转(默认 `10mb`)。 + - `resetArchiveRetention`:`*.reset.` 转录归档的保留时长。默认为 `pruneAfter`;设为 `false` 可禁用。 + - `maxDiskBytes`:可选的 sessions 目录磁盘预算。在 `warn` 模式下会记录警告;在 `enforce` 模式下会优先删除最旧的工件/会话。 + - `highWaterBytes`:预算清理后的可选目标值。默认为 `maxDiskBytes` 的 `80%`。 - **`threadBindings`**:线程绑定会话功能的全局默认值。 - `enabled`:主默认开关(提供商可覆盖;Discord 使用 `channels.discord.threadBindings.enabled`) - - `idleHours`:默认按小时计的无活动自动取消聚焦(`0` 表示禁用;提供商可覆盖) - - `maxAgeHours`:默认按小时计的硬性最大时长(`0` 表示禁用;提供商可覆盖) + - `idleHours`:默认按小时计算的不活动自动取消聚焦时间(`0` 表示禁用;提供商可覆盖) + - `maxAgeHours`:默认按小时计算的硬性最大存续时间(`0` 表示禁用;提供商可覆盖) @@ -2077,40 +2086,40 @@ scripts/sandbox-browser-setup.sh # 可选浏览器镜像 } ``` -### 回复前缀 +### 响应前缀 -每渠道/账号覆盖:`channels..responsePrefix`、`channels..accounts..responsePrefix`。 +按渠道/账号覆盖:`channels..responsePrefix`、`channels..accounts..responsePrefix`。 -解析顺序(越具体越优先):账号 → 渠道 → 全局。`""` 会禁用并停止级联。`"auto"` 会派生为 `[{identity.name}]`。 +解析顺序(越具体越优先):账号 → 渠道 → 全局。`""` 会禁用并停止级联。`"auto"` 会派生 `[{identity.name}]`。 **模板变量:** -| 变量 | 说明 | 示例 | -| ----------------- | ---------------- | --------------------------- | -| `{model}` | 短模型名 | `claude-opus-4-6` | -| `{modelFull}` | 完整模型标识符 | `anthropic/claude-opus-4-6` | -| `{provider}` | 提供商名称 | `anthropic` | -| `{thinkingLevel}` | 当前 thinking 级别 | `high`、`low`、`off` | -| `{identity.name}` | 智能体身份名称 | (与 `"auto"` 相同) | +| 变量 | 说明 | 示例 | +| ----------------- | -------------------- | --------------------------- | +| `{model}` | 简短模型名称 | `claude-opus-4-6` | +| `{modelFull}` | 完整模型标识符 | `anthropic/claude-opus-4-6` | +| `{provider}` | 提供商名称 | `anthropic` | +| `{thinkingLevel}` | 当前 thinking 级别 | `high`、`low`、`off` | +| `{identity.name}` | 智能体身份名称 | (与 `"auto"` 相同) | 变量不区分大小写。`{think}` 是 `{thinkingLevel}` 的别名。 ### 确认 reaction - 默认使用活动智能体的 `identity.emoji`,否则为 `"👀"`。设为 `""` 可禁用。 -- 每渠道覆盖:`channels..ackReaction`、`channels..accounts..ackReaction`。 +- 按渠道覆盖:`channels..ackReaction`、`channels..accounts..ackReaction`。 - 解析顺序:账号 → 渠道 → `messages.ackReaction` → identity 回退。 -- 范围:`group-mentions`(默认)、`group-all`、`direct`、`all`。 -- `removeAckAfterReply`:在 Slack、Discord 和 Telegram 上,回复后移除确认 reaction。 -- `messages.statusReactions.enabled`:在 Slack、Discord 和 Telegram 上启用生命周期状态 reactions。 - 在 Slack 和 Discord 上,未设置时如果确认 reactions 处于活动状态,则会保持状态 reactions 启用。 - 在 Telegram 上,需要显式设为 `true` 才会启用生命周期状态 reactions。 +- 作用范围:`group-mentions`(默认)、`group-all`、`direct`、`all`。 +- `removeAckAfterReply`:在 Slack、Discord 和 Telegram 上回复后移除确认。 +- `messages.statusReactions.enabled`:在 Slack、Discord 和 Telegram 上启用生命周期状态 reaction。 + 在 Slack 和 Discord 上,未设置时,如果确认 reaction 处于启用状态,则状态 reaction 保持启用。 + 在 Telegram 上,需要显式设为 `true` 才会启用生命周期状态 reaction。 -### 入站去抖 +### 传入防抖 -将同一发送者快速发送的纯文本消息合并为一次智能体轮次。媒体/附件会立即触发刷新。控制命令会绕过去抖。 +将同一发送者的快速纯文本消息合并为单个智能体轮次。媒体/附件会立即触发刷新。控制命令会绕过防抖。 -### TTS(text-to-speech) +### TTS(文本转语音) ```json5 { @@ -2151,9 +2160,9 @@ scripts/sandbox-browser-setup.sh # 可选浏览器镜像 } ``` -- `auto` 控制默认自动 TTS 模式:`off`、`always`、`inbound` 或 `tagged`。`/tts on|off` 可覆盖本地偏好,而 `/tts status` 会显示生效状态。 -- `summaryModel` 会覆盖自动摘要使用的 `agents.defaults.model.primary`。 -- `modelOverrides` 默认启用;`modelOverrides.allowProvider` 默认为 `false`(需显式选择加入)。 +- `auto` 控制默认的自动 TTS 模式:`off`、`always`、`inbound` 或 `tagged`。`/tts on|off` 可覆盖本地偏好,`/tts status` 会显示生效状态。 +- `summaryModel` 会覆盖自动摘要所使用的 `agents.defaults.model.primary`。 +- `modelOverrides` 默认启用;`modelOverrides.allowProvider` 默认为 `false`(需显式启用)。 - API key 会回退到 `ELEVENLABS_API_KEY`/`XI_API_KEY` 和 `OPENAI_API_KEY`。 - `openai.baseUrl` 会覆盖 OpenAI TTS 端点。解析顺序为配置,然后是 `OPENAI_TTS_BASE_URL`,最后是 `https://api.openai.com/v1`。 - 当 `openai.baseUrl` 指向非 OpenAI 端点时,OpenClaw 会将其视为兼容 OpenAI 的 TTS 服务器,并放宽模型/语音校验。 @@ -2187,12 +2196,12 @@ Talk 模式(macOS/iOS/Android)的默认值。 ``` - 当配置了多个 Talk 提供商时,`talk.provider` 必须匹配 `talk.providers` 中的某个键。 -- 旧版扁平 Talk 键(`talk.voiceId`、`talk.voiceAliases`、`talk.modelId`、`talk.outputFormat`、`talk.apiKey`)仅用于兼容,并会自动迁移到 `talk.providers.`。 +- 旧版扁平 Talk 键(`talk.voiceId`、`talk.voiceAliases`、`talk.modelId`、`talk.outputFormat`、`talk.apiKey`)仅用于兼容,会自动迁移到 `talk.providers.`。 - Voice ID 会回退到 `ELEVENLABS_VOICE_ID` 或 `SAG_VOICE_ID`。 - `providers.*.apiKey` 接受明文字符串或 SecretRef 对象。 -- 仅当未配置 Talk API key 时,才会应用 `ELEVENLABS_API_KEY` 回退。 +- 只有在未配置任何 Talk API key 时,才会应用 `ELEVENLABS_API_KEY` 回退。 - `providers.*.voiceAliases` 允许 Talk 指令使用友好名称。 -- `silenceTimeoutMs` 控制 Talk 模式在用户静音后等待多久才发送转录。未设置时保留平台默认暂停窗口(`macOS 和 Android 为 700 ms,iOS 为 900 ms`)。 +- `silenceTimeoutMs` 控制 Talk 模式在用户静音后等待多久才发送转录文本。未设置时会保留平台默认暂停窗口(`macOS 和 Android 为 700 ms,iOS 为 900 ms`)。 --- @@ -2202,35 +2211,35 @@ Talk 模式(macOS/iOS/Android)的默认值。 `tools.profile` 会在 `tools.allow`/`tools.deny` 之前设置一个基础 allowlist: -本地新手引导默认会在未设置时为新的本地配置设定 `tools.profile: "coding"`(现有显式配置文件会保留)。 +本地新手引导会在未设置时将新的本地配置默认设为 `tools.profile: "coding"`(现有显式配置文件会被保留)。 | 配置文件 | 包含内容 | | ----------- | ------------------------------------------------------------------------------------------------------------------------------- | | `minimal` | 仅 `session_status` | | `coding` | `group:fs`、`group:runtime`、`group:web`、`group:sessions`、`group:memory`、`cron`、`image`、`image_generate`、`video_generate` | | `messaging` | `group:messaging`、`sessions_list`、`sessions_history`、`sessions_send`、`session_status` | -| `full` | 不受限制(与未设置相同) | +| `full` | 无限制(与未设置相同) | ### 工具组 -| 组 | 工具 | -| ------------------- | ----------------------------------------------------------------------------------------------------------------------- | -| `group:runtime` | `exec`、`process`、`code_execution`(`bash` 可作为 `exec` 的别名) | -| `group:fs` | `read`、`write`、`edit`、`apply_patch` | -| `group:sessions` | `sessions_list`、`sessions_history`、`sessions_send`、`sessions_spawn`、`sessions_yield`、`subagents`、`session_status` | -| `group:memory` | `memory_search`、`memory_get` | -| `group:web` | `web_search`、`x_search`、`web_fetch` | -| `group:ui` | `browser`、`canvas` | -| `group:automation` | `cron`、`gateway` | -| `group:messaging` | `message` | -| `group:nodes` | `nodes` | -| `group:agents` | `agents_list` | -| `group:media` | `image`、`image_generate`、`video_generate`、`tts` | -| `group:openclaw` | 所有内置工具(不含 provider 插件) | +| 分组 | 工具 | +| ------------------ | ----------------------------------------------------------------------------------------------------------------------- | +| `group:runtime` | `exec`、`process`、`code_execution`(`bash` 可作为 `exec` 的别名) | +| `group:fs` | `read`、`write`、`edit`、`apply_patch` | +| `group:sessions` | `sessions_list`、`sessions_history`、`sessions_send`、`sessions_spawn`、`sessions_yield`、`subagents`、`session_status` | +| `group:memory` | `memory_search`、`memory_get` | +| `group:web` | `web_search`、`x_search`、`web_fetch` | +| `group:ui` | `browser`、`canvas` | +| `group:automation` | `cron`、`gateway` | +| `group:messaging` | `message` | +| `group:nodes` | `nodes` | +| `group:agents` | `agents_list` | +| `group:media` | `image`、`image_generate`、`video_generate`、`tts` | +| `group:openclaw` | 所有内置工具(不包括 provider 插件) | ### `tools.allow` / `tools.deny` -全局工具允许/拒绝策略(deny 优先)。不区分大小写,支持 `*` 通配符。即使 Docker 沙箱关闭,也会生效。 +全局工具允许/拒绝策略(拒绝优先)。不区分大小写,支持 `*` 通配符。即使 Docker 沙箱已关闭,也会应用。 ```json5 { @@ -2240,7 +2249,7 @@ Talk 模式(macOS/iOS/Android)的默认值。 ### `tools.byProvider` -针对特定提供商或模型进一步限制工具。顺序:基础配置文件 → 提供商配置文件 → allow/deny。 +进一步限制特定提供商或模型可用的工具。顺序:基础配置文件 → 提供商配置文件 → allow/deny。 ```json5 { @@ -2256,7 +2265,7 @@ Talk 模式(macOS/iOS/Android)的默认值。 ### `tools.elevated` -控制沙箱外的 elevated exec 访问: +控制沙箱外的提升权限 `exec` 访问: ```json5 { @@ -2272,9 +2281,9 @@ Talk 模式(macOS/iOS/Android)的默认值。 } ``` -- 每智能体覆盖(`agents.list[].tools.elevated`)只能进一步收紧限制。 -- `/elevated on|off|ask|full` 会按会话存储状态;内联指令仅作用于单条消息。 -- Elevated `exec` 会绕过沙箱隔离,并使用已配置的 escape 路径(默认是 `gateway`,当 exec 目标为 `node` 时则使用 `node`)。 +- 每个智能体的覆盖配置(`agents.list[].tools.elevated`)只能进一步收紧限制。 +- `/elevated on|off|ask|full` 会按会话存储状态;内联指令仅对单条消息生效。 +- 提权后的 `exec` 会绕过沙箱隔离,并使用已配置的逃逸路径(默认是 `gateway`,或者当 `exec` 目标为 `node` 时使用 `node`)。 ### `tools.exec` @@ -2298,8 +2307,8 @@ Talk 模式(macOS/iOS/Android)的默认值。 ### `tools.loopDetection` -工具循环安全检查默认**禁用**。设为 `enabled: true` 可启用检测。 -设置可在 `tools.loopDetection` 中全局定义,并在 `agents.list[].tools.loopDetection` 中按智能体覆盖。 +工具循环安全检查**默认禁用**。设置 `enabled: true` 可启用检测。 +设置可在全局 `tools.loopDetection` 中定义,也可在每个智能体的 `agents.list[].tools.loopDetection` 中覆盖。 ```json5 { @@ -2320,14 +2329,14 @@ Talk 模式(macOS/iOS/Android)的默认值。 } ``` -- `historySize`:为循环分析保留的最大工具调用历史。 -- `warningThreshold`:用于发出警告的重复无进展模式阈值。 +- `historySize`:为循环分析保留的最大工具调用历史记录数。 +- `warningThreshold`:触发警告的重复无进展模式阈值。 - `criticalThreshold`:用于阻止严重循环的更高重复阈值。 -- `globalCircuitBreakerThreshold`:针对任意无进展运行的硬停止阈值。 -- `detectors.genericRepeat`:对重复的同工具/同参数调用发出警告。 -- `detectors.knownPollNoProgress`:对已知轮询工具(`process.poll`、`command_status` 等)的无进展情况发出警告/阻止。 -- `detectors.pingPong`:对交替出现的无进展成对模式发出警告/阻止。 -- 如果 `warningThreshold >= criticalThreshold` 或 `criticalThreshold >= globalCircuitBreakerThreshold`,验证会失败。 +- `globalCircuitBreakerThreshold`:任何无进展运行的硬停止阈值。 +- `detectors.genericRepeat`:对重复调用相同工具且参数相同的情况发出警告。 +- `detectors.knownPollNoProgress`:对已知轮询工具(`process.poll`、`command_status` 等)的无进展轮询发出警告或阻止。 +- `detectors.pingPong`:对交替出现且无进展的成对模式发出警告或阻止。 +- 如果 `warningThreshold >= criticalThreshold` 或 `criticalThreshold >= globalCircuitBreakerThreshold`,则验证会失败。 ### `tools.web` @@ -2361,7 +2370,7 @@ Talk 模式(macOS/iOS/Android)的默认值。 ### `tools.media` -配置入站媒体理解(图像/音频/视频): +配置传入媒体理解能力(图片/音频/视频): ```json5 { @@ -2369,7 +2378,7 @@ Talk 模式(macOS/iOS/Android)的默认值。 media: { concurrency: 2, asyncCompletion: { - directSend: false, // 显式选择加入:将完成的异步音乐/视频直接发送到渠道 + directSend: false, // 选择启用:异步音乐/视频完成后直接发送到渠道 }, audio: { enabled: true, @@ -2398,27 +2407,27 @@ Talk 模式(macOS/iOS/Android)的默认值。 **提供商条目**(`type: "provider"` 或省略): - `provider`:API 提供商 id(`openai`、`anthropic`、`google`/`gemini`、`groq` 等) -- `model`:模型 id 覆盖 +- `model`:模型 id 覆盖值 - `profile` / `preferredProfile`:`auth-profiles.json` 配置文件选择 **CLI 条目**(`type: "cli"`): -- `command`:要运行的可执行文件 +- `command`:要运行的可执行命令 - `args`:模板化参数(支持 `{{MediaPath}}`、`{{Prompt}}`、`{{MaxChars}}` 等) **通用字段:** - `capabilities`:可选列表(`image`、`audio`、`video`)。默认值:`openai`/`anthropic`/`minimax` → image,`google` → image+audio+video,`groq` → audio。 -- `prompt`、`maxChars`、`maxBytes`、`timeoutSeconds`、`language`:每条目覆盖。 +- `prompt`、`maxChars`、`maxBytes`、`timeoutSeconds`、`language`:每个条目的覆盖设置。 - 失败时会回退到下一个条目。 -提供商认证遵循标准顺序:`auth-profiles.json` → 环境变量 → `models.providers.*.apiKey`。 +provider 凭证遵循标准顺序:`auth-profiles.json` → 环境变量 → `models.providers.*.apiKey`。 **异步完成字段:** -- `asyncCompletion.directSend`:设为 `true` 时,已完成的异步 `music_generate` +- `asyncCompletion.directSend`:当为 `true` 时,已完成的异步 `music_generate` 和 `video_generate` 任务会优先尝试直接投递到渠道。默认值:`false` - (旧版请求方会话唤醒/模型投递路径)。 + (旧版请求者会话唤醒/模型投递路径)。 @@ -2437,9 +2446,9 @@ Talk 模式(macOS/iOS/Android)的默认值。 ### `tools.sessions` -控制会话工具(`sessions_list`、`sessions_history`、`sessions_send`)可定位哪些会话。 +控制哪些会话可以被会话工具(`sessions_list`、`sessions_history`、`sessions_send`)作为目标。 -默认值:`tree`(当前会话 + 由其生成的会话,例如 subagents)。 +默认值:`tree`(当前会话 + 由其派生的会话,例如子智能体)。 ```json5 { @@ -2455,24 +2464,24 @@ Talk 模式(macOS/iOS/Android)的默认值。 说明: - `self`:仅当前会话键。 -- `tree`:当前会话 + 当前会话生成的会话(subagents)。 -- `agent`:属于当前智能体 id 的任意会话(如果你在同一智能体 id 下按发送者运行会话,则可能包含其他用户)。 -- `all`:任意会话。跨智能体定向仍需要 `tools.agentToAgent`。 -- 沙箱钳制:当当前会话处于沙箱隔离中,且 `agents.defaults.sandbox.sessionToolsVisibility="spawned"` 时,即使 `tools.sessions.visibility="all"`,可见性也会被强制为 `tree`。 +- `tree`:当前会话 + 由当前会话派生的会话(子智能体)。 +- `agent`:属于当前智能体 id 的任意会话(如果你在同一个智能体 id 下按发送者运行会话,也可能包括其他用户)。 +- `all`:任意会话。跨智能体定向仍然需要 `tools.agentToAgent`。 +- 沙箱限制:当当前会话处于沙箱隔离中,且 `agents.defaults.sandbox.sessionToolsVisibility="spawned"` 时,即使 `tools.sessions.visibility="all"`,可见性也会被强制为 `tree`。 ### `tools.sessions_spawn` -控制 `sessions_spawn` 对内联附件的支持。 +控制 `sessions_spawn` 的内联附件支持。 ```json5 { tools: { sessions_spawn: { attachments: { - enabled: false, // 显式选择加入:设为 true 以允许内联文件附件 - maxTotalBytes: 5242880, // 所有文件总计 5 MB + enabled: false, // 选择启用:设为 true 以允许内联文件附件 + maxTotalBytes: 5242880, // 所有文件合计最多 5 MB maxFiles: 50, - maxFileBytes: 1048576, // 每个文件 1 MB + maxFileBytes: 1048576, // 每个文件最多 1 MB retainOnSessionKeep: false, // 当 cleanup="keep" 时保留附件 }, }, @@ -2482,16 +2491,18 @@ Talk 模式(macOS/iOS/Android)的默认值。 说明: -- 附件仅支持 `runtime: "subagent"`。ACP 运行时会拒绝它们。 -- 文件会以 `.openclaw/attachments//` 的形式物化到子工作区中,并带有一个 `.manifest.json`。 +- 附件仅支持 `runtime: "subagent"`。ACP runtime 会拒绝它们。 +- 文件会以实体形式写入子工作区的 `.openclaw/attachments//`,并附带一个 `.manifest.json`。 - 附件内容会自动从转录持久化中脱敏。 -- Base64 输入会使用严格的字母表/填充检查以及解码前大小保护进行校验。 +- Base64 输入会通过严格的字母表/填充校验以及解码前大小保护进行验证。 - 文件权限为:目录 `0700`,文件 `0600`。 -- 清理由 `cleanup` 策略决定:`delete` 总是会移除附件;`keep` 仅在 `retainOnSessionKeep: true` 时保留附件。 +- 清理遵循 `cleanup` 策略:`delete` 总是删除附件;`keep` 仅在 `retainOnSessionKeep: true` 时保留附件。 + + ### `tools.experimental` -实验性内置工具标志。默认关闭,除非严格 agentic GPT-5 自动启用规则生效。 +实验性内置工具标志。默认关闭,除非适用 strict-agentic GPT-5 自动启用规则。 ```json5 { @@ -2506,8 +2517,8 @@ Talk 模式(macOS/iOS/Android)的默认值。 说明: - `planTool`:为非平凡的多步骤工作跟踪启用结构化 `update_plan` 工具。 -- 默认值:`false`,除非 `agents.defaults.embeddedPi.executionContract`(或每智能体覆盖)被设置为 `"strict-agentic"`,且运行的是 OpenAI 或 OpenAI Codex 的 GPT-5 家族模型。设为 `true` 可在该范围之外强制启用该工具,设为 `false` 则即使在 strict-agentic GPT-5 运行中也保持关闭。 -- 启用后,系统提示还会加入使用指南,使模型仅在重要工作中使用它,并始终最多只保留一个 `in_progress` 步骤。 +- 默认值:`false`,除非 `agents.defaults.embeddedPi.executionContract`(或每个智能体的覆盖值)被设置为 `"strict-agentic"`,且当前运行使用的是 OpenAI 或 OpenAI Codex 的 GPT-5 系列模型。设为 `true` 可在该范围之外强制启用此工具;设为 `false` 则即使在 strict-agentic GPT-5 运行中也保持关闭。 +- 启用后,系统提示也会添加使用指导,以便模型仅在处理重要工作时使用它,并且最多只保留一个 `in_progress` 步骤。 ### `agents.defaults.subagents` @@ -2527,21 +2538,21 @@ Talk 模式(macOS/iOS/Android)的默认值。 } ``` -- `model`:生成的子智能体的默认模型。若省略,子智能体会继承调用者的模型。 -- `allowAgents`:当请求方智能体未设置自己的 `subagents.allowAgents` 时,`sessions_spawn` 可定向的目标智能体 id 默认 allowlist(`["*"]` = 任意;默认:仅同一智能体)。 +- `model`:派生子智能体的默认模型。如果省略,子智能体会继承调用方的模型。 +- `allowAgents`:当请求方智能体未设置自己的 `subagents.allowAgents` 时,`sessions_spawn` 可定向的目标智能体 id 默认允许列表(`["*"]` = 任意;默认:仅同一智能体)。 - `runTimeoutSeconds`:当工具调用省略 `runTimeoutSeconds` 时,`sessions_spawn` 使用的默认超时时间(秒)。`0` 表示无超时。 -- 每子智能体工具策略:`tools.subagents.tools.allow` / `tools.subagents.tools.deny`。 +- 每个子智能体的工具策略:`tools.subagents.tools.allow` / `tools.subagents.tools.deny`。 --- -## 自定义提供商和 base URL +## 自定义 provider 和 base URL -OpenClaw 使用内置模型目录。可通过配置中的 `models.providers` 或 `~/.openclaw/agents//agent/models.json` 添加自定义提供商。 +OpenClaw 使用内置模型目录。通过配置中的 `models.providers` 或 `~/.openclaw/agents//agent/models.json` 添加自定义 provider。 ```json5 { models: { - mode: "merge", // merge(默认)| replace + mode: "merge", // merge(默认) | replace providers: { "custom-proxy": { baseUrl: "http://localhost:4000/v1", @@ -2565,51 +2576,51 @@ OpenClaw 使用内置模型目录。可通过配置中的 `models.providers` 或 } ``` -- 对于自定义认证需求,可使用 `authHeader: true` + `headers`。 +- 自定义认证需求请使用 `authHeader: true` + `headers`。 - 使用 `OPENCLAW_AGENT_DIR`(或旧版环境变量别名 `PI_CODING_AGENT_DIR`)覆盖智能体配置根目录。 -- 对于匹配的提供商 ID,合并优先级如下: - - 非空的智能体 `models.json` `baseUrl` 值优先生效。 - - 非空的智能体 `apiKey` 值仅在当前配置/auth-profile 上下文中该提供商不是 SecretRef 管理时才优先生效。 - - 由 SecretRef 管理的提供商 `apiKey` 值会根据源标记刷新(环境变量引用使用 `ENV_VAR_NAME`,文件/exec 引用使用 `secretref-managed`),而不会持久化已解析的 secret。 - - 由 SecretRef 管理的提供商 header 值会根据源标记刷新(环境变量引用使用 `secretref-env:ENV_VAR_NAME`,文件/exec 引用使用 `secretref-managed`)。 - - 空的或缺失的智能体 `apiKey`/`baseUrl` 会回退到配置中的 `models.providers`。 - - 匹配模型的 `contextWindow`/`maxTokens` 会在显式配置值与隐式目录值之间取较高者。 - - 匹配模型的 `contextTokens` 会在存在显式运行时上限时保留它;可用它在不改变模型原生元数据的情况下限制有效上下文。 - - 当你希望配置完全重写 `models.json` 时,请使用 `models.mode: "replace"`。 - - 标记持久化以源为准:标记会从活动源配置快照(解析前)写入,而不是从已解析的运行时 secret 值写入。 +- 匹配 provider ID 的合并优先级: + - 非空的智能体 `models.json` `baseUrl` 值优先。 + - 非空的智能体 `apiKey` 值仅在该 provider 在当前 config/auth-profile 上下文中不是由 SecretRef 管理时优先。 + - 由 SecretRef 管理的 provider `apiKey` 值会从源标记刷新(环境变量引用使用 `ENV_VAR_NAME`,文件/exec 引用使用 `secretref-managed`),而不是持久化已解析的 secret。 + - 由 SecretRef 管理的 provider header 值会从源标记刷新(环境变量引用使用 `secretref-env:ENV_VAR_NAME`,文件/exec 引用使用 `secretref-managed`)。 + - 空或缺失的智能体 `apiKey`/`baseUrl` 会回退到配置中的 `models.providers`。 + - 匹配模型的 `contextWindow`/`maxTokens` 会在显式配置值和隐式目录值之间取较高值。 + - 匹配模型的 `contextTokens` 会在存在时保留显式运行时上限;当你想限制有效上下文而不更改模型原生元数据时,可使用它。 + - 当你希望配置完全重写 `models.json` 时,使用 `models.mode: "replace"`。 + - 标记持久化以源为准:标记从活动源配置快照(解析前)写入,而不是从已解析的运行时 secret 值写入。 -### 提供商字段详情 +### provider 字段详情 -- `models.mode`:提供商目录行为(`merge` 或 `replace`)。 -- `models.providers`:以提供商 id 为键的自定义提供商映射。 - - 安全编辑方式:使用 `openclaw config set models.providers. '' --strict-json --merge` 或 `openclaw config set models.providers..models '' --strict-json --merge` 进行增量更新。除非传入 `--replace`,否则 `config set` 会拒绝破坏性替换。 +- `models.mode`:provider 目录行为(`merge` 或 `replace`)。 +- `models.providers`:按 provider id 键控的自定义 provider 映射。 + - 安全编辑:使用 `openclaw config set models.providers. '' --strict-json --merge` 或 `openclaw config set models.providers..models '' --strict-json --merge` 进行增量更新。`config set` 会拒绝破坏性替换,除非你传入 `--replace`。 - `models.providers.*.api`:请求适配器(`openai-completions`、`openai-responses`、`anthropic-messages`、`google-generative-ai` 等)。 -- `models.providers.*.apiKey`:提供商凭证(优先使用 SecretRef/环境变量替换)。 +- `models.providers.*.apiKey`:provider 凭证(优先使用 SecretRef/环境变量替换)。 - `models.providers.*.auth`:认证策略(`api-key`、`token`、`oauth`、`aws-sdk`)。 -- `models.providers.*.injectNumCtxForOpenAICompat`:对于 Ollama + `openai-completions`,向请求中注入 `options.num_ctx`(默认:`true`)。 +- `models.providers.*.injectNumCtxForOpenAICompat`:对于 Ollama + `openai-completions`,向请求中注入 `options.num_ctx`(默认值:`true`)。 - `models.providers.*.authHeader`:在需要时强制通过 `Authorization` header 传输凭证。 -- `models.providers.*.baseUrl`:上游 API base URL。 +- `models.providers.*.baseUrl`:上游 API 的 base URL。 - `models.providers.*.headers`:用于代理/租户路由的额外静态 headers。 -- `models.providers.*.request`:模型提供商 HTTP 请求的传输层覆盖。 - - `request.headers`:额外 headers(与提供商默认值合并)。值接受 SecretRef。 - - `request.auth`:认证策略覆盖。模式:`"provider-default"`(使用提供商内置认证)、`"authorization-bearer"`(配合 `token`)、`"header"`(配合 `headerName`、`value`,以及可选 `prefix`)。 - - `request.proxy`:HTTP 代理覆盖。模式:`"env-proxy"`(使用 `HTTP_PROXY`/`HTTPS_PROXY` 环境变量)、`"explicit-proxy"`(配合 `url`)。两种模式都接受可选的 `tls` 子对象。 - - `request.tls`:直连时的 TLS 覆盖。字段:`ca`、`cert`、`key`、`passphrase`(均接受 SecretRef)、`serverName`、`insecureSkipVerify`。 - - `request.allowPrivateNetwork`:设为 `true` 时,当 DNS 将 `baseUrl` 解析到私有、CGNAT 或类似网段时,允许通过提供商 HTTP 抓取保护访问 HTTPS `baseUrl`(这是针对受信任的自托管 OpenAI 兼容端点的 operator 显式选择加入)。WebSocket 对 headers/TLS 使用相同的 `request`,但不经过该抓取 SSRF 门禁。默认值 `false`。 -- `models.providers.*.models`:显式提供商模型目录条目。 +- `models.providers.*.request`:模型 provider HTTP 请求的传输覆盖配置。 + - `request.headers`:额外 headers(与 provider 默认值合并)。值支持 SecretRef。 + - `request.auth`:认证策略覆盖。模式:`"provider-default"`(使用 provider 内置认证)、`"authorization-bearer"`(配合 `token`)、`"header"`(配合 `headerName`、`value`,可选 `prefix`)。 + - `request.proxy`:HTTP 代理覆盖。模式:`"env-proxy"`(使用 `HTTP_PROXY`/`HTTPS_PROXY` 环境变量)、`"explicit-proxy"`(配合 `url`)。两种模式都支持可选的 `tls` 子对象。 + - `request.tls`:直连时的 TLS 覆盖。字段:`ca`、`cert`、`key`、`passphrase`(均支持 SecretRef)、`serverName`、`insecureSkipVerify`。 + - `request.allowPrivateNetwork`:当为 `true` 时,如果 DNS 将 `baseUrl` 解析到私有、CGNAT 或类似网段,则允许通过 provider HTTP 抓取防护访问 HTTPS `baseUrl`(供受信任的自托管 OpenAI-compatible 端点由运维人员选择启用)。WebSocket 使用同一个 `request` 处理 headers/TLS,但不使用该抓取 SSRF 防护。默认值 `false`。 +- `models.providers.*.models`:显式 provider 模型目录条目。 - `models.providers.*.models.*.contextWindow`:模型原生上下文窗口元数据。 - `models.providers.*.models.*.contextTokens`:可选的运行时上下文上限。当你希望有效上下文预算小于模型原生 `contextWindow` 时使用它。 -- `models.providers.*.models.*.compat.supportsDeveloperRole`:可选的兼容性提示。对于 `api: "openai-completions"` 且 `baseUrl` 为非空、非原生值(host 不是 `api.openai.com`)时,OpenClaw 会在运行时强制将其设为 `false`。空的/省略的 `baseUrl` 会保留默认 OpenAI 行为。 -- `models.providers.*.models.*.compat.requiresStringContent`:针对仅接受字符串的 OpenAI 兼容聊天端点的可选兼容性提示。设为 `true` 时,OpenClaw 会在发送请求前将纯文本 `messages[].content` 数组展平为普通字符串。 -- `plugins.entries.amazon-bedrock.config.discovery`:Bedrock 自动发现设置根路径。 +- `models.providers.*.models.*.compat.supportsDeveloperRole`:可选兼容性提示。对于 `api: "openai-completions"` 且 `baseUrl` 为非空、非原生值(主机不是 `api.openai.com`)的情况,OpenClaw 会在运行时强制将其设为 `false`。空或省略的 `baseUrl` 会保留默认 OpenAI 行为。 +- `models.providers.*.models.*.compat.requiresStringContent`:适用于仅支持字符串的 OpenAI-compatible 聊天端点的可选兼容性提示。当为 `true` 时,OpenClaw 会在发送请求前将纯文本 `messages[].content` 数组展平为普通字符串。 +- `plugins.entries.amazon-bedrock.config.discovery`:Bedrock 自动发现设置根节点。 - `plugins.entries.amazon-bedrock.config.discovery.enabled`:开启/关闭隐式发现。 - `plugins.entries.amazon-bedrock.config.discovery.region`:用于发现的 AWS 区域。 -- `plugins.entries.amazon-bedrock.config.discovery.providerFilter`:可选的 provider-id 过滤器,用于定向发现。 +- `plugins.entries.amazon-bedrock.config.discovery.providerFilter`:用于定向发现的可选 provider-id 过滤器。 - `plugins.entries.amazon-bedrock.config.discovery.refreshInterval`:发现刷新轮询间隔。 -- `plugins.entries.amazon-bedrock.config.discovery.defaultContextWindow`:已发现模型的后备上下文窗口。 -- `plugins.entries.amazon-bedrock.config.discovery.defaultMaxTokens`:已发现模型的后备最大输出 token 数。 +- `plugins.entries.amazon-bedrock.config.discovery.defaultContextWindow`:已发现模型的默认回退上下文窗口。 +- `plugins.entries.amazon-bedrock.config.discovery.defaultMaxTokens`:已发现模型的默认回退最大输出 token 数。 -### 提供商示例 +### provider 示例 @@ -2623,8 +2634,8 @@ OpenClaw 使用内置模型目录。可通过配置中的 `models.providers` 或 fallbacks: ["cerebras/zai-glm-4.6"], }, models: { - "cerebras/zai-glm-4.7": { alias: "GLM 4.7(Cerebras)" }, - "cerebras/zai-glm-4.6": { alias: "GLM 4.6(Cerebras)" }, + "cerebras/zai-glm-4.7": { alias: "GLM 4.7 (Cerebras)" }, + "cerebras/zai-glm-4.6": { alias: "GLM 4.6 (Cerebras)" }, }, }, }, @@ -2636,8 +2647,8 @@ OpenClaw 使用内置模型目录。可通过配置中的 `models.providers` 或 apiKey: "${CEREBRAS_API_KEY}", api: "openai-completions", models: [ - { id: "zai-glm-4.7", name: "GLM 4.7(Cerebras)" }, - { id: "zai-glm-4.6", name: "GLM 4.6(Cerebras)" }, + { id: "zai-glm-4.7", name: "GLM 4.7 (Cerebras)" }, + { id: "zai-glm-4.6", name: "GLM 4.6 (Cerebras)" }, ], }, }, @@ -2682,8 +2693,8 @@ Cerebras 请使用 `cerebras/zai-glm-4.7`;Z.AI 直连请使用 `zai/glm-4.7` 设置 `ZAI_API_KEY`。`z.ai/*` 和 `z-ai/*` 都是可接受的别名。快捷方式:`openclaw onboard --auth-choice zai-api-key`。 - 通用端点:`https://api.z.ai/api/paas/v4` -- Coding 端点(默认):`https://api.z.ai/api/coding/paas/v4` -- 若要使用通用端点,请定义一个带 base URL 覆盖的自定义提供商。 +- 编码端点(默认):`https://api.z.ai/api/coding/paas/v4` +- 对于通用端点,请定义带有 base URL 覆盖的自定义 provider。 @@ -2722,11 +2733,11 @@ Cerebras 请使用 `cerebras/zai-glm-4.7`;Z.AI 直连请使用 `zai/glm-4.7` } ``` -中国区端点:`baseUrl: "https://api.moonshot.cn/v1"` 或 `openclaw onboard --auth-choice moonshot-api-key-cn`。 +中国端点请使用:`baseUrl: "https://api.moonshot.cn/v1"` 或 `openclaw onboard --auth-choice moonshot-api-key-cn`。 原生 Moonshot 端点会在共享的 `openai-completions` 传输上声明流式使用兼容性,而 OpenClaw 会根据端点能力 -而不只是内置提供商 id 本身来进行判断。 +而不只是内置 provider id 来判断这一点。 @@ -2744,11 +2755,11 @@ Cerebras 请使用 `cerebras/zai-glm-4.7`;Z.AI 直连请使用 `zai/glm-4.7` } ``` -兼容 Anthropic,内置提供商。快捷方式:`openclaw onboard --auth-choice kimi-code-api-key`。 +Anthropic-compatible,内置 provider。快捷方式:`openclaw onboard --auth-choice kimi-code-api-key`。 - + ```json5 { @@ -2827,15 +2838,14 @@ Base URL 不应包含 `/v1`(Anthropic 客户端会自行追加)。快捷方 `openclaw onboard --auth-choice minimax-global-api` 或 `openclaw onboard --auth-choice minimax-cn-api`。 模型目录默认仅包含 M2.7。 -在兼容 Anthropic 的流式路径上,除非你显式设置 `thinking`,否则 OpenClaw 默认会禁用 MiniMax thinking。 -`/fast on` 或 `params.fastMode: true` 会将 `MiniMax-M2.7` 重写为 +在 Anthropic-compatible 流式路径上,除非你显式自行设置 `thinking`,否则 OpenClaw 默认会禁用 MiniMax thinking。`/fast on` 或 `params.fastMode: true` 会将 `MiniMax-M2.7` 重写为 `MiniMax-M2.7-highspeed`。 -参见 [本地模型](/zh-CN/gateway/local-models)。简而言之:在高性能硬件上通过 LM Studio Responses API 运行大型本地模型;同时保留已合并的托管模型以作后备。 +参见 [本地模型](/zh-CN/gateway/local-models)。简而言之:在高性能硬件上通过 LM Studio Responses API 运行大型本地模型;同时保留已合并的托管模型作为回退。 @@ -2866,13 +2876,13 @@ Base URL 不应包含 `/v1`(Anthropic 客户端会自行追加)。快捷方 } ``` -- `allowBundled`:仅针对内置 Skills 的可选 allowlist(对托管/工作区 Skills 无影响)。 -- `load.extraDirs`:额外的共享 Skills 根目录(优先级最低)。 -- `install.preferBrew`:设为 true 时,当 `brew` 可用,会优先使用 Homebrew 安装器,再回退到其他安装器类型。 +- `allowBundled`:仅对内置 Skills 生效的可选允许列表(托管/工作区 Skills 不受影响)。 +- `load.extraDirs`:额外的共享 Skill 根目录(优先级最低)。 +- `install.preferBrew`:当为 true 时,如果 `brew` 可用,则优先使用 Homebrew 安装器,然后再回退到其他安装器类型。 - `install.nodeManager`:用于 `metadata.openclaw.install` 规范的 Node 安装器偏好(`npm` | `pnpm` | `yarn` | `bun`)。 -- `entries..enabled: false`:即使某个 Skill 已内置/已安装,也会将其禁用。 -- `entries..apiKey`:为声明主环境变量的 Skills 提供的便捷字段(明文字符串或 SecretRef 对象)。 +- `entries..enabled: false`:即使 Skill 已内置/已安装,也会禁用该 Skill。 +- `entries..apiKey`:为声明了主环境变量的 Skills 提供的便捷字段(明文字符串或 SecretRef 对象)。 --- @@ -2885,7 +2895,7 @@ Base URL 不应包含 `/v1`(Anthropic 客户端会自行追加)。快捷方 allow: ["voice-call"], deny: [], load: { - paths: ["~/Projects/oss/voice-call-extension"], + paths: ["~/Projects/oss/voice-call-plugin"], }, entries: { "voice-call": { @@ -2901,46 +2911,46 @@ Base URL 不应包含 `/v1`(Anthropic 客户端会自行追加)。快捷方 ``` - 从 `~/.openclaw/extensions`、`/.openclaw/extensions` 以及 `plugins.load.paths` 加载。 -- 设备发现接受原生 OpenClaw 插件,以及兼容的 Codex bundles 和 Claude bundles,包括无 manifest 的 Claude 默认布局 bundles。 +- 设备发现支持原生 OpenClaw 插件,以及兼容的 Codex bundle 和 Claude bundle,包括无 manifest 的 Claude 默认布局 bundle。 - **配置变更需要重启 Gateway 网关。** -- `allow`:可选 allowlist(仅加载列出的插件)。`deny` 优先。 -- `plugins.entries..apiKey`:插件级 API key 便捷字段(在插件支持时)。 -- `plugins.entries..env`:插件作用域环境变量映射。 -- `plugins.entries..hooks.allowPromptInjection`:设为 `false` 时,core 会阻止 `before_prompt_build`,并忽略旧版 `before_agent_start` 中会修改提示的字段,同时保留旧版 `modelOverride` 和 `providerOverride`。适用于原生插件 hooks 以及受支持的 bundle 提供 hook 目录。 -- `plugins.entries..subagent.allowModelOverride`:显式信任此插件可为后台子智能体运行请求按次 `provider` 和 `model` 覆盖。 -- `plugins.entries..subagent.allowedModels`:受信任子智能体覆盖的规范 `provider/model` 目标可选 allowlist。仅当你有意允许任意模型时才使用 `"*"`。 -- `plugins.entries..config`:插件定义的配置对象(若可用,则按原生 OpenClaw 插件 schema 校验)。 -- `plugins.entries.firecrawl.config.webFetch`:Firecrawl web 抓取提供商设置。 - - `apiKey`:Firecrawl API key(接受 SecretRef)。会回退到 `plugins.entries.firecrawl.config.webSearch.apiKey`、旧版 `tools.web.fetch.firecrawl.apiKey`,或 `FIRECRAWL_API_KEY` 环境变量。 +- `allow`:可选允许列表(仅加载列出的插件)。`deny` 优先。 +- `plugins.entries..apiKey`:插件级 API key 便捷字段(当插件支持时)。 +- `plugins.entries..env`:插件作用域的环境变量映射。 +- `plugins.entries..hooks.allowPromptInjection`:当为 `false` 时,核心会阻止 `before_prompt_build`,并忽略旧版 `before_agent_start` 中会修改提示词的字段,同时保留旧版 `modelOverride` 和 `providerOverride`。适用于原生插件 hooks,以及受支持的 bundle 提供的 hook 目录。 +- `plugins.entries..subagent.allowModelOverride`:显式信任此插件可为后台子智能体运行请求每次运行的 `provider` 和 `model` 覆盖。 +- `plugins.entries..subagent.allowedModels`:受信任子智能体覆盖的可选规范 `provider/model` 目标允许列表。仅当你明确希望允许任意模型时才使用 `"*"`。 +- `plugins.entries..config`:插件定义的配置对象(如可用,将由原生 OpenClaw 插件 schema 验证)。 +- `plugins.entries.firecrawl.config.webFetch`:Firecrawl web 抓取 provider 设置。 + - `apiKey`:Firecrawl API key(支持 SecretRef)。回退到 `plugins.entries.firecrawl.config.webSearch.apiKey`、旧版 `tools.web.fetch.firecrawl.apiKey` 或 `FIRECRAWL_API_KEY` 环境变量。 - `baseUrl`:Firecrawl API base URL(默认:`https://api.firecrawl.dev`)。 - `onlyMainContent`:仅提取页面主内容(默认:`true`)。 - `maxAgeMs`:最大缓存时长(毫秒)(默认:`172800000` / 2 天)。 - - `timeoutSeconds`:抓取请求超时秒数(默认:`60`)。 + - `timeoutSeconds`:抓取请求超时时间(秒)(默认:`60`)。 - `plugins.entries.xai.config.xSearch`:xAI X Search(Grok web 搜索)设置。 - - `enabled`:启用 X Search 提供商。 - - `model`:搜索使用的 Grok 模型(例如 `"grok-4-1-fast"`)。 + - `enabled`:启用 X Search provider。 + - `model`:用于搜索的 Grok 模型(例如 `"grok-4-1-fast"`)。 - `plugins.entries.memory-core.config.dreaming`:memory Dreaming 设置。阶段和阈值请参见 [Dreaming](/zh-CN/concepts/dreaming)。 - - `enabled`:Dreaming 主开关(默认 `false`)。 - - `frequency`:每次完整 Dreaming 扫描的 cron 频率(默认 `"0 3 * * *"`)。 + - `enabled`:Dreaming 总开关(默认 `false`)。 + - `frequency`:每次完整 Dreaming 扫描的 cron 周期(默认 `"0 3 * * *"`)。 - 阶段策略和阈值属于实现细节(不是面向用户的配置键)。 -- 完整的 Memory 配置位于 [Memory 配置参考](/zh-CN/reference/memory-config): +- 完整 memory 配置位于 [Memory 配置参考](/zh-CN/reference/memory-config): - `agents.defaults.memorySearch.*` - `memory.backend` - `memory.citations` - `memory.qmd.*` - `plugins.entries.memory-core.config.dreaming` -- 已启用的 Claude bundle 插件也可以从 `settings.json` 提供嵌入式 Pi 默认值;OpenClaw 会将其作为经过净化的智能体设置应用,而不是作为原始 OpenClaw 配置补丁应用。 -- `plugins.slots.memory`:选择活动 memory 插件 id,或设为 `"none"` 以禁用 memory 插件。 -- `plugins.slots.contextEngine`:选择活动 context engine 插件 id;默认值为 `"legacy"`,除非你安装并选择了其他引擎。 +- 已启用的 Claude bundle 插件也可以从 `settings.json` 提供内嵌 Pi 默认值;OpenClaw 会将其作为已净化的智能体设置应用,而不是作为原始 OpenClaw 配置补丁应用。 +- `plugins.slots.memory`:选择当前活动的 memory 插件 id,或设为 `"none"` 以禁用 memory 插件。 +- `plugins.slots.contextEngine`:选择当前活动的上下文引擎插件 id;默认值为 `"legacy"`,除非你安装并选择了其他引擎。 - `plugins.installs`:由 CLI 管理的安装元数据,供 `openclaw plugins update` 使用。 - - 包括 `source`、`spec`、`sourcePath`、`installPath`、`version`、`resolvedName`、`resolvedVersion`、`resolvedSpec`、`integrity`、`shasum`、`resolvedAt`、`installedAt`。 - - 将 `plugins.installs.*` 视为受管状态;优先使用 CLI 命令,而不是手动编辑。 + - 包含 `source`、`spec`、`sourcePath`、`installPath`、`version`、`resolvedName`、`resolvedVersion`、`resolvedSpec`、`integrity`、`shasum`、`resolvedAt`、`installedAt`。 + - 将 `plugins.installs.*` 视为托管状态;优先使用 CLI 命令,而不是手动编辑。 参见 [插件](/zh-CN/tools/plugin)。 --- -## 浏览器 +## Browser ```json5 { @@ -2949,7 +2959,7 @@ Base URL 不应包含 `/v1`(Anthropic 客户端会自行追加)。快捷方 evaluateEnabled: true, defaultProfile: "user", ssrfPolicy: { - // dangerouslyAllowPrivateNetwork: true, // 仅在信任私有网络访问时选择加入 + // dangerouslyAllowPrivateNetwork: true, // 仅在信任私有网络访问时选择启用 // allowPrivateNetwork: true, // 旧版别名 // hostnameAllowlist: ["*.example.com", "example.com"], // allowedHostnames: ["localhost"], @@ -2977,26 +2987,21 @@ Base URL 不应包含 `/v1`(Anthropic 客户端会自行追加)。快捷方 ``` - `evaluateEnabled: false` 会禁用 `act:evaluate` 和 `wait --fn`。 -- `ssrfPolicy.dangerouslyAllowPrivateNetwork` 在未设置时处于禁用状态,因此浏览器导航默认保持严格模式。 -- 仅当你有意信任私有网络浏览器导航时,才设置 `ssrfPolicy.dangerouslyAllowPrivateNetwork: true`。 -- 在严格模式下,远程 CDP 配置文件端点(`profiles.*.cdpUrl`)在可达性/设备发现检查期间也会受到相同的私有网络阻止策略约束。 +- 未设置时,`ssrfPolicy.dangerouslyAllowPrivateNetwork` 为禁用状态,因此 browser 导航默认保持严格模式。 +- 仅当你明确信任私有网络 browser 导航时,才设置 `ssrfPolicy.dangerouslyAllowPrivateNetwork: true`。 +- 在严格模式下,远程 CDP 配置文件端点(`profiles.*.cdpUrl`)在可达性/设备发现检查期间也会受到相同的私有网络拦截限制。 - `ssrfPolicy.allowPrivateNetwork` 仍作为旧版别名受支持。 - 在严格模式下,使用 `ssrfPolicy.hostnameAllowlist` 和 `ssrfPolicy.allowedHostnames` 配置显式例外。 - 远程配置文件为仅附加模式(禁用 start/stop/reset)。 -- `profiles.*.cdpUrl` 接受 `http://`、`https://`、`ws://` 和 `wss://`。 - 如果你希望 OpenClaw 发现 `/json/version`,请使用 HTTP(S); - 如果提供商直接给你 DevTools WebSocket URL,请使用 WS(S)。 -- `existing-session` 配置文件使用 Chrome MCP 而不是 CDP,并且可以附加到所选主机或通过已连接的浏览器节点附加。 -- `existing-session` 配置文件可设置 `userDataDir`,以指定某个特定的基于 Chromium 的浏览器配置文件,例如 Brave 或 Edge。 -- `existing-session` 配置文件保留当前 Chrome MCP 路由限制: - 使用 snapshot/ref 驱动的操作而不是 CSS 选择器定向、单文件上传 - hooks、无对话框超时覆盖、无 `wait --load networkidle`,以及无 - `responsebody`、PDF 导出、下载拦截或批量操作。 -- 本地受管的 `openclaw` 配置文件会自动分配 `cdpPort` 和 `cdpUrl`;仅在远程 CDP 场景中显式设置 `cdpUrl`。 -- 自动检测顺序:默认浏览器(如果基于 Chromium)→ Chrome → Brave → Edge → Chromium → Chrome Canary。 -- Control 服务:仅限 loopback(端口由 `gateway.port` 派生,默认 `18791`)。 -- `extraArgs` 会为本地 Chromium 启动追加额外的启动标志(例如 - `--disable-gpu`、窗口尺寸或调试标志)。 +- `profiles.*.cdpUrl` 支持 `http://`、`https://`、`ws://` 和 `wss://`。 + 当你希望 OpenClaw 发现 `/json/version` 时,使用 HTTP(S);当 provider 直接给出 DevTools WebSocket URL 时,使用 WS(S)。 +- `existing-session` 配置文件使用 Chrome MCP 而非 CDP,并且可以附加到所选主机上,或通过已连接的 browser 节点附加。 +- `existing-session` 配置文件可以设置 `userDataDir`,以指向特定的 Chromium-based browser 配置文件,例如 Brave 或 Edge。 +- `existing-session` 配置文件保留当前 Chrome MCP 路由限制:使用 snapshot/ref 驱动的操作而不是 CSS 选择器定向、单文件上传 hooks、不支持对话框超时覆盖、不支持 `wait --load networkidle`,且不支持 `responsebody`、PDF 导出、下载拦截或批量操作。 +- 本地托管的 `openclaw` 配置文件会自动分配 `cdpPort` 和 `cdpUrl`;仅在远程 CDP 场景下显式设置 `cdpUrl`。 +- 自动检测顺序:默认 browser(如果基于 Chromium)→ Chrome → Brave → Edge → Chromium → Chrome Canary。 +- 控制服务:仅 loopback(端口从 `gateway.port` 派生,默认 `18791`)。 +- `extraArgs` 会向本地 Chromium 启动追加额外启动标志(例如 `--disable-gpu`、窗口尺寸或调试标志)。 --- @@ -3008,14 +3013,14 @@ Base URL 不应包含 `/v1`(Anthropic 客户端会自行追加)。快捷方 seamColor: "#FF4500", assistant: { name: "OpenClaw", - avatar: "CB", // emoji、简短文本、图像 URL 或 data URI + avatar: "CB", // emoji、短文本、图片 URL 或 data URI }, }, } ``` -- `seamColor`:原生 app UI 外观的强调色(Talk 模式气泡着色等)。 -- `assistant`:Control UI 身份覆盖。会回退到活动智能体身份。 +- `seamColor`:原生应用 UI 外观的强调色(Talk Mode 气泡着色等)。 +- `assistant`:Control UI 身份覆盖。会回退到当前活动智能体身份。 --- @@ -3051,7 +3056,7 @@ Base URL 不应包含 `/v1`(Anthropic 客户端会自行追加)。快捷方 // embedSandbox: "scripts", // strict | scripts | trusted // allowExternalEmbedUrls: false, // 危险:允许绝对外部 http(s) 嵌入 URL // allowedOrigins: ["https://control.example.com"], // 非 loopback Control UI 必需 - // dangerouslyAllowHostHeaderOriginFallback: false, // 危险的 Host-header origin 回退模式 + // dangerouslyAllowHostHeaderOriginFallback: false, // 危险的 Host header origin 回退模式 // allowInsecureAuth: false, // dangerouslyDisableDeviceAuth: false, }, @@ -3065,9 +3070,9 @@ Base URL 不应包含 `/v1`(Anthropic 客户端会自行追加)。快捷方 // 可选。默认 false。 allowRealIpFallback: false, tools: { - // 额外的 /tools/invoke HTTP deny 列表 + // 额外的 /tools/invoke HTTP 拒绝项 deny: ["browser"], - // 从默认 HTTP deny 列表中移除工具 + // 从默认 HTTP 拒绝列表中移除工具 allow: ["gateway"], }, push: { @@ -3087,61 +3092,61 @@ Base URL 不应包含 `/v1`(Anthropic 客户端会自行追加)。快捷方 - `mode`:`local`(运行 Gateway 网关)或 `remote`(连接到远程 Gateway 网关)。除非为 `local`,否则 Gateway 网关会拒绝启动。 - `port`:用于 WS + HTTP 的单一复用端口。优先级:`--port` > `OPENCLAW_GATEWAY_PORT` > `gateway.port` > `18789`。 - `bind`:`auto`、`loopback`(默认)、`lan`(`0.0.0.0`)、`tailnet`(仅 Tailscale IP)或 `custom`。 -- **旧版 bind 别名**:在 `gateway.bind` 中使用 bind 模式值(`auto`、`loopback`、`lan`、`tailnet`、`custom`),不要使用 host 别名(`0.0.0.0`、`127.0.0.1`、`localhost`、`::`、`::1`)。 -- **Docker 注意事项**:默认的 `loopback` bind 会在容器内监听 `127.0.0.1`。使用 Docker bridge 网络(`-p 18789:18789`)时,流量会到达 `eth0`,因此 Gateway 网关无法访问。请使用 `--network host`,或设置 `bind: "lan"`(或 `bind: "custom"` 并配合 `customBindHost: "0.0.0.0"`)以监听所有接口。 -- **认证**:默认必需。非 loopback bind 需要 Gateway 网关认证。实际中,这意味着共享 token/password,或使用带 `gateway.auth.mode: "trusted-proxy"` 的身份感知反向代理。新手引导向导默认会生成 token。 -- 如果同时配置了 `gateway.auth.token` 和 `gateway.auth.password`(包括 SecretRef),请显式设置 `gateway.auth.mode` 为 `token` 或 `password`。当两者都已配置但 mode 未设置时,启动和服务安装/修复流程会失败。 -- `gateway.auth.mode: "none"`:显式无认证模式。仅用于受信任的本地 local loopback 配置;新手引导提示中不会提供此选项。 -- `gateway.auth.mode: "trusted-proxy"`:将认证委托给身份感知反向代理,并信任来自 `gateway.trustedProxies` 的身份 header(参见 [Trusted Proxy Auth](/zh-CN/gateway/trusted-proxy-auth))。此模式要求**非 loopback** 代理源;同主机 loopback 反向代理不满足 trusted-proxy 认证条件。 -- `gateway.auth.allowTailscale`:当为 `true` 时,Tailscale Serve 身份 header 可满足 Control UI/WebSocket 认证(通过 `tailscale whois` 验证)。HTTP API 端点**不会**使用该 Tailscale header 认证;它们仍遵循 Gateway 网关常规的 HTTP 认证模式。此无 token 流程假定 Gateway 网关主机是受信任的。当 `tailscale.mode = "serve"` 时默认值为 `true`。 -- `gateway.auth.rateLimit`:可选的认证失败限流器。按客户端 IP 和认证作用域生效(共享密钥和设备 token 分开跟踪)。被阻止的尝试会返回 `429` + `Retry-After`。 - - 在异步 Tailscale Serve Control UI 路径上,对于同一 `{scope, clientIp}` 的失败尝试,会在写入失败记录前串行化。因此,同一客户端的并发错误尝试可能会在第二个请求时触发限流,而不是两者都作为普通不匹配竞态通过。 - - `gateway.auth.rateLimit.exemptLoopback` 默认为 `true`;当你有意希望 localhost 流量也受限流约束时(例如测试配置或严格代理部署),请设为 `false`。 -- 来自浏览器来源的 WS 认证尝试始终会在禁用 loopback 豁免的情况下被限流(作为针对基于浏览器的 localhost 暴力破解的纵深防御)。 -- 在 loopback 上,这些来自浏览器来源的锁定会按规范化后的 `Origin` - 值彼此隔离,因此来自某个 localhost origin 的重复失败 - 不会自动锁死另一个 origin。 -- `tailscale.mode`:`serve`(仅 tailnet,loopback bind)或 `funnel`(公网,需要认证)。 -- `controlUi.allowedOrigins`:用于 Gateway 网关 WebSocket 连接的显式浏览器来源 allowlist。浏览器客户端若来自非 loopback origin,则必须设置。 +- **旧版 bind 别名**:请在 `gateway.bind` 中使用 bind 模式值(`auto`、`loopback`、`lan`、`tailnet`、`custom`),不要使用 host 别名(`0.0.0.0`、`127.0.0.1`、`localhost`、`::`、`::1`)。 +- **Docker 注意事项**:默认的 `loopback` bind 会在容器内监听 `127.0.0.1`。使用 Docker bridge 网络(`-p 18789:18789`)时,流量会到达 `eth0`,因此 Gateway 网关无法访问。请使用 `--network host`,或者设置 `bind: "lan"`(或 `bind: "custom"` 并配合 `customBindHost: "0.0.0.0"`)以监听所有网络接口。 +- **认证**:默认必须启用。非 loopback 绑定要求 Gateway 网关认证。实际中,这意味着使用共享 token/password,或使用配置了 `gateway.auth.mode: "trusted-proxy"` 的身份感知型反向代理。新手引导向导默认会生成一个 token。 +- 如果同时配置了 `gateway.auth.token` 和 `gateway.auth.password`(包括 SecretRef),请显式将 `gateway.auth.mode` 设置为 `token` 或 `password`。如果两者都已配置但未设置 mode,启动以及服务安装/修复流程都会失败。 +- `gateway.auth.mode: "none"`:显式无认证模式。仅用于受信任的本地 local loopback 设置;新手引导提示中不会提供此选项。 +- `gateway.auth.mode: "trusted-proxy"`:将认证委托给身份感知型反向代理,并信任来自 `gateway.trustedProxies` 的身份 headers(参见 [Trusted Proxy Auth](/zh-CN/gateway/trusted-proxy-auth))。此模式要求**非 loopback** 的代理来源;同主机的 loopback 反向代理不满足 trusted-proxy 认证要求。 +- `gateway.auth.allowTailscale`:当为 `true` 时,Tailscale Serve 身份 headers 可用于满足 Control UI/WebSocket 认证(通过 `tailscale whois` 验证)。HTTP API 端点**不会**使用该 Tailscale header 认证;它们仍遵循 Gateway 网关正常的 HTTP 认证模式。此无 token 流程假定 Gateway 网关主机是受信任的。当 `tailscale.mode = "serve"` 时默认值为 `true`。 +- `gateway.auth.rateLimit`:可选的认证失败限制器。按客户端 IP 和认证范围生效(共享 secret 与设备 token 分开跟踪)。被拦截的尝试会返回 `429` + `Retry-After`。 + - 在异步 Tailscale Serve Control UI 路径上,同一 `{scope, clientIp}` 的失败尝试会在写入失败结果前串行化。因此,同一客户端的并发错误尝试可能会在第二个请求时触发限制器,而不是两个请求都作为普通不匹配同时通过。 + - `gateway.auth.rateLimit.exemptLoopback` 默认值为 `true`;当你明确希望 localhost 流量也受到速率限制(用于测试环境或严格代理部署)时,请将其设为 `false`。 +- 来自 browser 源的 WS 认证尝试始终会被限流,且不会豁免 loopback(作为针对基于 browser 的 localhost 暴力破解的纵深防御)。 +- 在 loopback 上,这些来自 browser 源的锁定会按规范化后的 `Origin` + 值分别隔离,因此某个 localhost origin 的重复失败不会自动 + 锁定另一个 origin。 +- `tailscale.mode`:`serve`(仅 tailnet,loopback bind)或 `funnel`(公开访问,需要认证)。 +- `controlUi.allowedOrigins`:用于 Gateway 网关 WebSocket 连接的显式 browser-origin 允许列表。当 browser 客户端来自非 loopback origin 时必须设置。 - `controlUi.dangerouslyAllowHostHeaderOriginFallback`:危险模式,为有意依赖 Host-header origin 策略的部署启用 Host-header origin 回退。 - `remote.transport`:`ssh`(默认)或 `direct`(ws/wss)。对于 `direct`,`remote.url` 必须是 `ws://` 或 `wss://`。 -- `OPENCLAW_ALLOW_INSECURE_PRIVATE_WS=1`:客户端侧的紧急兜底覆盖,允许对受信任私有网络 IP 使用明文 `ws://`;默认仍仅允许 loopback 使用明文。 -- `gateway.remote.token` / `.password` 是远程客户端凭证字段。它们本身不会配置 Gateway 网关认证。 -- `gateway.push.apns.relay.baseUrl`:官方/TestFlight iOS 构建在将基于 relay 的注册发布到 Gateway 网关之后,供外部 APNs relay 使用的基础 HTTPS URL。该 URL 必须与编译进 iOS 构建中的 relay URL 一致。 +- `OPENCLAW_ALLOW_INSECURE_PRIVATE_WS=1`:客户端侧的紧急放行开关,允许通过明文 `ws://` 连接受信任的私有网络 IP;默认仍然只允许 local loopback 使用明文连接。 +- `gateway.remote.token` / `.password`:远程客户端凭证字段。它们本身不会配置 Gateway 网关认证。 +- `gateway.push.apns.relay.baseUrl`:外部 APNs relay 的基础 HTTPS URL,供官方/TestFlight iOS 构建在向 Gateway 网关发布基于 relay 的注册后使用。此 URL 必须与编译进 iOS 构建中的 relay URL 一致。 - `gateway.push.apns.relay.timeoutMs`:Gateway 网关到 relay 的发送超时时间(毫秒)。默认值为 `10000`。 -- 基于 relay 的注册会委托给特定的 Gateway 网关身份。已配对的 iOS app 会获取 `gateway.identity.get`,将该身份包含到 relay 注册中,并把作用域限定为该注册的发送授权转发给 Gateway 网关。其他 Gateway 网关无法复用该已存储注册。 -- `OPENCLAW_APNS_RELAY_BASE_URL` / `OPENCLAW_APNS_RELAY_TIMEOUT_MS`:对上述 relay 配置的临时环境变量覆盖。 -- `OPENCLAW_APNS_RELAY_ALLOW_HTTP=true`:仅用于开发的逃生阀,允许 loopback HTTP relay URL。生产 relay URL 应保持为 HTTPS。 +- 基于 relay 的注册会被委托给特定的 Gateway 网关身份。配对的 iOS 应用会获取 `gateway.identity.get`,在 relay 注册中包含该身份,并将一个注册范围的发送授权转发给 Gateway 网关。另一个 Gateway 网关无法复用该已存储的注册。 +- `OPENCLAW_APNS_RELAY_BASE_URL` / `OPENCLAW_APNS_RELAY_TIMEOUT_MS`:上述 relay 配置的临时环境变量覆盖项。 +- `OPENCLAW_APNS_RELAY_ALLOW_HTTP=true`:仅用于开发环境的逃生开关,允许使用 loopback HTTP relay URL。生产环境的 relay URL 应保持为 HTTPS。 - `gateway.channelHealthCheckMinutes`:渠道健康监控间隔(分钟)。设为 `0` 可全局禁用健康监控重启。默认值:`5`。 - `gateway.channelStaleEventThresholdMinutes`:陈旧 socket 阈值(分钟)。应保持大于或等于 `gateway.channelHealthCheckMinutes`。默认值:`30`。 -- `gateway.channelMaxRestartsPerHour`:滚动一小时内每个渠道/账号允许的最大健康监控重启次数。默认值:`10`。 -- `channels..healthMonitor.enabled`:每渠道选择退出健康监控重启,同时保持全局监控启用。 -- `channels..accounts..healthMonitor.enabled`:多账号渠道的每账号覆盖。设置后,其优先级高于渠道级覆盖。 -- 本地 Gateway 网关调用路径仅在 `gateway.auth.*` 未设置时,才可将 `gateway.remote.*` 用作回退。 -- 如果通过 SecretRef 显式配置了 `gateway.auth.token` / `gateway.auth.password` 且无法解析,则解析会以失败关闭方式处理(不会用远程回退来掩盖)。 -- `trustedProxies`:终止 TLS 或注入转发客户端 header 的反向代理 IP。只列出你控制的代理。loopback 条目对于同主机代理/本地检测配置(例如 Tailscale Serve 或本地反向代理)仍然有效,但它们**不会**使 loopback 请求有资格使用 `gateway.auth.mode: "trusted-proxy"`。 -- `allowRealIpFallback`:为 `true` 时,如果缺少 `X-Forwarded-For`,Gateway 网关会接受 `X-Real-IP`。默认 `false`,以保持失败关闭行为。 -- `gateway.tools.deny`:对 HTTP `POST /tools/invoke` 额外阻止的工具名称(扩展默认 deny 列表)。 -- `gateway.tools.allow`:从默认 HTTP deny 列表中移除工具名称。 +- `gateway.channelMaxRestartsPerHour`:每个渠道/账号在滚动一小时内允许的健康监控最大重启次数。默认值:`10`。 +- `channels..healthMonitor.enabled`:每个渠道的健康监控重启退出设置,同时保留全局监控开启。 +- `channels..accounts..healthMonitor.enabled`:多账号渠道的每个账号覆盖设置。设置后,其优先级高于渠道级覆盖。 +- 本地 Gateway 网关调用路径仅在 `gateway.auth.*` 未设置时,才可使用 `gateway.remote.*` 作为回退。 +- 如果 `gateway.auth.token` / `gateway.auth.password` 通过 SecretRef 显式配置但未解析成功,则解析会以关闭方式失败(不会使用远程回退来掩盖问题)。 +- `trustedProxies`:终止 TLS 或注入转发客户端 headers 的反向代理 IP。仅列出你控制的代理。loopback 条目对同主机代理/本地检测设置(例如 Tailscale Serve 或本地反向代理)仍然有效,但它们**不会**使 loopback 请求具备 `gateway.auth.mode: "trusted-proxy"` 的资格。 +- `allowRealIpFallback`:当为 `true` 时,如果缺少 `X-Forwarded-For`,Gateway 网关会接受 `X-Real-IP`。默认值为 `false`,以实现失败即关闭的行为。 +- `gateway.tools.deny`:对 HTTP `POST /tools/invoke` 额外阻止的工具名称(扩展默认拒绝列表)。 +- `gateway.tools.allow`:从默认 HTTP 拒绝列表中移除工具名称。 -### OpenAI 兼容端点 +### OpenAI-compatible 端点 -- Chat Completions:默认禁用。通过 `gateway.http.endpoints.chatCompletions.enabled: true` 启用。 +- Chat Completions:默认禁用。使用 `gateway.http.endpoints.chatCompletions.enabled: true` 启用。 - Responses API:`gateway.http.endpoints.responses.enabled`。 - Responses URL 输入加固: - `gateway.http.endpoints.responses.maxUrlParts` - `gateway.http.endpoints.responses.files.urlAllowlist` - `gateway.http.endpoints.responses.images.urlAllowlist` - 空 allowlist 会被视为未设置;使用 `gateway.http.endpoints.responses.files.allowUrl=false` - 和/或 `gateway.http.endpoints.responses.images.allowUrl=false` 可禁用 URL 抓取。 + 空允许列表会被视为未设置;请使用 `gateway.http.endpoints.responses.files.allowUrl=false` + 和/或 `gateway.http.endpoints.responses.images.allowUrl=false` 来禁用 URL 抓取。 - 可选的响应加固 header: - - `gateway.http.securityHeaders.strictTransportSecurity`(仅对你控制的 HTTPS origin 设置;参见 [Trusted Proxy Auth](/zh-CN/gateway/trusted-proxy-auth#tls-termination-and-hsts)) + - `gateway.http.securityHeaders.strictTransportSecurity`(仅对你控制的 HTTPS origins 设置;参见 [Trusted Proxy Auth](/zh-CN/gateway/trusted-proxy-auth#tls-termination-and-hsts)) ### 多实例隔离 -在一台主机上运行多个 Gateway 网关时,请使用唯一的端口和状态目录: +通过唯一端口和状态目录,在一台主机上运行多个 Gateway 网关: ```bash OPENCLAW_CONFIG_PATH=~/.openclaw/a.json \ @@ -3151,7 +3156,7 @@ openclaw gateway --port 19001 便捷标志:`--dev`(使用 `~/.openclaw-dev` + 端口 `19001`)、`--profile `(使用 `~/.openclaw-`)。 -参见 [多个 Gateway 网关](/zh-CN/gateway/multiple-gateways)。 +参见 [Multiple Gateways](/zh-CN/gateway/multiple-gateways)。 ### `gateway.tls` @@ -3169,11 +3174,11 @@ openclaw gateway --port 19001 } ``` -- `enabled`:在 Gateway 网关监听器上启用 TLS 终止(HTTPS/WSS)(默认:`false`)。 -- `autoGenerate`:在未配置显式文件时自动生成本地自签名 cert/key 对;仅用于本地/开发环境。 +- `enabled`:在 Gateway 网关监听器上启用 TLS 终止(HTTPS/WSS)(默认值:`false`)。 +- `autoGenerate`:当未配置显式文件时,自动生成本地自签名证书/密钥对;仅适用于本地/开发环境。 - `certPath`:TLS 证书文件的文件系统路径。 -- `keyPath`:TLS 私钥文件的文件系统路径;请限制其权限。 -- `caPath`:用于客户端验证或自定义信任链的可选 CA bundle 路径。 +- `keyPath`:TLS 私钥文件的文件系统路径;请限制访问权限。 +- `caPath`:可选的 CA bundle 路径,用于客户端验证或自定义信任链。 ### `gateway.reload` @@ -3189,13 +3194,13 @@ openclaw gateway --port 19001 } ``` -- `mode`:控制运行时如何应用配置编辑。 +- `mode`:控制配置编辑在运行时的应用方式。 - `"off"`:忽略实时编辑;变更需要显式重启。 - `"restart"`:配置变更时始终重启 Gateway 网关进程。 - - `"hot"`:无需重启,在进程内应用变更。 - - `"hybrid"`(默认):先尝试热重载;如有必要则回退为重启。 + - `"hot"`:在不重启的情况下于进程内应用变更。 + - `"hybrid"`(默认):优先尝试热重载;如有需要则回退为重启。 - `debounceMs`:应用配置变更前的去抖窗口(毫秒)(非负整数)。 -- `deferralTimeoutMs`:在强制重启前,等待进行中操作完成的最长时间(毫秒)(默认:`300000` = 5 分钟)。 +- `deferralTimeoutMs`:在强制重启前等待正在进行中的操作完成的最长时间(毫秒)(默认:`300000` = 5 分钟)。 --- @@ -3233,46 +3238,46 @@ openclaw gateway --port 19001 ``` 认证:`Authorization: Bearer ` 或 `x-openclaw-token: `。 -拒绝查询字符串形式的 hook token。 +拒绝使用查询字符串中的 hook token。 -验证和安全说明: +验证与安全说明: -- `hooks.enabled=true` 需要一个非空的 `hooks.token`。 +- `hooks.enabled=true` 要求 `hooks.token` 为非空。 - `hooks.token` 必须与 `gateway.auth.token` **不同**;复用 Gateway 网关 token 会被拒绝。 -- `hooks.path` 不能是 `/`;请使用专用子路径,例如 `/hooks`。 -- 如果 `hooks.allowRequestSessionKey=true`,请约束 `hooks.allowedSessionKeyPrefixes`(例如 `["hook:"]`)。 -- 如果某个 mapping 或 preset 使用模板化的 `sessionKey`,请设置 `hooks.allowedSessionKeyPrefixes` 和 `hooks.allowRequestSessionKey=true`。静态 mapping key 不需要此显式选择加入。 +- `hooks.path` 不能为 `/`;请使用专用子路径,例如 `/hooks`。 +- 如果 `hooks.allowRequestSessionKey=true`,请限制 `hooks.allowedSessionKeyPrefixes`(例如 `["hook:"]`)。 +- 如果某个映射或预设使用了模板化 `sessionKey`,请设置 `hooks.allowedSessionKeyPrefixes` 并将 `hooks.allowRequestSessionKey=true`。静态映射键不需要此选择启用。 **端点:** - `POST /hooks/wake` → `{ text, mode?: "now"|"next-heartbeat" }` - `POST /hooks/agent` → `{ message, name?, agentId?, sessionKey?, wakeMode?, deliver?, channel?, to?, model?, thinking?, timeoutSeconds? }` - - 仅当 `hooks.allowRequestSessionKey=true`(默认:`false`)时,才接受请求负载中的 `sessionKey`。 + - 仅当 `hooks.allowRequestSessionKey=true`(默认:`false`)时,才接受来自请求负载的 `sessionKey`。 - `POST /hooks/` → 通过 `hooks.mappings` 解析 - - 模板渲染后的 mapping `sessionKey` 值会被视为外部提供,因此同样需要 `hooks.allowRequestSessionKey=true`。 + - 模板渲染后的映射 `sessionKey` 值会被视为外部提供,因此同样要求 `hooks.allowRequestSessionKey=true`。 - + -- `match.path` 匹配 `/hooks` 之后的子路径(例如 `/hooks/gmail` → `gmail`)。 -- `match.source` 匹配通用路径中的某个负载字段。 -- `{{messages[0].subject}}` 这类模板会从负载中读取。 -- `transform` 可以指向返回 hook action 的 JS/TS 模块。 - - `transform.module` 必须是相对路径,并且必须保持在 `hooks.transformsDir` 内(绝对路径和路径穿越会被拒绝)。 -- `agentId` 会路由到指定智能体;未知 ID 会回退到默认值。 -- `allowedAgentIds`:限制显式路由(`*` 或省略 = 允许全部,`[]` = 全部拒绝)。 -- `defaultSessionKey`:当 hook 智能体运行未显式提供 `sessionKey` 时使用的可选固定会话键。 -- `allowRequestSessionKey`:允许 `/hooks/agent` 调用方以及模板驱动的 mapping session key 设置 `sessionKey`(默认:`false`)。 -- `allowedSessionKeyPrefixes`:显式 `sessionKey` 值(请求 + mapping)的可选前缀 allowlist,例如 `["hook:"]`。当任意 mapping 或 preset 使用模板化 `sessionKey` 时,它会变为必需项。 -- `deliver: true` 会将最终回复发送到某个渠道;`channel` 默认为 `last`。 -- `model` 会覆盖此次 hook 运行使用的 LLM(如果已设置模型目录,则该模型必须被允许)。 +- `match.path`:匹配 `/hooks` 之后的子路径(例如 `/hooks/gmail` → `gmail`)。 +- `match.source`:为通用路径匹配负载中的某个字段。 +- 像 `{{messages[0].subject}}` 这样的模板会从负载中读取。 +- `transform` 可以指向返回 hook 动作的 JS/TS 模块。 + - `transform.module` 必须是相对路径,并且必须位于 `hooks.transformsDir` 内(绝对路径和路径穿越都会被拒绝)。 +- `agentId`:路由到指定智能体;未知 id 会回退到默认值。 +- `allowedAgentIds`:限制显式路由(`*` 或省略 = 全部允许,`[]` = 全部拒绝)。 +- `defaultSessionKey`:可选的固定会话键,用于未显式提供 `sessionKey` 的 hook 智能体运行。 +- `allowRequestSessionKey`:允许 `/hooks/agent` 调用方和模板驱动的映射会话键设置 `sessionKey`(默认:`false`)。 +- `allowedSessionKeyPrefixes`:显式 `sessionKey` 值(请求 + 映射)的可选前缀允许列表,例如 `["hook:"]`。当任一映射或预设使用模板化 `sessionKey` 时,它会成为必需项。 +- `deliver: true`:将最终回复发送到某个渠道;`channel` 默认值为 `last`。 +- `model`:覆盖本次 hook 运行的 LLM(如果设置了模型目录,则该模型必须被允许)。 ### Gmail 集成 -- 内置 Gmail preset 使用 `sessionKey: "hook:gmail:{{messages[0].id}}"`。 -- 如果你保留这种按消息路由方式,请设置 `hooks.allowRequestSessionKey: true`,并约束 `hooks.allowedSessionKeyPrefixes` 以匹配 Gmail 命名空间,例如 `["hook:", "hook:gmail:"]`。 -- 如果你需要 `hooks.allowRequestSessionKey: false`,请使用静态 `sessionKey` 覆盖该 preset,而不是使用模板化默认值。 +- 内置 Gmail 预设使用 `sessionKey: "hook:gmail:{{messages[0].id}}"`。 +- 如果你保留这种按消息路由的方式,请设置 `hooks.allowRequestSessionKey: true`,并限制 `hooks.allowedSessionKeyPrefixes` 以匹配 Gmail 命名空间,例如 `["hook:", "hook:gmail:"]`。 +- 如果你需要 `hooks.allowRequestSessionKey: false`,请使用静态 `sessionKey` 覆盖该预设,而不是使用模板化默认值。 ```json5 { @@ -3295,7 +3300,7 @@ openclaw gateway --port 19001 } ``` -- 配置后,Gateway 网关会在启动时自动启动 `gog gmail watch serve`。如需禁用,请设置 `OPENCLAW_SKIP_GMAIL_WATCHER=1`。 +- 配置后,Gateway 网关会在启动时自动启动 `gog gmail watch serve`。设置 `OPENCLAW_SKIP_GMAIL_WATCHER=1` 可禁用。 - 不要在 Gateway 网关旁边单独运行另一个 `gog gmail watch serve`。 --- @@ -3316,14 +3321,14 @@ openclaw gateway --port 19001 - `http://:/__openclaw__/canvas/` - `http://:/__openclaw__/a2ui/` - 仅限本地:保持 `gateway.bind: "loopback"`(默认)。 -- 非 loopback bind:canvas 路由与其他 Gateway 网关 HTTP 面一样,需要 Gateway 网关认证(token/password/trusted-proxy)。 -- Node WebViews 通常不会发送认证 header;节点完成配对并连接后,Gateway 网关会为 canvas/A2UI 访问发布节点作用域能力 URL。 +- 非 loopback 绑定:canvas 路由和其他 Gateway 网关 HTTP 接口一样,需要 Gateway 网关认证(token/password/trusted-proxy)。 +- Node WebView 通常不会发送认证 headers;在节点完成配对并连接后,Gateway 网关会广播节点作用域的能力 URL,用于访问 canvas/A2UI。 - 能力 URL 绑定到当前活动的节点 WS 会话,并且会很快过期。不使用基于 IP 的回退。 -- 会向所提供的 HTML 中注入实时重载客户端。 -- 在内容为空时自动创建起始 `index.html`。 -- 也会在 `/__openclaw__/a2ui/` 提供 A2UI。 -- 变更需要重启 gateway。 -- 对于大型目录或 `EMFILE` 错误,请禁用实时重载。 +- 会向所提供的 HTML 中注入 live-reload 客户端。 +- 为空时会自动创建起始 `index.html`。 +- 同时也会在 `/__openclaw__/a2ui/` 提供 A2UI。 +- 变更需要重启 Gateway 网关。 +- 对于大型目录或出现 `EMFILE` 错误时,请禁用 live reload。 --- @@ -3343,7 +3348,7 @@ openclaw gateway --port 19001 - `minimal`(默认):在 TXT 记录中省略 `cliPath` + `sshPort`。 - `full`:包含 `cliPath` + `sshPort`。 -- 主机名默认为 `openclaw`。使用 `OPENCLAW_MDNS_HOSTNAME` 覆盖。 +- 主机名默认为 `openclaw`。可通过 `OPENCLAW_MDNS_HOSTNAME` 覆盖。 ### 广域网(DNS-SD) @@ -3355,7 +3360,7 @@ openclaw gateway --port 19001 } ``` -会在 `~/.openclaw/dns/` 下写入单播 DNS-SD 区域。若需跨网络设备发现,请配合 DNS 服务器(推荐 CoreDNS)+ Tailscale split DNS。 +会在 `~/.openclaw/dns/` 下写入单播 DNS-SD 区域。若要实现跨网络设备发现,请搭配 DNS 服务器(推荐 CoreDNS)+ Tailscale 分割 DNS。 设置:`openclaw dns setup --apply`。 @@ -3380,14 +3385,14 @@ openclaw gateway --port 19001 } ``` -- 仅当进程环境中缺少对应键时,才会应用内联环境变量。 +- 仅当进程环境中缺少该键时,才会应用内联环境变量。 - `.env` 文件:当前工作目录下的 `.env` + `~/.openclaw/.env`(两者都不会覆盖现有变量)。 -- `shellEnv`:从你的登录 shell 配置文件中导入缺失的预期键名。 -- 完整优先级参见 [环境变量](/zh-CN/help/environment)。 +- `shellEnv`:从你的登录 shell 配置中导入缺失的预期键名。 +- 完整优先级请参见 [环境](/zh-CN/help/environment)。 ### 环境变量替换 -可在任意配置字符串中使用 `${VAR_NAME}` 引用环境变量: +可在任意配置字符串中通过 `${VAR_NAME}` 引用环境变量: ```json5 { @@ -3398,7 +3403,7 @@ openclaw gateway --port 19001 ``` - 仅匹配大写名称:`[A-Z_][A-Z0-9_]*`。 -- 缺失/为空的变量会在配置加载时抛出错误。 +- 缺失/空变量会在加载配置时抛出错误。 - 使用 `$${VAR}` 可转义为字面量 `${VAR}`。 - 可与 `$include` 一起使用。 @@ -3406,31 +3411,31 @@ openclaw gateway --port 19001 ## Secrets -Secret refs 是增量能力:明文值仍然可用。 +SecretRef 为增量功能:明文值仍然可用。 ### `SecretRef` -使用如下对象形状: +使用以下对象结构之一: ```json5 { source: "env" | "file" | "exec", provider: "default", id: "..." } ``` -校验规则: +验证规则: - `provider` 模式:`^[a-z][a-z0-9_-]{0,63}$` - `source: "env"` 的 id 模式:`^[A-Z][A-Z0-9_]{0,127}$` - `source: "file"` 的 id:绝对 JSON pointer(例如 `"/providers/openai/apiKey"`) - `source: "exec"` 的 id 模式:`^[A-Za-z0-9][A-Za-z0-9._:/-]{0,255}$` -- `source: "exec"` 的 id 不能包含以斜杠分隔的 `.` 或 `..` 路径段(例如 `a/../b` 会被拒绝) +- `source: "exec"` 的 id 不得包含以 `/` 分隔的 `.` 或 `..` 路径段(例如 `a/../b` 会被拒绝) -### 支持的凭证面 +### 支持的凭证范围 -- 规范矩阵:[SecretRef 凭证面](/zh-CN/reference/secretref-credential-surface) -- `secrets apply` 以受支持的 `openclaw.json` 凭证路径为目标。 -- `auth-profiles.json` refs 也包含在运行时解析和审计覆盖中。 +- 规范矩阵:[SecretRef 凭证范围](/zh-CN/reference/secretref-credential-surface) +- `secrets apply` 会作用于受支持的 `openclaw.json` 凭证路径。 +- `auth-profiles.json` 引用也包含在运行时解析和审计覆盖范围内。 -### Secret providers 配置 +### Secret provider 配置 ```json5 { @@ -3460,17 +3465,17 @@ Secret refs 是增量能力:明文值仍然可用。 说明: -- `file` provider 支持 `mode: "json"` 和 `mode: "singleValue"`(在 singleValue 模式下,`id` 必须是 `"value"`)。 -- `exec` provider 需要绝对 `command` 路径,并通过 stdin/stdout 使用协议负载。 -- 默认会拒绝符号链接命令路径。设置 `allowSymlinkCommand: true` 可在校验解析后的目标路径时允许符号链接路径。 -- 如果配置了 `trustedDirs`,trusted-dir 检查会应用到解析后的目标路径。 -- `exec` 子进程环境默认最小化;请使用 `passEnv` 显式传递所需变量。 -- Secret refs 会在激活时解析为内存快照,随后请求路径只读取该快照。 -- 激活期间会应用活动面过滤:启用面上的未解析 refs 会导致启动/重载失败,而非活动面会被跳过并附带诊断信息。 +- `file` provider 支持 `mode: "json"` 和 `mode: "singleValue"`(在 singleValue 模式下,`id` 必须为 `"value"`)。 +- `exec` provider 要求 `command` 为绝对路径,并通过 stdin/stdout 使用协议负载。 +- 默认情况下,符号链接命令路径会被拒绝。设置 `allowSymlinkCommand: true` 可允许符号链接路径,同时仍验证解析后的目标路径。 +- 如果配置了 `trustedDirs`,则受信任目录检查会作用于解析后的目标路径。 +- `exec` 子进程环境默认最小化;请通过 `passEnv` 显式传递所需变量。 +- Secret 引用会在激活时解析为内存中的快照,之后请求路径只读取该快照。 +- 激活期间会应用活动范围过滤:启用范围内未解析的引用会导致启动/重载失败,而非活动范围会被跳过并附带诊断信息。 --- -## 认证存储 +## Auth 存储 ```json5 { @@ -3488,10 +3493,10 @@ Secret refs 是增量能力:明文值仍然可用。 } ``` -- 每智能体配置文件保存在 `/auth-profiles.json`。 -- `auth-profiles.json` 支持静态凭证模式的值级 refs(`api_key` 使用 `keyRef`,`token` 使用 `tokenRef`)。 -- OAuth 模式配置文件(`auth.profiles..mode = "oauth"`)不支持 SecretRef 支持的 auth-profile 凭证。 -- 静态运行时凭证来自内存中的已解析快照;发现旧版静态 `auth.json` 条目时会清除。 +- 每个智能体的 profile 存储在 `/auth-profiles.json`。 +- `auth-profiles.json` 支持值级引用(静态凭证模式下,`api_key` 使用 `keyRef`,`token` 使用 `tokenRef`)。 +- OAuth 模式的 profile(`auth.profiles..mode = "oauth"`)不支持由 SecretRef 支持的 auth-profile 凭证。 +- 静态运行时凭证来自内存中的已解析快照;发现旧版静态 `auth.json` 条目时会被清理。 - 旧版 OAuth 会从 `~/.openclaw/credentials/oauth.json` 导入。 - 参见 [OAuth](/zh-CN/concepts/oauth)。 - Secrets 运行时行为以及 `audit/configure/apply` 工具:参见 [Secrets Management](/zh-CN/gateway/secrets)。 @@ -3516,20 +3521,20 @@ Secret refs 是增量能力:明文值仍然可用。 } ``` -- `billingBackoffHours`:当某个配置文件因真正的 - 账单/余额不足错误而失败时使用的基础退避时长(小时)(默认:`5`)。即使在 `401`/`403` 响应上, - 明确的账单文本也仍可能归入这里,但提供商特定的文本 - 匹配器仍仅限于其所属提供商(例如 OpenRouter 的 +- `billingBackoffHours`:当某个 profile 因真实 + 账单/余额不足错误而失败时的基础退避时长(小时)(默认:`5`)。即使是 `401`/`403` 响应,显式账单文本 + 也仍可能归入这里,但 provider 特定的文本 + 匹配器仍只作用于拥有它们的 provider(例如 OpenRouter 的 `Key limit exceeded`)。可重试的 HTTP `402` 用量窗口或 - 组织/工作区支出上限消息则仍归入 `rate_limit` 路径。 -- `billingBackoffHoursByProvider`:可选的按提供商划分的账单退避小时数覆盖。 + organization/workspace 支出上限消息则仍归入 `rate_limit` 路径。 +- `billingBackoffHoursByProvider`:可选的每个 provider 账单退避时长覆盖值(小时)。 - `billingMaxHours`:账单退避指数增长的上限(小时)(默认:`24`)。 - `authPermanentBackoffMinutes`:高置信度 `auth_permanent` 失败的基础退避时长(分钟)(默认:`10`)。 - `authPermanentMaxMinutes`:`auth_permanent` 退避增长的上限(分钟)(默认:`60`)。 -- `failureWindowHours`:用于退避计数器的滚动时间窗口(小时)(默认:`24`)。 -- `overloadedProfileRotations`:在切换到模型后备前,针对 overloaded 错误允许的同提供商 auth-profile 最大轮换次数(默认:`1`)。诸如 `ModelNotReadyException` 之类的提供商繁忙形态归入这里。 -- `overloadedBackoffMs`:在重试 overloaded 提供商/profile 轮换前的固定延迟(毫秒)(默认:`0`)。 -- `rateLimitedProfileRotations`:在切换到模型后备前,针对 rate-limit 错误允许的同提供商 auth-profile 最大轮换次数(默认:`1`)。该 rate-limit 桶包括提供商形态的文本,例如 `Too many concurrent requests`、`ThrottlingException`、`concurrency limit reached`、`workers_ai ... quota limit exceeded` 和 `resource exhausted`。 +- `failureWindowHours`:用于退避计数器的滚动窗口(小时)(默认:`24`)。 +- `overloadedProfileRotations`:对于过载错误,在切换到模型回退之前,同一 provider 的 auth-profile 允许的最大轮换次数(默认:`1`)。诸如 `ModelNotReadyException` 之类的 provider 忙碌形态会归入这里。 +- `overloadedBackoffMs`:在重试过载的 provider/profile 轮换前的固定延迟(毫秒)(默认:`0`)。 +- `rateLimitedProfileRotations`:对于限流错误,在切换到模型回退之前,同一 provider 的 auth-profile 允许的最大轮换次数(默认:`1`)。该限流桶包括 provider 形态的文本,例如 `Too many concurrent requests`、`ThrottlingException`、`concurrency limit reached`、`workers_ai ... quota limit exceeded` 和 `resource exhausted`。 --- @@ -3549,8 +3554,8 @@ Secret refs 是增量能力:明文值仍然可用。 ``` - 默认日志文件:`/tmp/openclaw/openclaw-YYYY-MM-DD.log`。 -- 设置 `logging.file` 可使用稳定路径。 -- 使用 `--verbose` 时,`consoleLevel` 会提升到 `debug`。 +- 设置 `logging.file` 可使用固定路径。 +- 使用 `--verbose` 时,`consoleLevel` 会提升为 `debug`。 - `maxFileBytes`:在抑制写入前允许的最大日志文件大小(字节)(正整数;默认:`524288000` = 500 MB)。生产部署请使用外部日志轮转。 --- @@ -3588,20 +3593,20 @@ Secret refs 是增量能力:明文值仍然可用。 } ``` -- `enabled`:仪表输出的总开关(默认:`true`)。 -- `flags`:用于启用定向日志输出的标志字符串数组(支持诸如 `"telegram.*"` 或 `"*"` 之类的通配符)。 -- `stuckSessionWarnMs`:当会话保持在处理状态时,发出卡住会话警告的年龄阈值(毫秒)。 +- `enabled`:仪表输出总开关(默认:`true`)。 +- `flags`:用于启用定向日志输出的标志字符串数组(支持 `"telegram.*"` 或 `"*"` 这样的通配符)。 +- `stuckSessionWarnMs`:当会话仍处于处理中状态时,发出卡住会话警告的时长阈值(毫秒)。 - `otel.enabled`:启用 OpenTelemetry 导出管线(默认:`false`)。 -- `otel.endpoint`:OTel 导出的采集器 URL。 +- `otel.endpoint`:用于 OTel 导出的 collector URL。 - `otel.protocol`:`"http/protobuf"`(默认)或 `"grpc"`。 - `otel.headers`:随 OTel 导出请求发送的额外 HTTP/gRPC 元数据 headers。 -- `otel.serviceName`:资源属性中的服务名称。 -- `otel.traces` / `otel.metrics` / `otel.logs`:启用 trace、metrics 或日志导出。 -- `otel.sampleRate`:trace 采样率 `0`–`1`。 -- `otel.flushIntervalMs`:周期性 telemetry 刷新间隔(毫秒)。 -- `cacheTrace.enabled`:为嵌入式运行记录缓存跟踪快照(默认:`false`)。 +- `otel.serviceName`:资源属性的服务名称。 +- `otel.traces` / `otel.metrics` / `otel.logs`:启用 trace、metrics 或 log 导出。 +- `otel.sampleRate`:trace 采样率,范围 `0`–`1`。 +- `otel.flushIntervalMs`:定期刷出 telemetry 的间隔(毫秒)。 +- `cacheTrace.enabled`:记录内嵌运行的缓存跟踪快照(默认:`false`)。 - `cacheTrace.filePath`:缓存跟踪 JSONL 的输出路径(默认:`$OPENCLAW_STATE_DIR/logs/cache-trace.jsonl`)。 -- `cacheTrace.includeMessages` / `includePrompt` / `includeSystem`:控制缓存跟踪输出中包含哪些内容(默认全部为 `true`)。 +- `cacheTrace.includeMessages` / `includePrompt` / `includeSystem`:控制缓存跟踪输出中包含哪些内容(默认均为 `true`)。 --- @@ -3623,12 +3628,12 @@ Secret refs 是增量能力:明文值仍然可用。 } ``` -- `channel`:用于 npm/git 安装的发布渠道——`"stable"`、`"beta"` 或 `"dev"`。 +- `channel`:npm/git 安装的发布通道——`"stable"`、`"beta"` 或 `"dev"`。 - `checkOnStart`:Gateway 网关启动时检查 npm 更新(默认:`true`)。 - `auto.enabled`:为包安装启用后台自动更新(默认:`false`)。 -- `auto.stableDelayHours`:stable 渠道自动应用前的最小延迟(小时)(默认:`6`;最大:`168`)。 -- `auto.stableJitterHours`:stable 渠道额外的发布分散窗口(小时)(默认:`12`;最大:`168`)。 -- `auto.betaCheckIntervalHours`:beta 渠道检查运行频率(小时)(默认:`1`;最大:`24`)。 +- `auto.stableDelayHours`:稳定通道自动应用前的最短延迟(小时)(默认:`6`;最大:`168`)。 +- `auto.stableJitterHours`:稳定通道额外的发布扩散窗口(小时)(默认:`12`;最大:`168`)。 +- `auto.betaCheckIntervalHours`:beta 通道检查运行的频率(小时)(默认:`1`;最大:`24`)。 --- @@ -3661,22 +3666,22 @@ Secret refs 是增量能力:明文值仍然可用。 } ``` -- `enabled`:ACP 功能的全局门控(默认:`false`)。 -- `dispatch.enabled`:ACP 会话轮次分发的独立门控(默认:`true`)。设为 `false` 可在保留 ACP 命令可用的同时阻止执行。 -- `backend`:默认 ACP 运行时后端 id(必须匹配已注册的 ACP 运行时插件)。 -- `defaultAgent`:当生成操作未指定显式目标时,ACP 目标智能体 id 的后备值。 -- `allowedAgents`:允许用于 ACP 运行时会话的智能体 id allowlist;为空表示无额外限制。 -- `maxConcurrentSessions`:并发活动 ACP 会话的最大数量。 -- `stream.coalesceIdleMs`:流式文本的空闲合并刷新窗口(毫秒)。 -- `stream.maxChunkChars`:拆分流式分块投影前允许的最大分块大小。 -- `stream.repeatSuppression`:抑制每轮中重复的状态/工具行(默认:`true`)。 -- `stream.deliveryMode`:`"live"` 为增量流式传输;`"final_only"` 则缓冲到轮次终止事件为止。 +- `enabled`:全局 ACP 功能开关(默认:`false`)。 +- `dispatch.enabled`:ACP 会话轮次分发的独立开关(默认:`true`)。设为 `false` 可在保留 ACP 命令可用的同时阻止执行。 +- `backend`:默认 ACP runtime backend id(必须与已注册的 ACP runtime 插件匹配)。 +- `defaultAgent`:当派生未指定显式目标时,ACP 默认的目标智能体 id。 +- `allowedAgents`:允许用于 ACP runtime 会话的智能体 id 列表;空列表表示不做额外限制。 +- `maxConcurrentSessions`:同时活动的 ACP 会话最大数量。 +- `stream.coalesceIdleMs`:流式文本的空闲合并刷出窗口(毫秒)。 +- `stream.maxChunkChars`:在拆分流式块投影前允许的最大块大小。 +- `stream.repeatSuppression`:每轮抑制重复的状态/工具行(默认:`true`)。 +- `stream.deliveryMode`:`"live"` 表示增量流式输出;`"final_only"` 表示缓冲到轮次终结事件后再输出。 - `stream.hiddenBoundarySeparator`:隐藏工具事件之后、可见文本之前的分隔符(默认:`"paragraph"`)。 -- `stream.maxOutputChars`:每个 ACP 轮次可投影的最大助手输出字符数。 -- `stream.maxSessionUpdateChars`:可投影 ACP 状态/更新行的最大字符数。 -- `stream.tagVisibility`:记录流式事件中标签名到布尔可见性覆盖的映射。 -- `runtime.ttlMinutes`:ACP 会话工作进程在可被清理前的空闲 TTL(分钟)。 -- `runtime.installCommand`:在引导 ACP 运行时环境时运行的可选安装命令。 +- `stream.maxOutputChars`:每个 ACP 轮次投影的助手输出最大字符数。 +- `stream.maxSessionUpdateChars`:投影 ACP 状态/更新行的最大字符数。 +- `stream.tagVisibility`:标签名称到布尔可见性覆盖的映射记录,用于流式事件。 +- `runtime.ttlMinutes`:ACP 会话工作进程在符合清理条件前的空闲 TTL(分钟)。 +- `runtime.installCommand`:引导 ACP runtime 环境时运行的可选安装命令。 --- @@ -3692,11 +3697,11 @@ Secret refs 是增量能力:明文值仍然可用。 } ``` -- `cli.banner.taglineMode` 控制横幅标语样式: - - `"random"`(默认):轮换的有趣/季节性标语。 - - `"default"`:固定的中性标语(`All your chats, one OpenClaw.`)。 - - `"off"`:不显示标语文本(仍显示横幅标题/版本)。 -- 若要隐藏整个横幅(而不仅是标语),请设置环境变量 `OPENCLAW_HIDE_BANNER=1`。 +- `cli.banner.taglineMode` 控制 banner 标语样式: + - `"random"`(默认):轮换显示有趣/季节性标语。 + - `"default"`:固定中性标语(`All your chats, one OpenClaw.`)。 + - `"off"`:不显示标语文本(仍显示 banner 标题/版本)。 +- 若要隐藏整个 banner(而不只是标语),请设置环境变量 `OPENCLAW_HIDE_BANNER=1`。 --- @@ -3720,7 +3725,7 @@ Secret refs 是增量能力:明文值仍然可用。 ## 身份 -请参见 [智能体默认值](#agent-defaults) 下 `agents.list` 的 identity 字段。 +请参见 [智能体默认值](#agent-defaults) 下的 `agents.list` 身份字段。 --- @@ -3755,7 +3760,7 @@ Secret refs 是增量能力:明文值仍然可用。 cron: { enabled: true, maxConcurrentRuns: 2, - webhook: "https://example.invalid/legacy", // 已弃用:用于已存储 notify:true 作业的后备值 + webhook: "https://example.invalid/legacy", // 已弃用:供已存储的 notify:true 任务使用的回退值 webhookToken: "replace-with-dedicated-token", // 可选:用于出站 webhook 认证的 bearer token sessionRetention: "24h", // 时长字符串或 false runLog: { @@ -3766,11 +3771,11 @@ Secret refs 是增量能力:明文值仍然可用。 } ``` -- `sessionRetention`:在从 `sessions.json` 修剪前,保留已完成隔离 cron 运行会话的时长。也控制已归档已删除 cron 转录的清理。默认:`24h`;设为 `false` 可禁用。 -- `runLog.maxBytes`:每个运行日志文件(`cron/runs/.jsonl`)在触发修剪前允许的最大大小。默认:`2_000_000` 字节。 +- `sessionRetention`:在从 `sessions.json` 中修剪前,保留已完成隔离 cron 运行会话的时长。也控制已归档且已删除的 cron 转录内容清理。默认:`24h`;设为 `false` 可禁用。 +- `runLog.maxBytes`:每个运行日志文件(`cron/runs/.jsonl`)在触发修剪前的最大大小。默认:`2_000_000` 字节。 - `runLog.keepLines`:触发运行日志修剪时保留的最新行数。默认:`2000`。 -- `webhookToken`:用于 cron webhook POST 投递(`delivery.mode = "webhook"`)的 bearer token;若省略则不发送认证 header。 -- `webhook`:已弃用的旧版后备 webhook URL(http/https),仅用于仍保留 `notify: true` 的已存储作业。 +- `webhookToken`:用于 cron webhook POST 投递(`delivery.mode = "webhook"`)的 bearer token;如果省略,则不会发送认证 header。 +- `webhook`:已弃用的旧版回退 webhook URL(http/https),仅供仍设置了 `notify: true` 的已存储任务使用。 ### `cron.retry` @@ -3786,11 +3791,11 @@ Secret refs 是增量能力:明文值仍然可用。 } ``` -- `maxAttempts`:一次性作业在瞬态错误下的最大重试次数(默认:`3`;范围:`0`–`10`)。 +- `maxAttempts`:一次性任务在瞬时错误上的最大重试次数(默认:`3`;范围:`0`–`10`)。 - `backoffMs`:每次重试尝试的退避延迟数组(毫秒)(默认:`[30000, 60000, 300000]`;1–10 个条目)。 -- `retryOn`:触发重试的错误类型——`"rate_limit"`、`"overloaded"`、`"network"`、`"timeout"`、`"server_error"`。省略时会对所有瞬态类型进行重试。 +- `retryOn`:触发重试的错误类型——`"rate_limit"`、`"overloaded"`、`"network"`、`"timeout"`、`"server_error"`。省略时会对所有瞬时类型进行重试。 -仅适用于一次性 cron 作业。周期性作业使用单独的失败处理方式。 +仅适用于一次性 cron 任务。周期性任务使用单独的失败处理机制。 ### `cron.failureAlert` @@ -3808,10 +3813,10 @@ Secret refs 是增量能力:明文值仍然可用。 } ``` -- `enabled`:为 cron 作业启用失败告警(默认:`false`)。 -- `after`:触发告警前所需的连续失败次数(正整数,最小值:`1`)。 -- `cooldownMs`:同一作业重复告警之间的最小间隔(毫秒)(非负整数)。 -- `mode`:投递模式——`"announce"` 通过渠道消息发送;`"webhook"` 向已配置 webhook 发送 POST 请求。 +- `enabled`:启用 cron 任务失败告警(默认:`false`)。 +- `after`:在触发告警前允许的连续失败次数(正整数,最小值:`1`)。 +- `cooldownMs`:同一任务重复告警之间的最短间隔(毫秒)(非负整数)。 +- `mode`:投递模式——`"announce"` 通过渠道消息发送;`"webhook"` 向已配置的 webhook 发送 POST 请求。 - `accountId`:用于限定告警投递范围的可选账号或渠道 id。 ### `cron.failureDestination` @@ -3829,16 +3834,16 @@ Secret refs 是增量能力:明文值仍然可用。 } ``` -- 所有作业共用的 cron 失败通知默认目标。 -- `mode`:`"announce"` 或 `"webhook"`;当存在足够的目标数据时,默认值为 `"announce"`。 -- `channel`:announce 投递的渠道覆盖。`"last"` 会复用上次已知的投递渠道。 -- `to`:显式的 announce 目标或 webhook URL。webhook 模式下必填。 -- `accountId`:可选的投递账号覆盖。 -- 每作业的 `delivery.failureDestination` 会覆盖该全局默认值。 -- 当既未设置全局也未设置每作业失败目标时,已通过 `announce` 投递的作业在失败时会回退到其主 announce 目标。 -- `delivery.failureDestination` 仅支持 `sessionTarget="isolated"` 的作业,除非该作业的主 `delivery.mode` 为 `"webhook"`。 +- 所有任务共用的 cron 失败通知默认目标。 +- `mode`:`"announce"` 或 `"webhook"`;当存在足够目标数据时,默认值为 `"announce"`。 +- `channel`:announce 投递的渠道覆盖值。`"last"` 会复用最近一次已知的投递渠道。 +- `to`:显式的 announce 目标或 webhook URL。在 webhook 模式下为必填。 +- `accountId`:可选的投递账号覆盖值。 +- 每个任务的 `delivery.failureDestination` 会覆盖这个全局默认值。 +- 如果既未设置全局失败目标,也未设置每任务失败目标,则已经通过 `announce` 投递的任务会在失败时回退到其主 announce 目标。 +- `delivery.failureDestination` 仅支持 `sessionTarget="isolated"` 的任务,除非该任务的主 `delivery.mode` 为 `"webhook"`。 -参见 [Cron 作业](/zh-CN/automation/cron-jobs)。隔离的 cron 执行会作为[后台任务](/zh-CN/automation/tasks)进行跟踪。 +参见 [Cron Jobs](/zh-CN/automation/cron-jobs)。隔离的 cron 执行会作为[后台任务](/zh-CN/automation/tasks)进行跟踪。 --- @@ -3846,34 +3851,34 @@ Secret refs 是增量能力:明文值仍然可用。 在 `tools.media.models[].args` 中展开的模板占位符: -| 变量 | 说明 | -| ------------------ | ------------------------------------- | -| `{{Body}}` | 完整入站消息正文 | -| `{{RawBody}}` | 原始正文(无历史/发送者包装) | -| `{{BodyStripped}}` | 去除群组 mentions 后的正文 | -| `{{From}}` | 发送者标识符 | -| `{{To}}` | 目标标识符 | -| `{{MessageSid}}` | 渠道消息 id | -| `{{SessionId}}` | 当前会话 UUID | -| `{{IsNewSession}}` | 新建会话时为 `"true"` | -| `{{MediaUrl}}` | 入站媒体伪 URL | -| `{{MediaPath}}` | 本地媒体路径 | -| `{{MediaType}}` | 媒体类型(image/audio/document/…) | -| `{{Transcript}}` | 音频转录 | -| `{{Prompt}}` | CLI 条目的已解析媒体提示 | -| `{{MaxChars}}` | CLI 条目的已解析最大输出字符数 | -| `{{ChatType}}` | `"direct"` 或 `"group"` | -| `{{GroupSubject}}` | 群组主题(尽力而为) | -| `{{GroupMembers}}` | 群组成员预览(尽力而为) | -| `{{SenderName}}` | 发送者显示名(尽力而为) | -| `{{SenderE164}}` | 发送者电话号码(尽力而为) | -| `{{Provider}}` | 提供商提示(whatsapp、telegram、discord 等) | +| 变量 | 描述 | +| ------------------ | ------------------------------------------------- | +| `{{Body}}` | 完整的传入消息正文 | +| `{{RawBody}}` | 原始正文(不含历史记录/发送者包装) | +| `{{BodyStripped}}` | 去除了群组提及的正文 | +| `{{From}}` | 发送者标识符 | +| `{{To}}` | 目标标识符 | +| `{{MessageSid}}` | 渠道消息 id | +| `{{SessionId}}` | 当前会话 UUID | +| `{{IsNewSession}}` | 新会话创建时为 `"true"` | +| `{{MediaUrl}}` | 传入媒体伪 URL | +| `{{MediaPath}}` | 本地媒体路径 | +| `{{MediaType}}` | 媒体类型(image/audio/document/…) | +| `{{Transcript}}` | 音频转录文本 | +| `{{Prompt}}` | 为 CLI 条目解析后的媒体提示词 | +| `{{MaxChars}}` | 为 CLI 条目解析后的最大输出字符数 | +| `{{ChatType}}` | `"direct"` 或 `"group"` | +| `{{GroupSubject}}` | 群组主题(尽力获取) | +| `{{GroupMembers}}` | 群成员预览(尽力获取) | +| `{{SenderName}}` | 发送者显示名称(尽力获取) | +| `{{SenderE164}}` | 发送者电话号码(尽力获取) | +| `{{Provider}}` | provider 提示(whatsapp、telegram、discord 等) | --- ## 配置包含(`$include`) -将配置拆分到多个文件中: +将配置拆分为多个文件: ```json5 // ~/.openclaw/openclaw.json @@ -3888,14 +3893,14 @@ Secret refs 是增量能力:明文值仍然可用。 **合并行为:** -- 单文件:替换所在的包含对象。 +- 单文件:替换其所在的包含对象。 - 文件数组:按顺序深度合并(后者覆盖前者)。 -- 同级键:在 includes 之后合并(覆盖被包含的值)。 -- 嵌套 includes:最多 10 层深。 -- 路径:相对于包含它的文件解析,但必须保持在顶层配置目录(`openclaw.json` 的 `dirname`)内。仅当绝对路径/`../` 形式最终仍解析到该边界内时才允许。 -- 仅更改由单文件 include 支持的某个顶层 section 的 OpenClaw 自有写入,会直写到该被包含文件。例如,`plugins install` 会将 `plugins: { $include: "./plugins.json5" }` 更新到 `plugins.json5` 中,并保持 `openclaw.json` 不变。 -- 根级 includes、include 数组,以及带同级覆盖的 includes 对 OpenClaw 自有写入来说是只读的;此类写入会以失败关闭方式处理,而不是将配置展平。 -- 错误:对于缺失文件、解析错误和循环 include,会给出清晰提示。 +- 同级键:在 include 之后合并(覆盖被包含的值)。 +- 嵌套 include:最多支持 10 层。 +- 路径:相对于包含它的文件解析,但必须保持在顶层配置目录(`openclaw.json` 的 `dirname`)内。仅当绝对路径/`../` 形式最终仍解析到该边界内时才允许使用。 +- 由 OpenClaw 发起、且只更改由单文件 include 支撑的某个顶层 section 的写入操作,会直接写回该被包含文件。例如,`plugins install` 会将 `plugins: { $include: "./plugins.json5" }` 更新到 `plugins.json5` 中,并保持 `openclaw.json` 不变。 +- 对于根级 include、include 数组,以及带有同级覆盖的 include,OpenClaw 发起的写入均为只读;这些写入会以关闭方式失败,而不是将配置展平。 +- 错误:对缺失文件、解析错误和循环 include 提供清晰的报错信息。 --- diff --git a/docs/zh-CN/help/testing.md b/docs/zh-CN/help/testing.md index 367e24a16..0ae2f841a 100644 --- a/docs/zh-CN/help/testing.md +++ b/docs/zh-CN/help/testing.md @@ -1,131 +1,132 @@ --- read_when: - 在本地或 CI 中运行测试 - - 为模型 / 提供商缺陷添加回归测试 + - 为模型/提供商缺陷添加回归测试 - 调试 Gateway 网关 + 智能体行为 -summary: 测试工具包:单元 / e2e / 实时测试套件、Docker 运行器,以及每类测试覆盖的内容 +summary: 测试工具包:单元 / e2e / 实时测试套件、Docker 运行器,以及各项测试的覆盖范围 title: 测试 x-i18n: - generated_at: "2026-04-23T05:53:22Z" + generated_at: "2026-04-23T06:40:48Z" model: gpt-5.4 provider: openai - source_hash: 8e4eabad0d4b899569336aa3d895c7be178455c9ad93927cb627c66d0f3df21d + source_hash: 6cb3c7e0644b66e5ca8bce51ec52e874ac8c1dfe02193afa3b34d5e6b5e8a355 source_path: help/testing.md workflow: 15 --- # 测试 -OpenClaw 有三套 `Vitest` 测试套件(单元 / 集成、e2e、实时)以及一小组 Docker 运行器。 +OpenClaw 有三个 Vitest 测试套件(单元/集成、e2e、实时)以及一小组 Docker 运行器。 本文档是一份“我们如何测试”的指南: -- 每个测试套件覆盖什么内容(以及它刻意 _不_ 覆盖什么) +- 每个测试套件覆盖什么(以及它刻意 _不_ 覆盖什么) - 常见工作流应运行哪些命令(本地、推送前、调试) -- 实时测试如何发现凭证并选择模型 / 提供商 -- 如何为真实世界中的模型 / 提供商问题添加回归测试 +- 实时测试如何发现凭证并选择模型/提供商 +- 如何为真实世界中的模型/提供商问题添加回归测试 ## 快速开始 -大多数情况下: +大多数时候: -- 完整门禁(预期在 push 前运行):`pnpm build && pnpm check && pnpm check:test-types && pnpm test` -- 在资源充足的机器上更快地运行本地完整测试套件:`pnpm test:max` -- 直接使用 `Vitest` 监听循环:`pnpm test:watch` -- 现在直接按文件定位也会路由扩展 / 渠道路径:`pnpm test extensions/discord/src/monitor/message-handler.preflight.test.ts` -- 当你在迭代单个失败用例时,优先先运行有针对性的测试。 -- 由 Docker 支持的 QA 站点:`pnpm qa:lab:up` -- 由 Linux VM 支持的 QA 通道:`pnpm openclaw qa suite --runner multipass --scenario channel-chat-baseline` +- 完整门禁(预期在推送前运行):`pnpm build && pnpm check && pnpm check:test-types && pnpm test` +- 在配置较宽裕的机器上更快地运行本地全套测试:`pnpm test:max` +- 直接使用 Vitest 监视循环:`pnpm test:watch` +- 直接按文件定位现在也会路由扩展/渠道路径:`pnpm test extensions/discord/src/monitor/message-handler.preflight.test.ts` +- 当你正在迭代处理单个失败问题时,优先进行有针对性的运行。 +- Docker 支持的 QA 站点:`pnpm qa:lab:up` +- Linux VM 支持的 QA 通道:`pnpm openclaw qa suite --runner multipass --scenario channel-chat-baseline` -当你修改了测试,或者想获得更多信心时: +当你修改了测试或希望获得更多信心时: - 覆盖率门禁:`pnpm test:coverage` -- E2E 测试套件:`pnpm test:e2e` +- E2E 套件:`pnpm test:e2e` -当你在调试真实提供商 / 模型时(需要真实凭证): +当你在调试真实提供商/模型时(需要真实凭证): -- 实时测试套件(模型 + Gateway 网关工具 / 图像探测):`pnpm test:live` -- 安静地只针对一个实时测试文件:`pnpm test:live -- src/agents/models.profiles.live.test.ts` -- Moonshot / Kimi 成本冒烟测试:设置 `MOONSHOT_API_KEY` 后,运行 +- 实时套件(模型 + Gateway 网关工具/图像探测):`pnpm test:live` +- 静默定位单个实时文件:`pnpm test:live -- src/agents/models.profiles.live.test.ts` +- Moonshot/Kimi 成本冒烟测试:设置 `MOONSHOT_API_KEY` 后,运行 `openclaw models list --provider moonshot --json`,然后针对 `moonshot/kimi-k2.6` 运行隔离的 `openclaw agent --local --session-id live-kimi-cost --message 'Reply exactly: KIMI_LIVE_OK' --thinking off --json` - 。验证 JSON 报告的是 Moonshot / K2.6,并且助手转录中存储了已归一化的 `usage.cost`。 + 。验证 JSON 报告的是 Moonshot/K2.6,并且助手转录存储了规范化的 `usage.cost`。 -提示:当你只需要一个失败用例时,优先通过下文描述的 allowlist 环境变量来缩小实时测试范围。 +提示:当你只需要一个失败用例时,优先使用下文描述的允许列表环境变量来缩小实时测试范围。 ## QA 专用运行器 -当你需要 QA-lab 级别的真实环境时,这些命令与主测试套件并列存在: +当你需要 QA-lab 级别的真实环境时,这些命令与主测试套件并列使用: -CI 会在专用工作流中运行 QA Lab。`Parity gate` 会在匹配的 PR 上以及通过手动触发时使用模拟提供商运行。`QA-Lab - All Lanes` 会在 `main` 上按夜间任务运行,也可通过手动触发运行,其中包含模拟 parity gate、实时 Matrix 通道,以及由 Convex 管理的实时 Telegram 通道,三者作为并行作业执行。`OpenClaw Release Checks` 会在发布批准前运行相同的通道。 +CI 会在专用工作流中运行 QA Lab。`Parity gate` 会在匹配的 PR 上运行,也可通过手动触发配合模拟提供商运行。`QA-Lab - All Lanes` 会在 `main` 上夜间运行,也可通过手动触发并行运行模拟 parity gate、实时 Matrix 通道以及由 Convex 管理的实时 Telegram 通道。`OpenClaw Release Checks` 会在发布批准前运行同样的通道。 - `pnpm openclaw qa suite` - - 直接在主机上运行由仓库支持的 QA 场景。 - - 默认情况下,会以隔离的 Gateway 网关 worker 并行运行多个选定场景。`qa-channel` 默认并发数为 4(受所选场景数量限制)。使用 `--concurrency ` 调整 worker 数量,或使用 `--concurrency 1` 运行旧式串行通道。 - - 任何场景失败时,退出码为非零。当你想保留产物但不希望退出失败时,使用 `--allow-failures`。 - - 支持 `live-frontier`、`mock-openai` 和 `aimock` 三种提供商模式。`aimock` 会启动一个基于本地 AIMock 的提供商服务器,用于实验性的 fixture 和协议模拟覆盖,而不会替代具备场景感知能力的 `mock-openai` 通道。 + - 直接在主机上运行基于仓库的 QA 场景。 + - 默认并行运行多个选定场景,并使用隔离的 Gateway 网关工作进程。`qa-channel` 默认并发数为 4(受所选场景数量限制)。使用 `--concurrency ` 调整工作进程数量,或使用 `--concurrency 1` 运行较旧的串行通道。 + - 任何场景失败时以非零状态退出。若你希望生成工件但不以失败退出,可使用 `--allow-failures`。 + - 支持提供商模式 `live-frontier`、`mock-openai` 和 `aimock`。 + `aimock` 会启动一个基于本地 AIMock 的提供商服务器,用于实验性的夹具和协议模拟覆盖,但不会替代场景感知的 `mock-openai` 通道。 - `pnpm openclaw qa suite --runner multipass` - - 在一次性 Multipass Linux VM 内运行同一套 QA 测试套件。 + - 在一次性 Multipass Linux VM 中运行同样的 QA 套件。 - 保持与主机上 `qa suite` 相同的场景选择行为。 - - 复用与 `qa suite` 相同的提供商 / 模型选择标志。 - - 实时运行会转发对来宾系统切实可用的受支持 QA 认证输入: + - 复用与 `qa suite` 相同的提供商/模型选择标志。 + - 实时运行会转发对来宾实用的受支持 QA 身份验证输入: 基于环境变量的提供商密钥、QA 实时提供商配置路径,以及存在时的 `CODEX_HOME`。 - - 输出目录必须保持在仓库根目录下,以便来宾系统能够通过挂载的工作区回写内容。 - - 会在 `.artifacts/qa-e2e/...` 下写入常规 QA 报告 + 摘要,以及 Multipass 日志。 + - 输出目录必须保持在仓库根目录下,以便来宾可以通过挂载的工作区回写。 + - 在 `.artifacts/qa-e2e/...` 下写入常规 QA 报告 + 摘要以及 Multipass 日志。 - `pnpm qa:lab:up` - - 启动由 Docker 支持的 QA 站点,以便进行偏操作员风格的 QA 工作。 + - 启动 Docker 支持的 QA 站点,用于运维风格的 QA 工作。 - `pnpm test:docker:npm-onboard-channel-agent` - - 从当前 checkout 构建一个 npm tarball,在 Docker 中全局安装,以非交互方式运行 OpenAI API key 新手引导,默认配置 Telegram,验证启用该 plugin 会按需安装运行时依赖,运行 doctor,并针对一个模拟的 OpenAI 端点运行一次本地智能体交互。 - - 使用 `OPENCLAW_NPM_ONBOARD_CHANNEL=discord` 可让相同的打包安装通道改用 Discord。 + - 从当前检出构建一个 npm tarball,在 Docker 中全局安装,运行非交互式 OpenAI API 密钥新手引导,默认配置 Telegram,验证启用插件会按需安装运行时依赖,运行 doctor,并针对模拟的 OpenAI 端点运行一次本地智能体回合。 + - 使用 `OPENCLAW_NPM_ONBOARD_CHANNEL=discord` 可用 Discord 运行同样的打包安装通道。 - `pnpm test:docker:bundled-channel-deps` - - 在 Docker 中打包并安装当前 OpenClaw 构建,启动已配置 OpenAI 的 Gateway 网关,然后通过配置编辑启用内置渠道 / plugins。 - - 验证设置发现流程不会提前安装未配置 plugin 的运行时依赖,验证首次配置后的 Gateway 网关或 doctor 运行会按需安装每个内置 plugin 的运行时依赖,并验证第二次重启不会重新安装已激活的依赖。 - - 还会安装一个已知的旧 npm 基线,在运行 `openclaw update --tag ` 之前启用 Telegram,并验证候选版本在更新后的 doctor 中会修复内置渠道运行时依赖,而无需测试框架侧的 postinstall 修复。 + - 在 Docker 中打包并安装当前 OpenClaw 构建,在已配置 OpenAI 的情况下启动 Gateway 网关,然后通过编辑配置启用内置渠道/插件。 + - 验证设置发现过程会使未配置的插件运行时依赖保持缺失状态,首次配置后的 Gateway 网关或 doctor 运行会按需安装每个内置插件的运行时依赖,而第二次重启不会重新安装已经激活的依赖。 + - 还会安装一个已知的较旧 npm 基线,在运行 `openclaw update --tag ` 之前启用 Telegram,并验证候选版本的更新后 doctor 会修复内置渠道运行时依赖,而无需由测试框架侧执行 postinstall 修复。 - `pnpm openclaw qa aimock` - 仅启动本地 AIMock 提供商服务器,用于直接协议冒烟测试。 - `pnpm openclaw qa matrix` - - 针对一个一次性、由 Docker 支持的 Tuwunel homeserver 运行 Matrix 实时 QA 通道。 - - 这个 QA 主机目前仅供仓库 / 开发环境使用。已打包的 OpenClaw 安装不附带 `qa-lab`,因此不会暴露 `openclaw qa`。 - - 仓库 checkout 会直接加载内置运行器,无需单独安装 plugin。 - - 会预配三个临时 Matrix 用户(`driver`、`sut`、`observer`)和一个私有房间,然后以真实的 Matrix plugin 作为 SUT 传输层启动一个 QA gateway 子进程。 - - 默认使用固定稳定版 Tuwunel 镜像 `ghcr.io/matrix-construct/tuwunel:v1.5.1`。当你需要测试不同镜像时,可使用 `OPENCLAW_QA_MATRIX_TUWUNEL_IMAGE` 覆盖。 + - 针对一次性的 Docker 支持 Tuwunel homeserver 运行 Matrix 实时 QA 通道。 + - 该 QA 主机目前仅供仓库/开发使用。打包后的 OpenClaw 安装不包含 `qa-lab`,因此不会暴露 `openclaw qa`。 + - 仓库检出会直接加载内置运行器;不需要单独的插件安装步骤。 + - 预配三个临时 Matrix 用户(`driver`、`sut`、`observer`)以及一个私有房间,然后以真实 Matrix 插件作为 SUT 传输启动一个 QA Gateway 网关子进程。 + - 默认使用固定稳定版 Tuwunel 镜像 `ghcr.io/matrix-construct/tuwunel:v1.5.1`。如需测试其他镜像,可使用 `OPENCLAW_QA_MATRIX_TUWUNEL_IMAGE` 覆盖。 - Matrix 不暴露共享凭证源标志,因为该通道会在本地预配一次性用户。 - - 会在 `.artifacts/qa-e2e/...` 下写入 Matrix QA 报告、摘要、观测事件产物,以及合并后的 stdout / stderr 输出日志。 + - 在 `.artifacts/qa-e2e/...` 下写入 Matrix QA 报告、摘要、观察到的事件工件,以及合并的 stdout/stderr 输出日志。 - `pnpm openclaw qa telegram` - - 使用来自环境变量的 driver 和 SUT bot token,针对一个真实的私有群组运行 Telegram 实时 QA 通道。 - - 需要 `OPENCLAW_QA_TELEGRAM_GROUP_ID`、`OPENCLAW_QA_TELEGRAM_DRIVER_BOT_TOKEN` 和 `OPENCLAW_QA_TELEGRAM_SUT_BOT_TOKEN`。群组 id 必须是 Telegram 聊天的数字 id。 - - 支持 `--credential-source convex` 以使用共享凭证池。默认使用环境变量模式,或设置 `OPENCLAW_QA_CREDENTIAL_SOURCE=convex` 以启用池化租约。 - - 任何场景失败时,退出码为非零。当你想保留产物但不希望退出失败时,使用 `--allow-failures`。 - - 需要同一私有群组中的两个不同 bot,且 SUT bot 需暴露 Telegram 用户名。 - - 为了实现稳定的 bot 对 bot 观测,请在 `@BotFather` 中为两个 bot 启用 Bot-to-Bot Communication Mode,并确保 driver bot 可以观测群组中的 bot 流量。 - - 会在 `.artifacts/qa-e2e/...` 下写入 Telegram QA 报告、摘要和观测消息产物。 + - 使用环境变量中的 driver 和 SUT 机器人令牌,针对真实私有群组运行 Telegram 实时 QA 通道。 + - 需要 `OPENCLAW_QA_TELEGRAM_GROUP_ID`、`OPENCLAW_QA_TELEGRAM_DRIVER_BOT_TOKEN` 和 `OPENCLAW_QA_TELEGRAM_SUT_BOT_TOKEN`。group id 必须是 Telegram 数字 chat id。 + - 支持 `--credential-source convex` 用于共享池化凭证。默认使用 env 模式,或设置 `OPENCLAW_QA_CREDENTIAL_SOURCE=convex` 以启用池化租约。 + - 任一场景失败时以非零状态退出。若你希望生成工件但不以失败退出,可使用 `--allow-failures`。 + - 需要两个不同的机器人位于同一个私有群组中,并且 SUT 机器人需要公开 Telegram 用户名。 + - 为了实现稳定的机器人到机器人观测,请在 `@BotFather` 中为两个机器人启用 Bot-to-Bot Communication Mode,并确保 driver 机器人可以观察群组中的机器人流量。 + - 在 `.artifacts/qa-e2e/...` 下写入 Telegram QA 报告、摘要和已观察消息工件。 -实时传输通道共享一份标准契约,以避免新传输方式发生漂移: +实时传输通道共享一个标准契约,以避免新传输发生漂移: -`qa-channel` 仍然是广义的合成 QA 测试套件,不属于实时传输覆盖矩阵的一部分。 +`qa-channel` 仍然是范围广泛的合成 QA 套件,不属于实时传输覆盖矩阵的一部分。 -| 通道 | Canary | 提及门控 | allowlist 屏蔽 | 顶层回复 | 重启恢复 | 线程后续跟进 | 线程隔离 | 反应观测 | 帮助命令 | -| ---- | ------ | -------- | -------------- | -------- | -------- | ------------ | -------- | -------- | -------- | -| Matrix | x | x | x | x | x | x | x | x | | -| Telegram | x | | | | | | | | x | +| Lane | Canary | Mention gating | Allowlist block | Top-level reply | Restart resume | Thread follow-up | Thread isolation | Reaction observation | Help command | +| -------- | ------ | -------------- | --------------- | --------------- | -------------- | ---------------- | ---------------- | -------------------- | ------------ | +| Matrix | x | x | x | x | x | x | x | x | | +| Telegram | x | | | | | | | | x | ### 通过 Convex 共享 Telegram 凭证(v1) -当为 `openclaw qa telegram` 启用 `--credential-source convex`(或 `OPENCLAW_QA_CREDENTIAL_SOURCE=convex`)时,QA lab 会从基于 Convex 的凭证池中获取一个独占租约,在通道运行期间为该租约发送心跳,并在关闭时释放租约。 +当为 `openclaw qa telegram` 启用 `--credential-source convex`(或 `OPENCLAW_QA_CREDENTIAL_SOURCE=convex`)时,QA lab 会从一个基于 Convex 的凭证池中获取独占租约,在通道运行期间为该租约发送心跳,并在关闭时释放该租约。 -参考用的 Convex 项目脚手架: +参考 Convex 项目脚手架: - `qa/convex-credential-broker/` 必需的环境变量: - `OPENCLAW_QA_CONVEX_SITE_URL`(例如 `https://your-deployment.convex.site`) -- 针对所选角色的一个 secret: - - `maintainer` 角色使用 `OPENCLAW_QA_CONVEX_SECRET_MAINTAINER` - - `ci` 角色使用 `OPENCLAW_QA_CONVEX_SECRET_CI` +- 为所选角色提供一个密钥: + - `OPENCLAW_QA_CONVEX_SECRET_MAINTAINER` 用于 `maintainer` + - `OPENCLAW_QA_CONVEX_SECRET_CI` 用于 `ci` - 凭证角色选择: - CLI:`--credential-role maintainer|ci` - - 环境变量默认值:`OPENCLAW_QA_CREDENTIAL_ROLE`(在 CI 中默认为 `ci`,否则默认为 `maintainer`) + - 环境变量默认值:`OPENCLAW_QA_CREDENTIAL_ROLE`(在 CI 中默认为 `ci`,否则为 `maintainer`) 可选环境变量: @@ -134,15 +135,14 @@ CI 会在专用工作流中运行 QA Lab。`Parity gate` 会在匹配的 PR 上 - `OPENCLAW_QA_CREDENTIAL_ACQUIRE_TIMEOUT_MS`(默认 `90000`) - `OPENCLAW_QA_CREDENTIAL_HTTP_TIMEOUT_MS`(默认 `15000`) - `OPENCLAW_QA_CONVEX_ENDPOINT_PREFIX`(默认 `/qa-credentials/v1`) -- `OPENCLAW_QA_CREDENTIAL_OWNER_ID`(可选的追踪 id) -- `OPENCLAW_QA_ALLOW_INSECURE_HTTP=1` 允许在仅限本地开发时使用 loopback `http://` Convex URL。 +- `OPENCLAW_QA_CREDENTIAL_OWNER_ID`(可选跟踪 id) +- `OPENCLAW_QA_ALLOW_INSECURE_HTTP=1` 允许仅用于本地开发的 loopback `http://` Convex URL。 -正常运行时,`OPENCLAW_QA_CONVEX_SITE_URL` 应使用 `https://`。 +`OPENCLAW_QA_CONVEX_SITE_URL` 在正常运行中应使用 `https://`。 -维护者管理员命令(池添加 / 删除 / 列表)必须特定使用 -`OPENCLAW_QA_CONVEX_SECRET_MAINTAINER`。 +维护者管理命令(池添加/删除/列出)必须专门使用 `OPENCLAW_QA_CONVEX_SECRET_MAINTAINER`。 -面向维护者的 CLI 辅助命令: +供维护者使用的 CLI 辅助命令: ```bash pnpm openclaw qa credentials add --kind telegram --payload-file qa/telegram-credential.json @@ -157,80 +157,80 @@ pnpm openclaw qa credentials remove --credential-id - `POST /acquire` - 请求:`{ kind, ownerId, actorRole, leaseTtlMs, heartbeatIntervalMs }` - 成功:`{ status: "ok", credentialId, leaseToken, payload, leaseTtlMs?, heartbeatIntervalMs? }` - - 耗尽 / 可重试:`{ status: "error", code: "POOL_EXHAUSTED" | "NO_CREDENTIAL_AVAILABLE", ... }` + - 资源耗尽/可重试:`{ status: "error", code: "POOL_EXHAUSTED" | "NO_CREDENTIAL_AVAILABLE", ... }` - `POST /heartbeat` - 请求:`{ kind, ownerId, actorRole, credentialId, leaseToken, leaseTtlMs }` - 成功:`{ status: "ok" }`(或空的 `2xx`) - `POST /release` - 请求:`{ kind, ownerId, actorRole, credentialId, leaseToken }` - 成功:`{ status: "ok" }`(或空的 `2xx`) -- `POST /admin/add`(仅限 maintainer secret) +- `POST /admin/add`(仅限 maintainer 密钥) - 请求:`{ kind, actorId, payload, note?, status? }` - 成功:`{ status: "ok", credential }` -- `POST /admin/remove`(仅限 maintainer secret) +- `POST /admin/remove`(仅限 maintainer 密钥) - 请求:`{ credentialId, actorId }` - 成功:`{ status: "ok", changed, credential }` - 活跃租约保护:`{ status: "error", code: "LEASE_ACTIVE", ... }` -- `POST /admin/list`(仅限 maintainer secret) +- `POST /admin/list`(仅限 maintainer 密钥) - 请求:`{ kind?, status?, includePayload?, limit? }` - 成功:`{ status: "ok", credentials, count }` -Telegram 类型的 payload 结构: +Telegram 类型的负载结构: - `{ groupId: string, driverToken: string, sutToken: string }` -- `groupId` 必须是 Telegram 聊天数字 id 的字符串。 -- 对于 `kind: "telegram"`,`admin/add` 会验证该结构,并拒绝格式不正确的 payload。 +- `groupId` 必须是数字形式的 Telegram chat id 字符串。 +- `admin/add` 会针对 `kind: "telegram"` 验证此结构,并拒绝格式错误的负载。 ### 向 QA 添加一个渠道 -向基于 Markdown 的 QA 系统中添加一个渠道,严格来说只需要两样东西: +向 Markdown QA 系统添加一个渠道需要且仅需要两样东西: -1. 该渠道的传输适配器。 -2. 一组用于验证该渠道契约的场景包。 +1. 一个用于该渠道的传输适配器。 +2. 一个用于验证该渠道契约的场景包。 -当共享的 `qa-lab` 主机能够承载该流程时,不要新增一个顶层 QA 命令根。 +当共享的 `qa-lab` 主机可以承载整个流程时,不要新增顶层 QA 命令根。 -`qa-lab` 负责共享的主机机制: +`qa-lab` 负责共享主机机制: - `openclaw qa` 命令根 -- 测试套件启动和拆除 -- worker 并发 -- 产物写入 +- 套件启动与清理 +- 工作进程并发 +- 工件写入 - 报告生成 - 场景执行 - 对旧版 `qa-channel` 场景的兼容别名 -运行器 plugins 负责传输契约: +运行器插件负责传输契约: -- `openclaw qa ` 如何挂载到共享的 `qa` 根命令之下 -- 如何为该传输方式配置 Gateway 网关 +- `openclaw qa ` 如何挂载在共享 `qa` 根命令之下 +- 如何为该传输配置 Gateway 网关 - 如何检查就绪状态 - 如何注入入站事件 - 如何观测出站消息 -- 如何暴露转录内容和归一化后的传输状态 +- 如何暴露转录和规范化的传输状态 - 如何执行由传输支持的操作 -- 如何处理传输特定的重置或清理逻辑 +- 如何处理传输特定的重置或清理 新渠道的最低接入门槛是: 1. 保持 `qa-lab` 作为共享 `qa` 根命令的所有者。 -2. 在共享的 `qa-lab` 主机接缝上实现该传输运行器。 -3. 将传输特定机制保留在运行器 plugin 或渠道 harness 内部。 +2. 在共享的 `qa-lab` 主机接缝上实现传输运行器。 +3. 将传输特定机制保留在运行器插件或渠道测试框架内部。 4. 将运行器挂载为 `openclaw qa `,而不是注册一个相互竞争的根命令。 - 运行器 plugin 应在 `openclaw.plugin.json` 中声明 `qaRunners`,并从 `runtime-api.ts` 导出匹配的 `qaRunnerCliRegistrations` 数组。 - 保持 `runtime-api.ts` 足够轻量;惰性 CLI 和运行器执行应保留在独立入口点之后。 -5. 在按主题划分的 `qa/scenarios/` 目录下编写或改造 Markdown 场景。 -6. 为新场景使用通用场景辅助函数。 -7. 除非仓库正在进行有意迁移,否则应保持现有兼容别名继续可用。 + 运行器插件应在 `openclaw.plugin.json` 中声明 `qaRunners`,并从 `runtime-api.ts` 导出匹配的 `qaRunnerCliRegistrations` 数组。 + 保持 `runtime-api.ts` 足够轻量;惰性 CLI 和运行器执行应放在独立入口点之后。 +5. 在按主题组织的 `qa/scenarios/` 目录下编写或调整 Markdown 场景。 +6. 为新场景使用通用场景辅助工具。 +7. 除非仓库正在进行有意迁移,否则保持现有兼容别名继续可用。 决策规则是严格的: -- 如果某个行为可以在 `qa-lab` 中表达一次,就把它放进 `qa-lab`。 -- 如果某个行为依赖于单一渠道传输方式,就把它保留在该运行器 plugin 或 plugin harness 中。 -- 如果某个场景需要一个多个渠道都可使用的新能力,应添加一个通用辅助函数,而不是在 `suite.ts` 中加入渠道特定分支。 -- 如果某个行为只对一种传输方式有意义,就让该场景保持传输特定性,并在场景契约中明确说明。 +- 如果某个行为可以在 `qa-lab` 中统一表达一次,就把它放在 `qa-lab` 中。 +- 如果某个行为依赖于某一个渠道传输,就把它保留在该运行器插件或插件测试框架中。 +- 如果一个场景需要多个渠道都能使用的新能力,应添加一个通用辅助工具,而不是在 `suite.ts` 中添加渠道特定分支。 +- 如果某个行为只对一种传输有意义,就让该场景保持传输特定,并在场景契约中明确说明。 -新场景的首选通用辅助函数名称是: +新场景推荐使用的通用辅助工具名称是: - `waitForTransportReady` - `waitForChannelReady` @@ -253,19 +253,18 @@ Telegram 类型的 payload 结构: - `formatConversationTranscript` - `resetBus` -新的渠道开发应使用通用辅助函数名称。 -兼容别名的存在是为了避免一次性强制迁移,而不是作为 -新场景编写的范式。 +新的渠道工作应使用这些通用辅助工具名称。 +兼容别名的存在是为了避免一次性迁移日,而不是作为新场景编写的范式。 -## 测试套件(各自运行位置与范围) +## 测试套件(各自运行位置) -可以把这些测试套件理解为“真实性逐步增加”(同时不稳定性 / 成本也逐步增加): +可以把这些套件理解为“真实度逐步提高”(同时波动性/成本也会提高): ### 单元 / 集成(默认) - 命令:`pnpm test` -- 配置:对现有按范围划分的 `Vitest` 项目执行十一个顺序分片运行(`vitest.full-*.config.ts`) -- 文件:`src/**/*.test.ts`、`packages/**/*.test.ts`、`test/**/*.test.ts` 下的核心 / 单元测试清单,以及 `vitest.unit.config.ts` 覆盖的白名单 `ui` Node 测试 +- 配置:针对现有按范围划分的 Vitest projects 运行十个顺序分片(`vitest.full-*.config.ts`) +- 文件:`src/**/*.test.ts`、`packages/**/*.test.ts`、`test/**/*.test.ts` 下的 core/unit 清单,以及 `vitest.unit.config.ts` 涵盖的白名单 `ui` node 测试 - 范围: - 纯单元测试 - 进程内集成测试(Gateway 网关认证、路由、工具、解析、配置) @@ -274,153 +273,153 @@ Telegram 类型的 payload 结构: - 在 CI 中运行 - 不需要真实密钥 - 应当快速且稳定 -- 项目说明: - - 未指定目标的 `pnpm test` 现在会运行十一个更小的分片配置(`core-unit-src`、`core-unit-security`、`core-unit-ui`、`core-unit-support`、`core-support-boundary`、`core-contracts`、`core-bundled`、`core-runtime`、`agentic`、`auto-reply`、`extensions`),而不是一个巨大的原生根项目进程。这样可以降低负载较高机器上的峰值 RSS,并避免 `auto-reply` / 扩展相关工作拖慢无关测试套件。 - - `pnpm test --watch` 仍然使用原生根 `vitest.config.ts` 项目图,因为多分片监听循环并不现实。 - - `pnpm test`、`pnpm test:watch` 和 `pnpm test:perf:imports` 现在会优先通过按范围划分的通道来处理显式文件 / 目录目标,因此 `pnpm test extensions/discord/src/monitor/message-handler.preflight.test.ts` 不必承担完整根项目启动的成本。 - - 当变更的 git 路径只涉及可路由的源码 / 测试文件时,`pnpm test:changed` 会将这些变更路径扩展到相同的按范围划分通道;配置 / 设置编辑仍会回退到更广泛的根项目重跑。 - - `pnpm check:changed` 是针对小范围开发工作的常规智能本地门禁。它会将 diff 分类为核心、核心测试、扩展、扩展测试、应用、文档、发布元数据和工具,然后运行相应的类型检查 / lint / 测试通道。公开的 Plugin SDK 和 plugin 契约变更会包含扩展验证,因为扩展依赖这些核心契约。仅涉及发布元数据的版本变更会运行针对性的版本 / 配置 / 根依赖检查,而不是完整测试套件,并带有一个防护机制,用于拒绝顶层版本字段之外的 `package` 变更。 - - 来自智能体、命令、plugins、`auto-reply` 辅助模块、`plugin-sdk` 以及类似纯工具区域的轻导入单元测试,会路由到 `unit-fast` 通道,该通道会跳过 `test/setup-openclaw-runtime.ts`;有状态 / 运行时负担较重的文件则保留在现有通道中。 - - 部分选定的 `plugin-sdk` 和 `commands` 辅助源码文件也会让 changed 模式运行映射到这些轻量通道中的显式同级测试,因此辅助文件编辑不必为该目录重跑完整的重型测试套件。 - - `auto-reply` 现在有三个专用桶:顶层核心辅助函数、顶层 `reply.*` 集成测试,以及 `src/auto-reply/reply/**` 子树。这样可以让最重的回复 harness 工作不影响轻量级的状态 / 分块 / token 测试。 +- Projects 说明: + - 未指定目标的 `pnpm test` 现在会运行 11 个更小的分片配置(`core-unit-src`、`core-unit-security`、`core-unit-ui`、`core-unit-support`、`core-support-boundary`、`core-contracts`、`core-bundled`、`core-runtime`、`agentic`、`auto-reply`、`extensions`),而不是运行一个巨大的原生 root-project 进程。这样可以降低高负载机器上的峰值 RSS,并避免 auto-reply/extension 工作拖累无关套件。 + - `pnpm test --watch` 仍然使用原生根 `vitest.config.ts` project graph,因为多分片 watch 循环并不现实。 + - `pnpm test`、`pnpm test:watch` 和 `pnpm test:perf:imports` 会先通过按范围划分的通道来路由显式文件/目录目标,因此 `pnpm test extensions/discord/src/monitor/message-handler.preflight.test.ts` 不必承担完整 root project 启动成本。 + - 当变更 diff 仅触及可路由的源文件/测试文件时,`pnpm test:changed` 会将变更后的 git 路径展开到相同的按范围划分通道;配置/设置编辑仍会回退到更广泛的 root-project 重跑。 + - `pnpm check:changed` 是窄范围工作的常规智能本地门禁。它会将 diff 分类到 core、core tests、extensions、extension tests、apps、docs、发布元数据和工具中,然后运行匹配的 typecheck/lint/test 通道。公开的插件 SDK 和插件契约变更会包含 extension 验证,因为 extensions 依赖这些 core 契约。仅包含发布元数据的版本升级会运行针对性的版本/配置/根依赖检查,而不是完整套件,同时带有一个保护措施,拒绝顶层 version 字段以外的 package 变更。 + - 来自 agents、commands、plugins、auto-reply helpers、`plugin-sdk` 以及类似纯工具区域的轻导入单元测试会通过 `unit-fast` 通道路由,该通道会跳过 `test/setup-openclaw-runtime.ts`;有状态/运行时较重的文件则保留在现有通道中。 + - 选定的 `plugin-sdk` 和 `commands` 辅助源文件也会在 changed 模式运行时映射到这些轻量通道中的显式同级测试,因此辅助工具编辑无需为该目录重跑完整的重型套件。 + - `auto-reply` 现在有三个专用分桶:顶层 core helpers、顶层 `reply.*` 集成测试,以及 `src/auto-reply/reply/**` 子树。这样可以让最重的 reply 测试框架工作远离那些便宜的 status/chunk/token 测试。 - 嵌入式运行器说明: - 当你修改消息工具发现输入或压缩运行时上下文时, - 请保持两个层级的覆盖。 - - 为纯路由 / 归一化边界添加聚焦的辅助函数回归测试。 - - 同时也要保持嵌入式运行器集成测试套件健康: + 要保持两个层级的覆盖。 + - 为纯路由/规范化边界添加聚焦的辅助工具回归测试。 + - 同时也要保持嵌入式运行器集成套件健康: `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`,并在根项目、e2e 和实时配置中使用非隔离运行器。 - - 根 UI 通道保留其 `jsdom` 设置和优化器,但现在也运行在共享的非隔离运行器之上。 - - 每个 `pnpm test` 分片都从共享 `Vitest` 配置继承相同的 `threads` + `isolate: false` 默认值。 - - 共享的 `scripts/run-vitest.mjs` 启动器现在默认还会为 `Vitest` 子 Node 进程添加 `--no-maglev`,以减少大型本地运行期间的 V8 编译抖动。如果你需要对比原生 V8 行为,可设置 `OPENCLAW_VITEST_ENABLE_MAGLEV=1`。 + - 基础 Vitest 配置现在默认使用 `threads`。 + - 共享 Vitest 配置还固定了 `isolate: false`,并在根 projects、e2e 和实时配置中使用非隔离运行器。 + - 根 UI 通道保留其 `jsdom` 设置和优化器,但现在也在共享的非隔离运行器上运行。 + - 每个 `pnpm test` 分片都继承了共享 Vitest 配置中的相同 `threads` + `isolate: false` 默认值。 + - 共享的 `scripts/run-vitest.mjs` 启动器现在还会默认给 Vitest 子 Node 进程添加 `--no-maglev`,以减少大型本地运行期间的 V8 编译抖动。如果你需要与原生 V8 行为对比,可设置 `OPENCLAW_VITEST_ENABLE_MAGLEV=1`。 - 快速本地迭代说明: - - `pnpm changed:lanes` 会显示某个 diff 触发了哪些架构通道。 - - pre-commit hook 会在对已暂存内容执行格式化 / lint 后运行 `pnpm check:changed --staged`,因此纯核心提交不会承担扩展测试成本,除非它们触及面向扩展的公开契约。仅涉及发布元数据的提交会保留在针对性的版本 / 配置 / 根依赖通道中。 - - 如果完全相同的已暂存变更集已经通过同等或更强的门禁验证,可使用 `scripts/committer --fast "" ` 只跳过 changed-scope hook 的重新运行。已暂存格式化 / lint 仍会运行。请在交接说明中提及已完成的门禁。这在独立重跑某个不稳定 hook 失败并以有范围证明通过之后也适用。 - - 当变更路径可以清晰映射到更小的测试套件时,`pnpm test:changed` 会通过按范围划分的通道进行路由。 + - `pnpm changed:lanes` 会显示某个 diff 会触发哪些架构通道。 + - pre-commit hook 会在对暂存内容完成格式化/lint 后运行 `pnpm check:changed --staged`,因此纯 core 提交不会承担 extension 测试成本,除非它们触及面向 extension 的公开契约。仅发布元数据提交会保留在针对性的版本/配置/根依赖通道。 + - 如果完全相同的暂存变更集已经通过同等或更强门禁验证,可以使用 `scripts/committer --fast "" ` 仅跳过 changed-scope hook 的重跑。暂存格式化/lint 仍会运行。请在交接中说明已完成的门禁。在孤立的 hook 偶发失败被重跑并通过、且有范围化证据时,这样做也是可以接受的。 + - 当变更路径可以清晰映射到较小套件时,`pnpm test:changed` 会通过按范围划分的通道进行路由。 - `pnpm test:max` 和 `pnpm test:changed:max` 保持相同的路由行为,只是使用更高的 worker 上限。 - - 本地 worker 自动扩缩容策略现在刻意更保守,并且在主机负载平均值已经较高时也会回退,因此默认情况下多个并发 `Vitest` 运行对系统的冲击更小。 - - 基础 `Vitest` 配置将项目 / 配置文件标记为 `forceRerunTriggers`,以便测试接线变更时 changed 模式重跑仍然正确。 - - 在受支持主机上,配置会保持启用 `OPENCLAW_VITEST_FS_MODULE_CACHE`;如果你想为直接性能分析指定一个明确的缓存位置,可设置 `OPENCLAW_VITEST_FS_MODULE_CACHE_PATH=/abs/path`。 + - 本地 worker 自动扩缩现在刻意更保守,并且当主机负载平均值已经很高时也会回退,因此多个并发 Vitest 运行默认造成的影响会更小。 + - 基础 Vitest 配置将 projects/config 文件标记为 `forceRerunTriggers`,从而在测试接线变更时保持 changed 模式重跑正确。 + - 在受支持的主机上,该配置会保持启用 `OPENCLAW_VITEST_FS_MODULE_CACHE`;如果你想为直接性能分析指定一个明确的缓存位置,可设置 `OPENCLAW_VITEST_FS_MODULE_CACHE_PATH=/abs/path`。 - 性能调试说明: - - `pnpm test:perf:imports` 会启用 `Vitest` 导入耗时报告以及导入明细输出。 - - `pnpm test:perf:imports:changed` 会将同样的性能分析视图限定到自 `origin/main` 以来变更的文件。 -- `pnpm test:perf:changed:bench -- --ref ` 会将按路由执行的 `test:changed` 与该已提交 diff 的原生根项目路径进行比较,并输出墙钟时间以及 macOS 最大 RSS。 -- `pnpm test:perf:changed:bench -- --worktree` 会通过将变更文件列表路由到 `scripts/test-projects.mjs` 和根 `Vitest` 配置,对当前脏工作树进行基准测试。 - - `pnpm test:perf:profile:main` 会写出一个主线程 CPU profile,用于分析 `Vitest` / `Vite` 启动和转换开销。 - - `pnpm test:perf:profile:runner` 会在禁用文件并行时,为单元测试套件写出运行器 CPU + heap profile。 + - `pnpm test:perf:imports` 会启用 Vitest 导入时长报告以及导入拆分输出。 + - `pnpm test:perf:imports:changed` 会将相同的性能分析视图限定到自 `origin/main` 以来发生变更的文件。 +- `pnpm test:perf:changed:bench -- --ref ` 会针对该提交 diff,比对经路由的 `test:changed` 与原生 root-project 路径,并输出墙钟时间以及 macOS 最大 RSS。 +- `pnpm test:perf:changed:bench -- --worktree` 会通过将变更文件列表路由到 `scripts/test-projects.mjs` 和根 Vitest 配置,对当前脏工作树进行基准测试。 + - `pnpm test:perf:profile:main` 会为 Vitest/Vite 启动和转换开销写入主线程 CPU profile。 + - `pnpm test:perf:profile:runner` 会在禁用文件并行的情况下,为单元测试套件写入运行器 CPU+heap profile。 ### 稳定性(Gateway 网关) - 命令:`pnpm test:stability:gateway` -- 配置:`vitest.gateway.config.ts`,强制单 worker +- 配置:`vitest.gateway.config.ts`,强制使用一个 worker - 范围: - - 启动一个真实的 loopback Gateway 网关,并默认启用诊断 + - 启动一个真实的 loopback Gateway 网关,默认启用诊断 - 通过诊断事件路径驱动合成的 Gateway 网关消息、内存和大负载抖动 - 通过 Gateway 网关 WS RPC 查询 `diagnostics.stability` - - 覆盖诊断稳定性 bundle 持久化辅助函数 - - 断言记录器保持有界、合成 RSS 采样保持在压力预算之下,并且每个会话的队列深度最终回落到零 + - 覆盖诊断稳定性包持久化辅助工具 + - 断言记录器保持有界、合成 RSS 采样低于压力预算,并且每个会话的队列深度会回落为零 - 预期: - - 可安全运行于 CI,且不需要密钥 - - 这是一个用于稳定性回归跟进的窄范围通道,不可替代完整的 Gateway 网关测试套件 + - 对 CI 安全且无需密钥 + - 这是用于稳定性回归跟进的窄范围通道,不是完整 Gateway 网关套件的替代品 ### E2E(Gateway 网关冒烟) - 命令:`pnpm test:e2e` - 配置:`vitest.e2e.config.ts` -- 文件:`src/**/*.e2e.test.ts`、`test/**/*.e2e.test.ts` +- 文件:`src/**/*.e2e.test.ts`、`test/**/*.e2e.test.ts`,以及 `extensions/` 下的内置插件 E2E 测试 - 运行时默认值: - - 使用 `Vitest` `threads` 且 `isolate: false`,与仓库其余部分保持一致。 - - 使用自适应 worker(CI:最多 2,本地:默认 1)。 + - 使用 Vitest `threads` 和 `isolate: false`,与仓库其余部分保持一致。 + - 使用自适应 workers(CI:最多 2 个,本地:默认 1 个)。 - 默认以静默模式运行,以减少控制台 I/O 开销。 -- 常用覆盖项: - - `OPENCLAW_E2E_WORKERS=`:强制指定 worker 数量(上限为 16)。 - - `OPENCLAW_E2E_VERBOSE=1`:重新启用详细控制台输出。 +- 常用覆盖选项: + - `OPENCLAW_E2E_WORKERS=` 强制指定 worker 数量(上限为 16)。 + - `OPENCLAW_E2E_VERBOSE=1` 重新启用详细控制台输出。 - 范围: - 多实例 Gateway 网关端到端行为 - - WebSocket / HTTP 接口、节点配对以及更重的网络交互 + - WebSocket/HTTP 表面、节点配对以及更重的网络行为 - 预期: - 在 CI 中运行(当流水线中启用时) - 不需要真实密钥 - - 比单元测试涉及更多活动部件(可能更慢) + - 比单元测试包含更多可变部件(可能更慢) ### E2E:OpenShell 后端冒烟 - 命令:`pnpm test:e2e:openshell` -- 文件:`test/openshell-sandbox.e2e.test.ts` +- 文件:`extensions/openshell/src/backend.e2e.test.ts` - 范围: - 通过 Docker 在主机上启动一个隔离的 OpenShell Gateway 网关 - - 从一个临时本地 Dockerfile 创建沙箱 - - 通过真实的 `sandbox ssh-config` + SSH 执行来测试 OpenClaw 的 OpenShell 后端 - - 通过沙箱 fs bridge 验证远端规范文件系统行为 + - 从临时本地 Dockerfile 创建一个沙箱 + - 通过真实的 `sandbox ssh-config` + SSH exec 练习 OpenClaw 的 OpenShell 后端 + - 通过沙箱 fs bridge 验证远程规范化文件系统行为 - 预期: - - 仅在显式启用时运行;不属于默认 `pnpm test:e2e` 执行的一部分 + - 仅按需启用;不属于默认 `pnpm test:e2e` 运行的一部分 - 需要本地 `openshell` CLI 和可用的 Docker daemon - 使用隔离的 `HOME` / `XDG_CONFIG_HOME`,然后销毁测试 Gateway 网关和沙箱 -- 常用覆盖项: - - `OPENCLAW_E2E_OPENSHELL=1`:在手动运行更广泛的 e2e 测试套件时启用该测试 - - `OPENCLAW_E2E_OPENSHELL_COMMAND=/path/to/openshell`:指定非默认 CLI 二进制文件或包装脚本 +- 常用覆盖选项: + - `OPENCLAW_E2E_OPENSHELL=1` 可在手动运行更广泛 e2e 套件时启用该测试 + - `OPENCLAW_E2E_OPENSHELL_COMMAND=/path/to/openshell` 可指向非默认 CLI 二进制或包装脚本 ### 实时(真实提供商 + 真实模型) - 命令:`pnpm test:live` - 配置:`vitest.live.config.ts` -- 文件:`src/**/*.live.test.ts` +- 文件:`src/**/*.live.test.ts`、`test/**/*.live.test.ts`,以及 `extensions/` 下的内置插件实时测试 - 默认:由 `pnpm test:live` **启用**(会设置 `OPENCLAW_LIVE_TEST=1`) - 范围: - - “这个提供商 / 模型在 _今天_ 配合真实凭证是否真的可用?” - - 捕获提供商格式变化、工具调用怪癖、认证问题以及速率限制行为 + - “这个提供商/模型在 _今天_ 配合真实凭证是否真的可用?” + - 捕获提供商格式变更、工具调用怪癖、认证问题和速率限制行为 - 预期: - - 按设计不具备 CI 稳定性(真实网络、真实提供商策略、配额、故障) - - 会花钱 / 消耗速率限制额度 - - 优先运行缩小范围的子集,而不是“全部运行” -- 实时运行会读取 `~/.profile`,以补齐缺失的 API key。 -- 默认情况下,实时运行仍会隔离 `HOME`,并将配置 / 认证材料复制到一个临时测试 home 中,这样单元测试 fixture 就不会修改你真实的 `~/.openclaw`。 -- 仅当你有意让实时测试使用真实 home 目录时,才设置 `OPENCLAW_LIVE_USE_REAL_HOME=1`。 -- `pnpm test:live` 现在默认采用更安静的模式:会保留 `[live] ...` 进度输出,但会抑制额外的 `~/.profile` 提示,并静默 Gateway 网关启动日志 / Bonjour 噪声。如果你想恢复完整启动日志,可设置 `OPENCLAW_LIVE_TEST_QUIET=0`。 -- API key 轮换(提供商特定):设置逗号 / 分号格式的 `*_API_KEYS`,或设置 `*_API_KEY_1`、`*_API_KEY_2`(例如 `OPENAI_API_KEYS`、`ANTHROPIC_API_KEYS`、`GEMINI_API_KEYS`),也可通过 `OPENCLAW_LIVE_*_KEY` 为单次实时运行覆盖;测试在遇到速率限制响应时会重试。 -- 进度 / 心跳输出: - - 实时测试套件现在会将进度行输出到 stderr,因此即使 `Vitest` 控制台捕获较安静,长时间的提供商调用仍然会清晰显示为活跃状态。 - - `vitest.live.config.ts` 会禁用 `Vitest` 控制台拦截,因此提供商 / Gateway 网关进度行会在实时运行期间立即流式输出。 + - 按设计并不具备 CI 稳定性(真实网络、真实提供商策略、配额、故障) + - 会花费金钱 / 消耗速率限制 + - 优先运行收窄后的子集,而不是“全部” +- 实时运行会加载 `~/.profile` 以获取缺失的 API 密钥。 +- 默认情况下,实时运行仍会隔离 `HOME`,并将配置/认证材料复制到临时测试 home 中,这样单元测试夹具就不会修改你真实的 `~/.openclaw`。 +- 仅当你明确需要让实时测试使用真实 home 目录时,才设置 `OPENCLAW_LIVE_USE_REAL_HOME=1`。 +- `pnpm test:live` 现在默认使用更安静的模式:它会保留 `[live] ...` 进度输出,但会抑制额外的 `~/.profile` 提示,并静音 Gateway 网关启动日志/Bonjour 噪声。如果你想恢复完整启动日志,请设置 `OPENCLAW_LIVE_TEST_QUIET=0`。 +- API 密钥轮换(提供商特定):设置 `*_API_KEYS`,使用逗号/分号格式,或设置 `*_API_KEY_1`、`*_API_KEY_2`(例如 `OPENAI_API_KEYS`、`ANTHROPIC_API_KEYS`、`GEMINI_API_KEYS`),或者通过 `OPENCLAW_LIVE_*_KEY` 为实时测试单独覆盖;测试会在收到速率限制响应时重试。 +- 进度/心跳输出: + - 实时套件现在会将进度行输出到 stderr,因此即使 Vitest 控制台捕获较安静,长时间的提供商调用也能明显显示为正在活动。 + - `vitest.live.config.ts` 会禁用 Vitest 控制台拦截,因此提供商/Gateway 网关进度行会在实时运行期间立即流式输出。 - 使用 `OPENCLAW_LIVE_HEARTBEAT_MS` 调整直连模型心跳。 - - 使用 `OPENCLAW_LIVE_GATEWAY_HEARTBEAT_MS` 调整 Gateway 网关 / probe 心跳。 + - 使用 `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` +- 调试“我的机器人宕了”/ 提供商特定失败 / 工具调用:运行收窄后的 `pnpm test:live` ## 实时:Android 节点能力扫描 - 测试:`src/gateway/android-node.capabilities.live.test.ts` - 脚本:`pnpm android:test:integration` -- 目标:调用已连接 Android 节点当前**公开的每一条命令**,并断言命令契约行为。 +- 目标:调用已连接 Android 节点当前声明的**每一个命令**,并断言命令契约行为。 - 范围: - - 以前置条件 / 手动设置为前提(该测试套件不会安装 / 运行 / 配对应用)。 + - 有前置条件/需要手动设置(该套件不会安装/运行/配对应用)。 - 针对所选 Android 节点逐条验证 Gateway 网关 `node.invoke`。 -- 必需的预先设置: - - Android 应用已连接并与 Gateway 网关配对。 +- 所需前置设置: + - Android 应用已连接并已与 Gateway 网关配对。 - 应用保持在前台。 - - 已授予你期望通过的能力所需的权限 / 捕获授权。 + - 已为你期望通过的能力授予权限/捕获同意。 - 可选目标覆盖: - `OPENCLAW_ANDROID_NODE_ID` 或 `OPENCLAW_ANDROID_NODE_NAME`。 - `OPENCLAW_ANDROID_GATEWAY_URL` / `OPENCLAW_ANDROID_GATEWAY_TOKEN` / `OPENCLAW_ANDROID_GATEWAY_PASSWORD`。 - 完整 Android 设置详情:[Android App](/zh-CN/platforms/android) -## 实时:模型冒烟(profile keys) +## 实时:模型冒烟测试(profile keys) 实时测试分为两层,以便我们隔离故障: -- “直连模型”告诉我们:该提供商 / 模型在给定 key 下是否至少能正常回复。 -- “Gateway 网关冒烟”告诉我们:该模型的完整 Gateway 网关 + 智能体链路是否正常(会话、历史、工具、沙箱策略等)。 +- “直连模型”告诉我们,给定密钥时该提供商/模型是否至少能响应。 +- “Gateway 网关冒烟”告诉我们,完整的 Gateway 网关 + 智能体流水线是否适用于该模型(会话、历史、工具、沙箱策略等)。 ### 第 1 层:直连模型补全(无 Gateway 网关) @@ -428,86 +427,86 @@ Telegram 类型的 payload 结构: - 目标: - 枚举已发现的模型 - 使用 `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) - - `OPENCLAW_LIVE_MODELS=all` 是 modern allowlist 的别名 - - 或 `OPENCLAW_LIVE_MODELS="openai/gpt-5.4,anthropic/claude-opus-4-6,..."`(逗号分隔的 allowlist) - - modern / all 扫描默认有一个精心挑选的高信号上限;设置 `OPENCLAW_LIVE_MAX_MODELS=0` 可执行完整的 modern 扫描,或设置为正数以应用更小的上限。 -- 如何选择提供商: - - `OPENCLAW_LIVE_PROVIDERS="google,google-antigravity,google-gemini-cli"`(逗号分隔的 allowlist) -- key 从哪里来: - - 默认:profile store 和环境变量回退 - - 设置 `OPENCLAW_LIVE_REQUIRE_PROFILE_KEYS=1` 可强制**仅使用 profile store** -- 该层存在的原因: - - 将“提供商 API 坏了 / key 无效”和“Gateway 网关智能体链路坏了”区分开来 - - 容纳小型、隔离的回归测试(例如:OpenAI Responses / Codex Responses 推理重放 + 工具调用流程) + - `pnpm test:live`(如果直接调用 Vitest,则设置 `OPENCLAW_LIVE_TEST=1`) +- 设置 `OPENCLAW_LIVE_MODELS=modern`(或 `all`,即 modern 的别名)后,才会实际运行此套件;否则它会跳过,以便让 `pnpm test:live` 聚焦于 Gateway 网关冒烟测试 +- 选择模型的方法: + - `OPENCLAW_LIVE_MODELS=modern` 运行 modern 允许列表(Opus/Sonnet 4.6+、GPT-5.x + Codex、Gemini 3、GLM 4.7、MiniMax M2.7、Grok 4) + - `OPENCLAW_LIVE_MODELS=all` 是 modern 允许列表的别名 + - 或设置 `OPENCLAW_LIVE_MODELS="openai/gpt-5.4,anthropic/claude-opus-4-6,..."`(逗号分隔的允许列表) + - modern/all 扫描默认使用精心挑选的高信号上限;设置 `OPENCLAW_LIVE_MAX_MODELS=0` 可执行穷尽的 modern 扫描,或设置为正数以指定更小的上限。 +- 选择提供商的方法: + - `OPENCLAW_LIVE_PROVIDERS="google,google-antigravity,google-gemini-cli"`(逗号分隔的允许列表) +- 密钥来源: + - 默认:profile 存储和环境变量回退 + - 设置 `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:*` 会话(每次运行按模型覆盖) - - 遍历带 key 的模型并断言: - - 存在“有意义”的回复(无工具) - - 一次真实工具调用成功(read probe) - - 可选的额外工具 probe 成功(exec+read probe) + - 创建/修补一个 `agent:dev:*` 会话(每次运行按模型覆盖) + - 遍历带密钥的模型并断言: + - “有意义”的响应(无工具) + - 一个真实工具调用可用(读取探针) + - 可选的额外工具探针(exec+read 探针) - OpenAI 回归路径(仅工具调用 → 后续跟进)持续可用 -- Probe 细节(这样你可以快速解释失败): - - `read` probe:测试会在工作区写入一个 nonce 文件,并要求智能体 `read` 该文件并回显 nonce。 - - `exec+read` probe:测试会要求智能体通过 `exec` 将 nonce 写入一个临时文件,然后再 `read` 回来。 - - 图像 probe:测试会附加一个生成的 PNG(猫 + 随机代码),并期望模型返回 `cat `。 +- 探针细节(这样你可以快速解释故障): + - `read` 探针:测试会在工作区中写入一个 nonce 文件,并要求智能体 `read` 该文件并回显 nonce。 + - `exec+read` 探针:测试会要求智能体通过 `exec` 将 nonce 写入一个临时文件,然后再将其 `read` 回来。 + - 图像探针:测试会附加一个生成的 PNG(猫 + 随机代码),并期望模型返回 `cat `。 - 实现参考:`src/gateway/gateway-models.profiles.live.test.ts` 和 `src/gateway/live-image-probe.ts`。 - 启用方式: - - `pnpm test:live`(或在直接调用 `Vitest` 时设置 `OPENCLAW_LIVE_TEST=1`) -- 如何选择模型: - - 默认:modern allowlist(Opus / Sonnet 4.6+、GPT-5.x + Codex、Gemini 3、GLM 4.7、MiniMax M2.7、Grok 4) - - `OPENCLAW_LIVE_GATEWAY_MODELS=all` 是 modern allowlist 的别名 - - 或设置 `OPENCLAW_LIVE_GATEWAY_MODELS="provider/model"`(或逗号列表)以缩小范围 - - modern / all Gateway 网关扫描默认有一个精心挑选的高信号上限;设置 `OPENCLAW_LIVE_GATEWAY_MAX_MODELS=0` 可执行完整的 modern 扫描,或设置为正数以应用更小的上限。 -- 如何选择提供商(避免“OpenRouter 全部都跑”): - - `OPENCLAW_LIVE_GATEWAY_PROVIDERS="google,google-antigravity,google-gemini-cli,openai,anthropic,zai,minimax"`(逗号分隔的 allowlist) -- 工具 + 图像 probe 在这个实时测试中始终开启: - - `read` probe + `exec+read` probe(工具压力测试) - - 当模型声明支持图像输入时,会运行图像 probe - - 流程(高层概览): - - 测试生成一个带有 “CAT” + 随机代码的小 PNG(`src/gateway/live-image-probe.ts`) - - 通过 `agent` `attachments: [{ mimeType: "image/png", content: "" }]` 发送 + - `pnpm test:live`(如果直接调用 Vitest,则设置 `OPENCLAW_LIVE_TEST=1`) +- 选择模型的方法: + - 默认:modern 允许列表(Opus/Sonnet 4.6+、GPT-5.x + Codex、Gemini 3、GLM 4.7、MiniMax M2.7、Grok 4) + - `OPENCLAW_LIVE_GATEWAY_MODELS=all` 是 modern 允许列表的别名 + - 或设置 `OPENCLAW_LIVE_GATEWAY_MODELS="provider/model"`(或逗号列表)来收窄范围 + - modern/all Gateway 网关扫描默认使用精心挑选的高信号上限;设置 `OPENCLAW_LIVE_GATEWAY_MAX_MODELS=0` 可执行穷尽的 modern 扫描,或设置为正数以指定更小的上限。 +- 选择提供商的方法(避免“OpenRouter 全家桶”): + - `OPENCLAW_LIVE_GATEWAY_PROVIDERS="google,google-antigravity,google-gemini-cli,openai,anthropic,zai,minimax"`(逗号分隔的允许列表) +- 工具 + 图像探针在此实时测试中始终启用: + - `read` 探针 + `exec+read` 探针(工具压力测试) + - 当模型声明支持图像输入时,会运行图像探针 + - 流程(高层级): + - 测试生成一个带有 “CAT” + 随机代码的小型 PNG(`src/gateway/live-image-probe.ts`) + - 通过 `agent` `attachments: [{ mimeType: "image/png", content: "" }]` 发送它 - Gateway 网关将附件解析为 `images[]`(`src/gateway/server-methods/agent.ts` + `src/gateway/chat-attachments.ts`) - - 嵌入式智能体将一个多模态用户消息转发给模型 - - 断言:回复中包含 `cat` + 该代码(OCR 容忍度:允许轻微错误) + - 嵌入式智能体将多模态用户消息转发给模型 + - 断言:回复包含 `cat` + 该代码(OCR 容错:允许轻微错误) -提示:如果你想查看你的机器上能测试什么(以及确切的 `provider/model` id),请运行: +提示:如果想查看你的机器上可以测试什么(以及精确的 `provider/model` id),请运行: ```bash openclaw models list openclaw models list --json ``` -## 实时:CLI 后端冒烟(Claude、Codex、Gemini 或其他本地 CLI) +## 实时:CLI 后端冒烟测试(Claude、Codex、Gemini 或其他本地 CLI) - 测试:`src/gateway/gateway-cli-backend.live.test.ts` -- 目标:在不触碰默认配置的情况下,使用本地 CLI 后端验证 Gateway 网关 + 智能体链路。 -- 后端特定的默认冒烟配置位于所属扩展的 `cli-backend.ts` 定义中。 +- 目标:使用本地 CLI 后端验证 Gateway 网关 + 智能体流水线,而不触碰你的默认配置。 +- 后端特定的默认冒烟测试配置位于对应扩展的 `cli-backend.ts` 定义中。 - 启用: - - `pnpm test:live`(或在直接调用 `Vitest` 时设置 `OPENCLAW_LIVE_TEST=1`) + - `pnpm test:live`(如果直接调用 Vitest,则设置 `OPENCLAW_LIVE_TEST=1`) - `OPENCLAW_LIVE_CLI_BACKEND=1` - 默认值: - - 默认提供商 / 模型:`claude-cli/claude-sonnet-4-6` - - 命令 / 参数 / 图像行为来自所属 CLI 后端 plugin 元数据。 + - 默认提供商/模型:`claude-cli/claude-sonnet-4-6` + - 命令/参数/图像行为来自所属 CLI 后端插件元数据。 - 覆盖项(可选): - `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` 用于发送真实图像附件(路径会注入到 prompt 中)。 - - `OPENCLAW_LIVE_CLI_BACKEND_IMAGE_ARG="--image"` 用于通过 CLI 参数传递图像文件路径,而不是通过 prompt 注入。 - - `OPENCLAW_LIVE_CLI_BACKEND_IMAGE_MODE="repeat"`(或 `"list"`)用于在设置 `IMAGE_ARG` 时控制图像参数的传递方式。 - - `OPENCLAW_LIVE_CLI_BACKEND_RESUME_PROBE=1` 用于发送第二轮并验证恢复流程。 - - `OPENCLAW_LIVE_CLI_BACKEND_MODEL_SWITCH_PROBE=0` 用于禁用默认的 Claude Sonnet -> Opus 同会话连续性 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` 发送第二轮消息并验证恢复流程。 + - `OPENCLAW_LIVE_CLI_BACKEND_MODEL_SWITCH_PROBE=0` 禁用默认的 Claude Sonnet -> Opus 同会话连续性探针(当所选模型支持切换目标时,可设置为 `1` 强制启用)。 示例: @@ -535,26 +534,26 @@ pnpm test:docker:live-cli-backend:gemini 说明: - Docker 运行器位于 `scripts/test-live-cli-backend-docker.sh`。 -- 它会在仓库 Docker 镜像内以非 root 的 `node` 用户身份运行实时 CLI 后端冒烟测试。 -- 它会从所属扩展解析 CLI 冒烟元数据,然后将匹配的 Linux CLI 包(`@anthropic-ai/claude-code`、`@openai/codex` 或 `@google/gemini-cli`)安装到一个可写且带缓存的前缀目录 `OPENCLAW_DOCKER_CLI_TOOLS_DIR`(默认:`~/.cache/openclaw/docker-cli-tools`)。 -- `pnpm test:docker:live-cli-backend:claude-subscription` 需要便携式 Claude Code 订阅 OAuth,可通过带有 `claudeAiOauth.subscriptionType` 的 `~/.claude/.credentials.json`,或来自 `claude setup-token` 的 `CLAUDE_CODE_OAUTH_TOKEN` 提供。它会先证明 Docker 中直接 `claude -p` 可用,然后在不保留 Anthropic API key 环境变量的情况下运行两轮 Gateway 网关 CLI 后端测试。该订阅通道默认禁用 Claude MCP / 工具和图像 probe,因为 Claude 目前会通过额外用量计费来处理第三方应用使用,而不是使用普通订阅套餐限制。 -- 实时 CLI 后端冒烟测试现在对 Claude、Codex 和 Gemini 执行相同的端到端流程:文本轮次、图像分类轮次,然后通过 Gateway 网关 CLI 验证 MCP `cron` 工具调用。 -- Claude 的默认冒烟测试还会将会话从 Sonnet 修补切换到 Opus,并验证恢复后的会话仍记得先前的备注。 +- 它会在仓库 Docker 镜像内,以非 root 的 `node` 用户身份运行实时 CLI 后端冒烟测试。 +- 它会从所属扩展中解析 CLI 冒烟测试元数据,然后将匹配的 Linux CLI 包(`@anthropic-ai/claude-code`、`@openai/codex` 或 `@google/gemini-cli`)安装到位于 `OPENCLAW_DOCKER_CLI_TOOLS_DIR` 的可写缓存前缀中(默认:`~/.cache/openclaw/docker-cli-tools`)。 +- `pnpm test:docker:live-cli-backend:claude-subscription` 需要通过 `~/.claude/.credentials.json` 中带有 `claudeAiOauth.subscriptionType` 的可移植 Claude Code 订阅 OAuth,或使用来自 `claude setup-token` 的 `CLAUDE_CODE_OAUTH_TOKEN`。它会先证明 Docker 中直接 `claude -p` 可用,然后在不保留 Anthropic API 密钥环境变量的情况下运行两轮 Gateway 网关 CLI 后端测试。该订阅通道默认禁用 Claude MCP/工具和图像探针,因为 Claude 目前会通过额外用量计费来路由第三方应用使用,而不是走普通订阅套餐限制。 +- 实时 CLI 后端冒烟测试现在会为 Claude、Codex 和 Gemini 演练相同的端到端流程:文本轮次、图像分类轮次,然后通过 Gateway 网关 CLI 验证 MCP `cron` 工具调用。 +- Claude 的默认冒烟测试还会将会话从 Sonnet 修补为 Opus,并验证恢复后的会话仍记得更早的笔记。 -## 实时:ACP 绑定冒烟(`/acp spawn ... --bind here`) +## 实时:ACP 绑定冒烟测试(`/acp spawn ... --bind here`) - 测试:`src/gateway/gateway-acp-bind.live.test.ts` -- 目标:使用一个实时 ACP 智能体验证真实的 ACP 会话绑定流程: +- 目标:使用实时 ACP 智能体验证真实 ACP 会话绑定流程: - 发送 `/acp spawn --bind here` - - 就地绑定一个合成的消息渠道会话 - - 在同一会话上发送普通后续消息 - - 验证该后续消息落入已绑定的 ACP 会话转录中 + - 原地绑定一个合成的消息渠道会话 + - 在同一个会话上发送一条普通后续消息 + - 验证该后续消息落入已绑定 ACP 会话的转录中 - 启用: - `pnpm test:live src/gateway/gateway-acp-bind.live.test.ts` - `OPENCLAW_LIVE_ACP_BIND=1` - 默认值: - Docker 中的 ACP 智能体:`claude,codex,gemini` - - 直接运行 `pnpm test:live ...` 时的 ACP 智能体:`claude` + - 直接 `pnpm test:live ...` 使用的 ACP 智能体:`claude` - 合成渠道:Slack 私信风格的会话上下文 - ACP 后端:`acpx` - 覆盖项: @@ -565,8 +564,8 @@ pnpm test:docker:live-cli-backend:gemini - `OPENCLAW_LIVE_ACP_BIND_AGENT_COMMAND='npx -y @agentclientprotocol/claude-agent-acp@'` - `OPENCLAW_LIVE_ACP_BIND_CODEX_MODEL=gpt-5.4` - 说明: - - 该通道使用 Gateway 网关 `chat.send` 接口,并带有仅管理员可用的合成 originating-route 字段,因此测试可以附加消息渠道上下文,而无需假装对外投递。 - - 当未设置 `OPENCLAW_LIVE_ACP_BIND_AGENT_COMMAND` 时,测试会使用内置 `acpx` plugin 的内建智能体注册表来选择 ACP harness 智能体。 + - 此通道使用 Gateway 网关 `chat.send` 接口,并带有仅管理员可用的合成来源路由字段,因此测试可以附加消息渠道上下文,而无需假装进行外部投递。 + - 当未设置 `OPENCLAW_LIVE_ACP_BIND_AGENT_COMMAND` 时,测试会使用嵌入式 `acpx` 插件内置的智能体注册表来处理所选 ACP 测试智能体。 示例: @@ -593,34 +592,34 @@ pnpm test:docker:live-acp-bind:gemini Docker 说明: - Docker 运行器位于 `scripts/test-live-acp-bind-docker.sh`。 -- 默认情况下,它会按顺序针对所有受支持的实时 CLI 智能体运行 ACP 绑定冒烟测试:`claude`、`codex`,然后是 `gemini`。 -- 使用 `OPENCLAW_LIVE_ACP_BIND_AGENTS=claude`、`OPENCLAW_LIVE_ACP_BIND_AGENTS=codex` 或 `OPENCLAW_LIVE_ACP_BIND_AGENTS=gemini` 可缩小测试矩阵。 -- 它会读取 `~/.profile`,将匹配的 CLI 认证材料暂存到容器中,把 `acpx` 安装到可写 npm 前缀中,然后在缺失时安装所请求的实时 CLI(`@anthropic-ai/claude-code`、`@openai/codex` 或 `@google/gemini-cli`)。 -- 在 Docker 内部,运行器会设置 `OPENCLAW_LIVE_ACP_BIND_ACPX_COMMAND=$HOME/.npm-global/bin/acpx`,以便 `acpx` 能让来自已读取 profile 的提供商环境变量继续对其子 harness CLI 可用。 +- 默认情况下,它会按顺序对所有受支持的实时 CLI 智能体运行 ACP 绑定冒烟测试:`claude`、`codex`,然后是 `gemini`。 +- 使用 `OPENCLAW_LIVE_ACP_BIND_AGENTS=claude`、`OPENCLAW_LIVE_ACP_BIND_AGENTS=codex` 或 `OPENCLAW_LIVE_ACP_BIND_AGENTS=gemini` 可缩小矩阵范围。 +- 它会加载 `~/.profile`,将匹配的 CLI 认证材料暂存到容器中,把 `acpx` 安装到可写 npm 前缀中,然后在缺失时安装所请求的实时 CLI(`@anthropic-ai/claude-code`、`@openai/codex` 或 `@google/gemini-cli`)。 +- 在 Docker 内部,运行器会设置 `OPENCLAW_LIVE_ACP_BIND_ACPX_COMMAND=$HOME/.npm-global/bin/acpx`,以便 acpx 保持从已加载 profile 获取的提供商环境变量对其子测试 CLI 可用。 -## 实时:Codex app-server harness 冒烟 +## 实时:Codex app-server 测试框架冒烟测试 -- 目标:通过正常的 Gateway 网关 - `agent` 方法验证由 plugin 拥有的 Codex harness: - - 加载内置的 `codex` plugin +- 目标:通过常规 Gateway 网关 + `agent` 方法验证由插件拥有的 Codex 测试框架: + - 加载内置的 `codex` 插件 - 选择 `OPENCLAW_AGENT_RUNTIME=codex` - 向 `codex/gpt-5.4` 发送第一轮 Gateway 网关智能体消息 - 向同一个 OpenClaw 会话发送第二轮消息,并验证 app-server 线程可以恢复 - - 通过同一个 Gateway 网关命令 + - 通过相同的 Gateway 网关命令 路径运行 `/codex status` 和 `/codex models` - - 可选地运行两个经 Guardian 审核的提权 shell probe:一个应被批准的无害 - 命令,以及一个应被拒绝的伪造 secret 上传, - 从而让智能体回问 + - 可选运行两个经 Guardian 审查的提权 shell 探针:一个应被批准的良性 + 命令,以及一个应被拒绝的伪造密钥上传命令, + 这样智能体会反问确认 - 测试:`src/gateway/gateway-codex-harness.live.test.ts` - 启用:`OPENCLAW_LIVE_CODEX_HARNESS=1` - 默认模型:`codex/gpt-5.4` -- 可选图像 probe:`OPENCLAW_LIVE_CODEX_HARNESS_IMAGE_PROBE=1` -- 可选 MCP / 工具 probe:`OPENCLAW_LIVE_CODEX_HARNESS_MCP_PROBE=1` -- 可选 Guardian probe:`OPENCLAW_LIVE_CODEX_HARNESS_GUARDIAN_PROBE=1` +- 可选图像探针:`OPENCLAW_LIVE_CODEX_HARNESS_IMAGE_PROBE=1` +- 可选 MCP/工具探针:`OPENCLAW_LIVE_CODEX_HARNESS_MCP_PROBE=1` +- 可选 Guardian 探针:`OPENCLAW_LIVE_CODEX_HARNESS_GUARDIAN_PROBE=1` - 该冒烟测试会设置 `OPENCLAW_AGENT_HARNESS_FALLBACK=none`,因此损坏的 Codex - harness 不可能通过静默回退到 PI 来蒙混过关。 -- 认证:来自 shell / profile 的 `OPENAI_API_KEY`,以及可选复制的 + 测试框架不能通过静默回退到 PI 来蒙混过关。 +- 认证:来自 shell/profile 的 `OPENAI_API_KEY`,以及可选复制的 `~/.codex/auth.json` 和 `~/.codex/config.toml` 本地配方: @@ -645,31 +644,32 @@ pnpm test:docker:live-codex-harness Docker 说明: - Docker 运行器位于 `scripts/test-live-codex-harness-docker.sh`。 -- 它会读取已挂载的 `~/.profile`,传递 `OPENAI_API_KEY`,在存在时复制 Codex CLI - 认证文件,将 `@openai/codex` 安装到可写的挂载 npm - 前缀中,暂存源码树,然后只运行 Codex harness 实时测试。 -- Docker 默认启用图像、MCP / 工具和 Guardian probe。需要更窄范围的调试 - 运行时,可设置 `OPENCLAW_LIVE_CODEX_HARNESS_IMAGE_PROBE=0` 或 +- 它会加载挂载的 `~/.profile`,传递 `OPENAI_API_KEY`,在存在时复制 Codex CLI + 认证文件,将 `@openai/codex` 安装到可写挂载 npm + 前缀中,暂存源代码树,然后只运行 Codex 测试框架实时测试。 +- Docker 默认启用图像、MCP/工具和 Guardian 探针。设置 + `OPENCLAW_LIVE_CODEX_HARNESS_IMAGE_PROBE=0` 或 `OPENCLAW_LIVE_CODEX_HARNESS_MCP_PROBE=0` 或 - `OPENCLAW_LIVE_CODEX_HARNESS_GUARDIAN_PROBE=0`。 + `OPENCLAW_LIVE_CODEX_HARNESS_GUARDIAN_PROBE=0`,当你需要更窄范围的调试 + 运行时使用。 - Docker 还会导出 `OPENCLAW_AGENT_HARNESS_FALLBACK=none`,与实时 - 测试配置保持一致,因此 `openai-codex/*` 或 PI 回退都无法掩盖 Codex harness + 测试配置保持一致,因此 `openai-codex/*` 或 PI 回退都无法掩盖 Codex 测试框架 回归问题。 ### 推荐的实时测试配方 -范围小、明确的 allowlist 最快,也最不容易不稳定: +范围窄、显式的允许列表最快,也最不容易波动: - 单模型,直连(无 Gateway 网关): - `OPENCLAW_LIVE_MODELS="openai/gpt-5.4" pnpm test:live src/agents/models.profiles.live.test.ts` -- 单模型,Gateway 网关冒烟: +- 单模型,Gateway 网关冒烟测试: - `OPENCLAW_LIVE_GATEWAY_MODELS="openai/gpt-5.4" pnpm test:live src/gateway/gateway-models.profiles.live.test.ts` -- 跨多个提供商的工具调用: +- 多个提供商的工具调用: - `OPENCLAW_LIVE_GATEWAY_MODELS="openai/gpt-5.4,anthropic/claude-opus-4-6,google/gemini-3-flash-preview,zai/glm-4.7,minimax/MiniMax-M2.7" pnpm test:live src/gateway/gateway-models.profiles.live.test.ts` -- 聚焦 Google(Gemini API key + Antigravity): +- Google 聚焦(Gemini API key + Antigravity): - Gemini(API key):`OPENCLAW_LIVE_GATEWAY_MODELS="google/gemini-3-flash-preview" pnpm test:live src/gateway/gateway-models.profiles.live.test.ts` - Antigravity(OAuth):`OPENCLAW_LIVE_GATEWAY_MODELS="google-antigravity/claude-opus-4-6-thinking,google-antigravity/gemini-3-pro-high" pnpm test:live src/gateway/gateway-models.profiles.live.test.ts` @@ -677,18 +677,18 @@ Docker 说明: - `google/...` 使用 Gemini API(API key)。 - `google-antigravity/...` 使用 Antigravity OAuth bridge(Cloud Code Assist 风格的智能体端点)。 -- `google-gemini-cli/...` 使用你机器上的本地 Gemini CLI(独立的认证 + 工具行为差异)。 +- `google-gemini-cli/...` 使用你机器上的本地 Gemini CLI(单独的认证 + 工具行为差异)。 - Gemini API 与 Gemini CLI: - - API:OpenClaw 通过 HTTP 调用 Google 托管的 Gemini API(API key / profile 认证);这通常是大多数用户所说的 “Gemini”。 - - CLI:OpenClaw 会 shell out 到本地 `gemini` 二进制文件;它有自己的认证方式,行为也可能不同(流式传输 / 工具支持 / 版本偏差)。 + - API:OpenClaw 通过 HTTP 调用 Google 托管的 Gemini API(API key / profile 认证);这是大多数用户提到 “Gemini” 时的含义。 + - CLI:OpenClaw 会调用本地 `gemini` 二进制;它有自己的认证,并且行为可能不同(流式传输/工具支持/版本偏差)。 ## 实时:模型矩阵(我们覆盖什么) -没有固定的“CI 模型列表”(实时测试是按需启用的),但以下是**推荐**在有 key 的开发机器上定期覆盖的模型。 +没有固定的 “CI 模型列表”(实时测试是按需启用的),但这些是建议在有密钥的开发机上定期覆盖的**推荐**模型。 -### 现代冒烟集合(工具调用 + 图像) +### 现代冒烟测试集(工具调用 + 图像) -这是我们预期始终可用的“常见模型”运行集合: +这是我们预期要持续保持可用的 “常用模型” 运行集合: - OpenAI(非 Codex):`openai/gpt-5.4`(可选:`openai/gpt-5.4-mini`) - OpenAI Codex:`openai-codex/gpt-5.4` @@ -703,7 +703,7 @@ Docker 说明: ### 基线:工具调用(Read + 可选 Exec) -每个提供商家族至少选一个: +每个提供商家族至少选择一个: - OpenAI:`openai/gpt-5.4`(或 `openai/gpt-5.4-mini`) - Anthropic:`anthropic/claude-opus-4-6`(或 `anthropic/claude-sonnet-4-6`) @@ -711,54 +711,54 @@ Docker 说明: - Z.AI(GLM):`zai/glm-4.7` - MiniMax:`minimax/MiniMax-M2.7` -可选的额外覆盖(有则更好): +可选的额外覆盖(有更好,没有也行): - xAI:`xai/grok-4`(或最新可用版本) -- Mistral:`mistral/`…(选一个你已启用、支持工具的模型) +- Mistral:`mistral/`…(选择一个你已启用、具备工具能力的模型) - Cerebras:`cerebras/`…(如果你有访问权限) - LM Studio:`lmstudio/`…(本地;工具调用取决于 API 模式) ### 视觉:图像发送(附件 → 多模态消息) -在 `OPENCLAW_LIVE_GATEWAY_MODELS` 中至少包含一个支持图像的模型(Claude / Gemini / OpenAI 支持视觉的变体等),以便执行图像 probe。 +在 `OPENCLAW_LIVE_GATEWAY_MODELS` 中至少包含一个具备图像能力的模型(Claude/Gemini/OpenAI 具备视觉能力的变体等),以覆盖图像探针。 ### 聚合器 / 替代 Gateway 网关 -如果你启用了相应 key,我们也支持通过以下方式测试: +如果你启用了相关密钥,我们也支持通过以下方式测试: -- OpenRouter:`openrouter/...`(数百个模型;使用 `openclaw models scan` 查找支持工具 + 图像的候选模型) +- OpenRouter:`openrouter/...`(数百个模型;使用 `openclaw models scan` 查找具备工具 + 图像能力的候选模型) - OpenCode:Zen 使用 `opencode/...`,Go 使用 `opencode-go/...`(通过 `OPENCODE_API_KEY` / `OPENCODE_ZEN_API_KEY` 认证) -如果你有凭证 / 配置,也可以将更多提供商加入实时测试矩阵: +如果你有凭证/配置,还可以将更多提供商纳入实时矩阵: - 内置:`openai`、`openai-codex`、`anthropic`、`google`、`google-vertex`、`google-antigravity`、`google-gemini-cli`、`zai`、`openrouter`、`opencode`、`opencode-go`、`xai`、`groq`、`cerebras`、`mistral`、`github-copilot` -- 通过 `models.providers`(自定义端点):`minimax`(云端 / API),以及任意兼容 OpenAI / Anthropic 的代理(LM Studio、vLLM、LiteLLM 等) +- 通过 `models.providers`(自定义端点):`minimax`(云/API),以及任何兼容 OpenAI/Anthropic 的代理(LM Studio、vLLM、LiteLLM 等) -提示:不要试图在文档中硬编码“所有模型”。权威列表就是你的机器上 `discoverModels(...)` 返回的内容 + 当前可用的 key。 +提示:不要试图在文档中硬编码 “所有模型”。权威列表是你机器上 `discoverModels(...)` 返回的内容 + 当前可用的密钥。 ## 凭证(绝不要提交) -实时测试发现凭证的方式与 CLI 相同。实际含义是: +实时测试发现凭证的方式与 CLI 相同。实际含义如下: -- 如果 CLI 能工作,实时测试应当能找到相同的 key。 -- 如果实时测试提示 “no creds”,就像调试 `openclaw models list` / 模型选择那样进行调试。 +- 如果 CLI 可用,实时测试也应该能找到相同的密钥。 +- 如果实时测试提示 “no creds”,请按调试 `openclaw models list` / 模型选择的同样方式来排查。 -- 每个智能体的认证 profile:`~/.openclaw/agents//agent/auth-profiles.json`(这就是实时测试中 “profile keys” 的含义) +- 按智能体划分的认证 profiles:`~/.openclaw/agents//agent/auth-profiles.json`(这就是实时测试中 “profile keys” 的含义) - 配置:`~/.openclaw/openclaw.json`(或 `OPENCLAW_CONFIG_PATH`) -- 旧版状态目录:`~/.openclaw/credentials/`(如果存在,会复制到暂存的实时测试 home 中,但它不是主 profile key 存储) -- 本地实时运行默认会把当前活动配置、每个智能体的 `auth-profiles.json` 文件、旧版 `credentials/` 以及受支持的外部 CLI 认证目录复制到一个临时测试 home 中;暂存的实时 home 会跳过 `workspace/` 和 `sandboxes/`,并移除 `agents.*.workspace` / `agentDir` 路径覆盖,以便 probe 不会落到你真实主机工作区中。 +- 旧版状态目录:`~/.openclaw/credentials/`(存在时会复制到暂存的实时 home 中,但它不是主 profile-key 存储) +- 本地实时运行默认会将活动配置、按智能体划分的 `auth-profiles.json` 文件、旧版 `credentials/` 以及受支持的外部 CLI 认证目录复制到临时测试 home 中;暂存的实时 home 会跳过 `workspace/` 和 `sandboxes/`,并移除 `agents.*.workspace` / `agentDir` 路径覆盖,以便探针不会落到你真实的主机工作区上。 -如果你想依赖环境变量 key(例如在你的 `~/.profile` 中导出的 key),请在本地测试前运行 `source ~/.profile`,或使用下方的 Docker 运行器(它们可以将 `~/.profile` 挂载到容器中)。 +如果你想依赖环境变量密钥(例如在你的 `~/.profile` 中导出),请在运行本地测试前先执行 `source ~/.profile`,或者使用下面的 Docker 运行器(它们可以将 `~/.profile` 挂载到容器中)。 -## Deepgram 实时测试(音频转录) +## Deepgram 实时测试(音频转写) -- 测试:`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` +- 测试:`extensions/deepgram/audio.live.test.ts` +- 启用:`DEEPGRAM_API_KEY=... DEEPGRAM_LIVE_TEST=1 pnpm test:live extensions/deepgram/audio.live.test.ts` ## BytePlus 编码计划实时测试 -- 测试:`src/agents/byteplus.live.test.ts` -- 启用:`BYTEPLUS_API_KEY=... BYTEPLUS_LIVE_TEST=1 pnpm test:live src/agents/byteplus.live.test.ts` +- 测试:`extensions/byteplus/live.test.ts` +- 启用:`BYTEPLUS_API_KEY=... BYTEPLUS_LIVE_TEST=1 pnpm test:live extensions/byteplus/live.test.ts` - 可选模型覆盖:`BYTEPLUS_CODING_MODEL=ark-code-latest` ## ComfyUI 工作流媒体实时测试 @@ -766,259 +766,262 @@ Docker 说明: - 测试:`extensions/comfy/comfy.live.test.ts` - 启用:`OPENCLAW_LIVE_TEST=1 COMFY_LIVE_TEST=1 pnpm test:live -- extensions/comfy/comfy.live.test.ts` - 范围: - - 测试内置 comfy 图像、视频和 `music_generate` 路径 + - 演练内置 comfy 图像、视频和 `music_generate` 路径 - 除非配置了 `models.providers.comfy.`,否则会跳过各项能力 - - 在修改 comfy 工作流提交、轮询、下载或 plugin 注册后尤其有用 + - 在修改 comfy 工作流提交、轮询、下载或插件注册后非常有用 ## 图像生成实时测试 -- 测试:`src/image-generation/runtime.live.test.ts` -- 命令:`pnpm test:live src/image-generation/runtime.live.test.ts` -- Harness:`pnpm test:live:media image` +- 测试:`test/image-generation.runtime.live.test.ts` +- 命令:`pnpm test:live test/image-generation.runtime.live.test.ts` +- 测试框架:`pnpm test:live:media image` - 范围: - - 枚举每一个已注册的图像生成提供商 plugin - - 在探测前,从你的登录 shell(`~/.profile`)加载缺失的提供商环境变量 - - 默认优先使用实时 / 环境变量 API key,而不是已存储的认证 profile,因此 `auth-profiles.json` 中过期的测试 key 不会掩盖真实 shell 凭证 - - 跳过没有可用认证 / profile / 模型的提供商 + - 枚举每个已注册的图像生成提供商插件 + - 在探测前从你的登录 shell(`~/.profile`)加载缺失的提供商环境变量 + - 默认优先使用实时/env API 密钥,而不是已存储的认证 profiles,这样 `auth-profiles.json` 中陈旧的测试密钥就不会掩盖真实 shell 凭证 + - 跳过没有可用认证/profile/模型的提供商 - 通过共享运行时能力运行标准图像生成变体: - `google:flash-generate` - `google:pro-generate` - `google:pro-edit` - `openai:default-generate` - 当前覆盖的内置提供商: - - `openai` + - `fal` - `google` + - `minimax` + - `openai` + - `vydra` - `xai` -- 可选缩小范围: +- 可选收窄: - `OPENCLAW_LIVE_IMAGE_GENERATION_PROVIDERS="openai,google,xai"` - `OPENCLAW_LIVE_IMAGE_GENERATION_MODELS="openai/gpt-image-2,google/gemini-3.1-flash-image-preview,xai/grok-imagine-image"` - `OPENCLAW_LIVE_IMAGE_GENERATION_CASES="google:flash-generate,google:pro-edit,xai:default-generate,xai:default-edit"` - 可选认证行为: - - `OPENCLAW_LIVE_REQUIRE_PROFILE_KEYS=1` 可强制使用 profile store 认证,并忽略仅来自环境变量的覆盖 + - `OPENCLAW_LIVE_REQUIRE_PROFILE_KEYS=1` 可强制使用 profile 存储认证,并忽略仅 env 的覆盖 ## 音乐生成实时测试 - 测试:`extensions/music-generation-providers.live.test.ts` - 启用:`OPENCLAW_LIVE_TEST=1 pnpm test:live -- extensions/music-generation-providers.live.test.ts` -- Harness:`pnpm test:live:media music` +- 测试框架:`pnpm test:live:media music` - 范围: - - 测试共享的内置音乐生成提供商路径 + - 演练共享的内置音乐生成提供商路径 - 当前覆盖 Google 和 MiniMax - - 在探测前,从你的登录 shell(`~/.profile`)加载提供商环境变量 - - 默认优先使用实时 / 环境变量 API key,而不是已存储的认证 profile,因此 `auth-profiles.json` 中过期的测试 key 不会掩盖真实 shell 凭证 - - 跳过没有可用认证 / profile / 模型的提供商 + - 在探测前从你的登录 shell(`~/.profile`)加载提供商环境变量 + - 默认优先使用实时/env API 密钥,而不是已存储的认证 profiles,这样 `auth-profiles.json` 中陈旧的测试密钥就不会掩盖真实 shell 凭证 + - 跳过没有可用认证/profile/模型的提供商 - 在可用时运行两种已声明的运行时模式: - - 使用仅 prompt 输入的 `generate` + - 使用仅提示词输入的 `generate` - 当提供商声明 `capabilities.edit.enabled` 时运行 `edit` - 当前共享通道覆盖: - `google`:`generate`、`edit` - `minimax`:`generate` - - `comfy`:单独的 Comfy 实时测试文件,不在这个共享扫描中 -- 可选缩小范围: + - `comfy`:使用单独的 Comfy 实时测试文件,不在此共享扫描中 +- 可选收窄: - `OPENCLAW_LIVE_MUSIC_GENERATION_PROVIDERS="google,minimax"` - `OPENCLAW_LIVE_MUSIC_GENERATION_MODELS="google/lyria-3-clip-preview,minimax/music-2.5+"` - 可选认证行为: - - `OPENCLAW_LIVE_REQUIRE_PROFILE_KEYS=1` 可强制使用 profile store 认证,并忽略仅来自环境变量的覆盖 + - `OPENCLAW_LIVE_REQUIRE_PROFILE_KEYS=1` 可强制使用 profile 存储认证,并忽略仅 env 的覆盖 ## 视频生成实时测试 - 测试:`extensions/video-generation-providers.live.test.ts` - 启用:`OPENCLAW_LIVE_TEST=1 pnpm test:live -- extensions/video-generation-providers.live.test.ts` -- Harness:`pnpm test:live:media video` +- 测试框架:`pnpm test:live:media video` - 范围: - - 测试共享的内置视频生成提供商路径 - - 默认使用发布安全的冒烟路径:非 FAL 提供商、每个提供商一次文生视频请求、时长一秒的龙虾 prompt,以及来自 `OPENCLAW_LIVE_VIDEO_GENERATION_TIMEOUT_MS` 的每提供商操作上限(默认 `180000`) - - 默认跳过 FAL,因为提供商端队列延迟可能会主导发布时间;传入 `--video-providers fal` 或 `OPENCLAW_LIVE_VIDEO_GENERATION_PROVIDERS="fal"` 可显式运行它 - - 在探测前,从你的登录 shell(`~/.profile`)加载提供商环境变量 - - 默认优先使用实时 / 环境变量 API key,而不是已存储的认证 profile,因此 `auth-profiles.json` 中过期的测试 key 不会掩盖真实 shell 凭证 - - 跳过没有可用认证 / profile / 模型的提供商 + - 演练共享的内置视频生成提供商路径 + - 默认使用发布安全的冒烟测试路径:非 FAL 提供商、每个提供商一个 text-to-video 请求、一秒钟的龙虾提示词,以及来自 `OPENCLAW_LIVE_VIDEO_GENERATION_TIMEOUT_MS` 的每提供商操作上限(默认 `180000`) + - 默认跳过 FAL,因为提供商侧队列延迟可能主导发布时间;传入 `--video-providers fal` 或 `OPENCLAW_LIVE_VIDEO_GENERATION_PROVIDERS="fal"` 可显式运行它 + - 在探测前从你的登录 shell(`~/.profile`)加载提供商环境变量 + - 默认优先使用实时/env API 密钥,而不是已存储的认证 profiles,这样 `auth-profiles.json` 中陈旧的测试密钥就不会掩盖真实 shell 凭证 + - 跳过没有可用认证/profile/模型的提供商 - 默认仅运行 `generate` - - 设置 `OPENCLAW_LIVE_VIDEO_GENERATION_FULL_MODES=1` 后,如果可用,还会运行已声明的转换模式: - - 当提供商声明 `capabilities.imageToVideo.enabled`,且所选提供商 / 模型在共享扫描中接受基于 buffer 的本地图像输入时,运行 `imageToVideo` - - 当提供商声明 `capabilities.videoToVideo.enabled`,且所选提供商 / 模型在共享扫描中接受基于 buffer 的本地视频输入时,运行 `videoToVideo` - - 当前在共享扫描中已声明但被跳过的 `imageToVideo` 提供商: + - 设置 `OPENCLAW_LIVE_VIDEO_GENERATION_FULL_MODES=1` 后,还会在可用时运行已声明的转换模式: + - 当提供商声明 `capabilities.imageToVideo.enabled`,且所选提供商/模型在共享扫描中接受基于 buffer 的本地图像输入时,运行 `imageToVideo` + - 当提供商声明 `capabilities.videoToVideo.enabled`,且所选提供商/模型在共享扫描中接受基于 buffer 的本地视频输入时,运行 `videoToVideo` + - 当前在共享扫描中已声明但跳过的 `imageToVideo` 提供商: - `vydra`,因为内置的 `veo3` 仅支持文本,而内置的 `kling` 需要远程图像 URL - 提供商特定的 Vydra 覆盖: - `OPENCLAW_LIVE_TEST=1 OPENCLAW_LIVE_VYDRA_VIDEO=1 pnpm test:live -- extensions/vydra/vydra.live.test.ts` - - 该文件会运行 `veo3` 文生视频,以及默认使用远程图像 URL fixture 的 `kling` 通道 + - 该文件会运行 `veo3` text-to-video,以及一个默认使用远程图像 URL 夹具的 `kling` 通道 - 当前 `videoToVideo` 实时覆盖: - - 仅 `runway`,且仅当所选模型为 `runway/gen4_aleph` - - 当前在共享扫描中已声明但被跳过的 `videoToVideo` 提供商: - - `alibaba`、`qwen`、`xai`,因为这些路径目前需要远程 `http(s)` / MP4 参考 URL - - `google`,因为当前共享的 Gemini / Veo 通道使用本地基于 buffer 的输入,而该路径在共享扫描中不被接受 - - `openai`,因为当前共享通道缺乏组织特定的视频局部重绘 / remix 访问保证 -- 可选缩小范围: + - 仅 `runway`,当所选模型为 `runway/gen4_aleph` 时 + - 当前在共享扫描中已声明但跳过的 `videoToVideo` 提供商: + - `alibaba`、`qwen`、`xai`,因为这些路径当前需要远程 `http(s)` / MP4 参考 URL + - `google`,因为当前共享 Gemini/Veo 通道使用的是基于本地 buffer 的输入,而该路径在共享扫描中不被接受 + - `openai`,因为当前共享通道缺少对特定组织的视频修补/混剪访问保证 +- 可选收窄: - `OPENCLAW_LIVE_VIDEO_GENERATION_PROVIDERS="google,openai,runway"` - `OPENCLAW_LIVE_VIDEO_GENERATION_MODELS="google/veo-3.1-fast-generate-preview,openai/sora-2,runway/gen4_aleph"` - - `OPENCLAW_LIVE_VIDEO_GENERATION_SKIP_PROVIDERS=""` 以在默认扫描中包含所有提供商,包括 FAL - - `OPENCLAW_LIVE_VIDEO_GENERATION_TIMEOUT_MS=60000` 以在激进冒烟测试中降低每个提供商的操作上限 + - `OPENCLAW_LIVE_VIDEO_GENERATION_SKIP_PROVIDERS=""` 可将每个提供商都纳入默认扫描,包括 FAL + - `OPENCLAW_LIVE_VIDEO_GENERATION_TIMEOUT_MS=60000` 可在激进的冒烟测试运行中降低每个提供商的操作上限 - 可选认证行为: - - `OPENCLAW_LIVE_REQUIRE_PROFILE_KEYS=1` 可强制使用 profile store 认证,并忽略仅来自环境变量的覆盖 + - `OPENCLAW_LIVE_REQUIRE_PROFILE_KEYS=1` 可强制使用 profile 存储认证,并忽略仅 env 的覆盖 -## 媒体实时测试 harness +## 媒体实时测试框架 - 命令:`pnpm test:live:media` -- 目的: - - 通过一个仓库原生入口运行共享的图像、音乐和视频实时测试套件 +- 用途: + - 通过一个仓库原生命令入口运行共享的图像、音乐和视频实时测试套件 - 自动从 `~/.profile` 加载缺失的提供商环境变量 - - 默认自动将每个测试套件缩小到当前具有可用认证的提供商 - - 复用 `scripts/test-live.mjs`,因此心跳和安静模式行为保持一致 + - 默认自动将每个套件收窄到当前具有可用认证的提供商 + - 复用 `scripts/test-live.mjs`,因此心跳和静默模式行为保持一致 - 示例: - `pnpm test:live:media` - `pnpm test:live:media image video --providers openai,google,minimax` - `pnpm test:live:media video --video-providers openai,runway --all-providers` - `pnpm test:live:media music --quiet` -## Docker 运行器(可选的“可在 Linux 中工作”检查) +## Docker 运行器(可选的“在 Linux 中可用”检查) 这些 Docker 运行器分为两类: -- 实时模型运行器:`test:docker:live-models` 和 `test:docker:live-gateway` 仅在仓库 Docker 镜像中运行各自匹配的 profile-key 实时测试文件(`src/agents/models.profiles.live.test.ts` 和 `src/gateway/gateway-models.profiles.live.test.ts`),同时挂载你的本地配置目录和工作区(如果已挂载,也会读取 `~/.profile`)。对应的本地入口点是 `test:live:models-profiles` 和 `test:live:gateway-profiles`。 -- Docker 实时运行器默认使用较小的冒烟上限,以便完整的 Docker 扫描仍然具有可操作性: - `test:docker:live-models` 默认设置 `OPENCLAW_LIVE_MAX_MODELS=12`,而 +- 实时模型运行器:`test:docker:live-models` 和 `test:docker:live-gateway` 仅在仓库 Docker 镜像内运行各自匹配的 profile-key 实时测试文件(`src/agents/models.profiles.live.test.ts` 和 `src/gateway/gateway-models.profiles.live.test.ts`),并挂载你的本地配置目录和工作区(如果有挂载,也会加载 `~/.profile`)。对应的本地入口点是 `test:live:models-profiles` 和 `test:live:gateway-profiles`。 +- Docker 实时运行器默认使用更小的冒烟测试上限,以便完整 Docker 扫描保持可行: + `test:docker:live-models` 默认设置 `OPENCLAW_LIVE_MAX_MODELS=12`,并且 `test:docker:live-gateway` 默认设置 `OPENCLAW_LIVE_GATEWAY_SMOKE=1`、 `OPENCLAW_LIVE_GATEWAY_MAX_MODELS=8`、 `OPENCLAW_LIVE_GATEWAY_STEP_TIMEOUT_MS=45000`,以及 `OPENCLAW_LIVE_GATEWAY_MODEL_TIMEOUT_MS=90000`。当你 - 明确想要更大的完整扫描时,可覆盖这些环境变量。 -- `test:docker:all` 会先通过 `test:docker:live-build` 构建一次实时 Docker 镜像,然后在两个实时 Docker 通道中复用它。它还会通过 `test:docker:e2e-build` 构建一个共享的 `scripts/e2e/Dockerfile` 镜像,并在测试已构建应用的 E2E 容器冒烟运行器中复用它。 -- 容器冒烟运行器:`test:docker:openwebui`、`test:docker:onboard`、`test:docker:npm-onboard-channel-agent`、`test:docker:gateway-network`、`test:docker:mcp-channels`、`test:docker:pi-bundle-mcp-tools`、`test:docker:cron-mcp-cleanup`、`test:docker:plugins`、`test:docker:plugin-update` 和 `test:docker:config-reload` 会启动一个或多个真实容器,并验证更高层级的集成路径。 + 明确想要更大、更穷尽的扫描时,可覆盖这些环境变量。 +- `test:docker:all` 会先通过 `test:docker:live-build` 构建一次实时 Docker 镜像,然后将其复用于两个实时 Docker 通道。它还会通过 `test:docker:e2e-build` 构建一个共享的 `scripts/e2e/Dockerfile` 镜像,并将其复用于演练已构建应用的 E2E 容器冒烟测试运行器。 +- 容器冒烟测试运行器:`test:docker:openwebui`、`test:docker:onboard`、`test:docker:npm-onboard-channel-agent`、`test:docker:gateway-network`、`test:docker:mcp-channels`、`test:docker:pi-bundle-mcp-tools`、`test:docker:cron-mcp-cleanup`、`test:docker:plugins`、`test:docker:plugin-update` 和 `test:docker:config-reload` 会启动一个或多个真实容器,并验证更高层级的集成路径。 -实时模型 Docker 运行器还只会 bind-mount 所需的 CLI 认证 home(如果运行未缩小范围,则会挂载所有受支持的 home),然后在运行前将它们复制到容器 home 中,以便外部 CLI OAuth 可以刷新 token,同时不修改主机认证存储: +实时模型 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`) -- Codex app-server harness 冒烟:`pnpm test:docker:live-codex-harness`(脚本:`scripts/test-live-codex-harness-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`) +- Codex app-server 测试框架冒烟测试:`pnpm test:docker:live-codex-harness`(脚本:`scripts/test-live-codex-harness-docker.sh`) - Gateway 网关 + dev 智能体:`pnpm test:docker:live-gateway`(脚本:`scripts/test-live-gateway-models-docker.sh`) -- Open WebUI 实时冒烟:`pnpm test:docker:openwebui`(脚本:`scripts/e2e/openwebui-docker.sh`) +- Open WebUI 实时冒烟测试:`pnpm test:docker:openwebui`(脚本:`scripts/e2e/openwebui-docker.sh`) - 新手引导向导(TTY,完整脚手架):`pnpm test:docker:onboard`(脚本:`scripts/e2e/onboard-docker.sh`) -- Npm tarball 新手引导 / 渠道 / 智能体冒烟:`pnpm test:docker:npm-onboard-channel-agent` 会在 Docker 中全局安装打包好的 OpenClaw tarball,通过 env-ref 新手引导配置 OpenAI,并默认配置 Telegram,验证启用 plugin 会按需安装其运行时依赖,运行 doctor,并运行一次模拟的 OpenAI 智能体交互。可通过 `OPENCLAW_NPM_ONBOARD_PACKAGE_TGZ=/path/to/openclaw-*.tgz` 复用预构建 tarball,通过 `OPENCLAW_NPM_ONBOARD_HOST_BUILD=0` 跳过主机重建,或通过 `OPENCLAW_NPM_ONBOARD_CHANNEL=discord` 切换渠道。 +- Npm tarball 新手引导/渠道/智能体冒烟测试:`pnpm test:docker:npm-onboard-channel-agent` 会在 Docker 中全局安装已打包的 OpenClaw tarball,通过 env-ref 新手引导配置 OpenAI,并默认配置 Telegram,验证启用插件会按需安装其运行时依赖,运行 doctor,并运行一次模拟的 OpenAI 智能体回合。可通过 `OPENCLAW_NPM_ONBOARD_PACKAGE_TGZ=/path/to/openclaw-*.tgz` 复用预构建 tarball,通过 `OPENCLAW_NPM_ONBOARD_HOST_BUILD=0` 跳过主机构建,或通过 `OPENCLAW_NPM_ONBOARD_CHANNEL=discord` 切换渠道。 - Gateway 网关网络(两个容器,WS 认证 + 健康检查):`pnpm test:docker:gateway-network`(脚本:`scripts/e2e/gateway-network-docker.sh`) -- OpenAI Responses `web_search` 最小推理回归:`pnpm test:docker:openai-web-search-minimal`(脚本:`scripts/e2e/openai-web-search-minimal-docker.sh`)会通过 Gateway 网关运行一个模拟的 OpenAI 服务器,验证 `web_search` 会把 `reasoning.effort` 从 `minimal` 提升到 `low`,然后强制让提供商 schema 拒绝并检查原始细节是否出现在 Gateway 网关日志中。 -- MCP 渠道桥接(带种子数据的 Gateway 网关 + stdio bridge + 原始 Claude 通知帧冒烟):`pnpm test:docker:mcp-channels`(脚本:`scripts/e2e/mcp-channels-docker.sh`) -- Pi bundle MCP 工具(真实 stdio MCP 服务器 + 嵌入式 Pi profile allow / deny 冒烟):`pnpm test:docker:pi-bundle-mcp-tools`(脚本:`scripts/e2e/pi-bundle-mcp-tools-docker.sh`) -- Cron / subagent MCP 清理(真实 Gateway 网关 + 在隔离 cron 和一次性 subagent 运行后拆除 stdio MCP 子进程):`pnpm test:docker:cron-mcp-cleanup`(脚本:`scripts/e2e/cron-mcp-cleanup-docker.sh`) -- Plugins(安装冒烟 + `/plugin` 别名 + Claude bundle 重启语义):`pnpm test:docker:plugins`(脚本:`scripts/e2e/plugins-docker.sh`) -- Plugin 更新无变化冒烟:`pnpm test:docker:plugin-update`(脚本:`scripts/e2e/plugin-update-unchanged-docker.sh`) -- 配置热重载元数据冒烟:`pnpm test:docker:config-reload`(脚本:`scripts/e2e/config-reload-source-docker.sh`) -- 内置 plugin 运行时依赖:`pnpm test:docker:bundled-channel-deps` 默认会构建一个小型 Docker 运行器镜像,在主机上构建并打包一次 OpenClaw,然后将该 tarball 挂载到每个 Linux 安装场景中。可通过 `OPENCLAW_SKIP_DOCKER_BUILD=1` 复用镜像,通过 `OPENCLAW_BUNDLED_CHANNEL_HOST_BUILD=0` 在完成新的本地构建后跳过主机重建,或通过 `OPENCLAW_BUNDLED_CHANNEL_PACKAGE_TGZ=/path/to/openclaw-*.tgz` 指向现有 tarball。 -- 在迭代时,可通过禁用无关场景来缩小内置 plugin 运行时依赖测试范围,例如: +- OpenAI Responses `web_search` 最小推理回归:`pnpm test:docker:openai-web-search-minimal`(脚本:`scripts/e2e/openai-web-search-minimal-docker.sh`)会通过 Gateway 网关运行一个模拟的 OpenAI 服务器,验证 `web_search` 会将 `reasoning.effort` 从 `minimal` 提升为 `low`,然后强制提供商 schema 拒绝,并检查原始细节是否出现在 Gateway 网关日志中。 +- MCP 渠道桥接(已播种 Gateway 网关 + stdio bridge + 原始 Claude 通知帧冒烟测试):`pnpm test:docker:mcp-channels`(脚本:`scripts/e2e/mcp-channels-docker.sh`) +- Pi 内置 MCP 工具(真实 stdio MCP 服务器 + 嵌入式 Pi profile allow/deny 冒烟测试):`pnpm test:docker:pi-bundle-mcp-tools`(脚本:`scripts/e2e/pi-bundle-mcp-tools-docker.sh`) +- Cron/subagent MCP 清理(真实 Gateway 网关 + 在隔离的 cron 和一次性 subagent 运行后清理 stdio MCP 子进程):`pnpm test:docker:cron-mcp-cleanup`(脚本:`scripts/e2e/cron-mcp-cleanup-docker.sh`) +- 插件(安装冒烟测试 + `/plugin` 别名 + Claude 内置包重启语义):`pnpm test:docker:plugins`(脚本:`scripts/e2e/plugins-docker.sh`) +- 插件更新未变化冒烟测试:`pnpm test:docker:plugin-update`(脚本:`scripts/e2e/plugin-update-unchanged-docker.sh`) +- 配置热重载元数据冒烟测试:`pnpm test:docker:config-reload`(脚本:`scripts/e2e/config-reload-source-docker.sh`) +- 内置插件运行时依赖:`pnpm test:docker:bundled-channel-deps` 默认会构建一个小型 Docker 运行器镜像,在主机上构建并打包一次 OpenClaw,然后将该 tarball 挂载到每个 Linux 安装场景中。可通过 `OPENCLAW_SKIP_DOCKER_BUILD=1` 复用镜像,在本地刚完成构建后通过 `OPENCLAW_BUNDLED_CHANNEL_HOST_BUILD=0` 跳过主机构建,或通过 `OPENCLAW_BUNDLED_CHANNEL_PACKAGE_TGZ=/path/to/openclaw-*.tgz` 指向现有 tarball。 +- 在迭代时可通过禁用无关场景来收窄内置插件运行时依赖测试,例如: `OPENCLAW_BUNDLED_CHANNEL_SCENARIOS=0 OPENCLAW_BUNDLED_CHANNEL_UPDATE_SCENARIO=0 OPENCLAW_BUNDLED_CHANNEL_ROOT_OWNED_SCENARIO=0 OPENCLAW_BUNDLED_CHANNEL_SETUP_ENTRY_SCENARIO=0 pnpm test:docker:bundled-channel-deps`。 -如需手动预构建并复用共享的已构建应用镜像: +若要手动预构建并复用共享的已构建应用镜像: ```bash OPENCLAW_DOCKER_E2E_IMAGE=openclaw-docker-e2e:local pnpm test:docker:e2e-build OPENCLAW_DOCKER_E2E_IMAGE=openclaw-docker-e2e:local OPENCLAW_SKIP_DOCKER_BUILD=1 pnpm test:docker:mcp-channels ``` -设置后,诸如 `OPENCLAW_GATEWAY_NETWORK_E2E_IMAGE` 这类测试套件专用镜像覆盖仍然具有更高优先级。当 `OPENCLAW_SKIP_DOCKER_BUILD=1` 指向远程共享镜像时,如果本地尚不存在,该脚本会先拉取镜像。QR 和安装器 Docker 测试保留各自独立的 Dockerfile,因为它们验证的是包 / 安装行为,而不是共享的已构建应用运行时。 +设置特定套件的镜像覆盖(例如 `OPENCLAW_GATEWAY_NETWORK_E2E_IMAGE`)后,仍然会优先生效。当 `OPENCLAW_SKIP_DOCKER_BUILD=1` 指向远程共享镜像时,如果该镜像尚未在本地存在,这些脚本会先拉取它。QR 和安装器 Docker 测试仍保留各自的 Dockerfile,因为它们验证的是打包/安装行为,而不是共享的已构建应用运行时。 -实时模型 Docker 运行器还会以只读方式 bind-mount 当前 checkout,并将其 -暂存到容器内部的临时工作目录中。这样可以保持运行时 -镜像足够精简,同时仍然让 `Vitest` 针对你当前本地的源码 / 配置运行。 -暂存步骤会跳过大型、仅本地使用的缓存以及应用构建输出,例如 -`.pnpm-store`、`.worktrees`、`__openclaw_vitest__`,以及应用本地的 `.build` 或 -Gradle 输出目录,从而避免 Docker 实时运行花费数分钟去复制 -机器特定的产物。 -它们还会设置 `OPENCLAW_SKIP_CHANNELS=1`,这样 Gateway 网关实时 probe 就不会在 -容器内启动真实的 Telegram / Discord / 等渠道 worker。 -`test:docker:live-models` 仍然运行 `pnpm test:live`,因此当你需要缩小范围或排除该 Docker 通道中的 Gateway 网关 -实时覆盖时,也请一并传入 +实时模型 Docker 运行器还会以只读方式绑定挂载当前检出内容,并 +将其暂存到容器内的临时工作目录中。这样可以保持运行时 +镜像轻量,同时仍让 Vitest 针对你精确的本地源代码/配置运行。 +暂存步骤会跳过大型本地专用缓存和应用构建输出,例如 +`.pnpm-store`、`.worktrees`、`__openclaw_vitest__`,以及应用本地 `.build` 或 +Gradle 输出目录,因此 Docker 实时运行不会花费数分钟复制 +与机器相关的工件。 +它们还会设置 `OPENCLAW_SKIP_CHANNELS=1`,以便 Gateway 网关实时探针不会在 +容器中启动真实的 Telegram/Discord 等渠道工作进程。 +`test:docker:live-models` 仍然运行 `pnpm test:live`,因此当你需要收窄或排除该 Docker 通道中的 Gateway 网关实时覆盖时, +也请同时传入 `OPENCLAW_LIVE_GATEWAY_*`。 `test:docker:openwebui` 是一个更高层级的兼容性冒烟测试:它会启动一个 启用了 OpenAI 兼容 HTTP 端点的 OpenClaw Gateway 网关容器, 再针对该 Gateway 网关启动一个固定版本的 Open WebUI 容器,通过 Open WebUI 完成登录,验证 `/api/models` 暴露了 `openclaw/default`,然后通过 -Open WebUI 的 `/api/chat/completions` 代理发送一个真实的 -聊天请求。 +Open WebUI 的 `/api/chat/completions` 代理发送一个 +真实聊天请求。 首次运行可能会明显更慢,因为 Docker 可能需要拉取 -Open WebUI 镜像,而且 Open WebUI 可能需要完成它自己的冷启动设置。 -这个通道需要可用的实时模型 key,而 `OPENCLAW_PROFILE_FILE` -(默认是 `~/.profile`)是在 Docker 化运行中提供它的主要方式。 +Open WebUI 镜像,而且 Open WebUI 可能需要完成自身的冷启动设置。 +该通道需要一个可用的实时模型密钥,并且在 Docker 化运行中, +`OPENCLAW_PROFILE_FILE` +(默认是 `~/.profile`)是提供该密钥的主要方式。 成功运行会打印一个小型 JSON 负载,例如 `{ "ok": true, "model": "openclaw/default", ... }`。 -`test:docker:mcp-channels` 是刻意设计成确定性的,不需要 -真实的 Telegram、Discord 或 iMessage 账号。它会启动一个带种子数据的 Gateway 网关 -容器,启动第二个容器来拉起 `openclaw mcp serve`,然后 -验证路由后的会话发现、转录读取、附件元数据、 -实时事件队列行为、出站发送路由,以及类似 Claude 风格的渠道 + -权限通知是否通过真实的 stdio MCP bridge 正常工作。该通知检查 -会直接检查原始 stdio MCP 帧,因此该冒烟测试验证的是 bridge -实际发出了什么,而不仅仅是某个特定客户端 SDK 恰好暴露了什么。 +`test:docker:mcp-channels` 被刻意设计为确定性的,不需要 +真实的 Telegram、Discord 或 iMessage 账户。它会启动一个已播种的 Gateway 网关 +容器,启动第二个容器来运行 `openclaw mcp serve`,然后 +通过真实的 stdio MCP bridge 验证路由后的会话发现、转录读取、附件元数据、 +实时事件队列行为、出站发送路由,以及 Claude 风格的渠道 + +权限通知。通知检查会直接检查原始 stdio MCP 帧, +因此该冒烟测试验证的是 bridge 实际发出的内容, +而不只是某个特定客户端 SDK 恰好暴露出的内容。 `test:docker:pi-bundle-mcp-tools` 是确定性的,不需要实时 -模型 key。它会构建仓库 Docker 镜像,在容器内启动一个真实的 stdio MCP probe 服务器, -通过嵌入式 Pi bundle MCP 运行时实例化该服务器, -执行工具,然后验证 `coding` 和 `messaging` 会保留 +模型密钥。它会构建仓库 Docker 镜像,在容器中启动一个真实的 stdio MCP 探测服务器, +通过嵌入式 Pi 内置 MCP 运行时实例化该服务器, +执行该工具,然后验证 `coding` 和 `messaging` 会保留 `bundle-mcp` 工具,而 `minimal` 和 `tools.deny: ["bundle-mcp"]` 会将其过滤掉。 -`test:docker:cron-mcp-cleanup` 是确定性的,也不需要实时模型 -key。它会启动一个带种子数据的 Gateway 网关和一个真实的 stdio MCP probe 服务器,运行一个 -隔离的 cron 轮次和一个 `/subagents spawn` 一次性子智能体轮次,然后验证 +`test:docker:cron-mcp-cleanup` 是确定性的,不需要实时模型 +密钥。它会启动一个带真实 stdio MCP 探测服务器的已播种 Gateway 网关,运行一次隔离的 +cron 回合和一次 `/subagents spawn` 的一次性子智能体回合,然后验证 每次运行后 MCP 子进程都会退出。 手动 ACP 自然语言线程冒烟测试(非 CI): - `bun scripts/dev/discord-acp-plain-language-smoke.ts --channel ...` -- 请保留这个脚本用于回归 / 调试工作流。它未来可能还需要再次用于 ACP 线程路由验证,因此不要删除它。 +- 请保留此脚本用于回归/调试工作流。它将来可能仍会用于 ACP 线程路由验证,因此不要删除。 -有用的环境变量: +常用环境变量: -- `OPENCLAW_CONFIG_DIR=...`(默认:`~/.openclaw`)挂载到 `/home/node/.openclaw` -- `OPENCLAW_WORKSPACE_DIR=...`(默认:`~/.openclaw/workspace`)挂载到 `/home/node/.openclaw/workspace` -- `OPENCLAW_PROFILE_FILE=...`(默认:`~/.profile`)挂载到 `/home/node/.profile`,并在运行测试前读取 -- `OPENCLAW_DOCKER_PROFILE_ENV_ONLY=1` 用于只验证从 `OPENCLAW_PROFILE_FILE` 读取的环境变量,使用临时配置 / 工作区目录,并且不挂载外部 CLI 认证 -- `OPENCLAW_DOCKER_CLI_TOOLS_DIR=...`(默认:`~/.cache/openclaw/docker-cli-tools`)挂载到 `/home/node/.npm-global`,用于 Docker 内缓存 CLI 安装 -- `$HOME` 下的外部 CLI 认证目录 / 文件会以只读方式挂载到 `/host-auth...`,然后在测试开始前复制到 `/home/node/...` +- `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_PROFILE_ENV_ONLY=1` 用于仅验证从 `OPENCLAW_PROFILE_FILE` 加载的环境变量,此时使用临时配置/工作区目录且不挂载外部 CLI 认证 +- `OPENCLAW_DOCKER_CLI_TOOLS_DIR=...`(默认:`~/.cache/openclaw/docker-cli-tools`),挂载到 `/home/node/.npm-global`,用于在 Docker 内缓存 CLI 安装 +- 位于 `$HOME` 下的外部 CLI 认证目录/文件会以只读方式挂载到 `/host-auth...` 下,然后在测试开始前复制到 `/home/node/...` - 默认目录:`.minimax` - 默认文件:`~/.codex/auth.json`、`~/.codex/config.toml`、`.claude.json`、`~/.claude/.credentials.json`、`~/.claude/settings.json`、`~/.claude/settings.local.json` - - 缩小范围后的提供商运行只会挂载由 `OPENCLAW_LIVE_PROVIDERS` / `OPENCLAW_LIVE_GATEWAY_PROVIDERS` 推断出的所需目录 / 文件 + - 范围已收窄的提供商运行只会挂载从 `OPENCLAW_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_MODELS=...` / `OPENCLAW_LIVE_MODELS=...` 用于收窄运行范围 - `OPENCLAW_LIVE_GATEWAY_PROVIDERS=...` / `OPENCLAW_LIVE_PROVIDERS=...` 用于在容器内筛选提供商 -- `OPENCLAW_SKIP_DOCKER_BUILD=1` 用于在不需要重建的重跑中复用已有的 `openclaw:local-live` 镜像 -- `OPENCLAW_LIVE_REQUIRE_PROFILE_KEYS=1` 用于确保凭证来自 profile store(而不是环境变量) -- `OPENCLAW_OPENWEBUI_MODEL=...` 用于选择 Gateway 网关向 Open WebUI 冒烟测试暴露的模型 -- `OPENCLAW_OPENWEBUI_PROMPT=...` 用于覆盖 Open WebUI 冒烟测试中使用的 nonce 检查 prompt +- `OPENCLAW_SKIP_DOCKER_BUILD=1` 用于复用现有的 `openclaw:local-live` 镜像,以便在不需要重新构建时重跑 +- `OPENCLAW_LIVE_REQUIRE_PROFILE_KEYS=1` 用于确保凭证来自 profile 存储(而不是 env) +- `OPENCLAW_OPENWEBUI_MODEL=...` 用于选择 Gateway 网关为 Open WebUI 冒烟测试暴露的模型 +- `OPENCLAW_OPENWEBUI_PROMPT=...` 用于覆盖 Open WebUI 冒烟测试使用的 nonce 检查提示词 - `OPENWEBUI_IMAGE=...` 用于覆盖固定的 Open WebUI 镜像标签 ## 文档完整性检查 -修改文档后运行文档检查:`pnpm check:docs`。 -当你还需要页内标题检查时,运行完整的 Mintlify 锚点验证:`pnpm docs:check-links:anchors`。 +编辑文档后运行文档检查:`pnpm check:docs`。 +如果还需要检查页内标题锚点,请运行完整的 Mintlify 锚点验证:`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 网关向导(WS `wizard.start`/`wizard.next`,强制写入配置 + 认证):`src/gateway/gateway.test.ts`(用例:“runs wizard over ws and writes auth token config”) ## 智能体可靠性评估(Skills) -我们已经有一些可在 CI 中安全运行、行为上类似“智能体可靠性评估”的测试: +我们已经有一些对 CI 安全的测试,行为上类似“智能体可靠性评估”: -- 通过真实 Gateway 网关 + 智能体循环执行模拟工具调用(`src/gateway/gateway.test.ts`)。 +- 通过真实 Gateway 网关 + 智能体循环进行模拟工具调用(`src/gateway/gateway.test.ts`)。 - 验证会话接线和配置效果的端到端向导流程(`src/gateway/gateway.test.ts`)。 对于 Skills(见 [Skills](/zh-CN/tools/skills)),目前仍缺少: -- **决策能力:** 当 prompt 中列出多个技能时,智能体是否会选择正确的技能(或避开无关技能)? -- **合规性:** 智能体是否会在使用前读取 `SKILL.md`,并遵循要求的步骤 / 参数? -- **工作流契约:** 用于断言工具顺序、会话历史延续和沙箱边界的多轮场景。 +- **决策:** 当 prompt 中列出 Skills 时,智能体是否会选择正确的 Skill(或避开无关 Skill)? +- **合规:** 智能体在使用前是否会读取 `SKILL.md`,并遵循所需步骤/参数? +- **工作流契约:** 断言工具顺序、会话历史延续和沙箱边界的多轮场景。 -未来的评估应当首先保持确定性: +未来的评估应优先保持确定性: -- 一个使用模拟提供商的场景运行器,用于断言工具调用 + 顺序、技能文件读取以及会话接线。 -- 一小组聚焦技能的场景(使用 vs 避免、门控、prompt 注入)。 -- 只有在 CI 安全测试套件到位之后,才考虑可选的实时评估(按需启用、通过环境变量门控)。 +- 一个使用模拟提供商的场景运行器,用于断言工具调用 + 顺序、Skill 文件读取和会话接线。 +- 一小组面向 Skill 的场景(使用 vs 避免、门控、prompt 注入)。 +- 只有在 CI 安全套件就位之后,才添加可选的实时评估(按需启用、由 env 控制)。 -## 契约测试(plugin 和 channel 形状) +## 契约测试(插件和渠道形态) -契约测试用于验证每个已注册的 plugin 和渠道都符合其 -接口契约。它们会遍历所有已发现的 plugin,并运行一组 -针对形状和行为的断言。默认的 `pnpm test` 单元测试通道会刻意 -跳过这些共享接缝和冒烟文件;当你修改共享渠道或提供商表面时, +契约测试用于验证每个已注册的插件和渠道都符合其 +接口契约。它们会遍历所有已发现的插件,并运行一组形态和行为断言。默认的 `pnpm test` 单元通道会刻意 +跳过这些共享接缝和冒烟测试文件;当你修改共享渠道或提供商表面时, 请显式运行契约命令。 ### 命令 @@ -1031,53 +1034,53 @@ key。它会启动一个带种子数据的 Gateway 网关和一个真实的 stdi 位于 `src/channels/plugins/contracts/*.contract.test.ts`: -- **plugin** - 基本 plugin 形状(id、name、capabilities) +- **plugin** - 基本插件形态(id、name、capabilities) - **setup** - 设置向导契约 - **session-binding** - 会话绑定行为 - **outbound-payload** - 消息负载结构 - **inbound** - 入站消息处理 - **actions** - 渠道操作处理器 - **threading** - 线程 ID 处理 -- **directory** - 目录 / 花名册 API +- **directory** - 目录/成员表 API - **group-policy** - 群组策略执行 ### 提供商状态契约 位于 `src/plugins/contracts/*.contract.test.ts`。 -- **status** - 渠道状态探针 -- **registry** - Plugin 注册表形状 +- **status** - 渠道状态探测 +- **registry** - 插件注册表形态 ### 提供商契约 位于 `src/plugins/contracts/*.contract.test.ts`: - **auth** - 认证流程契约 -- **auth-choice** - 认证选择 / 选择逻辑 +- **auth-choice** - 认证选项/选择 - **catalog** - 模型目录 API -- **discovery** - Plugin 发现 -- **loader** - Plugin 加载 +- **discovery** - 插件发现 +- **loader** - 插件加载 - **runtime** - 提供商运行时 -- **shape** - Plugin 形状 / 接口 +- **shape** - 插件形态/接口 - **wizard** - 设置向导 ### 何时运行 -- 修改 plugin-sdk 导出或子路径后 -- 添加或修改渠道或提供商 plugin 后 -- 重构 plugin 注册或发现逻辑后 +- 修改插件 SDK 导出或子路径后 +- 添加或修改渠道或提供商插件后 +- 重构插件注册或发现逻辑后 -契约测试会在 CI 中运行,不需要真实 API key。 +契约测试会在 CI 中运行,并且不需要真实 API 密钥。 ## 添加回归测试(指南) -当你修复一个在实时测试中发现的提供商 / 模型问题时: +当你修复了在实时测试中发现的提供商/模型问题时: -- 如果可能,添加一个 CI 安全的回归测试(模拟 / stub 提供商,或捕获确切的请求形状变换) -- 如果它天然只能在实时环境中复现(速率限制、认证策略),就让实时测试保持范围小,并通过环境变量按需启用 -- 优先瞄准能捕获该缺陷的最小层级: - - 提供商请求转换 / 重放缺陷 → 直连模型测试 - - Gateway 网关会话 / 历史 / 工具链路缺陷 → Gateway 网关实时冒烟测试或 CI 安全的 Gateway 网关模拟测试 -- SecretRef 遍历防护: +- 如果可能,添加一个对 CI 安全的回归测试(模拟/存根提供商,或捕获精确的请求形态转换) +- 如果它本质上只能在实时环境中复现(速率限制、认证策略),则保持实时测试范围窄,并通过环境变量按需启用 +- 优先锁定能捕获该缺陷的最小层级: + - 提供商请求转换/回放缺陷 → 直连模型测试 + - Gateway 网关会话/历史/工具流水线缺陷 → Gateway 网关实时冒烟测试或对 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 时故意失败,从而防止新类别被静默跳过。 + - 如果你在 `src/secrets/target-registry-data.ts` 中添加了新的 `includeInPlan` SecretRef 目标族,请更新该测试中的 `classifyTargetClass`。该测试会在遇到未分类目标 id 时故意失败,从而避免静默跳过新类别。 diff --git a/docs/zh-CN/install/docker.md b/docs/zh-CN/install/docker.md index 336a2a431..bfd14a8de 100644 --- a/docs/zh-CN/install/docker.md +++ b/docs/zh-CN/install/docker.md @@ -1,48 +1,48 @@ --- read_when: - - 你想要一个容器化的 Gateway 网关,而不是本地安装。 - - 你正在验证 Docker 流程。 -summary: 可选的基于 Docker 的 OpenClaw 设置和新手引导 + - 你想要使用容器化的 Gateway 网关,而不是本地安装 + - 你正在验证 Docker 流程 +summary: OpenClaw 的可选 Docker 安装与新手引导 title: Docker x-i18n: - generated_at: "2026-04-20T18:29:34Z" + generated_at: "2026-04-23T06:40:50Z" model: gpt-5.4 provider: openai - source_hash: f8d3e346ca60daa9908aef0846c9052321087af7dd2c919ce79de4d5925136a2 + source_hash: 60a874ff7a3c5405ba4437a1d6746f0d9268ba7bd4faf3e20cee6079d5fb68d3 source_path: install/docker.md workflow: 15 --- # Docker(可选) -Docker **是可选的**。仅当你想要一个容器化的 Gateway 网关,或需要验证 Docker 流程时才使用它。 +Docker **是可选的**。只有在你想要容器化的 Gateway 网关,或验证 Docker 流程时才使用它。 ## Docker 适合我吗? -- **是**:你想要一个隔离的、可随时丢弃的 Gateway 网关环境,或者希望在没有本地安装的主机上运行 OpenClaw。 +- **是**:你想要一个隔离的、可随时丢弃的 Gateway 网关 环境,或想在没有本地安装的主机上运行 OpenClaw。 - **否**:你是在自己的机器上运行,只想要最快的开发循环。请改用常规安装流程。 -- **沙箱注意事项**:默认的沙箱后端在启用沙箱隔离时会使用 Docker,但沙箱隔离默认是关闭的,并且**不**要求整个 Gateway 网关都运行在 Docker 中。也提供 SSH 和 OpenShell 沙箱后端。请参阅 [沙箱隔离](/zh-CN/gateway/sandboxing)。 +- **沙箱注意事项**:启用沙箱隔离时,默认沙箱后端会使用 Docker,但沙箱隔离默认是关闭的,并且**不**要求整个 Gateway 网关 都运行在 Docker 中。也提供 SSH 和 OpenShell 沙箱后端。参见 [沙箱隔离](/zh-CN/gateway/sandboxing)。 -## 前提条件 +## 先决条件 - Docker Desktop(或 Docker Engine)+ Docker Compose v2 -- 镜像构建至少需要 2 GB 内存(在 1 GB 主机上,`pnpm install` 可能因 OOM 被终止,并返回退出码 137) +- 镜像构建至少需要 2 GB 内存(在 1 GB 主机上,`pnpm install` 可能因 OOM 而以退出码 137 被终止) - 足够的磁盘空间用于镜像和日志 - 如果在 VPS/公网主机上运行,请查看 [网络暴露的安全加固](/zh-CN/gateway/security), - 特别是 Docker 的 `DOCKER-USER` 防火墙策略。 + 特别是 Docker `DOCKER-USER` 防火墙策略。 ## 容器化 Gateway 网关 - 在仓库根目录运行设置脚本: + 在仓库根目录运行安装脚本: ```bash ./scripts/docker/setup.sh ``` - 这会在本地构建 Gateway 网关镜像。如果要改用预构建镜像: + 这会在本地构建 Gateway 网关 镜像。若要改用预构建镜像: ```bash export OPENCLAW_IMAGE="ghcr.io/openclaw/openclaw:latest" @@ -56,23 +56,23 @@ Docker **是可选的**。仅当你想要一个容器化的 Gateway 网关,或 - 设置脚本会自动运行新手引导。它将会: + 安装脚本会自动运行新手引导。它会: - - 提示你输入提供商 API 密钥 - - 生成一个 Gateway 网关令牌并写入 `.env` + - 提示输入提供商 API 密钥 + - 生成一个 Gateway 网关 令牌并将其写入 `.env` - 通过 Docker Compose 启动 Gateway 网关 - 在设置期间,启动前的新手引导和配置写入会直接通过 - `openclaw-gateway` 运行。`openclaw-cli` 用于 Gateway 网关容器已经存在后 - 你再执行的命令。 + 在安装期间,启动前的新手引导和配置写入会直接通过 + `openclaw-gateway` 执行。`openclaw-cli` 用于在 + Gateway 网关 容器已存在之后运行的命令。 - + 在浏览器中打开 `http://127.0.0.1:18789/`,并将已配置的 - 共享密钥粘贴到“设置”中。设置脚本默认会将一个令牌写入 `.env`;如果你把容器配置切换为密码认证,请改用该密码。 + 共享密钥粘贴到 Settings 中。安装脚本默认会将令牌写入 `.env`;如果你把容器配置切换为密码认证,请改用该密码。 - 需要再次获取 URL 吗? + 想再次获取 URL? ```bash docker compose run --rm openclaw-cli dashboard --no-open @@ -84,7 +84,7 @@ Docker **是可选的**。仅当你想要一个容器化的 Gateway 网关,或 使用 CLI 容器添加消息渠道: ```bash - # WhatsApp(QR) + # WhatsApp(二维码) docker compose run --rm openclaw-cli channels login # Telegram @@ -101,7 +101,7 @@ Docker **是可选的**。仅当你想要一个容器化的 Gateway 网关,或 ### 手动流程 -如果你更喜欢自己逐步执行,而不是使用设置脚本: +如果你更喜欢自行运行每个步骤,而不是使用安装脚本: ```bash docker build -t openclaw:local -f Dockerfile . @@ -114,30 +114,30 @@ docker compose up -d openclaw-gateway 请从仓库根目录运行 `docker compose`。如果你启用了 `OPENCLAW_EXTRA_MOUNTS` -或 `OPENCLAW_HOME_VOLUME`,设置脚本会写入 `docker-compose.extra.yml`; -请使用 `-f docker-compose.yml -f docker-compose.extra.yml` 将其一并包含。 +或 `OPENCLAW_HOME_VOLUME`,安装脚本会写入 `docker-compose.extra.yml`; +请通过 `-f docker-compose.yml -f docker-compose.extra.yml` 将其包含进来。 由于 `openclaw-cli` 共享 `openclaw-gateway` 的网络命名空间,它是一个 -启动后的工具。在执行 `docker compose up -d openclaw-gateway` 之前,请通过 -带有 `--no-deps --entrypoint node` 的 `openclaw-gateway` 来运行新手引导 -和设置阶段的配置写入。 +启动后工具。在 `docker compose up -d openclaw-gateway` 之前,请通过带有 +`--no-deps --entrypoint node` 的 `openclaw-gateway` +运行新手引导和安装时配置写入。 ### 环境变量 -设置脚本接受以下可选环境变量: +安装脚本支持以下可选环境变量: -| Variable | Purpose | -| ------------------------------ | ---------------------------------------------------------------- | -| `OPENCLAW_IMAGE` | 使用远程镜像,而不是在本地构建 | -| `OPENCLAW_DOCKER_APT_PACKAGES` | 在构建期间安装额外的 apt 软件包(以空格分隔) | -| `OPENCLAW_EXTENSIONS` | 在构建时预安装扩展依赖(以空格分隔的名称) | -| `OPENCLAW_EXTRA_MOUNTS` | 额外的主机 bind mount(以逗号分隔的 `source:target[:opts]`) | -| `OPENCLAW_HOME_VOLUME` | 将 `/home/node` 持久化到一个具名 Docker volume 中 | -| `OPENCLAW_SANDBOX` | 选择启用沙箱引导(`1`、`true`、`yes`、`on`) | -| `OPENCLAW_DOCKER_SOCKET` | 覆盖 Docker socket 路径 | +| 变量 | 用途 | +| ------------------------------ | --------------------------------------------------------------- | +| `OPENCLAW_IMAGE` | 使用远程镜像,而不是在本地构建 | +| `OPENCLAW_DOCKER_APT_PACKAGES` | 在构建期间安装额外的 apt 软件包(以空格分隔) | +| `OPENCLAW_EXTENSIONS` | 在构建时预安装插件依赖(以空格分隔的名称) | +| `OPENCLAW_EXTRA_MOUNTS` | 额外的宿主机绑定挂载(以逗号分隔的 `source:target[:opts]`) | +| `OPENCLAW_HOME_VOLUME` | 将 `/home/node` 持久化到命名 Docker 卷中 | +| `OPENCLAW_SANDBOX` | 选择启用沙箱引导(`1`、`true`、`yes`、`on`) | +| `OPENCLAW_DOCKER_SOCKET` | 覆盖 Docker socket 路径 | ### 健康检查 @@ -148,9 +148,9 @@ curl -fsS http://127.0.0.1:18789/healthz # 存活性 curl -fsS http://127.0.0.1:18789/readyz # 就绪性 ``` -Docker 镜像内置了一个 `HEALTHCHECK`,会 ping `/healthz`。 +Docker 镜像包含一个内置的 `HEALTHCHECK`,会探测 `/healthz`。 如果检查持续失败,Docker 会将容器标记为 `unhealthy`, -编排系统可以重启或替换它。 +编排系统就可以重启或替换它。 需要认证的深度健康快照: @@ -160,53 +160,52 @@ docker compose exec openclaw-gateway node dist/index.js health --token "$OPENCLA ### LAN 与 loopback -`scripts/docker/setup.sh` 默认设置 `OPENCLAW_GATEWAY_BIND=lan`,这样通过 Docker 端口发布时,主机就可以访问 -`http://127.0.0.1:18789`。 +`scripts/docker/setup.sh` 默认将 `OPENCLAW_GATEWAY_BIND=lan`,以便宿主机能够通过 +Docker 端口发布访问 `http://127.0.0.1:18789`。 -- `lan`(默认):主机浏览器和主机 CLI 都可以访问已发布的 Gateway 网关端口。 +- `lan`(默认):宿主机浏览器和宿主机 CLI 都可以访问已发布的 Gateway 网关 端口。 - `loopback`:只有容器网络命名空间内的进程才能直接访问 Gateway 网关。 -请在 `gateway.bind` 中使用 bind mode 的值(`lan` / `loopback` / `custom` / -`tailnet` / `auto`),不要使用像 `0.0.0.0` 或 `127.0.0.1` 这样的主机别名。 +请在 `gateway.bind` 中使用绑定模式值(`lan` / `loopback` / `custom` / +`tailnet` / `auto`),而不是宿主机别名,如 `0.0.0.0` 或 `127.0.0.1`。 ### 存储与持久化 -Docker Compose 会将 `OPENCLAW_CONFIG_DIR` bind-mount 到 `/home/node/.openclaw`, -并将 `OPENCLAW_WORKSPACE_DIR` bind-mount 到 `/home/node/.openclaw/workspace`,因此这些路径在容器被替换后 -仍然会保留。 +Docker Compose 会将 `OPENCLAW_CONFIG_DIR` 绑定挂载到 `/home/node/.openclaw`, +并将 `OPENCLAW_WORKSPACE_DIR` 绑定挂载到 `/home/node/.openclaw/workspace`,因此这些路径在容器替换后仍会保留。 -这个已挂载的配置目录也是 OpenClaw 存放以下内容的位置: +这个已挂载的配置目录是 OpenClaw 存放以下内容的位置: - 用于行为配置的 `openclaw.json` -- 用于存储提供商 OAuth/API 密钥认证信息的 `agents//agent/auth-profiles.json` -- 用于保存基于环境变量的运行时密钥(例如 `OPENCLAW_GATEWAY_TOKEN`)的 `.env` +- 用于存储提供商 OAuth/API 密钥认证的 `agents//agent/auth-profiles.json` +- 用于基于环境变量的运行时密钥(如 `OPENCLAW_GATEWAY_TOKEN`)的 `.env` -有关 VM 部署中完整的持久化细节,请参阅 -[Docker VM Runtime - 数据会持久保存到哪里](/zh-CN/install/docker-vm-runtime#what-persists-where)。 +有关 VM 部署中持久化细节的完整说明,请参见 +[Docker VM Runtime - What persists where](/zh-CN/install/docker-vm-runtime#what-persists-where)。 **磁盘增长热点:**请关注 `media/`、会话 JSONL 文件、`cron/runs/*.jsonl`, 以及 `/tmp/openclaw/` 下的滚动文件日志。 -### Shell 辅助工具(可选) +### Shell 帮助脚本(可选) -为了更方便地进行日常 Docker 管理,请安装 `ClawDock`: +为了更轻松地进行日常 Docker 管理,请安装 `ClawDock`: ```bash mkdir -p ~/.clawdock && curl -sL https://raw.githubusercontent.com/openclaw/openclaw/main/scripts/clawdock/clawdock-helpers.sh -o ~/.clawdock/clawdock-helpers.sh echo 'source ~/.clawdock/clawdock-helpers.sh' >> ~/.zshrc && source ~/.zshrc ``` -如果你之前是通过旧的 `scripts/shell-helpers/clawdock-helpers.sh` 原始路径安装 ClawDock,请重新运行上面的安装命令,以便让你的本地辅助文件跟踪新位置。 +如果你之前是从旧路径 `scripts/shell-helpers/clawdock-helpers.sh` 安装 ClawDock 的原始文件,请重新运行上面的安装命令,以便你的本地帮助文件跟踪新位置。 -然后你可以使用 `clawdock-start`、`clawdock-stop`、`clawdock-dashboard` 等命令。运行 -`clawdock-help` 可查看所有命令。 -完整辅助指南请参阅 [ClawDock](/zh-CN/install/clawdock)。 +然后使用 `clawdock-start`、`clawdock-stop`、`clawdock-dashboard` 等命令。 +运行 `clawdock-help` 可查看所有命令。 +完整帮助指南请参见 [ClawDock](/zh-CN/install/clawdock)。 - + ```bash export OPENCLAW_SANDBOX=1 ./scripts/docker/setup.sh @@ -220,7 +219,7 @@ echo 'source ~/.clawdock/clawdock-helpers.sh' >> ~/.zshrc && source ~/.zshrc ./scripts/docker/setup.sh ``` - 只有在沙箱前提条件检查通过后,脚本才会挂载 `docker.sock`。如果 + 脚本只有在沙箱先决条件通过后才会挂载 `docker.sock`。如果 沙箱设置无法完成,脚本会将 `agents.defaults.sandbox.mode` 重置为 `off`。 @@ -238,14 +237,14 @@ echo 'source ~/.clawdock/clawdock-helpers.sh' >> ~/.zshrc && source ~/.zshrc `openclaw-cli` 使用 `network_mode: "service:openclaw-gateway"`,因此 CLI - 命令可以通过 `127.0.0.1` 访问 Gateway 网关。请将此视为一个共享的 - 信任边界。compose 配置为 `openclaw-cli` 去掉了 `NET_RAW`/`NET_ADMIN`,并启用了 + 命令可以通过 `127.0.0.1` 访问 Gateway 网关。请将此视为共享的 + 信任边界。compose 配置对 `openclaw-cli` 去除了 `NET_RAW`/`NET_ADMIN`,并启用了 `no-new-privileges`。 镜像以 `node`(uid 1000)身份运行。如果你在 - `/home/node/.openclaw` 上看到权限错误,请确保主机 bind mount 归 uid 1000 所有: + `/home/node/.openclaw` 上看到权限错误,请确保宿主机绑定挂载归 uid 1000 所有: ```bash sudo chown -R 1000:1000 /path/to/openclaw-config /path/to/openclaw-workspace @@ -253,9 +252,9 @@ echo 'source ~/.clawdock/clawdock-helpers.sh' >> ~/.zshrc && source ~/.zshrc - - 请安排你的 Dockerfile,使依赖层可以被缓存。这样可以避免在 lockfile 未变化时 - 反复运行 `pnpm install`: + + 请安排好 Dockerfile 的顺序,以便缓存依赖层。这样可避免在锁文件未变化时 + 重复运行 `pnpm install`: ```dockerfile FROM node:24-bookworm @@ -277,57 +276,59 @@ echo 'source ~/.clawdock/clawdock-helpers.sh' >> ~/.zshrc && source ~/.zshrc - - 默认镜像以安全优先为设计原则,并以非 root 用户 `node` 运行。如果你想要一个功能更完整的容器: + + 默认镜像以安全优先为设计目标,并以非 root 的 `node` 身份运行。若需要更 + 完整功能的容器: 1. **持久化 `/home/node`**:`export OPENCLAW_HOME_VOLUME="openclaw_home"` - 2. **预装系统依赖**:`export OPENCLAW_DOCKER_APT_PACKAGES="git curl jq"` + 2. **烘焙系统依赖**:`export OPENCLAW_DOCKER_APT_PACKAGES="git curl jq"` 3. **安装 Playwright 浏览器**: ```bash docker compose run --rm openclaw-cli \ node /app/node_modules/playwright-core/cli.js install chromium ``` 4. **持久化浏览器下载内容**:设置 - `PLAYWRIGHT_BROWSERS_PATH=/home/node/.cache/ms-playwright`,并使用 + `PLAYWRIGHT_BROWSERS_PATH=/home/node/.cache/ms-playwright` 并使用 `OPENCLAW_HOME_VOLUME` 或 `OPENCLAW_EXTRA_MOUNTS`。 如果你在向导中选择 OpenAI Codex OAuth,它会打开一个浏览器 URL。在 - Docker 或无头环境中,请复制你最终跳转到的完整重定向 URL,并将其粘贴回 - 向导中以完成认证。 + Docker 或无头环境中,请复制你最终到达的完整重定向 URL,并将其粘贴回 + 向导以完成认证。 主 Docker 镜像使用 `node:24-bookworm`,并发布 OCI 基础镜像 注解,包括 `org.opencontainers.image.base.name`、 - `org.opencontainers.image.source` 等。请参阅 + `org.opencontainers.image.source` 等。参见 [OCI image annotations](https://github.com/opencontainers/image-spec/blob/main/annotations.md)。 ### 在 VPS 上运行? -请参阅 [Hetzner(Docker VPS)](/zh-CN/install/hetzner) 和 -[Docker VM Runtime](/zh-CN/install/docker-vm-runtime),了解共享 VM 部署步骤, -包括二进制预构建、持久化和更新。 +有关共享 VM 部署步骤,包括二进制预烘焙、持久化和更新, +请参见 [Hetzner (Docker VPS)](/zh-CN/install/hetzner) 和 +[Docker VM Runtime](/zh-CN/install/docker-vm-runtime)。 ## 智能体沙箱 -当启用 `agents.defaults.sandbox` 并使用 Docker 后端时,Gateway 网关会在隔离的 Docker -容器中运行智能体工具执行(shell、文件读写等),而 Gateway 网关本身仍然保留在主机上。这样你就能在不将整个 -Gateway 网关容器化的前提下,为不受信任或多租户的智能体会话建立一道硬隔离墙。 +当使用 Docker 后端启用 `agents.defaults.sandbox` 时,Gateway 网关 +会在隔离的 Docker 容器中运行智能体工具执行(shell、文件读/写等), +而 Gateway 网关 本身仍运行在宿主机上。这为不受信任或多租户的智能体会话 +提供了一道硬隔离边界,而无需将整个 Gateway 网关 容器化。 -沙箱范围可以是每个智能体(默认)、每个会话,或共享。每种范围 -都会获得各自挂载到 `/workspace` 的工作区。你还可以配置 -工具允许/拒绝策略、网络隔离、资源限制以及浏览器容器。 +沙箱范围可以是按智能体(默认)、按会话,或共享。每种范围 +都会获得各自挂载在 `/workspace` 的工作区。你还可以配置 +工具允许/拒绝策略、网络隔离、资源限制和浏览器容器。 -有关完整配置、镜像、安全说明和多智能体配置文件,请参阅: +有关完整配置、镜像、安全说明和多智能体配置文件,请参见: - [沙箱隔离](/zh-CN/gateway/sandboxing) -- 完整的沙箱参考 - [OpenShell](/zh-CN/gateway/openshell) -- 对沙箱容器的交互式 shell 访问 -- [多智能体沙箱与工具](/zh-CN/tools/multi-agent-sandbox-tools) -- 按智能体覆盖 +- [Multi-Agent Sandbox and Tools](/zh-CN/tools/multi-agent-sandbox-tools) -- 按智能体覆盖 ### 快速启用 @@ -354,29 +355,29 @@ scripts/sandbox-setup.sh - 使用 + 请使用 [`scripts/sandbox-setup.sh`](https://github.com/openclaw/openclaw/blob/main/scripts/sandbox-setup.sh) 构建沙箱镜像,或将 `agents.defaults.sandbox.docker.image` 设置为你的自定义镜像。 容器会按需为每个会话自动创建。 - 将 `docker.user` 设置为与你挂载的工作区所有权匹配的 UID:GID, + 将 `docker.user` 设置为与你挂载工作区所有权匹配的 UID:GID, 或对工作区文件夹执行 chown。 OpenClaw 使用 `sh -lc`(登录 shell)运行命令,这会加载 - `/etc/profile`,并且可能重置 PATH。请设置 `docker.env.PATH` 以便在前面添加你的 - 自定义工具路径,或者在你的 Dockerfile 中向 `/etc/profile.d/` 添加脚本。 + `/etc/profile`,并且可能会重置 PATH。请设置 `docker.env.PATH` 以预先添加你的 + 自定义工具路径,或在你的 Dockerfile 中将脚本添加到 `/etc/profile.d/` 下。 - VM 至少需要 2 GB 内存。请使用更大的机器规格后重试。 + 虚拟机至少需要 2 GB 内存。请使用更大的机器规格后重试。 - - 获取一个新的仪表板链接,并批准该浏览器设备: + + 获取一个新的 dashboard 链接并批准浏览器设备: ```bash docker compose run --rm openclaw-cli dashboard --no-open @@ -384,12 +385,12 @@ scripts/sandbox-setup.sh docker compose run --rm openclaw-cli devices approve ``` - 更多细节: [Dashboard](/web/dashboard)、[Devices](/cli/devices)。 + 更多细节: [Dashboard](/zh-CN/web/dashboard)、[Devices](/zh-CN/cli/devices)。 - - 重置 Gateway 网关模式和绑定: + + 重置 Gateway 网关 模式和绑定: ```bash docker compose run --rm openclaw-cli config set --batch-json '[{"path":"gateway.mode","value":"local"},{"path":"gateway.bind","value":"lan"}]' @@ -401,8 +402,8 @@ scripts/sandbox-setup.sh ## 相关内容 -- [安装概览](/zh-CN/install) — 所有安装方式 +- [Install Overview](/zh-CN/install) — 所有安装方式 - [Podman](/zh-CN/install/podman) — Docker 的 Podman 替代方案 -- [ClawDock](/zh-CN/install/clawdock) — Docker Compose 社区配置 -- [更新](/zh-CN/install/updating) — 让 OpenClaw 保持最新 -- [配置](/zh-CN/gateway/configuration) — 安装后的 Gateway 网关配置 +- [ClawDock](/zh-CN/install/clawdock) — Docker Compose 社区安装方案 +- [Updating](/zh-CN/install/updating) — 让 OpenClaw 保持最新 +- [Configuration](/zh-CN/gateway/configuration) — 安装后的 Gateway 网关 配置 diff --git a/docs/zh-CN/install/hostinger.md b/docs/zh-CN/install/hostinger.md index 28374a12d..5004d9dbd 100644 --- a/docs/zh-CN/install/hostinger.md +++ b/docs/zh-CN/install/hostinger.md @@ -1,15 +1,15 @@ --- read_when: - 在 Hostinger 上设置 OpenClaw - - 正在寻找适用于 OpenClaw 的托管 VPS + - 正在寻找适合 OpenClaw 的托管 VPS - 使用 Hostinger 一键安装 OpenClaw summary: 在 Hostinger 上托管 OpenClaw title: Hostinger x-i18n: - generated_at: "2026-04-13T13:14:20Z" + generated_at: "2026-04-23T06:41:03Z" model: gpt-5.4 provider: openai - source_hash: cf173cdcf6344f8ee22e839a27f4e063a3a102186f9acc07c4a33d4794e2c034 + source_hash: 1ee70d24fd1c3a6de503fc967d7e726d701f84cc6717fe7a3bc65a6a28e386ea source_path: install/hostinger.md workflow: 15 --- @@ -18,26 +18,26 @@ x-i18n: 通过 **一键安装** 托管部署或 **VPS** 安装,在 [Hostinger](https://www.hostinger.com/openclaw) 上运行持久化的 OpenClaw Gateway 网关。 -## 前提条件 +## 先决条件 - Hostinger 账户([注册](https://www.hostinger.com/openclaw)) -- 大约 5-10 分钟 +- 大约 5 - 10 分钟 -## 选项 A:一键安装 OpenClaw +## 方案 A:一键安装 OpenClaw -最快的入门方式。Hostinger 会处理基础设施、Docker 和自动更新。 +最快的入门方式。Hostinger 会负责基础设施、Docker 和自动更新。 - 1. 在 [Hostinger OpenClaw 页面](https://www.hostinger.com/openclaw) 上,选择一个托管 OpenClaw 套餐并完成结账。 + 1. 前往 [Hostinger OpenClaw 页面](https://www.hostinger.com/openclaw),选择一个托管 OpenClaw 套餐并完成结账。 - 在结账过程中,你可以选择 **Ready-to-Use AI** 积分,这些积分已预先购买,并会立即在 OpenClaw 内集成——无需其他提供商的外部账户或 API 密钥。你可以立刻开始聊天。或者,你也可以在设置过程中提供你自己的 Anthropic、OpenAI、Google Gemini 或 xAI 密钥。 + 在结账过程中,你可以选择 **Ready-to-Use AI** 点数,这些点数会预先购买并立即集成到 OpenClaw 中——无需其他提供商的外部账户或 API 密钥。你可以立即开始聊天。或者,你也可以在设置期间提供自己来自 Anthropic、OpenAI、Google Gemini 或 xAI 的密钥。 - + 选择一个或多个要连接的渠道: - **WhatsApp** —— 扫描设置向导中显示的二维码。 @@ -46,21 +46,21 @@ x-i18n: - 点击 **Finish** 以部署实例。准备就绪后,可从 hPanel 中的 **OpenClaw Overview** 访问 OpenClaw 仪表板。 + 点击 **Finish** 来部署实例。实例准备就绪后,可从 hPanel 中的 **OpenClaw Overview** 访问 OpenClaw 控制面板。 -## 选项 B:在 VPS 上运行 OpenClaw +## 方案 B:在 VPS 上运行 OpenClaw -对你的服务器拥有更多控制权。Hostinger 会通过 Docker 在你的 VPS 上部署 OpenClaw,而你可通过 hPanel 中的 **Docker Manager** 进行管理。 +你可以对服务器拥有更多控制权。Hostinger 会通过 Docker 在你的 VPS 上部署 OpenClaw,而你可以通过 hPanel 中的 **Docker Manager** 进行管理。 - 1. 在 [Hostinger OpenClaw 页面](https://www.hostinger.com/openclaw) 上,选择一个 OpenClaw on VPS 套餐并完成结账。 + 1. 前往 [Hostinger OpenClaw 页面](https://www.hostinger.com/openclaw),选择一个 VPS 上的 OpenClaw 套餐并完成结账。 - 你可以在结账过程中选择 **Ready-to-Use AI** 积分——这些积分已预先购买,并会立即在 OpenClaw 内集成,因此你无需任何外部账户或其他提供商的 API 密钥即可开始聊天。 + 你可以在结账时选择 **Ready-to-Use AI** 点数——这些点数会预先购买并立即集成到 OpenClaw 中,因此你无需任何外部账户或其他提供商的 API 密钥即可开始聊天。 @@ -68,32 +68,32 @@ x-i18n: VPS 配置完成后,填写以下配置字段: - - **Gateway token** —— 自动生成;请保存以便后续使用。 - - **WhatsApp number** —— 带国家区号的你的号码(可选)。 + - **Gateway token** —— 自动生成;请保存以备后用。 + - **WhatsApp number** —— 你的带国家区号的号码(可选)。 - **Telegram bot token** —— 来自 [BotFather](https://t.me/BotFather)(可选)。 - - **API keys** —— 仅当你在结账时未选择 Ready-to-Use AI 积分时才需要。 + - **API keys** —— 仅当你在结账时未选择 Ready-to-Use AI 点数时才需要。 - 点击 **Deploy**。运行后,在 hPanel 中点击 **Open** 打开 OpenClaw 仪表板。 + 点击 **Deploy**。运行后,可在 hPanel 中点击 **Open** 打开 OpenClaw 控制面板。 -日志、重启和更新均可直接在 hPanel 的 Docker Manager 界面中管理。要更新,请在 Docker Manager 中点击 **Update**,这将拉取最新镜像。 +日志、重启和更新都可直接在 hPanel 的 Docker Manager 界面中管理。要更新,请在 Docker Manager 中点击 **Update**,这会拉取最新镜像。 ## 验证你的设置 -在你已连接的渠道中向你的助手发送“Hi”。OpenClaw 会回复你,并引导你完成初始偏好设置。 +在你已连接的渠道中,向你的助手发送“Hi”。OpenClaw 会回复,并引导你完成初始偏好设置。 ## 故障排除 -**仪表板无法加载** —— 等待几分钟,让容器完成配置。检查 hPanel 中 Docker Manager 的日志。 +**控制面板无法加载** —— 等待几分钟,让容器完成配置。检查 hPanel 中 Docker Manager 的日志。 -**Docker 容器持续重启** —— 打开 Docker Manager 日志,查看是否存在配置错误(缺少令牌、API 密钥无效)。 +**Docker 容器不断重启** —— 打开 Docker Manager 日志,查看是否存在配置错误(缺少令牌、API 密钥无效)。 -**Telegram 机器人没有响应** —— 直接通过 Telegram 将你的配对代码消息发送到 OpenClaw 聊天中,以完成连接。 +**Telegram 机器人没有响应** —— 直接从 Telegram 将你的配对代码消息作为消息发送到 OpenClaw 聊天中,以完成连接。 ## 后续步骤 diff --git a/docs/zh-CN/install/northflank.mdx b/docs/zh-CN/install/northflank.mdx index c28d94211..abb9fcaac 100644 --- a/docs/zh-CN/install/northflank.mdx +++ b/docs/zh-CN/install/northflank.mdx @@ -1,49 +1,51 @@ --- read_when: - 将 OpenClaw 部署到 Northflank - - 你想要一种支持基于浏览器控制 UI 的一键云部署方式 -summary: 使用一键模板在 Northflank 上部署 OpenClaw + - 你希望通过一键云部署获得基于浏览器的 Control UI +summary: 通过一键模板在 Northflank 上部署 OpenClaw title: Northflank x-i18n: - generated_at: "2026-04-05T08:28:00Z" + generated_at: "2026-04-23T06:41:06Z" model: gpt-5.4 provider: openai - source_hash: 6b659607621ad2b38e61644f41cf3e5ae1a32761469223c460952a832d3b93fe + source_hash: 5610e076b09d50c23186f1f8db16c039c99d287c34ef6fd71d4272bc527b0388 source_path: install/northflank.mdx workflow: 15 --- -使用一键模板在 Northflank 上部署 OpenClaw,并通过网页控制 UI 访问它。 +# Northflank + +通过一键模板在 Northflank 上部署 OpenClaw,并通过网页 Control UI 访问它。 这是最简单的“服务器上无需终端”路径:Northflank 会为你运行 Gateway 网关。 ## 如何开始 -1. 点击 [Deploy OpenClaw](https://northflank.com/stacks/deploy-openclaw) 打开模板。 -2. 如果你还没有账户,请先在 [Northflank](https://app.northflank.com/signup) 上创建一个。 -3. 点击 **Deploy OpenClaw now**。 -4. 设置必需的环境变量:`OPENCLAW_GATEWAY_TOKEN`(请使用高强度随机值)。 -5. 点击 **Deploy stack** 以构建并运行 OpenClaw 模板。 -6. 等待部署完成,然后点击 **View resources**。 +1. 点击 [部署 OpenClaw](https://northflank.com/stacks/deploy-openclaw) 打开模板。 +2. 如果你还没有账号,请先在 [Northflank 注册账号](https://app.northflank.com/signup)。 +3. 点击 **立即部署 OpenClaw**。 +4. 设置必需的环境变量:`OPENCLAW_GATEWAY_TOKEN`(请使用强随机值)。 +5. 点击 **部署堆栈** 以构建并运行 OpenClaw 模板。 +6. 等待部署完成,然后点击 **查看资源**。 7. 打开 OpenClaw 服务。 -8. 打开位于 `/openclaw` 的公开 OpenClaw URL,并使用已配置的共享密钥连接。此模板默认使用 `OPENCLAW_GATEWAY_TOKEN`;如果你将其替换为 password 认证,请改用该密码。 +8. 打开公开的 OpenClaw URL,并访问 `/openclaw`,然后使用已配置的共享密钥连接。此模板默认使用 `OPENCLAW_GATEWAY_TOKEN`;如果你改用密码认证,请改用该密码。 ## 你将获得 -- 托管的 OpenClaw Gateway 网关 + 控制 UI +- 托管的 OpenClaw Gateway 网关 + Control UI - 通过 Northflank Volume(`/data`)提供的持久化存储,因此 `openclaw.json`、 - 每个智能体的 `auth-profiles.json`、渠道/provider 状态、会话以及 + 每个智能体的 `auth-profiles.json`、渠道/提供商状态、会话以及 工作区都能在重新部署后保留 ## 连接一个渠道 -使用位于 `/openclaw` 的控制 UI,或通过 SSH 运行 `openclaw onboard` 获取渠道设置说明: +使用 `/openclaw` 下的 Control UI,或通过 SSH 运行 `openclaw onboard` 获取渠道设置说明: -- [Telegram](/channels/telegram)(最快——只需要一个 bot token) -- [Discord](/channels/discord) -- [所有渠道](/channels) +- [Telegram](/zh-CN/channels/telegram)(最快 —— 只需要一个机器人令牌) +- [Discord](/zh-CN/channels/discord) +- [所有渠道](/zh-CN/channels) ## 后续步骤 -- 设置消息渠道:[Channels](/channels) -- 配置 Gateway 网关:[Gateway 配置](/gateway/configuration) -- 保持 OpenClaw 为最新版本:[更新](/install/updating) +- 设置消息渠道:[Channels](/zh-CN/channels) +- 配置 Gateway 网关:[Gateway 配置](/zh-CN/gateway/configuration) +- 保持 OpenClaw 为最新版本:[更新](/zh-CN/install/updating) diff --git a/docs/zh-CN/install/podman.md b/docs/zh-CN/install/podman.md index fcad3eb7d..28919d674 100644 --- a/docs/zh-CN/install/podman.md +++ b/docs/zh-CN/install/podman.md @@ -1,34 +1,34 @@ --- read_when: - - 你想使用 Podman 而不是 Docker 来运行容器化 Gateway 网关 -summary: 在 rootless Podman 容器中运行 OpenClaw + - 你希望使用 Podman 而不是 Docker 来运行容器化的 Gateway 网关 +summary: 在无 root 的 Podman 容器中运行 OpenClaw title: Podman x-i18n: - generated_at: "2026-04-05T08:28:26Z" + generated_at: "2026-04-23T06:41:16Z" model: gpt-5.4 provider: openai - source_hash: 6cb06e2d85b4b0c8a8c6e69c81f629c83b447cbcbb32e34b7876a1819c488020 + source_hash: df478ad4ac63b363c86a53bc943494b32602abfaad8576c5e899e77f7699a533 source_path: install/podman.md workflow: 15 --- # Podman -在由你当前非 root 用户管理的 rootless Podman 容器中运行 OpenClaw Gateway 网关。 +在无 root 的 Podman 容器中运行 OpenClaw Gateway 网关,并由你当前的非 root 用户进行管理。 推荐的模型是: -- Podman 运行 gateway 容器。 +- Podman 运行 Gateway 网关容器。 - 你主机上的 `openclaw` CLI 是控制平面。 -- 持久化状态默认保存在主机的 `~/.openclaw` 下。 +- 持久状态默认存储在主机上的 `~/.openclaw` 下。 - 日常管理使用 `openclaw --container ...`,而不是 `sudo -u openclaw`、`podman exec` 或单独的服务用户。 ## 前置条件 -- 以 rootless 模式运行的 **Podman** -- 已安装在主机上的 **OpenClaw CLI** -- **可选:**如果你想要由 Quadlet 管理自动启动,则需要 `systemd --user` -- **可选:**只有当你想在无头主机上使用 `loginctl enable-linger "$(whoami)"` 以实现开机持久化时,才需要 `sudo` +- 以无 root 模式运行的 **Podman** +- 已在主机上安装 **OpenClaw CLI** +- **可选:** 如果你希望使用 Quadlet 管理自动启动,需要 `systemd --user` +- **可选:** 仅当你希望在无头主机上使用 `loginctl enable-linger "$(whoami)"` 实现开机持久运行时,才需要 `sudo` ## 快速开始 @@ -46,16 +46,16 @@ x-i18n: - 设置 `OPENCLAW_CONTAINER=openclaw`,然后在主机上使用普通的 `openclaw` 命令。 + 设置 `OPENCLAW_CONTAINER=openclaw`,然后从主机使用普通的 `openclaw` 命令。 -设置细节: +设置详情: -- `./scripts/podman/setup.sh` 默认会在你的 rootless Podman 存储中构建 `openclaw:local`,或者如果你已设置 `OPENCLAW_IMAGE` / `OPENCLAW_PODMAN_IMAGE`,则会使用它们。 -- 如果缺失,它会创建 `~/.openclaw/openclaw.json`,并设定 `gateway.mode: "local"`。 -- 如果缺失,它会创建带有 `OPENCLAW_GATEWAY_TOKEN` 的 `~/.openclaw/.env`。 -- 对于手动启动,辅助脚本只会从 `~/.openclaw/.env` 中读取一小部分与 Podman 相关的允许列表键,并向容器传递显式运行时环境变量;它不会把完整 env 文件交给 Podman。 +- `./scripts/podman/setup.sh` 默认会在你的无 root Podman 存储中构建 `openclaw:local`,或者如果你设置了 `OPENCLAW_IMAGE` / `OPENCLAW_PODMAN_IMAGE`,则使用它指定的镜像。 +- 如果 `~/.openclaw/openclaw.json` 不存在,它会创建该文件,并写入 `gateway.mode: "local"`。 +- 如果 `~/.openclaw/.env` 不存在,它会创建该文件,并写入 `OPENCLAW_GATEWAY_TOKEN`。 +- 对于手动启动,辅助脚本只会从 `~/.openclaw/.env` 读取一个较小的 Podman 相关键 allowlist,并将显式运行时环境变量传递给容器;它不会把整个 env 文件交给 Podman。 由 Quadlet 管理的设置: @@ -63,15 +63,15 @@ x-i18n: ./scripts/podman/setup.sh --quadlet ``` -Quadlet 是仅限 Linux 的选项,因为它依赖 systemd 用户服务。 +Quadlet 仅适用于 Linux,因为它依赖 systemd 用户服务。 你也可以设置 `OPENCLAW_PODMAN_QUADLET=1`。 可选的构建/设置环境变量: -- `OPENCLAW_IMAGE` 或 `OPENCLAW_PODMAN_IMAGE` —— 使用现有/已拉取的镜像,而不是构建 `openclaw:local` -- `OPENCLAW_DOCKER_APT_PACKAGES` —— 在构建镜像时安装额外 apt 软件包 -- `OPENCLAW_EXTENSIONS` —— 在构建时预安装扩展依赖 +- `OPENCLAW_IMAGE` 或 `OPENCLAW_PODMAN_IMAGE` —— 使用已有/已拉取的镜像,而不是构建 `openclaw:local` +- `OPENCLAW_DOCKER_APT_PACKAGES` —— 在镜像构建期间安装额外的 apt 软件包 +- `OPENCLAW_EXTENSIONS` —— 在构建时预安装插件依赖 容器启动: @@ -79,7 +79,7 @@ Quadlet 是仅限 Linux 的选项,因为它依赖 systemd 用户服务。 ./scripts/run-openclaw-podman.sh launch ``` -该脚本会以你当前的 uid/gid 配合 `--userns=keep-id` 启动容器,并将你的 OpenClaw 状态以 bind mount 的方式挂载进容器。 +该脚本会以你当前的 uid/gid,使用 `--userns=keep-id` 启动容器,并将你的 OpenClaw 状态目录 bind-mount 到容器中。 新手引导: @@ -87,7 +87,7 @@ Quadlet 是仅限 Linux 的选项,因为它依赖 systemd 用户服务。 ./scripts/run-openclaw-podman.sh launch setup ``` -然后打开 `http://127.0.0.1:18789/`,并使用 `~/.openclaw/.env` 中的 token。 +然后打开 `http://127.0.0.1:18789/`,并使用 `~/.openclaw/.env` 中的令牌。 主机 CLI 默认值: @@ -95,39 +95,39 @@ Quadlet 是仅限 Linux 的选项,因为它依赖 systemd 用户服务。 export OPENCLAW_CONTAINER=openclaw ``` -然后像下面这样的命令就会自动在该容器内运行: +这样,下面这些命令就会自动在该容器内运行: ```bash openclaw dashboard --no-open -openclaw gateway status --deep # 包含额外服务扫描 +openclaw gateway status --deep # includes extra service scan openclaw doctor openclaw channels login ``` -在 macOS 上,Podman machine 可能会让浏览器在 gateway 看来不再是本地访问。 -如果启动后 Control UI 报告设备认证错误,请参考 +在 macOS 上,Podman machine 可能会让浏览器在 Gateway 网关看来不像本地访问。 +如果启动后 Control UI 报告设备认证错误,请参阅 [Podman + Tailscale](#podman--tailscale) 中的 Tailscale 指南。 ## Podman + Tailscale -若要通过 HTTPS 或远程浏览器访问,请遵循主 Tailscale 文档。 +若要使用 HTTPS 或远程浏览器访问,请遵循主要的 Tailscale 文档。 -Podman 专用说明: +Podman 特别说明: - 保持 Podman 发布主机为 `127.0.0.1`。 -- 优先使用由主机管理的 `tailscale serve`,而不是 `openclaw gateway --tailscale serve`。 -- 在 macOS 上,如果本地浏览器设备认证上下文不可靠,请使用 Tailscale 访问,而不是临时的本地隧道变通方案。 +- 优先使用主机管理的 `tailscale serve`,而不是 `openclaw gateway --tailscale serve`。 +- 在 macOS 上,如果本地浏览器设备认证上下文不稳定,请使用 Tailscale 访问,而不是临时性的本地隧道变通方案。 -请参阅: +请参见: -- [Tailscale](/gateway/tailscale) -- [Control UI](/web/control-ui) +- [Tailscale](/zh-CN/gateway/tailscale) +- [Control UI](/zh-CN/web/control-ui) ## Systemd(Quadlet,可选) -如果你运行了 `./scripts/podman/setup.sh --quadlet`,setup 会在以下位置安装一个 Quadlet 文件: +如果你运行了 `./scripts/podman/setup.sh --quadlet`,设置程序会在以下位置安装一个 Quadlet 文件: ```bash ~/.config/containers/systemd/openclaw.container @@ -147,71 +147,71 @@ systemctl --user daemon-reload systemctl --user restart openclaw.service ``` -若要在 SSH/无头主机上实现开机持久化,请为当前用户启用 lingering: +若要在 SSH/无头主机上实现开机持久运行,请为你的当前用户启用 lingering: ```bash sudo loginctl enable-linger "$(whoami)" ``` -## 配置、环境变量和存储 +## 配置、env 和存储 - **配置目录:** `~/.openclaw` - **工作区目录:** `~/.openclaw/workspace` -- **Token 文件:** `~/.openclaw/.env` +- **令牌文件:** `~/.openclaw/.env` - **启动辅助脚本:** `./scripts/run-openclaw-podman.sh` -启动脚本和 Quadlet 会将主机状态以 bind mount 的方式挂载进容器: +启动脚本和 Quadlet 会将主机状态 bind-mount 到容器中: - `OPENCLAW_CONFIG_DIR` -> `/home/node/.openclaw` - `OPENCLAW_WORKSPACE_DIR` -> `/home/node/.openclaw/workspace` -默认情况下,这些都是主机目录,而不是匿名容器状态,因此 +默认情况下,这些是主机目录,而不是匿名容器状态,因此 `openclaw.json`、每个智能体的 `auth-profiles.json`、渠道/提供商状态、 -会话和工作区在容器被替换后仍然保留。 -Podman 设置还会在已发布的 gateway 端口上为 `127.0.0.1` 和 `localhost` 预设 `gateway.controlUi.allowedOrigins`,以便本地仪表板能在容器的非 loopback bind 配置下正常工作。 +会话以及工作区在容器替换后仍会保留。 +Podman 设置还会为发布的 Gateway 网关端口上的 `127.0.0.1` 和 `localhost` 预填充 `gateway.controlUi.allowedOrigins`,从而让本地仪表板在容器使用非 loopback 绑定时仍能正常工作。 -手动启动器的有用环境变量: +对手动启动器有用的环境变量: -- `OPENCLAW_PODMAN_CONTAINER` —— 容器名(默认是 `openclaw`) +- `OPENCLAW_PODMAN_CONTAINER` —— 容器名称(默认为 `openclaw`) - `OPENCLAW_PODMAN_IMAGE` / `OPENCLAW_IMAGE` —— 要运行的镜像 - `OPENCLAW_PODMAN_GATEWAY_HOST_PORT` —— 映射到容器 `18789` 的主机端口 - `OPENCLAW_PODMAN_BRIDGE_HOST_PORT` —— 映射到容器 `18790` 的主机端口 -- `OPENCLAW_PODMAN_PUBLISH_HOST` —— 发布端口使用的主机接口;默认是 `127.0.0.1` -- `OPENCLAW_GATEWAY_BIND` —— 容器内的 gateway bind 模式;默认是 `lan` +- `OPENCLAW_PODMAN_PUBLISH_HOST` —— 已发布端口的主机接口;默认为 `127.0.0.1` +- `OPENCLAW_GATEWAY_BIND` —— 容器内的 Gateway 网关绑定模式;默认为 `lan` - `OPENCLAW_PODMAN_USERNS` —— `keep-id`(默认)、`auto` 或 `host` -手动启动器会在最终确定容器/镜像默认值之前读取 `~/.openclaw/.env`,因此你可以将这些值持久化在其中。 +手动启动器在最终确定容器/镜像默认值之前会读取 `~/.openclaw/.env`,因此你可以将这些值持久保存在那里。 -如果你使用非默认的 `OPENCLAW_CONFIG_DIR` 或 `OPENCLAW_WORKSPACE_DIR`,请在 `./scripts/podman/setup.sh` 和后续 `./scripts/run-openclaw-podman.sh launch` 命令中设置相同的变量。仓库内的启动器不会在不同 shell 之间持久化自定义路径覆盖。 +如果你使用非默认的 `OPENCLAW_CONFIG_DIR` 或 `OPENCLAW_WORKSPACE_DIR`,请对 `./scripts/podman/setup.sh` 和后续的 `./scripts/run-openclaw-podman.sh launch` 命令设置相同的变量。仓库本地启动器不会在不同 shell 之间持久保存自定义路径覆盖值。 Quadlet 说明: -- 生成的 Quadlet 服务有意保持固定、加固后的默认形态:`127.0.0.1` 已发布端口、容器内使用 `--bind lan`,以及 `keep-id` 用户命名空间。 +- 生成的 Quadlet 服务有意保持固定且加固的默认形态:发布端口为 `127.0.0.1`、容器内使用 `--bind lan`,以及 `keep-id` 用户命名空间。 - 它固定设置 `OPENCLAW_NO_RESPAWN=1`、`Restart=on-failure` 和 `TimeoutStartSec=300`。 -- 它会发布 `127.0.0.1:18789:18789`(gateway)和 `127.0.0.1:18790:18790`(bridge)。 -- 它会将 `~/.openclaw/.env` 作为运行时 `EnvironmentFile` 读取,用于 `OPENCLAW_GATEWAY_TOKEN` 之类的值,但不会使用手动启动器中 Podman 专用的覆盖允许列表。 +- 它会同时发布 `127.0.0.1:18789:18789`(gateway)和 `127.0.0.1:18790:18790`(bridge)。 +- 它将 `~/.openclaw/.env` 作为运行时 `EnvironmentFile` 读取,用于获取 `OPENCLAW_GATEWAY_TOKEN` 等值,但不会使用手动启动器中 Podman 特定覆盖项的 allowlist。 - 如果你需要自定义发布端口、发布主机或其他容器运行标志,请使用手动启动器,或直接编辑 `~/.config/containers/systemd/openclaw.container`,然后重新加载并重启服务。 ## 常用命令 - **容器日志:** `podman logs -f openclaw` - **停止容器:** `podman stop openclaw` -- **移除容器:** `podman rm -f openclaw` +- **删除容器:** `podman rm -f openclaw` - **从主机 CLI 打开仪表板 URL:** `openclaw dashboard --no-open` -- **通过主机 CLI 查看健康/状态:** `openclaw gateway status --deep`(RPC 探测 + 额外 +- **通过主机 CLI 查看健康状态/状态:** `openclaw gateway status --deep`(RPC 探测 + 额外 服务扫描) ## 故障排除 -- **配置或工作区出现 Permission denied(EACCES):** 容器默认使用 `--userns=keep-id` 和 `--user :` 运行。请确保主机上的配置/工作区路径归当前用户所有。 -- **Gateway 网关启动被阻止(缺少 `gateway.mode=local`):** 请确保 `~/.openclaw/openclaw.json` 存在,并设置 `gateway.mode="local"`。如果缺失,`scripts/podman/setup.sh` 会创建它。 -- **容器 CLI 命令命中了错误目标:** 请显式使用 `openclaw --container ...`,或在你的 shell 中导出 `OPENCLAW_CONTAINER=`。 -- **使用 `--container` 时 `openclaw update` 失败:** 这是预期行为。请重建/拉取镜像,然后重启容器或 Quadlet 服务。 -- **Quadlet 服务无法启动:** 运行 `systemctl --user daemon-reload`,然后执行 `systemctl --user start openclaw.service`。在无头系统上,你可能还需要 `sudo loginctl enable-linger "$(whoami)"`。 -- **SELinux 阻止 bind mount:** 保持默认挂载行为不变;当 SELinux 处于 enforcing 或 permissive 模式时,启动器会在 Linux 上自动添加 `:Z`。 +- **配置或工作区出现权限被拒绝(EACCES):** 容器默认使用 `--userns=keep-id` 和 `--user :` 运行。请确保主机上的配置/工作区路径归你当前用户所有。 +- **Gateway 网关启动被阻止(缺少 `gateway.mode=local`):** 请确保 `~/.openclaw/openclaw.json` 存在,并设置了 `gateway.mode="local"`。如果文件不存在,`scripts/podman/setup.sh` 会创建它。 +- **容器 CLI 命令命中了错误目标:** 显式使用 `openclaw --container ...`,或在你的 shell 中导出 `OPENCLAW_CONTAINER=`。 +- **`openclaw update` 配合 `--container` 失败:** 这是预期行为。请重建/拉取镜像,然后重启容器或 Quadlet 服务。 +- **Quadlet 服务无法启动:** 运行 `systemctl --user daemon-reload`,然后运行 `systemctl --user start openclaw.service`。在无头系统上,你可能还需要执行 `sudo loginctl enable-linger "$(whoami)"`。 +- **SELinux 阻止 bind mount:** 保持默认挂载行为不变;当 Linux 上 SELinux 处于 enforcing 或 permissive 模式时,启动器会自动添加 `:Z`。 -## 相关 +## 相关内容 -- [Docker](/install/docker) -- [Gateway 后台进程](/gateway/background-process) -- [Gateway 网关故障排除](/gateway/troubleshooting) +- [Docker](/zh-CN/install/docker) +- [Gateway 后台进程](/zh-CN/gateway/background-process) +- [Gateway 故障排除](/zh-CN/gateway/troubleshooting) diff --git a/docs/zh-CN/install/railway.mdx b/docs/zh-CN/install/railway.mdx index 248979140..9edcad454 100644 --- a/docs/zh-CN/install/railway.mdx +++ b/docs/zh-CN/install/railway.mdx @@ -1,52 +1,54 @@ --- read_when: - 将 OpenClaw 部署到 Railway - - 你想要一种支持基于浏览器控制 UI 的一键云部署方式 -summary: 使用一键模板在 Railway 上部署 OpenClaw + - 你希望通过基于浏览器的 Control UI 进行一键云部署 +summary: 通过一键模板在 Railway 上部署 OpenClaw title: Railway x-i18n: - generated_at: "2026-04-05T08:28:12Z" + generated_at: "2026-04-23T06:41:16Z" model: gpt-5.4 provider: openai - source_hash: f59699aa4e9d27d50018acc2e89ed1bbb1b1a5c85e3fd52f2afe5b2c97b21720 + source_hash: 989c8467ead04b8aa7c94101abd99c936ecd3e451fe728afe8c2f2bd5a78df48 source_path: install/railway.mdx workflow: 15 --- -使用一键模板在 Railway 上部署 OpenClaw,并通过网页控制 UI 访问它。 +# Railway + +通过一键模板在 Railway 上部署 OpenClaw,并通过网页 Control UI 访问它。 这是最简单的“服务器上无需终端”路径:Railway 会为你运行 Gateway 网关。 ## 快速检查清单(新用户) -1. 点击下方的 **Deploy on Railway**。 +1. 点击**在 Railway 上部署**(见下方)。 2. 添加一个挂载到 `/data` 的 **Volume**。 -3. 设置必需的 **Variables**(至少包括 `OPENCLAW_GATEWAY_PORT` 和 `OPENCLAW_GATEWAY_TOKEN`)。 +3. 设置所需的**变量**(至少包括 `OPENCLAW_GATEWAY_PORT` 和 `OPENCLAW_GATEWAY_TOKEN`)。 4. 在端口 `8080` 上启用 **HTTP Proxy**。 -5. 打开 `https:///openclaw`,并使用已配置的共享密钥进行连接。此模板默认使用 `OPENCLAW_GATEWAY_TOKEN`;如果你将其替换为 password 认证,请改用该密码。 +5. 打开 `https:///openclaw`,并使用已配置的共享密钥连接。此模板默认使用 `OPENCLAW_GATEWAY_TOKEN`;如果你将其替换为密码认证,请改用该密码。 ## 一键部署 - Deploy on Railway + 在 Railway 上部署 -部署完成后,在 **Railway → 你的服务 → Settings → Domains** 中找到你的公开 URL。 +部署后,在 **Railway → 你的服务 → Settings → Domains** 中找到你的公开 URL。 Railway 会: -- 为你分配一个生成的域名(通常类似 `https://.up.railway.app`),或 -- 使用你附加的自定义域名。 +- 提供一个自动生成的域名(通常为 `https://.up.railway.app`),或 +- 如果你已绑定自定义域名,则使用你的自定义域名。 然后打开: -- `https:///openclaw` — 控制 UI +- `https:///openclaw` — Control UI ## 你将获得 -- 托管的 OpenClaw Gateway 网关 + 控制 UI +- 托管的 OpenClaw Gateway 网关 + Control UI - 通过 Railway Volume(`/data`)提供的持久化存储,因此 `openclaw.json`、 - 每个智能体的 `auth-profiles.json`、渠道/provider 状态、会话以及 - 工作区都能在重新部署后保留 + 每个智能体的 `auth-profiles.json`、渠道/提供商状态、会话以及 + 工作区都能在重新部署后继续保留 ## 必需的 Railway 设置 @@ -58,40 +60,40 @@ Railway 会: ### Volume(必需) -挂载一个 volume 到: +挂载一个卷到: - `/data` -### Variables +### 变量 在该服务上设置以下变量: -- `OPENCLAW_GATEWAY_PORT=8080`(必需——必须与 Public Networking 中的端口一致) -- `OPENCLAW_GATEWAY_TOKEN`(必需;请将其视为管理员级秘密) +- `OPENCLAW_GATEWAY_PORT=8080`(必需——必须与公共网络中的端口一致) +- `OPENCLAW_GATEWAY_TOKEN`(必需;请将其视为管理员密钥) - `OPENCLAW_STATE_DIR=/data/.openclaw`(推荐) - `OPENCLAW_WORKSPACE_DIR=/data/workspace`(推荐) ## 连接一个渠道 -使用位于 `/openclaw` 的控制 UI,或通过 Railway 的 shell 运行 `openclaw onboard` 获取渠道设置说明: +使用位于 `/openclaw` 的 Control UI,或通过 Railway 的 shell 运行 `openclaw onboard` 获取渠道设置说明: -- [Telegram](/channels/telegram)(最快——只需要一个 bot token) -- [Discord](/channels/discord) -- [所有渠道](/channels) +- [Telegram](/zh-CN/channels/telegram)(最快——只需一个 bot token) +- [Discord](/zh-CN/channels/discord) +- [所有渠道](/zh-CN/channels) ## 备份与迁移 -导出你的状态、配置、auth 配置文件和工作区: +导出你的状态、配置、认证配置文件和工作区: ```bash openclaw backup create ``` 这会创建一个可移植的备份归档,其中包含 OpenClaw 状态以及任何已配置的 -工作区。详情请参见 [Backup](/cli/backup)。 +工作区。详情请参见 [Backup](/zh-CN/cli/backup)。 ## 后续步骤 -- 设置消息渠道:[Channels](/channels) -- 配置 Gateway 网关:[Gateway 配置](/gateway/configuration) -- 保持 OpenClaw 为最新版本:[更新](/install/updating) +- 设置消息渠道:[Channels](/zh-CN/channels) +- 配置 Gateway 网关:[Gateway configuration](/zh-CN/gateway/configuration) +- 让 OpenClaw 保持最新:[Updating](/zh-CN/install/updating) diff --git a/docs/zh-CN/install/render.mdx b/docs/zh-CN/install/render.mdx index 686b3e4e2..54202da76 100644 --- a/docs/zh-CN/install/render.mdx +++ b/docs/zh-CN/install/render.mdx @@ -2,39 +2,40 @@ read_when: - 将 OpenClaw 部署到 Render - 你想使用 Render Blueprints 进行声明式云部署 -summary: 使用 Infrastructure as Code 在 Render 上部署 OpenClaw +summary: 使用基础设施即代码在 Render 上部署 OpenClaw title: Render x-i18n: - generated_at: "2026-04-05T08:28:33Z" + generated_at: "2026-04-23T06:41:21Z" model: gpt-5.4 provider: openai - source_hash: 379297f0298ddac0c1c657695f52619bb482f7b76d358e765880726f6f558c88 + source_hash: 95ffe98a60e9919826a7c7fdb9cbafd63d20ce3de111ac305f43907b1ae442dc source_path: install/render.mdx workflow: 15 --- -使用 Infrastructure as Code 在 Render 上部署 OpenClaw。内置的 `render.yaml` Blueprint 以声明式方式定义了你的整个栈、服务、磁盘和环境变量,因此你可以一键部署,并让基础设施与代码一起进行版本管理。 +# Render -## 前置条件 +使用基础设施即代码在 Render 上部署 OpenClaw。随附的 `render.yaml` Blueprint 会以声明式方式定义你的整个技术栈——服务、磁盘、环境变量——因此你可以一键部署,并让基础设施与代码一起进行版本管理。 + +## 先决条件 - 一个 [Render 账户](https://render.com)(提供免费层) -- 你首选[模型提供商](/providers)的 API key +- 你首选[模型提供商](/zh-CN/providers)的 API 密钥 ## 使用 Render Blueprint 部署 -[Deploy to Render](https://render.com/deploy?repo=https://github.com/openclaw/openclaw) +[部署到 Render](https://render.com/deploy?repo=https://github.com/openclaw/openclaw) 点击此链接将会: -1. 基于本仓库根目录中的 `render.yaml` Blueprint 创建一个新的 Render 服务。 +1. 从此仓库根目录中的 `render.yaml` Blueprint 创建一个新的 Render 服务。 2. 构建 Docker 镜像并部署 -部署完成后,你的服务 URL 将遵循 `https://.onrender.com` 这一格式。 +部署完成后,你的服务 URL 将遵循 `https://.onrender.com` 这样的格式。 ## 理解 Blueprint -Render Blueprint 是用于定义基础设施的 YAML 文件。本仓库中的 `render.yaml` -配置了运行 OpenClaw 所需的一切: +Render Blueprints 是用于定义基础设施的 YAML 文件。此仓库中的 `render.yaml` 配置了运行 OpenClaw 所需的一切: ```yaml services: @@ -58,41 +59,38 @@ services: sizeGB: 1 ``` -所使用的 Blueprint 关键特性: +使用到的 Blueprint 关键特性: -| 特性 | 用途 | +| 特性 | 用途 | | --------------------- | ---------------------------------------------------------- | -| `runtime: docker` | 从仓库中的 Dockerfile 构建 | -| `healthCheckPath` | Render 监控 `/health` 并重启不健康实例 | -| `generateValue: true` | 自动生成加密安全的值 | -| `disk` | 可在重新部署后保留的持久化存储 | +| `runtime: docker` | 从仓库的 Dockerfile 构建 | +| `healthCheckPath` | Render 监控 `/health`,并在实例不健康时重启 | +| `generateValue: true` | 自动生成加密安全的值 | +| `disk` | 可在重新部署后保留的持久化存储 | ## 选择套餐 -| 套餐 | 休眠 | 磁盘 | 最适合 | +| 套餐 | 休眠 | 磁盘 | 最适合 | | --------- | ----------------- | ------------- | ----------------------------- | -| Free | 空闲 15 分钟后 | 不可用 | 测试、演示 | -| Starter | 永不 | 1GB+ | 个人使用、小团队 | -| Standard+ | 永不 | 1GB+ | 生产环境、多个渠道 | +| Free | 空闲 15 分钟后 | 不可用 | 测试、演示 | +| Starter | 永不 | 1GB+ | 个人使用、小型团队 | +| Standard+ | 永不 | 1GB+ | 生产环境、多个渠道 | -Blueprint 默认使用 `starter`。如果你想使用免费层,请在 -你 fork 的 `render.yaml` 中将 `plan: starter` 改为 `plan: free`(但请注意:没有持久磁盘意味着 OpenClaw 状态会在每次部署时被重置)。 +Blueprint 默认使用 `starter`。若要使用免费层,请在你 fork 的 `render.yaml` 中将 `plan: starter` 改为 `plan: free`(但请注意:没有持久化磁盘意味着 OpenClaw 状态会在每次部署时重置)。 -## 部署后 +## 部署之后 ### 访问控制 UI -网页仪表板位于 `https://.onrender.com/`。 +Web 控制面板位于 `https://.onrender.com/`。 -请使用已配置的共享密钥进行连接。此部署模板会自动生成 -`OPENCLAW_GATEWAY_TOKEN`(可在 **Dashboard → 你的服务 → -Environment** 中查看);如果你将其替换为 password 认证,请改用该密码。 +使用已配置的共享密钥进行连接。此部署模板会自动生成 `OPENCLAW_GATEWAY_TOKEN`(可在 **Dashboard → your service → Environment** 中找到);如果你将其替换为密码认证,请改用该密码。 -## Render Dashboard 功能 +## Render 控制面板功能 ### 日志 -可在 **Dashboard → 你的服务 → Logs** 中查看实时日志。可按以下内容筛选: +可在 **Dashboard → your service → Logs** 中查看实时日志。可按以下类型筛选: - 构建日志(Docker 镜像创建) - 部署日志(服务启动) @@ -100,70 +98,68 @@ Environment** 中查看);如果你将其替换为 password 认证,请改 ### Shell 访问 -如需调试,请通过 **Dashboard → 你的服务 → Shell** 打开一个 shell 会话。持久化磁盘挂载在 `/data`。 +如需调试,可通过 **Dashboard → your service → Shell** 打开一个 shell 会话。持久化磁盘挂载在 `/data`。 ### 环境变量 -可在 **Dashboard → 你的服务 → Environment** 中修改变量。更改会触发自动重新部署。 +可在 **Dashboard → your service → Environment** 中修改变量。修改后会触发自动重新部署。 ### 自动部署 -如果你使用的是原始 OpenClaw 仓库,Render 不会自动部署你的 OpenClaw。要更新它,请在仪表板中手动运行一次 Blueprint 同步。 +如果你使用的是原始 OpenClaw 仓库,Render 不会自动部署你的 OpenClaw。要更新它,请从控制面板手动执行 Blueprint 同步。 ## 自定义域名 -1. 前往 **Dashboard → 你的服务 → Settings → Custom Domains** +1. 前往 **Dashboard → your service → Settings → Custom Domains** 2. 添加你的域名 -3. 按说明配置 DNS(将 CNAME 指向 `*.onrender.com`) +3. 按照说明配置 DNS(CNAME 指向 `*.onrender.com`) 4. Render 会自动配置 TLS 证书 -## 扩展 +## 扩缩容 -Render 支持水平和垂直扩展: +Render 支持水平扩展和垂直扩展: -- **垂直扩展**:更换套餐以获取更多 CPU/RAM -- **水平扩展**:增加实例数量(需 Standard 及以上套餐) +- **垂直扩展**:更换套餐以获得更多 CPU / RAM +- **水平扩展**:增加实例数量(Standard 套餐及以上) 对于 OpenClaw,通常垂直扩展就足够了。水平扩展则需要粘性会话或外部状态管理。 ## 备份与迁移 -可随时通过 Render Dashboard 中的 shell 访问导出你的状态、配置、auth 配置文件和工作区: +你可以随时使用 Render 控制面板中的 shell 访问导出状态、配置、认证配置文件和工作区: ```bash openclaw backup create ``` -这会创建一个可移植的备份归档,其中包含 OpenClaw 状态以及任何已配置的 -工作区。详情请参见 [Backup](/cli/backup)。 +这会创建一个可移植的备份归档,其中包含 OpenClaw 状态以及所有已配置的工作区。详见[备份](/zh-CN/cli/backup)。 ## 故障排除 ### 服务无法启动 -请检查 Render Dashboard 中的部署日志。常见问题包括: +请检查 Render 控制面板中的部署日志。常见问题包括: -- 缺少 `OPENCLAW_GATEWAY_TOKEN` —— 请确认它已在 **Dashboard → Environment** 中设置 -- 端口不匹配 —— 请确认已设置 `OPENCLAW_GATEWAY_PORT=8080`,以便 gateway 绑定到 Render 期望的端口 +- 缺少 `OPENCLAW_GATEWAY_TOKEN` —— 确认已在 **Dashboard → Environment** 中设置 +- 端口不匹配 —— 确保已设置 `OPENCLAW_GATEWAY_PORT=8080`,使 Gateway 网关绑定到 Render 所期望的端口 -### 冷启动缓慢(免费层) +### 冷启动较慢(免费层) -免费层服务在空闲 15 分钟后会休眠。休眠后的第一次请求需要几秒钟,因为容器需要启动。升级到 Starter 套餐可实现始终在线。 +免费层服务会在空闲 15 分钟后休眠。休眠后的首次请求需要几秒钟,因为容器需要启动。升级到 Starter 套餐即可保持始终在线。 ### 重新部署后数据丢失 -这会发生在免费层(无持久磁盘)上。请升级到付费套餐,或者 -定期在 Render shell 中通过 `openclaw backup create` 导出完整备份。 +这会发生在免费层(无持久化磁盘)上。请升级到付费套餐,或定期在 Render shell 中通过 `openclaw backup create` 导出完整备份。 ### 健康检查失败 Render 要求 `/health` 在 30 秒内返回 200 响应。如果构建成功但部署失败,可能是服务启动耗时过长。请检查: - 构建日志中是否有错误 -- 容器是否能在本地通过 `docker build && docker run` 正常运行 +- 容器在本地使用 `docker build && docker run` 是否可以运行 ## 后续步骤 -- 设置消息渠道:[Channels](/channels) -- 配置 Gateway 网关:[Gateway 配置](/gateway/configuration) -- 保持 OpenClaw 为最新版本:[更新](/install/updating) +- 设置消息渠道:[Channels](/zh-CN/channels) +- 配置 Gateway 网关:[Gateway 网关配置](/zh-CN/gateway/configuration) +- 保持 OpenClaw 为最新版本:[更新](/zh-CN/install/updating) diff --git a/docs/zh-CN/plugins/architecture.md b/docs/zh-CN/plugins/architecture.md index 6f13fe2be..102717a82 100644 --- a/docs/zh-CN/plugins/architecture.md +++ b/docs/zh-CN/plugins/architecture.md @@ -5,13 +5,13 @@ read_when: - 处理插件加载流水线或注册表 - 实现提供商运行时钩子或渠道插件 sidebarTitle: Internals -summary: 插件内部机制:能力模型、归属权、契约、加载流水线和运行时辅助工具 +summary: 插件内部机制:能力模型、归属关系、契约、加载流水线和运行时辅助工具 title: 插件内部机制 x-i18n: - generated_at: "2026-04-23T06:24:03Z" + generated_at: "2026-04-23T06:41:33Z" model: gpt-5.4 provider: openai - source_hash: 893063d259d4a813c92aec2a74a4d67b1ccf058fc085a900a0470d72ab88f8c8 + source_hash: 69075cecab525aacd19e350605c135334bdcfe913c2f024a48ff68e5b1e80f8c source_path: plugins/architecture.md workflow: 15 --- @@ -19,19 +19,20 @@ x-i18n: # 插件内部机制 - 本页是**深度架构参考**。如需实用指南,请参阅: - - [安装并使用插件](/zh-CN/tools/plugin) — 用户指南 - - [入门指南](/zh-CN/plugins/building-plugins) — 第一个插件教程 - - [渠道插件](/zh-CN/plugins/sdk-channel-plugins) — 构建一个消息渠道 - - [提供商插件](/zh-CN/plugins/sdk-provider-plugins) — 构建一个模型提供商 - - [SDK 概览](/zh-CN/plugins/sdk-overview) — 导入映射和注册 API + 这是**深度架构参考**。如需实用指南,请参见: + - [Install and use plugins](/zh-CN/tools/plugin) —— 用户指南 + - [入门指南](/zh-CN/plugins/building-plugins) —— 第一个插件教程 + - [渠道插件](/zh-CN/plugins/sdk-channel-plugins) —— 构建一个消息渠道 + - [提供商插件](/zh-CN/plugins/sdk-provider-plugins) —— 构建一个模型提供商 + - [SDK 概览](/zh-CN/plugins/sdk-overview) —— 导入映射和注册 API 本页介绍 OpenClaw 插件系统的内部架构。 ## 公共能力模型 -能力是 OpenClaw 内部公开的**原生插件**模型。每个原生 OpenClaw 插件都会针对一种或多种能力类型进行注册: +能力是 OpenClaw 内部公开的**原生插件**模型。每个 +原生 OpenClaw 插件都会针对一个或多个能力类型进行注册: | 能力 | 注册方法 | 示例插件 | | ---------------------- | ------------------------------------------------ | ------------------------------------ | @@ -44,106 +45,146 @@ x-i18n: | 图像生成 | `api.registerImageGenerationProvider(...)` | `openai`, `google`, `fal`, `minimax` | | 音乐生成 | `api.registerMusicGenerationProvider(...)` | `google`, `minimax` | | 视频生成 | `api.registerVideoGenerationProvider(...)` | `qwen` | -| Web 抓取 | `api.registerWebFetchProvider(...)` | `firecrawl` | -| Web 搜索 | `api.registerWebSearchProvider(...)` | `google` | +| 网页抓取 | `api.registerWebFetchProvider(...)` | `firecrawl` | +| 网页搜索 | `api.registerWebSearchProvider(...)` | `google` | | 渠道 / 消息传递 | `api.registerChannel(...)` | `msteams`, `matrix` | -如果一个插件注册了零个能力,但提供了钩子、工具或服务,那么它就是一个**仅 legacy hook** 插件。这种模式仍然被完全支持。 +一个注册了零个能力、但提供钩子、工具或 +服务的插件,是**旧式仅钩子**插件。该模式仍然受到完全支持。 ### 外部兼容性立场 -能力模型已经在核心中落地,并且当前已被内置/原生插件使用,但外部插件的兼容性仍然需要比“它已导出,因此它已冻结”更严格的标准。 +能力模型已经在核心中落地,并且今天已被内置/原生插件 +使用,但外部插件兼容性仍需要比“它已导出,因此它已冻结” +更严格的标准。 -当前指导如下: +当前指导原则: -- **现有外部插件:** 保持基于 hook 的集成继续工作;将其视为兼容性的基线 -- **新的内置/原生插件:** 优先使用显式能力注册,而不是依赖供应商特定的内部访问方式或新的仅 hook 设计 -- **采用能力注册的外部插件:** 允许,但除非文档明确将某个契约标记为稳定,否则应将特定于能力的辅助接口视为仍在演进中 +- **现有外部插件:** 保持基于钩子的集成正常工作;将其视为 + 兼容性的基线 +- **新的内置/原生插件:** 优先使用显式能力注册,而不是 + 依赖供应商专用的穿透式访问,或新的仅钩子设计 +- **采用能力注册的外部插件:** 允许这样做,但除非文档明确将某个契约标记为稳定, + 否则应将能力专用的辅助表面视为仍在演进中 -实际规则: +实用规则: - 能力注册 API 是预期的发展方向 -- 在过渡期间,legacy hook 仍然是对外部插件最安全、最不容易破坏的路径 -- 并非所有导出的 helper 子路径都同等稳定;优先使用文档化的狭义契约,而不是偶然导出的 helper 接口 +- 在过渡期间,旧式钩子仍然是外部插件最安全、最不易破坏的路径 +- 导出的辅助子路径并不完全等价;优先选择有文档说明的狭窄 + 契约,而不是附带导出的辅助工具 ### 插件形态 -OpenClaw 会根据每个已加载插件的实际注册行为来对其形态进行分类,而不仅仅依据静态元数据: +OpenClaw 会根据每个已加载插件的实际 +注册行为将其分类为一种形态(而不仅仅是静态元数据): -- **plain-capability** —— 只注册一种能力类型(例如仅提供商插件 `mistral`) -- **hybrid-capability** —— 注册多种能力类型(例如 `openai` 同时拥有文本推理、语音、媒体理解和图像生成) -- **hook-only** —— 只注册 hook(类型化或自定义),不注册能力、工具、命令或服务 -- **non-capability** —— 注册工具、命令、服务或路由,但不注册能力 +- **plain-capability** —— 恰好注册一种能力类型(例如仅提供商插件 + `mistral`) +- **hybrid-capability** —— 注册多种能力类型(例如 + `openai` 同时拥有文本推理、语音、媒体理解和图像 + 生成) +- **hook-only** —— 仅注册钩子(类型化或自定义),不注册能力、 + 工具、命令或服务 +- **non-capability** —— 注册工具、命令、服务或路由,但不注册 + 能力 -使用 `openclaw plugins inspect ` 可查看插件的形态和能力明细。详见 [CLI 参考](/zh-CN/cli/plugins#inspect)。 +使用 `openclaw plugins inspect ` 查看插件的形态和能力 +明细。详情请参见 [CLI reference](/zh-CN/cli/plugins#inspect)。 -### Legacy hooks +### 旧式钩子 -`before_agent_start` hook 仍然作为仅 hook 插件的兼容路径受到支持。仍有真实的 legacy 插件依赖它。 +`before_agent_start` 钩子仍然作为仅钩子插件的兼容路径受到支持。 +现实中仍有旧插件依赖它。 -方向如下: +方向: -- 保持其可用 -- 将其文档化为 legacy -- 对于模型/提供商覆盖相关工作,优先使用 `before_model_resolve` -- 对于提示词变更相关工作,优先使用 `before_prompt_build` -- 仅在真实使用量下降且 fixture 覆盖证明迁移安全后才移除 +- 保持其正常工作 +- 将其记录为旧式能力 +- 对于模型/提供商覆盖工作,优先使用 `before_model_resolve` +- 对于提示词变更工作,优先使用 `before_prompt_build` +- 只有在真实使用量下降,且夹具覆盖证明迁移安全后,才移除它 ### 兼容性信号 -当你运行 `openclaw doctor` 或 `openclaw plugins inspect ` 时,可能会看到以下标签之一: +当你运行 `openclaw doctor` 或 `openclaw plugins inspect ` 时,可能会看到 +以下标签之一: | 信号 | 含义 | | -------------------------- | ------------------------------------------------------------ | -| **config valid** | 配置解析正常,插件也能成功解析 | -| **compatibility advisory** | 插件使用了受支持但较旧的模式(例如 `hook-only`) | -| **legacy warning** | 插件使用了已弃用的 `before_agent_start` | +| **config valid** | 配置解析正常,插件可解析 | +| **compatibility advisory** | 插件使用受支持但较旧的模式(例如 `hook-only`) | +| **legacy warning** | 插件使用 `before_agent_start`,该项已弃用 | | **hard error** | 配置无效,或插件加载失败 | -当前,`hook-only` 和 `before_agent_start` 都不会导致你的插件失效——`hook-only` 只是提示性信息,而 `before_agent_start` 只会触发警告。这些信号也会出现在 `openclaw status --all` 和 `openclaw plugins doctor` 中。 +如今,`hook-only` 和 `before_agent_start` 都不会让你的插件失效—— +`hook-only` 只是提示性信息,而 `before_agent_start` 只会触发警告。这些 +信号也会出现在 `openclaw status --all` 和 `openclaw plugins doctor` 中。 ## 架构概览 -OpenClaw 的插件系统包含四层: +OpenClaw 的插件系统有四层: -1. **清单 + 设备发现** - OpenClaw 会从已配置路径、工作区根目录、全局扩展根目录以及内置扩展中查找候选插件。设备发现会优先读取原生 `openclaw.plugin.json` 清单以及受支持的 bundle 清单。 -2. **启用 + 验证** - 核心会决定某个已发现插件是启用、禁用、阻止,还是被选中用于某个独占槽位(例如 memory)。 -3. **运行时加载** - 原生 OpenClaw 插件会通过 jiti 在进程内加载,并将能力注册到中央注册表中。兼容的 bundle 会被规范化为注册表记录,而无需导入运行时代码。 +1. **Manifest + 设备发现** + OpenClaw 会从已配置路径、工作区根目录、 + 全局插件根目录以及内置插件中查找候选插件。设备发现会优先读取原生 + `openclaw.plugin.json` manifest,以及受支持的 bundle manifest。 +2. **启用 + 校验** + 核心决定某个已发现插件是已启用、已禁用、被阻止,还是 + 被选中用于某个独占槽位,例如 memory。 +3. **运行时加载** + 原生 OpenClaw 插件通过 jiti 在进程内加载,并将 + 能力注册到中央注册表中。兼容的 bundle 会被规范化为 + 注册表记录,而无需导入运行时代码。 4. **表面消费** - OpenClaw 的其余部分会读取注册表,以暴露工具、渠道、提供商设置、hook、HTTP 路由、CLI 命令和服务。 + OpenClaw 的其余部分读取注册表,以暴露工具、渠道、提供商 + 设置、钩子、HTTP 路由、CLI 命令和服务。 -对于插件 CLI,根命令发现会拆分为两个阶段: +对于插件 CLI 而言,根命令发现专门分为两个阶段: - 解析时元数据来自 `registerCli(..., { descriptors: [...] })` -- 真正的插件 CLI 模块可以保持惰性加载,并在首次调用时注册 +- 真正的插件 CLI 模块可以保持惰性,并在首次调用时注册 -这样既能让插件拥有自己的 CLI 代码,又能让 OpenClaw 在解析前预留根命令名称。 +这样可以将插件自有的 CLI 代码保留在插件内部,同时仍让 OpenClaw +在解析前保留根命令名称。 重要的设计边界是: -- 设备发现 + 配置验证应当能够仅依赖**清单/模式元数据**工作,而无需执行插件代码 +- 设备发现 + 配置校验应能基于**manifest/schema 元数据** + 完成,而无需执行插件代码 - 原生运行时行为来自插件模块的 `register(api)` 路径 -这种拆分使 OpenClaw 能够在完整运行时尚未激活之前,就验证配置、解释缺失/被禁用的插件,以及构建 UI/模式提示。 +这种拆分让 OpenClaw 能够在完整运行时尚未激活之前, +校验配置、解释缺失/禁用的插件,并构建 UI/schema 提示。 ### 渠道插件和共享 message 工具 -对于常规聊天动作,渠道插件不需要单独注册发送/编辑/回应工具。OpenClaw 在核心中保留了一个共享的 `message` 工具,而渠道插件负责其背后的渠道特定发现和执行。 +对于普通聊天操作,渠道插件不需要注册单独的发送/编辑/react 工具。 +OpenClaw 在核心中保留一个共享的 `message` 工具,而 +渠道插件负责其背后的渠道专属发现和执行。 当前边界如下: -- 核心拥有共享 `message` 工具宿主、提示词接线、会话/线程簿记和执行分发 -- 渠道插件拥有作用域化动作发现、能力发现以及任何渠道特定的 schema 片段 -- 渠道插件拥有提供商特定的会话对话语法,例如会话 id 如何编码线程 id,或如何从父会话继承 -- 渠道插件通过其动作适配器执行最终动作 +- 核心负责共享 `message` 工具宿主、提示词接线、会话/线程 + 记录和执行分发 +- 渠道插件负责作用域内操作发现、能力发现,以及任何 + 渠道专属 schema 片段 +- 渠道插件负责提供商专属的会话对话语法,例如 + 对话 id 如何编码线程 id,或如何从父对话继承 +- 渠道插件通过其 action adapter 执行最终操作 -对于渠道插件,SDK 接口是 `ChannelMessageActionAdapter.describeMessageTool(...)`。这个统一的发现调用使插件能够一起返回可见动作、能力和 schema 贡献,从而避免这些部分彼此漂移。 +对于渠道插件,SDK 表面是 +`ChannelMessageActionAdapter.describeMessageTool(...)`。这个统一的发现 +调用让插件可以将其可见操作、能力和 schema 贡献一起返回, +从而避免这些部分彼此漂移。 -当某个渠道特定的 message-tool 参数携带媒体来源(例如本地路径或远程媒体 URL)时,插件还应从 `describeMessageTool(...)` 返回 `mediaSourceParams`。核心会使用这个显式列表来应用沙箱路径规范化和对外媒体访问提示,而无需硬编码插件拥有的参数名称。 -这里应优先使用动作级映射,而不是单个渠道级扁平列表,以避免仅用于 profile 的媒体参数被错误地规范化到 `send` 等无关动作上。 +当某个渠道专属 message-tool 参数携带媒体源,例如 +本地路径或远程媒体 URL 时,插件还应从 +`describeMessageTool(...)` 返回 `mediaSourceParams`。核心使用这份显式 +列表来应用沙箱路径规范化和出站媒体访问提示,而无需硬编码插件自有的参数名称。 +在这里优先使用按 action 分组的映射,而不是整个渠道范围的单一平面列表, +这样仅用于 profile 的媒体参数就不会在诸如 +`send` 之类无关操作上被规范化。 核心会将运行时作用域传入该发现步骤。重要字段包括: @@ -156,85 +197,117 @@ OpenClaw 的插件系统包含四层: - `agentId` - 受信任的入站 `requesterSenderId` -这对于上下文敏感型插件非常重要。渠道可以根据活动账户、当前房间/线程/消息或受信任的请求者身份来隐藏或暴露消息动作,而无需在核心 `message` 工具中硬编码渠道特定分支。 +这对于上下文敏感的插件很重要。一个渠道可以根据活跃账户、 +当前房间/线程/消息或受信任的请求者身份来隐藏或暴露 +message 操作,而无需在核心 `message` 工具中硬编码渠道专属分支。 -这也是为什么嵌入式运行器路由变更仍然属于插件工作:运行器负责将当前聊天/会话身份转发到插件发现边界,以便共享的 `message` 工具在当前轮次暴露正确的渠道自有表面。 +这也是为什么嵌入式运行器路由变更仍然属于插件工作:运行器 +负责将当前聊天/会话身份转发到插件发现边界,以便共享的 `message` +工具为当前轮次暴露正确的插件自有表面。 -对于渠道自有的执行辅助工具,内置插件应将执行运行时保留在其自身扩展模块内。核心不再拥有位于 `src/agents/tools` 下的 Discord、Slack、Telegram 或 WhatsApp 消息动作运行时。我们不会发布单独的 `plugin-sdk/*-action-runtime` 子路径,内置插件应直接从其扩展自有模块导入本地运行时代码。 +对于渠道自有的执行辅助工具,内置插件应将执行运行时保留在其 +自有的扩展模块中。核心不再在 `src/agents/tools` 下拥有 Discord、 +Slack、Telegram 或 WhatsApp 的消息操作运行时。 +我们不会发布单独的 `plugin-sdk/*-action-runtime` 子路径,内置 +插件应直接从其扩展自有模块导入本地运行时代码。 -一般来说,同样的边界也适用于带有提供商名称的 SDK 接缝:核心不应导入 Slack、Discord、Signal、WhatsApp 或类似扩展的渠道特定便利 barrel。如果核心需要某种行为,应当消费内置插件自身的 `api.ts` / `runtime-api.ts` barrel,或者将该需求提升为共享 SDK 中一个狭义的通用能力。 +同样的边界也适用于一般的提供商命名 SDK 接缝:核心 +不应导入 Slack、Discord、Signal、 +WhatsApp 或类似扩展的渠道专用便捷 barrel。如果核心需要某个行为, +要么消费内置插件自己的 `api.ts` / `runtime-api.ts` barrel,要么将该需求提升为共享 SDK 中狭窄的通用能力。 -对于投票,当前有两条执行路径: +对于投票,具体有两条执行路径: -- `outbound.sendPoll` 是适用于符合通用投票模型渠道的共享基线 -- `actions.handleAction("poll")` 是处理渠道特定投票语义或额外投票参数的首选路径 +- `outbound.sendPoll` 是适用于符合通用 + 投票模型渠道的共享基线 +- `actions.handleAction("poll")` 是更推荐的路径,适用于渠道专属 + 投票语义或额外投票参数 -现在,核心会在插件投票分发拒绝该动作之后,才延迟进行共享投票解析,因此插件自有的投票处理器可以接受渠道特定投票字段,而不会先被通用投票解析器阻挡。 +现在,核心会在插件投票分发拒绝该操作之后,才延迟进行共享投票解析, +因此插件自有的投票处理器可以接受渠道专属的投票字段,而不会先被通用投票解析器拦住。 -完整启动顺序请参见[加载流水线](#load-pipeline)。 +完整启动顺序请参见 [Load pipeline](#load-pipeline)。 ## 能力归属模型 -OpenClaw 将原生插件视为**公司**或**功能**的归属边界,而不是一堆无关集成的集合。 +OpenClaw 将原生插件视为**公司**或 +**功能**的归属边界,而不是一堆无关集成的杂货袋。 这意味着: -- 公司插件通常应拥有该公司的所有 OpenClaw 对外表面 -- 功能插件通常应拥有它引入的完整功能表面 -- 渠道应消费共享的核心能力,而不是临时重新实现提供商行为 +- 一个公司插件通常应拥有该公司所有面向 OpenClaw 的 + 表面 +- 一个功能插件通常应拥有它引入的完整功能表面 +- 渠道应消费共享核心能力,而不是临时重新实现 + 提供商行为 示例: -- 内置的 `openai` 插件拥有 OpenAI 模型提供商行为,以及 OpenAI 的语音 + 实时语音 + 媒体理解 + 图像生成行为 +- 内置的 `openai` 插件拥有 OpenAI 模型提供商行为,以及 OpenAI + 语音 + 实时语音 + 媒体理解 + 图像生成行为 - 内置的 `elevenlabs` 插件拥有 ElevenLabs 语音行为 - 内置的 `microsoft` 插件拥有 Microsoft 语音行为 -- 内置的 `google` 插件拥有 Google 模型提供商行为,以及 Google 的媒体理解 + 图像生成 + Web 搜索行为 -- 内置的 `firecrawl` 插件拥有 Firecrawl Web 抓取行为 -- 内置的 `minimax`、`mistral`、`moonshot` 和 `zai` 插件拥有它们各自的媒体理解后端 -- 内置的 `qwen` 插件拥有 Qwen 文本提供商行为,以及媒体理解和视频生成行为 -- `voice-call` 插件是一个功能插件:它拥有通话传输、工具、CLI、路由和 Twilio 媒体流桥接,但它消费共享的语音以及实时转录和实时语音能力,而不是直接导入供应商插件 +- 内置的 `google` 插件拥有 Google 模型提供商行为,以及 Google + 媒体理解 + 图像生成 + 网页搜索行为 +- 内置的 `firecrawl` 插件拥有 Firecrawl 网页抓取行为 +- 内置的 `minimax`、`mistral`、`moonshot` 和 `zai` 插件拥有它们各自的 + 媒体理解后端 +- 内置的 `qwen` 插件拥有 Qwen 文本提供商行为,以及 + 媒体理解和视频生成行为 +- `voice-call` 插件是一个功能插件:它拥有通话传输、工具、 + CLI、路由和 Twilio 媒体流桥接,但它消费共享语音 + 以及实时转录和实时语音能力,而不是直接导入供应商插件 预期的最终状态是: -- 即使 OpenAI 横跨文本模型、语音、图像以及未来的视频能力,它仍然存在于一个插件中 -- 其他供应商也可以用同样方式统一管理自己的表面区域 -- 渠道不关心哪个供应商插件拥有该提供商;它们消费的是由核心暴露的共享能力契约 +- OpenAI 即使横跨文本模型、语音、图像以及未来的视频,也应存在于同一个插件中 +- 其他供应商也可以对其自己的表面范围采用同样方式 +- 渠道并不关心是哪个供应商插件拥有该提供商;它们消费的是由核心暴露的共享能力契约 -这是关键区别: +这就是关键区别: - **plugin** = 归属边界 - **capability** = 多个插件都可以实现或消费的核心契约 -因此,如果 OpenClaw 增加了一个新领域,例如视频,首要问题不是“哪个提供商应该硬编码视频处理?”首要问题是“核心视频能力契约是什么?”一旦这个契约存在,供应商插件就可以针对它注册,渠道/功能插件也可以消费它。 +因此,如果 OpenClaw 添加了一个新领域,例如视频,第一个问题 +不应是“哪个提供商应该硬编码视频处理?”第一个问题应是“核心视频能力契约 +是什么?”一旦这个契约存在,供应商插件 +就可以针对它进行注册,而渠道/功能插件也可以消费它。 -如果该能力还不存在,通常正确的做法是: +如果该能力尚不存在,通常正确的做法是: 1. 在核心中定义缺失的能力 -2. 通过插件 API/运行时以类型化方式暴露它 -3. 让渠道/功能对接这个能力 +2. 以类型化的方式通过插件 API/运行时暴露它 +3. 让渠道/功能针对该能力进行接线 4. 让供应商插件注册实现 -这样可以在保持归属清晰的同时,避免核心行为依赖单一供应商或某条一次性的插件特定代码路径。 +这样可以在保持归属明确的同时,避免核心行为依赖于某个 +单一供应商或某条一次性的插件专属代码路径。 ### 能力分层 -在决定代码归属位置时,请使用这个心智模型: +在决定代码应放在哪里时,请使用这个思维模型: -- **核心能力层**:共享编排、策略、回退、配置合并规则、交付语义以及类型化契约 -- **供应商插件层**:供应商特定 API、认证、模型目录、语音合成、图像生成、未来的视频后端、使用量端点 -- **渠道/功能插件层**:Slack/Discord/voice-call 等集成,它们消费核心能力,并在某个表面上呈现这些能力 +- **核心能力层**:共享编排、策略、回退、配置 + 合并规则、投递语义和类型化契约 +- **供应商插件层**:供应商专属 API、认证、模型目录、语音 + 合成、图像生成、未来的视频后端、用量端点 +- **渠道/功能插件层**:Slack/Discord/voice-call 等集成, + 它们消费核心能力并将其呈现在某个表面上 -例如,TTS 遵循以下结构: +例如,TTS 遵循这种结构: -- 核心拥有回复时 TTS 策略、回退顺序、偏好设置和渠道交付 -- `openai`、`elevenlabs` 和 `microsoft` 拥有合成实现 +- 核心负责回复时 TTS 策略、回退顺序、偏好设置和渠道投递 +- `openai`、`elevenlabs` 和 `microsoft` 负责合成实现 - `voice-call` 消费电话 TTS 运行时辅助工具 -未来的能力也应优先采用同样模式。 +对于未来的能力,也应优先采用同样的模式。 ### 多能力公司插件示例 -从外部看,一个公司插件应当具有一致性。如果 OpenClaw 为模型、语音、实时转录、实时语音、媒体理解、图像生成、视频生成、Web 抓取和 Web 搜索提供了共享契约,那么某个供应商就可以在一个位置统一拥有其所有表面: +一个公司插件从外部看应当是内聚的。如果 OpenClaw 具有针对模型、语音、实时转录、实时语音、媒体 +理解、图像生成、视频生成、网页抓取和网页搜索的共享 +契约,那么一个供应商可以在一个地方拥有其所有表面: ```ts import type { OpenClawPluginDefinition } from "openclaw/plugin-sdk/plugin-entry"; @@ -288,167 +361,210 @@ const plugin: OpenClawPluginDefinition = { export default plugin; ``` -重要的不是辅助函数的确切名称,而是这种结构: +重要的不是辅助函数的确切名称。重要的是这种结构: - 一个插件拥有供应商表面 - 核心仍然拥有能力契约 -- 渠道和功能插件消费 `api.runtime.*` 辅助工具,而不是供应商代码 -- 契约测试可以断言插件已注册它声称拥有的能力 +- 渠道和功能插件消费的是 `api.runtime.*` 辅助工具,而不是供应商代码 +- 契约测试可以断言插件确实注册了它 + 声称拥有的能力 ### 能力示例:视频理解 -OpenClaw 已经将图像/音频/视频理解视为一种共享能力。这里同样适用相同的归属模型: +OpenClaw 已经将图像/音频/视频理解视为一种共享 +能力。相同的归属模型也适用于此: 1. 核心定义媒体理解契约 -2. 供应商插件按适用情况注册 `describeImage`、`transcribeAudio` 和 `describeVideo` -3. 渠道和功能插件消费共享核心行为,而不是直接连接到供应商代码 +2. 供应商插件按需注册 `describeImage`、`transcribeAudio` 和 + `describeVideo` +3. 渠道和功能插件消费共享核心行为,而不是 + 直接接线到供应商代码 -这样可以避免将某个提供商的视频假设固化到核心中。插件拥有供应商表面;核心拥有能力契约和回退行为。 +这样可避免将某个提供商对视频的假设固化到核心中。插件拥有 +供应商表面;核心拥有能力契约和回退行为。 -视频生成也已经采用同样的顺序:核心拥有类型化的能力契约和运行时辅助工具,而供应商插件则针对其注册 `api.registerVideoGenerationProvider(...)` 实现。 +视频生成已经采用了同样的顺序:核心拥有类型化的 +能力契约和运行时辅助工具,而供应商插件则注册 +`api.registerVideoGenerationProvider(...)` 实现来对接它。 -需要一份具体的发布检查清单?请参阅 [能力扩展手册](/zh-CN/plugins/architecture)。 +需要一份具体的发布检查清单?请参见 +[能力扩展手册](/zh-CN/plugins/architecture)。 ## 契约与强制执行 -插件 API 表面被有意设计为类型化,并集中定义在 `OpenClawPluginApi` 中。这个契约定义了受支持的注册点,以及插件可以依赖的运行时辅助工具。 +插件 API 表面被有意设计为类型化并集中在 +`OpenClawPluginApi` 中。该契约定义了受支持的注册点,以及 +插件可以依赖的运行时辅助工具。 这很重要,因为: -- 插件作者获得一个稳定的内部标准 -- 核心可以拒绝重复归属,例如两个插件注册相同的 provider id -- 启动过程可以为格式错误的注册提供可操作的诊断 -- 契约测试可以强制执行内置插件归属,并防止静默漂移 +- 插件作者可以获得一个稳定的内部标准 +- 核心可以拒绝重复归属,例如两个插件注册相同的 + provider id +- 启动过程可以为格式错误的注册暴露可执行的诊断信息 +- 契约测试可以强制执行内置插件归属,并防止悄然漂移 -这里有两层强制执行: +存在两层强制执行: -1. **运行时注册强制执行** - 插件注册表会在插件加载时验证注册。例如:重复的 provider id、重复的语音提供商 id,以及格式错误的注册,都会产生插件诊断,而不是导致未定义行为。 -2. **契约测试** - 在测试运行期间,内置插件会被捕获到契约注册表中,从而使 OpenClaw 能够显式断言归属。当前这用于模型提供商、语音提供商、Web 搜索提供商以及内置注册归属。 +1. **运行时注册强制执行** + 插件注册表会在插件加载时校验注册。例如: + 重复的 provider id、重复的语音提供商 id,以及格式错误的 + 注册,都会产生插件诊断,而不是未定义行为。 +2. **契约测试** + 在测试运行期间,内置插件会被记录到契约注册表中, + 因此 OpenClaw 可以显式断言归属。今天这被用于模型 + 提供商、语音提供商、网页搜索提供商以及内置注册归属。 -实际效果是,OpenClaw 可以预先知道哪个插件拥有哪个表面。这使核心和渠道能够无缝组合,因为归属是声明式、类型化且可测试的,而不是隐式的。 +实际效果是,OpenClaw 能够预先知道,哪个插件拥有哪个 +表面。这让核心和渠道可以无缝组合,因为归属是被声明、类型化且可测试的,而不是隐式的。 -### 什么应属于契约 +### 什么内容应属于契约 -好的插件契约应当具备以下特征: +好的插件契约应当是: -- 类型化 -- 小而精 -- 特定于某项能力 +- 类型化的 +- 小而精的 +- 能力专属的 - 由核心拥有 - 可被多个插件复用 -- 可被渠道/功能消费,而无需了解供应商细节 +- 可被渠道/功能消费,而无需了解供应商知识 不好的插件契约包括: -- 隐藏在核心中的供应商特定策略 -- 绕过注册表的一次性插件逃生口 -- 渠道代码直接深入供应商实现 -- 不属于 `OpenClawPluginApi` 或 `api.runtime` 的临时运行时对象 +- 隐藏在核心中的供应商专属策略 +- 绕过注册表的一次性插件逃逸口 +- 渠道代码直接伸手访问某个供应商实现 +- 不属于 `OpenClawPluginApi` 或 + `api.runtime` 的临时运行时对象 -如果不确定,请提升抽象层级:先定义能力,再让插件接入该能力。 +如有疑问,请提升抽象层级:先定义能力,再让插件接入它。 ## 执行模型 -原生 OpenClaw 插件以**进程内**方式与 Gateway 网关一起运行。它们不是沙箱隔离的。一个已加载的原生插件与核心代码具有相同的进程级信任边界。 +原生 OpenClaw 插件与 Gateway 网关**在同一进程内**运行。它们并未 +沙箱隔离。一个已加载的原生插件与核心代码具有相同的进程级信任边界。 -这意味着: +其含义是: -- 原生插件可以注册工具、网络处理器、hook 和服务 -- 原生插件中的 bug 可能会导致 Gateway 网关崩溃或不稳定 -- 恶意原生插件等同于在 OpenClaw 进程内执行任意代码 +- 一个原生插件可以注册工具、网络处理器、钩子和服务 +- 原生插件中的 bug 可能导致 gateway 崩溃或不稳定 +- 恶意原生插件等同于在 OpenClaw 进程内部执行任意代码 -兼容 bundle 默认更安全,因为 OpenClaw 当前将它们视为元数据/内容包。在当前版本中,这主要意味着内置 Skills。 +兼容的 bundle 默认更安全,因为 OpenClaw 当前将它们视为 +元数据/内容包。在当前版本中,这主要意味着内置 +Skills。 -对于非内置插件,请使用允许列表和显式安装/加载路径。应将工作区插件视为开发期代码,而不是生产默认值。 +对于非内置插件,请使用允许列表和显式安装/加载路径。将 +工作区插件视为开发期代码,而不是生产环境默认值。 -对于内置工作区包名,请让插件 id 默认锚定在 npm 名称中的 `@openclaw/`,或者在包有意暴露更窄的插件角色时,使用获批的类型化后缀,例如 `-provider`、`-plugin`、`-speech`、`-sandbox` 或 `-media-understanding`。 +对于内置工作区 package 名称,请让插件 id 锚定在 npm +名称中:默认使用 `@openclaw/`,或者在包有意暴露更窄插件角色时, +使用已批准的类型化后缀,例如 +`-provider`、`-plugin`、`-speech`、`-sandbox` 或 `-media-understanding`。 -重要信任说明: +重要的信任说明: -- `plugins.allow` 信任的是**插件 id**,而不是来源出处。 -- 与内置插件拥有相同 id 的工作区插件,在启用/加入允许列表时,会有意遮蔽内置副本。 -- 这属于正常且有用的行为,适用于本地开发、补丁测试和热修复。 +- `plugins.allow` 信任的是**插件 id**,而不是来源证明。 +- 与内置插件具有相同 id 的工作区插件,在该工作区插件被启用/加入允许列表时, + 会有意遮蔽内置副本。 +- 这属于正常且有用的行为,可用于本地开发、补丁测试和热修复。 ## 导出边界 -OpenClaw 导出的是能力,而不是实现便利接口。 +OpenClaw 导出的是能力,而不是实现便捷工具。 -请保持能力注册为公共接口。对于非契约 helper 导出,应予以收缩: +保持能力注册为公开。裁剪非契约辅助导出: -- 内置插件特定的 helper 子路径 -- 不打算作为公共 API 的运行时管线子路径 -- 供应商特定的便利 helper -- 属于实现细节的设置/新手引导 helper +- 内置插件专属的辅助子路径 +- 不打算作为公开 API 的运行时接线子路径 +- 供应商专属便捷辅助工具 +- 属于实现细节的设置/新手引导辅助工具 -出于兼容性和内置插件维护原因,一些内置插件 helper 子路径仍然保留在生成的 SDK 导出映射中。当前示例包括 `plugin-sdk/feishu`、`plugin-sdk/feishu-setup`、`plugin-sdk/zalo`、`plugin-sdk/zalo-setup`,以及若干 `plugin-sdk/matrix*` 接缝。应将它们视为保留的实现细节导出,而不是为新的第三方插件推荐的 SDK 模式。 +出于兼容性和内置插件维护需要,一些内置插件辅助子路径 +仍保留在生成的 SDK 导出映射中。当前示例包括 +`plugin-sdk/feishu`、`plugin-sdk/feishu-setup`、`plugin-sdk/zalo`、 +`plugin-sdk/zalo-setup` 以及若干 `plugin-sdk/matrix*` 接缝。请将这些视为 +保留的实现细节导出,而不是新第三方插件推荐采用的 SDK 模式。 ## 加载流水线 -启动时,OpenClaw 大致会执行以下步骤: +在启动时,OpenClaw 大致会执行以下步骤: 1. 发现候选插件根目录 -2. 读取原生或兼容 bundle 的清单与包元数据 +2. 读取原生或兼容 bundle 的 manifest 与 package 元数据 3. 拒绝不安全的候选项 -4. 规范化插件配置(`plugins.enabled`、`allow`、`deny`、`entries`、`slots`、`load.paths`) +4. 规范化插件配置(`plugins.enabled`、`allow`、`deny`、`entries`、 + `slots`、`load.paths`) 5. 为每个候选项决定启用状态 6. 通过 jiti 加载已启用的原生模块 -7. 调用原生 `register(api)`(或 `activate(api)` —— 一个 legacy 别名)hook,并将注册内容收集到插件注册表中 +7. 调用原生 `register(api)`(或 `activate(api)` —— 旧式别名)钩子,并将注册内容收集到插件注册表中 8. 将注册表暴露给命令/运行时表面 -`activate` 是 `register` 的 legacy 别名 —— 加载器会解析现有者(`def.register ?? def.activate`),并在同一点调用它。所有内置插件都使用 `register`;新插件请优先使用 `register`。 +`activate` 是 `register` 的旧式别名 —— 加载器会解析二者中存在的那个(`def.register ?? def.activate`),并在同一时机调用。所有内置插件都使用 `register`;新插件请优先使用 `register`。 -安全门会在运行时执行**之前**触发。当入口路径逃离插件根目录、路径为所有人可写,或对于非内置插件而言路径归属看起来可疑时,候选项会被阻止。 +安全门控发生在**运行时执行之前**。当候选项出现以下情况时会被阻止: +入口逃逸出插件根目录、路径可被所有人写入,或者对于非内置插件而言, +路径归属看起来可疑。 -### Manifest-first 行为 +### Manifest 优先行为 -清单是控制平面的事实来源。OpenClaw 使用它来: +manifest 是控制平面的事实来源。OpenClaw 使用它来: - 标识插件 - 发现已声明的渠道/Skills/配置 schema 或 bundle 能力 -- 验证 `plugins.entries..config` +- 校验 `plugins.entries..config` - 增强 Control UI 标签/占位符 - 显示安装/目录元数据 -- 在不加载插件运行时的情况下保留轻量激活和设置描述符 +- 在不加载插件运行时的情况下保留轻量级激活和设置描述符 -对于原生插件,运行时模块属于数据平面部分。它会注册实际行为,例如 hook、工具、命令或提供商流程。 +对于原生插件,运行时模块是数据平面部分。它负责注册 +实际行为,例如钩子、工具、命令或提供商流程。 -可选的清单 `activation` 和 `setup` 块仍然留在控制平面。它们是用于激活规划和设置发现的纯元数据描述符;不会替代运行时注册、`register(...)` 或 `setupEntry`。 -当前首批真实激活使用方已经开始使用清单中的命令、渠道和提供商提示,在更广泛的注册表实例化之前缩小插件加载范围: +可选的 manifest `activation` 和 `setup` 块仍属于控制平面。 +它们是用于激活规划和设置发现的纯元数据描述符; +不会取代运行时注册、`register(...)` 或 `setupEntry`。 +首批实时激活消费者现在会使用 manifest 中的命令、渠道和提供商提示, +在更广泛的注册表实体化之前先缩小插件加载范围: - CLI 加载会缩小到拥有所请求主命令的插件 -- 渠道设置/插件解析会缩小到拥有所请求渠道 id 的插件 -- 显式提供商设置/运行时解析会缩小到拥有所请求 provider id 的插件 +- 渠道设置/插件解析会缩小到拥有所请求 + channel id 的插件 +- 显式提供商设置/运行时解析会缩小到拥有所请求 + provider id 的插件 -设置发现现在会优先使用描述符自有 id,例如 `setup.providers` 和 `setup.cliBackends`,以便在回退到 `setup-api` 之前先缩小候选插件范围;而 `setup-api` 仅用于那些仍然需要设置期运行时 hook 的插件。如果多个已发现插件声明了相同的规范化设置提供商或 CLI 后端 id,设置查找会拒绝这个有歧义的归属方,而不是依赖发现顺序。 +设置发现现在会优先使用描述符自有的 id,例如 `setup.providers` 和 +`setup.cliBackends`,以便在回退到 +`setup-api` 之前先缩小候选插件范围;`setup-api` 仅用于那些仍然需要设置阶段运行时钩子的插件。如果多个已发现插件声称拥有同一个已规范化的设置提供商或 CLI 后端 id,设置查找会拒绝这个存在歧义的归属者,而不是依赖发现顺序。 ### 加载器会缓存什么 -OpenClaw 会在进程内为以下内容保留短时缓存: +OpenClaw 会保留以下短生命周期的进程内缓存: -- 设备发现结果 -- 清单注册表数据 +- 发现结果 +- manifest 注册表数据 - 已加载的插件注册表 -这些缓存用于减少突发启动和重复命令的开销。可以安全地将它们视为短生命周期的性能缓存,而不是持久化机制。 +这些缓存可减少突发式启动开销和重复命令的开销。可以安全地将它们视为短期性能缓存,而不是持久化机制。 性能说明: -- 设置 `OPENCLAW_DISABLE_PLUGIN_DISCOVERY_CACHE=1` 或 `OPENCLAW_DISABLE_PLUGIN_MANIFEST_CACHE=1` 可禁用这些缓存。 -- 使用 `OPENCLAW_PLUGIN_DISCOVERY_CACHE_MS` 和 `OPENCLAW_PLUGIN_MANIFEST_CACHE_MS` 调整缓存时间窗口。 +- 设置 `OPENCLAW_DISABLE_PLUGIN_DISCOVERY_CACHE=1` 或 + `OPENCLAW_DISABLE_PLUGIN_MANIFEST_CACHE=1` 可禁用这些缓存。 +- 使用 `OPENCLAW_PLUGIN_DISCOVERY_CACHE_MS` 和 + `OPENCLAW_PLUGIN_MANIFEST_CACHE_MS` 调整缓存时间窗口。 ## 注册表模型 -已加载的插件不会直接修改任意核心全局状态。它们会注册到一个中央插件注册表中。 +已加载插件不会直接修改随意的核心全局状态。它们会注册到一个 +中央插件注册表中。 -注册表会跟踪: +该注册表会跟踪: - 插件记录(身份、来源、出处、状态、诊断) - 工具 -- legacy hook 和类型化 hook +- 旧式钩子和类型化钩子 - 渠道 - 提供商 - Gateway 网关 RPC 处理器 @@ -457,18 +573,20 @@ OpenClaw 会在进程内为以下内容保留短时缓存: - 后台服务 - 插件自有命令 -然后,核心功能会从这个注册表中读取,而不是直接与插件模块交互。这使加载保持单向流动: +然后,核心功能从该注册表中读取,而不是直接与插件模块交互。 +这使得加载保持单向: - 插件模块 -> 注册表注册 - 核心运行时 -> 注册表消费 -这种分离对可维护性很重要。这意味着,大多数核心表面只需要一个集成点:“读取注册表”,而不是“为每个插件模块做特殊处理”。 +这种分离对可维护性很重要。这意味着大多数核心表面只需要一个集成点: +“读取注册表”,而不是“为每个插件模块做特殊处理”。 ## 会话绑定回调 -绑定会话的插件可以在批准结果确定后作出响应。 +绑定会话的插件可以在批准结果确定时作出响应。 -使用 `api.onConversationBindingResolved(...)`,在绑定请求被批准或拒绝后接收回调: +使用 `api.onConversationBindingResolved(...)` 在绑定请求被批准或拒绝后接收回调: ```ts export default { @@ -476,12 +594,12 @@ export default { register(api) { api.onConversationBindingResolved(async (event) => { if (event.status === "approved") { - // A binding now exists for this plugin + conversation. + // 现在已为此插件 + 会话建立绑定。 console.log(event.binding?.conversationId); return; } - // The request was denied; clear any local pending state. + // 请求被拒绝;清除任何本地待定状态。 console.log(event.request.conversation.conversationId); }); }, @@ -492,82 +610,116 @@ export default { - `status`:`"approved"` 或 `"denied"` - `decision`:`"allow-once"`、`"allow-always"` 或 `"deny"` -- `binding`:针对已批准请求的已解析绑定 -- `request`:原始请求摘要、分离提示、发送者 id,以及会话元数据 +- `binding`:已批准请求的已解析绑定 +- `request`:原始请求摘要、分离提示、发送者 id,以及 + 会话元数据 -这个回调仅用于通知。它不会改变谁被允许绑定会话,并且它会在核心批准处理完成后运行。 +此回调仅用于通知。它不会改变谁被允许绑定某个 +会话,并且它会在核心的批准处理完成后运行。 -## 提供商运行时 hook +## 提供商运行时钩子 提供商插件现在有两层: -- 清单元数据:`providerAuthEnvVars` 用于在运行时加载前廉价查找基于环境变量的提供商认证,`providerAuthAliases` 用于共享认证的提供商变体,`channelEnvVars` 用于在运行时加载前廉价查找基于环境变量的渠道认证/设置,此外还有 `providerAuthChoices`,用于在运行时加载前廉价提供新手引导/认证选项标签和 CLI flag 元数据 -- 配置期 hook:`catalog` / legacy `discovery`,以及 `applyConfigDefaults` -- 运行时 hook:`normalizeModelId`、`normalizeTransport`、`normalizeConfig`、`applyNativeStreamingUsageCompat`、`resolveConfigApiKey`、`resolveSyntheticAuth`、`resolveExternalAuthProfiles`、`shouldDeferSyntheticProfileAuth`、`resolveDynamicModel`、`prepareDynamicModel`、`normalizeResolvedModel`、`contributeResolvedModelCompat`、`capabilities`、`normalizeToolSchemas`、`inspectToolSchemas`、`resolveReasoningOutputMode`、`prepareExtraParams`、`createStreamFn`、`wrapStreamFn`、`resolveTransportTurnState`、`resolveWebSocketSessionPolicy`、`formatApiKey`、`refreshOAuth`、`buildAuthDoctorHint`、`matchesContextOverflowError`、`classifyFailoverReason`、`isCacheTtlEligible`、`buildMissingAuthMessage`、`suppressBuiltInModel`、`augmentModelCatalog`、`resolveThinkingProfile`、`isBinaryThinking`、`supportsXHighThinking`、`resolveDefaultThinkingLevel`、`isModernModelRef`、`prepareRuntimeAuth`、`resolveUsageAuth`、`fetchUsageSnapshot`、`createEmbeddingProvider`、`buildReplayPolicy`、`sanitizeReplayHistory`、`validateReplayTurns`、`onModelSelected` +- manifest 元数据:`providerAuthEnvVars` 用于在运行时加载前 + 进行轻量级提供商环境变量认证查找,`providerAuthAliases` 用于共享 + 认证的提供商变体,`channelEnvVars` 用于在运行时 + 加载前进行轻量级渠道环境变量/设置查找,以及 `providerAuthChoices` 用于在运行时加载前 + 提供轻量级新手引导/认证选择标签和 CLI flag 元数据 +- 配置阶段钩子:`catalog` / 旧式 `discovery`,以及 `applyConfigDefaults` +- 运行时钩子:`normalizeModelId`、`normalizeTransport`、 + `normalizeConfig`、 + `applyNativeStreamingUsageCompat`、`resolveConfigApiKey`、 + `resolveSyntheticAuth`、`resolveExternalAuthProfiles`、 + `shouldDeferSyntheticProfileAuth`、 + `resolveDynamicModel`、`prepareDynamicModel`、`normalizeResolvedModel`、 + `contributeResolvedModelCompat`、`capabilities`、 + `normalizeToolSchemas`、`inspectToolSchemas`、 + `resolveReasoningOutputMode`、`prepareExtraParams`、`createStreamFn`、 + `wrapStreamFn`、`resolveTransportTurnState`、 + `resolveWebSocketSessionPolicy`、`formatApiKey`、`refreshOAuth`、 + `buildAuthDoctorHint`、`matchesContextOverflowError`、 + `classifyFailoverReason`、`isCacheTtlEligible`、 + `buildMissingAuthMessage`、`suppressBuiltInModel`、`augmentModelCatalog`、 + `resolveThinkingProfile`、`isBinaryThinking`、`supportsXHighThinking`、 + `resolveDefaultThinkingLevel`、`isModernModelRef`、`prepareRuntimeAuth`、 + `resolveUsageAuth`、`fetchUsageSnapshot`、`createEmbeddingProvider`、 + `buildReplayPolicy`、 + `sanitizeReplayHistory`、`validateReplayTurns`、`onModelSelected` -OpenClaw 仍然拥有通用智能体循环、故障转移、转录处理和工具策略。这些 hook 是提供商特定行为的扩展表面,而无需实现一整套自定义推理传输。 +OpenClaw 仍然拥有通用智能体循环、故障切换、转录处理和 +工具策略。这些钩子是提供商专属行为的扩展表面, +无需为此实现整个自定义推理传输。 -当某个提供商具有基于环境变量的凭证,且通用认证/状态/模型选择器路径需要在不加载插件运行时的情况下感知这些凭证时,请使用清单中的 `providerAuthEnvVars`。当某个 provider id 应复用另一个 provider id 的环境变量、认证配置文件、基于配置的认证以及 API key 新手引导选项时,请使用清单中的 `providerAuthAliases`。当新手引导/认证选择 CLI 表面需要在不加载提供商运行时的情况下知道提供商的 choice id、分组标签和简单的单 flag 认证接线时,请使用清单中的 `providerAuthChoices`。请将提供商运行时的 `envVars` 保留给面向操作员的提示,例如新手引导标签或 OAuth client-id/client-secret 设置变量。 +当某个提供商具有基于环境变量的凭证,且通用认证/状态/模型选择器路径应当在不加载插件运行时的情况下看到这些凭证时,请使用 manifest `providerAuthEnvVars`。当一个 provider id 应复用另一个 provider id 的环境变量、认证配置文件、基于配置的认证和 API key 新手引导选项时,请使用 manifest `providerAuthAliases`。当新手引导/认证选择 CLI 表面应在不加载提供商运行时的情况下知道该提供商的 choice id、分组标签和简单的单 flag 认证接线时,请使用 manifest `providerAuthChoices`。将提供商运行时的 `envVars` 保留给面向运维人员的提示,例如新手引导标签或 OAuth +client-id/client-secret 设置变量。 -当某个渠道具有基于环境变量驱动的认证或设置,且通用 shell 环境变量回退、配置/状态检查或设置提示需要在不加载渠道运行时的情况下感知这些信息时,请使用清单中的 `channelEnvVars`。 +当某个渠道具有基于环境变量驱动的认证或设置,且通用 shell 环境变量回退、配置/状态检查或设置提示应当在不加载渠道运行时的情况下看到这些内容时,请使用 manifest `channelEnvVars`。 -### Hook 顺序和用法 +### 钩子顺序与用法 -对于模型/提供商插件,OpenClaw 会大致按照以下顺序调用 hook。 -“何时使用”这一列是快速决策指南。 +对于模型/提供商插件,OpenClaw 大致按如下顺序调用这些钩子。 +“何时使用”这一列可作为快速决策指南。 -| # | Hook | 它的作用 | 何时使用 | +| # | 钩子 | 它的作用 | 何时使用 | | --- | --------------------------------- | -------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- | -| 1 | `catalog` | 在生成 `models.json` 期间,将提供商配置发布到 `models.providers` 中 | 提供商拥有一个目录或 base URL 默认值 | -| 2 | `applyConfigDefaults` | 在配置实例化期间应用提供商自有的全局配置默认值 | 默认值依赖认证模式、环境变量或提供商模型家族语义 | -| -- | _(内置模型查找)_ | OpenClaw 会先尝试常规注册表/目录路径 | _(不是插件 hook)_ | -| 3 | `normalizeModelId` | 在查找前规范化 legacy 或预览版 model-id 别名 | 提供商拥有在规范模型解析前进行别名清理的逻辑 | -| 4 | `normalizeTransport` | 在通用模型组装前规范化提供商家族的 `api` / `baseUrl` | 提供商拥有对同一传输家族中自定义 provider id 的传输清理逻辑 | -| 5 | `normalizeConfig` | 在运行时/提供商解析前规范化 `models.providers.` | 提供商需要让配置清理逻辑随插件一起存在;内置的 Google 家族 helper 也会为受支持的 Google 配置项提供兜底 | -| 6 | `applyNativeStreamingUsageCompat` | 将原生流式使用量兼容性重写应用到配置提供商 | 提供商需要基于端点的原生流式使用量元数据修正 | -| 7 | `resolveConfigApiKey` | 在加载运行时认证前,为配置提供商解析 env-marker 认证 | 提供商拥有自己的 env-marker API key 解析逻辑;`amazon-bedrock` 在此也有一个内置的 AWS env-marker 解析器 | -| 8 | `resolveSyntheticAuth` | 在不持久化明文的情况下暴露本地/自托管或基于配置的认证 | 提供商可以使用 synthetic/local 凭证标记运行 | -| 9 | `resolveExternalAuthProfiles` | 叠加提供商自有的外部认证配置文件;默认 `persistence` 为 `runtime-only`,适用于 CLI/应用自有凭证 | 提供商在不持久化复制后的刷新令牌的前提下复用外部认证凭证;需在清单中声明 `contracts.externalAuthProviders` | -| 10 | `shouldDeferSyntheticProfileAuth` | 将已存储的 synthetic 配置文件占位符降级到 env/基于配置的认证之后 | 提供商存储了 synthetic 占位配置文件,而这些占位符不应获得更高优先级 | -| 11 | `resolveDynamicModel` | 为本地注册表中尚不存在的提供商自有 model id 提供同步回退解析 | 提供商接受任意上游 model id | -| 12 | `prepareDynamicModel` | 异步预热,然后再次运行 `resolveDynamicModel` | 提供商在解析未知 id 前需要网络元数据 | -| 13 | `normalizeResolvedModel` | 在嵌入式运行器使用已解析模型前做最终重写 | 提供商需要传输重写,但仍使用核心传输 | -| 14 | `contributeResolvedModelCompat` | 为另一个兼容传输之后的供应商模型贡献兼容标记 | 提供商能在代理传输上识别自己的模型,而无需接管该提供商 | -| 15 | `capabilities` | 供共享核心逻辑使用的提供商自有转录/工具元数据 | 提供商需要转录或提供商家族特有的行为 | -| 16 | `normalizeToolSchemas` | 在嵌入式运行器看到工具 schema 前对其进行规范化 | 提供商需要针对传输家族进行 schema 清理 | -| 17 | `inspectToolSchemas` | 在规范化后暴露提供商自有的 schema 诊断 | 提供商想要关键词警告,而不需要让核心学习提供商特定规则 | -| 18 | `resolveReasoningOutputMode` | 选择原生或带标签的 reasoning-output 契约 | 提供商需要使用带标签的 reasoning/final 输出,而不是原生字段 | -| 19 | `prepareExtraParams` | 在通用流包装器之前进行请求参数规范化 | 提供商需要默认请求参数或按提供商清理参数 | -| 20 | `createStreamFn` | 用自定义传输完全替换正常流路径 | 提供商需要自定义线协议,而不仅仅是包一层封装 | -| 21 | `wrapStreamFn` | 在应用通用包装器后对流函数再做封装 | 提供商需要请求头/请求体/模型兼容包装,而不是自定义传输 | -| 22 | `resolveTransportTurnState` | 附加原生的逐轮传输头或元数据 | 提供商希望通用传输发送提供商原生的轮次身份 | -| 23 | `resolveWebSocketSessionPolicy` | 附加原生 WebSocket 头或会话冷却策略 | 提供商希望通用 WS 传输调整会话头或回退策略 | -| 24 | `formatApiKey` | 认证配置文件格式化器:已存储配置文件会变成运行时 `apiKey` 字符串 | 提供商存储了额外认证元数据,并需要自定义运行时令牌形态 | -| 25 | `refreshOAuth` | 为自定义刷新端点或刷新失败策略覆盖 OAuth 刷新逻辑 | 提供商不适配共享的 `pi-ai` 刷新器 | -| 26 | `buildAuthDoctorHint` | 当 OAuth 刷新失败时附加修复提示 | 提供商在刷新失败后需要提供商自有的认证修复指导 | -| 27 | `matchesContextOverflowError` | 提供商自有的上下文窗口溢出匹配器 | 提供商存在通用启发式无法识别的原始溢出错误 | -| 28 | `classifyFailoverReason` | 提供商自有的故障转移原因分类 | 提供商可以将原始 API/传输错误映射为限流、过载等原因 | -| 29 | `isCacheTtlEligible` | 面向代理/回传提供商的提示词缓存策略 | 提供商需要代理特定的缓存 TTL 门控 | -| 30 | `buildMissingAuthMessage` | 替代通用缺失认证恢复消息 | 提供商需要提供商特定的缺失认证恢复提示 | -| 31 | `suppressBuiltInModel` | 过时上游模型抑制,并可附带面向用户的错误提示 | 提供商需要隐藏过时的上游条目,或用供应商提示替换它们 | -| 32 | `augmentModelCatalog` | 在发现之后附加 synthetic/最终目录条目 | 提供商需要在 `models list` 和选择器中提供 synthetic 的前向兼容条目 | -| 33 | `resolveThinkingProfile` | 设置模型特定的 `/think` 级别、显示标签和默认值 | 提供商为选定模型暴露了自定义思考级阶或二元标签 | -| 34 | `isBinaryThinking` | 开/关推理切换兼容性 hook | 提供商只暴露二元的思考开/关 | -| 35 | `supportsXHighThinking` | `xhigh` 推理支持兼容性 hook | 提供商只希望在部分模型上启用 `xhigh` | -| 36 | `resolveDefaultThinkingLevel` | 默认 `/think` 级别兼容性 hook | 提供商拥有某个模型家族的默认 `/think` 策略 | -| 37 | `isModernModelRef` | 用于实时配置文件过滤和 smoke 选择的现代模型匹配器 | 提供商拥有实时/smoke 首选模型匹配逻辑 | -| 38 | `prepareRuntimeAuth` | 在推理前最后一刻,将已配置凭证交换为实际运行时令牌/key | 提供商需要令牌交换或短生命周期请求凭证 | -| 39 | `resolveUsageAuth` | 为 `/usage` 及相关状态表面解析使用量/计费凭证 | 提供商需要自定义使用量/配额令牌解析,或需要不同的使用量凭证 | -| 40 | `fetchUsageSnapshot` | 在认证解析后获取并规范化提供商特定的使用量/配额快照 | 提供商需要提供商特定的使用量端点或负载解析器 | -| 41 | `createEmbeddingProvider` | 为 Memory Wiki/搜索构建提供商自有的嵌入适配器 | memory 嵌入行为应归属于提供商插件 | -| 42 | `buildReplayPolicy` | 返回一个用于控制该提供商转录处理的回放策略 | 提供商需要自定义转录策略(例如移除 thinking 块) | -| 43 | `sanitizeReplayHistory` | 在通用转录清理之后重写回放历史 | 提供商需要在共享压缩 helper 之外执行提供商特定的回放重写 | -| 44 | `validateReplayTurns` | 在嵌入式运行器之前对回放轮次做最终验证或重塑 | 提供商传输在通用净化后需要更严格的轮次验证 | -| 45 | `onModelSelected` | 在模型被选中后运行提供商自有的副作用 | 当模型变为活动状态时,提供商需要遥测或提供商自有状态 | +| 1 | `catalog` | 在生成 `models.json` 期间将提供商配置发布到 `models.providers` 中 | 提供商拥有目录或 base URL 默认值 | +| 2 | `applyConfigDefaults` | 在配置实体化期间应用提供商自有的全局配置默认值 | 默认值依赖于认证模式、环境变量或提供商模型家族语义 | +| -- | _(内置模型查找)_ | OpenClaw 会先尝试正常的注册表/目录路径 | _(不是插件钩子)_ | +| 3 | `normalizeModelId` | 在查找前规范化旧式或预览版 model-id 别名 | 提供商在规范模型解析前拥有别名清理逻辑 | +| 4 | `normalizeTransport` | 在通用模型组装前规范化提供商家族的 `api` / `baseUrl` | 提供商拥有同一传输家族内自定义 provider id 的传输清理逻辑 | +| 5 | `normalizeConfig` | 在运行时/提供商解析前规范化 `models.providers.` | 提供商需要将配置清理逻辑放在插件中;内置的 Google 家族辅助工具也会为受支持的 Google 配置条目提供兜底 | +| 6 | `applyNativeStreamingUsageCompat` | 对配置提供商应用原生流式用量兼容性重写 | 提供商需要基于端点对原生流式用量元数据进行修正 | +| 7 | `resolveConfigApiKey` | 在运行时认证加载前,为配置提供商解析环境变量标记认证 | 提供商拥有自己的环境变量标记 API key 解析逻辑;`amazon-bedrock` 在这里也有一个内置的 AWS 环境变量标记解析器 | +| 8 | `resolveSyntheticAuth` | 在不持久化明文的情况下暴露本地/自托管或基于配置的认证 | 提供商可使用合成/本地凭证标记运行 | +| 9 | `resolveExternalAuthProfiles` | 覆盖提供商自有的外部认证配置文件;`persistence` 默认为 `runtime-only`,适用于 CLI/应用自有凭证 | 提供商在不持久化复制的 refresh token 的情况下复用外部认证凭证;请在 manifest 中声明 `contracts.externalAuthProviders` | +| 10 | `shouldDeferSyntheticProfileAuth` | 将已存储的合成配置文件占位符降低到环境变量/基于配置的认证之后 | 提供商会存储合成占位配置文件,而这些占位符不应具有更高优先级 | +| 11 | `resolveDynamicModel` | 对本地注册表中尚不存在的提供商自有模型 id 执行同步回退解析 | 提供商接受任意上游模型 id | +| 12 | `prepareDynamicModel` | 执行异步预热,然后再次运行 `resolveDynamicModel` | 提供商在解析未知 id 前需要网络元数据 | +| 13 | `normalizeResolvedModel` | 在嵌入式运行器使用已解析模型前执行最终重写 | 提供商需要传输重写,但仍使用核心传输 | +| 14 | `contributeResolvedModelCompat` | 为位于其他兼容传输之后的供应商模型贡献兼容性标志 | 提供商能在代理传输上识别自己的模型,而无需接管该提供商 | +| 15 | `capabilities` | 由提供商拥有、被共享核心逻辑使用的转录/工具元数据 | 提供商需要处理转录或提供商家族特性 | +| 16 | `normalizeToolSchemas` | 在嵌入式运行器看到工具 schema 之前对其进行规范化 | 提供商需要传输家族级别的 schema 清理 | +| 17 | `inspectToolSchemas` | 在规范化之后暴露提供商自有的 schema 诊断 | 提供商希望提供关键字警告,而不必让核心理解提供商专属规则 | +| 18 | `resolveReasoningOutputMode` | 选择原生或带标签的推理输出契约 | 提供商需要使用带标签的推理/最终输出,而不是原生字段 | +| 19 | `prepareExtraParams` | 在通用流式选项包装器之前规范化请求参数 | 提供商需要默认请求参数或按提供商执行参数清理 | +| 20 | `createStreamFn` | 使用自定义传输完全替换正常流路径 | 提供商需要自定义线协议,而不只是包装器 | +| 21 | `wrapStreamFn` | 在应用通用包装器之后对流进行包装 | 提供商需要请求头/请求体/模型兼容性包装器,而不是自定义传输 | +| 22 | `resolveTransportTurnState` | 附加原生的逐轮传输头或元数据 | 提供商希望通用传输发送提供商原生的轮次标识 | +| 23 | `resolveWebSocketSessionPolicy` | 附加原生 WebSocket 请求头或会话冷却策略 | 提供商希望通用 WS 传输调整会话请求头或回退策略 | +| 24 | `formatApiKey` | 认证配置文件格式化器:已存储的配置文件会变成运行时 `apiKey` 字符串 | 提供商存储了额外认证元数据,并需要自定义运行时 token 形态 | +| 25 | `refreshOAuth` | 针对自定义刷新端点或刷新失败策略的 OAuth 刷新覆盖 | 提供商不适配共享的 `pi-ai` 刷新器 | +| 26 | `buildAuthDoctorHint` | 当 OAuth 刷新失败时附加的修复提示 | 提供商在刷新失败后需要提供商自有的认证修复指导 | +| 27 | `matchesContextOverflowError` | 提供商自有的上下文窗口溢出匹配器 | 提供商存在通用启发式无法捕获的原始溢出错误 | +| 28 | `classifyFailoverReason` | 提供商自有的故障切换原因分类 | 提供商可以将原始 API/传输错误映射为限流、过载等 | +| 29 | `isCacheTtlEligible` | 面向代理/回程提供商的提示词缓存策略 | 提供商需要代理专属的缓存 TTL 门控 | +| 30 | `buildMissingAuthMessage` | 替代通用缺失认证恢复消息 | 提供商需要提供商专属的缺失认证恢复提示 | +| 31 | `suppressBuiltInModel` | 抑制过时的上游模型,并可选提供面向用户的错误提示 | 提供商需要隐藏过时的上游条目,或用供应商提示替换它们 | +| 32 | `augmentModelCatalog` | 在发现之后追加合成/最终目录条目 | 提供商需要在 `models list` 和选择器中提供合成的前向兼容条目 | +| 33 | `resolveThinkingProfile` | 设置特定于模型的 `/think` 级别、显示标签和默认值 | 提供商为选定模型暴露自定义思考等级体系或二元标签 | +| 34 | `isBinaryThinking` | 开/关推理切换兼容性钩子 | 提供商只暴露二元的思考开/关 | +| 35 | `supportsXHighThinking` | `xhigh` 推理支持兼容性钩子 | 提供商只希望在部分模型上支持 `xhigh` | +| 36 | `resolveDefaultThinkingLevel` | 默认 `/think` 级别兼容性钩子 | 提供商拥有某个模型家族的默认 `/think` 策略 | +| 37 | `isModernModelRef` | 用于实时配置文件过滤和冒烟选择的现代模型匹配器 | 提供商拥有实时/冒烟首选模型匹配逻辑 | +| 38 | `prepareRuntimeAuth` | 在推理前将已配置的凭证交换为实际运行时 token/key | 提供商需要执行 token 交换或使用短生命周期请求凭证 | +| 39 | `resolveUsageAuth` | 为 `/usage` 及相关状态表面解析用量/计费凭证 | 提供商需要自定义用量/配额 token 解析,或使用不同的用量凭证 | +| 40 | `fetchUsageSnapshot` | 在认证解析后获取并规范化提供商专属的用量/配额快照 | 提供商需要提供商专属的用量端点或负载解析器 | +| 41 | `createEmbeddingProvider` | 为 memory/search 构建由提供商拥有的 embedding adapter | Memory 的 embedding 行为应归属于提供商插件 | +| 42 | `buildReplayPolicy` | 返回一个控制该提供商转录处理方式的重放策略 | 提供商需要自定义转录策略(例如剥离 thinking 块) | +| 43 | `sanitizeReplayHistory` | 在通用转录清理后重写重放历史 | 提供商需要在共享压缩辅助工具之外执行提供商专属的重放重写 | +| 44 | `validateReplayTurns` | 在嵌入式运行器之前对重放轮次做最终校验或重塑 | 提供商传输在通用净化后仍需要更严格的轮次校验 | +| 45 | `onModelSelected` | 在模型被选中后运行提供商自有的后续副作用 | 当某个模型变为活跃时,提供商需要遥测或提供商自有状态 | -`normalizeModelId`、`normalizeTransport` 和 `normalizeConfig` 会先检查匹配到的提供商插件,然后再继续尝试其他支持这些 hook 的提供商插件,直到某个插件实际修改了 model id 或 transport/config。这样可以保持别名/兼容提供商 shim 正常工作,而无需调用方知道哪个内置插件拥有该重写逻辑。如果没有任何提供商 hook 重写受支持的 Google 家族配置项,内置的 Google 配置规范化器仍然会应用那层兼容性清理。 +`normalizeModelId`、`normalizeTransport` 和 `normalizeConfig` 会先检查 +匹配到的提供商插件,然后继续传递给其他具备钩子能力的提供商插件, +直到其中某个插件实际修改了模型 id 或传输/配置为止。这样可以让 +别名/兼容性提供商 shim 正常工作,而不要求调用方知道究竟是哪个 +内置插件拥有该重写逻辑。如果没有任何提供商钩子重写某个受支持的 +Google 家族配置条目,内置的 Google 配置规范化器仍会执行该兼容性清理。 -如果提供商需要完全自定义的线协议或自定义请求执行器,那就属于另一类扩展。这些 hook 适用于仍运行在 OpenClaw 常规推理循环上的提供商行为。 +如果提供商需要完全自定义的线协议或自定义请求执行器, +那属于另一类扩展。这些钩子适用于仍然运行在 OpenClaw +正常推理循环上的提供商行为。 ### 提供商示例 @@ -625,25 +777,111 @@ api.registerProvider({ ### 内置示例 -- Anthropic 使用 `resolveDynamicModel`、`capabilities`、`buildAuthDoctorHint`、`resolveUsageAuth`、`fetchUsageSnapshot`、`isCacheTtlEligible`、`resolveThinkingProfile`、`applyConfigDefaults`、`isModernModelRef` 和 `wrapStreamFn`,因为它拥有 Claude 4.6 前向兼容、提供商家族提示、认证修复指导、使用量端点集成、提示词缓存资格、感知认证的配置默认值、Claude 默认/自适应思考策略,以及面向 beta headers、`/fast` / `serviceTier` 和 `context1m` 的 Anthropic 特定流整形。 -- Anthropic 的 Claude 特定流辅助工具当前仍保留在内置插件自己的公共 `api.ts` / `contract-api.ts` 接缝中。该包表面导出 `wrapAnthropicProviderStream`、`resolveAnthropicBetas`、`resolveAnthropicFastMode`、`resolveAnthropicServiceTier` 以及更底层的 Anthropic 包装器构建器,而不是为了某个提供商的 beta-header 规则去扩大通用 SDK。 -- OpenAI 使用 `resolveDynamicModel`、`normalizeResolvedModel` 和 `capabilities`,以及 `buildMissingAuthMessage`、`suppressBuiltInModel`、`augmentModelCatalog`、`resolveThinkingProfile` 和 `isModernModelRef`,因为它拥有 GPT-5.4 前向兼容、直接 OpenAI `openai-completions` -> `openai-responses` 规范化、面向 Codex 的认证提示、Spark 抑制、synthetic OpenAI 列表条目,以及 GPT-5 思考 / 实时模型策略;`openai-responses-defaults` 流家族则拥有共享的原生 OpenAI Responses 包装器,用于 attribution headers、`/fast`/`serviceTier`、文本详细度、原生 Codex Web 搜索、reasoning-compat 负载整形和 Responses 上下文管理。 -- OpenRouter 使用 `catalog`,以及 `resolveDynamicModel` 和 `prepareDynamicModel`,因为该提供商是透传型的,并且可能会在 OpenClaw 的静态目录更新前暴露新的 model id;它还使用 `capabilities`、`wrapStreamFn` 和 `isCacheTtlEligible`,以便将提供商特定的请求头、路由元数据、reasoning 补丁和提示词缓存策略保留在核心之外。它的回放策略来自 `passthrough-gemini` 家族,而 `openrouter-thinking` 流家族拥有代理 reasoning 注入,以及对不受支持模型和 `auto` 的跳过逻辑。 -- GitHub Copilot 使用 `catalog`、`auth`、`resolveDynamicModel` 和 `capabilities`,以及 `prepareRuntimeAuth` 和 `fetchUsageSnapshot`,因为它需要提供商自有的设备登录、模型回退行为、Claude 转录特性、GitHub token -> Copilot token 交换,以及提供商自有的使用量端点。 -- OpenAI Codex 使用 `catalog`、`resolveDynamicModel`、`normalizeResolvedModel`、`refreshOAuth` 和 `augmentModelCatalog`,以及 `prepareExtraParams`、`resolveUsageAuth` 和 `fetchUsageSnapshot`,因为它仍运行在核心 OpenAI 传输之上,但拥有自己的传输/base URL 规范化、OAuth 刷新回退策略、默认传输选择、synthetic Codex 目录条目,以及 ChatGPT 使用量端点集成;它与直接 OpenAI 共用同一个 `openai-responses-defaults` 流家族。 -- Google AI Studio 和 Gemini CLI OAuth 使用 `resolveDynamicModel`、`buildReplayPolicy`、`sanitizeReplayHistory`、`resolveReasoningOutputMode`、`wrapStreamFn` 和 `isModernModelRef`,因为 `google-gemini` 回放家族拥有 Gemini 3.1 前向兼容回退、原生 Gemini 回放验证、bootstrap 回放净化、带标签的 reasoning-output 模式以及现代模型匹配,而 `google-thinking` 流家族拥有 Gemini thinking 负载规范化;Gemini CLI OAuth 还使用 `formatApiKey`、`resolveUsageAuth` 和 `fetchUsageSnapshot` 进行令牌格式化、令牌解析和配额端点接线。 -- Anthropic Vertex 通过 `anthropic-by-model` 回放家族使用 `buildReplayPolicy`,这样 Claude 特定的回放清理就能限定在 Claude id 范围内,而不是作用于每个 `anthropic-messages` 传输。 -- Amazon Bedrock 使用 `buildReplayPolicy`、`matchesContextOverflowError`、`classifyFailoverReason` 和 `resolveThinkingProfile`,因为它拥有面向 Anthropic-on-Bedrock 流量的 Bedrock 特定限流/未就绪/上下文溢出错误分类;它的回放策略仍然共享相同的仅 Claude `anthropic-by-model` 防护。 -- OpenRouter、Kilocode、Opencode 和 Opencode Go 通过 `passthrough-gemini` 回放家族使用 `buildReplayPolicy`,因为它们通过 OpenAI 兼容传输代理 Gemini 模型,并且需要 Gemini thought-signature 净化,而不需要原生 Gemini 回放验证或 bootstrap 重写。 -- MiniMax 通过 `hybrid-anthropic-openai` 回放家族使用 `buildReplayPolicy`,因为一个提供商同时拥有 Anthropic-message 和 OpenAI 兼容语义;它在 Anthropic 一侧保留仅 Claude 的 thinking 块丢弃逻辑,同时将 reasoning 输出模式改回原生,而 `minimax-fast-mode` 流家族则在共享流路径上拥有 fast-mode 模型重写。 -- Moonshot 使用 `catalog`、`resolveThinkingProfile` 和 `wrapStreamFn`,因为它仍使用共享 OpenAI 传输,但需要提供商自有的 thinking 负载规范化;`moonshot-thinking` 流家族将配置加 `/think` 状态映射到其原生二元 thinking 负载上。 -- Kilocode 使用 `catalog`、`capabilities`、`wrapStreamFn` 和 `isCacheTtlEligible`,因为它需要提供商自有的请求头、reasoning 负载规范化、Gemini 转录提示和 Anthropic 缓存 TTL 门控;`kilocode-thinking` 流家族将 Kilo thinking 注入保留在共享代理流路径上,同时跳过 `kilo/auto` 以及其他不支持显式 reasoning 负载的代理 model id。 -- Z.AI 使用 `resolveDynamicModel`、`prepareExtraParams`、`wrapStreamFn`、`isCacheTtlEligible`、`resolveThinkingProfile`、`isModernModelRef`、`resolveUsageAuth` 和 `fetchUsageSnapshot`,因为它拥有 GLM-5 回退、`tool_stream` 默认值、二元 thinking UX、现代模型匹配,以及使用量认证和配额抓取;`tool-stream-default-on` 流家族则将默认开启的 `tool_stream` 包装器从每个提供商手写胶水代码中抽离出来。 -- xAI 使用 `normalizeResolvedModel`、`normalizeTransport`、`contributeResolvedModelCompat`、`prepareExtraParams`、`wrapStreamFn`、`resolveSyntheticAuth`、`resolveDynamicModel` 和 `isModernModelRef`,因为它拥有原生 xAI Responses 传输规范化、Grok fast-mode 别名重写、默认 `tool_stream`、strict-tool / reasoning-payload 清理、面向插件自有工具的回退认证复用、前向兼容的 Grok 模型解析,以及提供商自有的兼容补丁,例如 xAI 工具 schema 配置文件、不受支持的 schema 关键字、原生 `web_search` 和 HTML 实体 tool-call 参数解码。 -- Mistral、OpenCode Zen 和 OpenCode Go 仅使用 `capabilities`,以将转录/工具特性保留在核心之外。 -- 仅目录型的内置提供商,例如 `byteplus`、`cloudflare-ai-gateway`、`huggingface`、`kimi-coding`、`nvidia`、`qianfan`、`synthetic`、`together`、`venice`、`vercel-ai-gateway` 和 `volcengine`,只使用 `catalog`。 -- Qwen 为其文本提供商使用 `catalog`,并为其多模态表面使用共享的媒体理解和视频生成注册。 -- MiniMax 和 Xiaomi 使用 `catalog` 加使用量 hook,因为尽管推理仍通过共享传输运行,但它们的 `/usage` 行为归属于插件。 +- Anthropic 使用 `resolveDynamicModel`、`capabilities`、`buildAuthDoctorHint`、 + `resolveUsageAuth`、`fetchUsageSnapshot`、`isCacheTtlEligible`、 + `resolveThinkingProfile`、`applyConfigDefaults`、`isModernModelRef` + 和 `wrapStreamFn`,因为它拥有 Claude 4.6 前向兼容、 + 提供商家族提示、认证修复指导、用量端点集成、 + 提示词缓存可用性、具备认证感知能力的配置默认值、Claude + 默认/自适应思考策略,以及面向 + beta headers、`/fast` / `serviceTier` 和 `context1m` 的 Anthropic 专属流整形能力。 +- Anthropic 的 Claude 专属流辅助工具目前保留在内置插件自身公开的 + `api.ts` / `contract-api.ts` 接缝中。该 package 表面 + 导出 `wrapAnthropicProviderStream`、`resolveAnthropicBetas`、 + `resolveAnthropicFastMode`、`resolveAnthropicServiceTier` 以及更底层的 + Anthropic wrapper builder,而不是围绕某一个 + 提供商的 beta-header 规则扩展通用 SDK。 +- OpenAI 使用 `resolveDynamicModel`、`normalizeResolvedModel` 和 + `capabilities`,以及 `buildMissingAuthMessage`、`suppressBuiltInModel`、 + `augmentModelCatalog`、`resolveThinkingProfile` 和 `isModernModelRef`, + 因为它拥有 GPT-5.4 前向兼容、直接的 OpenAI + `openai-completions` -> `openai-responses` 规范化、面向 Codex 的认证 + 提示、Spark 抑制、合成 OpenAI 列表条目,以及 GPT-5 的思考 / + 实时模型策略;`openai-responses-defaults` 流家族拥有共享的原生 OpenAI Responses 包装器,用于处理归因请求头、 + `/fast`/`serviceTier`、文本冗长度、原生 Codex 网页搜索、 + 推理兼容性负载整形,以及 Responses 上下文管理。 +- OpenRouter 使用 `catalog`,以及 `resolveDynamicModel` 和 + `prepareDynamicModel`,因为该提供商是透传型的,并且可能在 + OpenClaw 静态目录更新之前暴露新的模型 id;它还使用 + `capabilities`、`wrapStreamFn` 和 `isCacheTtlEligible`,以便将 + 提供商专属请求头、路由元数据、推理补丁以及 + 提示词缓存策略放在核心之外。其重放策略来自 + `passthrough-gemini` 家族,而 `openrouter-thinking` 流家族 + 拥有代理推理注入以及对不受支持模型 / `auto` 的跳过逻辑。 +- GitHub Copilot 使用 `catalog`、`auth`、`resolveDynamicModel` 和 + `capabilities`,以及 `prepareRuntimeAuth` 和 `fetchUsageSnapshot`, + 因为它需要提供商自有的设备登录、模型回退行为、Claude 转录 + 特性、GitHub token -> Copilot token 交换,以及提供商自有的用量端点。 +- OpenAI Codex 使用 `catalog`、`resolveDynamicModel`、 + `normalizeResolvedModel`、`refreshOAuth` 和 `augmentModelCatalog`,以及 + `prepareExtraParams`、`resolveUsageAuth` 和 `fetchUsageSnapshot`,因为它 + 虽然仍运行在核心 OpenAI 传输之上,但拥有自己的传输/base URL + 规范化、OAuth 刷新回退策略、默认传输选择、 + 合成 Codex 目录条目,以及 ChatGPT 用量端点集成;它 + 与直接 OpenAI 共享相同的 `openai-responses-defaults` 流家族。 +- Google AI Studio 和 Gemini CLI OAuth 使用 `resolveDynamicModel`、 + `buildReplayPolicy`、`sanitizeReplayHistory`、 + `resolveReasoningOutputMode`、`wrapStreamFn` 和 `isModernModelRef`,因为 + `google-gemini` 重放家族拥有 Gemini 3.1 前向兼容回退、 + 原生 Gemini 重放校验、引导式重放净化、 + 带标签的推理输出模式,以及现代模型匹配,而 + `google-thinking` 流家族拥有 Gemini thinking 负载规范化; + Gemini CLI OAuth 还使用 `formatApiKey`、`resolveUsageAuth` 和 + `fetchUsageSnapshot`,用于 token 格式化、token 解析以及配额端点 + 接线。 +- Anthropic Vertex 通过 + `anthropic-by-model` 重放家族使用 `buildReplayPolicy`,这样 Claude 专属的重放清理 + 只会限定在 Claude id 上,而不是作用于每个 `anthropic-messages` 传输。 +- Amazon Bedrock 使用 `buildReplayPolicy`、`matchesContextOverflowError`、 + `classifyFailoverReason` 和 `resolveThinkingProfile`,因为它拥有 + 针对 Anthropic-on-Bedrock 流量的 Bedrock 专属限流/未就绪/上下文溢出错误分类; + 其重放策略仍与相同的 + 仅 Claude 的 `anthropic-by-model` 防护共享。 +- OpenRouter、Kilocode、Opencode 和 Opencode Go 通过 `buildReplayPolicy` + 使用 `passthrough-gemini` 重放家族,因为它们通过 OpenAI 兼容传输代理 Gemini + 模型,并且需要 Gemini + thought-signature 净化,而不需要原生 Gemini 重放校验或 + 引导式重写。 +- MiniMax 通过 + `hybrid-anthropic-openai` 重放家族使用 `buildReplayPolicy`,因为一个提供商同时拥有 + Anthropic-message 和 OpenAI 兼容语义;它在 Anthropic 一侧保留仅 Claude 的 + thinking 块丢弃逻辑,同时将推理 + 输出模式覆盖回原生,而 `minimax-fast-mode` 流家族则拥有 + 共享流路径上的 fast-mode 模型重写。 +- Moonshot 使用 `catalog`、`resolveThinkingProfile` 和 `wrapStreamFn`,因为它仍使用共享的 + OpenAI 传输,但需要提供商自有的 thinking 负载规范化;而 + `moonshot-thinking` 流家族则将配置加上 `/think` 状态映射到其 + 原生的二元 thinking 负载。 +- Kilocode 使用 `catalog`、`capabilities`、`wrapStreamFn` 和 + `isCacheTtlEligible`,因为它需要提供商自有的请求头、 + 推理负载规范化、Gemini 转录提示以及 Anthropic + 缓存 TTL 门控;`kilocode-thinking` 流家族会在共享代理流路径上保留 Kilo thinking + 注入,同时跳过 `kilo/auto` 和其他 + 不支持显式推理负载的代理模型 id。 +- Z.AI 使用 `resolveDynamicModel`、`prepareExtraParams`、`wrapStreamFn`、 + `isCacheTtlEligible`、`resolveThinkingProfile`、`isModernModelRef`、 + `resolveUsageAuth` 和 `fetchUsageSnapshot`,因为它拥有 GLM-5 回退、 + `tool_stream` 默认值、二元 thinking UX、现代模型匹配,以及 + 用量认证和配额获取;`tool-stream-default-on` 流家族则将默认开启的 `tool_stream` 包装器从各提供商手写胶水代码中抽离出来。 +- xAI 使用 `normalizeResolvedModel`、`normalizeTransport`、 + `contributeResolvedModelCompat`、`prepareExtraParams`、`wrapStreamFn`、 + `resolveSyntheticAuth`、`resolveDynamicModel` 和 `isModernModelRef`, + 因为它拥有原生 xAI Responses 传输规范化、Grok fast-mode + 别名重写、默认 `tool_stream`、严格工具 / 推理负载 + 清理、面向插件自有工具的回退认证复用、前向兼容的 Grok + 模型解析,以及提供商自有的兼容性补丁,例如 xAI 工具 schema + 配置、受支持性不足的 schema 关键字、原生 `web_search` 和 HTML 实体 + 工具调用参数解码。 +- Mistral、OpenCode Zen 和 OpenCode Go 仅使用 `capabilities`, + 以便将转录/工具特性留在核心之外。 +- 仅目录型的内置提供商,例如 `byteplus`、`cloudflare-ai-gateway`、 + `huggingface`、`kimi-coding`、`nvidia`、`qianfan`、 + `synthetic`、`together`、`venice`、`vercel-ai-gateway` 和 `volcengine` + 只使用 `catalog`。 +- Qwen 使用 `catalog` 作为其文本提供商能力,同时为其多模态表面注册共享的媒体理解和 + 视频生成能力。 +- MiniMax 和 Xiaomi 使用 `catalog` 加上用量钩子,因为它们的 `/usage` + 行为归插件所有,尽管推理仍通过共享传输运行。 ## 运行时辅助工具 @@ -669,10 +907,10 @@ const voices = await api.runtime.tts.listVoices({ 说明: - `textToSpeech` 返回适用于文件/语音便笺表面的常规核心 TTS 输出负载。 -- 使用核心 `messages.tts` 配置和提供商选择逻辑。 -- 返回 PCM 音频缓冲区 + 采样率。插件必须为提供商自行重采样/编码。 -- `listVoices` 对每个提供商来说是可选的。可将其用于供应商自有语音选择器或设置流程。 -- 语音列表可以包含更丰富的元数据,例如语言区域、性别和个性标签,以支持感知提供商的选择器。 +- 使用核心 `messages.tts` 配置和提供商选择。 +- 返回 PCM 音频缓冲区 + 采样率。插件必须为各自提供商完成重采样/编码。 +- `listVoices` 对每个提供商而言是可选的。可将其用于供应商自有的语音选择器或设置流程。 +- 语音列表可以包含更丰富的元数据,例如区域设置、性别和个性标签,以供具备提供商感知能力的选择器使用。 - 当前 OpenAI 和 ElevenLabs 支持电话场景。Microsoft 不支持。 插件也可以通过 `api.registerSpeechProvider(...)` 注册语音提供商。 @@ -695,12 +933,15 @@ api.registerSpeechProvider({ 说明: -- 将 TTS 策略、回退和回复交付保留在核心中。 -- 对供应商自有的合成行为使用语音提供商。 -- legacy Microsoft `edge` 输入会被规范化为 `microsoft` provider id。 -- 首选的归属模型是面向公司的:随着 OpenClaw 添加这些能力契约,一个供应商插件可以统一拥有文本、语音、图像和未来的媒体提供商。 +- 将 TTS 策略、回退和回复投递保留在核心中。 +- 使用语音提供商来承载供应商自有的合成行为。 +- 旧式 Microsoft `edge` 输入会被规范化为 `microsoft` 提供商 id。 +- 更推荐的归属模型是面向公司:随着 OpenClaw 增加这些 + 能力契约,一个供应商插件可以同时拥有 + 文本、语音、图像和未来的媒体提供商能力。 -对于图像/音频/视频理解,插件会注册一个类型化的媒体理解提供商,而不是通用的键值包: +对于图像/音频/视频理解,插件会注册一个类型化的 +媒体理解提供商,而不是通用的键值包: ```ts api.registerMediaUnderstandingProvider({ @@ -716,8 +957,9 @@ api.registerMediaUnderstandingProvider({ - 将编排、回退、配置和渠道接线保留在核心中。 - 将供应商行为保留在提供商插件中。 -- 增量扩展应保持类型化:新增可选方法、新增可选结果字段、新增可选能力。 -- 视频生成已经遵循同样模式: +- 增量扩展应保持类型化:新的可选方法、新的可选 + 结果字段、新的可选能力。 +- 视频生成已经遵循同样的模式: - 核心拥有能力契约和运行时辅助工具 - 供应商插件注册 `api.registerVideoGenerationProvider(...)` - 功能/渠道插件消费 `api.runtime.videoGeneration.*` @@ -737,25 +979,27 @@ const video = await api.runtime.mediaUnderstanding.describeVideoFile({ }); ``` -对于音频转录,插件可以使用媒体理解运行时,或使用旧的 STT 别名: +对于音频转录,插件既可以使用媒体理解运行时, +也可以使用较旧的 STT 别名: ```ts const { text } = await api.runtime.mediaUnderstanding.transcribeAudioFile({ filePath: "/tmp/inbound-audio.ogg", cfg: api.config, - // Optional when MIME cannot be inferred reliably: + // 当无法可靠推断 MIME 时可选: mime: "audio/ogg", }); ``` 说明: -- `api.runtime.mediaUnderstanding.*` 是图像/音频/视频理解的首选共享表面。 +- `api.runtime.mediaUnderstanding.*` 是图像/音频/视频理解 + 首选的共享表面。 - 使用核心媒体理解音频配置(`tools.media.audio`)和提供商回退顺序。 -- 当未产生转录输出时(例如输入被跳过/不受支持),返回 `{ text: undefined }`。 +- 当没有生成转录输出时(例如输入被跳过/不受支持),返回 `{ text: undefined }`。 - `api.runtime.stt.transcribeAudioFile(...)` 仍保留为兼容性别名。 -插件也可以通过 `api.runtime.subagent` 启动后台子智能体运行: +插件还可以通过 `api.runtime.subagent` 启动后台子智能体运行: ```ts const result = await api.runtime.subagent.run({ @@ -769,13 +1013,14 @@ const result = await api.runtime.subagent.run({ 说明: -- `provider` 和 `model` 是每次运行的可选覆盖项,不是持久性的会话变更。 -- OpenClaw 仅对受信任调用方启用这些覆盖字段。 -- 对于插件自有的回退运行,操作员必须通过 `plugins.entries..subagent.allowModelOverride: true` 显式选择启用。 -- 使用 `plugins.entries..subagent.allowedModels` 将受信任插件限制为特定的规范 `provider/model` 目标,或者设为 `"*"` 以显式允许任意目标。 -- 不受信任的插件子智能体运行仍可工作,但覆盖请求会被拒绝,而不是静默回退。 +- `provider` 和 `model` 是每次运行的可选覆盖项,而不是持久化的会话更改。 +- OpenClaw 只会对受信任调用方应用这些覆盖字段。 +- 对于插件自有的回退运行,运维人员必须通过 `plugins.entries..subagent.allowModelOverride: true` 显式启用。 +- 使用 `plugins.entries..subagent.allowedModels` 可将受信任插件限制为特定的规范 `provider/model` 目标,或使用 `"*"` 明确允许任意目标。 +- 不受信任的插件子智能体运行仍然可用,但覆盖请求会被拒绝,而不是静默回退。 -对于 Web 搜索,插件可以消费共享运行时辅助工具,而不是深入智能体工具接线: +对于网页搜索,插件可以消费共享运行时辅助工具,而不是 +直接深入智能体工具接线: ```ts const providers = api.runtime.webSearch.listProviders({ @@ -791,13 +1036,14 @@ const result = await api.runtime.webSearch.search({ }); ``` -插件也可以通过 `api.registerWebSearchProvider(...)` 注册 Web 搜索提供商。 +插件也可以通过 +`api.registerWebSearchProvider(...)` 注册网页搜索提供商。 说明: - 将提供商选择、凭证解析和共享请求语义保留在核心中。 -- 对供应商特定搜索传输使用 Web 搜索提供商。 -- `api.runtime.webSearch.*` 是需要搜索行为但不依赖智能体工具包装器的功能/渠道插件的首选共享表面。 +- 使用网页搜索提供商来承载供应商专属搜索传输。 +- `api.runtime.webSearch.*` 是首选的共享表面,适用于需要搜索行为但不依赖智能体工具包装器的功能/渠道插件。 ### `api.runtime.imageGeneration` @@ -835,154 +1081,254 @@ api.registerHttpRoute({ 路由字段: - `path`:Gateway 网关 HTTP 服务器下的路由路径。 -- `auth`:必填。使用 `"gateway"` 以要求正常的 Gateway 网关认证,或使用 `"plugin"` 以启用插件管理的认证/webhook 验证。 -- `match`:可选。可为 `"exact"`(默认)或 `"prefix"`。 -- `replaceExisting`:可选。允许同一插件替换其自身已有的路由注册。 -- `handler`:当路由处理了该请求时返回 `true`。 +- `auth`:必填。使用 `"gateway"` 以要求普通 Gateway 网关认证,或使用 `"plugin"` 以启用插件管理的认证/webhook 校验。 +- `match`:可选。`"exact"`(默认)或 `"prefix"`。 +- `replaceExisting`:可选。允许同一个插件替换自己现有的路由注册。 +- `handler`:当路由处理了请求时返回 `true`。 说明: - `api.registerHttpHandler(...)` 已被移除,并会导致插件加载错误。请改用 `api.registerHttpRoute(...)`。 - 插件路由必须显式声明 `auth`。 -- 除非设置 `replaceExisting: true`,否则精确的 `path + match` 冲突会被拒绝,而且一个插件不能替换另一个插件的路由。 -- 不同 `auth` 级别的重叠路由会被拒绝。请仅在相同认证级别内保留 `exact`/`prefix` 透传链。 -- `auth: "plugin"` 路由**不会**自动收到操作员运行时作用域。它们用于插件管理的 webhook/签名验证,而不是特权 Gateway 网关 helper 调用。 -- `auth: "gateway"` 路由会在 Gateway 网关请求运行时作用域内运行,但该作用域有意保持保守: +- 除非设置了 `replaceExisting: true`,否则精确的 `path + match` 冲突会被拒绝,并且一个插件不能替换另一个插件的路由。 +- 具有不同 `auth` 级别的重叠路由会被拒绝。仅在相同认证级别下保留 `exact`/`prefix` 回退链。 +- `auth: "plugin"` 路由**不会**自动接收运维人员运行时作用域。它们用于插件管理的 webhook/签名校验,而不是特权 Gateway 网关辅助调用。 +- `auth: "gateway"` 路由运行在 Gateway 网关请求运行时作用域内,但该作用域被有意保持为保守模式: - 共享密钥 bearer 认证(`gateway.auth.mode = "token"` / `"password"`)会将插件路由运行时作用域固定为 `operator.write`,即使调用方发送了 `x-openclaw-scopes` - - 携带受信任身份的 HTTP 模式(例如 `trusted-proxy`,或私有入口上的 `gateway.auth.mode = "none"`)仅在显式存在该请求头时才会尊重 `x-openclaw-scopes` - - 如果这些携带身份的插件路由请求中不存在 `x-openclaw-scopes`,运行时作用域会回退到 `operator.write` -- 实际规则:不要假设一个经过 gateway 认证的插件路由天然就是管理员表面。如果你的路由需要仅管理员可用的行为,请要求使用携带身份的认证模式,并记录明确的 `x-openclaw-scopes` 请求头契约。 + - 带有受信任身份信息的 HTTP 模式(例如 `trusted-proxy` 或私有入口上的 `gateway.auth.mode = "none"`)仅在显式存在该请求头时才会尊重 `x-openclaw-scopes` + - 如果这些带身份信息的插件路由请求缺少 `x-openclaw-scopes`,运行时作用域会回退到 `operator.write` +- 实际规则:不要假设一个使用 gateway 认证的插件路由天然就是管理员表面。如果你的路由需要仅管理员可用的行为,请要求使用带身份信息的认证模式,并记录显式的 `x-openclaw-scopes` 请求头契约。 ## 插件 SDK 导入路径 -编写插件时,请使用 SDK 子路径,而不是单体 `openclaw/plugin-sdk` 导入: +在编写插件时,请使用 SDK 子路径,而不是使用单体式的 `openclaw/plugin-sdk` 导入: -- `openclaw/plugin-sdk/plugin-entry`:用于插件注册原语。 -- `openclaw/plugin-sdk/core`:用于通用共享的面向插件契约。 -- `openclaw/plugin-sdk/config-schema`:用于根 `openclaw.json` Zod schema 导出(`OpenClawSchema`)。 -- 稳定的渠道原语,例如 `openclaw/plugin-sdk/channel-setup`、`openclaw/plugin-sdk/setup-runtime`、`openclaw/plugin-sdk/setup-adapter-runtime`、`openclaw/plugin-sdk/setup-tools`、`openclaw/plugin-sdk/channel-pairing`、`openclaw/plugin-sdk/channel-contract`、`openclaw/plugin-sdk/channel-feedback`、`openclaw/plugin-sdk/channel-inbound`、`openclaw/plugin-sdk/channel-lifecycle`、`openclaw/plugin-sdk/channel-reply-pipeline`、`openclaw/plugin-sdk/command-auth`、`openclaw/plugin-sdk/secret-input` 和 `openclaw/plugin-sdk/webhook-ingress`,用于共享的设置/认证/回复/webhook 接线。`channel-inbound` 是 debounce、提及匹配、入站提及策略 helper、envelope 格式化以及入站 envelope 上下文 helper 的共享归属位置。`channel-setup` 是狭义的可选安装设置接缝。`setup-runtime` 是 `setupEntry` / 延迟启动所使用的运行时安全设置表面,其中包括导入安全的设置补丁适配器。`setup-adapter-runtime` 是感知环境变量的账户设置适配器接缝。`setup-tools` 是小型 CLI/归档/文档 helper 接缝(`formatCliCommand`、`detectBinary`、`extractArchive`、`resolveBrewExecutable`、`formatDocsLink`、`CONFIG_DIR`)。 -- 域子路径,例如 `openclaw/plugin-sdk/channel-config-helpers`、`openclaw/plugin-sdk/allow-from`、`openclaw/plugin-sdk/channel-config-schema`、`openclaw/plugin-sdk/telegram-command-config`、`openclaw/plugin-sdk/channel-policy`、`openclaw/plugin-sdk/approval-gateway-runtime`、`openclaw/plugin-sdk/approval-handler-adapter-runtime`、`openclaw/plugin-sdk/approval-handler-runtime`、`openclaw/plugin-sdk/approval-runtime`、`openclaw/plugin-sdk/config-runtime`、`openclaw/plugin-sdk/infra-runtime`、`openclaw/plugin-sdk/agent-runtime`、`openclaw/plugin-sdk/lazy-runtime`、`openclaw/plugin-sdk/reply-history`、`openclaw/plugin-sdk/routing`、`openclaw/plugin-sdk/status-helpers`、`openclaw/plugin-sdk/text-runtime`、`openclaw/plugin-sdk/runtime-store` 和 `openclaw/plugin-sdk/directory-runtime`,用于共享运行时/配置 helper。`telegram-command-config` 是 Telegram 自定义命令规范化/验证的狭义公共接缝,即使内置 Telegram 契约表面暂时不可用,它也会保持可用。`text-runtime` 是共享的文本/Markdown/日志接缝,其中包括对智能体可见文本的剥离、Markdown 渲染/分块 helper、脱敏 helper、directive-tag helper 和安全文本工具。 -- 审批特定的渠道接缝应优先在插件上使用一个 `approvalCapability` 契约。然后核心会通过这一项能力来读取审批认证、交付、渲染、原生路由和惰性原生处理器行为,而不是将审批行为混入无关的插件字段。 -- `openclaw/plugin-sdk/channel-runtime` 已弃用,当前仅作为对旧插件的兼容 shim 保留。新代码应改为导入更狭义的通用原语,仓库代码也不应新增对该 shim 的导入。 -- 内置扩展内部实现仍然是私有的。外部插件应只使用 `openclaw/plugin-sdk/*` 子路径。OpenClaw 核心/测试代码可以使用插件包根目录下的仓库公共入口点,例如 `index.js`、`api.js`、`runtime-api.js`、`setup-entry.js`,以及范围狭窄的文件,例如 `login-qr-api.js`。绝不要从核心或另一个扩展中导入某个插件包的 `src/*`。 +- `openclaw/plugin-sdk/plugin-entry` 用于插件注册原语。 +- `openclaw/plugin-sdk/core` 用于通用共享的面向插件契约。 +- `openclaw/plugin-sdk/config-schema` 用于根 `openclaw.json` Zod schema + 导出(`OpenClawSchema`)。 +- 稳定的渠道原语,例如 `openclaw/plugin-sdk/channel-setup`、 + `openclaw/plugin-sdk/setup-runtime`、 + `openclaw/plugin-sdk/setup-adapter-runtime`、 + `openclaw/plugin-sdk/setup-tools`、 + `openclaw/plugin-sdk/channel-pairing`、 + `openclaw/plugin-sdk/channel-contract`、 + `openclaw/plugin-sdk/channel-feedback`、 + `openclaw/plugin-sdk/channel-inbound`、 + `openclaw/plugin-sdk/channel-lifecycle`、 + `openclaw/plugin-sdk/channel-reply-pipeline`、 + `openclaw/plugin-sdk/command-auth`、 + `openclaw/plugin-sdk/secret-input` 以及 + `openclaw/plugin-sdk/webhook-ingress`,用于共享设置/认证/回复/webhook + 接线。`channel-inbound` 是防抖、提及匹配、 + 入站提及策略辅助工具、信封格式化以及入站信封 + 上下文辅助工具的共享归属位置。 + `channel-setup` 是狭窄的可选安装设置接缝。 + `setup-runtime` 是 `setupEntry` / + 延迟启动所使用的运行时安全设置表面,其中包括导入安全的设置补丁适配器。 + `setup-adapter-runtime` 是具备环境感知能力的账户设置适配器接缝。 + `setup-tools` 是小型 CLI/归档/文档辅助工具接缝(`formatCliCommand`、 + `detectBinary`、`extractArchive`、`resolveBrewExecutable`、`formatDocsLink`、 + `CONFIG_DIR`)。 +- 领域子路径,例如 `openclaw/plugin-sdk/channel-config-helpers`、 + `openclaw/plugin-sdk/allow-from`、 + `openclaw/plugin-sdk/channel-config-schema`、 + `openclaw/plugin-sdk/telegram-command-config`、 + `openclaw/plugin-sdk/channel-policy`、 + `openclaw/plugin-sdk/approval-gateway-runtime`、 + `openclaw/plugin-sdk/approval-handler-adapter-runtime`、 + `openclaw/plugin-sdk/approval-handler-runtime`、 + `openclaw/plugin-sdk/approval-runtime`、 + `openclaw/plugin-sdk/config-runtime`、 + `openclaw/plugin-sdk/infra-runtime`、 + `openclaw/plugin-sdk/agent-runtime`、 + `openclaw/plugin-sdk/lazy-runtime`、 + `openclaw/plugin-sdk/reply-history`、 + `openclaw/plugin-sdk/routing`、 + `openclaw/plugin-sdk/status-helpers`、 + `openclaw/plugin-sdk/text-runtime`、 + `openclaw/plugin-sdk/runtime-store` 以及 + `openclaw/plugin-sdk/directory-runtime`,用于共享运行时/配置辅助工具。 + `telegram-command-config` 是 Telegram 自定义 + 命令规范化/校验的狭窄公开接缝,即使内置的 + Telegram 契约表面暂时不可用,它仍会保持可用。 + `text-runtime` 是共享的文本/Markdown/日志接缝,其中包括 + 面向助手可见文本的剥离、Markdown 渲染/分块辅助工具、脱敏 + 辅助工具、directive-tag 辅助工具以及安全文本工具。 +- 审批专用的渠道接缝应优先在插件上使用单一的 `approvalCapability` + 契约。然后核心会通过这一项能力读取审批认证、投递、渲染、 + 原生路由和惰性原生处理器行为,而不是将审批行为混入无关的插件字段中。 +- `openclaw/plugin-sdk/channel-runtime` 已弃用,当前仅作为 + 旧插件的兼容性 shim 保留。新代码应改用更狭窄的 + 通用原语导入,而仓库代码不应新增对该 shim 的导入。 +- 内置扩展内部实现仍然是私有的。外部插件应只使用 + `openclaw/plugin-sdk/*` 子路径。OpenClaw 核心/测试代码可以使用 + 插件 package 根目录下的仓库公开入口点,例如 `index.js`、`api.js`、 + `runtime-api.js`、`setup-entry.js` 以及狭窄范围的文件,例如 + `login-qr-api.js`。绝不要从核心或另一个扩展中导入某个插件 package 的 `src/*`。 - 仓库入口点拆分: - `/api.js` 是 helper/类型 barrel, + `/api.js` 是辅助工具/类型 barrel, `/runtime-api.js` 是仅运行时 barrel, `/index.js` 是内置插件入口, `/setup-entry.js` 是设置插件入口。 - 当前内置提供商示例: - - Anthropic 使用 `api.js` / `contract-api.js` 提供 Claude 流 helper,例如 `wrapAnthropicProviderStream`、beta-header helpers 和 `service_tier` 解析。 - - OpenAI 使用 `api.js` 提供 provider 构建器、默认模型 helper 和实时 provider 构建器。 - - OpenRouter 使用 `api.js` 提供其 provider 构建器以及新手引导/配置 helper,而 `register.runtime.js` 仍可为仓库本地用途重新导出通用 `plugin-sdk/provider-stream` helper。 -- 通过 facade 加载的公共入口点会优先使用活动运行时配置快照;如果 OpenClaw 尚未提供运行时快照,则回退到磁盘上的已解析配置文件。 -- 通用共享原语仍然是首选的公共 SDK 契约。仍然存在一小组保留的、带内置渠道品牌的 helper 接缝以维持兼容性。应将这些视为内置维护/兼容性接缝,而不是新的第三方导入目标;新的跨渠道契约仍应落在通用 `plugin-sdk/*` 子路径或插件本地 `api.js` / `runtime-api.js` barrel 上。 + - Anthropic 使用 `api.js` / `contract-api.js` 提供 Claude 流辅助工具,例如 + `wrapAnthropicProviderStream`、beta-header 辅助工具以及 `service_tier` + 解析。 + - OpenAI 使用 `api.js` 提供 provider builder、默认模型辅助工具以及 + realtime provider builder。 + - OpenRouter 使用 `api.js` 提供其 provider builder 以及新手引导/配置 + 辅助工具,而 `register.runtime.js` 仍可为仓库本地用途重新导出通用 + `plugin-sdk/provider-stream` 辅助工具。 +- 由 facade 加载的公开入口点在存在活动运行时配置快照时会优先使用该快照, + 否则当 OpenClaw 尚未提供运行时快照时,会回退到磁盘上已解析的配置文件。 +- 通用共享原语仍然是首选的公开 SDK 契约。仍然存在一小组保留的、兼容性用途的内置渠道品牌化辅助工具接缝。请将这些视为内置维护/兼容性接缝,而不是新的第三方导入目标;新的跨渠道契约仍应落在通用 `plugin-sdk/*` 子路径或插件本地 `api.js` / + `runtime-api.js` barrel 上。 兼容性说明: -- 新代码应避免使用根 `openclaw/plugin-sdk` barrel。 -- 优先使用狭义稳定原语。较新的 setup/pairing/reply/feedback/contract/inbound/threading/command/secret-input/webhook/infra/allowlist/status/message-tool 子路径,是新的内置和外部插件工作的预期契约。目标解析/匹配应放在 `openclaw/plugin-sdk/channel-targets`。消息动作门控和 reaction message-id helper 应放在 `openclaw/plugin-sdk/channel-actions`。 -- 内置扩展特定的 helper barrel 默认不稳定。如果某个 helper 仅供某个内置扩展使用,请将它保留在该扩展本地的 `api.js` 或 `runtime-api.js` 接缝之后,而不是将其提升到 `openclaw/plugin-sdk/`。 -- 新的共享 helper 接缝应是通用的,而不是带渠道品牌的。共享目标解析应放在 `openclaw/plugin-sdk/channel-targets`;渠道特定内部实现则应保留在归属插件本地的 `api.js` 或 `runtime-api.js` 接缝之后。 -- `image-generation`、`media-understanding` 和 `speech` 这类特定于能力的子路径之所以存在,是因为当前内置/原生插件正在使用它们。它们的存在本身并不意味着每个导出的 helper 都是长期冻结的对外契约。 +- 新代码应避免使用根级 `openclaw/plugin-sdk` barrel。 +- 优先使用狭窄且稳定的原语。较新的 setup/pairing/reply/ + feedback/contract/inbound/threading/command/secret-input/webhook/infra/ + allowlist/status/message-tool 子路径,才是新的 + 内置和外部插件工作的预期契约。 + 目标解析/匹配应放在 `openclaw/plugin-sdk/channel-targets` 上。 + 消息操作门控和 reaction message-id 辅助工具应放在 + `openclaw/plugin-sdk/channel-actions` 上。 +- 内置扩展专用的辅助 barrel 默认并不稳定。如果某个 + 辅助工具只被内置扩展需要,应将其保留在扩展本地的 + `api.js` 或 `runtime-api.js` 接缝之后,而不是提升到 + `openclaw/plugin-sdk/` 中。 +- 新的共享辅助工具接缝应当是通用的,而不是带渠道品牌的。共享目标 + 解析应放在 `openclaw/plugin-sdk/channel-targets`;渠道专属 + 内部实现则保留在归属插件本地的 `api.js` 或 `runtime-api.js` + 接缝之后。 +- `image-generation`、 + `media-understanding` 和 `speech` 等能力专属子路径之所以存在,是因为今天 + 内置/原生插件正在使用它们。它们的存在本身并不意味着每个导出的辅助工具 + 都是长期冻结的外部契约。 -## Message 工具 schema +## 消息工具 schema -对于 reaction、已读和投票等非消息原语,插件应拥有渠道特定的 `describeMessageTool(...)` schema 贡献。共享发送呈现应使用通用 `MessagePresentation` 契约,而不是提供商原生的按钮、组件、块或卡片字段。有关契约、回退规则、提供商映射和插件作者检查清单,请参阅 [Message Presentation](/zh-CN/plugins/message-presentation)。 +对于 reaction、已读和投票等非消息原语, +插件应拥有渠道专属的 `describeMessageTool(...)` schema +贡献。共享发送展示应使用通用 `MessagePresentation` 契约, +而不是提供商原生的按钮、组件、区块或卡片字段。 +有关该契约、回退规则、提供商映射以及插件作者检查清单,请参见 [Message Presentation](/zh-CN/plugins/message-presentation)。 -具备发送能力的插件通过消息能力声明其可渲染内容: +具备发送能力的插件通过消息能力声明自己可以渲染什么: -- `presentation`:语义化呈现块(`text`、`context`、`divider`、`buttons`、`select`) -- `delivery-pin`:用于固定交付请求 +- `presentation`:语义化展示区块(`text`、`context`、`divider`、`buttons`、`select`) +- `delivery-pin`:置顶投递请求 -核心决定是原生渲染该呈现,还是将其降级为文本。不要从通用 message 工具暴露提供商原生 UI 的逃生口。 -针对 legacy 原生 schema 的已弃用 SDK helper 仍会导出以兼容现有第三方插件,但新插件不应使用它们。 +核心决定是原生渲染该展示,还是将其降级为文本。 +不要从通用消息工具中暴露提供商原生 UI 的逃逸口。 +面向旧原生 schema 的已弃用 SDK 辅助工具仍会为现有 +第三方插件导出,但新插件不应使用它们。 ## 渠道目标解析 -渠道插件应拥有渠道特定的目标语义。请保持共享出站宿主的通用性,并使用消息适配器表面处理提供商规则: +渠道插件应拥有渠道专属的目标语义。保持共享出站宿主通用, +并通过消息适配器表面处理提供商规则: -- `messaging.inferTargetChatType({ to })` 用于在目录查找之前,决定某个规范化目标应被视为 `direct`、`group` 还是 `channel` -- `messaging.targetResolver.looksLikeId(raw, normalized)` 告诉核心某个输入是否应跳过目录搜索,直接进入类似 id 的解析 -- `messaging.targetResolver.resolveTarget(...)` 是插件回退路径,当规范化之后或目录未命中之后,核心需要提供商自有的最终解析时使用 -- `messaging.resolveOutboundSessionRoute(...)` 在目标解析完成后拥有提供商特定的会话路由构造逻辑 +- `messaging.inferTargetChatType({ to })` 用于决定一个已规范化目标 + 在目录查找前应被视为 `direct`、`group` 还是 `channel`。 +- `messaging.targetResolver.looksLikeId(raw, normalized)` 用于告诉核心, + 某个输入是否应直接跳到类似 id 的解析,而不是进行目录搜索。 +- `messaging.targetResolver.resolveTarget(...)` 是插件回退路径, + 当核心在规范化后或目录未命中后需要最终的提供商自有解析时使用。 +- `messaging.resolveOutboundSessionRoute(...)` 用于在目标解析完成后, + 拥有提供商专属的会话路由构造逻辑。 -推荐拆分方式: +推荐拆分: -- 对于应在搜索联系人/群组之前进行的分类决策,使用 `inferTargetChatType` -- 对于“将此视为显式/原生目标 id”检查,使用 `looksLikeId` -- 将 `resolveTarget` 用于提供商特定的规范化回退,而不是大范围目录搜索 -- 将 chat id、thread id、JID、handle 和 room id 这类提供商原生 id 保留在 `target` 值或提供商特定参数中,而不是放进通用 SDK 字段 +- 对于应在搜索 peers/groups 之前完成的分类决策,使用 `inferTargetChatType`。 +- 对于“将此视为显式/原生目标 id”的检查,使用 `looksLikeId`。 +- 将 `resolveTarget` 用于提供商专属的规范化回退,而不是广泛的目录搜索。 +- 将 chat id、thread id、JID、handle 和 room id 等提供商原生 id 保留在 `target` 值或提供商专属参数中,而不是放入通用 SDK 字段。 ## 基于配置的目录 -如果插件从配置中派生目录条目,应将该逻辑保留在插件内,并复用 `openclaw/plugin-sdk/directory-runtime` 中的共享 helper。 +如果插件从配置中派生目录条目,请将该逻辑保留在 +插件内部,并复用 +`openclaw/plugin-sdk/directory-runtime` 中的共享辅助工具。 -当渠道需要基于配置的联系人/群组时,可以使用这种方式,例如: +适用于渠道需要基于配置的 peers/groups 的场景,例如: -- 基于允许列表的私信联系人 +- 基于 allowlist 驱动的私信 peers - 已配置的渠道/群组映射 -- 按账户作用域划分的静态目录回退 +- 按账户划分的静态目录回退 -`directory-runtime` 中的共享 helper 仅处理通用操作: +`directory-runtime` 中的共享辅助工具只处理通用操作: - 查询过滤 -- limit 应用 -- 去重/规范化 helper +- 限制应用 +- 去重/规范化辅助工具 - 构建 `ChannelDirectoryEntry[]` -渠道特定的账户检查和 id 规范化应保留在插件实现中。 +渠道专属的账户检查和 id 规范化仍应保留在 +插件实现中。 ## 提供商目录 -提供商插件可以使用 `registerProvider({ catalog: { run(...) { ... } } })` 为推理定义模型目录。 +提供商插件可以通过 +`registerProvider({ catalog: { run(...) { ... } } })` 定义用于推理的模型目录。 -`catalog.run(...)` 返回与 OpenClaw 写入 `models.providers` 相同的结构: +`catalog.run(...)` 返回与 OpenClaw 写入 +`models.providers` 相同的结构: - `{ provider }`:一个提供商条目 - `{ providers }`:多个提供商条目 -当插件拥有提供商特定的 model id、base URL 默认值或受认证控制的模型元数据时,请使用 `catalog`。 +当插件拥有提供商专属的模型 id、base URL 默认值,或需要认证门控的模型元数据时,请使用 `catalog`。 `catalog.order` 控制插件目录相对于 OpenClaw 内置隐式提供商的合并时机: -- `simple`:普通 API key 或基于环境变量的提供商 -- `profile`:当存在认证配置文件时出现的提供商 +- `simple`:普通 API key 或环境变量驱动的提供商 +- `profile`:存在认证配置文件时出现的提供商 - `paired`:合成多个相关提供商条目的提供商 - `late`:最后一轮,在其他隐式提供商之后 -后面的提供商会在键冲突时胜出,因此插件可以有意覆盖具有相同 provider id 的内置提供商条目。 +后出现的提供商在键冲突时获胜,因此插件可以有意使用相同 provider id 覆盖内置提供商条目。 兼容性: -- `discovery` 仍可作为 legacy 别名使用 +- `discovery` 仍可作为旧式别名使用 - 如果同时注册了 `catalog` 和 `discovery`,OpenClaw 会使用 `catalog` ## 只读渠道检查 -如果你的插件注册了一个渠道,请优先在 `resolveAccount(...)` 之外同时实现 `plugin.config.inspectAccount(cfg, accountId)`。 +如果你的插件注册了一个渠道,建议在 `resolveAccount(...)` 之外,同时实现 +`plugin.config.inspectAccount(cfg, accountId)`。 原因: -- `resolveAccount(...)` 是运行时路径。它可以假设凭证已完全实例化,并在缺少所需 secret 时快速失败。 -- `openclaw status`、`openclaw status --all`、`openclaw channels status`、`openclaw channels resolve` 以及 Doctor/配置修复流等只读命令路径,不应为了描述配置而必须实例化运行时凭证。 +- `resolveAccount(...)` 是运行时路径。它可以假定凭证 + 已被完全实体化,并且在缺少所需密钥时快速失败。 +- 只读命令路径,例如 `openclaw status`、`openclaw status --all`、 + `openclaw channels status`、`openclaw channels resolve`,以及 doctor/config + 修复流程,不应为了描述配置而需要实体化运行时凭证。 推荐的 `inspectAccount(...)` 行为: -- 仅返回描述性账户状态。 +- 仅返回描述性的账户状态。 - 保留 `enabled` 和 `configured`。 - 在相关时包含凭证来源/状态字段,例如: - `tokenSource`、`tokenStatus` - `botTokenSource`、`botTokenStatus` - `appTokenSource`、`appTokenStatus` - `signingSecretSource`、`signingSecretStatus` -- 你不需要为了报告只读可用性而返回原始 token 值。返回 `tokenStatus: "available"`(以及匹配的来源字段)就足以支持 status 风格命令。 -- 当凭证通过 SecretRef 配置,但在当前命令路径中不可用时,请使用 `configured_unavailable`。 +- 你不需要为了报告只读可用性而返回原始 token 值。 + 返回 `tokenStatus: "available"`(以及对应的来源字段) + 就足以满足状态类命令。 +- 当凭证通过 SecretRef 配置、但在当前命令路径中不可用时, + 使用 `configured_unavailable`。 -这样一来,只读命令就能报告“已配置,但在此命令路径中不可用”,而不是崩溃或错误地将账户报告为未配置。 +这样一来,只读命令就可以报告“已配置,但在当前命令路径中不可用”,而不是崩溃或错误地将该账户报告为未配置。 -## 包 pack +## Package packs -插件目录可以包含一个带有 `openclaw.extensions` 的 `package.json`: +一个插件目录可以包含带有 `openclaw.extensions` 的 `package.json`: ```json { @@ -994,37 +1340,59 @@ api.registerHttpRoute({ } ``` -每个条目都会成为一个插件。如果 pack 列出了多个扩展,则插件 id 会变成 `name/`。 +每个条目都会成为一个插件。如果该 pack 列出多个扩展,则插件 id +会变成 `name/`。 -如果你的插件导入了 npm 依赖,请在该目录中安装它们,以便 `node_modules` 可用(`npm install` / `pnpm install`)。 +如果你的插件导入了 npm 依赖,请在该目录中安装它们, +以便 `node_modules` 可用(`npm install` / `pnpm install`)。 -安全护栏:每个 `openclaw.extensions` 条目在解析符号链接后都必须仍位于插件目录内。逃离包目录的条目会被拒绝。 +安全护栏:每个 `openclaw.extensions` 条目在解析符号链接后都必须保留在插件 +目录内。逃逸出 package 目录的条目会被拒绝。 -安全说明:`openclaw plugins install` 会使用 `npm install --omit=dev --ignore-scripts` 安装插件依赖(无生命周期脚本,运行时无开发依赖)。请保持插件依赖树为“纯 JS/TS”,并避免依赖需要 `postinstall` 构建的包。 +安全说明:`openclaw plugins install` 会使用 +`npm install --omit=dev --ignore-scripts` 安装插件依赖(无生命周期脚本,运行时无开发依赖)。请保持插件依赖树为“纯 JS/TS”,并避免依赖需要 `postinstall` 构建的 package。 -可选:`openclaw.setupEntry` 可以指向一个轻量级、仅用于设置的模块。当 OpenClaw 需要为一个已禁用的渠道插件提供设置表面,或者渠道插件已启用但尚未配置时,它会加载 `setupEntry`,而不是完整插件入口。这样在主插件入口还会接入工具、hook 或其他仅运行时代码时,可以让启动和设置过程更轻量。 +可选:`openclaw.setupEntry` 可以指向一个轻量级的仅设置模块。 +当 OpenClaw 需要为一个已禁用的渠道插件提供设置表面时,或 +当某个渠道插件已启用但尚未配置时,它会加载 `setupEntry` +而不是完整插件入口。这样可以在你的主插件入口还会接线工具、钩子或其他仅运行时代码时, +让启动和设置过程更轻量。 -可选:`openclaw.startup.deferConfiguredChannelFullLoadUntilAfterListen` 可以让某个渠道插件在 Gateway 网关的 pre-listen 启动阶段也选择使用同一个 `setupEntry` 路径,即使该渠道已经配置完成。 +可选:`openclaw.startup.deferConfiguredChannelFullLoadUntilAfterListen` +可以让渠道插件在 Gateway 网关监听前的启动阶段,即便该渠道已完成配置, +也选择使用同样的 `setupEntry` 路径。 -仅当 `setupEntry` 完全覆盖了 Gateway 网关开始监听前必须存在的启动表面时,才应使用此选项。实际上,这意味着设置入口必须注册启动所依赖的每一项渠道自有能力,例如: +仅当 `setupEntry` 完整覆盖了 Gateway 网关开始监听前必须存在的启动表面时, +才应使用此项。实际上,这意味着设置入口 +必须注册启动所依赖的每一个渠道自有能力,例如: - 渠道注册本身 -- Gateway 网关开始监听前必须可用的任何 HTTP 路由 -- 在同一时间窗口内必须存在的任何 Gateway 网关方法、工具或服务 +- 任何必须在 Gateway 网关开始监听前可用的 HTTP 路由 +- 任何在同一时间窗口内必须存在的 Gateway 网关方法、工具或服务 -如果你的完整入口仍然拥有任何必需的启动能力,就不要启用这个标志。应保持插件使用默认行为,让 OpenClaw 在启动期间加载完整入口。 +如果你的完整入口仍然拥有任何必需的启动能力,请不要启用 +此标志。保持插件默认行为,并让 OpenClaw 在启动期间加载完整入口。 -内置渠道也可以发布仅设置期的契约表面 helper,以便核心在完整渠道运行时加载前进行查询。当前的设置提升表面包括: +内置渠道还可以发布仅设置用的契约表面辅助工具,供核心在完整渠道运行时加载前进行查询。当前的设置 +提升表面是: - `singleAccountKeysToMove` - `namedAccountPromotionKeys` - `resolveSingleAccountPromotionTarget(...)` -当核心需要在不加载完整插件入口的情况下,将 legacy 单账户渠道配置提升到 `channels..accounts.*` 时,会使用这层表面。Matrix 是当前的内置示例:当已存在命名账户时,它只会将认证/bootstrap 键移动到某个已命名的提升账户中,并且可以保留一个已配置的非规范默认账户键,而不是总是创建 `accounts.default`。 +当核心需要在不加载完整插件入口的情况下,将旧式单账户渠道 +配置提升到 `channels..accounts.*` 时,会使用这一表面。 +Matrix 是当前的内置示例:当已存在命名账户时,它只会将认证/引导键移动到 +某个命名提升账户中,并且它可以保留一个已配置的非规范默认账户键,而不是始终创建 +`accounts.default`。 -这些设置补丁适配器使内置契约表面发现保持惰性。导入时依然很轻量;提升表面只会在首次使用时加载,而不是在模块导入时重新进入内置渠道启动逻辑。 +这些设置补丁适配器会让内置契约表面发现保持惰性。导入时 +保持轻量;提升表面只会在首次使用时加载,而不是在模块导入时重新进入内置渠道启动流程。 -当这些启动表面包含 Gateway 网关 RPC 方法时,请将它们保留在插件特定前缀下。核心管理命名空间(`config.*`、`exec.approvals.*`、`wizard.*`、`update.*`)仍然保留,并且始终解析为 `operator.admin`,即使某个插件请求了更窄的作用域也是如此。 +当这些启动表面包含 Gateway 网关 RPC 方法时,请将它们保留在 +插件专属前缀下。核心管理员命名空间(`config.*`、 +`exec.approvals.*`、`wizard.*`、`update.*`)仍然是保留的,并且始终解析 +为 `operator.admin`,即使某个插件请求更窄的作用域也是如此。 示例: @@ -1043,7 +1411,8 @@ api.registerHttpRoute({ ### 渠道目录元数据 -渠道插件可以通过 `openclaw.channel` 宣传设置/发现元数据,并通过 `openclaw.install` 提供安装提示。这使核心目录保持无数据状态。 +渠道插件可以通过 `openclaw.channel` 宣告设置/发现元数据,并通过 +`openclaw.install` 宣告安装提示。这使核心目录保持无数据化。 示例: @@ -1071,34 +1440,42 @@ api.registerHttpRoute({ } ``` -除最小示例外,有用的 `openclaw.channel` 字段还包括: +除最小示例外,其他有用的 `openclaw.channel` 字段包括: -- `detailLabel`:用于更丰富目录/status 表面的次级标签 -- `docsLabel`:覆盖文档链接的链接文本 -- `preferOver`:该目录条目应优先于哪些低优先级插件/渠道 id -- `selectionDocsPrefix`、`selectionDocsOmitLabel`、`selectionExtras`:用于选择表面文案控制 +- `detailLabel`:用于更丰富目录/状态表面的次级标签 +- `docsLabel`:用于覆盖文档链接的链接文本 +- `preferOver`:此目录条目应优先于的低优先级插件/渠道 id +- `selectionDocsPrefix`、`selectionDocsOmitLabel`、`selectionExtras`:选择表面的文案控制项 - `markdownCapable`:将该渠道标记为支持 Markdown,以用于出站格式化决策 -- `exposure.configured`:设为 `false` 时,在已配置渠道列表表面中隐藏该渠道 -- `exposure.setup`:设为 `false` 时,在交互式设置/配置选择器中隐藏该渠道 +- `exposure.configured`:设置为 `false` 时,在已配置渠道列表表面中隐藏该渠道 +- `exposure.setup`:设置为 `false` 时,在交互式设置/配置选择器中隐藏该渠道 - `exposure.docs`:将该渠道标记为内部/私有,用于文档导航表面 -- `showConfigured` / `showInSetup`:仍接受的 legacy 别名,仅用于兼容性;优先使用 `exposure` -- `quickstartAllowFrom`:让该渠道接入标准快速开始 `allowFrom` 流程 +- `showConfigured` / `showInSetup`:为兼容性仍接受的旧式别名;优先使用 `exposure` +- `quickstartAllowFrom`:让该渠道加入标准快速开始 `allowFrom` 流程 - `forceAccountBinding`:即使只存在一个账户,也要求显式账户绑定 -- `preferSessionLookupForAnnounceTarget`:在解析通知目标时优先使用会话查找 +- `preferSessionLookupForAnnounceTarget`:在解析 announce 目标时优先使用会话查找 -OpenClaw 也可以合并**外部渠道目录**(例如某个 MPM 注册表导出)。可将 JSON 文件放在以下任一位置: +OpenClaw 还可以合并**外部渠道目录**(例如 MPM +注册表导出)。将 JSON 文件放到以下位置之一: - `~/.openclaw/mpm/plugins.json` - `~/.openclaw/mpm/catalog.json` - `~/.openclaw/plugins/catalog.json` -或者将 `OPENCLAW_PLUGIN_CATALOG_PATHS`(或 `OPENCLAW_MPM_CATALOG_PATHS`)指向一个或多个 JSON 文件(以逗号/分号/`PATH` 分隔)。每个文件应包含 `{ "entries": [ { "name": "@scope/pkg", "openclaw": { "channel": {...}, "install": {...} } } ] }`。解析器也接受 `"packages"` 或 `"plugins"` 作为 `"entries"` 键的 legacy 别名。 +或者将 `OPENCLAW_PLUGIN_CATALOG_PATHS`(或 `OPENCLAW_MPM_CATALOG_PATHS`)指向 +一个或多个 JSON 文件(以逗号/分号/`PATH` 分隔)。每个文件应 +包含 `{ "entries": [ { "name": "@scope/pkg", "openclaw": { "channel": {...}, "install": {...} } } ] }`。解析器也接受 `"packages"` 或 `"plugins"` 作为 +`"entries"` 键的旧式别名。 ## 上下文引擎插件 -上下文引擎插件拥有会话上下文编排,负责摄取、组装和压缩。请在你的插件中通过 `api.registerContextEngine(id, factory)` 注册它们,然后使用 `plugins.slots.contextEngine` 选择活动引擎。 +上下文引擎插件拥有会话上下文编排,负责摄取、组装 +和压缩。使用 +`api.registerContextEngine(id, factory)` 从你的插件中注册它们,然后通过 +`plugins.slots.contextEngine` 选择活动引擎。 -当你的插件需要替换或扩展默认上下文流水线,而不仅仅是添加 memory 搜索或 hook 时,请使用这种方式。 +当你的插件需要替换或扩展默认上下文 +流水线,而不仅仅是增加 memory search 或钩子时,请使用此方式。 ```ts import { buildMemorySystemPromptAddition } from "openclaw/plugin-sdk/core"; @@ -1126,7 +1503,8 @@ export default function (api) { } ``` -如果你的引擎**不**拥有压缩算法,请仍实现 `compact()` 并显式委托它: +如果你的引擎**不**拥有压缩算法,请保持 `compact()` +已实现,并显式委托它: ```ts import { @@ -1163,37 +1541,45 @@ export default function (api) { ## 添加新能力 -当插件需要当前 API 无法容纳的行为时,不要通过私有内部访问绕过插件系统。应添加缺失的能力。 +当插件需要当前 API 不适配的行为时,不要通过私有穿透方式绕过 +插件系统。请添加缺失的能力。 推荐顺序: -1. 定义核心契约 - 明确核心应拥有哪些共享行为:策略、回退、配置合并、生命周期、面向渠道的语义以及运行时辅助工具形态。 -2. 添加类型化的插件注册/运行时表面 - 以最小但有用的类型化能力表面扩展 `OpenClawPluginApi` 和/或 `api.runtime`。 -3. 接入核心 + 渠道/功能消费者 - 渠道和功能插件应通过核心消费新能力,而不是直接导入某个供应商实现。 -4. 注册供应商实现 - 然后让供应商插件针对该能力注册它们的后端实现。 -5. 添加契约覆盖 - 添加测试,使归属和注册结构在长期内保持明确。 +1. 定义核心契约 + 决定哪些共享行为应由核心拥有:策略、回退、配置合并、 + 生命周期、面向渠道的语义,以及运行时辅助工具形态。 +2. 添加类型化的插件注册/运行时表面 + 使用最小但有用的 + 类型化能力表面扩展 `OpenClawPluginApi` 和/或 `api.runtime`。 +3. 接线核心 + 渠道/功能消费者 + 渠道和功能插件应通过核心消费该新能力, + 而不是直接导入某个供应商实现。 +4. 注册供应商实现 + 然后由供应商插件将其后端注册到该能力上。 +5. 添加契约覆盖 + 添加测试,以便随着时间推移,归属和注册形态仍保持明确。 -这就是 OpenClaw 如何在保持主张性的同时,不被硬编码到某个提供商的世界观中。有关具体文件检查清单和完整示例,请参阅 [能力扩展手册](/zh-CN/plugins/architecture)。 +这就是 OpenClaw 如何在保持鲜明设计立场的同时,不被硬编码到某个 +供应商的世界观上。具体文件检查清单和完整示例,请参见 [能力扩展手册](/zh-CN/plugins/architecture)。 ### 能力检查清单 -当你添加一个新能力时,通常实现应同时涉及这些表面: +当你添加一个新能力时,通常实现应同时触及以下 +表面: - `src//types.ts` 中的核心契约类型 - `src//runtime.ts` 中的核心运行器/运行时辅助工具 - `src/plugins/types.ts` 中的插件 API 注册表面 - `src/plugins/registry.ts` 中的插件注册表接线 -- 当功能/渠道插件需要消费它时,位于 `src/plugins/runtime/*` 的插件运行时暴露层 -- `src/test-utils/plugin-registration.ts` 中的捕获/测试 helper +- `src/plugins/runtime/*` 中的插件运行时暴露,当功能/渠道 + 插件需要消费它时 +- `src/test-utils/plugin-registration.ts` 中的捕获/测试辅助工具 - `src/plugins/contracts/registry.ts` 中的归属/契约断言 -- `docs/` 中的操作员/插件文档 +- `docs/` 中的运维人员/插件文档 -如果这些表面中有任何一个缺失,通常说明该能力尚未完全集成。 +如果这些表面中有某一项缺失,通常意味着这个能力 +尚未完全集成。 ### 能力模板 @@ -1229,7 +1615,7 @@ const clip = await api.runtime.videoGeneration.generate({ expect(findVideoGenerationProviderIdsForPlugin("openai")).toEqual(["openai"]); ``` -这样规则就很简单: +这让规则保持简单: - 核心拥有能力契约 + 编排 - 供应商插件拥有供应商实现 diff --git a/docs/zh-CN/providers/anthropic.md b/docs/zh-CN/providers/anthropic.md index 915ac6c5c..98c6246c9 100644 --- a/docs/zh-CN/providers/anthropic.md +++ b/docs/zh-CN/providers/anthropic.md @@ -4,46 +4,44 @@ read_when: summary: 在 OpenClaw 中通过 API 密钥或 Claude CLI 使用 Anthropic Claude title: Anthropic x-i18n: - generated_at: "2026-04-12T11:08:22Z" + generated_at: "2026-04-23T06:41:43Z" model: gpt-5.4 provider: openai - source_hash: 5e3dda5f98ade9d4c3841888103bfb43d59e075d358a701ed0ae3ffb8d5694a7 + source_hash: 02e99e31bf58d08a18f526281b3bf5c3a5a96b2ff342adf3a6a193a076147a03 source_path: providers/anthropic.md workflow: 15 --- # Anthropic(Claude) -Anthropic 构建了 **Claude** 模型系列。OpenClaw 支持两种认证方式: +Anthropic 构建了 **Claude** 模型家族。OpenClaw 支持两种认证方式: -- **API 密钥** — 直接访问 Anthropic API,并按使用量计费(`anthropic/*` 模型) -- **Claude CLI** — 在同一主机上复用现有的 Claude CLI 登录 +- **API key** —— 通过 Anthropic API 直接访问,并按使用量计费(`anthropic/*` 模型) +- **Claude CLI** —— 复用同一主机上现有的 Claude CLI 登录 -Anthropic 员工告诉我们,OpenClaw 风格的 Claude CLI 用法再次被允许,因此 -除非 Anthropic 发布新的政策,否则 OpenClaw 会将 Claude CLI 复用和 `claude -p` -用法视为已获认可。 +Anthropic 团队告诉我们,OpenClaw 风格的 Claude CLI 用法已再次被允许,因此除非 Anthropic 发布新的政策,否则 OpenClaw 会将 Claude CLI 复用和 `claude -p` 用法视为获准行为。 -对于长期运行的 Gateway 网关主机,Anthropic API 密钥仍然是最明确且 -最可预测的生产路径。 +对于长期运行的 Gateway 网关主机,Anthropic API key 仍然是最清晰、最可预测的生产环境方案。 Anthropic 当前的公开文档: -- [Claude Code CLI 参考](https://code.claude.com/docs/en/cli-reference) -- [Claude Agent SDK 概览](https://platform.claude.com/docs/en/agent-sdk/overview) -- [在你的 Pro 或 Max 套餐中使用 Claude Code](https://support.claude.com/en/articles/11145838-using-claude-code-with-your-pro-or-max-plan) -- [在你的 Team 或 Enterprise 套餐中使用 Claude Code](https://support.anthropic.com/en/articles/11845131-using-claude-code-with-your-team-or-enterprise-plan/) - +- [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) +- [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/) + + ## 入门指南 - + **最适合:** 标准 API 访问和按使用量计费。 - - 在 [Anthropic Console](https://console.anthropic.com/) 中创建一个 API 密钥。 + + 在 [Anthropic Console](https://console.anthropic.com/) 中创建一个 API key。 ```bash @@ -51,7 +49,7 @@ Anthropic 当前的公开文档: # choose: Anthropic API key ``` - 或者直接传入密钥: + 或直接传入密钥: ```bash openclaw onboard --anthropic-api-key "$ANTHROPIC_API_KEY" @@ -76,11 +74,11 @@ Anthropic 当前的公开文档: - **最适合:** 复用现有的 Claude CLI 登录,而无需单独的 API 密钥。 + **最适合:** 复用现有 Claude CLI 登录,而无需单独的 API key。 - 验证方式如下: + 通过以下命令验证: ```bash claude --version @@ -102,21 +100,21 @@ Anthropic 当前的公开文档: - Claude CLI 后端的设置与运行时细节见 [CLI 后端](/zh-CN/gateway/cli-backends)。 + Claude CLI 后端的设置和运行时细节见 [CLI Backends](/zh-CN/gateway/cli-backends)。 - 如果你想要最清晰的计费路径,请改用 Anthropic API 密钥。OpenClaw 也支持来自 [OpenAI Codex](/zh-CN/providers/openai)、[Qwen Cloud](/zh-CN/providers/qwen)、[MiniMax](/zh-CN/providers/minimax) 和 [Z.AI / GLM](/zh-CN/providers/glm) 的订阅式选项。 + 如果你想要最清晰的计费路径,请改用 Anthropic API key。OpenClaw 还支持来自 [OpenAI Codex](/zh-CN/providers/openai)、[Qwen Cloud](/zh-CN/providers/qwen)、[MiniMax](/zh-CN/providers/minimax) 和 [Z.AI / GLM](/zh-CN/providers/glm) 的订阅式选项。 -## 思考默认值(Claude 4.6) +## Thinking 默认值(Claude 4.6) -当未设置显式思考级别时,Claude 4.6 模型在 OpenClaw 中默认使用 `adaptive` 思考。 +当未设置显式 thinking 级别时,Claude 4.6 模型在 OpenClaw 中默认使用 `adaptive` thinking。 -可通过 `/think:` 为每条消息覆盖,或在模型参数中设置: +可通过 `/think:` 按消息覆盖,或在模型参数中设置: ```json5 { @@ -134,19 +132,19 @@ Anthropic 当前的公开文档: 相关 Anthropic 文档: -- [自适应思考](https://platform.claude.com/docs/en/build-with-claude/adaptive-thinking) -- [扩展思考](https://platform.claude.com/docs/en/build-with-claude/extended-thinking) +- [Adaptive thinking](https://platform.claude.com/docs/en/build-with-claude/adaptive-thinking) +- [Extended thinking](https://platform.claude.com/docs/en/build-with-claude/extended-thinking) ## 提示词缓存 -OpenClaw 支持 Anthropic 在 API 密钥认证下的提示词缓存功能。 +OpenClaw 支持 Anthropic 的提示词缓存功能,适用于 API key 认证。 -| 值 | 缓存时长 | 说明 | -| ------------------- | -------- | ------------------------------ | -| `"short"`(默认) | 5 分钟 | 对 API 密钥认证自动启用 | -| `"long"` | 1 小时 | 扩展缓存 | -| `"none"` | 不缓存 | 禁用提示词缓存 | +| 值 | 缓存时长 | 说明 | +| ------------------- | -------------- | -------------------------------------- | +| `"short"`(默认) | 5 分钟 | 会自动应用于 API key 认证 | +| `"long"` | 1 小时 | 扩展缓存 | +| `"none"` | 不缓存 | 禁用提示词缓存 | ```json5 { @@ -164,7 +162,7 @@ OpenClaw 支持 Anthropic 在 API 密钥认证下的提示词缓存功能。 - 使用模型级参数作为基线,然后通过 `agents.list[].params` 覆盖特定智能体: + 先将模型级参数作为基线,然后通过 `agents.list[].params` 覆盖特定智能体: ```json5 { @@ -190,24 +188,24 @@ OpenClaw 支持 Anthropic 在 API 密钥认证下的提示词缓存功能。 1. `agents.defaults.models["provider/model"].params` 2. `agents.list[].params`(匹配 `id`,按键覆盖) - 这样可以让一个智能体保留长期缓存,而同一模型上的另一个智能体则为突发型 / 低复用流量禁用缓存。 + 这样可以让一个智能体保留长期缓存,而同一模型上的另一个智能体则为突发 / 低复用流量禁用缓存。 - - Bedrock 上的 Anthropic Claude 模型(`amazon-bedrock/*anthropic.claude*`)在已配置时接受 `cacheRetention` 透传。 - - 非 Anthropic 的 Bedrock 模型会在运行时被强制设为 `cacheRetention: "none"`。 - - 当未设置显式值时,API 密钥的智能默认值也会为 Bedrock 上的 Claude 引用预填 `cacheRetention: "short"`。 + - Bedrock 上的 Anthropic Claude 模型(`amazon-bedrock/*anthropic.claude*`)在配置后接受 `cacheRetention` 透传。 + - 非 Anthropic 的 Bedrock 模型会在运行时被强制设置为 `cacheRetention: "none"`。 + - 当未设置显式值时,API key 智能默认值也会为 Claude-on-Bedrock 引用预置 `cacheRetention: "short"`。 ## 高级配置 - - OpenClaw 的共享 `/fast` 开关支持直连 Anthropic 流量(API 密钥以及面向 `api.anthropic.com` 的 OAuth)。 + + OpenClaw 的共享 `/fast` 开关支持直接 Anthropic 流量(发送到 `api.anthropic.com` 的 API key 和 OAuth)。 - | Command | Maps to | + | 命令 | 映射为 | |---------|---------| | `/fast on` | `service_tier: "auto"` | | `/fast off` | `service_tier: "standard_only"` | @@ -227,30 +225,29 @@ OpenClaw 支持 Anthropic 在 API 密钥认证下的提示词缓存功能。 ``` - - 仅对直连 `api.anthropic.com` 的请求注入。代理路由会保持 `service_tier` 不变。 - - 如果同时设置了显式 `serviceTier` 或 `service_tier` 参数,它们会覆盖 `/fast`。 - - 在没有 Priority Tier 容量的账户上,`service_tier: "auto"` 可能会解析为 `standard`。 + - 仅注入到直接发送到 `api.anthropic.com` 的请求中。代理路由不会改动 `service_tier`。 + - 当 `/fast` 与显式 `serviceTier` 或 `service_tier` 参数同时设置时,后者优先。 + - 对于没有 Priority Tier 容量的账户,`service_tier: "auto"` 可能会解析为 `standard`。 - - 内置的 Anthropic 插件注册了图片和 PDF 理解能力。OpenClaw - 会根据已配置的 Anthropic 认证自动解析媒体能力——无需 - 额外配置。 + + 内置 Anthropic 插件注册了图像和 PDF 理解功能。OpenClaw + 会根据配置的 Anthropic 认证自动解析媒体能力——无需额外配置。 - | Property | Value | - | --------------- | -------------------- | - | Default model | `claude-opus-4-6` | - | Supported input | Images, PDF documents | + | 属性 | 值 | + | -------------- | -------------------- | + | 默认模型 | `claude-opus-4-6` | + | 支持的输入 | 图像、PDF 文档 | - 当图片或 PDF 附加到会话中时,OpenClaw 会自动 - 通过 Anthropic 媒体理解提供商进行路由。 + 当会话中附加图像或 PDF 时,OpenClaw 会自动 + 将其路由到 Anthropic 媒体理解提供商。 - - Anthropic 的 1M 上下文窗口受测试版权限控制。请按模型启用: + + Anthropic 的 1M 上下文窗口受 beta 门控。请按模型启用: ```json5 { @@ -269,29 +266,36 @@ OpenClaw 支持 Anthropic 在 API 密钥认证下的提示词缓存功能。 OpenClaw 会将其映射为请求中的 `anthropic-beta: context-1m-2025-08-07`。 - 需要你的 Anthropic 凭证具备长上下文访问权限。旧版令牌认证(`sk-ant-oat-*`)不支持 1M 上下文请求——OpenClaw 会记录一条警告并回退到标准上下文窗口。 + 需要你的 Anthropic 凭证具备长上下文访问权限。旧版 token 认证(`sk-ant-oat-*`)不支持 1M 上下文请求——OpenClaw 会记录警告,并回退到标准上下文窗口。 + + + Claude Opus 4.7(`anthropic/claude-opus-4.7`)及其 `claude-cli` 变体,会在解析后的运行时元数据以及活动智能体状态 / 上下文报告中标准化为 1M 上下文窗口。对于 Opus 4.7,你不需要设置 `params.context1m: true`;它不再继承过时的 200k 回退值。 + + 压缩和溢出处理会自动使用 1M 窗口。其他 Anthropic 模型仍保持其公开限制。 + + ## 故障排除 - - Anthropic 令牌认证可能过期或被撤销。对于新配置,建议迁移到 Anthropic API 密钥。 + + Anthropic token 认证可能会过期或被撤销。对于新配置,建议迁移到 Anthropic API key。 - - 认证是**按智能体**区分的。新智能体不会继承主智能体的密钥。请为该智能体重新运行新手引导,或在 Gateway 网关主机上配置 API 密钥,然后使用 `openclaw models status` 验证。 + + 认证是**按智能体**区分的。新智能体不会继承主智能体的密钥。请为该智能体重新运行新手引导,或在 Gateway 网关主机上配置 API key,然后使用 `openclaw models status` 验证。 - - 运行 `openclaw models status` 以查看当前启用的是哪个认证配置文件。重新运行新手引导,或为该配置文件路径配置 API 密钥。 + + 运行 `openclaw models status` 查看当前启用的是哪个认证配置文件。重新运行新手引导,或为该配置文件路径配置 API key。 - 检查 `openclaw models status --json` 中的 `auth.unusableProfiles`。Anthropic 的速率限制冷却可能是按模型作用域生效的,因此同级的其他 Anthropic 模型可能仍可使用。添加另一个 Anthropic 配置文件,或等待冷却结束。 + 使用 `openclaw models status --json` 检查 `auth.unusableProfiles`。Anthropic 限流冷却可能是按模型范围生效的,因此同级的另一个 Anthropic 模型可能仍然可用。请添加另一个 Anthropic 配置文件,或等待冷却结束。 @@ -306,10 +310,10 @@ OpenClaw 支持 Anthropic 在 API 密钥认证下的提示词缓存功能。 选择提供商、模型引用和故障切换行为。 - Claude CLI 后端设置与运行时细节。 + Claude CLI 后端设置和运行时细节。 - 提示词缓存在各提供商中的工作方式。 + 提示词缓存如何在不同提供商之间工作。 认证细节和凭证复用规则。 diff --git a/docs/zh-CN/providers/bedrock-mantle.md b/docs/zh-CN/providers/bedrock-mantle.md index 369f3b4fb..cf639bfd1 100644 --- a/docs/zh-CN/providers/bedrock-mantle.md +++ b/docs/zh-CN/providers/bedrock-mantle.md @@ -2,54 +2,57 @@ read_when: - 你想在 OpenClaw 中使用由 Bedrock Mantle 托管的 OSS 模型 - 你需要用于 GPT-OSS、Qwen、Kimi 或 GLM 的 Mantle OpenAI 兼容端点 -summary: 使用 Amazon Bedrock Mantle(兼容 OpenAI)模型与 OpenClaw 配合使用 +summary: 在 OpenClaw 中使用 Amazon Bedrock Mantle(兼容 OpenAI)模型 title: Amazon Bedrock Mantle x-i18n: - generated_at: "2026-04-12T10:22:34Z" + generated_at: "2026-04-23T06:42:01Z" model: gpt-5.4 provider: openai - source_hash: 27e602b6f6a3ae92427de135cb9df6356e0daaea6b6fe54723a7542dd0d5d21e + source_hash: b7b3ba0e0a6a175ca1159c0c8ac9cf13a43dfb59b7bb106089c635876c349c61 source_path: providers/bedrock-mantle.md workflow: 15 --- # Amazon Bedrock Mantle -OpenClaw 内置了一个 **Amazon Bedrock Mantle** 提供商,可连接到 Mantle 的 OpenAI 兼容端点。Mantle 通过基于 Bedrock 基础设施的标准 `/v1/chat/completions` 接口托管开源和第三方模型(GPT-OSS、Qwen、Kimi、GLM 及类似模型)。 +OpenClaw 内置了一个 **Amazon Bedrock Mantle** 提供商,用于连接到 +Mantle 的 OpenAI 兼容端点。Mantle 通过由 Bedrock 基础设施支持的标准 +`/v1/chat/completions` 接口托管开源和第三方模型 +(GPT-OSS、Qwen、Kimi、GLM 等类似模型)。 | 属性 | 值 | -| -------------- | ----------------------------------------------------------------------------------- | +| -------------- | ------------------------------------------------------------------------------------------- | | 提供商 ID | `amazon-bedrock-mantle` | -| API | `openai-completions`(兼容 OpenAI) | -| 认证 | 显式 `AWS_BEARER_TOKEN_BEDROCK` 或通过 IAM 凭证链生成 bearer token | +| API | `openai-completions`(OpenAI 兼容)或 `anthropic-messages`(Anthropic Messages 路由) | +| 认证 | 显式 `AWS_BEARER_TOKEN_BEDROCK` 或基于 IAM 凭证链生成 bearer token | | 默认区域 | `us-east-1`(可通过 `AWS_REGION` 或 `AWS_DEFAULT_REGION` 覆盖) | ## 入门指南 -选择你偏好的认证方式,并按照设置步骤进行操作。 +选择你偏好的认证方式,并按步骤进行设置。 - **最适合:** 已经拥有 Mantle bearer token 的环境。 + **最适合:** 你已经拥有 Mantle bearer token 的环境。 - + ```bash export AWS_BEARER_TOKEN_BEDROCK="..." ``` - 你也可以选择设置区域(默认为 `us-east-1`): + 你也可以选择设置区域(默认是 `us-east-1`): ```bash export AWS_REGION="us-west-2" ``` - + ```bash openclaw models list ``` - 已发现的模型会显示在 `amazon-bedrock-mantle` 提供商下。除非你想覆盖默认设置,否则无需额外配置。 + 已发现的模型会显示在 `amazon-bedrock-mantle` 提供商下。除非你想覆盖默认值,否则不需要额外配置。 @@ -59,25 +62,25 @@ OpenClaw 内置了一个 **Amazon Bedrock Mantle** 提供商,可连接到 Mant **最适合:** 使用兼容 AWS SDK 的凭证(共享配置、SSO、web identity、实例角色或任务角色)。 - - 任何兼容 AWS SDK 的认证来源都可以使用: + + 任何兼容 AWS SDK 的认证源都可以使用: ```bash export AWS_PROFILE="default" export AWS_REGION="us-west-2" ``` - + ```bash openclaw models list ``` - OpenClaw 会自动通过凭证链生成 Mantle bearer token。 + OpenClaw 会自动从凭证链生成 Mantle bearer token。 - 当未设置 `AWS_BEARER_TOKEN_BEDROCK` 时,OpenClaw 会通过 AWS 默认凭证链为你签发 bearer token,其中包括共享凭证/配置 profile、SSO、web identity、实例角色或任务角色。 + 当未设置 `AWS_BEARER_TOKEN_BEDROCK` 时,OpenClaw 会从 AWS 默认凭证链为你签发 bearer token,包括共享凭证/配置 profile、SSO、web identity,以及实例角色或任务角色。 @@ -85,15 +88,17 @@ OpenClaw 内置了一个 **Amazon Bedrock Mantle** 提供商,可连接到 Mant ## 自动模型发现 -当设置了 `AWS_BEARER_TOKEN_BEDROCK` 时,OpenClaw 会直接使用它。否则,OpenClaw 会尝试通过 AWS 默认凭证链生成 Mantle bearer token。然后,它会通过查询该区域的 `/v1/models` 端点来发现可用的 Mantle 模型。 +设置了 `AWS_BEARER_TOKEN_BEDROCK` 时,OpenClaw 会直接使用它。否则, +OpenClaw 会尝试从 AWS 默认凭证链生成 Mantle bearer token。 +然后,它会通过查询该区域的 `/v1/models` 端点来发现可用的 Mantle 模型。 | 行为 | 详情 | | ----------------- | ------------------------- | | 发现缓存 | 结果缓存 1 小时 | -| IAM token 刷新 | 每小时一次 | +| IAM token 刷新 | 每小时 | -该 bearer token 与标准 [Amazon Bedrock](/zh-CN/providers/bedrock) 提供商使用的 `AWS_BEARER_TOKEN_BEDROCK` 相同。 +该 bearer token 与标准 [Amazon Bedrock](/zh-CN/providers/bedrock) 提供商使用的 `AWS_BEARER_TOKEN_BEDROCK` 是同一个。 ### 支持的区域 @@ -104,7 +109,7 @@ OpenClaw 内置了一个 **Amazon Bedrock Mantle** 提供商,可连接到 Mant ## 手动配置 -如果你更喜欢显式配置而不是自动发现: +如果你更喜欢显式配置,而不是自动发现: ```json5 { @@ -136,17 +141,54 @@ OpenClaw 内置了一个 **Amazon Bedrock Mantle** 提供商,可连接到 Mant - 是否支持推理会根据模型 ID 中是否包含 `thinking`、`reasoner` 或 `gpt-oss-120b` 等模式来推断。对于匹配的模型,OpenClaw 会在发现时自动设置 `reasoning: true`。 + 推理支持会根据模型 ID 中是否包含诸如 + `thinking`、`reasoner` 或 `gpt-oss-120b` 之类的模式来推断。 + 对于匹配的模型,OpenClaw 会在发现期间自动设置 `reasoning: true`。 - 如果 Mantle 端点不可用或未返回任何模型,该提供商会被静默跳过。OpenClaw 不会报错;其他已配置的提供商仍会继续正常工作。 + 如果 Mantle 端点不可用或未返回任何模型,该提供商会被静默跳过。 + OpenClaw 不会报错;其他已配置的提供商会继续正常工作。 + + + + Mantle 还暴露了一个 Anthropic Messages 路由,该路由通过同一条基于 bearer 认证的流式传输路径承载 Claude 模型。Claude Opus 4.7(`amazon-bedrock-mantle/claude-opus-4.7`)可通过此路由调用,并使用由提供商拥有的流式传输,因此 AWS bearer token 不会被当作 Anthropic API 密钥处理。 + + 当你在 Mantle 提供商上固定使用一个 Anthropic Messages 模型时,OpenClaw 会对该模型使用 `anthropic-messages` API 接口,而不是 `openai-completions`。认证仍然来自 `AWS_BEARER_TOKEN_BEDROCK`(或已签发的 IAM bearer token)。 + + ```json5 + { + models: { + providers: { + "amazon-bedrock-mantle": { + models: [ + { + id: "claude-opus-4.7", + name: "Claude Opus 4.7", + api: "anthropic-messages", + reasoning: true, + input: ["text", "image"], + contextWindow: 1000000, + maxTokens: 32000, + }, + ], + }, + }, + }, + } + ``` + + 对于已发现的 Mantle 模型,其上下文窗口元数据会在可用时使用已知的公开限制;对于未列出的模型,则采用保守回退值,因此压缩和溢出处理能够对较新的条目正确工作,同时不会夸大未知模型的能力。 + - Bedrock Mantle 与标准的 [Amazon Bedrock](/zh-CN/providers/bedrock) 提供商是两个独立的提供商。Mantle 使用兼容 OpenAI 的 `/v1` 接口,而标准 Bedrock 提供商使用原生 Bedrock API。 + Bedrock Mantle 与标准 + [Amazon Bedrock](/zh-CN/providers/bedrock) 提供商是两个独立的提供商。Mantle 使用 + OpenAI 兼容的 `/v1` 接口,而标准 Bedrock 提供商使用 + 原生 Bedrock API。 - 如果存在,这两个提供商会共用同一个 `AWS_BEARER_TOKEN_BEDROCK` 凭证。 + 在存在时,这两个提供商共享同一个 `AWS_BEARER_TOKEN_BEDROCK` 凭证。 diff --git a/docs/zh-CN/providers/deepgram.md b/docs/zh-CN/providers/deepgram.md index 6b59c6149..7e0377729 100644 --- a/docs/zh-CN/providers/deepgram.md +++ b/docs/zh-CN/providers/deepgram.md @@ -1,30 +1,30 @@ --- read_when: - - 你想要为音频附件使用 Deepgram 语音转文本功能 - - 你想要为 Voice Call 使用 Deepgram 流式转录功能 + - 你希望为音频附件使用 Deepgram 语音转文本 + - 你希望为 Voice Call 使用 Deepgram 流式转录 - 你需要一个快速的 Deepgram 配置示例 -summary: 用于接收入站语音便笺的 Deepgram 转录 +summary: 用于入站语音便笺的 Deepgram 转录 title: Deepgram x-i18n: - generated_at: "2026-04-23T02:13:13Z" + generated_at: "2026-04-23T06:41:55Z" model: gpt-5.4 provider: openai - source_hash: ddc55436ebae295db9bd979765fbccab3ba7f25a6f5354a4e7964d151faffa22 + source_hash: 0b05f0f436a723c6e7697612afa0f8cb7e2b84a722d4ec12fae9c0bece945407 source_path: providers/deepgram.md workflow: 15 --- # Deepgram(音频转录) -Deepgram 是一个语音转文本 API。在 OpenClaw 中,它用于通过 `tools.media.audio` 进行入站音频/语音便笺转录,以及通过 `plugins.entries.voice-call.config.streaming` 为 Voice Call 提供流式 STT。 +Deepgram 是一个语音转文本 API。在 OpenClaw 中,它用于通过 `tools.media.audio` 处理入站音频/语音便笺转录,以及通过 `plugins.entries.voice-call.config.streaming` 处理 Voice Call 流式 STT。 -对于批量转录,OpenClaw 会将完整的音频文件上传到 Deepgram,并将转录文本注入回复流水线(`{{Transcript}}` + `[Audio]` 块)。对于 Voice Call 流式转录,OpenClaw 会通过 Deepgram 的 WebSocket `listen` 端点转发实时 G.711 u-law 帧,并在 Deepgram 返回结果时输出部分或最终转录文本。 +对于批量转录,OpenClaw 会将完整音频文件上传到 Deepgram,并将转录文本注入回复流水线(`{{Transcript}}` + `[Audio]` 块)。对于 Voice Call 流式处理,OpenClaw 会通过 Deepgram 的 WebSocket `listen` 端点转发实时 G.711 u-law 帧,并在 Deepgram 返回时发出部分或最终转录结果。 | 详情 | 值 | | ------------- | ---------------------------------------------------------- | | 网站 | [deepgram.com](https://deepgram.com) | | 文档 | [developers.deepgram.com](https://developers.deepgram.com) | -| 认证 | `DEEPGRAM_API_KEY` | +| 身份验证 | `DEEPGRAM_API_KEY` | | 默认模型 | `nova-3` | ## 入门指南 @@ -53,7 +53,8 @@ Deepgram 是一个语音转文本 API。在 OpenClaw 中,它用于通过 `tool ``` - 通过任何已连接的渠道发送一条音频消息。OpenClaw 会通过 Deepgram 对其进行转录,并将转录文本注入回复流水线。 + 通过任意已连接渠道发送一条音频消息。OpenClaw 会通过 Deepgram 对其进行转录, + 并将转录文本注入回复流水线。 @@ -68,7 +69,7 @@ Deepgram 是一个语音转文本 API。在 OpenClaw 中,它用于通过 `tool | `smart_format` | `tools.media.audio.providerOptions.deepgram.smart_format` | 启用智能格式化(可选) | - + ```json5 { tools: { @@ -82,7 +83,7 @@ Deepgram 是一个语音转文本 API。在 OpenClaw 中,它用于通过 `tool } ``` - + ```json5 { tools: { @@ -116,8 +117,8 @@ Deepgram 是一个语音转文本 API。在 OpenClaw 中,它用于通过 `tool | 语言 | `...deepgram.language` | (未设置) | | 编码 | `...deepgram.encoding` | `mulaw` | | 采样率 | `...deepgram.sampleRate` | `8000` | -| 端点检测 | `...deepgram.endpointingMs` | `800` | -| 中间结果 | `...deepgram.interimResults` | `true` | +| Endpointing | `...deepgram.endpointingMs` | `800` | +| 临时结果 | `...deepgram.interimResults` | `true` | ```json5 { @@ -145,34 +146,39 @@ Deepgram 是一个语音转文本 API。在 OpenClaw 中,它用于通过 `tool ``` -Voice Call 接收的是 8 kHz G.711 u-law 电话音频。Deepgram 流式提供商默认使用 `encoding: "mulaw"` 和 `sampleRate: 8000`,因此可以直接转发 Twilio 媒体帧。 +Voice Call 接收的是 8 kHz G.711 u-law 电话音频。Deepgram +流式提供商默认使用 `encoding: "mulaw"` 和 `sampleRate: 8000`,因此 +Twilio 媒体帧可以直接转发。 ## 说明 - - 认证遵循标准的提供商认证顺序。`DEEPGRAM_API_KEY` 是最简单的方式。 + + 身份验证遵循标准的提供商身份验证顺序。`DEEPGRAM_API_KEY` 是 + 最简单的方式。 - 使用代理时,可通过 `tools.media.audio.baseUrl` 和 `tools.media.audio.headers` 覆盖端点或请求头。 + 使用代理时,可通过 `tools.media.audio.baseUrl` 和 + `tools.media.audio.headers` 覆盖端点或请求头。 - 输出遵循与其他提供商相同的音频规则(大小限制、超时、转录文本注入)。 + 输出遵循与其他提供商相同的音频规则(大小上限、超时、 + 转录文本注入)。 ## 相关内容 - + 音频、图像和视频处理流水线概览。 - 包含媒体工具设置在内的完整配置参考。 + 包括媒体工具设置在内的完整配置参考。 - 常见问题和调试步骤。 + 常见问题与调试步骤。 关于 OpenClaw 设置的常见问题。 diff --git a/docs/zh-CN/providers/index.md b/docs/zh-CN/providers/index.md index f0e7f29c6..256cc37bf 100644 --- a/docs/zh-CN/providers/index.md +++ b/docs/zh-CN/providers/index.md @@ -5,23 +5,24 @@ read_when: summary: OpenClaw 支持的模型提供商(LLM) title: 提供商目录 x-i18n: - generated_at: "2026-04-23T05:40:53Z" + generated_at: "2026-04-23T06:41:52Z" model: gpt-5.4 provider: openai - source_hash: 5a62f8af86fa23f248163d1a23929c628f5bcc757366d0fdb12157f995f8024d + source_hash: 2b038f095480fc2cd4f7eb75500d9d8eb7b03fa90614e122744939e0ddc6996d source_path: providers/index.md workflow: 15 --- # 模型提供商 -OpenClaw 可以使用许多 LLM 提供商。选择一个提供商,完成身份验证,然后将默认模型设置为 `provider/model`。 +OpenClaw 可以使用许多 LLM 提供商。选择一个提供商,完成认证,然后将 +默认模型设置为 `provider/model`。 -在找聊天渠道文档(WhatsApp/Telegram/Discord/Slack/Mattermost(plugin)/等)吗?请参阅 [Channels](/zh-CN/channels)。 +在找聊天渠道文档(WhatsApp/Telegram/Discord/Slack/Mattermost(插件)/ 等)?请参见 [Channels](/zh-CN/channels)。 ## 快速开始 -1. 使用提供商完成身份验证(通常通过 `openclaw onboard`)。 +1. 使用提供商完成认证(通常通过 `openclaw onboard`)。 2. 设置默认模型: ```json5 @@ -46,10 +47,10 @@ OpenClaw 可以使用许多 LLM 提供商。选择一个提供商,完成身份 - [fal](/zh-CN/providers/fal) - [Fireworks](/zh-CN/providers/fireworks) - [GitHub Copilot](/zh-CN/providers/github-copilot) -- [GLM 模型](/zh-CN/providers/glm) +- [GLM models](/zh-CN/providers/glm) - [Google(Gemini)](/zh-CN/providers/google) - [Groq(LPU 推理)](/zh-CN/providers/groq) -- [Hugging Face(Inference)](/zh-CN/providers/huggingface) +- [Hugging Face(推理)](/zh-CN/providers/huggingface) - [inferrs(本地模型)](/zh-CN/providers/inferrs) - [Kilocode](/zh-CN/providers/kilocode) - [LiteLLM(统一 Gateway 网关)](/zh-CN/providers/litellm) @@ -70,6 +71,7 @@ OpenClaw 可以使用许多 LLM 提供商。选择一个提供商,完成身份 - [SGLang(本地模型)](/zh-CN/providers/sglang) - [StepFun](/zh-CN/providers/stepfun) - [Synthetic](/zh-CN/providers/synthetic) +- [腾讯云(TokenHub)](/zh-CN/providers/tencent) - [Together AI](/zh-CN/providers/together) - [Venice(Venice AI,注重隐私)](/zh-CN/providers/venice) - [Vercel AI Gateway](/zh-CN/providers/vercel-ai-gateway) @@ -83,9 +85,9 @@ OpenClaw 可以使用许多 LLM 提供商。选择一个提供商,完成身份 ## 共享概览页面 - [其他内置变体](/zh-CN/providers/models#additional-bundled-provider-variants) - Anthropic Vertex、Copilot Proxy 和 Gemini CLI OAuth -- [图像生成](/zh-CN/tools/image-generation) - 共享的 `image_generate` 工具、提供商选择和故障切换 -- [音乐生成](/zh-CN/tools/music-generation) - 共享的 `music_generate` 工具、提供商选择和故障切换 -- [视频生成](/zh-CN/tools/video-generation) - 共享的 `video_generate` 工具、提供商选择和故障切换 +- [图像生成](/zh-CN/tools/image-generation) - 共享的 `image_generate` 工具、提供商选择和故障转移 +- [音乐生成](/zh-CN/tools/music-generation) - 共享的 `music_generate` 工具、提供商选择和故障转移 +- [视频生成](/zh-CN/tools/video-generation) - 共享的 `video_generate` 工具、提供商选择和故障转移 ## 转录提供商 @@ -97,6 +99,7 @@ OpenClaw 可以使用许多 LLM 提供商。选择一个提供商,完成身份 ## 社区工具 -- [Claude Max API Proxy](/zh-CN/providers/claude-max-api-proxy) - 用于 Claude 订阅凭证的社区代理(使用前请确认 Anthropic 的政策/条款) +- [Claude Max API Proxy](/zh-CN/providers/claude-max-api-proxy) - 用于 Claude 订阅凭证的社区代理(使用前请核实 Anthropic 的政策/条款) -如需查看完整的提供商目录(xAI、Groq、Mistral 等)和高级配置,请参阅 [模型提供商](/zh-CN/concepts/model-providers)。 +有关完整的提供商目录(xAI、Groq、Mistral 等)和高级配置, +请参见 [模型提供商](/zh-CN/concepts/model-providers)。 diff --git a/docs/zh-CN/providers/litellm.md b/docs/zh-CN/providers/litellm.md index b2d67e06e..df870073a 100644 --- a/docs/zh-CN/providers/litellm.md +++ b/docs/zh-CN/providers/litellm.md @@ -1,37 +1,38 @@ --- read_when: - - 你想通过 LiteLLM 代理来路由 OpenClaw + - 你希望通过 LiteLLM 代理来路由 OpenClaw - 你需要通过 LiteLLM 实现成本跟踪、日志记录或模型路由 summary: 通过 LiteLLM Proxy 运行 OpenClaw,以实现统一的模型访问和成本跟踪 title: LiteLLM x-i18n: - generated_at: "2026-04-12T10:19:22Z" + generated_at: "2026-04-23T06:42:11Z" model: gpt-5.4 provider: openai - source_hash: 766692eb83a1be83811d8e09a970697530ffdd4f3392247cfb2927fd590364a0 + source_hash: 6f9665b204126861a7dbbd426b26a624e60fd219a44756cec6a023df73848cef source_path: providers/litellm.md workflow: 15 --- # LiteLLM -[LiteLLM](https://litellm.ai) 是一个开源的 LLM 网关,为 100 多家模型提供商提供统一 API。通过 LiteLLM 路由 OpenClaw,你可以获得集中的成本跟踪、日志记录,以及在不更改 OpenClaw 配置的情况下切换后端的灵活性。 +[LiteLLM](https://litellm.ai) 是一个开源 LLM Gateway 网关,为 100 多个模型提供商提供统一 API。将 OpenClaw 通过 LiteLLM 路由后,你可以获得集中式成本跟踪、日志记录,以及在不更改 OpenClaw 配置的情况下切换后端的灵活性。 -**为什么将 LiteLLM 与 OpenClaw 搭配使用?** +**为什么要将 LiteLLM 与 OpenClaw 一起使用?** -- **成本跟踪** — 准确查看 OpenClaw 在所有模型上的支出 -- **模型路由** — 无需更改配置,即可在 Claude、GPT-4、Gemini、Bedrock 之间切换 -- **虚拟密钥** — 为 OpenClaw 创建带有支出限制的密钥 -- **日志记录** — 用于调试的完整请求/响应日志 -- **故障切换** — 如果你的主要提供商不可用,可自动切换 - +- **成本跟踪** — 精确查看 OpenClaw 在所有模型上的花费 +- **模型路由** — 无需改动配置即可在 Claude、GPT-4、Gemini、Bedrock 之间切换 +- **虚拟密钥** — 为 OpenClaw 创建带有消费限制的密钥 +- **日志记录** — 提供完整的请求/响应日志,便于调试 +- **故障转移** — 当主提供商不可用时自动切换 + + ## 快速开始 - **最适合:** 以最快方式完成可用的 LiteLLM 设置。 + **最适合:** 以最快路径获得可用的 LiteLLM 设置。 @@ -53,14 +54,14 @@ x-i18n: litellm --model claude-opus-4-6 ``` - + ```bash export LITELLM_API_KEY="your-litellm-key" openclaw ``` - 就这些。OpenClaw 现在会通过 LiteLLM 进行路由。 + 就这样。OpenClaw 现在会通过 LiteLLM 进行路由。 @@ -118,7 +119,7 @@ export LITELLM_API_KEY="sk-litellm-key" - 为 OpenClaw 创建一个带有支出限制的专用密钥: + 为 OpenClaw 创建一个带消费限制的专用密钥: ```bash curl -X POST "http://localhost:4000/key/generate" \ @@ -131,12 +132,12 @@ export LITELLM_API_KEY="sk-litellm-key" }' ``` - 使用生成的密钥作为 `LITELLM_API_KEY`。 + 将生成的密钥用作 `LITELLM_API_KEY`。 - LiteLLM 可以将模型请求路由到不同后端。在你的 LiteLLM `config.yaml` 中进行配置: + LiteLLM 可以将模型请求路由到不同后端。在你的 LiteLLM `config.yaml` 中配置: ```yaml model_list: @@ -151,12 +152,12 @@ export LITELLM_API_KEY="sk-litellm-key" api_key: os.environ/OPENAI_API_KEY ``` - OpenClaw 会继续请求 `claude-opus-4-6`——LiteLLM 会负责路由。 + OpenClaw 会继续请求 `claude-opus-4-6` —— 路由由 LiteLLM 负责处理。 - 查看 LiteLLM 的仪表板或 API: + 检查 LiteLLM 的仪表板或 API: ```bash # Key info @@ -172,17 +173,17 @@ export LITELLM_API_KEY="sk-litellm-key" - LiteLLM 默认运行在 `http://localhost:4000` - - OpenClaw 通过 LiteLLM 的代理式、与 OpenAI 兼容的 `/v1` + - OpenClaw 通过 LiteLLM 的代理式、兼容 OpenAI 的 `/v1` 端点进行连接 - - 通过 LiteLLM 时,不会应用原生仅限 OpenAI 的请求整形: - 没有 `service_tier`、没有 Responses `store`、没有提示词缓存提示,也没有 - OpenAI 推理兼容负载整形 - - 在自定义 LiteLLM base URLs 上,不会注入隐藏的 OpenClaw 归因标头(`originator`、`version`、`User-Agent`) + - 原生仅限 OpenAI 的请求整形不会通过 LiteLLM 生效: + 不支持 `service_tier`、不支持 Responses `store`、不支持 prompt-cache 提示,也不支持 + OpenAI reasoning 兼容负载整形 + - 在自定义 LiteLLM base URL 上,不会注入隐藏的 OpenClaw 归因请求头(`originator`、`version`、`User-Agent`) -有关通用提供商配置和故障切换行为,请参阅 [模型提供商](/zh-CN/concepts/model-providers)。 +有关通用提供商配置和故障转移行为,请参见 [模型提供商](/zh-CN/concepts/model-providers)。 ## 相关内容 @@ -192,7 +193,7 @@ export LITELLM_API_KEY="sk-litellm-key" LiteLLM 官方文档和 API 参考。 - 所有提供商、模型引用和故障切换行为概览。 + 所有提供商、模型引用和故障转移行为的概览。 完整配置参考。 diff --git a/docs/zh-CN/providers/lmstudio.md b/docs/zh-CN/providers/lmstudio.md index cccf9d6ab..33a1f91a1 100644 --- a/docs/zh-CN/providers/lmstudio.md +++ b/docs/zh-CN/providers/lmstudio.md @@ -1,21 +1,21 @@ --- read_when: - - 你想通过 LM Studio 使用开源模型运行 OpenClaw。 - - 你想设置并配置 LM Studio。 + - 你希望通过 LM Studio 使用开源模型运行 OpenClaw + - 你希望设置并配置 LM Studio summary: 使用 LM Studio 运行 OpenClaw title: LM Studio x-i18n: - generated_at: "2026-04-13T07:24:19Z" + generated_at: "2026-04-23T06:42:19Z" model: gpt-5.4 provider: openai - source_hash: 11264584e8277260d4215feb7c751329ce04f59e9228da1c58e147c21cd9ac2c + source_hash: 733527e95041da04562c0ee5d9486750d8355a255624a6d5735954de34429a5c source_path: providers/lmstudio.md workflow: 15 --- # LM Studio -LM Studio 是一款友好且功能强大的应用,可让你在自己的硬件上运行开放权重模型。它支持运行 llama.cpp(GGUF)或 MLX 模型(Apple Silicon)。提供 GUI 安装包,也提供无头守护进程(`llmster`)。有关产品和设置文档,请参阅 [lmstudio.ai](https://lmstudio.ai/)。 +LM Studio 是一个对用户友好但功能强大的应用,可让你在自己的硬件上运行开放权重模型。它支持运行 llama.cpp(GGUF)或 MLX 模型(Apple Silicon)。既提供 GUI 安装包,也提供无头守护进程(`llmster`)。有关产品和设置文档,请参见 [lmstudio.ai](https://lmstudio.ai/)。 ## 快速开始 @@ -27,7 +27,7 @@ curl -fsSL https://lmstudio.ai/install.sh | bash 2. 启动服务器 -请确保你要么启动桌面应用,要么使用以下命令运行守护进程: +请确保你已启动桌面应用,或使用以下命令运行守护进程: ```bash lms daemon up @@ -37,9 +37,9 @@ lms daemon up lms server start --port 1234 ``` -如果你使用的是应用,请确保已启用 JIT,以获得流畅体验。了解更多信息,请参阅 [LM Studio JIT and TTL guide](https://lmstudio.ai/docs/developer/core/ttl-and-auto-evict)。 +如果你使用的是应用,请确保已启用 JIT,以获得更流畅的体验。了解更多信息,请参见 [LM Studio JIT and TTL guide](https://lmstudio.ai/docs/developer/core/ttl-and-auto-evict)。 -3. OpenClaw 需要一个 LM Studio token 值。设置 `LM_API_TOKEN`: +3. OpenClaw 需要一个 LM Studio token 值。请设置 `LM_API_TOKEN`: ```bash export LM_API_TOKEN="your-lm-studio-api-token" @@ -51,7 +51,7 @@ export LM_API_TOKEN="your-lm-studio-api-token" export LM_API_TOKEN="placeholder-key" ``` -有关 LM Studio 身份验证设置的详细信息,请参阅 [LM Studio Authentication](https://lmstudio.ai/docs/developer/core/authentication)。 +有关 LM Studio 身份验证设置详情,请参见 [LM Studio Authentication](https://lmstudio.ai/docs/developer/core/authentication)。 4. 运行新手引导并选择 `LM Studio`: @@ -59,7 +59,7 @@ export LM_API_TOKEN="placeholder-key" openclaw onboard ``` -5. 在新手引导中,使用 `Default model` 提示来选择你的 LM Studio 模型。 +5. 在新手引导中,使用 `Default model` 提示选择你的 LM Studio 模型。 你也可以稍后设置或更改它: @@ -67,11 +67,12 @@ openclaw onboard openclaw models set lmstudio/qwen/qwen3.5-9b ``` -LM Studio 模型键采用 `author/model-name` 格式(例如 `qwen/qwen3.5-9b`)。OpenClaw 模型引用会在前面加上提供商名称:`lmstudio/qwen/qwen3.5-9b`。你可以通过运行 `curl http://localhost:1234/api/v1/models` 并查看 `key` 字段来找到某个模型的准确键名。 +LM Studio 模型键采用 `author/model-name` 格式(例如 `qwen/qwen3.5-9b`)。OpenClaw +模型引用会在前面加上提供商名称:`lmstudio/qwen/qwen3.5-9b`。你可以通过运行 `curl http://localhost:1234/api/v1/models` 并查看 `key` 字段来找到模型的准确键名。 ## 非交互式新手引导 -当你想以脚本方式完成设置时(CI、配置、远程引导),请使用非交互式新手引导: +当你想要以脚本方式完成设置时(CI、预配、远程引导),请使用非交互式新手引导: ```bash openclaw onboard \ @@ -80,7 +81,7 @@ openclaw onboard \ --auth-choice lmstudio ``` -或者使用 API key 指定 base URL 或模型: +或者使用 API 密钥指定基础 URL 或模型: ```bash openclaw onboard \ @@ -92,20 +93,35 @@ openclaw onboard \ --custom-model-id qwen/qwen3.5-9b ``` -`--custom-model-id` 接收 LM Studio 返回的模型键(例如 `qwen/qwen3.5-9b`),不包含 `lmstudio/` 提供商前缀。 +`--custom-model-id` 接收 LM Studio 返回的模型键(例如 `qwen/qwen3.5-9b`),不包含 +`lmstudio/` 提供商前缀。 -非交互式新手引导需要 `--lmstudio-api-key`(或环境中的 `LM_API_TOKEN`)。 -对于未启用身份验证的 LM Studio 服务器,任意非空 token 值都可以使用。 +非交互式新手引导需要 `--lmstudio-api-key`(或环境变量中的 `LM_API_TOKEN`)。 +对于不启用身份验证的 LM Studio 服务器,任意非空 token 值都可用。 -`--custom-api-key` 仍然保留以兼容旧用法,但对于 LM Studio,优先使用 `--lmstudio-api-key`。 +出于兼容性考虑,`--custom-api-key` 仍受支持,但对于 LM Studio,优先使用 `--lmstudio-api-key`。 这会写入 `models.providers.lmstudio`,将默认模型设置为 `lmstudio/`,并写入 `lmstudio:default` 身份验证配置文件。 -交互式设置可以提示输入一个可选的首选加载上下文长度,并将其应用到保存到配置中的已发现 LM Studio 模型。 +交互式设置还可以提示输入可选的首选加载上下文长度,并将其应用到保存到配置中的已发现 LM Studio 模型。 ## 配置 +### 流式使用量兼容性 + +OpenClaw 将 LM Studio 标记为与流式使用量兼容,因此在流式补全时,token 统计不再退化为未知或过期总数。当 LM Studio 不输出 OpenAI 形状的 `usage` 对象时,OpenClaw 还会从 llama.cpp 风格的 `timings.prompt_n` / `timings.predicted_n` 元数据中恢复 token 计数。 + +适用相同行为的其他 OpenAI 兼容本地后端: + +- vLLM +- SGLang +- llama.cpp +- LocalAI +- Jan +- TabbyAPI +- text-generation-webui + ### 显式配置 ```json5 @@ -137,14 +153,14 @@ openclaw onboard \ ### 未检测到 LM Studio -请确保 LM Studio 正在运行,并且你已设置 `LM_API_TOKEN`(对于未启用身份验证的服务器,任意非空 token 值都可以使用): +请确保 LM Studio 正在运行,并且你已设置 `LM_API_TOKEN`(对于不启用身份验证的服务器,任意非空 token 值都可用): ```bash # 通过桌面应用启动,或以无头方式启动: lms server start --port 1234 ``` -验证 API 可访问: +验证 API 是否可访问: ```bash curl http://localhost:1234/api/v1/models @@ -152,12 +168,12 @@ curl http://localhost:1234/api/v1/models ### 身份验证错误(HTTP 401) -如果设置过程中报告 HTTP 401,请检查你的 API key: +如果设置过程中报告 HTTP 401,请验证你的 API 密钥: -- 检查 `LM_API_TOKEN` 是否与 LM Studio 中配置的 key 匹配。 -- 有关 LM Studio 身份验证设置的详细信息,请参阅 [LM Studio Authentication](https://lmstudio.ai/docs/developer/core/authentication)。 -- 如果你的服务器不需要身份验证,请为 `LM_API_TOKEN` 使用任意非空 token 值。 +- 检查 `LM_API_TOKEN` 是否与 LM Studio 中配置的密钥一致。 +- 有关 LM Studio 身份验证设置详情,请参见 [LM Studio Authentication](https://lmstudio.ai/docs/developer/core/authentication)。 +- 如果你的服务器不要求身份验证,请为 `LM_API_TOKEN` 使用任意非空 token 值。 ### 即时模型加载 -LM Studio 支持即时(JIT)模型加载,即模型会在第一次请求时加载。请确保已启用此功能,以避免出现“Model not loaded”错误。 +LM Studio 支持即时(JIT)模型加载,即模型会在第一次请求时加载。请确保你已启用此功能,以避免出现“Model not loaded”错误。 diff --git a/docs/zh-CN/providers/mistral.md b/docs/zh-CN/providers/mistral.md index fbb99a0a2..2b9b68f87 100644 --- a/docs/zh-CN/providers/mistral.md +++ b/docs/zh-CN/providers/mistral.md @@ -1,26 +1,26 @@ --- read_when: - 你想在 OpenClaw 中使用 Mistral 模型 - - 你想为 Voice Call 使用 Voxtral 实时转录功能 - - 你需要 Mistral API 密钥新手引导和模型参考信息 -summary: 使用 Mistral 模型和 Voxtral 转录功能与 OpenClaw 配合使用 + - 你想为 Voice Call 使用 Voxtral 实时转录 + - 你需要 Mistral API 密钥新手引导和模型参考 +summary: 在 OpenClaw 中使用 Mistral 模型和 Voxtral 转录 title: Mistral x-i18n: - generated_at: "2026-04-23T02:13:15Z" + generated_at: "2026-04-23T06:42:22Z" model: gpt-5.4 provider: openai - source_hash: 8aec3c47fee12588b28ea2b652b89f0ff136399d25ca47174d7cb6e7b5d5d97f + source_hash: cbf2f8926a1e8c877a12ea395e96622ff3b337ffa1368277c03abbfb881b18cf source_path: providers/mistral.md workflow: 15 --- # Mistral -OpenClaw 支持 Mistral,用于文本/图像模型路由(`mistral/...`)以及在媒体理解中通过 Voxtral 进行音频转录。 +OpenClaw 同时支持将 Mistral 用于文本/图像模型路由(`mistral/...`)以及通过 Voxtral 在媒体理解中进行音频转录。 Mistral 也可用于记忆嵌入(`memorySearch.provider = "mistral"`)。 - 提供商:`mistral` -- 凭证:`MISTRAL_API_KEY` +- 认证:`MISTRAL_API_KEY` - API:Mistral Chat Completions(`https://api.mistral.ai/v1`) ## 入门指南 @@ -60,19 +60,19 @@ Mistral 也可用于记忆嵌入(`memorySearch.provider = "mistral"`)。 OpenClaw 当前内置了以下 Mistral 目录: -| 模型引用 | 输入 | 上下文 | 最大输出 | 说明 | +| 模型引用 | 输入 | 上下文 | 最大输出 | 说明 | | -------------------------------- | ----------- | ------- | ---------- | ---------------------------------------------------------------- | -| `mistral/mistral-large-latest` | text, image | 262,144 | 16,384 | 默认模型 | -| `mistral/mistral-medium-2508` | text, image | 262,144 | 8,192 | Mistral Medium 3.1 | -| `mistral/mistral-small-latest` | text, image | 128,000 | 16,384 | Mistral Small 4;可通过 API `reasoning_effort` 调整推理强度 | -| `mistral/pixtral-large-latest` | text, image | 128,000 | 32,768 | Pixtral | -| `mistral/codestral-latest` | text | 256,000 | 4,096 | 编码 | -| `mistral/devstral-medium-latest` | text | 262,144 | 32,768 | Devstral 2 | -| `mistral/magistral-small` | text | 128,000 | 40,000 | 启用推理 | +| `mistral/mistral-large-latest` | text, image | 262,144 | 16,384 | 默认模型 | +| `mistral/mistral-medium-2508` | text, image | 262,144 | 8,192 | Mistral Medium 3.1 | +| `mistral/mistral-small-latest` | text, image | 128,000 | 16,384 | Mistral Small 4;可通过 API `reasoning_effort` 调整推理强度 | +| `mistral/pixtral-large-latest` | text, image | 128,000 | 32,768 | Pixtral | +| `mistral/codestral-latest` | text | 256,000 | 4,096 | 编码 | +| `mistral/devstral-medium-latest` | text | 262,144 | 32,768 | Devstral 2 | +| `mistral/magistral-small` | text | 128,000 | 40,000 | 启用推理 | ## 音频转录(Voxtral) -通过媒体理解流水线使用 Voxtral 进行批量音频转录。 +通过媒体理解管线使用 Voxtral 进行批量音频转录。 ```json5 { @@ -95,13 +95,13 @@ OpenClaw 当前内置了以下 Mistral 目录: 内置的 `mistral` 插件会将 Voxtral Realtime 注册为 Voice Call 流式 STT 提供商。 -| 设置 | 配置路径 | 默认值 | +| 设置 | 配置路径 | 默认值 | | ------------ | ---------------------------------------------------------------------- | --------------------------------------- | -| API 密钥 | `plugins.entries.voice-call.config.streaming.providers.mistral.apiKey` | 回退到 `MISTRAL_API_KEY` | -| 模型 | `...mistral.model` | `voxtral-mini-transcribe-realtime-2602` | -| 编码 | `...mistral.encoding` | `pcm_mulaw` | -| 采样率 | `...mistral.sampleRate` | `8000` | -| 目标延迟 | `...mistral.targetStreamingDelayMs` | `800` | +| API 密钥 | `plugins.entries.voice-call.config.streaming.providers.mistral.apiKey` | 回退到 `MISTRAL_API_KEY` | +| 模型 | `...mistral.model` | `voxtral-mini-transcribe-realtime-2602` | +| 编码 | `...mistral.encoding` | `pcm_mulaw` | +| 采样率 | `...mistral.sampleRate` | `8000` | +| 目标延迟 | `...mistral.targetStreamingDelayMs` | `800` | ```json5 { @@ -127,24 +127,24 @@ OpenClaw 当前内置了以下 Mistral 目录: ``` -OpenClaw 默认将 Mistral 实时 STT 设置为 `pcm_mulaw` 和 8 kHz,这样 Voice Call 就能直接转发 Twilio 媒体帧。仅当你的上游流已经是原始 PCM 时,才使用 `encoding: "pcm_s16le"` 和匹配的 `sampleRate`。 +OpenClaw 默认将 Mistral 实时 STT 设置为 8 kHz 的 `pcm_mulaw`,这样 Voice Call 就可以直接转发 Twilio 媒体帧。只有在你的上游流已经是原始 PCM 时,才使用 `encoding: "pcm_s16le"` 和匹配的 `sampleRate`。 ## 高级配置 - `mistral/mistral-small-latest` 映射到 Mistral Small 4,并通过 `reasoning_effort` 支持在 Chat Completions API 上进行[可调推理](https://docs.mistral.ai/capabilities/reasoning/adjustable)(`none` 会尽量减少输出中的额外思考;`high` 会在最终答案前展示完整的思考轨迹)。 + `mistral/mistral-small-latest` 对应 Mistral Small 4,并支持通过 Chat Completions API 的 `reasoning_effort` 使用[可调推理](https://docs.mistral.ai/capabilities/reasoning/adjustable)(`none` 会尽量减少输出中的额外思考;`high` 会在最终答案前展示完整的思考轨迹)。 - OpenClaw 会将会话 **thinking** 级别映射到 Mistral 的 API: + OpenClaw 会将会话的 **thinking** 级别映射到 Mistral 的 API: - | OpenClaw thinking 级别 | Mistral `reasoning_effort` | - | ---------------------------------------------- | -------------------------- | - | **off** / **minimal** | `none` | - | **low** / **medium** / **high** / **xhigh** / **adaptive** / **max** | `high` | + | OpenClaw thinking 级别 | Mistral `reasoning_effort` | + | ------------------------------------------------ | -------------------------- | + | **off** / **minimal** | `none` | + | **low** / **medium** / **high** / **xhigh** / **adaptive** / **max** | `high` | - 其他内置 Mistral 目录模型不会使用这个参数。当你想要使用 Mistral 原生的推理优先行为时,请继续使用 `magistral-*` 模型。 + 其他内置 Mistral 目录模型不使用此参数。如果你希望使用 Mistral 原生的以推理优先为主的行为,请继续使用 `magistral-*` 模型。 @@ -160,8 +160,8 @@ OpenClaw 默认将 Mistral 实时 STT 设置为 `pcm_mulaw` 和 8 kHz,这样 V - - - Mistral 凭证使用 `MISTRAL_API_KEY`。 + + - Mistral 认证使用 `MISTRAL_API_KEY`。 - 提供商基础 URL 默认为 `https://api.mistral.ai/v1`。 - 新手引导默认模型为 `mistral/mistral-large-latest`。 - Z.AI 使用你的 API 密钥进行 Bearer 认证。 @@ -172,9 +172,9 @@ OpenClaw 默认将 Mistral 实时 STT 设置为 `pcm_mulaw` 和 8 kHz,这样 V - 选择提供商、模型引用和故障切换行为。 + 选择提供商、模型引用和故障转移行为。 - + 音频转录设置和提供商选择。 diff --git a/docs/zh-CN/providers/moonshot.md b/docs/zh-CN/providers/moonshot.md index 5c6af51b5..2d349cd6d 100644 --- a/docs/zh-CN/providers/moonshot.md +++ b/docs/zh-CN/providers/moonshot.md @@ -1,25 +1,25 @@ --- read_when: - - 你想要设置 Moonshot K2(Moonshot Open Platform)与 Kimi Coding 的对比配置 - - 你需要了解单独的端点、密钥和模型引用 - - 你想要适用于任一提供商的可复制粘贴配置 -summary: 配置 Moonshot K2 与 Kimi Coding(使用单独的提供商 + 密钥) + - 你想设置 Moonshot K2(Moonshot Open Platform)与 Kimi Coding + - 你需要了解独立的端点、密钥和模型引用 + - 你想要适用于任一提供商的可复制 / 粘贴配置 +summary: 配置 Moonshot K2 与 Kimi Coding(独立的提供商 + 密钥) title: Moonshot AI x-i18n: - generated_at: "2026-04-21T02:12:32Z" + generated_at: "2026-04-23T06:42:20Z" model: gpt-5.4 provider: openai - source_hash: 5a04b0c45d55dbf8d56a04a1811f0850b800842ea501b212d44b53ff0680b5a2 + source_hash: d9a726df279bfc0351b8ab224e682b5c1e6e360440659e33e8568a94c351df51 source_path: providers/moonshot.md workflow: 15 --- # Moonshot AI(Kimi) -Moonshot 通过与 OpenAI 兼容的端点提供 Kimi API。请配置该提供商,并将默认模型设置为 `moonshot/kimi-k2.6`,或者使用 `kimi/kimi-code` 作为 Kimi Coding。 +Moonshot 提供带有 OpenAI 兼容端点的 Kimi API。配置该提供商并将默认模型设置为 `moonshot/kimi-k2.6`,或使用 `kimi/kimi-code` 来启用 Kimi Coding。 -Moonshot 和 Kimi Coding 是**单独的提供商**。密钥不能互换,端点不同,模型引用也不同(`moonshot/...` 与 `kimi/...`)。 +Moonshot 和 Kimi Coding 是**独立的提供商**。密钥不能互换,端点不同,模型引用也不同(`moonshot/...` vs `kimi/...`)。 ## 内置模型目录 @@ -28,19 +28,19 @@ Moonshot 和 Kimi Coding 是**单独的提供商**。密钥不能互换,端点 | Model ref | 名称 | 推理 | 输入 | 上下文 | 最大输出 | | --------------------------------- | ---------------------- | ---- | ----------- | ------ | -------- | -| `moonshot/kimi-k2.6` | Kimi K2.6 | 否 | text, image | 262,144 | 262,144 | -| `moonshot/kimi-k2.5` | Kimi K2.5 | 否 | text, image | 262,144 | 262,144 | -| `moonshot/kimi-k2-thinking` | Kimi K2 Thinking | 是 | text | 262,144 | 262,144 | -| `moonshot/kimi-k2-thinking-turbo` | Kimi K2 Thinking Turbo | 是 | text | 262,144 | 262,144 | -| `moonshot/kimi-k2-turbo` | Kimi K2 Turbo | 否 | text | 256,000 | 16,384 | +| `moonshot/kimi-k2.6` | Kimi K2.6 | 否 | text, image | 262,144 | 262,144 | +| `moonshot/kimi-k2.5` | Kimi K2.5 | 否 | text, image | 262,144 | 262,144 | +| `moonshot/kimi-k2-thinking` | Kimi K2 Thinking | 是 | text | 262,144 | 262,144 | +| `moonshot/kimi-k2-thinking-turbo` | Kimi K2 Thinking Turbo | 是 | text | 262,144 | 262,144 | +| `moonshot/kimi-k2-turbo` | Kimi K2 Turbo | 否 | text | 256,000 | 16,384 | [//]: # "moonshot-kimi-k2-ids:end" -当前由 Moonshot 托管的 K2 模型,其内置成本估算使用 Moonshot 公布的按量付费价格:Kimi K2.6 为 $0.16/MTok 缓存命中、$0.95/MTok 输入、$4.00/MTok 输出;Kimi K2.5 为 $0.10/MTok 缓存命中、$0.60/MTok 输入、$3.00/MTok 输出。其他旧版目录条目会保留零成本占位值,除非你在配置中覆盖它们。 +当前由 Moonshot 托管的 K2 模型,其内置成本估算使用 Moonshot 公布的按量计费价格:Kimi K2.6 为 $0.16/MTok 缓存命中、$0.95/MTok 输入、$4.00/MTok 输出;Kimi K2.5 为 $0.10/MTok 缓存命中、$0.60/MTok 输入、$3.00/MTok 输出。其他旧目录条目会保留零成本占位值,除非你在配置中覆盖它们。 ## 入门指南 -选择你的提供商并按步骤完成设置。 +选择你的提供商,并按步骤完成设置。 @@ -48,17 +48,17 @@ Moonshot 和 Kimi Coding 是**单独的提供商**。密钥不能互换,端点 - | 鉴权选项 | 端点 | 区域 | - | ---------------------- | ---------------------------- | ---- | - | `moonshot-api-key` | `https://api.moonshot.ai/v1` | 国际 | - | `moonshot-api-key-cn` | `https://api.moonshot.cn/v1` | 中国 | + | 认证选项 | 端点 | 区域 | + | -------------------- | ------------------------------ | ---- | + | `moonshot-api-key` | `https://api.moonshot.ai/v1` | 国际 | + | `moonshot-api-key-cn` | `https://api.moonshot.cn/v1` | 中国 | ```bash openclaw onboard --auth-choice moonshot-api-key ``` - 或者,如果使用中国端点: + 或者使用中国端点: ```bash openclaw onboard --auth-choice moonshot-api-key-cn @@ -75,13 +75,13 @@ Moonshot 和 Kimi Coding 是**单独的提供商**。密钥不能互换,端点 } ``` - + ```bash openclaw models list --provider moonshot ``` - 当你想在不影响正常会话的情况下验证模型访问和成本跟踪时,请使用独立的状态目录: + 当你想验证模型访问和成本跟踪,而不影响正常会话时,请使用隔离的状态目录: ```bash OPENCLAW_CONFIG_PATH=/tmp/openclaw-kimi/openclaw.json \ @@ -93,8 +93,8 @@ Moonshot 和 Kimi Coding 是**单独的提供商**。密钥不能互换,端点 --json ``` - JSON 响应应显示 `provider: "moonshot"` 和 - `model: "kimi-k2.6"`。当 Moonshot 返回用量元数据时,助手转录条目会在 `usage.cost` 下存储标准化后的 token 用量以及预估成本。 + JSON 响应应报告 `provider: "moonshot"` 和 + `model: "kimi-k2.6"`。当 Moonshot 返回使用量元数据时,助手转录条目会在 `usage.cost` 下存储标准化后的 token 使用量和估算成本。 @@ -182,10 +182,10 @@ Moonshot 和 Kimi Coding 是**单独的提供商**。密钥不能互换,端点 - **最适合:** 通过 Kimi Coding 端点执行以代码为重点的任务。 + **最适合:** 通过 Kimi Coding 端点处理以代码为重点的任务。 - Kimi Coding 使用与 Moonshot 不同的 API 密钥和提供商前缀(`kimi/...`),而 Moonshot 使用 `moonshot/...`。旧版模型引用 `kimi/k2p5` 仍然作为兼容性 id 被接受。 + Kimi Coding 使用与 Moonshot 不同的 API key 和提供商前缀(`kimi/...` 而非 `moonshot/...`)。旧模型引用 `kimi/k2p5` 仍作为兼容 id 被接受。 @@ -205,7 +205,7 @@ Moonshot 和 Kimi Coding 是**单独的提供商**。密钥不能互换,端点 } ``` - + ```bash openclaw models list --provider kimi ``` @@ -233,7 +233,7 @@ Moonshot 和 Kimi Coding 是**单独的提供商**。密钥不能互换,端点 ## Kimi web 搜索 -OpenClaw 还内置了 **Kimi** 作为 `web_search` 提供商,其底层由 Moonshot web 搜索支持。 +OpenClaw 还内置了 **Kimi** 作为 `web_search` 提供商,由 Moonshot web 搜索提供支持。 @@ -241,17 +241,17 @@ OpenClaw 还内置了 **Kimi** 作为 `web_search` 提供商,其底层由 Moon openclaw configure --section web ``` - 在 web 搜索部分选择 **Kimi**,以存储 + 在 web 搜索部分选择 **Kimi**,以保存 `plugins.entries.moonshot.config.webSearch.*`。 交互式设置会提示以下内容: - | 设置 | 选项 | + | 设置 | 选项 | | ------------------- | -------------------------------------------------------------------- | - | API 区域 | `https://api.moonshot.ai/v1`(国际)或 `https://api.moonshot.cn/v1`(中国) | - | Web 搜索模型 | 默认为 `kimi-k2.6` | + | API 区域 | `https://api.moonshot.ai/v1`(国际)或 `https://api.moonshot.cn/v1`(中国) | + | Web 搜索模型 | 默认为 `kimi-k2.6` | @@ -283,7 +283,7 @@ OpenClaw 还内置了 **Kimi** 作为 `web_search` 提供商,其底层由 Moon } ``` -## 高级 +## 高级设置 @@ -292,7 +292,7 @@ OpenClaw 还内置了 **Kimi** 作为 `web_search` 提供商,其底层由 Moon - `thinking: { type: "enabled" }` - `thinking: { type: "disabled" }` - 通过 `agents.defaults.models..params` 为每个模型配置: + 通过 `agents.defaults.models..params` 按模型配置: ```json5 { @@ -312,16 +312,16 @@ OpenClaw 还内置了 **Kimi** 作为 `web_search` 提供商,其底层由 Moon OpenClaw 还会为 Moonshot 映射运行时 `/think` 级别: - | `/think` 级别 | Moonshot 行为 | + | `/think` 级别 | Moonshot 行为 | | -------------------- | -------------------------- | | `/think off` | `thinking.type=disabled` | | 任何非 off 级别 | `thinking.type=enabled` | - 当启用 Moonshot thinking 时,`tool_choice` 必须为 `auto` 或 `none`。为保证兼容性,OpenClaw 会将不兼容的 `tool_choice` 值标准化为 `auto`。 + 启用 Moonshot thinking 时,`tool_choice` 必须是 `auto` 或 `none`。OpenClaw 会将不兼容的 `tool_choice` 值标准化为 `auto` 以确保兼容性。 - Kimi K2.6 还接受一个可选的 `thinking.keep` 字段,用于控制 `reasoning_content` 在多轮对话中的保留方式。将其设置为 `"all"` 可在多轮中保留完整推理;省略它(或保持为 `null`)则使用服务器默认策略。OpenClaw 只会为 `moonshot/kimi-k2.6` 转发 `thinking.keep`,并会从其他模型中移除该字段。 + Kimi K2.6 还接受一个可选的 `thinking.keep` 字段,用于控制 `reasoning_content` 在多轮对话中的保留方式。将其设置为 `"all"` 可在多轮中保留完整推理;省略它(或保留为 `null`)则使用服务器默认策略。OpenClaw 仅会为 `moonshot/kimi-k2.6` 转发 `thinking.keep`,并会从其他模型中移除它。 ```json5 { @@ -341,25 +341,45 @@ OpenClaw 还内置了 **Kimi** 作为 `web_search` 提供商,其底层由 Moon - - 原生 Moonshot 端点(`https://api.moonshot.ai/v1` 和 - `https://api.moonshot.cn/v1`)在共享的 `openai-completions` 传输协议上声明支持流式用量兼容性。OpenClaw 会基于端点能力进行判断,因此,指向相同原生 Moonshot 主机的兼容自定义提供商 id 也会继承相同的流式用量行为。 + + Moonshot Kimi 在 OpenAI 兼容传输上提供原生 `tool_call` id,其格式类似 `functions.:`。OpenClaw 不再为 Moonshot 严格清洗这些 id,因此当服务层根据原始工具定义匹配被改写的 id 时,经由 Kimi K2.6 的多轮智能体流程可以在 2 - 3 轮工具调用之后继续正常工作。 - 使用内置的 K2.6 定价时,包含输入、输出和缓存读取 token 的流式用量,也会被转换为本地预估美元成本,用于 `/status`、`/usage full`、`/usage cost` 以及基于转录的会话计费统计。 + 如果某个自定义 OpenAI 兼容提供商需要之前的行为,请在提供商条目上设置 `sanitizeToolCallIds: true`。该标志位于共享的 `openai-compatible` replay 系列上;Moonshot 默认接入的是选择退出行为。 + + ```json5 + { + models: { + providers: { + "my-kimi-proxy": { + api: "openai-completions", + sanitizeToolCallIds: true, + }, + }, + }, + } + ``` - - | 提供商 | 模型引用前缀 | 端点 | 鉴权环境变量 | - | ------------- | ---------------- | ----------------------------- | -------------------- | - | Moonshot | `moonshot/` | `https://api.moonshot.ai/v1` | `MOONSHOT_API_KEY` | - | Moonshot CN | `moonshot/` | `https://api.moonshot.cn/v1` | `MOONSHOT_API_KEY` | - | Kimi Coding | `kimi/` | Kimi Coding 端点 | `KIMI_API_KEY` | - | Web 搜索 | N/A | 与 Moonshot API 区域相同 | `KIMI_API_KEY` or `MOONSHOT_API_KEY` | + + 原生 Moonshot 端点(`https://api.moonshot.ai/v1` 和 + `https://api.moonshot.cn/v1`)会在共享的 `openai-completions` 传输上声明流式使用量兼容性。OpenClaw 基于端点能力来判断,因此指向相同原生 Moonshot 主机的兼容自定义提供商 id 也会继承相同的流式使用量行为。 - - Kimi web 搜索使用 `KIMI_API_KEY` 或 `MOONSHOT_API_KEY`,默认端点为 `https://api.moonshot.ai/v1`,默认模型为 `kimi-k2.6`。 - - 如有需要,可在 `models.providers` 中覆盖定价和上下文元数据。 - - 如果 Moonshot 为某个模型发布了不同的上下文限制,请相应调整 `contextWindow`。 + 配合内置的 K2.6 定价,包含输入、输出和缓存读取 token 的流式使用量,也会被转换为本地估算的 USD 成本,用于 `/status`、`/usage full`、`/usage cost` 和基于转录的会话计费。 + + + + + | Provider | 模型引用前缀 | 端点 | 认证环境变量 | + | ---------- | ---------------- | ----------------------------- | ------------------- | + | Moonshot | `moonshot/` | `https://api.moonshot.ai/v1` | `MOONSHOT_API_KEY` | + | Moonshot CN | `moonshot/` | `https://api.moonshot.cn/v1` | `MOONSHOT_API_KEY` | + | Kimi Coding | `kimi/` | Kimi Coding 端点 | `KIMI_API_KEY` | + | Web 搜索 | N/A | 与 Moonshot API 区域相同 | `KIMI_API_KEY` 或 `MOONSHOT_API_KEY` | + + - Kimi web 搜索使用 `KIMI_API_KEY` 或 `MOONSHOT_API_KEY`,并默认使用 `https://api.moonshot.ai/v1` 和模型 `kimi-k2.6`。 + - 如有需要,请在 `models.providers` 中覆盖定价和上下文元数据。 + - 如果 Moonshot 为某个模型公布了不同的上下文限制,请相应调整 `contextWindow`。 @@ -370,13 +390,13 @@ OpenClaw 还内置了 **Kimi** 作为 `web_search` 提供商,其底层由 Moon 选择提供商、模型引用和故障切换行为。 - - 配置 web 搜索提供商,包括 Kimi。 + + 配置包括 Kimi 在内的 web 搜索提供商。 提供商、模型和插件的完整配置 schema。 - Moonshot API 密钥管理与文档。 + Moonshot API key 管理和文档。 diff --git a/docs/zh-CN/providers/openai.md b/docs/zh-CN/providers/openai.md index b7005eff8..2049143a0 100644 --- a/docs/zh-CN/providers/openai.md +++ b/docs/zh-CN/providers/openai.md @@ -3,52 +3,52 @@ read_when: - 你想在 OpenClaw 中使用 OpenAI 模型 - 你想使用 Codex 订阅认证,而不是 API 密钥 - 你需要更严格的 GPT-5 智能体执行行为 -summary: 在 OpenClaw 中使用 OpenAI 的 API 密钥或 Codex 订阅 +summary: 在 OpenClaw 中通过 API 密钥或 Codex 订阅使用 OpenAI title: OpenAI x-i18n: - generated_at: "2026-04-23T01:23:55Z" + generated_at: "2026-04-23T06:42:29Z" model: gpt-5.4 provider: openai - source_hash: 775a937680731ff09181dd58d2be1ca1a751c9193ac299ba6657266490a6a9b7 + source_hash: c3d847e53c2faee5363071dfdcb1f4150b64577674161e000844f579482198d1 source_path: providers/openai.md workflow: 15 --- # OpenAI - OpenAI 提供用于 GPT 模型的开发者 API。OpenClaw 支持两种认证方式: + OpenAI 提供 GPT 模型的开发者 API。OpenClaw 支持两种认证路径: - - **API 密钥** — 通过按量计费直接访问 OpenAI Platform(`openai/*` 模型) - - **Codex 订阅** — 通过 ChatGPT/Codex 登录并使用订阅访问(`openai-codex/*` 模型) + - **API 密钥** —— 通过基于用量计费的 OpenAI Platform 直接访问(`openai/*` 模型) + - **Codex 订阅** —— 通过 ChatGPT/Codex 登录并使用订阅访问(`openai-codex/*` 模型) OpenAI 明确支持在 OpenClaw 这类外部工具和工作流中使用订阅 OAuth。 ## OpenClaw 功能覆盖范围 - | OpenAI 能力 | OpenClaw 表面 | 状态 | + | OpenAI 能力 | OpenClaw 接口 | 状态 | | ------------------------- | ----------------------------------------- | ------------------------------------------------------ | - | 聊天 / Responses | `openai/` 模型提供商 | 是 | + | Chat / Responses | `openai/` 模型提供商 | 是 | | Codex 订阅模型 | `openai-codex/` 模型提供商 | 是 | - | 服务端 Web 搜索 | 原生 OpenAI Responses 工具 | 是,启用 Web 搜索且未固定提供商时 | + | 服务端 Web 搜索 | 原生 OpenAI Responses 工具 | 是,在启用 Web 搜索且未固定提供商时 | | 图像 | `image_generate` | 是 | | 视频 | `video_generate` | 是 | | 文本转语音 | `messages.tts.provider: "openai"` / `tts` | 是 | | 批量语音转文本 | `tools.media.audio` / 媒体理解 | 是 | | 流式语音转文本 | Voice Call `streaming.provider: "openai"` | 是 | | 实时语音 | Voice Call `realtime.provider: "openai"` | 是 | - | Embeddings | memory embedding 提供商 | 是 | + | Embeddings | 记忆嵌入提供商 | 是 | ## 入门指南 - 选择你偏好的认证方式,并按照设置步骤操作。 + 选择你偏好的认证方式,并按步骤进行设置。 - **最适合:** 直接访问 API 和按量计费。 + **最适合:** 直接 API 访问和基于用量的计费。 - 在 [OpenAI Platform 控制台](https://platform.openai.com/api-keys) 中创建或复制一个 API 密钥。 + 在 [OpenAI Platform dashboard](https://platform.openai.com/api-keys) 创建或复制一个 API 密钥。 ```bash @@ -70,7 +70,7 @@ x-i18n: ### 路由摘要 - | Model ref | Route | Auth | + | 模型引用 | 路由 | 认证 | |-----------|-------|------| | `openai/gpt-5.4` | 直接 OpenAI Platform API | `OPENAI_API_KEY` | | `openai/gpt-5.4-pro` | 直接 OpenAI Platform API | `OPENAI_API_KEY` | @@ -89,7 +89,7 @@ x-i18n: ``` - OpenClaw **不会** 在直接 API 路径上公开 `openai/gpt-5.3-codex-spark`。实时 OpenAI API 请求会拒绝该模型。Spark 仅限 Codex。 + OpenClaw **不会**在直接 API 路径上暴露 `openai/gpt-5.3-codex-spark`。实时 OpenAI API 请求会拒绝该模型。Spark 仅限 Codex。 @@ -108,6 +108,12 @@ x-i18n: ```bash openclaw models auth login --provider openai-codex ``` + + 对于无头环境或不适合回调的环境,可添加 `--device-code`,通过 ChatGPT 设备码流程登录,而不是使用 localhost 浏览器回调: + + ```bash + openclaw models auth login --provider openai-codex --device-code + ``` ```bash @@ -123,13 +129,13 @@ x-i18n: ### 路由摘要 - | Model ref | Route | Auth | + | 模型引用 | 路由 | 认证 | |-----------|-------|------| | `openai-codex/gpt-5.4` | ChatGPT/Codex OAuth | Codex 登录 | - | `openai-codex/gpt-5.3-codex-spark` | ChatGPT/Codex OAuth | Codex 登录(取决于授权资格) | + | `openai-codex/gpt-5.3-codex-spark` | ChatGPT/Codex OAuth | Codex 登录(取决于 entitlement) | - 此路由与 `openai/gpt-5.4` 有意分离。直接 Platform 访问请使用带 API 密钥的 `openai/*`,Codex 订阅访问请使用 `openai-codex/*`。 + 此路由有意与 `openai/gpt-5.4` 分开。若要直接访问 Platform,请将 API 密钥用于 `openai/*`;若要使用 Codex 订阅访问,请使用 `openai-codex/*`。 ### 配置示例 @@ -140,9 +146,9 @@ x-i18n: } ``` - - 如果新手引导复用了现有的 Codex CLI 登录,这些凭证仍由 Codex CLI 管理。过期后,OpenClaw 会先重新读取外部 Codex 来源,再把刷新的凭证写回 Codex 存储。 - + + 新手引导不再从 `~/.codex` 导入 OAuth 材料。请使用浏览器 OAuth(默认)或上面的设备码流程登录 —— OpenClaw 会在它自己的智能体认证存储中管理生成的凭证。 + ### 上下文窗口上限 @@ -153,7 +159,7 @@ x-i18n: - 原生 `contextWindow`:`1050000` - 默认运行时 `contextTokens` 上限:`272000` - 较小的默认上限在实践中通常具有更好的延迟和质量表现。你可以用 `contextTokens` 覆盖它: + 实践中,较小的默认上限通常具有更好的延迟和质量特性。你可以通过 `contextTokens` 覆盖它: ```json5 { @@ -168,7 +174,7 @@ x-i18n: ``` - 使用 `contextWindow` 来声明原生模型元数据。使用 `contextTokens` 来限制运行时上下文预算。 + 使用 `contextWindow` 声明模型的原生元数据。使用 `contextTokens` 限制运行时上下文预算。 @@ -197,15 +203,16 @@ x-i18n: ``` -有关共享工具参数、提供商选择和故障转移行为,请参见 [图像生成](/zh-CN/tools/image-generation)。 +有关共享工具参数、提供商选择和故障转移行为,请参见 [Image Generation](/zh-CN/tools/image-generation)。 -`gpt-image-2` 是 OpenAI 文生图生成和图像编辑的默认模型。`gpt-image-1` 仍可作为显式模型覆盖使用,但新的 OpenAI 图像工作流应使用 `openai/gpt-image-2`。 +`gpt-image-2` 是 OpenAI 文生图和图像编辑的默认模型。`gpt-image-1` +仍可作为显式模型覆盖使用,但新的 OpenAI 图像工作流应使用 `openai/gpt-image-2`。 生成: ``` -/tool image_generate model=openai/gpt-image-2 prompt="为 macOS 上的 OpenClaw 制作一张精致的发布海报" size=3840x2160 count=1 +/tool image_generate model=openai/gpt-image-2 prompt="为 OpenClaw 在 macOS 上发布制作一张精致的启动海报" size=3840x2160 count=1 ``` 编辑: @@ -221,10 +228,10 @@ x-i18n: | 能力 | 值 | | ---------------- | --------------------------------------------------------------------------------- | | 默认模型 | `openai/sora-2` | -| 模式 | 文生视频、图生视频、单视频编辑 | +| 模式 | 文本生成视频、图像生成视频、单视频编辑 | | 参考输入 | 1 张图像或 1 个视频 | | 尺寸覆盖 | 支持 | -| 其他覆盖 | `aspectRatio`、`resolution`、`audio`、`watermark` 会被忽略,并产生工具警告 | +| 其他覆盖 | `aspectRatio`、`resolution`、`audio`、`watermark` 会被忽略,并给出工具警告 | ```json5 { @@ -237,20 +244,20 @@ x-i18n: ``` -有关共享工具参数、提供商选择和故障转移行为,请参见 [视频生成](/zh-CN/tools/video-generation)。 +有关共享工具参数、提供商选择和故障转移行为,请参见 [Video Generation](/zh-CN/tools/video-generation)。 -## GPT-5 提示词扩展 +## GPT-5 提示词贡献 -OpenClaw 会为跨提供商的 GPT-5 系列运行添加共享的 GPT-5 提示词扩展。它按模型 id 应用,因此 `openai/gpt-5.4`、`openai-codex/gpt-5.4`、`openrouter/openai/gpt-5.4`、`opencode/gpt-5.4` 以及其他兼容的 GPT-5 引用都会接收相同的叠加层。较旧的 GPT-4.x 模型不会应用该扩展。 +OpenClaw 会为跨提供商的 GPT-5 系列运行添加一个共享的 GPT-5 提示词贡献。它按模型 ID 应用,因此 `openai/gpt-5.4`、`openai-codex/gpt-5.4`、`openrouter/openai/gpt-5.4`、`opencode/gpt-5.4` 以及其他兼容的 GPT-5 引用都会获得同一层覆盖。较早的 GPT-4.x 模型则不会。 -内置的原生 Codex harness 提供商(`codex/*`)通过 Codex app-server 开发者指令使用相同的 GPT-5 行为和心跳叠加层,因此 `codex/gpt-5.x` 会话会保持相同的后续跟进行为和主动心跳指引,即使 Codex 拥有 harness 提示词的其余部分也是如此。 +内置的原生 Codex harness 提供商(`codex/*`)通过 Codex app-server 开发者指令使用相同的 GPT-5 行为和心跳覆盖,因此 `codex/gpt-5.x` 会话即使其余 harness 提示词由 Codex 自行管理,也会保持相同的执行跟进和主动心跳指导。 -GPT-5 扩展添加了一个带标签的行为契约,用于规定角色持续性、执行安全、工具纪律、输出形态、完成检查和验证。特定渠道的回复和静默消息行为仍保留在共享的 OpenClaw 系统提示词和出站传递策略中。对于匹配的模型,GPT-5 指引始终启用。友好的交互风格层是独立的,并且可配置。 +GPT-5 贡献为人设持久性、执行安全、工具纪律、输出形状、完成检查和验证添加了一个带标签的行为契约。渠道特定的回复和静默消息行为仍保留在共享的 OpenClaw 系统提示词和出站投递策略中。对于匹配的模型,GPT-5 指导始终启用。友好交互风格层是单独的,并且可配置。 | 值 | 效果 | | ---------------------- | ------------------------------------------- | -| `"friendly"`(默认) | 启用友好的交互风格层 | +| `"friendly"`(默认) | 启用友好交互风格层 | | `"on"` | `"friendly"` 的别名 | | `"off"` | 仅禁用友好风格层 | @@ -276,18 +283,18 @@ GPT-5 扩展添加了一个带标签的行为契约,用于规定角色持续 -运行时值不区分大小写,因此 `"Off"` 和 `"off"` 都会禁用友好风格层。 +这些值在运行时不区分大小写,因此 `"Off"` 和 `"off"` 都会禁用友好风格层。 -当共享设置 `agents.defaults.promptOverlays.gpt5.personality` 未设置时,仍会读取旧版 `plugins.entries.openai.config.personality` 作为兼容性回退。 +当未设置共享的 `agents.defaults.promptOverlays.gpt5.personality` 时,仍会读取旧版 `plugins.entries.openai.config.personality` 作为兼容性回退。 -## 语音和语音识别 +## 语音与音频 - 内置的 `openai` 插件为 `messages.tts` 表面注册语音合成功能。 + 内置的 `openai` 插件为 `messages.tts` 接口注册了语音合成功能。 | 设置 | 配置路径 | 默认值 | |---------|------------|---------| @@ -295,7 +302,7 @@ GPT-5 扩展添加了一个带标签的行为契约,用于规定角色持续 | 语音 | `messages.tts.providers.openai.voice` | `coral` | | 速度 | `messages.tts.providers.openai.speed` | (未设置) | | 指令 | `messages.tts.providers.openai.instructions` | (未设置,仅 `gpt-4o-mini-tts`) | - | 格式 | `messages.tts.providers.openai.responseFormat` | 语音便笺为 `opus`,文件为 `mp3` | + | 格式 | `messages.tts.providers.openai.responseFormat` | 语音便笺用 `opus`,文件用 `mp3` | | API 密钥 | `messages.tts.providers.openai.apiKey` | 回退到 `OPENAI_API_KEY` | | Base URL | `messages.tts.providers.openai.baseUrl` | `https://api.openai.com/v1` | @@ -314,22 +321,23 @@ GPT-5 扩展添加了一个带标签的行为契约,用于规定角色持续 ``` - 设置 `OPENAI_TTS_BASE_URL` 可以覆盖 TTS Base URL,而不会影响聊天 API 端点。 + 设置 `OPENAI_TTS_BASE_URL` 可覆盖 TTS 的 Base URL,而不会影响聊天 API 端点。 - 内置的 `openai` 插件通过 OpenClaw 的媒体理解转录表面注册批量语音转文本功能。 + 内置的 `openai` 插件通过 + OpenClaw 的媒体理解转录接口注册批量语音转文本。 - 默认模型:`gpt-4o-transcribe` - 端点:OpenAI REST `/v1/audio/transcriptions` - 输入路径:multipart 音频文件上传 - - 在 OpenClaw 中,只要入站音频转录使用 - `tools.media.audio`,就受支持,包括 Discord 语音频道片段和渠道 + - 在 OpenClaw 中,凡是入站音频转录使用 + `tools.media.audio` 的地方都支持,包括 Discord 语音频道片段和渠道 音频附件 - 要为入站音频转录强制使用 OpenAI: + 要强制对入站音频转录使用 OpenAI: ```json5 { @@ -349,13 +357,13 @@ GPT-5 扩展添加了一个带标签的行为契约,用于规定角色持续 } ``` - 当共享音频媒体配置或每次调用的转录请求提供了语言和提示词提示时, - 这些内容会转发给 OpenAI。 + 当共享音频媒体配置或按次转录请求提供了语言和提示词提示时, + 它们会被转发给 OpenAI。 - 内置的 `openai` 插件为 Voice Call 插件注册实时转录功能。 + 内置的 `openai` 插件为 Voice Call 插件注册了实时转录。 | 设置 | 配置路径 | 默认值 | |---------|------------|---------| @@ -367,13 +375,13 @@ GPT-5 扩展添加了一个带标签的行为契约,用于规定角色持续 | API 密钥 | `...openai.apiKey` | 回退到 `OPENAI_API_KEY` | - 使用到 `wss://api.openai.com/v1/realtime` 的 WebSocket 连接,并采用 G.711 u-law(`g711_ulaw` / `audio/pcmu`)音频。此流式提供商用于 Voice Call 的实时转录路径;Discord 语音当前仍会录制短片段,并改用批量 `tools.media.audio` 转录路径。 + 使用到 `wss://api.openai.com/v1/realtime` 的 WebSocket 连接,并采用 G.711 u-law(`g711_ulaw` / `audio/pcmu`)音频。这个流式提供商用于 Voice Call 的实时转录路径;Discord 语音目前仍会录制短片段,并改用批量 `tools.media.audio` 转录路径。 - 内置的 `openai` 插件为 Voice Call 插件注册实时语音功能。 + 内置的 `openai` 插件为 Voice Call 插件注册了实时语音。 | 设置 | 配置路径 | 默认值 | |---------|------------|---------| @@ -395,19 +403,19 @@ GPT-5 扩展添加了一个带标签的行为契约,用于规定角色持续 - OpenClaw 对 `openai/*` 和 `openai-codex/*` 都优先使用 WebSocket,并在失败时回退到 SSE(`"auto"`)。 + 对于 `openai/*` 和 `openai-codex/*`,OpenClaw 默认都采用 WebSocket 优先、SSE 回退(`"auto"`)。 在 `"auto"` 模式下,OpenClaw 会: - - 在回退到 SSE 之前,重试一次早期 WebSocket 失败 - - 失败后,将 WebSocket 标记为降级约 60 秒,并在冷却期间使用 SSE + - 在回退到 SSE 之前重试一次早期 WebSocket 失败 + - 在失败后,将 WebSocket 标记为约 60 秒的降级状态,并在冷却期间使用 SSE - 为重试和重连附加稳定的会话与轮次标识头 - - 在不同传输变体之间规范化用量计数器(`input_tokens` / `prompt_tokens`) + - 在不同传输变体间规范化用量计数器(`input_tokens` / `prompt_tokens`) | 值 | 行为 | |-------|----------| - | `"auto"`(默认) | 优先 WebSocket,失败时回退到 SSE | - | `"sse"` | 仅强制使用 SSE | - | `"websocket"` | 仅强制使用 WebSocket | + | `"auto"`(默认) | WebSocket 优先,SSE 回退 | + | `"sse"` | 强制仅使用 SSE | + | `"websocket"` | 强制仅使用 WebSocket | ```json5 { @@ -424,13 +432,13 @@ GPT-5 扩展添加了一个带标签的行为契约,用于规定角色持续 ``` 相关 OpenAI 文档: - - [使用 WebSocket 的 Realtime API](https://platform.openai.com/docs/guides/realtime-websocket) - - [流式 API 响应(SSE)](https://platform.openai.com/docs/guides/streaming-responses) + - [Realtime API with WebSocket](https://platform.openai.com/docs/guides/realtime-websocket) + - [Streaming API responses (SSE)](https://platform.openai.com/docs/guides/streaming-responses) - OpenClaw 默认对 `openai/*` 启用 WebSocket 预热,以降低首次轮次延迟。 + 为了降低首轮延迟,OpenClaw 默认对 `openai/*` 启用 WebSocket 预热。 ```json5 // 禁用预热 @@ -449,13 +457,15 @@ GPT-5 扩展添加了一个带标签的行为契约,用于规定角色持续 + + - OpenClaw 为 `openai/*` 和 `openai-codex/*` 提供共享的快速模式开关: + OpenClaw 为 `openai/*` 和 `openai-codex/*` 提供统一的快速模式开关: - **聊天/UI:** `/fast status|on|off` - **配置:** `agents.defaults.models["/"].params.fastMode` - 启用后,OpenClaw 会将快速模式映射到 OpenAI 优先处理(`service_tier = "priority"`)。现有的 `service_tier` 值会被保留,并且快速模式不会重写 `reasoning` 或 `text.verbosity`。 + 启用后,OpenClaw 会将快速模式映射到 OpenAI 的优先处理(`service_tier = "priority"`)。现有的 `service_tier` 值会被保留,快速模式不会改写 `reasoning` 或 `text.verbosity`。 ```json5 { @@ -471,13 +481,13 @@ GPT-5 扩展添加了一个带标签的行为契约,用于规定角色持续 ``` - 会话覆盖优先于配置。在 Sessions UI 中清除会话覆盖后,该会话会恢复为配置的默认值。 + 会话级覆盖优先于配置。在 Sessions UI 中清除会话覆盖后,该会话会恢复为配置中的默认值。 - OpenAI 的 API 通过 `service_tier` 提供优先处理。你可以在 OpenClaw 中按模型设置它: + OpenAI 的 API 通过 `service_tier` 暴露优先处理能力。你可以在 OpenClaw 中按模型设置: ```json5 { @@ -495,7 +505,7 @@ GPT-5 扩展添加了一个带标签的行为契约,用于规定角色持续 支持的值:`auto`、`default`、`flex`、`priority`。 - `serviceTier` 仅会转发到原生 OpenAI 端点(`api.openai.com`)和原生 Codex 端点(`chatgpt.com/backend-api`)。如果你通过代理路由任一提供商,OpenClaw 会保持 `service_tier` 不变。 + `serviceTier` 只会被转发到原生 OpenAI 端点(`api.openai.com`)和原生 Codex 端点(`chatgpt.com/backend-api`)。如果你通过代理路由任一提供商,OpenClaw 会保持 `service_tier` 不变。 @@ -503,13 +513,13 @@ GPT-5 扩展添加了一个带标签的行为契约,用于规定角色持续 对于直接 OpenAI Responses 模型(`api.openai.com` 上的 `openai/*`),OpenClaw 会自动启用服务端压缩: - - 强制设置 `store: true`(除非模型兼容性将 `supportsStore: false`) + - 强制 `store: true`(除非模型兼容性设置了 `supportsStore: false`) - 注入 `context_management: [{ type: "compaction", compact_threshold: ... }]` - - 默认 `compact_threshold`:`contextWindow` 的 70%(不可用时为 `80000`) + - 默认 `compact_threshold`:`contextWindow` 的 70%(如果不可用则为 `80000`) - 对 Azure OpenAI Responses 这类兼容端点很有用: + 这对兼容端点(如 Azure OpenAI Responses)很有用: ```json5 { @@ -561,7 +571,7 @@ GPT-5 扩展添加了一个带标签的行为契约,用于规定角色持续 - `responsesServerCompaction` 仅控制 `context_management` 注入。除非兼容性将 `supportsStore: false`,直接 OpenAI Responses 模型仍会强制使用 `store: true`。 + `responsesServerCompaction` 只控制 `context_management` 的注入。直接 OpenAI Responses 模型仍会强制 `store: true`,除非兼容性设置了 `supportsStore: false`。 @@ -580,26 +590,26 @@ GPT-5 扩展添加了一个带标签的行为契约,用于规定角色持续 ``` 使用 `strict-agentic` 时,OpenClaw 会: - - 当工具操作可用时,不再将仅有计划的轮次视为成功推进 - - 使用“立即行动”的引导重试该轮次 - - 对于较大工作自动启用 `update_plan` - - 如果模型持续只做计划而不行动,则显示明确的阻塞状态 + - 当工具操作可用时,不再将仅做计划的轮次视为成功推进 + - 通过“立即执行”的引导重试该轮次 + - 对实质性工作自动启用 `update_plan` + - 如果模型持续只规划不执行,则显式显示阻塞状态 - 仅限 OpenAI 和 Codex GPT-5 系列运行。其他提供商和较旧的模型系列保持默认行为。 + 仅适用于 OpenAI 和 Codex 的 GPT-5 系列运行。其他提供商和较旧的模型系列会保持默认行为。 - - OpenClaw 会区别对待直接 OpenAI、Codex 和 Azure OpenAI 端点,以及通用的 OpenAI-compatible `/v1` 代理: + + OpenClaw 会区别对待直接 OpenAI、Codex 和 Azure OpenAI 端点,以及通用的 OpenAI 兼容 `/v1` 代理: **原生路由**(`openai/*`、`openai-codex/*`、Azure OpenAI): - 仅对支持 OpenAI `none` effort 的模型保留 `reasoning: { effort: "none" }` - - 对于拒绝 `reasoning.effort: "none"` 的模型或代理,省略禁用的 reasoning + - 对拒绝 `reasoning.effort: "none"` 的模型或代理,省略禁用的 reasoning - 默认将工具 schema 设为严格模式 - - 仅在已验证的原生主机上附加隐藏归因头 - - 保留 OpenAI 专有的请求整形(`service_tier`、`store`、reasoning 兼容性、提示词缓存提示) + - 仅在已验证的原生宿主上附加隐藏归因头 + - 保留 OpenAI 专属的请求整形(`service_tier`、`store`、reasoning 兼容性、提示词缓存提示) **代理/兼容路由:** - 使用更宽松的兼容行为 diff --git a/docs/zh-CN/providers/qwen.md b/docs/zh-CN/providers/qwen.md index 49acb34c1..05b656c78 100644 --- a/docs/zh-CN/providers/qwen.md +++ b/docs/zh-CN/providers/qwen.md @@ -5,10 +5,10 @@ read_when: summary: 通过 OpenClaw 内置的 qwen 提供商使用 Qwen Cloud title: Qwen x-i18n: - generated_at: "2026-04-12T11:08:22Z" + generated_at: "2026-04-23T06:42:37Z" model: gpt-5.4 provider: openai - source_hash: 5247f851ef891645df6572d748ea15deeea47cd1d75858bc0d044a2930065106 + source_hash: 70726b64202d8167f7879320281bde86d69ffa4c40117a53352922eb65d66400 source_path: providers/qwen.md workflow: 15 --- @@ -17,37 +17,38 @@ x-i18n: -**Qwen OAuth 已被移除。** 之前使用 `portal.qwen.ai` 端点的免费层 OAuth 集成 +**Qwen OAuth 已移除。** 之前使用 `portal.qwen.ai` 端点的免费层 OAuth 集成 (`qwen-portal`)现已不可用。 背景信息请参见 [Issue #49557](https://github.com/openclaw/openclaw/issues/49557)。 -OpenClaw 现在将 Qwen 视为一等内置提供商,其规范 id -为 `qwen`。该内置提供商面向 Qwen Cloud / Alibaba DashScope 和 -Coding Plan 端点,并保留旧版 `modelstudio` id 作为兼容性别名。 +OpenClaw 现在将 Qwen 视为一级内置提供商,其规范 id +为 `qwen`。该内置提供商面向 Qwen Cloud / Alibaba DashScope 以及 +Coding Plan 端点,并保留旧版 `modelstudio` id 作为 +兼容性别名。 - 提供商:`qwen` - 首选环境变量:`QWEN_API_KEY` - 出于兼容性也接受:`MODELSTUDIO_API_KEY`、`DASHSCOPE_API_KEY` -- API 风格:与 OpenAI 兼容 +- API 风格:兼容 OpenAI -如果你想使用 `qwen3.6-plus`,建议优先选择**标准版(按量计费)**端点。 -Coding Plan 支持可能会落后于公开目录。 +如果你想使用 `qwen3.6-plus`,优先选择**标准版(按量付费)**端点。 +Coding Plan 支持可能会落后于公开模型目录。 ## 入门指南 -选择你的套餐类型并按照设置步骤操作。 +选择你的套餐类型,然后按照设置步骤进行。 - **最适合:** 通过 Qwen Coding Plan 获得基于订阅的访问。 + **最适合:** 通过 Qwen Coding Plan 使用订阅制访问。 - 在 [home.qwencloud.com/api-keys](https://home.qwencloud.com/api-keys) 创建或复制一个 API 密钥。 + 在 [home.qwencloud.com/api-keys](https://home.qwencloud.com/api-keys) 创建或复制 API 密钥。 对于**全球**端点: @@ -82,18 +83,18 @@ Coding Plan 支持可能会落后于公开目录。 旧版 `modelstudio-*` auth-choice id 和 `modelstudio/...` 模型引用仍然 - 可以作为兼容性别名继续使用,但新的设置流程应优先使用规范的 + 作为兼容性别名可用,但新的设置流程应优先使用规范的 `qwen-*` auth-choice id 和 `qwen/...` 模型引用。 - - **最适合:** 通过标准版 Model Studio 端点进行按量计费访问,包括像 `qwen3.6-plus` 这样在 Coding Plan 中可能不可用的模型。 + + **最适合:** 通过标准版 Model Studio 端点按量付费访问,包括 `qwen3.6-plus` 等可能在 Coding Plan 中不可用的模型。 - 在 [home.qwencloud.com/api-keys](https://home.qwencloud.com/api-keys) 创建或复制一个 API 密钥。 + 在 [home.qwencloud.com/api-keys](https://home.qwencloud.com/api-keys) 创建或复制 API 密钥。 对于**全球**端点: @@ -128,7 +129,7 @@ Coding Plan 支持可能会落后于公开目录。 旧版 `modelstudio-*` auth-choice id 和 `modelstudio/...` 模型引用仍然 - 可以作为兼容性别名继续使用,但新的设置流程应优先使用规范的 + 作为兼容性别名可用,但新的设置流程应优先使用规范的 `qwen-*` auth-choice id 和 `qwen/...` 模型引用。 @@ -139,14 +140,14 @@ Coding Plan 支持可能会落后于公开目录。 | 套餐 | 区域 | Auth choice | 端点 | | -------------------------- | ------ | -------------------------- | ------------------------------------------------ | -| 标准版(按量计费) | 中国 | `qwen-standard-api-key-cn` | `dashscope.aliyuncs.com/compatible-mode/v1` | -| 标准版(按量计费) | 全球 | `qwen-standard-api-key` | `dashscope-intl.aliyuncs.com/compatible-mode/v1` | +| 标准版(按量付费) | 中国 | `qwen-standard-api-key-cn` | `dashscope.aliyuncs.com/compatible-mode/v1` | +| 标准版(按量付费) | 全球 | `qwen-standard-api-key` | `dashscope-intl.aliyuncs.com/compatible-mode/v1` | | Coding Plan(订阅制) | 中国 | `qwen-api-key-cn` | `coding.dashscope.aliyuncs.com/v1` | | Coding Plan(订阅制) | 全球 | `qwen-api-key` | `coding-intl.dashscope.aliyuncs.com/v1` | -该提供商会根据你的 auth choice 自动选择端点。规范选择使用 `qwen-*` -系列;`modelstudio-*` 仅保留用于兼容性。 -你也可以在配置中通过自定义 `baseUrl` 进行覆盖。 +该提供商会根据你的 auth choice 自动选择端点。规范 +选项使用 `qwen-*` 系列;`modelstudio-*` 仅保留用于兼容。 +你也可以在配置中使用自定义 `baseUrl` 进行覆盖。 **管理密钥:** [home.qwencloud.com/api-keys](https://home.qwencloud.com/api-keys) | @@ -155,18 +156,18 @@ Coding Plan 支持可能会落后于公开目录。 ## 内置目录 -OpenClaw 当前内置了以下 Qwen 目录。已配置的目录会感知端点: -Coding Plan 配置会省略那些目前仅确认可在 -标准版端点上运行的模型。 +OpenClaw 当前内置以下 Qwen 目录。配置后的目录会感知端点类型: +Coding Plan 配置会省略那些已知仅在 +标准版端点上可用的模型。 | 模型引用 | 输入 | 上下文 | 说明 | | --------------------------- | ----------- | --------- | -------------------------------------------------- | | `qwen/qwen3.5-plus` | text, image | 1,000,000 | 默认模型 | -| `qwen/qwen3.6-plus` | text, image | 1,000,000 | 当你需要此模型时,建议优先使用标准版端点 | +| `qwen/qwen3.6-plus` | text, image | 1,000,000 | 需要此模型时优先使用标准版端点 | | `qwen/qwen3-max-2026-01-23` | text | 262,144 | Qwen Max 系列 | -| `qwen/qwen3-coder-next` | text | 262,144 | 编码 | -| `qwen/qwen3-coder-plus` | text | 1,000,000 | 编码 | -| `qwen/MiniMax-M2.5` | text | 1,000,000 | 已启用推理 | +| `qwen/qwen3-coder-next` | text | 262,144 | Coding | +| `qwen/qwen3-coder-plus` | text | 1,000,000 | Coding | +| `qwen/MiniMax-M2.5` | text | 1,000,000 | 已启用 reasoning | | `qwen/glm-5` | text | 202,752 | GLM | | `qwen/glm-4.7` | text | 202,752 | GLM | | `qwen/kimi-k2.5` | text, image | 262,144 | 通过 Alibaba 提供的 Moonshot AI | @@ -175,15 +176,15 @@ Coding Plan 配置会省略那些目前仅确认可在 即使某个模型出现在内置目录中,其可用性仍可能因端点和计费套餐而异。 -## 多模态附加能力 +## 多模态附加功能 -`qwen` 扩展还会在**标准版** -DashScope 端点(而非 Coding Plan 端点)上提供多模态能力: +`qwen` 插件还会在**标准版** +DashScope 端点上(而不是 Coding Plan 端点)公开多模态能力: - 通过 `qwen-vl-max-latest` 提供**视频理解** - 通过 `wan2.6-t2v`(默认)、`wan2.6-i2v`、`wan2.6-r2v`、`wan2.6-r2v-flash`、`wan2.7-r2v` 提供 **Wan 视频生成** -要将 Qwen 用作默认视频提供商: +要将 Qwen 设为默认视频提供商: ```json5 { @@ -196,85 +197,87 @@ DashScope 端点(而非 Coding Plan 端点)上提供多模态能力: ``` -有关共享工具参数、提供商选择和故障切换行为,请参见 [Video Generation](/zh-CN/tools/video-generation)。 +有关共享工具参数、提供商选择和故障转移行为,请参见 [视频生成](/zh-CN/tools/video-generation)。 ## 高级 - 内置的 Qwen 插件会在**标准版** DashScope 端点(而非 Coding Plan 端点)上为图像和视频注册媒体理解能力。 + 内置的 Qwen 插件会在**标准版** DashScope 端点上(而不是 Coding Plan 端点) + 为图像和视频注册媒体理解能力。 | 属性 | 值 | | ------------- | --------------------- | | 模型 | `qwen-vl-max-latest` | - | 支持的输入 | 图像、视频 | + | 支持的输入 | Images, video | - 媒体理解会根据已配置的 Qwen 凭证自动解析—— - 无需额外配置。请确保你使用的是支持媒体理解的标准版(按量计费) - 端点。 + 媒体理解会根据已配置的 Qwen 认证自动解析—— + 无需额外配置。请确保你使用的是标准版(按量付费) + 端点,以支持媒体理解。 - `qwen3.6-plus` 可在标准版(按量计费)Model Studio + `qwen3.6-plus` 可在标准版(按量付费)Model Studio 端点上使用: - 中国:`dashscope.aliyuncs.com/compatible-mode/v1` - 全球:`dashscope-intl.aliyuncs.com/compatible-mode/v1` - 如果 Coding Plan 端点对 `qwen3.6-plus` 返回“unsupported model”错误, - 请切换到标准版(按量计费),而不是继续使用 Coding Plan - 端点 / 密钥组合。 + 如果 Coding Plan 端点对 + `qwen3.6-plus` 返回“unsupported model”错误,请切换到标准版(按量付费),而不是继续使用 Coding Plan + 端点/密钥组合。 - `qwen` 扩展正在被定位为完整 Qwen - Cloud 能力面的厂商归属入口,而不仅仅是编码 / 文本模型。 + `qwen` 插件正在被定位为完整 Qwen + Cloud 能力面的厂商归属位置,而不仅仅是 coding/text 模型。 - - **文本 / 聊天模型:** 现已内置 - - **工具调用、结构化输出、思维链:** 继承自与 OpenAI 兼容的传输层 - - **图像生成:** 计划在提供商插件层支持 - - **图像 / 视频理解:** 现已在标准版端点内置 - - **语音 / 音频:** 计划在提供商插件层支持 - - **Memory 嵌入 / 重排序:** 计划通过嵌入适配器能力面支持 - - **视频生成:** 现已通过共享视频生成能力内置 + - **文本/聊天模型:** 当前已内置 + - **工具调用、结构化输出、thinking:** 继承自兼容 OpenAI 的传输层 + - **图像生成:** 计划在提供商插件层提供 + - **图像/视频理解:** 当前已在标准版端点内置 + - **语音/音频:** 计划在提供商插件层提供 + - **记忆 embeddings/reranking:** 计划通过 embedding 适配器层提供 + - **视频生成:** 当前已通过共享视频生成能力内置 - 对于视频生成,OpenClaw 会先将已配置的 Qwen 区域映射到匹配的 - DashScope AIGC 主机,然后再提交任务: + 对于视频生成,OpenClaw 会在提交任务前,将配置的 Qwen 区域映射到对应的 + DashScope AIGC 主机: - - 全球 / 国际版:`https://dashscope-intl.aliyuncs.com` + - 全球/国际版:`https://dashscope-intl.aliyuncs.com` - 中国:`https://dashscope.aliyuncs.com` 这意味着,普通的 `models.providers.qwen.baseUrl` 即使指向 - Coding Plan 或标准版 Qwen 主机之一, - 视频生成仍会使用正确的区域性 DashScope 视频端点。 + Coding Plan 或标准版 Qwen 主机,也仍然能让视频生成使用正确的 + 区域性 DashScope 视频端点。 - 当前内置 Qwen 视频生成限制: + 当前内置的 Qwen 视频生成限制: - 每个请求最多 **1** 个输出视频 - - 最多 **1** 张输入图片 + - 最多 **1** 张输入图像 - 最多 **4** 个输入视频 - 最长 **10 秒** 时长 - 支持 `size`、`aspectRatio`、`resolution`、`audio` 和 `watermark` - - 参考图片 / 视频模式目前要求使用**远程 http(s) URL**。本地 - 文件路径会被预先拒绝,因为 DashScope 视频端点不接受 - 为这些参考上传本地缓冲区。 + - 参考图像/视频模式当前要求使用**远程 http(s) URL**。本地 + 文件路径会被提前拒绝,因为 DashScope 视频端点不 + 接受为这些参考上传本地缓冲区。 - - 原生 Model Studio 端点会在共享 `openai-completions` 传输层上声明 - 流式使用兼容性。OpenClaw 现在基于端点能力来判断这一点,因此面向相同原生主机的 - DashScope 兼容自定义提供商 id 也会继承相同的流式使用行为, - 而不再要求必须使用内置 `qwen` 提供商 id。 + + 原生 Model Studio 端点在共享的 + `openai-completions` 传输上声明支持流式使用量兼容性。OpenClaw 现在会根据端点 + 能力进行判断,因此,指向同一原生主机的、兼容 DashScope 的自定义提供商 id + 也会继承相同的流式使用量行为,而不是 + 必须特定使用内置 `qwen` 提供商 id。 - 原生流式使用兼容性同时适用于 Coding Plan 主机和 - 标准版 DashScope 兼容主机: + 原生流式使用量兼容性同时适用于 Coding Plan 主机和 + 标准版兼容 DashScope 的主机: - `https://coding.dashscope.aliyuncs.com/v1` - `https://coding-intl.dashscope.aliyuncs.com/v1` @@ -287,14 +290,14 @@ DashScope 端点(而非 Coding Plan 端点)上提供多模态能力: 多模态能力面(视频理解和 Wan 视频生成)使用的是 **标准版** DashScope 端点,而不是 Coding Plan 端点: - - 全球 / 国际版标准 base URL:`https://dashscope-intl.aliyuncs.com/compatible-mode/v1` + - 全球/国际版标准 base URL:`https://dashscope-intl.aliyuncs.com/compatible-mode/v1` - 中国标准 base URL:`https://dashscope.aliyuncs.com/compatible-mode/v1` - 如果 Gateway 网关以守护进程(launchd/systemd)方式运行,请确保 `QWEN_API_KEY` - 对该进程可用(例如放在 `~/.openclaw/.env` 中,或通过 + 如果 Gateway 网关作为守护进程运行(launchd/systemd),请确保 `QWEN_API_KEY` 对该进程 + 可用(例如放在 `~/.openclaw/.env` 中,或通过 `env.shellEnv` 提供)。 @@ -303,7 +306,7 @@ DashScope 端点(而非 Coding Plan 端点)上提供多模态能力: - 选择提供商、模型引用和故障切换行为。 + 选择提供商、模型引用和故障转移行为。 共享视频工具参数和提供商选择。 @@ -312,6 +315,6 @@ DashScope 端点(而非 Coding Plan 端点)上提供多模态能力: 旧版 ModelStudio 提供商和迁移说明。 - 常规故障排除和常见问题。 + 通用故障排除和常见问题。 diff --git a/docs/zh-CN/providers/tencent.md b/docs/zh-CN/providers/tencent.md index 26c7f8351..9745adf96 100644 --- a/docs/zh-CN/providers/tencent.md +++ b/docs/zh-CN/providers/tencent.md @@ -1,21 +1,21 @@ --- read_when: - - 你想在 OpenClaw 中使用腾讯混元模型 + - 你希望在 OpenClaw 中使用腾讯混元模型 - 你需要设置 TokenHub API 密钥 -summary: 腾讯云 TokenHub 设置 +summary: 腾讯云(TokenHub)设置 title: 腾讯云(TokenHub) x-i18n: - generated_at: "2026-04-22T05:47:53Z" + generated_at: "2026-04-23T06:42:42Z" model: gpt-5.4 provider: openai - source_hash: 04da073973792c55dc0c2d287bfc51187bb2128bbbd5c4a483f850adeea50ab5 + source_hash: 90fce0d5957b261439cacd2b4df2362ed69511cb047af6a76ccaf54004806041 source_path: providers/tencent.md workflow: 15 --- # 腾讯云(TokenHub) -腾讯云提供商通过 TokenHub 端点(`tencent-tokenhub`)提供对腾讯混元模型的访问。 +腾讯云作为 **内置提供商插件** 随 OpenClaw 一起提供。它通过 TokenHub 端点(`tencent-tokenhub`)提供对腾讯混元模型的访问。 该提供商使用与 OpenAI 兼容的 API。 @@ -36,9 +36,9 @@ openclaw onboard --non-interactive \ --accept-risk ``` -## 提供商和端点 +## 提供商与端点 -| 提供商 | 端点 | 用例 | +| 提供商 | 端点 | 用途 | | ------------------ | ----------------------------- | ----------------------- | | `tencent-tokenhub` | `tokenhub.tencentmaas.com/v1` | 通过腾讯 TokenHub 使用混元 | @@ -46,19 +46,22 @@ openclaw onboard --non-interactive \ ### tencent-tokenhub -- **hy3-preview** — Hy3 预览版(256K 上下文、推理、默认) +- **hy3-preview** — 混元 3 预览版(256K 上下文、支持推理、默认) ## 说明 - TokenHub 模型引用使用 `tencent-tokenhub/`。 +- 该插件内置了分层的混元 3 定价元数据,因此无需手动覆盖定价即可填充成本估算。 - 如有需要,可在 `models.providers` 中覆盖定价和上下文元数据。 ## 环境说明 -如果 Gateway 网关 以守护进程方式运行(`launchd`/`systemd`),请确保 `TOKENHUB_API_KEY` 对该进程可用(例如,在 `~/.openclaw/.env` 中,或通过 `env.shellEnv`)。 +如果 Gateway 网关以守护进程方式运行(launchd/systemd),请确保 `TOKENHUB_API_KEY` +对该进程可用(例如放在 `~/.openclaw/.env` 中,或通过 +`env.shellEnv` 提供)。 ## 相关文档 - [OpenClaw 配置](/zh-CN/gateway/configuration) - [模型提供商](/zh-CN/concepts/model-providers) -- [腾讯 TokenHub](https://cloud.tencent.com/document/product/1823/130050) +- [Tencent TokenHub](https://cloud.tencent.com/document/product/1823/130050) diff --git a/docs/zh-CN/providers/volcengine.md b/docs/zh-CN/providers/volcengine.md index d1cdbe473..8ac215df3 100644 --- a/docs/zh-CN/providers/volcengine.md +++ b/docs/zh-CN/providers/volcengine.md @@ -2,26 +2,26 @@ read_when: - 你想在 OpenClaw 中使用火山引擎或 Doubao 模型 - 你需要设置 Volcengine API 密钥 -summary: 火山引擎设置(Doubao 模型,通用 + 编程端点) -title: 火山引擎(Doubao) +summary: 火山引擎设置(Doubao 模型、通用端点 + 编码端点) +title: Volcengine(Doubao) x-i18n: - generated_at: "2026-04-12T10:26:13Z" + generated_at: "2026-04-23T06:42:44Z" model: gpt-5.4 provider: openai - source_hash: a21f390da719f79c88c6d55a7d952d35c2ce5ff26d910c9f10020132cd7d2f4c + source_hash: 4d803e965699bedf06cc7ea4e902ffc92e4a168be012224e845820069fd67acc source_path: providers/volcengine.md workflow: 15 --- -# 火山引擎(Doubao) +# Volcengine(Doubao) -Volcengine 提供商可让你访问部署在火山引擎上的 Doubao 模型和第三方模型,并为通用工作负载和编程工作负载提供分别独立的端点。 +Volcengine 提供商可访问托管在火山引擎上的 Doubao 模型和第三方模型,并为通用工作负载和编码工作负载提供独立端点。 -| 详情 | 值 | +| 详情 | 值 | | --------- | --------------------------------------------------- | -| 提供商 | `volcengine`(通用)+ `volcengine-plan`(编程) | -| 认证 | `VOLCANO_ENGINE_API_KEY` | -| API | 与 OpenAI 兼容 | +| 提供商 | `volcengine`(通用)+ `volcengine-plan`(编码) | +| 认证 | `VOLCANO_ENGINE_API_KEY` | +| API | 兼容 OpenAI | ## 入门指南 @@ -33,7 +33,7 @@ Volcengine 提供商可让你访问部署在火山引擎上的 Doubao 模型和 openclaw onboard --auth-choice volcengine-api-key ``` - 这会通过一个 API 密钥同时注册通用提供商(`volcengine`)和编程提供商(`volcengine-plan`)。 + 这会通过一个 API 密钥同时注册通用提供商(`volcengine`)和编码提供商(`volcengine-plan`)。 @@ -47,7 +47,7 @@ Volcengine 提供商可让你访问部署在火山引擎上的 Doubao 模型和 } ``` - + ```bash openclaw models list --provider volcengine openclaw models list --provider volcengine-plan @@ -69,36 +69,36 @@ openclaw onboard --non-interactive \ ## 提供商和端点 -| 提供商 | 端点 | 使用场景 | -| ----------------- | ----------------------------------------- | ------------ | -| `volcengine` | `ark.cn-beijing.volces.com/api/v3` | 通用模型 | -| `volcengine-plan` | `ark.cn-beijing.volces.com/api/coding/v3` | 编程模型 | +| 提供商 | 端点 | 用途 | +| ----------------- | ----------------------------------------- | -------------- | +| `volcengine` | `ark.cn-beijing.volces.com/api/v3` | 通用模型 | +| `volcengine-plan` | `ark.cn-beijing.volces.com/api/coding/v3` | 编码模型 | -这两个提供商都通过同一个 API 密钥进行配置。设置时会自动同时注册两者。 +这两个提供商都通过同一个 API 密钥配置。设置时会自动同时注册。 ## 可用模型 - - | Model ref | 名称 | 输入 | 上下文 | - | -------------------------------------------- | ------------------------------- | ----------- | ------ | - | `volcengine/doubao-seed-1-8-251228` | Doubao Seed 1.8 | 文本、图像 | 256,000 | - | `volcengine/doubao-seed-code-preview-251028` | doubao-seed-code-preview-251028 | 文本、图像 | 256,000 | - | `volcengine/kimi-k2-5-260127` | Kimi K2.5 | 文本、图像 | 256,000 | - | `volcengine/glm-4-7-251222` | GLM 4.7 | 文本、图像 | 200,000 | - | `volcengine/deepseek-v3-2-251201` | DeepSeek V3.2 | 文本、图像 | 128,000 | + + | 模型引用 | 名称 | 输入 | 上下文 | + | -------------------------------------------- | ------------------------------- | ----------- | ------- | + | `volcengine/doubao-seed-1-8-251228` | Doubao Seed 1.8 | text, image | 256,000 | + | `volcengine/doubao-seed-code-preview-251028` | doubao-seed-code-preview-251028 | text, image | 256,000 | + | `volcengine/kimi-k2-5-260127` | Kimi K2.5 | text, image | 256,000 | + | `volcengine/glm-4-7-251222` | GLM 4.7 | text, image | 200,000 | + | `volcengine/deepseek-v3-2-251201` | DeepSeek V3.2 | text, image | 128,000 | - - | Model ref | 名称 | 输入 | 上下文 | - | ------------------------------------------------- | ------------------------ | ---- | ------ | - | `volcengine-plan/ark-code-latest` | Ark Coding Plan | 文本 | 256,000 | - | `volcengine-plan/doubao-seed-code` | Doubao Seed Code | 文本 | 256,000 | - | `volcengine-plan/glm-4.7` | GLM 4.7 Coding | 文本 | 200,000 | - | `volcengine-plan/kimi-k2-thinking` | Kimi K2 Thinking | 文本 | 256,000 | - | `volcengine-plan/kimi-k2.5` | Kimi K2.5 Coding | 文本 | 256,000 | - | `volcengine-plan/doubao-seed-code-preview-251028` | Doubao Seed Code Preview | 文本 | 256,000 | + + | 模型引用 | 名称 | 输入 | 上下文 | + | ------------------------------------------------- | ------------------------ | ----- | ------- | + | `volcengine-plan/ark-code-latest` | Ark Coding Plan | text | 256,000 | + | `volcengine-plan/doubao-seed-code` | Doubao Seed Code | text | 256,000 | + | `volcengine-plan/glm-4.7` | GLM 4.7 Coding | text | 200,000 | + | `volcengine-plan/kimi-k2-thinking` | Kimi K2 Thinking | text | 256,000 | + | `volcengine-plan/kimi-k2.5` | Kimi K2.5 Coding | text | 256,000 | + | `volcengine-plan/doubao-seed-code-preview-251028` | Doubao Seed Code Preview | text | 256,000 | @@ -107,13 +107,15 @@ openclaw onboard --non-interactive \ `openclaw onboard --auth-choice volcengine-api-key` 当前会将 - `volcengine-plan/ark-code-latest` 设为默认模型,同时也会注册通用的 `volcengine` 模型目录。 + `volcengine-plan/ark-code-latest` 设为默认模型,同时也会注册 + 通用 `volcengine` 目录。 - + 在新手引导/配置模型选择期间,Volcengine 认证选项会优先显示 - `volcengine/*` 和 `volcengine-plan/*` 条目。如果这些模型尚未加载, - OpenClaw 会回退到未筛选的模型目录,而不是显示一个空的按提供商范围筛选的选择器。 + `volcengine/*` 和 `volcengine-plan/*` 条目。如果这些模型尚未 + 加载,OpenClaw 会回退到未过滤的目录,而不是显示一个空的、 + 按提供商限定的选择器。 @@ -124,22 +126,23 @@ openclaw onboard --non-interactive \ -当 OpenClaw 作为后台服务运行时,你在交互式 shell 中设置的环境变量不会被自动继承。请参阅上面的守护进程说明。 +当 OpenClaw 作为后台服务运行时,你在交互式 shell 中设置的环境变量 +不会被自动继承。请参见上面的守护进程说明。 ## 相关内容 - 选择提供商、模型引用以及故障切换行为。 + 选择提供商、模型引用和故障转移行为。 - 关于智能体、模型和提供商的完整配置参考。 + 智能体、模型和提供商的完整配置参考。 常见问题和调试步骤。 - 关于 OpenClaw 设置的常见问题解答。 + 关于 OpenClaw 设置的常见问题。 diff --git a/docs/zh-CN/refactor/async-exec-duplicate-completion-investigation.md b/docs/zh-CN/refactor/async-exec-duplicate-completion-investigation.md index 909d177a1..fb7427580 100644 --- a/docs/zh-CN/refactor/async-exec-duplicate-completion-investigation.md +++ b/docs/zh-CN/refactor/async-exec-duplicate-completion-investigation.md @@ -1,132 +1,137 @@ --- +read_when: + - 调试重复的节点 exec 完成事件 + - 处理 heartbeat/system-event 去重 +summary: 重复 async exec 完成注入的调查说明 +title: Async Exec Duplicate Completion Investigation x-i18n: - generated_at: "2026-04-15T20:07:43Z" + generated_at: "2026-04-23T06:42:52Z" model: gpt-5.4 provider: openai - source_hash: 95e56c5411204363676f002059c942201503e2359515d1a4b409882cc2e04920 + source_hash: 8b0a3287b78bbc4c41e4354e9062daba7ae790fa207eee9a5f77515b958b510b source_path: refactor/async-exec-duplicate-completion-investigation.md workflow: 15 --- -# Async Exec 重复完成调查 +# Async Exec Duplicate Completion Investigation ## 范围 - 会话:`agent:main:telegram:group:-1003774691294:topic:1` -- 现象:同一个针对会话/运行 `keen-nexus` 的异步 exec 完成事件在 LCM 中被记录了两次,且都作为用户轮次。 +- 症状:同一个会话/运行 `keen-nexus` 的 async exec 完成事件在 LCM 中被记录为两次用户轮次。 - 目标:识别这更可能是重复的会话注入,还是单纯的出站投递重试。 ## 结论 -这最可能是**重复的会话注入**,而不是纯粹的出站投递重试。 +这更可能是**重复的会话注入**,而不是单纯的出站投递重试。 -Gateway 网关侧最明显的缺口在于**节点 exec 完成路径**: +Gateway 网关侧最明显的缺口出现在**节点 exec 完成路径**: -1. 节点侧 exec 结束会发出带完整 `runId` 的 `exec.finished`。 -2. Gateway 网关中的 `server-node-events` 会将其转换为一个 system event,并请求一次 heartbeat。 -3. heartbeat 运行会把已排空的 system event 块注入到智能体提示中。 -4. 嵌入式 runner 会将该提示作为新的用户轮次持久化到会话 transcript 中。 +1. 节点侧 exec 完成时会发出带完整 `runId` 的 `exec.finished`。 +2. Gateway 网关的 `server-node-events` 会将其转换为系统事件并请求一次 heartbeat。 +3. heartbeat 运行会将已排空的系统事件块注入到智能体提示词中。 +4. 嵌入式 runner 会将该提示词持久化为会话转录中的一个新用户轮次。 -如果同一个 `runId` 的 `exec.finished` 因任何原因再次到达 Gateway 网关(重放、重连重复、上游重发、生产者重复),OpenClaw 当前在这条路径上**没有基于 `runId` / `contextKey` 的幂等性检查**。第二份副本会变成第二条内容相同的用户消息。 +如果由于任何原因(重放、重连重复、上游重发、生产者重复)相同的 `exec.finished` 针对同一个 `runId` 两次到达 Gateway 网关,OpenClaw 当前在这条路径上**没有基于 `runId`/`contextKey` 的幂等检查**。第二份副本会变成第二条内容相同的用户消息。 ## 精确代码路径 ### 1. 生产者:节点 exec 完成事件 - `src/node-host/invoke.ts:340-360` - - `sendExecFinishedEvent(...)` 会发出事件为 `exec.finished` 的 `node.event`。 - - 载荷包含 `sessionKey` 和完整 `runId`。 + - `sendExecFinishedEvent(...)` 发出事件为 `exec.finished` 的 `node.event`。 + - 负载包含 `sessionKey` 和完整 `runId`。 ### 2. Gateway 网关事件摄取 - `src/gateway/server-node-events.ts:574-640` - 处理 `exec.finished`。 - - 构造文本: + - 构建文本: - `Exec finished (node=..., id=, code ...)` - - 通过以下方式入队: + - 通过以下方式将其入队: - `enqueueSystemEvent(text, { sessionKey, contextKey: runId ? \`exec:${runId}\` : "exec", trusted: false })` - - 然后立即请求唤醒: + - 并立即请求唤醒: - `requestHeartbeatNow(scopedHeartbeatWakeOptions(sessionKey, { reason: "exec-event" }))` -### 3. system event 去重薄弱点 +### 3. 系统事件去重薄弱点 - `src/infra/system-events.ts:90-115` - `enqueueSystemEvent(...)` 只会抑制**连续的重复文本**: - `if (entry.lastText === cleaned) return false` - - 它会存储 `contextKey`,但**不会**使用 `contextKey` 做幂等性判断。 - - drain 之后,重复抑制会重置。 + - 它会存储 `contextKey`,但**不会**使用 `contextKey` 做幂等检查。 + - 在 drain 之后,重复抑制会重置。 -这意味着,即使代码里已经有稳定的幂等性候选键(`exec:`),稍后被重放的相同 `runId` 的 `exec.finished` 仍然会再次被接受。 +这意味着,即使代码已经有一个稳定的幂等候选键(`exec:`),被重放的相同 `runId` 的 `exec.finished` 之后仍可能再次被接受。 ### 4. 唤醒处理不是主要的重复来源 - `src/infra/heartbeat-wake.ts:79-117` - 唤醒会按 `(agentId, sessionKey)` 合并。 - - 同一目标的重复唤醒请求会折叠为一个待处理唤醒条目。 + - 针对同一目标的重复唤醒请求会折叠为一个待处理唤醒条目。 -这使得**单独的重复唤醒处理**相比重复事件摄取而言,是一个更弱的解释。 +因此,相比重复事件摄取,**单靠重复唤醒处理**来解释问题的可能性更低。 -### 5. Heartbeat 消费事件并将其转为提示输入 +### 5. Heartbeat 消费该事件并将其转为提示词输入 - `src/infra/heartbeat-runner.ts:535-574` - - 预检会窥视待处理的 system event,并对 exec-event 运行进行分类。 + - 预检会窥视待处理系统事件,并对 exec-event 运行进行分类。 - `src/auto-reply/reply/session-system-events.ts:86-90` - `drainFormattedSystemEvents(...)` 会排空该会话的队列。 - `src/auto-reply/reply/get-reply-run.ts:400-427` - - 已排空的 system event 块会被前置到智能体提示正文中。 + - 排空后的系统事件块会被前置注入到智能体提示词主体中。 -### 6. Transcript 注入点 +### 6. 转录注入点 - `src/agents/pi-embedded-runner/run/attempt.ts:2000-2017` - - `activeSession.prompt(effectivePrompt)` 会将完整提示提交给嵌入式 PI 会话。 - - 这就是完成事件衍生出的提示被持久化为用户轮次的位置。 + - `activeSession.prompt(effectivePrompt)` 会将完整提示词提交给嵌入式 PI 会话。 + - 这就是基于完成事件生成的提示词变成持久化用户轮次的那个点。 -因此,一旦同一个 system event 被两次重建进提示中,LCM 中出现重复的用户消息就是符合预期的。 +因此,一旦同一个系统事件被两次重建进提示词中,出现重复的 LCM 用户消息就是预期结果。 ## 为什么单纯的出站投递重试可能性更低 heartbeat runner 中确实存在真实的出站失败路径: - `src/infra/heartbeat-runner.ts:1194-1242` - - 回复会先生成。 - - 出站投递随后通过 `deliverOutboundPayloads(...)` 进行。 - - 该步骤失败会返回 `{ status: "failed" }`。 + - 先生成回复。 + - 然后通过 `deliverOutboundPayloads(...)` 进行出站投递。 + - 此处失败会返回 `{ status: "failed" }`。 -但是,对于同一个 system event 队列条目,仅这一点**不足以**解释重复的用户轮次: +但是,对于同一个系统事件队列条目,仅凭这一点**不足以**解释重复的用户轮次: - `src/auto-reply/reply/session-system-events.ts:86-90` - - system event 队列在出站投递之前就已经被排空了。 + - 系统事件队列在出站投递之前就已经被排空。 -所以,单独的渠道发送重试不会重新创建同一个已入队事件。它可以解释外部投递缺失/失败,但本身不能解释第二条完全相同的会话用户消息。 +因此,仅仅是渠道发送重试本身不会重新创建完全相同的排队事件。它可以解释外部投递缺失/失败,但单靠这一点无法解释第二条完全相同的会话用户消息。 ## 次要的、置信度较低的可能性 -智能体 runner 中存在完整运行的重试循环: +智能体 runner 中存在一个完整运行重试循环: - `src/auto-reply/reply/agent-runner-execution.ts:741-1473` - - 某些瞬时失败可能会重试整个运行,并重新提交同一个 `commandBody`。 + - 某些瞬时失败会重试整个运行,并重新提交相同的 `commandBody`。 -如果在触发重试条件之前,提示已经被追加,那么这可能会在**同一次回复执行**中复制一个已持久化的用户提示。 +如果在触发重试条件之前提示词已经被追加,那么这可能会在**同一次回复执行内部**复制一个已持久化的用户提示词。 -我认为这比重复的 `exec.finished` 摄取可能性更低,因为: +我将这种可能性排在低于重复 `exec.finished` 摄取之后,因为: -- 观察到的间隔大约为 51 秒,这更像是第二次唤醒/轮次,而不是进程内重试; -- 报告中已经提到消息发送失败反复出现,这更指向一个单独的后续轮次,而不是一次即时的模型/运行时重试。 +- 观察到的时间间隔约为 51 秒,更像是第二次唤醒/轮次,而不是进程内重试; +- 报告中已经提到重复的消息发送失败,这更指向一次后续独立轮次,而不是即时的模型/运行时重试。 ## 根因假设 -最高置信度的假设是: +最高置信度假设: -- `keen-nexus` 的完成事件走的是**节点 exec 事件路径**。 -- 同一个 `exec.finished` 被投递到了 `server-node-events` 两次。 +- `keen-nexus` 完成事件走的是**节点 exec 事件路径**。 +- 同一个 `exec.finished` 被两次投递到 `server-node-events`。 - Gateway 网关接受了这两次事件,因为 `enqueueSystemEvent(...)` 不会按 `contextKey` / `runId` 去重。 -- 每个被接受的事件都会触发一次 heartbeat,并被注入为 PI transcript 中的一个用户轮次。 +- 每个被接受的事件都会触发一次 heartbeat,并作为一个用户轮次注入到 PI 转录中。 -## 建议的微创修复 +## 建议的微小外科式修复 如果要修复,最小但高价值的改动是: -- 让 exec/system-event 的幂等性在短时间窗口内基于 `contextKey` 生效,至少要拦截完全相同的 `(sessionKey, contextKey, text)` 重复; -- 或者在 `server-node-events` 中为 `exec.finished` 增加一个专门的去重,键为 `(sessionKey, runId, event kind)`。 +- 让 exec/系统事件幂等性在短时间窗口内尊重 `contextKey`,至少对完全相同的 `(sessionKey, contextKey, text)` 重复项生效; +- 或者在 `server-node-events` 中为 `exec.finished` 添加专用去重,键为 `(sessionKey, runId, event kind)`。 -这样可以在重放的 `exec.finished` 变成会话轮次之前,直接将其拦住。 +这将直接阻止被重放的 `exec.finished` 重复项在变成会话轮次之前通过。 diff --git a/docs/zh-CN/refactor/qa.md b/docs/zh-CN/refactor/qa.md index c397525ba..cb033602f 100644 --- a/docs/zh-CN/refactor/qa.md +++ b/docs/zh-CN/refactor/qa.md @@ -1,9 +1,14 @@ --- +read_when: + - 重构 QA 场景定义或 qa-lab 测试框架代码 + - 在 Markdown 场景与 TypeScript 测试框架逻辑之间迁移 QA 行为 +summary: QA 重构:场景目录与测试框架整合计划 +title: QA 重构 x-i18n: - generated_at: "2026-04-17T15:05:20Z" + generated_at: "2026-04-23T06:43:04Z" model: gpt-5.4 provider: openai - source_hash: dbb2c70c82da7f6f12d90e25666635ff4147c52e8a94135e902d1de4f5cbccca + source_hash: 16867d5be372ab414aa516144193144414c326ea53a52627f3ff91f85b8fdf9d source_path: refactor/qa.md workflow: 15 --- @@ -14,20 +19,21 @@ x-i18n: ## 目标 -将 OpenClaw QA 从拆分定义模型迁移为单一事实来源: +将 OpenClaw QA 从分裂定义模型迁移为单一事实来源: - 场景元数据 - 发送给模型的提示词 - 设置与清理 -- harness 逻辑 +- 测试框架逻辑 - 断言与成功标准 - 产物与报告提示 -期望的最终状态是:一个通用 QA harness 加载功能强大的场景定义文件,而不是将大部分行为硬编码在 TypeScript 中。 +期望的最终状态是:一个通用 QA 测试框架加载功能强大的场景定义文件,而不是在 TypeScript 中硬编码大部分行为。 ## 当前状态 -当前的主要事实来源现在位于 `qa/scenarios/index.md`,以及每个场景对应的单独文件 `qa/scenarios//*.md`。 +当前的主要事实来源已位于 `qa/scenarios/index.md`,以及 +`qa/scenarios//*.md` 下每个场景对应的单独文件中。 已实现: @@ -39,28 +45,28 @@ x-i18n: - 每个场景一个 Markdown 文件 - 场景元数据 - handler 绑定 - - 场景专用执行配置 + - 场景特定执行配置 - `extensions/qa-lab/src/scenario-catalog.ts` - Markdown 包解析器 + zod 校验 - `extensions/qa-lab/src/qa-agent-bootstrap.ts` - - 从 Markdown 包渲染执行计划 + - 从 Markdown 包渲染计划 - `extensions/qa-lab/src/qa-agent-workspace.ts` - - 生成兼容性文件种子,以及 `QA_SCENARIOS.md` + - 生成兼容性种子文件以及 `QA_SCENARIOS.md` - `extensions/qa-lab/src/suite.ts` - 通过 Markdown 定义的 handler 绑定选择可执行场景 -- QA 总线协议 + UI - - 用于图片 / 视频 / 音频 / 文件渲染的通用内联附件 +- QA bus 协议 + UI + - 用于图像/视频/音频/文件渲染的通用内联附件 -仍然拆分的部分: +仍然分裂的表面: - `extensions/qa-lab/src/suite.ts` - - 仍然承载大多数可执行自定义 handler 逻辑 + - 仍然承载大部分可执行的自定义 handler 逻辑 - `extensions/qa-lab/src/report.ts` - - 仍然根据运行时输出推导报告结构 + - 仍然从运行时输出中推导报告结构 -因此,事实来源拆分问题已经修复,但执行层仍然主要依赖 handler,而不是完全声明式。 +因此,事实来源分裂的问题已修复,但执行层面目前仍主要依赖 handler,而非完全声明式。 -## 实际场景面是什么样的 +## 实际的场景表面是什么样的 阅读当前 suite 可以看到几类不同的场景。 @@ -68,49 +74,49 @@ x-i18n: - 渠道基线 - 私信基线 -- 线程后续跟进 +- 线程跟进 - 模型切换 -- 审批后续执行 -- reaction / edit / delete +- 审批继续执行 +- 反应/编辑/删除 ### 配置与运行时变更 -- config patch skill disable -- config apply restart wake-up -- config restart capability flip -- runtime inventory drift check +- 配置补丁禁用 Skills +- 配置应用后重启唤醒 +- 配置重启能力切换 +- 运行时清单漂移检查 ### 文件系统与仓库断言 -- source / docs discovery report -- build Lobster Invaders -- generated image artifact lookup +- source/docs 发现报告 +- 构建 Lobster Invaders +- 生成图像产物查找 ### Memory 编排 -- memory recall -- 渠道上下文中的 memory 工具 -- memory failure fallback -- session memory ranking -- 线程 memory 隔离 -- memory dreaming sweep +- 记忆召回 +- 渠道上下文中的记忆工具 +- 记忆失败回退 +- 会话记忆排序 +- 线程记忆隔离 +- 记忆 Dreaming 扫描 ### 工具与插件集成 -- MCP plugin-tools call -- Skills 可见性 -- Skills 热安装 +- MCP plugin-tools 调用 +- skill 可见性 +- skill 热安装 - 原生图像生成 - 图像往返 - 从附件理解图像 ### 多轮与多参与者 -- subagent handoff -- subagent fanout synthesis -- restart recovery 风格流程 +- 子智能体移交 +- 子智能体扇出综合 +- 重启恢复类流程 -这些分类很重要,因为它们决定 DSL 的需求。仅靠“提示词 + 预期文本”的平面列表是不够的。 +这些分类之所以重要,是因为它们决定了 DSL 的需求。仅有“提示词 + 期望文本”的扁平列表是不够的。 ## 方向 @@ -120,18 +126,18 @@ x-i18n: 这个包应保持: -- 便于人工在评审中阅读 -- 可被机器解析 -- 足够丰富,可驱动: +- 在评审中人类可读 +- 机器可解析 +- 足够丰富,能够驱动: - suite 执行 - - QA 工作区 bootstrap + - QA 工作区引导 - QA Lab UI 元数据 - - docs / discovery 提示词 + - 文档/发现提示词 - 报告生成 ### 首选编写格式 -使用 Markdown 作为顶层格式,并在其中使用结构化 YAML。 +使用 Markdown 作为顶层格式,并在其中嵌入结构化 YAML。 推荐结构: @@ -142,7 +148,7 @@ x-i18n: - tags - docs refs - code refs - - model / provider overrides + - model/provider overrides - prerequisites - prose sections - objective @@ -156,13 +162,13 @@ x-i18n: 这样可以获得: -- 比庞大的 JSON 更好的 PR 可读性 +- 比大型 JSON 更好的 PR 可读性 - 比纯 YAML 更丰富的上下文 -- 严格解析与 zod 校验 +- 严格解析和 zod 校验 -原始 JSON 仅应作为中间生成形式接受。 +原始 JSON 只应作为中间生成形式被接受。 -## 提议的场景文件结构 +## 建议的场景文件结构 示例: @@ -187,7 +193,7 @@ codeRefs: # Objective -Verify generated media is reattached on the follow-up turn. +验证生成的媒体会在后续轮次中重新附加。 # Setup @@ -208,7 +214,7 @@ Verify generated media is reattached on the follow-up turn. - action: agent.send session: agent:qa:image-roundtrip message: | - Image generation check: generate a QA lighthouse image and summarize it in one short sentence. + 图像生成检查:生成一张 QA 灯塔图像,并用一句简短的话总结它。 - action: artifact.capture kind: generated-image promptSnippet: Image generation check @@ -216,7 +222,7 @@ Verify generated media is reattached on the follow-up turn. - action: agent.send session: agent:qa:image-roundtrip message: | - Roundtrip image inspection check: describe the generated lighthouse attachment in one short sentence. + 图像往返检查:用一句简短的话描述生成的灯塔附件。 attachments: - fromArtifact: lighthouseImage ``` @@ -235,11 +241,11 @@ Verify generated media is reattached on the follow-up turn. ``` ```` -## DSL 必须覆盖的运行器能力 +## DSL 必须覆盖的 Runner 能力 -根据当前 suite,通用运行器需要的不只是提示词执行。 +根据当前 suite,通用 runner 需要的不仅仅是执行提示词。 -### 环境与设置动作 +### 环境与设置操作 - `bus.reset` - `gateway.waitHealthy` @@ -248,14 +254,14 @@ Verify generated media is reattached on the follow-up turn. - `thread.create` - `workspace.writeSkill` -### 智能体轮次动作 +### 智能体轮次操作 - `agent.send` - `agent.wait` - `bus.injectInbound` - `bus.injectOutbound` -### 配置与运行时动作 +### 配置与运行时操作 - `config.get` - `config.patch` @@ -264,7 +270,7 @@ Verify generated media is reattached on the follow-up turn. - `tools.effective` - `skills.status` -### 文件与产物动作 +### 文件与产物操作 - `file.write` - `file.read` @@ -273,7 +279,7 @@ Verify generated media is reattached on the follow-up turn. - `artifact.captureGeneratedImage` - `artifact.capturePath` -### Memory 与 cron 动作 +### Memory 与 cron 操作 - `memory.indexForce` - `memory.searchCli` @@ -283,7 +289,7 @@ Verify generated media is reattached on the follow-up turn. - `cron.waitCompletion` - `sessionTranscript.write` -### MCP 动作 +### MCP 操作 - `mcp.callTool` @@ -307,62 +313,62 @@ Verify generated media is reattached on the follow-up turn. DSL 必须支持保存输出并在后续引用。 -当前 suite 中的示例: +来自当前 suite 的示例: -- 创建一个线程,然后复用 `threadId` -- 创建一个 session,然后复用 `sessionKey` -- 生成一张图片,然后在下一轮中附加该文件 -- 生成一个 wake marker 字符串,然后断言它稍后出现 +- 创建线程,然后复用 `threadId` +- 创建会话,然后复用 `sessionKey` +- 生成图像,然后在下一轮附加该文件 +- 生成一个唤醒标记字符串,然后断言它稍后出现 所需能力: - `saveAs` - `${vars.name}` - `${artifacts.name}` -- 针对路径、session key、线程 id、marker、工具输出的类型化引用 +- 路径、会话键、线程 ID、标记、工具输出的类型化引用 -如果没有变量支持,harness 逻辑就会继续泄漏回 TypeScript 中。 +如果没有变量支持,测试框架逻辑仍会不断从 DSL 泄漏回 TypeScript。 ## 哪些内容应保留为逃生口 -在第 1 阶段,完全纯声明式的运行器并不现实。 +在第一阶段,实现一个完全纯声明式的 runner 并不现实。 -有些场景天然就是重编排型的: +有些场景天生就更偏编排: -- memory dreaming sweep -- config apply restart wake-up -- config restart capability flip -- 按时间戳 / 路径解析生成图像产物 -- discovery-report evaluation +- 记忆 Dreaming 扫描 +- 配置应用后重启唤醒 +- 配置重启能力切换 +- 基于时间戳/路径解析生成图像产物 +- discovery-report 评估 -这些目前应继续使用显式自定义 handler。 +目前这些应继续使用显式自定义 handler。 推荐规则: -- 85-90% 声明式 -- 对剩余困难部分使用显式 `customHandler` steps -- 仅允许具名且有文档说明的自定义 handler -- 不允许在场景文件中写匿名内联代码 +- 85–90% 声明式 +- 对于剩余复杂部分,使用显式 `customHandler` 步骤 +- 仅允许已命名并有文档的自定义 handler +- 场景文件中不允许匿名内联代码 -这样可以让通用引擎保持整洁,同时仍然推进迁移。 +这样既能保持通用引擎整洁,又能继续推进。 ## 架构变更 ### 当前 -场景 Markdown 现在已经是以下内容的事实来源: +场景 Markdown 现在已是以下内容的事实来源: - suite 执行 -- 工作区 bootstrap 文件 +- 工作区引导文件 - QA Lab UI 场景目录 - 报告元数据 -- discovery 提示词 +- 发现提示词 -生成的兼容性内容: +已生成的兼容性内容: -- seed 工作区仍然包含 `QA_KICKOFF_TASK.md` -- seed 工作区仍然包含 `QA_SCENARIO_PLAN.md` -- seed 工作区现在还包含 `QA_SCENARIOS.md` +- 种子工作区仍包含 `QA_KICKOFF_TASK.md` +- 种子工作区仍包含 `QA_SCENARIO_PLAN.md` +- 种子工作区现在还包含 `QA_SCENARIOS.md` ## 重构计划 @@ -372,10 +378,10 @@ DSL 必须支持保存输出并在后续引用。 - 添加了 `qa/scenarios/index.md` - 将场景拆分到 `qa/scenarios//*.md` -- 为具名 Markdown YAML 包内容添加了解析器 +- 添加了命名 Markdown YAML 包内容解析器 - 使用 zod 进行校验 -- 将消费者切换到已解析的包 -- 删除了仓库级 `qa/seed-scenarios.json` 和 `qa/QA_KICKOFF_TASK.md` +- 将消费者切换到解析后的包 +- 移除了仓库级的 `qa/seed-scenarios.json` 和 `qa/QA_KICKOFF_TASK.md` ### 第 2 阶段:通用引擎 @@ -385,55 +391,55 @@ DSL 必须支持保存输出并在后续引用。 - action registry - assertion registry - custom handlers -- 保留现有 helper functions 作为引擎操作 +- 保留现有辅助函数作为引擎操作 交付物: -- 引擎执行简单的声明式场景 +- 引擎可执行简单的声明式场景 -先从主要是 prompt + wait + assert 的场景开始: +从主要是“提示词 + 等待 + 断言”的场景开始: -- threaded follow-up +- 线程跟进 - 从附件理解图像 -- Skills 可见性与调用 -- channel baseline +- skill 可见性与调用 +- 渠道基线 交付物: -- 第一批真正由 Markdown 定义并通过通用引擎交付的场景 +- 第一批真正由 Markdown 定义并通过通用引擎运行的场景上线 ### 第 4 阶段:迁移中等复杂度场景 -- image generation roundtrip -- 渠道上下文中的 memory 工具 -- session memory ranking -- subagent handoff -- subagent fanout synthesis +- 图像生成往返 +- 渠道上下文中的记忆工具 +- 会话记忆排序 +- 子智能体移交 +- 子智能体扇出综合 交付物: -- 变量、产物、工具断言、request-log 断言都得到验证 +- 变量、产物、工具断言、request-log 断言得到验证 -### 第 5 阶段:将困难场景保留在自定义 handler 中 +### 第 5 阶段:将复杂场景保留在自定义 handler 中 -- memory dreaming sweep -- config apply restart wake-up -- config restart capability flip -- runtime inventory drift +- 记忆 Dreaming 扫描 +- 配置应用后重启唤醒 +- 配置重启能力切换 +- 运行时清单漂移 交付物: -- 保持相同的编写格式,但在需要时使用显式 custom-step blocks +- 保持相同的编写格式,但在需要时使用显式自定义步骤块 ### 第 6 阶段:删除硬编码场景映射 当包覆盖率足够高后: -- 删除 `extensions/qa-lab/src/suite.ts` 中大多数按场景分支的 TypeScript 逻辑 +- 删除 `extensions/qa-lab/src/suite.ts` 中大部分特定场景的 TypeScript 分支逻辑 ## Fake Slack / 富媒体支持 -当前 QA 总线仍然是 text-first。 +当前的 QA bus 以文本为主。 相关文件: @@ -443,17 +449,17 @@ DSL 必须支持保存输出并在后续引用。 - `extensions/qa-lab/src/bus-server.ts` - `extensions/qa-lab/web/src/ui-render.ts` -目前 QA 总线支持: +当前 QA bus 支持: - 文本 -- reactions -- threads +- 反应 +- 线程 -它还不能建模内联媒体附件。 +它尚未对内联媒体附件建模。 -### 所需的传输契约 +### 所需传输契约 -添加通用 QA 总线附件模型: +添加一个通用 QA bus 附件模型: ```ts type QaBusAttachment = { @@ -478,34 +484,34 @@ type QaBusAttachment = { - `QaBusInboundMessageInput` - `QaBusOutboundMessageInput` -### 为什么要先做通用层 +### 为什么先做通用模型 不要构建仅限 Slack 的媒体模型。 -而应该: +而应采用: -- 先有一个通用 QA 传输模型 -- 再在其上构建多个渲染器 - - 当前 QA Lab chat +- 一个通用 QA 传输模型 +- 其上支持多个渲染器 + - 当前的 QA Lab 聊天 - 未来的 fake Slack web - - 其他任何 fake transport views + - 其他任何 fake transport 视图 -这样可以避免重复逻辑,并让媒体场景保持与传输层无关。 +这样可以避免重复逻辑,并让媒体场景保持与传输方式无关。 -### 所需的 UI 工作 +### 所需 UI 工作 -更新 QA UI 以渲染: +更新 QA UI,以渲染: - 内联图片预览 - 内联音频播放器 - 内联视频播放器 - 文件附件 chip -当前 UI 已经可以渲染线程和 reactions,因此附件渲染应可以叠加到同一消息卡片模型上。 +当前 UI 已能渲染线程和反应,因此附件渲染应能叠加到相同的消息卡片模型上。 -### 媒体传输启用后的场景工作 +### 媒体传输将启用的场景工作 -一旦附件可以通过 QA 总线流转,我们就可以添加更丰富的 fake-chat 场景: +一旦附件可以通过 QA bus 流动,我们就能添加更丰富的 fake-chat 场景: - fake Slack 中的内联图片回复 - 音频附件理解 @@ -515,24 +521,24 @@ type QaBusAttachment = { ## 建议 -下一块实现工作应是: +下一块实现应当是: 1. 添加 Markdown 场景加载器 + zod schema 2. 从 Markdown 生成当前目录 3. 先迁移几个简单场景 -4. 添加通用 QA 总线附件支持 +4. 添加通用 QA bus 附件支持 5. 在 QA UI 中渲染内联图片 -6. 然后再扩展到音频和视频 +6. 然后扩展到音频和视频 这是能同时验证两个目标的最小路径: -- 通用的 Markdown 定义 QA -- 更丰富的 fake messaging surfaces +- 通用、由 Markdown 定义的 QA +- 更丰富的 fake messaging 表面 -## 开放问题 +## 未决问题 - 场景文件是否应允许嵌入带变量插值的 Markdown 提示词模板 -- setup / cleanup 应该是具名 section,还是仅作为有序动作列表 -- 产物引用在 schema 中应采用强类型,还是基于字符串 -- 自定义 handler 应放在一个统一 registry 中,还是按 surface 分 registry -- 在迁移期间,生成的 JSON 兼容性文件是否应继续保留为已检入状态 +- 设置/清理应作为命名区段存在,还是仅作为有序操作列表 +- 产物引用在 schema 中应为强类型,还是基于字符串 +- 自定义 handler 应放在一个统一注册表中,还是按 surface 分注册表 +- 在迁移期间,生成的 JSON 兼容文件是否应继续保留为已检入状态 diff --git a/docs/zh-CN/reference/rich-output-protocol.md b/docs/zh-CN/reference/rich-output-protocol.md index 94ea59937..3b8436780 100644 --- a/docs/zh-CN/reference/rich-output-protocol.md +++ b/docs/zh-CN/reference/rich-output-protocol.md @@ -1,23 +1,28 @@ --- +read_when: + - 更改 Control UI 中的助手输出渲染方式 + - 调试 `[embed ...]`、`MEDIA:`、reply 或音频展示指令 +summary: 用于嵌入、媒体、音频提示和回复的富输出短代码协议 +title: 富输出协议 x-i18n: - generated_at: "2026-04-11T12:34:16Z" + generated_at: "2026-04-23T06:43:16Z" model: gpt-5.4 provider: openai - source_hash: 2a8884fc2c304bf96d4675f0c1d1ff781d6dc1ae8c49d92ce08040c9c7709035 + source_hash: 566338ac0571c6ab9062c6bad0bc4f71fe65249a3fcd9d8e575affcd93db11e7 source_path: reference/rich-output-protocol.md workflow: 15 --- # 富输出协议 -助手输出可以携带一小组传递/渲染指令: +助手输出可以携带一小组投递/渲染指令: -- `MEDIA:` 用于附件传递 -- `[[audio_as_voice]]` 用于音频呈现提示 +- `MEDIA:` 用于附件投递 +- `[[audio_as_voice]]` 用于音频展示提示 - `[[reply_to_current]]` / `[[reply_to:]]` 用于回复元数据 - `[embed ...]` 用于 Control UI 富渲染 -这些指令彼此独立。`MEDIA:` 以及回复/语音标签仍然是传递元数据;`[embed ...]` 是仅限 Web 的富渲染路径。 +这些指令彼此独立。`MEDIA:` 和 reply/voice 标签仍然属于投递元数据;`[embed ...]` 则是仅限 web 的富渲染路径。 ## `[embed ...]` @@ -26,19 +31,19 @@ x-i18n: 自闭合示例: ```text -[embed ref="cv_123" title="状态" /] +[embed ref="cv_123" title="Status" /] ``` 规则: - `[view ...]` 不再对新输出有效。 -- Embed 短代码只会在助手消息界面中渲染。 -- 只有基于 URL 的 embed 会被渲染。使用 `ref="..."` 或 `url="..."`。 -- 块级内联 HTML embed 短代码不会被渲染。 -- Web UI 会从可见文本中移除该短代码,并以内联方式渲染 embed。 -- `MEDIA:` 不是 embed 的别名,不应被用于富 embed 渲染。 +- Embed 短代码仅在助手消息界面中渲染。 +- 仅渲染基于 URL 的 embed。请使用 `ref="..."` 或 `url="..."`。 +- 不渲染块形式的内联 HTML embed 短代码。 +- Web UI 会从可见文本中移除该短代码,并在行内渲染 embed。 +- `MEDIA:` 不是 embed 别名,不应用于富 embed 渲染。 -## 存储渲染形状 +## 存储的渲染形状 规范化/存储后的助手内容块是一个结构化的 `canvas` 项: @@ -57,4 +62,4 @@ x-i18n: } ``` -存储/渲染后的富内容块直接使用这个 `canvas` 形状。`present_view` 不会被识别。 +存储/渲染后的富内容块直接使用这种 `canvas` 形状。`present_view` 不被识别。 diff --git a/docs/zh-CN/reference/transcript-hygiene.md b/docs/zh-CN/reference/transcript-hygiene.md index 11ed8ea76..b83079bfb 100644 --- a/docs/zh-CN/reference/transcript-hygiene.md +++ b/docs/zh-CN/reference/transcript-hygiene.md @@ -1,34 +1,38 @@ --- read_when: - 你正在调试与转录形状相关的提供商请求拒绝问题 - - 你正在修改转录清理或工具调用修复逻辑 + - 你正在更改转录清理或工具调用修复逻辑 - 你正在调查跨提供商的工具调用 id 不匹配问题 -summary: 参考:提供商专用的转录清理与修复规则 -title: 转录清理 +summary: 参考:提供商特定的转录清理与修复规则 +title: 转录卫生规范 x-i18n: - generated_at: "2026-04-05T10:08:54Z" + generated_at: "2026-04-23T06:43:29Z" model: gpt-5.4 provider: openai - source_hash: 217afafb693cf89651e8fa361252f7b5c197feb98d20be4697a83e6dedc0ec3f + source_hash: 0b528099b547155e5cf25be19e64a017d338b6f7b9c7ef51dc3ce2c2963193b8 source_path: reference/transcript-hygiene.md workflow: 15 --- -# 转录清理(提供商修复) +# 转录卫生规范(提供商修正规则) -本文档描述了在一次运行之前应用到转录上的**提供商专用修复**(构建模型上下文时)。这些是用于满足严格提供商要求的**内存中**调整。这些清理步骤**不会**重写磁盘上存储的 JSONL 转录;不过,在会话加载之前,单独的会话文件修复过程可能会通过丢弃无效行来重写格式错误的 JSONL 文件。发生修复时,原始文件会在会话文件旁边进行备份。 +本文档描述了在一次运行之前对转录应用的**提供商特定修复** +(构建模型上下文时)。这些是用于满足严格 +提供商要求的**内存中**调整。这些卫生步骤**不会**重写磁盘上存储的 JSONL 转录; +不过,在会话加载前,一个单独的会话文件修复流程可能会通过丢弃无效行来重写格式错误的 JSONL 文件。 +发生修复时,原始文件会与会话文件一起进行备份。 范围包括: - 工具调用 id 清理 -- 工具调用输入校验 +- 工具调用输入验证 - 工具结果配对修复 -- 轮次校验 / 排序 -- thought signature 清理 +- 轮次验证 / 排序 +- 思维签名清理 - 图像负载清理 -- 用户输入来源标记(用于跨会话路由的提示词) +- 用户输入来源标记(用于跨会话路由的提示) -如果你需要转录存储的详细信息,请参见: +如果你需要了解转录存储细节,请参见: - [/reference/session-management-compaction](/zh-CN/reference/session-management-compaction) @@ -36,62 +40,63 @@ x-i18n: ## 运行位置 -所有转录清理都集中在嵌入式运行器中: +所有转录卫生逻辑都集中在嵌入式运行器中: - 策略选择:`src/agents/transcript-policy.ts` -- 清理/修复应用:`src/agents/pi-embedded-runner/google.ts` 中的 `sanitizeSessionHistory` +- 清理/修复应用:`src/agents/pi-embedded-runner/replay-history.ts` 中的 `sanitizeSessionHistory` 该策略使用 `provider`、`modelApi` 和 `modelId` 来决定应用哪些规则。 -与转录清理分开的是,会话文件会在加载前按需修复: +与转录卫生分开的是,会话文件会在加载前按需修复: - `src/agents/session-file-repair.ts` 中的 `repairSessionFileIfNeeded` -- 从 `run/attempt.ts` 和 `compact.ts`(嵌入式运行器)中调用 +- 由 `run/attempt.ts` 和 `compact.ts`(嵌入式运行器)调用 --- ## 全局规则:图像清理 -图像负载始终会被清理,以防因大小限制导致提供商侧拒绝 -(对过大的 base64 图像进行缩放/重新压缩)。 +图像负载始终会被清理,以防止因尺寸 +限制而被提供商拒绝(对超大的 base64 图像进行缩放/重新压缩)。 -这也有助于控制支持视觉的模型中由图像驱动的 token 压力。 +这也有助于控制支持视觉模型时由图像驱动的 token 压力。 较低的最大尺寸通常会减少 token 使用量;较高的尺寸则能保留更多细节。 -实现: +实现位置: - `src/agents/pi-embedded-helpers/images.ts` 中的 `sanitizeSessionMessagesImages` - `src/agents/tool-images.ts` 中的 `sanitizeContentBlocksImages` -- 最大图像边长可通过 `agents.defaults.imageMaxDimensionPx` 配置(默认:`1200`)。 +- 最大图像边长可通过 `agents.defaults.imageMaxDimensionPx` 配置(默认值:`1200`)。 --- ## 全局规则:格式错误的工具调用 -缺少 `input` 和 `arguments` 的 assistant 工具调用区块会在构建模型上下文前被丢弃。 -这可防止提供商因部分持久化的工具调用而拒绝请求(例如在速率限制失败之后)。 +缺少 `input` 和 `arguments` 的 assistant 工具调用块会在构建 +模型上下文前被丢弃。这可防止提供商因部分持久化的工具调用 +而拒绝请求(例如在速率限制失败之后)。 -实现: +实现位置: - `src/agents/session-transcript-repair.ts` 中的 `sanitizeToolCallInputs` -- 应用于 `src/agents/pi-embedded-runner/google.ts` 中的 `sanitizeSessionHistory` +- 应用于 `src/agents/pi-embedded-runner/replay-history.ts` 中的 `sanitizeSessionHistory` --- ## 全局规则:跨会话输入来源 -当智能体通过 `sessions_send` 将提示词发送到另一个会话时(包括 -智能体对智能体的回复/公告步骤),OpenClaw 会将创建的用户轮次持久化为: +当一个智能体通过 `sessions_send` 向另一个会话发送提示时(包括 +智能体到智能体的回复/公告步骤),OpenClaw 会将创建出的用户轮次持久化为: - `message.provenance.kind = "inter_session"` -该元数据会在追加转录时写入,不会改变角色 -(为兼容提供商,`role: "user"` 保持不变)。转录读取器可以利用 -这一点,避免将路由的内部提示词视为最终用户撰写的指令。 +此元数据在追加到转录时写入,不会改变角色 +(为了兼容提供商,仍保持 `role: "user"`)。转录读取器可以利用 +这一点,避免将路由的内部提示视为终端用户编写的指令。 -在上下文重建期间,OpenClaw 还会在内存中为这些用户轮次前置一个简短的 `[Inter-session message]` -标记,以便模型将它们与 -外部最终用户指令区分开来。 +在重建上下文期间,OpenClaw 还会在内存中为这些用户轮次前置一个简短的 `[Inter-session message]` +标记,以便模型将其与 +外部终端用户指令区分开来。 --- @@ -100,35 +105,35 @@ x-i18n: **OpenAI / OpenAI Codex** - 仅图像清理。 -- 对于 OpenAI Responses/Codex 转录,丢弃孤立的 reasoning signature(后面没有内容区块的独立 reasoning 项)。 +- 对于 OpenAI Responses/Codex 转录,丢弃孤立的 reasoning 签名(即后面没有跟随内容块的独立 reasoning 项)。 - 不进行工具调用 id 清理。 - 不进行工具结果配对修复。 -- 不进行轮次校验或重排序。 -- 不生成合成工具结果。 -- 不移除 thought signature。 +- 不进行轮次验证或重新排序。 +- 不注入合成工具结果。 +- 不移除 thought 签名。 **Google(Generative AI / Gemini CLI / Antigravity)** - 工具调用 id 清理:严格字母数字。 - 工具结果配对修复和合成工具结果。 -- 轮次校验(Gemini 风格轮次交替)。 -- Google 轮次排序修复(如果历史记录以 assistant 开始,则前置一个很小的用户 bootstrap)。 -- Antigravity Claude:规范化 thinking signature;丢弃未签名的 thinking 区块。 +- 轮次验证(Gemini 风格的轮次交替)。 +- Google 轮次顺序修复(如果历史记录以 assistant 开始,则前置一个很小的用户引导消息)。 +- Antigravity Claude:规范化 thinking 签名;丢弃未签名的 thinking 块。 -**Anthropic / Minimax(兼容 Anthropic)** +**Anthropic / Minimax(Anthropic 兼容)** - 工具结果配对修复和合成工具结果。 -- 轮次校验(合并连续的用户轮次,以满足严格交替要求)。 +- 轮次验证(合并连续的用户轮次,以满足严格交替要求)。 -**Mistral(包括基于 model-id 的检测)** +**Mistral(包括基于 model id 的检测)** - 工具调用 id 清理:strict9(长度为 9 的字母数字)。 **OpenRouter Gemini** -- Thought signature 清理:移除非 base64 的 `thought_signature` 值(保留 base64)。 +- thought 签名清理:移除非 base64 的 `thought_signature` 值(保留 base64)。 -**其他所有情况** +**其他所有提供商** - 仅图像清理。 @@ -136,17 +141,17 @@ x-i18n: ## 历史行为(2026.1.22 之前) -在 2026.1.22 版本之前,OpenClaw 会应用多层转录清理: +在 2026.1.22 发布之前,OpenClaw 应用了多层转录卫生处理: -- 一个 **transcript-sanitize 扩展** 会在每次构建上下文时运行,并且可能: +- 每次构建上下文时都会运行一个 **transcript-sanitize 扩展**,它可以: - 修复工具使用/结果配对。 - 清理工具调用 id(包括保留 `_`/`-` 的非严格模式)。 -- 运行器还会执行提供商专用清理,从而造成重复工作。 -- 还有额外的变更发生在提供商策略之外,包括: - - 在持久化之前从 assistant 文本中移除 `` 标签。 +- 运行器也会执行提供商特定清理,这造成了重复工作。 +- 在提供商策略之外还存在额外变更,包括: + - 在持久化前从 assistant 文本中移除 `` 标签。 - 丢弃空的 assistant 错误轮次。 - - 在工具调用之后裁剪 assistant 内容。 + - 在工具调用后裁剪 assistant 内容。 这种复杂性导致了跨提供商回归(尤其是 `openai-responses` `call_id|fc_id` 配对)。2026.1.22 的清理工作移除了该扩展,将 -逻辑集中到运行器中,并使 OpenAI 除图像清理之外保持**不触碰**。 +逻辑集中到运行器中,并让 OpenAI 除图像清理之外保持**不做额外处理**。 diff --git a/docs/zh-CN/start/hubs.md b/docs/zh-CN/start/hubs.md index 5c6fa7e59..9130458e4 100644 --- a/docs/zh-CN/start/hubs.md +++ b/docs/zh-CN/start/hubs.md @@ -1,40 +1,40 @@ --- read_when: - - 你想查看完整的文档地图 -summary: 链接到每一篇 OpenClaw 文档的中心页 -title: 文档中心 + - 你想要一份完整的文档地图 +summary: 链接到所有 OpenClaw 文档的导航中心 +title: 文档导航中心 x-i18n: - generated_at: "2026-04-05T10:09:27Z" + generated_at: "2026-04-23T06:43:24Z" model: gpt-5.4 provider: openai - source_hash: 4998710e3dc8018a50abc41285caac83df4b3bf8aec2e4a7525a0563649eb06c + source_hash: 4bf24887af25cb345834e7f61e33d1ca3595833a42934ae91a87cc0951b3ae10 source_path: start/hubs.md workflow: 15 --- -# 文档中心 +# 文档导航中心 -如果你是 OpenClaw 新用户,请先阅读 [入门指南](/zh-CN/start/getting-started)。 +如果你刚开始接触 OpenClaw,请先阅读 [入门指南](/zh-CN/start/getting-started)。 -使用这些中心页来发现所有页面,包括那些不会出现在左侧导航中的深入解析和参考文档。 +使用这些导航中心来发现每一页文档,包括左侧导航中未显示的深度解析和参考文档。 ## 从这里开始 -- [索引](/zh-CN) +- [Index](/zh-CN) - [入门指南](/zh-CN/start/getting-started) - [新手引导](/zh-CN/start/onboarding) - [设置向导(CLI)](/zh-CN/start/wizard) - [设置](/zh-CN/start/setup) -- [仪表板(本地 Gateway 网关)](http://127.0.0.1:18789/) -- [帮助](/zh-CN/help) +- [Dashboard(本地 Gateway 网关)](http://127.0.0.1:18789/) +- [Help](/zh-CN/help) - [文档目录](/zh-CN/start/docs-directory) - [配置](/zh-CN/gateway/configuration) - [配置示例](/zh-CN/gateway/configuration-examples) -- [OpenClaw 助手](/zh-CN/start/openclaw) -- [展示](/zh-CN/start/showcase) -- [背景故事](/zh-CN/start/lore) +- [OpenClaw assistant](/zh-CN/start/openclaw) +- [Showcase](/zh-CN/start/showcase) +- [Lore](/zh-CN/start/lore) ## 安装 + 更新 @@ -45,7 +45,7 @@ x-i18n: ## 核心概念 -- [架构](/zh-CN/concepts/architecture) +- [Architecture](/zh-CN/concepts/architecture) - [功能](/zh-CN/concepts/features) - [网络中心](/zh-CN/network) - [智能体运行时](/zh-CN/concepts/agent) @@ -56,7 +56,7 @@ x-i18n: - [多智能体路由](/zh-CN/concepts/multi-agent) - [压缩](/zh-CN/concepts/compaction) - [会话](/zh-CN/concepts/session) -- [会话修剪](/zh-CN/concepts/session-pruning) +- [会话裁剪](/zh-CN/concepts/session-pruning) - [会话工具](/zh-CN/concepts/session-tool) - [队列](/zh-CN/concepts/queue) - [斜杠命令](/zh-CN/tools/slash-commands) @@ -69,10 +69,10 @@ x-i18n: - [渠道路由](/zh-CN/channels/channel-routing) - [群组](/zh-CN/channels/groups) - [群组消息](/zh-CN/channels/group-messages) -- [模型故障转移](/zh-CN/concepts/model-failover) +- [模型故障切换](/zh-CN/concepts/model-failover) - [OAuth](/zh-CN/concepts/oauth) -## 提供商 + 入站入口 +## 提供商 + 接入 - [聊天渠道中心](/zh-CN/channels) - [模型提供商中心](/zh-CN/providers/models) @@ -86,7 +86,7 @@ x-i18n: - [QQ Bot](/zh-CN/channels/qqbot) - [iMessage(旧版)](/zh-CN/channels/imessage) - [位置解析](/zh-CN/channels/location) -- [WebChat](/web/webchat) +- [WebChat](/zh-CN/web/webchat) - [Webhooks](/zh-CN/automation/cron-jobs#webhooks) - [Gmail Pub/Sub](/zh-CN/automation/cron-jobs#gmail-pubsub-integration) @@ -97,13 +97,13 @@ x-i18n: - [Gateway 网关配对](/zh-CN/gateway/pairing) - [Gateway 网关锁](/zh-CN/gateway/gateway-lock) - [后台进程](/zh-CN/gateway/background-process) -- [健康检查](/zh-CN/gateway/health) -- [心跳](/zh-CN/gateway/heartbeat) +- [健康状态](/zh-CN/gateway/health) +- [Heartbeat](/zh-CN/gateway/heartbeat) - [Doctor](/zh-CN/gateway/doctor) -- [日志记录](/zh-CN/gateway/logging) +- [日志](/zh-CN/gateway/logging) - [沙箱隔离](/zh-CN/gateway/sandboxing) -- [仪表板](/web/dashboard) -- [Control UI](/web/control-ui) +- [Dashboard](/zh-CN/web/dashboard) +- [Control UI](/zh-CN/web/control-ui) - [远程访问](/zh-CN/gateway/remote) - [远程 Gateway 网关 README](/zh-CN/gateway/remote-gateway-readme) - [Tailscale](/zh-CN/gateway/tailscale) @@ -112,28 +112,28 @@ x-i18n: ## 工具 + 自动化 -- [工具界面](/zh-CN/tools) +- [工具总览](/zh-CN/tools) - [OpenProse](/zh-CN/prose) -- [CLI 参考](/cli) +- [CLI 参考](/zh-CN/cli) - [Exec 工具](/zh-CN/tools/exec) -- [PDF 工具](/tools/pdf) -- [Elevated 模式](/zh-CN/tools/elevated) +- [PDF 工具](/zh-CN/tools/pdf) +- [提升模式](/zh-CN/tools/elevated) - [Cron 作业](/zh-CN/automation/cron-jobs) - [自动化与任务](/zh-CN/automation) -- [思考 + 详细模式](/zh-CN/tools/thinking) +- [Thinking + verbose](/zh-CN/tools/thinking) - [模型](/zh-CN/concepts/models) - [子智能体](/zh-CN/tools/subagents) -- [智能体发送 CLI](/zh-CN/tools/agent-send) -- [终端 UI](/web/tui) +- [Agent send CLI](/zh-CN/tools/agent-send) +- [Terminal UI](/zh-CN/web/tui) - [浏览器控制](/zh-CN/tools/browser) -- [浏览器(Linux 故障排除)](/zh-CN/tools/browser-linux-troubleshooting) -- [投票](/cli/message) +- [Browser(Linux 故障排除)](/zh-CN/tools/browser-linux-troubleshooting) +- [投票](/zh-CN/cli/message) ## 节点、媒体、语音 - [节点概览](/zh-CN/nodes) - [相机](/zh-CN/nodes/camera) -- [图片](/zh-CN/nodes/images) +- [图像](/zh-CN/nodes/images) - [音频](/zh-CN/nodes/audio) - [位置命令](/zh-CN/nodes/location-command) - [语音唤醒](/zh-CN/nodes/voicewake) @@ -147,39 +147,39 @@ x-i18n: - [Android](/zh-CN/platforms/android) - [Windows(WSL2)](/zh-CN/platforms/windows) - [Linux](/zh-CN/platforms/linux) -- [Web 界面](/web) +- [Web 界面](/zh-CN/web) ## macOS 配套应用(高级) - [macOS 开发设置](/zh-CN/platforms/mac/dev-setup) - [macOS 菜单栏](/zh-CN/platforms/mac/menu-bar) - [macOS 语音唤醒](/zh-CN/platforms/mac/voicewake) -- [macOS 语音覆盖层](/zh-CN/platforms/mac/voice-overlay) +- [macOS 语音浮层](/zh-CN/platforms/mac/voice-overlay) - [macOS WebChat](/zh-CN/platforms/mac/webchat) - [macOS Canvas](/zh-CN/platforms/mac/canvas) - [macOS 子进程](/zh-CN/platforms/mac/child-process) -- [macOS 健康检查](/zh-CN/platforms/mac/health) +- [macOS 健康状态](/zh-CN/platforms/mac/health) - [macOS 图标](/zh-CN/platforms/mac/icon) -- [macOS 日志记录](/zh-CN/platforms/mac/logging) +- [macOS 日志](/zh-CN/platforms/mac/logging) - [macOS 权限](/zh-CN/platforms/mac/permissions) -- [macOS 远程](/zh-CN/platforms/mac/remote) +- [macOS 远程访问](/zh-CN/platforms/mac/remote) - [macOS 签名](/zh-CN/platforms/mac/signing) - [macOS Gateway 网关(launchd)](/zh-CN/platforms/mac/bundled-gateway) - [macOS XPC](/zh-CN/platforms/mac/xpc) - [macOS Skills](/zh-CN/platforms/mac/skills) - [macOS Peekaboo](/zh-CN/platforms/mac/peekaboo) -## 扩展 + 插件 +## 插件 -- [插件概览](/zh-CN/tools/plugin) -- [Building Plugins](/zh-CN/plugins/building-plugins) -- [Plugin Manifest](/zh-CN/plugins/manifest) +- [Plugins 概览](/zh-CN/tools/plugin) +- [构建插件](/zh-CN/plugins/building-plugins) +- [插件清单](/zh-CN/plugins/manifest) - [智能体工具](/zh-CN/plugins/building-plugins#registering-agent-tools) - [插件包](/zh-CN/plugins/bundles) - [社区插件](/zh-CN/plugins/community) -- [能力扩展手册](/tools/capability-cookbook) -- [语音通话插件](/zh-CN/plugins/voice-call) -- [Zalo 用户插件](/zh-CN/plugins/zalouser) +- [能力扩展手册](/zh-CN/plugins/architecture) +- [Voice call 插件](/zh-CN/plugins/voice-call) +- [Zalo user 插件](/zh-CN/plugins/zalouser) ## 工作区 + 模板 @@ -203,4 +203,4 @@ x-i18n: - [测试](/zh-CN/reference/test) - [发布策略](/zh-CN/reference/RELEASING) -- [设备型号](/zh-CN/reference/device-models) +- [设备模型](/zh-CN/reference/device-models) diff --git a/docs/zh-CN/start/showcase.md b/docs/zh-CN/start/showcase.md index 34b0a2883..9f2bda9a8 100644 --- a/docs/zh-CN/start/showcase.md +++ b/docs/zh-CN/start/showcase.md @@ -1,27 +1,25 @@ --- description: Real-world OpenClaw projects from the community read_when: - - 在寻找真实的 OpenClaw 使用示例吗 - - 更新社区项目亮点 + - 寻找真实的 OpenClaw 使用示例 + - 更新社区项目精选 summary: 由 OpenClaw 驱动的社区构建项目和集成 title: 展示区 x-i18n: - generated_at: "2026-04-14T13:43:49Z" + generated_at: "2026-04-23T06:43:41Z" model: gpt-5.4 provider: openai - source_hash: 797d0b85c9eca920240c79d870eb9636216714f3eba871c5ebd0f7f40cf7bbf1 + source_hash: 5bf4bd2548709a01ad18331537f804b32c3213139c2234915aa17f7a2638f19f source_path: start/showcase.md workflow: 15 --- - - # 展示区

构建于聊天、终端、浏览器和客厅之中

- OpenClaw 项目不是玩具演示。人们正在从他们已经在使用的渠道中,交付 PR 审查闭环、移动应用、家庭自动化、语音系统、开发工具,以及内存密集型工作流。 + OpenClaw 项目不是玩具演示。人们正在通过他们早已使用的渠道,交付 PR 审查循环、移动应用、家庭自动化、语音系统、开发工具和重度记忆工作流。

观看演示 @@ -30,27 +28,27 @@ x-i18n:
- 原生聊天式构建 - Telegram、WhatsApp、Discord、Beeper、网页聊天,以及以终端为先的工作流。 + 聊天原生构建 + Telegram、WhatsApp、Discord、Beeper、网页聊天,以及终端优先工作流。
真实自动化 预订、购物、支持、报告和浏览器控制,无需等待 API。
- 本地 + 现实世界 - 打印机、扫地机器人、摄像头、健康数据、家庭系统,以及个人知识库。 + 本地 + 物理世界 + 打印机、扫地机器人、摄像头、健康数据、家庭系统和个人知识库。
-**想被推荐展示吗?** 在 [Discord 的 #self-promotion](https://discord.gg/clawd) 中分享你的项目,或在 [X 上 @openclaw](https://x.com/openclaw) 标记我们。 +**想被推荐展示?** 请在 [Discord 的 #self-promotion](https://discord.gg/clawd) 中分享你的项目,或在 [X 上标记 @openclaw](https://x.com/openclaw)。 -

视频

+## 视频

- 如果你想用最短路径从“这是什么?”到“好,我懂了。”,请从这里开始。 + 如果你想用最短路径从“这是什么?”走到“好,我懂了”,就从这里开始。

@@ -71,14 +69,14 @@ x-i18n: