From 5531502cb00986ffc63558a1f40900171472c075 Mon Sep 17 00:00:00 2001 From: Shakker Date: Mon, 27 Apr 2026 18:02:24 +0100 Subject: [PATCH] fix: normalize provider metadata live filters --- .../models-config.providers.implicit.ts | 51 ++++++++++++++++--- ...odels-config.providers.live-filter.test.ts | 42 +++++++++++++++ 2 files changed, 86 insertions(+), 7 deletions(-) diff --git a/src/agents/models-config.providers.implicit.ts b/src/agents/models-config.providers.implicit.ts index aa175b0c3c8..e6426737887 100644 --- a/src/agents/models-config.providers.implicit.ts +++ b/src/agents/models-config.providers.implicit.ts @@ -23,7 +23,7 @@ import { createProviderApiKeyResolver, createProviderAuthResolver, } from "./models-config.providers.secrets.js"; -import { findNormalizedProviderValue } from "./provider-id.js"; +import { findNormalizedProviderValue, normalizeProviderId } from "./provider-id.js"; const log = createSubsystemLogger("agents/model-providers"); @@ -133,18 +133,55 @@ function resolvePluginMetadataProviderOwners( if (!pluginMetadataSnapshot) { return undefined; } + const normalizedProvider = normalizeProviderId(provider); + if (!normalizedProvider) { + return undefined; + } const owners = new Set(); - for (const owner of pluginMetadataSnapshot.owners.providers.get(provider) ?? []) { - owners.add(owner); - } - for (const owner of pluginMetadataSnapshot.owners.cliBackends.get(provider) ?? []) { - owners.add(owner); - } + appendNormalizedPluginMetadataOwners( + owners, + pluginMetadataSnapshot.owners.providers, + provider, + normalizedProvider, + ); + appendNormalizedPluginMetadataOwners( + owners, + pluginMetadataSnapshot.owners.cliBackends, + provider, + normalizedProvider, + ); return owners.size > 0 ? [...owners].toSorted((left, right) => left.localeCompare(right)) : undefined; } +function appendNormalizedPluginMetadataOwners( + target: Set, + ownerMap: ReadonlyMap, + provider: string, + normalizedProvider: string, +): void { + for (const owner of ownerMap.get(provider) ?? []) { + target.add(owner); + } + if (normalizedProvider !== provider) { + for (const owner of ownerMap.get(normalizedProvider) ?? []) { + target.add(owner); + } + } + for (const [ownedId, owners] of ownerMap.entries()) { + if ( + ownedId !== provider && + ownedId !== normalizedProvider && + normalizeProviderId(ownedId) === normalizedProvider + ) { + for (const owner of owners) { + target.add(owner); + } + } + } +} + export function resolveProviderDiscoveryFilterForTest(params: { config?: OpenClawConfig; workspaceDir?: string; diff --git a/src/agents/models-config.providers.live-filter.test.ts b/src/agents/models-config.providers.live-filter.test.ts index 4c7b6d36b53..dca331b083e 100644 --- a/src/agents/models-config.providers.live-filter.test.ts +++ b/src/agents/models-config.providers.live-filter.test.ts @@ -90,4 +90,46 @@ describe("resolveProviderDiscoveryFilterForTest", () => { }), ).toEqual(["anthropic"]); }); + + it("normalizes mixed-case backend ids through plugin metadata owners", () => { + const snapshot = { + owners: metadataOwners({ + cliBackends: new Map([["claude-cli", ["anthropic"]]]), + }), + }; + + expect(resolvePluginMetadataProviderOwnersForTest(snapshot, "Claude-CLI")).toEqual([ + "anthropic", + ]); + expect( + resolveProviderDiscoveryFilterForTest({ + env: liveFilterEnv({ + OPENCLAW_LIVE_TEST: "1", + OPENCLAW_LIVE_PROVIDERS: "Claude-CLI", + }), + resolveOwners: (provider) => resolvePluginMetadataProviderOwnersForTest(snapshot, provider), + }), + ).toEqual(["anthropic"]); + }); + + it("normalizes provider aliases through plugin metadata owners", () => { + const snapshot = { + owners: metadataOwners({ + providers: new Map([["volcengine", ["volcengine"]]]), + }), + }; + + expect(resolvePluginMetadataProviderOwnersForTest(snapshot, "bytedance")).toEqual([ + "volcengine", + ]); + expect( + resolveProviderDiscoveryFilterForTest({ + env: liveFilterEnv({ + OPENCLAW_LIVE_TEST: "1", + OPENCLAW_LIVE_PROVIDERS: "bytedance", + }), + resolveOwners: (provider) => resolvePluginMetadataProviderOwnersForTest(snapshot, provider), + }), + ).toEqual(["volcengine"]); + }); });