@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.
@@ -3356,7 +3356,7 @@ function extractUserMessageFromMessages(messages) {
3356
3356
  }
3357
3357
 
3358
3358
  // src/lib/db/chat/operations.ts
3359
- function messageToStoredRaw(message, projection) {
3359
+ function messageToStoredRaw(message, projection2) {
3360
3360
  const convId = String(message._getRaw("conversation_id"));
3361
3361
  const parseJsonField = (rawValue) => {
3362
3362
  if (!rawValue) return void 0;
@@ -3370,7 +3370,7 @@ function messageToStoredRaw(message, projection) {
3370
3370
  }
3371
3371
  return rawValue;
3372
3372
  };
3373
- const skipEmbeddings = projection?.skipEmbeddings === true;
3373
+ const skipEmbeddings = projection2?.skipEmbeddings === true;
3374
3374
  const sourcesRaw = message._getRaw("sources");
3375
3375
  const vectorRaw = skipEmbeddings ? null : message._getRaw("vector");
3376
3376
  const chunksRaw = skipEmbeddings ? null : message._getRaw("chunks");
@@ -3404,8 +3404,8 @@ function messageToStoredRaw(message, projection) {
3404
3404
  origin: message.origin
3405
3405
  };
3406
3406
  }
3407
- async function messageToStored(message, walletAddress, signMessage, embeddedWalletSigner, projection) {
3408
- const baseMessage = messageToStoredRaw(message, projection);
3407
+ async function messageToStored(message, walletAddress, signMessage, embeddedWalletSigner, projection2) {
3408
+ const baseMessage = messageToStoredRaw(message, projection2);
3409
3409
  if (walletAddress) {
3410
3410
  return await decryptMessageFields(
3411
3411
  baseMessage,
@@ -3419,7 +3419,7 @@ async function messageToStored(message, walletAddress, signMessage, embeddedWall
3419
3419
  function rawDate(value) {
3420
3420
  return new Date(typeof value === "number" ? value : 0);
3421
3421
  }
3422
- function messageRawToStoredRaw(raw, projection) {
3422
+ function messageRawToStoredRaw(raw, projection2) {
3423
3423
  const parseJsonField = (rawValue) => {
3424
3424
  if (!rawValue) return void 0;
3425
3425
  if (typeof rawValue === "string") {
@@ -3432,7 +3432,7 @@ function messageRawToStoredRaw(raw, projection) {
3432
3432
  }
3433
3433
  return rawValue;
3434
3434
  };
3435
- const skipEmbeddings = projection?.skipEmbeddings === true;
3435
+ const skipEmbeddings = projection2?.skipEmbeddings === true;
3436
3436
  const vectorRaw = skipEmbeddings ? null : raw.vector;
3437
3437
  const chunksRaw = skipEmbeddings ? null : raw.chunks;
3438
3438
  return {
@@ -3463,8 +3463,8 @@ function messageRawToStoredRaw(raw, projection) {
3463
3463
  origin: raw.origin
3464
3464
  };
3465
3465
  }
3466
- async function messageRawToStored(raw, walletAddress, signMessage, embeddedWalletSigner, projection) {
3467
- const baseMessage = messageRawToStoredRaw(raw, projection);
3466
+ async function messageRawToStored(raw, walletAddress, signMessage, embeddedWalletSigner, projection2) {
3467
+ const baseMessage = messageRawToStoredRaw(raw, projection2);
3468
3468
  if (walletAddress) {
3469
3469
  return await decryptMessageFields(
3470
3470
  baseMessage,
@@ -12997,22 +12997,35 @@ async function vaultMemoryRawToStored(raw, walletAddress, signMessage, embeddedW
12997
12997
  return stored2;
12998
12998
  }
12999
12999
  async function getAllVaultMemoriesOp(ctx, options) {
13000
- const conditions = [
13000
+ const results = await ctx.vaultMemoryCollection.query(...vaultListConditions(ctx, options), ...vaultListOrder(options)).unsafeFetchRaw();
13001
+ return mapInBatches(
13002
+ results,
13003
+ (raw) => vaultMemoryRawToStored(raw, ctx.walletAddress, ctx.signMessage, ctx.embeddedWalletSigner)
13004
+ );
13005
+ }
13006
+ function vaultListConditions(ctx, options) {
13007
+ return [
13001
13008
  ...baseVaultConditions(ctx, options),
13002
13009
  ...options?.scopes?.length ? [import_watermelondb20.Q.where("scope", import_watermelondb20.Q.oneOf(options.scopes))] : [],
13003
13010
  ...visibilityConditions(options?.visibility),
13004
13011
  ...levelConditions(options?.levels),
13005
13012
  ...options?.kinds?.length ? [import_watermelondb20.Q.where("kind", import_watermelondb20.Q.oneOf(options.kinds))] : [],
13006
13013
  ...options?.folderId !== void 0 ? [import_watermelondb20.Q.where("folder_id", options.folderId)] : [],
13007
- ...options?.factTypes?.length ? [import_watermelondb20.Q.where("fact_type", import_watermelondb20.Q.oneOf(options.factTypes))] : [],
13014
+ ...options?.factTypes?.length ? [import_watermelondb20.Q.where("fact_type", import_watermelondb20.Q.oneOf(options.factTypes))] : []
13015
+ ];
13016
+ }
13017
+ function vaultListOrder(options) {
13018
+ return [
13008
13019
  import_watermelondb20.Q.sortBy(options?.since ? "updated_at" : "created_at", import_watermelondb20.Q.desc),
13009
13020
  ...options?.limit !== null && options?.limit !== void 0 && options.limit > 0 ? [import_watermelondb20.Q.take(options.limit)] : []
13010
13021
  ];
13011
- const results = await ctx.vaultMemoryCollection.query(...conditions).unsafeFetchRaw();
13012
- return mapInBatches(
13013
- results,
13014
- (raw) => vaultMemoryRawToStored(raw, ctx.walletAddress, ctx.signMessage, ctx.embeddedWalletSigner)
13015
- );
13022
+ }
13023
+ async function getVaultMemoryProjectionsOp(ctx, options) {
13024
+ const results = await ctx.vaultMemoryCollection.query(...vaultListConditions(ctx, options), ...vaultListOrder(options)).unsafeFetchRaw();
13025
+ return results.map((raw) => ({
13026
+ ...vaultMemoryRawToRankable(raw),
13027
+ topicsUserManaged: raw.topics_user_managed === true || raw.topics_user_managed === 1
13028
+ }));
13016
13029
  }
13017
13030
  function vaultMemoryRawToRankable(raw) {
13018
13031
  return {
@@ -18692,7 +18705,6 @@ async function recall(query, ctx, options = {}) {
18692
18705
  }
18693
18706
  const needsChunkEmbedding = types.includes("chunk") && ctx.storageCtx;
18694
18707
  const wantsTemporal = types.includes("fact") && (ctx.factSource || ctx.vaultCtx);
18695
- const graphRefiner = flags.traverse && options.graphRefine && options.decomposeOptions ? createLlmNeighborRefiner(options.decomposeOptions) : void 0;
18696
18708
  const queryEmbedTotalTimeoutMs = options.queryEmbedTotalTimeoutMs ?? DEFAULT_QUERY_EMBED_TOTAL_TIMEOUT_MS;
18697
18709
  const prepStart = nowMs2();
18698
18710
  let sharedEmbedMs = 0;
@@ -18721,13 +18733,12 @@ async function recall(query, ctx, options = {}) {
18721
18733
  safeLane(
18722
18734
  "graph",
18723
18735
  () => graphLaneFailed = true,
18724
- () => ctx.factSource ? ctx.factSource.graphRanking(query, flags.traverse, options) : buildGraphLaneRanking(query, ctx, flags.traverse, {
18725
- ...options.maxHops !== void 0 && { maxHops: options.maxHops },
18726
- ...options.entityFanout !== void 0 && { entityFanout: options.entityFanout },
18727
- ...options.nodeBudget !== void 0 && { nodeBudget: options.nodeBudget },
18728
- ...options.rrfK !== void 0 && { rrfK: options.rrfK },
18729
- ...graphRefiner && { refineNeighbors: graphRefiner }
18730
- })
18736
+ () => ctx.factSource ? ctx.factSource.graphRanking(query, flags.traverse, options) : buildGraphLaneRanking(
18737
+ query,
18738
+ ctx,
18739
+ flags.traverse,
18740
+ graphTraversalOptions(options, flags.traverse)
18741
+ )
18731
18742
  ),
18732
18743
  wantsTemporal ? safeLane(
18733
18744
  "temporal",
@@ -18946,6 +18957,16 @@ function toFactMemory(r, now) {
18946
18957
  updatedAt: r.updatedAt ?? /* @__PURE__ */ new Date(0)
18947
18958
  };
18948
18959
  }
18960
+ function graphTraversalOptions(options, traverse) {
18961
+ const refineNeighbors = traverse && options.graphRefine && options.decomposeOptions ? createLlmNeighborRefiner(options.decomposeOptions) : void 0;
18962
+ return {
18963
+ ...options.maxHops !== void 0 && { maxHops: options.maxHops },
18964
+ ...options.entityFanout !== void 0 && { entityFanout: options.entityFanout },
18965
+ ...options.nodeBudget !== void 0 && { nodeBudget: options.nodeBudget },
18966
+ ...options.rrfK !== void 0 && { rrfK: options.rrfK },
18967
+ ...refineNeighbors && { refineNeighbors }
18968
+ };
18969
+ }
18949
18970
  async function buildGraphLaneRanking(query, ctx, traverse = false, traversalOptions = {}) {
18950
18971
  const entityCtx = ctx.entityCtx ?? ctx.vaultCtx?.entityCtx;
18951
18972
  if (!entityCtx) return [];
@@ -19111,24 +19132,33 @@ function isDumpQuery(query) {
19111
19132
  return false;
19112
19133
  }
19113
19134
  async function listRecentFacts(ctx, limit, toolOptions) {
19135
+ const store = toolOptions?.memoryStore;
19114
19136
  const vaultCtx = ctx.vaultCtx;
19115
- if (!vaultCtx) return [];
19116
- const ordered = await getVaultRankingProjectionsOp(vaultCtx, {
19137
+ if (!vaultCtx && !store) return [];
19138
+ const read = (ids) => store ? store.list({ memoryIds: ids }) : getVaultMemoriesByIdsOp(vaultCtx, ids);
19139
+ const filters = {
19117
19140
  ...toolOptions?.scopes && { scopes: toolOptions.scopes },
19118
- ...toolOptions?.memoryIds !== void 0 && { memoryIds: toolOptions.memoryIds },
19141
+ ...toolOptions?.memoryIds !== void 0 && { memoryIds: toolOptions.memoryIds }
19142
+ };
19143
+ const project = (size) => store ? store.listProjections({ ...filters, limit: size }) : getVaultRankingProjectionsOp(vaultCtx, {
19144
+ ...filters,
19119
19145
  ...toolOptions?.folderId !== void 0 && { folderId: toolOptions.folderId }
19120
19146
  });
19121
19147
  const readable = [];
19122
- for (let i = 0; i < ordered.length && readable.length < limit; i += limit) {
19123
- const batch = ordered.slice(i, i + limit).map((p) => p.uniqueId);
19124
- const byId = new Map(
19125
- (await getVaultMemoriesByIdsOp(vaultCtx, batch)).map((m) => [m.uniqueId, m])
19126
- );
19127
- for (const id of batch) {
19128
- const m = byId.get(id);
19129
- if (m && !isEncrypted(m.content)) readable.push(m);
19130
- if (readable.length >= limit) break;
19148
+ let start = 0;
19149
+ for (let size = limit; readable.length < limit; size *= 2) {
19150
+ const ordered = await project(size);
19151
+ for (let i = start; i < ordered.length && readable.length < limit; i += limit) {
19152
+ const batch = ordered.slice(i, i + limit).map((p) => p.uniqueId);
19153
+ const byId = new Map((await read(batch)).map((m) => [m.uniqueId, m]));
19154
+ for (const id of batch) {
19155
+ const m = byId.get(id);
19156
+ if (m && !isEncrypted(m.content)) readable.push(m);
19157
+ if (readable.length >= limit) break;
19158
+ }
19131
19159
  }
19160
+ if (!store || ordered.length < size) break;
19161
+ start = ordered.length;
19132
19162
  }
19133
19163
  return readable.map((m) => ({
19134
19164
  id: m.uniqueId,
@@ -19145,6 +19175,8 @@ async function listRecentFacts(ctx, limit, toolOptions) {
19145
19175
  }));
19146
19176
  }
19147
19177
  function createRecallTool(ctx, toolOptions, callbacks) {
19178
+ if (toolOptions?.memoryStore && toolOptions.folderId !== void 0)
19179
+ throw new Error("Folders are not supported with a memoryStore");
19148
19180
  const defaultTypes = toolOptions?.types ?? ["fact", "chunk"];
19149
19181
  const defaultLimit = toolOptions?.limit ?? DEFAULT_LIMIT2;
19150
19182
  const defaultBudget = toolOptions?.budget ?? DEFAULT_BUDGET2;
@@ -19216,7 +19248,7 @@ function createRecallTool(ctx, toolOptions, callbacks) {
19216
19248
  let surfaced = 0;
19217
19249
  try {
19218
19250
  let recallDegraded = [];
19219
- const wantsRecent = args.sort === "recent" && defaultTypes.includes("fact") && ctx.vaultCtx !== void 0;
19251
+ const wantsRecent = args.sort === "recent" && defaultTypes.includes("fact") && (ctx.vaultCtx !== void 0 || toolOptions?.memoryStore !== void 0);
19220
19252
  let result;
19221
19253
  if (wantsRecent) {
19222
19254
  result = { memories: await listRecentFacts(ctx, effectiveLimit, toolOptions) };
@@ -19693,6 +19725,7 @@ function createLocalMemoryStore(options) {
19693
19725
  };
19694
19726
  const vaultCache = options.vaultCache ?? createVaultEmbeddingCache();
19695
19727
  const ownedBy = userId !== void 0 ? [import_watermelondb23.Q.where("user_id", userId)] : [];
19728
+ const linksOwnedBy = userId === void 0 ? [] : options.allowUnscopedRows ? [import_watermelondb23.Q.or(import_watermelondb23.Q.where("user_id", userId), import_watermelondb23.Q.where("user_id", null))] : [import_watermelondb23.Q.where("user_id", userId)];
19696
19729
  const watchedColumns = [
19697
19730
  "content",
19698
19731
  "scope",
@@ -19725,6 +19758,7 @@ function createLocalMemoryStore(options) {
19725
19758
  });
19726
19759
  };
19727
19760
  return {
19761
+ masksEmbeddingInput: options.embeddingOptions.maskInput !== void 0,
19728
19762
  list: (listOptions) => getAllVaultMemoriesOp(vaultCtx, listOptions),
19729
19763
  get: (id) => getVaultMemoryOp(vaultCtx, id),
19730
19764
  listArchived: async () => {
@@ -19735,6 +19769,29 @@ function createLocalMemoryStore(options) {
19735
19769
  },
19736
19770
  memoriesByTopics: (names) => getMemoriesByEntityNamesOp(entityCtx, names),
19737
19771
  topicsByMemories: (memoryIds) => getEntitiesByMemoryIdsOp(entityCtx, memoryIds),
19772
+ listTopics: async () => {
19773
+ const links = await entityCtx.memoryEntityCollection.query(...linksOwnedBy).fetch();
19774
+ const members = /* @__PURE__ */ new Map();
19775
+ for (const link of links) {
19776
+ const entityId = String(link.entityId);
19777
+ const set = members.get(entityId) ?? /* @__PURE__ */ new Set();
19778
+ set.add(String(link.memoryId));
19779
+ members.set(entityId, set);
19780
+ }
19781
+ const entities = userId === void 0 ? await entityCtx.entityCollection.query().fetch() : members.size ? await entityCtx.entityCollection.query(import_watermelondb23.Q.where("id", import_watermelondb23.Q.oneOf([...members.keys()]))).fetch() : [];
19782
+ const byName = /* @__PURE__ */ new Map();
19783
+ for (const entity of entities) {
19784
+ const count2 = members.get(entity.id)?.size ?? 0;
19785
+ const existing = byName.get(entity.canonicalName);
19786
+ byName.set(entity.canonicalName, {
19787
+ name: entity.canonicalName,
19788
+ kind: existing?.kind ?? entity.kind ?? null,
19789
+ memoryCount: (existing?.memoryCount ?? 0) + count2
19790
+ });
19791
+ }
19792
+ return [...byName.values()].sort((a, b) => a.name.localeCompare(b.name));
19793
+ },
19794
+ listProjections: (listOptions) => getVaultMemoryProjectionsOp(vaultCtx, listOptions),
19738
19795
  create: async (input) => {
19739
19796
  const created = await createVaultMemoryOp(vaultCtx, input);
19740
19797
  if (input.embedding === void 0) embedInBackground(created);
@@ -19783,6 +19840,22 @@ function createLocalMemoryStore(options) {
19783
19840
  { vaultCtx, embeddingOptions: options.embeddingOptions, vaultCache },
19784
19841
  retainOptions
19785
19842
  ),
19843
+ factSource: {
19844
+ search: (query, searchOptions) => searchVaultMemoriesWithSize(
19845
+ query,
19846
+ vaultCtx,
19847
+ options.embeddingOptions,
19848
+ vaultCache,
19849
+ searchOptions
19850
+ ),
19851
+ graphRanking: (query, traverse, recallOptions) => buildGraphLaneRanking(
19852
+ query,
19853
+ { vaultCtx, entityCtx, embeddingOptions: options.embeddingOptions },
19854
+ traverse,
19855
+ graphTraversalOptions(recallOptions, traverse)
19856
+ ),
19857
+ temporalRanking: (query, now) => buildTemporalLaneRanking(query, vaultCtx, now)
19858
+ },
19786
19859
  subscribe: (onChange, subscribeOptions) => {
19787
19860
  const afterFirst = () => {
19788
19861
  let first = true;
@@ -19796,7 +19869,6 @@ function createLocalMemoryStore(options) {
19796
19869
  );
19797
19870
  const subscriptions = [memories.subscribe(afterFirst())];
19798
19871
  if (subscribeOptions?.topics) {
19799
- const linksOwnedBy = userId === void 0 ? [] : options.allowUnscopedRows ? [import_watermelondb23.Q.or(import_watermelondb23.Q.where("user_id", userId), import_watermelondb23.Q.where("user_id", null))] : [import_watermelondb23.Q.where("user_id", userId)];
19800
19872
  subscriptions.push(
19801
19873
  entityCtx.memoryEntityCollection.query(...linksOwnedBy).observe().subscribe(afterFirst())
19802
19874
  );
@@ -20206,6 +20278,31 @@ async function createRemoteMemoryPersistence(options) {
20206
20278
  throw new Error("Invalid nearby candidate response");
20207
20279
  return result;
20208
20280
  };
20281
+ const fetchQueryPage = async (queryOptions) => {
20282
+ const { signal, ...query } = queryOptions;
20283
+ if (query.limit !== void 0 && (!Number.isInteger(query.limit) || query.limit < 1 || query.limit > 200))
20284
+ throw new Error("Page limit must be 1\u2013200");
20285
+ for (const [key, max] of queryListLimits) {
20286
+ const values = query[key];
20287
+ if (values && values.length > max)
20288
+ throw new Error(`Query ${key} accepts at most ${max} entries (got ${values.length})`);
20289
+ }
20290
+ const page = await request(
20291
+ "/memories/query",
20292
+ {
20293
+ method: "POST",
20294
+ body: JSON.stringify(
20295
+ Object.fromEntries(
20296
+ queryFields.filter((key) => query[key] !== void 0).map((key) => [key, query[key]])
20297
+ )
20298
+ )
20299
+ },
20300
+ signal
20301
+ );
20302
+ 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")
20303
+ throw new Error("Invalid nearby private-memory page");
20304
+ return page;
20305
+ };
20209
20306
  const candidateSet = async (embedding, candidateOptions = {}) => {
20210
20307
  const result = await fetchCandidates(embedding, candidateOptions, true);
20211
20308
  if (!Number.isSafeInteger(result.total_count) || result.total_count < 0 || !Number.isSafeInteger(result.unavailable_count) || result.unavailable_count < 0)
@@ -20284,34 +20381,27 @@ async function createRemoteMemoryPersistence(options) {
20284
20381
  return Promise.all(result.items.map((item, i) => decodeCommitted(item, prepared[i])));
20285
20382
  },
20286
20383
  query: async (queryOptions = {}) => {
20287
- const { signal, ...query } = queryOptions;
20288
- if (query.limit !== void 0 && (!Number.isInteger(query.limit) || query.limit < 1 || query.limit > 200))
20289
- throw new Error("Page limit must be 1\u2013200");
20290
- for (const [key, max] of queryListLimits) {
20291
- const values = query[key];
20292
- if (values && values.length > max)
20293
- throw new Error(`Query ${key} accepts at most ${max} entries (got ${values.length})`);
20294
- }
20295
- const page = await request(
20296
- "/memories/query",
20297
- {
20298
- method: "POST",
20299
- body: JSON.stringify(
20300
- Object.fromEntries(
20301
- queryFields.filter((key) => query[key] !== void 0).map((key) => [key, query[key]])
20302
- )
20303
- )
20304
- },
20305
- signal
20306
- );
20307
- 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")
20308
- throw new Error("Invalid nearby private-memory page");
20384
+ const page = await fetchQueryPage(queryOptions);
20309
20385
  return {
20310
20386
  ...await decodeAll(page.items),
20311
20387
  ...page.next_cursor !== void 0 && { next_cursor: page.next_cursor },
20312
20388
  ...page.changes_cursor !== void 0 && { changes_cursor: page.changes_cursor }
20313
20389
  };
20314
20390
  },
20391
+ queryMetadata: async (queryOptions = {}) => {
20392
+ const page = await fetchQueryPage(queryOptions);
20393
+ return {
20394
+ items: page.items.map((item) => {
20395
+ const {
20396
+ memory: { content: _content, kind_value: _kindValue, ...memory },
20397
+ version,
20398
+ server_updated_at
20399
+ } = memoryRecord(item);
20400
+ return { memory, version, server_updated_at };
20401
+ }),
20402
+ ...page.next_cursor !== void 0 && { next_cursor: page.next_cursor }
20403
+ };
20404
+ },
20315
20405
  candidateSet,
20316
20406
  candidates: async (embedding, candidateOptions = {}) => decodeAll((await fetchCandidates(embedding, candidateOptions, false)).items)
20317
20407
  };
@@ -20653,38 +20743,31 @@ function createRemoteMemoryPipeline(options) {
20653
20743
  };
20654
20744
  return { prepare, port };
20655
20745
  };
20656
- return {
20657
- recall: async (query, recallOptions = {}) => {
20746
+ const factSource = {
20747
+ graphRanking: options.graphRanking,
20748
+ temporalRanking: options.temporalRanking,
20749
+ search: async (text13, searchOptions) => {
20658
20750
  const { prepare } = operation("recall");
20659
- return recall(
20660
- query,
20661
- {
20662
- embeddingOptions,
20663
- factSource: {
20664
- graphRanking: options.graphRanking,
20665
- temporalRanking: options.temporalRanking,
20666
- search: async (text13, searchOptions) => {
20667
- const prepared = await prepare(text13, searchOptions);
20668
- const ranked = await rankPreparedVaultCandidates(
20669
- text13,
20670
- prepared,
20671
- embeddingOptions,
20672
- searchOptions
20673
- );
20674
- return {
20675
- ...ranked,
20676
- rankedOnCosine: prepared.memories.length > 0 && !prepared.embeddingsUnavailable,
20677
- decryptLast: true,
20678
- rowsDecrypted: prepared.rowsDecrypted,
20679
- queryEmbedMs: prepared.queryEmbedMs,
20680
- rowsEmbedded: 0
20681
- };
20682
- }
20683
- }
20684
- },
20685
- { ...recallOptions, types: ["fact"] }
20751
+ const prepared = await prepare(text13, searchOptions);
20752
+ const ranked = await rankPreparedVaultCandidates(
20753
+ text13,
20754
+ prepared,
20755
+ embeddingOptions,
20756
+ searchOptions
20686
20757
  );
20687
- },
20758
+ return {
20759
+ ...ranked,
20760
+ rankedOnCosine: prepared.memories.length > 0 && !prepared.embeddingsUnavailable,
20761
+ decryptLast: true,
20762
+ rowsDecrypted: prepared.rowsDecrypted,
20763
+ queryEmbedMs: prepared.queryEmbedMs,
20764
+ rowsEmbedded: 0
20765
+ };
20766
+ }
20767
+ };
20768
+ return {
20769
+ factSource,
20770
+ recall: async (query, recallOptions = {}) => recall(query, { embeddingOptions, factSource }, { ...recallOptions, types: ["fact"] }),
20688
20771
  retain: async (content, retainOptions) => {
20689
20772
  const { port } = operation("retain");
20690
20773
  return retainWithPersistence(
@@ -20704,6 +20787,19 @@ function createRemoteMemoryPipeline(options) {
20704
20787
  // src/lib/memory/store/remoteStore.ts
20705
20788
  var import_uuid5 = require("uuid");
20706
20789
  init_logger();
20790
+ function projection({ memory }) {
20791
+ return {
20792
+ uniqueId: memory.memory_id,
20793
+ scope: memory.scope,
20794
+ folderId: memory.folder_id ?? null,
20795
+ embedding: memory.embedding?.length ? JSON.stringify(memory.embedding) : null,
20796
+ embeddingModel: memory.embedding_model ?? null,
20797
+ createdAt: new Date(memory.created_at),
20798
+ updatedAt: new Date(memory.updated_at),
20799
+ lastObservedAt: memory.last_observed_at ?? null,
20800
+ topicsUserManaged: memory.topics_user_managed ?? false
20801
+ };
20802
+ }
20707
20803
  function relevant(change, options) {
20708
20804
  return options.includeDeleted ? change === "membership" : change !== "embedding" || !!options.embeddings;
20709
20805
  }
@@ -20738,6 +20834,9 @@ function bounded(filters, key) {
20738
20834
  if (!values || values.length <= MAX_QUERY_FILTER) return [filters];
20739
20835
  return chunks(values, MAX_QUERY_FILTER).map((chunk) => ({ ...filters, [key]: chunk }));
20740
20836
  }
20837
+ function maxOf(options) {
20838
+ return options.limit && options.limit > 0 ? options.limit : Infinity;
20839
+ }
20741
20840
  function chunks(values, size) {
20742
20841
  const out = [];
20743
20842
  for (let i = 0; i < values.length; i += size) out.push(values.slice(i, i + size));
@@ -20809,26 +20908,49 @@ function createRemoteMemoryStore(options) {
20809
20908
  for (const subscriber of [...subscribers])
20810
20909
  if (relevant(change, subscriber.options)) safely(subscriber.onChange);
20811
20910
  };
20812
- const enumerate = async (filters, max = Infinity) => {
20911
+ const pages = async (read, filters, max = Infinity) => {
20813
20912
  const records = [];
20814
20913
  let cursor2;
20815
20914
  do {
20816
- const page = await persistence.query({
20915
+ const page = await read({
20817
20916
  ...filters,
20818
20917
  limit: Math.min(200, Math.max(1, max - records.length)),
20819
20918
  ...cursor2 && { cursor: cursor2 }
20820
20919
  });
20821
- warnFailed(page.failed);
20920
+ if (page.failed) warnFailed(page.failed);
20822
20921
  records.push(...page.items);
20823
20922
  cursor2 = page.next_cursor;
20824
20923
  } while (cursor2 && records.length < max);
20825
20924
  return records.slice(0, max);
20826
20925
  };
20827
- const enumerateIds = async (ids, filters) => (await Promise.all(
20926
+ const decrypted = (options2) => persistence.query(options2);
20927
+ const metadata = (options2) => persistence.queryMetadata(options2);
20928
+ const enumerate = (filters, max = Infinity) => pages(decrypted, filters, max);
20929
+ const enumerateIds = async (read, ids, filters) => (await Promise.all(
20828
20930
  chunks([...new Set(ids)], MAX_QUERY_IDS).map(
20829
- (memory_ids) => enumerate({ ...filters, memory_ids })
20931
+ (memory_ids) => pages(read, { ...filters, memory_ids })
20830
20932
  )
20831
20933
  )).flat();
20934
+ const listFilters = (listOptions) => ({
20935
+ ...stateFilters(listOptions),
20936
+ include_embeddings: true,
20937
+ order: listOptions.since ? "updated" : "created",
20938
+ ...listOptions.scopes?.length && { scopes: listOptions.scopes },
20939
+ ...listOptions.factTypes?.length && { fact_types: listOptions.factTypes },
20940
+ ...listOptions.visibility?.length && { visibility: listOptions.visibility },
20941
+ ...listOptions.since && { updated_after: listOptions.since.getTime() }
20942
+ });
20943
+ const listRows = async (read, listOptions, filters, max) => {
20944
+ const variants = bounded(filters, "scopes").flatMap((f) => bounded(f, "fact_types"));
20945
+ if (!listOptions.memoryIds && variants.length === 1) return pages(read, filters, max);
20946
+ const fetched = await Promise.all(
20947
+ variants.map(
20948
+ (variant) => listOptions.memoryIds ? enumerateIds(read, listOptions.memoryIds, variant) : pages(read, variant, max)
20949
+ )
20950
+ );
20951
+ const time = (row) => filters.order === "updated" ? row.memory.updated_at : row.memory.created_at;
20952
+ 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);
20953
+ };
20832
20954
  const queues = /* @__PURE__ */ new Map();
20833
20955
  const serialized = (id, task) => {
20834
20956
  const run = (queues.get(id) ?? Promise.resolve()).then(task, task);
@@ -20870,12 +20992,15 @@ function createRemoteMemoryStore(options) {
20870
20992
  };
20871
20993
  const newRow = (input) => {
20872
20994
  const now = Date.now();
20873
- const scope = input.scope ?? "private";
20995
+ const { level, scope } = resolveCreateLevel(input);
20996
+ assertValidKindLevel(input.kind, level);
20874
20997
  return {
20875
20998
  memory_id: (0, import_uuid5.v7)(),
20876
20999
  content: input.content,
20877
21000
  scope,
20878
- level: levelFromScope(scope),
21001
+ level,
21002
+ ...input.kind !== void 0 && input.kind !== null && { kind: input.kind },
21003
+ ...typeof input.kindValue === "string" && { kind_value: input.kindValue },
20879
21004
  created_at: now,
20880
21005
  updated_at: now,
20881
21006
  is_deleted: false,
@@ -20904,6 +21029,30 @@ function createRemoteMemoryStore(options) {
20904
21029
  return records.map((record2) => stored(record2.memory));
20905
21030
  };
20906
21031
  const asStored = (record2) => record2 ? stored(record2.memory) : null;
21032
+ const withKnownKinds = async (topics) => {
21033
+ const unkinded = [
21034
+ ...new Set(topics.filter((t) => !t.kind).map((t) => normalizeEntityName(t.name)))
21035
+ ];
21036
+ if (unkinded.length === 0) return topics;
21037
+ const kinds = /* @__PURE__ */ new Map();
21038
+ for (const names of chunks(unkinded, MAX_QUERY_TOPICS)) {
21039
+ for (const { memory } of await pages(metadata, {
21040
+ topics: names,
21041
+ include_archived: true,
21042
+ include_quarantined: true,
21043
+ include_superseded: true
21044
+ })) {
21045
+ for (const topic of parseTopics(memory.topics) ?? []) {
21046
+ const name = normalizeEntityName(topic.name);
21047
+ if (topic.kind && !kinds.has(name)) kinds.set(name, topic.kind);
21048
+ }
21049
+ }
21050
+ }
21051
+ return topics.map((topic) => {
21052
+ const kind = topic.kind ?? kinds.get(normalizeEntityName(topic.name));
21053
+ return kind ? { ...topic, kind } : topic;
21054
+ });
21055
+ };
20907
21056
  const everyState = {
20908
21057
  include_deleted: true,
20909
21058
  include_archived: true,
@@ -20980,30 +21129,35 @@ function createRemoteMemoryStore(options) {
20980
21129
  });
20981
21130
  };
20982
21131
  return {
20983
- list: async (listOptions = {}) => {
20984
- const order = listOptions.since ? "updated" : "created";
20985
- const filters = {
20986
- ...stateFilters(listOptions),
20987
- include_embeddings: true,
20988
- order,
20989
- ...listOptions.scopes?.length && { scopes: listOptions.scopes },
20990
- ...listOptions.factTypes?.length && { fact_types: listOptions.factTypes },
20991
- ...listOptions.visibility?.length && { visibility: listOptions.visibility },
20992
- ...listOptions.since && { updated_after: listOptions.since.getTime() }
20993
- };
20994
- const max = listOptions.limit && listOptions.limit > 0 ? listOptions.limit : Infinity;
20995
- const variants = bounded(filters, "scopes").flatMap((f) => bounded(f, "fact_types"));
20996
- if (!listOptions.memoryIds && variants.length === 1)
20997
- return (await enumerate(filters, max)).map((r) => stored(r.memory));
20998
- const fetched = await Promise.all(
20999
- variants.map(
21000
- (variant) => listOptions.memoryIds ? enumerateIds(listOptions.memoryIds, variant) : enumerate(variant, max)
21001
- )
21002
- );
21003
- const rows = [...new Map(fetched.flat().map((r) => [r.memory.memory_id, r])).values()].map((record2) => stored(record2.memory)).sort(
21004
- (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)
21005
- );
21006
- return rows.slice(0, max);
21132
+ masksEmbeddingInput: embeddingOptions.maskInput !== void 0,
21133
+ list: async (listOptions = {}) => (await listRows(decrypted, listOptions, listFilters(listOptions), maxOf(listOptions))).map(
21134
+ (r) => stored(r.memory)
21135
+ ),
21136
+ listProjections: async (listOptions = {}) => (await listRows(metadata, listOptions, listFilters(listOptions), maxOf(listOptions))).map(
21137
+ projection
21138
+ ),
21139
+ listTopics: async () => {
21140
+ const topics = /* @__PURE__ */ new Map();
21141
+ for (const { memory } of await pages(metadata, {
21142
+ include_archived: true,
21143
+ include_quarantined: true,
21144
+ include_superseded: true
21145
+ })) {
21146
+ for (const topic of parseTopics(memory.topics) ?? []) {
21147
+ const name = normalizeEntityName(topic.name);
21148
+ if (!name) continue;
21149
+ const entry = topics.get(name) ?? {
21150
+ name,
21151
+ kind: null,
21152
+ memoryCount: 0,
21153
+ members: /* @__PURE__ */ new Set()
21154
+ };
21155
+ entry.kind ?? (entry.kind = topic.kind ?? null);
21156
+ entry.members.add(memory.memory_id);
21157
+ topics.set(name, entry);
21158
+ }
21159
+ }
21160
+ return [...topics.values()].map(({ members, ...topic }) => ({ ...topic, memoryCount: members.size })).sort((a, b) => a.name.localeCompare(b.name));
21007
21161
  },
21008
21162
  get: async (id) => asStored(await live(id)),
21009
21163
  listArchived: async () => (await enumerate({ archived_only: true, order: "archived", include_embeddings: true })).map(
@@ -21012,10 +21166,10 @@ function createRemoteMemoryStore(options) {
21012
21166
  memoriesByTopics: async (names) => {
21013
21167
  const wanted = new Set(names.map(normalizeEntityName).filter(Boolean));
21014
21168
  const out = /* @__PURE__ */ new Map();
21015
- const pages = await Promise.all(
21169
+ const pages2 = await Promise.all(
21016
21170
  chunks([...wanted], MAX_QUERY_TOPICS).map((topics) => enumerate({ topics }))
21017
21171
  );
21018
- for (const { memory } of pages.flat()) {
21172
+ for (const { memory } of pages2.flat()) {
21019
21173
  const matched = [...canonicalTopics(memory)].filter((name) => wanted.has(name));
21020
21174
  if (matched.length) out.set(memory.memory_id, new Set(matched));
21021
21175
  }
@@ -21023,7 +21177,7 @@ function createRemoteMemoryStore(options) {
21023
21177
  },
21024
21178
  topicsByMemories: async (memoryIds) => {
21025
21179
  const out = /* @__PURE__ */ new Map();
21026
- for (const { memory } of await enumerateIds(memoryIds, {
21180
+ for (const { memory } of await enumerateIds(decrypted, memoryIds, {
21027
21181
  include_archived: true,
21028
21182
  include_superseded: true,
21029
21183
  include_quarantined: true
@@ -21056,15 +21210,26 @@ function createRemoteMemoryStore(options) {
21056
21210
  update: async (id, patch) => {
21057
21211
  const saved = await mutate(id, "edit", (memory) => {
21058
21212
  if (memory.superseded_by) return null;
21213
+ 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);
21214
+ const kind = patch.kind !== void 0 ? patch.kind : memory.kind;
21215
+ assertValidKindLevel(kind, level);
21059
21216
  memory.content = patch.content;
21060
21217
  memory.updated_at = Date.now();
21061
- if (patch.scope !== void 0) {
21062
- memory.level = levelForScopeChange(
21063
- { level: memory.level, scope: memory.scope },
21064
- patch.scope
21065
- );
21218
+ if (patch.level !== void 0) {
21219
+ memory.level = level;
21220
+ memory.scope = scopeForLevel(level);
21221
+ } else if (patch.scope !== void 0) {
21222
+ memory.level = level;
21066
21223
  memory.scope = patch.scope;
21067
21224
  }
21225
+ if (patch.kind !== void 0) {
21226
+ if (patch.kind === null) delete memory.kind;
21227
+ else memory.kind = patch.kind;
21228
+ }
21229
+ if (patch.kindValue !== void 0) {
21230
+ if (patch.kindValue === null) delete memory.kind_value;
21231
+ else memory.kind_value = patch.kindValue;
21232
+ }
21068
21233
  if (patch.factType !== void 0) memory.fact_type = patch.factType ?? void 0;
21069
21234
  if (patch.eventTime !== void 0) {
21070
21235
  memory.event_time_start = patch.eventTime?.start ?? void 0;
@@ -21119,16 +21284,19 @@ function createRemoteMemoryStore(options) {
21119
21284
  notify("edit", [await persistence.put(memory, record2)]);
21120
21285
  return true;
21121
21286
  }),
21122
- setTopics: async (memoryId, topics) => asStored(
21123
- await mutate(memoryId, "edit", (memory) => ({
21124
- ...memory,
21125
- topics: serializeTopics(mergeTopics([], topicInputs(topics, "user"))),
21126
- topics_user_managed: true,
21127
- topics_updated_at: Date.now()
21128
- }))
21129
- ),
21287
+ setTopics: async (memoryId, topics) => {
21288
+ const chosen = await withKnownKinds(topicInputs(topics, "user"));
21289
+ return asStored(
21290
+ await mutate(memoryId, "edit", (memory) => ({
21291
+ ...memory,
21292
+ topics: serializeTopics(mergeTopics([], chosen)),
21293
+ topics_user_managed: true,
21294
+ topics_updated_at: Date.now()
21295
+ }))
21296
+ );
21297
+ },
21130
21298
  addTopics: async (memoryId, topics) => {
21131
- const added = topicInputs(topics, "auto");
21299
+ const added = await withKnownKinds(topicInputs(topics, "auto"));
21132
21300
  const saved = await mutate(memoryId, "edit", (memory) => ({
21133
21301
  ...memory,
21134
21302
  topics: serializeTopics(mergeTopics(parseTopics(memory.topics) ?? [], added)),
@@ -21157,6 +21325,7 @@ function createRemoteMemoryStore(options) {
21157
21325
  })
21158
21326
  ),
21159
21327
  recall: (query, recallOptions) => pipeline.recall(query, recallOptions),
21328
+ factSource: pipeline.factSource,
21160
21329
  retain: async (content, retainOptions) => {
21161
21330
  const result = await pipeline.retain(content, retainOptions);
21162
21331
  if (result.action === "create" || result.action === "supersede") notify("membership");
@@ -22925,19 +23094,20 @@ function createMemoryVaultSearchTool(vaultCtx, embeddingOptions, cache, searchOp
22925
23094
  const budget = wantsDecompose ? "high" : searchOptions?.rerank ? "mid" : "low";
22926
23095
  const folderId = searchOptions?.folderId ?? argFolderId;
22927
23096
  if (searchOptions?.useFusion === false) {
22928
- const { results: legacy, embeddingsUnavailable } = await searchVaultMemoriesWithSize(
23097
+ const legacyOptions = {
23098
+ limit: requestLimit,
23099
+ minSimilarity,
23100
+ useFusion: false,
23101
+ ...tuningForward,
23102
+ ...folderId !== void 0 && { folderId },
23103
+ ...searchOptions?.scopes && { scopes: searchOptions.scopes }
23104
+ };
23105
+ const { results: legacy, embeddingsUnavailable } = "retain" in vaultCtx ? await vaultCtx.factSource.search(query, legacyOptions) : await searchVaultMemoriesWithSize(
22929
23106
  query,
22930
23107
  vaultCtx,
22931
23108
  embeddingOptions,
22932
23109
  cache,
22933
- {
22934
- limit: requestLimit,
22935
- minSimilarity,
22936
- useFusion: false,
22937
- ...tuningForward,
22938
- ...folderId !== void 0 && { folderId },
22939
- ...searchOptions?.scopes && { scopes: searchOptions.scopes }
22940
- }
23110
+ legacyOptions
22941
23111
  );
22942
23112
  if (legacy.length === 0) {
22943
23113
  return embeddingsUnavailable ? EMBEDDINGS_DEGRADED_EMPTY_NO_LEXICAL : "No relevant memories found in the vault.";
@@ -22956,7 +23126,7 @@ function createMemoryVaultSearchTool(vaultCtx, embeddingOptions, cache, searchOp
22956
23126
  let recallDegraded = [];
22957
23127
  const result = await recall(
22958
23128
  query,
22959
- { vaultCtx, embeddingOptions, vaultCache: cache },
23129
+ "retain" in vaultCtx ? { factSource: vaultCtx.factSource, embeddingOptions } : { vaultCtx, embeddingOptions, vaultCache: cache },
22960
23130
  {
22961
23131
  onDiagnostics: (d) => {
22962
23132
  recallDegraded = d.degraded;
@@ -23036,8 +23206,10 @@ function describeWriteOutcome(outcome2) {
23036
23206
  }
23037
23207
  }
23038
23208
  function createMemoryVaultTool(vaultCtx, options, embeddingOptions, cache) {
23209
+ const store = "retain" in vaultCtx ? vaultCtx : void 0;
23210
+ const ctx = "retain" in vaultCtx ? void 0 : vaultCtx;
23039
23211
  const hasOnSave = !!options?.onSave;
23040
- const folderNames = options?.folderMap ? Array.from(options.folderMap.keys()) : [];
23212
+ const folderNames = !store && options?.folderMap ? Array.from(options.folderMap.keys()) : [];
23041
23213
  return {
23042
23214
  type: "function",
23043
23215
  function: {
@@ -23082,7 +23254,7 @@ function createMemoryVaultTool(vaultCtx, options, embeddingOptions, cache) {
23082
23254
  let previousContent;
23083
23255
  const scope = options?.scope ?? "private";
23084
23256
  if (isUpdate) {
23085
- const existing = await getVaultMemoryOp(vaultCtx, id);
23257
+ const existing = store ? await store.get(id) : await getVaultMemoryOp(ctx, id);
23086
23258
  if (!existing) {
23087
23259
  return `Error: Memory with ID "${id}" not found. Creating a new memory instead would require a separate call without an ID.`;
23088
23260
  }
@@ -23103,9 +23275,18 @@ function createMemoryVaultTool(vaultCtx, options, embeddingOptions, cache) {
23103
23275
  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.";
23104
23276
  }
23105
23277
  }
23106
- if (isUpdate) {
23278
+ if (isUpdate && store) {
23279
+ const updated = await store.update(id, {
23280
+ content,
23281
+ ...factType !== void 0 && { factType }
23282
+ });
23283
+ if (!updated) {
23284
+ return `Error: Failed to update memory "${id}".`;
23285
+ }
23286
+ return `Memory updated successfully (ID: ${updated.uniqueId}).`;
23287
+ } else if (isUpdate) {
23107
23288
  const folderId = folderName ? options?.folderMap?.get(folderName) : void 0;
23108
- const updated = await updateVaultMemoryOp(vaultCtx, id, {
23289
+ const updated = await updateVaultMemoryOp(ctx, id, {
23109
23290
  content,
23110
23291
  embedding: null,
23111
23292
  folderId,
@@ -23120,7 +23301,7 @@ function createMemoryVaultTool(vaultCtx, options, embeddingOptions, cache) {
23120
23301
  content,
23121
23302
  embeddingOptions,
23122
23303
  cache,
23123
- vaultCtx,
23304
+ ctx,
23124
23305
  id,
23125
23306
  updated.updatedAt
23126
23307
  ).catch(() => {
@@ -23140,18 +23321,22 @@ function createMemoryVaultTool(vaultCtx, options, embeddingOptions, cache) {
23140
23321
  await notifyWritten(options, input, outcome2);
23141
23322
  return describeWriteOutcome(outcome2);
23142
23323
  }
23143
- const created = await createVaultMemoryOp(vaultCtx, {
23324
+ const created = store ? await store.create({
23325
+ content,
23326
+ scope,
23327
+ ...factType !== void 0 && { factType }
23328
+ }) : await createVaultMemoryOp(ctx, {
23144
23329
  content,
23145
23330
  scope,
23146
23331
  folderId,
23147
23332
  ...factType !== void 0 && { factType }
23148
23333
  });
23149
- if (embeddingOptions && cache) {
23334
+ if (ctx && embeddingOptions && cache) {
23150
23335
  eagerEmbedContent(
23151
23336
  content,
23152
23337
  embeddingOptions,
23153
23338
  cache,
23154
- vaultCtx,
23339
+ ctx,
23155
23340
  created.uniqueId,
23156
23341
  created.updatedAt
23157
23342
  ).catch(() => {
@@ -25450,6 +25635,8 @@ onClearAllEncryptionState(resetRecentToolSets);
25450
25635
  // src/expo/useChatStorage.ts
25451
25636
  var CONVERSATION_REDACTOR_LIMIT = 50;
25452
25637
  var NO_CONVERSATION_KEY = "__no_conversation__";
25638
+ var NO_STORE_FOLDERS = "Folders are not supported with a memoryStore";
25639
+ var NO_STORE_MASK = "piiRedaction needs a memoryStore built with embeddingOptions.maskInput";
25453
25640
  var conversationRedactors = /* @__PURE__ */ new Map();
25454
25641
  var clientToolFilterCache = /* @__PURE__ */ new Map();
25455
25642
  function getConversationRedactor(conversationId, nerDetector) {
@@ -25551,6 +25738,7 @@ function useChatStorage(options) {
25551
25738
  signMessage,
25552
25739
  embeddedWalletSigner,
25553
25740
  getWalletAddress,
25741
+ memoryStore,
25554
25742
  enableQueue = true,
25555
25743
  autoFlushOnKeyAvailable = true,
25556
25744
  extraToolSets,
@@ -25591,6 +25779,7 @@ function useChatStorage(options) {
25591
25779
  [resolvedPiiRedaction]
25592
25780
  );
25593
25781
  const maskEmbeddingInput = isPiiRedactor(resolvedPiiRedaction) ? maskForEmbedding : void 0;
25782
+ const storeMaskMissing = memoryStore !== void 0 && maskEmbeddingInput !== void 0 && !memoryStore.masksEmbeddingInput;
25594
25783
  const messagesCollection = (0, import_react5.useMemo)(() => database.get("history"), [database]);
25595
25784
  const conversationsCollection = (0, import_react5.useMemo)(
25596
25785
  () => database.get("conversations"),
@@ -25839,6 +26028,15 @@ function useChatStorage(options) {
25839
26028
  }, [vaultEmbeddingCache]);
25840
26029
  const retainVaultMemory = (0, import_react5.useCallback)(
25841
26030
  async (input) => {
26031
+ if (memoryStore) {
26032
+ if (storeMaskMissing) throw new Error(NO_STORE_MASK);
26033
+ if (input.folderId !== void 0) throw new Error(NO_STORE_FOLDERS);
26034
+ return memoryStore.retain(input.content, {
26035
+ source: "manual",
26036
+ scope: input.scope,
26037
+ ...input.factType !== void 0 && { factType: input.factType }
26038
+ });
26039
+ }
25842
26040
  if (!getToken) {
25843
26041
  throw new Error("getToken is required to retain a vault memory");
25844
26042
  }
@@ -25862,37 +26060,56 @@ function useChatStorage(options) {
25862
26060
  }
25863
26061
  );
25864
26062
  },
25865
- [vaultCtx, getToken, baseUrl, embeddingModel, maskEmbeddingInput, vaultEmbeddingCache]
26063
+ [
26064
+ vaultCtx,
26065
+ getToken,
26066
+ baseUrl,
26067
+ embeddingModel,
26068
+ maskEmbeddingInput,
26069
+ vaultEmbeddingCache,
26070
+ memoryStore,
26071
+ storeMaskMissing
26072
+ ]
25866
26073
  );
25867
26074
  const createMemoryVaultTool2 = (0, import_react5.useCallback)(
25868
26075
  (options2) => {
26076
+ if (storeMaskMissing) throw new Error(NO_STORE_MASK);
25869
26077
  return createMemoryVaultTool(
25870
- vaultCtx,
25871
- getToken ? { write: retainVaultMemory, ...options2 } : options2
26078
+ memoryStore ?? vaultCtx,
26079
+ getToken || memoryStore ? { write: retainVaultMemory, ...options2 } : options2
25872
26080
  );
25873
26081
  },
25874
- [vaultCtx, getToken, retainVaultMemory]
26082
+ [vaultCtx, getToken, retainVaultMemory, memoryStore, storeMaskMissing]
25875
26083
  );
25876
26084
  const createRecallTool2 = (0, import_react5.useCallback)(
25877
26085
  (toolOptions, callbacks) => {
25878
- if (!getToken) {
26086
+ if (!getToken && !memoryStore) {
25879
26087
  throw new Error("getToken is required for recall tool");
25880
26088
  }
25881
26089
  const resolvedToolOptions = toolOptions?.excludeConversationId !== void 0 || !currentConversationId ? toolOptions : { ...toolOptions, excludeConversationId: currentConversationId };
26090
+ if (storeMaskMissing) throw new Error(NO_STORE_MASK);
26091
+ if (memoryStore && resolvedToolOptions?.folderId !== void 0)
26092
+ throw new Error(NO_STORE_FOLDERS);
26093
+ const embeddingOptions = {
26094
+ getToken,
26095
+ baseUrl,
26096
+ model: embeddingModel,
26097
+ maskInput: maskEmbeddingInput
26098
+ };
25882
26099
  return createRecallTool(
25883
- {
26100
+ memoryStore ? {
26101
+ factSource: memoryStore.factSource,
26102
+ ...getToken && { storageCtx },
26103
+ embeddingOptions,
26104
+ chunkCache: chunkVectorCacheRef.current
26105
+ } : {
25884
26106
  vaultCtx,
25885
26107
  storageCtx,
25886
- embeddingOptions: {
25887
- getToken,
25888
- baseUrl,
25889
- model: embeddingModel,
25890
- maskInput: maskEmbeddingInput
25891
- },
26108
+ embeddingOptions,
25892
26109
  vaultCache: vaultEmbeddingCache,
25893
26110
  chunkCache: chunkVectorCacheRef.current
25894
26111
  },
25895
- resolvedToolOptions,
26112
+ memoryStore ? { ...resolvedToolOptions, memoryStore } : resolvedToolOptions,
25896
26113
  callbacks
25897
26114
  );
25898
26115
  },
@@ -25904,12 +26121,14 @@ function useChatStorage(options) {
25904
26121
  embeddingModel,
25905
26122
  currentConversationId,
25906
26123
  maskEmbeddingInput,
25907
- vaultEmbeddingCache
26124
+ vaultEmbeddingCache,
26125
+ memoryStore,
26126
+ storeMaskMissing
25908
26127
  ]
25909
26128
  );
25910
26129
  const recallFn = (0, import_react5.useCallback)(
25911
26130
  async (query, options2) => {
25912
- if (!getToken) {
26131
+ if (!getToken && !memoryStore) {
25913
26132
  return {
25914
26133
  memories: [],
25915
26134
  usedBudget: options2?.budget ?? "low",
@@ -25918,17 +26137,25 @@ function useChatStorage(options) {
25918
26137
  };
25919
26138
  }
25920
26139
  const resolvedOptions = options2?.excludeConversationId !== void 0 || !currentConversationId ? options2 : { ...options2, excludeConversationId: currentConversationId };
26140
+ if (storeMaskMissing) throw new Error(NO_STORE_MASK);
26141
+ if (memoryStore && resolvedOptions?.folderId !== void 0) throw new Error(NO_STORE_FOLDERS);
26142
+ const embeddingOptions = {
26143
+ getToken,
26144
+ baseUrl,
26145
+ model: embeddingModel,
26146
+ maskInput: maskEmbeddingInput
26147
+ };
25921
26148
  return recall(
25922
26149
  query,
25923
- {
26150
+ memoryStore ? {
26151
+ factSource: memoryStore.factSource,
26152
+ ...getToken && { storageCtx },
26153
+ embeddingOptions,
26154
+ chunkCache: chunkVectorCacheRef.current
26155
+ } : {
25924
26156
  vaultCtx,
25925
26157
  storageCtx,
25926
- embeddingOptions: {
25927
- getToken,
25928
- baseUrl,
25929
- model: embeddingModel,
25930
- maskInput: maskEmbeddingInput
25931
- },
26158
+ embeddingOptions,
25932
26159
  vaultCache: vaultEmbeddingCache,
25933
26160
  chunkCache: chunkVectorCacheRef.current
25934
26161
  },
@@ -25943,20 +26170,27 @@ function useChatStorage(options) {
25943
26170
  embeddingModel,
25944
26171
  currentConversationId,
25945
26172
  maskEmbeddingInput,
25946
- vaultEmbeddingCache
26173
+ vaultEmbeddingCache,
26174
+ memoryStore,
26175
+ storeMaskMissing
25947
26176
  ]
25948
26177
  );
25949
26178
  const getVaultMemories = (0, import_react5.useCallback)(
25950
26179
  (options2) => {
25951
- return getAllVaultMemoriesOp(vaultCtx, options2);
26180
+ if (!memoryStore) return getAllVaultMemoriesOp(vaultCtx, options2);
26181
+ const { folderId, levels, kinds, ...listOptions } = options2 ?? {};
26182
+ if (folderId !== void 0) throw new Error(NO_STORE_FOLDERS);
26183
+ if (levels !== void 0 || kinds !== void 0)
26184
+ throw new Error("level and kind filters are not supported with a memoryStore");
26185
+ return memoryStore.list(listOptions);
25952
26186
  },
25953
- [vaultCtx]
26187
+ [vaultCtx, memoryStore]
25954
26188
  );
25955
26189
  const deleteVaultMemory = (0, import_react5.useCallback)(
25956
26190
  (id) => {
25957
- return deleteVaultMemoryOp(vaultCtx, id);
26191
+ return memoryStore ? memoryStore.delete(id) : deleteVaultMemoryOp(vaultCtx, id);
25958
26192
  },
25959
- [vaultCtx]
26193
+ [vaultCtx, memoryStore]
25960
26194
  );
25961
26195
  const {
25962
26196
  isLoading,