fix(combos): inherit model_context_overrides onto effort-suffixed targets (#12475) (#12926)

Validado numa worktree combinada com as 16 PRs desta leva sobre `release/v3.8.51`: typecheck:core limpo, check-file-size e check-changelog-integrity OK, complexity 2788/3218 e cognitive 1261/1437 (ambos sob a baseline), ESLint 0 erros nos 152 arquivos alterados, 771 testes unitários focados, 49 de integração e a suíte vitest:ui completa (2149) verdes.

A busca do sufixo mais longo primeiro (`-xhigh` antes de `-high`) é o detalhe que faz a herança funcionar em vez de quase-funcionar. Manter `getResolvedModelContextOverride` fora do escopo, com o teste existente registrando que aquele caminho continua sem herança, deixa a fronteira explícita.
This commit is contained in:
Bob.Hou
2026-09-07 07:57:27 -04:00
committed by GitHub
parent 6d6b6027c5
commit e8a91173de
3 changed files with 220 additions and 1 deletions

View File

@@ -0,0 +1 @@
- **fix(combos):** Effort-suffixed combo members inherit the base model's `model_context_overrides` row so priority order is not inverted on large requests ([#12926](https://github.com/diegosouzapw/OmniRoute/pull/12926)) — thanks @HouMinXi

View File

@@ -23,6 +23,56 @@
*/
import { getResolvedModelContextOverride } from "../../../src/lib/modelCapabilities";
import { parseModel } from "../model.ts";
/**
* Longest-first so `-xhigh` is not eaten by `-high`. Mirrors
* `stripKnownEffortSuffix` in modelCapabilities.ts, but that helper's array
* order still matches `-high` first (`"…-xhigh".endsWith("-high")`).
*/
const EFFORT_SUFFIXES_LONGEST_FIRST = [
"minimal",
"medium",
"xhigh",
"none",
"high",
"max",
"low",
] as const;
function stripTrailingEffortSuffix(modelId: string): string | null {
const normalized = String(modelId || "").trim();
if (!normalized) return null;
const lowered = normalized.toLowerCase();
for (const suffix of EFFORT_SUFFIXES_LONGEST_FIRST) {
const token = `-${suffix}`;
if (lowered.length > token.length && lowered.endsWith(token)) {
return normalized.slice(0, -token.length);
}
}
return null;
}
/**
* Exact override first; if missing, inherit the base id after stripping a
* trailing effort tier (#12475). Combo members are stored as
* `provider/GLM-5.3-high` while `model_context_overrides` is keyed on
* `GLM-5.3`. Dispatcher already strips the suffix; the compat filter did not.
*/
function lookupOverrideWithEffortInheritance(modelStr: string): number | null {
const exact = getResolvedModelContextOverride(modelStr);
if (exact != null) return exact;
const parsed = parseModel(modelStr);
const modelId = typeof parsed.model === "string" ? parsed.model.trim() : "";
const base = stripTrailingEffortSuffix(modelId);
if (!base || base === modelId) return null;
if (parsed.provider) {
return getResolvedModelContextOverride({ provider: parsed.provider, model: base });
}
return getResolvedModelContextOverride(base);
}
/**
* Resolve the context-fit verdict from a persisted per-model override, if one
@@ -35,7 +85,7 @@ function resolveContextOverrideVerdict(
requiredContextTokens: number
): boolean | undefined {
if (!modelStr) return undefined;
const override = getResolvedModelContextOverride(modelStr);
const override = lookupOverrideWithEffortInheritance(modelStr);
if (override == null) return undefined;
return override >= requiredContextTokens;
}

View File

@@ -0,0 +1,168 @@
import test from "node:test";
import assert from "node:assert/strict";
import fs from "node:fs";
import os from "node:os";
import path from "node:path";
// #12475: effort-suffixed combo targets must inherit the base model's
// model_context_overrides row. Without that, the compat filter falls back to
// the static catalog and inverts priority order (Diego confirmed the
// chokepoint is resolveContextOverrideVerdict).
const TEST_DATA_DIR = fs.mkdtempSync(path.join(os.tmpdir(), "omniroute-12475-effort-override-"));
const ORIGINAL_DATA_DIR = process.env.DATA_DIR;
process.env.DATA_DIR = TEST_DATA_DIR;
const core = await import("../../src/lib/db/core.ts");
const { setModelContextOverride, removeModelContextOverride } =
await import("../../src/lib/db/modelContextOverrides.ts");
const { evaluateContextLimit } =
await import("../../open-sse/services/combo/contextOverrideGate.ts");
const { saveModelsDevCapabilities, clearModelsDevCapabilities } =
await import("../../src/lib/modelsDevSync.ts");
const { filterTargetsByRequestCompatibility } =
await import("../../open-sse/services/combo.ts");
test.after(() => {
core.resetDbInstance();
if (ORIGINAL_DATA_DIR === undefined) {
delete process.env.DATA_DIR;
} else {
process.env.DATA_DIR = ORIGINAL_DATA_DIR;
}
fs.rmSync(TEST_DATA_DIR, { recursive: true, force: true, maxRetries: 5, retryDelay: 100 });
});
test.beforeEach(() => {
clearModelsDevCapabilities();
});
const LARGE_REQ = {
estimatedInputTokens: 300_000,
requiredContextTokens: 348_000,
};
function capabilityEntry(limitContext: number) {
return {
tool_call: true,
reasoning: false,
attachment: false,
structured_output: true,
temperature: true,
modalities_input: JSON.stringify(["text"]),
modalities_output: JSON.stringify(["text"]),
knowledge_cutoff: null,
release_date: null,
last_updated: null,
status: null,
family: null,
open_weights: false,
limit_context: limitContext,
limit_input: limitContext,
limit_output: 4096,
interleaved_field: null,
};
}
function target(modelStr: string) {
return {
kind: "model" as const,
stepId: modelStr,
executionKey: modelStr,
modelStr,
provider: modelStr.includes("/") ? modelStr.split("/")[0] : modelStr,
providerId: null,
connectionId: null,
weight: 1,
label: null,
};
}
function bigContextBody(tokens: number) {
return {
messages: [{ role: "user", content: "x".repeat(tokens * 4) }],
};
}
const noopLog = { info() {}, warn() {}, error() {}, debug() {} };
test("#12475 GLM-5.3-high inherits the GLM-5.3 override (catalog 200k would reject)", () => {
setModelContextOverride("unit-12475", "GLM-5.3", 385_351);
try {
const verdict = evaluateContextLimit(
{ maxInputTokens: 200_000, contextWindow: 200_000 },
LARGE_REQ,
"unit-12475/GLM-5.3-high"
);
assert.equal(verdict, true, "base override 385351 must fit 348k after stripping -high");
} finally {
removeModelContextOverride("unit-12475", "GLM-5.3");
}
});
test("#12475 GLM-5.2-high spec 1M must not shadow the GLM-5.2 override", () => {
setModelContextOverride("unit-12475", "GLM-5.2", 128_450);
try {
const verdict = evaluateContextLimit(
{ maxInputTokens: 1_000_000, contextWindow: 1_000_000 },
LARGE_REQ,
"unit-12475/GLM-5.2-high"
);
assert.equal(verdict, false, "base override 128450 must reject 348k even when spec says 1M");
} finally {
removeModelContextOverride("unit-12475", "GLM-5.2");
}
});
test("#12475 exact variant override still wins over the base row", () => {
setModelContextOverride("unit-12475", "GLM-5.3", 385_351);
setModelContextOverride("unit-12475", "GLM-5.3-high", 10_000);
try {
const verdict = evaluateContextLimit(
{ maxInputTokens: 200_000, contextWindow: 200_000 },
LARGE_REQ,
"unit-12475/GLM-5.3-high"
);
assert.equal(verdict, false, "an explicit GLM-5.3-high row must not inherit the larger base");
} finally {
removeModelContextOverride("unit-12475", "GLM-5.3-high");
removeModelContextOverride("unit-12475", "GLM-5.3");
}
});
test("#12475 xhigh / mixed-case suffix also inherit", () => {
setModelContextOverride("unit-12475", "GLM-5.3-Flash", 899_153);
try {
const verdict = evaluateContextLimit(
{ maxInputTokens: 200_000, contextWindow: 200_000 },
LARGE_REQ,
"unit-12475/GLM-5.3-Flash-xhigh"
);
assert.equal(verdict, true, "GLM-5.3-Flash-xhigh must inherit GLM-5.3-Flash");
} finally {
removeModelContextOverride("unit-12475", "GLM-5.3-Flash");
}
});
test("#12475 filter prefers the larger-window effort variant, not the spec-inflated one", () => {
saveModelsDevCapabilities({
"unit-12475": {
"GLM-5.3-high": capabilityEntry(200_000),
"GLM-5.2-high": capabilityEntry(1_000_000),
},
});
setModelContextOverride("unit-12475", "GLM-5.3", 1_000_000);
setModelContextOverride("unit-12475", "GLM-5.2", 128_000);
try {
const out = filterTargetsByRequestCompatibility(
[target("unit-12475/GLM-5.2-high"), target("unit-12475/GLM-5.3-high")],
bigContextBody(300_000),
noopLog
);
assert.equal(out[0]?.modelStr, "unit-12475/GLM-5.3-high");
assert.equal(out[1]?.modelStr, "unit-12475/GLM-5.2-high");
} finally {
removeModelContextOverride("unit-12475", "GLM-5.3");
removeModelContextOverride("unit-12475", "GLM-5.2");
}
});