nexo-brain 0.3.6 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,5 +1,13 @@
1
1
  # NEXO Brain — Your AI Gets a Brain
2
2
 
3
+ [![npm v0.5.0](https://img.shields.io/npm/v/nexo-brain?label=npm&color=purple)](https://www.npmjs.com/package/nexo-brain)
4
+ [![F1 0.588 on LoCoMo](https://img.shields.io/badge/LoCoMo_F1-0.588-brightgreen)](https://github.com/wazionapps/nexo/blob/main/benchmarks/locomo/results/)
5
+ [![+55% vs GPT-4](https://img.shields.io/badge/vs_GPT--4-%2B55%25-blue)](https://github.com/snap-research/locomo/issues/33)
6
+ [![GitHub stars](https://img.shields.io/github/stars/wazionapps/nexo?style=social)](https://github.com/wazionapps/nexo/stargazers)
7
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
8
+
9
+ > **v0.5.0** — Highest published score on [LoCoMo benchmark](https://github.com/snap-research/locomo) (ACL 2024). F1 **0.588** — outperforms GPT-4 (0.379) by 55%. Runs on CPU. No GPU required. [Full results](benchmarks/locomo/results/)
10
+
3
11
  **NEXO Brain transforms any MCP-compatible AI agent from a stateless assistant into a cognitive partner that remembers, learns, forgets, adapts, and builds a relationship with you over time.**
4
12
 
5
13
  [Watch the overview on YouTube](https://www.youtube.com/watch?v=-uvhicUhGTY)
@@ -68,7 +76,7 @@ NEXO Brain uses **Ebbinghaus forgetting curves** — memories naturally fade ove
68
76
 
69
77
  ### Semantic Search (Finding by Meaning)
70
78
 
71
- NEXO Brain doesn't search by keywords. It searches by **meaning** using vector embeddings (fastembed, 384 dimensions).
79
+ NEXO Brain doesn't search by keywords. It searches by **meaning** using vector embeddings (fastembed, 768 dimensions).
72
80
 
73
81
  Example: If you search for "deploy problems", NEXO Brain will find a memory about "SSH connection timeout on production server" — even though they share zero words. This is how human associative memory works.
74
82
 
@@ -140,6 +148,9 @@ NEXO Brain v0.3.1 adds 21 cognitive tools on top of the 76 base tools, bringing
140
148
  | Feature | What It Does |
141
149
  |---------|-------------|
142
150
  | **Pin / Snooze / Archive** | Granular lifecycle states for memories. Pin = never decays (critical knowledge). Snooze = temporarily hidden (revisit later). Archive = cold storage (searchable but inactive). |
151
+ | **Intelligent Chunking** | Adaptive chunking that respects sentence and paragraph boundaries. Produces semantically coherent chunks instead of arbitrary token splits, reducing retrieval noise. |
152
+ | **Adaptive Decay** | Decay rate adapts per memory based on access patterns: frequently-accessed memories decay slower, rarely-accessed ones fade faster. Prevents permanent clutter while keeping active knowledge sharp. |
153
+ | **Auto-Migration** | Formal schema migration system (schema_migrations table) tracks all database changes. Safe, reversible schema evolution for production systems — upgrades never lose data. |
143
154
  | **Auto-Merge Duplicates** | Batch cosine deduplication during the 03:00 sleep cycle. Respects sibling discrimination — similar memories about different contexts are kept separate. |
144
155
  | **Memory Dreaming** | Discovers hidden connections between recent memories during the 03:00 sleep cycle. Surfaces non-obvious patterns like "these three bugs all relate to the same root cause." |
145
156
 
@@ -148,6 +159,10 @@ NEXO Brain v0.3.1 adds 21 cognitive tools on top of the 76 base tools, bringing
148
159
  | Feature | What It Does |
149
160
  |---------|-------------|
150
161
  | **HyDE Query Expansion** | Generates hypothetical answer embeddings for richer semantic search. Instead of searching for "deploy error", it imagines what a helpful memory about deploy errors would look like, then searches for that. |
162
+ | **Hybrid Search (FTS5+BM25+RRF)** | Combines dense vector search with BM25 keyword search via Reciprocal Rank Fusion. Outperforms pure semantic search on precise terminology and code identifiers. |
163
+ | **Cross-Encoder Reranking** | After initial vector retrieval, a cross-encoder model rescores candidates for precision. The top-k results are reordered by true semantic relevance before being returned to the agent. |
164
+ | **Multi-Query Decomposition** | Complex questions are automatically split into sub-queries. Each component is retrieved independently, then fused for a higher-quality answer — improves recall on multi-faceted prompts. |
165
+ | **Temporal Indexing** | Memories are indexed by time in addition to semantics. Time-sensitive queries ("what did we decide last Tuesday?") use temporal proximity scoring alongside semantic similarity. |
151
166
  | **Spreading Activation** | Graph-based co-activation network. Memories retrieved together reinforce each other's connections, building an associative web that improves over time. |
152
167
  | **Recall Explanations** | Transparent score breakdown for every retrieval result. Shows exactly why a memory was returned: semantic similarity, recency, access frequency, and co-activation bonuses. |
153
168
 
@@ -157,6 +172,31 @@ NEXO Brain v0.3.1 adds 21 cognitive tools on top of the 76 base tools, bringing
157
172
  |---------|-------------|
158
173
  | **Prospective Memory** | Context-triggered reminders that fire when conversation topics match, not just by date. "Remind me about X when we discuss Y" works naturally. |
159
174
  | **Hook Auto-capture** | Extracts decisions, corrections, and factual statements from conversations automatically. You don't need to explicitly say "remember this" — the system detects what's worth storing. |
175
+ | **Session Summaries** | Automatic end-of-session summarization that distills key decisions, errors, and follow-ups into a compact diary entry. The next session starts with full context — not a cold slate. |
176
+
177
+ ## Benchmark: LoCoMo (ACL 2024)
178
+
179
+ NEXO Brain was evaluated on [LoCoMo](https://github.com/snap-research/locomo) (ACL 2024), a long-term conversation memory benchmark with 1,986 questions across 10 multi-session conversations.
180
+
181
+ | System | F1 | Adversarial | Hardware |
182
+ |---|---|---|---|
183
+ | **NEXO Brain v0.5.0** | **0.588** | **93.3%** | **CPU only** |
184
+ | GPT-4 (128K full context) | 0.379 | — | GPU cloud |
185
+ | Gemini Pro 1.0 | 0.313 | — | GPU cloud |
186
+ | LLaMA-3 70B | 0.295 | — | A100 GPU |
187
+ | GPT-3.5 + Contriever RAG | 0.283 | — | GPU |
188
+
189
+ **+55% vs GPT-4. Running entirely on CPU.**
190
+
191
+ **Key findings:**
192
+ - Outperforms GPT-4 (128K full context) by 55% on F1 score
193
+ - 93.3% adversarial rejection rate — reliably says "I don't know" when information isn't available
194
+ - 74.9% recall across 1,986 questions
195
+ - Open-domain F1: 0.637 | Multi-hop F1: 0.333 | Temporal F1: 0.326
196
+ - Runs on CPU with 768-dim embeddings (BAAI/bge-base-en-v1.5) — no GPU required
197
+ - First MCP memory server benchmarked on a peer-reviewed dataset
198
+
199
+ Full results in [`benchmarks/locomo/results/`](benchmarks/locomo/results/).
160
200
 
161
201
  ## Quick Start
162
202
 
@@ -386,9 +426,16 @@ NEXO Brain builds on ideas from several open-source projects. We're grateful for
386
426
  | [claude-mem](https://github.com/nicobailey/claude-mem) | Hook auto-capture (extracting decisions and facts from conversations) |
387
427
  | [ClawMem](https://github.com/nicobailey/ClawMem) | Co-activation reinforcement (memories retrieved together strengthen connections) |
388
428
 
389
- ## Contributing
429
+ ## Support the Project
430
+
431
+ If NEXO Brain is useful to you, consider:
432
+
433
+ - **Star this repo** — it helps others discover the project and motivates continued development
434
+ - **[Sponsor on GitHub](https://github.com/sponsors/wazionapps)** — support ongoing development directly
435
+ - **Share your experience** — tell others how you're using cognitive memory in your AI workflows
436
+ - **Contribute** — see [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines. Issues and PRs welcome
390
437
 
391
- See [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines. Issues and PRs welcome.
438
+ [![Star History Chart](https://api.star-history.com/svg?repos=wazionapps/nexo&type=Date)](https://star-history.com/#wazionapps/nexo&Date)
392
439
 
393
440
  ## License
394
441
 
@@ -396,4 +443,4 @@ MIT -- see [LICENSE](LICENSE)
396
443
 
397
444
  ---
398
445
 
399
- Built by [WAzion](https://www.wazion.com)
446
+ Created by **Francisco Cerdà Puigserver** & **NEXO** (Claude Opus) · Built by [WAzion](https://www.wazion.com)
package/bin/nexo-brain.js CHANGED
@@ -75,6 +75,120 @@ async function main() {
75
75
  process.exit(1);
76
76
  }
77
77
 
78
+ // Auto-migration: detect existing installation
79
+ const versionFile = path.join(NEXO_HOME, "version.json");
80
+ if (fs.existsSync(versionFile)) {
81
+ try {
82
+ const installed = JSON.parse(fs.readFileSync(versionFile, "utf8"));
83
+ const currentPkg = JSON.parse(fs.readFileSync(path.join(__dirname, "..", "package.json"), "utf8"));
84
+ const installedVersion = installed.version || "0.0.0";
85
+ const currentVersion = currentPkg.version;
86
+
87
+ if (installedVersion !== currentVersion) {
88
+ log(`Existing installation detected: v${installedVersion} → v${currentVersion}`);
89
+ log("Running auto-migration...");
90
+
91
+ // Update hooks
92
+ const hooksSrc = path.join(__dirname, "..", "src", "hooks");
93
+ const hooksDest = path.join(NEXO_HOME, "hooks");
94
+ fs.mkdirSync(hooksDest, { recursive: true });
95
+ ["session-start.sh", "capture-session.sh", "session-stop.sh", "pre-compact.sh", "caffeinate-guard.sh"].forEach((h) => {
96
+ const src = path.join(hooksSrc, h);
97
+ const dest = path.join(hooksDest, h);
98
+ if (fs.existsSync(src)) {
99
+ fs.copyFileSync(src, dest);
100
+ fs.chmodSync(dest, "755");
101
+ }
102
+ });
103
+ log(" Hooks updated.");
104
+
105
+ // Update core Python files
106
+ const srcDir = path.join(__dirname, "..", "src");
107
+ ["server.py", "db.py", "plugin_loader.py", "cognitive.py",
108
+ "tools_sessions.py", "tools_coordination.py", "tools_reminders.py",
109
+ "tools_reminders_crud.py", "tools_learnings.py", "tools_credentials.py",
110
+ "tools_task_history.py", "tools_menu.py"].forEach((f) => {
111
+ const src = path.join(srcDir, f);
112
+ if (fs.existsSync(src)) {
113
+ fs.copyFileSync(src, path.join(NEXO_HOME, f));
114
+ }
115
+ });
116
+ log(" Core files updated.");
117
+
118
+ // Update plugins
119
+ const pluginsSrc = path.join(srcDir, "plugins");
120
+ const pluginsDest = path.join(NEXO_HOME, "plugins");
121
+ fs.mkdirSync(pluginsDest, { recursive: true });
122
+ if (fs.existsSync(pluginsSrc)) {
123
+ fs.readdirSync(pluginsSrc).filter(f => f.endsWith(".py")).forEach((f) => {
124
+ fs.copyFileSync(path.join(pluginsSrc, f), path.join(pluginsDest, f));
125
+ });
126
+ }
127
+ log(" Plugins updated.");
128
+
129
+ // Update scripts
130
+ const scriptsSrc = path.join(srcDir, "scripts");
131
+ const scriptsDest = path.join(NEXO_HOME, "scripts");
132
+ fs.mkdirSync(scriptsDest, { recursive: true });
133
+ if (fs.existsSync(scriptsSrc)) {
134
+ fs.readdirSync(scriptsSrc).filter(f => f.endsWith(".py") || f.endsWith(".sh")).forEach((f) => {
135
+ fs.copyFileSync(path.join(scriptsSrc, f), path.join(scriptsDest, f));
136
+ });
137
+ }
138
+ log(" Scripts updated.");
139
+
140
+ // Add PreCompact hook to settings.json if missing
141
+ let settings = {};
142
+ if (fs.existsSync(CLAUDE_SETTINGS)) {
143
+ try { settings = JSON.parse(fs.readFileSync(CLAUDE_SETTINGS, "utf8")); } catch {}
144
+ }
145
+ if (settings.hooks && !settings.hooks.PreCompact) {
146
+ settings.hooks.PreCompact = [];
147
+ }
148
+ if (settings.hooks && settings.hooks.PreCompact) {
149
+ const hookPath = path.join(hooksDest, "pre-compact.sh");
150
+ if (!settings.hooks.PreCompact.some((h) => h.command && h.command.includes("pre-compact.sh"))) {
151
+ settings.hooks.PreCompact.push({
152
+ type: "command",
153
+ command: `bash ${hookPath}`,
154
+ });
155
+ fs.writeFileSync(CLAUDE_SETTINGS, JSON.stringify(settings, null, 2));
156
+ log(" PreCompact hook added to Claude Code settings.");
157
+ }
158
+ }
159
+
160
+ // Update version file
161
+ fs.writeFileSync(versionFile, JSON.stringify({
162
+ version: currentVersion,
163
+ installed_at: installed.installed_at,
164
+ updated_at: new Date().toISOString(),
165
+ migrated_from: installedVersion,
166
+ }, null, 2));
167
+
168
+ // Save updated CLAUDE.md template as reference (don't overwrite user's)
169
+ const templateSrc = path.join(__dirname, "..", "templates", "CLAUDE.md.template");
170
+ if (fs.existsSync(templateSrc)) {
171
+ const operatorName = installed.operator_name || "NEXO";
172
+ let claudeMd = fs.readFileSync(templateSrc, "utf8")
173
+ .replace(/\{\{NAME\}\}/g, operatorName)
174
+ .replace(/\{\{NEXO_HOME\}\}/g, NEXO_HOME);
175
+ fs.writeFileSync(path.join(NEXO_HOME, "CLAUDE.md.updated"), claudeMd);
176
+ log(` Updated CLAUDE.md template saved to ~/.nexo/CLAUDE.md.updated`);
177
+ log(` Review and merge changes into your ~/.claude/CLAUDE.md if desired.`);
178
+ }
179
+
180
+ console.log("");
181
+ log(`Migration complete: v${installedVersion} → v${currentVersion}`);
182
+ log("Your data (memories, learnings, preferences) is untouched.");
183
+ console.log("");
184
+ rl.close();
185
+ return;
186
+ }
187
+ } catch (e) {
188
+ // Version file corrupt — proceed with fresh install
189
+ }
190
+ }
191
+
78
192
  // Find or install Homebrew (needed for Python)
79
193
  let hasBrew = run("which brew");
80
194
  if (!hasBrew) {
@@ -249,6 +363,7 @@ async function main() {
249
363
  JSON.stringify({
250
364
  version: pkg.version,
251
365
  installed_at: new Date().toISOString(),
366
+ operator_name: operatorName,
252
367
  files_updated: 0,
253
368
  }, null, 2)
254
369
  );
@@ -421,7 +536,7 @@ Operator name: ${operatorName}
421
536
  const hooksSrcDir = path.join(__dirname, "..", "src", "hooks");
422
537
  const hooksDestDir = path.join(NEXO_HOME, "hooks");
423
538
  fs.mkdirSync(hooksDestDir, { recursive: true });
424
- ["session-start.sh", "capture-session.sh", "session-stop.sh"].forEach((h) => {
539
+ ["session-start.sh", "capture-session.sh", "session-stop.sh", "pre-compact.sh"].forEach((h) => {
425
540
  const src = path.join(hooksSrcDir, h);
426
541
  const dest = path.join(hooksDestDir, h);
427
542
  if (fs.existsSync(src)) {
@@ -460,6 +575,16 @@ Operator name: ${operatorName}
460
575
  settings.hooks.Stop.push(stopHook);
461
576
  }
462
577
 
578
+ // PreCompact hook (saves context before conversation compression)
579
+ if (!settings.hooks.PreCompact) settings.hooks.PreCompact = [];
580
+ const preCompactHook = {
581
+ type: "command",
582
+ command: `bash ${path.join(hooksDestDir, "pre-compact.sh")}`,
583
+ };
584
+ if (!settings.hooks.PreCompact.some((h) => h.command && h.command.includes("pre-compact.sh"))) {
585
+ settings.hooks.PreCompact.push(preCompactHook);
586
+ }
587
+
463
588
  const settingsDir = path.dirname(CLAUDE_SETTINGS);
464
589
  fs.mkdirSync(settingsDir, { recursive: true });
465
590
  fs.writeFileSync(CLAUDE_SETTINGS, JSON.stringify(settings, null, 2));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nexo-brain",
3
- "version": "0.3.6",
3
+ "version": "0.6.0",
4
4
  "mcpName": "io.github.wazionapps/nexo",
5
5
  "description": "NEXO — Cognitive co-operator for Claude Code. Atkinson-Shiffrin memory, semantic RAG, trust scoring, and metacognitive error prevention.",
6
6
  "bin": {
@@ -17,7 +17,7 @@
17
17
  "openclaw",
18
18
  "openclaw-plugin"
19
19
  ],
20
- "author": "WAzion Apps <hello@wazion.com>",
20
+ "author": "NEXO Brain <info@nexo-brain.com>",
21
21
  "license": "MIT",
22
22
  "repository": {
23
23
  "type": "git",