diff --git a/src/gateway/server-plugins.test.ts b/src/gateway/server-plugins.test.ts index 8af13556dea..6758a7a9b1d 100644 --- a/src/gateway/server-plugins.test.ts +++ b/src/gateway/server-plugins.test.ts @@ -7,6 +7,7 @@ import type { GatewayRequestContext, GatewayRequestOptions } from "./server-meth const loadOpenClawPlugins = vi.hoisted(() => vi.fn()); const resolveGatewayStartupPluginIds = vi.hoisted(() => vi.fn(() => ["discord", "telegram"])); +const applyPluginAutoEnable = vi.hoisted(() => vi.fn(({ config }) => ({ config, changes: [] }))); const primeConfiguredBindingRegistry = vi.hoisted(() => vi.fn(() => ({ bindingCount: 0, channelCount: 0 })), ); @@ -25,6 +26,10 @@ vi.mock("../plugins/channel-plugin-ids.js", () => ({ resolveGatewayStartupPluginIds, })); +vi.mock("../config/plugin-auto-enable.js", () => ({ + applyPluginAutoEnable, +})); + vi.mock("../channels/plugins/binding-registry.js", async (importOriginal) => { const actual = await importOriginal(); return { @@ -185,6 +190,7 @@ beforeAll(async () => { beforeEach(() => { loadOpenClawPlugins.mockReset(); resolveGatewayStartupPluginIds.mockReset().mockReturnValue(["discord", "telegram"]); + applyPluginAutoEnable.mockReset().mockImplementation(({ config }) => ({ config, changes: [] })); primeConfiguredBindingRegistry.mockClear().mockReturnValue({ bindingCount: 0, channelCount: 0 }); handleGatewayRequest.mockReset(); runtimeModule.clearGatewaySubagentRuntime(); @@ -235,6 +241,10 @@ describe("loadGatewayPlugins", () => { loadOpenClawPlugins.mockReturnValue(createRegistry([])); loadGatewayPluginsForTest(); + expect(applyPluginAutoEnable).toHaveBeenCalledWith({ + config: {}, + env: process.env, + }); expect(resolveGatewayStartupPluginIds).toHaveBeenCalledWith({ config: {}, workspaceDir: "/tmp", @@ -247,6 +257,25 @@ describe("loadGatewayPlugins", () => { ); }); + test("loads gateway plugins from the auto-enabled config snapshot", async () => { + const autoEnabledConfig = { channels: { slack: { enabled: true } }, autoEnabled: true }; + applyPluginAutoEnable.mockReturnValue({ config: autoEnabledConfig, changes: [] }); + loadOpenClawPlugins.mockReturnValue(createRegistry([])); + + loadGatewayPluginsForTest(); + + expect(resolveGatewayStartupPluginIds).toHaveBeenCalledWith({ + config: autoEnabledConfig, + workspaceDir: "/tmp", + env: process.env, + }); + expect(loadOpenClawPlugins).toHaveBeenCalledWith( + expect.objectContaining({ + config: autoEnabledConfig, + }), + ); + }); + test("provides subagent runtime with sessions.get method aliases", async () => { loadOpenClawPlugins.mockReturnValue(createRegistry([])); loadGatewayPluginsForTest(); diff --git a/src/gateway/server-plugins.ts b/src/gateway/server-plugins.ts index c59e4be6982..e599d32c18b 100644 --- a/src/gateway/server-plugins.ts +++ b/src/gateway/server-plugins.ts @@ -1,6 +1,7 @@ import { randomUUID } from "node:crypto"; import { normalizeModelRef, parseModelRef } from "../agents/model-selection.js"; import type { loadConfig } from "../config/config.js"; +import { applyPluginAutoEnable } from "../config/plugin-auto-enable.js"; import { resolveGatewayStartupPluginIds } from "../plugins/channel-plugin-ids.js"; import { normalizePluginsConfig } from "../plugins/config-state.js"; import { loadOpenClawPlugins } from "../plugins/loader.js"; @@ -390,11 +391,15 @@ export function loadGatewayPlugins(params: { baseMethods: string[]; preferSetupRuntimeForChannelPlugins?: boolean; }) { - const pluginRegistry = loadOpenClawPlugins({ + const resolvedConfig = applyPluginAutoEnable({ config: params.cfg, + env: process.env, + }).config; + const pluginRegistry = loadOpenClawPlugins({ + config: resolvedConfig, workspaceDir: params.workspaceDir, onlyPluginIds: resolveGatewayStartupPluginIds({ - config: params.cfg, + config: resolvedConfig, workspaceDir: params.workspaceDir, env: process.env, }),