Skip to content

fix(openai): bridge gpt-5.6+ tools to /v1/responses without reasoning_effort - #34043

Closed
devin-ai-integration[bot] wants to merge 1 commit into
litellm_internal_stagingfrom
litellm_gpt56_tools_responses_bridge
Closed

fix(openai): bridge gpt-5.6+ tools to /v1/responses without reasoning_effort#34043
devin-ai-integration[bot] wants to merge 1 commit into
litellm_internal_stagingfrom
litellm_gpt56_tools_responses_bridge

Conversation

@devin-ai-integration

Copy link
Copy Markdown
Contributor

Relevant issues

Fixes #33221

Linear ticket

Pre-Submission checklist

  • I have added meaningful tests
  • My PR passes all CI/CD checks (e.g., lint, format, unit tests)
  • My PR's scope is as isolated as possible; it only solves 1 specific problem
  • I have received a Greptile Confidence Score of at least 4/5 before requesting a maintainer review

Type

🐛 Bug Fix

Changes

Calling /chat/completions with function tools on a gpt-5.6 family model (gpt-5.6, gpt-5.6-sol/luna/terra) fails with a 400 even when the caller does not set reasoning_effort, because OpenAI applies a default reasoning_effort server-side for that family and then rejects tools on Chat Completions ("use /v1/responses or set reasoning_effort to 'none'").

responses_api_bridge_check in main.py only bridged tools-carrying requests to /v1/responses when reasoning_effort is not None, so these requests stayed on Chat Completions and 400'd.

The narrow-but-wrong fix would be to bridge all gpt-5.4+ tool calls unconditionally, but staging already pins the opposite behavior for gpt-5.4/5.5: test_responses_api_bridge_check_gpt_5_4_tools_without_reasoning_stays_chat (and its azure variant) assert that gpt-5.4 tools-only stays on Chat Completions. So this scopes the new tools-only bridge to gpt-5.6+ only.

Bridge condition, before -> after:

# before
reasoning_effort is not None
and (reasoning_summary is not None or (is_gpt_5_4_plus and tools))

# after
(
    reasoning_effort is not None
    and (reasoning_summary is not None or (is_gpt_5_4_plus and tools))
)
or (is_gpt_5_6_plus and tools)

Adds OpenAIGPT5Config.is_model_gpt_5_6_plus_model, factoring the shared minor-version parse out of is_model_gpt_5_4_plus_model into _gpt_5_minor_version_at_least(model, minimum) so both helpers stay in sync.

Net behavior: gpt-5.6+ with tools bridges even without reasoning_effort; gpt-5.4/5.5 tools-only keeps staying on Chat Completions; all existing explicit reasoning_effort / reasoning_summary paths are unchanged.

Screenshots / Proof of Fix

These are internal/preview model names without a public endpoint I can bill against, so proof is at the bridge-decision layer that produces the 400. Regression tests in tests/test_litellm/test_main.py assert mode == "responses" for every gpt-5.6 variant (openai and azure) with tools and reasoning_effort=None, and assert gpt-5.4/5.5 tools-only stay on chat; tests/test_litellm/llms/openai/test_is_model_gpt_5_model.py covers the new classifier. Happy to run a live /chat/completions -> bridged /v1/responses curl if a callable gpt-5.6 deployment is available.

Final Attestation

  • The tests check the right things, including the edge cases, and regressions in the respective real-world customer use-cases are not possible after this PR

Link to Devin session: https://app.devin.ai/sessions/07cee113560043bb99d091e5ad1f1286
Requested by: @krrish-berri-2

…_effort

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
@krrish-berri-2 krrish-berri-2 self-assigned this Jul 20, 2026
@devin-ai-integration

Copy link
Copy Markdown
Contributor Author

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR. Add '(aside)' to your comment to have me ignore it.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment, CI, and merge conflict monitoring

@CLAassistant

Copy link
Copy Markdown

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.
You have signed the CLA already but the status is still pending? Let us recheck it.

@greptile-apps

greptile-apps Bot commented Jul 20, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR fixes a 400 error that occurs when calling /chat/completions with function tools on gpt-5.6+ models (gpt-5.6, gpt-5.6-sol, gpt-5.6-luna, gpt-5.6-terra) because OpenAI applies a default reasoning_effort server-side for that family, causing Chat Completions to reject tool calls.

  • Introduces _gpt_5_minor_version_at_least(model, minimum) to share version-parse logic, and adds is_model_gpt_5_6_plus_model so responses_api_bridge_check in main.py can bridge tools-only requests for gpt-5.6+ to /v1/responses even when reasoning_effort is None.
  • gpt-5.4/5.5 tools-without-reasoning correctly keep going to Chat Completions; all pre-existing reasoning_effort/reasoning_summary paths are untouched; full mock test coverage is added for each case.

Confidence Score: 4/5

The bridge logic change is narrow, well-tested, and correctly scoped to gpt-5.6+; existing gpt-5.4/5.5 and reasoning-effort paths are untouched.

The core fix is correct and the regression test suite is comprehensive. The main concern is that is_model_gpt_5_6_plus_model hardcodes the version threshold rather than reading it from model_prices_and_context_window.json, which the repository convention requires — meaning a future model family with different bridging behaviour could be silently mis-routed without a code update.

litellm/llms/openai/chat/gpt_5_transformation.py — the new is_model_gpt_5_6_plus_model helper and the variable naming in _gpt_5_minor_version_at_least.

Important Files Changed

