Skip to content

Persistent Memory

Persistent Memory gives the agent a scoped memory store for facts, decisions, preferences, and reusable project context.

  • project memories are shared across sessions in the current working tree.
  • user memories are shared across projects for the current user.
  • local memories are isolated to the current session. With the SQLite backend they survive app restarts for that session and are removed when the session is deleted.
[options.persistent_memory]
enabled = true
backend = "sqlite"
[options.persistent_memory.embeddings]
enabled = true
read_projection = "default"
write_projections = ["default"]
[[options.persistent_memory.embeddings.projections]]
name = "default"
provider = "local"
model = "bmo-local"
indexed_scopes = ["project", "user"]
top_k = 10
BackendStorageUse case
sqliteLocal database (default)Durable, private, configurable semantic search via embedding projections
memoryIn-process onlyTests, demos; cleared on exit
supermemorySupermemory cloud APICloud-backed memory; requires API key

Privacy (Supermemory): With backend = "supermemory", memory content and metadata are sent to Supermemory’s cloud service. Use this only if you accept their terms and privacy policy. For local-only data, use sqlite or memory.

With the SQLite backend, semantic search runs through named embedding projections. Canonical memories remain in persistent_memories; each projection stores its own derived embeddings, build state, queue, and run history.

  • Reads use one active read_projection.
  • Writes can fan out to multiple write_projections for dual-write migration.
  • New projections backfill from canonical memory content, then drain queued writes before they become ready.
  • Read cutover is explicit, so rollback is just a routing change.

If a config still contains options.persistent_memory.vector, BMO imports those fields into a named legacy-default compatibility projection on startup. Prefer embeddings.projections[] for new configs.

When enabled, the agent can call:

ToolDescription
memory_store(scope, content, type)Save a fact, decision, or convention in project, user, or local scope
memory_update(scope, id, content)Replace an existing memory when a fact is corrected or superseded
memory_search(scope, query)Search stored memories; uses the active embedding projection when available, otherwise keyword search
memory_list(scope)List recent memories for a scope
memory_forget(scope, id)Delete a specific memory within the current project, user identity, or session

BMO can write memories during a conversation without waiting for an explicit “remember this” instruction. The agent is prompted to store durable information when it detects:

  • Corrections - the user corrects the agent’s behavior, output, or assumption.
  • Preferences - the user states a coding, communication, tooling, or workflow preference.
  • Project decisions - the conversation settles an architecture, dependency, naming, or process decision that should apply later.

These writes use the same memory_store tool and scope routing as explicit memory requests. For the first few proactive writes in a session, BMO may include a short inline note so the behavior is visible. After that, proactive writes continue more quietly and remain inspectable through the activity drawer and /memory viewer.

Auto-retain runs after completed turns as a safety net for corrections, preferences, and decisions the agent did not store during the turn. It is capped and selective; it is not a transcript recorder.

Good memory entries are short, typed, and easy to reuse:

  • Keep each entry to one durable fact or decision, usually one or two sentences.
  • Phrase entries as actionable positives, such as “prefer snake_case for config keys.”
  • Use the most specific type: preference, decision, convention, fact, or context.
  • Search before storing. If an older memory covers the same topic, update or replace it instead of adding a duplicate.
  • Choose the narrowest useful scope: project for the current codebase, user for cross-project preferences, and local for session-only context.

The /memory slash command opens an in-TUI memory manager. With SQLite-backed memory enabled it includes:

  • Memories for per-scope inspection and deletion
  • Embeddings for listing projections and managing create/rebuild/cutover
  • Migration for queue lag, recent runs, and projection status

When persistent memory is disabled it still shows status, but management controls are unavailable.

OptionDefaultDescription
enabledfalseEnable persistent memory
backendsqliteStorage backend: sqlite, memory, or supermemory (cloud; requires API key)
supermemory.api_key(env)Supermemory API key; can be set here or via SUPERMEMORY_API_KEY (prefer env for secrets)
embeddings.enabledfalseEnable named embedding projections for the SQLite backend
embeddings.read_projectionfirst enabled projectionActive semantic read projection
embeddings.write_projections[read_projection]Projections that receive new writes
embeddings.auto_backfilltrueResume/build projections automatically on startup
embeddings.fallback_to_lexicaltrueFall back to keyword search when semantic search is unavailable
embeddings.projections[].namenoneProjection name used for routing and migration
embeddings.projections[].providernoneEmbedding provider; supported values in v1: openai, cohere, local
embeddings.projections[].modelnoneEmbedding model name
embeddings.projections[].indexed_scopes["project", "user"]Scopes included in this projection
embeddings.projections[].top_k10Maximum semantic matches to score before returning results
embeddings.projections[].dimensionprovider defaultOptional embedding dimension override

Projection config is only supported with the sqlite backend. BMO validates the provider at startup and rejects projection config on memory and supermemory.

Legacy compatibility options:

OptionDefaultDescription
vector.enabledfalseImported into the compatibility projection’s enabled flag
vector.embedding_providernoneImported into the compatibility projection’s provider name
vector.embedding_modelnoneImported into the compatibility projection’s model id
vector.indexed_scopesall scopesImported into the compatibility projection’s indexed scopes
vector.top_k10Imported into the compatibility projection’s semantic result cap
  • project is keyed from the current working directory.
  • user is keyed from the authenticated principal when available, otherwise the local BMO user namespace.
  • local is keyed from the active session ID.
  • Project conventions — store coding standards so they’re available every session
  • Decisions log — record architectural choices for the agent to reference
  • Cross-session context — anything you’d otherwise have to paste into every new session

Memories are one of the sources that Adaptive Context can select and rank when building the user-message context block; enabling both can improve which memories are included in long sessions.