跳转至

审批

如果你的插件需要,请查阅本页。属于构建频道插件指南的一部分。

审批与频道能力

大多数频道插件不需要审批专用代码。核心负责同一聊天 /approve、共享审批按钮负载和通用回退投递。ChannelPlugin.approvals 已移除;改为将审批投递/原生/渲染/身份验证信息放在一个 approvalCapability 对象上。plugin.auth 仅用于登录/登出——核心不再从该对象读取审批身份验证钩子。

仅将 approvalCapability.delivery 用于原生审批路由或回退抑制,仅当频道确实需要自定义审批负载而不是共享渲染器时,才使用 approvalCapability.render。delivery.shouldBlockForwardingFallback 会拒绝无法执行所选审核者策略的回退,即使没有原生处理器在运行。频道可以要求原生审核者投递,并针对所选策略拒绝所有通用转发;delivery.shouldSuppressForwardingFallback 仅在原生处理器处于活动状态时避免重复投递。两者都会接收审批请求负载。对于没有缓存待处理请求的终止通知,核心会从已解析事件中重建它,并将 createdAtMs 和 expiresAtMs 设为零;策略检查应使用嵌套的请求负载。

审批身份验证

  • approvalCapability.authorizeActorAction 和 approvalCapability.getActionAvailabilityState 是规范的审批身份验证接口。
  • 对于原生卡片、转发提示和最终决定,强制使用宿主配置的、请求范围的插件审核者列表的频道,应设置 approvalCapability.supportsScopedPluginApprovalApprovers: true。当频道存在审核者策略时,宿主会拒绝通过缺少此标记的旧能力处理插件审批路由和决定。在每条审批路径都强制使用所选列表之前,保持该标记缺失。
  • 如果插件 /approve 授权需要带空间限定的审核者 ID,请实现 approvalCapability.resolveReviewerSenderId。核心会传递 cfg、accountId、senderId 和 spaceId,然后仅将结果用于插件审批命令授权。从已认证的频道入口推导空间;该回调不会接收待处理请求。如果未知,返回 undefined:核心将保留原始发送者 ID。无限定的原始 ID 无法满足带空间限定的策略。频道的 authorizeActorAction 和 Gateway 托管在解析决定时仍会检查确切请求。旧宿主会忽略此可选回调,并同样保留原始发送者 ID;仅提供无限定 ID 的频道需要一个会调用该回调以处理带空间限定的 /approve 策略的宿主。
  • 使用 getActionAvailabilityState 表示同一聊天审批身份验证的可用性。即使原生投递已禁用,也要让已配置的审批人可用于 /approve;改用原生发起界面状态提供投递/设置指引。
  • 如果你的频道暴露原生执行审批,当发起界面/原生客户端状态与同一聊天审批身份验证不同时,使用 approvalCapability.getExecInitiatingSurfaceState。核心使用该执行专用钩子来区分 enabled 与 disabled,判断发起频道是否支持原生执行审批,并将该频道纳入原生客户端回退指引。createApproverRestrictedNativeApprovalCapability(...) 会为常见情况填充此项。
  • 如果频道可以从现有配置推断出稳定的类似所有者的 DM 身份,请使用 openclaw/plugin-sdk/approval-runtime 中的 createResolvedApproverActionAuthAdapter,在不添加审批专用核心逻辑的情况下限制同一聊天 /approve。
  • 如果自定义审批身份验证有意仅允许同一聊天回退,请从 openclaw/plugin-sdk/approval-auth-runtime 返回 markImplicitSameChatApprovalAuthorization({ authorized: true });否则核心会将结果视为显式审批人授权。
  • 如果频道拥有的原生回调直接解析审批,请在解析前使用 isImplicitSameChatApprovalAuthorization(...),以便隐式回退仍经过频道的常规操作者授权。

负载生命周期与设置指引

  • 使用 outbound.shouldSuppressLocalPayloadPrompt 或 outbound.beforeDeliverPayload 实现频道特定的负载生命周期行为,例如隐藏重复的本地审批提示或在投递前发送正在输入指示器。
  • 当频道希望禁用路径的回复说明启用原生执行审批所需的确切配置项时,使用 approvalCapability.describeExecApprovalSetup。该钩子接收 { channel, channelLabel, accountId };命名账号频道应渲染账号范围的路径,例如 channels.<channel>.accounts.<id>.execApprovals.*,而不是顶层默认值。
  • 当插件审批失败指引可以安全地用于插件审批无路由和超时失败时,使用 approvalCapability.describePluginApprovalSetup。createApproverRestrictedNativeApprovalCapability(...) 不会从 describeExecApprovalSetup 推断此项;仅当插件审批和执行审批确实使用相同的原生设置时,才显式传入相同的辅助函数。

