Memory

Facts an agent keeps across sessions — extracted from idle conversations, scoped per agent, user or org, injected next turn.

Memory lets an agent carry what it learned in one conversation into the next. It exists because an assistant that is no better on day thirty than on day one is not an assistant; and because building extraction, storage and injection per project is exactly the plumbing Latch is for.

What it makes possible. An agent that remembers a user's preferences and context; an org-shared agent whose memory a whole team benefits from, next to personal memory that never leaks; a background sweep that needs only the cron you already run; per-principal prompt caching that stays correct when the prompt differs per user.

Memory — persistent facts across sessions

ts
defineAgent<Principal>(() => ({
  model,
  memory: { scope: "agent-user", connection: "loredex" },
}));

With a MemoryProvider wired, each turn gets the provider's compiled index appended to the instructions plus memory_search/memory_save tools; background jobs handle extraction and consolidation out of band.

The load-bearing part is that scopes are hard boundaries:

ScopeRemembers
agent-userthis agent, for this user
agent-orgthis agent, shared across the org
userthis user, across agents

Tools are path-locked at construction and consolidation never crosses a scope, so a personal agent's memory and a company-wide agent's memory differ by declaration, not by convention. @intentface/latch-memory is the implementation.

How memory grows

The runtime does not extract during a turn. @intentface/latch-memory runs a background job — driven by the same cron as everything else — that finds idle conversations, extracts episodes, consolidates them under the scope's schema, and rebuilds the compiled index the next turn injects. Failed extractions retry after a backoff; a window that yielded nothing is tombstoned so it is never re-read; a schema edit re-opens it.

Next