Repository navigation
[Provider compatibility] Codex Web GPT replay fails after routed Responses request loses current-turn IDs and metadata #6220
Description
Client or integration
Codex CLI
Provider or upstream service
Codex Web GPT (miuuyy/codex-chatgpt-web), local chatgpt-web/* Responses endpoint
OpenCodex version
2.69.0 (Codex Web GPT 6.1.3; Codex CLI 0.158.0; macOS)
Endpoint or capability
/v1/responses, routed openai-responses provider, current-turn browser-session replay
Current behaviour
OpenCodex accepts Codex Web GPT as a custom Responses provider and lists its models, but a live Codex CLI turn through the route fails. The launcher receives the routed request and rejects it with ChatGPT web requires a current-turn user message for browser-session replay. With the same account, model, and prompt, a direct Codex CLI route to the launcher succeeds and replies WEB READY.
I captured only the request structure at the launcher's local /v1/responses endpoint; no message contents, credentials, cookies, or raw request bodies were retained. The direct and routed requests differ as follows:
| Field / structure | Direct Codex -> launcher | Codex -> OpenCodex -> launcher |
|---|---|---|
client_metadata |
present | present |
input[].id |
present on additional_tools (at_...) and developer/user messages (msg_...) |
absent on every remaining input message |
input[].internal_chat_message_metadata_passthrough |
present on developer/user messages | absent |
additional_tools item |
present in input |
converted into top-level tools / instructions |
| input item count in this capture | 5 (additional_tools, 2 developer, 2 user) | 3 (developer, 2 user) |
The current stripItemIdsWhenUnstored path intentionally removes input IDs when store: false, to avoid treating them as references to nonexistent stored items for ordinary Responses upstreams. That rationale makes sense for those upstreams, but the Codex Web GPT launcher needs a different request shape for its browser-session replay. Other request changes were observed, so this comparison does not isolate which single field or combination triggers the rejection.
Expected behaviour
A model routed to Codex Web GPT through OpenCodex should complete the same minimal current-turn request that completes when Codex CLI connects to the launcher directly. A provider-specific compatibility path could preserve the current-turn identity and private metadata required by this upstream, while keeping the existing store: false sanitization for ordinary Responses providers.
Minimal redacted request or reproduction
# 1. Start Codex Web GPT 6.1.3; its local Responses endpoint is
# http://127.0.0.1:17841/v1.
# 2. Register that endpoint in OpenCodex 2.69.0 as a custom
# openai-responses provider named gpt-web and expose
# chatgpt-web/gpt-5.6-sol-instant.
# 3. Confirm the model is listed and resolved to that provider.
# 4. Point Codex CLI 0.158.0 at OpenCodex and run:
codex exec -m gpt-web/chatgpt-web/gpt-5.6-sol-instant 'Reply with exactly: WEB READY'
# 5. Point the same Codex CLI at the launcher directly and run:
codex exec -m chatgpt-web/gpt-5.6-sol-instant 'Reply with exactly: WEB READY'Actual response or error
Via OpenCodex: ChatGPT web requires a current-turn user message for browser-session replay
Direct: WEB READY
Upstream documentation
There is no public specification for Codex Web GPT's private browser-session replay metadata. The direct Codex CLI request that succeeds is the concrete client/upstream contract used here. The launcher project is https://github.com/miuuyy/codex-chatgpt-web. Generic Responses API documentation: https://platform.openai.com/docs/api-reference/responses.
Suggested mapping or implementation notes
The relevant OpenCodex code is src/adapters/openai-responses/request-strips.ts (stripItemIdsWhenUnstored) and its use in the Responses passthrough adapter. Please consider an explicit provider-specific compatibility mode rather than changing ID handling for every store: false upstream. The missing internal_chat_message_metadata_passthrough and additional_tools transformation may also matter; preserving only input[].id has not been independently tested. A focused regression could compare direct and routed current-turn requests and assert successful browser-session replay.
Additional context and attachments
Related but distinct: #938 concerns IDs in Responses output; this report concerns IDs and metadata in the outgoing request. Codex Web GPT issue miuuyy/codex-chatgpt-web#205 requested first-class external-router mode, but does not cover this request-shape failure.
Checks
- I searched existing provider and compatibility issues.
- The request and response were redacted.
- The expected behaviour is based on a concrete client requirement verified by a direct request.
Activity
arikon commentedon Sep 29, 2026
Source-level follow-up for the exact error, checked against Codex Web GPT v6.1.3 and OpenCodex v2.69.0:
extractChatGptTurnUserRevisionthrowsChatGPT web requires a current-turn user message for browser-session replayonly when it cannot find a user revision.userRevisionaccepts a non-contextual user message when it has eitherinternal_chat_message_metadata_passthrough.turn_idorid. It returnsundefinedif both are absent. The top-levelclient_metadatais used separately to obtain the expected turn ID; it is insufficient on its own to mark an input message as the current user revision.stripItemIdsWhenUnstoredalso strips allinput[].idwhenstore: false.client_metadataand user message content remain present. Thus the combined removal of the two alternative provenance fields is sufficient to explain this exact error. Theadditional_toolsrewrite is not part of this check.Restoring either field would satisfy this specific
userRevisionguard in a minimal first turn; it has not been tested as an end-to-end compatibility fix for later turns, tools, or compaction. The existing stripping is intentional for ordinary Responses upstreams, so any change should be scoped to a provider that understands the Codex-private fields.fix(responses): preserve input IDs and private metadata for opted-in …
Ingwannu commentedon Oct 1, 2026
Thank you for isolating the two alternative provenance fields in the follow-up; that is more precise than attributing the exact current-turn rejection to every wire difference. #6254 is the active opt-in proposal. Keep default stripping for ordinary Responses providers; the launcher contract is not permission to retain private fields for every destination. The PR remains draft with independent review/readiness requirements, and acceptance still needs a real launcher current-turn/tool-follow-up result plus unchanged xAI custom-call ID repair. Restoring a field in a fixture is not an end-to-end compatibility claim.
github-actions commentedon Oct 1, 2026
Automated translation bookkeeping — detected language: English.
fix(responses): preserve opted-in launcher replay metadata (carry lid…
lidge-jun commentedon Oct 3, 2026
Closing this issue at the maintainer's request as part of the recovered-train cleanup. The scoped, opt-in input-ID/private-metadata preservation from #6254 was carried into #6487, which is merged into dev.
Final cross-platform CI passed at 7c59baf: https://github.com/lidge-jun/opencodex/actions/runs/37110109894.
Verification limit: no real Codex Web GPT launcher current-turn/tool-follow-up acceptance run was performed. This closure records the landed implementation and the requested issue disposition; it does not claim end-to-end browser-session replay has been verified. This updates the earlier decision to leave the issue open for that acceptance. If the original failure persists with the opt-in compatibility settings in the updated build, this issue can be reopened with a redacted reproduction.