From 9f0fc74d10c6b5f3a29e6cf648b6ab8e37443fde Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Mon, 16 Feb 2026 22:58:23 +0000 Subject: [PATCH] refactor(model): share normalized provider map lookups --- src/agents/auth-profiles/order.ts | 28 ++----------------- src/agents/auth-profiles/repair.ts | 4 +-- src/agents/model-selection.ts | 27 ++++++++++++++++++ .../reply/directive-handling.auth.ts | 15 ++-------- src/commands/models/list.probe.ts | 27 ++++++------------ 5 files changed, 43 insertions(+), 58 deletions(-) diff --git a/src/agents/auth-profiles/order.ts b/src/agents/auth-profiles/order.ts index accdb97b996..013f0b8d748 100644 --- a/src/agents/auth-profiles/order.ts +++ b/src/agents/auth-profiles/order.ts @@ -1,6 +1,6 @@ import type { OpenClawConfig } from "../../config/config.js"; import type { AuthProfileStore } from "./types.js"; -import { normalizeProviderId } from "../model-selection.js"; +import { findNormalizedProviderValue, normalizeProviderId } from "../model-selection.js"; import { dedupeProfileIds, listProfilesForProvider } from "./profiles.js"; import { clearExpiredCooldowns, isProfileInCooldown } from "./usage.js"; @@ -31,30 +31,8 @@ export function resolveAuthProfileOrder(params: { // get a fresh error count and are not immediately re-penalized on the // next transient failure. See #3604. clearExpiredCooldowns(store, now); - const storedOrder = (() => { - const order = store.order; - if (!order) { - return undefined; - } - for (const [key, value] of Object.entries(order)) { - if (normalizeProviderId(key) === providerKey) { - return value; - } - } - return undefined; - })(); - const configuredOrder = (() => { - const order = cfg?.auth?.order; - if (!order) { - return undefined; - } - for (const [key, value] of Object.entries(order)) { - if (normalizeProviderId(key) === providerKey) { - return value; - } - } - return undefined; - })(); + const storedOrder = findNormalizedProviderValue(store.order, providerKey); + const configuredOrder = findNormalizedProviderValue(cfg?.auth?.order, providerKey); const explicitOrder = storedOrder ?? configuredOrder; const explicitProfiles = cfg?.auth?.profiles ? Object.entries(cfg.auth.profiles) diff --git a/src/agents/auth-profiles/repair.ts b/src/agents/auth-profiles/repair.ts index cbb34ea062d..b7b972112a9 100644 --- a/src/agents/auth-profiles/repair.ts +++ b/src/agents/auth-profiles/repair.ts @@ -1,7 +1,7 @@ import type { OpenClawConfig } from "../../config/config.js"; import type { AuthProfileConfig } from "../../config/types.js"; import type { AuthProfileIdRepairResult, AuthProfileStore } from "./types.js"; -import { normalizeProviderId } from "../model-selection.js"; +import { findNormalizedProviderKey, normalizeProviderId } from "../model-selection.js"; import { dedupeProfileIds, listProfilesForProvider } from "./profiles.js"; function getProfileSuffix(profileId: string): string { @@ -128,7 +128,7 @@ export function repairOAuthProfileIdMismatch(params: { if (!order) { return undefined; } - const resolvedKey = Object.keys(order).find((key) => normalizeProviderId(key) === providerKey); + const resolvedKey = findNormalizedProviderKey(order, providerKey); if (!resolvedKey) { return order; } diff --git a/src/agents/model-selection.ts b/src/agents/model-selection.ts index 515742eab1f..5deae273d71 100644 --- a/src/agents/model-selection.ts +++ b/src/agents/model-selection.ts @@ -48,6 +48,33 @@ export function normalizeProviderId(provider: string): string { return normalized; } +export function findNormalizedProviderValue( + entries: Record | undefined, + provider: string, +): T | undefined { + if (!entries) { + return undefined; + } + const providerKey = normalizeProviderId(provider); + for (const [key, value] of Object.entries(entries)) { + if (normalizeProviderId(key) === providerKey) { + return value; + } + } + return undefined; +} + +export function findNormalizedProviderKey( + entries: Record | undefined, + provider: string, +): string | undefined { + if (!entries) { + return undefined; + } + const providerKey = normalizeProviderId(provider); + return Object.keys(entries).find((key) => normalizeProviderId(key) === providerKey); +} + export function isCliProvider(provider: string, cfg?: OpenClawConfig): boolean { const normalized = normalizeProviderId(provider); if (normalized === "claude-cli") { diff --git a/src/auto-reply/reply/directive-handling.auth.ts b/src/auto-reply/reply/directive-handling.auth.ts index 4b25d86b690..e74b902fb9f 100644 --- a/src/auto-reply/reply/directive-handling.auth.ts +++ b/src/auto-reply/reply/directive-handling.auth.ts @@ -10,7 +10,7 @@ import { resolveAuthProfileOrder, resolveEnvApiKey, } from "../../agents/model-auth.js"; -import { normalizeProviderId } from "../../agents/model-selection.js"; +import { findNormalizedProviderValue, normalizeProviderId } from "../../agents/model-selection.js"; import { shortenHomePath } from "../../utils.js"; export type ModelAuthDetailMode = "compact" | "verbose"; @@ -39,18 +39,7 @@ export const resolveAuthLabel = async ( }); const order = resolveAuthProfileOrder({ cfg, store, provider }); const providerKey = normalizeProviderId(provider); - const lastGood = (() => { - const map = store.lastGood; - if (!map) { - return undefined; - } - for (const [key, value] of Object.entries(map)) { - if (normalizeProviderId(key) === providerKey) { - return value; - } - } - return undefined; - })(); + const lastGood = findNormalizedProviderValue(store.lastGood, providerKey); const nextProfileId = order[0]; const now = Date.now(); diff --git a/src/commands/models/list.probe.ts b/src/commands/models/list.probe.ts index 1c30a92eb5c..795933f24fc 100644 --- a/src/commands/models/list.probe.ts +++ b/src/commands/models/list.probe.ts @@ -12,7 +12,11 @@ import { import { describeFailoverError } from "../../agents/failover-error.js"; import { getCustomProviderApiKey, resolveEnvApiKey } from "../../agents/model-auth.js"; import { loadModelCatalog } from "../../agents/model-catalog.js"; -import { normalizeProviderId, parseModelRef } from "../../agents/model-selection.js"; +import { + findNormalizedProviderValue, + normalizeProviderId, + parseModelRef, +} from "../../agents/model-selection.js"; import { runEmbeddedPiAgent } from "../../agents/pi-embedded.js"; import { resolveDefaultAgentWorkspaceDir } from "../../agents/workspace.js"; import { @@ -164,23 +168,10 @@ function buildProbeTargets(params: { const profileIds = listProfilesForProvider(store, providerKey); const explicitOrder = (() => { - const order = store.order; - if (order) { - for (const [key, value] of Object.entries(order)) { - if (normalizeProviderId(key) === providerKey) { - return value; - } - } - } - const cfgOrder = cfg?.auth?.order; - if (cfgOrder) { - for (const [key, value] of Object.entries(cfgOrder)) { - if (normalizeProviderId(key) === providerKey) { - return value; - } - } - } - return undefined; + return ( + findNormalizedProviderValue(store.order, providerKey) ?? + findNormalizedProviderValue(cfg?.auth?.order, providerKey) + ); })(); const allowedProfiles = explicitOrder && explicitOrder.length > 0