feat: implement branch-aware context switching and integrate tantivy fuzzy search index

This commit is contained in:
Riz Ashraf committed 2026-09-08 11:44:25 +01:00
1 parent e4ff476b6d
commit 3239e32866
6 files changed
+797 -2

No files matched your search

+91
View File
@@ -0,0 +1,91 @@
use tantivy::schema::*;
use tantivy::{doc, Index, IndexWriter, IndexReader, ReloadPolicy};
use std::sync::Mutex;
use crate::models::{Entity, Task, StickyNote, Adr, Snippet};
pub struct MemoryIndex {
index: Index,
reader: IndexReader,
writer: Mutex<IndexWriter>,
// Schema fields
pub id_field: Field,
pub title_field: Field,
pub body_field: Field,
pub type_field: Field,
pub namespace_field: Field,
}
impl MemoryIndex {
pub fn new() -> tantivy::Result<Self> {
let mut schema_builder = Schema::builder();
let id_field = schema_builder.add_text_field("id", STRING | STORED);
let title_field = schema_builder.add_text_field("title", TEXT | STORED);
let body_field = schema_builder.add_text_field("body", TEXT | STORED);
let type_field = schema_builder.add_text_field("type", STRING | STORED);
let namespace_field = schema_builder.add_text_field("namespace", STRING | STORED);
let schema = schema_builder.build();
let index = Index::create_in_ram(schema.clone());
let writer = index.writer(50_000_000)?;
let reader = index
.reader_builder()
.reload_policy(ReloadPolicy::OnCommitWithDelay)
.try_into()?;
Ok(Self {
index,
reader,
writer: Mutex::new(writer),
id_field,
title_field,
body_field,
type_field,
namespace_field,
})
}
pub fn index_entity(&self, e: &Entity) -> tantivy::Result<()> {
let mut writer = self.writer.lock().unwrap();
writer.add_document(doc!(
self.id_field => e.name.clone(),
self.title_field => e.name.clone(),
self.body_field => e.observations.join(" "),
self.type_field => "entity",
self.namespace_field => e.namespace.clone()
))?;
writer.commit()?;
Ok(())
}
pub fn index_task(&self, t: &Task) -> tantivy::Result<()> {
let mut writer = self.writer.lock().unwrap();
writer.add_document(doc!(
self.id_field => t.id.clone(),
self.title_field => t.title.clone(),
self.body_field => t.description.clone(),
self.type_field => "task",
self.namespace_field => "global"
))?;
writer.commit()?;
Ok(())
}
pub fn search(&self, query: &str, namespace: Option<&str>) -> tantivy::Result<Vec<String>> {
let searcher = self.reader.searcher();
let query_parser = tantivy::query::QueryParser::for_index(&self.index, vec![self.title_field, self.body_field]);
let q = query_parser.parse_query(query)?;
let top_docs = searcher.search(&q, &tantivy::collector::TopDocs::with_limit(50))?;
let mut results = Vec::new();
for (_score, doc_address) in top_docs {
let retrieved_doc = searcher.doc::<tantivy::TantivyDocument>(doc_address)?;
if let Some(val) = retrieved_doc.get_first(self.title_field) {
if let Some(t) = val.as_str() {
results.push(t.to_string());
}
}
}
Ok(results)
}
}