agtrace_runtime/client/
insights.rs1use crate::Result;
2use crate::ops::{
3 CorpusStats, IndexProgress, IndexService, StatsResult, collect_tool_stats, get_corpus_overview,
4};
5use agtrace_index::Database;
6use agtrace_providers::ProviderAdapter;
7use std::path::PathBuf;
8use std::sync::{Arc, Mutex};
9
10pub struct InsightOps {
11 db: Arc<Mutex<Database>>,
12 provider_configs: Arc<Vec<(String, PathBuf)>>,
13}
14
15impl InsightOps {
16 pub fn new(db: Arc<Mutex<Database>>, provider_configs: Arc<Vec<(String, PathBuf)>>) -> Self {
17 Self {
18 db,
19 provider_configs,
20 }
21 }
22
23 pub fn corpus_stats(
24 &self,
25 project_hash: Option<&agtrace_types::ProjectHash>,
26 limit: usize,
27 ) -> Result<CorpusStats> {
28 self.ensure_index_is_fresh()?;
29
30 let db = self.db.lock().unwrap();
31 get_corpus_overview(&db, project_hash, limit)
32 }
33
34 pub fn tool_usage(
35 &self,
36 limit: Option<usize>,
37 provider: Option<String>,
38 ) -> Result<StatsResult> {
39 self.ensure_index_is_fresh()?;
40
41 let db = self.db.lock().unwrap();
42 collect_tool_stats(&db, limit, provider)
43 }
44
45 fn ensure_index_is_fresh(&self) -> Result<()> {
46 let db = self.db.lock().unwrap();
47
48 let providers: Vec<(ProviderAdapter, PathBuf)> = self
49 .provider_configs
50 .iter()
51 .filter_map(|(name, path)| {
52 agtrace_providers::create_adapter(name)
53 .ok()
54 .map(|p| (p, path.clone()))
55 })
56 .collect();
57
58 let service = IndexService::new(&db, providers);
59
60 let scope = agtrace_types::ProjectScope::All;
62
63 service.run(scope, false, |_progress: IndexProgress| {})?;
64
65 Ok(())
66 }
67}