






















@@ -91,8 +91,8 @@ const loadPluginLookUpTable = vi.hoisted(() =>
9191vi.fn((_params: unknown) => ({
9292manifestRegistry: pluginManifestRegistry,
9393startup: {
94-configuredDeferredChannelPluginIds: [],
95-pluginIds: ["telegram"],
94+configuredDeferredChannelPluginIds: [] as string[],
95+pluginIds: ["telegram"] as string[],
9696},
9797metrics: pluginLookUpTableMetrics,
9898})),
@@ -182,8 +182,8 @@ describe("prepareGatewayPluginBootstrap startup plugins", () => {
182182loadPluginLookUpTable.mockClear().mockReturnValue({
183183manifestRegistry: pluginManifestRegistry,
184184startup: {
185-configuredDeferredChannelPluginIds: [],
186-pluginIds: ["telegram"],
185+configuredDeferredChannelPluginIds: [] as string[],
186+pluginIds: ["telegram"] as string[],
187187},
188188metrics: pluginLookUpTableMetrics,
189189});
@@ -306,6 +306,87 @@ describe("prepareGatewayPluginBootstrap startup plugins", () => {
306306dreaming: { enabled: false },
307307});
308308});
309+310+it("loads only deferred setup-runtime plugins during pre-bind bootstrap", async () => {
311+loadPluginLookUpTable.mockReturnValueOnce({
312+manifestRegistry: pluginManifestRegistry,
313+startup: {
314+configuredDeferredChannelPluginIds: ["slack"] as string[],
315+pluginIds: ["slack", "memory-core"] as string[],
316+},
317+metrics: {
318+ ...pluginLookUpTableMetrics,
319+startupPluginCount: 2,
320+deferredChannelPluginCount: 1,
321+},
322+});
323+const cfg = {
324+channels: {
325+slack: { enabled: true, token: "token" },
326+},
327+} as OpenClawConfig;
328+const log = createLog();
329+const { prepareGatewayPluginBootstrap } = await import("./server-startup-plugins.js");
330+331+const result = await prepareGatewayPluginBootstrap({
332+cfgAtStart: cfg,
333+startupRuntimeConfig: cfg,
334+minimalTestGateway: false,
335+ log,
336+loadRuntimePlugins: false,
337+loadSetupRuntimePlugins: true,
338+});
339+340+expect(result.runtimePluginsLoaded).toBe(false);
341+const startupInput = firstCallArg<{
342+pluginIds?: string[];
343+preferSetupRuntimeForChannelPlugins?: boolean;
344+suppressPluginInfoLogs?: boolean;
345+}>(loadGatewayStartupPlugins);
346+expect(startupInput.pluginIds).toEqual(["slack"]);
347+expect(startupInput.preferSetupRuntimeForChannelPlugins).toBe(true);
348+expect(startupInput.suppressPluginInfoLogs).toBe(true);
349+});
350+351+it("does not use setup-runtime preference for full bootstrap loads", async () => {
352+loadPluginLookUpTable.mockReturnValueOnce({
353+manifestRegistry: pluginManifestRegistry,
354+startup: {
355+configuredDeferredChannelPluginIds: ["slack"] as string[],
356+pluginIds: ["slack", "memory-core"] as string[],
357+},
358+metrics: {
359+ ...pluginLookUpTableMetrics,
360+startupPluginCount: 2,
361+deferredChannelPluginCount: 1,
362+},
363+});
364+const cfg = {
365+channels: {
366+slack: { enabled: true, token: "token" },
367+},
368+} as OpenClawConfig;
369+const log = createLog();
370+const { prepareGatewayPluginBootstrap } = await import("./server-startup-plugins.js");
371+372+const result = await prepareGatewayPluginBootstrap({
373+cfgAtStart: cfg,
374+startupRuntimeConfig: cfg,
375+minimalTestGateway: false,
376+ log,
377+});
378+379+expect(result.runtimePluginsLoaded).toBe(true);
380+const startupInput = firstCallArg<{
381+pluginIds?: string[];
382+preferSetupRuntimeForChannelPlugins?: boolean;
383+suppressPluginInfoLogs?: boolean;
384+}>(loadGatewayStartupPlugins);
385+expect(startupInput.pluginIds).toEqual(["slack", "memory-core"]);
386+expect(startupInput.preferSetupRuntimeForChannelPlugins).toBe(false);
387+expect(startupInput.suppressPluginInfoLogs).toBe(false);
388+});
389+309390it("bypasses plugin lookup when plugins are globally disabled", async () => {
310391const cfg = {
311392channels: {
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。