Skip to main content

KhiveRuntime

Struct KhiveRuntime 

Source
pub struct KhiveRuntime { /* private fields */ }
Expand description

Composable runtime handle used by the MCP server.

Wraps a StorageBackend and provides namespace-scoped accessor methods for each storage capability, plus a lazily-loaded embedder.

Implementations§

Source§

impl KhiveRuntime

Source

pub async fn update_entity( &self, token: &NamespaceToken, id: Uuid, patch: EntityPatch, ) -> RuntimeResult<Entity>

Patch-style entity update.

Only fields set to Some(_) are changed. Re-indexes FTS5 (and vectors if configured) when name or description changes; skips re-indexing for property/tag-only patches.

Returns RuntimeError::NotFound if the entity does not exist or belongs to a different namespace. Namespace isolation is enforced at the runtime layer.

Source

pub async fn merge_entity( &self, token: &NamespaceToken, into_id: Uuid, from_id: Uuid, strategy: EntityDedupMergePolicy, dry_run: bool, ) -> RuntimeResult<MergeSummary>

Merge from_id into into_id.

All edges incident to from_id are rewired to into_id. Self-loops that would result from the rewire are dropped. Properties and tags are merged per strategy. from_id is tombstoned with merge provenance and removed from indexes. Returns a summary.

If dry_run is true, computes and returns the planned summary without mutating any rows.

Atomic: all SQL (entity reads/writes, edge rewires, FTS updates, vec-index delete) runs on a single pool connection inside one BEGIN IMMEDIATE transaction via merge_entity_sql. If embedding vectors are configured, the vector re-insert for into_id is performed after the transaction (requires async embedding computation).

Source

pub async fn update_note( &self, token: &NamespaceToken, id: Uuid, patch: NotePatch, ) -> RuntimeResult<Note>

Patch-style note update.

Source

pub async fn merge_note( &self, token: &NamespaceToken, into_id: Uuid, from_id: Uuid, strategy: EntityDedupMergePolicy, content_strategy: ContentMergeStrategy, dry_run: bool, ) -> RuntimeResult<MergeSummary>

Merge from_id note into into_id note.

Both notes must exist in the namespace and have the same kind. Content is merged per content_strategy. Properties are merged per strategy. from_id is tombstoned (status=‘deleted’, deleted_at set). Returns a summary.

If dry_run is true, computes and returns the planned summary without mutating any rows, edges, or indexes.

Source§

impl KhiveRuntime

Source

pub async fn hybrid_search_with_strategy( &self, token: &NamespaceToken, query_text: &str, query_vector: Option<Vec<f32>>, strategy: FusionStrategy, limit: u32, ) -> RuntimeResult<Vec<SearchHit>>

Hybrid search with a caller-supplied fusion strategy.

Source§

impl KhiveRuntime

Source

pub async fn bfs_traverse( &self, token: &NamespaceToken, start: Uuid, options: TraversalOptions, ) -> RuntimeResult<Vec<PathNode>>

BFS traversal from start, returning nodes in level order.

The first element is always the start node (via_edge = None, depth = 0). Nodes already visited are skipped so the result set is deduplicated.

Source

pub async fn shortest_path( &self, token: &NamespaceToken, from: Uuid, to: Uuid, max_depth: usize, ) -> RuntimeResult<Option<Vec<PathNode>>>

Bidirectional BFS shortest path from from to to.

Returns Some(path) where path[0] is from and path.last() is to, or None if no path exists within max_depth hops. For from == to returns Some with a single-node path immediately.

Source§

impl KhiveRuntime

Source

pub async fn create_entity( &self, token: &NamespaceToken, kind: &str, entity_type: Option<&str>, name: &str, description: Option<&str>, properties: Option<Value>, tags: Vec<String>, ) -> RuntimeResult<Entity>

Create and persist a new entity.

Source

pub async fn get_entity( &self, token: &NamespaceToken, id: Uuid, ) -> RuntimeResult<Entity>

Retrieve an entity by ID, enforcing namespace isolation.

Returns Err(NotFound) if the entity does not exist or belongs to a different namespace (indistinguishable — no cross-namespace existence oracle).

