# @vainplex/openclaw-cortex > Conversation intelligence layer for [OpenClaw](https://github.com/openclaw/openclaw) β€” automated thread tracking, decision extraction, boot context generation, and pre-compaction snapshots. [![npm](https://img.shields.io/npm/v/@vainplex/openclaw-cortex)](https://www.npmjs.com/package/@vainplex/openclaw-cortex) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) ## What It Does `openclaw-cortex` listens to OpenClaw message hooks and automatically: - **πŸ“‹ Tracks conversation threads** β€” detects topic shifts, closures, decisions, and blocking items - **🎯 Extracts decisions** β€” recognizes when decisions are made (English + German) and logs them - **πŸš€ Generates boot context** β€” assembles a dense `BOOTSTRAP.md` at session start so the agent has continuity - **πŸ“Έ Pre-compaction snapshots** β€” saves thread state + hot snapshot before memory compaction - **πŸ“– Structured narratives** β€” generates 24h activity summaries from threads + decisions Works **alongside** `memory-core` (OpenClaw's built-in memory) β€” doesn't replace it. ### Regex + LLM Hybrid (v0.2.0) By default, Cortex uses fast regex patterns (zero cost, instant). Optionally, you can plug in **any OpenAI-compatible LLM** for deeper analysis: - **Ollama** (local, free): `mistral:7b`, `qwen2.5:7b`, `llama3.1:8b` - **OpenAI**: `gpt-4o-mini`, `gpt-4o` - **OpenRouter / vLLM / any OpenAI-compatible API** The LLM runs **on top of regex** β€” it enhances, never replaces. If the LLM is down, Cortex falls back silently to regex-only. ## 🎬 Demo Try the interactive demo β€” it simulates a real bilingual dev conversation and shows every Cortex feature in action: ```bash git clone https://github.com/alberthild/openclaw-cortex.git cd openclaw-cortex && npm install npx tsx demo/demo.ts ``` ### What the demo shows A 13-message conversation between a developer (Albert) and an AI assistant (Claudia) covering 3 topics in English and German. Cortex processes every message in real-time: ``` πŸ‘€ Albert: Let's get back to the auth migration. We need to switch from JWT to OAuth2. πŸ€– Claudia: I'll start with the token validation layer. The plan is to keep backward compatibility for 2 weeks. πŸ‘€ Albert: Agreed. We decided to use Auth0 as the provider. πŸ‘€ Albert: Also, jetzt zu dem Performance-Bug. Die API braucht 3 Sekunden fΓΌr simple Queries. πŸ€– Claudia: Ich hab den Profiler laufen lassen. Das Problem ist der N+1 Query im User-Resolver. πŸ‘€ Albert: Mist, das ist nervig. Wir brauchen das bis Freitag gefixt. πŸ€– Claudia: Wir machen Batched DataLoader. πŸ‘€ Albert: Beschlossen. Und wir warten auf den Review von Alexey bevor wir deployen. πŸ€– Claudia: Auth migration is done βœ… All tests green, backward compat verified. πŸ‘€ Albert: Nice! Perfekt gelaufen. πŸš€ πŸ‘€ Albert: Now about the Kubernetes cluster β€” we need to plan the migration from Docker Compose. πŸ€– Claudia: I'll draft an architecture doc. Waiting for the cost estimate from Hetzner first. πŸ‘€ Albert: Guter Fortschritt heute. Lass uns morgen mit dem K8s-Plan weitermachen. ```
🧡 Thread Tracking β€” 3 threads detected, 1 auto-closed ``` Found 3 threads (2 open, 1 closed) β—‹ 🟠 the auth migration Status: closed ← detected "done βœ…" as closure signal Priority: high Mood: neutral ● 🟑 dem Performance-Bug Status: open Priority: medium Mood: neutral ● 🟑 the Kubernetes cluster Status: open Priority: medium Mood: neutral Waiting for: cost estimate from Hetzner ```
🎯 Decision Extraction β€” 4 decisions found across 2 languages ``` 🎯 The plan is to keep backward compatibility for 2 weeks Impact: medium | Who: claudia 🎯 We decided to use Auth0 as the provider Impact: medium | Who: albert 🎯 Wir machen Batched DataLoader Impact: medium | Who: claudia 🎯 Beschlossen. Und wir warten auf den Review von Alexey bevor wir deployen. Impact: high | Who: albert ``` Trigger patterns: `"the plan is"`, `"we decided"`, `"wir machen"`, `"beschlossen"`
πŸ”₯ Mood Detection β€” session mood tracked from patterns ``` Session mood: πŸ”₯ excited (Detected from "Nice!", "Perfekt gelaufen", "πŸš€") ``` Supported moods: `frustrated` 😀 Β· `excited` πŸ”₯ Β· `tense` ⚑ Β· `productive` πŸ”§ Β· `exploratory` πŸ”¬ Β· `neutral` 😐
πŸ“Έ Pre-Compaction Snapshot β€” saves state before memory loss ``` Success: yes Messages snapshotted: 13 Warnings: none Hot Snapshot (memory/reboot/hot-snapshot.md): # Hot Snapshot β€” 2026-02-17 ## Last conversation before compaction **Recent messages:** - [user] Let's get back to the auth migration... - [assistant] I'll start with the token validation layer... - [user] Agreed. We decided to use Auth0 as the provider. - [user] Also, jetzt zu dem Performance-Bug... - ... ```
πŸ“‹ Boot Context (BOOTSTRAP.md) β€” ~786 tokens, ready for next session ```markdown # Context Briefing Generated: 2026-02-17 | Local: 12:30 ## ⚑ State Mode: Afternoon β€” execution mode Last session mood: excited πŸ”₯ ## πŸ“– Narrative (last 24h) **Completed:** - βœ… the auth migration: Topic detected from albert **Open:** - 🟑 dem Performance-Bug: Topic detected from albert - 🟑 the Kubernetes cluster: Topic detected from albert **Decisions:** - 🎯 The plan is to keep backward compatibility for 2 weeks (claudia) - 🎯 We decided to use Auth0 as the provider (albert) - 🎯 Wir machen Batched DataLoader (claudia) - 🎯 Beschlossen. Warten auf Review von Alexey (albert) ``` Total: 3,143 chars Β· ~786 tokens Β· regenerated every session start
πŸ“ Generated Files ``` {workspace}/ β”œβ”€β”€ BOOTSTRAP.md 3,143 bytes └── memory/reboot/ β”œβ”€β”€ threads.json 1,354 bytes β”œβ”€β”€ decisions.json 1,619 bytes β”œβ”€β”€ narrative.md 866 bytes └── hot-snapshot.md 1,199 bytes ``` All plain JSON + Markdown. No database, no external dependencies.
> πŸ“ Full raw output: [`demo/SAMPLE-OUTPUT.md`](demo/SAMPLE-OUTPUT.md) ## Install ```bash # From npm npm install @vainplex/openclaw-cortex # Copy to OpenClaw extensions cp -r node_modules/@vainplex/openclaw-cortex ~/.openclaw/extensions/openclaw-cortex ``` Or clone directly: ```bash cd ~/.openclaw/extensions git clone https://github.com/alberthild/openclaw-cortex.git cd openclaw-cortex && npm install && npm run build ``` ## Configure Add to your OpenClaw config: ```json { "plugins": { "openclaw-cortex": { "enabled": true, "patterns": { "language": "both" }, "threadTracker": { "enabled": true, "pruneDays": 7, "maxThreads": 50 }, "decisionTracker": { "enabled": true, "maxDecisions": 100, "dedupeWindowHours": 24 }, "bootContext": { "enabled": true, "maxChars": 16000, "onSessionStart": true, "maxThreadsInBoot": 7, "maxDecisionsInBoot": 10, "decisionRecencyDays": 14 }, "preCompaction": { "enabled": true, "maxSnapshotMessages": 15 }, "narrative": { "enabled": true } } } } ``` ### LLM Enhancement (optional) Add an `llm` section to enable AI-powered analysis on top of regex: ```json { "plugins": { "openclaw-cortex": { "enabled": true, "llm": { "enabled": true, "endpoint": "http://localhost:11434/v1", "model": "mistral:7b", "apiKey": "", "timeoutMs": 15000, "batchSize": 3 } } } } ``` | Setting | Default | Description | |---------|---------|-------------| | `enabled` | `false` | Enable LLM enhancement | | `endpoint` | `http://localhost:11434/v1` | Any OpenAI-compatible API endpoint | | `model` | `mistral:7b` | Model identifier | | `apiKey` | `""` | API key (optional, for cloud providers) | | `timeoutMs` | `15000` | Timeout per LLM call | | `batchSize` | `3` | Messages to buffer before calling the LLM | **Examples:** ```jsonc // Ollama (local, free) { "endpoint": "http://localhost:11434/v1", "model": "mistral:7b" } // OpenAI { "endpoint": "https://api.openai.com/v1", "model": "gpt-4o-mini", "apiKey": "sk-..." } // OpenRouter { "endpoint": "https://openrouter.ai/api/v1", "model": "meta-llama/llama-3.1-8b-instruct", "apiKey": "sk-or-..." } ``` The LLM receives batches of messages and returns structured JSON: detected threads, decisions, closures, and mood. Results are merged with regex findings β€” the LLM can catch things regex misses (nuance, implicit decisions, context-dependent closures). Restart OpenClaw after configuring. ## How It Works ### Hooks | Hook | Feature | Priority | |---|---|---| | `message_received` | Thread + Decision Tracking | 100 | | `message_sent` | Thread + Decision Tracking | 100 | | `session_start` | Boot Context Generation | 10 | | `before_compaction` | Pre-Compaction Snapshot | 5 | | `after_compaction` | Logging | 200 | ### Output Files ``` {workspace}/ β”œβ”€β”€ BOOTSTRAP.md # Dense boot context (regenerated each session) └── memory/ └── reboot/ β”œβ”€β”€ threads.json # Thread state β”œβ”€β”€ decisions.json # Decision log β”œβ”€β”€ narrative.md # 24h activity summary └── hot-snapshot.md # Pre-compaction snapshot ``` ### Pattern Languages Thread and decision detection supports English, German, or both: - **Decision patterns**: "we decided", "let's do", "the plan is", "wir machen", "beschlossen" - **Closure patterns**: "is done", "it works", "fixed βœ…", "erledigt", "gefixt" - **Wait patterns**: "waiting for", "blocked by", "warte auf" - **Topic patterns**: "back to", "now about", "jetzt zu", "bzgl." - **Mood detection**: frustrated, excited, tense, productive, exploratory ### LLM Enhancement Flow When `llm.enabled: true`: ``` message_received β†’ regex analysis (instant, always) β†’ buffer message β†’ batch full? β†’ LLM call (async, fire-and-forget) β†’ merge LLM results into threads + decisions β†’ LLM down? β†’ silent fallback to regex-only ``` The LLM sees a conversation snippet (configurable batch size) and returns: - **Threads**: title, status (open/closed), summary - **Decisions**: what was decided, who, impact level - **Closures**: which threads were resolved - **Mood**: overall conversation mood ### Graceful Degradation - Read-only workspace β†’ runs in-memory, skips writes - Corrupt JSON β†’ starts fresh, next write recovers - Missing directories β†’ creates them automatically - Hook errors β†’ caught and logged, never crashes the gateway - LLM timeout/error β†’ falls back to regex-only, no data loss ## Development ```bash npm install npm test # 288 tests npm run typecheck # TypeScript strict mode npm run build # Compile to dist/ ``` ## Performance - Zero runtime dependencies (Node built-ins only β€” even LLM calls use `node:http`) - Regex analysis: instant, runs on every message - LLM enhancement: async, batched, fire-and-forget (never blocks hooks) - Atomic file writes via `.tmp` + rename - Noise filter prevents garbage threads from polluting state - Tested with 288 unit + integration tests ## Architecture See [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md) for the full design document including module diagrams, data flows, type definitions, and testing strategy. ## License MIT β€” see [LICENSE](LICENSE) ## Part of the Vainplex Plugin Suite | # | Plugin | Status | Description | |---|--------|--------|-------------| | 1 | [@vainplex/nats-eventstore](https://github.com/alberthild/openclaw-nats-eventstore) | βœ… Published | NATS JetStream event persistence | | 2 | **@vainplex/openclaw-cortex** | βœ… Published | Conversation intelligence β€” threads, decisions, boot context (this plugin) | | 3 | [@vainplex/openclaw-knowledge-engine](https://github.com/alberthild/openclaw-knowledge-engine) | βœ… Published | Real-time knowledge extraction | | 4 | @vainplex/openclaw-governance | πŸ“‹ Planned | Policy enforcement + guardrails | | 5 | @vainplex/openclaw-memory-engine | πŸ“‹ Planned | Unified memory layer | | 6 | @vainplex/openclaw-health-monitor | πŸ“‹ Planned | System health + auto-healing | ## License MIT β€” see [LICENSE](LICENSE)