pub struct IndexSession { /* private fields */ }Expand description
An index on disk together with the backends that query and refresh it.
This is the whole lifecycle in one place - open, check the index still
matches the pipeline that built it, update it incrementally, persist it,
search it - so callers do not each reimplement it and drift apart. The
semtree CLI and the MCP server are both thin shells over this type.
use std::sync::Arc;
use semtree_rag::{IndexSession, SearchFilters, SearchMode};
use semtree_embed::fastembed::FastEmbedder;
use semtree_store::usearch::UsearchStore;
use semtree_embed::Embedder;
let embedder = Arc::new(FastEmbedder::new()?);
let store = Arc::new(UsearchStore::new(embedder.dimension())?);
let mut session = IndexSession::open(embedder, store, std::path::Path::new(".semtree"))?;
session.index(std::path::Path::new("."), false, |_, _| {}).await?;
session.save()?;
let hits = session
.search("where do we skip unchanged files", 5, SearchMode::Hybrid, &SearchFilters::default())
.await?;Implementations§
Source§impl IndexSession
impl IndexSession
Sourcepub fn open(
embedder: Arc<dyn Embedder>,
store: Arc<dyn VectorStore>,
index_dir: &Path,
) -> Result<Self, RagError>
pub fn open( embedder: Arc<dyn Embedder>, store: Arc<dyn VectorStore>, index_dir: &Path, ) -> Result<Self, RagError>
Open the index at index_dir, or start an empty session if there is
none yet.
An index built by a different embedder, store, or chunker is not
loaded: it is left on disk and flagged for rebuild, so the next
index call replaces it instead of mixing vectors that
cannot be compared. Query it before that and it looks empty, which is
the honest answer.
Sourcepub fn open_existing(
embedder: Arc<dyn Embedder>,
store: Arc<dyn VectorStore>,
index_dir: &Path,
) -> Result<Self, RagError>
pub fn open_existing( embedder: Arc<dyn Embedder>, store: Arc<dyn VectorStore>, index_dir: &Path, ) -> Result<Self, RagError>
Like open, but refuses to start without a usable index.
Use it on read-only paths, where an empty result would otherwise be
indistinguishable from a codebase that was never indexed.
Sourcepub fn pending_rebuild(&self) -> Option<&RebuildReason>
pub fn pending_rebuild(&self) -> Option<&RebuildReason>
Why the next index call will rebuild from scratch, if
it will. None means the index on disk is usable as-is.
Sourcepub async fn index(
&mut self,
source_root: &Path,
full: bool,
on_progress: impl Fn(usize, usize),
) -> Result<IndexReport, RagError>
pub async fn index( &mut self, source_root: &Path, full: bool, on_progress: impl Fn(usize, usize), ) -> Result<IndexReport, RagError>
Index source_root, skipping files whose content has not changed.
Set full to force a rebuild; otherwise a rebuild still happens when
pending_rebuild says the existing index
cannot be trusted. Progress is reported as (files_done, files_total).
Nothing is written to disk until save.
Sourcepub fn save(&self) -> Result<(), RagError>
pub fn save(&self) -> Result<(), RagError>
Persist the vectors, the chunk metadata and the manifest together. They are only consistent as a set, so they are always written as one.
Sourcepub async fn search(
&self,
query: &str,
top_k: usize,
mode: SearchMode,
filters: &SearchFilters,
) -> Result<Vec<SearchResult<'_>>, RagError>
pub async fn search( &self, query: &str, top_k: usize, mode: SearchMode, filters: &SearchFilters, ) -> Result<Vec<SearchResult<'_>>, RagError>
Search the index, returning at most top_k results that pass filters.
Filters are metadata narrowing applied after ranking, so the ranker is asked for extra candidates to compensate. Hits the registry cannot resolve are dropped: without a chunk there is no path, name or code to hand back.
Sourcepub async fn context(
&self,
query: &str,
top_k: usize,
mode: SearchMode,
) -> Result<ContextWindow, RagError>
pub async fn context( &self, query: &str, top_k: usize, mode: SearchMode, ) -> Result<ContextWindow, RagError>
Build a prompt-ready context window for query from the top top_k
chunks under mode.
Sourcepub fn stats(&self) -> IndexStats
pub fn stats(&self) -> IndexStats
What the index currently holds, including the live vector count.
Sourcepub fn registry(&self) -> &ChunkRegistry
pub fn registry(&self) -> &ChunkRegistry
The chunk metadata backing the index.
Auto Trait Implementations§
impl !RefUnwindSafe for IndexSession
impl !UnwindSafe for IndexSession
impl Freeze for IndexSession
impl Send for IndexSession
impl Sync for IndexSession
impl Unpin for IndexSession
impl UnsafeUnpin for IndexSession
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§fn in_current_span(self) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more