跳转至

钩子连接

当家族构建器无法覆盖该行为时,请单独接入各个提供商钩子。这是构建提供商插件指南的一部分;对于共享构建器,请从提供商钩子家族开始。

模型路由策略

轻量级 provider-policy-api 工件通过 resolveModelRoutes 解析模型路由。其上下文和结果类型由 openclaw/plugin-sdk/provider-model-types 导出。

ProviderResolveModelRoutesContext.routeIntent 携带已准备好的、不含密钥的消费者意图:可选的 runtimeId、可选的 authRequirement("subscription" 或 "api-key"),以及 source("explicit" 或 "inherited")。宿主会投射现有的模型/提供商策略和继承的 agent 默认值;插件不得重新加载配置或凭据来重建它。这一事实不会授予凭据访问权限,也不会改变哪些运行时可以执行某条路由。

kind: "routes" 的 ProviderModelRouteResolution 可以设置 preferredAuthRequirement。核心仅当两类认证方式都有符合条件的配置文件且选择为自动时,才应用该偏好。准备和可用性应用相同的优先级:必需的消费者或提供商配置文件绑定会选择账户;已配置的提供商认证会将自动选择限制到该计费路由;显式认证顺序会对剩余符合条件的配置文件排序。继承的 routeIntent 和 preferredAuthRequirement 只在这些选择之后打破平局。环境凭据提供回退材料,而不清除已配置的认证;仅当未配置模式时才推断其模式。偏好不会创建凭据,也不会使不可用或处于冷却阻塞状态的配置文件变得符合条件。单类别选择保持其现有行为。

候选顺序仍与凭据优先级相互独立,runtimePolicy.compatibleIds 继续描述执行兼容性。例如,OpenAI 使用旧版官方 Completions 适配器为受支持的模型保持两条路由可用,当两种类型都符合条件时优先使用订阅认证,并遵循显式 API 路由意图。这些是现有契约上的附加字段;它们不新增钩子或用户设置。

凭据查找取消

使用 openclaw/plugin-sdk/provider-auth-runtime 中 resolveApiKeyForProvider 的凭据消费者应传递其请求的可选 signal。它会结束调用方对排队准入、配置文件锁或 OAuth 结算的等待,而不是结束已认领的刷新操作的凭据写入。已开始的锁获取在清理完成前仍保持拥有状态。应保留非缺失的认证错误,而不是将每个失败都转换为 API 密钥缺失。

openclaw/plugin-sdk/extension-shared 中的 buildTimeoutAbortSignal 将调用方信号与操作超时组合起来。当认证共享请求预算时,应在凭据准备之前启动它,并在 finally 中调用其 cleanup 以释放计时器。

钩子示例

对于需要在每次推理调用前进行 Token 交换的提供商:

prepareRuntimeAuth: async (ctx) => {
  const exchanged = await exchangeToken(ctx.apiKey);
  return {
    apiKey: exchanged.token,
    baseUrl: exchanged.baseUrl,
    expiresAt: exchanged.expiresAt,
  };
},

对于需要自定义请求头或请求体修改的提供商:

// wrapStreamFn returns a StreamFn derived from ctx.streamFn
wrapStreamFn: (ctx) => {
  if (!ctx.streamFn) return undefined;
  const inner = ctx.streamFn;
  return (model, context, options) =>
    inner(model, context, {
      ...options,
      headers: {
        ...options?.headers,
        "X-Acme-Version": "2",
      },
    });
},

现有包装器仍可以传递已弃用的 maxRetries 流选项,包括 0。内置文本传输会忽略它:嵌入式运行器负责重试预算,SDK 内部重试保持禁用。新包装器应省略该选项。此已发布的源契约会保留,直到未来的 Plugin SDK 主版本发布以及已发布插件读取器扫描确认移除是安全的;它不会改变图像生成或原生运行时重试策略。

对于需要在通用 HTTP 或 WebSocket 传输上使用原生请求/会话头或元数据的提供商:

resolveTransportTurnState: (ctx) => ({
  headers: {
    "x-request-id": ctx.turnId,
  },
  metadata: {
    session_id: ctx.sessionId ?? "",
    turn_id: ctx.turnId,
  },
  websocket: {
    headers: {
      "x-session-id": ctx.sessionId ?? "",
    },
    degradeCooldownMs: 60_000,
  },
}),

旧的 resolveWebSocketSessionPolicy 钩子仍受支持,但已弃用。将其字段移到 resolveTransportTurnState.websocket 下;迁移期间,新钩子的字段优先。该钩子仅带有 TypeScript @deprecated 注释:它没有兼容性注册表记录,因此没有已发布的移除日期。对于确实有移除日期的接口,请参阅移除时间线。

