refactor: use plugin lookup table for gateway load fallback

This commit is contained in:
Shakker
2026-04-27 07:22:57 +01:00
parent 123dee0513
commit dc6ac472db
2 changed files with 33 additions and 15 deletions

View File

@@ -6,7 +6,13 @@ import type { PluginDiagnostic } from "../plugins/types.js";
import type { GatewayRequestContext, GatewayRequestOptions } from "./server-methods/types.js";
const loadOpenClawPlugins = vi.hoisted(() => vi.fn());
const resolveGatewayStartupPluginIds = vi.hoisted(() => vi.fn(() => ["discord", "telegram"]));
const loadPluginLookUpTable = vi.hoisted(() =>
vi.fn(() => ({
startup: {
pluginIds: ["discord", "telegram"],
},
})),
);
const applyPluginAutoEnable = vi.hoisted(() =>
vi.fn(({ config }) => ({ config, changes: [], autoEnabledReasons: {} })),
);
@@ -34,8 +40,8 @@ vi.mock("../plugins/runtime/load-context.js", () => ({
createPluginRuntimeLoaderLogger: () => pluginRuntimeLoaderLogger,
}));
vi.mock("../plugins/channel-plugin-ids.js", () => ({
resolveGatewayStartupPluginIds,
vi.mock("../plugins/plugin-lookup-table.js", () => ({
loadPluginLookUpTable,
}));
vi.mock("../config/plugin-auto-enable.js", () => ({
@@ -243,7 +249,11 @@ beforeAll(async () => {
beforeEach(() => {
loadOpenClawPlugins.mockReset();
resolveGatewayStartupPluginIds.mockReset().mockReturnValue(["discord", "telegram"]);
loadPluginLookUpTable.mockReset().mockReturnValue({
startup: {
pluginIds: ["discord", "telegram"],
},
});
applyPluginAutoEnable
.mockReset()
.mockImplementation(({ config }) => ({ config, changes: [], autoEnabledReasons: {} }));
@@ -306,7 +316,7 @@ describe("loadGatewayPlugins", () => {
config: {},
env: process.env,
});
expect(resolveGatewayStartupPluginIds).toHaveBeenCalledWith({
expect(loadPluginLookUpTable).toHaveBeenCalledWith({
config: {},
activationSourceConfig: undefined,
workspaceDir: "/tmp",
@@ -354,7 +364,7 @@ describe("loadGatewayPlugins", () => {
pluginIds: ["browser"],
});
expect(resolveGatewayStartupPluginIds).not.toHaveBeenCalled();
expect(loadPluginLookUpTable).not.toHaveBeenCalled();
expect(loadOpenClawPlugins).toHaveBeenCalledWith(
expect.objectContaining({
onlyPluginIds: ["browser"],
@@ -397,7 +407,7 @@ describe("loadGatewayPlugins", () => {
pluginIds: ["slack"],
});
expect(resolveGatewayStartupPluginIds).not.toHaveBeenCalled();
expect(loadPluginLookUpTable).not.toHaveBeenCalled();
expect(applyPluginAutoEnable).toHaveBeenCalledWith({
config: rawConfig,
env: process.env,
@@ -415,7 +425,11 @@ describe("loadGatewayPlugins", () => {
});
test("treats an empty startup scope as no plugin load instead of an unscoped load", async () => {
resolveGatewayStartupPluginIds.mockReturnValue([]);
loadPluginLookUpTable.mockReturnValue({
startup: {
pluginIds: [],
},
});
const result = serverPluginsModule.loadGatewayPlugins({
cfg: {},
@@ -431,7 +445,11 @@ describe("loadGatewayPlugins", () => {
});
test("stores workspaceDir on the active registry when startup scope is empty", () => {
resolveGatewayStartupPluginIds.mockReturnValue([]);
loadPluginLookUpTable.mockReturnValue({
startup: {
pluginIds: [],
},
});
serverPluginsModule.loadGatewayPlugins({
cfg: {},
@@ -457,7 +475,7 @@ describe("loadGatewayPlugins", () => {
loadGatewayPluginsForTest();
expect(resolveGatewayStartupPluginIds).toHaveBeenCalledWith({
expect(loadPluginLookUpTable).toHaveBeenCalledWith({
config: autoEnabledConfig,
activationSourceConfig: undefined,
workspaceDir: "/tmp",
@@ -495,7 +513,7 @@ describe("loadGatewayPlugins", () => {
config: rawConfig,
env: process.env,
});
expect(resolveGatewayStartupPluginIds).toHaveBeenCalledWith({
expect(loadPluginLookUpTable).toHaveBeenCalledWith({
config: resolvedConfig,
activationSourceConfig: rawConfig,
workspaceDir: "/tmp",
@@ -979,7 +997,7 @@ describe("loadGatewayPlugins", () => {
logDiagnostics: false,
});
expect(resolveGatewayStartupPluginIds).not.toHaveBeenCalled();
expect(loadPluginLookUpTable).not.toHaveBeenCalled();
expect(loadOpenClawPlugins).toHaveBeenCalledWith(
expect.objectContaining({
onlyPluginIds: ["discord"],

View File

@@ -3,9 +3,9 @@ import { normalizeModelRef, parseModelRef } from "../agents/model-selection.js";
import { applyPluginAutoEnable } from "../config/plugin-auto-enable.js";
import type { OpenClawConfig } from "../config/types.openclaw.js";
import type { BundledRuntimeDepsInstallParams } from "../plugins/bundled-runtime-deps.js";
import { resolveGatewayStartupPluginIds } from "../plugins/channel-plugin-ids.js";
import { normalizePluginsConfig } from "../plugins/config-state.js";
import { loadOpenClawPlugins } from "../plugins/loader.js";
import { loadPluginLookUpTable } from "../plugins/plugin-lookup-table.js";
import { createEmptyPluginRegistry } from "../plugins/registry-empty.js";
import { setActivePluginRegistry } from "../plugins/runtime.js";
import { getPluginRuntimeGatewayRequestScope } from "../plugins/runtime/gateway-request-scope.js";
@@ -479,12 +479,12 @@ export function loadGatewayPlugins(params: {
const resolvedConfig = autoEnabled.config;
const pluginIds =
params.pluginIds ??
resolveGatewayStartupPluginIds({
loadPluginLookUpTable({
config: resolvedConfig,
activationSourceConfig: params.activationSourceConfig,
workspaceDir: params.workspaceDir,
env: process.env,
});
}).startup.pluginIds;
if (pluginIds.length === 0) {
const pluginRegistry = createEmptyPluginRegistry();
setActivePluginRegistry(pluginRegistry, undefined, "gateway-bindable", params.workspaceDir);