From 7c0cac2740c8526598867fa39a3e28a638b8275a Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Mon, 16 Mar 2026 01:24:26 +0000 Subject: [PATCH] refactor(plugins): share bundled compat transforms --- src/plugins/bundled-compat.ts | 65 ++++++++++++++++++++++++ src/plugins/providers.ts | 39 ++------------- src/plugins/web-search-providers.ts | 76 +++++------------------------ 3 files changed, 82 insertions(+), 98 deletions(-) create mode 100644 src/plugins/bundled-compat.ts diff --git a/src/plugins/bundled-compat.ts b/src/plugins/bundled-compat.ts new file mode 100644 index 00000000000..e946be355b5 --- /dev/null +++ b/src/plugins/bundled-compat.ts @@ -0,0 +1,65 @@ +import type { PluginEntryConfig } from "../config/types.plugins.js"; +import type { PluginLoadOptions } from "./loader.js"; + +export function withBundledPluginAllowlistCompat(params: { + config: PluginLoadOptions["config"]; + pluginIds: readonly string[]; +}): PluginLoadOptions["config"] { + const allow = params.config?.plugins?.allow; + if (!Array.isArray(allow) || allow.length === 0) { + return params.config; + } + + const allowSet = new Set(allow.map((entry) => entry.trim()).filter(Boolean)); + let changed = false; + for (const pluginId of params.pluginIds) { + if (!allowSet.has(pluginId)) { + allowSet.add(pluginId); + changed = true; + } + } + + if (!changed) { + return params.config; + } + + return { + ...params.config, + plugins: { + ...params.config?.plugins, + allow: [...allowSet], + }, + }; +} + +export function withBundledPluginEnablementCompat(params: { + config: PluginLoadOptions["config"]; + pluginIds: readonly string[]; +}): PluginLoadOptions["config"] { + const existingEntries = params.config?.plugins?.entries ?? {}; + let changed = false; + const nextEntries: Record = { ...existingEntries }; + + for (const pluginId of params.pluginIds) { + if (existingEntries[pluginId] !== undefined) { + continue; + } + nextEntries[pluginId] = { enabled: true }; + changed = true; + } + + if (!changed) { + return params.config; + } + + return { + ...params.config, + plugins: { + ...params.config?.plugins, + entries: { + ...existingEntries, + ...nextEntries, + }, + }, + }; +} diff --git a/src/plugins/providers.ts b/src/plugins/providers.ts index 010766e5fa9..4f4216730cf 100644 --- a/src/plugins/providers.ts +++ b/src/plugins/providers.ts @@ -1,4 +1,5 @@ import { createSubsystemLogger } from "../logging/subsystem.js"; +import { withBundledPluginAllowlistCompat } from "./bundled-compat.js"; import { loadOpenClawPlugins, type PluginLoadOptions } from "./loader.js"; import { createPluginLoaderLogger } from "./logger.js"; import type { ProviderPlugin } from "./types.js"; @@ -64,38 +65,6 @@ function hasExplicitPluginConfig(config: PluginLoadOptions["config"]): boolean { return false; } -function withBundledProviderAllowlistCompat( - config: PluginLoadOptions["config"], -): PluginLoadOptions["config"] { - const allow = config?.plugins?.allow; - if (!Array.isArray(allow) || allow.length === 0) { - return config; - } - - const allowSet = new Set(allow.map((entry) => entry.trim()).filter(Boolean)); - let changed = false; - for (const pluginId of BUNDLED_PROVIDER_ALLOWLIST_COMPAT_PLUGIN_IDS) { - if (!allowSet.has(pluginId)) { - allowSet.add(pluginId); - changed = true; - } - } - - if (!changed) { - return config; - } - - return { - ...config, - plugins: { - ...config?.plugins, - // Backward compat: bundled implicit providers historically stayed - // available even when operators kept a restrictive plugin allowlist. - allow: [...allowSet], - }, - }; -} - function withBundledProviderVitestCompat(params: { config: PluginLoadOptions["config"]; env?: PluginLoadOptions["env"]; @@ -118,7 +87,6 @@ function withBundledProviderVitestCompat(params: { }, }; } - export function resolvePluginProviders(params: { config?: PluginLoadOptions["config"]; workspaceDir?: string; @@ -129,7 +97,10 @@ export function resolvePluginProviders(params: { onlyPluginIds?: string[]; }): ProviderPlugin[] { const maybeAllowlistCompat = params.bundledProviderAllowlistCompat - ? withBundledProviderAllowlistCompat(params.config) + ? withBundledPluginAllowlistCompat({ + config: params.config, + pluginIds: BUNDLED_PROVIDER_ALLOWLIST_COMPAT_PLUGIN_IDS, + }) : params.config; const config = params.bundledProviderVitestCompat ? withBundledProviderVitestCompat({ diff --git a/src/plugins/web-search-providers.ts b/src/plugins/web-search-providers.ts index 8120be0113c..f59cf95f51a 100644 --- a/src/plugins/web-search-providers.ts +++ b/src/plugins/web-search-providers.ts @@ -1,5 +1,8 @@ -import type { PluginEntryConfig } from "../config/types.plugins.js"; import { createSubsystemLogger } from "../logging/subsystem.js"; +import { + withBundledPluginAllowlistCompat, + withBundledPluginEnablementCompat, +} from "./bundled-compat.js"; import { loadOpenClawPlugins, type PluginLoadOptions } from "./loader.js"; import { createPluginLoaderLogger } from "./logger.js"; import type { WebSearchProviderPlugin } from "./types.js"; @@ -14,67 +17,6 @@ const BUNDLED_WEB_SEARCH_ALLOWLIST_COMPAT_PLUGIN_IDS = [ "xai", ] as const; -function withBundledWebSearchAllowlistCompat( - config: PluginLoadOptions["config"], -): PluginLoadOptions["config"] { - const allow = config?.plugins?.allow; - if (!Array.isArray(allow) || allow.length === 0) { - return config; - } - - const allowSet = new Set(allow.map((entry) => entry.trim()).filter(Boolean)); - let changed = false; - for (const pluginId of BUNDLED_WEB_SEARCH_ALLOWLIST_COMPAT_PLUGIN_IDS) { - if (!allowSet.has(pluginId)) { - allowSet.add(pluginId); - changed = true; - } - } - - if (!changed) { - return config; - } - - return { - ...config, - plugins: { - ...config?.plugins, - allow: [...allowSet], - }, - }; -} - -function withBundledWebSearchEnablementCompat( - config: PluginLoadOptions["config"], -): PluginLoadOptions["config"] { - const existingEntries = config?.plugins?.entries ?? {}; - let changed = false; - const nextEntries: Record = { ...existingEntries }; - - for (const pluginId of BUNDLED_WEB_SEARCH_ALLOWLIST_COMPAT_PLUGIN_IDS) { - if (existingEntries[pluginId] !== undefined) { - continue; - } - nextEntries[pluginId] = { enabled: true }; - changed = true; - } - - if (!changed) { - return config; - } - - return { - ...config, - plugins: { - ...config?.plugins, - entries: { - ...existingEntries, - ...nextEntries, - }, - }, - }; -} - export function resolvePluginWebSearchProviders(params: { config?: PluginLoadOptions["config"]; workspaceDir?: string; @@ -82,9 +24,15 @@ export function resolvePluginWebSearchProviders(params: { bundledAllowlistCompat?: boolean; }): WebSearchProviderPlugin[] { const allowlistCompat = params.bundledAllowlistCompat - ? withBundledWebSearchAllowlistCompat(params.config) + ? withBundledPluginAllowlistCompat({ + config: params.config, + pluginIds: BUNDLED_WEB_SEARCH_ALLOWLIST_COMPAT_PLUGIN_IDS, + }) : params.config; - const config = withBundledWebSearchEnablementCompat(allowlistCompat); + const config = withBundledPluginEnablementCompat({ + config: allowlistCompat, + pluginIds: BUNDLED_WEB_SEARCH_ALLOWLIST_COMPAT_PLUGIN_IDS, + }); const registry = loadOpenClawPlugins({ config, workspaceDir: params.workspaceDir,