@@ -42,3 +42,116 @@ async def fake_acompletion(model, messages=None, **kwargs):
4242 )
4343
4444 assert {"cached_content" : "some_cache" , "foo" : 123 }.items () <= captured .items ()
45+
46+
47+ @pytest .mark .allow_call_model_methods
48+ @pytest .mark .asyncio
49+ async def test_extra_body_reasoning_effort_is_promoted (monkeypatch ):
50+ """
51+ Ensure reasoning_effort from extra_body is promoted to the top-level parameter.
52+ """
53+ captured : dict [str , object ] = {}
54+
55+ async def fake_acompletion (model , messages = None , ** kwargs ):
56+ captured .update (kwargs )
57+ msg = Message (role = "assistant" , content = "ok" )
58+ choice = Choices (index = 0 , message = msg )
59+ return ModelResponse (choices = [choice ], usage = Usage (0 , 0 , 0 ))
60+
61+ monkeypatch .setattr (litellm , "acompletion" , fake_acompletion )
62+ # GitHub issue context: https://github.com/openai/openai-agents-python/issues/1764.
63+ settings = ModelSettings (
64+ extra_body = {"reasoning_effort" : "none" , "cached_content" : "some_cache" }
65+ )
66+ model = LitellmModel (model = "test-model" )
67+
68+ await model .get_response (
69+ system_instructions = None ,
70+ input = [],
71+ model_settings = settings ,
72+ tools = [],
73+ output_schema = None ,
74+ handoffs = [],
75+ tracing = ModelTracing .DISABLED ,
76+ previous_response_id = None ,
77+ )
78+
79+ assert captured ["reasoning_effort" ] == "none"
80+ assert captured ["cached_content" ] == "some_cache"
81+ assert settings .extra_body == {"reasoning_effort" : "none" , "cached_content" : "some_cache" }
82+
83+
84+ @pytest .mark .allow_call_model_methods
85+ @pytest .mark .asyncio
86+ async def test_reasoning_effort_prefers_model_settings (monkeypatch ):
87+ """
88+ Verify explicit ModelSettings.reasoning takes precedence over extra_body entries.
89+ """
90+ from openai .types .shared import Reasoning
91+
92+ captured : dict [str , object ] = {}
93+
94+ async def fake_acompletion (model , messages = None , ** kwargs ):
95+ captured .update (kwargs )
96+ msg = Message (role = "assistant" , content = "ok" )
97+ choice = Choices (index = 0 , message = msg )
98+ return ModelResponse (choices = [choice ], usage = Usage (0 , 0 , 0 ))
99+
100+ monkeypatch .setattr (litellm , "acompletion" , fake_acompletion )
101+ settings = ModelSettings (
102+ reasoning = Reasoning (effort = "low" ),
103+ extra_body = {"reasoning_effort" : "high" },
104+ )
105+ model = LitellmModel (model = "test-model" )
106+
107+ await model .get_response (
108+ system_instructions = None ,
109+ input = [],
110+ model_settings = settings ,
111+ tools = [],
112+ output_schema = None ,
113+ handoffs = [],
114+ tracing = ModelTracing .DISABLED ,
115+ previous_response_id = None ,
116+ )
117+
118+ assert captured ["reasoning_effort" ] == "low"
119+ assert settings .extra_body == {"reasoning_effort" : "high" }
120+
121+
122+ @pytest .mark .allow_call_model_methods
123+ @pytest .mark .asyncio
124+ async def test_extra_body_reasoning_effort_overrides_extra_args (monkeypatch ):
125+ """
126+ Ensure extra_body reasoning_effort wins over extra_args when both are provided.
127+ """
128+ captured : dict [str , object ] = {}
129+
130+ async def fake_acompletion (model , messages = None , ** kwargs ):
131+ captured .update (kwargs )
132+ msg = Message (role = "assistant" , content = "ok" )
133+ choice = Choices (index = 0 , message = msg )
134+ return ModelResponse (choices = [choice ], usage = Usage (0 , 0 , 0 ))
135+
136+ monkeypatch .setattr (litellm , "acompletion" , fake_acompletion )
137+ # GitHub issue context: https://github.com/openai/openai-agents-python/issues/1764.
138+ settings = ModelSettings (
139+ extra_body = {"reasoning_effort" : "none" },
140+ extra_args = {"reasoning_effort" : "low" , "custom_param" : "custom" },
141+ )
142+ model = LitellmModel (model = "test-model" )
143+
144+ await model .get_response (
145+ system_instructions = None ,
146+ input = [],
147+ model_settings = settings ,
148+ tools = [],
149+ output_schema = None ,
150+ handoffs = [],
151+ tracing = ModelTracing .DISABLED ,
152+ previous_response_id = None ,
153+ )
154+
155+ assert captured ["reasoning_effort" ] == "none"
156+ assert captured ["custom_param" ] == "custom"
157+ assert settings .extra_args == {"reasoning_effort" : "low" , "custom_param" : "custom" }
0 commit comments