From 46bf210e048a6ad7a7bddb6b97f6ee91191545eb Mon Sep 17 00:00:00 2001 From: Ty Sabs Date: Mon, 16 Feb 2026 16:40:17 -0600 Subject: [PATCH] fix: always drop orphaned OpenAI reasoning blocks in session history downgradeOpenAIReasoningBlocks was only called on model change, but orphaned reasoning items (e.g. from an aborted stream) can exist without a model switch and cause a 400 from the OpenAI Responses API. Co-Authored-By: Claude Opus 4.6 --- .../pi-embedded-runner.sanitize-session-history.test.ts | 4 ++-- src/agents/pi-embedded-runner/google.ts | 7 +++---- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/src/agents/pi-embedded-runner.sanitize-session-history.test.ts b/src/agents/pi-embedded-runner.sanitize-session-history.test.ts index de10ae674..97358da85 100644 --- a/src/agents/pi-embedded-runner.sanitize-session-history.test.ts +++ b/src/agents/pi-embedded-runner.sanitize-session-history.test.ts @@ -204,7 +204,7 @@ describe("sanitizeSessionHistory", () => { expect(result.map((msg) => msg.role)).toEqual(["user"]); }); - it("does not downgrade openai reasoning when the model has not changed", async () => { + it("downgrades orphaned openai reasoning even when the model has not changed", async () => { const sessionEntries = [ makeModelSnapshotEntry({ provider: "openai", @@ -222,7 +222,7 @@ describe("sanitizeSessionHistory", () => { sessionManager, }); - expect(result).toEqual(messages); + expect(result).toEqual([]); }); it("downgrades openai reasoning only when the model changes", async () => { diff --git a/src/agents/pi-embedded-runner/google.ts b/src/agents/pi-embedded-runner/google.ts index 868db5983..0293cd5d2 100644 --- a/src/agents/pi-embedded-runner/google.ts +++ b/src/agents/pi-embedded-runner/google.ts @@ -457,10 +457,9 @@ export async function sanitizeSessionHistory(params: { modelId: params.modelId, }) : false; - const sanitizedOpenAI = - isOpenAIResponsesApi && modelChanged - ? downgradeOpenAIReasoningBlocks(sanitizedToolResults) - : sanitizedToolResults; + const sanitizedOpenAI = isOpenAIResponsesApi + ? downgradeOpenAIReasoningBlocks(sanitizedToolResults) + : sanitizedToolResults; if (hasSnapshot && (!priorSnapshot || modelChanged)) { appendModelSnapshot(params.sessionManager, {