Skip to content

Memory

Empryo remembers your preferences, project decisions and past gotchas across sessions, and adds up to 3 relevant ones to each turn automatically.

Tools4 minutes to read
Copy & share
On this page10 sections
Recall at work: Empryo scores stored memories against the current request and the files in play, then adds the three most relevant, each labeled with why it was picked.

Memory lets Empryo remember things between sessions: that you use bun, not npm; why the team switched state libraries; that a test is flaky on CI. You tell it once, and it comes back when it matters.

Memory is stored per project by default. You can also keep global memories that apply to every project, such as "be terse".

What gets storedLink to this section

Each memory has one of four categories:

CategoryExample
pref"use bun not npm", "be terse"
decision"switched to zustand because redux was too much boilerplate"
gotcha"JWT expiry uses the container clock, which drifts in prod"
context"legacy/ will be deleted next sprint, don't touch it"

The agent saves a memory on its own when you state a preference, make a decision with a reason, or hit a bug that wasn't obvious. You can also ask it directly: "remember that we deploy on Thursdays".

Left: a rules file sent in full on every turn, outdated lines included. Right: Empryo adds three short memories that match the file being edited.

How recall worksLink to this section

Before each turn, Empryo compares your message and the files you are working on with what's stored. It adds up to 3 relevant memories to the turn. You don't need to run a command or remember what's saved.

If nothing is relevant, nothing is added. Memories only take up space in the conversation when they help.

Browse and edit: /memoryLink to this section

In the terminal UI, run /memory to open the memory browser. It has four tabs:

  • All: every memory you can see, from the project and global stores. Pin, edit or hide a memory from here.
  • Hidden: memories you hid. Restore them with Ctrl+R.
  • Cleanup: suggestions to review, such as duplicates, memories that point at deleted files, and memories that are rarely useful.
  • Settings: which stores the agent reads from and writes to, and which embedding model is in use.

Hiding a memory is reversible. Purge all (Ctrl+X) deletes permanently, so use it with care.

The desktop app has a Memory pane with the same data.

ScopesLink to this section

Memories live in two databases:

ScopeLocationUse it for
Project.empryo/memory.db in the repositoryDecisions and gotchas about this code
Global~/.empryo/memory.dbYour personal preferences and style

New memories go to the project store by default. The read scope controls what recall can see:

all      project + global (default)
project  only this repository
global   only your global preferences
none     recall off

Change both in /memory → Settings.

PinningLink to this section

Pin a memory to keep it out of cleanup suggestions and rank it higher in recall. Pin the rules you never want the agent to miss.

LanguagesLink to this section

Memory search works in any language or script, including Chinese, Japanese, Arabic and Cyrillic, and mixed-script identifiers. It matches both whole words and parts of words, so rephrased and non-English queries still find the right memory.

Better matching with an embedding modelLink to this section

By default, Empryo uses a built-in offline embedder. It needs no API key and makes no network calls. It matches memories well when your wording overlaps with what was stored.

For better matching of rephrased text, point memory at an embedding model:

json
{
  "memory": {
    "embeddingModel": "openai/text-embedding-3-small"
  }
}

Do I need an API key?Link to this section

Yes, for a hosted model. Empryo uses the key you already configured for that provider. For openai/text-embedding-3-small, that is your OpenAI key. If the key is missing or wrong, Empryo falls back to the offline embedder and memory keeps working. /memory → Settings shows the reason.

Local models in Ollama or LM Studio need no key. Pull the model, then name it in the config.

Which models can I use?Link to this section

Any provider/model ID whose provider offers embeddings:

ProviderModel
OpenAIopenai/text-embedding-3-small, openai/text-embedding-3-large
Googlegoogle/text-embedding-004
Mistralmistral/mistral-embed
OpenRouteropenrouter/openai/text-embedding-3-small
Vercel AI Gatewayvercel_gateway/openai/text-embedding-3-small
Ollama (local)ollama/nomic-embed-text, ollama/mxbai-embed-large
LM Studio (local)lmstudio/nomic-embed-text

Providers without an embeddings API, such as Anthropic, xAI, Groq, DeepSeek and Bedrock, use the offline embedder instead. Custom OpenAI-compatible providers work if they expose an /embeddings endpoint.

If you don't set embeddingModel, Empryo picks one in this order: your taskRouter.semantic model, then a default for your current chat provider (OpenAI, Google, OpenRouter or Vercel AI Gateway), then the offline embedder. Set "embeddingModel": null to always use the offline embedder.

How do I check it's working?Link to this section

Open /memory → Settings and look at the Embedding row. It shows the model in use and where the choice came from. If your configured model failed, the row says why: a missing key, a provider without embeddings, or a network error.