fix: honor explicit model config when model is not in known tier map (#2643)
When a user configures a phase-specific model that is not in MODEL_CAPABILITY_TIER (e.g. gpt-5.4, custom-provider/my-model), getModelTier() defaults to "heavy". This causes resolveModelForComplexity to downgrade every standard/light unit to tier_models, silently ignoring the user's explicit configuration. Add an isKnownModel() check before the downgrade logic. If the configured primary model is not in the known tier map, skip downgrading entirely and honor the user's choice. Known models continue to be routed normally. Closes #2192
This commit is contained in:
parent
9f071fc1b0
commit
b8fe8a6f2d
2 changed files with 65 additions and 0 deletions
|
|
@ -114,6 +114,21 @@ export function resolveModelForComplexity(
|
|||
const configuredTier = getModelTier(configuredPrimary);
|
||||
const requestedTier = classification.tier;
|
||||
|
||||
// If the configured model is unknown (not in MODEL_CAPABILITY_TIER),
|
||||
// honor the user's explicit choice — don't downgrade based on a guess.
|
||||
// Unknown models default to "heavy" in getModelTier, which makes every
|
||||
// standard/light unit get downgraded to tier_models, silently ignoring
|
||||
// the user's configuration. (#2192)
|
||||
if (!isKnownModel(configuredPrimary)) {
|
||||
return {
|
||||
modelId: configuredPrimary,
|
||||
fallbacks: phaseConfig.fallbacks,
|
||||
tier: requestedTier,
|
||||
wasDowngraded: false,
|
||||
reason: `configured model "${configuredPrimary}" is not in the known tier map — honoring explicit config`,
|
||||
};
|
||||
}
|
||||
|
||||
// Downgrade-only: if requested tier >= configured tier, no change
|
||||
if (tierOrdinal(requestedTier) >= tierOrdinal(configuredTier)) {
|
||||
return {
|
||||
|
|
@ -202,6 +217,16 @@ function getModelTier(modelId: string): ComplexityTier {
|
|||
return "heavy";
|
||||
}
|
||||
|
||||
/** Check if a model ID has a known capability tier mapping. (#2192) */
|
||||
function isKnownModel(modelId: string): boolean {
|
||||
const bareId = modelId.includes("/") ? modelId.split("/").pop()! : modelId;
|
||||
if (MODEL_CAPABILITY_TIER[bareId]) return true;
|
||||
for (const knownId of Object.keys(MODEL_CAPABILITY_TIER)) {
|
||||
if (bareId.includes(knownId) || knownId.includes(bareId)) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function findModelForTier(
|
||||
tier: ComplexityTier,
|
||||
config: DynamicRoutingConfig,
|
||||
|
|
|
|||
|
|
@ -165,3 +165,43 @@ test("falls back to configured model when no light-tier model available", () =>
|
|||
assert.equal(result.modelId, "claude-opus-4-6");
|
||||
assert.equal(result.wasDowngraded, false);
|
||||
});
|
||||
|
||||
// ─── #2192: Unknown models honor explicit config ─────────────────────────────
|
||||
|
||||
test("#2192: unknown model is not downgraded — respects user config", () => {
|
||||
const config = { ...defaultRoutingConfig(), enabled: true };
|
||||
const result = resolveModelForComplexity(
|
||||
makeClassification("light"),
|
||||
{ primary: "gpt-5.4", fallbacks: [] },
|
||||
config,
|
||||
["gpt-5.4", ...AVAILABLE_MODELS],
|
||||
);
|
||||
assert.equal(result.modelId, "gpt-5.4", "unknown model should be used as-is");
|
||||
assert.equal(result.wasDowngraded, false, "should not be downgraded");
|
||||
assert.ok(result.reason.includes("not in the known tier map"), "reason should explain why");
|
||||
});
|
||||
|
||||
test("#2192: unknown model with provider prefix is not downgraded", () => {
|
||||
const config = { ...defaultRoutingConfig(), enabled: true };
|
||||
const result = resolveModelForComplexity(
|
||||
makeClassification("standard"),
|
||||
{ primary: "custom-provider/my-model-v3", fallbacks: [] },
|
||||
config,
|
||||
["custom-provider/my-model-v3", ...AVAILABLE_MODELS],
|
||||
);
|
||||
assert.equal(result.modelId, "custom-provider/my-model-v3");
|
||||
assert.equal(result.wasDowngraded, false);
|
||||
});
|
||||
|
||||
test("#2192: known model is still downgraded normally", () => {
|
||||
const config = { ...defaultRoutingConfig(), enabled: true };
|
||||
// claude-opus-4-6 is known as "heavy" — a light request should downgrade
|
||||
const result = resolveModelForComplexity(
|
||||
makeClassification("light"),
|
||||
{ primary: "claude-opus-4-6", fallbacks: [] },
|
||||
config,
|
||||
AVAILABLE_MODELS,
|
||||
);
|
||||
assert.equal(result.wasDowngraded, true, "known heavy model should still be downgraded for light tasks");
|
||||
assert.notEqual(result.modelId, "claude-opus-4-6");
|
||||
});
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue