ELIPS is the local, in-process layer beneath your application. ANN and exact indexes, first-class document lineage, hybrid retrieval, WAL recovery, segmented persistence — without running a separate service.
import elips
client = elips.Client(dimension=128)
docs = client.get_or_create_collection("documents")
docs.add(
documents=["alpha design note", "beta incident runbook"],
metadatas=[{"kind": "design"}, {"kind": "ops"}],
)
for hit in docs.query(query_texts="alpha", n_results=2):
print(hit.key, hit.distance, hit.text, hit.meta)Architecture decisions worth illustrating. Every diagram in the docs is rendered the same way — hand-drawn, editorial, never stock.
The planner emits a QueryPlan with a strategy, candidate set, metadata acceleration flags, and any text component. You can read it directly — in Python or C++.
Resolve filters, choose strategy.
Narrow via the metadata filter index equality sets.
ANN, exact, or hybrid fusion.
Re-sort by distance or metadata.
Project requested fields and return.
One process. Advisory file locks coordinate readers and writers. No daemons, no sidecars.
Every record may carry text, chunk coordinates, and embedding lineage — restored across restarts.
HNSW, flat, and IVF plug into the same FAISS-style Index (IndexFlat/IndexIVFFlat/IndexHNSW). GPU paths follow the same contract.
Text, vector, and hybrid query() plus EQL share one planner. Lexical overlap fuses with vector distance.
Every mutation appends with CRC32C before the in-memory store changes. Corrupt tails truncate cleanly.
explain() returns the strategy, candidate set, and acceleration flags used by the query.
import elips
client = elips.PersistentClient("/tmp/elips", dimension=128, metric="cosine")
docs = client.get_or_create_collection("documents")
docs.add(documents=["alpha design note"], metadatas=[{"kind": "design"}])
hit = docs.query(query_texts="alpha", n_results=1)[0]
print(hit.text, hit.distance)#include "elips/elips.hpp"
auto db = elips::open(
":memory:",
elips::Config{}.dimension(128).metric(elips::Metric::cosine));
auto& docs = db->collection("documents");
docs.add_document("alpha design note",
{{"kind", std::string{"design"}}});
auto hits = docs.search_text("alpha", 1);Meaning lives in geometry. Embeddings turn language, code, and user behavior into points in ℝᵈ, and the only useful question becomes "what's near this point?" — the question relational databases were never built to answer.
A vector database is the missing primitive between raw embeddings and the agents, search bars, and recommenders that consume them. ELIPS makes it small enough to embed and durable enough to trust.
Every useful agent loop ends the same way — retrieve, reason, respond, remember. ELIPS lives inside the loop, not across a network boundary, so the retrieval step costs microseconds and the write-back is just another function call.
Every turn is embedded and added back into a collection for the next session.
Entity cards and stable facts live in their own collection and survive restarts.
PDFs, code, tickets — chunked with lineage so citations are exact.
Past tool outputs are searchable, so the agent learns from its own runs.
Five layers, no sidecars. The agent runtime calls one client; the client talks to collections; collections route through the planner and the backends; everything terminates in a WAL frame and a segment on disk.
HNSW for scale, flat/exact for ground truth, GPU for throughput — all behind one Index contract. The planner never branches on which one is mounted.
A query batcher gathers concurrent queries inside a tiny window and fires a single kernel. One batched launch, saturated cores, std::expected on every fallible call.
From pip install to GPU-accelerated production serving, with sketched diagrams and runnable Python + C++ on every page.