fix(providers): drop image_generation for Codex Spark models regardless of plan (#6651) (#6721)

* fix(providers): drop image_generation for Codex Spark models regardless of plan (#6651)

* chore(6721): re-sync onto release tip; CHANGELOG entry → changelog.d fragment (fragments-first)
This commit is contained in:
Diego Rodrigues de Sa e Souza
2026-07-10 19:38:28 -03:00
committed by GitHub
parent 1834ed366e
commit 8338d6a5e7
3 changed files with 67 additions and 1 deletions

View File

@@ -0,0 +1 @@
- **fix(providers):** Codex Desktop requests to `gpt-5.3-codex-spark` failed with `[400]: Tool 'image_generation' is not supported with gpt-5.3-codex-spark`, even on paid-plan accounts ([#6651](https://github.com/diegosouzapw/OmniRoute/issues/6651)) — `CodexExecutor.transformRequest` (`open-sse/executors/codex.ts`) only dropped the Codex Desktop-injected `image_generation` hosted tool when `isCodexFreePlan()` matched the account's plan, with no awareness that Spark-scope Codex models reject `image_generation` upstream regardless of plan. `dropImageGeneration` now also drops it when `getCodexModelScope(model) === "spark"` (the existing Spark classifier from `open-sse/config/codexQuotaScopes.ts`), independent of account plan. Regression guard: `tests/unit/codex-spark-image-generation.test.ts`.

View File

@@ -1132,7 +1132,11 @@ export class CodexExecutor extends BaseExecutor {
// Cursor may include custom tools (e.g. ApplyPatch) that work locally but are
// invalid upstream, and translation bugs can leave orphaned/empty tool_choice names.
normalizeCodexTools(body, {
dropImageGeneration: isCodexFreePlan(credentials?.providerSpecificData),
// gpt-5.3-codex-spark (and other Spark-scope models) reject image_generation
// upstream even on paid-plan accounts, so drop it independent of plan (#6651).
dropImageGeneration:
isCodexFreePlan(credentials?.providerSpecificData) ||
getCodexModelScope(model) === "spark",
preserveCustomTools: nativeCodexPassthrough,
});

View File

@@ -0,0 +1,61 @@
/**
* #6651 — Codex Desktop injects the `image_generation` hosted tool into every
* Responses API request. OmniRoute only dropped it for free-plan Codex
* accounts (isCodexFreePlan). It did NOT drop it for gpt-5.3-codex-spark (and
* other Spark-scope models), which reject `image_generation` upstream even on
* paid-plan accounts, producing:
* [400]: Tool 'image_generation' is not supported with gpt-5.3-codex-spark.
*
* Fix: CodexExecutor.transformRequest now also drops image_generation when
* the target model resolves to the Spark quota scope
* (getCodexModelScope(model) === "spark"), independent of plan.
*/
import test from "node:test";
import assert from "node:assert/strict";
const { CodexExecutor } = await import("../../open-sse/executors/codex.ts");
function buildBody() {
return {
_nativeCodexPassthrough: true,
tools: [
{ type: "image_generation", output_format: "png" },
{ type: "function", name: "foo", parameters: { type: "object" } },
],
};
}
test("#6651: CodexExecutor.transformRequest drops image_generation for gpt-5.3-codex-spark even on a paid-plan account", () => {
const executor = new CodexExecutor();
// Paid-plan account (not free) — isCodexFreePlan() alone returns false, so
// the fix must rely on the model-scope check to still drop the tool.
const result = executor.transformRequest("gpt-5.3-codex-spark", buildBody(), false, {
providerSpecificData: { workspacePlanType: "team" },
}) as { tools: Array<{ type?: string }> };
assert.equal(
result.tools.some((t) => t.type === "image_generation"),
false,
"image_generation must be dropped for gpt-5.3-codex-spark regardless of account plan (#6651)"
);
assert.equal(
result.tools.some((t) => t.type === "function"),
true,
"the function tool must survive"
);
});
test("#6651: CodexExecutor.transformRequest still preserves image_generation for non-Spark models on paid plans", () => {
const executor = new CodexExecutor();
const result = executor.transformRequest("gpt-5", buildBody(), false, {
providerSpecificData: { workspacePlanType: "team" },
}) as { tools: Array<{ type?: string }> };
assert.equal(
result.tools.some((t) => t.type === "image_generation"),
true,
"image_generation must still be preserved for non-Spark models on paid plans"
);
});