From 34ef403cb2a21a8013cb4bcef3d319c8b26a31cf Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Wed, 29 Apr 2026 05:01:51 +0100 Subject: [PATCH] docs: clarify provider hook compatibility --- docs/concepts/model-providers.md | 2 +- docs/plugins/architecture-internals.md | 63 +++++++++++++------------- docs/plugins/sdk-migration.md | 4 +- docs/plugins/sdk-provider-plugins.md | 63 +++++++++++++------------- 4 files changed, 67 insertions(+), 65 deletions(-) diff --git a/docs/concepts/model-providers.md b/docs/concepts/model-providers.md index bc2c6cf902b..a1b5b59c924 100644 --- a/docs/concepts/model-providers.md +++ b/docs/concepts/model-providers.md @@ -49,7 +49,7 @@ Most provider-specific logic lives in provider plugins (`registerProvider(...)`) The full list of provider-SDK hooks and bundled-plugin examples lives in [Provider plugins](/plugins/sdk-provider-plugins). A provider that needs a totally custom request executor is a separate, deeper extension surface. -Provider runtime `capabilities` is shared runner metadata (provider family, transcript/tooling quirks, transport/cache hints). It is not the same as the [public capability model](/plugins/architecture#public-capability-model), which describes what a plugin registers (text inference, speech, etc.). +Provider-owned runner behavior lives on explicit provider hooks such as replay policy, tool-schema normalization, stream wrapping, and transport/request helpers. The legacy `ProviderPlugin.capabilities` static bag is compatibility-only and is no longer read by shared runner logic. ## API key rotation diff --git a/docs/plugins/architecture-internals.md b/docs/plugins/architecture-internals.md index eafbcab5300..66e3d8ab7cd 100644 --- a/docs/plugins/architecture-internals.md +++ b/docs/plugins/architecture-internals.md @@ -242,6 +242,9 @@ without loading channel runtime. For model/provider plugins, OpenClaw calls hooks in this rough order. The "When to use" column is the quick decision guide. +Compatibility-only provider fields that OpenClaw no longer calls, such as +`ProviderPlugin.capabilities` and `suppressBuiltInModel`, are intentionally not +listed here. | # | Hook | What it does | When to use | | --- | --------------------------------- | -------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- | @@ -260,37 +263,35 @@ The "When to use" column is the quick decision guide. | 12 | `prepareDynamicModel` | Async warm-up, then `resolveDynamicModel` runs again | Provider needs network metadata before resolving unknown ids | | 13 | `normalizeResolvedModel` | Final rewrite before the embedded runner uses the resolved model | Provider needs transport rewrites but still uses a core transport | | 14 | `contributeResolvedModelCompat` | Contribute compat flags for vendor models behind another compatible transport | Provider recognizes its own models on proxy transports without taking over the provider | -| 15 | `capabilities` | Provider-owned transcript/tooling metadata used by shared core logic | Provider needs transcript/provider-family quirks | -| 16 | `normalizeToolSchemas` | Normalize tool schemas before the embedded runner sees them | Provider needs transport-family schema cleanup | -| 17 | `inspectToolSchemas` | Surface provider-owned schema diagnostics after normalization | Provider wants keyword warnings without teaching core provider-specific rules | -| 18 | `resolveReasoningOutputMode` | Select native vs tagged reasoning-output contract | Provider needs tagged reasoning/final output instead of native fields | -| 19 | `prepareExtraParams` | Request-param normalization before generic stream option wrappers | Provider needs default request params or per-provider param cleanup | -| 20 | `createStreamFn` | Fully replace the normal stream path with a custom transport | Provider needs a custom wire protocol, not just a wrapper | -| 21 | `wrapStreamFn` | Stream wrapper after generic wrappers are applied | Provider needs request headers/body/model compat wrappers without a custom transport | -| 22 | `resolveTransportTurnState` | Attach native per-turn transport headers or metadata | Provider wants generic transports to send provider-native turn identity | -| 23 | `resolveWebSocketSessionPolicy` | Attach native WebSocket headers or session cool-down policy | Provider wants generic WS transports to tune session headers or fallback policy | -| 24 | `formatApiKey` | Auth-profile formatter: stored profile becomes the runtime `apiKey` string | Provider stores extra auth metadata and needs a custom runtime token shape | -| 25 | `refreshOAuth` | OAuth refresh override for custom refresh endpoints or refresh-failure policy | Provider does not fit the shared `pi-ai` refreshers | -| 26 | `buildAuthDoctorHint` | Repair hint appended when OAuth refresh fails | Provider needs provider-owned auth repair guidance after refresh failure | -| 27 | `matchesContextOverflowError` | Provider-owned context-window overflow matcher | Provider has raw overflow errors generic heuristics would miss | -| 28 | `classifyFailoverReason` | Provider-owned failover reason classification | Provider can map raw API/transport errors to rate-limit/overload/etc | -| 29 | `isCacheTtlEligible` | Prompt-cache policy for proxy/backhaul providers | Provider needs proxy-specific cache TTL gating | -| 30 | `buildMissingAuthMessage` | Replacement for the generic missing-auth recovery message | Provider needs a provider-specific missing-auth recovery hint | -| 31 | `suppressBuiltInModel` | Deprecated. Runtime hook is no longer called; use manifest `modelCatalog.suppressions` | Historical hook for hiding stale upstream rows; keep new suppression data in the plugin manifest | -| 32 | `augmentModelCatalog` | Synthetic/final catalog rows appended after discovery | Provider needs synthetic forward-compat rows in `models list` and pickers | -| 33 | `resolveThinkingProfile` | Model-specific `/think` level set, display labels, and default | Provider exposes a custom thinking ladder or binary label for selected models | -| 34 | `isBinaryThinking` | On/off reasoning toggle compatibility hook | Provider exposes only binary thinking on/off | -| 35 | `supportsXHighThinking` | `xhigh` reasoning support compatibility hook | Provider wants `xhigh` on only a subset of models | -| 36 | `resolveDefaultThinkingLevel` | Default `/think` level compatibility hook | Provider owns default `/think` policy for a model family | -| 37 | `isModernModelRef` | Modern-model matcher for live profile filters and smoke selection | Provider owns live/smoke preferred-model matching | -| 38 | `prepareRuntimeAuth` | Exchange a configured credential into the actual runtime token/key just before inference | Provider needs a token exchange or short-lived request credential | -| 39 | `resolveUsageAuth` | Resolve usage/billing credentials for `/usage` and related status surfaces | Provider needs custom usage/quota token parsing or a different usage credential | -| 40 | `fetchUsageSnapshot` | Fetch and normalize provider-specific usage/quota snapshots after auth is resolved | Provider needs a provider-specific usage endpoint or payload parser | -| 41 | `createEmbeddingProvider` | Build a provider-owned embedding adapter for memory/search | Memory embedding behavior belongs with the provider plugin | -| 42 | `buildReplayPolicy` | Return a replay policy controlling transcript handling for the provider | Provider needs custom transcript policy (for example, thinking-block stripping) | -| 43 | `sanitizeReplayHistory` | Rewrite replay history after generic transcript cleanup | Provider needs provider-specific replay rewrites beyond shared compaction helpers | -| 44 | `validateReplayTurns` | Final replay-turn validation or reshaping before the embedded runner | Provider transport needs stricter turn validation after generic sanitation | -| 45 | `onModelSelected` | Run provider-owned post-selection side effects | Provider needs telemetry or provider-owned state when a model becomes active | +| 15 | `normalizeToolSchemas` | Normalize tool schemas before the embedded runner sees them | Provider needs transport-family schema cleanup | +| 16 | `inspectToolSchemas` | Surface provider-owned schema diagnostics after normalization | Provider wants keyword warnings without teaching core provider-specific rules | +| 17 | `resolveReasoningOutputMode` | Select native vs tagged reasoning-output contract | Provider needs tagged reasoning/final output instead of native fields | +| 18 | `prepareExtraParams` | Request-param normalization before generic stream option wrappers | Provider needs default request params or per-provider param cleanup | +| 19 | `createStreamFn` | Fully replace the normal stream path with a custom transport | Provider needs a custom wire protocol, not just a wrapper | +| 20 | `wrapStreamFn` | Stream wrapper after generic wrappers are applied | Provider needs request headers/body/model compat wrappers without a custom transport | +| 21 | `resolveTransportTurnState` | Attach native per-turn transport headers or metadata | Provider wants generic transports to send provider-native turn identity | +| 22 | `resolveWebSocketSessionPolicy` | Attach native WebSocket headers or session cool-down policy | Provider wants generic WS transports to tune session headers or fallback policy | +| 23 | `formatApiKey` | Auth-profile formatter: stored profile becomes the runtime `apiKey` string | Provider stores extra auth metadata and needs a custom runtime token shape | +| 24 | `refreshOAuth` | OAuth refresh override for custom refresh endpoints or refresh-failure policy | Provider does not fit the shared `pi-ai` refreshers | +| 25 | `buildAuthDoctorHint` | Repair hint appended when OAuth refresh fails | Provider needs provider-owned auth repair guidance after refresh failure | +| 26 | `matchesContextOverflowError` | Provider-owned context-window overflow matcher | Provider has raw overflow errors generic heuristics would miss | +| 27 | `classifyFailoverReason` | Provider-owned failover reason classification | Provider can map raw API/transport errors to rate-limit/overload/etc | +| 28 | `isCacheTtlEligible` | Prompt-cache policy for proxy/backhaul providers | Provider needs proxy-specific cache TTL gating | +| 29 | `buildMissingAuthMessage` | Replacement for the generic missing-auth recovery message | Provider needs a provider-specific missing-auth recovery hint | +| 30 | `augmentModelCatalog` | Synthetic/final catalog rows appended after discovery | Provider needs synthetic forward-compat rows in `models list` and pickers | +| 31 | `resolveThinkingProfile` | Model-specific `/think` level set, display labels, and default | Provider exposes a custom thinking ladder or binary label for selected models | +| 32 | `isBinaryThinking` | On/off reasoning toggle compatibility hook | Provider exposes only binary thinking on/off | +| 33 | `supportsXHighThinking` | `xhigh` reasoning support compatibility hook | Provider wants `xhigh` on only a subset of models | +| 34 | `resolveDefaultThinkingLevel` | Default `/think` level compatibility hook | Provider owns default `/think` policy for a model family | +| 35 | `isModernModelRef` | Modern-model matcher for live profile filters and smoke selection | Provider owns live/smoke preferred-model matching | +| 36 | `prepareRuntimeAuth` | Exchange a configured credential into the actual runtime token/key just before inference | Provider needs a token exchange or short-lived request credential | +| 37 | `resolveUsageAuth` | Resolve usage/billing credentials for `/usage` and related status surfaces | Provider needs custom usage/quota token parsing or a different usage credential | +| 38 | `fetchUsageSnapshot` | Fetch and normalize provider-specific usage/quota snapshots after auth is resolved | Provider needs a provider-specific usage endpoint or payload parser | +| 39 | `createEmbeddingProvider` | Build a provider-owned embedding adapter for memory/search | Memory embedding behavior belongs with the provider plugin | +| 40 | `buildReplayPolicy` | Return a replay policy controlling transcript handling for the provider | Provider needs custom transcript policy (for example, thinking-block stripping) | +| 41 | `sanitizeReplayHistory` | Rewrite replay history after generic transcript cleanup | Provider needs provider-specific replay rewrites beyond shared compaction helpers | +| 42 | `validateReplayTurns` | Final replay-turn validation or reshaping before the embedded runner | Provider transport needs stricter turn validation after generic sanitation | +| 43 | `onModelSelected` | Run provider-owned post-selection side effects | Provider needs telemetry or provider-owned state when a model becomes active | `normalizeModelId`, `normalizeTransport`, and `normalizeConfig` first check the matched provider plugin, then fall through other hook-capable provider plugins diff --git a/docs/plugins/sdk-migration.md b/docs/plugins/sdk-migration.md index 06ebd814aee..e2f13077054 100644 --- a/docs/plugins/sdk-migration.md +++ b/docs/plugins/sdk-migration.md @@ -647,8 +647,8 @@ canonical replacement. | `ProviderPluginDiscovery` | `ProviderPluginCatalog` | Plus the legacy `ProviderCapabilities` static bag — provider plugins - should attach capability facts through the provider runtime contract - rather than a static object. + should use explicit provider hooks such as `buildReplayPolicy`, + `normalizeToolSchemas`, and `wrapStreamFn` rather than a static object. diff --git a/docs/plugins/sdk-provider-plugins.md b/docs/plugins/sdk-provider-plugins.md index 9928933e063..67b76162da2 100644 --- a/docs/plugins/sdk-provider-plugins.md +++ b/docs/plugins/sdk-provider-plugins.md @@ -420,6 +420,9 @@ API key auth, and dynamic model resolution. OpenClaw calls hooks in this order. Most providers only use 2-3: + Compatibility-only provider fields that OpenClaw no longer calls, such as + `ProviderPlugin.capabilities` and `suppressBuiltInModel`, are not listed + here. | # | Hook | When to use | | --- | --- | --- | @@ -436,37 +439,35 @@ API key auth, and dynamic model resolution. | 11 | `prepareDynamicModel` | Async metadata fetch before resolving | | 12 | `normalizeResolvedModel` | Transport rewrites before the runner | | 13 | `contributeResolvedModelCompat` | Compat flags for vendor models behind another compatible transport | - | 14 | `capabilities` | Legacy static capability bag; compatibility only | - | 15 | `normalizeToolSchemas` | Provider-owned tool-schema cleanup before registration | - | 16 | `inspectToolSchemas` | Provider-owned tool-schema diagnostics | - | 17 | `resolveReasoningOutputMode` | Tagged vs native reasoning-output contract | - | 18 | `prepareExtraParams` | Default request params | - | 19 | `createStreamFn` | Fully custom StreamFn transport | - | 20 | `wrapStreamFn` | Custom headers/body wrappers on the normal stream path | - | 21 | `resolveTransportTurnState` | Native per-turn headers/metadata | - | 22 | `resolveWebSocketSessionPolicy` | Native WS session headers/cool-down | - | 23 | `formatApiKey` | Custom runtime token shape | - | 24 | `refreshOAuth` | Custom OAuth refresh | - | 25 | `buildAuthDoctorHint` | Auth repair guidance | - | 26 | `matchesContextOverflowError` | Provider-owned overflow detection | - | 27 | `classifyFailoverReason` | Provider-owned rate-limit/overload classification | - | 28 | `isCacheTtlEligible` | Prompt cache TTL gating | - | 29 | `buildMissingAuthMessage` | Custom missing-auth hint | - | 30 | `suppressBuiltInModel` | Deprecated. Runtime hook is no longer called; use manifest `modelCatalog.suppressions` | - | 31 | `augmentModelCatalog` | Synthetic forward-compat rows | - | 32 | `resolveThinkingProfile` | Model-specific `/think` option set | - | 33 | `isBinaryThinking` | Binary thinking on/off compatibility | - | 34 | `supportsXHighThinking` | `xhigh` reasoning support compatibility | - | 35 | `resolveDefaultThinkingLevel` | Default `/think` policy compatibility | - | 36 | `isModernModelRef` | Live/smoke model matching | - | 37 | `prepareRuntimeAuth` | Token exchange before inference | - | 38 | `resolveUsageAuth` | Custom usage credential parsing | - | 39 | `fetchUsageSnapshot` | Custom usage endpoint | - | 40 | `createEmbeddingProvider` | Provider-owned embedding adapter for memory/search | - | 41 | `buildReplayPolicy` | Custom transcript replay/compaction policy | - | 42 | `sanitizeReplayHistory` | Provider-specific replay rewrites after generic cleanup | - | 43 | `validateReplayTurns` | Strict replay-turn validation before the embedded runner | - | 44 | `onModelSelected` | Post-selection callback (e.g. telemetry) | + | 14 | `normalizeToolSchemas` | Provider-owned tool-schema cleanup before registration | + | 15 | `inspectToolSchemas` | Provider-owned tool-schema diagnostics | + | 16 | `resolveReasoningOutputMode` | Tagged vs native reasoning-output contract | + | 17 | `prepareExtraParams` | Default request params | + | 18 | `createStreamFn` | Fully custom StreamFn transport | + | 19 | `wrapStreamFn` | Custom headers/body wrappers on the normal stream path | + | 20 | `resolveTransportTurnState` | Native per-turn headers/metadata | + | 21 | `resolveWebSocketSessionPolicy` | Native WS session headers/cool-down | + | 22 | `formatApiKey` | Custom runtime token shape | + | 23 | `refreshOAuth` | Custom OAuth refresh | + | 24 | `buildAuthDoctorHint` | Auth repair guidance | + | 25 | `matchesContextOverflowError` | Provider-owned overflow detection | + | 26 | `classifyFailoverReason` | Provider-owned rate-limit/overload classification | + | 27 | `isCacheTtlEligible` | Prompt cache TTL gating | + | 28 | `buildMissingAuthMessage` | Custom missing-auth hint | + | 29 | `augmentModelCatalog` | Synthetic forward-compat rows | + | 30 | `resolveThinkingProfile` | Model-specific `/think` option set | + | 31 | `isBinaryThinking` | Binary thinking on/off compatibility | + | 32 | `supportsXHighThinking` | `xhigh` reasoning support compatibility | + | 33 | `resolveDefaultThinkingLevel` | Default `/think` policy compatibility | + | 34 | `isModernModelRef` | Live/smoke model matching | + | 35 | `prepareRuntimeAuth` | Token exchange before inference | + | 36 | `resolveUsageAuth` | Custom usage credential parsing | + | 37 | `fetchUsageSnapshot` | Custom usage endpoint | + | 38 | `createEmbeddingProvider` | Provider-owned embedding adapter for memory/search | + | 39 | `buildReplayPolicy` | Custom transcript replay/compaction policy | + | 40 | `sanitizeReplayHistory` | Provider-specific replay rewrites after generic cleanup | + | 41 | `validateReplayTurns` | Strict replay-turn validation before the embedded runner | + | 42 | `onModelSelected` | Post-selection callback (e.g. telemetry) | Runtime fallback notes: