Repository navigation
fix(databricks): translate reasoning_effort to thinking for Gemini 2.5 - #34001
devin-ai-integration[bot] wants to merge 14 commits into
Conversation
…aging, resolving conflicts Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
🤖 Devin AI EngineerI'll be helping with this pull request! Here's what you should know: ✅ I will automatically:
Note: I can only respond to comments from users who have write access to this repository. ⚙️ Control Options:
|
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Greptile SummaryFixes a 400 error from Databricks when
Confidence Score: 5/5
|
| Filename | Overview |
|---|---|
| litellm/llms/databricks/chat/transformation.py | Adds _uses_anthropic_thinking_param static method that combines the existing "claude" in model name guard with a model-cost-map lookup via supports_anthropic_thinking_payload, then uses it to gate the reasoning_effort → thinking translation. Logic is correct and consistent with the established pattern. |
| litellm/utils.py | Adds supports_anthropic_thinking_payload helper that delegates to _supports_factory (same pattern as all other supports_* functions), and wires the new JSON key into _get_model_info_helper. No issues. |
| litellm/types/utils.py | Adds `supports_anthropic_thinking_payload: ReadOnly[bool |
| model_prices_and_context_window.json | Adds "supports_anthropic_thinking_payload": true to all Databricks Claude entries (maintaining backward compat) and to the two Databricks Gemini 2.5 entries (Flash and Pro). Gemini 3+, GPT-5, and GPT-OSS intentionally omitted so they continue to pass reasoning_effort through unchanged. |
| model_prices_and_context_window.schema.json | Adds supports_anthropic_thinking_payload as a boolean property to the JSON schema definition, consistent with the other supports_* capability flags. |
| tests/test_litellm/llms/databricks/chat/test_databricks_chat_transformation.py | Adds 12 new mock-only tests covering: Claude translation (mapped + unmapped endpoint), adaptive-Claude output_config path, Gemini 2.5 Flash/Pro across all effort levels, dot-notation normalization, Gemini 2.0 pass-through, reasoning_effort="none" drop, and Gemini 3/GPT-5/GPT-OSS pass-through. Fixture scoped to autouse=False per prior review feedback. |
| tests/test_litellm/test_utils.py | Adds "supports_anthropic_thinking_payload" to the local schema in the JSON-validation test, keeping it in sync with model_prices_and_context_window.schema.json. |
Reviews (5): Last reviewed commit: "fix(databricks): keep the Claude fallbac..." | Re-trigger Greptile
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
…on schema Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
…ture Addresses Greptile P2 feedback: reject an adaptive thinking payload for non-Claude Databricks models instead of silently emitting a shape the Gemini endpoint can't parse, and scope the local-cost-map fixture to the tests that need it rather than autouse. Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
|
@greptileai - review |
…i-reasoning-effort Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
|
@greptileai - review |
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
…us/sonnet 4-6 Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
|
Added the missing flag to databricks-claude-opus-4-6 and databricks-claude-sonnet-4-6 in both JSON files. @greptileai |
…i-reasoning-effort Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
…i-reasoning-effort
…hinking payload Gate the reasoning_effort translation on the cost-map flag or the model name containing claude, so unmapped Claude serving endpoints keep translating. Flag the newer Claude entries that were missing it. Expose supports_anthropic_thinking_payload as a public helper next to the other supports_* wrappers instead of importing the private factory. Drop the adaptive-only guard, since the adaptive flags only ever match Claude ids, and add regression tests for an unmapped Claude endpoint and an adaptive Claude model
|
❌ Cannot revive Devin session - the session is too old. Please start a new session instead. |
TLDR
Problem this solves:
reasoning_efforton a Databricks Gemini 2.5 model came back as a 400 from Databricksthinkingwhen the model name containedclaudedrop_paramsdid not help, since Databricks reportsreasoning_effortas supported everywhereHow it solves it:
supports_anthropic_thinking_payload, marks which Databricks models take the Anthropicthinkingshapereasoning_effortthrough untouched, as Databricks documentsUser Flow
Before: a developer calling a Databricks-hosted Gemini 2.5 model through the gateway with
reasoning_effortgets a 400 back, while the same request against a Databricks Claude model works"model": "databricks-gemini-2-5-flash", a user message, and"reasoning_effort": "low"Invalid JSON payload received. Unknown name "reasoning_effort" at 'generation_config': Cannot find field.reasoning_effortand get a 200, so they cannot control thinking on that model through the gatewayAfter: the same request returns 200 and the model reasons at the requested effort
"model": "databricks-gemini-2-5-flash", a user message, and"reasoning_effort": "low"Relevant issues
Reopened copy of #32786 with the merge conflicts against
litellm_internal_stagingresolved. The fix and its tests come from #32786 (head 2bff743); its author could not carry it further, so this copy takes it to mergeLinear ticket
Resolves LIT-7665
Pre-Submission checklist
Please complete all items before asking a LiteLLM maintainer to review your PR
uv run pytest tests/test_litellm/<your_test_file>.py -v. Leave the suites (make test-unit-*,make test-unit) to CI: it finishes in ~15 minutes where a laptop takes an hour or more@greptileaito re-request a review after pushing changes)Delays in PR merge?
If you're seeing a delay in your PR being merged, ping the LiteLLM Team on Slack (#pr-review).
Screenshots / Proof of Fix
Shared setup for both legs. One proxy per leg runs from a worktree checked out at that leg's commit, with the config below, a random free port,
--detailed_debugso the payload the proxy sends to Databricks shows up in the log as a-d '{...}'line, andLITELLM_LOCAL_MODEL_COST_MAP=Trueso the cost map on the checkout is the one loaded. The Databricks workspace used here serves Claude and GPT-OSS but has no Gemini serving endpoint, so the Gemini 2.5 cases show the payload the proxy sends upstream (the part Databricks rejects with the 400) and the workspace answers 404 on both legs; the Claude and GPT-OSS cases are full round trips against the real endpointsThe same request loop runs against each leg, followed by the grep that pulls the upstream payloads out of the log:
Before (559247f)
Gemini 2.5 Flash, /v1/chat/completions, reasoning_effort low
"model": "databricks-gemini-2-5-flash"and"reasoning_effort": "low"HTTP 404from this workspace,litellm.NotFoundError: DatabricksException - {"error_code":"ENDPOINT_NOT_FOUND", ...}reasoning_effortsent as is, which is what a workspace that serves the model rejects withUnknown name "reasoning_effort" at 'generation_config':Claude Sonnet 4.5, /v1/chat/completions, reasoning_effort low
"model": "databricks-claude-sonnet-4-5"and"reasoning_effort": "low"HTTP 200,"content": "The sky is blue because molecules in Earth's atmosphere scatter short-wavelength blue light ...", with"reasoning_content"filled inClaude Opus 4.7, /v1/chat/completions, reasoning_effort high
"model": "databricks-claude-opus-4-7"and"reasoning_effort": "high"HTTP 200,"content": "The sky appears blue because molecules in Earth's atmosphere scatter shorter wavelengths of sunlight (blue) ..."GPT-OSS 120B, /v1/chat/completions, reasoning_effort low
"model": "databricks-gpt-oss-120b"and"reasoning_effort": "low"HTTP 200,"content": "The sky appears blue because molecules in Earth's atmosphere scatter shorter (blue) wavelengths ...","reasoning_content": "Provide concise answer."Gemini 2.5 Flash, /v1/responses, reasoning.effort low
"model": "databricks-gemini-2-5-flash"and"reasoning": {"effort": "low"}HTTP 404from this workspace, sameENDPOINT_NOT_FOUNDbodyreasoning_effort:Claude Sonnet 4.5, /v1/responses, reasoning.effort low
"model": "databricks-claude-sonnet-4-5"and"reasoning": {"effort": "low"}HTTP 200, aresp_...object with the answer'thinking': {'type': 'enabled', 'budget_tokens': 1024}, 'max_tokens': 5120After (c7b607c)
Gemini 2.5 Flash, /v1/chat/completions, reasoning_effort low
"model": "databricks-gemini-2-5-flash"and"reasoning_effort": "low"HTTP 404from this workspace, sameENDPOINT_NOT_FOUNDbody, since it has no Gemini endpointthinkingand noreasoning_effort, the shape Databricks accepts for Gemini 2.5:Claude Sonnet 4.5, /v1/chat/completions, reasoning_effort low
"model": "databricks-claude-sonnet-4-5"and"reasoning_effort": "low"HTTP 200,"content": "The sky appears blue because molecules in Earth's atmosphere scatter shorter blue wavelengths ...", with"reasoning_content"filled inClaude Opus 4.7, /v1/chat/completions, reasoning_effort high
"model": "databricks-claude-opus-4-7"and"reasoning_effort": "high"HTTP 200,"content": "The sky appears blue because molecules in Earth's atmosphere scatter shorter blue wavelengths of sunlight more strongly ..."GPT-OSS 120B, /v1/chat/completions, reasoning_effort low
"model": "databricks-gpt-oss-120b"and"reasoning_effort": "low"HTTP 200,"content": "The sky appears blue because molecules in Earth's atmosphere scatter shorter (blue) wavelengths ...","reasoning_content": "Provide concise answer."reasoning_effortstill passes through for the models that take it natively:Gemini 2.5 Flash, /v1/responses, reasoning.effort low
"model": "databricks-gemini-2-5-flash"and"reasoning": {"effort": "low"}HTTP 404from this workspace, sameENDPOINT_NOT_FOUNDbodythinkinginstead ofreasoning_effort, so the Responses API route gets the same fix:Claude Sonnet 4.5, /v1/responses, reasoning.effort low
"model": "databricks-claude-sonnet-4-5"and"reasoning": {"effort": "low"}HTTP 200, aresp_...object with the answer'thinking': {'type': 'enabled', 'budget_tokens': 1024}, 'max_tokens': 5120Type
🐛 Bug Fix
Caveats (if any)
Low
claudestill passesreasoning_effortthrough unchanged. That is the documented behavior for Gemini 3, GPT-5 and GPT-OSS, and it means a future Anthropic-shaped model on Databricks needs its cost map entry flagged before the translation kicks inthinkingtokens guard from fix(databricks): translate reasoning_effort to thinking for Gemini 2.5 #32786 already landed on the base branch on its own, so it is not part of this diffFinal Attestation
Link to Devin session: https://app.devin.ai/sessions/aacc049712434d50888cf457809a50b1