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

@synapcores/openclaw-memory

v0.4.0

Published

OpenClaw long-term memory plugin backed by SynapCores AIDB engine-side MEMORY_STORE/RECALL/FORGET primitives + SQL filtering, graph relations, AutoML relevance

Readme

@synapcores/openclaw-memory

A long-term memory plugin for OpenClaw that uses SynapCores AIDB as the storage backend. Drop-in alternative to @openclaw/memory-lancedb with the same auto-recall / auto-capture lifecycle, plus four SynapCores-only extensions: SQL-filtered semantic recall, graph-relation walks, AutoML relevance scoring, and a model-training helper.

0.4.0 shipping note: the core memory ops (memory_store / memory_recall / memory_forget) now ride the engine-side MEMORY_STORE / MEMORY_RECALL / MEMORY_FORGET primitives via @synapcores/sdk@^0.5.0's client.memory surface. The plugin's public API (tools, CLI, extensions, types) is unchanged — only the internal storage path moved.

  • Requires SynapCores gateway v1.8.5-ce or newer (the version that ships the MEMORY_* SQL functions).
  • Embedding moved server-side for the hot path. memory_store / memory_recall no longer call OpenAI — the gateway embeds via its configured model. The OpenAI client is still used by the relevance extensions (predictRelevance, trainRelevanceModel) and the autoLinkSimilar graph-node embedding.
  • Migration from 0.3.x: the engine-managed table is _memory_<namespace>, a different storage backend from the v0.3.x vector collection. Existing v0.3.x memories WILL NOT appear after upgrade — re-capture them. See "Upgrading from 0.3.x" below.
  • collection config field becomes the engine namespace. It must now match ^[A-Za-z_][A-Za-z0-9_]*$. The default openclaw_memories continues to work; other custom values with hyphens or other non-identifier characters need updating.
  • recallFiltered WHERE clauses run engine-side against the MEMORY_RECALL(?, ?, ?) result-set. The plugin auto-rewrites the four legacy column shorthands (category, importance, createdAt, text) into the JSON-extract form so most existing call sites keep working unchanged.

Upgrading from 0.3.x

@synapcores/[email protected] is a hard cut: the storage backend changes, so old memories will not migrate automatically. Steps:

  1. Upgrade the SynapCores gateway to v1.8.5-ce or newer.
  2. npm install @synapcores/[email protected].
  3. If your collection config value contains hyphens or other non-identifier characters, rename it to match ^[A-Za-z_][A-Za-z0-9_]*$ before restarting.
  4. (Optional) export any high-value memories from the v0.3.x vector collection (the legacy openclaw_memories collection in your gateway) and re-store them via memory_store so they land in the new _memory_<namespace> table.
  5. (Optional) drop the old vector collection from the gateway once you're sure the export is done.

If your recallFiltered callers use plain column names (category, importance, createdAt, text), they continue to work via auto-rewrite. Callers using the more general SQL surface should switch to the JSON-extract form (metadata->>'…') directly.

Why use this over @openclaw/memory-lancedb?

| Capability | memory-lancedb | memory-synapcores | | --- | --- | --- | | Vector recall + capture | yes | yes | | Auto-recall / auto-capture hooks | yes | yes | | GDPR-style forget by ID or query | yes | yes | | SQL-scoped semantic recall (recallFiltered) | no | yes | | Graph relation walks (recallRelated) | no | yes | | AutoML relevance scoring (predictRelevance) | no | yes | | Backend | local LanceDB files | SynapCores gateway (HTTP) |

If you only need a private, single-user, file-backed vector store, stay on @openclaw/memory-lancedb. If you want any of: cross-session/multi-device shared memory, SQL filtering across metadata, graph relations between memories, or per-user relevance models — install this package.

Install

pnpm add @synapcores/openclaw-memory
# or
npm install @synapcores/openclaw-memory

openclaw (the host) is declared as a peer dependency — install it in your OpenClaw workspace.

Prerequisites

You need a running SynapCores gateway. The Community Edition is free:

# Linux/macOS one-liner installer (see https://synapcores.com/install)
curl -fsSL https://synapcores.com/install.sh | sh
# Then start it:
synapcores start

