@@ -679,40 +679,38 @@ def _handle_streaming_completion(
679679 params ["messages" ], full_response , from_agent
680680 )
681681
682- def _handle_tool_use_conversation (
682+ def _execute_tools_and_collect_results (
683683 self ,
684- initial_response : Message ,
685684 tool_uses : list [ToolUseBlock ],
686- params : dict [str , Any ],
687685 available_functions : dict [str , Any ],
688686 from_task : Any | None = None ,
689687 from_agent : Any | None = None ,
690- ) -> str :
691- """Handle the complete tool use conversation flow .
688+ ) -> list [ dict [ str , Any ]] :
689+ """Execute tools and collect results in Anthropic format .
692690
693- This implements the proper Anthropic tool use pattern:
694- 1. Claude requests tool use
695- 2. We execute the tools
696- 3. We send tool results back to Claude
697- 4. Claude processes results and generates final response
691+ Args:
692+ tool_uses: List of tool use blocks from Claude's response
693+ available_functions: Available functions for tool calling
694+ from_task: Task that initiated the call
695+ from_agent: Agent that initiated the call
696+
697+ Returns:
698+ List of tool result dictionaries in Anthropic format
698699 """
699- # Execute all requested tools and collect results
700700 tool_results = []
701701
702702 for tool_use in tool_uses :
703703 function_name = tool_use .name
704704 function_args = tool_use .input
705705
706- # Execute the tool
707706 result = self ._handle_tool_execution (
708707 function_name = function_name ,
709- function_args = function_args ,
708+ function_args = cast ( dict [ str , Any ], function_args ) ,
710709 available_functions = available_functions ,
711710 from_task = from_task ,
712711 from_agent = from_agent ,
713712 )
714713
715- # Create tool result in Anthropic format
716714 tool_result = {
717715 "type" : "tool_result" ,
718716 "tool_use_id" : tool_use .id ,
@@ -722,7 +720,29 @@ def _handle_tool_use_conversation(
722720 }
723721 tool_results .append (tool_result )
724722
725- # Prepare follow-up conversation with tool results
723+ return tool_results
724+
725+ def _handle_tool_use_conversation (
726+ self ,
727+ initial_response : Message ,
728+ tool_uses : list [ToolUseBlock ],
729+ params : dict [str , Any ],
730+ available_functions : dict [str , Any ],
731+ from_task : Any | None = None ,
732+ from_agent : Any | None = None ,
733+ ) -> str :
734+ """Handle the complete tool use conversation flow.
735+
736+ This implements the proper Anthropic tool use pattern:
737+ 1. Claude requests tool use
738+ 2. We execute the tools
739+ 3. We send tool results back to Claude
740+ 4. Claude processes results and generates final response
741+ """
742+ tool_results = self ._execute_tools_and_collect_results (
743+ tool_uses , available_functions , from_task , from_agent
744+ )
745+
726746 follow_up_params = params .copy ()
727747
728748 # Add Claude's tool use response to conversation
@@ -810,7 +830,7 @@ def _handle_tool_use_conversation(
810830 logging .error (f"Tool follow-up conversation failed: { e } " )
811831 # Fallback: return the first tool result if follow-up fails
812832 if tool_results :
813- return tool_results [0 ]["content" ]
833+ return cast ( str , tool_results [0 ]["content" ])
814834 raise e
815835
816836 async def _ahandle_completion (
@@ -1003,28 +1023,9 @@ async def _ahandle_tool_use_conversation(
10031023 3. We send tool results back to Claude
10041024 4. Claude processes results and generates final response
10051025 """
1006- tool_results = []
1007-
1008- for tool_use in tool_uses :
1009- function_name = tool_use .name
1010- function_args = tool_use .input
1011-
1012- result = self ._handle_tool_execution (
1013- function_name = function_name ,
1014- function_args = function_args ,
1015- available_functions = available_functions ,
1016- from_task = from_task ,
1017- from_agent = from_agent ,
1018- )
1019-
1020- tool_result = {
1021- "type" : "tool_result" ,
1022- "tool_use_id" : tool_use .id ,
1023- "content" : str (result )
1024- if result is not None
1025- else "Tool execution completed" ,
1026- }
1027- tool_results .append (tool_result )
1026+ tool_results = self ._execute_tools_and_collect_results (
1027+ tool_uses , available_functions , from_task , from_agent
1028+ )
10281029
10291030 follow_up_params = params .copy ()
10301031
@@ -1079,7 +1080,7 @@ async def _ahandle_tool_use_conversation(
10791080
10801081 logging .error (f"Tool follow-up conversation failed: { e } " )
10811082 if tool_results :
1082- return tool_results [0 ]["content" ]
1083+ return cast ( str , tool_results [0 ]["content" ])
10831084 raise e
10841085
10851086 def supports_function_calling (self ) -> bool :
@@ -1115,7 +1116,8 @@ def get_context_window_size(self) -> int:
11151116 # Default context window size for Claude models
11161117 return int (200000 * CONTEXT_WINDOW_USAGE_RATIO )
11171118
1118- def _extract_anthropic_token_usage (self , response : Message ) -> dict [str , Any ]:
1119+ @staticmethod
1120+ def _extract_anthropic_token_usage (response : Message ) -> dict [str , Any ]:
11191121 """Extract token usage from Anthropic response."""
11201122 if hasattr (response , "usage" ) and response .usage :
11211123 usage = response .usage
0 commit comments