@anuma/sdk 6.33.2 → 6.34.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.
@@ -1740,10 +1740,10 @@ function parsePlaintextToken(raw, walletAddress) {
1740
1740
  return null;
1741
1741
  }
1742
1742
  if (!parsed || typeof parsed !== "object") return null;
1743
- const record = parsed;
1744
- const data = record.token?.accessToken ? record.token : record;
1743
+ const record2 = parsed;
1744
+ const data = record2.token?.accessToken ? record2.token : record2;
1745
1745
  if (!data?.accessToken) return null;
1746
- if (record.wallet && record.wallet !== walletAddress) return null;
1746
+ if (record2.wallet && record2.wallet !== walletAddress) return null;
1747
1747
  return data;
1748
1748
  }
1749
1749
  function promoteUnscopedRow(raw, data, store, scopedKey, unscopedKey, walletAddress) {
@@ -1867,8 +1867,8 @@ async function storeTokenData(data, walletAddress) {
1867
1867
  getLogger().warn("Failed to encrypt GitHub OAuth token:", error);
1868
1868
  }
1869
1869
  }
1870
- const record = { wallet: walletAddress, token: data };
1871
- sessionStorage.setItem(getTokenStorageKey(walletAddress), JSON.stringify(record));
1870
+ const record2 = { wallet: walletAddress, token: data };
1871
+ sessionStorage.setItem(getTokenStorageKey(walletAddress), JSON.stringify(record2));
1872
1872
  }
1873
1873
  function clearGithubToken(walletAddress) {
1874
1874
  if (typeof window === "undefined") return;
@@ -1917,17 +1917,17 @@ function storeOAuthState(state) {
1917
1917
  }
1918
1918
  function getAndClearOAuthState() {
1919
1919
  if (typeof window === "undefined") return null;
1920
- const stored = sessionStorage.getItem(CODE_STORAGE_KEY);
1920
+ const stored2 = sessionStorage.getItem(CODE_STORAGE_KEY);
1921
1921
  sessionStorage.removeItem(CODE_STORAGE_KEY);
1922
- if (!stored) return null;
1922
+ if (!stored2) return null;
1923
1923
  try {
1924
- const parsed = JSON.parse(stored);
1924
+ const parsed = JSON.parse(stored2);
1925
1925
  if (parsed && typeof parsed === "object" && "state" in parsed) {
1926
1926
  return parsed.state;
1927
1927
  }
1928
1928
  } catch {
1929
1929
  }
1930
- return stored;
1930
+ return stored2;
1931
1931
  }
1932
1932
  function isGithubCallback(callbackPath) {
1933
1933
  if (typeof window === "undefined") return false;
@@ -2219,8 +2219,8 @@ async function storeTokenData2(data, walletAddress) {
2219
2219
  getLogger().warn("Failed to encrypt Calendar OAuth token:", error);
2220
2220
  }
2221
2221
  }
2222
- const record = { wallet: walletAddress, token: data };
2223
- sessionStorage.setItem(getTokenStorageKey2(walletAddress), JSON.stringify(record));
2222
+ const record2 = { wallet: walletAddress, token: data };
2223
+ sessionStorage.setItem(getTokenStorageKey2(walletAddress), JSON.stringify(record2));
2224
2224
  }
2225
2225
  function clearCalendarToken(walletAddress) {
2226
2226
  if (typeof window === "undefined") return;
@@ -2260,17 +2260,17 @@ function getRedirectUri2(callbackPath) {
2260
2260
  }
2261
2261
  function getAndClearOAuthState2() {
2262
2262
  if (typeof window === "undefined") return null;
2263
- const stored = sessionStorage.getItem(CODE_STORAGE_KEY2);
2263
+ const stored2 = sessionStorage.getItem(CODE_STORAGE_KEY2);
2264
2264
  sessionStorage.removeItem(CODE_STORAGE_KEY2);
2265
- if (!stored) return null;
2265
+ if (!stored2) return null;
2266
2266
  try {
2267
- const parsed = JSON.parse(stored);
2267
+ const parsed = JSON.parse(stored2);
2268
2268
  if (parsed && typeof parsed === "object" && "state" in parsed) {
2269
2269
  return parsed.state;
2270
2270
  }
2271
2271
  } catch {
2272
2272
  }
2273
- return stored;
2273
+ return stored2;
2274
2274
  }
2275
2275
  function isCalendarCallback(callbackPath) {
2276
2276
  if (typeof window === "undefined") return false;
@@ -2544,8 +2544,8 @@ async function storeTokenData3(data, walletAddress) {
2544
2544
  getLogger().warn("Failed to encrypt Drive OAuth token:", error);
2545
2545
  }
2546
2546
  }
2547
- const record = { wallet: walletAddress, token: data };
2548
- sessionStorage.setItem(getTokenStorageKey3(walletAddress), JSON.stringify(record));
2547
+ const record2 = { wallet: walletAddress, token: data };
2548
+ sessionStorage.setItem(getTokenStorageKey3(walletAddress), JSON.stringify(record2));
2549
2549
  }