Source

pub async fn get_entities_by_ids( &self, token: &NamespaceToken, ids: &[Uuid], ) -> RuntimeResult<Vec<Entity>>

Fetch multiple entities by ID, returning only those that exist in the caller’s namespace. Missing or namespace-mismatched IDs are silently omitted so that batch lookups don’t abort on a single stale reference.

Source

pub async fn list_entities( &self, token: &NamespaceToken, kind: Option<&str>, entity_type: Option<&str>, limit: u32, offset: u32, ) -> RuntimeResult<Vec<Entity>>

List entities in a namespace, optionally filtered by kind and entity_type.

Source

pub async fn list_entities_tagged( &self, token: &NamespaceToken, kind: Option<&str>, domain_tag: Option<&str>, limit: u32, offset: u32, ) -> RuntimeResult<Vec<Entity>>

List entities filtered by kind, optional domain tag, limit, and offset.

When domain_tag is Some, the query is restricted at the storage layer via EntityFilter::tags_any so the page result already reflects the domain constraint. This avoids the silent truncation that occurs when filtering post-page (K-3).

Source

pub async fn count_entities_tagged( &self, token: &NamespaceToken, kind: Option<&str>, domain_tag: Option<&str>, ) -> RuntimeResult<u64>

Count entities filtered by kind and optional domain tag.

Used to report a meaningful total alongside a paginated listing (K-6).

Source

pub async fn list_events( &self, token: &NamespaceToken, filter: EventFilter, page: PageRequest, ) -> RuntimeResult<Page<Event>>

List events in the namespace proven by the caller token.

Create a directed edge between two substrates.

Enforces the three-case relation contract via validate_edge_relation_endpoints. See that method for the full contract.

For symmetric relations (competes_with, composed_with) the endpoint pair is canonicalised to source_uuid < target_uuid so that A→B and B→A deduplicate to one row (F012).

metadata is validated against governed keys; dependency_kind is inferred for depends_on edges when absent (F013).

target_backend is always None for locally-routed edges written through this path. Both endpoints must exist in the local namespace, so setting target_backend = None is the only valid choice (F161).

A record that exists but belongs to a different namespace is treated as not found (fail-closed; no cross-namespace existence leak).

Source

pub async fn neighbors( &self, token: &NamespaceToken, node_id: Uuid, direction: Direction, limit: Option<u32>, relations: Option<Vec<EdgeRelation>>, ) -> RuntimeResult<Vec<NeighborHit>>

Get immediate neighbors of a node, optionally filtered by relation type.

Pass relations: Some(vec![EdgeRelation::Annotates]) to retrieve only annotation edges, enabling cross-substrate navigation.

Symmetric relations (competes_with, composed_with) are stored with the canonical source as the lower UUID. Direction normalization is applied in neighbors_with_query so both callers see correct results.

Source

pub async fn neighbors_with_query( &self, token: &NamespaceToken, node_id: Uuid, query: NeighborQuery, ) -> RuntimeResult<Vec<NeighborHit>>

Get neighbors with full query control (includes min_weight).

Applies symmetric-relation direction normalization: if the relations filter contains only symmetric relations the direction is overridden to Both so edges stored in canonical order are always found.

Soft-deleted entity nodes are excluded from results unless the caller explicitly requested them (future: include_deleted flag; currently always false per Fix 2).

Source

pub async fn traverse( &self, token: &NamespaceToken, request: TraversalRequest, ) -> RuntimeResult<Vec<GraphPath>>

Traverse the graph from a set of root nodes.

Roots in a foreign namespace are silently filtered before storage expansion. Soft-deleted entity nodes are excluded from results (Fix 2).

Source

pub async fn create_note( &self, token: &NamespaceToken, kind: &str, name: Option<&str>, content: &str, salience: Option<f64>, properties: Option<Value>, annotates: Vec<Uuid>, ) -> RuntimeResult<Note>

Create and persist a note, optionally with properties and annotation targets.

After creating the note:

  • Always indexes into FTS5 at the notes_<namespace> key.
  • If an embedding model is configured, indexes into the vector store with SubstrateKind::Note.
  • For each UUID in annotates, creates an EdgeRelation::Annotates edge from the note to that target.
