This skill should be used when working with memory-lancedb-pro, a production-grade long-term memory MCP plugin for OpenClaw AI agents. Use when installing, configuring, or using any feature of memory-lancedb-pro including Smart Extraction, hybrid retrieval, memory lifecycle management, multi-scope isolation, self-improvement governance, or any MCP memory tools (memory_recall, memory_store, memory_forget, memory_update, memory_stats, memory_list, self_improvement_log, self_improvement_extract_skill, self_improvement_review).
Trade-offs: No cross-encoder reranking = lower retrieval precision than Plans A/B; Smart Extraction quality depends on local LLM — if extraction produces garbage, set "smartExtraction": false
Best for: Privacy-sensitive deployments, air-gapped environments, zero API cost
After user selects a plan, ask in one message:
Please provide the required API key(s) for your chosen plan (paste directly, or say "already set as env vars")
Are the env vars already set in your OpenClaw Gateway process? (If unsure, answer No)
Where is your openclaw.json? (Skip if you want me to find it automatically)
If the user already stated their provider/keys in context, skip asking and proceed.
Do NOT proceed to Step 2 until API keys have been collected and verified (Step 2 below).
Step 2 — Verify API Keys (MANDATORY — do not skip)
Run ALL key checks for the chosen plan before touching any config. If any check fails, STOP and tell the user which key failed and why. Do not proceed to Step 3.
❌ STOP — ask user to check network / Ollama running
If any check fails: Tell the user exactly which provider failed, the HTTP code received, and what to fix. Do not proceed with installation until all required keys pass their checks.
If the user says keys are set as env vars in the gateway process, run checks using ${VAR_NAME} substituted inline or ask them to paste the key temporarily for verification.
Step 3 — Find openclaw.json
Check these locations in order:
bash
# Most common locations
ls ~/.openclaw/openclaw.json
ls ~/openclaw.json
# Ask the gateway where it's reading config from
openclaw config get --show-path 2>/dev/null || echo "not found"
If not found, ask the user for the path.
Step 4 — Read current config
bash
# Read and display current plugins config before changing anything
openclaw config get plugins.entries.memory-lancedb-pro 2>/dev/null
openclaw config get plugins.slots.memory 2>/dev/null
Check what already exists — never blindly overwrite existing settings.
Step 5 — Build the merged config based on chosen plan
Use the config block for the chosen plan. Substitute actual API keys inline if the user provided them directly; keep ${ENV_VAR} syntax if they confirmed env vars are set in the gateway process.
Plan A config (plugins.entries.memory-lancedb-pro.config):
Plan D prerequisites — run BEFORE applying config:
bash
# 1. Verify Ollama is running (should return JSON with model list)
curl http://localhost:11434/api/tags
# 2. Pull embedding model (choose one):
ollama pull mxbai-embed-large # recommended: 1024-dim, beats text-embedding-3-large, ~670MB
ollama pull snowflake-arctic-embed2 # best multilingual local option, ~670MB
ollama pull nomic-embed-text:v1.5 # classic stable, 768-dim, ~270MB
# 3. Pull LLM for Smart Extraction (choose one based on RAM):
ollama pull qwen3:8b # recommended: best JSON/structured output, ~5.2GB
ollama pull qwen3:14b # better quality, ~9GB, needs 16GB VRAM
ollama pull llama4:scout # multimodal MoE, 10M ctx, ~12GB
ollama pull mistral-small3.2 # 24B, 128K ctx, excellent, ~15GB
ollama pull mistral-nemo # 12B, 128K ctx, efficient, ~7GB
# 4. Verify models are installed
ollama list
# 5. Quick sanity check — embedding endpoint works:
curl http://localhost:11434/v1/embeddings \
-H "Content-Type: application/json" \
-d '{"model":"mxbai-embed-large","input":"test"}'
# Should return a JSON with a 1024-element vector
If Smart Extraction produces garbled/invalid output: The local LLM may not support structured JSON reliably. Try qwen3:8b first — it has native structured output support. If still failing, disable:
json
{ "smartExtraction": false }
If Ollama is on a different host or Docker: Replace http://localhost:11434/v1 with the actual host, e.g. http://192.168.1.100:11434/v1. Also set OLLAMA_HOST=0.0.0.0 in the Ollama process to allow remote connections.
For the plugins.entries.memory-lancedb-pro.config block, merge into the existing openclaw.json rather than replacing the whole file. Use a targeted edit of only the memory plugin config section.
Step 6 — Apply the config
Read the current openclaw.json first, then apply a surgical edit to the plugins.entries.memory-lancedb-pro section. Use the template that matches your installation method:
Method 1 — openclaw plugins install (plugin was installed via the plugin manager):
No load.paths or allow needed — the plugin manager already registered the plugin.
openclaw plugins info memory-lancedb-pro
openclaw hooks list --json | grep -E "before_agent_start|agent_end|command:new"
openclaw memory-pro stats
Then do a quick smoke test:
Store: call memory_store with text: "test memory for verification"
Recall: call memory_recall with query: "test memory"
Confirm the memory is returned
Installation
Quick Install (Beginner-Friendly)
For new users, the community one-click installer handles everything automatically — path detection, schema validation, auto-update, provider selection, and rollback:
Install Method 1 — via OpenClaw plugin manager (recommended)
bash
# Install from npm registry (@beta tag = latest pre-release, e.g. 1.1.0-beta.8)
openclaw plugins install memory-lancedb-pro@beta
# Install stable release from npm (@latest tag, e.g. 1.0.32)
openclaw plugins install memory-lancedb-pro
# Or install from a local git clone — use master branch (matches npm @beta)
git clone -b master https://github.com/CortexReach/memory-lancedb-pro.git /tmp/memory-lancedb-pro
openclaw plugins install /tmp/memory-lancedb-pro
npm vs GitHub branches:@beta installs from the npm registry (not directly from GitHub). The repo has two long-lived branches: master is the release branch (matches npm @beta), main is older/behind. Always clone master if you want code that matches the published beta.
Then bind the memory slot and add your config (see Configuration section below):
Use absolute paths in plugins.load.paths. Add to plugins.allow. Bind memory slot: plugins.slots.memory = "memory-lancedb-pro". Set plugins.entries.memory-lancedb-pro.enabled: true.
After the plugin starts successfully, determine which scenario applies and run the corresponding steps:
Scenario A — Coming from built-in memory-lancedb plugin (most common upgrade path)
The old plugin stores data in LanceDB at ~/.openclaw/memory/lancedb. Use the migrate command:
bash
# 1. Check if old data exists and is readable
openclaw memory-pro migrate check
# 2. Preview what would be migrated (dry run)
openclaw memory-pro migrate run --dry-run
# 3. Run the actual migration
openclaw memory-pro migrate run
# 4. Verify migrated data
openclaw memory-pro migrate verify
openclaw memory-pro stats
Note: Markdown-based memory files (MEMORY.md, AGENTS.md) are workspace context files, not the same as the LanceDB memory store. You only need to migrate them if you want that content searchable via memory_recall.
Scenario D — Fresh install, no prior memories
No migration needed. Verify the plugin is working with a quick smoke test:
bash
openclaw memory-pro stats # should show 0 memories
Then trigger a conversation — autoCapture will start storing memories automatically.
LanceDB Version Compatibility
No manual action required for LanceDB version changes.
The plugin requires @lancedb/lancedb ^0.26.2 as an npm dependency — this is installed automatically when you install or update the plugin. You do not need to manually install or upgrade LanceDB.
LanceDB 0.26+ changed how numeric columns are returned (Arrow BigInt type for timestamp, importance, _distance, _score). The plugin handles this transparently at runtime via internal Number(...) coercion — no migration commands are needed when moving between LanceDB versions.
TL;DR: LanceDB version compatibility is fully automatic. See the table below for when each maintenance command actually applies.
Upgrading plugin code vs. data
Command distinction (important):
Command
When to use
openclaw plugins update memory-lancedb-pro
Update plugin code after a new release (npm-installed only)
openclaw plugins update --all
Update all npm-installed plugins at once
openclaw memory-pro upgrade
Enrich old memory-lancedb-pro entries that predate the smart-memory schema (missing L0/L1/L2 metadata + 6-category system) — NOT related to LanceDB version
openclaw memory-pro migrate
One-time migration from the separate memory-lancedb built-in plugin → Pro
openclaw memory-pro reembed
Rebuild all embeddings after switching embedding model or provider
When do you need memory-pro upgrade?
Run it if you installed memory-lancedb-pro before the smart-memory format was introduced (i.e., entries are missing memory_category in their metadata). Signs you need it:
memory_recall returns results but without meaningful categories
memory-pro list --json shows entries with no l0_abstract / l1_overview fields
Safe upgrade sequence:
bash
# 1. Backup first
openclaw memory-pro export --scope global --output memories-backup.json
# 2. Preview what would change
openclaw memory-pro upgrade --dry-run
# 3. Run upgrade (uses LLM by default for L0/L1/L2 generation)
openclaw memory-pro upgrade
# 4. Verify results
openclaw memory-pro stats
openclaw memory-pro search "your known keyword" --scope global --limit 5
Upgrade options:
bash
openclaw memory-pro upgrade --no-llm # skip LLM, use simple text truncation
openclaw memory-pro upgrade --batch-size 5 # slower but safer for large collections
openclaw memory-pro upgrade --limit 50 # process only first N entries
openclaw memory-pro upgrade --scope global # limit to one scope
Plugin management commands
bash
openclaw plugins list # show all discovered plugins
openclaw plugins info memory-lancedb-pro # show plugin status and config
openclaw plugins enable memory-lancedb-pro # enable a disabled plugin
openclaw plugins disable memory-lancedb-pro # disable without removing
openclaw plugins update memory-lancedb-pro # update npm-installed plugin
openclaw plugins update --all # update all npm plugins
openclaw plugins doctor # health check for all plugins
openclaw plugins install ./path/to/plugin # install local plugin (copies + enables)
openclaw plugins install @scope/plugin@beta # install from npm registry
openclaw plugins install -l ./path/to/plugin # symlink for dev (no copy)
Gateway restart required after: plugins install, plugins enable, plugins disable, plugins update, or any change to openclaw.json. Changes do not take effect until the gateway is restarted.
bash
openclaw gateway restart
Easy-to-Miss Setup Steps
Gateway restart required after any change: After installing, enabling, disabling, updating, or changing config in openclaw.json, you MUST run openclaw gateway restart — changes are NOT hot-reloaded.
Workspace plugins are DISABLED by default: After git clone, you MUST add plugins.allow: ["memory-lancedb-pro"] AND plugins.entries.memory-lancedb-pro.enabled: true — without these the plugin silently does not load.
Env vars in gateway process: ${OPENAI_API_KEY} requires env vars set in the OpenClaw Gateway service process—not just your shell.
Absolute vs. relative paths: For existing deployments, always use absolute paths in plugins.load.paths.
baseURL not baseUrl: The embedding (and llm) config field is baseURL (capital URL), NOT baseUrl. Using the wrong casing causes a schema validation error: "must NOT have additional properties". Also note the required /v1 suffix: http://localhost:11434/v1, not http://localhost:11434. Do not confuse with agents.defaults.memorySearch.remote.baseUrl which uses a different casing.
jiti cache invalidation: After modifying .ts files under plugins, run rm -rf /tmp/jiti/ BEFORE openclaw gateway restart.
Unknown plugin id = error: OpenClaw treats unknown ids in entries, allow, deny, or slots as validation errors. The plugin id must be discoverable before referencing it.
Separate LLM config: If embedding and LLM use different providers, configure the llm section separately — it falls back to embedding key/URL otherwise.
Scope isolation: Multi-scope requires explicit scopes.agentAccess mapping — without it, agents only see global scope.
Session memory hook: Fires on /new command — test with an actual /new invocation.
Reranker credentials: When switching providers, update both rerankApiKey AND rerankEndpoint.
Config check before assuming defaults: Run openclaw config get plugins.entries.memory-lancedb-pro to verify what's actually loaded.
Custom config/state paths via env vars: OpenClaw respects the following environment variables for custom paths:
OPENCLAW_HOME — sets the root config/data directory (default: ~/.openclaw/)
OPENCLAW_CONFIG_PATH — absolute path to openclaw.json override
OPENCLAW_STATE_DIR — override for runtime state/data directory
Set these in the OpenClaw Gateway process's environment if the default ~/.openclaw/ path is not appropriate.
Post-Installation Verification
bash
openclaw doctor # full health check (recommended)
openclaw config validate # config schema check only
openclaw plugins info memory-lancedb-pro # plugin status
openclaw plugins doctor # plugin-specific health
openclaw hooks list --json | grep memory # confirm hooks registered
openclaw memory-pro stats
openclaw memory-pro list --scope global --limit 5
Full smoke test checklist:
✅ Plugin info shows enabled: true and config loaded
✅ Hooks include before_agent_start, agent_end, command:new
✅ One memory_store → memory_recall round trip via tools
# Download once
curl -fsSL https://raw.githubusercontent.com/CortexReach/toolbox/main/memory-lancedb-pro-setup/scripts/config-validate.mjs -o config-validate.mjs
# Run against your openclaw.json
node config-validate.mjs
# Or validate a specific config snippet
node config-validate.mjs --json '{"embedding":{"baseURL":"http://localhost:11434/v1","model":"bge-m3","apiKey":"ollama"}}'
Exit code 0 = pass/warn, 1 = errors found.
Error message
Root cause
Fix
must NOT have additional properties + config.embedding
Field name typo in embedding config (e.g. baseUrl instead of baseURL)
Check all field names against the schema table below — field names are case-sensitive
must NOT have additional properties (top-level config)
Unknown top-level field in plugin config
Remove or correct the field
memory-lancedb-pro: plugin not found / plugin silently not loading
plugins.allow missing (git-clone install) or enabled: false
Add plugins.allow: ["memory-lancedb-pro"] and set enabled: true, then restart
Unknown plugin id validation error
Plugin referenced in entries/slots before it's discoverable
Install/register the plugin first, then add config references
${OPENAI_API_KEY} not expanding / auth errors despite env var set
Env var not set in the gateway process environment
Set the env var in the service that runs OpenClaw gateway, not just your shell
Hooks (before_agent_start, agent_end) not firing
Gateway not restarted after install/config change
Run openclaw gateway restart
Embedding errors with Ollama
Wrong baseURL format
Must be http://localhost:11434/v1 (with /v1), field must be baseURL not baseUrl
memory-pro stats shows 0 entries after conversation
autoCapture false or extractMinMessages not reached
Set autoCapture: true; need at least extractMinMessages (default 2) turns
Memories not injected before agent replies
autoRecall is false (schema default)
Explicitly set "autoRecall": true
jiti cache error after editing plugin .ts files
Stale compiled cache
Run rm -rf /tmp/jiti/ then openclaw gateway restart
jina / siliconflow / voyage / pinecone / vllm (Docker Model Runner)
rerankModel
string
jina-reranker-v3
Reranker model name
rerankEndpoint
string
provider default
Reranker API URL
rerankApiKey
string
—
Reranker API key
candidatePoolSize
number
20
Candidates to rerank before final filter
recencyHalfLifeDays
number
14
Freshness decay half-life
recencyWeight
number
0.1
Weight of recency in scoring
timeDecayHalfLifeDays
number
60
Memory age decay factor
reinforcementFactor
number
0.5
Access-based half-life multiplier (0–2, set 0 to disable)
maxHalfLifeMultiplier
number
3
Hard cap on reinforcement boost
filterNoise
boolean
true
Filter refusals, greetings, etc.
lengthNormAnchor
number
500
Reference length for normalization (chars)
Access reinforcement note: Reinforcement is whitelisted to source: "manual" only — auto-recall does NOT strengthen memories, preventing noise amplification.
Session Strategy (v1.1.0+)
Use sessionStrategy (top-level field) to configure the session pipeline:
Value
Behavior
"systemSessionMemory"(default)
Built-in session memory (simpler)
"memoryReflection"
Advanced LLM-powered reflection with inheritance/derived injection
"none"
Session summaries disabled
memoryReflection config (used when sessionStrategy: "memoryReflection"):
self_improvement_log is enabled by default (selfImprovement.enabled: true). self_improvement_extract_skill and self_improvement_review additionally require enableManagementTools: true.
self_improvement_log — Log learning/error entries into LEARNINGS.md / ERRORS.md
DashScope rerank note: DashScope is not a rerankProvider enum value, but its rerank API response is Jina-compatible. Use rerankProvider: "jina" with DashScope's endpoint:
## Rule 1 — 双层记忆存储(铁律)
Every pitfall/lesson learned → IMMEDIATELY store TWO memories:
- Technical layer: Pitfall/Cause/Fix/Prevention (category: fact, importance ≥ 0.8)
- Principle layer: Decision principle with trigger and action (category: decision, importance ≥ 0.85)
After each store, immediately `memory_recall` to verify retrieval.
## Rule 2 — LanceDB 卫生
Entries must be short and atomic (< 500 chars). No raw conversation summaries or duplicates.
## Rule 3 — Recall before retry
On ANY tool failure, ALWAYS `memory_recall` with relevant keywords BEFORE retrying.
## Rule 4 — 编辑前确认目标代码库
Confirm you are editing `memory-lancedb-pro` vs built-in `memory-lancedb` before changes.
## Rule 5 — 插件代码变更必须清 jiti 缓存
After modifying `.ts` files under `plugins/`, MUST run `rm -rf /tmp/jiti/` BEFORE `openclaw gateway restart`.
Custom Slash Commands (add to CLAUDE.md / AGENTS.md)
markdown
## /lesson command
When user sends `/lesson <content>`:
1. Use memory_store with category=fact (raw knowledge)
2. Use memory_store with category=decision (actionable takeaway)
3. Confirm what was saved
## /remember command
When user sends `/remember <content>`:
1. Use memory_store with appropriate category and importance
2. Confirm with stored memory ID