From dbc0dbff546aa06e434d229120e1005ad49454d3 Mon Sep 17 00:00:00 2001 From: "openclaw-docs-i18n[bot]" Date: Wed, 29 Apr 2026 05:43:24 +0000 Subject: [PATCH] chore(i18n): refresh zh-CN translations --- docs/zh-CN/channels/discord.md | 528 ++++++++------- docs/zh-CN/channels/line.md | 72 ++- docs/zh-CN/channels/matrix-migration.md | 286 +++++---- docs/zh-CN/channels/matrix.md | 496 +++++++------- docs/zh-CN/channels/mattermost.md | 189 +++--- docs/zh-CN/channels/msteams.md | 607 +++++++++--------- docs/zh-CN/channels/nextcloud-talk.md | 93 +-- docs/zh-CN/channels/nostr.md | 122 ++-- docs/zh-CN/channels/tlon.md | 165 ++--- docs/zh-CN/channels/twitch.md | 130 ++-- docs/zh-CN/channels/whatsapp.md | 244 +++---- docs/zh-CN/channels/zalo.md | 225 +++---- docs/zh-CN/channels/zalouser.md | 125 ++-- docs/zh-CN/ci.md | 173 ++--- docs/zh-CN/cli/plugins.md | 144 +++-- docs/zh-CN/concepts/messages.md | 140 ++-- docs/zh-CN/gateway/config-channels.md | 299 +++++---- docs/zh-CN/gateway/protocol.md | 454 ++++++------- docs/zh-CN/help/testing.md | 676 ++++++++++---------- docs/zh-CN/plugins/building-plugins.md | 118 ++-- docs/zh-CN/plugins/community.md | 106 +-- docs/zh-CN/plugins/sdk-setup.md | 192 +++--- docs/zh-CN/plugins/sdk-subpaths.md | 331 +++++----- docs/zh-CN/plugins/voice-call.md | 218 +++---- docs/zh-CN/plugins/zalouser.md | 28 +- docs/zh-CN/tools/exec-approvals-advanced.md | 172 ++--- docs/zh-CN/tools/plugin.md | 362 ++++------- 27 files changed, 3331 insertions(+), 3364 deletions(-) diff --git a/docs/zh-CN/channels/discord.md b/docs/zh-CN/channels/discord.md index a4f5b2db3..36abfb2f9 100644 --- a/docs/zh-CN/channels/discord.md +++ b/docs/zh-CN/channels/discord.md @@ -1,65 +1,65 @@ --- read_when: - - 开发 Discord 渠道功能 -summary: Discord 机器人支持状态、功能和配置 + - 正在开发 Discord 渠道功能 +summary: Discord 机器人支持状态、能力和配置 title: Discord x-i18n: - generated_at: "2026-04-29T00:30:33Z" + generated_at: "2026-04-29T05:38:00Z" model: gpt-5.5 provider: openai - source_hash: 2fc2d3b26704ffa0f8e388cde48952ad2e205b9cd09c4873666d25db3a9bd94b + source_hash: f25e1e1ed36d9f6f943cdf155d8cab08f031fcaab67477acf04ea7f18f694ec7 source_path: channels/discord.md workflow: 16 --- -已准备好通过官方 Discord Gateway 网关用于私信和服务器频道。 +已准备好通过官方 Discord Gateway 网关用于私信和公会频道。 - + Discord 私信默认使用配对模式。 - + 原生命令行为和命令目录。 - + 跨渠道诊断和修复流程。 ## 快速设置 -你需要创建一个带机器人的新应用,将机器人添加到你的服务器,并将其与 OpenClaw 配对。我们建议将你的机器人添加到你自己的私有服务器。如果你还没有服务器,请先[创建一个](https://support.discord.com/hc/en-us/articles/204849977-How-do-I-create-a-server)(选择 **Create My Own > For me and my friends**)。 +你需要创建一个带有机器人的新应用,将机器人添加到你的服务器,并将它与 OpenClaw 配对。我们建议把机器人添加到你自己的私人服务器。如果你还没有服务器,[先创建一个](https://support.discord.com/hc/en-us/articles/204849977-How-do-I-create-a-server)(选择 **Create My Own > For me and my friends**)。 - + 前往 [Discord Developer Portal](https://discord.com/developers/applications),然后点击 **New Application**。将其命名为类似 “OpenClaw” 的名称。 - 点击侧边栏中的 **Bot**。将 **Username** 设置为你给 OpenClaw 智能体起的名称。 + 点击侧边栏中的 **Bot**。将 **Username** 设为你给 OpenClaw 智能体起的任意名称。 - + 仍在 **Bot** 页面,向下滚动到 **Privileged Gateway Intents** 并启用: - **Message Content Intent**(必需) - - **Server Members Intent**(推荐;角色允许列表和名称到 ID 匹配需要) + - **Server Members Intent**(推荐;角色 allowlist 和名称到 ID 匹配需要) - **Presence Intent**(可选;仅在需要在线状态更新时需要) - - 回到 **Bot** 页面顶部,点击 **Reset Token**。 + + 回到 **Bot** 页面顶部并点击 **Reset Token**。 - 尽管名称如此,这会生成你的第一个令牌,并没有任何内容被“重置”。 + 尽管名称如此,这会生成你的第一个 token,并没有真正“重置”任何内容。 - 复制令牌并保存在某处。这是你的 **Bot Token**,稍后会用到。 + 复制该 token 并保存到某处。这是你的 **Bot Token**,稍后会用到。 - - 点击侧边栏中的 **OAuth2**。你将生成一个具有正确权限的邀请 URL,用于将机器人添加到你的服务器。 + + 点击侧边栏中的 **OAuth2**。你将生成一个带有正确权限的邀请 URL,用来把机器人添加到你的服务器。 向下滚动到 **OAuth2 URL Generator** 并启用: @@ -77,31 +77,31 @@ x-i18n: - Attach Files - Add Reactions(可选) - 这是普通文本频道的基准权限集合。如果你计划在 Discord 话题中发帖,包括创建或继续话题的论坛或媒体频道工作流,也请启用 **Send Messages in Threads**。 + 这是普通文本频道的基线权限集。如果你计划在 Discord 线程中发帖,包括会创建或继续线程的论坛或媒体频道工作流,也请启用 **Send Messages in Threads**。 复制底部生成的 URL,将其粘贴到浏览器中,选择你的服务器,然后点击 **Continue** 进行连接。现在你应该能在 Discord 服务器中看到你的机器人。 - - 回到 Discord 应用,你需要启用开发者模式,以便复制内部 ID。 + + 回到 Discord 应用,你需要启用开发者模式,这样才能复制内部 ID。 - 1. 点击 **User Settings**(头像旁边的齿轮图标)→ **Advanced** → 开启 **Developer Mode** - 2. 右键点击侧边栏中的 **server icon** → **Copy Server ID** - 3. 右键点击你的 **own avatar** → **Copy User ID** + 1. 点击 **User Settings**(头像旁边的齿轮图标)→ **Advanced** → 打开 **Developer Mode** + 2. 在侧边栏中右键点击你的 **server icon** → **Copy Server ID** + 3. 右键点击你自己的 **own avatar** → **Copy User ID** - 将你的 **Server ID** 和 **User ID** 与 Bot Token 一起保存,你将在下一步把这三项发送给 OpenClaw。 + 将你的 **Server ID** 和 **User ID** 与 Bot Token 一起保存,下一步你会把这三项都发送给 OpenClaw。 - - 要让配对正常工作,Discord 需要允许你的机器人向你发送私信。右键点击你的 **server icon** → **Privacy Settings** → 开启 **Direct Messages**。 + + 为了让配对正常工作,Discord 需要允许你的机器人给你发送私信。右键点击你的 **server icon** → **Privacy Settings** → 打开 **Direct Messages**。 - 这会允许服务器成员(包括机器人)向你发送私信。如果你想通过 Discord 私信使用 OpenClaw,请保持此项启用。如果你只计划使用服务器频道,可以在配对后禁用私信。 + 这会允许服务器成员(包括机器人)向你发送私信。如果你想通过 Discord 私信使用 OpenClaw,请保持此项启用。如果你只计划使用公会频道,可以在配对后禁用私信。 - - 你的 Discord 机器人令牌是一个密钥(类似密码)。在向智能体发送消息之前,请在运行 OpenClaw 的机器上设置它。 + + 你的 Discord 机器人 token 是机密信息(类似密码)。在给智能体发消息之前,先在运行 OpenClaw 的机器上设置它。 ```bash export DISCORD_BOT_TOKEN="YOUR_BOT_TOKEN" @@ -112,19 +112,19 @@ openclaw gateway ``` 如果 OpenClaw 已经作为后台服务运行,请通过 OpenClaw Mac 应用重启它,或停止并重新启动 `openclaw gateway run` 进程。 - 对于托管服务安装,请从存在 `DISCORD_BOT_TOKEN` 的 shell 中运行 `openclaw gateway install`,或将该变量存储在 `~/.openclaw/.env` 中,以便服务在重启后可以解析 env SecretRef。 + 对于托管服务安装,请从存在 `DISCORD_BOT_TOKEN` 的 shell 中运行 `openclaw gateway install`,或将该变量存储在 `~/.openclaw/.env` 中,这样服务在重启后就能解析 env SecretRef。 - + - - 在任何现有渠道(例如 Telegram)与你的 OpenClaw 智能体聊天并告诉它。如果 Discord 是你的第一个渠道,请改用 CLI / 配置标签页。 + + 在任何现有渠道(例如 Telegram)与你的 OpenClaw 智能体聊天并告诉它。如果 Discord 是你的第一个渠道,请改用 CLI / config 标签页。 - > “我已经在配置中设置了 Discord 机器人令牌。请使用 User ID `` 和 Server ID `` 完成 Discord 设置。” + > “我已经在配置中设置了 Discord 机器人 token。请使用 User ID `` 和 Server ID `` 完成 Discord 设置。” - + 如果你更喜欢基于文件的配置,请设置: ```json5 @@ -142,25 +142,25 @@ openclaw gateway } ``` - 默认账户的环境变量回退: + 默认账户的 env 回退: ```bash DISCORD_BOT_TOKEN=... ``` - 支持明文 `token` 值。`channels.discord.token` 也支持跨 env/file/exec 提供商使用 SecretRef 值。请参阅[密钥管理](/zh-CN/gateway/secrets)。 + 支持明文 `token` 值。`channels.discord.token` 也支持跨 env/file/exec 提供商的 SecretRef 值。参见 [Secrets Management](/zh-CN/gateway/secrets)。 - - 等待 Gateway 网关运行,然后在 Discord 中私信你的机器人。它会返回一个配对码。 + + 等到 Gateway 网关运行后,在 Discord 中私信你的机器人。它会返回一个配对码。 - - 将配对码通过你现有的渠道发送给你的智能体: + + 在现有渠道上把配对码发送给你的智能体: > “批准这个 Discord 配对码:``” @@ -182,24 +182,24 @@ openclaw pairing approve discord -令牌解析是账户感知的。配置中的令牌值优先于环境变量回退。`DISCORD_BOT_TOKEN` 仅用于默认账户。 -如果两个已启用的 Discord 账户解析为同一个机器人令牌,OpenClaw 只会为该令牌启动一个 Gateway 网关监视器。配置来源的令牌优先于默认环境变量回退;否则第一个启用的账户胜出,重复账户会被报告为已禁用。 -对于高级出站调用(消息工具/渠道操作),显式的逐调用 `token` 会用于该调用。这适用于发送和读取/探测类操作(例如 read/search/fetch/thread/pins/permissions)。账户策略/重试设置仍来自活动运行时快照中选定的账户。 +Token 解析是账户感知的。配置 token 值优先于 env 回退。`DISCORD_BOT_TOKEN` 仅用于默认账户。 +如果两个已启用的 Discord 账户解析到同一个机器人 token,OpenClaw 只会为该 token 启动一个 Gateway 网关监视器。来自配置的 token 优先于默认 env 回退;否则第一个启用的账户胜出,重复账户会被报告为已禁用。 +对于高级出站调用(message 工具/渠道操作),显式的逐调用 `token` 会用于该调用。这适用于发送和读取/探测风格的操作(例如 read/search/fetch/thread/pins/permissions)。账户策略/重试设置仍来自活动运行时快照中的所选账户。 -## 推荐:设置服务器工作区 +## 推荐:设置公会工作区 -私信正常工作后,你可以将 Discord 服务器设置为完整工作区,其中每个频道都有自己的智能体会话和上下文。对于只有你和你的机器人的私有服务器,建议这样做。 +私信可用后,你可以将 Discord 服务器设置为完整工作区,其中每个频道都有自己的智能体会话和上下文。对于只有你和机器人的私人服务器,推荐这样做。 - - 这会让你的智能体能够在服务器上的任何频道中响应,而不仅限于私信。 + + 这会让你的智能体可以在服务器上的任意频道中响应,而不只是私信。 - - > “将我的 Discord Server ID `` 添加到服务器允许列表” + + > “将我的 Discord Server ID `` 添加到公会 allowlist” - + ```json5 { @@ -222,17 +222,17 @@ openclaw pairing approve discord - - 默认情况下,你的智能体只有在服务器频道中被 @提及时才会响应。对于私有服务器,你可能希望它响应每条消息。 + + 默认情况下,你的智能体只有在公会频道中被 @提及时才会响应。对于私人服务器,你可能希望它响应每条消息。 - 在服务器频道中,普通助手最终回复默认保持私密。可见的 Discord 输出必须通过 `message` 工具显式发送,因此智能体默认可以旁观,并且只在它判断频道回复有用时才发帖。 + 在公会频道中,普通 assistant 最终回复默认保持私有。可见的 Discord 输出必须通过 `message` 工具显式发送,因此智能体可以默认旁观,只在认为频道回复有用时发帖。 - - > “允许我的智能体在这个服务器上响应,而不需要被 @提及” + + > “允许我的智能体在此服务器上无需 @提及也能响应” - - 在你的服务器配置中设置 `requireMention: false`: + + 在你的公会配置中设置 `requireMention: false`: ```json5 { @@ -255,82 +255,82 @@ openclaw pairing approve discord - - 默认情况下,长期记忆(MEMORY.md)只会在私信会话中加载。服务器频道不会自动加载 MEMORY.md。 + + 默认情况下,长期记忆(MEMORY.md)只会在私信会话中加载。公会频道不会自动加载 MEMORY.md。 - - > “当我在 Discord 频道中提问时,如果你需要来自 MEMORY.md 的长期上下文,请使用 memory_search 或 memory_get。” + + > “当我在 Discord 频道中提问时,如果你需要 MEMORY.md 中的长期上下文,请使用 memory_search 或 memory_get。” - - 如果你需要在每个频道中共享上下文,请将稳定说明放入 `AGENTS.md` 或 `USER.md`(它们会注入到每个会话中)。将长期笔记保存在 `MEMORY.md` 中,并在需要时通过记忆工具访问。 + + 如果你需要在每个频道中共享上下文,请将稳定指令放入 `AGENTS.md` 或 `USER.md`(它们会注入到每个会话)。将长期笔记保存在 `MEMORY.md` 中,并按需使用 memory 工具访问它们。 -现在在你的 Discord 服务器上创建一些频道并开始聊天。你的智能体可以看到频道名称,并且每个频道都有自己的隔离会话,因此你可以设置 `#coding`、`#home`、`#research`,或任何适合你工作流的频道。 +现在在你的 Discord 服务器上创建一些频道并开始聊天。你的智能体可以看到频道名称,并且每个频道都有自己的隔离会话,所以你可以设置 `#coding`、`#home`、`#research`,或任何适合你工作流的频道。 ## 运行时模型 - Gateway 网关拥有 Discord 连接。 -- 回复路由是确定性的:Discord 入站回复会回到 Discord。 -- Discord 服务器/频道元数据会作为不受信任的上下文添加到模型提示中,而不是作为用户可见的回复前缀。如果模型将该封套复制回来,OpenClaw 会从出站回复和未来重放上下文中移除复制的元数据。 +- 回复路由是确定性的:Discord 入站会回复到 Discord。 +- Discord 公会/频道元数据会作为不受信任的上下文添加到模型提示中,而不是作为用户可见的回复前缀。如果模型把该包络复制回来,OpenClaw 会从出站回复和未来的重放上下文中剥离复制的元数据。 - 默认情况下(`session.dmScope=main`),直接聊天共享智能体主会话(`agent:main:main`)。 -- 服务器频道是隔离的会话键(`agent::discord:channel:`)。 +- 公会频道是隔离的会话键(`agent::discord:channel:`)。 - 群组私信默认会被忽略(`channels.discord.dm.groupEnabled=false`)。 -- 原生斜杠命令在隔离的命令会话中运行(`agent::discord:slash:`),同时仍携带 `CommandTargetSessionKey` 到路由后的对话会话。 -- 仅文本的 cron/heartbeat 公告投递到 Discord 时,会使用最终助手可见答案一次。媒体和结构化组件负载在智能体发出多个可投递负载时仍保持多消息形式。 +- 原生斜杠命令在隔离的命令会话中运行(`agent::discord:slash:`),同时仍携带 `CommandTargetSessionKey` 到被路由的对话会话。 +- 仅文本的 cron/heartbeat 到 Discord 的公告投递会使用一次最终的 assistant 可见答案。媒体和结构化组件载荷在智能体发出多个可投递载荷时仍保持多消息。 ## 论坛频道 -Discord 论坛和媒体频道只接受话题帖子。OpenClaw 支持两种创建方式: +Discord 论坛和媒体频道只接受线程帖子。OpenClaw 支持两种创建方式: -- 向论坛父频道(`channel:`)发送消息以自动创建话题。话题标题使用消息的第一行非空内容。 -- 使用 `openclaw message thread create` 直接创建话题。不要为论坛频道传递 `--message-id`。 +- 向论坛父频道(`channel:`)发送消息以自动创建线程。线程标题使用你消息中的第一个非空行。 +- 使用 `openclaw message thread create` 直接创建线程。不要为论坛频道传递 `--message-id`。 -示例:发送到论坛父频道以创建话题 +示例:发送到论坛父频道以创建线程 ```bash openclaw message send --channel discord --target channel: \ --message "Topic title\nBody of the post" ``` -示例:显式创建论坛话题 +示例:显式创建论坛线程 ```bash openclaw message thread create --channel discord --target channel: \ --thread-name "Topic title" --message "Body of the post" ``` -论坛父频道不接受 Discord 组件。如果你需要组件,请发送到话题本身(`channel:`)。 +论坛父频道不接受 Discord 组件。如果你需要组件,请发送到线程本身(`channel:`)。 ## 交互式组件 -OpenClaw 支持用于智能体消息的 Discord components v2 容器。请使用带有 `components` 载荷的消息工具。交互结果会作为普通入站消息路由回智能体,并遵循现有 Discord `replyToMode` 设置。 +OpenClaw 支持用于智能体消息的 Discord components v2 容器。请使用带有 `components` 负载的消息工具。交互结果会作为普通入站消息路由回智能体,并遵循现有 Discord `replyToMode` 设置。 -支持的块: +支持的区块: - `text`、`section`、`separator`、`actions`、`media-gallery`、`file` - 操作行最多允许 5 个按钮或一个选择菜单 - 选择类型:`string`、`user`、`role`、`mentionable`、`channel` -默认情况下,components 只能使用一次。设置 `components.reusable=true` 可允许按钮、选择菜单和表单被多次使用,直到它们过期。 +默认情况下,组件只能使用一次。设置 `components.reusable=true` 可允许按钮、选择菜单和表单被多次使用,直到它们过期。 要限制谁可以点击按钮,请在该按钮上设置 `allowedUsers`(Discord 用户 ID、标签或 `*`)。配置后,不匹配的用户会收到一条临时拒绝消息。 -`/model` 和 `/models` 斜杠命令会打开交互式模型选择器,其中包含提供商、模型和兼容运行时下拉菜单,以及提交步骤。`/models add` 已弃用,现在会返回弃用消息,而不是从聊天中注册模型。选择器回复是临时的,只有调用用户可以使用。 +`/model` 和 `/models` 斜杠命令会打开一个交互式模型选择器,其中包含提供商、模型和兼容运行时下拉菜单,以及一个提交步骤。`/models add` 已弃用,现在会返回弃用消息,而不是从聊天中注册模型。选择器回复是临时的,且只有调用用户可以使用它。 文件附件: -- `file` 块必须指向附件引用(`attachment://`) +- `file` 区块必须指向附件引用(`attachment://`) - 通过 `media`/`path`/`filePath` 提供附件(单个文件);多个文件请使用 `media-gallery` -- 当上传名称应匹配附件引用时,使用 `filename` 覆盖上传名称 +- 当上传名称应与附件引用匹配时,使用 `filename` 覆盖上传名称 模态表单: -- 添加最多包含 5 个字段的 `components.modal` +- 添加包含最多 5 个字段的 `components.modal` - 字段类型:`text`、`checkbox`、`radio`、`select`、`role-select`、`user-select` - OpenClaw 会自动添加触发按钮 @@ -391,7 +391,7 @@ OpenClaw 支持用于智能体消息的 Discord components v2 容器。请使用 ## 访问控制和路由 - + `channels.discord.dmPolicy` 控制私信访问(旧版:`channels.discord.dm.policy`): - `pairing`(默认) @@ -399,40 +399,40 @@ OpenClaw 支持用于智能体消息的 Discord components v2 容器。请使用 - `open`(要求 `channels.discord.allowFrom` 包含 `"*"`;旧版:`channels.discord.dm.allowFrom`) - `disabled` - 如果私信策略不是开放的,未知用户会被阻止(或在 `pairing` 模式中被提示配对)。 + 如果私信策略不是开放的,未知用户会被阻止(或在 `pairing` 模式下被提示配对)。 多账号优先级: - `channels.discord.accounts.default.allowFrom` 仅适用于 `default` 账号。 - - 具名账号在自身 `allowFrom` 未设置时继承 `channels.discord.allowFrom`。 - - 具名账号不会继承 `channels.discord.accounts.default.allowFrom`。 + - 命名账号在自身未设置 `allowFrom` 时继承 `channels.discord.allowFrom`。 + - 命名账号不会继承 `channels.discord.accounts.default.allowFrom`。 - 投递的私信目标格式: + 用于投递的私信目标格式: - `user:` - `<@id>` 提及 - 裸数字 ID 存在歧义,除非提供了显式的用户/渠道目标类型,否则会被拒绝。 + 纯数字 ID 存在歧义,会被拒绝,除非提供了明确的用户/渠道目标类型。 - - 服务器处理由 `channels.discord.groupPolicy` 控制: + + Guild 处理由 `channels.discord.groupPolicy` 控制: - `open` - `allowlist` - `disabled` - 当 `channels.discord` 存在时,安全基线是 `allowlist`。 + 当 `channels.discord` 存在时,安全基线为 `allowlist`。 `allowlist` 行为: - - 服务器必须匹配 `channels.discord.guilds`(优先使用 `id`,也接受 slug) - - 可选发送者允许列表:`users`(建议使用稳定 ID)和 `roles`(仅角色 ID);如果配置了任意一个,发送者匹配 `users` 或 `roles` 时即被允许 - - 默认禁用直接名称/标签匹配;仅在破窗兼容模式下启用 `channels.discord.dangerouslyAllowNameMatching: true` + - guild 必须匹配 `channels.discord.guilds`(首选 `id`,也接受 slug) + - 可选发送者允许列表:`users`(推荐使用稳定 ID)和 `roles`(仅角色 ID);如果任一项已配置,发送者匹配 `users` 或 `roles` 时会被允许 + - 默认禁用直接名称/标签匹配;仅在破除限制的兼容模式下启用 `channels.discord.dangerouslyAllowNameMatching: true` - `users` 支持名称/标签,但 ID 更安全;使用名称/标签条目时,`openclaw security audit` 会发出警告 - - 如果某个服务器配置了 `channels`,未列出的渠道会被拒绝 - - 如果某个服务器没有 `channels` 块,该允许列表服务器中的所有渠道都会被允许 + - 如果 guild 配置了 `channels`,未列出的渠道会被拒绝 + - 如果 guild 没有 `channels` 区块,则该允许列表 guild 中的所有渠道都被允许 示例: @@ -458,20 +458,20 @@ OpenClaw 支持用于智能体消息的 Discord components v2 容器。请使用 } ``` - 如果你只设置 `DISCORD_BOT_TOKEN` 而未创建 `channels.discord` 块,运行时回退会是 `groupPolicy="allowlist"`(日志中会有警告),即使 `channels.defaults.groupPolicy` 是 `open`。 + 如果你只设置了 `DISCORD_BOT_TOKEN`,并且没有创建 `channels.discord` 区块,运行时回退会是 `groupPolicy="allowlist"`(日志中会有警告),即使 `channels.defaults.groupPolicy` 是 `open`。 - - 服务器消息默认受提及门控。 + + Guild 消息默认受提及门控。 提及检测包括: - 显式机器人提及 - - 配置的提及模式(`agents.list[].groupChat.mentionPatterns`,回退为 `messages.groupChat.mentionPatterns`) + - 已配置的提及模式(`agents.list[].groupChat.mentionPatterns`,回退为 `messages.groupChat.mentionPatterns`) - 受支持情况下的隐式回复机器人行为 - `requireMention` 按服务器/渠道配置(`channels.discord.guilds...`)。 + `requireMention` 按 guild/渠道配置(`channels.discord.guilds...`)。 `ignoreOtherMentions` 可选择丢弃提及其他用户/角色但未提及机器人的消息(不包括 @everyone/@here)。 群组私信: @@ -484,7 +484,7 @@ OpenClaw 支持用于智能体消息的 Discord components v2 容器。请使用 ### 基于角色的智能体路由 -使用 `bindings[].match.roles` 按角色 ID 将 Discord 服务器成员路由到不同智能体。基于角色的绑定仅接受角色 ID,并在点对点或父点对点绑定之后、仅服务器绑定之前评估。如果某个绑定还设置了其他匹配字段(例如 `peer` + `guildId` + `roles`),所有配置字段都必须匹配。 +使用 `bindings[].match.roles` 按角色 ID 将 Discord guild 成员路由到不同智能体。基于角色的绑定仅接受角色 ID,并在对等或父对等绑定之后、仅 guild 绑定之前求值。如果某个绑定还设置了其他匹配字段(例如 `peer` + `guildId` + `roles`),所有已配置字段都必须匹配。 ```json5 { @@ -508,13 +508,13 @@ OpenClaw 支持用于智能体消息的 Discord components v2 容器。请使用 } ``` -## 原生命令和命令认证 +## 原生命令和命令身份验证 - `commands.native` 默认为 `"auto"`,并为 Discord 启用。 - 按渠道覆盖:`channels.discord.commands.native`。 -- `commands.native=false` 会显式清除先前注册的 Discord 原生命令。 -- 原生命令认证使用与普通消息处理相同的 Discord 允许列表/策略。 -- 命令仍可能在 Discord UI 中对未授权用户可见;执行时仍会强制执行 OpenClaw 认证,并返回 “not authorized”。 +- `commands.native=false` 会显式清除之前注册的 Discord 原生命令。 +- 原生命令身份验证使用与普通消息处理相同的 Discord 允许列表/策略。 +- 对未授权用户,命令仍可能在 Discord UI 中可见;执行时仍会强制执行 OpenClaw 身份验证,并返回“未授权”。 请参阅[斜杠命令](/zh-CN/tools/slash-commands)了解命令目录和行为。 @@ -525,8 +525,8 @@ OpenClaw 支持用于智能体消息的 Discord components v2 容器。请使用 ## 功能详情 - - Discord 支持智能体输出中的回复标签: + + Discord 在智能体输出中支持回复标签: - `[[reply_to_current]]` - `[[reply_to:]]` @@ -538,18 +538,18 @@ OpenClaw 支持用于智能体消息的 Discord components v2 容器。请使用 - `all` - `batched` - 注意:`off` 会禁用隐式回复串联。显式 `[[reply_to_*]]` 标签仍会被遵循。 - `first` 始终将隐式原生回复引用附加到该轮的第一条出站 Discord 消息。 - `batched` 仅在入站轮次是多条消息的防抖批次时,才附加 Discord 的隐式原生回复引用。这在你主要希望为含糊的突发聊天使用原生回复,而不是为每个单消息轮次都使用原生回复时很有用。 + 注意:`off` 会禁用隐式回复线程化。显式 `[[reply_to_*]]` 标签仍会被遵循。 + `first` 始终将隐式原生回复引用附加到本轮的第一条出站 Discord 消息。 + `batched` 仅当入站轮次是多条消息的防抖批次时,才附加 Discord 的隐式原生回复引用。这在你主要希望为含糊的突发聊天提供原生回复,而不是为每个单消息轮次都提供原生回复时很有用。 - 消息 ID 会出现在上下文/历史记录中,以便智能体可以定位特定消息。 + 消息 ID 会暴露在上下文/历史记录中,因此智能体可以定位特定消息。 - - OpenClaw 可以通过发送临时消息并在文本到达时编辑它来流式传输草稿回复。`channels.discord.streaming` 接受 `off`(默认)| `partial` | `block` | `progress`。`progress` 在 Discord 上映射为 `partial`;`streamMode` 是旧版别名,会自动迁移。 + + OpenClaw 可以通过发送临时消息并在文本到达时编辑该消息来流式传输草稿回复。`channels.discord.streaming` 接受 `off`(默认)| `partial` | `block` | `progress`。`progress` 在 Discord 上映射到 `partial`;`streamMode` 是旧版别名,会自动迁移。 - 默认保持 `off`,因为当多个机器人或 Gateway 网关共享账号时,Discord 预览编辑会很快触发速率限制。 + 默认保持 `off`,因为当多个机器人或 Gateway 网关共享一个账号时,Discord 预览编辑会很快触发速率限制。 ```json5 { @@ -566,19 +566,19 @@ OpenClaw 支持用于智能体消息的 Discord components v2 容器。请使用 } ``` - - `partial` 会在 token 到达时编辑单条预览消息。 - - `block` 会发出草稿大小的分块(使用 `draftChunk` 调整大小和断点,受限于 `textChunkLimit`)。 - - 媒体、错误和显式回复最终消息会取消待处理的预览编辑。 + - `partial` 会在令牌到达时编辑一条预览消息。 + - `block` 会发出草稿大小的分块(使用 `draftChunk` 调整大小和断点,并被限制到 `textChunkLimit`)。 + - 媒体、错误和显式回复的最终消息会取消待处理的预览编辑。 - `streaming.preview.toolProgress`(默认 `true`)控制工具/进度更新是否复用预览消息。 - 预览流式传输仅支持文本;媒体回复会回退到普通投递。当显式启用 `block` 流式传输时,OpenClaw 会跳过预览流,以避免双重流式传输。 + 预览流式传输仅支持文本;媒体回复会回退到普通投递。当显式启用 `block` 流式传输时,OpenClaw 会跳过预览流,以避免重复流式传输。 - - 服务器历史上下文: + + Guild 历史上下文: - - `channels.discord.historyLimit` 默认 `20` + - `channels.discord.historyLimit` 默认值 `20` - 回退:`messages.groupChat.historyLimit` - `0` 禁用 @@ -589,26 +589,26 @@ OpenClaw 支持用于智能体消息的 Discord components v2 容器。请使用 线程行为: - - Discord 线程按渠道会话路由,并继承父渠道配置,除非被覆盖。 - - 线程会话继承父渠道的会话级 `/model` 选择,作为仅模型回退;线程本地 `/model` 选择仍优先,且除非启用转录继承,否则不会复制父转录历史记录。 - - `channels.discord.thread.inheritParent`(默认 `false`)让新的自动线程选择从父转录播种。按账号覆盖位于 `channels.discord.accounts..thread.inheritParent` 下。 + - Discord 线程会作为渠道会话路由,并继承父渠道配置,除非被覆盖。 + - 线程会话会将父渠道的会话级 `/model` 选择作为仅模型回退继承;线程本地 `/model` 选择仍优先,并且不会复制父会话记录历史,除非已启用会话记录继承。 + - `channels.discord.thread.inheritParent`(默认 `false`)会让新的自动线程选择从父会话记录播种。按账号覆盖位于 `channels.discord.accounts..thread.inheritParent` 下。 - 消息工具反应可以解析 `user:` 私信目标。 - `guilds..channels..requireMention: false` 会在回复阶段激活回退期间保留。 - 渠道主题会作为**不可信**上下文注入。允许列表控制谁可以触发智能体,而不是完整的补充上下文脱敏边界。 + 渠道主题会作为**不受信任**的上下文注入。允许列表会限制谁可以触发智能体,但不是完整的补充上下文脱敏边界。 - - Discord 可以将线程绑定到会话目标,使该线程中的后续消息继续路由到同一会话(包括子智能体会话)。 + + Discord 可以将线程绑定到会话目标,因此该线程中的后续消息会继续路由到同一会话(包括子智能体会话)。 命令: - `/focus ` 将当前/新线程绑定到子智能体/会话目标 - `/unfocus` 移除当前线程绑定 - - `/agents` 显示活跃运行和绑定状态 - - `/session idle ` 检查/更新聚焦绑定的不活跃自动取消聚焦 - - `/session max-age ` 检查/更新聚焦绑定的硬性最大时长 + - `/agents` 显示活动运行和绑定状态 + - `/session idle ` 查看/更新聚焦绑定的不活动自动取消聚焦时间 + - `/session max-age ` 查看/更新聚焦绑定的硬性最大时长 配置: @@ -634,20 +634,20 @@ OpenClaw 支持用于智能体消息的 Discord components v2 容器。请使用 } ``` - 注意事项: + 备注: - `session.threadBindings.*` 设置全局默认值。 - `channels.discord.threadBindings.*` 覆盖 Discord 行为。 - - `spawnSubagentSessions` 必须为 true,才能为 `sessions_spawn({ thread: true })` 自动创建/绑定线程。 - - `spawnAcpSessions` 必须为 true,才能为 ACP(`/acp spawn ... --thread ...` 或 `sessions_spawn({ runtime: "acp", thread: true })`)自动创建/绑定线程。 - - 如果某个账号禁用了线程绑定,则 `/focus` 和相关线程绑定操作不可用。 + - `spawnSubagentSessions` 必须为 true,才能为 `sessions_spawn({ thread: true })` 自动创建/绑定话题。 + - `spawnAcpSessions` 必须为 true,才能为 ACP(`/acp spawn ... --thread ...` 或 `sessions_spawn({ runtime: "acp", thread: true })`)自动创建/绑定话题。 + - 如果某个账号禁用了话题绑定,`/focus` 和相关的话题绑定操作将不可用。 - 请参阅 [子智能体](/zh-CN/tools/subagents)、[ACP 智能体](/zh-CN/tools/acp-agents) 和 [配置参考](/zh-CN/gateway/configuration-reference)。 + 参见[子智能体](/zh-CN/tools/subagents)、[ACP 智能体](/zh-CN/tools/acp-agents)和[配置参考](/zh-CN/gateway/configuration-reference)。 - 对于稳定的“始终在线”ACP 工作区,请配置面向 Discord 对话的顶层类型化 ACP 绑定。 + 对于稳定的“始终在线”ACP 工作区,请配置顶层类型化 ACP 绑定,并将其指向 Discord 对话。 配置路径: @@ -701,49 +701,49 @@ OpenClaw 支持用于智能体消息的 Discord components v2 容器。请使用 } ``` - 说明: + 注意: - - `/acp spawn codex --bind here` 会就地绑定当前频道或线程,并让后续消息继续使用同一个 ACP 会话。线程消息会继承父频道绑定。 - - 在已绑定的频道或线程中,`/new` 和 `/reset` 会就地重置同一个 ACP 会话。临时线程绑定可在生效期间覆盖目标解析。 - - 只有在 OpenClaw 需要通过 `--thread auto|here` 创建/绑定子线程时,才需要 `spawnAcpSessions`。 + - `/acp spawn codex --bind here` 会就地绑定当前频道或话题,并让未来消息保持在同一个 ACP 会话中。话题消息会继承父频道绑定。 + - 在已绑定的频道或话题中,`/new` 和 `/reset` 会就地重置同一个 ACP 会话。临时话题绑定在激活期间可以覆盖目标解析。 + - 仅当 OpenClaw 需要通过 `--thread auto|here` 创建/绑定子话题时,才需要 `spawnAcpSessions`。 - 请参阅 [ACP 智能体](/zh-CN/tools/acp-agents) 了解绑定行为详情。 + 有关绑定行为详情,请参见 [ACP 智能体](/zh-CN/tools/acp-agents)。 - - 每个服务器的回应通知模式: + + 按服务器设置反应通知模式: - `off` - `own`(默认) - `all` - `allowlist`(使用 `guilds..users`) - 回应事件会转换为系统事件,并附加到已路由的 Discord 会话。 + 反应事件会被转换为系统事件,并附加到已路由的 Discord 会话。 - - `ackReaction` 会在 OpenClaw 处理入站消息时发送一个确认表情符号。 + + `ackReaction` 会在 OpenClaw 处理传入消息时发送一个确认表情符号。 解析顺序: - `channels.discord.accounts..ackReaction` - `channels.discord.ackReaction` - `messages.ackReaction` - - 智能体身份表情符号回退(`agents.list[].identity.emoji`,否则为 "👀") + - 智能体身份表情符号回退值(`agents.list[].identity.emoji`,否则为 "👀") - 说明: + 注意: - - Discord 接受 Unicode 表情符号或自定义表情符号名称。 - - 使用 `""` 可为某个频道或账号禁用该回应。 + - Discord 接受 Unicode 表情符号或自定义表情名称。 + - 使用 `""` 可禁用某个渠道或账号的反应。 默认启用由渠道发起的配置写入。 - 这会影响 `/config set|unset` 流程(当命令功能启用时)。 + 这会影响 `/config set|unset` 流程(当命令功能已启用时)。 禁用: @@ -760,7 +760,7 @@ OpenClaw 支持用于智能体消息的 Discord components v2 容器。请使用 - 使用 `channels.discord.proxy` 通过 HTTP(S) 代理路由 Discord 网关 WebSocket 流量和启动时的 REST 查询(应用 ID + allowlist 解析)。 + 使用 `channels.discord.proxy` 通过 HTTP(S) 代理路由 Discord Gateway 网关 WebSocket 流量和启动时的 REST 查询(应用 ID + allowlist 解析)。 ```json5 { @@ -772,7 +772,7 @@ OpenClaw 支持用于智能体消息的 Discord components v2 容器。请使用 } ``` - 每账号覆盖: + 按账号覆盖: ```json5 { @@ -806,19 +806,19 @@ OpenClaw 支持用于智能体消息的 Discord components v2 容器。请使用 } ``` - 说明: + 注意: - allowlist 可以使用 `pk:` - - 只有当 `channels.discord.dangerouslyAllowNameMatching: true` 时,才会按名称/slug 匹配成员显示名称 + - 仅当 `channels.discord.dangerouslyAllowNameMatching: true` 时,才会按名称/slug 匹配成员显示名称 - 查询使用原始消息 ID,并受时间窗口限制 - - 如果查询失败,代理消息会被视为机器人消息并被丢弃,除非 `allowBots=true` + - 如果查询失败,代理消息会被视为 bot 消息并丢弃,除非 `allowBots=true` - 当你设置状态或活动字段,或启用自动在线状态时,会应用在线状态更新。 + 当你设置 Status 或活动字段,或启用自动在线状态时,会应用在线状态更新。 - 仅状态示例: + 仅 Status 示例: ```json5 { @@ -830,7 +830,7 @@ OpenClaw 支持用于智能体消息的 Discord components v2 容器。请使用 } ``` - 活动示例(自定义状态是默认活动类型): + 活动示例(自定义 Status 是默认活动类型): ```json5 { @@ -843,7 +843,7 @@ OpenClaw 支持用于智能体消息的 Discord components v2 容器。请使用 } ``` - 直播示例: + 流式传输示例: ```json5 { @@ -859,12 +859,12 @@ OpenClaw 支持用于智能体消息的 Discord components v2 容器。请使用 活动类型映射: - - 0: 正在玩 - - 1: 正在直播(需要 `activityUrl`) - - 2: 正在听 - - 3: 正在观看 - - 4: 自定义(使用活动文本作为状态内容;表情符号可选) - - 5: 正在竞赛 + - 0:正在玩 + - 1:正在流式传输(需要 `activityUrl`) + - 2:正在听 + - 3:正在观看 + - 4:自定义(使用活动文本作为 Status 状态;表情符号可选) + - 5:正在竞赛 自动在线状态示例(运行时健康信号): @@ -883,7 +883,7 @@ OpenClaw 支持用于智能体消息的 Discord components v2 容器。请使用 } ``` - 自动在线状态会将运行时可用性映射到 Discord 状态:healthy => online,degraded 或 unknown => idle,exhausted 或 unavailable => dnd。可选文本覆盖: + 自动在线状态会将运行时可用性映射到 Discord Status:healthy => online,degraded 或 unknown => idle,exhausted 或 unavailable => dnd。可选文本覆盖: - `autoPresence.healthyText` - `autoPresence.degradedText` @@ -892,7 +892,7 @@ OpenClaw 支持用于智能体消息的 Discord components v2 容器。请使用 - Discord 支持在私信中通过按钮处理审批,也可以选择在发起审批的频道中发布审批提示。 + Discord 支持在私信中基于按钮处理审批,并且可以选择在发起渠道中发布审批提示。 配置路径: @@ -901,51 +901,53 @@ OpenClaw 支持用于智能体消息的 Discord components v2 容器。请使用 - `channels.discord.execApprovals.target`(`dm` | `channel` | `both`,默认:`dm`) - `agentFilter`、`sessionFilter`、`cleanupAfterResolve` - 当 `enabled` 未设置或为 `"auto"`,且可以从 `execApprovals.approvers` 或 `commands.ownerAllowFrom` 解析出至少一个审批人时,Discord 会自动启用原生 exec 审批。Discord 不会从频道 `allowFrom`、旧版 `dm.allowFrom` 或私信 `defaultTo` 推断 exec 审批人。设置 `enabled: false` 可明确禁用 Discord 作为原生审批客户端。 + 当 `enabled` 未设置或为 `"auto"`,并且至少能从 `execApprovals.approvers` 或 `commands.ownerAllowFrom` 解析出一个审批人时,Discord 会自动启用原生 exec 审批。Discord 不会从渠道 `allowFrom`、旧版 `dm.allowFrom` 或私信 `defaultTo` 推断 exec 审批人。设置 `enabled: false` 可明确禁用 Discord 作为原生审批客户端。 - 对于 `/diagnostics` 和 `/export-trajectory` 等敏感的仅所有者群组命令,OpenClaw 会私下发送审批提示和最终结果。当调用方所有者有 Discord 所有者路由时,它会先尝试 Discord 私信;如果不可用,则回退到 `commands.ownerAllowFrom` 中第一个可用的所有者路由,例如 Telegram。 + 对于 `/diagnostics` 和 `/export-trajectory` 等敏感的仅 owner 群组命令,OpenClaw 会私下发送审批提示和最终结果。当调用的 owner 有 Discord owner 路由时,它会先尝试 Discord 私信;如果不可用,则回退到 `commands.ownerAllowFrom` 中第一个可用的 owner 路由,例如 Telegram。 - 当 `target` 为 `channel` 或 `both` 时,审批提示会在频道中可见。只有解析出的审批人可以使用按钮;其他用户会收到临时拒绝。审批提示包含命令文本,因此只应在可信频道中启用频道投递。如果无法从会话键派生频道 ID,OpenClaw 会回退到私信投递。 + 当 `target` 为 `channel` 或 `both` 时,审批提示会在频道中可见。只有已解析的审批人可以使用按钮;其他用户会收到临时拒绝。审批提示包含命令文本,因此只应在受信任的频道中启用频道投递。如果无法从会话键派生频道 ID,OpenClaw 会回退到私信投递。 - Discord 也会渲染其他聊天渠道使用的共享审批按钮。原生 Discord 适配器主要增加审批人私信路由和频道扇出。 - 当这些按钮存在时,它们是主要审批 UX;OpenClaw - 只有在工具结果说明聊天审批不可用,或手动审批是唯一路径时, + Discord 还会渲染其他聊天渠道使用的共享审批按钮。原生 Discord 适配器主要添加审批人私信路由和频道扇出。 + 当这些按钮存在时,它们是主要审批 UX;只有当工具结果表明聊天审批不可用,或手动审批是唯一路径时,OpenClaw 才应包含手动 `/approve` 命令。 + 如果 Discord 原生审批运行时未激活,OpenClaw 会保持本地确定性的 `/approve ` 提示可见。如果 + 运行时已激活,但原生卡片无法投递到任何目标,OpenClaw 会发送同一聊天回退通知,其中包含待处理审批中的确切 `/approve` + 命令。 - Gateway 网关认证和审批解析遵循共享 Gateway 网关客户端契约(`plugin:` ID 通过 `plugin.approval.resolve` 解析;其他 ID 通过 `exec.approval.resolve` 解析)。审批默认在 30 分钟后过期。 + Gateway 网关身份验证和审批解析遵循共享 Gateway 网关客户端契约(`plugin:` ID 通过 `plugin.approval.resolve` 解析;其他 ID 通过 `exec.approval.resolve` 解析)。审批默认在 30 分钟后过期。 - 请参阅 [Exec 审批](/zh-CN/tools/exec-approvals)。 + 参见 [Exec 审批](/zh-CN/tools/exec-approvals)。 -## 工具和操作门控 +## 工具和操作门禁 -Discord 消息操作包括消息、频道管理、审核、在线状态和元数据操作。 +Discord 消息操作包括消息传递、频道管理、审核、在线状态和元数据操作。 核心示例: -- 消息:`sendMessage`、`readMessages`、`editMessage`、`deleteMessage`、`threadReply` -- 回应:`react`、`reactions`、`emojiList` +- 消息传递:`sendMessage`、`readMessages`、`editMessage`、`deleteMessage`、`threadReply` +- 反应:`react`、`reactions`、`emojiList` - 审核:`timeout`、`kick`、`ban` - 在线状态:`setPresence` -`event-create` 操作接受可选的 `image` 参数(URL 或本地文件路径),用于设置计划事件封面图。 +`event-create` 操作接受可选的 `image` 参数(URL 或本地文件路径),用于设置预定事件封面图。 -操作门控位于 `channels.discord.actions.*` 下。 +操作门禁位于 `channels.discord.actions.*` 下。 -默认门控行为: +默认门禁行为: -| 操作组 | 默认 | -| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ---- | -| reactions, messages, threads, pins, polls, search, memberInfo, roleInfo, channelInfo, channels, voiceStatus, events, stickers, emojiUploads, stickerUploads, permissions | 启用 | -| roles | 禁用 | -| moderation | 禁用 | -| presence | 禁用 | +| 操作组 | 默认值 | +| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------ | +| reactions, messages, threads, pins, polls, search, memberInfo, roleInfo, channelInfo, channels, voiceStatus, events, stickers, emojiUploads, stickerUploads, permissions | 已启用 | +| roles | 已禁用 | +| moderation | 已禁用 | +| presence | 已禁用 | ## 组件 v2 UI -OpenClaw 使用 Discord 组件 v2 处理 exec 审批和跨上下文标记。Discord 消息操作也可以接受用于自定义 UI 的 `components`(高级;需要通过 discord 工具构造组件载荷),而旧版 `embeds` 仍然可用,但不推荐。 +OpenClaw 使用 Discord 组件 v2 处理 exec 审批和跨上下文标记。Discord 消息操作也可以接受 `components` 来实现自定义 UI(高级;需要通过 discord 工具构造组件载荷),而旧版 `embeds` 仍然可用,但不推荐使用。 - `channels.discord.ui.components.accentColor` 设置 Discord 组件容器使用的强调色(十六进制)。 - 使用 `channels.discord.accounts..ui.components.accentColor` 按账号设置。 @@ -973,12 +975,12 @@ Discord 有两个不同的语音表面:实时**语音频道**(连续对话 ### 语音频道 -设置检查清单: +设置清单: 1. 在 Discord Developer Portal 中启用 Message Content Intent。 -2. 当使用角色/用户 allowlist 时,启用 Server Members Intent。 -3. 使用 `bot` 和 `applications.commands` 范围邀请机器人。 -4. 在目标语音频道中授予 Connect、Speak、Send Messages 和 Read Message History 权限。 +2. 使用角色/用户 allowlist 时,启用 Server Members Intent。 +3. 使用 `bot` 和 `applications.commands` 作用域邀请 bot。 +4. 在目标语音频道中授予 Connect、Speak、Send Messages 和 Read Message History。 5. 启用原生命令(`commands.native` 或 `channels.discord.commands.native`)。 6. 配置 `channels.discord.voice`。 @@ -1017,36 +1019,36 @@ Discord 有两个不同的语音表面:实时**语音频道**(连续对话 } ``` -注意: +说明: - `voice.tts` 仅覆盖语音播放的 `messages.tts`。 -- `voice.model` 仅覆盖用于 Discord 语音渠道响应的 LLM。留空则继承路由后的智能体模型。 -- STT 使用 `tools.media.audio`;`voice.model` 不影响转写。 -- 语音转写轮次会从 Discord `allowFrom`(或 `dm.allowFrom`)派生所有者状态;非所有者说话者无法访问仅限所有者的工具(例如 `gateway` 和 `cron`)。 -- 语音默认启用;设置 `channels.discord.voice.enabled=false` 可禁用语音运行时和 `GuildVoiceStates` Gateway 网关 intent。 -- `channels.discord.intents.voiceStates` 可以显式覆盖语音状态 intent 订阅。留空则该 intent 跟随 `voice.enabled`。 +- `voice.model` 仅覆盖用于 Discord 语音渠道响应的 LLM。保持未设置即可继承路由后的智能体模型。 +- STT 使用 `tools.media.audio`;`voice.model` 不影响转录。 +- 语音转录轮次从 Discord `allowFrom`(或 `dm.allowFrom`)派生所有者状态;非所有者发言者不能访问仅限所有者的工具(例如 `gateway` 和 `cron`)。 +- 语音默认启用;设置 `channels.discord.voice.enabled=false` 可禁用语音运行时和 `GuildVoiceStates` Gateway 网关意图。 +- `channels.discord.intents.voiceStates` 可以显式覆盖语音状态意图订阅。保持未设置可让该意图跟随 `voice.enabled`。 - `voice.daveEncryption` 和 `voice.decryptionFailureTolerance` 会透传给 `@discordjs/voice` 加入选项。 - 如果未设置,`@discordjs/voice` 的默认值为 `daveEncryption=true` 和 `decryptionFailureTolerance=24`。 -- OpenClaw 还会监视接收解密失败,并在短时间窗口内反复失败后通过离开并重新加入语音渠道自动恢复。 -- 如果更新后接收日志反复显示 `DecryptionFailed(UnencryptedWhenPassthroughDisabled)`,请收集依赖报告和日志。内置的 `@discordjs/voice` 版本线包含来自 discord.js PR #11449 的上游 padding 修复,该修复关闭了 discord.js issue #11419。 +- OpenClaw 还会监视接收解密失败,并在短时间窗口内重复失败后通过离开并重新加入语音渠道来自动恢复。 +- 如果更新后接收日志反复显示 `DecryptionFailed(UnencryptedWhenPassthroughDisabled)`,请收集依赖报告和日志。内置的 `@discordjs/voice` 版本线包含来自 discord.js PR #11449 的上游填充修复,该修复关闭了 discord.js issue #11419。 语音渠道流水线: - Discord PCM 捕获会转换为 WAV 临时文件。 - `tools.media.audio` 处理 STT,例如 `openai/gpt-4o-mini-transcribe`。 -- 转写文本会通过常规 Discord 入口和路由发送。 -- 设置 `voice.model` 时,它仅覆盖此语音渠道轮次的响应 LLM。 -- `voice.tts` 会合并覆盖 `messages.tts`;生成的音频会在已加入的渠道中播放。 +- 转录文本会通过常规 Discord 入口和路由发送。 +- 设置 `voice.model` 后,它仅覆盖此语音渠道轮次的响应 LLM。 +- `voice.tts` 会合并到 `messages.tts` 之上;生成的音频会在已加入的渠道中播放。 -凭证按组件解析:`voice.model` 使用 LLM 路由认证,`tools.media.audio` 使用 STT 认证,`messages.tts`/`voice.tts` 使用 TTS 认证。 +凭证按组件解析:`voice.model` 的 LLM 路由认证、`tools.media.audio` 的 STT 认证,以及 `messages.tts`/`voice.tts` 的 TTS 认证。 ### 语音消息 -Discord 语音消息会显示波形预览,并且需要 OGG/Opus 音频。OpenClaw 会自动生成波形,但需要 Gateway 网关主机上有 `ffmpeg` 和 `ffprobe` 来检查和转换。 +Discord 语音消息会显示波形预览,并要求使用 OGG/Opus 音频。OpenClaw 会自动生成波形,但需要 Gateway 网关主机上有 `ffmpeg` 和 `ffprobe` 来检查和转换。 -- 提供一个**本地文件路径**(URL 会被拒绝)。 -- 省略文本内容(Discord 会拒绝同一 payload 中同时包含文本和语音消息)。 -- 接受任意音频格式;OpenClaw 会按需转换为 OGG/Opus。 +- 提供**本地文件路径**(URL 会被拒绝)。 +- 省略文本内容(Discord 会拒绝在同一 payload 中同时包含文本和语音消息)。 +- 接受任何音频格式;OpenClaw 会按需转换为 OGG/Opus。 ```bash message(action="send", channel="discord", target="channel:123", path="/path/to/audio.mp3", asVoice=true) @@ -1055,22 +1057,22 @@ message(action="send", channel="discord", target="channel:123", path="/path/to/a ## 故障排除 - + - 启用 Message Content Intent - - 当你依赖用户/成员解析时启用 Server Members Intent - - 更改 intents 后重启 Gateway 网关 + - 当你依赖用户/成员解析时,启用 Server Members Intent + - 更改意图后重启 Gateway 网关 - + - 验证 `groupPolicy` - - 验证 `channels.discord.guilds` 下的 guild allowlist - - 如果存在 guild `channels` 映射,则只允许列出的渠道 + - 验证 `channels.discord.guilds` 下的服务器允许列表 + - 如果存在服务器 `channels` 映射,则只允许列出的渠道 - 验证 `requireMention` 行为和提及模式 - 有用检查: + 有用的检查: ```bash openclaw doctor @@ -1080,35 +1082,29 @@ openclaw logs --follow - + 常见原因: - - `groupPolicy="allowlist"` 但没有匹配的 guild/channel allowlist - - `requireMention` 配置在错误位置(必须位于 `channels.discord.guilds` 或渠道条目下) - - 发送者被 guild/channel `users` allowlist 阻止 + - `groupPolicy="allowlist"` 但没有匹配的服务器/渠道允许列表 + - `requireMention` 配置在了错误位置(必须位于 `channels.discord.guilds` 或渠道条目下) + - 发送者被服务器/渠道 `users` 允许列表阻止 - + 典型日志: - - `Listener DiscordMessageListener timed out after 30000ms for event MESSAGE_CREATE` - `Slow listener detected ...` - - `discord inbound worker timed out after ...` + - `stuck session: sessionKey=agent:...:discord:... state=processing ...` - 监听器预算旋钮: + Carbon Gateway 网关队列旋钮: - 单账号:`channels.discord.eventQueue.listenerTimeout` - 多账号:`channels.discord.accounts..eventQueue.listenerTimeout` + - 这只控制 Carbon Gateway 网关监听器工作,而不是智能体轮次生命周期 - Worker 运行超时旋钮: - - - 单账号:`channels.discord.inboundWorker.runTimeoutMs` - - 多账号:`channels.discord.accounts..inboundWorker.runTimeoutMs` - - 默认:`1800000`(30 分钟);设置为 `0` 可禁用 - - 推荐基线: + Discord 不会对排队的智能体轮次应用渠道拥有的超时。消息监听器会立即移交,排队的 Discord 运行会保持每个会话的顺序,直到会话/工具/运行时生命周期完成或中止工作。 ```json5 { @@ -1119,9 +1115,6 @@ openclaw logs --follow eventQueue: { listenerTimeout: 120000, }, - inboundWorker: { - runTimeoutMs: 1800000, - }, }, }, }, @@ -1129,54 +1122,52 @@ openclaw logs --follow } ``` - 使用 `eventQueue.listenerTimeout` 处理较慢的监听器设置;仅当你想为排队的智能体轮次设置单独安全阀时,才使用 `inboundWorker.runTimeoutMs`。 - - - OpenClaw 会在连接前获取 Discord `/gateway/bot` 元数据。短暂失败会回退到 Discord 的默认 Gateway 网关 URL,并在日志中进行速率限制。 + + OpenClaw 会在连接前获取 Discord `/gateway/bot` 元数据。临时失败会回退到 Discord 的默认 Gateway 网关 URL,并在日志中进行速率限制。 元数据超时旋钮: - 单账号:`channels.discord.gatewayInfoTimeoutMs` - 多账号:`channels.discord.accounts..gatewayInfoTimeoutMs` - 配置未设置时的环境变量回退:`OPENCLAW_DISCORD_GATEWAY_INFO_TIMEOUT_MS` - - 默认:`30000`(30 秒),最大:`120000` + - 默认值:`30000`(30 秒),最大值:`120000` - + `channels status --probe` 权限检查仅适用于数字渠道 ID。 - 如果你使用 slug 键,运行时匹配仍可工作,但 probe 无法完整验证权限。 + 如果你使用 slug 键,运行时匹配仍可工作,但 probe 无法完全验证权限。 - + - 私信已禁用:`channels.discord.dm.enabled=false` - 私信策略已禁用:`channels.discord.dmPolicy="disabled"`(旧版:`channels.discord.dm.policy`) - - 在 `pairing` 模式下等待配对批准 + - 在 `pairing` 模式中等待配对批准 - - 默认会忽略由机器人发出的消息。 + + 默认情况下,会忽略机器人编写的消息。 - 如果你设置 `channels.discord.allowBots=true`,请使用严格的提及和 allowlist 规则来避免循环行为。 - 建议使用 `channels.discord.allowBots="mentions"`,仅接受提及该机器人的机器人消息。 + 如果你设置了 `channels.discord.allowBots=true`,请使用严格的提及和允许列表规则来避免循环行为。 + 优先使用 `channels.discord.allowBots="mentions"`,仅接受提及该机器人的机器人消息。 - + - - 保持 OpenClaw 为当前版本(`openclaw update`),以便包含 Discord 语音接收恢复逻辑 - - 确认 `channels.discord.voice.daveEncryption=true`(默认值) + - 保持 OpenClaw 为当前版本(`openclaw update`),以便具备 Discord 语音接收恢复逻辑 + - 确认 `channels.discord.voice.daveEncryption=true`(默认) - 从 `channels.discord.voice.decryptionFailureTolerance=24`(上游默认值)开始,仅在需要时调整 - - 观察日志中的: + - 查看日志中的: - `discord voice: DAVE decrypt failures detected` - `discord voice: repeated decrypt failures; attempting rejoin` - - 如果自动重新加入后失败仍然持续,收集日志并与 [discord.js #11419](https://github.com/discordjs/discord.js/issues/11419) 和 [discord.js #11449](https://github.com/discordjs/discord.js/pull/11449) 中的上游 DAVE 接收历史进行对比 + - 如果自动重新加入后失败仍持续,请收集日志,并与 [discord.js #11419](https://github.com/discordjs/discord.js/issues/11419) 和 [discord.js #11449](https://github.com/discordjs/discord.js/pull/11449) 中的上游 DAVE 接收历史进行对比 @@ -1185,16 +1176,15 @@ openclaw logs --follow 主要参考:[配置参考 - Discord](/zh-CN/gateway/config-channels#discord)。 - + - 启动/认证:`enabled`、`token`、`accounts.*`、`allowBots` - 策略:`groupPolicy`、`dm.*`、`guilds.*`、`guilds.*.channels.*` - 命令:`commands.native`、`commands.useAccessGroups`、`configWrites`、`slashCommand.*` - 事件队列:`eventQueue.listenerTimeout`(监听器预算)、`eventQueue.maxQueueSize`、`eventQueue.maxConcurrency` -- 入站 worker:`inboundWorker.runTimeoutMs` - Gateway 网关元数据:`gatewayInfoTimeoutMs` - 回复/历史:`replyToMode`、`historyLimit`、`dmHistoryLimit`、`dms.*.historyLimit` -- 发送:`textChunkLimit`、`chunkMode`、`maxLinesPerMessage` +- 投递:`textChunkLimit`、`chunkMode`、`maxLinesPerMessage` - 流式传输:`streaming`(旧版别名:`streamMode`)、`streaming.preview.toolProgress`、`draftChunk`、`blockStreaming`、`blockStreamingCoalesce` - 媒体/重试:`mediaMaxMb`(限制出站 Discord 上传,默认 `100MB`)、`retry` - 操作:`actions.*` @@ -1206,27 +1196,27 @@ openclaw logs --follow ## 安全与运维 -- 将机器人 token 视为密钥(在受监管环境中首选 `DISCORD_BOT_TOKEN`)。 +- 将机器人令牌视为机密(在受监管环境中优先使用 `DISCORD_BOT_TOKEN`)。 - 授予最小权限的 Discord 权限。 -- 如果命令部署/状态过期,请重启 Gateway 网关,并使用 `openclaw channels status --probe` 重新检查。 +- 如果命令部署/状态已过期,请重启 Gateway 网关并使用 `openclaw channels status --probe` 重新检查。 ## 相关 - + 将 Discord 用户配对到 Gateway 网关。 - - 群聊和 allowlist 行为。 + + 群聊和允许列表行为。 - + 将入站消息路由到智能体。 - + 威胁模型和加固。 - - 将 guild 和渠道映射到智能体。 + + 将服务器和渠道映射到智能体。 原生命令行为。 diff --git a/docs/zh-CN/channels/line.md b/docs/zh-CN/channels/line.md index db2fbac51..e7637a208 100644 --- a/docs/zh-CN/channels/line.md +++ b/docs/zh-CN/channels/line.md @@ -2,32 +2,41 @@ read_when: - 你想将 OpenClaw 连接到 LINE - 你需要 LINE 网络钩子 + 凭证设置 - - 你想要 LINE 专用消息选项 + - 你想要 LINE 专用的消息选项 summary: LINE Messaging API 插件设置、配置和使用 title: 行 x-i18n: - generated_at: "2026-04-28T11:46:03Z" + generated_at: "2026-04-29T05:38:17Z" model: gpt-5.5 provider: openai - source_hash: 12afbb8d4e85a7865e25d916c8c46b374333c9583dca1e9063f6f393ed7f7e1a + source_hash: e9f06d882f1e8d2a758e50459fadefd77796a68c28f63bef5790eb1b540c17d1 source_path: channels/line.md workflow: 16 --- -LINE 通过 LINE Messaging API 连接到 OpenClaw。该插件在 Gateway 网关上作为 webhook 接收器运行,并使用你的渠道访问令牌 + 渠道密钥进行身份验证。 +LINE 通过 LINE Messaging API 连接到 OpenClaw。该插件在 Gateway 网关上作为 webhook +接收器运行,并使用你的 channel access token + channel secret 进行 +身份验证。 -Status:内置插件。支持私信、群聊、媒体、位置、Flex 消息、模板消息和快速回复。不支持回应和线程。 +Status:内置插件。支持私信、群聊、媒体、位置、Flex +消息、template messages 和 quick replies。不支持表情回应和线程。 ## 内置插件 -在当前 OpenClaw 版本中,LINE 作为内置插件提供,因此普通打包构建不需要单独安装。 +在当前 OpenClaw 版本中,LINE 作为内置插件提供,因此正常的 +打包构建不需要单独安装。 -如果你使用的是较旧的构建,或排除了 LINE 的自定义安装,请手动安装: +如果你使用的是较旧构建,或是不包含 LINE 的自定义安装,请在发布后安装 +当前 npm 包: ```bash openclaw plugins install @openclaw/line ``` +如果 npm 报告 OpenClaw 拥有的包已弃用或缺失,请使用 +当前打包的 OpenClaw 构建或本地检出,直到 npm 包发布节奏 +跟上。 + 本地检出(从 git 仓库运行时): ```bash @@ -47,12 +56,14 @@ openclaw plugins install ./path/to/local/line-plugin https://gateway-host/line/webhook ``` -Gateway 网关会响应 LINE 的 webhook 验证(GET)和入站事件(POST)。如果你需要自定义路径,请设置 `channels.line.webhookPath` 或 `channels.line.accounts..webhookPath`,并相应更新 URL。 +Gateway 网关会响应 LINE 的 webhook 验证(GET)和入站事件(POST)。 +如果需要自定义路径,请设置 `channels.line.webhookPath` 或 +`channels.line.accounts..webhookPath`,并相应更新 URL。 -安全注意事项: +安全说明: -- LINE 签名验证依赖 body(对原始 body 执行 HMAC),因此 OpenClaw 会在验证前应用严格的预认证 body 限制和超时。 -- OpenClaw 会从已验证的原始请求字节处理 webhook 事件。为保障签名完整性安全,上游中间件转换后的 `req.body` 值会被忽略。 +- LINE 签名验证依赖正文(对原始正文执行 HMAC),因此 OpenClaw 会在验证前应用严格的预认证正文限制和超时。 +- OpenClaw 会处理来自已验证原始请求字节的 webhook 事件。为保证签名完整性安全,会忽略上游中间件转换后的 `req.body` 值。 ## 配置 @@ -76,7 +87,7 @@ Gateway 网关会响应 LINE 的 webhook 验证(GET)和入站事件(POST - `LINE_CHANNEL_ACCESS_TOKEN` - `LINE_CHANNEL_SECRET` -令牌/密钥文件: +Token/secret 文件: ```json5 { @@ -89,7 +100,7 @@ Gateway 网关会响应 LINE 的 webhook 验证(GET)和入站事件(POST } ``` -`tokenFile` 和 `secretFile` 必须指向常规文件。符号链接会被拒绝。 +`tokenFile` 和 `secretFile` 必须指向普通文件。符号链接会被拒绝。 多个账号: @@ -111,7 +122,8 @@ Gateway 网关会响应 LINE 的 webhook 验证(GET)和入站事件(POST ## 访问控制 -私信默认使用配对。未知发送者会收到一个配对码,并且在获批前其消息会被忽略。 +私信默认使用配对。未知发送者会收到一个配对码,并且其 +消息会被忽略,直到获得批准。 ```bash openclaw pairing list line @@ -123,9 +135,9 @@ openclaw pairing approve line - `channels.line.dmPolicy`:`pairing | allowlist | open | disabled` - `channels.line.allowFrom`:允许发送私信的 LINE 用户 ID - `channels.line.groupPolicy`:`allowlist | open | disabled` -- `channels.line.groupAllowFrom`:允许在群组中发送消息的 LINE 用户 ID +- `channels.line.groupAllowFrom`:允许发送群组消息的 LINE 用户 ID - 按群组覆盖:`channels.line.groups..allowFrom` -- 运行时注意事项:如果完全缺少 `channels.line`,运行时会回退到 `groupPolicy="allowlist"` 进行群组检查(即使设置了 `channels.defaults.groupPolicy`)。 +- 运行时说明:如果 `channels.line` 完全缺失,运行时会回退到 `groupPolicy="allowlist"` 来进行群组检查(即使设置了 `channels.defaults.groupPolicy`)。 LINE ID 区分大小写。有效 ID 如下: @@ -136,14 +148,18 @@ LINE ID 区分大小写。有效 ID 如下: ## 消息行为 - 文本会按 5000 个字符分块。 -- Markdown 格式会被移除;代码块和表格会在可能时转换为 Flex 卡片。 -- 流式响应会被缓冲;当智能体工作时,LINE 会收到带加载动画的完整分块。 +- Markdown 格式会被剥离;代码块和表格会在可能时转换为 Flex + 卡片。 +- 流式响应会被缓冲;在智能体工作时,LINE 会收到带有加载 + 动画的完整分块。 - 媒体下载受 `channels.line.mediaMaxMb` 限制(默认 10)。 -- 入站媒体在传递给智能体之前会保存到 `~/.openclaw/media/inbound/` 下,与其他内置渠道插件使用的共享媒体存储保持一致。 +- 入站媒体会先保存到 `~/.openclaw/media/inbound/`,然后再传递给 + 智能体,这与其他内置渠道插件使用的共享媒体存储一致。 ## 渠道数据(富消息) -使用 `channelData.line` 发送快速回复、位置、Flex 卡片或模板消息。 +使用 `channelData.line` 发送 quick replies、位置、Flex 卡片或 template +messages。 ```json5 { @@ -176,7 +192,7 @@ LINE ID 区分大小写。有效 ID 如下: } ``` -LINE 插件还提供一个用于 Flex 消息预设的 `/card` 命令: +LINE 插件还提供用于 Flex 消息预设的 `/card` 命令: ``` /card info "Welcome" "Thanks for joining!" @@ -186,8 +202,8 @@ LINE 插件还提供一个用于 Flex 消息预设的 `/card` 命令: LINE 支持 ACP(Agent Communication Protocol)对话绑定: -- `/acp spawn --bind here` 将当前 LINE 聊天绑定到 ACP 会话,而不会创建子线程。 -- 已配置的 ACP 绑定和活跃的会话绑定 ACP 会话在 LINE 上的工作方式与其他对话渠道相同。 +- `/acp spawn --bind here` 将当前 LINE 聊天绑定到 ACP 会话,而不创建子线程。 +- 已配置的 ACP 绑定和活跃的对话绑定 ACP 会话在 LINE 上的工作方式与其他对话渠道相同。 详见 [ACP 智能体](/zh-CN/tools/acp-agents)。 @@ -199,15 +215,17 @@ LINE 插件支持通过智能体消息工具发送图片、视频和音频文件 - **视频**:发送时带有显式预览和内容类型处理。 - **音频**:作为 LINE 音频消息发送。 -出站媒体 URL 必须是公开 HTTPS URL。OpenClaw 会在将 URL 交给 LINE 之前验证目标主机名,并拒绝 local loopback、链路本地和私有网络目标。 +出站媒体 URL 必须是公开 HTTPS URL。OpenClaw 会在将 URL 交给 LINE 前验证目标主机名,并拒绝 local loopback、链路本地和私有网络目标。 当 LINE 专用路径不可用时,通用媒体发送会回退到现有的仅图片路由。 ## 故障排除 -- **Webhook 验证失败:** 确保 webhook URL 使用 HTTPS,并且 `channelSecret` 与 LINE console 匹配。 -- **没有入站事件:** 确认 webhook 路径与 `channels.line.webhookPath` 匹配,并且 LINE 可以访问 Gateway 网关。 -- **媒体下载错误:** 如果媒体超过默认限制,请提高 `channels.line.mediaMaxMb`。 +- **Webhook 验证失败:**确保 webhook URL 使用 HTTPS,并且 + `channelSecret` 与 LINE console 匹配。 +- **没有入站事件:**确认 webhook 路径与 `channels.line.webhookPath` + 匹配,并且 LINE 可以访问 Gateway 网关。 +- **媒体下载错误:**如果媒体超过默认限制,请提高 `channels.line.mediaMaxMb`。 ## 相关 diff --git a/docs/zh-CN/channels/matrix-migration.md b/docs/zh-CN/channels/matrix-migration.md index 8c68ff9d7..5de5cdeff 100644 --- a/docs/zh-CN/channels/matrix-migration.md +++ b/docs/zh-CN/channels/matrix-migration.md @@ -2,88 +2,88 @@ read_when: - 升级现有的 Matrix 安装 - 迁移加密的 Matrix 历史记录和设备状态 -summary: OpenClaw 如何原地升级先前的 Matrix 插件,包括加密状态恢复限制以及手动恢复步骤。 +summary: OpenClaw 如何就地升级旧版 Matrix 插件,包括加密状态恢复限制和手动恢复步骤。 title: Matrix 迁移 x-i18n: - generated_at: "2026-04-27T10:58:17Z" - model: gpt-5.4 + generated_at: "2026-04-29T05:38:09Z" + model: gpt-5.5 provider: openai - source_hash: 8bc9b875fef0ae08978061a9fc7cbb076617009d79487ca8329e03076103b32c + source_hash: fff409eef1b7da7be4b63d8459a62b8365a04adf989f271a2f2c4aef46e90716 source_path: channels/matrix-migration.md - workflow: 15 + workflow: 16 --- 从先前公开的 `matrix` 插件升级到当前实现。 -对大多数用户来说,升级会原地进行: +对大多数用户来说,升级会原地完成: -- 插件仍然是 `@openclaw/matrix` -- 渠道仍然是 `matrix` -- 你的配置仍然位于 `channels.matrix` -- 缓存的凭证仍然位于 `~/.openclaw/credentials/matrix/` -- 运行时状态仍然位于 `~/.openclaw/matrix/` +- 插件仍为 `@openclaw/matrix` +- 渠道仍为 `matrix` +- 你的配置仍位于 `channels.matrix` 下 +- 缓存的凭证仍位于 `~/.openclaw/credentials/matrix/` 下 +- 运行时状态仍位于 `~/.openclaw/matrix/` 下 -你不需要重命名配置键,也不需要用新名称重新安装插件。 +你无需重命名配置键,也无需用新名称重新安装插件。 -## 迁移会自动执行的内容 +## 迁移会自动执行什么 当 Gateway 网关启动时,以及当你运行 [`openclaw doctor --fix`](/zh-CN/gateway/doctor) 时,OpenClaw 会尝试自动修复旧的 Matrix 状态。 -在任何可执行的 Matrix 迁移步骤更改磁盘状态之前,OpenClaw 都会创建或复用一个专用的恢复快照。 +在任何可执行的 Matrix 迁移步骤修改磁盘状态之前,OpenClaw 会创建或复用一个有针对性的恢复快照。 -当你使用 `openclaw update` 时,具体触发方式取决于 OpenClaw 的安装方式: +当你使用 `openclaw update` 时,确切触发方式取决于 OpenClaw 的安装方式: - 源码安装会在更新流程中运行 `openclaw doctor --fix`,然后默认重启 Gateway 网关 -- 包管理器安装会更新软件包,运行一次非交互式的 Doctor 检查,然后依赖默认的 Gateway 网关重启,以便在启动时完成 Matrix 迁移 -- 如果你使用 `openclaw update --no-restart`,那么依赖启动的 Matrix 迁移会被推迟,直到你之后运行 `openclaw doctor --fix` 并重启 Gateway 网关 +- 包管理器安装会更新软件包,运行一次非交互式 Doctor 检查,然后依赖默认的 Gateway 网关重启,让启动流程完成 Matrix 迁移 +- 如果你使用 `openclaw update --no-restart`,由启动支持的 Matrix 迁移会推迟到你稍后运行 `openclaw doctor --fix` 并重启 Gateway 网关时执行 -自动迁移包括: +自动迁移涵盖: - 在 `~/Backups/openclaw-migrations/` 下创建或复用迁移前快照 - 复用你缓存的 Matrix 凭证 -- 保持相同的账户选择和 `channels.matrix` 配置 -- 将最旧的扁平 Matrix 同步存储移动到当前按账户划分的位置 -- 当可以安全解析目标账户时,将最旧的扁平 Matrix 加密存储移动到当前按账户划分的位置 -- 当旧的 rust 加密存储中本地存在该密钥时,从中提取先前保存的 Matrix 房间密钥备份解密密钥 -- 当访问令牌之后发生变化时,针对相同的 Matrix 账户、homeserver 和用户,复用现有最完整的令牌哈希存储根目录 -- 当 Matrix 访问令牌变化但账户/设备身份保持不变时,扫描同级令牌哈希存储根目录以查找待恢复的加密状态元数据 -- 在下一次 Matrix 启动时,将备份的房间密钥恢复到新的加密存储中 +- 保持相同的账号选择和 `channels.matrix` 配置 +- 将最旧的扁平 Matrix 同步存储移动到当前按账号划分的位置 +- 当目标账号可以安全解析时,将最旧的扁平 Matrix 加密存储移动到当前按账号划分的位置 +- 当本地存在先前保存的 Matrix 房间密钥备份解密密钥时,从旧的 Rust 加密存储中提取该密钥 +- 当访问令牌后续发生变化时,为同一个 Matrix 账号、homeserver 和用户复用最完整的现有令牌哈希存储根目录 +- 当 Matrix 访问令牌发生变化但账号/设备身份保持不变时,扫描同级令牌哈希存储根目录,查找待处理的加密状态恢复元数据 +- 在下一次 Matrix 启动时,将已备份的房间密钥恢复到新的加密存储中 -快照细节: +快照详情: -- 成功创建快照后,OpenClaw 会在 `~/.openclaw/matrix/migration-snapshot.json` 写入一个标记文件,这样后续启动和修复过程就可以复用同一个归档。 +- OpenClaw 会在快照成功后将标记文件写入 `~/.openclaw/matrix/migration-snapshot.json`,以便后续启动和修复流程可以复用同一个归档。 - 这些自动 Matrix 迁移快照只备份配置和状态(`includeWorkspace: false`)。 -- 如果 Matrix 目前只有警告级别的迁移状态,例如 `userId` 或 `accessToken` 仍然缺失,OpenClaw 暂时不会创建快照,因为此时还没有可执行的 Matrix 更改。 -- 如果快照步骤失败,OpenClaw 会跳过本次运行的 Matrix 迁移,而不是在没有恢复点的情况下更改状态。 +- 如果 Matrix 只有仅警告的迁移状态,例如因为仍缺少 `userId` 或 `accessToken`,OpenClaw 暂时不会创建快照,因为没有可执行的 Matrix 变更。 +- 如果快照步骤失败,OpenClaw 会跳过该次运行的 Matrix 迁移,而不是在没有恢复点的情况下修改状态。 -关于多账户升级: +关于多账号升级: -- 最旧的扁平 Matrix 存储(`~/.openclaw/matrix/bot-storage.json` 和 `~/.openclaw/matrix/crypto/`)来自单存储布局,因此 OpenClaw 只能将它迁移到一个已解析的 Matrix 账户目标中 -- 已经按账户划分的旧版 Matrix 存储会针对每个已配置的 Matrix 账户分别检测和准备 +- 最旧的扁平 Matrix 存储(`~/.openclaw/matrix/bot-storage.json` 和 `~/.openclaw/matrix/crypto/`)来自单一存储布局,因此 OpenClaw 只能将其迁移到一个已解析的 Matrix 账号目标 +- 已经按账号划分的旧版 Matrix 存储会按配置的 Matrix 账号逐个检测并准备 -## 迁移无法自动执行的内容 +## 迁移无法自动完成什么 -先前公开的 Matrix 插件**不会**自动创建 Matrix 房间密钥备份。它会持久化本地加密状态并请求设备验证,但并不能保证你的房间密钥已经备份到 homeserver。 +先前公开的 Matrix 插件**不会**自动创建 Matrix 房间密钥备份。它会持久化本地加密状态并请求设备验证,但不保证你的房间密钥已备份到 homeserver。 -这意味着某些启用了加密的安装只能部分迁移。 +这意味着某些加密安装只能部分迁移。 OpenClaw 无法自动恢复: -- 从未备份过、只存在于本地的房间密钥 -- 当 `homeserver`、`userId` 或 `accessToken` 仍不可用,导致尚无法解析目标 Matrix 账户时的加密状态 -- 当配置了多个 Matrix 账户但未设置 `channels.matrix.defaultAccount` 时,对单个共享扁平 Matrix 存储的自动迁移 +- 从未备份过的仅本地房间密钥 +- 当目标 Matrix 账号因 `homeserver`、`userId` 或 `accessToken` 仍不可用而暂时无法解析时的加密状态 +- 当配置了多个 Matrix 账号但未设置 `channels.matrix.defaultAccount` 时,对一个共享扁平 Matrix 存储的自动迁移 - 固定到仓库路径而不是标准 Matrix 软件包的自定义插件路径安装 -- 当旧存储中有已备份的密钥,但本地未保留解密密钥时,缺失的恢复密钥 +- 当旧存储有已备份密钥但没有在本地保留解密密钥时缺失的恢复密钥 当前警告范围: -- 自定义 Matrix 插件路径安装会同时在 Gateway 网关启动和 `openclaw doctor` 中提示 +- 自定义 Matrix 插件路径安装会同时由 Gateway 网关启动和 `openclaw doctor` 暴露 -如果你的旧安装包含从未备份过、只保存在本地的加密历史记录,那么升级后,一些较早的加密消息可能仍然无法读取。 +如果你的旧安装中有从未备份过的仅本地加密历史记录,升级后部分较旧的加密消息可能仍无法读取。 -## 推荐的升级流程 +## 推荐升级流程 1. 正常更新 OpenClaw 和 Matrix 插件。 - 优先使用普通的 `openclaw update`,不要加 `--no-restart`,这样启动时就能立即完成 Matrix 迁移。 + 优先使用不带 `--no-restart` 的普通 `openclaw update`,这样启动流程可以立即完成 Matrix 迁移。 2. 运行: ```bash @@ -93,47 +93,47 @@ OpenClaw 无法自动恢复: 如果 Matrix 有可执行的迁移工作,Doctor 会先创建或复用迁移前快照,并打印归档路径。 3. 启动或重启 Gateway 网关。 -4. 检查当前验证状态和备份状态: +4. 检查当前验证和备份状态: ```bash openclaw matrix verify status openclaw matrix verify backup status ``` -5. 将你要修复的 Matrix 账户的恢复密钥放入账户专用的环境变量中。对于单个默认账户,使用 `MATRIX_RECOVERY_KEY` 即可。对于多个账户,每个账户使用一个变量,例如 `MATRIX_RECOVERY_KEY_ASSISTANT`,并在命令中添加 `--account assistant`。 +5. 将你正在修复的 Matrix 账号的恢复密钥放入按账号区分的环境变量。对于单个默认账号,`MATRIX_RECOVERY_KEY` 即可。对于多个账号,请为每个账号使用一个变量,例如 `MATRIX_RECOVERY_KEY_ASSISTANT`,并在命令中添加 `--account assistant`。 -6. 如果 OpenClaw 提示需要恢复密钥,请为对应账户运行命令: +6. 如果 OpenClaw 告诉你需要恢复密钥,请为匹配的账号运行命令: ```bash printf '%s\n' "$MATRIX_RECOVERY_KEY" | openclaw matrix verify backup restore --recovery-key-stdin printf '%s\n' "$MATRIX_RECOVERY_KEY_ASSISTANT" | openclaw matrix verify backup restore --recovery-key-stdin --account assistant ``` -7. 如果此设备仍未验证,请为对应账户运行命令: +7. 如果此设备仍未验证,请为匹配的账号运行命令: ```bash printf '%s\n' "$MATRIX_RECOVERY_KEY" | openclaw matrix verify device --recovery-key-stdin printf '%s\n' "$MATRIX_RECOVERY_KEY_ASSISTANT" | openclaw matrix verify device --recovery-key-stdin --account assistant ``` - 如果恢复密钥被接受且备份可用,但 `Cross-signing verified` - 仍然是 `no`,请从另一个 Matrix 客户端完成自我验证: + 如果恢复密钥已接受且备份可用,但 `Cross-signing verified` + 仍为 `no`,请从另一个 Matrix 客户端完成自验证: ```bash openclaw matrix verify self ``` - 在另一个 Matrix 客户端中接受请求,比较表情符号或十进制数字, - 只有在它们匹配时才输入 `yes`。只有在 `Cross-signing verified` 变为 `yes` - 后,该命令才会成功退出。 + 在另一个 Matrix 客户端中接受请求,比较表情符号或小数, + 只有匹配时才输入 `yes`。该命令仅在 + `Cross-signing verified` 变为 `yes` 后成功退出。 -8. 如果你打算放弃无法恢复的旧历史记录,并希望为未来消息建立新的备份基线,请运行: +8. 如果你有意放弃无法恢复的旧历史记录,并希望为未来消息建立新的备份基线,请运行: ```bash openclaw matrix verify backup reset --yes ``` -9. 如果服务器端还没有密钥备份,请为未来恢复创建一个: +9. 如果尚不存在服务器端密钥备份,请为未来恢复创建一个: ```bash openclaw matrix verify bootstrap @@ -141,14 +141,14 @@ OpenClaw 无法自动恢复: ## 加密迁移的工作方式 -加密迁移是一个两阶段过程: +加密迁移是一个两阶段流程: -1. 如果加密迁移可执行,启动过程或 `openclaw doctor --fix` 会创建或复用迁移前快照。 -2. 启动过程或 `openclaw doctor --fix` 会通过当前激活的 Matrix 插件安装来检查旧的 Matrix 加密存储。 -3. 如果找到了备份解密密钥,OpenClaw 会将其写入新的恢复密钥流程,并将房间密钥恢复标记为待处理。 -4. 在下一次 Matrix 启动时,OpenClaw 会自动将备份的房间密钥恢复到新的加密存储中。 +1. 如果加密迁移可执行,启动流程或 `openclaw doctor --fix` 会创建或复用迁移前快照。 +2. 启动流程或 `openclaw doctor --fix` 会通过当前活跃的 Matrix 插件安装检查旧的 Matrix 加密存储。 +3. 如果找到备份解密密钥,OpenClaw 会将其写入新的恢复密钥流程,并将房间密钥恢复标记为待处理。 +4. 在下一次 Matrix 启动时,OpenClaw 会自动将已备份的房间密钥恢复到新的加密存储中。 -如果旧存储报告存在从未备份过的房间密钥,OpenClaw 会发出警告,而不是假装恢复已经成功。 +如果旧存储报告存在从未备份过的房间密钥,OpenClaw 会发出警告,而不是假装恢复成功。 ## 常见消息及其含义 @@ -156,189 +156,201 @@ OpenClaw 无法自动恢复: `Matrix plugin upgraded in place.` -- 含义:检测到了旧的磁盘 Matrix 状态,并已将其迁移到当前布局。 -- 该怎么做:如果同一输出中没有其他警告,则无需操作。 +- 含义:检测到旧的磁盘 Matrix 状态,并已迁移到当前布局。 +- 操作:无需操作,除非同一输出还包含警告。 `Matrix migration snapshot created before applying Matrix upgrades.` -- 含义:OpenClaw 在更改 Matrix 状态之前创建了一个恢复归档。 -- 该怎么做:保留输出中的归档路径,直到你确认迁移成功。 +- 含义:OpenClaw 在修改 Matrix 状态之前创建了恢复归档。 +- 操作:保留打印出的归档路径,直到确认迁移成功。 `Matrix migration snapshot reused before applying Matrix upgrades.` - 含义:OpenClaw 找到了现有的 Matrix 迁移快照标记,并复用了该归档,而不是创建重复备份。 -- 该怎么做:保留输出中的归档路径,直到你确认迁移成功。 +- 操作:保留打印出的归档路径,直到确认迁移成功。 `Legacy Matrix state detected at ... but channels.matrix is not configured yet.` -- 含义:存在旧的 Matrix 状态,但 OpenClaw 无法将其映射到当前 Matrix 账户,因为 Matrix 尚未配置。 -- 该怎么做:配置 `channels.matrix`,然后重新运行 `openclaw doctor --fix` 或重启 Gateway 网关。 +- 含义:旧 Matrix 状态存在,但 OpenClaw 无法将其映射到当前 Matrix 账号,因为 Matrix 尚未配置。 +- 操作:配置 `channels.matrix`,然后重新运行 `openclaw doctor --fix` 或重启 Gateway 网关。 `Legacy Matrix state detected at ... but the new account-scoped target could not be resolved yet (need homeserver, userId, and access token for channels.matrix...).` -- 含义:OpenClaw 找到了旧状态,但仍无法确定确切的当前账户/设备根目录。 -- 该怎么做:使用可用的 Matrix 登录先启动一次 Gateway 网关,或在缓存凭证存在后重新运行 `openclaw doctor --fix`。 +- 含义:OpenClaw 找到了旧状态,但仍无法确定确切的当前账号/设备根目录。 +- 操作:使用可用的 Matrix 登录启动一次 Gateway 网关,或在缓存凭证存在后重新运行 `openclaw doctor --fix`。 `Legacy Matrix state detected at ... but multiple Matrix accounts are configured and channels.matrix.defaultAccount is not set.` -- 含义:OpenClaw 找到了一个共享的扁平 Matrix 存储,但它拒绝猜测应将其分配给哪个具名 Matrix 账户。 -- 该怎么做:将 `channels.matrix.defaultAccount` 设置为目标账户,然后重新运行 `openclaw doctor --fix` 或重启 Gateway 网关。 +- 含义:OpenClaw 找到了一个共享的扁平 Matrix 存储,但拒绝猜测应由哪个命名 Matrix 账号接收它。 +- 操作:将 `channels.matrix.defaultAccount` 设置为目标账号,然后重新运行 `openclaw doctor --fix` 或重启 Gateway 网关。 `Matrix legacy sync store not migrated because the target already exists (...)` -- 含义:新的按账户划分位置已经有同步存储或加密存储,因此 OpenClaw 不会自动覆盖它。 -- 该怎么做:在手动删除或移动冲突目标之前,先确认当前账户就是正确的账户。 +- 含义:新的按账号划分位置已经有同步或加密存储,因此 OpenClaw 没有自动覆盖它。 +- 操作:在手动移除或移动冲突目标之前,确认当前账号是正确账号。 `Failed migrating Matrix legacy sync store (...)` 或 `Failed migrating Matrix legacy crypto store (...)` -- 含义:OpenClaw 尝试移动旧的 Matrix 状态,但文件系统操作失败了。 -- 该怎么做:检查文件系统权限和磁盘状态,然后重新运行 `openclaw doctor --fix`。 +- 含义:OpenClaw 尝试移动旧 Matrix 状态,但文件系统操作失败。 +- 操作:检查文件系统权限和磁盘状态,然后重新运行 `openclaw doctor --fix`。 `Legacy Matrix encrypted state detected at ... but channels.matrix is not configured yet.` -- 含义:OpenClaw 找到了旧的加密 Matrix 存储,但没有当前的 Matrix 配置可将其附加到其中。 -- 该怎么做:配置 `channels.matrix`,然后重新运行 `openclaw doctor --fix` 或重启 Gateway 网关。 +- 含义:OpenClaw 找到了旧的加密 Matrix 存储,但没有可附加到它的当前 Matrix 配置。 +- 操作:配置 `channels.matrix`,然后重新运行 `openclaw doctor --fix` 或重启 Gateway 网关。 `Legacy Matrix encrypted state detected at ... but the account-scoped target could not be resolved yet (need homeserver, userId, and access token for channels.matrix...).` -- 含义:加密存储存在,但 OpenClaw 无法安全判断它属于哪个当前账户/设备。 -- 该怎么做:使用可用的 Matrix 登录先启动一次 Gateway 网关,或在缓存凭证可用后重新运行 `openclaw doctor --fix`。 +- 含义:加密存储存在,但 OpenClaw 无法安全判断它属于哪个当前账号/设备。 +- 操作:使用可用的 Matrix 登录启动一次 Gateway 网关,或在缓存凭证可用后重新运行 `openclaw doctor --fix`。 `Legacy Matrix encrypted state detected at ... but multiple Matrix accounts are configured and channels.matrix.defaultAccount is not set.` -- 含义:OpenClaw 找到了一个共享的扁平旧版加密存储,但它拒绝猜测应将其分配给哪个具名 Matrix 账户。 -- 该怎么做:将 `channels.matrix.defaultAccount` 设置为目标账户,然后重新运行 `openclaw doctor --fix` 或重启 Gateway 网关。 +- 含义:OpenClaw 找到了一个共享的扁平旧版加密存储,但拒绝猜测应由哪个命名 Matrix 账号接收它。 +- 操作:将 `channels.matrix.defaultAccount` 设置为目标账号,然后重新运行 `openclaw doctor --fix` 或重启 Gateway 网关。 `Matrix migration warnings are present, but no on-disk Matrix mutation is actionable yet. No pre-migration snapshot was needed.` -- 含义:OpenClaw 检测到了旧的 Matrix 状态,但迁移仍被缺失的身份或凭证数据阻塞。 -- 该怎么做:完成 Matrix 登录或配置设置,然后重新运行 `openclaw doctor --fix` 或重启 Gateway 网关。 +- 含义:OpenClaw 检测到旧 Matrix 状态,但迁移仍受缺失的身份或凭证数据阻塞。 +- 操作:完成 Matrix 登录或配置设置,然后重新运行 `openclaw doctor --fix` 或重启 Gateway 网关。 `Legacy Matrix encrypted state was detected, but the Matrix plugin helper is unavailable. Install or repair @openclaw/matrix so OpenClaw can inspect the old rust crypto store before upgrading.` -- 含义:OpenClaw 找到了旧的加密 Matrix 状态,但它无法从通常用于检查该存储的 Matrix 插件中加载辅助入口点。 -- 该怎么做:重新安装或修复 Matrix 插件(`openclaw plugins install @openclaw/matrix`,或如果是仓库检出,则运行 `openclaw plugins install ./path/to/local/matrix-plugin`),然后重新运行 `openclaw doctor --fix` 或重启 Gateway 网关。 +- 含义:OpenClaw 找到了旧的已加密 Matrix 状态,但无法从 Matrix 插件加载通常用于检查该存储的辅助入口点。 +- 处理方式:重新安装或修复 Matrix 插件(`openclaw plugins install @openclaw/matrix`,或者对于仓库检出使用 `openclaw plugins install ./path/to/local/matrix-plugin`),然后重新运行 `openclaw doctor --fix` 或重启 Gateway 网关。 +- 如果 npm 报告 OpenClaw 拥有的 Matrix 包已弃用,请使用当前打包版 OpenClaw 构建中内置的 + 插件,或使用本地检出路径,直到 + 发布更新的 npm 包。 `Matrix plugin helper path is unsafe: ... Reinstall @openclaw/matrix and try again.` -- 含义:OpenClaw 找到了一个越过插件根目录或未通过插件边界检查的辅助文件路径,因此拒绝导入它。 -- 该怎么做:从受信任路径重新安装 Matrix 插件,然后重新运行 `openclaw doctor --fix` 或重启 Gateway 网关。 +- 含义:OpenClaw 找到的辅助文件路径会逃逸出插件根目录,或未通过插件边界检查,因此拒绝导入它。 +- 处理方式:从可信路径重新安装 Matrix 插件,然后重新运行 `openclaw doctor --fix` 或重启 Gateway 网关。 `- Failed creating a Matrix migration snapshot before repair: ...` `- Skipping Matrix migration changes for now. Resolve the snapshot failure, then rerun "openclaw doctor --fix".` -- 含义:OpenClaw 拒绝更改 Matrix 状态,因为它无法先创建恢复快照。 -- 该怎么做:解决备份错误,然后重新运行 `openclaw doctor --fix` 或重启 Gateway 网关。 +- 含义:OpenClaw 拒绝修改 Matrix 状态,因为它无法先创建恢复快照。 +- 处理方式:解决备份错误,然后重新运行 `openclaw doctor --fix` 或重启 Gateway 网关。 `Failed migrating legacy Matrix client storage: ...` -- 含义:Matrix 客户端侧的回退逻辑找到了旧的扁平存储,但移动失败。OpenClaw 现在会中止该回退流程,而不是静默地使用一个全新的存储启动。 -- 该怎么做:检查文件系统权限或冲突,保持旧状态完好无损,并在修复错误后重试。 +- 含义:Matrix 客户端侧回退流程发现了旧的扁平存储,但移动失败。OpenClaw 现在会中止该回退流程,而不是静默地用全新存储启动。 +- 处理方式:检查文件系统权限或冲突,保持旧状态完整,并在修复错误后重试。 `Matrix is installed from a custom path: ...` -- 含义:Matrix 被固定安装为路径安装,因此主线更新不会自动将其替换为仓库中的标准 Matrix 软件包。 -- 该怎么做:当你想恢复为默认 Matrix 插件时,使用 `openclaw plugins install @openclaw/matrix` 重新安装。 +- 含义:Matrix 被固定为路径安装,因此主线更新不会自动将其替换为仓库的标准 Matrix 包。 +- 处理方式:当你想回到默认 Matrix 插件时,使用 `openclaw plugins install @openclaw/matrix` 重新安装。 +- 如果 npm 报告 OpenClaw 拥有的 Matrix 包已弃用,请使用当前打包版 OpenClaw 构建中内置的 + 插件,直到发布更新的 npm 包。 ### 加密状态恢复消息 `matrix: restored X/Y room key(s) from legacy encrypted-state backup` -- 含义:已成功将备份的房间密钥恢复到新的加密存储中。 -- 该怎么做:通常无需操作。 +- 含义:已备份的房间密钥已成功恢复到新的加密存储中。 +- 处理方式:通常无需操作。 `matrix: N legacy local-only room key(s) were never backed up and could not be restored automatically` -- 含义:一些旧房间密钥仅存在于旧的本地存储中,且从未上传到 Matrix 备份。 -- 该怎么做:除非你能从另一个已验证客户端手动恢复这些密钥,否则一些旧的加密历史记录仍将不可用。 +- 含义:一些旧房间密钥只存在于旧本地存储中,从未上传到 Matrix 备份。 +- 处理方式:除非你能从另一个已验证客户端手动恢复这些密钥,否则部分旧的加密历史可能仍不可用。 `Legacy Matrix encrypted state for account "..." has backed-up room keys, but no local backup decryption key was found. Ask the operator to run "openclaw matrix verify backup restore --recovery-key-stdin" after upgrade if they have the recovery key.` - 含义:备份存在,但 OpenClaw 无法自动恢复恢复密钥。 -- 该怎么做:运行 `printf '%s\n' "$MATRIX_RECOVERY_KEY" | openclaw matrix verify backup restore --recovery-key-stdin`。 +- 处理方式:运行 `printf '%s\n' "$MATRIX_RECOVERY_KEY" | openclaw matrix verify backup restore --recovery-key-stdin`。 `Failed inspecting legacy Matrix encrypted state for account "..." (...): ...` -- 含义:OpenClaw 找到了旧的加密存储,但无法以足够安全的方式检查它来准备恢复。 -- 该怎么做:重新运行 `openclaw doctor --fix`。如果仍然重复出现,请保持旧状态目录完好无损,并通过另一个已验证的 Matrix 客户端加上 `printf '%s\n' "$MATRIX_RECOVERY_KEY" | openclaw matrix verify backup restore --recovery-key-stdin` 进行恢复。 +- 含义:OpenClaw 找到了旧的加密存储,但无法足够安全地检查它以准备恢复。 +- 处理方式:重新运行 `openclaw doctor --fix`。如果问题重复出现,请保持旧状态目录完整,并使用另一个已验证的 Matrix 客户端加上 `printf '%s\n' "$MATRIX_RECOVERY_KEY" | openclaw matrix verify backup restore --recovery-key-stdin` 来恢复。 `Legacy Matrix backup key was found for account "...", but .../recovery-key.json already contains a different recovery key. Leaving the existing file unchanged.` -- 含义:OpenClaw 检测到了备份密钥冲突,因此拒绝自动覆盖当前的 recovery-key 文件。 -- 该怎么做:在重试任何恢复命令之前,先确认哪个恢复密钥才是正确的。 +- 含义:OpenClaw 检测到备份密钥冲突,并拒绝自动覆盖当前的恢复密钥文件。 +- 处理方式:在重试任何恢复命令前,先确认哪个恢复密钥是正确的。 `Legacy Matrix encrypted state for account "..." cannot be fully converted automatically because the old rust crypto store does not expose all local room keys for export.` - 含义:这是旧存储格式的硬性限制。 -- 该怎么做:已备份的密钥仍然可以恢复,但仅存在于本地的加密历史记录可能仍然不可用。 +- 处理方式:已备份的密钥仍可恢复,但仅存在本地的加密历史可能仍不可用。 `matrix: failed restoring room keys from legacy encrypted-state backup: ...` -- 含义:新插件尝试恢复时,Matrix 返回了错误。 -- 该怎么做:运行 `openclaw matrix verify backup status`,如有需要,再使用 `printf '%s\n' "$MATRIX_RECOVERY_KEY" | openclaw matrix verify backup restore --recovery-key-stdin` 重试。 +- 含义:新插件尝试恢复,但 Matrix 返回了错误。 +- 处理方式:运行 `openclaw matrix verify backup status`,必要时再用 `printf '%s\n' "$MATRIX_RECOVERY_KEY" | openclaw matrix verify backup restore --recovery-key-stdin` 重试。 ### 手动恢复消息 `Backup key is not loaded on this device. Run 'openclaw matrix verify backup restore' to load it and restore old room keys.` -- 含义:OpenClaw 知道你应该有一个备份密钥,但该密钥当前未在此设备上激活。 -- 该怎么做:运行 `openclaw matrix verify backup restore`,或者如有需要,设置 `MATRIX_RECOVERY_KEY` 后运行 `printf '%s\n' "$MATRIX_RECOVERY_KEY" | openclaw matrix verify backup restore --recovery-key-stdin`。 +- 含义:OpenClaw 知道你应该有备份密钥,但它在此设备上未处于活动状态。 +- 处理方式:运行 `openclaw matrix verify backup restore`,或设置 `MATRIX_RECOVERY_KEY` 并在需要时运行 `printf '%s\n' "$MATRIX_RECOVERY_KEY" | openclaw matrix verify backup restore --recovery-key-stdin`。 `Store a recovery key with 'openclaw matrix verify device --recovery-key-stdin', then run 'openclaw matrix verify backup restore'.` -- 含义:此设备当前尚未存储恢复密钥。 -- 该怎么做:设置 `MATRIX_RECOVERY_KEY`,运行 `printf '%s\n' "$MATRIX_RECOVERY_KEY" | openclaw matrix verify device --recovery-key-stdin`,然后恢复备份。 +- 含义:此设备当前没有存储恢复密钥。 +- 处理方式:设置 `MATRIX_RECOVERY_KEY`,运行 `printf '%s\n' "$MATRIX_RECOVERY_KEY" | openclaw matrix verify device --recovery-key-stdin`,然后恢复备份。 `Backup key mismatch on this device. Re-run 'openclaw matrix verify device --recovery-key-stdin' with the matching recovery key.` -- 含义:已存储的密钥与当前激活的 Matrix 备份不匹配。 -- 该怎么做:将 `MATRIX_RECOVERY_KEY` 设置为正确的密钥,然后运行 `printf '%s\n' "$MATRIX_RECOVERY_KEY" | openclaw matrix verify device --recovery-key-stdin`。 +- 含义:存储的密钥与活动的 Matrix 备份不匹配。 +- 处理方式:将 `MATRIX_RECOVERY_KEY` 设置为正确的密钥,并运行 `printf '%s\n' "$MATRIX_RECOVERY_KEY" | openclaw matrix verify device --recovery-key-stdin`。 -如果你接受丢失无法恢复的旧加密历史记录,也可以使用 -`openclaw matrix verify backup reset --yes` 重置当前备份基线。当已存储的备份密钥损坏时, -该重置也可能会重新创建密钥存储,使新的备份密钥能够在重启后正确加载。 +如果你接受丢失无法恢复的旧加密历史,也可以改用 +`openclaw matrix verify backup reset --yes` 重置当前备份基线。当存储的备份密钥损坏时,该重置也可能重新创建密钥存储,使新的备份密钥在重启后能正确加载。 `Backup trust chain is not verified on this device. Re-run 'openclaw matrix verify device --recovery-key-stdin'.` -- 含义:备份存在,但此设备对交叉签名信任链的信任程度还不够。 -- 该怎么做:设置 `MATRIX_RECOVERY_KEY`,然后运行 `printf '%s\n' "$MATRIX_RECOVERY_KEY" | openclaw matrix verify device --recovery-key-stdin`。 +- 含义:备份存在,但此设备尚未充分信任交叉签名链。 +- 处理方式:设置 `MATRIX_RECOVERY_KEY` 并运行 `printf '%s\n' "$MATRIX_RECOVERY_KEY" | openclaw matrix verify device --recovery-key-stdin`。 `Matrix recovery key is required` -- 含义:你尝试执行恢复步骤时,没有提供所需的恢复密钥。 -- 该怎么做:使用 `--recovery-key-stdin` 重新运行该命令,例如 `printf '%s\n' "$MATRIX_RECOVERY_KEY" | openclaw matrix verify device --recovery-key-stdin`。 +- 含义:你尝试执行恢复步骤时没有提供必需的恢复密钥。 +- 处理方式:使用 `--recovery-key-stdin` 重新运行该命令,例如 `printf '%s\n' "$MATRIX_RECOVERY_KEY" | openclaw matrix verify device --recovery-key-stdin`。 `Invalid Matrix recovery key: ...` -- 含义:提供的密钥无法解析,或与预期格式不匹配。 -- 该怎么做:使用你的 Matrix 客户端或 recovery-key 文件中的准确恢复密钥重试。 +- 含义:提供的密钥无法解析,或不符合预期格式。 +- 处理方式:使用来自你的 Matrix 客户端或恢复密钥文件的精确恢复密钥重试。 `Matrix recovery key was applied, but this device still lacks full Matrix identity trust.` -- 含义:OpenClaw 可以应用恢复密钥,但 Matrix 仍未为此设备建立完整的交叉签名身份信任。请检查命令输出中的 `Recovery key accepted`、`Backup usable`、`Cross-signing verified` 和 `Device verified by owner`。 -- 该怎么做:运行 `openclaw matrix verify self`,在另一个 Matrix 客户端中接受请求,比较 SAS,并仅在匹配时输入 `yes`。该命令会等待完整的 Matrix 身份信任建立后才报告成功。只有在你明确想要替换当前交叉签名身份时,才使用 `printf '%s\n' "$MATRIX_RECOVERY_KEY" | openclaw matrix verify bootstrap --recovery-key-stdin --force-reset-cross-signing`。 +- 含义:OpenClaw 可以应用恢复密钥,但 Matrix 仍未为此设备 + 建立完整的交叉签名身份信任。检查命令输出中的 `Recovery key accepted`、`Backup usable`、 + `Cross-signing verified` 和 `Device verified by owner`。 +- 处理方式:运行 `openclaw matrix verify self`,在另一个 + Matrix 客户端中接受请求,比较 SAS,并且只在匹配时输入 `yes`。该 + 命令会等待完整的 Matrix 身份信任,然后才报告成功。仅当你有意替换当前交叉签名身份时,才使用 + `printf '%s\n' "$MATRIX_RECOVERY_KEY" | openclaw matrix verify bootstrap --recovery-key-stdin --force-reset-cross-signing`。 `Matrix key backup is not active on this device after loading from secret storage.` -- 含义:从密钥存储加载后,未能在此设备上生成激活的备份会话。 -- 该怎么做:先验证此设备,然后使用 `openclaw matrix verify backup status` 再次检查。 +- 含义:密钥存储没有在此设备上产生活动的备份会话。 +- 处理方式:先验证设备,然后用 `openclaw matrix verify backup status` 重新检查。 `Matrix crypto backend cannot load backup keys from secret storage. Verify this device with 'openclaw matrix verify device --recovery-key-stdin' first.` -- 含义:在设备验证完成之前,此设备无法从密钥存储恢复。 -- 该怎么做:先运行 `printf '%s\n' "$MATRIX_RECOVERY_KEY" | openclaw matrix verify device --recovery-key-stdin`。 +- 含义:设备验证完成之前,此设备无法从密钥存储恢复。 +- 处理方式:先运行 `printf '%s\n' "$MATRIX_RECOVERY_KEY" | openclaw matrix verify device --recovery-key-stdin`。 ### 自定义插件安装消息 `Matrix is installed from a custom path that no longer exists: ...` -- 含义:你的插件安装记录指向一个已经不存在的本地路径。 -- 该怎么做:使用 `openclaw plugins install @openclaw/matrix` 重新安装;如果你是从仓库检出运行,则使用 `openclaw plugins install ./path/to/local/matrix-plugin`。 +- 含义:你的插件安装记录指向一个已不存在的本地路径。 +- 处理方式:使用 `openclaw plugins install @openclaw/matrix` 重新安装,或者如果你从仓库检出运行,则使用 `openclaw plugins install ./path/to/local/matrix-plugin`。 +- 如果 npm 报告 OpenClaw 拥有的 Matrix 包已弃用,请使用当前打包版 OpenClaw 构建中内置的 + 插件,或使用本地检出路径,直到 + 发布更新的 npm 包。 -## 如果加密历史记录仍然没有恢复 +## 如果加密历史仍未恢复 -请按顺序运行以下检查: +按顺序运行以下检查: ```bash openclaw matrix verify status --verbose @@ -346,11 +358,11 @@ openclaw matrix verify backup status --verbose printf '%s\n' "$MATRIX_RECOVERY_KEY" | openclaw matrix verify backup restore --recovery-key-stdin --verbose ``` -如果备份恢复成功,但某些旧房间仍然缺少历史记录,那么这些缺失的密钥很可能从未被先前的插件备份过。 +如果备份恢复成功,但某些旧房间仍缺少历史记录,那么这些缺失的密钥很可能从未由以前的插件备份。 ## 如果你想为未来消息重新开始 -如果你接受丢失无法恢复的旧加密历史记录,并且只想为后续消息建立一个干净的备份基线,请按顺序运行以下命令: +如果你接受丢失无法恢复的旧加密历史,并且只想从现在开始使用干净的备份基线,请按顺序运行这些命令: ```bash openclaw matrix verify backup reset --yes @@ -358,12 +370,12 @@ openclaw matrix verify backup status --verbose openclaw matrix verify status ``` -如果之后设备仍未验证,请在你的 Matrix 客户端中通过比较 SAS 表情符号或十进制代码,并确认它们匹配,来完成验证。 +如果此后设备仍未验证,请从你的 Matrix 客户端完成验证,方法是比较 SAS 表情符号或十进制代码,并确认它们匹配。 -## 相关内容 +## 相关 - [Matrix](/zh-CN/channels/matrix):渠道设置和配置。 -- [Matrix push rules](/zh-CN/channels/matrix-push-rules):通知路由。 +- [Matrix 推送规则](/zh-CN/channels/matrix-push-rules):通知路由。 - [Doctor](/zh-CN/gateway/doctor):健康检查和自动迁移触发器。 -- [Migration guide](/zh-CN/install/migrating):所有迁移路径(机器迁移、跨系统导入)。 -- [Plugins](/zh-CN/tools/plugin):插件安装和注册。 +- [迁移指南](/zh-CN/install/migrating):所有迁移路径(机器迁移、跨系统导入)。 +- [插件](/zh-CN/tools/plugin):插件安装和注册。 diff --git a/docs/zh-CN/channels/matrix.md b/docs/zh-CN/channels/matrix.md index 858dca3a9..e0a218862 100644 --- a/docs/zh-CN/channels/matrix.md +++ b/docs/zh-CN/channels/matrix.md @@ -1,41 +1,49 @@ --- read_when: - 在 OpenClaw 中设置 Matrix - - 配置 Matrix 端到端加密和验证 + - 配置 Matrix E2EE 和验证 summary: Matrix 支持状态、设置和配置示例 title: Matrix x-i18n: - generated_at: "2026-04-27T20:27:49Z" - model: gpt-5.4 + generated_at: "2026-04-29T05:38:12Z" + model: gpt-5.5 provider: openai - source_hash: 42380d57ad7da25bc1fb8a1968671e91372f7dc681ea8503013729b764b74811 + source_hash: 261b0eaae452cff7bb9ddf8dc67ddda45fb27b6468e95450b19207348d0b577a source_path: channels/matrix.md - workflow: 15 + workflow: 16 --- -Matrix 是 OpenClaw 的一个内置渠道插件。 -它使用官方的 `matrix-js-sdk`,并支持私信、房间、线程、媒体、回应、投票、位置和端到端加密。 +Matrix 是 OpenClaw 的一个内置渠道插件。 +它使用官方 `matrix-js-sdk`,并支持私信、房间、线程、媒体、回应、投票、位置和 E2EE。 ## 内置插件 -当前打包发布的 OpenClaw 版本已内置 Matrix 插件。你无需安装任何内容;配置 `channels.matrix.*`(参见 [设置](#setup))即可激活它。 +当前打包的 OpenClaw 版本已内置 Matrix 插件。你无需安装任何内容;配置 `channels.matrix.*`(见[设置](#setup))即可激活它。 -对于较旧的构建版本,或排除了 Matrix 的自定义安装,请先手动安装: +对于不包含 Matrix 的较旧构建或自定义安装,请在 npm +package 发布后安装当前版本: ```bash openclaw plugins install @openclaw/matrix -# 或者,从本地检出安装 +``` + +如果 npm 报告 OpenClaw 拥有的 package 已弃用,请使用当前打包的 +OpenClaw 构建或本地 checkout,直到更新的 npm package 发布。 + +从本地 checkout 安装: + +```bash openclaw plugins install ./path/to/local/matrix-plugin ``` -`plugins install` 会注册并启用该插件,因此不需要单独执行 `openclaw plugins enable matrix`。在你完成下方的渠道配置之前,该插件仍不会执行任何操作。有关插件的一般行为和安装规则,请参见 [插件](/zh-CN/tools/plugin)。 +`plugins install` 会注册并启用插件,因此不需要单独执行 `openclaw plugins enable matrix` 步骤。插件在你配置下面的渠道之前仍然不会执行任何操作。有关通用插件行为和安装规则,请参阅[插件](/zh-CN/tools/plugin)。 ## 设置 1. 在你的 homeserver 上创建一个 Matrix 账号。 2. 使用 `homeserver` + `accessToken`,或 `homeserver` + `userId` + `password` 配置 `channels.matrix`。 3. 重启 Gateway 网关。 -4. 与机器人开始私信,或邀请它加入房间(参见 [自动加入](#auto-join)——只有在 `autoJoin` 允许时,新邀请才会生效)。 +4. 与机器人开启私信,或邀请它加入房间(见[自动加入](#auto-join) — 新邀请只有在 `autoJoin` 允许时才会进入)。 ### 交互式设置 @@ -44,9 +52,9 @@ openclaw channels add openclaw configure --section channels ``` -向导会询问以下内容:homeserver URL、认证方式(访问令牌或密码)、用户 ID(仅密码认证)、可选的设备名称、是否启用端到端加密,以及是否配置房间访问和自动加入。 +向导会询问:homeserver URL、认证方式(访问令牌或密码)、用户 ID(仅密码认证)、可选设备名称、是否启用 E2EE,以及是否配置房间访问和自动加入。 -如果匹配的 `MATRIX_*` 环境变量已存在,并且所选账号没有已保存的认证信息,向导会提供环境变量快捷方式。在保存允许列表之前,如需解析房间名称,请运行 `openclaw channels resolve --channel matrix "Project Room"`。启用端到端加密后,向导会写入配置,并运行与 [`openclaw matrix encryption setup`](#encryption-and-verification) 相同的引导流程。 +如果匹配的 `MATRIX_*` 环境变量已存在,且所选账号没有已保存的认证信息,向导会提供环境变量快捷方式。若要在保存 allowlist 之前解析房间名称,请运行 `openclaw channels resolve --channel matrix "Project Room"`。启用 E2EE 时,向导会写入配置,并运行与 [`openclaw matrix encryption setup`](#encryption-and-verification) 相同的 bootstrap。 ### 最小配置 @@ -83,14 +91,14 @@ openclaw configure --section channels ### 自动加入 -`channels.matrix.autoJoin` 默认为 `off`。使用默认值时,在你手动加入之前,机器人不会出现在由新邀请产生的新房间或私信中。 +`channels.matrix.autoJoin` 默认值为 `off`。使用默认值时,机器人不会出现在新房间中,也不会因新邀请出现在私信中,直到你手动加入。 -OpenClaw 无法在邀请时判断被邀请的房间是私信还是群组,因此所有邀请——包括类似私信的邀请——都会先经过 `autoJoin`。`dm.policy` 只会在机器人加入之后、并且房间已被分类后才生效。 +OpenClaw 无法在邀请时判断被邀请的房间是私信还是群组,因此所有邀请(包括私信样式邀请)都会先经过 `autoJoin`。`dm.policy` 只会在之后适用,即机器人已加入且房间已分类之后。 -设置 `autoJoin: "allowlist"` 并配合 `autoJoinAllowlist`,可以限制机器人接受哪些邀请;或者设置 `autoJoin: "always"` 以接受所有邀请。 +设置 `autoJoin: "allowlist"` 加 `autoJoinAllowlist`,以限制机器人接受哪些邀请;或设置 `autoJoin: "always"` 来接受每个邀请。 -`autoJoinAllowlist` 只接受稳定目标:`!roomId:server`、`#alias:server` 或 `*`。普通房间名称会被拒绝;别名条目会针对 homeserver 进行解析,而不会根据受邀房间声明的状态进行解析。 +`autoJoinAllowlist` 仅接受稳定目标:`!roomId:server`、`#alias:server` 或 `*`。普通房间名称会被拒绝;别名条目会根据 homeserver 解析,而不是根据被邀请房间声明的状态解析。 ```json5 @@ -107,34 +115,34 @@ OpenClaw 无法在邀请时判断被邀请的房间是私信还是群组,因 } ``` -若要接受所有邀请,请使用 `autoJoin: "always"`。 +若要接受每个邀请,请使用 `autoJoin: "always"`。 -### 允许列表目标格式 +### Allowlist 目标格式 -私信和房间允许列表最好使用稳定 ID 填充: +私信和房间 allowlist 最好填入稳定 ID: -- 私信(`dm.allowFrom`、`groupAllowFrom`、`groups..users`):使用 `@user:server`。仅当 homeserver 目录返回恰好一个匹配项时,显示名称才会被解析。 -- 房间(`groups`、`autoJoinAllowlist`):使用 `!room:server` 或 `#alias:server`。名称会尽力根据已加入的房间进行解析;未解析的条目会在运行时被忽略。 +- 私信(`dm.allowFrom`、`groupAllowFrom`、`groups..users`):使用 `@user:server`。显示名称仅在 homeserver 目录恰好返回一个匹配项时才会解析。 +- 房间(`groups`、`autoJoinAllowlist`):使用 `!room:server` 或 `#alias:server`。名称会尽力根据已加入的房间解析;未解析的条目会在运行时被忽略。 ### 账号 ID 规范化 -向导会将易读名称转换为规范化的账号 ID。例如,`Ops Bot` 会变成 `ops-bot`。在带作用域的环境变量名称中,标点符号会被转义,以避免两个账号发生冲突:`-` → `_X2D_`,因此 `ops-prod` 会映射为 `MATRIX_OPS_X2D_PROD_*`。 +向导会将友好名称转换为规范化账号 ID。例如,`Ops Bot` 会变为 `ops-bot`。标点符号会在带作用域的环境变量名称中转义,以便两个账号不会冲突:`-` → `_X2D_`,因此 `ops-prod` 映射为 `MATRIX_OPS_X2D_PROD_*`。 -### 缓存的凭证 +### 缓存凭证 -Matrix 会将缓存的凭证存储在 `~/.openclaw/credentials/matrix/` 下: +Matrix 会将缓存凭证存储在 `~/.openclaw/credentials/matrix/` 下: - 默认账号:`credentials.json` - 命名账号:`credentials-.json` -当这些位置存在缓存凭证时,即使配置文件中没有访问令牌,OpenClaw 仍会将 Matrix 视为已配置——这适用于设置流程、`openclaw doctor` 和渠道状态探测。 +当那里存在缓存凭证时,OpenClaw 会将 Matrix 视为已配置,即使访问令牌不在配置文件中也是如此 — 这覆盖设置、`openclaw doctor` 和渠道状态探测。 ### 环境变量 -当等效的配置键未设置时会使用这些变量。默认账号使用不带前缀的名称;命名账号会在后缀前插入账号 ID。 +在等效配置键未设置时使用。默认账号使用无前缀名称;命名账号会在后缀前插入账号 ID。 -| 默认账号 | 命名账号(`` 是规范化后的账号 ID) | -| ------------------- | -------------------------------------- | +| 默认账号 | 命名账号(`` 是规范化账号 ID) | +| --------------------- | --------------------------------------------------- | | `MATRIX_HOMESERVER` | `MATRIX__HOMESERVER` | | `MATRIX_ACCESS_TOKEN` | `MATRIX__ACCESS_TOKEN` | | `MATRIX_USER_ID` | `MATRIX__USER_ID` | @@ -143,13 +151,13 @@ Matrix 会将缓存的凭证存储在 `~/.openclaw/credentials/matrix/` 下: | `MATRIX_DEVICE_NAME` | `MATRIX__DEVICE_NAME` | | `MATRIX_RECOVERY_KEY` | `MATRIX__RECOVERY_KEY` | -对于账号 `ops`,名称会变为 `MATRIX_OPS_HOMESERVER`、`MATRIX_OPS_ACCESS_TOKEN` 等。恢复密钥环境变量会被具备恢复能力的 CLI 流程读取(`verify backup restore`、`verify device`、`verify bootstrap`),前提是你通过 `--recovery-key-stdin` 管道传入该密钥。 +对于账号 `ops`,名称会变为 `MATRIX_OPS_HOMESERVER`、`MATRIX_OPS_ACCESS_TOKEN`,依此类推。恢复密钥环境变量会被支持恢复的 CLI 流程(`verify backup restore`、`verify device`、`verify bootstrap`)读取,前提是你通过 `--recovery-key-stdin` 管道传入密钥。 -`MATRIX_HOMESERVER` 不能从工作区 `.env` 中设置;参见 [工作区 `.env` 文件](/zh-CN/gateway/security)。 +`MATRIX_HOMESERVER` 不能从工作区 `.env` 设置;见[工作区 `.env` 文件](/zh-CN/gateway/security)。 ## 配置示例 -一个实用的基础配置,包含私信配对、房间允许列表和端到端加密: +一个实用基线,包含私信配对、房间 allowlist 和 E2EE: ```json5 { @@ -184,7 +192,7 @@ Matrix 会将缓存的凭证存储在 `~/.openclaw/credentials/matrix/` 下: ## 流式预览 -Matrix 回复流式传输为可选启用。`streaming` 控制 OpenClaw 如何传递正在生成中的助手回复;`blockStreaming` 控制每个已完成的块是否保留为单独的 Matrix 消息。 +Matrix 回复流式传输是选择加入的。`streaming` 控制 OpenClaw 如何交付进行中的助手回复;`blockStreaming` 控制每个已完成块是否作为自己的 Matrix 消息保留。 ```json5 { @@ -196,7 +204,8 @@ Matrix 回复流式传输为可选启用。`streaming` 控制 OpenClaw 如何传 } ``` -如果你希望保留实时回答预览,但隐藏中间的工具/进度行,请使用对象形式: +若要保留实时答案预览,但隐藏临时工具/进度行,请使用对象 +形式: ```json5 { @@ -216,38 +225,38 @@ Matrix 回复流式传输为可选启用。`streaming` 控制 OpenClaw 如何传 | `streaming` | 行为 | | ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `"off"`(默认) | 等待完整回复,然后发送一次。`true` ↔ `"partial"`,`false` ↔ `"off"`。 | -| `"partial"` | 在模型写入当前块时,原地编辑一条普通文本消息。标准 Matrix 客户端可能会在首次预览时通知,而不是在最终编辑时通知。 | -| `"quiet"` | 与 `"partial"` 相同,但该消息是一个不通知的 notice。只有当某条按用户生效的推送规则与最终完成的编辑匹配时,接收者才会收到通知(见下文)。 | +| `"partial"` | 在模型写入当前块时,就地编辑一条普通文本消息。标准 Matrix 客户端可能会在首次预览时通知,而不是在最终编辑时通知。 | +| `"quiet"` | 与 `"partial"` 相同,但消息是不触发通知的 notice。接收者只有在按用户配置的推送规则匹配最终编辑时才会收到通知(见下文)。 | `blockStreaming` 独立于 `streaming`: | `streaming` | `blockStreaming: true` | `blockStreaming: false`(默认) | | ----------------------- | ------------------------------------------------------------------- | ---------------------------------------------------- | -| `"partial"` / `"quiet"` | 当前块使用实时草稿,已完成的块保留为消息 | 当前块使用实时草稿,并原地完成最终定稿 | -| `"off"` | 每个已完成块发送一条会通知的 Matrix 消息 | 完整回复发送一条会通知的 Matrix 消息 | +| `"partial"` / `"quiet"` | 当前块的实时草稿,已完成块保留为消息 | 当前块的实时草稿,就地最终化 | +| `"off"` | 每个完成块一条触发通知的 Matrix 消息 | 完整回复一条触发通知的 Matrix 消息 | -说明: +注意: -- 如果预览内容增长到超过 Matrix 的单事件大小限制,OpenClaw 会停止预览流式传输,并回退到仅发送最终结果。 -- 媒体回复始终会正常发送附件。如果陈旧的预览已无法安全复用,OpenClaw 会在发送最终媒体回复前将其擦除。 -- 当 Matrix 预览流式传输处于激活状态时,工具进度预览更新默认启用。设置 `streaming.preview.toolProgress: false` 可以保留回答文本的预览编辑,同时让工具进度继续走普通传递路径。 -- 预览编辑会产生额外的 Matrix API 调用。如果你希望采用最保守的速率限制配置,请保持 `streaming: "off"`。 +- 如果预览增长超过 Matrix 的单事件大小限制,OpenClaw 会停止预览流式传输,并回退到仅最终交付。 +- 媒体回复始终正常发送附件。如果过期预览无法再安全复用,OpenClaw 会先将其 redact,再发送最终媒体回复。 +- 当 Matrix 预览流式传输处于活动状态时,默认启用工具进度预览更新。设置 `streaming.preview.toolProgress: false` 可保留答案文本的预览编辑,但让工具进度沿正常交付路径发送。 +- 预览编辑会消耗额外的 Matrix API 调用。如果你想要最保守的速率限制配置,请保持 `streaming: "off"`。 ## 审批元数据 -Matrix 原生审批提示是普通的 `m.room.message` 事件,其中包含位于 `com.openclaw.approval` 下的 OpenClaw 专用自定义事件内容。Matrix 允许自定义事件内容键,因此标准客户端仍会渲染文本正文,而支持 OpenClaw 的客户端则可以读取结构化的审批 ID、类型、状态、可用决定以及 exec/plugin 详细信息。 +Matrix 原生审批提示是普通的 `m.room.message` 事件,其中在 `com.openclaw.approval` 下包含 OpenClaw 特定的自定义事件内容。Matrix 允许自定义事件内容键,因此标准客户端仍会渲染文本正文,而支持 OpenClaw 的客户端可以读取结构化的审批 ID、类型、状态、可用决定,以及 exec/插件详情。 -当审批提示过长、无法放入单个 Matrix 事件时,OpenClaw 会将可见文本分块,并且仅将 `com.openclaw.approval` 附加到第一个块。用于允许/拒绝决定的回应会绑定到第一个事件,因此长提示与单事件提示保持相同的审批目标。 +当审批提示过长,无法放入一个 Matrix 事件时,OpenClaw 会将可见文本分块,并且只把 `com.openclaw.approval` 附加到第一个块。用于允许/拒绝决定的回应会绑定到第一个事件,因此长提示与单事件提示保持相同的审批目标。 -### quiet 最终预览的自托管推送规则 +### 用于静默最终预览的自托管推送规则 -`streaming: "quiet"` 只有在某个块或轮次最终完成时才会通知接收者——必须有一条按用户生效的推送规则与最终预览标记匹配。完整做法请参见 [用于 quiet 预览的 Matrix 推送规则](/zh-CN/channels/matrix-push-rules)(接收者令牌、pusher 检查、规则安装、各 homeserver 说明)。 +`streaming: "quiet"` 只会在块或轮次最终化后通知接收者 — 必须有一条按用户配置的推送规则匹配最终预览标记。完整流程(接收者令牌、pusher 检查、规则安装、每个 homeserver 的注意事项)见[用于静默预览的 Matrix 推送规则](/zh-CN/channels/matrix-push-rules)。 -## 机器人到机器人的房间 +## 机器人到机器人房间 默认情况下,来自其他已配置 OpenClaw Matrix 账号的 Matrix 消息会被忽略。 -当你明确希望允许智能体之间的 Matrix 通信时,请使用 `allowBots`: +当你有意需要智能体间 Matrix 流量时,请使用 `allowBots`: ```json5 { @@ -264,19 +273,19 @@ Matrix 原生审批提示是普通的 `m.room.message` 事件,其中包含位 } ``` -- `allowBots: true` 会在允许的房间和私信中接受来自其他已配置 Matrix 机器人账号的消息。 -- `allowBots: "mentions"` 仅在这些消息于房间中明确提及此机器人时才接受。私信仍然允许。 -- `groups..allowBots` 会覆盖某个房间的账号级设置。 +- `allowBots: true` 会接受允许房间和私信中来自其他已配置 Matrix 机器人账号的消息。 +- `allowBots: "mentions"` 只在这些消息在房间中明显提及此机器人时才接受。私信仍然允许。 +- `groups..allowBots` 会覆盖单个房间的账号级设置。 - OpenClaw 仍会忽略来自同一 Matrix 用户 ID 的消息,以避免自我回复循环。 -- Matrix 在这里不会暴露原生机器人标记;OpenClaw 将“由机器人发送”视为“由此 OpenClaw Gateway 网关上的另一个已配置 Matrix 账号发送”。 +- Matrix 在这里不会暴露原生机器人标记;OpenClaw 将“由机器人撰写”视为“由此 OpenClaw Gateway 网关上另一个已配置的 Matrix 账号发送”。 -在共享房间中启用机器人到机器人通信时,请使用严格的房间允许列表和提及要求。 +在共享房间中启用机器人到机器人流量时,请使用严格的房间 allowlist 和提及要求。 ## 加密与验证 -在加密的(端到端加密)房间中,出站图片事件会使用 `thumbnail_file`,因此图片预览会与完整附件一起被加密。未加密房间仍使用普通的 `thumbnail_url`。无需配置——该插件会自动检测端到端加密状态。 +在加密(E2EE)房间中,出站图片事件使用 `thumbnail_file`,因此图片预览会与完整附件一起加密。未加密房间仍使用普通的 `thumbnail_url`。无需配置,插件会自动检测 E2EE 状态。 -所有 `openclaw matrix` 命令都接受 `--verbose`(完整诊断信息)、`--json`(机器可读输出)和 `--account `(多账号设置)。默认输出较为简洁,内部 SDK 日志保持安静。下面的示例展示了规范形式;你可以按需添加这些标志。 +所有 `openclaw matrix` 命令都接受 `--verbose`(完整诊断)、`--json`(机器可读输出)和 `--account `(多账户设置)。默认输出简洁,并带有安静的内部 SDK 日志。下面的示例展示标准形式;按需添加这些标志。 ### 启用加密 @@ -284,12 +293,12 @@ Matrix 原生审批提示是普通的 `m.room.message` 事件,其中包含位 openclaw matrix encryption setup ``` -引导初始化密钥存储和交叉签名,必要时创建房间密钥备份,然后输出 Status 和后续步骤。常用标志: +引导初始化密钥存储和交叉签名,在需要时创建房间密钥备份,然后打印状态和后续步骤。常用标志: -- `--recovery-key ` 在引导初始化之前应用恢复密钥(更推荐使用下文记录的 stdin 形式) -- `--force-reset-cross-signing` 丢弃当前的交叉签名身份并创建新身份(仅在明确需要时使用) +- `--recovery-key ` 在引导初始化前应用恢复密钥(优先使用下面记录的 stdin 形式) +- `--force-reset-cross-signing` 丢弃当前交叉签名身份并创建新身份(仅在有意这样做时使用) -对于新账号,可在创建时启用端到端加密: +对于新账户,在创建时启用 E2EE: ```bash openclaw matrix account add \ @@ -323,41 +332,39 @@ openclaw matrix verify status openclaw matrix verify status --include-recovery-key --json ``` -`verify status` 会报告三个彼此独立的信任信号(`--verbose` 会显示全部): +`verify status` 报告三个独立的信任信号(`--verbose` 会显示全部信号): -- `Locally trusted`:仅被当前客户端信任 -- `Cross-signing verified`:SDK 报告已通过交叉签名验证 -- `Signed by owner`:已由你自己的自签名密钥签名(仅用于诊断) +- `Locally trusted`:仅受此客户端信任 +- `Cross-signing verified`:SDK 报告通过交叉签名完成验证 +- `Signed by owner`:由你自己的自签名密钥签名(仅用于诊断) -只有当 `Cross-signing verified` 为 `yes` 时,`Verified by owner` 才会变为 `yes`。 +只有当 `Cross-signing verified` 为 `yes` 时,`Verified by owner` 才会变成 `yes`。仅有本地信任或所有者签名还不够。 -单独的本地信任或 owner 签名都不足以满足条件。 - -`--allow-degraded-local-state` 会在不预先准备 Matrix 账号的情况下返回尽力而为的诊断信息;这对于离线或仅部分配置的探测很有用。 +`--allow-degraded-local-state` 会在不先准备 Matrix 账户的情况下返回尽力而为的诊断;适用于离线或部分配置的探测。 ### 使用恢复密钥验证此设备 -恢复密钥属于敏感信息——应通过 stdin 管道传入,而不要直接写在命令行中。请设置 `MATRIX_RECOVERY_KEY`(或命名账号的 `MATRIX__RECOVERY_KEY`): +恢复密钥很敏感,请通过 stdin 管道传入,而不是在命令行上传递。设置 `MATRIX_RECOVERY_KEY`(或为命名账户设置 `MATRIX__RECOVERY_KEY`): ```bash printf '%s\n' "$MATRIX_RECOVERY_KEY" | openclaw matrix verify device --recovery-key-stdin ``` -该命令会报告三种状态: +该命令报告三种状态: -- `Recovery key accepted`:Matrix 已接受该密钥,用于密钥存储或设备信任。 +- `Recovery key accepted`:Matrix 已接受该密钥用于密钥存储或设备信任。 - `Backup usable`:可以使用受信任的恢复材料加载房间密钥备份。 -- `Device verified by owner`:该设备已获得完整的 Matrix 交叉签名身份信任。 +- `Device verified by owner`:此设备拥有完整的 Matrix 交叉签名身份信任。 -即使恢复密钥已解锁备份材料,只要完整身份信任尚未完成,命令仍会以非零状态退出。这种情况下,请在另一个 Matrix 客户端中完成自验证: +当完整身份信任不完整时,即使恢复密钥已解锁备份材料,它也会以非零状态退出。在这种情况下,请从另一个 Matrix 客户端完成自验证: ```bash openclaw matrix verify self ``` -`verify self` 会等待 `Cross-signing verified: yes`,然后才会成功退出。可使用 `--timeout-ms ` 调整等待时间。 +`verify self` 会等待 `Cross-signing verified: yes`,然后才成功退出。使用 `--timeout-ms ` 调整等待时间。 -也支持字面量密钥形式 `openclaw matrix verify device ""`,但该密钥会进入你的 shell 历史记录。 +字面密钥形式 `openclaw matrix verify device ""` 也受支持,但密钥会进入你的 shell 历史记录。 ### 引导初始化或修复交叉签名 @@ -365,19 +372,19 @@ openclaw matrix verify self openclaw matrix verify bootstrap ``` -`verify bootstrap` 是面向加密账号的修复和设置命令。它会依次执行以下操作: +`verify bootstrap` 是加密账户的修复和设置命令。它会按顺序: - 引导初始化密钥存储,并在可能时复用现有恢复密钥 -- 引导初始化交叉签名,并上传缺失的公钥 +- 引导初始化交叉签名并上传缺失的公钥 - 标记并交叉签名当前设备 -- 如果服务器端尚不存在房间密钥备份,则创建一个 +- 如果尚不存在服务器端房间密钥备份,则创建一个 -如果 homeserver 在上传交叉签名密钥时要求 UIA,OpenClaw 会先尝试无认证,再尝试 `m.login.dummy`,最后尝试 `m.login.password`(需要 `channels.matrix.password`)。 +如果 homeserver 要求 UIA 才能上传交叉签名密钥,OpenClaw 会先尝试无认证,然后尝试 `m.login.dummy`,再尝试 `m.login.password`(需要 `channels.matrix.password`)。 常用标志: -- `--recovery-key-stdin`(搭配 `printf '%s\n' "$MATRIX_RECOVERY_KEY" | …` 使用)或 `--recovery-key ` -- `--force-reset-cross-signing` 用于丢弃当前交叉签名身份(仅在明确需要时使用) +- `--recovery-key-stdin`(与 `printf '%s\n' "$MATRIX_RECOVERY_KEY" | …` 搭配使用)或 `--recovery-key ` +- `--force-reset-cross-signing` 用于丢弃当前交叉签名身份(仅在有意这样做时) ### 房间密钥备份 @@ -386,15 +393,15 @@ openclaw matrix verify backup status printf '%s\n' "$MATRIX_RECOVERY_KEY" | openclaw matrix verify backup restore --recovery-key-stdin ``` -`backup status` 会显示服务器端备份是否存在,以及当前设备是否能够解密它。`backup restore` 会将已备份的房间密钥导入本地加密存储;如果恢复密钥已经保存在磁盘上,你可以省略 `--recovery-key-stdin`。 +`backup status` 显示是否存在服务器端备份,以及此设备是否可以解密它。`backup restore` 会将备份的房间密钥导入本地加密存储;如果恢复密钥已在磁盘上,可以省略 `--recovery-key-stdin`。 -若要使用全新的基线替换损坏的备份(接受丢失无法恢复的旧历史;如果当前备份密钥无法加载,也可以重建密钥存储): +要用新的基线替换损坏的备份(接受丢失无法恢复的旧历史;如果当前备份密钥不可加载,也可以重新创建密钥存储): ```bash openclaw matrix verify backup reset --yes ``` -只有在你明确希望旧恢复密钥不再能解锁新的备份基线时,才添加 `--rotate-recovery-key`。 +仅当你有意让先前的恢复密钥无法解锁新的备份基线时,才添加 `--rotate-recovery-key`。 ### 列出、请求和响应验证 @@ -402,53 +409,53 @@ openclaw matrix verify backup reset --yes openclaw matrix verify list ``` -列出所选账号的待处理验证请求。 +列出所选账户的待处理验证请求。 ```bash openclaw matrix verify request --own-user openclaw matrix verify request --user-id @ops:example.org --device-id ABCDEF ``` -从当前 OpenClaw 账号发送验证请求。`--own-user` 请求自验证(你需要在同一用户的另一个 Matrix 客户端中接受提示);`--user-id` / `--device-id` / `--room-id` 用于指定其他人。`--own-user` 不能与其他目标标志一起使用。 +从此 OpenClaw 账户发送验证请求。`--own-user` 请求自验证(你在同一用户的另一个 Matrix 客户端中接受提示);`--user-id`/`--device-id`/`--room-id` 指向其他人。`--own-user` 不能与其他目标标志组合使用。 -对于更底层的生命周期处理——通常是在跟随来自另一个客户端的入站请求时——以下命令会作用于某个特定请求 ``(由 `verify list` 和 `verify request` 输出): +对于更低层级的生命周期处理,通常用于跟踪来自另一个客户端的入站请求,这些命令会作用于特定请求 ``(由 `verify list` 和 `verify request` 打印): -| 命令 | 用途 | -| ------------------------------------------ | ------------------------------------------------------------------- | -| `openclaw matrix verify accept ` | 接受入站请求 | -| `openclaw matrix verify start ` | 启动 SAS 流程 | -| `openclaw matrix verify sas ` | 输出 SAS 表情符号或数字 | -| `openclaw matrix verify confirm-sas ` | 确认 SAS 与另一客户端显示的内容一致 | -| `openclaw matrix verify mismatch-sas ` | 当表情符号或数字不一致时拒绝 SAS | -| `openclaw matrix verify cancel ` | 取消;可选接受 `--reason ` 和 `--code ` | +| 命令 | 用途 | +| ------------------------------------------ | ------------------------------------------------------------ | +| `openclaw matrix verify accept ` | 接受入站请求 | +| `openclaw matrix verify start ` | 启动 SAS 流程 | +| `openclaw matrix verify sas ` | 打印 SAS 表情符号或十进制数字 | +| `openclaw matrix verify confirm-sas ` | 确认 SAS 与另一个客户端显示的内容匹配 | +| `openclaw matrix verify mismatch-sas ` | 当表情符号或十进制数字不匹配时拒绝 SAS | +| `openclaw matrix verify cancel ` | 取消;接受可选的 `--reason ` 和 `--code ` | -`accept`、`start`、`sas`、`confirm-sas`、`mismatch-sas` 和 `cancel` 都接受 `--user-id` 和 `--room-id`,可在验证锚定到特定私信房间时,作为私信后续提示。 +当验证锚定到特定私信房间时,`accept`、`start`、`sas`、`confirm-sas`、`mismatch-sas` 和 `cancel` 都接受 `--user-id` 和 `--room-id` 作为私信后续提示。 -### 多账号说明 +### 多账户说明 -如果未提供 `--account `,Matrix CLI 命令会使用隐式默认账号。如果你有多个命名账号,且未设置 `channels.matrix.defaultAccount`,命令将拒绝猜测并要求你进行选择。当某个命名账号的端到端加密被禁用或不可用时,错误信息会指向该账号的配置键,例如 `channels.matrix.accounts.assistant.encryption`。 +没有 `--account ` 时,Matrix CLI 命令使用隐式默认账户。如果你有多个命名账户且未设置 `channels.matrix.defaultAccount`,它们会拒绝猜测并要求你选择。当某个命名账户的 E2EE 被禁用或不可用时,错误会指向该账户的配置键,例如 `channels.matrix.accounts.assistant.encryption`。 - 当 `encryption: true` 时,`startupVerification` 默认为 `"if-unverified"`。启动时,未验证设备会在另一个 Matrix 客户端中请求自验证,同时跳过重复请求并应用冷却时间(默认 24 小时)。可使用 `startupVerificationCooldownHours` 调整,或通过 `startupVerification: "off"` 禁用。 + 使用 `encryption: true` 时,`startupVerification` 默认为 `"if-unverified"`。启动时,未验证设备会在另一个 Matrix 客户端中请求自验证,跳过重复请求并应用冷却时间(默认 24 小时)。使用 `startupVerificationCooldownHours` 调整,或使用 `startupVerification: "off"` 禁用。 - 启动时还会执行一次保守的加密引导检查,复用当前的密钥存储和交叉签名身份。如果引导状态损坏,即使没有 `channels.matrix.password`,OpenClaw 也会尝试受保护的修复;如果 homeserver 需要密码 UIA,启动时会记录警告,但不会造成致命错误。已由 owner 签名的设备会被保留。 + 启动还会运行一次保守的加密引导初始化流程,复用当前密钥存储和交叉签名身份。如果引导初始化状态损坏,OpenClaw 即使没有 `channels.matrix.password` 也会尝试受保护的修复;如果 homeserver 要求密码 UIA,启动会记录警告并保持非致命。已由所有者签名的设备会被保留。 - 完整升级流程请参见 [Matrix 迁移](/zh-CN/channels/matrix-migration)。 + 完整升级流程见 [Matrix 迁移](/zh-CN/channels/matrix-migration)。 - Matrix 会将验证生命周期通知作为 `m.notice` 消息发布到严格私信验证房间中:请求、就绪(带有“通过表情符号验证”的说明)、开始/完成,以及在可用时显示 SAS(表情符号/数字)详情。 + Matrix 会将验证生命周期通知作为 `m.notice` 消息发布到严格的私信验证房间:请求、就绪(带有 “Verify by emoji” 指引)、开始/完成,以及可用时的 SAS(表情符号/十进制)详情。 - 来自另一个 Matrix 客户端的入站请求会被跟踪并自动接受。对于自验证,OpenClaw 会在表情符号验证可用后自动启动 SAS 流程并确认自身这一侧——你仍然需要在你的 Matrix 客户端中进行比对并确认“它们匹配”。 + 来自另一个 Matrix 客户端的传入请求会被跟踪并自动接受。对于自验证,OpenClaw 会自动启动 SAS 流程,并在表情符号验证可用后确认自己这一侧;你仍需要在你的 Matrix 客户端中比较并确认 “They match”。 - 验证系统通知不会转发到智能体聊天管道。 + 验证系统通知不会转发到智能体聊天管线。 - 如果 `verify status` 显示当前设备已不再列在 homeserver 上,请创建一个新的 OpenClaw Matrix 设备。对于密码登录: + 如果 `verify status` 表示当前设备已不在 homeserver 列表中,请创建一个新的 OpenClaw Matrix 设备。对于密码登录: ```bash openclaw matrix account add \ @@ -459,7 +466,7 @@ openclaw matrix account add \ --device-name OpenClaw-Gateway ``` - 对于令牌认证,请先在你的 Matrix 客户端或管理界面中创建一个新的访问令牌,然后更新 OpenClaw: + 对于令牌认证,请在你的 Matrix 客户端或管理 UI 中创建新的访问令牌,然后更新 OpenClaw: ```bash openclaw matrix account add \ @@ -468,12 +475,12 @@ openclaw matrix account add \ --access-token '' ``` - 将 `assistant` 替换为失败命令中的账号 ID;如果是默认账号,则省略 `--account`。 + 将 `assistant` 替换为失败命令中的账户 ID,或为默认账户省略 `--account`。 - - 旧的由 OpenClaw 管理的设备可能会逐渐累积。可列出并清理: + + 旧的 OpenClaw 管理设备可能会累积。列出并清理: ```bash openclaw matrix devices list @@ -483,78 +490,78 @@ openclaw matrix devices prune-stale - Matrix 端到端加密使用官方 `matrix-js-sdk` 的 Rust 加密路径,并使用 `fake-indexeddb` 作为 IndexedDB shim。加密状态会持久化到 `crypto-idb-snapshot.json`(文件权限受限)。 + Matrix E2EE 使用官方 `matrix-js-sdk` Rust 加密路径,并使用 `fake-indexeddb` 作为 IndexedDB 垫片。加密状态会持久化到 `crypto-idb-snapshot.json`(限制性文件权限)。 - 加密的运行时状态位于 `~/.openclaw/matrix/accounts//__//` 下,其中包括同步存储、加密存储、恢复密钥、IDB 快照、线程绑定和启动验证状态。当令牌变化但账号身份保持不变时,OpenClaw 会复用现有的最佳根目录,因此先前状态仍然可见。 + 加密运行时状态位于 `~/.openclaw/matrix/accounts//__//` 下,包括同步存储、加密存储、恢复密钥、IDB 快照、线程绑定和启动验证状态。当令牌变化但账户身份保持相同时,OpenClaw 会复用最佳的现有根目录,使先前状态仍然可见。 ## 配置文件管理 -更新所选账号的 Matrix 自身资料: +更新所选账户的 Matrix 自配置文件: ```bash openclaw matrix profile set --name "OpenClaw Assistant" openclaw matrix profile set --avatar-url https://cdn.example.org/avatar.png ``` -你可以在一次调用中同时传入这两个选项。Matrix 可直接接受 `mxc://` 头像 URL;当你传入 `http://` 或 `https://` 时,OpenClaw 会先上传文件,然后将解析得到的 `mxc://` URL 存入 `channels.matrix.avatarUrl`(或对应账号的覆盖项)。 +你可以在一次调用中传入两个选项。Matrix 直接接受 `mxc://` 头像 URL;当你传入 `http://` 或 `https://` 时,OpenClaw 会先上传文件,并将解析后的 `mxc://` URL 存储到 `channels.matrix.avatarUrl`(或每账户覆盖项)中。 ## 线程 -Matrix 同时支持自动回复和消息工具发送时使用原生 Matrix 线程。有两个彼此独立的开关控制其行为: +Matrix 支持原生 Matrix 线程,用于自动回复和消息工具发送。两个独立开关控制行为: ### 会话路由(`sessionScope`) `dm.sessionScope` 决定 Matrix 私信房间如何映射到 OpenClaw 会话: - `"per-user"`(默认):与同一路由对端相关的所有私信房间共享一个会话。 -- `"per-room"`:每个 Matrix 私信房间都有各自独立的会话键,即使对端相同也是如此。 +- `"per-room"`:每个 Matrix 私信房间获得自己的会话键,即使对端相同。 -显式的对话绑定始终优先于 `sessionScope`,因此已绑定的房间和线程会继续使用其选定的目标会话。 +显式对话绑定始终优先于 `sessionScope`,因此已绑定的房间和线程会保留其所选的目标会话。 -### 回复线程化(`threadReplies`) +### 回复线程(`threadReplies`) -`threadReplies` 决定机器人将回复发布到哪里: +`threadReplies` 决定机器人在哪里发布回复: -- `"off"`:回复为顶层消息。入站线程消息仍保留在父会话中。 -- `"inbound"`:仅当入站消息本身已位于某线程中时,才在线程内回复。 -- `"always"`:在线程中回复,且该线程以触发消息为根;从第一次触发开始,该对话就会通过匹配的线程作用域会话进行路由。 +- `"off"`:回复位于顶层。入站线程消息保留在父会话上。 +- `"inbound"`:仅当入站消息已经在线程中时,才在线程内回复。 +- `"always"`:在以触发消息为根的线程内回复;该对话从第一次触发开始通过匹配的线程作用域会话路由。 -`dm.threadReplies` 仅对私信覆盖此设置——例如,可让房间线程彼此隔离,同时保持私信为扁平形式。 +`dm.threadReplies` 仅针对私信覆盖此设置,例如,在保持私信扁平的同时隔离房间线程。 ### 线程继承和斜杠命令 -- 入站线程消息会将线程根消息作为额外的智能体上下文包含进来。 -- 消息工具发送在目标为同一房间(或相同的私信用户目标)时,会自动继承当前 Matrix 线程,除非显式提供了 `threadId`。 -- 私信用户目标复用仅会在当前会话元数据能够证明:这是同一个 Matrix 账号下的同一私信对端时才会生效;否则 OpenClaw 会回退到普通的用户作用域路由。 +- 入站线程消息会包含线程根消息,作为额外的智能体上下文。 +- 消息工具发送在目标为同一房间(或同一私信用户目标)时会自动继承当前 Matrix 线程,除非提供了显式的 `threadId`。 +- 只有当当前会话元数据证明是同一 Matrix 账号上的同一私信对象时,才会复用私信用户目标;否则 OpenClaw 会回退到正常的用户范围路由。 - `/focus`、`/unfocus`、`/agents`、`/session idle`、`/session max-age` 以及绑定线程的 `/acp spawn` 都可在 Matrix 房间和私信中使用。 - 当 `threadBindings.spawnSubagentSessions: true` 时,顶层 `/focus` 会创建一个新的 Matrix 线程,并将其绑定到目标会话。 -- 在现有 Matrix 线程中运行 `/focus` 或 `/acp spawn --thread here` 时,会直接在该线程上完成绑定。 +- 在现有 Matrix 线程内运行 `/focus` 或 `/acp spawn --thread here` 会就地绑定该线程。 -当 OpenClaw 检测到某个 Matrix 私信房间与同一共享会话上的另一个私信房间发生冲突时,它会在该房间中发布一条一次性的 `m.notice`,指向 `/focus` 这一脱困方式,并建议更改 `dm.sessionScope`。仅当线程绑定已启用时,才会显示该通知。 +当 OpenClaw 检测到某个 Matrix 私信房间与同一共享会话上的另一个私信房间冲突时,它会在该房间中发布一次性的 `m.notice`,指向 `/focus` 这个脱困入口,并建议更改 `dm.sessionScope`。此通知仅在线程绑定启用时出现。 -## ACP 会话绑定 +## ACP 对话绑定 -Matrix 房间、私信和现有 Matrix 线程都可以转换为持久的 ACP 工作区,而无需改变聊天界面。 +Matrix 房间、私信和现有 Matrix 线程可以转换为持久 ACP 工作区,而无需更改聊天表面。 快速操作流程: - 在你想继续使用的 Matrix 私信、房间或现有线程中运行 `/acp spawn codex --bind here`。 -- 在顶层 Matrix 私信或房间中,当前私信/房间仍然是聊天界面,后续消息会路由到新创建的 ACP 会话。 -- 在现有 Matrix 线程中,`--bind here` 会直接绑定当前线程。 -- `/new` 和 `/reset` 会在原地重置同一个已绑定的 ACP 会话。 -- `/acp close` 会关闭 ACP 会话并移除该绑定。 +- 在顶层 Matrix 私信或房间中,当前私信/房间会保留为聊天表面,后续消息会路由到新生成的 ACP 会话。 +- 在现有 Matrix 线程内,`--bind here` 会就地绑定当前线程。 +- `/new` 和 `/reset` 会就地重置同一个已绑定 ACP 会话。 +- `/acp close` 会关闭 ACP 会话并移除绑定。 -说明: +注意: - `--bind here` 不会创建子 Matrix 线程。 -- `threadBindings.spawnAcpSessions` 仅在 `/acp spawn --thread auto|here` 时需要,此时 OpenClaw 需要创建或绑定一个子 Matrix 线程。 +- 只有 `/acp spawn --thread auto|here` 需要 `threadBindings.spawnAcpSessions`,此时 OpenClaw 需要创建或绑定子 Matrix 线程。 ### 线程绑定配置 -Matrix 会继承 `session.threadBindings` 中的全局默认值,同时也支持按渠道覆盖: +Matrix 会继承来自 `session.threadBindings` 的全局默认值,也支持按渠道覆盖: - `threadBindings.enabled` - `threadBindings.idleHours` @@ -562,50 +569,50 @@ Matrix 会继承 `session.threadBindings` 中的全局默认值,同时也支 - `threadBindings.spawnSubagentSessions` - `threadBindings.spawnAcpSessions` -Matrix 的线程绑定生成标志为显式启用: +Matrix 绑定线程的生成标志为选择启用: - 设置 `threadBindings.spawnSubagentSessions: true` 以允许顶层 `/focus` 创建并绑定新的 Matrix 线程。 - 设置 `threadBindings.spawnAcpSessions: true` 以允许 `/acp spawn --thread auto|here` 将 ACP 会话绑定到 Matrix 线程。 -## 回应 +## 响应 -Matrix 支持出站回应、入站回应通知以及确认回应。 +Matrix 支持出站响应、入站响应通知和确认响应。 -出站回应工具受 `channels.matrix.actions.reactions` 控制: +出站响应工具由 `channels.matrix.actions.reactions` 控制: -- `react` 向 Matrix 事件添加一个回应。 -- `reactions` 列出 Matrix 事件当前的回应汇总。 -- `emoji=""` 会移除该事件上机器人自己的回应。 -- `remove: true` 仅移除机器人对此指定 emoji 的回应。 +- `react` 会向 Matrix 事件添加一个响应。 +- `reactions` 会列出 Matrix 事件的当前响应摘要。 +- `emoji=""` 会移除机器人自己在该事件上的响应。 +- `remove: true` 只会从机器人移除指定的 emoji 响应。 -**解析顺序**(先定义的值优先): +**解析顺序**(优先使用第一个已定义值): -| 设置 | 顺序 | +| 设置 | 顺序 | | ----------------------- | -------------------------------------------------------------------------------- | -| `ackReaction` | 按账号 → 按渠道 → `messages.ackReaction` → 智能体身份 emoji 回退值 | -| `ackReactionScope` | 按账号 → 按渠道 → `messages.ackReactionScope` → 默认 `"group-mentions"` | -| `reactionNotifications` | 按账号 → 按渠道 → 默认 `"own"` | +| `ackReaction` | 按账号 → 渠道 → `messages.ackReaction` → 智能体身份 emoji 回退 | +| `ackReactionScope` | 按账号 → 渠道 → `messages.ackReactionScope` → 默认 `"group-mentions"` | +| `reactionNotifications` | 按账号 → 渠道 → 默认 `"own"` | -`reactionNotifications: "own"` 会在新增的 `m.reaction` 事件目标是由机器人发送的 Matrix 消息时转发这些事件;`"off"` 会禁用回应系统事件。回应移除不会被合成为系统事件,因为 Matrix 将其表现为 redact,而不是独立的 `m.reaction` 移除事件。 +`reactionNotifications: "own"` 会在新增的 `m.reaction` 事件以机器人撰写的 Matrix 消息为目标时转发这些事件;`"off"` 会禁用响应系统事件。响应移除不会被合成为系统事件,因为 Matrix 会将其呈现为撤回,而不是独立的 `m.reaction` 移除。 ## 历史上下文 -- `channels.matrix.historyLimit` 控制当 Matrix 房间消息触发智能体时,会有多少条最近房间消息以 `InboundHistory` 形式包含进来。它会回退到 `messages.groupChat.historyLimit`;如果二者都未设置,则有效默认值为 `0`。设置为 `0` 可禁用。 -- Matrix 房间历史仅限房间。私信仍继续使用普通会话历史。 -- Matrix 房间历史是“仅待处理”的:OpenClaw 会缓冲尚未触发回复的房间消息,然后在提及或其他触发到来时,对该窗口拍摄快照。 +- `channels.matrix.historyLimit` 控制当 Matrix 房间消息触发智能体时,有多少最近房间消息会作为 `InboundHistory` 包含进去。会回退到 `messages.groupChat.historyLimit`;如果两者都未设置,则有效默认值为 `0`。设置为 `0` 可禁用。 +- Matrix 房间历史仅限房间。私信仍使用正常会话历史。 +- Matrix 房间历史仅处理待处理消息:OpenClaw 会缓冲尚未触发回复的房间消息,然后在提及或其他触发到来时快照该窗口。 - 当前触发消息不会包含在 `InboundHistory` 中;它会保留在该轮的主入站正文中。 -- 对同一 Matrix 事件的重试会复用原始历史快照,而不是向前漂移到更新的房间消息。 +- 同一 Matrix 事件的重试会复用原始历史快照,而不是向前漂移到更新的房间消息。 ## 上下文可见性 -Matrix 支持共享的 `contextVisibility` 控制,用于管理补充房间上下文,例如获取到的回复文本、线程根消息和待处理历史。 +Matrix 支持共享的 `contextVisibility` 控制,用于补充房间上下文,例如抓取的回复文本、线程根消息和待处理历史。 -- `contextVisibility: "all"` 是默认值。补充上下文会按接收到的样子保留。 -- `contextVisibility: "allowlist"` 会根据当前房间/用户允许列表检查,将补充上下文过滤到允许的发送者。 -- `contextVisibility: "allowlist_quote"` 的行为类似 `allowlist`,但仍会保留一条明确引用的回复。 +- `contextVisibility: "all"` 是默认值。补充上下文会按接收内容保留。 +- `contextVisibility: "allowlist"` 会筛选补充上下文,仅发送来自活动房间/用户允许列表检查所允许发送者的内容。 +- `contextVisibility: "allowlist_quote"` 的行为类似 `allowlist`,但仍会保留一个显式引用回复。 -此设置影响的是补充上下文的可见性,而不是入站消息本身是否可以触发回复。 -触发授权仍然来自 `groupPolicy`、`groups`、`groupAllowFrom` 和私信策略设置。 +此设置影响补充上下文的可见性,而不影响入站消息本身是否可以触发回复。 +触发授权仍来自 `groupPolicy`、`groups`、`groupAllowFrom` 和私信策略设置。 ## 私信和房间策略 @@ -628,7 +635,7 @@ Matrix 支持共享的 `contextVisibility` 控制,用于管理补充房间上 } ``` -如果要完全静默私信,同时保持房间功能正常,请设置 `dm.enabled: false`: +若要在保持房间可用的同时完全静默私信,请设置 `dm.enabled: false`: ```json5 { @@ -642,7 +649,7 @@ Matrix 支持共享的 `contextVisibility` 控制,用于管理补充房间上 } ``` -有关提及门控和允许列表行为,请参见 [群组](/zh-CN/channels/groups)。 +参见 [群组](/zh-CN/channels/groups),了解提及门控和允许列表行为。 Matrix 私信的配对示例: @@ -651,13 +658,13 @@ openclaw pairing list matrix openclaw pairing approve matrix ``` -如果某个尚未获批的 Matrix 用户在批准前持续向你发送消息,OpenClaw 会复用同一个待处理配对码,并且在短暂冷却后,可能发送提醒回复,而不是生成新的配对码。 +如果未批准的 Matrix 用户在批准前持续给你发消息,OpenClaw 会复用同一个待处理配对代码,并可能在短暂冷却后发送提醒回复,而不是生成新代码。 -有关共享的私信配对流程和存储布局,请参见 [配对](/zh-CN/channels/pairing)。 +参见 [配对](/zh-CN/channels/pairing),了解共享私信配对流程和存储布局。 ## 直接房间修复 -如果私信状态发生漂移并失去同步,OpenClaw 可能会保留过时的 `m.direct` 映射,指向旧的一对一房间,而不是当前有效的私信。检查某个对端的当前映射: +如果直接消息状态不同步,OpenClaw 可能会留下过时的 `m.direct` 映射,指向旧的单人房间而不是当前私信。检查某个对象的当前映射: ```bash openclaw matrix direct inspect --user-id @alice:example.org @@ -669,45 +676,45 @@ openclaw matrix direct inspect --user-id @alice:example.org openclaw matrix direct repair --user-id @alice:example.org ``` -这两个命令都支持 `--account `,用于多账号设置。修复流程如下: +这两个命令都接受 `--account `,用于多账号设置。修复流程: -- 优先选择已在 `m.direct` 中映射的严格一对一私信 -- 如果没有,则回退到当前已加入的、与该用户的任意严格一对一私信 +- 优先选择已在 `m.direct` 中映射的严格 1:1 私信 +- 回退到当前已加入的、与该用户的任何严格 1:1 私信 - 如果不存在健康的私信,则创建一个新的直接房间并重写 `m.direct` -它不会自动删除旧房间。它会选择健康的私信并更新映射,以便后续的 Matrix 发送、验证通知和其他私信流程都能定位到正确房间。 +它不会自动删除旧房间。它会选择健康的私信并更新映射,使未来的 Matrix 发送、验证通知和其他直接消息流程以正确房间为目标。 ## Exec 审批 -Matrix 可以作为原生审批客户端。配置位于 `channels.matrix.execApprovals` 下(或按账号覆盖时使用 `channels.matrix.accounts..execApprovals`): +Matrix 可以充当天然的审批客户端。在 `channels.matrix.execApprovals` 下配置(或使用 `channels.matrix.accounts..execApprovals` 进行按账号覆盖): -- `enabled`:通过 Matrix 原生提示传递审批。未设置或为 `"auto"` 时,一旦至少能解析出一个审批人,Matrix 就会自动启用。设置为 `false` 可显式禁用。 -- `approvers`:允许审批 exec 请求的 Matrix 用户 ID(`@owner:example.org`)。可选——会回退到 `channels.matrix.dm.allowFrom`。 -- `target`:提示发送到哪里。`"dm"`(默认)发送到审批人的私信;`"channel"` 发送到原始 Matrix 房间或私信;`"both"` 同时发送到两处。 -- `agentFilter` / `sessionFilter`:可选允许列表,用于限制哪些智能体/会话会触发 Matrix 传递。 +- `enabled`:通过 Matrix 原生提示交付审批。未设置或为 `"auto"` 时,只要能解析出至少一个审批者,Matrix 就会自动启用。设置为 `false` 可显式禁用。 +- `approvers`:允许批准 exec 请求的 Matrix 用户 ID(`@owner:example.org`)。可选,会回退到 `channels.matrix.dm.allowFrom`。 +- `target`:提示发送位置。`"dm"`(默认)发送到审批者私信;`"channel"` 发送到发起的 Matrix 房间或私信;`"both"` 两者都发送。 +- `agentFilter` / `sessionFilter`:可选允许列表,用于指定哪些智能体/会话触发 Matrix 交付。 不同审批类型的授权略有不同: - **Exec 审批** 使用 `execApprovals.approvers`,并回退到 `dm.allowFrom`。 - **插件审批** 仅通过 `dm.allowFrom` 授权。 -这两种审批都共享 Matrix 回应快捷方式和消息更新。审批人在主审批消息上会看到回应快捷方式: +两种类型共享 Matrix 响应快捷方式和消息更新。审批者会在主审批消息上看到响应快捷方式: - `✅` 允许一次 - `❌` 拒绝 -- `♾️` 始终允许(当实际的 exec 策略允许时) +- `♾️` 始终允许(当有效 exec 策略允许时) 回退斜杠命令:`/approve allow-once`、`/approve allow-always`、`/approve deny`。 -只有已解析出的审批人才能批准或拒绝。通过渠道传递 exec 审批时会包含命令文本——仅应在受信任房间中启用 `channel` 或 `both`。 +只有已解析的审批者才能批准或拒绝。exec 审批的渠道交付会包含命令文本,只应在可信房间中启用 `channel` 或 `both`。 -相关内容: [Exec 审批](/zh-CN/tools/exec-approvals)。 +相关:[Exec 审批](/zh-CN/tools/exec-approvals)。 ## 斜杠命令 -斜杠命令(`/new`、`/reset`、`/model`、`/focus`、`/unfocus`、`/agents`、`/session`、`/acp`、`/approve` 等)可直接在私信中使用。在房间中,OpenClaw 还会识别以前缀为机器人自身 Matrix 提及的命令,因此 `@bot:server /new` 会触发命令路径,而无需自定义提及正则。这使机器人能够响应 Element 及类似客户端发出的房间风格 `@mention /command` 帖子——即用户在输入命令前先通过 Tab 补全了机器人。 +斜杠命令(`/new`、`/reset`、`/model`、`/focus`、`/unfocus`、`/agents`、`/session`、`/acp`、`/approve` 等)可直接在私信中使用。在房间中,OpenClaw 也会识别以机器人自己的 Matrix 提及作为前缀的命令,因此 `@bot:server /new` 会触发命令路径,无需自定义提及正则。这让机器人能够响应 Element 和类似客户端在用户先用 Tab 补全机器人、再输入命令时发出的房间风格 `@mention /command` 帖子。 -授权规则仍然适用:命令发送者必须满足与普通消息相同的私信或房间允许列表 / owner 策略。 +授权规则仍然适用:命令发送者必须满足与普通消息相同的私信或房间允许列表/所有者策略。 ## 多账号 @@ -741,27 +748,29 @@ Matrix 可以作为原生审批客户端。配置位于 `channels.matrix.execApp **继承:** -- 顶层 `channels.matrix` 值会作为命名账号的默认值,除非账号自身进行了覆盖。 -- 可通过 `groups..account` 将继承的房间条目限定到特定账号。未设置 `account` 的条目会在各账号之间共享;当默认账号配置在顶层时,`account: "default"` 仍然有效。 +- 顶层 `channels.matrix` 值会作为命名账号的默认值,除非账号覆盖它们。 +- 使用 `groups..account` 将继承的房间条目限定到特定账号。没有 `account` 的条目会在账号之间共享;当默认账号在顶层配置时,`account: "default"` 仍然可用。 **默认账号选择:** -- 设置 `defaultAccount`,以指定隐式路由、探测和 CLI 命令优先使用的命名账号。 -- 如果你有多个账号,其中一个账号的名称恰好就是 `default`,即使未设置 `defaultAccount`,OpenClaw 也会隐式使用它。 -- 如果你有多个命名账号且未选择默认账号,CLI 命令将拒绝猜测——请设置 `defaultAccount` 或传入 `--account `。 -- 只有当顶层 `channels.matrix.*` 块的认证完整时(`homeserver` + `accessToken`,或 `homeserver` + `userId` + `password`),它才会被视为隐式 `default` 账号。命名账号在 `homeserver` + `userId` 且缓存凭证可覆盖认证的情况下,仍可被发现。 +- 设置 `defaultAccount` 以选择隐式路由、探测和 CLI 命令优先使用的命名账号。 +- 如果你有多个账号,且其中一个字面上命名为 `default`,即使未设置 `defaultAccount`,OpenClaw 也会隐式使用它。 +- 如果你有多个命名账号且未选择默认账号,CLI 命令会拒绝猜测,请设置 `defaultAccount` 或传入 `--account `。 +- 只有当顶层 `channels.matrix.*` 块的认证完整时(`homeserver` + `accessToken`,或 `homeserver` + `userId` + `password`),它才会被视为隐式 `default` 账号。当缓存凭据覆盖认证时,命名账号仍可从 `homeserver` + `userId` 中发现。 **提升:** -- 当 OpenClaw 在修复或设置期间将单账号配置提升为多账号配置时,如果已存在命名账号,或 `defaultAccount` 已经指向某个命名账号,它会保留现有命名账号。只有 Matrix 认证 / 引导初始化键会移动到提升后的账号中;共享的传递策略键仍保留在顶层。 +- 当 OpenClaw 在修复或设置期间将单账号配置提升为多账号配置时,如果已有命名账号或 `defaultAccount` 已指向某个命名账号,它会保留该账号。只有 Matrix 认证/引导键会移动到提升后的账号;共享交付策略键会保留在顶层。 -有关共享的多账号模式,请参见 [配置参考](/zh-CN/gateway/config-channels#multi-account-all-channels)。 +参见 [配置参考](/zh-CN/gateway/config-channels#multi-account-all-channels),了解共享多账号模式。 -## 私有 / 局域网 homeserver +## 私有/LAN 主服务器 -默认情况下,出于 SSRF 防护,OpenClaw 会阻止连接私有 / 内部 Matrix homeserver,除非你为每个账号显式选择启用。 +默认情况下,OpenClaw 会出于 SSRF 防护阻止私有/内部 Matrix 主服务器,除非你 +显式按账号选择启用。 -如果你的 homeserver 运行在 localhost、局域网 / Tailscale IP 或内部主机名上,请为该 Matrix 账号启用 `network.dangerouslyAllowPrivateNetwork`: +如果你的主服务器运行在本地主机、LAN/Tailscale IP 或内部主机名上,请为该 Matrix 账号启用 +`network.dangerouslyAllowPrivateNetwork`: ```json5 { @@ -787,8 +796,8 @@ openclaw matrix account add \ --access-token syt_ops_xxx ``` -此显式启用仅允许受信任的私有 / 内部目标。像 -`http://matrix.example.org:8008` 这样的公网明文 homeserver 仍会被阻止。请尽可能优先使用 `https://`。 +此选择启用项只允许受信任的私有/内部目标。公共明文 homeserver(例如 +`http://matrix.example.org:8008`)仍会被阻止。尽可能优先使用 `https://`。 ## 代理 Matrix 流量 @@ -806,107 +815,106 @@ openclaw matrix account add \ } ``` -命名账号可以使用 `channels.matrix.accounts..proxy` 覆盖顶层默认值。 -OpenClaw 会将相同的代理设置用于运行时 Matrix 流量和账号 Status 探测。 +命名账号可以使用 `channels.matrix.accounts..proxy` 覆盖顶层默认值。 +OpenClaw 会将同一代理设置用于运行时 Matrix 流量和账号 Status 探测。 ## 目标解析 -在 OpenClaw 要求你提供房间或用户目标的任何地方,Matrix 都接受以下目标形式: +在 OpenClaw 要求你提供房间或用户目标的任何位置,Matrix 都接受以下目标形式: - 用户:`@user:server`、`user:@user:server` 或 `matrix:user:@user:server` - 房间:`!room:server`、`room:!room:server` 或 `matrix:room:!room:server` - 别名:`#alias:server`、`channel:#alias:server` 或 `matrix:channel:#alias:server` -Matrix 房间 ID 区分大小写。 -在配置显式传递目标、cron 作业、绑定或允许列表时,请使用 Matrix 中房间 ID 的精确大小写。 -OpenClaw 会将内部会话键规范化以便存储,因此这些小写键并不是可靠的 Matrix 传递 ID 来源。 +Matrix 房间 ID 区分大小写。在配置显式投递目标、cron 任务、绑定或允许列表时,请使用 Matrix 中的确切房间 ID 大小写。 +OpenClaw 会保持内部会话键规范化以便存储,因此这些小写键不能作为 Matrix 投递 ID 的可靠来源。 实时目录查找使用已登录的 Matrix 账号: - 用户查找会查询该 homeserver 上的 Matrix 用户目录。 -- 房间查找会直接接受显式房间 ID 和别名,然后回退到搜索该账号已加入房间的名称。 -- 已加入房间名称查找是尽力而为的。如果某个房间名称无法解析为 ID 或别名,在运行时允许列表解析中会被忽略。 +- 房间查找会直接接受显式房间 ID 和别名,然后回退为搜索该账号已加入的房间名称。 +- 已加入房间名称查找是尽力而为的。如果房间名称无法解析为 ID 或别名,运行时允许列表解析会忽略它。 ## 配置参考 -允许列表风格字段(`groupAllowFrom`、`dm.allowFrom`、`groups..users`)接受完整 Matrix 用户 ID(最安全)。精确的目录匹配会在启动时以及监视器运行期间允许列表发生更改时进行解析;无法解析的条目会在运行时被忽略。出于同样原因,房间允许列表更推荐使用房间 ID 或别名。 +允许列表风格的字段(`groupAllowFrom`、`dm.allowFrom`、`groups..users`)接受完整的 Matrix 用户 ID(最安全)。精确目录匹配会在启动时解析,并在监视器运行期间允许列表变更时解析;运行时会忽略无法解析的条目。出于相同原因,房间允许列表优先使用房间 ID 或别名。 ### 账号和连接 - `enabled`:启用或禁用该渠道。 - `name`:账号的可选显示标签。 -- `defaultAccount`:配置了多个 Matrix 账号时的首选账号 ID。 -- `accounts`:按账号命名的覆盖项。顶层 `channels.matrix` 值会作为默认值继承。 +- `defaultAccount`:配置多个 Matrix 账号时首选的账号 ID。 +- `accounts`:命名的逐账号覆盖项。顶层 `channels.matrix` 值会作为默认值继承。 - `homeserver`:homeserver URL,例如 `https://matrix.example.org`。 -- `network.dangerouslyAllowPrivateNetwork`:允许该账号连接到 `localhost`、局域网 / Tailscale IP 或内部主机名。 -- `proxy`:Matrix 流量的可选 HTTP(S) 代理 URL。支持按账号覆盖。 -- `userId`:完整 Matrix 用户 ID(`@bot:example.org`)。 -- `accessToken`:基于令牌认证的访问令牌。支持跨 env/file/exec 提供商的明文和 SecretRef 值([Secrets Management](/zh-CN/gateway/secrets))。 -- `password`:基于密码登录的密码。支持明文和 SecretRef 值。 +- `network.dangerouslyAllowPrivateNetwork`:允许此账号连接到 `localhost`、LAN/Tailscale IP 或内部主机名。 +- `proxy`:用于 Matrix 流量的可选 HTTP(S) 代理 URL。支持逐账号覆盖。 +- `userId`:完整的 Matrix 用户 ID(`@bot:example.org`)。 +- `accessToken`:用于基于令牌认证的访问令牌。支持通过 env/file/exec 提供商使用明文和 SecretRef 值([密钥管理](/zh-CN/gateway/secrets))。 +- `password`:用于基于密码登录的密码。支持明文和 SecretRef 值。 - `deviceId`:显式 Matrix 设备 ID。 - `deviceName`:密码登录时使用的设备显示名称。 -- `avatarUrl`:用于资料同步和 `profile set` 更新的已存储自头像 URL。 -- `initialSyncLimit`:启动同步期间获取的最大事件数。 +- `avatarUrl`:为个人资料同步和 `profile set` 更新存储的自头像 URL。 +- `initialSyncLimit`:启动同步期间抓取的最大事件数。 ### 加密 -- `encryption`:启用端到端加密。默认值:`false`。 -- `startupVerification`:`"if-unverified"`(启用端到端加密时的默认值)或 `"off"`。当该设备未验证时,在启动时自动请求自验证。 +- `encryption`:启用 E2EE。默认值:`false`。 +- `startupVerification`:`"if-unverified"`(E2EE 开启时的默认值)或 `"off"`。当此设备未验证时,启动时自动请求自验证。 - `startupVerificationCooldownHours`:下次自动启动请求前的冷却时间。默认值:`24`。 ### 访问和策略 - `groupPolicy`:`"open"`、`"allowlist"` 或 `"disabled"`。默认值:`"allowlist"`。 - `groupAllowFrom`:房间流量的用户 ID 允许列表。 -- `dm.enabled`:为 `false` 时,忽略所有私信。默认值:`true`。 -- `dm.policy`:`"pairing"`(默认)、`"allowlist"`、`"open"` 或 `"disabled"`。它在机器人加入并将房间归类为私信后生效;不会影响邀请处理。 +- `dm.enabled`:当为 `false` 时,忽略所有私信。默认值:`true`。 +- `dm.policy`:`"pairing"`(默认)、`"allowlist"`、`"open"` 或 `"disabled"`。在机器人已加入并将房间分类为私信后应用;它不影响邀请处理。 - `dm.allowFrom`:私信流量的用户 ID 允许列表。 - `dm.sessionScope`:`"per-user"`(默认)或 `"per-room"`。 -- `dm.threadReplies`:仅用于私信的回复线程覆盖项(`"off"`、`"inbound"`、`"always"`)。 +- `dm.threadReplies`:仅私信的回复串联覆盖项(`"off"`、`"inbound"`、`"always"`)。 - `allowBots`:接受来自其他已配置 Matrix 机器人账号的消息(`true` 或 `"mentions"`)。 -- `allowlistOnly`:为 `true` 时,会将所有处于激活状态的私信策略(`"disabled"` 除外)和 `"open"` 群组策略强制改为 `"allowlist"`。不会更改 `"disabled"` 策略。 -- `autoJoin`:`"always"`、`"allowlist"` 或 `"off"`。默认值:`"off"`。适用于所有 Matrix 邀请,包括类似私信的邀请。 -- `autoJoinAllowlist`:当 `autoJoin` 为 `"allowlist"` 时允许的房间 / 别名。别名条目会针对 homeserver 进行解析,而不是根据受邀房间声明的状态进行解析。 +- `allowlistOnly`:当为 `true` 时,将所有活跃私信策略(除 `"disabled"` 外)和 `"open"` 群组策略强制设为 `"allowlist"`。不会更改 `"disabled"` 策略。 +- `autoJoin`:`"always"`、`"allowlist"` 或 `"off"`。默认值:`"off"`。适用于每个 Matrix 邀请,包括私信样式的邀请。 +- `autoJoinAllowlist`:当 `autoJoin` 为 `"allowlist"` 时允许的房间/别名。别名条目会相对于 homeserver 解析,而不是相对于受邀房间声明的状态解析。 - `contextVisibility`:补充上下文可见性(默认 `"all"`、`"allowlist"`、`"allowlist_quote"`)。 ### 回复行为 - `replyToMode`:`"off"`、`"first"`、`"all"` 或 `"batched"`。 - `threadReplies`:`"off"`、`"inbound"` 或 `"always"`。 -- `threadBindings`:用于线程绑定会话路由和生命周期的按渠道覆盖项。 +- `threadBindings`:线程绑定会话路由和生命周期的逐渠道覆盖项。 - `streaming`:`"off"`(默认)、`"partial"`、`"quiet"`,或对象形式 `{ mode, preview: { toolProgress } }`。`true` ↔ `"partial"`,`false` ↔ `"off"`。 -- `blockStreaming`:为 `true` 时,已完成的助手块会作为独立的进度消息保留。 +- `blockStreaming`:当为 `true` 时,已完成的助手块会保留为独立的进度消息。 - `markdown`:出站文本的可选 Markdown 渲染配置。 -- `responsePrefix`:附加到出站回复前的可选字符串。 -- `textChunkLimit`:当 `chunkMode: "length"` 时,出站分块的字符数上限。默认值:`4000`。 +- `responsePrefix`:添加到出站回复前的可选字符串。 +- `textChunkLimit`:当 `chunkMode: "length"` 时,出站分块的字符大小。默认值:`4000`。 - `chunkMode`:`"length"`(默认,按字符数拆分)或 `"newline"`(按行边界拆分)。 -- `historyLimit`:当房间消息触发智能体时,作为 `InboundHistory` 包含的最近房间消息数量。回退到 `messages.groupChat.historyLimit`;有效默认值为 `0`(禁用)。 -- `mediaMaxMb`:用于出站发送和入站处理的媒体大小上限,单位 MB。 +- `historyLimit`:当房间消息触发智能体时,作为 `InboundHistory` 包含的近期房间消息数量。回退为 `messages.groupChat.historyLimit`;有效默认值为 `0`(禁用)。 +- `mediaMaxMb`:出站发送和入站处理的媒体大小上限,单位为 MB。 -### 回应设置 +### 表情反应设置 -- `ackReaction`:此渠道 / 账号的确认回应覆盖项。 -- `ackReactionScope`:作用域覆盖(默认 `"group-mentions"`、`"group-all"`、`"direct"`、`"all"`、`"none"`、`"off"`)。 -- `reactionNotifications`:入站回应通知模式(默认 `"own"`、`"off"`)。 +- `ackReaction`:此渠道/账号的确认表情反应覆盖项。 +- `ackReactionScope`:范围覆盖项(默认 `"group-mentions"`、`"group-all"`、`"direct"`、`"all"`、`"none"`、`"off"`)。 +- `reactionNotifications`:入站表情反应通知模式(默认 `"own"`、`"off"`)。 -### 工具和按房间覆盖 +### 工具和逐房间覆盖项 -- `actions`:按操作的工具门控(`messages`、`reactions`、`pins`、`profile`、`memberInfo`、`channelInfo`、`verification`)。 -- `groups`:按房间的策略映射。解析后,会话身份使用稳定房间 ID。(`rooms` 是旧别名。) - - `groups..account`:将某条继承的房间条目限制到特定账号。 - - `groups..allowBots`:房间级覆盖渠道级设置(`true` 或 `"mentions"`)。 - - `groups..users`:按房间的发送者允许列表。 - - `groups..tools`:按房间的工具允许 / 拒绝覆盖。 - - `groups..autoReply`:按房间的提及门控覆盖。`true` 会禁用该房间的提及要求;`false` 会强制重新启用。 - - `groups..skills`:按房间的 Skills 过滤器。 - - `groups..systemPrompt`:按房间的系统提示片段。 +- `actions`:逐操作工具门控(`messages`、`reactions`、`pins`、`profile`、`memberInfo`、`channelInfo`、`verification`)。 +- `groups`:逐房间策略映射。会话身份在解析后使用稳定的房间 ID。(`rooms` 是旧版别名。) + - `groups..account`:将一个继承的房间条目限制到特定账号。 + - `groups..allowBots`:渠道级设置的逐房间覆盖项(`true` 或 `"mentions"`)。 + - `groups..users`:逐房间发送者允许列表。 + - `groups..tools`:逐房间工具允许/拒绝覆盖项。 + - `groups..autoReply`:逐房间提及门控覆盖项。`true` 会禁用该房间的提及要求;`false` 会强制重新启用。 + - `groups..skills`:逐房间技能筛选器。 + - `groups..systemPrompt`:逐房间系统提示片段。 ### Exec 审批设置 -- `execApprovals.enabled`:通过 Matrix 原生提示传递 exec 审批。 -- `execApprovals.approvers`:允许审批的 Matrix 用户 ID。回退到 `dm.allowFrom`。 +- `execApprovals.enabled`:通过 Matrix 原生提示投递 exec 审批。 +- `execApprovals.approvers`:允许审批的 Matrix 用户 ID。回退为 `dm.allowFrom`。 - `execApprovals.target`:`"dm"`(默认)、`"channel"` 或 `"both"`。 -- `execApprovals.agentFilter` / `execApprovals.sessionFilter`:用于传递的可选智能体 / 会话允许列表。 +- `execApprovals.agentFilter` / `execApprovals.sessionFilter`:用于投递的可选智能体/会话允许列表。 ## 相关内容 @@ -914,4 +922,4 @@ OpenClaw 会将内部会话键规范化以便存储,因此这些小写键并 - [配对](/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/mattermost.md b/docs/zh-CN/channels/mattermost.md index 07a6a6fb6..0ca6f8509 100644 --- a/docs/zh-CN/channels/mattermost.md +++ b/docs/zh-CN/channels/mattermost.md @@ -6,23 +6,23 @@ sidebarTitle: Mattermost summary: Mattermost 机器人设置和 OpenClaw 配置 title: Mattermost x-i18n: - generated_at: "2026-04-28T11:45:51Z" + generated_at: "2026-04-29T05:38:06Z" model: gpt-5.5 provider: openai - source_hash: a6d235f0880d879f1cf491a75bb15088be68c0bc27a97937120f88a2aaaee283 + source_hash: 1926a1d7347ff35ed60f8d5c3e0b26a064863ada213ad0e171776af5a84d8475 source_path: channels/mattermost.md workflow: 16 --- -Status:内置插件(机器人令牌 + WebSocket 事件)。支持渠道、群组和私信。Mattermost 是一个可自托管的团队消息平台;产品详情和下载请参阅官方网站 [mattermost.com](https://mattermost.com)。 +Status: 内置插件(bot token + WebSocket 事件)。支持渠道、组和私信。Mattermost 是一个可自托管的团队消息平台;产品详情和下载请查看官方网站 [mattermost.com](https://mattermost.com)。 ## 内置插件 -Mattermost 在当前 OpenClaw 版本中作为内置插件提供,因此常规打包构建无需单独安装。 +Mattermost 在当前 OpenClaw 版本中作为内置插件提供,因此正常的打包构建不需要单独安装。 -如果你使用的是较旧的构建,或自定义安装中排除了 Mattermost,请手动安装: +如果你使用的是较旧构建,或排除了 Mattermost 的自定义安装,请在发布后安装当前 npm 包: @@ -30,23 +30,26 @@ Mattermost 在当前 OpenClaw 版本中作为内置插件提供,因此常规 openclaw plugins install @openclaw/mattermost ``` - + ```bash openclaw plugins install ./path/to/local/mattermost-plugin ``` +如果 npm 报告 OpenClaw 拥有的包已弃用,请使用当前打包的 +OpenClaw 构建,或在较新的 npm 包发布前使用本地检出路径。 + 详情:[插件](/zh-CN/tools/plugin) ## 快速设置 - 当前打包的 OpenClaw 版本已经内置它。较旧/自定义安装可以使用上面的命令手动添加。 + 当前打包的 OpenClaw 版本已内置它。较旧/自定义安装可以使用上面的命令手动添加。 - - 创建一个 Mattermost 机器人账号并复制 **机器人令牌**。 + + 创建一个 Mattermost bot 账号并复制 **bot token**。 复制 Mattermost **基础 URL**(例如 `https://chat.example.com`)。 @@ -92,23 +95,23 @@ Mattermost 在当前 OpenClaw 版本中作为内置插件提供,因此常规 - - 对于 Mattermost,`native: "auto"` 默认禁用。设置 `native: true` 以启用。 - - 如果省略 `callbackUrl`,OpenClaw 会从 Gateway 网关主机/端口 + `callbackPath` 派生一个。 + - `native: "auto"` 对 Mattermost 默认禁用。设置 `native: true` 以启用。 + - 如果省略 `callbackUrl`,OpenClaw 会根据 Gateway 网关主机/端口 + `callbackPath` 推导一个。 - 对于多账号设置,可以在顶层设置 `commands`,也可以在 `channels.mattermost.accounts..commands` 下设置(账号值会覆盖顶层字段)。 - - 命令回调会使用 OpenClaw 注册 `oc_*` 命令时 Mattermost 返回的每条命令令牌进行验证。 - - 当注册失败、启动不完整,或回调令牌与任何已注册命令都不匹配时,斜杠回调会安全失败。 + - 命令回调会使用 OpenClaw 注册 `oc_*` 命令时 Mattermost 返回的逐命令 token 进行验证。 + - 当注册失败、启动不完整,或回调 token 与任何已注册命令不匹配时,斜杠回调会安全失败。 回调端点必须能从 Mattermost 服务器访问。 - 不要将 `callbackUrl` 设置为 `localhost`,除非 Mattermost 与 OpenClaw 运行在同一主机/网络命名空间中。 - - 不要将 `callbackUrl` 设置为你的 Mattermost 基础 URL,除非该 URL 将 `/api/channels/mattermost/command` 反向代理到 OpenClaw。 - - 快速检查方法是 `curl https:///api/channels/mattermost/command`;GET 应从 OpenClaw 返回 `405 Method Not Allowed`,而不是 `404`。 + - 不要将 `callbackUrl` 设置为你的 Mattermost 基础 URL,除非该 URL 会将 `/api/channels/mattermost/command` 反向代理到 OpenClaw。 + - 快速检查方式是 `curl https:///api/channels/mattermost/command`;GET 应该从 OpenClaw 返回 `405 Method Not Allowed`,而不是 `404`。 - 如果你的回调目标是私有/tailnet/内部地址,请设置 Mattermost `ServiceSettings.AllowedUntrustedInternalConnections`,使其包含回调主机/域名。 + 如果你的回调目标是私有/tailnet/内部地址,请将 Mattermost `ServiceSettings.AllowedUntrustedInternalConnections` 设置为包含回调主机/域名。 使用主机/域名条目,不要使用完整 URL。 @@ -120,13 +123,13 @@ Mattermost 在当前 OpenClaw 版本中作为内置插件提供,因此常规 ## 环境变量(默认账号) -如果你更喜欢使用环境变量,请在 Gateway 网关主机上设置这些变量: +如果你更喜欢环境变量,请在 Gateway 网关主机上设置这些项: - `MATTERMOST_BOT_TOKEN=...` - `MATTERMOST_URL=https://chat.example.com` -环境变量只适用于**默认**账号(`default`)。其他账号必须使用配置值。 +环境变量只应用于**默认**账号(`default`)。其他账号必须使用配置值。 `MATTERMOST_URL` 不能从工作区 `.env` 设置;请参阅[工作区 `.env` 文件](/zh-CN/gateway/security)。 @@ -136,11 +139,11 @@ Mattermost 在当前 OpenClaw 版本中作为内置插件提供,因此常规 Mattermost 会自动响应私信。渠道行为由 `chatmode` 控制: - + 仅在渠道中被 @提及时响应。 - 响应每条渠道消息。 + 响应每一条渠道消息。 当消息以触发前缀开头时响应。 @@ -162,17 +165,17 @@ Mattermost 会自动响应私信。渠道行为由 `chatmode` 控制: 说明: -- `onchar` 仍会响应明确的 @提及。 -- 旧版配置仍支持 `channels.mattermost.requireMention`,但推荐使用 `chatmode`。 +- `onchar` 仍会响应显式 @提及。 +- 旧配置仍支持 `channels.mattermost.requireMention`,但首选使用 `chatmode`。 ## 线程和会话 -使用 `channels.mattermost.replyToMode` 控制渠道和群组回复是保留在主渠道中,还是在触发帖子下开启线程。 +使用 `channels.mattermost.replyToMode` 控制渠道和组回复是留在主渠道,还是在触发帖下开启一个线程。 -- `off`(默认):仅当入站帖子已经在线程中时,才在线程中回复。 -- `first`:对于顶层渠道/群组帖子,在该帖子下开启线程,并将对话路由到线程作用域的会话。 +- `off`(默认):仅当入站帖子已经在线程中时才在线程里回复。 +- `first`:对于顶层渠道/组帖子,在该帖子下开启一个线程,并将对话路由到线程作用域的会话。 - `all`:目前在 Mattermost 中与 `first` 行为相同。 -- 直接消息会忽略此设置,并保持非线程形式。 +- 私信会忽略此设置,并保持非线程化。 配置示例: @@ -188,25 +191,25 @@ Mattermost 会自动响应私信。渠道行为由 `chatmode` 控制: 说明: -- 线程作用域会话使用触发帖子 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.groupPolicy = "allowlist"`(需要提及)。 -- 使用 `channels.mattermost.groupAllowFrom` 将发送者加入允许列表(建议使用用户 ID)。 -- 按渠道的提及覆盖项位于 `channels.mattermost.groups..requireMention` 下,或使用 `channels.mattermost.groups["*"].requireMention` 作为默认值。 +- 使用 `channels.mattermost.groupAllowFrom` 允许发送者(推荐使用用户 ID)。 +- 单渠道提及覆盖位于 `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="allowlist"` 进行组检查(即使设置了 `channels.defaults.groupPolicy`)。 示例: @@ -226,7 +229,7 @@ Mattermost 会自动响应私信。渠道行为由 `chatmode` 控制: ## 出站投递目标 -将这些目标格式与 `openclaw message send` 或 cron/webhook 一起使用: +将这些目标格式用于 `openclaw message send` 或 cron/webhooks: - `channel:` 表示渠道 - `user:` 表示私信 @@ -235,7 +238,7 @@ Mattermost 会自动响应私信。渠道行为由 `chatmode` 控制: 裸不透明 ID(如 `64ifufp...`)在 Mattermost 中是**有歧义的**(用户 ID 与渠道 ID)。 -OpenClaw 会按**用户优先**解析它们: +OpenClaw 会**优先按用户解析**: - 如果该 ID 作为用户存在(`GET /api/v4/users/` 成功),OpenClaw 会通过 `/api/v4/channels/direct` 解析直接渠道并发送**私信**。 - 否则,该 ID 会被视为**渠道 ID**。 @@ -245,9 +248,9 @@ OpenClaw 会按**用户优先**解析它们: ## 私信渠道重试 -当 OpenClaw 向 Mattermost 私信目标发送消息并需要先解析直接渠道时,它默认会重试临时性的直接渠道创建失败。 +当 OpenClaw 发送到 Mattermost 私信目标且需要先解析直接渠道时,默认会重试瞬时的直接渠道创建失败。 -使用 `channels.mattermost.dmChannelRetry` 为 Mattermost 插件全局调整该行为,或使用 `channels.mattermost.accounts..dmChannelRetry` 为单个账号调整。 +使用 `channels.mattermost.dmChannelRetry` 为 Mattermost 插件全局调优该行为,或使用 `channels.mattermost.accounts..dmChannelRetry` 为单个账号调优。 ```json5 { @@ -266,13 +269,13 @@ OpenClaw 会按**用户优先**解析它们: 说明: -- 这仅适用于私信渠道创建(`/api/v4/channels/direct`),不适用于每一次 Mattermost API 调用。 -- 重试适用于临时失败,例如速率限制、5xx 响应,以及网络或超时错误。 -- 除 `429` 外的 4xx 客户端错误会被视为永久错误,不会重试。 +- 这仅应用于私信渠道创建(`/api/v4/channels/direct`),不是每一次 Mattermost API 调用。 +- 重试适用于瞬时失败,例如速率限制、5xx 响应,以及网络或超时错误。 +- 除 `429` 之外的 4xx 客户端错误会被视为永久错误,不会重试。 ## 预览流式传输 -Mattermost 会将思考、工具活动和部分回复文本流式传输到单个**草稿预览帖子**中,并在最终答案可以安全发送时就地完成。预览会在同一个帖子 ID 上更新,而不是用逐块消息刷屏。媒体/错误最终结果会取消待处理的预览编辑,并使用常规投递,而不是刷新一个一次性的预览帖子。 +Mattermost 会将思考、工具活动和部分回复文本流式传输到单个**草稿预览帖子**中,并在最终答案可安全发送时原地完成。预览会更新同一个帖子 ID,而不是用逐分块消息刷屏渠道。媒体/错误最终消息会取消待处理的预览编辑,并使用正常投递,而不是刷新一个一次性预览帖子。 通过 `channels.mattermost.streaming` 启用: @@ -288,15 +291,15 @@ Mattermost 会将思考、工具活动和部分回复文本流式传输到单个 - - `partial` 是通常选择:一个预览帖子会随着回复增长而被编辑,然后用完整答案完成。 - - `block` 在预览帖子内使用追加式草稿分块。 - - `progress` 在生成期间显示状态预览,并且只在完成时发布最终答案。 + - `partial` 是常用选择:一个预览帖子会随着回复增长而被编辑,然后用完整答案完成。 + - `block` 在预览帖子中使用追加式草稿分块。 + - `progress` 在生成期间显示 Status 预览,并仅在完成时发布最终答案。 - `off` 禁用预览流式传输。 - - 如果无法就地完成流(例如帖子在流中途被删除),OpenClaw 会回退为发送新的最终帖子,确保回复不会丢失。 - - 仅推理载荷会从渠道帖子中抑制,包括作为 `> Reasoning:` 块引用到达的文本。设置 `/reasoning on` 可以在其他界面查看思考过程;Mattermost 的最终帖子只保留答案。 + - 如果流无法原地完成(例如帖子在流式传输中途被删除),OpenClaw 会回退为发送一个新的最终帖子,确保回复不会丢失。 + - 仅推理 payload 会从渠道帖子中抑制,包括以 `> Reasoning:` 引用块形式到达的文本。设置 `/reasoning on` 可在其他界面中查看思考;Mattermost 最终帖子只保留答案。 - 请参阅[流式传输](/zh-CN/concepts/streaming#preview-streaming-modes)了解渠道映射矩阵。 @@ -304,11 +307,11 @@ Mattermost 会将思考、工具活动和部分回复文本流式传输到单个 ## 表情反应(消息工具) -- 使用 `message action=react`,并设置 `channel=mattermost`。 +- 使用 `message action=react` 并设置 `channel=mattermost`。 - `messageId` 是 Mattermost 帖子 ID。 -- `emoji` 接受 `thumbsup` 或 `:+1:` 这样的名称(冒号可选)。 +- `emoji` 接受类似 `thumbsup` 或 `:+1:` 的名称(冒号可选)。 - 设置 `remove=true`(布尔值)以移除表情反应。 -- 表情反应添加/移除事件会作为系统事件转发到已路由的智能体会话。 +- 表情反应添加/移除事件会作为系统事件转发到路由的智能体会话。 示例: @@ -320,11 +323,11 @@ message action=react channel=mattermost target=channel: messageId=.actions.reactions`。 +- 单账号覆盖:`channels.mattermost.accounts..actions.reactions`。 ## 交互式按钮(消息工具) -发送带有可点击按钮的消息。当用户点击按钮时,智能体会收到所选项并可以响应。 +发送带可点击按钮的消息。当用户点击按钮时,智能体会收到选择并可以响应。 通过向渠道能力添加 `inlineButtons` 来启用按钮: @@ -338,7 +341,7 @@ message action=react channel=mattermost target=channel: messageId= buttons=[[{"text":"Yes","callback_data":"yes"},{"text":"No","callback_data":"no"}]] @@ -350,7 +353,7 @@ message action=send channel=mattermost target=channel: buttons=[[{"te 显示标签。 - 点击时发回的值(用作操作 ID)。 + 点击后发回的值(用作操作 ID)。 按钮样式。 @@ -359,27 +362,27 @@ message action=send channel=mattermost target=channel: buttons=[[{"te 当用户点击按钮时: - - 所有按钮都会替换为一行确认信息(例如,“✓ **Yes** selected by @user”)。 + + 所有按钮都会被替换为一行确认内容(例如:“✓ **是** 已由 @user 选择”)。 - 智能体会将该选择作为入站消息接收并响应。 + 智能体会将该选择作为传入消息接收并响应。 - - 按钮回调使用 HMAC-SHA256 验证(自动处理,无需配置)。 - - Mattermost 会从其 API 响应中去除回调数据(安全功能),因此点击时会移除所有按钮,无法进行部分移除。 - - 包含连字符或下划线的操作 ID 会自动清理(Mattermost 路由限制)。 + - 按钮回调使用 HMAC-SHA256 验证(自动完成,无需配置)。 + - Mattermost 会从其 API 响应中移除回调数据(安全功能),因此点击后会移除所有按钮 — 无法部分移除。 + - 包含连字符或下划线的操作 ID 会被自动清理(Mattermost 路由限制)。 - `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 服务器访问。只有当 Mattermost 和 OpenClaw 在同一主机/网络命名空间上运行时,`localhost` 才有效。 + - `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 服务器访问。只有当 Mattermost 和 OpenClaw 在同一主机/网络命名空间运行时,`localhost` 才有效。 - 如果你的回调目标是私有/tailnet/内部地址,请将其主机/域名添加到 Mattermost `ServiceSettings.AllowedUntrustedInternalConnections`。 @@ -424,12 +427,12 @@ message action=send channel=mattermost target=channel: buttons=[[{"te **关键规则** -1. 附件放在 `props.attachments` 中,而不是顶层 `attachments`(否则会被静默忽略)。 -2. 每个操作都需要 `type: "button"`,否则点击会被静默吞掉。 -3. 每个操作都需要 `id` 字段,Mattermost 会忽略没有 ID 的操作。 +1. 附件放在 `props.attachments` 中,而不是顶层 `attachments`(会被静默忽略)。 +2. 每个操作都需要 `type: "button"` — 没有它,点击会被静默吞掉。 +3. 每个操作都需要 `id` 字段 — Mattermost 会忽略没有 ID 的操作。 4. 操作 `id` 必须**仅包含字母数字字符**(`[a-zA-Z0-9]`)。连字符和下划线会破坏 Mattermost 的服务端操作路由(返回 404)。使用前请移除它们。 -5. `context.action_id` 必须匹配按钮的 `id`,这样确认消息会显示按钮名称(例如“Approve”),而不是原始 ID。 -6. `context.action_id` 是必需的;没有它时交互处理程序会返回 400。 +5. `context.action_id` 必须与按钮的 `id` 匹配,这样确认消息会显示按钮名称(例如 “Approve”),而不是原始 ID。 +6. `context.action_id` 是必需的 — 缺少它时交互处理器会返回 400。 @@ -442,10 +445,10 @@ Gateway 网关使用 HMAC-SHA256 验证按钮点击。外部脚本必须生成 `HMAC-SHA256(key="openclaw-mattermost-interactions", data=botToken)` - 使用除 `_token` 之外的所有字段构建上下文对象。 + 构建包含除 `_token` 之外所有字段的上下文对象。 - 使用**排序键**且**无空格**进行序列化(Gateway 网关使用带排序键的 `JSON.stringify`,会产生紧凑输出)。 + 使用**排序键**并且**不包含空格**进行序列化(Gateway 网关使用带排序键的 `JSON.stringify`,会产生紧凑输出)。 `HMAC-SHA256(key=secret, data=serializedContext)` @@ -475,22 +478,22 @@ context = {**ctx, "_token": token} - Python 的 `json.dumps` 默认会添加空格(`{"key": "val"}`)。使用 `separators=(",", ":")` 以匹配 JavaScript 的紧凑输出(`{"key":"val"}`)。 - - 始终签名**所有**上下文字段(减去 `_token`)。Gateway 网关会移除 `_token`,然后签名剩余的所有内容。只签名子集会导致静默验证失败。 - - 使用 `sort_keys=True`,因为 Gateway 网关会在签名前对键排序,而且 Mattermost 在存储载荷时可能会重新排序上下文字段。 - - 从机器人令牌派生密钥(确定性),不要使用随机字节。创建按钮的进程和执行验证的 Gateway 网关必须使用相同密钥。 + - 始终签名**所有**上下文字段(减去 `_token`)。Gateway 网关会移除 `_token`,然后签名剩余所有内容。只签名子集会导致静默验证失败。 + - 使用 `sort_keys=True` — Gateway 网关在签名前会排序键,并且 Mattermost 在存储载荷时可能会重新排列上下文字段。 + - 从机器人令牌派生密钥(确定性),不要使用随机字节。创建按钮的进程和执行验证的 Gateway 网关必须使用同一个密钥。 ## 目录适配器 -Mattermost 插件包含一个目录适配器,可通过 Mattermost API 解析渠道和用户名。这允许在 `openclaw message send` 以及 cron/webhook 投递中使用 `#channel-name` 和 `@username` 目标。 +Mattermost 插件包含一个目录适配器,可通过 Mattermost API 解析渠道和用户名。这支持在 `openclaw message send` 以及 cron/webhook 递送中使用 `#channel-name` 和 `@username` 目标。 -无需配置,适配器会使用账户配置中的机器人令牌。 +无需配置 — 该适配器会使用账号配置中的机器人令牌。 -## 多账户 +## 多账号 -Mattermost 支持在 `channels.mattermost.accounts` 下配置多个账户: +Mattermost 支持在 `channels.mattermost.accounts` 下配置多个账号: ```json5 { @@ -509,31 +512,31 @@ Mattermost 支持在 `channels.mattermost.accounts` 下配置多个账户: - 确保机器人在该渠道中,并提及它(oncall)、使用触发前缀(onchar),或设置 `chatmode: "onmessage"`。 + 确保机器人已在渠道中并提及它(oncall),使用触发前缀(onchar),或设置 `chatmode: "onmessage"`。 - - - 检查机器人令牌、基础 URL,以及账户是否已启用。 - - 多账户问题:环境变量只适用于 `default` 账户。 + + - 检查机器人令牌、基础 URL,以及账号是否已启用。 + - 多账号问题:环境变量只适用于 `default` 账号。 - - `Unauthorized: invalid command token.`:OpenClaw 未接受回调令牌。典型原因包括: + - `Unauthorized: invalid command token.`:OpenClaw 未接受回调令牌。典型原因: - 斜杠命令注册在启动时失败或仅部分完成 - - 回调命中了错误的 Gateway 网关/账户 - - Mattermost 仍有旧命令指向之前的回调目标 - - Gateway 网关重启后没有重新激活斜杠命令 + - 回调命中了错误的 Gateway 网关/账号 + - Mattermost 仍有旧命令指向先前的回调目标 + - 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`。 + - 如果省略 `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 的操作路由器在非字母数字 ID 上会失效。仅使用 `[a-zA-Z0-9]`。 - - Gateway 网关日志显示 `invalid _token`:HMAC 不匹配。检查你是否签名了所有上下文字段(而不是子集)、使用了排序键,并使用了紧凑 JSON(无空格)。请参阅上面的 HMAC 部分。 - - Gateway 网关日志显示 `missing _token in context`:按钮上下文中没有 `_token` 字段。构建集成载荷时请确保包含该字段。 - - 确认信息显示原始 ID 而不是按钮名称:`context.action_id` 与按钮的 `id` 不匹配。将两者设置为相同的清理后值。 - - 智能体不知道按钮:将 `capabilities: ["inlineButtons"]` 添加到 Mattermost 渠道配置。 + - 按钮显示为白色方框:智能体可能发送了格式错误的按钮数据。请检查每个按钮是否同时包含 `text` 和 `callback_data` 字段。 + - 按钮会渲染但点击无效:确认 Mattermost 服务器配置中的 `AllowedUntrustedInternalConnections` 包含 `127.0.0.1 localhost`,并且 ServiceSettings 中的 `EnablePostActionIntegration` 为 `true`。 + - 点击按钮返回 404:按钮 `id` 很可能包含连字符或下划线。Mattermost 的操作路由器会因非字母数字 ID 而失效。仅使用 `[a-zA-Z0-9]`。 + - Gateway 网关日志显示 `invalid _token`:HMAC 不匹配。检查你是否签名了所有上下文字段(而不是子集)、使用排序键,并使用紧凑 JSON(无空格)。参见上面的 HMAC 部分。 + - Gateway 网关日志显示 `missing _token in context`:按钮上下文中没有 `_token` 字段。确保构建集成载荷时包含它。 + - 确认内容显示原始 ID 而不是按钮名称:`context.action_id` 与按钮的 `id` 不匹配。将两者设置为相同的清理后值。 + - 智能体不知道按钮:将 `capabilities: ["inlineButtons"]` 添加到 Mattermost 渠道配置中。 diff --git a/docs/zh-CN/channels/msteams.md b/docs/zh-CN/channels/msteams.md index 3fe868575..391363714 100644 --- a/docs/zh-CN/channels/msteams.md +++ b/docs/zh-CN/channels/msteams.md @@ -1,72 +1,77 @@ --- read_when: - - 正在开发 Microsoft Teams 渠道功能 -summary: Microsoft Teams 机器人支持状态、功能和配置 + - 正在处理 Microsoft Teams 渠道功能 +summary: Microsoft Teams 机器人支持状态、能力和配置 title: Microsoft Teams x-i18n: - generated_at: "2026-04-27T07:23:43Z" - model: gpt-5.4 + generated_at: "2026-04-29T05:38:02Z" + model: gpt-5.5 provider: openai - source_hash: 243ef0e16429060605ac19ed8d49c6078b6823f3fc94eafd7ea08522db9d13e9 + source_hash: 62dfb6787c86b3aa1baef632654986621fc706ecd1f1c96b83b97b6d6c564d7a source_path: channels/msteams.md - workflow: 15 + workflow: 16 --- -Status:支持文本 + 私信附件;渠道/群组文件发送需要 `sharePointSiteId` + Graph 权限(参见 [在群组聊天中发送文件](#sending-files-in-group-chats))。投票通过 Adaptive Cards 发送。消息操作提供显式的 `upload-file`,用于以文件为先的发送。 +Status:支持文本 + 私信附件;渠道/群组发送文件需要 `sharePointSiteId` + Graph 权限(参见[在群组聊天中发送文件](#sending-files-in-group-chats))。投票通过 Adaptive Cards 发送。消息操作公开了显式的 `upload-file`,用于以文件优先方式发送。 ## 内置插件 -Microsoft Teams 在当前的 OpenClaw 版本中作为内置插件提供,因此在常规打包构建中不需要单独安装。 +Microsoft Teams 在当前 OpenClaw 版本中作为内置插件随附,因此在正常的打包构建中不需要 +单独安装。 -如果你使用的是较旧的构建版本,或是不包含内置 Teams 的自定义安装,请手动安装: +如果你使用的是较旧的构建,或自定义安装中排除了内置 Teams, +请在发布后安装当前的 npm 包: ```bash openclaw plugins install @openclaw/msteams ``` -本地检出版本(从 git 仓库运行时): +如果 npm 报告 OpenClaw 拥有的包已弃用,请使用当前的打包版 +OpenClaw 构建,或在更新的 npm 包发布前使用本地检出路径。 + +本地检出(从 git 仓库运行时): ```bash openclaw plugins install ./path/to/local/msteams-plugin ``` -详情: [Plugins](/zh-CN/tools/plugin) +详情:[插件](/zh-CN/tools/plugin) -## 快速开始 +## 快速设置 -[`@microsoft/teams.cli`](https://www.npmjs.com/package/@microsoft/teams.cli) 可通过一条命令完成机器人注册、清单创建和凭证生成。 +[`@microsoft/teams.cli`](https://www.npmjs.com/package/@microsoft/teams.cli) 可通过单条命令处理 bot 注册、manifest 创建和凭证生成。 **1. 安装并登录** ```bash npm install -g @microsoft/teams.cli@preview teams login -teams status # 验证你已登录,并查看你的租户信息 +teams status # verify you're logged in and see your tenant info ``` -Teams CLI 当前仍处于预览版。命令和标志可能会在不同版本之间发生变化。 +Teams CLI 目前处于预览阶段。命令和标志可能会在不同版本之间变化。 **2. 启动隧道**(Teams 无法访问 localhost) -如果你还没有安装 devtunnel CLI,请先安装并完成身份验证(参见[入门指南](https://learn.microsoft.com/en-us/azure/developer/dev-tunnels/get-started))。 +如果你还没有安装并认证 devtunnel CLI,请先完成这些步骤([入门指南](https://learn.microsoft.com/en-us/azure/developer/dev-tunnels/get-started))。 ```bash -# 一次性设置(跨会话保持持久 URL): +# One-time setup (persistent URL across sessions): devtunnel create my-openclaw-bot --allow-anonymous devtunnel port create my-openclaw-bot -p 3978 --protocol auto -# 每次开发会话: +# Each dev session: devtunnel host my-openclaw-bot -# 你的端点:https://.devtunnels.ms/api/messages +# Your endpoint: https://.devtunnels.ms/api/messages ``` -必须使用 `--allow-anonymous`,因为 Teams 无法通过 devtunnels 进行身份验证。每个传入的机器人请求仍会由 Teams SDK 自动验证。 +需要 `--allow-anonymous`,因为 Teams 无法通过 devtunnels 进行认证。每个传入的 bot 请求仍会由 Teams SDK 自动验证。 -替代方案:`ngrok http 3978` 或 `tailscale funnel 3978`(但这些方案可能会在每次会话中更改 URL)。 +替代方案:`ngrok http 3978` 或 `tailscale funnel 3978`(但这些方案可能会在每个会话中更改 URL)。 **3. 创建应用** @@ -76,16 +81,16 @@ teams app create \ --endpoint "https:///api/messages" ``` -这条命令会一次性完成以下操作: +这一条命令会: -- 创建 Entra ID(Azure AD)应用 +- 创建 Entra ID(Azure AD)应用程序 - 生成客户端密钥 -- 构建并上传 Teams 应用清单(包含图标) -- 注册机器人(默认由 Teams 托管 —— 无需 Azure 订阅) +- 构建并上传 Teams 应用 manifest(包含图标) +- 注册 bot(默认由 Teams 托管,不需要 Azure 订阅) -输出中会显示 `CLIENT_ID`、`CLIENT_SECRET`、`TENANT_ID` 和一个 **Teams App ID** —— 请记下这些值,以便用于后续步骤。它还会提示你直接在 Teams 中安装该应用。 +输出会显示 `CLIENT_ID`、`CLIENT_SECRET`、`TENANT_ID` 和一个 **Teams App ID**,请记下这些值以供后续步骤使用。它还会提供直接在 Teams 中安装该应用的选项。 -**4. 配置 OpenClaw**,使用输出中的凭证: +**4. 使用输出中的凭证配置 OpenClaw:** ```json5 { @@ -105,37 +110,37 @@ teams app create \ **5. 在 Teams 中安装应用** -`teams app create` 会提示你安装该应用 —— 选择“Install in Teams”。如果你跳过了这一步,稍后可以获取链接: +`teams app create` 会提示你安装应用,请选择“在 Teams 中安装”。如果你跳过了这一步,可以稍后获取链接: ```bash teams app get --install-link ``` -**6. 验证一切正常** +**6. 验证一切正常工作** ```bash teams app doctor ``` -这会对机器人注册、AAD 应用配置、清单有效性和 SSO 设置运行诊断。 +这会对 bot 注册、AAD 应用配置、manifest 有效性和 SSO 设置运行诊断。 -对于生产部署,建议考虑使用[联合身份验证](/zh-CN/channels/msteams#federated-authentication-certificate-plus-managed-identity)(证书或托管身份)来替代客户端密钥。 +对于生产部署,请考虑使用[联合认证](/zh-CN/channels/msteams#federated-authentication-certificate-plus-managed-identity)(证书或托管身份)而不是客户端密钥。 -默认会阻止群组聊天(`channels.msteams.groupPolicy: "allowlist"`)。如需允许群组回复,请设置 `channels.msteams.groupAllowFrom`,或使用 `groupPolicy: "open"` 以允许任意成员(默认仍需提及)。 +群组聊天默认被阻止(`channels.msteams.groupPolicy: "allowlist"`)。要允许群组回复,请设置 `channels.msteams.groupAllowFrom`,或使用 `groupPolicy: "open"` 允许任何成员(受提及门控)。 ## 目标 - 通过 Teams 私信、群组聊天或渠道与 OpenClaw 对话。 -- 保持路由确定性:回复始终返回到消息到达时所在的渠道。 -- 默认采用安全的渠道行为(除非另有配置,否则必须提及)。 +- 保持路由确定性:回复始终返回到它们到达的渠道。 +- 默认使用安全的渠道行为(除非另行配置,否则需要提及)。 ## 配置写入 -默认情况下,Microsoft Teams 被允许写入由 `/config set|unset` 触发的配置更新(需要 `commands.config: true`)。 +默认情况下,Microsoft Teams 允许写入由 `/config set|unset` 触发的配置更新(需要 `commands.config: true`)。 -如需禁用: +可通过以下配置禁用: ```json5 { @@ -147,17 +152,17 @@ teams app doctor **私信访问** -- 默认:`channels.msteams.dmPolicy = "pairing"`。未知发送者会被忽略,直到获得批准。 +- 默认:`channels.msteams.dmPolicy = "pairing"`。未知发送者在获批前会被忽略。 - `channels.msteams.allowFrom` 应使用稳定的 AAD 对象 ID。 -- 不要依赖 UPN/显示名称匹配来实现 allowlist —— 它们可能会变化。OpenClaw 默认禁用直接名称匹配;如需启用,请显式设置 `channels.msteams.dangerouslyAllowNameMatching: true`。 -- 当凭证权限允许时,向导可以通过 Microsoft Graph 将名称解析为 ID。 +- 不要依赖 UPN/显示名称匹配来设置允许列表,因为它们可能会变化。OpenClaw 默认禁用直接名称匹配;如需启用,请显式设置 `channels.msteams.dangerouslyAllowNameMatching: true`。 +- 当凭证允许时,向导可以通过 Microsoft Graph 将名称解析为 ID。 **群组访问** -- 默认:`channels.msteams.groupPolicy = "allowlist"`(除非你添加 `groupAllowFrom`,否则会被阻止)。使用 `channels.defaults.groupPolicy` 可在未设置时覆盖默认值。 +- 默认:`channels.msteams.groupPolicy = "allowlist"`(除非添加 `groupAllowFrom`,否则会被阻止)。在未设置时,可使用 `channels.defaults.groupPolicy` 覆盖默认值。 - `channels.msteams.groupAllowFrom` 控制哪些发送者可以在群组聊天/渠道中触发(回退到 `channels.msteams.allowFrom`)。 -- 设置 `groupPolicy: "open"` 可允许任意成员(默认仍需提及)。 -- 如需**禁止所有渠道**,请设置 `channels.msteams.groupPolicy: "disabled"`。 +- 设置 `groupPolicy: "open"` 可允许任何成员(默认仍受提及门控)。 +- 要不允许**任何渠道**,请设置 `channels.msteams.groupPolicy: "disabled"`。 示例: @@ -172,14 +177,14 @@ teams app doctor } ``` -**Teams + 渠道 allowlist** +**Teams + 渠道允许列表** -- 通过在 `channels.msteams.teams` 下列出团队和渠道来限定群组/渠道回复范围。 -- 键应使用稳定的团队 ID 和渠道会话 ID。 -- 当 `groupPolicy="allowlist"` 且存在 teams allowlist 时,只接受列出的团队/渠道(需提及)。 -- 配置向导接受 `Team/Channel` 条目并会为你保存。 -- 启动时,OpenClaw 会将团队/渠道和用户 allowlist 名称解析为 ID(当 Graph 权限允许时),并记录映射; - 未能解析的团队/渠道名称会按原样保留,但默认会在路由中被忽略,除非启用 `channels.msteams.dangerouslyAllowNameMatching: true`。 +- 通过在 `channels.msteams.teams` 下列出 teams 和渠道来限定群组/渠道回复范围。 +- 键应使用稳定的 team ID 和渠道会话 ID。 +- 当 `groupPolicy="allowlist"` 且存在 teams 允许列表时,仅接受列出的 teams/渠道(受提及门控)。 +- 配置向导接受 `Team/Channel` 条目并为你存储它们。 +- 启动时,OpenClaw 会将 team/channel 和用户允许列表名称解析为 ID(当 Graph 权限允许时), + 并记录映射;未解析的 team/channel 名称会按原样保留,但默认会在路由时被忽略,除非启用 `channels.msteams.dangerouslyAllowNameMatching: true`。 示例: @@ -203,66 +208,66 @@ teams app doctor
手动设置(不使用 Teams CLI) -如果你无法使用 Teams CLI,也可以通过 Azure 门户手动设置机器人。 +如果你无法使用 Teams CLI,可以通过 Azure Portal 手动设置 bot。 ### 工作原理 -1. 确保 Microsoft Teams 插件可用(当前版本中为内置)。 +1. 确保 Microsoft Teams 插件可用(当前版本中已内置)。 2. 创建一个 **Azure Bot**(App ID + 密钥 + tenant ID)。 -3. 构建一个引用该机器人的 **Teams 应用包**,并包含下方的 RSC 权限。 -4. 将 Teams 应用上传/安装到团队中(或用于私信的个人范围)。 -5. 在 `~/.openclaw/openclaw.json` 中配置 `msteams`(或使用环境变量),然后启动 Gateway 网关。 -6. Gateway 网关 默认在 `/api/messages` 上监听 Bot Framework webhook 流量。 +3. 构建一个引用该 bot 并包含以下 RSC 权限的 **Teams 应用包**。 +4. 将 Teams 应用上传/安装到一个 team(或用于私信的个人范围)。 +5. 在 `~/.openclaw/openclaw.json`(或环境变量)中配置 `msteams` 并启动 Gateway 网关。 +6. Gateway 网关默认在 `/api/messages` 上监听 Bot Framework webhook 流量。 ### 第 1 步:创建 Azure Bot -1. 前往 [Create Azure Bot](https://portal.azure.com/#create/Microsoft.AzureBot) +1. 前往[创建 Azure Bot](https://portal.azure.com/#create/Microsoft.AzureBot) 2. 填写 **Basics** 选项卡: - | Field | Value | + | 字段 | 值 | | ------------------ | -------------------------------------------------------- | - | **Bot handle** | 你的机器人名称,例如 `openclaw-msteams`(必须唯一) | - | **Subscription** | 选择你的 Azure 订阅 | - | **Resource group** | 新建或使用现有资源组 | - | **Pricing tier** | 开发/测试使用 **Free** | - | **Type of App** | **Single Tenant**(推荐 —— 见下方说明) | - | **Creation type** | **Create new Microsoft App ID** | + | **Bot 句柄** | 你的 bot 名称,例如 `openclaw-msteams`(必须唯一) | + | **订阅** | 选择你的 Azure 订阅 | + | **资源组** | 新建或使用现有资源组 | + | **定价层级** | **Free**,用于开发/测试 | + | **应用类型** | **Single Tenant**(推荐,参见下方说明) | + | **创建类型** | **Create new Microsoft App ID** | -在 2025-07-31 之后,新建多租户机器人已被弃用。新机器人请使用 **Single Tenant**。 +新的多租户 bot 创建已在 2025-07-31 后弃用。新 bot 请使用 **Single Tenant**。 -3. 点击 **Review + create** → **Create**(等待约 1–2 分钟) +3. 点击 **Review + create** → **Create**(等待约 1-2 分钟) ### 第 2 步:获取凭证 1. 前往你的 Azure Bot 资源 → **Configuration** -2. 复制 **Microsoft App ID** → 这就是你的 `appId` -3. 点击 **Manage Password** → 前往应用注册 -4. 在 **Certificates & secrets** 下 → **New client secret** → 复制 **Value** → 这就是你的 `appPassword` -5. 前往 **Overview** → 复制 **Directory (tenant) ID** → 这就是你的 `tenantId` +2. 复制 **Microsoft App ID** → 这是你的 `appId` +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` + - 生产:`https://your-domain.com/api/messages` - 本地开发:使用隧道(参见下方[本地开发](#local-development-tunneling)) ### 第 4 步:启用 Teams 渠道 -1. 在 Azure Bot 中 → **Channels** +1. 在 Azure Bot → **Channels** 2. 点击 **Microsoft Teams** → Configure → Save 3. 接受服务条款 -### 第 5 步:构建 Teams 应用清单 +### 第 5 步:构建 Teams 应用 Manifest - 包含一个 `bot` 条目,其中 `botId = `。 -- 作用域:`personal`、`team`、`groupChat`。 -- `supportsFiles: true`(个人作用域文件处理所必需)。 -- 添加 RSC 权限(参见 [RSC Permissions](#current-teams-rsc-permissions-manifest))。 +- 范围:`personal`、`team`、`groupChat`。 +- `supportsFiles: true`(个人范围文件处理必需)。 +- 添加 RSC 权限(参见 [RSC 权限](#current-teams-rsc-permissions-manifest))。 - 创建图标:`outline.png`(32x32)和 `color.png`(192x192)。 -- 将这三个文件一起打包为 zip:`manifest.json`、`outline.png`、`color.png`。 +- 将这三个文件一起压缩:`manifest.json`、`outline.png`、`color.png`。 ### 第 6 步:配置 OpenClaw @@ -284,24 +289,24 @@ teams app doctor ### 第 7 步:运行 Gateway 网关 -当插件可用且存在带有凭证的 `msteams` 配置时,Teams 渠道会自动启动。 +当插件可用且存在带凭证的 `msteams` 配置时,Teams 渠道会自动启动。
-## 联合身份验证(证书 + 托管身份) +## 联合认证(证书加托管身份) > 添加于 2026.3.24 -对于生产部署,OpenClaw 支持 **联合身份验证**,作为比客户端密钥更安全的替代方案。当前提供两种方式: +对于生产部署,OpenClaw 支持**联合认证**,作为客户端密钥的更安全替代方案。可使用两种方法: -### 选项 A:基于证书的身份验证 +### 选项 A:基于证书的认证 -使用已注册到你的 Entra ID 应用注册中的 PEM 证书。 +使用在你的 Entra ID 应用注册中注册的 PEM 证书。 **设置:** -1. 生成或获取一个证书(PEM 格式,包含私钥)。 -2. 在 Entra ID → 应用注册 → **Certificates & secrets** → **Certificates** → 上传公钥证书。 +1. 生成或获取证书(带私钥的 PEM 格式)。 +2. 在 Entra ID → App Registration → **Certificates & secrets** → **Certificates** → 上传公钥证书。 **配置:** @@ -325,22 +330,22 @@ teams app doctor - `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. 机器人所在的 pod/VM 拥有一个托管身份(系统分配或用户分配)。 -2. 一个 **联合身份凭证** 将该托管身份关联到 Entra ID 应用注册。 +1. bot pod/VM 拥有托管身份(系统分配或用户分配)。 +2. **联合身份凭证**将托管身份链接到 Entra ID 应用注册。 3. 运行时,OpenClaw 使用 `@azure/identity` 从 Azure IMDS 端点(`169.254.169.254`)获取令牌。 -4. 该令牌会传递给 Teams SDK,用于机器人身份验证。 +4. 令牌会传递给 Teams SDK,用于 bot 认证。 -**前置条件:** +**前提条件:** - 已启用托管身份的 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`) **配置(系统分配的托管身份):** @@ -359,7 +364,7 @@ teams app doctor } ``` -**配置(用户分配的托管身份):** +**配置(用户分配的托管标识):** ```json5 { @@ -381,14 +386,14 @@ teams app doctor - `MSTEAMS_AUTH_TYPE=federated` - `MSTEAMS_USE_MANAGED_IDENTITY=true` -- `MSTEAMS_MANAGED_IDENTITY_CLIENT_ID=`(仅用于用户分配) +- `MSTEAMS_MANAGED_IDENTITY_CLIENT_ID=`(仅适用于用户分配的标识) -### AKS Workload Identity 设置 +### AKS 工作负载标识设置 -对于使用 workload identity 的 AKS 部署: +对于使用工作负载标识的 AKS 部署: -1. 在你的 AKS 集群上**启用 workload identity**。 -2. 在 Entra ID 应用注册上**创建联合身份凭证**: +1. 在你的 AKS 集群上**启用工作负载标识**。 +2. 在 Entra ID 应用注册上**创建联合标识凭据**: ```bash az ad app federated-credential create --id --parameters '{ @@ -399,7 +404,7 @@ teams app doctor }' ``` -3. 使用应用客户端 ID **为 Kubernetes service account 添加注解**: +3. 使用应用客户端 ID **注释 Kubernetes 服务账户**: ```yaml apiVersion: v1 @@ -410,7 +415,7 @@ teams app doctor azure.workload.identity/client-id: "" ``` -4. 为 **pod 添加标签**,以启用 workload identity 注入: +4. 为工作负载标识注入**标记 Pod**: ```yaml metadata: @@ -418,28 +423,28 @@ teams app doctor 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,请添加一条出站规则,允许流量通过端口 80 访问 `169.254.169.254/32`。 -### 身份验证类型对比 +### 身份验证类型比较 -| Method | Config | Pros | Cons | -| -------------------- | ---------------------------------------------- | ---------------------------------- | ------------------------------------- | -| **Client secret** | `appPassword` | 设置简单 | 需要轮换密钥,安全性较低 | -| **Certificate** | `authType: "federated"` + `certificatePath` | 无需通过网络共享密钥 | 证书管理有额外开销 | -| **Managed Identity** | `authType: "federated"` + `useManagedIdentity` | 无密码,无需管理密钥 | 需要 Azure 基础设施 | +| 方法 | 配置 | 优点 | 缺点 | +| -------------------- | ---------------------------------------------- | ---------------------------- | ---------------------------- | +| **客户端密钥** | `appPassword` | 设置简单 | 需要轮换密钥,安全性较低 | +| **证书** | `authType: "federated"` + `certificatePath` | 没有通过网络共享的密钥 | 证书管理开销 | +| **托管标识** | `authType: "federated"` + `useManagedIdentity` | 无密码,无需管理密钥 | 需要 Azure 基础设施 | -**默认行为:** 当未设置 `authType` 时,OpenClaw 默认使用客户端密钥身份验证。现有配置无需修改即可继续工作。 +**默认行为:** 未设置 `authType` 时,OpenClaw 默认使用客户端密钥身份验证。现有配置无需更改即可继续工作。 ## 本地开发(隧道) -Teams 无法访问 `localhost`。请使用持久化开发隧道,以便你的 URL 在不同会话之间保持不变: +Teams 无法访问 `localhost`。使用持久开发隧道,让你的 URL 在不同会话中保持不变: ```bash -# 一次性设置: +# One-time setup: devtunnel create my-openclaw-bot --allow-anonymous devtunnel port create my-openclaw-bot -p 3978 --protocol auto -# 每次开发会话: +# Each dev session: devtunnel host my-openclaw-bot ``` @@ -459,64 +464,64 @@ teams app update --endpoint "https:///api/messages" teams app doctor ``` -这会一次性检查机器人注册、AAD 应用、清单和 SSO 配置。 +一次性检查机器人注册、AAD 应用、清单和 SSO 配置。 **发送测试消息:** -1. 安装 Teams 应用(使用 `teams app get --install-link` 提供的安装链接) -2. 在 Teams 中找到该机器人并发送一条私信 -3. 检查 Gateway 网关 日志中的传入活动 +1. 安装 Teams 应用(使用 `teams app get --install-link` 中的安装链接) +2. 在 Teams 中找到机器人并发送私信 +3. 检查 Gateway 网关日志中是否有传入活动 ## 环境变量 -所有配置键也都可以通过环境变量设置: +所有配置键都可以改用环境变量设置: - `MSTEAMS_APP_ID` - `MSTEAMS_APP_PASSWORD` - `MSTEAMS_TENANT_ID` - `MSTEAMS_AUTH_TYPE`(可选:`"secret"` 或 `"federated"`) - `MSTEAMS_CERTIFICATE_PATH`(联合身份验证 + 证书) -- `MSTEAMS_CERTIFICATE_THUMBPRINT`(可选,身份验证不要求) -- `MSTEAMS_USE_MANAGED_IDENTITY`(联合身份验证 + 托管身份) -- `MSTEAMS_MANAGED_IDENTITY_CLIENT_ID`(仅用于用户分配的 MI) +- `MSTEAMS_CERTIFICATE_THUMBPRINT`(可选,身份验证不需要) +- `MSTEAMS_USE_MANAGED_IDENTITY`(联合身份验证 + 托管标识) +- `MSTEAMS_MANAGED_IDENTITY_CLIENT_ID`(仅限用户分配的 MI) ## 成员信息操作 -OpenClaw 为 Microsoft Teams 提供了基于 Graph 的 `member-info` 操作,因此智能体和自动化可以直接通过 Microsoft Graph 解析渠道成员详情(显示名称、电子邮件、角色)。 +OpenClaw 为 Microsoft Teams 暴露由 Graph 支持的 `member-info` 操作,让智能体和自动化可以直接从 Microsoft Graph 解析渠道成员详细信息(显示名称、电子邮件、角色)。 要求: - `Member.Read.Group` RSC 权限(已包含在推荐清单中) -- 对于跨团队查询:具有管理员同意的 `User.Read.All` Graph 应用程序权限 +- 对于跨团队查找:需要带管理员同意的 `User.Read.All` Graph 应用程序权限 -该操作由 `channels.msteams.actions.memberInfo` 控制(默认:当 Graph 凭证可用时启用)。 +该操作由 `channels.msteams.actions.memberInfo` 控制(默认:当 Graph 凭据可用时启用)。 ## 历史上下文 -- `channels.msteams.historyLimit` 控制会包装进提示中的最近渠道/群组消息数量。 -- 回退到 `messages.groupChat.historyLimit`。设置为 `0` 可禁用(默认值为 50)。 -- 获取到的线程历史会按发送者 allowlist(`allowFrom` / `groupAllowFrom`)进行过滤,因此线程上下文播种仅包含来自允许发送者的消息。 -- 引用的附件上下文(从 Teams 回复 HTML 派生的 `ReplyTo*`)当前会按接收原样传递。 -- 换句话说,allowlist 控制谁可以触发智能体;目前只有特定的补充上下文路径会被过滤。 -- 私信历史可通过 `channels.msteams.dmHistoryLimit`(用户轮次)进行限制。按用户覆盖:`channels.msteams.dms[""].historyLimit`。 +- `channels.msteams.historyLimit` 控制最近多少条渠道/群组消息会被包装进提示词。 +- 回退到 `messages.groupChat.historyLimit`。设置为 `0` 可禁用(默认值 50)。 +- 获取的线程历史会按发送者允许列表(`allowFrom` / `groupAllowFrom`)过滤,因此线程上下文填充只包含来自允许发送者的消息。 +- 引用附件上下文(从 Teams 回复 HTML 派生的 `ReplyTo*`)目前会按接收到的内容传递。 +- 换句话说,允许列表控制谁可以触发智能体;目前只有特定的补充上下文路径会被过滤。 +- 私信历史可以用 `channels.msteams.dmHistoryLimit`(用户轮次)限制。按用户覆盖:`channels.msteams.dms[""].historyLimit`。 ## 当前 Teams RSC 权限(清单) -这些是我们 Teams 应用清单中**现有的 resourceSpecific 权限**。它们仅在安装该应用的团队/聊天内部生效。 +这些是我们的 Teams 应用清单中**现有的 resourceSpecific 权限**。它们只适用于安装了该应用的团队/聊天内部。 -**用于渠道(团队作用域):** +**对于渠道(团队范围):** -- `ChannelMessage.Read.Group`(Application)- 无需 @mention 即可接收所有渠道消息 -- `ChannelMessage.Send.Group`(Application) -- `Member.Read.Group`(Application) -- `Owner.Read.Group`(Application) -- `ChannelSettings.Read.Group`(Application) -- `TeamMember.Read.Group`(Application) -- `TeamSettings.Read.Group`(Application) +- `ChannelMessage.Read.Group`(应用程序)- 接收所有渠道消息,无需 @mention +- `ChannelMessage.Send.Group`(应用程序) +- `Member.Read.Group`(应用程序) +- `Owner.Read.Group`(应用程序) +- `ChannelSettings.Read.Group`(应用程序) +- `TeamMember.Read.Group`(应用程序) +- `TeamSettings.Read.Group`(应用程序) -**用于群组聊天:** +**对于群组聊天:** -- `ChatMessage.Read.Chat`(Application)- 无需 @mention 即可接收所有群组聊天消息 +- `ChatMessage.Read.Chat`(应用程序)- 接收所有群组聊天消息,无需 @mention 要通过 Teams CLI 添加 RSC 权限: @@ -524,9 +529,9 @@ OpenClaw 为 Microsoft Teams 提供了基于 Graph 的 `member-info` 操作, teams app rsc add ChannelMessage.Read.Group --type Application ``` -## Teams 清单示例(已脱敏) +## Teams 清单示例(已删减) -这是一个包含所需字段的最小有效示例。请替换其中的 ID 和 URL。 +包含所需字段的最小有效示例。替换 ID 和 URL。 ```json5 { @@ -576,41 +581,41 @@ teams app rsc add ChannelMessage.Read.Group --type Application ### 清单注意事项(必需字段) -- `bots[].botId` **必须**与 Azure Bot App ID 匹配。 -- `webApplicationInfo.id` **必须**与 Azure Bot App ID 匹配。 -- `bots[].scopes` 必须包含你计划使用的表面(`personal`、`team`、`groupChat`)。 -- `bots[].supportsFiles: true` 是个人作用域中文件处理的必需项。 -- 如果你希望处理渠道流量,`authorization.permissions.resourceSpecific` 必须包含渠道读取/发送权限。 +- `bots[].botId` **必须**与 Azure Bot 应用 ID 匹配。 +- `webApplicationInfo.id` **必须**与 Azure Bot 应用 ID 匹配。 +- `bots[].scopes` 必须包含你计划使用的界面(`personal`、`team`、`groupChat`)。 +- 个人范围中的文件处理需要 `bots[].supportsFiles: true`。 +- 如果你想要渠道流量,`authorization.permissions.resourceSpecific` 必须包含渠道读取/发送权限。 ### 更新现有应用 -如需更新已安装的 Teams 应用(例如添加 RSC 权限): +要更新已安装的 Teams 应用(例如添加 RSC 权限): ```bash -# 下载、编辑并重新上传清单 +# Download, edit, and re-upload the manifest teams app manifest download manifest.json -# 在本地编辑 manifest.json... +# Edit manifest.json locally... teams app manifest upload manifest.json -# 如果内容发生变化,版本号会自动递增 +# Version is auto-bumped if content changed ``` -更新后,请在每个团队中重新安装该应用以使新权限生效,并且**完全退出并重新启动 Teams**(而不只是关闭窗口),以清除缓存的应用元数据。 +更新后,在每个团队中重新安装该应用,以便新权限生效,并且**完全退出并重新启动 Teams**(不只是关闭窗口)以清除缓存的应用元数据。
手动更新清单(不使用 CLI) 1. 使用新设置更新你的 `manifest.json` -2. **递增 `version` 字段**(例如 `1.0.0` → `1.1.0`) -3. **重新打包为 zip**,包含清单和图标(`manifest.json`、`outline.png`、`color.png`) +2. **递增 `version` 字段**(例如,`1.0.0` → `1.1.0`) +3. 使用图标(`manifest.json`、`outline.png`、`color.png`)**重新打包为 zip** 4. 上传新的 zip: - - **Teams Admin Center:** Teams apps → Manage apps → 找到你的应用 → Upload new version - - **旁加载:** 在 Teams 中 → Apps → Manage your apps → Upload a custom app + - **Teams 管理中心:** Teams 应用 → 管理应用 → 找到你的应用 → 上传新版本 + - **侧载:** 在 Teams 中 → 应用 → 管理你的应用 → 上传自定义应用
-## 功能:仅 RSC 与 Graph 的区别 +## 能力:仅 RSC 与 Graph 对比 -### 使用**仅 Teams RSC**(已安装应用,无 Graph API 权限)时 +### 使用**仅 Teams RSC**(已安装应用,无 Graph API 权限) 可用: @@ -620,11 +625,11 @@ teams app manifest upload manifest.json 不可用: -- 渠道/群组中的**图片或文件内容**(负载仅包含 HTML 占位内容)。 +- 渠道/群组**图片或文件内容**(有效载荷只包含 HTML 占位片段)。 - 下载存储在 SharePoint/OneDrive 中的附件。 -- 读取消息历史记录(超出实时 webhook 事件之外的内容)。 +- 读取消息历史(实时 webhook 事件之外)。 -### 使用**Teams RSC + Microsoft Graph Application permissions** 时 +### 使用 **Teams RSC + Microsoft Graph 应用程序权限** 新增: @@ -634,106 +639,106 @@ teams app manifest upload manifest.json ### RSC 与 Graph API -| Capability | RSC Permissions | Graph API | -| ----------------------- | -------------------- | ----------------------------------- | -| **Real-time messages** | 是(通过 webhook) | 否(仅支持轮询) | -| **Historical messages** | 否 | 是(可查询历史) | -| **Setup complexity** | 仅需应用清单 | 需要管理员同意 + 令牌流程 | -| **Works offline** | 否(必须保持运行) | 是(可随时查询) | +| 能力 | RSC 权限 | Graph API | +| ---------------------- | -------------------- | ----------------------------------- | +| **实时消息** | 是(通过 webhook) | 否(仅轮询) | +| **历史消息** | 否 | 是(可以查询历史) | +| **设置复杂度** | 仅应用清单 | 需要管理员同意 + 令牌流程 | +| **离线工作** | 否(必须正在运行) | 是(可随时查询) | -**结论:** 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)**应用注册**中,添加 Microsoft Graph **应用程序权限**: - `ChannelMessage.Read.All`(渠道附件 + 历史) - `Chat.Read.All` 或 `ChatMessage.Read.All`(群组聊天) 2. 为租户**授予管理员同意**。 -3. 递增 Teams 应用**清单版本号**,重新上传,并在 Teams 中**重新安装应用**。 +3. 递增 Teams 应用的**清单版本**,重新上传,并在 Teams 中**重新安装应用**。 4. **完全退出并重新启动 Teams**,以清除缓存的应用元数据。 -**用户提及的附加权限:** 对于当前对话中的用户,用户 @mention 开箱即用。但是,如果你想动态搜索并提及**当前对话之外**的用户,请添加 `User.Read.All`(Application)权限并授予管理员同意。 +**用户提及的额外权限:** 对话中的用户 @mentions 可开箱即用。不过,如果你想动态搜索并提及**不在当前对话中**的用户,请添加 `User.Read.All`(应用程序)权限并授予管理员同意。 ## 已知限制 ### Webhook 超时 -Teams 通过 HTTP webhook 投递消息。如果处理耗时过长(例如 LLM 响应较慢),你可能会看到: +Teams 通过 HTTP webhook 传递消息。如果处理耗时过长(例如 LLM 响应较慢),你可能会看到: -- Gateway 网关 超时 -- Teams 重试该消息(导致重复) +- Gateway 网关超时 +- Teams 重试消息(导致重复) - 回复丢失 -OpenClaw 通过快速返回并主动发送回复来处理这一点,但在响应非常慢时仍然可能出现问题。 +OpenClaw 通过快速返回并主动发送回复来处理这种情况,但非常慢的响应仍可能造成问题。 -### 格式化 +### 格式设置 -Teams 的 markdown 能力比 Slack 或 Discord 更有限: +Teams markdown 比 Slack 或 Discord 更受限制: -- 基础格式可用:**粗体**、_斜体_、`code`、链接 +- 基本格式可用:**粗体**、_斜体_、`code`、链接 - 复杂 markdown(表格、嵌套列表)可能无法正确渲染 -- 支持使用 Adaptive Cards 进行投票和语义化展示发送(见下文) +- Adaptive Cards 支持投票和语义化演示发送(见下文) ## 配置 -关键设置(共享渠道模式参见 `/gateway/configuration`): +关键设置(共享渠道模式见 `/gateway/configuration`): - `channels.msteams.enabled`:启用/禁用该渠道。 -- `channels.msteams.appId`、`channels.msteams.appPassword`、`channels.msteams.tenantId`:机器人凭证。 -- `channels.msteams.webhook.port`(默认值 `3978`) -- `channels.msteams.webhook.path`(默认值 `/api/messages`) +- `channels.msteams.appId`、`channels.msteams.appPassword`、`channels.msteams.tenantId`:bot 凭证。 +- `channels.msteams.webhook.port`(默认 `3978`) +- `channels.msteams.webhook.path`(默认 `/api/messages`) - `channels.msteams.dmPolicy`:`pairing | allowlist | open | disabled`(默认:pairing) -- `channels.msteams.allowFrom`:私信 allowlist(建议使用 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`:传入附件主机的 allowlist(默认是 Microsoft/Teams 域名)。 -- `channels.msteams.mediaAuthAllowHosts`:媒体重试时允许附加 Authorization 头的主机 allowlist(默认是 Graph + Bot Framework 主机)。 -- `channels.msteams.requireMention`:在渠道/群组中要求 @mention(默认值为 true)。 -- `channels.msteams.replyStyle`:`thread | top-level`(参见 [回复样式](#reply-style-threads-vs-posts))。 +- `channels.msteams.chunkMode`:`length`(默认)或 `newline`,用于在按长度分块前按空行(段落边界)拆分。 +- `channels.msteams.mediaAllowHosts`:入站附件主机允许列表(默认为 Microsoft/Teams 域)。 +- `channels.msteams.mediaAuthAllowHosts`:媒体重试时可附加 Authorization 标头的主机允许列表(默认为 Graph + Bot Framework 主机)。 +- `channels.msteams.requireMention`:要求在渠道/群组中 @提及(默认 true)。 +- `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`:按渠道、按发送者的工具策略覆盖(支持 `"*"` 通配符)。 - `toolsBySender` 键应使用显式前缀: - `id:`、`e164:`、`username:`、`name:`(旧版无前缀键仍只映射到 `id:`)。 -- `channels.msteams.actions.memberInfo`:启用或禁用基于 Graph 的成员信息操作(默认:当 Graph 凭证可用时启用)。 -- `channels.msteams.authType`:身份验证类型 —— `"secret"`(默认)或 `"federated"`。 -- `channels.msteams.certificatePath`:PEM 证书文件路径(联合身份验证 + 证书身份验证)。 -- `channels.msteams.certificateThumbprint`:证书指纹(可选,身份验证不要求)。 -- `channels.msteams.useManagedIdentity`:启用托管身份验证(联合模式)。 + `id:`、`e164:`、`username:`、`name:`(旧版无前缀键仍仅映射到 `id:`)。 +- `channels.msteams.actions.memberInfo`:启用或禁用 Graph 支持的成员信息操作(默认:当 Graph 凭证可用时启用)。 +- `channels.msteams.authType`:认证类型 — `"secret"`(默认)或 `"federated"`。 +- `channels.msteams.certificatePath`:PEM 证书文件路径(联合 + 证书认证)。 +- `channels.msteams.certificateThumbprint`:证书指纹(可选,认证不需要)。 +- `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: + - 渠道/群组消息使用对话 ID: - `agent::msteams:channel:` - `agent::msteams:group:` ## 回复样式:线程与帖子 -Teams 最近在相同的底层数据模型之上引入了两种渠道 UI 样式: +Teams 最近在同一底层数据模型上引入了两种渠道 UI 样式: -| Style | Description | Recommended `replyStyle` | +| 样式 | 说明 | 推荐的 `replyStyle` | | ------------------------ | --------------------------------------------------------- | ------------------------ | -| **Posts** (classic) | 消息显示为卡片,下方附带线程回复 | `thread`(默认) | -| **Threads** (Slack-like) | 消息线性流动,更像 Slack | `top-level` | +| **帖子**(经典) | 消息显示为卡片,下方带有线程式回复 | `thread`(默认) | +| **线程**(类似 Slack) | 消息线性流动,更像 Slack | `top-level` | -**问题在于:** Teams API 不会暴露渠道使用的是哪种 UI 样式。如果你使用了错误的 `replyStyle`: +**问题:** Teams API 不会暴露渠道使用的是哪种 UI 样式。如果使用了错误的 `replyStyle`: -- 在 Threads 风格的渠道中使用 `thread` → 回复会以不自然的嵌套方式显示 -- 在 Posts 风格的渠道中使用 `top-level` → 回复会显示为单独的顶级帖子,而不是在线程中 +- 在线程样式渠道中使用 `thread` → 回复会以不自然的嵌套形式显示 +- 在帖子样式渠道中使用 `top-level` → 回复会显示为单独的顶层帖子,而不是在线程中 -**解决方案:** 根据渠道的实际设置,按渠道配置 `replyStyle`: +**解决方案:** 根据渠道的设置方式按渠道配置 `replyStyle`: ```json5 { @@ -754,52 +759,52 @@ Teams 最近在相同的底层数据模型之上引入了两种渠道 UI 样式 } ``` -## 附件与图片 +## 附件和图片 **当前限制:** -- **私信:** 图片和文件附件可通过 Teams 机器人文件 API 工作。 -- **渠道/群组:** 附件存储在 M365 存储中(SharePoint/OneDrive)。webhook 负载只包含 HTML 占位内容,不包含实际文件字节。**下载渠道附件需要 Graph API 权限**。 -- 对于显式的文件优先发送,请使用 `action=upload-file`,并配合 `media` / `filePath` / `path`;可选的 `message` 会作为附带文本/评论,`filename` 会覆盖上传文件名。 +- **私信:** 图片和文件附件通过 Teams bot 文件 API 工作。 +- **渠道/群组:** 附件存储在 M365 存储(SharePoint/OneDrive)中。webhook 载荷只包含 HTML 占位内容,而不包含实际文件字节。**需要 Graph API 权限**才能下载渠道附件。 +- 对于显式的文件优先发送,请使用 `action=upload-file` 并提供 `media` / `filePath` / `path`;可选的 `message` 会作为随附文本/评论,`filename` 会覆盖上传名称。 -如果没有 Graph 权限,带图片的渠道消息将仅以文本形式接收(机器人无法访问图片内容)。 -默认情况下,OpenClaw 仅从 Microsoft/Teams 主机名下载媒体。可通过 `channels.msteams.mediaAllowHosts` 覆盖(使用 `["*"]` 可允许任意主机)。 -Authorization 头仅会附加到 `channels.msteams.mediaAuthAllowHosts` 中的主机(默认是 Graph + Bot Framework 主机)。请保持此列表严格受限(避免使用多租户后缀)。 +如果没有 Graph 权限,带图片的渠道消息会以纯文本形式接收(bot 无法访问图片内容)。 +默认情况下,OpenClaw 只从 Microsoft/Teams 主机名下载媒体。可用 `channels.msteams.mediaAllowHosts` 覆盖(使用 `["*"]` 允许任何主机)。 +Authorization 标头只会附加到 `channels.msteams.mediaAuthAllowHosts` 中的主机(默认为 Graph + Bot Framework 主机)。请保持此列表严格(避免多租户后缀)。 -## 在群组聊天中发送文件 +## 在群聊中发送文件 -机器人可以在私信中使用 FileConsentCard 流程发送文件(内置支持)。但是,**在群组聊天/渠道中发送文件**需要额外设置: +Bot 可以使用 FileConsentCard 流程在私信中发送文件(内置)。但是,**在群聊/渠道中发送文件**需要额外设置: -| Context | How files are sent | Setup needed | +| 上下文 | 文件发送方式 | 需要的设置 | | ------------------------ | -------------------------------------------- | ----------------------------------------------- | -| **DMs** | FileConsentCard → 用户接受 → 机器人上传 | 开箱即用 | -| **Group chats/channels** | 上传到 SharePoint → 分享链接 | 需要 `sharePointSiteId` + Graph 权限 | -| **Images (any context)** | Base64 编码内联 | 开箱即用 | +| **私信** | FileConsentCard → 用户接受 → bot 上传 | 开箱即用 | +| **群聊/渠道** | 上传到 SharePoint → 分享链接 | 需要 `sharePointSiteId` + Graph 权限 | +| **图片(任何上下文)** | Base64 编码内联 | 开箱即用 | -### 为什么群组聊天需要 SharePoint +### 为什么群聊需要 SharePoint -机器人没有个人 OneDrive 驱动器(`/me/drive` Graph API 端点不适用于应用程序身份)。要在群组聊天/渠道中发送文件,机器人需要上传到 **SharePoint 站点** 并创建共享链接。 +Bot 没有个人 OneDrive 驱动器(`/me/drive` Graph API 端点不适用于应用程序身份)。要在群聊/渠道中发送文件,bot 会上传到一个 **SharePoint 站点**并创建分享链接。 ### 设置 -1. 在 Entra ID(Azure AD)→ 应用注册中**添加 Graph API 权限**: - - `Sites.ReadWrite.All`(Application)- 上传文件到 SharePoint - - `Chat.Read.All`(Application)- 可选,启用按用户共享链接 +1. 在 Entra ID(Azure AD)→ App Registration 中**添加 Graph API 权限**: + - `Sites.ReadWrite.All`(Application)- 将文件上传到 SharePoint + - `Chat.Read.All`(Application)- 可选,启用按用户分享链接 2. 为租户**授予管理员同意**。 3. **获取你的 SharePoint 站点 ID:** ```bash - # 通过 Graph Explorer,或使用有效令牌配合 curl: + # Via Graph Explorer or curl with a valid token: curl -H "Authorization: Bearer $TOKEN" \ "https://graph.microsoft.com/v1.0/sites/{hostname}:/{site-path}" - # 示例:对于位于 "contoso.sharepoint.com/sites/BotFiles" 的站点 + # Example: for a site at "contoso.sharepoint.com/sites/BotFiles" curl -H "Authorization: Bearer $TOKEN" \ "https://graph.microsoft.com/v1.0/sites/contoso.sharepoint.com:/sites/BotFiles" - # 响应中包含:"id": "contoso.sharepoint.com,guid1,guid2" + # Response includes: "id": "contoso.sharepoint.com,guid1,guid2" ``` 4. **配置 OpenClaw:** @@ -815,42 +820,42 @@ Authorization 头仅会附加到 `channels.msteams.mediaAuthAllowHosts` 中的 } ``` -### 共享行为 +### 分享行为 -| Permission | Sharing behavior | +| 权限 | 分享行为 | | --------------------------------------- | --------------------------------------------------------- | -| `Sites.ReadWrite.All` only | 组织范围共享链接(组织内任何人都可访问) | -| `Sites.ReadWrite.All` + `Chat.Read.All` | 按用户共享链接(仅聊天成员可访问) | +| 仅 `Sites.ReadWrite.All` | 组织范围分享链接(组织中的任何人都可访问) | +| `Sites.ReadWrite.All` + `Chat.Read.All` | 按用户分享链接(只有聊天成员可访问) | -按用户共享更安全,因为只有聊天参与者可以访问文件。如果缺少 `Chat.Read.All` 权限,机器人会回退到组织范围共享。 +按用户分享更安全,因为只有聊天参与者可以访问该文件。如果缺少 `Chat.Read.All` 权限,bot 会回退到组织范围分享。 ### 回退行为 -| Scenario | Result | +| 场景 | 结果 | | ------------------------------------------------- | -------------------------------------------------- | -| 群组聊天 + 文件 + 已配置 `sharePointSiteId` | 上传到 SharePoint,发送共享链接 | -| 群组聊天 + 文件 + 未配置 `sharePointSiteId` | 尝试上传到 OneDrive(可能失败),仅发送文本 | -| 个人聊天 + 文件 | FileConsentCard 流程(无需 SharePoint 即可工作) | -| 任意上下文 + 图片 | Base64 编码内联(无需 SharePoint 即可工作) | +| 群聊 + 文件 + 已配置 `sharePointSiteId` | 上传到 SharePoint,发送分享链接 | +| 群聊 + 文件 + 没有 `sharePointSiteId` | 尝试 OneDrive 上传(可能失败),仅发送文本 | +| 个人聊天 + 文件 | FileConsentCard 流程(无需 SharePoint 即可工作) | +| 任何上下文 + 图片 | Base64 编码内联(无需 SharePoint 即可工作) | ### 文件存储位置 -上传的文件存储在已配置 SharePoint 站点默认文档库中的 `/OpenClawShared/` 文件夹内。 +上传的文件存储在已配置 SharePoint 站点默认文档库中的 `/OpenClawShared/` 文件夹。 ## 投票(Adaptive Cards) -OpenClaw 通过 Adaptive Cards 发送 Teams 投票(Teams 没有原生投票 API)。 +OpenClaw 以 Adaptive Cards 形式发送 Teams 投票(没有原生 Teams 投票 API)。 - CLI:`openclaw message poll --channel msteams --target conversation: ...` -- 投票由 Gateway 网关 记录到 `~/.openclaw/msteams-polls.json` 中。 -- Gateway 网关 必须保持在线才能记录投票。 -- 投票目前不会自动发布结果摘要(如有需要,请检查存储文件)。 +- 投票由 Gateway 网关记录在 `~/.openclaw/msteams-polls.json` 中。 +- Gateway 网关必须保持在线才能记录投票。 +- 投票尚不会自动发布结果摘要(如有需要,请检查存储文件)。 -## 展示卡片 +## 演示卡片 -使用 `message` 工具或 CLI 将语义化展示负载发送给 Teams 用户或会话。OpenClaw 会根据通用展示契约将其渲染为 Teams Adaptive Cards。 +使用 `message` 工具或 CLI 向 Teams 用户或对话发送语义化演示载荷。OpenClaw 会根据通用演示契约将其渲染为 Teams Adaptive Cards。 -`presentation` 参数接受语义块。提供 `presentation` 时,消息文本为可选项。 +`presentation` 参数接受语义块。当提供 `presentation` 时,消息文本是可选的。 **智能体工具:** @@ -874,32 +879,32 @@ openclaw message send --channel msteams \ --presentation '{"title":"Hello","blocks":[{"type":"text","text":"Hello!"}]}' ``` -有关目标格式的详细信息,请参见下方[目标格式](#target-formats)。 +目标格式详情见下方[目标格式](#target-formats)。 ## 目标格式 -MSTeams 目标使用前缀来区分用户和会话: +MSTeams 目标使用前缀来区分用户和对话: -| Target type | Format | Example | +| 目标类型 | 格式 | 示例 | | ------------------- | -------------------------------- | --------------------------------------------------- | -| 用户(按 ID) | `user:` | `user:40a1a0ed-4ff2-4164-a219-55518990c197` | -| 用户(按名称) | `user:` | `user:John Smith`(需要 Graph API) | -| 群组/渠道 | `conversation:` | `conversation:19:abc123...@thread.tacv2` | +| 用户(按 ID) | `user:` | `user:40a1a0ed-4ff2-4164-a219-55518990c197` | +| 用户(按名称) | `user:` | `user:John Smith`(需要 Graph API) | +| 群组/渠道 | `conversation:` | `conversation:19:abc123...@thread.tacv2` | | 群组/渠道(原始) | `` | `19:abc123...@thread.tacv2`(如果包含 `@thread`) | **CLI 示例:** ```bash -# 按 ID 发送给用户 +# Send to a user by ID openclaw message send --channel msteams --target "user:40a1a0ed-..." --message "Hello" -# 按显示名称发送给用户(会触发 Graph API 查询) +# Send to a user by display name (triggers Graph API lookup) openclaw message send --channel msteams --target "user:John Smith" --message "Hello" -# 发送到群组聊天或渠道 +# Send to a group chat or channel openclaw message send --channel msteams --target "conversation:19:abc...@thread.tacv2" --message "Hello" -# 向会话发送展示卡片 +# Send a presentation card to a conversation openclaw message send --channel msteams --target "conversation:19:abc...@thread.tacv2" \ --presentation '{"title":"Hello","blocks":[{"type":"text","text":"Hello"}]}' ``` @@ -928,13 +933,13 @@ openclaw message send --channel msteams --target "conversation:19:abc...@thread. ``` -如果没有 `user:` 前缀,名称默认会按群组或团队解析。按显示名称指定个人时,请始终使用 `user:`。 +如果没有 `user:` 前缀,名称默认会按群组或团队进行解析。通过显示名称指定人员时,始终使用 `user:`。 ## 主动消息 -- 只有在用户已经发生过交互之后,才能发送**主动消息**,因为我们会在那时存储会话引用。 -- 有关 `dmPolicy` 和 allowlist 限制,请参见 `/gateway/configuration`。 +- 只有在用户交互**之后**,主动消息才可用,因为我们会在那时存储对话引用。 +- 有关 `dmPolicy` 和 allowlist 门控,请参阅 `/gateway/configuration`。 ## 团队和渠道 ID(常见陷阱) @@ -945,7 +950,7 @@ Teams URL 中的 `groupId` 查询参数**不是**用于配置的团队 ID。请 ``` https://teams.microsoft.com/l/team/19%3ABk4j...%40thread.tacv2/conversations?groupId=... └────────────────────────────┘ - 团队 ID(对其进行 URL 解码) + Team ID (URL-decode this) ``` **渠道 URL:** @@ -953,71 +958,71 @@ 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 解码) + Channel ID (URL-decode this) ``` -**用于配置:** +**对于配置:** -- 团队 ID = `/team/` 之后的路径片段(URL 解码后,例如 `19:Bk4j...@thread.tacv2`) -- 渠道 ID = `/channel/` 之后的路径片段(URL 解码后) +- 团队 ID = `/team/` 之后的路径段(URL 解码后,例如 `19:Bk4j...@thread.tacv2`) +- 渠道 ID = `/channel/` 之后的路径段(URL 解码后) - **忽略** `groupId` 查询参数 ## 私有渠道 机器人在私有渠道中的支持有限: -| Feature | Standard Channels | Private Channels | -| ---------------------------- | ----------------- | ---------------------- | -| 机器人安装 | 是 | 有限 | -| 实时消息(webhook) | 是 | 可能无法工作 | -| RSC 权限 | 是 | 行为可能不同 | -| @mentions | 是 | 如果机器人可访问 | -| Graph API 历史记录 | 是 | 是(需要权限) | +| 功能 | 标准渠道 | 私有渠道 | +| -------------------------- | -------- | -------------------- | +| 机器人安装 | 是 | 有限 | +| 实时消息(webhook) | 是 | 可能无法工作 | +| RSC 权限 | 是 | 可能表现不同 | +| @提及 | 是 | 如果机器人可访问 | +| Graph API 历史记录 | 是 | 是(具备权限时) | -**如果私有渠道无法工作,可使用以下变通方案:** +**如果私有渠道无法工作,可使用这些变通方法:** 1. 使用标准渠道进行机器人交互 -2. 使用私信 —— 用户始终可以直接向机器人发送消息 -3. 使用 Graph API 获取历史访问(需要 `ChannelMessage.Read.All`) +2. 使用私信 - 用户始终可以直接给机器人发消息 +3. 使用 Graph API 进行历史访问(需要 `ChannelMessage.Read.All`) ## 故障排除 ### 常见问题 -- **渠道中不显示图片:** 缺少 Graph 权限或管理员同意。请重新安装 Teams 应用,并完全退出/重新打开 Teams。 -- **渠道中没有响应:** 默认要求提及;请设置 `channels.msteams.requireMention=false` 或按团队/渠道配置。 -- **版本不匹配(Teams 仍显示旧清单):** 删除并重新添加应用,然后完全退出 Teams 以刷新。 -- **webhook 返回 401 Unauthorized:** 在没有 Azure JWT 的情况下手动测试时,这是预期行为 —— 表示端点可访问,但身份验证失败。请使用 Azure Web Chat 正确测试。 +- **图片未在渠道中显示:**缺少 Graph 权限或管理员同意。重新安装 Teams 应用,并完全退出后重新打开 Teams。 +- **渠道中没有响应:**默认需要提及;设置 `channels.msteams.requireMention=false`,或按团队/渠道配置。 +- **版本不匹配(Teams 仍显示旧清单):**移除并重新添加应用,然后完全退出 Teams 以刷新。 +- **webhook 返回 401 Unauthorized:**手动测试且没有 Azure JWT 时这是预期结果,表示端点可访问但认证失败。使用 Azure Web Chat 正确测试。 ### 清单上传错误 -- **“Icon file cannot be empty”:** 清单引用的图标文件大小为 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”:**清单引用了 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` 是否与你机器人的 App ID 完全一致 +1. 验证 `webApplicationInfo.id` 是否与你的机器人 App ID 完全匹配 2. 重新上传应用,并在团队/聊天中重新安装 -3. 检查你的组织管理员是否屏蔽了 RSC 权限 -4. 确认你使用了正确的作用域:团队使用 `ChannelMessage.Read.Group`,群组聊天使用 `ChatMessage.Read.Chat` +3. 检查你的组织管理员是否阻止了 RSC 权限 +4. 确认你使用了正确的范围:团队使用 `ChannelMessage.Read.Group`,群组聊天使用 `ChatMessage.Read.Chat` ## 参考 -- [Create Azure Bot](https://learn.microsoft.com/en-us/azure/bot-service/bot-service-quickstart-registration) - Azure Bot 设置指南 +- [创建 Azure Bot](https://learn.microsoft.com/en-us/azure/bot-service/bot-service-quickstart-registration) - Azure Bot 设置指南 - [Teams Developer Portal](https://dev.teams.microsoft.com/apps) - 创建/管理 Teams 应用 -- [Teams app manifest schema](https://learn.microsoft.com/en-us/microsoftteams/platform/resources/schema/manifest-schema) -- [Receive channel messages with RSC](https://learn.microsoft.com/en-us/microsoftteams/platform/bots/how-to/conversations/channel-messages-with-rsc) -- [RSC permissions reference](https://learn.microsoft.com/en-us/microsoftteams/platform/graph-api/rsc/resource-specific-consent) -- [Teams bot file handling](https://learn.microsoft.com/en-us/microsoftteams/platform/bots/how-to/bots-filesv4)(渠道/群组需要 Graph) -- [Proactive messaging](https://learn.microsoft.com/en-us/microsoftteams/platform/bots/how-to/conversations/send-proactive-messages) +- [Teams 应用清单架构](https://learn.microsoft.com/en-us/microsoftteams/platform/resources/schema/manifest-schema) +- [使用 RSC 接收渠道消息](https://learn.microsoft.com/en-us/microsoftteams/platform/bots/how-to/conversations/channel-messages-with-rsc) +- [RSC 权限参考](https://learn.microsoft.com/en-us/microsoftteams/platform/graph-api/rsc/resource-specific-consent) +- [Teams 机器人文件处理](https://learn.microsoft.com/en-us/microsoftteams/platform/bots/how-to/bots-filesv4)(渠道/群组需要 Graph) +- [主动消息](https://learn.microsoft.com/en-us/microsoftteams/platform/bots/how-to/conversations/send-proactive-messages) - [@microsoft/teams.cli](https://www.npmjs.com/package/@microsoft/teams.cli) - 用于机器人管理的 Teams CLI -## 相关内容 +## 相关 -- [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) — 访问模型与加固 +- [渠道概览](/zh-CN/channels) — 所有支持的渠道 +- [配对](/zh-CN/channels/pairing) — 私信认证和配对流程 +- [群组](/zh-CN/channels/groups) — 群组聊天行为和提及门控 +- [渠道路由](/zh-CN/channels/channel-routing) — 消息的会话路由 +- [安全](/zh-CN/gateway/security) — 访问模型和加固 diff --git a/docs/zh-CN/channels/nextcloud-talk.md b/docs/zh-CN/channels/nextcloud-talk.md index cc8ec4e58..be440eaab 100644 --- a/docs/zh-CN/channels/nextcloud-talk.md +++ b/docs/zh-CN/channels/nextcloud-talk.md @@ -1,32 +1,37 @@ --- read_when: - - 正在开发 Nextcloud Talk 渠道功能 -summary: Nextcloud Talk 支持状态、功能和配置 + - 开发 Nextcloud Talk 渠道功能 +summary: Nextcloud Talk 支持状态、能力和配置 title: Nextcloud Talk x-i18n: - generated_at: "2026-04-24T06:24:02Z" - model: gpt-5.4 + generated_at: "2026-04-29T05:37:57Z" + model: gpt-5.5 provider: openai - source_hash: 9a3af391ffa445ef1ebc7877a1158c3c6aa7ecc71ceadcb0e783a80b040fe062 + source_hash: fcbe8a65adfddc95d2b4944af88f9982e23a1676752efec2bbf40cfc4dd846d2 source_path: channels/nextcloud-talk.md - workflow: 15 + workflow: 16 --- -状态:内置插件(webhook 机器人)。支持私信、房间、表情回应和 Markdown 消息。 +Status:内置插件(webhook bot)。支持私信、房间、回应和 Markdown 消息。 ## 内置插件 -Nextcloud Talk 在当前的 OpenClaw 版本中作为内置插件提供,因此普通的打包构建不需要单独安装。 +Nextcloud Talk 在当前 OpenClaw 版本中作为内置插件提供,因此 +普通打包构建不需要单独安装。 -如果你使用的是较旧的构建版本,或排除了 Nextcloud Talk 的自定义安装,请手动安装: +如果你使用的是旧版构建,或是不包含 Nextcloud Talk 的自定义安装, +请在发布当前 npm 包后安装它: -通过 CLI 安装(npm 注册表): +通过 CLI 安装(npm registry,存在当前包时): ```bash openclaw plugins install @openclaw/nextcloud-talk ``` -本地检出安装(从 git 仓库运行时): +如果 npm 报告 OpenClaw 所有的包已弃用,请使用当前打包的 +OpenClaw 构建,或在发布更新的 npm 包前使用本地 checkout 路径。 + +本地 checkout(从 git repo 运行时): ```bash openclaw plugins install ./path/to/local/nextcloud-talk-plugin @@ -37,15 +42,15 @@ openclaw plugins install ./path/to/local/nextcloud-talk-plugin ## 快速设置(初学者) 1. 确保 Nextcloud Talk 插件可用。 - - 当前打包发布的 OpenClaw 版本已默认内置它。 - - 较旧/自定义安装可使用上面的命令手动添加。 -2. 在你的 Nextcloud 服务器上,创建一个机器人: + - 当前打包的 OpenClaw 版本已经内置它。 + - 旧版/自定义安装可以用上面的命令手动添加它。 +2. 在你的 Nextcloud 服务器上创建 bot: ```bash ./occ talk:bot:install "OpenClaw" "" "" --feature reaction ``` -3. 在目标房间设置中启用该机器人。 +3. 在目标房间设置中启用 bot。 4. 配置 OpenClaw: - 配置:`channels.nextcloud-talk.baseUrl` + `channels.nextcloud-talk.botSecret` - 或环境变量:`NEXTCLOUD_TALK_BOT_SECRET`(仅默认账户) @@ -58,7 +63,7 @@ openclaw plugins install ./path/to/local/nextcloud-talk-plugin --token "" ``` - 等效的显式字段: + 等价的显式字段: ```bash openclaw channels add --channel nextcloud-talk \ @@ -66,7 +71,7 @@ openclaw plugins install ./path/to/local/nextcloud-talk-plugin --secret "" ``` - 基于文件的 secret: + 文件后端密钥: ```bash openclaw channels add --channel nextcloud-talk \ @@ -91,26 +96,26 @@ openclaw plugins install ./path/to/local/nextcloud-talk-plugin } ``` -## 注意事项 +## 备注 -- 机器人无法主动发起私信。用户必须先给机器人发送消息。 -- webhook URL 必须可被 Gateway 网关访问;如果位于代理之后,请设置 `webhookPublicUrl`。 -- 机器人 API 不支持媒体上传;媒体会以 URL 形式发送。 -- webhook 负载不会区分私信和房间;设置 `apiUser` + `apiPassword` 可启用房间类型查询(否则私信会被视为房间)。 +- Bot 不能主动发起私信。用户必须先给 bot 发送消息。 +- Gateway 网关 必须能够访问 webhook URL;如果位于代理后面,请设置 `webhookPublicUrl`。 +- bot API 不支持媒体上传;媒体会作为 URL 发送。 +- webhook payload 不区分私信和房间;设置 `apiUser` + `apiPassword` 可启用房间类型查询(否则私信会被视为房间)。 ## 访问控制(私信) -- 默认:`channels.nextcloud-talk.dmPolicy = "pairing"`。未知发送者会收到一个配对码。 +- 默认:`channels.nextcloud-talk.dmPolicy = "pairing"`。未知发送者会收到配对码。 - 通过以下方式批准: - `openclaw pairing list nextcloud-talk` - `openclaw pairing approve nextcloud-talk ` -- 公开私信:`channels.nextcloud-talk.dmPolicy="open"` 加上 `channels.nextcloud-talk.allowFrom=["*"]`。 +- 公开私信:`channels.nextcloud-talk.dmPolicy="open"` 加 `channels.nextcloud-talk.allowFrom=["*"]`。 - `allowFrom` 仅匹配 Nextcloud 用户 ID;显示名称会被忽略。 ## 房间(群组) -- 默认:`channels.nextcloud-talk.groupPolicy = "allowlist"`(提及门控)。 -- 使用 `channels.nextcloud-talk.rooms` 将房间加入允许列表: +- 默认:`channels.nextcloud-talk.groupPolicy = "allowlist"`(需要提及)。 +- 用 `channels.nextcloud-talk.rooms` 将房间加入允许列表: ```json5 { @@ -124,17 +129,17 @@ openclaw plugins install ./path/to/local/nextcloud-talk-plugin } ``` -- 若不允许任何房间,可保持允许列表为空,或设置 `channels.nextcloud-talk.groupPolicy="disabled"`。 +- 要不允许任何房间,请保持允许列表为空,或设置 `channels.nextcloud-talk.groupPolicy="disabled"`。 -## 功能 +## 能力 -| 功能 | 状态 | +| 功能 | Status | | --------------- | ------------- | | 私信 | 支持 | | 房间 | 支持 | | 线程 | 不支持 | | 媒体 | 仅 URL | -| 表情回应 | 支持 | +| 回应 | 支持 | | 原生命令 | 不支持 | ## 配置参考(Nextcloud Talk) @@ -145,33 +150,33 @@ openclaw plugins install ./path/to/local/nextcloud-talk-plugin - `channels.nextcloud-talk.enabled`:启用/禁用渠道启动。 - `channels.nextcloud-talk.baseUrl`:Nextcloud 实例 URL。 -- `channels.nextcloud-talk.botSecret`:机器人共享 secret。 -- `channels.nextcloud-talk.botSecretFile`:常规文件 secret 路径。不接受符号链接。 -- `channels.nextcloud-talk.apiUser`:用于房间查询的 API 用户(私信检测)。 -- `channels.nextcloud-talk.apiPassword`:用于房间查询的 API 密码/应用密码。 +- `channels.nextcloud-talk.botSecret`:bot 共享密钥。 +- `channels.nextcloud-talk.botSecretFile`:常规文件密钥路径。符号链接会被拒绝。 +- `channels.nextcloud-talk.apiUser`:用于房间查询(私信检测)的 API 用户。 +- `channels.nextcloud-talk.apiPassword`:用于房间查询的 API/app 密码。 - `channels.nextcloud-talk.apiPasswordFile`:API 密码文件路径。 - `channels.nextcloud-talk.webhookPort`:webhook 监听端口(默认:8788)。 -- `channels.nextcloud-talk.webhookHost`:webhook 主机(默认:0.0.0.0)。 -- `channels.nextcloud-talk.webhookPath`:webhook 路径(默认:/nextcloud-talk-webhook)。 +- `channels.nextcloud-talk.webhookHost`:webhook host(默认:0.0.0.0)。 +- `channels.nextcloud-talk.webhookPath`:webhook path(默认:/nextcloud-talk-webhook)。 - `channels.nextcloud-talk.webhookPublicUrl`:外部可访问的 webhook URL。 - `channels.nextcloud-talk.dmPolicy`:`pairing | allowlist | open | disabled`。 - `channels.nextcloud-talk.allowFrom`:私信允许列表(用户 ID)。`open` 需要 `"*"`。 - `channels.nextcloud-talk.groupPolicy`:`allowlist | open | disabled`。 - `channels.nextcloud-talk.groupAllowFrom`:群组允许列表(用户 ID)。 -- `channels.nextcloud-talk.rooms`:按房间配置的设置和允许列表。 +- `channels.nextcloud-talk.rooms`:按房间的设置和允许列表。 - `channels.nextcloud-talk.historyLimit`:群组历史记录限制(0 表示禁用)。 - `channels.nextcloud-talk.dmHistoryLimit`:私信历史记录限制(0 表示禁用)。 -- `channels.nextcloud-talk.dms`:按私信配置的覆盖项(`historyLimit`)。 -- `channels.nextcloud-talk.textChunkLimit`:出站文本分块大小(字符数)。 -- `channels.nextcloud-talk.chunkMode`:`length`(默认)或 `newline`,用于在按长度分块前先按空行(段落边界)拆分。 +- `channels.nextcloud-talk.dms`:按私信的覆盖项(historyLimit)。 +- `channels.nextcloud-talk.textChunkLimit`:出站文本分块大小(字符)。 +- `channels.nextcloud-talk.chunkMode`:`length`(默认)或 `newline`,用于在按长度分块前按空行(段落边界)拆分。 - `channels.nextcloud-talk.blockStreaming`:为此渠道禁用分块流式传输。 - `channels.nextcloud-talk.blockStreamingCoalesce`:分块流式传输合并调优。 - `channels.nextcloud-talk.mediaMaxMb`:入站媒体上限(MB)。 -## 相关内容 +## 相关 -- [渠道概览](/zh-CN/channels) — 所有受支持的渠道 -- [配对](/zh-CN/channels/pairing) — 私信认证和配对流程 +- [渠道概览](/zh-CN/channels) — 所有支持的渠道 +- [配对](/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/nostr.md b/docs/zh-CN/channels/nostr.md index 675ddfbe9..e0db79d8e 100644 --- a/docs/zh-CN/channels/nostr.md +++ b/docs/zh-CN/channels/nostr.md @@ -2,41 +2,43 @@ read_when: - 你希望 OpenClaw 通过 Nostr 接收私信 - 你正在设置去中心化消息传递 -summary: 通过 NIP-04 加密消息提供的 Nostr 私信渠道 +summary: 通过 NIP-04 加密消息的 Nostr 私信渠道 title: Nostr x-i18n: - generated_at: "2026-04-23T20:41:47Z" - model: gpt-5.4 + generated_at: "2026-04-29T05:38:07Z" + model: gpt-5.5 provider: openai - source_hash: 7f722bb4e1c5f2b3a9c1d58f5597aad2826a809cba3d165af7bf2faf72b68a0f + source_hash: 545d68077c9fe81d5fa5a17262d37e3688185a1fb12d67b8b1053b27b96c3c7f source_path: channels/nostr.md - workflow: 15 + workflow: 16 --- -**状态:** 可选内置插件(默认禁用,需配置后启用)。 +**Status:** 可选内置插件(默认禁用,直到配置后启用)。 -Nostr 是一种用于社交网络的去中心化协议。此渠道使 OpenClaw 能够通过 NIP-04 接收并回复加密私信(DM)。 +Nostr 是一种用于社交网络的去中心化协议。此渠道让 OpenClaw 能够通过 NIP-04 接收并响应加密私信。 ## 内置插件 -当前 OpenClaw 版本将 Nostr 作为内置插件提供,因此常规打包构建无需单独安装。 +当前 OpenClaw 版本将 Nostr 作为内置插件发布,因此普通的打包构建不需要单独安装。 ### 较旧/自定义安装 - 新手引导(`openclaw onboard`)和 `openclaw channels add` 仍会从共享渠道目录中展示 Nostr。 -- 如果你的构建排除了内置的 Nostr,请手动安装。 +- 如果你的构建排除了内置 Nostr,请在有当前 npm 包发布时安装它。 ```bash openclaw plugins install @openclaw/nostr ``` -使用本地检出版本(开发工作流): +如果 npm 报告 OpenClaw 拥有的包已弃用,请使用当前打包的 OpenClaw 构建或本地检出,直到更新的 npm 包发布。 + +使用本地检出(开发工作流): ```bash openclaw plugins install --link ``` -安装或启用插件后,重启 Gateway 网关。 +安装或启用插件后重启 Gateway 网关。 ### 非交互式设置 @@ -45,18 +47,18 @@ openclaw channels add --channel nostr --private-key "$NOSTR_PRIVATE_KEY" openclaw channels add --channel nostr --private-key "$NOSTR_PRIVATE_KEY" --relay-urls "wss://relay.damus.io,wss://relay.primal.net" ``` -使用 `--use-env` 可将 `NOSTR_PRIVATE_KEY` 保留在环境变量中,而不是将该密钥存储在配置中。 +使用 `--use-env` 将 `NOSTR_PRIVATE_KEY` 保留在环境中,而不是把密钥存储到配置里。 ## 快速设置 -1. 生成 Nostr 密钥对(如有需要): +1. 生成一个 Nostr 密钥对(如有需要): ```bash # Using nak nak key generate ``` -2. 添加到配置中: +2. 添加到配置: ```json5 { @@ -78,19 +80,19 @@ export NOSTR_PRIVATE_KEY="nsec1..." ## 配置参考 -| 键名 | 类型 | 默认值 | 说明 | -| ------------ | -------- | ------------------------------------------- | ---------------------------------- | -| `privateKey` | string | 必填 | `nsec` 或十六进制格式的私钥 | -| `relays` | string[] | `['wss://relay.damus.io', 'wss://nos.lol']` | 中继 URL(WebSocket) | -| `dmPolicy` | string | `pairing` | 私信访问策略 | -| `allowFrom` | string[] | `[]` | 允许的发送者公钥 | -| `enabled` | boolean | `true` | 启用/禁用渠道 | -| `name` | string | - | 显示名称 | -| `profile` | object | - | NIP-01 个人资料元数据 | +| 键名 | 类型 | 默认值 | 描述 | +| ------------ | -------- | ------------------------------------------- | ------------------------------- | +| `privateKey` | string | 必需 | `nsec` 或十六进制格式的私钥 | +| `relays` | string[] | `['wss://relay.damus.io', 'wss://nos.lol']` | 中继 URL(WebSocket) | +| `dmPolicy` | string | `pairing` | 私信访问策略 | +| `allowFrom` | string[] | `[]` | 允许的发送者公钥 | +| `enabled` | boolean | `true` | 启用/禁用渠道 | +| `name` | string | - | 显示名称 | +| `profile` | object | - | NIP-01 个人资料元数据 | ## 个人资料元数据 -个人资料数据会作为 NIP-01 `kind:0` 事件发布。你可以在控制 UI 中管理它(Channels -> Nostr -> Profile),也可以直接在配置中设置。 +个人资料数据会作为 NIP-01 `kind:0` 事件发布。你可以从控制界面(Channels -> Nostr -> Profile)管理它,也可以直接在配置中设置。 示例: @@ -114,10 +116,10 @@ export NOSTR_PRIVATE_KEY="nsec1..." } ``` -说明: +注意: - 个人资料 URL 必须使用 `https://`。 -- 从中继导入时会合并字段,并保留本地覆盖值。 +- 从中继导入会合并字段并保留本地覆盖项。 ## 访问控制 @@ -125,14 +127,14 @@ export NOSTR_PRIVATE_KEY="nsec1..." - **pairing**(默认):未知发送者会收到配对码。 - **allowlist**:只有 `allowFrom` 中的公钥可以发送私信。 -- **open**:公开接收入站私信(需要 `allowFrom: ["*"]`)。 -- **disabled**:忽略入站私信。 +- **open**:公开传入私信(需要 `allowFrom: ["*"]`)。 +- **disabled**:忽略传入私信。 执行说明: -- 在执行发送者策略和 NIP-04 解密之前,会先验证入站事件签名,因此伪造事件会被尽早拒绝。 +- 在发送者策略和 NIP-04 解密之前,会先验证传入事件签名,因此伪造事件会被尽早拒绝。 - 配对回复会在不处理原始私信正文的情况下发送。 -- 入站私信会进行速率限制,过大的载荷会在解密前被丢弃。 +- 传入私信会受到速率限制,超大载荷会在解密前被丢弃。 ### 允许列表示例 @@ -172,19 +174,19 @@ export NOSTR_PRIVATE_KEY="nsec1..." 提示: -- 使用 2 到 3 个中继以实现冗余。 -- 避免使用过多中继(会增加延迟和重复)。 +- 使用 2-3 个中继以获得冗余。 +- 避免使用过多中继(延迟、重复)。 - 付费中继可以提升可靠性。 - 本地中继适合测试(`ws://localhost:7777`)。 ## 协议支持 -| NIP | 状态 | 说明 | -| ------ | ------- | ---------------------------- | -| NIP-01 | 支持 | 基本事件格式 + 个人资料元数据 | -| NIP-04 | 支持 | 加密私信(`kind:4`) | -| NIP-17 | 计划中 | Gift-wrapped 私信 | -| NIP-44 | 计划中 | 版本化加密 | +| NIP | Status | 描述 | +| ------ | --------- | ----------------------------------- | +| NIP-01 | 已支持 | 基本事件格式 + 个人资料元数据 | +| NIP-04 | 已支持 | 加密私信(`kind:4`) | +| NIP-17 | 已计划 | 礼物包装私信 | +| NIP-44 | 已计划 | 带版本的加密 | ## 测试 @@ -208,48 +210,48 @@ docker run -p 7777:7777 ghcr.io/hoytech/strfry ### 手动测试 -1. 从日志中记下机器人的公钥(npub)。 +1. 从日志中记下机器人公钥(npub)。 2. 打开一个 Nostr 客户端(Damus、Amethyst 等)。 3. 向机器人公钥发送私信。 -4. 验证回复。 +4. 验证响应。 ## 故障排除 -### 未接收到消息 +### 未收到消息 - 验证私钥有效。 -- 确保中继 URL 可达,并使用 `wss://`(本地可使用 `ws://`)。 +- 确保中继 URL 可访问,并使用 `wss://`(本地使用 `ws://`)。 - 确认 `enabled` 不是 `false`。 -- 检查 Gateway 网关日志中是否有中继连接错误。 +- 检查 Gateway 网关日志中的中继连接错误。 -### 未发送回复 +### 未发送响应 - 检查中继是否接受写入。 -- 验证出站连接正常。 -- 注意中继速率限制。 +- 验证出站连接。 +- 留意中继速率限制。 -### 重复回复 +### 重复响应 -- 在使用多个中继时这是预期行为。 -- 消息会按事件 ID 去重;只有首次送达会触发回复。 +- 使用多个中继时属于预期行为。 +- 消息按事件 ID 去重;只有首次投递会触发响应。 ## 安全 -- 不要提交私钥。 -- 对密钥使用环境变量。 +- 永远不要提交私钥。 +- 使用环境变量存放密钥。 - 生产机器人建议使用 `allowlist`。 -- 会先验证签名,再执行发送者策略,并在解密前完成发送者策略检查,因此伪造事件会被尽早拒绝,未知发送者也无法强制触发完整的加密计算。 +- 签名会在发送者策略之前验证,发送者策略会在解密之前执行,因此伪造事件会被尽早拒绝,未知发送者无法强制执行完整加密工作。 ## 限制(MVP) -- 仅支持私信(不支持群聊)。 +- 仅支持直接消息(不支持群聊)。 - 不支持媒体附件。 -- 仅支持 NIP-04(计划支持 NIP-17 gift-wrap)。 +- 仅支持 NIP-04(已计划 NIP-17 礼物包装)。 -## 相关内容 +## 相关 -- [渠道概览](/zh-CN/channels) —— 所有支持的渠道 -- [配对](/zh-CN/channels/pairing) —— 私信认证与配对流程 -- [群组](/zh-CN/channels/groups) —— 群聊行为与提及门控 -- [渠道路由](/zh-CN/channels/channel-routing) —— 消息的会话路由 -- [安全](/zh-CN/gateway/security) —— 访问模型与加固措施 +- [渠道概览](/zh-CN/channels) — 所有受支持的渠道 +- [配对](/zh-CN/channels/pairing) — 私信身份验证和配对流程 +- [群组](/zh-CN/channels/groups) — 群聊行为和提及门控 +- [渠道路由](/zh-CN/channels/channel-routing) — 消息的会话路由 +- [安全](/zh-CN/gateway/security) — 访问模型和加固 diff --git a/docs/zh-CN/channels/tlon.md b/docs/zh-CN/channels/tlon.md index d14e8e402..26b1d4bb6 100644 --- a/docs/zh-CN/channels/tlon.md +++ b/docs/zh-CN/channels/tlon.md @@ -4,54 +4,57 @@ read_when: summary: Tlon/Urbit 支持状态、能力和配置 title: Tlon x-i18n: - generated_at: "2026-04-23T20:42:06Z" - model: gpt-5.4 + generated_at: "2026-04-29T05:38:30Z" + model: gpt-5.5 provider: openai - source_hash: 1ff92473a958a4cba355351a686431748ea801b1c640cc5873e8bdac8f37a53f + source_hash: bec632f946796a0ea4bceb5ad26f1ff1825c4304bf7252e9d2fd4d3889d36b52 source_path: channels/tlon.md - workflow: 15 + workflow: 16 --- -Tlon 是一个构建在 Urbit 之上的去中心化消息工具。OpenClaw 可以连接到你的 Urbit ship,并且 -能够响应私信和群聊消息。默认情况下,群组回复需要带上 @ 提及,并且 -还可以通过允许列表进一步限制。 +Tlon 是构建在 Urbit 上的去中心化消息工具。OpenClaw 会连接到你的 Urbit ship,并可以 +回复私信和群聊消息。群组回复默认需要 @ 提及,并且可以通过允许列表进一步限制。 -状态:内置插件。支持私信、群组提及、线程回复、富文本格式以及 -图像上传。尚不支持回应和投票。 +Status:内置插件。支持私信、群组提及、线程回复、富文本格式和 +图片上传。尚不支持回应和投票。 ## 内置插件 -Tlon 在当前的 OpenClaw 版本中作为内置插件提供,因此普通打包 -构建无需单独安装。 +在当前 OpenClaw 版本中,Tlon 作为内置插件随包提供,因此普通打包 +构建不需要单独安装。 -如果你使用的是较旧的构建版本,或者排除了 Tlon 的自定义安装,请 -手动安装: +如果你使用的是较旧版本,或自定义安装排除了 Tlon,请在发布当前 npm 包后安装 +当前 npm 包: -通过 CLI 安装(npm registry): +通过 CLI 安装(npm registry,在存在当前包时): ```bash openclaw plugins install @openclaw/tlon ``` -本地检出安装(在 git 仓库中运行时): +如果 npm 报告 OpenClaw 所有的包已弃用,请使用当前打包的 +OpenClaw 构建,或在更新的 npm 包 +发布之前使用本地检出路径。 + +本地检出(从 git repo 运行时): ```bash openclaw plugins install ./path/to/local/tlon-plugin ``` -详情请参阅:[Plugins](/zh-CN/tools/plugin) +详情:[插件](/zh-CN/tools/plugin) ## 设置 1. 确保 Tlon 插件可用。 - - 当前打包的 OpenClaw 版本已内置该插件。 - - 较旧 / 自定义安装可通过上述命令手动添加。 -2. 收集你的 ship URL 和登录代码。 + - 当前打包的 OpenClaw 版本已经内置它。 + - 较旧/自定义安装可以使用上面的命令手动添加它。 +2. 获取你的 ship URL 和登录代码。 3. 配置 `channels.tlon`。 4. 重启 Gateway 网关。 -5. 给机器人发送私信,或在群组渠道中提及它。 +5. 私信该机器人,或在群组渠道中提及它。 -最小配置(单账户): +最小配置(单账号): ```json5 { @@ -61,17 +64,17 @@ openclaw plugins install ./path/to/local/tlon-plugin ship: "~sampel-palnet", url: "https://your-ship-host", code: "lidlut-tabwed-pillex-ridrup", - ownerShip: "~your-main-ship", // 推荐:你的 ship,始终允许 + ownerShip: "~your-main-ship", // recommended: your ship, always allowed }, }, } ``` -## 私有 / 局域网 ship +## 私有/LAN ships -默认情况下,OpenClaw 会阻止私有 / 内部主机名和 IP 范围,以提供 SSRF 防护。 -如果你的 ship 运行在私有网络中(localhost、局域网 IP 或内部主机名), -你必须显式启用: +默认情况下,OpenClaw 会阻止私有/内部主机名和 IP 范围以防护 SSRF。 +如果你的 ship 运行在私有网络上(localhost、LAN IP 或内部主机名), +你必须显式选择启用: ```json5 { @@ -84,14 +87,14 @@ openclaw plugins install ./path/to/local/tlon-plugin } ``` -这适用于以下 URL: +这适用于如下 URL: - `http://localhost:8080` - `http://192.168.x.x:8080` - `http://my-ship.local:8080` -⚠️ 仅当你信任本地网络时才启用此项。此设置会禁用对你的 ship URL -请求的 SSRF 防护。 +⚠️ 仅在你信任本地网络时启用此项。此设置会对发往你的 ship URL 的请求 +禁用 SSRF 防护。 ## 群组渠道 @@ -121,7 +124,7 @@ openclaw plugins install ./path/to/local/tlon-plugin ## 访问控制 -私信允许列表(空 = 不允许任何私信,使用 `ownerShip` 进行审批流程): +私信允许列表(空 = 不允许任何私信,使用 `ownerShip` 处理审批流程): ```json5 { @@ -156,9 +159,9 @@ openclaw plugins install ./path/to/local/tlon-plugin } ``` -## 所有者与审批系统 +## 所有者和审批系统 -设置一个所有者 ship,以便在未授权用户尝试交互时接收审批请求: +设置一个所有者 ship,以便在未授权用户尝试互动时接收审批请求: ```json5 { @@ -170,19 +173,19 @@ openclaw plugins install ./path/to/local/tlon-plugin } ``` -所有者 ship 会在**所有地方自动获得授权**——私信邀请会自动接受,并且 -渠道消息始终允许。你无需将所有者添加到 `dmAllowlist` 或 -`defaultAuthorizedShips` 中。 +所有者 ship 会**自动在所有位置获得授权**——私信邀请会自动接受, +渠道消息始终允许。你不需要把所有者添加到 `dmAllowlist` 或 +`defaultAuthorizedShips`。 -设置后,所有者会通过私信接收以下通知: +设置后,所有者会收到以下私信通知: -- 不在允许列表中的 ship 发来的私信请求 -- 未获授权的渠道提及 +- 来自不在允许列表中的 ship 的私信请求 +- 未授权渠道中的提及 - 群组邀请请求 ## 自动接受设置 -自动接受私信邀请(适用于 `dmAllowlist` 中的 ship): +自动接受私信邀请(来自 dmAllowlist 中的 ship): ```json5 { @@ -206,43 +209,43 @@ openclaw plugins install ./path/to/local/tlon-plugin } ``` -## 投递目标(CLI / cron) +## 投递目标(CLI/cron) 将这些与 `openclaw message send` 或 cron 投递一起使用: - 私信:`~sampel-palnet` 或 `dm/~sampel-palnet` - 群组:`chat/~host-ship/channel` 或 `group:~host-ship/channel` -## 内置 Skills +## 内置 skill -Tlon 插件包含一个内置 Skills([`@tloncorp/tlon-skill`](https://github.com/tloncorp/tlon-skill)), -提供对 Tlon 操作的 CLI 访问: +Tlon 插件包含一个内置 skill([`@tloncorp/tlon-skill`](https://github.com/tloncorp/tlon-skill)), +它提供对 Tlon 操作的 CLI 访问: -- **联系人**:获取 / 更新资料、列出联系人 +- **联系人**:获取/更新个人资料,列出联系人 - **渠道**:列出、创建、发布消息、获取历史记录 - **群组**:列出、创建、管理成员 -- **私信**:发送消息、对消息添加回应 -- **回应**:为帖子和私信添加 / 移除表情回应 -- **设置**:通过斜杠命令管理插件权限 +- **私信**:发送消息、对消息作出回应 +- **回应**:向帖子和私信添加/移除 emoji 回应 +- **设置**:通过 slash commands 管理插件权限 -安装插件后,该 Skills 会自动可用。 +安装插件后,该 skill 会自动可用。 ## 能力 -| 功能 | 状态 | +| 功能 | Status | | --------------- | --------------------------------------- | -| 私信 | ✅ 支持 | -| 群组 / 渠道 | ✅ 支持(默认需要提及门控) | -| 线程 | ✅ 支持(在线程中自动回复) | -| 富文本 | ✅ Markdown 转换为 Tlon 格式 | -| 图像 | ✅ 上传到 Tlon 存储 | -| 回应 | ✅ 通过[内置 Skills](#bundled-skill) | -| 投票 | ❌ 尚不支持 | -| 原生命令 | ✅ 支持(默认仅所有者可用) | +| 直接消息 | ✅ 支持 | +| 群组/渠道 | ✅ 支持(默认需要提及) | +| 线程 | ✅ 支持(在线程中自动回复) | +| 富文本 | ✅ Markdown 会转换为 Tlon 格式 | +| 图片 | ✅ 上传到 Tlon 存储 | +| 回应 | ✅ 通过[内置 skill](#bundled-skill) | +| 投票 | ❌ 尚不支持 | +| 原生命令 | ✅ 支持(默认仅所有者) | ## 故障排除 -请先运行以下检查链: +先运行此排查阶梯: ```bash openclaw status @@ -251,45 +254,45 @@ openclaw logs --follow openclaw doctor ``` -常见故障: +常见失败: -- **私信被忽略**:发送者不在 `dmAllowlist` 中,且未配置 `ownerShip` 用于审批流程。 -- **群组消息被忽略**:渠道未被发现,或发送者未获授权。 -- **连接错误**:检查 ship URL 是否可访问;本地 ship 请启用 `allowPrivateNetwork`。 -- **身份验证错误**:确认登录代码仍然有效(代码会轮换)。 +- **私信被忽略**:发送者不在 `dmAllowlist` 中,并且没有为审批流程配置 `ownerShip`。 +- **群组消息被忽略**:渠道未被发现,或发送者未获得授权。 +- **连接错误**:检查 ship URL 是否可访问;对本地 ship 启用 `allowPrivateNetwork`。 +- **认证错误**:确认登录代码是当前有效的(代码会轮换)。 ## 配置参考 -完整配置: [配置](/zh-CN/gateway/configuration) +完整配置:[配置](/zh-CN/gateway/configuration) 提供商选项: -- `channels.tlon.enabled`:启用 / 禁用渠道启动。 +- `channels.tlon.enabled`:启用/禁用渠道启动。 - `channels.tlon.ship`:机器人的 Urbit ship 名称(例如 `~sampel-palnet`)。 - `channels.tlon.url`:ship URL(例如 `https://sampel-palnet.tlon.network`)。 - `channels.tlon.code`:ship 登录代码。 -- `channels.tlon.allowPrivateNetwork`:允许 localhost / 局域网 URL(绕过 SSRF)。 -- `channels.tlon.ownerShip`:审批系统的所有者 ship(始终获授权)。 +- `channels.tlon.allowPrivateNetwork`:允许 localhost/LAN URL(绕过 SSRF)。 +- `channels.tlon.ownerShip`:审批系统的所有者 ship(始终授权)。 - `channels.tlon.dmAllowlist`:允许发送私信的 ship(空 = 无)。 -- `channels.tlon.autoAcceptDmInvites`:自动接受来自允许列表 ship 的私信。 +- `channels.tlon.autoAcceptDmInvites`:自动接受来自允许列表中 ship 的私信。 - `channels.tlon.autoAcceptGroupInvites`:自动接受所有群组邀请。 - `channels.tlon.autoDiscoverChannels`:自动发现群组渠道(默认:true)。 - `channels.tlon.groupChannels`:手动固定的渠道 nest。 -- `channels.tlon.defaultAuthorizedShips`:对所有渠道获授权的 ship。 -- `channels.tlon.authorization.channelRules`:按渠道设置的授权规则。 -- `channels.tlon.showModelSignature`:在消息后附加模型名称。 +- `channels.tlon.defaultAuthorizedShips`:对所有渠道授权的 ship。 +- `channels.tlon.authorization.channelRules`:按渠道设置的认证规则。 +- `channels.tlon.showModelSignature`:向消息追加模型名称。 -## 说明 +## 注意事项 - 群组回复需要提及(例如 `~your-bot-ship`)才会响应。 -- 线程回复:如果入站消息位于某个线程中,OpenClaw 会在线程内回复。 -- 富文本:Markdown 格式(粗体、斜体、代码、标题、列表)会被转换为 Tlon 原生格式。 -- 图像:URL 会上传到 Tlon 存储并嵌入为图像块。 +- 线程回复:如果入站消息位于线程中,OpenClaw 会在线程内回复。 +- 富文本:Markdown 格式(粗体、斜体、代码、标题、列表)会转换为 Tlon 的原生格式。 +- 图片:URL 会上传到 Tlon 存储,并作为图片块嵌入。 -## 相关内容 +## 相关 -- [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) —— 访问模型与加固措施 +- [渠道概览](/zh-CN/channels) — 所有支持的渠道 +- [配对](/zh-CN/channels/pairing) — 私信认证和配对流程 +- [群组](/zh-CN/channels/groups) — 群聊行为和提及门控 +- [渠道路由](/zh-CN/channels/channel-routing) — 消息的会话路由 +- [安全](/zh-CN/gateway/security) — 访问模型和加固 diff --git a/docs/zh-CN/channels/twitch.md b/docs/zh-CN/channels/twitch.md index 6879abc37..e5a015830 100644 --- a/docs/zh-CN/channels/twitch.md +++ b/docs/zh-CN/channels/twitch.md @@ -5,23 +5,23 @@ sidebarTitle: Twitch summary: Twitch 聊天机器人配置和设置 title: Twitch x-i18n: - generated_at: "2026-04-28T11:46:33Z" + generated_at: "2026-04-29T05:38:41Z" model: gpt-5.5 provider: openai - source_hash: 0f762cb1e3de2b81eeac4832ba47690961f0497e95a9cd67b60488b61df50a6e + source_hash: 897079687a243c9c2ce2be63167e59f4413bbd89735fb79f03928547023bd787 source_path: channels/twitch.md workflow: 16 --- -通过 IRC 连接支持 Twitch 聊天。OpenClaw 以 Twitch 用户(bot 账号)的身份连接,以在渠道中接收和发送消息。 +通过 IRC 连接支持 Twitch 聊天。OpenClaw 以 Twitch 用户(机器人账号)身份连接,以在渠道中接收和发送消息。 ## 内置插件 -Twitch 在当前 OpenClaw 版本中作为内置插件提供,因此普通打包构建不需要单独安装。 +Twitch 在当前 OpenClaw 版本中作为内置插件随附,因此普通打包构建不需要单独安装。 -如果你使用的是较旧构建,或排除了 Twitch 的自定义安装,请手动安装: +如果你使用的是较旧构建,或是不包含 Twitch 的自定义安装,请在发布当前 npm 包后安装它: @@ -36,42 +36,46 @@ Twitch 在当前 OpenClaw 版本中作为内置插件提供,因此普通打包 +如果 npm 报告 OpenClaw 拥有的包已弃用,请使用当前打包的 +OpenClaw 构建,或使用本地检出路径,直到更新的 npm 包 +发布。 + 详情:[插件](/zh-CN/tools/plugin) ## 快速设置(初学者) - - 当前打包的 OpenClaw 版本已经内置它。较旧/自定义安装可以使用上面的命令手动添加。 + + 当前打包的 OpenClaw 版本已经内置它。较旧或自定义安装可以使用上面的命令手动添加。 - - 为 bot 创建一个专用 Twitch 账号(或使用现有账号)。 + + 为机器人创建专用 Twitch 账号(或使用现有账号)。 - + 使用 [Twitch Token Generator](https://twitchtokengenerator.com/): - 选择 **Bot Token** - - 验证已选择 `chat:read` 和 `chat:write` scope + - 确认已选择 `chat:read` 和 `chat:write` 作用域 - 复制 **Client ID** 和 **Access Token** - + 使用 [https://www.streamweasels.com/tools/convert-twitch-username-to-user-id/](https://www.streamweasels.com/tools/convert-twitch-username-to-user-id/) 将用户名转换为 Twitch 用户 ID。 - + - 环境变量:`OPENCLAW_TWITCH_ACCESS_TOKEN=...`(仅默认账号) - 或配置:`channels.twitch.accessToken` 如果两者都已设置,配置优先(环境变量回退仅适用于默认账号)。 - - 使用已配置的渠道启动 Gateway 网关。 + + 使用配置好的渠道启动 Gateway 网关。 -添加访问控制(`allowFrom` 或 `allowedRoles`),防止未授权用户触发 bot。`requireMention` 默认为 `true`。 +添加访问控制(`allowFrom` 或 `allowedRoles`),防止未授权用户触发机器人。`requireMention` 默认值为 `true`。 最小配置: @@ -93,10 +97,10 @@ Twitch 在当前 OpenClaw 版本中作为内置插件提供,因此普通打包 ## 它是什么 -- 一个由 Gateway 网关拥有的 Twitch 渠道。 -- 确定性路由:回复始终返回到 Twitch。 -- 每个账号映射到一个隔离的会话键 `agent::twitch:`。 -- `username` 是 bot 的账号(用于身份验证),`channel` 是要加入的聊天室。 +- 由 Gateway 网关拥有的 Twitch 渠道。 +- 确定性路由:回复始终返回 Twitch。 +- 每个账号都会映射到一个隔离的会话键 `agent::twitch:`。 +- `username` 是机器人的账号(用于身份验证),`channel` 是要加入的聊天室。 ## 设置(详细) @@ -105,14 +109,14 @@ Twitch 在当前 OpenClaw 版本中作为内置插件提供,因此普通打包 使用 [Twitch Token Generator](https://twitchtokengenerator.com/): - 选择 **Bot Token** -- 验证已选择 `chat:read` 和 `chat:write` scope +- 确认已选择 `chat:read` 和 `chat:write` 作用域 - 复制 **Client ID** 和 **Access Token** -不需要手动注册应用。Token 会在数小时后过期。 +不需要手动注册应用。令牌会在数小时后过期。 -### 配置 bot +### 配置机器人 @@ -151,21 +155,21 @@ Twitch 在当前 OpenClaw 版本中作为内置插件提供,因此普通打包 } ``` -偏好使用 `allowFrom` 作为严格允许列表。如果你想使用基于角色的访问,请改用 `allowedRoles`。 +优先使用 `allowFrom` 作为严格允许列表。如果你想要基于角色的访问,请改用 `allowedRoles`。 **可用角色:** `"moderator"`、`"owner"`、`"vip"`、`"subscriber"`、`"all"`。 -**为什么使用用户 ID?** 用户名可能会更改,从而允许冒充。用户 ID 是永久的。 +**为什么使用用户 ID?** 用户名可以更改,可能导致冒充。用户 ID 是永久的。 查找你的 Twitch 用户 ID:[https://www.streamweasels.com/tools/convert-twitch-username-to-user-id/](https://www.streamweasels.com/tools/convert-twitch-username-to-user-id/)(将你的 Twitch 用户名转换为 ID) -## Token 刷新(可选) +## 令牌刷新(可选) -来自 [Twitch Token Generator](https://twitchtokengenerator.com/) 的 token 无法自动刷新 - 过期时请重新生成。 +来自 [Twitch Token Generator](https://twitchtokengenerator.com/) 的令牌无法自动刷新;过期后请重新生成。 -若要自动刷新 token,请在 [Twitch Developer Console](https://dev.twitch.tv/console) 创建你自己的 Twitch 应用,并添加到配置: +如需自动刷新令牌,请在 [Twitch Developer Console](https://dev.twitch.tv/console) 创建你自己的 Twitch 应用,并添加到配置中: ```json5 { @@ -178,13 +182,13 @@ Twitch 在当前 OpenClaw 版本中作为内置插件提供,因此普通打包 } ``` -bot 会在过期前自动刷新 token,并记录刷新事件。 +机器人会在过期前自动刷新令牌,并记录刷新事件。 ## 多账号支持 -使用 `channels.twitch.accounts` 并为每个账号配置 token。共享模式请参阅[配置](/zh-CN/gateway/configuration)。 +使用 `channels.twitch.accounts` 配置每个账号的令牌。共享模式见[配置](/zh-CN/gateway/configuration)。 -示例(一个 bot 账号加入两个渠道): +示例(一个机器人账号加入两个渠道): ```json5 { @@ -210,7 +214,7 @@ bot 会在过期前自动刷新 token,并记录刷新事件。 ``` -每个账号都需要自己的 token(每个渠道一个 token)。 +每个账号都需要自己的令牌(每个渠道一个令牌)。 ## 访问控制 @@ -246,11 +250,11 @@ bot 会在过期前自动刷新 token,并记录刷新事件。 } ``` - `allowFrom` 是严格允许列表。设置后,只允许这些用户 ID。如果你想要基于角色的访问,请不要设置 `allowFrom`,而是配置 `allowedRoles`。 + `allowFrom` 是严格允许列表。设置后,仅允许这些用户 ID。如果你想要基于角色的访问,请不要设置 `allowFrom`,改为配置 `allowedRoles`。 - 默认情况下,`requireMention` 为 `true`。要禁用并响应所有消息: + 默认情况下,`requireMention` 为 `true`。要禁用它并响应所有消息: ```json5 { @@ -271,7 +275,7 @@ bot 会在过期前自动刷新 token,并记录刷新事件。 ## 故障排除 -首先,运行诊断命令: +首先运行诊断命令: ```bash openclaw doctor @@ -281,15 +285,15 @@ openclaw channels status --probe - **检查访问控制:** 确保你的用户 ID 在 `allowFrom` 中,或临时移除 `allowFrom` 并设置 `allowedRoles: ["all"]` 进行测试。 - - **检查 bot 是否在渠道中:** bot 必须加入 `channel` 中指定的渠道。 + - **检查机器人是否在渠道中:** 机器人必须加入 `channel` 中指定的渠道。 - “Failed to connect”或身份验证错误: + “连接失败”或身份验证错误: - - 验证 `accessToken` 是 OAuth access token 值(通常以 `oauth:` 前缀开头) - - 检查 token 具有 `chat:read` 和 `chat:write` scope - - 如果使用 token 刷新,请验证已设置 `clientSecret` 和 `refreshToken` + - 确认 `accessToken` 是 OAuth 访问令牌值(通常以 `oauth:` 前缀开头) + - 检查令牌是否具有 `chat:read` 和 `chat:write` 作用域 + - 如果使用令牌刷新,请确认已设置 `clientSecret` 和 `refreshToken` @@ -300,7 +304,7 @@ openclaw channels status --probe Access token refreshed for user 123456 (expires in 14400s) ``` - 如果你看到“token refresh disabled (no refresh token)”: + 如果你看到 “token refresh disabled (no refresh token)”: - 确保已提供 `clientSecret` - 确保已提供 `refreshToken` @@ -313,10 +317,10 @@ openclaw channels status --probe ### 账号配置 - Bot 用户名。 + 机器人用户名。 - 具有 `chat:read` 和 `chat:write` 的 OAuth access token。 + 带有 `chat:read` 和 `chat:write` 的 OAuth 访问令牌。 Twitch Client ID(来自 Token Generator 或你的应用)。 @@ -328,16 +332,16 @@ openclaw channels status --probe 启用此账号。 - 可选:用于自动 token 刷新。 + 可选:用于自动刷新令牌。 - 可选:用于自动 token 刷新。 + 可选:用于自动刷新令牌。 - Token 过期时间(秒)。 + 令牌过期时间,单位为秒。 - Token 获取时间戳。 + 令牌获取时间戳。 用户 ID 允许列表。 @@ -346,17 +350,17 @@ openclaw channels status --probe 基于角色的访问控制。 - 要求 @mention。 + 要求 @提及。 ### 提供商选项 - `channels.twitch.enabled` - 启用/禁用渠道启动 -- `channels.twitch.username` - Bot 用户名(简化的单账号配置) -- `channels.twitch.accessToken` - OAuth access token(简化的单账号配置) +- `channels.twitch.username` - 机器人用户名(简化的单账号配置) +- `channels.twitch.accessToken` - OAuth 访问令牌(简化的单账号配置) - `channels.twitch.clientId` - Twitch Client ID(简化的单账号配置) - `channels.twitch.channel` - 要加入的渠道(简化的单账号配置) -- `channels.twitch.accounts.` - 多账号配置(上方所有账号字段) +- `channels.twitch.accounts.` - 多账号配置(上面的所有账号字段) 完整示例: @@ -395,7 +399,7 @@ openclaw channels status --probe ## 工具动作 -智能体可以调用 `twitch` 并使用动作: +智能体可以调用带有以下动作的 `twitch`: - `send` - 向渠道发送消息 @@ -413,23 +417,23 @@ openclaw channels status --probe ## 安全与运维 -- **像对待密码一样对待 token** — 切勿将 token 提交到 git。 -- **使用自动 token 刷新**,适用于长时间运行的 bot。 -- **使用用户 ID 允许列表**,不要用用户名进行访问控制。 -- **监控日志**,查看 token 刷新事件和连接状态。 -- **最小化 token scope** — 只请求 `chat:read` 和 `chat:write`。 -- **如果卡住**:确认没有其他进程占用会话后,重启 Gateway 网关。 +- **像对待密码一样对待令牌** — 切勿将令牌提交到 git。 +- **使用自动令牌刷新** 支持长期运行的机器人。 +- **使用用户 ID 允许列表** 而不是用户名进行访问控制。 +- **监控日志**,查看令牌刷新事件和连接状态。 +- **最小化令牌作用域** — 仅请求 `chat:read` 和 `chat:write`。 +- **如果卡住**:在确认没有其他进程占用该会话后,重启 Gateway 网关。 ## 限制 - 每条消息 **500 个字符**(按单词边界自动分块)。 -- Markdown 会在分块前被剥离。 -- 无速率限制(使用 Twitch 内置的速率限制)。 +- Markdown 会在分块前移除。 +- 无速率限制(使用 Twitch 内置速率限制)。 ## 相关 - [渠道路由](/zh-CN/channels/channel-routing) — 消息的会话路由 -- [渠道概览](/zh-CN/channels) — 所有受支持的渠道 -- [群组](/zh-CN/channels/groups) — 群聊行为和 mention 门控 +- [渠道概览](/zh-CN/channels) — 所有支持的渠道 +- [群组](/zh-CN/channels/groups) — 群聊行为与提及门控 - [配对](/zh-CN/channels/pairing) — 私信身份验证和配对流程 -- [安全](/zh-CN/gateway/security) — 访问模型和加固 +- [安全](/zh-CN/gateway/security) — 访问模型与加固 diff --git a/docs/zh-CN/channels/whatsapp.md b/docs/zh-CN/channels/whatsapp.md index c73b9a368..f32830be1 100644 --- a/docs/zh-CN/channels/whatsapp.md +++ b/docs/zh-CN/channels/whatsapp.md @@ -1,39 +1,41 @@ --- read_when: - - 处理 WhatsApp/web 渠道行为或收件箱路由 -summary: WhatsApp 渠道支持、访问控制、投递行为和运维 + - 处理 WhatsApp/网页渠道行为或收件箱路由 +summary: WhatsApp 渠道支持、访问控制、送达行为和运维 title: WhatsApp x-i18n: - generated_at: "2026-04-29T04:46:51Z" + generated_at: "2026-04-29T05:38:54Z" model: gpt-5.5 provider: openai - source_hash: adf84a966468b60d50f7a770fac5c862fa527957ff9ac06acaf8aa35ebd1bbdb + source_hash: 9057208c69d125aea8d063f7c16c98babbf70ded7f693bdb15cde159c4920019 source_path: channels/whatsapp.md workflow: 16 --- -Status:通过 WhatsApp Web(Baileys)达到生产就绪。Gateway 网关拥有已链接会话。 +Status:已通过 WhatsApp Web(Baileys)达到生产就绪。Gateway 网关拥有已关联会话。 -## 按需安装 +## 安装(按需) - 新手引导(`openclaw onboard`)和 `openclaw channels add --channel whatsapp` 会在你首次选择 WhatsApp 插件时提示安装。 - 当插件尚未存在时,`openclaw channels login --channel whatsapp` 也会提供安装流程。 - 开发渠道 + git checkout:默认使用本地插件路径。 -- 稳定版/Beta:默认使用 npm 包 `@openclaw/whatsapp`。 +- Stable/Beta:当当前软件包已发布时,使用 npm 包 `@openclaw/whatsapp`。 -仍可手动安装: +仍然可以手动安装: ```bash openclaw plugins install @openclaw/whatsapp ``` +如果 npm 报告 OpenClaw 拥有的软件包已弃用或缺失,请使用当前打包的 OpenClaw 构建或本地 checkout,直到 npm 包发布链路跟上。 + 未知发送者的默认私信策略是配对。 - 跨渠道诊断和修复操作手册。 + 跨渠道诊断和修复手册。 完整的渠道配置模式和示例。 @@ -60,19 +62,19 @@ openclaw plugins install @openclaw/whatsapp
- + ```bash openclaw channels login --channel whatsapp ``` - 针对特定账号: + 对于特定账户: ```bash openclaw channels login --channel whatsapp --account work ``` - 在登录前挂载现有/自定义 WhatsApp Web 认证目录: + 若要在登录前附加现有/自定义 WhatsApp Web 认证目录: ```bash openclaw channels add --channel whatsapp --account work --auth-dir /path/to/wa-auth @@ -89,7 +91,7 @@ openclaw gateway - + ```bash openclaw pairing list whatsapp @@ -102,7 +104,7 @@ openclaw pairing approve whatsapp
-OpenClaw 建议尽可能使用单独的号码运行 WhatsApp。(渠道元数据和设置流程针对这种设置做了优化,但也支持个人号码设置。) +OpenClaw 建议在可能时使用单独号码运行 WhatsApp。(渠道元数据和设置流程针对这种设置进行了优化,但也支持个人号码设置。) ## 部署模式 @@ -111,7 +113,7 @@ OpenClaw 建议尽可能使用单独的号码运行 WhatsApp。(渠道元数 这是最清晰的运维模式: - - OpenClaw 使用单独的 WhatsApp 身份 + - 为 OpenClaw 使用单独的 WhatsApp 身份 - 更清晰的私信 allowlist 和路由边界 - 更低的自聊混淆概率 @@ -130,14 +132,14 @@ OpenClaw 建议尽可能使用单独的号码运行 WhatsApp。(渠道元数 - - 新手引导支持个人号码模式,并会写入适合自聊的基线配置: + + 新手引导支持个人号码模式,并会写入适合自聊的基线: - `dmPolicy: "allowlist"` - `allowFrom` 包含你的个人号码 - `selfChatMode: true` - 运行时中,自聊保护基于已链接的本人号码和 `allowFrom`。 + 在运行时,自聊保护基于已关联的自身号码和 `allowFrom`。 @@ -152,21 +154,19 @@ OpenClaw 建议尽可能使用单独的号码运行 WhatsApp。(渠道元数 ## 运行时模型 - Gateway 网关拥有 WhatsApp socket 和重连循环。 -- 重连看门狗使用 WhatsApp Web 传输活动,而不只使用入站应用消息量,因此安静的已链接设备会话不会仅仅因为最近没人发送消息而被重启。如果传输帧持续到达,但在看门狗窗口内没有处理应用消息,较长的应用静默上限仍会强制重连。 -- Baileys socket 时序在 `web.whatsapp.*` 下显式配置:`keepAliveIntervalMs` 控制 WhatsApp Web 应用 ping,`connectTimeoutMs` 控制开启握手超时,`defaultQueryTimeoutMs` 控制 Baileys 查询超时。 -- 出站发送需要目标账号有活跃的 WhatsApp 监听器。 +- 重连 watchdog 使用 WhatsApp Web 传输活动,而不仅是入站应用消息量,因此安静的已关联设备会话不会仅因为最近没人发送消息而被重启。如果传输帧持续到达,但在 watchdog 窗口内没有处理任何应用消息,较长的应用静默上限仍会强制重连。 +- Baileys socket 计时在 `web.whatsapp.*` 下显式配置:`keepAliveIntervalMs` 控制 WhatsApp Web 应用 ping,`connectTimeoutMs` 控制开启握手超时,`defaultQueryTimeoutMs` 控制 Baileys 查询超时。 +- 出站发送需要目标账户有活跃的 WhatsApp 监听器。 - Status 和广播聊天会被忽略(`@status`、`@broadcast`)。 -- 重连看门狗跟随 WhatsApp Web 传输活动,而不只跟随入站应用消息量:只要传输帧持续,安静的已链接设备会话就会保持在线,但传输停滞会在后续远端断开路径之前很久就强制重连。 -- 直接聊天使用私信会话规则(`session.dmScope`;默认 `main` 会把私信折叠到智能体主会话)。 -- 群组会话彼此隔离(`agent::whatsapp:group:`)。 +- 重连 watchdog 跟随 WhatsApp Web 传输活动,而不仅是入站应用消息量:只要传输帧持续,安静的已关联设备会话就会保持在线,但传输停滞会在更晚的远端断开路径之前强制重连。 +- 直接聊天使用私信会话规则(`session.dmScope`;默认 `main` 会将私信折叠到智能体主会话)。 +- 群组会话隔离(`agent::whatsapp:group:`)。 - WhatsApp Web 传输遵循 Gateway 网关主机上的标准代理环境变量(`HTTPS_PROXY`、`HTTP_PROXY`、`NO_PROXY` / 小写变体)。优先使用主机级代理配置,而不是渠道特定的 WhatsApp 代理设置。 -- 启用 `messages.removeAckAfterReply` 时,OpenClaw 会在可见回复送达后清除 WhatsApp ack 反应。 +- 启用 `messages.removeAckAfterReply` 时,OpenClaw 会在可见回复送达后清除 WhatsApp ack reaction。 ## 插件钩子和隐私 -WhatsApp 入站消息可能包含个人消息内容、电话号码、 -群组标识符、发送者姓名和会话关联字段。因此, -除非你显式选择加入,否则 WhatsApp 不会向插件广播入站 `message_received` 钩子载荷: +WhatsApp 入站消息可能包含个人消息内容、电话号码、群组标识符、发送者姓名和会话关联字段。因此,除非你显式选择启用,否则 WhatsApp 不会向插件广播入站 `message_received` 钩子 payload: ```json5 { @@ -180,7 +180,7 @@ WhatsApp 入站消息可能包含个人消息内容、电话号码、 } ``` -你可以将选择加入限定到一个账号: +你可以将选择启用限定到一个账户: ```json5 { @@ -198,7 +198,7 @@ WhatsApp 入站消息可能包含个人消息内容、电话号码、 } ``` -仅对你信任可接收入站 WhatsApp 消息内容和标识符的插件启用此项。 +只对你信任、可接收入站 WhatsApp 消息内容和标识符的插件启用此选项。 ## 访问控制和激活 @@ -213,13 +213,13 @@ WhatsApp 入站消息可能包含个人消息内容、电话号码、 `allowFrom` 接受 E.164 风格号码(内部会规范化)。 - 多账号覆盖:`channels.whatsapp.accounts..dmPolicy`(以及 `allowFrom`)优先于该账号的渠道级默认值。 + 多账户覆盖:`channels.whatsapp.accounts..dmPolicy`(以及 `allowFrom`)优先于该账户的渠道级默认值。 运行时行为详情: - - 配对会持久化到渠道允许存储中,并与已配置的 `allowFrom` 合并 - - 如果未配置 allowlist,默认允许已链接的本人号码 - - OpenClaw 永远不会自动配对出站 `fromMe` 私信(你从已链接设备发送给自己的消息) + - 配对会持久化到渠道 allow-store,并与已配置的 `allowFrom` 合并 + - 如果未配置 allowlist,则默认允许已关联的自身号码 + - OpenClaw 绝不会自动配对出站 `fromMe` 私信(你从已关联设备发送给自己的消息)
@@ -227,63 +227,63 @@ WhatsApp 入站消息可能包含个人消息内容、电话号码、 群组访问有两层: 1. **群组成员 allowlist**(`channels.whatsapp.groups`) - - 如果省略 `groups`,则所有群组都有资格 + - 如果省略 `groups`,则所有群组都符合条件 - 如果存在 `groups`,它会作为群组 allowlist(允许 `"*"`) 2. **群组发送者策略**(`channels.whatsapp.groupPolicy` + `groupAllowFrom`) - `open`:绕过发送者 allowlist - `allowlist`:发送者必须匹配 `groupAllowFrom`(或 `*`) - - `disabled`:阻止所有群组入站消息 + - `disabled`:阻止所有群组入站 - 发送者 allowlist 后备: + 发送者 allowlist 备用逻辑: - 如果未设置 `groupAllowFrom`,运行时会在可用时回退到 `allowFrom` - - 发送者 allowlist 会在提及/回复激活之前评估 + - 发送者 allowlist 会在提及/回复激活前评估 - 注意:如果根本不存在 `channels.whatsapp` 块,运行时群组策略后备是 `allowlist`(并记录警告日志),即使设置了 `channels.defaults.groupPolicy` 也是如此。 + 注意:如果完全不存在 `channels.whatsapp` 块,则运行时群组策略备用值是 `allowlist`(并记录警告日志),即使设置了 `channels.defaults.groupPolicy` 也是如此。
- 群组回复默认需要提及。 + 默认情况下,群组回复需要提及。 提及检测包括: - - 显式提及机器人身份的 WhatsApp 提及 - - 已配置的提及正则模式(`agents.list[].groupChat.mentionPatterns`,后备为 `messages.groupChat.mentionPatterns`) - - 已授权群组消息的入站语音便笺转写 - - 隐式回复机器人检测(回复发送者匹配机器人身份) + - 显式提及 bot 身份的 WhatsApp mention + - 已配置的提及正则模式(`agents.list[].groupChat.mentionPatterns`,备用 `messages.groupChat.mentionPatterns`) + - 已授权群组消息的入站语音便笺转录 + - 隐式回复 bot 检测(回复发送者匹配 bot 身份) 安全说明: - - 引用/回复只满足提及门控;它**不会**授予发送者授权 - - 使用 `groupPolicy: "allowlist"` 时,非 allowlist 发送者即使回复 allowlist 用户的消息,仍会被阻止 + - quote/reply 只满足提及门控;它**不会**授予发送者授权 + - 使用 `groupPolicy: "allowlist"` 时,非 allowlisted 发送者仍会被阻止,即使他们回复的是 allowlisted 用户的消息 会话级激活命令: - `/activation mention` - `/activation always` - `activation` 更新会话状态(不是全局配置)。它受所有者门控。 + `activation` 会更新会话状态(不是全局配置)。它受 owner 门控。
## 个人号码和自聊行为 -当已链接的本人号码也出现在 `allowFrom` 中时,WhatsApp 自聊防护会激活: +当已关联的自身号码也存在于 `allowFrom` 中时,WhatsApp 自聊保护会激活: - 跳过自聊轮次的已读回执 -- 忽略否则会 ping 你自己的提及 JID 自动触发行为 +- 忽略原本会 ping 你自己的 mention-JID 自动触发行为 - 如果未设置 `messages.responsePrefix`,自聊回复默认使用 `[{identity.name}]` 或 `[openclaw]` ## 消息规范化和上下文 - 传入的 WhatsApp 消息会包装在共享入站信封中。 + 入站 WhatsApp 消息会包装在共享入站信封中。 - 如果存在引用回复,上下文会按以下形式追加: + 如果存在引用回复,上下文会以这种形式追加: ```text [Replying to id:] @@ -296,7 +296,7 @@ WhatsApp 入站消息可能包含个人消息内容、电话号码、 - 仅媒体的入站消息会用如下占位符规范化: + 仅媒体的入站消息会规范化为如下占位符: - `` - `` @@ -304,18 +304,18 @@ WhatsApp 入站消息可能包含个人消息内容、电话号码、 - `` - `` - 当正文只有 `` 时,已授权群组语音便笺会在提及门控前转写,因此在语音便笺中说出机器人提及可以触发回复。如果转写内容仍未提及机器人,转写会保存在待处理群组历史中,而不是原始占位符。 + 当正文只有 `` 时,已授权的群组语音便笺会在提及门控前转录,因此在语音便笺中说出 bot mention 可以触发回复。如果转录文本仍未提及 bot,转录文本会保留在待处理群组历史中,而不是保留原始占位符。 - 位置正文使用简洁的坐标文本。位置标签/评论以及联系人/vCard 详情会渲染为围栏包裹的不受信元数据,而不是内联提示词文本。 + 位置正文使用简短坐标文本。位置标签/评论和联系人/vCard 详情会呈现为 fenced untrusted metadata,而不是内联 prompt 文本。 - 对于群组,未处理消息可以缓冲,并在机器人最终被触发时作为上下文注入。 + 对于群组,未处理消息可以被缓冲,并在 bot 最终被触发时作为上下文注入。 - 默认限制:`50` - 配置:`channels.whatsapp.historyLimit` - - 后备:`messages.groupChat.historyLimit` + - 备用:`messages.groupChat.historyLimit` - `0` 禁用 注入标记: @@ -326,7 +326,7 @@ WhatsApp 入站消息可能包含个人消息内容、电话号码、 - 对于已接受的入站 WhatsApp 消息,默认启用已读回执。 + 对已接受的入站 WhatsApp 消息,默认启用已读回执。 全局禁用: @@ -340,7 +340,7 @@ WhatsApp 入站消息可能包含个人消息内容、电话号码、 } ``` - 按账号覆盖: + 按账户覆盖: ```json5 { @@ -367,19 +367,19 @@ WhatsApp 入站消息可能包含个人消息内容、电话号码、 - 默认分块限制:`channels.whatsapp.textChunkLimit = 4000` - `channels.whatsapp.chunkMode = "length" | "newline"` - - `newline` 模式优先使用段落边界(空行),然后回退到长度安全分块 + - `newline` 模式优先使用段落边界(空行),然后回退到长度安全的分块 - 支持图片、视频、音频(PTT 语音便笺)和文档载荷 - - 音频媒体会通过 Baileys `audio` 载荷并带 `ptt: true` 发送,因此 WhatsApp 客户端会将其呈现为一条一键通语音便笺 - - 回复载荷会保留 `audioAsVoice`;即使提供商返回 MP3 或 WebM,WhatsApp 的 TTS 语音便笺输出也会保持在这条 PTT 路径上 - - 原生 Ogg/Opus 音频会以 `audio/ogg; codecs=opus` 发送,以兼容语音便笺 - - 非 Ogg 音频,包括 Microsoft Edge TTS MP3/WebM 输出,会先用 `ffmpeg` 转码为 48 kHz 单声道 Ogg/Opus,再作为 PTT 发送 - - `/tts latest` 会把最新的助手回复作为一条语音便笺发送,并抑制同一回复的重复发送;`/tts chat on|off|default` 控制当前 WhatsApp 聊天的自动 TTS - - 通过视频发送中的 `gifPlayback: true` 支持 GIF 动画播放 - - 发送多媒体回复载荷时,说明文字会应用到第一个媒体项;但 PTT 语音便笺会先发送音频,再单独发送可见文本,因为 WhatsApp 客户端对语音便笺说明文字的呈现并不一致 + - 音频媒体会通过 Baileys `audio` 载荷并带上 `ptt: true` 发送,因此 WhatsApp 客户端会将其渲染为一条按住说话语音便笺 + - 回复载荷会保留 `audioAsVoice`;即使提供商返回 MP3 或 WebM,WhatsApp 的 TTS 语音便笺输出仍会走这条 PTT 路径 + - 原生 Ogg/Opus 音频会作为 `audio/ogg; codecs=opus` 发送,以兼容语音便笺 + - 非 Ogg 音频(包括 Microsoft Edge TTS 的 MP3/WebM 输出)会先用 `ffmpeg` 转码为 48 kHz 单声道 Ogg/Opus,再进行 PTT 投递 + - `/tts latest` 会把最新的助手回复作为一条语音便笺发送,并抑制同一条回复的重复发送;`/tts chat on|off|default` 控制当前 WhatsApp 聊天的自动 TTS + - 通过视频发送中的 `gifPlayback: true` 支持动画 GIF 播放 + - 发送多媒体回复载荷时,说明文字会应用到第一个媒体项;但 PTT 语音便笺会先发送音频,再单独发送可见文本,因为 WhatsApp 客户端不会稳定渲染语音便笺说明文字 - 媒体来源可以是 HTTP(S)、`file://` 或本地路径 @@ -387,8 +387,8 @@ WhatsApp 入站消息可能包含个人消息内容、电话号码、 - 入站媒体保存上限:`channels.whatsapp.mediaMaxMb`(默认 `50`) - 出站媒体发送上限:`channels.whatsapp.mediaMaxMb`(默认 `50`) - - 按账号覆盖使用 `channels.whatsapp.accounts..mediaMaxMb` - - 图片会自动优化(调整尺寸/质量扫描)以符合限制 + - 每账号覆盖使用 `channels.whatsapp.accounts..mediaMaxMb` + - 图片会自动优化(调整大小/质量扫描)以符合限制 - 媒体发送失败时,首项回退会发送文本警告,而不是静默丢弃响应 @@ -396,7 +396,7 @@ WhatsApp 入站消息可能包含个人消息内容、电话号码、 ## 错误可见性 -`channels.whatsapp.exposeErrorText` 控制是否将智能体/提供商错误文本传回 WhatsApp。默认值为 `true`。将其设为 `false` 可在 WhatsApp 上保持故障静默,同时保留其他渠道行为。 +`channels.whatsapp.exposeErrorText` 控制是否将智能体/提供商错误文本回传到 WhatsApp。默认值为 `true`。将其设为 `false` 可让 WhatsApp 上的失败保持静默,同时保留其他渠道行为。 ```json5 { @@ -408,20 +408,20 @@ WhatsApp 入站消息可能包含个人消息内容、电话号码、 } ``` -按账号覆盖使用 `channels.whatsapp.accounts..exposeErrorText`。 +每账号覆盖使用 `channels.whatsapp.accounts..exposeErrorText`。 ## 回复引用 -WhatsApp 支持原生回复引用,即出站回复会直观引用入站消息。使用 `channels.whatsapp.replyToMode` 控制它。 +WhatsApp 支持原生回复引用,即出站回复会可见地引用入站消息。用 `channels.whatsapp.replyToMode` 控制。 -| 值 | 行为 | -| ----------- | --------------------------------------------------------------------- | -| `"off"` | 从不引用;作为普通消息发送 | -| `"first"` | 只引用第一个出站回复块 | -| `"all"` | 引用每个出站回复块 | -| `"batched"` | 引用排队的批量回复,同时让即时回复不引用 | +| 值 | 行为 | +| ----------- | ------------------------------------------------------ | +| `"off"` | 从不引用;作为普通消息发送 | +| `"first"` | 仅引用第一个出站回复分块 | +| `"all"` | 引用每个出站回复分块 | +| `"batched"` | 引用排队的批量回复,同时让即时回复不带引用 | -默认值为 `"off"`。按账号覆盖使用 `channels.whatsapp.accounts..replyToMode`。 +默认值为 `"off"`。每账号覆盖使用 `channels.whatsapp.accounts..replyToMode`。 ```json5 { @@ -433,20 +433,20 @@ WhatsApp 支持原生回复引用,即出站回复会直观引用入站消息 } ``` -## 反应级别 +## 表情回应级别 -`channels.whatsapp.reactionLevel` 控制智能体在 WhatsApp 上使用表情反应的范围: +`channels.whatsapp.reactionLevel` 控制智能体在 WhatsApp 上使用表情回应的范围: -| 级别 | 确认反应 | 智能体发起的反应 | 描述 | -| ------------- | -------- | ---------------- | ------------------------------------------------ | -| `"off"` | 否 | 否 | 完全不使用反应 | -| `"ack"` | 是 | 否 | 仅确认反应(回复前回执) | -| `"minimal"` | 是 | 是(保守) | 确认 + 带保守指导的智能体反应 | -| `"extensive"` | 是 | 是(鼓励) | 确认 + 带鼓励指导的智能体反应 | +| 级别 | 确认回应 | 智能体发起的回应 | 描述 | +| ------------- | -------- | ---------------- | ---------------------------------- | +| `"off"` | 否 | 否 | 完全不使用回应 | +| `"ack"` | 是 | 否 | 仅确认回应(回复前回执) | +| `"minimal"` | 是 | 是(保守) | 确认 + 带保守指引的智能体回应 | +| `"extensive"` | 是 | 是(鼓励) | 确认 + 带鼓励指引的智能体回应 | 默认值:`"minimal"`。 -按账号覆盖使用 `channels.whatsapp.accounts..reactionLevel`。 +每账号覆盖使用 `channels.whatsapp.accounts..reactionLevel`。 ```json5 { @@ -458,10 +458,10 @@ WhatsApp 支持原生回复引用,即出站回复会直观引用入站消息 } ``` -## 确认反应 +## 确认回应 -WhatsApp 支持通过 `channels.whatsapp.ackReaction` 在收到入站消息后立即发送确认反应。 -确认反应受 `reactionLevel` 限制,在 `reactionLevel` 为 `"off"` 时会被抑制。 +WhatsApp 支持通过 `channels.whatsapp.ackReaction` 在收到入站消息时立即发送确认回应。 +确认回应受 `reactionLevel` 控制 —— 当 `reactionLevel` 为 `"off"` 时会被抑制。 ```json5 { @@ -480,8 +480,8 @@ WhatsApp 支持通过 `channels.whatsapp.ackReaction` 在收到入站消息后 行为说明: - 入站消息被接受后立即发送(回复前) -- 失败会被记录,但不会阻塞正常回复投递 -- 群组模式 `mentions` 会在由提及触发的轮次上作出反应;群组激活 `always` 会作为此检查的绕过 +- 失败会记录日志,但不会阻止正常回复投递 +- group 模式 `mentions` 会在由提及触发的轮次中回应;group 激活 `always` 会作为此检查的绕过 - WhatsApp 使用 `channels.whatsapp.ackReaction`(这里不使用旧版 `messages.ackReaction`) ## 多账号和凭证 @@ -489,8 +489,8 @@ WhatsApp 支持通过 `channels.whatsapp.ackReaction` 在收到入站消息后 - 账号 ID 来自 `channels.whatsapp.accounts` - - 默认账号选择:如果存在则使用 `default`,否则使用第一个已配置的账号 ID(排序后) - - 账号 ID 会在内部规范化以便查找 + - 默认账号选择:如果存在则使用 `default`,否则使用第一个已配置账号 ID(排序后) + - 账号 ID 会在内部规范化后用于查找 @@ -504,24 +504,24 @@ WhatsApp 支持通过 `channels.whatsapp.ackReaction` 在收到入站消息后 `openclaw channels logout --channel whatsapp [--account ]` 会清除该账号的 WhatsApp 认证状态。 - 在旧版认证目录中,`oauth.json` 会被保留,而 Baileys 认证文件会被移除。 + 在旧版认证目录中,`oauth.json` 会保留,同时移除 Baileys 认证文件。 ## 工具、操作和配置写入 -- 智能体工具支持包括 WhatsApp 反应操作(`react`)。 +- 智能体工具支持包括 WhatsApp 表情回应操作(`react`)。 - 操作门控: - `channels.whatsapp.actions.reactions` - `channels.whatsapp.actions.polls` -- 渠道发起的配置写入默认启用(通过 `channels.whatsapp.configWrites=false` 禁用)。 +- 渠道发起的配置写入默认启用(可通过 `channels.whatsapp.configWrites=false` 禁用)。 ## 故障排除 - 症状:渠道状态报告未关联。 + 症状:渠道 Status 报告未关联。 修复: @@ -532,12 +532,12 @@ WhatsApp 支持通过 `channels.whatsapp.ackReaction` 在收到入站消息后 - - 症状:已关联账号反复断开或尝试重连。 + + 症状:已关联账号反复断开连接或尝试重连。 - 安静账号可以在普通消息超时后继续保持连接;当 WhatsApp Web 传输活动停止、套接字关闭,或应用层活动静默超过更长的安全窗口时,看门狗会重启。 + 安静账号可以在正常消息超时后继续保持连接;当 WhatsApp Web 传输活动停止、套接字关闭,或应用层活动在更长的安全窗口内持续静默时,看门狗会重启。 - 如果日志显示反复出现 `status=408 Request Time-out Connection was lost`,请调节 `web.whatsapp` 下的 Baileys 套接字时序。先将 `keepAliveIntervalMs` 缩短到低于你的网络空闲超时,并在较慢或丢包链路上增大 `connectTimeoutMs`: + 如果日志显示重复的 `status=408 Request Time-out Connection was lost`,请调优 `web.whatsapp` 下的 Baileys 套接字时序。先将 `keepAliveIntervalMs` 缩短到低于你的网络空闲超时,并在慢速或有丢包的链路上增大 `connectTimeoutMs`: ```json5 { @@ -565,19 +565,19 @@ WhatsApp 支持通过 `channels.whatsapp.ackReaction` 在收到入站消息后 症状:`openclaw channels login --channel whatsapp` 在显示可用 QR 码之前失败,并出现 `status=408 Request Time-out` 或 TLS 套接字断开。 - WhatsApp Web 登录使用 Gateway 网关主机的标准代理环境(`HTTPS_PROXY`、`HTTP_PROXY`、小写变体和 `NO_PROXY`)。确认 Gateway 网关进程继承了代理环境,并且 `NO_PROXY` 不匹配 `mmg.whatsapp.net`。 + WhatsApp Web 登录使用 Gateway 网关主机的标准代理环境(`HTTPS_PROXY`、`HTTP_PROXY`、小写变体以及 `NO_PROXY`)。确认 Gateway 网关进程继承了代理环境变量,并且 `NO_PROXY` 不匹配 `mmg.whatsapp.net`。 - - 如果目标账号没有活动的 Gateway 网关监听器,出站发送会快速失败。 + + 当目标账号没有活跃的 Gateway 网关监听器时,出站发送会快速失败。 确保 Gateway 网关正在运行且账号已关联。 - 按此顺序检查: + 按以下顺序检查: - `groupPolicy` - `groupAllowFrom` / `allowFrom` @@ -592,36 +592,36 @@ WhatsApp 支持通过 `channels.whatsapp.ackReaction` 在收到入站消息后 -## 系统提示 +## 系统提示词 -WhatsApp 通过 `groups` 和 `direct` 映射,支持 Telegram 风格的群组和直接聊天系统提示。 +WhatsApp 支持通过 `groups` 和 `direct` 映射,为群组和直接聊天配置 Telegram 风格的系统提示词。 群组消息的解析层级: -首先确定有效的 `groups` 映射:如果账号定义了自己的 `groups`,它会完全替换根级 `groups` 映射(不进行深度合并)。随后在生成的单一映射上执行提示查找: +首先确定有效的 `groups` 映射:如果账号定义了自己的 `groups`,它会完全替换根级 `groups` 映射(不做深度合并)。随后在生成的单一映射上执行提示词查找: -1. **群组专属系统提示**(`groups[""].systemPrompt`):当映射中存在特定群组条目**且**其 `systemPrompt` 键已定义时使用。如果 `systemPrompt` 是空字符串(`""`),通配符会被抑制,且不会应用任何系统提示。 -2. **群组通配系统提示**(`groups["*"].systemPrompt`):当映射中完全没有特定群组条目,或该条目存在但未定义 `systemPrompt` 键时使用。 +1. **群组特定系统提示词**(`groups[""].systemPrompt`):当映射中存在特定群组条目**并且**定义了其 `systemPrompt` 键时使用。如果 `systemPrompt` 是空字符串(`""`),则通配符会被抑制,且不会应用任何系统提示词。 +2. **群组通配符系统提示词**(`groups["*"].systemPrompt`):当映射中完全不存在特定群组条目,或该条目存在但没有定义 `systemPrompt` 键时使用。 直接消息的解析层级: -首先确定有效的 `direct` 映射:如果账号定义了自己的 `direct`,它会完全替换根级 `direct` 映射(不进行深度合并)。随后在生成的单一映射上执行提示查找: +首先确定有效的 `direct` 映射:如果账号定义了自己的 `direct`,它会完全替换根级 `direct` 映射(不做深度合并)。随后在生成的单一映射上执行提示词查找: -1. **直接聊天专属系统提示**(`direct[""].systemPrompt`):当映射中存在特定对等方条目**且**其 `systemPrompt` 键已定义时使用。如果 `systemPrompt` 是空字符串(`""`),通配符会被抑制,且不会应用任何系统提示。 -2. **直接聊天通配系统提示**(`direct["*"].systemPrompt`):当映射中完全没有特定对等方条目,或该条目存在但未定义 `systemPrompt` 键时使用。 +1. **直接聊天特定系统提示词**(`direct[""].systemPrompt`):当映射中存在特定对端条目**并且**定义了其 `systemPrompt` 键时使用。如果 `systemPrompt` 是空字符串(`""`),则通配符会被抑制,且不会应用任何系统提示词。 +2. **直接聊天通配符系统提示词**(`direct["*"].systemPrompt`):当映射中完全不存在特定对端条目,或该条目存在但没有定义 `systemPrompt` 键时使用。 -`dms` 仍是轻量级的按私信历史覆盖桶(`dms..historyLimit`)。提示覆盖位于 `direct` 下。 +`dms` 仍是轻量的每私信历史覆盖桶(`dms..historyLimit`)。提示词覆盖位于 `direct` 下。 -**与 Telegram 多账号行为的区别:** 在 Telegram 中,多账号设置会刻意为所有账号抑制根级 `groups`,即使某些账号没有定义自己的 `groups` 也是如此,以防止机器人接收不属于它的群组消息。WhatsApp 不应用此保护:没有定义账号级覆盖的账号始终会继承根级 `groups` 和根级 `direct`,无论配置了多少个账号。在多账号 WhatsApp 设置中,如果你需要按账号设置群组或直接聊天提示,请在每个账号下显式定义完整映射,而不是依赖根级默认值。 +**与 Telegram 多账号行为的区别:**在 Telegram 中,多账号设置会有意对所有账号抑制根级 `groups` —— 即使某些账号没有定义自己的 `groups` —— 以防止机器人接收它不属于的群组消息。WhatsApp 不应用此保护:根级 `groups` 和根级 `direct` 始终会被未定义账号级覆盖的账号继承,无论配置了多少账号。在多账号 WhatsApp 设置中,如果你想要按账号配置群组或直接聊天提示词,请在每个账号下显式定义完整映射,而不是依赖根级默认值。 重要行为: -- `channels.whatsapp.groups` 既是按群组配置映射,也是聊天级群组允许列表。在根级或账号作用域中,`groups["*"]` 表示该作用域“允许所有群组”。 -- 只有在你已经希望该作用域允许所有群组时,才添加通配群组 `systemPrompt`。如果你仍希望只有固定的一组群组 ID 符合条件,请不要用 `groups["*"]` 作为提示默认值。请改为在每个显式允许列表群组条目上重复该提示。 -- 群组准入和发送者授权是独立检查。`groups["*"]` 会扩大可以进入群组处理的群组集合,但它本身不会授权这些群组中的每个发送者。发送者访问仍由 `channels.whatsapp.groupPolicy` 和 `channels.whatsapp.groupAllowFrom` 单独控制。 -- `channels.whatsapp.direct` 对私信没有相同副作用。`direct["*"]` 只会在私信已通过 `dmPolicy` 加 `allowFrom` 或配对存储规则准入后,提供默认直接聊天配置。 +- `channels.whatsapp.groups` 既是每群组配置映射,也是聊天级群组允许列表。在根作用域或账号作用域中,`groups["*"]` 表示该作用域“允许所有群组”。 +- 仅当你已经希望该作用域允许所有群组时,才添加通配符群组 `systemPrompt`。如果你仍希望只有一组固定的群组 ID 具备资格,不要使用 `groups["*"]` 作为提示词默认值。请改为在每个显式允许列出的群组条目上重复该提示词。 +- 群组准入和发送者授权是独立检查。`groups["*"]` 会扩大可进入群组处理的群组集合,但它本身不会授权这些群组中的每个发送者。发送者访问仍由 `channels.whatsapp.groupPolicy` 和 `channels.whatsapp.groupAllowFrom` 单独控制。 +- `channels.whatsapp.direct` 对私信没有相同的副作用。`direct["*"]` 只会在私信已通过 `dmPolicy` 加 `allowFrom` 或配对存储规则被准入后,提供默认的直接聊天配置。 示例: @@ -669,7 +669,7 @@ WhatsApp 通过 `groups` 和 `direct` 映射,支持 Telegram 风格的群组 - [配置参考 - WhatsApp](/zh-CN/gateway/config-channels#whatsapp) -关键 WhatsApp 字段: +高价值 WhatsApp 字段: - 访问:`dmPolicy`、`allowFrom`、`groupPolicy`、`groupAllowFrom`、`groups` - 投递:`textChunkLimit`、`chunkMode`、`mediaMaxMb`、`sendReadReceipts`、`ackReaction`、`reactionLevel`、`exposeErrorText` @@ -678,7 +678,7 @@ WhatsApp 通过 `groups` 和 `direct` 映射,支持 Telegram 风格的群组 - 会话行为:`session.dmScope`、`historyLimit`、`dmHistoryLimit`、`dms..historyLimit` - 提示词:`groups..systemPrompt`、`groups["*"].systemPrompt`、`direct..systemPrompt`、`direct["*"].systemPrompt` -## 相关内容 +## 相关 - [配对](/zh-CN/channels/pairing) - [群组](/zh-CN/channels/groups) diff --git a/docs/zh-CN/channels/zalo.md b/docs/zh-CN/channels/zalo.md index bceccd461..4f6073fd4 100644 --- a/docs/zh-CN/channels/zalo.md +++ b/docs/zh-CN/channels/zalo.md @@ -1,35 +1,40 @@ --- read_when: - - 处理 Zalo 功能或 webhook 时 -summary: Zalo 机器人支持状态、功能和配置 + - 开发 Zalo 功能或网络钩子 +summary: Zalo 机器人支持状态、能力和配置 title: Zalo x-i18n: - generated_at: "2026-04-24T18:07:22Z" - model: gpt-5.4 + generated_at: "2026-04-29T05:39:09Z" + model: gpt-5.5 provider: openai - source_hash: e7eb9d5b1879fcdf70220c4b1542e843e47e12048ff567eeb0e1cb3367b3d200 + source_hash: e79a4a27accc7f460bd3ae9c01e8f5f80e21a285af5d89b94bb9c89244a4438f source_path: channels/zalo.md - workflow: 15 + workflow: 16 --- -状态:实验性。支持私信。下方的 [功能](#capabilities) 部分反映当前 Marketplace 机器人的行为。 +Status:实验性。支持私信。下面的 [能力](#capabilities) 部分反映当前 Marketplace 机器人行为。 ## 内置插件 -Zalo 在当前 OpenClaw 版本中作为内置插件提供,因此常规打包构建不需要单独安装。 +Zalo 在当前 OpenClaw 版本中作为内置插件提供,因此普通打包 +构建不需要单独安装。 -如果你使用的是较旧版本,或是不包含 Zalo 的自定义安装,请手动安装: +如果你使用的是旧版构建,或者排除了 Zalo 的自定义安装,请在发布后安装 +当前 npm 包: - 通过 CLI 安装:`openclaw plugins install @openclaw/zalo` - 或从源码检出安装:`openclaw plugins install ./path/to/local/zalo-plugin` -- 详情: [插件](/zh-CN/tools/plugin) +- 详情:[插件](/zh-CN/tools/plugin) -## 快速开始(新手) +如果 npm 报告 OpenClaw 拥有的包已弃用,请使用当前打包的 +OpenClaw 构建,或使用本地检出路径,直到发布更新的 npm 包。 + +## 快速设置(初学者) 1. 确保 Zalo 插件可用。 - - 当前打包的 OpenClaw 版本已内置该插件。 - - 较旧/自定义安装可使用上述命令手动添加。 -2. 设置令牌: + - 当前打包的 OpenClaw 版本已经内置它。 + - 旧版/自定义安装可以使用上面的命令手动添加。 +2. 设置 token: - 环境变量:`ZALO_BOT_TOKEN=...` - 或配置:`channels.zalo.accounts.default.botToken: "..."`。 3. 重启 Gateway 网关(或完成设置)。 @@ -55,26 +60,26 @@ Zalo 在当前 OpenClaw 版本中作为内置插件提供,因此常规打包 ## 它是什么 -Zalo 是一款面向越南市场的消息应用;它的 Bot API 允许 Gateway 网关运行一个机器人来处理 1:1 对话。 -如果你希望将回复稳定地路由回 Zalo,它很适合用于支持或通知场景。 +Zalo 是一款面向越南的即时通讯应用;它的 Bot API 让 Gateway 网关可以运行用于一对一对话的机器人。 +当你需要确定性地路由回 Zalo 来做支持或通知时,它很合适。 -本页反映当前 OpenClaw 对 **Zalo Bot Creator / Marketplace 机器人** 的行为。 -**Zalo Official Account(OA)机器人** 属于 Zalo 的另一种产品形态,行为可能不同。 +本页反映当前 OpenClaw 对 **Zalo Bot Creator / Marketplace 机器人**的行为。 +**Zalo Official Account (OA) 机器人**是 Zalo 的另一个产品表面,行为可能不同。 -- 由 Gateway 网关托管的 Zalo Bot API 渠道。 -- 确定性路由:回复会返回到 Zalo;模型不会选择渠道。 +- 由 Gateway 网关拥有的 Zalo Bot API 渠道。 +- 确定性路由:回复会回到 Zalo;模型永远不会选择渠道。 - 私信共享智能体的主会话。 -- 下方的 [功能](#capabilities) 部分展示当前对 Marketplace 机器人的支持情况。 +- 下面的 [能力](#capabilities) 部分展示当前 Marketplace 机器人支持情况。 ## 设置(快速路径) -### 1)创建机器人令牌(Zalo Bot Platform) +### 1. 创建机器人 token(Zalo Bot Platform) 1. 前往 [https://bot.zaloplatforms.com](https://bot.zaloplatforms.com) 并登录。 -2. 创建一个新机器人并配置其设置。 -3. 复制完整的机器人令牌(通常为 `numeric_id:secret`)。对于 Marketplace 机器人,可用的运行时令牌可能会在创建后出现在机器人的欢迎消息中。 +2. 创建新机器人并配置其设置。 +3. 复制完整的机器人 token(通常为 `numeric_id:secret`)。对于 Marketplace 机器人,可用的运行时 token 可能会在创建后的机器人欢迎消息中显示。 -### 2)配置令牌(环境变量或配置) +### 2. 配置 token(环境变量或配置) 示例: @@ -94,105 +99,105 @@ Zalo 是一款面向越南市场的消息应用;它的 Bot API 允许 Gateway } ``` -如果你之后迁移到支持群组的 Zalo 机器人产品形态,可以显式添加群组相关配置,例如 `groupPolicy` 和 `groupAllowFrom`。当前 Marketplace 机器人的行为请参见 [功能](#capabilities)。 +如果你之后迁移到可用群组的 Zalo 机器人表面,可以显式添加群组专用配置,例如 `groupPolicy` 和 `groupAllowFrom`。关于当前 Marketplace 机器人行为,请参阅 [能力](#capabilities)。 -环境变量方式:`ZALO_BOT_TOKEN=...`(仅适用于默认账户)。 +环境变量选项:`ZALO_BOT_TOKEN=...`(仅适用于默认账号)。 -多账户支持:使用 `channels.zalo.accounts` 配置每个账户的令牌以及可选的 `name`。 +多账号支持:使用 `channels.zalo.accounts`,为每个账号配置 token,并可选择配置 `name`。 -3. 重启 Gateway 网关。只要成功解析到令牌(环境变量或配置),Zalo 就会启动。 -4. 私信访问默认使用配对。首次联系机器人时请批准配对码。 +3. 重启 Gateway 网关。Zalo 会在解析到 token(环境变量或配置)后启动。 +4. 私信访问默认为配对。机器人首次被联系时批准代码。 ## 工作方式(行为) -- 入站消息会被规范化为共享的渠道信封格式,并附带媒体占位符。 -- 回复始终会路由回同一个 Zalo 聊天。 -- 默认使用长轮询;也支持通过 `channels.zalo.webhookUrl` 使用 webhook 模式。 +- 入站消息会被规范化为共享渠道信封,并带有媒体占位符。 +- 回复始终路由回同一个 Zalo 聊天。 +- 默认使用长轮询;可通过 `channels.zalo.webhookUrl` 使用 webhook 模式。 ## 限制 - 出站文本会按 2000 个字符分块(Zalo API 限制)。 - 媒体下载/上传受 `channels.zalo.mediaMaxMb` 限制(默认 5)。 -- 默认阻止流式传输,因为 2000 字符限制会让流式传输的实用性变低。 +- 由于 2000 字符限制会让流式传输不太有用,默认会阻止流式传输。 ## 访问控制(私信) ### 私信访问 -- 默认:`channels.zalo.dmPolicy = "pairing"`。未知发送者会收到一个配对码;在批准前,其消息会被忽略(配对码 1 小时后过期)。 -- 批准方式: +- 默认值:`channels.zalo.dmPolicy = "pairing"`。未知发送者会收到配对码;在批准之前消息会被忽略(代码 1 小时后过期)。 +- 通过以下方式批准: - `openclaw pairing list zalo` - `openclaw pairing approve zalo ` -- 配对是默认的令牌交换方式。详情: [配对](/zh-CN/channels/pairing) -- `channels.zalo.allowFrom` 接受数字用户 ID(不支持用户名查询)。 +- 配对是默认的 token 交换方式。详情:[配对](/zh-CN/channels/pairing) +- `channels.zalo.allowFrom` 接受数字用户 ID(没有用户名查找可用)。 ## 访问控制(群组) -对于 **Zalo Bot Creator / Marketplace 机器人**,群组支持在实践中不可用,因为机器人根本无法被添加到群组中。 +对于 **Zalo Bot Creator / Marketplace 机器人**,群组支持在实践中不可用,因为机器人根本无法被添加到群组。 -这意味着,下面这些群组相关配置键虽然存在于 schema 中,但对 Marketplace 机器人不可用: +这意味着下面的群组相关配置键存在于 schema 中,但 Marketplace 机器人无法使用: - `channels.zalo.groupPolicy` 控制群组入站处理:`open | allowlist | disabled`。 - `channels.zalo.groupAllowFrom` 限制哪些发送者 ID 可以在群组中触发机器人。 -- 如果未设置 `groupAllowFrom`,Zalo 会回退到使用 `allowFrom` 进行发送者检查。 -- 运行时说明:如果完全缺少 `channels.zalo`,运行时仍会出于安全考虑回退为 `groupPolicy="allowlist"`。 +- 如果未设置 `groupAllowFrom`,Zalo 会回退到 `allowFrom` 进行发送者检查。 +- 运行时说明:如果完全缺少 `channels.zalo`,运行时仍会为了安全回退到 `groupPolicy="allowlist"`。 -群组策略的取值(当你的机器人产品形态支持群组访问时)如下: +群组策略值(当你的机器人表面可用群组访问时)如下: - `groupPolicy: "disabled"` — 阻止所有群组消息。 -- `groupPolicy: "open"` — 允许任意群组成员(需要提及门控)。 -- `groupPolicy: "allowlist"` — 默认失败关闭;仅接受允许的发送者。 +- `groupPolicy: "open"` — 允许任意群组成员(受提及门控)。 +- `groupPolicy: "allowlist"` — 默认失败关闭;只接受已允许的发送者。 -如果你使用的是另一种 Zalo 机器人产品形态,并且已验证群组行为可用,请单独记录该行为,而不要假设它与 Marketplace 机器人的流程一致。 +如果你使用的是不同的 Zalo 机器人产品表面,并且已验证群组行为可用,请单独记录该行为,不要假设它与 Marketplace 机器人流程一致。 ## 长轮询与 webhook - 默认:长轮询(不需要公共 URL)。 -- webhook 模式:设置 `channels.zalo.webhookUrl` 和 `channels.zalo.webhookSecret`。 - - webhook 密钥长度必须为 8-256 个字符。 - - webhook URL 必须使用 HTTPS。 - - Zalo 会通过 `X-Bot-Api-Secret-Token` 请求头发送事件以供验证。 - - Gateway 网关 HTTP 会在 `channels.zalo.webhookPath` 处理 webhook 请求(默认使用 webhook URL 的路径)。 +- Webhook 模式:设置 `channels.zalo.webhookUrl` 和 `channels.zalo.webhookSecret`。 + - Webhook 密钥必须为 8-256 个字符。 + - Webhook URL 必须使用 HTTPS。 + - Zalo 会发送带有 `X-Bot-Api-Secret-Token` 标头的事件用于验证。 + - Gateway 网关 HTTP 在 `channels.zalo.webhookPath` 处理 webhook 请求(默认为 webhook URL 路径)。 - 请求必须使用 `Content-Type: application/json`(或 `+json` 媒体类型)。 - - 重复事件(`event_name + message_id`)会在短暂的重放窗口内被忽略。 + - 重复事件(`event_name + message_id`)会在较短的重放窗口内被忽略。 - 突发流量会按路径/来源进行速率限制,并可能返回 HTTP 429。 -**注意:** 根据 Zalo API 文档,getUpdates(轮询)与 webhook 每个 Zalo API 实例只能二选一。 +**注意:** 根据 Zalo API 文档,getUpdates(轮询)和 webhook 对每个 Zalo API 是互斥的。 ## 支持的消息类型 -如需快速查看支持情况,请参见 [功能](#capabilities)。下方说明补充了需要更多上下文的行为细节。 +如需快速查看支持情况,请参阅 [能力](#capabilities)。下面的说明会在行为需要额外上下文时补充细节。 -- **文本消息**:完全支持,按 2000 个字符分块。 -- **文本中的纯 URL**:行为与普通文本输入相同。 -- **链接预览 / 富链接卡片**:请参见 [功能](#capabilities) 中的 Marketplace 机器人状态;它们无法稳定触发回复。 -- **图片消息**:请参见 [功能](#capabilities) 中的 Marketplace 机器人状态;入站图片处理不稳定(会显示输入中指示,但没有最终回复)。 -- **贴纸**:请参见 [功能](#capabilities) 中的 Marketplace 机器人状态。 -- **语音消息 / 音频文件 / 视频 / 通用文件附件**:请参见 [功能](#capabilities) 中的 Marketplace 机器人状态。 -- **不支持的类型**:会被记录(例如,来自受保护用户的消息)。 +- **文本消息**:完全支持,并按 2000 个字符分块。 +- **文本中的普通 URL**:表现与普通文本输入相同。 +- **链接预览 / 富链接卡片**:请参阅 [能力](#capabilities) 中的 Marketplace 机器人状态;它们无法可靠触发回复。 +- **图片消息**:请参阅 [能力](#capabilities) 中的 Marketplace 机器人状态;入站图片处理不可靠(显示输入指示器但没有最终回复)。 +- **贴纸**:请参阅 [能力](#capabilities) 中的 Marketplace 机器人状态。 +- **语音便笺 / 音频文件 / 视频 / 通用文件附件**:请参阅 [能力](#capabilities) 中的 Marketplace 机器人状态。 +- **不支持的类型**:会记录日志(例如,来自受保护用户的消息)。 -## 功能 +## 能力 -下表汇总了 OpenClaw 中当前 **Zalo Bot Creator / Marketplace 机器人** 的行为。 +此表总结了当前 **Zalo Bot Creator / Marketplace 机器人**在 OpenClaw 中的行为。 -| 功能 | 状态 | +| 功能 | Status | | --------------------------- | --------------------------------------- | -| 私信 | ✅ 支持 | -| 群组 | ❌ Marketplace 机器人不可用 | -| 媒体(入站图片) | ⚠️ 有限 / 请在你的环境中验证 | -| 媒体(出站图片) | ⚠️ 尚未针对 Marketplace 机器人重新测试 | -| 文本中的纯 URL | ✅ 支持 | -| 链接预览 | ⚠️ 对 Marketplace 机器人不稳定 | -| 表情回应 | ❌ 不支持 | -| 贴纸 | ⚠️ Marketplace 机器人不会触发智能体回复 | -| 语音消息 / 音频 / 视频 | ⚠️ Marketplace 机器人不会触发智能体回复 | -| 文件附件 | ⚠️ Marketplace 机器人不会触发智能体回复 | -| 线程 | ❌ 不支持 | -| 投票 | ❌ 不支持 | -| 原生命令 | ❌ 不支持 | -| 流式传输 | ⚠️ 已阻止(2000 字符限制) | +| 直接消息 | ✅ 支持 | +| 群组 | ❌ Marketplace 机器人不可用 | +| 媒体(入站图片) | ⚠️ 有限 / 请在你的环境中验证 | +| 媒体(出站图片) | ⚠️ 尚未针对 Marketplace 机器人重新测试 | +| 文本中的普通 URL | ✅ 支持 | +| 链接预览 | ⚠️ 对 Marketplace 机器人不可靠 | +| 反应 | ❌ 不支持 | +| 贴纸 | ⚠️ Marketplace 机器人无智能体回复 | +| 语音便笺 / 音频 / 视频 | ⚠️ Marketplace 机器人无智能体回复 | +| 文件附件 | ⚠️ Marketplace 机器人无智能体回复 | +| 线程 | ❌ 不支持 | +| 投票 | ❌ 不支持 | +| 原生命令 | ❌ 不支持 | +| 流式传输 | ⚠️ 已阻止(2000 字符限制) | -## 传递目标(CLI/cron) +## 交付目标(CLI/cron) - 使用聊天 ID 作为目标。 - 示例:`openclaw message send --channel zalo --target 123456789 --message "hi"`。 @@ -201,57 +206,57 @@ Zalo 是一款面向越南市场的消息应用;它的 Bot API 允许 Gateway **机器人没有响应:** -- 检查令牌是否有效:`openclaw channels status --probe` -- 验证发送者是否已获批准(配对或 allowFrom) +- 检查 token 是否有效:`openclaw channels status --probe` +- 验证发送者已批准(配对或 allowFrom) - 检查 Gateway 网关日志:`openclaw logs --follow` -**Webhook 未接收到事件:** +**Webhook 未接收事件:** - 确保 webhook URL 使用 HTTPS -- 验证密钥令牌长度为 8-256 个字符 -- 确认 Gateway 网关 HTTP 端点可在配置路径上访问 -- 检查是否未运行 getUpdates 轮询(两者互斥) +- 验证密钥 token 为 8-256 个字符 +- 确认 Gateway 网关 HTTP 端点在配置的路径上可达 +- 检查 getUpdates 轮询没有运行(它们互斥) ## 配置参考(Zalo) -完整配置: [配置](/zh-CN/gateway/configuration) +完整配置:[配置](/zh-CN/gateway/configuration) -扁平的顶层键(`channels.zalo.botToken`、`channels.zalo.dmPolicy` 及类似项)属于旧版单账户简写。新配置建议优先使用 `channels.zalo.accounts..*`。两种形式在此仍然保留文档说明,因为它们存在于 schema 中。 +扁平的顶级键(`channels.zalo.botToken`、`channels.zalo.dmPolicy` 以及类似键)是旧版单账号简写。新配置请优先使用 `channels.zalo.accounts..*`。这里仍然记录两种形式,因为它们存在于 schema 中。 提供商选项: - `channels.zalo.enabled`:启用/禁用渠道启动。 -- `channels.zalo.botToken`:来自 Zalo Bot Platform 的机器人令牌。 -- `channels.zalo.tokenFile`:从常规文件路径读取令牌。不接受符号链接。 +- `channels.zalo.botToken`:来自 Zalo Bot Platform 的机器人 token。 +- `channels.zalo.tokenFile`:从常规文件路径读取 token。符号链接会被拒绝。 - `channels.zalo.dmPolicy`:`pairing | allowlist | open | disabled`(默认:pairing)。 -- `channels.zalo.allowFrom`:私信允许列表(用户 ID)。`open` 需要 `"*"`。向导会要求输入数字 ID。 -- `channels.zalo.groupPolicy`:`open | allowlist | disabled`(默认:allowlist)。配置中存在该项;当前 Marketplace 机器人的行为请参见 [功能](#capabilities) 和 [访问控制(群组)](#access-control-groups)。 -- `channels.zalo.groupAllowFrom`:群组发送者允许列表(用户 ID)。未设置时回退到 `allowFrom`。 -- `channels.zalo.mediaMaxMb`:入站/出站媒体大小上限(MB,默认 5)。 +- `channels.zalo.allowFrom`:私信 allowlist(用户 ID)。`open` 需要 `"*"`。向导会要求输入数字 ID。 +- `channels.zalo.groupPolicy`:`open | allowlist | disabled`(默认:allowlist)。存在于配置中;关于当前 Marketplace 机器人行为,请参阅 [能力](#capabilities) 和 [访问控制(群组)](#access-control-groups)。 +- `channels.zalo.groupAllowFrom`:群组发送者 allowlist(用户 ID)。未设置时回退到 `allowFrom`。 +- `channels.zalo.mediaMaxMb`:入站/出站媒体上限(MB,默认 5)。 - `channels.zalo.webhookUrl`:启用 webhook 模式(需要 HTTPS)。 - `channels.zalo.webhookSecret`:webhook 密钥(8-256 个字符)。 - `channels.zalo.webhookPath`:Gateway 网关 HTTP 服务器上的 webhook 路径。 -- `channels.zalo.proxy`:API 请求使用的代理 URL。 +- `channels.zalo.proxy`:API 请求的代理 URL。 -多账户选项: +多账号选项: -- `channels.zalo.accounts..botToken`:每账户令牌。 -- `channels.zalo.accounts..tokenFile`:每账户常规令牌文件。不接受符号链接。 +- `channels.zalo.accounts..botToken`:每账号 token。 +- `channels.zalo.accounts..tokenFile`:每账号常规 token 文件。符号链接会被拒绝。 - `channels.zalo.accounts..name`:显示名称。 -- `channels.zalo.accounts..enabled`:启用/禁用账户。 -- `channels.zalo.accounts..dmPolicy`:每账户私信策略。 -- `channels.zalo.accounts..allowFrom`:每账户允许列表。 -- `channels.zalo.accounts..groupPolicy`:每账户群组策略。配置中存在该项;当前 Marketplace 机器人的行为请参见 [功能](#capabilities) 和 [访问控制(群组)](#access-control-groups)。 -- `channels.zalo.accounts..groupAllowFrom`:每账户群组发送者允许列表。 -- `channels.zalo.accounts..webhookUrl`:每账户 webhook URL。 -- `channels.zalo.accounts..webhookSecret`:每账户 webhook 密钥。 -- `channels.zalo.accounts..webhookPath`:每账户 webhook 路径。 -- `channels.zalo.accounts..proxy`:每账户代理 URL。 +- `channels.zalo.accounts..enabled`:启用/禁用账号。 +- `channels.zalo.accounts..dmPolicy`:每账号私信策略。 +- `channels.zalo.accounts..allowFrom`:每账号 allowlist。 +- `channels.zalo.accounts..groupPolicy`:每账号群组策略。存在于配置中;关于当前 Marketplace 机器人行为,请参阅 [能力](#capabilities) 和 [访问控制(群组)](#access-control-groups)。 +- `channels.zalo.accounts..groupAllowFrom`:每账号群组发送者 allowlist。 +- `channels.zalo.accounts..webhookUrl`:每账号 webhook URL。 +- `channels.zalo.accounts..webhookSecret`:每账号 webhook 密钥。 +- `channels.zalo.accounts..webhookPath`:每账号 webhook 路径。 +- `channels.zalo.accounts..proxy`:每账号代理 URL。 -## 相关内容 +## 相关 - [渠道概览](/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/zalouser.md b/docs/zh-CN/channels/zalouser.md index 8663c7975..be1281f63 100644 --- a/docs/zh-CN/channels/zalouser.md +++ b/docs/zh-CN/channels/zalouser.md @@ -1,45 +1,50 @@ --- read_when: - - 为 OpenClaw 设置 Zalo 个人账号 - - 调试 Zalo 个人账号登录或消息流程 -summary: 通过原生 `zca-js` 提供的 Zalo 个人账号支持(QR 登录)、能力与配置 -title: Zalo 个人账号 + - 为 OpenClaw 设置 Zalo Personal + - 调试 Zalo Personal 登录或消息流程 +summary: Zalo 个人账号通过原生 zca-js(二维码登录)的支持、能力和配置 +title: Zalo 个人版 x-i18n: - generated_at: "2026-04-27T06:02:29Z" - model: gpt-5.4 + generated_at: "2026-04-29T05:39:20Z" + model: gpt-5.5 provider: openai - source_hash: eaa50ef95eb5c0d887e712e4d18c71068184df4cfe7d71ab5bbeb996c4789179 + source_hash: 581a427f7fa37b0fa204f6b813c767eaa7af1f577baf2ac6ea3a31bf23ca6a49 source_path: channels/zalouser.md - workflow: 15 + workflow: 16 --- -状态:实验性。此集成通过 OpenClaw 内部的原生 `zca-js` 自动化一个**Zalo 个人账号**。 +Status:实验性。此集成通过 OpenClaw 内部的原生 `zca-js` 自动化一个**个人 Zalo 账户**。 -这是一个非官方集成,可能导致账号被暂停或封禁。请自行承担风险。 +这是一个非官方集成,可能导致账户被暂停或封禁。风险自负。 ## 内置插件 -Zalo 个人账号作为内置插件随当前 OpenClaw 版本一同提供,因此常规打包构建无需单独安装。 +Zalo Personal 在当前 OpenClaw 版本中作为内置插件提供,因此普通的 +打包构建不需要单独安装。 -如果你使用的是较旧版本,或是不包含 Zalo 个人账号的自定义安装,请手动安装: +如果你使用的是较旧构建,或自定义安装排除了 Zalo Personal, +请在新的 npm 包发布后安装当前 npm 包: - 通过 CLI 安装:`openclaw plugins install @openclaw/zalouser` - 或从源码检出安装:`openclaw plugins install ./path/to/local/zalouser-plugin` -- 详情参见:[Plugins](/zh-CN/tools/plugin) +- 详情:[插件](/zh-CN/tools/plugin) + +如果 npm 报告 OpenClaw 拥有的包已弃用,请使用当前打包的 +OpenClaw 构建,或在较新的 npm 包发布前使用本地检出路径。 不需要外部 `zca`/`openzca` CLI 二进制文件。 -## 快速设置(新手) +## 快速设置(初学者) -1. 确保 Zalo 个人账号插件可用。 - - 当前打包的 OpenClaw 版本已内置该插件。 - - 较旧版本/自定义安装可使用上述命令手动添加。 -2. 登录(QR,在 Gateway 网关所在机器上): +1. 确保 Zalo Personal 插件可用。 + - 当前打包的 OpenClaw 版本已经内置它。 + - 较旧/自定义安装可以使用上面的命令手动添加它。 +2. 登录(QR,在 Gateway 网关机器上): - `openclaw channels login --channel zalouser` - 使用 Zalo 移动应用扫描二维码。 -3. 启用该渠道: +3. 启用渠道: ```json5 { @@ -53,22 +58,22 @@ Zalo 个人账号作为内置插件随当前 OpenClaw 版本一同提供,因 ``` 4. 重启 Gateway 网关(或完成设置)。 -5. 私信访问默认使用配对;首次联系时批准配对代码。 +5. 私信访问默认使用配对;首次联系时批准配对码。 ## 它是什么 - 完全通过 `zca-js` 在进程内运行。 - 使用原生事件监听器接收入站消息。 -- 通过 JS API 直接发送回复(文本/媒体/链接)。 -- 面向无法使用 Zalo Bot API 的“个人账号”使用场景而设计。 +- 直接通过 JS API 发送回复(文本/媒体/链接)。 +- 专为无法使用 Zalo Bot API 的“个人账户”用例设计。 ## 命名 -渠道 ID 为 `zalouser`,以明确表示这是对**Zalo 个人用户账号**(非官方)的自动化。我们保留 `zalo`,用于未来可能出现的官方 Zalo API 集成。 +渠道 ID 是 `zalouser`,用于明确表示这会自动化一个**个人 Zalo 用户账户**(非官方)。我们保留 `zalo`,用于未来可能的官方 Zalo API 集成。 ## 查找 ID(目录) -使用目录 CLI 发现联系人/群组及其 ID: +使用目录 CLI 发现对等方/群组及其 ID: ```bash openclaw directory self --channel zalouser @@ -78,34 +83,34 @@ openclaw directory groups list --channel zalouser --query "work" ## 限制 -- 出站文本会被分块到约 2000 个字符(Zalo 客户端限制)。 -- 默认禁用流式传输。 +- 出站文本会被分块为约 2000 个字符(Zalo 客户端限制)。 +- 默认阻止流式传输。 ## 访问控制(私信) -`channels.zalouser.dmPolicy` 支持:`pairing | allowlist | open | disabled`(默认:`pairing`)。 +`channels.zalouser.dmPolicy` 支持:`pairing | allowlist | open | disabled`(默认值:`pairing`)。 -`channels.zalouser.allowFrom` 可接受用户 ID 或名称。在设置期间,名称会通过插件的进程内联系人查找解析为 ID。 +`channels.zalouser.allowFrom` 接受用户 ID 或名称。设置期间,名称会使用插件的进程内联系人查找解析为 ID。 -批准方式: +通过以下方式批准: - `openclaw pairing list zalouser` - `openclaw pairing approve zalouser ` ## 群组访问(可选) -- 默认:`channels.zalouser.groupPolicy = "open"`(允许群组)。当未设置时,可使用 `channels.defaults.groupPolicy` 覆盖默认值。 -- 限制为允许列表: +- 默认值:`channels.zalouser.groupPolicy = "open"`(允许群组)。未设置时,使用 `channels.defaults.groupPolicy` 覆盖默认值。 +- 使用以下设置限制为允许列表: - `channels.zalouser.groupPolicy = "allowlist"` - - `channels.zalouser.groups`(键应为稳定的群组 ID;如有可能,名称会在启动时解析为 ID) - - `channels.zalouser.groupAllowFrom`(控制允许群组中哪些发送者可以触发机器人) + - `channels.zalouser.groups`(键应为稳定的群组 ID;启动时会尽可能将名称解析为 ID) + - `channels.zalouser.groupAllowFrom`(控制允许群组中的哪些发送者可以触发机器人) - 阻止所有群组:`channels.zalouser.groupPolicy = "disabled"`。 -- 配置向导可以提示你设置群组允许列表。 -- 启动时,OpenClaw 会将允许列表中的群组/用户名称解析为 ID,并记录映射关系。 -- 默认情况下,群组允许列表匹配仅基于 ID。未解析的名称会在鉴权时被忽略,除非启用 `channels.zalouser.dangerouslyAllowNameMatching: true`。 -- `channels.zalouser.dangerouslyAllowNameMatching: true` 是一个紧急兼容模式,会重新启用可变的群组名称匹配。 -- 如果未设置 `groupAllowFrom`,运行时会回退到 `allowFrom` 来执行群组发送者检查。 -- 发送者检查同时适用于普通群组消息和控制命令(例如 `/new`、`/reset`)。 +- 配置向导可以提示输入群组允许列表。 +- 启动时,OpenClaw 会将允许列表中的群组/用户名称解析为 ID,并记录映射。 +- 群组允许列表匹配默认仅按 ID。除非启用 `channels.zalouser.dangerouslyAllowNameMatching: true`,否则未解析的名称会在认证时被忽略。 +- `channels.zalouser.dangerouslyAllowNameMatching: true` 是一种应急兼容模式,会重新启用可变的群组名称匹配。 +- 如果未设置 `groupAllowFrom`,运行时会回退到 `allowFrom` 进行群组发送者检查。 +- 发送者检查同时适用于普通群组消息和控制命令(例如 `/new`)。 示例: @@ -127,12 +132,12 @@ openclaw directory groups list --channel zalouser --query "work" ### 群组提及门控 - `channels.zalouser.groups..requireMention` 控制群组回复是否需要提及。 -- 解析顺序:精确群组 id/名称 -> 规范化后的群组 slug -> `*` -> 默认值(`true`)。 +- 解析顺序:精确群组 ID/名称 -> 规范化群组 slug -> `*` -> 默认值(`true`)。 - 这同时适用于允许列表群组和开放群组模式。 -- 引用机器人消息会被视为用于激活群组的一种隐式提及。 +- 引用机器人消息会计为群组激活的隐式提及。 - 已授权的控制命令(例如 `/new`)可以绕过提及门控。 -- 当某条群组消息因需要提及而被跳过时,OpenClaw 会将其存储为待处理的群组历史,并在下一条被处理的群组消息中包含它。 -- 群组历史限制默认取自 `messages.groupChat.historyLimit`(回退值为 `50`)。你可以通过 `channels.zalouser.historyLimit` 按账号覆盖。 +- 当群组消息因需要提及而被跳过时,OpenClaw 会将其存储为待处理群组历史记录,并在下一条已处理的群组消息中包含它。 +- 群组历史记录限制默认为 `messages.groupChat.historyLimit`(回退值 `50`)。你可以使用 `channels.zalouser.historyLimit` 按账户覆盖。 示例: @@ -150,9 +155,9 @@ openclaw directory groups list --channel zalouser --query "work" } ``` -## 多账号 +## 多账户 -账号映射到 OpenClaw 状态中的 `zalouser` 配置文件。示例: +账户会映射到 OpenClaw 状态中的 `zalouser` 配置文件。示例: ```json5 { @@ -168,17 +173,17 @@ openclaw directory groups list --channel zalouser --query "work" } ``` -## 正在输入、反应和投递确认 +## 正在输入、反应和送达确认 -- OpenClaw 会在发送回复前先发送一个“正在输入”事件(尽力而为)。 -- 在渠道操作中,消息反应动作 `react` 支持 `zalouser`。 - - 使用 `remove: true` 可从消息中移除指定的反应表情符号。 - - 反应语义参见:[Reactions](/zh-CN/tools/reactions) -- 对于包含事件元数据的入站消息,OpenClaw 会发送 delivered + seen 确认(尽力而为)。 +- OpenClaw 会在分发回复前发送正在输入事件(尽力而为)。 +- 渠道操作中,`zalouser` 支持消息反应操作 `react`。 + - 使用 `remove: true` 可从消息中移除特定反应表情符号。 + - 反应语义:[反应](/zh-CN/tools/reactions) +- 对于包含事件元数据的入站消息,OpenClaw 会发送已送达 + 已读确认(尽力而为)。 ## 故障排除 -**登录无法保持:** +**登录未保持:** - `openclaw channels status --probe` - 重新登录:`openclaw channels logout --channel zalouser && openclaw channels login --channel zalouser` @@ -187,15 +192,15 @@ openclaw directory groups list --channel zalouser --query "work" - 在 `allowFrom`/`groupAllowFrom`/`groups` 中使用数字 ID,或使用精确的好友/群组名称。 -**从旧版基于 CLI 的设置升级:** +**从旧的基于 CLI 的设置升级:** -- 移除任何关于旧外部 `zca` 进程的假设。 -- 该渠道现在完全在 OpenClaw 内运行,不依赖外部 CLI 二进制文件。 +- 移除任何旧的外部 `zca` 进程假设。 +- 该渠道现在完全在 OpenClaw 中运行,不需要外部 CLI 二进制文件。 ## 相关内容 -- [Channels Overview](/zh-CN/channels) — 所有支持的渠道 -- [配对](/zh-CN/channels/pairing) — 私信认证与配对流程 -- [Groups](/zh-CN/channels/groups) — 群聊行为与提及门控 -- [Channel Routing](/zh-CN/channels/channel-routing) — 消息的会话路由 -- [安全](/zh-CN/gateway/security) — 访问模型与加固措施 +- [渠道概览](/zh-CN/channels) — 所有支持的渠道 +- [配对](/zh-CN/channels/pairing) — 私信认证和配对流程 +- [群组](/zh-CN/channels/groups) — 群聊行为和提及门控 +- [渠道路由](/zh-CN/channels/channel-routing) — 消息的会话路由 +- [安全](/zh-CN/gateway/security) — 访问模型和加固 diff --git a/docs/zh-CN/ci.md b/docs/zh-CN/ci.md index 67df81e0f..00e611d26 100644 --- a/docs/zh-CN/ci.md +++ b/docs/zh-CN/ci.md @@ -1,55 +1,55 @@ --- read_when: - - 你需要了解某个 CI 作业为何运行或未运行 + - 你需要了解 CI 作业为什么运行或没有运行 - 你正在调试失败的 GitHub Actions 检查 -summary: CI 作业图、范围门禁和本地命令等价项 +summary: CI 作业图、范围门禁和本地命令等效项 title: CI 流水线 x-i18n: - generated_at: "2026-04-29T04:54:25Z" + generated_at: "2026-04-29T05:39:22Z" model: gpt-5.5 provider: openai - source_hash: 5315d80962cfce8e894fca23fe0eaf74c5d1f30638612b50d329946c7a6b0fb0 + source_hash: 07839136693d9bfa72da1bb24a2839e0b249882795fa939dbc79a35436572b01 source_path: ci.md workflow: 16 --- -CI 在每次推送到 `main` 以及每个拉取请求时运行。它使用智能范围划分,在只有无关区域发生变更时跳过高成本作业。手动 `workflow_dispatch` 运行会有意绕过智能范围划分,并展开完整的常规 CI 图,用于发布候选版本或广泛验证。 +CI 会在每次推送到 `main` 和每个拉取请求时运行。它使用智能范围限定,在只有无关区域发生变化时跳过昂贵的作业。手动 `workflow_dispatch` 运行会有意绕过智能范围限定,并为候选发布版本或广泛验证展开完整的常规 CI 图。仅发布用的插件预发布通道保持关闭,除非 `Full Release Validation` 以 `full_release_validation=true` 调度 CI。 -`Full Release Validation` 是用于“发布前运行所有检查”的手动总控工作流。它接受分支、标签或完整提交 SHA,使用该目标分发手动 `CI` 工作流,并分发 `OpenClaw Release Checks`,用于安装冒烟、包验收、Docker 发布路径套件、live/E2E、OpenWebUI、QA Lab parity、Matrix 和 Telegram 通道。它也可以在提供已发布包规格时运行发布后的 `NPM Telegram Beta E2E` 工作流。`release_profile=minimum|stable|full` 控制传入发布检查的 live/provider 覆盖广度:`minimum` 保留最快的 OpenAI/核心发布关键通道,`stable` 添加稳定的提供商/后端集合,`full` 运行广泛的建议提供商/媒体矩阵。这个总控工作流会记录被分发的子运行 ID,最终的 `Verify full validation` 作业会重新检查当前子运行结论,并为每个子运行追加最慢作业表。如果某个子工作流被重新运行并变为绿色,只需重新运行父级验证器作业,以刷新总控结果和耗时摘要。 +`Full Release Validation` 是“发布前运行所有内容”的手动总括工作流。它接受分支、标签或完整提交 SHA,使用该目标调度手动 `CI` 工作流,并调度 `OpenClaw Release Checks` 来覆盖安装冒烟、包验收、Docker 发布路径套件、实时/E2E、OpenWebUI、QA Lab parity、Matrix 和 Telegram 通道。提供已发布的包规范时,它还可以运行发布后的 `NPM Telegram Beta E2E` 工作流。`release_profile=minimum|stable|full` 控制传入发布检查的实时/提供商覆盖范围:`minimum` 保留最快的 OpenAI/核心发布关键通道,`stable` 添加稳定的提供商/后端集合,`full` 运行广泛的建议提供商/媒体矩阵。总括工作流会记录已调度的子运行 ID,最终的 `Verify full validation` 作业会重新检查当前子运行结论,并为每个子运行附加最慢作业表。如果某个子工作流重新运行后转绿,只需重新运行父验证器作业,以刷新总括结果和耗时摘要。 -对于恢复,`Full Release Validation` 和 `OpenClaw Release Checks` 都接受 `rerun_group`。发布候选版本使用 `all`,只运行常规完整 CI 子项使用 `ci`,运行每个发布子项使用 `release-checks`,或在总控中使用更窄的发布组:`install-smoke`、`cross-os`、`live-e2e`、`package`、`qa`、`qa-parity`、`qa-live` 或 `npm-telegram`。这会让失败的发布箱在针对性修复后保持有界重跑。 +为了恢复,`Full Release Validation` 和 `OpenClaw Release Checks` 都接受 `rerun_group`。对候选发布版本使用 `all`,只重跑常规完整 CI 子项使用 `ci`,重跑每个发布子项使用 `release-checks`,或者在总括工作流上使用更窄的发布组:`install-smoke`、`cross-os`、`live-e2e`、`package`、`qa`、`qa-parity`、`qa-live` 或 `npm-telegram`。这样在进行聚焦修复后,可以把失败的发布环境重跑范围限制住。 -发布 live/E2E 子项保留广泛的原生 `pnpm test:live` 覆盖,但它通过 `scripts/test-live-shard.mjs` 将其作为命名分片运行(`native-live-src-agents`、`native-live-src-gateway-core`、按提供商过滤的 `native-live-src-gateway-profiles` 作业、`native-live-src-gateway-backends`、`native-live-test`、`native-live-extensions-a-k`、`native-live-extensions-l-n`、`native-live-extensions-openai`、`native-live-extensions-o-z-other`、`native-live-extensions-xai`、拆分的媒体音频/视频分片,以及按提供商过滤的音乐分片),而不是一个串行作业。这样在保持相同文件覆盖的同时,让缓慢的 live 提供商失败更容易重跑和诊断。聚合的 `native-live-extensions-o-z`、`native-live-extensions-media` 和 `native-live-extensions-media-music` 分片名称仍可用于手动一次性重跑。 +发布实时/E2E 子项保留广泛的原生 `pnpm test:live` 覆盖,但会通过 `scripts/test-live-shard.mjs` 作为命名分片运行(`native-live-src-agents`、`native-live-src-gateway-core`、按提供商过滤的 `native-live-src-gateway-profiles` 作业、`native-live-src-gateway-backends`、`native-live-test`、`native-live-extensions-a-k`、`native-live-extensions-l-n`、`native-live-extensions-openai`、`native-live-extensions-o-z-other`、`native-live-extensions-xai`、拆分后的媒体音频/视频分片,以及按提供商过滤的音乐分片),而不是一个串行作业。这样在保持相同文件覆盖的同时,也让慢速实时提供商失败更容易重跑和诊断。聚合的 `native-live-extensions-o-z`、`native-live-extensions-media` 和 `native-live-extensions-media-music` 分片名称仍可用于手动一次性重跑。 -原生 live 媒体分片运行在 `ghcr.io/openclaw/openclaw-live-media-runner:ubuntu-24.04` 中,该镜像由 `Live Media Runner Image` 工作流构建。该镜像预安装 `ffmpeg` 和 `ffprobe`;媒体作业只在设置前验证这些二进制文件。将基于 Docker 的 live 套件保留在常规 Blacksmith runner 上,因为容器作业并不适合启动嵌套 Docker 测试。 +原生实时媒体分片运行在 `ghcr.io/openclaw/openclaw-live-media-runner:ubuntu-24.04` 中,该镜像由 `Live Media Runner Image` 工作流构建。该镜像预安装 `ffmpeg` 和 `ffprobe`;媒体作业只会在设置前验证这些二进制文件。将 Docker 支撑的实时套件保留在常规 Blacksmith runner 上,因为容器作业不适合启动嵌套 Docker 测试。 -基于 Docker 的 live 模型/后端分片会为每个选定提交使用单独的共享 `ghcr.io/openclaw/openclaw-live-test:` 镜像。live 发布工作流会构建并推送该镜像一次,然后 Docker live 模型、Gateway 网关、CLI 后端、ACP 绑定和 Codex harness 分片会以 `OPENCLAW_SKIP_DOCKER_BUILD=1` 运行。如果这些分片独立重建完整源 Docker 目标,则发布运行配置错误,并会在重复镜像构建上浪费墙钟时间。 +Docker 支撑的实时模型/后端分片会为所选提交使用单独的共享 `ghcr.io/openclaw/openclaw-live-test:` 镜像。实时发布工作流会构建并推送该镜像一次,然后 Docker 实时模型、Gateway 网关、CLI 后端、ACP bind 和 Codex harness 分片会带着 `OPENCLAW_SKIP_DOCKER_BUILD=1` 运行。如果这些分片独立重建完整源代码 Docker 目标,则说明发布运行配置有误,并会把墙钟时间浪费在重复镜像构建上。 -`OpenClaw Release Checks` 使用受信任的工作流引用,将选定引用一次性解析为 `release-package-under-test` tarball,然后把该工件传给 live/E2E 发布路径 Docker 工作流和包验收分片。这样可以确保不同发布箱之间的包字节一致,并避免在多个子作业中重新打包同一个候选包。 +`OpenClaw Release Checks` 使用受信任的工作流 ref 将所选 ref 一次性解析为 `release-package-under-test` tarball,然后将该工件传给实时/E2E 发布路径 Docker 工作流和包验收分片。这会让发布环境之间的包字节保持一致,并避免在多个子作业中重新打包同一个候选版本。 -`Package Acceptance` 是用于验证包工件而不阻塞发布工作流的旁路运行工作流。它会从已发布 npm 规格、使用选定 `workflow_ref` harness 构建的受信任 `package_ref`、带 SHA-256 的 HTTPS tarball URL,或另一个 GitHub Actions 运行中的 tarball 工件解析一个候选包,将其上传为 `package-under-test`,然后使用该 tarball 复用 Docker 发布/E2E 调度器,而不是重新打包工作流 checkout。Profile 覆盖冒烟、包、产品、完整和自定义 Docker 通道选择。`package` profile 使用离线插件覆盖,因此已发布包验证不会受 live ClawHub 可用性约束。可选的 Telegram 通道会在 `NPM Telegram Beta E2E` 工作流中复用 `package-under-test` 工件,同时保留已发布 npm 规格路径用于独立分发。 +`Package Acceptance` 是用于验证包工件且不会阻塞发布工作流的旁路运行工作流。它会从已发布的 npm 规范、使用所选 `workflow_ref` harness 构建的受信任 `package_ref`、带 SHA-256 的 HTTPS tarball URL,或另一个 GitHub Actions 运行中的 tarball 工件解析一个候选包,将其上传为 `package-under-test`,然后复用 Docker 发布/E2E 调度器,以该 tarball 代替重新打包工作流 checkout。Profile 覆盖 smoke、package、product、full 和自定义 Docker 通道选择。`package` profile 使用离线插件覆盖,因此已发布包验证不会受实时 ClawHub 可用性阻塞。可选 Telegram 通道会在 `NPM Telegram Beta E2E` 工作流中复用 `package-under-test` 工件,同时保留已发布 npm 规范路径用于独立调度。 ## 包验收 -当问题是“这个可安装的 OpenClaw 包是否作为产品正常工作?”时,使用 `Package Acceptance`。它不同于常规 CI:常规 CI 验证源代码树,而包验收会通过用户在安装或更新后实际运行的同一个 Docker E2E harness 验证单个 tarball。 +当问题是“这个可安装的 OpenClaw 包是否能作为产品正常工作?”时,使用 `Package Acceptance`。它不同于常规 CI:常规 CI 验证源代码树,而包验收会通过用户安装或更新后实际使用的同一个 Docker E2E harness 验证单个 tarball。 该工作流有四个作业: -1. `resolve_package` 检出 `workflow_ref`,解析一个包候选,写入 `.artifacts/docker-e2e-package/openclaw-current.tgz`,写入 `.artifacts/docker-e2e-package/package-candidate.json`,将两者作为 `package-under-test` 工件上传,并在 GitHub 步骤摘要中打印来源、工作流引用、包引用、版本、SHA-256 和 profile。 -2. `docker_acceptance` 使用 `ref=workflow_ref` 和 `package_artifact_name=package-under-test` 调用 `openclaw-live-and-e2e-checks-reusable.yml`。可复用工作流会下载该工件,验证 tarball 清单,在需要时准备包摘要 Docker 镜像,并针对该包运行选定的 Docker 通道,而不是打包工作流 checkout。当某个 profile 选择多个目标 `docker_lanes` 时,可复用工作流会先准备一次包和共享镜像,然后将这些通道展开为并行的目标 Docker 作业,并使用唯一工件。 -3. `package_telegram` 可选地调用 `NPM Telegram Beta E2E`。当 `telegram_mode` 不是 `none` 时运行;如果 Package Acceptance 已解析出包,则安装同一个 `package-under-test` 工件;独立的 Telegram 分发仍可安装已发布的 npm 规格。 -4. `summary` 会在包解析、Docker 验收或可选 Telegram 通道失败时使工作流失败。 +1. `resolve_package` checkout `workflow_ref`,解析一个包候选项,写入 `.artifacts/docker-e2e-package/openclaw-current.tgz`,写入 `.artifacts/docker-e2e-package/package-candidate.json`,将两者作为 `package-under-test` 工件上传,并在 GitHub 步骤摘要中打印来源、工作流 ref、包 ref、版本、SHA-256 和 profile。 +2. `docker_acceptance` 使用 `ref=workflow_ref` 和 `package_artifact_name=package-under-test` 调用 `openclaw-live-and-e2e-checks-reusable.yml`。可复用工作流会下载该工件,验证 tarball 清单,在需要时准备 package-digest Docker 镜像,并针对该包运行所选 Docker 通道,而不是打包工作流 checkout。当某个 profile 选择多个目标 `docker_lanes` 时,可复用工作流会先准备一次包和共享镜像,然后将这些通道展开为并行目标 Docker 作业,并生成唯一工件。 +3. `package_telegram` 可选调用 `NPM Telegram Beta E2E`。当 `telegram_mode` 不是 `none` 时它会运行,并在 Package Acceptance 已解析包时安装同一个 `package-under-test` 工件;独立 Telegram 调度仍可安装已发布的 npm 规范。 +4. `summary` 会在包解析、Docker 验收或可选 Telegram 通道失败时让工作流失败。 候选来源: - `source=npm`:只接受 `openclaw@beta`、`openclaw@latest`,或精确的 OpenClaw 发布版本,例如 `openclaw@2026.4.27-beta.2`。用于已发布 beta/stable 验收。 -- `source=ref`:打包受信任的 `package_ref` 分支、标签或完整提交 SHA。解析器会获取 OpenClaw 分支/标签,验证选定提交可从仓库分支历史或发布标签到达,在分离 worktree 中安装依赖,并用 `scripts/package-openclaw-for-docker.mjs` 打包。 +- `source=ref`:打包受信任的 `package_ref` 分支、标签或完整提交 SHA。解析器会获取 OpenClaw 分支/标签,验证所选提交可从仓库分支历史或发布标签到达,在分离 worktree 中安装依赖,并用 `scripts/package-openclaw-for-docker.mjs` 打包。 - `source=url`:下载 HTTPS `.tgz`;必须提供 `package_sha256`。 -- `source=artifact`:从 `artifact_run_id` 和 `artifact_name` 下载一个 `.tgz`;`package_sha256` 可选,但对于外部共享工件应提供。 +- `source=artifact`:从 `artifact_run_id` 和 `artifact_name` 下载一个 `.tgz`;`package_sha256` 是可选项,但对于外部共享的工件应提供。 -保持 `workflow_ref` 和 `package_ref` 分离。`workflow_ref` 是运行测试的受信任工作流/harness 代码。`package_ref` 是在 `source=ref` 时被打包的源提交。这样当前测试 harness 可以验证较旧的受信任源提交,而不运行旧的工作流逻辑。 +保持 `workflow_ref` 和 `package_ref` 分离。`workflow_ref` 是运行测试的受信任工作流/harness 代码。`package_ref` 是在 `source=ref` 时被打包的源提交。这样当前测试 harness 可以验证较旧的受信任源提交,而无需运行旧的工作流逻辑。 -Profile 映射到 Docker 覆盖: +Profile 映射到 Docker 覆盖范围: - `smoke`:`npm-onboard-channel-agent`、`gateway-network`、`config-reload` - `package`:`npm-onboard-channel-agent`、`doctor-switch`、`update-channel-switch`、`bundled-channel-deps-compat`、`plugins-offline`、`plugin-update` @@ -57,10 +57,9 @@ Profile 映射到 Docker 覆盖: - `full`:带 OpenWebUI 的完整 Docker 发布路径分块 - `custom`:精确的 `docker_lanes`;当 `suite_profile=custom` 时必需 -发布检查会用 `source=ref`、`package_ref=`、`workflow_ref=`、`suite_profile=custom`、`docker_lanes='bundled-channel-deps-compat plugins-offline'` 和 `telegram_mode=mock-openai` 调用 Package Acceptance。发布路径 Docker 分块覆盖重叠的包/更新/插件通道,而 Package Acceptance 会针对同一个已解析包 tarball 保留工件原生的内置渠道兼容、离线插件和 Telegram 证明。 -跨 OS 发布检查仍覆盖 OS 特定的新手引导、安装器和平台行为;包/更新产品验证应从 Package Acceptance 开始。Windows 打包和安装器全新通道也会验证已安装包可以从原始绝对 Windows 路径导入 browser-control override。 +发布检查会以 `source=ref`、`package_ref=`、`workflow_ref=`、`suite_profile=custom`、`docker_lanes='bundled-channel-deps-compat plugins-offline'` 和 `telegram_mode=mock-openai` 调用 Package Acceptance。发布路径 Docker 分块覆盖重叠的包/更新/插件通道,而 Package Acceptance 保留针对同一个已解析包 tarball 的工件原生内置渠道兼容性、离线插件和 Telegram 证明。跨 OS 发布检查仍覆盖特定 OS 的新手引导、安装器和平台行为;包/更新产品验证应从 Package Acceptance 开始。Windows 打包和安装器全新安装通道还会验证已安装包可以从原始绝对 Windows 路径导入 browser-control override。 -Package Acceptance 对已发布包有有界的旧版兼容窗口。到 `2026.4.25` 为止的包,包括 `2026.4.25-beta.*`,可以对 `dist/postinstall-inventory.json` 中指向 tarball 省略文件的已知私有 QA 条目使用兼容路径;当包未暴露该标志时,`doctor-switch` 可以跳过 `gateway install --wrapper` 持久化子用例;`update-channel-switch` 可以从 tarball 派生的 fake git fixture 中修剪缺失的 `pnpm.patchedDependencies`,并可以记录缺失的持久化 `update.channel`;插件冒烟可以读取旧版安装记录位置,或接受缺失的 marketplace 安装记录持久化;`plugin-update` 可以允许配置元数据迁移,同时仍要求安装记录和不重新安装行为保持不变。已发布的 `2026.4.26` 包也可以对已发布的本地构建元数据标记文件发出警告。后续包必须满足现代契约;相同条件会失败,而不是警告或跳过。 +Package Acceptance 对已经发布的包有有限的旧版兼容窗口。到 `2026.4.25` 为止的包,包括 `2026.4.25-beta.*`,可以对 `dist/postinstall-inventory.json` 中指向 tarball 省略文件的已知私有 QA 条目使用兼容路径;当包未暴露 `gateway install --wrapper` 标志时,`doctor-switch` 可以跳过该持久化子用例;`update-channel-switch` 可以从 tarball 派生的假 git fixture 中裁剪缺失的 `pnpm.patchedDependencies`,并可以记录缺失的持久化 `update.channel`;插件冒烟可以读取旧版安装记录位置,或接受缺失的 marketplace 安装记录持久化;`plugin-update` 可以允许配置元数据迁移,同时仍要求安装记录和不重装行为保持不变。已发布的 `2026.4.26` 包也可以对已经发布出去的本地构建元数据戳文件发出警告。之后的包必须满足现代契约;相同条件会失败,而不是警告或跳过。 示例: @@ -103,24 +102,24 @@ gh workflow run package-acceptance.yml \ -f docker_lanes='install-e2e plugin-update' ``` -调试失败的包验收运行时,先从 `resolve_package` 摘要开始,确认包来源、版本和 SHA-256。然后检查 `docker_acceptance` 子运行及其 Docker 工件:`.artifacts/docker-tests/**/summary.json`、`failures.json`、通道日志、阶段耗时和重跑命令。优先重跑失败的包 profile 或精确 Docker 通道,而不是重跑完整发布验证。 +调试失败的包验收运行时,从 `resolve_package` 摘要开始,确认包来源、版本和 SHA-256。然后检查 `docker_acceptance` 子运行及其 Docker 工件:`.artifacts/docker-tests/**/summary.json`、`failures.json`、通道日志、阶段耗时和重跑命令。优先重跑失败的包 profile 或精确 Docker 通道,而不是重跑完整发布验证。 -QA Lab 在主智能范围工作流之外有专用 CI 通道。`Parity gate` 工作流会在匹配的 PR 变更和手动调度时运行;它会构建私有 QA 运行时,并比较模拟 GPT-5.5 和 Opus 4.6 智能体包。`QA-Lab - All Lanes` 工作流每晚在 `main` 上运行,也可手动调度;它会将模拟 parity gate、实时 Matrix 通道,以及实时 Telegram 和 Discord 通道作为并行作业展开。实时作业使用 `qa-live-shared` 环境,Telegram/Discord 使用 Convex 租约。发布检查会使用确定性的模拟提供商和符合模拟条件的模型(`mock-openai/gpt-5.5` 和 `mock-openai/gpt-5.5-alt`)运行 Matrix 和 Telegram 实时传输通道,因此渠道契约会与实时模型延迟和常规提供商插件启动隔离。实时传输 Gateway 网关还会禁用记忆搜索,因为 QA parity 会单独覆盖记忆行为;提供商连通性由单独的实时模型、原生提供商和 Docker 提供商套件覆盖。Matrix 会对计划任务和发布门禁使用 `--profile fast`,仅在检出的 CLI 支持时才添加 `--fail-fast`。CLI 默认值和手动工作流输入仍为 `all`;手动 `matrix_profile=all` 调度始终会将完整 Matrix 覆盖分片为 `transport`、`media`、`e2ee-smoke`、`e2ee-deep` 和 `e2ee-cli` 作业。`OpenClaw Release Checks` 还会在发布批准前运行发布关键的 QA Lab 通道;其 QA parity gate 会将候选包和基线包作为并行通道作业运行,然后将两个产物下载到一个小型报告作业中,以进行最终 parity 比较。 -除非变更确实触及 QA 运行时、模型包 parity,或 parity 工作流拥有的表面,否则不要把 PR 落地路径放在 `Parity gate` 后面。对于普通渠道、配置、文档或单元测试修复,请将它视为可选信号,并改为遵循范围化 CI/检查证据。 +QA Lab 在主智能范围工作流之外有专用的 CI 通道。`Parity gate` 工作流会在匹配的 PR 变更和手动派发时运行;它会构建私有 QA 运行时,并比较模拟 GPT-5.5 和 Opus 4.6 智能体包。`QA-Lab - All Lanes` 工作流每晚在 `main` 上运行,也可手动派发;它会将模拟奇偶校验门、实时 Matrix 通道,以及实时 Telegram 和 Discord 通道展开为并行作业。实时作业使用 `qa-live-shared` 环境,Telegram/Discord 使用 Convex 租约。发布检查会使用确定性的模拟提供商和模拟限定模型(`mock-openai/gpt-5.5` 和 `mock-openai/gpt-5.5-alt`)运行 Matrix 和 Telegram 实时传输通道,从而将渠道契约与实时模型延迟和正常提供商插件启动隔离开。实时传输 Gateway 网关还会禁用内存搜索,因为 QA 奇偶校验会单独覆盖内存行为;提供商连通性由单独的实时模型、原生提供商和 Docker 提供商套件覆盖。Matrix 会对计划任务和发布门使用 `--profile fast`,仅在检出的 CLI 支持时添加 `--fail-fast`。CLI 默认值和手动工作流输入仍为 `all`;手动 `matrix_profile=all` 派发始终会将完整 Matrix 覆盖分片为 `transport`、`media`、`e2ee-smoke`、`e2ee-deep` 和 `e2ee-cli` 作业。`OpenClaw Release Checks` 也会在发布批准前运行发布关键的 QA Lab 通道;其 QA 奇偶校验门会将候选包和基线包作为并行通道作业运行,然后把两个工件下载到一个小型报告作业中,以执行最终奇偶校验比较。 +除非变更确实触及 QA 运行时、模型包奇偶校验,或奇偶校验工作流拥有的表面,否则不要把 PR 落地路径放在 `Parity gate` 后面。对于普通的渠道、配置、文档或单元测试修复,应将其视为可选信号,并遵循范围化 CI/检查证据。 -`Duplicate PRs After Merge` 工作流是一个用于落地后重复项清理的手动维护者工作流。它默认 dry-run,并且仅在 `apply=true` 时关闭显式列出的 PR。在修改 GitHub 前,它会验证已落地 PR 已合并,并且每个重复项都拥有共享引用的 issue 或重叠的变更 hunk。 +`Duplicate PRs After Merge` 工作流是一个手动维护者工作流,用于落地后的重复项清理。它默认 dry-run,只有在 `apply=true` 时才会关闭明确列出的 PR。在变更 GitHub 之前,它会验证已落地 PR 已合并,并且每个重复项要么共享引用的问题,要么有重叠的变更 hunks。 -`CodeQL` 工作流有意作为窄范围的一遍式安全扫描器,而不是完整仓库扫描。每日和手动运行会使用高精度安全查询扫描 Actions 工作流代码,以及风险最高的 JavaScript/TypeScript 凭证、机密、沙箱、cron 和 Gateway 网关表面。channel-runtime-boundary 作业会在 `/codeql-critical-security/channel-runtime-boundary` 类别下单独扫描核心渠道实现契约,以及渠道插件运行时、Gateway 网关、插件 SDK、机密和审计触点,因此渠道安全信号可以在不扩大基线 JS/TS 类别的情况下扩展。 +`CodeQL` 工作流有意作为窄范围的第一轮安全扫描器,而不是完整仓库扫描。每日和手动运行会使用高精度安全查询扫描 Actions 工作流代码,以及风险最高的 JavaScript/TypeScript 凭证、密钥、沙箱、cron 和 Gateway 网关表面。channel-runtime-boundary 作业会在 `/codeql-critical-security/channel-runtime-boundary` 类别下单独扫描核心渠道实现契约,以及渠道插件运行时、Gateway 网关、插件 SDK、密钥和审计接触点,这样渠道安全信号就能扩展,而无需扩大基线 JS/TS 类别。 -`CodeQL Android Critical Security` 工作流是计划运行的 Android 安全分片。它会在 workflow sanity 接受的最小 Blacksmith Linux runner 标签上,为 CodeQL 手动构建 Android 应用,并在 `/codeql-critical-security/android` 类别下上传结果。 +`CodeQL Android Critical Security` 工作流是计划运行的 Android 安全分片。它会在工作流完整性检查接受的最小 Blacksmith Linux runner 标签上为 CodeQL 手动构建 Android 应用,并在 `/codeql-critical-security/android` 类别下上传结果。 -`CodeQL macOS Critical Security` 工作流是每周/手动 macOS 安全分片。它会在 Blacksmith macOS 上为 CodeQL 手动构建 macOS 应用,从上传的 SARIF 中过滤掉依赖构建结果,并在 `/codeql-critical-security/macos` 类别下上传结果。请将它保留在每日默认工作流之外,因为即使结果干净,macOS 构建也会主导运行时间。 +`CodeQL macOS Critical Security` 工作流是每周/手动 macOS 安全分片。它会在 Blacksmith macOS 上为 CodeQL 手动构建 macOS 应用,从上传的 SARIF 中过滤掉依赖构建结果,并在 `/codeql-critical-security/macos` 类别下上传结果。保持它在每日默认工作流之外,因为即使干净通过,macOS 构建也会主导运行时间。 -`CodeQL Critical Quality` 工作流是对应的非安全分片。它只在较小的 Blacksmith Linux runner 上,对窄范围的高价值表面运行错误级别、非安全 JavaScript/TypeScript 质量查询。其基线作业扫描与安全工作流相同的凭证、机密、沙箱、cron 和 Gateway 网关表面。config-boundary 作业会在单独的 `/codeql-critical-quality/config-boundary` 类别下扫描配置 schema、迁移、规范化和 IO 契约。gateway-runtime-boundary 作业会在单独的 `/codeql-critical-quality/gateway-runtime-boundary` 类别下扫描 Gateway 网关协议 schema 和服务端方法契约。channel-runtime-boundary 作业会在单独的 `/codeql-critical-quality/channel-runtime-boundary` 类别下扫描核心渠道实现契约。agent-runtime-boundary 作业会在单独的 `/codeql-critical-quality/agent-runtime-boundary` 类别下扫描命令执行、模型/提供商调度、自动回复调度与队列,以及 ACP 控制平面运行时契约。ui-control-plane 作业会在单独的 `/codeql-critical-quality/ui-control-plane` 类别下扫描 Control UI 启动、本地持久化、Gateway 网关控制流,以及任务控制平面运行时契约。plugin-boundary 作业会在单独的 `/codeql-critical-quality/plugin-boundary` 类别下扫描加载器、注册表、公共表面和插件 SDK 入口点契约。请将该工作流与安全工作流分开,以便质量发现可以被计划、度量、禁用或扩展,而不会遮蔽安全信号。Swift、Python 和内置插件 CodeQL 扩展应仅在窄范围配置文件具备稳定运行时和信号后,作为范围化或分片的后续工作重新添加。 +`CodeQL Critical Quality` 工作流是匹配的非安全分片。它只在较小的 Blacksmith Linux runner 上,对窄范围高价值表面运行错误严重级别、非安全 JavaScript/TypeScript 质量查询。它的基线作业扫描与安全工作流相同的凭证、密钥、沙箱、cron 和 Gateway 网关表面。config-boundary 作业在单独的 `/codeql-critical-quality/config-boundary` 类别下扫描配置 schema、迁移、规范化和 IO 契约。gateway-runtime-boundary 作业在单独的 `/codeql-critical-quality/gateway-runtime-boundary` 类别下扫描 Gateway 网关协议 schema 和服务器方法契约。channel-runtime-boundary 作业在单独的 `/codeql-critical-quality/channel-runtime-boundary` 类别下扫描核心渠道实现契约。agent-runtime-boundary 作业在单独的 `/codeql-critical-quality/agent-runtime-boundary` 类别下扫描命令执行、模型/提供商分发、自动回复分发和队列,以及 ACP 控制平面运行时契约。ui-control-plane 作业在单独的 `/codeql-critical-quality/ui-control-plane` 类别下扫描 Control UI 引导、本地持久化、Gateway 网关控制流和任务控制平面运行时契约。web-media-runtime-boundary 作业在单独的 `/codeql-critical-quality/web-media-runtime-boundary` 类别下扫描核心网页抓取/搜索、媒体 IO、媒体理解、图像生成和媒体生成运行时契约。plugin-boundary 作业在单独的 `/codeql-critical-quality/plugin-boundary` 类别下扫描加载器、注册表、公共表面和插件 SDK 入口点契约。保持该工作流与安全工作流分离,这样质量发现就可以被计划运行、度量、禁用或扩展,而不会掩盖安全信号。Swift、Python 和内置插件的 CodeQL 扩展应只在窄范围配置文件拥有稳定运行时间和信号之后,作为范围化或分片的后续工作加回。 -`Docs Agent` 工作流是一个事件驱动的 Codex 维护通道,用于让现有文档与最近落地的变更保持一致。它没有纯计划任务:`main` 上成功的非 bot push CI 运行可以触发它,手动调度也可以直接运行它。当 `main` 已前进,或最近一小时内已创建另一个未跳过的 Docs Agent 运行时,workflow-run 调用会跳过。运行时,它会审查从上一个未跳过 Docs Agent 源 SHA 到当前 `main` 的提交范围,因此每小时一次的运行可以覆盖自上次文档处理以来累计的所有 main 变更。 +`Docs Agent` 工作流是事件驱动的 Codex 维护通道,用于让现有文档与最近落地的变更保持一致。它没有纯计划任务:`main` 上成功的非机器人 push CI 运行可以触发它,手动派发也可以直接运行它。当 `main` 已经前移,或过去一小时内已创建另一个未跳过的 Docs Agent 运行时,workflow-run 调用会跳过。运行时,它会审查从上一个未跳过 Docs Agent 源 SHA 到当前 `main` 的提交范围,因此一次每小时运行可以覆盖自上次文档处理以来累积的所有 main 变更。 -`Test Performance Agent` 工作流是一个事件驱动的 Codex 维护通道,用于慢测试。它没有纯计划任务:`main` 上成功的非 bot push CI 运行可以触发它,但如果当天 UTC 已有另一个 workflow-run 调用运行过或正在运行,它会跳过。手动调度会绕过该每日活动门禁。该通道会构建全套分组 Vitest 性能报告,让 Codex 只进行小型、保持覆盖率的测试性能修复,而不是大范围重构,然后重新运行全套报告,并拒绝会降低通过基线测试数量的变更。如果基线存在失败测试,Codex 只能修复明显失败,并且 after-agent 全套报告必须通过后才能提交任何内容。当 `main` 在 bot push 落地前前进时,该通道会 rebase 已验证补丁,重新运行 `pnpm check:changed`,并重试 push;存在冲突的过期补丁会被跳过。它使用 GitHub 托管的 Ubuntu,因此 Codex action 可以保持与 docs agent 相同的 drop-sudo 安全姿态。 +`Test Performance Agent` 工作流是事件驱动的 Codex 维护通道,用于慢测试。它没有纯计划任务:`main` 上成功的非机器人 push CI 运行可以触发它,但如果当天 UTC 已经有另一个 workflow-run 调用运行过或正在运行,它会跳过。手动派发会绕过该每日活动门。该通道会构建完整套件分组 Vitest 性能报告,让 Codex 只进行小型、保留覆盖率的测试性能修复,而不是大范围重构,然后重新运行完整套件报告,并拒绝会降低通过基线测试数量的变更。如果基线有失败测试,Codex 只能修复明显失败项,并且 agent 之后的完整套件报告必须通过,才能提交任何内容。当 `main` 在机器人 push 落地前前移时,该通道会 rebase 已验证补丁,重新运行 `pnpm check:changed`,并重试 push;有冲突的陈旧补丁会被跳过。它使用 GitHub 托管的 Ubuntu,因此 Codex action 可以保持与 docs agent 相同的 drop-sudo 安全姿态。 ```bash gh workflow run duplicate-after-merge.yml \ @@ -133,30 +132,30 @@ gh workflow run duplicate-after-merge.yml \ | 作业 | 目的 | 运行时机 | | -------------------------------- | -------------------------------------------------------------------------------------------- | ---------------------------------- | -| `preflight` | 检测仅文档变更、变更范围、变更插件,并构建 CI manifest | 始终在非草稿 push 和 PR 上运行 | +| `preflight` | 检测仅文档变更、变更范围、变更插件,并构建 CI 清单 | 始终在非草稿 push 和 PR 上运行 | | `security-scm-fast` | 通过 `zizmor` 进行私钥检测和工作流审计 | 始终在非草稿 push 和 PR 上运行 | | `security-dependency-audit` | 针对 npm advisories 执行无依赖的生产 lockfile 审计 | 始终在非草稿 push 和 PR 上运行 | -| `security-fast` | 快速安全作业的必需聚合作业 | 始终在非草稿 push 和 PR 上运行 | -| `build-artifacts` | 构建 `dist/`、Control UI、构建产物检查,以及可复用下游产物 | Node 相关变更 | +| `security-fast` | 快速安全作业的必需聚合项 | 始终在非草稿 push 和 PR 上运行 | +| `build-artifacts` | 构建 `dist/`、Control UI、构建工件检查,以及可复用下游工件 | Node 相关变更 | | `checks-fast-core` | 快速 Linux 正确性通道,例如内置/插件契约/协议检查 | Node 相关变更 | -| `checks-fast-contracts-channels` | 分片的渠道契约检查,并提供稳定的聚合检查结果 | Node 相关变更 | -| `checks-node-extensions` | 覆盖插件套件的完整内置插件测试分片 | Node 相关变更 | +| `checks-fast-contracts-channels` | 分片渠道契约检查,并提供稳定的聚合检查结果 | Node 相关变更 | +| `checks-node-extensions` | 跨插件套件的完整内置插件测试分片 | Node 相关变更 | | `checks-node-core-test` | 核心 Node 测试分片,不包括渠道、内置、契约和插件通道 | Node 相关变更 | -| `check` | 分片的主本地门禁等价项:生产类型、lint、guard、测试类型和严格 smoke | Node 相关变更 | -| `check-additional` | 架构、边界、插件表面 guard、包边界和 gateway-watch 分片 | Node 相关变更 | -| `build-smoke` | 已构建 CLI smoke 测试和 startup-memory smoke | Node 相关变更 | -| `checks` | 已构建产物渠道测试的验证器 | Node 相关变更 | -| `checks-node-compat-node22` | Node 22 兼容性构建和 smoke 通道 | 发布的手动 CI 调度 | -| `plugin-prerelease-suite` | 插件预发布静态检查和 Docker 产品通道的聚合作业 | 发布的手动 CI 调度 | -| `check-docs` | 文档格式化、lint 和断链检查 | 文档已变更 | -| `skills-python` | Python 支持的 Skills 的 Ruff + pytest | Python-skill 相关变更 | -| `checks-windows` | Windows 特定的进程/路径测试,以及共享运行时 import specifier 回归 | Windows 相关变更 | -| `macos-node` | 使用共享构建产物的 macOS TypeScript 测试通道 | macOS 相关变更 | +| `check` | 分片后的主本地门等价项:生产类型、lint、守卫、测试类型和严格 smoke | Node 相关变更 | +| `check-additional` | 架构、边界、插件表面守卫、包边界和 gateway-watch 分片 | Node 相关变更 | +| `build-smoke` | 已构建 CLI smoke 测试和启动内存 smoke | Node 相关变更 | +| `checks` | 已构建工件渠道测试的验证器 | Node 相关变更 | +| `checks-node-compat-node22` | Node 22 兼容性构建和 smoke 通道 | 发布的手动 CI 派发 | +| `plugin-prerelease-suite` | 插件预发布静态检查和 Docker 产品通道的聚合项 | Full Release Validation CI 子项 | +| `check-docs` | 文档格式、lint 和断链检查 | 文档已变更 | +| `skills-python` | Python 支持的 Skills 的 Ruff + pytest | Python 技能相关变更 | +| `checks-windows` | Windows 特定进程/路径测试,以及共享运行时导入说明符回归 | Windows 相关变更 | +| `macos-node` | 使用共享构建工件的 macOS TypeScript 测试通道 | macOS 相关变更 | | `macos-swift` | macOS 应用的 Swift lint、构建和测试 | macOS 相关变更 | -| `android` | 两种 flavor 的 Android 单元测试,以及一次 debug APK 构建 | Android 相关变更 | -| `test-performance-agent` | 受信任活动后的每日 Codex 慢测试优化 | Main CI 成功或手动调度 | +| `android` | 两种 flavor 的 Android 单元测试,加一个 debug APK 构建 | Android 相关变更 | +| `test-performance-agent` | 受信任活动后每日 Codex 慢测试优化 | Main CI 成功或手动派发 | -手动 CI 调度会运行与常规 CI 相同的作业图,但会强制开启每个范围化通道:Linux Node 分片、内置插件分片、渠道契约、Node 22 兼容性、插件预发布覆盖、`check`、`check-additional`、构建 smoke、文档检查、Python Skills、Windows、macOS、Android 和 Control UI i18n。手动运行使用唯一的并发组,因此 release-candidate 全套不会被同一 ref 上的另一个 push 或 PR 运行取消。可选的 `target_ref` 输入允许受信任调用方在使用所选调度 ref 的工作流文件时,针对分支、tag 或完整提交 SHA 运行该作业图。 +手动 CI 调度运行与普通 CI 相同的作业图,但会强制开启每个范围化检查通道:Linux Node 分片、内置插件分片、渠道契约、Node 22 兼容性、`check`、`check-additional`、构建冒烟、文档检查、Python Skills、Windows、macOS、Android,以及 Control UI i18n。插件预发布套件会从独立手动 CI 中排除,只有完整发布总控流程通过 `full_release_validation=true` 时才会启用。手动运行使用唯一的并发组,因此发布候选完整套件不会被同一 ref 上的另一次推送或 PR 运行取消。可选的 `target_ref` 输入允许受信任的调用方使用所选调度 ref 中的工作流文件,针对分支、标签或完整提交 SHA 运行该作业图。 ```bash gh workflow run ci.yml --ref release/YYYY.M.D @@ -164,49 +163,65 @@ gh workflow run ci.yml --ref main -f target_ref= gh workflow run full-release-validation.yml --ref main -f ref= ``` -## Fail-fast 顺序 +## 快速失败顺序 -任务的排序会让低成本检查先失败,避免昂贵任务继续运行: +作业按顺序排列,让低成本检查先于高成本检查失败: -1. `preflight` 决定哪些通道实际存在。`docs-scope` 和 `changed-scope` 逻辑是该任务中的步骤,而不是独立任务。 -2. `security-scm-fast`、`security-dependency-audit`、`security-fast`、`check`、`check-additional`、`check-docs` 和 `skills-python` 会快速失败,而不等待更重的制品和平台矩阵任务。 -3. `build-artifacts` 会与快速 Linux 通道重叠运行,这样共享构建就绪后,下游使用方可以立即开始。 -4. 更重的平台和运行时通道随后展开:`checks-fast-core`、`checks-fast-contracts-channels`、`checks-node-extensions`、`checks-node-core-test`、`checks`、`checks-windows`、`macos-node`、`macos-swift` 和 `android`。 +1. `preflight` 决定哪些检查通道实际存在。`docs-scope` 和 `changed-scope` 逻辑是此作业内的步骤,不是独立作业。 +2. `security-scm-fast`、`security-dependency-audit`、`security-fast`、`check`、`check-additional`、`check-docs` 和 `skills-python` 会快速失败,而不等待更重的产物和平台矩阵作业。 +3. `build-artifacts` 会与快速 Linux 检查通道重叠运行,使下游消费者能在共享构建就绪后立即开始。 +4. 更重的平台和运行时检查通道随后展开:`checks-fast-core`、`checks-fast-contracts-channels`、`checks-node-extensions`、`checks-node-core-test`、`checks`、`checks-windows`、`macos-node`、`macos-swift` 和 `android`。 范围逻辑位于 `scripts/ci-changed-scope.mjs`,并由 `src/scripts/ci-changed-scope.test.ts` 中的单元测试覆盖。 -手动触发会跳过变更范围检测,并让预检清单表现为每个受范围控制的区域都已变更。 -CI 工作流编辑会验证 Node CI 图以及工作流 lint 检查,但不会仅凭自身强制运行 Windows、Android 或 macOS 原生构建;这些平台通道仍然只针对平台源码变更启用。 -仅 CI 路由的编辑、选定的低成本核心测试夹具编辑,以及范围很窄的插件契约辅助代码/测试路由编辑,会使用快速的仅 Node 清单路径:预检、安全检查,以及单个 `checks-fast-core` 任务。当变更文件仅限于快速任务会直接执行的路由或辅助代码表面时,该路径会避开构建制品、Node 22 兼容性、渠道契约、完整核心分片、内置插件分片,以及额外的防护矩阵。 -Windows Node 检查的范围限定为 Windows 专用的进程/路径封装、npm/pnpm/UI 运行器辅助代码、包管理器配置,以及执行该通道的 CI 工作流表面;无关源码、插件、安装冒烟和仅测试变更会留在 Linux Node 通道上,因此不会为已经由常规测试分片覆盖的内容预留 16-vCPU Windows 工作器。 -独立的 `install-smoke` 工作流会通过自己的 `preflight` 任务复用同一个范围脚本。它将冒烟覆盖拆分为 `run_fast_install_smoke` 和 `run_full_install_smoke`。拉取请求会针对 Docker/包表面、内置插件包/清单变更,以及 Docker 冒烟任务会执行的核心插件/渠道/Gateway 网关/插件 SDK 表面运行快速路径。仅源码的内置插件变更、仅测试编辑和仅文档编辑不会预留 Docker 工作器。快速路径会构建一次根 Dockerfile 镜像,检查 CLI,运行智能体删除共享工作区 CLI 冒烟,运行容器 Gateway 网关网络端到端测试,验证内置扩展构建参数,并在 240 秒聚合命令超时下运行有边界的内置插件 Docker 配置文件,同时分别限制每个场景的 Docker 运行时间。完整路径会保留 QR 包安装和安装器 Docker/更新覆盖,用于夜间计划运行、手动触发、工作流调用发布检查,以及真正触及安装器/包/Docker 表面的拉取请求。`main` 推送(包括合并提交)不会强制完整路径;当变更范围逻辑会要求在推送中执行完整覆盖时,工作流会保留快速 Docker 冒烟,并将完整安装冒烟留给夜间或发布验证。较慢的 Bun 全局安装图像提供商冒烟由 `run_bun_global_install_smoke` 单独门控;它会在夜间计划和发布检查工作流中运行,手动 `install-smoke` 触发可以选择加入,但拉取请求和 `main` 推送不会运行它。QR 和安装器 Docker 测试保留各自面向安装的 Dockerfile。本地 `test:docker:all` 会预构建一个共享的实时测试镜像,将 OpenClaw 打包一次为 npm tarball,并构建两个共享的 `scripts/e2e/Dockerfile` 镜像:一个用于安装器/更新/插件依赖通道的裸 Node/Git 运行器,以及一个会把同一个 tarball 安装到 `/app` 中供常规功能通道使用的功能镜像。Docker 通道定义位于 `scripts/lib/docker-e2e-scenarios.mjs`,规划器逻辑位于 `scripts/lib/docker-e2e-plan.mjs`,运行器只执行选中的计划。调度器使用 `OPENCLAW_DOCKER_E2E_BARE_IMAGE` 和 `OPENCLAW_DOCKER_E2E_FUNCTIONAL_IMAGE` 按通道选择镜像,然后使用 `OPENCLAW_SKIP_DOCKER_BUILD=1` 运行通道;使用 `OPENCLAW_DOCKER_ALL_PARALLELISM` 调整默认主池槽位数 10,并使用 `OPENCLAW_DOCKER_ALL_TAIL_PARALLELISM` 调整对提供商敏感的尾部池槽位数 10。重型通道上限默认为 `OPENCLAW_DOCKER_ALL_LIVE_LIMIT=9`、`OPENCLAW_DOCKER_ALL_NPM_LIMIT=10` 和 `OPENCLAW_DOCKER_ALL_SERVICE_LIMIT=7`,这样 npm 安装和多服务通道不会让 Docker 过载,而较轻的通道仍能填满可用槽位。单个比有效上限更重的通道仍可从空池启动,然后独占运行直到释放容量。默认情况下,通道启动会错开 2 秒,以避免本地 Docker 守护进程出现创建风暴;可用 `OPENCLAW_DOCKER_ALL_START_STAGGER_MS=0` 或其他毫秒值覆盖。本地聚合会预检 Docker,移除陈旧的 OpenClaw 端到端容器,输出活动通道状态,持久化通道耗时以用于最长优先排序,并支持 `OPENCLAW_DOCKER_ALL_DRY_RUN=1` 进行调度器检查。默认情况下,它会在第一次失败后停止调度新的池化通道,并且每个通道都有 120 分钟兜底超时,可通过 `OPENCLAW_DOCKER_ALL_LANE_TIMEOUT_MS` 覆盖;选定的实时/尾部通道使用更严格的逐通道上限。`OPENCLAW_DOCKER_ALL_LANES=` 会运行精确的调度器通道,包括仅发布通道(如 `install-e2e`)以及拆分后的内置更新通道(如 `bundled-channel-update-acpx`),同时跳过清理冒烟,以便智能体复现单个失败通道。可复用的实时/端到端工作流会询问 `scripts/test-docker-all.mjs --plan-json` 需要哪些包、镜像类型、实时镜像、通道和凭证覆盖,然后 `scripts/docker-e2e.mjs` 会将该计划转换为 GitHub 输出和摘要。它会通过 `scripts/package-openclaw-for-docker.mjs` 打包 OpenClaw、下载当前运行的包制品,或从 `package_artifact_run_id` 下载包制品;验证 tarball 清单;当计划需要已安装包的通道时,通过 Blacksmith 的 Docker 层缓存构建并推送带有包摘要标签的裸/功能 GHCR Docker 端到端镜像;并复用提供的 `docker_e2e_bare_image`/`docker_e2e_functional_image` 输入或已有的包摘要镜像,而不是重新构建。`Package Acceptance` 工作流是高级包门禁:它会从 npm、可信的 `package_ref`、带 SHA-256 的 HTTPS tarball,或先前的工作流制品解析候选包,然后将单个 `package-under-test` 制品传入可复用的 Docker 端到端工作流。它将 `workflow_ref` 与 `package_ref` 分开,使当前验收逻辑能够验证较旧的可信提交,而不必检出旧的工作流代码。发布检查会针对目标 ref 运行自定义 Package Acceptance 增量:内置渠道兼容性、离线插件夹具,以及针对已解析 tarball 的 Telegram 包 QA。发布路径 Docker 套件会运行更小的分块任务,并设置 `OPENCLAW_SKIP_DOCKER_BUILD=1`,让每个分块只拉取所需的镜像类型,并通过同一个加权调度器执行多个通道(`OPENCLAW_DOCKER_ALL_PROFILE=release-path`、`OPENCLAW_DOCKER_ALL_CHUNK=core|package-update-openai|package-update-anthropic|package-update-core|plugins-runtime-plugins|plugins-runtime-services|plugins-runtime-install-a|plugins-runtime-install-b|plugins-runtime-install-c|plugins-runtime-install-d|bundled-channels`)。当完整发布路径覆盖请求 OpenWebUI 时,它会并入 `plugins-runtime-services`,并且仅在只针对 OpenWebUI 的触发中保留独立的 `openwebui` 分块。旧版聚合分块名称 `package-update`、`plugins-runtime-core`、`plugins-runtime` 和 `plugins-integrations` 仍可用于手动重跑,但发布工作流使用拆分后的分块,因此安装器端到端以及内置插件安装/卸载扫查不会主导关键路径。`install-e2e` 通道别名仍然是两个提供商安装器通道的聚合手动重跑别名。`bundled-channels` 分块会运行拆分后的 `bundled-channel-*` 和 `bundled-channel-update-*` 通道,而不是串行的一体化 `bundled-channel-deps` 通道。每个分块都会上传 `.artifacts/docker-tests/`,其中包含通道日志、耗时、`summary.json`、`failures.json`、阶段耗时、调度器计划 JSON、慢通道表格,以及逐通道重跑命令。工作流 `docker_lanes` 输入会针对已准备的镜像运行选定通道,而不是运行分块任务,这会将失败通道调试限制在一个定向 Docker 任务内,并为该次运行准备、下载或复用包制品;如果选定通道是实时 Docker 通道,定向任务会为该次重跑在本地构建实时测试镜像。生成的逐通道 GitHub 重跑命令会在存在这些值时包含 `package_artifact_run_id`、`package_artifact_name` 和已准备的镜像输入,因此失败通道可以复用失败运行中的精确包和镜像。使用 `pnpm test:docker:rerun ` 可从 GitHub 运行下载 Docker 制品,并打印组合式/逐通道定向重跑命令;使用 `pnpm test:docker:timings ` 可查看慢通道和阶段关键路径摘要。计划运行的实时/端到端工作流每天运行完整发布路径 Docker 套件。内置更新矩阵按更新目标拆分,因此重复的 npm 更新和 Doctor 修复步骤可以与其他内置检查一起分片运行。 +手动调度会跳过 changed-scope 检测,并让预检清单表现得像每个范围化区域都已更改。 +CI 工作流编辑会验证 Node CI 作业图以及工作流 lint,但它们本身不会强制运行 Windows、Android 或 macOS 原生构建;这些平台检查通道仍然只限定于平台源码变更。 +仅 CI 路由编辑、选定的低成本 core-test fixture 编辑,以及窄范围插件契约辅助/测试路由编辑,会使用快速的仅 Node 清单路径:preflight、security 和单个 `checks-fast-core` 任务。当变更文件仅限于该快速任务直接覆盖的路由或辅助表面时,此路径会避开构建产物、Node 22 兼容性、渠道契约、完整核心分片、内置插件分片和额外防护矩阵。 +Windows Node 检查限定于 Windows 特定的进程/路径封装、npm/pnpm/UI runner 辅助、包管理器配置,以及执行该检查通道的 CI 工作流表面;无关源码、插件、install-smoke 和仅测试变更仍留在 Linux Node 检查通道上,因此不会为已由常规测试分片覆盖的内容占用 16-vCPU Windows worker。 +独立的 `install-smoke` 工作流通过自己的 `preflight` 作业复用同一范围脚本。它将冒烟覆盖拆分为 `run_fast_install_smoke` 和 `run_full_install_smoke`。Pull request 会针对 Docker/包表面、内置插件包/清单变更,以及 Docker 冒烟作业会覆盖的核心插件/渠道/Gateway 网关/插件 SDK 表面运行快速路径。仅源码的内置插件变更、仅测试编辑和仅文档编辑不会占用 Docker worker。快速路径会构建一次根 Dockerfile 镜像,检查 CLI,运行 agents delete shared-workspace CLI 冒烟,运行容器 gateway-network e2e,验证一个内置扩展构建参数,并在 240 秒聚合命令超时内运行有界内置插件 Docker 配置文件,每个场景的 Docker 运行也会分别封顶。完整路径保留 QR 包安装和安装器 Docker/更新覆盖,用于夜间计划运行、手动调度、workflow-call 发布检查,以及真正触及安装器/包/Docker 表面的 pull request。`main` 推送(包括 merge commit)不会强制完整路径;当 changed-scope 逻辑会在推送上请求完整覆盖时,工作流保留快速 Docker 冒烟,并将完整安装冒烟留给夜间或发布验证。较慢的 Bun 全局安装 image-provider 冒烟由 `run_bun_global_install_smoke` 单独门控;它会在夜间计划和发布检查工作流中运行,手动 `install-smoke` 调度可以选择加入,但 pull request 和 `main` 推送不会运行它。QR 和安装器 Docker 测试保留各自聚焦安装的 Dockerfile。本地 `test:docker:all` 会预构建一个共享 live-test 镜像,将 OpenClaw 作为 npm tarball 打包一次,并构建两个共享 `scripts/e2e/Dockerfile` 镜像:一个用于安装器/更新/插件依赖检查通道的裸 Node/Git runner,以及一个将同一 tarball 安装到 `/app` 中、用于常规功能检查通道的功能镜像。Docker 检查通道定义位于 `scripts/lib/docker-e2e-scenarios.mjs`,规划器逻辑位于 `scripts/lib/docker-e2e-plan.mjs`,runner 只执行选定的计划。调度器按检查通道使用 `OPENCLAW_DOCKER_E2E_BARE_IMAGE` 和 `OPENCLAW_DOCKER_E2E_FUNCTIONAL_IMAGE` 选择镜像,然后使用 `OPENCLAW_SKIP_DOCKER_BUILD=1` 运行检查通道;使用 `OPENCLAW_DOCKER_ALL_PARALLELISM` 调整默认主池槽位数 10,使用 `OPENCLAW_DOCKER_ALL_TAIL_PARALLELISM` 调整对提供商敏感的尾池槽位数 10。重型检查通道上限默认为 `OPENCLAW_DOCKER_ALL_LIVE_LIMIT=9`、`OPENCLAW_DOCKER_ALL_NPM_LIMIT=10` 和 `OPENCLAW_DOCKER_ALL_SERVICE_LIMIT=7`,这样 npm install 和多服务检查通道不会过度占用 Docker,而较轻的检查通道仍能填满可用槽位。单个比有效上限更重的检查通道仍可从空池启动,然后独占运行直到释放容量。检查通道启动默认错开 2 秒,以避免本地 Docker daemon 创建风暴;可用 `OPENCLAW_DOCKER_ALL_START_STAGGER_MS=0` 或其他毫秒值覆盖。本地聚合会预检 Docker,移除过时的 OpenClaw E2E 容器,输出活动检查通道状态,持久化检查通道耗时以便最长优先排序,并支持 `OPENCLAW_DOCKER_ALL_DRY_RUN=1` 用于调度器检查。默认情况下,它会在首次失败后停止调度新的池化检查通道,每个检查通道都有 120 分钟后备超时,可用 `OPENCLAW_DOCKER_ALL_LANE_TIMEOUT_MS` 覆盖;选定的 live/tail 检查通道使用更严格的单检查通道上限。`OPENCLAW_DOCKER_ALL_LANES=` 会运行精确的调度器检查通道,包括仅发布检查通道(如 `install-e2e`)和拆分的内置更新检查通道(如 `bundled-channel-update-acpx`),同时跳过清理冒烟,使智能体可以复现单个失败检查通道。可复用 live/E2E 工作流会询问 `scripts/test-docker-all.mjs --plan-json` 需要哪些包、镜像种类、live 镜像、检查通道和凭据覆盖,然后 `scripts/docker-e2e.mjs` 将该计划转换为 GitHub 输出和摘要。它会通过 `scripts/package-openclaw-for-docker.mjs` 打包 OpenClaw,或下载当前运行的包产物,或从 `package_artifact_run_id` 下载包产物;验证 tarball 清单;当计划需要已安装包的检查通道时,通过 Blacksmith 的 Docker layer cache 构建并推送以包摘要标记的裸/功能 GHCR Docker E2E 镜像;并复用提供的 `docker_e2e_bare_image`/`docker_e2e_functional_image` 输入或现有包摘要镜像,而不是重新构建。`Package Acceptance` 工作流是高级包门禁:它从 npm、受信任的 `package_ref`、HTTPS tarball 加 SHA-256,或先前工作流产物解析候选包,然后将该单个 `package-under-test` 产物传入可复用 Docker E2E 工作流。它将 `workflow_ref` 与 `package_ref` 分开,使当前验收逻辑能验证较旧的受信任提交,而不必签出旧工作流代码。发布检查会针对目标 ref 运行自定义 Package Acceptance 差异:内置渠道兼容性、离线插件 fixture,以及针对解析出的 tarball 的 Telegram 包 QA。发布路径 Docker 套件运行更小的分块作业,并使用 `OPENCLAW_SKIP_DOCKER_BUILD=1`,因此每个分块只拉取所需的镜像种类,并通过同一加权调度器执行多个检查通道(`OPENCLAW_DOCKER_ALL_PROFILE=release-path`、`OPENCLAW_DOCKER_ALL_CHUNK=core|package-update-openai|package-update-anthropic|package-update-core|plugins-runtime-plugins|plugins-runtime-services|plugins-runtime-install-a|plugins-runtime-install-b|plugins-runtime-install-c|plugins-runtime-install-d|bundled-channels`)。当完整 release-path 覆盖请求 OpenWebUI 时,OpenWebUI 会并入 `plugins-runtime-services`,并且仅对 OpenWebUI-only 调度保留独立的 `openwebui` 分块。旧版聚合分块名称 `package-update`、`plugins-runtime-core`、`plugins-runtime` 和 `plugins-integrations` 仍可用于手动重跑,但发布工作流使用拆分分块,因此安装器 E2E 和内置插件安装/卸载扫描不会主导关键路径。`install-e2e` 检查通道别名仍是两个提供商安装器检查通道的聚合手动重跑别名。`bundled-channels` 分块运行拆分的 `bundled-channel-*` 和 `bundled-channel-update-*` 检查通道,而不是串行的一体式 `bundled-channel-deps` 检查通道。每个分块都会上传 `.artifacts/docker-tests/`,其中包含检查通道日志、耗时、`summary.json`、`failures.json`、阶段耗时、调度器计划 JSON、慢检查通道表,以及每检查通道重跑命令。工作流 `docker_lanes` 输入会针对准备好的镜像运行选定检查通道,而不是分块作业,这使失败检查通道调试被限定在一个目标 Docker 作业内,并为该运行准备、下载或复用包产物;如果选定检查通道是 live Docker 检查通道,目标作业会为该重跑在本地构建 live-test 镜像。生成的每检查通道 GitHub 重跑命令会在这些值存在时包含 `package_artifact_run_id`、`package_artifact_name` 和已准备镜像输入,因此失败检查通道可以复用失败运行中的精确包和镜像。使用 `pnpm test:docker:rerun ` 从 GitHub 运行下载 Docker 产物并打印组合/每检查通道目标重跑命令;使用 `pnpm test:docker:timings ` 查看慢检查通道和阶段关键路径摘要。计划 live/E2E 工作流每天运行完整 release-path Docker 套件。内置更新矩阵按更新目标拆分,使重复的 npm update 和 Doctor 修复流程可以与其他内置检查一起分片。 -当前发布 Docker 分块为 `core`、`package-update-openai`、`package-update-anthropic`、`package-update-core`、`plugins-runtime-plugins`、`plugins-runtime-services`、`plugins-runtime-install-a`、`plugins-runtime-install-b`、`plugins-runtime-install-c`、`plugins-runtime-install-d`、`bundled-channels-core`、`bundled-channels-update-a`、`bundled-channels-update-b` 和 `bundled-channels-contracts`。聚合 `bundled-channels` 分块仍可用于手动一次性重跑,`plugins-runtime-core`、`plugins-runtime` 和 `plugins-integrations` 也仍是聚合插件/运行时别名,但发布工作流使用拆分后的分块,以便渠道冒烟、更新目标、插件运行时检查,以及内置插件安装/卸载扫查可以并行运行。定向 `docker_lanes` 触发也会在一个共享包/镜像准备步骤之后,将多个选定通道拆分为并行任务,并且内置渠道更新通道会针对临时 npm 网络故障重试一次。 +当前发布 Docker 分块为 `core`、`package-update-openai`、`package-update-anthropic`、`package-update-core`、`plugins-runtime-plugins`、`plugins-runtime-services`、`plugins-runtime-install-a`、`plugins-runtime-install-b`、`plugins-runtime-install-c`、`plugins-runtime-install-d`、`bundled-channels-core`、`bundled-channels-update-a`、`bundled-channels-update-b` 和 `bundled-channels-contracts`。聚合 `bundled-channels` 分块仍可用于手动一次性重跑,`plugins-runtime-core`、`plugins-runtime` 和 `plugins-integrations` 仍是聚合插件/运行时别名,但发布工作流使用拆分分块,使渠道冒烟、更新目标、插件运行时检查以及内置插件安装/卸载扫描可以并行运行。目标 `docker_lanes` 调度也会在一次共享包/镜像准备步骤之后,将多个选定检查通道拆分为并行作业,并且内置渠道更新检查通道会针对临时 npm 网络故障重试一次。 -本地 changed-lane 逻辑位于 `scripts/changed-lanes.mjs`,并由 `scripts/check-changed.mjs` 执行。这个本地检查门禁对架构边界的要求比宽泛的 CI 平台范围更严格:核心生产代码变更会运行核心生产代码和核心测试的类型检查,以及核心 lint/guard;仅核心测试变更只运行核心测试类型检查和核心 lint;扩展生产代码变更会运行扩展生产代码和扩展测试类型检查,以及扩展 lint;仅扩展测试变更会运行扩展测试类型检查和扩展 lint。公开插件 SDK 或插件契约变更会扩展到扩展类型检查,因为扩展依赖这些核心契约,但 Vitest 扩展扫描属于显式测试工作。仅发布元数据的版本号提升会运行有针对性的版本/配置/根依赖检查。未知的根目录/配置变更会以故障安全方式进入所有检查 lane。 -本地 changed-test 路由位于 `scripts/test-projects.test-support.mjs`,并且有意比 `check:changed` 更轻量:直接测试编辑会运行自身,源码编辑优先使用显式映射,然后是同级测试和导入图依赖项。共享群组房间投递配置是其中一个显式映射:对群组可见回复配置、源码回复投递模式或 message-tool 系统提示词的变更,会路由到核心回复测试以及 Discord 和 Slack 投递回归测试,因此共享默认值变更会在第一次 PR 推送前失败。仅当变更的 harness 范围足够广,以至于这个轻量映射集合不是可信代理时,才使用 `OPENCLAW_TEST_CHANGED_BROAD=1 pnpm test:changed`。 +本地 changed-lane 逻辑位于 `scripts/changed-lanes.mjs`,并由 `scripts/check-changed.mjs` 执行。这个本地检查门禁在架构边界上比宽泛的 CI 平台范围更严格:核心生产变更会运行核心生产和核心测试类型检查,以及核心 lint/守卫;仅核心测试变更只运行核心测试类型检查和核心 lint;插件生产变更会运行插件生产和插件测试类型检查,以及插件 lint;仅插件测试变更会运行插件测试类型检查和插件 lint。公共插件 SDK 或插件契约变更会扩展到插件类型检查,因为插件依赖这些核心契约,但 Vitest 插件扫描属于显式测试工作。仅发布元数据的版本号变更会运行针对版本、配置和根依赖的检查。未知的根目录/配置变更会故障安全地回退到所有检查通道。 +本地 changed-test 路由位于 `scripts/test-projects.test-support.mjs`,并且 +有意比 `check:changed` 更轻量:直接测试编辑会运行自身, +源代码编辑会优先使用显式映射,然后是同级测试和导入图 +依赖项。共享群组房间投递配置是显式映射之一: +对群组可见回复配置、源回复投递模式或 +message-tool 系统提示词的更改,会路由到核心回复测试以及 Discord 和 +Slack 投递回归测试,这样共享默认值变更会在首次 PR +推送前失败。仅当变更覆盖整个 harness,导致廉价映射集合不能作为可信代理时, +才使用 `OPENCLAW_TEST_CHANGED_BROAD=1 pnpm test:changed`。 -对于 Testbox 验证,请从仓库根目录运行,并且宽泛证明优先使用全新预热的 box。在复用、过期或刚报告异常大同步量的 box 上花时间跑慢门禁之前,先在 box 内运行 `pnpm testbox:sanity`。当必需的根目录文件(例如 `pnpm-lock.yaml`)消失,或 `git status --short` 显示至少 200 个已跟踪删除时,完整性检查会快速失败。这通常意味着远程同步状态不是 PR 的可信副本。应停止该 box 并预热一个新的,而不是调试产品测试失败。对于有意的大规模删除 PR,请为该次完整性检查设置 `OPENCLAW_TESTBOX_ALLOW_MASS_DELETIONS=1`。 +对于 Testbox 验证,请从仓库根目录运行,并优先使用新预热的 box 来获取 +宽泛证明。在把慢速门禁花在一个被复用、已过期或 +刚报告异常大量同步的 box 上之前,先在该 +box 内运行 `pnpm testbox:sanity`。当所需根文件(例如 +`pnpm-lock.yaml`)消失,或 `git status --short` 显示至少 200 个 +已跟踪删除时,完整性检查会快速失败。这通常意味着远程同步状态不是 +PR 的可信副本。停止该 box 并预热一个新的,而不是调试 +产品测试失败。对于有意的大规模删除 PR,请为该完整性检查运行设置 +`OPENCLAW_TESTBOX_ALLOW_MASS_DELETIONS=1`。 -手动 CI 分发会运行 `checks-node-compat-node22` 和 `plugin-prerelease-suite`,作为候选发布版本兼容性覆盖。普通拉取请求和 `main` 推送会跳过这些 lane,并让矩阵聚焦于 Node 24 测试/渠道 lane。 +手动 CI 分派会运行 `checks-node-compat-node22` 作为宽泛兼容性覆盖。`plugin-prerelease-suite` 是成本更高的产品/包覆盖,因此只在 `Full Release Validation` 以 `full_release_validation=true` 分派 CI 时运行。普通拉取请求、`main` 推送和独立手动 CI 分派会保持该套件关闭。 -最慢的 Node 测试家族会被拆分或均衡,以便每个作业保持较小规模而不过度预留 runner:渠道契约作为三个加权分片运行,内置插件测试在六个扩展 worker 之间均衡,小型核心单元 lane 成对运行,auto-reply 作为四个均衡 worker 运行,并将回复子树拆分为 agent-runner、dispatch 和 commands/state-routing 分片,agentic Gateway 网关/插件配置则分布在现有仅源码 agentic Node 作业中,而不是等待构建产物。宽泛浏览器、QA、媒体和杂项插件测试使用各自专用的 Vitest 配置,而不是共享插件总括配置。扩展分片作业一次最多运行两个插件配置组,每组一个 Vitest worker,并使用更大的 Node 堆,因此导入量大的插件批次不会创建额外 CI 作业。宽泛 agents lane 使用共享 Vitest 文件并行调度器,因为它主要受导入/调度影响,而不是由单个慢测试文件主导。`runtime-config` 与 infra core-runtime 分片一起运行,以避免共享 runtime 分片承担尾部耗时。include-pattern 分片使用 CI 分片名称记录计时条目,因此 `.artifacts/vitest-shard-timings.json` 可以区分完整配置和过滤后的分片。`check-additional` 将 package-boundary 编译/canary 工作放在一起,并将 runtime topology architecture 与 Gateway 网关 watch 覆盖分开;boundary guard 分片会在一个作业内并发运行其小型独立 guard。Gateway 网关 watch、渠道测试和核心 support-boundary 分片会在 `dist/` 和 `dist-runtime/` 已构建后,于 `build-artifacts` 内并发运行,保留其旧检查名称作为轻量验证作业,同时避免两个额外 Blacksmith worker 和第二个 artifact-consumer 队列。 -Android CI 会同时运行 `testPlayDebugUnitTest` 和 `testThirdPartyDebugUnitTest`,然后构建 Play debug APK。第三方 flavor 没有单独的 source set 或 manifest;它的单元测试 lane 仍会使用 SMS/call-log BuildConfig 标志编译该 flavor,同时避免在每次 Android 相关推送时重复打包 debug APK。 -当同一 PR 或 `main` ref 上有较新的推送落地时,GitHub 可能会将被取代的作业标记为 `cancelled`。除非同一 ref 的最新运行也在失败,否则将其视为 CI 噪声。聚合分片检查使用 `!cancelled() && always()`,因此它们仍会报告正常的分片失败,但不会在整个工作流已被取代后继续排队。 -自动 CI 并发 key 带有版本(`CI-v7-*`),因此 GitHub 侧旧队列组中的僵尸作业无法无限期阻塞更新的 main 运行。手动全套件运行使用 `CI-manual-v1-*`,并且不会取消正在运行的任务。 +最慢的 Node 测试族已拆分或均衡,使每个作业保持较小规模且不过度预留 runner:渠道契约作为三个加权分片运行,内置插件测试在六个插件 worker 间均衡,小型核心单元通道会成对运行,自动回复作为四个均衡 worker 运行,并将回复子树拆分为 agent-runner、dispatch 和 commands/state-routing 分片,agentic Gateway 网关/插件配置分布在现有仅源码 agentic Node 作业中,而不是等待构建产物。宽泛浏览器、QA、媒体和杂项插件测试使用它们专用的 Vitest 配置,而不是共享插件兜底配置。插件分片作业一次最多运行两个插件配置组,每组一个 Vitest worker,并使用更大的 Node 堆,这样导入密集的插件批次不会创建额外 CI 作业。宽泛 agents 通道使用共享 Vitest 文件并行调度器,因为它主要受导入/调度影响,而不是由单个慢测试文件主导。`runtime-config` 与 infra core-runtime 分片一起运行,避免共享运行时分片承担尾部耗时。include-pattern 分片使用 CI 分片名称记录计时条目,因此 `.artifacts/vitest-shard-timings.json` 可以区分整个配置和过滤后的分片。`check-additional` 将包边界编译/canary 工作保持在一起,并将运行时拓扑架构与 Gateway 网关 watch 覆盖分离;boundary guard 分片会在一个作业内并发运行其小型独立守卫。Gateway 网关 watch、渠道测试和核心 support-boundary 分片在 `dist/` 和 `dist-runtime/` 已经构建后,在 `build-artifacts` 内并发运行,保留它们旧有的检查名称作为轻量验证作业,同时避免两个额外的 Blacksmith worker 和第二个产物消费队列。 +Android CI 会同时运行 `testPlayDebugUnitTest` 和 `testThirdPartyDebugUnitTest`,然后构建 Play debug APK。第三方 flavor 没有单独的 source set 或 manifest;它的单元测试通道仍会使用短信/通话记录 BuildConfig 标志编译该 flavor,同时避免在每次 Android 相关推送时重复执行 debug APK 打包作业。 +当同一 PR 或 `main` ref 上有更新推送落地时,GitHub 可能会将被取代的作业标记为 `cancelled`。除非同一 ref 的最新运行也失败,否则将其视为 CI 噪声。聚合分片检查使用 `!cancelled() && always()`,因此它们仍会报告正常的分片失败,但不会在整个 workflow 已经被取代后继续排队。 +自动 CI 并发键带有版本号(`CI-v7-*`),这样 GitHub 端旧队列组中的僵尸项无法无限期阻塞较新的 main 运行。手动全套件运行使用 `CI-manual-v1-*`,且不会取消进行中的运行。 -## Runners +## Runner | Runner | 作业 | | -------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `ubuntu-24.04` | `preflight`、快速安全作业和聚合(`security-scm-fast`、`security-dependency-audit`、`security-fast`)、快速协议/契约/内置检查、分片渠道契约检查、除 lint 以外的 `check` 分片、`check-additional` 分片和聚合、Node 测试聚合验证器、文档检查、Python Skills、workflow-sanity、labeler、auto-response;install-smoke preflight 也使用 GitHub 托管 Ubuntu,以便 Blacksmith 矩阵可以更早排队 | -| `blacksmith-4vcpu-ubuntu-2404` | `CodeQL Critical Quality`、较低权重的扩展分片、`checks-fast-core`、`checks-node-compat-node22`、`check-prod-types` 和 `check-test-types` | -| `blacksmith-8vcpu-ubuntu-2404` | `build-artifacts`、build-smoke、Linux Node 测试分片、内置插件测试分片、`android` | -| `blacksmith-16vcpu-ubuntu-2404` | `check-lint`,它仍然对 CPU 足够敏感,8 vCPU 的成本高于节省的收益;install-smoke Docker 构建,其中 32-vCPU 队列时间成本高于节省的收益 | +| `ubuntu-24.04` | `preflight`,快速安全作业和聚合(`security-scm-fast`、`security-dependency-audit`、`security-fast`),快速协议/契约/内置检查,分片渠道契约检查,除 lint 外的 `check` 分片,`check-additional` 分片和聚合,Node 测试聚合验证器,文档检查,Python Skills,workflow-sanity,labeler,auto-response;install-smoke preflight 也使用 GitHub 托管 Ubuntu,这样 Blacksmith 矩阵可以更早排队 | +| `blacksmith-4vcpu-ubuntu-2404` | `CodeQL Critical Quality`,较低权重的插件分片,`checks-fast-core`,`checks-node-compat-node22`,`check-prod-types` 和 `check-test-types` | +| `blacksmith-8vcpu-ubuntu-2404` | `build-artifacts`,build-smoke,Linux Node 测试分片,内置插件测试分片,`android` | +| `blacksmith-16vcpu-ubuntu-2404` | `check-lint`,它对 CPU 仍足够敏感,使 8 vCPU 带来的成本高于节省;install-smoke Docker 构建中,32-vCPU 排队时间成本高于节省 | | `blacksmith-16vcpu-windows-2025` | `checks-windows` | | `blacksmith-6vcpu-macos-latest` | `openclaw/openclaw` 上的 `macos-node`;fork 回退到 `macos-latest` | | `blacksmith-12vcpu-macos-latest` | `openclaw/openclaw` 上的 `macos-swift`;fork 回退到 `macos-latest` | -## 本地等价命令 +## 本地等效命令 ```bash pnpm changed:lanes # inspect the local changed-lane classifier for origin/main...HEAD @@ -232,7 +247,7 @@ pnpm test:perf:groups --full-suite --allow-failures --output .artifacts/test-per pnpm test:perf:groups:compare .artifacts/test-perf/baseline-before.json .artifacts/test-perf/after-agent.json ``` -## 相关内容 +## 相关 - [安装概览](/zh-CN/install) - [发布渠道](/zh-CN/install/development-channels) diff --git a/docs/zh-CN/cli/plugins.md b/docs/zh-CN/cli/plugins.md index 986695f5f..9fd6d46d7 100644 --- a/docs/zh-CN/cli/plugins.md +++ b/docs/zh-CN/cli/plugins.md @@ -1,15 +1,15 @@ --- read_when: - - 你想安装或管理 Gateway 网关插件或兼容包 + - 你想安装或管理 Gateway 网关插件或兼容的捆绑包 - 你想调试插件加载失败 sidebarTitle: Plugins summary: '`openclaw plugins` 的 CLI 参考(list、install、marketplace、uninstall、enable/disable、doctor)' title: 插件 x-i18n: - generated_at: "2026-04-28T23:40:12Z" + generated_at: "2026-04-29T05:39:32Z" model: gpt-5.5 provider: openai - source_hash: a27d62f78692da7744af28cb5427f43004063e7b5721a945232c995bc405186d + source_hash: 68d6a2734c7b4a3608467c64426f48bdf8dc1a36e33b51ba024313fc36762b5b source_path: cli/plugins.md workflow: 16 --- @@ -55,14 +55,14 @@ openclaw plugins marketplace list openclaw plugins marketplace list --json ``` -若要调查安装、检查、卸载或 registry 刷新速度慢的问题,请使用 `OPENCLAW_PLUGIN_LIFECYCLE_TRACE=1` 运行该命令。跟踪信息会将阶段耗时写入 stderr,并保持 JSON 输出可解析。参见[调试](/zh-CN/help/debugging#plugin-lifecycle-trace)。 +如需调查安装、检查、卸载或刷新 registry 速度慢的问题,请带上 `OPENCLAW_PLUGIN_LIFECYCLE_TRACE=1` 运行命令。该 trace 会将阶段耗时写入 stderr,并保持 JSON 输出可解析。参见[调试](/zh-CN/help/debugging#plugin-lifecycle-trace)。 -内置插件随 OpenClaw 一起发布。有些默认启用(例如内置模型提供商、内置语音提供商和内置浏览器插件);其他插件需要 `plugins enable`。 +内置插件随 OpenClaw 一起发布。其中一些默认启用(例如内置模型提供商、内置语音提供商和内置浏览器插件);其他插件需要使用 `plugins enable`。 -原生 OpenClaw 插件必须随附 `openclaw.plugin.json`,其中包含内联 JSON Schema(`configSchema`,即使为空)。兼容包改用它们自己的包清单。 +原生 OpenClaw 插件必须随附 `openclaw.plugin.json`,并包含内联 JSON Schema(`configSchema`,即使为空)。兼容包则使用自己的包清单。 -`plugins list` 会显示 `Format: openclaw` 或 `Format: bundle`。详细列表/info 输出还会显示包子类型(`codex`、`claude` 或 `cursor`)以及检测到的包能力。 +`plugins list` 会显示 `Format: openclaw` 或 `Format: bundle`。详细的 list/info 输出还会显示包子类型(`codex`、`claude` 或 `cursor`)以及检测到的包能力。 ### 安装 @@ -81,43 +81,47 @@ openclaw plugins install --marketplace https://github.com// -裸包名会先针对 ClawHub 检查,然后检查 npm。请像运行代码一样对待插件安装。优先使用固定版本。 +裸包名会先在 ClawHub 中检查,然后再检查 npm。请像运行代码一样对待插件安装。优先使用固定版本。 + +ClawHub 是大多数插件的主要分发和发现界面。Npm 仍然是受支持的后备方案和直接安装路径。在迁移到 ClawHub 期间,OpenClaw 仍会在 npm 上发布一些 OpenClaw 自有的 `@openclaw/*` 插件包;在插件发布列车之间,这些包版本可能落后于内置源码。如果 npm 报告某个 OpenClaw 自有插件包已废弃,则该已发布版本是旧的外部制品;请使用当前 OpenClaw 内置的插件或本地 checkout,直到发布更新的 npm 包。 + + - 如果你的 `plugins` 区段由单文件 `$include` 支持,`plugins install/update/enable/disable/uninstall` 会写入该被 include 的文件,并保持 `openclaw.json` 不变。根 include、include 数组以及带同级覆盖项的 include 会关闭失败,而不是扁平化。有关支持的形状,请参见[配置 include](/zh-CN/gateway/configuration)。 + 如果你的 `plugins` 区段由单文件 `$include` 支撑,`plugins install/update/enable/disable/uninstall` 会写入该被 include 的文件,并保持 `openclaw.json` 不变。root include、include 数组以及带有同级覆盖的 include 会失败关闭,而不是被展开。支持的形状请参见[配置 include](/zh-CN/gateway/configuration)。 - 如果安装期间配置无效,`plugins install` 通常会关闭失败,并提示你先运行 `openclaw doctor --fix`。在 Gateway 网关启动期间,某个插件的无效配置会隔离到该插件,以便其他渠道和插件可以继续运行;`openclaw doctor --fix` 可以隔离无效插件条目。唯一有文档说明的安装时例外,是针对明确选择加入 `openclaw.install.allowInvalidConfigRecovery` 的插件的狭窄内置插件恢复路径。 + 如果安装期间配置无效,`plugins install` 通常会失败关闭,并提示你先运行 `openclaw doctor --fix`。在 Gateway 网关启动期间,某个插件的无效配置会被隔离到该插件,因此其他渠道和插件可以继续运行;`openclaw doctor --fix` 可以隔离该无效插件条目。唯一有文档说明的安装时例外,是一个面向显式选择加入 `openclaw.install.allowInvalidConfigRecovery` 的插件的狭窄内置插件恢复路径。 - - `--force` 会复用现有安装目标,并就地覆盖已安装的插件或钩子包。当你有意从新的本地路径、归档、ClawHub 包或 npm 工件重新安装同一 id 时使用它。对于已跟踪 npm 插件的常规升级,优先使用 `openclaw plugins update `。 + + `--force` 会复用现有安装目标,并就地覆盖已安装的插件或钩子包。当你有意从新的本地路径、归档、ClawHub 包或 npm 制品重新安装同一 id 时使用它。对于已被跟踪的 npm 插件的常规升级,请优先使用 `openclaw plugins update `。 - 如果你对已安装的插件 id 运行 `plugins install`,OpenClaw 会停止,并指向 `plugins update ` 进行常规升级,或者在你确实想从其他来源覆盖当前安装时指向 `plugins install --force`。 + 如果你对已经安装的插件 id 运行 `plugins install`,OpenClaw 会停止,并在正常升级时指向 `plugins update `,或者在你确实想从其他来源覆盖当前安装时指向 `plugins install --force`。 - `--pin` 仅适用于 npm 安装。它不支持与 `--marketplace` 一起使用,因为 marketplace 安装会持久化 marketplace 来源元数据,而不是 npm spec。 + `--pin` 仅适用于 npm 安装。它不支持与 `--marketplace` 一起使用,因为 marketplace 安装会持久化 marketplace 源元数据,而不是 npm spec。 - `--dangerously-force-unsafe-install` 是针对内置危险代码扫描器误报的应急选项。即使内置扫描器报告 `critical` 发现,它也允许安装继续,但它**不会**绕过插件 `before_install` 钩子策略阻止,也**不会**绕过扫描失败。 + `--dangerously-force-unsafe-install` 是用于内置危险代码扫描器误报的应急选项。即使内置扫描器报告 `critical` 发现,它也允许安装继续,但它**不会**绕过插件 `before_install` 钩子策略阻断,也**不会**绕过扫描失败。 - 此 CLI 标志适用于插件 install/update 流程。由 Gateway 网关支持的 skill 依赖安装使用匹配的 `dangerouslyForceUnsafeInstall` 请求覆盖,而 `openclaw skills install` 仍然是单独的 ClawHub skill 下载/安装流程。 + 此 CLI 标志适用于插件安装/更新流程。由 Gateway 网关支撑的 skill 依赖安装使用匹配的 `dangerouslyForceUnsafeInstall` 请求覆盖,而 `openclaw skills install` 仍是单独的 ClawHub skill 下载/安装流程。 - 如果你发布在 ClawHub 上的插件被 registry 扫描阻止,请使用 [ClawHub](/zh-CN/tools/clawhub) 中的发布者步骤。 + 如果你在 ClawHub 上发布的插件被 registry 扫描阻止,请使用 [ClawHub](/zh-CN/tools/clawhub) 中的发布者步骤。 - - `plugins install` 也是安装在 `package.json` 中暴露 `openclaw.hooks` 的钩子包的界面。请使用 `openclaw hooks` 查看经过筛选的钩子可见性和按钩子启用,而不是安装包。 + + `plugins install` 也是安装钩子包的界面,这些钩子包会在 `package.json` 中暴露 `openclaw.hooks`。使用 `openclaw hooks` 查看经过筛选的钩子可见性和按钩子启用,不要用它安装包。 - Npm specs **仅限 registry**(包名 + 可选的**精确版本**或 **dist-tag**)。Git/URL/file specs 和 semver 范围会被拒绝。为了安全,依赖安装会在项目本地使用 `--ignore-scripts` 运行,即使你的 shell 有全局 npm 安装设置也是如此。 + Npm spec **仅限 registry**(包名 + 可选的**精确版本**或 **dist-tag**)。Git/URL/file spec 和 semver 范围会被拒绝。为确保安全,即使你的 shell 有全局 npm 安装设置,依赖安装也会在项目本地以 `--ignore-scripts` 运行。 - 当你想跳过 ClawHub 查找并直接从 npm 安装时,请使用 `npm:`。裸包 specs 仍优先使用 ClawHub,只有在 ClawHub 没有该包或版本时才回退到 npm。 + 当你想跳过 ClawHub 查找并直接从 npm 安装时,请使用 `npm:`。裸包 spec 仍会优先使用 ClawHub,并且仅在 ClawHub 没有该包或版本时回退到 npm。 - 裸 specs 和 `@latest` 会留在 stable 轨道。如果 npm 将其中任一项解析为 prerelease,OpenClaw 会停止并要求你使用 prerelease 标签(如 `@beta`/`@rc`)或精确 prerelease 版本(如 `@1.2.3-beta.4`)显式选择加入。 + 裸 spec 和 `@latest` 会停留在稳定轨道。如果 npm 将其中任一项解析为预发布版,OpenClaw 会停止并要求你使用预发布标签(例如 `@beta`/`@rc`)或精确预发布版本(例如 `@1.2.3-beta.4`)显式选择加入。 - 如果裸安装 spec 匹配内置插件 id(例如 `diffs`),OpenClaw 会直接安装内置插件。要安装同名 npm 包,请使用显式 scoped spec(例如 `@scope/diffs`)。 + 如果裸安装 spec 匹配内置插件 id(例如 `diffs`),OpenClaw 会直接安装该内置插件。若要安装同名 npm 包,请使用显式 scoped spec(例如 `@scope/diffs`)。 @@ -135,32 +139,32 @@ openclaw plugins install clawhub:openclaw-codex-app-server openclaw plugins install clawhub:openclaw-codex-app-server@1.2.3 ``` -OpenClaw 现在也会优先为裸 npm 安全插件 specs 使用 ClawHub。只有在 ClawHub 没有该包或版本时,才会回退到 npm: +OpenClaw 现在也会对裸 npm 安全插件 spec 优先使用 ClawHub。仅当 ClawHub 没有该包或版本时才会回退到 npm: ```bash openclaw plugins install openclaw-codex-app-server ``` -使用 `npm:` 强制仅通过 npm 解析,例如当 ClawHub 不可达,或你知道该包仅存在于 npm 上时: +使用 `npm:` 强制仅通过 npm 解析,例如当 ClawHub 无法访问,或你知道该包只存在于 npm 上时: ```bash openclaw plugins install npm:openclaw-codex-app-server openclaw plugins install npm:@scope/plugin-name@1.0.1 ``` -OpenClaw 会从 ClawHub 下载包归档,检查声明的插件 API / 最低 gateway 兼容性,然后通过常规归档路径安装它。记录的安装会保留其 ClawHub 来源元数据,以便后续更新。 -未指定版本的 ClawHub 安装会保留未指定版本的记录 spec,因此 `openclaw plugins update` 可以跟随较新的 ClawHub 发布;显式版本或标签选择器(如 `clawhub:pkg@1.2.3` 和 `clawhub:pkg@beta`)仍固定到该选择器。 +OpenClaw 会从 ClawHub 下载包归档,检查声明的插件 API / 最低 gateway 兼容性,然后通过常规归档路径安装。记录的安装会保留其 ClawHub 源元数据,以便后续更新。 +未指定版本的 ClawHub 安装会保留未指定版本的记录 spec,因此 `openclaw plugins update` 可以跟随更新的 ClawHub 发布;显式版本或标签选择器(例如 `clawhub:pkg@1.2.3` 和 `clawhub:pkg@beta`)仍会固定到该选择器。 #### Marketplace 简写 -当 marketplace 名称存在于 Claude 本地 registry 缓存 `~/.claude/plugins/known_marketplaces.json` 中时,使用 `plugin@marketplace` 简写: +当 marketplace 名称存在于 Claude 的本地 registry 缓存 `~/.claude/plugins/known_marketplaces.json` 中时,使用 `plugin@marketplace` 简写: ```bash openclaw plugins marketplace list openclaw plugins install @ ``` -当你想显式传入 marketplace 来源时,使用 `--marketplace`: +当你想显式传入 marketplace 源时,使用 `--marketplace`: ```bash openclaw plugins install --marketplace @@ -170,16 +174,16 @@ openclaw plugins install --marketplace ./my-marketplace ``` - + - 来自 `~/.claude/plugins/known_marketplaces.json` 的 Claude 已知 marketplace 名称 - 本地 marketplace 根目录或 `marketplace.json` 路径 - - GitHub 仓库简写,例如 `owner/repo` - - GitHub 仓库 URL,例如 `https://github.com/owner/repo` + - GitHub repo 简写,例如 `owner/repo` + - GitHub repo URL,例如 `https://github.com/owner/repo` - git URL - 对于从 GitHub 或 git 加载的远程 marketplace,插件条目必须保留在克隆的 marketplace 仓库内。OpenClaw 接受来自该仓库的相对路径来源,并拒绝远程清单中的 HTTP(S)、绝对路径、git、GitHub 和其他非路径插件来源。 + 对于从 GitHub 或 git 加载的远程 marketplace,插件条目必须保持在克隆的 marketplace repo 内部。OpenClaw 接受来自该 repo 的相对路径源,并拒绝远程清单中的 HTTP(S)、绝对路径、git、GitHub 以及其他非路径插件源。 @@ -187,14 +191,14 @@ openclaw plugins install --marketplace ./my-marketplace - 原生 OpenClaw 插件(`openclaw.plugin.json`) - Codex 兼容包(`.codex-plugin/plugin.json`) -- Claude 兼容包(`.claude-plugin/plugin.json` 或默认 Claude component 布局) +- 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 钩子目录;其他检测到的包能力会显示在 diagnostics/info 中,但尚未接入运行时执行。 +兼容包会安装到常规插件根目录,并参与相同的 list/info/enable/disable 流程。目前支持包 skills、Claude command-skills、Claude `settings.json` 默认值、Claude `.lsp.json` / 清单声明的 `lspServers` 默认值、Cursor command-skills 以及兼容的 Codex 钩子目录;其他检测到的包能力会显示在诊断/info 中,但尚未接入运行时执行。 -### 列表 +### 列出 ```bash openclaw plugins list @@ -207,23 +211,27 @@ openclaw plugins list --json 仅显示已启用的插件。 - 从表格视图切换到按插件显示的详细行,其中包含来源/origin/版本/激活元数据。 + 从表格视图切换到每个插件的详细行,包含 source/origin/version/activation 元数据。 - 机器可读的清单加 registry diagnostics。 + 机器可读的清单以及 registry 诊断。 -`plugins list` 会先读取持久化的本地插件 registry;当 registry 缺失或无效时,会使用仅基于清单推导的 fallback。它适合用于检查插件是否已安装、已启用,并且对冷启动规划可见,但它不是对已运行 Gateway 网关进程的实时运行时探测。更改插件代码、启用状态、钩子策略或 `plugins.load.paths` 后,请在期待新的 `register(api)` 代码或钩子运行之前,重启服务该渠道的 Gateway 网关。对于远程/容器部署,请确认你重启的是实际的 `openclaw gateway run` 子进程,而不仅是包装器进程。 +`plugins list` 会先读取持久化的本地插件注册表;当注册表缺失或无效时,会使用仅由清单派生的回退。它适合用于检查插件是否已安装、已启用,并且对冷启动规划可见,但它不是对已运行 Gateway 网关进程的实时运行时探测。更改插件代码、启用状态、钩子策略或 `plugins.load.paths` 后,需要重启为该渠道提供服务的 Gateway 网关,才能期待新的 `register(api)` 代码或钩子运行。对于远程/容器部署,请确认你重启的是实际的 `openclaw gateway run` 子进程,而不仅仅是包装器进程。 -对于打包 Docker 镜像内的内置插件工作,请将插件源目录 bind-mount 到匹配的打包源路径上,例如 `/app/extensions/synology-chat`。OpenClaw 会先发现该挂载的源码 overlay,再发现 `/app/dist/extensions/synology-chat`;普通复制的源码目录仍保持惰性,因此正常的打包安装仍会使用编译后的 dist。 +对于打包 Docker 镜像内的内置插件工作,请将插件 +源目录绑定挂载到匹配的打包源路径上,例如 +`/app/extensions/synology-chat`。OpenClaw 会先发现该挂载的源码 +覆盖层,然后才是 `/app/dist/extensions/synology-chat`;普通复制的源码 +目录仍然不会生效,因此常规打包安装仍会使用编译后的 dist。 -用于运行时钩子调试: +对于运行时钩子调试: - `openclaw plugins inspect --json` 会显示来自模块加载检查过程的已注册钩子和诊断信息。 -- `openclaw gateway status --deep --require-rpc` 会确认可访问的 Gateway 网关、服务/进程提示、配置路径以及 RPC 健康状态。 -- 非内置的会话钩子(`llm_input`、`llm_output`、`before_agent_finalize`、`agent_end`)需要 `plugins.entries..hooks.allowConversationAccess=true`。 +- `openclaw gateway status --deep --require-rpc` 会确认可访问的 Gateway 网关、服务/进程提示、配置路径和 RPC 健康状态。 +- 非内置对话钩子(`llm_input`、`llm_output`、`before_agent_finalize`、`agent_end`)需要 `plugins.entries..hooks.allowConversationAccess=true`。 使用 `--link` 避免复制本地目录(会添加到 `plugins.load.paths`): @@ -232,16 +240,16 @@ openclaw plugins install -l ./my-plugin ``` -`--force` 不支持与 `--link` 一起使用,因为链接安装会复用源路径,而不是复制到托管安装目标上。 +`--force` 不支持与 `--link` 一起使用,因为链接安装会复用源路径,而不是覆盖托管安装目标。 -在 npm 安装中使用 `--pin`,可以将解析后的精确 spec(`name@version`)保存到托管插件索引中,同时保持默认行为为未固定版本。 +在 npm 安装时使用 `--pin`,可将解析出的精确规范(`name@version`)保存到托管插件索引中,同时保持默认行为为不固定版本。 ### 插件索引 -插件安装元数据是机器管理的状态,不是用户配置。安装和更新会将其写入活动 OpenClaw 状态目录下的 `plugins/installs.json`。其顶层 `installRecords` map 是安装元数据的持久来源,包括损坏或缺失插件 manifest 的记录。`plugins` 数组是从 manifest 派生的冷注册表缓存。该文件包含请勿编辑警告,并由 `openclaw plugins update`、卸载、诊断和冷插件注册表使用。 +插件安装元数据是机器管理的状态,不是用户配置。安装和更新会把它写入活动 OpenClaw 状态目录下的 `plugins/installs.json`。其顶层 `installRecords` 映射是安装元数据的持久来源,包括损坏或缺失插件清单的记录。`plugins` 数组是由清单派生的冷注册表缓存。该文件包含不要编辑的警告,并会被 `openclaw plugins update`、卸载、诊断和冷插件注册表使用。 -当 OpenClaw 在配置中看到已发布的旧版 `plugins.installs` 记录时,会将它们移动到插件索引中,并移除该配置键;如果任一写入失败,则会保留配置记录,确保安装元数据不会丢失。 +当 OpenClaw 在配置中看到已发布的旧版 `plugins.installs` 记录时,会将它们移动到插件索引并移除该配置键;如果任一写入失败,则保留配置记录,避免安装元数据丢失。 ### 卸载 @@ -251,7 +259,7 @@ openclaw plugins uninstall --dry-run openclaw plugins uninstall --keep-files ``` -`uninstall` 会从 `plugins.entries`、持久化插件索引、插件允许/拒绝列表条目,以及适用时的链接 `plugins.load.paths` 条目中移除插件记录。除非设置了 `--keep-files`,卸载还会移除已跟踪的托管安装目录,前提是该目录位于 OpenClaw 的插件 extensions 根目录内。对于活动的 Memory 插件,Memory 槽位会重置为 `memory-core`。 +`uninstall` 会从 `plugins.entries`、持久化插件索引、插件允许/拒绝列表条目,以及适用时的已链接 `plugins.load.paths` 条目中移除插件记录。除非设置了 `--keep-files`,卸载还会移除跟踪的托管安装目录,前提是该目录位于 OpenClaw 的插件 extensions 根目录内。对于活动的记忆插件,记忆槽会重置为 `memory-core`。 `--keep-config` 作为 `--keep-files` 的已弃用别名受支持。 @@ -267,25 +275,25 @@ openclaw plugins update @openclaw/voice-call@beta openclaw plugins update openclaw-codex-app-server --dangerously-force-unsafe-install ``` -更新会应用于托管插件索引中已跟踪的插件安装,以及 `hooks.internal.installs` 中已跟踪的 hook-pack 安装。 +更新适用于托管插件索引中跟踪的插件安装,以及 `hooks.internal.installs` 中跟踪的 hook-pack 安装。 - - 当你传入插件 id 时,OpenClaw 会复用该插件记录的安装 spec。这意味着先前存储的 dist-tags(例如 `@beta`)和精确固定版本,会继续用于之后的 `update ` 运行。 + + 当你传入插件 id 时,OpenClaw 会复用该插件已记录的安装规范。这意味着先前存储的 dist-tag(例如 `@beta`)和精确固定版本会在后续 `update ` 运行中继续使用。 - 对于 npm 安装,你也可以传入带 dist-tag 或精确版本的显式 npm package spec。OpenClaw 会将该 package 名称解析回已跟踪的插件记录,更新已安装的插件,并记录新的 npm spec 供以后基于 id 的更新使用。 + 对于 npm 安装,你也可以传入带有 dist-tag 或精确版本的显式 npm 包规范。OpenClaw 会将该包名解析回跟踪的插件记录,更新该已安装插件,并记录新的 npm 规范以供未来基于 id 的更新使用。 - 传入不带版本或标签的 npm package 名称,也会解析回已跟踪的插件记录。当插件已固定到精确版本,而你想将其移回注册表的默认发布线时,请使用此方式。 + 传入不带版本或标签的 npm 包名也会解析回跟踪的插件记录。当插件被固定到精确版本,而你希望将它移回注册表的默认发布线时,请使用这种方式。 - - 在执行实时 npm 更新前,OpenClaw 会根据 npm 注册表元数据检查已安装 package 版本。如果已安装版本和记录的 artifact 身份已经匹配解析后的目标,则会跳过更新,不下载、不重新安装,也不重写 `openclaw.json`。 + + 在实时 npm 更新前,OpenClaw 会根据 npm 注册表元数据检查已安装包版本。如果已安装版本和已记录的工件身份已经与解析出的目标匹配,则会跳过更新,不下载、不重新安装,也不重写 `openclaw.json`。 - 当存在已存储的 integrity 哈希且获取到的 artifact 哈希发生变化时,OpenClaw 会将其视为 npm artifact 漂移。交互式 `openclaw plugins update` 命令会打印预期哈希和实际哈希,并在继续前请求确认。非交互式更新辅助程序会失败关闭,除非调用方提供显式的继续策略。 + 当存在已存储的完整性哈希且获取的工件哈希发生变化时,OpenClaw 会将其视为 npm 工件漂移。交互式 `openclaw plugins update` 命令会打印预期哈希和实际哈希,并在继续前请求确认。非交互式更新辅助程序默认失败关闭,除非调用方提供显式继续策略。 - - `--dangerously-force-unsafe-install` 也可用于 `plugins update`,作为插件更新期间内置危险代码扫描误报的紧急覆盖。它仍不会绕过插件 `before_install` 策略阻断或扫描失败阻断,并且只适用于插件更新,不适用于 hook-pack 更新。 + + `--dangerously-force-unsafe-install` 也可用于 `plugins update`,作为插件更新期间内置危险代码扫描误报的紧急覆盖。它仍然不会绕过插件 `before_install` 策略阻断或扫描失败阻断,并且只适用于插件更新,不适用于 hook-pack 更新。 @@ -296,19 +304,19 @@ openclaw plugins inspect openclaw plugins inspect --json ``` -用于单个插件的深度内省。显示身份、加载状态、来源、已注册能力、钩子、工具、命令、服务、Gateway 网关方法、HTTP 路由、策略标志、诊断、安装元数据、bundle 能力,以及检测到的任何 MCP 或 LSP server 支持。 +对单个插件进行深度自省。显示身份、加载状态、来源、已注册能力、钩子、工具、命令、服务、Gateway 网关方法、HTTP 路由、策略标志、诊断信息、安装元数据、包能力,以及任何检测到的 MCP 或 LSP 服务器支持。 -每个插件会按其运行时实际注册的内容分类: +每个插件会按其在运行时实际注册的内容分类: -- **plain-capability** — 一种能力类型(例如仅 provider 的插件) +- **plain-capability** — 一种能力类型(例如仅提供商插件) - **hybrid-capability** — 多种能力类型(例如文本 + 语音 + 图像) -- **hook-only** — 只有钩子,没有能力或 surface +- **hook-only** — 只有钩子,没有能力或表面 - **non-capability** — 有工具/命令/服务,但没有能力 有关能力模型的更多信息,请参阅 [插件形态](/zh-CN/plugins/architecture#plugin-shapes)。 -`--json` 标志会输出适合脚本和审计的机器可读报告。`inspect --all` 会渲染一个全局表格,包含形态、能力种类、兼容性通知、bundle 能力和钩子摘要列。`info` 是 `inspect` 的别名。 +`--json` 标志会输出适合脚本和审计使用的机器可读报告。`inspect --all` 会渲染覆盖整个插件群的表格,包含形态、能力种类、兼容性通知、包能力和钩子摘要列。`info` 是 `inspect` 的别名。 ### Doctor @@ -317,7 +325,7 @@ openclaw plugins inspect --json openclaw plugins doctor ``` -`doctor` 会报告插件加载错误、manifest/设备发现诊断和兼容性通知。当一切正常时,它会打印 `No plugin issues detected.` +`doctor` 会报告插件加载错误、清单/发现诊断信息和兼容性通知。当一切正常时,它会打印 `No plugin issues detected.` 对于缺少 `register`/`activate` 导出等模块形态失败,请使用 `OPENCLAW_PLUGIN_LOAD_DEBUG=1` 重新运行,以便在诊断输出中包含紧凑的导出形态摘要。 @@ -329,12 +337,12 @@ openclaw plugins registry --refresh openclaw plugins registry --json ``` -本地插件注册表是 OpenClaw 为已安装插件身份、启用状态、来源元数据和贡献归属持久化的冷读模型。正常启动、provider owner 查找、渠道设置分类和插件清单可以读取它,而无需导入插件运行时模块。 +本地插件注册表是 OpenClaw 持久化的冷读取模型,用于已安装插件身份、启用状态、来源元数据和贡献所有权。常规启动、提供商所有者查找、渠道设置分类和插件清单可以在不导入插件运行时模块的情况下读取它。 -使用 `plugins registry` 检查持久化注册表是否存在、当前是否最新或是否过期。使用 `--refresh` 可从持久化插件索引、配置策略和 manifest/package 元数据重建它。这是修复路径,不是运行时激活路径。 +使用 `plugins registry` 检查持久化注册表是否存在、当前有效或已过期。使用 `--refresh` 可从持久化插件索引、配置策略和清单/包元数据重建它。这是修复路径,不是运行时激活路径。 -`OPENCLAW_DISABLE_PERSISTED_PLUGIN_REGISTRY=1` 是一个已弃用的紧急兼容性开关,用于注册表读取失败。优先使用 `plugins registry --refresh` 或 `openclaw doctor --fix`;该环境变量回退仅用于迁移推出期间的紧急启动恢复。 +`OPENCLAW_DISABLE_PERSISTED_PLUGIN_REGISTRY=1` 是已弃用的注册表读取失败紧急兼容开关。优先使用 `plugins registry --refresh` 或 `openclaw doctor --fix`;该环境变量回退仅用于迁移推出期间的紧急启动恢复。 ### 市场 @@ -344,7 +352,7 @@ openclaw plugins marketplace list openclaw plugins marketplace list --json ``` -市场列表接受本地市场路径、`marketplace.json` 路径、类似 `owner/repo` 的 GitHub 简写、GitHub repo URL 或 git URL。`--json` 会打印解析后的来源标签,以及已解析的市场 manifest 和插件条目。 +市场列表接受本地市场路径、`marketplace.json` 路径、类似 `owner/repo` 的 GitHub 简写、GitHub 仓库 URL 或 git URL。`--json` 会打印解析出的来源标签,以及解析后的市场清单和插件条目。 ## 相关 diff --git a/docs/zh-CN/concepts/messages.md b/docs/zh-CN/concepts/messages.md index 13070e1a8..9a9bc623c 100644 --- a/docs/zh-CN/concepts/messages.md +++ b/docs/zh-CN/concepts/messages.md @@ -1,22 +1,22 @@ --- read_when: - - 解释入站消息如何变成回复 - - 说明会话、队列模式或流式传输行为 - - 记录推理可见性及其使用影响 -summary: 消息流、会话、队列处理和推理可见性 + - 说明入站消息如何变成回复 + - 说明会话、排队模式或流式传输行为 + - 记录推理可见性和用量影响 +summary: 消息流、会话、排队和推理可见性 title: 消息 x-i18n: - generated_at: "2026-04-27T06:03:45Z" - model: gpt-5.4 + generated_at: "2026-04-29T05:40:11Z" + model: gpt-5.5 provider: openai - source_hash: 0fcfadebb41a96e8e50a818081adf63487234541cf7805f502dae914a39983c0 + source_hash: d5db090a990c48c03f6dc010e211523590d4743aaa0e86fa76bfda0f001e5def source_path: concepts/messages.md - workflow: 15 + workflow: 16 --- -OpenClaw 通过一条由会话解析、队列处理、流式传输、工具执行和推理可见性组成的流水线来处理入站消息。此页面说明了从入站消息到回复的路径。 +OpenClaw 通过一条包含会话解析、排队、流式传输、工具执行和推理可见性的流水线处理入站消息。本页说明从入站消息到回复的路径。 -## 消息流(高级概览) +## 消息流程(高层) ``` Inbound message @@ -26,23 +26,23 @@ Inbound message -> outbound replies (channel limits + chunking) ``` -关键控制项位于配置中: +关键开关位于配置中: -- `messages.*` 用于前缀、队列处理和群组行为。 +- `messages.*` 用于前缀、排队和群组行为。 - `agents.defaults.*` 用于分块流式传输和分块默认值。 -- 渠道覆盖项(`channels.whatsapp.*`、`channels.telegram.*` 等)用于容量上限和流式传输开关。 +- 渠道覆盖项(`channels.whatsapp.*`、`channels.telegram.*` 等)用于上限和流式传输开关。 -完整 schema 请参见[配置](/zh-CN/gateway/configuration)。 +完整 schema 见[配置](/zh-CN/gateway/configuration)。 ## 入站去重 -渠道在重连后可能会重新投递同一条消息。OpenClaw 会维护一个短生命周期缓存,按 channel / account / peer / session / message id 作为键,这样重复投递就不会再次触发智能体运行。 +渠道在重新连接后可能会重新投递同一条消息。OpenClaw 会保留一个短生命周期缓存,以渠道/账号/对端/会话/消息 ID 为键,确保重复投递不会触发另一次智能体运行。 ## 入站防抖 -来自**同一发送者**的快速连续消息,可以通过 `messages.inbound` 合并成一个智能体轮次。防抖按每个渠道 + 会话范围生效,并使用最新的一条消息来处理回复线程 / ID。 +来自**同一发送者**的快速连续消息可以通过 `messages.inbound` 批处理成单个智能体轮次。防抖按渠道 + 对话限定范围,并使用最新消息进行回复串联/ID 关联。 -配置(全局默认值 + 每渠道覆盖): +配置(全局默认值 + 按渠道覆盖): ```json5 { @@ -59,118 +59,116 @@ Inbound message } ``` -说明: +注意: -- 防抖仅适用于**纯文本**消息;媒体 / 附件会立即刷新。 -- 控制命令会绕过防抖,以保持独立 —— **但有一个例外**:当某个渠道显式选择加入同发送者私信合并时(例如 [BlueBubbles `coalesceSameSenderDms`](/zh-CN/channels/bluebubbles#coalescing-split-send-dms-command--url-in-one-composition)),私信命令会在防抖窗口内等待,以便拆开发送的负载可以并入同一个智能体轮次。 +- 防抖适用于**仅文本**消息;媒体/附件会立即刷新。 +- 控制命令会绕过防抖,以便保持独立;**例外情况**是某个渠道显式选择加入同一发送者私信合并(例如 [BlueBubbles `coalesceSameSenderDms`](/zh-CN/channels/bluebubbles#coalescing-split-send-dms-command--url-in-one-composition)),这时私信命令会在防抖窗口内等待,以便拆分发送的载荷可以加入同一个智能体轮次。 ## 会话和设备 -会话归 Gateway 网关所有,而不归客户端所有。 +会话由 Gateway 网关拥有,而不是由客户端拥有。 -- 直接聊天会折叠到智能体主会话键。 -- 群组 / 渠道拥有各自独立的会话键。 -- 会话存储和转录保存在 Gateway 网关主机上。 +- 直接聊天会折叠到智能体主会话键中。 +- 群组/渠道会获得自己的会话键。 +- 会话存储和转录记录位于 Gateway 网关主机上。 -多个设备 / 渠道可以映射到同一个会话,但历史记录不会完全同步回每个客户端。建议:长对话中使用一个主要设备,以避免上下文分叉。Control UI 和 TUI 始终显示由 Gateway 网关支持的会话转录,因此它们是事实来源。 +多个设备/渠道可以映射到同一个会话,但历史记录不会完整同步回每个客户端。建议:长对话使用一个主设备,以避免上下文分歧。Control UI 和 TUI 始终显示由 Gateway 网关支持的会话转录记录,因此它们是真实来源。 -详情请参见:[会话管理](/zh-CN/concepts/session)。 +详情:[会话管理](/zh-CN/concepts/session)。 ## 工具结果元数据 -工具结果中的 `content` 是模型可见的结果。工具结果中的 `details` 是用于 UI 渲染、诊断、媒体发送和插件的运行时元数据。 +工具结果 `content` 是模型可见的结果。工具结果 `details` 是用于 UI 渲染、诊断、媒体投递和插件的运行时元数据。 -OpenClaw 明确保持这一边界: +OpenClaw 会明确保持这条边界: -- `toolResult.details` 会在提供商重放和压缩输入前被剥离。 -- 持久化的会话转录仅保留有界的 `details`;过大的元数据会被替换为紧凑摘要,并标记 `persistedDetailsTruncated: true`。 -- 插件和工具应将模型必须读取的文本放在 `content` 中,而不是只放在 `details` 中。 +- `toolResult.details` 会在提供商重放和压缩输入之前被剥离。 +- 持久化的会话转录记录只保留有界的 `details`;过大的元数据会替换为标记了 `persistedDetailsTruncated: true` 的紧凑摘要。 +- 插件和工具应将模型必须读取的文本放在 `content` 中,而不只是放在 `details` 中。 ## 入站正文和历史上下文 -OpenClaw 将**提示正文**与**命令正文**分开: +OpenClaw 会区分**提示正文**和**命令正文**: -- `Body`:发送给智能体的提示文本。其中可能包含渠道封装和可选的历史包装。 -- `CommandBody`:用于指令 / 命令解析的原始用户文本。 +- `Body`:发送给智能体的提示文本。这可能包含渠道信封和可选历史包装。 +- `CommandBody`:用于指令/命令解析的原始用户文本。 - `RawBody`:`CommandBody` 的旧版别名(为兼容性保留)。 -当某个渠道提供历史记录时,会使用共享包装: +当渠道提供历史记录时,会使用共享包装: - `[Chat messages since your last reply - for context]` - `[Current message - respond to this]` -对于**非直接聊天**(群组 / 渠道 / 房间),**当前消息正文**会加上发送者标签前缀(与历史条目使用相同风格)。这样可以让实时消息和队列 / 历史消息在智能体提示中保持一致。 +对于**非直接聊天**(群组/渠道/房间),**当前消息正文**会加上发送者标签前缀(与历史条目使用相同样式)。这会让实时消息和已排队/历史消息在智能体提示中保持一致。 -历史缓冲区是**仅待处理**的:它们包含那些_未_触发运行的群组消息(例如受提及门控的消息),并且**排除**已经在会话转录中的消息。 +历史缓冲区是**仅待处理**的:它们包含未触发运行的群组消息(例如受提及门控的消息),并**排除**已经在会话转录记录中的消息。 -指令剥离仅适用于**当前消息**部分,因此历史记录保持完整。包装历史的渠道应将 `CommandBody`(或 `RawBody`)设为原始消息文本,并将 `Body` 保持为合并后的提示。历史缓冲区可通过 `messages.groupChat.historyLimit`(全局默认值)以及每渠道覆盖项(如 `channels.slack.historyLimit` 或 `channels.telegram.accounts..historyLimit`)配置(设为 `0` 可禁用)。 +指令剥离只适用于**当前消息**部分,因此历史记录保持完整。包装历史记录的渠道应将 `CommandBody`(或 `RawBody`)设置为原始消息文本,并保持 `Body` 为组合后的提示。历史缓冲区可通过 `messages.groupChat.historyLimit`(全局默认值)以及按渠道覆盖项配置,例如 `channels.slack.historyLimit` 或 `channels.telegram.accounts..historyLimit`(设置为 `0` 可禁用)。 -## 队列处理和后续消息 +## 排队和跟进 -如果某个运行已经处于活动状态,入站消息可以进入队列、导向当前运行,或收集到后续轮次中。 +如果已有运行处于活动状态,入站消息可以排队、转向进入当前运行,或收集起来用于跟进轮次。 - 通过 `messages.queue`(以及 `messages.queue.byChannel`)配置。 -- 模式:`interrupt`、`steer`、`followup`、`collect`,以及 backlog 变体。 +- 模式:`interrupt`、`steer`、`followup`、`collect`,以及积压变体。 -详情请参见:[队列处理](/zh-CN/concepts/queue)。 +详情:[排队](/zh-CN/concepts/queue)。 + +## 渠道运行所有权 + +渠道插件可以在消息进入会话队列之前保持顺序、对输入进行防抖,并应用传输背压。它们不应围绕智能体轮次本身强加单独的超时。一旦消息被路由到会话,长时间运行的工作就由会话、工具和运行时生命周期管理,这样所有渠道都能一致地报告慢轮次并从中恢复。 ## 流式传输、分块和批处理 -分块流式传输会在模型生成文本块时发送部分回复。 -分块会遵守渠道文本限制,并避免拆分带围栏的代码块。 +分块流式传输会在模型生成文本块时发送部分回复。分块会遵守渠道文本限制,并避免拆分围栏代码。 关键设置: - `agents.defaults.blockStreamingDefault`(`on|off`,默认关闭) - `agents.defaults.blockStreamingBreak`(`text_end|message_end`) - `agents.defaults.blockStreamingChunk`(`minChars|maxChars|breakPreference`) -- `agents.defaults.blockStreamingCoalesce`(基于空闲时间的批处理) -- `agents.defaults.humanDelay`(块回复之间模拟人类的停顿) -- 渠道覆盖:`*.blockStreaming` 和 `*.blockStreamingCoalesce`(非 Telegram 渠道需要显式设置 `*.blockStreaming: true`) +- `agents.defaults.blockStreamingCoalesce`(基于空闲的批处理) +- `agents.defaults.humanDelay`(块回复之间的类人暂停) +- 渠道覆盖项:`*.blockStreaming` 和 `*.blockStreamingCoalesce`(非 Telegram 渠道需要显式设置 `*.blockStreaming: true`) -详情请参见:[流式传输 + 分块](/zh-CN/concepts/streaming)。 +详情:[流式传输 + 分块](/zh-CN/concepts/streaming)。 ## 推理可见性和 token -OpenClaw 可以显示或隐藏模型推理: +OpenClaw 可以公开或隐藏模型推理: - `/reasoning on|off|stream` 控制可见性。 -- 一旦模型生成了推理内容,它仍会计入 token 使用量。 +- 当模型生成推理内容时,它仍会计入 token 用量。 - Telegram 支持将推理流式传输到草稿气泡中。 -详情请参见:[Thinking + 推理指令](/zh-CN/tools/thinking) 和 [Token 使用](/zh-CN/reference/token-use)。 +详情:[思考 + 推理指令](/zh-CN/tools/thinking)和 [Token 使用](/zh-CN/reference/token-use)。 -## 前缀、线程和回复 +## 前缀、串联和回复 -出站消息格式由 `messages` 统一控制: +出站消息格式集中在 `messages` 中: - `messages.responsePrefix`、`channels..responsePrefix` 和 `channels..accounts..responsePrefix`(出站前缀级联),以及 `channels.whatsapp.messagePrefix`(WhatsApp 入站前缀) -- 通过 `replyToMode` 和每渠道默认值进行回复线程控制 +- 通过 `replyToMode` 和按渠道默认值实现回复串联 -详情请参见:[配置](/zh-CN/gateway/config-agents#messages) 和各渠道文档。 +详情:[配置](/zh-CN/gateway/config-agents#messages)和渠道文档。 ## 静默回复 -精确的静默标记 `NO_REPLY` / `no_reply` 表示“不要发送用户可见回复”。 -当某一轮同时带有待发送的工具媒体(例如生成的 TTS 音频)时,OpenClaw -会剥离静默文本,但仍发送媒体附件。 -OpenClaw 会按会话类型解析该行为: +精确的静默 token `NO_REPLY` / `no_reply` 表示“不要投递用户可见的回复”。当某个轮次还有待处理的工具媒体(例如生成的 TTS 音频)时,OpenClaw 会剥离静默文本,但仍会投递媒体附件。OpenClaw 按对话类型解析该行为: -- 直接会话默认不允许静默,并会将纯静默回复重写为简短的可见回退文本。 -- 群组 / 渠道默认允许静默。 +- 直接对话默认不允许静默,并会将裸静默回复改写为简短可见的兜底回复。 +- 群组/渠道默认允许静默。 - 内部编排默认允许静默。 -对于发生在任何助手回复之前的非直接聊天内部运行器失败,OpenClaw 也会使用静默回复,因此群组 / 渠道不会看到 Gateway 网关错误样板文本。直接聊天默认显示紧凑的失败说明;只有当 `/verbose` 为 `on` 或 `full` 时,才会显示原始运行器详情。 +OpenClaw 还会将静默回复用于非直接聊天中发生在任何助手回复之前的内部运行器失败,这样群组/渠道不会看到 Gateway 网关错误样板。直接聊天默认显示紧凑的失败文案;只有当 `/verbose` 为 `on` 或 `full` 时,才会显示原始运行器详情。 -默认值位于 `agents.defaults.silentReply` 和 -`agents.defaults.silentReplyRewrite`;`surfaces..silentReply` 和 -`surfaces..silentReplyRewrite` 可按界面进行覆盖。 +默认值位于 `agents.defaults.silentReply` 和 `agents.defaults.silentReplyRewrite` 下;`surfaces..silentReply` 和 `surfaces..silentReplyRewrite` 可以按 surface 覆盖它们。 -当父会话存在一个或多个待处理的已生成子智能体运行时,所有界面上的纯静默回复都会被丢弃,而不是被重写,这样父级会保持静默,直到子级完成事件发送真实回复。 +当父会话有一个或多个待处理的已生成子智能体运行时,所有 surface 上的裸静默回复都会被丢弃,而不是被改写,因此父会话会保持安静,直到子完成事件投递真实回复。 -## 相关内容 +## 相关 -- [Streaming](/zh-CN/concepts/streaming) — 实时消息发送 -- [Retry](/zh-CN/concepts/retry) — 消息发送重试行为 -- [Queue](/zh-CN/concepts/queue) — 消息处理队列 -- [Channels](/zh-CN/channels) — 消息平台集成 +- [流式传输](/zh-CN/concepts/streaming) — 实时消息投递 +- [重试](/zh-CN/concepts/retry) — 消息投递重试行为 +- [队列](/zh-CN/concepts/queue) — 消息处理队列 +- [渠道](/zh-CN/channels) — 消息平台集成 diff --git a/docs/zh-CN/gateway/config-channels.md b/docs/zh-CN/gateway/config-channels.md index 611be8de3..ecc407c0a 100644 --- a/docs/zh-CN/gateway/config-channels.md +++ b/docs/zh-CN/gateway/config-channels.md @@ -1,29 +1,26 @@ --- read_when: - - 配置渠道插件(身份验证、访问控制、多账户) - - 每个渠道配置键的故障排除 + - 配置渠道插件(认证、访问控制、多账户) + - 按渠道配置键名的故障排除 - 审计私信策略、群组策略或提及门控 -summary: 渠道配置:Slack、Discord、Telegram、WhatsApp、Matrix、iMessage 等渠道的访问控制、配对和每渠道密钥 +summary: 渠道配置:Slack、Discord、Telegram、WhatsApp、Matrix、iMessage 等渠道中的访问控制、配对和各渠道密钥 title: 配置 — 渠道 x-i18n: - generated_at: "2026-04-28T13:50:58Z" + generated_at: "2026-04-29T05:40:14Z" model: gpt-5.5 provider: openai - source_hash: e56a515d15fc6122d4de6cb30b81d969da9d72d9bb8fbba8a19542af35102058 + source_hash: 27393684cef61ab3599f9793cc9e691239a5bb5852ad638b3c2dd20de76ee9fa source_path: gateway/config-channels.md workflow: 16 --- -`channels.*` 下的按渠道配置键。涵盖私信和群组访问、 -多账号设置、提及门控,以及 Slack、Discord、 -Telegram、WhatsApp、Matrix、iMessage 和其他内置渠道插件的按渠道键。 +每个渠道的配置键位于 `channels.*` 下。涵盖私信和群组访问、多账号设置、提及门控,以及 Slack、Discord、Telegram、WhatsApp、Matrix、iMessage 和其他内置渠道插件的每渠道键。 -对于智能体、工具、Gateway 网关运行时以及其他顶级键,请参见 -[配置参考](/zh-CN/gateway/configuration-reference)。 +对于智能体、工具、Gateway 网关运行时和其他顶级键,请参阅[配置参考](/zh-CN/gateway/configuration-reference)。 ## 渠道 -每个渠道会在其配置段存在时自动启动(除非设置了 `enabled: false`)。 +每个渠道在其配置段存在时会自动启动(除非 `enabled: false`)。 ### 私信和群组访问 @@ -31,21 +28,21 @@ Telegram、WhatsApp、Matrix、iMessage 和其他内置渠道插件的按渠道 | 私信策略 | 行为 | | ------------------- | --------------------------------------------------------------- | -| `pairing`(默认) | 未知发送者会收到一次性配对码;所有者必须批准 | -| `allowlist` | 仅允许 `allowFrom` 中的发送者(或已配对的允许存储中的发送者) | -| `open` | 允许所有传入私信(需要 `allowFrom: ["*"]`) | -| `disabled` | 忽略所有传入私信 | +| `pairing`(默认) | 未知发送者会获得一次性配对码;所有者必须批准 | +| `allowlist` | 仅允许 `allowFrom` 中的发送者(或配对允许存储中的发送者) | +| `open` | 允许所有入站私信(需要 `allowFrom: ["*"]`) | +| `disabled` | 忽略所有入站私信 | -| 群组策略 | 行为 | -| --------------------- | ------------------------------------------------------ | -| `allowlist`(默认) | 仅允许匹配已配置允许列表的群组 | -| `open` | 绕过群组允许列表(提及门控仍然适用) | -| `disabled` | 阻止所有群组/房间消息 | +| 群组策略 | 行为 | +| --------------------- | ------------------------------------------------ | +| `allowlist`(默认) | 仅允许匹配已配置允许列表的群组 | +| `open` | 绕过群组允许列表(提及门控仍然适用) | +| `disabled` | 阻止所有群组/房间消息 | `channels.defaults.groupPolicy` 会在提供商的 `groupPolicy` 未设置时设置默认值。 -配对码会在 1 小时后过期。待处理的私信配对请求上限为**每个渠道 3 个**。 -如果提供商块完全缺失(不存在 `channels.`),运行时群组策略会回退到 `allowlist`(故障关闭),并在启动时发出警告。 +配对码在 1 小时后过期。待处理的私信配对请求限制为**每个渠道 3 个**。 +如果提供商块完全缺失(不存在 `channels.`),运行时群组策略会回退到 `allowlist`(失败关闭),并在启动时发出警告。 ### 渠道模型覆盖 @@ -73,7 +70,7 @@ Telegram、WhatsApp、Matrix、iMessage 和其他内置渠道插件的按渠道 ### 渠道默认值和心跳 -使用 `channels.defaults` 为各提供商共享群组策略和心跳行为: +使用 `channels.defaults` 为各提供商配置共享的群组策略和心跳行为: ```json5 { @@ -91,10 +88,10 @@ Telegram、WhatsApp、Matrix、iMessage 和其他内置渠道插件的按渠道 } ``` -- `channels.defaults.groupPolicy`:提供商级 `groupPolicy` 未设置时的回退群组策略。 -- `channels.defaults.contextVisibility`:所有渠道的默认补充上下文可见性模式。取值:`all`(默认,包含所有引用/线程/历史上下文)、`allowlist`(仅包含来自允许列表发送者的上下文)、`allowlist_quote`(与 allowlist 相同,但保留显式引用/回复上下文)。按渠道覆盖:`channels..contextVisibility`。 -- `channels.defaults.heartbeat.showOk`:在心跳输出中包含健康渠道 Status。 -- `channels.defaults.heartbeat.showAlerts`:在心跳输出中包含降级/错误 Status。 +- `channels.defaults.groupPolicy`:提供商级别的 `groupPolicy` 未设置时的备用群组策略。 +- `channels.defaults.contextVisibility`:所有渠道的默认补充上下文可见性模式。值:`all`(默认,包含所有引用/线程/历史上下文)、`allowlist`(仅包含来自允许列表发送者的上下文)、`allowlist_quote`(与允许列表相同,但保留显式引用/回复上下文)。每渠道覆盖:`channels..contextVisibility`。 +- `channels.defaults.heartbeat.showOk`:在心跳输出中包含健康的渠道状态。 +- `channels.defaults.heartbeat.showAlerts`:在心跳输出中包含降级/错误状态。 - `channels.defaults.heartbeat.useIndicator`:渲染紧凑的指示器样式心跳输出。 ### WhatsApp @@ -157,10 +154,10 @@ WhatsApp 通过 Gateway 网关的 Web 渠道(Baileys Web)运行。当存在 } ``` -- 出站命令默认使用账号 `default`(如果存在);否则使用第一个已配置账号 ID(排序后)。 -- 可选的 `channels.whatsapp.defaultAccount` 会在其匹配已配置账号 ID 时覆盖该回退默认账号选择。 -- 旧版单账号 Baileys 认证目录会由 `openclaw doctor` 迁移到 `whatsapp/default`。 -- 按账号覆盖:`channels.whatsapp.accounts..sendReadReceipts`、`channels.whatsapp.accounts..dmPolicy`、`channels.whatsapp.accounts..allowFrom`。 +- 出站命令默认使用账号 `default`(如果存在);否则使用第一个已配置的账号 ID(排序后)。 +- 可选的 `channels.whatsapp.defaultAccount` 会在匹配已配置账号 ID 时覆盖该备用默认账号选择。 +- 旧版单账号 Baileys 凭证目录会由 `openclaw doctor` 迁移到 `whatsapp/default`。 +- 每账号覆盖:`channels.whatsapp.accounts..sendReadReceipts`、`channels.whatsapp.accounts..dmPolicy`、`channels.whatsapp.accounts..allowFrom`。 @@ -219,14 +216,14 @@ WhatsApp 通过 Gateway 网关的 Web 渠道(Baileys Web)运行。当存在 } ``` -- 机器人令牌:`channels.telegram.botToken` 或 `channels.telegram.tokenFile`(仅限常规文件;符号链接会被拒绝),默认账号的回退值为 `TELEGRAM_BOT_TOKEN`。 -- `apiRoot` 仅是 Telegram Bot API 根地址。使用 `https://api.telegram.org` 或你的自托管/代理根地址,不要使用 `https://api.telegram.org/bot`;`openclaw doctor --fix` 会移除意外的尾随 `/bot` 后缀。 -- 可选的 `channels.telegram.defaultAccount` 会在其匹配已配置账号 ID 时覆盖默认账号选择。 -- 在多账号设置(2 个以上账号 ID)中,设置显式默认值(`channels.telegram.defaultAccount` 或 `channels.telegram.accounts.default`),以避免回退路由;当缺失或无效时,`openclaw doctor` 会发出警告。 -- `configWrites: false` 会阻止 Telegram 发起的配置写入(超级群组 ID 迁移、`/config set|unset`)。 -- 顶级 `bindings[]` 条目使用 `type: "acp"` 为论坛话题配置持久 ACP 绑定(在 `match.peer.id` 中使用规范的 `chatId:topic:topicId`)。字段语义在 [ACP 智能体](/zh-CN/tools/acp-agents#channel-specific-settings) 中共享。 -- Telegram 流式预览使用 `sendMessage` + `editMessageText`(适用于直接聊天和群聊)。 -- 重试策略:请参见[重试策略](/zh-CN/concepts/retry)。 +- Bot token:`channels.telegram.botToken` 或 `channels.telegram.tokenFile`(仅限普通文件;拒绝符号链接),默认账号的备用值为 `TELEGRAM_BOT_TOKEN`。 +- `apiRoot` 仅是 Telegram Bot API 根地址。使用 `https://api.telegram.org` 或你的自托管/代理根地址,不要使用 `https://api.telegram.org/bot`;`openclaw doctor --fix` 会移除意外尾随的 `/bot` 后缀。 +- 可选的 `channels.telegram.defaultAccount` 会在匹配已配置账号 ID 时覆盖默认账号选择。 +- 在多账号设置中(2 个以上账号 ID),设置显式默认值(`channels.telegram.defaultAccount` 或 `channels.telegram.accounts.default`)以避免备用路由;当它缺失或无效时,`openclaw doctor` 会发出警告。 +- `configWrites: false` 会阻止由 Telegram 发起的配置写入(超级群组 ID 迁移、`/config set|unset`)。 +- 顶级 `bindings[]` 条目配合 `type: "acp"` 为论坛主题配置持久 ACP 绑定(在 `match.peer.id` 中使用规范的 `chatId:topic:topicId`)。字段语义在 [ACP 智能体](/zh-CN/tools/acp-agents#channel-specific-settings)中共享。 +- Telegram 流式预览使用 `sendMessage` + `editMessageText`(适用于直接聊天和群组聊天)。 +- 重试策略:请参阅[重试策略](/zh-CN/concepts/retry)。 ### Discord @@ -328,37 +325,37 @@ WhatsApp 通过 Gateway 网关的 Web 渠道(Baileys Web)运行。当存在 } ``` -- 令牌:`channels.discord.token`,默认账户可回退到 `DISCORD_BOT_TOKEN`。 -- 提供显式 Discord `token` 的直接出站调用会使用该令牌执行调用;账户重试/策略设置仍来自活动运行时快照中选定的账户。 -- 可选的 `channels.discord.defaultAccount` 在匹配已配置账户 ID 时会覆盖默认账户选择。 -- 使用 `user:`(私信)或 `channel:`(服务器频道)作为投递目标;裸数字 ID 会被拒绝。 -- 服务器 slug 为小写,并将空格替换为 `-`;频道键使用 slug 化后的名称(不含 `#`)。优先使用服务器 ID。 -- 默认忽略机器人发送的消息。`allowBots: true` 会启用这些消息;使用 `allowBots: "mentions"` 仅接受提及该机器人的机器人消息(仍会过滤自己的消息)。 -- `channels.discord.guilds..ignoreOtherMentions`(以及频道覆盖项)会丢弃提及其他用户或角色但未提及该机器人的消息(不包括 @everyone/@here)。 -- `maxLinesPerMessage`(默认 17)会拆分过高的消息,即使消息少于 2000 个字符。 +- 令牌:`channels.discord.token`,默认账号可回退使用 `DISCORD_BOT_TOKEN`。 +- 提供显式 Discord `token` 的直接出站调用会使用该令牌进行调用;账号重试/策略设置仍来自活动运行时快照中选定的账号。 +- 可选的 `channels.discord.defaultAccount` 在匹配已配置账号 ID 时会覆盖默认账号选择。 +- 使用 `user:`(私信)或 `channel:`(公会渠道)作为投递目标;裸数字 ID 会被拒绝。 +- 公会 slug 为小写,并将空格替换为 `-`;渠道键使用 slug 化后的名称(不含 `#`)。优先使用公会 ID。 +- 默认会忽略机器人发送的消息。`allowBots: true` 会启用它们;使用 `allowBots: "mentions"` 仅接受提及该机器人的机器人消息(自己的消息仍会被过滤)。 +- `channels.discord.guilds..ignoreOtherMentions`(以及渠道覆盖项)会丢弃提及其他用户或角色但未提及该机器人的消息(不包括 @everyone/@here)。 +- `maxLinesPerMessage`(默认 17)即使在低于 2000 个字符时也会拆分较高的消息。 - `channels.discord.threadBindings` 控制 Discord 线程绑定路由: - `enabled`:Discord 对线程绑定会话功能的覆盖(`/focus`、`/unfocus`、`/agents`、`/session idle`、`/session max-age`,以及绑定投递/路由) - - `idleHours`:Discord 对非活动自动取消聚焦小时数的覆盖(`0` 表示禁用) - - `maxAgeHours`:Discord 对硬性最长生命周期小时数的覆盖(`0` 表示禁用) - - `spawnSubagentSessions`:`sessions_spawn({ thread: true })` 自动创建/绑定线程的选择加入开关 -- 顶层 `bindings[]` 中带有 `type: "acp"` 的条目会为渠道和线程配置持久 ACP 绑定(在 `match.peer.id` 中使用频道/线程 ID)。字段语义在 [ACP 智能体](/zh-CN/tools/acp-agents#channel-specific-settings) 中共享。 + - `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 容器的强调色。 -- `channels.discord.voice` 启用 Discord 语音频道对话,以及可选的自动加入 + LLM + TTS 覆盖。 -- `channels.discord.voice.model` 可选地覆盖用于 Discord 语音频道响应的 LLM 模型。 +- `channels.discord.voice` 启用 Discord 语音渠道对话,以及可选的自动加入 + LLM + TTS 覆盖。 +- `channels.discord.voice.model` 可选地覆盖用于 Discord 语音渠道响应的 LLM 模型。 - `channels.discord.voice.daveEncryption` 和 `channels.discord.voice.decryptionFailureTolerance` 会传递给 `@discordjs/voice` DAVE 选项(默认分别为 `true` 和 `24`)。 -- OpenClaw 还会在重复解密失败后尝试通过离开/重新加入语音会话来恢复语音接收。 +- OpenClaw 还会在重复解密失败后,通过离开/重新加入语音会话来尝试恢复语音接收。 - `channels.discord.streaming` 是规范的流模式键。旧版 `streamMode` 和布尔值 `streaming` 会自动迁移。 -- `channels.discord.autoPresence` 将运行时可用性映射到机器人在线状态(healthy => online、degraded => idle、exhausted => dnd),并允许可选的状态文本覆盖。 -- `channels.discord.dangerouslyAllowNameMatching` 会重新启用可变名称/tag 匹配(应急兼容模式)。 -- `channels.discord.execApprovals`:Discord 原生 exec 审批投递和审批者授权。 - - `enabled`:`true`、`false` 或 `"auto"`(默认)。在自动模式下,当可以从 `approvers` 或 `commands.ownerAllowFrom` 解析审批者时,exec 审批会激活。 - - `approvers`:允许审批 exec 请求的 Discord 用户 ID。省略时回退到 `commands.ownerAllowFrom`。 +- `channels.discord.autoPresence` 将运行时可用性映射到机器人在线状态(healthy => online,degraded => idle,exhausted => dnd),并允许可选的状态文本覆盖。 +- `channels.discord.dangerouslyAllowNameMatching` 会重新启用可变名称/标签匹配(紧急兼容模式)。 +- `channels.discord.execApprovals`:Discord 原生 exec 审批投递和审批人授权。 + - `enabled`:`true`、`false` 或 `"auto"`(默认)。在自动模式下,当可从 `approvers` 或 `commands.ownerAllowFrom` 解析审批人时,exec 审批会激活。 + - `approvers`:允许批准 exec 请求的 Discord 用户 ID。省略时回退到 `commands.ownerAllowFrom`。 - `agentFilter`:可选的智能体 ID 允许列表。省略则转发所有智能体的审批。 - `sessionFilter`:可选的会话键模式(子字符串或正则表达式)。 - - `target`:发送审批提示的位置。`"dm"`(默认)发送到审批者私信,`"channel"` 发送到来源频道,`"both"` 同时发送到两者。当 target 包含 `"channel"` 时,按钮只能由已解析的审批者使用。 + - `target`:发送审批提示的位置。`"dm"`(默认)发送到审批人私信,`"channel"` 发送到来源渠道,`"both"` 同时发送到两者。当目标包含 `"channel"` 时,按钮只能由已解析的审批人使用。 - `cleanupAfterResolve`:当为 `true` 时,会在批准、拒绝或超时后删除审批私信。 -**反应通知模式:**`off`(无)、`own`(机器人的消息,默认)、`all`(所有消息)、`allowlist`(来自所有消息上的 `guilds..users`)。 +**反应通知模式:** `off`(无)、`own`(机器人的消息,默认)、`all`(所有消息)、`allowlist`(来自所有消息上的 `guilds..users`)。 ### Google Chat @@ -389,11 +386,11 @@ WhatsApp 通过 Gateway 网关的 Web 渠道(Baileys Web)运行。当存在 } ``` -- 服务账户 JSON:内联(`serviceAccount`)或基于文件(`serviceAccountFile`)。 -- 也支持服务账户 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 @@ -465,35 +462,35 @@ WhatsApp 通过 Gateway 网关的 Web 渠道(Baileys Web)运行。当存在 } ``` -- **Socket mode** 需要同时配置 `botToken` 和 `appToken`(默认账户环境变量回退为 `SLACK_BOT_TOKEN` + `SLACK_APP_TOKEN`)。 -- **HTTP 模式** 需要 `botToken` 加 `signingSecret`(在根级或每个账户中)。 +- **Socket mode** 需要同时提供 `botToken` 和 `appToken`(默认账号环境变量回退为 `SLACK_BOT_TOKEN` + `SLACK_APP_TOKEN`)。 +- **HTTP mode** 需要 `botToken` 加 `signingSecret`(位于根级或按账号配置)。 - `socketMode` 会将 Slack SDK Socket Mode 传输调优传递给公共 Bolt receiver API。仅在调查 ping/pong 超时或陈旧 websocket 行为时使用它。 - `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` 会自动迁移。 +- Slack 账号快照会公开按凭证划分的来源/状态字段,例如 `botTokenSource`、`botTokenStatus`、`appTokenStatus`,以及在 HTTP mode 下的 `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:` 作为投递目标。 -**反应通知模式:**`off`、`own`(默认)、`all`、`allowlist`(来自 `reactionAllowlist`)。 +**反应通知模式:** `off`、`own`(默认)、`all`、`allowlist`(来自 `reactionAllowlist`)。 -**线程会话隔离:**`thread.historyScope` 是按线程(默认)或在频道间共享。`thread.inheritParent` 会将父频道转录复制到新线程。 +**线程会话隔离:** `thread.historyScope` 是按线程(默认)或在渠道内共享。`thread.inheritParent` 会将父渠道转录复制到新线程。 -- Slack 原生流式传输以及 Slack 助手风格的 “is typing...” 线程状态需要回复线程目标。顶层私信默认保持在线程外,因此它们使用 `typingReaction` 或普通投递,而不是线程风格预览。 -- `typingReaction` 会在回复运行时向入站 Slack 消息添加临时反应,并在完成后移除。使用 Slack emoji shortcode,例如 `"hourglass_flowing_sand"`。 -- `channels.slack.execApprovals`:Slack 原生 exec 审批投递和审批者授权。与 Discord 相同的 schema:`enabled`(`true`/`false`/`"auto"`)、`approvers`(Slack 用户 ID)、`agentFilter`、`sessionFilter` 和 `target`(`"dm"`、`"channel"` 或 `"both"`)。 +- Slack 原生流式传输加上 Slack 助手风格的 “is typing...” 线程状态需要回复线程目标。顶层私信默认保持在线程外,因此它们使用 `typingReaction` 或普通投递,而不是线程风格预览。 +- `typingReaction` 会在回复运行时向传入的 Slack 消息添加临时反应,并在完成时移除它。使用 Slack 表情短码,例如 `"hourglass_flowing_sand"`。 +- `channels.slack.execApprovals`:Slack 原生 exec 审批投递和审批人授权。与 Discord 相同的架构:`enabled`(`true`/`false`/`"auto"`)、`approvers`(Slack 用户 ID)、`agentFilter`、`sessionFilter` 和 `target`(`"dm"`、`"channel"` 或 `"both"`)。 -| 操作组 | 默认值 | 说明 | +| 操作组 | 默认值 | 备注 | | ------------ | ------- | ---------------------- | -| reactions | 启用 | 反应 + 列出反应 | -| messages | 启用 | 读取/发送/编辑/删除 | -| pins | 启用 | 置顶/取消置顶/列出 | -| memberInfo | 启用 | 成员信息 | -| emojiList | 启用 | 自定义 emoji 列表 | +| reactions | enabled | 反应 + 列出反应 | +| messages | enabled | 读取/发送/编辑/删除 | +| pins | enabled | 置顶/取消置顶/列出 | +| memberInfo | enabled | 成员信息 | +| emojiList | enabled | 自定义表情列表 | ### Mattermost -Mattermost 作为插件提供:`openclaw plugins install @openclaw/mattermost`。 +在当前 OpenClaw 版本中,Mattermost 作为内置插件提供。较旧版本或自定义构建可以通过 `openclaw plugins install @openclaw/mattermost` 安装当前 npm 包;如果 npm 报告 OpenClaw 拥有的包已弃用,请使用内置插件或本地检出,直到发布更新的 npm 包。 ```json5 { @@ -523,18 +520,18 @@ Mattermost 作为插件提供:`openclaw plugins install @openclaw/mattermost` } ``` -聊天模式:`oncall`(在 @-mention 时响应,默认)、`onmessage`(每条消息)、`onchar`(以触发前缀开头的消息)。 +聊天模式:`oncall`(在 @ 提及时响应,默认)、`onmessage`(每条消息)、`onchar`(以触发前缀开头的消息)。 启用 Mattermost 原生命令时: - `commands.callbackPath` 必须是路径(例如 `/api/channels/mattermost/command`),而不是完整 URL。 -- `commands.callbackUrl` 必须解析到 OpenClaw Gateway 网关端点,并可从 Mattermost 服务器访问。 -- 原生 slash 回调使用 Mattermost 在 slash 命令注册期间返回的每命令令牌进行身份验证。如果注册失败或没有命令被激活,OpenClaw 会以 `Unauthorized: invalid command token.` 拒绝回调。 +- `commands.callbackUrl` 必须解析到 OpenClaw Gateway 网关端点,并且可从 Mattermost 服务器访问。 +- 原生斜杠回调使用 Mattermost 在斜杠命令注册期间返回的按命令令牌进行身份验证。如果注册失败或没有激活任何命令,OpenClaw 会拒绝回调并返回 `Unauthorized: invalid command token.` - 对于私有/tailnet/内部回调主机,Mattermost 可能要求 `ServiceSettings.AllowedUntrustedInternalConnections` 包含回调主机/域名。使用主机/域名值,而不是完整 URL。 -- `channels.mattermost.configWrites`:允许或拒绝 Mattermost 发起的配置写入。 -- `channels.mattermost.requireMention`:在频道中回复前要求 `@mention`。 -- `channels.mattermost.groups..requireMention`:按频道的提及门控覆盖(`"*"` 表示默认值)。 -- 可选的 `channels.mattermost.defaultAccount` 在匹配已配置账户 ID 时会覆盖默认账户选择。 +- `channels.mattermost.configWrites`:允许或拒绝由 Mattermost 发起的配置写入。 +- `channels.mattermost.requireMention`:在渠道中回复前要求 `@mention`。 +- `channels.mattermost.groups..requireMention`:按渠道提及门控覆盖(`"*"` 表示默认)。 +- 可选的 `channels.mattermost.defaultAccount` 在匹配已配置账号 ID 时会覆盖默认账号选择。 ### Signal @@ -555,11 +552,11 @@ Mattermost 作为插件提供:`openclaw plugins install @openclaw/mattermost` } ``` -**回应通知模式:**`off`、`own`(默认)、`all`、`allowlist`(来自 `reactionAllowlist`)。 +**回应通知模式:** `off`、`own`(默认)、`all`、`allowlist`(来自 `reactionAllowlist`)。 -- `channels.signal.account`:将渠道启动固定到特定 Signal 账户身份。 +- `channels.signal.account`:将渠道启动固定到特定的 Signal 账户身份。 - `channels.signal.configWrites`:允许或拒绝由 Signal 发起的配置写入。 -- 可选的 `channels.signal.defaultAccount` 会在匹配已配置的账户 ID 时覆盖默认账户选择。 +- 可选的 `channels.signal.defaultAccount` 在匹配已配置的账户 ID 时,会覆盖默认账户选择。 ### BlueBubbles @@ -578,10 +575,10 @@ BlueBubbles 是推荐的 iMessage 路径(由插件支持,在 `channels.blueb } ``` -- 此处涵盖的核心键路径:`channels.bluebubbles`、`channels.bluebubbles.dmPolicy`。 -- 可选的 `channels.bluebubbles.defaultAccount` 会在匹配已配置的账户 ID 时覆盖默认账户选择。 -- 顶层 `bindings[]` 条目使用 `type: "acp"` 时,可以将 BlueBubbles 对话绑定到持久 ACP 会话。在 `match.peer.id` 中使用 BlueBubbles 句柄或目标字符串(`chat_id:*`、`chat_guid:*`、`chat_identifier:*`)。共享字段语义见:[ACP 智能体](/zh-CN/tools/acp-agents#channel-specific-settings)。 -- 完整 BlueBubbles 渠道配置记录在 [BlueBubbles](/zh-CN/channels/bluebubbles)。 +- 这里涵盖的核心键路径:`channels.bluebubbles`、`channels.bluebubbles.dmPolicy`。 +- 可选的 `channels.bluebubbles.defaultAccount` 在匹配已配置的账户 ID 时,会覆盖默认账户选择。 +- 顶层 `bindings[]` 条目带有 `type: "acp"` 时,可以将 BlueBubbles 对话绑定到持久 ACP 会话。请在 `match.peer.id` 中使用 BlueBubbles 句柄或目标字符串(`chat_id:*`、`chat_guid:*`、`chat_identifier:*`)。共享字段语义:[ACP 智能体](/zh-CN/tools/acp-agents#channel-specific-settings)。 +- 完整的 BlueBubbles 渠道配置记录在 [BlueBubbles](/zh-CN/channels/bluebubbles) 中。 ### iMessage @@ -609,15 +606,15 @@ OpenClaw 会生成 `imsg rpc`(通过 stdio 的 JSON-RPC)。不需要守护 } ``` -- 可选的 `channels.imessage.defaultAccount` 会在匹配已配置的账户 ID 时覆盖默认账户选择。 +- 可选的 `channels.imessage.defaultAccount` 在匹配已配置的账户 ID 时,会覆盖默认账户选择。 -- 需要对 Messages 数据库启用完全磁盘访问权限。 +- 需要对 Messages 数据库授予完全磁盘访问权限。 - 优先使用 `chat_id:` 目标。使用 `imsg chats --limit 20` 列出聊天。 -- `cliPath` 可以指向 SSH 包装器;设置 `remoteHost`(`host` 或 `user@host`)用于通过 SCP 获取附件。 -- `attachmentRoots` 和 `remoteAttachmentRoots` 限制入站附件路径(默认:`/Users/*/Library/Messages/Attachments`)。 -- SCP 使用严格的主机密钥检查,因此请确保中继主机密钥已经存在于 `~/.ssh/known_hosts` 中。 +- `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` 中使用规范化句柄或显式聊天目标(`chat_id:*`、`chat_guid:*`、`chat_identifier:*`)。共享字段语义见:[ACP 智能体](/zh-CN/tools/acp-agents#channel-specific-settings)。 +- 顶层 `bindings[]` 条目带有 `type: "acp"` 时,可以将 iMessage 对话绑定到持久 ACP 会话。请在 `match.peer.id` 中使用规范化句柄或显式聊天目标(`chat_id:*`、`chat_guid:*`、`chat_identifier:*`)。共享字段语义:[ACP 智能体](/zh-CN/tools/acp-agents#channel-specific-settings)。 @@ -661,20 +658,20 @@ Matrix 由插件支持,并在 `channels.matrix` 下配置。 ``` - 令牌认证使用 `accessToken`;密码认证使用 `userId` + `password`。 -- `channels.matrix.proxy` 通过显式 HTTP(S) 代理路由 Matrix HTTP 流量。命名账户可以用 `channels.matrix.accounts..proxy` 覆盖它。 -- `channels.matrix.network.dangerouslyAllowPrivateNetwork` 允许私有/内部 homeserver。`proxy` 和此网络选择加入是独立控制项。 +- `channels.matrix.proxy` 会通过显式 HTTP(S) 代理路由 Matrix HTTP 流量。命名账户可以用 `channels.matrix.accounts..proxy` 覆盖它。 +- `channels.matrix.network.dangerouslyAllowPrivateNetwork` 允许私有/内部 homeserver。`proxy` 和这个网络选择加入项是彼此独立的控制项。 - `channels.matrix.defaultAccount` 在多账户设置中选择首选账户。 -- `channels.matrix.autoJoin` 默认为 `off`,因此受邀房间和新的私信式邀请会被忽略,直到你设置带 `autoJoinAllowlist` 的 `autoJoin: "allowlist"`,或设置 `autoJoin: "always"`。 -- `channels.matrix.execApprovals`:Matrix 原生 exec 审批投递和审批者授权。 - - `enabled`:`true`、`false` 或 `"auto"`(默认)。在自动模式下,当可以从 `approvers` 或 `commands.ownerAllowFrom` 解析审批者时,exec 审批会激活。 - - `approvers`:允许批准 exec 请求的 Matrix 用户 ID(例如 `@owner:example.org`)。 - - `agentFilter`:可选智能体 ID 允许列表。省略则转发所有智能体的审批。 - - `sessionFilter`:可选会话键模式(子字符串或正则表达式)。 - - `target`:审批提示发送位置。`"dm"`(默认)、`"channel"`(来源房间)或 `"both"`。 +- `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 允许列表。省略则转发所有智能体的审批。 + - `sessionFilter`:可选的会话键模式(子字符串或正则表达式)。 + - `target`:发送审批提示的位置。`"dm"`(默认)、`"channel"`(来源房间)或 `"both"`。 - 按账户覆盖:`channels.matrix.accounts..execApprovals`。 -- `channels.matrix.dm.sessionScope` 控制 Matrix 私信如何分组为会话:`per-user`(默认)按路由对端共享,而 `per-room` 会隔离每个私信房间。 -- Matrix Status 探测和实时目录查找使用与运行时流量相同的代理策略。 -- 完整 Matrix 配置、目标规则和设置示例记录在 [Matrix](/zh-CN/channels/matrix)。 +- `channels.matrix.dm.sessionScope` 控制 Matrix 私信如何分组成会话:`per-user`(默认)按路由后的对端共享,而 `per-room` 会隔离每个私信房间。 +- Matrix Status 探针和实时目录查找使用与运行时流量相同的代理策略。 +- 完整的 Matrix 配置、目标规则和设置示例记录在 [Matrix](/zh-CN/channels/matrix) 中。 ### Microsoft Teams @@ -693,8 +690,8 @@ Microsoft Teams 由插件支持,并在 `channels.msteams` 下配置。 } ``` -- 此处涵盖的核心键路径:`channels.msteams`、`channels.msteams.configWrites`。 -- 完整 Teams 配置(凭证、webhook、私信/群组策略、按团队/按渠道覆盖)记录在 [Microsoft Teams](/zh-CN/channels/msteams)。 +- 这里涵盖的核心键路径:`channels.msteams`、`channels.msteams.configWrites`。 +- 完整的 Teams 配置(凭证、webhook、私信/群组策略、按团队/按渠道覆盖)记录在 [Microsoft Teams](/zh-CN/channels/msteams) 中。 ### IRC @@ -719,9 +716,9 @@ IRC 由插件支持,并在 `channels.irc` 下配置。 } ``` -- 此处涵盖的核心键路径:`channels.irc`、`channels.irc.dmPolicy`、`channels.irc.configWrites`、`channels.irc.nickserv.*`。 -- 可选的 `channels.irc.defaultAccount` 会在匹配已配置的账户 ID 时覆盖默认账户选择。 -- 完整 IRC 渠道配置(主机/端口/TLS/渠道/允许列表/提及门控)记录在 [IRC](/zh-CN/channels/irc)。 +- 这里涵盖的核心键路径:`channels.irc`、`channels.irc.dmPolicy`、`channels.irc.configWrites`、`channels.irc.nickserv.*`。 +- 可选的 `channels.irc.defaultAccount` 在匹配已配置的账户 ID 时,会覆盖默认账户选择。 +- 完整的 IRC 渠道配置(主机/端口/TLS/渠道/允许列表/提及门控)记录在 [IRC](/zh-CN/channels/irc) 中。 ### 多账户(所有渠道) @@ -747,29 +744,29 @@ IRC 由插件支持,并在 `channels.irc` 下配置。 ``` - 省略 `accountId` 时使用 `default`(CLI + 路由)。 -- 环境变量令牌仅适用于**默认**账户。 -- 基础渠道设置会应用于所有账户,除非按账户覆盖。 -- 使用 `bindings[].match.accountId` 将每个账户路由到不同智能体。 -- 如果你通过 `openclaw channels add`(或渠道新手引导)添加非默认账户,而当前仍是单账户顶层渠道配置,OpenClaw 会先将账户范围的顶层单账户值提升到渠道账户映射中,使原账户继续工作。多数渠道会将它们移动到 `channels..accounts.default`;Matrix 则可以保留现有匹配的命名/默认目标。 -- 现有仅渠道绑定(没有 `accountId`)会继续匹配默认账户;账户范围绑定仍是可选的。 -- `openclaw doctor --fix` 也会通过将账户范围的顶层单账户值移动到为该渠道选择的提升账户中来修复混合形态。多数渠道使用 `accounts.default`;Matrix 则可以保留现有匹配的命名/默认目标。 +- 环境变量令牌只适用于**默认**账户。 +- 基础渠道设置会应用到所有账户,除非按账户覆盖。 +- 使用 `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)。 +许多插件渠道配置为 `channels.`,并记录在各自专用的渠道页面中(例如 Feishu、Matrix、LINE、Nostr、Zalo、Nextcloud Talk、Synology Chat 和 Twitch)。 +请参阅完整的渠道索引:[渠道](/zh-CN/channels)。 ### 群聊提及门控 群组消息默认**需要提及**(元数据提及或安全正则表达式模式)。适用于 WhatsApp、Telegram、Discord、Google Chat 和 iMessage 群聊。 -可见回复单独控制。群组/渠道房间默认使用 `messages.groupChat.visibleReplies: "message_tool"`:OpenClaw 仍会处理该轮对话,但普通最终回复保持私密,可见的房间输出需要 `message(action=send)`。仅当你想要普通回复被发回房间的旧版行为时,才设置 `"automatic"`。 +可见回复单独控制。群组/渠道房间默认使用 `messages.groupChat.visibleReplies: "message_tool"`:OpenClaw 仍会处理该轮次,但普通最终回复会保持私密,房间中的可见输出需要 `message(action=send)`。仅当你想要旧版行为,也就是普通回复会发回房间时,才设置 `"automatic"`。 **提及类型:** - **元数据提及**:原生平台 @ 提及。在 WhatsApp 自聊模式中会被忽略。 - **文本模式**:`agents.list[].groupChat.mentionPatterns` 中的安全正则表达式模式。无效模式和不安全的嵌套重复会被忽略。 -- 仅在可以检测时(原生提及或至少一个模式)才强制提及门控。 +- 仅在可以检测时(原生提及或至少一个模式),才会强制执行提及门控。 ```json5 { @@ -787,7 +784,7 @@ IRC 由插件支持,并在 `channels.irc` 下配置。 `messages.groupChat.historyLimit` 设置全局默认值。渠道可以用 `channels..historyLimit`(或按账户)覆盖。设置为 `0` 可禁用。 -`messages.groupChat.visibleReplies` 对群组/渠道来源轮次全局生效;渠道允许列表和提及门控仍决定是否处理某一轮。 +`messages.groupChat.visibleReplies` 对群组/渠道来源轮次是全局的;渠道允许列表和提及门控仍会决定是否处理某个轮次。 #### 私信历史限制 @@ -810,7 +807,7 @@ IRC 由插件支持,并在 `channels.irc` 下配置。 #### 自聊模式 -在 `allowFrom` 中包含你自己的号码以启用自聊模式(忽略原生 @ 提及,仅响应文本模式): +将你自己的号码包含在 `allowFrom` 中以启用自聊模式(忽略原生 @ 提及,只响应文本模式): ```json5 { @@ -860,32 +857,32 @@ IRC 由插件支持,并在 `channels.irc` 下配置。 -- 此代码块用于配置命令入口。有关当前内置 + 打包命令目录,请参阅[斜杠命令](/zh-CN/tools/slash-commands)。 -- 本页是**配置键参考**,不是完整的命令目录。由渠道/插件拥有的命令,例如 QQ Bot `/bot-ping` `/bot-help` `/bot-logs`、LINE `/card`、设备配对 `/pair`、memory `/dreaming`、phone-control `/phone` 和 Talk `/voice`,记录在各自的渠道/插件页面以及[斜杠命令](/zh-CN/tools/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`,记录在它们各自的渠道/插件页面以及[斜杠命令](/zh-CN/tools/slash-commands)中。 - 文本命令必须是带有前导 `/` 的**独立**消息。 -- `native: "auto"` 会为 Discord/Telegram 启用原生命令,并让 Slack 保持关闭。 -- `nativeSkills: "auto"` 会为 Discord/Telegram 启用原生 Skills 命令,并让 Slack 保持关闭。 -- 按渠道覆盖:`channels.discord.commands.native`(布尔值或 `"auto"`)。`false` 会清除之前注册的命令。 +- `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 客户端使用。 -- `mcp: true` 为 `mcp.servers` 下由 OpenClaw 管理的 MCP server 配置启用 `/mcp`。 -- `plugins: true` 为插件发现、安装以及启用/禁用控制启用 `/plugins`。 -- `channels..configWrites` 按渠道控制配置变更(默认值:true)。 -- 对于多账号渠道,`channels..accounts..configWrites` 也会控制面向该账号的写入(例如 `/allowlist --config --account ` 或 `/config set channels..accounts....`)。 +- `channels.telegram.customCommands` 会添加额外的 Telegram 机器人菜单项。 +- `bash: true` 会为主机 shell 启用 `! `。需要 `tools.elevated.enabled`,且发送者位于 `tools.elevated.allowFrom.` 中。 +- `config: true` 会启用 `/config`(读取/写入 `openclaw.json`)。对于 Gateway 网关 `chat.send` 客户端,持久化的 `/config set|unset` 写入还需要 `operator.admin`;只读的 `/config show` 仍然可供普通写入范围的操作员客户端使用。 +- `mcp: true` 会为 `mcp.servers` 下由 OpenClaw 管理的 MCP 服务器配置启用 `/mcp`。 +- `plugins: true` 会为插件发现、安装以及启用/禁用控制启用 `/plugins`。 +- `channels..configWrites` 按渠道限制配置变更(默认:true)。 +- 对于多账号渠道,`channels..accounts..configWrites` 也会限制针对该账号的写入(例如 `/allowlist --config --account ` 或 `/config set channels..accounts....`)。 - `restart: false` 会禁用 `/restart` 和 Gateway 网关重启工具操作。默认值:`true`。 -- `ownerAllowFrom` 是仅限 owner 使用的命令/工具的显式 owner allowlist。它独立于 `allowFrom`。 -- `ownerDisplay: "hash"` 会在系统提示中对 owner id 进行哈希处理。设置 `ownerDisplaySecret` 可控制哈希。 -- `allowFrom` 按提供商配置。设置后,它就是**唯一**授权来源(渠道 allowlist/配对和 `useAccessGroups` 都会被忽略)。 -- 当未设置 `allowFrom` 时,`useAccessGroups: false` 允许命令绕过 access-group 策略。 +- `ownerAllowFrom` 是仅限 owner 命令/工具使用的显式 owner 允许列表。它独立于 `allowFrom`。 +- `ownerDisplay: "hash"` 会在系统提示中对 owner ID 进行哈希处理。设置 `ownerDisplaySecret` 以控制哈希。 +- `allowFrom` 按提供商配置。设置后,它就是**唯一**的授权来源(渠道允许列表/配对和 `useAccessGroups` 会被忽略)。 +- 当未设置 `allowFrom` 时,`useAccessGroups: false` 允许命令绕过访问组策略。 - 命令文档映射: - - 内置 + 打包目录:[斜杠命令](/zh-CN/tools/slash-commands) - - 渠道特定的命令入口:[渠道](/zh-CN/channels) + - 内置 + 捆绑目录:[斜杠命令](/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) @@ -893,6 +890,6 @@ IRC 由插件支持,并在 `channels.irc` 下配置。 ## 相关 -- [配置参考](/zh-CN/gateway/configuration-reference) — 顶层键 +- [配置参考](/zh-CN/gateway/configuration-reference) — 顶级键 - [配置 — 智能体](/zh-CN/gateway/config-agents) - [渠道概览](/zh-CN/channels) diff --git a/docs/zh-CN/gateway/protocol.md b/docs/zh-CN/gateway/protocol.md index ffb410f82..606545d32 100644 --- a/docs/zh-CN/gateway/protocol.md +++ b/docs/zh-CN/gateway/protocol.md @@ -1,33 +1,26 @@ --- read_when: - - 实现或更新 Gateway 网关 WS 客户端 + - 实现或更新 Gateway 网关 WebSocket 客户端 - 调试协议不匹配或连接失败 - - 重新生成协议架构/模型 + - 正在重新生成协议模式/模型 summary: Gateway 网关 WebSocket 协议:握手、帧、版本控制 title: Gateway 网关协议 x-i18n: - generated_at: "2026-04-29T04:57:30Z" + generated_at: "2026-04-29T05:40:15Z" model: gpt-5.5 provider: openai - source_hash: 713a72b15f029aad00a4c6427fefeef08643aee830f23eac05e53b50f43d048c + source_hash: 25ef7c128bdf73c3a5e8aa152bdad59a15ffcd6ab8009ac5c26b760b16d595d0 source_path: gateway/protocol.md workflow: 16 --- -Gateway 网关 WS 协议是 OpenClaw 的**单一控制平面 + 节点传输协议**。 -所有客户端(CLI、Web UI、macOS 应用、iOS/Android 节点、无头节点) -都通过 WebSocket 连接,并在握手时声明它们的**角色** + **范围**。 +Gateway 网关 WS 协议是 OpenClaw 的**单一控制平面 + 节点传输协议**。所有客户端(CLI、Web UI、macOS 应用、iOS/Android 节点、无头节点)都通过 WebSocket 连接,并在握手时声明其**角色** + **范围**。 ## 传输协议 - WebSocket,带 JSON 载荷的文本帧。 - 第一帧**必须**是 `connect` 请求。 -- 连接前帧限制为 64 KiB。握手成功后,客户端应遵循 - `hello-ok.policy.maxPayload` 和 - `hello-ok.policy.maxBufferedBytes` 限制。启用诊断后, - 过大的入站帧和缓慢的出站缓冲区会在 Gateway 网关关闭或丢弃受影响帧之前发出 `payload.large` 事件。 - 这些事件会保留大小、限制、表面和安全原因代码。它们不会保留消息 - 正文、附件内容、原始帧正文、令牌、Cookie 或密钥值。 +- 连接前帧上限为 64 KiB。握手成功后,客户端应遵循 `hello-ok.policy.maxPayload` 和 `hello-ok.policy.maxBufferedBytes` 限制。启用诊断后,超大的入站帧和缓慢的出站缓冲区会在 Gateway 网关关闭或丢弃受影响帧之前发出 `payload.large` 事件。这些事件会保留大小、限制、表面和安全原因代码。它们不会保留消息正文、附件内容、原始帧正文、令牌、Cookie 或机密值。 ## 握手(connect) @@ -102,12 +95,9 @@ Gateway 网关 → 客户端: } ``` -`server`、`features`、`snapshot` 和 `policy` 都是架构 -(`src/gateway/protocol/schema/frames.ts`)要求的字段。`auth` 也是必需的,并报告 -协商后的角色/范围。`canvasHostUrl` 是可选的。 +`server`、`features`、`snapshot` 和 `policy` 都是架构要求的必填项(`src/gateway/protocol/schema/frames.ts`)。`auth` 也是必填项,并报告协商后的角色/范围。`canvasHostUrl` 是可选项。 -未签发设备令牌时,`hello-ok.auth` 会报告协商后的 -权限,不包含令牌字段: +未签发设备令牌时,`hello-ok.auth` 会报告协商后的权限,不包含令牌字段: ```json { @@ -118,11 +108,7 @@ Gateway 网关 → 客户端: } ``` -受信任的同进程后端客户端(`client.id: "gateway-client"`、 -`client.mode: "backend"`)在使用共享 Gateway 网关令牌/密码进行身份验证时, -可以在直接 local loopback 连接上省略 `device`。此路径保留给内部控制平面 RPC, -并避免过时的 CLI/设备配对基线阻塞本地后端工作,例如子智能体会话更新。远程客户端、 -浏览器源客户端、节点客户端,以及显式设备令牌/设备身份客户端仍使用正常的配对和范围升级检查。 +受信任的同进程后端客户端(`client.id: "gateway-client"`、`client.mode: "backend"`)在使用共享 Gateway 网关令牌/密码进行身份验证时,可以在直接 loopback 连接上省略 `device`。此路径保留给内部控制平面 RPC,可避免陈旧的 CLI/设备配对基线阻塞本地后端工作,例如子智能体会话更新。远程客户端、浏览器来源客户端、节点客户端,以及显式设备令牌/设备身份客户端,仍使用正常的配对和范围升级检查。 签发设备令牌时,`hello-ok` 还会包含: @@ -136,8 +122,7 @@ Gateway 网关 → 客户端: } ``` -在受信任的引导交接期间,`hello-ok.auth` 也可能在 `deviceTokens` 中包含额外的 -有界角色条目: +在受信任的引导交接期间,`hello-ok.auth` 也可能在 `deviceTokens` 中包含额外的有界角色条目: ```json { @@ -156,12 +141,7 @@ Gateway 网关 → 客户端: } ``` -对于内置节点/操作员引导流程,主节点令牌保持为 -`scopes: []`,任何交接的操作员令牌都保持限制在引导 -操作员允许列表内(`operator.approvals`、`operator.read`、 -`operator.talk.secrets`、`operator.write`)。引导范围检查保持 -角色前缀:操作员条目只满足操作员请求,非操作员 -角色仍需要其自身角色前缀下的范围。 +对于内置节点/operator 引导流程,主节点令牌保持 `scopes: []`,交接的任何 operator 令牌都限制在引导 operator 允许列表内(`operator.approvals`、`operator.read`、`operator.talk.secrets`、`operator.write`)。引导范围检查保持角色前缀:operator 条目只满足 operator 请求,非 operator 角色仍需要其自身角色前缀下的范围。 ### 节点示例 @@ -198,13 +178,13 @@ Gateway 网关 → 客户端: } ``` -## 成帧 +## 分帧 - **请求**:`{type:"req", id, method, params}` - **响应**:`{type:"res", id, ok, payload|error}` - **事件**:`{type:"event", event, payload, seq?, stateVersion?}` -有副作用的方法需要**幂等键**(见架构)。 +有副作用的方法需要**幂等键**(请参阅架构)。 ## 角色 + 范围 @@ -213,9 +193,9 @@ Gateway 网关 → 客户端: - `operator` = 控制平面客户端(CLI/UI/自动化)。 - `node` = 能力宿主(camera/screen/canvas/system.run)。 -### 范围(操作员) +### 范围(operator) -常用范围: +常见范围: - `operator.read` - `operator.write` @@ -224,23 +204,17 @@ Gateway 网关 → 客户端: - `operator.pairing` - `operator.talk.secrets` -带有 `includeSecrets: true` 的 `talk.config` 需要 `operator.talk.secrets` -(或 `operator.admin`)。 +带有 `includeSecrets: true` 的 `talk.config` 需要 `operator.talk.secrets`(或 `operator.admin`)。 -插件注册的 Gateway 网关 RPC 方法可以请求自己的操作员范围,但 -保留的核心管理员前缀(`config.*`、`exec.approvals.*`、`wizard.*`、 -`update.*`)始终解析为 `operator.admin`。 +插件注册的 Gateway 网关 RPC 方法可以请求自己的 operator 范围,但保留的核心管理员前缀(`config.*`、`exec.approvals.*`、`wizard.*`、`update.*`)始终解析为 `operator.admin`。 -方法范围只是第一道门槛。通过 -`chat.send` 到达的某些斜杠命令会在此之上应用更严格的命令级检查。例如,持久化的 -`/config set` 和 `/config unset` 写入需要 `operator.admin`。 +方法范围只是第一道门槛。通过 `chat.send` 到达的某些斜杠命令会在其上应用更严格的命令级检查。例如,持久化的 `/config set` 和 `/config unset` 写入需要 `operator.admin`。 -`node.pair.approve` 在基础方法范围之外,还具有额外的批准时范围检查: +`node.pair.approve` 在基础方法范围之上,还有一个批准时的额外范围检查: - 无命令请求:`operator.pairing` -- 带有非 exec 节点命令的请求:`operator.pairing` + `operator.write` -- 包含 `system.run`、`system.run.prepare` 或 `system.which` 的请求: - `operator.pairing` + `operator.admin` +- 带非执行节点命令的请求:`operator.pairing` + `operator.write` +- 包含 `system.run`、`system.run.prepare` 或 `system.which` 的请求:`operator.pairing` + `operator.admin` ### 能力/命令/权限(节点) @@ -254,17 +228,13 @@ Gateway 网关将这些视为**主张**,并强制执行服务端允许列表 ## 在线状态 -- `system-presence` 返回以设备身份为键的条目。 -- 在线状态条目包含 `deviceId`、`roles` 和 `scopes`,因此即使某个设备同时以**操作员**和**节点**身份连接, - UI 也可以为每个设备显示单独一行。 -- `node.list` 包含可选的 `lastSeenAtMs` 和 `lastSeenReason` 字段。已连接节点会将 - 当前连接时间报告为 `lastSeenAtMs`,原因为 `connect`;当受信任的节点事件更新其配对元数据时, - 已配对节点也可以报告持久的后台在线状态。 +- `system-presence` 返回按设备身份键控的条目。 +- 在线状态条目包含 `deviceId`、`roles` 和 `scopes`,因此即使某个设备同时作为 **operator** 和**节点**连接,UI 也能为每个设备显示一行。 +- `node.list` 包含可选的 `lastSeenAtMs` 和 `lastSeenReason` 字段。已连接节点会将其当前连接时间报告为 `lastSeenAtMs`,原因为 `connect`;当受信任节点事件更新其配对元数据时,已配对节点也可以报告持久的后台在线状态。 ### 节点后台存活事件 -节点可以调用带有 `event: "node.presence.alive"` 的 `node.event`,以记录已配对节点在 -后台唤醒期间处于存活状态,而不将其标记为已连接。 +节点可以调用带有 `event: "node.presence.alive"` 的 `node.event`,以记录已配对节点在后台唤醒期间处于存活状态,而不将其标记为已连接。 ```json { @@ -273,12 +243,9 @@ Gateway 网关将这些视为**主张**,并强制执行服务端允许列表 } ``` -`trigger` 是闭合枚举:`background`、`silent_push`、`bg_app_refresh`、 -`significant_location`、`manual` 或 `connect`。未知触发器字符串会在持久化前由 -Gateway 网关规范化为 `background`。该事件仅对经过身份验证的节点 -设备会话是持久的;无设备或未配对会话返回 `handled: false`。 +`trigger` 是闭合枚举:`background`、`silent_push`、`bg_app_refresh`、`significant_location`、`manual` 或 `connect`。未知触发器字符串会在持久化前由 Gateway 网关规范化为 `background`。该事件仅对已认证的节点设备会话持久化;无设备或未配对的会话会返回 `handled: false`。 -成功的 Gateway 网关会返回结构化结果: +成功的 Gateway 网关返回结构化结果: ```json { @@ -289,8 +256,7 @@ Gateway 网关规范化为 `background`。该事件仅对经过身份验证的 } ``` -较旧的 Gateway 网关可能仍会为 `node.event` 返回 `{ "ok": true }`;客户端应将其视为 -已确认的 RPC,而不是持久在线状态已保存。 +较旧的 Gateway 网关可能仍会为 `node.event` 返回 `{ "ok": true }`;客户端应将其视为已确认的 RPC,而不是持久在线状态持久化。 ## 广播事件范围限定 @@ -298,145 +264,142 @@ Gateway 网关规范化为 `background`。该事件仅对经过身份验证的 - **聊天、智能体和工具结果帧**(包括流式 `agent` 事件和工具调用结果)至少需要 `operator.read`。没有 `operator.read` 的会话会完全跳过这些帧。 - **插件定义的 `plugin.*` 广播**会根据插件注册方式,门控到 `operator.write` 或 `operator.admin`。 -- **Status 和传输事件**(`heartbeat`、`presence`、`tick`、连接/断开生命周期等)保持不受限制,因此每个经过身份验证的会话都可以观察传输健康状态。 -- **未知广播事件族**默认进行范围门控(失败关闭),除非注册的处理程序明确放宽限制。 +- **Status 和传输事件**(`heartbeat`、`presence`、`tick`、连接/断开生命周期等)保持不受限制,因此每个已认证会话都能观察传输健康状况。 +- **未知广播事件族**默认进行范围门控(故障关闭),除非注册的处理程序显式放宽限制。 -每个客户端连接都维护自己的每客户端序列号,因此即使不同客户端看到不同的范围过滤事件流子集,广播也会在该套接字上保持单调顺序。 +每个客户端连接都保留自己的每客户端序列号,因此即使不同客户端看到事件流中不同的范围过滤子集,广播也能在该套接字上保持单调顺序。 ## 常见 RPC 方法族 -公开 WS 表面比上面的握手/身份验证示例更广。 -这不是生成的转储 — `hello-ok.features.methods` 是一个保守的 -设备发现列表,基于 `src/gateway/server-methods-list.ts` 加上已加载的 -插件/渠道方法导出构建。将其视为功能设备发现,而不是 -`src/gateway/server-methods/*.ts` 的完整枚举。 +公开 WS 表面比上面的握手/身份验证示例更广。这不是生成的转储,`hello-ok.features.methods` 是一个保守的设备发现列表,由 `src/gateway/server-methods-list.ts` 加上已加载的插件/渠道方法导出构建。请将其视为功能设备发现,而不是 `src/gateway/server-methods/*.ts` 的完整枚举。 - `health` 返回缓存的或新探测的 Gateway 网关健康快照。 - - `diagnostics.stability` 返回最近的有界诊断稳定性记录器。它会保留事件名称、计数、字节大小、内存读数、队列/会话状态、渠道/插件名称和会话 ID 等运行元数据。它不会保留聊天文本、Webhook 正文、工具输出、原始请求或响应正文、令牌、Cookie 或密钥值。需要操作员读取范围。 - - `status` 返回 `/status` 风格的 Gateway 网关摘要;敏感字段仅包含在管理员范围的操作员客户端中。 - - `gateway.identity.get` 返回中继和配对流程使用的 Gateway 网关设备身份。 - - `system-presence` 返回已连接操作员/节点设备的当前在线状态快照。 + - `diagnostics.stability` 返回最近的有界诊断稳定性记录器。它会保留操作元数据,例如事件名称、计数、字节大小、内存读数、队列/会话状态、渠道/插件名称和会话 ID。它不会保留聊天文本、webhook 正文、工具输出、原始请求或响应正文、令牌、Cookie 或机密值。需要 operator 读取范围。 + - `status` 返回 `/status` 风格的 Gateway 网关摘要;敏感字段仅包含给具备 admin 范围的 operator 客户端。 + - `gateway.identity.get` 返回 relay 和配对流程使用的 Gateway 网关设备身份。 + - `system-presence` 返回已连接 operator/节点设备的当前在线状态快照。 - `system-event` 追加系统事件,并可以更新/广播在线状态上下文。 - `last-heartbeat` 返回最新持久化的心跳事件。 - - `set-heartbeats` 切换 Gateway 网关上的心跳处理。 + - `set-heartbeats` 在 Gateway 网关上切换心跳处理。 - - - `models.list` 返回运行时允许的模型目录。传入 `{ "view": "configured" }` 可获得适合选择器大小的已配置模型(先是 `agents.defaults.models`,然后是 `models.providers.*.models`),或传入 `{ "view": "all" }` 获取完整目录。 - - `usage.status` 返回提供商使用窗口/剩余额度摘要。 - - `usage.cost` 返回某个日期范围的聚合成本使用摘要。 - - `doctor.memory.status` 返回活动默认 Agent 工作区的向量内存/缓存嵌入就绪状态。仅当调用方明确需要实时嵌入提供商 ping 时,才传入 `{ "probe": true }` 或 `{ "deep": true }`。 - - `sessions.usage` 返回按会话划分的使用摘要。 - - `sessions.usage.timeseries` 返回一个会话的时间序列使用情况。 - - `sessions.usage.logs` 返回一个会话的使用日志条目。 + + - `models.list` 返回运行时允许的模型目录。传入 `{ "view": "configured" }` 可获取适合选择器展示的已配置模型(先是 `agents.defaults.models`,然后是 `models.providers.*.models`),或传入 `{ "view": "all" }` 获取完整目录。 + - `usage.status` 返回提供商用量窗口/剩余额度摘要。 + - `usage.cost` 返回某个日期范围的聚合成本用量摘要。 + - `doctor.memory.status` 返回当前默认智能体工作区的向量记忆 / 缓存嵌入就绪状态。仅当调用方明确想要实时嵌入提供商 ping 时,才传入 `{ "probe": true }` 或 `{ "deep": true }`。 + - `doctor.memory.remHarness` 返回面向远程控制平面客户端的有界只读 REM 运行框架预览。它可以包含工作区路径、记忆片段、渲染后的基于依据的 Markdown,以及深度提升候选项,因此调用方需要 `operator.read`。 + - `sessions.usage` 返回按会话划分的用量摘要。 + - `sessions.usage.timeseries` 返回一个会话的时间序列用量。 + - `sessions.usage.logs` 返回一个会话的用量日志条目。 - - `channels.status` 返回内置 + 捆绑渠道/插件的 Status 摘要。 - - `channels.logout` 在渠道支持登出的情况下登出指定渠道/账号。 - - `web.login.start` 为当前支持二维码的 Web 渠道提供商启动二维码/Web 登录流程。 - - `web.login.wait` 等待该二维码/Web 登录流程完成,并在成功后启动渠道。 + - `channels.status` 返回内建 + 随附渠道/插件的状态摘要。 + - `channels.logout` 在渠道支持注销时注销特定渠道/账号。 + - `web.login.start` 为当前支持 QR 的网页渠道提供商启动 QR/网页登录流程。 + - `web.login.wait` 等待该 QR/网页登录流程完成,并在成功后启动该渠道。 - `push.test` 向已注册的 iOS 节点发送测试 APNs 推送。 - `voicewake.get` 返回已存储的唤醒词触发器。 - - `voicewake.set` 更新唤醒词触发器并广播变更。 + - `voicewake.set` 更新唤醒词触发器并广播该变更。 - - `send` 是直接出站投递 RPC,用于在聊天运行器之外按渠道/账号/线程目标发送消息。 - - `logs.tail` 返回已配置的 Gateway 网关文件日志尾部内容,并支持游标/限制和最大字节控制。 + - `send` 是聊天运行器之外、面向渠道/账号/线程目标发送的直接出站投递 RPC。 + - `logs.tail` 返回已配置的 Gateway 网关文件日志尾部内容,并带有游标/限制和最大字节控制。 - `talk.config` 返回生效的 Talk 配置载荷;`includeSecrets` 需要 `operator.talk.secrets`(或 `operator.admin`)。 - `talk.mode` 为 WebChat/Control UI 客户端设置/广播当前 Talk 模式状态。 - - `talk.speak` 通过活动的 Talk 语音提供商合成语音。 - - `tts.status` 返回 TTS 启用状态、活动提供商、后备提供商和提供商配置状态。 + - `talk.speak` 通过当前 Talk 语音提供商合成语音。 + - `tts.status` 返回 TTS 启用状态、当前提供商、备用提供商和提供商配置状态。 - `tts.providers` 返回可见的 TTS 提供商清单。 - - `tts.enable` 和 `tts.disable` 切换 TTS 偏好状态。 + - `tts.enable` 和 `tts.disable` 切换 TTS 偏好设置状态。 - `tts.setProvider` 更新首选 TTS 提供商。 - - `tts.convert` 执行一次性文本转语音转换。 + - `tts.convert` 运行一次性文本转语音转换。 - - `secrets.reload` 重新解析活动的 SecretRefs,并且仅在完全成功时替换运行时密钥状态。 - - `secrets.resolve` 为特定命令/目标集合解析面向命令目标的密钥分配。 + - `secrets.reload` 重新解析当前 SecretRefs,并且仅在完全成功时替换运行时密钥状态。 + - `secrets.resolve` 针对特定命令/目标集合解析面向命令目标的密钥分配。 - `config.get` 返回当前配置快照和哈希。 - - `config.set` 写入经过验证的配置载荷。 + - `config.set` 写入已验证的配置载荷。 - `config.patch` 合并部分配置更新。 - - `config.apply` 验证并替换完整配置载荷。 - - `config.schema` 返回 Control UI 和 CLI 工具使用的实时配置 schema 载荷:schema、`uiHints`、版本和生成元数据,包括运行时可加载时的插件 + 渠道 schema 元数据。该 schema 包含字段 `title` / `description` 元数据,它们来自 UI 使用的同一组标签和帮助文本;当存在匹配的字段文档时,也包括嵌套对象、通配符、数组项,以及 `anyOf` / `oneOf` / `allOf` 组合分支。 - - `config.schema.lookup` 返回一个配置路径的路径限定查询载荷:规范化路径、浅层 schema 节点、匹配的提示 + `hintPath`,以及用于 UI/CLI 下钻的直接子项摘要。查询 schema 节点会保留面向用户的文档和常见验证字段(`title`、`description`、`type`、`enum`、`const`、`format`、`pattern`、数字/字符串/数组/对象边界,以及 `additionalProperties`、`deprecated`、`readOnly`、`writeOnly` 等标志)。子项摘要会暴露 `key`、规范化的 `path`、`type`、`required`、`hasChildren`,以及匹配的 `hint` / `hintPath`。 + - `config.apply` 验证 + 替换完整配置载荷。 + - `config.schema` 返回 Control UI 和 CLI 工具使用的实时配置模式载荷:模式、`uiHints`、版本和生成元数据;当运行时可以加载时,还包括插件 + 渠道模式元数据。该模式包含字段 `title` / `description` 元数据,这些元数据源自 UI 使用的相同标签和帮助文本;当存在匹配的字段文档时,还包括嵌套对象、通配符、数组项以及 `anyOf` / `oneOf` / `allOf` 组合分支。 + - `config.schema.lookup` 返回针对一个配置路径的路径范围查找载荷:规范化路径、浅层模式节点、匹配的提示 + `hintPath`,以及供 UI/CLI 下钻使用的直接子项摘要。查找模式节点会保留面向用户的文档和常见验证字段(`title`、`description`、`type`、`enum`、`const`、`format`、`pattern`、数值/字符串/数组/对象边界,以及 `additionalProperties`、`deprecated`、`readOnly`、`writeOnly` 等标志)。子项摘要会暴露 `key`、规范化后的 `path`、`type`、`required`、`hasChildren`,以及匹配的 `hint` / `hintPath`。 - `update.run` 运行 Gateway 网关更新流程,并且仅在更新本身成功时安排重启。 - - `update.status` 返回最新缓存的更新重启哨兵,包括可用时重启后的运行版本。 + - `update.status` 返回最新缓存的更新重启哨兵,并在可用时包含重启后的运行版本。 - `wizard.start`、`wizard.next`、`wizard.status` 和 `wizard.cancel` 通过 WS RPC 暴露新手引导向导。 - `agents.list` 返回已配置的智能体条目,包括生效模型和运行时元数据。 - - `agents.create`、`agents.update` 和 `agents.delete` 管理智能体记录和工作区连接。 + - `agents.create`、`agents.update` 和 `agents.delete` 管理智能体记录和工作区关联配置。 - `agents.files.list`、`agents.files.get` 和 `agents.files.set` 管理为智能体暴露的引导工作区文件。 - `agent.identity.get` 返回智能体或会话的生效助手身份。 - - `agent.wait` 等待一次运行完成,并在可用时返回终态快照。 + - `agent.wait` 等待运行结束,并在可用时返回终态快照。 - - `sessions.list` 返回当前会话索引。 + - `sessions.list` 返回当前会话索引;当配置了智能体运行时后端时,会包含每行 `agentRuntime` 元数据。 - `sessions.subscribe` 和 `sessions.unsubscribe` 为当前 WS 客户端切换会话变更事件订阅。 - - `sessions.messages.subscribe` 和 `sessions.messages.unsubscribe` 为一个会话切换转录/消息事件订阅。 - - `sessions.preview` 返回特定会话键的有界转录预览。 + - `sessions.messages.subscribe` 和 `sessions.messages.unsubscribe` 为一个会话切换会话记录/消息事件订阅。 + - `sessions.preview` 返回特定会话键的有界会话记录预览。 - `sessions.resolve` 解析会话目标或将其规范化。 - `sessions.create` 创建新的会话条目。 - `sessions.send` 向现有会话发送消息。 - - `sessions.steer` 是活动会话的中断并引导变体。 + - `sessions.steer` 是面向活动会话的打断并引导变体。 - `sessions.abort` 中止会话的活动工作。 - - `sessions.patch` 更新会话元数据/覆盖项。 + - `sessions.patch` 更新会话元数据/覆盖项,并报告解析后的规范模型以及生效的 `agentRuntime`。 - `sessions.reset`、`sessions.delete` 和 `sessions.compact` 执行会话维护。 - - `sessions.get` 返回完整的已存储会话行。 - - 聊天执行仍使用 `chat.history`、`chat.send`、`chat.abort` 和 `chat.inject`。`chat.history` 会为 UI 客户端进行显示规范化:从可见文本中去除内联指令标签,去除纯文本工具调用 XML 载荷(包括 `...`、`...`、`...`、`...` 和被截断的工具调用块)以及泄漏的 ASCII/全角模型控制令牌,省略完全由静默令牌组成的助手行,例如精确的 `NO_REPLY` / `no_reply`,并且过大的行可替换为占位符。 + - `sessions.get` 返回完整存储的会话行。 + - 聊天执行仍使用 `chat.history`、`chat.send`、`chat.abort` 和 `chat.inject`。`chat.history` 会为 UI 客户端进行显示规范化:从可见文本中剥离内联指令标签,剥离纯文本工具调用 XML 载荷(包括 `...`、`...`、`...`、`...` 和被截断的工具调用块)以及泄漏的 ASCII/全角模型控制标记,省略纯静默标记助手行(例如精确的 `NO_REPLY` / `no_reply`),并且过大的行可以替换为占位符。 - `device.pair.list` 返回待处理和已批准的配对设备。 - `device.pair.approve`、`device.pair.reject` 和 `device.pair.remove` 管理设备配对记录。 - - `device.token.rotate` 在其已批准角色和调用方作用域边界内轮换配对设备令牌。 - - `device.token.revoke` 在其已批准角色和调用方作用域边界内撤销配对设备令牌。 + - `device.token.rotate` 在已批准角色和调用方作用域边界内轮换配对设备令牌。 + - `device.token.revoke` 在已批准角色和调用方作用域边界内吊销配对设备令牌。 - `node.pair.request`、`node.pair.list`、`node.pair.approve`、`node.pair.reject`、`node.pair.remove` 和 `node.pair.verify` 覆盖节点配对和引导验证。 - - `node.list` 和 `node.describe` 返回已知/已连接的节点状态。 - - `node.rename` 更新配对节点标签。 + - `node.list` 和 `node.describe` 返回已知/已连接节点状态。 + - `node.rename` 更新已配对节点标签。 - `node.invoke` 将命令转发到已连接节点。 - `node.invoke.result` 返回调用请求的结果。 - `node.event` 将节点发起的事件带回 Gateway 网关。 - `node.canvas.capability.refresh` 刷新有作用域的 canvas 能力令牌。 - `node.pending.pull` 和 `node.pending.ack` 是已连接节点队列 API。 - - `node.pending.enqueue` 和 `node.pending.drain` 管理离线/断开连接节点的持久待处理工作。 + - `node.pending.enqueue` 和 `node.pending.drain` 管理离线/断开连接节点的持久化待处理工作。 - - - `exec.approval.request`、`exec.approval.get`、`exec.approval.list` 和 `exec.approval.resolve` 覆盖一次性执行审批请求以及待处理审批查询/重放。 - - `exec.approval.waitDecision` 等待一个待处理的执行审批,并返回最终决定(超时时返回 `null`)。 - - `exec.approvals.get` 和 `exec.approvals.set` 管理 Gateway 网关执行审批策略快照。 - - `exec.approvals.node.get` 和 `exec.approvals.node.set` 通过节点中继命令管理节点本地执行审批策略。 + + - `exec.approval.request`、`exec.approval.get`、`exec.approval.list` 和 `exec.approval.resolve` 覆盖一次性 exec 审批请求以及待处理审批查找/重放。 + - `exec.approval.waitDecision` 等待一个待处理 exec 审批,并返回最终决策(或在超时时返回 `null`)。 + - `exec.approvals.get` 和 `exec.approvals.set` 管理 Gateway 网关 exec 审批策略快照。 + - `exec.approvals.node.get` 和 `exec.approvals.node.set` 通过节点中继命令管理节点本地 exec 审批策略。 - `plugin.approval.request`、`plugin.approval.list`、`plugin.approval.waitDecision` 和 `plugin.approval.resolve` 覆盖插件定义的审批流程。 - - 自动化:`wake` 调度立即或下一次心跳的唤醒文本注入;`cron.list`、`cron.status`、`cron.add`、`cron.update`、`cron.remove`、`cron.run`、`cron.runs` 管理计划工作。 + - 自动化:`wake` 安排立即或下一次心跳的唤醒文本注入;`cron.list`、`cron.status`、`cron.add`、`cron.update`、`cron.remove`、`cron.run`、`cron.runs` 管理定时工作。 - Skills 和工具:`commands.list`、`skills.*`、`tools.catalog`、`tools.effective`。 @@ -444,11 +407,12 @@ Gateway 网关规范化为 `background`。该事件仅对经过身份验证的 ### 常见事件族 -- `chat`:UI 聊天更新,例如 `chat.inject` 和其他仅转录聊天事件。 -- `session.message` 和 `session.tool`:已订阅会话的转录/事件流更新。 +- `chat`:UI 聊天更新,例如 `chat.inject` 和其他仅会话记录的聊天 + 事件。 +- `session.message` 和 `session.tool`:已订阅会话的会话记录/事件流更新。 - `sessions.changed`:会话索引或元数据已变更。 - `presence`:系统在线状态快照更新。 -- `tick`:周期性 keepalive / 活性事件。 +- `tick`:周期性保活 / 存活性事件。 - `health`:Gateway 网关健康快照更新。 - `heartbeat`:心跳事件流更新。 - `cron`:cron 运行/作业变更事件。 @@ -457,205 +421,211 @@ Gateway 网关规范化为 `background`。该事件仅对经过身份验证的 - `node.invoke.request`:节点调用请求广播。 - `device.pair.requested` / `device.pair.resolved`:配对设备生命周期。 - `voicewake.changed`:唤醒词触发器配置已变更。 -- `exec.approval.requested` / `exec.approval.resolved`:执行审批生命周期。 -- `plugin.approval.requested` / `plugin.approval.resolved`:插件审批生命周期。 +- `exec.approval.requested` / `exec.approval.resolved`:exec 审批 + 生命周期。 +- `plugin.approval.requested` / `plugin.approval.resolved`:插件审批 + 生命周期。 ### 节点辅助方法 -- 节点可以调用 `skills.bins`,以获取当前技能可执行文件列表,用于自动允许检查。 +- 节点可以调用 `skills.bins` 来获取当前技能可执行文件列表,用于自动允许检查。 ### 操作员辅助方法 -- 操作员可以调用 `commands.list`(`operator.read`)获取智能体的运行时命令清单。 +- 操作者可以调用 `commands.list`(`operator.read`)获取某个智能体的运行时 + 命令清单。 - `agentId` 是可选的;省略它会读取默认 Agent 工作区。 - - `scope` 控制主要 `name` 面向哪个界面: + - `scope` 控制主要 `name` 目标指向哪个表面: - `text` 返回不带前导 `/` 的主要文本命令令牌 - - `native` 和默认的 `both` 路径会在可用时返回提供商感知的原生命名 + - `native` 和默认的 `both` 路径会在可用时返回感知提供商的原生命名 - `textAliases` 携带精确的斜杠别名,例如 `/model` 和 `/m`。 - - `nativeName` 携带存在时的提供商感知原生命令名称。 + - `nativeName` 在存在时携带感知提供商的原生命令名称。 - `provider` 是可选的,并且只影响原生命名以及原生插件命令可用性。 - `includeArgs=false` 会从响应中省略序列化的参数元数据。 -- 操作员可以调用 `tools.catalog`(`operator.read`)获取智能体的运行时工具目录。响应包括分组工具和来源元数据: +- 操作者可以调用 `tools.catalog`(`operator.read`)获取某个智能体的运行时工具目录。响应包括分组工具和来源元数据: - `source`:`core` 或 `plugin` - - `pluginId`:当 `source="plugin"` 时的插件所有者 - - `optional`:插件工具是否可选 -- 操作员可以调用 `tools.effective`(`operator.read`)获取会话的运行时生效工具清单。 + - `pluginId`:当 `source="plugin"` 时为插件所有者 + - `optional`:插件工具是否为可选 +- 操作者可以调用 `tools.effective`(`operator.read`)获取某个会话的运行时生效工具清单。 - `sessionKey` 是必需的。 - - Gateway 网关会从服务端会话派生受信任的运行时上下文,而不是接受调用方提供的认证或投递上下文。 - - 响应限定于会话范围,并反映当前活动对话现在可以使用的内容,包括核心、插件和渠道工具。 -- 操作员可以调用 `skills.status`(`operator.read`)获取智能体的可见技能清单。 + - Gateway 网关会从会话服务端派生可信运行时上下文,而不是接受 + 调用方提供的认证或投递上下文。 + - 响应限定在会话范围内,并反映当前活动对话现在可以使用的内容, + 包括核心、插件和渠道工具。 +- 操作者可以调用 `skills.status`(`operator.read`)获取某个智能体的可见 + skill 清单。 - `agentId` 是可选的;省略它会读取默认 Agent 工作区。 - - 响应包括资格、缺失要求、配置检查,以及不会暴露原始密钥值的已脱敏安装选项。 -- 操作员可以调用 `skills.search` 和 `skills.detail`(`operator.read`)获取 ClawHub 设备发现元数据。 -- 操作员可以通过两种模式调用 `skills.install`(`operator.admin`): - - ClawHub 模式:`{ source: "clawhub", slug, version?, force? }` 将技能文件夹安装到默认 Agent 工作区的 `skills/` 目录。 - - Gateway 网关安装器模式:`{ name, installId, dangerouslyForceUnsafeInstall?, timeoutMs? }` 在 Gateway 网关主机上运行声明的 `metadata.openclaw.install` 操作。 -- 操作员可以通过两种模式调用 `skills.update`(`operator.admin`): - - ClawHub 模式会更新默认 Agent 工作区中的一个已跟踪 slug,或所有已跟踪的 ClawHub 安装。 - - 配置模式会修补 `skills.entries.` 值,例如 `enabled`、`apiKey` 和 `env`。 + - 响应包括资格、缺失要求、配置检查,以及 + 已清理的安装选项,不会暴露原始密钥值。 +- 操作者可以调用 `skills.search` 和 `skills.detail`(`operator.read`)获取 + ClawHub 设备发现元数据。 +- 操作者可以通过两种模式调用 `skills.install`(`operator.admin`): + - ClawHub 模式:`{ source: "clawhub", slug, version?, force? }` 会将 + skill 文件夹安装到默认 Agent 工作区的 `skills/` 目录。 + - Gateway 网关安装器模式:`{ name, installId, dangerouslyForceUnsafeInstall?, timeoutMs? }` + 在 Gateway 网关主机上运行声明的 `metadata.openclaw.install` 操作。 +- 操作者可以通过两种模式调用 `skills.update`(`operator.admin`): + - ClawHub 模式会更新一个已跟踪的 slug,或默认 Agent 工作区中 + 所有已跟踪的 ClawHub 安装。 + - 配置模式会修补 `skills.entries.` 值,例如 `enabled`、 + `apiKey` 和 `env`。 ### `models.list` 视图 `models.list` 接受可选的 `view` 参数: -- 省略或 `"default"`:当前运行时行为。如果配置了 `agents.defaults.models`,响应为允许的目录;否则响应为完整 Gateway 网关目录。 -- `"configured"`:适合选择器的行为。如果配置了 `agents.defaults.models`,它仍然优先。否则,响应使用显式的 `models.providers.*.models` 条目,仅在不存在已配置模型行时才回退到完整目录。 -- `"all"`:完整 Gateway 网关目录,绕过 `agents.defaults.models`。将其用于诊断和设备发现 UI,而不是常规模型选择器。 +- 省略或 `"default"`:当前运行时行为。如果配置了 `agents.defaults.models`,响应就是允许的目录;否则响应就是完整的 Gateway 网关目录。 +- `"configured"`:适合选择器大小的行为。如果配置了 `agents.defaults.models`,它仍然优先。否则响应使用显式的 `models.providers.*.models` 条目,仅在没有已配置模型行时回退到完整目录。 +- `"all"`:完整的 Gateway 网关目录,绕过 `agents.defaults.models`。将它用于诊断和设备发现 UI,而不是常规模型选择器。 ## Exec 批准 - 当 exec 请求需要批准时,Gateway 网关会广播 `exec.approval.requested`。 -- 操作员客户端通过调用 `exec.approval.resolve` 来完成处理(需要 `operator.approvals` scope)。 +- 操作者客户端通过调用 `exec.approval.resolve` 解决(需要 `operator.approvals` scope)。 - 对于 `host=node`,`exec.approval.request` 必须包含 `systemRunPlan`(规范的 `argv`/`cwd`/`rawCommand`/会话元数据)。缺少 `systemRunPlan` 的请求会被拒绝。 - 批准后,转发的 `node.invoke system.run` 调用会复用该规范 `systemRunPlan` 作为权威的命令/cwd/会话上下文。 -- 如果调用方在 prepare 和最终已批准的 `system.run` 转发之间改变了 `command`、`rawCommand`、`cwd`、`agentId` 或 - `sessionKey`,Gateway 网关会拒绝运行,而不是信任被改变的 payload。 +- 如果调用方在准备与最终批准的 `system.run` 转发之间更改了 `command`、`rawCommand`、`cwd`、`agentId` 或 + `sessionKey`,Gateway 网关会拒绝运行,而不是信任已更改的负载。 ## 智能体投递回退 - `agent` 请求可以包含 `deliver=true` 以请求出站投递。 - `bestEffortDeliver=false` 保持严格行为:无法解析或仅限内部的投递目标会返回 `INVALID_REQUEST`。 -- `bestEffortDeliver=true` 允许在无法解析外部可投递路由时回退到仅会话执行(例如内部/webchat 会话或有歧义的多渠道配置)。 +- `bestEffortDeliver=true` 允许在无法解析外部可投递路由时回退到仅会话执行(例如内部/webchat 会话或含糊的多渠道配置)。 ## 版本控制 - `PROTOCOL_VERSION` 位于 `src/gateway/protocol/schema/protocol-schemas.ts`。 - 客户端发送 `minProtocol` + `maxProtocol`;服务器会拒绝不匹配项。 -- schema + 模型由 TypeBox 定义生成: +- schema + 模型从 TypeBox 定义生成: - `pnpm protocol:gen` - `pnpm protocol:gen:swift` - `pnpm protocol:check` ### 客户端常量 -`src/gateway/client.ts` 中的参考客户端使用这些默认值。这些值在 +`src/gateway/client.ts` 中的参考客户端使用这些默认值。值在 协议 v3 中保持稳定,并且是第三方客户端的预期基线。 | 常量 | 默认值 | 来源 | | ----------------------------------------- | ----------------------------------------------------- | ------------------------------------------------------------------------------------------ | | `PROTOCOL_VERSION` | `3` | `src/gateway/protocol/schema/protocol-schemas.ts` | -| 请求超时(每个 RPC) | `30_000` ms | `src/gateway/client.ts` (`requestTimeoutMs`) | -| 预认证 / 连接质询超时 | `15_000` ms | `src/gateway/handshake-timeouts.ts`(配置/环境变量可提高配对的服务器/客户端预算) | -| 初始重连退避 | `1_000` ms | `src/gateway/client.ts` (`backoffMs`) | -| 最大重连退避 | `30_000` ms | `src/gateway/client.ts` (`scheduleReconnect`) | -| 设备 token 关闭后的快速重试钳制 | `250` ms | `src/gateway/client.ts` | +| 请求超时(每个 RPC) | `30_000` ms | `src/gateway/client.ts`(`requestTimeoutMs`) | +| 预认证 / 连接挑战超时 | `15_000` ms | `src/gateway/handshake-timeouts.ts`(配置/环境变量可以提高成对的服务器/客户端预算) | +| 初始重连退避 | `1_000` ms | `src/gateway/client.ts`(`backoffMs`) | +| 最大重连退避 | `30_000` ms | `src/gateway/client.ts`(`scheduleReconnect`) | +| 设备令牌关闭后的快速重试上限 | `250` ms | `src/gateway/client.ts` | | `terminate()` 前的强制停止宽限 | `250` ms | `FORCE_STOP_TERMINATE_GRACE_MS` | | `stopAndWait()` 默认超时 | `1_000` ms | `STOP_AND_WAIT_TIMEOUT_MS` | -| 默认 tick 间隔(`hello-ok` 前) | `30_000` ms | `src/gateway/client.ts` | -| Tick 超时关闭 | 静默超过 `tickIntervalMs * 2` 时使用 code `4000` | `src/gateway/client.ts` | -| `MAX_PAYLOAD_BYTES` | `25 * 1024 * 1024` (25 MB) | `src/gateway/server-constants.ts` | +| 默认 tick 间隔(`hello-ok` 之前) | `30_000` ms | `src/gateway/client.ts` | +| Tick 超时关闭 | 当静默超过 `tickIntervalMs * 2` 时使用代码 `4000` | `src/gateway/client.ts` | +| `MAX_PAYLOAD_BYTES` | `25 * 1024 * 1024`(25 MB) | `src/gateway/server-constants.ts` | -服务器会在 `hello-ok` 中公布有效的 `policy.tickIntervalMs`、`policy.maxPayload` +服务器会在 `hello-ok` 中公布生效的 `policy.tickIntervalMs`、`policy.maxPayload` 和 `policy.maxBufferedBytes`;客户端应遵循这些值, 而不是握手前的默认值。 -## 凭证 +## 认证 -- 共享密钥 Gateway 网关凭证使用 `connect.params.auth.token` 或 - `connect.params.auth.password`,取决于配置的凭证模式。 -- 携带身份的模式(例如 Tailscale Serve - (`gateway.auth.allowTailscale: true`) 或非 loopback - `gateway.auth.mode: "trusted-proxy"`)会从 - 请求标头而不是 `connect.params.auth.*` 满足连接凭证检查。 -- 私有入口 `gateway.auth.mode: "none"` 会完全跳过共享密钥连接凭证; - 不要在公共/不受信任的入口暴露该模式。 -- 配对后,Gateway 网关会签发一个限定到连接 - 角色 + scope 的**设备 token**。它会在 `hello-ok.auth.deviceToken` 中返回,客户端应持久化它以供将来连接使用。 -- 客户端应在任何成功连接后持久化主 `hello-ok.auth.deviceToken`。 -- 使用该**已存储**设备 token 重连时,也应复用该 token 的已存储 - 已批准 scope 集。这会保留已授予的读取/探测/Status 访问, - 并避免把重连静默收缩到更窄的隐式仅管理员 scope。 -- 客户端侧连接凭证组装(`src/gateway/client.ts` 中的 `selectConnectAuth`): - - `auth.password` 是正交的,只要设置就始终转发。 - - `auth.token` 按优先级填充:显式共享 token 优先, - 然后是显式 `deviceToken`,再然后是已存储的按设备 token(由 - `deviceId` + `role` 作为键)。 - - 仅当上述都未解析出 `auth.token` 时,才发送 `auth.bootstrapToken`。 - 共享 token 或任何已解析的设备 token 都会抑制它。 - - 在一次性 `AUTH_TOKEN_MISMATCH` 重试时自动提升已存储设备 token - 仅限于**受信任端点**—— - loopback,或带有固定 `tlsFingerprint` 的 `wss://`。未固定的公共 `wss://` +- 共享密钥 Gateway 网关认证使用 `connect.params.auth.token` 或 + `connect.params.auth.password`,具体取决于配置的认证模式。 +- 带身份的模式,例如 Tailscale Serve + (`gateway.auth.allowTailscale: true`)或非 loopback 的 + `gateway.auth.mode: "trusted-proxy"`,会从请求标头满足连接认证检查, + 而不是使用 `connect.params.auth.*`。 +- 私有入口 `gateway.auth.mode: "none"` 会完全跳过共享密钥连接认证; + 不要在公共/不可信入口上暴露该模式。 +- 配对后,Gateway 网关会颁发限定到连接 + 角色 + scope 的**设备令牌**。它会在 `hello-ok.auth.deviceToken` 中返回,客户端应将其持久化以供将来连接使用。 +- 客户端应在任何成功连接后持久化主要的 `hello-ok.auth.deviceToken`。 +- 使用该**已存储的**设备令牌重连时,也应复用为该令牌存储的 + 已批准 scope 集。这会保留已授予的读取/探测/status 访问, + 并避免把重连静默收窄到更窄的隐式仅管理员 scope。 +- 客户端侧连接认证组装(`src/gateway/client.ts` 中的 `selectConnectAuth`): + - `auth.password` 是正交的,并且在设置时始终转发。 + - `auth.token` 按优先级填充:先是显式共享令牌, + 然后是显式 `deviceToken`,再然后是已存储的每设备令牌(按 + `deviceId` + `role` 设键)。 + - 仅当上述都没有解析出 + `auth.token` 时,才会发送 `auth.bootstrapToken`。共享令牌或任何已解析的设备令牌都会抑制它。 + - 在一次性的 + `AUTH_TOKEN_MISMATCH` 重试中自动提升已存储设备令牌,仅限于**可信端点** — + loopback,或带固定 `tlsFingerprint` 的 `wss://`。未固定的公共 `wss://` 不符合条件。 -- 额外的 `hello-ok.auth.deviceTokens` 条目是 bootstrap 移交 token。 - 仅当连接在受信任传输(例如 `wss://` 或 loopback/local 配对)上使用 bootstrap 凭证时才持久化它们。 -- 如果客户端提供**显式** `deviceToken` 或显式 `scopes`,则该 - 调用方请求的 scope 集保持权威;只有当客户端复用已存储的按设备 token 时, - 才会复用缓存的 scope。 -- 设备 token 可以通过 `device.token.rotate` 和 +- 额外的 `hello-ok.auth.deviceTokens` 条目是引导交接令牌。 + 仅当连接在可信传输上使用引导认证时才持久化它们, + 例如 `wss://` 或 loopback/本地配对。 +- 如果客户端提供**显式** `deviceToken` 或显式 `scopes`,该 + 调用方请求的 scope 集保持权威;缓存的 scope 仅在 + 客户端复用已存储的每设备令牌时才会复用。 +- 设备令牌可以通过 `device.token.rotate` 和 `device.token.revoke` 轮换/撤销(需要 `operator.pairing` scope)。 -- `device.token.rotate` 返回轮换元数据。仅对于已经使用 - 该设备 token 认证的同设备调用,它会回显替换 bearer token, - 因此仅 token 客户端可在重连前持久化其替换项。共享/管理员轮换不会回显 bearer token。 -- token 签发、轮换和撤销会被限制在该设备配对条目中记录的已批准角色集内; - token 变更不能扩展或定位到配对批准从未授予的设备角色。 -- 对于配对设备 token 会话,除非调用方也具有 `operator.admin`, - 否则设备管理是自限定的:非管理员调用方只能移除/撤销/轮换 - 其**自己的**设备条目。 -- `device.token.rotate` 和 `device.token.revoke` 还会根据调用方当前会话 scope - 检查目标操作员 token scope 集。非管理员调用方不能轮换或撤销比其已持有权限更宽的操作员 token。 -- 凭证失败包含 `error.details.code` 以及恢复提示: +- `device.token.rotate` 返回轮换元数据。它仅针对已使用 + 该设备令牌认证的同设备调用回显替换的 bearer token, + 因此仅令牌客户端可以在重连前持久化替换令牌。共享/管理员轮换不会回显 bearer token。 +- 令牌颁发、轮换和撤销都限制在该设备配对条目中记录的 + 已批准角色集内;令牌变更不能扩展或指向 + 配对批准从未授予的设备角色。 +- 对于已配对设备令牌会话,设备管理是自我限定的,除非 + 调用方还拥有 `operator.admin`:非管理员调用方只能移除/撤销/轮换 + **自己的**设备条目。 +- `device.token.rotate` 和 `device.token.revoke` 还会根据调用方当前会话 scope 检查目标操作者 + 令牌 scope 集。非管理员调用方不能轮换或撤销比自己已持有范围更广的操作者令牌。 +- 认证失败包括 `error.details.code` 以及恢复提示: - `error.details.canRetryWithDeviceToken`(布尔值) - - `error.details.recommendedNextStep` (`retry_with_device_token`, `update_auth_configuration`, `update_auth_credentials`, `wait_then_retry`, `review_auth_configuration`) -- `AUTH_TOKEN_MISMATCH` 的客户端行为: - - 受信任客户端可以尝试使用缓存的按设备 token 进行一次有界重试。 - - 如果该重试失败,客户端应停止自动重连循环并显示操作员操作指引。 + - `error.details.recommendedNextStep`(`retry_with_device_token`、`update_auth_configuration`、`update_auth_credentials`、`wait_then_retry`、`review_auth_configuration`) +- 客户端对 `AUTH_TOKEN_MISMATCH` 的行为: + - 可信客户端可以使用缓存的每设备令牌尝试一次有界重试。 + - 如果该重试失败,客户端应停止自动重连循环,并显示操作者操作指引。 ## 设备身份 + 配对 -- 节点应包含从密钥对指纹派生的稳定设备身份(`device.id`)。 -- Gateway 网关按设备 + 角色签发 token。 -- 新设备 ID 需要配对批准,除非启用了本地自动批准。 +- 节点应包含稳定的设备身份(`device.id`),该身份派生自密钥对指纹。 +- Gateway 网关按设备 + 角色发放令牌。 +- 除非启用了本地自动批准,否则新的设备 ID 需要配对批准。 - 配对自动批准以直接 local loopback 连接为中心。 -- OpenClaw 还为 - 受信任共享密钥辅助流程提供了一个狭窄的后端/容器本地自连接路径。 -- 同主机 tailnet 或 LAN 连接仍被视为远程配对, - 并且需要批准。 -- WS 客户端通常在 `connect` 期间包含 `device` 身份(操作员 + - 节点)。唯一的无设备操作员例外是显式信任路径: - - `gateway.controlUi.allowInsecureAuth=true` 用于仅 localhost 的不安全 HTTP 兼容性。 - - 成功的 `gateway.auth.mode: "trusted-proxy"` 操作员 Control UI 凭证。 - - `gateway.controlUi.dangerouslyDisableDeviceAuth=true`(应急手段,严重安全降级)。 - - 使用共享 Gateway 网关 token/password 认证的 direct-loopback `gateway-client` 后端 RPC。 -- 所有连接都必须签名服务器提供的 `connect.challenge` nonce。 +- OpenClaw 还为可信共享密钥辅助流程提供了一个范围很窄的后端/容器本地自连接路径。 +- 同主机 tailnet 或 LAN 连接在配对时仍被视为远程连接,并且需要批准。 +- WS 客户端通常会在 `connect` 期间包含 `device` 身份(操作者 + 节点)。仅有的无设备操作者例外是显式信任路径: + - `gateway.controlUi.allowInsecureAuth=true`,用于仅限 localhost 的不安全 HTTP 兼容性。 + - 成功的 `gateway.auth.mode: "trusted-proxy"` 操作者 Control UI 认证。 + - `gateway.controlUi.dangerouslyDisableDeviceAuth=true`(应急开关,严重降低安全性)。 + - 直接 loopback 的 `gateway-client` 后端 RPC,使用共享 Gateway 网关令牌/密码认证。 +- 所有连接都必须对服务器提供的 `connect.challenge` nonce 进行签名。 -### 设备凭证迁移诊断 +### 设备认证迁移诊断 -对于仍使用质询前签名行为的旧版客户端,`connect` 现在会在 -`error.details.code` 下返回 `DEVICE_AUTH_*` 详情代码,并带有稳定的 `error.details.reason`。 +对于仍使用挑战前签名行为的旧版客户端,`connect` 现在会在 `error.details.code` 下返回 +`DEVICE_AUTH_*` 详情代码,并带有稳定的 `error.details.reason`。 常见迁移失败: | 消息 | details.code | details.reason | 含义 | | --------------------------- | -------------------------------- | ------------------------ | -------------------------------------------------- | -| `device nonce required` | `DEVICE_AUTH_NONCE_REQUIRED` | `device-nonce-missing` | 客户端省略了 `device.nonce`(或发送为空)。 | -| `device nonce mismatch` | `DEVICE_AUTH_NONCE_MISMATCH` | `device-nonce-mismatch` | 客户端使用过期/错误 nonce 签名。 | -| `device signature invalid` | `DEVICE_AUTH_SIGNATURE_INVALID` | `device-signature` | 签名 payload 与 v2 payload 不匹配。 | -| `device signature expired` | `DEVICE_AUTH_SIGNATURE_EXPIRED` | `device-signature-stale` | 签名时间戳超出允许偏差。 | +| `device nonce required` | `DEVICE_AUTH_NONCE_REQUIRED` | `device-nonce-missing` | 客户端省略了 `device.nonce`(或发送了空值)。 | +| `device nonce mismatch` | `DEVICE_AUTH_NONCE_MISMATCH` | `device-nonce-mismatch` | 客户端使用过期/错误的 nonce 进行签名。 | +| `device signature invalid` | `DEVICE_AUTH_SIGNATURE_INVALID` | `device-signature` | 签名载荷与 v2 载荷不匹配。 | +| `device signature expired` | `DEVICE_AUTH_SIGNATURE_EXPIRED` | `device-signature-stale` | 签名时间戳超出了允许的偏差范围。 | | `device identity mismatch` | `DEVICE_AUTH_DEVICE_ID_MISMATCH` | `device-id-mismatch` | `device.id` 与公钥指纹不匹配。 | | `device public key invalid` | `DEVICE_AUTH_PUBLIC_KEY_INVALID` | `device-public-key` | 公钥格式/规范化失败。 | 迁移目标: - 始终等待 `connect.challenge`。 -- 签名包含服务器 nonce 的 v2 payload。 -- 在 `connect.params.device.nonce` 中发送相同 nonce。 -- 首选签名 payload 是 `v3`,除设备/客户端/角色/scope/token/nonce 字段外, - 它还绑定 `platform` 和 `deviceFamily`。 -- 为了兼容,仍接受旧版 `v2` 签名,但配对设备 - 元数据固定仍会在重连时控制命令策略。 +- 对包含服务器 nonce 的 v2 载荷进行签名。 +- 在 `connect.params.device.nonce` 中发送相同的 nonce。 +- 首选签名载荷是 `v3`,它除了绑定设备/客户端/角色/范围/令牌/nonce 字段外,还绑定 `platform` 和 `deviceFamily`。 +- 为了兼容性,旧版 `v2` 签名仍会被接受,但配对设备元数据固定仍会控制重新连接时的命令策略。 ## TLS + 固定 - WS 连接支持 TLS。 -- 客户端可以选择固定 Gateway 网关证书指纹(请参阅 `gateway.tls` - 配置,以及 `gateway.remote.tlsFingerprint` 或 CLI `--tls-fingerprint`)。 +- 客户端可以选择固定 Gateway 网关证书指纹(见 `gateway.tls` 配置,以及 `gateway.remote.tlsFingerprint` 或 CLI `--tls-fingerprint`)。 ## 范围 -此协议公开 **完整的 Gateway 网关 API**(Status、渠道、模型、聊天、 -智能体、会话、节点、审批等)。确切的表面由 -`src/gateway/protocol/schema.ts` 中的 TypeBox schema 定义。 +此协议暴露**完整 Gateway 网关 API**(Status、渠道、模型、聊天、智能体、会话、节点、批准等)。确切表面由 `src/gateway/protocol/schema.ts` 中的 TypeBox schema 定义。 ## 相关 diff --git a/docs/zh-CN/help/testing.md b/docs/zh-CN/help/testing.md index 7a085e327..459ff9de4 100644 --- a/docs/zh-CN/help/testing.md +++ b/docs/zh-CN/help/testing.md @@ -1,46 +1,46 @@ --- read_when: - 在本地或 CI 中运行测试 - - 为模型/提供商 bug 添加回归测试 + - 为模型/提供商缺陷添加回归测试 - 调试 Gateway 网关 + 智能体行为 summary: 测试工具包:单元/e2e/live 套件、Docker 运行器,以及每项测试覆盖的内容 title: 测试 x-i18n: - generated_at: "2026-04-29T04:29:51Z" + generated_at: "2026-04-29T05:40:33Z" model: gpt-5.5 provider: openai - source_hash: c2a7f6b046e845f0c1823923090f90b3c246357ee54835a6561dee128d7f1cfc + source_hash: 883840f97ca94a4e6b64cfce414da59ad3710ddd8e5e2e3ba04e33a83e96d407 source_path: help/testing.md workflow: 16 --- -OpenClaw 有三个 Vitest 套件(单元/集成、e2e、实时)和一小组 +OpenClaw 有三个 Vitest 套件(单元/集成、e2e、live)和一小组 Docker 运行器。本文档是一份“我们如何测试”的指南: -- 每个套件覆盖什么(以及它刻意 _不_ 覆盖什么)。 -- 常见工作流(本地、推送前、调试)应运行哪些命令。 -- 实时测试如何发现凭据并选择模型/提供商。 +- 每个套件覆盖什么(以及它有意_不_覆盖什么)。 +- 常见工作流(本地、推送前、调试)应该运行哪些命令。 +- live 测试如何发现凭证并选择模型/提供商。 - 如何为真实世界的模型/提供商问题添加回归测试。 -**QA 栈(qa-lab、qa-channel、实时传输通道)** 另有单独文档: +**QA 栈(qa-lab、qa-channel、live 传输通道)** 单独记录在以下文档中: - [QA overview](/zh-CN/concepts/qa-e2e-automation) — 架构、命令界面、场景编写。 - [Matrix QA](/zh-CN/concepts/qa-matrix) — `pnpm openclaw qa matrix` 的参考。 - [QA channel](/zh-CN/channels/qa-channel) — 由仓库支持的场景使用的合成传输插件。 -本页涵盖运行常规测试套件和 Docker/Parallels 运行器。下面的 QA 专用运行器部分([QA 专用运行器](#qa-specific-runners))列出了具体的 `qa` 调用,并指回上面的参考资料。 +本页介绍如何运行常规测试套件和 Docker/Parallels 运行器。下面的 QA 专用运行器部分([QA 专用运行器](#qa-specific-runners))列出了具体的 `qa` 调用,并指回上面的参考文档。 ## 快速开始 大多数时候: -- 完整门禁(推送前预期运行):`pnpm build && pnpm check && pnpm check:test-types && pnpm test` +- 完整门禁(推送前预期执行):`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` -- 当你在迭代单个失败时,优先运行有针对性的命令。 +- 直接 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` @@ -49,144 +49,154 @@ Docker 运行器。本文档是一份“我们如何测试”的指南: - 覆盖率门禁:`pnpm test:coverage` - E2E 套件:`pnpm test:e2e` -调试真实提供商/模型时(需要真实凭据): +调试真实提供商/模型时(需要真实凭证): -- 实时套件(模型 + Gateway 网关工具/图片探测):`pnpm test:live` -- 静默定位一个实时文件:`pnpm test:live -- src/agents/models.profiles.live.test.ts` -- Docker 实时模型扫描:`pnpm test:docker:live-models` - - 每个选中的模型现在都会运行一个文本轮次,以及一个小型文件读取风格探测。 - 元数据声明支持 `image` 输入的模型还会运行一个极小的图片轮次。 +- Live 套件(模型 + Gateway 网关工具/图片探测):`pnpm test:live` +- 安静地定位一个 live 文件:`pnpm test:live -- src/agents/models.profiles.live.test.ts` +- Docker live 模型扫描:`pnpm test:docker:live-models` + - 每个选中的模型现在会运行一次文本回合外加一个小型文件读取式探测。 + 元数据声明支持 `image` 输入的模型也会运行一次微型图片回合。 在隔离提供商失败时,可用 `OPENCLAW_LIVE_MODEL_FILE_PROBE=0` 或 - `OPENCLAW_LIVE_MODEL_IMAGE_PROBE=0` 禁用额外探测。 + `OPENCLAW_LIVE_MODEL_IMAGE_PROBE=0` 禁用这些额外探测。 - CI 覆盖:每日 `OpenClaw Scheduled Live And E2E Checks` 和手动 - `OpenClaw Release Checks` 都会使用 `include_live_suites: true` 调用可复用的实时/E2E 工作流,其中包含按提供商分片的独立 Docker 实时模型 - 矩阵作业。 - - 如需聚焦的 CI 重跑,使用 `include_live_suites: true` 和 `live_models_only: true` 分派 `OpenClaw Live And E2E Checks (Reusable)`。 + `OpenClaw Release Checks` 都会调用可复用的 live/E2E 工作流,并设置 + `include_live_suites: true`,其中包含按提供商分片的独立 Docker live 模型 + 矩阵任务。 + - 对于聚焦的 CI 重跑,分发 `OpenClaw Live And E2E Checks (Reusable)`, + 并设置 `include_live_suites: true` 和 `live_models_only: true`。 - 将新的高信号提供商密钥添加到 `scripts/ci-hydrate-live-auth.sh`, - 以及 `.github/workflows/openclaw-live-and-e2e-checks-reusable.yml` 和其 - 计划/发布调用方。 + 以及 `.github/workflows/openclaw-live-and-e2e-checks-reusable.yml` 和它的 + 定时/发布调用方中。 - 原生 Codex 绑定聊天冒烟测试:`pnpm test:docker:live-codex-bind` - - 针对 Codex 应用服务器路径运行一个 Docker 实时通道,绑定一个带 `/codex bind` 的合成 - Slack 私信,执行 `/codex fast` 和 - `/codex permissions`,然后验证普通回复和图片附件 - 通过原生插件绑定路由,而不是 ACP。 -- Codex 应用服务器测试框架冒烟测试:`pnpm test:docker:live-codex-harness` - - 通过插件自有的 Codex 应用服务器测试框架运行 Gateway 网关智能体轮次, - 验证 `/codex status` 和 `/codex models`,默认还执行图片、 - cron MCP、子智能体和 Guardian 探测。在隔离其他 Codex - 应用服务器失败时,可用 + - 针对 Codex app-server 路径运行 Docker live 通道,使用 `/codex bind` + 绑定一个合成 Slack 私信,执行 `/codex fast` 和 + `/codex permissions`,然后验证一条纯文本回复和一个图片附件通过原生插件绑定 + 路由,而不是通过 ACP。 +- Codex app-server harness 冒烟测试:`pnpm test:docker:live-codex-harness` + - 通过插件拥有的 Codex app-server harness 运行 Gateway 网关智能体回合, + 验证 `/codex status` 和 `/codex models`,并默认执行图片、cron MCP、子智能体和 Guardian 探测。在隔离其他 Codex + app-server 失败时,可用 `OPENCLAW_LIVE_CODEX_HARNESS_SUBAGENT_PROBE=0` 禁用子智能体探测。对于聚焦的子智能体检查,禁用其他探测: `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_SUBAGENT_PROBE=1 pnpm test:docker:live-codex-harness`。 - 这会在子智能体探测后退出,除非设置了 - `OPENCLAW_LIVE_CODEX_HARNESS_SUBAGENT_ONLY=0`。 + 除非设置了 + `OPENCLAW_LIVE_CODEX_HARNESS_SUBAGENT_ONLY=0`,否则这会在子智能体探测后退出。 - Crestodian 救援命令冒烟测试:`pnpm test:live:crestodian-rescue-channel` - - 面向消息渠道救援命令界面的可选双保险检查。 + - 对消息渠道救援命令界面的可选双保险检查。 它会执行 `/crestodian status`,排队一个持久模型 变更,回复 `/crestodian yes`,并验证审计/配置写入路径。 - Crestodian 规划器 Docker 冒烟测试:`pnpm test:docker:crestodian-planner` - - 在无配置容器中运行 Crestodian,并在 `PATH` - 上放置一个假的 Claude CLI,然后验证模糊规划器回退会转换为带审计的类型化 + - 在无配置容器中运行 Crestodian,`PATH` 上有一个假的 Claude CLI, + 并验证模糊规划器回退会转换为经过审计的类型化 配置写入。 - Crestodian 首次运行 Docker 冒烟测试:`pnpm test:docker:crestodian-first-run` - 从空的 OpenClaw 状态目录开始,将裸 `openclaw` 路由到 Crestodian,应用设置/模型/智能体/Discord 插件 + SecretRef 写入, - 验证配置,并验证审计条目。同一个 Ring 0 设置路径也在 QA Lab 中由 + 验证配置,并验证审计条目。同一条 Ring 0 设置路径 + 也在 QA Lab 中通过 `pnpm openclaw qa suite --scenario crestodian-ring-zero-setup` 覆盖。 - 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 环境变量缩小 live 测试范围。 ## QA 专用运行器 -当你需要 QA-lab 真实性时,这些命令与主测试套件并列使用: +当你需要 QA-lab 的真实度时,这些命令与主测试套件并列: -CI 在专用工作流中运行 QA Lab。`Parity gate` 会在匹配的 PR 上运行,并可通过手动分派使用模拟提供商运行。`QA-Lab - All Lanes` 每晚在 -`main` 上运行,也可通过手动分派运行,包含模拟一致性门禁、实时 Matrix 通道、 -Convex 管理的实时 Telegram 通道,以及 Convex 管理的实时 Discord 通道作为 -并行作业。计划 QA 和发布检查会显式传递 Matrix `--profile fast`, -而 Matrix CLI 和手动工作流输入默认仍为 -`all`;手动分派可以将 `all` 分片为 `transport`、`media`、`e2ee-smoke`、 -`e2ee-deep` 和 `e2ee-cli` 作业。`OpenClaw Release Checks` 会在发布批准前运行一致性检查以及 +CI 在专用工作流中运行 QA Lab。`Parity gate` 在匹配的 PR 上运行,并且 +可通过使用模拟提供商的手动分发运行。`QA-Lab - All Lanes` 每晚在 +`main` 上运行,也可通过手动分发运行,其中包含模拟奇偶门禁、live Matrix 通道、 +Convex 管理的 live Telegram 通道,以及 Convex 管理的 live Discord 通道, +这些都作为并行任务运行。定时 QA 和发布检查会显式传入 Matrix `--profile fast`, +而 Matrix CLI 和手动工作流输入的默认值仍为 +`all`;手动分发可以将 `all` 分片为 `transport`、`media`、`e2ee-smoke`、 +`e2ee-deep` 和 `e2ee-cli` 任务。`OpenClaw Release Checks` 在发布批准前运行奇偶检查以及 快速 Matrix 和 Telegram 通道,发布传输检查使用 -`mock-openai/gpt-5.5`,以保持确定性并避免常规提供商插件启动。这些实时传输 Gateway 网关会禁用 -内存搜索;内存行为仍由 QA 一致性套件覆盖。 +`mock-openai/gpt-5.5`,以保持确定性并避免常规提供商插件启动。这些 live 传输 Gateway 网关会禁用 +memory 搜索;memory 行为仍由 QA 奇偶套件覆盖。 -完整发布实时媒体分片使用 -`ghcr.io/openclaw/openclaw-live-media-runner:ubuntu-24.04`,其中已经包含 -`ffmpeg` 和 `ffprobe`。Docker 实时模型/后端分片使用共享的 -`ghcr.io/openclaw/openclaw-live-test:` 镜像,该镜像会针对每个选定 -提交构建一次,然后以 `OPENCLAW_SKIP_DOCKER_BUILD=1` 拉取它,而不是在每个分片中重新构建。 +完整发布 live 媒体分片使用 +`ghcr.io/openclaw/openclaw-live-media-runner:ubuntu-24.04`,其中已经有 +`ffmpeg` 和 `ffprobe`。Docker live 模型/后端分片使用共享的 +`ghcr.io/openclaw/openclaw-live-test:` 镜像,该镜像会为每个选定的 +提交构建一次,然后用 `OPENCLAW_SKIP_DOCKER_BUILD=1` 拉取它,而不是在 +每个分片内部重新构建。 - `pnpm openclaw qa suite` - 直接在主机上运行由仓库支持的 QA 场景。 - - 默认使用隔离的 Gateway 网关工作进程并行运行多个选中的场景。 - `qa-channel` 默认并发数为 4(受选中场景数量限制)。使用 `--concurrency ` 调整工作进程 - 数量,或使用 `--concurrency 1` 进入较旧的串行通道。 - - 任一场景失败时以非零状态退出。当你想要产物但不想要失败退出码时,使用 `--allow-failures`。 + - 默认使用隔离的 Gateway 网关工作器并行运行多个选定场景。 + `qa-channel` 默认并发为 4(受选定场景数量限制)。使用 `--concurrency ` 调整工作器 + 数量,或使用 `--concurrency 1` 运行较旧的串行通道。 + - 任一场景失败时以非零状态退出。当你 + 想要产物但不想要失败退出码时,使用 `--allow-failures`。 - 支持提供商模式 `live-frontier`、`mock-openai` 和 `aimock`。 - `aimock` 会启动本地 AIMock 支持的提供商服务器,用于实验性 - 固件和协议模拟覆盖,而不替换感知场景的 + `aimock` 会启动一个本地 AIMock 支持的提供商服务器,用于实验性 + fixture 和协议模拟覆盖,而不会替代场景感知的 `mock-openai` 通道。 - `pnpm test:gateway:cpu-scenarios` - - 运行 Gateway 网关启动基准测试以及一个小型模拟 QA Lab 场景包 + - 运行 Gateway 网关启动基准测试,以及一个小型模拟 QA Lab 场景包 (`channel-chat-baseline`、`memory-failure-fallback`、 - `gateway-restart-inflight-run`),并在 `.artifacts/gateway-cpu-scenarios/` 下写入合并 CPU 观测 + `gateway-restart-inflight-run`),并在 `.artifacts/gateway-cpu-scenarios/` + 下写入合并的 CPU 观察 摘要。 - - 默认只标记持续的高 CPU 观测(`--cpu-core-warn` - 加 `--hot-wall-warn-ms`),因此短暂启动峰值会作为指标记录, - 而不会看起来像持续数分钟的 Gateway 网关占满 CPU 回归。 - - 使用构建后的 `dist` 产物;当检出内容尚无新的运行时输出时,先运行构建。 + - 默认只标记持续的高 CPU 观察(`--cpu-core-warn` + 加 `--hot-wall-warn-ms`),因此短暂的启动突发会被记录为指标, + 而不会看起来像持续数分钟的 Gateway 网关占满回归。 + - 使用构建好的 `dist` 产物;当检出内容中还没有新的运行时输出时, + 先运行构建。 - `pnpm openclaw qa suite --runner multipass` - 在一次性 Multipass Linux VM 中运行同一个 QA 套件。 - 保持与主机上的 `qa suite` 相同的场景选择行为。 - 复用与 `qa suite` 相同的提供商/模型选择标志。 - - 实时运行会转发对 guest 可行的受支持 QA 认证输入: - 基于环境的提供商密钥、QA 实时提供商配置路径,以及存在时的 `CODEX_HOME`。 - - 输出目录必须保留在仓库根目录下,以便 guest 可以通过挂载的工作区写回。 + - Live 运行会转发对 guest 实用的受支持 QA auth 输入: + 基于环境变量的提供商 key、QA live 提供商配置路径,以及存在时的 `CODEX_HOME`。 + - 输出目录必须保留在仓库根目录下,以便 guest 能通过 + 挂载的工作区写回。 - 在 `.artifacts/qa-e2e/...` 下写入常规 QA 报告 + 摘要以及 Multipass 日志。 - `pnpm qa:lab:up` - 启动 Docker 支持的 QA 站点,用于操作员风格的 QA 工作。 - `pnpm test:docker:npm-onboard-channel-agent` - - 从当前检出构建 npm tarball,在 Docker 中全局安装它,运行非交互式 OpenAI API 密钥新手引导,默认配置 Telegram, - 验证启用插件会按需安装运行时依赖项,运行 Doctor,并针对模拟的 OpenAI - 端点运行一个本地智能体轮次。 - - 使用 `OPENCLAW_NPM_ONBOARD_CHANNEL=discord` 以 Discord 运行同一个打包安装 + - 从当前检出内容构建一个 npm tarball,在 + Docker 中全局安装它,运行非交互式 OpenAI API key 新手引导,默认配置 Telegram, + 验证启用插件会按需安装运行时依赖,运行 Doctor,并针对模拟的 OpenAI + 端点运行一个本地智能体回合。 + - 使用 `OPENCLAW_NPM_ONBOARD_CHANNEL=discord` 通过 Discord 运行同一个打包安装 通道。 - `pnpm test:docker:session-runtime-context` - - 针对嵌入式运行时上下文转录运行确定性的已构建应用 Docker 冒烟测试。 - 它验证隐藏的 OpenClaw 运行时上下文会作为非显示自定义消息持久化,而不是泄漏进可见的用户轮次, - 然后植入一个受影响的损坏会话 JSONL,并验证 + - 为嵌入式运行时上下文转录运行确定性的已构建应用 Docker 冒烟测试。 + 它会验证隐藏的 OpenClaw 运行时上下文会作为非展示的自定义消息持久化, + 而不是泄露到可见用户回合中,然后植入一个受影响的损坏会话 JSONL,并验证 `openclaw doctor --fix` 会将其重写到活动分支并创建备份。 - `pnpm test:docker:npm-telegram-live` - - 在 Docker 中安装一个 OpenClaw 候选包,运行已安装包 + - 在 Docker 中安装 OpenClaw 候选包,运行已安装包的 新手引导,通过已安装的 CLI 配置 Telegram,然后复用 - 实时 Telegram QA 通道,并将该已安装包作为被测系统 Gateway 网关。 - - 默认使用 `OPENCLAW_NPM_TELEGRAM_PACKAGE_SPEC=openclaw@beta`;设置 + live Telegram QA 通道,并将该已安装包作为 SUT Gateway 网关。 + - 默认值为 `OPENCLAW_NPM_TELEGRAM_PACKAGE_SPEC=openclaw@beta`;设置 `OPENCLAW_NPM_TELEGRAM_PACKAGE_TGZ=/path/to/openclaw-current.tgz` 或 - `OPENCLAW_CURRENT_PACKAGE_TGZ` 来测试已解析的本地 tarball,而不是 + `OPENCLAW_CURRENT_PACKAGE_TGZ` 可测试已解析的本地 tarball,而不是 从 registry 安装。 - - 使用与 `pnpm openclaw qa telegram` 相同的 Telegram 环境凭据或 Convex 凭据来源。对于 CI/发布自动化,设置 + - 使用与 `pnpm openclaw qa telegram` 相同的 Telegram 环境变量凭证或 Convex 凭证源。 + 对于 CI/发布自动化,设置 `OPENCLAW_NPM_TELEGRAM_CREDENTIAL_SOURCE=convex`,以及 `OPENCLAW_QA_CONVEX_SITE_URL` 和角色密钥。如果 - `OPENCLAW_QA_CONVEX_SITE_URL` 和 Convex 角色密钥在 CI 中存在, + `OPENCLAW_QA_CONVEX_SITE_URL` 和一个 Convex 角色密钥存在于 CI 中, Docker 包装器会自动选择 Convex。 - - `OPENCLAW_NPM_TELEGRAM_CREDENTIAL_ROLE=ci|maintainer` 仅为此通道覆盖共享的 + - `OPENCLAW_NPM_TELEGRAM_CREDENTIAL_ROLE=ci|maintainer` 只为此通道覆盖共享的 `OPENCLAW_QA_CREDENTIAL_ROLE`。 - GitHub Actions 将此通道暴露为手动维护者工作流 `NPM Telegram Beta E2E`。它不会在合并时运行。该工作流使用 - `qa-live-shared` 环境和 Convex CI 凭据租约。 -- GitHub Actions 还暴露 `Package Acceptance`,用于针对一个候选包进行旁路产品证明。 - 它接受可信 ref、已发布 npm 规范、 + `qa-live-shared` 环境和 Convex CI 凭证租约。 +- GitHub Actions 还暴露了 `Package Acceptance`,用于针对一个候选包进行旁路产品证明。 + 它接受可信 ref、已发布的 npm spec、 HTTPS tarball URL 加 SHA-256,或来自另一次运行的 tarball 产物,上传 规范化的 `openclaw-current.tgz` 作为 `package-under-test`,然后使用 smoke、package、product、full 或 custom - 通道配置文件运行现有 Docker E2E 调度器。设置 `telegram_mode=mock-openai` 或 `live-frontier`,可针对同一个 `package-under-test` 产物运行 - Telegram QA 工作流。 + 通道 profile 运行现有 Docker E2E 调度器。设置 `telegram_mode=mock-openai` 或 `live-frontier` 可让 + Telegram QA 工作流针对同一个 `package-under-test` 产物运行。 - 最新 beta 产品证明: ```bash @@ -207,7 +217,7 @@ gh workflow run package-acceptance.yml --ref main \ -f suite_profile=package ``` -- 制品证明会从另一个 Actions 运行下载 tarball 制品: +- 工件证明会从另一个 Actions 运行下载 tarball 工件: ```bash gh workflow run package-acceptance.yml --ref main \ @@ -218,44 +228,44 @@ gh workflow run package-acceptance.yml --ref main \ ``` - `pnpm test:docker:bundled-channel-deps` - - 在 Docker 中打包并安装当前 OpenClaw 构建,启动已配置 OpenAI 的 Gateway 网关,然后通过配置编辑启用内置渠道/插件。 + - 在 Docker 中打包并安装当前 OpenClaw 构建,使用已配置的 OpenAI 启动 Gateway 网关,然后通过配置编辑启用内置渠道/插件。 - 验证设置发现会让未配置的插件运行时依赖保持缺失,首次配置的 Gateway 网关或 Doctor 运行会按需安装每个内置插件的运行时依赖,并且第二次重启不会重新安装已激活的依赖。 - - 还会安装一个已知较旧的 npm 基线,在运行 `openclaw update --tag ` 前启用 Telegram,并验证候选版本的更新后 Doctor 会修复内置渠道运行时依赖,而不需要 harness 侧的 postinstall 修复。 + - 还会安装一个已知的较旧 npm 基线,在运行 `openclaw update --tag ` 前启用 Telegram,并验证候选版本的更新后 Doctor 会修复内置渠道运行时依赖,无需 harness 侧 postinstall 修复。 - `pnpm test:parallels:npm-update` - - 跨 Parallels 客户机运行原生打包安装更新 smoke。每个选中的平台会先安装请求的基线包,然后在同一客户机中运行已安装的 `openclaw update` 命令,并验证已安装版本、更新 Status、Gateway 网关就绪状态以及一次本地智能体轮次。 - - 迭代单个客户机时使用 `--platform macos`、`--platform windows` 或 `--platform linux`。使用 `--json` 获取摘要制品路径和每条 lane 的 Status。 - - OpenAI lane 默认使用 `openai/gpt-5.5` 作为实时智能体轮次证明。刻意验证另一个 OpenAI 模型时,传入 `--model ` 或设置 `OPENCLAW_PARALLELS_OPENAI_MODEL`。 - - 将较长的本地运行包装在主机超时中,避免 Parallels 传输停滞消耗剩余测试窗口: + - 跨 Parallels 客户机运行原生打包安装更新冒烟测试。每个选中的平台先安装请求的基线包,然后在同一个客户机中运行已安装的 `openclaw update` 命令,并验证已安装版本、更新 Status、Gateway 网关就绪状态,以及一次本地智能体回合。 + - 在迭代单个客户机时使用 `--platform macos`、`--platform windows` 或 `--platform linux`。使用 `--json` 获取摘要工件路径和每条 lane 的 Status。 + - OpenAI lane 默认使用 `openai/gpt-5.5` 作为实时智能体回合证明。若要刻意验证另一个 OpenAI 模型,请传入 `--model ` 或设置 `OPENCLAW_PARALLELS_OPENAI_MODEL`。 + - 用主机超时包装长时间本地运行,避免 Parallels 传输停滞耗尽剩余测试窗口: ```bash timeout --foreground 150m pnpm test:parallels:npm-update -- --json timeout --foreground 90m pnpm test:parallels:npm-update -- --platform windows --json ``` - - 该脚本会在 `/tmp/openclaw-parallels-npm-update.*` 下写入嵌套 lane 日志。在假设外层包装器挂起之前,先检查 `windows-update.log`、`macos-update.log` 或 `linux-update.log`。 + - 脚本会在 `/tmp/openclaw-parallels-npm-update.*` 下写入嵌套 lane 日志。在假定外层包装器挂起之前,先检查 `windows-update.log`、`macos-update.log` 或 `linux-update.log`。 - 在冷启动客户机上,Windows 更新可能会在更新后 Doctor/运行时依赖修复中花费 10 到 15 分钟;只要嵌套 npm 调试日志仍在推进,这仍然是正常的。 - - 不要将这个聚合包装器与单独的 Parallels macOS、Windows 或 Linux smoke lane 并行运行。它们共享虚拟机状态,可能在快照恢复、包服务或客户机 Gateway 网关状态上冲突。 - - 更新后证明会运行常规内置插件表面,因为 speech、image generation 和 media understanding 等 capability facade 是通过内置运行时 API 加载的,即使智能体轮次本身只检查简单文本响应。 + - 不要将这个聚合包装器与单独的 Parallels macOS、Windows 或 Linux 冒烟 lane 并行运行。它们共享虚拟机状态,可能在快照恢复、包服务或客户机 Gateway 网关状态上发生冲突。 + - 更新后证明会运行常规内置插件表面,因为语音、图像生成和媒体理解等能力 facade 是通过内置运行时 API 加载的,即使智能体回合本身只检查一个简单文本响应。 - `pnpm openclaw qa aimock` - - 仅启动本地 AIMock provider 服务器,用于直接协议 smoke 测试。 + - 仅启动本地 AIMock provider 服务器,用于直接协议冒烟测试。 - `pnpm openclaw qa matrix` - - 针对一次性 Docker 支持的 Tuwunel homeserver 运行 Matrix 实时 QA lane。仅限源码检出 — 打包安装不随附 `qa-lab`。 - - 完整 CLI、profile/scenario 目录、环境变量和制品布局:[Matrix QA](/zh-CN/concepts/qa-matrix)。 + - 针对一次性 Docker 支持的 Tuwunel homeserver 运行 Matrix 实时 QA lane。仅源代码检出可用 — 打包安装不会发布 `qa-lab`。 + - 完整 CLI、profile/场景目录、环境变量和工件布局:[Matrix QA](/zh-CN/concepts/qa-matrix)。 - `pnpm openclaw qa telegram` - - 使用来自环境变量的 driver 和 SUT bot 令牌,在真实私有群组中运行 Telegram 实时 QA lane。 - - 需要 `OPENCLAW_QA_TELEGRAM_GROUP_ID`、`OPENCLAW_QA_TELEGRAM_DRIVER_BOT_TOKEN` 和 `OPENCLAW_QA_TELEGRAM_SUT_BOT_TOKEN`。群组 id 必须是数字 Telegram chat id。 - - 支持 `--credential-source convex` 以使用共享池化凭证。默认使用环境变量模式,或设置 `OPENCLAW_QA_CREDENTIAL_SOURCE=convex` 选择使用池化租约。 - - 任何 scenario 失败时会以非零码退出。需要制品但不想失败退出码时,使用 `--allow-failures`。 + - 使用来自环境变量的 driver 和 SUT bot token,针对真实私有群组运行 Telegram 实时 QA lane。 + - 需要 `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 报告、摘要和 observed-messages 制品。回复 scenario 会包含从 driver 发送请求到观测到 SUT 回复的 RTT。 + - 为获得稳定的 bot 到 bot 观察,在两个 bot 的 `@BotFather` 中启用机器人到机器人通信模式,并确保 driver bot 可以观察群组 bot 流量。 + - 在 `.artifacts/qa-e2e/...` 下写入 Telegram QA 报告、摘要和 observed-messages 工件。回复场景包含从 driver 发送请求到观察到 SUT 回复的 RTT。 -实时传输 lane 共享一个标准契约,使新传输不会漂移;每条 lane 的覆盖矩阵位于 [QA overview → 实时传输覆盖](/zh-CN/concepts/qa-e2e-automation#live-transport-coverage)。`qa-channel` 是宽泛的合成套件,不属于该矩阵。 +实时传输 lane 共享一个标准契约,避免新传输漂移;每条 lane 的覆盖矩阵位于 [QA overview → 实时传输覆盖范围](/zh-CN/concepts/qa-e2e-automation#live-transport-coverage)。`qa-channel` 是广泛的合成套件,不属于该矩阵。 -### 通过 Convex 共享 Telegram 凭证(v1) +### 通过 Convex 共享 Telegram 凭据(v1) -为 `openclaw qa telegram` 启用 `--credential-source convex`(或 `OPENCLAW_QA_CREDENTIAL_SOURCE=convex`)时,QA lab 会从 Convex 支持的池中获取独占租约,在 lane 运行期间为该租约发送心跳,并在关闭时释放租约。 +为 `openclaw qa telegram` 启用 `--credential-source convex`(或 `OPENCLAW_QA_CREDENTIAL_SOURCE=convex`)后,QA lab 会从 Convex 支持的池中获取独占租约,在 lane 运行期间对该租约发送心跳,并在关闭时释放租约。 参考 Convex 项目脚手架: @@ -267,9 +277,9 @@ gh workflow run package-acceptance.yml --ref main \ - 所选角色的一个密钥: - `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`) 可选环境变量: @@ -278,12 +288,12 @@ gh workflow run package-acceptance.yml --ref main \ - `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`(可选 trace id) -- `OPENCLAW_QA_ALLOW_INSECURE_HTTP=1` 允许仅本地开发使用 loopback `http://` Convex URL。 +- `OPENCLAW_QA_CREDENTIAL_OWNER_ID`(可选跟踪 ID) +- `OPENCLAW_QA_ALLOW_INSECURE_HTTP=1` 允许仅本地开发使用环回 `http://` Convex URL。 -正常操作中,`OPENCLAW_QA_CONVEX_SITE_URL` 应使用 `https://`。 +`OPENCLAW_QA_CONVEX_SITE_URL` 在正常运行中应使用 `https://`。 -维护者管理命令(池 add/remove/list)明确需要 `OPENCLAW_QA_CONVEX_SECRET_MAINTAINER`。 +维护者管理命令(池 add/remove/list)专门需要 `OPENCLAW_QA_CONVEX_SECRET_MAINTAINER`。 维护者 CLI 辅助命令: @@ -294,9 +304,9 @@ pnpm openclaw qa credentials list --kind telegram pnpm openclaw qa credentials remove --credential-id ``` -在实时运行前使用 `doctor` 检查 Convex site URL、broker 密钥、endpoint 前缀、HTTP 超时以及 admin/list 可达性,且不会打印密钥值。在脚本和 CI 工具中使用 `--json` 获取机器可读输出。 +在实时运行前使用 `doctor` 检查 Convex 站点 URL、broker 密钥、端点前缀、HTTP 超时和 admin/list 可达性,且不会打印密钥值。在脚本和 CI 工具中使用 `--json` 获取机器可读输出。 -默认 endpoint 契约(`OPENCLAW_QA_CONVEX_SITE_URL` + `/qa-credentials/v1`): +默认端点契约(`OPENCLAW_QA_CONVEX_SITE_URL` + `/qa-credentials/v1`): - `POST /acquire` - 请求:`{ kind, ownerId, actorRole, leaseTtlMs, heartbeatIntervalMs }` @@ -319,126 +329,127 @@ pnpm openclaw qa credentials remove --credential-id - 请求:`{ kind?, status?, includePayload?, limit? }` - 成功:`{ status: "ok", credentials, count }` -Telegram kind 的 payload 形状: +Telegram 类型的 payload 形状: - `{ groupId: string, driverToken: string, sutToken: string }` -- `groupId` 必须是数字 Telegram chat id 字符串。 -- `admin/add` 会为 `kind: "telegram"` 验证该形状,并拒绝格式错误的 payload。 +- `groupId` 必须是数字 Telegram 聊天 ID 字符串。 +- `admin/add` 会针对 `kind: "telegram"` 验证此形状,并拒绝格式错误的 payload。 ### 向 QA 添加渠道 -新渠道适配器的架构和 scenario-helper 名称位于 [QA overview → 添加渠道](/zh-CN/concepts/qa-e2e-automation#adding-a-channel)。最低要求:在共享的 `qa-lab` host seam 上实现传输 runner,在插件 manifest 中声明 `qaRunners`,挂载为 `openclaw qa `,并在 `qa/scenarios/` 下编写 scenario。 +新渠道适配器的架构和场景辅助函数名称位于 [QA overview → 添加渠道](/zh-CN/concepts/qa-e2e-automation#adding-a-channel)。最低要求:在共享 `qa-lab` host seam 上实现传输 runner,在插件 manifest 中声明 `qaRunners`,挂载为 `openclaw qa `,并在 `qa/scenarios/` 下编写场景。 ## 测试套件(在哪里运行什么) -可以把这些套件理解为“真实度递增”(同时脆弱性/成本也递增): +可以把这些套件理解为“逐步提高真实性”(同时也提高不稳定性/成本): ### 单元 / 集成(默认) - 命令:`pnpm test` -- 配置:非目标运行使用 `vitest.full-*.config.ts` shard 集,并可能将多项目 shard 展开为每项目配置以便并行调度 -- 文件:`src/**/*.test.ts`、`packages/**/*.test.ts` 和 `test/**/*.test.ts` 下的 core/unit 清单;UI 单元测试在专用 `unit-ui` shard 中运行 +- 配置:未定向运行使用 `vitest.full-*.config.ts` 分片集,并可能将多项目分片展开为按项目配置以进行并行调度 +- 文件:`src/**/*.test.ts`、`packages/**/*.test.ts` 和 `test/**/*.test.ts` 下的核心/单元清单;UI 单元测试在专用 `unit-ui` 分片中运行 - 范围: - 纯单元测试 - - 进程内集成测试(Gateway 网关 auth、routing、tooling、parsing、配置) + - 进程内集成测试(Gateway 网关鉴权、路由、工具调用、解析、配置) - 已知 bug 的确定性回归 - 预期: - 在 CI 中运行 - 不需要真实密钥 - - 应快速且稳定 + - 应该快速且稳定 - + - - 非定向的 `pnpm test` 会运行十二个更小的分片配置(`core-unit-fast`、`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` 项目图,因为多分片 watch 循环并不实用。 - - `pnpm test`、`pnpm test:watch` 和 `pnpm test:perf:imports` 会先通过有作用域的通道分流显式文件/目录目标,因此 `pnpm test extensions/discord/src/monitor/message-handler.preflight.test.ts` 可以避免支付完整根项目启动成本。 - - `pnpm test:changed` 默认会将已更改的 git 路径展开为低成本的有作用域通道:直接测试编辑、同级 `*.test.ts` 文件、显式源码映射,以及本地导入图依赖项。配置/设置/package 编辑不会广泛运行测试,除非你显式使用 `OPENCLAW_TEST_CHANGED_BROAD=1 pnpm test:changed`。 - - `pnpm check:changed` 是窄范围工作的常规智能本地检查门禁。它会将 diff 分类为核心、核心测试、插件、插件测试、应用、文档、发布元数据、实时 Docker 工具和工具链,然后运行匹配的类型检查、lint 和保护命令。它不会运行 Vitest 测试;需要测试证明时,请调用 `pnpm test:changed` 或显式的 `pnpm test `。仅发布元数据的版本号提升会运行有针对性的版本/配置/根依赖检查,并带有一个保护规则,用于拒绝顶层 version 字段以外的 package 变更。 - - 实时 Docker ACP harness 编辑会运行聚焦检查:实时 Docker auth 脚本的 shell 语法检查,以及实时 Docker 调度器 dry-run。仅当 diff 限定在 `scripts["test:docker:live-*"]` 时,才会包含 `package.json` 变更;依赖、导出、版本和其他 package 表面编辑仍使用更广泛的保护规则。 - - 来自 agents、commands、plugins、auto-reply helpers、`plugin-sdk` 和类似纯工具区域的轻导入单元测试会通过 `unit-fast` 通道,该通道会跳过 `test/setup-openclaw-runtime.ts`;有状态/运行时较重的文件仍保留在现有通道上。 - - 选定的 `plugin-sdk` 和 `commands` helper 源文件也会把 changed-mode 运行映射到这些轻量通道中的显式同级测试,因此 helper 编辑可以避免重新运行该目录的完整重型套件。 - - `auto-reply` 为顶层核心 helpers、顶层 `reply.*` 集成测试,以及 `src/auto-reply/reply/**` 子树提供专用 bucket。CI 还会进一步把 reply 子树拆分为 agent-runner、dispatch 和 commands/state-routing 分片,这样单个导入较重的 bucket 就不会占用完整的 Node 尾部时间。 + - 未指定目标的 `pnpm test` 会运行十二个更小的分片配置(`core-unit-fast`、`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/extension 工作让无关套件资源不足。 + - `pnpm test --watch` 仍然使用原生根 `vitest.config.ts` 项目图,因为多分片 watch 循环并不实用。 + - `pnpm test`、`pnpm test:watch` 和 `pnpm test:perf:imports` 会先通过作用域车道分派显式文件/目录目标,因此 `pnpm test extensions/discord/src/monitor/message-handler.preflight.test.ts` 可以避免承担完整根项目启动成本。 + - `pnpm test:changed` 默认会把已变更的 git 路径展开为低成本的作用域车道:直接测试编辑、相邻 `*.test.ts` 文件、显式源码映射,以及本地导入图依赖项。Config/Setup/package 编辑不会广泛运行测试,除非你显式使用 `OPENCLAW_TEST_CHANGED_BROAD=1 pnpm test:changed`。 + - `pnpm check:changed` 是窄范围工作的常规智能本地检查门禁。它会把 diff 分类为 core、core tests、extensions、extension tests、apps、docs、release metadata、live Docker tooling 和 tooling,然后运行匹配的 typecheck、lint 和 guard 命令。它不会运行 Vitest 测试;如需测试证明,请调用 `pnpm test:changed` 或显式 `pnpm test `。仅 release metadata 的版本号提升会运行定向 version/config/root-dependency 检查,并带有一个 guard,用来拒绝顶层 version 字段以外的 package 变更。 + - Live Docker ACP harness 编辑会运行聚焦检查:live Docker auth 脚本的 shell 语法检查,以及 live Docker scheduler dry-run。只有当 diff 限定在 `scripts["test:docker:live-*"]` 时才包含 `package.json` 变更;dependency、export、version 和其他 package 表面编辑仍然使用更广的 guard。 + - 来自 agents、commands、plugins、auto-reply helpers、`plugin-sdk` 以及类似纯工具区域的轻导入单元测试会走 `unit-fast` 车道,该车道会跳过 `test/setup-openclaw-runtime.ts`;有状态或运行时较重的文件仍保留在现有车道。 + - 选定的 `plugin-sdk` 和 `commands` helper 源文件也会把 changed-mode 运行映射到这些轻量车道中的显式相邻测试,因此 helper 编辑可以避免为该目录重新运行完整重型套件。 + - `auto-reply` 为顶层 core helpers、顶层 `reply.*` 集成测试以及 `src/auto-reply/reply/**` 子树设置了专用桶。CI 还会进一步把 reply 子树拆分为 agent-runner、dispatch 和 commands/state-routing 分片,避免一个导入较重的桶占用完整 Node 尾部时间。 - + - - 当你更改消息工具发现输入或压缩运行时 + - 当你更改 message-tool 发现输入或 compaction 运行时 上下文时,请保留两层覆盖。 - - 为纯路由和规范化 - 边界添加聚焦的 helper 回归测试。 - - 保持嵌入式 runner 集成套件健康: + - 为纯 routing 和 normalization + 边界添加聚焦 helper 回归测试。 + - 保持嵌入式运行器集成套件健康: `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.loop.test.ts`。 - - 这些套件会验证有作用域的 id 和压缩行为仍通过真实的 + - 这些套件会验证 scoped ids 和 compaction 行为仍然通过真实的 `run.ts` / `compact.ts` 路径流动;仅 helper 的测试 不能充分替代这些集成路径。 - + - 基础 Vitest 配置默认使用 `threads`。 - 共享 Vitest 配置固定 `isolate: false`,并在根项目、e2e 和 live 配置中使用 - 非隔离 runner。 - - 根 UI 通道保留其 `jsdom` 设置和优化器,但也运行在 - 共享的非隔离 runner 上。 - - 每个 `pnpm test` 分片都会继承共享 Vitest 配置中的同一组 `threads` + `isolate: false` + 非隔离运行器。 + - 根 UI 车道保留其 `jsdom` 设置和优化器,但也运行在 + 共享的非隔离运行器上。 + - 每个 `pnpm test` 分片都从共享 Vitest 配置继承相同的 `threads` + `isolate: false` 默认值。 - `scripts/run-vitest.mjs` 默认会为 Vitest 子 Node 进程添加 `--no-maglev`,以减少大型本地运行期间的 V8 编译抖动。 - 设置 `OPENCLAW_VITEST_ENABLE_MAGLEV=1` 可与原生 V8 - 行为进行比较。 + 设置 `OPENCLAW_VITEST_ENABLE_MAGLEV=1` 可与原始 V8 + 行为对比。 - + - - `pnpm changed:lanes` 会显示一个 diff 触发了哪些架构通道。 - - pre-commit hook 仅处理格式化。它会重新暂存已格式化的文件, - 不会运行 lint、类型检查或测试。 - - 在交接或 push 前,当你需要智能本地检查门禁时, + - `pnpm changed:lanes` 会显示一个 diff 触发了哪些架构车道。 + - pre-commit hook 仅负责格式化。它会重新暂存已格式化文件, + 不会运行 lint、typecheck 或测试。 + - 在交接或 push 之前,当你需要智能本地检查门禁时, 显式运行 `pnpm check:changed`。 - - `pnpm test:changed` 默认通过低成本有作用域通道分流。仅当智能体 - 判断 harness、配置、package 或契约编辑确实需要更广泛的 - Vitest 覆盖时,才使用 `OPENCLAW_TEST_CHANGED_BROAD=1 pnpm test:changed`。 - - `pnpm test:max` 和 `pnpm test:changed:max` 保持相同的分流 + - `pnpm test:changed` 默认会通过低成本作用域车道分派。只有当 agent + 判断 harness、config、package 或 contract 编辑确实需要更广的 + Vitest 覆盖时,才使用 + `OPENCLAW_TEST_CHANGED_BROAD=1 pnpm test:changed`。 + - `pnpm test:max` 和 `pnpm test:changed:max` 保持相同的路由 行为,只是使用更高的 worker 上限。 - - 本地 worker 自动扩缩容刻意保持保守,并会在主机负载平均值已经较高时 - 回退,因此多个并发 - Vitest 运行默认造成的影响更小。 - - 基础 Vitest 配置会将项目/配置文件标记为 - `forceRerunTriggers`,这样当测试 - wiring 变化时,changed-mode 重新运行仍保持正确。 - - 配置会在受支持的主机上保持 `OPENCLAW_VITEST_FS_MODULE_CACHE` 启用; - 如果你想为直接性能分析指定一个显式缓存位置,请设置 `OPENCLAW_VITEST_FS_MODULE_CACHE_PATH=/abs/path`。 + - 本地 worker 自动扩缩容有意保持保守,并会在主机负载平均值已经很高时退避, + 因此默认情况下多个并发 + Vitest 运行造成的影响更小。 + - 基础 Vitest 配置会把 projects/config 文件标记为 + `forceRerunTriggers`,因此当测试 + 线路变更时,changed-mode 重新运行仍能保持正确。 + - 该配置会在受支持的主机上保持启用 `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:imports` 会启用 Vitest import-duration 报告以及 + import-breakdown 输出。 + - `pnpm test:perf:imports:changed` 会把同一性能分析视图限定到 + 自 `origin/main` 以来变更的文件。 - 分片计时数据会写入 `.artifacts/vitest-shard-timings.json`。 - 整体配置运行使用配置路径作为键;include-pattern CI - 分片会追加分片名称,以便分别跟踪已过滤的分片。 - - 当某个热点测试仍将大部分时间花在启动导入上时, - 请把重型依赖放在窄范围本地 `*.runtime.ts` 接缝之后,并 - 直接 mock 该接缝,而不是为了将运行时 helpers 传给 `vi.mock(...)` - 而深度导入它们。 - - `pnpm test:perf:changed:bench -- --ref ` 会将分流后的 - `test:changed` 与该已提交 diff 的原生根项目路径进行比较, - 并打印 wall time 加 macOS 最大 RSS。 - - `pnpm test:perf:changed:bench -- --worktree` 会通过将已更改文件列表传给 - `scripts/test-projects.mjs` 和根 Vitest 配置,来基准测试当前 - dirty tree。 + 全配置运行使用配置路径作为键;include-pattern CI + 分片会追加分片名称,以便单独跟踪过滤后的分片。 + - 当某个热点测试仍把大部分时间花在启动导入上时, + 请把重型依赖放在狭窄的本地 `*.runtime.ts` 接缝之后,并 + 直接 mock 该接缝,而不是深度导入运行时 helper,只为了 + 把它们传给 `vi.mock(...)`。 + - `pnpm test:perf:changed:bench -- --ref ` 会将已提交 + diff 的路由后 `test:changed` 与原生根项目路径进行对比, + 并打印 wall time 与 macOS max RSS。 + - `pnpm test:perf:changed:bench -- --worktree` 会通过把 changed file list 路由到 + `scripts/test-projects.mjs` 和根 Vitest 配置来对当前 + dirty tree 做基准测试。 - `pnpm test:perf:profile:main` 会为 Vitest/Vite 启动和 transform 开销写入主线程 CPU profile。 - - `pnpm test:perf:profile:runner` 会在禁用文件并行的情况下,为 + - `pnpm test:perf:profile:runner` 会在禁用文件并行时为 单元套件写入 runner CPU+heap profiles。 @@ -449,14 +460,14 @@ Telegram kind 的 payload 形状: - 命令:`pnpm test:stability:gateway` - 配置:`vitest.gateway.config.ts`,强制使用一个 worker - 范围: - - 默认在启用诊断的情况下启动一个真实的 loopback Gateway 网关 - - 通过诊断事件路径驱动合成的 Gateway 网关消息、内存和大载荷 churn + - 默认启动一个启用诊断的真实 loopback Gateway 网关 + - 通过诊断事件路径驱动合成 gateway 消息、内存和大载荷 churn - 通过 Gateway 网关 WS RPC 查询 `diagnostics.stability` - 覆盖诊断稳定性 bundle 持久化 helpers - - 断言 recorder 保持有界,合成 RSS 样本低于压力预算,并且每会话队列深度会排空回零 + - 断言 recorder 保持有界、合成 RSS 样本保持低于 pressure budget,并且每个会话队列深度回落到零 - 预期: - CI 安全且不需要密钥 - - 用于稳定性回归跟进的窄通道,不是完整 Gateway 网关套件的替代品 + - 这是用于 stability-regression 跟进的窄车道,不是完整 Gateway 网关套件的替代品 ### E2E(Gateway 网关 smoke) @@ -464,36 +475,36 @@ Telegram kind 的 payload 形状: - 配置:`vitest.e2e.config.ts` - 文件:`src/**/*.e2e.test.ts`、`test/**/*.e2e.test.ts`,以及 `extensions/` 下的内置插件 E2E 测试 - 运行时默认值: - - 使用 Vitest `threads` 和 `isolate: false`,与 repo 其余部分匹配。 - - 使用自适应 workers(CI:最多 2,本地:默认 1)。 - - 默认以 silent mode 运行,以减少 console I/O 开销。 -- 有用的 override: - - `OPENCLAW_E2E_WORKERS=` 用于强制 worker 数量(上限 16)。 - - `OPENCLAW_E2E_VERBOSE=1` 用于重新启用详细 console 输出。 + - 使用 Vitest `threads` 和 `isolate: false`,与仓库其余部分一致。 + - 使用自适应 workers(CI:最多 2 个,本地:默认 1 个)。 + - 默认以 silent 模式运行,以减少 console I/O 开销。 +- 实用覆盖: + - `OPENCLAW_E2E_WORKERS=` 强制 worker 数量(上限 16)。 + - `OPENCLAW_E2E_VERBOSE=1` 重新启用详细 console 输出。 - 范围: - - 多实例 Gateway 网关端到端行为 - - WebSocket/HTTP 表面、节点配对,以及更重的网络行为 + - 多实例 gateway 端到端行为 + - WebSocket/HTTP 表面、node 配对以及更重的网络 - 预期: - - 在 CI 中运行(当 pipeline 启用时) + - 在 CI 中运行(当 pipeline 中启用时) - 不需要真实密钥 - - 比单元测试有更多 moving parts(可能更慢) + - 比单元测试有更多移动部件(可能更慢) ### E2E:OpenShell 后端 smoke - 命令:`pnpm test:e2e:openshell` - 文件:`extensions/openshell/src/backend.e2e.test.ts` - 范围: - - 通过 Docker 在主机上启动一个隔离的 OpenShell gateway - - 从临时本地 Dockerfile 创建一个沙箱 - - 通过真实的 `sandbox ssh-config` + SSH exec 练习 OpenClaw 的 OpenShell 后端 + - 通过 Docker 在主机上启动隔离的 OpenShell gateway + - 从临时本地 Dockerfile 创建沙箱 + - 通过真实的 `sandbox ssh-config` + SSH exec 运行 OpenClaw 的 OpenShell 后端 - 通过沙箱 fs bridge 验证 remote-canonical 文件系统行为 - 预期: - 仅 opt-in;不属于默认 `pnpm test:e2e` 运行的一部分 - - 需要本地 `openshell` CLI 加可用的 Docker daemon - - 使用隔离的 `HOME` / `XDG_CONFIG_HOME`,随后销毁测试 gateway 和沙箱 -- 有用的 override: - - `OPENCLAW_E2E_OPENSHELL=1` 用于在手动运行更广泛 e2e 套件时启用该测试 - - `OPENCLAW_E2E_OPENSHELL_COMMAND=/path/to/openshell` 用于指向非默认 CLI binary 或 wrapper script + - 需要本地 `openshell` CLI 以及可工作的 Docker daemon + - 使用隔离的 `HOME` / `XDG_CONFIG_HOME`,然后销毁测试 gateway 和沙箱 +- 实用覆盖: + - `OPENCLAW_E2E_OPENSHELL=1` 在手动运行更广的 e2e 套件时启用该测试 + - `OPENCLAW_E2E_OPENSHELL_COMMAND=/path/to/openshell` 指向非默认 CLI binary 或 wrapper script ### Live(真实提供商 + 真实模型) @@ -502,20 +513,20 @@ Telegram kind 的 payload 形状: - 文件:`src/**/*.live.test.ts`、`test/**/*.live.test.ts`,以及 `extensions/` 下的内置插件 live 测试 - 默认:由 `pnpm test:live` **启用**(设置 `OPENCLAW_LIVE_TEST=1`) - 范围: - - “这个提供商/模型 _今天_ 是否确实能用真实凭证工作?” - - 捕获提供商格式变化、工具调用怪癖、auth 问题,以及 rate limit 行为 + - “这个提供商/模型在 _今天_ 使用真实凭证是否确实可用?” + - 捕获提供商格式变更、tool-calling 特性差异、auth 问题和 rate limit 行为 - 预期: - - 设计上不保证 CI 稳定(真实网络、真实提供商策略、配额、故障) - - 会花钱 / 使用 rate limits - - 优先运行缩小范围的子集,而不是“一切” + - 设计上不具备 CI 稳定性(真实网络、真实提供商策略、配额、故障) + - 会产生费用 / 使用 rate limits + - 优先运行缩窄后的子集,而不是“全部” - Live 运行会 source `~/.profile` 以获取缺失的 API keys。 -- 默认情况下,live 运行仍会隔离 `HOME`,并将配置/auth 材料复制到临时测试 home 中,这样单元 fixtures 就无法修改你的真实 `~/.openclaw`。 -- 仅当你有意需要 live 测试使用你的真实 home 目录时,才设置 `OPENCLAW_LIVE_USE_REAL_HOME=1`。 -- `pnpm test:live` 现在默认使用更安静的模式:它保留 `[live] ...` progress 输出,但抑制额外的 `~/.profile` notice,并静音 Gateway 网关 bootstrap 日志/Bonjour chatter。如果你想恢复完整启动日志,请设置 `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` 设置每个 live override;测试会在 rate limit 响应时重试。 -- Progress/heartbeat 输出: - - Live 套件现在会向 stderr 发出 progress 行,因此即使 Vitest console capture 很安静,长时间提供商调用也能看到处于 active 状态。 - - `vitest.live.config.ts` 会禁用 Vitest console interception,因此提供商/Gateway 网关 progress 行会在 live 运行期间立即流式输出。 +- 默认情况下,live 运行仍会隔离 `HOME`,并把 config/auth material 复制到临时测试 home,这样单元 fixture 就不能改变你的真实 `~/.openclaw`。 +- 仅当你有意需要 live tests 使用你的真实 home directory 时,才设置 `OPENCLAW_LIVE_USE_REAL_HOME=1`。 +- `pnpm test:live` 现在默认使用更安静的模式:它保留 `[live] ...` 进度输出,但会抑制额外的 `~/.profile` notice,并静音 gateway bootstrap logs/Bonjour chatter。如果你想恢复完整 startup logs,请设置 `OPENCLAW_LIVE_TEST_QUIET=0`。 +- API key rotation(特定提供商):设置 `*_API_KEYS`,格式为逗号/分号分隔,或设置 `*_API_KEY_1`、`*_API_KEY_2`(例如 `OPENAI_API_KEYS`、`ANTHROPIC_API_KEYS`、`GEMINI_API_KEYS`),也可以通过 `OPENCLAW_LIVE_*_KEY` 进行 per-live override;测试会在 rate limit responses 时重试。 +- 进度/heartbeat 输出: + - Live 套件现在会向 stderr 发出进度行,因此即使 Vitest console capture 较安静,长时间提供商调用也能明显显示仍在活跃。 + - `vitest.live.config.ts` 禁用 Vitest console interception,因此提供商/gateway 进度行会在 live 运行期间立即流式输出。 - 使用 `OPENCLAW_LIVE_HEARTBEAT_MS` 调整 direct-model heartbeats。 - 使用 `OPENCLAW_LIVE_GATEWAY_HEARTBEAT_MS` 调整 gateway/probe heartbeats。 @@ -524,176 +535,173 @@ Telegram kind 的 payload 形状: 使用这个决策表: - 编辑逻辑/测试:运行 `pnpm test`(如果你改动很多,也运行 `pnpm test:coverage`) -- 触及 Gateway 网关网络 / WS protocol / pairing:添加 `pnpm test:e2e` -- 调试“我的 bot 挂了” / 特定提供商失败 / 工具调用:运行缩小范围的 `pnpm test:live` +- 触及 gateway networking / WS protocol / pairing:添加 `pnpm test:e2e` +- 调试“我的 bot 宕机了” / 特定提供商失败 / tool calling:运行缩窄后的 `pnpm test:live` -## Live(触及网络的)测试 +## Live(触网)测试 -针对实时模型矩阵、CLI 后端冒烟测试、ACP 冒烟测试、Codex app-server 测试框架,以及所有媒体提供商实时测试(Deepgram、BytePlus、ComfyUI、图像、 -音乐、视频、媒体测试框架)——再加上实时运行的凭据处理——请参阅 -[测试 — 实时套件](/zh-CN/help/testing-live)。 +有关真实模型矩阵、CLI 后端冒烟测试、ACP 冒烟测试、Codex 应用服务器 +harness,以及所有媒体提供商真实服务测试(Deepgram、BytePlus、ComfyUI、图像、 +音乐、视频、媒体 harness),以及真实运行的凭证处理,请参阅 +[测试 —— 真实服务套件](/zh-CN/help/testing-live)。 ## 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 镜像内运行对应的配置键真实服务文件(`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 镜像,通过 `scripts/package-openclaw-for-docker.mjs` 将 OpenClaw 打包一次为 npm tarball,然后构建/复用两个 `scripts/e2e/Dockerfile` 镜像。基础镜像只是用于安装/更新/插件依赖 lane 的 Node/Git 运行器;这些 lane 会挂载预构建的 tarball。功能镜像会将同一个 tarball 安装到 `/app`,用于已构建应用的功能 lane。Docker lane 定义位于 `scripts/lib/docker-e2e-scenarios.mjs`;规划器逻辑位于 `scripts/lib/docker-e2e-plan.mjs`;`scripts/test-docker-all.mjs` 执行选定计划。聚合运行使用加权本地调度器:`OPENCLAW_DOCKER_ALL_PARALLELISM` 控制进程槽位,而资源上限会避免繁重的实时、npm 安装和多服务 lane 同时启动。如果单个 lane 比当前上限更重,调度器仍可在池为空时启动它,并让它单独运行,直到容量再次可用。默认值为 10 个槽位、`OPENCLAW_DOCKER_ALL_LIVE_LIMIT=9`、`OPENCLAW_DOCKER_ALL_NPM_LIMIT=10` 和 `OPENCLAW_DOCKER_ALL_SERVICE_LIMIT=7`;只有当 Docker 主机有更多余量时,才调整 `OPENCLAW_DOCKER_ALL_WEIGHT_LIMIT` 或 `OPENCLAW_DOCKER_ALL_DOCKER_LIMIT`。运行器默认执行 Docker 预检,移除陈旧的 OpenClaw E2E 容器,每 30 秒打印一次 Status,将成功 lane 的耗时存储在 `.artifacts/docker-tests/lane-timings.json` 中,并在后续运行中使用这些耗时优先启动更长的 lane。使用 `OPENCLAW_DOCKER_ALL_DRY_RUN=1` 可以在不构建或运行 Docker 的情况下打印加权 lane manifest,或使用 `node scripts/test-docker-all.mjs --plan-json` 打印所选 lane、package/镜像需求和凭据的 CI 计划。 -- `Package Acceptance` 是 GitHub 原生的 package 门禁,用于回答“这个可安装 tarball 能否作为产品工作?”它会从 `source=npm`、`source=ref`、`source=url` 或 `source=artifact` 解析一个候选 package,将其上传为 `package-under-test`,然后针对这个确切的 tarball 运行可复用的 Docker E2E lane,而不是重新打包选定的 ref。`workflow_ref` 选择受信任的 workflow/harness 脚本,而 `package_ref` 在 `source=ref` 时选择要打包的源 commit/branch/tag;这让当前验收逻辑能够验证较旧的受信任 commit。profile 按覆盖广度排序:`smoke` 是快速安装/渠道/智能体加 Gateway 网关/配置,`package` 是 package/更新/插件契约,也是大多数 Parallels package/更新覆盖的默认原生替代项,`product` 添加 MCP 渠道、cron/subagent 清理、OpenAI Web 搜索和 OpenWebUI,`full` 则运行带 OpenWebUI 的发布路径 Docker 分块。发布验证会运行自定义 package delta(`bundled-channel-deps-compat plugins-offline`)以及 Telegram package QA,因为发布路径 Docker 分块已经覆盖了重叠的 package/更新/插件 lane。从 artifact 生成的定向 GitHub Docker 重跑命令会在可用时包含先前的 package artifact 和已准备的镜像输入,因此失败的 lane 可以避免重新构建 package 和镜像。 -- 构建和发布检查会在 tsdown 之后运行 `scripts/check-cli-bootstrap-imports.mjs`。该守卫会遍历来自 `dist/entry.js` 和 `dist/cli/run-main.js` 的静态构建图;如果命令分发前的启动阶段导入了 Commander、prompt UI、undici 或日志等 package 依赖,它会失败;它还会确保内置 Gateway 网关运行分块保持在预算内,并拒绝对已知冷启动 Gateway 网关路径的静态导入。打包后的 CLI 冒烟测试还覆盖根帮助、新手引导帮助、Doctor 帮助、Status、配置 schema 和模型列表命令。 -- Package Acceptance 旧版兼容性上限为 `2026.4.25`(包括 `2026.4.25-beta.*`)。在该截止版本之前,harness 只容忍已发布 package 的元数据缺口:省略的私有 QA 清单条目、缺失的 `gateway install --wrapper`、tarball 派生 git fixture 中缺失的 patch 文件、缺失的持久化 `update.channel`、旧版插件安装记录位置、缺失的 marketplace 安装记录持久化,以及 `plugins update` 期间的配置元数据迁移。对于 `2026.4.25` 之后的 package,这些路径都是严格失败。 + `OPENCLAW_LIVE_GATEWAY_MODEL_TIMEOUT_MS=90000`。只有在你明确需要更大的穷尽式扫描时,才覆盖这些环境变量。 +- `test:docker:all` 会先通过 `test:docker:live-build` 构建一次真实服务 Docker 镜像,再通过 `scripts/package-openclaw-for-docker.mjs` 将 OpenClaw 打包一次为 npm tarball,然后构建/复用两个 `scripts/e2e/Dockerfile` 镜像。裸镜像只是用于安装/更新/插件依赖通道的 Node/Git 运行器;这些通道会挂载预构建的 tarball。功能镜像会把同一个 tarball 安装到 `/app`,用于已构建应用功能通道。Docker 通道定义位于 `scripts/lib/docker-e2e-scenarios.mjs`;规划器逻辑位于 `scripts/lib/docker-e2e-plan.mjs`;`scripts/test-docker-all.mjs` 执行选定计划。聚合流程使用加权本地调度器:`OPENCLAW_DOCKER_ALL_PARALLELISM` 控制进程槽位,而资源上限会避免繁重的真实服务、npm 安装和多服务通道同时全部启动。如果单个通道比当前上限更重,调度器仍可在池为空时启动它,并让它单独运行,直到容量再次可用。默认值为 10 个槽位、`OPENCLAW_DOCKER_ALL_LIVE_LIMIT=9`、`OPENCLAW_DOCKER_ALL_NPM_LIMIT=10` 和 `OPENCLAW_DOCKER_ALL_SERVICE_LIMIT=7`;只有当 Docker 主机有更多余量时,才调整 `OPENCLAW_DOCKER_ALL_WEIGHT_LIMIT` 或 `OPENCLAW_DOCKER_ALL_DOCKER_LIMIT`。运行器默认执行 Docker 预检,移除陈旧的 OpenClaw E2E 容器,每 30 秒打印一次状态,将成功通道耗时存储在 `.artifacts/docker-tests/lane-timings.json`,并在后续运行中使用这些耗时优先启动更长的通道。使用 `OPENCLAW_DOCKER_ALL_DRY_RUN=1` 可在不构建或运行 Docker 的情况下打印加权通道清单,或使用 `node scripts/test-docker-all.mjs --plan-json` 打印选定通道、包/镜像需求和凭证的 CI 计划。 +- `Package Acceptance` 是 GitHub 原生的包门禁,用于验证“这个可安装的 tarball 作为产品是否可用?”它会从 `source=npm`、`source=ref`、`source=url` 或 `source=artifact` 解析一个候选包,将其上传为 `package-under-test`,然后针对这个精确的 tarball 运行可复用的 Docker E2E 通道,而不是重新打包所选 ref。`workflow_ref` 选择受信任的工作流/harness 脚本,而 `package_ref` 在 `source=ref` 时选择要打包的源提交/分支/标签;这使当前验收逻辑能够验证较旧的受信任提交。配置按覆盖面排序:`smoke` 是快速安装/渠道/智能体加 Gateway 网关/配置,`package` 是包/更新/插件契约,也是大多数 Parallels 包/更新覆盖的默认原生替代,`product` 添加 MCP 渠道、cron/子智能体清理、OpenAI Web 搜索和 OpenWebUI,`full` 使用 OpenWebUI 运行发布路径 Docker 分块。发布验证运行一个自定义包差异(`bundled-channel-deps-compat plugins-offline`),外加 Telegram 包 QA,因为发布路径 Docker 分块已经覆盖重叠的包/更新/插件通道。从构件生成的定向 GitHub Docker 重跑命令会在可用时包含先前的包构件和已准备镜像输入,因此失败通道可以避免重新构建包和镜像。 +- 构建和发布检查会在 tsdown 后运行 `scripts/check-cli-bootstrap-imports.mjs`。该守卫从 `dist/entry.js` 和 `dist/cli/run-main.js` 遍历静态构建图,如果命令分派前的启动阶段导入了 Commander、提示 UI、undici 或日志等包依赖,就会失败;它还会让打包的 Gateway 网关运行分块保持在预算内,并拒绝对已知冷 Gateway 网关路径的静态导入。打包 CLI 冒烟测试还覆盖根帮助、onboard 帮助、doctor 帮助、Status、配置架构,以及模型列表命令。 +- Package Acceptance 旧版兼容性上限为 `2026.4.25`(包括 `2026.4.25-beta.*`)。在该截止版本之前,harness 只容忍已发布包的元数据缺口:省略的私有 QA 清单条目、缺失的 `gateway install --wrapper`、tarball 派生 git fixture 中缺失的补丁文件、缺失的持久化 `update.channel`、旧版插件安装记录位置、缺失的 marketplace 安装记录持久化,以及 `plugins update` 期间的配置元数据迁移。对于 `2026.4.25` 之后的包,这些路径都是严格失败。 - 容器冒烟运行器:`test:docker:openwebui`、`test:docker:onboard`、`test:docker:npm-onboard-channel-agent`、`test:docker:update-channel-switch`、`test:docker:session-runtime-context`、`test:docker:agents-delete-shared-workspace`、`test:docker:gateway-network`、`test:docker:browser-cdp-snapshot`、`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 运行器还只会绑定挂载所需的 CLI 认证主目录(如果运行未缩窄,则挂载所有受支持的主目录),然后在运行前将它们复制到容器主目录中,以便外部 CLI OAuth 可以刷新令牌而不改变主机认证存储: +真实模型 Docker 运行器还只会绑定挂载所需的 CLI 认证主目录(或在运行未缩小时挂载所有支持的主目录),然后在运行前将其复制到容器主目录,使外部 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`;默认覆盖 Claude、Codex 和 Gemini,并通过 `pnpm test:docker:live-acp-bind:droid` 和 `pnpm test:docker:live-acp-bind:opencode` 严格覆盖 Droid/OpenCode) +- ACP 绑定冒烟测试:`pnpm test:docker:live-acp-bind`(脚本:`scripts/test-live-acp-bind-docker.sh`;默认覆盖 Claude、Codex 和 Gemini,并通过 `pnpm test:docker:live-acp-bind:droid` 和 `pnpm test:docker:live-acp-bind:opencode` 对 Droid/OpenCode 做严格覆盖) - 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`) - Gateway 网关 + 开发智能体:`pnpm test:docker:live-gateway`(脚本:`scripts/test-live-gateway-models-docker.sh`) -- 可观测性冒烟测试:`pnpm qa:otel:smoke` 是私有 QA 源码检出任务线。它有意不属于包 Docker 发布任务线,因为 npm tarball 会省略 QA Lab。 +- 可观测性冒烟测试:`pnpm qa:otel:smoke` 是私有 QA 源码检出通道。它有意不属于软件包 Docker 发布通道,因为 npm tarball 会省略 QA Lab。 - 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,验证 Doctor 会修复已激活插件的运行时依赖,然后运行一次模拟的 OpenAI 智能体轮次。可使用 `OPENCLAW_CURRENT_PACKAGE_TGZ=/path/to/openclaw-*.tgz` 复用预构建 tarball,使用 `OPENCLAW_NPM_ONBOARD_HOST_BUILD=0` 跳过宿主机重建,或使用 `OPENCLAW_NPM_ONBOARD_CHANNEL=discord` 切换渠道。 -- 更新渠道切换冒烟测试:`pnpm test:docker:update-channel-switch` 会在 Docker 中全局安装打包好的 OpenClaw tarball,从包 `stable` 切换到 git `dev`,验证持久化的渠道和插件更新后行为,然后切回包 `stable` 并检查更新 Status。 +- Npm tarball 新手引导/渠道/智能体冒烟测试:`pnpm test:docker:npm-onboard-channel-agent` 会在 Docker 中全局安装打包好的 OpenClaw tarball,通过 env-ref 新手引导配置 OpenAI,并默认配置 Telegram,验证 Doctor 是否修复已启用插件的运行时依赖,并运行一次模拟的 OpenAI 智能体轮次。使用 `OPENCLAW_CURRENT_PACKAGE_TGZ=/path/to/openclaw-*.tgz` 复用预构建 tarball,用 `OPENCLAW_NPM_ONBOARD_HOST_BUILD=0` 跳过主机重建,或用 `OPENCLAW_NPM_ONBOARD_CHANNEL=discord` 切换渠道。 +- 更新渠道切换冒烟测试:`pnpm test:docker:update-channel-switch` 会在 Docker 中全局安装打包好的 OpenClaw tarball,从软件包 `stable` 切换到 git `dev`,验证持久化的渠道和插件更新后工作正常,然后切回软件包 `stable` 并检查更新 Status。 - 会话运行时上下文冒烟测试:`pnpm test:docker:session-runtime-context` 会验证隐藏运行时上下文转录持久化,以及 Doctor 对受影响的重复提示词重写分支的修复。 -- Bun 全局安装冒烟测试:`bash scripts/e2e/bun-global-install-smoke.sh` 会打包当前树,在隔离 home 中用 `bun install -g` 安装,并验证 `openclaw infer image providers --json` 返回内置图像提供商而不是挂起。可使用 `OPENCLAW_BUN_GLOBAL_SMOKE_PACKAGE_TGZ=/path/to/openclaw-*.tgz` 复用预构建 tarball,使用 `OPENCLAW_BUN_GLOBAL_SMOKE_HOST_BUILD=0` 跳过宿主机构建,或使用 `OPENCLAW_BUN_GLOBAL_SMOKE_DIST_IMAGE=openclaw-dockerfile-smoke:local` 从已构建的 Docker 镜像复制 `dist/`。 -- 安装器 Docker 冒烟测试:`bash scripts/test-install-sh-docker.sh` 在它的 root、update 和 direct-npm 容器之间共享一个 npm 缓存。更新冒烟测试默认以 npm `latest` 作为稳定基线,然后升级到候选 tarball。本地可用 `OPENCLAW_INSTALL_SMOKE_UPDATE_BASELINE=2026.4.22` 覆盖,或在 GitHub 上使用 Install Smoke 工作流的 `update_baseline_version` 输入覆盖。非 root 安装器检查会保留隔离的 npm 缓存,避免 root 拥有的缓存条目掩盖用户本地安装行为。设置 `OPENCLAW_INSTALL_SMOKE_NPM_CACHE_DIR=/path/to/cache` 可在本地重跑之间复用 root/update/direct-npm 缓存。 -- Install Smoke CI 会用 `OPENCLAW_INSTALL_SMOKE_SKIP_NPM_GLOBAL=1` 跳过重复的 direct-npm 全局更新;当需要覆盖直接 `npm install -g` 时,在本地运行该脚本且不要设置该环境变量。 -- 智能体删除共享工作区 CLI 冒烟测试:`pnpm test:docker:agents-delete-shared-workspace`(脚本:`scripts/e2e/agents-delete-shared-workspace-docker.sh`)默认构建根 Dockerfile 镜像,在隔离容器 home 中为两个智能体播种一个工作区,运行 `agents delete --json`,并验证 JSON 有效以及工作区保留行为。可使用 `OPENCLAW_AGENTS_DELETE_SHARED_WORKSPACE_E2E_IMAGE=openclaw-dockerfile-smoke:local OPENCLAW_AGENTS_DELETE_SHARED_WORKSPACE_E2E_SKIP_BUILD=1` 复用 install-smoke 镜像。 -- Gateway 网关联网(两个容器,WS 认证 + 健康检查):`pnpm test:docker:gateway-network`(脚本:`scripts/e2e/gateway-network-docker.sh`) -- 浏览器 CDP 快照冒烟测试:`pnpm test:docker:browser-cdp-snapshot`(脚本:`scripts/e2e/browser-cdp-snapshot-docker.sh`)会构建源码 E2E 镜像和一个 Chromium 层,用原始 CDP 启动 Chromium,运行 `browser doctor --deep`,并验证 CDP 角色快照覆盖链接 URL、由光标提升的可点击项、iframe 引用和 frame 元数据。 -- 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 桥接 + 原始 Claude 通知帧冒烟测试):`pnpm test:docker:mcp-channels`(脚本:`scripts/e2e/mcp-channels-docker.sh`) -- Pi bundle MCP 工具(真实 stdio MCP 服务器 + 嵌入式 Pi profile 允许/拒绝冒烟测试):`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`) +- Bun 全局安装冒烟测试:`bash scripts/e2e/bun-global-install-smoke.sh` 会打包当前树,在隔离的 home 中用 `bun install -g` 安装它,并验证 `openclaw infer image providers --json` 返回内置图像提供商而不是挂起。使用 `OPENCLAW_BUN_GLOBAL_SMOKE_PACKAGE_TGZ=/path/to/openclaw-*.tgz` 复用预构建 tarball,用 `OPENCLAW_BUN_GLOBAL_SMOKE_HOST_BUILD=0` 跳过主机构建,或用 `OPENCLAW_BUN_GLOBAL_SMOKE_DIST_IMAGE=openclaw-dockerfile-smoke:local` 从已构建的 Docker 镜像复制 `dist/`。 +- 安装器 Docker 冒烟测试:`bash scripts/test-install-sh-docker.sh` 会在它的 root、update 和 direct-npm 容器之间共享一个 npm 缓存。更新冒烟测试默认以 npm `latest` 作为升级到候选 tarball 之前的 stable 基线。本地可用 `OPENCLAW_INSTALL_SMOKE_UPDATE_BASELINE=2026.4.22` 覆盖,或在 GitHub 上用 Install Smoke 工作流的 `update_baseline_version` 输入覆盖。非 root 安装器检查会保留隔离的 npm 缓存,避免 root 拥有的缓存条目掩盖用户本地安装行为。设置 `OPENCLAW_INSTALL_SMOKE_NPM_CACHE_DIR=/path/to/cache` 可在本地重复运行时复用 root/update/direct-npm 缓存。 +- Install Smoke CI 会用 `OPENCLAW_INSTALL_SMOKE_SKIP_NPM_GLOBAL=1` 跳过重复的 direct-npm 全局更新;需要覆盖直接 `npm install -g` 时,在本地运行脚本且不带该环境变量。 +- 智能体删除共享工作区 CLI 冒烟测试:`pnpm test:docker:agents-delete-shared-workspace`(脚本:`scripts/e2e/agents-delete-shared-workspace-docker.sh`)默认构建根 Dockerfile 镜像,在隔离容器 home 中为两个智能体填充一个工作区,运行 `agents delete --json`,并验证有效 JSON 以及保留工作区的行为。使用 `OPENCLAW_AGENTS_DELETE_SHARED_WORKSPACE_E2E_IMAGE=openclaw-dockerfile-smoke:local OPENCLAW_AGENTS_DELETE_SHARED_WORKSPACE_E2E_SKIP_BUILD=1` 复用 install-smoke 镜像。 +- Gateway 网关网络(两个容器,WS 身份验证 + 健康检查):`pnpm test:docker:gateway-network`(脚本:`scripts/e2e/gateway-network-docker.sh`) +- 浏览器 CDP 快照冒烟测试:`pnpm test:docker:browser-cdp-snapshot`(脚本:`scripts/e2e/browser-cdp-snapshot-docker.sh`)会构建源码 E2E 镜像以及一个 Chromium 层,使用原始 CDP 启动 Chromium,运行 `browser doctor --deep`,并验证 CDP 角色快照覆盖链接 URL、游标提升的可点击项、iframe 引用和框架元数据。 +- OpenAI Responses `web_search` minimal 推理回归:`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 桥接 + 原始 Claude 通知帧冒烟测试):`pnpm test:docker:mcp-channels`(脚本:`scripts/e2e/mcp-channels-docker.sh`) +- Pi bundle MCP 工具(真实 stdio MCP 服务器 + 嵌入式 Pi 配置文件 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`) - 插件(安装冒烟测试、ClawHub kitchen-sink 安装/卸载、marketplace 更新,以及 Claude-bundle 启用/检查):`pnpm test:docker:plugins`(脚本:`scripts/e2e/plugins-docker.sh`) - 设置 `OPENCLAW_PLUGINS_E2E_CLAWHUB=0` 可跳过 ClawHub 块,或用 `OPENCLAW_PLUGINS_E2E_CLAWHUB_SPEC` 和 `OPENCLAW_PLUGINS_E2E_CLAWHUB_ID` 覆盖默认的 kitchen-sink 包/运行时组合。如果没有 `OPENCLAW_CLAWHUB_URL`/`CLAWHUB_URL`,测试会使用一个 hermetic 本地 ClawHub fixture 服务器。 -- 插件未变更更新冒烟测试:`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 runner 镜像,在宿主机上构建并打包一次 OpenClaw,然后把该 tarball 挂载到每个 Linux 安装场景中。可用 `OPENCLAW_SKIP_DOCKER_BUILD=1` 复用镜像,在一次新的本地构建后用 `OPENCLAW_BUNDLED_CHANNEL_HOST_BUILD=0` 跳过宿主机重建,或用 `OPENCLAW_CURRENT_PACKAGE_TGZ=/path/to/openclaw-*.tgz` 指向现有 tarball。完整 Docker 聚合和 release-path 内置渠道分块会预先打包一次该 tarball,然后把内置渠道检查分片到独立任务线中,包括 Telegram、Discord、Slack、Feishu、memory-lancedb 和 ACPX 的独立更新任务线。发布分块会把渠道冒烟测试、更新目标和设置/运行时契约拆分到 `bundled-channels-core`、`bundled-channels-update-a`、`bundled-channels-update-b` 和 `bundled-channels-contracts`;聚合的 `bundled-channels` 分块仍可用于手动重跑。发布工作流还会拆分提供商安装器分块和内置插件安装/卸载分块;旧的 `package-update`、`plugins-runtime` 和 `plugins-integrations` 分块仍作为手动重跑的聚合别名保留。直接运行内置任务线时,可使用 `OPENCLAW_BUNDLED_CHANNELS=telegram,slack` 缩小渠道矩阵,或用 `OPENCLAW_BUNDLED_CHANNEL_UPDATE_TARGETS=telegram,acpx` 缩小更新场景。该任务线还会验证 `channels..enabled=false` 和 `plugins.entries..enabled=false` 会抑制 Doctor/运行时依赖修复。 -- 迭代时可通过禁用无关场景来缩小内置插件运行时依赖范围,例如: + 设置 `OPENCLAW_PLUGINS_E2E_CLAWHUB=0` 可跳过 ClawHub 块,或用 `OPENCLAW_PLUGINS_E2E_CLAWHUB_SPEC` 和 `OPENCLAW_PLUGINS_E2E_CLAWHUB_ID` 覆盖默认的 kitchen-sink 软件包/运行时组合。没有 `OPENCLAW_CLAWHUB_URL`/`CLAWHUB_URL` 时,测试会使用封闭的本地 ClawHub fixture 服务器。 +- 插件更新未变化冒烟测试:`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 runner 镜像,在主机上构建并打包一次 OpenClaw,然后把该 tarball 挂载到每个 Linux 安装场景中。用 `OPENCLAW_SKIP_DOCKER_BUILD=1` 复用镜像,在一次新的本地构建后用 `OPENCLAW_BUNDLED_CHANNEL_HOST_BUILD=0` 跳过主机重建,或用 `OPENCLAW_CURRENT_PACKAGE_TGZ=/path/to/openclaw-*.tgz` 指向现有 tarball。完整 Docker 聚合和发布路径内置渠道分块会先预打包一次该 tarball,然后将内置渠道检查拆分到独立通道,包括 Telegram、Discord、Slack、Feishu、memory-lancedb 和 ACPX 的单独更新通道。发布分块会把渠道冒烟测试、更新目标以及设置/运行时契约拆分为 `bundled-channels-core`、`bundled-channels-update-a`、`bundled-channels-update-b` 和 `bundled-channels-contracts`;聚合的 `bundled-channels` 分块仍可用于手动重跑。发布工作流还会拆分提供商安装器分块和内置插件安装/卸载分块;旧版 `package-update`、`plugins-runtime` 和 `plugins-integrations` 分块仍作为手动重跑的聚合别名保留。直接运行内置通道时,用 `OPENCLAW_BUNDLED_CHANNELS=telegram,slack` 缩小渠道矩阵,或用 `OPENCLAW_BUNDLED_CHANNEL_UPDATE_TARGETS=telegram,acpx` 缩小更新场景。每场景 Docker 运行默认使用 `OPENCLAW_BUNDLED_CHANNEL_DOCKER_RUN_TIMEOUT=900s`;多目标更新场景默认使用 `OPENCLAW_BUNDLED_CHANNEL_UPDATE_DOCKER_RUN_TIMEOUT=2400s`。该通道还会验证 `channels..enabled=false` 和 `plugins.entries..enabled=false` 会抑制 Doctor/运行时依赖修复。 +- 迭代时可通过禁用无关场景来缩小内置插件运行时依赖,例如: `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-functional:local pnpm test:docker:e2e-build OPENCLAW_DOCKER_E2E_IMAGE=openclaw-docker-e2e-functional: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,因为它们验证的是软件包/安装行为,而不是共享的已构建应用运行时。 -live-model Docker 运行器还会以只读方式 bind-mount 当前 checkout,并 -在容器内把它暂存到临时 workdir。这样既能让运行时镜像保持精简, -又能针对你的精确本地源码/配置运行 Vitest。 +实时模型 Docker runner 还会以只读方式 bind-mount 当前检出, +并在容器内将它暂存到临时 workdir。这会让运行时 +镜像保持精简,同时仍然针对你确切的本地源码/配置运行 Vitest。 暂存步骤会跳过大型本地专用缓存和应用构建输出,例如 `.pnpm-store`、`.worktrees`、`__openclaw_vitest__`,以及应用本地 `.build` 或 -Gradle 输出目录,因此 Docker live 运行不会花几分钟复制 -机器特定的产物。 -它们还会设置 `OPENCLAW_SKIP_CHANNELS=1`,这样 Gateway 网关 live 探测不会在容器内启动 -真实的 Telegram/Discord 等渠道 worker。 -`test:docker:live-models` 仍会运行 `pnpm test:live`,因此当你需要在该 Docker 任务线中缩小或排除 Gateway 网关 -live 覆盖范围时,也要传入 +Gradle 输出目录,这样 Docker 实时运行就不会花费数分钟复制 +机器专用产物。 +它们还会设置 `OPENCLAW_SKIP_CHANNELS=1`,这样 Gateway 网关实时探测就不会在 +容器内启动真实的 Telegram/Discord 等渠道 worker。 +`test:docker:live-models` 仍然运行 `pnpm test:live`,因此当你需要从该 Docker 通道 +缩小或排除 Gateway 网关实时覆盖时,也要传入 `OPENCLAW_LIVE_GATEWAY_*`。 -`test:docker:openwebui` 是更高层的兼容性冒烟测试:它会启动一个 -启用了 OpenAI 兼容 HTTP 端点的 OpenClaw Gateway 网关容器, -再启动一个固定版本的 Open WebUI 容器连接到该 Gateway 网关,通过 -Open WebUI 登录,验证 `/api/models` 暴露 `openclaw/default`,然后通过 Open WebUI 的 `/api/chat/completions` 代理发送一次 +`test:docker:openwebui` 是更高层的兼容性冒烟测试:它会启动一个启用了 +OpenAI 兼容 HTTP 端点的 OpenClaw Gateway 网关容器, +再启动一个 pinned Open WebUI 容器连接该 Gateway 网关, +通过 Open WebUI 登录,验证 `/api/models` 暴露 `openclaw/default`, +然后通过 Open WebUI 的 `/api/chat/completions` 代理发送一个 真实聊天请求。 -首次运行可能明显较慢,因为 Docker 可能需要拉取 -Open WebUI 镜像,且 Open WebUI 可能需要完成自己的冷启动设置。 -该任务线需要可用的真实模型密钥,而 `OPENCLAW_PROFILE_FILE` +首次运行可能明显更慢,因为 Docker 可能需要拉取 +Open WebUI 镜像,Open WebUI 也可能需要完成自己的冷启动设置。 +该通道需要可用的实时模型密钥,而 `OPENCLAW_PROFILE_FILE` (默认是 `~/.profile`)是在 Docker 化运行中提供它的主要方式。 -成功运行会打印一个小型 JSON 载荷,例如 `{ "ok": true, "model": +成功运行会打印一个小型 JSON 负载,例如 `{ "ok": true, "model": "openclaw/default", ... }`。 -`test:docker:mcp-channels` 有意保持确定性,不需要 -真实的 Telegram、Discord 或 iMessage 账号。它会启动一个已播种的 Gateway 网关 -容器,再启动第二个容器来生成 `openclaw mcp serve`,然后 +`test:docker:mcp-channels` 有意保持确定性,不需要真实的 +Telegram、Discord 或 iMessage 账号。它会启动一个已填充的 Gateway 网关 +容器,启动第二个容器并生成 `openclaw mcp serve`,然后 验证路由会话发现、转录读取、附件元数据、 -live 事件队列行为、出站发送路由,以及通过真实 stdio MCP 桥接发送的 Claude 风格渠道 + -权限通知。通知检查会直接检查原始 stdio MCP 帧,因此该冒烟测试验证的是 -桥接实际发出的内容,而不只是某个特定客户端 SDK 刚好暴露的内容。 -`test:docker:pi-bundle-mcp-tools` 是确定性的,不需要 live +实时事件队列行为、出站发送路由,以及通过真实 stdio MCP 桥接发出的 Claude 风格渠道 + +权限通知。通知检查会直接检查原始 stdio MCP 帧, +因此该冒烟测试验证的是桥接实际发出的内容,而不只是某个特定客户端 SDK 恰好暴露的内容。 +`test:docker:pi-bundle-mcp-tools` 是确定性的,不需要实时 模型密钥。它会构建仓库 Docker 镜像,在容器内启动一个真实 stdio MCP 探测服务器, -通过嵌入式 Pi bundle -MCP 运行时物化该服务器,执行该工具,然后验证 `coding` 和 `messaging` 保留 +通过嵌入式 Pi bundle MCP 运行时物化该服务器, +执行工具,然后验证 `coding` 和 `messaging` 保留 `bundle-mcp` 工具,而 `minimal` 和 `tools.deny: ["bundle-mcp"]` 会过滤它们。 -`test:docker:cron-mcp-cleanup` 是确定性的,不需要 live 模型 -密钥。它会启动一个带真实 stdio MCP 探测服务器的已播种 Gateway 网关,运行一个 +`test:docker:cron-mcp-cleanup` 是确定性的,不需要实时模型 +密钥。它会启动一个已填充的 Gateway 网关和真实 stdio MCP 探测服务器,运行一个 隔离 cron 轮次和一个 `/subagents spawn` 一次性子轮次,然后验证 -MCP 子进程在每次运行后都会退出。 +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`,并在运行测试前 source -- `OPENCLAW_DOCKER_PROFILE_ENV_ONLY=1` 用于仅验证从 `OPENCLAW_PROFILE_FILE` source 的环境变量,使用临时配置/工作区目录,且不挂载外部 CLI 凭证 -- `OPENCLAW_DOCKER_CLI_TOOLS_DIR=...`(默认:`~/.cache/openclaw/docker-cli-tools`)挂载到 `/home/node/.npm-global`,用于 Docker 内缓存 CLI 安装 +- `OPENCLAW_CONFIG_DIR=...`(默认值:`~/.openclaw`)挂载到 `/home/node/.openclaw` +- `OPENCLAW_WORKSPACE_DIR=...`(默认值:`~/.openclaw/workspace`)挂载到 `/home/node/.openclaw/workspace` +- `OPENCLAW_PROFILE_FILE=...`(默认值:`~/.profile`)挂载到 `/home/node/.profile`,并在运行测试前 source +- `OPENCLAW_DOCKER_PROFILE_ENV_ONLY=1` 仅验证从 `OPENCLAW_PROFILE_FILE` source 的环境变量,使用临时配置/工作区目录,且不挂载外部 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_DOCKER_AUTH_DIRS=all`、`OPENCLAW_DOCKER_AUTH_DIRS=none` 或类似 `OPENCLAW_DOCKER_AUTH_DIRS=.claude,.codex` 的逗号列表手动覆盖 -- `OPENCLAW_LIVE_GATEWAY_MODELS=...` / `OPENCLAW_LIVE_MODELS=...` 用于缩小运行范围 -- `OPENCLAW_LIVE_GATEWAY_PROVIDERS=...` / `OPENCLAW_LIVE_PROVIDERS=...` 用于在容器内过滤提供商 -- `OPENCLAW_SKIP_DOCKER_BUILD=1` 用于在不需要重新构建的重跑中复用现有的 `openclaw:local-live` 镜像 -- `OPENCLAW_LIVE_REQUIRE_PROFILE_KEYS=1` 用于确保凭证来自 profile 存储(而不是环境变量) -- `OPENCLAW_OPENWEBUI_MODEL=...` 用于选择 Gateway 网关向 Open WebUI smoke 暴露的模型 -- `OPENCLAW_OPENWEBUI_PROMPT=...` 用于覆盖 Open WebUI smoke 使用的 nonce 检查提示 + - 收窄的提供商运行只会挂载从 `OPENCLAW_LIVE_PROVIDERS` / `OPENCLAW_LIVE_GATEWAY_PROVIDERS` 推断出的所需目录/文件 + - 可用 `OPENCLAW_DOCKER_AUTH_DIRS=all`、`OPENCLAW_DOCKER_AUTH_DIRS=none` 或类似 `OPENCLAW_DOCKER_AUTH_DIRS=.claude,.codex` 的逗号列表手动覆盖 +- `OPENCLAW_LIVE_GATEWAY_MODELS=...` / `OPENCLAW_LIVE_MODELS=...` 用于收窄运行范围 +- `OPENCLAW_LIVE_GATEWAY_PROVIDERS=...` / `OPENCLAW_LIVE_PROVIDERS=...` 用于在容器内筛选提供商 +- `OPENCLAW_SKIP_DOCKER_BUILD=1` 用于在不需要重新构建的重复运行中复用现有 `openclaw:local-live` 镜像 +- `OPENCLAW_LIVE_REQUIRE_PROFILE_KEYS=1` 用于确保凭证来自配置文件存储(而不是环境变量) +- `OPENCLAW_OPENWEBUI_MODEL=...` 用于选择 Gateway 网关向 Open WebUI 冒烟测试暴露的模型 +- `OPENCLAW_OPENWEBUI_PROMPT=...` 用于覆盖 Open WebUI 冒烟测试使用的 nonce 检查提示词 - `OPENWEBUI_IMAGE=...` 用于覆盖固定的 Open WebUI 镜像标签 ## 文档完整性检查 文档编辑后运行文档检查:`pnpm check:docs`。 -如果还需要页内标题检查,请运行完整的 Mintlify 锚点验证:`pnpm docs:check-links:anchors`。 +如果还需要检查页内标题,请运行完整的 Mintlify 锚点验证:`pnpm docs:check-links:anchors`。 ## 离线回归(CI 安全) 这些是不使用真实提供商的“真实流水线”回归: -- Gateway 网关工具调用(模拟 OpenAI,真实 Gateway 网关 + Agent loop):`src/gateway/gateway.test.ts`(用例:“通过 Gateway 网关 Agent loop 端到端运行模拟 OpenAI 工具调用”) -- Gateway 网关向导(WS `wizard.start`/`wizard.next`,写入配置 + 强制凭证):`src/gateway/gateway.test.ts`(用例:“通过 ws 运行向导并写入凭证令牌配置”) +- Gateway 网关工具调用(模拟 OpenAI,真实 Gateway 网关 + 智能体循环):`src/gateway/gateway.test.ts`(用例:"runs a mock OpenAI tool call end-to-end via gateway agent loop") +- Gateway 网关向导(WS `wizard.start`/`wizard.next`,写入配置 + 强制执行凭证):`src/gateway/gateway.test.ts`(用例:"runs wizard over ws and writes auth token config") -## 智能体可靠性评测(Skills) +## 智能体可靠性评估(Skills) -我们已经有一些 CI 安全测试,其行为类似“智能体可靠性评测”: +我们已经有一些 CI 安全测试,其行为类似“智能体可靠性评估”: -- 通过真实 Gateway 网关 + Agent loop 进行模拟工具调用(`src/gateway/gateway.test.ts`)。 -- 验证会话接线和配置效果的端到端向导流程(`src/gateway/gateway.test.ts`)。 +- 通过真实 Gateway 网关 + 智能体循环进行模拟工具调用(`src/gateway/gateway.test.ts`)。 +- 端到端向导流程,用于验证会话接线和配置效果(`src/gateway/gateway.test.ts`)。 Skills 仍然缺少的内容(见 [Skills](/zh-CN/tools/skills)): -- **决策:** 当提示中列出 Skills 时,智能体是否会选择正确的 Skills(或避开无关项)? -- **合规:** 智能体是否会在使用前读取 `SKILL.md` 并遵循必需步骤/参数? -- **工作流契约:** 断言工具顺序、会话历史继承和沙箱边界的多轮场景。 +- **决策:** 当提示词中列出 Skills 时,智能体是否会选择正确的 skill(或避开不相关的 skill)? +- **合规:** 智能体在使用前是否读取 `SKILL.md`,并遵循必需的步骤/参数? +- **工作流契约:** 断言工具顺序、会话历史延续和沙箱边界的多轮场景。 -未来评测应首先保持确定性: +未来评估应首先保持确定性: -- 使用模拟提供商的场景运行器,用于断言工具调用 + 顺序、Skills 文件读取和会话接线。 -- 一小套聚焦 Skills 的场景(使用 vs 避免、门控、提示注入)。 -- 只有在 CI 安全套件就位后,才添加可选的实时评测(选择启用、由环境变量门控)。 +- 使用模拟提供商的场景运行器,用于断言工具调用 + 顺序、skill 文件读取和会话接线。 +- 一小套以 skill 为中心的场景(使用 vs 避免、门控、提示词注入)。 +- 可选实时评估(可选启用,通过环境变量门控)仅在 CI 安全套件到位后再添加。 ## 契约测试(插件和渠道形状) -契约测试验证每个已注册的插件和渠道都符合其 -接口契约。它们会遍历所有发现的插件,并运行一套 -形状和行为断言。默认的 `pnpm test` 单元测试 lane 会有意 -跳过这些共享接缝和 smoke 文件;当你触及共享渠道或提供商表面时, -请显式运行契约命令。 +契约测试验证每个已注册插件和渠道是否符合其接口契约。它们会遍历所有已发现的插件,并运行一套形状和行为断言。默认的 `pnpm test` 单元测试通道会有意跳过这些共享接口和冒烟文件;当你触碰共享渠道或提供商表面时,请显式运行契约命令。 ### 命令 @@ -710,9 +718,9 @@ Skills 仍然缺少的内容(见 [Skills](/zh-CN/tools/skills)): - **session-binding** - 会话绑定行为 - **outbound-payload** - 消息载荷结构 - **inbound** - 入站消息处理 -- **actions** - 渠道动作处理器 +- **actions** - 渠道操作处理器 - **threading** - 线程 ID 处理 -- **directory** - 目录/名册 API +- **directory** - 目录/花名册 API - **group-policy** - 群组策略强制执行 ### 提供商 Status 契约 @@ -737,24 +745,24 @@ Skills 仍然缺少的内容(见 [Skills](/zh-CN/tools/skills)): ### 何时运行 -- 更改插件 SDK 导出或子路径后 +- 更改 plugin-sdk 导出或子路径后 - 添加或修改渠道或提供商插件后 - 重构插件注册或发现后 -契约测试在 CI 中运行,不需要真实 API key。 +契约测试会在 CI 中运行,并且不需要真实 API 密钥。 ## 添加回归(指南) -当你修复实时环境中发现的提供商/模型问题时: +当你修复实时运行中发现的提供商/模型问题时: -- 如果可能,添加一个 CI 安全回归(模拟/存根提供商,或捕获精确的请求形状转换) -- 如果它本质上只能实时运行(速率限制、凭证策略),请让实时测试保持窄范围,并通过环境变量选择启用 -- 优先针对能捕获该 bug 的最小层: - - 提供商请求转换/回放 bug → 直接模型测试 - - Gateway 网关会话/历史/工具流水线 bug → Gateway 网关实时 smoke 或 CI 安全的 Gateway 网关模拟测试 -- SecretRef 遍历防护栏: - - `src/secrets/exec-secret-ref-id-parity.test.ts` 会从注册表元数据(`listSecretTargetRegistryEntries()`)为每个 SecretRef 类派生一个采样目标,然后断言遍历段 exec id 会被拒绝。 - - 如果你在 `src/secrets/target-registry-data.ts` 中添加新的 `includeInPlan` SecretRef 目标族,请更新该测试中的 `classifyTargetClass`。该测试会故意在未分类的目标 id 上失败,确保新类不能被静默跳过。 +- 尽可能添加 CI 安全回归(模拟/stub 提供商,或捕获确切的请求形状转换) +- 如果它本质上只能实时验证(速率限制、凭证策略),请保持实时测试范围狭窄,并通过环境变量可选启用 +- 优先针对能捕获该 bug 的最小层级: + - 提供商请求转换/重放 bug → 直接模型测试 + - Gateway 网关会话/历史/工具流水线 bug → 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 上失败,以便新类别不能被静默跳过。 ## 相关 diff --git a/docs/zh-CN/plugins/building-plugins.md b/docs/zh-CN/plugins/building-plugins.md index 806ee0535..4591309d6 100644 --- a/docs/zh-CN/plugins/building-plugins.md +++ b/docs/zh-CN/plugins/building-plugins.md @@ -2,24 +2,24 @@ read_when: - 你想创建一个新的 OpenClaw 插件 - 你需要一份插件开发快速开始指南 - - 你正在为 OpenClaw 添加新的渠道、提供商、工具或其他能力 + - 你正在向 OpenClaw 添加新的渠道、提供商、工具或其他能力 sidebarTitle: Getting Started summary: 几分钟内创建你的第一个 OpenClaw 插件 title: 构建插件 x-i18n: - generated_at: "2026-04-28T11:58:02Z" + generated_at: "2026-04-29T05:40:27Z" model: gpt-5.5 provider: openai - source_hash: 69411f22977b521adebcdaf1f6ac7592055aa800dd22f284bef4adef08027438 + source_hash: 321f8870d0ce3be8dece21b07815eda6859dcb00941d9181d913b95f3d74d230 source_path: plugins/building-plugins.md workflow: 16 --- -插件通过新增能力扩展 OpenClaw:渠道、模型提供商、语音、实时转写、实时语音、媒体理解、图像生成、视频生成、网页获取、Web 搜索、智能体工具,或任意组合。 +插件通过新能力扩展 OpenClaw:渠道、模型提供商、语音、实时转写、实时语音、媒体理解、图像生成、视频生成、网页获取、Web 搜索、智能体工具,或任意组合。 你不需要把你的插件添加到 OpenClaw 仓库。发布到 -[ClawHub](/zh-CN/tools/clawhub) 或 npm,用户再使用 -`openclaw plugins install ` 安装。OpenClaw 会先尝试 ClawHub,并在需要时自动回退到 npm。 +[ClawHub](/zh-CN/tools/clawhub),用户通过 +`openclaw plugins install ` 安装。OpenClaw 会先尝试 ClawHub,并对仍使用 npm 分发的软件包自动回退到 npm。 ## 前置条件 @@ -41,16 +41,16 @@ x-i18n: -对于在新手引导/设置运行时不保证已安装的渠道插件,请使用 +对于不能保证在新手引导/设置运行时已安装的渠道插件,请使用 `openclaw/plugin-sdk/channel-setup` 中的 `createOptionalChannelSetupSurface(...)`。 -它会生成一对设置适配器 + 向导,用于说明安装要求,并在插件安装之前对真实配置写入执行失败关闭。 +它会生成一个设置适配器 + 向导组合,用于提示安装要求,并在插件安装之前对真实配置写入采取失败关闭策略。 ## 快速开始:工具插件 -本演练会创建一个注册智能体工具的最小插件。渠道和提供商插件有上方链接的专门指南。 +本演练会创建一个注册智能体工具的最小插件。渠道插件和提供商插件有上方链接中的专门指南。 - + ```json package.json { @@ -87,9 +87,11 @@ x-i18n: ``` - 每个插件都需要清单,即使没有配置也是如此,并且每个插件都应有意声明 - `activation.onStartup`。运行时注册的工具需要启动时导入,因此此示例将其设为 `true`。完整架构见 - [清单](/zh-CN/plugins/manifest)。规范的 ClawHub 发布片段位于 `docs/snippets/plugin-publish/`。 + 每个插件都需要清单,即使没有配置;每个插件也都应有意声明 + `activation.onStartup`。运行时注册的工具需要启动时导入,所以此示例将其设为 + `true`。完整 schema 请参阅 + [清单](/zh-CN/plugins/manifest)。规范的 ClawHub 发布片段位于 + `docs/snippets/plugin-publish/`。 @@ -118,8 +120,8 @@ x-i18n: ``` `definePluginEntry` 用于非渠道插件。对于渠道,请使用 - `defineChannelPluginEntry` — 见 [渠道插件](/zh-CN/plugins/sdk-channel-plugins)。 - 如需完整入口点选项,见 [入口点](/zh-CN/plugins/sdk-entrypoints)。 + `defineChannelPluginEntry` — 参阅 [渠道插件](/zh-CN/plugins/sdk-channel-plugins)。 + 如需完整入口点选项,请参阅 [入口点](/zh-CN/plugins/sdk-entrypoints)。 @@ -133,7 +135,7 @@ x-i18n: openclaw plugins install clawhub:@myorg/openclaw-my-plugin ``` - 对于像 `@myorg/openclaw-my-plugin` 这样的裸包规格,OpenClaw 也会先检查 ClawHub,再检查 npm。 + 对于像 `@myorg/openclaw-my-plugin` 这样的裸包规格,OpenClaw 也会先检查 ClawHub,再检查 npm;对于尚未迁移到 ClawHub 的软件包,npm 仍是回退选项。 **仓库内插件:**放在内置插件工作区树下 — 会被自动发现。 @@ -152,7 +154,7 @@ x-i18n: | ---------------------- | ------------------------------------------------ | ------------------------------------------------------------------------------- | | 文本推理(LLM) | `api.registerProvider(...)` | [提供商插件](/zh-CN/plugins/sdk-provider-plugins) | | CLI 推理后端 | `api.registerCliBackend(...)` | [CLI 后端](/zh-CN/gateway/cli-backends) | -| 渠道 / 消息传递 | `api.registerChannel(...)` | [渠道插件](/zh-CN/plugins/sdk-channel-plugins) | +| 渠道 / 消息 | `api.registerChannel(...)` | [渠道插件](/zh-CN/plugins/sdk-channel-plugins) | | 语音(TTS/STT) | `api.registerSpeechProvider(...)` | [提供商插件](/zh-CN/plugins/sdk-provider-plugins#step-5-add-extra-capabilities) | | 实时转写 | `api.registerRealtimeTranscriptionProvider(...)` | [提供商插件](/zh-CN/plugins/sdk-provider-plugins#step-5-add-extra-capabilities) | | 实时语音 | `api.registerRealtimeVoiceProvider(...)` | [提供商插件](/zh-CN/plugins/sdk-provider-plugins#step-5-add-extra-capabilities) | @@ -170,37 +172,40 @@ x-i18n: | HTTP 路由 | `api.registerHttpRoute(...)` | [内部机制](/zh-CN/plugins/architecture-internals#gateway-http-routes) | | CLI 子命令 | `api.registerCli(...)` | [入口点](/zh-CN/plugins/sdk-entrypoints) | -完整注册 API 见 [SDK 概览](/zh-CN/plugins/sdk-overview#registration-api)。 +如需完整注册 API,请参阅 [SDK 概览](/zh-CN/plugins/sdk-overview#registration-api)。 -内置插件在需要在模型看到输出之前异步重写工具结果时,可以使用 `api.registerAgentToolResultMiddleware(...)`。 -请在 `contracts.agentToolResultMiddleware` 中声明目标运行时,例如 -`["pi", "codex"]`。这是一个受信任的内置插件接缝;外部插件应优先使用常规 OpenClaw 插件钩子,除非 OpenClaw 为此能力新增明确的信任策略。 +当内置插件需要在模型看到输出之前异步重写工具结果时,可以使用 +`api.registerAgentToolResultMiddleware(...)`。请在 +`contracts.agentToolResultMiddleware` 中声明目标运行时,例如 +`["pi", "codex"]`。这是一个可信的内置插件接口;除非 OpenClaw 为此能力扩展出明确的信任策略,否则外部插件应优先使用常规 OpenClaw 插件钩子。 -如果你的插件注册自定义 Gateway 网关 RPC 方法,请将它们放在插件专用前缀下。核心管理命名空间(`config.*`、 -`exec.approvals.*`、`wizard.*`、`update.*`)会保留,并且始终解析为 -`operator.admin`,即使插件请求的是更窄的作用域。 +如果你的插件注册自定义 Gateway 网关 RPC 方法,请把它们保留在 +插件专属前缀下。核心管理命名空间(`config.*`、 +`exec.approvals.*`、`wizard.*`、`update.*`)保持保留,并且始终解析到 +`operator.admin`,即使插件请求更窄的作用域也是如此。 需要记住的钩子保护语义: -- `before_tool_call`:`{ block: true }` 是终止性决定,会停止较低优先级的处理器。 -- `before_tool_call`:`{ block: false }` 会被视为没有决定。 -- `before_tool_call`:`{ requireApproval: true }` 会暂停智能体执行,并通过执行审批覆盖层、Telegram 按钮、Discord 交互,或任意渠道上的 `/approve` 命令提示用户审批。 -- `before_install`:`{ block: true }` 是终止性决定,会停止较低优先级的处理器。 -- `before_install`:`{ block: false }` 会被视为没有决定。 -- `message_sending`:`{ cancel: true }` 是终止性决定,会停止较低优先级的处理器。 -- `message_sending`:`{ cancel: false }` 会被视为没有决定。 -- `message_received`:当你需要入站线程/主题路由时,优先使用带类型的 `threadId` 字段。保留 `metadata` 用于渠道特定的附加信息。 -- `message_sending`:优先使用带类型的 `replyToId` / `threadId` 路由字段,而不是渠道特定的元数据键。 +- `before_tool_call`:`{ block: true }` 是终止决策,会停止优先级更低的处理程序。 +- `before_tool_call`:`{ block: false }` 会被视为未作出决策。 +- `before_tool_call`:`{ requireApproval: true }` 会暂停智能体执行,并通过 exec 审批覆盖层、Telegram 按钮、Discord 交互,或任意渠道上的 `/approve` 命令提示用户审批。 +- `before_install`:`{ block: true }` 是终止决策,会停止优先级更低的处理程序。 +- `before_install`:`{ block: false }` 会被视为未作出决策。 +- `message_sending`:`{ cancel: true }` 是终止决策,会停止优先级更低的处理程序。 +- `message_sending`:`{ cancel: false }` 会被视为未作出决策。 +- `message_received`:当你需要入站 thread/topic 路由时,优先使用带类型的 `threadId` 字段。将 `metadata` 保留给渠道专属附加项。 +- `message_sending`:优先使用带类型的 `replyToId` / `threadId` 路由字段,而不是渠道专属 metadata 键。 -`/approve` 命令通过有界回退同时处理执行审批和插件审批:当找不到执行审批 id 时,OpenClaw 会通过插件审批使用相同 id 重试。插件审批转发可以通过配置中的 `approvals.plugin` 独立配置。 +`/approve` 命令会通过有界回退同时处理 exec 和插件审批:当找不到 exec 审批 id 时,OpenClaw 会用同一个 id 通过插件审批重试。插件审批转发可以通过配置中的 `approvals.plugin` 独立配置。 -如果自定义审批管道需要检测同一个有界回退场景,请优先使用 `openclaw/plugin-sdk/error-runtime` 中的 `isApprovalNotFoundError`,而不是手动匹配审批过期字符串。 +如果自定义审批管道需要检测同一个有界回退情况,请优先使用 +`openclaw/plugin-sdk/error-runtime` 中的 `isApprovalNotFoundError`,而不是手动匹配审批过期字符串。 -示例和钩子参考见 [插件钩子](/zh-CN/plugins/hooks)。 +示例和钩子参考请参阅 [插件钩子](/zh-CN/plugins/hooks)。 ## 注册智能体工具 -工具是 LLM 可以调用的带类型函数。它们可以是必需的(始终可用),也可以是可选的(用户选择加入): +工具是 LLM 可以调用的带类型函数。它们可以是必需的(始终可用),也可以是可选的(用户选择启用): ```typescript register(api) { @@ -238,7 +243,7 @@ register(api) { ``` - 工具名称不得与核心工具冲突(冲突项会被跳过) -- 包含缺失 `parameters` 在内,带有格式错误注册对象的工具会被跳过并报告到插件诊断中,而不是破坏智能体运行 +- 注册对象格式错误的工具,包括缺少 `parameters` 的工具,会被跳过并在插件诊断中报告,而不是破坏智能体运行 - 对于有副作用或额外二进制要求的工具,请使用 `optional: true` - 用户可以通过将插件 id 添加到 `tools.allow` 来启用某个插件的所有工具 @@ -254,19 +259,24 @@ import { createPluginRuntimeStore } from "openclaw/plugin-sdk/runtime-store"; import { ... } from "openclaw/plugin-sdk"; ``` -完整子路径参考见 [SDK 概览](/zh-CN/plugins/sdk-overview)。 +完整子路径参考请参见 [SDK 概览](/zh-CN/plugins/sdk-overview)。 -在你的插件中,将本地 barrel 文件(`api.ts`、`runtime-api.ts`)用于内部导入,不要通过其 SDK 路径导入你自己的插件。 +在你的插件内,使用本地 barrel 文件(`api.ts`、`runtime-api.ts`)进行 +内部导入,不要通过其 SDK 路径导入你自己的插件。 -对于提供商插件,除非接口确实是通用的,否则应将提供商特定的辅助工具保留在这些包根级 barrel 中。当前内置示例: +对于提供商插件,除非接缝确实是通用的,否则将提供商特定的辅助工具保留在这些包根 +barrel 中。当前内置示例: -- Anthropic:Claude 流包装器,以及 `service_tier` / beta 辅助工具 +- Anthropic:Claude 流包装器以及 `service_tier` / beta 辅助工具 - OpenAI:提供商构建器、默认模型辅助工具、实时提供商 -- OpenRouter:提供商构建器,以及新手引导/配置辅助工具 +- OpenRouter:提供商构建器以及新手引导/配置辅助工具 -如果某个辅助工具只在一个内置提供商包内部有用,请将它保留在该包根级接口上,而不是提升到 `openclaw/plugin-sdk/*`。 +如果某个辅助工具只在一个内置提供商包内有用,请将其保留在该 +包根接缝上,而不是提升到 `openclaw/plugin-sdk/*` 中。 -一些生成的 `openclaw/plugin-sdk/` 辅助接口仍然存在,用于在具有已跟踪所有者用法时维护内置插件。请将这些视为保留接口,而不是新第三方插件的默认模式。 +一些生成的 `openclaw/plugin-sdk/` 辅助接缝仍然存在,用于 +内置插件维护,前提是它们有已跟踪的所有者用法。请将这些视为 +保留表面,而不是新第三方插件的默认模式。 ## 提交前检查清单 @@ -278,14 +288,14 @@ import { ... } from "openclaw/plugin-sdk"; 测试通过(`pnpm test -- /my-plugin/`) `pnpm check` 通过(仓库内插件) -## Beta 发布测试 +## Beta 版本测试 -1. 关注 [openclaw/openclaw](https://github.com/openclaw/openclaw/releases) 上的 GitHub 发布标签,并通过 `Watch` > `Releases` 订阅。Beta 标签看起来像 `v2026.3.N-beta.1`。你也可以为官方 OpenClaw X 账号 [@openclaw](https://x.com/openclaw) 开启通知,以接收发布公告。 -2. Beta 标签一出现,就立即用它测试你的插件。稳定版发布前的窗口通常只有几个小时。 -3. 测试后,在 `plugin-forum` Discord 渠道中你的插件主题帖里发布 `all good` 或说明哪里损坏了。如果你还没有主题帖,请创建一个。 -4. 如果有内容损坏,请打开或更新一个标题为 `Beta blocker: - ` 的 issue,并应用 `beta-blocker` 标签。将 issue 链接放到你的主题帖中。 -5. 向 `main` 打开一个标题为 `fix(): beta blocker - ` 的 PR,并在 PR 和你的 Discord 主题帖中都链接该 issue。贡献者无法给 PR 加标签,因此标题是给维护者和自动化使用的 PR 侧信号。有 PR 的阻塞问题会被合并;没有 PR 的阻塞问题可能仍会随版本发布。维护者会在 beta 测试期间关注这些主题帖。 -6. 沉默表示通过。如果你错过窗口,你的修复很可能会在下一个周期合入。 +1. 关注 [openclaw/openclaw](https://github.com/openclaw/openclaw/releases) 上的 GitHub 发布标签,并通过 `Watch` > `Releases` 订阅。Beta 标签类似于 `v2026.3.N-beta.1`。你也可以为官方 OpenClaw X 账号 [@openclaw](https://x.com/openclaw) 开启通知,以接收发布公告。 +2. Beta 标签一出现,就用它测试你的插件。稳定版发布前的窗口通常只有几个小时。 +3. 测试后,在 `plugin-forum` Discord 渠道中你的插件讨论串里发布 `all good` 或说明哪里出问题。如果你还没有讨论串,请创建一个。 +4. 如果出现问题,请打开或更新一个标题为 `Beta blocker: - ` 的 issue,并应用 `beta-blocker` 标签。将 issue 链接放入你的讨论串。 +5. 打开一个指向 `main` 的 PR,标题为 `fix(): beta blocker - `,并在 PR 和你的 Discord 讨论串中都链接该 issue。贡献者无法给 PR 加标签,因此标题是给维护者和自动化使用的 PR 侧信号。有 PR 的阻塞问题会被合并;没有 PR 的阻塞问题可能仍会随版本发布。维护者会在 Beta 测试期间关注这些讨论串。 +6. 沉默意味着绿色。如果你错过窗口,你的修复很可能会进入下一个周期。 ## 后续步骤 @@ -310,9 +320,9 @@ import { ... } from "openclaw/plugin-sdk"; -## 相关 +## 相关内容 -- [插件架构](/zh-CN/plugins/architecture) — 内部架构深度解析 +- [插件架构](/zh-CN/plugins/architecture) — 内部架构深入解析 - [SDK 概览](/zh-CN/plugins/sdk-overview) — 插件 SDK 参考 - [清单](/zh-CN/plugins/manifest) — 插件清单格式 - [渠道插件](/zh-CN/plugins/sdk-channel-plugins) — 构建渠道插件 diff --git a/docs/zh-CN/plugins/community.md b/docs/zh-CN/plugins/community.md index 7d521949b..308b92303 100644 --- a/docs/zh-CN/plugins/community.md +++ b/docs/zh-CN/plugins/community.md @@ -1,21 +1,21 @@ --- read_when: - 你想查找第三方 OpenClaw 插件 - - 你想发布或列出你自己的插件 + - 你想发布或列出自己的插件 summary: 社区维护的 OpenClaw 插件:浏览、安装并提交你自己的插件 title: 社区插件 x-i18n: - generated_at: "2026-04-27T15:08:03Z" - model: gpt-5.4 + generated_at: "2026-04-29T05:40:34Z" + model: gpt-5.5 provider: openai - source_hash: 3b9c92e8f2e592bbbdbaa8d3f354d176f1600354f6438f137dbe01c01c6f5603 + source_hash: a54130fefc55042d53270e5f7f4b49a4aad715570743013fbfe06b0e2fa067d0 source_path: plugins/community.md - workflow: 15 + workflow: 16 --- -社区插件是第三方软件包,可通过新的渠道、工具、提供商或其他能力扩展 OpenClaw。它们由社区构建和维护,发布在 [ClawHub](/zh-CN/tools/clawhub) 或 npm 上,并且只需一条命令即可安装。 +社区插件是第三方软件包,可为 OpenClaw 扩展新的渠道、工具、提供商或其他能力。它们由社区构建和维护,通常发布在 [ClawHub](/zh-CN/tools/clawhub),并且可通过一条命令安装。对于尚未迁移到 ClawHub 的软件包,npm 仍是受支持的备用方案。 -ClawHub 是社区插件的权威发现入口。不要仅仅为了让你的插件更容易被发现而提交只改文档的 PR;请改为将它发布到 ClawHub。 +ClawHub 是社区插件的规范发现入口。不要仅为了让你的插件可被发现而提交只改文档的 PR;请改为将其发布到 ClawHub。 ```bash openclaw plugins install @@ -27,10 +27,10 @@ OpenClaw 会先检查 ClawHub,并在需要时自动回退到 npm。 ### Apify -使用 20,000 多个现成爬虫从任何网站抓取数据。让你的智能体仅通过提问,就能从 Instagram、Facebook、TikTok、YouTube、Google Maps、Google Search、电商网站等提取数据。 +使用 20,000 多个现成爬虫从任何网站抓取数据。让你的智能体只需提问,就能从 Instagram、Facebook、TikTok、YouTube、Google Maps、Google Search、电子商务网站等提取数据。 -- **npm:** `@apify/apify-openclaw-plugin` -- **仓库:** [github.com/apify/apify-openclaw-plugin](https://github.com/apify/apify-openclaw-plugin) +- **npm:** `@apify/apify-openclaw-plugin` +- **repo:** [github.com/apify/apify-openclaw-plugin](https://github.com/apify/apify-openclaw-plugin) ```bash openclaw plugins install @apify/apify-openclaw-plugin @@ -38,10 +38,10 @@ openclaw plugins install @apify/apify-openclaw-plugin ### Codex App Server Bridge -面向 Codex App Server 对话的独立 OpenClaw 桥接插件。你可以将聊天绑定到一个 Codex 线程,通过纯文本与其交互,并使用聊天原生命令控制恢复、规划、审查、模型选择、压缩等功能。 +用于 Codex App Server 对话的独立 OpenClaw 桥接。将聊天绑定到 Codex 线程,用纯文本与其对话,并通过聊天原生命令控制恢复、规划、审查、模型选择、压缩等功能。 -- **npm:** `openclaw-codex-app-server` -- **仓库:** [github.com/pwrdrvr/openclaw-codex-app-server](https://github.com/pwrdrvr/openclaw-codex-app-server) +- **npm:** `openclaw-codex-app-server` +- **repo:** [github.com/pwrdrvr/openclaw-codex-app-server](https://github.com/pwrdrvr/openclaw-codex-app-server) ```bash openclaw plugins install openclaw-codex-app-server @@ -49,10 +49,10 @@ openclaw plugins install openclaw-codex-app-server ### DingTalk -使用 Stream 模式的企业机器人集成。支持通过任意 DingTalk 客户端发送文本、图片和文件消息。 +使用 Stream 模式的企业机器人集成。通过任意 DingTalk 客户端支持文本、图片和文件消息。 -- **npm:** `@largezhou/ddingtalk` -- **仓库:** [github.com/largezhou/openclaw-dingtalk](https://github.com/largezhou/openclaw-dingtalk) +- **npm:** `@largezhou/ddingtalk` +- **repo:** [github.com/largezhou/openclaw-dingtalk](https://github.com/largezhou/openclaw-dingtalk) ```bash openclaw plugins install @largezhou/ddingtalk @@ -60,10 +60,10 @@ openclaw plugins install @largezhou/ddingtalk ### Lossless Claw (LCM) -适用于 OpenClaw 的无损上下文管理插件。基于 DAG 的对话摘要与增量压缩,在减少 token 使用量的同时保留完整上下文保真度。 +用于 OpenClaw 的无损上下文管理插件。基于 DAG 的对话摘要,支持增量压缩,在减少令牌使用量的同时保留完整上下文保真度。 -- **npm:** `@martian-engineering/lossless-claw` -- **仓库:** [github.com/Martian-Engineering/lossless-claw](https://github.com/Martian-Engineering/lossless-claw) +- **npm:** `@martian-engineering/lossless-claw` +- **repo:** [github.com/Martian-Engineering/lossless-claw](https://github.com/Martian-Engineering/lossless-claw) ```bash openclaw plugins install @martian-engineering/lossless-claw @@ -71,10 +71,10 @@ openclaw plugins install @martian-engineering/lossless-claw ### Opik -将智能体追踪导出到 Opik 的官方插件。可监控智能体行为、成本、token、错误等。 +将智能体轨迹导出到 Opik 的官方插件。监控智能体行为、成本、令牌、错误等。 -- **npm:** `@opik/opik-openclaw` -- **仓库:** [github.com/comet-ml/opik-openclaw](https://github.com/comet-ml/opik-openclaw) +- **npm:** `@opik/opik-openclaw` +- **repo:** [github.com/comet-ml/opik-openclaw](https://github.com/comet-ml/opik-openclaw) ```bash openclaw plugins install @opik/opik-openclaw @@ -82,10 +82,10 @@ openclaw plugins install @opik/opik-openclaw ### Prometheus Avatar -为你的 OpenClaw 智能体赋予一个带有实时唇形同步、情绪表情和文本转语音能力的 Live2D 虚拟形象。包含用于 AI 资产生成的创作者工具,以及一键部署到 Prometheus Marketplace 的功能。目前处于 alpha 阶段。 +为你的 OpenClaw 智能体提供 Live2D 头像,支持实时唇形同步、情绪表情和文本转语音。包含用于 AI 资产生成和一键部署到 Prometheus Marketplace 的创作者工具。目前处于 alpha 阶段。 -- **npm:** `@prometheusavatar/openclaw-plugin` -- **仓库:** [github.com/myths-labs/prometheus-avatar](https://github.com/myths-labs/prometheus-avatar) +- **npm:** `@prometheusavatar/openclaw-plugin` +- **repo:** [github.com/myths-labs/prometheus-avatar](https://github.com/myths-labs/prometheus-avatar) ```bash openclaw plugins install @prometheusavatar/openclaw-plugin @@ -93,12 +93,12 @@ openclaw plugins install @prometheusavatar/openclaw-plugin ### QQbot -通过 QQ Bot API 将 OpenClaw 连接到 QQ。支持私聊、群组提及、频道消息,以及语音、图片、视频和文件等富媒体内容。 +通过 QQ Bot API 将 OpenClaw 连接到 QQ。支持私聊、群组提及、频道消息,以及包括语音、图片、视频和文件在内的富媒体。 -当前的 OpenClaw 版本已内置 QQ Bot。正常安装时,请使用 [QQ Bot](/zh-CN/channels/qqbot) 中的内置设置;只有在你明确想使用腾讯维护的独立软件包时,才安装这个外部插件。 +当前 OpenClaw 版本内置 QQ Bot。常规安装请使用 [QQ Bot](/zh-CN/channels/qqbot) 中的内置设置;仅当你明确需要 Tencent 维护的独立软件包时,才安装这个外部插件。 -- **npm:** `@tencent-connect/openclaw-qqbot` -- **仓库:** [github.com/tencent-connect/openclaw-qqbot](https://github.com/tencent-connect/openclaw-qqbot) +- **npm:** `@tencent-connect/openclaw-qqbot` +- **repo:** [github.com/tencent-connect/openclaw-qqbot](https://github.com/tencent-connect/openclaw-qqbot) ```bash openclaw plugins install @tencent-connect/openclaw-qqbot @@ -106,21 +106,21 @@ openclaw plugins install @tencent-connect/openclaw-qqbot ### wecom -由腾讯企业微信团队提供的 OpenClaw WeCom 渠道插件。基于 WeCom Bot WebSocket 长连接,支持私信和群聊、流式回复、主动消息发送、图片/文件处理、Markdown 格式化、内置访问控制,以及文档/会议/消息相关 Skills。 +Tencent WeCom 团队为 OpenClaw 提供的 WeCom 渠道插件。它由 WeCom Bot WebSocket 持久连接驱动,支持私信和群聊、流式回复、主动消息、图片/文件处理、Markdown 格式、内置访问控制,以及文档/会议/消息 Skills。 -- **npm:** `@wecom/wecom-openclaw-plugin` -- **仓库:** [github.com/WecomTeam/wecom-openclaw-plugin](https://github.com/WecomTeam/wecom-openclaw-plugin) +- **npm:** `@wecom/wecom-openclaw-plugin` +- **repo:** [github.com/WecomTeam/wecom-openclaw-plugin](https://github.com/WecomTeam/wecom-openclaw-plugin) ```bash openclaw plugins install @wecom/wecom-openclaw-plugin ``` -### Yuanbao +### 腾讯元宝 -由腾讯元宝团队提供的 OpenClaw Yuanbao 渠道插件。基于 WebSocket 长连接,支持私信和群聊、流式回复、主动消息发送、图片/文件/音频/视频处理、Markdown 格式化、内置访问控制以及斜杠命令菜单。 +Tencent 腾讯元宝团队为 OpenClaw 提供的腾讯元宝渠道插件。它由 WebSocket 持久连接驱动,支持私信和群聊、流式回复、主动消息、图片/文件/音频/视频处理、Markdown 格式、内置访问控制,以及斜杠命令菜单。 -- **npm:** `openclaw-plugin-yuanbao` -- **仓库:** [github.com/yb-claw/openclaw-plugin-yuanbao](https://github.com/yb-claw/openclaw-plugin-yuanbao) +- **npm:** `openclaw-plugin-yuanbao` +- **repo:** [github.com/yb-claw/openclaw-plugin-yuanbao](https://github.com/yb-claw/openclaw-plugin-yuanbao) ```bash openclaw plugins install openclaw-plugin-yuanbao @@ -128,41 +128,43 @@ openclaw plugins install openclaw-plugin-yuanbao ## 提交你的插件 -我们欢迎实用、有文档且可安全运行的社区插件。 +我们欢迎实用、有文档且运行安全的社区插件。 - - 你的插件必须可以通过 `openclaw plugins install \` 安装。 - 请发布到 [ClawHub](/zh-CN/tools/clawhub)(推荐)或 npm。 + + 你的插件必须可通过 `openclaw plugins install \` 安装。 + 请发布到 [ClawHub](/zh-CN/tools/clawhub),除非你明确需要仅通过 npm + 分发。 完整指南请参阅 [构建插件](/zh-CN/plugins/building-plugins)。 - - 源代码必须位于带有设置文档和 issue 跟踪器的公开仓库中。 + + 源代码必须位于包含设置文档和问题跟踪器的公开仓库中。 - - 你不需要仅为了让插件可被发现而提交文档 PR。请改为将它发布到 ClawHub。 + + 你不需要仅为了让插件可被发现而提交文档 PR。请改为将其发布到 + ClawHub。 - 只有当 OpenClaw 的源文档确实需要内容变更时,才应提交文档 PR,例如更正安装指引,或添加属于主文档集的跨仓库文档。 + 仅当 OpenClaw 的源文档需要实际内容变更时才提交文档 PR,例如修正安装指南,或添加属于主文档集的跨仓库文档。 ## 质量门槛 -| 要求 | 原因 | +| 要求 | 原因 | | --------------------------- | --------------------------------------------- | -| 发布到 ClawHub 或 npm | 用户需要 `openclaw plugins install` 能正常工作 | -| 公开的 GitHub 仓库 | 便于审查源码、跟踪问题并提升透明度 | -| 设置和使用文档 | 用户需要知道如何配置它 | -| 持续维护 | 近期有更新,或能及时响应 issue 处理 | +| 发布在 ClawHub 或 npm | 用户需要 `openclaw plugins install` 能正常工作 | +| 公开 GitHub 仓库 | 源码审查、问题跟踪、透明度 | +| 设置和使用文档 | 用户需要知道如何配置它 | +| 活跃维护 | 近期更新或及时响应问题处理 | -低质量封装、归属不清或无人维护的软件包可能会被拒绝。 +投入不足的封装、所有权不清晰或无人维护的软件包可能会被拒绝。 -## 相关内容 +## 相关 - [安装和配置插件](/zh-CN/tools/plugin) — 如何安装任意插件 - [构建插件](/zh-CN/plugins/building-plugins) — 创建你自己的插件 diff --git a/docs/zh-CN/plugins/sdk-setup.md b/docs/zh-CN/plugins/sdk-setup.md index 5b3ce2332..cce819d26 100644 --- a/docs/zh-CN/plugins/sdk-setup.md +++ b/docs/zh-CN/plugins/sdk-setup.md @@ -1,24 +1,24 @@ --- read_when: - 你正在为插件添加设置向导 - - 你需要了解 setup-entry.ts 与 index.ts 的区别 + - 你需要理解 setup-entry.ts 与 index.ts 的区别 - 你正在定义插件配置模式或 package.json openclaw 元数据 sidebarTitle: Setup and config summary: 设置向导、setup-entry.ts、配置模式和 package.json 元数据 title: 插件设置和配置 x-i18n: - generated_at: "2026-04-28T12:00:06Z" + generated_at: "2026-04-29T05:40:55Z" model: gpt-5.5 provider: openai - source_hash: b915993d7fc2ace1a21da551be5afec831c72974e1d89d4381e85f3b0ac759a6 + source_hash: 4785b95b4780341d373f119a2e08277e7ced9b92b7dd3c2b5dc0f49a64f659aa source_path: plugins/sdk-setup.md workflow: 16 --- -插件打包(`package.json` 元数据)、清单(`openclaw.plugin.json`)、设置入口和配置 schema 的参考。 +Reference,用于插件打包(`package.json` 元数据)、清单(`openclaw.plugin.json`)、设置入口和配置架构。 -**想看演练?** 操作指南会结合上下文介绍打包:[渠道插件](/zh-CN/plugins/sdk-channel-plugins#step-1-package-and-manifest) 和 [提供商插件](/zh-CN/plugins/sdk-provider-plugins#step-1-package-and-manifest)。 +**想要查看分步指南?** 操作指南会结合上下文讲解打包:[渠道插件](/zh-CN/plugins/sdk-channel-plugins#step-1-package-and-manifest) 和 [提供商插件](/zh-CN/plugins/sdk-provider-plugins#step-1-package-and-manifest)。 ## 包元数据 @@ -26,7 +26,7 @@ x-i18n: 你的 `package.json` 需要一个 `openclaw` 字段,用来告诉插件系统你的插件提供什么: - + ```json { "name": "@myorg/openclaw-my-channel", @@ -44,7 +44,7 @@ x-i18n: } ``` - + ```json openclaw-clawhub-package.json { "name": "@myorg/openclaw-my-plugin", @@ -67,7 +67,7 @@ x-i18n: -如果你在 ClawHub 上对外发布插件,这些 `compat` 和 `build` 字段是必需的。规范发布片段位于 `docs/snippets/plugin-publish/`。 +如果你在 ClawHub 上对外发布插件,这些 `compat` 和 `build` 字段是必需的。规范的发布片段位于 `docs/snippets/plugin-publish/`。 ### `openclaw` 字段 @@ -76,10 +76,10 @@ x-i18n: 入口点文件(相对于包根目录)。 - 轻量级的仅设置入口(可选)。 + 轻量的仅设置入口(可选)。 - 用于设置、选择器、快速开始和 Status 界面的渠道目录元数据。 + 用于设置、选择器、快速开始和 Status 表面的渠道目录元数据。 此插件注册的提供商 ID。 @@ -93,29 +93,29 @@ x-i18n: ### `openclaw.channel` -`openclaw.channel` 是廉价的包元数据,用于运行时加载前的渠道发现和设置界面。 +`openclaw.channel` 是用于运行时加载前的渠道发现和设置表面的低成本包元数据。 -| 字段 | 类型 | 含义 | +| 字段 | 类型 | 含义 | | -------------------------------------- | ---------- | ----------------------------------------------------------------------------- | | `id` | `string` | 规范渠道 ID。 | | `label` | `string` | 主要渠道标签。 | -| `selectionLabel` | `string` | 当应与 `label` 不同时,在选择器/设置中使用的标签。 | -| `detailLabel` | `string` | 用于更丰富的渠道目录和 Status 界面的次级详情标签。 | +| `selectionLabel` | `string` | 当需要不同于 `label` 时使用的选择器/设置标签。 | +| `detailLabel` | `string` | 用于更丰富渠道目录和 Status 表面的次级详情标签。 | | `docsPath` | `string` | 用于设置和选择链接的文档路径。 | -| `docsLabel` | `string` | 当应与渠道 ID 不同时,用于文档链接的覆盖标签。 | -| `blurb` | `string` | 简短的新手引导/目录说明。 | +| `docsLabel` | `string` | 当需要不同于渠道 ID 时,用于文档链接的覆盖标签。 | +| `blurb` | `string` | 简短的新手引导/目录描述。 | | `order` | `number` | 渠道目录中的排序顺序。 | | `aliases` | `string[]` | 用于渠道选择的额外查找别名。 | | `preferOver` | `string[]` | 此渠道应优先于的低优先级插件/渠道 ID。 | -| `systemImage` | `string` | 用于渠道 UI 目录的可选图标/系统图像名称。 | -| `selectionDocsPrefix` | `string` | 选择界面中文档链接前的前缀文本。 | -| `selectionDocsOmitLabel` | `boolean` | 在选择文案中直接显示文档路径,而不是带标签的文档链接。 | -| `selectionExtras` | `string[]` | 附加到选择文案中的额外短字符串。 | -| `markdownCapable` | `boolean` | 将渠道标记为支持 markdown,用于出站格式化决策。 | -| `exposure` | `object` | 用于设置、已配置列表和文档界面的渠道可见性控制。 | -| `quickstartAllowFrom` | `boolean` | 让此渠道加入标准快速开始 `allowFrom` 设置流程。 | -| `forceAccountBinding` | `boolean` | 即使只有一个账号,也要求显式账号绑定。 | -| `preferSessionLookupForAnnounceTarget` | `boolean` | 为此渠道解析公告目标时,优先使用会话查找。 | +| `systemImage` | `string` | 渠道 UI 目录的可选图标/系统图片名称。 | +| `selectionDocsPrefix` | `string` | 选择表面中文档链接之前的前缀文本。 | +| `selectionDocsOmitLabel` | `boolean` | 在选择文案中直接显示文档路径,而不是带标签的文档链接。 | +| `selectionExtras` | `string[]` | 追加到选择文案中的额外短字符串。 | +| `markdownCapable` | `boolean` | 将渠道标记为支持 Markdown,用于出站格式化决策。 | +| `exposure` | `object` | 控制渠道在设置、已配置列表和文档表面中的可见性。 | +| `quickstartAllowFrom` | `boolean` | 将此渠道加入标准快速开始 `allowFrom` 设置流程。 | +| `forceAccountBinding` | `boolean` | 即使只有一个账号存在,也要求显式账号绑定。 | +| `preferSessionLookupForAnnounceTarget` | `boolean` | 为此渠道解析公告目标时优先使用会话查找。 | 示例: @@ -149,9 +149,9 @@ x-i18n: `exposure` 支持: -- `configured`:在已配置/Status 风格的列表界面中包含该渠道 +- `configured`:在已配置/Status 风格的列表表面中包含该渠道 - `setup`:在交互式设置/配置选择器中包含该渠道 -- `docs`:在文档/导航界面中将该渠道标记为面向公众 +- `docs`:在文档/导航表面中将该渠道标记为面向公众 `showConfigured` 和 `showInSetup` 仍作为旧版别名受支持。优先使用 `exposure`。 @@ -161,24 +161,24 @@ x-i18n: `openclaw.install` 是包元数据,不是清单元数据。 -| 字段 | 类型 | 含义 | -| ---------------------------- | -------------------- | ------------------------------------------------------------------------------ | -| `npmSpec` | `string` | 用于安装/更新流程的规范 npm spec。 | -| `localPath` | `string` | 本地开发或内置安装路径。 | -| `defaultChoice` | `"npm"` \| `"local"` | 当两者都可用时的首选安装来源。 | -| `minHostVersion` | `string` | 支持的最低 OpenClaw 版本,格式为 `>=x.y.z`。 | -| `expectedIntegrity` | `string` | 预期的 npm dist 完整性字符串,通常为 `sha512-...`,用于固定安装。 | -| `allowInvalidConfigRecovery` | `boolean` | 允许内置插件重装流程从特定的过期配置故障中恢复。 | +| 字段 | 类型 | 含义 | +| ---------------------------- | -------------------- | -------------------------------------------------------------------------------- | +| `npmSpec` | `string` | 用于安装/更新流程的规范 npm 规范。 | +| `localPath` | `string` | 本地开发或内置安装路径。 | +| `defaultChoice` | `"npm"` \| `"local"` | 两者都可用时的首选安装来源。 | +| `minHostVersion` | `string` | 受支持的最低 OpenClaw 版本,格式为 `>=x.y.z`。 | +| `expectedIntegrity` | `string` | 预期的 npm dist 完整性字符串,通常为 `sha512-...`,用于固定版本安装。 | +| `allowInvalidConfigRecovery` | `boolean` | 允许内置插件重装流程从特定的陈旧配置故障中恢复。 | - - 交互式新手引导也会将 `openclaw.install` 用于按需安装界面。如果你的插件在运行时加载前暴露提供商认证选项或渠道设置/目录元数据,新手引导可以显示该选项,提示选择 npm 还是本地安装,安装或启用插件,然后继续所选流程。npm 新手引导选项需要带有注册表 `npmSpec` 的可信目录元数据;精确版本和 `expectedIntegrity` 是可选固定值。如果存在 `expectedIntegrity`,安装/更新流程会强制校验它。将“显示什么”的元数据放在 `openclaw.plugin.json` 中,将“如何安装它”的元数据放在 `package.json` 中。 + + 交互式新手引导也会在按需安装表面使用 `openclaw.install`。如果你的插件在运行时加载前公开提供商认证选项或渠道设置/目录元数据,新手引导可以显示该选项,提示选择 npm 还是本地安装,安装或启用该插件,然后继续所选流程。Npm 新手引导选项需要带有 registry `npmSpec` 的可信目录元数据;精确版本和 `expectedIntegrity` 是可选固定项。如果存在 `expectedIntegrity`,安装/更新流程会强制校验它。将“显示什么”的元数据放在 `openclaw.plugin.json` 中,将“如何安装它”的元数据放在 `package.json` 中。 - - 如果设置了 `minHostVersion`,安装和清单注册表加载都会强制执行它。较旧的宿主会跳过该插件;无效的版本字符串会被拒绝。 + + 如果设置了 `minHostVersion`,安装和清单注册表加载都会强制执行它。较旧的主机会跳过该插件;无效的版本字符串会被拒绝。 - - 对于固定 npm 安装,请在 `npmSpec` 中保留精确版本,并添加预期制品完整性: + + 对于固定的 npm 安装,请在 `npmSpec` 中保留精确版本,并添加预期的构件完整性: ```json { @@ -193,8 +193,8 @@ x-i18n: ``` - - `allowInvalidConfigRecovery` 不是破损配置的通用绕过方式。它只用于狭窄的内置插件恢复场景,因此重装/设置可以修复已知的升级遗留项,例如缺失的内置插件路径,或同一插件的过期 `channels.` 条目。如果配置因无关原因而破损,安装仍会关闭失败,并提示操作员运行 `openclaw doctor --fix`。 + + `allowInvalidConfigRecovery` 不是破损配置的通用绕过机制。它只用于狭窄的内置插件恢复场景,使重装/设置可以修复已知升级遗留项,例如缺少内置插件路径,或同一插件的陈旧 `channels.` 条目。如果配置因无关原因损坏,安装仍会关闭失败,并提示操作员运行 `openclaw doctor --fix`。 @@ -214,17 +214,17 @@ x-i18n: } ``` -启用后,即使对于已经配置的渠道,OpenClaw 在监听前启动阶段也只加载 `setupEntry`。完整入口会在 Gateway 网关开始监听后加载。 +启用后,即使对于已配置的渠道,OpenClaw 在监听前启动阶段也只加载 `setupEntry`。完整入口会在 Gateway 网关开始监听后加载。 -只有当你的 `setupEntry` 在网关开始监听前注册了网关所需的一切(渠道注册、HTTP 路由、Gateway 网关方法)时,才启用延迟加载。如果完整入口拥有必需的启动能力,请保留默认行为。 +只有当你的 `setupEntry` 注册了 Gateway 网关开始监听前所需的一切(渠道注册、HTTP 路由、Gateway 网关方法)时,才启用延迟加载。如果完整入口拥有必需的启动能力,请保留默认行为。 -如果你的设置/完整入口注册 Gateway 网关 RPC 方法,请将它们放在插件专用前缀下。保留的核心管理命名空间(`config.*`、`exec.approvals.*`、`wizard.*`、`update.*`)仍归核心所有,并且始终解析为 `operator.admin`。 +如果你的设置/完整入口注册 Gateway 网关 RPC 方法,请将它们放在插件专属前缀下。保留的核心管理命名空间(`config.*`、`exec.approvals.*`、`wizard.*`、`update.*`)保持由核心拥有,并始终解析到 `operator.admin`。 ## 插件清单 -每个原生插件都必须在包根目录中附带一个 `openclaw.plugin.json`。OpenClaw 使用它在不执行插件代码的情况下验证配置。 +每个原生插件都必须在包根目录中随附一个 `openclaw.plugin.json`。OpenClaw 使用它在不执行插件代码的情况下验证配置。 ```json { @@ -244,7 +244,7 @@ x-i18n: } ``` -对于渠道插件,请添加 `kind` 和 `channels`: +对于渠道插件,添加 `kind` 和 `channels`: ```json { @@ -259,7 +259,7 @@ x-i18n: } ``` -即使没有配置的插件也必须附带 schema。空 schema 是有效的: +即使没有配置的插件也必须随附一个架构。空架构是有效的: ```json { @@ -271,11 +271,11 @@ x-i18n: } ``` -完整 schema 参考见[插件清单](/zh-CN/plugins/manifest)。 +完整架构参考见 [插件清单](/zh-CN/plugins/manifest)。 ## ClawHub 发布 -对于插件包,请使用包专用的 ClawHub 命令: +对于插件包,请使用包专属的 ClawHub 命令: ```bash clawhub package publish your-org/your-plugin --dry-run @@ -283,12 +283,12 @@ clawhub package publish your-org/your-plugin ``` -旧版仅 Skills 发布别名用于 Skills。插件包应始终使用 `clawhub package publish`。 +旧版的仅技能发布别名用于 Skills。插件包应始终使用 `clawhub package publish`。 ## 设置入口 -`setup-entry.ts` 文件是 `index.ts` 的轻量级替代入口,OpenClaw 仅需要设置界面(新手引导、配置修复、已禁用渠道检查)时会加载它。 +`setup-entry.ts` 文件是 `index.ts` 的轻量替代项,OpenClaw 只需要设置表面(新手引导、配置修复、已禁用渠道检查)时会加载它。 ```typescript // setup-entry.ts @@ -298,9 +298,9 @@ import { myChannelPlugin } from "./src/channel.js"; export default defineSetupPluginEntry(myChannelPlugin); ``` -这可以避免在设置流程中加载繁重的运行时代码(加密库、CLI 注册、后台服务)。 +这会避免在设置流程中加载沉重的运行时代码(加密库、CLI 注册、后台服务)。 -将设置安全导出放在 sidecar 模块中的内置工作区渠道,可以使用 `openclaw/plugin-sdk/channel-entry-contract` 中的 `defineBundledChannelSetupEntry(...)`,而不是 `defineSetupPluginEntry(...)`。该内置契约还支持可选的 `runtime` 导出,因此设置期间的运行时接线可以保持轻量且显式。 +在 sidecar 模块中保留设置安全导出的内置工作区渠道,可以使用来自 `openclaw/plugin-sdk/channel-entry-contract` 的 `defineBundledChannelSetupEntry(...)`,而不是 `defineSetupPluginEntry(...)`。该内置契约还支持可选的 `runtime` 导出,因此设置时的运行时接线可以保持轻量且显式。 @@ -320,43 +320,43 @@ export default defineSetupPluginEntry(myChannelPlugin); - CLI 注册。 - 后台服务。 - - 繁重的运行时导入(加密、SDK)。 + - 沉重的运行时导入(加密、SDK)。 - 仅在启动后才需要的 Gateway 网关方法。 -### 窄设置辅助导入 +### 窄范围设置助手导入 -对于热路径上的仅设置路径,如果你只需要设置界面的一部分,请优先使用窄设置辅助接缝,而不是更宽泛的 `plugin-sdk/setup` 总括模块: +对于热路径中的仅设置流程,如果你只需要设置界面的一部分,优先使用窄范围设置助手接缝,而不是更宽泛的 `plugin-sdk/setup` 伞形入口: -| 导入路径 | 用途 | 关键导出 | +| 导入路径 | 用途 | 关键导出 | | ---------------------------------- | ----------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `plugin-sdk/setup-runtime` | 在 `setupEntry` / 延迟渠道启动中保持可用的设置期间运行时辅助工具 | `createPatchedAccountSetupAdapter`, `createEnvPatchedAccountSetupAdapter`, `createSetupInputPresenceValidator`, `noteChannelLookupFailure`, `noteChannelLookupSummary`, `promptResolvedAllowFrom`, `splitSetupEntries`, `createAllowlistSetupWizardProxy`, `createDelegatedSetupWizardProxy` | -| `plugin-sdk/setup-adapter-runtime` | 感知环境的账号设置适配器 | `createEnvPatchedAccountSetupAdapter` | -| `plugin-sdk/setup-tools` | 设置/安装 CLI/归档/文档辅助工具 | `formatCliCommand`, `detectBinary`, `extractArchive`, `resolveBrewExecutable`, `formatDocsLink`, `CONFIG_DIR` | +| `plugin-sdk/setup-runtime` | 设置时运行时助手,可在 `setupEntry` / 延迟渠道启动中保持可用 | `createPatchedAccountSetupAdapter`, `createEnvPatchedAccountSetupAdapter`, `createSetupInputPresenceValidator`, `noteChannelLookupFailure`, `noteChannelLookupSummary`, `promptResolvedAllowFrom`, `splitSetupEntries`, `createAllowlistSetupWizardProxy`, `createDelegatedSetupWizardProxy` | +| `plugin-sdk/setup-adapter-runtime` | 感知环境的账号设置适配器 | `createEnvPatchedAccountSetupAdapter` | +| `plugin-sdk/setup-tools` | 设置/安装 CLI/归档/文档助手 | `formatCliCommand`, `detectBinary`, `extractArchive`, `resolveBrewExecutable`, `formatDocsLink`, `CONFIG_DIR` | -当你需要完整的共享设置工具箱时,请使用更宽泛的 `plugin-sdk/setup` 接缝,包括 `moveSingleAccountChannelSectionToDefaultAccount(...)` 等配置补丁辅助工具。 +当你需要完整的共享设置工具箱时,请使用更宽泛的 `plugin-sdk/setup` 接缝,包括 `moveSingleAccountChannelSectionToDefaultAccount(...)` 等配置补丁助手。 -设置补丁适配器在导入时保持热路径安全。它们的内置单账号提升契约界面查找是惰性的,因此导入 `plugin-sdk/setup-runtime` 不会在适配器实际使用前急切加载内置契约界面发现逻辑。 +设置补丁适配器在导入时保持热路径安全。其内置的单账号提升契约界面查找是惰性的,因此导入 `plugin-sdk/setup-runtime` 不会在实际使用适配器前急切加载内置契约界面发现逻辑。 ### 渠道拥有的单账号提升 -当某个渠道从单账号顶层配置升级到 `channels..accounts.*` 时,默认共享行为是将提升后的账号作用域值移入 `accounts.default`。 +当渠道从单账号顶层配置升级到 `channels..accounts.*` 时,默认共享行为是将提升后的账号作用域值移动到 `accounts.default`。 -内置渠道可以通过其设置契约界面收窄或覆盖该提升: +内置渠道可以通过其设置契约界面缩小或覆盖该提升行为: -- `singleAccountKeysToMove`:应移入已提升账号的额外顶层键 -- `namedAccountPromotionKeys`:当命名账号已经存在时,只有这些键会移入已提升账号;共享策略/投递键会保留在渠道根级别 +- `singleAccountKeysToMove`:应移动到提升账号中的额外顶层键 +- `namedAccountPromotionKeys`:当命名账号已存在时,只有这些键会移动到提升账号;共享策略/投递键保留在渠道根部 - `resolveSingleAccountPromotionTarget(...)`:选择哪个现有账号接收提升后的值 -Matrix 是当前的内置示例。如果已经恰好存在一个命名 Matrix 账号,或者 `defaultAccount` 指向现有的非规范键(例如 `Ops`),提升会保留该账号,而不是创建新的 `accounts.default` 条目。 +Matrix 是当前的内置示例。如果恰好已存在一个命名 Matrix 账号,或者 `defaultAccount` 指向一个现有的非规范键(例如 `Ops`),提升会保留该账号,而不是创建新的 `accounts.default` 条目。 -## 配置架构 +## 配置 schema -插件配置会根据清单中的 JSON Schema 进行验证。用户通过以下方式配置插件: +插件配置会根据你的清单中的 JSON Schema 进行验证。用户通过以下方式配置插件: ```json5 { @@ -374,7 +374,7 @@ Matrix 是当前的内置示例。如果已经恰好存在一个命名 Matrix 你的插件会在注册期间通过 `api.pluginConfig` 接收此配置。 -对于特定渠道的配置,请改用渠道配置段: +对于渠道特定配置,请改用渠道配置部分: ```json5 { @@ -387,9 +387,9 @@ Matrix 是当前的内置示例。如果已经恰好存在一个命名 Matrix } ``` -### 构建渠道配置架构 +### 构建渠道配置 schema -使用 `buildChannelConfigSchema` 将 Zod 架构转换为插件拥有的配置工件所使用的 `ChannelConfigSchema` 包装器: +使用 `buildChannelConfigSchema` 将 Zod schema 转换为插件拥有的配置构件所使用的 `ChannelConfigSchema` 包装器: ```typescript import { z } from "zod"; @@ -405,11 +405,11 @@ const accountSchema = z.object({ const configSchema = buildChannelConfigSchema(accountSchema); ``` -对于第三方插件,冷路径契约仍然是插件清单:将生成的 JSON Schema 镜像到 `openclaw.plugin.json#channelConfigs`,以便配置架构、设置和 UI 界面可以在不加载运行时代码的情况下检查 `channels.`。 +对于第三方插件,冷路径契约仍然是插件清单:将生成的 JSON Schema 镜像到 `openclaw.plugin.json#channelConfigs`,这样配置 schema、设置和 UI 界面就可以在不加载运行时代码的情况下检查 `channels.`。 ## 设置向导 -渠道插件可以为 `openclaw onboard` 提供交互式设置向导。向导是 `ChannelPlugin` 上的 `ChannelSetupWizard` 对象: +渠道插件可以为 `openclaw onboard` 提供交互式设置向导。该向导是 `ChannelPlugin` 上的一个 `ChannelSetupWizard` 对象: ```typescript import type { ChannelSetupWizard } from "openclaw/plugin-sdk/channel-setup"; @@ -442,17 +442,17 @@ const setupWizard: ChannelSetupWizard = { }; ``` -`ChannelSetupWizard` 类型支持 `credentials`、`textInputs`、`dmPolicy`、`allowFrom`、`groupAccess`、`prepare`、`finalize` 等。完整示例请参阅内置插件包(例如 Discord 插件的 `src/channel.setup.ts`)。 +`ChannelSetupWizard` 类型支持 `credentials`、`textInputs`、`dmPolicy`、`allowFrom`、`groupAccess`、`prepare`、`finalize` 等。完整示例请参阅内置插件包(例如 Discord 插件 `src/channel.setup.ts`)。 - 对于只需要标准 `note -> prompt -> parse -> merge -> patch` 流程的私信允许列表提示,请优先使用 `openclaw/plugin-sdk/setup` 中的共享设置辅助工具:`createPromptParsedAllowFromForAccount(...)`、`createTopLevelChannelParsedAllowFromPrompt(...)` 和 `createNestedChannelParsedAllowFromPrompt(...)`。 + 对于只需要标准 `note -> prompt -> parse -> merge -> patch` 流程的私信 allowlist 提示,优先使用来自 `openclaw/plugin-sdk/setup` 的共享设置助手:`createPromptParsedAllowFromForAccount(...)`、`createTopLevelChannelParsedAllowFromPrompt(...)` 和 `createNestedChannelParsedAllowFromPrompt(...)`。 - - 对于仅在标签、分数和可选额外行上有所不同的渠道设置状态块,请优先使用 `openclaw/plugin-sdk/setup` 中的 `createStandardChannelSetupStatus(...)`,而不是在每个插件中手写相同的 `status` 对象。 + + 对于只因标签、分数和可选额外行而变化的渠道设置 Status 块,优先使用来自 `openclaw/plugin-sdk/setup` 的 `createStandardChannelSetupStatus(...)`,而不是在每个插件中手写相同的 `status` 对象。 - 对于只应在特定上下文中出现的可选设置界面,请使用 `openclaw/plugin-sdk/channel-setup` 中的 `createOptionalChannelSetupSurface`: + 对于只应在特定上下文中出现的可选设置界面,请使用来自 `openclaw/plugin-sdk/channel-setup` 的 `createOptionalChannelSetupSurface`: ```typescript import { createOptionalChannelSetupSurface } from "openclaw/plugin-sdk/channel-setup"; @@ -468,26 +468,26 @@ const setupWizard: ChannelSetupWizard = { 当你只需要该可选安装界面的一半时,`plugin-sdk/channel-setup` 还公开了更底层的 `createOptionalChannelSetupAdapter(...)` 和 `createOptionalChannelSetupWizard(...)` 构建器。 - 生成的可选适配器/向导会对真实配置写入采取封闭失败策略。它们会在 `validateInput`、`applyAccountConfig` 和 `finalize` 中复用同一条需要安装的消息,并在设置了 `docsPath` 时追加文档链接。 + 生成的可选适配器/向导会在真实配置写入时默认拒绝。它们在 `validateInput`、`applyAccountConfig` 和 `finalize` 中复用一条需要安装的消息,并在设置了 `docsPath` 时附加文档链接。 - - 对于二进制驱动的设置 UI,请优先使用共享委托辅助工具,而不是在每个渠道中复制相同的二进制/状态接合代码: + + 对于由二进制驱动的设置 UI,优先使用共享委托助手,而不是把相同的二进制/Status 胶水复制到每个渠道中: - - `createDetectedBinaryStatus(...)`:用于仅在标签、提示、分数和二进制检测上有所不同的状态块 + - `createDetectedBinaryStatus(...)`:用于只因标签、提示、分数和二进制检测而变化的 Status 块 - `createCliPathTextInput(...)`:用于基于路径的文本输入 - `createDelegatedSetupWizardStatusResolvers(...)`、`createDelegatedPrepare(...)`、`createDelegatedFinalize(...)` 和 `createDelegatedResolveConfigured(...)`:当 `setupEntry` 需要惰性转发到更重的完整向导时使用 - - `createDelegatedTextInputShouldPrompt(...)`:当 `setupEntry` 只需要委托一个 `textInputs[*].shouldPrompt` 决策时使用 + - `createDelegatedTextInputShouldPrompt(...)`:当 `setupEntry` 只需要委托 `textInputs[*].shouldPrompt` 决策时使用 ## 发布和安装 -**外部插件:**发布到 [ClawHub](/zh-CN/tools/clawhub) 或 npm,然后安装: +**外部插件:**发布到 [ClawHub](/zh-CN/tools/clawhub),然后安装: - + ```bash openclaw plugins install @myorg/openclaw-my-plugin ``` @@ -500,17 +500,17 @@ const setupWizard: ChannelSetupWizard = { openclaw plugins install clawhub:@myorg/openclaw-my-plugin ``` - - 没有匹配的 `npm:` 覆盖项。当你希望在 ClawHub 回退后走 npm 路径时,请使用普通的 npm 包规范: + + 当包尚未迁移到 ClawHub,或者你在迁移期间需要直接 npm 安装路径时,请使用 npm: ```bash - openclaw plugins install @myorg/openclaw-my-plugin + openclaw plugins install npm:@myorg/openclaw-my-plugin ``` -**仓库内插件:**放在内置插件工作区树下,它们会在构建期间自动发现。 +**仓库内插件:**放在内置插件工作区树下,构建期间会自动发现它们。 **用户可以安装:** @@ -519,15 +519,15 @@ openclaw plugins install ``` -对于来自 npm 的安装,`openclaw plugins install` 会运行项目本地的 `npm install --ignore-scripts`(无生命周期脚本),并忽略继承的全局 npm 安装设置。请保持插件依赖树为纯 JS/TS,并避免使用需要 `postinstall` 构建的软件包。 +对于来源于 npm 的安装,`openclaw plugins install` 会运行项目本地的 `npm install --ignore-scripts`(无生命周期脚本),并忽略继承的全局 npm 安装设置。保持插件依赖树为纯 JS/TS,并避免需要 `postinstall` 构建的软件包。 -内置且由 OpenClaw 拥有的插件是唯一的启动修复例外:当打包安装发现插件配置、旧版渠道配置或其内置的默认启用 manifest 启用了某个插件时,启动会在导入前安装该插件缺失的运行时依赖项。第三方插件不应依赖启动时安装;请继续使用显式插件安装器。 +内置且由 OpenClaw 拥有的插件是唯一的启动修复例外:当打包安装发现某个插件通过插件配置、旧版渠道配置或其内置的默认启用清单被启用时,启动会在导入前安装该插件缺失的运行时依赖项。第三方插件不应依赖启动安装;请继续使用显式插件安装器。 ## 相关 -- [构建插件](/zh-CN/plugins/building-plugins) — 分步式入门指南 -- [插件 manifest](/zh-CN/plugins/manifest) — 完整 manifest schema 参考 +- [构建插件](/zh-CN/plugins/building-plugins) — 分步入门指南 +- [插件清单](/zh-CN/plugins/manifest) — 完整的清单架构参考 - [SDK 入口点](/zh-CN/plugins/sdk-entrypoints) — `definePluginEntry` 和 `defineChannelPluginEntry` diff --git a/docs/zh-CN/plugins/sdk-subpaths.md b/docs/zh-CN/plugins/sdk-subpaths.md index 8bd1b0c42..ec495242e 100644 --- a/docs/zh-CN/plugins/sdk-subpaths.md +++ b/docs/zh-CN/plugins/sdk-subpaths.md @@ -2,51 +2,49 @@ read_when: - 为插件导入选择正确的 plugin-sdk 子路径 - 审计内置插件子路径和辅助接口面 -summary: 插件 SDK 子路径目录:按领域分组列出各导入项所在位置 +summary: 插件 SDK 子路径目录:哪些导入位于何处,按领域分组 title: 插件 SDK 子路径 x-i18n: - generated_at: "2026-04-29T04:42:14Z" + generated_at: "2026-04-29T05:41:00Z" model: gpt-5.5 provider: openai - source_hash: 2ca42dc1b56245b8d26924eb2b957dac872fd0e2db4b62978ab2e2e15dcde3dc + source_hash: a6830e451e9db504c9293992d50ba4bcb149d31d2e54d29f925f01ad4243ed95 source_path: plugins/sdk-subpaths.md workflow: 16 --- - 插件 SDK 作为 `openclaw/plugin-sdk/` 下的一组窄子路径公开。 - 本页按用途分组列出常用子路径。生成的 200+ 子路径完整列表位于 `scripts/lib/plugin-sdk-entrypoints.json`; - 保留的内置插件辅助子路径会出现在其中,但除非某个文档页面明确推荐,否则它们属于实现细节。 - 维护者可以用 `pnpm plugins:boundary-report:summary` 审计当前保留的辅助子路径;未使用的 - 保留辅助导出会使 CI 报告失败,而不是作为休眠的兼容性负担留在公共 SDK 中。 + 插件 SDK 以 `openclaw/plugin-sdk/` 下的一组窄子路径形式暴露。 + 本页按用途分组列出常用子路径。生成的 200+ 个子路径完整列表位于 `scripts/lib/plugin-sdk-entrypoints.json`; + 保留的内置插件辅助子路径会出现在那里,但除非文档页面明确提升它们,否则它们属于实现细节。维护者可以使用 `pnpm plugins:boundary-report:summary` 审计当前活跃的保留辅助子路径;未使用的保留辅助导出会导致 CI 报告失败,而不是作为休眠的兼容性债务留在公共 SDK 中。 - 关于插件创作指南,请参阅 [插件 SDK 概览](/zh-CN/plugins/sdk-overview)。 + 插件编写指南见 [插件 SDK 概览](/zh-CN/plugins/sdk-overview)。 ## 插件入口 - | Subpath | 主要导出 | + | 子路径 | 关键导出 | | ----------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `plugin-sdk/plugin-entry` | `definePluginEntry` | | `plugin-sdk/core` | `defineChannelPluginEntry`, `createChatChannelPlugin`, `createChannelPluginBase`, `defineSetupPluginEntry`, `buildChannelConfigSchema` | | `plugin-sdk/config-schema` | `OpenClawSchema` | | `plugin-sdk/provider-entry` | `defineSingleProviderPluginEntry` | - | `plugin-sdk/testing` | 面向旧版插件测试的宽泛兼容性 barrel;新的插件测试应优先使用聚焦的测试子路径 | + | `plugin-sdk/testing` | 面向旧版插件测试的宽兼容 barrel;新扩展测试应优先使用聚焦的测试子路径 | | `plugin-sdk/plugin-test-api` | 用于直接插件注册单元测试的最小 `OpenClawPluginApi` mock 构建器 | - | `plugin-sdk/agent-runtime-test-contracts` | 原生智能体运行时适配器契约夹具,涵盖认证配置文件、投递抑制、回退分类、工具钩子、提示词覆盖、schema 和转录修复 | - | `plugin-sdk/channel-test-helpers` | 渠道账号生命周期、目录、发送配置、运行时 mock、钩子、内置渠道入口、信封时间戳、配对回复和通用渠道契约测试辅助工具 | - | `plugin-sdk/channel-target-testing` | 共享的渠道目标解析错误场景测试套件 | - | `plugin-sdk/plugin-test-contracts` | 插件注册、包清单、公共工件、运行时 API、导入副作用和直接导入契约辅助工具 | - | `plugin-sdk/plugin-test-runtime` | 用于测试的插件运行时、注册表、提供商注册、设置向导和运行时任务流夹具 | - | `plugin-sdk/provider-test-contracts` | 提供商运行时、认证、设备发现、新手引导、目录、媒体能力、重放策略、实时 STT 实时音频、Web 搜索/抓取和向导契约辅助工具 | - | `plugin-sdk/provider-http-test-mocks` | 面向演练 `plugin-sdk/provider-http` 的提供商测试的可选 Vitest HTTP/认证 mock | + | `plugin-sdk/agent-runtime-test-contracts` | 面向认证配置文件、投递抑制、回退分类、工具钩子、提示词叠加层、schema 和 transcript 修复的原生 agent-runtime 适配器契约夹具 | + | `plugin-sdk/channel-test-helpers` | 渠道账户生命周期、目录、发送配置、运行时 mock、钩子、内置渠道入口、信封时间戳、配对回复和通用渠道契约测试辅助工具 | + | `plugin-sdk/channel-target-testing` | 共享渠道目标解析错误用例测试套件 | + | `plugin-sdk/plugin-test-contracts` | 插件注册、包 manifest、公共制品、运行时 API、导入副作用和直接导入契约辅助工具 | + | `plugin-sdk/plugin-test-runtime` | 用于测试的插件运行时、registry、提供商注册、设置向导和运行时任务流夹具 | + | `plugin-sdk/provider-test-contracts` | 提供商运行时、认证、设备发现、onboard、catalog、媒体能力、重放策略、实时 STT 实时音频、Web 搜索/fetch 和向导契约辅助工具 | + | `plugin-sdk/provider-http-test-mocks` | 面向会执行 `plugin-sdk/provider-http` 的提供商测试的可选 Vitest HTTP/认证 mock | | `plugin-sdk/test-env` | 测试环境、fetch/网络、一次性 HTTP 服务器、传入请求、实时测试、临时文件系统和时间控制夹具 | - | `plugin-sdk/test-fixtures` | 通用 CLI、沙箱、skill、智能体消息、系统事件、模块重新加载、内置插件路径、终端、分块、认证令牌和类型化用例测试夹具 | + | `plugin-sdk/test-fixtures` | 通用 CLI、沙箱、skill、agent-message、system-event、模块重新加载、内置插件路径、终端、分块、认证令牌和类型化 case 测试夹具 | | `plugin-sdk/test-node-mocks` | 用于 Vitest `vi.mock("node:*")` 工厂内部的聚焦 Node 内置 mock 辅助工具 | | `plugin-sdk/migration` | 迁移提供商条目辅助工具,例如 `createMigrationItem`、原因常量、条目状态标记、脱敏辅助工具和 `summarizeMigrationItems` | | `plugin-sdk/migration-runtime` | 运行时迁移辅助工具,例如 `copyMigrationFileItem` 和 `writeMigrationReport` | - | Subpath | 主要导出 | + | 子路径 | 关键导出 | | --- | --- | | `plugin-sdk/channel-core` | `defineChannelPluginEntry`, `defineSetupPluginEntry`, `createChatChannelPlugin`, `createChannelPluginBase` | | `plugin-sdk/config-schema` | 根 `openclaw.json` Zod schema 导出(`OpenClawSchema`) | @@ -55,117 +53,117 @@ x-i18n: | `plugin-sdk/setup-runtime` | `createPatchedAccountSetupAdapter`, `createEnvPatchedAccountSetupAdapter`, `createSetupInputPresenceValidator`, `noteChannelLookupFailure`, `noteChannelLookupSummary`, `promptResolvedAllowFrom`, `splitSetupEntries`, `createAllowlistSetupWizardProxy`, `createDelegatedSetupWizardProxy` | | `plugin-sdk/setup-adapter-runtime` | `createEnvPatchedAccountSetupAdapter` | | `plugin-sdk/setup-tools` | `formatCliCommand`, `detectBinary`, `extractArchive`, `resolveBrewExecutable`, `formatDocsLink`, `CONFIG_DIR` | - | `plugin-sdk/account-core` | 多账号配置/操作门控辅助工具、默认账号回退辅助工具 | - | `plugin-sdk/account-id` | `DEFAULT_ACCOUNT_ID`、账号 ID 规范化辅助工具 | - | `plugin-sdk/account-resolution` | 账号查找 + 默认回退辅助工具 | - | `plugin-sdk/account-helpers` | 窄账号列表/账号操作辅助工具 | + | `plugin-sdk/account-core` | 多账户配置/操作门控辅助工具、默认账户回退辅助工具 | + | `plugin-sdk/account-id` | `DEFAULT_ACCOUNT_ID`,账户 ID 规范化辅助工具 | + | `plugin-sdk/account-resolution` | 账户查找 + 默认回退辅助工具 | + | `plugin-sdk/account-helpers` | 窄账户列表/账户操作辅助工具 | | `plugin-sdk/channel-pairing` | `createChannelPairingController` | | `plugin-sdk/channel-reply-pipeline` | `createChannelReplyPipeline`, `resolveChannelSourceReplyDeliveryMode` | | `plugin-sdk/channel-config-helpers` | `createHybridChannelConfigAdapter` | - | `plugin-sdk/channel-config-schema` | 共享渠道配置 schema 原语和通用构建器 | - | `plugin-sdk/bundled-channel-config-schema` | 仅供维护中的内置插件使用的内置 OpenClaw 渠道配置 schema | - | `plugin-sdk/channel-config-schema-legacy` | 内置渠道配置 schema 的已弃用兼容性别名 | - | `plugin-sdk/telegram-command-config` | Telegram 自定义命令规范化/验证辅助工具,带内置契约回退 | + | `plugin-sdk/channel-config-schema` | 共享渠道配置 schema primitives 和通用构建器 | + | `plugin-sdk/bundled-channel-config-schema` | 仅供维护的内置插件使用的内置 OpenClaw 渠道配置 schema | + | `plugin-sdk/channel-config-schema-legacy` | 内置渠道配置 schema 的已废弃兼容性别名 | + | `plugin-sdk/telegram-command-config` | 带内置契约回退的 Telegram 自定义命令规范化/校验辅助工具 | | `plugin-sdk/command-gating` | 窄命令授权门控辅助工具 | | `plugin-sdk/channel-policy` | `resolveChannelGroupRequireMention` | - | `plugin-sdk/channel-lifecycle` | `createAccountStatusSink`、草稿流生命周期/完成辅助工具 | - | `plugin-sdk/inbound-envelope` | 共享传入路由 + 信封构建器辅助工具 | - | `plugin-sdk/inbound-reply-dispatch` | 共享传入记录和分发辅助工具 | + | `plugin-sdk/channel-lifecycle` | `createAccountStatusSink`, `createChannelRunQueue`,草稿流生命周期/最终化辅助工具 | + | `plugin-sdk/inbound-envelope` | 共享入站路由 + 信封构建器辅助工具 | + | `plugin-sdk/inbound-reply-dispatch` | 共享入站记录和分派辅助工具 | | `plugin-sdk/messaging-targets` | 目标解析/匹配辅助工具 | | `plugin-sdk/outbound-media` | 共享出站媒体加载辅助工具 | - | `plugin-sdk/outbound-send-deps` | 面向渠道适配器的轻量出站发送依赖查找 | - | `plugin-sdk/outbound-runtime` | 出站投递、身份、发送委托、会话、格式化和负载规划辅助工具 | + | `plugin-sdk/outbound-send-deps` | 面向渠道适配器的轻量级出站发送依赖查找 | + | `plugin-sdk/outbound-runtime` | 出站投递、身份、发送委托、会话、格式化和载荷规划辅助工具 | | `plugin-sdk/poll-runtime` | 窄投票规范化辅助工具 | | `plugin-sdk/thread-bindings-runtime` | 线程绑定生命周期和适配器辅助工具 | - | `plugin-sdk/agent-media-payload` | 旧版智能体媒体负载构建器 | + | `plugin-sdk/agent-media-payload` | 旧版智能体媒体载荷构建器 | | `plugin-sdk/conversation-runtime` | 对话/线程绑定、配对和已配置绑定辅助工具 | | `plugin-sdk/runtime-config-snapshot` | 运行时配置快照辅助工具 | | `plugin-sdk/runtime-group-policy` | 运行时群组策略解析辅助工具 | - | `plugin-sdk/channel-status` | 共享渠道 Status 快照/摘要辅助工具 | - | `plugin-sdk/channel-config-primitives` | 窄渠道配置 schema 原语 | + | `plugin-sdk/channel-status` | 共享渠道状态快照/摘要辅助工具 | + | `plugin-sdk/channel-config-primitives` | 窄渠道配置 schema primitives | | `plugin-sdk/channel-config-writes` | 渠道配置写入授权辅助工具 | - | `plugin-sdk/channel-plugin-common` | 共享渠道插件前置导出 | + | `plugin-sdk/channel-plugin-common` | 共享渠道插件 prelude 导出 | | `plugin-sdk/allowlist-config-edit` | allowlist 配置编辑/读取辅助工具 | | `plugin-sdk/group-access` | 共享群组访问决策辅助工具 | - | `plugin-sdk/direct-dm` | 共享直接私信认证/防护辅助工具 | - | `plugin-sdk/discord` | 已弃用的 Discord 兼容性 facade,用于已发布的 `@openclaw/discord@2026.3.13` 和已跟踪的所有者兼容性;新插件应使用通用渠道 SDK 子路径 | - | `plugin-sdk/telegram-account` | 已弃用的 Telegram 账号解析兼容性 facade,用于已跟踪的所有者兼容性;新插件应使用注入的运行时辅助工具或通用渠道 SDK 子路径 | - | `plugin-sdk/interactive-runtime` | 语义消息呈现、投递和旧版交互式回复辅助工具。参阅 [消息呈现](/zh-CN/plugins/message-presentation) | - | `plugin-sdk/channel-inbound` | 传入防抖、提及匹配、提及策略辅助工具和信封辅助工具的兼容性 barrel | - | `plugin-sdk/channel-inbound-debounce` | 窄传入防抖辅助工具 | - | `plugin-sdk/channel-mention-gating` | 窄提及策略、提及标记和提及文本辅助工具,不包含更宽泛的传入运行时表面 | - | `plugin-sdk/channel-envelope` | 窄传入信封格式化辅助工具 | + | `plugin-sdk/direct-dm` | 共享直接私信认证/guard 辅助工具 | + | `plugin-sdk/discord` | 面向已发布 `@openclaw/discord@2026.3.13` 和已跟踪所有者兼容性的已废弃 Discord 兼容性 facade;新插件应使用通用渠道 SDK 子路径 | + | `plugin-sdk/telegram-account` | 面向已跟踪所有者兼容性的已废弃 Telegram 账户解析兼容性 facade;新插件应使用注入的运行时辅助工具或通用渠道 SDK 子路径 | + | `plugin-sdk/interactive-runtime` | 语义消息呈现、投递和旧版交互式回复辅助工具。见 [消息呈现](/zh-CN/plugins/message-presentation) | + | `plugin-sdk/channel-inbound` | 入站防抖、提及匹配、提及策略辅助工具和信封辅助工具的兼容性 barrel | + | `plugin-sdk/channel-inbound-debounce` | 窄入站防抖辅助工具 | + | `plugin-sdk/channel-mention-gating` | 不包含更宽入站运行时表面的窄提及策略、提及标记和提及文本辅助工具 | + | `plugin-sdk/channel-envelope` | 窄入站信封格式化辅助工具 | | `plugin-sdk/channel-location` | 渠道位置上下文和格式化辅助工具 | - | `plugin-sdk/channel-logging` | 用于传入丢弃和正在输入/确认失败的渠道日志辅助工具 | + | `plugin-sdk/channel-logging` | 面向入站丢弃和 typing/ack 失败的渠道日志辅助工具 | | `plugin-sdk/channel-send-result` | 回复结果类型 | - | `plugin-sdk/channel-actions` | 渠道消息操作辅助工具,以及为插件兼容性保留的已弃用原生 schema 辅助工具 | - | `plugin-sdk/channel-route` | 共享路由规范化、解析器驱动的目标解析、线程 ID 字符串化、去重/紧凑路由键、已解析目标类型,以及路由/目标比较辅助工具 | + | `plugin-sdk/channel-actions` | 渠道消息操作辅助工具,以及为插件兼容性保留的已废弃原生 schema 辅助工具 | + | `plugin-sdk/channel-route` | 共享路由规范化、解析器驱动的目标解析、线程 ID 字符串化、去重/压缩路由键、已解析目标类型,以及路由/目标比较辅助工具 | | `plugin-sdk/channel-targets` | 目标解析辅助工具;路由比较调用方应使用 `plugin-sdk/channel-route` | | `plugin-sdk/channel-contract` | 渠道契约类型 | - | `plugin-sdk/channel-feedback` | 反馈/反应接线 | - | `plugin-sdk/channel-secret-runtime` | 窄 secret 契约辅助工具,例如 `collectSimpleChannelFieldAssignments`、`getChannelSurface`、`pushAssignment` 和 secret 目标类型 | + | `plugin-sdk/channel-feedback` | 反馈/reaction wiring | + | `plugin-sdk/channel-secret-runtime` | 窄 secret 契约辅助工具,例如 `collectSimpleChannelFieldAssignments`, `getChannelSurface`, `pushAssignment` 和 secret 目标类型 | - | 子路径 | 主要导出 | + | 子路径 | 关键导出 | | --- | --- | | `plugin-sdk/provider-entry` | `defineSingleProviderPluginEntry` | - | `plugin-sdk/lmstudio` | 支持的 LM Studio 提供商外观,用于设置、目录发现和运行时模型准备 | - | `plugin-sdk/lmstudio-runtime` | 支持的 LM Studio 运行时外观,用于本地服务器默认值、模型发现、请求标头和已加载模型辅助工具 | + | `plugin-sdk/lmstudio` | 用于设置、目录发现和运行时模型准备的受支持 LM Studio 提供商门面 | + | `plugin-sdk/lmstudio-runtime` | 用于本地服务器默认值、模型发现、请求标头和已加载模型辅助工具的受支持 LM Studio 运行时门面 | | `plugin-sdk/provider-setup` | 精选的本地/自托管提供商设置辅助工具 | - | `plugin-sdk/self-hosted-provider-setup` | 聚焦于 OpenAI 兼容自托管提供商的设置辅助工具 | - | `plugin-sdk/cli-backend` | CLI 后端默认值 + 看门狗常量 | - | `plugin-sdk/provider-auth-runtime` | 面向提供商插件的运行时 API 密钥解析辅助工具 | - | `plugin-sdk/provider-auth-api-key` | API 密钥新手引导/资料写入辅助工具,例如 `upsertApiKeyProfile` | - | `plugin-sdk/provider-auth-result` | 标准 OAuth 身份验证结果构建器 | - | `plugin-sdk/provider-auth-login` | 面向提供商插件的共享交互式登录辅助工具 | - | `plugin-sdk/provider-env-vars` | 提供商身份验证环境变量查找辅助工具 | + | `plugin-sdk/self-hosted-provider-setup` | 专注于 OpenAI 兼容自托管提供商的设置辅助工具 | + | `plugin-sdk/cli-backend` | CLI 后端默认值 + watchdog 常量 | + | `plugin-sdk/provider-auth-runtime` | 提供商插件的运行时 API 密钥解析辅助工具 | + | `plugin-sdk/provider-auth-api-key` | API 密钥新手引导/配置文件写入辅助工具,例如 `upsertApiKeyProfile` | + | `plugin-sdk/provider-auth-result` | 标准 OAuth 凭证结果构建器 | + | `plugin-sdk/provider-auth-login` | 提供商插件的共享交互式登录辅助工具 | + | `plugin-sdk/provider-env-vars` | 提供商凭证环境变量查找辅助工具 | | `plugin-sdk/provider-auth` | `createProviderApiKeyAuthMethod`, `ensureApiKeyFromOptionEnvOrPrompt`, `upsertAuthProfile`, `upsertApiKeyProfile`, `writeOAuthCredentials` | - | `plugin-sdk/provider-model-shared` | `ProviderReplayFamily`, `buildProviderReplayFamilyHooks`, `normalizeModelCompat`、共享重放策略构建器、提供商端点辅助工具,以及模型 ID 规范化辅助工具,例如 `normalizeNativeXaiModelId` | + | `plugin-sdk/provider-model-shared` | `ProviderReplayFamily`, `buildProviderReplayFamilyHooks`, `normalizeModelCompat`, 共享重放策略构建器、提供商端点辅助工具,以及模型 ID 规范化辅助工具,例如 `normalizeNativeXaiModelId` | | `plugin-sdk/provider-catalog-runtime` | 提供商目录增强运行时钩子,以及用于契约测试的插件提供商注册表接缝 | | `plugin-sdk/provider-catalog-shared` | `findCatalogTemplate`, `buildSingleProviderApiKeyCatalog`, `buildManifestModelProviderConfig`, `supportsNativeStreamingUsageCompat`, `applyProviderNativeStreamingUsageCompat` | | `plugin-sdk/provider-http` | 通用提供商 HTTP/端点能力辅助工具、提供商 HTTP 错误,以及音频转录 multipart 表单辅助工具 | - | `plugin-sdk/provider-web-fetch-contract` | 窄范围 Web-fetch 配置/选择契约辅助工具,例如 `enablePluginInConfig` 和 `WebFetchProviderPlugin` | - | `plugin-sdk/provider-web-fetch` | Web-fetch 提供商注册/缓存辅助工具 | + | `plugin-sdk/provider-web-fetch-contract` | 窄范围 Web fetch 配置/选择契约辅助工具,例如 `enablePluginInConfig` 和 `WebFetchProviderPlugin` | + | `plugin-sdk/provider-web-fetch` | Web fetch 提供商注册/缓存辅助工具 | | `plugin-sdk/provider-web-search-config-contract` | 面向不需要插件启用接线的提供商的窄范围 Web 搜索配置/凭证辅助工具 | - | `plugin-sdk/provider-web-search-contract` | 窄范围 Web 搜索配置/凭证契约辅助工具,例如 `createWebSearchProviderContractFields`, `enablePluginInConfig`, `resolveProviderWebSearchPluginConfig`,以及带作用域的凭证 setter/getter | + | `plugin-sdk/provider-web-search-contract` | 窄范围 Web 搜索配置/凭证契约辅助工具,例如 `createWebSearchProviderContractFields`, `enablePluginInConfig`, `resolveProviderWebSearchPluginConfig`,以及作用域凭证 setter/getter | | `plugin-sdk/provider-web-search` | Web 搜索提供商注册/缓存/运行时辅助工具 | | `plugin-sdk/provider-tools` | `ProviderToolCompatFamily`, `buildProviderToolCompatFamilyHooks`, Gemini schema 清理 + 诊断,以及 xAI 兼容性辅助工具,例如 `resolveXaiModelCompatPatch` / `applyXaiModelCompat` | - | `plugin-sdk/provider-usage` | `fetchClaudeUsage` 及类似工具 | - | `plugin-sdk/provider-stream` | `ProviderStreamFamily`, `buildProviderStreamFamilyHooks`, `composeProviderStreamWrappers`、流包装器类型,以及共享的 Anthropic/Bedrock/DeepSeek V4/Google/Kilocode/Moonshot/OpenAI/OpenRouter/Z.A.I/MiniMax/Copilot 包装器辅助工具 | - | `plugin-sdk/provider-transport-runtime` | 原生提供商传输辅助工具,例如受保护的 fetch、传输消息转换和可写传输事件流 | + | `plugin-sdk/provider-usage` | `fetchClaudeUsage` 和类似工具 | + | `plugin-sdk/provider-stream` | `ProviderStreamFamily`, `buildProviderStreamFamilyHooks`, `composeProviderStreamWrappers`, 流包装器类型,以及共享的 Anthropic/Bedrock/DeepSeek V4/Google/Kilocode/Moonshot/OpenAI/OpenRouter/Z.A.I/MiniMax/Copilot 包装器辅助工具 | + | `plugin-sdk/provider-transport-runtime` | 原生提供商传输辅助工具,例如受保护的 fetch、传输消息转换,以及可写传输事件流 | | `plugin-sdk/provider-onboard` | 新手引导配置补丁辅助工具 | - | `plugin-sdk/global-singleton` | 进程本地单例/map/cache 辅助工具 | + | `plugin-sdk/global-singleton` | 进程本地 singleton/map/cache 辅助工具 | | `plugin-sdk/group-activation` | 窄范围群组激活模式和命令解析辅助工具 | - - | 子路径 | 主要导出 | + + | 子路径 | 关键导出 | | --- | --- | - | `plugin-sdk/command-auth` | `resolveControlCommandGate`、命令注册表辅助工具(包括动态参数菜单格式化)、发送者授权辅助工具 | + | `plugin-sdk/command-auth` | `resolveControlCommandGate`,命令注册表辅助工具,包括动态参数菜单格式化、发送者授权辅助工具 | | `plugin-sdk/command-status` | 命令/帮助消息构建器,例如 `buildCommandsMessagePaginated` 和 `buildHelpMessage` | - | `plugin-sdk/approval-auth-runtime` | 审批者解析和同聊天操作身份验证辅助工具 | - | `plugin-sdk/approval-client-runtime` | 原生 exec 审批资料/过滤器辅助工具 | - | `plugin-sdk/approval-delivery-runtime` | 原生审批能力/投递适配器 | + | `plugin-sdk/approval-auth-runtime` | 审批者解析和同一聊天操作凭证辅助工具 | + | `plugin-sdk/approval-client-runtime` | 原生 exec 审批配置文件/过滤器辅助工具 | + | `plugin-sdk/approval-delivery-runtime` | 原生审批能力/递送适配器 | | `plugin-sdk/approval-gateway-runtime` | 共享审批 Gateway 网关解析辅助工具 | | `plugin-sdk/approval-handler-adapter-runtime` | 面向热渠道入口点的轻量级原生审批适配器加载辅助工具 | - | `plugin-sdk/approval-handler-runtime` | 更宽范围的审批处理器运行时辅助工具;当较窄的适配器/Gateway 网关接缝足够时,优先使用它们 | + | `plugin-sdk/approval-handler-runtime` | 更广泛的审批处理程序运行时辅助工具;当更窄的适配器/Gateway 网关接缝足够时,优先使用它们 | | `plugin-sdk/approval-native-runtime` | 原生审批目标 + 账号绑定辅助工具 | | `plugin-sdk/approval-reply-runtime` | Exec/插件审批回复载荷辅助工具 | | `plugin-sdk/approval-runtime` | Exec/插件审批载荷辅助工具、原生审批路由/运行时辅助工具,以及结构化审批显示辅助工具,例如 `formatApprovalDisplayPath` | | `plugin-sdk/reply-dedupe` | 窄范围入站回复去重重置辅助工具 | - | `plugin-sdk/channel-contract-testing` | 不包含宽泛测试桶的窄范围渠道契约测试辅助工具 | - | `plugin-sdk/command-auth-native` | 原生命令身份验证、动态参数菜单格式化,以及原生会话目标辅助工具 | + | `plugin-sdk/channel-contract-testing` | 不包含宽泛测试 barrel 的窄范围渠道契约测试辅助工具 | + | `plugin-sdk/command-auth-native` | 原生命令凭证、动态参数菜单格式化,以及原生会话目标辅助工具 | | `plugin-sdk/command-detection` | 共享命令检测辅助工具 | - | `plugin-sdk/command-primitives-runtime` | 面向热渠道路径的轻量级命令文本谓词 | + | `plugin-sdk/command-primitives-runtime` | 热渠道路径的轻量级命令文本谓词 | | `plugin-sdk/command-surface` | 命令正文规范化和命令表面辅助工具 | | `plugin-sdk/allow-from` | `formatAllowFromLowercase` | - | `plugin-sdk/channel-secret-runtime` | 面向渠道/插件密钥表面的窄范围密钥契约收集辅助工具 | - | `plugin-sdk/secret-ref-runtime` | 面向密钥契约/配置解析的窄范围 `coerceSecretRef` 和 SecretRef 类型辅助工具 | - | `plugin-sdk/security-runtime` | 共享信任、私信 gating、外部内容、敏感文本脱敏、常量时间密钥比较和密钥收集辅助工具 | + | `plugin-sdk/channel-secret-runtime` | 渠道/插件密钥表面的窄范围密钥契约收集辅助工具 | + | `plugin-sdk/secret-ref-runtime` | 用于密钥契约/配置解析的窄范围 `coerceSecretRef` 和 SecretRef 类型辅助工具 | + | `plugin-sdk/security-runtime` | 共享信任、私信门控、外部内容、敏感文本脱敏、常量时间密钥比较,以及密钥收集辅助工具 | | `plugin-sdk/ssrf-policy` | 主机允许列表和私有网络 SSRF 策略辅助工具 | - | `plugin-sdk/ssrf-dispatcher` | 不包含宽泛基础设施运行时表面的窄范围固定 dispatcher 辅助工具 | - | `plugin-sdk/ssrf-runtime` | 固定 dispatcher、受 SSRF 保护的 fetch、SSRF 错误和 SSRF 策略辅助工具 | + | `plugin-sdk/ssrf-dispatcher` | 不包含宽泛基础设施运行时表面的窄范围 pinned-dispatcher 辅助工具 | + | `plugin-sdk/ssrf-runtime` | Pinned-dispatcher、SSRF 保护的 fetch、SSRF 错误,以及 SSRF 策略辅助工具 | | `plugin-sdk/secret-input` | 密钥输入解析辅助工具 | | `plugin-sdk/webhook-ingress` | Webhook 请求/目标辅助工具,以及原始 websocket/body 强制转换 | | `plugin-sdk/webhook-request-guards` | 请求正文大小/超时辅助工具 | @@ -174,40 +172,40 @@ x-i18n: | 子路径 | 关键导出 | | --- | --- | - | `plugin-sdk/runtime` | 宽泛的运行时/日志/备份/插件安装辅助工具 | - | `plugin-sdk/runtime-env` | 窄范围的运行时环境、日志记录器、超时、重试和退避辅助工具 | - | `plugin-sdk/browser-config` | 支持的浏览器配置门面,用于规范化配置文件/默认值、CDP URL 解析和浏览器控制认证辅助工具 | + | `plugin-sdk/runtime` | 广泛的运行时、日志记录、备份和插件安装辅助工具 | + | `plugin-sdk/runtime-env` | 精简的运行时环境、日志记录器、超时、重试和退避辅助工具 | + | `plugin-sdk/browser-config` | 支持的浏览器配置门面,用于规范化的配置文件/默认值、CDP URL 解析以及浏览器控制身份验证辅助工具 | | `plugin-sdk/channel-runtime-context` | 通用渠道运行时上下文注册和查找辅助工具 | | `plugin-sdk/runtime-store` | `createPluginRuntimeStore` | - | `plugin-sdk/plugin-runtime` | 共享插件命令/钩子/http/交互式辅助工具 | - | `plugin-sdk/hook-runtime` | 共享 webhook/内部钩子管道辅助工具 | - | `plugin-sdk/lazy-runtime` | 惰性运行时导入/绑定辅助工具,例如 `createLazyRuntimeModule`、`createLazyRuntimeMethod` 和 `createLazyRuntimeSurface` | + | `plugin-sdk/plugin-runtime` | 共享插件命令、钩子、HTTP 和交互式辅助工具 | + | `plugin-sdk/hook-runtime` | 共享 webhook/内部钩子流水线辅助工具 | + | `plugin-sdk/lazy-runtime` | 延迟运行时导入/绑定辅助工具,例如 `createLazyRuntimeModule`、`createLazyRuntimeMethod` 和 `createLazyRuntimeSurface` | | `plugin-sdk/process-runtime` | 进程执行辅助工具 | - | `plugin-sdk/cli-runtime` | CLI 格式化、等待、版本、参数调用和惰性命令组辅助工具 | - | `plugin-sdk/gateway-runtime` | Gateway 网关客户端、Gateway 网关 CLI RPC、Gateway 网关协议错误和渠道状态补丁辅助工具 | - | `plugin-sdk/config-types` | 仅类型配置表面,用于插件配置形状,例如 `OpenClawConfig` 以及渠道/提供商配置类型 | + | `plugin-sdk/cli-runtime` | CLI 格式化、等待、版本、参数调用和延迟命令组辅助工具 | + | `plugin-sdk/gateway-runtime` | Gateway 网关客户端、Gateway 网关 CLI RPC、Gateway 网关协议错误和渠道 Status 补丁辅助工具 | + | `plugin-sdk/config-types` | 插件配置形状的仅类型配置表面,例如 `OpenClawConfig` 和渠道/提供商配置类型 | | `plugin-sdk/plugin-config-runtime` | 运行时插件配置查找辅助工具,例如 `requireRuntimeConfig`、`resolvePluginConfigObject` 和 `resolveLivePluginConfigObject` | | `plugin-sdk/config-mutation` | 事务性配置变更辅助工具,例如 `mutateConfigFile`、`replaceConfigFile` 和 `logConfigUpdated` | | `plugin-sdk/runtime-config-snapshot` | 当前进程配置快照辅助工具,例如 `getRuntimeConfig`、`getRuntimeConfigSnapshot` 和测试快照设置器 | - | `plugin-sdk/telegram-command-config` | Telegram 命令名称/描述规范化和重复/冲突检查,即使内置 Telegram 合同表面不可用也可使用 | - | `plugin-sdk/text-autolink-runtime` | 无需宽泛 text-runtime barrel 的文件引用自动链接检测 | - | `plugin-sdk/approval-runtime` | 执行/插件审批辅助工具、审批能力构建器、认证/配置文件辅助工具、原生路由/运行时辅助工具,以及结构化审批显示路径格式化 | + | `plugin-sdk/telegram-command-config` | Telegram 命令名称/描述规范化以及重复/冲突检查,即使内置 Telegram 契约表面不可用也可使用 | + | `plugin-sdk/text-autolink-runtime` | 不通过宽泛的文本运行时 barrel 进行文件引用自动链接检测 | + | `plugin-sdk/approval-runtime` | 执行/插件审批辅助工具、审批能力构建器、身份验证/配置文件辅助工具、原生路由/运行时辅助工具,以及结构化审批显示路径格式化 | | `plugin-sdk/reply-runtime` | 共享入站/回复运行时辅助工具、分块、分发、心跳、回复规划器 | - | `plugin-sdk/reply-dispatch-runtime` | 窄范围回复分发/完成和对话标签辅助工具 | + | `plugin-sdk/reply-dispatch-runtime` | 精简的回复分发/完成和会话标签辅助工具 | | `plugin-sdk/reply-history` | 共享短窗口回复历史辅助工具和标记,例如 `buildHistoryContext`、`HISTORY_CONTEXT_MARKER`、`recordPendingHistoryEntry` 和 `clearHistoryEntriesIfEnabled` | | `plugin-sdk/reply-reference` | `createReplyReferencePlanner` | - | `plugin-sdk/reply-chunking` | 窄范围文本/Markdown 分块辅助工具 | + | `plugin-sdk/reply-chunking` | 精简的文本/Markdown 分块辅助工具 | | `plugin-sdk/session-store-runtime` | 会话存储路径、会话键、更新时间和存储变更辅助工具 | | `plugin-sdk/cron-store-runtime` | Cron 存储路径/加载/保存辅助工具 | | `plugin-sdk/state-paths` | 状态/OAuth 目录路径辅助工具 | - | `plugin-sdk/routing` | 路由/会话键/账户绑定辅助工具,例如 `resolveAgentRoute`、`buildAgentSessionKey` 和 `resolveDefaultAgentBoundAccountId` | - | `plugin-sdk/status-helpers` | 共享渠道/账户状态摘要辅助工具、运行时状态默认值和问题元数据辅助工具 | + | `plugin-sdk/routing` | 路由/会话键/账号绑定辅助工具,例如 `resolveAgentRoute`、`buildAgentSessionKey` 和 `resolveDefaultAgentBoundAccountId` | + | `plugin-sdk/status-helpers` | 共享渠道/账号状态摘要辅助工具、运行时状态默认值和问题元数据辅助工具 | | `plugin-sdk/target-resolver-runtime` | 共享目标解析器辅助工具 | | `plugin-sdk/string-normalization-runtime` | Slug/字符串规范化辅助工具 | - | `plugin-sdk/request-url` | 从 fetch/request-like 输入中提取字符串 URL | - | `plugin-sdk/run-command` | 带规范化 stdout/stderr 结果的定时命令运行器 | + | `plugin-sdk/request-url` | 从类似 fetch/request 的输入中提取字符串 URL | + | `plugin-sdk/run-command` | 带计时的命令运行器,返回规范化的 stdout/stderr 结果 | | `plugin-sdk/param-readers` | 通用工具/CLI 参数读取器 | - | `plugin-sdk/tool-payload` | 从工具结果对象中提取规范化 payload | + | `plugin-sdk/tool-payload` | 从工具结果对象中提取规范化载荷 | | `plugin-sdk/tool-send` | 从工具参数中提取规范发送目标字段 | | `plugin-sdk/temp-path` | 共享临时下载路径辅助工具 | | `plugin-sdk/logging-core` | 子系统日志记录器和脱敏辅助工具 | @@ -216,114 +214,111 @@ x-i18n: | `plugin-sdk/talk-config-runtime` | Talk 提供商配置解析辅助工具 | | `plugin-sdk/json-store` | 小型 JSON 状态读/写辅助工具 | | `plugin-sdk/file-lock` | 可重入文件锁辅助工具 | - | `plugin-sdk/persistent-dedupe` | 磁盘支持的去重缓存辅助工具 | + | `plugin-sdk/persistent-dedupe` | 磁盘后备去重缓存辅助工具 | | `plugin-sdk/acp-runtime` | ACP 运行时/会话和回复分发辅助工具 | - | `plugin-sdk/acp-runtime-backend` | 用于启动时加载插件的轻量级 ACP 后端注册和回复分发辅助工具 | - | `plugin-sdk/acp-binding-resolve-runtime` | 无生命周期启动导入的只读 ACP 绑定解析 | - | `plugin-sdk/agent-config-primitives` | 窄范围智能体运行时配置 schema 原语 | + | `plugin-sdk/acp-runtime-backend` | 面向启动时加载插件的轻量级 ACP 后端注册和回复分发辅助工具 | + | `plugin-sdk/acp-binding-resolve-runtime` | 不导入生命周期启动内容的只读 ACP 绑定解析 | + | `plugin-sdk/agent-config-primitives` | 精简的智能体运行时配置架构原语 | | `plugin-sdk/boolean-param` | 宽松布尔参数读取器 | | `plugin-sdk/dangerous-name-runtime` | 危险名称匹配解析辅助工具 | - | `plugin-sdk/device-bootstrap` | 设备引导和配对令牌辅助工具 | - | `plugin-sdk/extension-shared` | 共享被动渠道、Status 和环境代理辅助原语 | + | `plugin-sdk/device-bootstrap` | 设备启动引导和配对令牌辅助工具 | + | `plugin-sdk/extension-shared` | 共享被动渠道、状态和环境代理辅助原语 | | `plugin-sdk/models-provider-runtime` | `/models` 命令/提供商回复辅助工具 | | `plugin-sdk/skill-commands-runtime` | Skill 命令列表辅助工具 | | `plugin-sdk/native-command-registry` | 原生命令注册表/构建/序列化辅助工具 | - | `plugin-sdk/agent-harness` | 用于低层智能体 harness 的实验性受信插件表面:harness 类型、活动运行引导/中止辅助工具、OpenClaw 工具桥接辅助工具、运行时计划工具策略辅助工具、终端结果分类、工具进度格式化/详情辅助工具,以及尝试结果实用工具 | + | `plugin-sdk/agent-harness` | 面向低层智能体 harness 的实验性受信任插件表面:harness 类型、活跃运行引导/中止辅助工具、OpenClaw 工具桥接辅助工具、运行时计划工具策略辅助工具、终端结果分类、工具进度格式化/详情辅助工具,以及尝试结果实用工具 | | `plugin-sdk/provider-zai-endpoint` | Z.AI 端点检测辅助工具 | | `plugin-sdk/async-lock-runtime` | 用于小型运行时状态文件的进程本地异步锁辅助工具 | | `plugin-sdk/channel-activity-runtime` | 渠道活动遥测辅助工具 | | `plugin-sdk/concurrency-runtime` | 有界异步任务并发辅助工具 | - | `plugin-sdk/dedupe-runtime` | 内存去重缓存辅助工具 | - | `plugin-sdk/delivery-queue-runtime` | 出站待处理交付清空辅助工具 | + | `plugin-sdk/dedupe-runtime` | 内存中去重缓存辅助工具 | + | `plugin-sdk/delivery-queue-runtime` | 出站待处理投递排空辅助工具 | | `plugin-sdk/file-access-runtime` | 安全本地文件和媒体源路径辅助工具 | | `plugin-sdk/heartbeat-runtime` | 心跳事件和可见性辅助工具 | | `plugin-sdk/number-runtime` | 数值强制转换辅助工具 | | `plugin-sdk/secure-random-runtime` | 安全令牌/UUID 辅助工具 | | `plugin-sdk/system-event-runtime` | 系统事件队列辅助工具 | | `plugin-sdk/transport-ready-runtime` | 传输就绪等待辅助工具 | - | `plugin-sdk/infra-runtime` | 已弃用的兼容性 shim;请使用上面的聚焦运行时子路径 | + | `plugin-sdk/infra-runtime` | 已弃用的兼容性垫片;请使用上面的聚焦运行时子路径 | | `plugin-sdk/collection-runtime` | 小型有界缓存辅助工具 | | `plugin-sdk/diagnostic-runtime` | 诊断标志、事件和跟踪上下文辅助工具 | | `plugin-sdk/error-runtime` | 错误图、格式化、共享错误分类辅助工具、`isApprovalNotFoundError` | - | `plugin-sdk/fetch-runtime` | 包装 fetch、代理和固定查找辅助工具 | - | `plugin-sdk/runtime-fetch` | 感知 dispatcher 的运行时 fetch,不导入代理/受保护 fetch | - | `plugin-sdk/response-limit-runtime` | 有界响应体读取器,无需宽泛媒体运行时表面 | - | `plugin-sdk/session-binding-runtime` | 当前对话绑定状态,无需已配置绑定路由或配对存储 | - | `plugin-sdk/session-store-runtime` | 会话存储辅助工具,无需宽泛配置写入/维护导入 | - | `plugin-sdk/context-visibility-runtime` | 上下文可见性解析和补充上下文过滤,无需宽泛配置/安全导入 | - | `plugin-sdk/string-coerce-runtime` | 窄范围原始记录/字符串强制转换和规范化辅助工具,无需 Markdown/日志导入 | + | `plugin-sdk/fetch-runtime` | 包装后的 fetch、代理和固定查找辅助工具 | + | `plugin-sdk/runtime-fetch` | 感知调度器的运行时 fetch,不导入代理/受保护 fetch | + | `plugin-sdk/response-limit-runtime` | 有界响应正文读取器,不依赖宽泛的媒体运行时表面 | + | `plugin-sdk/session-binding-runtime` | 当前会话绑定状态,不依赖已配置绑定路由或配对存储 | + | `plugin-sdk/session-store-runtime` | 会话存储辅助工具,不导入宽泛的配置写入/维护内容 | + | `plugin-sdk/context-visibility-runtime` | 上下文可见性解析和补充上下文过滤,不导入宽泛的配置/安全内容 | + | `plugin-sdk/string-coerce-runtime` | 精简的原始记录/字符串强制转换和规范化辅助工具,不导入 Markdown/日志记录内容 | | `plugin-sdk/host-runtime` | 主机名和 SCP 主机规范化辅助工具 | | `plugin-sdk/retry-runtime` | 重试配置和重试运行器辅助工具 | | `plugin-sdk/agent-runtime` | 智能体目录/身份/工作区辅助工具 | - | `plugin-sdk/directory-runtime` | 配置支持的目录查询/去重 | + | `plugin-sdk/directory-runtime` | 基于配置的目录查询/去重 | | `plugin-sdk/keyed-async-queue` | `KeyedAsyncQueue` | | 子路径 | 主要导出 | | --- | --- | - | `plugin-sdk/media-runtime` | 共享媒体获取/转换/存储辅助工具,以及媒体载荷构建器 | - | `plugin-sdk/media-store` | 精简媒体存储辅助工具,例如 `saveMediaBuffer` | - | `plugin-sdk/media-generation-runtime` | 共享媒体生成故障转移辅助工具、候选选择和缺失模型消息 | - | `plugin-sdk/media-understanding` | 媒体理解提供商类型,以及面向提供商的图像/音频辅助工具导出 | - | `plugin-sdk/text-runtime` | 共享文本/Markdown/日志辅助工具,例如去除智能体可见文本、Markdown 渲染/分块/表格辅助工具、脱敏辅助工具、指令标签辅助工具和安全文本实用工具 | - | `plugin-sdk/text-chunking` | 出站文本分块辅助工具 | - | `plugin-sdk/speech` | 语音提供商类型,以及面向提供商的指令、注册表、验证、OpenAI 兼容 TTS 构建器和语音辅助工具导出 | - | `plugin-sdk/speech-core` | 共享语音提供商类型、注册表、指令、规范化和语音辅助工具导出 | - | `plugin-sdk/realtime-transcription` | 实时转录提供商类型、注册表辅助工具和共享 WebSocket 会话辅助工具 | - | `plugin-sdk/realtime-voice` | 实时语音提供商类型和注册表辅助工具 | - | `plugin-sdk/image-generation` | 图像生成提供商类型,以及图像资产/数据 URL 辅助工具和 OpenAI 兼容图像提供商构建器 | - | `plugin-sdk/image-generation-core` | 共享图像生成类型、故障转移、认证和注册表辅助工具 | + | `plugin-sdk/media-runtime` | 共享媒体获取/转换/存储辅助函数,以及媒体载荷构建器 | + | `plugin-sdk/media-store` | 精简媒体存储辅助函数,例如 `saveMediaBuffer` | + | `plugin-sdk/media-generation-runtime` | 共享媒体生成故障转移辅助函数、候选选择和缺失模型消息 | + | `plugin-sdk/media-understanding` | 媒体理解提供商类型,以及面向提供商的图像/音频辅助导出 | + | `plugin-sdk/text-runtime` | 共享文本/Markdown/日志辅助函数,例如移除智能体可见文本、Markdown 渲染/分块/表格辅助函数、脱敏辅助函数、指令标签辅助函数和安全文本实用工具 | + | `plugin-sdk/text-chunking` | 出站文本分块辅助函数 | + | `plugin-sdk/speech` | 语音提供商类型,以及面向提供商的指令、注册表、验证、OpenAI 兼容 TTS 构建器和语音辅助导出 | + | `plugin-sdk/speech-core` | 共享语音提供商类型、注册表、指令、规范化和语音辅助导出 | + | `plugin-sdk/realtime-transcription` | 实时转写提供商类型、注册表辅助函数和共享 WebSocket 会话辅助函数 | + | `plugin-sdk/realtime-voice` | 实时语音提供商类型和注册表辅助函数 | + | `plugin-sdk/image-generation` | 图像生成提供商类型,以及图像资产/数据 URL 辅助函数和 OpenAI 兼容图像提供商构建器 | + | `plugin-sdk/image-generation-core` | 共享图像生成类型、故障转移、认证和注册表辅助函数 | | `plugin-sdk/music-generation` | 音乐生成提供商/请求/结果类型 | - | `plugin-sdk/music-generation-core` | 共享音乐生成类型、故障转移辅助工具、提供商查找和模型引用解析 | + | `plugin-sdk/music-generation-core` | 共享音乐生成类型、故障转移辅助函数、提供商查找和模型引用解析 | | `plugin-sdk/video-generation` | 视频生成提供商/请求/结果类型 | - | `plugin-sdk/video-generation-core` | 共享视频生成类型、故障转移辅助工具、提供商查找和模型引用解析 | - | `plugin-sdk/webhook-targets` | Webhook 目标注册表和路由安装辅助工具 | - | `plugin-sdk/webhook-path` | Webhook 路径规范化辅助工具 | - | `plugin-sdk/web-media` | 共享远程/本地媒体加载辅助工具 | + | `plugin-sdk/video-generation-core` | 共享视频生成类型、故障转移辅助函数、提供商查找和模型引用解析 | + | `plugin-sdk/webhook-targets` | Webhook 目标注册表和路由安装辅助函数 | + | `plugin-sdk/webhook-path` | Webhook 路径规范化辅助函数 | + | `plugin-sdk/web-media` | 共享远程/本地媒体加载辅助函数 | | `plugin-sdk/zod` | 为插件 SDK 使用者重新导出的 `zod` | - | `plugin-sdk/testing` | 面向旧版插件测试的宽泛兼容性 barrel。新的插件测试应改为导入聚焦的 SDK 子路径,例如 `plugin-sdk/agent-runtime-test-contracts`、`plugin-sdk/plugin-test-runtime`、`plugin-sdk/channel-test-helpers`、`plugin-sdk/test-env` 或 `plugin-sdk/test-fixtures` | - | `plugin-sdk/plugin-test-api` | 最小化 `createTestPluginApi` 辅助工具,用于不导入仓库测试辅助桥接的直接插件注册单元测试 | - | `plugin-sdk/agent-runtime-test-contracts` | 用于认证、投递、回退、工具钩子、提示词覆盖、schema 和转录投影测试的原生智能体运行时适配器契约夹具 | - | `plugin-sdk/channel-test-helpers` | 面向渠道的测试辅助工具,用于通用操作/设置/Status 契约、目录断言、账户启动生命周期、发送配置线程化、运行时 mock、Status 问题、出站投递和钩子注册 | - | `plugin-sdk/channel-target-testing` | 用于渠道测试的共享目标解析错误场景套件 | - | `plugin-sdk/plugin-test-contracts` | 插件包、注册、公共制品、直接导入、运行时 API 和导入副作用契约辅助工具 | - | `plugin-sdk/provider-test-contracts` | 提供商运行时、认证、设备发现、新手引导、目录、向导、媒体能力、重放策略、实时 STT 现场音频、Web 搜索/获取和流式契约辅助工具 | - | `plugin-sdk/provider-http-test-mocks` | 面向会执行 `plugin-sdk/provider-http` 的提供商测试的可选 Vitest HTTP/认证 mock | - | `plugin-sdk/test-fixtures` | 通用 CLI 运行时捕获、沙箱上下文、skill 写入器、智能体消息、系统事件、模块重载、内置插件路径、终端文本、分块、认证令牌和类型化用例夹具 | - | `plugin-sdk/test-node-mocks` | 聚焦的 Node 内置 mock 辅助工具,用于 Vitest `vi.mock("node:*")` 工厂内部 | + | `plugin-sdk/testing` | 用于旧版插件测试的宽泛兼容性桶导出。新的插件测试应改为导入聚焦的 SDK 子路径,例如 `plugin-sdk/agent-runtime-test-contracts`、`plugin-sdk/plugin-test-runtime`、`plugin-sdk/channel-test-helpers`、`plugin-sdk/test-env` 或 `plugin-sdk/test-fixtures` | + | `plugin-sdk/plugin-test-api` | 极简 `createTestPluginApi` 辅助函数,用于不导入仓库测试辅助桥接的直接插件注册单元测试 | + | `plugin-sdk/agent-runtime-test-contracts` | 原生 agent-runtime 适配器契约夹具,用于认证、投递、回退、工具钩子、提示词叠加、schema 和转录投影测试 | + | `plugin-sdk/channel-test-helpers` | 面向渠道的测试辅助函数,用于通用操作/设置/Status 契约、目录断言、账号启动生命周期、发送配置线程、运行时 mock、Status 问题、出站投递和钩子注册 | + | `plugin-sdk/channel-target-testing` | 渠道测试共享的目标解析错误场景套件 | + | `plugin-sdk/plugin-test-contracts` | 插件包、注册、公共制品、直接导入、运行时 API 和导入副作用契约辅助函数 | + | `plugin-sdk/provider-test-contracts` | 提供商运行时、认证、设备发现、新手引导、目录、向导、媒体能力、重放策略、实时 STT 实时音频、Web 搜索/获取和流契约辅助函数 | + | `plugin-sdk/provider-http-test-mocks` | 面向测试 `plugin-sdk/provider-http` 的提供商测试的可选 Vitest HTTP/认证 mock | + | `plugin-sdk/test-fixtures` | 通用 CLI 运行时捕获、沙箱上下文、Skill 写入器、智能体消息、系统事件、模块重载、内置插件路径、终端文本、分块、认证令牌和类型化用例夹具 | + | `plugin-sdk/test-node-mocks` | 用于 Vitest `vi.mock("node:*")` 工厂内部的聚焦 Node 内置 mock 辅助函数 | | 子路径 | 主要导出 | | --- | --- | - | `plugin-sdk/memory-core` | 面向管理器/配置/文件/CLI 辅助工具的内置 memory-core 辅助表面 | + | `plugin-sdk/memory-core` | 用于管理器/配置/文件/CLI 辅助函数的内置 memory-core 辅助表面 | | `plugin-sdk/memory-core-engine-runtime` | Memory 索引/搜索运行时门面 | | `plugin-sdk/memory-core-host-engine-foundation` | Memory 主机基础引擎导出 | - | `plugin-sdk/memory-core-host-engine-embeddings` | Memory 主机嵌入契约、注册表访问、本地提供商和通用批处理/远程辅助工具 | + | `plugin-sdk/memory-core-host-engine-embeddings` | Memory 主机嵌入契约、注册表访问、本地提供商和通用批处理/远程辅助函数 | | `plugin-sdk/memory-core-host-engine-qmd` | Memory 主机 QMD 引擎导出 | | `plugin-sdk/memory-core-host-engine-storage` | Memory 主机存储引擎导出 | - | `plugin-sdk/memory-core-host-multimodal` | Memory 主机多模态辅助工具 | - | `plugin-sdk/memory-core-host-query` | Memory 主机查询辅助工具 | - | `plugin-sdk/memory-core-host-secret` | Memory 主机密钥辅助工具 | - | `plugin-sdk/memory-core-host-events` | Memory 主机事件日志辅助工具 | - | `plugin-sdk/memory-core-host-status` | Memory 主机 Status 辅助工具 | - | `plugin-sdk/memory-core-host-runtime-cli` | Memory 主机 CLI 运行时辅助工具 | - | `plugin-sdk/memory-core-host-runtime-core` | Memory 主机核心运行时辅助工具 | - | `plugin-sdk/memory-core-host-runtime-files` | Memory 主机文件/运行时辅助工具 | - | `plugin-sdk/memory-host-core` | 面向 Memory 主机核心运行时辅助工具的供应商中立别名 | - | `plugin-sdk/memory-host-events` | 面向 Memory 主机事件日志辅助工具的供应商中立别名 | - | `plugin-sdk/memory-host-files` | 面向 Memory 主机文件/运行时辅助工具的供应商中立别名 | - | `plugin-sdk/memory-host-markdown` | 面向 Memory 相关插件的共享托管 Markdown 辅助工具 | - | `plugin-sdk/memory-host-search` | 面向搜索管理器访问的活动 Memory 运行时门面 | - | `plugin-sdk/memory-host-status` | 面向 Memory 主机 Status 辅助工具的供应商中立别名 | + | `plugin-sdk/memory-core-host-multimodal` | Memory 主机多模态辅助函数 | + | `plugin-sdk/memory-core-host-query` | Memory 主机查询辅助函数 | + | `plugin-sdk/memory-core-host-secret` | Memory 主机密钥辅助函数 | + | `plugin-sdk/memory-core-host-events` | Memory 主机事件日志辅助函数 | + | `plugin-sdk/memory-core-host-status` | Memory 主机 Status 辅助函数 | + | `plugin-sdk/memory-core-host-runtime-cli` | Memory 主机 CLI 运行时辅助函数 | + | `plugin-sdk/memory-core-host-runtime-core` | Memory 主机核心运行时辅助函数 | + | `plugin-sdk/memory-core-host-runtime-files` | Memory 主机文件/运行时辅助函数 | + | `plugin-sdk/memory-host-core` | memory 主机核心运行时辅助函数的供应商中立别名 | + | `plugin-sdk/memory-host-events` | memory 主机事件日志辅助函数的供应商中立别名 | + | `plugin-sdk/memory-host-files` | memory 主机文件/运行时辅助函数的供应商中立别名 | + | `plugin-sdk/memory-host-markdown` | 供 memory 相邻插件使用的共享托管 Markdown 辅助函数 | + | `plugin-sdk/memory-host-search` | 用于搜索管理器访问的活动 memory 运行时门面 | + | `plugin-sdk/memory-host-status` | memory 主机 Status 辅助函数的供应商中立别名 | - - 当前没有预留的内置辅助工具 SDK 子路径。特定所有者的 - 辅助工具位于归属插件包内,而可复用的主机契约 - 使用通用 SDK 子路径,例如 `plugin-sdk/gateway-runtime`、 - `plugin-sdk/security-runtime` 和 `plugin-sdk/plugin-config-runtime`。 + + 当前没有保留的内置辅助 SDK 子路径。所有者专属辅助函数位于所属插件包内,而可复用的主机契约使用通用 SDK 子路径,例如 `plugin-sdk/gateway-runtime`、`plugin-sdk/security-runtime` 和 `plugin-sdk/plugin-config-runtime`。 diff --git a/docs/zh-CN/plugins/voice-call.md b/docs/zh-CN/plugins/voice-call.md index 310851f70..f1a37d4af 100644 --- a/docs/zh-CN/plugins/voice-call.md +++ b/docs/zh-CN/plugins/voice-call.md @@ -2,44 +2,43 @@ read_when: - 你想从 OpenClaw 发起外拨语音通话 - 你正在配置或开发语音通话插件 - - 你需要在电话系统中使用实时语音或流式转录 + - 你需要在电话场景中使用实时语音或流式转录 sidebarTitle: Voice call -summary: 通过 Twilio、Telnyx 或 Plivo 发起外呼并接听呼入语音通话,可选支持实时语音和流式转录 +summary: 通过 Twilio、Telnyx 或 Plivo 拨打出站语音电话并接听入站语音电话,可选支持实时语音和流式转录 title: 语音通话插件 x-i18n: - generated_at: "2026-04-28T12:00:56Z" + generated_at: "2026-04-29T05:41:20Z" model: gpt-5.5 provider: openai - source_hash: c2847b22c29f224d58390993ddc2d9af499e18e7f9a652f1d5dfa3b6f110c50b + source_hash: 7976b84ce1ee6e29706e595a4a25337632b34a9bb8f7cecdee1d6f833a8ce932 source_path: plugins/voice-call.md workflow: 16 --- 通过插件为 OpenClaw 提供语音通话。支持出站通知、 -多轮对话、全双工实时语音、流式 -转写,以及带 allowlist 策略的入站呼叫。 +多轮对话、全双工实时语音、流式转写,以及带允许列表策略的入站通话。 **当前提供商:** `twilio`(Programmable Voice + Media Streams)、 `telnyx`(Call Control v2)、`plivo`(Voice API + XML transfer + GetInput -语音)、`mock`(开发/无网络)。 +speech)、`mock`(开发/无网络)。 -Voice Call 插件运行在 **Gateway 网关进程内部**。如果你使用 -远程 Gateway 网关,请在运行 Gateway 网关的机器上安装并配置该插件, +语音通话插件在 **Gateway 网关进程内部**运行。如果你使用远程 +Gateway 网关,请在运行 Gateway 网关的机器上安装并配置该插件, 然后重启 Gateway 网关以加载它。 ## 快速开始 - + - + ```bash openclaw plugins install @openclaw/voice-call ``` - + ```bash PLUGIN_SRC=./path/to/local/voice-call-plugin openclaw plugins install "$PLUGIN_SRC" @@ -48,34 +47,38 @@ Voice Call 插件运行在 **Gateway 网关进程内部**。如果你使用 - 之后重启 Gateway 网关,让插件加载。 + 如果 npm 将 OpenClaw 拥有的软件包报告为已弃用,则该软件包版本 + 来自较旧的外部软件包发布线;请使用当前打包的 OpenClaw + 构建,或在发布更新的 npm 软件包之前使用本地文件夹路径。 + + 之后重启 Gateway 网关,以便加载插件。 - + 在 `plugins.entries.voice-call.config` 下设置配置(完整结构见下方 [配置](#configuration))。至少需要: - `provider`、提供商凭证、`fromNumber`,以及一个公网可访问的 + `provider`、提供商凭据、`fromNumber`,以及一个公网可访问的 webhook URL。 - + ```bash openclaw voicecall setup ``` 默认输出适合在聊天日志和终端中阅读。它会检查 - 插件启用状态、提供商凭证、webhook 暴露情况,以及是否 - 仅启用了一个音频模式(`streaming` 或 `realtime`)。脚本请使用 + 插件是否启用、提供商凭据、webhook 暴露情况,以及是否只有一个 + 音频模式(`streaming` 或 `realtime`)处于激活状态。脚本请使用 `--json`。 - + ```bash openclaw voicecall smoke openclaw voicecall smoke --to "+15555550123" ``` - 默认两者都是 dry run。添加 `--yes` 可实际发起一次简短的 - 出站通知呼叫: + 两者默认都是空运行。添加 `--yes` 会实际发起一个简短的 + 出站通知通话: ```bash openclaw voicecall smoke --to "+15555550123" --yes @@ -85,21 +88,21 @@ Voice Call 插件运行在 **Gateway 网关进程内部**。如果你使用 -对于 Twilio、Telnyx 和 Plivo,设置必须解析为**公网 webhook URL**。 -如果 `publicUrl`、隧道 URL、Tailscale URL 或 serve 回退地址 -解析到 loopback 或私有网络空间,设置会失败,而不是 -启动一个无法接收运营商 webhook 的提供商。 +对于 Twilio、Telnyx 和 Plivo,设置必须解析为一个**公共 webhook URL**。 +如果 `publicUrl`、隧道 URL、Tailscale URL 或服务回退地址 +解析为 loopback 或私有网络空间,设置会失败,而不是启动一个 +无法接收运营商 webhook 的提供商。 ## 配置 -如果 `enabled: true` 但所选提供商缺少凭证, -Gateway 网关启动时会记录 setup-incomplete 警告,列出缺失键名,并 -跳过运行时启动。命令、RPC 调用和智能体工具在使用时仍会 +如果 `enabled: true` 但所选提供商缺少凭据, +Gateway 网关启动时会记录一条设置未完成警告,其中包含缺失的键名,并 +跳过启动运行时。命令、RPC 调用和智能体工具在使用时仍会 返回确切缺失的提供商配置。 -Voice Call 凭证接受 SecretRefs。`plugins.entries.voice-call.config.twilio.authToken` 和 `plugins.entries.voice-call.config.tts.providers.*.apiKey` 会通过标准 SecretRef 表面解析;参见 [SecretRef 凭证表面](/zh-CN/reference/secretref-credential-surface)。 +语音通话凭据接受 SecretRef。`plugins.entries.voice-call.config.twilio.authToken` 和 `plugins.entries.voice-call.config.tts.providers.*.apiKey` 会通过标准 SecretRef 表面解析;请参阅 [SecretRef 凭据表面](/zh-CN/reference/secretref-credential-surface)。 ```json5 @@ -160,28 +163,28 @@ Voice Call 凭证接受 SecretRefs。`plugins.entries.voice-call.config.twilio.a ``` - + - Twilio、Telnyx 和 Plivo 都需要一个**公网可访问**的 webhook URL。 - - `mock` 是本地开发提供商(不会发起网络调用)。 + - `mock` 是本地开发提供商(不进行网络调用)。 - Telnyx 需要 `telnyx.publicKey`(或 `TELNYX_PUBLIC_KEY`),除非 `skipSignatureVerification` 为 true。 - `skipSignatureVerification` 仅用于本地测试。 - - 在 ngrok 免费层上,将 `publicUrl` 设置为确切的 ngrok URL;签名验证始终强制执行。 - - `tunnel.allowNgrokFreeTierLoopbackBypass: true` 仅在 `tunnel.provider="ngrok"` 且 `serve.bind` 为 loopback(ngrok 本地代理)时,允许签名无效的 Twilio webhook。仅限本地开发。 - - Ngrok 免费层 URL 可能会变化或添加中间页行为;如果 `publicUrl` 发生漂移,Twilio 签名会失败。生产环境:优先使用稳定域名或 Tailscale funnel。 + - 在 ngrok 免费层上,将 `publicUrl` 设置为确切的 ngrok URL;签名验证始终会强制执行。 + - `tunnel.allowNgrokFreeTierLoopbackBypass: true` 仅在 `tunnel.provider="ngrok"` 且 `serve.bind` 为 loopback(ngrok 本地 agent)时,才允许签名无效的 Twilio webhook。仅限本地开发。 + - Ngrok 免费层 URL 可能会变化或添加插页行为;如果 `publicUrl` 漂移,Twilio 签名会失败。生产环境:优先使用稳定域名或 Tailscale funnel。 - + - `streaming.preStartTimeoutMs` 会关闭从未发送有效 `start` 帧的 socket。 - `streaming.maxPendingConnections` 限制未经认证的预启动 socket 总数。 - - `streaming.maxPendingConnectionsPerIp` 限制每个来源 IP 的未经认证预启动 socket 数量。 - - `streaming.maxConnections` 限制已打开媒体流 socket 的总数(pending + active)。 + - `streaming.maxPendingConnectionsPerIp` 限制每个来源 IP 未经认证的预启动 socket 数量。 + - `streaming.maxConnections` 限制打开的媒体流 socket 总数(待处理 + 活跃)。 - + 使用 `provider: "log"`、`twilio.from` 或旧版 - `streaming.*` OpenAI 键的较旧配置会由 `openclaw doctor --fix` - 重写。目前运行时回退仍接受旧的 voice-call 键,但 - 重写路径是 `openclaw doctor --fix`,并且兼容 shim + `streaming.*` OpenAI 键的较旧配置会由 `openclaw doctor --fix` 重写。 + 目前运行时回退仍接受旧的语音通话键,但 + 重写路径是 `openclaw doctor --fix`,兼容 shim 是临时的。 自动迁移的流式键: @@ -197,34 +200,34 @@ Voice Call 凭证接受 SecretRefs。`plugins.entries.voice-call.config.twilio.a ## 实时语音对话 -`realtime` 为实时通话音频选择全双工实时语音提供商。 -它独立于 `streaming`,后者仅将音频转发给 +`realtime` 为实时通话音频选择一个全双工实时语音提供商。 +它独立于 `streaming`,后者只会将音频转发给 实时转写提供商。 -`realtime.enabled` 不能与 `streaming.enabled` 组合使用。每次呼叫请选择一个 +`realtime.enabled` 不能与 `streaming.enabled` 组合使用。每次通话请选择一个 音频模式。 当前运行时行为: - Twilio Media Streams 支持 `realtime.enabled`。 -- `realtime.provider` 是可选的。如果未设置,Voice Call 会使用第一个已注册的实时语音提供商。 -- 内置实时语音提供商:Google Gemini Live(`google`)和 OpenAI(`openai`),由各自的提供商插件注册。 +- `realtime.provider` 是可选的。如果未设置,语音通话会使用第一个注册的实时语音提供商。 +- 内置实时语音提供商:Google Gemini Live(`google`)和 OpenAI(`openai`),由其提供商插件注册。 - 提供商拥有的原始配置位于 `realtime.providers.` 下。 -- Voice Call 默认暴露共享的 `openclaw_agent_consult` 实时工具。当来电者要求更深度推理、当前信息或普通 OpenClaw 工具时,实时模型可以调用它。 -- 如果 `realtime.provider` 指向未注册的提供商,或者根本没有注册实时语音提供商,Voice Call 会记录警告并跳过实时媒体,而不是让整个插件失败。 +- 语音通话默认暴露共享的 `openclaw_agent_consult` 实时工具。当来电者请求更深入的推理、当前信息或普通 OpenClaw 工具时,实时模型可以调用它。 +- 如果 `realtime.provider` 指向未注册的提供商,或者根本没有注册实时语音提供商,语音通话会记录警告并跳过实时媒体,而不是让整个插件失败。 - 咨询会话键会在可用时复用现有语音会话,然后回退到主叫/被叫电话号码,以便后续咨询调用在通话期间保留上下文。 ### 工具策略 `realtime.toolPolicy` 控制咨询运行: -| 策略 | 行为 | +| 策略 | 行为 | | ---------------- | ---------------------------------------------------------------------------------------------------------------------------------------- | | `safe-read-only` | 暴露咨询工具,并将常规智能体限制为 `read`、`web_search`、`web_fetch`、`x_search`、`memory_search` 和 `memory_get`。 | -| `owner` | 暴露咨询工具,并允许常规智能体使用普通智能体工具策略。 | -| `none` | 不暴露咨询工具。自定义 `realtime.tools` 仍会传递给实时提供商。 | +| `owner` | 暴露咨询工具,并让常规智能体使用普通智能体工具策略。 | +| `none` | 不暴露咨询工具。自定义 `realtime.tools` 仍会传递给实时提供商。 | ### 实时提供商示例 @@ -287,25 +290,25 @@ Voice Call 凭证接受 SecretRefs。`plugins.entries.voice-call.config.twilio.a -有关提供商特定的实时语音选项,请参见 [Google 提供商](/zh-CN/providers/google) 和 +有关提供商特定的实时语音选项,请参阅 [Google 提供商](/zh-CN/providers/google) 和 [OpenAI provider](/zh-CN/providers/openai)。 ## 流式转写 -`streaming` 为实时通话音频选择实时转写提供商。 +`streaming` 为实时通话音频选择一个实时转写提供商。 当前运行时行为: -- `streaming.provider` 是可选的。如果未设置,Voice Call 会使用第一个已注册的实时转写提供商。 -- 内置实时转写提供商:Deepgram(`deepgram`)、ElevenLabs(`elevenlabs`)、Mistral(`mistral`)、OpenAI(`openai`)和 xAI(`xai`),由各自的提供商插件注册。 +- `streaming.provider` 是可选的。如果未设置,语音通话会使用第一个注册的实时转写提供商。 +- 内置实时转写提供商:Deepgram(`deepgram`)、ElevenLabs(`elevenlabs`)、Mistral(`mistral`)、OpenAI(`openai`)和 xAI(`xai`),由其提供商插件注册。 - 提供商拥有的原始配置位于 `streaming.providers.` 下。 -- 如果 `streaming.provider` 指向未注册的提供商,或者没有注册任何提供商,Voice Call 会记录警告并跳过媒体流式传输,而不是让整个插件失败。 +- 如果 `streaming.provider` 指向未注册的提供商,或者没有注册任何提供商,语音通话会记录警告并跳过媒体流式传输,而不是让整个插件失败。 ### 流式提供商示例 - 默认值:API key `streaming.providers.openai.apiKey` 或 + 默认值:API key 为 `streaming.providers.openai.apiKey` 或 `OPENAI_API_KEY`;模型 `gpt-4o-transcribe`;`silenceDurationMs: 800`; `vadThreshold: 0.5`。 @@ -369,11 +372,9 @@ Voice Call 凭证接受 SecretRefs。`plugins.entries.voice-call.config.twilio.a -## 通话 TTS +## 通话的 TTS -Voice Call 使用核心 `messages.tts` 配置为通话提供流式 -语音。你可以在插件配置下使用**相同结构**覆盖它,它会与 -`messages.tts` 深度合并。 +Voice Call 使用核心 `messages.tts` 配置为通话提供流式语音。你可以在插件配置下用**相同结构**覆盖它,它会与 `messages.tts` 深度合并。 ```json5 { @@ -390,17 +391,16 @@ Voice Call 使用核心 `messages.tts` 配置为通话提供流式 ``` -**语音通话会忽略 Microsoft speech。** 电话音频需要 PCM; -当前 Microsoft 传输不公开电话 PCM 输出。 +**Microsoft speech 会被语音通话忽略。** 电话音频需要 PCM;当前 Microsoft 传输不公开电话 PCM 输出。 行为说明: - 插件配置中的旧版 `tts.` 键(`openai`、`elevenlabs`、`microsoft`、`edge`)会由 `openclaw doctor --fix` 修复;提交的配置应使用 `tts.providers.`。 - 启用 Twilio 媒体流式传输时会使用核心 TTS;否则通话会回退到提供商原生语音。 -- 如果 Twilio 媒体流已处于活动状态,Voice Call 不会回退到 TwiML ``。如果在该状态下电话 TTS 不可用,播放请求会失败,而不是混用两条播放路径。 +- 如果 Twilio 媒体流已处于活动状态,Voice Call 不会回退到 TwiML ``。如果该状态下电话 TTS 不可用,播放请求会失败,而不是混用两条播放路径。 - 当电话 TTS 回退到次级提供商时,Voice Call 会记录一条包含提供商链(`from`、`to`、`attempts`)的警告,便于调试。 -- 当 Twilio 插话或流拆除清空待处理 TTS 队列时,已排队的播放请求会完成结算,而不是让调用者一直等待播放完成。 +- 当 Twilio 插话或流拆除清空待处理 TTS 队列时,排队的播放请求会完成结算,而不是让呼叫者一直等待播放完成。 ### TTS 示例 @@ -467,9 +467,9 @@ Voice Call 使用核心 `messages.tts` 配置为通话提供流式 -## 入站通话 +## 呼入通话 -入站策略默认值为 `disabled`。要启用入站通话,请设置: +呼入策略默认为 `disabled`。要启用呼入通话,请设置: ```json5 { @@ -480,62 +480,52 @@ Voice Call 使用核心 `messages.tts` 配置为通话提供流式 ``` -`inboundPolicy: "allowlist"` 是低保证级别的主叫号码筛选。 -该插件会规范化提供商提供的 `From` 值,并将其与 -`allowFrom` 比较。Webhook 验证会认证提供商投递和 -载荷完整性,但它**不能**证明 PSTN/VoIP 主叫号码的 -所有权。应将 `allowFrom` 视为主叫号码过滤,而不是强主叫 -身份验证。 +`inboundPolicy: "allowlist"` 是低保证级别的来电显示筛选。该插件会规范化提供商提供的 `From` 值,并将其与 `allowFrom` 比较。Webhook 验证会认证提供商交付和载荷完整性,但它**不会**证明 PSTN/VoIP 主叫号码所有权。请将 `allowFrom` 视为来电显示过滤,而不是强主叫身份。 -自动响应使用智能体系统。可通过 `responseModel`、 -`responseSystemPrompt` 和 `responseTimeoutMs` 调整。 +自动响应使用智能体系统。可通过 `responseModel`、`responseSystemPrompt` 和 `responseTimeoutMs` 调整。 ### 语音输出契约 -对于自动响应,Voice Call 会向系统提示追加严格的语音输出契约: +对于自动响应,Voice Call 会在系统提示末尾追加严格的语音输出契约: ```text {"spoken":"..."} ``` -Voice Call 会以防御性方式提取语音文本: +Voice Call 会以防御方式提取语音文本: - 忽略标记为推理/错误内容的载荷。 - 解析直接 JSON、围栏 JSON 或内联 `"spoken"` 键。 -- 回退到纯文本,并移除疑似规划/元信息的开头段落。 +- 回退到纯文本,并移除可能的规划/元信息开头段落。 -这会让语音播放聚焦于面向调用者的文本,并避免把规划文本泄漏到音频中。 +这会让语音播放聚焦于面向呼叫者的文本,并避免将规划文本泄漏到音频中。 -### 会话启动行为 +### 对话启动行为 -对于出站 `conversation` 通话,首条消息处理与实时 -播放状态绑定: +对于出站 `conversation` 通话,首条消息处理与实时播放状态绑定: -- 仅在初始问候正在主动朗读时,才会抑制插话队列清空和自动响应。 -- 如果初始播放失败,通话会返回 `listening`,且初始消息会保留在队列中以便重试。 -- Twilio 流式传输的初始播放会在流连接时启动,没有额外延迟。 -- 插话会中止当前播放,并清空已排队但尚未开始播放的 Twilio TTS 条目。清空的条目会解析为已跳过,因此后续响应逻辑可以继续,而无需等待永远不会播放的音频。 -- 实时语音会话使用实时流自身的开场轮次。Voice Call **不会**为该初始消息发布旧版 `` TwiML 更新,因此出站 `` 会话会保持连接。 +- 仅当初始问候正在主动播放时,才会抑制插话队列清空和自动响应。 +- 如果初始播放失败,通话会返回 `listening`,初始消息仍会排队等待重试。 +- Twilio 流式传输的初始播放会在流连接时启动,无需额外延迟。 +- 插话会中止活动播放,并清空已排队但尚未播放的 Twilio TTS 条目。被清空的条目会解析为已跳过,因此后续响应逻辑可以继续,而不必等待永远不会播放的音频。 +- 实时语音对话使用实时流自身的开场轮次。Voice Call **不会**为该初始消息发布旧版 `` TwiML 更新,因此出站 `` 会话会保持附着。 ### Twilio 流断开宽限期 -当 Twilio 媒体流断开连接时,Voice Call 会等待 **2000 ms** 后 -自动结束通话: +当 Twilio 媒体流断开时,Voice Call 会等待 **2000 ms** 后再自动结束通话: -- 如果流在该窗口内重新连接,则取消自动结束。 -- 如果宽限期后没有流重新注册,则结束通话,以防止活动通话卡住。 +- 如果流在该窗口内重新连接,自动结束会被取消。 +- 如果宽限期后没有流重新注册,通话会被结束,以防止活动通话卡住。 ## 过期通话清理器 -使用 `staleCallReaperSeconds` 结束从未收到终态 -webhook 的通话(例如从未完成的通知模式通话)。默认值为 -`0`(禁用)。 +使用 `staleCallReaperSeconds` 结束从未收到终止 Webhook 的通话(例如从未完成的通知模式通话)。默认值为 `0`(禁用)。 推荐范围: - **生产:** 对通知式流程使用 `120`–`300` 秒。 -- 将此值保持为**高于 `maxDurationSeconds`**,以便正常通话可以完成。良好的起点是 `maxDurationSeconds + 30–60` 秒。 +- 保持此值**高于 `maxDurationSeconds`**,以便正常通话可以完成。一个较好的起点是 `maxDurationSeconds + 30–60` 秒。 ```json5 { @@ -554,27 +544,26 @@ webhook 的通话(例如从未完成的通知模式通话)。默认值为 ## Webhook 安全 -当代理或隧道位于 Gateway 网关 前方时,该插件会重建用于签名验证的 -公开 URL。这些选项控制信任哪些转发标头: +当代理或隧道位于 Gateway 网关前面时,插件会重建用于签名验证的公共 URL。这些选项控制信任哪些转发头: - 允许列表中的转发标头主机。 + 允许列表中的转发头主机。 - 无需允许列表即可信任转发标头。 + 在没有允许列表的情况下信任转发头。 - 仅当请求远程 IP 与列表匹配时才信任转发标头。 + 仅当请求远端 IP 与列表匹配时信任转发头。 -其他保护: +额外保护: -- 已为 Twilio 和 Plivo 启用 Webhook **重放保护**。重放的有效 webhook 请求会被确认,但会跳过副作用。 -- Twilio 会话轮次会在 `` 回调中包含每轮 token,因此过期/重放的语音回调不能满足较新的待处理转录轮次。 -- 当缺少提供商所需的签名标头时,未经认证的 webhook 请求会在读取正文之前被拒绝。 -- voice-call webhook 使用共享的预认证正文配置文件(64 KB / 5 秒),并在签名验证前施加按 IP 统计的并发上限。 +- Twilio 和 Plivo 已启用 Webhook **重放保护**。重放的有效 Webhook 请求会被确认,但会跳过副作用。 +- Twilio 对话轮次在 `` 回调中包含每轮 token,因此过期/重放的语音回调无法满足更新的待处理转录轮次。 +- 当缺少提供商所需的签名头时,未经认证的 Webhook 请求会在读取正文前被拒绝。 +- voice-call Webhook 使用共享的预认证正文配置(64 KB / 5 秒),并在签名验证前应用按 IP 的进行中请求上限。 -带稳定公开主机的示例: +具有稳定公共主机的示例: ```json5 { @@ -608,16 +597,13 @@ openclaw voicecall latency # summarize turn latency from lo openclaw voicecall expose --mode funnel ``` -`latency` 会从默认 voice-call 存储路径读取 `calls.jsonl`。 -使用 `--file ` 指向不同日志,使用 `--last ` 将 -分析限制为最后 N 条记录(默认 200)。输出包含轮次延迟和 -监听等待时间的 p50/p90/p99。 +`latency` 从默认 voice-call 存储路径读取 `calls.jsonl`。使用 `--file ` 指向不同日志,并使用 `--last ` 将分析限制为最后 N 条记录(默认 200)。输出包含轮次延迟和监听等待时间的 p50/p90/p99。 -## 智能体工具 +## Agent 工具 工具名称:`voice_call`。 -| 操作 | 参数 | +| 操作 | 参数 | | --------------- | ------------------------- | | `initiate_call` | `message`, `to?`, `mode?` | | `continue_call` | `callId`, `message` | @@ -626,11 +612,11 @@ openclaw voicecall expose --mode funnel | `end_call` | `callId` | | `get_status` | `callId` | -此仓库在 `skills/voice-call/SKILL.md` 提供了匹配的 skill 文档。 +此仓库在 `skills/voice-call/SKILL.md` 提供匹配的 skill 文档。 ## Gateway 网关 RPC -| 方法 | 参数 | +| 方法 | 参数 | | -------------------- | ------------------------- | | `voicecall.initiate` | `to?`, `message`, `mode?` | | `voicecall.continue` | `callId`, `message` | @@ -639,8 +625,8 @@ openclaw voicecall expose --mode funnel | `voicecall.end` | `callId` | | `voicecall.status` | `callId` | -## 相关 +## 相关内容 -- [Talk mode](/zh-CN/nodes/talk) +- [通话模式](/zh-CN/nodes/talk) - [文本转语音](/zh-CN/tools/tts) - [语音唤醒](/zh-CN/nodes/voicewake) diff --git a/docs/zh-CN/plugins/zalouser.md b/docs/zh-CN/plugins/zalouser.md index 6ff6fd781..042dc1f72 100644 --- a/docs/zh-CN/plugins/zalouser.md +++ b/docs/zh-CN/plugins/zalouser.md @@ -1,33 +1,33 @@ --- read_when: - - 你想在 OpenClaw 中使用 Zalo Personal(非官方)支持 + - 你希望 OpenClaw 支持 Zalo Personal(非官方) - 你正在配置或开发 zalouser 插件 -summary: Zalo Personal 插件:通过原生 `zca-js` 实现二维码登录和消息收发(插件安装 + 渠道配置 + 工具) -title: Zalo Personal 插件 +summary: Zalo Personal 插件:通过原生 zca-js 进行 QR 登录 + 消息收发(插件安装 + 渠道配置 + 工具) +title: Zalo 个人插件 x-i18n: - generated_at: "2026-04-27T06:06:21Z" - model: gpt-5.4 + generated_at: "2026-04-29T05:41:29Z" + model: gpt-5.5 provider: openai - source_hash: a9fc40683980ea73cb0b547d9e327f18e100ed9b6646512d9755934d19a48b9c + source_hash: 4cbf56d81d4137706fb03b516f65b20f51a4e40ce301c2eaa7923ddc9ac0787f source_path: plugins/zalouser.md - workflow: 15 + workflow: 16 --- # Zalo Personal(插件) -通过插件为 OpenClaw 提供 Zalo Personal 支持,使用原生 `zca-js` 自动化普通 Zalo 个人账号。 +通过插件为 OpenClaw 提供 Zalo Personal 支持,使用原生 `zca-js` 自动化普通 Zalo 用户账号。 -非官方自动化可能导致账号被暂停或封禁。请自行承担使用风险。 +非官方自动化可能导致账号被暂停或封禁。使用风险自负。 ## 命名 -渠道 id 为 `zalouser`,以明确表示这是在自动化一个**个人 Zalo 用户账号**(非官方)。我们保留 `zalo`,用于未来可能推出的官方 Zalo API 集成。 +渠道 ID 是 `zalouser`,以明确表示它自动化的是**个人 Zalo 用户账号**(非官方)。我们保留 `zalo`,用于未来可能的官方 Zalo API 集成。 ## 运行位置 -该插件运行在 **Gateway 网关进程内部**。 +此插件运行在 **Gateway 网关进程内部**。 如果你使用远程 Gateway 网关,请在**运行 Gateway 网关的机器**上安装/配置它,然后重启 Gateway 网关。 @@ -41,6 +41,8 @@ x-i18n: openclaw plugins install @openclaw/zalouser ``` +如果 npm 报告 OpenClaw 拥有的软件包已弃用,则该软件包版本来自较旧的外部软件包链;请使用当前打包的 OpenClaw 构建,或在发布更新的 npm 软件包之前使用本地文件夹路径。 + 之后重启 Gateway 网关。 ### 选项 B:从本地文件夹安装(开发) @@ -82,9 +84,9 @@ openclaw directory peers list --channel zalouser --query "name" 工具名称:`zalouser` -动作:`send`、`image`、`link`、`friends`、`groups`、`me`、`status` +操作:`send`、`image`、`link`、`friends`、`groups`、`me`、`status` -渠道消息动作还支持 `react`,用于消息反应。 +渠道消息操作也支持用于消息回应的 `react`。 ## 相关内容 diff --git a/docs/zh-CN/tools/exec-approvals-advanced.md b/docs/zh-CN/tools/exec-approvals-advanced.md index 955781ed0..90805aaae 100644 --- a/docs/zh-CN/tools/exec-approvals-advanced.md +++ b/docs/zh-CN/tools/exec-approvals-advanced.md @@ -1,27 +1,27 @@ --- read_when: - - 配置 safe bins 或自定义 safe-bin 配置文件 + - 配置安全 bin 或自定义 safe-bin 配置文件 - 将审批转发到 Slack/Discord/Telegram 或其他聊天渠道 - 为渠道实现原生审批客户端 summary: 高级 exec 审批:安全二进制文件、解释器绑定、审批转发、原生交付 title: 执行审批 — 高级 x-i18n: - generated_at: "2026-04-29T00:30:47Z" + generated_at: "2026-04-29T05:41:43Z" model: gpt-5.5 provider: openai - source_hash: ad31e606eb8d0a5d99c59a53feee82212ee7d4fad7346c183315d6257a41cf43 + source_hash: de8a72ca1d23e55dc198ae3c5ad55a57660c2111feebfb89f08d8fa9584e4337 source_path: tools/exec-approvals-advanced.md workflow: 16 --- -高级 exec 批准主题:`safeBins` 快速路径、解释器/运行时绑定,以及将批准转发到聊天渠道(包括原生投递)。关于核心策略和批准流程,请参阅 [Exec 批准](/zh-CN/tools/exec-approvals)。 +高级 exec 审批主题:`safeBins` 快速路径、解释器/运行时绑定,以及向聊天渠道转发审批(包括原生投递)。关于核心策略和审批流程,请参见 [Exec 审批](/zh-CN/tools/exec-approvals)。 ## 安全二进制文件(仅 stdin) -`tools.exec.safeBins` 定义了一小组**仅 stdin** 的二进制文件(例如 `cut`),它们可以在允许列表模式下运行,**无需**显式允许列表条目。安全二进制文件会拒绝位置文件参数和类似路径的 token,因此它们只能处理传入流。请将其视为流过滤器的窄范围快速路径,而不是通用信任列表。 +`tools.exec.safeBins` 定义了一小组**仅 stdin** 的二进制文件(例如 `cut`),它们可以在允许列表模式下运行,而**不需要**显式允许列表条目。安全二进制文件会拒绝位置文件参数和类似路径的令牌,因此它们只能处理传入流。请把它视为面向流过滤器的狭窄快速路径,而不是通用信任列表。 -**不要**将解释器或运行时二进制文件(例如 `python3`、`node`、`ruby`、`bash`、`sh`、`zsh`)添加到 `safeBins`。如果某个命令按设计可以求值代码、执行子命令或读取文件,请优先使用显式允许列表条目,并保持批准提示启用。自定义安全二进制文件必须在 `tools.exec.safeBinProfiles.` 中定义显式配置档案。 +**不要**将解释器或运行时二进制文件(例如 `python3`、`node`、`ruby`、`bash`、`sh`、`zsh`)加入 `safeBins`。如果某个命令按设计可以求值代码、执行子命令或读取文件,请优先使用显式允许列表条目,并保持审批提示启用。自定义安全二进制文件必须在 `tools.exec.safeBinProfiles.` 中定义显式 profile。 默认安全二进制文件: @@ -32,13 +32,13 @@ x-i18n: [//]: # "SAFE_BIN_DEFAULTS:END" -`grep` 和 `sort` 不在默认列表中。如果你选择加入,请为它们的非 stdin 工作流保留显式允许列表条目。对于安全二进制文件模式下的 `grep`,请使用 `-e`/`--regexp` 提供模式;位置模式形式会被拒绝,因此文件操作数不能伪装成含糊的位置参数。 +`grep` 和 `sort` 不在默认列表中。如果你选择加入,请为它们的非 stdin 工作流保留显式允许列表条目。对于 safe-bin 模式下的 `grep`,请使用 `-e`/`--regexp` 提供模式;位置模式形式会被拒绝,因此文件操作数无法伪装成有歧义的位置参数。 ### Argv 验证和被拒绝的标志 -验证仅根据 argv 形状确定(不检查主机文件系统是否存在),这可以防止通过允许/拒绝差异产生文件存在性探测行为。面向文件的选项会被默认安全二进制文件拒绝;长选项以失败关闭方式验证(未知标志和含糊缩写会被拒绝)。 +验证仅基于 argv 形状确定(不会检查主机文件系统是否存在),这可以防止允许/拒绝差异带来的文件存在性 oracle 行为。默认安全二进制文件会拒绝面向文件的选项;长选项采用失败关闭方式验证(未知标志和有歧义的缩写都会被拒绝)。 -按安全二进制文件配置档案划分的被拒绝标志: +按 safe-bin profile 列出的被拒绝标志: [//]: # "SAFE_BIN_DENIED_FLAGS:START" @@ -49,148 +49,148 @@ x-i18n: [//]: # "SAFE_BIN_DENIED_FLAGS:END" -安全二进制文件还会强制 argv token 在执行时被视为**字面文本**(不进行 glob 展开,也不展开 `$VARS`),用于仅 stdin 的片段,因此不能用 `*` 或 `$HOME/...` 这类模式来夹带文件读取。 +安全二进制文件还会强制 argv 令牌在执行时被当作**字面文本**处理(不会进行 glob 展开,也不会展开 `$VARS`),仅限 stdin 段,因此类似 `*` 或 `$HOME/...` 的模式不能用来伪装文件读取。 -### 受信任的二进制文件目录 +### 受信任的二进制目录 -安全二进制文件必须从受信任的二进制文件目录解析(系统默认值加上可选的 `tools.exec.safeBinTrustedDirs`)。`PATH` 条目绝不会被自动信任。默认受信任目录刻意保持最小:`/bin`、`/usr/bin`。如果你的安全二进制文件可执行文件位于包管理器/用户路径中(例如 `/opt/homebrew/bin`、`/usr/local/bin`、`/opt/local/bin`、`/snap/bin`),请将它们显式添加到 `tools.exec.safeBinTrustedDirs`。 +安全二进制文件必须从受信任的二进制目录解析(系统默认目录加上可选的 `tools.exec.safeBinTrustedDirs`)。`PATH` 条目绝不会被自动信任。默认受信任目录有意保持最小化:`/bin`、`/usr/bin`。如果你的 safe-bin 可执行文件位于包管理器/用户路径中(例如 `/opt/homebrew/bin`、`/usr/local/bin`、`/opt/local/bin`、`/snap/bin`),请将它们显式加入 `tools.exec.safeBinTrustedDirs`。 ### Shell 链接、包装器和多路复用器 -当每个顶层片段都满足允许列表(包括安全二进制文件或 Skills 自动允许)时,允许 shell 链接(`&&`、`||`、`;`)。允许列表模式仍不支持重定向。命令替换(`$()` / 反引号)会在允许列表解析期间被拒绝,包括在双引号内部;如果你需要字面 `$()` 文本,请使用单引号。 +当每个顶层段都满足允许列表(包括安全二进制文件或 Skills 自动允许)时,允许 shell 链接(`&&`、`||`、`;`)。允许列表模式仍不支持重定向。命令替换(`$()` / 反引号)会在允许列表解析期间被拒绝,包括在双引号内;如果需要字面 `$()` 文本,请使用单引号。 -在 macOS 配套应用批准中,包含 shell 控制或展开语法(`&&`、`||`、`;`、`|`、`` ` ``、`$`、`<`、`>`、`(`、`)`)的原始 shell 文本会被视为允许列表未命中,除非 shell 二进制文件本身已被加入允许列表。 +在 macOS 配套应用审批中,包含 shell 控制或展开语法(`&&`、`||`、`;`、`|`、`` ` ``、`$`、`<`、`>`、`(`、`)`)的原始 shell 文本会被视为允许列表未命中,除非 shell 二进制文件本身已被加入允许列表。 -对于 shell 包装器(`bash|sh|zsh ... -c/-lc`),请求范围的环境覆盖会缩减为一小组显式允许列表(`TERM`、`LANG`、`LC_*`、`COLORTERM`、`NO_COLOR`、`FORCE_COLOR`)。 +对于 shell 包装器(`bash|sh|zsh ... -c/-lc`),请求作用域的 env 覆盖会被缩减为一个小型显式允许列表(`TERM`、`LANG`、`LC_*`、`COLORTERM`、`NO_COLOR`、`FORCE_COLOR`)。 -对于允许列表模式下的 `allow-always` 决策,已知分发包装器(`env`、`nice`、`nohup`、`stdbuf`、`timeout`)会持久化内部可执行文件路径,而不是包装器路径。Shell 多路复用器(`busybox`、`toybox`)会以相同方式对 shell applet(`sh`、`ash` 等)进行解包。如果无法安全解包包装器或多路复用器,则不会自动持久化允许列表条目。 +在允许列表模式下,对于 `allow-always` 决策,已知的调度包装器(`env`、`nice`、`nohup`、`stdbuf`、`timeout`)会持久化内部可执行文件路径,而不是包装器路径。Shell 多路复用器(`busybox`、`toybox`)会以相同方式为 shell applet(`sh`、`ash` 等)解包。如果包装器或多路复用器无法安全解包,则不会自动持久化任何允许列表条目。 -如果你将 `python3` 或 `node` 这类解释器加入允许列表,请优先设置 `tools.exec.strictInlineEval=true`,这样内联求值仍需要显式批准。在严格模式下,`allow-always` 仍可持久化良性的解释器/脚本调用,但内联求值载体不会自动持久化。 +如果你将 `python3` 或 `node` 等解释器加入允许列表,请优先设置 `tools.exec.strictInlineEval=true`,这样内联 eval 仍需要显式审批。在严格模式下,`allow-always` 仍可持久化良性的解释器/脚本调用,但内联 eval 载体不会自动持久化。 ### 安全二进制文件与允许列表 | 主题 | `tools.exec.safeBins` | 允许列表(`exec-approvals.json`) | | ---------------- | ------------------------------------------------------ | ---------------------------------------------------------------------------------- | -| 目标 | 自动允许窄范围 stdin 过滤器 | 显式信任特定可执行文件 | -| 匹配类型 | 可执行文件名称 + 安全二进制文件 argv 策略 | 已解析可执行文件路径 glob,或 PATH 调用命令的裸命令名 glob | -| 参数范围 | 受安全二进制文件配置档案和字面 token 规则限制 | 仅路径匹配;参数在其他方面由你负责 | -| 典型示例 | `head`, `tail`, `tr`, `wc` | `jq`, `python3`, `node`, `ffmpeg`, 自定义 CLI | -| 最佳用途 | 管道中的低风险文本转换 | 任何具有更广行为或副作用的工具 | +| 目标 | 自动允许狭窄的 stdin 过滤器 | 显式信任特定可执行文件 | +| 匹配类型 | 可执行文件名称 + safe-bin argv 策略 | 已解析的可执行文件路径 glob,或对 PATH 调用命令使用裸命令名 glob | +| 参数范围 | 受 safe-bin profile 和字面令牌规则限制 | 只匹配路径;其他参数由你负责 | +| 典型示例 | `head`、`tail`、`tr`、`wc` | `jq`、`python3`、`node`、`ffmpeg`、自定义 CLI | +| 最佳用途 | 管道中的低风险文本转换 | 任何具备更广行为或副作用的工具 | 配置位置: -- `safeBins` 来自配置(`tools.exec.safeBins` 或按智能体设置的 `agents.list[].tools.exec.safeBins`)。 -- `safeBinTrustedDirs` 来自配置(`tools.exec.safeBinTrustedDirs` 或按智能体设置的 `agents.list[].tools.exec.safeBinTrustedDirs`)。 -- `safeBinProfiles` 来自配置(`tools.exec.safeBinProfiles` 或按智能体设置的 `agents.list[].tools.exec.safeBinProfiles`)。按智能体设置的配置档案键会覆盖全局键。 +- `safeBins` 来自配置(`tools.exec.safeBins` 或每个智能体的 `agents.list[].tools.exec.safeBins`)。 +- `safeBinTrustedDirs` 来自配置(`tools.exec.safeBinTrustedDirs` 或每个智能体的 `agents.list[].tools.exec.safeBinTrustedDirs`)。 +- `safeBinProfiles` 来自配置(`tools.exec.safeBinProfiles` 或每个智能体的 `agents.list[].tools.exec.safeBinProfiles`)。每个智能体的 profile 键会覆盖全局键。 - 允许列表条目位于主机本地 `~/.openclaw/exec-approvals.json` 的 `agents..allowlist` 下(或通过 Control UI / `openclaw approvals allowlist ...`)。 -- 当解释器/运行时二进制文件出现在 `safeBins` 中但没有显式配置档案时,`openclaw security audit` 会用 `tools.exec.safe_bins_interpreter_unprofiled` 发出警告。 -- `openclaw doctor --fix` 可以将缺失的自定义 `safeBinProfiles.` 条目脚手架生成为 `{}`(之后请审查并收紧)。解释器/运行时二进制文件不会被自动脚手架生成。 +- 当解释器/运行时二进制文件出现在 `safeBins` 中但没有显式 profile 时,`openclaw security audit` 会用 `tools.exec.safe_bins_interpreter_unprofiled` 发出警告。 +- `openclaw doctor --fix` 可以将缺失的自定义 `safeBinProfiles.` 条目搭建为 `{}`(之后请审查并收紧)。解释器/运行时二进制文件不会被自动搭建。 -自定义配置档案示例: +自定义 profile 示例: __OC_I18N_900000__ -如果你显式将 `jq` 加入 `safeBins`,OpenClaw 仍会在安全二进制文件模式下拒绝 `env` 内建命令,因此 `jq -n env` 不能在没有显式允许列表路径或批准提示的情况下转储主机进程环境。 +如果你显式选择将 `jq` 加入 `safeBins`,OpenClaw 仍会在 safe-bin 模式下拒绝 `env` 内建命令,因此 `jq -n env` 不能在没有显式允许列表路径或审批提示的情况下转储主机进程环境。 ## 解释器/运行时命令 -由批准支持的解释器/运行时运行刻意保持保守: +由审批支持的解释器/运行时运行有意保持保守: - 始终绑定精确的 argv/cwd/env 上下文。 - 直接 shell 脚本和直接运行时文件形式会尽力绑定到一个具体的本地文件快照。 -- 仍解析到一个直接本地文件的常见包管理器包装器形式(例如 `pnpm exec`、`pnpm node`、`npm exec`、`npx`)会在绑定前解包。 -- 如果 OpenClaw 无法为解释器/运行时命令准确识别一个具体的本地文件(例如包脚本、eval 形式、运行时特定加载器链,或含糊的多文件形式),由批准支持的执行会被拒绝,而不是声称拥有它并不具备的语义覆盖。 -- 对于这些工作流,请优先使用沙箱隔离、单独的主机边界,或显式受信任的允许列表/完整工作流,由操作者接受更宽泛的运行时语义。 +- 仍可解析到一个直接本地文件的常见包管理器包装器形式(例如 `pnpm exec`、`pnpm node`、`npm exec`、`npx`)会在绑定前解包。 +- 如果 OpenClaw 无法为解释器/运行时命令准确识别一个具体的本地文件(例如包脚本、eval 形式、运行时特定加载器链,或有歧义的多文件形式),由审批支持的执行会被拒绝,而不是声称拥有它实际没有的语义覆盖。 +- 对于这些工作流,请优先使用沙箱隔离、单独的主机边界,或显式受信任的允许列表/完整工作流,由操作员接受更广泛的运行时语义。 -需要批准时,exec 工具会立即返回一个批准 id。使用该 id 关联后续系统事件(`Exec finished` / `Exec denied`)。如果超时前没有决策到达,请求会被视为批准超时,并作为拒绝原因呈现。 +需要审批时,exec 工具会立即返回一个审批 ID。使用该 ID 关联后续系统事件(`Exec finished` / `Exec denied`)。如果在超时前没有收到决策,请求会被视为审批超时,并作为拒绝原因呈现。 ### 后续投递行为 -批准的异步 exec 完成后,OpenClaw 会向同一会话发送一个后续 `agent` 轮次。 +已批准的异步 exec 完成后,OpenClaw 会向同一会话发送一个后续 `agent` 轮次。 - 如果存在有效的外部投递目标(可投递渠道加目标 `to`),后续投递会使用该渠道。 -- 在仅 webchat 或没有外部目标的内部会话流程中,后续投递会保持仅会话(`deliver: false`)。 +- 在只有 webchat 或没有外部目标的内部会话流中,后续投递保持仅会话(`deliver: false`)。 - 如果调用方显式请求严格外部投递,但没有可解析的外部渠道,请求会以 `INVALID_REQUEST` 失败。 - 如果启用了 `bestEffortDeliver` 且无法解析外部渠道,投递会降级为仅会话,而不是失败。 -## 将批准转发到聊天渠道 +## 向聊天渠道转发审批 -你可以将 exec 批准提示转发到任何聊天渠道(包括插件渠道),并用 `/approve` 批准它们。这会使用正常的出站投递管道。 +你可以将 exec 审批提示转发到任何聊天渠道(包括插件渠道),并用 `/approve` 批准它们。这会使用正常的出站投递管线。 配置: __OC_I18N_900001__ 在聊天中回复: __OC_I18N_900002__ -`/approve` 命令同时处理 exec 批准和插件批准。如果 ID 不匹配任何待处理的 exec 批准,它会自动改为检查插件批准。 +`/approve` 命令同时处理 exec 审批和插件审批。如果 ID 不匹配待处理的 exec 审批,它会自动改为检查插件审批。 -### 插件批准转发 +### 插件审批转发 -插件批准转发使用与 exec 批准相同的投递管道,但在 `approvals.plugin` 下拥有独立配置。启用或禁用其中一个不会影响另一个。 +插件审批转发使用与 exec 审批相同的投递管线,但在 `approvals.plugin` 下拥有自己的独立配置。启用或停用其中一个不会影响另一个。 __OC_I18N_900003__ -配置形状与 `approvals.exec` 相同:`enabled`、`mode`、`agentFilter`、`sessionFilter` 和 `targets` 的工作方式相同。 +配置形状与 `approvals.exec` 相同:`enabled`、`mode`、`agentFilter`、`sessionFilter` 和 `targets` 的工作方式一致。 -支持共享交互式回复的渠道会为 exec 和插件批准呈现相同的批准按钮。没有共享交互式 UI 的渠道会回退为带 `/approve` 说明的纯文本。 +支持共享交互式回复的渠道会为 exec 和插件审批渲染相同的审批按钮。没有共享交互式 UI 的渠道会回退到带有 `/approve` 说明的纯文本。 -### 任意渠道上的同聊天批准 +### 任何渠道上的同一聊天审批 -当 exec 或插件批准请求源自可投递聊天表面时,默认情况下,同一聊天现在可以用 `/approve` 批准它。除现有的 Web UI 和终端 UI 流程外,这也适用于 Slack、Matrix 和 Microsoft Teams 等渠道。 +当 exec 或插件审批请求来自可投递的聊天界面时,同一个聊天现在默认可以用 `/approve` 批准它。这适用于 Slack、Matrix 和 Microsoft Teams 等渠道,以及现有的 Web UI 和终端 UI 流。 -这个共享文本命令路径使用该会话的正常渠道认证模型。如果发起聊天已经可以发送命令并接收回复,批准请求就不再需要单独的原生投递适配器来保持待处理状态。 +此共享文本命令路径使用该对话的正常渠道鉴权模型。如果发起聊天已经可以发送命令并接收回复,审批请求不再需要单独的原生投递适配器才能保持待处理状态。 -Discord 和 Telegram 也支持同聊天 `/approve`,但即使原生批准投递已禁用,这些渠道仍会使用其已解析的批准者列表进行授权。 +Discord 和 Telegram 也支持同一聊天 `/approve`,但这些渠道即使在禁用原生审批投递时,仍会使用其解析出的审批人列表进行授权。 -对于 Telegram 和其他直接调用 Gateway 网关的原生批准客户端,此回退刻意限定为“未找到批准”失败。真实的 exec 批准拒绝/错误不会静默重试为插件批准。 +对于 Telegram 和其他直接调用 Gateway 网关的原生审批客户端,此回退有意限定在“未找到审批”的失败场景。真实的 exec 审批拒绝/错误不会静默重试为插件审批。 -### 原生批准投递 +### 原生审批投递 -某些渠道也可以充当原生批准客户端。原生客户端会在共享的同聊天 `/approve` 流程之上,添加批准者私信、源聊天扇出和渠道特定的交互式批准 UX。 +某些渠道也可以充当原生审批客户端。原生客户端会在共享的同一聊天 `/approve` 流程之上,增加审批人私信、来源聊天扇出和渠道特定的交互式审批体验。 -当原生批准卡片/按钮可用时,该原生 UI 是面向智能体的主要路径。除非工具结果说明聊天批准不可用,或手动批准是唯一剩余路径,否则智能体不应再回显重复的纯聊天 -`/approve` 命令。 +当原生审批卡片/按钮可用时,该原生 UI 是主要的面向智能体路径。除非工具结果表明聊天审批不可用,或手动审批是唯一剩余路径,否则智能体不应再回显重复的纯聊天 `/approve` 命令。 + +如果已配置原生审批客户端,但发起渠道没有活跃的原生运行时,OpenClaw 会保持本地确定性的 `/approve` 提示可见。如果原生运行时处于活跃状态并尝试投递,但没有目标收到卡片,OpenClaw 会在同一聊天中发送回退通知,包含准确的 `/approve ` 命令,以便该请求仍可被处理。 通用模型: -- 主机 exec 策略仍决定是否需要 exec 批准 -- `approvals.exec` 控制将批准提示转发到其他聊天目标 -- `channels..execApprovals` 控制该渠道是否作为原生批准客户端 +- 主机 exec 策略仍决定是否需要 exec 审批 +- `approvals.exec` 控制将审批提示转发到其他聊天目的地 +- `channels..execApprovals` 控制该渠道是否作为原生审批客户端 -当以下条件全部为真时,原生批准客户端会自动启用私信优先投递: +当以下条件全部为真时,原生审批客户端会自动启用私信优先投递: -- 该渠道支持原生批准投递 -- 可以从显式的 `execApprovals.approvers` 或所有者身份(例如 `commands.ownerAllowFrom`)解析批准者 +- 渠道支持原生审批投递 +- 审批人可以从显式的 `execApprovals.approvers` 或所有者身份(例如 `commands.ownerAllowFrom`)解析出来 - `channels..execApprovals.enabled` 未设置或为 `"auto"` -设置 `enabled: false` 可显式禁用原生批准客户端。设置 `enabled: true` 可在批准者可解析时强制启用它。公开的原始聊天投递仍通过 -`channels..execApprovals.target` 显式配置。 +设置 `enabled: false` 可显式禁用原生审批客户端。设置 `enabled: true` 可在审批人可解析时强制启用它。公共来源聊天投递仍通过 `channels..execApprovals.target` 显式配置。 -常见问题:[为什么聊天批准有两个 exec 批准配置?](/help/faq-first-run#why-are-there-two-exec-approval-configs-for-chat-approvals) +常见问题:[为什么聊天审批有两套 exec 审批配置?](/help/faq-first-run#why-are-there-two-exec-approval-configs-for-chat-approvals) - Discord:`channels.discord.execApprovals.*` - Slack:`channels.slack.execApprovals.*` - Telegram:`channels.telegram.execApprovals.*` -这些原生批准客户端在共享的同一聊天 `/approve` 流程和共享批准按钮之上,添加了私信路由和可选的渠道扇出。 +这些原生审批客户端在共享的同一聊天 `/approve` 流程和共享审批按钮之上,增加了私信路由和可选渠道扇出。 共享行为: -- Slack、Matrix、Microsoft Teams 以及类似的可投递聊天,会对同一聊天 `/approve` 使用普通渠道认证模型 -- 当原生批准客户端自动启用时,默认的原生投递目标是批准者私信 -- 对于 Discord 和 Telegram,只有已解析的批准者可以批准或拒绝 -- Discord 批准者可以是显式的(`execApprovals.approvers`),也可以从 `commands.ownerAllowFrom` 推断 -- Telegram 批准者可以是显式的(`execApprovals.approvers`),也可以从 `commands.ownerAllowFrom` 推断 -- Slack 批准者可以是显式的(`execApprovals.approvers`),也可以从 `commands.ownerAllowFrom` 推断 -- Slack 原生按钮会保留批准 ID 类型,因此 `plugin:` ID 可以解析插件批准,而无需第二层 Slack 本地回退 -- Matrix 原生私信/渠道路由和回应快捷方式同时处理 exec 和插件批准;插件授权仍来自 `channels.matrix.dm.allowFrom` -- Matrix 原生提示会在第一个提示事件中包含 `com.openclaw.approval` 自定义事件内容,因此支持 OpenClaw 的 Matrix 客户端可以读取结构化批准状态,而普通客户端仍保留纯文本 `/approve` 回退 -- 请求者不需要是批准者 -- 当发起聊天已经支持命令和回复时,可以直接用 `/approve` 批准 -- 原生 Discord 批准按钮会按批准 ID 类型路由:`plugin:` ID 直接进入插件批准,其他所有内容进入 exec 批准 -- 原生 Telegram 批准按钮遵循与 `/approve` 相同的有界 exec 到插件回退 -- 当原生 `target` 启用原始聊天投递时,批准提示会包含命令文本 -- 待处理的 exec 批准默认会在 30 分钟后过期 -- 如果没有任何操作员 UI 或已配置的批准客户端可以接收请求,提示会回退到 `askFallback` +- Slack、Matrix、Microsoft Teams 以及类似的可投递聊天使用常规渠道认证模型来处理同一聊天中的 `/approve` +- 当原生审批客户端自动启用时,默认原生投递目标是审批人私信 +- 对于 Discord 和 Telegram,只有已解析的审批人可以批准或拒绝 +- Discord 审批人可以显式配置(`execApprovals.approvers`),也可以从 `commands.ownerAllowFrom` 推断 +- Telegram 审批人可以显式配置(`execApprovals.approvers`),也可以从 `commands.ownerAllowFrom` 推断 +- Slack 审批人可以显式配置(`execApprovals.approvers`),也可以从 `commands.ownerAllowFrom` 推断 +- Slack 原生按钮会保留审批 id 类型,因此 `plugin:` id 可以解析为插件审批,而无需第二层 Slack 本地回退 +- Matrix 原生私信/渠道路由和回应快捷操作同时处理 exec 和插件审批;插件授权仍来自 `channels.matrix.dm.allowFrom` +- Matrix 原生提示会在第一个提示事件中包含 `com.openclaw.approval` 自定义事件内容,使支持 OpenClaw 的 Matrix 客户端可以读取结构化审批状态,而标准客户端仍保留纯文本 `/approve` 回退 +- 请求者不需要是审批人 +- 当发起聊天已支持命令和回复时,可以直接用 `/approve` 审批 +- 原生 Discord 审批按钮按审批 id 类型路由:`plugin:` id 会直接进入插件审批,其他所有 id 进入 exec 审批 +- 原生 Telegram 审批按钮遵循与 `/approve` 相同的有界 exec 到插件回退 +- 当原生 `target` 启用来源聊天投递时,审批提示会包含命令文本 +- 默认情况下,待处理的 exec 审批会在 30 分钟后过期 +- 如果没有操作员 UI 或已配置的审批客户端能够接受请求,提示会回退到 `askFallback` -敏感的仅限所有者的群组命令(例如 `/diagnostics` 和 `/export-trajectory`)会对批准提示和最终结果使用私有所有者路由。OpenClaw 会先尝试在所有者运行命令的同一界面上使用私有路由。如果该界面没有私有所有者路由,则回退到 `commands.ownerAllowFrom` 中第一个可用的所有者路由,因此当 Telegram 是已配置的主要私有界面时,Discord 群组命令仍可将批准和结果发送到所有者的 Telegram 私信。群聊只会收到一条简短确认。 +敏感的仅限所有者的群组命令(例如 `/diagnostics` 和 `/export-trajectory`)会使用私有所有者路由发送审批提示和最终结果。OpenClaw 会先尝试在所有者运行命令的同一表面上使用私有路由。如果该表面没有私有所有者路由,则会回退到 `commands.ownerAllowFrom` 中第一个可用的所有者路由,因此当 Telegram 是已配置的主要私有界面时,Discord 群组命令仍可以将审批和结果发送到所有者的 Telegram 私信。群组聊天只会收到一条简短确认。 -Telegram 默认使用批准者私信(`target: "dm"`)。当你希望批准提示也显示在发起的 Telegram 聊天/话题中时,可以切换到 `channel` 或 `both`。对于 Telegram 论坛话题,OpenClaw 会为批准提示和批准后的后续消息保留该话题。 +Telegram 默认使用审批人私信(`target: "dm"`)。当你希望审批提示也出现在发起的 Telegram 聊天/话题中时,可以切换到 `channel` 或 `both`。对于 Telegram 论坛话题,OpenClaw 会为审批提示和审批后跟进保留该话题。 参见: @@ -201,13 +201,13 @@ Telegram 默认使用批准者私信(`target: "dm"`)。当你希望批准提 __OC_I18N_900004__ 安全说明: -- Unix 套接字模式 `0600`,令牌存储在 `exec-approvals.json` 中。 -- 同一 UID 对端检查。 -- 质询/响应(nonce + HMAC 令牌 + 请求哈希)+ 短 TTL。 +- Unix socket 模式 `0600`,令牌存储在 `exec-approvals.json` 中。 +- 同 UID 对等端检查。 +- 挑战/响应(nonce + HMAC 令牌 + 请求哈希)+ 短 TTL。 -## 相关内容 +## 相关 -- [Exec 批准](/zh-CN/tools/exec-approvals) — 核心策略和批准流程 +- [Exec 审批](/zh-CN/tools/exec-approvals) — 核心策略和审批流程 - [Exec 工具](/zh-CN/tools/exec) - [提权模式](/zh-CN/tools/elevated) -- [Skills](/zh-CN/tools/skills) — 由 Skills 支持的自动允许行为 +- [Skills](/zh-CN/tools/skills) — 基于 skill 的自动允许行为 diff --git a/docs/zh-CN/tools/plugin.md b/docs/zh-CN/tools/plugin.md index 721346737..591d86084 100644 --- a/docs/zh-CN/tools/plugin.md +++ b/docs/zh-CN/tools/plugin.md @@ -7,24 +7,20 @@ sidebarTitle: Install and Configure summary: 安装、配置和管理 OpenClaw 插件 title: 插件 x-i18n: - generated_at: "2026-04-28T23:40:12Z" + generated_at: "2026-04-29T05:42:07Z" model: gpt-5.5 provider: openai - source_hash: ec4b58de5ec69566ce15536dfc0cf1e08b329293cb84da7aa8436763c017668f + source_hash: 7a12d158053c13b47a56d8d6b382818962e9b5109fdf8ededd3ecf92b83089e6 source_path: tools/plugin.md workflow: 16 --- -插件为 OpenClaw 扩展新能力:渠道、模型提供商、 -Agent harness plugins、工具、Skills、语音、实时转录、实时 -语音、媒体理解、图像生成、视频生成、Web 获取、Web -搜索等。部分插件是 **核心**(随 OpenClaw 提供),其他 -是 **外部**(由社区发布到 npm)。 +插件通过新功能扩展 OpenClaw:渠道、模型提供商、智能体运行框架、工具、Skills、语音、实时转写、实时语音、媒体理解、图像生成、视频生成、网页获取、网页搜索等。有些插件是 **核心** 插件(随 OpenClaw 一起提供),其他则是 **外部** 插件。大多数外部插件通过 [ClawHub](/zh-CN/tools/clawhub) 发布和发现。Npm 仍支持直接安装,也会临时支持一组 OpenClaw 拥有的插件包,直到迁移完成。 ## 快速开始 - + ```bash openclaw plugins list ``` @@ -33,7 +29,7 @@ Agent harness plugins、工具、Skills、语音、实时转录、实时 ```bash # From npm - openclaw plugins install @openclaw/voice-call + openclaw plugins install npm:@acme/openclaw-plugin # From a local directory or archive openclaw plugins install ./my-plugin @@ -52,48 +48,37 @@ Agent harness plugins、工具、Skills、语音、实时转录、实时 -如果你更偏好聊天原生控制,请启用 `commands.plugins: true` 并使用: +如果你更喜欢聊天原生控制,请启用 `commands.plugins: true` 并使用: ```text -/plugin install clawhub:@openclaw/voice-call -/plugin show voice-call -/plugin enable voice-call +/plugin install clawhub: +/plugin show +/plugin enable ``` 安装路径使用与 CLI 相同的解析器:本地路径/归档、显式 -`clawhub:`、显式 `npm:`,或裸包规范(先 ClawHub,然后 -回退到 npm)。 +`clawhub:`、显式 `npm:`,或裸包规范(先 ClawHub,后 +npm 回退)。 -如果配置无效,安装通常会故障关闭,并提示你运行 -`openclaw doctor --fix`。唯一的恢复例外是一条很窄的内置插件 -重装路径,适用于选择加入 +如果配置无效,安装通常会以失败关闭方式停止,并指引你运行 +`openclaw doctor --fix`。唯一的恢复例外是一条狭窄的内置插件重装路径,适用于选择加入 `openclaw.install.allowInvalidConfigRecovery` 的插件。 -Gateway 网关启动期间,某个插件的无效配置会隔离在该插件范围内: -启动日志会记录 `plugins.entries..config` 问题,在加载期间跳过该插件, +在 Gateway 网关启动期间,某个插件的无效配置会被隔离到该插件: +启动会记录 `plugins.entries..config` 问题,加载时跳过该插件, 并保持其他插件和渠道在线。运行 `openclaw doctor --fix` -可通过禁用该插件条目并移除其无效配置载荷来隔离有问题的插件配置; -正常配置备份会保留先前的值。 -当渠道配置引用了一个不再可发现的插件,但同一个陈旧插件 ID 仍保留在插件配置或安装记录中时, -Gateway 网关启动会记录警告并跳过该渠道,而不是阻塞所有其他渠道。 -运行 `openclaw doctor --fix` 可移除陈旧的渠道/插件条目;没有陈旧插件证据的未知 -渠道键仍会验证失败,以便拼写错误保持可见。 -如果设置了 `plugins.enabled: false`,陈旧插件引用会被视为非活动: -Gateway 网关启动会跳过插件发现/加载工作,`openclaw doctor` 会保留 -已禁用的插件配置,而不是自动移除它。若要移除陈旧插件 ID,请先重新启用插件再运行 -doctor 清理。 +可通过禁用该插件条目并移除其无效配置负载来隔离错误插件配置;正常的配置备份会保留之前的值。 +当渠道配置引用了一个不再可发现的插件,但同一个过期插件 id 仍保留在插件配置或安装记录中时,Gateway 网关启动会记录警告并跳过该渠道,而不是阻塞其他所有渠道。 +运行 `openclaw doctor --fix` 可移除过期的渠道/插件条目;没有过期插件证据的未知渠道键仍会验证失败,以便拼写错误保持可见。 +如果设置了 `plugins.enabled: false`,过期插件引用会被视为惰性: +Gateway 网关启动会跳过插件发现/加载工作,而 `openclaw doctor` 会保留已禁用的插件配置,而不是自动移除它。如果你想移除过期插件 id,请先重新启用插件再运行 Doctor 清理。 -打包的 OpenClaw 安装不会急切安装每个内置插件的 -运行时依赖树。当一个 OpenClaw 拥有的内置插件因 -插件配置、旧版渠道配置或默认启用的清单而处于活动状态时,启动只会 -在导入该插件前修复该插件声明的运行时依赖。 -仅持久化的渠道认证状态不会为 Gateway 网关启动运行时依赖修复 -激活内置渠道。 +打包的 OpenClaw 安装不会急切安装每个内置插件的运行时依赖树。 +当某个 OpenClaw 拥有的内置插件因插件配置、旧版渠道配置或默认启用的清单而处于活动状态时,启动只会在导入该插件前修复该插件声明的运行时依赖。 +仅持久化的渠道认证状态不会为 Gateway 网关启动运行时依赖修复激活内置渠道。 显式禁用仍然优先:`plugins.entries..enabled: false`、 `plugins.deny`、`plugins.enabled: false` 和 `channels..enabled: false` 会阻止该插件/渠道的自动内置运行时依赖修复。 -非空的 `plugins.allow` 也会限制默认启用的内置运行时依赖 -修复;显式启用内置渠道(`channels..enabled: true`)仍然可以 -修复该渠道的插件依赖。 +非空的 `plugins.allow` 也会限制默认启用的内置运行时依赖修复;显式启用内置渠道(`channels..enabled: true`)仍可修复该渠道的插件依赖。 外部插件和自定义加载路径仍必须通过 `openclaw plugins install` 安装。 @@ -101,12 +86,12 @@ doctor 清理。 OpenClaw 识别两种插件格式: -| 格式 | 工作方式 | 示例 | +| 格式 | 工作方式 | 示例 | | ---------- | ------------------------------------------------------------------ | ------------------------------------------------------ | -| **原生** | `openclaw.plugin.json` + 运行时模块;在进程内执行 | 官方插件、社区 npm 包 | -| **Bundle** | Codex/Claude/Cursor 兼容布局;映射到 OpenClaw 功能 | `.codex-plugin/`、`.claude-plugin/`、`.cursor-plugin/` | +| **原生** | `openclaw.plugin.json` + 运行时模块;在进程内执行 | 官方插件、社区 npm 包 | +| **包** | 兼容 Codex/Claude/Cursor 的布局;映射到 OpenClaw 功能 | `.codex-plugin/`、`.claude-plugin/`、`.cursor-plugin/` | -两者都会出现在 `openclaw plugins list` 下。参见 [插件 Bundle](/zh-CN/plugins/bundles) 了解 Bundle 详情。 +两者都会显示在 `openclaw plugins list` 下。参见 [插件包](/zh-CN/plugins/bundles) 了解包详情。 如果你正在编写原生插件,请从 [构建插件](/zh-CN/plugins/building-plugins) 和 [插件 SDK 概览](/zh-CN/plugins/sdk-overview) 开始。 @@ -114,14 +99,9 @@ OpenClaw 识别两种插件格式: ## 包入口点 原生插件 npm 包必须在 `package.json` 中声明 `openclaw.extensions`。 -每个条目都必须位于包目录内,并解析为可读的 -运行时文件,或解析为一个 TypeScript 源文件,并带有推断出的已构建 JavaScript -对等文件,例如从 `src/index.ts` 到 `dist/index.js`。 +每个条目都必须保持在包目录内,并解析到可读的运行时文件,或解析到带有推断生成的 JavaScript 对等文件的 TypeScript 源文件,例如从 `src/index.ts` 到 `dist/index.js`。 -当发布的运行时文件不在与源条目相同的路径时,请使用 -`openclaw.runtimeExtensions`。如果存在,`runtimeExtensions` 必须为 -每个 `extensions` 条目包含且仅包含一个条目。列表不匹配会导致安装和 -插件发现失败,而不是静默回退到源路径。 +当发布的运行时文件与源条目不在相同路径时,请使用 `openclaw.runtimeExtensions`。存在时,`runtimeExtensions` 必须为每个 `extensions` 条目包含恰好一个条目。列表不匹配会导致安装和插件发现失败,而不是静默回退到源路径。 ```json { @@ -135,18 +115,29 @@ OpenClaw 识别两种插件格式: ## 官方插件 -### 可安装(npm) +### 迁移期间 OpenClaw 拥有的 npm 包 -| 插件 | 包 | 文档 | -| --------------- | ---------------------- | ------------------------------------ | -| Matrix | `@openclaw/matrix` | [Matrix](/zh-CN/channels/matrix) | -| Microsoft Teams | `@openclaw/msteams` | [Microsoft Teams](/zh-CN/channels/msteams) | -| Nostr | `@openclaw/nostr` | [Nostr](/zh-CN/channels/nostr) | -| Voice Call | `@openclaw/voice-call` | [Voice Call](/zh-CN/plugins/voice-call) | -| Zalo | `@openclaw/zalo` | [Zalo](/zh-CN/channels/zalo) | -| Zalo Personal | `@openclaw/zalouser` | [Zalo Personal](/zh-CN/plugins/zalouser) | +ClawHub 是大多数插件的主要分发路径。当前打包的 OpenClaw 版本已经内置许多官方插件,因此在常规设置中这些插件不需要单独的 npm 安装。在每个 OpenClaw 拥有的插件都迁移到 ClawHub 之前,OpenClaw 仍会在 npm 上发布一些 `@openclaw/*` 插件包,以支持较旧/自定义安装和直接 npm 工作流。 -### 核心(随 OpenClaw 提供) +如果 npm 报告某个 `@openclaw/*` 插件包已弃用,则该包版本来自较旧的外部包线。请使用当前 OpenClaw 中的内置插件或本地检出,直到发布更新的 npm 包。 + +| 插件 | 包 | 文档 | +| --------------- | -------------------------- | ------------------------------------------ | +| BlueBubbles | `@openclaw/bluebubbles` | [BlueBubbles](/zh-CN/channels/bluebubbles) | +| Discord | `@openclaw/discord` | [Discord](/zh-CN/channels/discord) | +| Feishu | `@openclaw/feishu` | [Feishu](/zh-CN/channels/feishu) | +| Matrix | `@openclaw/matrix` | [Matrix](/zh-CN/channels/matrix) | +| Mattermost | `@openclaw/mattermost` | [Mattermost](/zh-CN/channels/mattermost) | +| Microsoft Teams | `@openclaw/msteams` | [Microsoft Teams](/zh-CN/channels/msteams) | +| Nextcloud Talk | `@openclaw/nextcloud-talk` | [Nextcloud Talk](/zh-CN/channels/nextcloud-talk) | +| Nostr | `@openclaw/nostr` | [Nostr](/zh-CN/channels/nostr) | +| Synology Chat | `@openclaw/synology-chat` | [Synology Chat](/zh-CN/channels/synology-chat) | +| Tlon | `@openclaw/tlon` | [Tlon](/zh-CN/channels/tlon) | +| WhatsApp | `@openclaw/whatsapp` | [WhatsApp](/zh-CN/channels/whatsapp) | +| Zalo | `@openclaw/zalo` | [Zalo](/zh-CN/channels/zalo) | +| Zalo Personal | `@openclaw/zalouser` | [Zalo Personal](/zh-CN/plugins/zalouser) | + +### 核心(随 OpenClaw 一起提供) @@ -157,11 +148,11 @@ OpenClaw 识别两种插件格式: `vercel-ai-gateway`, `volcengine`, `xiaomi`, `zai` - - - `memory-core` — 内置内存搜索(默认通过 `plugins.slots.memory`) - - `memory-lancedb` — 按需安装的长期内存,支持自动召回/捕获(设置 `plugins.slots.memory = "memory-lancedb"`) + + - `memory-core` — 内置记忆搜索(默认通过 `plugins.slots.memory`) + - `memory-lancedb` — 按需安装的长期记忆,支持自动召回/捕获(设置 `plugins.slots.memory = "memory-lancedb"`) - 参见 [Memory LanceDB](/zh-CN/plugins/memory-lancedb) 了解 OpenAI 兼容的 + 参见 [Memory LanceDB](/zh-CN/plugins/memory-lancedb) 了解兼容 OpenAI 的 嵌入设置、Ollama 示例、召回限制和故障排除。 @@ -171,13 +162,13 @@ OpenClaw 识别两种插件格式: - - `browser` — 内置浏览器插件,用于浏览器工具、`openclaw browser` CLI、`browser.request` gateway 方法、浏览器运行时,以及默认浏览器控制服务(默认启用;替换前请先禁用) + - `browser` — 用于浏览器工具、`openclaw browser` CLI、`browser.request` Gateway 网关方法、浏览器运行时和默认浏览器控制服务的内置浏览器插件(默认启用;替换前请禁用它) - `copilot-proxy` — VS Code Copilot Proxy 桥接(默认禁用) -在寻找第三方插件?参见 [社区插件](/zh-CN/plugins/community)。 +在找第三方插件?参见 [社区插件](/zh-CN/plugins/community)。 ## 配置 @@ -195,45 +186,36 @@ OpenClaw 识别两种插件格式: } ``` -| 字段 | 说明 | +| 字段 | 描述 | | ---------------- | --------------------------------------------------------- | -| `enabled` | 主开关(默认:`true`) | -| `allow` | 插件允许列表(可选) | -| `deny` | 插件拒绝列表(可选;拒绝优先) | -| `load.paths` | 额外插件文件/目录 | -| `slots` | 独占槽位选择器(例如 `memory`、`contextEngine`) | -| `entries.\` | 单个插件的开关 + 配置 | +| `enabled` | 主开关(默认:`true`) | +| `allow` | 插件允许列表(可选) | +| `deny` | 插件拒绝列表(可选;拒绝优先) | +| `load.paths` | 额外的插件文件/目录 | +| `slots` | 独占槽选择器(例如 `memory`、`contextEngine`) | +| `entries.\` | 每个插件的开关 + 配置 | -配置更改**需要重启 Gateway 网关**。如果 Gateway 网关运行时启用了配置 -监听 + 进程内重启(默认的 `openclaw gateway` 路径),该 -重启通常会在配置写入落地片刻后自动执行。 -原生插件运行时代码或生命周期 -钩子没有受支持的热重载路径;在期待更新后的 `register(api)` 代码、`api.on(...)` 钩子、工具、服务或 -提供商/运行时钩子运行之前,请重启正在服务实时渠道的 Gateway 网关进程。 +配置更改**需要重启 Gateway 网关**。如果 Gateway 网关在启用配置监视 + 进程内重启的情况下运行(默认 `openclaw gateway` 路径),通常会在配置写入落地后片刻自动执行该重启。 +原生插件运行时代码或生命周期钩子没有受支持的热重载路径;在期望更新后的 `register(api)` 代码、`api.on(...)` 钩子、工具、服务或提供商/运行时钩子运行之前,请重启正在服务实时渠道的 Gateway 网关进程。 -`openclaw plugins list` 是本地插件注册表/配置快照。其中的 -`enabled` 插件表示持久化注册表和当前配置允许该 -插件参与。它并不能证明一个已经运行的远程 Gateway 网关 -子进程已经重启到同一份插件代码。在带有 -包装进程的 VPS/容器设置中,请将重启发送到实际的 `openclaw gateway run` 进程, -或针对正在运行的 Gateway 网关使用 `openclaw gateway restart`。 +`openclaw plugins list` 是本地插件注册表/配置快照。那里的 +`enabled` 插件表示持久化注册表和当前配置允许该插件参与。它并不能证明已经运行的远程 Gateway 网关子进程已重启到相同的插件代码。在带有包装进程的 VPS/容器设置中,请将重启发送到实际的 `openclaw gateway run` 进程,或对正在运行的 Gateway 网关使用 `openclaw gateway restart`。 - - **已禁用**:插件存在,但启用规则将其关闭。配置会保留。 - - **缺失**:配置引用了发现流程没有找到的插件 ID。 - - **无效**:插件存在,但其配置与声明的 schema 不匹配。Gateway 网关启动只会跳过该插件;`openclaw doctor --fix` 可通过禁用无效条目并移除其配置载荷来隔离它。 + - **已禁用**:插件存在,但启用规则将其关闭。配置会被保留。 + - **缺失**:配置引用了发现过程未找到的插件 id。 + - **无效**:插件存在,但其配置与声明的架构不匹配。Gateway 网关启动只会跳过该插件;`openclaw doctor --fix` 可通过禁用该条目并移除其配置负载来隔离无效条目。 ## 发现和优先级 -OpenClaw 按以下顺序扫描插件(第一个匹配项胜出): +OpenClaw 按此顺序扫描插件(第一个匹配项获胜): - `plugins.load.paths` — 显式文件或目录路径。指回 - OpenClaw 自身打包内置插件目录的路径会被忽略; - 运行 `openclaw doctor --fix` 可移除这些陈旧别名。 + `plugins.load.paths` — 显式文件或目录路径。指回 OpenClaw 自己打包的内置插件目录的路径会被忽略; + 运行 `openclaw doctor --fix` 可移除这些过期别名。 @@ -245,20 +227,12 @@ OpenClaw 按以下顺序扫描插件(第一个匹配项胜出): - 随 OpenClaw 提供。许多默认启用(模型提供商、语音)。 - 其他则需要显式启用。 + 随 OpenClaw 一起发布。许多插件默认启用(模型提供商、语音)。 + 其他插件需要显式启用。 -打包安装和 Docker 镜像通常会从已编译的 -`dist/extensions` 树解析内置插件。如果内置插件源目录 -被绑定挂载到匹配的打包源路径上,例如 -`/app/extensions/synology-chat`,OpenClaw 会将该挂载的源目录 -视为内置源覆盖层,并在打包的 -`/app/dist/extensions/synology-chat` Bundle 之前发现它。这让维护者容器 -循环能够继续工作,而无需把每个内置插件都切回 TypeScript 源。 -设置 `OPENCLAW_DISABLE_BUNDLED_SOURCE_OVERLAYS=1` 可强制使用打包的 dist Bundle, -即使存在源覆盖挂载也是如此。 +打包安装和 Docker 镜像通常会从编译后的 `dist/extensions` 树解析内置插件。如果内置插件源目录被 bind-mounted 到匹配的打包源路径上,例如 `/app/extensions/synology-chat`,OpenClaw 会将该挂载的源目录视为内置源覆盖层,并优先于打包的 `/app/dist/extensions/synology-chat` bundle 发现它。这样维护者的容器循环可以继续工作,而无需把每个内置插件都切回 TypeScript 源码。设置 `OPENCLAW_DISABLE_BUNDLED_SOURCE_OVERLAYS=1` 可强制使用打包的 dist bundle,即使存在源覆盖层挂载也是如此。 ### 启用规则 @@ -266,38 +240,23 @@ OpenClaw 按以下顺序扫描插件(第一个匹配项胜出): - `plugins.deny` 始终优先于 allow - `plugins.entries.\.enabled: false` 会禁用该插件 - 工作区来源的插件**默认禁用**(必须显式启用) -- 内置插件遵循内置的默认启用集合,除非被覆盖 -- 独占槽位可以强制启用该槽位选中的插件 -- 当配置命名某个插件拥有的表面时,一些内置的可选启用插件会自动启用, - 例如提供商模型引用、渠道配置或 harness 运行时 -- 当 `plugins.enabled: false` 处于活动状态时,过期插件配置会被保留; - 如果你想移除过期 id,请先重新启用插件再运行 Doctor 清理 -- OpenAI 系列 Codex 路由保持独立的插件边界: - `openai-codex/*` 属于 OpenAI 插件,而内置 Codex - app-server 插件由 `agentRuntime.id: "codex"` 或旧版 - `codex/*` 模型引用选择 +- 内置插件会遵循内建的默认启用集合,除非被覆盖 +- 独占 slot 可以强制启用为该 slot 选择的插件 +- 当配置命名了插件拥有的表面时,一些内置的选择加入插件会自动启用,例如提供商模型引用、渠道配置或 harness 运行时 +- 当 `plugins.enabled: false` 处于活动状态时,过期插件配置会被保留;如果想移除过期 id,请先重新启用插件再运行 doctor 清理 +- OpenAI 系列 Codex 路由保持独立的插件边界:`openai-codex/*` 属于 OpenAI 插件,而内置 Codex app-server 插件由 `agentRuntime.id: "codex"` 或旧版 `codex/*` 模型引用选择 ## 运行时钩子故障排除 -如果某个插件出现在 `plugins list` 中,但 `register(api)` 副作用或钩子 -没有在实时聊天流量中运行,请先检查这些内容: +如果某个插件出现在 `plugins list` 中,但 `register(api)` 的副作用或钩子没有在实时聊天流量中运行,请先检查以下内容: -- 运行 `openclaw gateway status --deep --require-rpc`,并确认活动的 - Gateway 网关 URL、profile、配置路径和进程就是你正在编辑的那些。 -- 在插件安装/配置/代码变更后重启实时 Gateway 网关。在 wrapper - 容器中,PID 1 可能只是 supervisor;请重启或向子 - `openclaw gateway run` 进程发送信号。 -- 使用 `openclaw plugins inspect --json` 确认钩子注册和 - diagnostics。非内置会话钩子,例如 `llm_input`、 - `llm_output`、`before_agent_finalize` 和 `agent_end`,需要 - `plugins.entries..hooks.allowConversationAccess=true`。 -- 对于模型切换,优先使用 `before_model_resolve`。它会在智能体轮次的模型 - 解析前运行;`llm_output` 只会在模型尝试产生 assistant 输出后运行。 -- 如需证明有效会话模型,请使用 `openclaw sessions` 或 - Gateway 网关会话/Status 表面;调试提供商 payload 时,请用 - `--raw-stream --raw-stream-path ` 启动 Gateway 网关。 +- 运行 `openclaw gateway status --deep --require-rpc`,并确认活动 Gateway 网关 URL、profile、配置路径和进程都是你正在编辑的那些。 +- 在插件安装/配置/代码更改后重启实时 Gateway 网关。在 wrapper 容器中,PID 1 可能只是 supervisor;请重启或向子 `openclaw gateway run` 进程发送信号。 +- 使用 `openclaw plugins inspect --json` 确认钩子注册和诊断信息。非内置 conversation 钩子(如 `llm_input`、`llm_output`、`before_agent_finalize` 和 `agent_end`)需要 `plugins.entries..hooks.allowConversationAccess=true`。 +- 对于模型切换,优先使用 `before_model_resolve`。它会在智能体 turn 的模型解析前运行;`llm_output` 只会在一次模型尝试产生 assistant 输出后运行。 +- 若要证明有效会话模型,请使用 `openclaw sessions` 或 Gateway 网关会话/Status 表面;调试提供商 payload 时,请使用 `--raw-stream --raw-stream-path ` 启动 Gateway 网关。 -### 渠道或工具归属重复 +### 重复的渠道或工具所有权 症状: @@ -305,28 +264,22 @@ OpenClaw 按以下顺序扫描插件(第一个匹配项胜出): - `channel setup already registered: ()` - `plugin tool name conflict (): ` -这些表示多个已启用插件正在尝试拥有同一个渠道、设置流程或工具名称。 -最常见的原因是,一个外部渠道插件安装在了现在提供相同渠道 id 的内置插件旁边。 +这些表示不止一个已启用插件正在尝试拥有同一个渠道、设置流程或工具名称。最常见的原因是外部渠道插件安装在现在提供相同渠道 id 的内置插件旁边。 调试步骤: -- 运行 `openclaw plugins list --enabled --verbose`,查看每个已启用插件 - 及其来源。 -- 对每个疑似插件运行 `openclaw plugins inspect --json`,并比较 - `channels`、`channelConfigs`、`tools` 和 diagnostics。 -- 安装或移除插件包后,运行 `openclaw plugins registry --refresh`, - 让持久化 metadata 反映当前安装状态。 -- 在安装、registry 或配置变更后重启 Gateway 网关。 +- 运行 `openclaw plugins list --enabled --verbose` 查看每个已启用插件及其来源。 +- 对每个可疑插件运行 `openclaw plugins inspect --json`,并比较 `channels`、`channelConfigs`、`tools` 和诊断信息。 +- 安装或移除插件包后,运行 `openclaw plugins registry --refresh`,让持久化元数据反映当前安装。 +- 在安装、registry 或配置更改后重启 Gateway 网关。 修复选项: -- 如果一个插件有意替换另一个使用相同渠道 id 的插件,首选插件应声明 - `channelConfigs..preferOver`,并填入优先级较低的插件 id。参见 [/plugins/manifest#replacing-another-channel-plugin](/zh-CN/plugins/manifest#replacing-another-channel-plugin)。 -- 如果重复是意外造成的,请用 - `plugins.entries..enabled: false` 禁用其中一方,或移除过期的插件安装。 -- 如果你显式启用了两个插件,OpenClaw 会保留该请求并报告冲突。请为该渠道选择一个所有者,或重命名插件拥有的工具,使运行时表面不存在歧义。 +- 如果某个插件有意替换另一个具有相同渠道 id 的插件,首选插件应声明 `channelConfigs..preferOver`,并填入优先级较低的插件 id。请参阅 [/plugins/manifest#replacing-another-channel-plugin](/zh-CN/plugins/manifest#replacing-another-channel-plugin)。 +- 如果重复是意外的,请使用 `plugins.entries..enabled: false` 禁用其中一侧,或移除过期插件安装。 +- 如果你显式启用了两个插件,OpenClaw 会保留该请求并报告冲突。请为该渠道选择一个所有者,或重命名插件拥有的工具,使运行时表面没有歧义。 -## 插件槽位(独占类别) +## 插件 slot(独占类别) 某些类别是独占的(同一时间只能有一个处于活动状态): @@ -341,10 +294,10 @@ OpenClaw 按以下顺序扫描插件(第一个匹配项胜出): } ``` -| 槽位 | 控制内容 | 默认值 | +| Slot | 控制内容 | 默认值 | | --------------- | --------------------- | ------------------- | | `memory` | 活动 memory 插件 | `memory-core` | -| `contextEngine` | 活动 context engine | `legacy`(内置) | +| `contextEngine` | 活动 context engine | `legacy`(内建) | ## CLI 参考 @@ -384,68 +337,33 @@ openclaw plugins enable openclaw plugins disable ``` -内置插件随 OpenClaw 一起发布。许多插件默认启用(例如内置模型提供商、 -内置语音提供商和内置浏览器插件)。其他内置插件仍需要 -`openclaw plugins enable `。 +内置插件随 OpenClaw 一起发布。许多默认启用(例如内置模型提供商、内置语音提供商和内置 browser 插件)。其他内置插件仍需要 `openclaw plugins enable `。 -`--force` 会原地覆盖已安装的插件或 hook pack。对于已跟踪 npm -插件的常规升级,请使用 `openclaw plugins update `。 -它不支持与 `--link` 一起使用,后者会复用源路径,而不是复制到托管安装目标上。 +`--force` 会原地覆盖现有已安装插件或 hook pack。对于已跟踪 npm 插件的常规升级,请使用 `openclaw plugins update `。它不支持与 `--link` 一起使用,因为 `--link` 会复用源路径,而不是复制到受管理的安装目标上。 -当 `plugins.allow` 已设置时,`openclaw plugins install` 会在启用已安装插件之前, -把该插件 id 添加到该 allowlist。如果同一个插件 id 存在于 `plugins.deny` 中, -install 会移除该过期 deny 条目,使显式安装在重启后可以立即加载。 +当 `plugins.allow` 已设置时,`openclaw plugins install` 会先将已安装插件 id 添加到该 allowlist,然后启用它。如果同一个插件 id 出现在 `plugins.deny` 中,install 会移除该过期 deny 条目,使显式安装在重启后立即可加载。 -OpenClaw 会保留一个持久化的本地插件 registry,作为插件清单、contribution -归属和启动规划的冷读取模型。Install、update、uninstall、enable 和 disable -流程会在更改插件状态后刷新该 registry。同一个 `plugins/installs.json` 文件会在 -顶层 `installRecords` 中保留持久安装 metadata,并在 `plugins` 中保留可重建的 manifest -metadata。如果 registry 缺失、过期或无效,`openclaw plugins registry ---refresh` 会从安装记录、配置策略和 manifest/package metadata 重建其 manifest 视图, -而不会加载插件运行时模块。 -`openclaw plugins update ` 适用于已跟踪安装。传入带 dist-tag -或精确版本的 npm 包 spec,会把包名解析回已跟踪的插件记录,并记录新的 spec -供未来更新使用。传入不带版本的包名,会把精确固定的安装移回 registry -的默认发布线。如果已安装的 npm 插件已经匹配解析出的版本和记录的 artifact identity, -OpenClaw 会跳过更新,而不会下载、重新安装或重写配置。 +OpenClaw 会保留一个持久化的本地插件 registry,作为插件清单、贡献所有权和启动规划的冷读模型。安装、更新、卸载、启用和禁用流程会在更改插件状态后刷新该 registry。同一个 `plugins/installs.json` 文件在顶层 `installRecords` 中保存持久安装元数据,并在 `plugins` 中保存可重建的 manifest 元数据。如果 registry 缺失、过期或无效,`openclaw plugins registry --refresh` 会从安装记录、配置策略和 manifest/package 元数据重建其 manifest 视图,而无需加载插件运行时模块。`openclaw plugins update ` 适用于已跟踪安装。传入带有 dist-tag 或精确版本的 npm 包 spec 会将包名解析回已跟踪的插件记录,并记录新的 spec 以供后续更新。传入不带版本的包名会把精确 pin 的安装移回 registry 的默认发布线。如果已安装的 npm 插件已经匹配解析出的版本和已记录的 artifact identity,OpenClaw 会跳过更新,不下载、不重新安装,也不重写配置。 -`--pin` 仅适用于 npm。它不支持与 `--marketplace` 一起使用,因为 -marketplace 安装会持久化 marketplace source metadata,而不是 npm spec。 +`--pin` 仅适用于 npm。它不支持与 `--marketplace` 一起使用,因为 marketplace 安装会持久化 marketplace 源元数据,而不是 npm spec。 -`--dangerously-force-unsafe-install` 是针对内置危险代码扫描器误报的应急覆盖。 -它允许插件安装和插件更新在内置 `critical` findings 后继续,但仍不会绕过插件 -`before_install` 策略阻断或扫描失败阻断。安装扫描会忽略常见测试文件和目录, -例如 `tests/`、`__tests__/`、`*.test.*` 和 `*.spec.*`,以避免阻断打包的测试 mock; -声明的插件运行时入口点即使使用这些名称之一,仍会被扫描。 +`--dangerously-force-unsafe-install` 是用于处理内建危险代码扫描器误报的 break-glass 覆盖。它允许插件安装和插件更新在内建 `critical` findings 之后继续,但仍不会绕过插件 `before_install` 策略拦截或扫描失败拦截。安装扫描会忽略常见测试文件和目录,例如 `tests/`、`__tests__/`、`*.test.*` 和 `*.spec.*`,以避免阻塞打包测试 mock;已声明的插件运行时入口点即使使用这些名称之一,仍会被扫描。 -此 CLI 标志仅适用于插件 install/update 流程。由 Gateway 网关支持的 skill -依赖安装使用匹配的 `dangerouslyForceUnsafeInstall` 请求覆盖,而 -`openclaw skills install` 仍是独立的 ClawHub skill download/install 流程。 +该 CLI 标志仅适用于插件安装/更新流程。Gateway 网关支持的 skill 依赖安装改用匹配的 `dangerouslyForceUnsafeInstall` 请求覆盖,而 `openclaw skills install` 仍是独立的 ClawHub skill 下载/安装流程。 -如果你发布在 ClawHub 上的插件因扫描被隐藏或阻断,请打开 -ClawHub dashboard,或运行 `clawhub package rescan ` 请求 ClawHub 重新检查。 -`--dangerously-force-unsafe-install` 只影响你自己机器上的安装;它不会请求 ClawHub -重新扫描插件,也不会让被阻断的 release 公开。 +如果你在 ClawHub 上发布的插件被扫描隐藏或阻止,请打开 ClawHub dashboard 或运行 `clawhub package rescan `,请求 ClawHub 重新检查它。`--dangerously-force-unsafe-install` 只影响你自己机器上的安装;它不会请求 ClawHub 重新扫描插件,也不会让被阻止的 release 公开。 -兼容 bundle 参与同一个插件 list/inspect/enable/disable 流程。当前运行时支持包括 -bundle skills、Claude command-skills、Claude `settings.json` 默认值、Claude -`.lsp.json` 和 manifest 声明的 `lspServers` 默认值、Cursor command-skills -以及兼容的 Codex hook 目录。 +兼容 bundle 会参与同一个插件 list/inspect/enable/disable 流程。当前运行时支持包括 bundle skills、Claude command-skills、Claude `settings.json` 默认值、Claude `.lsp.json` 和 manifest 声明的 `lspServers` 默认值、Cursor command-skills,以及兼容的 Codex hook 目录。 -`openclaw plugins inspect ` 还会报告检测到的 bundle capabilities,以及 -bundle 支持的插件中受支持或不受支持的 MCP 和 LSP server 条目。 +`openclaw plugins inspect ` 还会报告检测到的 bundle 能力,以及 bundle 支持的插件中受支持或不受支持的 MCP 和 LSP server 条目。 -Marketplace sources 可以是来自 `~/.claude/plugins/known_marketplaces.json` -的 Claude known-marketplace 名称、本地 marketplace root 或 `marketplace.json` -路径、像 `owner/repo` 这样的 GitHub shorthand、GitHub repo URL,或 git URL。 -对于远程 marketplaces,插件条目必须保留在 cloned marketplace repo 内,并且只使用相对路径 sources。 +Marketplace 源可以是来自 `~/.claude/plugins/known_marketplaces.json` 的 Claude 已知 marketplace 名称、本地 marketplace root 或 `marketplace.json` 路径、类似 `owner/repo` 的 GitHub 简写、GitHub repo URL,或 git URL。对于远程 marketplace,插件条目必须保留在 cloned marketplace repo 内,并且只使用相对路径源。 -参见 [`openclaw plugins` CLI 参考](/zh-CN/cli/plugins) 了解详情。 +了解详情,请参阅 [`openclaw plugins` CLI 参考](/zh-CN/cli/plugins)。 ## 插件 API 概览 -原生插件会导出一个暴露 `register(api)` 的 entry object。较旧插件可能仍使用 -`activate(api)` 作为 legacy alias,但新插件应使用 `register`。 +原生插件会导出一个暴露 `register(api)` 的 entry object。旧插件仍可使用 `activate(api)` 作为旧版别名,但新插件应使用 `register`。 ```typescript export default definePluginEntry({ @@ -465,30 +383,28 @@ export default definePluginEntry({ }); ``` -OpenClaw 会加载 entry object,并在插件激活期间调用 `register(api)`。 -loader 仍会对旧插件回退到 `activate(api)`,但内置插件和新的外部插件应将 -`register` 视为公共契约。 +OpenClaw 会加载 entry object,并在插件激活期间调用 `register(api)`。loader 仍会为旧插件回退到 `activate(api)`,但内置插件和新的外部插件应将 `register` 视为公共契约。 -`api.registrationMode` 会告诉插件其 entry 被加载的原因: +`api.registrationMode` 会告诉插件其 entry 为什么被加载: | 模式 | 含义 | | --------------- | -------------------------------------------------------------------------------------------------------------------------------- | -| `full` | 运行时激活。注册工具、钩子、服务、命令、路由,以及其他实时副作用。 | -| `discovery` | 只读能力设备发现。注册提供商和元数据;可信插件入口代码可以加载,但跳过实时副作用。 | +| `full` | 运行时激活。注册工具、钩子、服务、命令、路由和其他实时副作用。 | +| `discovery` | 只读能力设备发现。注册提供商和元数据;受信任的插件入口代码可能会加载,但会跳过实时副作用。 | | `setup-only` | 通过轻量级设置入口加载渠道设置元数据。 | -| `setup-runtime` | 同时需要运行时入口的渠道设置加载。 | +| `setup-runtime` | 还需要运行时入口的渠道设置加载。 | | `cli-metadata` | 仅收集 CLI 命令元数据。 | -会打开套接字、数据库、后台工作进程或长生命周期 -客户端的插件入口,应使用 `api.registrationMode === "full"` -保护这些副作用。设备发现加载会与激活加载分开缓存,并且不会替换 -正在运行的 Gateway 网关注册表。设备发现是非激活的,但并非无需导入: -OpenClaw 可能会求值可信插件入口或渠道插件模块来构建 +打开套接字、数据库、后台工作线程或长生命周期 +客户端的插件入口,应使用 `api.registrationMode === "full"` 保护这些副作用。 +设备发现加载与激活加载分开缓存,并且不会替换 +正在运行的 Gateway 网关注册表。设备发现是非激活式的,但并非免导入: +OpenClaw 可能会执行受信任的插件入口或渠道插件模块来构建 快照。保持模块顶层轻量且无副作用,并将 网络客户端、子进程、监听器、凭证读取和服务启动 -放到完整运行时路径之后。 +移到完整运行时路径之后。 -常见注册方法: +常用注册方法: | 方法 | 注册内容 | | --------------------------------------- | --------------------------- | @@ -503,27 +419,27 @@ OpenClaw 可能会求值可信插件入口或渠道插件模块来构建 | `registerImageGenerationProvider` | 图像生成 | | `registerMusicGenerationProvider` | 音乐生成 | | `registerVideoGenerationProvider` | 视频生成 | -| `registerWebFetchProvider` | 网页获取 / 抓取提供商 | +| `registerWebFetchProvider` | Web 获取 / 抓取提供商 | | `registerWebSearchProvider` | Web 搜索 | | `registerHttpRoute` | HTTP 端点 | | `registerCommand` / `registerCli` | CLI 命令 | | `registerContextEngine` | 上下文引擎 | | `registerService` | 后台服务 | -类型化生命周期钩子的守卫行为: +类型化生命周期钩子的钩子保护行为: -- `before_tool_call`:`{ block: true }` 会终止流程;低优先级处理器会被跳过。 -- `before_tool_call`:`{ block: false }` 是空操作,不会清除之前的阻止。 -- `before_install`:`{ block: true }` 会终止流程;低优先级处理器会被跳过。 -- `before_install`:`{ block: false }` 是空操作,不会清除之前的阻止。 -- `message_sending`:`{ cancel: true }` 会终止流程;低优先级处理器会被跳过。 -- `message_sending`:`{ cancel: false }` 是空操作,不会清除之前的取消。 +- `before_tool_call`:`{ block: true }` 是终止性的;低优先级处理程序会被跳过。 +- `before_tool_call`:`{ block: false }` 是无操作,并且不会清除先前的阻止。 +- `before_install`:`{ block: true }` 是终止性的;低优先级处理程序会被跳过。 +- `before_install`:`{ block: false }` 是无操作,并且不会清除先前的阻止。 +- `message_sending`:`{ cancel: true }` 是终止性的;低优先级处理程序会被跳过。 +- `message_sending`:`{ cancel: false }` 是无操作,并且不会清除先前的取消。 -原生 Codex app-server 会将 Codex 原生工具事件桥接回此 +原生 Codex 应用服务器会把 Codex 原生工具事件桥接回此 钩子表面。插件可以通过 `before_tool_call` 阻止原生 Codex 工具, 通过 `after_tool_call` 观察结果,并参与 Codex -`PermissionRequest` 批准。该桥接尚不会重写 Codex 原生工具 -参数。确切的 Codex 运行时支持边界见 +`PermissionRequest` 批准。该桥接目前还不会重写 Codex 原生工具 +参数。确切的 Codex 运行时支持边界位于 [Codex harness v1 支持契约](/zh-CN/plugins/codex-harness#v1-support-contract)。 完整的类型化钩子行为见 [SDK 概览](/zh-CN/plugins/sdk-overview#hook-decision-semantics)。 @@ -531,8 +447,8 @@ OpenClaw 可能会求值可信插件入口或渠道插件模块来构建 ## 相关内容 - [构建插件](/zh-CN/plugins/building-plugins) — 创建你自己的插件 -- [插件包](/zh-CN/plugins/bundles) — Codex/Claude/Cursor bundle 兼容性 -- [插件清单](/zh-CN/plugins/manifest) — 清单 schema +- [插件包](/zh-CN/plugins/bundles) — Codex/Claude/Cursor 包兼容性 +- [插件清单](/zh-CN/plugins/manifest) — 清单架构 - [注册工具](/zh-CN/plugins/building-plugins#registering-agent-tools) — 在插件中添加智能体工具 -- [插件内部机制](/zh-CN/plugins/architecture) — 能力模型和加载管线 +- [插件内部机制](/zh-CN/plugins/architecture) — 能力模型和加载流水线 - [社区插件](/zh-CN/plugins/community) — 第三方列表