Source

pub async fn create_note_with_decay( &self, token: &NamespaceToken, kind: &str, name: Option<&str>, content: &str, salience: Option<f64>, decay_factor: f64, properties: Option<Value>, annotates: Vec<Uuid>, ) -> RuntimeResult<Note>

Like [create_note] but also sets a non-zero decay factor on the note.

Source

pub async fn create_note_with_decay_for_embedding_model( &self, token: &NamespaceToken, kind: &str, name: Option<&str>, content: &str, salience: Option<f64>, decay_factor: f64, properties: Option<Value>, annotates: Vec<Uuid>, embedding_model: Option<&str>, ) -> RuntimeResult<Note>

Like [create_note_with_decay] but targets a specific embedding model.

Source

pub async fn list_notes( &self, token: &NamespaceToken, kind: Option<&str>, limit: u32, offset: u32, ) -> RuntimeResult<Vec<Note>>

List notes, optionally filtered by kind.

Source

pub async fn search_notes( &self, token: &NamespaceToken, query_text: &str, query_vector: Option<Vec<f32>>, limit: u32, note_kind: Option<&str>, include_superseded: bool, ) -> RuntimeResult<Vec<NoteSearchHit>>

Search notes using a hybrid FTS5 + vector pipeline with salience weighting.

Pipeline:

  1. FTS5 query against notes_<namespace>.
  2. If embedding model is configured: vector search filtered to kind="note".
  3. RRF fusion (k=60).
  4. Salience-weighted rerank: score *= (0.5 + 0.5 * note.salience).
  5. Filter soft-deleted notes (deleted_at IS NOT NULL).
  6. Truncate to limit.
Source

pub async fn resolve_prefix( &self, token: &NamespaceToken, prefix: &str, ) -> RuntimeResult<Option<Uuid>>

Resolve a short UUID prefix (8+ hex chars) to a full UUID.

Searches entities, notes, and edges tables for a UUID starting with the given prefix, scoped to the caller’s namespace. Returns Ok(Some(uuid)) if exactly one match is found, Ok(None) if no matches, or an error if ambiguous (multiple matches).

Source

pub async fn resolve( &self, token: &NamespaceToken, id: Uuid, ) -> RuntimeResult<Option<Resolved>>

Resolve a UUID to its substrate kind by trying entity, then note, then event stores.

Returns None if the UUID is not found in any substrate. Cost: at most 3 store lookups per call (cheap for v0.1).

Source

pub async fn delete_note( &self, token: &NamespaceToken, id: Uuid, hard: bool, ) -> RuntimeResult<bool>

Delete a note by ID, enforcing namespace isolation.

On hard delete, cascades to remove all incident edges (both inbound and outbound) and cleans up FTS and vector indexes, preventing dangling references for annotates edges that target this note. Soft delete also cleans FTS and vector indexes; edges are left in place.

Returns Ok(false) if the note does not exist or belongs to a different namespace (wrong-namespace is indistinguishable from absent).

Source§

impl KhiveRuntime

Source

pub async fn query( &self, token: &NamespaceToken, query: &str, ) -> RuntimeResult<Vec<SqlRow>>

Execute a GQL or SPARQL query string, returning raw SQL rows.

The query is compiled to SQL with the namespace scope applied. GQL syntax: MATCH (a:concept)-[e:extends]->(b) RETURN a, b LIMIT 10 SPARQL syntax: SELECT ?a WHERE { ?a :kind "concept" . }

Source

pub async fn query_with_metadata( &self, token: &NamespaceToken, query: &str, opts: CompileOptions, ) -> RuntimeResult<QueryResult>

Execute a GQL/SPARQL query, returning rows and any validation warnings.

Source

pub async fn delete_entity( &self, token: &NamespaceToken, id: Uuid, hard: bool, ) -> RuntimeResult<bool>

Delete an entity by ID (soft delete by default).

On hard delete, cascades to remove all incident edges (both inbound and outbound) to prevent dangling references. Soft delete also cleans FTS and vector indexes; edges are left in place.

Returns Err(NotFound) if the entity does not exist or belongs to a different namespace (indistinguishable — no existence oracle).

