1111 TextBlock ,
1212 VideoBlock ,
1313 ThinkingBlock ,
14+ ToolCallBlock ,
1415)
1516from llama_index .core .llms .llm import ToolSelection
1617from llama_index .core .program .function_program import get_function_tool
@@ -564,8 +565,16 @@ def test_tool_required_integration(llm: GoogleGenAI) -> None:
564565 tools = [search_tool ],
565566 tool_required = True ,
566567 )
567- assert response .message .additional_kwargs .get ("tool_calls" ) is not None
568- assert len (response .message .additional_kwargs ["tool_calls" ]) > 0
568+ assert (
569+ len (
570+ [
571+ block
572+ for block in response .message .blocks
573+ if isinstance (block , ToolCallBlock )
574+ ]
575+ )
576+ > 0
577+ )
569578
570579 # Test with tool_required=False
571580 response = llm .chat_with_tools (
@@ -729,6 +738,10 @@ async def test_prepare_chat_params_more_than_2_tool_calls():
729738 )
730739 ],
731740 ),
741+ ChatMessage (
742+ blocks = [ToolCallBlock (tool_name = "get_available_tools" , tool_kwargs = {})],
743+ role = MessageRole .ASSISTANT ,
744+ ),
732745 ChatMessage (
733746 content = "Let me search for puppies." ,
734747 role = MessageRole .ASSISTANT ,
@@ -777,10 +790,11 @@ async def test_prepare_chat_params_more_than_2_tool_calls():
777790 text = "The user is asking me for a puppy, so I should search for puppies using the available tools." ,
778791 thought = True ,
779792 ),
793+ types .Part .from_function_call (name = "get_available_tools" , args = {}),
780794 types .Part (text = "Let me search for puppies." ),
781- types .Part .from_function_call (name = "tool_1" , args = None ),
782- types .Part .from_function_call (name = "tool_2" , args = None ),
783- types .Part .from_function_call (name = "tool_3" , args = None ),
795+ types .Part .from_function_call (name = "tool_1" , args = {} ),
796+ types .Part .from_function_call (name = "tool_2" , args = {} ),
797+ types .Part .from_function_call (name = "tool_3" , args = {} ),
784798 ],
785799 role = MessageRole .MODEL ,
786800 ),
@@ -872,6 +886,10 @@ def test_cached_content_in_response() -> None:
872886 mock_response .candidates [0 ].content .parts [0 ].text = "Test response"
873887 mock_response .candidates [0 ].content .parts [0 ].thought = False
874888 mock_response .candidates [0 ].content .parts [0 ].inline_data = None
889+ mock_response .candidates [0 ].content .parts [0 ].function_call .id = ""
890+ mock_response .candidates [0 ].content .parts [0 ].function_call .name = "hello"
891+ mock_response .candidates [0 ].content .parts [0 ].function_call .args = {}
892+ mock_response .candidates [0 ].content .parts [0 ].function_response = None
875893 mock_response .prompt_feedback = None
876894 mock_response .usage_metadata = None
877895 mock_response .function_calls = None
@@ -899,6 +917,10 @@ def test_cached_content_without_cached_content() -> None:
899917 mock_response .candidates [0 ].content .parts [0 ].text = "Test response"
900918 mock_response .candidates [0 ].content .parts [0 ].thought = False
901919 mock_response .candidates [0 ].content .parts [0 ].inline_data = None
920+ mock_response .candidates [0 ].content .parts [0 ].function_call .id = ""
921+ mock_response .candidates [0 ].content .parts [0 ].function_call .name = "hello"
922+ mock_response .candidates [0 ].content .parts [0 ].function_call .args = {}
923+ mock_response .candidates [0 ].content .parts [0 ].function_response = None
902924 mock_response .prompt_feedback = None
903925 mock_response .usage_metadata = None
904926 mock_response .function_calls = None
@@ -923,9 +945,15 @@ def test_thoughts_in_response() -> None:
923945 mock_response .candidates [0 ].content .parts [0 ].text = "This is a thought."
924946 mock_response .candidates [0 ].content .parts [0 ].inline_data = None
925947 mock_response .candidates [0 ].content .parts [0 ].thought = True
948+ mock_response .candidates [0 ].content .parts [0 ].function_call .id = ""
949+ mock_response .candidates [0 ].content .parts [0 ].function_call .name = "hello"
950+ mock_response .candidates [0 ].content .parts [0 ].function_call .args = {}
926951 mock_response .candidates [0 ].content .parts [1 ].text = "This is not a thought."
927952 mock_response .candidates [0 ].content .parts [1 ].inline_data = None
928953 mock_response .candidates [0 ].content .parts [1 ].thought = None
954+ mock_response .candidates [0 ].content .parts [1 ].function_call = None
955+ mock_response .candidates [0 ].content .parts [1 ].function_response = None
956+ mock_response .candidates [0 ].content .parts [0 ].function_response = None
929957 mock_response .candidates [0 ].content .parts [0 ].model_dump = MagicMock (return_value = {})
930958 mock_response .candidates [0 ].content .parts [1 ].model_dump = MagicMock (return_value = {})
931959 mock_response .prompt_feedback = None
@@ -967,6 +995,8 @@ def test_thoughts_without_thought_response() -> None:
967995 mock_response .candidates [0 ].content .parts [0 ].text = "This is not a thought."
968996 mock_response .candidates [0 ].content .parts [0 ].inline_data = None
969997 mock_response .candidates [0 ].content .parts [0 ].thought = None
998+ mock_response .candidates [0 ].content .parts [0 ].function_call = None
999+ mock_response .candidates [0 ].content .parts [0 ].function_response = None
9701000 mock_response .prompt_feedback = None
9711001 mock_response .usage_metadata = None
9721002 mock_response .function_calls = None
@@ -1084,6 +1114,8 @@ def test_built_in_tool_in_response() -> None:
10841114 ].text = "Test response with search results"
10851115 mock_response .candidates [0 ].content .parts [0 ].inline_data = None
10861116 mock_response .candidates [0 ].content .parts [0 ].thought = None
1117+ mock_response .candidates [0 ].content .parts [0 ].function_call = None
1118+ mock_response .candidates [0 ].content .parts [0 ].function_response = None
10871119 mock_response .prompt_feedback = None
10881120 mock_response .usage_metadata = MagicMock ()
10891121 mock_response .usage_metadata .model_dump .return_value = {
@@ -1523,6 +1555,8 @@ def test_code_execution_response_parts() -> None:
15231555 )
15241556 mock_text_part .inline_data = None
15251557 mock_text_part .thought = None
1558+ mock_text_part .function_call = None
1559+ mock_text_part .function_response = None
15261560
15271561 mock_code_part = MagicMock ()
15281562 mock_code_part .text = None
@@ -1532,6 +1566,8 @@ def test_code_execution_response_parts() -> None:
15321566 "code" : "def is_prime(n):\n if n < 2:\n return False\n for i in range(2, int(n**0.5) + 1):\n if n % i == 0:\n return False\n return True\n \n primes = []\n n = 2\n while len(primes) < 50:\n if is_prime(n):\n primes.append(n)\n n += 1\n \n print(f'Sum of first 50 primes: {sum(primes)}')" ,
15331567 "language" : types .Language .PYTHON ,
15341568 }
1569+ mock_code_part .function_call = None
1570+ mock_code_part .function_response = None
15351571
15361572 mock_result_part = MagicMock ()
15371573 mock_result_part .text = None
@@ -1541,11 +1577,15 @@ def test_code_execution_response_parts() -> None:
15411577 "outcome" : types .Outcome .OUTCOME_OK ,
15421578 "output" : "Sum of first 50 primes: 5117" ,
15431579 }
1580+ mock_result_part .function_call = None
1581+ mock_result_part .function_response = None
15441582
15451583 mock_final_text_part = MagicMock ()
15461584 mock_final_text_part .text = "The sum of the first 50 prime numbers is 5117."
15471585 mock_final_text_part .inline_data = None
15481586 mock_final_text_part .thought = None
1587+ mock_final_text_part .function_call = None
1588+ mock_final_text_part .function_response = None
15491589
15501590 mock_candidate .content .parts = [
15511591 mock_text_part ,
0 commit comments