Local long-term memory for Oh My Pi, backed by the
zg (zvec-grep) CLI.
It works with any omp build — including the stock Homebrew/npm binary — because it is an
extension, not a core patch. It lives in your own directory, so omp update / brew upgrade omp
never touches it.
- Auto-recall — on the first turn of a session, searches memory with the user's prompt and
injects the hits as a
<memories>block. - Auto-retain — every 4 user turns, writes the completed turn window to memory.
- Tools —
zvec_recall,zvec_retain,zvec_reflect,zvec_edit(distinct names, so the built-inrecall/retain/reflect/memory_edittools of a mnemopi/hindsight session are never shadowed). - Command —
/zvec stats | search <query> | enqueue | clear.
Memories are plain markdown files under <agent dir>/memories/zvec/<bank>/memories/<id>.md;
zg builds a hybrid BM25 + vector index in <bank>/.zvec-grep/. The layout matches the in-tree
zvec backend, so a bank written here is read unchanged by a build that ships the backend natively.
zgonPATH(zg --version). Install from the zvec-grep releases orcargo install zvec-grep.- An embedding model for new indexes. The default is
local/potion-code-16m-v2(tiny, fast); override withZVEC_MEMORY_EMBEDDINGor the config file. Seezg help models.
The Memory Backend list in /settings is a hardcoded enum in the core binary
(config/settings-schema.ts → memory.backend.values + ui.options, resolved by
memory-backend/resolve.ts). The extension API cannot register a settings entry or a backend
implementation, so an extension can never add itself to that list.
| Menu entry | Works on the stock binary | Survives omp update |
|
|---|---|---|---|
| This extension | no | yes | yes |
| Patched build (below) | yes | — (it is the binary) | no — rebuild per update |
Both share the same bank layout and bank ids, so memories written by one are read by the other.
scripts/build-patched-omp.sh v18.2.6 # → dist/omp-v18.2.6
scripts/build-patched-omp.sh v18.2.6 --force # re-clone and rebuildThe script clones the requested upstream tag into ~/Lab/.omp-zvec-build/<tag>, applies
patch/zvec-backend-<tag>.patch (falling back to patch/zvec-backend.patch), installs
dependencies plus the prebuilt native addon, and builds. Run it again after each upstream release
to get a patched binary at the new version.
scripts/omp-wrapper.sh prefers a patched build that matches the installed version and falls back
to the stock binary otherwise, so a fresh brew upgrade keeps working (without the menu entry
until you rebuild). It resolves its own location — following symlinks — to find the repo's dist/,
so it works from any clone path:
ln -sf /path/to/omp-zvec-memory/scripts/omp-wrapper.sh ~/.local/bin/ompThis requires ~/.local/bin to precede the Homebrew bin directory in PATH. Verify with
which omp and omp config list | grep memory.backend (the enum should end with |zvec).
Remove the symlink to go back to the stock binary.
Set OMP_ZVEC_DIST to read patched builds from a directory other than <repo>/dist, or
OMP_ZVEC_STOCK to point at a non-Homebrew omp.
A patch is verified against one tag only — upstream moves files between releases (for example
modes/components/settings-defs.ts became config/settings-ui.ts in v18.2.6). When a new tag
rejects the patch, port the changes and save the result as patch/zvec-backend-<tag>.patch.
omp plugin link /path/to/omp-zvec-memory # symlink, keeps the source editable
# or
omp plugin install /path/to/omp-zvec-memory # copy into ~/.omp/plugins/node_modulesRestart omp (or open a new session). Verify with omp plugin list.
To remove: omp plugin uninstall omp-zvec-memory.
Precedence: environment variable → host zvec.* setting (only on builds that ship the backend) →
<agent dir>/zvec-memory.json → default.
| Env var | Config file key | Default | Meaning |
|---|---|---|---|
ZVEC_MEMORY_SCOPING |
scoping |
per-project |
per-project = bank per working directory; global = one bank |
ZVEC_MEMORY_BANK |
bank |
unset | Shared bank name used when scoping is global |
ZVEC_MEMORY_EMBEDDING |
embeddingModel |
local/potion-code-16m-v2 |
Embedding model for new indexes |
ZVEC_MEMORY_AUTO_RECALL |
autoRecall |
true |
Recall on the first turn |
ZVEC_MEMORY_AUTO_RETAIN |
autoRetain |
true |
Retain completed turns |
ZVEC_MEMORY_RETAIN_EVERY |
retainEveryNTurns |
4 |
Minimum user turns between automatic retains |
ZVEC_MEMORY_RECALL_LIMIT |
recallLimit |
8 |
Maximum hits per recall |
ZVEC_MEMORY_INJECTION_TOKENS |
injectionTokenLimit |
5000 |
Approximate token budget for the injected block |
ZVEC_MEMORY_DEBUG |
debug |
false |
Log backend failures |
Example <agent dir>/zvec-memory.json:
{
"scoping": "per-project",
"autoRetain": true,
"recallLimit": 10
}bun test test/smoke.test.tsThe smoke test loads the extension against a stub host and a fake zg runner, so it needs neither
omp nor zg installed.