Source

pub async fn count_entities( &self, token: &NamespaceToken, kind: Option<&str>, ) -> RuntimeResult<u64>

Count entities in a namespace, optionally filtered.

Source

pub async fn get_edge( &self, token: &NamespaceToken, edge_id: Uuid, ) -> RuntimeResult<Option<Edge>>

Fetch a single edge by id, enforcing namespace isolation.

Returns Err(NotFound) if the edge exists in a different namespace, Ok(None) if no edge with that id exists at all.

Source

pub async fn list_edges( &self, token: &NamespaceToken, filter: EdgeListFilter, limit: u32, ) -> RuntimeResult<Vec<Edge>>

List edges matching filter. limit is capped at 1000; defaults to 100.

Source

pub async fn update_edge( &self, token: &NamespaceToken, edge_id: Uuid, patch: EdgePatch, ) -> RuntimeResult<Edge>

Patch-style edge update. Only Some(_) fields are applied.

When relation is Some(new_rel), validates that the edge’s existing endpoints are legal for new_rel before persisting. Weight-only updates (relation = None) skip validation. Returns InvalidInput if the new relation would violate the three-case endpoint contract; the edge is NOT mutated on error.

For symmetric relations (competes_with, composed_with), endpoint order is canonicalised to source_uuid < target_uuid after validation. If a canonical row already exists at the target triple, the non-canonical edge is deleted and the existing canonical row is refreshed (DELETE + UPDATE pattern, mirroring merge_entity_sql).

Source

pub async fn delete_edge( &self, token: &NamespaceToken, edge_id: Uuid, hard: bool, ) -> RuntimeResult<bool>

Hard-delete an edge by id.

Cascades to remove any annotates edges whose target is the deleted edge (annotates is note → anything; deleting an edge target leaves annotation edges dangling if not cleaned up). Returns true if the primary edge was removed.

If edge_id does not refer to an edge (e.g. the caller passes an entity or note UUID by mistake), this method returns Ok(false) immediately with no side effects — it does not cascade inbound edges of the non-edge record.

Source

pub async fn count_edges( &self, token: &NamespaceToken, filter: EdgeListFilter, ) -> RuntimeResult<u64>

Count edges matching filter.

Source

pub async fn build_edge( &self, token: &NamespaceToken, spec: &LinkSpec, ) -> RuntimeResult<Edge>

Validate and construct an edge from a LinkSpec without writing to storage.

Applies the full edge contract (endpoint validation, symmetric canonicalization, dependency_kind inference and metadata validation). Returns the constructed Edge on success; the caller is responsible for persisting it (e.g. via upsert_edge or link_many).

The token must be a pre-authorized namespace token from the dispatch layer. If spec.namespace is set it must match token.namespace(); a mismatch returns RuntimeError::InvalidInput.

Validate and atomically upsert a batch of edges.

All edges are validated and constructed with build_edge before any write. If validation fails for any entry the entire batch is rejected (no writes occur). On success, all edges are persisted in a single atomic transaction via upsert_edges.

After the bulk upsert, each edge is read back by its natural key (namespace, source_id, target_id, relation) so that the returned IDs are always the persisted row IDs, not the locally-generated UUIDs that may have been displaced by an ON CONFLICT DO UPDATE. This mirrors the H1 fix applied to singleton link() and prevents phantom-ID exposure when callers upsert overlapping triples with verbose=true.

All specs must share the same namespace; the namespace is taken from token (or validated against it if spec.namespace is set).

Source§

impl KhiveRuntime

Source

pub async fn export_kg( &self, token: &NamespaceToken, ) -> RuntimeResult<KgArchive>

Export all entities and edges in a namespace to a portable JSON archive.

Edge collection: all entity IDs in the namespace are gathered first; query_edges is then called with those IDs as source_ids. This captures every edge whose source entity belongs to the namespace.

Source

pub async fn export_kg_json( &self, token: &NamespaceToken, ) -> RuntimeResult<String>

Export to a JSON string (convenience wrapper around export_kg).

Source

pub async fn import_kg( &self, archive: &KgArchive, token: &NamespaceToken, ) -> RuntimeResult<ImportSummary>

