openclaw/src/gateway/server-plugin-bootstrap.ts

96 lines
3.1 KiB
TypeScript

import { primeConfiguredBindingRegistry } from "../channels/plugins/binding-registry.js";
import type { loadConfig } from "../config/config.js";
import type { PluginRegistry } from "../plugins/registry.js";
import { pinActivePluginChannelRegistry } from "../plugins/runtime.js";
import { setGatewaySubagentRuntime } from "../plugins/runtime/index.js";
import type { GatewayRequestHandler } from "./server-methods/types.js";
import {
createGatewaySubagentRuntime,
loadGatewayPlugins,
setPluginSubagentOverridePolicies,
} from "./server-plugins.js";
type GatewayPluginBootstrapLog = {
info: (msg: string) => void;
warn: (msg: string) => void;
error: (msg: string) => void;
debug: (msg: string) => void;
};
type GatewayPluginBootstrapParams = {
cfg: ReturnType<typeof loadConfig>;
workspaceDir: string;
log: GatewayPluginBootstrapLog;
coreGatewayHandlers: Record<string, GatewayRequestHandler>;
baseMethods: string[];
preferSetupRuntimeForChannelPlugins?: boolean;
logDiagnostics?: boolean;
beforePrimeRegistry?: (pluginRegistry: PluginRegistry) => void;
};
function installGatewayPluginRuntimeEnvironment(cfg: ReturnType<typeof loadConfig>) {
setPluginSubagentOverridePolicies(cfg);
setGatewaySubagentRuntime(createGatewaySubagentRuntime());
}
function logGatewayPluginDiagnostics(params: {
diagnostics: PluginRegistry["diagnostics"];
log: Pick<GatewayPluginBootstrapLog, "error" | "info">;
}) {
for (const diag of params.diagnostics) {
const details = [
diag.pluginId ? `plugin=${diag.pluginId}` : null,
diag.source ? `source=${diag.source}` : null,
]
.filter((entry): entry is string => Boolean(entry))
.join(", ");
const message = details
? `[plugins] ${diag.message} (${details})`
: `[plugins] ${diag.message}`;
if (diag.level === "error") {
params.log.error(message);
} else {
params.log.info(message);
}
}
}
export function prepareGatewayPluginLoad(params: GatewayPluginBootstrapParams) {
installGatewayPluginRuntimeEnvironment(params.cfg);
const loaded = loadGatewayPlugins({
cfg: params.cfg,
workspaceDir: params.workspaceDir,
log: params.log,
coreGatewayHandlers: params.coreGatewayHandlers,
baseMethods: params.baseMethods,
preferSetupRuntimeForChannelPlugins: params.preferSetupRuntimeForChannelPlugins,
});
params.beforePrimeRegistry?.(loaded.pluginRegistry);
primeConfiguredBindingRegistry({ cfg: params.cfg });
if ((params.logDiagnostics ?? true) && loaded.pluginRegistry.diagnostics.length > 0) {
logGatewayPluginDiagnostics({
diagnostics: loaded.pluginRegistry.diagnostics,
log: params.log,
});
}
return loaded;
}
export function loadGatewayStartupPlugins(
params: Omit<GatewayPluginBootstrapParams, "beforePrimeRegistry">,
) {
return prepareGatewayPluginLoad(params);
}
export function reloadDeferredGatewayPlugins(
params: Omit<
GatewayPluginBootstrapParams,
"beforePrimeRegistry" | "preferSetupRuntimeForChannelPlugins"
>,
) {
return prepareGatewayPluginLoad({
...params,
beforePrimeRegistry: pinActivePluginChannelRegistry,
});
}