diff --git a/docs/zh-CN/channels/whatsapp.md b/docs/zh-CN/channels/whatsapp.md index 9e2607ea4..e7d78f9df 100644 --- a/docs/zh-CN/channels/whatsapp.md +++ b/docs/zh-CN/channels/whatsapp.md @@ -1,29 +1,28 @@ --- read_when: - 处理 WhatsApp/web 渠道行为或收件箱路由 -summary: WhatsApp 渠道支持、访问控制、投递行为和运维 +summary: WhatsApp 渠道支持、访问控制、消息投递行为和运维 title: WhatsApp x-i18n: - generated_at: "2026-04-24T16:49:41Z" + generated_at: "2026-04-24T20:10:22Z" model: gpt-5.4 provider: openai - source_hash: badc448123ff9a12633255db5756236c3ccbd7a75b4ddc3f76d6454d0555011c + source_hash: a74c21cbc178c2e629f6d1273e37e9f8b503d9fedc51bada530c765a1fca0b11 source_path: channels/whatsapp.md workflow: 15 --- -状态:通过 WhatsApp Web(Baileys)已达到生产就绪。Gateway 网关拥有已关联的会话。 +状态:通过 WhatsApp Web(Baileys)达到生产就绪。Gateway 网关负责已关联的会话。 ## 安装(按需) - 新手引导(`openclaw onboard`)和 `openclaw channels add --channel whatsapp` - 会在你首次选择 WhatsApp 插件时提示安装。 -- `openclaw channels login --channel whatsapp` 也会在 - 插件尚未安装时提供安装流程。 + 会在你首次选择该渠道时,提示安装 WhatsApp 插件。 +- 当插件尚未安装时,`openclaw channels login --channel whatsapp` 也会提供安装流程。 - 开发渠道 + git 检出:默认使用本地插件路径。 -- Stable/Beta:默认使用 npm 包 `@openclaw/whatsapp`。 +- 稳定版/Beta:默认使用 npm 包 `@openclaw/whatsapp`。 -也可以继续手动安装: +仍然可以手动安装: ```bash openclaw plugins install @openclaw/whatsapp @@ -31,7 +30,7 @@ openclaw plugins install @openclaw/whatsapp - 对未知发送者的默认私信策略是配对。 + 未知发送者的默认私信策略是配对。 跨渠道诊断和修复操作手册。 @@ -67,13 +66,13 @@ openclaw plugins install @openclaw/whatsapp openclaw channels login --channel whatsapp ``` - 对于特定账户: + 对于特定账号: ```bash openclaw channels login --channel whatsapp --account work ``` - 要在登录前附加现有/自定义的 WhatsApp Web 认证目录: + 若要在登录前附加现有/自定义的 WhatsApp Web 凭证目录: ```bash openclaw channels add --channel whatsapp --account work --auth-dir /path/to/wa-auth @@ -103,17 +102,17 @@ openclaw pairing approve whatsapp -OpenClaw 建议在可能的情况下为 WhatsApp 使用单独的号码。(渠道元数据和设置流程已针对这种设置进行优化,但也支持使用个人号码的设置。) +OpenClaw 建议尽可能为 WhatsApp 使用单独的号码。(渠道元数据和设置流程已针对这种设置进行优化,但也支持个人号码设置。) ## 部署模式 - 这是最简洁的运维模式: + 这是最清晰的运维模式: - - 为 OpenClaw 使用独立的 WhatsApp 身份 - - 更清晰的私信允许列表和路由边界 + - 为 OpenClaw 使用单独的 WhatsApp 身份 + - 更清晰的私信允许名单和路由边界 - 更低的自聊混淆概率 最小策略模式: @@ -132,18 +131,18 @@ OpenClaw 建议在可能的情况下为 WhatsApp 使用单独的号码。(渠 - 新手引导支持个人号码模式,并会写入适合自聊的基线配置: + 新手引导支持个人号码模式,并会写入一个适合自聊的基线配置: - `dmPolicy: "allowlist"` - `allowFrom` 包含你的个人号码 - `selfChatMode: true` - 在运行时,自聊保护会基于已关联的自身号码和 `allowFrom` 生效。 + 在运行时,自聊保护会依据已关联的自身号码和 `allowFrom` 生效。 - 在当前 OpenClaw 渠道架构中,消息平台渠道基于 WhatsApp Web(`Baileys`)。 + 在当前的 OpenClaw 渠道架构中,消息平台渠道基于 WhatsApp Web(`Baileys`)。 内置聊天渠道注册表中没有单独的 Twilio WhatsApp 消息渠道。 @@ -152,54 +151,92 @@ OpenClaw 建议在可能的情况下为 WhatsApp 使用单独的号码。(渠 ## 运行时模型 -- Gateway 网关拥有 WhatsApp socket 和重连循环。 -- 出站发送要求目标账户存在活跃的 WhatsApp 监听器。 +- Gateway 网关负责 WhatsApp socket 和重连循环。 +- 出站发送要求目标账号存在活动中的 WhatsApp 监听器。 - 状态和广播聊天会被忽略(`@status`、`@broadcast`)。 -- 私聊使用私信会话规则(`session.dmScope`;默认 `main` 会将私信折叠到智能体主会话)。 +- 直接聊天使用私信会话规则(`session.dmScope`;默认 `main` 会将私信折叠到智能体主会话)。 - 群组会话彼此隔离(`agent::whatsapp:group:`)。 - WhatsApp Web 传输遵循 Gateway 网关主机上的标准代理环境变量(`HTTPS_PROXY`、`HTTP_PROXY`、`NO_PROXY` 及其小写变体)。优先使用主机级代理配置,而不是渠道专用的 WhatsApp 代理设置。 -## 访问控制和激活 +## 插件钩子与隐私 + +WhatsApp 入站消息可能包含个人消息内容、电话号码、 +群组标识符、发送者名称以及会话关联字段。因此, +除非你显式选择启用,否则 WhatsApp 不会将入站 `message_received` 钩子负载广播给插件: + +```json5 +{ + channels: { + whatsapp: { + pluginHooks: { + messageReceived: true, + }, + }, + }, +} +``` + +你可以将此选择启用范围限定到某个账号: + +```json5 +{ + channels: { + whatsapp: { + accounts: { + work: { + pluginHooks: { + messageReceived: true, + }, + }, + }, + }, + }, +} +``` + +仅在你信任插件可以接收入站 WhatsApp 消息内容和标识符时,才启用此功能。 + +## 访问控制与激活 - `channels.whatsapp.dmPolicy` 控制私聊访问: + `channels.whatsapp.dmPolicy` 控制直接聊天访问: - `pairing`(默认) - `allowlist` - `open`(要求 `allowFrom` 包含 `"*"`) - `disabled` - `allowFrom` 接受 E.164 风格号码(内部会标准化)。 + `allowFrom` 接受 E.164 风格的号码(内部会进行标准化)。 - 多账户覆盖:对于该账户,`channels.whatsapp.accounts..dmPolicy`(以及 `allowFrom`)优先于渠道级默认值。 + 多账号覆盖:对于该账号,`channels.whatsapp.accounts..dmPolicy`(以及 `allowFrom`)优先于渠道级默认值。 运行时行为细节: - - 配对信息会持久化到渠道 allow-store 中,并与已配置的 `allowFrom` 合并 - - 如果未配置允许列表,则默认允许已关联的自身号码 + - 配对会持久化到渠道允许存储中,并与配置的 `allowFrom` 合并 + - 如果未配置允许名单,则默认允许已关联的自身号码 - OpenClaw 永远不会自动配对出站 `fromMe` 私信(即你从已关联设备发给自己的消息) - - 群组访问有两层控制: + + 群组访问有两层: - 1. **群组成员资格允许列表**(`channels.whatsapp.groups`) + 1. **群组成员允许名单**(`channels.whatsapp.groups`) - 如果省略 `groups`,则所有群组都有资格 - - 如果存在 `groups`,它将作为群组允许列表(允许 `"*"`) + - 如果存在 `groups`,它就充当群组允许名单(允许使用 `"*"`) 2. **群组发送者策略**(`channels.whatsapp.groupPolicy` + `groupAllowFrom`) - - `open`:绕过发送者允许列表 + - `open`:绕过发送者允许名单 - `allowlist`:发送者必须匹配 `groupAllowFrom`(或 `*`) - `disabled`:阻止所有群组入站消息 - 发送者允许列表回退规则: + 发送者允许名单回退: - 如果未设置 `groupAllowFrom`,运行时会在可用时回退到 `allowFrom` - - 发送者允许列表会在提及/回复激活之前进行评估 + - 在提及/回复激活之前,会先评估发送者允许名单 - 注意:如果完全不存在 `channels.whatsapp` 配置块,运行时的群组策略回退值是 `allowlist`(并会记录警告日志),即使已设置 `channels.defaults.groupPolicy` 也是如此。 + 注意:如果完全不存在 `channels.whatsapp` 配置块,运行时的群组策略回退值是 `allowlist`(并记录一条警告日志),即使已设置 `channels.defaults.groupPolicy` 也是如此。 @@ -210,19 +247,19 @@ OpenClaw 建议在可能的情况下为 WhatsApp 使用单独的号码。(渠 - 对机器人身份的显式 WhatsApp 提及 - 已配置的提及正则模式(`agents.list[].groupChat.mentionPatterns`,回退到 `messages.groupChat.mentionPatterns`) - - 隐式回复机器人检测(回复发送者与机器人身份匹配) + - 隐式回复给机器人检测(回复发送者与机器人身份匹配) 安全说明: - 引用/回复只会满足提及门控;它**不会**授予发送者授权 - - 当使用 `groupPolicy: "allowlist"` 时,即使非允许列表中的发送者回复了允许列表用户的消息,仍然会被阻止 + - 在 `groupPolicy: "allowlist"` 下,即使非允许名单发送者回复了允许名单用户的消息,仍会被阻止 会话级激活命令: - `/activation mention` - `/activation always` - `activation` 会更新会话状态(而不是全局配置)。它受 owner 权限控制。 + `activation` 会更新会话状态(而不是全局配置)。它受所有者权限控制。 @@ -232,16 +269,16 @@ OpenClaw 建议在可能的情况下为 WhatsApp 使用单独的号码。(渠 当已关联的自身号码也存在于 `allowFrom` 中时,WhatsApp 自聊保护会启用: - 跳过自聊轮次的已读回执 -- 忽略原本会触发提醒你自己的 mention-JID 自动触发行为 +- 忽略原本会提醒你自己的 mention-JID 自动触发行为 - 如果未设置 `messages.responsePrefix`,自聊回复默认使用 `[{identity.name}]` 或 `[openclaw]` -## 消息标准化和上下文 +## 消息标准化与上下文 - - 传入的 WhatsApp 消息会被包装到共享的入站信封中。 + + 传入的 WhatsApp 消息会被包装到共享的入站封装中。 - 如果存在引用回复,上下文会按以下形式追加: + 如果存在引用回复,上下文会按以下形式附加: ```text [Replying to id:] @@ -249,12 +286,12 @@ OpenClaw 建议在可能的情况下为 WhatsApp 使用单独的号码。(渠 [/Replying] ``` - 如果可用,也会填充回复元数据字段(`ReplyToId`、`ReplyToBody`、`ReplyToSender`、发送者 JID/E.164)。 + 可用时也会填充回复元数据字段(`ReplyToId`、`ReplyToBody`、`ReplyToSender`、发送者 JID/E.164)。 - - 仅含媒体的入站消息会用如下占位符标准化: + + 仅媒体的入站消息会使用如下占位符进行标准化: - `` - `` @@ -262,7 +299,7 @@ OpenClaw 建议在可能的情况下为 WhatsApp 使用单独的号码。(渠 - `` - `` - 位置消息正文使用简洁的坐标文本。位置标签/评论以及联系人/vCard 详情会渲染为带围栏的不受信任元数据,而不是内联提示文本。 + 位置消息正文使用简洁的坐标文本。位置标签/备注以及联系人/vCard 详细信息会渲染为带围栏的不受信任元数据,而不是内联提示文本。 @@ -296,7 +333,7 @@ OpenClaw 建议在可能的情况下为 WhatsApp 使用单独的号码。(渠 } ``` - 按账户覆盖: + 按账号覆盖: ```json5 { @@ -317,19 +354,19 @@ OpenClaw 建议在可能的情况下为 WhatsApp 使用单独的号码。(渠 -## 投递、分块和媒体 +## 消息投递、分块和媒体 - 默认分块限制:`channels.whatsapp.textChunkLimit = 4000` - `channels.whatsapp.chunkMode = "length" | "newline"` - - `newline` 模式优先按段落边界(空行)分块,然后回退到按长度安全分块 + - `newline` 模式优先按段落边界(空行)拆分,然后回退到按长度安全分块 - 支持图片、视频、音频(PTT 语音便笺)和文档负载 - - `audio/ogg` 会被改写为 `audio/ogg; codecs=opus`,以兼容语音便笺 - - 视频发送时通过 `gifPlayback: true` 支持动画 GIF 播放 + - 为了兼容语音便笺,`audio/ogg` 会被重写为 `audio/ogg; codecs=opus` + - 通过在视频发送时设置 `gifPlayback: true`,支持动画 GIF 播放 - 发送多媒体回复负载时,说明文字会应用到第一个媒体项 - 媒体来源可以是 HTTP(S)、`file://` 或本地路径 @@ -337,15 +374,15 @@ OpenClaw 建议在可能的情况下为 WhatsApp 使用单独的号码。(渠 - 入站媒体保存上限:`channels.whatsapp.mediaMaxMb`(默认 `50`) - 出站媒体发送上限:`channels.whatsapp.mediaMaxMb`(默认 `50`) - - 按账户覆盖使用 `channels.whatsapp.accounts..mediaMaxMb` - - 图片会自动优化(调整尺寸/质量扫描)以符合限制 - - 当媒体发送失败时,首项回退会发送文本警告,而不是悄无声息地丢弃响应 + - 按账号覆盖使用 `channels.whatsapp.accounts..mediaMaxMb` + - 图片会自动优化(调整大小/质量扫描)以满足限制 + - 发送媒体失败时,首项回退会发送文本警告,而不是静默丢弃响应 ## 回复引用 -WhatsApp 支持原生回复引用,即出站回复会以可见方式引用入站消息。使用 `channels.whatsapp.replyToMode` 控制此行为。 +WhatsApp 支持原生回复引用,即出站回复会以可见方式引用入站消息。使用 `channels.whatsapp.replyToMode` 控制它。 | 值 | 行为 | | -------- | ---------------------------------------------------------------------------------- | @@ -353,7 +390,7 @@ WhatsApp 支持原生回复引用,即出站回复会以可见方式引用入 | `"on"` | 始终引用入站消息;如果引用被拒绝,则回退为普通发送 | | `"off"` | 从不引用;作为普通消息发送 | -默认值为 `"auto"`。按账户覆盖使用 `channels.whatsapp.accounts..replyToMode`。 +默认值是 `"auto"`。按账号覆盖使用 `channels.whatsapp.accounts..replyToMode`。 ```json5 { @@ -365,20 +402,20 @@ WhatsApp 支持原生回复引用,即出站回复会以可见方式引用入 } ``` -## Reaction 级别 +## 反应级别 -`channels.whatsapp.reactionLevel` 控制智能体在 WhatsApp 上使用 emoji reaction 的广泛程度: +`channels.whatsapp.reactionLevel` 控制智能体在 WhatsApp 上使用 emoji 反应的范围: -| 级别 | 确认 reaction | 智能体主动 reaction | 说明 | -| ------------- | ------------- | ------------------- | ------------------------------------------------ | -| `"off"` | 否 | 否 | 完全不使用 reaction | -| `"ack"` | 是 | 否 | 仅确认 reaction(回复前回执) | -| `"minimal"` | 是 | 是(保守) | 确认 + 在保守指引下使用智能体 reaction | -| `"extensive"` | 是 | 是(鼓励) | 确认 + 在鼓励性指引下使用智能体 reaction | +| 级别 | 确认反应 | 智能体主动反应 | 说明 | +| ------------- | -------- | ----------------------- | --------------------------------- | +| `"off"` | 否 | 否 | 完全不使用反应 | +| `"ack"` | 是 | 否 | 仅使用确认反应(回复前接收确认) | +| `"minimal"` | 是 | 是(保守) | 确认反应 + 智能体反应,策略较保守 | +| `"extensive"` | 是 | 是(鼓励) | 确认反应 + 智能体反应,策略更积极 | 默认值:`"minimal"`。 -按账户覆盖使用 `channels.whatsapp.accounts..reactionLevel`。 +按账号覆盖使用 `channels.whatsapp.accounts..reactionLevel`。 ```json5 { @@ -390,10 +427,10 @@ WhatsApp 支持原生回复引用,即出站回复会以可见方式引用入 } ``` -## 确认 reaction +## 确认反应 -WhatsApp 支持通过 `channels.whatsapp.ackReaction` 在接收入站消息时立即发送确认 reaction。 -确认 reaction 受 `reactionLevel` 控制 —— 当 `reactionLevel` 为 `"off"` 时,它们会被抑制。 +WhatsApp 支持通过 `channels.whatsapp.ackReaction` 在接收入站消息时立即发送确认反应。 +确认反应受 `reactionLevel` 控制——当 `reactionLevel` 为 `"off"` 时会被抑制。 ```json5 { @@ -412,36 +449,36 @@ WhatsApp 支持通过 `channels.whatsapp.ackReaction` 在接收入站消息时 行为说明: - 在入站消息被接受后立即发送(回复前) -- 失败会被记录日志,但不会阻止正常回复投递 -- 群组模式 `mentions` 会在因提及触发的轮次发送 reaction;群组激活模式 `always` 可绕过此检查 -- WhatsApp 使用 `channels.whatsapp.ackReaction`(这里不使用旧版 `messages.ackReaction`) +- 失败会被记录到日志中,但不会阻止正常回复投递 +- 群组模式 `mentions` 会在由提及触发的轮次中做出反应;群组激活模式 `always` 会绕过此检查 +- WhatsApp 使用 `channels.whatsapp.ackReaction`(此处不使用旧版 `messages.ackReaction`) -## 多账户和凭证 +## 多账号与凭证 - - - 账户 id 来自 `channels.whatsapp.accounts` - - 默认账户选择:如果存在则为 `default`,否则为第一个已配置的账户 id(排序后) - - 账户 id 在内部会标准化以便查找 + + - 账号 id 来自 `channels.whatsapp.accounts` + - 默认账号选择:如果存在 `default` 则使用它,否则使用第一个已配置的账号 id(排序后) + - 账号 id 会在内部标准化后用于查找 - - 当前认证路径:`~/.openclaw/credentials/whatsapp//creds.json` + - 当前凭证路径:`~/.openclaw/credentials/whatsapp//creds.json` - 备份文件:`creds.json.bak` - - `~/.openclaw/credentials/` 中的旧版默认认证仍会被识别/迁移,用于默认账户流程 + - `~/.openclaw/credentials/` 中的旧版默认凭证仍然可以被识别/迁移,用于默认账号流程 - `openclaw channels logout --channel whatsapp [--account ]` 会清除该账户的 WhatsApp 认证状态。 + `openclaw channels logout --channel whatsapp [--account ]` 会清除该账号的 WhatsApp 凭证状态。 - 在旧版认证目录中,会保留 `oauth.json`,同时移除 Baileys 认证文件。 + 在旧版凭证目录中,会保留 `oauth.json`,同时移除 Baileys 凭证文件。 ## 工具、操作和配置写入 -- 智能体工具支持包括 WhatsApp reaction 操作(`react`)。 +- 智能体工具支持包括 WhatsApp 反应操作(`react`)。 - 操作门控: - `channels.whatsapp.actions.reactions` - `channels.whatsapp.actions.polls` @@ -463,7 +500,7 @@ WhatsApp 支持通过 `channels.whatsapp.ackReaction` 在接收入站消息时 - 症状:已关联账户反复断开或重复尝试重连。 + 症状:已关联账号反复断开连接或重复尝试重连。 修复: @@ -476,57 +513,57 @@ WhatsApp 支持通过 `channels.whatsapp.ackReaction` 在接收入站消息时 - - 当目标账户不存在活跃的 Gateway 网关监听器时,出站发送会快速失败。 + + 当目标账号不存在活动中的 Gateway 网关监听器时,出站发送会快速失败。 - 请确保 Gateway 网关正在运行,且账户已关联。 + 请确保 Gateway 网关正在运行且该账号已关联。 - + 按以下顺序检查: - `groupPolicy` - `groupAllowFrom` / `allowFrom` - - `groups` 允许列表条目 + - `groups` 允许名单条目 - 提及门控(`requireMention` + 提及模式) - `openclaw.json`(JSON5)中的重复键:后面的条目会覆盖前面的条目,因此每个作用域只保留一个 `groupPolicy` - WhatsApp Gateway 网关运行时应使用 Node。Bun 被标记为与稳定的 WhatsApp/Telegram Gateway 网关运行不兼容。 + WhatsApp Gateway 网关运行时应使用 Node。Bun 被标记为不兼容稳定的 WhatsApp/Telegram Gateway 网关运行。 ## 系统提示词 -WhatsApp 支持像 Telegram 一样通过 `groups` 和 `direct` 映射为群组和私聊配置系统提示词。 +WhatsApp 通过 `groups` 和 `direct` 映射支持类似 Telegram 的群组和直接聊天系统提示词。 群组消息的解析层级: -首先确定生效的 `groups` 映射:如果账户定义了自己的 `groups`,它会完全替换根级 `groups` 映射(不进行深度合并)。然后会在所得的单一映射上执行提示词查找: +首先确定生效的 `groups` 映射:如果账号定义了自己的 `groups`,它会完全替换根级 `groups` 映射(不进行深度合并)。随后提示词查找会在这个最终得到的单一映射上进行: -1. **群组专用系统提示词**(`groups[""].systemPrompt`):当映射中存在该特定群组条目,且其定义了 `systemPrompt` 键时使用。如果 `systemPrompt` 是空字符串(`""`),则会抑制通配符,不应用任何系统提示词。 -2. **群组通配符系统提示词**(`groups["*"].systemPrompt`):当映射中完全不存在该特定群组条目,或者该条目存在但未定义 `systemPrompt` 键时使用。 +1. **群组专用系统提示词**(`groups[""].systemPrompt`):当映射中存在该特定群组条目,**且**其定义了 `systemPrompt` 键时使用。如果 `systemPrompt` 是空字符串(`""`),则会抑制通配符,并且不应用任何系统提示词。 +2. **群组通配符系统提示词**(`groups["*"].systemPrompt`):当映射中完全不存在该特定群组条目,或虽然存在但没有定义 `systemPrompt` 键时使用。 -私信消息的解析层级: +直接消息的解析层级: -首先确定生效的 `direct` 映射:如果账户定义了自己的 `direct`,它会完全替换根级 `direct` 映射(不进行深度合并)。然后会在所得的单一映射上执行提示词查找: +首先确定生效的 `direct` 映射:如果账号定义了自己的 `direct`,它会完全替换根级 `direct` 映射(不进行深度合并)。随后提示词查找会在这个最终得到的单一映射上进行: -1. **私信专用系统提示词**(`direct[""].systemPrompt`):当映射中存在该特定对端条目,且其定义了 `systemPrompt` 键时使用。如果 `systemPrompt` 是空字符串(`""`),则会抑制通配符,不应用任何系统提示词。 -2. **私信通配符系统提示词**(`direct["*"].systemPrompt`):当映射中完全不存在该特定对端条目,或者该条目存在但未定义 `systemPrompt` 键时使用。 +1. **直接聊天专用系统提示词**(`direct[""].systemPrompt`):当映射中存在该特定对端条目,**且**其定义了 `systemPrompt` 键时使用。如果 `systemPrompt` 是空字符串(`""`),则会抑制通配符,并且不应用任何系统提示词。 +2. **直接聊天通配符系统提示词**(`direct["*"].systemPrompt`):当映射中完全不存在该特定对端条目,或虽然存在但没有定义 `systemPrompt` 键时使用。 -注意:`dms` 仍然是轻量级的按私信历史覆盖桶(`dms..historyLimit`);提示词覆盖项位于 `direct` 下。 +注意:`dms` 仍然是轻量级的逐私信历史覆盖桶(`dms..historyLimit`);提示词覆盖位于 `direct` 下。 -**与 Telegram 多账户行为的区别:** 在 Telegram 中,在多账户设置下,根级 `groups` 会被有意地对所有账户抑制——即使某些账户没有定义自己的 `groups`——以防止机器人接收其并未加入的群组消息。WhatsApp 不应用此保护:对于未定义账户级覆盖的账户,无论配置了多少账户,都会始终继承根级 `groups` 和根级 `direct`。在多账户 WhatsApp 设置中,如果你想为每个账户设置独立的群组或私信提示词,请在每个账户下显式定义完整映射,而不要依赖根级默认值。 +**与 Telegram 多账号行为的区别:** 在 Telegram 中,为了防止机器人接收到它不属于的群组消息,在多账号设置下,根级 `groups` 会被有意抑制——即使某些账号根本没有定义自己的 `groups` 也是如此。WhatsApp 不应用这个保护:无论配置了多少账号,对于没有定义账号级覆盖的账号,根级 `groups` 和根级 `direct` 都会始终被继承。在多账号 WhatsApp 设置中,如果你想要按账号定制群组或直接聊天提示词,请在每个账号下显式定义完整映射,而不要依赖根级默认值。 重要行为: -- `channels.whatsapp.groups` 既是按群组的配置映射,也是聊天级的群组允许列表。在根级或账户级作用域中,`groups["*"]` 表示该作用域下“允许所有群组进入”。 -- 只有在你本来就希望该作用域允许所有群组时,才添加通配符群组 `systemPrompt`。如果你仍然只希望固定的一组群组 id 有资格进入,请不要将 `groups["*"]` 用作提示词默认值。应改为在每个显式列入允许列表的群组条目上重复设置该提示词。 -- 群组准入和发送者授权是两项独立检查。`groups["*"]` 会扩大可进入群组处理流程的群组集合,但它本身不会授权这些群组中的所有发送者。发送者访问仍然由 `channels.whatsapp.groupPolicy` 和 `channels.whatsapp.groupAllowFrom` 单独控制。 -- `channels.whatsapp.direct` 对私信没有相同的副作用。`direct["*"]` 只会在私信已经通过 `dmPolicy` 加上 `allowFrom` 或配对存储规则获准后,提供默认的私聊配置。 +- `channels.whatsapp.groups` 既是逐群组配置映射,也是聊天级群组允许名单。在根级或账号作用域中,`groups["*"]` 都表示该作用域“允许所有群组”。 +- 只有当你本来就希望该作用域允许所有群组时,才添加通配符群组 `systemPrompt`。如果你仍然只想让一组固定的群组 ID 有资格被允许,不要用 `groups["*"]` 作为提示词默认值。相反,应在每个显式列入允许名单的群组条目上重复该提示词。 +- 群组准入和发送者授权是两个独立检查。`groups["*"]` 会扩大可以进入群组处理流程的群组集合,但它本身不会授权这些群组中的每个发送者。发送者访问仍然由 `channels.whatsapp.groupPolicy` 和 `channels.whatsapp.groupAllowFrom` 单独控制。 +- `channels.whatsapp.direct` 对私信没有相同的副作用。`direct["*"]` 只会在私信已经通过 `dmPolicy` 加上 `allowFrom` 或配对存储规则获准后,提供默认的直接聊天配置。 示例: @@ -535,31 +572,31 @@ WhatsApp 支持像 Telegram 一样通过 `groups` 和 `direct` 映射为群组 channels: { whatsapp: { groups: { - // 仅当根级作用域应允许所有群组时使用。 - // 适用于所有未定义自身 groups 映射的账户。 - "*": { systemPrompt: "所有群组的默认提示词。" }, + // 仅当根级作用域应允许所有群组时才使用。 + // 适用于所有未定义自己 groups 映射的账号。 + "*": { systemPrompt: "Default prompt for all groups." }, }, direct: { - // 适用于所有未定义自身 direct 映射的账户。 - "*": { systemPrompt: "所有私聊的默认提示词。" }, + // 适用于所有未定义自己 direct 映射的账号。 + "*": { systemPrompt: "Default prompt for all direct chats." }, }, accounts: { work: { groups: { - // 该账户定义了自己的 groups,因此根级 groups 会被完全 + // 该账号定义了自己的 groups,因此根级 groups 会被完全 // 替换。若要保留通配符,也需要在这里显式定义 "*"。 "120363406415684625@g.us": { requireMention: false, - systemPrompt: "专注于项目管理。", + systemPrompt: "Focus on project management.", }, - // 仅当该账户应允许所有群组时使用。 - "*": { systemPrompt: "工作群组的默认提示词。" }, + // 仅当此账号中应允许所有群组时才使用。 + "*": { systemPrompt: "Default prompt for work groups." }, }, direct: { - // 该账户定义了自己的 direct 映射,因此根级 direct 条目会被 + // 该账号定义了自己的 direct 映射,因此根级 direct 条目会被 // 完全替换。若要保留通配符,也需要在这里显式定义 "*"。 - "+15551234567": { systemPrompt: "特定工作私聊的提示词。" }, - "*": { systemPrompt: "工作私聊的默认提示词。" }, + "+15551234567": { systemPrompt: "Prompt for a specific work direct chat." }, + "*": { systemPrompt: "Default prompt for work direct chats." }, }, }, }, @@ -568,7 +605,7 @@ WhatsApp 支持像 Telegram 一样通过 `groups` 和 `direct` 映射为群组 } ``` -## 配置参考指针 +## 配置参考指引 主要参考: @@ -577,8 +614,8 @@ WhatsApp 支持像 Telegram 一样通过 `groups` 和 `direct` 映射为群组 高价值的 WhatsApp 字段: - 访问控制:`dmPolicy`、`allowFrom`、`groupPolicy`、`groupAllowFrom`、`groups` -- 投递:`textChunkLimit`、`chunkMode`、`mediaMaxMb`、`sendReadReceipts`、`ackReaction`、`reactionLevel` -- 多账户:`accounts..enabled`、`accounts..authDir`、账户级覆盖 +- 消息投递:`textChunkLimit`、`chunkMode`、`mediaMaxMb`、`sendReadReceipts`、`ackReaction`、`reactionLevel` +- 多账号:`accounts..enabled`、`accounts..authDir`、账号级覆盖 - 运维:`configWrites`、`debounceMs`、`web.enabled`、`web.heartbeatSeconds`、`web.reconnect.*` - 会话行为:`session.dmScope`、`historyLimit`、`dmHistoryLimit`、`dms..historyLimit` - 提示词:`groups..systemPrompt`、`groups["*"].systemPrompt`、`direct..systemPrompt`、`direct["*"].systemPrompt` diff --git a/docs/zh-CN/gateway/index.md b/docs/zh-CN/gateway/index.md index 51b403ee1..6681249cd 100644 --- a/docs/zh-CN/gateway/index.md +++ b/docs/zh-CN/gateway/index.md @@ -1,31 +1,31 @@ --- read_when: - - 运行或调试 gateway 进程 -summary: Gateway 网关服务、生命周期和运维的操作手册 -title: Gateway 网关操作手册 + - 运行或调试 Gateway 网关进程 +summary: Gateway 网关服务、生命周期与运维运行手册 +title: Gateway 网关运行手册 x-i18n: - generated_at: "2026-04-24T03:15:57Z" + generated_at: "2026-04-24T20:10:21Z" model: gpt-5.4 provider: openai - source_hash: 6192a38447424b7e9437a7420f37d08fc38d27b736ce8c30347e6d52e3430600 + source_hash: a1d82474bc6485cc14a0be74154e08ba54455031cdae37916de5bc615d3e01a4 source_path: gateway/index.md workflow: 15 --- -将此页用于 Gateway 网关服务的 day-1 启动和 day-2 运维。 +将此页面用于 Gateway 网关服务的第 1 天启动和第 2 天运维操作。 - 按症状优先的诊断方式,提供精确的命令阶梯和日志特征。 + 以症状为起点的诊断,提供精确的命令阶梯和日志特征。 面向任务的设置指南 + 完整配置参考。 - SecretRef 契约、运行时快照行为以及 migrate/reload 操作。 + SecretRef 契约、运行时快照行为,以及迁移 / 重载操作。 - 精确的 `secrets apply` target/path 规则以及仅 ref 的 auth-profile 行为。 + 精确的 `secrets apply` 目标 / 路径规则,以及仅引用 auth-profile 行为。 @@ -36,9 +36,9 @@ x-i18n: ```bash openclaw gateway --port 18789 -# 将 debug/trace 镜像输出到 stdio +# 调试 / 跟踪会镜像到标准输入输出 openclaw gateway --port 18789 --verbose -# 强制杀掉所选端口上的监听进程,然后启动 +# 强制终止所选端口上的监听器,然后启动 openclaw gateway --force ``` @@ -52,7 +52,7 @@ openclaw status openclaw logs --follow ``` -健康基线:`Runtime: running`、`Connectivity probe: ok`,以及与你预期一致的 `Capability: ...`。当你需要的是读权限范围的 RPC 证明,而不仅仅是可达性时,请使用 `openclaw gateway status --require-rpc`。 +健康基线:`Runtime: running`、`Connectivity probe: ok`,以及与你预期一致的 `Capability: ...`。当你需要读取作用域的 RPC 证明,而不只是可达性时,请使用 `openclaw gateway status --require-rpc`。 @@ -62,34 +62,35 @@ openclaw logs --follow openclaw channels status --probe ``` -当 Gateway 网关可达时,这会运行实时的逐账户渠道探测和可选审计。 -如果 Gateway 网关不可达,CLI 会回退为仅配置的渠道摘要,而不是实时探测输出。 +在 Gateway 网关可达的情况下,这会针对每个账户运行实时渠道探测和可选审计。 +如果 Gateway 网关不可达,CLI 会回退为仅配置的渠道摘要, +而不是实时探测输出。 -Gateway 网关配置重载会监视当前活动配置文件路径(从 profile/state 默认值解析,或者在设置时使用 `OPENCLAW_CONFIG_PATH`)。 +Gateway 网关配置重载会监视当前生效的配置文件路径(从 profile / state 默认值解析,或在设置时使用 `OPENCLAW_CONFIG_PATH`)。 默认模式是 `gateway.reload.mode="hybrid"`。 -首次成功加载之后,运行中的进程会提供当前的内存内配置快照;成功重载时会以原子方式替换该快照。 +首次成功加载后,运行中的进程会提供当前生效的内存中配置快照;成功重载会以原子方式替换该快照。 ## 运行时模型 -- 一个始终在线的进程,负责路由、控制平面和渠道连接。 -- 一个复用端口,用于: - - WebSocket 控制/RPC - - HTTP API、OpenAI 兼容接口(`/v1/models`、`/v1/embeddings`、`/v1/chat/completions`、`/v1/responses`、`/tools/invoke`) - - 控制 UI 和 hooks +- 一个始终在线的进程,用于路由、控制平面和渠道连接。 +- 一个单一复用端口,用于: + - WebSocket 控制 / RPC + - HTTP API,兼容 OpenAI(`/v1/models`、`/v1/embeddings`、`/v1/chat/completions`、`/v1/responses`、`/tools/invoke`) + - 控制 UI 和钩子 - 默认绑定模式:`loopback`。 -- 默认需要认证。共享密钥方案使用 +- 默认要求身份验证。共享密钥设置使用 `gateway.auth.token` / `gateway.auth.password`(或 - `OPENCLAW_GATEWAY_TOKEN` / `OPENCLAW_GATEWAY_PASSWORD`),而非 loopback - 的反向代理方案可使用 `gateway.auth.mode: "trusted-proxy"`。 + `OPENCLAW_GATEWAY_TOKEN` / `OPENCLAW_GATEWAY_PASSWORD`),非 loopback + 的反向代理设置可使用 `gateway.auth.mode: "trusted-proxy"`。 -## OpenAI 兼容端点 +## 兼容 OpenAI 的端点 -OpenClaw 当前最高杠杆的兼容性入口是: +OpenClaw 当前最具杠杆效应的兼容性接口是: - `GET /v1/models` - `GET /v1/models/{id}` @@ -97,34 +98,34 @@ OpenClaw 当前最高杠杆的兼容性入口是: - `POST /v1/chat/completions` - `POST /v1/responses` -为什么这一组很重要: +这组接口的重要性在于: -- 大多数 Open WebUI、LobeChat 和 LibreChat 集成会先探测 `/v1/models`。 -- 许多 RAG 和 memory 流水线依赖 `/v1/embeddings`。 -- 原生面向智能体的客户端越来越倾向于使用 `/v1/responses`。 +- 大多数 Open WebUI、LobeChat 和 LibreChat 集成会首先探测 `/v1/models`。 +- 许多 RAG 和记忆流水线期望使用 `/v1/embeddings`。 +- 原生智能体客户端越来越倾向于使用 `/v1/responses`。 规划说明: -- `/v1/models` 是 agent-first:它返回 `openclaw`、`openclaw/default` 和 `openclaw/`。 +- `/v1/models` 以智能体优先:它返回 `openclaw`、`openclaw/default` 和 `openclaw/`。 - `openclaw/default` 是稳定别名,始终映射到已配置的默认智能体。 -- 当你想覆盖后端 provider/model 时,使用 `x-openclaw-model`;否则将继续由所选智能体的常规模型和嵌入设置控制。 +- 当你想覆盖后端提供商 / 模型时,请使用 `x-openclaw-model`;否则,所选智能体的常规模型和嵌入设置会继续生效。 -所有这些都运行在主 Gateway 网关端口上,并使用与 Gateway 网关其余 HTTP API 相同的可信操作员认证边界。 +以上所有接口都运行在主 Gateway 网关端口上,并使用与 Gateway 网关其余 HTTP API 相同的受信任操作员身份验证边界。 ### 端口和绑定优先级 | 设置 | 解析顺序 | | ------------ | ------------------------------------------------------------- | | Gateway 网关端口 | `--port` → `OPENCLAW_GATEWAY_PORT` → `gateway.port` → `18789` | -| 绑定模式 | CLI/override → `gateway.bind` → `loopback` | +| 绑定模式 | CLI / override → `gateway.bind` → `loopback` | ### 热重载模式 | `gateway.reload.mode` | 行为 | | --------------------- | ------------------------------------------ | | `off` | 不进行配置重载 | -| `hot` | 仅应用热安全变更 | -| `restart` | 对需要重启的变更执行重启 | +| `hot` | 仅应用可安全热更新的变更 | +| `restart` | 遇到需要重启的变更时重启 | | `hybrid`(默认) | 安全时热应用,需要时重启 | ## 操作员命令集 @@ -141,14 +142,15 @@ openclaw logs --follow openclaw doctor ``` -`gateway status --deep` 用于额外的服务发现(LaunchDaemons/systemd system -units/schtasks),而不是更深层次的 RPC 健康探测。 +`gateway status --deep` 用于额外的服务发现(LaunchDaemons / systemd system +units / schtasks),而不是更深层的 RPC 健康探测。 -## 多个网关(同一主机) +## 多个 Gateway 网关(同一主机) -大多数安装应当每台机器运行一个网关。单个 Gateway 网关可以承载多个智能体和渠道。 +大多数安装应在每台机器上运行一个 Gateway 网关。单个 Gateway 网关可以托管多个 +智能体和渠道。 -只有当你有意需要隔离或一个救援机器人时,才需要多个网关。 +只有在你明确需要隔离或救援机器人时,才需要多个 Gateway 网关。 有用的检查: @@ -157,12 +159,13 @@ openclaw gateway status --deep openclaw gateway probe ``` -预期行为: +预期结果: - `gateway status --deep` 可能报告 `Other gateway-like services detected (best effort)` - ,并在仍存在过时的 launchd/systemd/schtasks 安装时打印清理提示。 -- 当有多个目标作出响应时,`gateway probe` 可能警告 `multiple reachable gateways`。 -- 如果这是有意为之,请为每个网关隔离端口、config/state 和工作区根目录。 + 并在仍存在过时的 launchd / systemd / schtasks 安装时打印清理提示。 +- `gateway probe` 在有多个目标 + 响应时可能会警告 `multiple reachable gateways`。 +- 如果这是有意设置,请为每个 Gateway 网关隔离端口、配置 / 状态以及工作区根目录。 每个实例的检查清单: @@ -180,27 +183,57 @@ OPENCLAW_CONFIG_PATH=~/.openclaw/b.json OPENCLAW_STATE_DIR=~/.openclaw-b opencla 详细设置:[/gateway/multiple-gateways](/zh-CN/gateway/multiple-gateways)。 +## VoiceClaw 实时 brain 端点 + +OpenClaw 在 +`/voiceclaw/realtime` 提供兼容 VoiceClaw 的实时 WebSocket 端点。当 VoiceClaw 桌面客户端应直接与实时 OpenClaw brain 通信,而不是通过单独的中继进程时,请使用它。 + +该端点使用 Gemini Live 处理实时音频,并通过将 OpenClaw 工具直接暴露给 Gemini Live 来调用 OpenClaw 作为 brain。工具调用会立即返回 +`working` 结果,以保持语音轮次响应迅速;随后 OpenClaw 会异步执行实际工具,并将结果注入回实时会话中。在 Gateway 网关进程环境中设置 `GEMINI_API_KEY`。如果 +Gateway 网关身份验证已启用,桌面客户端会在其第一个 `session.config` 消息中发送 gateway token 或 password。 + +实时 brain 访问会运行经所有者授权的 OpenClaw 智能体命令。请将 +`gateway.auth.mode: "none"` 限制在仅 loopback 的测试实例中。非本地实时 brain 连接需要 Gateway 网关身份验证。 + +对于隔离的测试 Gateway 网关,请运行一个使用独立端口、配置 +和状态的单独实例: + +```bash +OPENCLAW_CONFIG_PATH=/path/to/openclaw-realtime/openclaw.json \ +OPENCLAW_STATE_DIR=/path/to/openclaw-realtime/state \ +OPENCLAW_SKIP_CHANNELS=1 \ +GEMINI_API_KEY=... \ +openclaw gateway --port 19789 +``` + +然后将 VoiceClaw 配置为使用: + +```text +ws://127.0.0.1:19789/voiceclaw/realtime +``` + ## 远程访问 -首选:Tailscale/VPN。 +首选:Tailscale / VPN。 备选:SSH 隧道。 ```bash ssh -N -L 18789:127.0.0.1:18789 user@host ``` -然后让客户端在本地连接到 `ws://127.0.0.1:18789`。 +然后在本地将客户端连接到 `ws://127.0.0.1:18789`。 -SSH 隧道不会绕过 gateway 认证。对于共享密钥认证,客户端即使通过隧道连接, -仍必须发送 `token`/`password`。对于携带身份的模式,请求仍然必须满足该认证路径。 +SSH 隧道不会绕过 Gateway 网关身份验证。对于共享密钥身份验证,客户端即使通过隧道 +仍必须发送 `token` / `password`。对于带身份标识的模式, +请求仍然必须满足该身份验证路径。 参见:[Remote Gateway](/zh-CN/gateway/remote)、[Authentication](/zh-CN/gateway/authentication)、[Tailscale](/zh-CN/gateway/tailscale)。 -## 监督和服务生命周期 +## 监管和服务生命周期 -对于接近生产环境的可靠性,请使用受监督运行。 +对于接近生产环境的可靠性,请使用受监管的运行方式。 @@ -224,7 +257,7 @@ systemctl --user enable --now openclaw-gateway[-].service openclaw gateway status ``` -如需在登出后仍保持持久运行,请启用 lingering: +若要在注销后保持持久运行,请启用 lingering: ```bash sudo loginctl enable-linger @@ -262,15 +295,16 @@ openclaw gateway restart openclaw gateway stop ``` -原生 Windows 托管启动使用名为 `OpenClaw Gateway` -的计划任务(命名 profile 则为 `OpenClaw Gateway ()`)。如果计划任务 -创建被拒绝,OpenClaw 会回退到每用户 Startup-folder 启动器,该启动器指向状态目录中的 `gateway.cmd`。 +Windows 原生托管启动使用名为 `OpenClaw Gateway` +的计划任务(命名 profile 时为 `OpenClaw Gateway ()`)。如果计划任务 +创建被拒绝,OpenClaw 会回退到每用户 Startup 文件夹启动器, +该启动器指向状态目录中的 `gateway.cmd`。 - + -对于多用户/始终在线的主机,请使用系统级 unit。 +对于多用户 / 始终在线主机,请使用系统 unit。 ```bash sudo systemctl daemon-reload @@ -278,7 +312,7 @@ sudo systemctl enable --now openclaw-gateway[-].service ``` 使用与 user unit 相同的服务主体,但将其安装到 -`/etc/systemd/system/openclaw-gateway[-].service` 下,并在你的 `openclaw` 二进制位于其他位置时调整 +`/etc/systemd/system/openclaw-gateway[-].service` 下,并在你的 `openclaw` 二进制文件位于其他位置时调整 `ExecStart=`。 @@ -292,31 +326,32 @@ openclaw --dev gateway --allow-unconfigured openclaw --dev status ``` -默认值包括隔离的 state/config,以及基础 Gateway 网关端口 `19001`。 +默认包括隔离的状态 / 配置,以及基础 Gateway 网关端口 `19001`。 ## 协议快速参考(操作员视角) -- 客户端发送的第一帧必须是 `connect`。 -- Gateway 网关返回 `hello-ok` 快照(`presence`、`health`、`stateVersion`、`uptimeMs`、limits/policy)。 -- `hello-ok.features.methods` / `events` 是保守的发现列表,而不是每个可调用辅助路由的自动生成转储。 +- 第一个客户端帧必须是 `connect`。 +- Gateway 网关返回 `hello-ok` 快照(`presence`、`health`、`stateVersion`、`uptimeMs`、limits / policy)。 +- `hello-ok.features.methods` / `events` 是保守的发现列表,而不是 + 每个可调用辅助路由的自动生成转储。 - 请求:`req(method, params)` → `res(ok/payload|error)`。 - 常见事件包括 `connect.challenge`、`agent`、`chat`、 `session.message`、`session.tool`、`sessions.changed`、`presence`、`tick`、 - `health`、`heartbeat`、配对/审批生命周期事件,以及 `shutdown`。 + `health`、`heartbeat`、pairing / approval 生命周期事件,以及 `shutdown`。 智能体运行分为两个阶段: 1. 立即接受确认(`status:"accepted"`) -2. 最终完成响应(`status:"ok"|"error"`),期间会穿插流式 `agent` 事件。 +2. 最终完成响应(`status:"ok"|"error"`),中间会流式发送 `agent` 事件。 -完整协议文档请参见:[Gateway Protocol](/zh-CN/gateway/protocol)。 +完整协议文档参见:[Gateway Protocol](/zh-CN/gateway/protocol)。 ## 运维检查 ### 存活性 - 打开 WS 并发送 `connect`。 -- 预期收到带快照的 `hello-ok` 响应。 +- 期望收到带快照的 `hello-ok` 响应。 ### 就绪性 @@ -328,23 +363,23 @@ openclaw health ### 缺口恢复 -事件不会被重放。发生序列缺口时,先刷新状态(`health`、`system-presence`)再继续。 +事件不会重放。出现序列缺口时,请先刷新状态(`health`、`system-presence`),再继续。 ## 常见故障特征 | 特征 | 可能问题 | | -------------------------------------------------------------- | ------------------------------------------------------------------------------- | -| `refusing to bind gateway ... without auth` | 非 loopback 绑定但没有有效的 gateway 认证路径 | +| `refusing to bind gateway ... without auth` | 非 loopback 绑定,且没有有效的 Gateway 网关身份验证路径 | | `another gateway instance is already listening` / `EADDRINUSE` | 端口冲突 | -| `Gateway start blocked: set gateway.mode=local` | 配置设置为 remote mode,或受损配置中缺少 local-mode 标记 | -| `unauthorized` during connect | 客户端与 Gateway 网关之间的认证不匹配 | +| `Gateway start blocked: set gateway.mode=local` | 配置设置为远程模式,或损坏配置中缺少本地模式标记 | +| `unauthorized` during connect | 客户端与 Gateway 网关之间的身份验证不匹配 | -完整诊断阶梯请使用 [Gateway 故障排除](/zh-CN/gateway/troubleshooting)。 +如需完整诊断阶梯,请参见 [Gateway 故障排除](/zh-CN/gateway/troubleshooting)。 ## 安全保证 -- 当 Gateway 网关不可用时,Gateway 协议客户端会快速失败(不会隐式回退到 direct-channel)。 -- 无效的首帧或非 connect 首帧会被拒绝并关闭连接。 +- 当 Gateway 网关不可用时,Gateway 网关协议客户端会快速失败(不会隐式回退到直连渠道)。 +- 无效的 / 非 `connect` 首帧会被拒绝并关闭连接。 - 优雅关闭会在 socket 关闭前发出 `shutdown` 事件。 --- @@ -356,9 +391,9 @@ openclaw health - [配置](/zh-CN/gateway/configuration) - [健康状态](/zh-CN/gateway/health) - [Doctor](/zh-CN/gateway/doctor) -- [认证](/zh-CN/gateway/authentication) +- [身份验证](/zh-CN/gateway/authentication) -## 相关内容 +## 相关 - [配置](/zh-CN/gateway/configuration) - [Gateway 网关故障排除](/zh-CN/gateway/troubleshooting) diff --git a/docs/zh-CN/plugins/architecture-internals.md b/docs/zh-CN/plugins/architecture-internals.md index efe2097f8..591764389 100644 --- a/docs/zh-CN/plugins/architecture-internals.md +++ b/docs/zh-CN/plugins/architecture-internals.md @@ -1,77 +1,77 @@ --- read_when: - - 实现提供商运行时钩子、渠道生命周期或软件包打包方案 + - 实现提供商运行时钩子、渠道生命周期或软件包打包 - 调试插件加载顺序或注册表状态 - 添加新的插件能力或上下文引擎插件 summary: 插件架构内部机制:加载流水线、注册表、运行时钩子、HTTP 路由和参考表格 title: 插件架构内部机制 x-i18n: - generated_at: "2026-04-24T18:19:00Z" + generated_at: "2026-04-24T20:10:23Z" model: gpt-5.4 provider: openai - source_hash: 5e2401a211505fbcda0e855572f53af74b6441c931509a2f45a1ac174a48d6ac + source_hash: 4926ca8b020752da694749f8fc43a246c7f4499a404192408dfdc9611f721ebb source_path: plugins/architecture-internals.md workflow: 15 --- -对于公开的能力模型、插件形态以及所有权 / 执行契约,请参阅 [插件架构](/zh-CN/plugins/architecture)。本页是内部机制的参考文档:加载流水线、注册表、运行时钩子、Gateway 网关 HTTP 路由、导入路径和模式表。 +关于公开的能力模型、插件形状以及所有权/执行契约,请参阅 [插件架构](/zh-CN/plugins/architecture)。本页是内部机制的参考文档:加载流水线、注册表、运行时钩子、Gateway 网关 HTTP 路由、导入路径和模式表。 ## 加载流水线 启动时,OpenClaw 大致会执行以下步骤: 1. 发现候选插件根目录 -2. 读取原生或兼容包清单以及软件包元数据 +2. 读取原生或兼容 bundle 清单以及软件包元数据 3. 拒绝不安全的候选项 4. 规范化插件配置(`plugins.enabled`、`allow`、`deny`、`entries`、`slots`、`load.paths`) -5. 决定每个候选项是否启用 +5. 为每个候选项决定是否启用 6. 加载已启用的原生模块:已构建的内置模块使用原生加载器;未构建的原生插件使用 `jiti` 7. 调用原生 `register(api)` 钩子,并将注册内容收集到插件注册表中 -8. 将注册表暴露给命令 / 运行时表面 +8. 将注册表暴露给命令/运行时表面 -`activate` 是 `register` 的旧别名——加载器会解析当前存在的那个(`def.register ?? def.activate`),并在同一时机调用。所有内置插件都使用 `register`;新插件请优先使用 `register`。 +`activate` 是 `register` 的旧别名——加载器会解析存在的那个(`def.register ?? def.activate`),并在同一时机调用它。所有内置插件都使用 `register`;新插件优先使用 `register`。 -安全门禁发生在**运行时执行之前**。当入口逃逸出插件根目录、路径对所有用户可写,或者对于非内置插件而言路径所有权看起来可疑时,候选项会被阻止。 +安全门禁发生在运行时执行**之前**。当入口逃逸出插件根目录、路径对所有用户可写,或对于非内置插件而言路径所有权看起来可疑时,候选项会被阻止。 ### 清单优先行为 清单是控制平面的事实来源。OpenClaw 用它来: -- 标识插件 -- 发现声明的渠道 / Skills / 配置模式或包能力 +- 识别插件 +- 发现声明的渠道/Skills/配置模式或 bundle 能力 - 验证 `plugins.entries..config` -- 增强 Control UI 标签 / 占位符 -- 显示安装 / 目录元数据 -- 在不加载插件运行时的情况下,保留低成本激活和设置描述符 +- 增强 Control UI 标签/占位符 +- 显示安装/目录元数据 +- 在不加载插件运行时的情况下保留轻量激活和设置描述符 对于原生插件,运行时模块是数据平面部分。它会注册实际行为,例如钩子、工具、命令或提供商流程。 -可选的清单 `activation` 和 `setup` 块仍停留在控制平面。它们只是用于激活规划和设置发现的纯元数据描述符;并不会替代运行时注册、`register(...)` 或 `setupEntry`。当前首批实时激活消费者现在会使用清单中的命令、渠道和提供商提示,在更广泛的注册表具体化之前缩小插件加载范围: +可选的清单 `activation` 和 `setup` 区块仍保留在控制平面。它们只是用于激活规划和设置发现的仅元数据描述符;不会替代运行时注册、`register(...)` 或 `setupEntry`。当前第一批实时激活消费者会使用清单中的命令、渠道和提供商提示,在更广泛的注册表实体化之前先缩小插件加载范围: - CLI 加载会缩小到拥有所请求主命令的插件 -- 渠道设置 / 插件解析会缩小到拥有所请求渠道 id 的插件 -- 显式提供商设置 / 运行时解析会缩小到拥有所请求提供商 id 的插件 +- 渠道设置/插件解析会缩小到拥有所请求渠道 id 的插件 +- 显式提供商设置/运行时解析会缩小到拥有所请求提供商 id 的插件 -激活规划器同时暴露了供现有调用方使用的仅 id API,以及供新诊断使用的 plan API。计划项会报告插件为何被选中,将显式 `activation.*` 规划器提示与清单所有权回退(如 `providers`、`channels`、`commandAliases`、`setup.providers`、`contracts.tools` 和 hooks)分离开来。这个原因拆分就是兼容性边界:现有插件元数据可继续工作,而新代码无需改变运行时加载语义,就能检测宽泛提示或回退行为。 +激活规划器既提供面向现有调用方的仅 id API,也提供面向新诊断的 plan API。Plan 条目会报告某个插件为何被选中,并将显式 `activation.*` 规划器提示与清单所有权回退原因区分开来,例如 `providers`、`channels`、`commandAliases`、`setup.providers`、`contracts.tools` 和钩子。这种原因拆分就是兼容性边界:现有插件元数据仍然可用,而新代码可以在不改变运行时加载语义的前提下检测宽泛提示或回退行为。 -设置发现现在会优先使用描述符拥有的 id,例如 `setup.providers` 和 `setup.cliBackends`,以便在回退到 `setup-api` 之前先缩小候选插件范围;`setup-api` 仅用于那些仍需要设置时运行时钩子的插件。显式 `setup.requiresRuntime: false` 是一个纯描述符截止点;若省略 `requiresRuntime`,则会为兼容性保留旧版的 `setup-api` 回退。如果发现多个插件声明了同一个规范化后的设置提供商或 CLI 后端 id,设置查找会拒绝这个模糊所有者,而不是依赖发现顺序。当设置运行时确实执行时,注册表诊断会报告 `setup.providers` / `setup.cliBackends` 与由 `setup-api` 注册的提供商或 CLI 后端之间的漂移,但不会阻止旧版插件。 +设置发现现在会优先使用描述符拥有的 id,例如 `setup.providers` 和 `setup.cliBackends`,以便在回退到 `setup-api` 之前先缩小候选插件范围;`setup-api` 用于那些仍需要设置时运行时钩子的插件。显式 `setup.requiresRuntime: false` 是仅描述符层面的截止条件;省略 `requiresRuntime` 则会保留旧版 `setup-api` 回退以实现兼容。如果多个已发现插件声明了相同的规范化设置提供商或 CLI 后端 id,设置查找会拒绝这个有歧义的所有者,而不是依赖发现顺序。当设置运行时确实执行时,注册表诊断会报告 `setup.providers` / `setup.cliBackends` 与通过 `setup-api` 注册的提供商或 CLI 后端之间的漂移,但不会阻止旧版插件。 ### 加载器会缓存什么 -OpenClaw 会保留下列短期进程内缓存: +OpenClaw 会保留短期的进程内缓存,用于: - 发现结果 - 清单注册表数据 - 已加载的插件注册表 -这些缓存可减少突发启动和重复命令开销。你可以安全地将它们视为短期性能缓存,而不是持久化存储。 +这些缓存可以减少突发启动和重复命令开销。可以把它们安全地理解为短生命周期的性能缓存,而不是持久化机制。 性能说明: - 设置 `OPENCLAW_DISABLE_PLUGIN_DISCOVERY_CACHE=1` 或 `OPENCLAW_DISABLE_PLUGIN_MANIFEST_CACHE=1` 可禁用这些缓存。 -- 可使用 `OPENCLAW_PLUGIN_DISCOVERY_CACHE_MS` 和 `OPENCLAW_PLUGIN_MANIFEST_CACHE_MS` 调整缓存窗口。 +- 使用 `OPENCLAW_PLUGIN_DISCOVERY_CACHE_MS` 和 `OPENCLAW_PLUGIN_MANIFEST_CACHE_MS` 调整缓存窗口。 ## 注册表模型 @@ -79,7 +79,7 @@ OpenClaw 会保留下列短期进程内缓存: 注册表会跟踪: -- 插件记录(标识、来源、源头、状态、诊断) +- 插件记录(身份、来源、起源、状态、诊断) - 工具 - 旧版钩子和类型化钩子 - 渠道 @@ -90,18 +90,18 @@ OpenClaw 会保留下列短期进程内缓存: - 后台服务 - 插件拥有的命令 -然后,核心功能会从该注册表中读取,而不是直接与插件模块通信。这使加载保持单向: +然后,核心功能会从该注册表中读取,而不是直接与插件模块通信。这样可以保持单向加载: - 插件模块 -> 注册表注册 - 核心运行时 -> 注册表消费 -这种分离对可维护性很重要。它意味着大多数核心表面只需要一个集成点:“读取注册表”,而不是“为每个插件模块做特殊处理”。 +这种分离对于可维护性很重要。它意味着大多数核心表面只需要一个集成点:“读取注册表”,而不是“为每个插件模块做特殊处理”。 ## 会话绑定回调 -绑定会话的插件可以在审批完成时作出响应。 +绑定会话的插件可以在审批被解决后作出响应。 -使用 `api.onConversationBindingResolved(...)` 可在绑定请求被批准或拒绝后接收回调: +使用 `api.onConversationBindingResolved(...)` 可以在绑定请求被批准或拒绝后接收回调: ```ts export default { @@ -125,81 +125,87 @@ export default { - `status`:`"approved"` 或 `"denied"` - `decision`:`"allow-once"`、`"allow-always"` 或 `"deny"` -- `binding`:用于已批准请求的已解析绑定 -- `request`:原始请求摘要、分离提示、发送方 id 和会话元数据 +- `binding`:已批准请求对应的解析后绑定 +- `request`:原始请求摘要、分离提示、发送者 id 和会话元数据 此回调仅用于通知。它不会改变谁被允许绑定会话,并且会在核心审批处理完成后运行。 ## 提供商运行时钩子 -提供商插件有三层: +提供商插件分为三层: -- **清单元数据**,用于低成本的运行时前查找:`providerAuthEnvVars`、`providerAuthAliases`、`providerAuthChoices` 和 `channelEnvVars`。 -- **配置时钩子**:`catalog`(旧称 `discovery`)以及 `applyConfigDefaults`。 -- **运行时钩子**:40 多个可选钩子,涵盖认证、模型解析、流包装、思考级别、重放策略和用量端点。完整列表请参见[钩子顺序和用法](#hook-order-and-usage)。 +- **清单元数据**,用于低成本的运行前查找: + `setup.providers[].envVars`、已弃用的兼容字段 `providerAuthEnvVars`、 + `providerAuthAliases`、`providerAuthChoices` 和 `channelEnvVars`。 +- **配置时钩子**:`catalog`(旧称 `discovery`)以及 + `applyConfigDefaults`。 +- **运行时钩子**:40 多个可选钩子,涵盖鉴权、模型解析、 + 流包装、思考等级、重放策略和用量端点。完整列表请参阅 + [钩子顺序和用法](#hook-order-and-usage)。 -OpenClaw 仍然负责通用智能体循环、故障切换、转录处理和工具策略。这些钩子是提供商特定行为的扩展表面,无需完整自定义推理传输即可实现。 +OpenClaw 仍然负责通用智能体循环、故障转移、转录处理和工具策略。这些钩子是提供商特定行为的扩展表面,无需整套自定义推理传输即可实现。 -当提供商具有基于环境变量的凭证,且通用认证 / 状态 / 模型选择器路径需要在不加载插件运行时的情况下看到这些凭证时,请使用清单 `providerAuthEnvVars`。当某个提供商 id 需要复用另一个提供商 id 的环境变量、认证配置文件、基于配置的认证以及 API 密钥新手引导选项时,请使用清单 `providerAuthAliases`。当新手引导 / 认证选择 CLI 表面需要在不加载提供商运行时的情况下了解该提供商的 choice id、分组标签和简单的单标志认证接线时,请使用清单 `providerAuthChoices`。请将提供商运行时 `envVars` 保留用于面向运维人员的提示,例如新手引导标签或 OAuth client-id / client-secret 设置变量。 +当提供商具有基于环境变量的凭证,并且希望通用鉴权/状态/模型选择器路径在不加载插件运行时的情况下也能看到这些凭证时,请使用清单 `setup.providers[].envVars`。已弃用的 `providerAuthEnvVars` 在弃用窗口期间仍会被兼容适配器读取,使用它的非内置插件会收到一条清单诊断。当一个提供商 id 应复用另一个提供商 id 的环境变量、鉴权配置文件、基于配置的鉴权以及 API 密钥新手引导选项时,请使用清单 `providerAuthAliases`。当新手引导/鉴权选择 CLI 表面需要在不加载提供商运行时的情况下知道提供商的 choice id、分组标签和简单单标志鉴权接线时,请使用清单 `providerAuthChoices`。提供商运行时中的 `envVars` 仍应用于面向操作员的提示,例如新手引导标签或 OAuth `client-id`/`client-secret` 设置变量。 -当某个渠道具有由环境变量驱动的认证或设置,且通用 shell 环境变量回退、配置 / 状态检查或设置提示需要在不加载渠道运行时的情况下看到这些内容时,请使用清单 `channelEnvVars`。 +当某个渠道具有由环境变量驱动的鉴权或设置,并且希望通用 shell 环境变量回退、配置/状态检查或设置提示在不加载渠道运行时的情况下也能看到这些信息时,请使用清单 `channelEnvVars`。 ### 钩子顺序和用法 -对于模型 / 提供商插件,OpenClaw 会大致按以下顺序调用钩子。“何时使用”列是快速决策指南。 +对于模型/提供商插件,OpenClaw 大致会按以下顺序调用钩子。 +“何时使用”列是快速决策指南。 -| # | 钩子 | 作用 | 何时使用 | +| # | 钩子 | 作用 | 何时使用 | | --- | --------------------------------- | -------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- | -| 1 | `catalog` | 在生成 `models.json` 期间将提供商配置发布到 `models.providers` 中 | 提供商拥有目录或 base URL 默认值 | -| 2 | `applyConfigDefaults` | 在配置具体化期间应用由提供商拥有的全局配置默认值 | 默认值依赖认证模式、环境变量或提供商模型家族语义 | -| -- | _(内置模型查找)_ | OpenClaw 会先尝试正常的注册表 / 目录路径 | _(不是插件钩子)_ | -| 3 | `normalizeModelId` | 在查找前规范化旧版或预览版 model-id 别名 | 提供商拥有在规范模型解析前进行别名清理的逻辑 | -| 4 | `normalizeTransport` | 在通用模型组装前规范化提供商家族的 `api` / `baseUrl` | 提供商拥有同一传输家族中自定义提供商 id 的传输清理逻辑 | -| 5 | `normalizeConfig` | 在运行时 / 提供商解析前规范化 `models.providers.` | 提供商需要将配置清理逻辑放在插件中;内置的 Google 家族辅助逻辑也会为受支持的 Google 配置项提供兜底 | -| 6 | `applyNativeStreamingUsageCompat` | 对配置提供商应用原生流式用量兼容性重写 | 提供商需要针对由端点驱动的原生流式用量元数据进行修正 | -| 7 | `resolveConfigApiKey` | 在加载运行时认证前,为配置提供商解析环境变量标记认证 | 提供商拥有由其管理的环境变量标记 API 密钥解析逻辑;`amazon-bedrock` 在这里也有一个内置的 AWS 环境变量标记解析器 | -| 8 | `resolveSyntheticAuth` | 在不持久化明文的情况下暴露本地 / 自托管或基于配置的认证 | 提供商可使用合成 / 本地凭证标记运行 | -| 9 | `resolveExternalAuthProfiles` | 叠加由提供商拥有的外部认证配置文件;CLI / 应用拥有的凭证默认 `persistence` 为 `runtime-only` | 提供商可复用外部认证凭证而不持久化复制的刷新令牌;请在清单中声明 `contracts.externalAuthProviders` | -| 10 | `shouldDeferSyntheticProfileAuth` | 将已存储的合成配置文件占位符优先级降低到环境变量 / 基于配置的认证之后 | 提供商存储了合成占位配置文件,而这些配置文件不应具有更高优先级 | -| 11 | `resolveDynamicModel` | 为本地注册表中尚不存在的由提供商拥有的模型 id 提供同步回退 | 提供商接受任意上游模型 id | -| 12 | `prepareDynamicModel` | 先执行异步预热,然后再次运行 `resolveDynamicModel` | 提供商在解析未知 id 前需要网络元数据 | -| 13 | `normalizeResolvedModel` | 在嵌入式运行器使用已解析模型之前进行最终重写 | 提供商需要进行传输重写,但仍使用核心传输 | -| 14 | `contributeResolvedModelCompat` | 为另一种兼容传输背后的厂商模型提供兼容性标志 | 提供商可在不接管该提供商的情况下,在代理传输上识别自己的模型 | -| 15 | `capabilities` | 由共享核心逻辑使用的、由提供商拥有的转录 / 工具元数据 | 提供商需要处理转录 / 提供商家族特有行为 | -| 16 | `normalizeToolSchemas` | 在嵌入式运行器看到工具模式前,对工具模式进行规范化 | 提供商需要进行传输家族级别的模式清理 | -| 17 | `inspectToolSchemas` | 在规范化后暴露由提供商拥有的模式诊断信息 | 提供商希望给出关键字警告,而不必让核心学习提供商特定规则 | -| 18 | `resolveReasoningOutputMode` | 选择原生推理输出契约还是带标签的推理输出契约 | 提供商需要使用带标签的推理 / 最终输出,而不是原生字段 | -| 19 | `prepareExtraParams` | 在通用流选项包装器之前执行请求参数规范化 | 提供商需要默认请求参数或按提供商进行参数清理 | -| 20 | `createStreamFn` | 使用自定义传输完全替换正常流路径 | 提供商需要自定义线协议,而不仅仅是包装器 | -| 21 | `wrapStreamFn` | 在应用通用包装器后对流函数进行包装 | 提供商需要请求头 / 请求体 / 模型兼容性包装器,而不需要自定义传输 | -| 22 | `resolveTransportTurnState` | 附加原生的逐轮传输请求头或元数据 | 提供商希望通用传输发送提供商原生的轮次标识 | -| 23 | `resolveWebSocketSessionPolicy` | 附加原生 WebSocket 请求头或会话冷却策略 | 提供商希望通用 WS 传输调整会话请求头或回退策略 | -| 24 | `formatApiKey` | 认证配置文件格式化器:已存储的配置文件会变成运行时 `apiKey` 字符串 | 提供商存储了额外的认证元数据,并且需要自定义运行时令牌形态 | -| 25 | `refreshOAuth` | 针对自定义刷新端点或刷新失败策略的 OAuth 刷新覆盖 | 提供商不适配共享的 `pi-ai` 刷新器 | -| 26 | `buildAuthDoctorHint` | 在 OAuth 刷新失败时附加修复提示 | 提供商需要在刷新失败后给出由其管理的认证修复指导 | -| 27 | `matchesContextOverflowError` | 由提供商拥有的上下文窗口溢出匹配器 | 提供商存在通用启发式无法识别的原始溢出错误 | -| 28 | `classifyFailoverReason` | 由提供商拥有的故障切换原因分类 | 提供商可以将原始 API / 传输错误映射为速率限制 / 过载等 | -| 29 | `isCacheTtlEligible` | 面向代理 / 回传提供商的提示缓存策略 | 提供商需要代理特定的缓存 TTL 门控 | -| 30 | `buildMissingAuthMessage` | 替换通用的缺失认证恢复消息 | 提供商需要提供商特定的缺失认证恢复提示 | -| 31 | `suppressBuiltInModel` | 过时上游模型抑制,并可附带面向用户的错误提示 | 提供商需要隐藏过时的上游条目,或用厂商提示替换它们 | -| 32 | `augmentModelCatalog` | 在发现之后追加合成 / 最终目录条目 | 提供商需要在 `models list` 和选择器中加入用于前向兼容的合成条目 | -| 33 | `resolveThinkingProfile` | 针对特定模型的 `/think` 级别集、显示标签和默认值 | 提供商为选定模型提供自定义思考层级或二元标签 | -| 34 | `isBinaryThinking` | 开 / 关推理切换兼容性钩子 | 提供商只暴露二元的思考开 / 关 | -| 35 | `supportsXHighThinking` | `xhigh` 推理支持兼容性钩子 | 提供商只希望在部分模型上启用 `xhigh` | -| 36 | `resolveDefaultThinkingLevel` | 默认 `/think` 级别兼容性钩子 | 提供商拥有某个模型家族的默认 `/think` 策略 | -| 37 | `isModernModelRef` | 用于实时配置文件过滤和冒烟选择的现代模型匹配器 | 提供商拥有实时 / 冒烟优选模型匹配逻辑 | -| 38 | `prepareRuntimeAuth` | 在推理前将已配置的凭证交换为实际运行时令牌 / 密钥 | 提供商需要令牌交换或短期请求凭证 | -| 39 | `resolveUsageAuth` | 为 `/usage` 和相关状态表面解析用量 / 计费凭证 | 提供商需要自定义用量 / 配额令牌解析,或使用不同的用量凭证 | -| 40 | `fetchUsageSnapshot` | 在认证解析完成后获取并规范化提供商特定的用量 / 配额快照 | 提供商需要提供商特定的用量端点或负载解析器 | -| 41 | `createEmbeddingProvider` | 为内存 / 搜索构建由提供商拥有的嵌入适配器 | Memory 嵌入行为应归属于提供商插件 | -| 42 | `buildReplayPolicy` | 返回一个控制该提供商转录处理方式的重放策略 | 提供商需要自定义转录策略(例如去除 thinking 块) | -| 43 | `sanitizeReplayHistory` | 在通用转录清理后重写重放历史 | 提供商需要在共享压缩辅助逻辑之外执行提供商特定的重放重写 | -| 44 | `validateReplayTurns` | 在嵌入式运行器之前对重放轮次进行最终验证或重塑 | 提供商传输在通用净化后需要更严格的轮次验证 | -| 45 | `onModelSelected` | 在模型被选中后运行由提供商拥有的副作用 | 当模型变为激活状态时,提供商需要遥测或由提供商拥有的状态 | +| 1 | `catalog` | 在生成 `models.json` 期间,将提供商配置发布到 `models.providers` 中 | 提供商拥有目录或基础 URL 默认值 | +| 2 | `applyConfigDefaults` | 在配置实体化期间应用由提供商拥有的全局配置默认值 | 默认值依赖于鉴权模式、环境或提供商模型族语义 | +| -- | _(内置模型查找)_ | OpenClaw 会先尝试常规的注册表/目录路径 | _(不是插件钩子)_ | +| 3 | `normalizeModelId` | 在查找之前规范化旧版或预览版 model-id 别名 | 提供商在规范模型解析之前拥有别名清理逻辑 | +| 4 | `normalizeTransport` | 在通用模型组装之前规范化提供商族的 `api` / `baseUrl` | 提供商拥有同一传输族中自定义提供商 id 的传输清理逻辑 | +| 5 | `normalizeConfig` | 在运行时/提供商解析之前规范化 `models.providers.` | 提供商需要应与插件一起维护的配置清理逻辑;内置的 Google 族辅助逻辑也会为受支持的 Google 配置条目提供兜底 | +| 6 | `applyNativeStreamingUsageCompat` | 对配置提供商应用原生流式用量兼容性重写 | 提供商需要基于端点驱动的原生流式用量元数据修复 | +| 7 | `resolveConfigApiKey` | 在加载运行时鉴权之前,为配置提供商解析 env-marker 鉴权 | 提供商拥有自己的 env-marker API 密钥解析逻辑;`amazon-bedrock` 在这里也有内置的 AWS env-marker 解析器 | +| 8 | `resolveSyntheticAuth` | 在不持久化明文的情况下暴露本地/自托管或基于配置的鉴权 | 提供商可以使用合成/本地凭证标记运行 | +| 9 | `resolveExternalAuthProfiles` | 叠加由提供商拥有的外部鉴权配置文件;默认 `persistence` 对 CLI/应用拥有的凭证为 `runtime-only` | 提供商可在不持久化复制来的刷新令牌的情况下复用外部鉴权凭证;在清单中声明 `contracts.externalAuthProviders` | +| 10 | `shouldDeferSyntheticProfileAuth` | 将已存储的合成配置文件占位符优先级降低到环境变量/基于配置的鉴权之后 | 提供商存储了不应获得更高优先级的合成占位配置文件 | +| 11 | `resolveDynamicModel` | 对本地注册表中尚不存在的、由提供商拥有的模型 id 进行同步回退 | 提供商接受任意上游模型 id | +| 12 | `prepareDynamicModel` | 先进行异步预热,然后再次运行 `resolveDynamicModel` | 提供商在解析未知 id 之前需要网络元数据 | +| 13 | `normalizeResolvedModel` | 在嵌入式运行器使用已解析模型之前进行最终重写 | 提供商需要传输重写,但仍使用核心传输 | +| 14 | `contributeResolvedModelCompat` | 为位于另一兼容传输之后的厂商模型提供兼容标志 | 提供商能在不接管该提供商的情况下,在代理传输上识别自己的模型 | +| 15 | `capabilities` | 由提供商拥有、供共享核心逻辑使用的转录/工具元数据 | 提供商需要转录/提供商族特定的特殊处理 | +| 16 | `normalizeToolSchemas` | 在嵌入式运行器看到工具模式之前对其进行规范化 | 提供商需要传输族级别的模式清理逻辑 | +| 17 | `inspectToolSchemas` | 在规范化之后暴露由提供商拥有的模式诊断 | 提供商希望提供关键字警告,而不需要让核心理解提供商特定规则 | +| 18 | `resolveReasoningOutputMode` | 选择原生推理输出契约还是带标签的推理输出契约 | 提供商需要使用带标签的推理/最终输出,而不是原生字段 | +| 19 | `prepareExtraParams` | 在通用流选项包装器之前进行请求参数规范化 | 提供商需要默认请求参数或按提供商进行参数清理 | +| 20 | `createStreamFn` | 用自定义传输完全替换常规流路径 | 提供商需要自定义线传协议,而不仅仅是包装器 | +| 21 | `wrapStreamFn` | 在应用通用包装器之后对流函数进行包装 | 提供商需要请求头/请求体/模型兼容性包装器,但不需要自定义传输 | +| 22 | `resolveTransportTurnState` | 附加原生的逐轮传输头或元数据 | 提供商希望通用传输发送提供商原生的轮次标识 | +| 23 | `resolveWebSocketSessionPolicy` | 附加原生 WebSocket 请求头或会话冷却策略 | 提供商希望通用 WS 传输调整会话请求头或回退策略 | +| 24 | `formatApiKey` | 鉴权配置文件格式化器:已存储配置文件会变成运行时 `apiKey` 字符串 | 提供商存储了额外鉴权元数据,并且需要自定义运行时令牌形状 | +| 25 | `refreshOAuth` | 针对自定义刷新端点或刷新失败策略的 OAuth 刷新覆盖 | 提供商不适配共享的 `pi-ai` 刷新器 | +| 26 | `buildAuthDoctorHint` | 当 OAuth 刷新失败时附加的修复提示 | 提供商在刷新失败后需要由提供商拥有的鉴权修复指引 | +| 27 | `matchesContextOverflowError` | 由提供商拥有的上下文窗口溢出匹配器 | 提供商存在通用启发式无法识别的原始溢出错误 | +| 28 | `classifyFailoverReason` | 由提供商拥有的故障转移原因分类 | 提供商可以将原始 API/传输错误映射为速率限制/过载等原因 | +| 29 | `isCacheTtlEligible` | 面向代理/回程提供商的提示缓存策略 | 提供商需要代理特定的缓存 TTL 门禁 | +| 30 | `buildMissingAuthMessage` | 替换通用的缺失鉴权恢复消息 | 提供商需要提供商特定的缺失鉴权恢复提示 | +| 31 | `suppressBuiltInModel` | 过时上游模型抑制,以及可选的面向用户错误提示 | 提供商需要隐藏过时的上游行,或用厂商提示替换它们 | +| 32 | `augmentModelCatalog` | 在发现之后追加合成/最终目录行 | 提供商需要在 `models list` 和选择器中提供合成的前向兼容行 | +| 33 | `resolveThinkingProfile` | 设置特定模型的 `/think` 级别、显示标签和默认值 | 提供商为选定模型提供自定义思考阶梯或二元标签 | +| 34 | `isBinaryThinking` | 开/关推理切换兼容性钩子 | 提供商只暴露二元的思考开/关 | +| 35 | `supportsXHighThinking` | `xhigh` 推理支持兼容性钩子 | 提供商希望仅在部分模型上启用 `xhigh` | +| 36 | `resolveDefaultThinkingLevel` | 默认 `/think` 级别兼容性钩子 | 提供商拥有某个模型族的默认 `/think` 策略 | +| 37 | `isModernModelRef` | 用于实时配置文件过滤和 smoke 选择的现代模型匹配器 | 提供商拥有实时/smoke 首选模型匹配逻辑 | +| 38 | `prepareRuntimeAuth` | 在推理前将已配置凭证交换为实际运行时令牌/密钥 | 提供商需要令牌交换或短期请求凭证 | +| 39 | `resolveUsageAuth` | 为 `/usage` 及相关状态表面解析用量/计费凭证 | 提供商需要自定义用量/配额令牌解析,或使用不同的用量凭证 | +| 40 | `fetchUsageSnapshot` | 在鉴权解析后获取并规范化提供商特定的用量/配额快照 | 提供商需要提供商特定的用量端点或负载解析器 | +| 41 | `createEmbeddingProvider` | 为 memory/search 构建由提供商拥有的 embedding 适配器 | Memory embedding 行为应与提供商插件放在一起 | +| 42 | `buildReplayPolicy` | 返回一个控制该提供商转录处理的重放策略 | 提供商需要自定义转录策略(例如去除 thinking block) | +| 43 | `sanitizeReplayHistory` | 在通用转录清理后重写重放历史 | 提供商需要超出共享压缩辅助逻辑之外的提供商特定重放重写 | +| 44 | `validateReplayTurns` | 在嵌入式运行器之前对重放轮次进行最终验证或重塑 | 提供商传输在通用清理之后需要更严格的轮次验证 | +| 45 | `onModelSelected` | 运行由提供商拥有的选择后副作用 | 当模型变为活动状态时,提供商需要遥测或由提供商拥有的状态 | -`normalizeModelId`、`normalizeTransport` 和 `normalizeConfig` 会先检查匹配到的提供商插件,然后继续检查其他具备钩子能力的提供商插件,直到某个插件实际更改了模型 id 或传输 / 配置。这样可以让别名 / 兼容性提供商 shim 正常工作,而不要求调用方知道哪个内置插件拥有该重写逻辑。如果没有任何提供商钩子重写某个受支持的 Google 家族配置项,内置的 Google 配置规范化器仍会应用该兼容性清理。 +`normalizeModelId`、`normalizeTransport` 和 `normalizeConfig` 会先检查匹配到的提供商插件,然后继续落到其他支持这些钩子的提供商插件,直到某个插件真正更改了模型 id 或传输/配置。这样可以让别名/兼容性提供商 shim 正常工作,而不要求调用方知道究竟是哪个内置插件拥有这次重写。如果没有任何提供商钩子重写受支持的 Google 族配置条目,内置的 Google 配置规范化器仍会应用该兼容性清理。 -如果提供商需要完全自定义的线协议或自定义请求执行器,那就是另一类扩展了。这些钩子适用于仍然运行在 OpenClaw 正常推理循环上的提供商行为。 +如果提供商需要完全自定义的线传协议或自定义请求执行器,那属于另一类扩展。这些钩子适用于仍运行在 OpenClaw 常规推理循环上的提供商行为。 ### 提供商示例 @@ -257,29 +263,41 @@ api.registerProvider({ ### 内置示例 -内置提供商插件会组合使用上述钩子,以适配各个厂商在目录、认证、思考、重放和用量方面的需求。权威的钩子集合位于 `extensions/` 下各个插件内部;本页旨在说明这些形态,而不是镜像完整列表。 +内置提供商插件会组合使用上述钩子,以满足各厂商在目录、鉴权、思考、重放和用量方面的需求。权威的钩子集合与每个 `extensions/` 下的插件一同维护;本页展示的是形状,而不是镜像完整列表。 - OpenRouter、Kilocode、Z.AI、xAI 会注册 `catalog` 以及 `resolveDynamicModel` / `prepareDynamicModel`,这样它们就能在 OpenClaw 的静态目录之前暴露上游模型 id。 + OpenRouter、Kilocode、Z.AI、xAI 会注册 `catalog` 以及 + `resolveDynamicModel` / `prepareDynamicModel`,这样它们就能在 + OpenClaw 的静态目录之前暴露上游模型 id。 - GitHub Copilot、Gemini CLI、ChatGPT Codex、MiniMax、Xiaomi、z.ai 会将 `prepareRuntimeAuth` 或 `formatApiKey` 与 `resolveUsageAuth` + `fetchUsageSnapshot` 配对使用,以接管令牌交换和 `/usage` 集成。 + GitHub Copilot、Gemini CLI、ChatGPT Codex、MiniMax、Xiaomi、z.ai + 会将 `prepareRuntimeAuth` 或 `formatApiKey` 与 `resolveUsageAuth` + + `fetchUsageSnapshot` 配对使用,以接管令牌交换和 `/usage` 集成。 - 共享的命名家族(`google-gemini`、`passthrough-gemini`、`anthropic-by-model`、`hybrid-anthropic-openai`)允许提供商通过 `buildReplayPolicy` 选择启用转录策略,而无需每个插件都重新实现清理逻辑。 + 共享的命名家族(`google-gemini`、`passthrough-gemini`、 + `anthropic-by-model`、`hybrid-anthropic-openai`)让提供商可以通过 + `buildReplayPolicy` 选择加入转录策略,而不必由每个插件重新实现清理。 - `byteplus`、`cloudflare-ai-gateway`、`huggingface`、`kimi-coding`、`nvidia`、`qianfan`、`synthetic`、`together`、`venice`、`vercel-ai-gateway` 和 `volcengine` 仅注册 `catalog`,并复用共享推理循环。 + `byteplus`、`cloudflare-ai-gateway`、`huggingface`、`kimi-coding`、`nvidia`、 + `qianfan`、`synthetic`、`together`、`venice`、`vercel-ai-gateway` 和 + `volcengine` 只注册 `catalog`,并复用共享推理循环。 - - Beta 请求头、`/fast` / `serviceTier` 和 `context1m` 位于 Anthropic 插件公开的 `api.ts` / `contract-api.ts` 接缝中(`wrapAnthropicProviderStream`、`resolveAnthropicBetas`、`resolveAnthropicFastMode`、`resolveAnthropicServiceTier`),而不是放在通用 SDK 中。 + + Beta 请求头、`/fast` / `serviceTier` 以及 `context1m` 位于 + Anthropic 插件公开的 `api.ts` / `contract-api.ts` 接缝中 + (`wrapAnthropicProviderStream`、`resolveAnthropicBetas`、 + `resolveAnthropicFastMode`、`resolveAnthropicServiceTier`),而不是位于 + 通用 SDK 中。 ## 运行时辅助工具 -插件可以通过 `api.runtime` 访问选定的核心辅助工具。以 TTS 为例: +插件可以通过 `api.runtime` 访问部分核心辅助工具。对于 TTS: ```ts const clip = await api.runtime.tts.textToSpeech({ @@ -300,12 +318,12 @@ const voices = await api.runtime.tts.listVoices({ 说明: -- `textToSpeech` 返回普通核心 TTS 输出负载,用于文件 / 语音便笺表面。 +- `textToSpeech` 返回用于文件/语音便笺表面的常规核心 TTS 输出负载。 - 使用核心 `messages.tts` 配置和提供商选择。 -- 返回 PCM 音频缓冲区 + 采样率。插件必须为提供商执行重采样 / 编码。 -- `listVoices` 对每个提供商来说是可选的。可将其用于厂商自有的语音选择器或设置流程。 -- 语音列表可以包含更丰富的元数据,例如语言区域、性别和个性标签,以供具备提供商感知能力的选择器使用。 -- 目前支持电话语音的是 OpenAI 和 ElevenLabs。Microsoft 不支持。 +- 返回 PCM 音频缓冲区 + 采样率。插件必须为提供商进行重采样/编码。 +- `listVoices` 对每个提供商而言是可选的。将其用于由厂商拥有的语音选择器或设置流程。 +- 语音列表可以包含更丰富的元数据,例如语言区域、性别和个性标签,以便提供商感知型选择器使用。 +- 当前 OpenAI 和 ElevenLabs 支持 telephony。Microsoft 不支持。 插件也可以通过 `api.registerSpeechProvider(...)` 注册语音提供商。 @@ -328,11 +346,11 @@ api.registerSpeechProvider({ 说明: - 将 TTS 策略、回退和回复投递保留在核心中。 -- 使用语音提供商来承载厂商自有的合成行为。 +- 使用语音提供商来承载由厂商拥有的合成行为。 - 旧版 Microsoft `edge` 输入会被规范化为 `microsoft` 提供商 id。 -- 首选所有权模型是面向公司的:随着 OpenClaw 添加这些能力契约,一个厂商插件可以统一拥有文本、语音、图像和未来的媒体提供商。 +- 推荐的所有权模型是面向公司:随着 OpenClaw 添加这些能力契约,一个厂商插件可以统一拥有文本、语音、图像以及未来的媒体提供商。 -对于图像 / 音频 / 视频理解,插件应注册一个类型化的媒体理解提供商,而不是使用通用键 / 值包: +对于图像/音频/视频理解,插件会注册一个带类型的媒体理解提供商,而不是通用的键值包: ```ts api.registerMediaUnderstandingProvider({ @@ -349,10 +367,10 @@ api.registerMediaUnderstandingProvider({ - 将编排、回退、配置和渠道接线保留在核心中。 - 将厂商行为保留在提供商插件中。 - 增量扩展应保持类型化:新增可选方法、新增可选结果字段、新增可选能力。 -- 视频生成已经遵循相同模式: +- 视频生成已经遵循同样的模式: - 核心拥有能力契约和运行时辅助工具 - 厂商插件注册 `api.registerVideoGenerationProvider(...)` - - 功能 / 渠道插件消费 `api.runtime.videoGeneration.*` + - 功能/渠道插件消费 `api.runtime.videoGeneration.*` 对于媒体理解运行时辅助工具,插件可以调用: @@ -369,7 +387,7 @@ const video = await api.runtime.mediaUnderstanding.describeVideoFile({ }); ``` -对于音频转录,插件既可以使用媒体理解运行时,也可以使用旧版 STT 别名: +对于音频转录,插件既可以使用媒体理解运行时,也可以使用较旧的 STT 别名: ```ts const { text } = await api.runtime.mediaUnderstanding.transcribeAudioFile({ @@ -382,10 +400,10 @@ const { text } = await api.runtime.mediaUnderstanding.transcribeAudioFile({ 说明: -- `api.runtime.mediaUnderstanding.*` 是图像 / 音频 / 视频理解的首选共享表面。 +- `api.runtime.mediaUnderstanding.*` 是图像/音频/视频理解的首选共享表面。 - 使用核心媒体理解音频配置(`tools.media.audio`)和提供商回退顺序。 -- 当未产生转录输出时(例如输入被跳过 / 不受支持),返回 `{ text: undefined }`。 -- `api.runtime.stt.transcribeAudioFile(...)` 仍作为兼容性别名保留。 +- 当没有产生转录输出时(例如输入被跳过/不受支持),返回 `{ text: undefined }`。 +- `api.runtime.stt.transcribeAudioFile(...)` 仍然保留为兼容性别名。 插件还可以通过 `api.runtime.subagent` 启动后台子智能体运行: @@ -402,12 +420,12 @@ const result = await api.runtime.subagent.run({ 说明: - `provider` 和 `model` 是每次运行的可选覆盖项,不是持久化的会话变更。 -- OpenClaw 只会为受信任调用方应用这些覆盖字段。 -- 对于插件自有的回退运行,运维人员必须通过 `plugins.entries..subagent.allowModelOverride: true` 显式启用。 -- 使用 `plugins.entries..subagent.allowedModels` 将受信任插件限制为特定规范 `provider/model` 目标,或使用 `"*"` 显式允许任意目标。 -- 不受信任插件的子智能体运行仍然可用,但覆盖请求会被拒绝,而不是静默回退。 +- OpenClaw 只会对受信任调用方应用这些覆盖字段。 +- 对于插件拥有的回退运行,操作员必须通过 `plugins.entries..subagent.allowModelOverride: true` 显式启用。 +- 使用 `plugins.entries..subagent.allowedModels` 可将受信任插件限制为特定的规范 `provider/model` 目标,或使用 `"*"` 以显式允许任意目标。 +- 不受信任的插件子智能体运行仍然可用,但覆盖请求会被拒绝,而不是静默回退。 -对于 Web 搜索,插件可以使用共享运行时辅助工具,而不是深入依赖智能体工具接线: +对于 Web 搜索,插件可以使用共享运行时辅助工具,而不必深入到智能体工具接线中: ```ts const providers = api.runtime.webSearch.listProviders({ @@ -423,13 +441,14 @@ const result = await api.runtime.webSearch.search({ }); ``` -插件也可以通过 `api.registerWebSearchProvider(...)` 注册 Web 搜索提供商。 +插件也可以通过 +`api.registerWebSearchProvider(...)` 注册 Web 搜索提供商。 说明: - 将提供商选择、凭证解析和共享请求语义保留在核心中。 -- 使用 Web 搜索提供商来承载厂商特定的搜索传输。 -- `api.runtime.webSearch.*` 是功能 / 渠道插件在需要搜索行为但不依赖智能体工具包装器时的首选共享表面。 +- 使用 Web 搜索提供商承载厂商特定的搜索传输。 +- `api.runtime.webSearch.*` 是需要搜索行为但又不依赖智能体工具包装器的功能/渠道插件的首选共享表面。 ### `api.runtime.imageGeneration` @@ -467,151 +486,173 @@ api.registerHttpRoute({ 路由字段: - `path`:Gateway 网关 HTTP 服务器下的路由路径。 -- `auth`:必填。使用 `"gateway"` 以要求普通 Gateway 网关认证,或使用 `"plugin"` 以要求插件管理的认证 / webhook 验证。 -- `match`:可选。可为 `"exact"`(默认)或 `"prefix"`。 -- `replaceExisting`:可选。允许同一插件替换其自己现有的路由注册。 -- `handler`:当路由处理了该请求时返回 `true`。 +- `auth`:必填。使用 `"gateway"` 以要求常规 Gateway 网关鉴权,或使用 `"plugin"` 以要求由插件管理的鉴权/Webhook 验证。 +- `match`:可选。`"exact"`(默认)或 `"prefix"`。 +- `replaceExisting`:可选。允许同一个插件替换自己现有的路由注册。 +- `handler`:当该路由处理了请求时返回 `true`。 说明: -- `api.registerHttpHandler(...)` 已被移除,并会导致插件加载错误。请改用 `api.registerHttpRoute(...)`。 +- `api.registerHttpHandler(...)` 已移除,并会导致插件加载错误。请改用 `api.registerHttpRoute(...)`。 - 插件路由必须显式声明 `auth`。 -- 除非设置 `replaceExisting: true`,否则精确的 `path + match` 冲突会被拒绝,且一个插件不能替换另一个插件的路由。 -- 具有不同 `auth` 级别的重叠路由会被拒绝。`exact` / `prefix` 贯穿链只能保留在同一认证级别上。 -- `auth: "plugin"` 路由**不会**自动接收运维人员运行时作用域。它们用于插件管理的 webhook / 签名验证,而不是特权 Gateway 网关辅助调用。 -- `auth: "gateway"` 路由会在 Gateway 网关请求运行时作用域中运行,但该作用域是有意保守设计的: - - 共享密钥 bearer 认证(`gateway.auth.mode = "token"` / `"password"`)会将插件路由运行时作用域固定为 `operator.write`,即使调用方发送了 `x-openclaw-scopes` - - 受信任的携带身份 HTTP 模式(例如 `trusted-proxy`,或私有入口上的 `gateway.auth.mode = "none"`)只有在请求头显式存在时才会应用 `x-openclaw-scopes` - - 如果这些携带身份的插件路由请求中缺少 `x-openclaw-scopes`,运行时作用域会回退到 `operator.write` -- 实务规则:不要假设一个采用 gateway 认证的插件路由天然就是管理员表面。如果你的路由需要仅管理员可用的行为,请要求使用携带身份的认证模式,并记录显式的 `x-openclaw-scopes` 请求头契约。 +- 除非设置 `replaceExisting: true`,否则完全相同的 `path + match` 冲突会被拒绝,而且一个插件不能替换另一个插件的路由。 +- 具有不同 `auth` 级别的重叠路由会被拒绝。仅在相同鉴权级别上保留 `exact`/`prefix` 的落空链。 +- `auth: "plugin"` 路由**不会**自动接收操作员运行时作用域。它们用于由插件管理的 Webhook/签名验证,而不是特权 Gateway 网关辅助调用。 +- `auth: "gateway"` 路由会在 Gateway 网关请求运行时作用域内执行,但该作用域是有意保守的: + - 共享密钥 bearer 鉴权(`gateway.auth.mode = "token"` / `"password"`)会将插件路由运行时作用域固定为 `operator.write`,即使调用方发送了 `x-openclaw-scopes` 也是如此 + - 受信任的、携带身份的 HTTP 模式(例如 `trusted-proxy`,或私有入口上的 `gateway.auth.mode = "none"`)只有在显式存在该请求头时,才会遵循 `x-openclaw-scopes` + - 如果这些携带身份的插件路由请求中缺少 `x-openclaw-scopes`,运行时作用域会回退为 `operator.write` +- 实用规则:不要假设启用了 gateway 鉴权的插件路由就是隐式管理员表面。如果你的路由需要仅管理员可用的行为,请要求使用携带身份的鉴权模式,并记录显式 `x-openclaw-scopes` 请求头契约。 ## 插件 SDK 导入路径 -在编写新插件时,请使用更窄的 SDK 子路径,而不是单体的 `openclaw/plugin-sdk` 根 barrel。核心子路径包括: +编写新插件时,请使用狭窄的 SDK 子路径,而不是单体的 `openclaw/plugin-sdk` 根 barrel。核心子路径包括: | 子路径 | 用途 | | ----------------------------------- | -------------------------------------------------- | | `openclaw/plugin-sdk/plugin-entry` | 插件注册原语 | -| `openclaw/plugin-sdk/channel-core` | 渠道入口 / 构建辅助工具 | +| `openclaw/plugin-sdk/channel-core` | 渠道入口/构建辅助工具 | | `openclaw/plugin-sdk/core` | 通用共享辅助工具和总括契约 | | `openclaw/plugin-sdk/config-schema` | 根 `openclaw.json` Zod 模式(`OpenClawSchema`) | -渠道插件可从一组更窄的接缝中选择——`channel-setup`、`setup-runtime`、`setup-adapter-runtime`、`setup-tools`、`channel-pairing`、`channel-contract`、`channel-feedback`、`channel-inbound`、`channel-lifecycle`、`channel-reply-pipeline`、`command-auth`、`secret-input`、`webhook-ingress`、`channel-targets` 和 `channel-actions`。审批行为应统一到一个 `approvalCapability` 契约上,而不是分散混用在不相关的插件字段之间。参见 [渠道插件](/zh-CN/plugins/sdk-channel-plugins)。 +渠道插件从一组狭窄接缝中进行选择——`channel-setup`、 +`setup-runtime`、`setup-adapter-runtime`、`setup-tools`、`channel-pairing`、 +`channel-contract`、`channel-feedback`、`channel-inbound`、`channel-lifecycle`、 +`channel-reply-pipeline`、`command-auth`、`secret-input`、`webhook-ingress`、 +`channel-targets` 和 `channel-actions`。审批行为应统一收敛到一个 +`approvalCapability` 契约,而不是混杂在互不相关的插件字段之间。 +请参阅 [渠道插件](/zh-CN/plugins/sdk-channel-plugins)。 -运行时和配置辅助工具位于对应的 `*-runtime` 子路径下(`approval-runtime`、`config-runtime`、`infra-runtime`、`agent-runtime`、`lazy-runtime`、`directory-runtime`、`text-runtime`、`runtime-store` 等)。 +运行时和配置辅助工具位于对应的 `*-runtime` 子路径下 +(`approval-runtime`、`config-runtime`、`infra-runtime`、`agent-runtime`、 +`lazy-runtime`、`directory-runtime`、`text-runtime`、`runtime-store` 等)。 -`openclaw/plugin-sdk/channel-runtime` 已弃用——这是为旧版插件保留的兼容性 shim。新代码应改为导入更窄的通用原语。 +`openclaw/plugin-sdk/channel-runtime` 已弃用——它是为旧版插件提供的兼容性 shim。 +新代码应改为导入更狭窄的通用原语。 -仓库内部入口点(按每个内置插件的软件包根目录划分): +仓库内部入口点(按每个内置插件软件包根目录划分): - `index.js` —— 内置插件入口 -- `api.js` —— 辅助工具 / 类型 barrel +- `api.js` —— 辅助工具/类型 barrel - `runtime-api.js` —— 仅运行时 barrel - `setup-entry.js` —— 设置插件入口 -外部插件应只导入 `openclaw/plugin-sdk/*` 子路径。绝不要从核心或其他插件中导入另一个插件包的 `src/*`。由 facade 加载的入口点会优先使用当前活动的运行时配置快照;如果不存在,则回退到磁盘上已解析的配置文件。 +外部插件只能导入 `openclaw/plugin-sdk/*` 子路径。绝不要从核心或另一个插件中导入其他插件软件包的 `src/*`。 +由 facade 加载的入口点会优先使用当前活动的运行时配置快照;如果不存在,再回退到磁盘上的已解析配置文件。 -诸如 `image-generation`、`media-understanding` 和 `speech` 之类的能力专用子路径之所以存在,是因为内置插件目前正在使用它们。它们并不自动构成长期冻结的外部契约——在依赖它们时,请查阅相关的 SDK 参考页面。 +像 `image-generation`、`media-understanding` 和 `speech` 这样的能力专用子路径之所以存在,是因为当前内置插件正在使用它们。它们并不自动构成长期冻结的外部契约——在依赖它们之前,请查阅相关 SDK 参考页面。 ## 消息工具模式 -对于反应、已读和投票等非消息原语,插件应自行拥有渠道特定的 `describeMessageTool(...)` 模式贡献。共享发送展示应使用通用 `MessagePresentation` 契约,而不是提供商原生的按钮、组件、块或卡片字段。有关该契约、回退规则、提供商映射和插件作者检查清单,请参见 [Message Presentation](/zh-CN/plugins/message-presentation)。 +对于反应、已读和投票等非消息原语,插件应拥有特定于渠道的 `describeMessageTool(...)` 模式贡献。 +共享发送展示应使用通用 `MessagePresentation` 契约,而不是提供商原生的按钮、组件、块或卡片字段。 +关于该契约、回退规则、提供商映射以及插件作者检查清单,请参阅 [消息展示](/zh-CN/plugins/message-presentation)。 -具备发送能力的插件通过消息能力声明自己能渲染的内容: +支持发送的插件通过消息能力声明自己能渲染什么: - `presentation` 用于语义展示块(`text`、`context`、`divider`、`buttons`、`select`) - `delivery-pin` 用于置顶投递请求 -核心决定是原生渲染该展示,还是将其降级为文本。不要从通用消息工具中暴露提供商原生 UI 逃生口。为旧版原生模式保留的已弃用 SDK 辅助工具仍然会为现有第三方插件导出,但新插件不应再使用它们。 +核心会决定是原生渲染该展示,还是将其降级为文本。 +不要从通用消息工具中暴露提供商原生 UI 逃生口。 +面向旧版原生模式的已弃用 SDK 辅助工具仍会导出,以支持现有第三方插件,但新插件不应使用它们。 ## 渠道目标解析 -渠道插件应自行拥有渠道特定的目标语义。请保持共享出站宿主通用,并使用消息适配器表面承载提供商规则: +渠道插件应拥有渠道特定的目标语义。保持共享出站宿主通用,并使用消息适配器表面来承载提供商规则: -- `messaging.inferTargetChatType({ to })` 决定规范化目标在目录查找前应被视为 `direct`、`group` 还是 `channel`。 -- `messaging.targetResolver.looksLikeId(raw, normalized)` 告诉核心某个输入是否应跳过目录搜索,直接进入类似 id 的解析。 -- `messaging.targetResolver.resolveTarget(...)` 是插件回退路径,用于核心在规范化之后或目录未命中之后需要最终的提供商自有解析时使用。 -- `messaging.resolveOutboundSessionRoute(...)` 在目标解析完成后接管提供商特定的会话路由构建。 +- `messaging.inferTargetChatType({ to })` 用于在目录查找之前决定规范化目标应被视为 `direct`、`group` 还是 `channel`。 +- `messaging.targetResolver.looksLikeId(raw, normalized)` 用于告诉核心,某个输入是否应跳过目录搜索,直接进入类似 id 的解析。 +- `messaging.targetResolver.resolveTarget(...)` 是插件回退路径,当核心在规范化之后或目录未命中之后需要最终由提供商拥有的解析时使用。 +- `messaging.resolveOutboundSessionRoute(...)` 在目标解析完成后,负责构造提供商特定的会话路由。 -推荐拆分方式: +建议的拆分方式: -- 对于应在搜索联系人 / 群组前作出的类别判断,使用 `inferTargetChatType`。 -- 对于“将其视为显式 / 原生目标 id”的判断,使用 `looksLikeId`。 -- 对于提供商特定的规范化回退,而非广义目录搜索,使用 `resolveTarget`。 -- 将聊天 id、线程 id、JID、handle 和 room id 等提供商原生 id 保留在 `target` 值或提供商特定参数中,而不要放进通用 SDK 字段。 +- 对于应在搜索 peers/groups 之前进行的分类决策,使用 `inferTargetChatType`。 +- 对于“将此视为显式/原生目标 id”的检查,使用 `looksLikeId`。 +- 对于提供商特定的规范化回退,使用 `resolveTarget`,不要将其用于宽泛的目录搜索。 +- 将 chat id、thread id、JID、handle 和 room id 等提供商原生 id 保留在 `target` 值或提供商特定参数中,而不要放入通用 SDK 字段。 ## 基于配置的目录 -从配置派生目录条目的插件应将该逻辑保留在插件内部,并复用 `openclaw/plugin-sdk/directory-runtime` 中的共享辅助工具。 +如果插件从配置中派生目录条目,应将该逻辑保留在插件中,并复用 +`openclaw/plugin-sdk/directory-runtime` +中的共享辅助工具。 -当某个渠道需要基于配置的联系人 / 群组时,请使用这一方式,例如: +适用于渠道需要基于配置的 peers/groups 的情况,例如: -- 基于 allowlist 的私信联系人 -- 已配置的渠道 / 群组映射 -- 按账户范围划分的静态目录回退 +- 基于 allowlist 的私信 peers +- 已配置的渠道/群组映射 +- 按账户作用域划分的静态目录回退 `directory-runtime` 中的共享辅助工具只处理通用操作: - 查询过滤 -- 应用限制 -- 去重 / 规范化辅助工具 +- 限制应用 +- 去重/规范化辅助工具 - 构建 `ChannelDirectoryEntry[]` 渠道特定的账户检查和 id 规范化应保留在插件实现中。 ## 提供商目录 -提供商插件可通过 `registerProvider({ catalog: { run(...) { ... } } })` 为推理定义模型目录。 +提供商插件可以通过 +`registerProvider({ catalog: { run(...) { ... } } })` +为推理定义模型目录。 -`catalog.run(...)` 返回与 OpenClaw 写入 `models.providers` 相同的结构: +`catalog.run(...)` 返回与 OpenClaw 写入 +`models.providers` +时相同的形状: -- `{ provider }` 表示一个提供商条目 +- `{ provider }` 表示单个提供商条目 - `{ providers }` 表示多个提供商条目 -当插件拥有提供商特定的模型 id、base URL 默认值或受认证控制的模型元数据时,请使用 `catalog`。 +当插件拥有提供商特定的模型 id、基础 URL 默认值或受鉴权限制的模型元数据时,请使用 `catalog`。 `catalog.order` 控制插件目录相对于 OpenClaw 内置隐式提供商的合并时机: -- `simple`:普通 API 密钥或环境变量驱动的提供商 -- `profile`:当存在认证配置文件时出现的提供商 +- `simple`:纯 API 密钥或由环境变量驱动的提供商 +- `profile`:存在鉴权配置文件时出现的提供商 - `paired`:合成多个相关提供商条目的提供商 - `late`:最后一轮,在其他隐式提供商之后 -发生键冲突时,后出现的提供商会胜出,因此插件可以有意用相同的提供商 id 覆盖内置提供商条目。 +发生键冲突时,后面的提供商会胜出,因此插件可以有意用相同的提供商 id 覆盖内置提供商条目。 -兼容性: +兼容性说明: -- `discovery` 仍然可作为旧别名使用 +- `discovery` 仍可作为旧别名使用 - 如果同时注册了 `catalog` 和 `discovery`,OpenClaw 会使用 `catalog` ## 只读渠道检查 -如果你的插件注册了一个渠道,请优先实现 `plugin.config.inspectAccount(cfg, accountId)`,并与 `resolveAccount(...)` 一起提供。 +如果你的插件注册了一个渠道,除了 `resolveAccount(...)` 之外,优先实现 +`plugin.config.inspectAccount(cfg, accountId)`。 原因: -- `resolveAccount(...)` 是运行时路径。它可以假定凭证已经完全具体化,并且在缺少必要密钥时快速失败。 -- 只读命令路径,如 `openclaw status`、`openclaw status --all`、`openclaw channels status`、`openclaw channels resolve` 以及 doctor / 配置修复流程,不应为了描述配置而必须具体化运行时凭证。 +- `resolveAccount(...)` 是运行时路径。它可以假定凭证已经完全实体化,并且在缺少必需 secret 时快速失败。 +- 像 `openclaw status`、`openclaw status --all`、 + `openclaw channels status`、`openclaw channels resolve` 以及 Doctor/配置修复流程这样的只读命令路径,不应该为了描述配置而必须实体化运行时凭证。 推荐的 `inspectAccount(...)` 行为: - 只返回描述性的账户状态。 - 保留 `enabled` 和 `configured`。 -- 在相关时包含凭证来源 / 状态字段,例如: +- 在相关时包含凭证来源/状态字段,例如: - `tokenSource`、`tokenStatus` - `botTokenSource`、`botTokenStatus` - `appTokenSource`、`appTokenStatus` - `signingSecretSource`、`signingSecretStatus` -- 你不需要为了报告只读可用性而返回原始令牌值。返回 `tokenStatus: "available"`(以及对应的来源字段)就足以支持状态类命令。 -- 当某个凭证通过 SecretRef 配置,但在当前命令路径中不可用时,请使用 `configured_unavailable`。 +- 你不需要为了报告只读可用性而返回原始令牌值。返回 `tokenStatus: "available"`(以及匹配的来源字段)就足以支持状态类命令。 +- 当凭证通过 `SecretRef` 配置,但在当前命令路径中不可用时,请使用 `configured_unavailable`。 -这样,只读命令就能报告“已配置,但在当前命令路径中不可用”,而不是崩溃或错误地将该账户报告为未配置。 +这样可以让只读命令报告“已配置,但在此命令路径中不可用”,而不是崩溃或错误地将账户报告为未配置。 -## 软件包打包方案 +## 软件包打包 -插件目录可以包含带有 `openclaw.extensions` 的 `package.json`: +插件目录可以包含一个带有 `openclaw.extensions` 的 `package.json`: ```json { @@ -623,37 +664,49 @@ api.registerHttpRoute({ } ``` -每个条目都会变成一个插件。如果该 pack 列出了多个扩展,插件 id 会变成 `name/`。 +每个条目都会变成一个插件。如果这个 pack 列出了多个扩展,插件 id +会变成 `name/`。 -如果你的插件导入了 npm 依赖,请在该目录中安装它们,以便 `node_modules` 可用(`npm install` / `pnpm install`)。 +如果你的插件导入了 npm 依赖,请在该目录中安装它们,以便 +`node_modules` +可用(`npm install` / `pnpm install`)。 安全护栏:每个 `openclaw.extensions` 条目在解析符号链接后都必须保持在插件目录内。逃逸出软件包目录的条目会被拒绝。 -安全说明:`openclaw plugins install` 会通过 `npm install --omit=dev --ignore-scripts` 安装插件依赖(无生命周期脚本,运行时无开发依赖)。请保持插件依赖树为“纯 JS/TS”,并避免使用需要 `postinstall` 构建的软件包。 +安全说明:`openclaw plugins install` 会使用 +`npm install --omit=dev --ignore-scripts` +安装插件依赖(无生命周期脚本,运行时无开发依赖)。请保持插件依赖树为“纯 JS/TS”,并避免使用需要 `postinstall` 构建的软件包。 -可选项:`openclaw.setupEntry` 可以指向一个轻量级、仅用于设置的模块。当 OpenClaw 需要为已禁用的渠道插件提供设置表面,或某个渠道插件已启用但尚未配置时,它会加载 `setupEntry`,而不是完整插件入口。这样在你的主插件入口还会接入工具、钩子或其他仅运行时代码时,就能让启动和设置更轻量。 +可选:`openclaw.setupEntry` 可以指向一个轻量级、仅用于设置的模块。 +当 OpenClaw 需要为一个已禁用的渠道插件提供设置表面时,或者当一个渠道插件已启用但尚未配置时,它会加载 `setupEntry`,而不是完整的插件入口。 +当主插件入口还会接线工具、钩子或其他仅运行时代码时,这样可以让启动和设置更轻量。 -可选项:`openclaw.startup.deferConfiguredChannelFullLoadUntilAfterListen` 可让渠道插件在 Gateway 网关的 pre-listen 启动阶段选择使用相同的 `setupEntry` 路径,即使该渠道已经配置完成。 +可选:`openclaw.startup.deferConfiguredChannelFullLoadUntilAfterListen` +可以让渠道插件在 Gateway 网关的 pre-listen 启动阶段,即使渠道已经配置好,也选择加入相同的 `setupEntry` 路径。 -只有在 `setupEntry` 能完全覆盖 Gateway 网关开始监听前必须存在的启动表面时,才应使用此选项。实际来说,这意味着设置入口必须注册启动所依赖的每一项渠道自有能力,例如: +只有当 `setupEntry` 完全覆盖了 Gateway 网关开始监听之前必须存在的启动表面时,才应使用此功能。实际上,这意味着设置入口必须注册启动所依赖的每一项渠道拥有能力,例如: - 渠道注册本身 -- 任何必须在 Gateway 网关开始监听前就可用的 HTTP 路由 -- 任何必须在同一时间窗口内存在的 Gateway 网关方法、工具或服务 +- 任何必须在 Gateway 网关开始监听前可用的 HTTP 路由 +- 任何在同一时间窗口内必须存在的 Gateway 网关方法、工具或服务 -如果你的完整入口仍然拥有任何必需的启动能力,就不要启用这个标志。请保留默认行为,让 OpenClaw 在启动期间加载完整入口。 +如果你的完整入口仍然拥有任何必需的启动能力,请不要启用此标志。保持插件使用默认行为,并让 OpenClaw 在启动期间加载完整入口。 -内置渠道也可以发布仅设置用的契约表面辅助工具,以便核心在完整渠道运行时加载之前进行查询。当前的设置提升表面包括: +内置渠道还可以发布仅用于设置的契约表面辅助工具,供核心在完整渠道运行时加载前查询。当前的设置提升表面包括: - `singleAccountKeysToMove` - `namedAccountPromotionKeys` - `resolveSingleAccountPromotionTarget(...)` -当核心需要在不加载完整插件入口的情况下,将旧版单账户渠道配置提升为 `channels..accounts.*` 时,会使用该表面。Matrix 是当前的内置示例:当已存在命名账户时,它只会将认证 / 引导键移动到一个命名的提升账户中,并且可以保留已配置的非规范默认账户键,而不总是创建 `accounts.default`。 +当核心需要在不加载完整插件入口的情况下,将旧版单账户渠道配置提升到 +`channels..accounts.*` +时,会使用该表面。Matrix 是当前的内置示例:当命名账户已经存在时,它只会把鉴权/引导键迁移到一个已命名的提升账户中,并且它可以保留一个已配置的、非规范默认账户键,而不是总是创建 +`accounts.default`。 -这些设置补丁适配器使内置契约表面发现保持惰性。导入时间仍然较轻;提升表面只会在首次使用时加载,而不会在模块导入时重新进入内置渠道启动流程。 +这些设置补丁适配器让内置契约表面发现保持惰性。导入时保持轻量;提升表面只会在首次使用时加载,而不是在模块导入时重新进入内置渠道启动。 -当这些启动表面包含 Gateway 网关 RPC 方法时,请将它们保留在插件特定前缀下。核心管理命名空间(`config.*`、`exec.approvals.*`、`wizard.*`、`update.*`)仍然保留,并且始终解析为 `operator.admin`,即使某个插件请求了更窄的作用域也是如此。 +当这些启动表面包含 Gateway 网关 RPC 方法时,请将它们保留在插件特定前缀下。核心管理命名空间(`config.*`、 +`exec.approvals.*`、`wizard.*`、`update.*`)仍然保留,并且始终解析为 `operator.admin`,即使插件请求了更窄的作用域也是如此。 示例: @@ -672,7 +725,7 @@ api.registerHttpRoute({ ### 渠道目录元数据 -渠道插件可以通过 `openclaw.channel` 公布设置 / 发现元数据,并通过 `openclaw.install` 公布安装提示。这样可让核心目录保持无数据。 +渠道插件可以通过 `openclaw.channel` 宣传设置/发现元数据,并通过 `openclaw.install` 宣传安装提示。这样可以让核心目录保持无数据。 示例: @@ -687,7 +740,7 @@ api.registerHttpRoute({ "selectionLabel": "Nextcloud Talk(自托管)", "docsPath": "/channels/nextcloud-talk", "docsLabel": "nextcloud-talk", - "blurb": "通过 Nextcloud Talk webhook 机器人实现自托管聊天。", + "blurb": "通过 Nextcloud Talk webhook 机器人实现的自托管聊天。", "order": 65, "aliases": ["nc-talk", "nc"] }, @@ -700,38 +753,43 @@ api.registerHttpRoute({ } ``` -除了最小示例之外,有用的 `openclaw.channel` 字段还包括: +除最小示例外,其他有用的 `openclaw.channel` 字段包括: -- `detailLabel`:用于更丰富目录 / 状态表面的次级标签 +- `detailLabel`:用于更丰富目录/状态表面的次级标签 - `docsLabel`:覆盖文档链接的链接文本 -- `preferOver`:此目录项应优先于的低优先级插件 / 渠道 id -- `selectionDocsPrefix`、`selectionDocsOmitLabel`、`selectionExtras`:选择表面文案控制 +- `preferOver`:此目录条目应优先于的低优先级插件/渠道 id +- `selectionDocsPrefix`、`selectionDocsOmitLabel`、`selectionExtras`:选择表面文案控制项 - `markdownCapable`:将该渠道标记为支持 Markdown,以便用于出站格式决策 -- `exposure.configured`:当设置为 `false` 时,在已配置渠道列表表面中隐藏该渠道 -- `exposure.setup`:当设置为 `false` 时,在交互式设置 / 配置选择器中隐藏该渠道 -- `exposure.docs`:在文档导航表面中将该渠道标记为内部 / 私有 -- `showConfigured` / `showInSetup`:为兼容性仍接受的旧别名;优先使用 `exposure` +- `exposure.configured`:设为 `false` 时,在已配置渠道列表表面中隐藏该渠道 +- `exposure.setup`:设为 `false` 时,在交互式设置/配置选择器中隐藏该渠道 +- `exposure.docs`:将该渠道标记为内部/私有,用于文档导航表面 +- `showConfigured` / `showInSetup`:仍可接受的旧别名,仅用于兼容;优先使用 `exposure` - `quickstartAllowFrom`:让该渠道选择加入标准快速开始 `allowFrom` 流程 - `forceAccountBinding`:即使只存在一个账户,也要求显式账户绑定 - `preferSessionLookupForAnnounceTarget`:在解析公告目标时优先使用会话查找 -OpenClaw 还可以合并**外部渠道目录**(例如 MPM 注册表导出)。将 JSON 文件放在以下任一位置: +OpenClaw 还可以合并**外部渠道目录**(例如 MPM +注册表导出)。将一个 JSON 文件放到以下任一位置: - `~/.openclaw/mpm/plugins.json` - `~/.openclaw/mpm/catalog.json` - `~/.openclaw/plugins/catalog.json` -或者将 `OPENCLAW_PLUGIN_CATALOG_PATHS`(或 `OPENCLAW_MPM_CATALOG_PATHS`)指向一个或多个 JSON 文件(以逗号 / 分号 / `PATH` 分隔)。每个文件应包含 `{ "entries": [ { "name": "@scope/pkg", "openclaw": { "channel": {...}, "install": {...} } } ] }`。解析器还接受 `"packages"` 或 `"plugins"` 作为 `"entries"` 键的旧别名。 +或者将 `OPENCLAW_PLUGIN_CATALOG_PATHS`(或 `OPENCLAW_MPM_CATALOG_PATHS`)指向一个或多个 JSON 文件(用逗号/分号/`PATH` 分隔)。每个文件应包含 `{ "entries": [ { "name": "@scope/pkg", "openclaw": { "channel": {...}, "install": {...} } } ] }`。解析器也接受将 `"packages"` 或 `"plugins"` 作为 `"entries"` 键的旧别名。 -生成的渠道目录项和提供商安装目录项会在原始 `openclaw.install` 块旁边暴露规范化后的安装源信息。规范化信息会标识 npm 规格是精确版本还是浮动选择器、是否存在预期完整性元数据,以及本地源路径是否也可用。当已知目录 / 软件包标识时,如果解析出的 npm 软件包名偏离该标识,规范化信息会发出警告。它们还会在 `defaultChoice` 无效、指向不可用源,或者存在 npm 完整性元数据但缺少有效 npm 源时发出警告。消费者应将 `installSource` 视为附加的可选字段,这样较旧的手工构建条目和兼容性 shim 就不必合成它。这使新手引导和诊断能够在不导入插件运行时的情况下解释源平面状态。 +生成的渠道目录条目和提供商安装目录条目会在原始 `openclaw.install` 区块旁边暴露规范化后的安装源事实。规范化事实会标识 npm 规范是否为精确版本或浮动选择器、是否存在预期的完整性元数据,以及本地源路径是否也可用。当目录/软件包标识已知时,规范化事实会在解析出的 npm 软件包名称偏离该标识时发出警告。它们还会在 `defaultChoice` 无效或指向不可用源时发出警告,以及在存在 npm 完整性元数据但没有有效 npm 源时发出警告。消费者应将 `installSource` 视为一个可选的增量字段,这样较旧的手工构建条目和兼容性 shim 就不必合成它。这使得新手引导和诊断可以在不导入插件运行时的情况下解释源平面状态。 -官方外部 npm 条目应优先使用精确的 `npmSpec` 加上 `expectedIntegrity`。裸软件包名称和 dist-tag 出于兼容性仍然可用,但它们会暴露源平面警告,从而让目录可以逐步转向固定版本、带完整性校验的安装,而不会破坏现有插件。当新手引导从本地目录路径安装时,它会记录一条 `plugins.installs` 条目,并在可能时使用 `source: "path"` 和相对于工作区的 `sourcePath`。绝对的运行加载路径仍保留在 `plugins.load.paths` 中;安装记录会避免将本地工作站路径重复写入长期配置。这样可以让本地开发安装对源平面诊断可见,而无需增加第二个原始文件系统路径暴露表面。 +官方外部 npm 条目应优先使用精确的 `npmSpec` 加上 +`expectedIntegrity`。裸软件包名称和 dist-tag 仍可出于兼容性而继续工作,但它们会暴露源平面警告,使目录可以朝着固定版本、带完整性校验的安装方式演进,而不破坏现有插件。当新手引导从本地目录路径安装时,它会在 `plugins.installs` 中记录一个 `source: "path"` 的条目,并在可能时记录工作区相对的 `sourcePath`。绝对的实际加载路径仍保留在 `plugins.load.paths` 中;安装记录会避免将本地工作站路径重复写入长期配置。这让本地开发安装对源平面诊断可见,而不会增加第二个原始文件系统路径暴露表面。 ## 上下文引擎插件 -上下文引擎插件负责会话上下文的摄取、组装和压缩编排。通过 `api.registerContextEngine(id, factory)` 从你的插件中注册它们,然后使用 `plugins.slots.contextEngine` 选择活动引擎。 +上下文引擎插件负责会话上下文编排,包括摄取、组装和压缩。在你的插件中通过 +`api.registerContextEngine(id, factory)` 注册它们,然后使用 +`plugins.slots.contextEngine` +选择活动引擎。 -当你的插件需要替换或扩展默认上下文流水线,而不仅仅是添加内存搜索或钩子时,请使用这种方式。 +当你的插件需要替换或扩展默认上下文流水线,而不是仅仅添加 memory 搜索或钩子时,请使用这种方式。 ```ts import { buildMemorySystemPromptAddition } from "openclaw/plugin-sdk/core"; @@ -759,7 +817,8 @@ export default function (api) { } ``` -如果你的引擎**不**拥有压缩算法,请保持 `compact()` 已实现并显式委托: +如果你的引擎**不**拥有压缩算法,请保留 `compact()` +实现,并显式委托给它: ```ts import { @@ -794,39 +853,42 @@ export default function (api) { } ``` -## 添加新能力 +## 添加新的能力 -当插件需要当前 API 无法适配的行为时,不要通过私有深入访问来绕过插件系统。应添加缺失的能力。 +当插件需要当前 API 无法适配的行为时,不要通过私有深入访问绕过插件系统。应添加缺失的能力。 推荐顺序: 1. 定义核心契约 - 决定哪些共享行为应由核心负责:策略、回退、配置合并、生命周期、面向渠道的语义以及运行时辅助工具形态。 -2. 添加类型化的插件注册 / 运行时表面 - 使用最小但有用的类型化能力表面扩展 `OpenClawPluginApi` 和 / 或 `api.runtime`。 -3. 连接核心 + 渠道 / 功能消费者 - 渠道和功能插件应通过核心消费该新能力,而不是直接导入某个厂商实现。 + 决定核心应拥有哪些共享行为:策略、回退、配置合并、 + 生命周期、面向渠道的语义以及运行时辅助工具形状。 +2. 添加带类型的插件注册/运行时表面 + 以最小但有用的带类型能力表面扩展 `OpenClawPluginApi` + 和/或 `api.runtime`。 +3. 接线核心 + 渠道/功能消费者 + 渠道和功能插件应通过核心消费新能力, + 而不是直接导入某个厂商实现。 4. 注册厂商实现 - 然后由厂商插件针对该能力注册它们的后端实现。 + 然后由厂商插件针对该能力注册它们的后端。 5. 添加契约覆盖 - 添加测试,以便随着时间推移,所有权和注册形态仍保持明确。 + 添加测试,以便随着时间推移,所有权和注册形状仍保持明确。 -这就是 OpenClaw 在保持明确主张的同时,不会被硬编码到某个提供商世界观中的方式。有关具体文件检查清单和完整示例,请参见[能力扩展手册](/zh-CN/plugins/architecture)。 +这就是 OpenClaw 保持鲜明设计立场、又不会被某个提供商的世界观硬编码的方式。请参阅 [能力扩展手册](/zh-CN/plugins/architecture),其中包含具体的文件检查清单和完整示例。 ### 能力检查清单 -当你添加一个新能力时,实现通常应同时覆盖以下表面: +当你添加一个新能力时,通常应同时涉及这些表面: - `src//types.ts` 中的核心契约类型 -- `src//runtime.ts` 中的核心运行器 / 运行时辅助工具 +- `src//runtime.ts` 中的核心运行器/运行时辅助工具 - `src/plugins/types.ts` 中的插件 API 注册表面 - `src/plugins/registry.ts` 中的插件注册表接线 -- 当功能 / 渠道插件需要消费它时,位于 `src/plugins/runtime/*` 中的插件运行时暴露 -- `src/test-utils/plugin-registration.ts` 中的捕获 / 测试辅助工具 -- `src/plugins/contracts/registry.ts` 中的所有权 / 契约断言 -- `docs/` 中面向运维人员 / 插件的文档 +- 当功能/渠道插件需要消费它时,`src/plugins/runtime/*` 中的插件运行时暴露 +- `src/test-utils/plugin-registration.ts` 中的捕获/测试辅助工具 +- `src/plugins/contracts/registry.ts` 中的所有权/契约断言 +- `docs/` 中面向操作员/插件的文档 -如果这些表面中缺少某一项,通常说明该能力尚未完全集成。 +如果其中某个表面缺失,通常说明该能力尚未完全集成。 ### 能力模板 @@ -862,16 +924,16 @@ const clip = await api.runtime.videoGeneration.generate({ expect(findVideoGenerationProviderIdsForPlugin("openai")).toEqual(["openai"]); ``` -这使规则保持简单: +这样规则就保持简单: - 核心拥有能力契约 + 编排 - 厂商插件拥有厂商实现 -- 功能 / 渠道插件消费运行时辅助工具 -- 契约测试使所有权保持明确 +- 功能/渠道插件消费运行时辅助工具 +- 契约测试保持所有权明确 ## 相关内容 -- [插件架构](/zh-CN/plugins/architecture) —— 公开能力模型和形态 +- [插件架构](/zh-CN/plugins/architecture) —— 公开的能力模型和形状 - [插件 SDK 子路径](/zh-CN/plugins/sdk-subpaths) - [插件 SDK 设置](/zh-CN/plugins/sdk-setup) - [构建插件](/zh-CN/plugins/building-plugins) diff --git a/docs/zh-CN/plugins/hooks.md b/docs/zh-CN/plugins/hooks.md index fb2f6e7e6..857c2bcf3 100644 --- a/docs/zh-CN/plugins/hooks.md +++ b/docs/zh-CN/plugins/hooks.md @@ -1,26 +1,26 @@ --- read_when: - - 你正在构建一个插件,需要 `before_tool_call`、`before_agent_reply`、消息钩子或生命周期钩子 - - 你需要从插件中阻止、重写或要求批准工具调用 + - 你正在构建一个插件,它需要 `before_tool_call`、`before_agent_reply`、消息钩子或生命周期钩子 + - 你需要从插件中拦截、改写或要求批准工具调用 - 你正在内部钩子和插件钩子之间做选择 summary: 插件钩子:拦截智能体、工具、消息、会话以及 Gateway 网关生命周期事件 title: 插件钩子 x-i18n: - generated_at: "2026-04-24T18:41:24Z" + generated_at: "2026-04-24T20:10:22Z" model: gpt-5.4 provider: openai - source_hash: 122060cc36dd0ef0be4dbc6bab629742142543ba718fccd7f5a75885e73d43e1 + source_hash: e880a8eb3b69e67450ddedd40e0356645e0cbd1825d8846a069d972b7e0c858c source_path: plugins/hooks.md workflow: 15 --- -插件钩子是 OpenClaw 插件的进程内扩展点。当插件需要检查或更改智能体运行、工具调用、消息流、会话生命周期、子智能体路由、安装过程或 Gateway 网关启动时,请使用它们。 +插件钩子是 OpenClaw 插件的进程内扩展点。当插件需要检查或更改智能体运行、工具调用、消息流、会话生命周期、子智能体路由、安装流程或 Gateway 网关启动时,请使用它们。 -如果你想要一个由运维人员安装的、用于命令和 Gateway 网关事件(例如 `/new`、`/reset`、`/stop`、`agent:bootstrap` 或 `gateway:startup`)的小型 `HOOK.md` 脚本,请改用 [内部钩子](/zh-CN/automation/hooks)。 +如果你想要一个由操作员安装的轻量 `HOOK.md` 脚本来处理命令和 Gateway 网关事件,例如 `/new`、`/reset`、`/stop`、`agent:bootstrap` 或 `gateway:startup`,请改用 [内部钩子](/zh-CN/automation/hooks)。 ## 快速开始 -在你的插件入口中,使用 `api.on(...)` 注册带类型的插件钩子: +在你的插件入口中使用 `api.on(...)` 注册带类型的插件钩子: ```typescript import { definePluginEntry } from "openclaw/plugin-sdk/plugin-entry"; @@ -52,45 +52,45 @@ export default definePluginEntry({ }); ``` -钩子处理程序会按 `priority` 降序依次运行。同一优先级的钩子会保持注册顺序。 +钩子处理器会按照 `priority` 的降序依次运行。同一优先级的钩子会保持注册顺序。 ## 钩子目录 -钩子按其扩展的表面进行分组。**粗体** 标出的名称接受决策结果(阻止、取消、覆盖或要求批准);其余都仅用于观察。 +钩子按其扩展的功能面分组。以 **粗体** 标出的名称接受决策结果(阻止、取消、覆盖或要求批准);其余钩子仅用于观察。 **智能体轮次** - `before_model_resolve` — 在加载会话消息之前覆盖提供商或模型 -- `before_prompt_build` — 在模型调用之前添加动态上下文或 system prompt 文本 -- `before_agent_start` — 仅用于兼容性的组合阶段;优先使用上面的两个钩子 +- `before_prompt_build` — 在模型调用之前添加动态上下文或系统提示文本 +- `before_agent_start` — 仅用于兼容性的合并阶段;优先使用上面的两个钩子 - **`before_agent_reply`** — 使用合成回复或静默来短路模型轮次 - `agent_end` — 观察最终消息、成功状态和运行时长 -**会话观察** +**对话观察** -- `llm_input` — 观察提供商输入(system prompt、prompt、历史记录) +- `llm_input` — 观察提供商输入(系统提示、提示词、历史记录) - `llm_output` — 观察提供商输出 **工具** - **`before_tool_call`** — 重写工具参数、阻止执行或要求批准 - `after_tool_call` — 观察工具结果、错误和耗时 -- **`tool_result_persist`** — 重写由工具结果生成的助手消息 -- **`before_message_write`** — 检查或阻止进行中的消息写入(较少见) +- **`tool_result_persist`** — 重写根据工具结果生成的助手消息 +- **`before_message_write`** — 检查或阻止进行中的消息写入(少见) **消息与投递** -- **`inbound_claim`** — 在智能体路由之前认领入站消息(合成回复) +- **`inbound_claim`** — 在智能体路由之前声明一条入站消息(合成回复) - `message_received` — 观察入站内容、发送者、线程和元数据 - **`message_sending`** — 重写出站内容或取消投递 - `message_sent` — 观察出站投递成功或失败 -- **`before_dispatch`** — 在交给渠道之前检查或重写出站分发 -- **`reply_dispatch`** — 参与最终的回复分发流水线 +- **`before_dispatch`** — 在交给渠道之前检查或重写一条出站分发 +- **`reply_dispatch`** — 参与最终回复分发流水线 **会话与压缩** - `session_start` / `session_end` — 跟踪会话生命周期边界 -- `before_compaction` / `after_compaction` — 观察或注释压缩周期 +- `before_compaction` / `after_compaction` — 观察或标注压缩周期 - `before_reset` — 观察会话重置事件(`/reset`、程序化重置) **子智能体** @@ -99,8 +99,8 @@ export default definePluginEntry({ **生命周期** -- `gateway_start` / `gateway_stop` — 随 Gateway 网关启动或停止插件拥有的服务 -- **`before_install`** — 检查 Skills 或插件安装扫描,并可选择阻止 +- `gateway_start` / `gateway_stop` — 随 Gateway 网关启动或停止由插件拥有的服务 +- **`before_install`** — 检查 Skills 或插件安装扫描,并可选择阻止安装 ## 工具调用策略 @@ -135,25 +135,25 @@ type BeforeToolCallResult = { 规则: -- `block: true` 是终止性的,并会跳过更低优先级的处理程序。 -- `block: false` 会被视为没有作出决定。 -- `params` 会重写执行时使用的工具参数。 -- `requireApproval` 会暂停智能体运行,并通过插件批准机制向用户发起请求。`/approve` 命令既可以批准 exec 批准,也可以批准插件批准。 -- 即使更高优先级的钩子请求了批准,更低优先级的 `block: true` 仍然可以阻止调用。 -- `onResolution` 会接收最终的批准决定——`allow-once`、`allow-always`、`deny`、`timeout` 或 `cancelled`。 +- `block: true` 是终止性的,并会跳过较低优先级的处理器。 +- `block: false` 会被视为未作出决策。 +- `params` 会重写用于执行的工具参数。 +- `requireApproval` 会暂停智能体运行,并通过插件批准机制向用户发起请求。`/approve` 命令既可批准 exec 批准,也可批准插件批准。 +- 即使较高优先级的钩子请求了批准,较低优先级的 `block: true` 仍然可以阻止执行。 +- `onResolution` 会接收已解析的批准决定——`allow-once`、`allow-always`、`deny`、`timeout` 或 `cancelled`。 -## Prompt 和模型钩子 +## 提示词与模型钩子 对于新插件,请使用按阶段划分的钩子: -- `before_model_resolve`:仅接收当前 prompt 和附件元数据。返回 `providerOverride` 或 `modelOverride`。 -- `before_prompt_build`:接收当前 prompt 和会话消息。返回 `prependContext`、`systemPrompt`、`prependSystemContext` 或 `appendSystemContext`。 +- `before_model_resolve`:只接收当前提示词和附件元数据。返回 `providerOverride` 或 `modelOverride`。 +- `before_prompt_build`:接收当前提示词和会话消息。返回 `prependContext`、`systemPrompt`、`prependSystemContext` 或 `appendSystemContext`。 -`before_agent_start` 仍然保留用于兼容性。优先使用上面的显式钩子,这样你的插件就不会依赖旧版的组合阶段。 +`before_agent_start` 仍然保留用于兼容性。优先使用上面的显式钩子,这样你的插件就不会依赖旧版合并阶段。 -当 OpenClaw 能识别当前活跃运行时,`before_agent_start` 和 `agent_end` 会包含 `event.runId`。同一个值也可通过 `ctx.runId` 获取。 +当 OpenClaw 能识别当前活动运行时,`before_agent_start` 和 `agent_end` 会包含 `event.runId`。同一个值也可通过 `ctx.runId` 获取。 -需要使用 `llm_input`、`llm_output` 或 `agent_end` 的非内置插件必须设置: +需要 `llm_input`、`llm_output` 或 `agent_end` 的非内置插件必须设置: ```json { @@ -169,42 +169,52 @@ type BeforeToolCallResult = { } ``` -可变更 prompt 的钩子可以按插件禁用,方式是设置 `plugins.entries..hooks.allowPromptInjection=false`。 +可修改提示词的钩子可以按插件禁用,方式是设置 `plugins.entries..hooks.allowPromptInjection=false`。 ## 消息钩子 -将消息钩子用于渠道级路由和投递策略: +对渠道级路由和投递策略,请使用消息钩子: -- `message_received`:观察入站内容、发送者、`threadId`、`messageId`、`senderId`、可选的运行/会话关联信息,以及元数据。 +- `message_received`:观察入站内容、发送者、`threadId`、`messageId`、`senderId`、可选的运行/会话关联以及元数据。 - `message_sending`:重写 `content` 或返回 `{ cancel: true }`。 - `message_sent`:观察最终成功或失败。 -消息钩子上下文会在可用时公开稳定的关联字段: -`ctx.sessionKey`、`ctx.runId`、`ctx.messageId`、`ctx.senderId`、`ctx.trace`、 -`ctx.traceId`、`ctx.spanId`、`ctx.parentSpanId` 和 `ctx.callDepth`。在读取旧版元数据之前,优先使用这些一等字段。 +消息钩子的上下文会在可用时公开稳定的关联字段: +`ctx.sessionKey`、`ctx.runId`、`ctx.messageId`、`ctx.senderId`、`ctx.trace`、`ctx.traceId`、`ctx.spanId`、`ctx.parentSpanId` 和 `ctx.callDepth`。在读取旧版元数据之前,优先使用这些一等字段。 -在使用渠道特定元数据之前,优先使用带类型的 `threadId` 和 `replyToId` 字段。 +优先使用带类型的 `threadId` 和 `replyToId` 字段,而不是使用特定于渠道的元数据。 决策规则: - 带有 `cancel: true` 的 `message_sending` 是终止性的。 -- 带有 `cancel: false` 的 `message_sending` 会被视为没有作出决定。 -- 被重写的 `content` 会继续传递给更低优先级的钩子,除非后续钩子取消投递。 +- 带有 `cancel: false` 的 `message_sending` 会被视为未作出决策。 +- 被重写的 `content` 会继续传递给较低优先级的钩子,除非后续钩子取消投递。 ## 安装钩子 -`before_install` 会在内置的 Skills 和插件安装扫描之后运行。返回额外发现项,或返回 `{ block: true, blockReason }` 以停止安装。 +`before_install` 会在内置的 Skills 和插件安装扫描之后运行。返回额外发现项,或返回 `{ block: true, blockReason }` 来停止安装。 -`block: true` 是终止性的。`block: false` 会被视为没有作出决定。 +`block: true` 是终止性的。`block: false` 会被视为未作出决策。 ## Gateway 网关生命周期 -对需要 Gateway 网关拥有状态的插件服务,请使用 `gateway_start`。上下文会公开 `ctx.config`、`ctx.workspaceDir` 以及用于检查和更新 cron 的 `ctx.getCron?.()`。使用 `gateway_stop` 清理长时间运行的资源。 +对需要 Gateway 网关拥有状态的插件服务,请使用 `gateway_start`。上下文会公开 `ctx.config`、`ctx.workspaceDir` 和 `ctx.getCron?.()`,用于检查和更新 cron。使用 `gateway_stop` 清理长时间运行的资源。 -不要依赖内部的 `gateway:startup` 钩子来实现插件拥有的运行时服务。 +不要依赖内部的 `gateway:startup` 钩子来运行由插件拥有的运行时服务。 + +## 即将弃用的内容 + +有少量与钩子相邻的功能面已被弃用,但仍受支持。请在下一个主要版本发布之前完成迁移: + +- **`inbound_claim` 和 `message_received` 处理器中的纯文本渠道信封**。请读取 `BodyForAgent` 和结构化的用户上下文块,而不是解析扁平信封文本。参见 [纯文本渠道信封 → BodyForAgent](/zh-CN/plugins/sdk-migration#active-deprecations)。 +- **`before_agent_start`** 仍保留用于兼容性。新插件应使用 `before_model_resolve` 和 `before_prompt_build`,而不是合并阶段。 +- **`before_tool_call` 中的 `onResolution`** 现在使用带类型的 `PluginApprovalResolution` 联合类型(`allow-once` / `allow-always` / `deny` / `timeout` / `cancelled`),而不是自由形式的 `string`。 + +完整列表——包括 memory 能力注册、提供商 thinking 配置文件、外部身份验证提供商、提供商发现类型、任务运行时访问器,以及 `command-auth` → `command-status` 重命名——请参见 [插件 SDK 迁移 → 当前弃用项](/zh-CN/plugins/sdk-migration#active-deprecations)。 ## 相关内容 +- [Plugin SDK migration](/zh-CN/plugins/sdk-migration) — 当前弃用项和移除时间线 - [构建插件](/zh-CN/plugins/building-plugins) - [插件 SDK 概览](/zh-CN/plugins/sdk-overview) - [插件入口点](/zh-CN/plugins/sdk-entrypoints) diff --git a/docs/zh-CN/plugins/manifest.md b/docs/zh-CN/plugins/manifest.md index 450355c59..89d90d140 100644 --- a/docs/zh-CN/plugins/manifest.md +++ b/docs/zh-CN/plugins/manifest.md @@ -1,21 +1,21 @@ --- read_when: - 你正在构建一个 OpenClaw 插件 - - 你需要交付一个插件配置 schema,或调试插件验证错误 + - 你需要发布一个插件配置 schema,或调试插件验证错误 summary: 插件清单 + JSON schema 要求(严格配置验证) title: 插件清单 x-i18n: - generated_at: "2026-04-24T19:57:08Z" + generated_at: "2026-04-24T20:10:23Z" model: gpt-5.4 provider: openai - source_hash: c4eb13f5b90656d164736e0fed964e6e2f0c8af2cfc7e9788c888bc65be8f0cf + source_hash: ac25782f26abe79875c25abcd6f7b53fbe7a3c7b139c80c8a1a6675e69d6529c source_path: plugins/manifest.md workflow: 15 --- -本页仅适用于**原生 OpenClaw 插件清单**。 +此页面仅适用于**原生 OpenClaw 插件清单**。 -如需了解兼容的 bundle 布局,请参阅 [插件 bundle](/zh-CN/plugins/bundles)。 +有关兼容的 bundle 布局,请参阅 [Plugin bundles](/zh-CN/plugins/bundles)。 兼容的 bundle 格式使用不同的清单文件: @@ -23,31 +23,31 @@ x-i18n: - Claude bundle:`.claude-plugin/plugin.json`,或不带清单的默认 Claude 组件布局 - Cursor bundle:`.cursor-plugin/plugin.json` -OpenClaw 也会自动检测这些 bundle 布局,但它们不会按照此处描述的 `openclaw.plugin.json` schema 进行验证。 +OpenClaw 也会自动检测这些 bundle 布局,但不会根据此处描述的 `openclaw.plugin.json` schema 对其进行验证。 -对于兼容 bundle,OpenClaw 当前会在布局符合 OpenClaw 运行时预期时,读取 bundle 元数据,以及声明的 skill 根目录、Claude 命令根目录、Claude bundle `settings.json` 默认值、Claude bundle LSP 默认值和受支持的 hook pack。 +对于兼容 bundle,当前当其布局符合 OpenClaw 运行时预期时,OpenClaw 会读取 bundle 元数据,以及声明的 skill 根目录、Claude 命令根目录、Claude bundle `settings.json` 默认值、Claude bundle LSP 默认值和受支持的 hook pack。 每个原生 OpenClaw 插件**都必须**在**插件根目录**中提供一个 `openclaw.plugin.json` 文件。OpenClaw 使用此清单在**不执行插件代码的情况下**验证配置。缺失或无效的清单会被视为插件错误,并阻止配置验证。 -请参阅完整的插件系统指南:[插件](/zh-CN/tools/plugin)。 -有关原生能力模型和当前外部兼容性指南,请参阅: -[能力模型](/zh-CN/plugins/architecture#public-capability-model)。 +请参阅完整的插件系统指南:[Plugins](/zh-CN/tools/plugin)。 +有关原生能力模型和当前外部兼容性指引,请参阅: +[Capability model](/zh-CN/plugins/architecture#public-capability-model)。 ## 此文件的作用 -`openclaw.plugin.json` 是 OpenClaw 在**加载你的插件代码之前**读取的元数据。下面的所有内容都必须足够轻量,以便在不启动插件运行时的情况下完成检查。 +`openclaw.plugin.json` 是 OpenClaw 在**加载你的插件代码之前**读取的元数据。下面的所有内容都必须足够轻量,能够在不启动插件运行时的情况下进行检查。 -**用于:** +**请将它用于:** - 插件标识、配置验证和配置 UI 提示 -- 认证、新手引导和设置元数据(别名、自动启用、provider 环境变量、认证选项) -- control-plane 表面的激活提示 +- 凭证、onboarding 和设置元数据(别名、自动启用、提供商环境变量、凭证选项) +- 控制平面界面的激活提示 - 简写模型家族归属 - 静态能力归属快照(`contracts`) -- 供共享 `openclaw qa` 宿主检查的 QA 运行器元数据 -- 合并到 catalog 和验证表面的渠道专用配置元数据 +- 共享 `openclaw qa` 主机可检查的 QA 运行器元数据 +- 合并到目录和验证界面中的渠道专用配置元数据 -**不要用于:**注册运行时行为、声明代码入口点或 npm 安装元数据。这些应放在你的插件代码和 `package.json` 中。 +**不要将它用于:**注册运行时行为、声明代码入口点或 npm 安装元数据。这些应放在你的插件代码和 `package.json` 中。 ## 最小示例 @@ -96,19 +96,19 @@ OpenClaw 也会自动检测这些 bundle 布局,但它们不会按照此处描 "provider": "openrouter", "method": "api-key", "choiceId": "openrouter-api-key", - "choiceLabel": "OpenRouter API key", + "choiceLabel": "OpenRouter API 密钥", "groupId": "openrouter", "groupLabel": "OpenRouter", "optionKey": "openrouterApiKey", "cliFlag": "--openrouter-api-key", "cliOption": "--openrouter-api-key ", - "cliDescription": "OpenRouter API key", + "cliDescription": "OpenRouter API 密钥", "onboardingScopes": ["text-inference"] } ], "uiHints": { "apiKey": { - "label": "API key", + "label": "API 密钥", "placeholder": "sk-or-v1-...", "sensitive": true } @@ -127,66 +127,66 @@ OpenClaw 也会自动检测这些 bundle 布局,但它们不会按照此处描 ## 顶层字段参考 -| 字段 | 必填 | 类型 | 含义 | -| ------------------------------------ | -------- | -------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `id` | 是 | `string` | 规范插件 ID。这是在 `plugins.entries.` 中使用的 ID。 | -| `configSchema` | 是 | `object` | 此插件配置的内联 JSON Schema。 | -| `enabledByDefault` | 否 | `true` | 将内置插件标记为默认启用。省略此字段,或将其设置为任何非 `true` 的值,则插件默认保持禁用。 | -| `legacyPluginIds` | 否 | `string[]` | 会规范化为此规范插件 ID 的旧版 ID。 | -| `autoEnableWhenConfiguredProviders` | 否 | `string[]` | 当认证、配置或模型引用提到这些 provider ID 时,应自动启用此插件。 | -| `kind` | 否 | `"memory"` \| `"context-engine"` | 声明一个由 `plugins.slots.*` 使用的互斥插件类型。 | -| `channels` | 否 | `string[]` | 由此插件拥有的渠道 ID。用于设备发现和配置验证。 | -| `providers` | 否 | `string[]` | 由此插件拥有的 provider ID。 | -| `providerDiscoveryEntry` | 否 | `string` | 轻量级 provider 发现模块路径,相对于插件根目录,用于可在不激活完整插件运行时的情况下加载的、清单作用域的 provider catalog 元数据。 | -| `modelSupport` | 否 | `object` | 由清单拥有的简写模型家族元数据,用于在运行时之前自动加载插件。 | -| `providerEndpoints` | 否 | `object[]` | 由清单拥有的 endpoint host/baseUrl 元数据,用于 core 必须在 provider 运行时加载前分类的 provider 路由。 | -| `cliBackends` | 否 | `string[]` | 由此插件拥有的 CLI 推理后端 ID。用于根据显式配置引用在启动时自动激活。 | -| `syntheticAuthRefs` | 否 | `string[]` | provider 或 CLI 后端引用,在运行时加载前的冷模型发现期间,应探测其由插件拥有的 synthetic auth hook。 | -| `nonSecretAuthMarkers` | 否 | `string[]` | 由内置插件拥有的占位 API key 值,表示非密钥的本地、OAuth 或环境凭证状态。 | -| `commandAliases` | 否 | `object[]` | 由此插件拥有的命令名称,在运行时加载前应生成具备插件感知能力的配置和 CLI 诊断信息。 | -| `providerAuthEnvVars` | 否 | `Record` | OpenClaw 可在不加载插件代码的情况下检查的轻量 provider 认证环境变量元数据。 | -| `providerAuthAliases` | 否 | `Record` | 应复用另一个 provider ID 进行认证查找的 provider ID,例如共享基础 provider API key 和 auth profile 的 coding provider。 | -| `channelEnvVars` | 否 | `Record` | OpenClaw 可在不加载插件代码的情况下检查的轻量渠道环境变量元数据。对于由环境变量驱动的渠道设置或认证表面,请使用此字段,以便通用启动/配置辅助逻辑能够看到它们。 | -| `providerAuthChoices` | 否 | `object[]` | 用于新手引导选择器、首选 provider 解析和简单 CLI 标志接线的轻量认证选项元数据。 | -| `activation` | 否 | `object` | 用于 provider、命令、渠道、路由和能力触发加载的轻量激活规划器元数据。仅为元数据;实际行为仍由插件运行时拥有。 | -| `setup` | 否 | `object` | 轻量设置/新手引导描述符,供设备发现和设置表面在不加载插件运行时的情况下检查。 | -| `qaRunners` | 否 | `object[]` | 由共享 `openclaw qa` 宿主在插件运行时加载前使用的轻量 QA 运行器描述符。 | -| `contracts` | 否 | `object` | 外部 auth hook、speech、实时转录、实时语音、媒体理解、图像生成、音乐生成、视频生成、web-fetch、Web 搜索 和工具归属的静态内置能力快照。 | -| `mediaUnderstandingProviderMetadata` | 否 | `Record` | 为在 `contracts.mediaUnderstandingProviders` 中声明的 provider ID 提供的轻量媒体理解默认值。 | -| `channelConfigs` | 否 | `Record` | 由清单拥有的渠道配置元数据,会在运行时加载前合并到设备发现和验证表面中。 | -| `skills` | 否 | `string[]` | 要加载的 Skills 目录,相对于插件根目录。 | -| `name` | 否 | `string` | 人类可读的插件名称。 | -| `description` | 否 | `string` | 显示在插件表面中的简短摘要。 | -| `version` | 否 | `string` | 信息性插件版本。 | -| `uiHints` | 否 | `Record` | 配置字段的 UI 标签、占位符和敏感性提示。 | +| 字段 | 必填 | 类型 | 含义 | +| ------------------------------------ | ---- | -------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `id` | 是 | `string` | 规范插件 id。这是在 `plugins.entries.` 中使用的 id。 | +| `configSchema` | 是 | `object` | 该插件配置的内联 JSON Schema。 | +| `enabledByDefault` | 否 | `true` | 将内置插件标记为默认启用。省略此字段,或将其设置为任何非 `true` 的值,以保持插件默认禁用。 | +| `legacyPluginIds` | 否 | `string[]` | 会规范化为此规范插件 id 的旧版 id。 | +| `autoEnableWhenConfiguredProviders` | 否 | `string[]` | 当凭证、配置或模型引用提到这些提供商 id 时,应自动启用此插件。 | +| `kind` | 否 | `"memory"` \| `"context-engine"` | 声明由 `plugins.slots.*` 使用的排他性插件类型。 | +| `channels` | 否 | `string[]` | 此插件拥有的渠道 id。用于设备发现和配置验证。 | +| `providers` | 否 | `string[]` | 此插件拥有的提供商 id。 | +| `providerDiscoveryEntry` | 否 | `string` | 轻量级提供商设备发现模块路径,相对于插件根目录,用于可在不激活完整插件运行时的情况下加载的、限定于清单作用域的提供商目录元数据。 | +| `modelSupport` | 否 | `object` | 由清单拥有的简写模型家族元数据,用于在运行时之前自动加载插件。 | +| `providerEndpoints` | 否 | `object[]` | 由清单拥有的 endpoint 主机 / `baseUrl` 元数据,用于核心在提供商运行时加载前必须分类的提供商路由。 | +| `cliBackends` | 否 | `string[]` | 此插件拥有的 CLI 推理后端 id。用于根据显式配置引用在启动时自动激活。 | +| `syntheticAuthRefs` | 否 | `string[]` | 在运行时加载前、冷启动模型发现期间,应探测其插件自有 synthetic auth hook 的提供商或 CLI 后端引用。 | +| `nonSecretAuthMarkers` | 否 | `string[]` | 由内置插件拥有的占位 API 密钥值,表示非机密的本地、OAuth 或环境凭证状态。 | +| `commandAliases` | 否 | `object[]` | 由此插件拥有的命令名称,在运行时加载前应生成具备插件感知能力的配置和 CLI 诊断信息。 | +| `providerAuthEnvVars` | 否 | `Record` | 用于提供商凭证 / 状态查找的已弃用兼容性环境变量元数据。对于新插件,优先使用 `setup.providers[].envVars`;在弃用窗口期内,OpenClaw 仍会读取此字段。 | +| `providerAuthAliases` | 否 | `Record` | 应复用另一个提供商 id 进行凭证查找的提供商 id,例如与基础提供商共享 API 密钥和凭证配置文件的编码提供商。 | +| `channelEnvVars` | 否 | `Record` | OpenClaw 可在不加载插件代码的情况下检查的轻量级渠道环境变量元数据。将其用于由环境变量驱动的渠道设置或凭证界面,以便通用启动 / 配置辅助工具能够识别。 | +| `providerAuthChoices` | 否 | `object[]` | 用于 onboarding 选择器、首选提供商解析和简单 CLI 标志接线的轻量级凭证选项元数据。 | +| `activation` | 否 | `object` | 用于由提供商、命令、渠道、路由和能力触发加载的轻量级激活规划器元数据。仅包含元数据;插件运行时仍拥有实际行为。 | +| `setup` | 否 | `object` | 供设备发现和设置界面在不加载插件运行时的情况下检查的轻量级设置 / onboarding 描述符。 | +| `qaRunners` | 否 | `object[]` | 共享 `openclaw qa` 主机在插件运行时加载前使用的轻量级 QA 运行器描述符。 | +| `contracts` | 否 | `object` | 外部凭证 hook、语音、实时转录、实时语音、媒体理解、图像生成、音乐生成、视频生成、网页抓取、网页搜索和工具归属的静态内置能力快照。 | +| `mediaUnderstandingProviderMetadata` | 否 | `Record` | 为 `contracts.mediaUnderstandingProviders` 中声明的提供商 id 提供的轻量级媒体理解默认值。 | +| `channelConfigs` | 否 | `Record` | 在运行时加载前合并到设备发现和验证界面中的、由清单拥有的渠道配置元数据。 | +| `skills` | 否 | `string[]` | 要加载的 Skills 目录,相对于插件根目录。 | +| `name` | 否 | `string` | 人类可读的插件名称。 | +| `description` | 否 | `string` | 在插件界面中显示的简短摘要。 | +| `version` | 否 | `string` | 仅供参考的插件版本。 | +| `uiHints` | 否 | `Record` | 配置字段的 UI 标签、占位符和敏感性提示。 | ## `providerAuthChoices` 参考 -每个 `providerAuthChoices` 条目描述一个新手引导或认证选项。 -OpenClaw 会在 provider 运行时加载前读取此信息。 +每个 `providerAuthChoices` 条目描述一个 onboarding 或凭证选项。 +OpenClaw 会在提供商运行时加载之前读取这些信息。 -| 字段 | 必填 | 类型 | 含义 | -| --------------------- | -------- | ----------------------------------------------- | -------------------------------------------------------------------------------------------------------- | -| `provider` | 是 | `string` | 此选项所属的 provider ID。 | -| `method` | 是 | `string` | 要分发到的认证方法 ID。 | -| `choiceId` | 是 | `string` | 由新手引导和 CLI 流程使用的稳定认证选项 ID。 | -| `choiceLabel` | 否 | `string` | 面向用户的标签。若省略,OpenClaw 会回退到 `choiceId`。 | -| `choiceHint` | 否 | `string` | 选择器的简短辅助文本。 | -| `assistantPriority` | 否 | `number` | 在由 assistant 驱动的交互式选择器中,值越小排序越靠前。 | -| `assistantVisibility` | 否 | `"visible"` \| `"manual-only"` | 在 assistant 选择器中隐藏该选项,但仍允许手动通过 CLI 选择。 | -| `deprecatedChoiceIds` | 否 | `string[]` | 旧版选项 ID,应将用户重定向到这个替代选项。 | -| `groupId` | 否 | `string` | 用于对相关选项分组的可选组 ID。 | -| `groupLabel` | 否 | `string` | 该分组的面向用户标签。 | -| `groupHint` | 否 | `string` | 该分组的简短辅助文本。 | -| `optionKey` | 否 | `string` | 用于简单单标志认证流程的内部选项键。 | -| `cliFlag` | 否 | `string` | CLI 标志名称,例如 `--openrouter-api-key`。 | -| `cliOption` | 否 | `string` | 完整 CLI 选项形式,例如 `--openrouter-api-key `。 | -| `cliDescription` | 否 | `string` | CLI 帮助中使用的说明。 | -| `onboardingScopes` | 否 | `Array<"text-inference" \| "image-generation">` | 该选项应出现在哪些新手引导表面中。若省略,则默认是 `["text-inference"]`。 | +| 字段 | 必填 | 类型 | 含义 | +| -------------------- | ---- | ----------------------------------------------- | ------------------------------------------------------------------------------------------ | +| `provider` | 是 | `string` | 此选项所属的提供商 id。 | +| `method` | 是 | `string` | 要分派到的凭证方法 id。 | +| `choiceId` | 是 | `string` | 由 onboarding 和 CLI 流程使用的稳定凭证选项 id。 | +| `choiceLabel` | 否 | `string` | 面向用户的标签。如果省略,OpenClaw 会回退为 `choiceId`。 | +| `choiceHint` | 否 | `string` | 选择器的简短帮助文本。 | +| `assistantPriority` | 否 | `number` | 在由智能体驱动的交互式选择器中,值越小排序越靠前。 | +| `assistantVisibility` | 否 | `"visible"` \| `"manual-only"` | 在智能体选择器中隐藏此选项,但仍允许手动通过 CLI 进行选择。 | +| `deprecatedChoiceIds` | 否 | `string[]` | 应将用户重定向到此替代选项的旧版选项 id。 | +| `groupId` | 否 | `string` | 用于对相关选项分组的可选组 id。 | +| `groupLabel` | 否 | `string` | 该分组面向用户的标签。 | +| `groupHint` | 否 | `string` | 该分组的简短帮助文本。 | +| `optionKey` | 否 | `string` | 用于简单单标志凭证流程的内部选项键。 | +| `cliFlag` | 否 | `string` | CLI 标志名称,例如 `--openrouter-api-key`。 | +| `cliOption` | 否 | `string` | 完整的 CLI 选项形式,例如 `--openrouter-api-key `。 | +| `cliDescription` | 否 | `string` | 用于 CLI 帮助信息中的描述。 | +| `onboardingScopes` | 否 | `Array<"text-inference" \| "image-generation">` | 此选项应显示在哪些 onboarding 界面中。如果省略,默认值为 `["text-inference"]`。 | ## `commandAliases` 参考 -当插件拥有某个运行时命令名,而用户可能错误地将其放入 `plugins.allow`,或者尝试将其作为根 CLI 命令运行时,请使用 `commandAliases`。OpenClaw 使用这些元数据来生成诊断信息,而无需导入插件运行时代码。 +当插件拥有某个运行时命令名称,而用户可能会误将其放入 `plugins.allow`,或尝试将其作为根级 CLI 命令运行时,请使用 `commandAliases`。OpenClaw 使用此元数据在不导入插件运行时代码的情况下提供诊断信息。 ```json { @@ -200,21 +200,21 @@ OpenClaw 会在 provider 运行时加载前读取此信息。 } ``` -| 字段 | 必填 | 类型 | 含义 | -| ------------ | -------- | ----------------- | ----------------------------------------------------------------------- | -| `name` | 是 | `string` | 属于此插件的命令名称。 | -| `kind` | 否 | `"runtime-slash"` | 将该别名标记为聊天斜杠命令,而不是根 CLI 命令。 | -| `cliCommand` | 否 | `string` | 若存在,用于 CLI 操作时建议的相关根 CLI 命令。 | +| 字段 | 必填 | 类型 | 含义 | +| ------------ | ---- | ----------------- | ---------------------------------------------------------------- | +| `name` | 是 | `string` | 属于此插件的命令名称。 | +| `kind` | 否 | `"runtime-slash"` | 将该别名标记为聊天斜杠命令,而不是根级 CLI 命令。 | +| `cliCommand` | 否 | `string` | 可用于 CLI 操作时建议的相关根级 CLI 命令(如果存在)。 | ## `activation` 参考 -当插件可以低成本声明哪些 control-plane 事件应将其纳入激活/加载计划时,请使用 `activation`。 +当插件能够以低成本声明哪些控制平面事件应将其纳入激活 / 加载计划时,请使用 `activation`。 -此块是规划器元数据,而不是生命周期 API。它不会注册运行时行为,不会替代 `register(...)`,也不保证插件代码已经执行。激活规划器使用这些字段在回退到现有清单归属元数据(例如 `providers`、`channels`、`commandAliases`、`setup.providers`、`contracts.tools` 和 hooks)之前缩小候选插件范围。 +该区块是规划器元数据,而不是生命周期 API。它不会注册运行时行为,不会替代 `register(...)`,也不保证插件代码已经执行。激活规划器使用这些字段在回退到现有清单归属元数据(如 `providers`、`channels`、`commandAliases`、`setup.providers`、`contracts.tools` 和 hooks)之前,先缩小候选插件范围。 -优先使用已经能描述归属关系的最窄元数据。当这些字段能够表达关系时,请使用 `providers`、`channels`、`commandAliases`、setup 描述符或 `contracts`。只有在这些归属字段无法表示额外规划提示时,才使用 `activation`。 +优先使用已经描述归属关系的最窄元数据。如果 `providers`、`channels`、`commandAliases`、设置描述符或 `contracts` 这些字段已经能够表达这种关系,就使用它们。仅在这些归属字段无法表示额外规划器提示时,才使用 `activation`。 -此块仅是元数据。它不会注册运行时行为,也不会替代 `register(...)`、`setupEntry` 或其他运行时/插件入口点。当前使用方会将其作为更广泛插件加载之前的缩小范围提示,因此缺少激活元数据通常只会影响性能;在旧版清单归属回退仍存在时,它不应改变正确性。 +该区块仅包含元数据。它不会注册运行时行为,也不会替代 `register(...)`、`setupEntry` 或其他运行时 / 插件入口点。当前使用方会在更广泛的插件加载之前将其作为缩小范围的提示,因此缺失激活元数据通常只会带来性能成本;在旧版清单归属回退仍存在的情况下,它不应影响正确性。 ```json { @@ -228,28 +228,29 @@ OpenClaw 会在 provider 运行时加载前读取此信息。 } ``` -| 字段 | 必填 | 类型 | 含义 | -| ---------------- | -------- | ---------------------------------------------------- | ------------------------------------------------------------------------------------------------------- | -| `onProviders` | 否 | `string[]` | 应将此插件纳入激活/加载计划的 provider ID。 | -| `onCommands` | 否 | `string[]` | 应将此插件纳入激活/加载计划的命令 ID。 | -| `onChannels` | 否 | `string[]` | 应将此插件纳入激活/加载计划的渠道 ID。 | -| `onRoutes` | 否 | `string[]` | 应将此插件纳入激活/加载计划的路由类型。 | -| `onCapabilities` | 否 | `Array<"provider" \| "channel" \| "tool" \| "hook">` | control-plane 激活规划使用的宽泛能力提示。可能时优先使用更窄的字段。 | +| 字段 | 必填 | 类型 | 含义 | +| ---------------- | ---- | ---------------------------------------------------- | ------------------------------------------------------------------------------------------ | +| `onProviders` | 否 | `string[]` | 应将此插件纳入激活 / 加载计划的提供商 id。 | +| `onCommands` | 否 | `string[]` | 应将此插件纳入激活 / 加载计划的命令 id。 | +| `onChannels` | 否 | `string[]` | 应将此插件纳入激活 / 加载计划的渠道 id。 | +| `onRoutes` | 否 | `string[]` | 应将此插件纳入激活 / 加载计划的路由类型。 | +| `onCapabilities` | 否 | `Array<"provider" \| "channel" \| "tool" \| "hook">` | 控制平面激活规划使用的宽泛能力提示。若可能,优先使用更窄的字段。 | -当前的实时使用方: +当前正在使用的消费者: -- 由命令触发的 CLI 规划会回退到旧版 +- 由命令触发的 CLI 规划会回退到旧版的 `commandAliases[].cliCommand` 或 `commandAliases[].name` -- 由渠道触发的 setup/channel 规划在缺少显式渠道激活元数据时,会回退到旧版 `channels[]` - 归属 -- 由 provider 触发的 setup/runtime 规划在缺少显式 provider - 激活元数据时,会回退到旧版 `providers[]` 和顶层 `cliBackends[]` 归属 +- 由渠道触发的设置 / 渠道规划在缺少显式渠道激活元数据时, + 会回退到旧版的 `channels[]` 归属 +- 由提供商触发的设置 / 运行时规划在缺少显式提供商 + 激活元数据时,会回退到旧版的 + `providers[]` 和顶层 `cliBackends[]` 归属 -规划器诊断可以区分显式激活提示和清单归属回退。例如,`activation-command-hint` 表示命中了 `activation.onCommands`,而 `manifest-command-alias` 表示规划器改为使用 `commandAliases` 归属。这些原因标签面向宿主诊断和测试;插件作者应继续声明最能描述归属关系的元数据。 +规划器诊断可以区分显式激活提示与清单归属回退。例如,`activation-command-hint` 表示匹配了 `activation.onCommands`,而 `manifest-command-alias` 表示规划器改为使用了 `commandAliases` 归属。这些原因标签用于宿主诊断和测试;插件作者应继续声明最能描述归属关系的元数据。 ## `qaRunners` 参考 -当插件在共享 `openclaw qa` 根命令下提供一个或多个传输运行器时,请使用 `qaRunners`。请让这些元数据保持轻量且静态;实际 CLI 注册仍由插件运行时通过导出 `qaRunnerCliRegistrations` 的轻量 `runtime-api.ts` 表面拥有。 +当插件在共享的 `openclaw qa` 根命令下贡献一个或多个传输运行器时,请使用 `qaRunners`。保持这些元数据轻量且静态;插件运行时仍通过导出 `qaRunnerCliRegistrations` 的轻量级 `runtime-api.ts` 接口拥有实际的 CLI 注册逻辑。 ```json { @@ -262,14 +263,14 @@ OpenClaw 会在 provider 运行时加载前读取此信息。 } ``` -| 字段 | 必填 | 类型 | 含义 | -| ------------- | -------- | -------- | ------------------------------------------------------------------ | -| `commandName` | 是 | `string` | 挂载在 `openclaw qa` 下的子命令,例如 `matrix`。 | -| `description` | 否 | `string` | 当共享宿主需要一个桩命令时使用的后备帮助文本。 | +| 字段 | 必填 | 类型 | 含义 | +| ------------- | ---- | -------- | --------------------------------------------------------------------- | +| `commandName` | 是 | `string` | 挂载在 `openclaw qa` 下的子命令,例如 `matrix`。 | +| `description` | 否 | `string` | 当共享宿主需要一个 stub 命令时使用的回退帮助文本。 | ## `setup` 参考 -当设置和新手引导表面在运行时加载前需要低成本的插件拥有元数据时,请使用 `setup`。 +当设置和 onboarding 界面在运行时加载前需要低成本的、由插件拥有的元数据时,请使用 `setup`。 ```json { @@ -288,43 +289,45 @@ OpenClaw 会在 provider 运行时加载前读取此信息。 } ``` -顶层 `cliBackends` 仍然有效,并继续描述 CLI 推理后端。`setup.cliBackends` 是一个面向 setup 的描述符表面,供应保持为纯元数据的 control-plane/setup 流程使用。 +顶层 `cliBackends` 仍然有效,并继续描述 CLI 推理后端。`setup.cliBackends` 是控制平面 / 设置流程使用的、专用于设置的描述符界面,应保持为仅元数据。 -存在 `setup.providers` 和 `setup.cliBackends` 时,它们是 setup 发现的首选“描述符优先”查找表面。如果描述符只能缩小候选插件范围,而 setup 仍需要更丰富的设置时运行时 hooks,请设置 `requiresRuntime: true`,并保留 `setup-api` 作为回退执行路径。 +存在 `setup.providers` 和 `setup.cliBackends` 时,它们是设置设备发现的首选“描述符优先”查找界面。如果描述符只能缩小候选插件范围,而设置仍需要更丰富的设置时运行时 hooks,请设置 `requiresRuntime: true`,并保留 `setup-api` 作为回退执行路径。 -仅当这些描述符对 setup 表面来说已经足够时,才设置 `requiresRuntime: false`。OpenClaw 会将显式 `false` 视为仅描述符契约,并且在 setup 查找时不会执行 `setup-api`。若省略 `requiresRuntime`,则保留旧版回退行为,以确保那些添加了描述符但未添加该标志的现有插件不会出问题。 +OpenClaw 还会在通用提供商凭证和环境变量查找中包含 `setup.providers[].envVars`。在弃用窗口期内,`providerAuthEnvVars` 仍通过兼容适配器受到支持,但仍在使用它的非内置插件会收到清单诊断。新插件应将设置 / 状态环境变量元数据放在 `setup.providers[].envVars` 上。 -由于 setup 查找可能会执行插件拥有的 `setup-api` 代码,因此规范化后的 `setup.providers[].id` 和 `setup.cliBackends[]` 值必须在所有已发现插件之间保持唯一。归属不明确时会以失败关闭,而不是按发现顺序选择一个赢家。 +仅当这些描述符对设置界面已经足够时,才设置 `requiresRuntime: false`。OpenClaw 将显式的 `false` 视为仅描述符契约,并且不会为设置查找执行 `setup-api`。省略 `requiresRuntime` 会保留旧版回退行为,以便那些在未添加该标志的情况下已添加描述符的现有插件不会中断。 -当 setup 运行时确实执行时,如果 `setup-api` 注册了清单描述符中未声明的 provider 或 CLI 后端,或者某个描述符没有匹配的运行时注册,setup 注册表诊断会报告描述符漂移。这些诊断是增量补充,不会拒绝旧版插件。 +由于设置查找可能执行插件自有的 `setup-api` 代码,因此规范化后的 `setup.providers[].id` 和 `setup.cliBackends[]` 值在所有已发现插件之间必须保持唯一。归属不明确时会以封闭失败方式处理,而不是根据发现顺序选出一个获胜者。 + +当设置运行时确实执行时,如果 `setup-api` 注册了清单描述符未声明的提供商或 CLI 后端,或某个描述符没有对应的运行时注册,设置注册表诊断会报告描述符漂移。这些诊断是附加性的,不会拒绝旧版插件。 ### `setup.providers` 参考 -| 字段 | 必填 | 类型 | 含义 | -| ------------- | -------- | ---------- | ------------------------------------------------------------------------------------ | -| `id` | 是 | `string` | 在 setup 或新手引导期间暴露的 provider ID。请保持规范化 ID 在全局范围内唯一。 | -| `authMethods` | 否 | `string[]` | 此 provider 在不加载完整运行时的情况下支持的 setup/auth 方法 ID。 | -| `envVars` | 否 | `string[]` | 通用 setup/status 表面可在插件运行时加载前检查的环境变量。 | +| 字段 | 必填 | 类型 | 含义 | +| ------------- | ---- | ---------- | -------------------------------------------------------------------------- | +| `id` | 是 | `string` | 在设置或 onboarding 期间公开的提供商 id。保持规范化 id 在全局范围内唯一。 | +| `authMethods` | 否 | `string[]` | 此提供商在不加载完整运行时的情况下支持的设置 / 凭证方法 id。 | +| `envVars` | 否 | `string[]` | 通用设置 / 状态界面可在插件运行时加载前检查的环境变量。 | ### `setup` 字段 -| 字段 | 必填 | 类型 | 含义 | -| ------------------ | -------- | ---------- | --------------------------------------------------------------------------------------------------- | -| `providers` | 否 | `object[]` | 在 setup 和新手引导期间暴露的 provider setup 描述符。 | -| `cliBackends` | 否 | `string[]` | 用于“描述符优先” setup 查找的 setup 时后端 ID。请保持规范化 ID 在全局范围内唯一。 | -| `configMigrations` | 否 | `string[]` | 属于此插件 setup 表面的配置迁移 ID。 | -| `requiresRuntime` | 否 | `boolean` | 在描述符查找之后,setup 是否仍需要执行 `setup-api`。 | +| 字段 | 必填 | 类型 | 含义 | +| ------------------ | ---- | ---------- | ---------------------------------------------------------------------------------------- | +| `providers` | 否 | `object[]` | 在设置和 onboarding 期间公开的提供商设置描述符。 | +| `cliBackends` | 否 | `string[]` | 用于描述符优先设置查找的设置阶段后端 id。保持规范化 id 在全局范围内唯一。 | +| `configMigrations` | 否 | `string[]` | 属于此插件设置界面的配置迁移 id。 | +| `requiresRuntime` | 否 | `boolean` | 在描述符查找之后,设置是否仍需要执行 `setup-api`。 | ## `uiHints` 参考 -`uiHints` 是一个从配置字段名映射到小型渲染提示的映射表。 +`uiHints` 是从配置字段名到小型渲染提示的映射。 ```json { "uiHints": { "apiKey": { - "label": "API key", - "help": "Used for OpenRouter requests", + "label": "API 密钥", + "help": "用于 OpenRouter 请求", "placeholder": "sk-or-v1-...", "sensitive": true } @@ -334,18 +337,18 @@ OpenClaw 会在 provider 运行时加载前读取此信息。 每个字段提示可以包含: -| 字段 | 类型 | 含义 | -| ------------- | ---------- | --------------------------------------- | -| `label` | `string` | 面向用户的字段标签。 | -| `help` | `string` | 简短辅助文本。 | -| `tags` | `string[]` | 可选的 UI 标签。 | -| `advanced` | `boolean` | 将该字段标记为高级项。 | -| `sensitive` | `boolean` | 将该字段标记为密钥或敏感项。 | -| `placeholder` | `string` | 表单输入的占位文本。 | +| 字段 | 类型 | 含义 | +| ------------- | ---------- | ------------------------------- | +| `label` | `string` | 面向用户的字段标签。 | +| `help` | `string` | 简短帮助文本。 | +| `tags` | `string[]` | 可选的 UI 标签。 | +| `advanced` | `boolean` | 将该字段标记为高级。 | +| `sensitive` | `boolean` | 将该字段标记为机密或敏感。 | +| `placeholder` | `string` | 表单输入框的占位文本。 | ## `contracts` 参考 -仅在 OpenClaw 可在不导入插件运行时的情况下读取静态能力归属元数据时使用 `contracts`。 +仅在 OpenClaw 能够在不导入插件运行时的情况下读取静态能力归属元数据时,才使用 `contracts`。 ```json { @@ -368,31 +371,31 @@ OpenClaw 会在 provider 运行时加载前读取此信息。 每个列表都是可选的: -| 字段 | 类型 | 含义 | -| -------------------------------- | ---------- | ---------------------------------------------------------------- | -| `embeddedExtensionFactories` | `string[]` | 已弃用的内嵌 extension factory ID。 | -| `agentToolResultMiddleware` | `string[]` | 此插件可为其注册工具结果中间件的 harness ID。 | -| `externalAuthProviders` | `string[]` | 此插件拥有其外部 auth profile hook 的 provider ID。 | -| `speechProviders` | `string[]` | 此插件拥有的 speech provider ID。 | -| `realtimeTranscriptionProviders` | `string[]` | 此插件拥有的实时转录 provider ID。 | -| `realtimeVoiceProviders` | `string[]` | 此插件拥有的实时语音 provider ID。 | -| `memoryEmbeddingProviders` | `string[]` | 此插件拥有的 memory embedding provider ID。 | -| `mediaUnderstandingProviders` | `string[]` | 此插件拥有的媒体理解 provider ID。 | -| `imageGenerationProviders` | `string[]` | 此插件拥有的图像生成 provider ID。 | -| `videoGenerationProviders` | `string[]` | 此插件拥有的视频生成 provider ID。 | -| `webFetchProviders` | `string[]` | 此插件拥有的 web-fetch provider ID。 | -| `webSearchProviders` | `string[]` | 此插件拥有的 Web 搜索 provider ID。 | -| `tools` | `string[]` | 此插件为内置契约检查所拥有的智能体工具名称。 | +| 字段 | 类型 | 含义 | +| -------------------------------- | ---------- | -------------------------------------------------------------- | +| `embeddedExtensionFactories` | `string[]` | 已弃用的内嵌扩展工厂 id。 | +| `agentToolResultMiddleware` | `string[]` | 此插件可为其注册工具结果中间件的 harness id。 | +| `externalAuthProviders` | `string[]` | 此插件拥有其外部凭证配置文件 hook 的提供商 id。 | +| `speechProviders` | `string[]` | 此插件拥有的语音提供商 id。 | +| `realtimeTranscriptionProviders` | `string[]` | 此插件拥有的实时转录提供商 id。 | +| `realtimeVoiceProviders` | `string[]` | 此插件拥有的实时语音提供商 id。 | +| `memoryEmbeddingProviders` | `string[]` | 此插件拥有的 Memory 嵌入提供商 id。 | +| `mediaUnderstandingProviders` | `string[]` | 此插件拥有的媒体理解提供商 id。 | +| `imageGenerationProviders` | `string[]` | 此插件拥有的图像生成提供商 id。 | +| `videoGenerationProviders` | `string[]` | 此插件拥有的视频生成提供商 id。 | +| `webFetchProviders` | `string[]` | 此插件拥有的网页抓取提供商 id。 | +| `webSearchProviders` | `string[]` | 此插件拥有的网页搜索提供商 id。 | +| `tools` | `string[]` | 此插件拥有的智能体工具名称,用于内置契约检查。 | -`contracts.embeddedExtensionFactories` 被保留用于仍然需要直接 Pi 内嵌运行器事件的内置兼容代码。新的工具结果转换应声明 `contracts.agentToolResultMiddleware`,并改用 `api.registerAgentToolResultMiddleware(...)` 进行注册。 +保留 `contracts.embeddedExtensionFactories` 是为了兼容仍需要直接 Pi 内嵌运行器事件的内置兼容代码。新的工具结果转换应声明 `contracts.agentToolResultMiddleware`,并改为使用 `api.registerAgentToolResultMiddleware(...)` 进行注册。 -实现 `resolveExternalAuthProfiles` 的 provider 插件应声明 `contracts.externalAuthProviders`。未声明该字段的插件仍会通过一个已弃用的兼容性回退路径运行,但该回退路径更慢,并将在迁移窗口结束后移除。 +实现 `resolveExternalAuthProfiles` 的提供商插件应声明 `contracts.externalAuthProviders`。未声明该字段的插件仍会通过已弃用的兼容回退继续运行,但该回退更慢,并将在迁移窗口结束后移除。 -内置 memory embedding provider 应为其暴露的每个适配器 ID 声明 `contracts.memoryEmbeddingProviders`,包括像 `local` 这样的内置适配器。独立 CLI 路径使用此清单契约,只在完整 Gateway 网关运行时注册 provider 之前加载所属插件。 +内置的 Memory 嵌入提供商应为其公开的每个适配器 id 声明 `contracts.memoryEmbeddingProviders`,包括诸如 `local` 之类的内置适配器。独立 CLI 路径使用此清单契约,仅在完整 Gateway 网关运行时注册提供商之前加载所属插件。 ## `mediaUnderstandingProviderMetadata` 参考 -当媒体理解 provider 具有默认模型、自动认证回退优先级,或需要在运行时加载前供通用 core 辅助逻辑使用的原生文档支持时,请使用 `mediaUnderstandingProviderMetadata`。其键也必须在 `contracts.mediaUnderstandingProviders` 中声明。 +当媒体理解提供商具有默认模型、自动凭证回退优先级,或在运行时加载前就需要供通用核心辅助工具使用的原生文档支持时,请使用 `mediaUnderstandingProviderMetadata`。键也必须在 `contracts.mediaUnderstandingProviders` 中声明。 ```json { @@ -415,14 +418,14 @@ OpenClaw 会在 provider 运行时加载前读取此信息。 } ``` -每个 provider 条目可以包含: +每个提供商条目可以包含: -| 字段 | 类型 | 含义 | -| ---------------------- | ----------------------------------- | ---------------------------------------------------------------------------- | -| `capabilities` | `("image" \| "audio" \| "video")[]` | 该 provider 暴露的媒体能力。 | -| `defaultModels` | `Record` | 当配置未指定模型时使用的“能力到模型”默认值。 | -| `autoPriority` | `Record` | 在基于凭证的自动 provider 回退中,数字越小排序越靠前。 | -| `nativeDocumentInputs` | `"pdf"[]` | 该 provider 支持的原生文档输入。 | +| 字段 | 类型 | 含义 | +| ---------------------- | ----------------------------------- | -------------------------------------------------------------------------- | +| `capabilities` | `("image" \| "audio" \| "video")[]` | 此提供商公开的媒体能力。 | +| `defaultModels` | `Record` | 当配置未指定模型时使用的“能力到模型”默认值。 | +| `autoPriority` | `Record` | 用于基于凭证自动回退提供商时的排序优先级,数字越小排序越靠前。 | +| `nativeDocumentInputs` | `"pdf"[]` | 该提供商支持的原生文档输入。 | ## `channelConfigs` 参考 @@ -455,17 +458,17 @@ OpenClaw 会在 provider 运行时加载前读取此信息。 每个渠道条目可以包含: -| 字段 | 类型 | 含义 | -| ------------- | ------------------------ | ----------------------------------------------------------------------------------------- | -| `schema` | `object` | `channels.` 的 JSON Schema。每个已声明的渠道配置条目都必须提供。 | -| `uiHints` | `Record` | 该渠道配置部分的可选 UI 标签/占位符/敏感性提示。 | -| `label` | `string` | 当运行时元数据尚未就绪时,合并到选择器和检查表面中的渠道标签。 | -| `description` | `string` | 用于检查和 catalog 表面的简短渠道说明。 | -| `preferOver` | `string[]` | 在选择表面中应优先于其显示的旧版或较低优先级插件 ID。 | +| 字段 | 类型 | 含义 | +| ------------- | ------------------------ | ------------------------------------------------------------------------------------- | +| `schema` | `object` | `channels.` 的 JSON Schema。每个已声明的渠道配置条目都必须提供。 | +| `uiHints` | `Record` | 该渠道配置部分的可选 UI 标签 / 占位符 / 敏感性提示。 | +| `label` | `string` | 当运行时元数据尚未准备好时,合并到选择器和检查界面中的渠道标签。 | +| `description` | `string` | 用于检查和目录界面的简短渠道描述。 | +| `preferOver` | `string[]` | 在选择界面中应优先于其显示的旧版或较低优先级插件 id。 | ## `modelSupport` 参考 -当 OpenClaw 应在插件运行时加载前,根据像 `gpt-5.5` 或 `claude-sonnet-4.6` 这样的简写模型 ID 推断你的 provider 插件时,请使用 `modelSupport`。 +当 OpenClaw 应在插件运行时加载前,根据诸如 `gpt-5.5` 或 `claude-sonnet-4.6` 这样的简写模型 id 推断你的提供商插件时,请使用 `modelSupport`。 ```json { @@ -476,71 +479,74 @@ OpenClaw 会在 provider 运行时加载前读取此信息。 } ``` -OpenClaw 应用以下优先级: +OpenClaw 按以下优先级应用: -- 显式的 `provider/model` 引用使用所属 `providers` 清单元数据 -- `modelPatterns` 优先于 `modelPrefixes` -- 如果一个非内置插件和一个内置插件同时匹配,则非内置插件获胜 -- 剩余歧义会被忽略,直到用户或配置显式指定 provider +- 显式 `provider/model` 引用使用所属 `providers` 清单元数据 +- `modelPatterns` 的优先级高于 `modelPrefixes` +- 如果一个非内置插件和一个内置插件都匹配,则非内置插件胜出 +- 对于其余歧义,在用户或配置明确指定提供商之前会被忽略 字段: -| 字段 | 类型 | 含义 | -| --------------- | ---------- | ------------------------------------------------------------------------------- | -| `modelPrefixes` | `string[]` | 使用 `startsWith` 与简写模型 ID 匹配的前缀。 | -| `modelPatterns` | `string[]` | 在移除 profile 后缀后,用于与简写模型 ID 匹配的正则表达式源码。 | +| 字段 | 类型 | 含义 | +| --------------- | ---------- | ----------------------------------------------------------------------------- | +| `modelPrefixes` | `string[]` | 使用 `startsWith` 针对简写模型 id 进行匹配的前缀。 | +| `modelPatterns` | `string[]` | 在移除配置文件后缀后,针对简写模型 id 进行匹配的正则表达式源码。 | -旧版顶层能力键已弃用。使用 `openclaw doctor --fix` 将 `speechProviders`、`realtimeTranscriptionProviders`、`realtimeVoiceProviders`、`mediaUnderstandingProviders`、`imageGenerationProviders`、`videoGenerationProviders`、`webFetchProviders` 和 `webSearchProviders` 移到 `contracts` 下;常规清单加载已不再将这些顶层字段视为能力归属。 +旧版顶层能力键已弃用。使用 `openclaw doctor --fix` 将 +`speechProviders`、`realtimeTranscriptionProviders`、 +`realtimeVoiceProviders`、`mediaUnderstandingProviders`、 +`imageGenerationProviders`、`videoGenerationProviders`、 +`webFetchProviders` 和 `webSearchProviders` 移动到 `contracts` 下;常规清单加载不再将这些顶层字段视为能力归属。 ## 清单与 package.json 的区别 -这两个文件承担不同职责: +这两个文件承担不同的职责: -| 文件 | 用途 | -| ---------------------- | -------------------------------------------------------------------------------------------------------------------------------- | -| `openclaw.plugin.json` | 设备发现、配置验证、认证选项元数据,以及在插件代码运行前必须存在的 UI 提示 | -| `package.json` | npm 元数据、依赖安装,以及用于入口点、安装门控、设置或 catalog 元数据的 `openclaw` 块 | +| 文件 | 用途 | +| ---------------------- | ---------------------------------------------------------------------------------------------------------------------- | +| `openclaw.plugin.json` | 设备发现、配置验证、凭证选项元数据,以及在插件代码运行前必须存在的 UI 提示 | +| `package.json` | npm 元数据、依赖安装,以及用于入口点、安装门控、设置或目录元数据的 `openclaw` 区块 | -如果你不确定某条元数据应放在哪里,请遵循这条规则: +如果你不确定某段元数据应放在哪里,请使用以下规则: -- 如果 OpenClaw 必须在加载插件代码之前知道它,请将其放在 `openclaw.plugin.json` 中 -- 如果它与打包、入口文件或 npm 安装行为有关,请将其放在 `package.json` 中 +- 如果 OpenClaw 必须在加载插件代码之前知道它,就把它放在 `openclaw.plugin.json` 中 +- 如果它与打包、入口文件或 npm 安装行为有关,就把它放在 `package.json` 中 -### 会影响设备发现的 `package.json` 字段 +### 影响设备发现的 `package.json` 字段 -某些运行时前插件元数据有意放在 `package.json` 的 `openclaw` 块下,而不是 `openclaw.plugin.json` 中。 +某些运行时前插件元数据有意放在 `package.json` 的 `openclaw` 区块下,而不是 `openclaw.plugin.json` 中。 重要示例: -| 字段 | 含义 | -| ----------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -| `openclaw.extensions` | 声明原生插件入口点。必须保持在插件包目录内。 | -| `openclaw.runtimeExtensions` | 为已安装包声明已构建的 JavaScript 运行时入口点。必须保持在插件包目录内。 | -| `openclaw.setupEntry` | 仅用于 setup 的轻量入口点,在新手引导、延迟渠道启动和只读渠道状态/SecretRef 发现期间使用。必须保持在插件包目录内。 | -| `openclaw.runtimeSetupEntry` | 为已安装包声明已构建的 JavaScript setup 入口点。必须保持在插件包目录内。 | -| `openclaw.channel` | 轻量渠道 catalog 元数据,例如标签、文档路径、别名和选择文案。 | -| `openclaw.channel.configuredState` | 轻量 configured-state 检查器元数据,可在不加载完整渠道运行时的情况下回答“是否已存在仅基于环境变量的设置?”。 | -| `openclaw.channel.persistedAuthState` | 轻量 persisted-auth 检查器元数据,可在不加载完整渠道运行时的情况下回答“是否已有任何已登录状态?”。 | -| `openclaw.install.npmSpec` / `openclaw.install.localPath` | 内置插件和外部发布插件的安装/更新提示。 | -| `openclaw.install.defaultChoice` | 当有多个安装源可用时的首选安装路径。 | -| `openclaw.install.minHostVersion` | 最低支持的 OpenClaw 宿主版本,使用类似 `>=2026.3.22` 的 semver 下限。 | -| `openclaw.install.expectedIntegrity` | 预期的 npm dist 完整性字符串,例如 `sha512-...`;安装和更新流程会据此校验获取到的产物。 | -| `openclaw.install.allowInvalidConfigRecovery` | 当配置无效时,允许一个受限的内置插件重新安装恢复路径。 | -| `openclaw.startup.deferConfiguredChannelFullLoadUntilAfterListen` | 允许在启动期间,先加载仅用于 setup 的渠道表面,再加载完整渠道插件。 | +| 字段 | 含义 | +| ----------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `openclaw.extensions` | 声明原生插件入口点。必须保持在插件包目录内。 | +| `openclaw.runtimeExtensions` | 声明已安装包的构建后 JavaScript 运行时入口点。必须保持在插件包目录内。 | +| `openclaw.setupEntry` | 仅用于设置的轻量级入口点,用于 onboarding、延迟渠道启动和只读渠道状态 / SecretRef 设备发现。必须保持在插件包目录内。 | +| `openclaw.runtimeSetupEntry` | 声明已安装包的构建后 JavaScript 设置入口点。必须保持在插件包目录内。 | +| `openclaw.channel` | 轻量级渠道目录元数据,例如标签、文档路径、别名和选择文案。 | +| `openclaw.channel.configuredState` | 轻量级已配置状态检查器元数据,可在不加载完整渠道运行时的情况下回答“是否已存在仅由环境变量驱动的设置?”。 | +| `openclaw.channel.persistedAuthState` | 轻量级持久化凭证状态检查器元数据,可在不加载完整渠道运行时的情况下回答“是否已有任何内容处于已登录状态?”。 | +| `openclaw.install.npmSpec` / `openclaw.install.localPath` | 用于内置和外部发布插件的安装 / 更新提示。 | +| `openclaw.install.defaultChoice` | 当存在多个安装来源时的首选安装路径。 | +| `openclaw.install.minHostVersion` | 最低支持的 OpenClaw 宿主版本,使用类似 `>=2026.3.22` 的 semver 下限。 | +| `openclaw.install.expectedIntegrity` | 预期的 npm dist 完整性字符串,例如 `sha512-...`;安装和更新流程会根据它验证获取到的制品。 | +| `openclaw.install.allowInvalidConfigRecovery` | 当配置无效时,允许一个狭窄的内置插件重新安装恢复路径。 | +| `openclaw.startup.deferConfiguredChannelFullLoadUntilAfterListen` | 允许在启动期间先加载仅设置用的渠道界面,然后再加载完整渠道插件。 | -清单元数据决定了在运行时加载前,新手引导中会出现哪些 provider/channel/setup 选项。`package.json#openclaw.install` 则告诉新手引导,当用户选择这些选项之一时,应如何获取或启用该插件。不要将安装提示移到 `openclaw.plugin.json` 中。 +清单元数据决定了在运行时加载前,onboarding 中会出现哪些提供商 / 渠道 / 设置选项。`package.json#openclaw.install` 则告诉 onboarding,当用户选择其中某个选项时,应如何获取或启用该插件。不要将安装提示移动到 `openclaw.plugin.json` 中。 -`openclaw.install.minHostVersion` 会在安装和清单注册表加载期间强制执行。无效值会被拒绝;对于较新的但有效的值,在较旧宿主上会跳过该插件。 +`openclaw.install.minHostVersion` 会在安装期间和清单注册表加载期间强制执行。无效值会被拒绝;对较旧宿主而言,较新但有效的值会导致跳过该插件。 -精确的 npm 版本固定已经存在于 `npmSpec` 中,例如 -`"npmSpec": "@wecom/wecom-openclaw-plugin@1.2.3"`。官方外部 catalog 条目应将精确 spec 与 `expectedIntegrity` 搭配使用,这样一旦获取到的 npm 产物不再匹配固定发布版本,更新流程就会以失败关闭。为了兼容性,交互式新手引导仍会提供受信任注册表的 npm spec,包括裸包名和 dist-tag。catalog 诊断可以区分精确、浮动、带完整性固定、缺失完整性、包名不匹配以及无效 default-choice 来源。它们还会在存在 `expectedIntegrity` 但没有可用于固定的有效 npm 源时发出警告。 -当存在 `expectedIntegrity` 时,安装/更新流程会强制执行它;当省略该字段时,注册表解析结果会被记录,但不会附带完整性固定。 +精确的 npm 版本固定已存在于 `npmSpec` 中,例如 +`"npmSpec": "@wecom/wecom-openclaw-plugin@1.2.3"`。官方外部目录条目应将精确 spec 与 `expectedIntegrity` 配对使用,这样如果获取到的 npm 制品不再匹配固定的发布版本,更新流程就会以封闭失败方式处理。出于兼容性考虑,交互式 onboarding 仍会提供受信任注册表的 npm spec,包括裸包名和 dist-tag。目录诊断可以区分精确、浮动、带完整性固定、缺失完整性、包名不匹配和无效默认选项来源。它们还会在存在 `expectedIntegrity` 但没有可用于固定的有效 npm 来源时发出警告。存在 `expectedIntegrity` 时,安装 / 更新流程会强制执行它;省略时,注册表解析会被记录,但不会附带完整性固定。 -当状态、渠道列表或 SecretRef 扫描需要在不加载完整运行时的情况下识别已配置账户时,渠道插件应提供 `openclaw.setupEntry`。该 setup 入口点应暴露渠道元数据以及对 setup 安全的配置、状态和密钥适配器;请将网络客户端、Gateway 网关监听器和传输运行时保留在主 extension 入口点中。 +当状态、渠道列表或 SecretRef 扫描需要在不加载完整运行时的情况下识别已配置账户时,渠道插件应提供 `openclaw.setupEntry`。设置入口点应公开渠道元数据以及适用于设置的安全配置、状态和密钥适配器;将网络客户端、Gateway 网关监听器和传输运行时保留在主扩展入口点中。 -运行时入口点字段不会覆盖源码入口点字段的包边界检查。例如,`openclaw.runtimeExtensions` 不能让越界的 `openclaw.extensions` 路径变得可加载。 +运行时入口点字段不会覆盖源码入口点字段的包边界检查。例如,`openclaw.runtimeExtensions` 不能让一个越界的 `openclaw.extensions` 路径变得可加载。 -`openclaw.install.allowInvalidConfigRecovery` 的设计刻意保持狭窄。它不会让任意损坏的配置变得可安装。目前,它只允许安装流程从特定的陈旧内置插件升级失败中恢复,例如缺失的内置插件路径,或同一内置插件对应的陈旧 `channels.` 条目。无关的配置错误仍会阻止安装,并将操作员引导至 `openclaw doctor --fix`。 +`openclaw.install.allowInvalidConfigRecovery` 的作用范围是有意保持狭窄的。它不会让任意损坏的配置都变得可安装。当前它只允许安装流程从特定的过时内置插件升级失败中恢复,例如缺失的内置插件路径,或该内置插件对应的过时 `channels.` 条目。无关的配置错误仍会阻止安装,并将操作人员引导到 `openclaw doctor --fix`。 `openclaw.channel.persistedAuthState` 是一个微型检查器模块的包元数据: @@ -558,9 +564,9 @@ OpenClaw 应用以下优先级: } ``` -当 setup、Doctor 或 configured-state 流程需要在完整渠道插件加载前进行低成本的 yes/no 认证探测时,请使用它。目标导出应是一个仅读取持久化状态的小函数;不要通过完整渠道运行时 barrel 暴露它。 +当设置、Doctor 或已配置状态流程需要在完整渠道插件加载前进行一个低成本的“是 / 否”凭证探测时,请使用它。目标导出应是一个仅读取持久化状态的小函数;不要通过完整渠道运行时 barrel 来间接调用它。 -`openclaw.channel.configuredState` 对低成本、仅基于环境变量的 configured 检查采用相同结构: +`openclaw.channel.configuredState` 对低成本的仅环境变量配置检查采用相同的结构: ```json { @@ -576,52 +582,54 @@ OpenClaw 应用以下优先级: } ``` -当某个渠道可以通过环境变量或其他小型非运行时输入回答 configured-state 时,请使用它。如果该检查需要完整配置解析或真实渠道运行时,请将该逻辑保留在插件 `config.hasConfiguredState` hook 中。 +当某个渠道能够通过环境变量或其他微型非运行时输入回答已配置状态时,请使用它。如果检查需要完整配置解析或真实渠道运行时,请将该逻辑保留在插件的 `config.hasConfiguredState` hook 中。 -## 设备发现优先级(重复插件 ID) +## 设备发现优先级(重复插件 id) -OpenClaw 会从多个根位置发现插件(内置、全局安装、工作区、配置中显式选择的路径)。如果两个发现结果共享同一个 `id`,则只保留**优先级最高**的清单;优先级较低的重复项会被丢弃,而不是与其并排加载。 +OpenClaw 会从多个根位置发现插件(内置、全局安装、工作区、配置中显式选择的路径)。如果两个发现结果共享同一个 `id`,则只保留**优先级最高**的清单;低优先级的重复项会被丢弃,而不会与其并行加载。 优先级从高到低如下: -1. **配置选定** — 在 `plugins.entries.` 中显式固定的路径 -2. **内置** — 随 OpenClaw 一起发布的插件 -3. **全局安装** — 安装到全局 OpenClaw 插件根目录中的插件 -4. **工作区** — 相对于当前工作区发现的插件 +1. **配置中选择的** —— 在 `plugins.entries.` 中显式固定的路径 +2. **内置** —— 随 OpenClaw 一起发布的插件 +3. **全局安装** —— 安装到全局 OpenClaw 插件根目录中的插件 +4. **工作区** —— 相对于当前工作区发现的插件 影响: -- 工作区中存在的某个内置插件的分叉或陈旧副本,不会遮蔽内置构建版本。 -- 如果你确实要用本地插件覆盖内置插件,请通过 `plugins.entries.` 固定它,让它凭优先级获胜,而不是依赖工作区发现。 -- 重复项的丢弃会被记录,因此 Doctor 和启动诊断可以指向被丢弃的副本。 +- 位于工作区中的内置插件分叉或过时副本不会遮蔽内置构建。 +- 如果要真正用本地插件覆盖一个内置插件,请通过 `plugins.entries.` 固定它,使其依靠优先级获胜,而不是依赖工作区发现。 +- 被丢弃的重复项会被记录下来,以便 Doctor 和启动诊断能够指出被丢弃的副本。 ## JSON Schema 要求 - **每个插件都必须提供一个 JSON Schema**,即使它不接受任何配置。 -- 可以接受空 schema(例如,`{ "type": "object", "additionalProperties": false }`)。 -- schema 会在配置读写时验证,而不是在运行时验证。 +- 空 schema 也是可接受的(例如 `{ "type": "object", "additionalProperties": false }`)。 +- Schema 会在配置读取 / 写入时验证,而不是在运行时验证。 ## 验证行为 -- 未知的 `channels.*` 键是**错误**,除非该渠道 ID 已由某个插件清单声明。 +- 未知的 `channels.*` 键是**错误**,除非该渠道 id 由某个插件清单声明。 - `plugins.entries.`、`plugins.allow`、`plugins.deny` 和 `plugins.slots.*` - 必须引用**可发现的**插件 ID。未知 ID 都是**错误**。 -- 如果插件已安装,但其清单或 schema 缺失或损坏,验证会失败,Doctor 会报告该插件错误。 -- 如果插件配置存在,但插件已**禁用**,则该配置会被保留,并且 Doctor + 日志中会显示**警告**。 + 必须引用**可发现的**插件 id。未知 id 是**错误**。 +- 如果插件已安装,但其清单或 schema 损坏或缺失, + 验证会失败,Doctor 会报告该插件错误。 +- 如果插件配置存在,但插件被**禁用**,配置会被保留, + 并且 Doctor + 日志中会显示**警告**。 -有关完整的 `plugins.*` schema,请参阅 [配置参考](/zh-CN/gateway/configuration)。 +有关完整的 `plugins.*` schema,请参阅[配置参考](/zh-CN/gateway/configuration)。 ## 说明 -- **原生 OpenClaw 插件必须提供**清单,包括本地文件系统加载。运行时仍会单独加载插件模块;清单仅用于设备发现 + 验证。 -- 原生清单使用 JSON5 解析,因此允许注释、尾随逗号和未加引号的键,只要最终值仍然是对象即可。 +- 对于**原生 OpenClaw 插件**,包括本地文件系统加载,清单都是**必需的**。运行时仍会单独加载插件模块;清单仅用于设备发现 + 验证。 +- 原生清单使用 JSON5 解析,因此支持注释、尾随逗号和未加引号的键,只要最终值仍然是一个对象即可。 - 清单加载器只会读取有文档说明的清单字段。避免使用自定义顶层键。 -- 当插件不需要时,可以省略 `channels`、`providers`、`cliBackends` 和 `skills`。 -- `providerDiscoveryEntry` 必须保持轻量,不应导入宽泛的运行时代码;请将其用于静态 provider catalog 元数据或狭窄的发现描述符,而不是请求时执行。 -- 互斥插件类型通过 `plugins.slots.*` 选择:`kind: "memory"` 通过 `plugins.slots.memory`,`kind: "context-engine"` 通过 `plugins.slots.contextEngine`(默认 `legacy`)。 -- 环境变量元数据(`providerAuthEnvVars`、`channelEnvVars`)仅具有声明性质。状态、审计、cron 投递验证以及其他只读表面,在将环境变量视为已配置之前,仍会应用插件信任和有效激活策略。 -- 对于需要 provider 代码的运行时向导元数据,请参阅 [Provider 运行时钩子](/zh-CN/plugins/architecture-internals#provider-runtime-hooks)。 -- 如果你的插件依赖原生模块,请记录构建步骤以及任何包管理器 allowlist 要求(例如 pnpm `allow-build-scripts` + `pnpm rebuild `)。 +- 当插件不需要它们时,可以省略 `channels`、`providers`、`cliBackends` 和 `skills`。 +- `providerDiscoveryEntry` 必须保持轻量,不应导入宽泛的运行时代码;应将其用于静态提供商目录元数据或狭义设备发现描述符,而不是请求时执行。 +- 排他性插件类型通过 `plugins.slots.*` 选择:`kind: "memory"` 通过 `plugins.slots.memory` 选择,`kind: "context-engine"` 通过 `plugins.slots.contextEngine` 选择(默认值为 `legacy`)。 +- 环境变量元数据(`setup.providers[].envVars`、已弃用的 `providerAuthEnvVars` 和 `channelEnvVars`)仅具有声明性。状态、审计、cron 投递验证和其他只读界面在将某个环境变量视为已配置之前,仍会应用插件信任和有效激活策略。 +- 有关需要提供商代码的运行时向导元数据,请参阅[提供商运行时 hook](/zh-CN/plugins/architecture-internals#provider-runtime-hooks)。 +- 如果你的插件依赖原生模块,请记录构建步骤以及任何包管理器允许列表要求(例如 pnpm `allow-build-scripts` + `pnpm rebuild `)。 ## 相关内容 diff --git a/docs/zh-CN/plugins/sdk-migration.md b/docs/zh-CN/plugins/sdk-migration.md index 37f0e1eaf..2ece10429 100644 --- a/docs/zh-CN/plugins/sdk-migration.md +++ b/docs/zh-CN/plugins/sdk-migration.md @@ -1,90 +1,77 @@ --- read_when: - - 你看到了 `OPENCLAW_PLUGIN_SDK_COMPAT_DEPRECATED` 警告。 - - 你看到了 `OPENCLAW_EXTENSION_API_DEPRECATED` 警告。 - - 你正在使用 `api.registerEmbeddedExtensionFactory`。 - - 你正在将插件更新到现代插件架构。 - - 你在维护一个外部 OpenClaw 插件。 + - 你看到了 `OPENCLAW_PLUGIN_SDK_COMPAT_DEPRECATED` 警告 + - 你看到了 `OPENCLAW_EXTENSION_API_DEPRECATED` 警告 + - 你使用 `api.registerEmbeddedExtensionFactory` + - 你正在将插件更新到现代插件架构 + - 你维护一个外部 OpenClaw 插件 sidebarTitle: Migrate to SDK summary: 从旧版向后兼容层迁移到现代插件 SDK title: 插件 SDK 迁移 x-i18n: - generated_at: "2026-04-24T19:57:52Z" + generated_at: "2026-04-24T20:10:29Z" model: gpt-5.4 provider: openai - source_hash: fa44b2e9f3748ce41c91b5e389dbe0acee03e2ec84b35086068f419a252208a0 + source_hash: 0cd1f130ab3d82113ced47600e259330332d0063e17e8212b9e3120dfc73b0dd source_path: plugins/sdk-migration.md workflow: 15 --- -OpenClaw 已从宽泛的向后兼容层迁移到具有聚焦且有文档说明导入路径的现代插件架构。如果你的插件是在新架构之前构建的,本指南将帮助你完成迁移。 +OpenClaw 已从宽泛的向后兼容层迁移到现代插件架构,提供聚焦且有文档说明的导入路径。如果你的插件是在新架构之前构建的,本指南将帮助你完成迁移。 -## 正在发生的变化 +## 正在发生什么变化 -旧的插件系统提供了两个完全开放的接口,使插件可以从单个入口点导入所需的任何内容: +旧版插件系统提供了两个高度开放的接口面,使插件可以通过单一入口点导入所需的任何内容: -- **`openclaw/plugin-sdk/compat`** —— 一个会重新导出数十个辅助函数的单一导入入口。 - 它的引入是为了在新的插件架构构建期间,让较旧的基于 hook 的插件继续工作。 -- **`openclaw/extension-api`** —— 一个桥接层,使插件可以直接访问 - 宿主侧辅助函数,例如嵌入式 agent 运行器。 -- **`api.registerEmbeddedExtensionFactory(...)`** —— 一个仅限 Pi 的内置扩展 - hook,可用于观察诸如 `tool_result` 之类的 embedded-runner 事件。 +- **`openclaw/plugin-sdk/compat`** —— 一个单一导入入口,会重新导出数十个辅助工具。它的引入是为了在新插件架构构建期间,让旧的基于钩子的插件继续正常工作。 +- **`openclaw/extension-api`** —— 一个桥接层,使插件能够直接访问宿主侧辅助工具,例如嵌入式智能体运行器。 +- **`api.registerEmbeddedExtensionFactory(...)`** —— 一个仅限 Pi 的内置扩展钩子,可观察诸如 `tool_result` 之类的嵌入式运行器事件。 -这些接口现在都已被**弃用**。它们在运行时仍然可用,但新插件不得再使用它们,现有插件也应在下一个 major 版本移除它们之前完成迁移。 +这些接口面现已被**弃用**。它们在运行时仍然有效,但新插件不得再使用它们,现有插件也应在下一个主要版本移除它们之前完成迁移。 -OpenClaw 不会在引入替代方案的同一次变更中移除或重新解释已文档化的插件行为。破坏性契约变更必须先经过兼容适配器、诊断、文档和弃用窗口。 -这适用于 SDK 导入、manifest 字段、设置 API、hooks 和运行时注册行为。 +OpenClaw 不会在引入替代方案的同一次变更中,移除或重新解释已有文档说明的插件行为。破坏性合约变更必须先经过兼容适配器、诊断信息、文档说明和弃用窗口。这同样适用于 SDK 导入、清单字段、设置 API、钩子以及运行时注册行为。 - 向后兼容层将在未来的某个 major 版本中移除。 - 到那时仍从这些接口导入的插件将会失效。 + 向后兼容层将在未来的主要版本中移除。 + 到那时,仍然从这些接口面导入的插件将会失效。 -## 为什么会有这个变化 +## 为什么会有这项变化 -旧方法会导致这些问题: +旧方式会带来一些问题: -- **启动缓慢** —— 导入一个辅助函数会加载数十个无关模块 -- **循环依赖** —— 宽泛的重新导出很容易造成导入环 -- **API 接口不清晰** —— 无法分辨哪些导出是稳定的,哪些是内部实现 +- **启动缓慢** —— 导入一个辅助工具会加载数十个无关模块 +- **循环依赖** —— 宽泛的重新导出会让导入循环变得很容易产生 +- **API 接口面不清晰** —— 无法判断哪些导出是稳定的,哪些属于内部实现 -现代插件 SDK 解决了这些问题:每个导入路径(`openclaw/plugin-sdk/\`) -都是一个小型、自包含的模块,具有明确用途和文档化契约。 +现代插件 SDK 解决了这些问题:每个导入路径(`openclaw/plugin-sdk/\`)都是一个小型、独立的模块,具有明确用途和文档化合约。 -用于内置渠道的旧版提供商便捷接口也已移除。像 -`openclaw/plugin-sdk/slack`、`openclaw/plugin-sdk/discord`、 -`openclaw/plugin-sdk/signal`、`openclaw/plugin-sdk/whatsapp`、 -带渠道品牌的辅助接口,以及 -`openclaw/plugin-sdk/telegram-core` -这类导入,都是私有 mono-repo 快捷方式,而不是稳定的插件契约。请改用更窄的通用 SDK 子路径。在内置插件工作区内部,请将提供商自有辅助函数保留在该插件自己的 -`api.ts` 或 `runtime-api.ts` 中。 +面向内置渠道的旧版提供商便捷接口也已移除。诸如 `openclaw/plugin-sdk/slack`、`openclaw/plugin-sdk/discord`、`openclaw/plugin-sdk/signal`、`openclaw/plugin-sdk/whatsapp`、带渠道品牌的辅助接口,以及 `openclaw/plugin-sdk/telegram-core` 之类的导入路径,都是私有 monorepo 快捷方式,而不是稳定的插件合约。请改用更精简的通用 SDK 子路径。在内置插件工作区内部,请将由提供商拥有的辅助工具保留在该插件自己的 `api.ts` 或 `runtime-api.ts` 中。 -当前的内置提供商示例: +当前内置提供商示例: -- Anthropic 将 Claude 专用流辅助函数保留在它自己的 `api.ts` / - `contract-api.ts` 接口中 -- OpenAI 将提供商构建器、默认模型辅助函数和实时提供商构建器保留在它自己的 `api.ts` 中 -- OpenRouter 将提供商构建器以及新手引导 / 配置辅助函数保留在它自己的 - `api.ts` 中 +- Anthropic 将 Claude 专用流式辅助工具保留在它自己的 `api.ts` / `contract-api.ts` 接口中 +- OpenAI 将提供商构建器、默认模型辅助工具以及实时提供商构建器保留在它自己的 `api.ts` 中 +- OpenRouter 将提供商构建器以及新手引导 / 配置辅助工具保留在它自己的 `api.ts` 中 ## 兼容性策略 对于外部插件,兼容性工作遵循以下顺序: -1. 添加新契约 -2. 通过兼容适配器继续保留旧行为 -3. 发出诊断或警告,明确指出旧路径及其替代项 +1. 添加新合约 +2. 通过兼容适配器保留旧行为接线 +3. 发出诊断信息或警告,明确指出旧路径及替代方案 4. 在测试中覆盖两条路径 -5. 记录弃用信息和迁移路径 -6. 仅在已宣布的迁移窗口结束后移除,通常是在某个 major 版本中 +5. 记录弃用说明和迁移路径 +6. 仅在已宣布的迁移窗口结束后移除,通常是在主要版本中 -如果某个 manifest 字段仍被接受,那么在文档和诊断另有说明之前,插件作者可以继续使用它。新代码应优先使用文档中的替代方案,但现有插件不应在普通 minor 版本中被破坏。 +如果某个清单字段仍然被接受,插件作者就可以继续使用它,直到文档和诊断信息另有说明。新代码应优先使用文档中说明的替代方案,但现有插件不应在普通次要版本发布期间被破坏。 ## 如何迁移 - - 将仅限 Pi 的 `api.registerEmbeddedExtensionFactory(...)` 工具结果 + + 将仅限 Pi 的 `api.registerEmbeddedExtensionFactory(...)` tool-result 处理器替换为与 harness 无关的中间件。 ```typescript @@ -103,7 +90,7 @@ OpenClaw 不会在引入替代方案的同一次变更中移除或重新解释 }); ``` - 同时更新插件 manifest: + 同时更新插件清单: ```json { @@ -113,39 +100,29 @@ OpenClaw 不会在引入替代方案的同一次变更中移除或重新解释 } ``` - 仅当内置兼容代码仍然需要直接访问 Pi embedded-runner 事件时, - 才保留 `contracts.embeddedExtensionFactories`。 + 仅为仍然需要直接访问 Pi 嵌入式运行器事件的内置兼容代码保留 `contracts.embeddedExtensionFactories`。 - 具备审批能力的渠道插件现在通过 - `approvalCapability.nativeRuntime` 加上共享运行时上下文注册表来公开原生审批行为。 + 支持审批能力的渠道插件现在通过 `approvalCapability.nativeRuntime` 加上共享运行时上下文注册表,暴露原生审批行为。 关键变化: - - 将 `approvalCapability.handler.loadRuntime(...)` 替换为 - `approvalCapability.nativeRuntime` - - 将审批专用的认证 / 传递从旧版 `plugin.auth` / - `plugin.approvals` 线路迁移到 `approvalCapability` - - `ChannelPlugin.approvals` 已从公共渠道插件契约中移除; - 请将 delivery / native / render 字段迁移到 `approvalCapability` - - `plugin.auth` 仅保留给渠道登录 / 登出流程使用;其中的审批认证 - hooks 不再被核心读取 - - 通过 `openclaw/plugin-sdk/channel-runtime-context` - 注册渠道自有运行时对象,例如 clients、tokens 或 Bolt apps - - 不要从原生审批处理器发送插件自有的重路由通知; - 核心现在根据实际传递结果统一处理“已路由到其他位置”的通知 - - 将 `channelRuntime` 传递给 `createChannelManager(...)` 时,请提供真实的 - `createPluginRuntime().channel` 接口。不接受部分 stub。 + - 用 `approvalCapability.nativeRuntime` 替换 `approvalCapability.handler.loadRuntime(...)` + - 将审批专用的认证 / 投递逻辑从旧版 `plugin.auth` / `plugin.approvals` 接线迁移到 `approvalCapability` + - `ChannelPlugin.approvals` 已从公开的渠道插件合约中移除;请将 delivery / native / render 字段迁移到 `approvalCapability` + - `plugin.auth` 仅保留用于渠道登录 / 登出流程;核心不再读取其中的审批认证钩子 + - 通过 `openclaw/plugin-sdk/channel-runtime-context` 注册由渠道拥有的运行时对象,例如客户端、令牌或 Bolt 应用 + - 不要从原生审批处理器发送由插件拥有的重路由通知;核心现在会根据实际投递结果负责处理“已路由到其他位置”的通知 + - 在将 `channelRuntime` 传入 `createChannelManager(...)` 时,请提供真实的 `createPluginRuntime().channel` 接口面。部分桩实现会被拒绝。 - 当前的审批能力布局请参见 `/plugins/sdk-channel-plugins`。 + 请参阅 `/plugins/sdk-channel-plugins`,了解当前的审批能力布局。 - 如果你的插件使用 `openclaw/plugin-sdk/windows-spawn`,现在未解析的 Windows - `.cmd`/`.bat` wrapper 会以默认拒绝方式失败,除非你显式传入 `allowShellFallback: true`。 + 如果你的插件使用 `openclaw/plugin-sdk/windows-spawn`,现在在未解析的 Windows `.cmd`/`.bat` wrapper 情况下,系统会默认失败关闭,除非你显式传入 `allowShellFallback: true`。 ```typescript // Before @@ -160,13 +137,12 @@ OpenClaw 不会在引入替代方案的同一次变更中移除或重新解释 }); ``` - 如果你的调用方并不依赖 shell 回退,请不要设置 - `allowShellFallback`,而应改为处理抛出的错误。 + 如果你的调用方并非有意依赖 shell 回退,请不要设置 `allowShellFallback`,而应改为处理抛出的错误。 - 在你的插件中搜索来自任一已弃用接口的导入: + 在你的插件中搜索来自任一已弃用接口面的导入: ```bash grep -r "plugin-sdk/compat" my-plugin/ @@ -176,7 +152,7 @@ OpenClaw 不会在引入替代方案的同一次变更中移除或重新解释 - 旧接口中的每个导出都映射到一个特定的现代导入路径: + 旧接口面中的每个导出都映射到一个特定的现代导入路径: ```typescript // Before (deprecated backwards-compatibility layer) @@ -192,7 +168,7 @@ OpenClaw 不会在引入替代方案的同一次变更中移除或重新解释 import { resolveControlCommandGate } from "openclaw/plugin-sdk/command-auth"; ``` - 对于宿主侧辅助函数,请使用注入的插件运行时,而不是直接导入: + 对于宿主侧辅助工具,请使用注入的插件运行时,而不是直接导入: ```typescript // Before (deprecated extension-api bridge) @@ -203,9 +179,9 @@ OpenClaw 不会在引入替代方案的同一次变更中移除或重新解释 const result = await api.runtime.agent.runEmbeddedPiAgent({ sessionId, prompt }); ``` - 相同模式也适用于其他旧版桥接辅助函数: + 同样的模式也适用于其他旧版桥接辅助工具: - | 旧导入 | 现代等效项 | + | 旧导入 | 现代等价项 | | --- | --- | | `resolveAgentDir` | `api.runtime.agent.resolveAgentDir` | | `resolveAgentWorkspaceDir` | `api.runtime.agent.resolveAgentWorkspaceDir` | @@ -230,181 +206,182 @@ OpenClaw 不会在引入替代方案的同一次变更中移除或重新解释 | 导入路径 | 用途 | 关键导出 | | --- | --- | --- | - | `plugin-sdk/plugin-entry` | 规范的插件入口辅助函数 | `definePluginEntry` | + | `plugin-sdk/plugin-entry` | 规范的插件入口辅助工具 | `definePluginEntry` | | `plugin-sdk/core` | 用于渠道入口定义 / 构建器的旧版聚合重新导出 | `defineChannelPluginEntry`, `createChatChannelPlugin` | | `plugin-sdk/config-schema` | 根配置 schema 导出 | `OpenClawSchema` | - | `plugin-sdk/provider-entry` | 单提供商入口辅助函数 | `defineSingleProviderPluginEntry` | + | `plugin-sdk/provider-entry` | 单提供商入口辅助工具 | `defineSingleProviderPluginEntry` | | `plugin-sdk/channel-core` | 聚焦的渠道入口定义和构建器 | `defineChannelPluginEntry`, `defineSetupPluginEntry`, `createChatChannelPlugin`, `createChannelPluginBase` | - | `plugin-sdk/setup` | 共享设置向导辅助函数 | Allowlist 提示,设置状态构建器 | - | `plugin-sdk/setup-runtime` | 设置时运行时辅助函数 | 导入安全的设置补丁适配器、lookup-note 辅助函数、`promptResolvedAllowFrom`、`splitSetupEntries`、委托设置代理 | - | `plugin-sdk/setup-adapter-runtime` | 设置适配器辅助函数 | `createEnvPatchedAccountSetupAdapter` | - | `plugin-sdk/setup-tools` | 设置工具辅助函数 | `formatCliCommand`, `detectBinary`, `extractArchive`, `resolveBrewExecutable`, `formatDocsLink`, `CONFIG_DIR` | - | `plugin-sdk/account-core` | 多账户辅助函数 | 账户列表 / 配置 / action-gate 辅助函数 | - | `plugin-sdk/account-id` | account-id 辅助函数 | `DEFAULT_ACCOUNT_ID`,account-id 规范化 | - | `plugin-sdk/account-resolution` | 账户查找辅助函数 | 账户查找 + 默认回退辅助函数 | - | `plugin-sdk/account-helpers` | 窄范围账户辅助函数 | 账户列表 / account-action 辅助函数 | + | `plugin-sdk/setup` | 共享的设置向导辅助工具 | allowlist 提示、设置状态构建器 | + | `plugin-sdk/setup-runtime` | 设置阶段运行时辅助工具 | 导入安全的设置补丁适配器、lookup-note 辅助工具、`promptResolvedAllowFrom`、`splitSetupEntries`、委托设置代理 | + | `plugin-sdk/setup-adapter-runtime` | 设置适配器辅助工具 | `createEnvPatchedAccountSetupAdapter` | + | `plugin-sdk/setup-tools` | 设置工具辅助工具 | `formatCliCommand`, `detectBinary`, `extractArchive`, `resolveBrewExecutable`, `formatDocsLink`, `CONFIG_DIR` | + | `plugin-sdk/account-core` | 多账户辅助工具 | 账户列表 / 配置 / action-gate 辅助工具 | + | `plugin-sdk/account-id` | account-id 辅助工具 | `DEFAULT_ACCOUNT_ID`、account-id 规范化 | + | `plugin-sdk/account-resolution` | 账户查找辅助工具 | 账户查找 + 默认回退辅助工具 | + | `plugin-sdk/account-helpers` | 精简账户辅助工具 | 账户列表 / account-action 辅助工具 | | `plugin-sdk/channel-setup` | 设置向导适配器 | `createOptionalChannelSetupSurface`, `createOptionalChannelSetupAdapter`, `createOptionalChannelSetupWizard`,以及 `DEFAULT_ACCOUNT_ID`, `createTopLevelChannelDmPolicy`, `setSetupChannelEnabled`, `splitSetupEntries` | | `plugin-sdk/channel-pairing` | 私信配对原语 | `createChannelPairingController` | - | `plugin-sdk/channel-reply-pipeline` | 回复前缀 + 输入中 wiring | `createChannelReplyPipeline` | + | `plugin-sdk/channel-reply-pipeline` | 回复前缀 + 正在输入状态接线 | `createChannelReplyPipeline` | | `plugin-sdk/channel-config-helpers` | 配置适配器工厂 | `createHybridChannelConfigAdapter` | | `plugin-sdk/channel-config-schema` | 配置 schema 构建器 | 渠道配置 schema 类型 | - | `plugin-sdk/telegram-command-config` | Telegram 命令配置辅助函数 | 命令名规范化、描述裁剪、重复 / 冲突校验 | + | `plugin-sdk/telegram-command-config` | Telegram 命令配置辅助工具 | 命令名规范化、描述裁剪、重复 / 冲突校验 | | `plugin-sdk/channel-policy` | 群组 / 私信策略解析 | `resolveChannelGroupRequireMention` | - | `plugin-sdk/channel-lifecycle` | 账户状态和 draft 流生命周期辅助函数 | `createAccountStatusSink`,draft 预览完成辅助函数 | - | `plugin-sdk/inbound-envelope` | 入站 envelope 辅助函数 | 共享 route + envelope 构建器辅助函数 | - | `plugin-sdk/inbound-reply-dispatch` | 入站回复辅助函数 | 共享记录和分发辅助函数 | - | `plugin-sdk/messaging-targets` | 消息目标解析 | 目标解析 / 匹配辅助函数 | - | `plugin-sdk/outbound-media` | 出站媒体辅助函数 | 共享出站媒体加载 | - | `plugin-sdk/outbound-runtime` | 出站运行时辅助函数 | 出站身份 / 发送委托和负载规划辅助函数 | - | `plugin-sdk/thread-bindings-runtime` | 线程绑定辅助函数 | 线程绑定生命周期和适配器辅助函数 | - | `plugin-sdk/agent-media-payload` | 旧版媒体负载辅助函数 | 用于旧字段布局的智能体媒体负载构建器 | + | `plugin-sdk/channel-lifecycle` | 账户状态和草稿流生命周期辅助工具 | `createAccountStatusSink`、草稿预览最终化辅助工具 | + | `plugin-sdk/inbound-envelope` | 入站 envelope 辅助工具 | 共享路由 + envelope 构建器辅助工具 | + | `plugin-sdk/inbound-reply-dispatch` | 入站回复辅助工具 | 共享的 record-and-dispatch 辅助工具 | + | `plugin-sdk/messaging-targets` | 消息目标解析 | 目标解析 / 匹配辅助工具 | + | `plugin-sdk/outbound-media` | 出站媒体辅助工具 | 共享出站媒体加载 | + | `plugin-sdk/outbound-runtime` | 出站运行时辅助工具 | 出站身份 / 发送委托和负载规划辅助工具 | + | `plugin-sdk/thread-bindings-runtime` | 线程绑定辅助工具 | 线程绑定生命周期和适配器辅助工具 | + | `plugin-sdk/agent-media-payload` | 旧版媒体负载辅助工具 | 面向旧字段布局的智能体媒体负载构建器 | | `plugin-sdk/channel-runtime` | 已弃用的兼容性 shim | 仅限旧版渠道运行时工具 | | `plugin-sdk/channel-send-result` | 发送结果类型 | 回复结果类型 | | `plugin-sdk/runtime-store` | 持久化插件存储 | `createPluginRuntimeStore` | - | `plugin-sdk/runtime` | 宽范围运行时辅助函数 | 运行时 / 日志 / 备份 / 插件安装辅助函数 | - | `plugin-sdk/runtime-env` | 窄范围运行时环境辅助函数 | Logger / 运行时环境、超时、重试和退避辅助函数 | - | `plugin-sdk/plugin-runtime` | 共享插件运行时辅助函数 | 插件命令 / hooks / HTTP / 交互式辅助函数 | - | `plugin-sdk/hook-runtime` | hook 管道辅助函数 | 共享 webhook / 内部 hook 管道辅助函数 | - | `plugin-sdk/lazy-runtime` | 惰性运行时辅助函数 | `createLazyRuntimeModule`, `createLazyRuntimeMethod`, `createLazyRuntimeMethodBinder`, `createLazyRuntimeNamedExport`, `createLazyRuntimeSurface` | - | `plugin-sdk/process-runtime` | 进程辅助函数 | 共享 exec 辅助函数 | - | `plugin-sdk/cli-runtime` | CLI 运行时辅助函数 | 命令格式化、等待、版本辅助函数 | - | `plugin-sdk/gateway-runtime` | Gateway 网关辅助函数 | Gateway 网关客户端和渠道状态补丁辅助函数 | - | `plugin-sdk/config-runtime` | 配置辅助函数 | 配置加载 / 写入辅助函数 | - | `plugin-sdk/telegram-command-config` | Telegram 命令辅助函数 | 当内置 Telegram 契约接口不可用时,提供具备稳定回退能力的 Telegram 命令校验辅助函数 | - | `plugin-sdk/approval-runtime` | 审批提示辅助函数 | exec / 插件审批负载、审批能力 / 配置档辅助函数、原生审批路由 / 运行时辅助函数 | - | `plugin-sdk/approval-auth-runtime` | 审批认证辅助函数 | approver 解析、同聊天 action 认证 | - | `plugin-sdk/approval-client-runtime` | 审批客户端辅助函数 | 原生 exec 审批配置档 / 过滤辅助函数 | - | `plugin-sdk/approval-delivery-runtime` | 审批传递辅助函数 | 原生审批能力 / 传递适配器 | - | `plugin-sdk/approval-gateway-runtime` | 审批 Gateway 网关辅助函数 | 共享审批 Gateway 网关解析辅助函数 | - | `plugin-sdk/approval-handler-adapter-runtime` | 审批适配器辅助函数 | 用于热渠道入口点的轻量级原生审批适配器加载辅助函数 | - | `plugin-sdk/approval-handler-runtime` | 审批处理器辅助函数 | 更宽范围的审批处理器运行时辅助函数;如果更窄的 adapter / gateway 接口已足够,请优先使用它们 | - | `plugin-sdk/approval-native-runtime` | 审批目标辅助函数 | 原生审批目标 / 账户绑定辅助函数 | - | `plugin-sdk/approval-reply-runtime` | 审批回复辅助函数 | exec / 插件审批回复负载辅助函数 | - | `plugin-sdk/channel-runtime-context` | 渠道运行时上下文辅助函数 | 通用渠道运行时上下文 register / get / watch 辅助函数 | - | `plugin-sdk/security-runtime` | 安全辅助函数 | 共享信任、私信门控、外部内容和秘密收集辅助函数 | - | `plugin-sdk/ssrf-policy` | SSRF 策略辅助函数 | 主机 allowlist 和私有网络策略辅助函数 | - | `plugin-sdk/ssrf-runtime` | SSRF 运行时辅助函数 | pinned-dispatcher、受保护 fetch、SSRF 策略辅助函数 | - | `plugin-sdk/collection-runtime` | 有界缓存辅助函数 | `pruneMapToMaxSize` | - | `plugin-sdk/diagnostic-runtime` | 诊断门控辅助函数 | `isDiagnosticFlagEnabled`, `isDiagnosticsEnabled` | - | `plugin-sdk/error-runtime` | 错误格式化辅助函数 | `formatUncaughtError`, `isApprovalNotFoundError`,错误图辅助函数 | - | `plugin-sdk/fetch-runtime` | 封装的 fetch / 代理辅助函数 | `resolveFetch`,代理辅助函数 | - | `plugin-sdk/host-runtime` | 主机规范化辅助函数 | `normalizeHostname`, `normalizeScpRemoteHost` | - | `plugin-sdk/retry-runtime` | 重试辅助函数 | `RetryConfig`, `retryAsync`,策略运行器 | + | `plugin-sdk/runtime` | 宽泛的运行时辅助工具 | 运行时 / 日志 / 备份 / 插件安装辅助工具 | + | `plugin-sdk/runtime-env` | 精简的运行时环境辅助工具 | Logger / 运行时环境、超时、重试和退避辅助工具 | + | `plugin-sdk/plugin-runtime` | 共享插件运行时辅助工具 | 插件命令 / 钩子 / http / 交互式辅助工具 | + | `plugin-sdk/hook-runtime` | 钩子流水线辅助工具 | 共享 webhook / 内部钩子流水线辅助工具 | + | `plugin-sdk/lazy-runtime` | 惰性运行时辅助工具 | `createLazyRuntimeModule`, `createLazyRuntimeMethod`, `createLazyRuntimeMethodBinder`, `createLazyRuntimeNamedExport`, `createLazyRuntimeSurface` | + | `plugin-sdk/process-runtime` | 进程辅助工具 | 共享 exec 辅助工具 | + | `plugin-sdk/cli-runtime` | CLI 运行时辅助工具 | 命令格式化、等待、版本辅助工具 | + | `plugin-sdk/gateway-runtime` | Gateway 网关辅助工具 | Gateway 网关客户端和渠道状态补丁辅助工具 | + | `plugin-sdk/config-runtime` | 配置辅助工具 | 配置加载 / 写入辅助工具 | + | `plugin-sdk/telegram-command-config` | Telegram 命令辅助工具 | 当内置 Telegram 合约接口不可用时,提供具备稳定回退能力的 Telegram 命令校验辅助工具 | + | `plugin-sdk/approval-runtime` | 审批提示辅助工具 | exec / 插件审批负载、approval capability / profile 辅助工具、原生审批路由 / 运行时辅助工具 | + | `plugin-sdk/approval-auth-runtime` | 审批认证辅助工具 | approver 解析、同聊天 action 认证 | + | `plugin-sdk/approval-client-runtime` | 审批客户端辅助工具 | 原生 exec 审批 profile / filter 辅助工具 | + | `plugin-sdk/approval-delivery-runtime` | 审批投递辅助工具 | 原生 approval capability / delivery 适配器 | + | `plugin-sdk/approval-gateway-runtime` | 审批 Gateway 网关辅助工具 | 共享审批 Gateway 网关解析辅助工具 | + | `plugin-sdk/approval-handler-adapter-runtime` | 审批适配器辅助工具 | 用于热渠道入口点的轻量级原生审批适配器加载辅助工具 | + | `plugin-sdk/approval-handler-runtime` | 审批处理器辅助工具 | 更宽泛的审批处理器运行时辅助工具;如果更精简的 adapter / gateway 接口已足够,优先使用它们 | + | `plugin-sdk/approval-native-runtime` | 审批目标辅助工具 | 原生审批目标 / 账户绑定辅助工具 | + | `plugin-sdk/approval-reply-runtime` | 审批回复辅助工具 | exec / 插件审批回复负载辅助工具 | + | `plugin-sdk/channel-runtime-context` | 渠道运行时上下文辅助工具 | 通用渠道运行时上下文 register / get / watch 辅助工具 | + | `plugin-sdk/security-runtime` | 安全辅助工具 | 共享信任、私信门控、外部内容和密钥收集辅助工具 | + | `plugin-sdk/ssrf-policy` | SSRF 策略辅助工具 | 主机 allowlist 和私有网络策略辅助工具 | + | `plugin-sdk/ssrf-runtime` | SSRF 运行时辅助工具 | pinned-dispatcher、guarded fetch、SSRF 策略辅助工具 | + | `plugin-sdk/collection-runtime` | 有界缓存辅助工具 | `pruneMapToMaxSize` | + | `plugin-sdk/diagnostic-runtime` | 诊断门控辅助工具 | `isDiagnosticFlagEnabled`, `isDiagnosticsEnabled` | + | `plugin-sdk/error-runtime` | 错误格式化辅助工具 | `formatUncaughtError`, `isApprovalNotFoundError`、错误图辅助工具 | + | `plugin-sdk/fetch-runtime` | 封装 fetch / 代理辅助工具 | `resolveFetch`、代理辅助工具 | + | `plugin-sdk/host-runtime` | 主机规范化辅助工具 | `normalizeHostname`, `normalizeScpRemoteHost` | + | `plugin-sdk/retry-runtime` | 重试辅助工具 | `RetryConfig`, `retryAsync`、策略运行器 | | `plugin-sdk/allow-from` | allowlist 格式化 | `formatAllowFromLowercase` | | `plugin-sdk/allowlist-resolution` | allowlist 输入映射 | `mapAllowlistResolutionInputs` | - | `plugin-sdk/command-auth` | 命令门控和命令接口辅助函数 | `resolveControlCommandGate`,发送者授权辅助函数,命令注册表辅助函数 | + | `plugin-sdk/command-auth` | 命令门控和命令接口辅助工具 | `resolveControlCommandGate`、发送者授权辅助工具、命令注册表辅助工具 | | `plugin-sdk/command-status` | 命令状态 / 帮助渲染器 | `buildCommandsMessage`, `buildCommandsMessagePaginated`, `buildHelpMessage` | - | `plugin-sdk/secret-input` | 秘密输入解析 | 秘密输入辅助函数 | - | `plugin-sdk/webhook-ingress` | webhook 请求辅助函数 | webhook 目标工具 | - | `plugin-sdk/webhook-request-guards` | webhook 请求体守卫辅助函数 | 请求体读取 / 限制辅助函数 | - | `plugin-sdk/reply-runtime` | 共享回复运行时 | 入站分发、heartbeat、回复规划器、分块 | - | `plugin-sdk/reply-dispatch-runtime` | 窄范围回复分发辅助函数 | 完成、提供商分发和会话标签辅助函数 | - | `plugin-sdk/reply-history` | 回复历史辅助函数 | `buildHistoryContext`, `buildPendingHistoryContextFromMap`, `recordPendingHistoryEntry`, `clearHistoryEntriesIfEnabled` | + | `plugin-sdk/secret-input` | 密钥输入解析 | 密钥输入辅助工具 | + | `plugin-sdk/webhook-ingress` | webhook 请求辅助工具 | webhook 目标工具 | + | `plugin-sdk/webhook-request-guards` | webhook 请求体保护辅助工具 | 请求体读取 / 限制辅助工具 | + | `plugin-sdk/reply-runtime` | 共享回复运行时 | 入站分发、心跳、回复规划器、分块 | + | `plugin-sdk/reply-dispatch-runtime` | 精简回复分发辅助工具 | finalization、provider 分发和会话标签辅助工具 | + | `plugin-sdk/reply-history` | 回复历史辅助工具 | `buildHistoryContext`, `buildPendingHistoryContextFromMap`, `recordPendingHistoryEntry`, `clearHistoryEntriesIfEnabled` | | `plugin-sdk/reply-reference` | 回复引用规划 | `createReplyReferencePlanner` | - | `plugin-sdk/reply-chunking` | 回复分块辅助函数 | 文本 / markdown 分块辅助函数 | - | `plugin-sdk/session-store-runtime` | 会话存储辅助函数 | 存储路径 + updated-at 辅助函数 | - | `plugin-sdk/state-paths` | 状态路径辅助函数 | 状态和 OAuth 目录辅助函数 | - | `plugin-sdk/routing` | 路由 / session-key 辅助函数 | `resolveAgentRoute`, `buildAgentSessionKey`, `resolveDefaultAgentBoundAccountId`,session-key 规范化辅助函数 | - | `plugin-sdk/status-helpers` | 渠道状态辅助函数 | 渠道 / 账户状态摘要构建器、运行时状态默认值、问题元数据辅助函数 | - | `plugin-sdk/target-resolver-runtime` | 目标解析器辅助函数 | 共享目标解析器辅助函数 | - | `plugin-sdk/string-normalization-runtime` | 字符串规范化辅助函数 | slug / 字符串规范化辅助函数 | - | `plugin-sdk/request-url` | 请求 URL 辅助函数 | 从类似请求的输入中提取字符串 URL | - | `plugin-sdk/run-command` | 定时命令辅助函数 | 带规范化 stdout / stderr 的定时命令运行器 | + | `plugin-sdk/reply-chunking` | 回复分块辅助工具 | 文本 / markdown 分块辅助工具 | + | `plugin-sdk/session-store-runtime` | 会话存储辅助工具 | 存储路径 + updated-at 辅助工具 | + | `plugin-sdk/state-paths` | 状态路径辅助工具 | 状态和 OAuth 目录辅助工具 | + | `plugin-sdk/routing` | 路由 / session-key 辅助工具 | `resolveAgentRoute`, `buildAgentSessionKey`, `resolveDefaultAgentBoundAccountId`、session-key 规范化辅助工具 | + | `plugin-sdk/status-helpers` | 渠道状态辅助工具 | 渠道 / 账户状态摘要构建器、运行时状态默认值、问题元数据辅助工具 | + | `plugin-sdk/target-resolver-runtime` | 目标解析器辅助工具 | 共享目标解析器辅助工具 | + | `plugin-sdk/string-normalization-runtime` | 字符串规范化辅助工具 | slug / 字符串规范化辅助工具 | + | `plugin-sdk/request-url` | 请求 URL 辅助工具 | 从类似请求的输入中提取字符串 URL | + | `plugin-sdk/run-command` | 定时命令辅助工具 | 带规范化 stdout / stderr 的定时命令运行器 | | `plugin-sdk/param-readers` | 参数读取器 | 通用工具 / CLI 参数读取器 | | `plugin-sdk/tool-payload` | 工具负载提取 | 从工具结果对象中提取规范化负载 | | `plugin-sdk/tool-send` | 工具发送提取 | 从工具参数中提取规范的发送目标字段 | - | `plugin-sdk/temp-path` | 临时路径辅助函数 | 共享临时下载路径辅助函数 | - | `plugin-sdk/logging-core` | 日志辅助函数 | 子系统 logger 和脱敏辅助函数 | - | `plugin-sdk/markdown-table-runtime` | Markdown 表格辅助函数 | Markdown 表格模式辅助函数 | + | `plugin-sdk/temp-path` | 临时路径辅助工具 | 共享临时下载路径辅助工具 | + | `plugin-sdk/logging-core` | 日志辅助工具 | 子系统 logger 和脱敏辅助工具 | + | `plugin-sdk/markdown-table-runtime` | Markdown 表格辅助工具 | Markdown 表格模式辅助工具 | | `plugin-sdk/reply-payload` | 消息回复类型 | 回复负载类型 | - | `plugin-sdk/provider-setup` | 精选的本地 / 自托管提供商设置辅助函数 | 自托管提供商发现 / 配置辅助函数 | - | `plugin-sdk/self-hosted-provider-setup` | 聚焦的 OpenAI 兼容自托管提供商设置辅助函数 | 同一组自托管提供商发现 / 配置辅助函数 | - | `plugin-sdk/provider-auth-runtime` | 提供商运行时认证辅助函数 | 运行时 API 密钥解析辅助函数 | - | `plugin-sdk/provider-auth-api-key` | 提供商 API 密钥设置辅助函数 | API 密钥新手引导 / 配置档写入辅助函数 | - | `plugin-sdk/provider-auth-result` | 提供商认证结果辅助函数 | 标准 OAuth 认证结果构建器 | - | `plugin-sdk/provider-auth-login` | 提供商交互式登录辅助函数 | 共享交互式登录辅助函数 | - | `plugin-sdk/provider-selection-runtime` | 提供商选择辅助函数 | 已配置或自动提供商选择,以及原始提供商配置合并 | - | `plugin-sdk/provider-env-vars` | 提供商环境变量辅助函数 | 提供商认证环境变量查找辅助函数 | - | `plugin-sdk/provider-model-shared` | 共享提供商模型 / 重放辅助函数 | `ProviderReplayFamily`, `buildProviderReplayFamilyHooks`, `normalizeModelCompat`,共享重放策略构建器、提供商端点辅助函数,以及 model-id 规范化辅助函数 | - | `plugin-sdk/provider-catalog-shared` | 共享提供商目录辅助函数 | `findCatalogTemplate`, `buildSingleProviderApiKeyCatalog`, `supportsNativeStreamingUsageCompat`, `applyProviderNativeStreamingUsageCompat` | - | `plugin-sdk/provider-onboard` | 提供商新手引导补丁 | 新手引导配置辅助函数 | - | `plugin-sdk/provider-http` | 提供商 HTTP 辅助函数 | 通用提供商 HTTP / 端点能力辅助函数,包括音频转录 multipart form 辅助函数 | - | `plugin-sdk/provider-web-fetch` | 提供商 web 获取辅助函数 | web 获取提供商注册 / 缓存辅助函数 | - | `plugin-sdk/provider-web-search-config-contract` | 提供商 web 搜索配置辅助函数 | 适用于不需要插件启用线路的提供商的窄范围 web 搜索配置 / 凭证辅助函数 | - | `plugin-sdk/provider-web-search-contract` | 提供商 web 搜索契约辅助函数 | 窄范围 web 搜索配置 / 凭证契约辅助函数,例如 `createWebSearchProviderContractFields`、`enablePluginInConfig`、`resolveProviderWebSearchPluginConfig`,以及带作用域的凭证 setter / getter | - | `plugin-sdk/provider-web-search` | 提供商 web 搜索辅助函数 | web 搜索提供商注册 / 缓存 / 运行时辅助函数 | - | `plugin-sdk/provider-tools` | 提供商工具 / schema 兼容辅助函数 | `ProviderToolCompatFamily`, `buildProviderToolCompatFamilyHooks`, Gemini schema 清理 + 诊断,以及 xAI 兼容辅助函数,如 `resolveXaiModelCompatPatch` / `applyXaiModelCompat` | - | `plugin-sdk/provider-usage` | 提供商使用量辅助函数 | `fetchClaudeUsage`, `fetchGeminiUsage`, `fetchGithubCopilotUsage`,以及其他提供商使用量辅助函数 | - | `plugin-sdk/provider-stream` | 提供商流包装辅助函数 | `ProviderStreamFamily`, `buildProviderStreamFamilyHooks`, `composeProviderStreamWrappers`、流包装器类型,以及共享的 Anthropic / Bedrock / Google / Kilocode / Moonshot AI / OpenAI / OpenRouter / Z.A.I / MiniMax / Copilot 包装辅助函数 | - | `plugin-sdk/provider-transport-runtime` | 提供商传输辅助函数 | 原生提供商传输辅助函数,例如受保护 fetch、传输消息转换和可写传输事件流 | + | `plugin-sdk/provider-setup` | 精选的本地 / 自托管 provider 设置辅助工具 | 自托管 provider 发现 / 配置辅助工具 | + | `plugin-sdk/self-hosted-provider-setup` | 聚焦的 OpenAI 兼容自托管 provider 设置辅助工具 | 同一组自托管 provider 发现 / 配置辅助工具 | + | `plugin-sdk/provider-auth-runtime` | provider 运行时认证辅助工具 | 运行时 API key 解析辅助工具 | + | `plugin-sdk/provider-auth-api-key` | provider API key 设置辅助工具 | API key 新手引导 / profile 写入辅助工具 | + | `plugin-sdk/provider-auth-result` | provider auth-result 辅助工具 | 标准 OAuth auth-result 构建器 | + | `plugin-sdk/provider-auth-login` | provider 交互式登录辅助工具 | 共享交互式登录辅助工具 | + | `plugin-sdk/provider-selection-runtime` | provider 选择辅助工具 | 已配置或自动 provider 选择,以及原始 provider 配置合并 | + | `plugin-sdk/provider-env-vars` | provider 环境变量辅助工具 | provider 认证环境变量查找辅助工具 | + | `plugin-sdk/provider-model-shared` | 共享 provider 模型 / replay 辅助工具 | `ProviderReplayFamily`, `buildProviderReplayFamilyHooks`, `normalizeModelCompat`、共享 replay-policy 构建器、provider endpoint 辅助工具,以及 model-id 规范化辅助工具 | + | `plugin-sdk/provider-catalog-shared` | 共享 provider 目录辅助工具 | `findCatalogTemplate`, `buildSingleProviderApiKeyCatalog`, `supportsNativeStreamingUsageCompat`, `applyProviderNativeStreamingUsageCompat` | + | `plugin-sdk/provider-onboard` | provider 新手引导补丁 | 新手引导配置辅助工具 | + | `plugin-sdk/provider-http` | provider HTTP 辅助工具 | 通用 provider HTTP / endpoint capability 辅助工具,包括音频转录 multipart form 辅助工具 | + | `plugin-sdk/provider-web-fetch` | provider web-fetch 辅助工具 | web-fetch provider 注册 / 缓存辅助工具 | + | `plugin-sdk/provider-web-search-config-contract` | provider web-search 配置辅助工具 | 面向不需要插件启用接线的 provider 的精简 web-search 配置 / 凭证辅助工具 | + | `plugin-sdk/provider-web-search-contract` | provider web-search 合约辅助工具 | 精简 web-search 配置 / 凭证合约辅助工具,例如 `createWebSearchProviderContractFields`、`enablePluginInConfig`、`resolveProviderWebSearchPluginConfig`,以及带作用域的凭证 setter / getter | + | `plugin-sdk/provider-web-search` | provider web-search 辅助工具 | web-search provider 注册 / 缓存 / 运行时辅助工具 | + | `plugin-sdk/provider-tools` | provider 工具 / schema 兼容辅助工具 | `ProviderToolCompatFamily`, `buildProviderToolCompatFamilyHooks`、Gemini schema 清理 + 诊断,以及 xAI 兼容辅助工具,例如 `resolveXaiModelCompatPatch` / `applyXaiModelCompat` | + | `plugin-sdk/provider-usage` | provider 用量辅助工具 | `fetchClaudeUsage`, `fetchGeminiUsage`, `fetchGithubCopilotUsage` 以及其他 provider 用量辅助工具 | + | `plugin-sdk/provider-stream` | provider 流包装辅助工具 | `ProviderStreamFamily`, `buildProviderStreamFamilyHooks`, `composeProviderStreamWrappers`、流包装类型,以及共享的 Anthropic / Bedrock / Google / Kilocode / Moonshot / OpenAI / OpenRouter / Z.A.I / MiniMax / Copilot 包装辅助工具 | + | `plugin-sdk/provider-transport-runtime` | provider 传输辅助工具 | 原生 provider 传输辅助工具,例如 guarded fetch、传输消息转换和可写传输事件流 | | `plugin-sdk/keyed-async-queue` | 有序异步队列 | `KeyedAsyncQueue` | - | `plugin-sdk/media-runtime` | 共享媒体辅助函数 | 媒体获取 / 转换 / 存储辅助函数以及媒体负载构建器 | - | `plugin-sdk/media-generation-runtime` | 共享媒体生成辅助函数 | 图像 / 视频 / 音乐生成的共享故障转移辅助函数、候选项选择和缺失模型消息 | - | `plugin-sdk/media-understanding` | 媒体理解辅助函数 | 媒体理解提供商类型,以及面向提供商的图像 / 音频辅助函数导出 | - | `plugin-sdk/text-runtime` | 共享文本辅助函数 | 面向助手可见文本剥离、markdown 渲染 / 分块 / 表格辅助函数、脱敏辅助函数、directive-tag 辅助函数、安全文本工具,以及相关文本 / 日志辅助函数 | - | `plugin-sdk/text-chunking` | 文本分块辅助函数 | 出站文本分块辅助函数 | - | `plugin-sdk/speech` | 语音辅助函数 | 语音提供商类型,以及面向提供商的 directive、registry 和校验辅助函数 | - | `plugin-sdk/speech-core` | 共享语音核心 | 语音提供商类型、registry、directives、规范化 | - | `plugin-sdk/realtime-transcription` | 实时转录辅助函数 | 提供商类型、registry 辅助函数和共享 WebSocket 会话辅助函数 | - | `plugin-sdk/realtime-voice` | 实时语音辅助函数 | 提供商类型、registry / 解析辅助函数和桥接会话辅助函数 | - | `plugin-sdk/image-generation-core` | 共享图像生成核心 | 图像生成类型、故障转移、认证和 registry 辅助函数 | - | `plugin-sdk/music-generation` | 音乐生成辅助函数 | 音乐生成提供商 / 请求 / 结果类型 | - | `plugin-sdk/music-generation-core` | 共享音乐生成核心 | 音乐生成类型、故障转移辅助函数、提供商查找和 model-ref 解析 | - | `plugin-sdk/video-generation` | 视频生成辅助函数 | 视频生成提供商 / 请求 / 结果类型 | - | `plugin-sdk/video-generation-core` | 共享视频生成核心 | 视频生成类型、故障转移辅助函数、提供商查找和 model-ref 解析 | - | `plugin-sdk/interactive-runtime` | 交互式回复辅助函数 | 交互式回复负载规范化 / 规约 | - | `plugin-sdk/channel-config-primitives` | 渠道配置原语 | 窄范围渠道 config-schema 原语 | - | `plugin-sdk/channel-config-writes` | 渠道配置写入辅助函数 | 渠道配置写入授权辅助函数 | + | `plugin-sdk/media-runtime` | 共享媒体辅助工具 | 媒体获取 / 转换 / 存储辅助工具,以及媒体负载构建器 | + | `plugin-sdk/media-generation-runtime` | 共享媒体生成辅助工具 | 面向图像 / 视频 / 音乐生成的共享故障转移辅助工具、候选项选择和缺失模型提示 | + | `plugin-sdk/media-understanding` | 媒体理解辅助工具 | 媒体理解 provider 类型,以及面向 provider 的图像 / 音频辅助工具导出 | + | `plugin-sdk/text-runtime` | 共享文本辅助工具 | 面向助手可见文本剥离、markdown 渲染 / 分块 / 表格辅助工具、脱敏辅助工具、directive-tag 辅助工具、安全文本工具以及相关文本 / 日志辅助工具 | + | `plugin-sdk/text-chunking` | 文本分块辅助工具 | 出站文本分块辅助工具 | + | `plugin-sdk/speech` | 语音辅助工具 | 语音 provider 类型,以及面向 provider 的 directive、注册表和校验辅助工具 | + | `plugin-sdk/speech-core` | 共享语音核心 | 语音 provider 类型、注册表、directives、规范化 | + | `plugin-sdk/realtime-transcription` | 实时转录辅助工具 | provider 类型、注册表辅助工具和共享 WebSocket 会话辅助工具 | + | `plugin-sdk/realtime-voice` | 实时语音辅助工具 | provider 类型、注册表 / 解析辅助工具和桥接会话辅助工具 | + | `plugin-sdk/image-generation-core` | 共享图像生成核心 | 图像生成类型、故障转移、认证和注册表辅助工具 | + | `plugin-sdk/music-generation` | 音乐生成辅助工具 | 音乐生成 provider / 请求 / 结果类型 | + | `plugin-sdk/music-generation-core` | 共享音乐生成核心 | 音乐生成类型、故障转移辅助工具、provider 查找和 model-ref 解析 | + | `plugin-sdk/video-generation` | 视频生成辅助工具 | 视频生成 provider / 请求 / 结果类型 | + | `plugin-sdk/video-generation-core` | 共享视频生成核心 | 视频生成类型、故障转移辅助工具、provider 查找和 model-ref 解析 | + | `plugin-sdk/interactive-runtime` | 交互式回复辅助工具 | 交互式回复负载规范化 / 归约 | + | `plugin-sdk/channel-config-primitives` | 渠道配置原语 | 精简的渠道 config-schema 原语 | + | `plugin-sdk/channel-config-writes` | 渠道配置写入辅助工具 | 渠道配置写入授权辅助工具 | | `plugin-sdk/channel-plugin-common` | 共享渠道前导模块 | 共享渠道插件前导导出 | - | `plugin-sdk/channel-status` | 渠道状态辅助函数 | 共享渠道状态快照 / 摘要辅助函数 | - | `plugin-sdk/allowlist-config-edit` | allowlist 配置辅助函数 | allowlist 配置编辑 / 读取辅助函数 | - | `plugin-sdk/group-access` | 群组访问辅助函数 | 共享群组访问决策辅助函数 | - | `plugin-sdk/direct-dm` | 直接私信辅助函数 | 共享直接私信认证 / 守卫辅助函数 | - | `plugin-sdk/extension-shared` | 共享扩展辅助函数 | 被动渠道 / 状态和环境代理辅助原语 | - | `plugin-sdk/webhook-targets` | webhook 目标辅助函数 | webhook 目标注册表和路由安装辅助函数 | - | `plugin-sdk/webhook-path` | webhook 路径辅助函数 | webhook 路径规范化辅助函数 | - | `plugin-sdk/web-media` | 共享 web 媒体辅助函数 | 远程 / 本地媒体加载辅助函数 | - | `plugin-sdk/zod` | Zod 重新导出 | 面向插件 SDK 使用者重新导出的 `zod` | - | `plugin-sdk/memory-core` | 内置 memory-core 辅助函数 | Memory 管理器 / 配置 / 文件 / CLI 辅助接口 | - | `plugin-sdk/memory-core-engine-runtime` | Memory 引擎运行时外观层 | Memory 索引 / 搜索运行时外观层 | + | `plugin-sdk/channel-status` | 渠道状态辅助工具 | 共享渠道状态快照 / 摘要辅助工具 | + | `plugin-sdk/allowlist-config-edit` | allowlist 配置辅助工具 | allowlist 配置编辑 / 读取辅助工具 | + | `plugin-sdk/group-access` | 群组访问辅助工具 | 共享群组访问决策辅助工具 | + | `plugin-sdk/direct-dm` | 直接私信辅助工具 | 共享直接私信认证 / 保护辅助工具 | + | `plugin-sdk/extension-shared` | 共享扩展辅助工具 | 被动渠道 / 状态和环境代理辅助工具原语 | + | `plugin-sdk/webhook-targets` | webhook 目标辅助工具 | webhook 目标注册表和路由安装辅助工具 | + | `plugin-sdk/webhook-path` | webhook 路径辅助工具 | webhook 路径规范化辅助工具 | + | `plugin-sdk/web-media` | 共享 Web 媒体辅助工具 | 远程 / 本地媒体加载辅助工具 | + | `plugin-sdk/zod` | Zod 重新导出 | 为插件 SDK 使用方重新导出的 `zod` | + | `plugin-sdk/memory-core` | 内置 memory-core 辅助工具 | Memory 管理器 / 配置 / 文件 / CLI 辅助工具接口 | + | `plugin-sdk/memory-core-engine-runtime` | Memory 引擎运行时门面 | Memory 索引 / 搜索运行时门面 | | `plugin-sdk/memory-core-host-engine-foundation` | Memory 宿主基础引擎 | Memory 宿主基础引擎导出 | - | `plugin-sdk/memory-core-host-engine-embeddings` | Memory 宿主嵌入引擎 | Memory 嵌入契约、registry 访问、本地提供商和通用批处理 / 远程辅助函数;具体远程提供商位于其所属插件中 | + | `plugin-sdk/memory-core-host-engine-embeddings` | Memory 宿主嵌入引擎 | Memory 嵌入合约、注册表访问、本地 provider 以及通用批处理 / 远程辅助工具;具体远程 provider 位于各自所属插件中 | | `plugin-sdk/memory-core-host-engine-qmd` | Memory 宿主 QMD 引擎 | Memory 宿主 QMD 引擎导出 | | `plugin-sdk/memory-core-host-engine-storage` | Memory 宿主存储引擎 | Memory 宿主存储引擎导出 | - | `plugin-sdk/memory-core-host-multimodal` | Memory 宿主多模态辅助函数 | Memory 宿主多模态辅助函数 | - | `plugin-sdk/memory-core-host-query` | Memory 宿主查询辅助函数 | Memory 宿主查询辅助函数 | - | `plugin-sdk/memory-core-host-secret` | Memory 宿主秘密辅助函数 | Memory 宿主秘密辅助函数 | - | `plugin-sdk/memory-core-host-events` | Memory 宿主事件日志辅助函数 | Memory 宿主事件日志辅助函数 | - | `plugin-sdk/memory-core-host-status` | Memory 宿主状态辅助函数 | Memory 宿主状态辅助函数 | - | `plugin-sdk/memory-core-host-runtime-cli` | Memory 宿主 CLI 运行时 | Memory 宿主 CLI 运行时辅助函数 | - | `plugin-sdk/memory-core-host-runtime-core` | Memory 宿主核心运行时 | Memory 宿主核心运行时辅助函数 | - | `plugin-sdk/memory-core-host-runtime-files` | Memory 宿主文件 / 运行时辅助函数 | Memory 宿主文件 / 运行时辅助函数 | - | `plugin-sdk/memory-host-core` | Memory 宿主核心运行时别名 | 面向供应商中立的 Memory 宿主核心运行时辅助函数别名 | - | `plugin-sdk/memory-host-events` | Memory 宿主事件日志别名 | 面向供应商中立的 Memory 宿主事件日志辅助函数别名 | - | `plugin-sdk/memory-host-files` | Memory 宿主文件 / 运行时别名 | 面向供应商中立的 Memory 宿主文件 / 运行时辅助函数别名 | - | `plugin-sdk/memory-host-markdown` | 托管 markdown 辅助函数 | 用于 memory 邻接插件的共享托管 markdown 辅助函数 | - | `plugin-sdk/memory-host-search` | 活跃 Memory 搜索外观层 | 惰性 active-memory search-manager 运行时外观层 | - | `plugin-sdk/memory-host-status` | Memory 宿主状态别名 | 面向供应商中立的 Memory 宿主状态辅助函数别名 | - | `plugin-sdk/memory-lancedb` | 内置 memory-lancedb 辅助函数 | Memory-lancedb 辅助接口 | - | `plugin-sdk/testing` | 测试工具 | 测试辅助函数和 mocks | + | `plugin-sdk/memory-core-host-multimodal` | Memory 宿主多模态辅助工具 | Memory 宿主多模态辅助工具 | + | `plugin-sdk/memory-core-host-query` | Memory 宿主查询辅助工具 | Memory 宿主查询辅助工具 | + | `plugin-sdk/memory-core-host-secret` | Memory 宿主密钥辅助工具 | Memory 宿主密钥辅助工具 | + | `plugin-sdk/memory-core-host-events` | Memory 宿主事件日志辅助工具 | Memory 宿主事件日志辅助工具 | + | `plugin-sdk/memory-core-host-status` | Memory 宿主状态辅助工具 | Memory 宿主状态辅助工具 | + | `plugin-sdk/memory-core-host-runtime-cli` | Memory 宿主 CLI 运行时 | Memory 宿主 CLI 运行时辅助工具 | + | `plugin-sdk/memory-core-host-runtime-core` | Memory 宿主核心运行时 | Memory 宿主核心运行时辅助工具 | + | `plugin-sdk/memory-core-host-runtime-files` | Memory 宿主文件 / 运行时辅助工具 | Memory 宿主文件 / 运行时辅助工具 | + | `plugin-sdk/memory-host-core` | Memory 宿主核心运行时别名 | 面向 vendor 中立的 Memory 宿主核心运行时辅助工具别名 | + | `plugin-sdk/memory-host-events` | Memory 宿主事件日志别名 | 面向 vendor 中立的 Memory 宿主事件日志辅助工具别名 | + | `plugin-sdk/memory-host-files` | Memory 宿主文件 / 运行时别名 | 面向 vendor 中立的 Memory 宿主文件 / 运行时辅助工具别名 | + | `plugin-sdk/memory-host-markdown` | 托管 markdown 辅助工具 | 面向 Memory 邻接插件的共享托管 markdown 辅助工具 | + | `plugin-sdk/memory-host-search` | 活跃 Memory 搜索门面 | 惰性活跃 Memory 搜索管理器运行时门面 | + | `plugin-sdk/memory-host-status` | Memory 宿主状态别名 | 面向 vendor 中立的 Memory 宿主状态辅助工具别名 | + | `plugin-sdk/memory-lancedb` | 内置 memory-lancedb 辅助工具 | Memory-lancedb 辅助工具接口 | + | `plugin-sdk/testing` | 测试工具 | 测试辅助工具和 mocks | -此表刻意只包含常见迁移子集,而不是完整的 SDK -接口。完整的 200+ 个入口点列表位于 +该表特意只包含常见迁移子集,而不是完整的 SDK +接口。完整的 200 多个入口点列表位于 `scripts/lib/plugin-sdk-entrypoints.json`。 -该列表仍包含一些内置插件辅助接口,例如 +该列表仍然包含一些内置插件辅助接口,例如 `plugin-sdk/feishu`、`plugin-sdk/feishu-setup`、`plugin-sdk/zalo`、 -`plugin-sdk/zalo-setup` 和 `plugin-sdk/matrix*`。这些接口仍会继续导出, -以支持内置插件维护和兼容性,但它们被有意排除在常见迁移表之外,也不是新插件代码的推荐目标。 +`plugin-sdk/zalo-setup` 和 `plugin-sdk/matrix*`。这些接口仍然会继续导出, +用于内置插件维护和兼容性,但它们被有意省略在常见迁移表之外,也不是 +新插件代码推荐使用的目标。 -同样的规则也适用于其他内置辅助接口族,例如: +同样的规则也适用于其他内置辅助工具族,例如: -- 浏览器支持辅助函数:`plugin-sdk/browser-cdp`、`plugin-sdk/browser-config-runtime`、`plugin-sdk/browser-config-support`、`plugin-sdk/browser-control-auth`、`plugin-sdk/browser-node-runtime`、`plugin-sdk/browser-profiles`、`plugin-sdk/browser-security-runtime`、`plugin-sdk/browser-setup-tools`、`plugin-sdk/browser-support` +- 浏览器支持辅助工具:`plugin-sdk/browser-cdp`、`plugin-sdk/browser-config-runtime`、`plugin-sdk/browser-config-support`、`plugin-sdk/browser-control-auth`、`plugin-sdk/browser-node-runtime`、`plugin-sdk/browser-profiles`、`plugin-sdk/browser-security-runtime`、`plugin-sdk/browser-setup-tools`、`plugin-sdk/browser-support` - Matrix:`plugin-sdk/matrix*` - LINE:`plugin-sdk/line*` - IRC:`plugin-sdk/irc*` -- 内置辅助 / 插件接口,例如 `plugin-sdk/googlechat`、 +- 内置辅助工具 / 插件接口,例如 `plugin-sdk/googlechat`、 `plugin-sdk/zalouser`、`plugin-sdk/bluebubbles*`、 `plugin-sdk/mattermost*`、`plugin-sdk/msteams`、 `plugin-sdk/nextcloud-talk`、`plugin-sdk/nostr`、`plugin-sdk/tlon`、 @@ -413,32 +390,240 @@ OpenClaw 不会在引入替代方案的同一次变更中移除或重新解释 `plugin-sdk/diagnostics-otel`、`plugin-sdk/diffs`、`plugin-sdk/llm-task`、 `plugin-sdk/thread-ownership` 和 `plugin-sdk/voice-call` -`plugin-sdk/github-copilot-token` 当前公开的窄范围 token 辅助接口为 -`DEFAULT_COPILOT_API_BASE_URL`、 +`plugin-sdk/github-copilot-token` 目前暴露了精简的 token 辅助工具 +接口 `DEFAULT_COPILOT_API_BASE_URL`、 `deriveCopilotApiBaseUrlFromToken` 和 `resolveCopilotApiToken`。 -请使用与任务最匹配的最窄导入路径。如果你找不到某个导出,请查看 -`src/plugin-sdk/` 中的源码,或在 Discord 中提问。 +请使用与任务最匹配的最精简导入。如果你找不到某个导出, +请查看 `src/plugin-sdk/` 下的源码,或在 Discord 中询问。 + +## 当前弃用项 + +以下是适用于整个插件 SDK、provider 合约、 +运行时接口和清单的更精细弃用项。它们目前仍然可用,但将在未来的主要版本中移除。 +每项下方的条目都将旧 API 映射到其规范替代方案。 + + + + **旧版(`openclaw/plugin-sdk/command-auth`)**:`buildCommandsMessage`、 + `buildCommandsMessagePaginated`、`buildHelpMessage`。 + + **新版(`openclaw/plugin-sdk/command-status`)**:签名相同,导出也相同——只是改为从更精简的子路径导入。`command-auth` + 会将它们作为兼容 stub 重新导出。 + + ```typescript + // Before + import { buildHelpMessage } from "openclaw/plugin-sdk/command-auth"; + + // After + import { buildHelpMessage } from "openclaw/plugin-sdk/command-status"; + ``` + + + + + **旧版**:`resolveInboundMentionRequirement({ facts, policy })` 和 + `shouldDropInboundForMention(...)`,来自 + `openclaw/plugin-sdk/channel-inbound` 或 + `openclaw/plugin-sdk/channel-mention-gating`。 + + **新版**:`resolveInboundMentionDecision({ facts, policy })` —— 返回一个 + 单一决策对象,而不是拆分成两个调用。 + + 下游渠道插件(Slack、Discord、Matrix、Microsoft Teams)已经完成切换。 + + + + + `openclaw/plugin-sdk/channel-runtime` 是面向旧版 + 渠道插件的兼容性 shim。不要在新代码中导入它;请使用 + `openclaw/plugin-sdk/channel-runtime-context` 来注册运行时 + 对象。 + + `openclaw/plugin-sdk/channel-actions` 中的 `channelActions*` + 辅助工具,已与原始 “actions” 渠道导出一同弃用。请改为通过语义化的 `presentation` + 接口暴露能力——渠道插件应声明它们渲染什么(卡片、按钮、选择器),而不是声明它们接受哪些原始 + action 名称。 + + + + + **旧版**:`tool()` 工厂,来自 `openclaw/plugin-sdk/provider-web-search`。 + + **新版**:直接在 provider 插件上实现 `createTool(...)`。 + OpenClaw 不再需要 SDK 辅助工具来注册该工具包装器。 + + + + + **旧版**:`formatInboundEnvelope(...)`(以及 + `ChannelMessageForAgent.channelEnvelope`),用于从入站渠道消息构建一个扁平的纯文本提示 + envelope。 + + **新版**:`BodyForAgent` 加上结构化用户上下文块。渠道 + 插件通过类型化字段附加路由元数据(线程、主题、回复目标、反应),而不是将它们拼接进提示字符串。 + `formatAgentEnvelope(...)` 辅助工具仍然支持用于合成面向助手的 + envelope,但入站纯文本 envelope 正在逐步淘汰。 + + 受影响区域:`inbound_claim`、`message_received`,以及任何对 `channelEnvelope` + 文本进行后处理的自定义渠道插件。 + + + + + 四个 discovery 类型别名现在只是 + catalog 时代类型的轻量包装: + + | 旧别名 | 新类型 | + | ------------------------- | ------------------------- | + | `ProviderDiscoveryOrder` | `ProviderCatalogOrder` | + | `ProviderDiscoveryContext`| `ProviderCatalogContext` | + | `ProviderDiscoveryResult` | `ProviderCatalogResult` | + | `ProviderPluginDiscovery` | `ProviderPluginCatalog` | + + 另外,旧版 `ProviderCapabilities` 静态集合也已弃用——provider 插件 + 应通过 provider 运行时合约附加 capability facts, + 而不是使用静态对象。 + + + + + **旧版**(`ProviderThinkingPolicy` 上的三个独立钩子): + `isBinaryThinking(ctx)`、`supportsXHighThinking(ctx)` 和 + `resolveDefaultThinkingLevel(ctx)`。 + + **新版**:单个 `resolveThinkingProfile(ctx)`,返回一个 + `ProviderThinkingProfile`,其中包含规范 `id`、可选 `label` 以及 + 按排名排序的级别列表。OpenClaw 会根据 profile 排名自动降级过期的已存储值。 + + 实现一个钩子即可,不再需要三个。旧版钩子在弃用窗口期间仍可使用, + 但不会与 profile 结果组合使用。 + + + + + **旧版**:实现 `resolveExternalOAuthProfiles(...)`,但 + 不在插件清单中声明 provider。 + + **新版**:在插件清单中声明 `contracts.externalAuthProviders` + **并且** 实现 `resolveExternalAuthProfiles(...)`。旧版 “auth + fallback” 路径会在运行时发出警告,并将在未来移除。 + + ```json + { + "contracts": { + "externalAuthProviders": ["anthropic", "openai"] + } + } + ``` + + + + + **旧版**清单字段:`providerAuthEnvVars: { anthropic: ["ANTHROPIC_API_KEY"] }`。 + + **新版**:将相同的环境变量查找镜像到清单中的 `setup.providers[].envVars` + 中。这样可以将设置 / 状态环境变量元数据集中到一个位置, + 并避免仅为了响应环境变量查找而启动插件运行时。 + + `providerAuthEnvVars` 会继续通过兼容适配器受到支持, + 直到弃用窗口结束。 + + + + + **旧版**:三个独立调用 — + `api.registerMemoryPromptSection(...)`、 + `api.registerMemoryFlushPlan(...)`、 + `api.registerMemoryRuntime(...)`。 + + **新版**:在 memory-state API 上进行一次调用 — + `registerMemoryCapability(pluginId, { promptBuilder, flushPlanResolver, runtime })`。 + + 相同的槽位,单次注册调用。附加型 Memory 辅助工具 + (`registerMemoryPromptSupplement`、`registerMemoryCorpusSupplement`、 + `registerMemoryEmbeddingProvider`)不受影响。 + + + + + 两个旧版类型别名仍然从 `src/plugins/runtime/types.ts` 导出: + + | 旧版 | 新版 | + | ----------------------------- | ------------------------------- | + | `SubagentReadSessionParams` | `SubagentGetSessionMessagesParams` | + | `SubagentReadSessionResult` | `SubagentGetSessionMessagesResult` | + + 运行时方法 `readSession` 已弃用,改用 + `getSessionMessages`。签名相同;旧方法会调用 + 新方法。 + + + + + **旧版**:`runtime.tasks.flow`(单数)返回一个实时 task-flow 访问器。 + + **新版**:`runtime.tasks.flows`(复数)返回基于 DTO 的 TaskFlow 访问, + 这样可确保导入安全,并且不需要加载完整任务运行时。 + + ```typescript + // Before + const flow = api.runtime.tasks.flow(ctx); + // After + const flows = api.runtime.tasks.flows(ctx); + ``` + + + + + 上文“如何迁移 → 将 Pi tool-result 扩展迁移到 + 中间件”中已经说明。这里再次列出以便完整说明:仅限 Pi 的 + `api.registerEmbeddedExtensionFactory(...)` 路径已弃用,改用 + `api.registerAgentToolResultMiddleware(...)`,并在 `contracts.agentToolResultMiddleware` + 中显式声明 harness 列表。 + + + + 从 `openclaw/plugin-sdk` 重新导出的 `OpenClawSchemaType` 现在是 + `OpenClawConfig` 的单行别名。请优先使用规范名称。 + + ```typescript + // Before + import type { OpenClawSchemaType } from "openclaw/plugin-sdk"; + // After + import type { OpenClawConfig } from "openclaw/plugin-sdk/config-schema"; + ``` + + + + + +扩展级弃用项(位于 `extensions/` 下的内置渠道 / provider 插件内部) +会在它们各自的 `api.ts` 和 `runtime-api.ts` +barrel 中跟踪。这些内容不会影响第三方插件合约,因此未在此列出。 +如果你直接使用某个内置插件的本地 barrel,请在升级前先阅读该 barrel 中的 +弃用注释。 + ## 移除时间线 | 时间 | 会发生什么 | | ---------------------- | ----------------------------------------------------------------------- | | **现在** | 已弃用接口会发出运行时警告 | -| **下一个 major 版本** | 已弃用接口将被移除;仍在使用它们的插件将会失效 | +| **下一个主要版本** | 已弃用接口将被移除;仍在使用它们的插件将会失效 | -所有核心插件都已经完成迁移。外部插件应在下一个 major 版本之前完成迁移。 +所有核心插件都已经完成迁移。外部插件应在下一个主要版本之前完成迁移。 -## 临时抑制警告 +## 暂时抑制警告 -在你进行迁移期间,可设置以下环境变量: +在你进行迁移时,可以设置以下环境变量: ```bash OPENCLAW_SUPPRESS_PLUGIN_SDK_COMPAT_WARNING=1 openclaw gateway run OPENCLAW_SUPPRESS_EXTENSION_API_WARNING=1 openclaw gateway run ``` -这是一个临时紧急放行手段,不是永久解决方案。 +这只是临时逃生通道,不是永久解决方案。 ## 相关内容 @@ -446,5 +631,5 @@ OPENCLAW_SUPPRESS_EXTENSION_API_WARNING=1 openclaw gateway run - [SDK 概览](/zh-CN/plugins/sdk-overview) — 完整子路径导入参考 - [渠道插件](/zh-CN/plugins/sdk-channel-plugins) — 构建渠道插件 - [提供商插件](/zh-CN/plugins/sdk-provider-plugins) — 构建提供商插件 -- [插件内部机制](/zh-CN/plugins/architecture) — 架构深度解析 +- [插件内部机制](/zh-CN/plugins/architecture) — 架构深入解析 - [插件清单](/zh-CN/plugins/manifest) — 清单 schema 参考