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:
@@ -142,6 +142,48 @@ describe("model-resolution check", () => {
|
|||||||
snapshot: { source: "bundled-snapshot" },
|
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", () => {
|
describe("checkModelResolution", () => {
|
||||||
|
|||||||
@@ -178,8 +178,8 @@ describe("getModelCapabilities", () => {
|
|||||||
expect(result.diagnostics).toMatchObject({
|
expect(result.diagnostics).toMatchObject({
|
||||||
resolutionMode: "alias-backed",
|
resolutionMode: "alias-backed",
|
||||||
canonicalization: {
|
canonicalization: {
|
||||||
source: "exact-alias",
|
source: "pattern-alias",
|
||||||
ruleID: "claude-opus-4-6-thinking-legacy-alias",
|
ruleID: "claude-thinking-legacy-alias",
|
||||||
},
|
},
|
||||||
snapshot: { source: "bundled-snapshot" },
|
snapshot: { source: "bundled-snapshot" },
|
||||||
})
|
})
|
||||||
@@ -202,13 +202,63 @@ describe("getModelCapabilities", () => {
|
|||||||
expect(result.diagnostics).toMatchObject({
|
expect(result.diagnostics).toMatchObject({
|
||||||
resolutionMode: "alias-backed",
|
resolutionMode: "alias-backed",
|
||||||
canonicalization: {
|
canonicalization: {
|
||||||
source: "exact-alias",
|
source: "pattern-alias",
|
||||||
ruleID: "gemini-3.1-pro-tier-alias",
|
ruleID: "gemini-3.1-pro-tier-alias",
|
||||||
},
|
},
|
||||||
snapshot: { source: "bundled-snapshot" },
|
snapshot: { source: "bundled-snapshot" },
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
test("canonicalizes provider-prefixed gemini aliases without changing the transport-facing request", () => {
|
||||||
|
const result = getModelCapabilities({
|
||||||
|
providerID: "google",
|
||||||
|
modelID: "google/gemini-3.1-pro-high",
|
||||||
|
bundledSnapshot,
|
||||||
|
})
|
||||||
|
|
||||||
|
expect(result).toMatchObject({
|
||||||
|
requestedModelID: "google/gemini-3.1-pro-high",
|
||||||
|
canonicalModelID: "gemini-3.1-pro",
|
||||||
|
family: "gemini",
|
||||||
|
supportsThinking: true,
|
||||||
|
supportsTemperature: true,
|
||||||
|
maxOutputTokens: 65_000,
|
||||||
|
})
|
||||||
|
expect(result.diagnostics).toMatchObject({
|
||||||
|
resolutionMode: "alias-backed",
|
||||||
|
canonicalization: {
|
||||||
|
source: "pattern-alias",
|
||||||
|
ruleID: "gemini-3.1-pro-tier-alias",
|
||||||
|
},
|
||||||
|
snapshot: { source: "bundled-snapshot" },
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
test("canonicalizes provider-prefixed Claude thinking aliases to bare snapshot IDs", () => {
|
||||||
|
const result = getModelCapabilities({
|
||||||
|
providerID: "anthropic",
|
||||||
|
modelID: "anthropic/claude-opus-4-6-thinking",
|
||||||
|
bundledSnapshot,
|
||||||
|
})
|
||||||
|
|
||||||
|
expect(result).toMatchObject({
|
||||||
|
requestedModelID: "anthropic/claude-opus-4-6-thinking",
|
||||||
|
canonicalModelID: "claude-opus-4-6",
|
||||||
|
family: "claude-opus",
|
||||||
|
supportsThinking: true,
|
||||||
|
supportsTemperature: true,
|
||||||
|
maxOutputTokens: 128_000,
|
||||||
|
})
|
||||||
|
expect(result.diagnostics).toMatchObject({
|
||||||
|
resolutionMode: "alias-backed",
|
||||||
|
canonicalization: {
|
||||||
|
source: "pattern-alias",
|
||||||
|
ruleID: "claude-thinking-legacy-alias",
|
||||||
|
},
|
||||||
|
snapshot: { source: "bundled-snapshot" },
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
test("prefers runtime models.dev cache over bundled snapshot", () => {
|
test("prefers runtime models.dev cache over bundled snapshot", () => {
|
||||||
const runtimeSnapshot: ModelCapabilitiesSnapshot = {
|
const runtimeSnapshot: ModelCapabilitiesSnapshot = {
|
||||||
...bundledSnapshot,
|
...bundledSnapshot,
|
||||||
@@ -272,7 +322,8 @@ describe("getModelCapabilities", () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
expect(result).toMatchObject({
|
expect(result).toMatchObject({
|
||||||
canonicalModelID: "openai/o3-mini",
|
requestedModelID: "openai/o3-mini",
|
||||||
|
canonicalModelID: "o3-mini",
|
||||||
family: "openai-reasoning",
|
family: "openai-reasoning",
|
||||||
variants: ["low", "medium", "high"],
|
variants: ["low", "medium", "high"],
|
||||||
reasoningEfforts: ["none", "minimal", "low", "medium", "high"],
|
reasoningEfforts: ["none", "minimal", "low", "medium", "high"],
|
||||||
|
|||||||
@@ -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")
|
const result = resolveModelIDAlias("gemini-3.1-pro-high")
|
||||||
|
|
||||||
expect(result).toEqual({
|
expect(result).toEqual({
|
||||||
requestedModelID: "gemini-3.1-pro-high",
|
requestedModelID: "gemini-3.1-pro-high",
|
||||||
canonicalModelID: "gemini-3.1-pro",
|
canonicalModelID: "gemini-3.1-pro",
|
||||||
source: "exact-alias",
|
source: "pattern-alias",
|
||||||
ruleID: "gemini-3.1-pro-tier-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", () => {
|
test("does not resolve prototype keys as aliases", () => {
|
||||||
const result = resolveModelIDAlias("constructor")
|
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")
|
const result = resolveModelIDAlias("claude-opus-4-6-thinking")
|
||||||
|
|
||||||
expect(result).toEqual({
|
expect(result).toEqual({
|
||||||
requestedModelID: "claude-opus-4-6-thinking",
|
requestedModelID: "claude-opus-4-6-thinking",
|
||||||
canonicalModelID: "claude-opus-4-6",
|
canonicalModelID: "claude-opus-4-6",
|
||||||
source: "exact-alias",
|
source: "pattern-alias",
|
||||||
ruleID: "claude-opus-4-6-thinking-legacy-alias",
|
ruleID: "claude-thinking-legacy-alias",
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -20,18 +20,6 @@ export type ModelIDAliasResolution = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const EXACT_ALIAS_RULES: ReadonlyArray<ExactAliasRule> = [
|
const EXACT_ALIAS_RULES: ReadonlyArray<ExactAliasRule> = [
|
||||||
{
|
|
||||||
aliasModelID: "gemini-3.1-pro-high",
|
|
||||||
ruleID: "gemini-3.1-pro-tier-alias",
|
|
||||||
canonicalModelID: "gemini-3.1-pro",
|
|
||||||
rationale: "OmO historically encoded Gemini tier selection in the model name instead of variant metadata.",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
aliasModelID: "gemini-3.1-pro-low",
|
|
||||||
ruleID: "gemini-3.1-pro-tier-alias",
|
|
||||||
canonicalModelID: "gemini-3.1-pro",
|
|
||||||
rationale: "OmO historically encoded Gemini tier selection in the model name instead of variant metadata.",
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
aliasModelID: "gemini-3-pro-high",
|
aliasModelID: "gemini-3-pro-high",
|
||||||
ruleID: "gemini-3-pro-tier-alias",
|
ruleID: "gemini-3-pro-tier-alias",
|
||||||
@@ -44,30 +32,47 @@ const EXACT_ALIAS_RULES: ReadonlyArray<ExactAliasRule> = [
|
|||||||
canonicalModelID: "gemini-3-pro-preview",
|
canonicalModelID: "gemini-3-pro-preview",
|
||||||
rationale: "Legacy Gemini 3 tier suffixes still need to land on the canonical preview model.",
|
rationale: "Legacy Gemini 3 tier suffixes still need to land on the canonical preview model.",
|
||||||
},
|
},
|
||||||
{
|
|
||||||
aliasModelID: "claude-opus-4-6-thinking",
|
|
||||||
ruleID: "claude-opus-4-6-thinking-legacy-alias",
|
|
||||||
canonicalModelID: "claude-opus-4-6",
|
|
||||||
rationale: "OmO historically used a legacy compatibility suffix before models.dev shipped canonical thinking variants for newer Claude families.",
|
|
||||||
},
|
|
||||||
]
|
]
|
||||||
|
|
||||||
const EXACT_ALIAS_RULES_BY_MODEL: ReadonlyMap<string, ExactAliasRule> = new Map(
|
const EXACT_ALIAS_RULES_BY_MODEL: ReadonlyMap<string, ExactAliasRule> = new Map(
|
||||||
EXACT_ALIAS_RULES.map((rule) => [rule.aliasModelID, rule]),
|
EXACT_ALIAS_RULES.map((rule) => [rule.aliasModelID, rule]),
|
||||||
)
|
)
|
||||||
|
|
||||||
const PATTERN_ALIAS_RULES: ReadonlyArray<PatternAliasRule> = []
|
const PATTERN_ALIAS_RULES: ReadonlyArray<PatternAliasRule> = [
|
||||||
|
{
|
||||||
|
ruleID: "claude-thinking-legacy-alias",
|
||||||
|
description: "Normalizes the legacy Claude Opus 4.6 thinking suffix to the canonical snapshot ID.",
|
||||||
|
match: (normalizedModelID) => /^claude-opus-4-6-thinking$/.test(normalizedModelID),
|
||||||
|
canonicalize: () => "claude-opus-4-6",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ruleID: "gemini-3.1-pro-tier-alias",
|
||||||
|
description: "Normalizes Gemini 3.1 Pro tier suffixes to the canonical snapshot ID.",
|
||||||
|
match: (normalizedModelID) => /^gemini-3\.1-pro-(?:high|low)$/.test(normalizedModelID),
|
||||||
|
canonicalize: () => "gemini-3.1-pro",
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
function normalizeLookupModelID(modelID: string): string {
|
function normalizeLookupModelID(modelID: string): string {
|
||||||
return modelID.trim().toLowerCase()
|
return modelID.trim().toLowerCase()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function stripProviderPrefixForAliasLookup(normalizedModelID: string): string {
|
||||||
|
const slashIndex = normalizedModelID.indexOf("/")
|
||||||
|
if (slashIndex <= 0 || slashIndex === normalizedModelID.length - 1) {
|
||||||
|
return normalizedModelID
|
||||||
|
}
|
||||||
|
|
||||||
|
return normalizedModelID.slice(slashIndex + 1)
|
||||||
|
}
|
||||||
|
|
||||||
export function resolveModelIDAlias(modelID: string): ModelIDAliasResolution {
|
export function resolveModelIDAlias(modelID: string): ModelIDAliasResolution {
|
||||||
const normalizedModelID = normalizeLookupModelID(modelID)
|
const requestedModelID = normalizeLookupModelID(modelID)
|
||||||
const exactRule = EXACT_ALIAS_RULES_BY_MODEL.get(normalizedModelID)
|
const aliasLookupModelID = stripProviderPrefixForAliasLookup(requestedModelID)
|
||||||
|
const exactRule = EXACT_ALIAS_RULES_BY_MODEL.get(aliasLookupModelID)
|
||||||
if (exactRule) {
|
if (exactRule) {
|
||||||
return {
|
return {
|
||||||
requestedModelID: normalizedModelID,
|
requestedModelID,
|
||||||
canonicalModelID: exactRule.canonicalModelID,
|
canonicalModelID: exactRule.canonicalModelID,
|
||||||
source: "exact-alias",
|
source: "exact-alias",
|
||||||
ruleID: exactRule.ruleID,
|
ruleID: exactRule.ruleID,
|
||||||
@@ -75,21 +80,21 @@ export function resolveModelIDAlias(modelID: string): ModelIDAliasResolution {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (const rule of PATTERN_ALIAS_RULES) {
|
for (const rule of PATTERN_ALIAS_RULES) {
|
||||||
if (!rule.match(normalizedModelID)) {
|
if (!rule.match(aliasLookupModelID)) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
requestedModelID: normalizedModelID,
|
requestedModelID,
|
||||||
canonicalModelID: rule.canonicalize(normalizedModelID),
|
canonicalModelID: rule.canonicalize(aliasLookupModelID),
|
||||||
source: "pattern-alias",
|
source: "pattern-alias",
|
||||||
ruleID: rule.ruleID,
|
ruleID: rule.ruleID,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
requestedModelID: normalizedModelID,
|
requestedModelID,
|
||||||
canonicalModelID: normalizedModelID,
|
canonicalModelID: aliasLookupModelID,
|
||||||
source: "canonical",
|
source: "canonical",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ describe("model-capability-guardrails", () => {
|
|||||||
const brokenSnapshot: ModelCapabilitiesSnapshot = {
|
const brokenSnapshot: ModelCapabilitiesSnapshot = {
|
||||||
...bundledSnapshot,
|
...bundledSnapshot,
|
||||||
models: Object.fromEntries(
|
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(issues).toContainEqual(
|
||||||
expect.objectContaining({
|
expect.objectContaining({
|
||||||
kind: "alias-target-missing-from-snapshot",
|
kind: "alias-target-missing-from-snapshot",
|
||||||
aliasModelID: "gemini-3.1-pro-high",
|
aliasModelID: "gemini-3-pro-high",
|
||||||
canonicalModelID: "gemini-3.1-pro",
|
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 bundledSnapshot = getBundledModelCapabilitiesSnapshot()
|
||||||
const aliasCollisionSnapshot: ModelCapabilitiesSnapshot = {
|
const aliasCollisionSnapshot: ModelCapabilitiesSnapshot = {
|
||||||
...bundledSnapshot,
|
...bundledSnapshot,
|
||||||
@@ -68,13 +68,41 @@ describe("model-capability-guardrails", () => {
|
|||||||
|
|
||||||
expect(issues).toContainEqual(
|
expect(issues).toContainEqual(
|
||||||
expect.objectContaining({
|
expect.objectContaining({
|
||||||
kind: "exact-alias-collides-with-snapshot",
|
kind: "pattern-alias-collides-with-snapshot",
|
||||||
aliasModelID: "gemini-3.1-pro-high",
|
modelID: "gemini-3.1-pro-high",
|
||||||
canonicalModelID: "gemini-3.1-pro",
|
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", () => {
|
test("flags built-in requirement models that rely on aliases instead of canonical IDs", () => {
|
||||||
const issues = collectModelCapabilityGuardrailIssues({
|
const issues = collectModelCapabilityGuardrailIssues({
|
||||||
requirementModelIDs: ["gemini-3.1-pro-high"],
|
requirementModelIDs: ["gemini-3.1-pro-high"],
|
||||||
|
|||||||
Reference in New Issue
Block a user