use std::fs;
use anyhow::Result;
use brainwires_agents::validation_loop::{
ValidationCheck, ValidationConfig, ValidationSeverity, format_validation_feedback,
run_validation,
};
#[tokio::main]
async fn main() -> Result<()> {
println!("=== Validation Loop Demo ===\n");
let tmp_dir = tempfile::tempdir()?;
let tmp_path = tmp_dir.path().to_string_lossy().to_string();
let bad_file = tmp_dir.path().join("utils.ts");
let bad_content = r#"export function greet(name: string): string {
return `Hello, ${name}!`;
}
export function greet(name: string): string {
return `Hi, ${name}!`;
}
"#;
fs::write(&bad_file, bad_content)?;
println!(
"Created file with duplicate function: {}",
bad_file.display()
);
let config = ValidationConfig {
checks: vec![ValidationCheck::NoDuplicates, ValidationCheck::SyntaxValid],
working_directory: tmp_path.clone(),
max_retries: 3,
enabled: true,
working_set_files: vec!["utils.ts".to_string()],
};
println!("Validation config:");
println!(" Checks: {:?}", config.checks);
println!(" Working directory: {}", config.working_directory);
println!(" Max retries: {}", config.max_retries);
println!(" Working set files: {:?}", config.working_set_files);
println!("\n--- First validation run (expecting issues) ---");
let result = run_validation(&config).await?;
println!("Passed: {}", result.passed);
println!("Issues found: {}", result.issues.len());
for issue in &result.issues {
let severity = match issue.severity {
ValidationSeverity::Error => "ERROR",
ValidationSeverity::Warning => "WARN",
ValidationSeverity::Info => "INFO",
};
println!(" [{}] {}: {}", severity, issue.check, issue.message);
if let Some(file) = &issue.file {
print!(" File: {file}");
if let Some(line) = issue.line {
print!(" (line {line})");
}
println!();
}
}
let feedback = format_validation_feedback(&result);
println!("\nAgent feedback:\n{feedback}");
println!("--- Fixing the file ---");
let good_content = r#"export function greet(name: string): string {
return `Hello, ${name}!`;
}
export function farewell(name: string): string {
return `Goodbye, ${name}!`;
}
"#;
fs::write(&bad_file, good_content)?;
println!("Replaced duplicate function with unique 'farewell'");
println!("\n--- Second validation run (expecting pass) ---");
let result2 = run_validation(&config).await?;
println!("Passed: {}", result2.passed);
println!("Issues found: {}", result2.issues.len());
let feedback2 = format_validation_feedback(&result2);
println!("Agent feedback: {feedback2}");
println!("--- File existence check ---");
let missing_config = ValidationConfig {
checks: vec![],
working_directory: tmp_path.clone(),
max_retries: 1,
enabled: true,
working_set_files: vec!["nonexistent.rs".to_string()],
};
let missing_result = run_validation(&missing_config).await?;
println!("Passed (with missing file): {}", missing_result.passed);
for issue in &missing_result.issues {
println!(" [{}] {}", issue.check, issue.message);
}
println!("\n--- Summary ---");
println!("The validation loop prevents agents from reporting success when:");
println!(" - Files in the working set do not exist on disk (Bug #5)");
println!(" - Duplicate exports/functions/types are present");
println!(" - Basic syntax errors are detected");
println!(" - Build commands fail (when BuildSuccess check is enabled)");
println!("\nValidation loop demo complete.");
Ok(())
}