Skip to content

fix(responses): tolerate unsupported Codex tools - #625

Merged
SantiagoDePolonia merged 5 commits into
mainfrom
fix/codex-namespace-tools
Aug 1, 2026
Merged

fix(responses): tolerate unsupported Codex tools#625
SantiagoDePolonia merged 5 commits into
mainfrom
fix/codex-namespace-tools

Conversation

@SantiagoDePolonia

@SantiagoDePolonia SantiagoDePolonia commented Jul 31, 2026

Copy link
Copy Markdown
Contributor

Summary

  • accept Responses-only tools such as namespace and web_search on chat-translated providers
  • omit unsupported tools at the Responses-to-Chat boundary while preserving ordinary function tools and tool-call identity
  • omit incompatible tool_choice and parallel_tool_calls when every declared tool is filtered
  • document that this is graceful capability degradation, not hosted-tool emulation

Why

Codex 0.146.0 advertises ordinary function tools together with namespace groups and web search. DeepSeek and other chat-backed providers cannot execute Responses-only tools, but rejecting the entire request prevents supported Codex function tools from working. Filtering only the unsupported declarations follows the gateway ingress policy without pretending a search or namespaced tool ran.

Verification

  • go test ./...
  • repository pre-commit hooks, including race tests and hot-path performance guard
  • Python probe syntax validation
  • live Codex 0.146.0 run through an isolated local GoModel instance using DEEPSEEK_API_KEY from the sibling .env
    • provider-qualified deepseek/deepseek-v4-pro
    • two /v1/responses requests, both HTTP 200
    • each request advertised 19 tools: 9 function, 9 namespace, and 1 web_search
    • exec_command completed a real tool round trip and Codex returned the exact expected response

Risk

Unsupported hosted tools are intentionally unavailable on chat-translated providers. Requests continue with supported function tools, but web search and namespace-contained tools do not execute. Native Responses providers retain their existing passthrough behavior. No extra provider call or hot-path pass is added.

Summary by CodeRabbit

  • Bug Fixes

    • Improved Responses API compatibility with hosted tools, including web search, file search, and computer use.
    • Unsupported hosted tools are now safely omitted instead of causing requests to fail.
    • Supported function tools remain available, while incompatible tool settings are removed when necessary.
    • Fixed streaming output ordering for tool calls arriving out of sequence.
  • Documentation

    • Updated compatibility guidance and examples to explain hosted-tool omission and resulting capability limitations.

Copilot AI review requested due to automatic review settings July 31, 2026 15:23

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@coderabbitai

coderabbitai Bot commented Jul 31, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

GoModel now omits unsupported Responses hosted tools during Responses-to-Chat conversion. Supported function tools remain available. Tool choices and parallel-call settings are cleared when no supported tools remain. Stream output indexes remain unique for out-of-order tool calls.

Changes

Responses compatibility and stream conversion

Layer / File(s) Summary
Filter unsupported tools during conversion
internal/providers/responses_adapter.go, internal/providers/responses_adapter_test.go
The adapter retains supported function tools, omits unsupported tools and choices, and clears related settings when no function tools remain. Tests cover these cases.
Allocate unique stream output indexes
internal/providers/responses_converter.go, internal/providers/responses_converter_test.go
The converter uses a monotonic output-index counter and validates tool-call startup. Tests cover out-of-order tool-call deltas.
Document omission and probe expectations
docs/advanced/responses-compatibility.mdx, docs/examples/openai-agents-sdk/anthropic_responses_probe.py
Documentation and probes describe successful hosted-tool omission instead of request rejection.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Sequence Diagram(s)

sequenceDiagram
  participant ResponsesClient
  participant ConvertResponsesRequestToChat
  participant ChatProvider
  ResponsesClient->>ConvertResponsesRequestToChat: submit tools and tool choice
  ConvertResponsesRequestToChat->>ConvertResponsesRequestToChat: retain function tools and omit unsupported tools
  ConvertResponsesRequestToChat->>ChatProvider: dispatch normalized Chat request
Loading

Possibly related PRs

Suggested reviewers: copilot

Poem

A rabbit trims tools from the tray,
Keeps function tools in play.
Stream indexes hop in line,
Even when deltas misalign.
The chat path stays clear today.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly identifies the main change: allowing unsupported Responses tools in Codex requests.
Description check ✅ Passed The description clearly covers the changes, rationale, verification, and risks, although it uses Summary instead of the template's Description heading.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/codex-namespace-tools

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@mintlify

mintlify Bot commented Jul 31, 2026

Copy link
Copy Markdown

