Repository navigation
Fix Codex routing: restore SSE Content-Type and send probes as the account identity - #193
Merged
Merged
Conversation
Since 2026-09-23 the ChatGPT edge no longer sends Content-Type on /backend-api/codex/responses streams (9/9 production-egress requests: no content-type header, body still SSE ending in response.completed with the requested model). readCodexRoutingCompletion and the qualified-route observer only parse SSE when the header says text/event-stream, so every cold acquisition, verification and business observation ended as routing_incomplete and fail_closed locked OAuth accounts out of the gated GPT-6 models. Tool-name mapping and image streaming key on the same header. - Relabel a 200 reply to a POST chatgpt.com/backend-api/codex/responses request that asked for text/event-stream as text/event-stream when the upstream sent no type (Do, DoWithTLS and the connection lease). - Let the routing completion reader recognise an untyped body by its SSE framing, covering the pinned-trust acquisition client as well. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
buildCodexRoutingProbe never set originator or User-Agent, and enforceCodexIdentityHeadersForAccountContext only aligns an originator that is already present, so every acquisition and verification left as Go-http-client/1.1 on a ChatGPT OAuth token. With routing observations working again those probes repeat per enrolled account and model. Set originator, user-agent and version from the account's resolved outbound identity, the same triple the routing scope profile hashes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Content-Typeon/backend-api/codex/responsesSSE replies. A fixed production-egress diagnostic (9 real requests, accounts 16376/16380/16379, astra/sol/luna, Lite and legacy bodies, account and harvest proxies) returned HTTP 200 with nocontent-typeheader, while the body was a normal SSE stream ending inresponse.completedwhoseresponse.modelequals the requested model;__oailb/__cflbwere issued on every reply.readCodexRoutingCompletionand the qualified-route observer only use the SSE parser when the header saystext/event-stream; otherwise theyjson.Unmarshalthe whole stream, fail, and recordrouting_incomplete— exactly the acceptance result (HTTP 200, 780-char turn-state,routing_incomplete). Withfail_closed=truethis keeps OAuth accounts out of the four gated models. Client tool-name mapping and image streaming key on the same header.buildCodexRoutingProbenever setoriginator/User-Agent, andenforceCodexIdentityHeadersForAccountContextonly aligns an originator that is already present, so every acquisition/verification left asGo-http-client/1.1on a ChatGPT OAuth token. Once observations work, these probes repeat per enrolled account and model.Change
repository: after decompression, relabel a 200 reply to aPOST chatgpt.com/backend-api/codex/responsesrequest that asked fortext/event-streamastext/event-streamwhen the upstream sent no type (Do,DoWithTLS, connection lease). Compact (JSON) and every other endpoint are untouched.service: the routing completion reader also recognises an untyped body by its SSE framing (covers the pinned-trust acquisition client, which bypasses the repository).service: routing probes setoriginator,user-agentandversionfrom the account's resolved outbound identity — the same triple the routing scope profile hashes..downstream/gpt6-routing-and-prompts.md: one line recording the upstream behaviour.Tests
Minimal, one per defect:
TestRestoreCodexEventStreamContentType(stream relabelled, compact untouched), one assertion inTestCodexRoutingCompletionRequiresOriginalModelAndDelimitedTerminal(untyped stream verifies), andTestCodexRoutingProbeSpeaksAsAccountIdentity. All pass locally; full verification is left to the required CI checks.🤖 Generated with Claude Code