Merge pull request #18635 from BerriAI/litellm_completions_api_summary_param

(feat) Add mapping for reasoning effort to summary param of responses API
This commit is contained in:
Sameer Kankute
2026-01-05 17:36:21 +05:30
committed by GitHub
2 changed files with 47 additions and 7 deletions
@@ -691,19 +691,19 @@ class LiteLLMResponsesTransformationHandler(CompletionTransformationBridge):
if isinstance(reasoning_effort, dict):
return Reasoning(**reasoning_effort) # type: ignore[typeddict-item]
# If string is passed, map without summary (default)
# If string is passed, map with summary="detailed"
if reasoning_effort == "none":
return Reasoning(effort="none") # type: ignore
return Reasoning(effort="none", summary="detailed") # type: ignore
elif reasoning_effort == "high":
return Reasoning(effort="high")
return Reasoning(effort="high", summary="detailed")
elif reasoning_effort == "xhigh":
return Reasoning(effort="xhigh") # type: ignore[typeddict-item]
return Reasoning(effort="xhigh", summary="detailed") # type: ignore[typeddict-item]
elif reasoning_effort == "medium":
return Reasoning(effort="medium")
return Reasoning(effort="medium", summary="detailed")
elif reasoning_effort == "low":
return Reasoning(effort="low")
return Reasoning(effort="low", summary="detailed")
elif reasoning_effort == "minimal":
return Reasoning(effort="minimal")
return Reasoning(effort="minimal", summary="detailed")
return None
def _transform_response_format_to_text_format(
@@ -1007,3 +1007,43 @@ def test_multiple_tool_calls_in_single_choice():
assert tool_calls[2]["function"]["name"] == "get_horoscope"
print("✓ Multiple tool calls are correctly grouped in a single choice")
def test_map_reasoning_effort_adds_summary_detailed():
"""
Test that _map_reasoning_effort adds summary="detailed" when user provides reasoning_effort as a string.
This ensures that when users pass reasoning_effort in the completions API for OpenAI responses/models,
the transformation automatically includes summary="detailed" in the reasoning parameter.
"""
from litellm.completion_extras.litellm_responses_transformation.transformation import (
LiteLLMResponsesTransformationHandler,
)
handler = LiteLLMResponsesTransformationHandler()
# Test all string effort levels
effort_levels = ["none", "low", "medium", "high", "xhigh", "minimal"]
for effort in effort_levels:
result = handler._map_reasoning_effort(effort)
assert result is not None, f"Result should not be None for effort={effort}"
assert result["effort"] == effort, f"Effort should be {effort}"
assert result["summary"] == "detailed", f"Summary should be 'detailed' for effort={effort}"
print(f"✓ reasoning_effort='{effort}' correctly maps to effort='{effort}', summary='detailed'")
# Test that dict input is passed through as-is (no modification)
dict_input = {"effort": "high", "summary": "custom_summary"}
result_dict = handler._map_reasoning_effort(dict_input)
assert result_dict["effort"] == "high"
assert result_dict["summary"] == "custom_summary"
print("✓ Dict input is passed through without modification")
# Test that None/unknown values return None
result_unknown = handler._map_reasoning_effort("unknown_value")
assert result_unknown is None
print("✓ Unknown reasoning_effort values return None")
print("✓ All reasoning_effort string values correctly map to summary='detailed'")