From 201bf85ce965720a011167e4287ab8e168dc04b4 Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Tue, 21 Apr 2026 03:46:26 +0100 Subject: [PATCH] test: expand codex image fallback coverage (#65061) (thanks @zhulijin1991) --- CHANGELOG.md | 1 + .../run-attempt.vision-tools.test.ts | 28 ++++++++++++++----- .../model-fallback.image-provider.test.ts | 22 +++++++++++++++ 3 files changed, 44 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6fc15818e0d..641eac3b90f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,7 @@ Docs: https://docs.openclaw.ai ### Fixes - Setup/TUI: relaunch the setup hatch TUI in a fresh process while preserving the configured gateway target and auth source, so onboarding recovers terminal state cleanly without exposing gateway secrets on command-line args. (#69524) Thanks @shakkernerd. +- Codex: avoid re-exposing the image-generation tool on native vision turns with inbound images, and keep bare image-model overrides on the configured image provider. (#65061) Thanks @zhulijin1991. - Sessions/reset: clear auto-sourced model, provider, and auth-profile overrides on `/new` and `/reset` while preserving explicit user selections, so channel sessions stop staying pinned to runtime fallback choices. (#69419) Thanks @sk7n4k3d. - Sessions/costs: snapshot `estimatedCostUsd` like token counters so repeated persist paths no longer compound the same run cost by up to dozens of times. (#69403) Thanks @MrMiaigi. - OpenAI Codex: route ChatGPT/Codex OAuth Responses requests through the `/backend-api/codex` endpoint so `openai-codex/gpt-5.4` no longer hits the removed `/backend-api/responses` alias. (#69336) Thanks @mzogithub. diff --git a/extensions/codex/src/app-server/run-attempt.vision-tools.test.ts b/extensions/codex/src/app-server/run-attempt.vision-tools.test.ts index 8c3e9fc5eb9..8f3c1240aff 100644 --- a/extensions/codex/src/app-server/run-attempt.vision-tools.test.ts +++ b/extensions/codex/src/app-server/run-attempt.vision-tools.test.ts @@ -4,17 +4,31 @@ import { __testing } from "./run-attempt.js"; describe("Codex dynamic tool filtering", () => { it("drops the image tool when the model already has inbound vision input", () => { const toolNames = __testing - .filterToolsForVisionInputs( - [{ name: "image" }, { name: "read" }, { name: "write" }], - { - modelHasVision: true, - hasInboundImages: true, - }, - ) + .filterToolsForVisionInputs([{ name: "image" }, { name: "read" }, { name: "write" }], { + modelHasVision: true, + hasInboundImages: true, + }) .map((tool) => tool.name); expect(toolNames).toContain("read"); expect(toolNames).toContain("write"); expect(toolNames).not.toContain("image"); }); + + it("keeps the image tool unless both model vision and inbound images are present", () => { + const tools = [{ name: "image" }, { name: "read" }]; + + expect( + __testing.filterToolsForVisionInputs(tools, { + modelHasVision: false, + hasInboundImages: true, + }), + ).toBe(tools); + expect( + __testing.filterToolsForVisionInputs(tools, { + modelHasVision: true, + hasInboundImages: false, + }), + ).toBe(tools); + }); }); diff --git a/src/agents/model-fallback.image-provider.test.ts b/src/agents/model-fallback.image-provider.test.ts index 4a9c3af9c8c..9155d41b8c4 100644 --- a/src/agents/model-fallback.image-provider.test.ts +++ b/src/agents/model-fallback.image-provider.test.ts @@ -25,4 +25,26 @@ describe("runWithImageModelFallback provider resolution", () => { expect(result.result).toBe("ok"); expect(run.mock.calls).toEqual([["openai-codex", "gpt-5.4-mini"]]); }); + + it("keeps a fully qualified override provider over the configured default", async () => { + const cfg = makeModelFallbackCfg({ + agents: { + defaults: { + imageModel: { + primary: "openai-codex/gpt-5.4", + }, + }, + }, + }); + const run = vi.fn().mockResolvedValueOnce("ok"); + + const result = await runWithImageModelFallback({ + cfg, + modelOverride: "google/gemini-3-pro-image", + run, + }); + + expect(result.result).toBe("ok"); + expect(run.mock.calls).toEqual([["google", "gemini-3-pro-image"]]); + }); });