Episodic Auto-Capture v0 (tool/alert + conversation fallback)¶
Status: IMPLEMENTED (dev)
Owner: openclaw-mem sidecar plugin + CLI
1) Architecture¶
Auto mode is rollbackable and split into lanes:
- Plugin lane (
extensions/openclaw-mem) - auto-emits episodic spool JSONL for:
tool.calltool.resultops.alert
- Conversation extractor lane (
openclaw-mem episodes extract-sessions) - tails OpenClaw
sessions/*.jsonl - emits:
conversation.userconversation.assistant
- uses per-file offset+inode state (
episodes-extract-state.json) - Ingest lane (
openclaw-mem episodes ingest) - consumes spool with offset state (
episodes-ingest-state.json) - inserts deterministic rows into
episodic_events
2) Safety policy (defaults)¶
- Query/replay are summary-only by default.
- Payload is returned only with explicit
--include-payload. - Secret-like redaction is always on.
- PII-lite redaction (email/phone) is enabled by default.
- Payload policy:
- conversation payload default cap: 4096 bytes
- ingest hard ceiling: 8192 bytes
- If content still looks secret-like after redaction, or clearly looks like a tool dump,
ingest stores
payload_json = NULLandredacted = 1.
3) Scope derivation¶
For conversation extraction:
- parse leading tag in message text:
[SCOPE: x] - if absent, fallback scope =
global
4) Retention defaults¶
episodes gc default policy:
conversation.user: 60dconversation.assistant: 90dtool.call: 30dtool.result: 30dops.alert: 90dops.decision: forever
5) Enablement¶
Plugin config (tool/alert lane)¶
plugins.entries["openclaw-mem"].config.episodes:
{
"enabled": true,
"outputPath": "memory/openclaw-mem-episodes.jsonl",
"scope": "global",
"captureToolCall": true,
"captureToolResult": true,
"captureOpsAlert": true,
"payloadCapBytes": 2048,
"refsCapBytes": 1024,
"maxSummaryLength": 220
}
Conversation extractor lane¶
openclaw-mem episodes extract-sessions \
--sessions-root ~/.openclaw/sessions \
--file ~/.openclaw/memory/openclaw-mem-episodes.jsonl \
--state ~/.openclaw/memory/openclaw-mem/episodes-extract-state.json \
--payload-cap-bytes 4096 \
--json
Ingest lane¶
openclaw-mem episodes ingest \
--file ~/.openclaw/memory/openclaw-mem-episodes.jsonl \
--state ~/.openclaw/memory/openclaw-mem/episodes-ingest-state.json \
--conversation-payload-cap-bytes 4096 \
--json
6) Cron wiring (example)¶
Every 2 minutes, silent on green:
*/2 * * * * cd /opt/openclaw-mem && uv run --python 3.13 -- python -m openclaw_mem episodes extract-sessions --sessions-root ~/.openclaw/sessions --file ~/.openclaw/memory/openclaw-mem-episodes.jsonl --state ~/.openclaw/memory/openclaw-mem/episodes-extract-state.json --json >/dev/null 2>&1
*/2 * * * * cd /opt/openclaw-mem && uv run --python 3.13 -- python -m openclaw_mem episodes ingest --file ~/.openclaw/memory/openclaw-mem-episodes.jsonl --state ~/.openclaw/memory/openclaw-mem/episodes-ingest-state.json --conversation-payload-cap-bytes 4096 --json >/dev/null 2>&1
7) Rollback¶
Immediate rollback:
- set
plugins.entries.openclaw-mem.config.episodes.enabled=false - disable extractor + ingest cron jobs
- restart gateway
Manual episodic mode remains available (append/query/replay/redact/gc).