Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
5 changes: 4 additions & 1 deletion src/provider/codex-responses-adapter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -321,9 +321,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;

Expand Down
19 changes: 18 additions & 1 deletion tests/unit/codex-responses-adapter.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -132,9 +132,26 @@ describe("codex-responses buildRequest", () => {
const body = JSON.parse(
adapter().buildRequest([userTurn("x")], "gpt-5-codex", options).body,
) as Record<string, unknown>;
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
Expand Down
Loading