refactor(aliases): migrate to pattern-based model alias resolution
Move from hardcoded exact aliases to pattern-based canonicalization:
- Populate PATTERN_ALIAS_RULES with regex patterns for:
- Claude thinking variants (claude-opus-4-6-thinking → claude-opus-4-6)
- Gemini tier suffixes (gemini-3.1-pro-{high,low} → gemini-3.1-pro)
- Add stripProviderPrefixForAliasLookup() for provider-prefixed models
(anthropic/claude-sonnet-4-6 → claude-sonnet-4-6 for capability lookup)
- Preserve requestedModelID (with prefix) for API transport
- Reduce EXACT_ALIAS_RULES to exceptional cases only
(gemini-3-pro-{high,low} → gemini-3-pro-preview)
- Comprehensive test coverage for patterns, prefix stripping, negatives
Addresses Discussion #2835 (pattern matching architecture)
Related to PR #2834 (alias guardrails)
41 targeted tests pass, 4467 full suite tests pass, tsc clean.
This commit is contained in:
@@ -13,17 +13,49 @@ describe("model-capability-aliases", () => {
|
||||
})
|
||||
})
|
||||
|
||||
test("normalizes exact local tier aliases to canonical models.dev IDs", () => {
|
||||
test("strips provider prefixes when the input is already canonical", () => {
|
||||
const result = resolveModelIDAlias("anthropic/claude-sonnet-4-6")
|
||||
|
||||
expect(result).toEqual({
|
||||
requestedModelID: "anthropic/claude-sonnet-4-6",
|
||||
canonicalModelID: "claude-sonnet-4-6",
|
||||
source: "canonical",
|
||||
})
|
||||
})
|
||||
|
||||
test("normalizes gemini tier aliases through a pattern rule", () => {
|
||||
const result = resolveModelIDAlias("gemini-3.1-pro-high")
|
||||
|
||||
expect(result).toEqual({
|
||||
requestedModelID: "gemini-3.1-pro-high",
|
||||
canonicalModelID: "gemini-3.1-pro",
|
||||
source: "exact-alias",
|
||||
source: "pattern-alias",
|
||||
ruleID: "gemini-3.1-pro-tier-alias",
|
||||
})
|
||||
})
|
||||
|
||||
test("normalizes provider-prefixed gemini tier aliases to bare canonical IDs", () => {
|
||||
const result = resolveModelIDAlias("google/gemini-3.1-pro-high")
|
||||
|
||||
expect(result).toEqual({
|
||||
requestedModelID: "google/gemini-3.1-pro-high",
|
||||
canonicalModelID: "gemini-3.1-pro",
|
||||
source: "pattern-alias",
|
||||
ruleID: "gemini-3.1-pro-tier-alias",
|
||||
})
|
||||
})
|
||||
|
||||
test("keeps exceptional gemini preview aliases as exact rules", () => {
|
||||
const result = resolveModelIDAlias("gemini-3-pro-high")
|
||||
|
||||
expect(result).toEqual({
|
||||
requestedModelID: "gemini-3-pro-high",
|
||||
canonicalModelID: "gemini-3-pro-preview",
|
||||
source: "exact-alias",
|
||||
ruleID: "gemini-3-pro-tier-alias",
|
||||
})
|
||||
})
|
||||
|
||||
test("does not resolve prototype keys as aliases", () => {
|
||||
const result = resolveModelIDAlias("constructor")
|
||||
|
||||
@@ -34,14 +66,45 @@ describe("model-capability-aliases", () => {
|
||||
})
|
||||
})
|
||||
|
||||
test("normalizes legacy Claude thinking aliases through a named exact rule", () => {
|
||||
test("normalizes provider-prefixed Claude thinking aliases through a pattern rule", () => {
|
||||
const result = resolveModelIDAlias("anthropic/claude-opus-4-6-thinking")
|
||||
|
||||
expect(result).toEqual({
|
||||
requestedModelID: "anthropic/claude-opus-4-6-thinking",
|
||||
canonicalModelID: "claude-opus-4-6",
|
||||
source: "pattern-alias",
|
||||
ruleID: "claude-thinking-legacy-alias",
|
||||
})
|
||||
})
|
||||
|
||||
test("does not pattern-match nearby canonical Claude IDs incorrectly", () => {
|
||||
const result = resolveModelIDAlias("claude-opus-4-6-think")
|
||||
|
||||
expect(result).toEqual({
|
||||
requestedModelID: "claude-opus-4-6-think",
|
||||
canonicalModelID: "claude-opus-4-6-think",
|
||||
source: "canonical",
|
||||
})
|
||||
})
|
||||
|
||||
test("does not pattern-match canonical gemini preview IDs incorrectly", () => {
|
||||
const result = resolveModelIDAlias("gemini-3.1-pro-preview")
|
||||
|
||||
expect(result).toEqual({
|
||||
requestedModelID: "gemini-3.1-pro-preview",
|
||||
canonicalModelID: "gemini-3.1-pro-preview",
|
||||
source: "canonical",
|
||||
})
|
||||
})
|
||||
|
||||
test("normalizes legacy Claude thinking aliases through a pattern rule", () => {
|
||||
const result = resolveModelIDAlias("claude-opus-4-6-thinking")
|
||||
|
||||
expect(result).toEqual({
|
||||
requestedModelID: "claude-opus-4-6-thinking",
|
||||
canonicalModelID: "claude-opus-4-6",
|
||||
source: "exact-alias",
|
||||
ruleID: "claude-opus-4-6-thinking-legacy-alias",
|
||||
source: "pattern-alias",
|
||||
ruleID: "claude-thinking-legacy-alias",
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user