Preview deployment for your docs. Learn more about Mintlify Previews.

Project Status Preview Updated (UTC)
gomodel 🟢 Ready View Preview Jul 31, 2026, 3:24 PM

💡 Tip: Enable Workflows to automatically generate PRs for you.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@internal/providers/responses_adapter_test.go`:
- Around line 596-662: Add a table-driven test case alongside
TestConvertResponsesRequestToChat_IgnoresUnsupportedTools covering a namespace
child named spawn_agent that is omitted while exec_command is retained, with
tool_choice selecting spawn_agent and ParallelToolCalls enabled. Assert that
only exec_command remains, ToolChoice is nil, and ParallelToolCalls remains set.

In `@internal/providers/responses_adapter.go`:
- Around line 33-39: The normalized tool-choice handling in
internal/providers/responses_adapter.go lines 33-39 must clear a named function
choice when its name is absent from the normalized function tools, while
preserving valid choices and the existing empty-tools behavior; add a
table-driven mixed namespace-and-function case in
internal/providers/responses_adapter_test.go lines 596-662 verifying an omitted
child choice is cleared.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 9f058967-d745-4d3d-9755-dd88e0361759

📥 Commits

Reviewing files that changed from the base of the PR and between c0b5d40 and c4ee3d6.

📒 Files selected for processing (4)
  • docs/advanced/responses-compatibility.mdx
  • docs/examples/openai-agents-sdk/anthropic_responses_probe.py
  • internal/providers/responses_adapter.go
  • internal/providers/responses_adapter_test.go

Comment thread internal/providers/responses_adapter_test.go
Comment thread internal/providers/responses_adapter.go
@codecov-commenter

codecov-commenter commented Jul 31, 2026

Copy link
Copy Markdown

⚠️ Please install the 'codecov app svg image' to ensure uploads and comments are reliably processed by Codecov.

Codecov Report

❌ Patch coverage is 98.11321% with 1 line in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
internal/providers/responses_converter.go 92.30% 1 Missing ⚠️

📢 Thoughts on this report? Let us know!

@mintlify

mintlify Bot commented Jul 31, 2026

Copy link
Copy Markdown

Preview deployment for your docs. Learn more about Mintlify Previews.

Project Status Preview Updated (UTC)
gomodel 🟡 Building Jul 31, 2026, 3:23 PM

💡 Tip: Enable Workflows to automatically generate PRs for you.

@greptile-apps

greptile-apps Bot commented Jul 31, 2026

Copy link
Copy Markdown

Confidence Score: 5/5

T-Rex T-Rex Logs

What T-Rex did

  • The base revision 61493f4 rejected web_search during conversion in the black-box harness, exiting with code 1, while the PR head harness completed with exit code 0 and preserved stream indexes [0 1 2 3].
  • Focused adapter and stream converter regression tests covering unsupported and mixed tool choices, reasoning, text, delayed metadata, and out-of-order tool-call events all passed.
  • Go test ./internal/providers -count=1 reported an unrelated configuration-state failure in TestResolveProviders_NoProvidersNoEnvVars, while the changed Responses paths passed.
  • The PR HEAD results include no product code changes and rely on the test-only harness as evidence.

View all artifacts

T-Rex Ran code and verified through T-Rex

Reviews (2): Last reviewed commit: "test(responses): assert streamed output ..." | Re-trigger Greptile

Copilot AI review requested due to automatic review settings July 31, 2026 16:25

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@SantiagoDePolonia

Copy link
Copy Markdown
Contributor Author

Addressed the reproduced out-of-order stream index collision in da1713e. OpenAI-compatible Responses streams now allocate output indexes monotonically when items are actually emitted, instead of deriving them from upstream tool-call slots. The exact reasoning → tool index 1 → assistant text → tool index 0 sequence now has unique indexes, with a regression test. Full go test ./... and all commit hooks, including race tests and the hot-path performance guard, pass.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@internal/providers/responses_converter_test.go`:
- Around line 312-359: Update
TestOpenAIResponsesStreamConverter_OutOfOrderToolCallsKeepUniqueIndexes to
record each response.output_item.added output_index in emission order and assert
the complete sequence is [0, 1, 2, 3]. Preserve the existing uniqueness,
output-count, and tool-call ID/index assertions, and incorporate this scenario
into the existing table-driven test structure if available.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 659365bb-8bec-4dc6-8d79-79b94f3e2061

📥 Commits

Reviewing files that changed from the base of the PR and between c4ee3d6 and da1713e.

