@wrongstack/vector-memory 1.0.11 → 1.0.13

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.
Files changed (2) hide show
  1. package/dist/index.js +50 -30
  2. package/package.json +4 -4
package/dist/index.js CHANGED
@@ -42,10 +42,22 @@ function subscribeVectorMemoryToSage(opts) {
42
42
  return null;
43
43
  }
44
44
  };
45
+ const chains = /* @__PURE__ */ new Map();
46
+ const serialized = (memoryId, work) => {
47
+ const previous = chains.get(memoryId) ?? Promise.resolve();
48
+ const next = previous.then(work, work).finally(() => {
49
+ if (chains.get(memoryId) === next) chains.delete(memoryId);
50
+ });
51
+ chains.set(memoryId, next);
52
+ };
45
53
  const mirror = async (memoryId) => {
46
54
  const memory = await fetch(memoryId);
47
55
  if (!memory) return;
48
56
  if (memory.scope === "session") return;
57
+ if (!isMirroredStatus(memory.status)) {
58
+ await forgetMirror(memoryId);
59
+ return;
60
+ }
49
61
  try {
50
62
  const existing = store.findBySageId(memoryId);
51
63
  if (existing) await store.forget(existing.id);
@@ -79,34 +91,43 @@ function subscribeVectorMemoryToSage(opts) {
79
91
  const offAccepted = events.onPattern("memory.accepted", (_event, payload) => {
80
92
  const memoryId = payload?.memoryId;
81
93
  if (typeof memoryId !== "string") return;
82
- void mirror(memoryId);
94
+ serialized(memoryId, () => mirror(memoryId));
83
95
  });
84
96
  const offRecovered = events.onPattern("memory.recovered", (_event, payload) => {
85
97
  const memoryId = payload?.memoryId;
86
98
  if (typeof memoryId !== "string") return;
87
- void mirror(memoryId);
99
+ serialized(memoryId, () => mirror(memoryId));
100
+ });
101
+ const offMerged = events.onPattern("memory.merged", (_event, payload) => {
102
+ const memoryId = payload?.memoryId;
103
+ if (typeof memoryId !== "string") return;
104
+ serialized(memoryId, () => mirror(memoryId));
88
105
  });
89
106
  const offUpdated = events.onPattern("memory.updated", (_event, payload) => {
90
107
  const memoryId = payload?.memoryId;
91
108
  if (typeof memoryId !== "string") return;
92
109
  const status = payload?.status;
93
110
  if (status === "deleted") return;
94
- void mirror(memoryId);
111
+ serialized(memoryId, () => mirror(memoryId));
95
112
  });
96
113
  const offDeleted = events.onPattern("memory.deleted", (_event, payload) => {
97
114
  const memoryId = payload?.memoryId;
98
115
  if (typeof memoryId !== "string") return;
99
- void forgetMirror(memoryId);
116
+ serialized(memoryId, () => forgetMirror(memoryId));
100
117
  });
101
118
  return {
102
119
  dispose: () => {
103
120
  offAccepted();
104
121
  offRecovered();
122
+ offMerged();
105
123
  offUpdated();
106
124
  offDeleted();
107
125
  }
108
126
  };
109
127
  }
128
+ function isMirroredStatus(status) {
129
+ return status === "active" || status === "stale";
130
+ }
110
131
  async function forgetStaleSageMirrors(store, memoryStore, logger, options) {
111
132
  const surface = getSageSurface(memoryStore);
112
133
  if (!surface) return { scanned: 0, removed: 0 };
@@ -125,7 +146,7 @@ async function forgetStaleSageMirrors(store, memoryStore, logger, options) {
125
146
  if (typeof sageId !== "string") continue;
126
147
  try {
127
148
  const memory = await surface.getSage(sageId);
128
- if (memory !== null && memory.status !== "deleted") continue;
149
+ if (memory !== null && isMirroredStatus(memory.status)) continue;
129
150
  await store.forget(entry.id);
130
151
  removed++;
131
152
  } catch (err) {
@@ -268,6 +289,7 @@ import {
268
289
  augmentLexicalWithVectorRecall,
269
290
  isSageVisibleForSearch,
270
291
  SAGE_RETRIEVAL_CAPABILITY,
292
+ SAGE_SERVICE_CAPABILITY,
271
293
  SAGE_SURFACE_CAPABILITY
272
294
  } from "@wrongstack/sage";
273
295
  function asVectorRecallProviderAdapter(store) {
@@ -328,32 +350,27 @@ function wrapMemoryPortWithVectorRecall(port, options) {
328
350
  Object.getPrototypeOf(port),
329
351
  Object.getOwnPropertyDescriptors(port)
330
352
  );
353
+ const wrapSearchCapability = (original) => ({
354
+ ...original,
355
+ searchSage: wrapSearchSage(original.searchSage),
356
+ ...original.searchSageWithBreakdown ? {
357
+ searchSageWithBreakdown: wrapSearchWithBreakdown(
358
+ original.searchSageWithBreakdown
359
+ )
360
+ } : {}
361
+ });
362
+ const wrappedCapabilityIds = /* @__PURE__ */ new Set([
363
+ SAGE_RETRIEVAL_CAPABILITY.id,
364
+ SAGE_SURFACE_CAPABILITY.id,
365
+ SAGE_SERVICE_CAPABILITY.id
366
+ ]);
331
367
  wrapped.getCapability = (capability) => {
332
- if (capability.id === SAGE_RETRIEVAL_CAPABILITY.id) {
368
+ if (wrappedCapabilityIds.has(capability.id)) {
333
369
  const original = port.getCapability(capability);
334
- if (!original) return void 0;
335
- return {
336
- ...original,
337
- searchSage: wrapSearchSage(original.searchSage),
338
- ...original.searchSageWithBreakdown ? {
339
- searchSageWithBreakdown: wrapSearchWithBreakdown(
340
- original.searchSageWithBreakdown
341
- )
342
- } : {}
343
- };
344
- }
345
- if (capability.id === SAGE_SURFACE_CAPABILITY.id) {
346
- const original = port.getCapability(capability);
347
- if (!original) return void 0;
348
- return {
349
- ...original,
350
- searchSage: wrapSearchSage(original.searchSage),
351
- ...original.searchSageWithBreakdown ? {
352
- searchSageWithBreakdown: wrapSearchWithBreakdown(
353
- original.searchSageWithBreakdown
354
- )
355
- } : {}
356
- };
370
+ if (!original || typeof original.searchSage !== "function") {
371
+ return original;
372
+ }
373
+ return wrapSearchCapability(original);
357
374
  }
358
375
  return port.getCapability(capability);
359
376
  };
@@ -387,7 +404,10 @@ function createSageSurfaceSyncSource(sage, opts = {}) {
387
404
  }
388
405
  const remaining = requested - memories.length;
389
406
  const page = await sage.listSagePage({
390
- statuses: ["active"],
407
+ // Same corpus the live mirror keeps (`isMirroredStatus`): a stale
408
+ // memory is still recallable for mutation triggers, so a first-boot
409
+ // index without it disagreed with every later event-driven write.
410
+ statuses: ["active", "stale"],
391
411
  limit: Math.min(pageSize, Math.max(1, remaining)),
392
412
  ...cursor ? { cursor } : {}
393
413
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wrongstack/vector-memory",
3
- "version": "1.0.11",
3
+ "version": "1.0.13",
4
4
  "license": "MIT",
5
5
  "description": "WrongStack Vector Memory — an additional vector-search memory store powered by @huggingface/transformers (local ONNX embeddings), alongside the SAGE lexical memory system.",
6
6
  "repository": {
@@ -27,9 +27,9 @@
27
27
  "README.md"
28
28
  ],
29
29
  "dependencies": {
30
- "@wrongstack/core": "1.0.11",
31
- "@wrongstack/persistence": "1.0.11",
32
- "@wrongstack/sage": "1.0.11"
30
+ "@wrongstack/core": "1.0.13",
31
+ "@wrongstack/persistence": "1.0.13",
32
+ "@wrongstack/sage": "1.0.13"
33
33
  },
34
34
  "devDependencies": {
35
35
  "@types/node": "^26.5.1",