From a478ab3dfa6c894b07640ea6c68af2e8faa2d507 Mon Sep 17 00:00:00 2001 From: Shakker Date: Mon, 27 Apr 2026 17:09:51 +0100 Subject: [PATCH] refactor: let provider discovery reuse plugin metadata --- .../provider-discovery.runtime.test.ts | 34 +++++++++++++++++++ src/plugins/provider-discovery.runtime.ts | 21 +++++++----- src/plugins/provider-discovery.ts | 2 ++ 3 files changed, 49 insertions(+), 8 deletions(-) diff --git a/src/plugins/provider-discovery.runtime.test.ts b/src/plugins/provider-discovery.runtime.test.ts index d7ff4fa6116..e1ec0ad6f51 100644 --- a/src/plugins/provider-discovery.runtime.test.ts +++ b/src/plugins/provider-discovery.runtime.test.ts @@ -179,6 +179,40 @@ describe("resolvePluginDiscoveryProvidersRuntime", () => { ); }); + it("uses a provided plugin metadata snapshot without rebuilding registry metadata", () => { + const registry = { plugins: [] }; + const manifestRegistry = { + plugins: [createManifestPlugin("deepseek")], + diagnostics: [], + }; + mocks.loadSource.mockReturnValue(createProvider({ id: "deepseek", mode: "catalog" })); + + expect( + resolvePluginDiscoveryProvidersRuntime({ + config: {}, + env: {} as NodeJS.ProcessEnv, + pluginMetadataSnapshot: { + index: registry as never, + manifestRegistry, + }, + }), + ).toEqual([ + expect.objectContaining({ + id: "deepseek", + pluginId: "deepseek", + }), + ]); + + expect(mocks.loadPluginRegistrySnapshot).not.toHaveBeenCalled(); + expect(mocks.loadPluginManifestRegistryForInstalledIndex).not.toHaveBeenCalled(); + expect(mocks.resolveDiscoveredProviderPluginIds).toHaveBeenCalledWith( + expect.objectContaining({ + registry, + manifestRegistry, + }), + ); + }); + it("returns static-only discovery entries for callers that explicitly request them", () => { const staticProvider = createProvider({ id: "deepseek", mode: "static" }); mocks.loadSource.mockReturnValue(staticProvider); diff --git a/src/plugins/provider-discovery.runtime.ts b/src/plugins/provider-discovery.runtime.ts index 6f7bcdf6499..716ef2a82dc 100644 --- a/src/plugins/provider-discovery.runtime.ts +++ b/src/plugins/provider-discovery.runtime.ts @@ -1,6 +1,7 @@ import type { OpenClawConfig } from "../config/types.openclaw.js"; import { loadPluginManifestRegistryForInstalledIndex } from "./manifest-registry-installed.js"; import type { PluginManifestRecord } from "./manifest-registry.js"; +import type { PluginMetadataSnapshot } from "./plugin-metadata-snapshot.js"; import { loadPluginRegistrySnapshot } from "./plugin-registry.js"; import { resolveDiscoveredProviderPluginIds } from "./providers.js"; import { resolvePluginProviders } from "./providers.runtime.js"; @@ -76,15 +77,18 @@ function resolveProviderDiscoveryEntryPlugins(params: { includeUntrustedWorkspacePlugins?: boolean; requireCompleteDiscoveryEntryCoverage?: boolean; discoveryEntriesOnly?: boolean; + pluginMetadataSnapshot?: Pick; }): ProviderDiscoveryEntryResult { - const registry = loadPluginRegistrySnapshot(params); - const manifestRegistry = loadPluginManifestRegistryForInstalledIndex({ - index: registry, - config: params.config, - workspaceDir: params.workspaceDir, - env: params.env, - includeDisabled: true, - }); + const registry = params.pluginMetadataSnapshot?.index ?? loadPluginRegistrySnapshot(params); + const manifestRegistry = + params.pluginMetadataSnapshot?.manifestRegistry ?? + loadPluginManifestRegistryForInstalledIndex({ + index: registry, + config: params.config, + workspaceDir: params.workspaceDir, + env: params.env, + includeDisabled: true, + }); const pluginIds = resolveDiscoveredProviderPluginIds({ ...params, registry, @@ -144,6 +148,7 @@ export function resolvePluginDiscoveryProvidersRuntime(params: { includeUntrustedWorkspacePlugins?: boolean; requireCompleteDiscoveryEntryCoverage?: boolean; discoveryEntriesOnly?: boolean; + pluginMetadataSnapshot?: Pick; }): ProviderPlugin[] { const env = params.env ?? process.env; const entryResult = resolveProviderDiscoveryEntryPlugins(params); diff --git a/src/plugins/provider-discovery.ts b/src/plugins/provider-discovery.ts index 48f00710264..6014805b5dd 100644 --- a/src/plugins/provider-discovery.ts +++ b/src/plugins/provider-discovery.ts @@ -1,6 +1,7 @@ import { normalizeProviderId } from "../agents/model-selection.js"; import type { ModelProviderConfig } from "../config/types.js"; import type { OpenClawConfig } from "../config/types.openclaw.js"; +import type { PluginMetadataSnapshot } from "./plugin-metadata-snapshot.js"; import { listPluginContributionIds, loadPluginRegistrySnapshot, @@ -42,6 +43,7 @@ export type ResolveRuntimePluginDiscoveryProvidersParams = { includeUntrustedWorkspacePlugins?: boolean; requireCompleteDiscoveryEntryCoverage?: boolean; discoveryEntriesOnly?: boolean; + pluginMetadataSnapshot?: Pick; }; export type ResolveInstalledPluginProviderContributionIdsParams = LoadPluginRegistryParams & {