Files
OmniRoute/tests/unit/model-capabilities-command-code-codex-textonly-10703.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

71 lines
3.2 KiB
TypeScript

/**
* #10703 — Command Code `gpt-5.3-codex` model ids must NOT resolve as
* vision-capable through the shared capability resolver.
*
* The Command Code gateway registry declared `supportsVision: true` for
* `gpt-5.3-codex`, so the Modality Bridge Vision dropdown (which reads
* `/api/models` → `getResolvedModelCapabilities`) listed it as a Vision Bridge
* candidate. Selecting it as the Vision model failed image describe calls
* (#10703, CONTRIBUTOR). The fix adds the id family to the existing
* `KNOWN_TEXT_ONLY_DESPITE_SYNC` hard-override — the same mechanism that keeps
* `mimo-v2.5-pro` text-only — so the shared verdict is `false` everywhere
* (dropdown, Vision Bridge auto-router, `/v1/models`, compression).
*
* Scope discipline: only the Command Code gateway's `cmd/` / `command-code/`
* codex variants are overridden. Genuine multimodal OpenAI codex ids
* (`openai/gpt-5.3-codex`) and the `gpt-5.x` chat family (`gpt-5.4`,
* `gpt-5.4-mini`, `gpt-5.5`) must keep `supportsVision: true`.
*/
import test from "node:test";
import assert from "node:assert/strict";
import { getResolvedModelCapabilities } from "../../src/lib/modelCapabilities.ts";
// ── Overridden: Command Code gateway codex ids are text-only (#10703) ────────
const CC_TEXT_ONLY_CODEX: [string, string][] = [
["alias prefix", "cmd/gpt-5.3-codex"],
["raw provider id", "command-code/gpt-5.3-codex"],
["spark variant", "cmd/gpt-5.3-codex-spark"],
["effort variant", "cmd/gpt-5.3-codex-high"],
["preview variant", "cmd/gpt-5.3-codex-spark-preview"],
];
for (const [desc, modelId] of CC_TEXT_ONLY_CODEX) {
test(`#10703: ${desc} ${modelId} → supportsVision=false`, () => {
const caps = getResolvedModelCapabilities(modelId);
assert.equal(caps.supportsVision, false, `${modelId} is text-only via Command Code (#10703)`);
});
}
// ── NOT overridden: known multimodal / non-CC ids keep their vision verdict ──
const MUST_STAY_VISION: [string, string][] = [
["real OpenAI codex", "openai/gpt-5.3-codex"],
["multimodal gpt-5.5", "cmd/gpt-5.5"],
["multimodal gpt-5.4", "cmd/gpt-5.4"],
["multimodal gpt-5.4-mini", "cmd/gpt-5.4-mini"],
["claude opus 4.7 (CC)", "cmd/claude-opus-4-7"],
["kimi k2.6 (CC)", "cmd/moonshotai/Kimi-K2.6"],
];
for (const [desc, modelId] of MUST_STAY_VISION) {
test(`#10703 scope guard: ${desc} ${modelId} stays supportsVision=true`, () => {
const caps = getResolvedModelCapabilities(modelId);
assert.equal(caps.supportsVision, true, `${modelId} must not be overridden (#10703 scope)`);
});
}
// ── The override must also beat a wrong synced attachment/modalit
// (the #4071 failure mode), mirroring the mimo-v2.5-pro guard tests. ──────
test("#10703: override still wins when synced capability wrongly claims vision-support", () => {
// No DB/synced fan-in in this repo for command-code static ids (they are
// registry-driven), so a plain resolution is the authoritative check — a
// registry `supportsVision: true` must be neutralized even without synced
// data present.
const caps = getResolvedModelCapabilities("cmd/gpt-5.3-codex");
assert.equal(caps.supportsVision, false);
assert.equal(caps.provider, "command-code");
});