diff --git a/src/plugins/loader.test.ts b/src/plugins/loader.test.ts index 3a7ea349311..61c810ae615 100644 --- a/src/plugins/loader.test.ts +++ b/src/plugins/loader.test.ts @@ -1753,20 +1753,20 @@ module.exports = { id: "throws-after-import", register() {} };`, }, }, { - name: "does not reuse cached registries across gateway subagent binding modes", + name: "does not reuse cached registries across different plugin SDK resolution preferences", setup: () => { useNoBundledPlugins(); const plugin = writePlugin({ - id: "cache-gateway-bindable", - filename: "cache-gateway-bindable.cjs", - body: `module.exports = { id: "cache-gateway-bindable", register() {} };`, + id: "cache-sdk-resolution", + filename: "cache-sdk-resolution.cjs", + body: `module.exports = { id: "cache-sdk-resolution", register() {} };`, }); const options = { workspaceDir: plugin.dir, config: { plugins: { - allow: ["cache-gateway-bindable"], + allow: ["cache-sdk-resolution"], load: { paths: [plugin.file], }, @@ -1779,9 +1779,7 @@ module.exports = { id: "throws-after-import", register() {} };`, loadVariant: () => loadOpenClawPlugins({ ...options, - runtimeOptions: { - allowGatewaySubagentBinding: true, - }, + pluginSdkResolution: "workspace" as const, }), }; }, @@ -1790,6 +1788,34 @@ module.exports = { id: "throws-after-import", register() {} };`, expectCacheMissThenHit(setup()); }); + it("reuses cached registry across gateway subagent binding modes", () => { + useNoBundledPlugins(); + const plugin = writePlugin({ + id: "cache-gateway-shared", + filename: "cache-gateway-shared.cjs", + body: `module.exports = { id: "cache-gateway-shared", register() {} };`, + }); + + const options = { + workspaceDir: plugin.dir, + config: { + plugins: { + allow: ["cache-gateway-shared"], + load: { + paths: [plugin.file], + }, + }, + }, + }; + + const first = loadOpenClawPlugins(options); + const second = loadOpenClawPlugins({ + ...options, + runtimeOptions: { allowGatewaySubagentBinding: true }, + }); + expect(second).toBe(first); + }); + it("evicts least recently used registries when the loader cache exceeds its cap", () => { useNoBundledPlugins(); const plugin = writePlugin({ diff --git a/src/plugins/loader.ts b/src/plugins/loader.ts index d142edcbbf9..562ade0b999 100644 --- a/src/plugins/loader.ts +++ b/src/plugins/loader.ts @@ -285,7 +285,6 @@ function buildCacheKey(params: { includeSetupOnlyChannelPlugins?: boolean; preferSetupRuntimeForChannelPlugins?: boolean; loadModules?: boolean; - runtimeSubagentMode?: "default" | "explicit" | "gateway-bindable"; pluginSdkResolution?: PluginSdkResolutionPreference; coreGatewayMethodNames?: string[]; }): string { @@ -321,7 +320,7 @@ function buildCacheKey(params: { installs, loadPaths, activationMetadataKey: params.activationMetadataKey ?? "", - })}::${scopeKey}::${setupOnlyKey}::${startupChannelMode}::${moduleLoadMode}::${params.runtimeSubagentMode ?? "default"}::${params.pluginSdkResolution ?? "auto"}::${gatewayMethodsKey}`; + })}::${scopeKey}::${setupOnlyKey}::${startupChannelMode}::${moduleLoadMode}::${params.pluginSdkResolution ?? "auto"}::${gatewayMethodsKey}`; } function normalizeScopedPluginIds(ids?: string[]): string[] | undefined { @@ -434,7 +433,6 @@ function resolvePluginLoadCacheContext(options: PluginLoadOptions = {}) { includeSetupOnlyChannelPlugins, preferSetupRuntimeForChannelPlugins, loadModules: options.loadModules, - runtimeSubagentMode: resolveRuntimeSubagentMode(options.runtimeOptions), pluginSdkResolution: options.pluginSdkResolution, coreGatewayMethodNames, });