This commit is contained in:
Dhanji Prasanna
2025-09-06 13:46:12 +10:00
parent 1834b8946c
commit 10970566b1
2 changed files with 26 additions and 514 deletions

View File

@@ -1,4 +1,4 @@
use clap::{Parser, Subcommand};
use clap::Parser;
use g3_core::Agent;
use g3_config::Config;
use anyhow::Result;
@@ -9,9 +9,6 @@ use tracing::{info, error};
#[command(about = "A modular, composable AI coding agent")]
#[command(version)]
pub struct Cli {
#[command(subcommand)]
pub command: Option<Commands>,
/// Enable verbose logging
#[arg(short, long)]
pub verbose: bool,
@@ -27,79 +24,9 @@ pub struct Cli {
/// Configuration file path
#[arg(short, long)]
pub config: Option<String>,
}
#[derive(Subcommand)]
pub enum Commands {
/// Solve any task by writing and executing code
Task {
/// Description of the task to accomplish
description: String,
/// Programming language to prefer (auto-detect if not specified)
#[arg(short, long)]
language: Option<String>,
/// Execute the generated code automatically (default: ask for approval)
#[arg(short, long)]
execute: bool,
},
/// Create automation scripts for recurring tasks
Automate {
/// Description of the workflow to automate
workflow: String,
/// Output file for the automation script
#[arg(short, long)]
output: Option<String>,
},
/// Process and analyze data with code
Data {
/// Description of the data processing task
operation: String,
/// Input file or data source
#[arg(short, long)]
input: Option<String>,
/// Output format (json, csv, text)
#[arg(short = 'f', long, default_value = "text")]
format: String,
},
/// Web-related tasks (scraping, APIs, downloads)
Web {
/// Description of the web task
task: String,
/// Target URL (if applicable)
#[arg(short, long)]
url: Option<String>,
},
/// File system operations and management
File {
/// Description of the file operation
operation: String,
/// Target path
#[arg(short, long)]
path: Option<String>,
},
/// Legacy: Analyze code and provide insights
Analyze {
/// Path to analyze
path: String,
/// Output format (json, text)
#[arg(short, long, default_value = "text")]
format: String,
},
/// Legacy: Generate code based on description
Generate {
/// Description of what to generate
description: String,
/// Output file path
#[arg(short, long)]
output: Option<String>,
},
/// Legacy: Review code and suggest improvements
Review {
/// Path to review
path: String,
},
/// Interactive mode (default)
Interactive,
/// Task to execute (if provided, runs in single-shot mode instead of interactive)
pub task: Option<String>,
}
pub async fn run() -> Result<()> {
@@ -124,80 +51,24 @@ pub async fn run() -> Result<()> {
// Initialize agent
let agent = Agent::new(config).await?;
// Execute command - default to Interactive if no command provided
match cli.command.unwrap_or(Commands::Interactive) {
Commands::Task { description, language, execute } => {
info!("Executing task: {}", description);
let result = agent.execute_task(&description, language.as_deref(), execute).await?;
println!("{}", result);
}
Commands::Automate { workflow, output } => {
info!("Creating automation: {}", workflow);
let result = agent.create_automation(&workflow).await?;
if let Some(output_path) = output {
std::fs::write(&output_path, &result)?;
println!("Automation script written to: {}", output_path);
} else {
println!("{}", result);
}
}
Commands::Data { operation, input, format } => {
info!("Processing data: {}", operation);
let result = agent.process_data(&operation, input.as_deref()).await?;
match format.as_str() {
"json" => println!("{}", serde_json::to_string_pretty(&result)?),
_ => println!("{}", result),
}
}
Commands::Web { task, url } => {
info!("Web task: {}", task);
let result = agent.execute_web_task(&task, url.as_deref()).await?;
println!("{}", result);
}
Commands::File { operation, path } => {
info!("File operation: {}", operation);
let result = agent.execute_file_operation(&operation, path.as_deref()).await?;
println!("{}", result);
}
Commands::Analyze { path, format } => {
info!("Analyzing: {}", path);
let result = agent.analyze(&path).await?;
match format.as_str() {
"json" => println!("{}", serde_json::to_string_pretty(&result)?),
_ => println!("{}", result),
}
}
Commands::Generate { description, output } => {
info!("Generating code: {}", description);
let result = agent.generate(&description).await?;
if let Some(output_path) = output {
std::fs::write(&output_path, &result)?;
println!("Generated code written to: {}", output_path);
} else {
println!("{}", result);
}
}
Commands::Review { path } => {
info!("Reviewing: {}", path);
let result = agent.review(&path).await?;
println!("{}", result);
}
Commands::Interactive => {
info!("Starting interactive mode");
run_interactive(agent, cli.show_prompt, cli.show_code).await?;
}
// Execute task or start interactive mode
if let Some(task) = cli.task {
// Single-shot mode
info!("Executing task: {}", task);
let result = agent.execute_task_with_timing(&task, None, false, cli.show_prompt, cli.show_code, true).await?;
println!("{}", result);
} else {
// Interactive mode (default)
info!("Starting interactive mode");
run_interactive(agent, cli.show_prompt, cli.show_code).await?;
}
Ok(())
}
async fn run_interactive(agent: Agent, show_prompt: bool, show_code: bool) -> Result<()> {
println!("🤖 G3 General Purpose AI Agent - Interactive Mode");
println!("I solve problems by writing code. Tell me what you need to accomplish!");
println!("🤖 G3 AI Coding Agent - Interactive Mode");
println!("I solve problems by writing and executing code. Tell me what you need to accomplish!");
println!();
println!("Type 'exit' or 'quit' to exit");
println!();
@@ -219,32 +90,7 @@ async fn run_interactive(agent: Agent, show_prompt: bool, show_code: bool) -> Re
continue;
}
// Handle legacy commands
if let Some(path) = input.strip_prefix("analyze ") {
match agent.analyze(path).await {
Ok(result) => println!("{}", result),
Err(e) => error!("Error analyzing {}: {}", path, e),
}
continue;
}
if let Some(description) = input.strip_prefix("generate ") {
match agent.generate(description).await {
Ok(result) => println!("{}", result),
Err(e) => error!("Error generating code: {}", e),
}
continue;
}
if let Some(path) = input.strip_prefix("review ") {
match agent.review(path).await {
Ok(result) => println!("{}", result),
Err(e) => error!("Error reviewing {}: {}", path, e),
}
continue;
}
// Default to task execution (code-first approach)
// Execute task (code-first approach)
match agent.execute_task_with_timing(input, None, false, show_prompt, show_code, true).await {
Ok(response) => println!("{}", response),
Err(e) => error!("Error: {}", e),