fix(mcp): wrap websocket activity broadcasts in JSON-RPC notifications
Fixes a critical bug where the Antigravity MCP client would crash with 'invalid message version tag' during long-running tool executions. The server was broadcasting raw JSON activity objects ({'type': 'activity', 'data': ...}) over the WebSocket connection without wrapping them in the required JSON-RPC 2.0 Notification envelope, violating the protocol expectation on the proxy stub.
This commit is contained in:
1 parent
208c5d448f
commit
da1b7cdc9d
6 files changed
+90
-86
No files matched your search
+17
-2
@@ -10,6 +10,7 @@ pub struct MemoryIndex {
|
||||
index: Index,
|
||||
reader: IndexReader,
|
||||
writer: Arc<Mutex<IndexWriter>>,
|
||||
needs_commit: Arc<std::sync::atomic::AtomicBool>,
|
||||
|
||||
// Schema fields
|
||||
pub id_field: Field,
|
||||
@@ -47,6 +48,7 @@ impl MemoryIndex {
|
||||
index,
|
||||
reader,
|
||||
writer: Arc::new(Mutex::new(writer)),
|
||||
needs_commit: Arc::new(std::sync::atomic::AtomicBool::new(false)),
|
||||
id_field,
|
||||
title_field,
|
||||
body_field,
|
||||
@@ -59,6 +61,7 @@ impl MemoryIndex {
|
||||
let writer = Arc::clone(&self.writer);
|
||||
let id_field = self.id_field;
|
||||
let id_val = e.name.clone();
|
||||
let needs_commit = Arc::clone(&self.needs_commit);
|
||||
|
||||
let doc = doc!(
|
||||
self.id_field => e.name.as_str(),
|
||||
@@ -72,6 +75,7 @@ impl MemoryIndex {
|
||||
let writer = writer.lock().unwrap_or_else(|e| e.into_inner());
|
||||
writer.delete_term(tantivy::Term::from_field_text(id_field, &id_val));
|
||||
writer.add_document(doc)?;
|
||||
needs_commit.store(true, std::sync::atomic::Ordering::SeqCst);
|
||||
Ok(())
|
||||
})
|
||||
}
|
||||
@@ -80,6 +84,7 @@ impl MemoryIndex {
|
||||
let writer = Arc::clone(&self.writer);
|
||||
let id_field = self.id_field;
|
||||
let id_val = t.id.clone();
|
||||
let needs_commit = Arc::clone(&self.needs_commit);
|
||||
|
||||
let doc = doc!(
|
||||
self.id_field => t.id.as_str(),
|
||||
@@ -93,6 +98,7 @@ impl MemoryIndex {
|
||||
let writer = writer.lock().unwrap_or_else(|e| e.into_inner());
|
||||
writer.delete_term(tantivy::Term::from_field_text(id_field, &id_val));
|
||||
writer.add_document(doc)?;
|
||||
needs_commit.store(true, std::sync::atomic::Ordering::SeqCst);
|
||||
Ok(())
|
||||
})
|
||||
}
|
||||
@@ -101,19 +107,24 @@ impl MemoryIndex {
|
||||
let writer = Arc::clone(&self.writer);
|
||||
let id_field = self.id_field;
|
||||
let id_val = id.to_string();
|
||||
let needs_commit = Arc::clone(&self.needs_commit);
|
||||
|
||||
tokio::task::spawn_blocking(move || {
|
||||
let writer = writer.lock().unwrap_or_else(|e| e.into_inner());
|
||||
writer.delete_term(tantivy::Term::from_field_text(id_field, &id_val));
|
||||
needs_commit.store(true, std::sync::atomic::Ordering::SeqCst);
|
||||
Ok(())
|
||||
})
|
||||
}
|
||||
|
||||
pub async fn commit(&self) -> tantivy::Result<()> {
|
||||
let writer = Arc::clone(&self.writer);
|
||||
let needs_commit = Arc::clone(&self.needs_commit);
|
||||
tokio::task::spawn_blocking(move || {
|
||||
let mut writer = writer.lock().unwrap_or_else(|e| e.into_inner());
|
||||
writer.commit()?;
|
||||
if needs_commit.swap(false, std::sync::atomic::Ordering::SeqCst) {
|
||||
let mut writer = writer.lock().unwrap_or_else(|e| e.into_inner());
|
||||
writer.commit()?;
|
||||
}
|
||||
Ok(())
|
||||
})
|
||||
.await
|
||||
@@ -182,6 +193,7 @@ impl MemoryIndex {
|
||||
let writer = Arc::clone(&self.writer);
|
||||
let id_field = self.id_field;
|
||||
let id_val = s.name.clone();
|
||||
let needs_commit = Arc::clone(&self.needs_commit);
|
||||
|
||||
let doc = doc!(
|
||||
self.id_field => s.name.as_str(),
|
||||
@@ -195,6 +207,7 @@ impl MemoryIndex {
|
||||
let writer = writer.lock().unwrap_or_else(|e| e.into_inner());
|
||||
writer.delete_term(tantivy::Term::from_field_text(id_field, &id_val));
|
||||
writer.add_document(doc)?;
|
||||
needs_commit.store(true, std::sync::atomic::Ordering::SeqCst);
|
||||
Ok(())
|
||||
})
|
||||
}
|
||||
@@ -203,6 +216,7 @@ impl MemoryIndex {
|
||||
let writer = Arc::clone(&self.writer);
|
||||
let id_field = self.id_field;
|
||||
let id_val = a.id.clone();
|
||||
let needs_commit = Arc::clone(&self.needs_commit);
|
||||
|
||||
let doc = doc!(
|
||||
self.id_field => a.id.as_str(),
|
||||
@@ -216,6 +230,7 @@ impl MemoryIndex {
|
||||
let writer = writer.lock().unwrap_or_else(|e| e.into_inner());
|
||||
writer.delete_term(tantivy::Term::from_field_text(id_field, &id_val));
|
||||
writer.add_document(doc)?;
|
||||
needs_commit.store(true, std::sync::atomic::Ordering::SeqCst);
|
||||
Ok(())
|
||||
})
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user