diff --git a/src/agents/models-config.providers.implicit.ts b/src/agents/models-config.providers.implicit.ts index 0a40411997a..aa175b0c3c8 100644 --- a/src/agents/models-config.providers.implicit.ts +++ b/src/agents/models-config.providers.implicit.ts @@ -126,6 +126,25 @@ function resolveProviderDiscoveryFilter(params: { : undefined; } +function resolvePluginMetadataProviderOwners( + pluginMetadataSnapshot: Pick | undefined, + provider: string, +): readonly string[] | undefined { + if (!pluginMetadataSnapshot) { + 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); + } + return owners.size > 0 + ? [...owners].toSorted((left, right) => left.localeCompare(right)) + : undefined; +} + export function resolveProviderDiscoveryFilterForTest(params: { config?: OpenClawConfig; workspaceDir?: string; @@ -135,6 +154,13 @@ export function resolveProviderDiscoveryFilterForTest(params: { return resolveProviderDiscoveryFilter(params); } +export function resolvePluginMetadataProviderOwnersForTest( + pluginMetadataSnapshot: Pick | undefined, + provider: string, +): readonly string[] | undefined { + return resolvePluginMetadataProviderOwners(pluginMetadataSnapshot, provider); +} + function mergeImplicitProviderSet( target: Record, additions: Record | undefined, @@ -370,7 +396,7 @@ export async function resolveImplicitProviders( workspaceDir: params.workspaceDir, env, resolveOwners: params.pluginMetadataSnapshot - ? (provider) => params.pluginMetadataSnapshot?.owners.providers.get(provider) + ? (provider) => resolvePluginMetadataProviderOwners(params.pluginMetadataSnapshot, provider) : undefined, }), ...(params.pluginMetadataSnapshot diff --git a/src/agents/models-config.providers.live-filter.test.ts b/src/agents/models-config.providers.live-filter.test.ts index 3cd55195b8b..4c7b6d36b53 100644 --- a/src/agents/models-config.providers.live-filter.test.ts +++ b/src/agents/models-config.providers.live-filter.test.ts @@ -1,5 +1,9 @@ import { describe, expect, it } from "vitest"; -import { resolveProviderDiscoveryFilterForTest } from "./models-config.providers.implicit.js"; +import type { PluginMetadataSnapshotOwnerMaps } from "../plugins/plugin-metadata-snapshot.js"; +import { + resolvePluginMetadataProviderOwnersForTest, + resolveProviderDiscoveryFilterForTest, +} from "./models-config.providers.implicit.js"; function liveFilterEnv(overrides: NodeJS.ProcessEnv): NodeJS.ProcessEnv { return { @@ -12,6 +16,22 @@ function resolveOwners(provider: string): readonly string[] | undefined { return provider === "claude-cli" ? ["anthropic"] : undefined; } +function metadataOwners( + overrides: Partial, +): PluginMetadataSnapshotOwnerMaps { + return { + channels: new Map(), + channelConfigs: new Map(), + providers: new Map(), + modelCatalogProviders: new Map(), + cliBackends: new Map(), + setupProviders: new Map(), + commandAliases: new Map(), + contracts: new Map(), + ...overrides, + }; +} + describe("resolveProviderDiscoveryFilterForTest", () => { it("maps live provider backend ids to owning plugin ids", () => { expect( @@ -48,4 +68,26 @@ describe("resolveProviderDiscoveryFilterForTest", () => { }), ).toEqual(["openrouter"]); }); + + it("maps live provider backend ids through plugin metadata cli backend owners", () => { + const snapshot = { + owners: metadataOwners({ + cliBackends: new Map([["claude-cli", ["anthropic"]]]), + }), + }; + + const resolveMetadataOwners = (provider: string) => + resolvePluginMetadataProviderOwnersForTest(snapshot, provider); + + expect(resolveMetadataOwners("claude-cli")).toEqual(["anthropic"]); + expect( + resolveProviderDiscoveryFilterForTest({ + env: liveFilterEnv({ + OPENCLAW_LIVE_TEST: "1", + OPENCLAW_LIVE_PROVIDERS: "claude-cli", + }), + resolveOwners: resolveMetadataOwners, + }), + ).toEqual(["anthropic"]); + }); });