gobby_code/search/
semantic.rs1pub use crate::vector::code_symbols::{embed_query, vector_search};
6
7use crate::config::{CODE_SYMBOL_COLLECTION_PREFIX, Context};
8use gobby_core::qdrant::{CollectionScope, SearchRequest};
9
10pub fn semantic_search(ctx: &Context, query: &str, limit: usize) -> Vec<(String, f64)> {
11 let Some(embedding_config) = ctx.embedding.as_ref() else {
12 return vec![];
13 };
14 let Some(query_vector) = embed_query(embedding_config, query) else {
15 return vec![];
16 };
17
18 let collection = gobby_core::qdrant::collection_name(
19 "gcode",
20 CollectionScope::Custom(&format!(
21 "{CODE_SYMBOL_COLLECTION_PREFIX}{}",
22 ctx.project_id
23 )),
24 );
25 let request = SearchRequest {
26 vector: query_vector,
27 limit,
28 filter: None,
29 };
30
31 let Ok((hits, _state)) =
32 gobby_core::qdrant::with_qdrant(ctx.qdrant.as_ref(), Vec::new(), |config| {
33 gobby_core::qdrant::search(config, &collection, request)
34 })
35 else {
36 return vec![];
37 };
38
39 hits.into_iter()
40 .map(|hit| (hit.id, f64::from(hit.score)))
41 .collect()
42}
43
44#[cfg(test)]
45mod tests {
46 use super::*;
47 use crate::config::QdrantConfig;
48 use std::path::PathBuf;
49
50 fn make_ctx_no_qdrant() -> Context {
51 Context {
52 database_url: "postgresql://localhost/nonexistent".to_string(),
53 project_root: PathBuf::from("/nonexistent"),
54 project_id: "test".to_string(),
55 quiet: true,
56 falkordb: None,
57 qdrant: None,
58 embedding: None,
59 code_vectors: crate::config::CodeVectorSettings::default(),
60 daemon_url: None,
61 }
62 }
63
64 #[test]
65 fn test_semantic_search_no_qdrant() {
66 let ctx = make_ctx_no_qdrant();
67 let result = semantic_search(&ctx, "test query", 10);
68 assert!(result.is_empty());
69 }
70
71 #[test]
72 fn test_semantic_search_no_embedding_config() {
73 let ctx = Context {
74 qdrant: Some(QdrantConfig {
75 url: Some("http://localhost:6333".to_string()),
76 api_key: None,
77 }),
78 ..make_ctx_no_qdrant()
79 };
80 let result = semantic_search(&ctx, "test query", 10);
81 assert!(result.is_empty());
82 }
83}