fix(codex): strip stream_options from Responses API requests#2347
fix(codex): strip stream_options from Responses API requests#2347luispater merged 1 commit intorouter-for-me:devfrom
Conversation
The Codex/OpenAI Responses API does not support the stream_options
parameter. When clients (e.g. Amp CLI) include stream_options in their
requests, CLIProxyAPI forwards it as-is, causing a 400 error:
{"detail":"Unsupported parameter: stream_options"}
Strip stream_options alongside the other unsupported parameters
(previous_response_id, prompt_cache_retention, safety_identifier)
in Execute, ExecuteStream, and CountTokens.
Summary of ChangesHello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request resolves a critical issue where requests to the Codex/OpenAI Responses API were failing due to the inclusion of an unsupported Highlights
🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console. Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here. Footnotes
|
There was a problem hiding this comment.
Code Review
This pull request modifies codex_executor.go to consistently delete the stream_options field from the request body in the Execute, ExecuteStream, and CountTokens functions. The review comments highlight that the parameter deletion logic is duplicated across these functions and suggest refactoring it into a loop, potentially using a package-level variable, to improve code maintainability and reduce redundancy.
| body, _ = sjson.DeleteBytes(body, "previous_response_id") | ||
| body, _ = sjson.DeleteBytes(body, "prompt_cache_retention") | ||
| body, _ = sjson.DeleteBytes(body, "safety_identifier") | ||
| body, _ = sjson.DeleteBytes(body, "stream_options") |
There was a problem hiding this comment.
This block of parameter deletions is duplicated in ExecuteStream and CountTokens. To improve maintainability, consider refactoring this into a loop over a slice of parameter names. For even better maintainability, this slice could be defined as a package-level variable to be shared across all three functions.
| body, _ = sjson.DeleteBytes(body, "previous_response_id") | |
| body, _ = sjson.DeleteBytes(body, "prompt_cache_retention") | |
| body, _ = sjson.DeleteBytes(body, "safety_identifier") | |
| body, _ = sjson.DeleteBytes(body, "stream_options") | |
| for _, param := range []string{ | |
| "previous_response_id", | |
| "prompt_cache_retention", | |
| "safety_identifier", | |
| "stream_options", | |
| } { | |
| body, _ = sjson.DeleteBytes(body, param) | |
| } |
| body, _ = sjson.DeleteBytes(body, "previous_response_id") | ||
| body, _ = sjson.DeleteBytes(body, "prompt_cache_retention") | ||
| body, _ = sjson.DeleteBytes(body, "safety_identifier") | ||
| body, _ = sjson.DeleteBytes(body, "stream_options") |
There was a problem hiding this comment.
This block of parameter deletions is duplicated from Execute and also present in CountTokens. To improve maintainability, consider refactoring this into a loop over a slice of parameter names. For even better maintainability, this slice could be defined as a package-level variable to be shared across all three functions.
| body, _ = sjson.DeleteBytes(body, "previous_response_id") | |
| body, _ = sjson.DeleteBytes(body, "prompt_cache_retention") | |
| body, _ = sjson.DeleteBytes(body, "safety_identifier") | |
| body, _ = sjson.DeleteBytes(body, "stream_options") | |
| for _, param := range []string{ | |
| "previous_response_id", | |
| "prompt_cache_retention", | |
| "safety_identifier", | |
| "stream_options", | |
| } { | |
| body, _ = sjson.DeleteBytes(body, param) | |
| } |
| body, _ = sjson.DeleteBytes(body, "previous_response_id") | ||
| body, _ = sjson.DeleteBytes(body, "prompt_cache_retention") | ||
| body, _ = sjson.DeleteBytes(body, "safety_identifier") | ||
| body, _ = sjson.DeleteBytes(body, "stream_options") |
There was a problem hiding this comment.
This block of parameter deletions is duplicated from Execute and ExecuteStream. To improve maintainability, consider refactoring this into a loop over a slice of parameter names. For even better maintainability, this slice could be defined as a package-level variable to be shared across all three functions.
| body, _ = sjson.DeleteBytes(body, "previous_response_id") | |
| body, _ = sjson.DeleteBytes(body, "prompt_cache_retention") | |
| body, _ = sjson.DeleteBytes(body, "safety_identifier") | |
| body, _ = sjson.DeleteBytes(body, "stream_options") | |
| for _, param := range []string{ | |
| "previous_response_id", | |
| "prompt_cache_retention", | |
| "safety_identifier", | |
| "stream_options", | |
| } { | |
| body, _ = sjson.DeleteBytes(body, param) | |
| } |
luispater
left a comment
There was a problem hiding this comment.
Summary:
This PR fixes a real compatibility issue by stripping stream_options before forwarding requests to the Codex Responses API. The change is minimal, targeted, and consistent with existing payload sanitization logic.
Key findings:
- Blocking: None.
- Non-blocking: Please consider adding a regression test that asserts
stream_optionsis removed across non-streaming, streaming, and token-count paths.
Test plan:
- Reviewed PR metadata, diff, and checks.
- Verified the change is applied in all three intended request-building paths.
Recommendation:
Approve.
This is an automated Codex review result and still requires manual verification by a human reviewer.
Problem
The Codex/OpenAI Responses API does not support the
stream_optionsparameter. When clients such as Amp CLI includestream_optionsin their requests, CLIProxyAPI forwards it verbatim to the upstream/responsesendpoint, resulting in a 400 error:{"detail":"Unsupported parameter: stream_options"}Both OAuth accounts are tried and both fail, so the request is never fulfilled.
Log evidence:
Fix
Strip
stream_optionsfrom the request body before forwarding to the Codex Responses API, consistent with howprevious_response_id,prompt_cache_retention, andsafety_identifierare already stripped.Applied in all three code paths:
Execute(non-streaming fetch)ExecuteStream(streaming)CountTokens(token counting)Testing
go build ./internal/runtime/executor/).sjson.DeleteBytescall per method, following the identical pattern used for the adjacent parameter deletions.