Skip to content

fix(databricks): accept Reasoning(effort=..., summary=...) dict for reasoning_effort - #29330

Open
hclsys wants to merge 3 commits into
BerriAI:litellm_internal_stagingfrom
hclsys:fix/databricks-reasoning-effort-dict-coerce
Open

fix(databricks): accept Reasoning(effort=..., summary=...) dict for reasoning_effort#29330
hclsys wants to merge 3 commits into
BerriAI:litellm_internal_stagingfrom
hclsys:fix/databricks-reasoning-effort-dict-coerce

Conversation

@hclsys

@hclsys hclsys commented May 30, 2026

Copy link
Copy Markdown
Contributor

Third + final adapter in the #28196 lane — direct Anthropic path was fixed in #25359, Bedrock Converse companion is #29329, this is Databricks Claude.

Same root cause: map_openai_params passed the raw reasoning_effort straight to AnthropicConfig._map_reasoning_effort, which compares with string equality (reasoning_effort == "low"), so the OpenAI Responses Reasoning(effort, summary) dict shape returned None → no thinking / output_config set. The downstream isinstance(reasoning_effort_value, str) adaptive-Claude check would then short-circuit, surfacing a misleading invalid reasoning_effort from _raise_invalid_reasoning_effort.

fix

One-liner coercion before any downstream branch — matches what bedrock + anthropic already do:

if isinstance(reasoning_effort_value, dict):
    reasoning_effort_value = reasoning_effort_value.get("effort")

proof

$ .venv/bin/python -m pytest tests/test_litellm/llms/databricks/chat/test_databricks_chat_transformation.py -k reasoning_effort -v
[...]
test_reasoning_effort_accepts_dict_shape[databricks/databricks-claude-3-7-sonnet] PASSED
test_reasoning_effort_accepts_dict_shape[databricks/databricks-claude-opus-4-7] PASSED
test_reasoning_effort_bare_string_still_works PASSED
======================= 3 passed, 11 deselected in 0.09s =======================

sibling tests in the same file (11 pre-existing) still pass.

@CLAassistant

CLAassistant commented May 30, 2026

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

@greptile-apps

greptile-apps Bot commented May 30, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

Fixes the Databricks Claude adapter to accept reasoning_effort as either a plain string ("low") or the OpenAI Responses dict shape ({"effort": "low", "summary": "concise"}), by coercing the dict to its "effort" value before passing it to AnthropicConfig._map_reasoning_effort. This is the third of three adapters patched in the #28196 lane, matching identical coercions already present in the direct Anthropic and Bedrock Converse adapters.

  • transformation.py: Adds a two-line isinstance(dict) guard that extracts effort from the dict before the downstream string-comparison branches run, preventing None being forwarded and thinking/output_config being silently dropped.
  • test_databricks_chat_transformation.py: Adds three new mock-only unit tests — parametrised over claude-3-7-sonnet and claude-opus-4-7 for the dict path, and a separate bare-string regression guard — with no modifications to existing tests.

Confidence Score: 5/5

Safe to merge — the change is a minimal, well-tested one-liner that mirrors an identical fix already applied to two sibling adapters.

The coercion is isolated to a local variable, does not touch non_default_params, and the post-coercion path (string equality checks, adaptive-model output_config branch) is identical to what worked before for bare-string callers. Three new mock-only unit tests cover both the dict and string input shapes across the affected models, and no existing tests were modified.

No files require special attention.

Important Files Changed

Filename Overview
litellm/llms/databricks/chat/transformation.py Adds dict-to-string coercion for reasoning_effort before passing to AnthropicConfig._map_reasoning_effort, matching the pattern already used in the direct Anthropic and Bedrock Converse adapters.
tests/test_litellm/llms/databricks/chat/test_databricks_chat_transformation.py Adds three new unit tests covering the dict-shape and bare-string paths for reasoning_effort; all tests are mocked with no real network calls, and no existing tests are modified.

Reviews (1): Last reviewed commit: "fix(databricks): accept Reasoning(effort..." | Re-trigger Greptile

@codspeed-hq

