From 74a57ace10bce2f3e80639127101a683c60e456b Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Sun, 15 Mar 2026 18:20:29 -0700 Subject: [PATCH] refactor(plugins): lazy load provider runtime shims --- src/agents/model-auth.ts | 10 +++++++++- src/agents/model-catalog.ts | 18 ++++++++++++++++-- src/agents/model-suppression.runtime.ts | 1 + src/plugins/provider-runtime.runtime.ts | 4 ++++ src/plugins/provider-runtime.test.ts | 5 +++-- 5 files changed, 33 insertions(+), 5 deletions(-) create mode 100644 src/agents/model-suppression.runtime.ts create mode 100644 src/plugins/provider-runtime.runtime.ts diff --git a/src/agents/model-auth.ts b/src/agents/model-auth.ts index 7064b2fcd01..0616bc41194 100644 --- a/src/agents/model-auth.ts +++ b/src/agents/model-auth.ts @@ -6,7 +6,6 @@ import type { ModelProviderAuthMode, ModelProviderConfig } from "../config/types import { coerceSecretRef } from "../config/types.secrets.js"; import { getShellEnvAppliedKeys } from "../infra/shell-env.js"; import { createSubsystemLogger } from "../logging/subsystem.js"; -import { buildProviderMissingAuthMessageWithPlugin } from "../plugins/provider-runtime.js"; import { normalizeOptionalSecretInput, normalizeSecretInput, @@ -36,6 +35,14 @@ const AWS_BEARER_ENV = "AWS_BEARER_TOKEN_BEDROCK"; const AWS_ACCESS_KEY_ENV = "AWS_ACCESS_KEY_ID"; const AWS_SECRET_KEY_ENV = "AWS_SECRET_ACCESS_KEY"; const AWS_PROFILE_ENV = "AWS_PROFILE"; +let providerRuntimePromise: + | Promise + | undefined; + +function loadProviderRuntime() { + providerRuntimePromise ??= import("../plugins/provider-runtime.runtime.js"); + return providerRuntimePromise; +} function resolveProviderConfig( cfg: OpenClawConfig | undefined, @@ -359,6 +366,7 @@ export async function resolveApiKeyForProvider(params: { return resolveAwsSdkAuthInfo(); } + const { buildProviderMissingAuthMessageWithPlugin } = await loadProviderRuntime(); const pluginMissingAuthMessage = buildProviderMissingAuthMessageWithPlugin({ provider, config: cfg, diff --git a/src/agents/model-catalog.ts b/src/agents/model-catalog.ts index 4274333a518..983150f8d36 100644 --- a/src/agents/model-catalog.ts +++ b/src/agents/model-catalog.ts @@ -1,8 +1,6 @@ import { type OpenClawConfig, loadConfig } from "../config/config.js"; import { createSubsystemLogger } from "../logging/subsystem.js"; -import { augmentModelCatalogWithProviderPlugins } from "../plugins/provider-runtime.js"; import { resolveOpenClawAgentDir } from "./agent-paths.js"; -import { shouldSuppressBuiltInModel } from "./model-suppression.js"; import { ensureOpenClawModelsJson } from "./models-config.js"; const log = createSubsystemLogger("model-catalog"); @@ -33,9 +31,23 @@ let modelCatalogPromise: Promise | null = null; let hasLoggedModelCatalogError = false; const defaultImportPiSdk = () => import("./pi-model-discovery-runtime.js"); let importPiSdk = defaultImportPiSdk; +let providerRuntimePromise: + | Promise + | undefined; +let modelSuppressionPromise: Promise | undefined; const NON_PI_NATIVE_MODEL_PROVIDERS = new Set(["kilocode"]); +function loadProviderRuntime() { + providerRuntimePromise ??= import("../plugins/provider-runtime.runtime.js"); + return providerRuntimePromise; +} + +function loadModelSuppression() { + modelSuppressionPromise ??= import("./model-suppression.runtime.js"); + return modelSuppressionPromise; +} + function normalizeConfiguredModelInput(input: unknown): ModelInputType[] | undefined { if (!Array.isArray(input)) { return undefined; @@ -160,6 +172,8 @@ export async function loadModelCatalog(params?: { // will keep failing until restart). const piSdk = await importPiSdk(); const agentDir = resolveOpenClawAgentDir(); + const [{ shouldSuppressBuiltInModel }, { augmentModelCatalogWithProviderPlugins }] = + await Promise.all([loadModelSuppression(), loadProviderRuntime()]); const { join } = await import("node:path"); const authStorage = piSdk.discoverAuthStorage(agentDir); const registry = new (piSdk.ModelRegistry as unknown as { diff --git a/src/agents/model-suppression.runtime.ts b/src/agents/model-suppression.runtime.ts new file mode 100644 index 00000000000..472a662b810 --- /dev/null +++ b/src/agents/model-suppression.runtime.ts @@ -0,0 +1 @@ +export { shouldSuppressBuiltInModel } from "./model-suppression.js"; diff --git a/src/plugins/provider-runtime.runtime.ts b/src/plugins/provider-runtime.runtime.ts new file mode 100644 index 00000000000..34a46e1bdac --- /dev/null +++ b/src/plugins/provider-runtime.runtime.ts @@ -0,0 +1,4 @@ +export { + augmentModelCatalogWithProviderPlugins, + buildProviderMissingAuthMessageWithPlugin, +} from "./provider-runtime.js"; diff --git a/src/plugins/provider-runtime.test.ts b/src/plugins/provider-runtime.test.ts index af5066b5453..24bd47a915f 100644 --- a/src/plugins/provider-runtime.test.ts +++ b/src/plugins/provider-runtime.test.ts @@ -81,8 +81,9 @@ describe("provider-runtime", () => { displayName: "Demo", windows: [{ label: "Day", usedPercent: 25 }], })); - resolvePluginProvidersMock.mockImplementation((params?: { onlyPluginIds?: string[] }) => { - if (params?.onlyPluginIds?.includes("openai")) { + resolvePluginProvidersMock.mockImplementation((params: unknown) => { + const scopedParams = params as { onlyPluginIds?: string[] } | undefined; + if (scopedParams?.onlyPluginIds?.includes("openai")) { return [ { id: "openai",