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
@@ -142,6 +142,48 @@ describe("model-resolution check", () => {
snapshot: { source: "bundled-snapshot" },
})
})
it("keeps provider-prefixed overrides for transport while capability diagnostics use pattern aliases", async () => {
const { getModelResolutionInfoWithOverrides } = await import("./model-resolution")
const info = getModelResolutionInfoWithOverrides({
categories: {
"visual-engineering": { model: "google/gemini-3.1-pro-high" },
},
})
const visual = info.categories.find((category) => category.name === "visual-engineering")
expect(visual).toBeDefined()
expect(visual!.effectiveModel).toBe("google/gemini-3.1-pro-high")
expect(visual!.capabilityDiagnostics).toMatchObject({
resolutionMode: "alias-backed",
canonicalization: {
source: "pattern-alias",
ruleID: "gemini-3.1-pro-tier-alias",
},
})
})
it("keeps provider-prefixed Claude overrides for transport while capability diagnostics canonicalize to bare IDs", async () => {
const { getModelResolutionInfoWithOverrides } = await import("./model-resolution")
const info = getModelResolutionInfoWithOverrides({
agents: {
oracle: { model: "anthropic/claude-opus-4-6-thinking" },
},
})
const oracle = info.agents.find((agent) => agent.name === "oracle")
expect(oracle).toBeDefined()
expect(oracle!.effectiveModel).toBe("anthropic/claude-opus-4-6-thinking")
expect(oracle!.capabilityDiagnostics).toMatchObject({
resolutionMode: "alias-backed",
canonicalization: {
source: "pattern-alias",
ruleID: "claude-thinking-legacy-alias",
},
})
})
})
describe("checkModelResolution", () => {