对于公开用量/计费数据的提供商:

resolveUsageAuth: async (ctx) => {
  const auth = await ctx.resolveOAuthToken();
  return auth ? { token: auth.token } : null;
},
fetchUsageSnapshot: async (ctx) => {
  // fetchAcmeUsage is your plugin's own vendor API call, not an SDK export.
  return await fetchAcmeUsage(ctx.token, ctx.timeoutMs, {
    fetch: ctx.fetchFn,
    signal: ctx.signal,
  });
},

两个用量钩子都会接收一个可选的 ctx.signal,用于取消收集。ctx.fetchFn 已经将其与请求取消组合起来;自定义传输必须将 ctx.signal 转发到其 I/O。在 await 之后开始额外的认证工作之前,请检查取消状态。预算耗尽时不会调用任一钩子,并会生成一个可见的 Timeout 快照。核心会保留已完成的同级操作,并通过清理跟踪未完成的工作,包括由认证拥有的凭据刷新。

resolveUsageAuth 有三种结果。当提供商具有用量/计费凭据时,返回 { token, accountId?, subscriptionType?, rateLimitTier? }(可选字段将已解析配置档案中的非机密套餐元数据带入 fetchUsageSnapshot)。仅当提供商已明确处理用量认证但没有可用的用量令牌,且 OpenClaw 必须跳过通用 API 密钥/OAuth 回退时,才返回 { handled: true }。当提供商未处理该请求且 OpenClaw 应继续通用回退时,返回 null 或 undefined。

在 `contracts.usageProviders` 中声明提供商 ID。当该清单契约和**两个**钩子都存在时,OpenClaw 会自动将该提供商纳入用量采集,而无需加载无关的提供商插件。无需更新核心允许列表。
`fetchUsageSnapshot` 返回共享的、与提供商无关的结构:

- `plan`:提供商报告的订阅或密钥标签
- `windows`:以使用百分比表示的可重置配额窗口
- `billing`:带类型的 `balance`、`spend` 或 `budget` 条目;`unit` 可以是
  ISO 货币,也可以是提供商单位,例如 `credits`
- `summary`:无法放入上述结构化字段的紧凑提供商特定上下文

保持货币语义精确。除非上游契约明确说明,否则提供商积分不是美元。仅实现
`fetchUsageSnapshot` 的插件仍可供显式/合成调用方使用,但不会被自动发现,因为 OpenClaw 无法解析其用量凭据。

仅当提供商注册的 createStreamFn 传输能够理解稳定/动态系统提示边界时,才在提供商注册上设置 supportsSystemPromptCacheBoundary: true。使用来自 openclaw/plugin-sdk/provider-transport-runtime 的 splitSystemPromptCacheBoundary 单独为稳定前缀设置检查点,并在发送任何负载之前消费标记。 当缓存被禁用时,使用 stripSystemPromptCacheBoundary。默认情况下, OpenClaw 在调用自定义传输之前会移除标记。

对于累积 JSON 工具参数的自定义 createStreamFn 传输,请使用来自 openclaw/plugin-sdk/llm 的 createToolArgumentPreviewSchedule()。 为每个工具调用创建一个调度,并在调用 parseStreamingJson 之前将累积原始字符串的长度传入其中。返回的函数 允许在几何增长检查点处刷新预览,因此在原始片段到达时,中间 arguments 快照可以保持不变。 继续发出每个原始增量,并在传输的终端边界处验证完整参数,即使最后一次预览未刷新。

常见提供商钩子

对于模型/提供商插件,OpenClaw 大致按此顺序调用钩子。 大多数提供商只使用 2-3 个。这不是完整的 ProviderPlugin 契约——请参阅 内部:提供商运行时钩子 获取完整且当前准确的钩子列表和回退说明。 OpenClaw 不再调用的仅用于兼容性的提供商字段,例如 ProviderPlugin.capabilities 和 suppressBuiltInModel,未在此列出。

保持 resolveSyntheticAuth 同步且有界。外部进程/网络登录 检查应放在 prepareSyntheticAuth 中,它会接收捕获的配置、 环境和取消信号,并返回合成认证结果或无结果。OpenClaw 会在该准备代内保留已完成的可用性。只读工作进程会接收最终的 provider-ref 结果(包括 不可用),从而在不重新运行外部检查的情况下保留别名优先级。 被取消的准备必须在清理后拒绝,而不是报告缺少登录。

