Custom embedders
Two paths exist. The rehydratable local embedder is persisted via TEXT_EMBEDDER.manifest and reattached automatically. A Python callable embedder is metadata-only — reopening without the same callable raises ConfigError.
def my_embedder(texts: list[str]) -> list[list[float]]:
return model.encode(texts).tolist()
client = elips.PersistentClient(
"/tmp/elips",
dimension=384,
metric="cosine",
embedder=my_embedder,
)Planner introspection
explain returns the strategy the planner chose, whether MetadataIndex narrowed the search, and the candidate count when narrowing occurred. Use it in tests to lock query shapes against accidental regressions.
plan = docs.explain(
[1.0, 0.0],
n_results=5,
where={"kind": "design"},
)
assert plan.metadata_accelerated
assert plan.strategy in {"exact_candidates", "hybrid_fusion"}Transactions
Transactions buffer add and remove in memory and commit atomically.
auto txn = db->begin_transaction();
txn.collection("documents").add(elips::Vector{{1.0F, 0.0F}});
txn.collection("documents").add(elips::Vector{{0.0F, 1.0F}});
txn.commit(); // both visible or neitherLineage & migration
EmbeddingLineage records the provider, model, and revision that produced each vector. When you migrate to a new embedder, you can filter on lineage to re-embed only the records that need it.
stale = docs.get(where={"__lineage.model": "bge-small"})
for r in stale:
docs.delete(ids=[r.key])
docs.add(text=r.text, metadata=r.meta, id=r.key)Recovery testing
Calling close() without a preceding checkpoint() leaves pending writes in the WAL. Inspect them with client.pending_writes(), then pair with elips verify in integration tests to assert recovery semantics across crash points.