@@ -323,8 +323,8 @@ def _generate_ollama_tool_summary(self, tool_results: List[Any], response_text:
323323 if not (self ._is_ollama_provider () and tool_results ):
324324 return None
325325
326- # If response is substantial , no summary needed
327- if response_text and len ( response_text . strip ()) > OLLAMA_MIN_RESPONSE_LENGTH :
326+ # If response is a final answer , no summary needed
327+ if self . _is_final_answer ( response_text , False , tool_results ) :
328328 return None
329329
330330 # Build tool summary efficiently
@@ -349,6 +349,64 @@ def _format_ollama_tool_result_message(self, function_name: str, tool_result: An
349349 "content" : f"The { function_name } function returned: { tool_result_str } "
350350 }
351351
352+ def _is_final_answer (self , response_text : str , has_tool_calls : bool , tool_results : List [Any ]) -> bool :
353+ """
354+ Determine if a response is a final answer or intermediate acknowledgment.
355+
356+ This method provides intelligent differentiation between:
357+ - Intermediate responses that acknowledge tool execution
358+ - Final responses that contain actual answers to user queries
359+
360+ Args:
361+ response_text: The text response from the LLM
362+ has_tool_calls: Whether the response contains tool calls
363+ tool_results: Results from executed tools
364+
365+ Returns:
366+ True if this is a final answer, False if intermediate
367+ """
368+ if not response_text or not response_text .strip ():
369+ return False
370+
371+ response_lower = response_text .lower ().strip ()
372+
373+ # If response contains tool calls, it's likely not a final answer
374+ if has_tool_calls :
375+ return False
376+
377+ # For Ollama, be more conservative about what constitutes a final answer
378+ if self ._is_ollama_provider ():
379+ # If we have recent tool results, check if this is just acknowledgment
380+ if tool_results :
381+ # Common patterns of tool acknowledgment (not final answers)
382+ acknowledgment_patterns = [
383+ "i'll" , "let me" , "now i'll" , "next i'll" , "i need to" , "i should" ,
384+ "executing" , "calling" , "running" , "using the" , "based on this" ,
385+ "now let me" , "let me now" , "i will now" , "proceeding to" ,
386+ "moving to" , "continuing with" , "next step" , "now that i have" ,
387+ "tool executed" , "function called" , "result obtained" , "got the result"
388+ ]
389+
390+ # Check if response is primarily acknowledgment
391+ if any (pattern in response_lower for pattern in acknowledgment_patterns ):
392+ # If it's short and contains acknowledgment patterns, likely intermediate
393+ if len (response_text .strip ()) < 50 :
394+ return False
395+
396+ # If response is very short and we have tool results, likely intermediate
397+ if len (response_text .strip ()) < 30 :
398+ return False
399+
400+ # Additional check: if response mainly contains status updates or simple confirmations
401+ status_patterns = ["done" , "completed" , "finished" , "successful" , "ok" , "ready" ]
402+ if (len (response_text .strip ()) < 40 and
403+ any (pattern in response_lower for pattern in status_patterns )):
404+ return False
405+
406+ # For other providers, maintain existing behavior
407+ # Substantial content (>10 chars) is considered final
408+ return len (response_text .strip ()) > 10
409+
352410 def _process_stream_delta (self , delta , response_text : str , tool_calls : List [Dict ], formatted_tools : Optional [List ] = None ) -> tuple :
353411 """
354412 Process a streaming delta chunk to extract content and tool calls.
@@ -1102,17 +1160,19 @@ def get_response(
11021160 continue
11031161
11041162 # Check if the LLM provided a final answer alongside the tool calls
1105- # If response_text contains substantive content, treat it as the final answer
1106- if response_text and response_text . strip () and len ( response_text . strip ()) > 10 :
1163+ # Use intelligent differentiation between intermediate and final responses
1164+ if self . _is_final_answer ( response_text , bool ( tool_calls ), tool_results ) :
11071165 # LLM provided a final answer after tool execution, don't continue
11081166 final_response_text = response_text .strip ()
11091167 break
11101168
11111169 # 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
1170+ # Only generate summary if we're approaching max iterations or stuck in a loop
1171+ if self ._is_ollama_provider () and iteration_count >= 5 :
1172+ tool_summary = self ._generate_ollama_tool_summary (tool_results , response_text )
1173+ if tool_summary :
1174+ final_response_text = tool_summary
1175+ break
11161176
11171177 # Otherwise, continue the loop to check if more tools are needed
11181178 iteration_count += 1
@@ -1851,17 +1911,19 @@ async def get_response_async(
18511911 stored_reasoning_content = reasoning_content
18521912
18531913 # Check if the LLM provided a final answer alongside the tool calls
1854- # If response_text contains substantive content, treat it as the final answer
1855- if response_text and response_text . strip () and len ( response_text . strip ()) > 10 :
1914+ # Use intelligent differentiation between intermediate and final responses
1915+ if self . _is_final_answer ( response_text , bool ( tool_calls ), tool_results ) :
18561916 # LLM provided a final answer after tool execution, don't continue
18571917 final_response_text = response_text .strip ()
18581918 break
18591919
18601920 # 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
1921+ # Only generate summary if we're approaching max iterations or stuck in a loop
1922+ if self ._is_ollama_provider () and iteration_count >= 5 :
1923+ tool_summary = self ._generate_ollama_tool_summary (tool_results , response_text )
1924+ if tool_summary :
1925+ final_response_text = tool_summary
1926+ break
18651927
18661928 # Continue the loop to check if more tools are needed
18671929 iteration_count += 1
0 commit comments