原生审批投递

如果频道需要原生审批投递,请让频道代码专注于目标规范化以及传输/呈现事实。从 openclaw/plugin-sdk/approval-runtime 使用 createChannelExecApprovalProfile、createChannelNativeOriginTargetResolver、createChannelApproverDmTargetResolver 和 createApproverRestrictedNativeApprovalCapability。将频道特定的事实放在 approvalCapability.nativeRuntime 之后,最好通过 createChannelApprovalNativeRuntimeAdapter(...) 或 createLazyChannelApprovalNativeRuntimeAdapter(...),以便核心可以组装处理器并负责请求过滤、路由、去重、过期、Gateway 订阅和已路由至他处的通知。

nativeRuntime 被拆分为几个较小的扩展点:

  • availability - 账户是否已配置,以及是否应处理某个请求
  • presentation - 将共享审批视图模型映射为待处理/已解决/已过期的原生载荷或最终操作
  • transport - 准备目标,并发送/更新/删除原生审批消息
  • interactions - 可选的用于原生按钮或表情反应的绑定/解绑/清除操作钩子,以及可选的 cancelDelivered 钩子。当 deliverPending 注册了进程内或持久化状态(例如表情反应目标存储)时,实现 cancelDelivered,以便在处理器停止导致投递被取消且发生在 bindPending 运行之前,或 bindPending 未返回句柄时,可以释放状态
  • observe - 可选的投递诊断钩子

原生审批运行时可接收三种审批类型:exec、plugin 和 system-agent。system-agent 请求要求操作员批准 Gateway 侧的持久化变更,例如配置写入或 Gateway 重启。运行时必须渲染类型化的审批操作,然后渲染最终应用结果。被允许的请求可以以已应用或未应用结束;不要仅将记录的审批视为变更已完成的证明。

表情反应绑定必须从投递到决策解决保留显式的审批类型,包括在加载持久化插件状态之后。iMessage 原生轮询和表情反应索引在重启后遵循相同规则。