Import an archive into target_namespace.

If target_namespace is None, the archive’s own namespace is used.

  • Entities: upserted by ID; existing records are overwritten.
  • Edges: upserted; existing records are overwritten.
  • Validation: format != "khive-kg" or unsupported version → InvalidInput. Invalid edge relations are caught at JSON deserialization time.
Source

pub async fn import_kg_json( &self, json: &str, token: &NamespaceToken, ) -> RuntimeResult<ImportSummary>

Import from a JSON string (convenience wrapper around import_kg).

Source§

impl KhiveRuntime

Source

pub async fn embed(&self, text: &str) -> RuntimeResult<Vec<f32>>

Generate an embedding vector for text using the configured default model.

First call lazily loads model weights (cold start cost). Subsequent calls reuse them. Returns Unconfigured("embedding_model") if no model is configured.

Source

pub async fn embed_with_model( &self, model_name: &str, text: &str, ) -> RuntimeResult<Vec<f32>>

Generate an embedding vector for text using the named model.

Accepts both built-in lattice model names/aliases and custom provider names registered via KhiveRuntime::register_embedder. For lattice models the resolved EmbeddingModel enum is forwarded to embed_one so the service can select the correct model variant. For custom providers, embed_one is called with EmbeddingModel::default() because custom services are expected to ignore the enum argument (they own a single model implicitly).

Returns UnknownModel if model_name is not in the embedder registry.

Source

pub async fn embed_batch( &self, texts: &[String], ) -> RuntimeResult<Vec<Vec<f32>>>

Generate embeddings for multiple texts in one call using the configured default model.

Delegates to the cached EmbeddingService::embed, so repeated texts within and across calls benefit from the runtime-level LRU cache.

Returns an empty vec for empty input without hitting the embedding service. Returns Unconfigured("embedding_model") if no model is configured.

Source

pub async fn embed_batch_with_model( &self, model_name: &str, texts: &[String], ) -> RuntimeResult<Vec<Vec<f32>>>

Generate embeddings for multiple texts using the named model.

Accepts lattice model names/aliases and custom provider names. Returns UnknownModel if model_name is not in the embedder registry.

Search vectors using either a caller-provided embedding or query text.

Existing callers pass query_embedding: Some(vec) to avoid re-embedding. Text callers pass query_embedding: None, query_text: Some(...) and the runtime embeds internally.

Hybrid search: text (FTS5) + vector retrieval fused via Reciprocal Rank Fusion.

  • Always performs text search over query_text.
  • If query_vector is Some, also performs vector search and fuses both lists.
  • If None, returns text-only results — no vector store needed.
  • If entity_kind is Some, the alive-set query filters to that kind. The text/vector candidate pools are unfiltered up front; the kind filter applies at the alive-check stage where we already fetch each candidate to confirm it isn’t soft-deleted.

limit caps the final returned list; internally pulls limit * 4 candidates per path. The fused candidate set is kept untruncated until after the alive + kind filter so that right-kind hits ranked below limit in the raw fusion still surface when higher-ranked candidates are wrong-kind or soft-deleted.

Source

pub async fn knn( &self, token: &NamespaceToken, query_vector: Vec<f32>, top_k: u32, ) -> RuntimeResult<Vec<VectorSearchHit>>

Exact KNN over the full namespace’s vector store.

sqlite-vec uses brute-force cosine — results are exact, not approximate. Cost is O(N · D) per query. For small-to-medium namespaces (~hundreds of thousands of vectors) this is well within latency budgets.

Source

pub async fn rerank( &self, token: &NamespaceToken, query_vector: &[f32], candidate_ids: &[Uuid], top_k: u32, ) -> RuntimeResult<Vec<VectorSearchHit>>

Exact KNN restricted to a candidate set.

Useful for reranking the top-N results from hybrid_search (or any other retrieval path) with exact cosine similarity against a query vector. Returns hits sorted by similarity (highest first), truncated to top_k.

Source

pub async fn backfill_missing_embeddings( &self, token: &NamespaceToken, ) -> RuntimeResult<u64>

Backfill vector and FTS index entries for entities and notes that are missing them.

