@@ -14,6 +14,7 @@ import {
1414import type { ProviderSystemPromptContribution } from "../agents/system-prompt-contribution.js" ;
1515import type { ModelProviderConfig } from "../config/types.js" ;
1616import type { OpenClawConfig } from "../config/types.openclaw.js" ;
17+ import { formatErrorMessage } from "../infra/errors.js" ;
1718import { createSubsystemLogger } from "../logging/subsystem.js" ;
1819import { normalizeProviderModelIdWithManifest } from "./manifest-model-id-normalization.js" ;
1920import { resolvePluginMetadataSnapshot } from "./plugin-metadata-snapshot.js" ;
@@ -123,6 +124,29 @@ function matchesAnyProviderPluginRef(provider: ProviderPlugin, providerRefs: rea
123124 return providerRefs . some ( ( providerRef ) => matchesProviderPluginRef ( provider , providerRef ) ) ;
124125}
125126
127+ function getProviderRuntimePluginKey ( plugin : ProviderPlugin ) : string {
128+ return `${ plugin . pluginId ?? "" } :${ plugin . id } ` ;
129+ }
130+
131+ function runProviderRuntimeHook < TResult > ( params : {
132+ plugin : ProviderPlugin | undefined ;
133+ hookName : string ;
134+ run : ( plugin : ProviderPlugin ) => TResult ;
135+ } ) : TResult | undefined {
136+ if ( ! params . plugin ) {
137+ return undefined ;
138+ }
139+ try {
140+ return params . run ( params . plugin ) ;
141+ } catch ( error ) {
142+ const pluginId = params . plugin . pluginId ?? params . plugin . id ;
143+ log . warn (
144+ `Provider plugin "${ sanitizeForLog ( pluginId ) } " ${ sanitizeForLog ( params . hookName ) } hook failed; ignoring hook: ${ sanitizeForLog ( formatErrorMessage ( error ) ) } ` ,
145+ ) ;
146+ return undefined ;
147+ }
148+ }
149+
126150function hasExplicitProviderRuntimePluginActivation ( params : {
127151 provider : string ;
128152 config ?: OpenClawConfig ;
@@ -369,8 +393,13 @@ export function normalizeProviderModelIdWithPlugin(params: {
369393} ) : string | undefined {
370394 const plugin = resolveProviderHookPlugin ( params ) ;
371395 return (
372- normalizeOptionalString ( plugin ?. normalizeModelId ?.( params . context ) ) ??
373- normalizeProviderModelIdWithManifest ( params )
396+ normalizeOptionalString (
397+ runProviderRuntimeHook ( {
398+ plugin,
399+ hookName : "normalizeModelId" ,
400+ run : ( providerPlugin ) => providerPlugin . normalizeModelId ?.( params . context ) ,
401+ } ) ,
402+ ) ?? normalizeProviderModelIdWithManifest ( params )
374403 ) ;
375404}
376405
@@ -385,16 +414,28 @@ export function normalizeProviderTransportWithPlugin(params: {
385414 ( normalized . api ?? params . context . api ) !== params . context . api ||
386415 ( normalized . baseUrl ?? params . context . baseUrl ) !== params . context . baseUrl ;
387416 const matchedPlugin = resolveProviderHookPlugin ( params ) ;
388- const normalizedMatched = matchedPlugin ?. normalizeTransport ?.( params . context ) ;
417+ const normalizedMatched = runProviderRuntimeHook ( {
418+ plugin : matchedPlugin ,
419+ hookName : "normalizeTransport" ,
420+ run : ( providerPlugin ) => providerPlugin . normalizeTransport ?.( params . context ) ,
421+ } ) ;
422+ const matchedPluginKey = matchedPlugin ? getProviderRuntimePluginKey ( matchedPlugin ) : undefined ;
389423 if ( normalizedMatched && hasTransportChange ( normalizedMatched ) ) {
390424 return normalizedMatched ;
391425 }
392426
393427 for ( const candidate of resolveProviderPluginsForHooks ( params ) ) {
394- if ( ! candidate . normalizeTransport || candidate === matchedPlugin ) {
428+ if (
429+ ! candidate . normalizeTransport ||
430+ ( matchedPluginKey && getProviderRuntimePluginKey ( candidate ) === matchedPluginKey )
431+ ) {
395432 continue ;
396433 }
397- const normalized = candidate . normalizeTransport ( params . context ) ;
434+ const normalized = runProviderRuntimeHook ( {
435+ plugin : candidate ,
436+ hookName : "normalizeTransport" ,
437+ run : ( providerPlugin ) => providerPlugin . normalizeTransport ?.( params . context ) ,
438+ } ) ;
398439 if ( normalized && hasTransportChange ( normalized ) ) {
399440 return normalized ;
400441 }
0 commit comments