From 7ae52dc56ecf9dc4105c04f698666e1cd62ef45b Mon Sep 17 00:00:00 2001 From: zw-xysk Date: Mon, 29 Jun 2026 09:55:25 +0800 Subject: [PATCH] fix(model-resolver): use numeric-aware version comparison for model alias resolution --- src/agents/sessions/model-resolver.test.ts | 14 +++++++++++++- src/agents/sessions/model-resolver.ts | 4 ++-- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/src/agents/sessions/model-resolver.test.ts b/src/agents/sessions/model-resolver.test.ts index b312ab1f7df0..d94680b409b3 100644 --- a/src/agents/sessions/model-resolver.test.ts +++ b/src/agents/sessions/model-resolver.test.ts @@ -4,7 +4,7 @@ import { describe, expect, it } from "vitest"; import type { Model } from "../../llm/types.js"; import { DEFAULT_MODEL, DEFAULT_PROVIDER } from "../defaults.js"; import type { ModelRegistry } from "./model-registry.js"; -import { findInitialModel, restoreModelFromSession } from "./model-resolver.js"; +import { findInitialModel, parseModelPattern, restoreModelFromSession } from "./model-resolver.js"; function model(provider: string, id: string): Model { return { @@ -57,3 +57,15 @@ describe("model resolver fallback selection", () => { expect(result.model).toBe(firstAvailable); }); }); + +describe("parseModelPattern version sorting", () => { + it("selects the numerically highest version when aliases span double-digit minors", () => { + const models = [ + model("anthropic", "claude-opus-4-9"), + model("anthropic", "claude-opus-4-10"), + model("anthropic", "claude-opus-4-11"), + ]; + const result = parseModelPattern("opus", models); + expect(result.model?.id).toBe("claude-opus-4-11"); + }); +}); diff --git a/src/agents/sessions/model-resolver.ts b/src/agents/sessions/model-resolver.ts index 81bce0da388e..ecc7ff3d492b 100644 --- a/src/agents/sessions/model-resolver.ts +++ b/src/agents/sessions/model-resolver.ts @@ -116,11 +116,11 @@ function tryMatchModel(modelPattern: string, availableModels: Model[]): Model | if (aliases.length > 0) { // Prefer alias - if multiple aliases, pick the one that sorts highest - aliases.sort((a, b) => b.id.localeCompare(a.id)); + aliases.sort((a, b) => b.id.localeCompare(a.id, undefined, { numeric: true })); return aliases[0]; } // No alias found, pick latest dated version - datedVersions.sort((a, b) => b.id.localeCompare(a.id)); + datedVersions.sort((a, b) => b.id.localeCompare(a.id, undefined, { numeric: true })); return datedVersions[0]; }