npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

openclaw-amem

v1.0.0

Published

A-MEM agentic memory backend for OpenClaw — TypeScript rewrite

Readme

openclaw-amem

License: MIT npm arXiv CI

A-MEM agentic memory backend for OpenClaw

If you find this useful, star us on GitHub!

The first open-source A-MEM memory plugin for 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.

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.


Key Features ✨

  • 🔄 Dynamic Memory Network — Inspired by Zettelkasten. Memories are stored as nodes in a graph, not just flat vector rows.
  • 🔗 Automatic Link Generation — New memories automatically link bidirectionally to existing related memories via embedding similarity + LLM verification.
  • 🧬 Memory Evolution & Strengthening — Linked memories update context/tags/embeddings when new details arrive. Supports active link strengthening and tag propagation.
  • 🚦 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.
  • 🧹 Same-Day Semantic Merger — Automatically merge semantic duplicates written during the same day (≥ 0.80 cosine similarity).
  • 📅 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.
  • Temporal Invalidation & Soft-Delete — Outdated/conflicting memories are marked is_active: false (soft-deleted) and excluded from searches using zero-migration Qdrant filters.
  • 🔥 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:
Final Score = RRF Score × (1 + 0.05 × ln(1 + retrieval_count) / (age_days + 1))

A note last accessed 60 days ago with 10 retrievals gets boost ≈ 1.002; the same note accessed today gets ≈ 1.060.

  • 🔍 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.
  • 🀄 Chinese-Optimized BM25 — The BM25 pipeline uses 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.
  • 🧠 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.
  • 🏷️ Topic Tags for Knowledge Notesknowledge-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.
  • 🛡️ 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.
  • 📊 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.
  • 🔐 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).
  • 🔔 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.

Why A-MEM? (vs Traditional RAG) 🎯

| Dimension | Traditional RAG | A-MEM (Zettelkasten Graph) | | :--------------------------- | :--------------------------------------------------------- | :------------------------------------------------------------------------------------------------------------------------------ | | Retrieval Mode | Single-vector similarity | BM25 + Dense Vector Hybrid (RRF) + 2-hop Graph Expansion | | Chinese Recall | Character-level n-gram / single char split | Jieba word segmentation for accurate CJK BM25 indexing | | Fact Evolution | Static chunking — cannot update historical entries | Dynamic Attribute Evolution & Connection Strengthening | | Temporal Conflicts | Recalls contradictory facts simultaneously | is_active soft-invalidation shields outdated facts | | Memory Bloat | Fragmented memories stack up infinitely | Daily Consolidation merges semantic duplicates | | Stale Memory Suppression | High-retrieval old memories permanently outrank fresh ones | Time-decayed heat boost — age dampens retrieval_count influence | | Graph Noise | N/A | BFS Relevance Gate filters low-similarity linked nodes | | Knowledge vs. Episodic | All memories treated equally | note_type field separates durable knowledge from episodic events; knowledge notes skip consolidation merge and time-decay | | Topic-Based Recall | Only similarity-based | topics tags + topicsFilter enables precise subject-level knowledge retrieval |


What is A-MEM?

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:

  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.
  2. Link Generation — Retrieves top-6 candidates; LLM judges whether to link bidirectionally (similarity > 0.3).
  3. Memory Evolution & Strengthening — Up to 3 linked memories have their attributes evolved based on the new context, potentially triggering additional links.
  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).
  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.

Academic Paper: A-MEM: Agentic Memory for LLM AgentsarXiv:2502.12110 (NeurIPS 2025)


Architecture

OpenClaw Agent
     │
     ├── memory_search(query)  ──►  openclaw-amem plugin (TypeScript, in-process)
     └── memory_add(text)      ──►       │
                                         ▼
                          ┌──────────────┼──────────────┐
                          ▼              ▼               ▼
                       Qdrant     Transformers.js    LLM (Anthropic)
                    (vector store)  (ONNX embed)   (CRUD decision
                      :6333        384-dim local    + link judgment
                   agent_id ISO   + Jieba BM25     + evolution)

Evolution Mechanism (Story 30)

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:

| Type | Meaning | Action | | ------------ | --------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------- | | 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 | | CONFLICT | Old and new info contradict each other (e.g. "lives in Riverstone" vs "moved to Eastholm") | Both notes kept, both marked conflict: true | | 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 | | NEW | Unrelated information, no real connection | Both notes kept as-is |

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.


Quality Scoring & Auto-Review (Story 31)

A-MEM enforces quality at both write time and periodic scan:

Write-Time Quality Gate

Every memory_add call passes through checkQuality() before any LLM or embedding work:

  • Content < 10 characters → write rejected, error returned
  • Contains temporal signal words (待跑, 等确认, 昨日, 明天完成) → written with ephemeral: true flag

Periodic Quality Scan

The memory_quality_scan tool scans the entire memory store and identifies:

| Reason | Condition | | ------------------- | ------------------------------------------------------------ | | too_short | Content < 10 characters (legacy notes that predate the gate) | | expired_ephemeral | ephemeral=true and written > 7 days ago | | pending_conflict | conflict=true (contradictory evolution detected) |

Flagged notes are patched with low_quality: true in Qdrant.


Agent Isolation (Story 32)

Each OpenClaw agent gets its own private memory namespace. Memories written by main are not visible to dev or other agents by default.

Mode A — Shared Collection (default)

All agents share one Qdrant collection (amem_notes), isolated by agent_id filter at query time:

| Scope | agent_id in Qdrant | readers | Visible to | | ----------------- | -------------------- | ---------- | ---------------------- | | Private (default) | "main" | ["main"] | Only the writing agent | | Shared | "shared" | ["*"] | All agents |

