Skip to content

fix: normalize web_search_preview for codex responses#2223

Open
cnrpman wants to merge 3 commits intorouter-for-me:mainfrom
cnrpman:fix/codex-responses-web-search-preview-compat
Open

fix: normalize web_search_preview for codex responses#2223
cnrpman wants to merge 3 commits intorouter-for-me:mainfrom
cnrpman:fix/codex-responses-web-search-preview-compat

Conversation

@cnrpman
Copy link

@cnrpman cnrpman commented Mar 18, 2026

Summary

Normalize web_search_preview to web_search for Codex Responses requests.

Codex upstream currently rejects web_search_preview with:

curl -sS http://localhost:8317/v1/responses \
  -H 'Authorization: Bearer your-api-key-1' \
  -H 'Content-Type: application/json' \
  -d '{
    "model": "gpt-5.2",
    "input": "帮我查一下 OpenAI 最新模型",
    "tools": [
      { "type": "web_search_preview" }
    ]
  }'
{"detail":"Unsupported tool type: web_search_preview"}%

This change adds a narrow compatibility layer in the Codex OpenAI Responses translator so existing
clients using the older tool type continue to work.

What changed

  • rewrite tools[].type from web_search_preview to web_search
  • rewrite tool_choice.type from web_search_preview to web_search
  • add a regression test covering both fields

Scope

This change is intentionally limited to the Codex Responses translation path and does not affect other
providers or request formats.

Verification

Ran:

go test ./internal/translator/codex/openai/responses

Also verified end-to-end locally by retrying a /v1/responses request that previously failed with
Unsupported tool type: web_search_preview.

Misc

might be related to #1539
but the current PR is a minimal fix towards web_search_preview compatibility

@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello, 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 introduces a compatibility layer within the Codex OpenAI Responses translator. It addresses an issue where the Codex upstream API rejects requests using the web_search_preview tool type. The changes normalize this legacy tool type to web_search, ensuring that existing clients continue to function correctly without encountering 'Unsupported tool type' errors.

Highlights

  • Tool Type Normalization: Rewrote tools[].type from web_search_preview to web_search to ensure compatibility with the Codex upstream API.
  • Tool Choice Normalization: Rewrote tool_choice.type from web_search_preview to web_search for the same compatibility reasons.
  • Regression Test: Added a new regression test to cover the normalization of both tools[].type and tool_choice.type.

🧠 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 Assist

The 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 /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

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 .gemini/ folder in the base of the repository. Detailed instructions can be found here.

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

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

The pull request effectively addresses the issue of normalizing web_search_preview to web_search for Codex Responses, ensuring compatibility with the upstream API. The new normalizeCodexBuiltinTools function is well-implemented and the addition of a dedicated test case provides good coverage for the introduced functionality. The changes are concise and directly target the problem described in the pull request.

