From 02c48511649d569c7751d9b86187010dc86eaf3a Mon Sep 17 00:00:00 2001 From: Subash Natarajan Date: Fri, 27 Mar 2026 18:21:09 +0530 Subject: [PATCH] fix: strip orphaned OpenAI reasoning blocks before responses API call Wire downgradeOpenAIReasoningBlocks into the openai-responses stream wrapper alongside the existing function-call pairing sanitizer. This prevents 400 errors when conversation history contains reasoning items without their required following content block (e.g. after compaction, error recovery, or session restore). The function already existed and was tested but was only called in the Google provider path, not the OpenAI responses path. Fixes #54534. --- src/agents/pi-embedded-runner/run/attempt.ts | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/agents/pi-embedded-runner/run/attempt.ts b/src/agents/pi-embedded-runner/run/attempt.ts index ea465367a33..49938ba2d6e 100644 --- a/src/agents/pi-embedded-runner/run/attempt.ts +++ b/src/agents/pi-embedded-runner/run/attempt.ts @@ -72,6 +72,7 @@ import { import type { EmbeddedContextFile } from "../../pi-embedded-helpers.js"; import { downgradeOpenAIFunctionCallReasoningPairs, + downgradeOpenAIReasoningBlocks, isCloudCodeAssistFormatError, resolveBootstrapMaxChars, resolveBootstrapPromptTruncationWarningMode, @@ -1367,7 +1368,12 @@ export async function runEmbeddedAttempt( if (!Array.isArray(messages)) { return inner(model, context, options); } - const sanitized = downgradeOpenAIFunctionCallReasoningPairs(messages as AgentMessage[]); + const pairSanitized = downgradeOpenAIFunctionCallReasoningPairs( + messages as AgentMessage[], + ); + // Also strip orphaned reasoning blocks that lack a required following + // content item — OpenAI rejects these with a 400 error. + const sanitized = downgradeOpenAIReasoningBlocks(pairSanitized); if (sanitized === messages) { return inner(model, context, options); }