fix(codex): request reasoning summaries (#4359)

Adds reasoning.summary=auto + reasoning.encrypted_content include for Codex. Thanks @xz-dev.
This commit is contained in:
Xiangzhe
2026-06-20 21:51:08 +08:00
committed by GitHub
parent fe70c4c5ad
commit 08a6795083
2 changed files with 33 additions and 10 deletions

View File

@@ -618,6 +618,9 @@ function clampEffort(model: string, requested: string): string {
return requested;
}
const CODEX_REASONING_ENCRYPTED_CONTENT_INCLUDE = "reasoning.encrypted_content";
const CODEX_DEFAULT_REASONING_SUMMARY = "auto";
function normalizeEffortValue(value: unknown): string | undefined {
if (typeof value !== "string") return undefined;
const normalized = value.trim().toLowerCase();
@@ -625,6 +628,27 @@ function normalizeEffortValue(value: unknown): string | undefined {
return normalized || undefined;
}
function ensureCodexReasoningSummary(body: Record<string, unknown>): void {
const reasoning =
body.reasoning && typeof body.reasoning === "object" && !Array.isArray(body.reasoning)
? (body.reasoning as Record<string, unknown>)
: null;
if (!reasoning || normalizeEffortValue(reasoning.effort) === "none") return;
if (!("summary" in reasoning)) {
reasoning.summary = CODEX_DEFAULT_REASONING_SUMMARY;
}
if (!Array.isArray(body.include)) {
body.include = [CODEX_REASONING_ENCRYPTED_CONTENT_INCLUDE];
return;
}
if (!body.include.includes(CODEX_REASONING_ENCRYPTED_CONTENT_INCLUDE)) {
body.include = [...body.include, CODEX_REASONING_ENCRYPTED_CONTENT_INCLUDE];
}
}
function consumeResponsesStoreMarker(body: Record<string, unknown>): unknown {
const marker = body._omnirouteResponsesStore;
delete body._omnirouteResponsesStore;
@@ -1321,6 +1345,7 @@ export class CodexExecutor extends BaseExecutor {
effort: clampEffort(cleanModel, rawEffort),
};
}
ensureCodexReasoningSummary(body);
delete body.reasoning_effort;
// Remove unsupported token limit parameters BEFORE the passthrough return.

View File

@@ -242,10 +242,10 @@ test("CodexExecutor.transformRequest injects default instructions, clamps reason
requestEndpointPath: "/responses",
});
assert.equal(result.stream, true);
assert.equal(result.store, false);
assert.deepEqual([result.stream, result.store], [true, false]);
assert.equal(result.instructions.length > 0, true);
assert.equal(result.reasoning.effort, "high");
assert.deepEqual(result.reasoning, { effort: "high", summary: "auto" });
assert.deepEqual(result.include, ["reasoning.encrypted_content"]);
assert.equal(result.service_tier, "priority");
assert.equal(result.messages, undefined);
assert.equal(result.prompt, undefined);
@@ -736,7 +736,7 @@ test("CodexExecutor.transformRequest keeps explicit request values ahead of conn
}
);
assert.equal(result.reasoning.effort, "none");
assert.deepEqual([result.reasoning, result.include], [{ effort: "none" }, undefined]);
assert.equal(result.service_tier, "standard");
});
@@ -806,7 +806,8 @@ test("CodexExecutor.transformRequest passes GPT 5.4 Mini xhigh reasoning through
{
model: "gpt-5.4-mini",
input: [],
reasoning: { effort: "xhigh", summary: "auto" },
reasoning: { effort: "xhigh", summary: "detailed" },
include: ["code_interpreter_call.outputs"],
},
true,
{
@@ -822,11 +823,8 @@ test("CodexExecutor.transformRequest passes GPT 5.4 Mini xhigh reasoning through
const reasoning = getRecord(sanitized.reasoning);
assert.equal(sanitized.model, "gpt-5.4-mini");
// #3756: xhigh now passes through by default. gpt-5.4-mini has no
// supportsXHighEffort:false flag (and ships a gpt-5.4-mini-xhigh catalog
// variant), so the effort is preserved instead of downgraded to "high".
assert.equal(reasoning.effort, "xhigh");
assert.equal(reasoning.summary, "auto");
assert.deepEqual(reasoning, { effort: "xhigh", summary: "detailed" });
assert.deepEqual(sanitized.include, ["code_interpreter_call.outputs", "reasoning.encrypted_content"]);
assert.equal(sanitized.reasoning_effort, undefined);
});