From 6217561931caff871d288a823c4eaefe5a78b6e6 Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Sun, 15 Feb 2026 06:33:37 +0000 Subject: [PATCH] refactor(commands): dedupe provider config + default model helpers --- src/commands/onboard-auth.config-core.ts | 157 +++++--------------- src/commands/onboard-auth.config-litellm.ts | 24 +-- src/commands/onboard-auth.config-shared.ts | 72 ++++++++- 3 files changed, 107 insertions(+), 146 deletions(-) diff --git a/src/commands/onboard-auth.config-core.ts b/src/commands/onboard-auth.config-core.ts index 1b2252ffc74..ed18b742991 100644 --- a/src/commands/onboard-auth.config-core.ts +++ b/src/commands/onboard-auth.config-core.ts @@ -48,7 +48,11 @@ export { LITELLM_BASE_URL, LITELLM_DEFAULT_MODEL_ID, } from "./onboard-auth.config-litellm.js"; -import { applyProviderConfigWithDefaultModel } from "./onboard-auth.config-shared.js"; +import { + applyAgentDefaultModelPrimary, + applyProviderConfigWithDefaultModel, + applyProviderConfigWithDefaultModels, +} from "./onboard-auth.config-shared.js"; import { buildZaiModelDefinition, buildMoonshotModelDefinition, @@ -236,46 +240,12 @@ function applyMoonshotProviderConfigWithBaseUrl( export function applyMoonshotConfig(cfg: OpenClawConfig): OpenClawConfig { const next = applyMoonshotProviderConfig(cfg); - const existingModel = next.agents?.defaults?.model; - return { - ...next, - agents: { - ...next.agents, - defaults: { - ...next.agents?.defaults, - model: { - ...(existingModel && "fallbacks" in (existingModel as Record) - ? { - fallbacks: (existingModel as { fallbacks?: string[] }).fallbacks, - } - : undefined), - primary: MOONSHOT_DEFAULT_MODEL_REF, - }, - }, - }, - }; + return applyAgentDefaultModelPrimary(next, MOONSHOT_DEFAULT_MODEL_REF); } export function applyMoonshotConfigCn(cfg: OpenClawConfig): OpenClawConfig { const next = applyMoonshotProviderConfigCn(cfg); - const existingModel = next.agents?.defaults?.model; - return { - ...next, - agents: { - ...next.agents, - defaults: { - ...next.agents?.defaults, - model: { - ...(existingModel && "fallbacks" in (existingModel as Record) - ? { - fallbacks: (existingModel as { fallbacks?: string[] }).fallbacks, - } - : undefined), - primary: MOONSHOT_DEFAULT_MODEL_REF, - }, - }, - }, - }; + return applyAgentDefaultModelPrimary(next, MOONSHOT_DEFAULT_MODEL_REF); } export function applyKimiCodeProviderConfig(cfg: OpenClawConfig): OpenClawConfig { @@ -394,47 +364,16 @@ export function applyXiaomiProviderConfig(cfg: OpenClawConfig): OpenClawConfig { ...models[XIAOMI_DEFAULT_MODEL_REF], alias: models[XIAOMI_DEFAULT_MODEL_REF]?.alias ?? "Xiaomi", }; - - const providers = { ...cfg.models?.providers }; - const existingProvider = providers.xiaomi; const defaultProvider = buildXiaomiProvider(); - const existingModels = Array.isArray(existingProvider?.models) ? existingProvider.models : []; - const defaultModels = defaultProvider.models ?? []; - const hasDefaultModel = existingModels.some((model) => model.id === XIAOMI_DEFAULT_MODEL_ID); - const mergedModels = - existingModels.length > 0 - ? hasDefaultModel - ? existingModels - : [...existingModels, ...defaultModels] - : defaultModels; - const { apiKey: existingApiKey, ...existingProviderRest } = (existingProvider ?? {}) as Record< - string, - unknown - > as { apiKey?: string }; - const resolvedApiKey = typeof existingApiKey === "string" ? existingApiKey : undefined; - const normalizedApiKey = resolvedApiKey?.trim(); - providers.xiaomi = { - ...existingProviderRest, + const resolvedApi = defaultProvider.api ?? "openai-completions"; + return applyProviderConfigWithDefaultModels(cfg, { + agentModels: models, + providerId: "xiaomi", + api: resolvedApi, baseUrl: defaultProvider.baseUrl, - api: defaultProvider.api, - ...(normalizedApiKey ? { apiKey: normalizedApiKey } : {}), - models: mergedModels.length > 0 ? mergedModels : defaultProvider.models, - }; - - return { - ...cfg, - agents: { - ...cfg.agents, - defaults: { - ...cfg.agents?.defaults, - models, - }, - }, - models: { - mode: cfg.models?.mode ?? "merge", - providers, - }, - }; + defaultModels: defaultProvider.models ?? [], + defaultModelId: XIAOMI_DEFAULT_MODEL_ID, + }); } export function applyXiaomiConfig(cfg: OpenClawConfig): OpenClawConfig { @@ -780,53 +719,29 @@ export function applyQianfanProviderConfig(cfg: OpenClawConfig): OpenClawConfig ...models[QIANFAN_DEFAULT_MODEL_REF], alias: models[QIANFAN_DEFAULT_MODEL_REF]?.alias ?? "QIANFAN", }; - - const providers = { ...cfg.models?.providers }; - const existingProvider = providers.qianfan; const defaultProvider = buildQianfanProvider(); - const existingModels = Array.isArray(existingProvider?.models) ? existingProvider.models : []; - const defaultModels = defaultProvider.models ?? []; - const hasDefaultModel = existingModels.some((model) => model.id === QIANFAN_DEFAULT_MODEL_ID); - const mergedModels = - existingModels.length > 0 - ? hasDefaultModel - ? existingModels - : [...existingModels, ...defaultModels] - : defaultModels; - const { - apiKey: existingApiKey, - baseUrl: existingBaseUrl, - api: existingApi, - ...existingProviderRest - } = (existingProvider ?? {}) as Record as { - apiKey?: string; - baseUrl?: string; - api?: ModelApi; - }; - const resolvedApiKey = typeof existingApiKey === "string" ? existingApiKey : undefined; - const normalizedApiKey = resolvedApiKey?.trim(); - providers.qianfan = { - ...existingProviderRest, - baseUrl: existingBaseUrl ?? QIANFAN_BASE_URL, - api: existingApi ?? "openai-completions", - ...(normalizedApiKey ? { apiKey: normalizedApiKey } : {}), - models: mergedModels.length > 0 ? mergedModels : defaultProvider.models, - }; + const existingProvider = cfg.models?.providers?.qianfan as + | { + baseUrl?: unknown; + api?: unknown; + } + | undefined; + const existingBaseUrl = + typeof existingProvider?.baseUrl === "string" ? existingProvider.baseUrl.trim() : ""; + const resolvedBaseUrl = existingBaseUrl || QIANFAN_BASE_URL; + const resolvedApi = + typeof existingProvider?.api === "string" + ? (existingProvider.api as ModelApi) + : "openai-completions"; - return { - ...cfg, - agents: { - ...cfg.agents, - defaults: { - ...cfg.agents?.defaults, - models, - }, - }, - models: { - mode: cfg.models?.mode ?? "merge", - providers, - }, - }; + return applyProviderConfigWithDefaultModels(cfg, { + agentModels: models, + providerId: "qianfan", + api: resolvedApi, + baseUrl: resolvedBaseUrl, + defaultModels: defaultProvider.models ?? [], + defaultModelId: QIANFAN_DEFAULT_MODEL_ID, + }); } export function applyQianfanConfig(cfg: OpenClawConfig): OpenClawConfig { diff --git a/src/commands/onboard-auth.config-litellm.ts b/src/commands/onboard-auth.config-litellm.ts index 29041f1d5ca..ec1ba251056 100644 --- a/src/commands/onboard-auth.config-litellm.ts +++ b/src/commands/onboard-auth.config-litellm.ts @@ -1,5 +1,8 @@ import type { OpenClawConfig } from "../config/config.js"; -import { applyProviderConfigWithDefaultModel } from "./onboard-auth.config-shared.js"; +import { + applyAgentDefaultModelPrimary, + applyProviderConfigWithDefaultModel, +} from "./onboard-auth.config-shared.js"; import { LITELLM_DEFAULT_MODEL_REF } from "./onboard-auth.credentials.js"; export const LITELLM_BASE_URL = "http://localhost:4000"; @@ -58,22 +61,5 @@ export function applyLitellmProviderConfig(cfg: OpenClawConfig): OpenClawConfig export function applyLitellmConfig(cfg: OpenClawConfig): OpenClawConfig { const next = applyLitellmProviderConfig(cfg); - const existingModel = next.agents?.defaults?.model; - return { - ...next, - agents: { - ...next.agents, - defaults: { - ...next.agents?.defaults, - model: { - ...(existingModel && "fallbacks" in (existingModel as Record) - ? { - fallbacks: (existingModel as { fallbacks?: string[] }).fallbacks, - } - : undefined), - primary: LITELLM_DEFAULT_MODEL_REF, - }, - }, - }, - }; + return applyAgentDefaultModelPrimary(next, LITELLM_DEFAULT_MODEL_REF); } diff --git a/src/commands/onboard-auth.config-shared.ts b/src/commands/onboard-auth.config-shared.ts index 3b7995f0098..5bae67f60d7 100644 --- a/src/commands/onboard-auth.config-shared.ts +++ b/src/commands/onboard-auth.config-shared.ts @@ -6,14 +6,45 @@ import type { ModelProviderConfig, } from "../config/types.models.js"; -export function applyProviderConfigWithDefaultModel( +function extractAgentDefaultModelFallbacks(model: unknown): string[] | undefined { + if (!model || typeof model !== "object") { + return undefined; + } + if (!("fallbacks" in model)) { + return undefined; + } + const fallbacks = (model as { fallbacks?: unknown }).fallbacks; + return Array.isArray(fallbacks) ? fallbacks.map((v) => String(v)) : undefined; +} + +export function applyAgentDefaultModelPrimary( + cfg: OpenClawConfig, + primary: string, +): OpenClawConfig { + const existingFallbacks = extractAgentDefaultModelFallbacks(cfg.agents?.defaults?.model); + return { + ...cfg, + agents: { + ...cfg.agents, + defaults: { + ...cfg.agents?.defaults, + model: { + ...(existingFallbacks ? { fallbacks: existingFallbacks } : undefined), + primary, + }, + }, + }, + }; +} + +export function applyProviderConfigWithDefaultModels( cfg: OpenClawConfig, params: { agentModels: Record; providerId: string; api: ModelApi; baseUrl: string; - defaultModel: ModelDefinitionConfig; + defaultModels: ModelDefinitionConfig[]; defaultModelId?: string; }, ): OpenClawConfig { @@ -24,9 +55,17 @@ export function applyProviderConfigWithDefaultModel( ? existingProvider.models : []; - const defaultModelId = params.defaultModelId ?? params.defaultModel.id; - const hasDefaultModel = existingModels.some((model) => model.id === defaultModelId); - const mergedModels = hasDefaultModel ? existingModels : [...existingModels, params.defaultModel]; + const defaultModels = params.defaultModels; + const defaultModelId = params.defaultModelId ?? defaultModels[0]?.id; + const hasDefaultModel = defaultModelId + ? existingModels.some((model) => model.id === defaultModelId) + : true; + const mergedModels = + existingModels.length > 0 + ? hasDefaultModel || defaultModels.length === 0 + ? existingModels + : [...existingModels, ...defaultModels] + : defaultModels; const { apiKey: existingApiKey, ...existingProviderRest } = (existingProvider ?? {}) as { apiKey?: string; @@ -39,7 +78,7 @@ export function applyProviderConfigWithDefaultModel( baseUrl: params.baseUrl, api: params.api, ...(normalizedApiKey ? { apiKey: normalizedApiKey } : {}), - models: mergedModels.length > 0 ? mergedModels : [params.defaultModel], + models: mergedModels.length > 0 ? mergedModels : defaultModels, }; return { @@ -57,3 +96,24 @@ export function applyProviderConfigWithDefaultModel( }, }; } + +export function applyProviderConfigWithDefaultModel( + cfg: OpenClawConfig, + params: { + agentModels: Record; + providerId: string; + api: ModelApi; + baseUrl: string; + defaultModel: ModelDefinitionConfig; + defaultModelId?: string; + }, +): OpenClawConfig { + return applyProviderConfigWithDefaultModels(cfg, { + agentModels: params.agentModels, + providerId: params.providerId, + api: params.api, + baseUrl: params.baseUrl, + defaultModels: [params.defaultModel], + defaultModelId: params.defaultModelId ?? params.defaultModel.id, + }); +}