Files
OmniRoute/tests/unit/claude-context-1m-supported-models.test.ts
Diego Rodrigues de Sa e Souza 50da54484e fix: downgrade adaptive thinking and gate context-1m beta on model eligibility (#10119) (#10481)
* fix(sse): downgrade adaptive thinking and gate context-1m beta on model eligibility (#10119)

* fix(sse): thread resolved model into DefaultExecutor's anthropic-beta merge (#10119)

DefaultExecutor.buildHeaders() merged the client-negotiated anthropic-beta
header without ever passing the resolved target model into
mergeClientAnthropicBeta(), so the context-1m-2025-08-07 eligibility gate
added earlier in this PR could not see which model a combo/fallback had
actually routed to at this call site. buildHeaders() now accepts an
optional model parameter (mirroring BaseExecutor.buildHeaders' existing
signature and the pattern already used by grok-cli.ts/qoder.ts) and
forwards it through, so an ineligible model target (e.g. Haiku) has the
beta dropped instead of forwarded blind.

Restores a CHANGELOG bullet (PR #10366) that a prior merge auto-resolve
had dropped from this branch.

---------

Co-authored-by: adevwithpurpose <adevwithpurpose@users.noreply.github.com>
2026-08-18 10:50:49 -03:00

168 lines
5.8 KiB
TypeScript

import test from "node:test";
import assert from "node:assert/strict";
import fs from "node:fs";
import path from "node:path";
const REPO_ROOT = path.resolve(import.meta.dirname, "../..");
// ─── Parse 1M model lists from source (no module import needed) ───
function parseModelList(constantName: string): string[] {
const sourceFile =
constantName === "CONTEXT_1M_NATIVE_MODELS"
? "open-sse/config/claudeCodeCompatibleIdentity.ts"
: constantName === "CONTEXT_1M_SUPPORTED_MODELS"
? "open-sse/config/context1m.ts"
: "open-sse/services/claudeCodeCompatible.ts";
const src = fs.readFileSync(path.join(REPO_ROOT, sourceFile), "utf8");
// Strip type annotations before matching to handle `const X: string[] = [...]`
const match = src
.replace(/:\s*\w+(\[\])?/, "")
.match(new RegExp(`${constantName}\\s*=\\s*\\[([\\s\\S]*?)\\]`));
if (!match) throw new Error(`${constantName} not found in source`);
return match[1]
.split(",")
.map((s) => s.replace(/["'\s]/g, "").toLowerCase())
.filter(Boolean);
}
// ─── Parse Claude models from provider registry (source-level) ───
// Uses brace-counting to isolate each model block within the models array,
// avoiding false matches on the provider-level id field.
function parseClaudeRegistryModels(): Array<{
provider: string;
modelId: string;
contextLength: number;
}> {
const registryDir = path.join(REPO_ROOT, "open-sse/config/providers/registry/claude");
const results: Array<{
provider: string;
modelId: string;
contextLength: number;
}> = [];
for (const file of fs.readdirSync(registryDir).filter((f) => f.endsWith(".ts"))) {
const src = fs.readFileSync(path.join(registryDir, file), "utf8");
// Extract provider id
const providerIdMatch = src.match(/id:\s*["']([^"']+)["']/);
const providerId = providerIdMatch?.[1] ?? file.replace(".ts", "");
// Find the models array
const modelsStart = src.indexOf("models:");
if (modelsStart === -1) continue;
const arrayStart = src.indexOf("[", modelsStart);
if (arrayStart === -1) continue;
// Extract individual model objects using brace counting.
// Skips any non-model nested braces by requiring both id and contextLength
// in the same brace-delimited block.
let braceDepth = 0;
let objStart = -1;
const modelBlocks: string[] = [];
for (let i = arrayStart; i < src.length; i++) {
if (src[i] === "{") {
if (braceDepth === 0) objStart = i;
braceDepth++;
} else if (src[i] === "}") {
braceDepth--;
if (braceDepth === 0 && objStart !== -1) {
modelBlocks.push(src.slice(objStart, i + 1));
objStart = -1;
}
} else if (src[i] === "]" && braceDepth === 0) {
break;
}
}
for (const block of modelBlocks) {
const idMatch = block.match(/id:\s*["']([^"']+)["']/);
const ctxMatch = block.match(/contextLength:\s*(\d+)/);
if (idMatch && ctxMatch) {
results.push({
provider: providerId,
modelId: idMatch[1].toLowerCase(),
contextLength: parseInt(ctxMatch[1], 10),
});
}
}
}
return results;
}
const CONTEXT_1M_THRESHOLD = 200_000;
function isModel1mSupported(modelId: string, supportedModels: string[]): boolean {
const normalized = modelId.replace(/:.*$/, "").toLowerCase();
return supportedModels.some((s) => normalized === s || normalized.startsWith(`${s}-`));
}
// ─── Sanity: parser must find at least one model ───
test("parser finds at least one Claude model in the registry", () => {
const models = parseClaudeRegistryModels();
assert.ok(
models.length > 0,
"parseClaudeRegistryModels returned 0 models — check that open-sse/config/providers/registry/claude/ exists and contains model definitions"
);
});
// ─── Forward: every high-context Claude model must be in the allowlist ───
test("every Claude model with contextLength > 200K is in a known 1M model list", () => {
const supportedModels = [
...parseModelList("CONTEXT_1M_SUPPORTED_MODELS"),
...parseModelList("CONTEXT_1M_NATIVE_MODELS"),
];
const claudeModels = parseClaudeRegistryModels();
const violations: string[] = [];
for (const m of claudeModels) {
if (m.contextLength > CONTEXT_1M_THRESHOLD && !isModel1mSupported(m.modelId, supportedModels)) {
violations.push(`${m.provider}/${m.modelId} (contextLength=${m.contextLength})`);
}
}
assert.deepEqual(
violations,
[],
`Claude models with contextLength > 200K missing from the beta/native 1M lists.\n` +
`Add the model prefix to the correct source list.\n` +
`Violations:\n ${violations.join("\n ")}`
);
});
// ─── Reverse: every allowlist entry must have a matching high-context model ───
test("every known 1M model entry has a matching high-context Claude model", () => {
const supportedModels = [
...parseModelList("CONTEXT_1M_SUPPORTED_MODELS"),
...parseModelList("CONTEXT_1M_NATIVE_MODELS"),
];
const claudeModels = parseClaudeRegistryModels();
const orphans: string[] = [];
for (const supported of supportedModels) {
const found = claudeModels.some(
(m) =>
m.contextLength > CONTEXT_1M_THRESHOLD &&
(m.modelId === supported || m.modelId.startsWith(`${supported}-`))
);
if (!found) orphans.push(supported);
}
assert.deepEqual(
orphans,
[],
`Known 1M entries with no matching high-context Claude model.\n` +
`Remove stale entries or check model id spelling.\n` +
`Orphans:\n ${orphans.join("\n ")}`
);
});
test("Claude Opus 5 uses native 1M context without the legacy beta header", () => {
assert.equal(parseModelList("CONTEXT_1M_SUPPORTED_MODELS").includes("claude-opus-5"), false);
assert.equal(parseModelList("CONTEXT_1M_NATIVE_MODELS").includes("claude-opus-5"), true);
});