Smart Memory Plus
Unified memory management + context compression for OpenClaw. Zero external dependencies.
⚠️ Conflict Warning: This skill replaces both smart-memory and context-compactor.
Do NOT install alongside either of those skills — they share the same files
(SESSION-STATE.md, memory/, MEMORY.md) and will cause write conflicts.
Requirements
- - Runtime: Python 3.10+ (standard library only), Bash 4.0+ (health/extract scripts only)
- OS: Linux, macOS
- Environment variables (all optional, with defaults):
-
OPENCLAW_WORKSPACE — Workspace root (default:
~/.openclaw/workspace)
-
OPENCLAW_SESSION_ID — Session identifier for temp cache (default:
default)
Security
Write Restrictions (Hard Rules)
The agent MUST use the provided scripts for ALL writes. Direct file writes are FORBIDDEN.
| File | Required Script | Forbidden |
|---|
| INLINECODE9 | INLINECODE10 (WAL protocol) | Direct write/overwrite |
| INLINECODE11 |
compact_session.py --write | Direct write/overwrite |
|
memory/*.md (daily notes) |
extract_memories.sh --auto or append via script | Direct overwrite |
|
MEMORY.md |
memory_decay.py --promote-only | Direct overwrite |
|
/tmp/openclaw-session-*.json |
session_cache.py | Direct write |
Critical: Never use the agent's file-write tool directly on memory files. Always pipe through scripts — they enforce sanitization, deduplication, and append-only behavior.
The agent MUST NOT write to:
- - Any directory outside the workspace
- System directories (/etc, /usr, /var, /tmp except session cache)
- User home directory root (~/.ssh, ~/.config, ~/.aws, etc.)
- Any
.* dotfile or dotdir in workspace root
Sensitive Data Protection
All write commands automatically reject inputs matching:
- - API keys/tokens (OpenAI
sk-*, GitHub ghp_*, ClawHub clh_*) - Passwords (
password=, passwd:, etc.) - Private keys (
-----BEGIN PRIVATE KEY-----)
This is a hard block at the script level — the agent cannot bypass it.
Privacy Boundaries
- - Compacts must NOT contain: file paths, internal URLs, IPs, passwords, tokens
- Use placeholders:
<REDACTED_PATH>, <REDACTED_URL>, INLINECODE28 - All data stays local — all scripts make zero network calls, no LLM usage
Memory Layers
| Layer | File | Purpose | Lifetime |
|---|
| HOT RAM | INLINECODE29 | Current task, context, decisions | Session (survives compaction) |
| DAILY |
memory/YYYY-MM-DD.md | Raw daily notes with type tags | 90 days → archive |
|
CURATED |
MEMORY.md | Promoted long-term facts | Permanent |
|
COMPACT |
memory/compacts/YYYY-MM-DD-HHMM.md | Session digests | 30 max, auto-cleanup |
|
GRAPH |
memory/.index/graph.db | Entity-relation knowledge graph | Rebuild from source |
|
ARCHIVE |
memory/archive/YYYY-MM/ | Stale daily files | Forever (compressed) |
|
CACHE |
/tmp/openclaw-session-*.json | Session temp data | Session end / reboot |
Quick Reference
Memory Management
| Action | Script |
|---|
| WAL shortcut | INLINECODE36 |
| Set current task |
scripts/wal task "description" |
| Log a decision |
scripts/wal decide "chose X over Y" |
| Add context |
scripts/wal context key value |
| Session cache |
python3 scripts/session_cache.py set/get/list/clear |
| Classify memories |
python3 scripts/classify_memory.py --summary/--apply |
| Decay & archive |
python3 scripts/memory_decay.py --dry-run/--promote-only |
| Health report |
bash scripts/memory_health.sh |
Search & Relations
| Action | Script |
|---|
| Full index rebuild | INLINECODE44 |
| Incremental update |
python3 scripts/memory_search_bm25.py update |
| Search memories (BM25) |
python3 scripts/memory_search_bm25.py search "query" [--top N] |
| Index status |
python3 scripts/memory_search_bm25.py status |
| Find related entries |
python3 scripts/classify_memory.py --related "query" [--top N] |
| Build knowledge graph |
python3 scripts/memory_graph.py build |
| Graph relations |
python3 scripts/memory_graph.py related "entity" [--depth N] |
| Graph stats |
python3 scripts/memory_graph.py stats |
| Raw graph query |
python3 scripts/memory_graph.py query "SELECT ..." |
Context Compression
| Action | Script |
|---|
| Extract compact (stdin) | INLINECODE53 |
| Write compact (stdin) |
python3 scripts/compact_session.py --write |
| List compacts |
python3 scripts/compact_session.py --list |
| Read latest compact |
python3 scripts/compact_session.py --latest |
| Compact stats |
python3 scripts/compact_session.py --stats |
WAL Protocol (Write-Ahead Log)
Critical rule: Write BEFORE responding.
When the user provides information that should be remembered:
- 1. Write to SESSION-STATE.md (via
session_state.py) - Then respond to the user
This prevents context loss if compaction, crash, or restart happens between response and write.
| User Action | WAL Write |
|---|
| States a preference | INLINECODE59 |
| Makes a decision |
session_state.py decide "chose X" |
| Gives a deadline |
session_state.py context "deadline" "date" |
| Corrects agent |
session_state.py decide "correction: X not Y" |
| Assigns task |
session_state.py task "description" |
| Mentions blocker |
session_state.py blocker "description" |
Memory Types
All entries tagged with a type prefix:
- -
[PREF] — User preferences, habits, style - INLINECODE66 — Project context, active work, goals
- INLINECODE67 — Technical details, configs, system knowledge
- INLINECODE68 — Lessons learned, errors, corrections
- INLINECODE69 — People, relationships, social context
- INLINECODE70 — Session-scoped, auto-expires
Core Workflows
Session Start
- 1. Read
SESSION-STATE.md for current task/context - Search for relevant context:
-
python3 scripts/memory_search_bm25.py build (if index is stale or missing)
-
python3 scripts/memory_search_bm25.py search "current topic" (semantic search)
- Also use
memory_search (OpenClaw built-in tool) as complementary search
- 3. Check for recent compacts: INLINECODE75
- If output exists, read it and use relevant parts as context for the session
- This is a manual agent step — the skill does not auto-inject
- 4. Check
memory/YYYY-MM-DD.md for today's activity
During Conversation (WAL)
- 1. User provides actionable info → write to SESSION-STATE.md FIRST
- Important facts → append to
memory/YYYY-MM-DD.md with type tag - Use
session_cache.py for transient session data
Session End (Compaction)
- 1. Update
SESSION-STATE.md with final state - If conversation > 50 turns or user says "compact":
- Draft compact content (decisions, facts, pending, blockers)
- Pipe through security checks:
echo "content" | python3 scripts/compact_session.py --write
- Include
[TYPE] tags per smart-memory classification
- 3. Promote durable items from daily notes to INLINECODE82
Periodic Maintenance
- - Run
memory_decay.py when MEMORY.md > 200 lines or 50+ daily files - Run
classify_memory.py to tag orphaned entries - Run
memory_search_bm25.py update to refresh search index after edits - Run
memory_graph.py build to refresh knowledge graph - Archive daily files older than 90 days
- Compact auto-cleanup keeps only last 30
Agent Behavior
Auto-Extract When
- - User shares preference, opinion, or personal fact
- Project decision is made or changed
- Error encountered and resolved (→ LESSON)
- New people, tools, or workflows mentioned
Extraction Mode
- -
extract_memories.sh --auto "text" — keyword matching, zero token cost, fully local
Compaction Mode
- -
compact_session.py --extract — regex-based extraction, zero token cost, fully local
Do NOT Extract/Compact
- - Passwords, tokens, API keys, credentials (scripts hard-block these)
- Private conversations about third parties not relevant to work
- Speculation or uncertain information
- Transient state ("user is currently looking at page X")
- Information the user explicitly said not to remember
Scripts
| Script | Language | Purpose | Security |
|---|
| INLINECODE89 | Python | HOT RAM working memory (WAL) | Sensitive data filter + sanitization |
| INLINECODE90 |
Python | Session-scoped temp cache | Sensitive data filter + path-safe IDs |
|
compact_session.py | Python | Context compression & digests | Path containment + sensitive filter |
|
extract_memories.sh | Bash | Memory extraction guide & auto-extract | Read-only + sensitive filter (Python) |
|
classify_memory.py | Python | Keyword + n-gram type classification, related search | Dry-run mode, duplicate check |
|
memory_decay.py | Python | Temporal decay & LESSON promotion | Dry-run mode |
|
memory_health.sh | Bash | Health report (stats, orphans, tokens) | Read-only |
|
memory_search_bm25.py | Python | BM25 semantic search over memories | Local-only, zero network |
|
memory_graph.py | Python | SQLite knowledge graph (entities + relations) | Local-only, SELECT-only queries |
References
- -
references/extraction_prompt.md — Extraction prompt template (for agent-internal use) - INLINECODE99 — Compaction prompt template (for agent-internal use)
- INLINECODE100 — Decay/archival rule set
- INLINECODE101 — Full schema and format spec
Smart Memory Plus
为 OpenClaw 提供统一的内存管理与上下文压缩。零外部依赖。
⚠️ 冲突警告:此技能会替换 smart-memory 和 context-compactor 两个技能。
请勿与这两个技能同时安装——它们共享相同的文件
>(SESSION-STATE.md、memory/、MEMORY.md),会导致写入冲突。
要求
- - 运行环境:Python 3.10+(仅标准库)、Bash 4.0+(仅健康检查/提取脚本)
- 操作系统:Linux、macOS
- 环境变量(均为可选,有默认值):
- OPENCLAW_WORKSPACE — 工作区根目录(默认:~/.openclaw/workspace)
- OPENCLAW
SESSIONID — 临时缓存的会话标识符(默认:default)
安全
写入限制(硬性规则)
代理必须使用提供的脚本进行所有写入操作。禁止直接写入文件。
| 文件 | 必需脚本 | 禁止操作 |
|---|
| SESSION-STATE.md | sessionstate.py(WAL 协议) | 直接写入/覆盖 |
| memory/compacts/*.md |
compactsession.py --write | 直接写入/覆盖 |
| memory/*.md(每日笔记) | extract_memories.sh --auto 或通过脚本追加 | 直接覆盖 |
| MEMORY.md | memory_decay.py --promote-only | 直接覆盖 |
| /tmp/openclaw-session-*.json | session_cache.py | 直接写入 |
关键:切勿直接使用代理的文件写入工具操作内存文件。始终通过脚本传递——它们强制执行清理、去重和仅追加行为。
代理不得写入:
- - 工作区之外的任何目录
- 系统目录(/etc、/usr、/var、/tmp 除会话缓存外)
- 用户主目录根目录(~/.ssh、~/.config、~/.aws 等)
- 工作区根目录中的任何 .* 点文件或点目录
敏感数据保护
所有写入命令会自动拒绝匹配以下模式的输入:
- - API 密钥/令牌(OpenAI sk-、GitHub ghp、ClawHub clh*)
- 密码(password=、passwd: 等)
- 私钥(-----BEGIN PRIVATE KEY-----)
这是脚本级别的硬性拦截——代理无法绕过。
隐私边界
- - 压缩内容不得包含:文件路径、内部 URL、IP 地址、密码、令牌
- 使用占位符:PATH>、URL>、
- 所有数据保留在本地——所有脚本零网络调用,不使用 LLM
内存层级
| 层级 | 文件 | 用途 | 生命周期 |
|---|
| 热内存 | SESSION-STATE.md | 当前任务、上下文、决策 | 会话(压缩后保留) |
| 每日 |
memory/YYYY-MM-DD.md | 带类型标签的原始每日笔记 | 90 天 → 归档 |
|
精选 | MEMORY.md | 提升的长期事实 | 永久 |
|
压缩 | memory/compacts/YYYY-MM-DD-HHMM.md | 会话摘要 | 最多 30 个,自动清理 |
|
图谱 | memory/.index/graph.db | 实体关系知识图谱 | 从源重建 |
|
归档 | memory/archive/YYYY-MM/ | 过期的每日文件 | 永久(压缩) |
|
缓存 | /tmp/openclaw-session-*.json | 会话临时数据 | 会话结束/重启 |
快速参考
内存管理
| 操作 | 脚本 |
|---|
| WAL 快捷方式 | scripts/wal task/decide/context/pending/done/blocker/get/snapshot/restore |
| 设置当前任务 |
scripts/wal task 描述 |
| 记录决策 | scripts/wal decide 选择了 X 而非 Y |
| 添加上下文 | scripts/wal context 键 值 |
| 会话缓存 | python3 scripts/session_cache.py set/get/list/clear |
| 分类记忆 | python3 scripts/classify_memory.py --summary/--apply |
| 衰减与归档 | python3 scripts/memory_decay.py --dry-run/--promote-only |
| 健康报告 | bash scripts/memory_health.sh |
搜索与关系
| 操作 | 脚本 |
|---|
| 完整索引重建 | python3 scripts/memorysearchbm25.py build |
| 增量更新 |
python3 scripts/memory
searchbm25.py update |
| 搜索记忆(BM25) | python3 scripts/memory
searchbm25.py search 查询 [--top N] |
| 索引状态 | python3 scripts/memory
searchbm25.py status |
| 查找相关条目 | python3 scripts/classify_memory.py --related 查询 [--top N] |
| 构建知识图谱 | python3 scripts/memory_graph.py build |
| 图谱关系 | python3 scripts/memory_graph.py related 实体 [--depth N] |
| 图谱统计 | python3 scripts/memory_graph.py stats |
| 原始图谱查询 | python3 scripts/memory_graph.py query SELECT ... |
上下文压缩
| 操作 | 脚本 |
|---|
| 提取压缩(标准输入) | python3 scripts/compactsession.py --extract |
| 写入压缩(标准输入) |
python3 scripts/compactsession.py --write |
| 列出压缩 | python3 scripts/compact_session.py --list |
| 读取最新压缩 | python3 scripts/compact_session.py --latest |
| 压缩统计 | python3 scripts/compact_session.py --stats |
WAL 协议(预写日志)
关键规则:先写入,再回复。
当用户提供需要记住的信息时:
- 1. 写入 SESSION-STATE.md(通过 session_state.py)
- 然后回复用户
这可以防止在回复和写入之间发生压缩、崩溃或重启时丢失上下文。
| 用户操作 | WAL 写入 |
|---|
| 陈述偏好 | sessionstate.py context pref 值 |
| 做出决策 |
sessionstate.py decide 选择了 X |
| 给出截止日期 | session_state.py context deadline 日期 |
| 纠正代理 | session_state.py decide 纠正:X 而非 Y |
| 分配任务 | session_state.py task 描述 |
| 提及障碍 | session_state.py blocker 描述 |
记忆类型
所有条目都带有类型前缀标签:
- - [PREF] — 用户偏好、习惯、风格
- [PROJ] — 项目上下文、进行中的工作、目标
- [TECH] — 技术细节、配置、系统知识
- [LESSON] — 经验教训、错误、纠正
- [PEOPLE] — 人员、关系、社交上下文
- [TEMP] — 会话范围,自动过期
核心工作流
会话开始
- 1. 读取 SESSION-STATE.md 获取当前任务/上下文
- 搜索相关上下文:
- python3 scripts/memory
searchbm25.py build(如果索引过期或缺失)
- python3 scripts/memory
searchbm25.py search 当前主题(语义搜索)
- 同时使用 memory_search(OpenClaw 内置工具)作为补充搜索
- 3. 检查最近的压缩:python3 scripts/compact_session.py --latest
- 如果存在输出,读取并将其相关部分用作会话上下文
- 这是手动代理步骤——技能不会自动注入
- 4. 检查 memory/YYYY-MM-DD.md 获取今日活动
对话期间(WAL)
- 1. 用户提供可操作信息 → 首先写入 SESSION-STATE.md
- 重要事实 → 使用类型标签追加到 memory/YYYY-MM-DD.md
- 使用 session_cache.py 处理临时会话数据
会话结束(压缩)
- 1. 使用最终状态更新 SESSION-STATE.md
- 如果对话超过 50 轮或用户说压缩:
- 起草压缩内容(决策、事实、待办、障碍)
- 通过安全检查:echo 内容 | python3 scripts/compact_session