From b0c2a90e5162e1fba9fe1ecd3ed6cd1cf01852d7 Mon Sep 17 00:00:00 2001 From: David Brailovsky Date: Fri, 17 Jul 2026 10:55:56 +0200 Subject: [PATCH] fix(coding-agent): retry OpenAI Responses early EOF closes #6727 --- packages/ai/CHANGELOG.md | 1 + packages/ai/src/utils/retry.ts | 1 + packages/ai/test/retry.test.ts | 9 +++++++++ packages/coding-agent/CHANGELOG.md | 1 + 4 files changed, 12 insertions(+) diff --git a/packages/ai/CHANGELOG.md b/packages/ai/CHANGELOG.md index 8e516d79..46ce4ed6 100644 --- a/packages/ai/CHANGELOG.md +++ b/packages/ai/CHANGELOG.md @@ -5,6 +5,7 @@ ### Fixed - Fixed Kimi Coding subscription models to report API-equivalent implied costs when models.dev reports zero pricing. +- Fixed OpenAI Responses early stream endings to be classified as retryable provider errors ([#6727](https://github.com/earendil-works/pi/issues/6727)). ## [0.80.10] - 2026-07-16 diff --git a/packages/ai/src/utils/retry.ts b/packages/ai/src/utils/retry.ts index 24e327ad..6332ff55 100644 --- a/packages/ai/src/utils/retry.ts +++ b/packages/ai/src/utils/retry.ts @@ -68,6 +68,7 @@ const RETRYABLE_PROVIDER_ERROR_PATTERN = buildProviderErrorPattern([ // (#4433); Bedrock/Smithy can throw an HTTP/2 no-response error (#3594). "ended without", "stream ended before message_stop", + "stream ended before a terminal response event", "http2 request did not get a response", // Provider-requested retry delay cap failures should flow through the outer diff --git a/packages/ai/test/retry.test.ts b/packages/ai/test/retry.test.ts index 70b0c409..abdc8716 100644 --- a/packages/ai/test/retry.test.ts +++ b/packages/ai/test/retry.test.ts @@ -9,6 +9,7 @@ const bedrockExplicitRetryMessage = const nvidiaNIMResourceExhaustedMessage = "ResourceExhausted: Worker local total request limit reached (288/48)"; const bunFetchSocketClosedMessage = "The socket connection was closed unexpectedly. For more information, pass `verbose: true` in the second argument to fetch()"; +const openAIResponsesEarlyEofMessage = "OpenAI Responses stream ended before a terminal response event"; describe("provider retry classification", () => { it("matches explicit provider retry guidance", () => { @@ -37,6 +38,14 @@ describe("provider retry classification", () => { ).toBe(true); }); + it("matches OpenAI Responses streams that end before terminal events", () => { + expect( + isRetryableAssistantError( + fauxAssistantMessage("", { stopReason: "error", errorMessage: openAIResponsesEarlyEofMessage }), + ), + ).toBe(true); + }); + it("keeps provider limit errors non-retryable", () => { expect( isRetryableAssistantError( diff --git a/packages/coding-agent/CHANGELOG.md b/packages/coding-agent/CHANGELOG.md index f2c0eaf0..4a8ce1c1 100644 --- a/packages/coding-agent/CHANGELOG.md +++ b/packages/coding-agent/CHANGELOG.md @@ -10,6 +10,7 @@ - Fixed obsolete custom UI, custom tool, and custom editor examples in the extension documentation ([#6735](https://github.com/earendil-works/pi/issues/6735)). - Fixed Kimi Coding sessions to show API-equivalent implied costs with the subscription indicator. +- Fixed OpenAI Responses early stream endings to trigger automatic retry instead of ending the agent run ([#6727](https://github.com/earendil-works/pi/issues/6727)). ## [0.80.10] - 2026-07-16