openclaw-amem 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 +21 -0
- package/README.md +355 -0
- package/dist/index.js +6361 -0
- package/openclaw.plugin.json +63 -0
- package/package.json +81 -0
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,355 @@
|
|
|
1
|
+
# openclaw-amem
|
|
2
|
+
|
|
3
|
+
<p align="center">
|
|
4
|
+
<img src="https://raw.githubusercontent.com/heichaowo/openclaw-amem/main/website/public/logo.webp" width="120" alt="A-MEM Logo" />
|
|
5
|
+
</p>
|
|
6
|
+
|
|
7
|
+
[](LICENSE)
|
|
8
|
+
[](https://www.npmjs.com/package/openclaw-amem)
|
|
9
|
+
[](https://arxiv.org/abs/2502.12110)
|
|
10
|
+
[](https://github.com/heichaowo/openclaw-amem/actions)
|
|
11
|
+
|
|
12
|
+
**A-MEM agentic memory backend for [OpenClaw](https://github.com/openclaw/openclaw)**
|
|
13
|
+
|
|
14
|
+
โญ **If you find this useful, [star us on GitHub](https://github.com/heichaowo/openclaw-amem)!**
|
|
15
|
+
|
|
16
|
+
The first open-source A-MEM memory plugin for [OpenClaw](https://github.com/openclaw/openclaw) โ memories **evolve**, not just accumulate. Dynamic graph linking, hybrid retrieval, and LLM-driven evolution judgment. Backed by Qdrant + local Transformers.js + LLM. **No Python required.**
|
|
17
|
+
|
|
18
|
+
> **Note:** This project is a production-ready OpenClaw plugin integration of the A-MEM system. For the original research implementation and paper reproduction, see [agiresearch/A-MEM](https://github.com/agiresearch/A-MEM).
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## Key Features โจ
|
|
23
|
+
|
|
24
|
+
- ๐ **Dynamic Memory Network** โ Inspired by Zettelkasten. Memories are stored as nodes in a graph, not just flat vector rows.
|
|
25
|
+
- ๐ **Automatic Link Generation** โ New memories automatically link bidirectionally to existing related memories via embedding similarity + LLM verification.
|
|
26
|
+
- ๐งฌ **Memory Evolution & Strengthening** โ Linked memories update context/tags/embeddings when new details arrive. Supports active link strengthening and tag propagation.
|
|
27
|
+
- ๐ฆ **LLM CRUD Decision Gate** โ Hooked into OpenClaw's `agent_end` dialog termination. Analyses user-assistant dialogue context, running `NEW` / `UPDATE` / `DELETE` / `NONE` decisions to keep memory clean.
|
|
28
|
+
- ๐งน **Same-Day Semantic Merger** โ Automatically merge semantic duplicates written during the same day (โฅ 0.80 cosine similarity).
|
|
29
|
+
- ๐
**In-Process Daily Consolidation** โ Endogenous in-process `setTimeout` scheduler running at 02:30 AM. Groups notes by `category`, merges semantic duplicates (โฅ 0.75) into clean unified knowledge notes, and **cascades all link references** automatically to preserve graph topology.
|
|
30
|
+
- โณ **Temporal Invalidation & Soft-Delete** โ Outdated/conflicting memories are marked `is_active: false` (soft-deleted) and excluded from searches using zero-migration Qdrant filters.
|
|
31
|
+
- ๐ฅ **Retrieval Heat Tracking with Time Decay** โ Incorporates `retrieval_count` and `last_accessed` timestamps in hybrid scoring. Frequently retrieved memories receive a logarithmic heat boost, dampened by elapsed time since last access so stale memories do not permanently outrank fresh ones:
|
|
32
|
+
|
|
33
|
+
```
|
|
34
|
+
Final Score = RRF Score ร (1 + 0.05 ร ln(1 + retrieval_count) / (age_days + 1))
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
A note last accessed 60 days ago with 10 retrievals gets boost โ 1.002; the same note accessed today gets โ 1.060.
|
|
38
|
+
|
|
39
|
+
- ๐ **2-hop Graph Traversal with Relevance Gate** โ After vector retrieval, BFS walks the link graph up to 2 hops from each anchor result. Only nodes passing an embedding relevance gate (cosine similarity โฅ 0.25 against the query) are admitted, preventing noise from distant graph neighborhoods.
|
|
40
|
+
- ๐ **Chinese-Optimized BM25** โ The BM25 pipeline uses [Jieba](https://github.com/fxsjy/jieba) (via `@node-rs/jieba`) for CJK word segmentation instead of character-level splitting, dramatically improving recall for Chinese queries. English and mixed-language text fall back to whitespace tokenization automatically.
|
|
41
|
+
- ๐ง **Knowledge Type Classification** โ Notes are automatically classified as `memory` (episodic, time-sensitive) or `knowledge` (durable reference, timeless) by LLM. Knowledge notes are excluded from Daily Consolidation merging and time-decay heat penalties, ensuring durable facts remain reliably retrievable regardless of age.
|
|
42
|
+
- ๐ท๏ธ **Topic Tags for Knowledge Notes** โ `knowledge`-type notes carry a `topics: string[]` field (1-5 concise subject labels, e.g. `["TypeScript", "Qdrant"]`). The `memory_search` tool accepts a `topicsFilter` parameter (AND semantics, case-insensitive) for precise knowledge retrieval by subject.
|
|
43
|
+
- ๐ก๏ธ **Strict Quality Controls** โ Full Vitest test coverage for embeddings, storage, link-cascading consolidation, tokenization, and BFS gate behavior, integrated into ESLint + Prettier + import boundary CI checks running on GitHub Actions.
|
|
44
|
+
- ๐ **Quality Scoring & Auto-Review** โ Write-time quality gate rejects content under 10 characters and marks temporal/ephemeral content (containing signal words like 'ๅพ
่ท', '็ญ็กฎ่ฎค'). The `memory_quality_scan` tool scans the full memory store, identifies low-quality entries (too short, expired ephemeral >7 days, unresolved conflicts), and generates Obsidian-compatible review batch files for human curation.
|
|
45
|
+
- ๐ **Per-Agent Memory Isolation** โ Each agent operates in its own private memory namespace. Memories written by `main` are invisible to `dev` by default. A `shared` scope lets the writing agent publish memories readable by all agents, with explicit `owner`/`readers`/`writers` access fields on every note. Two modes: Mode A (shared Qdrant collection, filtered by `agent_id`) and Mode B (dedicated collection per agent, full physical isolation).
|
|
46
|
+
- ๐ **Hook Self-Check** โ If the `agent_end` hook has never fired within 10 minutes of startup (likely blocked by OpenClaw's security policy), the plugin logs a warning and appends a visible notice to every `memory_search` result so you know automatic write-back is disabled.
|
|
47
|
+
|
|
48
|
+
---
|
|
49
|
+
|
|
50
|
+
## Why A-MEM? (vs Traditional RAG) ๐ฏ
|
|
51
|
+
|
|
52
|
+
| Dimension | Traditional RAG | A-MEM (Zettelkasten Graph) |
|
|
53
|
+
| :--------------------------- | :--------------------------------------------------------- | :------------------------------------------------------------------------------------------------------------------------------ |
|
|
54
|
+
| **Retrieval Mode** | Single-vector similarity | **BM25 + Dense Vector Hybrid (RRF) + 2-hop Graph Expansion** |
|
|
55
|
+
| **Chinese Recall** | Character-level n-gram / single char split | **Jieba word segmentation for accurate CJK BM25 indexing** |
|
|
56
|
+
| **Fact Evolution** | Static chunking โ cannot update historical entries | **Dynamic Attribute Evolution & Connection Strengthening** |
|
|
57
|
+
| **Temporal Conflicts** | Recalls contradictory facts simultaneously | **`is_active` soft-invalidation** shields outdated facts |
|
|
58
|
+
| **Memory Bloat** | Fragmented memories stack up infinitely | **Daily Consolidation** merges semantic duplicates |
|
|
59
|
+
| **Stale Memory Suppression** | High-retrieval old memories permanently outrank fresh ones | **Time-decayed heat boost** โ age dampens retrieval_count influence |
|
|
60
|
+
| **Graph Noise** | N/A | **BFS Relevance Gate** filters low-similarity linked nodes |
|
|
61
|
+
| **Knowledge vs. Episodic** | All memories treated equally | **`note_type` field** separates durable knowledge from episodic events; knowledge notes skip consolidation merge and time-decay |
|
|
62
|
+
| **Topic-Based Recall** | Only similarity-based | **`topics` tags + `topicsFilter`** enables precise subject-level knowledge retrieval |
|
|
63
|
+
|
|
64
|
+
---
|
|
65
|
+
|
|
66
|
+
## What is A-MEM?
|
|
67
|
+
|
|
68
|
+
A-MEM is an advanced memory architecture for LLM agents inspired by the Zettelkasten method. Unlike traditional flat vector databases, A-MEM maintains memory as a living, self-evolving semantic graph:
|
|
69
|
+
|
|
70
|
+
1. **Note Construction** โ On write, LLM extracts keywords, tags, a context summary, categorizes the note (Technical, Business, Personal, Project, Research, System, General), classifies it as `memory` (episodic) or `knowledge` (durable), and for knowledge notes extracts 1-5 `topics` subject tags.
|
|
71
|
+
2. **Link Generation** โ Retrieves top-6 candidates; LLM judges whether to link bidirectionally (similarity > 0.3).
|
|
72
|
+
3. **Memory Evolution & Strengthening** โ Up to 3 linked memories have their attributes evolved based on the new context, potentially triggering additional links.
|
|
73
|
+
4. **Hybrid Retrieval** โ Fuses vector search (Transformers.js ONNX local `paraphrase-multilingual-MiniLM-L12-v2`, 384-dim) and BM25 using Reciprocal Rank Fusion (RRF), boosted by retrieval frequency (heat).
|
|
74
|
+
5. **2-hop BFS Graph Expansion** โ After RRF top-K selection, BFS traverses the link graph up to 2 hops, appending up to 8 contextually linked notes that may be semantically distant but graph-connected. Each candidate passes an embedding relevance gate (cos-sim โฅ 0.25) before admission. This is the key architectural advantage over flat vector memory systems like mem0.
|
|
75
|
+
|
|
76
|
+
Academic Paper: _A-MEM: Agentic Memory for LLM Agents_ โ [arXiv:2502.12110](https://arxiv.org/abs/2502.12110) (NeurIPS 2025)
|
|
77
|
+
|
|
78
|
+
---
|
|
79
|
+
|
|
80
|
+
## Architecture
|
|
81
|
+
|
|
82
|
+
```
|
|
83
|
+
OpenClaw Agent
|
|
84
|
+
โ
|
|
85
|
+
โโโ memory_search(query) โโโบ openclaw-amem plugin (TypeScript, in-process)
|
|
86
|
+
โโโ memory_add(text) โโโบ โ
|
|
87
|
+
โผ
|
|
88
|
+
โโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโ
|
|
89
|
+
โผ โผ โผ
|
|
90
|
+
Qdrant Transformers.js LLM (Anthropic)
|
|
91
|
+
(vector store) (ONNX embed) (CRUD decision
|
|
92
|
+
:6333 384-dim local + link judgment
|
|
93
|
+
agent_id ISO + Jieba BM25 + evolution)
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
---
|
|
97
|
+
|
|
98
|
+
## Evolution Mechanism (Story 30)
|
|
99
|
+
|
|
100
|
+
When new memories are borderline-similar to existing ones (cosine similarity 0.72โ0.85), A-MEM marks them `pending_merge` and routes them through an **LLM-driven evolution judgment** instead of simple deduplication. The LLM classifies the relationship between the old and new memory into one of four paths:
|
|
101
|
+
|
|
102
|
+
| Type | Meaning | Action |
|
|
103
|
+
| ------------ | --------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------- |
|
|
104
|
+
| **EVOLVE** | New info deepens/updates the old memory (e.g. "wants to buy Model 3" โ "decided on standard RWD Model 3") | Old note content updated, `evolution_history` appended, new note absorbed |
|
|
105
|
+
| **CONFLICT** | Old and new info contradict each other (e.g. "lives in Riverstone" vs "moved to Eastholm") | Both notes kept, both marked `conflict: true` |
|
|
106
|
+
| **EXPAND** | New info complements the old memory (e.g. "has a sister" + "sister works in finance in Northvale") | Content merged into old note, `evolution_history` appended, new note absorbed |
|
|
107
|
+
| **NEW** | Unrelated information, no real connection | Both notes kept as-is |
|
|
108
|
+
|
|
109
|
+
This is the key differentiator from mem0-style flat memory systems: memories **evolve** rather than being silently overwritten. The `evolution_history` field provides a full audit trail of how each memory changed over time.
|
|
110
|
+
|
|
111
|
+
---
|
|
112
|
+
|
|
113
|
+
## Quality Scoring & Auto-Review (Story 31)
|
|
114
|
+
|
|
115
|
+
A-MEM enforces quality at both **write time** and **periodic scan**:
|
|
116
|
+
|
|
117
|
+
### Write-Time Quality Gate
|
|
118
|
+
|
|
119
|
+
Every `memory_add` call passes through `checkQuality()` before any LLM or embedding work:
|
|
120
|
+
|
|
121
|
+
- **Content < 10 characters** โ write rejected, error returned
|
|
122
|
+
- **Contains temporal signal words** (`ๅพ
่ท`, `็ญ็กฎ่ฎค`, `ๆจๆฅ`, `ๆๅคฉๅฎๆ`) โ written with `ephemeral: true` flag
|
|
123
|
+
|
|
124
|
+
### Periodic Quality Scan
|
|
125
|
+
|
|
126
|
+
The `memory_quality_scan` tool scans the entire memory store and identifies:
|
|
127
|
+
|
|
128
|
+
| Reason | Condition |
|
|
129
|
+
| ------------------- | ------------------------------------------------------------ |
|
|
130
|
+
| `too_short` | Content < 10 characters (legacy notes that predate the gate) |
|
|
131
|
+
| `expired_ephemeral` | `ephemeral=true` and written > 7 days ago |
|
|
132
|
+
| `pending_conflict` | `conflict=true` (contradictory evolution detected) |
|
|
133
|
+
|
|
134
|
+
Flagged notes are patched with `low_quality: true` in Qdrant.
|
|
135
|
+
|
|
136
|
+
---
|
|
137
|
+
|
|
138
|
+
## Agent Isolation (Story 32)
|
|
139
|
+
|
|
140
|
+
Each OpenClaw agent gets its own private memory namespace. Memories written by `main` are not visible to `dev` or other agents by default.
|
|
141
|
+
|
|
142
|
+
### Mode A โ Shared Collection (default)
|
|
143
|
+
|
|
144
|
+
All agents share one Qdrant collection (`amem_notes`), isolated by `agent_id` filter at query time:
|
|
145
|
+
|
|
146
|
+
| Scope | `agent_id` in Qdrant | `readers` | Visible to |
|
|
147
|
+
| ----------------- | -------------------- | ---------- | ---------------------- |
|
|
148
|
+
| Private (default) | `"main"` | `["main"]` | Only the writing agent |
|
|
149
|
+
| Shared | `"shared"` | `["*"]` | All agents |
|
|
150
|
+
|
|
151
|
+
### Mode B โ Dedicated Collection
|
|
152
|
+
|
|
153
|
+
Each agent gets a physically isolated Qdrant collection:
|
|
154
|
+
|
|
155
|
+
```json
|
|
156
|
+
"agents": {
|
|
157
|
+
"dev": {
|
|
158
|
+
"agentId": "dev",
|
|
159
|
+
"collection": "amem_notes_dev"
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
In Mode B, `dev` reads and writes only `amem_notes_dev`. Shared notes written by `main` are not visible to `dev` (no cross-collection sharing).
|
|
165
|
+
|
|
166
|
+
### Access fields on every note
|
|
167
|
+
|
|
168
|
+
Every `MemoryNote` carries three access fields:
|
|
169
|
+
|
|
170
|
+
```ts
|
|
171
|
+
{
|
|
172
|
+
owner: "main", // the agent that wrote this note
|
|
173
|
+
readers: ["main"], // ["*"] = all agents; ["main"] = private
|
|
174
|
+
writers: ["main"] // writers enforcement: Story 33
|
|
175
|
+
}
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
### Design rationale
|
|
179
|
+
|
|
180
|
+
amem uses an **explicit** `agent_id="shared"` marker rather than mem0's implicit null-scoping (omitting `agent_id` to indicate shared access). Per [arXiv:2604.16548], isolation should be the default; sharing is an explicit, auditable exception. amem's approach makes shared notes immediately identifiable in the database.
|
|
181
|
+
|
|
182
|
+
Consolidation runs per-agent scope: `dev`'s consolidation never touches `main`'s private notes or shared notes.
|
|
183
|
+
|
|
184
|
+
---
|
|
185
|
+
|
|
186
|
+
## Requirements
|
|
187
|
+
|
|
188
|
+
- OpenClaw v2026.4+
|
|
189
|
+
- Node.js 18+ (Node 24/26 fully supported)
|
|
190
|
+
- Qdrant running on `:6333`
|
|
191
|
+
- Anthropic API key (`ANTHROPIC_API_KEY` env var) โ or set `AMEM_LLM_BASE_URL` for a compatible proxy
|
|
192
|
+
|
|
193
|
+
---
|
|
194
|
+
|
|
195
|
+
## Installation
|
|
196
|
+
|
|
197
|
+
### 1. Install the plugin
|
|
198
|
+
|
|
199
|
+
```bash
|
|
200
|
+
# From ClawHub (recommended)
|
|
201
|
+
openclaw plugins install clawhub:@heichaowo/openclaw-amem
|
|
202
|
+
|
|
203
|
+
# From npm
|
|
204
|
+
openclaw plugins install openclaw-amem
|
|
205
|
+
|
|
206
|
+
# From git
|
|
207
|
+
openclaw plugins install git:github.com/heichaowo/openclaw-amem
|
|
208
|
+
|
|
209
|
+
# From local checkout
|
|
210
|
+
openclaw plugins install --link ./openclaw-amem
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
### 2. Configure `~/.openclaw/openclaw.json`
|
|
214
|
+
|
|
215
|
+
Add `openclaw-amem` to your allowed plugins and hook it into the `memory` slot:
|
|
216
|
+
|
|
217
|
+
```json
|
|
218
|
+
{
|
|
219
|
+
"plugins": {
|
|
220
|
+
"allow": ["openclaw-amem"],
|
|
221
|
+
"entries": {
|
|
222
|
+
"openclaw-amem": {
|
|
223
|
+
"enabled": true,
|
|
224
|
+
"config": {
|
|
225
|
+
"agentId": "main",
|
|
226
|
+
"topK": 5
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
},
|
|
230
|
+
"slots": {
|
|
231
|
+
"memory": "openclaw-amem"
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
> **โ ๏ธ Memory slot conflict:** If your `openclaw.json` already assigns the `memory` slot to another plugin (e.g. `memory-core`), you **must** change it to `openclaw-amem`. The gateway only loads one plugin per slot โ any additional `memory`-kind plugins are **silently skipped** with no error in the logs. Set `"memory-core": { "enabled": false }` in `entries` to disable the old plugin.
|
|
238
|
+
|
|
239
|
+
### 3. Restart OpenClaw
|
|
240
|
+
|
|
241
|
+
```bash
|
|
242
|
+
openclaw gateway restart
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
---
|
|
246
|
+
|
|
247
|
+
## Plugin Configuration Reference
|
|
248
|
+
|
|
249
|
+
| Key | Type | Default | Description |
|
|
250
|
+
| ------------------------------- | ----------------------------------------- | -------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
251
|
+
| `agentId` | `string` | `"main"` | Agent namespace for memory isolation |
|
|
252
|
+
| `topK` | `number` | `5` | Maximum memories to retrieve during search |
|
|
253
|
+
| `agents` | `Record<string, {agentId?, collection?}>` | `{}` | Per-agent overrides. Set `collection` for Mode B physical isolation. |
|
|
254
|
+
| `hooks.allowConversationAccess` | `boolean` | `false` | **Required** for automatic memory write-back. Must be set explicitly in `plugins.entries.openclaw-amem.hooks`; without it, the `agent_end` hook is silently blocked by OpenClaw's security policy. |
|
|
255
|
+
|
|
256
|
+
---
|
|
257
|
+
|
|
258
|
+
## Usage & Tools
|
|
259
|
+
|
|
260
|
+
Once installed, the plugin exposes the following capabilities:
|
|
261
|
+
|
|
262
|
+
### `memory_add`
|
|
263
|
+
|
|
264
|
+
Writes a new memory. Automatically evaluates exact-hash duplicate checks, runs LLM note construction, generates bidirectional links, and evaluates memory evolution.
|
|
265
|
+
|
|
266
|
+
```js
|
|
267
|
+
memory_add((text = 'vendor profile'))
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
### `memory_search`
|
|
271
|
+
|
|
272
|
+
Searches long-term memories using fused RRF (BM25 + Cosine similarity) with heat-based ranking and 2-hop BFS graph expansion.
|
|
273
|
+
|
|
274
|
+
```js
|
|
275
|
+
memory_search((query = 'database configuration'), (limit = 5))
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
### `memory_list`
|
|
279
|
+
|
|
280
|
+
Returns the total active note count for the current agent namespace.
|
|
281
|
+
|
|
282
|
+
### `memory_consolidate`
|
|
283
|
+
|
|
284
|
+
Exposes the memory consolidation tool to manually trigger category-based semantic deduplication and link cascading.
|
|
285
|
+
|
|
286
|
+
### `memory_quality_scan`
|
|
287
|
+
|
|
288
|
+
Scans all memories for quality issues (content < 10 chars, expired ephemeral notes > 7 days, unresolved conflicts) and generates an Obsidian-compatible review batch markdown file.
|
|
289
|
+
|
|
290
|
+
```js
|
|
291
|
+
memory_quality_scan() // auto-generates batch file in Obsidian vault
|
|
292
|
+
memory_quality_scan((outputPath = '/tmp/review.md')) // custom output path
|
|
293
|
+
```
|
|
294
|
+
|
|
295
|
+
---
|
|
296
|
+
|
|
297
|
+
## Development & Test
|
|
298
|
+
|
|
299
|
+
We maintain a strict code quality pipeline including linting, code formatting, path audits, and Vitest test suites.
|
|
300
|
+
|
|
301
|
+
```bash
|
|
302
|
+
npm install
|
|
303
|
+
npm run build # Compile TS files to dist/
|
|
304
|
+
npm run lint # Lint code using ESLint (Flat Config)
|
|
305
|
+
npm run format # Check code formatting via Prettier
|
|
306
|
+
npm run test # Run Vitest unit & integration tests
|
|
307
|
+
npm run check # Run entire validation suite (format + lint + test)
|
|
308
|
+
```
|
|
309
|
+
|
|
310
|
+
Test coverage spans embedding, storage, memory operations, tokenization, BFS gate, heat decay, quality gate, evolution mechanism, and agent isolation.
|
|
311
|
+
|
|
312
|
+
---
|
|
313
|
+
|
|
314
|
+
## References & Prior Work
|
|
315
|
+
|
|
316
|
+
This plugin implements and extends the following prior work:
|
|
317
|
+
|
|
318
|
+
| Reference | Role |
|
|
319
|
+
| ------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------- |
|
|
320
|
+
| Xu et al., _A-MEM: Agentic Memory for LLM Agents_, NeurIPS 2025 ยท [arXiv:2502.12110](https://arxiv.org/abs/2502.12110) | Core architecture: note construction, link generation, memory evolution, RRF hybrid retrieval |
|
|
321
|
+
| Robertson & Zaragoza, _The Probabilistic Relevance Framework: BM25 and Beyond_, 2009 | BM25 ranking formula (k1=1.5, b=0.75) used in hybrid retrieval |
|
|
322
|
+
| Weller et al., _On the Theoretical Limitations of Embedding-Based Retrieval_, arXiv:2508.21038, 2025 | Motivation for BM25 hybrid: single-vector models cannot scale to combinatorial query complexity |
|
|
323
|
+
| Sun et al., _E5: Text Embeddings by Weakly Supervised Contrastive Pre-training_, arXiv:2212.03533, 2022 | Embedding model family reference for multilingual retrieval quality benchmarks |
|
|
324
|
+
| Sun et al., _Jieba Chinese Text Segmentation_ ยท [github.com/fxsjy/jieba](https://github.com/fxsjy/jieba) | Chinese word segmentation for BM25 (via `@node-rs/jieba`, Rust port) |
|
|
325
|
+
| Cormack et al., _Reciprocal Rank Fusion outperforms Condorcet and individual Rank Learning Methods_, SIGIR 2009 | RRF fusion formula used to merge BM25 and dense vector ranked lists |
|
|
326
|
+
| Chhikara et al., _Mem0: Building Production-Ready AI Agents with Scalable Long-Term Memory_, ECAI 2025 ยท [arXiv:2504.19413](https://arxiv.org/abs/2504.19413) | Multi-dimensional scope isolation (user_id/agent_id/run_id/app_id); amem's explicit shared marker vs mem0's implicit null-scoping |
|
|
327
|
+
| _Multi-Agent Memory from a Computer Architecture Perspective_, arXiv:2603.10062, 2026 | Private/shared/distributed memory hierarchy; access protocol design |
|
|
328
|
+
| _Security of Long-Term Memory in LLM Agents_, arXiv:2604.16548, 2026 | Isolation-by-default principle; explicit sharing as exception |
|
|
329
|
+
| Kerestecioglu et al., _Human-Inspired Memory Architecture for LLM Agents_, arXiv:2605.08538, Microsoft, 2026 | Sleep-phase consolidation design |
|
|
330
|
+
| _Governing Evolving Memory in LLM Agents: SSGM Framework_, arXiv:2603.11768, 2026 | Memory evolution taxonomy (EVOLVE/CONFLICT/EXPAND/NEW) |
|
|
331
|
+
| _Graph-based Agent Memory: Taxonomy, Techniques, and Applications_, arXiv:2602.05665, 2026 | Conflict detection in graph memory updates |
|
|
332
|
+
| _Memory in the LLM Era_, arXiv:2604.01707, 2026 | Memory operations taxonomy |
|
|
333
|
+
|
|
334
|
+
---
|
|
335
|
+
|
|
336
|
+
## Citation
|
|
337
|
+
|
|
338
|
+
If you use this memory system in your research, please cite the original A-MEM paper:
|
|
339
|
+
|
|
340
|
+
```bibtex
|
|
341
|
+
@inproceedings{xu2025amem,
|
|
342
|
+
title={A-Mem: Agentic Memory for LLM Agents},
|
|
343
|
+
author={Xu, Wujiang and Liang, Zujie and Mei, Kai and Gao, Hang and Tan, Juntao and Zhang, Yongfeng},
|
|
344
|
+
booktitle={Advances in Neural Information Processing Systems (NeurIPS)},
|
|
345
|
+
year={2025}
|
|
346
|
+
}
|
|
347
|
+
```
|
|
348
|
+
|
|
349
|
+
Original research repository: [agiresearch/A-MEM](https://github.com/agiresearch/A-MEM)
|
|
350
|
+
|
|
351
|
+
---
|
|
352
|
+
|
|
353
|
+
## License
|
|
354
|
+
|
|
355
|
+
MIT
|