Skip to main content

soma_core/cli/
custom_agent_config.rs

1// Custom Agent Configuration CLI for SOMA-CORE
2// Issue #30: Interactive interface for user-defined agent personalities and behavior modification
3// All comments in English (US) per coding_guidelines.md
4
5use crate::agents::custom_agent_config::{
6    CustomAgentConfigurationSystem, AgentPersonality, CodingStyle, RiskTolerance,
7    CommunicationStyle, PriorityWeights, ErrorHandlingStyle, FormattingPreferences,
8    IndentStyle, BraceStyle, UserAction, ProjectType
9};
10use crate::edit_control::ModifiableEdit;
11use std::io::{self, Write};
12use anyhow::Result;
13
14/// Interactive CLI for custom agent configuration
15pub struct CustomAgentConfigCLI {
16    config_system: CustomAgentConfigurationSystem,
17    current_view: ConfigView,
18}
19
20/// Different views in the configuration interface
21#[derive(Debug, Clone)]
22pub enum ConfigView {
23    MainMenu,
24    PersonalityManagement,
25    PersonalityCreation,
26    PreferenceLearning,
27    ProjectConfiguration,
28    AgentTesting,
29}
30
31impl CustomAgentConfigCLI {
32    /// Create a new configuration CLI
33    pub fn new() -> Result<Self> {
34        let config_dir = ".soma_config";
35        let mut config_system = CustomAgentConfigurationSystem::new(config_dir);
36        config_system.load_from_file()?;
37        
38        Ok(Self {
39            config_system,
40            current_view: ConfigView::MainMenu,
41        })
42    }
43
44    /// Start the interactive configuration session
45    pub fn start_interactive_session(&mut self) -> Result<()> {
46        self.print_welcome();
47        
48        loop {
49            match &self.current_view {
50                ConfigView::MainMenu => {
51                    if !self.handle_main_menu()? {
52                        break;
53                    }
54                }
55                ConfigView::PersonalityManagement => {
56                    self.handle_personality_management()?;
57                }
58                ConfigView::PersonalityCreation => {
59                    self.handle_personality_creation()?;
60                }
61                ConfigView::PreferenceLearning => {
62                    self.handle_preference_learning()?;
63                }
64                ConfigView::ProjectConfiguration => {
65                    self.handle_project_configuration()?;
66                }
67                ConfigView::AgentTesting => {
68                    self.handle_agent_testing()?;
69                }
70            }
71        }
72        
73        Ok(())
74    }
75
76    fn print_welcome(&self) {
77        println!("{}", "=".repeat(70));
78        println!("๐Ÿค– SOMA-CORE Custom Agent Configuration");
79        println!("{}", "=".repeat(70));
80        println!("Configure personalized AI agents for your development workflow!");
81        println!("Create custom personalities, set preferences, and optimize agent behavior.\n");
82    }
83
84    fn handle_main_menu(&mut self) -> Result<bool> {
85        println!("\n๐Ÿ“‹ Custom Agent Configuration - Main Menu");
86        println!("{}", "=".repeat(50));
87        println!("  [1] ๐ŸŽญ Personality Management");
88        println!("  [2] ๐Ÿ“Š Preference Learning & Analytics");
89        println!("  [3] ๐Ÿ—๏ธ  Project Configuration");
90        println!("  [4] ๐Ÿงช Agent Testing & Validation");
91        println!("  [5] ๐Ÿ“ˆ View Current Configuration");
92        println!("  [6] ๐Ÿ’พ Save & Export Configuration");
93        println!("  [0] ๐Ÿšช Exit");
94
95        print!("\nSelect option (0-6): ");
96        io::stdout().flush()?;
97
98        let mut input = String::new();
99        io::stdin().read_line(&mut input)?;
100
101        match input.trim() {
102            "1" => {
103                self.current_view = ConfigView::PersonalityManagement;
104                Ok(true)
105            }
106            "2" => {
107                self.current_view = ConfigView::PreferenceLearning;
108                Ok(true)
109            }
110            "3" => {
111                self.current_view = ConfigView::ProjectConfiguration;
112                Ok(true)
113            }
114            "4" => {
115                self.current_view = ConfigView::AgentTesting;
116                Ok(true)
117            }
118            "5" => {
119                self.show_current_configuration()?;
120                Ok(true)
121            }
122            "6" => {
123                self.save_and_export_configuration()?;
124                Ok(true)
125            }
126            "0" => {
127                println!("\n๐Ÿ‘‹ Configuration saved. Thank you for using SOMA-CORE!");
128                Ok(false)
129            }
130            _ => {
131                println!("โŒ Invalid option. Please try again.");
132                Ok(true)
133            }
134        }
135    }
136
137    fn handle_personality_management(&mut self) -> Result<()> {
138        println!("\n๐ŸŽญ Personality Management");
139        println!("{}", "=".repeat(30));
140        
141        let personalities = self.config_system.get_personalities();
142        
143        if personalities.is_empty() {
144            println!("No custom personalities found. Let's create your first one!");
145            self.current_view = ConfigView::PersonalityCreation;
146            return Ok(());
147        }
148
149        println!("Available personalities:");
150        let mut personality_list: Vec<_> = personalities.iter().collect();
151        personality_list.sort_by_key(|(name, _)| *name);
152        
153        for (i, (_name, personality)) in personality_list.iter().enumerate() {
154            println!("  [{}] {} - {}", i + 1, personality.name, personality.description);
155        }
156
157        println!("\nOptions:");
158        println!("  [c] Create new personality");
159        println!("  [s] Set active personality");
160        println!("  [b] Back to main menu");
161
162        print!("\nYour choice: ");
163        io::stdout().flush()?;
164
165        let mut input = String::new();
166        io::stdin().read_line(&mut input)?;
167
168        match input.trim().to_lowercase().as_str() {
169            "c" => {
170                self.current_view = ConfigView::PersonalityCreation;
171            }
172            "s" => {
173                self.set_active_personality()?;
174            }
175            "b" => {
176                self.current_view = ConfigView::MainMenu;
177            }
178            _ => {
179                println!("โŒ Invalid option. Please try again.");
180            }
181        }
182
183        Ok(())
184    }
185
186    fn handle_personality_creation(&mut self) -> Result<()> {
187        println!("\n๐ŸŽจ Create New Agent Personality");
188        println!("{}", "=".repeat(35));
189
190        // Get basic information
191        print!("Enter personality name: ");
192        io::stdout().flush()?;
193        let mut name = String::new();
194        io::stdin().read_line(&mut name)?;
195        let name = name.trim().to_string();
196
197        if name.is_empty() {
198            println!("โŒ Name cannot be empty. Returning to personality management.");
199            self.current_view = ConfigView::PersonalityManagement;
200            return Ok(());
201        }
202
203        print!("Enter description: ");
204        io::stdout().flush()?;
205        let mut description = String::new();
206        io::stdin().read_line(&mut description)?;
207        let description = description.trim().to_string();
208
209        // Get focus areas
210        println!("\nSelect focus areas (comma-separated):");
211        println!("  performance, readability, security, testing, documentation, architecture");
212        print!("Focus areas: ");
213        io::stdout().flush()?;
214        let mut focus_input = String::new();
215        io::stdin().read_line(&mut focus_input)?;
216        let focus_areas: Vec<String> = focus_input
217            .trim()
218            .split(',')
219            .map(|s| s.trim().to_string())
220            .filter(|s| !s.is_empty())
221            .collect();
222
223        // Get risk tolerance
224        println!("\nSelect risk tolerance:");
225        println!("  [1] Conservative - Only safe, well-tested changes");
226        println!("  [2] Moderate - Balance between safety and innovation");
227        println!("  [3] Aggressive - Bold improvements even if risky");
228        println!("  [4] Adaptive - Adjust based on project context");
229        print!("Risk tolerance (1-4): ");
230        io::stdout().flush()?;
231        let mut risk_input = String::new();
232        io::stdin().read_line(&mut risk_input)?;
233        
234        let risk_tolerance = match risk_input.trim() {
235            "1" => RiskTolerance::Conservative,
236            "2" => RiskTolerance::Moderate,
237            "3" => RiskTolerance::Aggressive,
238            "4" => RiskTolerance::Adaptive,
239            _ => RiskTolerance::Moderate,
240        };
241
242        // Get communication style
243        println!("\nSelect communication style:");
244        println!("  [1] Concise - Brief, to-the-point explanations");
245        println!("  [2] Detailed - Comprehensive explanations with examples");
246        println!("  [3] Tutorial - Educational style with learning focus");
247        println!("  [4] Professional - Formal, business-oriented tone");
248        println!("  [5] Friendly - Casual, approachable tone");
249        print!("Communication style (1-5): ");
250        io::stdout().flush()?;
251        let mut comm_input = String::new();
252        io::stdin().read_line(&mut comm_input)?;
253        
254        let communication_style = match comm_input.trim() {
255            "1" => CommunicationStyle::Concise,
256            "2" => CommunicationStyle::Detailed,
257            "3" => CommunicationStyle::Tutorial,
258            "4" => CommunicationStyle::Professional,
259            "5" => CommunicationStyle::Friendly,
260            _ => CommunicationStyle::Professional,
261        };
262
263        // Create priority weights
264        let priority_weights = self.configure_priority_weights()?;
265
266        // Create coding style
267        let coding_style = self.configure_coding_style()?;
268
269        // Create the personality
270        let personality = AgentPersonality {
271            name: name.clone(),
272            description,
273            focus_areas,
274            coding_style,
275            risk_tolerance,
276            communication_style,
277            priority_weights,
278        };
279
280        self.config_system.add_personality(name.clone(), personality);
281        self.config_system.save_to_file()?;
282
283        println!("\nโœ… Personality '{}' created successfully!", name);
284        println!("You can now test it or set it as active.");
285
286        self.current_view = ConfigView::PersonalityManagement;
287        Ok(())
288    }
289
290    fn configure_priority_weights(&self) -> Result<PriorityWeights> {
291        println!("\nโš–๏ธ  Configure Priority Weights (0.0 to 1.0, total should sum to 1.0):");
292        
293        let mut weights = PriorityWeights::default();
294        
295        print!("Performance weight [{}]: ", weights.performance);
296        io::stdout().flush()?;
297        let mut input = String::new();
298        io::stdin().read_line(&mut input)?;
299        if let Ok(val) = input.trim().parse::<f64>() {
300            weights.performance = val.clamp(0.0, 1.0);
301        }
302
303        print!("Readability weight [{}]: ", weights.readability);
304        io::stdout().flush()?;
305        input.clear();
306        io::stdin().read_line(&mut input)?;
307        if let Ok(val) = input.trim().parse::<f64>() {
308            weights.readability = val.clamp(0.0, 1.0);
309        }
310
311        print!("Maintainability weight [{}]: ", weights.maintainability);
312        io::stdout().flush()?;
313        input.clear();
314        io::stdin().read_line(&mut input)?;
315        if let Ok(val) = input.trim().parse::<f64>() {
316            weights.maintainability = val.clamp(0.0, 1.0);
317        }
318
319        print!("Security weight [{}]: ", weights.security);
320        io::stdout().flush()?;
321        input.clear();
322        io::stdin().read_line(&mut input)?;
323        if let Ok(val) = input.trim().parse::<f64>() {
324            weights.security = val.clamp(0.0, 1.0);
325        }
326
327        print!("Testing weight [{}]: ", weights.testing);
328        io::stdout().flush()?;
329        input.clear();
330        io::stdin().read_line(&mut input)?;
331        if let Ok(val) = input.trim().parse::<f64>() {
332            weights.testing = val.clamp(0.0, 1.0);
333        }
334
335        print!("Documentation weight [{}]: ", weights.documentation);
336        io::stdout().flush()?;
337        input.clear();
338        io::stdin().read_line(&mut input)?;
339        if let Ok(val) = input.trim().parse::<f64>() {
340            weights.documentation = val.clamp(0.0, 1.0);
341        }
342
343        // Normalize weights to sum to 1.0
344        let total = weights.performance + weights.readability + weights.maintainability 
345                   + weights.security + weights.testing + weights.documentation;
346        
347        if total > 0.0 {
348            weights.performance /= total;
349            weights.readability /= total;
350            weights.maintainability /= total;
351            weights.security /= total;
352            weights.testing /= total;
353            weights.documentation /= total;
354        }
355
356        println!("โœ… Weights normalized. Total: 1.0");
357        Ok(weights)
358    }
359
360    fn configure_coding_style(&self) -> Result<CodingStyle> {
361        println!("\n๐ŸŽจ Configure Coding Style Preferences:");
362        
363        // Verbose comments
364        print!("Prefer verbose comments? (y/n) [y]: ");
365        io::stdout().flush()?;
366        let mut input = String::new();
367        io::stdin().read_line(&mut input)?;
368        let prefers_verbose_comments = !matches!(input.trim().to_lowercase().as_str(), "n" | "no");
369
370        // Short functions
371        print!("Prefer short functions? (y/n) [y]: ");
372        io::stdout().flush()?;
373        input.clear();
374        io::stdin().read_line(&mut input)?;
375        let prefers_short_functions = !matches!(input.trim().to_lowercase().as_str(), "n" | "no");
376
377        // Explicit types
378        print!("Prefer explicit types? (y/n) [y]: ");
379        io::stdout().flush()?;
380        input.clear();
381        io::stdin().read_line(&mut input)?;
382        let prefers_explicit_types = !matches!(input.trim().to_lowercase().as_str(), "n" | "no");
383
384        // Error handling style
385        println!("Error handling style:");
386        println!("  [1] Explicit - Always use Result<T, E>");
387        println!("  [2] Panic - Use unwrap() and expect()");
388        println!("  [3] Optional - Use Option<T> where possible");
389        println!("  [4] Hybrid - Mix based on context");
390        print!("Choice (1-4) [1]: ");
391        io::stdout().flush()?;
392        input.clear();
393        io::stdin().read_line(&mut input)?;
394        
395        let prefers_error_handling = match input.trim() {
396            "2" => ErrorHandlingStyle::Panic,
397            "3" => ErrorHandlingStyle::Optional,
398            "4" => ErrorHandlingStyle::Hybrid,
399            _ => ErrorHandlingStyle::Explicit,
400        };
401
402        // Formatting preferences
403        print!("Maximum line length [100]: ");
404        io::stdout().flush()?;
405        input.clear();
406        io::stdin().read_line(&mut input)?;
407        let max_line_length = input.trim().parse().unwrap_or(100);
408
409        print!("Prefer single-line blocks? (y/n) [n]: ");
410        io::stdout().flush()?;
411        input.clear();
412        io::stdin().read_line(&mut input)?;
413        let prefer_single_line_blocks = matches!(input.trim().to_lowercase().as_str(), "y" | "yes");
414
415        let formatting_preferences = FormattingPreferences {
416            max_line_length,
417            prefer_single_line_blocks,
418            indent_style: IndentStyle::Spaces(4),
419            brace_style: BraceStyle::SameLine,
420        };
421
422        Ok(CodingStyle {
423            prefers_verbose_comments,
424            prefers_short_functions,
425            prefers_explicit_types,
426            prefers_error_handling,
427            formatting_preferences,
428        })
429    }
430
431    fn handle_preference_learning(&mut self) -> Result<()> {
432        println!("\n๐Ÿ“Š Preference Learning & Analytics");
433        println!("{}", "=".repeat(35));
434        println!("This feature tracks your interactions with agent suggestions");
435        println!("to continuously improve agent behavior and recommendations.");
436        
437        // Show current learning statistics
438        println!("\n๐Ÿ“ˆ Learning Statistics:");
439        println!("  โ€ข Total interactions: 0 (new system)");
440        println!("  โ€ข Acceptance rate: N/A");
441        println!("  โ€ข Most preferred suggestion types: Learning...");
442        println!("  โ€ข Confidence improvement: Baseline");
443        
444        println!("\n๐Ÿ”ง Learning Configuration:");
445        println!("  [1] Reset learning data");
446        println!("  [2] Export learning insights");
447        println!("  [3] Configure learning sensitivity");
448        println!("  [b] Back to main menu");
449        
450        print!("Your choice: ");
451        io::stdout().flush()?;
452        
453        let mut input = String::new();
454        io::stdin().read_line(&mut input)?;
455        
456        match input.trim() {
457            "1" => println!("๐Ÿ”„ Learning data reset (feature coming soon)"),
458            "2" => println!("๐Ÿ“ค Export insights (feature coming soon)"),
459            "3" => println!("โš™๏ธ  Configure sensitivity (feature coming soon)"),
460            "b" => self.current_view = ConfigView::MainMenu,
461            _ => println!("โŒ Invalid option"),
462        }
463        
464        Ok(())
465    }
466
467    fn handle_project_configuration(&mut self) -> Result<()> {
468        println!("\n๐Ÿ—๏ธ  Project Configuration");
469        println!("{}", "=".repeat(25));
470        println!("Configure agent behavior for specific projects and contexts.");
471        
472        println!("\nProject-specific settings:");
473        println!("  [1] Set project type and constraints");
474        println!("  [2] Configure team preferences");
475        println!("  [3] Set coding standards and guidelines");
476        println!("  [4] Configure review requirements");
477        println!("  [b] Back to main menu");
478        
479        print!("Your choice: ");
480        io::stdout().flush()?;
481        
482        let mut input = String::new();
483        io::stdin().read_line(&mut input)?;
484        
485        match input.trim() {
486            "1" => self.configure_project_type()?,
487            "2" => println!("๐Ÿ‘ฅ Team preferences (feature coming soon)"),
488            "3" => println!("๐Ÿ“‹ Coding standards (feature coming soon)"),
489            "4" => println!("๐Ÿ” Review requirements (feature coming soon)"),
490            "b" => self.current_view = ConfigView::MainMenu,
491            _ => println!("โŒ Invalid option"),
492        }
493        
494        Ok(())
495    }
496
497    fn configure_project_type(&self) -> Result<()> {
498        println!("\n๐ŸŽฏ Project Type Configuration");
499        println!("Select your project type:");
500        println!("  [1] Web Application");
501        println!("  [2] Library/Framework");
502        println!("  [3] System Tool/CLI");
503        println!("  [4] Game Development");
504        println!("  [5] Mobile Application");
505        println!("  [6] Data Science/Analytics");
506        println!("  [7] Machine Learning/AI");
507        println!("  [8] Embedded Systems");
508        println!("  [9] Other");
509        
510        print!("Project type (1-9): ");
511        io::stdout().flush()?;
512        
513        let mut input = String::new();
514        io::stdin().read_line(&mut input)?;
515        
516        let project_type = match input.trim() {
517            "1" => ProjectType::WebApplication,
518            "2" => ProjectType::Library,
519            "3" => ProjectType::SystemTool,
520            "4" => ProjectType::Game,
521            "5" => ProjectType::Mobile,
522            "6" => ProjectType::DataScience,
523            "7" => ProjectType::MachineLearning,
524            "8" => ProjectType::Embedded,
525            "9" => {
526                print!("Enter custom project type: ");
527                io::stdout().flush()?;
528                let mut custom = String::new();
529                io::stdin().read_line(&mut custom)?;
530                ProjectType::Other(custom.trim().to_string())
531            }
532            _ => ProjectType::Library,
533        };
534        
535        println!("โœ… Project type set to: {:?}", project_type);
536        Ok(())
537    }
538
539    fn handle_agent_testing(&mut self) -> Result<()> {
540        println!("\n๐Ÿงช Agent Testing & Validation");
541        println!("{}", "=".repeat(30));
542        println!("Test your configured agents with sample scenarios.");
543        
544        let personalities = self.config_system.get_personalities();
545        if personalities.is_empty() {
546            println!("โŒ No personalities available for testing.");
547            println!("Create a personality first in the Personality Management section.");
548            self.current_view = ConfigView::MainMenu;
549            return Ok(());
550        }
551        
552        println!("\nAvailable test scenarios:");
553        println!("  [1] Performance optimization scenario");
554        println!("  [2] Code readability improvement");
555        println!("  [3] Security vulnerability assessment");
556        println!("  [4] Custom test scenario");
557        println!("  [b] Back to main menu");
558        
559        print!("Select test (1-4, b): ");
560        io::stdout().flush()?;
561        
562        let mut input = String::new();
563        io::stdin().read_line(&mut input)?;
564        
565        match input.trim() {
566            "1" => self.run_performance_test()?,
567            "2" => self.run_readability_test()?,
568            "3" => self.run_security_test()?,
569            "4" => self.run_custom_test()?,
570            "b" => self.current_view = ConfigView::MainMenu,
571            _ => println!("โŒ Invalid option"),
572        }
573        
574        Ok(())
575    }
576
577    fn run_performance_test(&self) -> Result<()> {
578        println!("\nโšก Performance Optimization Test");
579        println!("Testing agent response to performance optimization scenarios...");
580        
581        // This would integrate with the actual CustomAgent implementation
582        println!("โœ… Test completed! Agent suggestions would appear here.");
583        println!("In a full implementation, this would show:");
584        println!("  โ€ข Agent's suggested optimizations");
585        println!("  โ€ข Confidence scores");
586        println!("  โ€ข Reasoning and explanations");
587        println!("  โ€ข Performance impact estimates");
588        
589        Ok(())
590    }
591
592    fn run_readability_test(&self) -> Result<()> {
593        println!("\n๐Ÿ“– Readability Improvement Test");
594        println!("Testing agent response to code clarity scenarios...");
595        println!("โœ… Test completed! Readability suggestions would appear here.");
596        Ok(())
597    }
598
599    fn run_security_test(&self) -> Result<()> {
600        println!("\n๐Ÿ”’ Security Assessment Test");
601        println!("Testing agent response to security scenarios...");
602        println!("โœ… Test completed! Security recommendations would appear here.");
603        Ok(())
604    }
605
606    fn run_custom_test(&self) -> Result<()> {
607        println!("\n๐ŸŽฏ Custom Test Scenario");
608        print!("Enter your test scenario description: ");
609        io::stdout().flush()?;
610        
611        let mut scenario = String::new();
612        io::stdin().read_line(&mut scenario)?;
613        
614        println!("โœ… Custom test '{}' completed!", scenario.trim());
615        println!("Agent response would be generated based on configured personality.");
616        Ok(())
617    }
618
619    fn set_active_personality(&mut self) -> Result<()> {
620        let personalities = self.config_system.get_personalities();
621        let personality_list: Vec<_> = personalities.keys().collect();
622        
623        if personality_list.is_empty() {
624            println!("No personalities available.");
625            return Ok(());
626        }
627        
628        println!("Select active personality:");
629        for (i, name) in personality_list.iter().enumerate() {
630            println!("  [{}] {}", i + 1, name);
631        }
632        
633        print!("Enter number: ");
634        io::stdout().flush()?;
635        
636        let mut input = String::new();
637        io::stdin().read_line(&mut input)?;
638        
639        if let Ok(index) = input.trim().parse::<usize>() {
640            if index > 0 && index <= personality_list.len() {
641                let selected = personality_list[index - 1].clone();
642                self.config_system.set_active_configuration(selected.clone());
643                self.config_system.save_to_file()?;
644                println!("โœ… Active personality set to: {}", selected);
645            } else {
646                println!("โŒ Invalid selection.");
647            }
648        } else {
649            println!("โŒ Invalid input.");
650        }
651        
652        Ok(())
653    }
654
655    fn show_current_configuration(&self) -> Result<()> {
656        println!("\n๐Ÿ“‹ Current Configuration");
657        println!("{}", "=".repeat(25));
658        
659        if let Some(active) = self.config_system.get_active_configuration() {
660            println!("๐ŸŽฏ Active Personality: {}", active);
661            
662            if let Some(personality) = self.config_system.get_personalities().get(active) {
663                println!("   Description: {}", personality.description);
664                println!("   Focus Areas: {}", personality.focus_areas.join(", "));
665                println!("   Risk Tolerance: {:?}", personality.risk_tolerance);
666                println!("   Communication: {:?}", personality.communication_style);
667                
668                println!("\nโš–๏ธ  Priority Weights:");
669                println!("   Performance: {:.2}", personality.priority_weights.performance);
670                println!("   Readability: {:.2}", personality.priority_weights.readability);
671                println!("   Maintainability: {:.2}", personality.priority_weights.maintainability);
672                println!("   Security: {:.2}", personality.priority_weights.security);
673                println!("   Testing: {:.2}", personality.priority_weights.testing);
674                println!("   Documentation: {:.2}", personality.priority_weights.documentation);
675            }
676        } else {
677            println!("โŒ No active personality set.");
678        }
679        
680        let total_personalities = self.config_system.get_personalities().len();
681        println!("\n๐Ÿ“Š Statistics:");
682        println!("   Total Personalities: {}", total_personalities);
683        println!("   Learning Data: Available");
684        println!("   Configuration Status: โœ… Loaded");
685        
686        Ok(())
687    }
688
689    fn save_and_export_configuration(&mut self) -> Result<()> {
690        println!("\n๐Ÿ’พ Save & Export Configuration");
691        println!("{}", "=".repeat(30));
692        
693        // Save current configuration
694        self.config_system.save_to_file()?;
695        println!("โœ… Configuration saved successfully!");
696        
697        println!("\nExport options:");
698        println!("  [1] Export to JSON file");
699        println!("  [2] Export personality summary");
700        println!("  [3] Export learning data");
701        println!("  [b] Back to main menu");
702        
703        print!("Your choice: ");
704        io::stdout().flush()?;
705        
706        let mut input = String::new();
707        io::stdin().read_line(&mut input)?;
708        
709        match input.trim() {
710            "1" => println!("๐Ÿ“„ JSON export (feature coming soon)"),
711            "2" => println!("๐Ÿ“‹ Personality summary export (feature coming soon)"),
712            "3" => println!("๐Ÿ“Š Learning data export (feature coming soon)"),
713            "b" => {},
714            _ => println!("โŒ Invalid option"),
715        }
716        
717        Ok(())
718    }
719
720    /// Record user interaction for preference learning
721    pub fn record_interaction(&mut self, edit: &ModifiableEdit, action: UserAction) -> Result<()> {
722        self.config_system.record_user_interaction(
723            edit.base_edit.reason.clone(),
724            format!("File: {}, Lines: {}-{}", 
725                edit.base_edit.file, 
726                edit.base_edit.line_range.0, 
727                edit.base_edit.line_range.1),
728            edit.base_edit.confidence,
729            action,
730            "current_project".to_string(),
731        );
732        
733        self.config_system.save_to_file()?;
734        Ok(())
735    }
736}
737
738/// Standalone function for quick agent configuration
739pub fn quick_agent_config() -> Result<()> {
740    let mut cli = CustomAgentConfigCLI::new()?;
741    cli.start_interactive_session()
742}