From da4c3660f49ac7937bfece3c827039363565b479 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Art=D1=91m?= <470045+yart@users.noreply.github.com> Date: Mon, 27 Apr 2026 16:30:17 +0300 Subject: [PATCH] fix(vision): respected native GPT vision support (#1678) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Integrated into release/v3.7.2 — removes blanket gpt-* Vision Bridge override, respects native vision support --- src/shared/constants/visionBridgeDefaults.ts | 10 +++++++--- tests/unit/guardrails/visionBridge.test.ts | 15 +++++++++------ tests/unit/visionBridgeDefaults.test.ts | 7 +++++++ 3 files changed, 23 insertions(+), 9 deletions(-) diff --git a/src/shared/constants/visionBridgeDefaults.ts b/src/shared/constants/visionBridgeDefaults.ts index e4392af60b..7a561e742d 100644 --- a/src/shared/constants/visionBridgeDefaults.ts +++ b/src/shared/constants/visionBridgeDefaults.ts @@ -2,12 +2,16 @@ * Vision Bridge default configuration values. */ -const NORMALIZED_GPT_MODEL_PATTERN = /^gpt-/i; +const FORCED_VISION_BRIDGE_MODELS = new Set([ + // Fallback list for models whose metadata is known to overstate native vision support. +]); export function isVisionBridgeForcedModel(model: string | null | undefined): boolean { if (!model) return false; - const normalizedModel = model.includes("/") ? model.split("/").pop() || model : model; - return NORMALIZED_GPT_MODEL_PATTERN.test(normalizedModel); + const normalizedModel = (model.includes("/") ? model.split("/").pop() || model : model) + .trim() + .toLowerCase(); + return FORCED_VISION_BRIDGE_MODELS.has(normalizedModel); } export const VISION_BRIDGE_DEFAULTS = { diff --git a/tests/unit/guardrails/visionBridge.test.ts b/tests/unit/guardrails/visionBridge.test.ts index d8b241ad4d..0925bbe8bc 100644 --- a/tests/unit/guardrails/visionBridge.test.ts +++ b/tests/unit/guardrails/visionBridge.test.ts @@ -164,11 +164,10 @@ test("VB-S02: passthroughs for vision-capable model (gpt-4o)", async () => { } }); -test("VB-S02b: forces Vision Bridge for GPT-family models even when model capabilities advertise vision", async () => { +test("VB-S02b: respects native vision support for GPT-family models", async () => { const guardrail = createGuardrail(); - for (const model of ["gpt-5.4", "gpt-5.4-mini", "gpt-4o", "openai/gpt-4o-mini"]) { - mockVisionResponse = `Forced bridge description for ${model}`; + for (const model of ["gpt-5.5", "gpt-5.5-high", "codex/gpt-5.5", "openai/gpt-4o-mini"]) { visionCallCount = 0; const payload = createPayload({ @@ -189,9 +188,13 @@ test("VB-S02b: forces Vision Bridge for GPT-family models even when model capabi const result = await guardrail.preCall(payload, createContext({ model })); - assert.strictEqual(result.block, false, `expected passthrough=false for ${model}`); - assert.ok(result.modifiedPayload, `expected modified payload for ${model}`); - assert.strictEqual(visionCallCount, 1, `expected one forced bridge call for ${model}`); + assert.strictEqual(result.block, false, `expected passthrough for ${model}`); + assert.strictEqual( + result.modifiedPayload, + undefined, + `expected unmodified payload for ${model}` + ); + assert.strictEqual(visionCallCount, 0, `expected no bridge call for ${model}`); } }); diff --git a/tests/unit/visionBridgeDefaults.test.ts b/tests/unit/visionBridgeDefaults.test.ts index 2d631e05de..65042c8eb9 100644 --- a/tests/unit/visionBridgeDefaults.test.ts +++ b/tests/unit/visionBridgeDefaults.test.ts @@ -8,6 +8,7 @@ import { VISION_BRIDGE_DEFAULTS, VISION_BRIDGE_SETTINGS_KEYS, getVisionBridgeConfig, + isVisionBridgeForcedModel, type VisionBridgeSettings, } from "@/shared/constants/visionBridgeDefaults"; @@ -32,6 +33,12 @@ test("VISION_BRIDGE_SETTINGS_KEYS exports all expected keys", () => { ]); }); +test("isVisionBridgeForcedModel does not blanket-force GPT-family models", () => { + assert.strictEqual(isVisionBridgeForcedModel("gpt-5.5"), false); + assert.strictEqual(isVisionBridgeForcedModel("codex/gpt-5.5"), false); + assert.strictEqual(isVisionBridgeForcedModel("openai/gpt-4o-mini"), false); +}); + test("getVisionBridgeConfig returns defaults when no settings provided", () => { const config = getVisionBridgeConfig({});