📒 Files selected for processing (4)
  • internal/providers/responses_adapter.go
  • internal/providers/responses_adapter_test.go
  • internal/providers/responses_converter.go
  • internal/providers/responses_converter_test.go

Comment thread internal/providers/responses_converter_test.go
Copilot AI review requested due to automatic review settings July 31, 2026 16:29

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

Copilot AI review requested due to automatic review settings August 1, 2026 17:29
@SantiagoDePolonia
SantiagoDePolonia force-pushed the fix/codex-namespace-tools branch from a6c0afe to c484c32 Compare August 1, 2026 17:29

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
internal/providers/responses_adapter.go (1)

292-355: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add test coverage for the new tool_choice branches.

Two new branches in this segment have no visible test coverage:

  • The raw-string handling in normalizeResponsesToolChoiceForChat (lines 293-300) accepts tool_choice: "auto"/"required"/"none" as a bare string and returns nil for any other string. Only the map form ({"type": "auto"}) is tested in TestConvertResponsesRequestToChat_NormalizesToolChoiceAliases.
  • The fail-open guards in dropUnavailableResponsesToolChoice (lines 339-346) for a missing function map or a missing/empty name return the choice unchanged. No test exercises a malformed function-choice shape alongside available tools.

Add table-driven cases for a bare-string ToolChoice and for a malformed function choice, alongside the existing tool-choice tests.

As per coding guidelines for **/*_test.go, "Add or update table-driven tests for behavior changes, covering request translation, response normalization, error handling, default configuration, and provider-specific parameter mapping."

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@internal/providers/responses_adapter.go` around lines 292 - 355, Extend the
existing table-driven tool-choice tests around
TestConvertResponsesRequestToChat_NormalizesToolChoiceAliases to cover
bare-string values: preserve “auto”, “required”, and “none”, and normalize
unsupported strings to nil. Add malformed function-choice cases with available
tools to exercise dropUnavailableResponsesToolChoice’s missing function map and
missing or empty name guards, verifying each choice is returned unchanged.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@docs/advanced/responses-compatibility.mdx`:
- Line 38: Update the Responses-only tools table entry to replace the plain
“computer use” text with the backtick-formatted exact identifier
`computer_use_preview`, preserving the existing table structure and other tool
names.

---

Outside diff comments:
In `@internal/providers/responses_adapter.go`:
- Around line 292-355: Extend the existing table-driven tool-choice tests around
TestConvertResponsesRequestToChat_NormalizesToolChoiceAliases to cover
bare-string values: preserve “auto”, “required”, and “none”, and normalize
unsupported strings to nil. Add malformed function-choice cases with available
tools to exercise dropUnavailableResponsesToolChoice’s missing function map and
missing or empty name guards, verifying each choice is returned unchanged.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 73421e56-34f3-4019-bc2f-f9251ce5ecb5

📥 Commits

Reviewing files that changed from the base of the PR and between a6c0afe and c484c32.

📒 Files selected for processing (6)
  • docs/advanced/responses-compatibility.mdx
  • docs/examples/openai-agents-sdk/anthropic_responses_probe.py
  • internal/providers/responses_adapter.go
  • internal/providers/responses_adapter_test.go
  • internal/providers/responses_converter.go
  • internal/providers/responses_converter_test.go

Comment thread docs/advanced/responses-compatibility.mdx Outdated
Copilot AI review requested due to automatic review settings August 1, 2026 20:19

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@SantiagoDePolonia

Copy link
Copy Markdown
Contributor Author

Addressed the remaining outside-diff test coverage feedback in 47d5ce0. The table-driven tool-choice tests now cover bare auto/required/none values, unsupported bare strings, and malformed function choices with a missing function map, missing name, or empty name. Provider tests, race tests, lint, the performance guard, and Mintlify build validation pass.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@docs/advanced/responses-compatibility.mdx`:
- Line 38: Align the hosted web-search tool type across the documentation and
probe: update the Anthropic responses probe in
internal/providers/responses_adapter_test.go:569-571 to use the supported
web_search type, and ensure the corresponding documentation entry in
docs/advanced/responses-compatibility.mdx:38 remains consistent; alternatively,
explicitly document both accepted native hosted aliases.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 09c8b568-6310-48d5-9c70-b14080a07077

📥 Commits

Reviewing files that changed from the base of the PR and between c484c32 and 47d5ce0.

📒 Files selected for processing (2)
  • docs/advanced/responses-compatibility.mdx
  • internal/providers/responses_adapter_test.go

Comment thread docs/advanced/responses-compatibility.mdx
Copilot AI review requested due to automatic review settings August 1, 2026 20:24

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

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.

3 participants