Skip to content

Commit 3a05fca

Browse files
committed
no-mistakes(test): Report mismatched daemon vectors instead of "embeddings building
1 parent cf0eae2 commit 3a05fca

2 files changed

Lines changed: 57 additions & 8 deletions

File tree

‎crates/codegraph-server/src/ai_query/engine.rs‎

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,19 @@ pub struct QueryEngine {
5050
/// Prepend split-identifier words to the embed text (helps static
5151
/// embedders; off by default to leave the transformer path unchanged).
5252
split_identifiers: std::sync::atomic::AtomicBool,
53+
/// Set when the watcher daemon this session attached to holds vectors
54+
/// built with different embed settings. No embed run will follow, so the
55+
/// search status must not say embeddings are building.
56+
daemon_vectors_mismatched: std::sync::atomic::AtomicBool,
5357
}
5458

59+
/// Search status when the attached watcher daemon's vectors were built with
60+
/// different embed settings than this session's.
61+
const DAEMON_VECTORS_MISMATCHED_STATUS: &str = "The --watch daemon's stored vectors were built \
62+
with different embedding settings, so semantic matching is unavailable this session - results \
63+
are from name/text search only. Restart the daemon with the same --full-body-embedding / \
64+
--split-identifiers / --embedding-model flags as this session.";
65+
5566
/// Max characters of function body for full-body embedding.
5667
/// ~512 tokens ≈ first 40-50 lines of code.
5768
const FULL_BODY_MAX_CHARS: usize = 2048;
@@ -397,9 +408,18 @@ impl QueryEngine {
397408
// cannot recover the words on its own. needs_word_split() keeps it
398409
// off for snake_case, where it does not help.
399410
split_identifiers: std::sync::atomic::AtomicBool::new(true),
411+
daemon_vectors_mismatched: std::sync::atomic::AtomicBool::new(false),
400412
}
401413
}
402414

415+
/// Record that the attached watcher daemon's vectors were built with
416+
/// different embed settings, so they will not load and nothing in this
417+
/// session will build replacements.
418+
pub fn set_daemon_vectors_mismatched(&self) {
419+
self.daemon_vectors_mismatched
420+
.store(true, std::sync::atomic::Ordering::Relaxed);
421+
}
422+
403423
/// Enable or disable full-body embedding mode.
404424
pub fn set_full_body_embedding(&self, enabled: bool) {
405425
self.full_body_embedding
@@ -1405,7 +1425,12 @@ impl QueryEngine {
14051425

14061426
let query_time_ms = start.elapsed().as_millis() as u64;
14071427

1408-
let embedding_status = if !self.are_embeddings_ready() {
1428+
let embedding_status = if self
1429+
.daemon_vectors_mismatched
1430+
.load(std::sync::atomic::Ordering::Relaxed)
1431+
{
1432+
Some(DAEMON_VECTORS_MISMATCHED_STATUS.to_string())
1433+
} else if !self.are_embeddings_ready() {
14091434
Some("Embeddings are building in the background. Semantic matching is temporarily unavailable — results are from name/text search only.".to_string())
14101435
} else {
14111436
None
@@ -3066,6 +3091,27 @@ mod tests {
30663091
assert_eq!(results.results[0].symbol.name, "validateEmail");
30673092
}
30683093

3094+
#[tokio::test]
3095+
async fn symbol_search_status_names_mismatched_daemon_vectors_not_a_build() {
3096+
let (engine, _) = create_test_engine().await;
3097+
let building = engine
3098+
.symbol_search("test", &SearchOptions::new())
3099+
.await
3100+
.embedding_status
3101+
.expect("no vectors yet");
3102+
assert!(building.contains("building"));
3103+
3104+
engine.set_daemon_vectors_mismatched();
3105+
let status = engine
3106+
.symbol_search("test", &SearchOptions::new())
3107+
.await
3108+
.embedding_status
3109+
.expect("mismatched daemon vectors leave semantic search unavailable");
3110+
assert!(!status.contains("building"), "{status}");
3111+
assert!(status.contains("different embedding settings"), "{status}");
3112+
assert!(status.contains("Restart the daemon"), "{status}");
3113+
}
3114+
30693115
#[tokio::test]
30703116
async fn test_symbol_search_with_type_filter() {
30713117
let (engine, graph) = create_test_engine().await;

‎crates/codegraph-server/src/mcp/server.rs‎

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1390,13 +1390,16 @@ impl McpServer {
13901390
// session, which is the cold-start cost attaching to a
13911391
// daemon exists to avoid. The daemon owns the set, so
13921392
// the daemon is what should rebuild it.
1393-
VectorLoad::Mismatched => tracing::warn!(
1394-
"Watcher daemon's vectors were built from different embed text - \
1395-
semantic search and similarity tools are unavailable this session. \
1396-
Restart the daemon (after an upgrade), or start it with the same \
1397-
--full-body-embedding / --split-identifiers / --embedding-model \
1398-
flags as this session."
1399-
),
1393+
VectorLoad::Mismatched => {
1394+
self.backend.query_engine.set_daemon_vectors_mismatched();
1395+
tracing::warn!(
1396+
"Watcher daemon's vectors were built from different embed text - \
1397+
semantic search and similarity tools are unavailable this session. \
1398+
Restart the daemon (after an upgrade), or start it with the same \
1399+
--full-body-embedding / --split-identifiers / --embedding-model \
1400+
flags as this session."
1401+
)
1402+
}
14001403
// The daemon owns this workspace and simply has not
14011404
// finished its first embed run. Re-embedding here would
14021405
// duplicate, in every attached session, exactly the

0 commit comments

Comments
 (0)