From 0ce23d3065c2d9c677385c6ff313ce01d165f1e2 Mon Sep 17 00:00:00 2001 From: Thomas Ricouard Date: Mon, 23 Feb 2026 20:24:01 +0100 Subject: [PATCH] Use raw model slug for model list display names --- .../models/utils/modelListResponse.test.ts | 54 +++---------------- .../models/utils/modelListResponse.ts | 29 +--------- 2 files changed, 10 insertions(+), 73 deletions(-) diff --git a/src/features/models/utils/modelListResponse.test.ts b/src/features/models/utils/modelListResponse.test.ts index 6af73c3fd..b63a0fa32 100644 --- a/src/features/models/utils/modelListResponse.test.ts +++ b/src/features/models/utils/modelListResponse.test.ts @@ -1,43 +1,5 @@ import { describe, expect, it } from "vitest"; -import { formatModelSlug, parseModelListResponse } from "./modelListResponse"; - -describe("formatModelSlug", () => { - it("capitalizes plain segments", () => { - expect(formatModelSlug("codex-mini")).toBe("Codex-Mini"); - }); - - it("uppercases known acronyms", () => { - expect(formatModelSlug("gpt-5.3-codex")).toBe("GPT-5.3-Codex"); - }); - - it("leaves version-like segments unchanged", () => { - expect(formatModelSlug("gpt-5.1-codex-max")).toBe("GPT-5.1-Codex-Max"); - }); - - it("handles a version-only slug", () => { - expect(formatModelSlug("gpt-5.2")).toBe("GPT-5.2"); - }); - it("is case-insensitive for acronym detection", () => { - expect(formatModelSlug("GPT-5.3-codex")).toBe("GPT-5.3-Codex"); - expect(formatModelSlug("Gpt-5.3-codex")).toBe("GPT-5.3-Codex"); - }); - - it("returns empty string for non-string input", () => { - expect(formatModelSlug(null)).toBe(""); - expect(formatModelSlug(undefined)).toBe(""); - expect(formatModelSlug(42)).toBe(""); - }); - - it("returns empty string for blank strings", () => { - expect(formatModelSlug("")).toBe(""); - expect(formatModelSlug(" ")).toBe(""); - }); - - it("handles a single segment", () => { - expect(formatModelSlug("codex")).toBe("Codex"); - expect(formatModelSlug("gpt")).toBe("GPT"); - }); -}); +import { parseModelListResponse } from "./modelListResponse"; describe("parseModelListResponse", () => { it("uses displayName when present", () => { @@ -52,34 +14,34 @@ describe("parseModelListResponse", () => { expect(model.displayName).toBe("GPT-5.3-Codex-Spark"); }); - it("formats the slug when displayName is missing", () => { + it("uses the raw model slug when displayName is missing", () => { const response = { result: { data: [{ id: "m1", model: "gpt-5.3-codex" }], }, }; const [model] = parseModelListResponse(response); - expect(model.displayName).toBe("GPT-5.3-Codex"); + expect(model.displayName).toBe("gpt-5.3-codex"); }); - it("formats the slug when displayName is an empty string", () => { + it("uses the raw model slug when displayName is an empty string", () => { const response = { result: { data: [{ id: "m1", model: "gpt-5.1-codex-mini", displayName: "" }], }, }; const [model] = parseModelListResponse(response); - expect(model.displayName).toBe("GPT-5.1-Codex-Mini"); + expect(model.displayName).toBe("gpt-5.1-codex-mini"); }); - it("formats the slug when displayName equals the model slug", () => { + it("preserves displayName when it equals the model slug", () => { const response = { result: { data: [{ id: "m1", model: "gpt-5.3-codex", displayName: "gpt-5.3-codex" }], }, }; const [model] = parseModelListResponse(response); - expect(model.displayName).toBe("GPT-5.3-Codex"); + expect(model.displayName).toBe("gpt-5.3-codex"); }); it("preserves displayName when it differs from the slug", () => { @@ -93,6 +55,6 @@ describe("parseModelListResponse", () => { }; const models = parseModelListResponse(response); expect(models[0].displayName).toBe("GPT-5.3-Codex-Spark"); - expect(models[1].displayName).toBe("GPT-5.2-Codex"); + expect(models[1].displayName).toBe("gpt-5.2-codex"); }); }); diff --git a/src/features/models/utils/modelListResponse.ts b/src/features/models/utils/modelListResponse.ts index 12161da91..77e046afe 100644 --- a/src/features/models/utils/modelListResponse.ts +++ b/src/features/models/utils/modelListResponse.ts @@ -1,30 +1,5 @@ import type { ModelOption } from "../../../types"; -const UPPERCASE_SEGMENTS = new Set(["gpt"]); - -/** - * Formats a model slug like "gpt-5.3-codex" into "GPT-5.3-Codex". - * Known acronyms are uppercased, version-like segments are left as-is, - * and everything else is capitalized. - */ -export function formatModelSlug(slug: unknown): string { - if (typeof slug !== "string" || !slug.trim()) { - return ""; - } - return slug - .split("-") - .map((segment) => { - if (UPPERCASE_SEGMENTS.has(segment.toLowerCase())) { - return segment.toUpperCase(); - } - if (/^\d/.test(segment)) { - return segment; - } - return segment.charAt(0).toUpperCase() + segment.slice(1); - }) - .join("-"); -} - export function normalizeEffortValue(value: unknown): string | null { if (typeof value !== "string") { return null; @@ -108,11 +83,11 @@ export function parseModelListResponse(response: unknown): ModelOption[] { const record = item as Record; const modelSlug = String(record.model ?? record.id ?? ""); const rawDisplayName = String(record.displayName || record.display_name || ""); - const hasCustomDisplayName = rawDisplayName !== "" && rawDisplayName !== modelSlug; + const displayName = rawDisplayName.trim().length > 0 ? rawDisplayName : modelSlug; return { id: String(record.id ?? record.model ?? ""), model: modelSlug, - displayName: hasCustomDisplayName ? rawDisplayName : (formatModelSlug(modelSlug) || modelSlug), + displayName, description: String(record.description ?? ""), supportedReasoningEfforts: parseReasoningEfforts(record), defaultReasoningEffort: normalizeEffortValue(