Files
OmniRoute/tests/unit/model-capabilities-command-code-codex-textonly-10703.test.ts
Wahyu Hidayatulloh Pamungkas 3805494250 feat(vision-bridge): consolidate vision bridge fixes (catalog verdict, creds, cache key, CC vision) (#10859)
Validado no worktree combinado do lote: typecheck:core, lint, gates de qualidade (file-size rebaselineado com justificativa — crescimento legítimo em modelCapabilities.ts/commandCode.ts) e os 97+9 testes focados (vision-bridge, command-code vision, model-select-field-catalog-vision) todos verdes. Duas correções reais (#10808/#10809) bem documentadas. CI vermelho neste PR é o base-red já rastreado em #9985. Obrigado!
2026-08-21 02:13:07 -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");
});