perf(agents): lazy cli backend setup lookup

This commit is contained in:
Peter Steinberger
2026-04-07 03:48:46 +01:00
parent 416a3148e9
commit 4436ca23ca
3 changed files with 82 additions and 4 deletions

View File

@@ -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 ?? {};

View File

@@ -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<typeof import("./runtime.js"), "getActivePluginRegistry">;
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,
}));

View File

@@ -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,
);
}