From d4c7b0505fd23825481dfd0817f235a323156469 Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Sun, 15 Feb 2026 16:24:30 +0000 Subject: [PATCH] refactor(models): dedupe fallback key parsing --- src/commands/models/fallbacks.ts | 16 ++-------------- src/commands/models/image-fallbacks.ts | 16 ++-------------- src/commands/models/shared.ts | 20 ++++++++++++++++++++ 3 files changed, 24 insertions(+), 28 deletions(-) diff --git a/src/commands/models/fallbacks.ts b/src/commands/models/fallbacks.ts index afd14667b2..fcb729b05b 100644 --- a/src/commands/models/fallbacks.ts +++ b/src/commands/models/fallbacks.ts @@ -7,6 +7,7 @@ import { ensureFlagCompatibility, modelKey, resolveModelTarget, + resolveModelKeysFromEntries, updateConfig, } from "./shared.js"; @@ -47,21 +48,8 @@ export async function modelsFallbacksAddCommand(modelRaw: string, runtime: Runti if (!nextModels[targetKey]) { nextModels[targetKey] = {}; } - const aliasIndex = buildModelAliasIndex({ - cfg, - defaultProvider: DEFAULT_PROVIDER, - }); const existing = cfg.agents?.defaults?.model?.fallbacks ?? []; - const existingKeys = existing - .map((entry) => - resolveModelRefFromString({ - raw: String(entry ?? ""), - defaultProvider: DEFAULT_PROVIDER, - aliasIndex, - }), - ) - .filter((entry): entry is NonNullable => Boolean(entry)) - .map((entry) => modelKey(entry.ref.provider, entry.ref.model)); + const existingKeys = resolveModelKeysFromEntries({ cfg, entries: existing }); if (existingKeys.includes(targetKey)) { return cfg; diff --git a/src/commands/models/image-fallbacks.ts b/src/commands/models/image-fallbacks.ts index e4beb1adf2..53e1fd2306 100644 --- a/src/commands/models/image-fallbacks.ts +++ b/src/commands/models/image-fallbacks.ts @@ -7,6 +7,7 @@ import { ensureFlagCompatibility, modelKey, resolveModelTarget, + resolveModelKeysFromEntries, updateConfig, } from "./shared.js"; @@ -47,21 +48,8 @@ export async function modelsImageFallbacksAddCommand(modelRaw: string, runtime: if (!nextModels[targetKey]) { nextModels[targetKey] = {}; } - const aliasIndex = buildModelAliasIndex({ - cfg, - defaultProvider: DEFAULT_PROVIDER, - }); const existing = cfg.agents?.defaults?.imageModel?.fallbacks ?? []; - const existingKeys = existing - .map((entry) => - resolveModelRefFromString({ - raw: String(entry ?? ""), - defaultProvider: DEFAULT_PROVIDER, - aliasIndex, - }), - ) - .filter((entry): entry is NonNullable => Boolean(entry)) - .map((entry) => modelKey(entry.ref.provider, entry.ref.model)); + const existingKeys = resolveModelKeysFromEntries({ cfg, entries: existing }); if (existingKeys.includes(targetKey)) { return cfg; diff --git a/src/commands/models/shared.ts b/src/commands/models/shared.ts index b25be3a892..98139ce420 100644 --- a/src/commands/models/shared.ts +++ b/src/commands/models/shared.ts @@ -91,6 +91,26 @@ export function resolveModelTarget(params: { raw: string; cfg: OpenClawConfig }) return resolved.ref; } +export function resolveModelKeysFromEntries(params: { + cfg: OpenClawConfig; + entries: readonly unknown[]; +}): string[] { + const aliasIndex = buildModelAliasIndex({ + cfg: params.cfg, + defaultProvider: DEFAULT_PROVIDER, + }); + return params.entries + .map((entry) => + resolveModelRefFromString({ + raw: String(entry ?? ""), + defaultProvider: DEFAULT_PROVIDER, + aliasIndex, + }), + ) + .filter((entry): entry is NonNullable => Boolean(entry)) + .map((entry) => modelKey(entry.ref.provider, entry.ref.model)); +} + export function buildAllowlistSet(cfg: OpenClawConfig): Set { const allowed = new Set(); const models = cfg.agents?.defaults?.models ?? {};