From be7d5cf58594fa2c6c82c6d8f051c0ef5b479bd0 Mon Sep 17 00:00:00 2001 From: Armin Ronacher Date: Fri, 12 Jun 2026 17:07:50 +0200 Subject: [PATCH] fix(ai): relax Codex SSE header timeout --- packages/ai/CHANGELOG.md | 1 + packages/ai/src/providers/openai-codex-responses.ts | 4 +++- packages/ai/test/openai-codex-stream.test.ts | 12 ++++++++++-- 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/packages/ai/CHANGELOG.md b/packages/ai/CHANGELOG.md index 5af75b1e..93fc9a80 100644 --- a/packages/ai/CHANGELOG.md +++ b/packages/ai/CHANGELOG.md @@ -6,6 +6,7 @@ ### Fixed +- Increased the OpenAI Codex Responses SSE response-header timeout to 20 seconds to reduce false-positive stalls while retaining the bounded wait introduced for zero-event hangs ([#4945](https://github.com/earendil-works/pi/issues/4945)). - Fixed Claude Fable 5 thinking-off requests to omit Anthropic's unsupported `thinking.type: "disabled"` payload ([#5567](https://github.com/earendil-works/pi/pull/5567) by [@tmustier](https://github.com/tmustier)). ## [0.79.1] - 2026-06-09 diff --git a/packages/ai/src/providers/openai-codex-responses.ts b/packages/ai/src/providers/openai-codex-responses.ts index 5836ee1b..7fe9e256 100644 --- a/packages/ai/src/providers/openai-codex-responses.ts +++ b/packages/ai/src/providers/openai-codex-responses.ts @@ -53,7 +53,9 @@ const JWT_CLAIM_PATH = "https://api.openai.com/auth" as const; const DEFAULT_MAX_RETRIES = 0; const BASE_DELAY_MS = 1000; const DEFAULT_MAX_RETRY_DELAY_MS = 60_000; -const DEFAULT_SSE_HEADER_TIMEOUT_MS = 10_000; +// Keep a bounded pre-header timeout so zero-event Codex SSE stalls fail instead of +// leaving callers stuck on "Working..." indefinitely. See #4945. +const DEFAULT_SSE_HEADER_TIMEOUT_MS = 20_000; const DEFAULT_WEBSOCKET_CONNECT_TIMEOUT_MS = 15_000; const CODEX_TOOL_CALL_PROVIDERS = new Set(["openai", "openai-codex", "opencode"]); const WEBSOCKET_MESSAGE_TOO_BIG_CLOSE_CODE = 1009; diff --git a/packages/ai/test/openai-codex-stream.test.ts b/packages/ai/test/openai-codex-stream.test.ts index 9cf0f981..fe4f3ea6 100644 --- a/packages/ai/test/openai-codex-stream.test.ts +++ b/packages/ai/test/openai-codex-stream.test.ts @@ -361,13 +361,21 @@ describe("openai-codex streaming", () => { apiKey: token, transport: "sse", }).result(); + let settled = false; + const observedResultPromise = resultPromise.then((result) => { + settled = true; + return result; + }); await vi.advanceTimersByTimeAsync(0); expect(fetchMock).toHaveBeenCalledTimes(1); await vi.advanceTimersByTimeAsync(10_000); - const result = await resultPromise; + expect(settled).toBe(false); + + await vi.advanceTimersByTimeAsync(10_000); + const result = await observedResultPromise; expect(result.stopReason).toBe("error"); - expect(result.errorMessage).toBe("Codex SSE response headers timed out after 10000ms"); + expect(result.errorMessage).toBe("Codex SSE response headers timed out after 20000ms"); }); it("aborts SSE body reads after response headers arrive", async () => {