From bfa6708c03f24c7caa5d0a96a298c292be0d85c1 Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Fri, 24 Apr 2026 05:48:26 +0100 Subject: [PATCH] perf: narrow gateway runtime reset imports --- src/gateway/server-plugin-bootstrap.ts | 5 ++- src/gateway/test-helpers.server.ts | 2 +- src/plugins/runtime/gateway-bindings.ts | 42 ++++++++++++++++++++ src/plugins/runtime/index.ts | 52 ++++++------------------- 4 files changed, 58 insertions(+), 43 deletions(-) create mode 100644 src/plugins/runtime/gateway-bindings.ts diff --git a/src/gateway/server-plugin-bootstrap.ts b/src/gateway/server-plugin-bootstrap.ts index aadcb81136d..63c4a35c7fa 100644 --- a/src/gateway/server-plugin-bootstrap.ts +++ b/src/gateway/server-plugin-bootstrap.ts @@ -3,7 +3,10 @@ import { applyPluginAutoEnable } from "../config/plugin-auto-enable.js"; import type { OpenClawConfig } from "../config/types.openclaw.js"; import type { PluginRegistry } from "../plugins/registry.js"; import { pinActivePluginChannelRegistry } from "../plugins/runtime.js"; -import { setGatewayNodesRuntime, setGatewaySubagentRuntime } from "../plugins/runtime/index.js"; +import { + setGatewayNodesRuntime, + setGatewaySubagentRuntime, +} from "../plugins/runtime/gateway-bindings.js"; import type { GatewayRequestHandler } from "./server-methods/types.js"; import { createGatewayNodesRuntime, diff --git a/src/gateway/test-helpers.server.ts b/src/gateway/test-helpers.server.ts index e3512f60c07..cdc42e6570b 100644 --- a/src/gateway/test-helpers.server.ts +++ b/src/gateway/test-helpers.server.ts @@ -20,7 +20,7 @@ import { import { drainSystemEvents, peekSystemEvents } from "../infra/system-events.js"; import { rawDataToString } from "../infra/ws.js"; import { resetLogger, setLoggerOverride } from "../logging.js"; -import { clearGatewaySubagentRuntime } from "../plugins/runtime/index.js"; +import { clearGatewaySubagentRuntime } from "../plugins/runtime/gateway-bindings.js"; import { DEFAULT_AGENT_ID, normalizeMainKey, diff --git a/src/plugins/runtime/gateway-bindings.ts b/src/plugins/runtime/gateway-bindings.ts new file mode 100644 index 00000000000..1b683cbd1d3 --- /dev/null +++ b/src/plugins/runtime/gateway-bindings.ts @@ -0,0 +1,42 @@ +import { resolveGlobalSingleton } from "../../shared/global-singleton.js"; +import type { PluginRuntime } from "./types.js"; + +const GATEWAY_SUBAGENT_SYMBOL: unique symbol = Symbol.for( + "openclaw.plugin.gatewaySubagentRuntime", +) as unknown as typeof GATEWAY_SUBAGENT_SYMBOL; + +type GatewaySubagentState = { + subagent: PluginRuntime["subagent"] | undefined; + nodes: PluginRuntime["nodes"] | undefined; +}; + +export const gatewaySubagentState = resolveGlobalSingleton( + GATEWAY_SUBAGENT_SYMBOL, + () => ({ + subagent: undefined, + nodes: undefined, + }), +); + +/** + * Set the process-global gateway subagent runtime. + * Called during gateway startup so that gateway-bindable plugin runtimes can + * resolve subagent methods dynamically even when their registry was cached + * before the gateway finished loading plugins. + */ +export function setGatewaySubagentRuntime(subagent: PluginRuntime["subagent"]): void { + gatewaySubagentState.subagent = subagent; +} + +export function setGatewayNodesRuntime(nodes: PluginRuntime["nodes"]): void { + gatewaySubagentState.nodes = nodes; +} + +/** + * Reset the process-global gateway subagent runtime. + * Used by tests to avoid leaking gateway state across module reloads. + */ +export function clearGatewaySubagentRuntime(): void { + gatewaySubagentState.subagent = undefined; + gatewaySubagentState.nodes = undefined; +} diff --git a/src/plugins/runtime/index.ts b/src/plugins/runtime/index.ts index b8bc2c6643a..f0b270b5f43 100644 --- a/src/plugins/runtime/index.ts +++ b/src/plugins/runtime/index.ts @@ -8,7 +8,6 @@ import { listRuntimeMusicGenerationProviders, } from "../../music-generation/runtime.js"; import { RequestScopedSubagentRuntimeError } from "../../plugin-sdk/error-runtime.js"; -import { resolveGlobalSingleton } from "../../shared/global-singleton.js"; import { createLazyRuntimeMethod, createLazyRuntimeMethodBinder, @@ -20,6 +19,12 @@ import { listRuntimeVideoGenerationProviders, } from "../../video-generation/runtime.js"; import { listWebSearchProviders, runWebSearch } from "../../web-search/runtime.js"; +import { + gatewaySubagentState, + setGatewayNodesRuntime, + setGatewaySubagentRuntime, + clearGatewaySubagentRuntime, +} from "./gateway-bindings.js"; import { createRuntimeAgent } from "./runtime-agent.js"; import { defineCachedValue } from "./runtime-cache.js"; import { createRuntimeChannel } from "./runtime-channel.js"; @@ -33,6 +38,11 @@ import { createRuntimeTasks } from "./runtime-tasks.js"; import type { CreatePluginRuntimeOptions, PluginRuntime } from "./types.js"; export type { CreatePluginRuntimeOptions } from "./types.js"; +export { + clearGatewaySubagentRuntime, + setGatewayNodesRuntime, + setGatewaySubagentRuntime, +} from "./gateway-bindings.js"; const loadTtsRuntime = createLazyRuntimeModule(() => import("../../tts/tts.js")); const loadMediaUnderstandingRuntime = createLazyRuntimeModule( @@ -140,46 +150,6 @@ function createUnavailableSubagentRuntime(): PluginRuntime["subagent"] { // active gateway subagent dynamically without changing the default behavior for // ordinary plugin runtimes. -const GATEWAY_SUBAGENT_SYMBOL: unique symbol = Symbol.for( - "openclaw.plugin.gatewaySubagentRuntime", -) as unknown as typeof GATEWAY_SUBAGENT_SYMBOL; - -type GatewaySubagentState = { - subagent: PluginRuntime["subagent"] | undefined; - nodes: PluginRuntime["nodes"] | undefined; -}; - -const gatewaySubagentState = resolveGlobalSingleton( - GATEWAY_SUBAGENT_SYMBOL, - () => ({ - subagent: undefined, - nodes: undefined, - }), -); - -/** - * Set the process-global gateway subagent runtime. - * Called during gateway startup so that gateway-bindable plugin runtimes can - * resolve subagent methods dynamically even when their registry was cached - * before the gateway finished loading plugins. - */ -export function setGatewaySubagentRuntime(subagent: PluginRuntime["subagent"]): void { - gatewaySubagentState.subagent = subagent; -} - -export function setGatewayNodesRuntime(nodes: PluginRuntime["nodes"]): void { - gatewaySubagentState.nodes = nodes; -} - -/** - * Reset the process-global gateway subagent runtime. - * Used by tests to avoid leaking gateway state across module reloads. - */ -export function clearGatewaySubagentRuntime(): void { - gatewaySubagentState.subagent = undefined; - gatewaySubagentState.nodes = undefined; -} - /** * Create a late-binding subagent that resolves to: * 1. An explicitly provided subagent (from runtimeOptions), OR