@anuma/sdk 6.37.0 → 6.39.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.
@@ -1788,7 +1788,7 @@ function extractUserMessageFromMessages(messages) {
1788
1788
  }
1789
1789
 
1790
1790
  // src/lib/db/chat/operations.ts
1791
- function messageToStoredRaw(message, projection) {
1791
+ function messageToStoredRaw(message, projection2) {
1792
1792
  const convId = String(message._getRaw("conversation_id"));
1793
1793
  const parseJsonField = (rawValue) => {
1794
1794
  if (!rawValue) return void 0;
@@ -1802,7 +1802,7 @@ function messageToStoredRaw(message, projection) {
1802
1802
  }
1803
1803
  return rawValue;
1804
1804
  };
1805
- const skipEmbeddings = projection?.skipEmbeddings === true;
1805
+ const skipEmbeddings = projection2?.skipEmbeddings === true;
1806
1806
  const sourcesRaw = message._getRaw("sources");
1807
1807
  const vectorRaw = skipEmbeddings ? null : message._getRaw("vector");
1808
1808
  const chunksRaw = skipEmbeddings ? null : message._getRaw("chunks");
@@ -1836,8 +1836,8 @@ function messageToStoredRaw(message, projection) {
1836
1836
  origin: message.origin
1837
1837
  };
1838
1838
  }
1839
- async function messageToStored(message, walletAddress, signMessage, embeddedWalletSigner, projection) {
1840
- const baseMessage = messageToStoredRaw(message, projection);
1839
+ async function messageToStored(message, walletAddress, signMessage, embeddedWalletSigner, projection2) {
1840
+ const baseMessage = messageToStoredRaw(message, projection2);
1841
1841
  if (walletAddress) {
1842
1842
  return await decryptMessageFields(
1843
1843
  baseMessage,
@@ -1851,7 +1851,7 @@ async function messageToStored(message, walletAddress, signMessage, embeddedWall
1851
1851
  function rawDate(value) {
1852
1852
  return new Date(typeof value === "number" ? value : 0);
1853
1853
  }
1854
- function messageRawToStoredRaw(raw, projection) {
1854
+ function messageRawToStoredRaw(raw, projection2) {
1855
1855
  const parseJsonField = (rawValue) => {
1856
1856
  if (!rawValue) return void 0;
1857
1857
  if (typeof rawValue === "string") {
@@ -1864,7 +1864,7 @@ function messageRawToStoredRaw(raw, projection) {
1864
1864
  }
1865
1865
  return rawValue;
1866
1866
  };
1867
- const skipEmbeddings = projection?.skipEmbeddings === true;
1867
+ const skipEmbeddings = projection2?.skipEmbeddings === true;
1868
1868
  const vectorRaw = skipEmbeddings ? null : raw.vector;
1869
1869
  const chunksRaw = skipEmbeddings ? null : raw.chunks;
1870
1870
  return {
@@ -1895,8 +1895,8 @@ function messageRawToStoredRaw(raw, projection) {
1895
1895
  origin: raw.origin
1896
1896
  };
1897
1897
  }
1898
- async function messageRawToStored(raw, walletAddress, signMessage, embeddedWalletSigner, projection) {
1899
- const baseMessage = messageRawToStoredRaw(raw, projection);
1898
+ async function messageRawToStored(raw, walletAddress, signMessage, embeddedWalletSigner, projection2) {
1899
+ const baseMessage = messageRawToStoredRaw(raw, projection2);
1900
1900
  if (walletAddress) {
1901
1901
  return await decryptMessageFields(
1902
1902
  baseMessage,
@@ -11413,22 +11413,35 @@ async function vaultMemoryRawToStored(raw, walletAddress, signMessage, embeddedW
11413
11413
  return stored2;
11414
11414
  }
11415
11415
  async function getAllVaultMemoriesOp(ctx, options) {
11416
- const conditions = [
11416
+ const results = await ctx.vaultMemoryCollection.query(...vaultListConditions(ctx, options), ...vaultListOrder(options)).unsafeFetchRaw();
11417
+ return mapInBatches(
11418
+ results,
11419
+ (raw) => vaultMemoryRawToStored(raw, ctx.walletAddress, ctx.signMessage, ctx.embeddedWalletSigner)
11420
+ );
11421
+ }
11422
+ function vaultListConditions(ctx, options) {
11423
+ return [
11417
11424
  ...baseVaultConditions(ctx, options),
11418
11425
  ...options?.scopes?.length ? [Q5.where("scope", Q5.oneOf(options.scopes))] : [],
11419
11426
  ...visibilityConditions(options?.visibility),
11420
11427
  ...levelConditions(options?.levels),
11421
11428
  ...options?.kinds?.length ? [Q5.where("kind", Q5.oneOf(options.kinds))] : [],
11422
11429
  ...options?.folderId !== void 0 ? [Q5.where("folder_id", options.folderId)] : [],
11423
- ...options?.factTypes?.length ? [Q5.where("fact_type", Q5.oneOf(options.factTypes))] : [],
11430
+ ...options?.factTypes?.length ? [Q5.where("fact_type", Q5.oneOf(options.factTypes))] : []
11431
+ ];
11432
+ }
11433
+ function vaultListOrder(options) {
11434
+ return [
11424
11435
  Q5.sortBy(options?.since ? "updated_at" : "created_at", Q5.desc),
11425
11436
  ...options?.limit !== null && options?.limit !== void 0 && options.limit > 0 ? [Q5.take(options.limit)] : []
11426
11437
  ];
11427
- const results = await ctx.vaultMemoryCollection.query(...conditions).unsafeFetchRaw();
11428
- return mapInBatches(
11429
- results,
11430
- (raw) => vaultMemoryRawToStored(raw, ctx.walletAddress, ctx.signMessage, ctx.embeddedWalletSigner)
11431
- );
11438
+ }
11439
+ async function getVaultMemoryProjectionsOp(ctx, options) {
11440
+ const results = await ctx.vaultMemoryCollection.query(...vaultListConditions(ctx, options), ...vaultListOrder(options)).unsafeFetchRaw();
11441
+ return results.map((raw) => ({
11442
+ ...vaultMemoryRawToRankable(raw),
11443
+ topicsUserManaged: raw.topics_user_managed === true || raw.topics_user_managed === 1
11444
+ }));
11432
11445
  }
11433
11446
  function vaultMemoryRawToRankable(raw) {
11434
11447
  return {
@@ -17071,7 +17084,6 @@ async function recall(query, ctx, options = {}) {
17071
17084
  }
17072
17085
  const needsChunkEmbedding = types.includes("chunk") && ctx.storageCtx;
17073
17086
  const wantsTemporal = types.includes("fact") && (ctx.factSource || ctx.vaultCtx);
17074
- const graphRefiner = flags.traverse && options.graphRefine && options.decomposeOptions ? createLlmNeighborRefiner(options.decomposeOptions) : void 0;
17075
17087
  const queryEmbedTotalTimeoutMs = options.queryEmbedTotalTimeoutMs ?? DEFAULT_QUERY_EMBED_TOTAL_TIMEOUT_MS;
17076
17088
  const prepStart = nowMs2();
17077
17089
  let sharedEmbedMs = 0;
@@ -17100,13 +17112,12 @@ async function recall(query, ctx, options = {}) {
17100
17112
  safeLane(
17101
17113
  "graph",
17102
17114
  () => graphLaneFailed = true,
17103
- () => ctx.factSource ? ctx.factSource.graphRanking(query, flags.traverse, options) : buildGraphLaneRanking(query, ctx, flags.traverse, {
17104
- ...options.maxHops !== void 0 && { maxHops: options.maxHops },
17105
- ...options.entityFanout !== void 0 && { entityFanout: options.entityFanout },
17106
- ...options.nodeBudget !== void 0 && { nodeBudget: options.nodeBudget },
17107
- ...options.rrfK !== void 0 && { rrfK: options.rrfK },
17108
- ...graphRefiner && { refineNeighbors: graphRefiner }
17109
- })
17115
+ () => ctx.factSource ? ctx.factSource.graphRanking(query, flags.traverse, options) : buildGraphLaneRanking(
17116
+ query,
17117
+ ctx,
17118
+ flags.traverse,
17119
+ graphTraversalOptions(options, flags.traverse)
17120
+ )
17110
17121
  ),
17111
17122
  wantsTemporal ? safeLane(
17112
17123
  "temporal",
@@ -17325,6 +17336,16 @@ function toFactMemory(r, now) {
17325
17336
  updatedAt: r.updatedAt ?? /* @__PURE__ */ new Date(0)
17326
17337
  };
17327
17338
  }
17339
+ function graphTraversalOptions(options, traverse) {
17340
+ const refineNeighbors = traverse && options.graphRefine && options.decomposeOptions ? createLlmNeighborRefiner(options.decomposeOptions) : void 0;
17341
+ return {
17342
+ ...options.maxHops !== void 0 && { maxHops: options.maxHops },
17343
+ ...options.entityFanout !== void 0 && { entityFanout: options.entityFanout },
17344
+ ...options.nodeBudget !== void 0 && { nodeBudget: options.nodeBudget },
17345
+ ...options.rrfK !== void 0 && { rrfK: options.rrfK },
17346
+ ...refineNeighbors && { refineNeighbors }
17347
+ };
17348
+ }
17328
17349
  async function buildGraphLaneRanking(query, ctx, traverse = false, traversalOptions = {}) {
17329
17350
  const entityCtx = ctx.entityCtx ?? ctx.vaultCtx?.entityCtx;
17330
17351
  if (!entityCtx) return [];
@@ -17490,24 +17511,33 @@ function isDumpQuery(query) {
17490
17511
  return false;
17491
17512
  }
17492
17513
  async function listRecentFacts(ctx, limit, toolOptions) {
17514
+ const store = toolOptions?.memoryStore;
17493
17515
  const vaultCtx = ctx.vaultCtx;
17494
- if (!vaultCtx) return [];
17495
- const ordered = await getVaultRankingProjectionsOp(vaultCtx, {
17516
+ if (!vaultCtx && !store) return [];
17517
+ const read = (ids) => store ? store.list({ memoryIds: ids }) : getVaultMemoriesByIdsOp(vaultCtx, ids);
17518
+ const filters = {
17496
17519
  ...toolOptions?.scopes && { scopes: toolOptions.scopes },
17497
- ...toolOptions?.memoryIds !== void 0 && { memoryIds: toolOptions.memoryIds },
17520
+ ...toolOptions?.memoryIds !== void 0 && { memoryIds: toolOptions.memoryIds }
17521
+ };
17522
+ const project = (size) => store ? store.listProjections({ ...filters, limit: size }) : getVaultRankingProjectionsOp(vaultCtx, {
17523
+ ...filters,
17498
17524
  ...toolOptions?.folderId !== void 0 && { folderId: toolOptions.folderId }
17499
17525
  });
17500
17526
  const readable = [];
17501
- for (let i = 0; i < ordered.length && readable.length < limit; i += limit) {
17502
- const batch = ordered.slice(i, i + limit).map((p) => p.uniqueId);
17503
- const byId = new Map(
17504
- (await getVaultMemoriesByIdsOp(vaultCtx, batch)).map((m) => [m.uniqueId, m])
17505
- );
17506
- for (const id of batch) {
17507
- const m = byId.get(id);
17508
- if (m && !isEncrypted(m.content)) readable.push(m);
17509
- if (readable.length >= limit) break;
17527
+ let start = 0;
17528
+ for (let size = limit; readable.length < limit; size *= 2) {
17529
+ const ordered = await project(size);
17530
+ for (let i = start; i < ordered.length && readable.length < limit; i += limit) {
17531
+ const batch = ordered.slice(i, i + limit).map((p) => p.uniqueId);
17532
+ const byId = new Map((await read(batch)).map((m) => [m.uniqueId, m]));
17533
+ for (const id of batch) {
17534
+ const m = byId.get(id);
17535
+ if (m && !isEncrypted(m.content)) readable.push(m);
17536
+ if (readable.length >= limit) break;
17537
+ }
17510
17538
  }
17539
+ if (!store || ordered.length < size) break;
17540
+ start = ordered.length;
17511
17541
  }
17512
17542
  return readable.map((m) => ({
17513
17543
  id: m.uniqueId,
@@ -17524,6 +17554,8 @@ async function listRecentFacts(ctx, limit, toolOptions) {
17524
17554
  }));
17525
17555
  }
17526
17556
  function createRecallTool(ctx, toolOptions, callbacks) {
17557
+ if (toolOptions?.memoryStore && toolOptions.folderId !== void 0)
17558
+ throw new Error("Folders are not supported with a memoryStore");
17527
17559
  const defaultTypes = toolOptions?.types ?? ["fact", "chunk"];
17528
17560
  const defaultLimit = toolOptions?.limit ?? DEFAULT_LIMIT2;
17529
17561
  const defaultBudget = toolOptions?.budget ?? DEFAULT_BUDGET2;
@@ -17595,7 +17627,7 @@ function createRecallTool(ctx, toolOptions, callbacks) {
17595
17627
  let surfaced = 0;
17596
17628
  try {
17597
17629
  let recallDegraded = [];
17598
- const wantsRecent = args.sort === "recent" && defaultTypes.includes("fact") && ctx.vaultCtx !== void 0;
17630
+ const wantsRecent = args.sort === "recent" && defaultTypes.includes("fact") && (ctx.vaultCtx !== void 0 || toolOptions?.memoryStore !== void 0);
17599
17631
  let result;
17600
17632
  if (wantsRecent) {
17601
17633
  result = { memories: await listRecentFacts(ctx, effectiveLimit, toolOptions) };
@@ -18064,6 +18096,7 @@ function createLocalMemoryStore(options) {
18064
18096
  };
18065
18097
  const vaultCache = options.vaultCache ?? createVaultEmbeddingCache();
18066
18098
  const ownedBy = userId !== void 0 ? [Q8.where("user_id", userId)] : [];
18099
+ const linksOwnedBy = userId === void 0 ? [] : options.allowUnscopedRows ? [Q8.or(Q8.where("user_id", userId), Q8.where("user_id", null))] : [Q8.where("user_id", userId)];
18067
18100
  const watchedColumns = [
18068
18101
  "content",
18069
18102
  "scope",
@@ -18096,6 +18129,7 @@ function createLocalMemoryStore(options) {
18096
18129
  });
18097
18130
  };
18098
18131
  return {
18132
+ masksEmbeddingInput: options.embeddingOptions.maskInput !== void 0,
18099
18133
  list: (listOptions) => getAllVaultMemoriesOp(vaultCtx, listOptions),
18100
18134
  get: (id) => getVaultMemoryOp(vaultCtx, id),
18101
18135
  listArchived: async () => {
@@ -18106,6 +18140,29 @@ function createLocalMemoryStore(options) {
18106
18140
  },
18107
18141
  memoriesByTopics: (names) => getMemoriesByEntityNamesOp(entityCtx, names),
18108
18142
  topicsByMemories: (memoryIds) => getEntitiesByMemoryIdsOp(entityCtx, memoryIds),
18143
+ listTopics: async () => {
18144
+ const links = await entityCtx.memoryEntityCollection.query(...linksOwnedBy).fetch();
18145
+ const members = /* @__PURE__ */ new Map();
18146
+ for (const link of links) {
18147
+ const entityId = String(link.entityId);
18148
+ const set = members.get(entityId) ?? /* @__PURE__ */ new Set();
18149
+ set.add(String(link.memoryId));
18150
+ members.set(entityId, set);
18151
+ }
18152
+ const entities = userId === void 0 ? await entityCtx.entityCollection.query().fetch() : members.size ? await entityCtx.entityCollection.query(Q8.where("id", Q8.oneOf([...members.keys()]))).fetch() : [];
18153
+ const byName = /* @__PURE__ */ new Map();
18154
+ for (const entity of entities) {
18155
+ const count2 = members.get(entity.id)?.size ?? 0;
18156
+ const existing = byName.get(entity.canonicalName);
18157
+ byName.set(entity.canonicalName, {
18158
+ name: entity.canonicalName,
18159
+ kind: existing?.kind ?? entity.kind ?? null,
18160
+ memoryCount: (existing?.memoryCount ?? 0) + count2
18161
+ });
18162
+ }
18163
+ return [...byName.values()].sort((a, b) => a.name.localeCompare(b.name));
18164
+ },
18165
+ listProjections: (listOptions) => getVaultMemoryProjectionsOp(vaultCtx, listOptions),
18109
18166
  create: async (input) => {
18110
18167
  const created = await createVaultMemoryOp(vaultCtx, input);
18111
18168
  if (input.embedding === void 0) embedInBackground(created);
@@ -18154,6 +18211,22 @@ function createLocalMemoryStore(options) {
18154
18211
  { vaultCtx, embeddingOptions: options.embeddingOptions, vaultCache },
18155
18212
  retainOptions
18156
18213
  ),
18214
+ factSource: {
18215
+ search: (query, searchOptions) => searchVaultMemoriesWithSize(
18216
+ query,
18217
+ vaultCtx,
18218
+ options.embeddingOptions,
18219
+ vaultCache,
18220
+ searchOptions
18221
+ ),
18222
+ graphRanking: (query, traverse, recallOptions) => buildGraphLaneRanking(
18223
+ query,
18224
+ { vaultCtx, entityCtx, embeddingOptions: options.embeddingOptions },
18225
+ traverse,
18226
+ graphTraversalOptions(recallOptions, traverse)
18227
+ ),
18228
+ temporalRanking: (query, now) => buildTemporalLaneRanking(query, vaultCtx, now)
18229
+ },
18157
18230
  subscribe: (onChange, subscribeOptions) => {
18158
18231
  const afterFirst = () => {
18159
18232
  let first = true;
@@ -18167,7 +18240,6 @@ function createLocalMemoryStore(options) {
18167
18240
  );
18168
18241
  const subscriptions = [memories.subscribe(afterFirst())];
18169
18242
  if (subscribeOptions?.topics) {
18170
- const linksOwnedBy = userId === void 0 ? [] : options.allowUnscopedRows ? [Q8.or(Q8.where("user_id", userId), Q8.where("user_id", null))] : [Q8.where("user_id", userId)];
18171
18243
  subscriptions.push(
18172
18244
  entityCtx.memoryEntityCollection.query(...linksOwnedBy).observe().subscribe(afterFirst())
18173
18245
  );
@@ -18577,6 +18649,31 @@ async function createRemoteMemoryPersistence(options) {
18577
18649
  throw new Error("Invalid nearby candidate response");
18578
18650
  return result;
18579
18651
  };
18652
+ const fetchQueryPage = async (queryOptions) => {
18653
+ const { signal, ...query } = queryOptions;
18654
+ if (query.limit !== void 0 && (!Number.isInteger(query.limit) || query.limit < 1 || query.limit > 200))
18655
+ throw new Error("Page limit must be 1\u2013200");
18656
+ for (const [key, max] of queryListLimits) {
18657
+ const values = query[key];
18658
+ if (values && values.length > max)
18659
+ throw new Error(`Query ${key} accepts at most ${max} entries (got ${values.length})`);
18660
+ }
18661
+ const page = await request(
18662
+ "/memories/query",
18663
+ {
18664
+ method: "POST",
18665
+ body: JSON.stringify(
18666
+ Object.fromEntries(
18667
+ queryFields.filter((key) => query[key] !== void 0).map((key) => [key, query[key]])
18668
+ )
18669
+ )
18670
+ },
18671
+ signal
18672
+ );
18673
+ if (!record(page) || !Array.isArray(page.items) || page.next_cursor !== void 0 && typeof page.next_cursor !== "string" || page.changes_cursor !== void 0 && typeof page.changes_cursor !== "string")
18674
+ throw new Error("Invalid nearby private-memory page");
18675
+ return page;
18676
+ };
18580
18677
  const candidateSet = async (embedding, candidateOptions = {}) => {
18581
18678
  const result = await fetchCandidates(embedding, candidateOptions, true);
18582
18679
  if (!Number.isSafeInteger(result.total_count) || result.total_count < 0 || !Number.isSafeInteger(result.unavailable_count) || result.unavailable_count < 0)
@@ -18655,34 +18752,27 @@ async function createRemoteMemoryPersistence(options) {
18655
18752
  return Promise.all(result.items.map((item, i) => decodeCommitted(item, prepared[i])));
18656
18753
  },
18657
18754
  query: async (queryOptions = {}) => {
18658
- const { signal, ...query } = queryOptions;
18659
- if (query.limit !== void 0 && (!Number.isInteger(query.limit) || query.limit < 1 || query.limit > 200))
18660
- throw new Error("Page limit must be 1\u2013200");
18661
- for (const [key, max] of queryListLimits) {
18662
- const values = query[key];
18663
- if (values && values.length > max)
18664
- throw new Error(`Query ${key} accepts at most ${max} entries (got ${values.length})`);
18665
- }
18666
- const page = await request(
18667
- "/memories/query",
18668
- {
18669
- method: "POST",
18670
- body: JSON.stringify(
18671
- Object.fromEntries(
18672
- queryFields.filter((key) => query[key] !== void 0).map((key) => [key, query[key]])
18673
- )
18674
- )
18675
- },
18676
- signal
18677
- );
18678
- if (!record(page) || !Array.isArray(page.items) || page.next_cursor !== void 0 && typeof page.next_cursor !== "string" || page.changes_cursor !== void 0 && typeof page.changes_cursor !== "string")
18679
- throw new Error("Invalid nearby private-memory page");
18755
+ const page = await fetchQueryPage(queryOptions);
18680
18756
  return {
18681
18757
  ...await decodeAll(page.items),
18682
18758
  ...page.next_cursor !== void 0 && { next_cursor: page.next_cursor },
18683
18759
  ...page.changes_cursor !== void 0 && { changes_cursor: page.changes_cursor }
18684
18760
  };
18685
18761
  },
18762
+ queryMetadata: async (queryOptions = {}) => {
18763
+ const page = await fetchQueryPage(queryOptions);
18764
+ return {
18765
+ items: page.items.map((item) => {
18766
+ const {
18767
+ memory: { content: _content, kind_value: _kindValue, ...memory },
18768
+ version,
18769
+ server_updated_at
18770
+ } = memoryRecord(item);
18771
+ return { memory, version, server_updated_at };
18772
+ }),
18773
+ ...page.next_cursor !== void 0 && { next_cursor: page.next_cursor }
18774
+ };
18775
+ },
18686
18776
  candidateSet,
18687
18777
  candidates: async (embedding, candidateOptions = {}) => decodeAll((await fetchCandidates(embedding, candidateOptions, false)).items)
18688
18778
  };
@@ -19023,38 +19113,31 @@ function createRemoteMemoryPipeline(options) {
19023
19113
  };
19024
19114
  return { prepare, port };
19025
19115
  };
19026
- return {
19027
- recall: async (query, recallOptions = {}) => {
19116
+ const factSource = {
19117
+ graphRanking: options.graphRanking,
19118
+ temporalRanking: options.temporalRanking,
19119
+ search: async (text13, searchOptions) => {
19028
19120
  const { prepare } = operation("recall");
19029
- return recall(
19030
- query,
19031
- {
19032
- embeddingOptions,
19033
- factSource: {
19034
- graphRanking: options.graphRanking,
19035
- temporalRanking: options.temporalRanking,
19036
- search: async (text13, searchOptions) => {
19037
- const prepared = await prepare(text13, searchOptions);
19038
- const ranked = await rankPreparedVaultCandidates(
19039
- text13,
19040
- prepared,
19041
- embeddingOptions,
19042
- searchOptions
19043
- );
19044
- return {
19045
- ...ranked,
19046
- rankedOnCosine: prepared.memories.length > 0 && !prepared.embeddingsUnavailable,
19047
- decryptLast: true,
19048
- rowsDecrypted: prepared.rowsDecrypted,
19049
- queryEmbedMs: prepared.queryEmbedMs,
19050
- rowsEmbedded: 0
19051
- };
19052
- }
19053
- }
19054
- },
19055
- { ...recallOptions, types: ["fact"] }
19121
+ const prepared = await prepare(text13, searchOptions);
19122
+ const ranked = await rankPreparedVaultCandidates(
19123
+ text13,
19124
+ prepared,
19125
+ embeddingOptions,
19126
+ searchOptions
19056
19127
  );
19057
- },
19128
+ return {
19129
+ ...ranked,
19130
+ rankedOnCosine: prepared.memories.length > 0 && !prepared.embeddingsUnavailable,
19131
+ decryptLast: true,
19132
+ rowsDecrypted: prepared.rowsDecrypted,
19133
+ queryEmbedMs: prepared.queryEmbedMs,
19134
+ rowsEmbedded: 0
19135
+ };
19136
+ }
19137
+ };
19138
+ return {
19139
+ factSource,
19140
+ recall: async (query, recallOptions = {}) => recall(query, { embeddingOptions, factSource }, { ...recallOptions, types: ["fact"] }),
19058
19141
  retain: async (content, retainOptions) => {
19059
19142
  const { port } = operation("retain");
19060
19143
  return retainWithPersistence(
@@ -19073,6 +19156,19 @@ function createRemoteMemoryPipeline(options) {
19073
19156
 
19074
19157
  // src/lib/memory/store/remoteStore.ts
19075
19158
  import { v7 as uuidv75 } from "uuid";
19159
+ function projection({ memory }) {
19160
+ return {
19161
+ uniqueId: memory.memory_id,
19162
+ scope: memory.scope,
19163
+ folderId: memory.folder_id ?? null,
19164
+ embedding: memory.embedding?.length ? JSON.stringify(memory.embedding) : null,
19165
+ embeddingModel: memory.embedding_model ?? null,
19166
+ createdAt: new Date(memory.created_at),
19167
+ updatedAt: new Date(memory.updated_at),
19168
+ lastObservedAt: memory.last_observed_at ?? null,
19169
+ topicsUserManaged: memory.topics_user_managed ?? false
19170
+ };
19171
+ }
19076
19172
  function relevant(change, options) {
19077
19173
  return options.includeDeleted ? change === "membership" : change !== "embedding" || !!options.embeddings;
19078
19174
  }
@@ -19107,6 +19203,9 @@ function bounded(filters, key) {
19107
19203
  if (!values || values.length <= MAX_QUERY_FILTER) return [filters];
19108
19204
  return chunks(values, MAX_QUERY_FILTER).map((chunk) => ({ ...filters, [key]: chunk }));
19109
19205
  }
19206
+ function maxOf(options) {
19207
+ return options.limit && options.limit > 0 ? options.limit : Infinity;
19208
+ }
19110
19209
  function chunks(values, size) {
19111
19210
  const out = [];
19112
19211
  for (let i = 0; i < values.length; i += size) out.push(values.slice(i, i + size));
@@ -19178,26 +19277,49 @@ function createRemoteMemoryStore(options) {
19178
19277
  for (const subscriber of [...subscribers])
19179
19278
  if (relevant(change, subscriber.options)) safely(subscriber.onChange);
19180
19279
  };
19181
- const enumerate = async (filters, max = Infinity) => {
19280
+ const pages = async (read, filters, max = Infinity) => {
19182
19281
  const records = [];
19183
19282
  let cursor2;
19184
19283
  do {
19185
- const page = await persistence.query({
19284
+ const page = await read({
19186
19285
  ...filters,
19187
19286
  limit: Math.min(200, Math.max(1, max - records.length)),
19188
19287
  ...cursor2 && { cursor: cursor2 }
19189
19288
  });
19190
- warnFailed(page.failed);
19289
+ if (page.failed) warnFailed(page.failed);
19191
19290
  records.push(...page.items);
19192
19291
  cursor2 = page.next_cursor;
19193
19292
  } while (cursor2 && records.length < max);
19194
19293
  return records.slice(0, max);
19195
19294
  };
19196
- const enumerateIds = async (ids, filters) => (await Promise.all(
19295
+ const decrypted = (options2) => persistence.query(options2);
19296
+ const metadata = (options2) => persistence.queryMetadata(options2);
19297
+ const enumerate = (filters, max = Infinity) => pages(decrypted, filters, max);
19298
+ const enumerateIds = async (read, ids, filters) => (await Promise.all(
19197
19299
  chunks([...new Set(ids)], MAX_QUERY_IDS).map(
19198
- (memory_ids) => enumerate({ ...filters, memory_ids })
19300
+ (memory_ids) => pages(read, { ...filters, memory_ids })
19199
19301
  )
19200
19302
  )).flat();
19303
+ const listFilters = (listOptions) => ({
19304
+ ...stateFilters(listOptions),
19305
+ include_embeddings: true,
19306
+ order: listOptions.since ? "updated" : "created",
19307
+ ...listOptions.scopes?.length && { scopes: listOptions.scopes },
19308
+ ...listOptions.factTypes?.length && { fact_types: listOptions.factTypes },
19309
+ ...listOptions.visibility?.length && { visibility: listOptions.visibility },
19310
+ ...listOptions.since && { updated_after: listOptions.since.getTime() }
19311
+ });
19312
+ const listRows = async (read, listOptions, filters, max) => {
19313
+ const variants = bounded(filters, "scopes").flatMap((f) => bounded(f, "fact_types"));
19314
+ if (!listOptions.memoryIds && variants.length === 1) return pages(read, filters, max);
19315
+ const fetched = await Promise.all(
19316
+ variants.map(
19317
+ (variant) => listOptions.memoryIds ? enumerateIds(read, listOptions.memoryIds, variant) : pages(read, variant, max)
19318
+ )
19319
+ );
19320
+ const time = (row) => filters.order === "updated" ? row.memory.updated_at : row.memory.created_at;
19321
+ return [...new Map(fetched.flat().map((r) => [r.memory.memory_id, r])).values()].sort((a, b) => time(b) - time(a) || (a.memory.memory_id < b.memory.memory_id ? 1 : -1)).slice(0, max);
19322
+ };
19201
19323
  const queues = /* @__PURE__ */ new Map();
19202
19324
  const serialized = (id, task) => {
19203
19325
  const run = (queues.get(id) ?? Promise.resolve()).then(task, task);
@@ -19239,12 +19361,15 @@ function createRemoteMemoryStore(options) {
19239
19361
  };
19240
19362
  const newRow = (input) => {
19241
19363
  const now = Date.now();
19242
- const scope = input.scope ?? "private";
19364
+ const { level, scope } = resolveCreateLevel(input);
19365
+ assertValidKindLevel(input.kind, level);
19243
19366
  return {
19244
19367
  memory_id: uuidv75(),
19245
19368
  content: input.content,
19246
19369
  scope,
19247
- level: levelFromScope(scope),
19370
+ level,
19371
+ ...input.kind !== void 0 && input.kind !== null && { kind: input.kind },
19372
+ ...typeof input.kindValue === "string" && { kind_value: input.kindValue },
19248
19373
  created_at: now,
19249
19374
  updated_at: now,
19250
19375
  is_deleted: false,
@@ -19273,6 +19398,30 @@ function createRemoteMemoryStore(options) {
19273
19398
  return records.map((record2) => stored(record2.memory));
19274
19399
  };
19275
19400
  const asStored = (record2) => record2 ? stored(record2.memory) : null;
19401
+ const withKnownKinds = async (topics) => {
19402
+ const unkinded = [
19403
+ ...new Set(topics.filter((t) => !t.kind).map((t) => normalizeEntityName(t.name)))
19404
+ ];
19405
+ if (unkinded.length === 0) return topics;
19406
+ const kinds = /* @__PURE__ */ new Map();
19407
+ for (const names of chunks(unkinded, MAX_QUERY_TOPICS)) {
19408
+ for (const { memory } of await pages(metadata, {
19409
+ topics: names,
19410
+ include_archived: true,
19411
+ include_quarantined: true,
19412
+ include_superseded: true
19413
+ })) {
19414
+ for (const topic of parseTopics(memory.topics) ?? []) {
19415
+ const name = normalizeEntityName(topic.name);
19416
+ if (topic.kind && !kinds.has(name)) kinds.set(name, topic.kind);
19417
+ }
19418
+ }
19419
+ }
19420
+ return topics.map((topic) => {
19421
+ const kind = topic.kind ?? kinds.get(normalizeEntityName(topic.name));
19422
+ return kind ? { ...topic, kind } : topic;
19423
+ });
19424
+ };
19276
19425
  const everyState = {
19277
19426
  include_deleted: true,
19278
19427
  include_archived: true,
@@ -19349,30 +19498,35 @@ function createRemoteMemoryStore(options) {
19349
19498
  });
19350
19499
  };
19351
19500
  return {
19352
- list: async (listOptions = {}) => {
19353
- const order = listOptions.since ? "updated" : "created";
19354
- const filters = {
19355
- ...stateFilters(listOptions),
19356
- include_embeddings: true,
19357
- order,
19358
- ...listOptions.scopes?.length && { scopes: listOptions.scopes },
19359
- ...listOptions.factTypes?.length && { fact_types: listOptions.factTypes },
19360
- ...listOptions.visibility?.length && { visibility: listOptions.visibility },
19361
- ...listOptions.since && { updated_after: listOptions.since.getTime() }
19362
- };
19363
- const max = listOptions.limit && listOptions.limit > 0 ? listOptions.limit : Infinity;
19364
- const variants = bounded(filters, "scopes").flatMap((f) => bounded(f, "fact_types"));
19365
- if (!listOptions.memoryIds && variants.length === 1)
19366
- return (await enumerate(filters, max)).map((r) => stored(r.memory));
19367
- const fetched = await Promise.all(
19368
- variants.map(
19369
- (variant) => listOptions.memoryIds ? enumerateIds(listOptions.memoryIds, variant) : enumerate(variant, max)
19370
- )
19371
- );
19372
- const rows = [...new Map(fetched.flat().map((r) => [r.memory.memory_id, r])).values()].map((record2) => stored(record2.memory)).sort(
19373
- (a, b) => order === "updated" ? b.updatedAt.getTime() - a.updatedAt.getTime() || (a.uniqueId < b.uniqueId ? 1 : -1) : b.createdAt.getTime() - a.createdAt.getTime() || (a.uniqueId < b.uniqueId ? 1 : -1)
19374
- );
19375
- return rows.slice(0, max);
19501
+ masksEmbeddingInput: embeddingOptions.maskInput !== void 0,
19502
+ list: async (listOptions = {}) => (await listRows(decrypted, listOptions, listFilters(listOptions), maxOf(listOptions))).map(
19503
+ (r) => stored(r.memory)
19504
+ ),
19505
+ listProjections: async (listOptions = {}) => (await listRows(metadata, listOptions, listFilters(listOptions), maxOf(listOptions))).map(
19506
+ projection
19507
+ ),
19508
+ listTopics: async () => {
19509
+ const topics = /* @__PURE__ */ new Map();
19510
+ for (const { memory } of await pages(metadata, {
19511
+ include_archived: true,
19512
+ include_quarantined: true,
19513
+ include_superseded: true
19514
+ })) {
19515
+ for (const topic of parseTopics(memory.topics) ?? []) {
19516
+ const name = normalizeEntityName(topic.name);
19517
+ if (!name) continue;
19518
+ const entry = topics.get(name) ?? {
19519
+ name,
19520
+ kind: null,
19521
+ memoryCount: 0,
19522
+ members: /* @__PURE__ */ new Set()
19523
+ };
19524
+ entry.kind ?? (entry.kind = topic.kind ?? null);
19525
+ entry.members.add(memory.memory_id);
19526
+ topics.set(name, entry);
19527
+ }
19528
+ }
19529
+ return [...topics.values()].map(({ members, ...topic }) => ({ ...topic, memoryCount: members.size })).sort((a, b) => a.name.localeCompare(b.name));
19376
19530
  },
19377
19531
  get: async (id) => asStored(await live(id)),
19378
19532
  listArchived: async () => (await enumerate({ archived_only: true, order: "archived", include_embeddings: true })).map(
@@ -19381,10 +19535,10 @@ function createRemoteMemoryStore(options) {
19381
19535
  memoriesByTopics: async (names) => {
19382
19536
  const wanted = new Set(names.map(normalizeEntityName).filter(Boolean));
19383
19537
  const out = /* @__PURE__ */ new Map();
19384
- const pages = await Promise.all(
19538
+ const pages2 = await Promise.all(
19385
19539
  chunks([...wanted], MAX_QUERY_TOPICS).map((topics) => enumerate({ topics }))
19386
19540
  );
19387
- for (const { memory } of pages.flat()) {
19541
+ for (const { memory } of pages2.flat()) {
19388
19542
  const matched = [...canonicalTopics(memory)].filter((name) => wanted.has(name));
19389
19543
  if (matched.length) out.set(memory.memory_id, new Set(matched));
19390
19544
  }
@@ -19392,7 +19546,7 @@ function createRemoteMemoryStore(options) {
19392
19546
  },
19393
19547
  topicsByMemories: async (memoryIds) => {
19394
19548
  const out = /* @__PURE__ */ new Map();
19395
- for (const { memory } of await enumerateIds(memoryIds, {
19549
+ for (const { memory } of await enumerateIds(decrypted, memoryIds, {
19396
19550
  include_archived: true,
19397
19551
  include_superseded: true,
19398
19552
  include_quarantined: true
@@ -19425,15 +19579,26 @@ function createRemoteMemoryStore(options) {
19425
19579
  update: async (id, patch) => {
19426
19580
  const saved = await mutate(id, "edit", (memory) => {
19427
19581
  if (memory.superseded_by) return null;
19582
+ const level = patch.level !== void 0 ? patch.level : patch.scope !== void 0 ? levelForScopeChange({ level: memory.level, scope: memory.scope }, patch.scope) : resolveMemoryLevel(memory.level, memory.scope);
19583
+ const kind = patch.kind !== void 0 ? patch.kind : memory.kind;
19584
+ assertValidKindLevel(kind, level);
19428
19585
  memory.content = patch.content;
19429
19586
  memory.updated_at = Date.now();
19430
- if (patch.scope !== void 0) {
19431
- memory.level = levelForScopeChange(
19432
- { level: memory.level, scope: memory.scope },
19433
- patch.scope
19434
- );
19587
+ if (patch.level !== void 0) {
19588
+ memory.level = level;
19589
+ memory.scope = scopeForLevel(level);
19590
+ } else if (patch.scope !== void 0) {
19591
+ memory.level = level;
19435
19592
  memory.scope = patch.scope;
19436
19593
  }
19594
+ if (patch.kind !== void 0) {
19595
+ if (patch.kind === null) delete memory.kind;
19596
+ else memory.kind = patch.kind;
19597
+ }
19598
+ if (patch.kindValue !== void 0) {
19599
+ if (patch.kindValue === null) delete memory.kind_value;
19600
+ else memory.kind_value = patch.kindValue;
19601
+ }
19437
19602
  if (patch.factType !== void 0) memory.fact_type = patch.factType ?? void 0;
19438
19603
  if (patch.eventTime !== void 0) {
19439
19604
  memory.event_time_start = patch.eventTime?.start ?? void 0;
@@ -19488,16 +19653,19 @@ function createRemoteMemoryStore(options) {
19488
19653
  notify("edit", [await persistence.put(memory, record2)]);
19489
19654
  return true;
19490
19655
  }),
19491
- setTopics: async (memoryId, topics) => asStored(
19492
- await mutate(memoryId, "edit", (memory) => ({
19493
- ...memory,
19494
- topics: serializeTopics(mergeTopics([], topicInputs(topics, "user"))),
19495
- topics_user_managed: true,
19496
- topics_updated_at: Date.now()
19497
- }))
19498
- ),
19656
+ setTopics: async (memoryId, topics) => {
19657
+ const chosen = await withKnownKinds(topicInputs(topics, "user"));
19658
+ return asStored(
19659
+ await mutate(memoryId, "edit", (memory) => ({
19660
+ ...memory,
19661
+ topics: serializeTopics(mergeTopics([], chosen)),
19662
+ topics_user_managed: true,
19663
+ topics_updated_at: Date.now()
19664
+ }))
19665
+ );
19666
+ },
19499
19667
  addTopics: async (memoryId, topics) => {
19500
- const added = topicInputs(topics, "auto");
19668
+ const added = await withKnownKinds(topicInputs(topics, "auto"));
19501
19669
  const saved = await mutate(memoryId, "edit", (memory) => ({
19502
19670
  ...memory,
19503
19671
  topics: serializeTopics(mergeTopics(parseTopics(memory.topics) ?? [], added)),
@@ -19526,6 +19694,7 @@ function createRemoteMemoryStore(options) {
19526
19694
  })
19527
19695
  ),
19528
19696
  recall: (query, recallOptions) => pipeline.recall(query, recallOptions),
19697
+ factSource: pipeline.factSource,
19529
19698
  retain: async (content, retainOptions) => {
19530
19699
  const result = await pipeline.retain(content, retainOptions);
19531
19700
  if (result.action === "create" || result.action === "supersede") notify("membership");
@@ -21289,19 +21458,20 @@ function createMemoryVaultSearchTool(vaultCtx, embeddingOptions, cache, searchOp
21289
21458
  const budget = wantsDecompose ? "high" : searchOptions?.rerank ? "mid" : "low";
21290
21459
  const folderId = searchOptions?.folderId ?? argFolderId;
21291
21460
  if (searchOptions?.useFusion === false) {
21292
- const { results: legacy, embeddingsUnavailable } = await searchVaultMemoriesWithSize(
21461
+ const legacyOptions = {
21462
+ limit: requestLimit,
21463
+ minSimilarity,
21464
+ useFusion: false,
21465
+ ...tuningForward,
21466
+ ...folderId !== void 0 && { folderId },
21467
+ ...searchOptions?.scopes && { scopes: searchOptions.scopes }
21468
+ };
21469
+ const { results: legacy, embeddingsUnavailable } = "retain" in vaultCtx ? await vaultCtx.factSource.search(query, legacyOptions) : await searchVaultMemoriesWithSize(
21293
21470
  query,
21294
21471
  vaultCtx,
21295
21472
  embeddingOptions,
21296
21473
  cache,
21297
- {
21298
- limit: requestLimit,
21299
- minSimilarity,
21300
- useFusion: false,
21301
- ...tuningForward,
21302
- ...folderId !== void 0 && { folderId },
21303
- ...searchOptions?.scopes && { scopes: searchOptions.scopes }
21304
- }
21474
+ legacyOptions
21305
21475
  );
21306
21476
  if (legacy.length === 0) {
21307
21477
  return embeddingsUnavailable ? EMBEDDINGS_DEGRADED_EMPTY_NO_LEXICAL : "No relevant memories found in the vault.";
@@ -21320,7 +21490,7 @@ function createMemoryVaultSearchTool(vaultCtx, embeddingOptions, cache, searchOp
21320
21490
  let recallDegraded = [];
21321
21491
  const result = await recall(
21322
21492
  query,
21323
- { vaultCtx, embeddingOptions, vaultCache: cache },
21493
+ "retain" in vaultCtx ? { factSource: vaultCtx.factSource, embeddingOptions } : { vaultCtx, embeddingOptions, vaultCache: cache },
21324
21494
  {
21325
21495
  onDiagnostics: (d) => {
21326
21496
  recallDegraded = d.degraded;
@@ -21400,8 +21570,10 @@ function describeWriteOutcome(outcome2) {
21400
21570
  }
21401
21571
  }
21402
21572
  function createMemoryVaultTool(vaultCtx, options, embeddingOptions, cache) {
21573
+ const store = "retain" in vaultCtx ? vaultCtx : void 0;
21574
+ const ctx = "retain" in vaultCtx ? void 0 : vaultCtx;
21403
21575
  const hasOnSave = !!options?.onSave;
21404
- const folderNames = options?.folderMap ? Array.from(options.folderMap.keys()) : [];
21576
+ const folderNames = !store && options?.folderMap ? Array.from(options.folderMap.keys()) : [];
21405
21577
  return {
21406
21578
  type: "function",
21407
21579
  function: {
@@ -21446,7 +21618,7 @@ function createMemoryVaultTool(vaultCtx, options, embeddingOptions, cache) {
21446
21618
  let previousContent;
21447
21619
  const scope = options?.scope ?? "private";
21448
21620
  if (isUpdate) {
21449
- const existing = await getVaultMemoryOp(vaultCtx, id);
21621
+ const existing = store ? await store.get(id) : await getVaultMemoryOp(ctx, id);
21450
21622
  if (!existing) {
21451
21623
  return `Error: Memory with ID "${id}" not found. Creating a new memory instead would require a separate call without an ID.`;
21452
21624
  }
@@ -21467,9 +21639,18 @@ function createMemoryVaultTool(vaultCtx, options, embeddingOptions, cache) {
21467
21639
  return isUpdate ? `Memory update was cancelled by the user. The memory "${id}" was not modified.` : "Memory save was cancelled by the user. No memory was created.";
21468
21640
  }
21469
21641
  }
21470
- if (isUpdate) {
21642
+ if (isUpdate && store) {
21643
+ const updated = await store.update(id, {
21644
+ content,
21645
+ ...factType !== void 0 && { factType }
21646
+ });
21647
+ if (!updated) {
21648
+ return `Error: Failed to update memory "${id}".`;
21649
+ }
21650
+ return `Memory updated successfully (ID: ${updated.uniqueId}).`;
21651
+ } else if (isUpdate) {
21471
21652
  const folderId = folderName ? options?.folderMap?.get(folderName) : void 0;
21472
- const updated = await updateVaultMemoryOp(vaultCtx, id, {
21653
+ const updated = await updateVaultMemoryOp(ctx, id, {
21473
21654
  content,
21474
21655
  embedding: null,
21475
21656
  folderId,
@@ -21484,7 +21665,7 @@ function createMemoryVaultTool(vaultCtx, options, embeddingOptions, cache) {
21484
21665
  content,
21485
21666
  embeddingOptions,
21486
21667
  cache,
21487
- vaultCtx,
21668
+ ctx,
21488
21669
  id,
21489
21670
  updated.updatedAt
21490
21671
  ).catch(() => {
@@ -21504,18 +21685,22 @@ function createMemoryVaultTool(vaultCtx, options, embeddingOptions, cache) {
21504
21685
  await notifyWritten(options, input, outcome2);
21505
21686
  return describeWriteOutcome(outcome2);
21506
21687
  }
21507
- const created = await createVaultMemoryOp(vaultCtx, {
21688
+ const created = store ? await store.create({
21689
+ content,
21690
+ scope,
21691
+ ...factType !== void 0 && { factType }
21692
+ }) : await createVaultMemoryOp(ctx, {
21508
21693
  content,
21509
21694
  scope,
21510
21695
  folderId,
21511
21696
  ...factType !== void 0 && { factType }
21512
21697
  });
21513
- if (embeddingOptions && cache) {
21698
+ if (ctx && embeddingOptions && cache) {
21514
21699
  eagerEmbedContent(
21515
21700
  content,
21516
21701
  embeddingOptions,
21517
21702
  cache,
21518
- vaultCtx,
21703
+ ctx,
21519
21704
  created.uniqueId,
21520
21705
  created.updatedAt
21521
21706
  ).catch(() => {
@@ -23794,6 +23979,8 @@ onClearAllEncryptionState(resetRecentToolSets);
23794
23979
  // src/expo/useChatStorage.ts
23795
23980
  var CONVERSATION_REDACTOR_LIMIT = 50;
23796
23981
  var NO_CONVERSATION_KEY = "__no_conversation__";
23982
+ var NO_STORE_FOLDERS = "Folders are not supported with a memoryStore";
23983
+ var NO_STORE_MASK = "piiRedaction needs a memoryStore built with embeddingOptions.maskInput";
23797
23984
  var conversationRedactors = /* @__PURE__ */ new Map();
23798
23985
  var clientToolFilterCache = /* @__PURE__ */ new Map();
23799
23986
  function getConversationRedactor(conversationId, nerDetector) {
@@ -23895,6 +24082,7 @@ function useChatStorage(options) {
23895
24082
  signMessage,
23896
24083
  embeddedWalletSigner,
23897
24084
  getWalletAddress,
24085
+ memoryStore,
23898
24086
  enableQueue = true,
23899
24087
  autoFlushOnKeyAvailable = true,
23900
24088
  extraToolSets,
@@ -23935,6 +24123,7 @@ function useChatStorage(options) {
23935
24123
  [resolvedPiiRedaction]
23936
24124
  );
23937
24125
  const maskEmbeddingInput = isPiiRedactor(resolvedPiiRedaction) ? maskForEmbedding : void 0;
24126
+ const storeMaskMissing = memoryStore !== void 0 && maskEmbeddingInput !== void 0 && !memoryStore.masksEmbeddingInput;
23938
24127
  const messagesCollection = useMemo(() => database.get("history"), [database]);
23939
24128
  const conversationsCollection = useMemo(
23940
24129
  () => database.get("conversations"),
@@ -24183,6 +24372,15 @@ function useChatStorage(options) {
24183
24372
  }, [vaultEmbeddingCache]);
24184
24373
  const retainVaultMemory = useCallback4(
24185
24374
  async (input) => {
24375
+ if (memoryStore) {
24376
+ if (storeMaskMissing) throw new Error(NO_STORE_MASK);
24377
+ if (input.folderId !== void 0) throw new Error(NO_STORE_FOLDERS);
24378
+ return memoryStore.retain(input.content, {
24379
+ source: "manual",
24380
+ scope: input.scope,
24381
+ ...input.factType !== void 0 && { factType: input.factType }
24382
+ });
24383
+ }
24186
24384
  if (!getToken) {
24187
24385
  throw new Error("getToken is required to retain a vault memory");
24188
24386
  }
@@ -24206,37 +24404,56 @@ function useChatStorage(options) {
24206
24404
  }
24207
24405
  );
24208
24406
  },
24209
- [vaultCtx, getToken, baseUrl, embeddingModel, maskEmbeddingInput, vaultEmbeddingCache]
24407
+ [
24408
+ vaultCtx,
24409
+ getToken,
24410
+ baseUrl,
24411
+ embeddingModel,
24412
+ maskEmbeddingInput,
24413
+ vaultEmbeddingCache,
24414
+ memoryStore,
24415
+ storeMaskMissing
24416
+ ]
24210
24417
  );
24211
24418
  const createMemoryVaultTool2 = useCallback4(
24212
24419
  (options2) => {
24420
+ if (storeMaskMissing) throw new Error(NO_STORE_MASK);
24213
24421
  return createMemoryVaultTool(
24214
- vaultCtx,
24215
- getToken ? { write: retainVaultMemory, ...options2 } : options2
24422
+ memoryStore ?? vaultCtx,
24423
+ getToken || memoryStore ? { write: retainVaultMemory, ...options2 } : options2
24216
24424
  );
24217
24425
  },
24218
- [vaultCtx, getToken, retainVaultMemory]
24426
+ [vaultCtx, getToken, retainVaultMemory, memoryStore, storeMaskMissing]
24219
24427
  );
24220
24428
  const createRecallTool2 = useCallback4(
24221
24429
  (toolOptions, callbacks) => {
24222
- if (!getToken) {
24430
+ if (!getToken && !memoryStore) {
24223
24431
  throw new Error("getToken is required for recall tool");
24224
24432
  }
24225
24433
  const resolvedToolOptions = toolOptions?.excludeConversationId !== void 0 || !currentConversationId ? toolOptions : { ...toolOptions, excludeConversationId: currentConversationId };
24434
+ if (storeMaskMissing) throw new Error(NO_STORE_MASK);
24435
+ if (memoryStore && resolvedToolOptions?.folderId !== void 0)
24436
+ throw new Error(NO_STORE_FOLDERS);
24437
+ const embeddingOptions = {
24438
+ getToken,
24439
+ baseUrl,
24440
+ model: embeddingModel,
24441
+ maskInput: maskEmbeddingInput
24442
+ };
24226
24443
  return createRecallTool(
24227
- {
24444
+ memoryStore ? {
24445
+ factSource: memoryStore.factSource,
24446
+ ...getToken && { storageCtx },
24447
+ embeddingOptions,
24448
+ chunkCache: chunkVectorCacheRef.current
24449
+ } : {
24228
24450
  vaultCtx,
24229
24451
  storageCtx,
24230
- embeddingOptions: {
24231
- getToken,
24232
- baseUrl,
24233
- model: embeddingModel,
24234
- maskInput: maskEmbeddingInput
24235
- },
24452
+ embeddingOptions,
24236
24453
  vaultCache: vaultEmbeddingCache,
24237
24454
  chunkCache: chunkVectorCacheRef.current
24238
24455
  },
24239
- resolvedToolOptions,
24456
+ memoryStore ? { ...resolvedToolOptions, memoryStore } : resolvedToolOptions,
24240
24457
  callbacks
24241
24458
  );
24242
24459
  },
@@ -24248,12 +24465,14 @@ function useChatStorage(options) {
24248
24465
  embeddingModel,
24249
24466
  currentConversationId,
24250
24467
  maskEmbeddingInput,
24251
- vaultEmbeddingCache
24468
+ vaultEmbeddingCache,
24469
+ memoryStore,
24470
+ storeMaskMissing
24252
24471
  ]
24253
24472
  );
24254
24473
  const recallFn = useCallback4(
24255
24474
  async (query, options2) => {
24256
- if (!getToken) {
24475
+ if (!getToken && !memoryStore) {
24257
24476
  return {
24258
24477
  memories: [],
24259
24478
  usedBudget: options2?.budget ?? "low",
@@ -24262,17 +24481,25 @@ function useChatStorage(options) {
24262
24481
  };
24263
24482
  }
24264
24483
  const resolvedOptions = options2?.excludeConversationId !== void 0 || !currentConversationId ? options2 : { ...options2, excludeConversationId: currentConversationId };
24484
+ if (storeMaskMissing) throw new Error(NO_STORE_MASK);
24485
+ if (memoryStore && resolvedOptions?.folderId !== void 0) throw new Error(NO_STORE_FOLDERS);
24486
+ const embeddingOptions = {
24487
+ getToken,
24488
+ baseUrl,
24489
+ model: embeddingModel,
24490
+ maskInput: maskEmbeddingInput
24491
+ };
24265
24492
  return recall(
24266
24493
  query,
24267
- {
24494
+ memoryStore ? {
24495
+ factSource: memoryStore.factSource,
24496
+ ...getToken && { storageCtx },
24497
+ embeddingOptions,
24498
+ chunkCache: chunkVectorCacheRef.current
24499
+ } : {
24268
24500
  vaultCtx,
24269
24501
  storageCtx,
24270
- embeddingOptions: {
24271
- getToken,
24272
- baseUrl,
24273
- model: embeddingModel,
24274
- maskInput: maskEmbeddingInput
24275
- },
24502
+ embeddingOptions,
24276
24503
  vaultCache: vaultEmbeddingCache,
24277
24504
  chunkCache: chunkVectorCacheRef.current
24278
24505
  },
@@ -24287,20 +24514,27 @@ function useChatStorage(options) {
24287
24514
  embeddingModel,
24288
24515
  currentConversationId,
24289
24516
  maskEmbeddingInput,
24290
- vaultEmbeddingCache
24517
+ vaultEmbeddingCache,
24518
+ memoryStore,
24519
+ storeMaskMissing
24291
24520
  ]
24292
24521
  );
24293
24522
  const getVaultMemories = useCallback4(
24294
24523
  (options2) => {
24295
- return getAllVaultMemoriesOp(vaultCtx, options2);
24524
+ if (!memoryStore) return getAllVaultMemoriesOp(vaultCtx, options2);
24525
+ const { folderId, levels, kinds, ...listOptions } = options2 ?? {};
24526
+ if (folderId !== void 0) throw new Error(NO_STORE_FOLDERS);
24527
+ if (levels !== void 0 || kinds !== void 0)
24528
+ throw new Error("level and kind filters are not supported with a memoryStore");
24529
+ return memoryStore.list(listOptions);
24296
24530
  },
24297
- [vaultCtx]
24531
+ [vaultCtx, memoryStore]
24298
24532
  );
24299
24533
  const deleteVaultMemory = useCallback4(
24300
24534
  (id) => {
24301
- return deleteVaultMemoryOp(vaultCtx, id);
24535
+ return memoryStore ? memoryStore.delete(id) : deleteVaultMemoryOp(vaultCtx, id);
24302
24536
  },
24303
- [vaultCtx]
24537
+ [vaultCtx, memoryStore]
24304
24538
  );
24305
24539
  const {
24306
24540
  isLoading,