lossless-claw works without FTS5 as of the current release. When FTS5 is unavailable in the
Node runtime that runs the OpenClaw gateway, the plugin:
- keeps persisting messages and summaries
- falls back from
"full_text"search to a slowerLIKE-based search - loses FTS ranking/snippet quality
If you want native FTS5 search performance and ranking, the exact Node runtime that runs the gateway must have SQLite FTS5 compiled in.
Run this with the same node binary your gateway uses:
node --input-type=module - <<'NODE'
import { DatabaseSync } from 'node:sqlite';
const db = new DatabaseSync(':memory:');
const options = db.prepare('pragma compile_options').all().map((row) => row.compile_options);
console.log(options.filter((value) => value.includes('FTS')).join('\n') || 'no fts compile options');
try {
db.exec("CREATE VIRTUAL TABLE t USING fts5(content)");
console.log("fts5: ok");
} catch (err) {
console.log("fts5: fail");
console.log(err instanceof Error ? err.message : String(err));
}
NODEExpected output:
ENABLE_FTS5
fts5: ok
If you get fts5: fail, build or install an FTS5-capable Node and point the gateway at that runtime.
This workflow was verified with Node v22.15.0.
cd ~/Projects
git clone --depth 1 --branch v22.15.0 https://github.com/nodejs/node.git node-fts5
cd node-fts5Edit deps/sqlite/sqlite.gyp and add SQLITE_ENABLE_FTS5 to the defines list for the sqlite
target:
'defines': [
'SQLITE_DEFAULT_MEMSTATUS=0',
+ 'SQLITE_ENABLE_FTS5',
'SQLITE_ENABLE_MATH_FUNCTIONS',
'SQLITE_ENABLE_SESSION',
'SQLITE_ENABLE_PREUPDATE_HOOK'
],Important:
- patch
deps/sqlite/sqlite.gyp, not onlynode.gyp node:sqliteuses the embedded SQLite built fromdeps/sqlite/sqlite.gyp
Build the runtime:
./configure --prefix="$PWD/out-install"
make -j8 nodeExpose the binary under a Node-compatible basename that OpenClaw recognizes:
mkdir -p ~/Projects/node-fts5/bin
ln -sfn ~/Projects/node-fts5/out/Release/node ~/Projects/node-fts5/bin/node-22.15.0Use a basename like node-22.15.0, node, or nodejs. Names like
node-v22.15.0-fts5 may not be recognized correctly by OpenClaw's CLI/runtime parsing.
Verify the new runtime:
~/Projects/node-fts5/bin/node-22.15.0 --version
~/Projects/node-fts5/bin/node-22.15.0 --input-type=module - <<'NODE'
import { DatabaseSync } from 'node:sqlite';
const db = new DatabaseSync(':memory:');
db.exec("CREATE VIRTUAL TABLE t USING fts5(content)");
console.log("fts5: ok");
NODEBack up the existing LaunchAgent plist first:
cp ~/Library/LaunchAgents/ai.openclaw.gateway.plist \
~/Library/LaunchAgents/ai.openclaw.gateway.plist.bak-$(date +%Y%m%d-%H%M%S)Replace the runtime path, then reload the agent:
/usr/libexec/PlistBuddy -c 'Set :ProgramArguments:0 /Users/youruser/Projects/node-fts5/bin/node-22.15.0' \
~/Library/LaunchAgents/ai.openclaw.gateway.plist
launchctl bootout gui/$UID ~/Library/LaunchAgents/ai.openclaw.gateway.plist 2>/dev/null || true
launchctl bootstrap gui/$UID ~/Library/LaunchAgents/ai.openclaw.gateway.plist
launchctl kickstart -k gui/$UID/ai.openclaw.gatewayVerify the live runtime:
launchctl print gui/$UID/ai.openclaw.gateway | sed -n '1,80p'You should see:
program = /Users/youruser/Projects/node-fts5/bin/node-22.15.0
Check the logs:
tail -n 60 ~/.openclaw/logs/gateway.log
tail -n 60 ~/.openclaw/logs/gateway.err.logYou want:
[gateway] [lcm] Plugin loaded ...- no new
no such module: fts5
Then force one turn through the gateway and verify the DB fills:
/Users/youruser/Projects/node-fts5/bin/node-22.15.0 \
/path/to/openclaw/dist/index.js \
agent --session-id fts5-smoke --message 'Reply with exactly: ok' --timeout 60
sqlite3 ~/.openclaw/lcm.db '
select count(*) as conversations from conversations;
select count(*) as messages from messages;
select count(*) as summaries from summaries;
'Those counts should increase after a real turn.