Files
OmniRoute/tests/unit/claude-context-1m-supported-models.test.ts
Praveen K Palaniswamy 65e81158ab fix(ollama): route models by advertised capability (#11088)
Landed with the design call resolved per the owner's pick — **option 1**: the synced store is now endpoint-agnostic (persistDiscoveredModels and managedModelImport no longer drop non-chat models at write time), and chat selectability moved to read time (auto-pool expansion in autoStrategy applies filterChatSelectableModels; the models-route projection already had its chatOnly filter). Your discovery test now passes end-to-end (3/3): /api/show capabilities persist per connection and image/embedding requests route through the advertising host.

Reconciliation notes: conflicted areas merged onto the current tip (adobe discovery import, requestedModel preflight signature, resolvedProvider fast-path coexists with the synced-route override — explicit resolution wins); carried base-red drains (#10055 memoization, #11071 test variants) dropped as already-landed; the managed-model-import exclusion test was propagated to the new contract (image/video models persist; the read filter still hides them from chat pickers — pinned by a new assertion). Full battery: 205/206 focused (the one red is a confirmed periodic-timer timing flake on the loaded devbox — 20/20 isolated), autoCombo vitest 30/30, combo suites 46/46, gates + typecheck clean.

Thank you @yourspraveen — the capability probe + routing design was right; it just needed the store contract opened up. Fixes #11087.
2026-08-23 11:45:01 -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);
});