__all__ in
khora/__init__.py. Additive changes land in minor releases; breaking changes require
a major bump. Private imports (khora.engines.*, khora.query.engine,
khora.pipelines.flows) are not stable.
Khora
The primary facade. Delegates to a pluggable engine (default vectorcypher).
KhoraConfig, or nothing, to read
KHORA_DATABASE_URL / KHORA_NEO4J_URL.
run_migrations=True runs Alembic under an advisory lock on connect. Credential fields
are pydantic.SecretStr (rendered as '**********', call .get_secret_value() to read).
Namespaces
create_namespace is keyword-only, no positional name. Use ns.namespace_id (the
stable public id) everywhere below, not the row-level ns.id. See
Namespaces & isolation.
Writing
remember
session_id propagates to the document and its chunks for session-scoped recall and
forget_session.
remember_batch
remember(), and per-doc values override the top-level kwargs.
submit_batch
PENDING, returns immediately. Requires
kb.start_pending_processor() (after connect()) or it raises. await handle.wait()
blocks until every document’s on_result has fired.
Reading
recall
start_time / end_time are honored on all three engines (both naive or both aware).
Fusion weights, reranking, HyDE, and recency are global (KhoraConfig.query /
KHORA_QUERY_*). There’s no config= kwarg. See Retrieval.
context_text
RecallResult into a flat LLM-context string (chunks grouped by document
title, then --- Entities --- and --- Relationships --- sections).
Entity & document reads
namespace is required on these (accepts str | UUID). Cross-namespace ids resolve
to None / empty rather than leaking the foreign row. The isolation contract holds at
every layer (see Namespaces & isolation).
Deleting
forget_session cascade-deletes every document tagged with session_id (chunks via FK
cascade, graph cleanup via the engine). For TTL cleanup, the opt-in helper
khora.gc.expire_sessions(*, kb, before, namespace_id=None) calls forget_session for
each session whose newest document predates before. Khora runs no scheduler. Call it
from your own loop.
Result types
All result types are frozen, slotted dataclasses.RememberResult: document_id, namespace_id, chunks_created,
entities_extracted, relationships_created, metadata, llm_usage.
BatchResult: total / processed / skipped / failed, chunks / entities
/ relationships, metadata, llm_usage.
BatchHandle: id, total, and await handle.wait().
DocumentResult (per-doc on_result payload): document_id, namespace_id,
success, error, per-doc counts, llm_usage, skipped.
Stats: documents / chunks / entities / relationships, last_activity_at.
RecallResult
| Field | Type | Notes |
|---|---|---|
query | str | The original query |
namespace_id | UUID | Namespace searched |
chunks | list[RecallChunk] | Scored chunks (score is a typed field) |
entities | list[RecallEntity] | Scored entities with provenance ids |
relationships | list[RecallRelationship] | Connections between entities from VectorCypher’s graph traversal |
documents | list[DocumentProjection] | Deduplicated source docs |
engine_info | dict | Engine telemetry: always carries "engine", plus max_raw_vector_score |
usage | list[LLMUsage] | Tokens spent during recall |
chunks[i].document_id and every id in
entities[i].source_document_ids / relationships[i].source_document_ids appears in
documents[]. RecallChunk carries id, document_id, content, score,
occurred_at, connected_entity_ids, chunker_info.
SearchMode
Engines
vectorcypher is the default and the engine these docs cover. Prefer the engine=
argument to Khora(...) over create_engine directly. Custom engines must implement
the full MemoryEngineProtocol. See VectorCypher.
Expertise
ExpertiseConfig (a stable public API) defines a domain ontology, with entity/relationship
types plus a system prompt, correlation rules, and inference rules. See
Expertise & ontologies for the full guide:
Hooks & errors
kb.subscribe(event_type, callback, filter=None) / kb.unsubscribe(id) / kb.hooks.
See Semantic hooks. All domain errors subclass KhoraError.
Catch it at system boundaries.
input
Ingestion
What
remember() / remember_batch() / submit_batch() do under the hood.search
Retrieval
What
recall() does and how to read a RecallResult.