From 097226b61707ec0e0ddf216da33826e702c07c75 Mon Sep 17 00:00:00 2001 From: Bl0ck <36800583+Bl0ck154@users.noreply.github.com> Date: Sun, 30 Aug 2026 11:09:48 +0300 Subject: [PATCH] fix(codex): normalize non-stream responses (#11951) Boarded with #11954/#11953/#11952/#11948 in one combined worktree: typecheck:core, check:file-size, check:changelog-integrity, check:complexity, check:cognitive-complexity, check:cycles all green; 85/85 focused tests pass. Confirmed the codex registry entry was missing forceStream: true while every other JSON-only-client provider (cline, clinepass, ghe-copilot, kimi, zed-hosted, chatgpt-web-codex) already has it. Clean reuse of the existing bridge, no Codex-specific response handling needed. Thanks! --- .../config/providers/registry/codex/index.ts | 3 +++ tests/unit/cline-force-stream.test.ts | 16 +++++++++++----- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/open-sse/config/providers/registry/codex/index.ts b/open-sse/config/providers/registry/codex/index.ts index 6b67797fa3..a70549f7c1 100644 --- a/open-sse/config/providers/registry/codex/index.ts +++ b/open-sse/config/providers/registry/codex/index.ts @@ -11,6 +11,9 @@ export const codexProvider: RegistryEntry = { alias: "cx", format: "openai-responses", executor: "codex", + // Codex /responses is upstream-streaming even when the client requested stream:false. + // Mark it forceStream so chatCore drains terminal SSE into JSON instead of waiting for EOF. + forceStream: true, baseUrl: "https://chatgpt.com/backend-api/codex/responses", reasoningTransport: "opaque", authType: "oauth", diff --git a/tests/unit/cline-force-stream.test.ts b/tests/unit/cline-force-stream.test.ts index 2c8ea5caaf..e4035ec218 100644 --- a/tests/unit/cline-force-stream.test.ts +++ b/tests/unit/cline-force-stream.test.ts @@ -22,14 +22,20 @@ test("clinepass provider is flagged forceStream (streaming-only upstream)", () = assert.equal(REGISTRY.clinepass?.forceStream, true); }); +test("codex provider is flagged forceStream because /responses always streams upstream", () => { + assert.equal(REGISTRY.codex?.forceStream, true); +}); + test("upstreamStream is forced true for a forceStream provider even when the client sent stream:false", () => { // Mirror the chatCore wiring: providerRequiresStreaming derives from the // registry flag, and upstreamStream ORs it in so the upstream always streams. - const providerRequiresStreaming = REGISTRY.cline?.forceStream === true; - const isClaudeCodeCompatible = false; - const clientStream = false; // client asked for JSON - const upstreamStream = clientStream || isClaudeCodeCompatible || providerRequiresStreaming; - assert.equal(upstreamStream, true); + for (const provider of ["cline", "codex"] as const) { + const providerRequiresStreaming = REGISTRY[provider]?.forceStream === true; + const isClaudeCodeCompatible = false; + const clientStream = false; // client asked for JSON + const upstreamStream = clientStream || isClaudeCodeCompatible || providerRequiresStreaming; + assert.equal(upstreamStream, true, provider); + } }); test("client-facing stream stays false for a stream:false JSON caller (so SSE→JSON conversion runs)", () => {