#20577: Add versioning and time-travel to memory-lancedb
extensions: memory-lancedb
size: M
Cluster:
Plugin Fixes and Enhancements
## Motivation
The existing `memory-lancedb` extension lacked version control, making it impossible to:
- Roll back after storing incorrect information
- Debug issues by recreating memory state at a specific point in time
- Safely experiment with different memory states
- Audit how agent knowledge evolved over time
This PR adds versioning with time-travel and named snapshots using LanceDB's native APIs.
## Summary
Add versioning and time-travel capabilities to the existing `memory-lancedb` extension:
- ✅ Automatic versioning on every add() operation
- ✅ Named snapshots (checkpoints) via tags
- ✅ Time-travel via checkout to previous versions
- ✅ Version history with timestamps
- ✅ Storage optimization via compaction
## Implementation
Uses **native LanceDB JavaScript APIs** (requires @lancedb/lancedb >= 0.26.2):
- `table.version()` - Get current version number
- `table.checkout(version)` - Time-travel to specific version
- `table.checkoutLatest()` - Return to latest version
- `table.listVersions()` - List all versions with timestamps
- `table.tags()` - Manage named snapshots (tags)
- `table.optimize()` - Compaction and version pruning
## New Agent Tools
```typescript
// Create a named checkpoint
await memory_snapshot({ name: "before-experiment" })
// Time-travel to a specific version or snapshot
await memory_checkout({ version: "before-experiment" })
await memory_checkout({ version: 42 })
// Return to latest version
await memory_checkout_latest({})
// List version history
await memory_versions({ limit: 10 })
// List all snapshots
await memory_snapshots({})
// Delete a snapshot
await memory_delete_snapshot({ name: "old-snapshot" })
```
## New CLI Commands
```bash
# Show current version
openclaw ltm version
# List version history
openclaw ltm versions --limit 20
# Create a named snapshot
openclaw ltm snapshot before-refactor
# Time-travel to a version
openclaw ltm checkout 42
openclaw ltm checkout before-refactor
# Return to latest
openclaw ltm checkout-latest
# List all snapshots
openclaw ltm snapshots
# Delete a snapshot
openclaw ltm delete-snapshot old-snapshot
# Optimize storage (compaction and pruning)
openclaw ltm optimize --cleanup-days 30
```
## Example Workflow
```typescript
// 1. Store some memories
await memory_store({ text: "User prefers TypeScript", importance: 0.8 })
await memory_store({ text: "User uses VSCode", importance: 0.7 })
// 2. Create a checkpoint
await memory_snapshot({ name: "stable-state" })
// 3. Store more memories (oops, wrong info!)
await memory_store({ text: "User prefers JavaScript", importance: 0.6 })
// 4. Time-travel back to the checkpoint (read-only)
await memory_checkout({ version: "stable-state" })
// 5. Verify - search now returns TypeScript, not JavaScript
await memory_recall({ query: "language preferences" })
// Returns: "User prefers TypeScript"
// 6. Return to latest to continue normal operations
await memory_checkout_latest({})
```
## Important: Checkout Behavior
When you checkout an old version:
- **Read operations** (memory_recall, memory_search) return data from that version
- **Write operations** (memory_store) are **blocked** - you must `checkout_latest` first
- Checkout state is **per-process** - doesn't affect other running instances
This prevents accidentally writing to historical versions.
## Limitations
- **Linear history only**: No branching or merging (unlike Git)
- **Storage overhead**: Each version stores metadata; use `optimize` to prune old versions
- **Checkout is read-only**: Must return to latest before writing
- **No concurrent checkout**: Multiple checkouts in same process will conflict
## Performance Note
LanceDB creates a new version on every `add()` operation. For high-volume usage:
- Run `openclaw ltm optimize --cleanup-days 30` monthly
- Or add a cron job: `0 0 1 * * openclaw ltm optimize`
Optimization prunes old versions and compacts storage for better query performance.
## Test Plan
- [ ] **Basic versioning**: Verify version increments after each add()
- [ ] **Snapshots**: Create, list, delete, and checkout snapshots
- [ ] **Time-travel**: Checkout version → verify search results change → checkout latest
- [ ] **Write blocking**: Verify memory_store fails when checked out to old version
- [ ] **Version history**: List versions with correct timestamps
- [ ] **Compaction**: Run optimize, verify storage reduction and version pruning
- [ ] **CLI commands**: Test all new ltm commands
- [ ] **Backward compatibility**: Existing tools (memory_store, memory_recall) still work
## Files Changed
- `extensions/memory-lancedb/index.ts` - Added versioning methods, tools, and CLI commands (+320 lines)
## Dependencies
- Requires `@lancedb/lancedb` >= 0.26.2 for versioning APIs
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Most Similar PRs
#22692: fix(memory-lancedb): [P1] add missing runtime deps — plugin broken ...
by mahsumaktas · 2026-02-21
70.5%
#16657: feat(memory-lancedb): add memory CLI command alias
by ciberponk · 2026-02-15
67.5%
#3401: fix(memory-lancedb): improve autoCapture with turn-by-turn processing
by mike-nott · 2026-01-28
67.5%
#15896: fix(memory-lancedb): capture even with injected recall context
by aelaguiz · 2026-02-14
66.1%
#13671: fix(memory-lancedb): ship @lancedb/lancedb for bundled extension
by CryptoJym · 2026-02-10
66.0%
#11113: fix(memory-lancedb): preserve error cause in LanceDB load failure
by marezgui · 2026-02-07
65.1%
#20791: Feature/aeon memory plugin
by mustafarslan · 2026-02-19
65.0%
#18701: feat(memory-milvus): add Milvus/Zilliz Cloud vector memory provider
by supmo668 · 2026-02-17
64.7%
#16669: feat(memory-lancedb): add memory_search/memory_get compatibility re...
by ciberponk · 2026-02-15
64.7%
#17566: memory-lancedb: support local OpenAI-compatible embeddings
by lumenradley · 2026-02-15
63.9%