Filename Overview
litellm/llms/openai/chat/gpt_5_transformation.py Refactors is_model_gpt_5_4_plus_model into a shared _gpt_5_minor_version_at_least helper and adds is_model_gpt_5_6_plus_model; logic is correct but the version boundary is hardcoded rather than driven by model_prices JSON per repo convention.
litellm/main.py Adds the gpt-5.6+ tools-only bridge branch to responses_api_bridge_check; the condition correctly sits outside the reasoning_effort is not None guard, and the existing gpt-5.4/5.5 paths are unchanged.
tests/test_litellm/llms/openai/test_is_model_gpt_5_model.py Adds TestOpenAIGPT5ConfigIsModelGpt56PlusModel with positive and negative parametrized cases; coverage is adequate for the new classifier, no real network calls.
tests/test_litellm/test_main.py Adds three new bridge-check tests (gpt-5.6 tools-without-reasoning bridges, gpt-5.6 tools+effort bridges, gpt-5.4/5.5 tools-only stays on chat); tests are mocked, comprehensive, and correctly assert the expected mode.

Reviews (1): Last reviewed commit: "fix(openai): bridge gpt-5.6+ tools to /v..." | Re-trigger Greptile

Comment on lines 117 to +118
major = version_str.split(".")[0]
return int(major) >= 4
return int(major) >= minimum

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.

P2 The local variable major stores the minor part of the gpt-5.X version (the X after the dot), not the major version. This naming is inverted and can mislead future readers who try to understand the parse logic.

Suggested change
major = version_str.split(".")[0]
return int(major) >= 4
return int(major) >= minimum
minor = version_str.split(".")[0]
return int(minor) >= minimum

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

Comment on lines +128 to +130
def is_model_gpt_5_6_plus_model(cls, model: str) -> bool:
"""Check if the model is gpt-5.6 or newer (5.6, 5.7, etc., including named/pro variants)."""
return cls._gpt_5_minor_version_at_least(model, 6)

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.

P2 Hardcoded version boundary violates repo rule

The is_model_gpt_5_6_plus_model helper (and the unchanged is_model_gpt_5_4_plus_model) hardcode version thresholds in Python rather than using a flag in model_prices_and_context_window.json read via get_model_info. The repo rule exists so that new model families can be supported without a code change — for example, if a future gpt-5.8 family needs different bridging behaviour the >= 6 predicate would silently mis-classify it. A field like "tools_require_responses_bridge": true on each gpt-5.6 entry in the JSON (already present for azure/gpt-5.6, azure/gpt-5.6-sol, azure/gpt-5.6-terra, azure/gpt-5.6-luna) read through get_model_info would make the boundary data-driven and auditable.

Rule Used: What: Do not hardcode model-specific flags in the ... (source)

@codecov

codecov Bot commented Jul 20, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@codspeed-hq

codspeed-hq Bot commented Jul 20, 2026

Copy link
Copy Markdown
Contributor

Merging this PR will not alter performance

✅ 31 untouched benchmarks


Comparing litellm_gpt56_tools_responses_bridge (5369fe1) with litellm_internal_staging (214945a)1

Open in CodSpeed

Footnotes

  1. No successful run was found on litellm_internal_staging (432954a) during the generation of this report, so 214945a was used instead as the comparison base. There might be some changes unrelated to this pull request in this report.

@mvrodrig

mvrodrig commented Jul 27, 2026

Copy link
Copy Markdown

Hi @krrish-berri-2 @greptile-apps! When are you merging this PR? Thanks!

@greptile-apps

greptile-apps Bot commented Jul 27, 2026

Copy link
Copy Markdown
Contributor

I'm a code review bot — I don't have any say in merge timelines. That decision is up to the maintainers (@krrish-berri-2 or whoever owns this repo).

If the PR is ready for maintainer review, make sure the Greptile confidence score is at least 4/5 (per the pre-submission checklist) and then ping a maintainer directly on the PR.

Tip: You can customize Greptile's behavior for this repo with .greptile/rules.md and .greptile/config.json.

@aspexdaniel

Copy link
Copy Markdown

when this can be merged into stable release?

@mateo-berri

Copy link
Copy Markdown
Contributor

#34029's merged bridge covers gpt-5.4+ function tools even without explicit reasoning_effort, so #34043 is no longer needed. It's in v1.97.0-rc.1 and any version thereafter. Closing this

@mateo-berri
mateo-berri deleted the litellm_gpt56_tools_responses_bridge branch August 14, 2026 03:11
@devin-ai-integration

Copy link
Copy Markdown
Contributor Author

Agreed, closing is right — #34029 is a strict superset of this PR and I'd rather have it. Verified against current litellm_internal_staging: for gpt-5.6-sol + function tools with reasoning_effort unset, is_model_gpt_5_4_plus_model matches, reasoning_active is True (None != "none"), and on_constraint_enforcing_endpoint covers the default OpenAI base and Azure, so it bridges — which is exactly the #33221 repro.

#34029 also handles three things this PR did not: custom/grammar tools staying on chat (has_function_tool), reasoning_effort="none" as an explicit chat-servable opt-out, and not bridging OpenAI-compatible backends on a custom api_base that have no /responses route. Merging this on top would have narrowed the fix to 5.6+ and lost those. Thanks for the pointer to v1.97.0-rc.1.

Unrelated note for anyone landing here from the batch: #34044 (duration-only provider_budget_config dropping deployments, #33327) is a separate bug and is still reproducible on staging — the if config.max_budget is None: continue in _filter_out_deployments_above_budget is unchanged there.

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.

[Bug]: Function tools fail with reasoning_effort error for OpenAI gpt-5.6 family models (gpt-5.6-sol/luna/terra) on /chat/completions

6 participants