Create an API key from the SynapCores admin UI (default http://localhost:8095) and copy it into your OpenClaw config below.

Configure

Requires OpenClaw >=2026.4.10. Install the plugin, then add its config and give it the memory slot:

openclaw plugins install @synapcores/openclaw-memory

Add this to your OpenClaw config (run openclaw config file to find the path, typically ~/.openclaw/openclaw.json). Three things matter: the plugins.entries.<id>.config nesting, the plugins.allow entry, and plugins.slots.memory:

{
  "plugins": {
    "allow": ["memory-synapcores"],
    "slots": { "memory": "memory-synapcores" },
    "entries": {
      "memory-synapcores": {
        "enabled": true,
        "config": {
          "embedding": {
            "apiKey": "${OPENAI_API_KEY}",
            "model": "text-embedding-3-small"
          },
          "synapcores": {
            "host": "localhost",
            "port": 8080,
            "apiKey": "${SYNAPCORES_API_KEY}",
            "useHttps": false
          },
          "collection": "openclaw_memories",
          "graph": "openclaw_memory_graph",
          "autoCapture": true,
          "autoRecall": true,
          "autoLinkSimilar": true
        }
      }
    }
  }
}

You must set plugins.slots.memory to "memory-synapcores". Only one plugin can own the memory slot, and the default is OpenClaw's built-in memory-core — without claiming the slot the plugin loads but stays disabled.

Then openclaw config validate. Environment-variable interpolation (${OPENAI_API_KEY}, ${SYNAPCORES_API_KEY}) is supported in any string field so you don't have to commit secrets. (Store keys clean — a trailing newline in apiKey will break auth.)

Config fields

| Field | Required | Default | Notes | | --- | --- | --- | --- | | embedding.apiKey | yes | — | OpenAI API key for the embedding model. | | embedding.model | no | text-embedding-3-small | Either text-embedding-3-small (1536 dims) or text-embedding-3-large (3072 dims). | | synapcores.apiKey | yes | — | SynapCores API key (ak_prod_… or aidb_…). | | synapcores.host | no | localhost | SynapCores gateway hostname. | | synapcores.port | no | 8080 | SynapCores gateway port. | | synapcores.useHttps | no | false | Use TLS to talk to the gateway. | | collection | no | openclaw_memories | SynapCores collection name. | | graph | no | openclaw_memory_graph | SynapCores graph name (used for SIMILAR_TO edges and recallRelated walks). | | autoCapture | no | true | Auto-store memorable utterances after each agent turn. | | autoRecall | no | true | Auto-inject relevant memories before each agent turn. | | autoLinkSimilar | no | true | On capture, insert each Memory as a graph node carrying the embedding so recallRelated returns useful neighborhoods out of the box. Adds ~30-80ms per capture; disable if you never call recallRelated. | | workspace | no | — | Optional workspace suffix on the AutoML relevance model name so multiple installations sharing one gateway can train independent models. |

What you get

Once registered, the plugin:

  1. Exposes three OpenClaw tools to your agents: memory_recall, memory_store, memory_forget.
  2. Adds a CLI sub-command openclaw ltm {list,search,stats}.
  3. Hooks before_agent_start to auto-recall relevant memories (if autoRecall: true).
  4. Hooks agent_end to auto-capture preferences / decisions / entities / facts (if autoCapture: true).
  5. Exposes four SynapCores-only methods at plugin.extensions.* (see "Extensions" below).

API reference

Tools (used by agents at runtime)

| Tool | What it does | | --- | --- | | memory_recall | Vector-search the memory store. Params: { query: string, limit?: number } (default 5). | | memory_store | Persist a new memory. Params: { text, importance?, category? }. De-dupes against >0.95 cosine similarity. | | memory_forget | Delete a memory by memoryId (UUID) or by query (auto-deletes if exactly one candidate at >0.9 similarity, otherwise returns candidates). |

Extensions (programmatic, SynapCores-only)

Reached via plugin.extensions.* after plugin.register(api) runs.

interface MemorySynapCoresExtensions {
  /** Vector recall scoped by a SQL WHERE clause. */
  recallFiltered(opts: {
    where: string;          // e.g. "category = 'preference' AND importance >= 0.7"
    semantic: string;       // natural-language query
    limit?: number;         // default 5
  }): Promise<MemorySearchResult[]>;

  /** Walk SIMILAR_TO / MENTIONS / RELATES_TO edges from a memory. */
  recallRelated(memoryId: string, opts?: {
    hops?: number;          // default 1
    edgeKinds?: string[];   // default: any
  }): Promise<RelatedMemoryResult[]>;

  /** Score candidates with an AutoML model (with heuristic fallback). */
  predictRelevance(query: string, candidates: MemoryEntry[]): Promise<RelevanceScoredMemory[]>;

  /** Train (or retrain) the AutoML relevance model from feedback. */
  trainRelevanceModel(feedback: Array<{
    memoryId: string;
    queryText: string;
    score: number;          // 0..1
  }>): Promise<{ modelId: string; modelName: string }>;
}

recallFiltered — SQL-scoped semantic recall

const results = await plugin.extensions.recallFiltered({
  where: "category = 'preference' AND importance >= 0.7",
  semantic: "what UI style does the user prefer?",
  limit: 5,
});

The where clause is forwarded to the SynapCores gateway as the filter field on /vector_search. SQL validation happens on the gateway — a malformed clause will surface as an SDK error.

recallRelated — graph neighborhood walk

const neighbors = await plugin.extensions.recallRelated(memoryId, {
  hops: 1,
  edgeKinds: ["SIMILAR_TO"],   // default
  similarityThreshold: 0.5,    // default — cosine threshold for synthetic edges
  limit: 20,
});

Returns memories cosine-similar to the source (synthetic SIMILAR_TO edges, single-hop), plus any explicit MENTIONS / RELATES_TO edges the caller has populated (multi-hop supported on non-synthetic edge kinds). Requires autoLinkSimilar: true at capture time — the plugin inserts each Memory as a graph node carrying the embedding so the gateway's vector-indexed synthetic edges resolve at MATCH time.

If a source memory was captured before autoLinkSimilar was enabled, its Memory graph node won't exist and recallRelated will return [] for it. Re-capture (or write a one-off back-fill that posts {labels: ["Memory"], properties: {id, text, embedding, ...}} to /v1/graph/nodes) to retro-fit.

predictRelevance — AutoML re-ranking with heuristic fallback

const top = await plugin.extensions.recallFiltered({ where: "1=1", semantic: query, limit: 20 });
const ranked = await plugin.extensions.predictRelevance(query, top.map((r) => r.entry));
ranked.sort((a, b) => b.relevance - a.relevance);

When a model named openclaw_memory_relevance[_<workspace>] exists, candidates are scored by it. Otherwise the plugin falls back to:

relevance = 0.6 * cosine_similarity(query, memory)
          + 0.25 * exp(-age_days / 14)         # 14-day half-life
          + 0.15 * memory.importance

trainRelevanceModel — promote feedback to a model

const feedback = [
  { memoryId: "...", queryText: "what's my email?", score: 1.0 },
  { memoryId: "...", queryText: "dark mode preference", score: 0.9 },
  // ... at least 10 samples
];
await plugin.extensions.trainRelevanceModel(feedback);
// `predictRelevance` will automatically pick up the new model on the next call.

Requires at least 10 samples; throws otherwise. Train periodically (cron / on-demand) — the next predictRelevance call will detect the model and switch out of heuristic mode.

Under the hood, v0.4.0 stages feedback rows in a SQL table (openclaw_memory_relevance_training[_<workspace>]) on the gateway, then calls /v1/automl/train with target: 'score' and task: 'regression'. The table is preserved across calls so feedback accumulates between sessions; clear it manually with DROP TABLE (via client.executeQuery) if you want a clean restart. Memory hydration is via MEMORY_RECALL(?, ?, ?) WHERE id = ? against the engine's namespace; rows whose memories have been deleted are skipped.

Roadmap (0.5.0+)

  • Entity extraction on capture — parse @mention tokens and known-contact names out of incoming text and create Person / Project graph nodes with MENTIONS edges back to the memory.
  • Tag inference — auto-classify memories into a configurable tag vocabulary on capture (small classifier or LLM call) so recallFiltered queries can use tags out of the box.
  • synapcores-import-lancedb migration script — read an existing ~/.openclaw/memory/lancedb store, re-embed if needed, and bulk-load into a SynapCores collection. Ships as a bin entry on the package.
  • Drop the _getHttpClient graph-node workaround once @synapcores/sdk >0.4.0 fixes client.graph.nodes.create to post {labels: [label]} instead of {label} (the wire shape the gateway's /v1/graph/nodes handler expects).

Upstream

OpenClaw PR adding this plugin to the upstream extension catalogue: TBD — link will be added once the PR opens.

License

MIT. See LICENSE.