@amemhq/core 1.0.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 heichaowo
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,125 @@
1
+ # @amemhq/core
2
+
3
+ Framework-agnostic **A-MEM agentic memory engine** — memories that **evolve**, not just accumulate. Qdrant + local Transformers.js + LLM, **no Python required**.
4
+
5
+ ```bash
6
+ npm i @amemhq/core
7
+ ```
8
+
9
+ Extracted from [`openclaw-amem`](https://github.com/amemhq/amem/tree/main/packages/openclaw-amem) so any host can share one memory engine: an OpenClaw plugin, a standalone service ([`amem-api`](../amem-api)), or a game agent. Part of the [amem monorepo](../../).
10
+
11
+ > Based on _A-MEM: Agentic Memory for LLM Agents_ ([arXiv:2502.12110](https://arxiv.org/abs/2502.12110), NeurIPS 2025). For the original research implementation, see [agiresearch/A-MEM](https://github.com/agiresearch/A-MEM).
12
+
13
+ ## What is A-MEM?
14
+
15
+ Unlike a flat vector store, A-MEM maintains memory as a living, self-evolving semantic graph. On every write:
16
+
17
+ 1. **Note Construction** — an LLM extracts keywords, tags, and a context summary; categorizes the note; and classifies it as `memory` (episodic) or `knowledge` (durable), extracting 1–5 `topics` for knowledge notes.
18
+ 2. **Link Generation** — retrieves top-6 candidates; the LLM judges whether to link bidirectionally (similarity > 0.3).
19
+ 3. **Memory Evolution** — up to 3 linked notes have their attributes evolved from the new context, possibly triggering further links.
20
+ 4. **Hybrid Retrieval** — fuses dense vectors (Transformers.js `paraphrase-multilingual-MiniLM-L12-v2`, 384-dim) and BM25 via Reciprocal Rank Fusion (RRF), boosted by retrieval heat.
21
+ 5. **2-hop BFS Graph Expansion** — after RRF top-K, BFS walks the link graph up to 2 hops, admitting up to 8 graph-connected notes that pass an embedding relevance gate (cos-sim ≥ 0.25). This is the key advantage over flat vector systems.
22
+
23
+ ## Features
24
+
25
+ - 🔄 **Dynamic memory network** (Zettelkasten-inspired) — notes are graph nodes with bidirectional links, not flat rows.
26
+ - 🧬 **Evolution & strengthening** — linked notes update context/tags/embeddings when new details arrive; `evolution_history` audit trail.
27
+ - 🚦 **LLM CRUD gate** — analyzes a user↔assistant exchange and decides `NEW` / `UPDATE` / `DELETE` / `NONE` to keep memory clean.
28
+ - 🧹 **Same-day merge + daily consolidation** — merges semantic duplicates (≥ 0.80 same-day; ≥ 0.75 in the 02:30 sweep) and **cascades link references** to preserve graph topology.
29
+ - ⏳ **Temporal soft-delete** — outdated/conflicting notes are marked `is_active: false` (zero-migration Qdrant filter) and excluded from search.
30
+ - 🔥 **Heat tracking with time decay** — `retrieval_count` + `last_accessed` give a logarithmic boost, dampened by age so stale notes don't permanently outrank fresh ones:
31
+
32
+ ```
33
+ Final Score = RRF Score × (1 + 0.05 × ln(1 + retrieval_count) / (age_days + 1))
34
+ ```
35
+
36
+ - 🔍 **2-hop graph traversal with relevance gate** — BFS from anchors, admitting only nodes with cos-sim ≥ 0.25 to the query.
37
+ - 🀄 **Chinese-optimized BM25** — [Jieba](https://github.com/fxsjy/jieba) (`@node-rs/jieba`) word segmentation for CJK; whitespace fallback for other languages.
38
+ - 🧠 **Knowledge vs episodic** — `note_type` separates durable `knowledge` (skips consolidation-merge + time-decay) from `memory`; `topics` tags + `topicsFilter` enable subject-level recall.
39
+ - 🔐 **Multi-agent isolation** — explicit `owner` / `readers` / `writers` on every note; Mode A (shared collection filtered by `agent_id`) or Mode B (dedicated collection).
40
+ - 📊 **Quality controls** — write-time gate rejects < 10-char content and flags ephemeral notes; `scanLowQuality` finds too-short/expired/conflicting notes.
41
+
42
+ ## Architecture
43
+
44
+ ```
45
+ host (OpenClaw plugin / amem-api / game agent)
46
+ │ addMemory / searchMemory / consolidate ...
47
+
48
+ @amemhq/core (TypeScript)
49
+ ├── LLM (Anthropic) note construction · link judgment · CRUD · evolution
50
+ ├── Transformers.js (ONNX) 384-dim local embeddings + Jieba BM25
51
+ └── Qdrant :6333 vector store · owner/readers/writers · agent_id isolation
52
+ ```
53
+
54
+ ## Memory Evolution
55
+
56
+ When a new note is borderline-similar to an existing one (cosine 0.72–0.85), @amemhq/core routes it through an **LLM evolution judgment** instead of naive dedup, classifying the relationship:
57
+
58
+ | Type | Meaning | Action |
59
+ | --- | --- | --- |
60
+ | **EVOLVE** | New info deepens/updates the old note | Old content updated, `evolution_history` appended, new note absorbed |
61
+ | **CONFLICT** | Old and new contradict | Both kept, both marked `conflict: true` |
62
+ | **EXPAND** | New info complements the old | Content merged into old note, history appended, new note absorbed |
63
+ | **NEW** | Unrelated | Both kept as-is |
64
+
65
+ Memories **evolve** rather than being silently overwritten; `evolution_history` is a full audit trail. (Taxonomy per the SSGM framework, arXiv:2603.11768.)
66
+
67
+ ## Quality Scoring
68
+
69
+ - **Write-time gate** (`checkQuality`) — content < 10 chars is rejected; temporal signal words (`待跑`, `等确认`, `昨日`, `明天完成`) flag the note `ephemeral: true`.
70
+ - **Periodic scan** (`scanLowQuality` / `generateReviewBatch`) — flags `too_short`, `expired_ephemeral` (> 7 days), and `pending_conflict`, patching `low_quality: true` and emitting an Obsidian-compatible review batch.
71
+
72
+ ## Multi-Agent Isolation
73
+
74
+ Every `MemoryNote` carries access fields:
75
+
76
+ ```ts
77
+ { owner: 'main', readers: ['main'], writers: ['main'] } // readers: ['*'] = shared with all agents
78
+ ```
79
+
80
+ - **Mode A** (default) — one shared Qdrant collection, isolated by `agent_id` at query time; `agent_id="shared"` (explicit, auditable) publishes a note to all agents.
81
+ - **Mode B** — a dedicated collection per agent for full physical isolation.
82
+
83
+ Isolation is the default; sharing is an explicit exception (per arXiv:2604.16548). Consolidation runs per-agent scope.
84
+
85
+ ## Usage
86
+
87
+ ```ts
88
+ import { configure, addMemory, searchMemory, createStorageContext } from '@amemhq/core'
89
+
90
+ configure({ dataDir: '~/.myapp' }) // evo counter + consolidation logs (default ~/.amem, or AMEM_DATA_DIR)
91
+
92
+ const storageCtx = createStorageContext(/* collection */ undefined, /* modeBIsolated */ false)
93
+ await addMemory('The player prefers building with oak.', 'game-agent', { storageCtx })
94
+ const hits = await searchMemory('what does the player like to build with?', 5, 'game-agent', { storageCtx })
95
+ ```
96
+
97
+ ## Requirements
98
+
99
+ - Node.js 24 (18+ works)
100
+ - [Qdrant](https://qdrant.tech) on `:6333`
101
+ - An LLM for note/link/evolution calls: `ANTHROPIC_API_KEY` by default, or set `AMEM_LLM_PROVIDER=openai` with `AMEM_LLM_BASE_URL` + `AMEM_LLM_API_KEY` to use any OpenAI-compatible endpoint (OpenAI, DeepSeek, OpenRouter, Ollama, vLLM…)
102
+
103
+ ## References & Citation
104
+
105
+ | Reference | Role |
106
+ | --- | --- |
107
+ | Xu et al., _A-MEM: Agentic Memory for LLM Agents_, NeurIPS 2025 · [arXiv:2502.12110](https://arxiv.org/abs/2502.12110) | Core architecture |
108
+ | Cormack et al., _Reciprocal Rank Fusion…_, SIGIR 2009 | RRF fusion of BM25 + dense |
109
+ | Robertson & Zaragoza, _The Probabilistic Relevance Framework: BM25 and Beyond_, 2009 | BM25 ranking (k1=1.5, b=0.75) |
110
+ | _Governing Evolving Memory in LLM Agents: SSGM_, arXiv:2603.11768, 2026 | Evolution taxonomy (EVOLVE/CONFLICT/EXPAND/NEW) |
111
+ | _Security of Long-Term Memory in LLM Agents_, arXiv:2604.16548, 2026 | Isolation-by-default; explicit sharing |
112
+ | Chhikara et al., _Mem0…_, ECAI 2025 · [arXiv:2504.19413](https://arxiv.org/abs/2504.19413) | Scope isolation; amem's explicit shared marker |
113
+
114
+ ```bibtex
115
+ @inproceedings{xu2025amem,
116
+ title={A-Mem: Agentic Memory for LLM Agents},
117
+ author={Xu, Wujiang and Liang, Zujie and Mei, Kai and Gao, Hang and Tan, Juntao and Zhang, Yongfeng},
118
+ booktitle={Advances in Neural Information Processing Systems (NeurIPS)},
119
+ year={2025}
120
+ }
121
+ ```
122
+
123
+ ## License
124
+
125
+ MIT © heichaowo