Files
OmniRoute/tests/unit/cursor-available-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

102 lines
3.8 KiB
TypeScript

import { describe, it } from "node:test";
import assert from "node:assert/strict";
import {
ensureCursorAutoCatalogEntry,
normalizeCursorAvailableModelsPayload,
} from "../../src/lib/providerModels/cursorAvailableModels.ts";
import { resolveRequestedModel } from "../../open-sse/utils/cursorAgentProtobuf.ts";
describe("normalizeCursorAvailableModelsPayload", () => {
it("extracts models from models[] with name ids", () => {
const models = normalizeCursorAvailableModelsPayload({
models: [
{ name: "claude-opus-5-high", displayName: "Opus 5" },
{ name: "gpt-5.6-sol-high", displayName: "GPT-5.6 Sol" },
{ name: "disabled-model", disabled: true },
],
});
assert.equal(models[0].id, "auto");
assert.ok(models.some((m) => m.id === "claude-opus-5-high"));
assert.ok(models.some((m) => m.id === "gpt-5.6-sol-high"));
assert.ok(models.some((m) => m.id === "auto-cost"));
assert.equal(models.find((m) => m.id === "claude-opus-5-high")?.name, "Opus 5");
assert.equal(models.find((m) => m.id === "claude-opus-5-high")?.owned_by, "cursor");
assert.equal(
models.some((m) => m.id === "disabled-model"),
false
);
});
it("accepts string arrays and skips empties", () => {
const models = normalizeCursorAvailableModelsPayload({
availableModels: ["auto", "composer-2.5", "auto", ""],
});
assert.equal(models[0].id, "auto");
assert.ok(models.some((m) => m.id === "composer-2.5"));
assert.ok(models.some((m) => m.id === "auto-balance"));
// Only one auto entry despite duplicate in payload
assert.equal(models.filter((m) => m.id === "auto").length, 1);
});
it("aliases default to auto and keeps default", () => {
const models = normalizeCursorAvailableModelsPayload({
models: [{ name: "default", displayName: "Auto" }, { name: "composer-2.5" }],
});
assert.equal(models[0].id, "auto");
assert.equal(models[0].name, "Auto");
assert.ok(models.some((m) => m.id === "default"));
assert.ok(models.some((m) => m.id === "composer-2.5"));
});
it("injects auto when payload has neither auto nor default", () => {
const models = normalizeCursorAvailableModelsPayload({
models: [{ name: "composer-2.5" }],
});
assert.equal(models[0].id, "auto");
assert.match(models[0].name, /Auto/i);
});
it("injects auto into an empty usable list", () => {
const models = normalizeCursorAvailableModelsPayload({ models: [] });
assert.deepEqual(
models.map((m) => m.id),
["auto", "auto-cost", "auto-balance", "auto-intelligence"]
);
});
it("injects auto router variants alongside existing models", () => {
const models = normalizeCursorAvailableModelsPayload({
models: [{ name: "composer-2.5" }],
});
for (const id of ["auto", "auto-cost", "auto-balance", "auto-intelligence", "composer-2.5"]) {
assert.ok(
models.some((m) => m.id === id),
`missing ${id}`
);
}
});
});
describe("ensureCursorAutoCatalogEntry + resolveRequestedModel", () => {
it("catalog auto stays aligned with wire default", () => {
const models = ensureCursorAutoCatalogEntry([]);
assert.equal(models[0].id, "auto");
assert.deepEqual(resolveRequestedModel("auto"), { modelId: "default", parameters: [] });
});
it("auto-cost/balance/intelligence map to default + optimization parameter", () => {
assert.deepEqual(resolveRequestedModel("auto-cost"), {
modelId: "default",
parameters: [{ id: "optimization", value: "cost" }],
});
assert.deepEqual(resolveRequestedModel("auto-balance"), {
modelId: "default",
parameters: [{ id: "optimization", value: "balance" }],
});
assert.deepEqual(resolveRequestedModel("auto-intelligence"), {
modelId: "default",
parameters: [{ id: "optimization", value: "intelligence" }],
});
});
});