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:
YeonGyu-Kim
2026-03-26 12:04:50 +09:00
parent 23df6bd255
commit 829c58ccb0
5 changed files with 231 additions and 42 deletions
+34 -6
View File
@@ -29,7 +29,7 @@ describe("model-capability-guardrails", () => {
const brokenSnapshot: ModelCapabilitiesSnapshot = {
...bundledSnapshot,
models: Object.fromEntries(
Object.entries(bundledSnapshot.models).filter(([modelID]) => modelID !== "gemini-3.1-pro"),
Object.entries(bundledSnapshot.models).filter(([modelID]) => modelID !== "gemini-3-pro-preview"),
),
}
@@ -41,13 +41,13 @@ describe("model-capability-guardrails", () => {
expect(issues).toContainEqual(
expect.objectContaining({
kind: "alias-target-missing-from-snapshot",
aliasModelID: "gemini-3.1-pro-high",
canonicalModelID: "gemini-3.1-pro",
aliasModelID: "gemini-3-pro-high",
canonicalModelID: "gemini-3-pro-preview",
}),
)
})
test("flags exact aliases when models.dev gains a canonical entry for the alias itself", () => {
test("flags pattern aliases when models.dev gains a canonical entry for the alias itself", () => {
const bundledSnapshot = getBundledModelCapabilitiesSnapshot()
const aliasCollisionSnapshot: ModelCapabilitiesSnapshot = {
...bundledSnapshot,
@@ -68,13 +68,41 @@ describe("model-capability-guardrails", () => {
expect(issues).toContainEqual(
expect.objectContaining({
kind: "exact-alias-collides-with-snapshot",
aliasModelID: "gemini-3.1-pro-high",
kind: "pattern-alias-collides-with-snapshot",
modelID: "gemini-3.1-pro-high",
canonicalModelID: "gemini-3.1-pro",
}),
)
})
test("flags exact aliases when models.dev gains a canonical entry for the alias itself", () => {
const bundledSnapshot = getBundledModelCapabilitiesSnapshot()
const aliasCollisionSnapshot: ModelCapabilitiesSnapshot = {
...bundledSnapshot,
models: {
...bundledSnapshot.models,
"gemini-3-pro-high": {
id: "gemini-3-pro-high",
family: "gemini",
reasoning: true,
},
},
}
const issues = collectModelCapabilityGuardrailIssues({
snapshot: aliasCollisionSnapshot,
requirementModelIDs: [],
})
expect(issues).toContainEqual(
expect.objectContaining({
kind: "exact-alias-collides-with-snapshot",
aliasModelID: "gemini-3-pro-high",
canonicalModelID: "gemini-3-pro-preview",
}),
)
})
test("flags built-in requirement models that rely on aliases instead of canonical IDs", () => {
const issues = collectModelCapabilityGuardrailIssues({
requirementModelIDs: ["gemini-3.1-pro-high"],