Skip to content

Library API

Both surfaces, the MCP tools and the command line verbs, are thin wrappers over one type, Memory. If you embed Lambo in a Rust program, this is the type you work with. For full signatures, run cargo doc --open.

Memory holds the in-memory graph together with its background workers, which handle write-behind flushing and canonization. Exactly one Memory writes a given session. See The single-writer lease.

Use the builder. Prefer backends, which supplies the store, embedder, and their compatibility in one value, because it is the single place backends are constructed.

let mem = Memory::builder()
.session("my-session")
.agent("agent-a")
.backends(resolved)
.build()
.await?;

The builder accepts session, agent, store, embedder, embedding_contract, backends, match_strategy, flush_interval, scoring_weights, and config.

build().await acquires the writer lease, fails if another process holds it, runs the startup load, and starts the background workers.

The accessors session, agent, config, embedding_contract, graph, index, and store return the current state.

MethodWhat it does
deriveDerives concepts from an interaction. Async.
record_actionRecords an action as a concept plus its causal and dependency edges.
demoteDemotes a chunk.
retractRetracts a concept. Pass a dry-run flag to get an impact report without mutating. Async.
reserve and releaseTake or release an advisory soft lock.
set_root_goal and declare_synonymSet up the session.
MethodWhat it returns
recallThe context block for a query. Async.
canonical_memoriesThe session’s canonical memories.
statsFlush lag, log depth, counts, and degraded state.
eventsA live feed of background events.

Config holds the product settings: recall defaults, flush timing, canonization thresholds, and scoring weights. Pass it to the builder with .config(...).

These are library settings, not lambo.toml keys. The file only chooses the store and the embedder, and it refuses any other key. See Configuration.

let mem = Memory::builder()
.session("my-session")
.agent("agent-a")
.backends(resolved)
.config(Config { default_top_k: 10, ..Config::default() })
.build()
.await?;
KeyDefaultWhat it controls
default_top_k5Hits a recall returns when the caller omits top_k.
default_max_tokens500Token budget for the rendered context block.
default_traversal_depth2Graph expansion depth during recall.
match_strategyHybridCanonical or Hybrid concept matching.
semantic_match_threshold0.85Similarity above which two concepts match. Must be between 0 and 1.
backend_flush_interval1 secondHow often pending writes flush, which sets how far behind durable storage a session can be.
backend_flush_max_batch500Mutations per flush batch.
backend_flush_retries3Attempts before a batch is dead-lettered.
backend_log_max50000Cap on the write-behind log.
daemon_tick_interval1 secondHow often the background workers rescore and re-run the detectors.
max_canonical_nodes1000Cap on canonical concepts.
canonization_min_peer_count20Peers a concept needs before it can be promoted.
canonization_edge_min_age60 secondsHow long an edge must exist before it counts as evidence.
canonization_eval_interval60 secondsHow often promotion is evaluated.
canonization_eval_batch_size50Concepts evaluated per pass.
canonization_repromotion_cooldown300 secondsWait before a demoted concept can be promoted again.
scoring0.25, 0.20, 0.20, 0.35Recency, frequency, session activity, and density weights.
recall_weights0.5, 0.5How much the background score and the query relevance each contribute.

Config::validate() checks the settings that must fail closed rather than quietly poison selection. A scoring weight that is negative or not a number drops that one dimension to zero instead of failing the session.

close().await flushes the pending write-behind tail and releases the lease. It is time-bounded. If a dependency hangs, it stops rather than waiting forever, and it reports honestly that the un-flushed tail was not saved.

Backends are chosen by Cargo feature and configuration, not loaded as plugins. See Configuration for the feature flags.

GraphStore handles durable graph storage. The implementations are the in-memory store, the SQLite store, and the CockroachDB store. Its methods cover schema setup, flushing a batch, loading a session, keyword and vector candidate lookup, blast radius, interaction spans, and canonization records, plus the lease methods below.

A store also declares what it can do. capabilities reports its features, and vector_dimensions reports the width of its vector column, or nothing when it has none. A store that reports a width must agree with the embedder’s, and Lambo refuses to start when they differ.

Embedder turns text into vectors.

pub trait Embedder: Send + Sync {
fn dimensions(&self) -> usize;
async fn embed(&self, text: &str) -> Result<Vec<f32>, EmbedError>;
}

The implementations are the fixture embedder, BGE-M3 over llama-server, and Amazon Titan through Bedrock.

A session has exactly one writer. Lambo enforces this in the store with a per-session lease that records the current holder and a time-to-live.

  • build() acquires the lease or fails, naming the process that holds it. close() releases it.
  • A heartbeat keeps a live holder’s lease fresh and lets a crashed holder’s lease expire.
  • If a holder’s lease is taken over, that holder is fenced. Its further writes are refused and its pending writes are dropped, so it cannot overwrite the new holder.

See MCP tools and Configuration.