go straight to coach turn if files exist
This commit is contained in:
@@ -256,15 +256,26 @@ 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 content:\n{}", requirements));
|
logger.log(&format!("Requirements: {}", logger.truncate_for_log(&requirements, 150)));
|
||||||
|
|
||||||
|
// Check if there are existing project files (skip first player turn if so)
|
||||||
|
let has_existing_files = check_existing_project_files(&workspace_dir, &logger)?;
|
||||||
|
|
||||||
logger.log("🔄 Starting coach-player feedback loop...");
|
logger.log("🔄 Starting coach-player feedback loop...");
|
||||||
logger.log("");
|
logger.log("");
|
||||||
|
|
||||||
const MAX_TURNS: usize = 5;
|
const MAX_TURNS: usize = 5;
|
||||||
let mut turn = 1;
|
let mut turn = 1;
|
||||||
let mut coach_feedback = String::new();
|
let mut coach_feedback = String::new();
|
||||||
|
let mut skip_player_turn = has_existing_files;
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
|
// Skip player turn if we have existing files and this is the first iteration
|
||||||
|
if skip_player_turn {
|
||||||
|
logger.log_section(&format!("TURN {}/{} - SKIPPING PLAYER MODE", turn, MAX_TURNS));
|
||||||
|
logger.log("📁 Existing project files detected, skipping to coach evaluation");
|
||||||
|
skip_player_turn = false; // Only skip the first turn
|
||||||
|
} else {
|
||||||
logger.log_section(&format!("TURN {}/{} - PLAYER MODE", turn, MAX_TURNS));
|
logger.log_section(&format!("TURN {}/{} - PLAYER MODE", turn, MAX_TURNS));
|
||||||
|
|
||||||
// Player mode: implement requirements (with coach feedback if available)
|
// Player mode: implement requirements (with coach feedback if available)
|
||||||
@@ -291,6 +302,7 @@ async fn run_autonomous(mut agent: Agent, show_prompt: bool, show_code: bool) ->
|
|||||||
|
|
||||||
logger.log("🎯 Player implementation completed");
|
logger.log("🎯 Player implementation completed");
|
||||||
logger.log("");
|
logger.log("");
|
||||||
|
}
|
||||||
|
|
||||||
// Create a new agent instance for coach mode to ensure fresh context
|
// Create a new agent instance for coach mode to ensure fresh context
|
||||||
// Make sure the coach agent also operates in the workspace directory
|
// Make sure the coach agent also operates in the workspace directory
|
||||||
@@ -360,6 +372,64 @@ Keep your response concise and focused on actionable items.",
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Check if there are existing project files in the workspace 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> {
|
||||||
|
logger.log("🔍 Checking for existing project files...");
|
||||||
|
|
||||||
|
let entries = match std::fs::read_dir(workspace_dir) {
|
||||||
|
Ok(entries) => entries,
|
||||||
|
Err(e) => {
|
||||||
|
logger.log(&format!("❌ Failed to read workspace directory: {}", e));
|
||||||
|
return Ok(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut project_files = Vec::new();
|
||||||
|
let mut total_files = 0;
|
||||||
|
|
||||||
|
for entry in entries {
|
||||||
|
let entry = entry?;
|
||||||
|
let path = entry.path();
|
||||||
|
let file_name = path.file_name()
|
||||||
|
.and_then(|n| n.to_str())
|
||||||
|
.unwrap_or("unknown");
|
||||||
|
|
||||||
|
// Skip requirements.md, logs directory, and hidden files
|
||||||
|
if file_name == "requirements.md" || file_name == "logs" || file_name.starts_with('.') {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
total_files += 1;
|
||||||
|
|
||||||
|
// Collect project files for logging (limit to first 5)
|
||||||
|
if project_files.len() < 5 {
|
||||||
|
if path.is_dir() {
|
||||||
|
project_files.push(format!("{}/", file_name));
|
||||||
|
} else {
|
||||||
|
project_files.push(file_name.to_string());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if total_files > 0 {
|
||||||
|
logger.log(&format!("📁 Found {} existing project files", total_files));
|
||||||
|
if !project_files.is_empty() {
|
||||||
|
let files_display = if total_files > 5 {
|
||||||
|
format!("{} (and {} more)", project_files.join(", "), total_files - 5)
|
||||||
|
} else {
|
||||||
|
project_files.join(", ")
|
||||||
|
};
|
||||||
|
logger.log(&format!(" Files: {}", files_display));
|
||||||
|
}
|
||||||
|
logger.log("⏭️ Will skip first player turn and evaluate existing implementation");
|
||||||
|
Ok(true)
|
||||||
|
} else {
|
||||||
|
logger.log("📂 No existing project files found, starting fresh implementation");
|
||||||
|
Ok(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn display_context_progress(agent: &Agent) {
|
fn display_context_progress(agent: &Agent) {
|
||||||
let context = agent.get_context_window();
|
let context = agent.get_context_window();
|
||||||
let percentage = context.percentage_used();
|
let percentage = context.percentage_used();
|
||||||
@@ -431,28 +501,67 @@ impl AutonomousLogger {
|
|||||||
Ok(Self { log_writer })
|
Ok(Self { log_writer })
|
||||||
}
|
}
|
||||||
|
|
||||||
fn log(&self, message: &str) {
|
/// Truncate text to a single line for logging
|
||||||
// Print to console
|
fn truncate_for_log(&self, text: &str, max_chars: usize) -> String {
|
||||||
println!("{}", message);
|
// First, get the first line only
|
||||||
|
let first_line = text.lines().next().unwrap_or("").trim();
|
||||||
|
|
||||||
// Write to log file with timestamp
|
// Then truncate if too long
|
||||||
|
if first_line.len() <= max_chars {
|
||||||
|
first_line.to_string()
|
||||||
|
} else {
|
||||||
|
format!("{}...", &first_line[..max_chars.saturating_sub(3)])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn log(&self, message: &str) {
|
||||||
|
// Ensure single line for console output
|
||||||
|
let single_line_message = self.truncate_for_log(message, 200);
|
||||||
|
|
||||||
|
// Print to console
|
||||||
|
println!("{}", single_line_message);
|
||||||
|
|
||||||
|
// Write to log file with timestamp (also single line)
|
||||||
if let Ok(mut writer) = self.log_writer.lock() {
|
if let Ok(mut writer) = self.log_writer.lock() {
|
||||||
let timestamp = chrono::Utc::now().format("%Y-%m-%d %H:%M:%S UTC");
|
let timestamp = chrono::Utc::now().format("%Y-%m-%d %H:%M:%S UTC");
|
||||||
let _ = writeln!(writer, "[{}] {}", timestamp, message);
|
let _ = writeln!(writer, "[{}] {}", timestamp, single_line_message);
|
||||||
let _ = writer.flush();
|
let _ = writer.flush();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn log_section(&self, section: &str) {
|
fn log_section(&self, section: &str) {
|
||||||
|
// Sections can be multi-line for visual separation, but content should be single line
|
||||||
|
let single_line_section = self.truncate_for_log(section, 100);
|
||||||
let separator = "=".repeat(80);
|
let separator = "=".repeat(80);
|
||||||
let message = format!("{}\n{}\n{}", separator, section, separator);
|
|
||||||
self.log(&message);
|
// Print to console with visual formatting
|
||||||
|
println!("{}", separator);
|
||||||
|
println!("{}", single_line_section);
|
||||||
|
println!("{}", separator);
|
||||||
|
|
||||||
|
// Log to file as single entries
|
||||||
|
if let Ok(mut writer) = self.log_writer.lock() {
|
||||||
|
let timestamp = chrono::Utc::now().format("%Y-%m-%d %H:%M:%S UTC");
|
||||||
|
let _ = writeln!(writer, "[{}] === {} ===", timestamp, single_line_section);
|
||||||
|
let _ = writer.flush();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn log_subsection(&self, subsection: &str) {
|
fn log_subsection(&self, subsection: &str) {
|
||||||
|
let single_line_subsection = self.truncate_for_log(subsection, 100);
|
||||||
let separator = "-".repeat(60);
|
let separator = "-".repeat(60);
|
||||||
let message = format!("{}\n{}\n{}", separator, subsection, separator);
|
|
||||||
self.log(&message);
|
// Print to console with visual formatting
|
||||||
|
println!("{}", separator);
|
||||||
|
println!("{}", single_line_subsection);
|
||||||
|
println!("{}", separator);
|
||||||
|
|
||||||
|
// Log to file as single entry
|
||||||
|
if let Ok(mut writer) = self.log_writer.lock() {
|
||||||
|
let timestamp = chrono::Utc::now().format("%Y-%m-%d %H:%M:%S UTC");
|
||||||
|
let _ = writeln!(writer, "[{}] --- {} ---", timestamp, single_line_subsection);
|
||||||
|
let _ = writer.flush();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user