codspeed-hq Bot commented May 30, 2026

Copy link
Copy Markdown
Contributor

Merging this PR will not alter performance

✅ 31 untouched benchmarks


Comparing hclsys:fix/databricks-reasoning-effort-dict-coerce (c2b8927) with litellm_internal_staging (39c01fe)

Open in CodSpeed

@codecov

codecov Bot commented May 30, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@krrish-berri-2

Copy link
Copy Markdown
Contributor

@hclsys — could you add a screenshot or short video showing a Databricks request with a Reasoning(effort=..., summary=...) dict being accepted end-to-end? Visual proof really helps reviewers verify the fix quickly. Thanks!

@hclsys

hclsys commented May 30, 2026

Copy link
Copy Markdown
Contributor Author

companion PR #29329 (same one-line dict coercion for the Bedrock Converse adapter) — both bedrock + databricks have the same #28196 root cause that the direct Anthropic adapter already fixed via #25359. Same coercion, sequential audit of the 3 anthropic-via-X adapters in litellm.

@hclsys

hclsys commented May 30, 2026

Copy link
Copy Markdown
Contributor Author

@krrish-berri-2 before/after exercised against DatabricksConfig.map_openai_params for adaptive Claude 4.7:

from litellm.llms.databricks.chat.transformation import DatabricksConfig
cfg = DatabricksConfig()
op = cfg.map_openai_params(
    non_default_params={"reasoning_effort": {"effort": "low", "summary": "concise"}},
    optional_params={},
    model="databricks/databricks-claude-opus-4-7",
    drop_params=False,
    replace_max_completion_tokens_with_max_tokens=False,
)
print(op.get("thinking"), op.get("output_config"))

unpatched main — actually worse than silent-drop here, it raises:

litellm.exceptions.BadRequestError: litellm.BadRequestError: Invalid reasoning_effort:
{'effort': 'low', 'summary': 'concise'}. Must be one of: 'minimal', 'low', 'medium', 'high', 'xhigh', 'max', 'none'

this PR:

{'type': 'adaptive'} {'effort': 'low'}    # ← dict accepted, identical to passing reasoning_effort="low"
match str path: True

@hclsys
hclsys changed the base branch from main to litellm_internal_staging May 31, 2026 03:02
@hclsys
hclsys force-pushed the fix/databricks-reasoning-effort-dict-coerce branch from 1763522 to 2d622fa Compare June 4, 2026 15:34
@hclsys

hclsys commented Jun 4, 2026

Copy link
Copy Markdown
Contributor Author

branch now starts from internal_staging head. same one-commit change, just clean base. CI should pass.

@hclsys

hclsys commented Jun 4, 2026

Copy link
Copy Markdown
Contributor Author

@krrish-berri-2 best i can offer from this env is the test stdout exercising the Reasoning(effort=..., summary=...) dict path end-to-end through DatabricksConfig.map_openai_params:

$ uv run pytest tests/test_litellm/llms/databricks/chat/test_databricks_chat_transformation.py -k reasoning_effort
3 passed in 0.23s

CI is green. happy to add more coverage if you want it.

hclsys added 3 commits July 16, 2026 11:06
…easoning_effort

Same companion fix as bedrock-converse and the direct Anthropic path (BerriAI#25359
/ BerriAI#28196). Databricks Claude's `map_openai_params` passed the raw value
straight to `AnthropicConfig._map_reasoning_effort`, which compares with
string equality (`reasoning_effort == "low"`) so a dict shape was silently
dropped and `thinking`/`output_config` never got set. The downstream
`isinstance(reasoning_effort_value, str)` check for the adaptive Claude
output_config also short-circuited, raising a misleading
"invalid reasoning_effort" error from `_raise_invalid_reasoning_effort`.

Coerce the dict to its `effort` string before any downstream branch,
matching the bedrock + anthropic adapters.

Related to BerriAI#28196 (third + final adapter in the same lane).
@hclsys
hclsys force-pushed the fix/databricks-reasoning-effort-dict-coerce branch from 2d622fa to c2b8927 Compare July 16, 2026 03:08
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