diff --git a/src/plugins/loader.test.ts b/src/plugins/loader.test.ts index 09052bb6d41..b92c3a6814f 100644 --- a/src/plugins/loader.test.ts +++ b/src/plugins/loader.test.ts @@ -2361,23 +2361,78 @@ module.exports = { id: "throws-after-import", register() {} };`, ).toBe(true); }); - it("can scope bundled provider loads to deepseek without hanging", () => { + it("can scope bundled provider loads without hanging", () => { + const bundledDir = makeTempDir(); + const scopedDir = path.join(bundledDir, "scoped-provider"); + mkdirSafe(scopedDir); + fs.writeFileSync( + path.join(scopedDir, "package.json"), + JSON.stringify({ + name: "@openclaw/scoped-provider", + openclaw: { extensions: ["./index.cjs"] }, + }), + "utf-8", + ); + const plugin = writePlugin({ + id: "scoped-provider", + dir: scopedDir, + filename: "index.cjs", + body: `module.exports = { + id: "scoped-provider", + register(api) { + api.registerProvider({ + id: "scoped-provider", + label: "Scoped Provider", + auth: [], + }); + }, + };`, + }); + updatePluginManifest(plugin, { enabledByDefault: true, providers: ["scoped-provider"] }); + + const unscopedDir = path.join(bundledDir, "unscoped-provider"); + mkdirSafe(unscopedDir); + fs.writeFileSync( + path.join(unscopedDir, "package.json"), + JSON.stringify({ + name: "@openclaw/unscoped-provider", + openclaw: { extensions: ["./index.cjs"] }, + }), + "utf-8", + ); + const unscoped = writePlugin({ + id: "unscoped-provider", + dir: unscopedDir, + filename: "index.cjs", + body: `module.exports = { + id: "unscoped-provider", + register() { + throw new Error("unscoped provider should not load"); + }, + };`, + }); + updatePluginManifest(unscoped, { + enabledByDefault: true, + providers: ["unscoped-provider"], + }); + process.env.OPENCLAW_BUNDLED_PLUGINS_DIR = bundledDir; + delete process.env.OPENCLAW_DISABLE_BUNDLED_PLUGINS; + const scoped = loadOpenClawPlugins({ cache: false, activate: false, - pluginSdkResolution: "dist", config: { plugins: { enabled: true, - allow: ["deepseek"], + allow: ["scoped-provider", "unscoped-provider"], }, }, - onlyPluginIds: ["deepseek"], + onlyPluginIds: ["scoped-provider"], }); - expect(scoped.plugins.map((entry) => entry.id)).toEqual(["deepseek"]); + expect(scoped.plugins.map((entry) => entry.id)).toEqual(["scoped-provider"]); expect(scoped.plugins[0]?.status).toBe("loaded"); - expect(scoped.providers.map((entry) => entry.provider.id)).toEqual(["deepseek"]); + expect(scoped.providers.map((entry) => entry.provider.id)).toEqual(["scoped-provider"]); }); it("does not replace active memory plugin registries during non-activating loads", () => {