From 4436ca23ca2601c265d084863521e6cf413a1f5a Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Tue, 7 Apr 2026 03:48:46 +0100 Subject: [PATCH] perf(agents): lazy cli backend setup lookup --- src/agents/model-selection.ts | 4 +- src/plugins/cli-backends.runtime.ts | 26 ++++++++++++- src/plugins/setup-registry.runtime.ts | 56 +++++++++++++++++++++++++++ 3 files changed, 82 insertions(+), 4 deletions(-) create mode 100644 src/plugins/setup-registry.runtime.ts diff --git a/src/agents/model-selection.ts b/src/agents/model-selection.ts index f81c859e443..94b5eefedc3 100644 --- a/src/agents/model-selection.ts +++ b/src/agents/model-selection.ts @@ -7,7 +7,7 @@ import { } from "../config/model-input.js"; import { createSubsystemLogger } from "../logging/subsystem.js"; import { resolveRuntimeCliBackends } from "../plugins/cli-backends.runtime.js"; -import { resolvePluginSetupCliBackend } from "../plugins/setup-registry.js"; +import { resolvePluginSetupCliBackendRuntime } from "../plugins/setup-registry.runtime.js"; import { sanitizeForLog, stripAnsi } from "../terminal/ansi.js"; import { resolveAgentConfig, @@ -94,7 +94,7 @@ export function isCliProvider(provider: string, cfg?: OpenClawConfig): boolean { if (cliBackends.some((backend) => normalizeProviderId(backend.id) === normalized)) { return true; } - if (resolvePluginSetupCliBackend({ backend: normalized })) { + if (resolvePluginSetupCliBackendRuntime({ backend: normalized })) { return true; } const backends = cfg?.agents?.defaults?.cliBackends ?? {}; diff --git a/src/plugins/cli-backends.runtime.ts b/src/plugins/cli-backends.runtime.ts index 2ea34054854..170da48644f 100644 --- a/src/plugins/cli-backends.runtime.ts +++ b/src/plugins/cli-backends.runtime.ts @@ -1,12 +1,34 @@ -import { getActivePluginRegistry } from "./runtime.js"; +import { createRequire } from "node:module"; import type { CliBackendPlugin } from "./types.js"; export type PluginCliBackendEntry = CliBackendPlugin & { pluginId: string; }; +type PluginRuntimeModule = Pick; + +const require = createRequire(import.meta.url); +const RUNTIME_MODULE_CANDIDATES = ["./runtime.js", "./runtime.ts"] as const; + +let pluginRuntimeModule: PluginRuntimeModule | undefined; + +function loadPluginRuntime(): PluginRuntimeModule | null { + if (pluginRuntimeModule) { + return pluginRuntimeModule; + } + for (const candidate of RUNTIME_MODULE_CANDIDATES) { + try { + pluginRuntimeModule = require(candidate) as PluginRuntimeModule; + return pluginRuntimeModule; + } catch { + // Try source/runtime candidates in order. + } + } + return null; +} + export function resolveRuntimeCliBackends(): PluginCliBackendEntry[] { - return (getActivePluginRegistry()?.cliBackends ?? []).map((entry) => ({ + return (loadPluginRuntime()?.getActivePluginRegistry()?.cliBackends ?? []).map((entry) => ({ ...entry.backend, pluginId: entry.pluginId, })); diff --git a/src/plugins/setup-registry.runtime.ts b/src/plugins/setup-registry.runtime.ts new file mode 100644 index 00000000000..8d3e245cba4 --- /dev/null +++ b/src/plugins/setup-registry.runtime.ts @@ -0,0 +1,56 @@ +import { createRequire } from "node:module"; +import { normalizeProviderId } from "../agents/provider-id.js"; +import { BUNDLED_PLUGIN_CONTRACT_SNAPSHOTS } from "./contracts/inventory/bundled-capability-metadata.js"; + +type SetupRegistryRuntimeModule = Pick< + typeof import("./setup-registry.js"), + "resolvePluginSetupCliBackend" +>; + +type SetupCliBackendRuntimeEntry = { + pluginId: string; + backend: { + id: string; + }; +}; + +const require = createRequire(import.meta.url); +const SETUP_REGISTRY_RUNTIME_CANDIDATES = ["./setup-registry.js", "./setup-registry.ts"] as const; + +let setupRegistryRuntimeModule: SetupRegistryRuntimeModule | undefined; + +const BUNDLED_SETUP_CLI_BACKENDS = BUNDLED_PLUGIN_CONTRACT_SNAPSHOTS.flatMap((entry) => + entry.cliBackendIds.map( + (backendId) => + ({ + pluginId: entry.pluginId, + backend: { id: backendId }, + }) satisfies SetupCliBackendRuntimeEntry, + ), +); + +function loadSetupRegistryRuntime(): SetupRegistryRuntimeModule | null { + if (setupRegistryRuntimeModule) { + return setupRegistryRuntimeModule; + } + for (const candidate of SETUP_REGISTRY_RUNTIME_CANDIDATES) { + try { + setupRegistryRuntimeModule = require(candidate) as SetupRegistryRuntimeModule; + return setupRegistryRuntimeModule; + } catch { + // Try source/runtime candidates in order. + } + } + return null; +} + +export function resolvePluginSetupCliBackendRuntime(params: { backend: string }) { + const runtime = loadSetupRegistryRuntime(); + if (runtime) { + return runtime.resolvePluginSetupCliBackend(params); + } + const normalized = normalizeProviderId(params.backend); + return BUNDLED_SETUP_CLI_BACKENDS.find( + (entry) => normalizeProviderId(entry.backend.id) === normalized, + ); +}