perf(plugins): lazy-load setup surfaces

This commit is contained in:
Peter Steinberger
2026-03-15 18:46:22 -07:00
parent de6666b895
commit fb991e6f31
30 changed files with 443 additions and 16 deletions

View File

@@ -1703,6 +1703,188 @@ module.exports = { id: "skipped", register() { throw new Error("skipped plugin s
expect(disabled?.status).toBe("disabled");
});
it("skips disabled channel imports unless setup-only loading is explicitly enabled", () => {
useNoBundledPlugins();
const marker = path.join(makeTempDir(), "lazy-channel-imported.txt");
const plugin = writePlugin({
id: "lazy-channel",
filename: "lazy-channel.cjs",
body: `require("node:fs").writeFileSync(${JSON.stringify(marker)}, "loaded", "utf-8");
module.exports = {
id: "lazy-channel",
register(api) {
api.registerChannel({
plugin: {
id: "lazy-channel",
meta: {
id: "lazy-channel",
label: "Lazy Channel",
selectionLabel: "Lazy Channel",
docsPath: "/channels/lazy-channel",
blurb: "lazy test channel",
},
capabilities: { chatTypes: ["direct"] },
config: {
listAccountIds: () => [],
resolveAccount: () => ({ accountId: "default" }),
},
outbound: { deliveryMode: "direct" },
},
});
},
};`,
});
fs.writeFileSync(
path.join(plugin.dir, "openclaw.plugin.json"),
JSON.stringify(
{
id: "lazy-channel",
configSchema: EMPTY_PLUGIN_SCHEMA,
channels: ["lazy-channel"],
},
null,
2,
),
"utf-8",
);
const config = {
plugins: {
load: { paths: [plugin.file] },
allow: ["lazy-channel"],
entries: {
"lazy-channel": { enabled: false },
},
},
};
const registry = loadOpenClawPlugins({
cache: false,
config,
});
expect(fs.existsSync(marker)).toBe(false);
expect(registry.channelSetups).toHaveLength(0);
expect(registry.plugins.find((entry) => entry.id === "lazy-channel")?.status).toBe("disabled");
const setupRegistry = loadOpenClawPlugins({
cache: false,
config,
includeSetupOnlyChannelPlugins: true,
});
expect(fs.existsSync(marker)).toBe(true);
expect(setupRegistry.channelSetups).toHaveLength(1);
expect(setupRegistry.channels).toHaveLength(0);
expect(setupRegistry.plugins.find((entry) => entry.id === "lazy-channel")?.status).toBe(
"disabled",
);
});
it("uses package setupEntry for setup-only channel loads", () => {
useNoBundledPlugins();
const pluginDir = makeTempDir();
const fullMarker = path.join(pluginDir, "full-loaded.txt");
const setupMarker = path.join(pluginDir, "setup-loaded.txt");
fs.writeFileSync(
path.join(pluginDir, "package.json"),
JSON.stringify(
{
name: "@openclaw/setup-entry-test",
openclaw: {
extensions: ["./index.cjs"],
setupEntry: "./setup-entry.cjs",
},
},
null,
2,
),
"utf-8",
);
fs.writeFileSync(
path.join(pluginDir, "openclaw.plugin.json"),
JSON.stringify(
{
id: "setup-entry-test",
configSchema: EMPTY_PLUGIN_SCHEMA,
channels: ["setup-entry-test"],
},
null,
2,
),
"utf-8",
);
fs.writeFileSync(
path.join(pluginDir, "index.cjs"),
`require("node:fs").writeFileSync(${JSON.stringify(fullMarker)}, "loaded", "utf-8");
module.exports = {
id: "setup-entry-test",
register(api) {
api.registerChannel({
plugin: {
id: "setup-entry-test",
meta: {
id: "setup-entry-test",
label: "Setup Entry Test",
selectionLabel: "Setup Entry Test",
docsPath: "/channels/setup-entry-test",
blurb: "full entry should not run in setup-only mode",
},
capabilities: { chatTypes: ["direct"] },
config: {
listAccountIds: () => [],
resolveAccount: () => ({ accountId: "default" }),
},
outbound: { deliveryMode: "direct" },
},
});
},
};`,
"utf-8",
);
fs.writeFileSync(
path.join(pluginDir, "setup-entry.cjs"),
`require("node:fs").writeFileSync(${JSON.stringify(setupMarker)}, "loaded", "utf-8");
module.exports = {
plugin: {
id: "setup-entry-test",
meta: {
id: "setup-entry-test",
label: "Setup Entry Test",
selectionLabel: "Setup Entry Test",
docsPath: "/channels/setup-entry-test",
blurb: "setup entry",
},
capabilities: { chatTypes: ["direct"] },
config: {
listAccountIds: () => [],
resolveAccount: () => ({ accountId: "default" }),
},
outbound: { deliveryMode: "direct" },
},
};`,
"utf-8",
);
const setupRegistry = loadOpenClawPlugins({
cache: false,
config: {
plugins: {
load: { paths: [pluginDir] },
allow: ["setup-entry-test"],
entries: {
"setup-entry-test": { enabled: false },
},
},
},
includeSetupOnlyChannelPlugins: true,
});
expect(fs.existsSync(setupMarker)).toBe(true);
expect(fs.existsSync(fullMarker)).toBe(false);
expect(setupRegistry.channelSetups).toHaveLength(1);
expect(setupRegistry.channels).toHaveLength(0);
});
it("blocks before_prompt_build but preserves legacy model overrides when prompt injection is disabled", async () => {
useNoBundledPlugins();
const plugin = writePlugin({