Skip to content

Fix ChatGPT Codex requests and post-tool retries - #563

Closed
itkonen wants to merge 1 commit into
editor-code-assistant:masterfrom
itkonen:agent/fix-codex-oauth-retries
Closed

Fix ChatGPT Codex requests and post-tool retries#563
itkonen wants to merge 1 commit into
editor-code-assistant:masterfrom
itkonen:agent/fix-codex-oauth-retries

Conversation

@itkonen

@itkonen itkonen commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

Recently Codex had become practically unusable with constant overload errors. It turned out, the problem was in the way ECA handled Responses API, as the API behaviour had evolved. The constant errors also revealed a gap in how the harness handled errors/retries after tool calls, causing the session to stop on transient errors. This was especially problematic for subagents, which could never finish if such an error occured. This PR should fix all these problems. Initial testing indicates that Codex sessions now run problem free.

Summary

  • Align ChatGPT OAuth requests with the current Codex request identity, routing state, and Responses API request shapes.
  • Add Responses Lite handling and model metadata for GPT-5.6 Sol, Terra, and Luna.
  • Retry replay-safe OpenAI post-tool requests without executing completed tools again.
  • Keep Codex-specific behavior isolated from API-key OpenAI, Copilot, custom Responses providers, and other LLM providers.

Root cause

ECA sent the Codex Originator header without a matching versioned User-Agent. The ChatGPT Codex backend reported this invalid request identity as server_is_overloaded, so retries could not recover.

Requests now use Codex's paired default identity:

  • Originator: codex_cli_rs
  • User-Agent: codex_cli_rs/0.146.0

GPT-5.6 Codex models additionally use the Responses Lite payload shape, stable session and thread identifiers, and x-codex-turn-state continuation. Instructions are sent exactly once: as top-level instructions for regular Responses requests, or as a developer input message for Responses Lite.

Retry behavior

The existing outer retry controller cannot safely restart a turn after a tool has executed. OpenAI Responses continuations can now retry only the failed HTTP request while it remains replay-safe, preserving completed tool results. Duplicate terminal errors from stacked continuation requests are also suppressed.

Provider safety

The Codex request profile is selected only for the built-in openai provider using ChatGPT OAuth. API-key OpenAI, Copilot, custom Responses providers, and other providers retain their existing request formats. Responses Lite moves function tools into additional_tools; regular Responses requests continue to preserve hosted web and image tools.

Validation

  • bb test: 853 tests, 4,734 assertions, 0 failures

  • Focused OpenAI provider tests: 35 tests, 156 assertions, 0 failures

  • Integration tests: 5 tests, 93 assertions, 0 failures

  • Touched-file lint: 0 errors, 0 warnings

  • Full lint: 0 errors; 10 pre-existing protocol warnings

  • bb prod-cli

  • Live ChatGPT OAuth request with the rebuilt executable and gpt-5.6-sol: returned OK, generated a title, exposed function tools, and produced no overload or transport errors

  • I added a entry in changelog under unreleased section.

  • This is not an AI slop.

@itkonen
itkonen marked this pull request as ready for review July 30, 2026 11:45
Comment thread src/eca/models.clj
:reason? (:discovered-reason? model-config)
:api (:discovered-api model-config)
:variants (:discovered-variants model-config)
:codex-responses-lite? (:discovered-codex-responses-lite? model-config)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't like this specific flag for a llm provider, we should have this agnostic like all other keys

Comment thread src/eca/features/chat.clj
(lifecycle/maybe-renew-auth-token chat-ctx)
(get-in @db* [:auth provider]))
:variant (:variant chat-ctx)
:chat-id chat-id

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this really needed? llm-api should be agnostic of chats and ids ideally

@ericdallo

Copy link
Copy Markdown
Member

@itkonen I fixed it in master in a different way to avoid some code coupling + small concerns I had, I think next time is good for us to start with a issue before the PR, but thank you for the problem report and details!
Please let me know if works for you

ericdallo added a commit that referenced this pull request Jul 31, 2026
Co-authored-by: Juha Itkonen <itkonen.juha@gmail.com>
@ericdallo ericdallo closed this Jul 31, 2026
@itkonen

itkonen commented Jul 31, 2026

Copy link
Copy Markdown
Contributor Author

@ericdallo Yes, I agree. This was sort of a hotfix that ended up having a wider impact than I would have liked. The Codex OAuth provider had essentially stopped working in ECA, and I needed a solution fast. The were multiple design choices that would have merited discussion, if it weren't for the urgency.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants