fix(ui): inherit default model fallbacks in agents overview (#25729)

Land PR #25729 from @Suko.
Use shared fallback-resolution helper and add regression coverage for default, override, and explicit-empty cases.

Co-authored-by: suko <miha.sukic@gmail.com>
This commit is contained in:
Peter Steinberger
2026-02-25 01:28:17 +00:00
parent 43f318cd9a
commit 4d89548e59
5 changed files with 56 additions and 2 deletions

View File

@@ -0,0 +1,42 @@
import { describe, expect, it } from "vitest";
import { resolveEffectiveModelFallbacks } from "./agents-utils.ts";
describe("resolveEffectiveModelFallbacks", () => {
it("inherits defaults when no entry fallbacks are configured", () => {
const entryModel = undefined;
const defaultModel = {
primary: "openai/gpt-5-nano",
fallbacks: ["google/gemini-2.0-flash"],
};
expect(resolveEffectiveModelFallbacks(entryModel, defaultModel)).toEqual([
"google/gemini-2.0-flash",
]);
});
it("prefers entry fallbacks over defaults", () => {
const entryModel = {
primary: "openai/gpt-5-mini",
fallbacks: ["openai/gpt-5-nano"],
};
const defaultModel = {
primary: "openai/gpt-5",
fallbacks: ["google/gemini-2.0-flash"],
};
expect(resolveEffectiveModelFallbacks(entryModel, defaultModel)).toEqual(["openai/gpt-5-nano"]);
});
it("keeps explicit empty entry fallback lists", () => {
const entryModel = {
primary: "openai/gpt-5-mini",
fallbacks: [],
};
const defaultModel = {
primary: "openai/gpt-5",
fallbacks: ["google/gemini-2.0-flash"],
};
expect(resolveEffectiveModelFallbacks(entryModel, defaultModel)).toEqual([]);
});
});

View File

@@ -244,6 +244,13 @@ export function resolveModelFallbacks(model?: unknown): string[] | null {
return null;
}
export function resolveEffectiveModelFallbacks(
entryModel?: unknown,
defaultModel?: unknown,
): string[] | null {
return resolveModelFallbacks(entryModel) ?? resolveModelFallbacks(defaultModel);
}
export function parseFallbackList(value: string): string[] {
return value
.split(",")

View File

@@ -24,7 +24,7 @@ import {
parseFallbackList,
resolveAgentConfig,
resolveAgentEmoji,
resolveModelFallbacks,
resolveEffectiveModelFallbacks,
resolveModelLabel,
resolveModelPrimary,
} from "./agents-utils.ts";
@@ -390,7 +390,10 @@ function renderAgentOverview(params: {
resolveModelPrimary(config.defaults?.model) ||
(defaultModel !== "-" ? normalizeModelValue(defaultModel) : null);
const effectivePrimary = modelPrimary ?? defaultPrimary ?? null;
const modelFallbacks = resolveModelFallbacks(config.entry?.model);
const modelFallbacks = resolveEffectiveModelFallbacks(
config.entry?.model,
config.defaults?.model,
);
const fallbackText = modelFallbacks ? modelFallbacks.join(", ") : "";
const identityName =
agentIdentity?.name?.trim() ||