Summary
The embedFn (embedding function) is not being passed to the Recaller instance, causing vector search to always fall back to keyword search even when embeddings are available.
Environment
- OpenClaw: v4.5.x (host: atom, Linux 6.17.0-1011-ome)
- Node.js: v22.22.1
- Plugin: graph-memory 1.5.8(extension)
- Runtime: systemd user service (
openclaw-gateway.service)
- Model: litellm/minimax-m2.1
- Testing: Vector search in graph-memory recall always returns keyword-only results
Root Cause
In index.ts, recaller is created as a closure variable, then setEmbedFn(fn) is called asynchronously. However, when recall(query) is called later, it creates a new Recaller instance instead of using the one with embedFn already set.
Code Flow (Before Fix)
// index.ts - original buggy code
let recaller: Recaller; // module-level variable
async function onModuleInit() {
recaller = new Recaller(...); // Line 107: create instance
await recaller.setEmbedFn(embedFn); // Line 117: async set embedFn
}
async function recall(query: string) {
const recaller = new Recaller(...); // Bug: creates NEW instance! (Line 199)
// ... recaller does not have embedFn set
}
Fix
Use the same recaller instance for both setting embedFn and calling recall:
// index.ts - fixed code
let recaller: Recaller; // module-level variable
async function onModuleInit() {
recaller = new Recaller(...); // Line 107
await recaller.setEmbedFn(embedFn);
}
async function recall(query: string) {
// Use the same recaller instance
return recaller.recall(query); // Fixed: use closure variable
}
Verification
After fix, logs show (embed=true) indicating vector search is active:
2026-04-09T08:51:00 [plugins] [graph-memory] recall query: ... (embed=true)
2026-04-09T08:51:00 [plugins] [graph-memory] recalled 12 nodes, 3 edges
Files Changed
src/index.ts - use module-level recaller in recall()
src/recall.ts - add hasEmbed getter for debugging
Labels
Summary
The
embedFn(embedding function) is not being passed to theRecallerinstance, causing vector search to always fall back to keyword search even when embeddings are available.Environment
openclaw-gateway.service)Root Cause
In
index.ts,recalleris created as a closure variable, thensetEmbedFn(fn)is called asynchronously. However, whenrecall(query)is called later, it creates a newRecallerinstance instead of using the one with embedFn already set.Code Flow (Before Fix)
Fix
Use the same
recallerinstance for both setting embedFn and calling recall:Verification
After fix, logs show
(embed=true)indicating vector search is active:Files Changed
src/index.ts- use module-level recaller in recall()src/recall.ts- add hasEmbed getter for debuggingLabels