钩子 使用时机
catalog 模型目录或基础 URL 默认值
applyConfigDefaults 配置物化期间提供商拥有的全局默认值
normalizeModelId 查找前清理旧版/预览 model-id 别名
normalizeTransport 通用模型组装前清理提供商家族的 api / baseUrl
normalizeConfig 规范化 models.providers.<id> 配置
applyNativeStreamingUsageCompat 为配置提供商进行原生流式用量兼容性重写
resolveConfigApiKey 提供商拥有的环境变量标记认证解析
resolveSyntheticAuth 本地/自托管或由配置支持的合成认证
prepareSyntheticAuth 在同步可用性读取之前异步验证外部认证
resolveExternalAuthProfiles 为 CLI/应用管理的凭据叠加提供商拥有的外部认证配置文件
shouldDeferSyntheticProfileAuth 将合成存储配置文件占位符置于环境变量/配置认证之后
resolveDynamicModel 接受任意上游模型 ID
prepareDynamicModel 返回异步发现的模型,或在同步解析前预热可复用元数据
normalizeResolvedModel 运行器之前的传输重写
normalizeToolSchemas 注册前清理提供商拥有的工具架构
钩子 使用时机
inspectToolSchemas Provider 侧工具模式诊断
resolveReasoningOutputMode 带标签与原生推理输出契约
prepareExtraParams 默认请求参数
createStreamFn 完全自定义的 StreamFn 传输
wrapStreamFn 在常规流路径上添加自定义请求头/请求体包装
reconcileLocalService 在健康检查之后、每次请求之前执行的廉价且幂等的托管服务修复
resolveTransportTurnState 原生每轮请求头/元数据以及 WebSocket 请求头/冷却
resolveWebSocketSessionPolicy 已弃用的 WebSocket 兼容性钩子;请使用 resolveTransportTurnState
formatApiKey 自定义运行时 Token 形态
loginOAuth 基于回调的 OAuth 登录,用于会话 SDK 的 AuthStorage API
refreshOAuth 自定义 OAuth 刷新
buildAuthDoctorHint 认证修复指导
matchesContextOverflowError Provider 侧溢出检测
classifyFailoverReason Provider 侧速率限制/过载分类
isCacheTtlEligible Prompt 缓存 TTL 门控
buildMissingAuthMessage 自定义缺失认证提示
augmentModelCatalog 合成前向兼容行(已弃用 - 优先使用 registerModelCatalogProvider)
resolveThinkingProfile 特定于模型的 /think 选项集
isBinaryThinking 二元思考开/关兼容性(已弃用 - 优先使用 resolveThinkingProfile)
supportsXHighThinking xhigh 推理支持兼容性(已弃用 - 优先使用 resolveThinkingProfile)
resolveDefaultThinkingLevel 默认 /think 策略兼容性(已弃用 - 优先使用 resolveThinkingProfile)
isModernModelRef 实时/冒烟模型匹配
prepareRuntimeAuth 推理前的 Token 交换
resolveUsageAuth 自定义用量凭据解析
fetchUsageSnapshot 自定义用量端点
createEmbeddingProvider Provider 侧用于记忆/搜索的嵌入适配器
buildReplayPolicy 自定义转录重放/压缩策略
sanitizeReplayHistory 通用清理后的 Provider 特定重放重写
validateReplayTurns 嵌入式运行器之前的严格重放轮次验证
onModelSelected 选择后回调(例如遥测)
`reconcileLocalService` 仅针对已配置的本地服务调用,
包括被重启的 Gateway 复用的健康进程。请尊重其
中止信号,并在协调失败时拒绝;OpenClaw 会阻止
Provider 请求并释放请求租约。

运行时回退说明:

