Files
OmniRoute/tests/unit/model-catalog-name-disambiguation.test.ts
Diego Rodrigues de Sa e Souza ee24eb52d4 Release v3.8.33 (#4515)
Release v3.8.33 — full CHANGELOG in the PR body. Blocking gates green (Build, Lint, Unit Tests 8/8, Package Artifact, Quality Gates, Quality Ratchet, Docs Sync, PR Test Policy, test-vitest). Admin-merged over a Node 26 future-compat timer flake (1/4) + an E2E UI flake (3/9) — both verified non-deterministic; full test:unit validated locally (16936 pass).
2026-06-22 03:17:02 -03:00

81 lines
3.6 KiB
TypeScript

import test from "node:test";
import assert from "node:assert/strict";
// Pure function — importable without DB setup.
const { disambiguateCatalogModelNames } = await import("../../src/lib/modelMetadataRegistry.ts");
type CatalogEntry = { id: string; name?: string; owned_by?: string; [key: string]: unknown };
test("leaves names untouched when each name appears under only one provider", () => {
const models: CatalogEntry[] = [
{ id: "gh/gpt-5.5", name: "GPT-5.5", owned_by: "github" },
{ id: "cc/claude-sonnet-4-6", name: "Claude Sonnet 4.6", owned_by: "claude" },
{ id: "ds-web/deepseek-r2", name: "DeepSeek R2", owned_by: "deepseek-web" },
];
const result = disambiguateCatalogModelNames(models);
assert.equal(result[0].name, "GPT-5.5", "unique name should be unchanged");
assert.equal(result[1].name, "Claude Sonnet 4.6", "unique name should be unchanged");
assert.equal(result[2].name, "DeepSeek R2", "unique name should be unchanged");
});
test("qualifies names shared across multiple providers with their prefix", () => {
const models: CatalogEntry[] = [
{ id: "gh/gpt-5.5", name: "GPT-5.5", owned_by: "github" },
{ id: "cx/gpt-5.5", name: "GPT-5.5", owned_by: "codex" },
{ id: "opencode-zen/gpt-5.5", name: "GPT-5.5", owned_by: "opencode-zen" },
{ id: "cc/claude-sonnet-4-6", name: "Claude Sonnet 4.6", owned_by: "claude" },
];
const result = disambiguateCatalogModelNames(models);
assert.equal(result[0].name, "gh/GPT-5.5", "ambiguous name should gain gh/ prefix");
assert.equal(result[1].name, "cx/GPT-5.5", "ambiguous name should gain cx/ prefix");
assert.equal(
result[2].name,
"opencode-zen/GPT-5.5",
"ambiguous name should gain opencode-zen/ prefix"
);
assert.equal(result[3].name, "Claude Sonnet 4.6", "unique name should remain unqualified");
});
test("skips entries with no name field", () => {
const models: CatalogEntry[] = [
{ id: "gh/gpt-5.5", owned_by: "github" },
{ id: "cx/gpt-5.5", owned_by: "codex" },
];
const result = disambiguateCatalogModelNames(models);
assert.equal(result[0].name, undefined, "nameless entry should stay nameless");
assert.equal(result[1].name, undefined, "nameless entry should stay nameless");
});
test("skips entries with no provider prefix in id", () => {
const models: CatalogEntry[] = [
{ id: "gpt-5.5", name: "GPT-5.5" },
{ id: "gpt-5.5-mini", name: "GPT-5.5" },
];
const result = disambiguateCatalogModelNames(models);
// No prefix extractable → counts as same prefix bucket, treated as same source
// Both names should remain because disambiguation needs 2+ distinct prefixes.
assert.equal(result[0].name, "GPT-5.5");
assert.equal(result[1].name, "GPT-5.5");
});
test("does not mutate the original model objects", () => {
const original: CatalogEntry = { id: "gh/gpt-5.5", name: "GPT-5.5", owned_by: "github" };
const dup: CatalogEntry = { id: "cx/gpt-5.5", name: "GPT-5.5", owned_by: "codex" };
const models = [original, dup];
disambiguateCatalogModelNames(models);
assert.equal(original.name, "GPT-5.5", "original object must not be mutated");
assert.equal(dup.name, "GPT-5.5", "original object must not be mutated");
});
test("handles models with no name-conflicts among combo/unprefixed entries gracefully", () => {
const models: CatalogEntry[] = [
{ id: "auto/best", owned_by: "combo" },
{ id: "my-combo", owned_by: "combo" },
{ id: "gh/gpt-4o", name: "GPT-4o", owned_by: "github" },
{ id: "cx/gpt-4o", name: "GPT-4o", owned_by: "codex" },
];
const result = disambiguateCatalogModelNames(models);
assert.equal(result[2].name, "gh/GPT-4o");
assert.equal(result[3].name, "cx/GPT-4o");
});