From 6dbaa0a27837c0d2825f374503eb8531d266104b Mon Sep 17 00:00:00 2001 From: "clawsweeper[bot]" <274271284+clawsweeper[bot]@users.noreply.github.com> Date: Wed, 29 Apr 2026 23:15:47 -0700 Subject: [PATCH] fix(plugins): keep disabled plugin runtime deps off Co-authored-by: openclaw-clawsweeper[bot] <280122609+openclaw-clawsweeper[bot]@users.noreply.github.com> --- .../capability-provider-runtime.test.ts | 65 +++++++++++++++++++ src/plugins/capability-provider-runtime.ts | 8 ++- 2 files changed, 72 insertions(+), 1 deletion(-) diff --git a/src/plugins/capability-provider-runtime.test.ts b/src/plugins/capability-provider-runtime.test.ts index b6b0d1ad96c..47aea18ba33 100644 --- a/src/plugins/capability-provider-runtime.test.ts +++ b/src/plugins/capability-provider-runtime.test.ts @@ -657,6 +657,34 @@ describe("resolvePluginCapabilityProviders", () => { }); }); + it("keeps bundled runtime dependency repair disabled when plugins are globally disabled", () => { + const cfg = { plugins: { enabled: false, allow: ["custom-plugin"] } } as OpenClawConfig; + const enablementCompat = { + plugins: { + enabled: true, + allow: ["custom-plugin", "openai"], + entries: { openai: { enabled: true } }, + }, + }; + setBundledCapabilityFixture("mediaUnderstandingProviders"); + mocks.withBundledPluginEnablementCompat.mockReturnValue(enablementCompat); + mocks.withBundledPluginVitestCompat.mockReturnValue(enablementCompat); + + expectNoResolvedCapabilityProviders( + resolvePluginCapabilityProviders({ + key: "mediaUnderstandingProviders", + cfg, + }), + ); + + expect(mocks.resolveRuntimePluginRegistry).toHaveBeenCalledWith({ + config: enablementCompat, + onlyPluginIds: ["openai"], + activate: false, + installBundledRuntimeDeps: false, + }); + }); + it.each([ "imageGenerationProviders", "videoGenerationProviders", @@ -816,4 +844,41 @@ describe("resolvePluginCapabilityProviders", () => { activate: false, }); }); + + it("keeps targeted provider fallback dependency repair disabled when plugins are globally disabled", () => { + const cfg = { plugins: { enabled: false, allow: ["custom-plugin"] } } as OpenClawConfig; + const enablementCompat = { + plugins: { + enabled: true, + allow: ["custom-plugin", "google"], + entries: { google: { enabled: true } }, + }, + }; + mocks.loadPluginManifestRegistry.mockReturnValue({ + plugins: [ + { + id: "google", + origin: "bundled", + contracts: { memoryEmbeddingProviders: ["gemini"] }, + }, + ] as never, + diagnostics: [], + }); + mocks.withBundledPluginEnablementCompat.mockReturnValue(enablementCompat); + mocks.withBundledPluginVitestCompat.mockReturnValue(enablementCompat); + + const provider = resolvePluginCapabilityProvider({ + key: "memoryEmbeddingProviders", + providerId: "gemini", + cfg, + }); + + expect(provider).toBeUndefined(); + expect(mocks.resolveRuntimePluginRegistry).toHaveBeenCalledWith({ + config: enablementCompat, + onlyPluginIds: ["google"], + activate: false, + installBundledRuntimeDeps: false, + }); + }); }); diff --git a/src/plugins/capability-provider-runtime.ts b/src/plugins/capability-provider-runtime.ts index 96a5cff82a6..30c4934d8b8 100644 --- a/src/plugins/capability-provider-runtime.ts +++ b/src/plugins/capability-provider-runtime.ts @@ -87,6 +87,7 @@ function resolveCapabilityProviderConfig(params: { function createCapabilityProviderFallbackLoadOptions(params: { compatConfig?: OpenClawConfig; + sourceConfig?: OpenClawConfig; pluginIds: string[]; installBundledRuntimeDeps?: boolean; }): PluginLoadOptions { @@ -95,7 +96,10 @@ function createCapabilityProviderFallbackLoadOptions(params: { onlyPluginIds: params.pluginIds, activate: false, }; - if (params.installBundledRuntimeDeps === false) { + if ( + params.installBundledRuntimeDeps === false || + params.sourceConfig?.plugins?.enabled === false + ) { loadOptions.installBundledRuntimeDeps = false; } return loadOptions; @@ -243,6 +247,7 @@ export function resolvePluginCapabilityProvider