mirror of
https://github.com/BerriAI/litellm.git
synced 2026-09-07 08:26:10 +00:00
fix(databricks): accept Reasoning(effort=..., summary=...) dict for reasoning_effort
OpenAI Responses callers send reasoning_effort as a dict
({'effort': 'low', 'summary': 'concise'}) — the Responses->Chat parser keeps
the full dict when summary is set (#25359 / #28196). The Databricks Claude
adapter only handled the bare string and silently dropped the dict shape.
Coerce dict -> effort before mapping, matching the direct Anthropic and
Bedrock Converse adapters. Adds regression tests for both shapes.
This commit is contained in:
parent
31a67561ab
commit
63fa72643d
2 changed files with 55 additions and 6 deletions
|
|
@ -358,7 +358,15 @@ class DatabricksConfig(DatabricksBase, OpenAILikeChatConfig, AnthropicConfig):
|
|||
) # unsupported for claude models - if json_schema -> convert to tool call
|
||||
|
||||
if "reasoning_effort" in non_default_params and "claude" in model:
|
||||
reasoning_effort_value: Final = non_default_params.get("reasoning_effort")
|
||||
reasoning_effort_value = non_default_params.get("reasoning_effort")
|
||||
# Accept both string ("low") and dict ({"effort": "low",
|
||||
# "summary": "concise"}). The Responses->Chat parser keeps the
|
||||
# full dict when `summary` is set (see #25359 / #28196), so a
|
||||
# dict here is the standard shape Otto/OpenAI-Responses-Bridge
|
||||
# callers send. Same coercion the direct Anthropic adapter and
|
||||
# the Bedrock Converse adapter already do.
|
||||
if isinstance(reasoning_effort_value, dict):
|
||||
reasoning_effort_value = reasoning_effort_value.get("effort")
|
||||
mapped_thinking: Final = AnthropicConfig._map_reasoning_effort(
|
||||
reasoning_effort=reasoning_effort_value,
|
||||
model=model,
|
||||
|
|
|
|||
|
|
@ -1,9 +1,4 @@
|
|||
import json
|
||||
|
||||
import pytest
|
||||
from fastapi.testclient import TestClient
|
||||
|
||||
from unittest.mock import MagicMock, patch
|
||||
|
||||
from litellm.llms.databricks.chat.transformation import (
|
||||
DatabricksChatResponseIterator,
|
||||
|
|
@ -493,3 +488,49 @@ def test_chunk_parser_without_usage_still_parses_content():
|
|||
assert result.id == "chatcmpl-test"
|
||||
assert result.model == "databricks-claude-sonnet-5"
|
||||
assert result.choices[0]["delta"]["content"] == "hi"
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"model",
|
||||
[
|
||||
"databricks/databricks-claude-3-7-sonnet",
|
||||
"databricks/databricks-claude-opus-4-7",
|
||||
],
|
||||
)
|
||||
def test_reasoning_effort_accepts_dict_shape(model):
|
||||
"""Regression for #28196 (companion to bedrock + direct Anthropic fixes).
|
||||
|
||||
OpenAI Responses callers send
|
||||
``reasoning_effort={'effort': 'low', 'summary': 'concise'}``;
|
||||
the Databricks Claude adapter must coerce the dict to ``low`` and
|
||||
forward thinking + (for adaptive Claude 4.6 / 4.7) output_config,
|
||||
instead of silently dropping it.
|
||||
"""
|
||||
config = DatabricksConfig()
|
||||
|
||||
optional_params = config.map_openai_params(
|
||||
non_default_params={
|
||||
"reasoning_effort": {"effort": "low", "summary": "concise"},
|
||||
},
|
||||
optional_params={},
|
||||
model=model,
|
||||
drop_params=False,
|
||||
replace_max_completion_tokens_with_max_tokens=False,
|
||||
)
|
||||
|
||||
assert "thinking" in optional_params, f"reasoning_effort dict was dropped on {model}: {optional_params!r}"
|
||||
|
||||
|
||||
def test_reasoning_effort_bare_string_still_works():
|
||||
"""Regression guard for the pre-existing string shape."""
|
||||
config = DatabricksConfig()
|
||||
|
||||
optional_params = config.map_openai_params(
|
||||
non_default_params={"reasoning_effort": "low"},
|
||||
optional_params={},
|
||||
model="databricks/databricks-claude-3-7-sonnet",
|
||||
drop_params=False,
|
||||
replace_max_completion_tokens_with_max_tokens=False,
|
||||
)
|
||||
|
||||
assert "thinking" in optional_params
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue