From 7dce61ce48c46bca7bae9e2a98d480361f9bfdc7 Mon Sep 17 00:00:00 2001 From: Sameer Kankute Date: Sat, 14 Mar 2026 00:13:16 +0530 Subject: [PATCH] fix(tests): update TestGPT5ReasoningEffortPreservation for dict normalization Made-with: Cursor --- .../chat/test_openai_gpt_transformation.py | 56 +++++++++---------- 1 file changed, 26 insertions(+), 30 deletions(-) diff --git a/tests/test_litellm/llms/openai/chat/test_openai_gpt_transformation.py b/tests/test_litellm/llms/openai/chat/test_openai_gpt_transformation.py index 81ffa1aa42..086d01f65b 100644 --- a/tests/test_litellm/llms/openai/chat/test_openai_gpt_transformation.py +++ b/tests/test_litellm/llms/openai/chat/test_openai_gpt_transformation.py @@ -364,12 +364,11 @@ class TestGPT5ReasoningEffortPreservation: # Dict with only 'effort' should be normalized to string assert non_default_params.get("reasoning_effort") == "high" - def test_reasoning_effort_dict_with_summary_preserved(self): - """Test that reasoning_effort dict with 'summary' field is preserved for Responses API. + def test_reasoning_effort_dict_with_summary_normalized(self): + """Test that reasoning_effort dict with 'summary' is normalized for Chat Completions API. - Regression test for: User reported that summary field was being dropped when - routing to Responses API. The dict format with additional fields should be - preserved so it can be properly handled by the Responses API transformation. + map_openai_params normalizes all dicts to string. Full dict is restored in main.py + when routing to Responses API (test_gpt_5_4_responses_bridge_preserves_reasoning_summary_dict). """ non_default_params = {"reasoning_effort": {"effort": "high", "summary": "detailed"}} optional_params = {} @@ -381,14 +380,11 @@ class TestGPT5ReasoningEffortPreservation: drop_params=False, ) - # Dict with additional fields should be preserved - assert non_default_params.get("reasoning_effort") == {"effort": "high", "summary": "detailed"} - assert isinstance(non_default_params.get("reasoning_effort"), dict) - assert non_default_params["reasoning_effort"]["effort"] == "high" - assert non_default_params["reasoning_effort"]["summary"] == "detailed" + # Dict is normalized to string for Chat Completions API + assert non_default_params.get("reasoning_effort") == "high" - def test_reasoning_effort_dict_with_generate_summary_preserved(self): - """Test that reasoning_effort dict with 'generate_summary' field is preserved.""" + def test_reasoning_effort_dict_with_generate_summary_normalized(self): + """Test that reasoning_effort dict with 'generate_summary' is normalized for Chat Completions API.""" non_default_params = {"reasoning_effort": {"effort": "medium", "generate_summary": "auto"}} optional_params = {} @@ -399,12 +395,11 @@ class TestGPT5ReasoningEffortPreservation: drop_params=False, ) - # Dict with additional fields should be preserved - assert non_default_params.get("reasoning_effort") == {"effort": "medium", "generate_summary": "auto"} - assert isinstance(non_default_params.get("reasoning_effort"), dict) + # Dict is normalized to string for Chat Completions API + assert non_default_params.get("reasoning_effort") == "medium" - def test_reasoning_effort_dict_with_all_fields_preserved(self): - """Test that reasoning_effort dict with all fields is preserved.""" + def test_reasoning_effort_dict_with_all_fields_normalized(self): + """Test that reasoning_effort dict with all fields is normalized to effort string.""" non_default_params = { "reasoning_effort": { "effort": "high", @@ -421,12 +416,8 @@ class TestGPT5ReasoningEffortPreservation: drop_params=False, ) - # Dict with all fields should be preserved - reasoning = non_default_params.get("reasoning_effort") - assert isinstance(reasoning, dict) - assert reasoning["effort"] == "high" - assert reasoning["summary"] == "detailed" - assert reasoning["generate_summary"] == "concise" + # Dict is normalized to string for Chat Completions API + assert non_default_params.get("reasoning_effort") == "high" def test_reasoning_effort_dict_xhigh_triggers_validation(self): """xhigh-dict: effective effort is extracted for model-support validation. @@ -461,8 +452,8 @@ class TestGPT5ReasoningEffortPreservation: assert "reasoning_effort" not in non_default_params - def test_reasoning_effort_dict_none_dropped_for_gpt5_4_with_tools(self): - """none-dict with tools on gpt-5.4: reasoning_effort is dropped.""" + def test_reasoning_effort_dict_none_passed_through_for_gpt5_4_with_tools(self): + """none-dict with tools on gpt-5.4: reasoning_effort is passed through (routing to Responses at completion level).""" tools = [{"type": "function", "function": {"name": "test", "description": "test"}}] non_default_params = {"reasoning_effort": {"effort": "none", "summary": "detailed"}, "tools": tools} optional_params = {} @@ -474,13 +465,15 @@ class TestGPT5ReasoningEffortPreservation: drop_params=False, ) - assert "reasoning_effort" not in non_default_params + # Normalized to "none", passed through; routing to Responses API happens at completion() + assert non_default_params.get("reasoning_effort") == "none" assert non_default_params.get("tools") == tools def test_reasoning_effort_dict_none_treated_as_none_for_sampling(self): """none-dict: {"effort": "none", "summary": "detailed"} allows logprobs/top_p. - Sampling-param guard should NOT fire; logprobs should be kept. + effective_effort='none' is used for sampling guard; logprobs should be kept. + Dict is normalized to "none" for Chat Completions API. """ non_default_params = { "reasoning_effort": {"effort": "none", "summary": "detailed"}, @@ -495,11 +488,14 @@ class TestGPT5ReasoningEffortPreservation: drop_params=False, ) - assert non_default_params.get("reasoning_effort") == {"effort": "none", "summary": "detailed"} + assert non_default_params.get("reasoning_effort") == "none" assert non_default_params.get("logprobs") is True def test_reasoning_effort_dict_none_allows_temperature(self): - """none-dict: {"effort": "none", "summary": "detailed"} allows non-default temperature.""" + """none-dict: {"effort": "none", "summary": "detailed"} allows non-default temperature. + + effective_effort='none' is used for temperature guard. Dict is normalized to "none". + """ non_default_params = { "reasoning_effort": {"effort": "none", "summary": "detailed"}, "temperature": 0.5, @@ -514,4 +510,4 @@ class TestGPT5ReasoningEffortPreservation: ) assert optional_params.get("temperature") == 0.5 - assert non_default_params.get("reasoning_effort") == {"effort": "none", "summary": "detailed"} + assert non_default_params.get("reasoning_effort") == "none"