vtcode_core/code/code_completion/engine/
mod.rs

1pub mod ranking;
2pub mod suggestions;
3
4pub use ranking::SuggestionRanker;
5pub use suggestions::CompletionSuggestion;
6
7use crate::code::code_completion::context::CompletionContext;
8use crate::code::code_completion::learning::CompletionLearningData;
9use serde::{Deserialize, Serialize};
10use std::collections::HashMap;
11use std::sync::Arc;
12use tokio::sync::RwLock;
13
14/// Type of completion suggestion
15#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
16pub enum CompletionKind {
17    Function,
18    Method,
19    Variable,
20    Class,
21    Struct,
22    Enum,
23    Trait,
24    Module,
25    Keyword,
26    Snippet,
27    Import,
28    Type,
29}
30
31/// Code completion engine
32pub struct CompletionEngine {
33    suggestion_cache: Arc<RwLock<HashMap<String, Vec<CompletionSuggestion>>>>,
34    learning_data: Arc<RwLock<CompletionLearningData>>,
35    performance_stats: Arc<RwLock<CompletionStats>>,
36}
37
38/// Performance statistics for completion engine
39#[derive(Debug, Clone, Default)]
40pub struct CompletionStats {
41    pub total_requests: usize,
42    pub cache_hits: usize,
43    pub average_response_time_ms: f64,
44    pub acceptance_rate: f64,
45}
46
47impl CompletionEngine {
48    pub fn new() -> Self {
49        Self {
50            suggestion_cache: Arc::new(RwLock::new(HashMap::new())),
51            learning_data: Arc::new(RwLock::new(CompletionLearningData::default())),
52            performance_stats: Arc::new(RwLock::new(CompletionStats::default())),
53        }
54    }
55
56    /// Generate completion suggestions for the given context
57    pub async fn complete(&self, context: &CompletionContext) -> Vec<CompletionSuggestion> {
58        // Check cache first
59        let cache_key = format!("{}:{}:{}", context.language, context.line, context.column);
60        {
61            let cache = self.suggestion_cache.read().await;
62            if let Some(cached) = cache.get(&cache_key) {
63                return cached.clone();
64            }
65        }
66
67        // Generate new suggestions based on context
68        let mut suggestions = Vec::new();
69
70        // Add keyword suggestions
71        let keywords = self.get_language_keywords(&context.language);
72        for keyword in keywords {
73            if keyword.starts_with(&context.prefix) {
74                suggestions.push(CompletionSuggestion {
75                    text: keyword.to_string(),
76                    kind: CompletionKind::Keyword,
77                    confidence: 0.8,
78                    context: context.clone(),
79                    metadata: HashMap::new(),
80                    acceptance_rate: 0.0,
81                    learning_data: CompletionLearningData::default(),
82                    accepted_count: 0,
83                    rejected_count: 0,
84                });
85            }
86        }
87
88        // Add snippet suggestions
89        let snippets = self.get_language_snippets(&context.language);
90        for snippet in snippets {
91            if snippet.label.starts_with(&context.prefix) {
92                suggestions.push(CompletionSuggestion {
93                    text: snippet.template,
94                    kind: CompletionKind::Snippet,
95                    confidence: 0.7,
96                    context: context.clone(),
97                    metadata: HashMap::from([
98                        ("label".to_string(), snippet.label),
99                        ("description".to_string(), snippet.description),
100                    ]),
101                    acceptance_rate: 0.0,
102                    learning_data: CompletionLearningData::default(),
103                    accepted_count: 0,
104                    rejected_count: 0,
105                });
106            }
107        }
108
109        // Cache the results
110        {
111            let mut cache = self.suggestion_cache.write().await;
112            cache.insert(cache_key, suggestions.clone());
113        }
114
115        suggestions
116    }
117
118    /// Record user feedback on a suggestion
119    pub async fn record_feedback(&self, suggestion_id: &str, accepted: bool) {
120        let mut learning_data = self.learning_data.write().await;
121
122        // Update acceptance statistics
123        let current_rate = learning_data
124            .pattern_acceptance
125            .get(suggestion_id)
126            .copied()
127            .unwrap_or(0.0);
128        let new_rate = if accepted {
129            (current_rate + 1.0) / 2.0
130        } else {
131            current_rate * 0.9
132        };
133        learning_data
134            .pattern_acceptance
135            .insert(suggestion_id.to_string(), new_rate);
136
137        // Update performance stats
138        let mut stats = self.performance_stats.write().await;
139        stats.total_requests += 1;
140        if accepted {
141            stats.acceptance_rate = (stats.acceptance_rate * (stats.total_requests - 1) as f64
142                + 1.0)
143                / stats.total_requests as f64;
144        }
145    }
146
147    /// Get language-specific keywords
148    fn get_language_keywords(&self, language: &str) -> Vec<&'static str> {
149        match language {
150            "rust" => vec![
151                "fn", "let", "mut", "const", "static", "struct", "enum", "impl", "trait", "mod",
152                "use", "pub", "crate", "super", "self", "Self", "async", "await", "move", "if",
153                "else", "match", "loop", "while", "for", "in", "break", "continue", "return", "as",
154                "dyn", "where", "unsafe",
155            ],
156            "python" => vec![
157                "def", "class", "if", "elif", "else", "for", "while", "try", "except", "finally",
158                "with", "as", "import", "from", "return", "yield", "lambda", "and", "or", "not",
159                "in", "is", "None", "True", "False", "self", "super",
160            ],
161            "javascript" => vec![
162                "function",
163                "const",
164                "let",
165                "var",
166                "if",
167                "else",
168                "for",
169                "while",
170                "try",
171                "catch",
172                "finally",
173                "return",
174                "async",
175                "await",
176                "class",
177                "extends",
178                "import",
179                "export",
180                "from",
181                "as",
182                "this",
183                "super",
184                "new",
185                "typeof",
186                "instanceof",
187            ],
188            _ => vec![],
189        }
190    }
191
192    /// Get language-specific snippets
193    fn get_language_snippets(&self, language: &str) -> Vec<CodeSnippet> {
194        match language {
195            "rust" => vec![
196                CodeSnippet {
197                    label: "fn".to_string(),
198                    template: "fn ${1:name}(${2:params}) -> ${3:ReturnType} {\n\t${0:// body}\n}".to_string(),
199                    description: "Function declaration".to_string(),
200                },
201                CodeSnippet {
202                    label: "impl".to_string(),
203                    template: "impl ${1:Trait} for ${2:Type} {\n\t${0:// implementation}\n}".to_string(),
204                    description: "Implementation block".to_string(),
205                },
206            ],
207            "python" => vec![
208                CodeSnippet {
209                    label: "def".to_string(),
210                    template: "def ${1:name}(${2:params}):\n\t${0:# body}".to_string(),
211                    description: "Function definition".to_string(),
212                },
213                CodeSnippet {
214                    label: "class".to_string(),
215                    template: "class ${1:Name}:\n\tdef __init__(self${2:params}):\n\t\t${0:# initialization}".to_string(),
216                    description: "Class definition".to_string(),
217                },
218            ],
219            "javascript" => vec![
220                CodeSnippet {
221                    label: "func".to_string(),
222                    template: "function ${1:name}(${2:params}) {\n\t${0:// body}\n}".to_string(),
223                    description: "Function declaration".to_string(),
224                },
225                CodeSnippet {
226                    label: "class".to_string(),
227                    template: "class ${1:Name} {\n\tconstructor(${2:params}) {\n\t\t${0:// initialization}\n\t}\n}".to_string(),
228                    description: "Class declaration".to_string(),
229                },
230            ],
231            _ => vec![],
232        }
233    }
234}
235
236impl Default for CompletionEngine {
237    fn default() -> Self {
238        Self::new()
239    }
240}
241
242/// Code snippet template
243#[derive(Debug, Clone)]
244pub struct CodeSnippet {
245    pub label: String,
246    pub template: String,
247    pub description: String,
248}