jeevesagent.vectorstore.inmemory

In-memory vector store — cosine over a Python list.

Zero dependencies. Default for dev, tests, and small corpora (up to ~10K chunks before search latency starts to bite). For larger corpora swap to FAISSVectorStore (in-process ANN) or ChromaVectorStore / PostgresVectorStore (persistent).

Beyond the protocol contract this backend additionally supports:

  • Diversity (MMR) — pass diversity=0.3 to search() for varied top-k.

  • Hybrid searchsearch_hybrid() combines BM25 lexical scores with vector similarity via Reciprocal Rank Fusion.

  • Persistencesave() / load() round-trip the store to JSON on disk.

Classes

InMemoryVectorStore

In-process vector store backed by a Python list.

Module Contents

class jeevesagent.vectorstore.inmemory.InMemoryVectorStore(embedder: jeevesagent.core.protocols.Embedder)[source]

In-process vector store backed by a Python list.

async add(chunks: list[jeevesagent.loader.base.Chunk], ids: list[str] | None = None) list[str][source]
async count() int[source]
async delete(ids: list[str]) None[source]
classmethod from_chunks(chunks: list[jeevesagent.loader.base.Chunk], *, embedder: jeevesagent.core.protocols.Embedder, ids: list[str] | None = None) InMemoryVectorStore[source]
Async:

One-shot: construct an InMemoryVectorStore + add chunks.

classmethod from_texts(texts: list[str], *, embedder: jeevesagent.core.protocols.Embedder, metadatas: list[dict[str, Any]] | None = None, ids: list[str] | None = None) InMemoryVectorStore[source]
Async:

One-shot: construct an InMemoryVectorStore from raw text strings (each becomes a Chunk with the matching metadata dict, or empty if metadatas is None).

async get_by_ids(ids: list[str]) list[jeevesagent.loader.base.Chunk][source]
classmethod load(path: str | pathlib.Path, *, embedder: jeevesagent.core.protocols.Embedder) InMemoryVectorStore[source]
Async:

Restore a store previously save()-d. Pass the same embedder kind/dimensions or queries will produce nonsense scores.

async save(path: str | pathlib.Path) None[source]

Write the full store (chunks + vectors + ids) to a JSON file. The embedder is NOT serialized — supply the same embedder when calling load().

async search(query: str, *, k: int = 4, filter: collections.abc.Mapping[str, Any] | None = None, diversity: float | None = None) list[jeevesagent.vectorstore.base.SearchResult][source]
async search_by_vector(vector: list[float], *, k: int = 4, filter: collections.abc.Mapping[str, Any] | None = None, diversity: float | None = None) list[jeevesagent.vectorstore.base.SearchResult][source]
async search_hybrid(query: str, *, k: int = 4, filter: collections.abc.Mapping[str, Any] | None = None, alpha: float = 0.5) list[jeevesagent.vectorstore.base.SearchResult][source]

Hybrid lexical (BM25) + vector search via RRF.

alpha is in [0, 1]: 0 = pure BM25, 1 = pure vector, 0.5 = even weighting (RRF default). Both rankings are computed independently and fused by Reciprocal Rank Fusion, then the top-k survivors are returned.

Embeddings catch semantic similarity (“automobile” ↔ “car”), BM25 catches exact-term hits (model names, error codes, person names) — together they outperform either alone on most retrieval benchmarks.

property embedder: jeevesagent.core.protocols.Embedder
name = 'in-memory'