From d0049858015aa76fccb82a7f216d981b6763b9ab Mon Sep 17 00:00:00 2001 From: Sawyer Cutler Date: Sat, 22 Aug 2026 17:41:09 -0700 Subject: [PATCH] Omit Codex Responses reasoning.summary auto ChatGPT Codex rejects summary "auto" for the gpt-5.6-terra / gpt-5.3-codex family (HTTP 400). Send effort only to match the Codex CLI catalog default_reasoning_summary=none. --- CHANGELOG.md | 9 +++++++++ src/provider/codex-responses-adapter.ts | 5 ++++- tests/unit/codex-responses-adapter.test.ts | 20 +++++++++++++++++++- 3 files changed, 32 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8dbf17187..1529f6cca 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,15 @@ matching `## [X.Y.Z]` section (plus install instructions). Do not maintain parallel copies under `docs/` or `scripts/notes/`. At cut time: rename `## [Unreleased]` to `## [X.Y.Z] - YYYY-MM-DD`, then run the release script. +## [Unreleased] + +### Fixed + +- **Codex Responses no longer sends `reasoning.summary: "auto"`.** ChatGPT + Codex rejects that value for gpt-5.6-terra / gpt-5.3-codex family models + (HTTP 400 at turn 0). The adapter now sends `{ effort }` only, matching + Codex CLI catalog `default_reasoning_summary=none` (CL-6893). + ## [0.2.103] - 2026-08-23 ### TUI diff --git a/src/provider/codex-responses-adapter.ts b/src/provider/codex-responses-adapter.ts index aa50b0832..4440dcca2 100644 --- a/src/provider/codex-responses-adapter.ts +++ b/src/provider/codex-responses-adapter.ts @@ -297,9 +297,12 @@ function buildRequest( } // reasoning_effort rides in providerOptions (same place the OpenAI-compatible // path reads it); map it onto the Responses `reasoning.effort` field. + // ChatGPT Codex rejects summary:"auto" for gpt-5.6-terra / gpt-5.3-codex + // family (HTTP 400; supported: concise | detailed | none). Codex CLI catalog + // default_reasoning_summary is none — send effort only (CL-6893). const effort = options.providerOptions?.["reasoning_effort"]; if (typeof effort === "string" && effort !== "none") { - body["reasoning"] = { effort, summary: "auto" }; + body["reasoning"] = { effort }; } if (sessionId !== undefined) body["prompt_cache_key"] = sessionId; diff --git a/tests/unit/codex-responses-adapter.test.ts b/tests/unit/codex-responses-adapter.test.ts index 2e9073812..12c54f918 100644 --- a/tests/unit/codex-responses-adapter.test.ts +++ b/tests/unit/codex-responses-adapter.test.ts @@ -103,9 +103,27 @@ describe("codex-responses buildRequest", () => { test("maps reasoning_effort to the Responses reasoning config", () => { const options: InferenceOptions = { providerOptions: { ...baseOptions.providerOptions, reasoning_effort: "high" } }; const body = JSON.parse(adapter().buildRequest([userTurn("x")], "gpt-5-codex", options).body) as Record; - expect(body["reasoning"]).toEqual({ effort: "high", summary: "auto" }); + expect(body["reasoning"]).toEqual({ effort: "high" }); }); + // CL-6893: ChatGPT Codex rejects reasoning.summary "auto" for the gpt-5.6-terra / + // gpt-5.3-codex family (HTTP 400). Codex CLI catalog default is none — omit summary + // (effort only) so Terra/Luna request bodies never send summary:"auto". + test.each(["gpt-5.6-terra", "gpt-5.6-luna"] as const)( + "omits reasoning.summary auto for %s (CL-6893)", + (model) => { + const options: InferenceOptions = { + providerOptions: { ...baseOptions.providerOptions, reasoning_effort: "high" }, + }; + const body = JSON.parse(adapter().buildRequest([userTurn("x")], model, options).body) as Record< + string, + unknown + >; + expect(body["reasoning"]).toEqual({ effort: "high" }); + expect(body["reasoning"]).not.toHaveProperty("summary"); + }, + ); + test("roundtrips encrypted reasoning signature from prior assistant turn into Responses reasoning item", () => { // Prior turn's assistant content included a thinking block with signature. // buildRequest must emit the "reasoning" item (with encrypted_content) before