recall
Retrieving context assembled to fit a budget.
const { payload, tokensSaved } = await hm.recall({
q: "how often can we deploy?",
budget: 2000,
});payload is ready to put in a prompt. It is not a list of hits, selection,
ordering and formatting are the point, and reassembling them yourself would
throw all three away.
Parameters
| Default | ||
|---|---|---|
q | required | What you need context about |
budget | 4000 | Hard token ceiling |
sourceRef | none | Where you are asking from, ranking origin, never a filter |
limit | , | Cap on results, independent of budget |
threshold | calibrated | Relevance floor, 0–1. Higher is stricter |
searchMode | hybrid | memories, documents, or both |
filters | , | Metadata predicate |
rerank | false | Re-score the shortlist. ~100ms |
rewriteQuery | false | Also search alternative phrasings |
targetTool | , | Shapes the payload for the receiving client |
threadId | , | Boost a thread |
include | , | memories, dropped, trace |
Result
{
payload: string; // ready for a prompt
memoryIds: string[];
memories?: Memory[]; // with include.memories
threadId: string | null;
candidateCount: number; // considered
droppedCount: number; // discarded as too weak
tokensSaved: number; // against sending everything found
latencyMs: number;
}An empty payload is a real answer
const { memoryIds } = await hm.recall({ q: "what is the capital of Peru" });
// memoryIds.length === 0If nothing is relevant enough, nothing comes back. Check memoryIds.length
rather than assuming there is always something to inject, a memory layer that
always finds something buries the answer in noise.
Filtering
await hm.recall({
q: "database migrations",
filters: {
AND: [
{ key: "team", value: "platform" },
{ key: "priority", value: 5, comparator: "gte", numeric: true },
],
},
});Comparators: eq, ne, gt, gte, lt, lte, contains, in. Nest with
AND and OR; add negate: true to invert; add numeric: true to compare as
numbers rather than text.
Formatting for the receiving tool
await hm.recall({ q: "…", targetTool: "claude-code" });The same memories are shaped differently for a client that expects structured context than for one that expects prose. If you are assembling a prompt yourself, leave it unset.
Tuning
Getting too little. Lower threshold, or set rewriteQuery: true if
queries are terse, "db for invoicing" and "which database does billing use"
should find the same thing.
Getting too much. Raise threshold, or set a limit.
Right results, wrong order. rerank: true. It costs about 100ms and helps
most when several results are genuinely close.