Lore

Core concepts

How Lore turns a stream of agent events into a read-your-writes context pack.

At a glance: agents write to an append-only event log; Lore consolidates those events into versioned memories and claims; and a pack returns a budget-fit slice of that memory for a query.

Lore data flowAgents write events with sequence tokens to an append-only event log. An asynchronous pipeline consolidates events into versioned memories. A deterministic, budget-fit context pack is returned; calling pack with min_seq guarantees covered_seq is at least seq — read-your-writes.Agent AAgent Bwrite → seqwriteEvent logappend-onlyasyncConsolidateversioned memories & claimsContext packbudget-fit · deterministicread-your-writespack(min_seq)covered_seq ≥ seq

Data flow

The middle "consolidate" step is an asynchronous pipeline. Writes never block on it — a write returns immediately, and the pipeline catches up behind the scenes.

Write

Agents stream events to a run. Each event gets a server-assigned monotonic seq (per run), and the write returns right away with HTTP 202 — nothing blocks.

Extract

An async worker reads new events and distills them into candidate memories and claims. The default extractor is an offline, deterministic fixture, so this runs with no external API key.

Consolidate

Candidates are merged into the durable store: deduplicated against existing memories, and each claim's conflicts resolved by policy — last-writer-wins by default — then versioned. Superseded content is kept as version history, not overwritten.

Embed

Each memory gets a vector so it can be retrieved by meaning, not just keywords. The default is the offline fixture embedder; point Lore at an OpenAI-compatible endpoint for a real semantic space (see Configuration).

Pack

The read path assembles a budget-fit context for a query: live working facts, distilled memories, and a raw tail of not-yet-distilled events, in a deterministic order. The response reports how fresh the distilled view is.

Extract, consolidate, and embed together advance the run's distilled checkpoint — the high-water mark of events the pack can serve as distilled memory rather than raw tail.

Read-your-writes

The reason the checkpoint matters: agents work over a shared memory that a moment ago was being written by someone else. Lore gives you an API-level guarantee so you never have to guess whether your write is visible yet.

Give multi-agent teams a read-your-writes guarantee at the API level: when one agent writes, any later pack request can be guaranteed to reflect that write — either as a distilled memory, or as a raw tail until extraction catches up. The client always knows its consistency state instead of guessing.

Three fields carry the contract:

  • seq — every write returns a server-assigned, per-run monotonic counter. Keep it.
  • min_seq — pass a prior write's seq on a pack request to require the pack reflect your writes up to that point. Anything newer than the distilled checkpoint is included as a raw tail.
  • covered_seq (+ freshness_lag_ms) — the pack response reports the run's distilled checkpoint and the age of the oldest not-yet-distilled event. covered_seq >= min_seq means read-your-writes is satisfied from distilled memory; below it, the requested events are still served — as the raw tail.

The read-your-writes window (events up to min_seq) is never dropped from a pack, even under a tight token budget. For the full contract and the design rationale, see RFC 0001 — Read-your-writes.

Pack anatomy

A pack is a single sectioned envelope of data, not instructions. It opens with a header that tells any downstream model to treat everything below as retrieved reference — never as directives to follow — and then lays out its sections in a fixed, deterministic order:

  • Working — live coordination facts written through the low-latency lane (a same-run reader sees them immediately). Its source is reported as live, durable, or unavailable. unavailable means this pack carries no working section — the live stripe was not authoritative and no durable snapshot existed; the facts are still stored and still reach you through the raw tail. No producer writes durable working snapshots yet, so durable is in the contract but not currently returned.
  • Distilled memories — the consolidated semantic, episodic, and procedural knowledge retrieved for the query (hybrid vector + lexical retrieval).
  • Raw tail — recent events extraction hasn't distilled yet, labelled as raw and unverified. The read-your-writes window is always included here; beyond it, a bounded number of the most recent events may be appended.

An optional token_budget caps the distilled section with a coarse chars / 4 ≈ tokens heuristic; whole memories are dropped once the estimate exceeds the budget, while the working section and the read-your-writes window are exempt. truncated in the response flags when anything was capped.

A separate optional degraded array reports retrieval legs that missed the server's partial-result budget and contributed nothing to the pack — today only dense, when the embedding provider answered slower than LORE_RETRIEVAL_PARTIAL_TIMEOUT. It is unrelated to token_budget: nothing was capped, a source simply never arrived. The field is omitted entirely when every leg finished, so its presence is the signal that this answer was assembled from fewer sources than are configured. The response is still 200 — the pack is valid, just narrower.

saved_tokens in the response is an estimate (the same chars / 4 heuristic), not a measured count.

The /v1/pack request and response fields are defined in the OpenAPI spec.

On this page