1#![allow(dead_code)] use crate::agents::gpt4_agent::{CognitiveAgent, ProposedEdit, Insight, ExecutionTrace};
8use crate::memory::SymbolicContext;
9use crate::dag::Node;
10use serde::{Deserialize, Serialize};
11use std::collections::HashMap;
12use std::fs;
13use std::path::Path;
14use anyhow::{anyhow, Result};
15
16#[derive(Debug, Clone, Serialize, Deserialize)]
18pub struct AgentPersonality {
19 pub name: String,
20 pub description: String,
21 pub focus_areas: Vec<String>,
22 pub coding_style: CodingStyle,
23 pub risk_tolerance: RiskTolerance,
24 pub communication_style: CommunicationStyle,
25 pub priority_weights: PriorityWeights,
26}
27
28#[derive(Debug, Clone, Serialize, Deserialize)]
30pub struct CodingStyle {
31 pub prefers_verbose_comments: bool,
32 pub prefers_short_functions: bool,
33 pub prefers_explicit_types: bool,
34 pub prefers_error_handling: ErrorHandlingStyle,
35 pub formatting_preferences: FormattingPreferences,
36}
37
38#[derive(Debug, Clone, Serialize, Deserialize)]
40pub enum ErrorHandlingStyle {
41 Explicit, Panic, Optional, Hybrid, }
46
47#[derive(Debug, Clone, Serialize, Deserialize)]
49pub struct FormattingPreferences {
50 pub max_line_length: usize,
51 pub prefer_single_line_blocks: bool,
52 pub indent_style: IndentStyle,
53 pub brace_style: BraceStyle,
54}
55
56#[derive(Debug, Clone, Serialize, Deserialize)]
58pub enum IndentStyle {
59 Spaces(usize),
60 Tabs,
61}
62
63#[derive(Debug, Clone, Serialize, Deserialize)]
65pub enum BraceStyle {
66 SameLine, NextLine, Mixed, }
70
71#[derive(Debug, Clone, Serialize, Deserialize)]
73pub enum RiskTolerance {
74 Conservative, Moderate, Aggressive, Adaptive, }
79
80#[derive(Debug, Clone, Serialize, Deserialize)]
82pub enum CommunicationStyle {
83 Concise, Detailed, Tutorial, Professional, Friendly, }
89
90#[derive(Debug, Clone, Serialize, Deserialize)]
92pub struct PriorityWeights {
93 pub performance: f64,
94 pub readability: f64,
95 pub maintainability: f64,
96 pub security: f64,
97 pub testing: f64,
98 pub documentation: f64,
99}
100
101#[derive(Debug, Clone, Serialize, Deserialize)]
103pub struct CustomPromptConfig {
104 pub base_prompt: String,
105 pub context_templates: HashMap<String, String>,
106 pub response_format_preferences: ResponseFormatPreferences,
107 pub custom_instructions: Vec<String>,
108}
109
110#[derive(Debug, Clone, Serialize, Deserialize)]
112pub struct ResponseFormatPreferences {
113 pub include_confidence_scores: bool,
114 pub include_reasoning_steps: bool,
115 pub include_alternative_options: bool,
116 pub preferred_explanation_length: ExplanationLength,
117}
118
119#[derive(Debug, Clone, Serialize, Deserialize)]
121pub enum ExplanationLength {
122 Minimal, Brief, Standard, Detailed, Comprehensive, }
128
129#[derive(Debug, Clone, Serialize, Deserialize)]
131pub struct PreferenceLearning {
132 pub accepted_suggestions: Vec<SuggestionRecord>,
133 pub rejected_suggestions: Vec<SuggestionRecord>,
134 pub modification_patterns: Vec<ModificationPattern>,
135 pub learned_preferences: LearnedPreferences,
136}
137
138#[derive(Debug, Clone, Serialize, Deserialize)]
140pub struct SuggestionRecord {
141 pub suggestion_type: String,
142 pub context: String,
143 pub confidence: f64,
144 pub user_action: UserAction,
145 pub timestamp: String,
146 pub project_context: String,
147}
148
149#[derive(Debug, Clone, Serialize, Deserialize)]
151pub enum UserAction {
152 Accepted,
153 Rejected,
154 Modified,
155 Deferred,
156}
157
158#[derive(Debug, Clone, Serialize, Deserialize)]
160pub struct ModificationPattern {
161 pub pattern_type: String,
162 pub frequency: usize,
163 pub description: String,
164 pub confidence: f64,
165}
166
167#[derive(Debug, Clone, Serialize, Deserialize)]
169pub struct LearnedPreferences {
170 pub preferred_suggestion_types: HashMap<String, f64>,
171 pub disliked_patterns: Vec<String>,
172 pub context_specific_preferences: HashMap<String, ContextualPreference>,
173 pub optimal_confidence_thresholds: HashMap<String, f64>,
174}
175
176#[derive(Debug, Clone, Serialize, Deserialize)]
178pub struct ContextualPreference {
179 pub context: String,
180 pub preference_adjustments: PriorityWeights,
181 pub specific_instructions: Vec<String>,
182}
183
184#[derive(Debug, Clone, Serialize, Deserialize)]
186pub struct ProjectContext {
187 pub project_name: String,
188 pub project_type: ProjectType,
189 pub languages: Vec<String>,
190 pub frameworks: Vec<String>,
191 pub coding_standards: Vec<String>,
192 pub specific_constraints: Vec<String>,
193 pub team_preferences: Option<TeamPreferences>,
194}
195
196#[derive(Debug, Clone, Serialize, Deserialize)]
198pub enum ProjectType {
199 WebApplication,
200 Library,
201 SystemTool,
202 Game,
203 Mobile,
204 DataScience,
205 MachineLearning,
206 Embedded,
207 Other(String),
208}
209
210#[derive(Debug, Clone, Serialize, Deserialize)]
212pub struct TeamPreferences {
213 pub shared_coding_style: CodingStyle,
214 pub review_requirements: ReviewRequirements,
215 pub testing_standards: TestingStandards,
216 pub documentation_requirements: DocumentationRequirements,
217}
218
219#[derive(Debug, Clone, Serialize, Deserialize)]
221pub struct ReviewRequirements {
222 pub require_peer_review: bool,
223 pub minimum_reviewers: usize,
224 pub require_security_review: bool,
225 pub require_performance_review: bool,
226}
227
228#[derive(Debug, Clone, Serialize, Deserialize)]
230pub struct TestingStandards {
231 pub minimum_coverage: f64,
232 pub require_unit_tests: bool,
233 pub require_integration_tests: bool,
234 pub test_naming_convention: String,
235}
236
237#[derive(Debug, Clone, Serialize, Deserialize)]
239pub struct DocumentationRequirements {
240 pub require_function_docs: bool,
241 pub require_module_docs: bool,
242 pub require_examples: bool,
243 pub documentation_style: DocumentationStyle,
244}
245
246#[derive(Debug, Clone, Serialize, Deserialize)]
248pub enum DocumentationStyle {
249 Minimal, Standard, Comprehensive, Tutorial, }
254
255pub struct CustomAgentConfigurationSystem {
257 personalities: HashMap<String, AgentPersonality>,
258 prompt_configs: HashMap<String, CustomPromptConfig>,
259 preference_learning: PreferenceLearning,
260 project_contexts: HashMap<String, ProjectContext>,
261 active_configuration: Option<String>,
262 config_file_path: String,
263}
264
265impl CustomAgentConfigurationSystem {
266 pub fn new(config_dir: &str) -> Self {
268 let config_file_path = format!("{}/agent_configurations.json", config_dir);
269
270 Self {
271 personalities: HashMap::new(),
272 prompt_configs: HashMap::new(),
273 preference_learning: PreferenceLearning::new(),
274 project_contexts: HashMap::new(),
275 active_configuration: None,
276 config_file_path,
277 }
278 }
279
280 pub fn load_from_file(&mut self) -> Result<()> {
282 if Path::new(&self.config_file_path).exists() {
283 let content = fs::read_to_string(&self.config_file_path)?;
284 let config: SavedConfiguration = serde_json::from_str(&content)?;
285
286 self.personalities = config.personalities;
287 self.prompt_configs = config.prompt_configs;
288 self.preference_learning = config.preference_learning;
289 self.project_contexts = config.project_contexts;
290 self.active_configuration = config.active_configuration;
291 } else {
292 self.create_default_personalities();
294 self.create_default_prompt_configs();
295 self.save_to_file()?;
296 }
297
298 Ok(())
299 }
300
301 pub fn save_to_file(&self) -> Result<()> {
303 let config = SavedConfiguration {
304 personalities: self.personalities.clone(),
305 prompt_configs: self.prompt_configs.clone(),
306 preference_learning: self.preference_learning.clone(),
307 project_contexts: self.project_contexts.clone(),
308 active_configuration: self.active_configuration.clone(),
309 };
310
311 let content = serde_json::to_string_pretty(&config)?;
312
313 if let Some(parent) = Path::new(&self.config_file_path).parent() {
315 fs::create_dir_all(parent)?;
316 }
317
318 fs::write(&self.config_file_path, content)?;
319 Ok(())
320 }
321
322 fn create_default_personalities(&mut self) {
324 let performance_agent = AgentPersonality {
326 name: "PerformanceOptimizer".to_string(),
327 description: "Focuses on code performance, efficiency, and optimization".to_string(),
328 focus_areas: vec![
329 "algorithm_optimization".to_string(),
330 "memory_usage".to_string(),
331 "cpu_efficiency".to_string(),
332 "caching_strategies".to_string(),
333 ],
334 coding_style: CodingStyle {
335 prefers_verbose_comments: false,
336 prefers_short_functions: true,
337 prefers_explicit_types: true,
338 prefers_error_handling: ErrorHandlingStyle::Explicit,
339 formatting_preferences: FormattingPreferences {
340 max_line_length: 100,
341 prefer_single_line_blocks: true,
342 indent_style: IndentStyle::Spaces(4),
343 brace_style: BraceStyle::SameLine,
344 },
345 },
346 risk_tolerance: RiskTolerance::Moderate,
347 communication_style: CommunicationStyle::Professional,
348 priority_weights: PriorityWeights {
349 performance: 0.4,
350 readability: 0.15,
351 maintainability: 0.2,
352 security: 0.1,
353 testing: 0.1,
354 documentation: 0.05,
355 },
356 };
357
358 let readability_agent = AgentPersonality {
360 name: "ReadabilityExpert".to_string(),
361 description: "Emphasizes code clarity, readability, and maintainability".to_string(),
362 focus_areas: vec![
363 "code_clarity".to_string(),
364 "naming_conventions".to_string(),
365 "code_structure".to_string(),
366 "documentation".to_string(),
367 ],
368 coding_style: CodingStyle {
369 prefers_verbose_comments: true,
370 prefers_short_functions: true,
371 prefers_explicit_types: true,
372 prefers_error_handling: ErrorHandlingStyle::Explicit,
373 formatting_preferences: FormattingPreferences {
374 max_line_length: 80,
375 prefer_single_line_blocks: false,
376 indent_style: IndentStyle::Spaces(4),
377 brace_style: BraceStyle::NextLine,
378 },
379 },
380 risk_tolerance: RiskTolerance::Conservative,
381 communication_style: CommunicationStyle::Tutorial,
382 priority_weights: PriorityWeights {
383 performance: 0.1,
384 readability: 0.4,
385 maintainability: 0.3,
386 security: 0.05,
387 testing: 0.1,
388 documentation: 0.05,
389 },
390 };
391
392 let security_agent = AgentPersonality {
394 name: "SecuritySpecialist".to_string(),
395 description: "Prioritizes security, safety, and robust error handling".to_string(),
396 focus_areas: vec![
397 "input_validation".to_string(),
398 "memory_safety".to_string(),
399 "secure_coding".to_string(),
400 "error_handling".to_string(),
401 ],
402 coding_style: CodingStyle {
403 prefers_verbose_comments: true,
404 prefers_short_functions: true,
405 prefers_explicit_types: true,
406 prefers_error_handling: ErrorHandlingStyle::Explicit,
407 formatting_preferences: FormattingPreferences {
408 max_line_length: 100,
409 prefer_single_line_blocks: false,
410 indent_style: IndentStyle::Spaces(4),
411 brace_style: BraceStyle::SameLine,
412 },
413 },
414 risk_tolerance: RiskTolerance::Conservative,
415 communication_style: CommunicationStyle::Detailed,
416 priority_weights: PriorityWeights {
417 performance: 0.1,
418 readability: 0.2,
419 maintainability: 0.2,
420 security: 0.4,
421 testing: 0.05,
422 documentation: 0.05,
423 },
424 };
425
426 self.personalities.insert("performance_optimizer".to_string(), performance_agent);
427 self.personalities.insert("readability_expert".to_string(), readability_agent);
428 self.personalities.insert("security_specialist".to_string(), security_agent);
429 }
430
431 fn create_default_prompt_configs(&mut self) {
433 let performance_prompt = CustomPromptConfig {
434 base_prompt: "You are a performance optimization expert. Focus on improving code efficiency, reducing memory usage, and optimizing algorithms. Always consider the performance implications of your suggestions.".to_string(),
435 context_templates: {
436 let mut templates = HashMap::new();
437 templates.insert("file_analysis".to_string(),
438 "Analyze the following code for performance optimization opportunities: {code}".to_string());
439 templates.insert("function_optimization".to_string(),
440 "Optimize this function for better performance: {function}".to_string());
441 templates
442 },
443 response_format_preferences: ResponseFormatPreferences {
444 include_confidence_scores: true,
445 include_reasoning_steps: true,
446 include_alternative_options: true,
447 preferred_explanation_length: ExplanationLength::Standard,
448 },
449 custom_instructions: vec![
450 "Always measure before optimizing".to_string(),
451 "Consider algorithmic complexity first".to_string(),
452 "Profile memory usage patterns".to_string(),
453 ],
454 };
455
456 let readability_prompt = CustomPromptConfig {
457 base_prompt: "You are a code readability expert. Focus on making code clear, well-documented, and easy to understand. Prioritize maintainability and developer experience.".to_string(),
458 context_templates: {
459 let mut templates = HashMap::new();
460 templates.insert("file_analysis".to_string(),
461 "Review the following code for readability improvements: {code}".to_string());
462 templates.insert("naming_review".to_string(),
463 "Suggest better naming for variables and functions in: {code}".to_string());
464 templates
465 },
466 response_format_preferences: ResponseFormatPreferences {
467 include_confidence_scores: false,
468 include_reasoning_steps: true,
469 include_alternative_options: true,
470 preferred_explanation_length: ExplanationLength::Detailed,
471 },
472 custom_instructions: vec![
473 "Prefer descriptive names over short ones".to_string(),
474 "Add comments for complex logic".to_string(),
475 "Break down large functions".to_string(),
476 ],
477 };
478
479 self.prompt_configs.insert("performance_optimizer".to_string(), performance_prompt);
480 self.prompt_configs.insert("readability_expert".to_string(), readability_prompt);
481 }
482
483 pub fn create_custom_agent(&self, personality_name: &str) -> Result<CustomAgent> {
485 let personality = self.personalities.get(personality_name)
486 .ok_or_else(|| anyhow!("Personality '{}' not found", personality_name))?;
487
488 let prompt_config = self.prompt_configs.get(personality_name);
489
490 Ok(CustomAgent {
491 personality: personality.clone(),
492 prompt_config: prompt_config.cloned(),
493 learned_preferences: self.preference_learning.learned_preferences.clone(),
494 })
495 }
496
497 pub fn add_personality(&mut self, name: String, personality: AgentPersonality) {
499 self.personalities.insert(name, personality);
500 }
501
502 pub fn record_user_interaction(&mut self, suggestion_type: String, context: String,
504 confidence: f64, action: UserAction, project_context: String) {
505 let record = SuggestionRecord {
506 suggestion_type: suggestion_type.clone(),
507 context,
508 confidence,
509 user_action: action.clone(),
510 timestamp: chrono::Utc::now().to_rfc3339(),
511 project_context,
512 };
513
514 match action {
515 UserAction::Accepted => self.preference_learning.accepted_suggestions.push(record),
516 UserAction::Rejected => self.preference_learning.rejected_suggestions.push(record),
517 _ => {} }
519
520 self.update_learned_preferences(&suggestion_type, &action);
522 }
523
524 fn update_learned_preferences(&mut self, suggestion_type: &str, action: &UserAction) {
526 let current_score = self.preference_learning.learned_preferences
527 .preferred_suggestion_types
528 .get(suggestion_type)
529 .unwrap_or(&0.5);
530
531 let adjustment = match action {
532 UserAction::Accepted => 0.1,
533 UserAction::Rejected => -0.1,
534 UserAction::Modified => 0.05,
535 UserAction::Deferred => -0.02,
536 };
537
538 let new_score = (current_score + adjustment).clamp(0.0, 1.0);
539 self.preference_learning.learned_preferences
540 .preferred_suggestion_types
541 .insert(suggestion_type.to_string(), new_score);
542 }
543
544 pub fn get_personalities(&self) -> &HashMap<String, AgentPersonality> {
546 &self.personalities
547 }
548
549 pub fn set_active_configuration(&mut self, personality_name: String) {
551 self.active_configuration = Some(personality_name);
552 }
553
554 pub fn get_active_configuration(&self) -> Option<&String> {
556 self.active_configuration.as_ref()
557 }
558}
559
560#[derive(Debug, Serialize, Deserialize)]
562struct SavedConfiguration {
563 personalities: HashMap<String, AgentPersonality>,
564 prompt_configs: HashMap<String, CustomPromptConfig>,
565 preference_learning: PreferenceLearning,
566 project_contexts: HashMap<String, ProjectContext>,
567 active_configuration: Option<String>,
568}
569
570pub struct CustomAgent {
572 personality: AgentPersonality,
573 prompt_config: Option<CustomPromptConfig>,
574 learned_preferences: LearnedPreferences,
575}
576
577impl CognitiveAgent for CustomAgent {
578 fn propose_edit(&self, ctx: &SymbolicContext) -> ProposedEdit {
579 let task = ctx.resolve_or_default("current_task", "general improvement");
580 let file = ctx.resolve_or_default("target_file", "src/main.rs");
581
582 let confidence_modifier = match self.personality.risk_tolerance {
584 RiskTolerance::Conservative => -0.1,
585 RiskTolerance::Moderate => 0.0,
586 RiskTolerance::Aggressive => 0.1,
587 RiskTolerance::Adaptive => self.calculate_adaptive_modifier(ctx),
588 };
589
590 let edit = if self.personality.focus_areas.contains(&"performance".to_string()) {
592 self.generate_performance_edit(&task, &file)
593 } else if self.personality.focus_areas.contains(&"code_clarity".to_string()) {
594 self.generate_readability_edit(&task, &file)
595 } else if self.personality.focus_areas.contains(&"input_validation".to_string()) {
596 self.generate_security_edit(&task, &file)
597 } else {
598 self.generate_general_edit(&task, &file)
599 };
600
601 let mut adjusted_edit = edit;
603 adjusted_edit.confidence = (adjusted_edit.confidence + confidence_modifier).clamp(0.0, 1.0);
604
605 if let Some(preference_score) = self.learned_preferences.preferred_suggestion_types.get(&adjusted_edit.reason) {
607 adjusted_edit.confidence = (adjusted_edit.confidence * preference_score).clamp(0.0, 1.0);
608 }
609
610 adjusted_edit
611 }
612
613 fn reason_about_code(&self, file: &str, lines: &[String]) -> Insight {
614 let analysis = self.analyze_code_with_personality(lines);
615
616 Insight {
617 summary: format!("{} analysis of {} ({} lines)",
618 self.personality.name, file, lines.len()),
619 details: analysis,
620 confidence: self.calculate_reasoning_confidence(lines),
621 }
622 }
623
624 fn simulate(&self, phase: &str, dag: &[Node]) -> Vec<ExecutionTrace> {
625 dag.iter()
626 .map(|node| ExecutionTrace {
627 phase: phase.to_string(),
628 node_id: node.id.clone(),
629 result: format!("{} simulation result", self.personality.name),
630 })
631 .collect()
632 }
633}
634
635impl CustomAgent {
636 fn calculate_adaptive_modifier(&self, _ctx: &SymbolicContext) -> f64 {
637 0.0
639 }
640
641 fn generate_performance_edit(&self, task: &str, file: &str) -> ProposedEdit {
642 ProposedEdit {
643 file: file.to_string(),
644 line_range: (10, 15),
645 new_code: format!("// {}: Performance optimization\n// {}\npub fn optimized_implementation() {{\n // More efficient approach\n}}",
646 self.personality.name, task),
647 reason: "performance_optimization".to_string(),
648 confidence: 0.85,
649 }
650 }
651
652 fn generate_readability_edit(&self, task: &str, file: &str) -> ProposedEdit {
653 ProposedEdit {
654 file: file.to_string(),
655 line_range: (20, 25),
656 new_code: format!("// {}: Readability improvement\n// {}\n/// Clear documentation for better understanding\npub fn well_documented_function() {{\n // Self-explanatory implementation\n}}",
657 self.personality.name, task),
658 reason: "readability_improvement".to_string(),
659 confidence: 0.90,
660 }
661 }
662
663 fn generate_security_edit(&self, task: &str, file: &str) -> ProposedEdit {
664 ProposedEdit {
665 file: file.to_string(),
666 line_range: (30, 35),
667 new_code: format!("// {}: Security enhancement\n// {}\npub fn secure_function(input: &str) -> Result<String, SecurityError> {{\n validate_input(input)?;\n // Secure processing\n Ok(processed_result)\n}}",
668 self.personality.name, task),
669 reason: "security_enhancement".to_string(),
670 confidence: 0.88,
671 }
672 }
673
674 fn generate_general_edit(&self, task: &str, file: &str) -> ProposedEdit {
675 ProposedEdit {
676 file: file.to_string(),
677 line_range: (40, 45),
678 new_code: format!("// {}: General improvement\n// {}\npub fn improved_function() {{\n // Enhanced implementation\n}}",
679 self.personality.name, task),
680 reason: "general_improvement".to_string(),
681 confidence: 0.75,
682 }
683 }
684
685 fn analyze_code_with_personality(&self, lines: &[String]) -> String {
686 let focus = self.personality.focus_areas.join(", ");
687 match self.personality.communication_style {
688 CommunicationStyle::Concise => format!("Focused on: {}", focus),
689 CommunicationStyle::Detailed => format!("Comprehensive analysis focusing on {}. Code structure appears well-organized with {} lines analyzed.", focus, lines.len()),
690 CommunicationStyle::Tutorial => format!("Let's examine this code with focus on {}. We have {} lines to analyze, which allows us to understand the structure and identify improvement opportunities.", focus, lines.len()),
691 CommunicationStyle::Professional => format!("Professional assessment: The code base consists of {} lines with analysis focus on {}. Initial review indicates standard implementation patterns.", lines.len(), focus),
692 CommunicationStyle::Friendly => format!("Hey! Looking at this code with {} in mind. We've got {} lines here - let's see what we can improve together!", focus, lines.len()),
693 }
694 }
695
696 fn calculate_reasoning_confidence(&self, lines: &[String]) -> f64 {
697 let base_confidence = match self.personality.risk_tolerance {
698 RiskTolerance::Conservative => 0.7,
699 RiskTolerance::Moderate => 0.8,
700 RiskTolerance::Aggressive => 0.9,
701 RiskTolerance::Adaptive => 0.75,
702 };
703
704 let complexity_factor: f64 = if lines.len() > 100 { -0.1 } else { 0.0 };
706
707 (base_confidence + complexity_factor).clamp(0.0, 1.0)
708 }
709}
710
711impl PreferenceLearning {
712 pub fn new() -> Self {
713 Self {
714 accepted_suggestions: Vec::new(),
715 rejected_suggestions: Vec::new(),
716 modification_patterns: Vec::new(),
717 learned_preferences: LearnedPreferences {
718 preferred_suggestion_types: HashMap::new(),
719 disliked_patterns: Vec::new(),
720 context_specific_preferences: HashMap::new(),
721 optimal_confidence_thresholds: HashMap::new(),
722 },
723 }
724 }
725}
726
727impl Default for PriorityWeights {
728 fn default() -> Self {
729 Self {
730 performance: 0.2,
731 readability: 0.2,
732 maintainability: 0.2,
733 security: 0.15,
734 testing: 0.15,
735 documentation: 0.1,
736 }
737 }
738}
739
740#[cfg(test)]
741mod tests {
742 use super::*;
743 use tempfile::TempDir;
744
745 #[test]
746 fn test_custom_agent_configuration_system_creation() {
747 let temp_dir = TempDir::new().unwrap();
748 let config_dir = temp_dir.path().to_str().unwrap();
749
750 let mut system = CustomAgentConfigurationSystem::new(config_dir);
751 assert!(system.load_from_file().is_ok());
752 assert_eq!(system.personalities.len(), 3); assert!(!system.personalities.is_empty());
754 }
755
756 #[test]
757 fn test_personality_creation_and_retrieval() {
758 let temp_dir = TempDir::new().unwrap();
759 let config_dir = temp_dir.path().to_str().unwrap();
760
761 let mut system = CustomAgentConfigurationSystem::new(config_dir);
762 system.load_from_file().unwrap();
763
764 let personalities = system.get_personalities();
766 assert!(personalities.contains_key("performance_optimizer"));
767 assert!(personalities.contains_key("readability_expert"));
768 assert!(personalities.contains_key("security_specialist"));
769 }
770
771 #[test]
772 fn test_custom_agent_creation() {
773 let temp_dir = TempDir::new().unwrap();
774 let config_dir = temp_dir.path().to_str().unwrap();
775
776 let mut system = CustomAgentConfigurationSystem::new(config_dir);
777 system.load_from_file().unwrap();
778
779 let agent = system.create_custom_agent("performance_optimizer").unwrap();
780 assert_eq!(agent.personality.name, "PerformanceOptimizer");
781 assert_eq!(agent.personality.priority_weights.performance, 0.4);
782 }
783
784 #[test]
785 fn test_user_interaction_recording() {
786 let temp_dir = TempDir::new().unwrap();
787 let config_dir = temp_dir.path().to_str().unwrap();
788
789 let mut system = CustomAgentConfigurationSystem::new(config_dir);
790 system.load_from_file().unwrap();
791
792 system.record_user_interaction(
793 "performance_optimization".to_string(),
794 "loop optimization".to_string(),
795 0.9,
796 UserAction::Accepted,
797 "rust_project".to_string(),
798 );
799
800 assert_eq!(system.preference_learning.accepted_suggestions.len(), 1);
801 let learned_score = system.preference_learning.learned_preferences
802 .preferred_suggestion_types
803 .get("performance_optimization")
804 .unwrap();
805 assert!(*learned_score > 0.5);
806 }
807
808 #[test]
809 fn test_save_and_load_configuration() {
810 let temp_dir = TempDir::new().unwrap();
811 let config_dir = temp_dir.path().to_str().unwrap();
812
813 let mut system = CustomAgentConfigurationSystem::new(config_dir);
814 system.load_from_file().unwrap();
815 system.set_active_configuration("performance_optimizer".to_string());
816
817 assert!(system.save_to_file().is_ok());
819
820 let mut new_system = CustomAgentConfigurationSystem::new(config_dir);
822 assert!(new_system.load_from_file().is_ok());
823 assert_eq!(new_system.get_active_configuration(), Some(&"performance_optimizer".to_string()));
824 }
825}