|
13 | 13 | # limitations under the License.
|
14 | 14 |
|
15 | 15 |
|
| 16 | +import json |
16 | 17 | from unittest.mock import AsyncMock
|
17 | 18 | from unittest.mock import Mock
|
18 | 19 |
|
|
38 | 39 | from litellm.types.utils import ModelResponse
|
39 | 40 | from litellm.types.utils import StreamingChoices
|
40 | 41 | import pytest
|
41 |
| -import json |
42 | 42 |
|
43 | 43 | LLM_REQUEST_WITH_FUNCTION_DECLARATION = LlmRequest(
|
44 | 44 | contents=[
|
@@ -1190,74 +1190,70 @@ async def test_generate_content_async_stream_with_usage_metadata(
|
1190 | 1190 | async def test_generate_content_async_multiple_function_calls(
|
1191 | 1191 | mock_completion, lite_llm_instance
|
1192 | 1192 | ):
|
1193 |
| - """Test handling of multiple function calls with different indices in streaming mode. |
1194 |
| -
|
1195 |
| - This test verifies that: |
1196 |
| - 1. Multiple function calls with different indices are handled correctly |
1197 |
| - 2. Arguments and names are properly accumulated for each function call |
1198 |
| - 3. The final response contains all function calls with correct indices |
1199 |
| - """ |
1200 |
| - mock_completion.return_value = MULTIPLE_FUNCTION_CALLS_STREAM |
1201 |
| - |
1202 |
| - llm_request = LlmRequest( |
1203 |
| - contents=[ |
1204 |
| - types.Content( |
1205 |
| - role="user", |
1206 |
| - parts=[types.Part.from_text(text="Test multiple function calls")], |
1207 |
| - ) |
1208 |
| - ], |
1209 |
| - config=types.GenerateContentConfig( |
1210 |
| - tools=[ |
1211 |
| - types.Tool( |
1212 |
| - function_declarations=[ |
1213 |
| - types.FunctionDeclaration( |
1214 |
| - name="function_1", |
1215 |
| - description="First test function", |
1216 |
| - parameters=types.Schema( |
1217 |
| - type=types.Type.OBJECT, |
1218 |
| - properties={ |
1219 |
| - "arg": types.Schema(type=types.Type.STRING), |
1220 |
| - }, |
1221 |
| - ), |
1222 |
| - ), |
1223 |
| - types.FunctionDeclaration( |
1224 |
| - name="function_2", |
1225 |
| - description="Second test function", |
1226 |
| - parameters=types.Schema( |
1227 |
| - type=types.Type.OBJECT, |
1228 |
| - properties={ |
1229 |
| - "arg": types.Schema(type=types.Type.STRING), |
1230 |
| - }, |
1231 |
| - ), |
1232 |
| - ), |
1233 |
| - ] |
1234 |
| - ) |
1235 |
| - ], |
1236 |
| - ), |
1237 |
| - ) |
| 1193 | + """Test handling of multiple function calls with different indices in streaming mode. |
1238 | 1194 |
|
1239 |
| - responses = [] |
1240 |
| - async for response in lite_llm_instance.generate_content_async( |
1241 |
| - llm_request, stream=True |
1242 |
| - ): |
1243 |
| - responses.append(response) |
1244 |
| - |
1245 |
| - # Verify we got the final response with both function calls |
1246 |
| - assert len(responses) > 0 |
1247 |
| - final_response = responses[-1] |
1248 |
| - assert final_response.content.role == "model" |
1249 |
| - assert len(final_response.content.parts) == 2 |
1250 |
| - |
1251 |
| - # Verify first function call |
1252 |
| - assert final_response.content.parts[0].function_call.name == "function_1" |
1253 |
| - assert final_response.content.parts[0].function_call.id == "call_1" |
1254 |
| - assert final_response.content.parts[0].function_call.args == { |
1255 |
| - "arg": "value1" |
1256 |
| - } |
| 1195 | + This test verifies that: |
| 1196 | + 1. Multiple function calls with different indices are handled correctly |
| 1197 | + 2. Arguments and names are properly accumulated for each function call |
| 1198 | + 3. The final response contains all function calls with correct indices |
| 1199 | + """ |
| 1200 | + mock_completion.return_value = MULTIPLE_FUNCTION_CALLS_STREAM |
1257 | 1201 |
|
1258 |
| - # Verify second function call |
1259 |
| - assert final_response.content.parts[1].function_call.name == "function_2" |
1260 |
| - assert final_response.content.parts[1].function_call.id == "call_2" |
1261 |
| - assert final_response.content.parts[1].function_call.args == { |
1262 |
| - "arg": "value2" |
1263 |
| - } |
| 1202 | + llm_request = LlmRequest( |
| 1203 | + contents=[ |
| 1204 | + types.Content( |
| 1205 | + role="user", |
| 1206 | + parts=[types.Part.from_text(text="Test multiple function calls")], |
| 1207 | + ) |
| 1208 | + ], |
| 1209 | + config=types.GenerateContentConfig( |
| 1210 | + tools=[ |
| 1211 | + types.Tool( |
| 1212 | + function_declarations=[ |
| 1213 | + types.FunctionDeclaration( |
| 1214 | + name="function_1", |
| 1215 | + description="First test function", |
| 1216 | + parameters=types.Schema( |
| 1217 | + type=types.Type.OBJECT, |
| 1218 | + properties={ |
| 1219 | + "arg": types.Schema(type=types.Type.STRING), |
| 1220 | + }, |
| 1221 | + ), |
| 1222 | + ), |
| 1223 | + types.FunctionDeclaration( |
| 1224 | + name="function_2", |
| 1225 | + description="Second test function", |
| 1226 | + parameters=types.Schema( |
| 1227 | + type=types.Type.OBJECT, |
| 1228 | + properties={ |
| 1229 | + "arg": types.Schema(type=types.Type.STRING), |
| 1230 | + }, |
| 1231 | + ), |
| 1232 | + ), |
| 1233 | + ] |
| 1234 | + ) |
| 1235 | + ], |
| 1236 | + ), |
| 1237 | + ) |
| 1238 | + |
| 1239 | + responses = [] |
| 1240 | + async for response in lite_llm_instance.generate_content_async( |
| 1241 | + llm_request, stream=True |
| 1242 | + ): |
| 1243 | + responses.append(response) |
| 1244 | + |
| 1245 | + # Verify we got the final response with both function calls |
| 1246 | + assert len(responses) > 0 |
| 1247 | + final_response = responses[-1] |
| 1248 | + assert final_response.content.role == "model" |
| 1249 | + assert len(final_response.content.parts) == 2 |
| 1250 | + |
| 1251 | + # Verify first function call |
| 1252 | + assert final_response.content.parts[0].function_call.name == "function_1" |
| 1253 | + assert final_response.content.parts[0].function_call.id == "call_1" |
| 1254 | + assert final_response.content.parts[0].function_call.args == {"arg": "value1"} |
| 1255 | + |
| 1256 | + # Verify second function call |
| 1257 | + assert final_response.content.parts[1].function_call.name == "function_2" |
| 1258 | + assert final_response.content.parts[1].function_call.id == "call_2" |
| 1259 | + assert final_response.content.parts[1].function_call.args == {"arg": "value2"} |
0 commit comments