for i := 0; i < len(toolArray); i++ {
typePath := fmt.Sprintf("tools.%d.type", i)
if gjson.GetBytes(result, typePath).String() == "web_search_preview" {
result, _ = sjson.SetBytes(result, typePath, "web_search")
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

The sjson.SetBytes function can return an error, which is currently ignored. While the transformation might be expected to always succeed for valid JSON, explicitly handling potential errors (e.g., logging them or returning the original rawJSON if an error occurs) would make the function more robust against unexpected input structures. This could prevent silent failures where the normalization doesn't happen as intended.

result, err := sjson.SetBytes(result, typePath, "web_search")
if err != nil {
	// Log the error or handle it appropriately
	// For now, we proceed with the original result if setting fails
	// log.Printf("Error setting tool type: %v", err)
}

}

if gjson.GetBytes(result, "tool_choice.type").String() == "web_search_preview" {
result, _ = sjson.SetBytes(result, "tool_choice.type", "web_search")
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

Similar to the previous comment, the error returned by sjson.SetBytes here is ignored. Consider adding error handling to ensure that any issues during JSON modification are either logged or gracefully managed.

result, err := sjson.SetBytes(result, "tool_choice.type", "web_search")
if err != nil {
	// Log the error or handle it appropriately
	// For now, we proceed with the original result if setting fails
	// log.Printf("Error setting tool_choice type: %v", err)
}

Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: be2dd60ee7

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment on lines +97 to +98
if gjson.GetBytes(result, typePath).String() == "web_search_preview" {
result, _ = sjson.SetBytes(result, typePath, "web_search")

Choose a reason for hiding this comment

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

P2 Badge Normalize the dated web_search_preview alias too

This comparison only catches the undated literal web_search_preview. OpenAI’s current tool schema/SDKs also emit the dated alias web_search_preview_2025_03_11; when a caller uses that value in tools (or in the identical tool_choice.type check below), the translator forwards it unchanged and Codex will still reject the request as an unsupported tool type. That leaves the new compatibility layer incomplete for one of the valid preview names clients send today.

Useful? React with 👍 / 👎.

Comment on lines +103 to +104
if gjson.GetBytes(result, "tool_choice.type").String() == "web_search_preview" {
result, _ = sjson.SetBytes(result, "tool_choice.type", "web_search")

Choose a reason for hiding this comment

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

P2 Badge Rewrite preview tools nested under tool_choice.allowed_tools

Only the top-level tool_choice.type is normalized here. Responses requests can also force a subset of tools with tool_choice: {"type":"allowed_tools","tools":[...]}; if one of those nested entries is {"type":"web_search_preview"}, it survives translation unchanged because this helper only touches the root tools[] array and tool_choice.type. In that supported tool-choice mode, Codex will continue to fail on the same legacy tool value this patch is trying to make compatible.

Useful? React with 👍 / 👎.

@cnrpman
Copy link
Author

cnrpman commented Mar 18, 2026

all review comments above addressed

Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 793840cdb4

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment on lines +129 to +130
case "web_search_preview", "web_search_preview_2025_03_11":
return "web_search"

Choose a reason for hiding this comment

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

P2 Badge Preserve external_web_access semantics for preview web search

For requests that still use {"type":"web_search_preview"} (or the dated alias) together with external_web_access: false, this rewrite changes behavior instead of just making the request acceptable. OpenAI’s current web-search guide says preview variants ignore external_web_access and behave as if it were true, but after translating only the type field we forward {"type":"web_search","external_web_access":false} to Codex, which disables live web access. Existing preview clients relying on the documented preview behavior will silently start getting cache-only search results.

Useful? React with 👍 / 👎.

Copy link

@xkonjin xkonjin left a comment

Choose a reason for hiding this comment

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

Code Review

Clean, focused PR. The normalization approach is solid. A few observations:

Looks good:

  • Smart placement in the translation pipeline right after convertSystemRoleToDeveloper
  • Covers both tools[] and tool_choice (including nested tool_choice.tools[])
  • Good test coverage with both variants (web_search_preview and web_search_preview_2025_03_11)
  • The helper returning empty string for unknown types is a safe default

Suggestions:

  1. Future-proofing: The normalizeCodexBuiltinToolType switch only handles web_search_preview* variants. Consider a comment noting this is the single known case, so future maintainers know whether to extend it or use a different pattern if more normalizations are needed.

  2. Logging: Consider adding a debug log when normalization fires (e.g. log.Debug("normalized tool type", "from", toolType, "to", "web_search")). This would help diagnose issues if Codex upstream changes behavior again.

  3. Minor: The second test (TestConvertOpenAIResponsesRequestToCodex_NormalizesTopLevelToolChoicePreviewAlias) tests tool_choice.type directly set to web_search_preview_2025_03_11. This is good, but worth verifying whether any real client sends tool_choice.type as a raw tool type vs wrapped in allowed_tools — both are covered now though.

No blocking issues. Approve-worthy once CI passes.

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