其他审批辅助功能:

  • 对于明确授权的表情反应决策,使用来自 openclaw/plugin-sdk/approval-reaction-runtime 的 settleApprovalReaction。它会检查提供的审批人和操作者授权,惰性加载 Gateway 解析器,并等待每个最终结果(包括未胜出的点击)或审批未找到错误的 clearTarget。保持传输身份、路由检查、清理和结果日志记录在插件中。解析器错误会保持绑定完整并传播;通道必须将它们交给其持久化入口或轮询器以进行重放。readApprovalReactionTargetRecord 验证共享持久化字段;传输特定的路由和作者字段仍需要各自的验证。
  • 在完成注册或清理之前,等待 createApprovalReactionTargetStore().register(...) 和 .delete(...)。两者都会在等待存储之前更新其内存索引。可选存储失败保留现有策略:报告失败,禁用持久化访问,并保留内存回退。结算仅在清理完成后报告解决;清理失败会传播,而不会被报告为 Gateway 解决失败。
  • 对于最终展示,使用来自 openclaw/plugin-sdk/approval-runtime 的 formatChannelApprovalResolvedLabel 和 buildSystemAgentApprovalResolvedText。富标签保留应用状态优先级;散文保留拒绝优先级,因为被拒绝的系统变更也可能报告 not-applied。两者都优先处理取消。传递决策格式化程序用于传输特定的标签拼写,并在构建散文之前准备任何有界操作摘要。使用 formatApprovalDecisionLabel 表示已记录的决策,而不暗示应用已完成。
  • 审批账户查找辅助函数 resolveApprovalRequestAccountId 和 resolveApprovalRequestChannelAccountId 使用 approval-native-runtime。它们重复的 approval-runtime 导出以及未使用的 matchesApprovalRequestSessionFilter 导出已被弃用。核心实现未更改。
  • 对于进程本地原生卡片 token,使用来自 openclaw/plugin-sdk/approval-runtime 的 createNativeApprovalControlRegistry。每个实例拥有一个 1,024 绑定的 FIFO 注册表,并在 Gateway 解决和最终卡片更新期间保持其声明。缺失的审批会使其 token 退役;其他失败会释放声明以进行重试。插件在调用 settle 之前验证原生事件范围并授权操作者,通过 releaseClaimOnLookupExpiry 保留其查找过期策略,并使用 onComplete 进行传输拥有的清理,例如手动提示抑制。
  • 当通道同时支持会话来源的原生投递和显式审批转发目标时,使用来自 openclaw/plugin-sdk/approval-native-runtime 的 createNativeApprovalChannelRouteGates。该辅助函数集中处理审批配置选择、mode 处理、代理/会话过滤器、账户绑定、会话目标匹配和目标列表匹配,而调用方仍拥有通道 id、默认转发模式、账户查找、传输启用检查、目标归一化和轮次来源目标解析。不要使用它来创建核心拥有的通道策略默认值;显式传递通道的文档默认模式。未使用的 createChannelApprovalForwardingEvaluator 导出已被弃用;此路由门辅助函数仍是受支持的路由路径。
  • createNativeApprovalMessagingTargetResolvers 集中处理通道匹配和 { to, accountId, threadId } 归一化,用于其原生审批目标是通道拥有的归一化目的地的消息传输。将群组授权、审批人映射和其他传输策略保留在通道插件中。
  • createChannelNativeOriginTargetResolver 默认使用共享通道路由匹配器处理 { to, accountId, threadId } 目标。仅当通道具有提供商特定的等价规则(例如 Slack 时间戳前缀匹配)时,才传递 targetsMatch。当通道需要在默认路由匹配器或自定义 targetsMatch 回调运行之前规范化提供商 id,同时保留原始目标用于投递时,传递 normalizeTargetForMatch。仅当解析后的投递目标本身应被规范化时,使用 normalizeTarget。
  • 如果通道需要运行时拥有的对象,例如客户端、token、Bolt 应用或 webhook 接收器,请通过 openclaw/plugin-sdk/channel-runtime-context 注册它们。通用运行时上下文注册表允许核心从通道启动状态引导能力驱动的处理器,而无需添加审批特定的包装胶水。
  • 仅在能力驱动的扩展点尚不够表达时,才使用较低层的 createChannelApprovalHandler 或 createChannelNativeApprovalRuntime。
  • 原生审批通道必须通过那些辅助函数路由 accountId 和 approvalKind。accountId 将多账户审批策略限定到正确的机器人账户,approvalKind 使 exec 与 plugin 审批行为对通道可用,而无需在核心中硬编码分支。
  • 核心也拥有审批重路由通知。通道插件不应从 createChannelNativeApprovalRuntime 发送自己的“审批已转到 DM / 另一个通道”后续消息;相反,通过共享审批能力辅助函数暴露准确的来源 + 审批人 DM 路由,并让核心在将任何通知发回发起聊天之前聚合实际投递。
  • 端到端保留已投递审批 id 的类型。原生客户端不应从通道本地状态猜测或重写 exec 与 plugin 审批路由。
  • 将该显式 approvalKind 传递给 resolveApprovalOverGateway。这使用规范的 approval.resolve 服务,并在另一个界面先回答时返回记录的获胜者。旧的显式 resolveMethod 输入仍保留用于命令支持的控件;新的原生操作不得使用它或从 ID 推断类型。
  • 不同的审批类型可以有意暴露不同的原生界面。当前捆绑示例:Matrix 对 exec 和 plugin 审批保持相同的原生 DM/通道路由和表情反应用户体验,同时仍允许授权按审批类型不同;Slack 对 exec 和 plugin id 保持原生审批路由可用。
  • createApproverRestrictedNativeApprovalAdapter 仍作为兼容性包装器存在,但新代码应优先使用能力构建器并在插件上暴露 approvalCapability。

更窄的审批运行时子路径

对于热通道入口点,当只需要该系列中的一个部分时,请优先使用以下更窄的子路径,而不是更宽泛的 approval-runtime barrel:

  • openclaw/plugin-sdk/approval-auth-runtime
  • openclaw/plugin-sdk/approval-client-runtime
  • openclaw/plugin-sdk/approval-delivery-runtime
  • openclaw/plugin-sdk/approval-gateway-runtime
  • openclaw/plugin-sdk/approval-reference-runtime
  • openclaw/plugin-sdk/approval-handler-adapter-runtime
  • openclaw/plugin-sdk/approval-handler-runtime
  • openclaw/plugin-sdk/approval-native-runtime
  • openclaw/plugin-sdk/approval-reply-runtime
  • openclaw/plugin-sdk/channel-runtime-context

同样,当不需要全部功能时,请优先使用 openclaw/plugin-sdk/reply-runtime、openclaw/plugin-sdk/reply-dispatch-runtime、openclaw/plugin-sdk/reply-reference 和 openclaw/plugin-sdk/reply-chunking,而不是更宽泛的伞形接口。

本页原文 Markdown:在 AtomGit 查看·内容源自开源项目 cl/openclaw