2550
2550
  function clearDriveToken(walletAddress) {
2551
2551
  if (typeof window === "undefined") return;
@@ -2585,17 +2585,17 @@ function getRedirectUri3(callbackPath) {
2585
2585
  }
2586
2586
  function getAndClearOAuthState3() {
2587
2587
  if (typeof window === "undefined") return null;
2588
- const stored = sessionStorage.getItem(CODE_STORAGE_KEY3);
2588
+ const stored2 = sessionStorage.getItem(CODE_STORAGE_KEY3);
2589
2589
  sessionStorage.removeItem(CODE_STORAGE_KEY3);
2590
- if (!stored) return null;
2590
+ if (!stored2) return null;
2591
2591
  try {
2592
- const parsed = JSON.parse(stored);
2592
+ const parsed = JSON.parse(stored2);
2593
2593
  if (parsed && typeof parsed === "object" && "state" in parsed) {
2594
2594
  return parsed.state;
2595
2595
  }
2596
2596
  } catch {
2597
2597
  }
2598
- return stored;
2598
+ return stored2;
2599
2599
  }
2600
2600
  function isDriveCallback(callbackPath) {
2601
2601
  if (typeof window === "undefined") return false;
@@ -2924,11 +2924,11 @@ function storePKCEState(pkce) {
2924
2924
  }
2925
2925
  function getAndClearPKCEState() {
2926
2926
  if (typeof window === "undefined") return null;
2927
- const stored = sessionStorage.getItem(PKCE_STORAGE_KEY);
2927
+ const stored2 = sessionStorage.getItem(PKCE_STORAGE_KEY);
2928
2928
  sessionStorage.removeItem(PKCE_STORAGE_KEY);
2929
- if (!stored) return null;
2929
+ if (!stored2) return null;
2930
2930
  try {
2931
- return JSON.parse(stored);
2931
+ return JSON.parse(stored2);
2932
2932
  } catch {
2933
2933
  return null;
2934
2934
  }
@@ -2946,8 +2946,8 @@ async function storeTokenData4(data, walletAddress) {
2946
2946
  } catch {
2947
2947
  }
2948
2948
  }
2949
- const record = { wallet: walletAddress, token: data };
2950
- sessionStorage.setItem(getTokenStorageKey4(walletAddress), JSON.stringify(record));
2949
+ const record2 = { wallet: walletAddress, token: data };
2950
+ sessionStorage.setItem(getTokenStorageKey4(walletAddress), JSON.stringify(record2));
2951
2951
  }
2952
2952
  async function getStoredTokenData4(walletAddress) {
2953
2953
  if (typeof window === "undefined") return null;
@@ -2963,12 +2963,12 @@ async function getStoredTokenData4(walletAddress) {
2963
2963
  cachedWalletAddress4 = null;
2964
2964
  }
2965
2965
  try {
2966
- const stored = localStorage.getItem(getTokenStorageKey4(walletAddress));
2967
- if (stored?.startsWith(ENCRYPTED_PREFIX5)) {
2966
+ const stored2 = localStorage.getItem(getTokenStorageKey4(walletAddress));
2967
+ if (stored2?.startsWith(ENCRYPTED_PREFIX5)) {
2968
2968
  if (walletAddress && hasEncryptionKey(walletAddress)) {
2969
2969
  try {
2970
2970
  const cryptoKey = await getEncryptionKey(walletAddress);
2971
- const encrypted = stored.slice(ENCRYPTED_PREFIX5.length);
2971
+ const encrypted = stored2.slice(ENCRYPTED_PREFIX5.length);
2972
2972
  const decrypted = await decryptDataWithKey(encrypted, cryptoKey);
2973
2973
  const data = JSON.parse(decrypted);
2974
2974
  if (data.accessToken) return data;
@@ -3077,12 +3077,12 @@ async function getClientRegistration(walletAddress) {
3077
3077
  if (typeof window === "undefined") return null;
3078
3078
  try {
3079
3079
  const scopedKey = getClientRegistrationStorageKey(walletAddress);
3080
- const stored = localStorage.getItem(scopedKey);
3081
- if (stored?.startsWith(ENCRYPTED_PREFIX5)) {
3080
+ const stored2 = localStorage.getItem(scopedKey);
3081
+ if (stored2?.startsWith(ENCRYPTED_PREFIX5)) {
3082
3082
  if (walletAddress && hasEncryptionKey(walletAddress)) {
3083
3083
  try {
3084
3084
  const cryptoKey = await getEncryptionKey(walletAddress);
3085
- const encrypted = stored.slice(ENCRYPTED_PREFIX5.length);
3085
+ const encrypted = stored2.slice(ENCRYPTED_PREFIX5.length);
3086
3086
  const decrypted = await decryptDataWithKey(encrypted, cryptoKey);
3087
3087
  const data = JSON.parse(decrypted);
3088
3088
  if (data.clientId) {
@@ -3092,8 +3092,8 @@ async function getClientRegistration(walletAddress) {
3092
3092
  }
3093
3093
  }
3094
3094
  }
3095
- if (stored && !stored.startsWith(ENCRYPTED_PREFIX5)) {
3096
- const data = JSON.parse(stored);
3095
+ if (stored2 && !stored2.startsWith(ENCRYPTED_PREFIX5)) {
3096
+ const data = JSON.parse(stored2);
3097
3097
  if (!data.clientId) return null;
3098
3098
  return data;
3099
3099
  }
@@ -4934,13 +4934,13 @@ async function searchMessagesOp(ctx, queryVector, options) {
4934
4934
  const topK = candidates.sort((a, b) => b.similarity - a.similarity).slice(0, limit);
4935
4935
  return Promise.all(
4936
4936
  topK.map(async ({ message, similarity }) => {
4937
- const stored = await messageRawToStored(
4937
+ const stored2 = await messageRawToStored(
4938
4938
  message,
4939
4939
  ctx.walletAddress,
4940
4940
  ctx.signMessage,
4941
4941
  ctx.embeddedWalletSigner
4942
4942
  );
4943
- return { ...stored, similarity };
4943
+ return { ...stored2, similarity };
4944
4944
  })
4945
4945
  );
4946
4946
  }
@@ -5044,13 +5044,13 @@ async function searchChunksOp(ctx, queryVector, options) {
5044
5044
  const storedById = new Map(
5045
5045
  await Promise.all(
5046
5046
  Array.from(uniqueMessages, async ([id, m]) => {
5047
- const stored = await messageRawToStored(
5047
+ const stored2 = await messageRawToStored(
5048
5048
  m,
5049
5049
  ctx.walletAddress,
5050
5050
  ctx.signMessage,
5051
5051
  ctx.embeddedWalletSigner
5052
5052
  );
5053
- return [id, stored];
5053
+ return [id, stored2];
5054
5054
  })
5055
5055
  )
5056
5056
  );
@@ -5068,18 +5068,18 @@ async function searchChunksOp(ctx, queryVector, options) {
5068
5068
  })
5069
5069
  );
5070
5070
  return topK.map(({ message, similarity, chunkTextSource }) => {
5071
- const stored = { ...storedById.get(message.id) };
5071
+ const stored2 = { ...storedById.get(message.id) };
5072
5072
  let chunkText2;
5073
5073
  if (chunkTextSource.kind === "chunk") {
5074
- chunkText2 = resolveChunkText(stored.content, chunkTextSource.chunk, chunkTextSource.siblings);
5074
+ chunkText2 = resolveChunkText(stored2.content, chunkTextSource.chunk, chunkTextSource.siblings);
5075
5075
  } else if (chunkTextSource.kind === "chunk-cached") {
5076
5076
  const state = chunkStateByMsgId.get(message.id);
5077
5077
  const chunk = state && state.version === chunkTextSource.version ? state.chunks[chunkTextSource.chunkIndex] : void 0;
5078
- chunkText2 = resolveChunkText(stored.content, chunk, state?.chunks);
5078
+ chunkText2 = resolveChunkText(stored2.content, chunk, state?.chunks);
5079
5079
  } else {
5080
- chunkText2 = stored.content;
5080
+ chunkText2 = stored2.content;
5081
5081
  }
5082
- return { chunkText: chunkText2, message: stored, similarity };
5082
+ return { chunkText: chunkText2, message: stored2, similarity };
5083
5083
  });
5084
5084
  }
5085
5085
  async function getAllFilesOp(ctx, options) {
@@ -5425,7 +5425,7 @@ async function embedOne(text12, options, outer) {
5425
5425
  }
5426
5426
  var DEFAULT_EMBEDDING_BATCH_SIZE = 100;
5427
5427
  var DEFAULT_EMBEDDING_BATCH_CONCURRENCY = 3;
5428
- async function generateEmbeddingsBatch(texts, headers, baseUrl, model, onUsage, maskInput, timeoutMs) {
5428
+ async function generateEmbeddingsBatch(texts, headers, baseUrl, model, onUsage, maskInput, timeoutMs, outer) {
5429
5429
  const response = await withEmbeddingRetry(
5430
5430
  () => withDeadline(
5431
5431
  (signal) => postApiV1Embeddings({
@@ -5435,8 +5435,10 @@ async function generateEmbeddingsBatch(texts, headers, baseUrl, model, onUsage,
5435
5435
  ...signal && { signal }
5436
5436
  }),
5437
5437
  timeoutMs,
5438
- "embedding batch request"
5439
- )
5438
+ "embedding batch request",
5439
+ outer
5440
+ ),
5441
+ outer
5440
5442
  );
5441
5443
  if (response.error) {
5442
5444
  throw embeddingErrorFrom(response);
@@ -5454,6 +5456,11 @@ async function generateEmbeddingsBatch(texts, headers, baseUrl, model, onUsage,
5454
5456
  }
5455
5457
  async function generateEmbeddings(texts, options) {
5456
5458
  if (texts.length === 0) return [];
5459
+ const total = options.totalTimeoutMs;
5460
+ if (total === void 0) return embedMany(texts, options, void 0);
5461
+ return withDeadline((signal) => embedMany(texts, options, signal), total, "embedding batch");
5462
+ }
5463
+ async function embedMany(texts, options, outer) {
5457
5464
  const { baseUrl = BASE_URL, model, batchSize, cache } = options;
5458
5465
  const timeoutMs = options.timeoutMs ?? DEFAULT_EMBEDDING_REQUEST_TIMEOUT_MS;
5459
5466
  const chunkSize = batchSize ?? DEFAULT_EMBEDDING_BATCH_SIZE;
@@ -5474,7 +5481,8 @@ async function generateEmbeddings(texts, options) {
5474
5481
  if (uncachedTexts.length === 0) {
5475
5482
  return results;
5476
5483
  }
5477
- const headers = await resolveAuthHeaders(options);
5484
+ const headers = await resolveAuthHeaders(options, outer);
5485
+ if (outer?.aborted) throw outer.reason;
5478
5486
  const embeddingModel = model ?? DEFAULT_API_EMBEDDING_MODEL;
5479
5487
  let newEmbeddings;
5480
5488
  if (uncachedTexts.length <= chunkSize) {
@@ -5485,7 +5493,8 @@ async function generateEmbeddings(texts, options) {
5485
5493
  embeddingModel,
5486
5494
  options.onUsage,
5487
5495
  options.maskInput,
5488
- timeoutMs
5496
+ timeoutMs,
5497
+ outer
5489
5498
  );
5490
5499
  } else {
5491
5500
  const chunks = [];
@@ -5496,6 +5505,7 @@ async function generateEmbeddings(texts, options) {
5496
5505
  let nextIndex = 0;
5497
5506
  const worker = async () => {
5498
5507
  while (nextIndex < chunks.length) {
5508
+ if (outer?.aborted) throw outer.reason;
5499
5509
  const idx = nextIndex++;
5500
5510
  allEmbeddings[idx] = await generateEmbeddingsBatch(
5501
5511
  chunks[idx],
@@ -5504,7 +5514,8 @@ async function generateEmbeddings(texts, options) {
5504
5514
  embeddingModel,
5505
5515
  options.onUsage,
5506
5516
  options.maskInput,
5507
- timeoutMs
5517
+ timeoutMs,
5518
+ outer
5508
5519
  );
5509
5520
  }
5510
5521
  };
@@ -5515,6 +5526,7 @@ async function generateEmbeddings(texts, options) {
5515
5526
  await Promise.all(workers);
5516
5527
  newEmbeddings = allEmbeddings.flat();
5517
5528
  }
5529
+ if (outer?.aborted) throw outer.reason;
5518
5530
  for (let i = 0; i < uncachedIndices.length; i++) {
5519
5531
  const f32Embedding = Float32Array.from(newEmbeddings[i]);
5520
5532
  results[uncachedIndices[i]] = Array.from(f32Embedding);
@@ -10674,15 +10686,15 @@ function createSummaryContext(database) {
10674
10686
  summariesCollection: database.get("conversation_summaries")
10675
10687
  };
10676
10688
  }
10677
- function modelToStored(record) {
10689
+ function modelToStored(record2) {
10678
10690
  return {
10679
- uniqueId: record.id,
10680
- conversationId: record.conversationId,
10681
- summary: record.summary,
10682
- summarizedUpTo: record.summarizedUpTo,
10683
- tokenCount: record.tokenCount,
10684
- createdAt: record.createdAt,
10685
- updatedAt: record.updatedAt
10691
+ uniqueId: record2.id,
10692
+ conversationId: record2.conversationId,
10693
+ summary: record2.summary,
10694
+ summarizedUpTo: record2.summarizedUpTo,
10695
+ tokenCount: record2.tokenCount,
10696
+ createdAt: record2.createdAt,
10697
+ updatedAt: record2.updatedAt
10686
10698
  };
10687
10699
  }
10688
10700
  async function getConversationSummaryOp(ctx, conversationId) {
@@ -10691,17 +10703,17 @@ async function getConversationSummaryOp(ctx, conversationId) {
10691
10703
  return modelToStored(results[0]);
10692
10704
  }
10693
10705
  async function upsertConversationSummaryOp(ctx, conversationId, summary, summarizedUpTo, tokenCount) {
10694
- let record;
10706
+ let record2;
10695
10707
  await ctx.database.write(async () => {
10696
10708
  const existing = await ctx.summariesCollection.query(Q3.where("conversation_id", conversationId)).fetch();
10697
10709
  if (existing.length > 0) {
10698
- record = await existing[0].update((rec) => {
10710
+ record2 = await existing[0].update((rec) => {
10699
10711
  rec.summary = summary;
10700
10712
  rec.summarizedUpTo = summarizedUpTo;
10701
10713
  rec.tokenCount = tokenCount;
10702
10714
  });
10703
10715
  } else {
10704
- record = await ctx.summariesCollection.create((rec) => {
10716
+ record2 = await ctx.summariesCollection.create((rec) => {
10705
10717
  rec.conversationId = conversationId;
10706
10718
  rec.summary = summary;
10707
10719
  rec.summarizedUpTo = summarizedUpTo;
@@ -10709,13 +10721,13 @@ async function upsertConversationSummaryOp(ctx, conversationId, summary, summari
10709
10721
  });
10710
10722
  }
10711
10723
  });
10712
- return modelToStored(record);
10724
+ return modelToStored(record2);
10713
10725
  }
10714
10726
  async function deleteConversationSummaryOp(ctx, conversationId) {
10715
10727
  await ctx.database.write(async () => {
10716
10728
  const existing = await ctx.summariesCollection.query(Q3.where("conversation_id", conversationId)).fetch();
10717
- for (const record of existing) {
10718
- await record.destroyPermanently();
10729
+ for (const record2 of existing) {
10730
+ await record2.destroyPermanently();
10719
10731
  }
10720
10732
  });
10721
10733
  }
@@ -10908,25 +10920,25 @@ async function upsertEntitiesInWrite(ctx, entities) {
10908
10920
  const kindBackfills = existing.filter((e) => {
10909
10921
  const incoming = kindByName.get(e.canonicalName);
10910
10922
  return incoming !== void 0 && (e.kind === null || e.kind === void 0 || e.kind === "");
10911
- }).map((record) => ({ record, kind: kindByName.get(record.canonicalName) }));
10923
+ }).map((record2) => ({ record: record2, kind: kindByName.get(record2.canonicalName) }));
10912
10924
  const missing = unique.filter((n) => !existingNames.has(n));
10913
10925
  const created = missing.map(
10914
- (name) => ctx.entityCollection.prepareCreate((record) => {
10915
- record._setRaw("canonical_name", name);
10926
+ (name) => ctx.entityCollection.prepareCreate((record2) => {
10927
+ record2._setRaw("canonical_name", name);
10916
10928
  const kind = kindByName.get(name);
10917
- if (kind !== void 0) record._setRaw("kind", kind);
10929
+ if (kind !== void 0) record2._setRaw("kind", kind);
10918
10930
  })
10919
10931
  );
10920
10932
  for (const e of existing) out.set(e.canonicalName, entityToStored(e));
10921
- for (const record of created) out.set(record.canonicalName, entityToStored(record));
10922
- for (const { record, kind } of kindBackfills) {
10923
- out.set(record.canonicalName, { ...entityToStored(record), kind });
10933
+ for (const record2 of created) out.set(record2.canonicalName, entityToStored(record2));
10934
+ for (const { record: record2, kind } of kindBackfills) {
10935
+ out.set(record2.canonicalName, { ...entityToStored(record2), kind });
10924
10936
  }
10925
10937
  return { entities: out, operations: created, kindBackfills };
10926
10938
  }
10927
10939
  function prepareKindBackfills(backfills) {
10928
10940
  return backfills.map(
10929
- ({ record, kind }) => record.prepareUpdate((r) => {
10941
+ ({ record: record2, kind }) => record2.prepareUpdate((r) => {
10930
10942
  r._setRaw("kind", kind);
10931
10943
  })
10932
10944
  );
@@ -10957,10 +10969,10 @@ function displayNamesOf(entities) {
10957
10969
  }
10958
10970
  return out;
10959
10971
  }
10960
- function topicsEqual(stored, computed) {
10961
- if (stored === null || stored.length !== computed.length) return false;
10972
+ function topicsEqual(stored2, computed) {
10973
+ if (stored2 === null || stored2.length !== computed.length) return false;
10962
10974
  const key = (t) => JSON.stringify([t.name, t.kind ?? null, t.source]);
10963
- const storedKeys = stored.map(key).sort();
10975
+ const storedKeys = stored2.map(key).sort();
10964
10976
  const computedKeys = computed.map(key).sort();
10965
10977
  return storedKeys.every((k, i) => k === computedKeys[i]);
10966
10978
  }
@@ -11026,10 +11038,10 @@ async function linkMemoryEntitiesOp(ctx, memoryId, entityInputs, options) {
11026
11038
  return;
11027
11039
  }
11028
11040
  const linkOps = toCreate.map(
11029
- (e) => ctx.memoryEntityCollection.prepareCreate((record) => {
11030
- record._setRaw("memory_id", memoryId);
11031
- record._setRaw("entity_id", e.uniqueId);
11032
- if (userId !== void 0) record._setRaw("user_id", userId);
11041
+ (e) => ctx.memoryEntityCollection.prepareCreate((record2) => {
11042
+ record2._setRaw("memory_id", memoryId);
11043
+ record2._setRaw("entity_id", e.uniqueId);
11044
+ if (userId !== void 0) record2._setRaw("user_id", userId);
11033
11045
  })
11034
11046
  );
11035
11047
  await ctx.database.batch(
@@ -11097,10 +11109,10 @@ async function replaceMemoryEntities(ctx, memoryId, entityInputs, options) {
11097
11109
  ...entityOps,
11098
11110
  ...prepareKindBackfills(kindBackfills),
11099
11111
  ...toCreate.map(
11100
- (e) => ctx.memoryEntityCollection.prepareCreate((record) => {
11101
- record._setRaw("memory_id", memoryId);
11102
- record._setRaw("entity_id", e.uniqueId);
11103
- if (userId !== void 0) record._setRaw("user_id", userId);
11112
+ (e) => ctx.memoryEntityCollection.prepareCreate((record2) => {
11113
+ record2._setRaw("memory_id", memoryId);
11114
+ record2._setRaw("entity_id", e.uniqueId);
11115
+ if (userId !== void 0) record2._setRaw("user_id", userId);
11104
11116
  })
11105
11117
  ),
11106
11118
  ...toDestroy.map((l) => l.prepareDestroyPermanently()),
@@ -13172,13 +13184,13 @@ async function relinkMisclassifiedVideosOp(ctx, walletAddress) {
13172
13184
  toRelink.push({ media, ext: mime.split("/")[1] || "mp4" });
13173
13185
  continue;
13174
13186
  }
13175
- const stored = await mediaToStored(
13187
+ const stored2 = await mediaToStored(
13176
13188
  media,
13177
13189
  ctx.walletAddress,
13178
13190
  ctx.signMessage,
13179
13191
  ctx.embeddedWalletSigner
13180
13192
  );
13181
- const ext = videoExtensionOf(stored.sourceUrl) ?? videoExtensionOf(stored.name);
13193
+ const ext = videoExtensionOf(stored2.sourceUrl) ?? videoExtensionOf(stored2.name);
13182
13194
  if (ext) {
13183
13195
  toRelink.push({ media, ext });
13184
13196
  }
@@ -13474,8 +13486,8 @@ function visibilityConditions(requested) {
13474
13486
  if (excluded.length === 0) return [];
13475
13487
  return [Q8.or(Q8.where("visibility", null), Q8.where("visibility", Q8.notIn(excluded)))];
13476
13488
  }
13477
- function isOwnedByCtxUser(ctx, record) {
13478
- return ctx.userId === void 0 || record.userId === ctx.userId;
13489
+ function isOwnedByCtxUser(ctx, record2) {
13490
+ return ctx.userId === void 0 || record2.userId === ctx.userId;
13479
13491
  }
13480
13492
  function baseVaultConditions(ctx, options) {
13481
13493
  return [
@@ -13555,39 +13567,39 @@ async function vaultMemoryToStored(memory, walletAddress, signMessage, embeddedW
13555
13567
  }
13556
13568
  return raw;
13557
13569
  }
13558
- function populateNewVaultMemory(record, ctx, opts, encryptedContent) {
13559
- record._setRaw("content", encryptedContent);
13560
- record._setRaw("scope", opts.scope ?? "private");
13561
- record._setRaw("folder_id", opts.folderId ?? null);
13562
- record._setRaw("user_id", ctx.userId ?? null);
13563
- record._setRaw("is_deleted", false);
13570
+ function populateNewVaultMemory(record2, ctx, opts, encryptedContent) {
13571
+ record2._setRaw("content", encryptedContent);
13572
+ record2._setRaw("scope", opts.scope ?? "private");
13573
+ record2._setRaw("folder_id", opts.folderId ?? null);
13574
+ record2._setRaw("user_id", ctx.userId ?? null);
13575
+ record2._setRaw("is_deleted", false);
13564
13576
  if (opts.embedding !== void 0) {
13565
- record._setRaw("embedding", opts.embedding);
13566
- record._setRaw("embedding_model", opts.embeddingModel ?? null);
13577
+ record2._setRaw("embedding", opts.embedding);
13578
+ record2._setRaw("embedding_model", opts.embeddingModel ?? null);
13567
13579
  }
13568
13580
  if (opts.sourceChunkIds !== void 0) {
13569
- record._setRaw("source_chunk_ids", JSON.stringify(opts.sourceChunkIds));
13581
+ record2._setRaw("source_chunk_ids", JSON.stringify(opts.sourceChunkIds));
13570
13582
  }
13571
- record._setRaw("proof_count", opts.proofCount ?? 1);
13572
- record._setRaw("source", opts.source ?? "manual");
13583
+ record2._setRaw("proof_count", opts.proofCount ?? 1);
13584
+ record2._setRaw("source", opts.source ?? "manual");
13573
13585
  if (opts.eventTime) {
13574
- record._setRaw("event_time_start", opts.eventTime.start ?? null);
13575
- record._setRaw("event_time_end", opts.eventTime.end ?? null);
13576
- record._setRaw("event_time_kind", opts.eventTime.kind ?? null);
13586
+ record2._setRaw("event_time_start", opts.eventTime.start ?? null);
13587
+ record2._setRaw("event_time_end", opts.eventTime.end ?? null);
13588
+ record2._setRaw("event_time_kind", opts.eventTime.kind ?? null);
13577
13589
  }
13578
13590
  if (opts.factType !== void 0) {
13579
- record._setRaw("fact_type", opts.factType);
13591
+ record2._setRaw("fact_type", opts.factType);
13580
13592
  }
13581
13593
  if (opts.trustTier !== void 0) {
13582
- record._setRaw("trust_tier", normalizeTrustTier(opts.trustTier));
13594
+ record2._setRaw("trust_tier", normalizeTrustTier(opts.trustTier));
13583
13595
  }
13584
- record._setRaw("visibility", opts.visibility ?? "private");
13585
- record._setRaw(
13596
+ record2._setRaw("visibility", opts.visibility ?? "private");
13597
+ record2._setRaw(
13586
13598
  "published_at",
13587
13599
  opts.visibility && opts.visibility !== "private" ? opts.publishedAt ?? Date.now() : null
13588
13600
  );
13589
13601
  if (opts.geohash !== void 0) {
13590
- record._setRaw("geohash", opts.geohash);
13602
+ record2._setRaw("geohash", opts.geohash);
13591
13603
  }
13592
13604
  }
13593
13605
  async function createVaultMemoryOp(ctx, opts) {
@@ -13601,7 +13613,7 @@ async function createVaultMemoryOp(ctx, opts) {
13601
13613
  if (ctx.canWrite && !await ctx.canWrite())
13602
13614
  throw new Error("Memory source is no longer eligible");
13603
13615
  return ctx.vaultMemoryCollection.create(
13604
- (record) => populateNewVaultMemory(record, ctx, opts, encryptedContent)
13616
+ (record2) => populateNewVaultMemory(record2, ctx, opts, encryptedContent)
13605
13617
  );
13606
13618
  });
13607
13619
  return vaultMemoryToStored(created, ctx.walletAddress, ctx.signMessage, ctx.embeddedWalletSigner);
@@ -13626,7 +13638,7 @@ async function createSupersedingMemoryOp(ctx, opts, targetId) {
13626
13638
  }
13627
13639
  if (target.isDeleted || target.supersededBy || !isOwnedByCtxUser(ctx, target)) return;
13628
13640
  createdRecord = await ctx.vaultMemoryCollection.create(
13629
- (record) => populateNewVaultMemory(record, ctx, opts, encryptedContent)
13641
+ (record2) => populateNewVaultMemory(record2, ctx, opts, encryptedContent)
13630
13642
  );
13631
13643
  await target.update((r) => {
13632
13644
  r._setRaw("superseded_by", createdRecord.id);
@@ -13708,7 +13720,7 @@ async function createVaultMemoriesBatchOp(ctx, optionsArray) {
13708
13720
  throw new Error("Memory source is no longer eligible");
13709
13721
  const prepared = optionsArray.map(
13710
13722
  (opts, i) => ctx.vaultMemoryCollection.prepareCreate(
13711
- (record) => populateNewVaultMemory(record, ctx, opts, encryptedContents[i])
13723
+ (record2) => populateNewVaultMemory(record2, ctx, opts, encryptedContents[i])
13712
13724
  )
13713
13725
  );
13714
13726
  await ctx.database.batch(...prepared);
@@ -13716,16 +13728,16 @@ async function createVaultMemoriesBatchOp(ctx, optionsArray) {
13716
13728
  });
13717
13729
  return Promise.all(
13718
13730
  created.map(
13719
- (record) => vaultMemoryToStored(record, ctx.walletAddress, ctx.signMessage, ctx.embeddedWalletSigner)
13731
+ (record2) => vaultMemoryToStored(record2, ctx.walletAddress, ctx.signMessage, ctx.embeddedWalletSigner)
13720
13732
  )
13721
13733
  );
13722
13734
  }
13723
13735
  async function getVaultMemoryOp(ctx, id) {
13724
13736
  try {
13725
- const record = await ctx.vaultMemoryCollection.find(id);
13726
- if (record.isDeleted || !isOwnedByCtxUser(ctx, record)) return null;
13737
+ const record2 = await ctx.vaultMemoryCollection.find(id);
13738
+ if (record2.isDeleted || !isOwnedByCtxUser(ctx, record2)) return null;
13727
13739
  return vaultMemoryToStored(
13728
- record,
13740
+ record2,
13729
13741
  ctx.walletAddress,
13730
13742
  ctx.signMessage,
13731
13743
  ctx.embeddedWalletSigner
@@ -13783,11 +13795,11 @@ function vaultMemoryRawToStoredRaw(raw) {
13783
13795
  };
13784
13796
  }
13785
13797
  async function vaultMemoryRawToStored(raw, walletAddress, signMessage, embeddedWalletSigner) {
13786
- const stored = vaultMemoryRawToStoredRaw(raw);
13798
+ const stored2 = vaultMemoryRawToStoredRaw(raw);
13787
13799
  if (walletAddress) {
13788
- return decryptVaultMemoryFields(stored, walletAddress, signMessage, embeddedWalletSigner);
13800
+ return decryptVaultMemoryFields(stored2, walletAddress, signMessage, embeddedWalletSigner);
13789
13801
  }
13790
- return stored;
13802
+ return stored2;
13791
13803
  }
13792
13804
  async function getAllVaultMemoriesOp(ctx, options) {
13793
13805
  const conditions = [
@@ -13939,13 +13951,13 @@ async function getVaultMemoriesByIdsOp(ctx, ids, options) {
13939
13951
  async function getAllVaultMemoryContentsOp(ctx, options) {
13940
13952
  const results = await ctx.vaultMemoryCollection.query(...baseVaultConditions(ctx, options)).unsafeFetchRaw();
13941
13953
  return mapInBatches(results, async (raw) => {
13942
- const stored = await vaultMemoryRawToStored(
13954
+ const stored2 = await vaultMemoryRawToStored(
13943
13955
  raw,
13944
13956
  ctx.walletAddress,
13945
13957
  ctx.signMessage,
13946
13958
  ctx.embeddedWalletSigner
13947
13959
  );
13948
- return stored.content;
13960
+ return stored2.content;
13949
13961
  });
13950
13962
  }
13951
13963
  async function countActiveVaultMemoriesOp(ctx) {
@@ -13967,12 +13979,12 @@ async function updateVaultMemoryOp(ctx, id, opts) {
13967
13979
  ctx.embeddedWalletSigner
13968
13980
  ) : opts.content;
13969
13981
  let stale = false;
13970
- const record = probe;
13971
- const originalUpdatedAt = record.updatedAt.getTime();
13982
+ const record2 = probe;
13983
+ const originalUpdatedAt = record2.updatedAt.getTime();
13972
13984
  await ctx.database.write(async () => {
13973
13985
  if (ctx.canWrite && !await ctx.canWrite())
13974
13986
  throw new Error("Memory source is no longer eligible");
13975
- if (record.isDeleted || record.supersededBy || !isOwnedByCtxUser(ctx, record)) {
13987
+ if (record2.isDeleted || record2.supersededBy || !isOwnedByCtxUser(ctx, record2)) {
13976
13988
  stale = true;
13977
13989
  return;
13978
13990
  }
@@ -13980,14 +13992,14 @@ async function updateVaultMemoryOp(ctx, id, opts) {
13980
13992
  let replayedObservation = false;
13981
13993
  if (opts.observationSourceIds?.length) {
13982
13994
  try {
13983
- const parsed = JSON.parse(record.sourceChunkIds ?? "[]");
13995
+ const parsed = JSON.parse(record2.sourceChunkIds ?? "[]");
13984
13996
  if (Array.isArray(parsed))
13985
13997
  observedSources = parsed.filter((id2) => typeof id2 === "string");
13986
13998
  } catch {
13987
13999
  }
13988
14000
  replayedObservation = opts.observationSourceIds.every((id2) => observedSources.includes(id2));
13989
14001
  }
13990
- await record.update((r) => {
14002
+ await record2.update((r) => {
13991
14003
  r._setRaw("content", encryptedContent);
13992
14004
  if (opts.scope !== void 0) {
13993
14005
  r._setRaw("scope", opts.scope);
@@ -14044,7 +14056,7 @@ async function updateVaultMemoryOp(ctx, id, opts) {
14044
14056
  });
14045
14057
  if (stale) return null;
14046
14058
  return vaultMemoryToStored(
14047
- record,
14059
+ record2,
14048
14060
  ctx.walletAddress,
14049
14061
  ctx.signMessage,
14050
14062
  ctx.embeddedWalletSigner
@@ -14058,21 +14070,21 @@ async function setMemoryEntitiesOp(ctx, memoryId, entities) {
14058
14070
  if (!entityCtx) {
14059
14071
  throw new Error("setMemoryEntitiesOp requires ctx.entityCtx (entity collections)");
14060
14072
  }
14061
- let record;
14073
+ let record2;
14062
14074
  try {
14063
- record = await ctx.vaultMemoryCollection.find(memoryId);
14075
+ record2 = await ctx.vaultMemoryCollection.find(memoryId);
14064
14076
  } catch {
14065
14077
  return null;
14066
14078
  }
14067
- if (record.isDeleted || !isOwnedByCtxUser(ctx, record)) return null;
14079
+ if (record2.isDeleted || !isOwnedByCtxUser(ctx, record2)) return null;
14068
14080
  let stale = false;
14069
- const originalUpdatedAt = record.updatedAt.getTime();
14081
+ const originalUpdatedAt = record2.updatedAt.getTime();
14070
14082
  await ctx.database.write(async (writer) => {
14071
- if (record.isDeleted || !isOwnedByCtxUser(ctx, record)) {
14083
+ if (record2.isDeleted || !isOwnedByCtxUser(ctx, record2)) {
14072
14084
  stale = true;
14073
14085
  return;
14074
14086
  }
14075
- await record.update((r) => {
14087
+ await record2.update((r) => {
14076
14088
  r._setRaw("topics_user_managed", true);
14077
14089
  r._setRaw("updated_at", originalUpdatedAt);
14078
14090
  });
@@ -14096,25 +14108,25 @@ async function setMemoryEntitiesOp(ctx, memoryId, entities) {
14096
14108
  );
14097
14109
  });
14098
14110
  if (stale) return null;
14099
- return vaultMemoryToStored(record, ctx.walletAddress, ctx.signMessage, ctx.embeddedWalletSigner);
14111
+ return vaultMemoryToStored(record2, ctx.walletAddress, ctx.signMessage, ctx.embeddedWalletSigner);
14100
14112
  }
14101
14113
  async function clearMemoryTopicsOverrideOp(ctx, memoryId, options) {
14102
- let record;
14114
+ let record2;
14103
14115
  try {
14104
- record = await ctx.vaultMemoryCollection.find(memoryId);
14116
+ record2 = await ctx.vaultMemoryCollection.find(memoryId);
14105
14117
  } catch {
14106
14118
  return false;
14107
14119
  }
14108
- if (record.isDeleted || !isOwnedByCtxUser(ctx, record)) return false;
14109
- const originalUpdatedAt = record.updatedAt.getTime();
14120
+ if (record2.isDeleted || !isOwnedByCtxUser(ctx, record2)) return false;
14121
+ const originalUpdatedAt = record2.updatedAt.getTime();
14110
14122
  let cleared = false;
14111
14123
  await ctx.database.write(async () => {
14112
- if (options?.unlessTopicsRecorded && parseTopics(record.topics) !== null) return;
14124
+ if (options?.unlessTopicsRecorded && parseTopics(record2.topics) !== null) return;
14113
14125
  cleared = true;
14114
- await record.update((r) => {
14126
+ await record2.update((r) => {
14115
14127
  r._setRaw("topics_user_managed", false);
14116
14128
  r._setRaw("topics_extracted_version", null);
14117
- if (record.topicsExtractedAt === null) {
14129
+ if (record2.topicsExtractedAt === null) {
14118
14130
  r._setRaw("topics_extracted_at", originalUpdatedAt);
14119
14131
  }
14120
14132
  r._setRaw("updated_at", originalUpdatedAt);
@@ -14123,22 +14135,22 @@ async function clearMemoryTopicsOverrideOp(ctx, memoryId, options) {
14123
14135
  return cleared;
14124
14136
  }
14125
14137
  async function setMemoryVisibilityOp(ctx, id, opts) {
14126
- let record;
14138
+ let record2;
14127
14139
  try {
14128
- record = await ctx.vaultMemoryCollection.find(id);
14140
+ record2 = await ctx.vaultMemoryCollection.find(id);
14129
14141
  } catch {
14130
14142
  return null;
14131
14143
  }
14132
- if (record.isDeleted || !isOwnedByCtxUser(ctx, record)) return null;
14144
+ if (record2.isDeleted || !isOwnedByCtxUser(ctx, record2)) return null;
14133
14145
  let stale = false;
14134
14146
  await ctx.database.write(async () => {
14135
- if (record.isDeleted || !isOwnedByCtxUser(ctx, record)) {
14147
+ if (record2.isDeleted || !isOwnedByCtxUser(ctx, record2)) {
14136
14148
  stale = true;
14137
14149
  return;
14138
14150
  }
14139
- const currentUpdatedAt = record.updatedAt.getTime();
14140
- const currentPublishedAt = record.publishedAt ?? null;
14141
- await record.update((r) => {
14151
+ const currentUpdatedAt = record2.updatedAt.getTime();
14152
+ const currentPublishedAt = record2.publishedAt ?? null;
14153
+ await record2.update((r) => {
14142
14154
  r._setRaw("visibility", opts.visibility);
14143
14155
  if (opts.visibility === "private") {
14144
14156
  r._setRaw("published_at", null);
@@ -14152,19 +14164,19 @@ async function setMemoryVisibilityOp(ctx, id, opts) {
14152
14164
  });
14153
14165
  });
14154
14166
  if (stale) return null;
14155
- return vaultMemoryToStored(record, ctx.walletAddress, ctx.signMessage, ctx.embeddedWalletSigner);
14167
+ return vaultMemoryToStored(record2, ctx.walletAddress, ctx.signMessage, ctx.embeddedWalletSigner);
14156
14168
  }
14157
14169
  async function deleteVaultMemoryOp(ctx, id) {
14158
14170
  try {
14159
- const record = await ctx.vaultMemoryCollection.find(id);
14160
- if (record.isDeleted || !isOwnedByCtxUser(ctx, record)) return false;
14171
+ const record2 = await ctx.vaultMemoryCollection.find(id);
14172
+ if (record2.isDeleted || !isOwnedByCtxUser(ctx, record2)) return false;
14161
14173
  let stale = false;
14162
14174
  await ctx.database.write(async () => {
14163
- if (record.isDeleted || !isOwnedByCtxUser(ctx, record)) {
14175
+ if (record2.isDeleted || !isOwnedByCtxUser(ctx, record2)) {
14164
14176
  stale = true;
14165
14177
  return;
14166
14178
  }
14167
- await record.update((r) => {
14179
+ await record2.update((r) => {
14168
14180
  r._setRaw("is_deleted", true);
14169
14181
  });
14170
14182
  });
@@ -14183,8 +14195,8 @@ async function deleteVaultMemoryOp(ctx, id) {
14183
14195
  async function supersedeVaultMemoryOp(ctx, id, supersededById) {
14184
14196
  if (id === supersededById) return false;
14185
14197
  try {
14186
- const record = await ctx.vaultMemoryCollection.find(id);
14187
- if (record.isDeleted || record.supersededBy || !isOwnedByCtxUser(ctx, record)) return false;
14198
+ const record2 = await ctx.vaultMemoryCollection.find(id);
14199
+ if (record2.isDeleted || record2.supersededBy || !isOwnedByCtxUser(ctx, record2)) return false;
14188
14200
  let successor;
14189
14201
  try {
14190
14202
  successor = await ctx.vaultMemoryCollection.find(supersededById);
@@ -14198,7 +14210,7 @@ async function supersedeVaultMemoryOp(ctx, id, supersededById) {
14198
14210
  await ctx.database.write(async () => {
14199
14211
  if (ctx.canWrite && !await ctx.canWrite())
14200
14212
  throw new Error("Memory source is no longer eligible");
14201
- if (record.isDeleted || record.supersededBy || !isOwnedByCtxUser(ctx, record)) {
14213
+ if (record2.isDeleted || record2.supersededBy || !isOwnedByCtxUser(ctx, record2)) {
14202
14214
  stale = true;
14203
14215
  return;
14204
14216
  }
@@ -14206,7 +14218,7 @@ async function supersedeVaultMemoryOp(ctx, id, supersededById) {
14206
14218
  stale = true;
14207
14219
  return;
14208
14220
  }
14209
- await record.update((r) => {
14221
+ await record2.update((r) => {
14210
14222
  r._setRaw("superseded_by", supersededById);
14211
14223
  r._setRaw("superseded_at", Date.now());
14212
14224
  });
@@ -14225,7 +14237,7 @@ async function getUnfiledVaultMemoriesOp(ctx) {
14225
14237
  const results = await ctx.vaultMemoryCollection.query(...conditions).fetch();
14226
14238
  return mapInBatches(
14227
14239
  results,
14228
- (record) => vaultMemoryToStored(record, ctx.walletAddress, ctx.signMessage, ctx.embeddedWalletSigner)
14240
+ (record2) => vaultMemoryToStored(record2, ctx.walletAddress, ctx.signMessage, ctx.embeddedWalletSigner)
14229
14241
  );
14230
14242
  }
14231
14243
  var TOPICS_EXTRACTION_VERSION = 3;
@@ -14367,17 +14379,17 @@ async function stampTopicsExtractedAtOp(ctx, memoryIds, extractedAt, version = T
14367
14379
  }
14368
14380
  }
14369
14381
  const eligible = records.filter(
14370
- (record) => !record.isDeleted && isOwnedByCtxUser(ctx, record) && !record.topicsUserManaged
14382
+ (record2) => !record2.isDeleted && isOwnedByCtxUser(ctx, record2) && !record2.topicsUserManaged
14371
14383
  );
14372
- const prepared = eligible.map((record) => {
14373
- const originalUpdatedAt = record.updatedAt.getTime();
14374
- return record.prepareUpdate((r) => {
14384
+ const prepared = eligible.map((record2) => {
14385
+ const originalUpdatedAt = record2.updatedAt.getTime();
14386
+ return record2.prepareUpdate((r) => {
14375
14387
  r._setRaw("topics_extracted_at", extractedAt);
14376
14388
  r._setRaw("topics_extracted_version", version);
14377
14389
  r._setRaw("updated_at", originalUpdatedAt);
14378
14390
  });
14379
14391
  });
14380
- for (const record of eligible) stamped.push(record.id);
14392
+ for (const record2 of eligible) stamped.push(record2.id);
14381
14393
  if (prepared.length > 0) await ctx.database.batch(...prepared);
14382
14394
  });
14383
14395
  }
@@ -14392,14 +14404,14 @@ async function relinkMemoryTopicsOp(ctx, memoryIds) {
14392
14404
  for (const id of Array.from(new Set(memoryIds))) {
14393
14405
  try {
14394
14406
  await ctx.database.write(async (writer) => {
14395
- let record;
14407
+ let record2;
14396
14408
  try {
14397
- record = await ctx.vaultMemoryCollection.find(id);
14409
+ record2 = await ctx.vaultMemoryCollection.find(id);
14398
14410
  } catch {
14399
14411
  return;
14400
14412
  }
14401
- if (record.isDeleted || !isOwnedByCtxUser(ctx, record)) return;
14402
- const topics = parseTopics(record.topics);
14413
+ if (record2.isDeleted || !isOwnedByCtxUser(ctx, record2)) return;
14414
+ const topics = parseTopics(record2.topics);
14403
14415
  if (topics === null) return;
14404
14416
  await writer.callWriter(() => relinkMemoryEntitiesFromTopicsOp(entityCtx, id, topics));
14405
14417
  relinked.push(id);
@@ -14424,20 +14436,20 @@ async function backfillMemoryTopicsOp(ctx, memoryIds) {
14424
14436
  await ctx.database.write(async () => {
14425
14437
  const writes = [];
14426
14438
  for (const id of chunkIds) {
14427
- let record;
14439
+ let record2;
14428
14440
  try {
14429
- record = await ctx.vaultMemoryCollection.find(id);
14441
+ record2 = await ctx.vaultMemoryCollection.find(id);
14430
14442
  } catch {
14431
14443
  continue;
14432
14444
  }
14433
- if (record.isDeleted || !isOwnedByCtxUser(ctx, record)) continue;
14434
- if (parseTopics(record.topics) !== null) continue;
14445
+ if (record2.isDeleted || !isOwnedByCtxUser(ctx, record2)) continue;
14446
+ if (parseTopics(record2.topics) !== null) continue;
14435
14447
  const links = await entityCtx.memoryEntityCollection.query(Q8.where("memory_id", id)).unsafeFetchRaw();
14436
14448
  const entityIds = links.map((l) => String(l.entity_id));
14437
14449
  if (entityIds.length === 0) continue;
14438
14450
  const entities = await entityCtx.entityCollection.query(Q8.where("id", Q8.oneOf(entityIds))).fetch();
14439
14451
  if (entities.length === 0) continue;
14440
- const source = record.topicsUserManaged ? "user" : "auto";
14452
+ const source = record2.topicsUserManaged ? "user" : "auto";
14441
14453
  const write = await resolveMemoryTopicsWrite(entityCtx, id, entities, [], source);
14442
14454
  if (write) writes.push(write);
14443
14455
  }
@@ -14455,7 +14467,7 @@ async function deleteAllVaultMemoriesForUserOp(ctx, userId) {
14455
14467
  if (records.length === 0) return 0;
14456
14468
  await ctx.database.write(async () => {
14457
14469
  const prepared = records.map(
14458
- (record) => record.prepareUpdate((r) => {
14470
+ (record2) => record2.prepareUpdate((r) => {
14459
14471
  r._setRaw("is_deleted", true);
14460
14472
  })
14461
14473
  );
@@ -14500,20 +14512,20 @@ async function getDecayCandidatesRawOp(ctx) {
14500
14512
  }
14501
14513
  async function archiveVaultMemoryOp(ctx, id, opts) {
14502
14514
  try {
14503
- const record = await ctx.vaultMemoryCollection.find(id);
14504
- if (record.isDeleted || !isOwnedByCtxUser(ctx, record)) return false;
14515
+ const record2 = await ctx.vaultMemoryCollection.find(id);
14516
+ if (record2.isDeleted || !isOwnedByCtxUser(ctx, record2)) return false;
14505
14517
  let stale = false;
14506
14518
  const archivedAtValue = opts?.now ?? Date.now();
14507
14519
  await ctx.database.write(async () => {
14508
- if (record.isDeleted || !isOwnedByCtxUser(ctx, record) || record.archivedAt !== null) {
14520
+ if (record2.isDeleted || !isOwnedByCtxUser(ctx, record2) || record2.archivedAt !== null) {
14509
14521
  stale = true;
14510
14522
  return;
14511
14523
  }
14512
- if (opts?.expectedUpdatedAt !== void 0 && record.updatedAt.getTime() !== opts.expectedUpdatedAt || opts?.expectedLastObservedAt !== void 0 && (record.lastObservedAt ?? null) !== opts.expectedLastObservedAt) {
14524
+ if (opts?.expectedUpdatedAt !== void 0 && record2.updatedAt.getTime() !== opts.expectedUpdatedAt || opts?.expectedLastObservedAt !== void 0 && (record2.lastObservedAt ?? null) !== opts.expectedLastObservedAt) {
14513
14525
  stale = true;
14514
14526
  return;
14515
14527
  }
14516
- await record.update((r) => {
14528
+ await record2.update((r) => {
14517
14529
  r._setRaw("archived_at", archivedAtValue);
14518
14530
  });
14519
14531
  });
@@ -14524,15 +14536,15 @@ async function archiveVaultMemoryOp(ctx, id, opts) {
14524
14536
  }
14525
14537
  async function restoreVaultMemoryOp(ctx, id) {
14526
14538
  try {
14527
- const record = await ctx.vaultMemoryCollection.find(id);
14528
- if (record.isDeleted || !isOwnedByCtxUser(ctx, record)) return false;
14539
+ const record2 = await ctx.vaultMemoryCollection.find(id);
14540
+ if (record2.isDeleted || !isOwnedByCtxUser(ctx, record2)) return false;
14529
14541
  let stale = false;
14530
14542
  await ctx.database.write(async () => {
14531
- if (record.isDeleted || !isOwnedByCtxUser(ctx, record)) {
14543
+ if (record2.isDeleted || !isOwnedByCtxUser(ctx, record2)) {
14532
14544
  stale = true;
14533
14545
  return;
14534
14546
  }
14535
- await record.update((r) => {
14547
+ await record2.update((r) => {
14536
14548
  r._setRaw("archived_at", null);
14537
14549
  });
14538
14550
  });
@@ -14543,17 +14555,17 @@ async function restoreVaultMemoryOp(ctx, id) {
14543
14555
  }
14544
14556
  async function hardDeleteDecayedOp(ctx, id, opts) {
14545
14557
  try {
14546
- const record = await ctx.vaultMemoryCollection.find(id);
14547
- if (record.isDeleted || !isOwnedByCtxUser(ctx, record)) return false;
14558
+ const record2 = await ctx.vaultMemoryCollection.find(id);
14559
+ if (record2.isDeleted || !isOwnedByCtxUser(ctx, record2)) return false;
14548
14560
  const now = opts.now ?? Date.now();
14549
14561
  let stale = false;
14550
14562
  await ctx.database.write(async () => {
14551
- const archivedAt = record.archivedAt;
14552
- if (record.isDeleted || !isOwnedByCtxUser(ctx, record) || archivedAt === null || now - archivedAt <= opts.hardDeleteWindowMs) {
14563
+ const archivedAt = record2.archivedAt;
14564
+ if (record2.isDeleted || !isOwnedByCtxUser(ctx, record2) || archivedAt === null || now - archivedAt <= opts.hardDeleteWindowMs) {
14553
14565
  stale = true;
14554
14566
  return;
14555
14567
  }
14556
- await record.update((r) => {
14568
+ await record2.update((r) => {
14557
14569
  r._setRaw("is_deleted", true);
14558
14570
  });
14559
14571
  });
@@ -14571,14 +14583,14 @@ async function hardDeleteDecayedOp(ctx, id, opts) {
14571
14583
  }
14572
14584
  async function updateVaultMemoryEmbeddingOp(ctx, id, embedding, embeddingModel, expected) {
14573
14585
  try {
14574
- const record = await ctx.vaultMemoryCollection.find(id);
14575
- if (record.isDeleted || !isOwnedByCtxUser(ctx, record)) return false;
14576
- const readUpdatedAt = record.updatedAt.getTime();
14577
- const readStoredContent = record._getRaw("content");
14586
+ const record2 = await ctx.vaultMemoryCollection.find(id);
14587
+ if (record2.isDeleted || !isOwnedByCtxUser(ctx, record2)) return false;
14588
+ const readUpdatedAt = record2.updatedAt.getTime();
14589
+ const readStoredContent = record2._getRaw("content");
14578
14590
  if (expected?.updatedAt !== void 0 && expected.updatedAt !== readUpdatedAt) return false;
14579
14591
  if (expected?.content !== void 0) {
14580
14592
  const current = await vaultMemoryToStored(
14581
- record,
14593
+ record2,
14582
14594
  ctx.walletAddress,
14583
14595
  ctx.signMessage,
14584
14596
  ctx.embeddedWalletSigner
@@ -14587,11 +14599,11 @@ async function updateVaultMemoryEmbeddingOp(ctx, id, embedding, embeddingModel,
14587
14599
  }
14588
14600
  let written = false;
14589
14601
  await ctx.database.write(async () => {
14590
- if (record.isDeleted || !isOwnedByCtxUser(ctx, record)) return;
14591
- const originalUpdatedAt = record.updatedAt.getTime();
14592
- if (originalUpdatedAt !== readUpdatedAt || record._getRaw("content") !== readStoredContent)
14602
+ if (record2.isDeleted || !isOwnedByCtxUser(ctx, record2)) return;
14603
+ const originalUpdatedAt = record2.updatedAt.getTime();
14604
+ if (originalUpdatedAt !== readUpdatedAt || record2._getRaw("content") !== readStoredContent)
14593
14605
  return;
14594
- await record.update((r) => {
14606
+ await record2.update((r) => {
14595
14607
  r._setRaw("embedding", embedding);
14596
14608
  r._setRaw("embedding_model", embeddingModel);
14597
14609
  r._setRaw("updated_at", originalUpdatedAt);
@@ -14606,8 +14618,8 @@ async function updateVaultMemoryEmbeddingOp(ctx, id, embedding, embeddingModel,
14606
14618
  function normalizeForDedupe(content) {
14607
14619
  return content.normalize("NFKC").trim().replace(/\s+/g, " ").toLowerCase();
14608
14620
  }
14609
- async function findQuarantinedDuplicateOp(ctx, content, sourceIds, where) {
14610
- const wanted = [...new Set(sourceIds)].sort().join("\0");
14621
+ async function findQuarantinedDuplicateOp(ctx, content, sourceIds2, where) {
14622
+ const wanted = [...new Set(sourceIds2)].sort().join("\0");
14611
14623
  const target = normalizeForDedupe(content);
14612
14624
  const rows = await ctx.vaultMemoryCollection.query(
14613
14625
  Q8.where("trust_tier", "quarantined"),
@@ -14626,13 +14638,13 @@ async function findQuarantinedDuplicateOp(ctx, content, sourceIds, where) {
14626
14638
  if (!Array.isArray(ids)) continue;
14627
14639
  const key = [...new Set(ids.filter((id) => typeof id === "string"))].sort().join("\0");
14628
14640
  if (key !== wanted) continue;
14629
- const stored = await vaultMemoryRawToStored(
14641
+ const stored2 = await vaultMemoryRawToStored(
14630
14642
  raw,
14631
14643
  ctx.walletAddress,
14632
14644
  ctx.signMessage,
14633
14645
  ctx.embeddedWalletSigner
14634
14646
  );
14635
- if (normalizeForDedupe(stored.content) === target) return stored.uniqueId;
14647
+ if (normalizeForDedupe(stored2.content) === target) return stored2.uniqueId;
14636
14648
  }
14637
14649
  return null;
14638
14650
  }
@@ -14741,25 +14753,25 @@ async function ingestPublishedPhotoMemoriesOp(ctx, rows) {
14741
14753
  inserted = writable.length;
14742
14754
  if (writable.length === 0) return;
14743
14755
  const prepared = writable.map(
14744
- ({ row, content }) => ctx.vaultMemoryCollection.prepareCreate((record) => {
14745
- record._raw.id = row.memoryId;
14746
- record._setRaw("content", content);
14747
- record._setRaw("scope", "shared");
14748
- record._setRaw("folder_id", null);
14749
- record._setRaw("user_id", ctx.userId ?? null);
14750
- record._setRaw("is_deleted", false);
14751
- record._setRaw("proof_count", 1);
14752
- record._setRaw("source", SOURCE_PHOTO);
14753
- record._setRaw(
14756
+ ({ row, content }) => ctx.vaultMemoryCollection.prepareCreate((record2) => {
14757
+ record2._raw.id = row.memoryId;
14758
+ record2._setRaw("content", content);
14759
+ record2._setRaw("scope", "shared");
14760
+ record2._setRaw("folder_id", null);
14761
+ record2._setRaw("user_id", ctx.userId ?? null);
14762
+ record2._setRaw("is_deleted", false);
14763
+ record2._setRaw("proof_count", 1);
14764
+ record2._setRaw("source", SOURCE_PHOTO);
14765
+ record2._setRaw(
14754
14766
  "media",
14755
14767
  row.media && row.media.length > 0 ? JSON.stringify(row.media) : null
14756
14768
  );
14757
- record._setRaw("visibility", "public");
14758
- record._setRaw("published_at", now);
14769
+ record2._setRaw("visibility", "public");
14770
+ record2._setRaw("published_at", now);
14759
14771
  if (row.eventTime) {
14760
- record._setRaw("event_time_start", row.eventTime.start ?? null);
14761
- record._setRaw("event_time_end", row.eventTime.end ?? null);
14762
- record._setRaw("event_time_kind", row.eventTime.kind ?? null);
14772
+ record2._setRaw("event_time_start", row.eventTime.start ?? null);
14773
+ record2._setRaw("event_time_end", row.eventTime.end ?? null);
14774
+ record2._setRaw("event_time_kind", row.eventTime.kind ?? null);
14763
14775
  }
14764
14776
  })
14765
14777
  );
@@ -15580,11 +15592,11 @@ function folderToStored(folder) {
15580
15592
  }
15581
15593
  async function createVaultFolderOp(ctx, opts) {
15582
15594
  const created = await ctx.database.write(async () => {
15583
- return ctx.vaultFolderCollection.create((record) => {
15584
- record._setRaw("name", opts.name);
15585
- record._setRaw("scope", opts.scope ?? "private");
15586
- record._setRaw("is_system", opts.isSystem ?? false);
15587
- record._setRaw("is_deleted", false);
15595
+ return ctx.vaultFolderCollection.create((record2) => {
15596
+ record2._setRaw("name", opts.name);
15597
+ record2._setRaw("scope", opts.scope ?? "private");
15598
+ record2._setRaw("is_system", opts.isSystem ?? false);
15599
+ record2._setRaw("is_deleted", false);
15588
15600
  });
15589
15601
  });
15590
15602
  return folderToStored(created);
@@ -15595,14 +15607,14 @@ async function getAllVaultFoldersOp(ctx) {
15595
15607
  }
15596
15608
  async function updateVaultFolderOp(ctx, id, opts) {
15597
15609
  try {
15598
- const record = await ctx.vaultFolderCollection.find(id);
15599
- if (record.isDeleted) return null;
15600
- const scopeChanged = opts.scope !== void 0 && opts.scope !== record.scope;
15610
+ const record2 = await ctx.vaultFolderCollection.find(id);
15611
+ if (record2.isDeleted) return null;
15612
+ const scopeChanged = opts.scope !== void 0 && opts.scope !== record2.scope;
15601
15613
  const updated = await ctx.database.write(async () => {
15602
15614
  const memories = scopeChanged ? await ctx.vaultMemoryCollection.query(Q13.where("folder_id", id), Q13.where("is_deleted", false)).fetch() : [];
15603
15615
  const updates = [];
15604
15616
  updates.push(
15605
- record.prepareUpdate((r) => {
15617
+ record2.prepareUpdate((r) => {
15606
15618
  if (opts.name !== void 0) r._setRaw("name", opts.name);
15607
15619
  if (opts.scope !== void 0) r._setRaw("scope", opts.scope);
15608
15620
  })
@@ -15624,8 +15636,8 @@ async function updateVaultFolderOp(ctx, id, opts) {
15624
15636
  }
15625
15637
  async function deleteVaultFolderOp(ctx, id) {
15626
15638
  try {
15627
- const record = await ctx.vaultFolderCollection.find(id);
15628
- if (record.isDeleted) return false;
15639
+ const record2 = await ctx.vaultFolderCollection.find(id);
15640
+ if (record2.isDeleted) return false;
15629
15641
  await ctx.database.write(async () => {
15630
15642
  const memories = await ctx.vaultMemoryCollection.query(Q13.where("folder_id", id), Q13.where("is_deleted", false)).fetch();
15631
15643
  const preparedMemories = memories.map(
@@ -15634,7 +15646,7 @@ async function deleteVaultFolderOp(ctx, id) {
15634
15646
  r._setRaw("scope", "private");
15635
15647
  })
15636
15648
  );
15637
- const preparedFolder = record.prepareUpdate((r) => {
15649
+ const preparedFolder = record2.prepareUpdate((r) => {
15638
15650
  r._setRaw("is_deleted", true);
15639
15651
  });
15640
15652
  await ctx.database.batch(...preparedMemories, preparedFolder);
@@ -15680,11 +15692,11 @@ async function moveMemoriesToFolderOp(ctx, memoryIds, folderId) {
15680
15692
  }
15681
15693
  async function updateVaultFolderContextOp(ctx, id, context) {
15682
15694
  try {
15683
- const record = await ctx.vaultFolderCollection.find(id);
15684
- if (record.isDeleted) return null;
15695
+ const record2 = await ctx.vaultFolderCollection.find(id);
15696
+ if (record2.isDeleted) return null;
15685
15697
  const updated = await ctx.database.write(async () => {
15686
15698
  await ctx.database.batch(
15687
- record.prepareUpdate((r) => {
15699
+ record2.prepareUpdate((r) => {
15688
15700
  r._setRaw("context", context);
15689
15701
  })
15690
15702
  );
@@ -17741,7 +17753,7 @@ async function rankPreparedVaultCandidates(query, prepared, embeddingOptions, se
17741
17753
  if (useFusion && !embeddingsUnavailable && facetQueries) {
17742
17754
  let subEmbeddings;
17743
17755
  try {
17744
- subEmbeddings = await generateEmbeddings(facetQueries, embeddingOptions);
17756
+ subEmbeddings = prepared.facetEmbeddings ?? await generateEmbeddings(facetQueries, embeddingOptions);
17745
17757
  } catch (err) {
17746
17758
  getLogger().warn(
17747
17759
  "memoryVault: sub-query embedding failed \u2014 falling back to single-query ranking: " + (err instanceof Error ? err.message : String(err))
@@ -17926,6 +17938,35 @@ var DEFAULT_SCOPE = "private";
17926
17938
  var DEFAULT_CONSOLIDATE_THRESHOLD = 0.55;
17927
17939
  var DEFAULT_CONSOLIDATE_TOP_K = 20;
17928
17940
  async function retain(content, ctx, options = {}) {
17941
+ return retainWithPersistence(
17942
+ content,
17943
+ {
17944
+ embeddingOptions: ctx.embeddingOptions,
17945
+ vaultCache: ctx.vaultCache,
17946
+ persistence: {
17947
+ prepare: (query, searchOptions) => prepareVaultCandidates(
17948
+ query,
17949
+ ctx.vaultCtx,
17950
+ ctx.embeddingOptions,
17951
+ ctx.vaultCache,
17952
+ searchOptions
17953
+ ),
17954
+ get: (id) => getVaultMemoryOp(ctx.vaultCtx, id),
17955
+ tombstones: (_embedding, _model, scope, folderId) => getAllVaultMemoriesOp(ctx.vaultCtx, {
17956
+ includeDeleted: true,
17957
+ scopes: [scope],
17958
+ ...folderId !== void 0 && { folderId }
17959
+ }),
17960
+ create: (input) => createVaultMemoryOp(ctx.vaultCtx, input),
17961
+ update: (id, patch) => updateVaultMemoryOp(ctx.vaultCtx, id, patch),
17962
+ supersede: (id, successor) => supersedeVaultMemoryOp(ctx.vaultCtx, id, successor),
17963
+ createSuperseding: (input, target) => createSupersedingMemoryOp(ctx.vaultCtx, input, target)
17964
+ }
17965
+ },
17966
+ options
17967
+ );
17968
+ }
17969
+ async function retainWithPersistence(content, ctx, options = {}) {
17929
17970
  const trimmed = content.trim();
17930
17971
  if (trimmed.length === 0) {
17931
17972
  throw new Error("retain: content cannot be empty");
@@ -17938,19 +17979,13 @@ async function retain(content, ctx, options = {}) {
17938
17979
  let supersedeContent;
17939
17980
  let prepared;
17940
17981
  if (enableAutoMerge) {
17941
- prepared = await prepareVaultCandidates(
17942
- trimmed,
17943
- ctx.vaultCtx,
17944
- ctx.embeddingOptions,
17945
- ctx.vaultCache,
17946
- {
17947
- limit: Math.max(options.consolidateTopK ?? DEFAULT_CONSOLIDATE_TOP_K, 1),
17948
- useFusion: false,
17949
- scopes: [resolvedScope],
17950
- includeArchived: true,
17951
- ...options.folderId !== void 0 && { folderId: options.folderId }
17952
- }
17953
- );
17982
+ prepared = await ctx.persistence.prepare(trimmed, {
17983
+ limit: Math.max(options.consolidateTopK ?? DEFAULT_CONSOLIDATE_TOP_K, 1),
17984
+ useFusion: false,
17985
+ scopes: [resolvedScope],
17986
+ includeArchived: true,
17987
+ ...options.folderId !== void 0 && { folderId: options.folderId }
17988
+ });
17954
17989
  if (prepared.embeddingFailure || prepared.embeddingsUnavailable) {
17955
17990
  throw new Error(
17956
17991
  "retain: embeddings unavailable \u2014 refusing to auto-merge against an inert cosine lane, which would create a duplicate instead of merging into the existing memory. Retry when embeddings recover, or pass enableAutoMerge: false to force a create."
@@ -17981,7 +18016,7 @@ async function retain(content, ctx, options = {}) {
17981
18016
  );
17982
18017
  if (matches.length > 0) {
17983
18018
  const targetId = matches[0].uniqueId;
17984
- const existing = await getVaultMemoryOp(ctx.vaultCtx, targetId);
18019
+ const existing = await ctx.persistence.get(targetId);
17985
18020
  if (existing && !existing.supersededBy) {
17986
18021
  const mergedSourceIds = unionStrings(
17987
18022
  existing.sourceChunkIds ?? [],
@@ -17990,7 +18025,7 @@ async function retain(content, ctx, options = {}) {
17990
18025
  const eventTimeUpdate = pickEventTimeUpdate(existing, options.eventTime);
17991
18026
  const factTypeUpdate = pickFactTypeUpdate(existing, options.factType);
17992
18027
  const resurrect = resurrectFields(existing);
17993
- const updated = await updateVaultMemoryOp(ctx.vaultCtx, targetId, {
18028
+ const updated = await ctx.persistence.update(targetId, {
17994
18029
  content: existing.content,
17995
18030
  proofCountIncrement: 1,
17996
18031
  observationSourceIds: options.sourceChunkIds,
@@ -18017,7 +18052,8 @@ async function retain(content, ctx, options = {}) {
18017
18052
  }
18018
18053
  const contentToWrite = supersedeContent ?? trimmed;
18019
18054
  const reusableQueryEmbedding = supersedeContent === void 0 && prepared && prepared.queryEmbedding.length > 0 ? prepared.queryEmbedding : void 0;
18020
- const embedding = reusableQueryEmbedding ?? await generateEmbedding(contentToWrite, ctx.embeddingOptions);
18055
+ const generatedEmbedding = reusableQueryEmbedding ?? await generateEmbedding(contentToWrite, ctx.embeddingOptions);
18056
+ const embedding = ctx.normalizeEmbedding?.(generatedEmbedding) ?? generatedEmbedding;
18021
18057
  const embeddingModel = ctx.embeddingOptions.model ?? DEFAULT_API_EMBEDDING_MODEL;
18022
18058
  if (options.respectTombstones) {
18023
18059
  const tombstone = await findTombstoneMatch(embedding, embeddingModel, resolvedScope, ctx, {
@@ -18057,8 +18093,7 @@ async function retain(content, ctx, options = {}) {
18057
18093
  };
18058
18094
  if (supersedeTargetIds.length > 0) {
18059
18095
  const [primaryTargetId, ...restTargetIds] = supersedeTargetIds;
18060
- const { created: created2, retired } = await createSupersedingMemoryOp(
18061
- ctx.vaultCtx,
18096
+ const { created: created2, retired } = await ctx.persistence.createSuperseding(
18062
18097
  createOpts,
18063
18098
  primaryTargetId
18064
18099
  );
@@ -18074,11 +18109,11 @@ async function retain(content, ctx, options = {}) {
18074
18109
  for (const staleId of restTargetIds) {
18075
18110
  let ok = false;
18076
18111
  try {
18077
- ok = await supersedeVaultMemoryOp(ctx.vaultCtx, staleId, created2.uniqueId) === true;
18112
+ ok = await ctx.persistence.supersede(staleId, created2.uniqueId) === true;
18078
18113
  } catch {
18079
18114
  }
18080
18115
  if (ok) continue;
18081
- const stillLive = await getVaultMemoryOp(ctx.vaultCtx, staleId).catch(() => null);
18116
+ const stillLive = await (ctx.persistence.getFresh ? ctx.persistence.getFresh(staleId) : ctx.persistence.get(staleId)).catch(() => null);
18082
18117
  if (stillLive && !stillLive.supersededBy) liveLeftovers.push(staleId);
18083
18118
  }
18084
18119
  if (liveLeftovers.length > 0) {
@@ -18105,7 +18140,7 @@ async function retain(content, ctx, options = {}) {
18105
18140
  `supersede: primary target ${primaryTargetId} retired or deleted inside the atomic write`
18106
18141
  );
18107
18142
  }
18108
- const created = await createVaultMemoryOp(ctx.vaultCtx, createOpts);
18143
+ const created = await ctx.persistence.create(createOpts);
18109
18144
  cacheRowVector(
18110
18145
  ctx.vaultCache,
18111
18146
  created.uniqueId,
@@ -18124,11 +18159,7 @@ function unionStrings(a, b) {
18124
18159
  return [.../* @__PURE__ */ new Set([...a, ...b])];
18125
18160
  }
18126
18161
  async function findTombstoneMatch(embedding, embeddingModel, scope, ctx, opts) {
18127
- const rows = await getAllVaultMemoriesOp(ctx.vaultCtx, {
18128
- includeDeleted: true,
18129
- scopes: [scope],
18130
- ...opts.folderId !== void 0 && { folderId: opts.folderId }
18131
- });
18162
+ const rows = await ctx.persistence.tombstones(embedding, embeddingModel, scope, opts.folderId);
18132
18163
  let bestId = null;
18133
18164
  let bestSim = opts.threshold;
18134
18165
  for (const row of rows) {
@@ -18195,7 +18226,7 @@ async function tryConsolidate(trimmed, ctx, options, prepared) {
18195
18226
  if (requestedIds.length === 0) return null;
18196
18227
  const valid = [];
18197
18228
  for (const id of requestedIds) {
18198
- const existing = await getVaultMemoryOp(ctx.vaultCtx, id);
18229
+ const existing = await ctx.persistence.get(id);
18199
18230
  if (existing && !existing.supersededBy) valid.push(id);
18200
18231
  }
18201
18232
  if (valid.length === 0) {
@@ -18207,7 +18238,7 @@ async function tryConsolidate(trimmed, ctx, options, prepared) {
18207
18238
  return { supersede: valid, content: decision.content };
18208
18239
  }
18209
18240
  if (decision.action === "noop" && decision.targetId) {
18210
- const existing = await getVaultMemoryOp(ctx.vaultCtx, decision.targetId);
18241
+ const existing = await ctx.persistence.get(decision.targetId);
18211
18242
  if (!existing || existing.supersededBy) {
18212
18243
  return abandonToRace(
18213
18244
  options,
@@ -18221,7 +18252,7 @@ async function tryConsolidate(trimmed, ctx, options, prepared) {
18221
18252
  const eventTimeUpdate = pickEventTimeUpdate(existing, options.eventTime);
18222
18253
  const factTypeUpdate = pickFactTypeUpdate(existing, options.factType);
18223
18254
  const resurrect = resurrectFields(existing);
18224
- const updated = await updateVaultMemoryOp(ctx.vaultCtx, decision.targetId, {
18255
+ const updated = await ctx.persistence.update(decision.targetId, {
18225
18256
  content: existing.content,
18226
18257
  proofCountIncrement: 1,
18227
18258
  observationSourceIds: options.sourceChunkIds,
@@ -18249,7 +18280,7 @@ async function tryConsolidate(trimmed, ctx, options, prepared) {
18249
18280
  };
18250
18281
  }
18251
18282
  if (decision.action === "update" && decision.targetId && decision.content) {
18252
- const existing = await getVaultMemoryOp(ctx.vaultCtx, decision.targetId);
18283
+ const existing = await ctx.persistence.get(decision.targetId);
18253
18284
  if (!existing || existing.supersededBy) {
18254
18285
  return abandonToRace(
18255
18286
  options,
@@ -18260,12 +18291,13 @@ async function tryConsolidate(trimmed, ctx, options, prepared) {
18260
18291
  existing.sourceChunkIds ?? [],
18261
18292
  options.sourceChunkIds ?? []
18262
18293
  );
18263
- const newEmbedding = await generateEmbedding(decision.content, ctx.embeddingOptions);
18294
+ const generatedEmbedding = await generateEmbedding(decision.content, ctx.embeddingOptions);
18295
+ const newEmbedding = ctx.normalizeEmbedding?.(generatedEmbedding) ?? generatedEmbedding;
18264
18296
  const consolidatedModel = ctx.embeddingOptions.model ?? DEFAULT_API_EMBEDDING_MODEL;
18265
18297
  const eventTimeUpdate = pickEventTimeUpdate(existing, options.eventTime);
18266
18298
  const factTypeUpdate = pickFactTypeUpdate(existing, options.factType);
18267
18299
  const resurrect = resurrectFields(existing);
18268
- const updated = await updateVaultMemoryOp(ctx.vaultCtx, decision.targetId, {
18300
+ const updated = await ctx.persistence.update(decision.targetId, {
18269
18301
  content: decision.content,
18270
18302
  proofCountIncrement: 1,
18271
18303
  observationSourceIds: options.sourceChunkIds,
@@ -18309,7 +18341,7 @@ async function tryConsolidate(trimmed, ctx, options, prepared) {
18309
18341
  return null;
18310
18342
  }
18311
18343
  async function assertMergeTargetGoneOrThrow(ctx, targetId) {
18312
- const stillExists = await getVaultMemoryOp(ctx.vaultCtx, targetId);
18344
+ const stillExists = await (ctx.persistence.getFresh ? ctx.persistence.getFresh(targetId) : ctx.persistence.get(targetId));
18313
18345
  if (stillExists) {
18314
18346
  throw new Error(`retain: merge into memory ${targetId} failed to persist`);
18315
18347
  }
@@ -18824,9 +18856,9 @@ function createAutoExtractor(options) {
18824
18856
  const persistCursor = (conversationId, messages, advancedToId, contiguous) => {
18825
18857
  if (!cursorStore || conversationId === void 0 || !contiguous) return;
18826
18858
  try {
18827
- const stored = cursorStore.get(conversationId);
18828
- if (stored && stored !== advancedToId) {
18829
- const storedIdx = messages.findIndex((m) => m.id === stored);
18859
+ const stored2 = cursorStore.get(conversationId);
18860
+ if (stored2 && stored2 !== advancedToId) {
18861
+ const storedIdx = messages.findIndex((m) => m.id === stored2);
18830
18862
  const newIdx = messages.findIndex((m) => m.id === advancedToId);
18831
18863
  if (storedIdx !== -1 && newIdx !== -1 && storedIdx >= newIdx) return;
18832
18864
  }
@@ -19795,7 +19827,7 @@ async function recall(query, ctx, options = {}) {
19795
19827
  if (graphLaneFailed) degraded.push("graph-lane-failed");
19796
19828
  if (temporalLaneFailed) degraded.push("temporal-lane-failed");
19797
19829
  if (chunksScopeRestricted) degraded.push("chunks-scope-restricted");
19798
- const laneRan = types.includes("fact") && !!ctx.vaultCtx && !!ctx.vaultCache || types.includes("chunk") && !!ctx.storageCtx || chunksScopeRestricted && !!ctx.storageCtx;
19830
+ const laneRan = types.includes("fact") && (!!ctx.factSource || !!ctx.vaultCtx && !!ctx.vaultCache) || types.includes("chunk") && !!ctx.storageCtx || chunksScopeRestricted && !!ctx.storageCtx;
19799
19831
  const scores = admitted.map((m) => m.score);
19800
19832
  const minScoreApplied = factResults.length > 0 ? factFloor : chunkResults.length > 0 ? chunkFloor : factFloor >= 0 ? factFloor : chunkFloor;
19801
19833
  const diagnostics = {
@@ -19837,7 +19869,7 @@ async function recall(query, ctx, options = {}) {
19837
19869
  return { memories: [], usedBudget, reranked: false, candidateCount: 0 };
19838
19870
  }
19839
19871
  const needsChunkEmbedding = types.includes("chunk") && ctx.storageCtx;
19840
- const wantsTemporal = types.includes("fact") && ctx.vaultCtx;
19872
+ const wantsTemporal = types.includes("fact") && (ctx.factSource || ctx.vaultCtx);
19841
19873
  const graphRefiner = flags.traverse && options.graphRefine && options.decomposeOptions ? createLlmNeighborRefiner(options.decomposeOptions) : void 0;
19842
19874
  const queryEmbedTotalTimeoutMs = options.queryEmbedTotalTimeoutMs ?? DEFAULT_QUERY_EMBED_TOTAL_TIMEOUT_MS;
19843
19875
  const prepStart = nowMs2();
@@ -19867,7 +19899,7 @@ async function recall(query, ctx, options = {}) {
19867
19899
  safeLane(
19868
19900
  "graph",
19869
19901
  () => graphLaneFailed = true,
19870
- () => buildGraphLaneRanking(query, ctx, flags.traverse, {
19902
+ () => ctx.factSource ? ctx.factSource.graphRanking(query, flags.traverse, options) : buildGraphLaneRanking(query, ctx, flags.traverse, {
19871
19903
  ...options.maxHops !== void 0 && { maxHops: options.maxHops },
19872
19904
  ...options.entityFanout !== void 0 && { entityFanout: options.entityFanout },
19873
19905
  ...options.nodeBudget !== void 0 && { nodeBudget: options.nodeBudget },
@@ -19878,13 +19910,13 @@ async function recall(query, ctx, options = {}) {
19878
19910
  wantsTemporal ? safeLane(
19879
19911
  "temporal",
19880
19912
  () => temporalLaneFailed = true,
19881
- () => buildTemporalLaneRanking(query, ctx.vaultCtx, options.now)
19913
+ () => ctx.factSource ? ctx.factSource.temporalRanking(query, options.now) : buildTemporalLaneRanking(query, ctx.vaultCtx, options.now)
19882
19914
  ) : Promise.resolve([])
19883
19915
  ]);
19884
19916
  prepMs = nowMs2() - prepStart;
19885
19917
  graphLaneCount = entityRanking.length;
19886
19918
  temporalLaneCount = temporalRanking.length;
19887
- if (types.includes("fact") && ctx.vaultCtx && ctx.vaultCache) {
19919
+ if (types.includes("fact") && (ctx.factSource || ctx.vaultCtx && ctx.vaultCache)) {
19888
19920
  const factStart = nowMs2();
19889
19921
  const vaultMinScore = options.minScore ?? DEFAULT_FACT_MIN_SCORE;
19890
19922
  factFloor = vaultMinScore;
@@ -19900,50 +19932,50 @@ async function recall(query, ctx, options = {}) {
19900
19932
  rankedOnCosine: factRankedOnCosine,
19901
19933
  decryptLast: factDecryptLast,
19902
19934
  rowsDecrypted: factRowsDecrypted
19903
- } = await searchVaultMemoriesWithSize(
19904
- query,
19935
+ } = await (ctx.factSource?.search.bind(ctx.factSource) ?? ((searchQuery, searchOptions) => searchVaultMemoriesWithSize(
19936
+ searchQuery,
19905
19937
  ctx.vaultCtx,
19906
19938
  ctx.embeddingOptions,
19907
19939
  ctx.vaultCache,
19908
- {
19909
- limit: types.includes("chunk") ? Math.max(limit * 2, 16) : limit,
19910
- minSimilarity: vaultMinScore,
19911
- useFusion: true,
19912
- rerank: flags.rerank,
19913
- ...options.rerankTopN !== void 0 && { rerankTopN: options.rerankTopN },
19914
- ...options.ceWeight !== void 0 && { ceWeight: options.ceWeight },
19915
- ...options.rerankLoadTimeoutMs !== void 0 && {
19916
- rerankLoadTimeoutMs: options.rerankLoadTimeoutMs
19917
- },
19918
- ...options.recencyAlpha !== void 0 && { recencyAlpha: options.recencyAlpha },
19919
- ...options.recency && { recency: options.recency },
19920
- ...options.mmr !== void 0 && { mmr: options.mmr },
19921
- ...options.supersessionBoost !== void 0 && {
19922
- supersessionBoost: options.supersessionBoost
19923
- },
19924
- ...options.supersessionWindow !== void 0 && {
19925
- supersessionWindow: options.supersessionWindow
19926
- },
19927
- ...options.proofCountAlpha !== void 0 && {
19928
- proofCountAlpha: options.proofCountAlpha
19929
- },
19930
- ...options.bm25AdmissionDivisor !== void 0 && {
19931
- bm25AdmissionDivisor: options.bm25AdmissionDivisor
19932
- },
19933
- ...options.rrfK !== void 0 && { rrfK: options.rrfK },
19934
- ...options.decryptLast !== void 0 && { decryptLast: options.decryptLast },
19935
- ...subQueries && { subQueries },
19936
- ...options.scopes && { scopes: options.scopes },
19937
- ...options.folderId !== void 0 && { folderId: options.folderId },
19938
- ...options.factTypes?.length && { factTypes: options.factTypes },
19939
- ...options.memoryIds !== void 0 && { memoryIds: options.memoryIds },
19940
- ...options.factTypeWeights && { factTypeWeights: options.factTypeWeights },
19941
- ...entityRanking.length > 0 && { entityRanking },
19942
- ...temporalRanking.length > 0 && { temporalRanking },
19943
- ...needsChunkEmbedding && { queryEmbedding: queryEmbedding ?? [] },
19944
- queryEmbedTotalTimeoutMs
19945
- }
19946
- );
19940
+ searchOptions
19941
+ )))(query, {
19942
+ limit: types.includes("chunk") ? Math.max(limit * 2, 16) : limit,
19943
+ minSimilarity: vaultMinScore,
19944
+ useFusion: true,
19945
+ rerank: flags.rerank,
19946
+ ...options.rerankTopN !== void 0 && { rerankTopN: options.rerankTopN },
19947
+ ...options.ceWeight !== void 0 && { ceWeight: options.ceWeight },
19948
+ ...options.rerankLoadTimeoutMs !== void 0 && {
19949
+ rerankLoadTimeoutMs: options.rerankLoadTimeoutMs
19950
+ },
19951
+ ...options.recencyAlpha !== void 0 && { recencyAlpha: options.recencyAlpha },
19952
+ ...options.recency && { recency: options.recency },
19953
+ ...options.mmr !== void 0 && { mmr: options.mmr },
19954
+ ...options.supersessionBoost !== void 0 && {
19955
+ supersessionBoost: options.supersessionBoost
19956
+ },
19957
+ ...options.supersessionWindow !== void 0 && {
19958
+ supersessionWindow: options.supersessionWindow
19959
+ },
19960
+ ...options.proofCountAlpha !== void 0 && {
19961
+ proofCountAlpha: options.proofCountAlpha
19962
+ },
19963
+ ...options.bm25AdmissionDivisor !== void 0 && {
19964
+ bm25AdmissionDivisor: options.bm25AdmissionDivisor
19965
+ },
19966
+ ...options.rrfK !== void 0 && { rrfK: options.rrfK },
19967
+ ...options.decryptLast !== void 0 && { decryptLast: options.decryptLast },
19968
+ ...subQueries && { subQueries },
19969
+ ...options.scopes && { scopes: options.scopes },
19970
+ ...options.folderId !== void 0 && { folderId: options.folderId },
19971
+ ...options.factTypes?.length && { factTypes: options.factTypes },
19972
+ ...options.memoryIds !== void 0 && { memoryIds: options.memoryIds },
19973
+ ...options.factTypeWeights && { factTypeWeights: options.factTypeWeights },
19974
+ ...entityRanking.length > 0 && { entityRanking },
19975
+ ...temporalRanking.length > 0 && { temporalRanking },
19976
+ ...needsChunkEmbedding && { queryEmbedding: queryEmbedding ?? [] },
19977
+ queryEmbedTotalTimeoutMs
19978
+ });
19947
19979
  factResults.push(
19948
19980
  ...dedupeBy(
19949
19981
  results,
@@ -20748,26 +20780,26 @@ async function extractAndLinkEntitiesForMemoriesOp(ctx, memoryIds, options) {
20748
20780
  };
20749
20781
  const inputs = [];
20750
20782
  for (const id of new Set(memoryIds)) {
20751
- let record;
20783
+ let record2;
20752
20784
  try {
20753
- record = await ctx.vaultMemoryCollection.find(id);
20785
+ record2 = await ctx.vaultMemoryCollection.find(id);
20754
20786
  } catch (err) {
20755
20787
  log.warn("[memory/topics] vault lookup failed for extraction", err);
20756
20788
  skip(id, "not-found");
20757
20789
  continue;
20758
20790
  }
20759
- if (record.isDeleted || ctx.userId !== void 0 && record.userId !== ctx.userId || record.topicsUserManaged) {
20791
+ if (record2.isDeleted || ctx.userId !== void 0 && record2.userId !== ctx.userId || record2.topicsUserManaged) {
20760
20792
  skip(id, "excluded");
20761
20793
  continue;
20762
20794
  }
20763
20795
  try {
20764
- const stored = await vaultMemoryToStored(
20765
- record,
20796
+ const stored2 = await vaultMemoryToStored(
20797
+ record2,
20766
20798
  ctx.walletAddress,
20767
20799
  ctx.signMessage,
20768
20800
  ctx.embeddedWalletSigner
20769
20801
  );
20770
- inputs.push({ id, content: stored.content });
20802
+ inputs.push({ id, content: stored2.content });
20771
20803
  } catch (err) {
20772
20804
  log.warn("[memory/topics] failed to load memory for extraction", err);
20773
20805
  skip(id, "unreadable");
@@ -20952,6 +20984,773 @@ function createLocalMemoryStore(options) {
20952
20984
  };
20953
20985
  }
20954
20986
 
20987
+ // src/lib/memory/store/remotePersistence.ts
20988
+ var RemoteMemoryError = class extends Error {
20989
+ constructor(message, status, code) {
20990
+ super(message);
20991
+ this.status = status;
20992
+ this.code = code;
20993
+ this.name = "RemoteMemoryError";
20994
+ }
20995
+ };
20996
+ var ciphertextPattern = /^enc:v\d+:[0-9a-f]+$/i;
20997
+ var memoryFields = {
20998
+ memory_id: true,
20999
+ content: true,
21000
+ scope: true,
21001
+ created_at: true,
21002
+ updated_at: true,
21003
+ is_deleted: true,
21004
+ embedding: true,
21005
+ embedding_model: true,
21006
+ kind: true,
21007
+ kind_value: true,
21008
+ level: true,
21009
+ folder_id: true,
21010
+ source_chunk_ids: true,
21011
+ proof_count: true,
21012
+ source: true,
21013
+ event_time_start: true,
21014
+ event_time_end: true,
21015
+ event_time_kind: true,
21016
+ topics_user_managed: true,
21017
+ topics: true,
21018
+ topics_updated_at: true,
21019
+ media: true,
21020
+ topics_extracted_at: true,
21021
+ topics_extracted_version: true,
21022
+ superseded_by: true,
21023
+ superseded_at: true,
21024
+ last_observed_at: true,
21025
+ fact_type: true,
21026
+ archived_at: true,
21027
+ trust_tier: true,
21028
+ visibility: true,
21029
+ twin_opt_in: true,
21030
+ published_at: true,
21031
+ geohash: true
21032
+ };
21033
+ var candidateListLimits = [
21034
+ ["scopes", 20],
21035
+ ["fact_types", 20],
21036
+ ["memory_ids", 1e3],
21037
+ ["force_ids", 100]
21038
+ ];
21039
+ function record(value) {
21040
+ return typeof value === "object" && value !== null && !Array.isArray(value);
21041
+ }
21042
+ function memoryRecord(value) {
21043
+ if (!record(value) || !record(value.memory) || typeof value.memory.memory_id !== "string" || typeof value.memory.content !== "string" || typeof value.memory.scope !== "string" || typeof value.memory.created_at !== "number" || typeof value.memory.updated_at !== "number" || typeof value.memory.is_deleted !== "boolean" || !Number.isSafeInteger(value.version) || value.version < 1 || typeof value.server_updated_at !== "string" || value.score !== void 0 && (typeof value.score !== "number" || !Number.isFinite(value.score))) {
21044
+ throw new Error("Invalid nearby private-memory response");
21045
+ }
21046
+ return value;
21047
+ }
21048
+ async function createRemoteMemoryPersistence(options) {
21049
+ const base = new URL(options.baseUrl);
21050
+ if (!/^https?:$/.test(base.protocol) || base.username || base.password || base.search || base.hash) {
21051
+ throw new Error(
21052
+ "baseUrl must be an HTTP(S) origin or base path without credentials, query or fragment"
21053
+ );
21054
+ }
21055
+ if (!options.keyId || options.keyId.length > 256)
21056
+ throw new Error("A canonical keyId is required");
21057
+ const timeoutMs = options.timeoutMs ?? 3e4;
21058
+ if (!Number.isFinite(timeoutMs) || timeoutMs <= 0)
21059
+ throw new Error("timeoutMs must be a positive number");
21060
+ const root = base.href.replace(/\/$/, "") + "/api/private-memories";
21061
+ const fetcher = options.fetch ?? globalThis.fetch;
21062
+ const request = async (path, init = {}, signal) => {
21063
+ const controller = new AbortController();
21064
+ let timedOut = false;
21065
+ const timer = setTimeout(() => {
21066
+ timedOut = true;
21067
+ controller.abort();
21068
+ }, timeoutMs);
21069
+ const forwardAbort = () => controller.abort(signal?.reason);
21070
+ if (signal?.aborted) forwardAbort();
21071
+ else signal?.addEventListener("abort", forwardAbort, { once: true });
21072
+ let rejectAborted;
21073
+ const aborted = new Promise((_, reject) => {
21074
+ rejectAborted = () => reject(
21075
+ controller.signal.reason instanceof Error ? controller.signal.reason : new Error("Nearby request aborted")
21076
+ );
21077
+ if (controller.signal.aborted) rejectAborted();
21078
+ else controller.signal.addEventListener("abort", rejectAborted, { once: true });
21079
+ });
21080
+ aborted.catch(() => void 0);
21081
+ try {
21082
+ const token = await Promise.race([options.getToken(), aborted]);
21083
+ if (controller.signal.aborted) await aborted;
21084
+ if (!token) throw new RemoteMemoryError("Authentication required", 401);
21085
+ const response = await fetcher(root + path, {
21086
+ ...init,
21087
+ headers: {
21088
+ Authorization: `Bearer ${token}`,
21089
+ ...init.body ? { "Content-Type": "application/json" } : {}
21090
+ },
21091
+ redirect: "error",
21092
+ signal: controller.signal
21093
+ });
21094
+ if (!response.ok) {
21095
+ const body = await response.json().catch(() => null);
21096
+ throw new RemoteMemoryError(
21097
+ record(body) && typeof body.detail === "string" ? body.detail : `Nearby request failed (${response.status})`,
21098
+ response.status,
21099
+ record(body) && typeof body.code === "string" ? body.code : void 0
21100
+ );
21101
+ }
21102
+ return await response.json();
21103
+ } catch (error) {
21104
+ if (timedOut) throw new RemoteMemoryError("Nearby request timed out", 408, "timeout");
21105
+ throw error;
21106
+ } finally {
21107
+ clearTimeout(timer);
21108
+ signal?.removeEventListener("abort", forwardAbort);
21109
+ if (rejectAborted) controller.signal.removeEventListener("abort", rejectAborted);
21110
+ }
21111
+ };
21112
+ const account = await request("/account", {}, options.signal);
21113
+ if (!record(account) || account.state !== "active") {
21114
+ throw new RemoteMemoryError(
21115
+ "Complete and verify migration before using remote memories",
21116
+ 409,
21117
+ "memory_not_active"
21118
+ );
21119
+ }
21120
+ if (account.key_id !== options.keyId) {
21121
+ throw new RemoteMemoryError(
21122
+ "The canonical memory key does not match this account",
21123
+ 409,
21124
+ "key_mismatch"
21125
+ );
21126
+ }
21127
+ const snapshots = /* @__PURE__ */ new WeakMap();
21128
+ const decode = async (value) => {
21129
+ const item = memoryRecord(value);
21130
+ const decrypt = async (ciphertext) => {
21131
+ if (!ciphertextPattern.test(ciphertext))
21132
+ throw new Error("Nearby returned unencrypted memory content");
21133
+ const plaintext = await options.decrypt(ciphertext);
21134
+ if (plaintext === ciphertext) throw new Error("Memory decryption failed");
21135
+ return plaintext;
21136
+ };
21137
+ const decoded = {
21138
+ ...item,
21139
+ memory: {
21140
+ ...item.memory,
21141
+ content: await decrypt(item.memory.content),
21142
+ ...item.memory.kind_value !== void 0 && {
21143
+ kind_value: await decrypt(item.memory.kind_value)
21144
+ }
21145
+ }
21146
+ };
21147
+ return remember(decoded, item);
21148
+ };
21149
+ const remember = (decoded, item) => {
21150
+ snapshots.set(decoded, {
21151
+ id: item.memory.memory_id,
21152
+ version: item.version,
21153
+ content: decoded.memory.content,
21154
+ kindValue: decoded.memory.kind_value,
21155
+ encryptedContent: item.memory.content,
21156
+ encryptedKindValue: item.memory.kind_value
21157
+ });
21158
+ return decoded;
21159
+ };
21160
+ const decodeAll = async (values) => {
21161
+ const records = values.map(memoryRecord);
21162
+ const settled = await Promise.allSettled(records.map(decode));
21163
+ const items = [];
21164
+ const failed = [];
21165
+ settled.forEach((result, i) => {
21166
+ if (result.status === "fulfilled") items.push(result.value);
21167
+ else
21168
+ failed.push({
21169
+ memory_id: records[i].memory.memory_id,
21170
+ version: records[i].version,
21171
+ error: result.reason instanceof Error ? result.reason : new Error(String(result.reason))
21172
+ });
21173
+ });
21174
+ return { items, failed };
21175
+ };
21176
+ const decodeCommitted = async (value, write) => {
21177
+ const item = memoryRecord(value);
21178
+ if (item.memory.memory_id !== write.body.memory.memory_id || item.memory.content !== write.body.memory.content || item.memory.kind_value !== write.body.memory.kind_value)
21179
+ return decode(item);
21180
+ return remember(
21181
+ {
21182
+ ...item,
21183
+ memory: {
21184
+ ...item.memory,
21185
+ content: write.content,
21186
+ ...write.kindValue !== void 0 && { kind_value: write.kindValue }
21187
+ }
21188
+ },
21189
+ item
21190
+ );
21191
+ };
21192
+ const encryptField2 = async (plaintext) => {
21193
+ const ciphertext = await options.encrypt(plaintext);
21194
+ if (ciphertext === plaintext || !ciphertextPattern.test(ciphertext))
21195
+ throw new Error("Field encryption must return SDK ciphertext; refusing to upload plaintext");
21196
+ return ciphertext;
21197
+ };
21198
+ const memoryPath = (id) => {
21199
+ if (!id || id.length > 128) throw new Error("memory_id must be 1\u2013128 characters");
21200
+ return "/memories/" + encodeURIComponent(id);
21201
+ };
21202
+ const prepareWrite = async (memory, expectedVersion, signal) => {
21203
+ const unknown = Object.keys(memory).filter(
21204
+ (key) => !Object.prototype.hasOwnProperty.call(memoryFields, key)
21205
+ );
21206
+ if (unknown.length) {
21207
+ throw new RemoteMemoryError(
21208
+ `Unknown private-memory fields (${unknown.join(", ")}); refusing to forward them`,
21209
+ 400,
21210
+ "unknown_field"
21211
+ );
21212
+ }
21213
+ memory = { ...memory, ...memory.embedding && { embedding: [...memory.embedding] } };
21214
+ const path = memoryPath(memory.memory_id);
21215
+ const snapshot = typeof expectedVersion === "number" ? void 0 : snapshots.get(expectedVersion);
21216
+ if (typeof expectedVersion !== "number" && (!snapshot || snapshot.id !== memory.memory_id || snapshot.version !== expectedVersion.version))
21217
+ throw new Error(
21218
+ "Expected snapshot must be an unmodified version from this persistence instance"
21219
+ );
21220
+ expectedVersion = typeof expectedVersion === "number" ? expectedVersion : snapshot.version;
21221
+ if (!Number.isSafeInteger(expectedVersion) || expectedVersion < 0)
21222
+ throw new Error("expectedVersion must be a nonnegative integer");
21223
+ const conflict = () => new RemoteMemoryError("The memory changed since it was read", 409, "version_conflict");
21224
+ let existing;
21225
+ if (expectedVersion !== 0 && !snapshot) {
21226
+ try {
21227
+ existing = memoryRecord(await request(path, {}, signal));
21228
+ } catch (error) {
21229
+ if (error instanceof RemoteMemoryError && error.status === 404) throw conflict();
21230
+ throw error;
21231
+ }
21232
+ }
21233
+ if (existing && existing.version !== expectedVersion) throw conflict();
21234
+ const decoded = existing ? await decode(existing).catch(() => void 0) : void 0;
21235
+ const content = (snapshot?.content ?? decoded?.memory.content) === memory.content ? snapshot?.encryptedContent ?? existing.memory.content : await encryptField2(memory.content);
21236
+ const kindValue = memory.kind_value === void 0 ? void 0 : (snapshot?.kindValue ?? decoded?.memory.kind_value) === memory.kind_value ? snapshot?.encryptedKindValue ?? existing.memory.kind_value : await encryptField2(memory.kind_value);
21237
+ return {
21238
+ body: {
21239
+ expected_version: expectedVersion,
21240
+ memory: { ...memory, content, ...kindValue !== void 0 && { kind_value: kindValue } }
21241
+ },
21242
+ content: memory.content,
21243
+ kindValue: memory.kind_value
21244
+ };
21245
+ };
21246
+ const fetchCandidates = async (embedding, candidateOptions, withCounts) => {
21247
+ const limit = candidateOptions.limit ?? 100;
21248
+ if (!Number.isInteger(limit) || limit < 1 || limit > 100)
21249
+ throw new Error("Candidate limit must be 1\u2013100");
21250
+ for (const [key, max] of candidateListLimits) {
21251
+ const values = candidateOptions[key];
21252
+ if (values && values.length > max)
21253
+ throw new Error(`Candidate ${key} accepts at most ${max} entries (got ${values.length})`);
21254
+ }
21255
+ const result = await request(
21256
+ "/candidates",
21257
+ {
21258
+ method: "POST",
21259
+ body: JSON.stringify({
21260
+ embedding,
21261
+ limit,
21262
+ force_ids: candidateOptions.force_ids ?? [],
21263
+ ...withCounts && { with_counts: true },
21264
+ ...Object.fromEntries(
21265
+ [
21266
+ "scopes",
21267
+ "memory_ids",
21268
+ "embedding_model",
21269
+ "strict_model",
21270
+ "include_deleted",
21271
+ "deleted_only"
21272
+ ].filter(
21273
+ (key) => candidateOptions[key] !== void 0
21274
+ ).map((key) => [key, candidateOptions[key]])
21275
+ ),
21276
+ ...candidateOptions.fact_types !== void 0 && {
21277
+ fact_types: candidateOptions.fact_types
21278
+ },
21279
+ ...candidateOptions.include_archived !== void 0 && {
21280
+ include_archived: candidateOptions.include_archived
21281
+ },
21282
+ ...candidateOptions.include_quarantined !== void 0 && {
21283
+ include_quarantined: candidateOptions.include_quarantined
21284
+ },
21285
+ ...candidateOptions.include_superseded !== void 0 && {
21286
+ include_superseded: candidateOptions.include_superseded
21287
+ }
21288
+ })
21289
+ },
21290
+ candidateOptions.signal
21291
+ );
21292
+ if (!record(result) || !Array.isArray(result.items))
21293
+ throw new Error("Invalid nearby candidate response");
21294
+ return result;
21295
+ };
21296
+ const candidateSet = async (embedding, candidateOptions = {}) => {
21297
+ const result = await fetchCandidates(embedding, candidateOptions, true);
21298
+ if (!Number.isSafeInteger(result.total_count) || result.total_count < 0 || !Number.isSafeInteger(result.unavailable_count) || result.unavailable_count < 0)
21299
+ throw new Error("Invalid nearby candidate response");
21300
+ return {
21301
+ ...await decodeAll(result.items),
21302
+ total_count: result.total_count,
21303
+ unavailable_count: result.unavailable_count
21304
+ };
21305
+ };
21306
+ return {
21307
+ get: async (id, signal) => {
21308
+ try {
21309
+ return await decode(await request(memoryPath(id), {}, signal));
21310
+ } catch (error) {
21311
+ if (error instanceof RemoteMemoryError && error.status === 404) return null;
21312
+ throw error;
21313
+ }
21314
+ },
21315
+ list: async (listOptions = {}) => {
21316
+ const { signal, ...query } = listOptions;
21317
+ if (query.limit !== void 0 && (!Number.isInteger(query.limit) || query.limit < 1 || query.limit > 200)) {
21318
+ throw new Error("Page limit must be 1\u2013200");
21319
+ }
21320
+ const params = new URLSearchParams();
21321
+ for (const key of [
21322
+ "cursor",
21323
+ "limit",
21324
+ "include_deleted",
21325
+ "include_archived",
21326
+ "include_quarantined",
21327
+ "include_superseded",
21328
+ "include_embeddings"
21329
+ ]) {
21330
+ if (query[key] !== void 0) params.set(key, String(query[key]));
21331
+ }
21332
+ const page = await request("/memories?" + params.toString(), {}, signal);
21333
+ if (!record(page) || !Array.isArray(page.items) || page.next_cursor !== void 0 && typeof page.next_cursor !== "string") {
21334
+ throw new Error("Invalid nearby private-memory page");
21335
+ }
21336
+ return {
21337
+ ...await decodeAll(page.items),
21338
+ ...page.next_cursor !== void 0 && { next_cursor: page.next_cursor }
21339
+ };
21340
+ },
21341
+ put: async (memory, expectedVersion, signal) => {
21342
+ const write = await prepareWrite(memory, expectedVersion, signal);
21343
+ return decodeCommitted(
21344
+ await request(
21345
+ memoryPath(write.body.memory.memory_id),
21346
+ {
21347
+ method: "PUT",
21348
+ body: JSON.stringify({ key_id: options.keyId, ...write.body })
21349
+ },
21350
+ signal
21351
+ ),
21352
+ write
21353
+ );
21354
+ },
21355
+ putMany: async (writes, signal) => {
21356
+ if (writes.length < 1 || writes.length > 50 || new Set(writes.map((w) => w.memory.memory_id)).size !== writes.length)
21357
+ throw new Error("Batch must contain 1\u201350 distinct memory ids");
21358
+ const prepared = await Promise.all(
21359
+ writes.map((w) => prepareWrite(w.memory, w.expectedVersion, signal))
21360
+ );
21361
+ const result = await request(
21362
+ "/memories/batch",
21363
+ {
21364
+ method: "POST",
21365
+ body: JSON.stringify({ key_id: options.keyId, writes: prepared.map((w) => w.body) })
21366
+ },
21367
+ signal
21368
+ );
21369
+ if (!record(result) || !Array.isArray(result.items) || result.items.length !== prepared.length)
21370
+ throw new Error("Invalid nearby batch response");
21371
+ return Promise.all(result.items.map((item, i) => decodeCommitted(item, prepared[i])));
21372
+ },
21373
+ candidateSet,
21374
+ candidates: async (embedding, candidateOptions = {}) => decodeAll((await fetchCandidates(embedding, candidateOptions, false)).items)
21375
+ };
21376
+ }
21377
+
21378
+ // src/lib/memory/store/remotePipeline.ts
21379
+ import { v7 as uuidv75 } from "uuid";
21380
+ function storedVector(vector) {
21381
+ if (!Array.isArray(vector) || vector.length !== 1536 && vector.length !== 4096 || vector.some((v) => !Number.isFinite(v)))
21382
+ throw new Error("Remote memories require a finite 1536/4096-dimensional vector");
21383
+ const out = vector.slice(0, 1536);
21384
+ const norm = Math.sqrt(out.reduce((sum, v) => sum + v * v, 0));
21385
+ if (!norm) throw new Error("Remote query/content vector has no direction after MRL truncation");
21386
+ return out.map((v) => v / norm);
21387
+ }
21388
+ function sourceIds(value) {
21389
+ if (!value) return [];
21390
+ try {
21391
+ const parsed = JSON.parse(value);
21392
+ return Array.isArray(parsed) ? parsed.filter((id) => typeof id === "string") : [];
21393
+ } catch {
21394
+ return [];
21395
+ }
21396
+ }
21397
+ function stored(row) {
21398
+ return {
21399
+ uniqueId: row.memory_id,
21400
+ content: row.content,
21401
+ scope: row.scope,
21402
+ folderId: row.folder_id ?? null,
21403
+ userId: null,
21404
+ embedding: row.embedding ? JSON.stringify(row.embedding) : null,
21405
+ embeddingModel: row.embedding_model ?? null,
21406
+ sourceChunkIds: row.source_chunk_ids === void 0 ? null : sourceIds(row.source_chunk_ids),
21407
+ proofCount: row.proof_count ?? null,
21408
+ source: row.source ?? null,
21409
+ media: parseMedia(row.media),
21410
+ eventTimeStart: row.event_time_start ?? null,
21411
+ eventTimeEnd: row.event_time_end ?? null,
21412
+ eventTimeKind: row.event_time_kind ?? null,
21413
+ topicsUserManaged: row.topics_user_managed ?? false,
21414
+ topics: parseTopics(row.topics),
21415
+ topicsUpdatedAt: row.topics_updated_at ?? null,
21416
+ topicsExtractedAt: row.topics_extracted_at ?? null,
21417
+ topicsExtractedVersion: row.topics_extracted_version ?? null,
21418
+ supersededBy: row.superseded_by ?? null,
21419
+ supersededAt: row.superseded_at ?? null,
21420
+ lastObservedAt: row.last_observed_at ?? null,
21421
+ factType: row.fact_type ?? null,
21422
+ archivedAt: row.archived_at ?? null,
21423
+ trustTier: row.trust_tier ?? null,
21424
+ visibility: row.visibility === "public" ? "public" : "private",
21425
+ twinOptIn: row.twin_opt_in ?? false,
21426
+ publishedAt: row.published_at ?? null,
21427
+ geohash: row.geohash ?? null,
21428
+ createdAt: new Date(row.created_at),
21429
+ updatedAt: new Date(row.updated_at),
21430
+ isDeleted: row.is_deleted
21431
+ };
21432
+ }
21433
+ function createRemoteMemoryPipeline(options) {
21434
+ const { persistence, embeddingOptions } = options;
21435
+ const model = embeddingOptions.model ?? DEFAULT_API_EMBEDDING_MODEL;
21436
+ const operation = (mode) => {
21437
+ const rejectUndecryptable = (failed) => {
21438
+ if (!failed.length) return;
21439
+ if (mode === "retain")
21440
+ throw new Error(
21441
+ `Remote memories could not decrypt ${failed.length} candidate row(s); refusing to retain until they are repaired`
21442
+ );
21443
+ getLogger().warn(
21444
+ `[memory/remote] Skipping ${failed.length} undecryptable candidate row(s)`,
21445
+ failed.map((failure) => failure.memory_id)
21446
+ );
21447
+ };
21448
+ const snapshots = /* @__PURE__ */ new Map();
21449
+ const remember = (items) => {
21450
+ items.forEach((item) => snapshots.set(item.memory.memory_id, item));
21451
+ return items.map((item) => stored(item.memory));
21452
+ };
21453
+ const get = async (id) => {
21454
+ const snapshot = snapshots.get(id) ?? await persistence.get(id);
21455
+ if (!snapshot || snapshot.memory.is_deleted || snapshot.memory.superseded_by) return null;
21456
+ snapshots.set(id, snapshot);
21457
+ return stored(snapshot.memory);
21458
+ };
21459
+ const prepare = async (query, search = {}) => {
21460
+ if (search.folderId !== void 0)
21461
+ throw new Error("Remote memories do not support folder filters");
21462
+ const facets = normalizeSubQueries(search.subQueries);
21463
+ const facetQueries = facets.length >= 2 ? facets : [];
21464
+ const start = Date.now();
21465
+ const budgetMs = search.queryEmbedTotalTimeoutMs ?? 8e3;
21466
+ const embed = (texts) => generateEmbeddings(texts, {
21467
+ ...embeddingOptions,
21468
+ totalTimeoutMs: budgetMs
21469
+ });
21470
+ const embedFacets = async () => {
21471
+ if (!facetQueries.length) return [];
21472
+ try {
21473
+ const vectors2 = await embed(facetQueries);
21474
+ if (vectors2.length !== facetQueries.length)
21475
+ throw new Error("Incomplete facet embeddings");
21476
+ return vectors2.map(storedVector);
21477
+ } catch (error) {
21478
+ getLogger().warn(
21479
+ "[memory/remote] Facet embeddings unavailable; using primary query",
21480
+ error
21481
+ );
21482
+ return [];
21483
+ }
21484
+ };
21485
+ const [primary, facetEmbeddings] = await Promise.all([
21486
+ search.queryEmbedding ?? embed([query]).then((vectors2) => vectors2[0]),
21487
+ embedFacets()
21488
+ ]);
21489
+ const queryEmbedding = storedVector(primary);
21490
+ const queryEmbedMs = Date.now() - start;
21491
+ const graph = search.entityRanking ?? [];
21492
+ const temporal = search.temporalRanking ?? [];
21493
+ const forced = /* @__PURE__ */ new Set();
21494
+ for (let i = 0; i < Math.max(graph.length, temporal.length) && forced.size < 100; i++) {
21495
+ if (graph[i] !== void 0) forced.add(graph[i]);
21496
+ if (forced.size < 100 && temporal[i] !== void 0) forced.add(temporal[i]);
21497
+ }
21498
+ const forceIds = [...forced];
21499
+ const windowOptions = (i, signal) => ({
21500
+ limit: Math.min(100, Math.max((search.limit ?? 8) * 3, 30)),
21501
+ force_ids: i === 0 ? forceIds : [],
21502
+ ...search.scopes && { scopes: search.scopes },
21503
+ ...search.factTypes && { fact_types: search.factTypes },
21504
+ ...search.memoryIds !== void 0 && { memory_ids: search.memoryIds },
21505
+ include_archived: search.includeArchived,
21506
+ embedding_model: model,
21507
+ ...signal && { signal }
21508
+ });
21509
+ const vectors = [queryEmbedding, ...facetEmbeddings];
21510
+ let windows;
21511
+ if (mode === "retain") {
21512
+ windows = await Promise.all(
21513
+ vectors.map((embedding, i) => persistence.candidateSet(embedding, windowOptions(i)))
21514
+ );
21515
+ } else {
21516
+ const deadline = new AbortController();
21517
+ const timer = setTimeout(
21518
+ () => deadline.abort(
21519
+ new RemoteMemoryError("Remote recall exceeded its query budget", 408, "timeout")
21520
+ ),
21521
+ Math.max(0, start + budgetMs - Date.now())
21522
+ );
21523
+ try {
21524
+ windows = await Promise.all(
21525
+ vectors.map(
21526
+ (embedding, i) => persistence.candidates(embedding, windowOptions(i, deadline.signal))
21527
+ )
21528
+ );
21529
+ } finally {
21530
+ clearTimeout(timer);
21531
+ }
21532
+ }
21533
+ rejectUndecryptable([
21534
+ ...new Map(
21535
+ windows.flatMap((window2) => window2.failed).map((failure) => [failure.memory_id, failure])
21536
+ ).values()
21537
+ ]);
21538
+ const items = [
21539
+ ...new Map(
21540
+ windows.flatMap((window2) => window2.items).map((item) => [item.memory.memory_id, item])
21541
+ ).values()
21542
+ ];
21543
+ const memories = remember(items);
21544
+ return {
21545
+ memories,
21546
+ embeddedItems: memories.map((memory) => ({
21547
+ id: memory.uniqueId,
21548
+ content: memory.content,
21549
+ embedding: JSON.parse(memory.embedding ?? "[]"),
21550
+ createdAt: memory.createdAt,
21551
+ updatedAt: memory.updatedAt,
21552
+ proofCount: memory.proofCount,
21553
+ lastObservedAt: memory.lastObservedAt,
21554
+ eventTimeStart: memory.eventTimeStart,
21555
+ eventTimeEnd: memory.eventTimeEnd,
21556
+ eventTimeKind: memory.eventTimeKind === "point" || memory.eventTimeKind === "range" || memory.eventTimeKind === "ongoing" ? memory.eventTimeKind : null,
21557
+ factType: memory.factType,
21558
+ sourceChunkIds: memory.sourceChunkIds
21559
+ })),
21560
+ queryEmbedding,
21561
+ facetEmbeddings,
21562
+ vaultSize: Math.max(windows[0].total_count ?? 0, items.length),
21563
+ embeddingFailure: windows.some((window2) => (window2.unavailable_count ?? 0) > 0),
21564
+ embeddingsUnavailable: (windows[0].total_count ?? items.length) > 0 && !memories.some((memory) => memory.embedding),
21565
+ decryptLast: true,
21566
+ rowsDecrypted: items.length,
21567
+ queryEmbedMs,
21568
+ rowsEmbedded: 0
21569
+ };
21570
+ };
21571
+ const createRow = (input) => {
21572
+ if (input.folderId !== void 0 && input.folderId !== null)
21573
+ throw new Error("Remote memories do not support folders");
21574
+ const now = Date.now();
21575
+ return {
21576
+ memory_id: uuidv75(),
21577
+ content: input.content,
21578
+ scope: input.scope ?? "private",
21579
+ created_at: now,
21580
+ updated_at: now,
21581
+ is_deleted: false,
21582
+ ...input.embedding !== void 0 && {
21583
+ embedding: storedVector(JSON.parse(input.embedding)),
21584
+ embedding_model: input.embeddingModel
21585
+ },
21586
+ source_chunk_ids: JSON.stringify(input.sourceChunkIds ?? []),
21587
+ proof_count: input.proofCount ?? 1,
21588
+ source: input.source ?? "manual",
21589
+ ...input.eventTime && {
21590
+ event_time_start: input.eventTime.start ?? void 0,
21591
+ event_time_end: input.eventTime.end ?? void 0,
21592
+ event_time_kind: input.eventTime.kind ?? void 0
21593
+ },
21594
+ fact_type: input.factType,
21595
+ trust_tier: normalizeTrustTier(input.trustTier) ?? void 0,
21596
+ geohash: input.geohash,
21597
+ visibility: "private",
21598
+ twin_opt_in: false
21599
+ };
21600
+ };
21601
+ const write = async (memory, snapshot) => remember([await persistence.put(memory, snapshot)])[0];
21602
+ const port = {
21603
+ prepare,
21604
+ get,
21605
+ getFresh: async (id) => {
21606
+ const current = await persistence.get(id);
21607
+ return current && !current.memory.is_deleted && !current.memory.superseded_by ? stored(current.memory) : null;
21608
+ },
21609
+ tombstones: async (embedding, embeddingModel, scope, folderId) => {
21610
+ if (folderId !== void 0) throw new Error("Remote memories do not support folders");
21611
+ const window2 = await persistence.candidateSet(storedVector(embedding), {
21612
+ limit: 1,
21613
+ scopes: [scope],
21614
+ embedding_model: embeddingModel,
21615
+ strict_model: true,
21616
+ include_deleted: true,
21617
+ deleted_only: true
21618
+ });
21619
+ rejectUndecryptable(window2.failed);
21620
+ return remember(window2.items);
21621
+ },
21622
+ create: (input) => write(createRow(input), 0),
21623
+ update: async (id, patch) => {
21624
+ const existing = await get(id);
21625
+ if (!existing) return null;
21626
+ const snapshot = snapshots.get(id);
21627
+ const memory = {
21628
+ ...snapshot.memory,
21629
+ content: patch.content,
21630
+ updated_at: patch.preserveUpdatedAt ? snapshot.memory.updated_at : Date.now()
21631
+ };
21632
+ if (patch.scope !== void 0) memory.scope = patch.scope;
21633
+ if (patch.embedding === void 0 && patch.content !== snapshot.memory.content) {
21634
+ delete memory.embedding;
21635
+ delete memory.embedding_model;
21636
+ }
21637
+ if (patch.embedding !== void 0) {
21638
+ memory.embedding = patch.embedding === null ? [] : storedVector(JSON.parse(patch.embedding));
21639
+ memory.embedding_model = patch.embeddingModel ?? void 0;
21640
+ }
21641
+ const observed = sourceIds(memory.source_chunk_ids);
21642
+ const replay = !!patch.observationSourceIds?.length && patch.observationSourceIds.every((id2) => observed.includes(id2));
21643
+ if (patch.sourceChunkIds !== void 0)
21644
+ memory.source_chunk_ids = JSON.stringify(
21645
+ patch.observationSourceIds?.length ? [.../* @__PURE__ */ new Set([...observed, ...patch.sourceChunkIds])] : patch.sourceChunkIds
21646
+ );
21647
+ if (!replay) {
21648
+ if (patch.proofCountIncrement !== void 0)
21649
+ memory.proof_count = (memory.proof_count ?? 1) + patch.proofCountIncrement;
21650
+ else if (patch.proofCount !== void 0) memory.proof_count = patch.proofCount;
21651
+ if (patch.lastObservedAt !== void 0) memory.last_observed_at = patch.lastObservedAt;
21652
+ }
21653
+ if (patch.source !== void 0) memory.source = patch.source;
21654
+ if (patch.factType !== void 0) memory.fact_type = patch.factType;
21655
+ if (patch.trustTier !== void 0)
21656
+ memory.trust_tier = normalizeTrustTier(patch.trustTier) ?? void 0;
21657
+ if (patch.topicsUserManaged !== void 0)
21658
+ memory.topics_user_managed = patch.topicsUserManaged;
21659
+ if (patch.eventTime !== void 0) {
21660
+ memory.event_time_start = patch.eventTime.start ?? void 0;
21661
+ memory.event_time_end = patch.eventTime.end ?? void 0;
21662
+ memory.event_time_kind = patch.eventTime.kind ?? void 0;
21663
+ }
21664
+ if (patch.restore) memory.archived_at = void 0;
21665
+ return write(memory, snapshot);
21666
+ },
21667
+ supersede: async (id, successor) => {
21668
+ const [target, newer] = await Promise.all([get(id), get(successor)]);
21669
+ if (!target || !newer || id === successor) return false;
21670
+ const old = snapshots.get(id);
21671
+ const next = snapshots.get(successor);
21672
+ remember(
21673
+ await persistence.putMany([
21674
+ {
21675
+ memory: { ...old.memory, superseded_by: successor, superseded_at: Date.now() },
21676
+ expectedVersion: old
21677
+ },
21678
+ { memory: next.memory, expectedVersion: next }
21679
+ ])
21680
+ );
21681
+ return true;
21682
+ },
21683
+ createSuperseding: async (input, targetId) => {
21684
+ const target = await get(targetId);
21685
+ if (!target) return { created: null, retired: false };
21686
+ const snapshot = snapshots.get(targetId);
21687
+ const successor = createRow(input);
21688
+ const rows = remember(
21689
+ await persistence.putMany([
21690
+ { memory: successor, expectedVersion: 0 },
21691
+ {
21692
+ memory: {
21693
+ ...snapshot.memory,
21694
+ superseded_by: successor.memory_id,
21695
+ superseded_at: Date.now()
21696
+ },
21697
+ expectedVersion: snapshot
21698
+ }
21699
+ ])
21700
+ );
21701
+ return { created: rows[0], retired: true };
21702
+ }
21703
+ };
21704
+ return { prepare, port };
21705
+ };
21706
+ return {
21707
+ recall: async (query, recallOptions = {}) => {
21708
+ const { prepare } = operation("recall");
21709
+ return recall(
21710
+ query,
21711
+ {
21712
+ embeddingOptions,
21713
+ factSource: {
21714
+ graphRanking: options.graphRanking,
21715
+ temporalRanking: options.temporalRanking,
21716
+ search: async (text12, searchOptions) => {
21717
+ const prepared = await prepare(text12, searchOptions);
21718
+ const ranked = await rankPreparedVaultCandidates(
21719
+ text12,
21720
+ prepared,
21721
+ embeddingOptions,
21722
+ searchOptions
21723
+ );
21724
+ return {
21725
+ ...ranked,
21726
+ rankedOnCosine: prepared.memories.length > 0 && !prepared.embeddingsUnavailable,
21727
+ decryptLast: true,
21728
+ rowsDecrypted: prepared.rowsDecrypted,
21729
+ queryEmbedMs: prepared.queryEmbedMs,
21730
+ rowsEmbedded: 0
21731
+ };
21732
+ }
21733
+ }
21734
+ },
21735
+ { ...recallOptions, types: ["fact"] }
21736
+ );
21737
+ },
21738
+ retain: async (content, retainOptions) => {
21739
+ const { port } = operation("retain");
21740
+ return retainWithPersistence(
21741
+ content,
21742
+ {
21743
+ persistence: port,
21744
+ embeddingOptions,
21745
+ vaultCache: /* @__PURE__ */ new Map(),
21746
+ normalizeEmbedding: storedVector
21747
+ },
21748
+ retainOptions
21749
+ );
21750
+ }
21751
+ };
21752
+ }
21753
+
20955
21754
  // src/lib/memory/synthesizeProfile.ts
20956
21755
  var DEFAULT_SYNTHESIS_MODEL = "inclusionai/ling-2.6-flash";
20957
21756
  var DEFAULT_FACET_RECALL_LIMIT = 20;
@@ -27206,7 +28005,7 @@ async function uploadFileToICloud(filename, content) {
27206
28005
  const recordName = `backup_${filename.replace(/[^a-zA-Z0-9]/g, "_")}`;
27207
28006
  const arrayBuffer = await content.arrayBuffer();
27208
28007
  const base64Data = uint8ArrayToBase64(new Uint8Array(arrayBuffer));
27209
- const record = {
28008
+ const record2 = {
27210
28009
  recordType: RECORD_TYPE,
27211
28010
  recordName,
27212
28011
  fields: {
@@ -27216,7 +28015,7 @@ async function uploadFileToICloud(filename, content) {
27216
28015
  contentType: { value: content.type || "application/json" }
27217
28016
  }
27218
28017
  };
27219
- const response = await database.saveRecords(record);
28018
+ const response = await database.saveRecords(record2);
27220
28019
  if (!response.records || response.records.length === 0) {
27221
28020
  throw new Error("Failed to upload file to iCloud");
27222
28021
  }
@@ -27242,11 +28041,11 @@ async function listICloudFiles() {
27242
28041
  while (response.continuationMarker) {
27243
28042
  break;
27244
28043
  }
27245
- const files = allRecords.map((record) => ({
27246
- recordName: record.recordName,
27247
- filename: record.fields.filename?.value ?? "",
27248
- modifiedAt: new Date(record.modified?.timestamp ?? Date.now()),
27249
- size: typeof record.fields.data?.value === "object" && record.fields.data?.value !== null ? record.fields.data.value.size : 0
28044
+ const files = allRecords.map((record2) => ({
28045
+ recordName: record2.recordName,
28046
+ filename: record2.fields.filename?.value ?? "",
28047
+ modifiedAt: new Date(record2.modified?.timestamp ?? Date.now()),
28048
+ size: typeof record2.fields.data?.value === "object" && record2.fields.data?.value !== null ? record2.fields.data.value.size : 0
27250
28049
  }));
27251
28050
  return files.sort((a, b) => b.modifiedAt.getTime() - a.modifiedAt.getTime());
27252
28051
  }
@@ -27259,8 +28058,8 @@ async function downloadICloudFile(recordName) {
27259
28058
  if (!response.records || response.records.length === 0) {
27260
28059
  throw new Error(`File not found: ${recordName}`);
27261
28060
  }
27262
- const record = response.records[0];
27263
- const dataField = record.fields.data?.value;
28061
+ const record2 = response.records[0];
28062
+ const dataField = record2.fields.data?.value;
27264
28063
  if (!dataField) {
27265
28064
  throw new Error("No data in record");
27266
28065
  }
@@ -27294,12 +28093,12 @@ async function findICloudFile(filename) {
27294
28093
  if (!response.records || response.records.length === 0) {
27295
28094
  return null;
27296
28095
  }
27297
- const record = response.records[0];
28096
+ const record2 = response.records[0];
27298
28097
  return {
27299
- recordName: record.recordName,
27300
- filename: record.fields.filename?.value ?? "",
27301
- modifiedAt: new Date(record.modified?.timestamp ?? Date.now()),
27302
- size: typeof record.fields.data?.value === "object" && record.fields.data?.value !== null ? record.fields.data.value.size : 0
28098
+ recordName: record2.recordName,
28099
+ filename: record2.fields.filename?.value ?? "",
28100
+ modifiedAt: new Date(record2.modified?.timestamp ?? Date.now()),
28101
+ size: typeof record2.fields.data?.value === "object" && record2.fields.data?.value !== null ? record2.fields.data.value.size : 0
27303
28102
  };
27304
28103
  }
27305
28104
 
@@ -27457,8 +28256,8 @@ async function getStoredTokenData5(provider, walletAddress) {
27457
28256
  return null;
27458
28257
  }
27459
28258
  }
27460
- async function readTokenRow(stored, provider, walletAddress) {
27461
- if (stored.startsWith(ENCRYPTED_PREFIX6)) {
28259
+ async function readTokenRow(stored2, provider, walletAddress) {
28260
+ if (stored2.startsWith(ENCRYPTED_PREFIX6)) {
27462
28261
  if (!walletAddress) {
27463
28262
  getLogger().warn(
27464
28263
  `Encrypted OAuth token found for ${provider} but no wallet address provided`
@@ -27466,7 +28265,7 @@ async function readTokenRow(stored, provider, walletAddress) {
27466
28265
  return null;
27467
28266
  }
27468
28267
  try {
27469
- const encryptedData = stored.slice(ENCRYPTED_PREFIX6.length);
28268
+ const encryptedData = stored2.slice(ENCRYPTED_PREFIX6.length);
27470
28269
  let decryptedJson;
27471
28270
  try {
27472
28271
  decryptedJson = await decryptData(encryptedData, walletAddress);
@@ -27481,7 +28280,7 @@ async function readTokenRow(stored, provider, walletAddress) {
27481
28280
  return null;
27482
28281
  }
27483
28282
  }
27484
- return parsePlaintextToken(stored, walletAddress);
28283
+ return parsePlaintextToken(stored2, walletAddress);
27485
28284
  }
27486
28285
  async function storeTokenData5(provider, data, walletAddress) {
27487
28286
  if (typeof window === "undefined") return;
@@ -27557,8 +28356,8 @@ async function migrateUnencryptedTokens(provider, walletAddress) {
27557
28356
  const keys = [scopedKey, legacyKey];
27558
28357
  const isEncrypted2 = (value) => !!value && value.startsWith(ENCRYPTED_PREFIX6);
27559
28358
  const plaintextAt = (key) => {
27560
- const stored = sessionStorage.getItem(key) ?? localStorage.getItem(key);
27561
- return stored && !isEncrypted2(stored) ? stored : null;
28359
+ const stored2 = sessionStorage.getItem(key) ?? localStorage.getItem(key);
28360
+ return stored2 && !isEncrypted2(stored2) ? stored2 : null;
27562
28361
  };
27563
28362
  let tokenToMigrate = null;
27564
28363
  for (const key of keys) {
@@ -27570,8 +28369,8 @@ async function migrateUnencryptedTokens(provider, walletAddress) {
27570
28369
  }
27571
28370
  if (!tokenToMigrate) {
27572
28371
  for (const key of keys) {
27573
- const stored = sessionStorage.getItem(key);
27574
- if (isEncrypted2(localStorage.getItem(key)) && stored && !isEncrypted2(stored)) {
28372
+ const stored2 = sessionStorage.getItem(key);
28373
+ if (isEncrypted2(localStorage.getItem(key)) && stored2 && !isEncrypted2(stored2)) {
27575
28374
  sessionStorage.removeItem(key);
27576
28375
  }
27577
28376
  }
@@ -27627,17 +28426,17 @@ function storeOAuthState2(state) {
27627
28426
  }
27628
28427
  function getAndClearOAuthState4() {
27629
28428
  if (typeof window === "undefined") return null;
27630
- const stored = sessionStorage.getItem(STATE_STORAGE_KEY);
28429
+ const stored2 = sessionStorage.getItem(STATE_STORAGE_KEY);
27631
28430
  sessionStorage.removeItem(STATE_STORAGE_KEY);
27632
- if (!stored) return null;
28431
+ if (!stored2) return null;
27633
28432
  try {
27634
- const parsed = JSON.parse(stored);
28433
+ const parsed = JSON.parse(stored2);
27635
28434
  if (parsed && typeof parsed === "object" && "state" in parsed) {
27636
28435
  return parsed.state;
27637
28436
  }
27638
28437
  } catch {
27639
28438
  }
27640
- return stored;
28439
+ return stored2;
27641
28440
  }
27642
28441
  function isDropboxCallback() {
27643
28442
  if (typeof window === "undefined") return false;
@@ -27820,17 +28619,17 @@ function storeOAuthState3(state) {
27820
28619
  }
27821
28620
  function getAndClearOAuthState5() {
27822
28621
  if (typeof window === "undefined") return null;
27823
- const stored = sessionStorage.getItem(CODE_STORAGE_KEY4);
28622
+ const stored2 = sessionStorage.getItem(CODE_STORAGE_KEY4);
27824
28623
  sessionStorage.removeItem(CODE_STORAGE_KEY4);
27825
- if (!stored) return null;
28624
+ if (!stored2) return null;
27826
28625
  try {
27827
- const parsed = JSON.parse(stored);
28626
+ const parsed = JSON.parse(stored2);
27828
28627
  if (parsed && typeof parsed === "object" && "state" in parsed) {
27829
28628
  return parsed.state;
27830
28629
  }
27831
28630
  } catch {
27832
28631
  }
27833
- return stored;
28632
+ return stored2;
27834
28633
  }
27835
28634
  function isGoogleDriveCallback() {
27836
28635
  if (typeof window === "undefined") return false;
@@ -29760,18 +30559,18 @@ async function blobToDataUri(blob) {
29760
30559
  reader.readAsDataURL(blob);
29761
30560
  });
29762
30561
  }
29763
- async function storedToLlmapiMessage(stored, encryptionKey, resolveMediaByIds) {
29764
- let textContent = stored.content;
30562
+ async function storedToLlmapiMessage(stored2, encryptionKey, resolveMediaByIds) {
30563
+ let textContent = stored2.content;
29765
30564
  const fileUrlMap = /* @__PURE__ */ new Map();
29766
30565
  const imageParts = [];
29767
- if (stored.role !== "assistant" && stored.files?.length) {
29768
- for (const file of stored.files) {
30566
+ if (stored2.role !== "assistant" && stored2.files?.length) {
30567
+ for (const file of stored2.files) {
29769
30568
  if (isSendableImageURL(file.url)) {
29770
30569
  imageParts.push({
29771
30570
  type: "image_url",
29772
30571
  image_url: { url: file.url }
29773
30572
  });
29774
- } else if (file.sourceUrl && !isR2UrlExpired(file.sourceUrl, stored.createdAt)) {
30573
+ } else if (file.sourceUrl && !isR2UrlExpired(file.sourceUrl, stored2.createdAt)) {
29775
30574
  imageParts.push({
29776
30575
  type: "image_url",
29777
30576
  image_url: { url: file.sourceUrl }
@@ -29791,11 +30590,11 @@ async function storedToLlmapiMessage(stored, encryptionKey, resolveMediaByIds) {
29791
30590
  }
29792
30591
  }
29793
30592
  }
29794
- } else if (stored.role === "assistant" && stored.files?.length) {
30593
+ } else if (stored2.role === "assistant" && stored2.files?.length) {
29795
30594
  const expiredFileIds = [];
29796
- for (const file of stored.files) {
30595
+ for (const file of stored2.files) {
29797
30596
  if (file.sourceUrl) {
29798
- if (!isR2UrlExpired(file.sourceUrl, stored.createdAt)) {
30597
+ if (!isR2UrlExpired(file.sourceUrl, stored2.createdAt)) {
29799
30598
  fileUrlMap.set(file.id, file.sourceUrl);
29800
30599
  } else {
29801
30600
  expiredFileIds.push(file.id);
@@ -29808,11 +30607,11 @@ async function storedToLlmapiMessage(stored, encryptionKey, resolveMediaByIds) {
29808
30607
  [${expiredFileIds.length} expired image URL${expiredFileIds.length > 1 ? "s" : ""} omitted \u2014 the user can still see ${expiredFileIds.length > 1 ? "them" : "it"} locally]`;
29809
30608
  }
29810
30609
  }
29811
- if (stored.fileIds?.length && resolveMediaByIds) {
30610
+ if (stored2.fileIds?.length && resolveMediaByIds) {
29812
30611
  try {
29813
- const mediaItems = await resolveMediaByIds(stored.fileIds);
30612
+ const mediaItems = await resolveMediaByIds(stored2.fileIds);
29814
30613
  for (const media of mediaItems) {
29815
- if (media.sourceUrl && !isR2UrlExpired(media.sourceUrl, stored.createdAt)) {
30614
+ if (media.sourceUrl && !isR2UrlExpired(media.sourceUrl, stored2.createdAt)) {
29816
30615
  fileUrlMap.set(media.mediaId, media.sourceUrl);
29817
30616
  }
29818
30617
  }
@@ -29836,7 +30635,7 @@ async function storedToLlmapiMessage(stored, encryptionKey, resolveMediaByIds) {
29836
30635
  return "";
29837
30636
  }
29838
30637
  );
29839
- if (stored.role === "assistant" && fileUrlMap.size > 0) {
30638
+ if (stored2.role === "assistant" && fileUrlMap.size > 0) {
29840
30639
  const unreferencedImages = [...fileUrlMap.entries()].filter(
29841
30640
  ([, url]) => !textContent.includes(url)
29842
30641
  );
@@ -29848,11 +30647,11 @@ async function storedToLlmapiMessage(stored, encryptionKey, resolveMediaByIds) {
29848
30647
  textContent = textContent.replace(/\n{3,}/g, "\n\n").trim();
29849
30648
  const content = [{ type: "text", text: textContent }, ...imageParts];
29850
30649
  const messages = [];
29851
- if (stored.role === "assistant" && stored.toolCallEvents?.length) {
30650
+ if (stored2.role === "assistant" && stored2.toolCallEvents?.length) {
29852
30651
  messages.push({
29853
- role: stored.role,
30652
+ role: stored2.role,
29854
30653
  content: void 0,
29855
- tool_calls: stored.toolCallEvents.map((event) => ({
30654
+ tool_calls: stored2.toolCallEvents.map((event) => ({
29856
30655
  id: event.id,
29857
30656
  type: "function",
29858
30657
  function: {
@@ -29861,7 +30660,7 @@ async function storedToLlmapiMessage(stored, encryptionKey, resolveMediaByIds) {
29861
30660
  }
29862
30661
  }))
29863
30662
  });
29864
- for (const event of stored.toolCallEvents) {
30663
+ for (const event of stored2.toolCallEvents) {
29865
30664
  if (event.id && event.output !== void 0 && event.output !== null) {
29866
30665
  messages.push({
29867
30666
  role: "tool",
@@ -29872,12 +30671,12 @@ async function storedToLlmapiMessage(stored, encryptionKey, resolveMediaByIds) {
29872
30671
  }
29873
30672
  const postToolText = textContent.replace(/!\[[^\]]*\]\(https?:\/\/[a-z0-9]+\.r2\.cloudflarestorage\.com\/[^)]+\)/g, "").replace(/https?:\/\/[a-z0-9]+\.r2\.cloudflarestorage\.com\/[^\s)]+/g, "").replace(/!\[[^\]]*\]\(https?:\/\/[^)\s]+\/api\/v1\/media\/[^/)\s]+\/[^)]+\)/g, "").replace(/https?:\/\/[^\s)]+\/api\/v1\/media\/[^/\s)]+\/[^\s)]+/g, "").replace(/\n{3,}/g, "\n\n").trim();
29874
30673
  messages.push({
29875
- role: stored.role,
30674
+ role: stored2.role,
29876
30675
  content: [{ type: "text", text: postToolText }]
29877
30676
  });
29878
30677
  } else {
29879
30678
  messages.push({
29880
- role: stored.role,
30679
+ role: stored2.role,
29881
30680
  content
29882
30681
  });
29883
30682
  }
@@ -33708,19 +34507,19 @@ function startObserve(entry, walletAddress) {
33708
34507
  "updated_at"
33709
34508
  ]).subscribe({
33710
34509
  next: (records) => {
33711
- const record = records[0];
33712
- if (!record) return;
34510
+ const record2 = records[0];
34511
+ if (!record2) return;
33713
34512
  const patch = {
33714
34513
  userPreference: {
33715
- uniqueId: record.id,
33716
- walletAddress: record.walletAddress,
33717
- nickname: record.nickname,
33718
- occupation: record.occupation,
33719
- description: record.description,
33720
- models: record.models,
33721
- personality: record.personality,
33722
- createdAt: record.createdAt,
33723
- updatedAt: record.updatedAt
34514
+ uniqueId: record2.id,
34515
+ walletAddress: record2.walletAddress,
34516
+ nickname: record2.nickname,
34517
+ occupation: record2.occupation,
34518
+ description: record2.description,
34519
+ models: record2.models,
34520
+ personality: record2.personality,
34521
+ createdAt: record2.createdAt,
34522
+ updatedAt: record2.updatedAt
33724
34523
  }
33725
34524
  };
33726
34525
  if (isInitialEmission) {
@@ -34943,6 +35742,7 @@ export {
34943
35742
  R2_DEFAULT_TTL_MS,
34944
35743
  RECALL_MAX_LIMIT,
34945
35744
  RECALL_TOOL_NAME,
35745
+ RemoteMemoryError,
34946
35746
  RerankerUnavailableError,
34947
35747
  SDK_SCHEMA_VERSION,
34948
35748
  SERVER_TOOL_DEPENDENCY_SETS,
@@ -35034,6 +35834,8 @@ export {
35034
35834
  createPlatformCursorStore,
35035
35835
  createProjectOp,
35036
35836
  createRecallTool,
35837
+ createRemoteMemoryPersistence,
35838
+ createRemoteMemoryPipeline,
35037
35839
  createSavedToolOp,
35038
35840
  createServerToolsFilter,
35039
35841
  createStockPricePreProcessor,