@@ -115,6 +115,69 @@ def test_format_request_message_content(content, exp_result):
115115 assert tru_result == exp_result
116116
117117
118+ @pytest .mark .asyncio
119+ async def test_stream (litellm_client , model , alist ):
120+ mock_tool_call_1_part_1 = unittest .mock .Mock (index = 0 )
121+ mock_tool_call_2_part_1 = unittest .mock .Mock (index = 1 )
122+ mock_delta_1 = unittest .mock .Mock (
123+ reasoning_content = "" ,
124+ content = None ,
125+ tool_calls = None ,
126+ )
127+ mock_delta_2 = unittest .mock .Mock (
128+ reasoning_content = "\n I'm thinking" ,
129+ content = None ,
130+ tool_calls = None ,
131+ )
132+ mock_delta_3 = unittest .mock .Mock (
133+ content = "I'll calculate" , tool_calls = [mock_tool_call_1_part_1 , mock_tool_call_2_part_1 ], reasoning_content = None
134+ )
135+
136+ mock_tool_call_1_part_2 = unittest .mock .Mock (index = 0 )
137+ mock_tool_call_2_part_2 = unittest .mock .Mock (index = 1 )
138+ mock_delta_4 = unittest .mock .Mock (
139+ content = "that for you" , tool_calls = [mock_tool_call_1_part_2 , mock_tool_call_2_part_2 ], reasoning_content = None
140+ )
141+
142+ mock_delta_5 = unittest .mock .Mock (content = "" , tool_calls = None , reasoning_content = None )
143+
144+ mock_event_1 = unittest .mock .Mock (choices = [unittest .mock .Mock (finish_reason = None , delta = mock_delta_1 )])
145+ mock_event_2 = unittest .mock .Mock (choices = [unittest .mock .Mock (finish_reason = None , delta = mock_delta_2 )])
146+ mock_event_3 = unittest .mock .Mock (choices = [unittest .mock .Mock (finish_reason = None , delta = mock_delta_3 )])
147+ mock_event_4 = unittest .mock .Mock (choices = [unittest .mock .Mock (finish_reason = None , delta = mock_delta_4 )])
148+ mock_event_5 = unittest .mock .Mock (choices = [unittest .mock .Mock (finish_reason = "tool_calls" , delta = mock_delta_5 )])
149+ mock_event_6 = unittest .mock .Mock ()
150+
151+ litellm_client .chat .completions .create .return_value = iter (
152+ [mock_event_1 , mock_event_2 , mock_event_3 , mock_event_4 , mock_event_5 , mock_event_6 ]
153+ )
154+
155+ request = {"model" : "m1" , "messages" : [{"role" : "user" , "content" : [{"type" : "text" , "text" : "calculate 2+2" }]}]}
156+ response = model .stream (request )
157+ tru_events = await alist (response )
158+ exp_events = [
159+ {"chunk_type" : "message_start" },
160+ {"chunk_type" : "content_start" , "data_type" : "text" },
161+ {"chunk_type" : "content_delta" , "data_type" : "reasoning_content" , "data" : "\n I'm thinking" },
162+ {"chunk_type" : "content_delta" , "data_type" : "text" , "data" : "I'll calculate" },
163+ {"chunk_type" : "content_delta" , "data_type" : "text" , "data" : "that for you" },
164+ {"chunk_type" : "content_stop" , "data_type" : "text" },
165+ {"chunk_type" : "content_start" , "data_type" : "tool" , "data" : mock_tool_call_1_part_1 },
166+ {"chunk_type" : "content_delta" , "data_type" : "tool" , "data" : mock_tool_call_1_part_1 },
167+ {"chunk_type" : "content_delta" , "data_type" : "tool" , "data" : mock_tool_call_1_part_2 },
168+ {"chunk_type" : "content_stop" , "data_type" : "tool" },
169+ {"chunk_type" : "content_start" , "data_type" : "tool" , "data" : mock_tool_call_2_part_1 },
170+ {"chunk_type" : "content_delta" , "data_type" : "tool" , "data" : mock_tool_call_2_part_1 },
171+ {"chunk_type" : "content_delta" , "data_type" : "tool" , "data" : mock_tool_call_2_part_2 },
172+ {"chunk_type" : "content_stop" , "data_type" : "tool" },
173+ {"chunk_type" : "message_stop" , "data" : "tool_calls" },
174+ {"chunk_type" : "metadata" , "data" : mock_event_6 .usage },
175+ ]
176+
177+ assert tru_events == exp_events
178+ litellm_client .chat .completions .create .assert_called_once_with (** request )
179+
180+
118181@pytest .mark .asyncio
119182async def test_structured_output (litellm_client , model , test_output_model_cls , alist ):
120183 messages = [{"role" : "user" , "content" : [{"text" : "Generate a person" }]}]
0 commit comments