- `isCacheTtlEligible(ctx)` 接收 `provider`、`modelId`、可选的 `modelApi`,以及已解析的路由事实 `baseUrl` 和 `supportsPromptCacheKey`。安装缓存 TTL 修剪和记录缓存触达时使用相同的有界上下文;它不包括完整模型、请求头或额外请求参数。OpenAI 在官方 Platform 和 Codex 端点上默认符合条件,尊重显式的 `supportsPromptCacheKey: false`,并且要求自定义代理路由显式选择加入。这控制客户端侧的空闲修剪,而不是保证 Provider 缓存命中。
- 错误分类使用已准备好的 Provider 所有者或已加载的 Provider 钩子。在处理错误时,`matchesContextOverflowError` 和 `classifyFailoverReason` 绝不会触发插件发现;Provider 准备负责加载这些钩子。
- `normalizeConfig` 为每个 provider id 解析一个归属插件(优先内置 Provider,然后是匹配的运行时插件),并且只调用该钩子——不会跨其他 Provider 扫描。Google 自身的 `normalizeConfig` 钩子用于规范化 `google` / `google-vertex` / `google-antigravity` 配置项;它不是独立的核心回退。
- `resolveConfigApiKey` 在暴露时使用 Provider 钩子。Amazon Bedrock 在其 Provider 插件中保留 AWS 环境变量标记解析;当配置为 `auth: "aws-sdk"` 时,运行时认证本身仍使用 AWS SDK 默认链。
- `resolveThinkingProfile(ctx)` 接收所选的 `provider`、`modelId`、可选的目录路由事实 `api` 和 `baseUrl`、可选的合并 `reasoning` 目录提示,以及可选的合并模型 `compat` 事实。仅使用 `compat` 来选择 Provider 的思考 UI/配置档。
- `normalizeResolvedModel(ctx)` 可以在 Provider 具有首选嵌入摘要强度时,在返回的 `ProviderRuntimeModel` 上设置 `compactionThinkingDefault`。这是已准备好的运行时元数据,而不是操作员设置或目录字段。显式的 `agents.defaults.compaction.thinkingLevel` 优先;否则宿主使用此偏好,然后使用 `low`。所选强度仍会被限制在实际压缩候选范围内。
- `resolveSystemPromptContribution` 允许 Provider 为某个模型家族注入缓存感知的系统提示指导。当行为属于某个 Provider/模型家族,并且应保留稳定/动态缓存拆分时,请优先使用它,而不是旧版的全插件 `before_prompt_build` 钩子。

内置 HTTP 适配器可以使用私有本地 openclaw/plugin-sdk/provider-http 入口点中的 createProviderHttpError 来保留数值响应状态。已经绑定并脱敏其诊断信息的适配器可以构造 ProviderHttpError(message, { status })。在调整其消息时,请保留该错误实例,以便状态和重试元数据得以保留;搜索工具使用这些字段进行安全身份验证和配额指导,而不暴露响应体。

内置且受信任的官方提供商策略可以使用私有 openclaw/plugin-sdk/provider-thinking-runtime 辅助函数中的 resolveEffortThinkingProfile(compat?.supportedReasoningEfforts)。它接受精确的 off、minimal、low、medium、high、xhigh 和 max 值,将 none 映射为 off,并在保留其余每个级别首次出现的同时,在开头添加 off。默认偏好为 medium、high、low,然后是 off。缺失、null 或空的元数据返回 undefined;不包含受支持值的非空列表返回仅包含 off 的配置文件。将特定于模型的覆盖项和 API 回退保留在提供商策略中。

内置且受信任的官方插件还可以从其轻量级 provider-policy-api 工件中导出 resolveToolSearchMode(ctx)。上下文包含最终的 provider、modelId、api 和可选的 baseUrl;其类型从 openclaw/plugin-sdk/provider-model-types 导出。返回 "tools" 以优先使用结构化 Tool Search,返回 false 以否决托管本地服务默认值,或返回 undefined 将该决定留给宿主。宿主会将结果记录在已解析的运行时模型上,而不是写入配置。显式的 tools.toolSearch 设置优先。此钩子更改模式暴露,而不是工具权限或可用性。

当提供商提供托管搜索时,可以从同一策略工件中导出 resolveNativeWebSearch(ctx)。其 ProviderNativeWebSearchPolicyContext(来自 openclaw/plugin-sdk/provider-model-types)包含 config、provider、可选的 modelId、api 和 baseUrl。仅当该路由将注入托管搜索时返回 true;将此策略与负载构造共享。保持钩子同步,并且不包含运行时激活或凭据探测。宿主独立应用工具权限,并在构建 Tool Search 和 Code Mode 目录之前移除托管的 web_search。显式的托管提供商选择必须保持权威。

resolveFastModeSupport(ctx) 可以从同一策略工件中导出并注册到提供商上。仅对于已确认的空操作 Fast 选择返回 false,对于适用的本地请求映射返回 true,或在事实缺失时返回 undefined。ProviderFastModePolicyContext 携带所选模型、路由、身份验证模式、运行时、请求参数和传输策略;不包含凭据。将策略与请求构造共享。宿主仅发布 supportsFastMode,保留未知行为并清除已保存的偏好。这描述的是本地适用性,而不是上游授权或履约,并且不会拒绝 /fast 命令。

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