Mode B — Dedicated Collection

Each agent gets a physically isolated Qdrant collection:

"agents": {
  "dev": {
    "agentId": "dev",
    "collection": "amem_notes_dev"
  }
}

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).

Access fields on every note

Every MemoryNote carries three access fields:

{
  owner:   "main",      // the agent that wrote this note
  readers: ["main"],    // ["*"] = all agents; ["main"] = private
  writers: ["main"]     // writers enforcement: Story 33
}

Design rationale

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.

Consolidation runs per-agent scope: dev's consolidation never touches main's private notes or shared notes.


Requirements

  • OpenClaw v2026.4+
  • Node.js 18+ (Node 24/26 fully supported)
  • Qdrant running on :6333
  • Anthropic API key (ANTHROPIC_API_KEY env var) — or set AMEM_LLM_BASE_URL for a compatible proxy

Installation

1. Install the plugin

# From ClawHub (recommended)
openclaw plugins install clawhub:@heichaowo/openclaw-amem

# From npm
openclaw plugins install openclaw-amem

# From git
openclaw plugins install git:github.com/heichaowo/openclaw-amem

# From local checkout
openclaw plugins install --link ./openclaw-amem

2. Configure ~/.openclaw/openclaw.json

Add openclaw-amem to your allowed plugins and hook it into the memory slot:

{
  "plugins": {
    "allow": ["openclaw-amem"],
    "entries": {
      "openclaw-amem": {
        "enabled": true,
        "config": {
          "agentId": "main",
          "topK": 5
        }
      }
    },
    "slots": {
      "memory": "openclaw-amem"
    }
  }
}

⚠️ 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.

3. Restart OpenClaw

openclaw gateway restart

Plugin Configuration Reference

| Key | Type | Default | Description | | ------------------------------- | ----------------------------------------- | -------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | agentId | string | "main" | Agent namespace for memory isolation | | topK | number | 5 | Maximum memories to retrieve during search | | agents | Record<string, {agentId?, collection?}> | {} | Per-agent overrides. Set collection for Mode B physical isolation. | | 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. |


Usage & Tools

Once installed, the plugin exposes the following capabilities:

memory_add

Writes a new memory. Automatically evaluates exact-hash duplicate checks, runs LLM note construction, generates bidirectional links, and evaluates memory evolution.

memory_add((text = 'vendor profile'))

memory_search

Searches long-term memories using fused RRF (BM25 + Cosine similarity) with heat-based ranking and 2-hop BFS graph expansion.

memory_search((query = 'database configuration'), (limit = 5))

memory_list

Returns the total active note count for the current agent namespace.

memory_consolidate

Exposes the memory consolidation tool to manually trigger category-based semantic deduplication and link cascading.

memory_quality_scan

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.

memory_quality_scan() // auto-generates batch file in Obsidian vault
memory_quality_scan((outputPath = '/tmp/review.md')) // custom output path

Development & Test

We maintain a strict code quality pipeline including linting, code formatting, path audits, and Vitest test suites.

npm install
npm run build              # Compile TS files to dist/
npm run lint               # Lint code using ESLint (Flat Config)
npm run format             # Check code formatting via Prettier
npm run test               # Run Vitest unit & integration tests
npm run check              # Run entire validation suite (format + lint + test)

Test coverage spans embedding, storage, memory operations, tokenization, BFS gate, heat decay, quality gate, evolution mechanism, and agent isolation.


References & Prior Work

This plugin implements and extends the following prior work:

| Reference | Role | | ------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------- | | Xu et al., A-MEM: Agentic Memory for LLM Agents, NeurIPS 2025 · arXiv:2502.12110 | Core architecture: note construction, link generation, memory evolution, RRF hybrid retrieval | | Robertson & Zaragoza, The Probabilistic Relevance Framework: BM25 and Beyond, 2009 | BM25 ranking formula (k1=1.5, b=0.75) used in hybrid retrieval | | 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 | | 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 | | Sun et al., Jieba Chinese Text Segmentation · github.com/fxsjy/jieba | Chinese word segmentation for BM25 (via @node-rs/jieba, Rust port) | | 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 | | Chhikara et al., Mem0: Building Production-Ready AI Agents with Scalable Long-Term Memory, ECAI 2025 · arXiv: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 | | Multi-Agent Memory from a Computer Architecture Perspective, arXiv:2603.10062, 2026 | Private/shared/distributed memory hierarchy; access protocol design | | Security of Long-Term Memory in LLM Agents, arXiv:2604.16548, 2026 | Isolation-by-default principle; explicit sharing as exception | | Kerestecioglu et al., Human-Inspired Memory Architecture for LLM Agents, arXiv:2605.08538, Microsoft, 2026 | Sleep-phase consolidation design | | Governing Evolving Memory in LLM Agents: SSGM Framework, arXiv:2603.11768, 2026 | Memory evolution taxonomy (EVOLVE/CONFLICT/EXPAND/NEW) | | Graph-based Agent Memory: Taxonomy, Techniques, and Applications, arXiv:2602.05665, 2026 | Conflict detection in graph memory updates | | Memory in the LLM Era, arXiv:2604.01707, 2026 | Memory operations taxonomy |


Citation

If you use this memory system in your research, please cite the original A-MEM paper:

@inproceedings{xu2025amem,
  title={A-Mem: Agentic Memory for LLM Agents},
  author={Xu, Wujiang and Liang, Zujie and Mei, Kai and Gao, Hang and Tan, Juntao and Zhang, Yongfeng},
  booktitle={Advances in Neural Information Processing Systems (NeurIPS)},
  year={2025}
}

Original research repository: agiresearch/A-MEM


License

MIT