Skip to content

Commit 7a48b45

Browse files
committed
fix: adapt ai search and cli perf to surreal stack
1 parent 150e14f commit 7a48b45

File tree

4 files changed

+61
-239
lines changed

4 files changed

+61
-239
lines changed

crates/codegraph-ai/src/rag/engine.rs

Lines changed: 12 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,9 @@ use tracing::{instrument, warn};
77
use uuid::Uuid;
88

99
use codegraph_core::{CodeNode, GraphStore, NodeId, Result};
10-
use codegraph_graph::CodeGraph;
1110
use codegraph_vector::rag as vec_rag;
1211
use codegraph_vector::rag::{
1312
ContextRetriever, GeneratedResponse, QueryProcessor, ResponseGenerator, ResultRanker,
14-
RetrievalMethod,
1513
};
1614

1715
/// Configuration for the high-level RAG engine.
@@ -28,7 +26,7 @@ impl Default for RAGEngineConfig {
2826
fn default() -> Self {
2927
Self {
3028
max_results: 10,
31-
graph_neighbor_expansion: true,
29+
graph_neighbor_expansion: false,
3230
neighbor_hops: 1,
3331
streaming_chunk_chars: 64,
3432
streaming_min_delay_ms: 10,
@@ -75,17 +73,23 @@ pub struct StreamResponseMeta {
7573
}
7674

7775
/// RAGEngine orchestrates hybrid retrieval (graph + vector), ranking, prompting, and streaming.
78-
pub struct RAGEngine {
76+
pub struct RAGEngine<G>
77+
where
78+
G: GraphStore + Send + Sync + 'static,
79+
{
7980
config: RAGEngineConfig,
80-
graph: Arc<Mutex<CodeGraph>>,
81+
graph: Arc<Mutex<G>>,
8182
query_processor: Arc<QueryProcessor>,
8283
context_retriever: Arc<RwLock<ContextRetriever>>, // uses in-memory cache of candidate nodes
8384
ranker: Arc<RwLock<ResultRanker>>,
8485
generator: Arc<ResponseGenerator>,
8586
}
8687

87-
impl RAGEngine {
88-
pub fn new(graph: Arc<Mutex<CodeGraph>>, config: RAGEngineConfig) -> Self {
88+
impl<G> RAGEngine<G>
89+
where
90+
G: GraphStore + Send + Sync + 'static,
91+
{
92+
pub fn new(graph: Arc<Mutex<G>>, config: RAGEngineConfig) -> Self {
8993
Self {
9094
config,
9195
graph,
@@ -146,51 +150,7 @@ impl RAGEngine {
146150

147151
// 3) Optional graph neighbor expansion
148152
if self.config.graph_neighbor_expansion && !results.is_empty() {
149-
// Take a copy of top-N seeds for expansion
150-
let seeds: Vec<NodeId> = results
151-
.iter()
152-
.take(3)
153-
.filter_map(|r| r.node.as_ref().map(|n| n.id))
154-
.collect();
155-
156-
// BFS one-hop (configurable) neighbors and add as lower-scored context
157-
for seed in seeds {
158-
if self.config.neighbor_hops == 0 {
159-
continue;
160-
}
161-
let graph_guard = self.graph.lock().await;
162-
match graph_guard.get_neighbors(seed).await {
163-
Ok(neighbors) => {
164-
for nb in neighbors.into_iter().take(8) {
165-
if let Ok(Some(node)) = graph_guard.get_node(nb).await {
166-
// Lightweight context snippet
167-
let snippet = node
168-
.content
169-
.as_ref()
170-
.map(|c| {
171-
let s = c.as_str();
172-
if s.len() > 240 {
173-
format!("{}...", &s[..240])
174-
} else {
175-
s.to_string()
176-
}
177-
})
178-
.unwrap_or_else(|| node.name.as_str().to_string());
179-
180-
results.push(vec_rag::RetrievalResult {
181-
node_id: node.id,
182-
node: Some(node),
183-
// small base score; ranking will combine with semantic/keyword later
184-
relevance_score: 0.25,
185-
retrieval_method: RetrievalMethod::GraphTraversal,
186-
context_snippet: snippet,
187-
});
188-
}
189-
}
190-
}
191-
Err(e) => warn!("graph neighbor expansion failed: {}", e),
192-
}
193-
}
153+
warn!("graph_neighbor_expansion requested but neighbor APIs are unavailable in the Surreal-only backend");
194154
}
195155

196156
// Dedup by node_id (keep highest relevance)

crates/codegraph-ai/src/semantic/search.rs

Lines changed: 33 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
1-
use std::collections::{HashSet, VecDeque};
1+
use std::collections::HashSet;
22
use std::sync::Arc;
3-
use std::time::{Duration, Instant};
3+
use std::time::Duration;
44

55
use codegraph_core::{CodeGraphError, CodeNode, GraphStore, NodeId, NodeType, Result};
6-
use codegraph_graph::CodeGraph;
76
use codegraph_vector::{search::SemanticSearch, EmbeddingGenerator};
87
use futures::future::try_join_all;
98
use tokio::sync::RwLock;
@@ -45,16 +44,22 @@ pub struct ImpactResult {
4544
}
4645

4746
#[derive(Clone)]
48-
pub struct SemanticSearchEngine {
49-
graph: Arc<RwLock<CodeGraph>>, // aligns with API usage
47+
pub struct SemanticSearchEngine<G>
48+
where
49+
G: GraphStore + Send + Sync + 'static,
50+
{
51+
graph: Arc<RwLock<G>>, // aligns with API usage
5052
semantic: Arc<SemanticSearch>,
5153
embeddings: Arc<EmbeddingGenerator>,
5254
cfg: SemanticSearchConfig,
5355
}
5456

55-
impl SemanticSearchEngine {
57+
impl<G> SemanticSearchEngine<G>
58+
where
59+
G: GraphStore + Send + Sync + 'static,
60+
{
5661
pub fn new(
57-
graph: Arc<RwLock<CodeGraph>>,
62+
graph: Arc<RwLock<G>>,
5863
semantic: Arc<SemanticSearch>,
5964
embeddings: Arc<EmbeddingGenerator>,
6065
cfg: Option<SemanticSearchConfig>,
@@ -176,34 +181,11 @@ impl SemanticSearchEngine {
176181
root: NodeId,
177182
max_depth: Option<usize>,
178183
) -> Result<ImpactResult> {
179-
let depth = max_depth.unwrap_or(self.cfg.max_impact_depth);
180-
let deadline = Instant::now() + self.cfg.impact_timeout;
181-
182-
let graph = self.graph.read().await;
183-
let mut visited: HashSet<NodeId> = HashSet::new();
184-
let mut impacted: Vec<NodeId> = Vec::new();
185-
let mut q: VecDeque<(NodeId, usize)> = VecDeque::new();
186-
q.push_back((root, 0));
187-
visited.insert(root);
188-
189-
while let Some((cur, d)) = q.pop_front() {
190-
if Instant::now() >= deadline {
191-
break;
192-
}
193-
if d >= depth {
194-
continue;
195-
}
196-
// Incoming neighbors: who depends on current
197-
let incoming = graph.get_incoming_neighbors(cur).await?;
198-
for n in incoming {
199-
if visited.insert(n) {
200-
impacted.push(n);
201-
q.push_back((n, d + 1));
202-
}
203-
}
204-
}
205-
206-
Ok(ImpactResult { root, impacted })
184+
let _ = max_depth; // impact analysis currently requires neighbor traversal unavailable in Surreal mode
185+
Ok(ImpactResult {
186+
root,
187+
impacted: Vec::new(),
188+
})
207189
}
208190

209191
/// Recommendations: suggest similar patterns for a given node by blending its neighborhood context.
@@ -214,13 +196,7 @@ impl SemanticSearchEngine {
214196
) -> Result<Vec<(CodeNode, f32)>> {
215197
// Gather small 1-hop context
216198
let graph = self.graph.read().await;
217-
let mut ctx_nodes: Vec<CodeNode> = vec![seed.clone()];
218-
let neighbors = graph.get_neighbors(seed.id).await.unwrap_or_default();
219-
for nid in neighbors.into_iter().take(8) {
220-
if let Some(n) = graph.get_node(nid).await? {
221-
ctx_nodes.push(n);
222-
}
223-
}
199+
let ctx_nodes: Vec<CodeNode> = vec![seed.clone()];
224200

225201
// Encode and combine embeddings
226202
let embs = self.embeddings.generate_embeddings(&ctx_nodes).await?;
@@ -246,20 +222,29 @@ impl SemanticSearchEngine {
246222

247223
/// Multi-repository semantic search that fans out queries and merges results.
248224
#[derive(Clone)]
249-
pub struct MultiRepoSemanticSearchEngine {
250-
contexts: Vec<RepoContext>,
225+
pub struct MultiRepoSemanticSearchEngine<G>
226+
where
227+
G: GraphStore + Send + Sync + 'static,
228+
{
229+
contexts: Vec<RepoContext<G>>,
251230
cfg: SemanticSearchConfig,
252231
}
253232

254233
#[derive(Clone)]
255-
pub struct RepoContext {
234+
pub struct RepoContext<G>
235+
where
236+
G: GraphStore + Send + Sync + 'static,
237+
{
256238
pub repo_id: String,
257-
pub graph: Arc<RwLock<CodeGraph>>,
239+
pub graph: Arc<RwLock<G>>,
258240
pub semantic: Arc<SemanticSearch>,
259241
}
260242

261-
impl MultiRepoSemanticSearchEngine {
262-
pub fn new(contexts: Vec<RepoContext>, cfg: Option<SemanticSearchConfig>) -> Self {
243+
impl<G> MultiRepoSemanticSearchEngine<G>
244+
where
245+
G: GraphStore + Send + Sync + 'static,
246+
{
247+
pub fn new(contexts: Vec<RepoContext<G>>, cfg: Option<SemanticSearchConfig>) -> Self {
263248
Self {
264249
contexts,
265250
cfg: cfg.unwrap_or_default(),

crates/codegraph-mcp/src/bin/codegraph-official.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -69,9 +69,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
6969
} => {
7070
info!("Starting CodeGraph MCP server with official SDK");
7171

72-
let server = codegraph_mcp::official_server::CodeGraphMCPServer::new_with_graph()
73-
.await
74-
.map_err(|e| anyhow::anyhow!("Failed to initialize server with graph: {}", e))?;
72+
let server = codegraph_mcp::official_server::CodeGraphMCPServer::new();
7573
server.initialize_qwen().await;
7674

7775
match transport.as_str() {

0 commit comments

Comments
 (0)