Memory
Empryo remembers your preferences, project decisions and past gotchas across sessions, and adds up to 3 relevant ones to each turn automatically.
Copy & share
On this page10 sections
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:
| Category | Example |
|---|---|
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".
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:
| Scope | Location | Use it for |
|---|---|---|
| Project | .empryo/memory.db in the repository | Decisions and gotchas about this code |
| Global | ~/.empryo/memory.db | Your 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 offChange 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:
{
"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:
| Provider | Model |
|---|---|
| OpenAI | openai/text-embedding-3-small, openai/text-embedding-3-large |
google/text-embedding-004 | |
| Mistral | mistral/mistral-embed |
| OpenRouter | openrouter/openai/text-embedding-3-small |
| Vercel AI Gateway | vercel_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.