"use bun not npm", "be terse").
What gets stored
Four kinds:| Category | Example |
|---|---|
pref | ”use bun not npm”, “be terse” |
decision | ”switched to zustand — redux was too much boilerplate” |
gotcha | ”JWT expiry uses container clock, drifts in prod” |
context | ”legacy/ deletes next sprint — don’t touch” |
How recall works
Before each turn, SoulForge looks at your prompt and which files you’ve been editing, then injects up to 3 relevant memories silently. The agent sees them and adjusts. You don’t have to type/memory or remember what’s stored.
If nothing’s relevant, nothing’s injected — memory earns its prompt slot every turn or it doesn’t take one.
Browser — /memory
Type /memory to open the browser. Five tabs:
- All — every memory across project + global. Pin, soft-delete, or supersede per row.
- Hidden — soft-deleted entries, restorable forever.
- Cleanup — Quick (dupes + dead file refs) and Stale (low-signal candidates) for manual review.
- SIM — clusters of related memories.
- Settings — read & write scopes.
Scopes
Two databases:| Scope | Location | Use for |
|---|---|---|
| Project | .soulforge/memory.db | code-specific decisions, file-scoped gotchas |
| Global | ~/.soulforge/memory.db | cross-project preferences, your style |
Pinning
Pin a memory to keep it from being surfaced in cleanup suggestions and to lift its ranking in recall. Useful for non-obvious rules you want to keep close.Languages
Memory works in any script — English, CJK, Arabic, Cyrillic, mixed-script identifiers. Searches use a word index plus a character n-gram index together, so paraphrases and non-Latin queries both hit.Commands
| Command | Description |
|---|---|
/memory | Open the browser |
Config
Do I need an API key?
Yes, if you set a provider model. The embedder runs through the AI SDK, so it needs that provider’s key. Foropenai/text-embedding-3-small that is your OpenAI key. Without a valid key the embedder fails its startup probe and silently falls back to the offline embedder. Memory keeps working either way.
Which models can I use?
Any AI SDKprovider/model id. Verified routes:
| Provider | Model |
|---|---|
| OpenAI | openai/text-embedding-3-small, openai/text-embedding-3-large |
google/text-embedding-004 | |
| Vercel Gateway | vercel_gateway/openai/text-embedding-3-small |
| LLM Gateway | llmgateway/openai/text-embedding-3-small |
| OpenRouter | openrouter/openai/text-embedding-3-small |
embeddingModel explicitly.
You do not have to set this at all. When unset, it auto-resolves in order: taskRouter.semantic, a default for your active chat provider, then the offline embedder.
How do I check it is working?
Open/memory, go to the Settings tab, and read the Embedding row. It shows the active model and where the choice came from, or offline (hashbag-v2) when the offline embedder is in use. If you set a provider model but the row still says offline, the key is missing or the model was rejected.
