Skip to content

feat(proxy): add tool schema rectifier for non-OpenAI provider compatibility#1810

Open
wejack639 wants to merge 2 commits into
farion1231:mainfrom
wejack639:fix/tool-schema-rectifier
Open

feat(proxy): add tool schema rectifier for non-OpenAI provider compatibility#1810
wejack639 wants to merge 2 commits into
farion1231:mainfrom
wejack639:fix/tool-schema-rectifier

Conversation

@wejack639
Copy link
Copy Markdown

Problem

When using Codex CLI (v0.117+) with CC Switch proxying to DashScope/Bailian, requests fail with:

InvalidParameter: The parameters, when provided as a dict, must confirm to a valid openai-compatible JSON schema

Root Cause

Codex CLI sends ~188 tools via the OpenAI Responses API. Two patterns are incompatible with DashScope and similar providers:

  1. Non-function tool types (e.g. web_search, code_interpreter) - these are OpenAI-specific built-in tools that third-party providers don't recognize
  2. Missing required field in tool parameters - DashScope requires this field to be present even when empty ([]), but ~48 of Codex's tools omit it (all-optional-param tools)

Solution

Add a Tool Schema Rectifier that runs in the proxy forward() pipeline (after filter_private_params_with_whitelist):

  • Filter out tools where type != "function"
  • Patch "required": [] into any tool parameters missing the field

This follows the same pattern as existing rectifiers (thinking_rectifier, thinking_budget_rectifier).

Testing

  • 9 unit tests covering: no tools, empty tools, web_search removal, code_interpreter removal, missing required patch, existing required skip, combined rectification, no-params tools, non-object params
  • All tests pass: cargo test -- tool_schema_rectifier
  • Manually verified: Codex CLI codex exec 'say hello' works through CC Switch -> DashScope after this fix

Files Changed

File Change
src-tauri/src/proxy/tool_schema_rectifier.rs New - rectifier implementation + 9 tests
src-tauri/src/proxy/mod.rs Register new module
src-tauri/src/proxy/forwarder.rs Call rectifier in forward() pipeline

…ibility

Fix Codex CLI (Responses API) failing with DashScope/Bailian and similar
providers due to two incompatible tool schema patterns:

1. Non-function tool types (e.g. web_search, code_interpreter) that are
   OpenAI-specific built-in tools - now filtered out before forwarding
2. Missing 'required' field in tool parameters - some providers (notably
   DashScope) require this field even when empty - now auto-patched

Root cause: Codex CLI v0.117+ sends ~188 tools via Responses API, of which
~48 have no 'required' field and 1 is a 'web_search' type. This causes
DashScope to return InvalidParameter errors.

Includes 9 unit tests covering all edge cases.
@farion1231
Copy link
Copy Markdown
Owner

@codex review

Copy link
Copy Markdown

@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: 66595235e5

ℹ️ About Codex in GitHub

Your team has set up Codex to 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 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src-tauri/src/proxy/forwarder.rs Outdated
Comment on lines +831 to +832
let tool_rectify_result =
super::tool_schema_rectifier::rectify_tool_schema(&mut filtered_body);
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Gate tool schema rectifier to non-OpenAI providers

This rectifier is invoked for every forwarded request, so OpenAI-hosted tool types are removed even when the upstream provider actually supports them. Because rectify_tool_schema drops any tool whose type is not "function", requests that intentionally use built-ins like web_search/code_interpreter will silently lose those capabilities when routed through providers that should accept them. The rectification should be conditional on provider/API-format compatibility constraints (for example, DashScope-like targets) instead of global.

Useful? React with 👍 / 👎.

Comment on lines +41 to +44
tools.retain(|tool| {
let tool_type = tool.get("type").and_then(|v| v.as_str()).unwrap_or("");
tool_type == "function"
});
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Preserve typeless Anthropic tools during schema filtering

The filter keeps only tools with type == "function", which deletes valid Anthropic-style tool definitions that do not carry a type field (name + input_schema). In this codebase, Anthropic tools are explicitly represented in that typeless shape (for example in providers/transform.rs tests), so forwarding default anthropic requests through this logic strips all tools and breaks tool calling. Restrict this pruning to OpenAI/Responses-shaped requests or detect Anthropic schema before filtering.

Useful? React with 👍 / 👎.

…and preserve typeless tools

Address Codex Review P1 feedback on PR farion1231#1810:

1. Gate rectifier to Codex adapter + non-OpenAI providers only:
   - Only apply tool schema rectification when adapter is Codex and
     base_url is not api.openai.com
   - OpenAI natively supports web_search/code_interpreter built-in tools
   - Claude/Gemini adapters use their own formats, not applicable

2. Preserve Anthropic-style typeless tools:
   - Tools without a 'type' field (using name + input_schema) are now
     retained instead of being incorrectly filtered out
   - Only tools with an explicit non-function type are removed

3. Add 2 new unit tests:
   - test_preserve_anthropic_typeless_tools: verify Anthropic tools survive
   - test_mixed_openai_and_typeless_tools: mixed format scenario
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