diff --git a/packages/ai/CHANGELOG.md b/packages/ai/CHANGELOG.md index 34d51f42b..28950dd62 100644 --- a/packages/ai/CHANGELOG.md +++ b/packages/ai/CHANGELOG.md @@ -2,6 +2,10 @@ ## [Unreleased] +### Changed + +- Default reasoning context to `all_turns` for all Codex requests + ## [16.2.2] - 2026-06-27 ### Added diff --git a/packages/ai/src/providers/openai-codex-responses.ts b/packages/ai/src/providers/openai-codex-responses.ts index fd7c42472..db61ee383 100644 --- a/packages/ai/src/providers/openai-codex-responses.ts +++ b/packages/ai/src/providers/openai-codex-responses.ts @@ -104,7 +104,7 @@ import { transformMessages } from "./transform-messages"; export interface OpenAICodexResponsesOptions extends StreamOptions { reasoning?: "none" | "minimal" | "low" | "medium" | "high" | "xhigh"; reasoningSummary?: "auto" | "concise" | "detailed" | null; - /** `reasoning.context` replay scope. Defaults to `all_turns` under {@link OpenAICodexResponsesOptions.responsesLite}, otherwise omitted (server default is `current_turn`). */ + /** `reasoning.context` replay scope; defaults to `all_turns` for every Codex request when unset. */ reasoningContext?: CodexReasoningContext; textVerbosity?: "low" | "medium" | "high"; include?: string[]; @@ -117,7 +117,7 @@ export interface OpenAICodexResponsesOptions extends StreamOptions { * `x-openai-internal-codex-responses-lite: true` on HTTP requests and on the * WebSocket upgrade (the marker is connection-scoped there, so lite and * non-lite turns never share a pooled socket), strips image detail from - * input, and defaults `reasoning.context` to `all_turns` — mirroring codex-rs. + * input, and disables parallel tool calling — mirroring codex-rs. */ responsesLite?: boolean; /** diff --git a/packages/ai/src/providers/openai-codex/request-transformer.ts b/packages/ai/src/providers/openai-codex/request-transformer.ts index 25ee1099d..b627fcbfa 100644 --- a/packages/ai/src/providers/openai-codex/request-transformer.ts +++ b/packages/ai/src/providers/openai-codex/request-transformer.ts @@ -14,11 +14,11 @@ export interface ReasoningConfig { export interface CodexRequestOptions { reasoningEffort?: ReasoningConfig["effort"]; reasoningSummary?: ReasoningConfig["summary"] | null; - /** Explicit `reasoning.context` override. Defaults to `all_turns` under {@link CodexRequestOptions.responsesLite}, otherwise omitted (server default is `current_turn`). */ + /** Explicit `reasoning.context` override; defaults to `all_turns` for every Codex request when unset. */ reasoningContext?: CodexReasoningContext; textVerbosity?: "low" | "medium" | "high"; include?: string[]; - /** Responses Lite transport contract: strips image detail and defaults `reasoning.context` to `all_turns`, mirroring codex-rs. */ + /** Responses Lite transport contract: strips image detail and disables parallel tool calling, mirroring codex-rs. */ responsesLite?: boolean; } @@ -254,13 +254,9 @@ export async function transformRequestBody( ...body.reasoning, ...reasoningConfig, }; - // Responses Lite keeps reasoning replay server-side; codex-rs requests - // `all_turns` there and otherwise omits context so the server default - // (currently `current_turn`) applies. - const reasoningContext = options.reasoningContext ?? "all_turns"; - if (reasoningContext !== undefined) { - body.reasoning.context = reasoningContext; - } + // Default reasoning replay to `all_turns` for every Codex request, + // mirroring codex-rs; an explicit `reasoningContext` overrides it. + body.reasoning.context = options.reasoningContext ?? "all_turns"; } else { delete body.reasoning; } diff --git a/packages/ai/test/openai-codex-responses-lite.test.ts b/packages/ai/test/openai-codex-responses-lite.test.ts index e8f6864e6..575c3cdd3 100644 --- a/packages/ai/test/openai-codex-responses-lite.test.ts +++ b/packages/ai/test/openai-codex-responses-lite.test.ts @@ -83,7 +83,7 @@ function createCodexFetchMock(sse: string, onRequest: (captured: CapturedCodexRe } describe("openai-codex reasoning.context", () => { - it("forwards an explicit reasoning.context and omits it by default", async () => { + it("forwards an explicit reasoning.context and defaults to all_turns", async () => { const model = createCodexModel("gpt-5.1-codex"); const explicit = await transformRequestBody({ model: model.id }, model, { @@ -92,8 +92,8 @@ describe("openai-codex reasoning.context", () => { }); expect(explicit.reasoning?.context).toBe("current_turn"); - const omitted = await transformRequestBody({ model: model.id }, model, { reasoningEffort: "medium" }); - expect(omitted.reasoning?.context).toBeUndefined(); + const defaulted = await transformRequestBody({ model: model.id }, model, { reasoningEffort: "medium" }); + expect(defaulted.reasoning?.context).toBe("all_turns"); }); it("defaults reasoning.context to all_turns under Responses Lite unless overridden", async () => {