| 317 | } |
| 318 | |
| 319 | async fn query(&self, query: &ContextQuery) -> anyhow::Result<ContextResult> { |
| 320 | let file_matches = self.search_files(&query.query, query.max_results).await?; |
| 321 | |
| 322 | let mut result = ContextResult::new("ripgrep"); |
| 323 | let mut total_tokens = 0usize; |
| 324 | |
| 325 | for file_match in file_matches { |
| 326 | if total_tokens >= query.max_tokens { |
| 327 | result.truncated = true; |
| 328 | break; |
| 329 | } |
| 330 | |
| 331 | let content = self.format_match(&file_match, &query.depth); |
| 332 | let token_count = content.split_whitespace().count(); |
| 333 | |
| 334 | if total_tokens + token_count > query.max_tokens { |
| 335 | result.truncated = true; |
| 336 | break; |
| 337 | } |
| 338 | |
| 339 | total_tokens += token_count; |
| 340 | |
| 341 | result.add_item( |
| 342 | ContextItem::new( |
| 343 | file_match.path.to_string_lossy().to_string(), |
| 344 | ContextType::Resource, |
| 345 | content, |
| 346 | ) |
| 347 | .with_token_count(token_count) |
| 348 | .with_relevance(file_match.relevance) |
| 349 | .with_source(format!("file:{}", file_match.path.display())) |
| 350 | .with_provenance("ripgrep") |
| 351 | .with_priority(0.6) |
| 352 | .with_trust(0.8) |
| 353 | .with_freshness(0.75) |
| 354 | .with_metadata("match_count", serde_json::json!(file_match.matches.len())), |
| 355 | ); |
| 356 | } |
| 357 | |
| 358 | Ok(result) |
| 359 | } |
| 360 | } |
| 361 | |
| 362 | // ============================================================================ |