@synapcores/openclaw-memory 0.3.0 → 0.4.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,12 +1,26 @@
1
1
  # @synapcores/openclaw-memory
2
2
 
3
- A long-term memory plugin for [OpenClaw](https://github.com/openclaw/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 three SynapCores-only extensions: SQL-filtered semantic recall, graph-relation walks, and AutoML relevance scoring.
3
+ A long-term memory plugin for [OpenClaw](https://github.com/openclaw/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.
4
4
 
5
- > **0.2.0 shipping note:** verified against gateway `v1.6.5.2-ce` and `@synapcores/sdk@^0.4.0`. The full surface parity API (recall/capture/forget) **plus all four SynapCores-only extensions** (`recallFiltered`, `recallRelated`, `predictRelevance`, `trainRelevanceModel`) is wired against the live SDK and exercised end-to-end (7/7 live smoke steps pass against `:28201`).
5
+ > **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.
6
6
  >
7
- > - **`recallRelated`** is now implemented (was signature-only in 0.1.0). On capture, the plugin inserts each Memory as a graph node carrying the embedding under the `embedding` property so the gateway's synthetic `SIMILAR_TO` edge resolves at MATCH time. `autoLinkSimilar: true` (default) enables this; turn it off if you don't need graph-backed recall.
8
- > - **`trainRelevanceModel`** is now implemented (was signature-only in 0.1.0). Feedback rows are staged in a SQL table (`openclaw_memory_relevance_training[_<workspace>]`) the gateway's AutoML can read, then trained as a regression model targeting the `score` column.
9
- > - SDK dep bumped to `@synapcores/sdk@^0.4.0` (which switched API-key auth to `Authorization: Bearer` and added `createVectorCollection` / `vectorCollection(name)`). The three v0.1.0 workarounds auth-header shim, direct `/v1/vectors/collections` POSTs, direct `/v1/vectors/collections/{n}/vectors` POSTsare deleted in favour of the SDK's typed helpers.
7
+ > - **Requires SynapCores gateway `v1.8.5-ce` or newer** (the version that ships the `MEMORY_*` SQL functions).
8
+ > - **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.
9
+ > - **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 upgradere-capture them.** See "Upgrading from 0.3.x" below.
10
+ > - **`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.
11
+ > - **`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.
12
+
13
+ ## Upgrading from 0.3.x
14
+
15
+ `@synapcores/openclaw-memory@0.4.0` is a **hard cut**: the storage backend changes, so old memories will not migrate automatically. Steps:
16
+
17
+ 1. Upgrade the SynapCores gateway to `v1.8.5-ce` or newer.
18
+ 2. `npm install @synapcores/openclaw-memory@0.4.0`.
19
+ 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.
20
+ 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.
21
+ 5. (Optional) drop the old vector collection from the gateway once you're sure the export is done.
22
+
23
+ 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.
10
24
 
11
25
  ## Why use this over `@openclaw/memory-lancedb`?
12
26
 
@@ -225,9 +239,9 @@ await plugin.extensions.trainRelevanceModel(feedback);
225
239
 
226
240
  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.
227
241
 
228
- Under the hood, v0.2.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.
242
+ 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.
229
243
 
230
- ## Roadmap (0.3.0+)
244
+ ## Roadmap (0.5.0+)
231
245
 
232
246
  - **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.
233
247
  - **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.
package/dist/index.d.ts CHANGED
@@ -2,19 +2,29 @@
2
2
  * OpenClaw Memory (SynapCores) Plugin
3
3
  *
4
4
  * Long-term memory with vector search for AI conversations.
5
- * Uses SynapCores AIDB for storage and OpenAI for embeddings.
5
+ * Uses SynapCores AIDB for storage via the engine-side
6
+ * `MEMORY_STORE` / `MEMORY_RECALL` / `MEMORY_FORGET` primitives and
7
+ * OpenAI for the relevance-extension features that still need a
8
+ * client-side embedding (cosine feature in `predictRelevance`,
9
+ * graph-node embedding when `autoLinkSimilar` is on).
10
+ *
6
11
  * Provides seamless auto-recall and auto-capture via lifecycle hooks,
7
- * plus three SynapCores-only extensions (SQL-filtered recall, graph-relation
8
- * walks, and AutoML relevance scoring) — see `recallFiltered`,
9
- * `recallRelated`, and `predictRelevance`.
12
+ * plus four SynapCores-only extensions (SQL-filtered recall, graph-relation
13
+ * walks, AutoML relevance scoring, and a model-training helper) — see
14
+ * `recallFiltered`, `recallRelated`, `predictRelevance`, and
15
+ * `trainRelevanceModel`.
10
16
  *
11
- * This is the @synapcores/openclaw-memory drop-in alternative to
12
- * @openclaw/memory-lancedb. Verified end-to-end against SynapCores
13
- * gateway v1.6.5.2-ce. Requires @synapcores/sdk@^0.4.0 — which added
14
- * `client.vectorCollection(name)` + `client.createVectorCollection(...)`
15
- * and switched API-key auth to `Authorization: Bearer`.
17
+ * v0.4.0 migrates the core memory ops to `@synapcores/sdk@^0.5.0`'s
18
+ * `client.memory` surface. Requires SynapCores gateway v1.8.5-ce+.
16
19
  */
17
20
  import { type MemoryCategory } from "./config.js";
21
+ /**
22
+ * Internal memory record shape used throughout the plugin. The legacy v0.3.x
23
+ * surface guaranteed `vector: number[]` on every entry because storage went
24
+ * through `client.vectorCollection(...)`. v0.4.0's `client.memory.recall`
25
+ * does not return embeddings — `vector` is filled lazily by callers that
26
+ * need it (currently only `predictRelevance` / `trainRelevanceModel`).
27
+ */
18
28
  export type MemoryEntry = {
19
29
  id: string;
20
30
  text: string;
@@ -33,9 +43,21 @@ export type MemorySearchResult = {
33
43
  * importance thresholds, category equality, etc.).
34
44
  */
35
45
  export type RecallFilteredOptions = {
36
- /** SQL fragment applied as the search filter (e.g. `category = 'preference' AND importance >= 0.7`). */
46
+ /**
47
+ * SQL fragment applied as the search filter.
48
+ *
49
+ * v0.4.0 note: the WHERE clause is now evaluated against the columns
50
+ * returned by `MEMORY_RECALL(?, ?, ?)` — `id`, `content`, `similarity`,
51
+ * `metadata`, `created_at`. The legacy v0.3.x `category = 'preference'`
52
+ * shorthand still works for callers that wrote category/importance into
53
+ * the metadata blob (the plugin always does so) BUT the path is now
54
+ * engine-side JSON access: `metadata->>'category' = 'preference'` is the
55
+ * portable form. The plugin auto-rewrites a handful of the legacy
56
+ * shorthands (`category`, `importance`, `createdAt`, `text`) into the
57
+ * JSON-extract form so most existing callers keep working unchanged.
58
+ */
37
59
  where: string;
38
- /** Natural-language query that gets embedded and used as the search vector. */
60
+ /** Natural-language query that gets embedded engine-side and used as the search vector. */
39
61
  semantic: string;
40
62
  /** Maximum results to return (default: 5). */
41
63
  limit?: number;
@@ -96,11 +118,12 @@ export type RelevanceFeedback = {
96
118
  /**
97
119
  * Escape a string literal for safe inlining into a Cypher query.
98
120
  *
99
- * Gateway v1.6.5.2-ce explicitly rejects named-parameter bindings (`$param`)
100
- * with HTTP 400; the supported path is to inline literal values into the
101
- * query string. Memory IDs flow in from `randomUUID()` so they are normally
102
- * safe, BUT we never trust upstream input — every string that ends up
103
- * inside `'...'` in a Cypher fragment must go through this helper.
121
+ * Gateway v1.6.5.2+ rejects named-parameter bindings (`$param`) with HTTP
122
+ * 400; the supported path is to inline literal values into the query
123
+ * string. Memory IDs flow in from `MEMORY_STORE` (engine-generated, e.g.
124
+ * `mem_1kv69sxfn_5ofzwK`) so they are normally safe, BUT we never trust
125
+ * upstream input — every string that ends up inside `'...'` in a Cypher
126
+ * fragment must go through this helper.
104
127
  *
105
128
  * Escapes single quotes (`'` -> `\'`) and backslashes (`\` -> `\\`).
106
129
  * Returns the inner content only; callers are responsible for the
@@ -113,9 +136,8 @@ export declare function escapeCypherString(value: string): string;
113
136
  * them through the OpenClaw plugin registry.
114
137
  *
115
138
  * The four SynapCores-only methods use:
116
- * - `vectorCollection.search({ ..., filter: { sql } })` for `recallFiltered`,
117
- * forwarding the SQL `WHERE` clause to the gateway under
118
- * `filter: { sql: where }`.
139
+ * - `client.executeQuery(...)` against MEMORY_RECALL for `recallFiltered`,
140
+ * wrapping the user's WHERE clause around the engine's recall result-set.
119
141
  * - `client.graph.cypher(...)` for `recallRelated`, walking the synthetic
120
142
  * `SIMILAR_TO` edges that resolve against `Memory.embedding`.
121
143
  * - `client.automl.getModel(...).predict(...)` for `predictRelevance`, with
@@ -130,7 +152,7 @@ export interface MemorySynapCoresExtensions {
130
152
  *
131
153
  * @example
132
154
  * await ext.recallFiltered({
133
- * where: "category = 'preference' AND importance >= 0.7 AND createdAt > 1700000000000",
155
+ * where: "category = 'preference' AND importance >= 0.7",
134
156
  * semantic: "what kind of UI does the user prefer?",
135
157
  * limit: 5,
136
158
  * });
@@ -140,13 +162,13 @@ export interface MemorySynapCoresExtensions {
140
162
  * Graph walk from a memory through `SIMILAR_TO` / `MENTIONS` / `RELATES_TO`
141
163
  * edges, returning the neighborhood.
142
164
  *
143
- * v0.2.0 wires this against the gateway's synthetic-SIMILAR_TO Cypher
144
- * syntax (`[:SIMILAR_TO > T]`) which resolves against the `embedding`
145
- * property the plugin writes onto every captured Memory node. If a
146
- * source memory has not been promoted to a graph node yet (e.g.
147
- * `autoLinkSimilar: false`), this returns an empty array.
165
+ * Wires against the gateway's synthetic-SIMILAR_TO Cypher syntax
166
+ * (`[:SIMILAR_TO > T]`) which resolves against the `embedding` property
167
+ * the plugin writes onto every captured Memory node. If a source memory
168
+ * has not been promoted to a graph node yet (e.g. `autoLinkSimilar:
169
+ * false`), this returns an empty array.
148
170
  *
149
- * @param memoryId - UUID of the source memory.
171
+ * @param memoryId - id of the source memory (engine-assigned, e.g. `mem_...`).
150
172
  * @param options - Hops, edge-kind filter, similarity threshold, limit.
151
173
  */
152
174
  recallRelated(memoryId: string, options?: RecallRelatedOptions): Promise<RelatedMemoryResult[]>;
@@ -171,12 +193,12 @@ export interface MemorySynapCoresExtensions {
171
193
  /**
172
194
  * Train (or retrain) the AutoML model used by `predictRelevance`.
173
195
  *
174
- * v0.2.0 wires this against the staged-collection workflow: feedback
175
- * rows are inserted into a SQL table the gateway's AutoML can read
176
- * via `SELECT * FROM {table}`, then `/v1/automl/train` is invoked with
196
+ * Wires against the staged-collection workflow: feedback rows are
197
+ * inserted into a SQL table the gateway's AutoML can read via
198
+ * `SELECT * FROM {table}`, then `/v1/automl/train` is invoked with
177
199
  * `target: 'score'` to fit a regression model. Existing training data
178
- * in the staging table is preserved across calls so feedback
179
- * accumulates across sessions.
200
+ * in the staging table is preserved across calls so feedback accumulates
201
+ * across sessions.
180
202
  *
181
203
  * @param feedback - Array of `{ memoryId, queryText, score }` samples.
182
204
  * Requires at least {@link MIN_TRAINING_SAMPLES} samples;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAUH,OAAO,EAEL,KAAK,cAAc,EAGpB,MAAM,aAAa,CAAC;AAMrB,MAAM,MAAM,WAAW,GAAG;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,cAAc,CAAC;IACzB,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAC/B,KAAK,EAAE,WAAW,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEF;;;;GAIG;AACH,MAAM,MAAM,qBAAqB,GAAG;IAClC,wGAAwG;IACxG,KAAK,EAAE,MAAM,CAAC;IACd,+EAA+E;IAC/E,QAAQ,EAAE,MAAM,CAAC;IACjB,8CAA8C;IAC9C,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF;;;GAGG;AACH,MAAM,MAAM,oBAAoB,GAAG;IACjC,uFAAuF;IACvF,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;;;;;OAMG;IACH,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB;;;;OAIG;IACH,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,+CAA+C;IAC/C,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF;;;GAGG;AACH,MAAM,MAAM,mBAAmB,GAAG;IAChC,KAAK,EAAE,WAAW,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,EAAE,CAAC;CACf,CAAC;AAEF;;;GAGG;AACH,MAAM,MAAM,qBAAqB,GAAG;IAClC,KAAK,EAAE,WAAW,CAAC;IACnB,2CAA2C;IAC3C,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,iBAAiB,GAAG;IAC9B,qEAAqE;IACrE,QAAQ,EAAE,MAAM,CAAC;IACjB,8CAA8C;IAC9C,SAAS,EAAE,MAAM,CAAC;IAClB,0EAA0E;IAC1E,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAsfF;;;;;;;;;;;;GAYG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAExD;AAuGD;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,WAAW,0BAA0B;IACzC;;;;;;;;;OASG;IACH,cAAc,CAAC,OAAO,EAAE,qBAAqB,GAAG,OAAO,CAAC,kBAAkB,EAAE,CAAC,CAAC;IAE9E;;;;;;;;;;;;OAYG;IACH,aAAa,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,oBAAoB,GAAG,OAAO,CAAC,mBAAmB,EAAE,CAAC,CAAC;IAEhG;;;;;;;;;;;;;;;;OAgBG;IACH,gBAAgB,CACd,KAAK,EAAE,MAAM,EACb,UAAU,EAAE,WAAW,EAAE,GACxB,OAAO,CAAC,qBAAqB,EAAE,CAAC,CAAC;IAEpC;;;;;;;;;;;;;;OAcG;IACH,mBAAmB,CAAC,QAAQ,EAAE,iBAAiB,EAAE,GAAG,OAAO,CAAC;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACrG;AAkwBD,QAAA,MAAM,WAAW;;;;;;yIAAkC,CAAC;AAEpD,eAAe,WAAW,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AASH,OAAO,EAEL,KAAK,cAAc,EAGpB,MAAM,aAAa,CAAC;AAMrB;;;;;;GAMG;AACH,MAAM,MAAM,WAAW,GAAG;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,cAAc,CAAC;IACzB,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAC/B,KAAK,EAAE,WAAW,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEF;;;;GAIG;AACH,MAAM,MAAM,qBAAqB,GAAG;IAClC;;;;;;;;;;;;OAYG;IACH,KAAK,EAAE,MAAM,CAAC;IACd,2FAA2F;IAC3F,QAAQ,EAAE,MAAM,CAAC;IACjB,8CAA8C;IAC9C,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF;;;GAGG;AACH,MAAM,MAAM,oBAAoB,GAAG;IACjC,uFAAuF;IACvF,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;;;;;OAMG;IACH,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB;;;;OAIG;IACH,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,+CAA+C;IAC/C,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF;;;GAGG;AACH,MAAM,MAAM,mBAAmB,GAAG;IAChC,KAAK,EAAE,WAAW,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,EAAE,CAAC;CACf,CAAC;AAEF;;;GAGG;AACH,MAAM,MAAM,qBAAqB,GAAG;IAClC,KAAK,EAAE,WAAW,CAAC;IACnB,2CAA2C;IAC3C,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,iBAAiB,GAAG;IAC9B,qEAAqE;IACrE,QAAQ,EAAE,MAAM,CAAC;IACjB,8CAA8C;IAC9C,SAAS,EAAE,MAAM,CAAC;IAClB,0EAA0E;IAC1E,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAiqBF;;;;;;;;;;;;;GAaG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAExD;AAqGD;;;;;;;;;;;;;;;GAeG;AACH,MAAM,WAAW,0BAA0B;IACzC;;;;;;;;;OASG;IACH,cAAc,CAAC,OAAO,EAAE,qBAAqB,GAAG,OAAO,CAAC,kBAAkB,EAAE,CAAC,CAAC;IAE9E;;;;;;;;;;;;OAYG;IACH,aAAa,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,oBAAoB,GAAG,OAAO,CAAC,mBAAmB,EAAE,CAAC,CAAC;IAEhG;;;;;;;;;;;;;;;;OAgBG;IACH,gBAAgB,CACd,KAAK,EAAE,MAAM,EACb,UAAU,EAAE,WAAW,EAAE,GACxB,OAAO,CAAC,qBAAqB,EAAE,CAAC,CAAC;IAEpC;;;;;;;;;;;;;;OAcG;IACH,mBAAmB,CAAC,QAAQ,EAAE,iBAAiB,EAAE,GAAG,OAAO,CAAC;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACrG;AA4zBD,QAAA,MAAM,WAAW;;;;;;yIAAkC,CAAC;AAEpD,eAAe,WAAW,CAAC"}