main.rs
1 use clap::{Parser, Subcommand}; 2 use std::path::PathBuf; 3 4 mod agent; 5 mod cli; 6 mod config; 7 mod llm; 8 mod memory; 9 mod tools; 10 mod tui; 11 mod tui_enhanced; 12 13 #[derive(Parser)] 14 #[command(name = "kamaji")] 15 #[command(about = "A powerful CLI for interacting with LLMs with enhanced tools and agents")] 16 #[command(version = "1.1.4-rust-fixed")] 17 #[command(long_version = "kamaji 1.1.4-rust-fixed\nBuilt with Rust\nEnhanced with ReAct agents, streaming, and advanced tools\nTool execution fix applied")] 18 struct Cli { 19 #[command(subcommand)] 20 command: Commands, 21 } 22 23 #[derive(Subcommand)] 24 enum Commands { 25 /// Start beautiful TUI with agent tools 26 Tui { 27 #[arg(short, long)] 28 temperature: Option<f32>, 29 #[arg(short, long)] 30 work: bool, 31 }, 32 /// Start enhanced TUI with advanced features 33 Enhanced { 34 #[arg(short, long)] 35 temperature: Option<f32>, 36 #[arg(short, long)] 37 work: bool, 38 }, 39 /// Start interactive chat with enhanced features 40 Chat { 41 #[arg(short, long)] 42 temperature: Option<f32>, 43 }, 44 /// Ask a single question 45 Ask { 46 question: String, 47 #[arg(short, long)] 48 temperature: Option<f32>, 49 }, 50 /// Query documents using enhanced RAG 51 Rag { 52 question: String, 53 files: Vec<PathBuf>, 54 }, 55 /// Run agent with enhanced tools 56 Agent { 57 prompt: String, 58 }, 59 /// Start interactive agent with all tools 60 Interactive, 61 /// Calculator mode - evaluate math expressions 62 Calc { 63 expression: String, 64 }, 65 /// Create document index for search 66 Index { 67 files: Vec<PathBuf>, 68 }, 69 /// Search indexed documents 70 Search { 71 query: String, 72 }, 73 /// Memory commands 74 Memory { 75 #[command(subcommand)] 76 action: MemoryAction, 77 }, 78 /// Task management 79 Tasks { 80 #[command(subcommand)] 81 action: Option<TaskAction>, 82 }, 83 /// Analyze codebase and suggest improvements 84 Mature { 85 path: Option<String>, 86 }, 87 /// Work on tasks or projects 88 Work { 89 prompt: Option<String>, 90 }, 91 /// Add multiple tasks to queue 92 Queue { 93 tasks: String, 94 }, 95 /// Select and execute a task interactively 96 Do, 97 /// Show configuration 98 Config { 99 #[command(subcommand)] 100 action: Option<ConfigAction>, 101 }, 102 /// Update Kamaji 103 Update, 104 } 105 106 #[derive(Subcommand)] 107 enum ConfigAction { 108 Set { key: String, value: String }, 109 } 110 111 #[derive(Subcommand)] 112 enum MemoryAction { 113 /// Store information 114 Memorize { key: String, content: String, tags: Option<String> }, 115 /// Recall information 116 Remember { query: String }, 117 /// List all memories 118 List, 119 /// Delete a memory 120 Delete { key: String }, 121 /// Clear all memories 122 Clear, 123 } 124 125 #[derive(Subcommand)] 126 enum TaskAction { 127 /// Add a task 128 Add { task: String }, 129 /// List all tasks 130 List, 131 /// Clear all tasks 132 Clear, 133 } 134 135 #[tokio::main] 136 async fn main() -> anyhow::Result<()> { 137 let cli = Cli::parse(); 138 139 match cli.command { 140 Commands::Tui { temperature, work } => { 141 tui::run_tui(temperature, work).await?; 142 } 143 Commands::Enhanced { temperature, work } => { 144 tui_enhanced::run_enhanced_tui(temperature, work).await?; 145 } 146 Commands::Chat { temperature } => { 147 cli::run_chat(temperature).await?; 148 } 149 Commands::Ask { question, temperature } => { 150 cli::run_ask(&question, temperature).await?; 151 } 152 Commands::Rag { question, files } => { 153 cli::run_rag(&question, &files).await?; 154 } 155 Commands::Agent { prompt } => { 156 cli::run_agent(&prompt).await?; 157 } 158 Commands::Interactive => { 159 cli::run_interactive().await?; 160 } 161 Commands::Calc { expression } => { 162 match tools::calculator(&expression) { 163 Ok(result) => println!("📊 Result: {}", result), 164 Err(e) => eprintln!("❌ Error: {}", e), 165 } 166 } 167 Commands::Index { files } => { 168 let file_paths: Vec<String> = files.iter().map(|p| p.to_string_lossy().to_string()).collect(); 169 match tools::create_document_index(&file_paths) { 170 Ok(result) => println!("✅ {}", result), 171 Err(e) => eprintln!("❌ Error: {}", e), 172 } 173 } 174 Commands::Search { query } => { 175 match tools::search_documents(&query) { 176 Ok(results) => println!("🔍 Search Results:\n{}", results), 177 Err(e) => eprintln!("❌ Error: {}", e), 178 } 179 } 180 Commands::Memory { action } => { 181 match action { 182 MemoryAction::Memorize { key, content, tags } => { 183 let tag_str = tags.unwrap_or_default(); 184 match tools::memorize_info(&key, &content, &tag_str) { 185 Ok(result) => println!("{}", result), 186 Err(e) => eprintln!("❌ Error: {}", e), 187 } 188 } 189 MemoryAction::Remember { query } => { 190 match tools::remember_info(&query) { 191 Ok(result) => println!("{}", result), 192 Err(e) => eprintln!("❌ Error: {}", e), 193 } 194 } 195 MemoryAction::List => { 196 match tools::get_all_memories() { 197 Ok(result) => println!("{}", result), 198 Err(e) => eprintln!("❌ Error: {}", e), 199 } 200 } 201 MemoryAction::Delete { key } => { 202 match tools::delete_memory(&key) { 203 Ok(result) => println!("{}", result), 204 Err(e) => eprintln!("❌ Error: {}", e), 205 } 206 } 207 MemoryAction::Clear => { 208 match tools::clear_memories() { 209 Ok(result) => println!("{}", result), 210 Err(e) => eprintln!("❌ Error: {}", e), 211 } 212 } 213 } 214 } 215 Commands::Tasks { action } => { 216 match action { 217 Some(TaskAction::Add { task }) => { 218 match tools::add_task(&task) { 219 Ok(result) => println!("{}", result), 220 Err(e) => eprintln!("❌ Error: {}", e), 221 } 222 } 223 Some(TaskAction::List) | None => { 224 match tools::list_tasks() { 225 Ok(result) => println!("{}", result), 226 Err(e) => eprintln!("❌ Error: {}", e), 227 } 228 } 229 Some(TaskAction::Clear) => { 230 match tools::clear_tasks() { 231 Ok(result) => println!("{}", result), 232 Err(e) => eprintln!("❌ Error: {}", e), 233 } 234 } 235 } 236 } 237 Commands::Mature { path } => { 238 let analysis_path = path.unwrap_or_else(|| ".".to_string()); 239 match tools::analyze_codebase(&analysis_path) { 240 Ok(result) => println!("{}", result), 241 Err(e) => eprintln!("❌ Error: {}", e), 242 } 243 } 244 Commands::Work { prompt } => { 245 let work_prompt = prompt.unwrap_or_else(|| "Work on the current project and suggest improvements".to_string()); 246 cli::run_agent(&work_prompt).await?; 247 } 248 Commands::Queue { tasks } => { 249 let task_list: Vec<&str> = tasks.split(',').map(|s| s.trim()).collect(); 250 for task in task_list { 251 if !task.is_empty() { 252 match tools::add_task(task) { 253 Ok(result) => println!("{}", result), 254 Err(e) => eprintln!("❌ Error adding task '{}': {}", task, e), 255 } 256 } 257 } 258 match tools::list_tasks() { 259 Ok(result) => println!("\n{}", result), 260 Err(e) => eprintln!("❌ Error: {}", e), 261 } 262 } 263 Commands::Do => { 264 cli::run_do().await?; 265 } 266 Commands::Config { action } => { 267 match action { 268 Some(ConfigAction::Set { key, value }) => { 269 config::set_config(&key, &value)?; 270 } 271 None => { 272 config::show_config()?; 273 } 274 } 275 } 276 Commands::Update => { 277 println!("🔄 Update functionality not implemented yet"); 278 println!("💡 To update manually:"); 279 println!(" 1. git pull"); 280 println!(" 2. cargo build --release"); 281 println!(" 3. ./install.sh"); 282 } 283 } 284 285 Ok(()) 286 }