refactor(models): share primary/fallback merge

This commit is contained in:
Peter Steinberger
2026-02-15 17:13:09 +00:00
parent 3ce0e80f57
commit cbf6ee3a64
5 changed files with 64 additions and 62 deletions

View File

@@ -5,6 +5,8 @@ import { logConfigUpdated } from "../../config/logging.js";
import {
DEFAULT_PROVIDER,
ensureFlagCompatibility,
mergePrimaryFallbackConfig,
type PrimaryFallbackConfig,
modelKey,
resolveModelTarget,
resolveModelKeysFromEntries,
@@ -55,20 +57,16 @@ export async function modelsFallbacksAddCommand(modelRaw: string, runtime: Runti
return cfg;
}
const existingModel = cfg.agents?.defaults?.model as
| { primary?: string; fallbacks?: string[] }
| undefined;
return {
...cfg,
agents: {
...cfg.agents,
defaults: {
...cfg.agents?.defaults,
model: {
...(existingModel?.primary ? { primary: existingModel.primary } : undefined),
fallbacks: [...existing, targetKey],
},
model: mergePrimaryFallbackConfig(
cfg.agents?.defaults?.model as unknown as PrimaryFallbackConfig | undefined,
{ fallbacks: [...existing, targetKey] },
),
models: nextModels,
},
},
@@ -104,20 +102,16 @@ export async function modelsFallbacksRemoveCommand(modelRaw: string, runtime: Ru
throw new Error(`Fallback not found: ${targetKey}`);
}
const existingModel = cfg.agents?.defaults?.model as
| { primary?: string; fallbacks?: string[] }
| undefined;
return {
...cfg,
agents: {
...cfg.agents,
defaults: {
...cfg.agents?.defaults,
model: {
...(existingModel?.primary ? { primary: existingModel.primary } : undefined),
fallbacks: filtered,
},
model: mergePrimaryFallbackConfig(
cfg.agents?.defaults?.model as unknown as PrimaryFallbackConfig | undefined,
{ fallbacks: filtered },
),
},
},
};
@@ -129,19 +123,16 @@ export async function modelsFallbacksRemoveCommand(modelRaw: string, runtime: Ru
export async function modelsFallbacksClearCommand(runtime: RuntimeEnv) {
await updateConfig((cfg) => {
const existingModel = cfg.agents?.defaults?.model as
| { primary?: string; fallbacks?: string[] }
| undefined;
return {
...cfg,
agents: {
...cfg.agents,
defaults: {
...cfg.agents?.defaults,
model: {
...(existingModel?.primary ? { primary: existingModel.primary } : undefined),
fallbacks: [],
},
model: mergePrimaryFallbackConfig(
cfg.agents?.defaults?.model as unknown as PrimaryFallbackConfig | undefined,
{ fallbacks: [] },
),
},
},
};

View File

@@ -5,6 +5,8 @@ import { logConfigUpdated } from "../../config/logging.js";
import {
DEFAULT_PROVIDER,
ensureFlagCompatibility,
mergePrimaryFallbackConfig,
type PrimaryFallbackConfig,
modelKey,
resolveModelTarget,
resolveModelKeysFromEntries,
@@ -55,20 +57,16 @@ export async function modelsImageFallbacksAddCommand(modelRaw: string, runtime:
return cfg;
}
const existingModel = cfg.agents?.defaults?.imageModel as
| { primary?: string; fallbacks?: string[] }
| undefined;
return {
...cfg,
agents: {
...cfg.agents,
defaults: {
...cfg.agents?.defaults,
imageModel: {
...(existingModel?.primary ? { primary: existingModel.primary } : undefined),
fallbacks: [...existing, targetKey],
},
imageModel: mergePrimaryFallbackConfig(
cfg.agents?.defaults?.imageModel as unknown as PrimaryFallbackConfig | undefined,
{ fallbacks: [...existing, targetKey] },
),
models: nextModels,
},
},
@@ -106,20 +104,16 @@ export async function modelsImageFallbacksRemoveCommand(modelRaw: string, runtim
throw new Error(`Image fallback not found: ${targetKey}`);
}
const existingModel = cfg.agents?.defaults?.imageModel as
| { primary?: string; fallbacks?: string[] }
| undefined;
return {
...cfg,
agents: {
...cfg.agents,
defaults: {
...cfg.agents?.defaults,
imageModel: {
...(existingModel?.primary ? { primary: existingModel.primary } : undefined),
fallbacks: filtered,
},
imageModel: mergePrimaryFallbackConfig(
cfg.agents?.defaults?.imageModel as unknown as PrimaryFallbackConfig | undefined,
{ fallbacks: filtered },
),
},
},
};
@@ -133,19 +127,16 @@ export async function modelsImageFallbacksRemoveCommand(modelRaw: string, runtim
export async function modelsImageFallbacksClearCommand(runtime: RuntimeEnv) {
await updateConfig((cfg) => {
const existingModel = cfg.agents?.defaults?.imageModel as
| { primary?: string; fallbacks?: string[] }
| undefined;
return {
...cfg,
agents: {
...cfg.agents,
defaults: {
...cfg.agents?.defaults,
imageModel: {
...(existingModel?.primary ? { primary: existingModel.primary } : undefined),
fallbacks: [],
},
imageModel: mergePrimaryFallbackConfig(
cfg.agents?.defaults?.imageModel as unknown as PrimaryFallbackConfig | undefined,
{ fallbacks: [] },
),
},
},
};

View File

@@ -1,6 +1,11 @@
import type { RuntimeEnv } from "../../runtime.js";
import { logConfigUpdated } from "../../config/logging.js";
import { resolveModelTarget, updateConfig } from "./shared.js";
import {
mergePrimaryFallbackConfig,
type PrimaryFallbackConfig,
resolveModelTarget,
updateConfig,
} from "./shared.js";
export async function modelsSetImageCommand(modelRaw: string, runtime: RuntimeEnv) {
const updated = await updateConfig((cfg) => {
@@ -10,19 +15,16 @@ export async function modelsSetImageCommand(modelRaw: string, runtime: RuntimeEn
if (!nextModels[key]) {
nextModels[key] = {};
}
const existingModel = cfg.agents?.defaults?.imageModel as
| { primary?: string; fallbacks?: string[] }
| undefined;
return {
...cfg,
agents: {
...cfg.agents,
defaults: {
...cfg.agents?.defaults,
imageModel: {
...(existingModel?.fallbacks ? { fallbacks: existingModel.fallbacks } : undefined),
primary: key,
},
imageModel: mergePrimaryFallbackConfig(
cfg.agents?.defaults?.imageModel as unknown as PrimaryFallbackConfig | undefined,
{ primary: key },
),
models: nextModels,
},
},

View File

@@ -1,6 +1,11 @@
import type { RuntimeEnv } from "../../runtime.js";
import { logConfigUpdated } from "../../config/logging.js";
import { resolveModelTarget, updateConfig } from "./shared.js";
import {
mergePrimaryFallbackConfig,
type PrimaryFallbackConfig,
resolveModelTarget,
updateConfig,
} from "./shared.js";
export async function modelsSetCommand(modelRaw: string, runtime: RuntimeEnv) {
const updated = await updateConfig((cfg) => {
@@ -10,19 +15,16 @@ export async function modelsSetCommand(modelRaw: string, runtime: RuntimeEnv) {
if (!nextModels[key]) {
nextModels[key] = {};
}
const existingModel = cfg.agents?.defaults?.model as
| { primary?: string; fallbacks?: string[] }
| undefined;
return {
...cfg,
agents: {
...cfg.agents,
defaults: {
...cfg.agents?.defaults,
model: {
...(existingModel?.fallbacks ? { fallbacks: existingModel.fallbacks } : undefined),
primary: key,
},
model: mergePrimaryFallbackConfig(
cfg.agents?.defaults?.model as unknown as PrimaryFallbackConfig | undefined,
{ primary: key },
),
models: nextModels,
},
},

View File

@@ -153,6 +153,22 @@ export function resolveKnownAgentId(params: {
return agentId;
}
export type PrimaryFallbackConfig = { primary?: string; fallbacks?: string[] };
export function mergePrimaryFallbackConfig(
existing: PrimaryFallbackConfig | undefined,
patch: { primary?: string; fallbacks?: string[] },
): PrimaryFallbackConfig {
const next: PrimaryFallbackConfig = { ...existing };
if (patch.primary !== undefined) {
next.primary = patch.primary;
}
if (patch.fallbacks !== undefined) {
next.fallbacks = patch.fallbacks;
}
return next;
}
export { modelKey };
export { DEFAULT_MODEL, DEFAULT_PROVIDER };