A structured, self-maintaining memory system for OpenClaw agents.
OpenClaw's built-in memory is markdown files + LLM discretion. This means:
Memory Oracle fixes all of these with zero external dependencies (Python stdlib + SQLite).
Two processes, mirroring the HEAVY/LIGHT pattern:
capture.py — Rule-based extraction runs AFTER each agent response.
Parses the conversation turn for facts, decisions, preferences, tasks
using bilingual (RU+EN) pattern matching. Writes to SQLite.
If a fact's content hash already exists → bumps access_count instead.
recall.py — Three-slot retrieval runs BEFORE each agent response. Injects relevant context from SQLite using a budget of ~2000 tokens:
score = importance × recency × access_boostcheckpoint.py — Emergency save triggered by OpenClaw's pre-compaction hook.
Dumps all hot-tier context to SQLite with source = "checkpoint" tag.
Runs nightly at 03:00 agent-local time:
consolidate.py — Sends today's daily log to Claude API (~2K tokens). Extracts structured facts that rule-based capture missed.
reflect.py — Analyzes the day's facts against MEMORY.md and prior reflections.
reflection.json with score modifications + YYYY-MM-DD-reflection.md digest.maintenance.py — Applies decay, prunes dead facts, archives cold tier, re-renders MEMORY.md from top SQLite facts, vacuums DB.
These rules go into your AGENTS.md or equivalent config:
text
## Memory Oracle Protocol
BEFORE responding to the user:
Run: python3 ~/.openclaw/skills/memory-oracle/scripts/recall.py --query "<user message>"
Inject the output into your context as relevant background.
AFTER responding to the user:
Run: python3 ~/.openclaw/skills/memory-oracle/scripts/capture.py --turn "<full turn text>"
When the user says "remember this", "never forget", "this is critical":
Run: python3 ~/.openclaw/skills/memory-oracle/scripts/capture.py --turn "<text>" --guardrail
When the user asks "what do you know about X":
Run: python3 ~/.openclaw/skills/memory-oracle/scripts/recall.py --query "X" --verbose
Show the facts with their scores, sources, and ages.
Every 10 turns (heartbeat):
Run: python3 ~/.openclaw/skills/memory-oracle/scripts/capture.py --flush
This forces extraction of any buffered context.
bash
cd ~/.openclaw/skills/
git clone <repo-url> memory-oracle
cd memory-oracle
bash install.sh
The installer will:
Note: The installer does NOT auto-edit your AGENTS.md or OpenClaw config. You review and paste the snippets yourself.
All thresholds live in config/settings.json. Key tunables:
recall_budget_tokens: Total injection budget (default: 2000)decay_rate: Daily score decay multiplier (default: 0.05)archive_threshold: Score below which facts move to cold (default: 0.2)delete_threshold: Score below which cold facts are purged (default: 0.05)delete_min_age_days: Minimum age before deletion (default: 90)reflect_deep_day: Day of week for deep reflection, 0=Mon (default: 0)api_model: Model for HEAVY process (default: claude-sonnet-4-20250514)api_max_tokens: Max response tokens for LLM calls (default: 1000)bash
cd ~/.openclaw/skills/memory-oracle
bash uninstall.sh
The uninstaller will:
Use --force to skip confirmations, --keep-db to keep the database while removing everything else.
FTS5 not available on some systems. Minimal containers (Alpine) and old Debian/Ubuntu may lack FTS5. install.sh checks for this and prints fix instructions. Most systems with Python 3.8+ include FTS5.
Conflict with other memory skills.
If you have memory-complete, continuity, or agent-brain installed, they may
compete for MEMORY.md writes. Disable other memory plugins before installing:
plugins.slots.memory = "none" in your OpenClaw config, or remove conflicting skills.
Cron unavailable in containers. Docker, sandboxed VPS, and some hosting environments block crontab. install.sh handles this gracefully — just run the HEAVY pipeline manually or via your own scheduler (systemd timer, supervisor, etc.):
bash
python3 scripts/consolidate.py && python3 scripts/reflect.py --auto && python3 scripts/maintenance.py
Large existing MEMORY.md (>50KB).
Import during init_db.py works but may create noisy low-confidence facts.
After install, run python3 scripts/maintenance.py --stats and check the
fact count. If too high, run python3 scripts/maintenance.py to let decay
and pruning clean up naturally over a few days.
Rule-based capture misses implicit facts. Capture.py uses pattern matching — it catches ~70% of facts. The remaining 30% are caught by consolidate.py (HEAVY process) with LLM extraction. Without ANTHROPIC_API_KEY, only rule-based capture works.
text
memory-oracle/
├── SKILL.md ← You are here
├── README.md ← GitHub-friendly docs
├── LICENSE ← MIT
├── install.sh ← Bootstrap + cron setup
├── uninstall.sh ← Safe rollback + export
├── scripts/
│ ├── init_db.py ← Schema + migration from existing .md
│ ├── capture.py ← LIGHT: rule-based extraction
│ ├── recall.py ← LIGHT: 3-slot hybrid search
│ ├── checkpoint.py ← Pre-compaction emergency save
│ ├── consolidate.py ← HEAVY: LLM fact extraction
│ ├── reflect.py ← HEAVY: adaptive reflection
│ ├── maintenance.py ← HEAVY: decay, prune, re-render
│ └── migrate.py ← Schema version management
├── config/
│ ├── settings.json ← All tunables
│ └── patterns.json ← Bilingual extraction rules
├── prompts/
│ ├── consolidate.txt ← LLM extraction prompt
│ ├── reflect_light.txt ← Daily reflection prompt
│ └── reflect_deep.txt ← Weekly reflection prompt
└── tests/
├── test_capture.py ← Pattern matching tests
└── test_recall.py ← Ranking + budget tests
Every component is designed to fail safely:
pending_queue.json, LIGHT continuesfailed_reflections/, scores unchangedWhat stays local (always):
What is sent to Anthropic API (HEAVY process only):
consolidate.py sends the text of today's daily log to Claude API for fact extractionreflect.py sends extracted facts (not raw logs) and current memory state for analysisANTHROPIC_API_KEY env var to be setIf you are not comfortable sending daily logs to an external LLM:
api.model to a local model endpoint in config/settings.jsonANTHROPIC_API_KEY — the skill runs in LIGHT-only mode
with rule-based capture and full recall, just without LLM-powered consolidation
and reflectionOther privacy rules:
maintenance.py --export dumps full state to JSON for backup/migrationTMkk6SHacogyEtSepLPzh8qU12iPTsG8Y3