Intended to run once at startup as a background task (warm-up sequence steps 2–4). Queries the SQL substrate for entity descriptions and note contents that have no corresponding entry in the vector store for any registered embedding model, then embeds and inserts them. FTS entries missing for notes are also repopulated.

The operation is best-effort: individual embed/insert failures are logged and skipped rather than aborting the whole backfill. If no embedding models are registered, returns immediately with 0.

Returns the total number of records backfilled across all models.

Source

pub async fn sweep_orphan_vectors( &self, token: &NamespaceToken, max_delete_per_model: u32, dry_run: bool, ) -> RuntimeResult<u64>

Sweep orphaned vector entries for all registered embedding models.

A vector entry is orphaned when its subject_id no longer exists as a live row in the entity or note tables (i.e. either the row is absent or has deleted_at IS NOT NULL). Orphaned entries accumulate after hard-deletes because the vector store and SQL substrate are decoupled.

Iterates over every registered embedding model and calls [VectorStore::orphan_sweep] for the token’s namespace. Models whose backend returns [StorageError::Unsupported] are skipped without error — this preserves forward-compat when a newly registered model does not yet implement sweep.

Returns the total number of vector rows deleted across all models.

Source§

impl KhiveRuntime

Source

pub fn new(config: RuntimeConfig) -> RuntimeResult<Self>

Create a new runtime with the given config.

The config’s db_path is used to open or create the SQLite backend. For the preferred boot path in multi-backend deployments, use from_backend instead.

Source

pub fn new_readonly(config: RuntimeConfig) -> RuntimeResult<Self>

Open a runtime for read-only inspection (no model registration, no DB creation).

Runs migrations (idempotent) but skips register_configured_embedding_models, so engine list / engine status cannot mutate the registry as a side effect. Returns None when db_path is None and the default DB does not exist.

Source

pub fn from_backend(backend: Arc<StorageBackend>, config: RuntimeConfig) -> Self

Construct a runtime from an already-opened backend.

This is the preferred constructor for multi-backend deployments. The caller (boot path in kkernel or khive-mcp) opens each backend from khive.toml, then constructs a KhiveRuntime per pack using this method.

The returned runtime has db_path = None and embedding_model = None; all storage access is through the provided backend. Set backend_id and default_namespace via the config builder pattern if non-defaults are needed.

Source

pub fn memory() -> RuntimeResult<Self>

Create an in-memory runtime (for tests and ephemeral use).

Source

pub fn backend_id(&self) -> &BackendId

Return the BackendId for this runtime’s backend.

Used by the SubstrateCoordinator to identify which backend owns a given node, and to detect cross-backend merges.

Source

pub fn config(&self) -> &RuntimeConfig

Return a reference to the runtime config.

Source

pub fn backend(&self) -> &StorageBackend

Return a reference to the underlying storage backend.

Source

pub fn entities( &self, token: &NamespaceToken, ) -> RuntimeResult<Arc<dyn EntityStore>>

Get an EntityStore scoped to the token’s namespace.

Source

pub fn graph( &self, token: &NamespaceToken, ) -> RuntimeResult<Arc<dyn GraphStore>>

Get a GraphStore scoped to the token’s namespace.

Source

pub fn notes(&self, token: &NamespaceToken) -> RuntimeResult<Arc<dyn NoteStore>>

Get a NoteStore scoped to the token’s namespace.

Source

pub fn events( &self, token: &NamespaceToken, ) -> RuntimeResult<Arc<dyn EventStore>>

Get an EventStore scoped to the token’s namespace.

Source

pub fn sql(&self) -> Arc<dyn SqlAccess>

Get the raw SQL access capability (for ad-hoc queries).

Source

pub fn vectors( &self, token: &NamespaceToken, ) -> RuntimeResult<Arc<dyn VectorStore>>

Get a VectorStore for the configured embedding model, scoped to the token’s namespace.

Returns Unconfigured("embedding_model") if no model is set.

Source

pub fn vectors_for_model( &self, token: &NamespaceToken, model_name: &str, ) -> RuntimeResult<Arc<dyn VectorStore>>

