diff --git a/docs/zh-CN/channels/slack.md b/docs/zh-CN/channels/slack.md index bd7f95ac2..edbd1e6e8 100644 --- a/docs/zh-CN/channels/slack.md +++ b/docs/zh-CN/channels/slack.md @@ -1,18 +1,18 @@ --- read_when: - - 设置 Slack 或调试 Slack 套接字/HTTP 模式 -summary: Slack 设置和运行时行为(Socket 模式 + HTTP 请求 URL) + - 设置 Slack 或调试 Slack socket/HTTP 模式 +summary: Slack 设置和运行时行为(Socket Mode + HTTP 请求 URL) title: Slack x-i18n: - generated_at: "2026-05-04T07:02:43Z" + generated_at: "2026-05-05T01:21:00Z" model: gpt-5.5 provider: openai - source_hash: d4a91fc1ae5f1e03f714308be54e164ef204809e74efabed8dc75c3035c14228 + source_hash: 7334027c606ff6465190433d2159c3f9cfbcf1e8a3a1e826682423f71700a064 source_path: channels/slack.md workflow: 16 --- -通过 Slack 应用集成,已可用于生产环境中的私信和渠道。默认模式是 Socket Mode;也支持 HTTP 请求 URL。 +可通过 Slack 应用集成用于生产环境的私信和渠道。默认模式是 Socket Mode;也支持 HTTP Request URL。 @@ -22,7 +22,7 @@ x-i18n: 原生命令行为和命令目录。 - 跨渠道诊断和修复操作手册。 + 跨渠道诊断和修复手册。 @@ -32,12 +32,147 @@ x-i18n: - 在 Slack 应用设置中点击 **[创建新应用](https://api.slack.com/apps/new)** 按钮: + 打开 [api.slack.com/apps](https://api.slack.com/apps/new) → **Create New App** → **From a manifest** → 选择你的工作区 → 粘贴下方任一清单 → **Next** → **Create**。 - - 选择 **从清单创建**,并为你的应用选择一个工作区 - - 粘贴下方的 [示例清单](#manifest-and-scope-checklist),然后继续创建 - - 生成具有 `connections:write` 权限的 **应用级令牌**(`xapp-...`) - - 安装应用,并复制显示的 **Bot 令牌**(`xoxb-...`) + + +```json Recommended +{ + "display_information": { + "name": "OpenClaw", + "description": "Slack connector for OpenClaw" + }, + "features": { + "bot_user": { "display_name": "OpenClaw", "always_online": true }, + "app_home": { + "home_tab_enabled": true, + "messages_tab_enabled": true, + "messages_tab_read_only_enabled": false + }, + "slash_commands": [ + { + "command": "/openclaw", + "description": "Send a message to OpenClaw", + "should_escape": false + } + ] + }, + "oauth_config": { + "scopes": { + "bot": [ + "app_mentions:read", + "assistant:write", + "channels:history", + "channels:read", + "chat:write", + "commands", + "emoji:read", + "files:read", + "files:write", + "groups:history", + "groups:read", + "im:history", + "im:read", + "im:write", + "mpim:history", + "mpim:read", + "mpim:write", + "pins:read", + "pins:write", + "reactions:read", + "reactions:write", + "usergroups:read", + "users:read" + ] + } + }, + "settings": { + "socket_mode_enabled": true, + "event_subscriptions": { + "bot_events": [ + "app_home_opened", + "app_mention", + "channel_rename", + "member_joined_channel", + "member_left_channel", + "message.channels", + "message.groups", + "message.im", + "message.mpim", + "pin_added", + "pin_removed", + "reaction_added", + "reaction_removed" + ] + } + } +} +``` + +```json Minimal +{ + "display_information": { + "name": "OpenClaw", + "description": "Slack connector for OpenClaw" + }, + "features": { + "bot_user": { "display_name": "OpenClaw", "always_online": true }, + "app_home": { + "home_tab_enabled": true, + "messages_tab_enabled": true, + "messages_tab_read_only_enabled": false + }, + "slash_commands": [ + { + "command": "/openclaw", + "description": "Send a message to OpenClaw", + "should_escape": false + } + ] + }, + "oauth_config": { + "scopes": { + "bot": [ + "app_mentions:read", + "assistant:write", + "channels:history", + "channels:read", + "chat:write", + "commands", + "groups:history", + "groups:read", + "im:history", + "im:read", + "im:write", + "users:read" + ] + } + }, + "settings": { + "socket_mode_enabled": true, + "event_subscriptions": { + "bot_events": [ + "app_home_opened", + "app_mention", + "message.channels", + "message.groups", + "message.im" + ] + } + } +} +``` + + + + + **Recommended** 与内置 Slack 插件的完整功能集一致:App Home、斜杠命令、文件、回应、置顶、群组私信,以及 emoji/usergroup 读取。当工作区策略限制作用域时,请选择 **Minimal**:它涵盖私信、渠道/群组历史记录、提及和斜杠命令,但不包含文件、回应、置顶、群组私信(`mpim:*`)、`emoji:read` 和 `usergroups:read`。请参阅[清单和作用域检查清单](#manifest-and-scope-checklist),了解每个作用域的理由以及额外斜杠命令等增量选项。 + + + Slack 创建应用后: + + - **Basic Information → App-Level Tokens → Generate Token and Scopes**:添加 `connections:write`,保存,然后复制 `xapp-...` 值。 + - **Install App → Install to Workspace**:复制 `xoxb-...` Bot User OAuth Token。 @@ -64,7 +199,7 @@ openclaw config patch --file ./slack.socket.patch.json5 --dry-run openclaw config patch --file ./slack.socket.patch.json5 ``` - 环境变量回退(仅默认账号): + 环境变量回退(仅默认账户): ```bash SLACK_APP_TOKEN=xapp-... @@ -84,15 +219,162 @@ openclaw gateway - + - 在 Slack 应用设置中点击 **[创建新应用](https://api.slack.com/apps/new)** 按钮: + 打开 [api.slack.com/apps](https://api.slack.com/apps/new) → **Create New App** → **From a manifest** → 选择你的工作区 → 粘贴下方任一清单 → 将 `https://gateway-host.example.com/slack/events` 替换为你的公开 Gateway 网关 URL → **Next** → **Create**。 - - 选择 **从清单创建**,并为你的应用选择一个工作区 - - 粘贴 [示例清单](#manifest-and-scope-checklist),并在创建前更新 URL - - 保存用于请求验证的 **签名密钥** - - 安装应用,并复制显示的 **Bot 令牌**(`xoxb-...`) + + +```json Recommended +{ + "display_information": { + "name": "OpenClaw", + "description": "Slack connector for OpenClaw" + }, + "features": { + "bot_user": { "display_name": "OpenClaw", "always_online": true }, + "app_home": { + "home_tab_enabled": true, + "messages_tab_enabled": true, + "messages_tab_read_only_enabled": false + }, + "slash_commands": [ + { + "command": "/openclaw", + "description": "Send a message to OpenClaw", + "should_escape": false, + "url": "https://gateway-host.example.com/slack/events" + } + ] + }, + "oauth_config": { + "scopes": { + "bot": [ + "app_mentions:read", + "assistant:write", + "channels:history", + "channels:read", + "chat:write", + "commands", + "emoji:read", + "files:read", + "files:write", + "groups:history", + "groups:read", + "im:history", + "im:read", + "im:write", + "mpim:history", + "mpim:read", + "mpim:write", + "pins:read", + "pins:write", + "reactions:read", + "reactions:write", + "usergroups:read", + "users:read" + ] + } + }, + "settings": { + "event_subscriptions": { + "request_url": "https://gateway-host.example.com/slack/events", + "bot_events": [ + "app_home_opened", + "app_mention", + "channel_rename", + "member_joined_channel", + "member_left_channel", + "message.channels", + "message.groups", + "message.im", + "message.mpim", + "pin_added", + "pin_removed", + "reaction_added", + "reaction_removed" + ] + }, + "interactivity": { + "is_enabled": true, + "request_url": "https://gateway-host.example.com/slack/events", + "message_menu_options_url": "https://gateway-host.example.com/slack/events" + } + } +} +``` + +```json Minimal +{ + "display_information": { + "name": "OpenClaw", + "description": "Slack connector for OpenClaw" + }, + "features": { + "bot_user": { "display_name": "OpenClaw", "always_online": true }, + "app_home": { + "home_tab_enabled": true, + "messages_tab_enabled": true, + "messages_tab_read_only_enabled": false + }, + "slash_commands": [ + { + "command": "/openclaw", + "description": "Send a message to OpenClaw", + "should_escape": false, + "url": "https://gateway-host.example.com/slack/events" + } + ] + }, + "oauth_config": { + "scopes": { + "bot": [ + "app_mentions:read", + "assistant:write", + "channels:history", + "channels:read", + "chat:write", + "commands", + "groups:history", + "groups:read", + "im:history", + "im:read", + "im:write", + "users:read" + ] + } + }, + "settings": { + "event_subscriptions": { + "request_url": "https://gateway-host.example.com/slack/events", + "bot_events": [ + "app_home_opened", + "app_mention", + "message.channels", + "message.groups", + "message.im" + ] + }, + "interactivity": { + "is_enabled": true, + "request_url": "https://gateway-host.example.com/slack/events", + "message_menu_options_url": "https://gateway-host.example.com/slack/events" + } + } +} +``` + + + + + **Recommended** 与内置 Slack 插件的完整功能集一致;对于限制严格的工作区,**Minimal** 不包含文件、回应、置顶、群组私信(`mpim:*`)、`emoji:read` 和 `usergroups:read`。请参阅[清单和作用域检查清单](#manifest-and-scope-checklist),了解每个作用域的理由。 + + + Slack 创建应用后: + + - **Basic Information → App Credentials**:复制用于请求验证的 **Signing Secret**。 + - **Install App → Install to Workspace**:复制 `xoxb-...` Bot User OAuth Token。 @@ -121,9 +403,9 @@ openclaw config patch --file ./slack.http.patch.json5 ``` - 为多账号 HTTP 使用唯一 webhook 路径 + 为多账户 HTTP 使用唯一的 webhook 路径 - 为每个账号指定不同的 `webhookPath`(默认 `/slack/events`),以避免注册冲突。 + 为每个账户提供不同的 `webhookPath`(默认 `/slack/events`),避免注册冲突。 @@ -142,7 +424,7 @@ openclaw gateway ## Socket Mode 传输调优 -对于 Socket Mode,OpenClaw 默认将 Slack SDK 客户端 pong 超时设为 15 秒。仅在需要针对工作区或主机进行特定调优时,才覆盖传输设置: +默认情况下,OpenClaw 会将 Slack SDK 客户端的 pong 超时设置为 15 秒,用于 Socket Mode。仅在需要针对工作区或主机进行特定调优时才覆盖传输设置: ```json5 { @@ -159,11 +441,11 @@ openclaw gateway } ``` -仅当 Socket Mode 工作区记录 Slack WebSocket pong/server-ping 超时,或运行在已知存在事件循环饥饿问题的主机上时,才使用此配置。`clientPingTimeout` 是 SDK 发送客户端 ping 后等待 pong 的时间;`serverPingTimeout` 是等待 Slack 服务器 ping 的时间。应用消息和事件仍然是应用状态,而不是传输存活信号。 +仅将此设置用于记录 Slack websocket pong/server-ping 超时,或运行在已知存在事件循环饥饿问题的主机上的 Socket Mode 工作区。`clientPingTimeout` 是 SDK 发送客户端 ping 后等待 pong 的时间;`serverPingTimeout` 是等待 Slack 服务器 ping 的时间。应用消息和事件仍是应用状态,而不是传输活跃性信号。 -## 清单和作用域核对清单 +## 清单和作用域检查清单 -Socket Mode 和 HTTP 请求 URL 使用相同的基础 Slack 应用清单。只有 `settings` 块(以及斜杠命令的 `url`)不同。 +基础 Slack 应用清单对 Socket Mode 和 HTTP Request URL 相同。只有 `settings` 块(以及斜杠命令 `url`)不同。 基础清单(Socket Mode 默认): @@ -240,7 +522,7 @@ Socket Mode 和 HTTP 请求 URL 使用相同的基础 Slack 应用清单。只 } ``` -对于 **HTTP 请求 URL 模式**,将 `settings` 替换为 HTTP 变体,并为每个斜杠命令添加 `url`。需要公共 URL: +对于 **HTTP Request URLs 模式**,将 `settings` 替换为 HTTP 变体,并为每个斜杠命令添加 `url`。需要公开 URL: ```json { @@ -284,22 +566,22 @@ Socket Mode 和 HTTP 请求 URL 使用相同的基础 Slack 应用清单。只 ### 其他清单设置 -启用不同功能来扩展上述默认设置。 +暴露扩展上述默认值的不同功能。 -默认清单启用 Slack 应用首页的 **首页** 标签页,并订阅 `app_home_opened`。当工作区成员打开首页标签页时,OpenClaw 会通过 `views.publish` 发布一个安全的默认首页视图;其中不包含任何对话载荷或私有配置。**消息** 标签页仍为 Slack 私信启用。 +默认清单启用 Slack App Home 的 **Home** 标签页,并订阅 `app_home_opened`。当工作区成员打开 Home 标签页时,OpenClaw 会通过 `views.publish` 发布一个安全的默认 Home 视图;不会包含会话载荷或私有配置。**Messages** 标签页仍为 Slack 私信启用。 - + - 可以使用多个 [原生斜杠命令](#commands-and-slash-behavior),而不是单个已配置命令;但有一些细节: + 可以使用多个[原生斜杠命令](#commands-and-slash-behavior),替代单个已配置命令,但有一些细节: - - 请使用 `/agentstatus` 而不是 `/status`,因为 `/status` 命令已保留。 + - 使用 `/agentstatus` 而不是 `/status`,因为 `/status` 命令已被保留。 - 一次最多只能提供 25 个斜杠命令。 - 将现有的 `features.slash_commands` 部分替换为 [可用命令](/zh-CN/tools/slash-commands#command-list) 的一个子集: + 将现有的 `features.slash_commands` 部分替换为[可用命令](/zh-CN/tools/slash-commands#command-list)的子集: - + ```json { @@ -422,7 +704,7 @@ Socket Mode 和 HTTP 请求 URL 使用相同的基础 Slack 应用清单。只 ``` - + 使用与上方 Socket Mode 相同的 `slash_commands` 列表,并为每个条目添加 `"url": "https://gateway-host.example.com/slack/events"`。示例: ```json @@ -443,23 +725,23 @@ Socket Mode 和 HTTP 请求 URL 使用相同的基础 Slack 应用清单。只 } ``` - 对列表中的每个命令重复使用该 `url` 值。 + 在列表中的每个命令上重复该 `url` 值。 - - 如果你希望外发消息使用当前智能体身份(自定义用户名和图标),而不是默认 Slack 应用身份,请添加 `chat:write.customize` bot 作用域。 + + 如果你希望传出消息使用活动 agent 身份(自定义用户名和图标),而不是默认 Slack 应用身份,请添加 `chat:write.customize` 机器人作用域。 - 如果你使用表情图标,Slack 需要 `:emoji_name:` 语法。 + 如果你使用 emoji 图标,Slack 期望使用 `:emoji_name:` 语法。 - - 如果你配置了 `channels.slack.userToken`,典型读取作用域为: + + 如果你配置 `channels.slack.userToken`,典型读取作用域包括: - - `channels:history`, `groups:history`, `im:history`, `mpim:history` - - `channels:read`, `groups:read`, `im:read`, `mpim:read` + - `channels:history`、`groups:history`、`im:history`、`mpim:history` + - `channels:read`、`groups:read`、`im:read`、`mpim:read` - `users:read` - `reactions:read` - `pins:read` @@ -473,25 +755,20 @@ Socket Mode 和 HTTP 请求 URL 使用相同的基础 Slack 应用清单。只 - Socket Mode 需要 `botToken` + `appToken`。 - HTTP 模式需要 `botToken` + `signingSecret`。 -- `botToken`、`appToken`、`signingSecret` 和 `userToken` 接受明文 - 字符串或 SecretRef 对象。 +- `botToken`、`appToken`、`signingSecret` 和 `userToken` 接受明文字符串或 SecretRef 对象。 - 配置令牌会覆盖环境变量回退。 - `SLACK_BOT_TOKEN` / `SLACK_APP_TOKEN` 环境变量回退仅适用于默认账户。 -- `userToken`(`xoxp-...`)只能通过配置提供(没有环境变量回退),并默认采用只读行为(`userTokenReadOnly: true`)。 +- `userToken`(`xoxp-...`)只能通过配置提供(无环境变量回退),并默认使用只读行为(`userTokenReadOnly: true`)。 Status 快照行为: -- Slack 账户检查会跟踪每个凭据的 `*Source` 和 `*Status` - 字段(`botToken`、`appToken`、`signingSecret`、`userToken`)。 +- Slack 账户检查会跟踪每个凭证的 `*Source` 和 `*Status` 字段(`botToken`、`appToken`、`signingSecret`、`userToken`)。 - Status 为 `available`、`configured_unavailable` 或 `missing`。 -- `configured_unavailable` 表示账户通过 SecretRef - 或其他非内联密钥来源进行了配置,但当前命令/运行时路径 - 无法解析实际值。 -- 在 HTTP 模式下,会包含 `signingSecretStatus`;在 Socket Mode 下, - 必需组合为 `botTokenStatus` + `appTokenStatus`。 +- `configured_unavailable` 表示账户已通过 SecretRef 或其他非内联密钥来源配置,但当前命令/运行时路径无法解析实际值。 +- 在 HTTP 模式下,会包含 `signingSecretStatus`;在 Socket Mode 中,所需组合是 `botTokenStatus` + `appTokenStatus`。 -对于操作/目录读取,配置后可以优先使用用户令牌。对于写入,仍优先使用 bot 令牌;只有当 `userTokenReadOnly: false` 且 bot 令牌不可用时,才允许用户令牌写入。 +对于操作/目录读取,配置后可以优先使用用户令牌。对于写入,仍优先使用机器人令牌;只有当 `userTokenReadOnly: false` 且机器人令牌不可用时,才允许用户令牌写入。 ## 操作和门控 @@ -502,19 +779,19 @@ Slack 操作由 `channels.slack.actions.*` 控制。 | 组 | 默认值 | | ---------- | ------- | -| messages | 启用 | -| reactions | 启用 | -| pins | 启用 | -| memberInfo | 启用 | -| emojiList | 启用 | +| messages | enabled | +| reactions | enabled | +| pins | enabled | +| memberInfo | enabled | +| emojiList | enabled | -当前 Slack 消息操作包括 `send`、`upload-file`、`download-file`、`read`、`edit`、`delete`、`pin`、`unpin`、`list-pins`、`member-info` 和 `emoji-list`。`download-file` 接受入站文件占位符中显示的 Slack 文件 ID,并对图片返回图片预览,或对其他文件类型返回本地文件元数据。 +当前 Slack 消息操作包括 `send`、`upload-file`、`download-file`、`read`、`edit`、`delete`、`pin`、`unpin`、`list-pins`、`member-info` 和 `emoji-list`。`download-file` 接受入站文件占位符中显示的 Slack 文件 ID,并为图片返回图片预览,或为其他文件类型返回本地文件元数据。 ## 访问控制和路由 - - `channels.slack.dmPolicy` 控制私信访问。`channels.slack.allowFrom` 是规范私信允许列表。 + + `channels.slack.dmPolicy` 控制私信访问。`channels.slack.allowFrom` 是规范的私信允许列表。 - `pairing`(默认) - `allowlist` @@ -523,7 +800,7 @@ Slack 操作由 `channels.slack.actions.*` 控制。 私信标志: - - `dm.enabled`(默认 true) + - `dm.enabled`(默认为 true) - `channels.slack.allowFrom` - `dm.allowFrom`(旧版) - `dm.groupEnabled`(群组私信默认为 false) @@ -535,35 +812,35 @@ Slack 操作由 `channels.slack.actions.*` 控制。 - 命名账户在自己的 `allowFrom` 未设置时继承 `channels.slack.allowFrom`。 - 命名账户不会继承 `channels.slack.accounts.default.allowFrom`。 - 为兼容性,旧版 `channels.slack.dm.policy` 和 `channels.slack.dm.allowFrom` 仍会读取。`openclaw doctor --fix` 会在不改变访问权限的情况下,将它们迁移到 `dmPolicy` 和 `allowFrom`。 + 为兼容性仍会读取旧版 `channels.slack.dm.policy` 和 `channels.slack.dm.allowFrom`。`openclaw doctor --fix` 在不会更改访问权限的情况下,会将它们迁移到 `dmPolicy` 和 `allowFrom`。 私信中的配对使用 `openclaw pairing approve slack `。 - - `channels.slack.groupPolicy` 控制渠道处理: + + `channels.slack.groupPolicy` 控制 channel 处理: - `open` - `allowlist` - `disabled` - 渠道允许列表位于 `channels.slack.channels` 下,并且配置键名**必须使用稳定的 Slack 渠道 ID**(例如 `C12345678`)。 + channel 允许列表位于 `channels.slack.channels` 下,并且**必须使用稳定的 Slack channel ID**(例如 `C12345678`)作为配置键。 - 运行时注意事项:如果完全缺少 `channels.slack`(仅环境变量设置),运行时会回退到 `groupPolicy="allowlist"` 并记录一条警告(即使已设置 `channels.defaults.groupPolicy`)。 + 运行时注意事项:如果完全缺少 `channels.slack`(仅环境变量设置),运行时会回退到 `groupPolicy="allowlist"` 并记录警告(即使设置了 `channels.defaults.groupPolicy`)。 名称/ID 解析: - - 当令牌访问允许时,渠道允许列表条目和私信允许列表条目会在启动时解析 - - 未解析的渠道名称条目会按配置保留,但默认会在路由时被忽略 - - 入站授权和渠道路由默认以 ID 优先;直接用户名/slug 匹配需要 `channels.slack.dangerouslyAllowNameMatching: true` + - 渠道允许列表条目和私信允许列表条目会在启动时解析,前提是 token 访问权限允许 + - 未解析的渠道名称条目会按配置保留,但默认会被路由忽略 + - 入站授权和渠道路由默认采用 ID 优先;直接用户名/slug 匹配需要 `channels.slack.dangerouslyAllowNameMatching: true` - 在 `groupPolicy: "allowlist"` 下,基于名称的键(`#channel-name` 或 `channel-name`)**不会**匹配。渠道查找默认以 ID 优先,因此基于名称的键永远无法成功路由,并且该渠道中的所有消息都会被静默阻止。这不同于 `groupPolicy: "open"`,后者不需要渠道键即可路由,而基于名称的键看起来也能工作。 + 基于名称的键(`#channel-name` 或 `channel-name`)在 `groupPolicy: "allowlist"` 下**不会**匹配。渠道查找默认采用 ID 优先,因此基于名称的键永远无法成功路由,该渠道中的所有消息都会被静默阻止。这不同于 `groupPolicy: "open"`,在后者中路由不需要渠道键,并且基于名称的键看起来可以工作。 - 始终使用 Slack 渠道 ID 作为键。查找方式:在 Slack 中右键点击渠道 → **复制链接** — ID(`C...`)会显示在 URL 末尾。 + 始终使用 Slack 渠道 ID 作为键。查找方法:在 Slack 中右键点击渠道 → **复制链接** — ID(`C...`)会出现在 URL 末尾。 - 正确示例: + 正确: ```json5 { @@ -578,7 +855,7 @@ Slack 操作由 `channels.slack.actions.*` 控制。 } ``` - 不正确(在 `groupPolicy: "allowlist"` 下会被静默阻止): + 错误(在 `groupPolicy: "allowlist"` 下会被静默阻止): ```json5 { @@ -597,27 +874,27 @@ Slack 操作由 `channels.slack.actions.*` 控制。 - 渠道消息默认需要提及才会处理。 + 渠道消息默认受提及门控限制。 提及来源: - 显式应用提及(`<@botId>`) - Slack 用户组提及(``),当机器人用户是该用户组成员时生效;需要 `usergroups:read` - - 提及正则模式(`agents.list[].groupChat.mentionPatterns`,回退到 `messages.groupChat.mentionPatterns`) + - 提及正则表达式模式(`agents.list[].groupChat.mentionPatterns`,回退为 `messages.groupChat.mentionPatterns`) - 隐式回复机器人线程行为(当 `thread.requireExplicitMention` 为 `true` 时禁用) - 每个渠道的控制项(`channels.slack.channels.`;名称仅通过启动解析或 `dangerouslyAllowNameMatching` 使用): + 按渠道控制(`channels.slack.channels.`;名称只能通过启动时解析或 `dangerouslyAllowNameMatching` 使用): - `requireMention` - `users`(允许列表) - `allowBots` - `skills` - `systemPrompt` - - `tools`、`toolsBySender` - - `toolsBySender` 键格式:`id:`、`e164:`、`username:`、`name:`,或 `"*"` 通配符 - (旧版无前缀键仍仅映射到 `id:`) + - `tools`, `toolsBySender` + - `toolsBySender` 键格式:`id:`、`e164:`、`username:`、`name:` 或 `"*"` 通配符 + (旧版无前缀键仍然只映射到 `id:`) - `allowBots` 对渠道和私有渠道采取保守策略:只有当发送消息的机器人被显式列入该房间的 `users` 允许列表,或来自 `channels.slack.allowFrom` 的至少一个显式 Slack 所有者 ID 当前是房间成员时,才会接受机器人发出的房间消息。通配符和显示名称所有者条目不满足所有者在场条件。所有者在场使用 Slack `conversations.members`;确保应用拥有匹配房间类型的读取范围(公共渠道为 `channels:read`,私有渠道为 `groups:read`)。如果成员查询失败,OpenClaw 会丢弃机器人发出的房间消息。 + `allowBots` 对渠道和私有渠道采取保守策略:只有当发送机器人的 ID 明确列在该房间的 `users` 允许列表中,或 `channels.slack.allowFrom` 中至少有一个显式 Slack 所有者 ID 当前是房间成员时,才会接受机器人发送的房间消息。通配符和显示名称所有者条目不满足所有者在场要求。所有者在场使用 Slack `conversations.members`;请确保应用拥有对应房间类型的匹配读取 scope(公共渠道为 `channels:read`,私有渠道为 `groups:read`)。如果成员查找失败,OpenClaw 会丢弃机器人发送的房间消息。 @@ -625,18 +902,18 @@ Slack 操作由 `channels.slack.actions.*` 控制。 ## 线程、会话和回复标签 - 私信路由为 `direct`;渠道路由为 `channel`;MPIM 路由为 `group`。 -- Slack 路由绑定接受原始对端 ID,以及 `channel:C12345678`、`user:U12345678` 和 `<@U12345678>` 等 Slack 目标形式。 +- Slack 路由绑定接受原始 peer ID,以及 Slack 目标形式,例如 `channel:C12345678`、`user:U12345678` 和 `<@U12345678>`。 - 使用默认 `session.dmScope=main` 时,Slack 私信会合并到智能体主会话。 - 渠道会话:`agent::slack:channel:`。 - 适用时,线程回复可以创建线程会话后缀(`:thread:`)。 -- `channels.slack.thread.historyScope` 默认值为 `thread`;`thread.inheritParent` 默认值为 `false`。 +- `channels.slack.thread.historyScope` 默认为 `thread`;`thread.inheritParent` 默认为 `false`。 - `channels.slack.thread.initialHistoryLimit` 控制新线程会话启动时获取多少条现有线程消息(默认 `20`;设为 `0` 可禁用)。 -- `channels.slack.thread.requireExplicitMention`(默认 `false`):当为 `true` 时,抑制隐式线程提及,使机器人只响应线程内显式的 `@bot` 提及,即使机器人已经参与过该线程。否则,机器人已参与线程中的回复会绕过 `requireMention` 门控。 +- `channels.slack.thread.requireExplicitMention`(默认 `false`):当为 `true` 时,抑制隐式线程提及,因此即使机器人已参与该线程,机器人也只会响应线程内显式的 `@bot` 提及。否则,在机器人已参与的线程中的回复会绕过 `requireMention` 门控。 -回复线程控制项: +回复线程控制: - `channels.slack.replyToMode`:`off|first|all|batched`(默认 `off`) -- `channels.slack.replyToModeByChatType`:按 `direct|group|channel` 分别设置 +- `channels.slack.replyToModeByChatType`:按 `direct|group|channel` 设置 - 直接聊天的旧版回退:`channels.slack.dm.replyToMode` 支持手动回复标签: @@ -645,23 +922,23 @@ Slack 操作由 `channels.slack.actions.*` 控制。 - `[[reply_to:]]` -`replyToMode="off"` 会禁用 Slack 中的**所有**回复线程,包括显式 `[[reply_to_*]]` 标签。这与 Telegram 不同,Telegram 在 `"off"` 模式下仍会遵循显式标签。Slack 线程会将消息从渠道中隐藏,而 Telegram 回复会以内联形式保持可见。 +`replyToMode="off"` 会在 Slack 中禁用**所有**回复线程,包括显式 `[[reply_to_*]]` 标签。这不同于 Telegram,后者在 `"off"` 模式下仍会遵循显式标签。Slack 线程会从渠道中隐藏消息,而 Telegram 回复会以内联方式保持可见。 ## 确认反应 -`ackReaction` 会在 OpenClaw 处理入站消息时发送一个确认表情符号。 +`ackReaction` 会在 OpenClaw 处理入站消息时发送一个确认 emoji。 解析顺序: - `channels.slack.accounts..ackReaction` - `channels.slack.ackReaction` - `messages.ackReaction` -- 智能体身份表情符号回退(`agents.list[].identity.emoji`,否则为 "👀") +- 智能体身份 emoji 回退(`agents.list[].identity.emoji`,否则为 "👀") -注意事项: +注意: -- Slack 期望使用短代码(例如 `"eyes"`)。 +- Slack 需要 shortcodes(例如 `"eyes"`)。 - 使用 `""` 可为 Slack 账号或全局禁用该反应。 ## 文本流式传输 @@ -673,9 +950,9 @@ Slack 操作由 `channels.slack.actions.*` 控制。 - `block`:追加分块预览更新。 - `progress`:生成时显示进度状态文本,然后发送最终文本。 - `streaming.preview.toolProgress`:当草稿预览处于活动状态时,将工具/进度更新路由到同一条已编辑的预览消息中(默认:`true`)。设为 `false` 可保留单独的工具/进度消息。 -- `streaming.preview.commandText` / `streaming.progress.commandText`:设为 `status` 可隐藏原始命令/执行文本,同时保留紧凑的工具进度行(默认:`raw`)。 +- `streaming.preview.commandText` / `streaming.progress.commandText`:设为 `status` 可在隐藏原始 command/exec 文本的同时保留紧凑的工具进度行(默认:`raw`)。 -隐藏原始命令/执行文本,同时保留紧凑的进度行: +隐藏原始 command/exec 文本,同时保留紧凑进度行: ```json { @@ -693,16 +970,16 @@ Slack 操作由 `channels.slack.actions.*` 控制。 } ``` -`channels.slack.streaming.nativeTransport` 在 `channels.slack.streaming.mode` 为 `partial` 时控制 Slack 原生文本流式传输(默认:`true`)。 +当 `channels.slack.streaming.mode` 为 `partial` 时,`channels.slack.streaming.nativeTransport` 控制 Slack 原生文本流式传输(默认:`true`)。 -- 必须有可用的回复线程,原生文本流式传输和 Slack 助手线程状态才会显示。线程选择仍遵循 `replyToMode`。 -- 当原生流式传输不可用或不存在回复线程时,渠道、群聊和顶层私信根仍可使用普通草稿预览。 -- 顶层 Slack 私信默认保持在线程外,因此不会显示 Slack 线程样式的原生流/状态预览;OpenClaw 会改为在私信中发布并编辑草稿预览。 -- 媒体和非文本载荷会回退到普通投递。 -- 媒体/错误最终消息会取消待处理的预览编辑;符合条件的文本/分块最终消息仅在可以就地编辑预览时刷新。 -- 如果流式传输在回复中途失败,OpenClaw 会对剩余载荷回退到普通投递。 +- 必须有可用的回复线程,原生文本流式传输和 Slack assistant 线程状态才会出现。线程选择仍遵循 `replyToMode`。 +- 当原生流式传输不可用或不存在回复线程时,渠道、群聊和顶层私信根消息仍可使用普通草稿预览。 +- 顶层 Slack 私信默认保持在线程外,因此不会显示 Slack 线程样式的原生 stream/status 预览;OpenClaw 会改为在私信中发布并编辑草稿预览。 +- 媒体和非文本 payload 会回退到普通投递。 +- 媒体/错误最终消息会取消待处理的预览编辑;符合条件的文本/块最终消息只有在能就地编辑预览时才会 flush。 +- 如果流式传输在回复中途失败,OpenClaw 会对剩余 payload 回退到普通投递。 -使用草稿预览,而不是 Slack 原生文本流式传输: +使用草稿预览而不是 Slack 原生文本流式传输: ```json5 { @@ -723,54 +1000,54 @@ Slack 操作由 `channels.slack.actions.*` 控制。 - 布尔值 `channels.slack.streaming` 会自动迁移到 `channels.slack.streaming.mode` 和 `channels.slack.streaming.nativeTransport`。 - 旧版 `channels.slack.nativeStreaming` 会自动迁移到 `channels.slack.streaming.nativeTransport`。 -## 输入反应回退 +## 输入中反应回退 -`typingReaction` 会在 OpenClaw 处理回复期间,为入站 Slack 消息添加一个临时表情回应,并在运行结束时移除它。这在线程回复之外最有用;线程回复会使用默认的“正在输入...”状态指示器。 +`typingReaction` 会在 OpenClaw 处理回复时向入站 Slack 消息添加一个临时反应,并在运行结束时移除。它在线程回复之外最有用;线程回复会使用默认的“正在输入...”状态指示器。 解析顺序: - `channels.slack.accounts..typingReaction` - `channels.slack.typingReaction` -注意事项: +注意: -- Slack 需要短代码(例如 `"hourglass_flowing_sand"`)。 -- 该表情回应是尽力而为的,并且会在回复或失败路径完成后自动尝试清理。 +- Slack 需要 shortcodes(例如 `"hourglass_flowing_sand"`)。 +- 该反应是尽力而为的,并会在回复或失败路径完成后自动尝试清理。 ## 媒体、分块和投递 - - Slack 文件附件会从 Slack 托管的私有 URL 下载(令牌认证请求流),并在获取成功且大小限制允许时写入媒体存储。文件占位符包含 Slack `fileId`,因此智能体可以使用 `download-file` 获取原始文件。 + + Slack 文件附件会从 Slack 托管的私有 URL 下载(token 认证请求流程),并在获取成功且大小限制允许时写入媒体存储。文件占位符包含 Slack `fileId`,因此智能体可以使用 `download-file` 获取原始文件。 下载使用有界空闲超时和总超时。如果 Slack 文件检索停滞或失败,OpenClaw 会继续处理消息,并回退到文件占位符。 - 运行时入站大小上限默认为 `20MB`,除非被 `channels.slack.mediaMaxMb` 覆盖。 + 运行时入站大小上限默认为 `20MB`,除非由 `channels.slack.mediaMaxMb` 覆盖。 - - - 文本分块使用 `channels.slack.textChunkLimit`(默认 4000) - - `channels.slack.chunkMode="newline"` 启用优先按段落拆分 + + - 文本块使用 `channels.slack.textChunkLimit`(默认 4000) + - `channels.slack.chunkMode="newline"` 启用段落优先拆分 - 文件发送使用 Slack 上传 API,并且可以包含线程回复(`thread_ts`) - - 配置后,出站媒体上限遵循 `channels.slack.mediaMaxMb`;否则渠道发送会使用媒体流水线中的 MIME 类型默认值 + - 配置时,出站媒体上限遵循 `channels.slack.mediaMaxMb`;否则渠道发送使用媒体流水线中的 MIME kind 默认值 - + 首选显式目标: - - `user:` 用于私信 - - `channel:` 用于渠道 + - 私信使用 `user:` + - 渠道使用 `channel:` - 仅文本/区块的 Slack 私信可以直接发布到用户 ID;文件上传和线程发送会先通过 Slack conversation API 打开私信,因为这些路径需要具体的 conversation ID。 + 仅文本/块的 Slack 私信可以直接发布到用户 ID;文件上传和线程发送会先通过 Slack conversation API 打开私信,因为这些路径需要具体的 conversation ID。 -## 命令和斜杠行为 +## 命令和 slash 行为 -斜杠命令在 Slack 中可以表现为单个已配置命令,也可以表现为多个原生命令。配置 `channels.slack.slashCommand` 可更改命令默认值: +Slash 命令在 Slack 中显示为单个已配置命令或多个原生命令。配置 `channels.slack.slashCommand` 可更改命令默认值: - `enabled: false` - `name: "openclaw"` @@ -781,7 +1058,7 @@ Slack 操作由 `channels.slack.actions.*` 控制。 /openclaw /help ``` -原生命令需要在你的 Slack 应用中配置[其他清单设置](#additional-manifest-settings),并改用 `channels.slack.commands.native: true` 或全局配置中的 `commands.native: true` 启用。 +原生命令需要在你的 Slack 应用中配置[额外清单设置](#additional-manifest-settings),并通过 `channels.slack.commands.native: true` 启用,或在全局配置中通过 `commands.native: true` 启用。 - Slack 的原生命令自动模式为**关闭**,因此 `commands.native: "auto"` 不会启用 Slack 原生命令。 @@ -789,22 +1066,22 @@ Slack 操作由 `channels.slack.actions.*` 控制。 /help ``` -原生参数菜单使用自适应渲染策略,会在分派所选选项值前显示确认模态框: +原生参数菜单使用自适应渲染策略,在分发选中的选项值之前显示确认 modal: -- 最多 5 个选项:按钮区块 -- 6-100 个选项:静态选择菜单 -- 超过 100 个选项:当交互选项处理器可用时,使用带异步选项过滤的外部选择 +- 最多 5 个选项:button blocks +- 6-100 个选项:static select menu +- 超过 100 个选项:当 interactivity options handlers 可用时,使用带异步选项过滤的 external select - 超出 Slack 限制:编码后的选项值回退为按钮 ```txt /think ``` -斜杠会话使用类似 `agent::slack:slash:` 的隔离键,并且仍使用 `CommandTargetSessionKey` 将命令执行路由到目标 conversation 会话。 +Slash 会话使用类似 `agent::slack:slash:` 的隔离键,并且仍使用 `CommandTargetSessionKey` 将命令执行路由到目标 conversation 会话。 ## 交互式回复 -Slack 可以渲染由智能体编写的交互式回复控件,但此功能默认禁用。 +Slack 可以渲染智能体创作的交互式回复控件,但该功能默认禁用。 全局启用: @@ -820,7 +1097,7 @@ Slack 可以渲染由智能体编写的交互式回复控件,但此功能默 } ``` -或仅为一个 Slack 账户启用: +或仅为一个 Slack 账号启用: ```json5 { @@ -843,37 +1120,37 @@ Slack 可以渲染由智能体编写的交互式回复控件,但此功能默 - `[[slack_buttons: Approve:approve, Reject:reject]]` - `[[slack_select: Choose a target | Canary:canary, Production:production]]` -这些指令会编译为 Slack Block Kit,并通过现有 Slack 交互事件路径将点击或选择路由回来。 +这些指令会编译为 Slack Block Kit,并通过现有 Slack interaction 事件路径回传点击或选择。 -注意事项: +注意: -- 这是 Slack 专属 UI。其他渠道不会将 Slack Block Kit 指令转换为自己的按钮系统。 -- 交互式回调值是 OpenClaw 生成的不透明令牌,而不是智能体编写的原始值。 -- 如果生成的交互区块会超出 Slack Block Kit 限制,OpenClaw 会回退为原始文本回复,而不是发送无效的 blocks 载荷。 +- 这是 Slack 专用 UI。其他渠道不会将 Slack Block Kit 指令转换为自己的按钮系统。 +- 交互式回调值是 OpenClaw 生成的不透明令牌,不是智能体编写的原始值。 +- 如果生成的交互式块会超出 Slack Block Kit 限制,OpenClaw 会回退到原始文本回复,而不是发送无效的块载荷。 -## Slack 中的执行审批 +## Slack 中的执行批准 -Slack 可以作为带有交互式按钮和交互的原生审批客户端,而不是回退到 Web 界面或终端。 +Slack 可以作为带有交互式按钮和交互的原生批准客户端,而不是回退到 Web UI 或终端。 -- 执行审批使用 `channels.slack.execApprovals.*` 进行原生私信/渠道路由。 -- 当请求已经落在 Slack 中且审批 ID 类型为 `plugin:` 时,插件审批仍可以通过同一个 Slack 原生按钮界面解析。 -- 审批者授权仍会强制执行:只有被识别为审批者的用户才能通过 Slack 批准或拒绝请求。 +- 执行批准使用 `channels.slack.execApprovals.*` 进行原生私信/渠道路由。 +- 当请求已经落在 Slack 中且批准 ID 类型为 `plugin:` 时,插件批准仍可通过同一个 Slack 原生按钮界面解析。 +- 批准者授权仍会强制执行:只有被识别为批准者的用户才能通过 Slack 批准或拒绝请求。 -这使用与其他渠道相同的共享审批按钮界面。当你的 Slack 应用设置中启用 `interactivity` 时,审批提示会直接在 conversation 中渲染为 Block Kit 按钮。 -当这些按钮存在时,它们是主要审批体验;只有在工具结果表明聊天审批不可用或手动审批是唯一路径时,OpenClaw +这使用与其他渠道相同的共享批准按钮界面。当你的 Slack 应用设置中启用 `interactivity` 时,批准提示会直接在对话中渲染为 Block Kit 按钮。 +当这些按钮存在时,它们就是主要批准 UX;只有在工具结果表明聊天批准不可用或手动批准是唯一途径时,OpenClaw 才应包含手动 `/approve` 命令。 配置路径: - `channels.slack.execApprovals.enabled` -- `channels.slack.execApprovals.approvers`(可选;可能时回退到 `commands.ownerAllowFrom`) +- `channels.slack.execApprovals.approvers`(可选;可行时回退到 `commands.ownerAllowFrom`) - `channels.slack.execApprovals.target`(`dm` | `channel` | `both`,默认:`dm`) -- `agentFilter`、`sessionFilter` +- `agentFilter`, `sessionFilter` -当 `enabled` 未设置或为 `"auto"` 且至少解析出一个审批者时,Slack 会自动启用原生执行审批。设置 `enabled: false` 可明确禁用 Slack 作为原生审批客户端。 -设置 `enabled: true` 可在解析出审批者时强制启用原生审批。 +当 `enabled` 未设置或为 `"auto"`,且至少能解析出一个批准者时,Slack 会自动启用原生执行批准。设置 `enabled: false` 可显式禁用 Slack 作为原生批准客户端。 +设置 `enabled: true` 可在能解析出批准者时强制启用原生批准。 -没有显式 Slack 执行审批配置时的默认行为: +没有显式 Slack 执行批准配置时的默认行为: ```json5 { @@ -883,7 +1160,7 @@ Slack 可以作为带有交互式按钮和交互的原生审批客户端,而 } ``` -只有在你想覆盖审批者、添加过滤器或选择启用来源聊天投递时,才需要显式 Slack 原生配置: +只有在你想覆盖批准者、添加筛选器,或选择启用源聊天投递时,才需要显式 Slack 原生配置: ```json5 { @@ -899,22 +1176,22 @@ Slack 可以作为带有交互式按钮和交互的原生审批客户端,而 } ``` -共享 `approvals.exec` 转发是独立的。只有在执行审批提示还必须路由到其他聊天或显式带外目标时才使用它。共享 `approvals.plugin` 转发也是独立的;当这些请求已经落在 Slack 中时,Slack 原生按钮仍可以解析插件审批。 +共享的 `approvals.exec` 转发是单独的。仅当执行批准提示还必须路由到其他聊天或显式带外目标时才使用它。共享的 `approvals.plugin` 转发也是单独的;当这些请求已经落在 Slack 中时,Slack 原生按钮仍可解析插件批准。 -同一聊天中的 `/approve` 也适用于已支持命令的 Slack 渠道和私信。请参阅[执行审批](/zh-CN/tools/exec-approvals),了解完整的审批转发模型。 +同一聊天中的 `/approve` 也适用于已支持命令的 Slack 渠道和私信。完整批准转发模型见[执行批准](/zh-CN/tools/exec-approvals)。 ## 事件和运行行为 - 消息编辑/删除会映射为系统事件。 -- 线程广播(“同时发送到渠道”的线程回复)会作为普通用户消息处理。 -- 表情回应添加/移除事件会映射为系统事件。 -- 成员加入/离开、渠道创建/重命名以及置顶添加/移除事件会映射为系统事件。 +- 线程广播(“同时发送到渠道”线程回复)会按普通用户消息处理。 +- 添加/移除表情回应事件会映射为系统事件。 +- 成员加入/离开、渠道创建/重命名,以及置顶添加/移除事件会映射为系统事件。 - 启用 `configWrites` 时,`channel_id_changed` 可以迁移渠道配置键。 - 渠道主题/用途元数据会被视为不受信任的上下文,并可注入到路由上下文中。 -- 线程起始消息和初始线程历史上下文种子填充会在适用时按已配置的发送者允许列表过滤。 -- 区块操作和模态交互会发出结构化的 `Slack interaction: ...` 系统事件,并带有丰富的载荷字段: - - 区块操作:所选值、标签、选择器值以及 `workflow_*` 元数据 - - 模态 `view_submission` 和 `view_closed` 事件,包含已路由的渠道元数据和表单输入 +- 适用时,线程起始消息和初始线程历史上下文填充会按配置的发送者允许列表过滤。 +- 块操作和模态交互会发出结构化的 `Slack interaction: ...` 系统事件,并带有丰富的载荷字段: + - 块操作:选中值、标签、选择器值,以及 `workflow_*` 元数据 + - 模态 `view_submission` 和 `view_closed` 事件,包含路由后的渠道元数据和表单输入 ## 配置参考 @@ -922,13 +1199,13 @@ Slack 可以作为带有交互式按钮和交互的原生审批客户端,而 -- 模式/身份验证:`mode`、`botToken`、`appToken`、`signingSecret`、`webhookPath`、`accounts.*` -- 私信访问:`dm.enabled`、`dmPolicy`、`allowFrom`(旧版:`dm.policy`、`dm.allowFrom`)、`dm.groupEnabled`、`dm.groupChannels` -- 兼容性开关:`dangerouslyAllowNameMatching`(应急;除非需要,否则保持关闭) -- 渠道访问:`groupPolicy`、`channels.*`、`channels.*.users`、`channels.*.requireMention` -- 线程/历史:`replyToMode`、`replyToModeByChatType`、`thread.*`、`historyLimit`、`dmHistoryLimit`、`dms.*.historyLimit` -- 投递:`textChunkLimit`、`chunkMode`、`mediaMaxMb`、`streaming`、`streaming.nativeTransport`、`streaming.preview.toolProgress` -- 运维/功能:`configWrites`、`commands.native`、`slashCommand.*`、`actions.*`、`userToken`、`userTokenReadOnly` +- 模式/身份验证:`mode`, `botToken`, `appToken`, `signingSecret`, `webhookPath`, `accounts.*` +- 私信访问:`dm.enabled`, `dmPolicy`, `allowFrom`(旧版:`dm.policy`, `dm.allowFrom`), `dm.groupEnabled`, `dm.groupChannels` +- 兼容性开关:`dangerouslyAllowNameMatching`(紧急开关;除非需要,否则保持关闭) +- 渠道访问:`groupPolicy`, `channels.*`, `channels.*.users`, `channels.*.requireMention` +- 线程/历史记录:`replyToMode`, `replyToModeByChatType`, `thread.*`, `historyLimit`, `dmHistoryLimit`, `dms.*.historyLimit` +- 投递:`textChunkLimit`, `chunkMode`, `mediaMaxMb`, `streaming`, `streaming.nativeTransport`, `streaming.preview.toolProgress` +- 运维/功能:`configWrites`, `commands.native`, `slashCommand.*`, `actions.*`, `userToken`, `userTokenReadOnly` @@ -939,11 +1216,11 @@ Slack 可以作为带有交互式按钮和交互的原生审批客户端,而 按顺序检查: - `groupPolicy` - - 渠道允许列表(`channels.slack.channels`):**键必须是渠道 ID**(`C12345678`),而不是名称(`#channel-name`)。在 `groupPolicy: "allowlist"` 下,基于名称的键会静默失败,因为默认情况下渠道路由会优先使用 ID。要查找 ID:在 Slack 中右键点击渠道 → **复制链接**;URL 末尾的 `C...` 值就是渠道 ID。 + - 渠道允许列表(`channels.slack.channels`)— **键必须是渠道 ID**(`C12345678`),不能是名称(`#channel-name`)。在 `groupPolicy: "allowlist"` 下,基于名称的键会静默失败,因为渠道路由默认优先使用 ID。要查找 ID:在 Slack 中右键点击该渠道 → **复制链接** — URL 末尾的 `C...` 值就是渠道 ID。 - `requireMention` - - 每渠道 `users` 允许列表 + - 每个渠道的 `users` 允许列表 - 常用命令: + 有用命令: ```bash openclaw channels status --probe @@ -958,10 +1235,8 @@ openclaw doctor - `channels.slack.dm.enabled` - `channels.slack.dmPolicy`(或旧版 `channels.slack.dm.policy`) - - 配对审批/允许列表条目 - - Slack Assistant 私信事件:提到 `drop message_changed` 的详细日志 - 通常表示 Slack 发送了一个已编辑的 Assistant 线程事件, - 且消息元数据中没有可恢复的人类发送者 + - 配对批准/允许列表条目 + - Slack Assistant 私信事件:提到 `drop message_changed` 的详细日志通常表示 Slack 发送了一个已编辑的 Assistant 线程事件,但消息元数据中没有可恢复的人类发送者 ```bash openclaw pairing list slack @@ -969,52 +1244,50 @@ openclaw pairing list slack - - 在 Slack 应用设置中验证机器人和应用令牌,以及 Socket Mode 启用状态。 + + 验证机器人 + 应用令牌,以及 Slack 应用设置中是否已启用 Socket Mode。 如果 `openclaw channels status --probe --json` 显示 `botTokenStatus` 或 - `appTokenStatus: "configured_unavailable"`,说明 Slack 账户已配置, - 但当前运行时无法解析由 SecretRef 支持的值。 + `appTokenStatus: "configured_unavailable"`,则 Slack 账号已配置,但当前运行时无法解析由 SecretRef 支持的值。 - + 验证: - 签名密钥 - webhook 路径 - Slack 请求 URL(事件 + 交互性 + 斜杠命令) - - 每个 HTTP 账户唯一的 `webhookPath` + - 每个 HTTP 账号使用唯一的 `webhookPath` - 如果账户快照中出现 `signingSecretStatus: "configured_unavailable"`, - 说明 HTTP 账户已配置,但当前运行时无法解析由 SecretRef 支持的签名密钥。 + 如果账号快照中出现 `signingSecretStatus: "configured_unavailable"`,则 HTTP 账号已配置,但当前运行时无法解析由 SecretRef 支持的签名密钥。 - 验证你的预期是: + 确认你的意图是: - - 原生命令模式(`channels.slack.commands.native: true`),并在 Slack 中注册了匹配的斜杠命令 - - 或单斜杠命令模式(`channels.slack.slashCommand.enabled: true`) + - 原生命令模式(`channels.slack.commands.native: true`),并且在 Slack 中注册了匹配的斜杠命令 + - 或单一斜杠命令模式(`channels.slack.slashCommand.enabled: true`) - 另请检查 `commands.useAccessGroups` 和渠道/用户允许列表。 + 同时检查 `commands.useAccessGroups` 以及渠道/用户允许列表。 ## 附件视觉参考 -当 Slack 文件下载成功且大小限制允许时,Slack 可以将下载的媒体附加到智能体回合。图像文件可以通过媒体理解路径传递,或直接传递给具备视觉能力的回复模型;其他文件会保留为可下载的文件上下文,而不是作为图像输入处理。 +当 Slack 文件下载成功且大小限制允许时,Slack 可以将下载的媒体附加到智能体轮次。图像文件可以通过媒体理解路径传递,或直接传给支持视觉的回复模型;其他文件会作为可下载文件上下文保留,而不是被当作图像输入。 ### 支持的媒体类型 -| 媒体类型 | 来源 | 当前行为 | 备注 | -| ------------------------------ | -------------------- | ------------------------------------------------------------------------------------- | ------------------------------------------------------------------------ | -| JPEG / PNG / GIF / WebP 图像 | Slack 文件 URL | 已下载并附加到该轮次,以便支持视觉的处理 | 单文件上限:`channels.slack.mediaMaxMb`(默认 20 MB) | -| PDF 文件 | Slack 文件 URL | 已下载并作为文件上下文暴露给 `download-file` 或 `pdf` 等工具 | Slack 入站不会自动将 PDF 转换为图像视觉输入 | -| 其他文件 | Slack 文件 URL | 可行时下载并作为文件上下文暴露 | 二进制文件不会被视为图像输入 | -| 线程回复 | 线程起始消息文件 | 当回复没有直接媒体时,根消息文件可以作为上下文补齐 | 仅包含文件的起始消息使用附件占位符 | -| 多图像消息 | 多个 Slack 文件 | 每个文件都会独立评估 | Slack 处理限制为每条消息最多八个文件 | +| 媒体类型 | 来源 | 当前行为 | 备注 | +| ------------------------------ | -------------------- | --------------------------------------------------------------------------------- | ------------------------------------------------------------------------- | +| JPEG / PNG / GIF / WebP 图像 | Slack 文件 URL | 下载并附加到该轮次,以供支持视觉的处理使用 | 每文件上限:`channels.slack.mediaMaxMb`(默认 20 MB) | +| PDF 文件 | Slack 文件 URL | 下载并作为文件上下文暴露给 `download-file` 或 `pdf` 等工具 | Slack 入站流程不会自动将 PDF 转换为图像视觉输入 | +| 其他文件 | Slack 文件 URL | 可行时下载并作为文件上下文暴露 | 二进制文件不会被当作图像输入 | +| 线程回复 | 线程起始消息文件 | 当回复没有直接媒体时,根消息文件可作为上下文补全 | 只有文件的起始消息会使用附件占位符 | +| 多图像消息 | 多个 Slack 文件 | 每个文件都会独立评估 | Slack 处理限制为每条消息最多八个文件 | ### 入站流水线 @@ -1024,68 +1297,68 @@ openclaw pairing list slack 2. 下载成功后,文件会写入媒体存储。 3. 下载的媒体路径和内容类型会添加到入站上下文。 4. 支持图像的模型/工具路径可以使用该上下文中的图像附件。 -5. 非图像文件仍会作为文件元数据或媒体引用,供能够处理它们的工具使用。 +5. 非图像文件仍可作为文件元数据或媒体引用供可以处理它们的工具使用。 ### 线程根附件继承 -当消息到达某个线程中(具有 `thread_ts` 父级)时: +当消息在线程中到达(具有 `thread_ts` 父项)时: -- 如果回复本身没有直接媒体,而包含的根消息有文件,Slack 可以将根文件补齐为线程起始消息上下文。 +- 如果回复本身没有直接媒体,而包含的根消息有文件,Slack 可以将根文件补全为线程起始上下文。 - 直接回复附件优先于根消息附件。 -- 只有文件且没有文本的根消息会用附件占位符表示,这样回退仍能包含其文件。 +- 只有文件且没有文本的根消息会以附件占位符表示,以便回退内容仍可包含其文件。 ### 多附件处理 当单条 Slack 消息包含多个文件附件时: - 每个附件都会通过媒体流水线独立处理。 -- 已下载的媒体引用会聚合到消息上下文中。 -- 处理顺序遵循事件载荷中的 Slack 文件顺序。 +- 下载的媒体引用会聚合到消息上下文中。 +- 处理顺序遵循事件载荷中 Slack 的文件顺序。 - 某个附件下载失败不会阻塞其他附件。 ### 大小、下载和模型限制 -- **大小上限**:默认每个文件 20 MB。可通过 `channels.slack.mediaMaxMb` 配置。 -- **下载失败**:Slack 无法提供的文件、过期 URL、无法访问的文件、超大文件以及 Slack 凭证/登录 HTML 响应会被跳过,而不是报告为不支持的格式。 -- **视觉模型**:图像分析会使用支持视觉的当前回复模型,或使用在 `agents.defaults.imageModel` 配置的图像模型。 +- **大小上限**:默认每文件 20 MB。可通过 `channels.slack.mediaMaxMb` 配置。 +- **下载失败**:Slack 无法提供的文件、过期 URL、不可访问文件、超大文件,以及 Slack 身份验证/登录 HTML 响应会被跳过,而不会被报告为不受支持的格式。 +- **视觉模型**:图像分析会在当前回复模型支持视觉时使用该模型,否则使用在 `agents.defaults.imageModel` 配置的图像模型。 ### 已知限制 -| 场景 | 当前行为 | 解决方法 | -| -------------------------------------- | ------------------------------------------------------------------------ | ------------------------------------------------------------------------ | -| 过期的 Slack 文件 URL | 文件被跳过;不会显示错误 | 在 Slack 中重新上传文件 | -| 未配置视觉模型 | 图像附件会存储为媒体引用,但不会作为图像分析 | 配置 `agents.defaults.imageModel` 或使用支持视觉的回复模型 | -| 非常大的图像(默认 > 20 MB) | 按大小上限跳过 | 如果 Slack 允许,增大 `channels.slack.mediaMaxMb` | -| 转发/共享的附件 | 文本以及由 Slack 托管的图像/文件媒体会尽力处理 | 直接在 OpenClaw 线程中重新共享 | -| PDF 附件 | 存储为文件/媒体上下文,不会自动通过图像视觉处理 | 使用 `download-file` 获取文件元数据,或使用 `pdf` 工具分析 PDF | +| 场景 | 当前行为 | 解决方法 | +| -------------------------------------- | ---------------------------------------------------------------------------- | -------------------------------------------------------------------------- | +| 已过期的 Slack 文件 URL | 文件被跳过;不显示错误 | 在 Slack 中重新上传该文件 | +| 未配置视觉模型 | 图片附件会作为媒体引用存储,但不会作为图片分析 | 配置 `agents.defaults.imageModel`,或使用支持视觉的回复模型 | +| 超大图片(默认 > 20 MB) | 按大小上限跳过 | 如果 Slack 允许,增加 `channels.slack.mediaMaxMb` | +| 转发/共享的附件 | 文本和 Slack 托管的图片/文件媒体会尽力处理 | 直接在 OpenClaw 线程中重新共享 | +| PDF 附件 | 作为文件/媒体上下文存储,不会自动路由到图片视觉处理 | 使用 `download-file` 获取文件元数据,或使用 `pdf` 工具进行 PDF 分析 | ### 相关文档 - [媒体理解流水线](/zh-CN/nodes/media-understanding) - [PDF 工具](/zh-CN/tools/pdf) -- Epic:[#51349](https://github.com/openclaw/openclaw/issues/51349) — Slack 附件视觉启用 -- 回归测试:[#51353](https://github.com/openclaw/openclaw/issues/51353) -- 实时验证:[#51354](https://github.com/openclaw/openclaw/issues/51354) +- Epic: [#51349](https://github.com/openclaw/openclaw/issues/51349) — Slack 附件视觉启用 +- 回归测试: [#51353](https://github.com/openclaw/openclaw/issues/51353) +- 实时验证: [#51354](https://github.com/openclaw/openclaw/issues/51354) -## 相关 +## 相关内容 - + 将 Slack 用户与 Gateway 网关配对。 - + 渠道和群组私信行为。 - + 将入站消息路由到智能体。 - + 威胁模型和加固。 - + 配置布局和优先级。 - + 命令目录和行为。 diff --git a/docs/zh-CN/cli/doctor.md b/docs/zh-CN/cli/doctor.md index ec292ec03..8cc2120bb 100644 --- a/docs/zh-CN/cli/doctor.md +++ b/docs/zh-CN/cli/doctor.md @@ -1,21 +1,21 @@ --- read_when: - - 你遇到连接或凭证问题,并希望获得引导式修复 - - 你已更新,想做一次完整性检查 + - 你遇到连接/身份验证问题,并希望获得引导式修复 + - 你已更新并想做一次完整性检查 summary: '`openclaw doctor` 的 CLI 参考(健康检查 + 引导式修复)' title: Doctor x-i18n: - generated_at: "2026-05-03T21:48:58Z" + generated_at: "2026-05-05T01:21:13Z" model: gpt-5.5 provider: openai - source_hash: cd7fb09d373c313e4be45ad9e3b19ceb187a5787ef3e70fcd2b1f1f01b50c905 + source_hash: 079d7674ae2a259a0430e30e7577ac532135ad5461c57c4b3a6514a007bc9ea5 source_path: cli/doctor.md workflow: 16 --- # `openclaw doctor` -针对 Gateway 网关和渠道的健康检查 + 快速修复。 +Gateway 网关和渠道的健康检查 + 快速修复。 相关: @@ -36,43 +36,43 @@ openclaw doctor --generate-gateway-token - `--no-workspace-suggestions`:禁用工作区记忆/搜索建议 - `--yes`:不提示,接受默认值 -- `--repair`:不提示地应用推荐的非服务修复;Gateway 网关服务安装和重写仍需要交互式确认或显式 Gateway 网关命令 +- `--repair`:不提示,应用推荐的非服务修复;Gateway 网关服务安装和重写仍需要交互式确认或显式 Gateway 网关命令 - `--fix`:`--repair` 的别名 - `--force`:应用激进修复,包括在需要时覆盖自定义服务配置 -- `--non-interactive`:无提示运行;仅执行安全迁移和非服务修复 +- `--non-interactive`:不显示提示运行;仅执行安全迁移和非服务修复 - `--generate-gateway-token`:生成并配置 Gateway 网关令牌 -- `--deep`:扫描系统服务,查找额外的 Gateway 网关安装 +- `--deep`:扫描系统服务以查找额外的 Gateway 网关安装 -注意: +注意事项: -- 交互式提示(如 keychain/OAuth 修复)只会在 stdin 是 TTY 且**未**设置 `--non-interactive` 时运行。无头运行(cron、Telegram、无终端)会跳过提示。 -- 性能:非交互式 `doctor` 运行会跳过预先加载插件,因此无头健康检查保持快速。交互式会话在检查需要插件参与时仍会完整加载插件。 -- `--fix`(`--repair` 的别名)会将备份写入 `~/.openclaw/openclaw.json.bak`,并删除未知配置键,同时列出每项删除。 -- `doctor --fix --non-interactive` 会报告缺失或过期的 Gateway 网关服务定义,但不会在更新修复模式之外安装或重写它们。服务缺失时运行 `openclaw gateway install`;如果你有意替换启动器,则运行 `openclaw gateway install --force`。 -- 状态完整性检查现在会检测会话目录中的孤立转录文件。将它们归档为 `.deleted.` 需要交互式确认;`--fix`、`--yes` 和无头运行会将它们留在原处。 -- Doctor 还会扫描 `~/.openclaw/cron/jobs.json`(或 `cron.store`)中的旧版 cron 任务形态,并可在调度器必须在运行时自动规范化它们之前就地重写它们。 -- 在 Linux 上,当用户的 crontab 仍运行旧版 `~/.openclaw/bin/ensure-whatsapp.sh` 时,Doctor 会发出警告;该脚本已不再维护,并且在 cron 缺少 systemd 用户总线环境时,可能记录错误的 WhatsApp Gateway 网关故障。 -- Doctor 会清理旧版 OpenClaw 创建的旧版插件依赖暂存状态。它还会在注册表可以解析缺失的已配置可下载插件时修复它们,并且 2026.5.2 的 Doctor 检查会在将配置标记为该版本已触碰之前,自动安装旧配置已在使用的可下载插件。如果下载失败,Doctor 会报告安装错误,并保留已配置的插件条目,以便下次修复尝试。 -- Doctor 会通过从 `plugins.allow`/`plugins.entries` 移除缺失的插件 ID,并在插件发现正常时移除匹配的悬空渠道配置、Heartbeat 目标和渠道模型覆盖,来修复过期插件配置。 -- Doctor 会通过禁用受影响的 `plugins.entries.` 条目并移除其无效的 `config` 载荷,来隔离无效插件配置。Gateway 网关启动时已经只会跳过该坏插件,因此其他插件和渠道可以继续运行。 -- 当另一个 supervisor 管理 Gateway 网关生命周期时,设置 `OPENCLAW_SERVICE_REPAIR_POLICY=external`。Doctor 仍会报告 Gateway 网关/服务健康状态并应用非服务修复,但会跳过服务安装/启动/重启/bootstrap 和旧版服务清理。 -- 在 Linux 上,Doctor 会忽略非活动的额外类 Gateway 网关 systemd unit,并且在修复期间不会重写正在运行的 systemd Gateway 网关服务的命令/入口点元数据。如果你有意替换活动启动器,请先停止该服务,或使用 `openclaw gateway install --force`。 +- 交互式提示(例如钥匙串/OAuth 修复)仅在 stdin 是 TTY 且**未**设置 `--non-interactive` 时运行。无头运行(cron、Telegram、无终端)会跳过提示。 +- 性能:非交互式 `doctor` 运行会跳过预先加载插件,因此无头健康检查能保持快速。交互式会话在检查需要插件贡献时仍会完整加载插件。 +- `--fix`(`--repair` 的别名)会将备份写入 `~/.openclaw/openclaw.json.bak`,并删除未知配置键,同时列出每一项删除。 +- `doctor --fix --non-interactive` 会报告缺失或过期的 Gateway 网关服务定义,但不会在更新修复模式之外安装或重写它们。对于缺失的服务,请运行 `openclaw gateway install`;如果你有意替换启动器,请运行 `openclaw gateway install --force`。 +- 状态完整性检查现在会检测会话目录中的孤立转录文件。将它们归档为 `.deleted.` 需要交互式确认;`--fix`、`--yes` 和无头运行会保留它们不变。 +- Doctor 还会扫描 `~/.openclaw/cron/jobs.json`(或 `cron.store`)中的旧版 cron 任务形态,并可在调度器必须在运行时自动规范化它们之前就地重写。 +- 在 Linux 上,当用户的 crontab 仍运行旧版 `~/.openclaw/bin/ensure-whatsapp.sh` 时,Doctor 会发出警告;该脚本不再维护,并且在 cron 缺少 systemd 用户总线环境时可能记录虚假的 WhatsApp Gateway 网关故障。 +- Doctor 会清理由旧版 OpenClaw 创建的旧版插件依赖暂存状态。它还会修复配置引用的缺失可下载插件,例如 `plugins.entries`、已配置渠道、已配置提供商/搜索设置,或已配置 Agent Runtimes。在包更新期间,Doctor 会跳过包管理器插件修复,直到包替换完成;如果已配置插件仍需要恢复,请之后重新运行 `openclaw doctor --fix`。如果下载失败,Doctor 会报告安装错误,并保留已配置插件条目以便下一次修复尝试。 +- 当插件设备发现正常时,Doctor 会通过从 `plugins.allow`/`plugins.entries` 中移除缺失插件 ID,以及匹配的悬空渠道配置、Heartbeat 目标和渠道模型覆盖,来修复过期插件配置。 +- Doctor 会通过禁用受影响的 `plugins.entries.` 条目并移除其无效的 `config` 载荷,来隔离无效插件配置。Gateway 网关启动本来就只会跳过该故障插件,因此其他插件和渠道可以继续运行。 +- 当另一个监督器拥有 Gateway 网关生命周期时,设置 `OPENCLAW_SERVICE_REPAIR_POLICY=external`。Doctor 仍会报告 Gateway 网关/服务健康状况并应用非服务修复,但会跳过服务安装/启动/重启/bootstrap 和旧版服务清理。 +- 在 Linux 上,Doctor 会忽略不活跃的额外类 Gateway 网关 systemd 单元,并且在修复期间不会为正在运行的 systemd Gateway 网关服务重写命令/入口点元数据。如果你有意替换活动启动器,请先停止服务或使用 `openclaw gateway install --force`。 - Doctor 会将旧版扁平 Talk 配置(`talk.voiceId`、`talk.modelId` 及相关项)自动迁移到 `talk.provider` + `talk.providers.`。 - 当唯一差异是对象键顺序时,重复运行 `doctor --fix` 不再报告/应用 Talk 规范化。 -- Doctor 包含记忆搜索就绪检查,并且可在缺少嵌入凭证时推荐 `openclaw configure --section model`。 -- 未配置命令所有者时,Doctor 会发出警告。命令所有者是允许运行仅所有者命令并批准危险操作的人类操作员账号。私信配对只允许某人与机器人对话;如果你在首个所有者 bootstrap 存在之前批准过发送者,请显式设置 `commands.ownerAllowFrom`。 -- 当配置了 Codex 模式智能体,并且操作员的 Codex 主目录中存在个人 Codex CLI 资产时,Doctor 会发出警告。本地 Codex 应用服务器启动会使用隔离的逐智能体主目录,因此请使用 `openclaw migrate codex --dry-run` 来盘点应被有意提升的资产。 -- 当默认智能体允许的 Skills 因缺少可执行文件、环境变量、配置或 OS 要求而在当前运行时环境中不可用时,Doctor 会发出警告。`doctor --fix` 可以通过 `skills.entries..enabled=false` 禁用这些不可用的 Skills;如果你想保持该 Skill 启用,请改为安装/配置缺失的要求。 -- 如果启用了沙箱模式但 Docker 不可用,Doctor 会报告高信号警告并附带修复建议(`install Docker` 或 `openclaw config set agents.defaults.sandbox.mode off`)。 -- 如果存在旧版沙箱注册表文件(`~/.openclaw/sandbox/containers.json` 或 `~/.openclaw/sandbox/browsers.json`),Doctor 会报告它们;`openclaw doctor --fix` 会将有效条目迁移到分片注册表目录,并隔离无效的旧版文件。 -- 如果 `gateway.auth.token`/`gateway.auth.password` 由 SecretRef 管理且在当前命令路径中不可用,Doctor 会报告只读警告,并且不会写入明文后备凭证。 -- 如果在修复路径中检查渠道 SecretRef 失败,Doctor 会继续并报告警告,而不是提前退出。 -- 状态目录迁移后,当已启用的默认 Telegram 或 Discord 账号依赖环境变量回退,而 `TELEGRAM_BOT_TOKEN` 或 `DISCORD_BOT_TOKEN` 对 Doctor 进程不可用时,Doctor 会发出警告。 -- Telegram `allowFrom` 用户名自动解析(`doctor --fix`)需要当前命令路径中有可解析的 Telegram 令牌。如果令牌检查不可用,Doctor 会报告警告,并跳过本次自动解析。 +- Doctor 包含记忆搜索就绪性检查,并可在缺少嵌入凭据时推荐 `openclaw configure --section model`。 +- 当未配置命令所有者时,Doctor 会发出警告。命令所有者是允许运行仅限所有者命令并批准危险操作的人类操作员账户。私信配对只允许某人与机器人对话;如果你在首位所有者 bootstrap 存在之前批准过发送者,请显式设置 `commands.ownerAllowFrom`。 +- 当配置了 Codex 模式智能体,并且操作员的 Codex 主目录中存在个人 Codex CLI 资产时,Doctor 会发出警告。本地 Codex 应用服务器启动会使用隔离的逐智能体主目录,因此请使用 `openclaw migrate codex --dry-run` 清点应有意提升的资产。 +- 当默认智能体允许的 Skills 在当前运行时环境中不可用时,Doctor 会发出警告,原因可能是缺少二进制文件、环境变量、配置或 OS 要求。`doctor --fix` 可以通过 `skills.entries..enabled=false` 禁用这些不可用 Skills;如果你想保持该 Skills 活跃,请改为安装/配置缺失要求。 +- 如果启用了沙箱模式但 Docker 不可用,Doctor 会报告高信号警告并附带修复方式(`install Docker` 或 `openclaw config set agents.defaults.sandbox.mode off`)。 +- 如果存在旧版沙箱注册表文件(`~/.openclaw/sandbox/containers.json` 或 `~/.openclaw/sandbox/browsers.json`),Doctor 会报告它们;`openclaw doctor --fix` 会将有效条目迁移到分片注册表目录,并隔离无效旧版文件。 +- 如果 `gateway.auth.token`/`gateway.auth.password` 由 SecretRef 管理且在当前命令路径中不可用,Doctor 会报告只读警告,并且不会写入明文后备凭据。 +- 如果渠道 SecretRef 检查在修复路径中失败,Doctor 会继续运行并报告警告,而不是提前退出。 +- 状态目录迁移后,当已启用的默认 Telegram 或 Discord 账户依赖环境回退,而 `TELEGRAM_BOT_TOKEN` 或 `DISCORD_BOT_TOKEN` 对 Doctor 进程不可用时,Doctor 会发出警告。 +- Telegram `allowFrom` 用户名自动解析(`doctor --fix`)要求当前命令路径中有可解析的 Telegram 令牌。如果令牌检查不可用,Doctor 会报告警告并在该轮跳过自动解析。 ## macOS:`launchctl` 环境覆盖 -如果你之前运行过 `launchctl setenv OPENCLAW_GATEWAY_TOKEN ...`(或 `...PASSWORD`),该值会覆盖你的配置文件,并可能导致持久的“未授权”错误。 +如果你之前运行过 `launchctl setenv OPENCLAW_GATEWAY_TOKEN ...`(或 `...PASSWORD`),该值会覆盖你的配置文件,并可能导致持续的“unauthorized”错误。 ```bash launchctl getenv OPENCLAW_GATEWAY_TOKEN diff --git a/docs/zh-CN/cli/plugins.md b/docs/zh-CN/cli/plugins.md index c45b39902..0a9105956 100644 --- a/docs/zh-CN/cli/plugins.md +++ b/docs/zh-CN/cli/plugins.md @@ -1,33 +1,33 @@ --- read_when: - - 你想安装或管理 Gateway 网关插件或兼容包 - - 你想调试插件加载失败问题 + - 你想安装或管理 Gateway 网关插件或兼容捆绑包 + - 你想调试插件加载失败 sidebarTitle: Plugins summary: '`openclaw plugins` 的 CLI 参考(list、install、marketplace、uninstall、enable/disable、doctor)' title: 插件 x-i18n: - generated_at: "2026-05-04T09:22:18Z" + generated_at: "2026-05-05T01:21:18Z" model: gpt-5.5 provider: openai - source_hash: f561ce098181b07f25db3520b1726162863469ac05fb4a3e786915257d97c9a4 + source_hash: 24d274f33213231eaed48ac848a9266802a2179ba0311ab18462ad783219095a source_path: cli/plugins.md workflow: 16 --- -管理 Gateway 网关插件、钩子包和兼容包。 +管理 Gateway 网关插件、钩子包和兼容捆绑包。 - 用于安装、启用插件以及排查插件问题的最终用户指南。 + 安装、启用插件以及排查插件问题的终端用户指南。 安装、列出、更新、卸载和发布的快速示例。 - - 包兼容性模型。 + + 捆绑包兼容性模型。 - 清单字段和配置 schema。 + 清单字段和配置架构。 插件安装的安全加固。 @@ -62,14 +62,14 @@ openclaw plugins marketplace list openclaw plugins marketplace list --json ``` -如需调查缓慢的安装、检查、卸载或注册表刷新,请使用 `OPENCLAW_PLUGIN_LIFECYCLE_TRACE=1` 运行该命令。trace 会将阶段耗时写入 stderr,并保持 JSON 输出可解析。请参阅[调试](/zh-CN/help/debugging#plugin-lifecycle-trace)。 +若要调查缓慢的安装、检查、卸载或注册表刷新,请使用 `OPENCLAW_PLUGIN_LIFECYCLE_TRACE=1` 运行该命令。跟踪会将阶段耗时写入 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`。详细的 list/info 输出还会显示包子类型(`codex`、`claude` 或 `cursor`)以及检测到的包能力。 +`plugins list` 会显示 `Format: openclaw` 或 `Format: bundle`。详细列表/info 输出还会显示捆绑包子类型(`codex`、`claude` 或 `cursor`)以及检测到的捆绑包能力。 ### 安装 @@ -91,61 +91,61 @@ openclaw plugins install --marketplace https://github.com// -在发布切换期间,裸包名默认从 npm 安装。对 ClawHub 使用 `clawhub:`。应像运行代码一样看待插件安装。优先使用固定版本。 +在发布切换期间,裸包名默认从 npm 安装。对 ClawHub 使用 `clawhub:`。应像运行代码一样对待插件安装。优先使用固定版本。 -`plugins search` 会查询 ClawHub 中可安装的插件包,并打印可直接用于安装的包名。它搜索代码插件和包插件的软件包,而不是 Skills。使用 `openclaw skills search` 搜索 ClawHub Skills。 +`plugins search` 会查询 ClawHub 中可安装的插件包,并打印可直接安装的包名。它搜索代码插件和捆绑包插件包,而不是 Skills。对 ClawHub Skills 使用 `openclaw skills search`。 -ClawHub 是大多数插件的主要分发和发现界面。Npm 仍是受支持的回退和直接安装路径。OpenClaw 拥有的 `@openclaw/*` 插件包已重新发布到 npm;请在 [npmjs.com/org/openclaw](https://www.npmjs.com/org/openclaw) 或[插件清单](/zh-CN/plugins/plugin-inventory)查看当前列表。稳定安装使用 `latest`。当 npm `beta` dist-tag 可用时,Beta 频道的安装和更新优先使用该标签,然后回退到 `latest`。 +ClawHub 是大多数插件的主要分发和发现界面。Npm 仍然是受支持的回退和直接安装路径。OpenClaw 自有的 `@openclaw/*` 插件包已重新发布到 npm;请在 [npmjs.com/org/openclaw](https://www.npmjs.com/org/openclaw) 或[插件清单](/zh-CN/plugins/plugin-inventory)查看当前列表。稳定安装使用 `latest`。Beta 频道安装和更新会在 npm `beta` dist-tag 可用时优先使用该标签,然后回退到 `latest`。 - - 如果你的 `plugins` 部分由单文件 `$include` 支持,`plugins install/update/enable/disable/uninstall` 会写入该被包含文件,并保持 `openclaw.json` 不变。根 include、include 数组以及带同级覆盖的 include 会失败关闭,而不是被扁平化。请参阅[配置 include](/zh-CN/gateway/configuration)了解受支持的形状。 + + 如果你的 `plugins` 部分由单文件 `$include` 支持,`plugins install/update/enable/disable/uninstall` 会写入该被包含文件,并保持 `openclaw.json` 不变。根 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 安装。它不支持 `git:` 安装;当你需要固定来源时,请使用显式 git ref,例如 `git:github.com/acme/plugin@v1.2.3`。它不支持 `--marketplace`,因为 marketplace 安装会持久化 marketplace 来源元数据,而不是 npm spec。 + `--pin` 仅适用于 npm 安装。它不支持 `git:` 安装;当你想固定来源时,请使用显式 git ref,例如 `git:github.com/acme/plugin@v1.2.3`。它不支持 `--marketplace`,因为 marketplace 安装会持久化 marketplace 来源元数据,而不是 npm spec。 - `--dangerously-force-unsafe-install` 是针对内置危险代码扫描器误报的应急选项。即使内置扫描器报告 `critical` 发现,它也允许安装继续,但它**不会**绕过插件 `before_install` 钩子策略阻断,也**不会**绕过扫描失败。 + `--dangerously-force-unsafe-install` 是内置危险代码扫描器误报时的应急选项。即使内置扫描器报告 `critical` 发现项,它也允许安装继续,但它**不会**绕过插件 `before_install` 钩子策略阻断,也**不会**绕过扫描失败。 - 此 CLI 标志适用于插件安装/更新流程。由 Gateway 网关支持的 skill 依赖安装使用匹配的 `dangerouslyForceUnsafeInstall` 请求覆盖,而 `openclaw skills install` 仍是单独的 ClawHub skill 下载/安装流程。 + 此 CLI 标志适用于插件安装/更新流程。由 Gateway 网关支持的 Skill 依赖安装使用匹配的 `dangerouslyForceUnsafeInstall` 请求覆盖,而 `openclaw skills install` 仍然是单独的 ClawHub Skill 下载/安装流程。 - 如果你发布在 ClawHub 上的插件被注册表扫描阻断,请使用 [ClawHub](/zh-CN/tools/clawhub) 中的发布者步骤。 + 如果你在 ClawHub 上发布的插件被注册表扫描阻断,请使用 [ClawHub](/zh-CN/tools/clawhub) 中的发布者步骤。 - - `plugins install` 也是安装在 `package.json` 中暴露 `openclaw.hooks` 的钩子包的入口。使用 `openclaw hooks` 查看经过过滤的钩子可见性和逐钩子启用,不用于软件包安装。 + + `plugins install` 也是安装在 `package.json` 中公开 `openclaw.hooks` 的钩子包的入口。使用 `openclaw hooks` 查看筛选后的钩子可见性和按钩子启用,而不是用于包安装。 - Npm specs 是**仅注册表**形式(包名 + 可选的**精确版本**或 **dist-tag**)。Git/URL/file specs 和 semver 范围会被拒绝。为安全起见,依赖安装会以项目本地方式配合 `--ignore-scripts` 运行,即使你的 shell 设置了全局 npm 安装设置也是如此。 + Npm spec **仅限注册表**(包名 + 可选的**精确版本**或 **dist-tag**)。Git/URL/file spec 和 semver 范围会被拒绝。为安全起见,依赖安装会使用 `--ignore-scripts` 在项目本地运行,即使你的 shell 有全局 npm 安装设置也是如此。 - 当你想明确使用 npm 解析时,请使用 `npm:`。在发布切换期间,裸包 specs 也会直接从 npm 安装。 + 当你想明确使用 npm 解析时,使用 `npm:`。在发布切换期间,裸包 spec 也会直接从 npm 安装。 - 裸 specs 和 `@latest` 会停留在稳定轨道。OpenClaw 日期戳修正版(例如 `2026.5.3-1`)在此检查中属于稳定版本。如果 npm 将其中任一解析为预发布版本,OpenClaw 会停止,并要求你使用预发布标签(例如 `@beta`/`@rc`)或精确的预发布版本(例如 `@1.2.3-beta.4`)显式选择加入。 + 裸 spec 和 `@latest` 会停留在稳定轨道上。OpenClaw 日期标记的修正版,例如 `2026.5.3-1`,在此检查中是稳定发布。如果 npm 将其中任一项解析为预发布版本,OpenClaw 会停止,并要求你使用预发布标签(如 `@beta`/`@rc`)或精确预发布版本(如 `@1.2.3-beta.4`)显式选择加入。 - 如果裸安装 spec 匹配官方插件 id(例如 `diffs`),OpenClaw 会直接安装目录条目。若要安装同名 npm 包,请使用显式作用域 spec(例如 `@scope/diffs`)。 + 如果裸安装 spec 匹配官方插件 id(例如 `diffs`),OpenClaw 会直接安装目录条目。若要安装同名 npm 包,请使用显式 scoped spec(例如 `@scope/diffs`)。 - 使用 `git:` 可直接从 git 仓库安装。受支持的形式包括 `git:github.com/owner/repo`、`git:owner/repo`、完整的 `https://`、`ssh://`、`git://`、`file://` 以及 `git@host:owner/repo.git` clone URL。添加 `@` 或 `#` 可在安装前检出分支、标签或提交。 + 使用 `git:` 可直接从 git 仓库安装。支持的形式包括 `git:github.com/owner/repo`、`git:owner/repo`、完整的 `https://`、`ssh://`、`git://`、`file://` 以及 `git@host:owner/repo.git` 克隆 URL。添加 `@` 或 `#` 可在安装前签出分支、标签或提交。 - Git 安装会克隆到临时目录,在存在请求的 ref 时检出它,然后使用正常的插件目录安装器。这意味着清单验证、危险代码扫描、包管理器安装工作和安装记录的行为都类似 npm 安装。记录的 git 安装包含来源 URL/ref 以及解析后的提交,因此 `openclaw plugins update` 之后可以重新解析来源。 + Git 安装会克隆到临时目录,在存在请求的 ref 时签出它,然后使用普通插件目录安装器。这意味着清单验证、危险代码扫描、包管理器安装工作和安装记录的行为与 npm 安装相同。记录的 git 安装包括来源 URL/ref 以及解析出的提交,以便 `openclaw plugins update` 后续可以重新解析该来源。 - 从 git 安装后,使用 `openclaw plugins inspect --runtime --json` 验证运行时注册,例如 gateway 方法和 CLI 命令。如果插件通过 `api.registerCli` 注册了 CLI 根命令,请直接通过 OpenClaw 根 CLI 执行该命令,例如 `openclaw demo-plugin ping`。 + 从 git 安装后,使用 `openclaw plugins inspect --runtime --json` 验证运行时注册项,例如 gateway 方法和 CLI 命令。如果插件通过 `api.registerCli` 注册了 CLI 根,请通过 OpenClaw 根 CLI 直接执行该命令,例如 `openclaw demo-plugin ping`。 - 支持的归档:`.zip`、`.tgz`、`.tar.gz`、`.tar`。原生 OpenClaw 插件归档必须在解压后的插件根目录包含有效的 `openclaw.plugin.json`;仅包含 `package.json` 的归档会在 OpenClaw 写入安装记录之前被拒绝。 + 支持的归档:`.zip`、`.tgz`、`.tar.gz`、`.tar`。原生 OpenClaw 插件归档必须在解压后的插件根目录包含有效的 `openclaw.plugin.json`;只包含 `package.json` 的归档会在 OpenClaw 写入安装记录前被拒绝。 也支持 Claude marketplace 安装。 @@ -159,32 +159,32 @@ openclaw plugins install clawhub:openclaw-codex-app-server openclaw plugins install clawhub:openclaw-codex-app-server@1.2.3 ``` -在发布切换期间,npm 安全的裸插件 specs 默认从 npm 安装: +在发布切换期间,裸 npm 安全插件 spec 默认从 npm 安装: ```bash openclaw plugins install openclaw-codex-app-server ``` -使用 `npm:` 明确仅通过 npm 解析: +使用 `npm:` 明确仅使用 npm 解析: ```bash openclaw plugins install npm:openclaw-codex-app-server openclaw plugins install npm:@scope/plugin-name@1.0.1 ``` -OpenClaw 会在安装前检查公布的插件 API / 最低 gateway 兼容性。当选定的 ClawHub 版本发布 ClawPack 构件时,OpenClaw 会下载带版本的 npm-pack `.tgz`,验证 ClawHub 摘要头和构件摘要,然后通过正常归档路径安装。没有 ClawPack 元数据的旧 ClawHub 版本仍会通过旧版包归档验证路径安装。记录的安装会保留其 ClawHub 来源元数据、构件类型、npm integrity、npm shasum、tarball 名称和 ClawPack 摘要事实,以供后续更新使用。 -未带版本的 ClawHub 安装会保留未带版本的记录 spec,以便 `openclaw plugins update` 可以跟随较新的 ClawHub 版本;显式版本或标签选择器(例如 `clawhub:pkg@1.2.3` 和 `clawhub:pkg@beta`)仍固定到该选择器。 +OpenClaw 会在安装前检查公开的插件 API / 最低 gateway 兼容性。当所选 ClawHub 版本发布 ClawPack 构件时,OpenClaw 会下载带版本的 npm-pack `.tgz`,验证 ClawHub 摘要头和构件摘要,然后通过普通归档路径安装。没有 ClawPack 元数据的旧 ClawHub 版本仍会通过旧版包归档验证路径安装。记录的安装会保留其 ClawHub 来源元数据、构件类型、npm integrity、npm shasum、tarball 名称以及 ClawPack 摘要事实,以供后续更新使用。 +未指定版本的 ClawHub 安装会保留未指定版本的记录 spec,以便 `openclaw plugins update` 可以跟随较新的 ClawHub 发布;显式版本或标签选择器(如 `clawhub:pkg@1.2.3` 和 `clawhub:pkg@beta`)仍固定到该选择器。 #### Marketplace 简写 -当 marketplace 名称存在于 Claude 位于 `~/.claude/plugins/known_marketplaces.json` 的本地注册表缓存中时,请使用 `plugin@marketplace` 简写: +当 marketplace 名称存在于 Claude 的本地注册表缓存 `~/.claude/plugins/known_marketplaces.json` 中时,使用 `plugin@marketplace` 简写: ```bash openclaw plugins marketplace list openclaw plugins install @ ``` -当你想显式传递 marketplace 来源时,请使用 `--marketplace`: +当你想显式传递 marketplace 来源时,使用 `--marketplace`: ```bash openclaw plugins install --marketplace @@ -194,20 +194,20 @@ openclaw plugins install --marketplace ./my-marketplace ``` - - - 来自 `~/.claude/plugins/known_marketplaces.json` 的 Claude 已知市场名称 - - 本地市场根目录或 `marketplace.json` 路径 + + - 来自 `~/.claude/plugins/known_marketplaces.json` 的 Claude 已知 Marketplace 名称 + - 本地 Marketplace 根目录或 `marketplace.json` 路径 - GitHub 仓库简写,例如 `owner/repo` - GitHub 仓库 URL,例如 `https://github.com/owner/repo` - git URL - - 对于从 GitHub 或 git 加载的远程市场,插件条目必须保留在克隆的市场仓库内。OpenClaw 接受来自该仓库的相对路径源,并拒绝来自远程清单的 HTTP(S)、绝对路径、git、GitHub 以及其他非路径插件源。 + + 对于从 GitHub 或 git 加载的远程 Marketplace,插件条目必须保留在克隆的 Marketplace 仓库内。OpenClaw 接受该仓库中的相对路径来源,并拒绝来自远程清单的 HTTP(S)、绝对路径、git、GitHub 以及其他非路径插件来源。 -对于本地路径和归档,OpenClaw 会自动检测: +对于本地路径和归档文件,OpenClaw 会自动检测: - 原生 OpenClaw 插件(`openclaw.plugin.json`) - Codex 兼容包(`.codex-plugin/plugin.json`) @@ -215,7 +215,7 @@ openclaw plugins install --marketplace ./my-marketplace - Cursor 兼容包(`.cursor-plugin/plugin.json`) -兼容包会安装到常规插件根目录,并参与同一套列表/信息/启用/禁用流程。目前支持包 Skills、Claude 命令 Skills、Claude `settings.json` 默认值、Claude `.lsp.json` / 清单声明的 `lspServers` 默认值、Cursor 命令 Skills,以及兼容的 Codex 钩子目录;其他检测到的包能力会显示在诊断/信息中,但尚未接入运行时执行。 +兼容包会安装到普通插件根目录,并参与同一套列表/信息/启用/禁用流程。目前支持包 Skills、Claude 命令 Skills、Claude `settings.json` 默认值、Claude `.lsp.json` / 清单声明的 `lspServers` 默认值、Cursor 命令 Skills,以及兼容的 Codex 钩子目录;其他检测到的包能力会显示在诊断/信息中,但尚未接入运行时执行。 ### 列表 @@ -234,40 +234,40 @@ openclaw plugins search --json 仅显示已启用的插件。 - 从表格视图切换为每个插件的详细行,包含源/来源/版本/激活元数据。 + 从表格视图切换为按插件显示的详情行,包含来源/原点/版本/激活元数据。 机器可读的清单,以及注册表诊断和包依赖安装状态。 -`plugins list` 会先读取持久化的本地插件注册表;当注册表缺失或无效时,回退到仅由清单派生的结果。它适合检查某个插件是否已安装、已启用,并且对冷启动规划可见,但它不是对已经运行的 Gateway 网关进程的实时运行时探测。更改插件代码、启用状态、钩子策略或 `plugins.load.paths` 后,请重启为该渠道提供服务的 Gateway 网关,然后再期望新的 `register(api)` 代码或钩子运行。对于远程/容器部署,请确认你重启的是实际的 `openclaw gateway run` 子进程,而不仅是包装进程。 +`plugins list` 会先读取持久化的本地插件注册表;当注册表缺失或无效时,回退到仅基于清单派生的结果。它适合检查某个插件是否已安装、已启用并且对冷启动规划可见,但它不是对已经运行的 Gateway 网关进程的实时运行时探测。更改插件代码、启用状态、钩子策略或 `plugins.load.paths` 后,需要重启为该渠道提供服务的 Gateway 网关,才能期待新的 `register(api)` 代码或钩子运行。对于远程/容器部署,请确认你重启的是实际的 `openclaw gateway run` 子进程,而不只是包装器进程。 -`plugins list --json` 会包含每个插件来自 `package.json` +`plugins list --json` 包含每个插件来自 `package.json` `dependencies` 和 `optionalDependencies` 的 `dependencyStatus`。OpenClaw 会检查这些包 -名称是否存在于该插件正常的 Node `node_modules` 查找路径上;它 -不会导入插件运行时代码、运行包管理器或修复缺失的 +名称是否存在于插件正常的 Node `node_modules` 查找路径中;它 +不会导入插件运行时代码、运行包管理器,也不会修复缺失的 依赖。 `plugins search` 是远程 ClawHub 目录查询。它不会检查本地 -状态、变更配置、安装包或加载插件运行时代码。搜索 -结果包含 ClawHub 包名称、系列、渠道、版本、摘要,以及 +状态、修改配置、安装包或加载插件运行时代码。搜索 +结果包含 ClawHub 包名、系列、渠道、版本、摘要,以及 类似 `openclaw plugins install clawhub:` 的安装提示。 -对于打包 Docker 镜像内的内置插件工作,请将插件 +对于打包 Docker 镜像中的内置插件工作,请将插件 源目录绑定挂载到匹配的打包源路径上,例如 `/app/extensions/synology-chat`。OpenClaw 会先发现该挂载的源 -覆盖层,再发现 `/app/dist/extensions/synology-chat`;普通复制的源 -目录会保持惰性,因此正常的打包安装仍会使用编译后的 dist。 +覆盖层,然后才是 `/app/dist/extensions/synology-chat`;普通复制的源 +目录仍保持惰性,因此正常打包安装仍使用已编译的 dist。 对于运行时钩子调试: -- `openclaw plugins inspect --runtime --json` 会显示来自模块加载检查过程的已注册钩子和诊断。运行时检查绝不会安装依赖;使用 `openclaw doctor --fix` 清理旧版依赖状态,或安装缺失的已配置可下载插件。 +- `openclaw plugins inspect --runtime --json` 会显示来自模块加载检查过程的已注册钩子和诊断。运行时检查从不安装依赖;请使用 `openclaw doctor --fix` 清理旧版依赖状态,或恢复配置中引用的、缺失的可下载插件。 - `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`): +使用 `--link` 避免复制本地目录(添加到 `plugins.load.paths`): ```bash openclaw plugins install -l ./my-plugin @@ -276,14 +276,14 @@ openclaw plugins install -l ./my-plugin `--force` 不支持与 `--link` 一起使用,因为链接安装会复用源路径,而不是复制覆盖托管安装目标。 -在 npm 安装时使用 `--pin`,可将解析出的精确规格(`name@version`)保存到托管插件索引中,同时保持默认行为不固定版本。 +在 npm 安装上使用 `--pin`,可将解析后的精确规格(`name@version`)保存到托管插件索引,同时保持默认行为不固定。 ### 插件索引 -插件安装元数据是机器管理的状态,而不是用户配置。安装和更新会将其写入活动 OpenClaw 状态目录下的 `plugins/installs.json`。其顶层 `installRecords` 映射是安装元数据的持久来源,包括损坏或缺失插件清单的记录。`plugins` 数组是由清单派生的冷注册表缓存。该文件包含不要编辑的警告,并由 `openclaw plugins update`、卸载、诊断以及冷插件注册表使用。 +插件安装元数据是机器管理的状态,不是用户配置。安装和更新会将其写入活动 OpenClaw 状态目录下的 `plugins/installs.json`。其顶层 `installRecords` 映射是安装元数据的持久来源,包括损坏或缺失插件清单的记录。`plugins` 数组是清单派生的冷注册表缓存。该文件包含不要编辑的警告,并由 `openclaw plugins update`、卸载、诊断和冷插件注册表使用。 -当 OpenClaw 在配置中看到已发布的旧版 `plugins.installs` 记录时,会将它们移动到插件索引中并移除该配置键;如果任一写入失败,配置记录会被保留,以免安装元数据丢失。 +当 OpenClaw 在配置中看到已发布的旧版 `plugins.installs` 记录时,会将它们移入插件索引并移除该配置键;如果任一写入失败,则保留配置记录,以免安装元数据丢失。 ### 卸载 @@ -293,10 +293,10 @@ openclaw plugins uninstall --dry-run openclaw plugins uninstall --keep-files ``` -`uninstall` 会从 `plugins.entries`、持久化插件索引、插件允许/拒绝列表条目,以及适用时的已链接 `plugins.load.paths` 条目中移除插件记录。除非设置了 `--keep-files`,卸载还会在跟踪的托管安装目录位于 OpenClaw 插件扩展根目录内时将其移除。对于主动记忆插件,记忆槽会重置为 `memory-core`。 +`uninstall` 会从 `plugins.entries`、持久化插件索引、插件允许/拒绝列表条目,以及适用时的链接 `plugins.load.paths` 条目中移除插件记录。除非设置了 `--keep-files`,否则卸载还会在跟踪的托管安装目录位于 OpenClaw 插件扩展根目录内时移除该目录。对于主动记忆插件,记忆插槽会重置为 `memory-core`。 -`--keep-config` 作为 `--keep-files` 的已弃用别名仍受支持。 +`--keep-config` 作为 `--keep-files` 的弃用别名受支持。 ### 更新 @@ -309,29 +309,29 @@ openclaw plugins update @openclaw/voice-call openclaw plugins update openclaw-codex-app-server --dangerously-force-unsafe-install ``` -更新适用于托管插件索引中跟踪的插件安装,以及 `hooks.internal.installs` 中跟踪的钩子包安装。 +更新会应用于托管插件索引中跟踪的插件安装,以及 `hooks.internal.installs` 中跟踪的钩子包安装。 - 当你传入插件 id 时,OpenClaw 会复用该插件记录的安装规格。这意味着之前存储的 dist-tag(例如 `@beta`)和精确固定版本会在之后运行 `update ` 时继续使用。 + 当你传入插件 id 时,OpenClaw 会复用该插件记录的安装规格。这意味着之前存储的 dist-tag(例如 `@beta`)以及精确固定版本会在后续 `update ` 运行中继续使用。 - 对于 npm 安装,你也可以传入带有 dist-tag 或精确版本的显式 npm 包规格。OpenClaw 会将该包名解析回已跟踪的插件记录,更新该已安装插件,并记录新的 npm 规格以供未来基于 id 的更新使用。 + 对于 npm 安装,你也可以传入带有 dist-tag 或精确版本的显式 npm 包规格。OpenClaw 会将该包名解析回跟踪的插件记录,更新该已安装插件,并记录新的 npm 规格以供未来基于 id 的更新使用。 - 传入不带版本或标签的 npm 包名,也会解析回已跟踪的插件记录。当插件已固定到精确版本,而你想将它移回注册表默认发布线时,请使用这种方式。 + 传入不带版本或标签的 npm 包名也会解析回跟踪的插件记录。当某个插件已固定到精确版本,而你想将它移回注册表默认发布线时,请使用这种方式。 - `openclaw plugins update` 会复用已跟踪的插件规格,除非你传入新的规格。`openclaw update` 还知道活动的 OpenClaw 更新渠道:在 beta 渠道上,默认线 npm 和 ClawHub 插件记录会先尝试 `@beta`,如果没有插件 beta 版本,再回退到记录的默认/latest 规格。精确版本和显式标签会继续固定到该选择器。 + `openclaw plugins update` 会复用跟踪的插件规格,除非你传入新的规格。`openclaw update` 还知道活动的 OpenClaw 更新渠道:在 beta 渠道上,默认线 npm 和 ClawHub 插件记录会先尝试 `@beta`,如果不存在插件 beta 版本,再回退到记录的默认/latest 规格。精确版本和显式标签会继续固定到该选择器。 - 在实时 npm 更新之前,OpenClaw 会根据 npm 注册表元数据检查已安装的包版本。如果已安装版本和记录的构件标识已经与解析目标匹配,则会跳过更新,不下载、不重新安装,也不重写 `openclaw.json`。 + 在实时 npm 更新之前,OpenClaw 会对照 npm 注册表元数据检查已安装的包版本。如果已安装版本和记录的构件身份已经与解析出的目标匹配,则会跳过更新,不下载、不重新安装,也不重写 `openclaw.json`。 - 当存在已存储的完整性哈希,且获取到的构件哈希发生变化时,OpenClaw 会将其视为 npm 构件漂移。交互式 `openclaw plugins update` 命令会打印预期哈希和实际哈希,并在继续前请求确认。非交互式更新辅助工具会默认关闭失败,除非调用方提供显式的继续策略。 + 当存在已存储的完整性哈希且获取到的构件哈希发生变化时,OpenClaw 会将其视为 npm 构件漂移。交互式 `openclaw plugins update` 命令会打印预期和实际哈希,并在继续前要求确认。非交互式更新助手默认关闭失败,除非调用方提供显式继续策略。 - `--dangerously-force-unsafe-install` 也可用于 `plugins update`,作为插件更新期间内置危险代码扫描误报的破窗覆盖项。它仍然不会绕过插件 `before_install` 策略阻断或扫描失败阻断,并且只适用于插件更新,不适用于钩子包更新。 + `--dangerously-force-unsafe-install` 也可用于 `plugins update`,作为插件更新期间内置危险代码扫描误报的应急覆盖。它仍不会绕过插件 `before_install` 策略阻断或扫描失败阻断,并且只适用于插件更新,不适用于钩子包更新。 @@ -343,21 +343,21 @@ openclaw plugins inspect --runtime openclaw plugins inspect --json ``` -默认情况下,检查会显示身份、加载状态、源、清单能力、策略标志、诊断、安装元数据、包能力,以及任何检测到的 MCP 或 LSP 服务器支持,而不会导入插件运行时。添加 `--runtime` 可加载插件模块,并包含已注册的钩子、工具、命令、服务、Gateway 网关方法和 HTTP 路由。运行时检查会直接报告缺失的插件依赖;安装和修复仍由 `openclaw plugins install`、`openclaw plugins update` 和 `openclaw doctor --fix` 处理。 +默认情况下,检查会显示身份、加载状态、来源、清单能力、策略标志、诊断、安装元数据、包能力,以及检测到的任何 MCP 或 LSP 服务器支持,而不会导入插件运行时。添加 `--runtime` 可加载插件模块,并包含已注册的钩子、工具、命令、服务、Gateway 网关方法和 HTTP 路由。运行时检查会直接报告缺失的插件依赖;安装和修复仍保留在 `openclaw plugins install`、`openclaw plugins update` 和 `openclaw doctor --fix` 中。 -插件拥有的 CLI 命令会安装为根 `openclaw` 命令组。在 `inspect --runtime` 于 `cliCommands` 下显示某个命令后,请以 `openclaw ...` 运行它;例如,注册了 `demo-git` 的插件可以用 `openclaw demo-git ping` 验证。 +插件拥有的 CLI 命令会作为根 `openclaw` 命令组安装。在 `inspect --runtime` 于 `cliCommands` 下显示命令后,将其作为 `openclaw ...` 运行;例如,注册了 `demo-git` 的插件可以用 `openclaw demo-git ping` 验证。 每个插件都会按其在运行时实际注册的内容分类: - **plain-capability** — 一种能力类型(例如仅提供商插件) - **hybrid-capability** — 多种能力类型(例如文本 + 语音 + 图像) -- **hook-only** — 仅钩子,没有能力或表面 -- **non-capability** — 工具/命令/服务,但没有能力 +- **hook-only** — 只有钩子,没有能力或表面 +- **non-capability** — 有工具/命令/服务,但没有能力 有关能力模型的更多信息,请参阅 [插件形态](/zh-CN/plugins/architecture#plugin-shapes)。 -`--json` 标志会输出适合脚本和审计使用的机器可读报告。`inspect --all` 会呈现覆盖整个插件群的表格,包含形态、能力种类、兼容性通知、包能力和钩子摘要列。`info` 是 `inspect` 的别名。 +`--json` 标志会输出适合脚本和审计的机器可读报告。`inspect --all` 会渲染一张全局表格,包含形态、能力种类、兼容性通知、包能力和钩子摘要列。`info` 是 `inspect` 的别名。 ### Doctor @@ -368,7 +368,7 @@ openclaw plugins doctor `doctor` 会报告插件加载错误、清单/发现诊断和兼容性通知。当一切正常时,它会打印 `No plugin issues detected.` -如果已配置的插件存在于磁盘上,但被加载器的路径安全检查阻止,配置验证会保留该插件条目,并将其报告为 `present but blocked`。请修复前面的被阻止插件诊断,例如路径所有权或全局可写权限,而不是移除 `plugins.entries.` 或 `plugins.allow` 配置。 +如果配置的插件存在于磁盘上,但被加载器的路径安全检查阻止,配置验证会保留该插件条目,并将其报告为 `present but blocked`。请修复前面的被阻止插件诊断,例如路径所有权或全局可写权限,而不是移除 `plugins.entries.` 或 `plugins.allow` 配置。 对于缺少 `register`/`activate` 导出等模块形态失败,请使用 `OPENCLAW_PLUGIN_LOAD_DEBUG=1` 重新运行,以在诊断输出中包含紧凑的导出形态摘要。 @@ -380,14 +380,14 @@ openclaw plugins registry --refresh openclaw plugins registry --json ``` -本地插件注册表是 OpenClaw 对已安装插件身份、启用状态、源元数据和贡献所有权持久化的冷读取模型。正常启动、提供商所有者查找、渠道设置分类和插件清单都可以读取它,而无需导入插件运行时模块。 +本地插件注册表是 OpenClaw 为已安装插件身份、启用状态、来源元数据和贡献所有权持久化的冷读取模型。正常启动、提供商所有者查找、渠道设置分类和插件清单都可以读取它,而无需导入插件运行时模块。 -使用 `plugins registry` 检查持久化注册表是否存在、是否为当前版本或是否已过期。使用 `--refresh` 可根据持久化插件索引、配置策略以及清单/包元数据重建它。这是修复路径,不是运行时激活路径。 +使用 `plugins registry` 检查持久化注册表是否存在、为当前版本或已过期。使用 `--refresh` 可根据持久化插件索引、配置策略以及清单/包元数据重建它。这是修复路径,不是运行时激活路径。 -`openclaw doctor --fix` 还会修复注册表相邻的托管 npm 漂移:如果托管插件 npm 根目录下某个孤立或恢复的 `@openclaw/*` 包遮蔽了内置插件,Doctor 会移除该过期包并重建注册表,使启动时根据内置清单进行验证。 +`openclaw doctor --fix` 也会修复与注册表相邻的托管 npm 漂移:如果托管插件 npm 根目录下某个孤立或恢复的 `@openclaw/*` 包遮蔽了内置插件,Doctor 会移除该过期包并重建注册表,使启动时根据内置清单进行验证。 -`OPENCLAW_DISABLE_PERSISTED_PLUGIN_REGISTRY=1` 是一个已弃用的应急兼容开关,用于处理注册表读取失败。优先使用 `plugins registry --refresh` 或 `openclaw doctor --fix`;环境变量回退机制仅用于迁移推出期间的紧急启动恢复。 +`OPENCLAW_DISABLE_PERSISTED_PLUGIN_REGISTRY=1` 是一个已弃用的应急兼容性开关,用于处理注册表读取失败。优先使用 `plugins registry --refresh` 或 `openclaw doctor --fix`;该环境变量回退仅用于迁移推出期间的紧急启动恢复。 ### 插件市场 @@ -397,7 +397,7 @@ openclaw plugins marketplace list openclaw plugins marketplace list --json ``` -插件市场列表接受本地市场路径、`marketplace.json` 路径、类似 `owner/repo` 的 GitHub 简写、GitHub 仓库 URL 或 git URL。`--json` 会打印解析后的来源标签,以及解析后的市场清单和插件条目。 +插件市场列表接受本地插件市场路径、`marketplace.json` 路径、类似 `owner/repo` 的 GitHub 简写、GitHub 仓库 URL 或 git URL。`--json` 会打印解析后的来源标签,以及解析得到的插件市场清单和插件条目。 ## 相关内容 diff --git a/docs/zh-CN/concepts/qa-e2e-automation.md b/docs/zh-CN/concepts/qa-e2e-automation.md index 94cef6de8..421c78164 100644 --- a/docs/zh-CN/concepts/qa-e2e-automation.md +++ b/docs/zh-CN/concepts/qa-e2e-automation.md @@ -2,15 +2,15 @@ read_when: - 了解 QA 栈如何协同工作 - 扩展 qa-lab、qa-channel 或传输适配器 - - 添加基于仓库的 QA 场景 + - 添加由仓库支持的 QA 场景 - 围绕 Gateway 网关仪表板构建更高真实度的 QA 自动化 -summary: QA 堆栈概览:qa-lab、qa-channel、仓库支持的场景、实时传输通道、传输适配器和报告。 +summary: QA 栈概览:qa-lab、qa-channel、由仓库支持的场景、实时传输通道、传输适配器和报告。 title: QA overview x-i18n: - generated_at: "2026-05-05T00:43:19Z" + generated_at: "2026-05-05T01:21:32Z" model: gpt-5.5 provider: openai - source_hash: 01cc3543a10a8ea3a7ea3a135e95ae0ea0c6e983e6b30c35aab1f74c13d7f4a3 + source_hash: 83adbe934d73265a1b47ee463c98fdd3eddfb1cd063d3a46a83dfc7568df0a96 source_path: concepts/qa-e2e-automation.md workflow: 16 --- @@ -19,53 +19,53 @@ x-i18n: 当前组成部分: -- `extensions/qa-channel`:合成消息渠道,包含私信、渠道、线程、表情回应、编辑和删除界面。 -- `extensions/qa-lab`:调试器 UI 和 QA 总线,用于观察转录、注入入站消息,以及导出 Markdown 报告。 -- `extensions/qa-matrix`、未来的运行器插件:实时传输适配器,在子 QA Gateway 网关内驱动真实渠道。 -- `qa/`:由仓库提供的启动任务种子资源和基线 QA 场景。 -- [Mantis](/zh-CN/concepts/mantis):针对需要真实传输、浏览器截图、VM 状态和 PR 证据的错误进行前后实时验证。 +- `extensions/qa-channel`:合成消息渠道,包含私信、渠道、线程、回应、编辑和删除界面。 +- `extensions/qa-lab`:用于观察转录、注入入站消息并导出 Markdown 报告的调试器 UI 和 QA 总线。 +- `extensions/qa-matrix`,未来的运行器插件:实时传输适配器,在子 QA Gateway 网关内驱动真实渠道。 +- `qa/`:由仓库支持的启动任务和基线 QA 场景种子资产。 +- [Mantis](/zh-CN/concepts/mantis):用于需要真实传输、浏览器截图、VM 状态和 PR 证据的错误的前后实时验证。 -## 命令接口 +## 命令界面 每个 QA 流程都在 `pnpm openclaw qa ` 下运行。许多命令有 `pnpm qa:*` 脚本别名;两种形式都受支持。 -| 命令 | 用途 | -| --------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `qa run` | 内置 QA 自检;写入 Markdown 报告。 | -| `qa suite` | 针对 QA Gateway 网关通道运行仓库支持的场景。别名:`pnpm openclaw qa suite --runner multipass`,用于一次性 Linux VM。 | -| `qa coverage` | 打印 Markdown 场景覆盖清单(`--json` 用于机器输出)。 | -| `qa parity-report` | 比较两个 `qa-suite-summary.json` 文件并写入智能体一致性报告。 | -| `qa character-eval` | 跨多个实时模型运行角色 QA 场景,并生成评审报告。参见[报告](#reporting)。 | -| `qa manual` | 针对所选提供商/模型通道运行一次性提示。 | -| `qa ui` | 启动 QA 调试器 UI 和本地 QA 总线(别名:`pnpm qa:lab:ui`)。 | -| `qa docker-build-image` | 构建预烘焙的 QA Docker 镜像。 | -| `qa docker-scaffold` | 为 QA 仪表盘 + Gateway 网关通道写入 docker-compose 脚手架。 | -| `qa up` | 构建 QA 站点,启动 Docker 支持的栈,并打印 URL(别名:`pnpm qa:lab:up`;`:fast` 变体会添加 `--use-prebuilt-image --bind-ui-dist --skip-ui-build`)。 | -| `qa aimock` | 仅启动 AIMock provider 服务器。 | -| `qa mock-openai` | 仅启动感知场景的 `mock-openai` provider 服务器。 | -| `qa credentials doctor` / `add` / `list` / `remove` | 管理共享 Convex 凭证池。 | -| `qa matrix` | 针对一次性 Tuwunel homeserver 的实时传输通道。参见 [Matrix QA](/zh-CN/concepts/qa-matrix)。 | -| `qa telegram` | 针对真实私有 Telegram 群组的实时传输通道。 | -| `qa discord` | 针对真实私有 Discord guild 渠道的实时传输通道。 | -| `qa slack` | 针对真实私有 Slack 渠道的实时传输通道。 | -| `qa mantis` | 用于实时传输错误的前后验证运行器,包含 Discord 状态表情回应证据、Crabbox 桌面/浏览器冒烟测试,以及 VNC 中的 Slack 冒烟测试。参见 [Mantis](/zh-CN/concepts/mantis)。 | +| 命令 | 用途 | +| --------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `qa run` | 内置 QA 自检;写入 Markdown 报告。 | +| `qa suite` | 针对 QA Gateway 网关通道运行由仓库支持的场景。别名:`pnpm openclaw qa suite --runner multipass`,用于一次性 Linux VM。 | +| `qa coverage` | 打印 Markdown 场景覆盖率清单(`--json` 用于机器输出)。 | +| `qa parity-report` | 比较两个 `qa-suite-summary.json` 文件并写入智能体对等报告。 | +| `qa character-eval` | 跨多个实时模型运行角色 QA 场景,并生成评审报告。参见[报告](#reporting)。 | +| `qa manual` | 针对选定的提供商/模型通道运行一次性提示。 | +| `qa ui` | 启动 QA 调试器 UI 和本地 QA 总线(别名:`pnpm qa:lab:ui`)。 | +| `qa docker-build-image` | 构建预制 QA Docker 镜像。 | +| `qa docker-scaffold` | 为 QA 仪表板 + Gateway 网关通道写入 docker-compose 脚手架。 | +| `qa up` | 构建 QA 站点,启动由 Docker 支持的栈,打印 URL(别名:`pnpm qa:lab:up`;`:fast` 变体会添加 `--use-prebuilt-image --bind-ui-dist --skip-ui-build`)。 | +| `qa aimock` | 仅启动 AIMock 提供商服务器。 | +| `qa mock-openai` | 仅启动具备场景感知能力的 `mock-openai` 提供商服务器。 | +| `qa credentials doctor` / `add` / `list` / `remove` | 管理共享 Convex 凭据池。 | +| `qa matrix` | 针对一次性 Tuwunel homeserver 的实时传输通道。参见 [Matrix QA](/zh-CN/concepts/qa-matrix)。 | +| `qa telegram` | 针对真实私有 Telegram 群组的实时传输通道。 | +| `qa discord` | 针对真实私有 Discord 公会渠道的实时传输通道。 | +| `qa slack` | 针对真实私有 Slack 渠道的实时传输通道。 | +| `qa mantis` | 用于实时传输错误的前后验证运行器,包含 Discord 状态回应证据、Crabbox 桌面/浏览器冒烟测试,以及 Slack-in-VNC 冒烟测试。参见 [Mantis](/zh-CN/concepts/mantis)。 | ## 操作员流程 -当前 QA 操作员流程是一个双栏 QA 站点: +当前 QA 操作员流程是一个双窗格 QA 站点: -- 左侧:包含智能体的 Gateway 网关仪表盘(Control UI)。 +- 左侧:带有智能体的 Gateway 网关仪表板(Control UI)。 - 右侧:QA Lab,显示类似 Slack 的转录和场景计划。 -运行方式: +使用以下命令运行: ```bash pnpm qa:lab:up ``` -这会构建 QA 站点,启动 Docker 支持的 Gateway 网关通道,并公开 QA Lab 页面,操作员或自动化循环可以在其中向智能体交付 QA 任务、观察真实渠道行为,并记录哪些有效、失败或仍被阻塞。 +这会构建 QA 站点,启动由 Docker 支持的 Gateway 网关通道,并公开 QA Lab 页面,操作员或自动化 loop 可以在其中给智能体分配 QA 任务、观察真实渠道行为,并记录哪些有效、失败或仍然受阻。 -为了在不每次重建 Docker 镜像的情况下更快迭代 QA Lab UI,可以使用绑定挂载的 QA Lab 包启动栈: +为了更快地迭代 QA Lab UI,而不必每次都重建 Docker 镜像,请使用绑定挂载的 QA Lab bundle 启动栈: ```bash pnpm openclaw qa docker-build-image @@ -74,25 +74,25 @@ pnpm qa:lab:up:fast pnpm qa:lab:watch ``` -`qa:lab:up:fast` 会让 Docker 服务使用预构建镜像,并将 `extensions/qa-lab/web/dist` 绑定挂载到 `qa-lab` 容器中。`qa:lab:watch` 会在变更时重建该包,浏览器会在 QA Lab 资源哈希变化时自动重新加载。 +`qa:lab:up:fast` 会让 Docker 服务使用预构建镜像,并将 `extensions/qa-lab/web/dist` 绑定挂载到 `qa-lab` 容器中。`qa:lab:watch` 会在变更时重建该 bundle,并且浏览器会在 QA Lab 资产哈希变化时自动重新加载。 -要进行本地 OpenTelemetry trace 冒烟测试,运行: +要进行本地 OpenTelemetry trace 冒烟测试,请运行: ```bash pnpm qa:otel:smoke ``` -该脚本会启动本地 OTLP/HTTP trace 接收器,在启用 `diagnostics-otel` 插件的情况下运行 `otel-trace-smoke` QA 场景,然后解码导出的 protobuf spans,并断言发布关键形态:必须存在 `openclaw.run`、`openclaw.harness.run`、`openclaw.model.call`、`openclaw.context.assembled` 和 `openclaw.message.delivery`;模型调用在成功轮次中不得导出 `StreamAbandoned`;原始诊断 ID 和 `openclaw.content.*` 属性必须保留在 trace 之外。它会在 QA suite 工件旁写入 `otel-smoke-summary.json`。 +该脚本会启动本地 OTLP/HTTP trace 接收器,在启用 `diagnostics-otel` 插件的情况下运行 `otel-trace-smoke` QA 场景,然后解码导出的 protobuf spans,并断言发布关键形态:必须存在 `openclaw.run`、`openclaw.harness.run`、`openclaw.model.call`、`openclaw.context.assembled` 和 `openclaw.message.delivery`;成功轮次中的模型调用不得导出 `StreamAbandoned`;原始诊断 ID 和 `openclaw.content.*` 属性必须留在 trace 之外。它会在 QA 套件工件旁写入 `otel-smoke-summary.json`。 -可观测性 QA 仅限源代码检出。npm tarball 会有意省略 QA Lab,因此包 Docker 发布通道不会运行 `qa` 命令。更改诊断 instrumentation 时,请从构建后的源代码检出中使用 `pnpm qa:otel:smoke`。 +可观测性 QA 仅保留在源码 checkout 中。npm tarball 会有意省略 QA Lab,因此包 Docker 发布通道不会运行 `qa` 命令。修改诊断 instrumentation 时,请从已构建的源码 checkout 运行 `pnpm qa:otel:smoke`。 -要运行真实传输的 Matrix 冒烟通道,运行: +要运行真实 Matrix 传输冒烟通道,请运行: ```bash pnpm openclaw qa matrix --profile fast --fail-fast ``` -此通道的完整 CLI 参考、profile/场景目录、环境变量和工件布局位于 [Matrix QA](/zh-CN/concepts/qa-matrix)。概览:它会在 Docker 中配置一次性 Tuwunel homeserver,注册临时 driver/SUT/observer 用户,在限定到该传输的子 QA Gateway 网关内运行真实 Matrix 插件(没有 `qa-channel`),然后在 `.artifacts/qa-e2e/matrix-/` 下写入 Markdown 报告、JSON 摘要、observed-events 工件和合并输出日志。 +该通道的完整 CLI 参考、profile/场景目录、环境变量和工件布局位于 [Matrix QA](/zh-CN/concepts/qa-matrix)。简要来说:它会在 Docker 中预配一次性 Tuwunel homeserver,注册临时的驱动/SUT/观察者用户,在限定到该传输的子 QA Gateway 网关内运行真实 Matrix 插件(不使用 `qa-channel`),然后在 `.artifacts/qa-e2e/matrix-/` 下写入 Markdown 报告、JSON 摘要、observed-events 工件和组合输出日志。 要运行真实传输的 Telegram、Discord 和 Slack 冒烟通道: @@ -102,9 +102,9 @@ pnpm openclaw qa discord pnpm openclaw qa slack ``` -它们面向一个预先存在的真实渠道,使用两个 bot(driver + SUT)。所需环境变量、场景列表、输出工件和 Convex 凭证池记录在下面的 [Telegram、Discord 和 Slack QA 参考](#telegram-discord-and-slack-qa-reference)中。 +它们会针对一个预先存在的真实渠道,并使用两个 bot(driver + SUT)。所需环境变量、场景列表、输出工件和 Convex 凭据池记录在下方的 [Telegram、Discord 和 Slack QA 参考](#telegram-discord-and-slack-qa-reference)中。 -要运行带 VNC 救援的完整 Slack 桌面 VM: +要运行带有 VNC 救援的完整 Slack 桌面 VM,请运行: ```bash pnpm openclaw qa mantis slack-desktop-smoke \ @@ -113,62 +113,62 @@ pnpm openclaw qa mantis slack-desktop-smoke \ --keep-lease ``` -该命令会租用一台 Crabbox 桌面/浏览器机器,在 VM 内运行 Slack 实时通道,在 VNC 浏览器中打开 Slack Web,捕获桌面,并将 `slack-qa/` 和 `slack-desktop-smoke.png` 复制回 Mantis 工件目录。通过 VNC 手动登录 Slack Web 后,可复用 `--lease-id `。使用 `--gateway-setup` 时,Mantis 会在 VM 内的 `38973` 端口保留一个持久运行的 OpenClaw Slack Gateway 网关;不使用它时,该命令会运行普通的 bot 到 bot Slack QA 通道,并在捕获工件后退出。 +该命令会租用一台 Crabbox 桌面/浏览器机器,在 VM 内运行 Slack 实时通道,在 VNC 浏览器中打开 Slack Web,捕获桌面,并将 `slack-qa/` 以及 `slack-desktop-smoke.png` 复制回 Mantis 工件目录。通过 VNC 手动登录 Slack Web 后,可复用 `--lease-id `。使用 `--gateway-setup` 时,Mantis 会在 VM 内的端口 `38973` 上保留一个持久运行的 OpenClaw Slack Gateway 网关;不使用时,该命令会运行普通的 bot 到 bot Slack QA 通道,并在捕获工件后退出。 -使用池化实时凭证前,运行: +使用池化实时凭据前,请运行: ```bash pnpm openclaw qa credentials doctor ``` -Doctor 会检查 Convex broker 环境,验证端点设置,并在 maintainer secret 存在时验证 admin/list 可达性。它只报告 secret 的已设置/缺失状态。 +Doctor 会检查 Convex 代理环境,验证端点设置,并在存在维护者 secret 时验证 admin/list 可达性。它只报告 secret 的已设置/缺失状态。 -## 实时传输覆盖范围 +## 实时传输覆盖率 -实时传输通道共享一个契约,而不是各自发明自己的场景列表形态。`qa-channel` 是覆盖面较广的合成产品行为套件,不属于实时传输覆盖矩阵。 +实时传输通道共享一份契约,而不是各自发明自己的场景列表形态。`qa-channel` 是广泛的合成产品行为套件,不属于实时传输覆盖率矩阵。 -| 通道 | Canary | 提及门控 | Bot 到 bot | Allowlist block | 顶层回复 | 重启恢复 | 线程跟进 | 线程隔离 | 表情回应观察 | 帮助命令 | 原生命令注册 | -| -------- | ------ | -------- | ---------- | --------------- | -------- | -------- | -------- | -------- | ------------ | -------- | ------------ | -| Matrix | x | x | x | x | x | x | x | x | x | | | -| Telegram | x | x | x | | | | | | | x | | -| Discord | x | x | x | | | | | | | | x | -| Slack | x | x | x | | | | | | | | | +| 通道 | Canary | 提及门控 | Bot 到 bot | 允许列表拦截 | 顶层回复 | 重启恢复 | 线程跟进 | 线程隔离 | 回应观察 | 帮助命令 | 原生命令注册 | +| -------- | ------ | -------- | ---------- | ------------ | -------- | -------- | -------- | -------- | -------- | -------- | ------------ | +| Matrix | x | x | x | x | x | x | x | x | x | | | +| Telegram | x | x | x | | | | | | | x | | +| Discord | x | x | x | | | | | | | | x | +| Slack | x | x | x | | | | | | | | | -这会让 `qa-channel` 保持为覆盖面较广的产品行为套件,同时 Matrix、Telegram 和未来的实时传输共享一个明确的传输契约检查清单。 +这会将 `qa-channel` 保持为广泛的产品行为套件,同时让 Matrix、Telegram 和未来的实时传输共享一份明确的传输契约清单。 -要运行不把 Docker 带入 QA 路径的一次性 Linux VM 通道,运行: +要运行一次性 Linux VM 通道而不把 Docker 带入 QA 路径,请运行: ```bash pnpm openclaw qa suite --runner multipass --scenario channel-chat-baseline ``` -这会启动一个全新的 Multipass 客户机,安装依赖,在客户机内构建 OpenClaw,运行 `qa suite`,然后把常规 QA 报告和摘要复制回主机上的 `.artifacts/qa-e2e/...`。 -它复用与主机上 `qa suite` 相同的场景选择行为。 -默认情况下,主机和 Multipass 套件运行会通过隔离的 Gateway 网关工作进程并行执行多个选中的场景。`qa-channel` 默认并发数为 4,并受选中场景数量限制。使用 `--concurrency ` 调整工作进程数量,或使用 `--concurrency 1` 进行串行执行。 -当任何场景失败时,该命令会以非零状态退出。如果你想生成产物但不希望退出码失败,请使用 `--allow-failures`。 -实时运行会转发客户机可实际使用的受支持 QA 身份验证输入:基于环境变量的提供商密钥、QA 实时提供商配置路径,以及存在时的 `CODEX_HOME`。请将 `--output-dir` 保持在仓库根目录下,这样客户机就能通过挂载的工作区写回。 +这会启动一个全新的 Multipass 来宾系统,在来宾系统内安装依赖、构建 OpenClaw、运行 `qa suite`,然后把标准 QA 报告和摘要复制回宿主机的 `.artifacts/qa-e2e/...`。 +它复用与宿主机上 `qa suite` 相同的场景选择行为。 +默认情况下,宿主机和 Multipass 套件运行会使用隔离的 Gateway 网关 worker 并行执行多个选定场景。`qa-channel` 默认并发数为 4,并受选定场景数量限制。使用 `--concurrency ` 调整 worker 数量,或使用 `--concurrency 1` 进行串行执行。 +当任一场景失败时,该命令会以非零状态退出。如果你想获取产物但不想产生失败退出码,请使用 `--allow-failures`。 +实时运行会转发对来宾系统实用且受支持的 QA 认证输入:基于环境变量的提供商密钥、QA 实时提供商配置路径,以及存在时的 `CODEX_HOME`。将 `--output-dir` 保持在仓库根目录下,这样来宾系统才能通过挂载的工作区写回。 ## Telegram、Discord 和 Slack QA 参考 -Matrix 因场景数量和基于 Docker 的 homeserver 预配而有一个[专用页面](/zh-CN/concepts/qa-matrix)。Telegram、Discord 和 Slack 较小,每个只有少量场景,没有配置文件系统,并针对预先存在的真实渠道,因此其参考内容放在这里。 +Matrix 因为场景数量以及基于 Docker 的 homeserver 供应,有一个[专用页面](/zh-CN/concepts/qa-matrix)。Telegram、Discord 和 Slack 更小,每个只有少量场景,没有配置文件系统,并且针对预先存在的真实渠道,所以它们的参考内容放在这里。 ### 共享 CLI 标志 -这些通道通过 `extensions/qa-lab/src/live-transports/shared/live-transport-cli.ts` 注册,并接受相同的标志: +这些 lane 通过 `extensions/qa-lab/src/live-transports/shared/live-transport-cli.ts` 注册,并接受相同的标志: -| 标志 | 默认值 | 描述 | -| ------------------------------------- | --------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------- | -| `--scenario ` | — | 只运行此场景。可重复使用。 | -| `--output-dir ` | `/.artifacts/qa-e2e/{telegram,discord,slack}-` | 写入报告、摘要、观测到的消息和输出日志的位置。相对路径会基于 `--repo-root` 解析。 | -| `--repo-root ` | `process.cwd()` | 从中立 cwd 调用时使用的仓库根目录。 | -| `--sut-account ` | `sut` | QA Gateway 网关配置中的临时账号 id。 | -| `--provider-mode ` | `live-frontier` | `mock-openai` 或 `live-frontier`(旧版 `live-openai` 仍可使用)。 | -| `--model ` / `--alt-model ` | 提供商默认值 | 主模型/备用模型引用。 | -| `--fast` | 关闭 | 在受支持的位置启用提供商快速模式。 | -| `--credential-source ` | `env` | 参见 [Convex 凭据池](#convex-credential-pool)。 | -| `--credential-role ` | CI 中为 `ci`,否则为 `maintainer` | 使用 `--credential-source convex` 时采用的角色。 | +| 标志 | 默认值 | 描述 | +| ------------------------------------- | --------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------- | +| `--scenario ` | — | 只运行此场景。可重复。 | +| `--output-dir ` | `/.artifacts/qa-e2e/{telegram,discord,slack}-` | 报告、摘要、已观察消息和输出日志的写入位置。相对路径会根据 `--repo-root` 解析。 | +| `--repo-root ` | `process.cwd()` | 从中立 cwd 调用时的仓库根目录。 | +| `--sut-account ` | `sut` | QA Gateway 网关配置中的临时账号 id。 | +| `--provider-mode ` | `live-frontier` | `mock-openai` 或 `live-frontier`(旧版 `live-openai` 仍可使用)。 | +| `--model ` / `--alt-model ` | 提供商默认值 | 主模型/备用模型引用。 | +| `--fast` | 关闭 | 支持时启用提供商快速模式。 | +| `--credential-source ` | `env` | 请参阅 [Convex 凭证池](#convex-credential-pool)。 | +| `--credential-role ` | CI 中为 `ci`,否则为 `maintainer` | 使用 `--credential-source convex` 时采用的角色。 | -任何场景失败时,每个通道都会以非零状态退出。`--allow-failures` 会写入产物,但不会设置失败退出码。 +任一场景失败时,每个 lane 都会以非零状态退出。`--allow-failures` 会写入产物,但不会设置失败退出码。 ### Telegram QA @@ -176,9 +176,9 @@ Matrix 因场景数量和基于 Docker 的 homeserver 预配而有一个[专用 pnpm openclaw qa telegram ``` -目标是一个真实的私有 Telegram 群组,其中包含两个不同的 bot(驱动 + SUT)。SUT bot 必须有 Telegram 用户名;当两个 bot 都在 `@BotFather` 中启用 **Bot-to-Bot Communication Mode** 时,bot 到 bot 的观测效果最好。 +目标是一个真实的私有 Telegram 群组,并使用两个不同的 bot(driver + SUT)。SUT bot 必须有 Telegram 用户名;当两个 bot 都在 `@BotFather` 中启用 **Bot-to-Bot Communication Mode** 时,bot 到 bot 的观测效果最好。 -使用 `--credential-source env` 时所需的环境变量: +使用 `--credential-source env` 时必需的环境变量: - `OPENCLAW_QA_TELEGRAM_GROUP_ID` — 数字聊天 id(字符串)。 - `OPENCLAW_QA_TELEGRAM_DRIVER_BOT_TOKEN` @@ -186,7 +186,7 @@ pnpm openclaw qa telegram 可选: -- `OPENCLAW_QA_TELEGRAM_CAPTURE_CONTENT=1` 会在观测消息产物中保留消息正文(默认会脱敏)。 +- `OPENCLAW_QA_TELEGRAM_CAPTURE_CONTENT=1` 会在已观察消息产物中保留消息正文(默认会脱敏)。 场景(`extensions/qa-lab/src/live-transports/telegram/telegram-live.runtime.ts:44`): @@ -202,7 +202,7 @@ pnpm openclaw qa telegram 输出产物: - `telegram-qa-report.md` -- `telegram-qa-summary.json` — 从 canary 开始,包含每条回复的 RTT(驱动发送 → 观测到 SUT 回复)。 +- `telegram-qa-summary.json` — 从 canary 开始,包含每条回复的 RTT(driver 发送 → 观察到 SUT 回复)。 - `telegram-qa-observed-messages.json` — 除非设置 `OPENCLAW_QA_TELEGRAM_CAPTURE_CONTENT=1`,否则正文会被脱敏。 ### Discord QA @@ -211,28 +211,28 @@ pnpm openclaw qa telegram pnpm openclaw qa discord ``` -目标是一个真实的私有 Discord guild 频道,其中包含两个 bot:由 harness 控制的驱动 bot,以及由子 OpenClaw Gateway 网关通过内置 Discord 插件启动的 SUT bot。它会验证频道提及处理、SUT bot 已向 Discord 注册原生 `/help` 命令,以及可选择启用的 Mantis 证据场景。 +目标是一个真实的私有 Discord guild 渠道,并使用两个 bot:一个由 harness 控制的 driver bot,以及一个由子 OpenClaw Gateway 网关通过内置 Discord 插件启动的 SUT bot。它会验证渠道提及处理、SUT bot 是否已向 Discord 注册原生 `/help` 命令,以及选择启用的 Mantis 证据场景。 -使用 `--credential-source env` 时所需的环境变量: +使用 `--credential-source env` 时必需的环境变量: - `OPENCLAW_QA_DISCORD_GUILD_ID` - `OPENCLAW_QA_DISCORD_CHANNEL_ID` - `OPENCLAW_QA_DISCORD_DRIVER_BOT_TOKEN` - `OPENCLAW_QA_DISCORD_SUT_BOT_TOKEN` -- `OPENCLAW_QA_DISCORD_SUT_APPLICATION_ID` — 必须匹配 Discord 返回的 SUT bot 用户 id(否则该通道会快速失败)。 +- `OPENCLAW_QA_DISCORD_SUT_APPLICATION_ID` — 必须与 Discord 返回的 SUT bot 用户 id 匹配(否则该 lane 会快速失败)。 可选: -- `OPENCLAW_QA_DISCORD_CAPTURE_CONTENT=1` 会在观测消息产物中保留消息正文。 +- `OPENCLAW_QA_DISCORD_CAPTURE_CONTENT=1` 会在已观察消息产物中保留消息正文。 场景(`extensions/qa-lab/src/live-transports/discord/discord-live.runtime.ts:36`): - `discord-canary` - `discord-mention-gating` - `discord-native-help-command-registration` -- `discord-status-reactions-tool-only` — 可选择启用的 Mantis 场景。它会单独运行,因为它会将 SUT 切换为始终开启、仅工具的 guild 回复,并设置 `messages.statusReactions.enabled=true`,然后捕获 REST reaction 时间线以及 HTML/PNG 可视化产物。 +- `discord-status-reactions-tool-only` — 选择启用的 Mantis 场景。该场景会单独运行,因为它会将 SUT 切换为始终开启、仅工具模式的 guild 回复,并设置 `messages.statusReactions.enabled=true`,然后捕获 REST reaction 时间线以及 HTML/PNG 视觉产物。 -显式运行 Mantis 状态 reaction 场景: +显式运行 Mantis status-reaction 场景: ```bash pnpm openclaw qa discord \ @@ -248,7 +248,7 @@ pnpm openclaw qa discord \ - `discord-qa-report.md` - `discord-qa-summary.json` - `discord-qa-observed-messages.json` — 除非设置 `OPENCLAW_QA_DISCORD_CAPTURE_CONTENT=1`,否则正文会被脱敏。 -- 运行状态 reaction 场景时,会生成 `discord-qa-reaction-timelines.json` 和 `discord-status-reactions-tool-only-timeline.png`。 +- 运行 status-reaction 场景时会生成 `discord-qa-reaction-timelines.json` 和 `discord-status-reactions-tool-only-timeline.png`。 ### Slack QA @@ -256,9 +256,9 @@ pnpm openclaw qa discord \ pnpm openclaw qa slack ``` -目标是一个真实的私有 Slack 频道,其中包含两个不同的 bot:由 harness 控制的驱动 bot,以及由子 OpenClaw Gateway 网关通过内置 Slack 插件启动的 SUT bot。 +目标是一个真实的私有 Slack 渠道,并使用两个不同的 bot:一个由 harness 控制的 driver bot,以及一个由子 OpenClaw Gateway 网关通过内置 Slack 插件启动的 SUT bot。 -使用 `--credential-source env` 时所需的环境变量: +使用 `--credential-source env` 时必需的环境变量: - `OPENCLAW_QA_SLACK_CHANNEL_ID` - `OPENCLAW_QA_SLACK_DRIVER_BOT_TOKEN` @@ -267,7 +267,7 @@ pnpm openclaw qa slack 可选: -- `OPENCLAW_QA_SLACK_CAPTURE_CONTENT=1` 会在观测消息产物中保留消息正文。 +- `OPENCLAW_QA_SLACK_CAPTURE_CONTENT=1` 会在已观察消息产物中保留消息正文。 场景(`extensions/qa-lab/src/live-transports/slack/slack-live.runtime.ts:39`): @@ -282,18 +282,20 @@ pnpm openclaw qa slack #### 设置 Slack 工作区 -该通道需要在一个工作区中有两个不同的 Slack 应用,外加一个两个 bot 都是成员的频道: +该 lane 需要在一个工作区中有两个不同的 Slack 应用,以及一个两个 bot 都是成员的渠道: -- `channelId` — 两个 bot 都已受邀加入的频道的 `Cxxxxxxxxxx` id。请使用专用频道;该通道每次运行都会发帖。 +- `channelId` — 两个 bot 都已被邀请加入的渠道的 `Cxxxxxxxxxx` id。请使用专用渠道;该 lane 每次运行都会发帖。 - `driverBotToken` — **Driver** 应用的 bot token(`xoxb-...`)。 -- `sutBotToken` — **SUT** 应用的 bot token(`xoxb-...`),它必须是不同于驱动的单独 Slack 应用,以确保其 bot 用户 id 不同。 -- `sutAppToken` — SUT 应用的应用级 token(`xapp-...`),带有 `connections:write`,Socket Mode 会使用它让 SUT 应用接收事件。 +- `sutBotToken` — **SUT** 应用的 bot token(`xoxb-...`),它必须是与 driver 分离的 Slack 应用,这样它的 bot 用户 id 才会不同。 +- `sutAppToken` — SUT 应用的应用级 token(`xapp-...`),带有 `connections:write`,供 Socket Mode 使用,使 SUT 应用能够接收事件。 -建议使用专门用于 QA 的 Slack 工作区,而不是复用生产工作区。 +相比复用生产工作区,更推荐使用专门用于 QA 的 Slack 工作区。 + +下面的 SUT manifest 映射了内置 Slack 插件的生产安装(`extensions/slack/src/setup-shared.ts:10`)。关于用户看到的生产渠道设置,请参阅 [Slack 渠道快速设置](/zh-CN/channels/slack#quick-setup);QA Driver/SUT 对有意分开,因为该 lane 需要在同一个工作区中有两个不同的 bot 用户 id。 **1. 创建 Driver 应用** -前往 [api.slack.com/apps](https://api.slack.com/apps) → _Create New App_ → _From a manifest_ → 选择 QA 工作区,粘贴以下清单,然后执行 _Install to Workspace_: +前往 [api.slack.com/apps](https://api.slack.com/apps) → _Create New App_ → _From a manifest_ → 选择 QA 工作区,粘贴以下 manifest,然后点击 _Install to Workspace_: ```json { @@ -318,11 +320,11 @@ pnpm openclaw qa slack } ``` -复制 _Bot User OAuth Token_(`xoxb-...`)—— 它就是 `driverBotToken`。驱动只需要发消息并识别自己;不需要事件,也不需要 Socket Mode。 +复制 _Bot User OAuth Token_(`xoxb-...`)— 它会成为 `driverBotToken`。driver 只需要发布消息并识别自身;不需要事件,也不需要 Socket Mode。 **2. 创建 SUT 应用** -在同一工作区中重复 _Create New App → From a manifest_。scope 集合与内置 Slack 插件的生产安装一致(`extensions/slack/src/setup-shared.ts:10`): +在同一个工作区中重复 _Create New App → From a manifest_。scope 集合映射了内置 Slack 插件的生产安装(`extensions/slack/src/setup-shared.ts:10`): ```json { @@ -393,27 +395,27 @@ pnpm openclaw qa slack } ``` -Slack 创建应用后,在其设置页面完成两件事: +Slack 创建应用后,在其设置页面执行两项操作: -- _Install to Workspace_ → 复制 _Bot User OAuth Token_ → 它就是 `sutBotToken`。 -- _Basic Information → App-Level Tokens → Generate Token and Scopes_ → 添加 scope `connections:write` → 保存 → 复制 `xapp-...` 值 → 它就是 `sutAppToken`。 +- _Install to Workspace_ → 复制 _Bot User OAuth Token_ → 它会成为 `sutBotToken`。 +- _Basic Information → App-Level Tokens → Generate Token and Scopes_ → 添加 scope `connections:write` → 保存 → 复制 `xapp-...` 值 → 它会成为 `sutAppToken`。 -通过分别对每个 token 调用 `auth.test`,验证两个 bot 的用户 id 不同。运行时会通过用户 id 区分驱动和 SUT;将一个应用同时用于两者会导致 mention-gating 立即失败。 +通过对每个 token 调用 `auth.test` 来验证这两个机器人具有不同的用户 ID。运行时通过用户 ID 区分 driver 和 SUT;如果两者复用同一个应用,提及门控会立即失败。 -**3. 创建频道** +**3. 创建渠道** -在 QA 工作区中创建一个频道(例如 `#openclaw-qa`),并从频道内邀请两个 bot: +在 QA 工作区中创建一个渠道(例如 `#openclaw-qa`),并从渠道内邀请两个机器人: ``` /invite @OpenClaw QA Driver /invite @OpenClaw QA SUT ``` -从 _channel info → About → Channel ID_ 复制 `Cxxxxxxxxxx` ID,它会成为 `channelId`。公共频道可以使用;如果你使用私有频道,两个应用都已经有 `groups:history`,因此 harness 的历史读取仍会成功。 +从 _渠道信息 → 关于 → 渠道 ID_ 复制 `Cxxxxxxxxxx` ID,这会成为 `channelId`。公共渠道可用;如果你使用私有渠道,两个应用都已经有 `groups:history`,因此 harness 的历史读取仍会成功。 **4. 注册凭证** -有两种选项。单机调试使用环境变量(设置四个 `OPENCLAW_QA_SLACK_*` 变量并传入 `--credential-source env`),或者填充共享的 Convex 池,让 CI 和其他维护者可以租用它们。 +有两种选择。单机调试时使用环境变量(设置四个 `OPENCLAW_QA_SLACK_*` 变量并传入 `--credential-source env`),或者为共享 Convex 池播种,让 CI 和其他维护者可以租用它们。 对于 Convex 池,将四个字段写入 JSON 文件: @@ -441,7 +443,7 @@ pnpm openclaw qa credentials list --kind slack --status all --json **5. 端到端验证** -在本地运行该 lane,以确认两个机器人都能通过 broker 相互通信: +在本地运行该 lane,确认两个机器人可以通过 broker 互相通信: ```bash pnpm openclaw qa slack \ @@ -450,19 +452,19 @@ pnpm openclaw qa slack \ --output-dir .artifacts/qa-e2e/slack-local ``` -绿色运行会在远少于 30 秒内完成,且 `slack-qa-report.md` 显示 `slack-canary` 和 `slack-mention-gating` 的 Status 都是 `pass`。如果 lane 挂起约 90 秒并以 `Convex credential pool exhausted for kind "slack"` 退出,说明池为空或每一行都已被租用,`qa credentials list --kind slack --status all --json` 会告诉你是哪一种情况。 +绿色运行会在远少于 30 秒内完成,并且 `slack-qa-report.md` 会显示 `slack-canary` 和 `slack-mention-gating` 的 Status 都是 `pass`。如果该 lane 挂起约 90 秒后以 `Convex credential pool exhausted for kind "slack"` 退出,说明池为空或每一行都已被租用,`qa credentials list --kind slack --status all --json` 会告诉你是哪种情况。 ### Convex 凭证池 -Telegram、Discord 和 Slack lane 可以从共享 Convex 池租用凭证,而不是读取上面的环境变量。传入 `--credential-source convex`(或设置 `OPENCLAW_QA_CREDENTIAL_SOURCE=convex`);QA Lab 会获取一个独占租约,在运行期间发送 Heartbeat,并在关闭时释放它。池类型是 `"telegram"`、`"discord"` 和 `"slack"`。 +Telegram、Discord 和 Slack lane 可以从共享 Convex 池租用凭证,而不是读取上面的环境变量。传入 `--credential-source convex`(或设置 `OPENCLAW_QA_CREDENTIAL_SOURCE=convex`);QA Lab 会获取独占租约,在运行期间发送 Heartbeat,并在关闭时释放。池种类是 `"telegram"`、`"discord"` 和 `"slack"`。 broker 在 `admin/add` 上验证的 payload 形状: -- Telegram(`kind: "telegram"`):`{ groupId: string, driverToken: string, sutToken: string }`,`groupId` 必须是数字 chat-id 字符串。 +- Telegram(`kind: "telegram"`):`{ groupId: string, driverToken: string, sutToken: string }` —— `groupId` 必须是数字聊天 ID 字符串。 - Discord(`kind: "discord"`):`{ guildId: string, channelId: string, driverBotToken: string, sutBotToken: string, sutApplicationId: string }`。 -- Slack(`kind: "slack"`):`{ channelId: string, driverBotToken: string, sutBotToken: string, sutAppToken: string }`,`channelId` 必须匹配 `^[A-Z][A-Z0-9]+$`(例如 `Cxxxxxxxxxx` 这样的 Slack ID)。有关应用和 scope 配置,请参阅[设置 Slack 工作区](#setting-up-the-slack-workspace)。 +- Slack(`kind: "slack"`):`{ channelId: string, driverBotToken: string, sutBotToken: string, sutAppToken: string }` —— `channelId` 必须匹配 `^[A-Z][A-Z0-9]+$`(类似 `Cxxxxxxxxxx` 的 Slack ID)。有关应用和 scope 配置,请参阅 [设置 Slack 工作区](#setting-up-the-slack-workspace)。 -操作环境变量和 Convex broker 端点契约位于[测试 → 通过 Convex 共享 Telegram 凭证](/zh-CN/help/testing#shared-telegram-credentials-via-convex-v1)(该章节名称早于 Discord 支持;两种类型的 broker 语义相同)。 +操作环境变量和 Convex broker 端点契约位于 [测试 → 通过 Convex 共享 Telegram 凭证](/zh-CN/help/testing#shared-telegram-credentials-via-convex-v1)(该章节名称早于 Discord 支持;两种类型的 broker 语义相同)。 ## 仓库支持的种子 @@ -471,22 +473,22 @@ broker 在 `admin/add` 上验证的 payload 形状: - `qa/scenarios/index.md` - `qa/scenarios//*.md` -这些内容有意放在 git 中,这样 QA 计划对人类和智能体都可见。 +这些内容有意放在 git 中,让 QA 计划对人类和智能体都可见。 `qa-lab` 应保持为通用的 Markdown runner。每个场景 Markdown 文件都是一次测试运行的事实来源,并应定义: - 场景元数据 -- 可选的 category、capability、lane 和 risk 元数据 +- 可选的类别、能力、lane 和风险元数据 - 文档和代码引用 -- 可选的插件要求 -- 可选的 Gateway 网关配置补丁 +- 可选插件要求 +- 可选 Gateway 网关配置 patch - 可执行的 `qa-flow` -支持 `qa-flow` 的可复用运行时表面允许保持通用且跨领域。例如,Markdown 场景可以把传输侧 helper 与浏览器侧 helper 结合起来,通过 Gateway 网关 `browser.request` seam 驱动嵌入式 Control UI,而无需添加特殊情况 runner。 +支撑 `qa-flow` 的可复用运行时表面可以保持通用且跨领域。例如,Markdown 场景可以将传输侧 helper 与浏览器侧 helper 组合起来,后者通过 Gateway 网关 `browser.request` seam 驱动嵌入式 Control UI,而不需要添加特例 runner。 -场景文件应按产品能力分组,而不是按源码树文件夹分组。文件移动时保持场景 ID 稳定;使用 `docsRefs` 和 `codeRefs` 进行实现可追溯性。 +场景文件应按产品能力分组,而不是按源码树文件夹分组。文件移动时保持场景 ID 稳定;使用 `docsRefs` 和 `codeRefs` 实现实现可追溯性。 -基线列表应保持足够广,以覆盖: +基线列表应保持足够宽,以覆盖: - 私信和渠道聊天 - 线程行为 @@ -494,7 +496,7 @@ broker 在 `admin/add` 上验证的 payload 形状: - cron 回调 - 记忆召回 - 模型切换 -- subagent 移交 +- subagent handoff - 仓库读取和文档读取 - 一个小型构建任务,例如 Lobster Invaders @@ -502,10 +504,10 @@ broker 在 `admin/add` 上验证的 payload 形状: `qa suite` 有两个本地提供商 mock lane: -- `mock-openai` 是感知场景的 OpenClaw mock。它仍然是仓库支持 QA 和 parity gate 的默认确定性 mock lane。 -- `aimock` 会启动一个由 AIMock 支持的提供商服务器,用于实验性协议、fixture、record/replay 和 chaos 覆盖。它是增量能力,不会替代 `mock-openai` 场景 dispatcher。 +- `mock-openai` 是感知场景的 OpenClaw mock。它仍是仓库支持的 QA 和 parity gate 的默认确定性 mock lane。 +- `aimock` 会启动一个 AIMock 支持的提供商服务器,用于实验性协议、fixture、录制/回放和 chaos 覆盖。它是增量补充,不会替代 `mock-openai` 场景 dispatcher。 -提供商 lane 实现位于 `extensions/qa-lab/src/providers/` 下。每个提供商拥有自己的默认值、本地服务器启动、Gateway 网关模型配置、auth-profile 暂存需求以及 live/mock 能力标志。共享 suite 和 Gateway 网关代码应通过提供商 registry 路由,而不是按提供商名称分支。 +提供商 lane 实现位于 `extensions/qa-lab/src/providers/` 下。每个提供商拥有自己的默认值、本地服务器启动、Gateway 网关模型配置、auth-profile 暂存需求,以及 live/mock 能力标志。共享 suite 和 Gateway 网关代码应通过提供商 registry 路由,而不是按提供商名称分支。 ## 传输适配器 @@ -513,60 +515,60 @@ broker 在 `admin/add` 上验证的 payload 形状: 在架构层面,拆分如下: -- `qa-lab` 拥有通用场景执行、worker 并发、工件写入和报告。 -- 传输适配器拥有 Gateway 网关配置、就绪状态、入站和出站观测、传输操作以及规范化传输状态。 +- `qa-lab` 负责通用场景执行、worker 并发、artifact 写入和报告。 +- 传输适配器负责 Gateway 网关配置、就绪状态、入站和出站观察、传输操作,以及规范化传输状态。 - `qa/scenarios/` 下的 Markdown 场景文件定义测试运行;`qa-lab` 提供执行它们的可复用运行时表面。 ### 添加渠道 -向 Markdown QA 系统添加渠道只需要两件事: +向 Markdown QA 系统添加一个渠道只需要两件事: 1. 该渠道的传输适配器。 -2. 覆盖该渠道契约的场景包。 +2. 覆盖渠道契约的场景包。 -当共享 `qa-lab` host 可以拥有该流程时,不要添加新的顶层 QA command root。 +当共享的 `qa-lab` host 可以拥有该流程时,不要添加新的顶层 QA 命令根。 `qa-lab` 拥有共享 host 机制: -- `openclaw qa` command root +- `openclaw qa` 命令根 - suite 启动和 teardown - worker 并发 -- 工件写入 +- artifact 写入 - 报告生成 - 场景执行 - 旧版 `qa-channel` 场景的兼容别名 Runner 插件拥有传输契约: -- `openclaw qa ` 如何挂载到共享 `qa` root 下 -- 如何为该传输配置 Gateway 网关 +- `openclaw qa ` 如何挂载在共享 `qa` 根之下 +- Gateway 网关如何为该传输配置 - 如何检查就绪状态 - 如何注入入站事件 -- 如何观测出站消息 +- 如何观察出站消息 - 如何暴露 transcript 和规范化传输状态 - 如何执行传输支持的操作 -- 如何处理传输专用 reset 或 cleanup +- 如何处理传输专用 reset 或清理 -新渠道的最低采用门槛: +新渠道的最低采纳门槛: -1. 保持 `qa-lab` 作为共享 `qa` root 的所有者。 +1. 保持 `qa-lab` 作为共享 `qa` 根的所有者。 2. 在共享 `qa-lab` host seam 上实现传输 runner。 3. 将传输专用机制保留在 runner 插件或渠道 harness 内。 -4. 将 runner 挂载为 `openclaw qa `,而不是注册竞争性的 root command。Runner 插件应在 `openclaw.plugin.json` 中声明 `qaRunners`,并从 `runtime-api.ts` 导出匹配的 `qaRunnerCliRegistrations` 数组。保持 `runtime-api.ts` 轻量;惰性 CLI 和 runner 执行应保留在单独入口点之后。 -5. 在按主题组织的 `qa/scenarios/` 目录下编写或适配 Markdown 场景。 -6. 对新场景使用通用场景 helper。 +4. 将 runner 挂载为 `openclaw qa `,而不是注册一个竞争性的根命令。Runner 插件应在 `openclaw.plugin.json` 中声明 `qaRunners`,并从 `runtime-api.ts` 导出匹配的 `qaRunnerCliRegistrations` 数组。保持 `runtime-api.ts` 轻量;惰性 CLI 和 runner 执行应留在单独入口点之后。 +5. 在主题化的 `qa/scenarios/` 目录下编写或改编 Markdown 场景。 +6. 为新场景使用通用场景 helper。 7. 保持现有兼容别名可用,除非仓库正在进行有意的迁移。 决策规则很严格: -- 如果行为可以在 `qa-lab` 中表达一次,就把它放在 `qa-lab` 中。 -- 如果行为依赖一个渠道传输,就把它保留在该 runner 插件或插件 harness 中。 -- 如果某个场景需要多个渠道都可使用的新能力,就添加通用 helper,而不是在 `suite.ts` 中添加渠道专用分支。 -- 如果某个行为只对一个传输有意义,就保持场景传输专用,并在场景契约中明确说明。 +- 如果行为可以在 `qa-lab` 中表达一次,就放到 `qa-lab` 中。 +- 如果行为依赖某一个渠道传输,就将它保留在对应 runner 插件或插件 harness 中。 +- 如果某个场景需要一个可被多个渠道使用的新能力,则添加通用 helper,而不是在 `suite.ts` 中添加渠道专用分支。 +- 如果某个行为只对一个传输有意义,则保持该场景为传输专用,并在场景契约中明确说明。 ### 场景 helper 名称 -新场景首选的通用 helper: +新场景的首选通用 helper: - `waitForTransportReady` - `waitForChannelReady` @@ -581,20 +583,20 @@ Runner 插件拥有传输契约: - `formatTransportTranscript` - `resetTransport` -兼容别名仍可用于现有场景:`waitForQaChannelReady`、`waitForOutboundMessage`、`waitForNoOutbound`、`formatConversationTranscript`、`resetBus`,但新场景编写应使用通用名称。这些别名用于避免一次性强制迁移,不代表未来的模型。 +现有场景仍可使用兼容别名:`waitForQaChannelReady`、`waitForOutboundMessage`、`waitForNoOutbound`、`formatConversationTranscript`、`resetBus`,但新场景编写应使用通用名称。这些别名用于避免一次性迁移,而不是未来的模型。 ## 报告 -`qa-lab` 会从观测到的 bus timeline 导出 Markdown 协议报告。报告应回答: +`qa-lab` 会根据观察到的 bus timeline 导出 Markdown 协议报告。报告应回答: -- 哪些有效 -- 哪些失败 -- 哪些仍被阻塞 +- 哪些内容有效 +- 哪些内容失败 +- 哪些内容仍被阻塞 - 哪些后续场景值得添加 -要查看可用场景清单(在评估后续工作规模或接入新传输时很有用),运行 `pnpm openclaw qa coverage`(添加 `--json` 可获得机器可读输出)。 +如需查看可用场景清单(在评估后续工作规模或接入新传输时很有用),运行 `pnpm openclaw qa coverage`(添加 `--json` 可获得机器可读输出)。 -对于角色和风格检查,在多个 live 模型 ref 上运行同一个场景,并写入经过评审的 Markdown 报告: +如需进行角色和风格检查,请在多个 live 模型引用上运行同一个场景,并写入经过评审的 Markdown 报告: ```bash pnpm openclaw qa character-eval \ @@ -613,21 +615,16 @@ pnpm openclaw qa character-eval \ --judge-concurrency 16 ``` -该命令运行本地 QA Gateway 网关子进程,而不是 Docker。角色评估场景应通过 `SOUL.md` 设置 persona,然后运行普通用户轮次,例如聊天、工作区帮助和小型文件任务。不应告诉候选模型它正在被评估。该命令会保留每个完整 transcript,记录基本运行统计,然后要求 judge 模型使用 fast mode,并在支持时使用 `xhigh` reasoning,按自然度、vibe 和幽默感对运行结果排名。比较提供商时使用 `--blind-judge-models`:judge prompt 仍会获得每个 transcript 和运行状态,但候选 ref 会替换为 `candidate-01` 等中性标签;报告会在解析后将排名映射回真实 ref。 - -候选运行默认使用 `high` thinking,GPT-5.5 使用 `medium`,支持它的旧版 OpenAI eval ref 使用 `xhigh`。使用 `--model provider/model,thinking=` 内联覆盖特定候选。`--thinking ` 仍会设置全局 fallback,旧的 `--model-thinking ` 形式保留用于兼容。 - -OpenAI 候选 ref 默认启用 fast mode,因此在提供商支持时会使用 priority processing。当单个候选或 judge 需要覆盖时,内联添加 `,fast`、`,no-fast` 或 `,fast=false`。只有当你想为每个候选模型强制开启 fast mode 时,才传入 `--fast`。候选和 judge 的持续时间会记录在报告中用于 benchmark 分析,但 judge prompt 会明确说明不要按速度排名。 - -候选和 judge 模型运行的默认并发均为 16。当提供商限制或本地 Gateway 网关压力使运行噪声过大时,降低 `--concurrency` 或 `--judge-concurrency`。 - -未传入候选 `--model` 时,角色评估默认使用 `openai/gpt-5.5`、`openai/gpt-5.2`、`openai/gpt-5`、`anthropic/claude-opus-4-6`、`anthropic/claude-sonnet-4-6`、`zai/glm-5.1`、`moonshot/kimi-k2.5` 和 `google/gemini-3.1-pro-preview`。 - -未传入 `--judge-model` 时,judge 默认使用 `openai/gpt-5.5,thinking=xhigh,fast` 和 `anthropic/claude-opus-4-6,thinking=high`。 +该命令运行本地 QA Gateway 网关子进程,而不是 Docker。角色评测场景应通过 `SOUL.md` 设置 persona,然后运行普通用户轮次,例如聊天、工作区帮助和小文件任务。不应告知候选模型它正在接受评测。该命令会保留每份完整 transcript,记录基本运行统计,然后以快速模式请求 judge models,并在支持的情况下使用 `xhigh` reasoning,按自然度、氛围和幽默感对运行结果排序。比较提供商时使用 `--blind-judge-models`:judge prompt 仍会获取每份 transcript 和运行状态,但候选引用会替换为中性标签,例如 `candidate-01`;报告会在解析后将排名映射回真实引用。 +候选运行默认使用 `high` thinking,GPT-5.5 使用 `medium`,较旧且支持的 OpenAI eval 引用使用 `xhigh`。可用 `--model provider/model,thinking=` 内联覆盖特定候选。`--thinking ` 仍会设置全局 fallback,较旧的 `--model-thinking ` 形式会保留以兼容。 +OpenAI 候选引用默认使用快速模式,因此在提供商支持时会使用 priority processing。当单个候选或 judge 需要覆盖时,可内联添加 `,fast`、`,no-fast` 或 `,fast=false`。仅当你想为每个候选模型强制开启快速模式时,才传入 `--fast`。候选和 judge 的耗时会记录在报告中以便基准分析,但 judge prompt 会明确说明不要按速度排名。 +候选和 judge 模型运行都默认并发数为 16。当提供商限制或本地 Gateway 网关压力导致运行噪声过大时,降低 `--concurrency` 或 `--judge-concurrency`。 +如果未传入候选 `--model`,角色评测在未传入 `--model` 时默认使用 `openai/gpt-5.5`、`openai/gpt-5.2`、`openai/gpt-5`、`anthropic/claude-opus-4-6`、`anthropic/claude-sonnet-4-6`、`zai/glm-5.1`、`moonshot/kimi-k2.5` 和 `google/gemini-3.1-pro-preview`。 +如果未传入 `--judge-model`,judge 默认使用 `openai/gpt-5.5,thinking=xhigh,fast` 和 `anthropic/claude-opus-4-6,thinking=high`。 ## 相关文档 - [Matrix QA](/zh-CN/concepts/qa-matrix) -- [QA channel](/zh-CN/channels/qa-channel) +- [QA Channel](/zh-CN/channels/qa-channel) - [测试](/zh-CN/help/testing) - [仪表板](/zh-CN/web/dashboard) diff --git a/docs/zh-CN/gateway/doctor.md b/docs/zh-CN/gateway/doctor.md index ed5c9fd45..322291c5f 100644 --- a/docs/zh-CN/gateway/doctor.md +++ b/docs/zh-CN/gateway/doctor.md @@ -6,15 +6,15 @@ sidebarTitle: Doctor summary: Doctor 命令:健康检查、配置迁移和修复步骤 title: Doctor x-i18n: - generated_at: "2026-05-05T00:56:00Z" + generated_at: "2026-05-05T01:21:19Z" model: gpt-5.5 provider: openai - source_hash: f8386e5d733ab599c78b96ad04135c8168cacdc55e864676aac26cd095a72685 + source_hash: 3e374f91d00d4b43a3852de6f746b044471e80af936d464a789061a31cadd09d source_path: gateway/doctor.md workflow: 16 --- -`openclaw doctor` 是 OpenClaw 的修复 + 迁移工具。它会修复过时的配置/状态,检查健康状况,并提供可执行的修复步骤。 +`openclaw doctor` 是 OpenClaw 的修复 + 迁移工具。它会修复过期配置/状态、检查健康状况,并提供可执行的修复步骤。 ## 快速开始 @@ -30,7 +30,7 @@ openclaw doctor openclaw doctor --yes ``` - 不提示并接受默认值(包括适用时的重启/服务/沙箱修复步骤)。 + 不提示即接受默认值(包括适用时的重启/服务/沙箱修复步骤)。 @@ -38,7 +38,7 @@ openclaw doctor openclaw doctor --repair ``` - 不提示并应用推荐的修复(在安全时执行修复 + 重启)。 + 不提示即应用推荐修复(在安全时执行修复 + 重启)。 @@ -54,7 +54,7 @@ openclaw doctor openclaw doctor --non-interactive ``` - 不提示运行,并且只应用安全迁移(配置规范化 + 磁盘状态移动)。跳过需要人工确认的重启/服务/沙箱操作。检测到旧版状态迁移时会自动运行。 + 不显示提示运行,并且只应用安全迁移(配置规范化 + 磁盘状态移动)。跳过需要人工确认的重启/服务/沙箱操作。检测到旧版状态迁移时会自动运行。 @@ -62,77 +62,77 @@ openclaw doctor openclaw doctor --deep ``` - 扫描系统服务中的额外 Gateway 网关安装(launchd/systemd/schtasks)。 + 扫描系统服务,查找额外的 Gateway 网关安装(launchd/systemd/schtasks)。 -如果你想在写入前查看更改,请先打开配置文件: +如果你想在写入前审查更改,请先打开配置文件: ```bash cat ~/.openclaw/openclaw.json ``` -## 它的作用(摘要) +## 它会做什么(摘要) - - - git 安装的可选预检更新(仅交互模式)。 - - UI 协议新鲜度检查(当协议 schema 更新时重建 Control UI)。 + + - 对 git 安装执行可选的预检更新(仅交互模式)。 + - UI 协议新鲜度检查(当协议 schema 较新时重建 Control UI)。 - 健康检查 + 重启提示。 - - Skills 状态摘要(符合条件/缺失/被阻止)和插件状态。 + - Skills Status 摘要(可用/缺失/被阻止)和插件 Status。 - - - 旧版值的配置规范化。 + + - 针对旧版值的配置规范化。 - 将 Talk 配置从旧版扁平 `talk.*` 字段迁移到 `talk.provider` + `talk.providers.`。 - - 针对旧版 Chrome 扩展配置和 Chrome MCP 就绪状态的浏览器迁移检查。 + - 浏览器迁移检查,覆盖旧版 Chrome 扩展配置和 Chrome MCP 就绪状态。 - OpenCode 提供商覆盖警告(`models.providers.opencode` / `models.providers.opencode-go`)。 - Codex OAuth 遮蔽警告(`models.providers.openai-codex`)。 - OpenAI Codex OAuth profile 的 OAuth TLS 前置条件检查。 - - 当 `plugins.allow` 具有限制性但工具策略仍请求通配符或插件自有工具时,发出插件/工具 allowlist 警告。 - - 旧版磁盘状态迁移(会话/智能体目录/WhatsApp 认证)。 - - 旧版插件清单合约键迁移(`speechProviders`、`realtimeTranscriptionProviders`、`realtimeVoiceProviders`、`mediaUnderstandingProviders`、`imageGenerationProviders`、`videoGenerationProviders`、`webFetchProviders`、`webSearchProviders` → `contracts`)。 - - 旧版 cron 存储迁移(`jobId`、`schedule.cron`、顶层 delivery/payload 字段、payload `provider`、简单的 `notify: true` webhook fallback 任务)。 - - 旧版智能体运行时策略迁移到 `agents.defaults.agentRuntime` 和 `agents.list[].agentRuntime`。 - - 插件启用时清理过时的插件配置;当 `plugins.enabled=false` 时,过时的插件引用会被视为惰性 containment 配置并保留。 + - 当 `plugins.allow` 具有限制性但工具策略仍请求通配符或插件拥有的工具时,发出插件/工具 allowlist 警告。 + - 旧版磁盘状态迁移(会话/agent 目录/WhatsApp auth)。 + - 旧版插件清单契约键迁移(`speechProviders`、`realtimeTranscriptionProviders`、`realtimeVoiceProviders`、`mediaUnderstandingProviders`、`imageGenerationProviders`、`videoGenerationProviders`、`webFetchProviders`、`webSearchProviders` → `contracts`)。 + - 旧版 cron 存储迁移(`jobId`、`schedule.cron`、顶层 delivery/payload 字段、payload `provider`、简单 `notify: true` webhook fallback jobs)。 + - 旧版智能体 runtime-policy 迁移到 `agents.defaults.agentRuntime` 和 `agents.list[].agentRuntime`。 + - 启用插件时清理过期插件配置;当 `plugins.enabled=false` 时,过期插件引用会被视为惰性的 containment 配置并被保留。 - - - 会话锁文件检查和过时锁清理。 + + - 会话锁文件检查和过期锁清理。 - 修复受影响的 2026.4.24 构建创建的重复 prompt-rewrite 分支的会话 transcript。 - - 卡住的 subagent 重启恢复墓碑检测,支持通过 `--fix` 清除过时的 aborted recovery 标志,避免启动持续将子进程视为 restart-aborted。 + - 检测卡住的 subagent 重启恢复 tombstone,支持使用 `--fix` 清除过期的已中止恢复标志,避免启动时继续将子进程视为 restart-aborted。 - 状态完整性和权限检查(会话、transcript、状态目录)。 - - 本地运行时的配置文件权限检查(chmod 600)。 - - 模型认证健康状况:检查 OAuth 过期状态,可以刷新即将过期的 token,并报告 auth-profile 冷却/禁用状态。 + - 本地运行时检查配置文件权限(chmod 600)。 + - 模型 auth 健康:检查 OAuth 过期状态,可刷新即将过期的 token,并报告 auth-profile cooldown/disabled 状态。 - 额外工作区目录检测(`~/openclaw`)。 - - - 启用沙箱隔离时的沙箱镜像修复。 + + - 启用沙箱隔离时修复沙箱镜像。 - 旧版服务迁移和额外 Gateway 网关检测。 - Matrix 渠道旧版状态迁移(在 `--fix` / `--repair` 模式下)。 - Gateway 网关运行时检查(服务已安装但未运行;缓存的 launchd label)。 - - 渠道状态警告(从运行中的 Gateway 网关探测)。 - - Supervisor 配置审计(launchd/systemd/schtasks)以及可选修复。 - - 清理 Gateway 网关服务的嵌入式代理环境,这些服务在安装或更新期间捕获了 shell `HTTP_PROXY` / `HTTPS_PROXY` / `NO_PROXY` 值。 - - Gateway 网关运行时最佳实践检查(Node 与 Bun、版本管理器路径)。 + - 渠道 Status 警告(从正在运行的 Gateway 网关探测)。 + - supervisor 配置审计(launchd/systemd/schtasks),可选择修复。 + - 清理 Gateway 网关服务的嵌入式 proxy 环境,这些服务在安装或更新期间捕获了 shell `HTTP_PROXY` / `HTTPS_PROXY` / `NO_PROXY` 值。 + - Gateway 网关运行时最佳实践检查(Node vs Bun,版本管理器路径)。 - Gateway 网关端口冲突诊断(默认 `18789`)。 - - - 开放私信策略的安全警告。 - - local token 模式的 Gateway 网关认证检查(当不存在 token 来源时提供 token 生成;不会覆盖 token SecretRef 配置)。 - - 设备配对问题检测(待处理的首次配对请求、待处理的角色/范围升级、过时的本地 device-token 缓存漂移,以及 paired-record 认证漂移)。 + + - 针对开放私信策略的安全警告。 + - local token 模式的 Gateway 网关 auth 检查(当不存在 token 来源时提供 token 生成;不会覆盖 token SecretRef 配置)。 + - 设备配对问题检测(待处理的首次配对请求、待处理的 role/scope 升级、过期本地 device-token 缓存漂移,以及 paired-record auth 漂移)。 - + - Linux 上的 systemd linger 检查。 - - 工作区 bootstrap 文件大小检查(上下文文件的截断/接近限制警告)。 - - 默认智能体的 Skills 就绪检查;报告缺少 bin、环境变量、配置或操作系统要求的已允许 Skills,且 `--fix` 可以在 `skills.entries` 中禁用不可用 Skills。 - - Shell completion 状态检查和自动安装/升级。 + - 工作区 bootstrap 文件大小检查(针对 context 文件的截断/接近限制警告)。 + - 默认智能体的 Skills 就绪检查;报告缺少 bin、env、配置或 OS 要求的已允许 Skills,并且 `--fix` 可在 `skills.entries` 中禁用不可用的 Skills。 + - shell completion Status 检查和自动安装/升级。 - 记忆搜索 embedding 提供商就绪检查(本地模型、远程 API key 或 QMD binary)。 - - 源码安装检查(pnpm 工作区不匹配、缺少 UI asset、缺少 tsx binary)。 + - 源码安装检查(pnpm workspace mismatch、缺失 UI assets、缺失 tsx binary)。 - 写入更新后的配置 + 向导元数据。 @@ -140,57 +140,57 @@ cat ~/.openclaw/openclaw.json ## Dreams UI 回填和重置 -Control UI Dreams 场景包含用于 grounded dreaming 工作流的 **回填**、**重置** 和 **清除 Grounded** 操作。这些操作使用 Gateway 网关 doctor 风格的 RPC 方法,但它们**不**属于 `openclaw doctor` CLI 修复/迁移。 +Control UI 的 Dreams scene 包含用于 grounded dreaming 工作流的 **Backfill**、**Reset** 和 **Clear Grounded** 操作。这些操作使用 Gateway 网关 doctor-style RPC 方法,但它们**不是** `openclaw doctor` CLI 修复/迁移的一部分。 它们会做什么: -- **回填** 会扫描活动工作区中的历史 `memory/YYYY-MM-DD.md` 文件,运行 grounded REM diary pass,并将可逆的回填条目写入 `DREAMS.md`。 -- **重置** 只会从 `DREAMS.md` 中移除这些带标记的回填 diary 条目。 -- **清除 Grounded** 只会移除来自历史 replay、且尚未积累 live recall 或 daily support 的 staged grounded-only short-term 条目。 +- **Backfill** 扫描活动工作区中的历史 `memory/YYYY-MM-DD.md` 文件,运行 grounded REM diary pass,并将可逆的回填条目写入 `DREAMS.md`。 +- **Reset** 只从 `DREAMS.md` 中移除那些已标记的回填 diary 条目。 +- **Clear Grounded** 只移除来自历史 replay、尚未积累 live recall 或 daily support 的 staged grounded-only short-term 条目。 它们本身**不会**做什么: - 它们不会编辑 `MEMORY.md` -- 它们不会运行完整的 doctor 迁移 -- 它们不会自动将 grounded candidates 暂存到 live short-term promotion store,除非你先显式运行 staged CLI 路径 +- 它们不会运行完整 doctor 迁移 +- 它们不会自动将 grounded candidates stage 到 live short-term promotion store,除非你先显式运行 staged CLI path -如果你想让 grounded 历史 replay 影响正常的深度提升通道,请改用 CLI 流程: +如果你想让 grounded historical replay 影响正常的 deep promotion lane,请改用 CLI 流程: ```bash openclaw memory rem-backfill --path ./memory --stage-short-term ``` -这会将 grounded durable candidates 暂存到 short-term dreaming store,同时保留 `DREAMS.md` 作为 review surface。 +这会将 grounded durable candidates stage 到 short-term dreaming store,同时将 `DREAMS.md` 保留为审查界面。 -## 详细行为和原理 +## 详细行为和理由 - + 如果这是 git checkout 且 doctor 正在交互式运行,它会在运行 doctor 前提供更新(fetch/rebase/build)选项。 - - 如果配置包含旧版值形态(例如没有渠道特定覆盖的 `messages.ackReaction`),doctor 会将其规范化为当前 schema。 + + 如果配置包含旧版值形状(例如没有渠道专属覆盖的 `messages.ackReaction`),doctor 会将它们规范化为当前 schema。 - 这包括旧版 Talk 扁平字段。当前公开 Talk 配置是 `talk.provider` + `talk.providers.`。Doctor 会将旧的 `talk.voiceId` / `talk.voiceAliases` / `talk.modelId` / `talk.outputFormat` / `talk.apiKey` 形态重写到 provider map 中。 + 这包括旧版 Talk 扁平字段。当前公开的 Talk 配置是 `talk.provider` + `talk.providers.`。Doctor 会将旧的 `talk.voiceId` / `talk.voiceAliases` / `talk.modelId` / `talk.outputFormat` / `talk.apiKey` 形状重写到 provider map 中。 当 `plugins.allow` 非空且工具策略使用 - 通配符或插件自有工具条目时,Doctor 也会发出警告。`tools.allow: ["*"]` 只匹配 - 来自实际加载插件的工具;它不会绕过独占的插件 - allowlist。Doctor 会为迁移后的 - 旧版 allowlist 配置写入 `plugins.bundledDiscovery: "compat"`,以保留现有内置提供商行为,并且 - 随后指向更严格的 `"allowlist"` 设置。 + 通配符或插件拥有的工具条目时,Doctor 也会发出警告。`tools.allow: ["*"]` 只匹配 + 实际加载的插件中的工具;它不会绕过独占插件 + allowlist。Doctor 会为已迁移的 + 旧版 allowlist 配置写入 `plugins.bundledDiscovery: "compat"`, + 以保留现有内置提供商行为,然后指向更严格的 `"allowlist"` 设置。 - - 当配置包含已弃用的键时,其他命令会拒绝运行,并要求你运行 `openclaw doctor`。 + + 当配置包含已弃用键时,其他命令会拒绝运行,并要求你运行 `openclaw doctor`。 - Doctor 会: + Doctor 将会: - 说明发现了哪些旧版键。 - 显示它应用的迁移。 - 使用更新后的 schema 重写 `~/.openclaw/openclaw.json`。 - 当 Gateway 网关在启动时检测到旧版配置格式,它也会自动运行 doctor 迁移,因此过时的配置无需人工干预即可修复。Cron 任务存储迁移由 `openclaw doctor --fix` 处理。 + Gateway 网关在启动时检测到旧版配置格式时,也会自动运行 doctor 迁移,因此过期配置无需人工干预即可修复。Cron job store 迁移由 `openclaw doctor --fix` 处理。 当前迁移: @@ -206,176 +206,176 @@ openclaw memory rem-backfill --path ./memory --stage-short-term - 旧版 `talk.voiceId`/`talk.voiceAliases`/`talk.modelId`/`talk.outputFormat`/`talk.apiKey` → `talk.provider` + `talk.providers.` - `routing.agentToAgent` → `tools.agentToAgent` - `routing.transcribeAudio` → `tools.media.audio.models` - - `messages.tts.` (`openai`/`elevenlabs`/`microsoft`/`edge`) → `messages.tts.providers.` + - `messages.tts.`(`openai`/`elevenlabs`/`microsoft`/`edge`)→ `messages.tts.providers.` - `messages.tts.provider: "edge"` 和 `messages.tts.providers.edge` → `messages.tts.provider: "microsoft"` 和 `messages.tts.providers.microsoft` - - `channels.discord.voice.tts.` (`openai`/`elevenlabs`/`microsoft`/`edge`) → `channels.discord.voice.tts.providers.` - - `channels.discord.accounts..voice.tts.` (`openai`/`elevenlabs`/`microsoft`/`edge`) → `channels.discord.accounts..voice.tts.providers.` - - `plugins.entries.voice-call.config.tts.` (`openai`/`elevenlabs`/`microsoft`/`edge`) → `plugins.entries.voice-call.config.tts.providers.` + - `channels.discord.voice.tts.`(`openai`/`elevenlabs`/`microsoft`/`edge`)→ `channels.discord.voice.tts.providers.` + - `channels.discord.accounts..voice.tts.`(`openai`/`elevenlabs`/`microsoft`/`edge`)→ `channels.discord.accounts..voice.tts.providers.` + - `plugins.entries.voice-call.config.tts.`(`openai`/`elevenlabs`/`microsoft`/`edge`)→ `plugins.entries.voice-call.config.tts.providers.` - `plugins.entries.voice-call.config.tts.provider: "edge"` 和 `plugins.entries.voice-call.config.tts.providers.edge` → `provider: "microsoft"` 和 `providers.microsoft` - `plugins.entries.voice-call.config.provider: "log"` → `"mock"` - `plugins.entries.voice-call.config.twilio.from` → `plugins.entries.voice-call.config.fromNumber` - `plugins.entries.voice-call.config.streaming.sttProvider` → `plugins.entries.voice-call.config.streaming.provider` - `plugins.entries.voice-call.config.streaming.openaiApiKey|sttModel|silenceDurationMs|vadThreshold` → `plugins.entries.voice-call.config.streaming.providers.openai.*` - `bindings[].match.accountID` → `bindings[].match.accountId` - - 对于带有命名 `accounts` 但仍残留单账号顶层渠道值的渠道,将这些账号作用域的值移动到为该渠道选定并提升的账号中(大多数渠道使用 `accounts.default`;Matrix 可以保留现有匹配的命名/默认目标) + - 对于有命名 `accounts` 但仍残留单账号顶层渠道值的渠道,将这些账号作用域的值移入为该渠道提升的账号(大多数渠道为 `accounts.default`;Matrix 可以保留现有的匹配命名/默认目标) - `identity` → `agents.list[].identity` - - `agent.*` → `agents.defaults` + `tools.*` (tools/elevated/exec/sandbox/subagents) + - `agent.*` → `agents.defaults` + `tools.*`(工具/提升权限/执行/沙箱/子智能体) - `agent.model`/`allowedModels`/`modelAliases`/`modelFallbacks`/`imageModelFallbacks` → `agents.defaults.models` + `agents.defaults.model.primary/fallbacks` + `agents.defaults.imageModel.primary/fallbacks` - - 移除 `agents.defaults.llm`;对较慢的提供商/模型超时使用 `models.providers..timeoutSeconds` + - 移除 `agents.defaults.llm`;对慢速提供商/模型超时使用 `models.providers..timeoutSeconds` - `browser.ssrfPolicy.allowPrivateNetwork` → `browser.ssrfPolicy.dangerouslyAllowPrivateNetwork` - `browser.profiles.*.driver: "extension"` → `"existing-session"` - - 移除 `browser.relayBindHost`(旧版扩展中继设置) - - 旧版 `models.providers.*.api: "openai"` → `"openai-completions"`(Gateway 网关启动时也会跳过 `api` 设置为未来或未知枚举值的提供商,而不是以关闭失败结束) + - 移除 `browser.relayBindHost`(旧版插件中继设置) + - 旧版 `models.providers.*.api: "openai"` → `"openai-completions"`(Gateway 网关启动时也会跳过 `api` 设置为未来或未知枚举值的提供商,而不是关闭失败) Doctor 警告还包括多账号渠道的账号默认值指导: - - 如果配置了两个或更多 `channels..accounts` 条目,但没有配置 `channels..defaultAccount` 或 `accounts.default`,Doctor 会警告后备路由可能选中意外的账号。 + - 如果配置了两个或更多 `channels..accounts` 条目,但未配置 `channels..defaultAccount` 或 `accounts.default`,Doctor 会警告回退路由可能选中意外的账号。 - 如果 `channels..defaultAccount` 设置为未知账号 ID,Doctor 会警告并列出已配置的账号 ID。 - - 如果你手动添加了 `models.providers.opencode`、`opencode-zen` 或 `opencode-go`,它会覆盖来自 `@mariozechner/pi-ai` 的内置 OpenCode 目录。这可能会强制模型使用错误的 API,或将成本清零。Doctor 会发出警告,以便你移除该覆盖并恢复按模型的 API 路由和成本。 + + 如果你手动添加了 `models.providers.opencode`、`opencode-zen` 或 `opencode-go`,它会覆盖来自 `@mariozechner/pi-ai` 的内置 OpenCode 目录。这可能会强制模型使用错误的 API,或将成本清零。Doctor 会发出警告,以便你移除该覆盖项并恢复按模型的 API 路由和成本。 - + 如果你的浏览器配置仍指向已移除的 Chrome 扩展路径,Doctor 会将其规范化为当前的主机本地 Chrome MCP 附加模型: - `browser.profiles.*.driver: "extension"` 变为 `"existing-session"` - `browser.relayBindHost` 会被移除 - 当你使用 `defaultProfile: "user"` 或已配置的 `existing-session` 配置文件时,Doctor 也会审计主机本地 Chrome MCP 路径: + 当你使用 `defaultProfile: "user"` 或已配置的 `existing-session` 配置文件时,Doctor 还会审计主机本地 Chrome MCP 路径: - - 检查同一主机上是否为默认自动连接配置文件安装了 Google Chrome + - 检查同一主机上是否安装了 Google Chrome,以用于默认自动连接配置文件 - 检查检测到的 Chrome 版本,并在低于 Chrome 144 时发出警告 - - 提醒你在浏览器检查页面启用远程调试(例如 `chrome://inspect/#remote-debugging`、`brave://inspect/#remote-debugging` 或 `edge://inspect/#remote-debugging`) + - 提醒你在浏览器检查页面中启用远程调试(例如 `chrome://inspect/#remote-debugging`、`brave://inspect/#remote-debugging` 或 `edge://inspect/#remote-debugging`) - Doctor 不能替你启用 Chrome 侧设置。主机本地 Chrome MCP 仍然需要: + Doctor 无法替你启用 Chrome 端设置。主机本地 Chrome MCP 仍然需要: - Gateway 网关/节点主机上有基于 Chromium 的浏览器 144+ - 浏览器在本地运行 - - 该浏览器已启用远程调试 + - 该浏览器中已启用远程调试 - 在浏览器中批准首次附加同意提示 - 这里的就绪状态只涉及本地附加前置条件。Existing-session 保留当前的 Chrome MCP 路由限制;`responsebody`、PDF 导出、下载拦截和批量操作等高级路由仍需要托管浏览器或原始 CDP 配置文件。 + 这里的就绪状态仅关乎本地附加前置条件。Existing-session 保持当前 Chrome MCP 路由限制;`responsebody`、PDF 导出、下载拦截和批量操作等高级路由仍需要托管浏览器或原始 CDP 配置文件。 此检查**不**适用于 Docker、沙箱、远程浏览器或其他无头流程。它们会继续使用原始 CDP。 - - 配置 OpenAI Codex OAuth 配置文件后,Doctor 会探测 OpenAI 授权端点,以验证本地 Node/OpenSSL TLS 栈能否校验证书链。如果探测因证书错误失败(例如 `UNABLE_TO_GET_ISSUER_CERT_LOCALLY`、证书过期或自签名证书),Doctor 会打印平台特定的修复指导。在使用 Homebrew Node 的 macOS 上,修复通常是 `brew postinstall ca-certificates`。使用 `--deep` 时,即使 Gateway 网关健康,也会运行该探测。 + + 配置 OpenAI Codex OAuth 配置文件后,Doctor 会探测 OpenAI 授权端点,验证本地 Node/OpenSSL TLS 栈能否验证证书链。如果探测因证书错误而失败(例如 `UNABLE_TO_GET_ISSUER_CERT_LOCALLY`、证书过期或自签名证书),Doctor 会输出特定于平台的修复指导。在 macOS 上使用 Homebrew Node 时,修复通常是 `brew postinstall ca-certificates`。使用 `--deep` 时,即使 Gateway 网关健康,探测也会运行。 - - 如果你之前在 `models.providers.openai-codex` 下添加了旧版 OpenAI 传输设置,它们可能会遮蔽新版自动使用的内置 Codex OAuth provider 路径。当 Doctor 看到这些旧传输设置与 Codex OAuth 同时存在时,会发出警告,以便你移除或重写过期的传输覆盖,并恢复内置路由/后备行为。自定义代理和仅标头覆盖仍受支持,且不会触发此警告。 + + 如果你之前在 `models.providers.openai-codex` 下添加过旧版 OpenAI 传输设置,它们可能会遮蔽较新版本自动使用的内置 Codex OAuth 提供商路径。Doctor 在看到这些旧传输设置与 Codex OAuth 同时存在时会发出警告,以便你移除或重写过时的传输覆盖项,并恢复内置路由/回退行为。自定义代理和仅标头覆盖仍受支持,且不会触发此警告。 - - 启用内置 Codex 插件后,Doctor 还会检查 `openai-codex/*` 主模型引用是否仍通过默认 PI 运行器解析。当你想通过 PI 使用 Codex OAuth/订阅凭证时,这种组合是有效的,但它很容易与原生 Codex 应用服务器 harness 混淆。Doctor 会警告并指向显式的应用服务器形态:`openai/*` 加 `agentRuntime.id: "codex"` 或 `OPENCLAW_AGENT_RUNTIME=codex`。 + + 启用内置 Codex 插件时,Doctor 还会检查 `openai-codex/*` 主模型引用是否仍通过默认 PI 运行器解析。当你希望通过 PI 使用 Codex OAuth/订阅凭证时,此组合是有效的,但它很容易与原生 Codex 应用服务器 harness 混淆。Doctor 会发出警告,并指向显式应用服务器形态:`openai/*` 加 `agentRuntime.id: "codex"` 或 `OPENCLAW_AGENT_RUNTIME=codex`。 Doctor 不会自动修复此问题,因为两条路由都有效: - `openai-codex/*` + PI 表示“通过普通 OpenClaw 运行器使用 Codex OAuth/订阅凭证。” - - `openai/*` + `agentRuntime.id: "codex"` 表示“通过原生 Codex 应用服务器运行嵌入式轮次。” + - `openai/*` + `agentRuntime.id: "codex"` 表示“通过原生 Codex app-server 运行嵌入式轮次。” - `/codex ...` 表示“从聊天中控制或绑定原生 Codex 对话。” - `/acp ...` 或 `runtime: "acp"` 表示“使用外部 ACP/acpx 适配器。” - 如果出现该警告,请选择你原本打算使用的路由,并手动编辑配置。当 PI Codex OAuth 是有意配置时,请保持该警告原样。 + 如果出现该警告,请选择你原本打算使用的路由并手动编辑配置。当 PI Codex OAuth 是有意使用时,请保持该警告不变。 - - 当你将已配置的默认/后备模型或运行时从 Codex 等插件拥有的路由迁移走后,Doctor 还会扫描活动会话存储中是否有过期的自动创建路由状态。 + + 在你将配置的默认/回退模型或运行时从 Codex 这类插件拥有的路由移开后,Doctor 还会扫描活动会话存储中陈旧的自动创建路由状态。 - `openclaw doctor --fix` 可以清除自动创建的过期状态,例如 `modelOverrideSource: "auto"` 模型固定、运行时模型元数据、固定的 harness ID、CLI 会话绑定,以及当其所属路由不再配置时的自动凭证配置文件覆盖。显式用户或旧版会话模型选择会报告给你手动审查并保持不变;当不再打算使用该路由时,请用 `/model ...`、`/new` 切换,或重置该会话。 + `openclaw doctor --fix` 可以清除自动创建的陈旧状态,例如 `modelOverrideSource: "auto"` 模型固定、运行时模型元数据、固定的 harness ID、CLI 会话绑定,以及拥有路由不再配置时的自动凭证配置覆盖。显式用户或旧版会话模型选择会被报告以供手动审查,并保持不变;当不再打算使用该路由时,请用 `/model ...`、`/new` 切换它们,或重置会话。 - + Doctor 可以将较旧的磁盘布局迁移到当前结构: - - 会话存储 + 转录记录: + - 会话存储 + 转录: - 从 `~/.openclaw/sessions/` 到 `~/.openclaw/agents//sessions/` - - Agent 目录: + - 智能体目录: - 从 `~/.openclaw/agent/` 到 `~/.openclaw/agents//agent/` - WhatsApp 凭证状态(Baileys): - 从旧版 `~/.openclaw/credentials/*.json`(`oauth.json` 除外) - - 到 `~/.openclaw/credentials/whatsapp//...`(默认账号 ID:`default`) + - 到 `~/.openclaw/credentials/whatsapp//...`(默认账户 ID:`default`) - 这些迁移是尽力而为且幂等的;当 Doctor 将任何旧版文件夹作为备份保留时,会发出警告。Gateway 网关/CLI 也会在启动时自动迁移旧版会话 + Agent 目录,因此历史记录/凭证/模型会落在按 agent 划分的路径中,而无需手动运行 Doctor。WhatsApp 凭证有意只通过 `openclaw doctor` 迁移。Talk 提供商/提供商映射规范化现在按结构相等性比较,因此仅键顺序不同的差异不再触发重复的空操作 `doctor --fix` 变更。 + 这些迁移是尽力而为且幂等的;当 Doctor 将任何旧版文件夹作为备份留在原处时,它会发出警告。Gateway 网关/CLI 也会在启动时自动迁移旧版会话 + 智能体目录,因此历史记录/凭证/模型无需手动运行 Doctor 即可落到按智能体划分的路径中。WhatsApp 凭证有意只通过 `openclaw doctor` 迁移。Talk 提供商/provider-map 规范化现在按结构相等性比较,因此仅键顺序不同的差异不再触发重复的无操作 `doctor --fix` 更改。 - - Doctor 会扫描所有已安装的插件清单,查找已弃用的顶层能力键(`speechProviders`、`realtimeTranscriptionProviders`、`realtimeVoiceProviders`、`mediaUnderstandingProviders`、`imageGenerationProviders`、`videoGenerationProviders`、`webFetchProviders`、`webSearchProviders`)。找到后,它会提出将它们移动到 `contracts` 对象中,并就地重写清单文件。此迁移是幂等的;如果 `contracts` 键已经有相同的值,旧键会被移除,而不会复制数据。 + + Doctor 会扫描所有已安装插件清单,查找已弃用的顶级能力键(`speechProviders`、`realtimeTranscriptionProviders`、`realtimeVoiceProviders`、`mediaUnderstandingProviders`、`imageGenerationProviders`、`videoGenerationProviders`、`webFetchProviders`、`webSearchProviders`)。找到后,它会提示将它们移入 `contracts` 对象,并就地重写清单文件。此迁移是幂等的;如果 `contracts` 键已经有相同的值,则会移除旧版键,而不会重复数据。 - - Doctor 还会检查 cron 作业存储(默认是 `~/.openclaw/cron/jobs.json`,或在覆盖时使用 `cron.store`),查找调度器为了兼容性仍接受的旧作业形态。 + + Doctor 还会检查 cron 作业存储(默认是 `~/.openclaw/cron/jobs.json`,覆盖时为 `cron.store`),查找调度器为了兼容性仍接受的旧作业形态。 当前 cron 清理包括: - `jobId` → `id` - `schedule.cron` → `schedule.expr` - - 顶层载荷字段(`message`、`model`、`thinking`、...)→ `payload` - - 顶层投递字段(`deliver`、`channel`、`to`、`provider`、...)→ `delivery` - - 载荷 `provider` 投递别名 → 显式 `delivery.channel` - - 简单旧版 `notify: true` webhook 后备作业 → 显式 `delivery.mode="webhook"`,并带有 `delivery.to=cron.webhook` + - 顶级载荷字段(`message`、`model`、`thinking`、...)→ `payload` + - 顶级递送字段(`deliver`、`channel`、`to`、`provider`、...)→ `delivery` + - 载荷 `provider` 递送别名 → 显式 `delivery.channel` + - 简单旧版 `notify: true` webhook 后备作业 → 显式 `delivery.mode="webhook"`,并设置 `delivery.to=cron.webhook` - Doctor 只有在不改变行为的情况下,才会自动迁移 `notify: true` 作业。如果某个作业将旧版通知后备与现有非 webhook 投递模式组合在一起,Doctor 会警告并将该作业留给手动审查。 + Doctor 只会在不改变行为的情况下自动迁移 `notify: true` 作业。如果某个作业将旧版通知后备与现有的非 webhook 递送模式结合使用,Doctor 会发出警告,并将该作业留给手动审查。 - 在 Linux 上,当用户的 crontab 仍调用旧版 `~/.openclaw/bin/ensure-whatsapp.sh` 时,Doctor 也会发出警告。当前 OpenClaw 不再维护这个主机本地脚本;当 cron 无法访问 systemd 用户总线时,它可能会向 `~/.openclaw/logs/whatsapp-health.log` 写入错误的 `Gateway inactive` 消息。使用 `crontab -e` 移除过时的 crontab 条目;使用 `openclaw channels status --probe`、`openclaw doctor` 和 `openclaw gateway status` 执行当前健康检查。 + 在 Linux 上,当用户的 crontab 仍调用旧版 `~/.openclaw/bin/ensure-whatsapp.sh` 时,Doctor 也会发出警告。该主机本地脚本不由当前 OpenClaw 维护,并且当 cron 无法访问 systemd 用户总线时,可能会向 `~/.openclaw/logs/whatsapp-health.log` 写入错误的 `Gateway inactive` 消息。使用 `crontab -e` 删除过时的 crontab 条目;使用 `openclaw channels status --probe`、`openclaw doctor` 和 `openclaw gateway status` 执行当前健康检查。 - Doctor 会扫描每个智能体会话目录,查找过时的写入锁文件,即会话异常退出后遗留的文件。对于找到的每个锁文件,它会报告:路径、PID、PID 是否仍存活、锁龄,以及它是否被视为过时(PID 已死亡或超过 30 分钟)。在 `--fix` / `--repair` 模式下,它会自动移除过时的锁文件;否则会打印提示,并指示你使用 `--fix` 重新运行。 + Doctor 会扫描每个智能体会话目录,查找过时的写入锁文件,也就是会话异常退出后留下的文件。对于找到的每个锁文件,它会报告:路径、PID、该 PID 是否仍然存活、锁的存在时长,以及是否被视为过时(PID 已死或超过 30 分钟)。在 `--fix` / `--repair` 模式下,它会自动移除过时的锁文件;否则会打印一条说明,并指示你使用 `--fix` 重新运行。 - Doctor 会扫描智能体会话 JSONL 文件,查找 2026.4.24 提示词转录重写缺陷创建的重复分支形态:一个包含 OpenClaw 内部运行时上下文的废弃用户轮次,以及一个包含相同可见用户提示词的活跃同级分支。在 `--fix` / `--repair` 模式下,Doctor 会在原文件旁备份每个受影响文件,并将转录重写到活跃分支,使 Gateway 网关历史记录和记忆读取器不再看到重复轮次。 + Doctor 会扫描智能体会话 JSONL 文件,查找由 2026.4.24 提示词转录重写错误创建的重复分支形态:一个被废弃的用户轮次,包含 OpenClaw 内部运行时上下文,以及一个活跃的同级分支,包含相同的可见用户提示词。在 `--fix` / `--repair` 模式下,Doctor 会在原文件旁备份每个受影响文件,并将转录重写为活跃分支,这样 Gateway 网关历史记录和记忆读取器就不再看到重复轮次。 - 状态目录是运行时的核心枢纽。如果它消失,你会丢失会话、凭证、日志和配置(除非你在其他位置有备份)。 + 状态目录是运行中的关键中枢。如果它消失,你会丢失会话、凭证、日志和配置(除非你在其他地方有备份)。 Doctor 会检查: - - **状态目录缺失**:警告灾难性状态丢失,提示重新创建目录,并提醒你它无法恢复丢失的数据。 - - **状态目录权限**:验证可写性;提供修复权限的选项(当检测到所有者/组不匹配时,会输出 `chown` 提示)。 - - **macOS 云同步状态目录**:当状态解析到 iCloud Drive(`~/Library/Mobile Documents/com~apple~CloudDocs/...`)或 `~/Library/CloudStorage/...` 下时发出警告,因为同步支持的路径可能导致较慢的 I/O 以及锁/同步竞争。 - - **Linux SD 或 eMMC 状态目录**:当状态解析到 `mmcblk*` 挂载源时发出警告,因为 SD 或 eMMC 支持的随机 I/O 在会话和凭证写入下可能更慢且更易磨损。 + - **状态目录缺失**:警告灾难性状态丢失,提示重新创建目录,并提醒你它无法恢复缺失数据。 + - **状态目录权限**:验证可写性;提供修复权限的选项(并在检测到所有者/组不匹配时发出 `chown` 提示)。 + - **macOS 云同步状态目录**:当状态解析到 iCloud Drive(`~/Library/Mobile Documents/com~apple~CloudDocs/...`)或 `~/Library/CloudStorage/...` 下时发出警告,因为由同步支持的路径可能导致更慢的 I/O 和锁定/同步竞争。 + - **Linux SD 或 eMMC 状态目录**:当状态解析到 `mmcblk*` 挂载源时发出警告,因为由 SD 或 eMMC 支持的随机 I/O 在会话和凭证写入下可能更慢且磨损更快。 - **会话目录缺失**:`sessions/` 和会话存储目录是持久化历史记录并避免 `ENOENT` 崩溃所必需的。 - **转录不匹配**:当最近的会话条目缺少转录文件时发出警告。 - **主会话“1 行 JSONL”**:当主转录只有一行时标记(历史记录没有累积)。 - - **多个状态目录**:当多个主目录中存在多个 `~/.openclaw` 文件夹,或 `OPENCLAW_STATE_DIR` 指向其他位置时发出警告(历史记录可能在安装之间分裂)。 + - **多个状态目录**:当多个主目录中存在多个 `~/.openclaw` 文件夹,或 `OPENCLAW_STATE_DIR` 指向其他位置时发出警告(历史记录可能会在安装之间拆分)。 - **远程模式提醒**:如果 `gateway.mode=remote`,Doctor 会提醒你在远程主机上运行它(状态位于那里)。 - - **配置文件权限**:如果 `~/.openclaw/openclaw.json` 可被组/所有人读取,则发出警告,并提供收紧到 `600` 的选项。 + - **配置文件权限**:如果 `~/.openclaw/openclaw.json` 可被组/全局读取,则发出警告并提供收紧到 `600` 的选项。 - - Doctor 会检查凭证存储中的 OAuth 配置文件,在令牌即将过期/已过期时发出警告,并在安全时刷新它们。如果 Anthropic OAuth/令牌配置文件过时,它会建议使用 Anthropic API key 或 Anthropic setup-token 路径。刷新提示只会在交互式运行(TTY)时出现;`--non-interactive` 会跳过刷新尝试。 + + Doctor 会检查认证存储中的 OAuth 配置文件,在令牌即将过期/已过期时发出警告,并在安全时刷新它们。如果 Anthropic OAuth/令牌配置文件已过期,它会建议使用 Anthropic API key 或 Anthropic setup-token 路径。刷新提示只会在交互式运行(TTY)时出现;`--non-interactive` 会跳过刷新尝试。 - 当 OAuth 刷新永久失败时(例如 `refresh_token_reused`、`invalid_grant`,或提供商要求你重新登录),Doctor 会报告需要重新认证,并打印要运行的确切 `openclaw models auth login --provider ...` 命令。 + 当 OAuth 刷新永久失败时(例如 `refresh_token_reused`、`invalid_grant`,或提供商提示你重新登录),Doctor 会报告需要重新认证,并打印要运行的确切 `openclaw models auth login --provider ...` 命令。 - Doctor 还会报告因以下原因暂时不可用的凭证配置文件: + Doctor 还会报告由于以下原因暂时不可用的认证配置文件: - 短暂冷却(速率限制/超时/认证失败) - - 较长时间禁用(账单/额度失败) + - 更长时间禁用(账单/额度失败) - 如果设置了 `hooks.gmail.model`,Doctor 会根据目录和允许列表验证模型引用,并在它无法解析或被禁止时发出警告。 + 如果设置了 `hooks.gmail.model`,Doctor 会根据目录和允许列表验证该模型引用,并在它无法解析或被禁止时发出警告。 启用沙箱隔离时,Doctor 会检查 Docker 镜像,并在当前镜像缺失时提供构建或切换到旧版名称的选项。 - Doctor 会在 `openclaw doctor --fix` / `openclaw doctor --repair` 模式下移除旧版 OpenClaw 生成的插件依赖暂存状态。这包括过时的生成依赖根目录、旧安装阶段目录、早期内置插件依赖修复代码留下的包本地残留,以及可能遮蔽当前内置清单的孤立或已恢复的托管 npm 内置 `@openclaw/*` 插件副本。 + Doctor 会在 `openclaw doctor --fix` / `openclaw doctor --repair` 模式下移除旧版 OpenClaw 生成的插件依赖暂存状态。这涵盖过时的生成依赖根目录、旧安装阶段目录、早期内置插件依赖修复代码留下的包本地残留,以及可能遮蔽当前内置清单的孤立或已恢复的托管 npm 内置 `@openclaw/*` 插件副本。 - 当配置引用了可下载插件但本地插件注册表找不到它们时,Doctor 也可以重新安装已配置的可下载插件。对于 2026.5.2 的内置插件外部化,Doctor 会自动安装现有配置已使用的可下载插件,然后依靠 `meta.lastTouchedVersion` 确保该发布迁移只运行一次。Gateway 网关启动和配置重载不会运行包管理器;插件安装仍然是显式的 Doctor/安装/更新工作。 + 当配置引用可下载插件但本地插件注册表找不到它们时,Doctor 也可以重新安装缺失的可下载插件。示例包括实际的 `plugins.entries`、已配置的渠道/提供商/搜索设置,以及已配置的 Agent Runtimes。在包更新期间,Doctor 会避免在核心包正在被替换时运行包管理器插件修复;如果配置的插件仍需恢复,请在更新后再次运行 `openclaw doctor --fix`。Gateway 网关启动和配置重载不会运行包管理器;插件安装仍是显式的 Doctor/安装/更新工作。 - Doctor 会检测旧版 Gateway 网关服务(launchd/systemd/schtasks),并提供移除它们以及使用当前 Gateway 网关端口安装 OpenClaw 服务的选项。它还可以扫描额外的 Gateway 网关类服务并打印清理提示。带配置文件名称的 OpenClaw Gateway 网关服务被视为一等服务,不会被标记为“额外”。 + Doctor 会检测旧版 Gateway 网关服务(launchd/systemd/schtasks),并提供移除它们并使用当前 Gateway 网关端口安装 OpenClaw 服务的选项。它还可以扫描额外的类 Gateway 网关服务并打印清理提示。以配置文件命名的 OpenClaw Gateway 网关服务被视为一等服务,不会被标记为“额外”。 - 在 Linux 上,如果用户级 Gateway 网关服务缺失,但系统级 OpenClaw Gateway 网关服务存在,Doctor 不会自动安装第二个用户级服务。使用 `openclaw gateway status --deep` 或 `openclaw doctor --deep` 检查,然后移除重复项;如果系统监督进程拥有 Gateway 网关生命周期,则设置 `OPENCLAW_SERVICE_REPAIR_POLICY=external`。 + 在 Linux 上,如果缺少用户级 Gateway 网关服务,但存在系统级 OpenClaw Gateway 网关服务,Doctor 不会自动安装第二个用户级服务。使用 `openclaw gateway status --deep` 或 `openclaw doctor --deep` 检查,然后移除重复项,或者当系统监督器拥有 Gateway 网关生命周期时设置 `OPENCLAW_SERVICE_REPAIR_POLICY=external`。 - 当 Matrix 渠道账号有待处理或可执行的旧版状态迁移时,Doctor(在 `--fix` / `--repair` 模式下)会创建迁移前快照,然后运行尽力而为的迁移步骤:旧版 Matrix 状态迁移和旧版加密状态准备。这两个步骤都是非致命的;错误会被记录,启动会继续。在只读模式(不带 `--fix` 的 `openclaw doctor`)下,此检查会被完全跳过。 + 当 Matrix 渠道账户存在待处理或可执行的旧版状态迁移时,Doctor(在 `--fix` / `--repair` 模式下)会创建迁移前快照,然后运行尽力而为的迁移步骤:旧版 Matrix 状态迁移和旧版加密状态准备。这两个步骤都是非致命的;错误会被记录,启动会继续。在只读模式下(不带 `--fix` 的 `openclaw doctor`),此检查会被完全跳过。 - - Doctor 现在会在常规健康检查中检查设备配对状态。 + + Doctor 现在会在正常健康检查中检查设备配对状态。 它会报告: @@ -383,124 +383,124 @@ openclaw memory rem-backfill --path ./memory --stage-short-term - 已配对设备的待处理角色升级 - 已配对设备的待处理作用域升级 - 设备 ID 仍匹配但设备身份不再匹配已批准记录的公钥不匹配修复 - - 缺少已批准角色的活跃令牌的配对记录 - - 作用域漂移到已批准配对基线之外的配对令牌 - - 当前机器上的本地缓存设备令牌条目,这些条目早于 Gateway 网关侧令牌轮换,或携带过时的作用域元数据 + - 缺少已批准角色活跃令牌的配对记录 + - 作用域漂移出已批准配对基线的配对令牌 + - 当前机器上早于 Gateway 网关侧令牌轮换或携带过时作用域元数据的本地缓存设备令牌条目 - Doctor 不会自动批准配对请求,也不会自动轮换设备令牌。它会改为打印确切的后续步骤: + Doctor 不会自动批准配对请求或自动轮换设备令牌。它会改为打印确切的后续步骤: - 使用 `openclaw devices list` 检查待处理请求 - 使用 `openclaw devices approve ` 批准确切请求 - 使用 `openclaw devices rotate --device --role ` 轮换新令牌 - 使用 `openclaw devices remove ` 移除并重新批准过时记录 - 这补上了常见的“已配对但仍提示需要配对”漏洞:Doctor 现在会区分首次配对、待处理角色/作用域升级,以及过时令牌/设备身份漂移。 + 这修复了常见的“已经配对但仍收到需要配对”缺口:Doctor 现在会区分首次配对、待处理的角色/作用域升级,以及过时令牌/设备身份漂移。 当提供商在没有允许列表的情况下向私信开放,或策略以危险方式配置时,Doctor 会发出警告。 - 如果作为 systemd 用户服务运行,Doctor 会确保已启用 linger,使 Gateway 网关在登出后保持运行。 + 如果作为 systemd 用户服务运行,Doctor 会确保已启用 linger,使 Gateway 网关在注销后仍保持运行。 - Doctor 会为默认智能体打印工作区状态摘要: + Doctor 会打印默认智能体的工作区状态摘要: - - **Skills 状态**:统计符合条件、缺少要求和被允许列表阻止的 Skills。 + - **Skills 状态**:统计符合条件、缺少要求以及被允许列表阻止的 Skills。 - **旧版工作区目录**:当 `~/openclaw` 或其他旧版工作区目录与当前工作区并存时发出警告。 - - **插件状态**:统计已启用/已禁用/出错的插件;列出任何错误的插件 ID;报告内置插件能力。 + - **插件状态**:统计已启用/已禁用/出错的插件;列出任何错误对应的插件 ID;报告内置插件能力。 - **插件兼容性警告**:标记与当前运行时存在兼容性问题的插件。 - - **插件诊断**:展示插件注册表在加载时输出的任何警告或错误。 + - **插件诊断**:呈现插件注册表在加载时发出的任何警告或错误。 - - Doctor 会检查工作区引导文件(例如 `AGENTS.md`、`CLAUDE.md` 或其他注入的上下文文件)是否接近或超过配置的字符预算。它会按文件报告原始字符数与注入字符数、截断百分比、截断原因(`max/file` 或 `max/total`),以及总注入字符数占总预算的比例。当文件被截断或接近限制时,Doctor 会打印用于调整 `agents.defaults.bootstrapMaxChars` 和 `agents.defaults.bootstrapTotalMaxChars` 的提示。 + + Doctor 会检查工作区 bootstrap 文件(例如 `AGENTS.md`、`CLAUDE.md` 或其他注入的上下文文件)是否接近或超过配置的字符预算。它会报告每个文件的原始字符数与注入字符数、截断百分比、截断原因(`max/file` 或 `max/total`),以及总注入字符数占总预算的比例。当文件被截断或接近限制时,Doctor 会打印用于调优 `agents.defaults.bootstrapMaxChars` 和 `agents.defaults.bootstrapTotalMaxChars` 的提示。 - 当 `openclaw doctor --fix` 移除缺失的渠道插件时,它也会移除引用该插件的悬空渠道作用域配置:`channels.` 条目、命名该渠道的 Heartbeat 目标,以及 `agents.*.models["/*"]` 覆盖。这可以防止渠道运行时已消失但配置仍要求 Gateway 网关绑定到它而导致的 Gateway 网关启动循环。 + 当 `openclaw doctor --fix` 移除缺失的渠道插件时,它也会移除引用该插件的悬空渠道范围配置:`channels.` 条目、命名该渠道的 Heartbeat 目标,以及 `agents.*.models["/*"]` 覆盖。这可以防止渠道运行时已消失但配置仍要求 Gateway 网关绑定到它而导致的 Gateway 网关启动循环。 Doctor 会检查当前 shell(zsh、bash、fish 或 PowerShell)是否已安装 Tab 补全: - - 如果 shell 配置文件使用较慢的动态补全模式(`source <(openclaw completion ...)`),Doctor 会将其升级为更快的缓存文件变体。 + - 如果 shell 配置文件使用缓慢的动态补全模式(`source <(openclaw completion ...)`),Doctor 会将其升级为更快的缓存文件变体。 - 如果补全已在配置文件中配置但缓存文件缺失,Doctor 会自动重新生成缓存。 - 如果完全没有配置补全,Doctor 会提示安装它(仅交互模式;使用 `--non-interactive` 时跳过)。 运行 `openclaw completion --write-state` 可手动重新生成缓存。 - + Doctor 会检查本地 Gateway 网关令牌认证就绪状态。 - - 如果令牌模式需要令牌但不存在令牌来源,Doctor 会提供生成一个令牌的选项。 + - 如果令牌模式需要令牌且不存在令牌来源,Doctor 会提供生成令牌的选项。 - 如果 `gateway.auth.token` 由 SecretRef 管理但不可用,Doctor 会发出警告,并且不会用明文覆盖它。 - `openclaw doctor --generate-gateway-token` 仅在未配置令牌 SecretRef 时强制生成。 - + 某些修复流程需要检查已配置的凭证,同时不削弱运行时快速失败行为。 - - `openclaw doctor --fix` 现在对定向配置修复使用与 Status 系列命令相同的只读 SecretRef 摘要模型。 - - 示例:Telegram `allowFrom` / `groupAllowFrom` `@username` 修复会在可用时尝试使用已配置的 bot 凭证。 - - 如果 Telegram bot 令牌通过 SecretRef 配置,但在当前命令路径中不可用,Doctor 会报告该凭证已配置但不可用,并跳过自动解析,而不是崩溃或误报令牌缺失。 + - `openclaw doctor --fix` 现在对定向配置修复使用与 status 系列命令相同的只读 SecretRef 摘要模型。 + - 示例:Telegram `allowFrom` / `groupAllowFrom` `@username` 修复会在可用时尝试使用已配置的机器人凭证。 + - 如果 Telegram 机器人令牌通过 SecretRef 配置,但在当前命令路径中不可用,doctor 会报告该凭证已配置但不可用,并跳过自动解析,而不是崩溃或误报令牌缺失。 Doctor 会运行健康检查,并在 Gateway 网关看起来不健康时提示重启。 - Doctor 会检查已配置的记忆搜索嵌入提供商是否已为默认智能体准备就绪。行为取决于已配置的后端和提供商: + Doctor 会检查已配置的记忆搜索嵌入提供商是否已为默认智能体就绪。行为取决于已配置的后端和提供商: - - **QMD 后端**:探测 `qmd` 二进制文件是否可用且可启动。如果不可用,会打印修复指引,包括 npm 包和手动二进制路径选项。 - - **显式本地提供商**:检查本地模型文件,或可识别的远程/可下载模型 URL。如果缺失,会建议切换到远程提供商。 - - **显式远程提供商**(`openai`、`voyage` 等):验证环境或认证存储中是否存在 API key。如果缺失,会打印可操作的修复提示。 - - **自动提供商**:先检查本地模型可用性,然后按自动选择顺序逐一尝试每个远程提供商。 + - **QMD 后端**:探测 `qmd` 二进制文件是否可用且可启动。如果不可用,会输出修复指导,包括 npm 包和手动二进制路径选项。 + - **显式本地提供商**:检查本地模型文件或可识别的远程/可下载模型 URL。如果缺失,建议切换到远程提供商。 + - **显式远程提供商**(`openai`、`voyage` 等):验证环境或认证存储中是否存在 API key。如果缺失,会输出可操作的修复提示。 + - **自动提供商**:先检查本地模型可用性,然后按自动选择顺序尝试每个远程提供商。 - 当缓存的 Gateway 网关探测结果可用时(检查时 Gateway 网关处于健康状态),Doctor 会将其结果与 CLI 可见配置交叉参照,并指出任何差异。Doctor 不会在默认路径上启动新的嵌入 ping;如果你想进行实时提供商检查,请使用深度记忆 Status 命令。 + 当缓存的 Gateway 网关探测结果可用时(检查时 Gateway 网关处于健康状态),doctor 会将其结果与 CLI 可见配置交叉比对,并指出任何差异。Doctor 不会在默认路径上启动新的嵌入 ping;当你需要实时提供商检查时,请使用深度记忆 Status 命令。 使用 `openclaw memory status --deep` 在运行时验证嵌入就绪状态。 - 如果 Gateway 网关健康,Doctor 会运行渠道 Status 探测,并报告警告及建议的修复方法。 + 如果 Gateway 网关健康,doctor 会运行渠道 Status 探测,并报告警告及建议修复方式。 - - Doctor 会检查已安装的监督器配置(launchd/systemd/schtasks)是否缺少默认值或默认值过旧(例如 systemd network-online 依赖和重启延迟)。发现不匹配时,它会建议更新,并可将服务文件/任务重写为当前默认值。 + + Doctor 会检查已安装的监督程序配置(launchd/systemd/schtasks),查看是否缺少默认值或默认值已过时(例如 systemd network-online 依赖和重启延迟)。发现不匹配时,它会建议更新,并可将服务文件/任务重写为当前默认值。 - 注意: + 说明: - - `openclaw doctor` 会在重写监督器配置前提示。 - - `openclaw doctor --yes` 会接受默认修复提示。 - - `openclaw doctor --repair` 会在不提示的情况下应用建议修复。 - - `openclaw doctor --repair --force` 会覆盖自定义监督器配置。 - - `OPENCLAW_SERVICE_REPAIR_POLICY=external` 会让 Doctor 对 Gateway 网关服务生命周期保持只读。它仍会报告服务健康状态并运行非服务修复,但会跳过服务安装/启动/重启/引导、监督器配置重写和旧版服务清理,因为该生命周期由外部监督器负责。 - - 在 Linux 上,当匹配的 systemd Gateway 网关单元处于活动状态时,Doctor 不会重写命令/入口点元数据。它还会在重复服务扫描期间忽略非活动的非旧版额外 Gateway 网关类单元,因此配套服务文件不会产生清理噪音。 - - 如果令牌认证需要令牌,且 `gateway.auth.token` 由 SecretRef 管理,Doctor 服务安装/修复会验证 SecretRef,但不会将解析后的明文令牌值持久化到监督器服务环境元数据中。 - - Doctor 会检测旧版 LaunchAgent、systemd 或 Windows Scheduled Task 安装以内联方式嵌入的托管 `.env`/SecretRef 支持的服务环境值,并重写服务元数据,使这些值从运行时来源加载,而不是从监督器定义加载。 + - `openclaw doctor` 在重写监督程序配置前会提示。 + - `openclaw doctor --yes` 接受默认修复提示。 + - `openclaw doctor --repair` 应用建议修复且不提示。 + - `openclaw doctor --repair --force` 覆盖自定义监督程序配置。 + - `OPENCLAW_SERVICE_REPAIR_POLICY=external` 让 doctor 对 Gateway 网关服务生命周期保持只读。它仍会报告服务健康状态并运行非服务修复,但会跳过服务安装/启动/重启/引导、监督程序配置重写以及旧版服务清理,因为该生命周期由外部监督程序拥有。 + - 在 Linux 上,当匹配的 systemd Gateway 网关单元处于活动状态时,doctor 不会重写命令/入口点元数据。它还会在重复服务扫描期间忽略非活动的非旧版额外类 Gateway 网关单元,因此配套服务文件不会产生清理噪音。 + - 如果令牌认证需要令牌,并且 `gateway.auth.token` 由 SecretRef 管理,doctor 服务安装/修复会验证 SecretRef,但不会将解析后的明文令牌值持久化到监督程序服务环境元数据中。 + - Doctor 会检测较旧的 LaunchAgent、systemd 或 Windows 计划任务安装以内联方式嵌入的托管 `.env`/SecretRef 支持的服务环境值,并重写服务元数据,使这些值从运行时来源加载,而不是从监督程序定义加载。 - Doctor 会检测服务命令是否在 `gateway.port` 更改后仍固定旧的 `--port`,并将服务元数据重写为当前端口。 - - 如果令牌认证需要令牌,且已配置的令牌 SecretRef 未解析,Doctor 会阻止安装/修复路径,并提供可操作的指引。 - - 如果同时配置了 `gateway.auth.token` 和 `gateway.auth.password`,且 `gateway.auth.mode` 未设置,Doctor 会阻止安装/修复,直到显式设置模式。 - - 对于 Linux 用户 systemd 单元,Doctor 令牌漂移检查现在会在比较服务认证元数据时同时包含 `Environment=` 和 `EnvironmentFile=` 来源。 - - 当配置最后由较新版本写入时,Doctor 服务修复会拒绝用较旧的 OpenClaw 二进制文件重写、停止或重启 Gateway 网关服务。参见 [Gateway 网关故障排除](/zh-CN/gateway/troubleshooting#split-brain-installs-and-newer-config-guard)。 + - 如果令牌认证需要令牌且配置的令牌 SecretRef 未解析,doctor 会阻止安装/修复路径,并给出可操作指导。 + - 如果同时配置了 `gateway.auth.token` 和 `gateway.auth.password`,且未设置 `gateway.auth.mode`,doctor 会阻止安装/修复,直到显式设置模式。 + - 对于 Linux user-systemd 单元,doctor 令牌漂移检查现在会在比较服务认证元数据时同时包含 `Environment=` 和 `EnvironmentFile=` 来源。 + - 当配置最后由较新版本写入时,Doctor 服务修复会拒绝从较旧的 OpenClaw 二进制文件重写、停止或重启 Gateway 网关服务。参见 [Gateway 网关故障排除](/zh-CN/gateway/troubleshooting#split-brain-installs-and-newer-config-guard)。 - 你始终可以通过 `openclaw gateway install --force` 强制完整重写。 - Doctor 会检查服务运行时(PID、上次退出状态),并在服务已安装但实际上未运行时发出警告。它还会检查 Gateway 网关端口(默认 `18789`)上的端口冲突,并报告可能原因(Gateway 网关已在运行、SSH 隧道)。 + Doctor 会检查服务运行时(PID、上次退出状态),并在服务已安装但实际未运行时发出警告。它还会检查 Gateway 网关端口(默认 `18789`)上的端口冲突,并报告可能原因(Gateway 网关已在运行、SSH 隧道)。 - 当 Gateway 网关服务运行在 Bun 或版本管理的 Node 路径(`nvm`、`fnm`、`volta`、`asdf` 等)上时,Doctor 会发出警告。WhatsApp + Telegram 渠道需要 Node,且版本管理器路径可能在升级后失效,因为服务不会加载你的 shell 初始化。Doctor 会在系统 Node 安装可用时(Homebrew/apt/choco)提示迁移到该安装。 + 当 Gateway 网关服务运行在 Bun 或版本管理的 Node 路径(`nvm`、`fnm`、`volta`、`asdf` 等)上时,Doctor 会发出警告。WhatsApp + Telegram 渠道需要 Node,而版本管理器路径可能会在升级后失效,因为服务不会加载你的 shell 初始化。Doctor 会在系统 Node 安装可用时(Homebrew/apt/choco)提示迁移到它。 - 新安装或修复的 macOS LaunchAgent 使用规范的系统 PATH(`/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin`),而不是复制交互式 shell PATH,因此 Volta、asdf、fnm、pnpm 和其他版本管理器目录不会改变 Node 子进程的解析位置。Linux 服务仍会保留显式环境根目录(`NVM_DIR`、`FNM_DIR`、`VOLTA_HOME`、`ASDF_DATA_DIR`、`BUN_INSTALL`、`PNPM_HOME`)和稳定的用户 bin 目录,但推测的版本管理器回退目录只有在这些目录实际存在于磁盘上时才会写入服务 PATH。 + 新安装或修复的 macOS LaunchAgent 会使用规范的系统 PATH(`/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin`),而不是复制交互式 shell PATH,因此 Volta、asdf、fnm、pnpm 和其他版本管理器目录不会改变 Node 子进程的解析方式。Linux 服务仍会保留显式环境根(`NVM_DIR`、`FNM_DIR`、`VOLTA_HOME`、`ASDF_DATA_DIR`、`BUN_INSTALL`、`PNPM_HOME`)和稳定的用户 bin 目录,但推测出的版本管理器后备目录只有在这些目录存在于磁盘上时才会写入服务 PATH。 - Doctor 会持久化任何配置更改,并标记向导元数据以记录 Doctor 运行。 + Doctor 会持久化任何配置更改,并标记向导元数据以记录 doctor 运行。 - 当缺少工作区记忆系统时,Doctor 会建议添加;如果工作区尚未纳入 git,它还会打印备份提示。 + Doctor 会在缺失时建议使用工作区记忆系统,并在工作区尚未纳入 git 管理时输出备份提示。 - 参见 [/concepts/agent-workspace](/zh-CN/concepts/agent-workspace),了解工作区结构和 git 备份的完整指南(推荐使用私有 GitHub 或 GitLab)。 + 有关工作区结构和 git 备份(推荐私有 GitHub 或 GitLab)的完整指南,请参见 [/concepts/agent-workspace](/zh-CN/concepts/agent-workspace)。 diff --git a/docs/zh-CN/plugins/bundles.md b/docs/zh-CN/plugins/bundles.md index b21b91209..e99a5b449 100644 --- a/docs/zh-CN/plugins/bundles.md +++ b/docs/zh-CN/plugins/bundles.md @@ -1,37 +1,30 @@ --- read_when: - - 你想安装与 Codex、Claude 或 Cursor 兼容的套件 - - 你需要了解 OpenClaw 如何将包内容映射到原生功能 - - 你正在调试 bundle 检测或缺失的能力 -summary: 以 OpenClaw 插件形式安装并使用 Codex、Claude 和 Cursor 捆绑包 + - 你想安装一个兼容 Codex、Claude 或 Cursor 的捆绑包 + - 你需要了解 OpenClaw 如何将捆绑包内容映射为原生功能 + - 你正在调试捆绑包检测或缺失的能力 +summary: 安装并使用 Codex、Claude 和 Cursor 捆绑包作为 OpenClaw 插件 title: 插件包 x-i18n: - generated_at: "2026-05-01T20:39:39Z" + generated_at: "2026-05-05T01:21:23Z" model: gpt-5.5 provider: openai - source_hash: 4b949ad70881714a30ab136261441687b439e39b516638ffa052efeab6b75bd4 + source_hash: 5bc06300e765e2faaf51800462003e242d29d4102ac9feaa47f86d4ad35bf157 source_path: plugins/bundles.md workflow: 16 --- -OpenClaw 可以安装来自三个外部生态系统的插件:**Codex**、**Claude** -和 **Cursor**。这些称为 **bundle 包**,也就是内容和元数据包, -OpenClaw 会将其映射为 Skills、钩子和 MCP 工具等原生功能。 +OpenClaw 可以从三个外部生态系统安装插件:**Codex**、**Claude** 和 **Cursor**。这些称为 **bundle**,也就是 OpenClaw 映射到 Skills、钩子和 MCP 工具等原生功能的内容与元数据包。 - bundle 包与原生 OpenClaw 插件**不同**。原生插件在进程内运行, - 可以注册任何能力。bundle 包是内容包,具有选择性的功能映射和 - 更窄的信任边界。 + bundle **不同于**原生 OpenClaw 插件。原生插件在进程内运行,并且可以注册任何能力。bundle 是内容包,具有选择性的功能映射和更窄的信任边界。 -## 为什么存在 bundle 包 +## 为什么存在 bundle -许多有用的插件以 Codex、Claude 或 Cursor 格式发布。OpenClaw -不会要求作者将它们重写为原生 OpenClaw 插件,而是检测这些格式,并将其支持的内容映射到原生功能集。 -这意味着你可以安装 Claude 命令包或 Codex skill bundle, -并立即使用。 +许多有用的插件以 Codex、Claude 或 Cursor 格式发布。OpenClaw 不要求作者将它们重写为原生 OpenClaw 插件,而是检测这些格式,并将其支持的内容映射到原生功能集。这意味着你可以安装一个 Claude 命令包或 Codex Skills bundle 并立即使用。 -## 安装 bundle 包 +## 安装 bundle @@ -55,7 +48,7 @@ OpenClaw 会将其映射为 Skills、钩子和 MCP 工具等原生功能。 openclaw plugins inspect ``` - bundle 包会显示为 `Format: bundle`,并带有 `codex`、`claude` 或 `cursor` 子类型。 + bundle 显示为 `Format: bundle`,并带有 `codex`、`claude` 或 `cursor` 子类型。 @@ -69,57 +62,49 @@ OpenClaw 会将其映射为 Skills、钩子和 MCP 工具等原生功能。 -## OpenClaw 从 bundle 包映射什么 +## OpenClaw 从 bundle 映射什么 -目前并非每个 bundle 包功能都能在 OpenClaw 中运行。下面列出了可用功能,以及 -已检测但尚未接入的功能。 +目前并非每个 bundle 功能都能在 OpenClaw 中运行。以下是已可用的内容,以及已检测但尚未接线的内容。 ### 目前支持 -| 功能 | 映射方式 | 适用范围 | +| 功能 | 映射方式 | 适用于 | | ------------- | ------------------------------------------------------------------------------------------- | -------------- | -| Skill 内容 | bundle 包 skill 根目录会作为普通 OpenClaw Skills 加载 | 所有格式 | -| 命令 | `commands/` 和 `.cursor/commands/` 会作为 skill 根目录处理 | Claude、Cursor | +| Skills 内容 | bundle Skills 根目录作为普通 OpenClaw Skills 加载 | 所有格式 | +| 命令 | `commands/` 和 `.cursor/commands/` 被视为 Skills 根目录 | Claude、Cursor | | 钩子包 | OpenClaw 风格的 `HOOK.md` + `handler.ts` 布局 | Codex | -| MCP 工具 | bundle 包 MCP 配置会合并到嵌入式 Pi 设置中;加载受支持的 stdio 和 HTTP 服务器 | 所有格式 | -| LSP 服务器 | Claude `.lsp.json` 和清单声明的 `lspServers` 会合并到嵌入式 Pi LSP 默认值 | Claude | -| 设置 | Claude `settings.json` 会作为嵌入式 Pi 默认值导入 | Claude | +| MCP 工具 | bundle MCP 配置合并到嵌入式 Pi 设置中;加载受支持的 stdio 和 HTTP 服务器 | 所有格式 | +| LSP 服务器 | Claude `.lsp.json` 和清单声明的 `lspServers` 合并到嵌入式 Pi LSP 默认值中 | Claude | +| 设置 | Claude `settings.json` 作为嵌入式 Pi 默认值导入 | Claude | -#### Skill 内容 +#### Skills 内容 -- bundle 包 skill 根目录会作为普通 OpenClaw skill 根目录加载 -- Claude `commands` 根目录会作为额外的 skill 根目录处理 -- Cursor `.cursor/commands` 根目录会作为额外的 skill 根目录处理 +- bundle Skills 根目录作为普通 OpenClaw Skills 根目录加载 +- Claude `commands` 根目录被视为额外的 Skills 根目录 +- Cursor `.cursor/commands` 根目录被视为额外的 Skills 根目录 -这意味着 Claude markdown 命令文件会通过普通 OpenClaw skill -加载器工作。Cursor 命令 markdown 会通过同一路径工作。 +这意味着 Claude markdown 命令文件会通过普通 OpenClaw Skills 加载器工作。Cursor 命令 markdown 也通过同一路径工作。 #### 钩子包 -- bundle 包钩子根目录**只有**在使用普通 OpenClaw 钩子包 - 布局时才有效。目前这主要是 Codex 兼容场景: +- bundle 钩子根目录**仅在**使用普通 OpenClaw 钩子包布局时可用。今天这主要是 Codex 兼容的情况: - `HOOK.md` - `handler.ts` 或 `handler.js` #### Pi 的 MCP -- 已启用的 bundle 包可以贡献 MCP 服务器配置 -- OpenClaw 会将 bundle 包 MCP 配置合并到有效的嵌入式 Pi 设置中,作为 - `mcpServers` -- OpenClaw 会在嵌入式 Pi 智能体轮次期间通过 - 启动 stdio 服务器或连接到 HTTP 服务器,暴露受支持的 bundle 包 MCP 工具 -- `coding` 和 `messaging` 工具配置文件默认包含 bundle 包 MCP 工具; - 对于某个智能体或 Gateway 网关,可使用 `tools.deny: ["bundle-mcp"]` 选择退出 -- 项目本地 Pi 设置仍会在 bundle 包默认值之后应用,因此工作区 - 设置可以在需要时覆盖 bundle 包 MCP 条目 -- bundle 包 MCP 工具目录会在注册前按确定性方式排序,因此 - 上游 `listTools()` 顺序变化不会反复扰动提示缓存工具块 +- 已启用的 bundle 可以贡献 MCP 服务器配置 +- OpenClaw 会将 bundle MCP 配置作为 `mcpServers` 合并到有效的嵌入式 Pi 设置中 +- OpenClaw 会通过启动 stdio 服务器或连接到 HTTP 服务器,在嵌入式 Pi agent 轮次中暴露受支持的 bundle MCP 工具 +- `coding` 和 `messaging` 工具配置文件默认包含 bundle MCP 工具;使用 `tools.deny: ["bundle-mcp"]` 可为某个 agent 或 Gateway 网关选择退出 +- 项目本地 Pi 设置仍会在 bundle 默认值之后应用,因此工作区设置可以在需要时覆盖 bundle MCP 条目 +- bundle MCP 工具目录在注册前会确定性排序,因此上游 `listTools()` 顺序变化不会导致提示缓存工具块频繁变动 ##### 传输协议 MCP 服务器可以使用 stdio 或 HTTP 传输协议: -**Stdio** 会启动子进程: +**Stdio** 会启动一个子进程: ```json { @@ -154,36 +139,30 @@ MCP 服务器可以使用 stdio 或 HTTP 传输协议: } ``` -- `transport` 可设置为 `"streamable-http"` 或 `"sse"`;省略时,OpenClaw 使用 `sse` -- `type: "http"` 是 CLI 原生的下游形态;请在 OpenClaw 配置中使用 `transport: "streamable-http"`。`openclaw mcp set` 和 `openclaw doctor --fix` 会规范化这个常见别名。 -- 仅允许 `http:` 和 `https:` URL scheme +- `transport` 可以设置为 `"streamable-http"` 或 `"sse"`;省略时,OpenClaw 使用 `sse` +- `type: "http"` 是 CLI 原生的下游形状;在 OpenClaw 配置中使用 `transport: "streamable-http"`。`openclaw mcp set` 和 `openclaw doctor --fix` 会规范化这个常见别名。 +- 仅允许 `http:` 和 `https:` URL 方案 - `headers` 值支持 `${ENV_VAR}` 插值 - 同时包含 `command` 和 `url` 的服务器条目会被拒绝 -- URL 凭据(userinfo 和查询参数)会从工具 - 描述和日志中脱敏 -- `connectionTimeoutMs` 会覆盖 stdio 和 HTTP 传输协议的默认 30 秒连接超时 +- URL 凭证(userinfo 和查询参数)会从工具描述和日志中脱敏 +- `connectionTimeoutMs` 会覆盖 stdio 和 HTTP 传输协议默认的 30 秒连接超时 ##### 工具命名 -OpenClaw 会以 `serverName__toolName` 形式,用提供商安全的名称注册 bundle 包 MCP 工具。 -例如,键为 `"vigil-harbor"` 的服务器暴露 -`memory_search` 工具时,会注册为 `vigil-harbor__memory_search`。 +OpenClaw 会以 `serverName__toolName` 形式,使用对提供商安全的名称注册 bundle MCP 工具。例如,键名为 `"vigil-harbor"` 的服务器暴露一个 `memory_search` 工具时,会注册为 `vigil-harbor__memory_search`。 - `A-Za-z0-9_-` 之外的字符会替换为 `-` -- 服务器前缀限制为最多 30 个字符 -- 完整工具名称限制为最多 64 个字符 -- 空服务器名称会回退为 `mcp` -- 清理后发生冲突的名称会用数字后缀消歧 -- 最终暴露的工具顺序会按安全名称确定性排序,以保持重复 Pi - 轮次的缓存稳定 -- 配置文件过滤会将来自同一个 bundle 包 MCP 服务器的所有工具视为 - `bundle-mcp` 插件所有,因此配置文件 allowlist 和 deny list 可以包含 - 单个暴露工具名称,也可以包含 `bundle-mcp` 插件键 +- 服务器前缀上限为 30 个字符 +- 完整工具名称上限为 64 个字符 +- 空服务器名称回退为 `mcp` +- 发生冲突的清理后名称会用数字后缀消歧 +- 最终暴露的工具顺序会按安全名称确定性排序,使重复的 Pi 轮次保持缓存稳定 +- 配置文件过滤会将同一个 bundle MCP 服务器中的所有工具视为由 `bundle-mcp` 插件拥有,因此配置文件 allowlist 和 deny list 可以包含单个暴露工具名称,也可以包含 `bundle-mcp` 插件键 #### 嵌入式 Pi 设置 -- 启用 bundle 包时,Claude `settings.json` 会作为默认嵌入式 Pi 设置导入 -- OpenClaw 会在应用 shell 覆盖键前对其进行清理 +- 当 bundle 启用时,Claude `settings.json` 会作为默认嵌入式 Pi 设置导入 +- OpenClaw 会在应用 shell 覆盖键之前对其进行清理 清理后的键: @@ -192,56 +171,54 @@ OpenClaw 会以 `serverName__toolName` 形式,用提供商安全的名称注 #### 嵌入式 Pi LSP -- 已启用的 Claude bundle 包可以贡献 LSP 服务器配置 +- 已启用的 Claude bundle 可以贡献 LSP 服务器配置 - OpenClaw 会加载 `.lsp.json` 以及任何清单声明的 `lspServers` 路径 -- bundle 包 LSP 配置会合并到有效的嵌入式 Pi LSP 默认值中 -- 目前只有受支持的 stdio 后端 LSP 服务器可运行;不支持的 - 传输协议仍会显示在 `openclaw plugins inspect ` 中 +- bundle LSP 配置会合并到有效的嵌入式 Pi LSP 默认值中 +- 目前只有受支持的 stdio 后端 LSP 服务器可运行;不支持的传输协议仍会显示在 `openclaw plugins inspect ` 中 ### 已检测但不执行 -这些内容会被识别并显示在诊断信息中,但 OpenClaw 不会运行它们: +这些会被识别并显示在诊断中,但 OpenClaw 不会运行它们: - Claude `agents`、`hooks.json` 自动化、`outputStyles` - Cursor `.cursor/agents`、`.cursor/hooks.json`、`.cursor/rules` -- 能力报告之外的 Codex 内联/应用元数据 +- Codex 中超出能力报告范围的内联/应用元数据 -## bundle 包格式 +## bundle 格式 - + 标记:`.codex-plugin/plugin.json` 可选内容:`skills/`、`hooks/`、`.mcp.json`、`.app.json` - 当 Codex bundle 包使用 skill 根目录和 OpenClaw 风格的 - 钩子包目录(`HOOK.md` + `handler.ts`)时,最适合 OpenClaw。 + 当 Codex bundle 使用 Skills 根目录和 OpenClaw 风格的钩子包目录(`HOOK.md` + `handler.ts`)时,最适合 OpenClaw。 - + 两种检测模式: - **基于清单:** `.claude-plugin/plugin.json` - **无清单:** 默认 Claude 布局(`skills/`、`commands/`、`agents/`、`hooks/`、`.mcp.json`、`.lsp.json`、`settings.json`) - Claude 特定行为: + Claude 专属行为: - - `commands/` 会作为 skill 内容处理 + - `commands/` 被视为 Skills 内容 - `settings.json` 会导入到嵌入式 Pi 设置中(shell 覆盖键会被清理) - `.mcp.json` 会向嵌入式 Pi 暴露受支持的 stdio 工具 - `.lsp.json` 以及清单声明的 `lspServers` 路径会加载到嵌入式 Pi LSP 默认值中 - - `hooks/hooks.json` 会被检测但不会执行 - - 清单中的自定义组件路径是追加式的(它们扩展默认值,而不是替换默认值) + - `hooks/hooks.json` 会被检测但不执行 + - 清单中的自定义组件路径是追加式的(它们会扩展默认值,而不是替换默认值) - + 标记:`.cursor-plugin/plugin.json` 可选内容:`skills/`、`.cursor/commands/`、`.cursor/agents/`、`.cursor/rules/`、`.cursor/hooks.json`、`.mcp.json` - - `.cursor/commands/` 会作为 skill 内容处理 + - `.cursor/commands/` 被视为 Skills 内容 - `.cursor/rules/`、`.cursor/agents/` 和 `.cursor/hooks.json` 仅检测 @@ -249,63 +226,52 @@ OpenClaw 会以 `serverName__toolName` 形式,用提供商安全的名称注 ## 检测优先级 -OpenClaw 会先检查原生插件格式: +OpenClaw 首先检查原生插件格式: -1. `openclaw.plugin.json` 或带有 `openclaw.extensions` 的有效 `package.json`,会作为**原生插件**处理 -2. bundle 包标记(`.codex-plugin/`、`.claude-plugin/` 或默认 Claude/Cursor 布局),会作为 **bundle 包**处理 +1. `openclaw.plugin.json` 或带有 `openclaw.extensions` 的有效 `package.json` —— 视为**原生插件** +2. bundle 标记(`.codex-plugin/`、`.claude-plugin/` 或默认 Claude/Cursor 布局)—— 视为 **bundle** -如果一个目录同时包含两者,OpenClaw 会使用原生路径。这可以防止 -双格式包被部分安装为 bundle 包。 +如果目录同时包含两者,OpenClaw 会使用原生路径。这可以防止双格式包被部分安装为 bundle。 -## 运行时依赖和清理 +## 运行时依赖与清理 -- 第三方兼容 bundle 包不会获得启动时 `npm install` 修复。 - 它们应通过 `openclaw plugins install` 安装,并在已安装的插件目录中携带 - 所需的一切。 -- OpenClaw 自有的内置插件要么以轻量形式随核心一起发布,要么 - 可通过插件安装器下载。Gateway 网关启动永远不会为它们运行 - 包管理器。 -- `openclaw doctor --fix` 会移除旧版暂存依赖目录,并可以 - 安装本地插件索引中缺失的已配置可下载插件。 +- 第三方兼容 bundle 不会获得启动时的 `npm install` 修复。它们应通过 `openclaw plugins install` 安装,并在已安装的插件目录中随附所需的一切。 +- OpenClaw 拥有的内置插件要么以轻量形式随核心发布,要么可通过插件安装器下载。Gateway 网关启动永远不会为它们运行包管理器。 +- `openclaw doctor --fix` 会移除旧版暂存依赖目录,并且可以恢复配置引用但本地插件索引缺失的可下载插件。 ## 安全 -bundle 包的信任边界比原生插件更窄: +bundle 的信任边界比原生插件更窄: -- OpenClaw **不会**在进程内加载任意 bundle 包运行时模块 -- Skills 和钩子包路径必须保持在插件根目录内(经过边界检查) -- 设置文件会以相同的边界检查读取 +- OpenClaw **不会**在进程内加载任意 bundle 运行时模块 +- Skills 和钩子包路径必须保留在插件根目录内(带边界检查) +- 设置文件会用相同的边界检查读取 - 受支持的 stdio MCP 服务器可以作为子进程启动 -这使 bundle 包默认更安全,但你仍应将第三方 -bundle 包视为其暴露功能范围内的受信任内容。 +这使 bundle 默认更安全,但你仍应将第三方 bundle 视为受信任内容来使用它们暴露的功能。 ## 故障排除 - - 运行 `openclaw plugins inspect `。如果某项能力已列出但标记为 - 未接入,那是产品限制,而不是安装损坏。 + + 运行 `openclaw plugins inspect `。如果某项能力已列出但标记为未接线,那是产品限制,而不是安装损坏。 - 确保 bundle 包已启用,并且 markdown 文件位于检测到的 - `commands/` 或 `skills/` 根目录中。 + 确保 bundle 已启用,并且 markdown 文件位于检测到的 `commands/` 或 `skills/` 根目录内。 - - 仅支持来自 `settings.json` 的嵌入式 Pi 设置。OpenClaw - 不会将 bundle 包设置视为原始配置补丁。 + + 仅支持来自 `settings.json` 的嵌入式 Pi 设置。OpenClaw 不会将 bundle 设置视为原始配置补丁。 - - `hooks/hooks.json` 仅检测。如果需要可运行的钩子,请使用 - OpenClaw 钩子包布局,或发布原生插件。 + + `hooks/hooks.json` 仅用于检测。如果需要可运行的钩子,请使用 OpenClaw 钩子包布局,或发布原生插件。 -## 相关内容 +## 相关 - [安装和配置插件](/zh-CN/tools/plugin) -- [构建插件](/zh-CN/plugins/building-plugins) — 创建原生插件 -- [插件清单](/zh-CN/plugins/manifest) — 原生清单 schema +- [构建插件](/zh-CN/plugins/building-plugins) —— 创建原生插件 +- [插件清单](/zh-CN/plugins/manifest) —— 原生清单 schema diff --git a/docs/zh-CN/plugins/dependency-resolution.md b/docs/zh-CN/plugins/dependency-resolution.md index 22ac182ef..c776e8f6f 100644 --- a/docs/zh-CN/plugins/dependency-resolution.md +++ b/docs/zh-CN/plugins/dependency-resolution.md @@ -2,60 +2,60 @@ read_when: - 你正在调试插件包安装 - 你正在更改插件启动、Doctor 或包管理器安装行为 - - 你正在维护打包的 OpenClaw 安装或内置插件清单 + - 你正在维护打包版 OpenClaw 安装或内置插件清单 sidebarTitle: Dependencies summary: OpenClaw 如何安装插件包并解析插件依赖项 title: 插件依赖解析 x-i18n: - generated_at: "2026-05-03T20:54:29Z" + generated_at: "2026-05-05T01:21:20Z" model: gpt-5.5 provider: openai - source_hash: 46af62ff866d50cb53bb2761d9928f0fd2a25bdb945040885ec6bfb85be35c6d + source_hash: 1a832f705e51bba8ac77e2a8715a7213fd2caf10bfa42059d53db4a6d5ad8c20 source_path: plugins/dependency-resolution.md workflow: 16 --- -# 插件依赖解析 +# 插件依赖项解析 -OpenClaw 将插件依赖处理保留在安装/更新时间。运行时加载 -不会运行包管理器、修复依赖树,或改变 OpenClaw +OpenClaw 将插件依赖项工作保留在安装/更新时间。运行时加载 +不会运行包管理器、修复依赖项树,或更改 OpenClaw 包目录。 ## 责任划分 -插件包拥有自己的依赖图: +插件包负责自己的依赖图: -- 运行时依赖位于插件包的 `dependencies` 或 +- 运行时依赖项位于插件包的 `dependencies` 或 `optionalDependencies` -- SDK/核心导入是 peer 依赖或由 OpenClaw 提供的导入 -- 本地开发插件自带已经安装好的依赖 -- npm 和 git 插件会安装到 OpenClaw 拥有的包根目录 +- SDK/核心导入是 peer 或由 OpenClaw 提供的导入 +- 本地开发插件自带已安装的依赖项 +- npm 和 git 插件会安装到 OpenClaw 拥有的包根目录中 -OpenClaw 只拥有插件生命周期: +OpenClaw 只负责插件生命周期: - 发现插件来源 - 在明确请求时安装或更新包 - 记录安装元数据 - 加载插件入口点 -- 缺少依赖时以可操作的错误失败 +- 依赖项缺失时,以可操作的错误失败 ## 安装根目录 -OpenClaw 使用按来源划分的稳定根目录: +OpenClaw 使用稳定的按来源划分的根目录: - npm 包安装在 `~/.openclaw/npm` 下 - git 包克隆到 `~/.openclaw/git` 下 -- 本地/路径/归档安装会被复制或引用,不进行依赖修复 +- 本地/路径/归档安装会被复制或引用,不进行依赖项修复 -npm 安装会在 npm 根目录中运行: +npm 安装在 npm 根目录中运行: ```bash npm install --prefix ~/.openclaw/npm --omit=dev --ignore-scripts --no-audit --no-fund ``` -npm 可能会把传递依赖提升到插件包旁边的 `~/.openclaw/npm/node_modules`。 -OpenClaw 会先扫描托管的 npm 根目录,再信任该安装,并在卸载期间使用 npm -移除由 npm 托管的包,因此被提升的运行时依赖仍留在托管清理边界内。 +npm 可能会将传递依赖项提升到插件包旁边的 `~/.openclaw/npm/node_modules`。 +OpenClaw 会在信任安装前扫描受管 npm 根目录,并在卸载期间使用 npm +移除 npm 管理的包,因此提升后的运行时依赖项仍留在受管清理边界内。 git 安装会克隆或刷新仓库,然后运行: @@ -63,25 +63,24 @@ git 安装会克隆或刷新仓库,然后运行: npm install --omit=dev --ignore-scripts --no-audit --no-fund ``` -已安装的插件随后会从该包目录加载,因此包本地和父级 `node_modules` +安装后的插件会从该包目录加载,因此包本地和父级 `node_modules` 解析的工作方式与普通 Node 包相同。 ## 本地插件 -本地插件被视为开发者控制的目录。OpenClaw 不会为它们运行 -`npm install`、`pnpm install` 或依赖修复。如果本地 -插件有依赖,请在加载它之前先在该插件中安装这些依赖。 +本地插件会被视为开发者控制的目录。OpenClaw 不会为它们运行 +`npm install`、`pnpm install` 或依赖项修复。如果本地插件有依赖项, +请在加载它之前在该插件中安装这些依赖项。 -第三方 TypeScript 本地插件可以使用应急 Jiti 路径。已打包的 -JavaScript 插件和内置内部插件会通过原生 import/require 加载, -而不是通过 Jiti。 +第三方 TypeScript 本地插件可以使用紧急 Jiti 路径。打包的 JavaScript +插件和内置内部插件会通过原生 import/require 加载,而不是通过 Jiti。 -## 启动和重载 +## 启动和重新加载 -Gateway 网关启动和配置重载绝不会安装插件依赖。它们会读取 -插件安装记录,计算入口点,并加载它。 +Gateway 网关启动和配置重新加载绝不会安装插件依赖项。它们会读取 +插件安装记录,计算入口点,然后加载它。 -如果运行时缺少某个依赖,插件会加载失败,错误应指向明确的修复方式: +如果运行时缺少某个依赖项,插件加载会失败,并且错误应指引操作员执行明确的修复: ```bash openclaw plugins update @@ -89,40 +88,41 @@ openclaw plugins install openclaw doctor --fix ``` -`doctor --fix` 可以清理旧版 OpenClaw 生成的依赖状态,并安装 -已配置但本地安装记录中缺失的可下载插件。它不会为已安装的本地插件修复依赖。 +`doctor --fix` 可以清理旧版 OpenClaw 生成的依赖项状态,并恢复在配置 +引用它们时本地安装记录中缺失的可下载插件。Doctor 不会为已经安装的 +本地插件修复依赖项。 ## 内置插件 -轻量级和核心关键的内置插件会作为 OpenClaw 的一部分发布。 -它们应该没有庞大的运行时依赖树,或被移出为 ClawHub/npm 上的 +轻量级且对核心关键的内置插件会作为 OpenClaw 的一部分发布。 +它们应当没有沉重的运行时依赖项树,或者被移出为 ClawHub/npm 上的 可下载包。 -若要查看当前随核心包发布、外部安装或仅保留源码的插件生成列表,请参阅 +有关当前随核心包发布、外部安装或仅保留源码的插件生成列表,请参阅 [插件清单](/zh-CN/plugins/plugin-inventory)。 -内置插件清单不得请求依赖暂存。大型或可选的插件功能应作为普通插件打包, +内置插件清单不得请求依赖项暂存。大型或可选插件功能应作为普通插件打包, 并通过与第三方插件相同的 npm/git/ClawHub 路径安装。 -在源码检出中,OpenClaw 将该仓库视为 pnpm monorepo。在 -`pnpm install` 之后,内置插件会从 `extensions/` 加载, -因此包本地工作区依赖可用,编辑也会被直接拾取。源码检出开发仅支持 pnpm; -在仓库根目录运行普通的 `npm install` 不是准备内置插件依赖的受支持方式。 +在源码检出中,OpenClaw 会将仓库视为 pnpm monorepo。执行 +`pnpm install` 后,内置插件会从 `extensions/` 加载,因此包本地 +workspace 依赖项可用,编辑也会被直接拾取。源码检出开发仅支持 pnpm; +在仓库根目录执行普通 `npm install` 不是准备内置插件依赖项的受支持方式。 -| 安装形态 | 内置插件位置 | 依赖所有者 | +| 安装形态 | 内置插件位置 | 依赖项所有者 | | -------------------------------- | ------------------------------------- | -------------------------------------------------------------------- | -| `npm install -g openclaw` | 包内部的已构建运行时树 | OpenClaw 包和显式插件安装/更新/Doctor 流程 | -| Git 检出加 `pnpm install` | `extensions/` 工作区包 | pnpm 工作区,包括每个插件包自己的依赖 | -| `openclaw plugins install ...` | 托管的 npm/git/ClawHub 插件根目录 | 插件安装/更新流程 | +| `npm install -g openclaw` | 包内部构建出的运行时树 | OpenClaw 包以及显式的插件安装/更新/Doctor 流程 | +| Git 检出加 `pnpm install` | `extensions/` workspace 包 | pnpm workspace,包括每个插件包自己的依赖项 | +| `openclaw plugins install ...` | 受管 npm/git/ClawHub 插件根目录 | 插件安装/更新流程 | ## 旧版清理 -较旧的 OpenClaw 版本会在启动时或 Doctor 修复期间生成内置插件依赖根目录。 -当前的 Doctor 清理会在使用 `--fix` 时移除这些陈旧目录和符号链接, -包括旧的 `plugin-runtime-deps` 根目录、指向已剪除 `plugin-runtime-deps` -目标的全局 Node-prefix 包符号链接、`.openclaw-runtime-deps*` 清单、 -生成的插件 `node_modules`、安装暂存目录,以及包本地 pnpm stores。 -已打包的 postinstall 也会在剪除旧版目标根目录之前移除这些全局符号链接, -因此升级不会留下悬空的 ESM 包导入。 +较早的 OpenClaw 版本会在启动时或 Doctor 修复期间生成内置插件依赖项根目录。 +当前的 Doctor 清理会在使用 `--fix` 时移除这些陈旧目录和符号链接,包括旧的 +`plugin-runtime-deps` 根目录、指向已清理 `plugin-runtime-deps` 目标的全局 +Node-prefix 包符号链接、`.openclaw-runtime-deps*` 清单、生成的插件 +`node_modules`、安装暂存目录以及包本地 pnpm 存储。打包后的 postinstall +也会在清理旧版目标根目录之前移除这些全局符号链接,这样升级不会留下悬空的 +ESM 包导入。 -这些路径只是旧版残留。新的安装不应创建它们。 +这些路径只是旧版残留。新安装不应创建它们。 diff --git a/docs/zh-CN/tools/loop-detection.md b/docs/zh-CN/tools/loop-detection.md index dbbc7975a..625c03784 100644 --- a/docs/zh-CN/tools/loop-detection.md +++ b/docs/zh-CN/tools/loop-detection.md @@ -1,25 +1,25 @@ --- read_when: - - 有用户报告智能体卡住并重复工具调用 - - 你需要调优重复调用保护 + - 有用户报告智能体卡住并重复执行工具调用 + - 你需要调整重复调用保护 - 你正在编辑智能体工具/运行时策略 -summary: 如何启用并调优用于检测重复性工具调用循环的防护机制 +summary: 如何启用并调优用于检测重复工具调用循环的防护机制 title: 工具循环检测 x-i18n: - generated_at: "2026-05-03T17:32:58Z" + generated_at: "2026-05-05T01:21:22Z" model: gpt-5.5 provider: openai - source_hash: 1b3976948d5735cf08b7ce854bab048a77a778a07a9f3f66d17c15aed0d42a97 + source_hash: b9221e1716d3f4c2814a4705b160253839510cd6d11fe4ccd598c67958851afb source_path: tools/loop-detection.md workflow: 16 --- OpenClaw 可以防止智能体陷入重复的工具调用模式。 -该防护**默认禁用**。 +该防护默认 **禁用**。 仅在需要的地方启用它,因为在严格设置下,它可能会阻止合法的重复调用。 -## 存在原因 +## 为什么存在此功能 - 检测没有取得进展的重复序列。 - 检测高频无结果循环(相同工具、相同输入、重复错误)。 @@ -48,7 +48,7 @@ OpenClaw 可以防止智能体陷入重复的工具调用模式。 } ``` -单智能体覆盖(可选): +按智能体覆盖(可选): ```json5 { @@ -72,42 +72,65 @@ OpenClaw 可以防止智能体陷入重复的工具调用模式。 ### 字段行为 - `enabled`:总开关。`false` 表示不执行循环检测。 -- `historySize`:保留用于分析的最近工具调用数量。 -- `warningThreshold`:将模式分类为仅警告之前的阈值。 -- `criticalThreshold`:阻止重复循环模式的阈值。 +- `historySize`:为分析保留的最近工具调用数量。 +- `warningThreshold`:在将某个模式归类为仅警告之前使用的阈值。 +- `criticalThreshold`:用于阻止重复循环模式的阈值。 - `globalCircuitBreakerThreshold`:全局无进展断路器阈值。 -- `detectors.genericRepeat`:检测重复的相同工具 + 相同参数模式。 +- `detectors.genericRepeat`:检测相同工具 + 相同参数的重复模式。 - `detectors.knownPollNoProgress`:检测没有状态变化的已知类轮询模式。 - `detectors.pingPong`:检测交替的乒乓模式。 对于 `exec`,无进展检查会比较稳定的命令结果,并忽略易变的运行时元数据,例如持续时间、PID、会话 ID 和工作目录。 -当 run id 可用时,最近的工具调用历史只会在该 run 内评估,因此定时 Heartbeat 周期和新的 run 不会继承早前 run 的陈旧循环计数。 +当 run id 可用时,最近的工具调用历史只会在该运行内评估,因此定时 Heartbeat 周期和新的运行不会继承较早运行中的陈旧循环计数。 ## 推荐设置 -- 对于较小的模型,从 `enabled: true` 开始,保持默认值不变。旗舰模型很少需要循环检测,可以保持禁用。 +- 对于较小的模型,从 `enabled: true` 开始,并保持默认值不变。旗舰模型很少需要循环检测,可以保持禁用。 - 保持阈值顺序为 `warningThreshold < criticalThreshold < globalCircuitBreakerThreshold`。 - 如果出现误报: - 提高 `warningThreshold` 和/或 `criticalThreshold` - (可选)提高 `globalCircuitBreakerThreshold` - - 只禁用导致问题的检测器 + - 仅禁用导致问题的检测器 - 减小 `historySize`,以降低历史上下文的严格程度 +## 压缩后防护 + +当 runner 完成自动压缩重试(在上下文溢出之后)时,它会启用一个短窗口防护,用于观察接下来的几次工具调用。如果智能体在该窗口内多次发出 _相同的_ `(toolName, args, result)` 三元组,该防护会判定压缩未能打破循环,并以 `compaction_loop_persisted` 错误中止运行。 + +这是独立于全局 `tools.loopDetection` 检测器的代码路径。它可单独配置: + +```json5 +{ + tools: { + loopDetection: { + enabled: true, // existing master switch; set false to disable loop guards + postCompactionGuard: { + windowSize: 3, // default: 3 + }, + }, + }, +} +``` + +- `windowSize`:压缩后防护保持启用期间的工具调用数量,_并且_ 也是触发中止的相同(工具、参数、结果)三元组数量。 + +当结果发生变化时,该防护绝不会中止运行;只有当整个窗口内的结果按字节完全相同时才会中止。它有意保持范围很窄:只会在压缩重试后的立即阶段触发。 + ## 日志和预期行为 -检测到循环时,OpenClaw 会报告循环事件,并根据严重程度阻止或缓和下一个工具周期。 -这可以保护用户免受失控 token 消耗和卡死影响,同时保留正常的工具访问能力。 +当检测到循环时,OpenClaw 会报告循环事件,并根据严重程度阻止或削弱下一个工具周期。 +这可以保护用户免受失控的 token 消耗和卡死影响,同时保留正常的工具访问能力。 -- 优先采用警告和临时抑制。 -- 仅在重复证据累积时升级。 +- 优先使用警告和临时抑制。 +- 仅在重复证据积累后升级处理。 -## 备注 +## 注意事项 - `tools.loopDetection` 会与智能体级覆盖合并。 -- 单智能体配置会完全覆盖或扩展全局值。 -- 如果不存在配置,防护会保持关闭。 +- 按智能体配置会完全覆盖或扩展全局值。 +- 如果没有配置,防护机制保持关闭。 -## 相关 +## 相关内容 - [Exec 审批](/zh-CN/tools/exec-approvals) - [思考级别](/zh-CN/tools/thinking)