From dab99531e42b7cadea62e8f9cee67adacc61a480 Mon Sep 17 00:00:00 2001 From: YeonGyu-Kim Date: Tue, 17 Feb 2026 01:27:10 +0900 Subject: [PATCH] fix: handle all model versions in normalizeModelName for fallback chains (#1679) --- src/shared/model-availability.test.ts | 21 +++++++++++++++++++++ src/shared/model-availability.ts | 3 +-- src/shared/model-name-matcher.ts | 4 +--- 3 files changed, 23 insertions(+), 5 deletions(-) diff --git a/src/shared/model-availability.test.ts b/src/shared/model-availability.test.ts index cbaed0f5c..7ef44c55d 100644 --- a/src/shared/model-availability.test.ts +++ b/src/shared/model-availability.test.ts @@ -233,6 +233,27 @@ describe("fuzzyMatchModel", () => { expect(result).toBe("anthropic/claude-opus-4-6") }) + // given github-copilot serves claude versions with dot notation + // when fallback chain uses hyphen notation in requested model + // then normalize both forms and match github-copilot model + it("should match github-copilot claude-opus-4-6 to claude-opus-4.6", () => { + const available = new Set([ + "github-copilot/claude-opus-4.6", + "opencode/glm-4.7-free", + ]) + const result = fuzzyMatchModel("claude-opus-4-6", available, ["github-copilot"]) + expect(result).toBe("github-copilot/claude-opus-4.6") + }) + + // given claude models can evolve to newer version numbers + // when matching across dot and hyphen version separators + // then normalize generically without hardcoding specific versions + it("should normalize claude version separators for future versions", () => { + const available = new Set(["github-copilot/claude-sonnet-5.1"]) + const result = fuzzyMatchModel("claude-sonnet-5-1", available, ["github-copilot"]) + expect(result).toBe("github-copilot/claude-sonnet-5.1") + }) + // given available models from multiple providers // when providers filter is specified // then only search models from specified providers diff --git a/src/shared/model-availability.ts b/src/shared/model-availability.ts index 0943ce857..940f955b8 100644 --- a/src/shared/model-availability.ts +++ b/src/shared/model-availability.ts @@ -28,8 +28,7 @@ import { normalizeSDKResponse } from "./normalize-sdk-response" function normalizeModelName(name: string): string { return name .toLowerCase() - .replace(/claude-(opus|sonnet|haiku)-4-5/g, "claude-$1-4.5") - .replace(/claude-(opus|sonnet|haiku)-4\.5/g, "claude-$1-4.5") + .replace(/claude-(opus|sonnet|haiku)-(\d+)[.-](\d+)/g, "claude-$1-$2.$3") } export function fuzzyMatchModel( diff --git a/src/shared/model-name-matcher.ts b/src/shared/model-name-matcher.ts index dc10289df..bcdd3fb41 100644 --- a/src/shared/model-name-matcher.ts +++ b/src/shared/model-name-matcher.ts @@ -3,8 +3,7 @@ import { log } from "./logger" function normalizeModelName(name: string): string { return name .toLowerCase() - .replace(/claude-(opus|sonnet|haiku)-4-5/g, "claude-$1-4.5") - .replace(/claude-(opus|sonnet|haiku)-4\.5/g, "claude-$1-4.5") + .replace(/claude-(opus|sonnet|haiku)-(\d+)[.-](\d+)/g, "claude-$1-$2.$3") } export function fuzzyMatchModel( @@ -82,4 +81,3 @@ export function fuzzyMatchModel( log("[fuzzyMatchModel] shortest match", { result }) return result } -