Repository navigation
Retrieval
search and recall are keyword search: SQLite FTS5 ranked by BM25. No
embedding model, no network call, no GPU. Retrieval only narrows the
candidates — whether a result answers the question is the agent's call.
Spend terms freely. Each word is matched on its own, and a memory that matches more of them ranks higher. Piling synonyms, the identifier and the plain-language phrasing into one query costs one call and finds more:
search("stripe webhook duplicate retry idempotency event id charge.succeeded")Common words score near zero, so a whole sentence is fine too. Words are
stemmed (porter), so retry also finds retries.
Pasting a uid returns that memory first, then the memories that mention it.
Each column carries a different weight:
| column | weight | why |
|---|---|---|
title |
1.5 | one line chosen to name the memory |
content |
1.0 | the body |
tags |
0.8 | the synonyms the body does not use |
domain, also
|
0.3 | a scope name is findable, but filing under acme/cache should not outrank the memory that discusses the cache |
Tip
Tags matter more than they look. A memory with no tags answers only a query that quotes its own wording. A writer is told how many tags it indexed, and the dashboard's Health view lists the untagged ones.
| field | means |
|---|---|
match_source |
fts, or uid for the memory a pasted id names |
fts_rank |
the BM25 score; lower is better |
est_tokens |
what a get_memory(uid) of the full record would cost |
succeeded_by |
a newer memory supersedes this one — read that instead |
collapsed |
near-identical results folded into this one |
confidence |
a contradicted memory sorts behind everything that still holds |
Listings truncate content at 400 characters and point at get_memory(uid) for
the rest. A result that would run past 40,000 characters comes in pages: pass
its next_offset as offset for the next one. See Tools.
| try | because |
|---|---|
| more synonyms in the same query | each extra term widens the net at no cost |
list_by_domain(domain) |
newest first, everything under a path |
must_read(domain, type=…) |
headers of what is open in a scope |
timeline(uid) |
what was written around a memory you did find |
pulse, must_read and the list_* calls sort by creation date, never by
similarity, so the newest checkpoint is always the one returned.
Home · Getting started · Troubleshooting · Changelog · MIT licence
Getting started
Concepts
Guides
Reference