Skip to content

Commit 0ffe380

Browse files
authored
Invert family order (Fable first) and uppercase GPT/GLM names
Order model families most-capable first (Fable, Opus, Sonnet, Haiku) and display OpenAI/Cloudflare model names with their acronym uppercased (gpt-5.5 -> GPT-5.5, glm-5.2 -> GLM-5.2). Generated-By: PostHog Code Task-Id: ea8239ab-8fc1-46b7-8dc6-d3661caf8800
1 parent 5bf5399 commit 0ffe380

2 files changed

Lines changed: 27 additions & 23 deletions

File tree

packages/agent/src/gateway-models.test.ts

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ describe("formatGatewayModelName", () => {
3535
).toBe("Claude Opus 4.8");
3636
});
3737

38-
it("formats OpenAI models as raw lowercase model ids", () => {
38+
it("uppercases the GPT acronym in OpenAI model ids", () => {
3939
expect(
4040
formatGatewayModelName({
4141
id: "GPT-5.5",
@@ -45,23 +45,23 @@ describe("formatGatewayModelName", () => {
4545
supports_vision: true,
4646
allowed: true,
4747
}),
48-
).toBe("gpt-5.5");
48+
).toBe("GPT-5.5");
4949
});
5050

51-
it("strips the openai/ prefix from OpenAI model ids", () => {
51+
it("strips the openai/ prefix and uppercases GPT", () => {
5252
expect(
5353
formatGatewayModelName({
54-
id: "openai/gpt-5.5",
54+
id: "openai/gpt-5.6-sol",
5555
owned_by: "openai",
5656
context_window: 200000,
5757
supports_streaming: true,
5858
supports_vision: true,
5959
allowed: true,
6060
}),
61-
).toBe("gpt-5.5");
61+
).toBe("GPT-5.6-sol");
6262
});
6363

64-
it("formats Cloudflare models as the lowercase final path segment", () => {
64+
it("formats Cloudflare models as the final path segment with GLM uppercased", () => {
6565
expect(
6666
formatGatewayModelName({
6767
id: "@cf/zai-org/glm-5.2",
@@ -71,7 +71,7 @@ describe("formatGatewayModelName", () => {
7171
supports_vision: false,
7272
allowed: true,
7373
}),
74-
).toBe("glm-5.2");
74+
).toBe("GLM-5.2");
7575
});
7676

7777
it("blocks deprecated Claude gateway models", () => {
@@ -132,17 +132,17 @@ describe("compareModelsForPicker", () => {
132132
"claude-opus-4-7",
133133
];
134134
const displayed = [...gatewayOrder].sort(compareModelsForPicker);
135-
// Each family stays contiguous (both Sonnets together, both Opuses
136-
// together) instead of interleaving by raw version number. The menu opens
137-
// upward, so the newest flagship family sits closest to the trigger, and
138-
// unknown/non-Anthropic models trail the known families.
135+
// Families are ordered most-capable first and each stays contiguous (both
136+
// Sonnets together, both Opuses together) instead of interleaving by raw
137+
// version number. Within a family, versions run oldest-to-newest.
138+
// Unknown/non-Anthropic models trail the known families.
139139
expect(displayed).toEqual([
140-
"claude-haiku-4-5",
141-
"claude-sonnet-4-6",
142-
"claude-sonnet-5",
140+
"claude-fable-5",
143141
"claude-opus-4-7",
144142
"claude-opus-4-8",
145-
"claude-fable-5",
143+
"claude-sonnet-4-6",
144+
"claude-sonnet-5",
145+
"claude-haiku-4-5",
146146
"claude-mystery",
147147
]);
148148
});

packages/agent/src/gateway-models.ts

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -276,10 +276,8 @@ export function getClaudeModelRecency(modelId: string): number {
276276
return major * 1000 + minor;
277277
}
278278

279-
// Anthropic model families ordered by tier, fastest/smallest first. The picker
280-
// menu opens upward (side="top"), so families later in this list sit closer to
281-
// the trigger.
282-
const MODEL_FAMILY_ORDER = ["haiku", "sonnet", "opus", "fable"];
279+
// Anthropic model families ordered by tier, most capable first.
280+
const MODEL_FAMILY_ORDER = ["fable", "opus", "sonnet", "haiku"];
283281

284282
function getModelFamilyRank(modelId: string): number {
285283
const id = modelId.toLowerCase();
@@ -292,8 +290,7 @@ function getModelFamilyRank(modelId: string): number {
292290
// Comparator for the model picker. Groups models by family (tier) first, then
293291
// orders each family's versions oldest-to-newest. Sorting by version alone
294292
// interleaves families (e.g. a Sonnet 5 lands between Opus versions), which
295-
// reads as an arbitrary order; grouping keeps every family contiguous and the
296-
// newest flagship closest to the trigger.
293+
// reads as an arbitrary order; grouping keeps every family contiguous.
297294
export function compareModelsForPicker(a: string, b: string): number {
298295
const familyDiff = getModelFamilyRank(a) - getModelFamilyRank(b);
299296
if (familyDiff !== 0) return familyDiff;
@@ -302,13 +299,20 @@ export function compareModelsForPicker(a: string, b: string): number {
302299

303300
const PROVIDER_PREFIXES = ["anthropic/", "openai/", "google-vertex/"];
304301

302+
// Uppercase the leading acronym in a model id so provider prefixes read as
303+
// their brand (e.g. "gpt-5.5" -> "GPT-5.5", "glm-5.2" -> "GLM-5.2").
304+
function uppercaseLeadingAcronym(name: string): string {
305+
return name.replace(/^[a-z]+/, (prefix) => prefix.toUpperCase());
306+
}
307+
305308
export function formatGatewayModelName(model: GatewayModel): string {
306309
if (isCloudflareModel(model)) {
307-
return (model.id.split("/").pop() ?? model.id).toLowerCase();
310+
const name = (model.id.split("/").pop() ?? model.id).toLowerCase();
311+
return uppercaseLeadingAcronym(name);
308312
}
309313

310314
if (isOpenAIModel(model)) {
311-
return stripProviderPrefix(model.id).toLowerCase();
315+
return uppercaseLeadingAcronym(stripProviderPrefix(model.id).toLowerCase());
312316
}
313317

314318
return formatModelId(model.id);

0 commit comments

Comments
 (0)