From ff05d38690a3329503c9dd56d45545153f72f0ea Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 29 Jul 2026 22:03:32 +0000 Subject: [PATCH 1/3] fix: leave short model names (< 6 chars) unchanged in reduceModelNameToIdentifier Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> --- actions/setup/js/model_aliases.cjs | 4 ++ actions/setup/js/model_aliases.test.cjs | 67 +++++++++++++++++++++++++ 2 files changed, 71 insertions(+) create mode 100644 actions/setup/js/model_aliases.test.cjs diff --git a/actions/setup/js/model_aliases.cjs b/actions/setup/js/model_aliases.cjs index 6e4ade7743c..49ccb15e2c6 100644 --- a/actions/setup/js/model_aliases.cjs +++ b/actions/setup/js/model_aliases.cjs @@ -16,6 +16,10 @@ function reduceModelNameToIdentifier(modelName) { return normalized; } + if (normalized.length < 6) { + return normalized; + } + const VERSION_SUFFIX_PATTERN = "[-_\\s]*([0-9]+)(?:[._-]+([0-9]+))?"; const FALLBACK_LETTER_LENGTH = 3; const FALLBACK_DIGIT_LENGTH = 2; diff --git a/actions/setup/js/model_aliases.test.cjs b/actions/setup/js/model_aliases.test.cjs new file mode 100644 index 00000000000..5f6a6a84784 --- /dev/null +++ b/actions/setup/js/model_aliases.test.cjs @@ -0,0 +1,67 @@ +// @ts-check + +import { describe, expect, it } from "vitest"; +import { createRequire } from "module"; + +const require = createRequire(import.meta.url); +const { reduceModelNameToIdentifier, formatModelEmojiAlias, formatModelEmojiAliasLegend } = require("./model_aliases.cjs"); + +describe("reduceModelNameToIdentifier", () => { + it('returns "auto" unchanged (short name, 4 chars)', () => { + expect(reduceModelNameToIdentifier("auto")).toBe("auto"); + }); + + it("returns short model names (< 6 chars) unchanged", () => { + expect(reduceModelNameToIdentifier("o1")).toBe("o1"); + expect(reduceModelNameToIdentifier("o3")).toBe("o3"); + expect(reduceModelNameToIdentifier("gpt")).toBe("gpt"); + expect(reduceModelNameToIdentifier("mini")).toBe("mini"); + expect(reduceModelNameToIdentifier("haiku")).toBe("haiku"); + }); + + it("returns empty string for empty/null/undefined input", () => { + expect(reduceModelNameToIdentifier("")).toBe(""); + expect(reduceModelNameToIdentifier(null)).toBe(""); + expect(reduceModelNameToIdentifier(undefined)).toBe(""); + }); + + it("handles known Claude model families", () => { + expect(reduceModelNameToIdentifier("claude-sonnet-4.5")).toBe("sonnet45"); + expect(reduceModelNameToIdentifier("claude-opus-5")).toBe("opus50"); + expect(reduceModelNameToIdentifier("claude-haiku-4.5")).toBe("haiku45"); + }); + + it("handles GPT model families", () => { + // "gpt-5" is 5 chars (< 6) so it is returned as-is + expect(reduceModelNameToIdentifier("gpt-5")).toBe("gpt-5"); + expect(reduceModelNameToIdentifier("gpt-4o")).toBe("gpt40"); + }); + + it("handles Gemini model families", () => { + expect(reduceModelNameToIdentifier("gemini-3.1-pro")).toBe("gem31pro"); + }); + + it("normalizes to lowercase before processing", () => { + expect(reduceModelNameToIdentifier("AUTO")).toBe("auto"); + expect(reduceModelNameToIdentifier("Auto")).toBe("auto"); + }); + + it("uses fallback identifier for unrecognized longer model names", () => { + // "unknown-model" -> compact "unknownmodel" (12 chars) -> letterPart "unk", digitPart "00" -> "unk00" + expect(reduceModelNameToIdentifier("unknown-model")).toBe("unk00"); + }); +}); + +describe("formatModelEmojiAlias", () => { + it('returns "auto" unchanged', () => { + expect(formatModelEmojiAlias("auto")).toBe("auto"); + }); +}); + +describe("formatModelEmojiAliasLegend", () => { + it("produces legend entries for a list of models", () => { + const result = formatModelEmojiAliasLegend(["auto", "claude-sonnet-4.5"]); + expect(result).toContain("auto=auto"); + expect(result).toContain("sonnet45=claude-sonnet-4.5"); + }); +}); From 0fb4c1d51fa8f51adb5a4af1b7b4b99c36bc44f1 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 29 Jul 2026 23:12:27 +0000 Subject: [PATCH 2/3] Apply remaining changes Co-authored-by: gh-aw-bot <259018956+gh-aw-bot@users.noreply.github.com> --- actions/setup/js/model_aliases.cjs | 2 +- actions/setup/js/model_aliases.test.cjs | 12 +++++++++--- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/actions/setup/js/model_aliases.cjs b/actions/setup/js/model_aliases.cjs index 49ccb15e2c6..3682aeb2363 100644 --- a/actions/setup/js/model_aliases.cjs +++ b/actions/setup/js/model_aliases.cjs @@ -16,7 +16,7 @@ function reduceModelNameToIdentifier(modelName) { return normalized; } - if (normalized.length < 6) { + if (normalized.length < 6 && /^[a-z0-9]+$/.test(normalized)) { return normalized; } diff --git a/actions/setup/js/model_aliases.test.cjs b/actions/setup/js/model_aliases.test.cjs index 5f6a6a84784..f9f28bb6c91 100644 --- a/actions/setup/js/model_aliases.test.cjs +++ b/actions/setup/js/model_aliases.test.cjs @@ -11,7 +11,7 @@ describe("reduceModelNameToIdentifier", () => { expect(reduceModelNameToIdentifier("auto")).toBe("auto"); }); - it("returns short model names (< 6 chars) unchanged", () => { + it("returns safe short model names (< 6 alphanumeric chars) unchanged", () => { expect(reduceModelNameToIdentifier("o1")).toBe("o1"); expect(reduceModelNameToIdentifier("o3")).toBe("o3"); expect(reduceModelNameToIdentifier("gpt")).toBe("gpt"); @@ -19,6 +19,13 @@ describe("reduceModelNameToIdentifier", () => { expect(reduceModelNameToIdentifier("haiku")).toBe("haiku"); }); + it("sanitizes short model names that contain non-alphanumeric characters", () => { + // "a|b" has a pipe character that would split a Markdown table row — must be compacted + expect(reduceModelNameToIdentifier("a|b")).toBe("abx00"); + // "gpt-5" has a hyphen, so it falls through to the GPT family shortcut + expect(reduceModelNameToIdentifier("gpt-5")).toBe("gpt50"); + }); + it("returns empty string for empty/null/undefined input", () => { expect(reduceModelNameToIdentifier("")).toBe(""); expect(reduceModelNameToIdentifier(null)).toBe(""); @@ -32,8 +39,7 @@ describe("reduceModelNameToIdentifier", () => { }); it("handles GPT model families", () => { - // "gpt-5" is 5 chars (< 6) so it is returned as-is - expect(reduceModelNameToIdentifier("gpt-5")).toBe("gpt-5"); + expect(reduceModelNameToIdentifier("gpt-5")).toBe("gpt50"); expect(reduceModelNameToIdentifier("gpt-4o")).toBe("gpt40"); }); From 080314fc99a9c614832f036a7d66681d8964590e Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 29 Jul 2026 23:46:13 +0000 Subject: [PATCH 3/3] Apply remaining changes Co-authored-by: gh-aw-bot <259018956+gh-aw-bot@users.noreply.github.com> --- actions/setup/js/model_aliases.cjs | 5 +++++ actions/setup/js/model_aliases.test.cjs | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/actions/setup/js/model_aliases.cjs b/actions/setup/js/model_aliases.cjs index 3682aeb2363..2c80eb7e8bf 100644 --- a/actions/setup/js/model_aliases.cjs +++ b/actions/setup/js/model_aliases.cjs @@ -16,6 +16,11 @@ function reduceModelNameToIdentifier(modelName) { return normalized; } + // Exact-name shortcuts for opus/sonnet/haiku are handled above. This guard + // returns any remaining short (< 6 chars) pure-alphanumeric name verbatim so + // that tokens like "o1", "auto", or "gpt" are not padded with spurious zeros. + // Names containing non-alphanumeric characters (hyphens, pipes, etc.) fall + // through to the family shortcuts or the fallback sanitizer below. if (normalized.length < 6 && /^[a-z0-9]+$/.test(normalized)) { return normalized; } diff --git a/actions/setup/js/model_aliases.test.cjs b/actions/setup/js/model_aliases.test.cjs index f9f28bb6c91..6b468227b2d 100644 --- a/actions/setup/js/model_aliases.test.cjs +++ b/actions/setup/js/model_aliases.test.cjs @@ -26,6 +26,11 @@ describe("reduceModelNameToIdentifier", () => { expect(reduceModelNameToIdentifier("gpt-5")).toBe("gpt50"); }); + it("processes names of exactly 6 characters through normalization (boundary)", () => { + // 6 chars is not < 6, so the short-name guard does not apply; normalization runs + expect(reduceModelNameToIdentifier("gpt-4o")).toBe("gpt40"); + }); + it("returns empty string for empty/null/undefined input", () => { expect(reduceModelNameToIdentifier("")).toBe(""); expect(reduceModelNameToIdentifier(null)).toBe("");