Get a VectorStore for a specific named embedding model, scoped to the token’s namespace.

Accepts both built-in lattice model names/aliases and custom provider names registered via register_embedder. Lattice names are routed through the enum-backed path; custom provider names use the provider’s declared dimensions() directly so that the vector store key is consistent with how vectors were written during remember/recall.

Source

pub fn text(&self, token: &NamespaceToken) -> RuntimeResult<Arc<dyn TextSearch>>

Get a TextSearch index for the token’s namespace entity corpus.

Source

pub fn text_for_notes( &self, token: &NamespaceToken, ) -> RuntimeResult<Arc<dyn TextSearch>>

Get a TextSearch index for the token’s namespace notes corpus.

Source

pub fn authorize(&self, ns: Namespace) -> RuntimeResult<NamespaceToken>

Mint an authorization token for the given namespace.

Consults the configured [Gate] before minting. With the default AllowAllGate this always succeeds. When a real policy-backed gate is installed, this method enforces it and returns PermissionDenied on denial.

Source

pub fn install_edge_rules(&self, rules: Vec<EdgeEndpointRule>)

Install the pack-aggregated edge endpoint rules.

Called by the transport layer after the VerbRegistry is built so that runtime-layer edge validation can consult pack rules. Idempotent: later calls overwrite the previous rule set.

Source

pub fn install_kind_registry( &self, entity_kinds: Vec<String>, note_kinds: Vec<String>, )

Install the pack-aggregated valid entity and note kinds.

Called by the transport layer after the VerbRegistry is built so that runtime-layer entity/note creation and import validate kind strings against the merged pack vocabulary. Idempotent: later calls overwrite previous sets.

When no kinds are installed (empty lists), kind validation is skipped at the runtime layer. The pack handler layer remains the primary enforcement point; this provides defense-in-depth for direct Rust callers and import.

Source

pub fn default_embedder_name(&self) -> &str

Return the name of the default embedding model (empty string if none configured).

Source

pub fn resolve_embedding_model( &self, name: Option<&str>, ) -> RuntimeResult<EmbeddingModel>

Resolve a model name (or None for the default) to an EmbeddingModel.

Returns UnknownModel if the name is not in the registry, or Unconfigured if None is passed and no default model is set.

Source

pub fn registered_embedding_model_names(&self) -> Vec<String>

Names of all registered embedding models in this runtime.

Includes both built-in lattice models and any custom embedders registered by packs via register_embedder. Useful for operations that must touch every model’s storage (e.g., scoped vector deletion on note delete — codex High 2 (PR #407)). The default model is included.

Source

pub async fn embedder( &self, name: &str, ) -> RuntimeResult<Arc<dyn EmbeddingService>>

Get the lazily-initialized embedding service for the named model.

Accepts both built-in lattice model names (e.g. "all-minilm-l6-v2", "paraphrase") and custom provider names registered via register_embedder.

For lattice model names, aliases (e.g. "paraphrase") are resolved to their canonical key before looking up the registry. For custom providers the name must match exactly as supplied during registration.

First call for any name loads the underlying service (cold start cost); subsequent calls are cheap (registry caches the Arc).

Source

pub fn register_embedder(&self, provider: impl EmbedderProvider + 'static)

Register a custom embedding provider with this runtime.

The provider is added to the shared EmbedderRegistry so all clones of this runtime see the new provider immediately. If a provider with the same name already exists it is replaced (last-writer wins — see [EmbedderRegistry::register] for the rationale).

Packs should call this from [PackRuntime::register_embedders] (the hook is invoked by the transport during pack initialisation, before the first verb dispatch).

Source

pub async fn list_embedding_models( &self, engine_filter: Option<&str>, ) -> RuntimeResult<Vec<EmbeddingModelRegistryRecord>>

List registered embedding models via SqlAccess, routing through the existing connection pool rather than opening a fresh Connection per call.

Optionally filter by engine_name. Returns an empty vec when the _embedding_models table does not yet exist (e.g. no migrations have run or no models have been registered). All other SQL errors are propagated.

Trait Implementations§

Source§

impl Clone for KhiveRuntime

Source§

fn clone(&self) -> KhiveRuntime

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more