working much simpler

This commit is contained in:
Dhanji Prasanna
2025-09-27 14:46:53 +10:00
parent 3c74cd410e
commit 7fbfec50d8
2 changed files with 101 additions and 80 deletions

View File

@@ -5,7 +5,7 @@ use g3_core::Agent;
use rustyline::error::ReadlineError; use rustyline::error::ReadlineError;
use rustyline::DefaultEditor; use rustyline::DefaultEditor;
use std::fs::OpenOptions; use std::fs::OpenOptions;
use std::io::{Write, BufWriter}; use std::io::{BufWriter, Write};
use std::path::PathBuf; use std::path::PathBuf;
use std::sync::{Arc, Mutex}; use std::sync::{Arc, Mutex};
use tokio_util::sync::CancellationToken; use tokio_util::sync::CancellationToken;
@@ -229,7 +229,10 @@ async fn run_autonomous(mut agent: Agent, show_prompt: bool, show_code: bool) ->
logger.log_section("G3 AUTONOMOUS MODE SESSION STARTED"); logger.log_section("G3 AUTONOMOUS MODE SESSION STARTED");
logger.log(&format!("🤖 G3 AI Coding Agent - Autonomous Mode")); logger.log(&format!("🤖 G3 AI Coding Agent - Autonomous Mode"));
logger.log(&format!("📁 Using workspace directory: {}", workspace_dir.display())); logger.log(&format!(
"📁 Using workspace directory: {}",
workspace_dir.display()
));
// Change to workspace directory // Change to workspace directory
std::env::set_current_dir(&workspace_dir)?; std::env::set_current_dir(&workspace_dir)?;
@@ -241,7 +244,9 @@ async fn run_autonomous(mut agent: Agent, show_prompt: bool, show_code: bool) ->
let requirements_path = workspace_dir.join("requirements.md"); let requirements_path = workspace_dir.join("requirements.md");
if !requirements_path.exists() { if !requirements_path.exists() {
logger.log("❌ Error: requirements.md not found in workspace directory"); logger.log("❌ Error: requirements.md not found in workspace directory");
logger.log(&format!(" Please create a requirements.md file with your project requirements at:")); logger.log(&format!(
" Please create a requirements.md file with your project requirements at:"
));
logger.log(&format!(" {}", requirements_path.display())); logger.log(&format!(" {}", requirements_path.display()));
return Ok(()); return Ok(());
} }
@@ -256,7 +261,10 @@ async fn run_autonomous(mut agent: Agent, show_prompt: bool, show_code: bool) ->
}; };
logger.log("📋 Requirements loaded from requirements.md"); logger.log("📋 Requirements loaded from requirements.md");
logger.log(&format!("Requirements: {}", logger.truncate_for_log(&requirements, 150))); logger.log(&format!(
"Requirements: {}",
logger.truncate_for_log(&requirements, 150)
));
// Check if there are existing project files (skip first player turn if so) // Check if there are existing project files (skip first player turn if so)
let has_existing_files = check_existing_project_files(&workspace_dir, &logger)?; let has_existing_files = check_existing_project_files(&workspace_dir, &logger)?;
@@ -272,7 +280,10 @@ async fn run_autonomous(mut agent: Agent, show_prompt: bool, show_code: bool) ->
loop { loop {
// Skip player turn if we have existing files and this is the first iteration // Skip player turn if we have existing files and this is the first iteration
if skip_player_turn { if skip_player_turn {
logger.log_section(&format!("TURN {}/{} - SKIPPING PLAYER MODE", turn, MAX_TURNS)); logger.log_section(&format!(
"TURN {}/{} - SKIPPING PLAYER MODE",
turn, MAX_TURNS
));
logger.log("📁 Existing project files detected, skipping to coach evaluation"); logger.log("📁 Existing project files detected, skipping to coach evaluation");
skip_player_turn = false; // Only skip the first turn skip_player_turn = false; // Only skip the first turn
} else { } else {
@@ -328,7 +339,8 @@ Review the current state of the project and provide a concise critique focusing
3. Specific improvements needed 3. Specific improvements needed
If the implementation correctly meets all requirements, respond with: 'IMPLEMENTATION_APPROVED' If the implementation correctly meets all requirements, respond with: 'IMPLEMENTATION_APPROVED'
If improvements are needed, provide specific actionable feedback. If improvements are needed, provide specific actionable feedback. Don't be overly critical. APPROVE the
implementation if it generally fits the bill, doesn't have compile errors or glaring omissions.
Keep your response concise and focused on actionable items.", Keep your response concise and focused on actionable items.",
requirements requirements
@@ -364,7 +376,10 @@ Keep your response concise and focused on actionable items.",
turn += 1; turn += 1;
logger.log("🔄 Coach provided feedback for next iteration"); logger.log("🔄 Coach provided feedback for next iteration");
logger.log(&format!("📝 Preparing to incorporate feedback in turn {}", turn)); logger.log(&format!(
"📝 Preparing to incorporate feedback in turn {}",
turn
));
logger.log(""); logger.log("");
} }
@@ -374,7 +389,10 @@ Keep your response concise and focused on actionable items.",
/// Check if there are existing project files in the workspace directory /// Check if there are existing project files in the workspace directory
/// Returns true if project files are found (excluding requirements.md and logs directory) /// Returns true if project files are found (excluding requirements.md and logs directory)
fn check_existing_project_files(workspace_dir: &PathBuf, logger: &AutonomousLogger) -> Result<bool> { fn check_existing_project_files(
workspace_dir: &PathBuf,
logger: &AutonomousLogger,
) -> Result<bool> {
logger.log("🔍 Checking for existing project files..."); logger.log("🔍 Checking for existing project files...");
let entries = match std::fs::read_dir(workspace_dir) { let entries = match std::fs::read_dir(workspace_dir) {
@@ -391,7 +409,8 @@ fn check_existing_project_files(workspace_dir: &PathBuf, logger: &AutonomousLogg
for entry in entries { for entry in entries {
let entry = entry?; let entry = entry?;
let path = entry.path(); let path = entry.path();
let file_name = path.file_name() let file_name = path
.file_name()
.and_then(|n| n.to_str()) .and_then(|n| n.to_str())
.unwrap_or("unknown"); .unwrap_or("unknown");
@@ -416,7 +435,11 @@ fn check_existing_project_files(workspace_dir: &PathBuf, logger: &AutonomousLogg
logger.log(&format!("📁 Found {} existing project files", total_files)); logger.log(&format!("📁 Found {} existing project files", total_files));
if !project_files.is_empty() { if !project_files.is_empty() {
let files_display = if total_files > 5 { let files_display = if total_files > 5 {
format!("{} (and {} more)", project_files.join(", "), total_files - 5) format!(
"{} (and {} more)",
project_files.join(", "),
total_files - 5
)
} else { } else {
project_files.join(", ") project_files.join(", ")
}; };
@@ -465,7 +488,10 @@ fn setup_workspace_directory() -> Result<PathBuf> {
// Create the directory if it doesn't exist // Create the directory if it doesn't exist
if !workspace_dir.exists() { if !workspace_dir.exists() {
std::fs::create_dir_all(&workspace_dir)?; std::fs::create_dir_all(&workspace_dir)?;
println!("📁 Created workspace directory: {}", workspace_dir.display()); println!(
"📁 Created workspace directory: {}",
workspace_dir.display()
);
} }
Ok(workspace_dir) Ok(workspace_dir)
@@ -564,5 +590,3 @@ impl AutonomousLogger {
} }
} }
} }

View File

@@ -1409,44 +1409,41 @@ The tool will execute immediately and you'll receive the result (success or erro
// Helper function to filter JSON tool calls from display content // Helper function to filter JSON tool calls from display content
fn filter_json_tool_calls(content: &str) -> String { fn filter_json_tool_calls(content: &str) -> String {
let mut filtered_content = String::new(); // Check if content contains any JSON tool call patterns
let mut in_json_tool_call = false; let patterns = [
r#"{"tool":"#,
r#"{ "tool":"#,
r#"{"tool" :"#,
r#"{ "tool" :"#,
];
for line in content.lines() { // Check if any pattern is found in the content
let trimmed_line = line.trim_start(); let has_tool_call_pattern = patterns.iter().any(|pattern| content.contains(pattern));
// Check if this line starts with a JSON tool call pattern if has_tool_call_pattern {
if trimmed_line.starts_with(r#"{"tool":"#) || // If we detect a JSON tool call pattern anywhere in the content,
trimmed_line.starts_with(r#"{ "tool":"#) || // replace the entire content with the indicator
trimmed_line.starts_with(r#"{"tool" :"#) || "<<tool call detected>>".to_string()
trimmed_line.starts_with(r#"{ "tool" :"#) { } else {
// This is the start of a JSON tool call // Check for partial JSON patterns that might be split across chunks
if !in_json_tool_call { let trimmed = content.trim();
// First line of JSON tool call - replace with indicator
if !filtered_content.is_empty() { // Check for partial patterns that might indicate the start of a JSON tool call
filtered_content.push('\n'); if trimmed.starts_with(r#"{"tool"#) ||
} trimmed.starts_with(r#"{ "tool"#) ||
filtered_content.push_str("<<tool call detected>>"); trimmed.starts_with(r#"{"#) && (trimmed.contains("tool") || trimmed.contains("args")) ||
in_json_tool_call = true; trimmed.contains(r#""tool":"#) ||
} trimmed.contains(r#""args":"#) ||
// Skip this line and any subsequent lines that are part of the JSON trimmed.contains(r#"file_path"#) ||
} else if in_json_tool_call { trimmed.contains(r#"command"#) ||
// Check if this line ends the JSON tool call (trimmed.starts_with('{') && trimmed.len() < 50 && (trimmed.contains("tool") || trimmed.contains("args"))) {
if trimmed_line.ends_with('}') || trimmed_line.trim() == "}" { // This looks like part of a JSON tool call, suppress it
// End of JSON tool call "".to_string()
in_json_tool_call = false;
}
// Skip this line (it's part of the JSON tool call)
} else { } else {
// Regular content line - add it // Regular content, return as-is
if !filtered_content.is_empty() { content.to_string()
filtered_content.push('\n');
}
filtered_content.push_str(line);
} }
} }
filtered_content
} }
// Helper function to properly escape shell commands // Helper function to properly escape shell commands