From da91459e09138888fd0283f6241e3c03aaa4d96d Mon Sep 17 00:00:00 2001 From: "Dhanji R. Prasanna" Date: Mon, 22 Dec 2025 16:45:17 +1100 Subject: [PATCH] Fix auto-continue bug: don't return early when tools executed but final_output not called The bug was in the chunk.finished block inside stream_completion_with_tools. When no tool was executed in the CURRENT iteration (!tool_executed), the code would return early without checking if tools were executed in PREVIOUS iterations (any_tool_executed) and final_output was never called. This caused the agent to terminate prematurely after executing tools like todo_read when the LLM responded with text instead of calling final_output. The fix adds a check: if any_tool_executed && !final_output_called, we break to let the outer loop's auto-continue logic prompt the LLM to continue. Also fixed missing debug! import in g3-console/src/main.rs. --- crates/g3-console/src/main.rs | 2 +- crates/g3-core/src/lib.rs | 11 +++++++++++ tmp/test_planner_ui.sh | 24 ------------------------ 3 files changed, 12 insertions(+), 25 deletions(-) delete mode 100755 tmp/test_planner_ui.sh diff --git a/crates/g3-console/src/main.rs b/crates/g3-console/src/main.rs index 50e7ee7..616b74f 100644 --- a/crates/g3-console/src/main.rs +++ b/crates/g3-console/src/main.rs @@ -16,7 +16,7 @@ use std::sync::Arc; use tokio::sync::Mutex; use tower_http::cors::CorsLayer; use tower_http::services::ServeDir; -use tracing::Level; +use tracing::{debug, Level}; use tracing_subscriber; #[derive(Parser, Debug)] diff --git a/crates/g3-core/src/lib.rs b/crates/g3-core/src/lib.rs index 2fb6d73..1f086ca 100644 --- a/crates/g3-core/src/lib.rs +++ b/crates/g3-core/src/lib.rs @@ -4884,6 +4884,17 @@ impl Agent { )); } + // If tools were executed in previous iterations but final_output wasn't called, + // break to let the outer loop's auto-continue logic handle it + if any_tool_executed && !final_output_called { + debug!("Tools were executed but final_output not called - breaking to auto-continue"); + // Add the text response to context before breaking + if has_text_response && !current_response.trim().is_empty() { + full_response = current_response.clone(); + } + break; + } + // Set full_response to current_response (don't append) // current_response already contains everything that was displayed // Don't set full_response here - it would duplicate the output diff --git a/tmp/test_planner_ui.sh b/tmp/test_planner_ui.sh deleted file mode 100755 index 9cdf019..0000000 --- a/tmp/test_planner_ui.sh +++ /dev/null @@ -1,24 +0,0 @@ -#!/bin/bash -set -e - -# Clean logs first -rm -rf ~/RustroverProjects/g3/logs/*.log ~/RustroverProjects/g3/logs/*.txt 2>/dev/null || true - -# Create test requirements file -mkdir -p /tmp/g3-test-planning/g3-plan -cat > /tmp/g3-test-planning/g3-plan/new_requirements.md <<'EOF' -Simple test task: List all .rs files in the src directory. -EOF - -# Initialize git repo for test (planning mode requires git) -cd /tmp/g3-test-planning -if [ ! -d .git ]; then - git init - git config user.name "Test User" - git config user.email "test@example.com" - git add . - git commit -m "Initial commit" || true -fi - -echo "Test environment ready at /tmp/g3-test-planning" -echo "Run: cd /tmp && ~/RustroverProjects/g3/target/release/g3 --planning --codepath /tmp/g3-test-planning --no-git"