@@ -302,6 +302,42 @@ def _is_ollama_provider(self) -> bool:
302302
303303 return False
304304
305+ def _generate_ollama_tool_summary (self , tool_results : List [Any ], response_text : str ) -> Optional [str ]:
306+ """
307+ Generate a summary from tool results for Ollama to prevent infinite loops.
308+
309+ This prevents infinite loops where Ollama provides an empty response after a
310+ tool call, expecting the user to prompt for a summary.
311+
312+ Args:
313+ tool_results: The list of results from tool execution.
314+ response_text: The text response from the LLM.
315+
316+ Returns:
317+ A summary string if conditions are met, otherwise None.
318+ """
319+ # Constant for minimal response length check
320+ OLLAMA_MIN_RESPONSE_LENGTH = 10
321+
322+ # Only generate summary for Ollama with tool results
323+ if not (self ._is_ollama_provider () and tool_results ):
324+ return None
325+
326+ # If response is substantial, no summary needed
327+ if response_text and len (response_text .strip ()) > OLLAMA_MIN_RESPONSE_LENGTH :
328+ return None
329+
330+ # Build tool summary efficiently
331+ summary_lines = ["Based on the tool execution results:" ]
332+ for i , result in enumerate (tool_results ):
333+ if isinstance (result , dict ) and 'result' in result :
334+ function_name = result .get ('function_name' , 'Tool' )
335+ summary_lines .append (f"- { function_name } : { result ['result' ]} " )
336+ else :
337+ summary_lines .append (f"- Tool { i + 1 } : { result } " )
338+
339+ return "\n " .join (summary_lines )
340+
305341 def _format_ollama_tool_result_message (self , function_name : str , tool_result : Any ) -> Dict [str , str ]:
306342 """
307343 Format tool result message for Ollama provider.
@@ -1072,21 +1108,11 @@ def get_response(
10721108 final_response_text = response_text .strip ()
10731109 break
10741110
1075- # Special handling for Ollama: if we have tool results but empty/minimal response,
1076- # generate a summary based on tool results to prevent infinite loops
1077- if self ._is_ollama_provider () and tool_results and len (tool_results ) > 0 :
1078- # Create a summary of tool results for Ollama
1079- tool_summary = "Based on the tool execution results:\n "
1080- for i , result in enumerate (tool_results ):
1081- if isinstance (result , dict ) and 'result' in result :
1082- tool_summary += f"- { result .get ('function_name' , 'Tool' )} : { result ['result' ]} \n "
1083- else :
1084- tool_summary += f"- Tool { i + 1 } : { result } \n "
1085-
1086- # If response is empty or minimal, use tool summary as final answer
1087- if not response_text or len (response_text .strip ()) <= 10 :
1088- final_response_text = tool_summary .strip ()
1089- break
1111+ # Special handling for Ollama to prevent infinite loops
1112+ tool_summary = self ._generate_ollama_tool_summary (tool_results , response_text )
1113+ if tool_summary :
1114+ final_response_text = tool_summary
1115+ break
10901116
10911117 # Otherwise, continue the loop to check if more tools are needed
10921118 iteration_count += 1
@@ -1831,21 +1857,11 @@ async def get_response_async(
18311857 final_response_text = response_text .strip ()
18321858 break
18331859
1834- # Special handling for Ollama: if we have tool results but empty/minimal response,
1835- # generate a summary based on tool results to prevent infinite loops
1836- if self ._is_ollama_provider () and tool_results and len (tool_results ) > 0 :
1837- # Create a summary of tool results for Ollama
1838- tool_summary = "Based on the tool execution results:\n "
1839- for i , result in enumerate (tool_results ):
1840- if isinstance (result , dict ) and 'result' in result :
1841- tool_summary += f"- { result .get ('function_name' , 'Tool' )} : { result ['result' ]} \n "
1842- else :
1843- tool_summary += f"- Tool { i + 1 } : { result } \n "
1844-
1845- # If response is empty or minimal, use tool summary as final answer
1846- if not response_text or len (response_text .strip ()) <= 10 :
1847- final_response_text = tool_summary .strip ()
1848- break
1860+ # Special handling for Ollama to prevent infinite loops
1861+ tool_summary = self ._generate_ollama_tool_summary (tool_results , response_text )
1862+ if tool_summary :
1863+ final_response_text = tool_summary
1864+ break
18491865
18501866 # Continue the loop to check if more tools are needed
18511867 iteration_count += 1
0 commit comments