1use serde::{Deserialize, Serialize};
17
18pub mod context; pub mod git_relay; pub mod nlp; pub mod relevance; pub mod smart_ls; pub mod smart_read; pub mod unified_search; pub use context::ContextAnalyzer;
29pub use git_relay::{GitOperation, GitRelay, GitRelayResponse, GitResult};
30pub use nlp::{ParsedQuery, QueryParser, SearchIntent};
31pub use relevance::{ProjectContext, ProjectType, RelevanceEngine};
32pub use smart_ls::{SmartDirEntry, SmartLS, SmartLSResponse};
33pub use smart_read::{FileSection, SmartReadResponse, SmartReader};
34pub use unified_search::{SearchResult, SearchResultType, UnifiedSearch, UnifiedSearchResponse};
35
36#[derive(Debug, Clone, Serialize, Deserialize)]
38pub struct TaskContext {
39 pub task: String,
41 pub focus_areas: Vec<FocusArea>,
43 pub relevance_threshold: f32,
45 pub max_results: Option<usize>,
47}
48
49#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Hash)]
51pub enum FocusArea {
52 Authentication,
53 API,
54 Database,
55 Frontend,
56 Backend,
57 Testing,
58 Configuration,
59 Security,
60 Performance,
61 Documentation,
62 ErrorHandling,
63 Logging,
64 Deployment,
65 Dependencies,
66 Custom(String),
67}
68
69#[derive(Debug, Clone, Serialize, Deserialize)]
71pub struct RelevanceScore {
72 pub score: f32,
73 pub reasons: Vec<String>,
74 pub focus_matches: Vec<FocusArea>,
75}
76
77#[derive(Debug, Serialize, Deserialize)]
79pub struct SmartResponse<T> {
80 pub primary: Vec<T>,
82 pub secondary: Vec<T>,
84 pub context_summary: String,
86 pub token_savings: TokenSavings,
88 pub suggestions: Vec<String>,
90}
91
92#[derive(Debug, Serialize, Deserialize)]
94pub struct TokenSavings {
95 pub original_tokens: usize,
97 pub compressed_tokens: usize,
99 pub percentage_saved: f32,
101 pub method: String,
103}
104
105impl TokenSavings {
106 pub fn new(original: usize, compressed: usize, method: &str) -> Self {
107 let percentage = if original > 0 {
108 ((original - compressed) as f32 / original as f32) * 100.0
109 } else {
110 0.0
111 };
112
113 Self {
114 original_tokens: original,
115 compressed_tokens: compressed,
116 percentage_saved: percentage,
117 method: method.to_string(),
118 }
119 }
120}
121
122impl Default for TaskContext {
124 fn default() -> Self {
125 Self {
126 task: "General development".to_string(),
127 focus_areas: vec![FocusArea::API, FocusArea::Configuration],
128 relevance_threshold: 0.6,
129 max_results: Some(50),
130 }
131 }
132}
133
134impl FocusArea {
135 #[allow(clippy::should_implement_trait)]
137 pub fn from_str(s: &str) -> Self {
138 match s.to_lowercase().as_str() {
139 "auth" | "authentication" => FocusArea::Authentication,
140 "api" => FocusArea::API,
141 "db" | "database" => FocusArea::Database,
142 "frontend" | "ui" => FocusArea::Frontend,
143 "backend" | "server" => FocusArea::Backend,
144 "test" | "testing" => FocusArea::Testing,
145 "config" | "configuration" => FocusArea::Configuration,
146 "security" | "sec" => FocusArea::Security,
147 "performance" | "perf" => FocusArea::Performance,
148 "docs" | "documentation" => FocusArea::Documentation,
149 "error" | "errors" | "error_handling" => FocusArea::ErrorHandling,
150 "logging" | "logs" => FocusArea::Logging,
151 "deploy" | "deployment" => FocusArea::Deployment,
152 "deps" | "dependencies" => FocusArea::Dependencies,
153 _ => FocusArea::Custom(s.to_string()),
154 }
155 }
156
157 pub fn keywords(&self) -> Vec<&'static str> {
159 match self {
160 FocusArea::Authentication => vec![
161 "auth", "login", "password", "token", "session", "jwt", "oauth",
162 ],
163 FocusArea::API => vec![
164 "api", "endpoint", "route", "handler", "request", "response", "http",
165 ],
166 FocusArea::Database => vec![
167 "db",
168 "database",
169 "sql",
170 "query",
171 "table",
172 "schema",
173 "migration",
174 ],
175 FocusArea::Frontend => {
176 vec!["ui", "component", "react", "vue", "angular", "html", "css"]
177 }
178 FocusArea::Backend => vec![
179 "server",
180 "service",
181 "controller",
182 "model",
183 "business",
184 "logic",
185 ],
186 FocusArea::Testing => vec![
187 "test",
188 "spec",
189 "mock",
190 "assert",
191 "expect",
192 "unit",
193 "integration",
194 ],
195 FocusArea::Configuration => vec![
196 "config",
197 "env",
198 "settings",
199 "properties",
200 "yaml",
201 "json",
202 "toml",
203 ],
204 FocusArea::Security => vec![
205 "security",
206 "vulnerability",
207 "sanitize",
208 "validate",
209 "encrypt",
210 "hash",
211 ],
212 FocusArea::Performance => vec![
213 "performance",
214 "optimize",
215 "cache",
216 "memory",
217 "cpu",
218 "benchmark",
219 ],
220 FocusArea::Documentation => vec![
221 "doc",
222 "readme",
223 "comment",
224 "documentation",
225 "guide",
226 "manual",
227 ],
228 FocusArea::ErrorHandling => vec![
229 "error",
230 "exception",
231 "try",
232 "catch",
233 "panic",
234 "result",
235 "option",
236 ],
237 FocusArea::Logging => vec!["log", "logger", "debug", "info", "warn", "error", "trace"],
238 FocusArea::Deployment => vec![
239 "deploy",
240 "docker",
241 "kubernetes",
242 "ci",
243 "cd",
244 "pipeline",
245 "build",
246 ],
247 FocusArea::Dependencies => vec![
248 "dependency",
249 "import",
250 "require",
251 "package",
252 "module",
253 "crate",
254 ],
255 FocusArea::Custom(_s) => vec![], }
257 }
258}
259
260#[cfg(test)]
261mod tests {
262 use super::*;
263
264 #[test]
265 fn test_focus_area_parsing() {
266 assert_eq!(FocusArea::from_str("auth"), FocusArea::Authentication);
267 assert_eq!(FocusArea::from_str("API"), FocusArea::API);
268 assert_eq!(
269 FocusArea::from_str("custom_thing"),
270 FocusArea::Custom("custom_thing".to_string())
271 );
272 }
273
274 #[test]
275 fn test_token_savings() {
276 let savings = TokenSavings::new(1000, 300, "quantum-semantic");
277 assert_eq!(savings.percentage_saved, 70.0);
278 }
279
280 #[test]
281 fn test_focus_area_keywords() {
282 let auth_keywords = FocusArea::Authentication.keywords();
283 assert!(auth_keywords.contains(&"auth"));
284 assert!(auth_keywords.contains(&"login"));
285 }
286}