1use serde::Deserialize;
7use serde::Serialize;
8use std::collections::HashMap;
9use std::collections::HashSet;
10use thiserror::Error;
11
12#[derive(Debug, Clone, Serialize, Deserialize)]
14pub struct ToolRecommendation {
15 pub tool: String,
17 pub confidence: f32,
19 pub rationale: String,
21 pub priority: usize,
23}
24
25#[derive(Debug, Clone, Serialize, Deserialize)]
27pub struct StepDescription {
28 pub description: String,
30 pub expected_outcome: String,
32 pub next_conditions: Vec<String>,
34}
35
36#[derive(Debug, Clone, Serialize, Deserialize)]
38pub struct ThoughtData {
39 pub thought: String,
41 pub thought_number: usize,
43 pub total_thoughts: usize,
45 pub next_thought_needed: bool,
47 pub is_revision: bool,
49 pub revises_thought: Option<usize>,
51 pub branch_from_thought: Option<usize>,
53 pub branch_id: Option<String>,
55 pub recommended_tools: Vec<ToolRecommendation>,
57 pub current_step: Option<StepDescription>,
59 pub previous_steps: Vec<StepDescription>,
61 pub remaining_steps: Vec<String>,
63 pub confidence: f32,
65 pub timestamp: u64,
67}
68
69impl ThoughtData {
70 pub fn new(thought: String, thought_number: usize, total_thoughts: usize) -> Self {
72 Self {
73 thought,
74 thought_number,
75 total_thoughts,
76 next_thought_needed: thought_number < total_thoughts,
77 is_revision: false,
78 revises_thought: None,
79 branch_from_thought: None,
80 branch_id: None,
81 recommended_tools: Vec::new(),
82 current_step: None,
83 previous_steps: Vec::new(),
84 remaining_steps: Vec::new(),
85 confidence: 0.5,
86 timestamp: std::time::SystemTime::now()
87 .duration_since(std::time::UNIX_EPOCH)
88 .map(|d| d.as_secs())
89 .unwrap_or(0),
90 }
91 }
92
93 pub const fn as_revision(mut self, revises: usize) -> Self {
95 self.is_revision = true;
96 self.revises_thought = Some(revises);
97 self
98 }
99
100 pub fn with_branch(mut self, branch_from: usize, branch_id: String) -> Self {
102 self.branch_from_thought = Some(branch_from);
103 self.branch_id = Some(branch_id);
104 self
105 }
106
107 pub fn with_tools(mut self, tools: Vec<ToolRecommendation>) -> Self {
109 self.recommended_tools = tools;
110 self
111 }
112
113 pub const fn with_confidence(mut self, confidence: f32) -> Self {
115 self.confidence = confidence.max(0.0).min(1.0);
116 self
117 }
118}
119
120#[derive(Debug, Clone, Serialize, Deserialize)]
122pub struct ThinkSession {
123 pub thought_history: Vec<ThoughtData>,
125 pub branches: HashMap<String, Vec<ThoughtData>>,
127 pub max_history_size: usize,
129 pub session_id: String,
131 pub active_branch: Option<String>,
133 pub total_thought_count: usize,
135 pub created_at: u64,
137 pub last_activity: u64,
139}
140
141impl ThinkSession {
142 pub fn new(max_history_size: usize) -> Self {
144 let now = std::time::SystemTime::now()
145 .duration_since(std::time::UNIX_EPOCH)
146 .map(|d| d.as_secs())
147 .unwrap_or(0);
148
149 Self {
150 thought_history: Vec::new(),
151 branches: HashMap::new(),
152 max_history_size,
153 session_id: format!("think_{}", now),
154 active_branch: None,
155 total_thought_count: 0,
156 created_at: now,
157 last_activity: now,
158 }
159 }
160
161 pub fn add_thought(&mut self, thought: ThoughtData) {
163 self.total_thought_count += 1;
164 self.last_activity = std::time::SystemTime::now()
165 .duration_since(std::time::UNIX_EPOCH)
166 .map(|d| d.as_secs())
167 .unwrap_or(0);
168
169 if let Some(branch_id) = &self.active_branch {
170 self.branches
172 .entry(branch_id.clone())
173 .or_default()
174 .push(thought);
175
176 if let Some(branch) = self.branches.get_mut(branch_id) {
178 while branch.len() > self.max_history_size {
179 branch.remove(0);
180 }
181 }
182 } else {
183 self.thought_history.push(thought);
185
186 while self.thought_history.len() > self.max_history_size {
188 self.thought_history.remove(0);
189 }
190 }
191 }
192
193 pub fn create_branch(&mut self, from_thought: usize, branch_id: String) {
195 let branch_point = if let Some(branch_id) = &self.active_branch {
196 self.branches
198 .get(branch_id)
199 .and_then(|b| b.get(from_thought))
200 .cloned()
201 } else {
202 self.thought_history.get(from_thought).cloned()
204 };
205
206 if let Some(thought) = branch_point {
207 let mut branch_history = vec![thought];
208 branch_history[0].branch_from_thought = Some(from_thought);
209 branch_history[0].branch_id = Some(branch_id.clone());
210 self.branches.insert(branch_id.clone(), branch_history);
211 self.active_branch = Some(branch_id);
212 }
213 }
214
215 pub fn switch_branch(&mut self, branch_id: Option<String>) {
217 self.active_branch = branch_id;
218 }
219
220 pub fn current_history(&self) -> &[ThoughtData] {
222 if let Some(branch_id) = &self.active_branch {
223 self.branches
224 .get(branch_id)
225 .map(Vec::as_slice)
226 .unwrap_or(&[])
227 } else {
228 &self.thought_history
229 }
230 }
231
232 pub fn find_thought_to_revise(&self, thought_number: usize) -> Option<&ThoughtData> {
234 self.current_history()
235 .iter()
236 .find(|t| t.thought_number == thought_number)
237 }
238
239 pub fn get_revisions(&self) -> Vec<&ThoughtData> {
241 self.current_history()
242 .iter()
243 .filter(|t| t.is_revision)
244 .collect()
245 }
246
247 pub fn get_high_confidence_thoughts(&self, threshold: f32) -> Vec<&ThoughtData> {
249 self.current_history()
250 .iter()
251 .filter(|t| t.confidence >= threshold)
252 .collect()
253 }
254
255 pub fn get_all_recommended_tools(&self) -> Vec<&ToolRecommendation> {
257 self.current_history()
258 .iter()
259 .flat_map(|t| &t.recommended_tools)
260 .collect()
261 }
262
263 pub fn needs_more_thoughts(&self) -> bool {
265 self.current_history()
266 .last()
267 .map(|t| t.next_thought_needed)
268 .unwrap_or(true)
269 }
270}
271
272impl Default for ThinkSession {
273 fn default() -> Self {
274 Self::new(100) }
276}
277
278#[derive(Debug, Error)]
279pub enum ThinkError {
280 #[error("problem description is empty or too short")]
281 EmptyProblem,
282
283 #[error("failed to generate reasoning steps: {0}")]
284 ReasoningFailed(String),
285
286 #[error("confidence calculation error: {0}")]
287 ConfidenceError(String),
288}
289
290#[derive(Debug, Clone, Serialize, Deserialize)]
292pub struct ThinkStep {
293 pub step_number: usize,
295 pub thought: String,
297 pub reasoning: String,
299}
300
301#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
303pub enum Complexity {
304 Simple, Medium, Complex, }
308
309#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
311pub enum CodeProblemType {
312 BugFix, Refactoring, Implementation, Performance, Security, Testing, Documentation, Architecture, CodeReview, }
322
323#[derive(Debug, Clone, Serialize, Deserialize)]
325pub struct CodeThinkResult {
326 pub steps: Vec<ThinkStep>,
328 pub conclusion: String,
330 pub confidence: f32,
332 pub recommended_action: String,
334 pub affected_files: Vec<String>,
336 pub complexity: Complexity,
338 pub problem_type: CodeProblemType,
340}
341
342#[derive(Debug, Clone, Serialize, Deserialize)]
344pub struct ThinkResult {
345 pub steps: Vec<ThinkStep>,
347 pub conclusion: String,
349 pub confidence: f32,
351 pub thought_data: Option<ThoughtData>,
353}
354
355#[derive(Debug)]
357pub struct ThinkTool {
358 pub session: Option<ThinkSession>,
360}
361
362impl ThinkTool {
363 pub const fn new() -> Self {
365 Self { session: None }
366 }
367
368 pub fn with_session(max_history_size: usize) -> Self {
370 Self {
371 session: Some(ThinkSession::new(max_history_size)),
372 }
373 }
374
375 pub fn process_thought(
377 &mut self,
378 thought: String,
379 thought_number: usize,
380 total_thoughts: usize,
381 next_thought_needed: bool,
382 is_revision: Option<bool>,
383 revises_thought: Option<usize>,
384 ) -> Result<ThinkResult, ThinkError> {
385 let recommended_tools = self.analyze_for_tool_recommendations(&thought);
387
388 let mut thought_data = ThoughtData::new(thought.clone(), thought_number, total_thoughts)
390 .with_tools(recommended_tools);
391
392 if let Some(true) = is_revision {
394 thought_data.is_revision = true;
395 thought_data.revises_thought = revises_thought;
396 }
397
398 thought_data.next_thought_needed = next_thought_needed;
400
401 if let Some(ref mut session) = self.session {
403 session.add_thought(thought_data.clone());
404 }
405
406 let steps = vec![ThinkStep {
408 step_number: thought_number,
409 thought: thought.clone(),
410 reasoning: format!(
411 "Processing thought {} of {}",
412 thought_number, total_thoughts
413 ),
414 }];
415
416 let conclusion = if next_thought_needed {
417 format!(
418 "Thought {} processed. More thoughts needed.",
419 thought_number
420 )
421 } else {
422 format!("Thought {} processed. Thinking complete.", thought_number)
423 };
424
425 Ok(ThinkResult {
426 steps,
427 conclusion,
428 confidence: 0.7, thought_data: Some(thought_data),
430 })
431 }
432
433 fn analyze_for_tool_recommendations(&self, thought: &str) -> Vec<ToolRecommendation> {
435 let mut recommendations = Vec::new();
436 let thought_lower = thought.to_lowercase();
437 let mut priority = 1;
438
439 if thought_lower.contains("search")
441 || thought_lower.contains("find")
442 || thought_lower.contains("look")
443 || thought_lower.contains("locate")
444 || thought_lower.contains("discover")
445 {
446 recommendations.push(ToolRecommendation {
447 tool: "search".to_string(),
448 confidence: 0.9,
449 rationale: "Thought indicates need for code search or discovery".to_string(),
450 priority,
451 });
452 priority += 1;
453 }
454
455 if thought_lower.contains("edit")
457 || thought_lower.contains("modify")
458 || thought_lower.contains("change")
459 || thought_lower.contains("update")
460 || thought_lower.contains("fix")
461 || thought_lower.contains("correct")
462 {
463 recommendations.push(ToolRecommendation {
464 tool: "edit".to_string(),
465 confidence: 0.85,
466 rationale: "Thought suggests code modification needed".to_string(),
467 priority,
468 });
469 priority += 1;
470 }
471
472 if thought_lower.contains("refactor")
474 || thought_lower.contains("rename")
475 || thought_lower.contains("restructure")
476 || thought_lower.contains("reorganize")
477 || thought_lower.contains("extract")
478 {
479 recommendations.push(ToolRecommendation {
480 tool: "patch".to_string(),
481 confidence: 0.9,
482 rationale: "Thought indicates structural code changes".to_string(),
483 priority,
484 });
485 priority += 1;
486 }
487
488 if thought_lower.contains("test")
490 || thought_lower.contains("verify")
491 || thought_lower.contains("validate")
492 || thought_lower.contains("check")
493 || thought_lower.contains("ensure")
494 {
495 recommendations.push(ToolRecommendation {
496 tool: "test".to_string(),
497 confidence: 0.8,
498 rationale: "Thought suggests verification or testing needed".to_string(),
499 priority,
500 });
501 priority += 1;
502 }
503
504 if thought_lower.contains("parse")
506 || thought_lower.contains("ast")
507 || thought_lower.contains("syntax")
508 || thought_lower.contains("structure")
509 || thought_lower.contains("analyze")
510 {
511 recommendations.push(ToolRecommendation {
512 tool: "tree".to_string(),
513 confidence: 0.75,
514 rationale: "Thought indicates need for AST or structural analysis".to_string(),
515 priority,
516 });
517 priority += 1;
518 }
519
520 if thought_lower.contains("index")
522 || thought_lower.contains("catalog")
523 || thought_lower.contains("organize")
524 || thought_lower.contains("scan")
525 {
526 recommendations.push(ToolRecommendation {
527 tool: "index".to_string(),
528 confidence: 0.7,
529 rationale: "Thought suggests indexing or cataloging needed".to_string(),
530 priority,
531 });
532 priority += 1;
533 }
534
535 if thought_lower.contains("file")
537 || thought_lower.contains("files")
538 || thought_lower.contains("directory")
539 || thought_lower.contains("folder")
540 || thought_lower.contains("glob")
541 {
542 recommendations.push(ToolRecommendation {
543 tool: "glob".to_string(),
544 confidence: 0.75,
545 rationale: "Thought indicates file system operations".to_string(),
546 priority,
547 });
548 priority += 1;
549 }
550
551 if thought_lower.contains("plan")
553 || thought_lower.contains("decompose")
554 || thought_lower.contains("break down")
555 || thought_lower.contains("strategy")
556 || thought_lower.contains("approach")
557 {
558 recommendations.push(ToolRecommendation {
559 tool: "plan".to_string(),
560 confidence: 0.8,
561 rationale: "Thought suggests need for task planning".to_string(),
562 priority,
563 });
564 }
565
566 recommendations.sort_by_key(|r| r.priority);
568
569 recommendations
570 }
571
572 pub fn think(question: &str) -> Result<ThinkResult, ThinkError> {
574 if question.trim().is_empty() || question.len() < 5 {
575 return Err(ThinkError::EmptyProblem);
576 }
577
578 let steps = Self::generate_reasoning_steps(question)?;
579 let conclusion = Self::generate_conclusion(question, &steps);
580 let confidence = Self::calculate_confidence(question, &steps);
581
582 Ok(ThinkResult {
583 steps,
584 conclusion,
585 confidence,
586 thought_data: None,
587 })
588 }
589
590 pub fn think_about_code(
592 problem: &str,
593 language: Option<&str>,
594 context: Option<&str>, ) -> Result<CodeThinkResult, ThinkError> {
596 if problem.trim().is_empty() || problem.len() < 5 {
597 return Err(ThinkError::EmptyProblem);
598 }
599
600 let problem_type = Self::classify_code_problem(problem);
601 let complexity = Self::assess_complexity(problem, language, context);
602 let steps = Self::generate_code_reasoning_steps(problem, &problem_type, language, context)?;
603 let conclusion = Self::generate_code_conclusion(problem, &steps, &problem_type);
604 let confidence = Self::calculate_code_confidence(problem, &steps, &problem_type);
605 let recommended_action = Self::determine_recommended_action(&problem_type, problem);
606 let affected_files = Self::identify_affected_files(problem, context);
607
608 Ok(CodeThinkResult {
609 steps,
610 conclusion,
611 confidence,
612 recommended_action,
613 affected_files,
614 complexity,
615 problem_type,
616 })
617 }
618
619 pub fn analyze_error(error_message: &str) -> Result<CodeThinkResult, ThinkError> {
621 if error_message.trim().is_empty() {
622 return Err(ThinkError::EmptyProblem);
623 }
624
625 let _problem = format!("Debug and fix error: {}", error_message);
626 let steps = Self::generate_error_analysis_steps(error_message)?;
627 let recommended_action = Self::determine_error_action(error_message);
628 let affected_files = Self::extract_files_from_error(error_message);
629 let complexity = if affected_files.len() > 2 {
630 Complexity::Complex
631 } else if affected_files.len() > 1 {
632 Complexity::Medium
633 } else {
634 Complexity::Simple
635 };
636
637 Ok(CodeThinkResult {
638 steps,
639 conclusion: "Systematic error analysis completed with specific debugging steps."
640 .to_string(),
641 confidence: 0.8,
642 recommended_action,
643 affected_files,
644 complexity,
645 problem_type: CodeProblemType::BugFix,
646 })
647 }
648
649 pub fn plan_refactoring(code_smell: &str) -> Result<CodeThinkResult, ThinkError> {
651 if code_smell.trim().is_empty() {
652 return Err(ThinkError::EmptyProblem);
653 }
654
655 let _problem = format!("Refactor to address: {}", code_smell);
656 let steps = Self::generate_refactoring_steps(code_smell)?;
657 let recommended_action = "Implement refactoring strategy".to_string();
658 let _complexity = 5; Ok(CodeThinkResult {
661 steps,
662 conclusion: "Refactoring strategy defined with clear improvement goals.".to_string(),
663 confidence: 0.85,
664 recommended_action,
665 affected_files: vec![], complexity: Complexity::Medium,
667 problem_type: CodeProblemType::Refactoring,
668 })
669 }
670
671 fn generate_reasoning_steps(question: &str) -> Result<Vec<ThinkStep>, ThinkError> {
673 let mut steps = Vec::new();
674
675 steps.push(ThinkStep {
677 step_number: 1,
678 thought: format!("Analyzing the core question: '{}'", question.trim()),
679 reasoning: Self::analyze_problem_type(question),
680 });
681
682 steps.push(ThinkStep {
684 step_number: 2,
685 thought: "Breaking down the problem into key components".to_string(),
686 reasoning: Self::identify_key_components(question),
687 });
688
689 steps.push(ThinkStep {
691 step_number: 3,
692 thought: "Evaluating possible approaches and considerations".to_string(),
693 reasoning: Self::evaluate_approaches(question),
694 });
695
696 if Self::is_complex_problem(question) {
698 steps.push(ThinkStep {
699 step_number: 4,
700 thought: "Analyzing potential challenges and constraints".to_string(),
701 reasoning: Self::analyze_constraints(question),
702 });
703 }
704
705 if Self::requires_implementation_thinking(question) {
706 let step_num = steps.len() + 1;
707 steps.push(ThinkStep {
708 step_number: step_num,
709 thought: "Considering implementation details and practical aspects".to_string(),
710 reasoning: Self::consider_implementation(question),
711 });
712 }
713
714 Ok(steps)
715 }
716
717 fn generate_conclusion(question: &str, _steps: &[ThinkStep]) -> String {
719 let problem_type = Self::classify_problem_type(question);
720
721 match problem_type {
722 ProblemType::Technical => {
723 "Based on analysis: Technical solution requires systematic approach with careful implementation, testing, and edge case handling.".to_string()
724 }
725 ProblemType::Design => {
726 "Design approach: Balance user requirements, technical constraints, and maintainability through iterative refinement.".to_string()
727 }
728 ProblemType::Analysis => {
729 "Analysis complete: Key factors identified. Thorough data examination will inform decision-making process.".to_string()
730 }
731 ProblemType::Planning => {
732 "Planning strategy: Break into phases, identify dependencies, maintain flexibility for evolving requirements.".to_string()
733 }
734 ProblemType::Debugging => {
735 "Debug approach: Systematic investigation from most likely causes, methodical elimination of potential issues.".to_string()
736 }
737 ProblemType::General => {
738 "Solution path: Focus on core requirements while maintaining adaptability for changing circumstances.".to_string()
739 }
740 }
741 }
742
743 fn calculate_confidence(question: &str, steps: &[ThinkStep]) -> f32 {
745 let mut confidence = 0.5; if Self::is_well_defined_problem(question) {
749 confidence += 0.2;
750 }
751
752 let step_bonus = (steps.len() as f32 - 3.0) * 0.05;
754 confidence += step_bonus.min(0.2);
755
756 if Self::contains_technical_terms(question) {
758 confidence += 0.1;
759 }
760
761 if Self::is_vague_problem(question) {
763 confidence -= 0.2;
764 }
765
766 confidence.max(0.1).min(0.95)
768 }
769
770 fn classify_code_problem(problem: &str) -> CodeProblemType {
773 let p_lower = problem.to_lowercase();
774
775 if p_lower.contains("bug")
777 || p_lower.contains("crash")
778 || p_lower.contains("debug")
779 || p_lower.contains("exception")
780 || p_lower.contains("failure")
781 || p_lower.contains("memory leak") || (p_lower.contains("fix")
783 && (p_lower.contains("error")
784 || p_lower.contains("issue")
785 || p_lower.contains("null")))
786 {
787 CodeProblemType::BugFix
788 } else if p_lower.contains("implement")
790 || p_lower.contains("build")
791 || p_lower.contains("create")
792 || p_lower.contains("develop")
793 || p_lower.contains("add feature")
794 || p_lower.contains("new feature")
795 {
796 CodeProblemType::Implementation
797 } else if p_lower.contains("security")
799 || p_lower.contains("vulnerability")
800 || p_lower.contains("exploit")
801 || p_lower.contains("injection")
802 || p_lower.contains("csrf")
803 || p_lower.contains("xss")
804 || (p_lower.contains("auth")
805 && p_lower.contains("secure")
806 && !p_lower.contains("implement"))
807 {
809 CodeProblemType::Security
810 } else if p_lower.contains("optimiz") || p_lower.contains("performance")
813 || p_lower.contains("speed")
814 || p_lower.contains("efficient")
815 || p_lower.contains("bottleneck")
816 || p_lower.contains("latency")
817 || p_lower.contains("throughput")
818 {
819 CodeProblemType::Performance
820 } else if p_lower.contains("architecture")
821 || p_lower.contains("design pattern")
822 || p_lower.contains("system design")
823 || p_lower.contains("microservice")
824 || (p_lower.contains("design")
825 && (p_lower.contains("system") || p_lower.contains("pattern")))
826 {
827 CodeProblemType::Architecture
828 } else if p_lower.contains("refactor")
829 || p_lower.contains("clean up")
830 || p_lower.contains("improve code")
831 || p_lower.contains("simplify")
832 || p_lower.contains("restructure")
833 || p_lower.contains("code smell")
834 {
835 CodeProblemType::Refactoring
836 } else if p_lower.contains("test")
837 && (p_lower.contains("write")
838 || p_lower.contains("create")
839 || p_lower.contains("unit")
840 || p_lower.contains("integration")
841 || p_lower.contains("coverage"))
842 {
843 CodeProblemType::Testing
844 } else if p_lower.contains("document")
845 || p_lower.contains("comment")
846 || p_lower.contains("explain")
847 || p_lower.contains("readme")
848 || p_lower.contains("api doc")
849 || p_lower.contains("javadoc")
850 {
851 CodeProblemType::Documentation
852 } else if p_lower.contains("review")
853 && (p_lower.contains("code")
854 || p_lower.contains("quality")
855 || p_lower.contains("standards")
856 || p_lower.contains("best practice")
857 || p_lower.contains("lint"))
858 {
859 CodeProblemType::CodeReview
860 } else if p_lower.contains("auth") && !p_lower.contains("secure") {
862 CodeProblemType::Implementation
863 } else {
864 CodeProblemType::Implementation }
866 }
867
868 fn assess_complexity(
869 problem: &str,
870 language: Option<&str>,
871 context: Option<&str>,
872 ) -> Complexity {
873 let mut complexity_score = 0;
874
875 let p_lower = problem.to_lowercase();
877 if p_lower.contains("system") || p_lower.contains("architecture") {
878 complexity_score += 2;
879 }
880 if p_lower.contains("multiple") || p_lower.contains("several") {
881 complexity_score += 1;
882 }
883 if p_lower.contains("integration") || p_lower.contains("api") {
884 complexity_score += 1;
885 }
886 if p_lower.contains("database") || p_lower.contains("concurrent") {
887 complexity_score += 1;
888 }
889 if p_lower.contains("migration") || p_lower.contains("legacy") {
890 complexity_score += 2;
891 }
892
893 if let Some(lang) = language {
895 let lang_lower = lang.to_lowercase();
896 if lang_lower == "c++" || lang_lower == "rust" || lang_lower == "haskell" {
897 complexity_score += 1;
898 }
899 if lang_lower == "assembly" || lang_lower == "cuda" {
900 complexity_score += 2;
901 }
902 }
903
904 if let Some(ctx) = context {
906 if ctx.contains('/') && ctx.matches('/').count() > 3 {
907 complexity_score += 1;
908 } if ctx.contains("test") && ctx.contains("integration") {
910 complexity_score += 1;
911 }
912 }
913
914 if problem.len() > 200 {
916 complexity_score += 1;
917 }
918 if problem.len() > 500 {
919 complexity_score += 2;
920 }
921
922 match complexity_score {
923 0..=2 => Complexity::Simple,
924 3..=5 => Complexity::Medium,
925 _ => Complexity::Complex,
926 }
927 }
928
929 fn generate_code_reasoning_steps(
930 problem: &str,
931 problem_type: &CodeProblemType,
932 language: Option<&str>,
933 context: Option<&str>,
934 ) -> Result<Vec<ThinkStep>, ThinkError> {
935 let mut steps = Vec::new();
936
937 let context_analysis = if let Some(ctx) = context {
939 format!(
940 "Code context: {}. Understanding scope and dependencies.",
941 ctx
942 )
943 } else {
944 "Analyzing code context and identifying scope of changes.".to_string()
945 };
946
947 steps.push(ThinkStep {
948 step_number: 1,
949 thought: format!("Understanding code context for: '{}'", problem.trim()),
950 reasoning: context_analysis,
951 });
952
953 let problem_reasoning = match problem_type {
955 CodeProblemType::BugFix => {
956 "Identifying root cause, reproduction steps, and potential side effects of the bug."
957 }
958 CodeProblemType::Refactoring => {
959 "Analyzing code structure, identifying improvement opportunities without changing behavior."
960 }
961 CodeProblemType::Implementation => {
962 "Breaking down requirements into implementable components and design decisions."
963 }
964 CodeProblemType::Performance => {
965 "Profiling bottlenecks, measuring current performance, identifying optimization targets."
966 }
967 CodeProblemType::Security => {
968 "Evaluating security vulnerabilities, attack vectors, and mitigation strategies."
969 }
970 CodeProblemType::Testing => {
971 "Designing test cases, coverage analysis, and validation strategies."
972 }
973 CodeProblemType::Documentation => {
974 "Structuring documentation, identifying key concepts, and user scenarios."
975 }
976 CodeProblemType::Architecture => {
977 "Analyzing system components, dependencies, and architectural patterns."
978 }
979 CodeProblemType::CodeReview => {
980 "Evaluating code quality, standards compliance, and best practices."
981 }
982 };
983
984 steps.push(ThinkStep {
985 step_number: 2,
986 thought: format!("Analyzing specific challenge: {:?} problem", problem_type),
987 reasoning: problem_reasoning.to_string(),
988 });
989
990 let approach_reasoning = Self::get_implementation_approach(problem_type, language);
992 steps.push(ThinkStep {
993 step_number: 3,
994 thought: "Evaluating implementation approaches and technical considerations"
995 .to_string(),
996 reasoning: approach_reasoning,
997 });
998
999 if Self::is_complex_code_problem(problem, problem_type) {
1001 steps.push(ThinkStep {
1002 step_number: 4,
1003 thought: "Analyzing trade-offs and technical constraints".to_string(),
1004 reasoning: Self::analyze_code_tradeoffs(problem_type, language),
1005 });
1006 }
1007
1008 let solution_step = steps.len() + 1;
1010 steps.push(ThinkStep {
1011 step_number: solution_step,
1012 thought: "Proposing concrete solution strategy".to_string(),
1013 reasoning: Self::propose_solution_strategy(problem_type, problem),
1014 });
1015
1016 Ok(steps)
1017 }
1018
1019 fn generate_error_analysis_steps(error_message: &str) -> Result<Vec<ThinkStep>, ThinkError> {
1020 let mut steps = Vec::new();
1021
1022 steps.push(ThinkStep {
1024 step_number: 1,
1025 thought: "Parsing error message for key information".to_string(),
1026 reasoning: Self::parse_error_components(error_message),
1027 });
1028
1029 steps.push(ThinkStep {
1031 step_number: 2,
1032 thought: "Identifying potential root causes".to_string(),
1033 reasoning: Self::identify_error_causes(error_message),
1034 });
1035
1036 steps.push(ThinkStep {
1038 step_number: 3,
1039 thought: "Planning systematic debugging approach".to_string(),
1040 reasoning:
1041 "Use debugging tools, add logging, isolate components, reproduce consistently."
1042 .to_string(),
1043 });
1044
1045 Ok(steps)
1046 }
1047
1048 fn generate_refactoring_steps(code_smell: &str) -> Result<Vec<ThinkStep>, ThinkError> {
1049 let mut steps = Vec::new();
1050
1051 steps.push(ThinkStep {
1053 step_number: 1,
1054 thought: "Analyzing code smell and its impact".to_string(),
1055 reasoning: Self::analyze_code_smell(code_smell),
1056 });
1057
1058 steps.push(ThinkStep {
1060 step_number: 2,
1061 thought: "Selecting appropriate refactoring technique".to_string(),
1062 reasoning: Self::select_refactoring_technique(code_smell),
1063 });
1064
1065 steps.push(ThinkStep {
1067 step_number: 3,
1068 thought: "Planning safe refactoring with behavior preservation".to_string(),
1069 reasoning: "Ensure comprehensive tests, incremental changes, continuous validation."
1070 .to_string(),
1071 });
1072
1073 Ok(steps)
1074 }
1075
1076 fn analyze_problem_type(question: &str) -> String {
1079 let problem_type = Self::classify_problem_type(question);
1080 match problem_type {
1081 ProblemType::Technical => {
1082 "Technical problem - requires systematic analysis and solution design"
1083 }
1084 ProblemType::Design => {
1085 "Design challenge - needs multiple perspectives and trade-off analysis"
1086 }
1087 ProblemType::Analysis => {
1088 "Analysis task - examine data, patterns, and existing conditions"
1089 }
1090 ProblemType::Planning => {
1091 "Planning objective - structured approach with timeline consideration"
1092 }
1093 ProblemType::Debugging => {
1094 "Troubleshooting scenario - systematic investigation required"
1095 }
1096 ProblemType::General => "General problem - logical step-by-step reasoning approach",
1097 }
1098 .to_string()
1099 }
1100
1101 fn identify_key_components(question: &str) -> String {
1102 let q_lower = question.to_lowercase();
1103 let mut components = Vec::new();
1104
1105 if q_lower.contains("how") {
1107 components.push("Process/method");
1108 }
1109 if q_lower.contains("why") {
1110 components.push("Causal analysis");
1111 }
1112 if q_lower.contains("what") {
1113 components.push("Definition/identification");
1114 }
1115 if q_lower.contains("when") {
1116 components.push("Timing");
1117 }
1118 if q_lower.contains("where") {
1119 components.push("Location/context");
1120 }
1121
1122 if q_lower.contains("implement") || q_lower.contains("build") || q_lower.contains("create")
1124 {
1125 components.push("Implementation");
1126 }
1127 if q_lower.contains("optimize") || q_lower.contains("improve") {
1128 components.push("Performance/efficiency");
1129 }
1130 if q_lower.contains("debug") || q_lower.contains("fix") || q_lower.contains("error") {
1131 components.push("Problem resolution");
1132 }
1133
1134 if components.is_empty() {
1135 "Core objectives and success criteria need identification".to_string()
1136 } else {
1137 format!("Key components: {}", components.join(", "))
1138 }
1139 }
1140
1141 fn evaluate_approaches(question: &str) -> String {
1142 let q_lower = question.to_lowercase();
1143
1144 if q_lower.contains("code") || q_lower.contains("program") || q_lower.contains("implement") {
1145 "Implementation factors: code quality, performance, maintainability, testing, documentation"
1146 } else if q_lower.contains("design") || q_lower.contains("architecture") {
1147 "Design factors: user needs, technical constraints, scalability, extensibility"
1148 } else if q_lower.contains("debug") || q_lower.contains("error") || q_lower.contains("bug") {
1149 "Debug factors: reproduction steps, error patterns, logs, systematic elimination"
1150 } else if q_lower.contains("optimize") || q_lower.contains("performance") {
1151 "Performance factors: bottlenecks, measurement, trade-offs, system impact"
1152 } else {
1153 "General factors: resources, constraints, alternatives, risks"
1154 }.to_string()
1155 }
1156
1157 fn analyze_constraints(question: &str) -> String {
1158 let q_lower = question.to_lowercase();
1159 let mut constraints = Vec::new();
1160
1161 if q_lower.contains("time") || q_lower.contains("deadline") || q_lower.contains("urgent") {
1162 constraints.push("Time");
1163 }
1164 if q_lower.contains("budget") || q_lower.contains("cost") || q_lower.contains("resource") {
1165 constraints.push("Resources");
1166 }
1167 if q_lower.contains("compatibility") || q_lower.contains("legacy") {
1168 constraints.push("Compatibility");
1169 }
1170 if q_lower.contains("security") || q_lower.contains("privacy") {
1171 constraints.push("Security");
1172 }
1173 if q_lower.contains("scalab") || q_lower.contains("performance") {
1174 constraints.push("Performance");
1175 }
1176
1177 if constraints.is_empty() {
1178 "Consider technical, business, and operational constraints impacting solution"
1179 .to_string()
1180 } else {
1181 format!("Constraints: {}", constraints.join(", "))
1182 }
1183 }
1184
1185 fn consider_implementation(question: &str) -> String {
1186 let q_lower = question.to_lowercase();
1187
1188 if q_lower.contains("test") {
1189 "Implementation: comprehensive testing (unit, integration, edge cases)"
1190 } else if q_lower.contains("deploy") || q_lower.contains("production") {
1191 "Implementation: deployment strategy, monitoring, rollback, production readiness"
1192 } else {
1193 "Implementation: incremental approach with validation, documentation, maintainability"
1194 }
1195 .to_string()
1196 }
1197
1198 fn classify_problem_type(question: &str) -> ProblemType {
1201 let q_lower = question.to_lowercase();
1202
1203 if q_lower.contains("implement")
1204 || q_lower.contains("code")
1205 || q_lower.contains("program")
1206 || q_lower.contains("algorithm")
1207 || q_lower.contains("function")
1208 {
1209 ProblemType::Technical
1210 } else if q_lower.contains("design")
1211 || q_lower.contains("architecture")
1212 || q_lower.contains("structure")
1213 {
1214 ProblemType::Design
1215 } else if q_lower.contains("analyze")
1216 || q_lower.contains("evaluate")
1217 || q_lower.contains("compare")
1218 {
1219 ProblemType::Analysis
1220 } else if q_lower.contains("plan")
1221 || q_lower.contains("schedule")
1222 || q_lower.contains("organize")
1223 {
1224 ProblemType::Planning
1225 } else if q_lower.contains("debug")
1226 || q_lower.contains("fix")
1227 || q_lower.contains("error")
1228 || q_lower.contains("bug")
1229 || q_lower.contains("problem")
1230 {
1231 ProblemType::Debugging
1232 } else {
1233 ProblemType::General
1234 }
1235 }
1236
1237 fn is_complex_problem(question: &str) -> bool {
1238 let q_lower = question.to_lowercase();
1239 question.len() > 50
1240 || q_lower.contains("complex")
1241 || q_lower.contains("multiple")
1242 || q_lower.contains("integrate")
1243 || q_lower.contains("system")
1244 || (q_lower.matches("and").count() + q_lower.matches("or").count()) > 2
1245 }
1246
1247 fn requires_implementation_thinking(question: &str) -> bool {
1248 let q_lower = question.to_lowercase();
1249 q_lower.contains("implement")
1250 || q_lower.contains("build")
1251 || q_lower.contains("create")
1252 || q_lower.contains("develop")
1253 || q_lower.contains("code")
1254 }
1255
1256 fn is_well_defined_problem(question: &str) -> bool {
1257 let q_lower = question.to_lowercase();
1258 let has_specifics = q_lower.contains("specific")
1259 || q_lower.contains("exactly")
1260 || q_lower.contains("precisely");
1261 let has_context = question.len() > 30;
1262 let has_clear_intent = q_lower.starts_with("how to")
1263 || q_lower.starts_with("what is")
1264 || q_lower.starts_with("why does");
1265
1266 has_specifics || (has_context && has_clear_intent)
1267 }
1268
1269 fn contains_technical_terms(question: &str) -> bool {
1270 let q_lower = question.to_lowercase();
1271 let technical_terms = [
1272 "algorithm",
1273 "function",
1274 "class",
1275 "method",
1276 "variable",
1277 "array",
1278 "object",
1279 "database",
1280 "server",
1281 "client",
1282 "api",
1283 "framework",
1284 "library",
1285 "module",
1286 "performance",
1287 "memory",
1288 "cpu",
1289 "thread",
1290 "process",
1291 "cache",
1292 "index",
1293 "security",
1294 "authentication",
1295 "encryption",
1296 "hash",
1297 "protocol",
1298 "network",
1299 ];
1300
1301 technical_terms.iter().any(|term| q_lower.contains(term))
1302 }
1303
1304 fn is_vague_problem(question: &str) -> bool {
1305 let q_lower = question.to_lowercase();
1306 let vague_indicators = [
1307 "something",
1308 "anything",
1309 "stuff",
1310 "things",
1311 "whatever",
1312 "somehow",
1313 "maybe",
1314 "perhaps",
1315 "might",
1316 "could be",
1317 "not sure",
1318 "unclear",
1319 ];
1320
1321 question.len() < 20
1322 || vague_indicators
1323 .iter()
1324 .any(|indicator| q_lower.contains(indicator))
1325 }
1326
1327 fn get_implementation_approach(
1330 problem_type: &CodeProblemType,
1331 language: Option<&str>,
1332 ) -> String {
1333 let lang_considerations =
1334 language.map_or(String::new(), |lang| match lang.to_lowercase().as_str() {
1335 "rust" => " Consider ownership, borrowing, and zero-cost abstractions.".to_string(),
1336 "javascript" | "typescript" => {
1337 " Consider async patterns, type safety, and browser compatibility.".to_string()
1338 }
1339 "python" => {
1340 " Consider performance implications, type hints, and Pythonic patterns."
1341 .to_string()
1342 }
1343 "java" => {
1344 " Consider OOP design, memory management, and JVM optimizations.".to_string()
1345 }
1346 "c++" => {
1347 " Consider RAII, memory safety, and performance optimizations.".to_string()
1348 }
1349 "go" => " Consider goroutines, channels, and simplicity principles.".to_string(),
1350 _ => String::new(),
1351 });
1352
1353 let base_approach = match problem_type {
1354 CodeProblemType::BugFix => {
1355 "Isolate the issue, create minimal reproduction, apply targeted fix"
1356 }
1357 CodeProblemType::Refactoring => {
1358 "Preserve behavior, improve structure, maintain test coverage"
1359 }
1360 CodeProblemType::Implementation => {
1361 "Start with interfaces, implement incrementally, add comprehensive tests"
1362 }
1363 CodeProblemType::Performance => {
1364 "Measure first, optimize bottlenecks, validate improvements"
1365 }
1366 CodeProblemType::Security => {
1367 "Apply defense in depth, validate inputs, use secure defaults"
1368 }
1369 CodeProblemType::Testing => {
1370 "Cover edge cases, aim for behavior verification, maintain readability"
1371 }
1372 CodeProblemType::Documentation => {
1373 "Focus on user scenarios, provide examples, keep up-to-date"
1374 }
1375 CodeProblemType::Architecture => {
1376 "Design for scalability, maintainability, and clear separation of concerns"
1377 }
1378 CodeProblemType::CodeReview => {
1379 "Focus on readability, performance, security, and maintainability"
1380 }
1381 };
1382
1383 format!("{}.{}", base_approach, lang_considerations)
1384 }
1385
1386 fn analyze_code_tradeoffs(problem_type: &CodeProblemType, language: Option<&str>) -> String {
1387 let general_tradeoffs = match problem_type {
1388 CodeProblemType::BugFix => "Speed vs thoroughness: Quick fixes may introduce new bugs",
1389 CodeProblemType::Refactoring => {
1390 "Improvement benefits vs risk of introducing regressions"
1391 }
1392 CodeProblemType::Implementation => {
1393 "Feature completeness vs time to market and code complexity"
1394 }
1395 CodeProblemType::Performance => {
1396 "Optimization effort vs maintainability and code readability"
1397 }
1398 CodeProblemType::Security => {
1399 "Security measures vs user experience and system performance"
1400 }
1401 CodeProblemType::Testing => {
1402 "Test coverage vs test maintenance burden and execution time"
1403 }
1404 CodeProblemType::Documentation => "Documentation depth vs maintenance overhead",
1405 CodeProblemType::Architecture => {
1406 "Flexibility vs simplicity, future-proofing vs over-engineering"
1407 }
1408 CodeProblemType::CodeReview => "Thoroughness vs development velocity",
1409 };
1410
1411 if let Some(lang) = language {
1412 format!("{} (Language: {})", general_tradeoffs, lang)
1413 } else {
1414 general_tradeoffs.to_string()
1415 }
1416 }
1417
1418 fn propose_solution_strategy(problem_type: &CodeProblemType, _problem: &str) -> String {
1419 match problem_type {
1420 CodeProblemType::BugFix => "1) Reproduce the bug consistently, 2) Identify root cause through debugging, 3) Implement minimal fix, 4) Add regression tests".to_string(),
1421 CodeProblemType::Refactoring => "1) Ensure comprehensive test coverage, 2) Apply refactoring incrementally, 3) Validate behavior after each change, 4) Update documentation".to_string(),
1422 CodeProblemType::Implementation => "1) Define clear requirements and interfaces, 2) Implement core functionality with TDD, 3) Add error handling and edge cases, 4) Integrate and test".to_string(),
1423 CodeProblemType::Performance => "1) Profile and identify bottlenecks, 2) Optimize critical paths, 3) Measure improvements, 4) Ensure correctness maintained".to_string(),
1424 CodeProblemType::Security => "1) Identify threat model, 2) Apply security best practices, 3) Implement defense mechanisms, 4) Conduct security testing".to_string(),
1425 CodeProblemType::Testing => "1) Analyze requirements for test scenarios, 2) Implement unit and integration tests, 3) Verify edge cases and error conditions, 4) Maintain test suite".to_string(),
1426 CodeProblemType::Documentation => "1) Identify target audience and use cases, 2) Structure information logically, 3) Provide examples and tutorials, 4) Keep documentation current".to_string(),
1427 CodeProblemType::Architecture => "1) Analyze current system constraints, 2) Design modular, extensible architecture, 3) Plan migration strategy, 4) Implement incrementally".to_string(),
1428 CodeProblemType::CodeReview => "1) Review for correctness and logic, 2) Evaluate performance and security implications, 3) Check coding standards, 4) Provide constructive feedback".to_string(),
1429 }
1430 }
1431
1432 fn is_complex_code_problem(problem: &str, problem_type: &CodeProblemType) -> bool {
1433 matches!(problem_type, CodeProblemType::Architecture | CodeProblemType::Performance)
1435 || problem.to_lowercase().contains("multiple")
1437 || problem.to_lowercase().contains("system")
1438 || problem.to_lowercase().contains("integration")
1439 || problem.len() > 150 }
1441
1442 fn generate_code_conclusion(
1443 problem: &str,
1444 _steps: &[ThinkStep],
1445 problem_type: &CodeProblemType,
1446 ) -> String {
1447 let base_conclusion = match problem_type {
1448 CodeProblemType::BugFix => {
1449 "Bug analysis complete: Systematic debugging approach will isolate root cause and enable targeted fix with regression prevention."
1450 }
1451 CodeProblemType::Refactoring => {
1452 "Refactoring strategy defined: Incremental improvements with behavior preservation and comprehensive test validation."
1453 }
1454 CodeProblemType::Implementation => {
1455 "Implementation plan ready: Clear requirements breakdown with TDD approach ensures robust, maintainable solution."
1456 }
1457 CodeProblemType::Performance => {
1458 "Performance optimization strategy: Profile-driven improvements with measurable results and correctness validation."
1459 }
1460 CodeProblemType::Security => {
1461 "Security analysis complete: Defense-in-depth approach with threat modeling and comprehensive protection measures."
1462 }
1463 CodeProblemType::Testing => {
1464 "Testing strategy established: Comprehensive coverage with behavior verification and maintainable test suite."
1465 }
1466 CodeProblemType::Documentation => {
1467 "Documentation plan ready: User-focused content with examples and maintainable structure."
1468 }
1469 CodeProblemType::Architecture => {
1470 "Architectural design complete: Scalable, maintainable system with clear separation of concerns and migration path."
1471 }
1472 CodeProblemType::CodeReview => {
1473 "Code review framework ready: Systematic evaluation covering correctness, performance, security, and maintainability."
1474 }
1475 };
1476
1477 let p_lower = problem.to_lowercase();
1479 let mut specific_context = Vec::new();
1480
1481 if p_lower.contains("auth") {
1482 specific_context.push("authentication mechanisms");
1483 }
1484 if p_lower.contains("oauth") || p_lower.contains("oauth2") {
1485 specific_context.push("OAuth2 integration");
1486 }
1487 if p_lower.contains("security") || p_lower.contains("secure") {
1488 specific_context.push("security best practices");
1489 }
1490 if p_lower.contains("database") {
1491 specific_context.push("database optimization");
1492 }
1493 if p_lower.contains("scalab") {
1494 specific_context.push("scalability considerations");
1495 }
1496
1497 if specific_context.is_empty() {
1498 base_conclusion.to_string()
1499 } else {
1500 format!(
1501 "{} Focus areas include: {}.",
1502 base_conclusion,
1503 specific_context.join(", ")
1504 )
1505 }
1506 }
1507
1508 fn calculate_code_confidence(
1509 problem: &str,
1510 steps: &[ThinkStep],
1511 problem_type: &CodeProblemType,
1512 ) -> f32 {
1513 let mut confidence: f32 = 0.58; match problem_type {
1517 CodeProblemType::BugFix | CodeProblemType::Testing | CodeProblemType::Documentation => {
1518 confidence += 0.15
1519 }
1520 CodeProblemType::Implementation => confidence += 0.05, CodeProblemType::Refactoring => confidence += 0.08, CodeProblemType::Performance => confidence += 0.04, CodeProblemType::Security => confidence += 0.05, CodeProblemType::Architecture | CodeProblemType::CodeReview => confidence += 0.0, }
1526
1527 if Self::contains_technical_terms(problem) {
1529 match problem_type {
1531 CodeProblemType::Architecture
1532 | CodeProblemType::Performance
1533 | CodeProblemType::Security => {
1534 confidence += 0.05; }
1536 _ => confidence += 0.1, }
1538 }
1539
1540 if steps.len() > 4 {
1542 match problem_type {
1545 CodeProblemType::Architecture
1546 | CodeProblemType::Performance
1547 | CodeProblemType::Security => {
1548 }
1550 _ => confidence += 0.05,
1551 }
1552 }
1553
1554 if Self::is_vague_problem(problem) {
1556 confidence -= 0.2;
1557 }
1558
1559 confidence.max(0.1).min(0.95)
1560 }
1561
1562 fn determine_recommended_action(problem_type: &CodeProblemType, _problem: &str) -> String {
1563 match problem_type {
1564 CodeProblemType::BugFix => "Start debugging: Add logging, create minimal reproduction case, use debugger to trace execution",
1565 CodeProblemType::Refactoring => "Begin refactoring: Ensure tests exist, apply small incremental changes, validate behavior continuously",
1566 CodeProblemType::Implementation => "Start implementation: Define interfaces first, use TDD approach, implement incrementally",
1567 CodeProblemType::Performance => "Profile first: Measure current performance, identify bottlenecks before optimizing",
1568 CodeProblemType::Security => "Conduct security assessment: Review for common vulnerabilities, apply security best practices",
1569 CodeProblemType::Testing => "Design test cases: Cover happy path, edge cases, error conditions with clear assertions",
1570 CodeProblemType::Documentation => "Create documentation structure: Focus on user scenarios, include code examples",
1571 CodeProblemType::Architecture => "Design system architecture: Start with high-level design, define component interfaces",
1572 CodeProblemType::CodeReview => "Perform systematic review: Check correctness, performance, security, and coding standards",
1573 }.to_string()
1574 }
1575
1576 fn identify_affected_files(problem: &str, context: Option<&str>) -> Vec<String> {
1577 let mut files = Vec::new();
1578
1579 if let Some(ctx) = context
1581 && (ctx.contains('/') || ctx.contains('\\'))
1582 {
1583 files.push(ctx.to_string());
1584 }
1585
1586 let words: Vec<&str> = problem.split_whitespace().collect();
1588 for word in words {
1589 if word.contains('.') && (word.contains('/') || word.contains('\\')) {
1590 files.push(word.to_string());
1591 }
1592 }
1593
1594 let unique_files: HashSet<String> = files.into_iter().collect();
1596 unique_files.into_iter().collect()
1597 }
1598
1599 fn determine_error_action(error_message: &str) -> String {
1600 let error_lower = error_message.to_lowercase();
1601
1602 let base_action = if error_lower.contains("compilation") || error_lower.contains("syntax") {
1603 "Fix syntax errors: Check for missing semicolons, brackets, or type mismatches. Review code structure and ensure all language requirements are met"
1604 } else if error_lower.contains("null") || error_lower.contains("undefined") {
1605 "Handle null/undefined: Add comprehensive null checks before dereferencing, initialize all variables at declaration, implement Option/Result patterns for safe error handling"
1606 } else if error_lower.contains("memory") || error_lower.contains("segmentation") {
1607 "Fix memory issue: Validate array bounds before access, verify pointer validity, audit memory allocation/deallocation patterns, check for use-after-free and double-free bugs"
1608 } else if error_lower.contains("timeout") || error_lower.contains("deadlock") {
1609 "Resolve concurrency issue: Audit lock acquisition order, check for race conditions, ensure proper synchronization primitives, implement timeout mechanisms"
1610 } else if error_lower.contains("permission") || error_lower.contains("access") {
1611 "Fix access issue: Verify file permissions match requirements, check user privileges, validate path accessibility, ensure proper resource ownership"
1612 } else {
1613 "Debug systematically: Add comprehensive logging at key points, reproduce error consistently, trace full execution path, examine state at failure point"
1614 };
1615
1616 if error_lower.contains("line")
1618 || error_lower.contains(".rs")
1619 || error_lower.contains(".cpp")
1620 || error_lower.contains(".java")
1621 || error_lower.contains(".py")
1622 || error_lower.contains(".js")
1623 {
1624 format!(
1625 "{} - Focus on the specific file and line mentioned in the error message for targeted debugging",
1626 base_action
1627 )
1628 } else {
1629 base_action.to_string()
1630 }
1631 }
1632
1633 fn extract_files_from_error(error_message: &str) -> Vec<String> {
1634 let mut files = Vec::new();
1635 let lines: Vec<&str> = error_message.lines().collect();
1636
1637 for line in lines {
1638 if let Some(start) = line.find('/')
1640 && let Some(end) = line[start..].find(':')
1641 {
1642 let potential_file = &line[start..start + end];
1643 if potential_file.contains('.') {
1644 files.push(potential_file.to_string());
1645 }
1646 }
1647 }
1648
1649 let unique_files: HashSet<String> = files.into_iter().collect();
1651 unique_files.into_iter().collect()
1652 }
1653
1654 fn parse_error_components(error_message: &str) -> String {
1655 let mut components = Vec::new();
1656 let error_lower = error_message.to_lowercase();
1657
1658 if error_lower.contains("syntax") {
1660 components.push("Syntax error");
1661 }
1662 if error_lower.contains("runtime") {
1663 components.push("Runtime error");
1664 }
1665 if error_lower.contains("compile") {
1666 components.push("Compilation error");
1667 }
1668 if error_lower.contains("null") {
1669 components.push("Null reference");
1670 }
1671 if error_lower.contains("index") || error_lower.contains("bounds") {
1672 components.push("Array bounds");
1673 }
1674 if error_lower.contains("memory") {
1675 components.push("Memory error");
1676 }
1677 if error_lower.contains("network") || error_lower.contains("connection") {
1678 components.push("Network error");
1679 }
1680
1681 let files = Self::extract_files_from_error(error_message);
1683 if !files.is_empty() {
1684 components.push("File locations identified");
1685 }
1686
1687 if components.is_empty() {
1688 "General error requiring systematic analysis".to_string()
1689 } else {
1690 format!("Error components: {}", components.join(", "))
1691 }
1692 }
1693
1694 fn identify_error_causes(error_message: &str) -> String {
1695 let error_lower = error_message.to_lowercase();
1696
1697 if error_lower.contains("null") || error_lower.contains("undefined") {
1698 "Likely cause: Uninitialized variable, missing null check, or incorrect object access"
1699 } else if error_lower.contains("index") || error_lower.contains("bounds") {
1700 "Likely cause: Array access beyond bounds, off-by-one error, or empty collection access"
1701 } else if error_lower.contains("type") {
1702 "Likely cause: Type mismatch, incorrect casting, or missing type conversion"
1703 } else if error_lower.contains("memory") || error_lower.contains("segmentation") {
1704 "Likely cause: Buffer overflow, dangling pointer, or memory corruption"
1705 } else if error_lower.contains("permission") || error_lower.contains("access") {
1706 "Likely cause: Insufficient file permissions, incorrect path, or security restrictions"
1707 } else if error_lower.contains("network") || error_lower.contains("connection") {
1708 "Likely cause: Network connectivity, server unavailability, or timeout issues"
1709 } else {
1710 "Multiple potential causes: Requires systematic elimination through debugging"
1711 }
1712 .to_string()
1713 }
1714
1715 fn analyze_code_smell(code_smell: &str) -> String {
1716 let smell_lower = code_smell.to_lowercase();
1717
1718 if smell_lower.contains("long method") || smell_lower.contains("long function") {
1719 "Impact: Reduced readability, difficult testing, multiple responsibilities. Extract smaller methods."
1720 } else if smell_lower.contains("duplicate") || smell_lower.contains("repetition") {
1721 "Impact: Maintenance burden, inconsistent changes, code bloat. Extract common functionality."
1722 } else if smell_lower.contains("large class") || smell_lower.contains("god object") {
1723 "Impact: Low cohesion, high coupling, difficult maintenance. Apply Single Responsibility Principle."
1724 } else if smell_lower.contains("complex") || smell_lower.contains("cyclomatic") {
1725 "Impact: Hard to understand, error-prone, difficult testing. Simplify control flow."
1726 } else if smell_lower.contains("coupling") {
1727 "Impact: Rigid design, difficult changes, reduced reusability. Introduce abstractions."
1728 } else {
1729 "General code quality issue requiring analysis of structure, readability, and maintainability."
1730 }.to_string()
1731 }
1732
1733 fn select_refactoring_technique(code_smell: &str) -> String {
1734 let smell_lower = code_smell.to_lowercase();
1735
1736 if smell_lower.contains("long method") || smell_lower.contains("long function") {
1737 "Technique: Extract Method - Break down into smaller, focused functions with clear purposes"
1738 } else if smell_lower.contains("duplicate") {
1739 "Technique: Extract Common Method/Class - Centralize repeated logic in reusable components"
1740 } else if smell_lower.contains("large class") {
1741 "Technique: Extract Class/Module - Split responsibilities into focused, cohesive units"
1742 } else if smell_lower.contains("complex") {
1743 "Technique: Simplify Conditional - Use guard clauses, strategy pattern, or state machines"
1744 } else if smell_lower.contains("coupling") {
1745 "Technique: Introduce Interface/Dependency Injection - Reduce direct dependencies"
1746 } else if smell_lower.contains("magic number") || smell_lower.contains("hardcode") {
1747 "Technique: Extract Constants/Configuration - Make values explicit and configurable"
1748 } else {
1749 "Technique: Systematic analysis required - Identify specific structural issues first"
1750 }.to_string()
1751 }
1752
1753 fn _assess_refactoring_complexity(code_smell: &str) -> Complexity {
1754 let smell_lower = code_smell.to_lowercase();
1755
1756 if smell_lower.contains("system")
1757 || smell_lower.contains("architecture")
1758 || smell_lower.contains("large class")
1759 || smell_lower.contains("god object")
1760 {
1761 Complexity::Complex
1762 } else if smell_lower.contains("multiple")
1763 || smell_lower.contains("coupling")
1764 || smell_lower.contains("duplicate")
1765 {
1766 Complexity::Medium
1767 } else {
1768 Complexity::Simple
1769 }
1770 }
1771
1772 pub fn recommend_tools_for_problem(
1774 &self,
1775 problem_type: &CodeProblemType,
1776 ) -> Vec<ToolRecommendation> {
1777 match problem_type {
1778 CodeProblemType::BugFix => vec![
1779 ToolRecommendation {
1780 tool: "search".to_string(),
1781 confidence: 0.9,
1782 rationale: "Search tool helps locate error patterns, find related code sections, and identify all instances of the problematic code across the codebase".to_string(),
1783 priority: 1,
1784 },
1785 ToolRecommendation {
1786 tool: "edit".to_string(),
1787 confidence: 0.85,
1788 rationale: "Edit tool enables precise line-based fixes for identified bugs with immediate feedback and validation".to_string(),
1789 priority: 2,
1790 },
1791 ToolRecommendation {
1792 tool: "test".to_string(),
1793 confidence: 0.8,
1794 rationale: "Test tool ensures the bug fix doesn't introduce regressions and validates the solution works correctly".to_string(),
1795 priority: 3,
1796 },
1797 ],
1798 CodeProblemType::Refactoring => vec![
1799 ToolRecommendation {
1800 tool: "search".to_string(),
1801 confidence: 0.85,
1802 rationale: "Search tool identifies all code locations that need refactoring and finds usage patterns to ensure consistent changes".to_string(),
1803 priority: 1,
1804 },
1805 ToolRecommendation {
1806 tool: "patch".to_string(),
1807 confidence: 0.9,
1808 rationale: "Patch tool performs semantic-aware AST transformations that preserve code structure and behavior during refactoring".to_string(),
1809 priority: 2,
1810 },
1811 ToolRecommendation {
1812 tool: "test".to_string(),
1813 confidence: 0.8,
1814 rationale: "Test tool verifies behavior preservation after refactoring and ensures no functionality is broken".to_string(),
1815 priority: 3,
1816 },
1817 ],
1818 CodeProblemType::Implementation => vec![
1819 ToolRecommendation {
1820 tool: "plan".to_string(),
1821 confidence: 0.9,
1822 rationale: "Plan tool breaks down implementation into manageable tasks with dependencies and parallel execution opportunities".to_string(),
1823 priority: 1, },
1824 ToolRecommendation {
1825 tool: "edit".to_string(),
1826 confidence: 0.85,
1827 rationale: "Edit tool creates new code sections and implements features with fast iteration and immediate validation".to_string(),
1828 priority: 2, },
1829 ToolRecommendation {
1830 tool: "test".to_string(),
1831 confidence: 0.8,
1832 rationale: "Test tool validates new implementation meets requirements and integrates correctly with existing code".to_string(),
1833 priority: 3, },
1834 ],
1835 CodeProblemType::Performance => vec![
1836 ToolRecommendation {
1837 tool: "search".to_string(),
1838 confidence: 0.8,
1839 rationale: "Search tool locates performance-critical code sections, bottlenecks, and resource-intensive operations".to_string(),
1840 priority: 1, },
1841 ToolRecommendation {
1842 tool: "analyze".to_string(),
1843 confidence: 0.85,
1844 rationale: "Analyze tool profiles code execution, measures performance metrics, and identifies optimization opportunities".to_string(),
1845 priority: 2, },
1846 ToolRecommendation {
1847 tool: "patch".to_string(),
1848 confidence: 0.8,
1849 rationale: "Patch tool applies algorithmic optimizations and structural improvements while maintaining correctness".to_string(),
1850 priority: 3, },
1851 ],
1852 CodeProblemType::Security => vec![
1853 ToolRecommendation {
1854 tool: "search".to_string(),
1855 confidence: 0.9,
1856 rationale: "Search tool identifies security-sensitive code patterns, vulnerable functions, and potential attack vectors".to_string(),
1857 priority: 1, },
1858 ToolRecommendation {
1859 tool: "analyze".to_string(),
1860 confidence: 0.9,
1861 rationale: "Analyze tool performs security scanning, vulnerability assessment, and compliance checking against security standards".to_string(),
1862 priority: 2, },
1863 ToolRecommendation {
1864 tool: "edit".to_string(),
1865 confidence: 0.85,
1866 rationale: "Edit tool applies security patches, input validation, and defensive programming techniques".to_string(),
1867 priority: 3, },
1868 ],
1869 CodeProblemType::Testing => vec![
1870 ToolRecommendation {
1871 tool: "search".to_string(),
1872 confidence: 0.7,
1873 rationale: "Search tool finds existing test patterns, identifies untested code, and locates test utilities".to_string(),
1874 priority: 1, },
1875 ToolRecommendation {
1876 tool: "edit".to_string(),
1877 confidence: 0.9,
1878 rationale: "Edit tool creates test cases, implements assertions, and builds comprehensive test suites".to_string(),
1879 priority: 2, },
1880 ToolRecommendation {
1881 tool: "test".to_string(),
1882 confidence: 0.95,
1883 rationale: "Test tool executes test suites, validates coverage, and ensures all tests pass successfully".to_string(),
1884 priority: 3, },
1885 ],
1886 CodeProblemType::Documentation => vec![
1887 ToolRecommendation {
1888 tool: "search".to_string(),
1889 confidence: 0.8,
1890 rationale: "Search tool analyzes code structure, finds undocumented functions, and identifies documentation patterns".to_string(),
1891 priority: 1, },
1892 ToolRecommendation {
1893 tool: "edit".to_string(),
1894 confidence: 0.9,
1895 rationale: "Edit tool adds documentation comments, creates README files, and updates API documentation".to_string(),
1896 priority: 2, },
1897 ],
1898 CodeProblemType::Architecture => vec![
1899 ToolRecommendation {
1900 tool: "plan".to_string(),
1901 confidence: 0.95,
1902 rationale: "Plan tool designs system architecture, defines component relationships, and creates implementation roadmaps".to_string(),
1903 priority: 1, },
1904 ToolRecommendation {
1905 tool: "think".to_string(),
1906 confidence: 0.85,
1907 rationale: "Think tool reasons through architectural decisions, evaluates trade-offs, and considers long-term implications".to_string(),
1908 priority: 2, },
1909 ToolRecommendation {
1910 tool: "edit".to_string(),
1911 confidence: 0.7,
1912 rationale: "Edit tool implements architectural scaffolding, creates interfaces, and establishes module boundaries".to_string(),
1913 priority: 3, },
1914 ],
1915 CodeProblemType::CodeReview => vec![
1916 ToolRecommendation {
1917 tool: "search".to_string(),
1918 confidence: 0.9,
1919 rationale: "Search tool examines code patterns, finds similar implementations, and checks for consistency across codebase".to_string(),
1920 priority: 1, },
1921 ToolRecommendation {
1922 tool: "analyze".to_string(),
1923 confidence: 0.85,
1924 rationale: "Analyze tool evaluates code quality metrics, complexity scores, and adherence to best practices".to_string(),
1925 priority: 2, },
1926 ],
1927 }
1928 }
1929
1930 pub fn analyze_thought_for_tools(&self, thought: &str) -> Vec<ToolRecommendation> {
1932 let thought_lower = thought.to_lowercase();
1933 let mut recommendations = Vec::new();
1934 let mut priority = 1;
1935
1936 if thought_lower.contains("search")
1938 || thought_lower.contains("find")
1939 || thought_lower.contains("locate")
1940 || thought_lower.contains("look for")
1941 || thought_lower.contains("identify")
1942 || thought_lower.contains("discover")
1943 {
1944 recommendations.push(ToolRecommendation {
1945 tool: "search".to_string(),
1946 confidence: 0.9,
1947 rationale: "Thought mentions searching or finding - search tool provides multi-layer search with symbol, full-text, and AST capabilities".to_string(),
1948 priority, });
1949 priority += 1;
1950 }
1951
1952 if thought_lower.contains("edit")
1954 || thought_lower.contains("modify")
1955 || thought_lower.contains("change")
1956 || thought_lower.contains("update")
1957 || thought_lower.contains("fix")
1958 || thought_lower.contains("replace")
1959 {
1960 recommendations.push(ToolRecommendation {
1961 tool: "edit".to_string(),
1962 confidence: 0.85,
1963 rationale: "Thought mentions editing or modifying - edit tool provides fast line-based changes with context awareness".to_string(),
1964 priority, });
1965 priority += 1;
1966 }
1967
1968 if thought_lower.contains("plan")
1970 || thought_lower.contains("organize")
1971 || thought_lower.contains("structure")
1972 || thought_lower.contains("break down")
1973 || thought_lower.contains("decompose")
1974 || thought_lower.contains("strategy")
1975 {
1976 recommendations.push(ToolRecommendation {
1977 tool: "plan".to_string(),
1978 confidence: 0.9,
1979 rationale: "Thought mentions planning or organization - plan tool provides task decomposition with dependency analysis".to_string(),
1980 priority, });
1981 priority += 1;
1982 }
1983
1984 if thought_lower.contains("analyze")
1986 || thought_lower.contains("examine")
1987 || thought_lower.contains("investigate")
1988 || thought_lower.contains("review")
1989 || thought_lower.contains("evaluate")
1990 || thought_lower.contains("assess")
1991 {
1992 recommendations.push(ToolRecommendation {
1993 tool: "analyze".to_string(),
1994 confidence: 0.85,
1995 rationale: "Thought mentions analysis or investigation - analyze tool provides deep code analysis and metrics".to_string(),
1996 priority, });
1997 priority += 1;
1998 }
1999
2000 if thought_lower.contains("test")
2002 || thought_lower.contains("verify")
2003 || thought_lower.contains("validate")
2004 || thought_lower.contains("check")
2005 || thought_lower.contains("ensure")
2006 {
2007 recommendations.push(ToolRecommendation {
2008 tool: "test".to_string(),
2009 confidence: 0.8,
2010 rationale: "Thought mentions testing or validation - test tool ensures correctness and prevents regressions".to_string(),
2011 priority, });
2012 priority += 1;
2013 }
2014
2015 if thought_lower.contains("ast")
2017 || thought_lower.contains("syntax")
2018 || thought_lower.contains("parse")
2019 || thought_lower.contains("tree")
2020 || thought_lower.contains("structure")
2021 {
2022 recommendations.push(ToolRecommendation {
2023 tool: "tree".to_string(),
2024 confidence: 0.85,
2025 rationale: "Thought mentions AST or syntax - tree tool provides tree-sitter parsing for 27+ languages".to_string(),
2026 priority, });
2027 priority += 1;
2028 }
2029
2030 if thought_lower.contains("pattern")
2032 || thought_lower.contains("grep")
2033 || thought_lower.contains("match")
2034 || thought_lower.contains("regex")
2035 {
2036 recommendations.push(ToolRecommendation {
2037 tool: "grep".to_string(),
2038 confidence: 0.8,
2039 rationale: "Thought mentions patterns or matching - grep tool provides AST-aware pattern matching".to_string(),
2040 priority, });
2041 priority += 1;
2042 }
2043
2044 if thought_lower.contains("files")
2046 || thought_lower.contains("directory")
2047 || thought_lower.contains("folder")
2048 || thought_lower.contains("glob")
2049 || thought_lower.contains("discover files")
2050 {
2051 recommendations.push(ToolRecommendation {
2052 tool: "glob".to_string(),
2053 confidence: 0.75,
2054 rationale: "Thought mentions file discovery - glob tool provides fast parallel file finding with pattern support".to_string(),
2055 priority, });
2056 priority += 1;
2057 }
2058
2059 if thought_lower.contains("run")
2061 || thought_lower.contains("execute")
2062 || thought_lower.contains("command")
2063 || thought_lower.contains("script")
2064 || thought_lower.contains("bash")
2065 || thought_lower.contains("shell")
2066 {
2067 recommendations.push(ToolRecommendation {
2068 tool: "bash".to_string(),
2069 confidence: 0.7,
2070 rationale: "Thought mentions execution or commands - bash tool provides safe command execution with validation".to_string(),
2071 priority, });
2072 priority += 1;
2073 }
2074
2075 if thought_lower.contains("refactor")
2077 || thought_lower.contains("transform")
2078 || thought_lower.contains("restructure")
2079 || thought_lower.contains("patch")
2080 {
2081 recommendations.push(ToolRecommendation {
2082 tool: "patch".to_string(),
2083 confidence: 0.9,
2084 rationale: "Thought mentions refactoring or transformation - patch tool provides semantic-aware AST transformations".to_string(),
2085 priority, });
2086 priority += 1;
2087 }
2088
2089 if thought_lower.contains("index")
2091 || thought_lower.contains("catalog")
2092 || thought_lower.contains("full-text")
2093 {
2094 recommendations.push(ToolRecommendation {
2095 tool: "index".to_string(),
2096 confidence: 0.75,
2097 rationale: "Thought mentions indexing - index tool provides Tantivy-based full-text indexing for fast searches".to_string(),
2098 priority, });
2099 priority += 1;
2100 }
2101
2102 if thought_lower.contains("think")
2104 || thought_lower.contains("reason")
2105 || thought_lower.contains("consider")
2106 || thought_lower.contains("evaluate options")
2107 {
2108 recommendations.push(ToolRecommendation {
2109 tool: "think".to_string(),
2110 confidence: 0.8,
2111 rationale: "Thought mentions reasoning or consideration - think tool provides structured reasoning strategies".to_string(),
2112 priority, });
2113 }
2114
2115 if recommendations.is_empty() {
2117 recommendations.push(ToolRecommendation {
2119 tool: "search".to_string(),
2120 confidence: 0.6,
2121 rationale: "No specific tools mentioned - search tool helps understand the codebase before making changes".to_string(),
2122 priority: 1, });
2123 recommendations.push(ToolRecommendation {
2124 tool: "edit".to_string(),
2125 confidence: 0.5,
2126 rationale:
2127 "No specific tools mentioned - edit tool enables making necessary code changes"
2128 .to_string(),
2129 priority: 2,
2130 });
2131 }
2132
2133 recommendations.sort_by_key(|r| r.priority);
2135 recommendations
2136 }
2137}
2138
2139impl Default for ThinkTool {
2140 fn default() -> Self {
2141 Self::new()
2142 }
2143}
2144
2145#[derive(Debug, Clone, PartialEq)]
2147enum ProblemType {
2148 Technical, Design, Analysis, Planning, Debugging, General, }
2155
2156#[cfg(test)]
2157mod tests {
2158 use super::*;
2159
2160 #[test]
2161 fn test_basic_thinking() {
2162 let result = ThinkTool::think("How to implement a hash table?").unwrap();
2163
2164 assert!(result.steps.len() >= 3);
2165 assert!(!result.conclusion.is_empty());
2166 assert!(result.confidence > 0.0 && result.confidence <= 1.0);
2167
2168 for (i, step) in result.steps.iter().enumerate() {
2170 assert_eq!(step.step_number, i + 1);
2171 }
2172 }
2173
2174 #[test]
2175 fn test_empty_question() {
2176 let result = ThinkTool::think("");
2177 assert!(matches!(result, Err(ThinkError::EmptyProblem)));
2178 }
2179
2180 #[test]
2181 fn test_short_question() {
2182 let result = ThinkTool::think("Hi");
2183 assert!(matches!(result, Err(ThinkError::EmptyProblem)));
2184 }
2185
2186 #[test]
2187 fn test_technical_question_confidence() {
2188 let result =
2189 ThinkTool::think("How to optimize database query performance using indexes?").unwrap();
2190
2191 assert!(result.confidence > 0.6);
2193 }
2194
2195 #[test]
2196 fn test_vague_question_confidence() {
2197 let result = ThinkTool::think("How to do something with stuff?").unwrap();
2198
2199 assert!(result.confidence < 0.6);
2201 }
2202
2203 #[test]
2204 fn test_complex_problem_extra_steps() {
2205 let result = ThinkTool::think(
2206 "How to implement a distributed system with multiple microservices, message queues, and load balancing?"
2207 ).unwrap();
2208
2209 assert!(result.steps.len() > 3);
2211 }
2212
2213 #[test]
2214 fn test_step_content_quality() {
2215 let result = ThinkTool::think("How to debug a memory leak in a C++ application?").unwrap();
2216
2217 for step in &result.steps {
2219 assert!(!step.thought.is_empty());
2220 assert!(!step.reasoning.is_empty());
2221 assert!(step.thought.len() > 10);
2222 assert!(step.reasoning.len() > 20);
2223 }
2224 }
2225
2226 #[test]
2227 fn test_conclusion_relevance() {
2228 let result = ThinkTool::think("What's the best way to learn Rust programming?").unwrap();
2229
2230 assert!(!result.conclusion.is_empty());
2232 assert!(result.conclusion.len() > 50);
2233 }
2234
2235 #[test]
2238 fn test_code_problem_classification() {
2239 assert_eq!(
2240 ThinkTool::classify_code_problem("Fix the null pointer bug"),
2241 CodeProblemType::BugFix
2242 );
2243 assert_eq!(
2244 ThinkTool::classify_code_problem("Refactor the messy code"),
2245 CodeProblemType::Refactoring
2246 );
2247 assert_eq!(
2248 ThinkTool::classify_code_problem("Implement user authentication"),
2249 CodeProblemType::Implementation
2250 );
2251 assert_eq!(
2252 ThinkTool::classify_code_problem("Optimize database performance"),
2253 CodeProblemType::Performance
2254 );
2255 assert_eq!(
2256 ThinkTool::classify_code_problem("Fix security vulnerability"),
2257 CodeProblemType::Security
2258 );
2259 assert_eq!(
2260 ThinkTool::classify_code_problem("Write unit tests"),
2261 CodeProblemType::Testing
2262 );
2263 assert_eq!(
2264 ThinkTool::classify_code_problem("Document the API"),
2265 CodeProblemType::Documentation
2266 );
2267 assert_eq!(
2268 ThinkTool::classify_code_problem("Design system architecture"),
2269 CodeProblemType::Architecture
2270 );
2271 assert_eq!(
2272 ThinkTool::classify_code_problem("Review code quality"),
2273 CodeProblemType::CodeReview
2274 );
2275 }
2276
2277 #[test]
2278 fn test_complexity_assessment() {
2279 let simple =
2281 ThinkTool::assess_complexity("Fix variable name", Some("rust"), Some("main.rs"));
2282 assert_eq!(simple, Complexity::Simple);
2283
2284 let complex = ThinkTool::assess_complexity(
2286 "Implement distributed system with multiple microservices and database migration",
2287 Some("rust"),
2288 Some("src/services/complex/integration/handler.rs"),
2289 );
2290 assert!(matches!(complex, Complexity::Medium | Complexity::Complex));
2291 }
2292
2293 #[test]
2294 fn test_think_about_code() {
2295 let result = ThinkTool::think_about_code(
2296 "Fix memory leak in C++ application",
2297 Some("c++"),
2298 Some("src/memory_manager.cpp"),
2299 )
2300 .unwrap();
2301
2302 assert_eq!(result.problem_type, CodeProblemType::BugFix);
2303 assert!(result.steps.len() >= 3);
2304 assert!(!result.recommended_action.is_empty());
2305 assert_eq!(result.affected_files, vec!["src/memory_manager.cpp"]);
2306 assert!(result.confidence > 0.5);
2307 assert!(!result.conclusion.is_empty());
2308 }
2309
2310 #[test]
2311 fn test_analyze_error() {
2312 let result =
2313 ThinkTool::analyze_error("NullPointerException at line 42 in UserService.java")
2314 .unwrap();
2315
2316 assert_eq!(result.problem_type, CodeProblemType::BugFix);
2317 assert!(result.steps.len() >= 3);
2318 assert!(result.recommended_action.contains("null"));
2319 assert!(result.confidence >= 0.7); assert!(!result.affected_files.is_empty() || result.affected_files.is_empty()); }
2322
2323 #[test]
2324 fn test_plan_refactoring() {
2325 let result =
2326 ThinkTool::plan_refactoring("Long method with too many responsibilities").unwrap();
2327
2328 assert_eq!(result.problem_type, CodeProblemType::Refactoring);
2329 assert!(result.steps.len() >= 3);
2330 assert!(result.recommended_action.contains("refactor"));
2331 assert!(result.confidence >= 0.8); assert!(matches!(
2333 result.complexity,
2334 Complexity::Simple | Complexity::Medium
2335 ));
2336 }
2337
2338 #[test]
2339 fn test_error_file_extraction() {
2340 let error_msg = "Error in /src/main.rs:42:10\nCompilation failed in /tests/unit_test.rs:15";
2341 let files = ThinkTool::extract_files_from_error(error_msg);
2342
2343 assert!(
2344 files.contains(&"/src/main.rs".to_string())
2345 || files.contains(&"/tests/unit_test.rs".to_string())
2346 );
2347 }
2348
2349 #[test]
2350 fn test_recommended_actions() {
2351 let bug_action =
2352 ThinkTool::determine_recommended_action(&CodeProblemType::BugFix, "null pointer");
2353 assert!(bug_action.contains("debug"));
2354
2355 let perf_action =
2356 ThinkTool::determine_recommended_action(&CodeProblemType::Performance, "slow query");
2357 assert!(perf_action.contains("Profile") || perf_action.contains("profile"));
2358
2359 let test_action =
2360 ThinkTool::determine_recommended_action(&CodeProblemType::Testing, "no tests");
2361 assert!(test_action.contains("test"));
2362 }
2363
2364 #[test]
2365 fn test_code_confidence_calculation() {
2366 let steps = vec![ThinkStep {
2367 step_number: 1,
2368 thought: "test".to_string(),
2369 reasoning: "test reasoning".to_string(),
2370 }];
2371
2372 let bug_confidence = ThinkTool::calculate_code_confidence(
2374 "Fix null pointer exception in authentication module",
2375 &steps,
2376 &CodeProblemType::BugFix,
2377 );
2378 assert!(bug_confidence > 0.7);
2379
2380 let arch_confidence = ThinkTool::calculate_code_confidence(
2382 "Design system architecture",
2383 &steps,
2384 &CodeProblemType::Architecture,
2385 );
2386 assert!(arch_confidence < bug_confidence);
2387 }
2388
2389 #[test]
2390 fn test_implementation_approach() {
2391 let rust_approach =
2392 ThinkTool::get_implementation_approach(&CodeProblemType::BugFix, Some("rust"));
2393 assert!(rust_approach.contains("ownership") || rust_approach.contains("borrowing"));
2394
2395 let js_approach = ThinkTool::get_implementation_approach(
2396 &CodeProblemType::Implementation,
2397 Some("javascript"),
2398 );
2399 assert!(js_approach.contains("async") || js_approach.contains("type"));
2400 }
2401
2402 #[test]
2403 fn test_affected_files_identification() {
2404 let files = ThinkTool::identify_affected_files(
2405 "Fix bug in src/auth.rs and update tests/auth_test.rs",
2406 Some("src/main.rs"),
2407 );
2408
2409 assert!(!files.is_empty());
2410 assert!(files.contains(&"src/main.rs".to_string()));
2412 }
2413
2414 #[test]
2415 fn test_backward_compatibility() {
2416 let result = ThinkTool::think("How to implement authentication?").unwrap();
2418
2419 assert!(result.steps.len() >= 3);
2420 assert!(!result.conclusion.is_empty());
2421 assert!(result.confidence > 0.0 && result.confidence <= 1.0);
2422 }
2423
2424 #[test]
2427 fn test_sequential_thinking_basic() {
2428 let problems = [
2430 "How to debug a segmentation fault?",
2431 "What's the best approach for database optimization?",
2432 "How to implement user authentication securely?",
2433 ];
2434
2435 let mut results = Vec::new();
2436 for problem in problems {
2437 let result = ThinkTool::think_about_code(problem, Some("rust"), None).unwrap();
2438 results.push(result);
2439 }
2440
2441 for (i, result) in results.iter().enumerate() {
2443 assert!(
2444 result.steps.len() >= 3,
2445 "Problem {} should have at least 3 steps",
2446 i
2447 );
2448
2449 for (step_idx, step) in result.steps.iter().enumerate() {
2451 assert_eq!(
2452 step.step_number,
2453 step_idx + 1,
2454 "Step numbering should be sequential"
2455 );
2456 assert!(!step.thought.is_empty(), "Each thought should have content");
2457 assert!(
2458 !step.reasoning.is_empty(),
2459 "Each step should have reasoning"
2460 );
2461 }
2462
2463 assert!(
2465 result.confidence >= 0.1 && result.confidence <= 0.95,
2466 "Confidence should be in valid range"
2467 );
2468 assert!(!result.conclusion.is_empty(), "Should have a conclusion");
2469 assert!(
2470 !result.recommended_action.is_empty(),
2471 "Should have recommended action"
2472 );
2473 }
2474
2475 let problem_types: Vec<_> = results.iter().map(|r| &r.problem_type).collect();
2477 assert!(problem_types.contains(&&CodeProblemType::BugFix));
2478 assert!(problem_types.contains(&&CodeProblemType::Performance));
2479 assert!(problem_types.contains(&&CodeProblemType::Implementation));
2480 }
2481
2482 #[test]
2483 fn test_thought_revision() {
2484 let initial_problem = "Fix the authentication bug";
2486
2487 let initial_result =
2489 ThinkTool::think_about_code(initial_problem, Some("rust"), None).unwrap();
2490 assert_eq!(initial_result.problem_type, CodeProblemType::BugFix);
2491
2492 let revised_problem =
2494 "Fix the authentication bug that causes null pointer exception in login validation";
2495 let revised_result =
2496 ThinkTool::think_about_code(revised_problem, Some("rust"), Some("src/auth.rs"))
2497 .unwrap();
2498
2499 assert!(
2501 revised_result.steps.len() >= initial_result.steps.len(),
2502 "Revised analysis should be as detailed or more"
2503 );
2504 assert!(
2505 !revised_result.affected_files.is_empty(),
2506 "Revised analysis should identify affected files"
2507 );
2508 assert!(
2509 revised_result.confidence >= initial_result.confidence - 0.1,
2510 "Confidence should not significantly decrease"
2511 );
2512
2513 let error_result =
2515 ThinkTool::analyze_error("NullPointerException in auth validation").unwrap();
2516 assert_eq!(error_result.problem_type, CodeProblemType::BugFix);
2517 assert!(
2518 error_result.recommended_action.contains("null")
2519 || error_result.recommended_action.contains("check")
2520 );
2521
2522 let thought1 = ThoughtData::new("Initial analysis".to_string(), 1, 3);
2524 let thought2 = ThoughtData::new("Revised analysis".to_string(), 2, 3).as_revision(1);
2525
2526 assert!(!thought1.is_revision);
2527 assert!(thought2.is_revision);
2528 assert_eq!(thought2.revises_thought, Some(1));
2529 }
2530
2531 #[test]
2532 fn test_tool_recommendations() {
2533 let test_cases = [
2535 (
2536 "Debug memory leak in C++ application",
2537 CodeProblemType::BugFix,
2538 "debug",
2539 ),
2540 (
2541 "Optimize slow database queries",
2542 CodeProblemType::Performance,
2543 "profile",
2544 ),
2545 (
2546 "Refactor messy legacy code",
2547 CodeProblemType::Refactoring,
2548 "refactor",
2549 ),
2550 (
2551 "Implement user registration feature",
2552 CodeProblemType::Implementation,
2553 "implement",
2554 ),
2555 (
2556 "Fix SQL injection vulnerability",
2557 CodeProblemType::Security,
2558 "security",
2559 ),
2560 (
2561 "Write comprehensive unit tests",
2562 CodeProblemType::Testing,
2563 "test",
2564 ),
2565 (
2566 "Document the REST API endpoints",
2567 CodeProblemType::Documentation,
2568 "documentation",
2569 ),
2570 (
2571 "Design microservices architecture",
2572 CodeProblemType::Architecture,
2573 "architecture",
2574 ),
2575 (
2576 "Review code for best practices",
2577 CodeProblemType::CodeReview,
2578 "review",
2579 ),
2580 ];
2581
2582 for (problem, expected_type, expected_action_keyword) in test_cases {
2583 let result = ThinkTool::think_about_code(problem, Some("rust"), None).unwrap();
2584
2585 assert_eq!(
2586 result.problem_type, expected_type,
2587 "Problem '{}' should be classified as {:?}",
2588 problem, expected_type
2589 );
2590
2591 let action_lower = result.recommended_action.to_lowercase();
2592 assert!(
2593 action_lower.contains(expected_action_keyword),
2594 "Recommended action '{}' should contain '{}' for problem type {:?}",
2595 result.recommended_action,
2596 expected_action_keyword,
2597 expected_type
2598 );
2599
2600 let has_relevant_step = result.steps.iter().any(|step| {
2602 let step_content = format!("{} {}", step.thought, step.reasoning).to_lowercase();
2603 step_content.contains(expected_action_keyword)
2604 || step_content.contains(&format!("{:?}", expected_type).to_lowercase())
2605 });
2606 assert!(
2607 has_relevant_step,
2608 "Steps should contain problem-type specific reasoning for {:?}",
2609 expected_type
2610 );
2611 }
2612
2613 let tool_rec = ToolRecommendation {
2615 tool: "search".to_string(),
2616 confidence: 0.8,
2617 rationale: "Need to find relevant code".to_string(),
2618 priority: 1,
2619 };
2620
2621 assert_eq!(tool_rec.tool, "search");
2622 assert!(tool_rec.confidence > 0.0 && tool_rec.confidence <= 1.0);
2623 assert!(!tool_rec.rationale.is_empty());
2624 }
2625
2626 #[test]
2627 fn test_branch_management() {
2628 let perf_result = ThinkTool::think_about_code(
2632 "Optimize performance bottlenecks in authentication system",
2633 Some("rust"),
2634 Some("src/auth.rs"),
2635 )
2636 .unwrap();
2637
2638 let security_result = ThinkTool::think_about_code(
2640 "Fix security vulnerabilities in authentication system",
2641 Some("rust"),
2642 Some("src/auth.rs"),
2643 )
2644 .unwrap();
2645
2646 assert_eq!(perf_result.problem_type, CodeProblemType::Performance);
2648 assert_eq!(security_result.problem_type, CodeProblemType::Security);
2649
2650 let perf_actions = perf_result.recommended_action.to_lowercase();
2652 assert!(
2653 perf_actions.contains("profile")
2654 || perf_actions.contains("measure")
2655 || perf_actions.contains("performance")
2656 );
2657
2658 let security_actions = security_result.recommended_action.to_lowercase();
2660 assert!(
2661 security_actions.contains("security")
2662 || security_actions.contains("vulnerability")
2663 || security_actions.contains("assessment")
2664 );
2665
2666 assert_eq!(perf_result.affected_files, security_result.affected_files);
2668 assert_ne!(
2669 perf_result.recommended_action,
2670 security_result.recommended_action
2671 );
2672
2673 let mut session = ThinkSession::new(100);
2675 session.add_thought(ThoughtData::new("Main thought".to_string(), 1, 3));
2676
2677 session.create_branch(0, "security-branch".to_string());
2679 assert!(session.branches.contains_key("security-branch"));
2680
2681 let branched_thought = ThoughtData::new("Security analysis".to_string(), 1, 2)
2683 .with_branch(1, "security-branch".to_string());
2684
2685 assert_eq!(branched_thought.branch_from_thought, Some(1));
2686 assert_eq!(
2687 branched_thought.branch_id,
2688 Some("security-branch".to_string())
2689 );
2690
2691 let null_error = ThinkTool::analyze_error("NullPointerException in user service").unwrap();
2693 let memory_error =
2694 ThinkTool::analyze_error("Segmentation fault in buffer handling").unwrap();
2695 let network_error = ThinkTool::analyze_error("Connection timeout in API client").unwrap();
2696
2697 assert_eq!(null_error.problem_type, CodeProblemType::BugFix);
2699 assert_eq!(memory_error.problem_type, CodeProblemType::BugFix);
2700 assert_eq!(network_error.problem_type, CodeProblemType::BugFix);
2701
2702 let actions = [
2704 &null_error.recommended_action,
2705 &memory_error.recommended_action,
2706 &network_error.recommended_action,
2707 ];
2708 assert!(actions.iter().all(|action| !action.is_empty()));
2709 for (i, action1) in actions.iter().enumerate() {
2711 for (j, action2) in actions.iter().enumerate() {
2712 if i != j {
2713 assert_ne!(
2714 action1, action2,
2715 "Different error types should have different recommended actions"
2716 );
2717 }
2718 }
2719 }
2720 }
2721
2722 #[test]
2723 fn test_session_history() {
2724 let mut session = ThinkSession::new(100);
2726
2727 let problems = [
2729 "Application crashes on startup",
2730 "Application crashes when loading configuration",
2731 "Null pointer when parsing config file in src/config.rs line 45",
2732 ];
2733
2734 let mut session_results = Vec::new();
2735
2736 for (i, problem) in problems.iter().enumerate() {
2737 let context = if i == 2 { Some("src/config.rs") } else { None };
2738 let result = if i == 2 {
2739 ThinkTool::analyze_error(problem).unwrap()
2740 } else {
2741 ThinkTool::think_about_code(problem, Some("rust"), context).unwrap()
2742 };
2743
2744 let thought = ThoughtData::new(format!("Problem {}: {}", i + 1, problem), i + 1, 3)
2746 .with_confidence(result.confidence);
2747 session.add_thought(thought);
2748
2749 session_results.push(result);
2750 }
2751
2752 assert_eq!(session.thought_history.len(), 3);
2754 assert_eq!(session.total_thought_count, 3);
2755
2756 assert!(session_results.len() == 3);
2758
2759 assert!(session_results[2].affected_files.len() >= session_results[0].affected_files.len());
2761
2762 assert!(
2764 session_results[2].confidence >= 0.7,
2765 "Error analysis should have high confidence"
2766 );
2767
2768 let problem_types: Vec<_> = session_results.iter().map(|r| &r.problem_type).collect();
2770 assert!(problem_types.iter().all(|&pt| matches!(
2771 pt,
2772 &CodeProblemType::BugFix | &CodeProblemType::Implementation
2773 )));
2774
2775 let actions: Vec<_> = session_results
2777 .iter()
2778 .map(|r| &r.recommended_action)
2779 .collect();
2780 assert!(
2781 actions[2].len() >= actions[0].len(),
2782 "Later actions should be more detailed"
2783 );
2784
2785 let current_history = session.current_history();
2787 assert_eq!(current_history.len(), 3);
2788
2789 for (i, thought) in current_history.iter().enumerate() {
2791 assert_eq!(thought.thought_number, i + 1);
2792 assert!(!thought.thought.is_empty());
2793 }
2794 }
2795
2796 #[test]
2797 fn test_tool_confidence_scores() {
2798 let test_cases = [
2800 (
2802 "Fix NullPointerException in UserService.java line 42",
2803 CodeProblemType::BugFix,
2804 0.7,
2805 0.95,
2806 ),
2807 (
2808 "Write unit tests for calculateTax method",
2809 CodeProblemType::Testing,
2810 0.7,
2811 0.95,
2812 ),
2813 (
2814 "Document the getUserById API endpoint",
2815 CodeProblemType::Documentation,
2816 0.7,
2817 0.95,
2818 ),
2819 (
2821 "Implement user authentication with JWT",
2822 CodeProblemType::Implementation,
2823 0.5,
2824 0.8,
2825 ),
2826 (
2827 "Refactor the large UserService class",
2828 CodeProblemType::Refactoring,
2829 0.5,
2830 0.8,
2831 ),
2832 (
2834 "Design scalable microservices architecture",
2835 CodeProblemType::Architecture,
2836 0.4,
2837 0.7,
2838 ),
2839 (
2840 "Optimize overall system performance",
2841 CodeProblemType::Performance,
2842 0.4,
2843 0.7,
2844 ),
2845 (
2846 "Review codebase for security issues",
2847 CodeProblemType::Security,
2848 0.4,
2849 0.7,
2850 ),
2851 ];
2852
2853 for (problem, expected_type, min_confidence, max_confidence) in test_cases {
2854 let result = ThinkTool::think_about_code(problem, Some("java"), None).unwrap();
2855
2856 assert_eq!(
2857 result.problem_type, expected_type,
2858 "Problem type should match for: {}",
2859 problem
2860 );
2861
2862 assert!(
2863 result.confidence >= min_confidence && result.confidence <= max_confidence,
2864 "Confidence {:.2} should be between {:.2} and {:.2} for {:?} problem: '{}'",
2865 result.confidence,
2866 min_confidence,
2867 max_confidence,
2868 expected_type,
2869 problem
2870 );
2871 }
2872
2873 let vague_problem = "Fix something that's broken";
2875 let specific_problem =
2876 "Fix memory leak in ArrayList resize operation in Java HashMap implementation";
2877
2878 let vague_result = ThinkTool::think_about_code(vague_problem, Some("java"), None).unwrap();
2879 let specific_result =
2880 ThinkTool::think_about_code(specific_problem, Some("java"), None).unwrap();
2881
2882 assert!(
2883 specific_result.confidence > vague_result.confidence,
2884 "Specific problems should have higher confidence than vague ones"
2885 );
2886
2887 let rust_result =
2889 ThinkTool::think_about_code("Implement memory-safe linked list", Some("rust"), None)
2890 .unwrap();
2891 let assembly_result = ThinkTool::think_about_code(
2892 "Implement memory-safe linked list",
2893 Some("assembly"),
2894 None,
2895 )
2896 .unwrap();
2897
2898 assert!(
2900 rust_result.confidence >= assembly_result.confidence,
2901 "Complex languages should not increase confidence unnecessarily"
2902 );
2903
2904 let error_result = ThinkTool::analyze_error(
2906 "java.lang.NullPointerException: Cannot invoke method on null object",
2907 )
2908 .unwrap();
2909 assert!(
2910 error_result.confidence >= 0.7,
2911 "Error analysis with clear error messages should have high confidence"
2912 );
2913
2914 let refactoring_result = ThinkTool::plan_refactoring("Long method with 200 lines").unwrap();
2916 assert!(
2917 refactoring_result.confidence >= 0.8,
2918 "Clear refactoring problems should have high confidence"
2919 );
2920
2921 let thought = ThoughtData::new("Test thought".to_string(), 1, 3).with_confidence(0.85);
2923 assert_eq!(thought.confidence, 0.85);
2924
2925 let bounded_thought = ThoughtData::new("Test".to_string(), 1, 1).with_confidence(1.5); assert_eq!(bounded_thought.confidence, 1.0);
2928 }
2929
2930 #[test]
2931 fn test_sequential_thinking_step_quality() {
2932 let complex_problem = "Design and implement a secure, scalable user authentication system with OAuth2 integration";
2934
2935 let result =
2936 ThinkTool::think_about_code(complex_problem, Some("typescript"), Some("src/auth/"))
2937 .unwrap();
2938
2939 assert!(
2941 result.steps.len() >= 4,
2942 "Complex problems should generate more detailed analysis"
2943 );
2944
2945 let step_keywords = result
2947 .steps
2948 .iter()
2949 .map(|step| format!("{} {}", step.thought, step.reasoning).to_lowercase())
2950 .collect::<Vec<_>>();
2951
2952 assert!(
2954 step_keywords[0].contains("context")
2955 || step_keywords[0].contains("understand")
2956 || step_keywords[0].contains("analyz")
2957 );
2958
2959 let last_steps = &step_keywords[step_keywords.len().saturating_sub(2)..];
2961 assert!(last_steps.iter().any(|step| {
2962 step.contains("implement") || step.contains("solution") || step.contains("strategy")
2963 }));
2964
2965 for (i, step) in result.steps.iter().enumerate() {
2967 assert!(
2968 step.thought.len() >= 20,
2969 "Step {} thought should be substantial",
2970 i + 1
2971 );
2972 assert!(
2973 step.reasoning.len() >= 30,
2974 "Step {} reasoning should be detailed",
2975 i + 1
2976 );
2977
2978 for (j, other_step) in result.steps.iter().enumerate() {
2980 if i != j {
2981 assert_ne!(
2982 step.thought, other_step.thought,
2983 "Steps should not be identical"
2984 );
2985 }
2986 }
2987 }
2988
2989 assert!(
2991 result.conclusion.len() >= 50,
2992 "Conclusion should be comprehensive"
2993 );
2994 assert!(
2995 result.conclusion.contains("auth")
2996 || result.conclusion.contains("security")
2997 || result.conclusion.contains("OAuth")
2998 );
2999
3000 assert!(
3002 result.recommended_action.len() >= 30,
3003 "Recommended action should be detailed"
3004 );
3005 assert!(
3006 !result.recommended_action.contains("TODO")
3007 && !result.recommended_action.contains("...")
3008 );
3009
3010 let step_desc = StepDescription {
3012 description: "Analyze authentication requirements".to_string(),
3013 expected_outcome: "Clear understanding of auth needs".to_string(),
3014 next_conditions: vec!["Security requirements defined".to_string()],
3015 };
3016
3017 assert!(!step_desc.description.is_empty());
3018 assert!(!step_desc.expected_outcome.is_empty());
3019 assert!(!step_desc.next_conditions.is_empty());
3020 }
3021
3022 #[test]
3023 fn test_thinking_consistency() {
3024 let problem = "Optimize database query performance for user search";
3026
3027 let results: Vec<_> = (0..3)
3028 .map(|_| {
3029 ThinkTool::think_about_code(problem, Some("sql"), Some("queries/user_search.sql"))
3030 .unwrap()
3031 })
3032 .collect();
3033
3034 let problem_types: Vec<_> = results.iter().map(|r| &r.problem_type).collect();
3036 assert!(
3037 problem_types
3038 .iter()
3039 .all(|&pt| pt == &CodeProblemType::Performance)
3040 );
3041
3042 let confidences: Vec<_> = results.iter().map(|r| r.confidence).collect();
3044 let confidence_variance = {
3045 let mean = confidences.iter().sum::<f32>() / confidences.len() as f32;
3046 confidences.iter().map(|c| (c - mean).abs()).sum::<f32>() / confidences.len() as f32
3047 };
3048 assert!(
3049 confidence_variance < 0.1,
3050 "Confidence should be consistent across runs"
3051 );
3052
3053 let step_counts: Vec<_> = results.iter().map(|r| r.steps.len()).collect();
3055 let min_steps = *step_counts.iter().min().unwrap();
3056 let max_steps = *step_counts.iter().max().unwrap();
3057 assert!(
3058 max_steps - min_steps <= 1,
3059 "Step count should be consistent"
3060 );
3061
3062 let actions: Vec<_> = results.iter().map(|r| &r.recommended_action).collect();
3064 assert!(actions.iter().all(|action| {
3065 action.to_lowercase().contains("profile")
3066 || action.to_lowercase().contains("measure")
3067 || action.to_lowercase().contains("performance")
3068 }));
3069
3070 let basic_result = ThinkTool::think("How to solve this?").unwrap();
3072 assert!(basic_result.steps.len() >= 3);
3073 assert!(!basic_result.conclusion.is_empty());
3074 assert!(basic_result.confidence > 0.0);
3075 assert!(basic_result.thought_data.is_none());
3077 }
3078}