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; workspaceDir: string; log: GatewayPluginBootstrapLog; coreGatewayHandlers: Record; baseMethods: string[]; preferSetupRuntimeForChannelPlugins?: boolean; logDiagnostics?: boolean; beforePrimeRegistry?: (pluginRegistry: PluginRegistry) => void; }; function installGatewayPluginRuntimeEnvironment(cfg: ReturnType) { setPluginSubagentOverridePolicies(cfg); setGatewaySubagentRuntime(createGatewaySubagentRuntime()); } function logGatewayPluginDiagnostics(params: { diagnostics: PluginRegistry["diagnostics"]; log: Pick; }) { 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, ) { return prepareGatewayPluginLoad(params); } export function reloadDeferredGatewayPlugins( params: Omit< GatewayPluginBootstrapParams, "beforePrimeRegistry" | "preferSetupRuntimeForChannelPlugins" >, ) { return prepareGatewayPluginLoad({ ...params, beforePrimeRegistry: pinActivePluginChannelRegistry, }); }