From 464352c664c0c059457b8cceafbaa3844011a1d9 Mon Sep 17 00:00:00 2001 From: Nikolas de Hor Date: Wed, 18 Feb 2026 21:29:10 -0300 Subject: [PATCH] fix: allow one retry for models that send interim text before tool calls Some LLM providers (MiniMax, Gemini Flash, GPT-4.1, etc.) send an initial text-only response like "Let me investigate..." before actually making tool calls. The agent loop previously broke immediately on any text response without tool calls, preventing these models from ever using tools. Now, when the model responds with text but hasn't used any tools yet, the loop forwards the text as progress to the user and gives the model one additional iteration to make tool calls. This is limited to a single retry to prevent infinite loops. Closes #705 --- nanobot/agent/loop.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/nanobot/agent/loop.py b/nanobot/agent/loop.py index e5a5183..6acbb38 100644 --- a/nanobot/agent/loop.py +++ b/nanobot/agent/loop.py @@ -183,6 +183,7 @@ class AgentLoop: iteration = 0 final_content = None tools_used: list[str] = [] + text_only_retried = False while iteration < self.max_iterations: iteration += 1 @@ -226,6 +227,21 @@ class AgentLoop: ) else: final_content = self._strip_think(response.content) + # Some models (MiniMax, Gemini Flash, GPT-4.1, etc.) send an + # interim text response (e.g. "Let me investigate...") before + # making tool calls. If no tools have been used yet and we + # haven't already retried, forward the text as progress and + # give the model one more chance to use tools. + if not tools_used and not text_only_retried and final_content: + text_only_retried = True + logger.debug(f"Interim text response (no tools used yet), retrying: {final_content[:80]}") + if on_progress: + await on_progress(final_content) + messages = self.context.add_assistant_message( + messages, response.content, + reasoning_content=response.reasoning_content, + ) + continue break return final_content, tools_used