@anuma/sdk 6.33.2 → 6.35.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()),
@@ -11306,6 +11318,15 @@ __decorateClass([
11306
11318
  __decorateClass([
11307
11319
  text6("scope")
11308
11320
  ], VaultMemory.prototype, "scope", 2);
11321
+ __decorateClass([
11322
+ field5("kind")
11323
+ ], VaultMemory.prototype, "kind", 2);
11324
+ __decorateClass([
11325
+ field5("kind_value")
11326
+ ], VaultMemory.prototype, "kindValue", 2);
11327
+ __decorateClass([
11328
+ field5("level")
11329
+ ], VaultMemory.prototype, "level", 2);
11309
11330
  __decorateClass([
11310
11331
  field5("folder_id")
11311
11332
  ], VaultMemory.prototype, "folderId", 2);
@@ -11531,7 +11552,7 @@ __decorateClass([
11531
11552
  ], VaultFolder.prototype, "context", 2);
11532
11553
 
11533
11554
  // src/lib/db/schema.ts
11534
- var SDK_SCHEMA_VERSION = 47;
11555
+ var SDK_SCHEMA_VERSION = 48;
11535
11556
  var sdkSchema = appSchema2({
11536
11557
  version: SDK_SCHEMA_VERSION,
11537
11558
  tables: [
@@ -11626,6 +11647,9 @@ var sdkSchema = appSchema2({
11626
11647
  columns: [
11627
11648
  { name: "content", type: "string" },
11628
11649
  { name: "scope", type: "string", isIndexed: true },
11650
+ { name: "kind", type: "string", isOptional: true, isIndexed: true },
11651
+ { name: "kind_value", type: "string", isOptional: true },
11652
+ { name: "level", type: "string", isOptional: true, isIndexed: true },
11629
11653
  { name: "folder_id", type: "string", isOptional: true, isIndexed: true },
11630
11654
  { name: "created_at", type: "number", isIndexed: true },
11631
11655
  { name: "updated_at", type: "number", isIndexed: true },
@@ -12302,6 +12326,22 @@ var sdkMigrations = schemaMigrations2({
12302
12326
  ]
12303
12327
  })
12304
12328
  ]
12329
+ },
12330
+ {
12331
+ toVersion: 48,
12332
+ steps: [
12333
+ addColumns2({
12334
+ table: "memory_vault",
12335
+ columns: [
12336
+ { name: "kind", type: "string", isOptional: true, isIndexed: true },
12337
+ { name: "kind_value", type: "string", isOptional: true },
12338
+ { name: "level", type: "string", isOptional: true, isIndexed: true }
12339
+ ]
12340
+ }),
12341
+ unsafeExecuteSql(
12342
+ "UPDATE memory_vault SET level = CASE WHEN scope IN ('shared', 'public') THEN 'matching' ELSE 'private' END WHERE level IS NULL;"
12343
+ )
12344
+ ]
12305
12345
  }
12306
12346
  ]
12307
12347
  });
@@ -13172,13 +13212,13 @@ async function relinkMisclassifiedVideosOp(ctx, walletAddress) {
13172
13212
  toRelink.push({ media, ext: mime.split("/")[1] || "mp4" });
13173
13213
  continue;
13174
13214
  }
13175
- const stored = await mediaToStored(
13215
+ const stored2 = await mediaToStored(
13176
13216
  media,
13177
13217
  ctx.walletAddress,
13178
13218
  ctx.signMessage,
13179
13219
  ctx.embeddedWalletSigner
13180
13220
  );
13181
- const ext = videoExtensionOf(stored.sourceUrl) ?? videoExtensionOf(stored.name);
13221
+ const ext = videoExtensionOf(stored2.sourceUrl) ?? videoExtensionOf(stored2.name);
13182
13222
  if (ext) {
13183
13223
  toRelink.push({ media, ext });
13184
13224
  }
@@ -13438,13 +13478,54 @@ async function decryptVaultMemoryFields(memory, address, signMessage, embeddedWa
13438
13478
  }
13439
13479
  }
13440
13480
  const decryptedContent = await decryptField(memory.content, address);
13481
+ const decryptedKindValue = typeof memory.kindValue === "string" ? await decryptField(memory.kindValue, address) : memory.kindValue;
13441
13482
  return {
13442
13483
  ...memory,
13443
- content: decryptedContent
13484
+ content: decryptedContent,
13485
+ ...decryptedKindValue !== void 0 && { kindValue: decryptedKindValue }
13444
13486
  };
13445
13487
  }
13446
13488
 
13447
13489
  // src/lib/db/memoryVault/types.ts
13490
+ var MEMORY_KINDS = [
13491
+ "display_name",
13492
+ "birth_date",
13493
+ "bio",
13494
+ "occupation",
13495
+ "interest",
13496
+ "gender",
13497
+ "height_cm",
13498
+ "looking_for",
13499
+ "politics",
13500
+ "religion",
13501
+ "ethnicity",
13502
+ "smoking",
13503
+ "drinking",
13504
+ "exercise",
13505
+ "sexuality",
13506
+ "prompt"
13507
+ ];
13508
+ var MEMORY_LEVELS = ["private", "matching", "profile"];
13509
+ var MemoryLevelError = class extends Error {
13510
+ constructor(message) {
13511
+ super(message);
13512
+ this.name = "MemoryLevelError";
13513
+ }
13514
+ };
13515
+ var PUBLISHED_SCOPES = /* @__PURE__ */ new Set(["shared", "public"]);
13516
+ function levelFromScope(scope) {
13517
+ return typeof scope === "string" && PUBLISHED_SCOPES.has(scope) ? "matching" : "private";
13518
+ }
13519
+ function scopeForLevel(level) {
13520
+ return level === "private" ? "private" : "shared";
13521
+ }
13522
+ function resolveMemoryLevel(level, scope) {
13523
+ return typeof level === "string" && MEMORY_LEVELS.includes(level) ? level : levelFromScope(scope);
13524
+ }
13525
+ function levelForScopeChange(current, nextScope) {
13526
+ const implied = levelFromScope(nextScope);
13527
+ return implied === "matching" && resolveMemoryLevel(current.level, current.scope) === "profile" ? "profile" : implied;
13528
+ }
13448
13529
  function parseMedia(value) {
13449
13530
  if (typeof value !== "string" || value === "") return null;
13450
13531
  try {
@@ -13474,8 +13555,58 @@ function visibilityConditions(requested) {
13474
13555
  if (excluded.length === 0) return [];
13475
13556
  return [Q8.or(Q8.where("visibility", null), Q8.where("visibility", Q8.notIn(excluded)))];
13476
13557
  }
13477
- function isOwnedByCtxUser(ctx, record) {
13478
- return ctx.userId === void 0 || record.userId === ctx.userId;
13558
+ function isKinded(record2) {
13559
+ return record2.kind !== null && record2.kind !== void 0;
13560
+ }
13561
+ function assertValidKindLevel(kind, level) {
13562
+ const hasKind = kind !== null && kind !== void 0;
13563
+ if (hasKind && !MEMORY_KINDS.includes(kind)) {
13564
+ throw new MemoryLevelError(`Unknown memory kind: ${kind}`);
13565
+ }
13566
+ if (level !== void 0 && !MEMORY_LEVELS.includes(level)) {
13567
+ throw new MemoryLevelError(`Unknown memory level: ${level}`);
13568
+ }
13569
+ if (level === "profile" && !hasKind) {
13570
+ throw new MemoryLevelError("Only a memory with a kind can be at level 'profile'");
13571
+ }
13572
+ }
13573
+ function resolveCreateLevel(opts) {
13574
+ if (opts.level !== void 0) return { level: opts.level, scope: scopeForLevel(opts.level) };
13575
+ if (opts.scope !== void 0) return { level: levelFromScope(opts.scope), scope: opts.scope };
13576
+ return { level: "private", scope: "private" };
13577
+ }
13578
+ async function encryptKindValue(ctx, value) {
13579
+ if (typeof value !== "string" || !ctx.walletAddress || !ctx.signMessage) return value;
13580
+ return encryptVaultMemoryContent(
13581
+ value,
13582
+ ctx.walletAddress,
13583
+ ctx.signMessage,
13584
+ ctx.embeddedWalletSigner
13585
+ );
13586
+ }
13587
+ function levelConditions(requested) {
13588
+ if (!requested?.length) return [];
13589
+ const published = ["shared", "public"];
13590
+ const wantsMatching = requested.includes("matching");
13591
+ const wantsPrivate = requested.includes("private");
13592
+ const unresolved = Q8.or(Q8.where("level", null), Q8.where("level", Q8.notIn([...MEMORY_LEVELS])));
13593
+ const byLevel = Q8.where("level", Q8.oneOf([...requested]));
13594
+ if (wantsMatching && wantsPrivate) return [Q8.or(byLevel, unresolved)];
13595
+ if (wantsMatching) {
13596
+ return [Q8.or(byLevel, Q8.and(unresolved, Q8.where("scope", Q8.oneOf(published))))];
13597
+ }
13598
+ if (wantsPrivate) {
13599
+ return [
13600
+ Q8.or(
13601
+ byLevel,
13602
+ Q8.and(unresolved, Q8.or(Q8.where("scope", null), Q8.where("scope", Q8.notIn(published))))
13603
+ )
13604
+ ];
13605
+ }
13606
+ return [byLevel];
13607
+ }
13608
+ function isOwnedByCtxUser(ctx, record2) {
13609
+ return ctx.userId === void 0 || record2.userId === ctx.userId;
13479
13610
  }
13480
13611
  function baseVaultConditions(ctx, options) {
13481
13612
  return [
@@ -13517,6 +13648,9 @@ function vaultMemoryToStoredRaw(memory) {
13517
13648
  uniqueId: memory.id,
13518
13649
  content: memory.content,
13519
13650
  scope: memory.scope,
13651
+ kind: memory.kind ?? null,
13652
+ kindValue: memory.kindValue ?? null,
13653
+ level: resolveMemoryLevel(memory.level, memory.scope),
13520
13654
  folderId: memory.folderId ?? null,
13521
13655
  userId: memory.userId ?? null,
13522
13656
  embedding: memory.embedding ?? null,
@@ -13555,42 +13689,48 @@ async function vaultMemoryToStored(memory, walletAddress, signMessage, embeddedW
13555
13689
  }
13556
13690
  return raw;
13557
13691
  }
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);
13692
+ function populateNewVaultMemory(record2, ctx, opts, encryptedContent, encryptedKindValue) {
13693
+ const { level, scope } = resolveCreateLevel(opts);
13694
+ record2._setRaw("content", encryptedContent);
13695
+ record2._setRaw("scope", scope);
13696
+ record2._setRaw("level", level);
13697
+ record2._setRaw("kind", opts.kind ?? null);
13698
+ record2._setRaw("kind_value", encryptedKindValue ?? null);
13699
+ record2._setRaw("folder_id", opts.folderId ?? null);
13700
+ record2._setRaw("user_id", ctx.userId ?? null);
13701
+ record2._setRaw("is_deleted", false);
13564
13702
  if (opts.embedding !== void 0) {
13565
- record._setRaw("embedding", opts.embedding);
13566
- record._setRaw("embedding_model", opts.embeddingModel ?? null);
13703
+ record2._setRaw("embedding", opts.embedding);
13704
+ record2._setRaw("embedding_model", opts.embeddingModel ?? null);
13567
13705
  }
13568
13706
  if (opts.sourceChunkIds !== void 0) {
13569
- record._setRaw("source_chunk_ids", JSON.stringify(opts.sourceChunkIds));
13707
+ record2._setRaw("source_chunk_ids", JSON.stringify(opts.sourceChunkIds));
13570
13708
  }
13571
- record._setRaw("proof_count", opts.proofCount ?? 1);
13572
- record._setRaw("source", opts.source ?? "manual");
13709
+ record2._setRaw("proof_count", opts.proofCount ?? 1);
13710
+ record2._setRaw("source", opts.source ?? "manual");
13573
13711
  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);
13712
+ record2._setRaw("event_time_start", opts.eventTime.start ?? null);
13713
+ record2._setRaw("event_time_end", opts.eventTime.end ?? null);
13714
+ record2._setRaw("event_time_kind", opts.eventTime.kind ?? null);
13577
13715
  }
13578
13716
  if (opts.factType !== void 0) {
13579
- record._setRaw("fact_type", opts.factType);
13717
+ record2._setRaw("fact_type", opts.factType);
13580
13718
  }
13581
13719
  if (opts.trustTier !== void 0) {
13582
- record._setRaw("trust_tier", normalizeTrustTier(opts.trustTier));
13720
+ record2._setRaw("trust_tier", normalizeTrustTier(opts.trustTier));
13583
13721
  }
13584
- record._setRaw("visibility", opts.visibility ?? "private");
13585
- record._setRaw(
13722
+ record2._setRaw("visibility", opts.visibility ?? "private");
13723
+ record2._setRaw(
13586
13724
  "published_at",
13587
13725
  opts.visibility && opts.visibility !== "private" ? opts.publishedAt ?? Date.now() : null
13588
13726
  );
13589
13727
  if (opts.geohash !== void 0) {
13590
- record._setRaw("geohash", opts.geohash);
13728
+ record2._setRaw("geohash", opts.geohash);
13591
13729
  }
13592
13730
  }
13593
13731
  async function createVaultMemoryOp(ctx, opts) {
13732
+ assertValidKindLevel(opts.kind, resolveCreateLevel(opts).level);
13733
+ const encryptedKindValue = await encryptKindValue(ctx, opts.kindValue);
13594
13734
  const encryptedContent = ctx.walletAddress && ctx.signMessage ? await encryptVaultMemoryContent(
13595
13735
  opts.content,
13596
13736
  ctx.walletAddress,
@@ -13601,13 +13741,15 @@ async function createVaultMemoryOp(ctx, opts) {
13601
13741
  if (ctx.canWrite && !await ctx.canWrite())
13602
13742
  throw new Error("Memory source is no longer eligible");
13603
13743
  return ctx.vaultMemoryCollection.create(
13604
- (record) => populateNewVaultMemory(record, ctx, opts, encryptedContent)
13744
+ (record2) => populateNewVaultMemory(record2, ctx, opts, encryptedContent, encryptedKindValue)
13605
13745
  );
13606
13746
  });
13607
13747
  return vaultMemoryToStored(created, ctx.walletAddress, ctx.signMessage, ctx.embeddedWalletSigner);
13608
13748
  }
13609
13749
  async function createSupersedingMemoryOp(ctx, opts, targetId) {
13610
13750
  if (!targetId) return { created: null, retired: false };
13751
+ assertValidKindLevel(opts.kind, resolveCreateLevel(opts).level);
13752
+ const encryptedKindValue = await encryptKindValue(ctx, opts.kindValue);
13611
13753
  const encryptedContent = ctx.walletAddress && ctx.signMessage ? await encryptVaultMemoryContent(
13612
13754
  opts.content,
13613
13755
  ctx.walletAddress,
@@ -13624,9 +13766,10 @@ async function createSupersedingMemoryOp(ctx, opts, targetId) {
13624
13766
  } catch {
13625
13767
  return;
13626
13768
  }
13627
- if (target.isDeleted || target.supersededBy || !isOwnedByCtxUser(ctx, target)) return;
13769
+ if (target.isDeleted || target.supersededBy || isKinded(target) || !isOwnedByCtxUser(ctx, target))
13770
+ return;
13628
13771
  createdRecord = await ctx.vaultMemoryCollection.create(
13629
- (record) => populateNewVaultMemory(record, ctx, opts, encryptedContent)
13772
+ (record2) => populateNewVaultMemory(record2, ctx, opts, encryptedContent, encryptedKindValue)
13630
13773
  );
13631
13774
  await target.update((r) => {
13632
13775
  r._setRaw("superseded_by", createdRecord.id);
@@ -13690,6 +13833,10 @@ async function getMemoriesByEventTimeOp(ctx, windowStart, windowEnd) {
13690
13833
  }
13691
13834
  async function createVaultMemoriesBatchOp(ctx, optionsArray) {
13692
13835
  if (optionsArray.length === 0) return [];
13836
+ for (const opts of optionsArray) assertValidKindLevel(opts.kind, resolveCreateLevel(opts).level);
13837
+ const encryptedKindValues = await Promise.all(
13838
+ optionsArray.map((opts) => encryptKindValue(ctx, opts.kindValue))
13839
+ );
13693
13840
  const encryptedContents = await Promise.all(
13694
13841
  optionsArray.map(async (opts) => {
13695
13842
  if (ctx.walletAddress && ctx.signMessage) {
@@ -13708,7 +13855,7 @@ async function createVaultMemoriesBatchOp(ctx, optionsArray) {
13708
13855
  throw new Error("Memory source is no longer eligible");
13709
13856
  const prepared = optionsArray.map(
13710
13857
  (opts, i) => ctx.vaultMemoryCollection.prepareCreate(
13711
- (record) => populateNewVaultMemory(record, ctx, opts, encryptedContents[i])
13858
+ (record2) => populateNewVaultMemory(record2, ctx, opts, encryptedContents[i], encryptedKindValues[i])
13712
13859
  )
13713
13860
  );
13714
13861
  await ctx.database.batch(...prepared);
@@ -13716,16 +13863,16 @@ async function createVaultMemoriesBatchOp(ctx, optionsArray) {
13716
13863
  });
13717
13864
  return Promise.all(
13718
13865
  created.map(
13719
- (record) => vaultMemoryToStored(record, ctx.walletAddress, ctx.signMessage, ctx.embeddedWalletSigner)
13866
+ (record2) => vaultMemoryToStored(record2, ctx.walletAddress, ctx.signMessage, ctx.embeddedWalletSigner)
13720
13867
  )
13721
13868
  );
13722
13869
  }
13723
13870
  async function getVaultMemoryOp(ctx, id) {
13724
13871
  try {
13725
- const record = await ctx.vaultMemoryCollection.find(id);
13726
- if (record.isDeleted || !isOwnedByCtxUser(ctx, record)) return null;
13872
+ const record2 = await ctx.vaultMemoryCollection.find(id);
13873
+ if (record2.isDeleted || !isOwnedByCtxUser(ctx, record2)) return null;
13727
13874
  return vaultMemoryToStored(
13728
- record,
13875
+ record2,
13729
13876
  ctx.walletAddress,
13730
13877
  ctx.signMessage,
13731
13878
  ctx.embeddedWalletSigner
@@ -13751,6 +13898,9 @@ function vaultMemoryRawToStoredRaw(raw) {
13751
13898
  uniqueId: raw.id,
13752
13899
  content: raw.content ?? "",
13753
13900
  scope: raw.scope ?? "",
13901
+ kind: raw.kind ?? null,
13902
+ kindValue: raw.kind_value ?? null,
13903
+ level: resolveMemoryLevel(raw.level, raw.scope),
13754
13904
  folderId: raw.folder_id ?? null,
13755
13905
  userId: raw.user_id ?? null,
13756
13906
  embedding: raw.embedding ?? null,
@@ -13783,17 +13933,19 @@ function vaultMemoryRawToStoredRaw(raw) {
13783
13933
  };
13784
13934
  }
13785
13935
  async function vaultMemoryRawToStored(raw, walletAddress, signMessage, embeddedWalletSigner) {
13786
- const stored = vaultMemoryRawToStoredRaw(raw);
13936
+ const stored2 = vaultMemoryRawToStoredRaw(raw);
13787
13937
  if (walletAddress) {
13788
- return decryptVaultMemoryFields(stored, walletAddress, signMessage, embeddedWalletSigner);
13938
+ return decryptVaultMemoryFields(stored2, walletAddress, signMessage, embeddedWalletSigner);
13789
13939
  }
13790
- return stored;
13940
+ return stored2;
13791
13941
  }
13792
13942
  async function getAllVaultMemoriesOp(ctx, options) {
13793
13943
  const conditions = [
13794
13944
  ...baseVaultConditions(ctx, options),
13795
13945
  ...options?.scopes?.length ? [Q8.where("scope", Q8.oneOf(options.scopes))] : [],
13796
13946
  ...visibilityConditions(options?.visibility),
13947
+ ...levelConditions(options?.levels),
13948
+ ...options?.kinds?.length ? [Q8.where("kind", Q8.oneOf(options.kinds))] : [],
13797
13949
  ...options?.folderId !== void 0 ? [Q8.where("folder_id", options.folderId)] : [],
13798
13950
  ...options?.factTypes?.length ? [Q8.where("fact_type", Q8.oneOf(options.factTypes))] : [],
13799
13951
  Q8.sortBy(options?.since ? "updated_at" : "created_at", Q8.desc),
@@ -13939,13 +14091,13 @@ async function getVaultMemoriesByIdsOp(ctx, ids, options) {
13939
14091
  async function getAllVaultMemoryContentsOp(ctx, options) {
13940
14092
  const results = await ctx.vaultMemoryCollection.query(...baseVaultConditions(ctx, options)).unsafeFetchRaw();
13941
14093
  return mapInBatches(results, async (raw) => {
13942
- const stored = await vaultMemoryRawToStored(
14094
+ const stored2 = await vaultMemoryRawToStored(
13943
14095
  raw,
13944
14096
  ctx.walletAddress,
13945
14097
  ctx.signMessage,
13946
14098
  ctx.embeddedWalletSigner
13947
14099
  );
13948
- return stored.content;
14100
+ return stored2.content;
13949
14101
  });
13950
14102
  }
13951
14103
  async function countActiveVaultMemoriesOp(ctx) {
@@ -13960,6 +14112,14 @@ async function updateVaultMemoryOp(ctx, id, opts) {
13960
14112
  try {
13961
14113
  const probe = await ctx.vaultMemoryCollection.find(id);
13962
14114
  if (probe.isDeleted || probe.supersededBy || !isOwnedByCtxUser(ctx, probe)) return null;
14115
+ if (opts.freeFormOnly && isKinded(probe)) return null;
14116
+ const levelAfter = (current) => {
14117
+ if (opts.level !== void 0) return opts.level;
14118
+ if (opts.scope === void 0) return resolveMemoryLevel(current.level, current.scope);
14119
+ return levelForScopeChange(current, opts.scope);
14120
+ };
14121
+ assertValidKindLevel(opts.kind !== void 0 ? opts.kind : probe.kind, levelAfter(probe));
14122
+ const encryptedKindValue = await encryptKindValue(ctx, opts.kindValue);
13963
14123
  const encryptedContent = ctx.walletAddress && ctx.signMessage ? await encryptVaultMemoryContent(
13964
14124
  opts.content,
13965
14125
  ctx.walletAddress,
@@ -13967,30 +14127,43 @@ async function updateVaultMemoryOp(ctx, id, opts) {
13967
14127
  ctx.embeddedWalletSigner
13968
14128
  ) : opts.content;
13969
14129
  let stale = false;
13970
- const record = probe;
13971
- const originalUpdatedAt = record.updatedAt.getTime();
14130
+ const record2 = probe;
14131
+ const originalUpdatedAt = record2.updatedAt.getTime();
13972
14132
  await ctx.database.write(async () => {
13973
14133
  if (ctx.canWrite && !await ctx.canWrite())
13974
14134
  throw new Error("Memory source is no longer eligible");
13975
- if (record.isDeleted || record.supersededBy || !isOwnedByCtxUser(ctx, record)) {
14135
+ if (record2.isDeleted || record2.supersededBy || !isOwnedByCtxUser(ctx, record2) || opts.freeFormOnly && isKinded(record2)) {
13976
14136
  stale = true;
13977
14137
  return;
13978
14138
  }
14139
+ const nextKind = opts.kind !== void 0 ? opts.kind : record2.kind;
14140
+ const nextLevel = levelAfter(record2);
14141
+ assertValidKindLevel(nextKind, nextLevel);
13979
14142
  let observedSources = [];
13980
14143
  let replayedObservation = false;
13981
14144
  if (opts.observationSourceIds?.length) {
13982
14145
  try {
13983
- const parsed = JSON.parse(record.sourceChunkIds ?? "[]");
14146
+ const parsed = JSON.parse(record2.sourceChunkIds ?? "[]");
13984
14147
  if (Array.isArray(parsed))
13985
14148
  observedSources = parsed.filter((id2) => typeof id2 === "string");
13986
14149
  } catch {
13987
14150
  }
13988
14151
  replayedObservation = opts.observationSourceIds.every((id2) => observedSources.includes(id2));
13989
14152
  }
13990
- await record.update((r) => {
14153
+ await record2.update((r) => {
13991
14154
  r._setRaw("content", encryptedContent);
13992
- if (opts.scope !== void 0) {
14155
+ if (opts.level !== void 0) {
14156
+ r._setRaw("level", nextLevel);
14157
+ r._setRaw("scope", scopeForLevel(nextLevel));
14158
+ } else if (opts.scope !== void 0) {
13993
14159
  r._setRaw("scope", opts.scope);
14160
+ r._setRaw("level", nextLevel);
14161
+ }
14162
+ if (opts.kind !== void 0) {
14163
+ r._setRaw("kind", opts.kind);
14164
+ }
14165
+ if (encryptedKindValue !== void 0) {
14166
+ r._setRaw("kind_value", encryptedKindValue);
13994
14167
  }
13995
14168
  if (opts.folderId !== void 0) {
13996
14169
  r._setRaw("folder_id", opts.folderId);
@@ -14044,12 +14217,13 @@ async function updateVaultMemoryOp(ctx, id, opts) {
14044
14217
  });
14045
14218
  if (stale) return null;
14046
14219
  return vaultMemoryToStored(
14047
- record,
14220
+ record2,
14048
14221
  ctx.walletAddress,
14049
14222
  ctx.signMessage,
14050
14223
  ctx.embeddedWalletSigner
14051
14224
  );
14052
- } catch {
14225
+ } catch (err) {
14226
+ if (err instanceof MemoryLevelError) throw err;
14053
14227
  return null;
14054
14228
  }
14055
14229
  }
@@ -14058,21 +14232,21 @@ async function setMemoryEntitiesOp(ctx, memoryId, entities) {
14058
14232
  if (!entityCtx) {
14059
14233
  throw new Error("setMemoryEntitiesOp requires ctx.entityCtx (entity collections)");
14060
14234
  }
14061
- let record;
14235
+ let record2;
14062
14236
  try {
14063
- record = await ctx.vaultMemoryCollection.find(memoryId);
14237
+ record2 = await ctx.vaultMemoryCollection.find(memoryId);
14064
14238
  } catch {
14065
14239
  return null;
14066
14240
  }
14067
- if (record.isDeleted || !isOwnedByCtxUser(ctx, record)) return null;
14241
+ if (record2.isDeleted || !isOwnedByCtxUser(ctx, record2)) return null;
14068
14242
  let stale = false;
14069
- const originalUpdatedAt = record.updatedAt.getTime();
14243
+ const originalUpdatedAt = record2.updatedAt.getTime();
14070
14244
  await ctx.database.write(async (writer) => {
14071
- if (record.isDeleted || !isOwnedByCtxUser(ctx, record)) {
14245
+ if (record2.isDeleted || !isOwnedByCtxUser(ctx, record2)) {
14072
14246
  stale = true;
14073
14247
  return;
14074
14248
  }
14075
- await record.update((r) => {
14249
+ await record2.update((r) => {
14076
14250
  r._setRaw("topics_user_managed", true);
14077
14251
  r._setRaw("updated_at", originalUpdatedAt);
14078
14252
  });
@@ -14096,25 +14270,25 @@ async function setMemoryEntitiesOp(ctx, memoryId, entities) {
14096
14270
  );
14097
14271
  });
14098
14272
  if (stale) return null;
14099
- return vaultMemoryToStored(record, ctx.walletAddress, ctx.signMessage, ctx.embeddedWalletSigner);
14273
+ return vaultMemoryToStored(record2, ctx.walletAddress, ctx.signMessage, ctx.embeddedWalletSigner);
14100
14274
  }
14101
14275
  async function clearMemoryTopicsOverrideOp(ctx, memoryId, options) {
14102
- let record;
14276
+ let record2;
14103
14277
  try {
14104
- record = await ctx.vaultMemoryCollection.find(memoryId);
14278
+ record2 = await ctx.vaultMemoryCollection.find(memoryId);
14105
14279
  } catch {
14106
14280
  return false;
14107
14281
  }
14108
- if (record.isDeleted || !isOwnedByCtxUser(ctx, record)) return false;
14109
- const originalUpdatedAt = record.updatedAt.getTime();
14282
+ if (record2.isDeleted || !isOwnedByCtxUser(ctx, record2)) return false;
14283
+ const originalUpdatedAt = record2.updatedAt.getTime();
14110
14284
  let cleared = false;
14111
14285
  await ctx.database.write(async () => {
14112
- if (options?.unlessTopicsRecorded && parseTopics(record.topics) !== null) return;
14286
+ if (options?.unlessTopicsRecorded && parseTopics(record2.topics) !== null) return;
14113
14287
  cleared = true;
14114
- await record.update((r) => {
14288
+ await record2.update((r) => {
14115
14289
  r._setRaw("topics_user_managed", false);
14116
14290
  r._setRaw("topics_extracted_version", null);
14117
- if (record.topicsExtractedAt === null) {
14291
+ if (record2.topicsExtractedAt === null) {
14118
14292
  r._setRaw("topics_extracted_at", originalUpdatedAt);
14119
14293
  }
14120
14294
  r._setRaw("updated_at", originalUpdatedAt);
@@ -14123,22 +14297,22 @@ async function clearMemoryTopicsOverrideOp(ctx, memoryId, options) {
14123
14297
  return cleared;
14124
14298
  }
14125
14299
  async function setMemoryVisibilityOp(ctx, id, opts) {
14126
- let record;
14300
+ let record2;
14127
14301
  try {
14128
- record = await ctx.vaultMemoryCollection.find(id);
14302
+ record2 = await ctx.vaultMemoryCollection.find(id);
14129
14303
  } catch {
14130
14304
  return null;
14131
14305
  }
14132
- if (record.isDeleted || !isOwnedByCtxUser(ctx, record)) return null;
14306
+ if (record2.isDeleted || !isOwnedByCtxUser(ctx, record2)) return null;
14133
14307
  let stale = false;
14134
14308
  await ctx.database.write(async () => {
14135
- if (record.isDeleted || !isOwnedByCtxUser(ctx, record)) {
14309
+ if (record2.isDeleted || !isOwnedByCtxUser(ctx, record2)) {
14136
14310
  stale = true;
14137
14311
  return;
14138
14312
  }
14139
- const currentUpdatedAt = record.updatedAt.getTime();
14140
- const currentPublishedAt = record.publishedAt ?? null;
14141
- await record.update((r) => {
14313
+ const currentUpdatedAt = record2.updatedAt.getTime();
14314
+ const currentPublishedAt = record2.publishedAt ?? null;
14315
+ await record2.update((r) => {
14142
14316
  r._setRaw("visibility", opts.visibility);
14143
14317
  if (opts.visibility === "private") {
14144
14318
  r._setRaw("published_at", null);
@@ -14152,19 +14326,19 @@ async function setMemoryVisibilityOp(ctx, id, opts) {
14152
14326
  });
14153
14327
  });
14154
14328
  if (stale) return null;
14155
- return vaultMemoryToStored(record, ctx.walletAddress, ctx.signMessage, ctx.embeddedWalletSigner);
14329
+ return vaultMemoryToStored(record2, ctx.walletAddress, ctx.signMessage, ctx.embeddedWalletSigner);
14156
14330
  }
14157
14331
  async function deleteVaultMemoryOp(ctx, id) {
14158
14332
  try {
14159
- const record = await ctx.vaultMemoryCollection.find(id);
14160
- if (record.isDeleted || !isOwnedByCtxUser(ctx, record)) return false;
14333
+ const record2 = await ctx.vaultMemoryCollection.find(id);
14334
+ if (record2.isDeleted || !isOwnedByCtxUser(ctx, record2)) return false;
14161
14335
  let stale = false;
14162
14336
  await ctx.database.write(async () => {
14163
- if (record.isDeleted || !isOwnedByCtxUser(ctx, record)) {
14337
+ if (record2.isDeleted || !isOwnedByCtxUser(ctx, record2)) {
14164
14338
  stale = true;
14165
14339
  return;
14166
14340
  }
14167
- await record.update((r) => {
14341
+ await record2.update((r) => {
14168
14342
  r._setRaw("is_deleted", true);
14169
14343
  });
14170
14344
  });
@@ -14183,8 +14357,9 @@ async function deleteVaultMemoryOp(ctx, id) {
14183
14357
  async function supersedeVaultMemoryOp(ctx, id, supersededById) {
14184
14358
  if (id === supersededById) return false;
14185
14359
  try {
14186
- const record = await ctx.vaultMemoryCollection.find(id);
14187
- if (record.isDeleted || record.supersededBy || !isOwnedByCtxUser(ctx, record)) return false;
14360
+ const record2 = await ctx.vaultMemoryCollection.find(id);
14361
+ if (record2.isDeleted || record2.supersededBy || !isOwnedByCtxUser(ctx, record2)) return false;
14362
+ if (isKinded(record2)) return false;
14188
14363
  let successor;
14189
14364
  try {
14190
14365
  successor = await ctx.vaultMemoryCollection.find(supersededById);
@@ -14198,7 +14373,7 @@ async function supersedeVaultMemoryOp(ctx, id, supersededById) {
14198
14373
  await ctx.database.write(async () => {
14199
14374
  if (ctx.canWrite && !await ctx.canWrite())
14200
14375
  throw new Error("Memory source is no longer eligible");
14201
- if (record.isDeleted || record.supersededBy || !isOwnedByCtxUser(ctx, record)) {
14376
+ if (record2.isDeleted || record2.supersededBy || !isOwnedByCtxUser(ctx, record2)) {
14202
14377
  stale = true;
14203
14378
  return;
14204
14379
  }
@@ -14206,7 +14381,7 @@ async function supersedeVaultMemoryOp(ctx, id, supersededById) {
14206
14381
  stale = true;
14207
14382
  return;
14208
14383
  }
14209
- await record.update((r) => {
14384
+ await record2.update((r) => {
14210
14385
  r._setRaw("superseded_by", supersededById);
14211
14386
  r._setRaw("superseded_at", Date.now());
14212
14387
  });
@@ -14225,7 +14400,7 @@ async function getUnfiledVaultMemoriesOp(ctx) {
14225
14400
  const results = await ctx.vaultMemoryCollection.query(...conditions).fetch();
14226
14401
  return mapInBatches(
14227
14402
  results,
14228
- (record) => vaultMemoryToStored(record, ctx.walletAddress, ctx.signMessage, ctx.embeddedWalletSigner)
14403
+ (record2) => vaultMemoryToStored(record2, ctx.walletAddress, ctx.signMessage, ctx.embeddedWalletSigner)
14229
14404
  );
14230
14405
  }
14231
14406
  var TOPICS_EXTRACTION_VERSION = 3;
@@ -14367,17 +14542,17 @@ async function stampTopicsExtractedAtOp(ctx, memoryIds, extractedAt, version = T
14367
14542
  }
14368
14543
  }
14369
14544
  const eligible = records.filter(
14370
- (record) => !record.isDeleted && isOwnedByCtxUser(ctx, record) && !record.topicsUserManaged
14545
+ (record2) => !record2.isDeleted && isOwnedByCtxUser(ctx, record2) && !record2.topicsUserManaged
14371
14546
  );
14372
- const prepared = eligible.map((record) => {
14373
- const originalUpdatedAt = record.updatedAt.getTime();
14374
- return record.prepareUpdate((r) => {
14547
+ const prepared = eligible.map((record2) => {
14548
+ const originalUpdatedAt = record2.updatedAt.getTime();
14549
+ return record2.prepareUpdate((r) => {
14375
14550
  r._setRaw("topics_extracted_at", extractedAt);
14376
14551
  r._setRaw("topics_extracted_version", version);
14377
14552
  r._setRaw("updated_at", originalUpdatedAt);
14378
14553
  });
14379
14554
  });
14380
- for (const record of eligible) stamped.push(record.id);
14555
+ for (const record2 of eligible) stamped.push(record2.id);
14381
14556
  if (prepared.length > 0) await ctx.database.batch(...prepared);
14382
14557
  });
14383
14558
  }
@@ -14392,14 +14567,14 @@ async function relinkMemoryTopicsOp(ctx, memoryIds) {
14392
14567
  for (const id of Array.from(new Set(memoryIds))) {
14393
14568
  try {
14394
14569
  await ctx.database.write(async (writer) => {
14395
- let record;
14570
+ let record2;
14396
14571
  try {
14397
- record = await ctx.vaultMemoryCollection.find(id);
14572
+ record2 = await ctx.vaultMemoryCollection.find(id);
14398
14573
  } catch {
14399
14574
  return;
14400
14575
  }
14401
- if (record.isDeleted || !isOwnedByCtxUser(ctx, record)) return;
14402
- const topics = parseTopics(record.topics);
14576
+ if (record2.isDeleted || !isOwnedByCtxUser(ctx, record2)) return;
14577
+ const topics = parseTopics(record2.topics);
14403
14578
  if (topics === null) return;
14404
14579
  await writer.callWriter(() => relinkMemoryEntitiesFromTopicsOp(entityCtx, id, topics));
14405
14580
  relinked.push(id);
@@ -14424,20 +14599,20 @@ async function backfillMemoryTopicsOp(ctx, memoryIds) {
14424
14599
  await ctx.database.write(async () => {
14425
14600
  const writes = [];
14426
14601
  for (const id of chunkIds) {
14427
- let record;
14602
+ let record2;
14428
14603
  try {
14429
- record = await ctx.vaultMemoryCollection.find(id);
14604
+ record2 = await ctx.vaultMemoryCollection.find(id);
14430
14605
  } catch {
14431
14606
  continue;
14432
14607
  }
14433
- if (record.isDeleted || !isOwnedByCtxUser(ctx, record)) continue;
14434
- if (parseTopics(record.topics) !== null) continue;
14608
+ if (record2.isDeleted || !isOwnedByCtxUser(ctx, record2)) continue;
14609
+ if (parseTopics(record2.topics) !== null) continue;
14435
14610
  const links = await entityCtx.memoryEntityCollection.query(Q8.where("memory_id", id)).unsafeFetchRaw();
14436
14611
  const entityIds = links.map((l) => String(l.entity_id));
14437
14612
  if (entityIds.length === 0) continue;
14438
14613
  const entities = await entityCtx.entityCollection.query(Q8.where("id", Q8.oneOf(entityIds))).fetch();
14439
14614
  if (entities.length === 0) continue;
14440
- const source = record.topicsUserManaged ? "user" : "auto";
14615
+ const source = record2.topicsUserManaged ? "user" : "auto";
14441
14616
  const write = await resolveMemoryTopicsWrite(entityCtx, id, entities, [], source);
14442
14617
  if (write) writes.push(write);
14443
14618
  }
@@ -14455,7 +14630,7 @@ async function deleteAllVaultMemoriesForUserOp(ctx, userId) {
14455
14630
  if (records.length === 0) return 0;
14456
14631
  await ctx.database.write(async () => {
14457
14632
  const prepared = records.map(
14458
- (record) => record.prepareUpdate((r) => {
14633
+ (record2) => record2.prepareUpdate((r) => {
14459
14634
  r._setRaw("is_deleted", true);
14460
14635
  })
14461
14636
  );
@@ -14485,7 +14660,10 @@ function assertVaultScopeForSweep(ctx) {
14485
14660
  }
14486
14661
  async function getDecayCandidatesRawOp(ctx) {
14487
14662
  assertVaultScopeForSweep(ctx);
14488
- const results = await ctx.vaultMemoryCollection.query(...baseVaultConditions(ctx, { includeArchived: true, includeQuarantined: true })).unsafeFetchRaw();
14663
+ const results = await ctx.vaultMemoryCollection.query(
14664
+ ...baseVaultConditions(ctx, { includeArchived: true, includeQuarantined: true }),
14665
+ Q8.where("kind", null)
14666
+ ).unsafeFetchRaw();
14489
14667
  return results.map((raw) => ({
14490
14668
  uniqueId: raw.id,
14491
14669
  factType: raw.fact_type ?? null,
@@ -14500,20 +14678,20 @@ async function getDecayCandidatesRawOp(ctx) {
14500
14678
  }
14501
14679
  async function archiveVaultMemoryOp(ctx, id, opts) {
14502
14680
  try {
14503
- const record = await ctx.vaultMemoryCollection.find(id);
14504
- if (record.isDeleted || !isOwnedByCtxUser(ctx, record)) return false;
14681
+ const record2 = await ctx.vaultMemoryCollection.find(id);
14682
+ if (record2.isDeleted || !isOwnedByCtxUser(ctx, record2)) return false;
14505
14683
  let stale = false;
14506
14684
  const archivedAtValue = opts?.now ?? Date.now();
14507
14685
  await ctx.database.write(async () => {
14508
- if (record.isDeleted || !isOwnedByCtxUser(ctx, record) || record.archivedAt !== null) {
14686
+ if (record2.isDeleted || !isOwnedByCtxUser(ctx, record2) || record2.archivedAt !== null) {
14509
14687
  stale = true;
14510
14688
  return;
14511
14689
  }
14512
- if (opts?.expectedUpdatedAt !== void 0 && record.updatedAt.getTime() !== opts.expectedUpdatedAt || opts?.expectedLastObservedAt !== void 0 && (record.lastObservedAt ?? null) !== opts.expectedLastObservedAt) {
14690
+ if (opts?.expectedUpdatedAt !== void 0 && record2.updatedAt.getTime() !== opts.expectedUpdatedAt || opts?.expectedLastObservedAt !== void 0 && (record2.lastObservedAt ?? null) !== opts.expectedLastObservedAt) {
14513
14691
  stale = true;
14514
14692
  return;
14515
14693
  }
14516
- await record.update((r) => {
14694
+ await record2.update((r) => {
14517
14695
  r._setRaw("archived_at", archivedAtValue);
14518
14696
  });
14519
14697
  });
@@ -14524,15 +14702,15 @@ async function archiveVaultMemoryOp(ctx, id, opts) {
14524
14702
  }
14525
14703
  async function restoreVaultMemoryOp(ctx, id) {
14526
14704
  try {
14527
- const record = await ctx.vaultMemoryCollection.find(id);
14528
- if (record.isDeleted || !isOwnedByCtxUser(ctx, record)) return false;
14705
+ const record2 = await ctx.vaultMemoryCollection.find(id);
14706
+ if (record2.isDeleted || !isOwnedByCtxUser(ctx, record2)) return false;
14529
14707
  let stale = false;
14530
14708
  await ctx.database.write(async () => {
14531
- if (record.isDeleted || !isOwnedByCtxUser(ctx, record)) {
14709
+ if (record2.isDeleted || !isOwnedByCtxUser(ctx, record2)) {
14532
14710
  stale = true;
14533
14711
  return;
14534
14712
  }
14535
- await record.update((r) => {
14713
+ await record2.update((r) => {
14536
14714
  r._setRaw("archived_at", null);
14537
14715
  });
14538
14716
  });
@@ -14543,17 +14721,17 @@ async function restoreVaultMemoryOp(ctx, id) {
14543
14721
  }
14544
14722
  async function hardDeleteDecayedOp(ctx, id, opts) {
14545
14723
  try {
14546
- const record = await ctx.vaultMemoryCollection.find(id);
14547
- if (record.isDeleted || !isOwnedByCtxUser(ctx, record)) return false;
14724
+ const record2 = await ctx.vaultMemoryCollection.find(id);
14725
+ if (record2.isDeleted || !isOwnedByCtxUser(ctx, record2)) return false;
14548
14726
  const now = opts.now ?? Date.now();
14549
14727
  let stale = false;
14550
14728
  await ctx.database.write(async () => {
14551
- const archivedAt = record.archivedAt;
14552
- if (record.isDeleted || !isOwnedByCtxUser(ctx, record) || archivedAt === null || now - archivedAt <= opts.hardDeleteWindowMs) {
14729
+ const archivedAt = record2.archivedAt;
14730
+ if (record2.isDeleted || !isOwnedByCtxUser(ctx, record2) || archivedAt === null || now - archivedAt <= opts.hardDeleteWindowMs) {
14553
14731
  stale = true;
14554
14732
  return;
14555
14733
  }
14556
- await record.update((r) => {
14734
+ await record2.update((r) => {
14557
14735
  r._setRaw("is_deleted", true);
14558
14736
  });
14559
14737
  });
@@ -14571,14 +14749,14 @@ async function hardDeleteDecayedOp(ctx, id, opts) {
14571
14749
  }
14572
14750
  async function updateVaultMemoryEmbeddingOp(ctx, id, embedding, embeddingModel, expected) {
14573
14751
  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");
14752
+ const record2 = await ctx.vaultMemoryCollection.find(id);
14753
+ if (record2.isDeleted || !isOwnedByCtxUser(ctx, record2)) return false;
14754
+ const readUpdatedAt = record2.updatedAt.getTime();
14755
+ const readStoredContent = record2._getRaw("content");
14578
14756
  if (expected?.updatedAt !== void 0 && expected.updatedAt !== readUpdatedAt) return false;
14579
14757
  if (expected?.content !== void 0) {
14580
14758
  const current = await vaultMemoryToStored(
14581
- record,
14759
+ record2,
14582
14760
  ctx.walletAddress,
14583
14761
  ctx.signMessage,
14584
14762
  ctx.embeddedWalletSigner
@@ -14587,11 +14765,11 @@ async function updateVaultMemoryEmbeddingOp(ctx, id, embedding, embeddingModel,
14587
14765
  }
14588
14766
  let written = false;
14589
14767
  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)
14768
+ if (record2.isDeleted || !isOwnedByCtxUser(ctx, record2)) return;
14769
+ const originalUpdatedAt = record2.updatedAt.getTime();
14770
+ if (originalUpdatedAt !== readUpdatedAt || record2._getRaw("content") !== readStoredContent)
14593
14771
  return;
14594
- await record.update((r) => {
14772
+ await record2.update((r) => {
14595
14773
  r._setRaw("embedding", embedding);
14596
14774
  r._setRaw("embedding_model", embeddingModel);
14597
14775
  r._setRaw("updated_at", originalUpdatedAt);
@@ -14606,8 +14784,8 @@ async function updateVaultMemoryEmbeddingOp(ctx, id, embedding, embeddingModel,
14606
14784
  function normalizeForDedupe(content) {
14607
14785
  return content.normalize("NFKC").trim().replace(/\s+/g, " ").toLowerCase();
14608
14786
  }
14609
- async function findQuarantinedDuplicateOp(ctx, content, sourceIds, where) {
14610
- const wanted = [...new Set(sourceIds)].sort().join("\0");
14787
+ async function findQuarantinedDuplicateOp(ctx, content, sourceIds2, where) {
14788
+ const wanted = [...new Set(sourceIds2)].sort().join("\0");
14611
14789
  const target = normalizeForDedupe(content);
14612
14790
  const rows = await ctx.vaultMemoryCollection.query(
14613
14791
  Q8.where("trust_tier", "quarantined"),
@@ -14626,13 +14804,13 @@ async function findQuarantinedDuplicateOp(ctx, content, sourceIds, where) {
14626
14804
  if (!Array.isArray(ids)) continue;
14627
14805
  const key = [...new Set(ids.filter((id) => typeof id === "string"))].sort().join("\0");
14628
14806
  if (key !== wanted) continue;
14629
- const stored = await vaultMemoryRawToStored(
14807
+ const stored2 = await vaultMemoryRawToStored(
14630
14808
  raw,
14631
14809
  ctx.walletAddress,
14632
14810
  ctx.signMessage,
14633
14811
  ctx.embeddedWalletSigner
14634
14812
  );
14635
- if (normalizeForDedupe(stored.content) === target) return stored.uniqueId;
14813
+ if (normalizeForDedupe(stored2.content) === target) return stored2.uniqueId;
14636
14814
  }
14637
14815
  return null;
14638
14816
  }
@@ -14741,25 +14919,26 @@ async function ingestPublishedPhotoMemoriesOp(ctx, rows) {
14741
14919
  inserted = writable.length;
14742
14920
  if (writable.length === 0) return;
14743
14921
  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(
14922
+ ({ row, content }) => ctx.vaultMemoryCollection.prepareCreate((record2) => {
14923
+ record2._raw.id = row.memoryId;
14924
+ record2._setRaw("content", content);
14925
+ record2._setRaw("scope", "shared");
14926
+ record2._setRaw("level", "matching");
14927
+ record2._setRaw("folder_id", null);
14928
+ record2._setRaw("user_id", ctx.userId ?? null);
14929
+ record2._setRaw("is_deleted", false);
14930
+ record2._setRaw("proof_count", 1);
14931
+ record2._setRaw("source", SOURCE_PHOTO);
14932
+ record2._setRaw(
14754
14933
  "media",
14755
14934
  row.media && row.media.length > 0 ? JSON.stringify(row.media) : null
14756
14935
  );
14757
- record._setRaw("visibility", "public");
14758
- record._setRaw("published_at", now);
14936
+ record2._setRaw("visibility", "public");
14937
+ record2._setRaw("published_at", now);
14759
14938
  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);
14939
+ record2._setRaw("event_time_start", row.eventTime.start ?? null);
14940
+ record2._setRaw("event_time_end", row.eventTime.end ?? null);
14941
+ record2._setRaw("event_time_kind", row.eventTime.kind ?? null);
14763
14942
  }
14764
14943
  })
14765
14944
  );
@@ -15580,11 +15759,11 @@ function folderToStored(folder) {
15580
15759
  }
15581
15760
  async function createVaultFolderOp(ctx, opts) {
15582
15761
  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);
15762
+ return ctx.vaultFolderCollection.create((record2) => {
15763
+ record2._setRaw("name", opts.name);
15764
+ record2._setRaw("scope", opts.scope ?? "private");
15765
+ record2._setRaw("is_system", opts.isSystem ?? false);
15766
+ record2._setRaw("is_deleted", false);
15588
15767
  });
15589
15768
  });
15590
15769
  return folderToStored(created);
@@ -15595,14 +15774,14 @@ async function getAllVaultFoldersOp(ctx) {
15595
15774
  }
15596
15775
  async function updateVaultFolderOp(ctx, id, opts) {
15597
15776
  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;
15777
+ const record2 = await ctx.vaultFolderCollection.find(id);
15778
+ if (record2.isDeleted) return null;
15779
+ const scopeChanged = opts.scope !== void 0 && opts.scope !== record2.scope;
15601
15780
  const updated = await ctx.database.write(async () => {
15602
15781
  const memories = scopeChanged ? await ctx.vaultMemoryCollection.query(Q13.where("folder_id", id), Q13.where("is_deleted", false)).fetch() : [];
15603
15782
  const updates = [];
15604
15783
  updates.push(
15605
- record.prepareUpdate((r) => {
15784
+ record2.prepareUpdate((r) => {
15606
15785
  if (opts.name !== void 0) r._setRaw("name", opts.name);
15607
15786
  if (opts.scope !== void 0) r._setRaw("scope", opts.scope);
15608
15787
  })
@@ -15610,6 +15789,7 @@ async function updateVaultFolderOp(ctx, id, opts) {
15610
15789
  for (const memory of memories) {
15611
15790
  updates.push(
15612
15791
  memory.prepareUpdate((r) => {
15792
+ r._setRaw("level", levelForScopeChange(r, opts.scope));
15613
15793
  r._setRaw("scope", opts.scope);
15614
15794
  })
15615
15795
  );
@@ -15624,17 +15804,18 @@ async function updateVaultFolderOp(ctx, id, opts) {
15624
15804
  }
15625
15805
  async function deleteVaultFolderOp(ctx, id) {
15626
15806
  try {
15627
- const record = await ctx.vaultFolderCollection.find(id);
15628
- if (record.isDeleted) return false;
15807
+ const record2 = await ctx.vaultFolderCollection.find(id);
15808
+ if (record2.isDeleted) return false;
15629
15809
  await ctx.database.write(async () => {
15630
15810
  const memories = await ctx.vaultMemoryCollection.query(Q13.where("folder_id", id), Q13.where("is_deleted", false)).fetch();
15631
15811
  const preparedMemories = memories.map(
15632
15812
  (memory) => memory.prepareUpdate((r) => {
15633
15813
  r._setRaw("folder_id", null);
15814
+ r._setRaw("level", levelForScopeChange(r, "private"));
15634
15815
  r._setRaw("scope", "private");
15635
15816
  })
15636
15817
  );
15637
- const preparedFolder = record.prepareUpdate((r) => {
15818
+ const preparedFolder = record2.prepareUpdate((r) => {
15638
15819
  r._setRaw("is_deleted", true);
15639
15820
  });
15640
15821
  await ctx.database.batch(...preparedMemories, preparedFolder);
@@ -15667,6 +15848,7 @@ async function moveMemoriesToFolderOp(ctx, memoryIds, folderId) {
15667
15848
  const prepared = memories.map(
15668
15849
  (memory) => memory.prepareUpdate((r) => {
15669
15850
  r._setRaw("folder_id", folderId);
15851
+ r._setRaw("level", levelForScopeChange(r, targetScope));
15670
15852
  r._setRaw("scope", targetScope);
15671
15853
  })
15672
15854
  );
@@ -15680,11 +15862,11 @@ async function moveMemoriesToFolderOp(ctx, memoryIds, folderId) {
15680
15862
  }
15681
15863
  async function updateVaultFolderContextOp(ctx, id, context) {
15682
15864
  try {
15683
- const record = await ctx.vaultFolderCollection.find(id);
15684
- if (record.isDeleted) return null;
15865
+ const record2 = await ctx.vaultFolderCollection.find(id);
15866
+ if (record2.isDeleted) return null;
15685
15867
  const updated = await ctx.database.write(async () => {
15686
15868
  await ctx.database.batch(
15687
- record.prepareUpdate((r) => {
15869
+ record2.prepareUpdate((r) => {
15688
15870
  r._setRaw("context", context);
15689
15871
  })
15690
15872
  );
@@ -17741,7 +17923,7 @@ async function rankPreparedVaultCandidates(query, prepared, embeddingOptions, se
17741
17923
  if (useFusion && !embeddingsUnavailable && facetQueries) {
17742
17924
  let subEmbeddings;
17743
17925
  try {
17744
- subEmbeddings = await generateEmbeddings(facetQueries, embeddingOptions);
17926
+ subEmbeddings = prepared.facetEmbeddings ?? await generateEmbeddings(facetQueries, embeddingOptions);
17745
17927
  } catch (err) {
17746
17928
  getLogger().warn(
17747
17929
  "memoryVault: sub-query embedding failed \u2014 falling back to single-query ranking: " + (err instanceof Error ? err.message : String(err))
@@ -17926,6 +18108,35 @@ var DEFAULT_SCOPE = "private";
17926
18108
  var DEFAULT_CONSOLIDATE_THRESHOLD = 0.55;
17927
18109
  var DEFAULT_CONSOLIDATE_TOP_K = 20;
17928
18110
  async function retain(content, ctx, options = {}) {
18111
+ return retainWithPersistence(
18112
+ content,
18113
+ {
18114
+ embeddingOptions: ctx.embeddingOptions,
18115
+ vaultCache: ctx.vaultCache,
18116
+ persistence: {
18117
+ prepare: (query, searchOptions) => prepareVaultCandidates(
18118
+ query,
18119
+ ctx.vaultCtx,
18120
+ ctx.embeddingOptions,
18121
+ ctx.vaultCache,
18122
+ searchOptions
18123
+ ),
18124
+ get: (id) => getVaultMemoryOp(ctx.vaultCtx, id),
18125
+ tombstones: (_embedding, _model, scope, folderId) => getAllVaultMemoriesOp(ctx.vaultCtx, {
18126
+ includeDeleted: true,
18127
+ scopes: [scope],
18128
+ ...folderId !== void 0 && { folderId }
18129
+ }),
18130
+ create: (input) => createVaultMemoryOp(ctx.vaultCtx, input),
18131
+ update: (id, patch) => updateVaultMemoryOp(ctx.vaultCtx, id, patch),
18132
+ supersede: (id, successor) => supersedeVaultMemoryOp(ctx.vaultCtx, id, successor),
18133
+ createSuperseding: (input, target) => createSupersedingMemoryOp(ctx.vaultCtx, input, target)
18134
+ }
18135
+ },
18136
+ options
18137
+ );
18138
+ }
18139
+ async function retainWithPersistence(content, ctx, options = {}) {
17929
18140
  const trimmed = content.trim();
17930
18141
  if (trimmed.length === 0) {
17931
18142
  throw new Error("retain: content cannot be empty");
@@ -17938,19 +18149,14 @@ async function retain(content, ctx, options = {}) {
17938
18149
  let supersedeContent;
17939
18150
  let prepared;
17940
18151
  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
- );
18152
+ prepared = await ctx.persistence.prepare(trimmed, {
18153
+ limit: Math.max(options.consolidateTopK ?? DEFAULT_CONSOLIDATE_TOP_K, 1),
18154
+ useFusion: false,
18155
+ scopes: [resolvedScope],
18156
+ includeArchived: true,
18157
+ ...options.folderId !== void 0 && { folderId: options.folderId }
18158
+ });
18159
+ prepared = withoutKindedRows(prepared);
17954
18160
  if (prepared.embeddingFailure || prepared.embeddingsUnavailable) {
17955
18161
  throw new Error(
17956
18162
  "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 +18187,7 @@ async function retain(content, ctx, options = {}) {
17981
18187
  );
17982
18188
  if (matches.length > 0) {
17983
18189
  const targetId = matches[0].uniqueId;
17984
- const existing = await getVaultMemoryOp(ctx.vaultCtx, targetId);
18190
+ const existing = await ctx.persistence.get(targetId);
17985
18191
  if (existing && !existing.supersededBy) {
17986
18192
  const mergedSourceIds = unionStrings(
17987
18193
  existing.sourceChunkIds ?? [],
@@ -17990,8 +18196,9 @@ async function retain(content, ctx, options = {}) {
17990
18196
  const eventTimeUpdate = pickEventTimeUpdate(existing, options.eventTime);
17991
18197
  const factTypeUpdate = pickFactTypeUpdate(existing, options.factType);
17992
18198
  const resurrect = resurrectFields(existing);
17993
- const updated = await updateVaultMemoryOp(ctx.vaultCtx, targetId, {
18199
+ const updated = await ctx.persistence.update(targetId, {
17994
18200
  content: existing.content,
18201
+ freeFormOnly: true,
17995
18202
  proofCountIncrement: 1,
17996
18203
  observationSourceIds: options.sourceChunkIds,
17997
18204
  sourceChunkIds: mergedSourceIds,
@@ -18017,7 +18224,8 @@ async function retain(content, ctx, options = {}) {
18017
18224
  }
18018
18225
  const contentToWrite = supersedeContent ?? trimmed;
18019
18226
  const reusableQueryEmbedding = supersedeContent === void 0 && prepared && prepared.queryEmbedding.length > 0 ? prepared.queryEmbedding : void 0;
18020
- const embedding = reusableQueryEmbedding ?? await generateEmbedding(contentToWrite, ctx.embeddingOptions);
18227
+ const generatedEmbedding = reusableQueryEmbedding ?? await generateEmbedding(contentToWrite, ctx.embeddingOptions);
18228
+ const embedding = ctx.normalizeEmbedding?.(generatedEmbedding) ?? generatedEmbedding;
18021
18229
  const embeddingModel = ctx.embeddingOptions.model ?? DEFAULT_API_EMBEDDING_MODEL;
18022
18230
  if (options.respectTombstones) {
18023
18231
  const tombstone = await findTombstoneMatch(embedding, embeddingModel, resolvedScope, ctx, {
@@ -18057,8 +18265,7 @@ async function retain(content, ctx, options = {}) {
18057
18265
  };
18058
18266
  if (supersedeTargetIds.length > 0) {
18059
18267
  const [primaryTargetId, ...restTargetIds] = supersedeTargetIds;
18060
- const { created: created2, retired } = await createSupersedingMemoryOp(
18061
- ctx.vaultCtx,
18268
+ const { created: created2, retired } = await ctx.persistence.createSuperseding(
18062
18269
  createOpts,
18063
18270
  primaryTargetId
18064
18271
  );
@@ -18074,11 +18281,11 @@ async function retain(content, ctx, options = {}) {
18074
18281
  for (const staleId of restTargetIds) {
18075
18282
  let ok = false;
18076
18283
  try {
18077
- ok = await supersedeVaultMemoryOp(ctx.vaultCtx, staleId, created2.uniqueId) === true;
18284
+ ok = await ctx.persistence.supersede(staleId, created2.uniqueId) === true;
18078
18285
  } catch {
18079
18286
  }
18080
18287
  if (ok) continue;
18081
- const stillLive = await getVaultMemoryOp(ctx.vaultCtx, staleId).catch(() => null);
18288
+ const stillLive = await (ctx.persistence.getFresh ? ctx.persistence.getFresh(staleId) : ctx.persistence.get(staleId)).catch(() => null);
18082
18289
  if (stillLive && !stillLive.supersededBy) liveLeftovers.push(staleId);
18083
18290
  }
18084
18291
  if (liveLeftovers.length > 0) {
@@ -18105,7 +18312,7 @@ async function retain(content, ctx, options = {}) {
18105
18312
  `supersede: primary target ${primaryTargetId} retired or deleted inside the atomic write`
18106
18313
  );
18107
18314
  }
18108
- const created = await createVaultMemoryOp(ctx.vaultCtx, createOpts);
18315
+ const created = await ctx.persistence.create(createOpts);
18109
18316
  cacheRowVector(
18110
18317
  ctx.vaultCache,
18111
18318
  created.uniqueId,
@@ -18120,15 +18327,22 @@ async function retain(content, ctx, options = {}) {
18120
18327
  ...consolidationDecidedCreate && { consolidation: "create" }
18121
18328
  };
18122
18329
  }
18330
+ function withoutKindedRows(prepared) {
18331
+ const kinded = new Set(
18332
+ prepared.memories.filter((m) => m.kind !== null && m.kind !== void 0).map((m) => m.uniqueId)
18333
+ );
18334
+ if (kinded.size === 0) return prepared;
18335
+ return {
18336
+ ...prepared,
18337
+ memories: prepared.memories.filter((m) => !kinded.has(m.uniqueId)),
18338
+ embeddedItems: prepared.embeddedItems.filter((item) => !kinded.has(item.id))
18339
+ };
18340
+ }
18123
18341
  function unionStrings(a, b) {
18124
18342
  return [.../* @__PURE__ */ new Set([...a, ...b])];
18125
18343
  }
18126
18344
  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
- });
18345
+ const rows = await ctx.persistence.tombstones(embedding, embeddingModel, scope, opts.folderId);
18132
18346
  let bestId = null;
18133
18347
  let bestSim = opts.threshold;
18134
18348
  for (const row of rows) {
@@ -18195,7 +18409,7 @@ async function tryConsolidate(trimmed, ctx, options, prepared) {
18195
18409
  if (requestedIds.length === 0) return null;
18196
18410
  const valid = [];
18197
18411
  for (const id of requestedIds) {
18198
- const existing = await getVaultMemoryOp(ctx.vaultCtx, id);
18412
+ const existing = await ctx.persistence.get(id);
18199
18413
  if (existing && !existing.supersededBy) valid.push(id);
18200
18414
  }
18201
18415
  if (valid.length === 0) {
@@ -18207,7 +18421,7 @@ async function tryConsolidate(trimmed, ctx, options, prepared) {
18207
18421
  return { supersede: valid, content: decision.content };
18208
18422
  }
18209
18423
  if (decision.action === "noop" && decision.targetId) {
18210
- const existing = await getVaultMemoryOp(ctx.vaultCtx, decision.targetId);
18424
+ const existing = await ctx.persistence.get(decision.targetId);
18211
18425
  if (!existing || existing.supersededBy) {
18212
18426
  return abandonToRace(
18213
18427
  options,
@@ -18221,8 +18435,9 @@ async function tryConsolidate(trimmed, ctx, options, prepared) {
18221
18435
  const eventTimeUpdate = pickEventTimeUpdate(existing, options.eventTime);
18222
18436
  const factTypeUpdate = pickFactTypeUpdate(existing, options.factType);
18223
18437
  const resurrect = resurrectFields(existing);
18224
- const updated = await updateVaultMemoryOp(ctx.vaultCtx, decision.targetId, {
18438
+ const updated = await ctx.persistence.update(decision.targetId, {
18225
18439
  content: existing.content,
18440
+ freeFormOnly: true,
18226
18441
  proofCountIncrement: 1,
18227
18442
  observationSourceIds: options.sourceChunkIds,
18228
18443
  sourceChunkIds: mergedSourceIds,
@@ -18249,7 +18464,7 @@ async function tryConsolidate(trimmed, ctx, options, prepared) {
18249
18464
  };
18250
18465
  }
18251
18466
  if (decision.action === "update" && decision.targetId && decision.content) {
18252
- const existing = await getVaultMemoryOp(ctx.vaultCtx, decision.targetId);
18467
+ const existing = await ctx.persistence.get(decision.targetId);
18253
18468
  if (!existing || existing.supersededBy) {
18254
18469
  return abandonToRace(
18255
18470
  options,
@@ -18260,13 +18475,15 @@ async function tryConsolidate(trimmed, ctx, options, prepared) {
18260
18475
  existing.sourceChunkIds ?? [],
18261
18476
  options.sourceChunkIds ?? []
18262
18477
  );
18263
- const newEmbedding = await generateEmbedding(decision.content, ctx.embeddingOptions);
18478
+ const generatedEmbedding = await generateEmbedding(decision.content, ctx.embeddingOptions);
18479
+ const newEmbedding = ctx.normalizeEmbedding?.(generatedEmbedding) ?? generatedEmbedding;
18264
18480
  const consolidatedModel = ctx.embeddingOptions.model ?? DEFAULT_API_EMBEDDING_MODEL;
18265
18481
  const eventTimeUpdate = pickEventTimeUpdate(existing, options.eventTime);
18266
18482
  const factTypeUpdate = pickFactTypeUpdate(existing, options.factType);
18267
18483
  const resurrect = resurrectFields(existing);
18268
- const updated = await updateVaultMemoryOp(ctx.vaultCtx, decision.targetId, {
18484
+ const updated = await ctx.persistence.update(decision.targetId, {
18269
18485
  content: decision.content,
18486
+ freeFormOnly: true,
18270
18487
  proofCountIncrement: 1,
18271
18488
  observationSourceIds: options.sourceChunkIds,
18272
18489
  sourceChunkIds: mergedSourceIds,
@@ -18309,8 +18526,8 @@ async function tryConsolidate(trimmed, ctx, options, prepared) {
18309
18526
  return null;
18310
18527
  }
18311
18528
  async function assertMergeTargetGoneOrThrow(ctx, targetId) {
18312
- const stillExists = await getVaultMemoryOp(ctx.vaultCtx, targetId);
18313
- if (stillExists) {
18529
+ const stillExists = await (ctx.persistence.getFresh ? ctx.persistence.getFresh(targetId) : ctx.persistence.get(targetId));
18530
+ if (stillExists && (stillExists.kind === null || stillExists.kind === void 0)) {
18314
18531
  throw new Error(`retain: merge into memory ${targetId} failed to persist`);
18315
18532
  }
18316
18533
  }
@@ -18824,9 +19041,9 @@ function createAutoExtractor(options) {
18824
19041
  const persistCursor = (conversationId, messages, advancedToId, contiguous) => {
18825
19042
  if (!cursorStore || conversationId === void 0 || !contiguous) return;
18826
19043
  try {
18827
- const stored = cursorStore.get(conversationId);
18828
- if (stored && stored !== advancedToId) {
18829
- const storedIdx = messages.findIndex((m) => m.id === stored);
19044
+ const stored2 = cursorStore.get(conversationId);
19045
+ if (stored2 && stored2 !== advancedToId) {
19046
+ const storedIdx = messages.findIndex((m) => m.id === stored2);
18830
19047
  const newIdx = messages.findIndex((m) => m.id === advancedToId);
18831
19048
  if (storedIdx !== -1 && newIdx !== -1 && storedIdx >= newIdx) return;
18832
19049
  }
@@ -19795,7 +20012,7 @@ async function recall(query, ctx, options = {}) {
19795
20012
  if (graphLaneFailed) degraded.push("graph-lane-failed");
19796
20013
  if (temporalLaneFailed) degraded.push("temporal-lane-failed");
19797
20014
  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;
20015
+ const laneRan = types.includes("fact") && (!!ctx.factSource || !!ctx.vaultCtx && !!ctx.vaultCache) || types.includes("chunk") && !!ctx.storageCtx || chunksScopeRestricted && !!ctx.storageCtx;
19799
20016
  const scores = admitted.map((m) => m.score);
19800
20017
  const minScoreApplied = factResults.length > 0 ? factFloor : chunkResults.length > 0 ? chunkFloor : factFloor >= 0 ? factFloor : chunkFloor;
19801
20018
  const diagnostics = {
@@ -19837,7 +20054,7 @@ async function recall(query, ctx, options = {}) {
19837
20054
  return { memories: [], usedBudget, reranked: false, candidateCount: 0 };
19838
20055
  }
19839
20056
  const needsChunkEmbedding = types.includes("chunk") && ctx.storageCtx;
19840
- const wantsTemporal = types.includes("fact") && ctx.vaultCtx;
20057
+ const wantsTemporal = types.includes("fact") && (ctx.factSource || ctx.vaultCtx);
19841
20058
  const graphRefiner = flags.traverse && options.graphRefine && options.decomposeOptions ? createLlmNeighborRefiner(options.decomposeOptions) : void 0;
19842
20059
  const queryEmbedTotalTimeoutMs = options.queryEmbedTotalTimeoutMs ?? DEFAULT_QUERY_EMBED_TOTAL_TIMEOUT_MS;
19843
20060
  const prepStart = nowMs2();
@@ -19867,7 +20084,7 @@ async function recall(query, ctx, options = {}) {
19867
20084
  safeLane(
19868
20085
  "graph",
19869
20086
  () => graphLaneFailed = true,
19870
- () => buildGraphLaneRanking(query, ctx, flags.traverse, {
20087
+ () => ctx.factSource ? ctx.factSource.graphRanking(query, flags.traverse, options) : buildGraphLaneRanking(query, ctx, flags.traverse, {
19871
20088
  ...options.maxHops !== void 0 && { maxHops: options.maxHops },
19872
20089
  ...options.entityFanout !== void 0 && { entityFanout: options.entityFanout },
19873
20090
  ...options.nodeBudget !== void 0 && { nodeBudget: options.nodeBudget },
@@ -19878,13 +20095,13 @@ async function recall(query, ctx, options = {}) {
19878
20095
  wantsTemporal ? safeLane(
19879
20096
  "temporal",
19880
20097
  () => temporalLaneFailed = true,
19881
- () => buildTemporalLaneRanking(query, ctx.vaultCtx, options.now)
20098
+ () => ctx.factSource ? ctx.factSource.temporalRanking(query, options.now) : buildTemporalLaneRanking(query, ctx.vaultCtx, options.now)
19882
20099
  ) : Promise.resolve([])
19883
20100
  ]);
19884
20101
  prepMs = nowMs2() - prepStart;
19885
20102
  graphLaneCount = entityRanking.length;
19886
20103
  temporalLaneCount = temporalRanking.length;
19887
- if (types.includes("fact") && ctx.vaultCtx && ctx.vaultCache) {
20104
+ if (types.includes("fact") && (ctx.factSource || ctx.vaultCtx && ctx.vaultCache)) {
19888
20105
  const factStart = nowMs2();
19889
20106
  const vaultMinScore = options.minScore ?? DEFAULT_FACT_MIN_SCORE;
19890
20107
  factFloor = vaultMinScore;
@@ -19900,50 +20117,50 @@ async function recall(query, ctx, options = {}) {
19900
20117
  rankedOnCosine: factRankedOnCosine,
19901
20118
  decryptLast: factDecryptLast,
19902
20119
  rowsDecrypted: factRowsDecrypted
19903
- } = await searchVaultMemoriesWithSize(
19904
- query,
20120
+ } = await (ctx.factSource?.search.bind(ctx.factSource) ?? ((searchQuery, searchOptions) => searchVaultMemoriesWithSize(
20121
+ searchQuery,
19905
20122
  ctx.vaultCtx,
19906
20123
  ctx.embeddingOptions,
19907
20124
  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
- );
20125
+ searchOptions
20126
+ )))(query, {
20127
+ limit: types.includes("chunk") ? Math.max(limit * 2, 16) : limit,
20128
+ minSimilarity: vaultMinScore,
20129
+ useFusion: true,
20130
+ rerank: flags.rerank,
20131
+ ...options.rerankTopN !== void 0 && { rerankTopN: options.rerankTopN },
20132
+ ...options.ceWeight !== void 0 && { ceWeight: options.ceWeight },
20133
+ ...options.rerankLoadTimeoutMs !== void 0 && {
20134
+ rerankLoadTimeoutMs: options.rerankLoadTimeoutMs
20135
+ },
20136
+ ...options.recencyAlpha !== void 0 && { recencyAlpha: options.recencyAlpha },
20137
+ ...options.recency && { recency: options.recency },
20138
+ ...options.mmr !== void 0 && { mmr: options.mmr },
20139
+ ...options.supersessionBoost !== void 0 && {
20140
+ supersessionBoost: options.supersessionBoost
20141
+ },
20142
+ ...options.supersessionWindow !== void 0 && {
20143
+ supersessionWindow: options.supersessionWindow
20144
+ },
20145
+ ...options.proofCountAlpha !== void 0 && {
20146
+ proofCountAlpha: options.proofCountAlpha
20147
+ },
20148
+ ...options.bm25AdmissionDivisor !== void 0 && {
20149
+ bm25AdmissionDivisor: options.bm25AdmissionDivisor
20150
+ },
20151
+ ...options.rrfK !== void 0 && { rrfK: options.rrfK },
20152
+ ...options.decryptLast !== void 0 && { decryptLast: options.decryptLast },
20153
+ ...subQueries && { subQueries },
20154
+ ...options.scopes && { scopes: options.scopes },
20155
+ ...options.folderId !== void 0 && { folderId: options.folderId },
20156
+ ...options.factTypes?.length && { factTypes: options.factTypes },
20157
+ ...options.memoryIds !== void 0 && { memoryIds: options.memoryIds },
20158
+ ...options.factTypeWeights && { factTypeWeights: options.factTypeWeights },
20159
+ ...entityRanking.length > 0 && { entityRanking },
20160
+ ...temporalRanking.length > 0 && { temporalRanking },
20161
+ ...needsChunkEmbedding && { queryEmbedding: queryEmbedding ?? [] },
20162
+ queryEmbedTotalTimeoutMs
20163
+ });
19947
20164
  factResults.push(
19948
20165
  ...dedupeBy(
19949
20166
  results,
@@ -20748,26 +20965,26 @@ async function extractAndLinkEntitiesForMemoriesOp(ctx, memoryIds, options) {
20748
20965
  };
20749
20966
  const inputs = [];
20750
20967
  for (const id of new Set(memoryIds)) {
20751
- let record;
20968
+ let record2;
20752
20969
  try {
20753
- record = await ctx.vaultMemoryCollection.find(id);
20970
+ record2 = await ctx.vaultMemoryCollection.find(id);
20754
20971
  } catch (err) {
20755
20972
  log.warn("[memory/topics] vault lookup failed for extraction", err);
20756
20973
  skip(id, "not-found");
20757
20974
  continue;
20758
20975
  }
20759
- if (record.isDeleted || ctx.userId !== void 0 && record.userId !== ctx.userId || record.topicsUserManaged) {
20976
+ if (record2.isDeleted || ctx.userId !== void 0 && record2.userId !== ctx.userId || record2.topicsUserManaged) {
20760
20977
  skip(id, "excluded");
20761
20978
  continue;
20762
20979
  }
20763
20980
  try {
20764
- const stored = await vaultMemoryToStored(
20765
- record,
20981
+ const stored2 = await vaultMemoryToStored(
20982
+ record2,
20766
20983
  ctx.walletAddress,
20767
20984
  ctx.signMessage,
20768
20985
  ctx.embeddedWalletSigner
20769
20986
  );
20770
- inputs.push({ id, content: stored.content });
20987
+ inputs.push({ id, content: stored2.content });
20771
20988
  } catch (err) {
20772
20989
  log.warn("[memory/topics] failed to load memory for extraction", err);
20773
20990
  skip(id, "unreadable");
@@ -20952,6 +21169,780 @@ function createLocalMemoryStore(options) {
20952
21169
  };
20953
21170
  }
20954
21171
 
21172
+ // src/lib/memory/store/remotePersistence.ts
21173
+ var RemoteMemoryError = class extends Error {
21174
+ constructor(message, status, code) {
21175
+ super(message);
21176
+ this.status = status;
21177
+ this.code = code;
21178
+ this.name = "RemoteMemoryError";
21179
+ }
21180
+ };
21181
+ var ciphertextPattern = /^enc:v\d+:[0-9a-f]+$/i;
21182
+ var memoryFields = {
21183
+ memory_id: true,
21184
+ content: true,
21185
+ scope: true,
21186
+ created_at: true,
21187
+ updated_at: true,
21188
+ is_deleted: true,
21189
+ embedding: true,
21190
+ embedding_model: true,
21191
+ kind: true,
21192
+ kind_value: true,
21193
+ level: true,
21194
+ folder_id: true,
21195
+ source_chunk_ids: true,
21196
+ proof_count: true,
21197
+ source: true,
21198
+ event_time_start: true,
21199
+ event_time_end: true,
21200
+ event_time_kind: true,
21201
+ topics_user_managed: true,
21202
+ topics: true,
21203
+ topics_updated_at: true,
21204
+ media: true,
21205
+ topics_extracted_at: true,
21206
+ topics_extracted_version: true,
21207
+ superseded_by: true,
21208
+ superseded_at: true,
21209
+ last_observed_at: true,
21210
+ fact_type: true,
21211
+ archived_at: true,
21212
+ trust_tier: true,
21213
+ visibility: true,
21214
+ twin_opt_in: true,
21215
+ published_at: true,
21216
+ geohash: true
21217
+ };
21218
+ var candidateListLimits = [
21219
+ ["scopes", 20],
21220
+ ["fact_types", 20],
21221
+ ["memory_ids", 1e3],
21222
+ ["force_ids", 100]
21223
+ ];
21224
+ function record(value) {
21225
+ return typeof value === "object" && value !== null && !Array.isArray(value);
21226
+ }
21227
+ function memoryRecord(value) {
21228
+ 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))) {
21229
+ throw new Error("Invalid nearby private-memory response");
21230
+ }
21231
+ return value;
21232
+ }
21233
+ async function createRemoteMemoryPersistence(options) {
21234
+ const base = new URL(options.baseUrl);
21235
+ if (!/^https?:$/.test(base.protocol) || base.username || base.password || base.search || base.hash) {
21236
+ throw new Error(
21237
+ "baseUrl must be an HTTP(S) origin or base path without credentials, query or fragment"
21238
+ );
21239
+ }
21240
+ if (!options.keyId || options.keyId.length > 256)
21241
+ throw new Error("A canonical keyId is required");
21242
+ const timeoutMs = options.timeoutMs ?? 3e4;
21243
+ if (!Number.isFinite(timeoutMs) || timeoutMs <= 0)
21244
+ throw new Error("timeoutMs must be a positive number");
21245
+ const root = base.href.replace(/\/$/, "") + "/api/private-memories";
21246
+ const fetcher = options.fetch ?? globalThis.fetch;
21247
+ const request = async (path, init = {}, signal) => {
21248
+ const controller = new AbortController();
21249
+ let timedOut = false;
21250
+ const timer = setTimeout(() => {
21251
+ timedOut = true;
21252
+ controller.abort();
21253
+ }, timeoutMs);
21254
+ const forwardAbort = () => controller.abort(signal?.reason);
21255
+ if (signal?.aborted) forwardAbort();
21256
+ else signal?.addEventListener("abort", forwardAbort, { once: true });
21257
+ let rejectAborted;
21258
+ const aborted = new Promise((_, reject) => {
21259
+ rejectAborted = () => reject(
21260
+ controller.signal.reason instanceof Error ? controller.signal.reason : new Error("Nearby request aborted")
21261
+ );
21262
+ if (controller.signal.aborted) rejectAborted();
21263
+ else controller.signal.addEventListener("abort", rejectAborted, { once: true });
21264
+ });
21265
+ aborted.catch(() => void 0);
21266
+ try {
21267
+ const token = await Promise.race([options.getToken(), aborted]);
21268
+ if (controller.signal.aborted) await aborted;
21269
+ if (!token) throw new RemoteMemoryError("Authentication required", 401);
21270
+ const response = await fetcher(root + path, {
21271
+ ...init,
21272
+ headers: {
21273
+ Authorization: `Bearer ${token}`,
21274
+ ...init.body ? { "Content-Type": "application/json" } : {}
21275
+ },
21276
+ redirect: "error",
21277
+ signal: controller.signal
21278
+ });
21279
+ if (!response.ok) {
21280
+ const body = await response.json().catch(() => null);
21281
+ throw new RemoteMemoryError(
21282
+ record(body) && typeof body.detail === "string" ? body.detail : `Nearby request failed (${response.status})`,
21283
+ response.status,
21284
+ record(body) && typeof body.code === "string" ? body.code : void 0
21285
+ );
21286
+ }
21287
+ return await response.json();
21288
+ } catch (error) {
21289
+ if (timedOut) throw new RemoteMemoryError("Nearby request timed out", 408, "timeout");
21290
+ throw error;
21291
+ } finally {
21292
+ clearTimeout(timer);
21293
+ signal?.removeEventListener("abort", forwardAbort);
21294
+ if (rejectAborted) controller.signal.removeEventListener("abort", rejectAborted);
21295
+ }
21296
+ };
21297
+ const account = await request("/account", {}, options.signal);
21298
+ if (!record(account) || account.state !== "active") {
21299
+ throw new RemoteMemoryError(
21300
+ "Complete and verify migration before using remote memories",
21301
+ 409,
21302
+ "memory_not_active"
21303
+ );
21304
+ }
21305
+ if (account.key_id !== options.keyId) {
21306
+ throw new RemoteMemoryError(
21307
+ "The canonical memory key does not match this account",
21308
+ 409,
21309
+ "key_mismatch"
21310
+ );
21311
+ }
21312
+ const snapshots = /* @__PURE__ */ new WeakMap();
21313
+ const decode = async (value) => {
21314
+ const item = memoryRecord(value);
21315
+ const decrypt = async (ciphertext) => {
21316
+ if (!ciphertextPattern.test(ciphertext))
21317
+ throw new Error("Nearby returned unencrypted memory content");
21318
+ const plaintext = await options.decrypt(ciphertext);
21319
+ if (plaintext === ciphertext) throw new Error("Memory decryption failed");
21320
+ return plaintext;
21321
+ };
21322
+ const decoded = {
21323
+ ...item,
21324
+ memory: {
21325
+ ...item.memory,
21326
+ content: await decrypt(item.memory.content),
21327
+ ...item.memory.kind_value !== void 0 && {
21328
+ kind_value: await decrypt(item.memory.kind_value)
21329
+ }
21330
+ }
21331
+ };
21332
+ return remember(decoded, item);
21333
+ };
21334
+ const remember = (decoded, item) => {
21335
+ snapshots.set(decoded, {
21336
+ id: item.memory.memory_id,
21337
+ version: item.version,
21338
+ content: decoded.memory.content,
21339
+ kindValue: decoded.memory.kind_value,
21340
+ encryptedContent: item.memory.content,
21341
+ encryptedKindValue: item.memory.kind_value
21342
+ });
21343
+ return decoded;
21344
+ };
21345
+ const decodeAll = async (values) => {
21346
+ const records = values.map(memoryRecord);
21347
+ const settled = await Promise.allSettled(records.map(decode));
21348
+ const items = [];
21349
+ const failed = [];
21350
+ settled.forEach((result, i) => {
21351
+ if (result.status === "fulfilled") items.push(result.value);
21352
+ else
21353
+ failed.push({
21354
+ memory_id: records[i].memory.memory_id,
21355
+ version: records[i].version,
21356
+ error: result.reason instanceof Error ? result.reason : new Error(String(result.reason))
21357
+ });
21358
+ });
21359
+ return { items, failed };
21360
+ };
21361
+ const decodeCommitted = async (value, write) => {
21362
+ const item = memoryRecord(value);
21363
+ 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)
21364
+ return decode(item);
21365
+ return remember(
21366
+ {
21367
+ ...item,
21368
+ memory: {
21369
+ ...item.memory,
21370
+ content: write.content,
21371
+ ...write.kindValue !== void 0 && { kind_value: write.kindValue }
21372
+ }
21373
+ },
21374
+ item
21375
+ );
21376
+ };
21377
+ const encryptField2 = async (plaintext) => {
21378
+ const ciphertext = await options.encrypt(plaintext);
21379
+ if (ciphertext === plaintext || !ciphertextPattern.test(ciphertext))
21380
+ throw new Error("Field encryption must return SDK ciphertext; refusing to upload plaintext");
21381
+ return ciphertext;
21382
+ };
21383
+ const memoryPath = (id) => {
21384
+ if (!id || id.length > 128) throw new Error("memory_id must be 1\u2013128 characters");
21385
+ return "/memories/" + encodeURIComponent(id);
21386
+ };
21387
+ const prepareWrite = async (memory, expectedVersion, signal) => {
21388
+ const unknown = Object.keys(memory).filter(
21389
+ (key) => !Object.prototype.hasOwnProperty.call(memoryFields, key)
21390
+ );
21391
+ if (unknown.length) {
21392
+ throw new RemoteMemoryError(
21393
+ `Unknown private-memory fields (${unknown.join(", ")}); refusing to forward them`,
21394
+ 400,
21395
+ "unknown_field"
21396
+ );
21397
+ }
21398
+ memory = { ...memory, ...memory.embedding && { embedding: [...memory.embedding] } };
21399
+ const path = memoryPath(memory.memory_id);
21400
+ const snapshot = typeof expectedVersion === "number" ? void 0 : snapshots.get(expectedVersion);
21401
+ if (typeof expectedVersion !== "number" && (!snapshot || snapshot.id !== memory.memory_id || snapshot.version !== expectedVersion.version))
21402
+ throw new Error(
21403
+ "Expected snapshot must be an unmodified version from this persistence instance"
21404
+ );
21405
+ expectedVersion = typeof expectedVersion === "number" ? expectedVersion : snapshot.version;
21406
+ if (!Number.isSafeInteger(expectedVersion) || expectedVersion < 0)
21407
+ throw new Error("expectedVersion must be a nonnegative integer");
21408
+ const conflict = () => new RemoteMemoryError("The memory changed since it was read", 409, "version_conflict");
21409
+ let existing;
21410
+ if (expectedVersion !== 0 && !snapshot) {
21411
+ try {
21412
+ existing = memoryRecord(await request(path, {}, signal));
21413
+ } catch (error) {
21414
+ if (error instanceof RemoteMemoryError && error.status === 404) throw conflict();
21415
+ throw error;
21416
+ }
21417
+ }
21418
+ if (existing && existing.version !== expectedVersion) throw conflict();
21419
+ const decoded = existing ? await decode(existing).catch(() => void 0) : void 0;
21420
+ const content = (snapshot?.content ?? decoded?.memory.content) === memory.content ? snapshot?.encryptedContent ?? existing.memory.content : await encryptField2(memory.content);
21421
+ 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);
21422
+ return {
21423
+ body: {
21424
+ expected_version: expectedVersion,
21425
+ memory: { ...memory, content, ...kindValue !== void 0 && { kind_value: kindValue } }
21426
+ },
21427
+ content: memory.content,
21428
+ kindValue: memory.kind_value
21429
+ };
21430
+ };
21431
+ const fetchCandidates = async (embedding, candidateOptions, withCounts) => {
21432
+ const limit = candidateOptions.limit ?? 100;
21433
+ if (!Number.isInteger(limit) || limit < 1 || limit > 100)
21434
+ throw new Error("Candidate limit must be 1\u2013100");
21435
+ for (const [key, max] of candidateListLimits) {
21436
+ const values = candidateOptions[key];
21437
+ if (values && values.length > max)
21438
+ throw new Error(`Candidate ${key} accepts at most ${max} entries (got ${values.length})`);
21439
+ }
21440
+ const result = await request(
21441
+ "/candidates",
21442
+ {
21443
+ method: "POST",
21444
+ body: JSON.stringify({
21445
+ embedding,
21446
+ limit,
21447
+ force_ids: candidateOptions.force_ids ?? [],
21448
+ ...withCounts && { with_counts: true },
21449
+ ...Object.fromEntries(
21450
+ [
21451
+ "scopes",
21452
+ "memory_ids",
21453
+ "embedding_model",
21454
+ "strict_model",
21455
+ "include_deleted",
21456
+ "deleted_only"
21457
+ ].filter(
21458
+ (key) => candidateOptions[key] !== void 0
21459
+ ).map((key) => [key, candidateOptions[key]])
21460
+ ),
21461
+ ...candidateOptions.fact_types !== void 0 && {
21462
+ fact_types: candidateOptions.fact_types
21463
+ },
21464
+ ...candidateOptions.include_archived !== void 0 && {
21465
+ include_archived: candidateOptions.include_archived
21466
+ },
21467
+ ...candidateOptions.include_quarantined !== void 0 && {
21468
+ include_quarantined: candidateOptions.include_quarantined
21469
+ },
21470
+ ...candidateOptions.include_superseded !== void 0 && {
21471
+ include_superseded: candidateOptions.include_superseded
21472
+ }
21473
+ })
21474
+ },
21475
+ candidateOptions.signal
21476
+ );
21477
+ if (!record(result) || !Array.isArray(result.items))
21478
+ throw new Error("Invalid nearby candidate response");
21479
+ return result;
21480
+ };
21481
+ const candidateSet = async (embedding, candidateOptions = {}) => {
21482
+ const result = await fetchCandidates(embedding, candidateOptions, true);
21483
+ if (!Number.isSafeInteger(result.total_count) || result.total_count < 0 || !Number.isSafeInteger(result.unavailable_count) || result.unavailable_count < 0)
21484
+ throw new Error("Invalid nearby candidate response");
21485
+ return {
21486
+ ...await decodeAll(result.items),
21487
+ total_count: result.total_count,
21488
+ unavailable_count: result.unavailable_count
21489
+ };
21490
+ };
21491
+ return {
21492
+ get: async (id, signal) => {
21493
+ try {
21494
+ return await decode(await request(memoryPath(id), {}, signal));
21495
+ } catch (error) {
21496
+ if (error instanceof RemoteMemoryError && error.status === 404) return null;
21497
+ throw error;
21498
+ }
21499
+ },
21500
+ list: async (listOptions = {}) => {
21501
+ const { signal, ...query } = listOptions;
21502
+ if (query.limit !== void 0 && (!Number.isInteger(query.limit) || query.limit < 1 || query.limit > 200)) {
21503
+ throw new Error("Page limit must be 1\u2013200");
21504
+ }
21505
+ const params = new URLSearchParams();
21506
+ for (const key of [
21507
+ "cursor",
21508
+ "limit",
21509
+ "include_deleted",
21510
+ "include_archived",
21511
+ "include_quarantined",
21512
+ "include_superseded",
21513
+ "include_embeddings"
21514
+ ]) {
21515
+ if (query[key] !== void 0) params.set(key, String(query[key]));
21516
+ }
21517
+ const page = await request("/memories?" + params.toString(), {}, signal);
21518
+ if (!record(page) || !Array.isArray(page.items) || page.next_cursor !== void 0 && typeof page.next_cursor !== "string") {
21519
+ throw new Error("Invalid nearby private-memory page");
21520
+ }
21521
+ return {
21522
+ ...await decodeAll(page.items),
21523
+ ...page.next_cursor !== void 0 && { next_cursor: page.next_cursor }
21524
+ };
21525
+ },
21526
+ put: async (memory, expectedVersion, signal) => {
21527
+ const write = await prepareWrite(memory, expectedVersion, signal);
21528
+ return decodeCommitted(
21529
+ await request(
21530
+ memoryPath(write.body.memory.memory_id),
21531
+ {
21532
+ method: "PUT",
21533
+ body: JSON.stringify({ key_id: options.keyId, ...write.body })
21534
+ },
21535
+ signal
21536
+ ),
21537
+ write
21538
+ );
21539
+ },
21540
+ putMany: async (writes, signal) => {
21541
+ if (writes.length < 1 || writes.length > 50 || new Set(writes.map((w) => w.memory.memory_id)).size !== writes.length)
21542
+ throw new Error("Batch must contain 1\u201350 distinct memory ids");
21543
+ const prepared = await Promise.all(
21544
+ writes.map((w) => prepareWrite(w.memory, w.expectedVersion, signal))
21545
+ );
21546
+ const result = await request(
21547
+ "/memories/batch",
21548
+ {
21549
+ method: "POST",
21550
+ body: JSON.stringify({ key_id: options.keyId, writes: prepared.map((w) => w.body) })
21551
+ },
21552
+ signal
21553
+ );
21554
+ if (!record(result) || !Array.isArray(result.items) || result.items.length !== prepared.length)
21555
+ throw new Error("Invalid nearby batch response");
21556
+ return Promise.all(result.items.map((item, i) => decodeCommitted(item, prepared[i])));
21557
+ },
21558
+ candidateSet,
21559
+ candidates: async (embedding, candidateOptions = {}) => decodeAll((await fetchCandidates(embedding, candidateOptions, false)).items)
21560
+ };
21561
+ }
21562
+
21563
+ // src/lib/memory/store/remotePipeline.ts
21564
+ import { v7 as uuidv75 } from "uuid";
21565
+ function storedVector(vector) {
21566
+ if (!Array.isArray(vector) || vector.length !== 1536 && vector.length !== 4096 || vector.some((v) => !Number.isFinite(v)))
21567
+ throw new Error("Remote memories require a finite 1536/4096-dimensional vector");
21568
+ const out = vector.slice(0, 1536);
21569
+ const norm = Math.sqrt(out.reduce((sum, v) => sum + v * v, 0));
21570
+ if (!norm) throw new Error("Remote query/content vector has no direction after MRL truncation");
21571
+ return out.map((v) => v / norm);
21572
+ }
21573
+ function sourceIds(value) {
21574
+ if (!value) return [];
21575
+ try {
21576
+ const parsed = JSON.parse(value);
21577
+ return Array.isArray(parsed) ? parsed.filter((id) => typeof id === "string") : [];
21578
+ } catch {
21579
+ return [];
21580
+ }
21581
+ }
21582
+ function isMemoryLevel(value) {
21583
+ return MEMORY_LEVELS.includes(value);
21584
+ }
21585
+ function stored(row) {
21586
+ return {
21587
+ uniqueId: row.memory_id,
21588
+ content: row.content,
21589
+ scope: row.scope,
21590
+ folderId: row.folder_id ?? null,
21591
+ userId: null,
21592
+ kind: row.kind ?? null,
21593
+ kindValue: row.kind_value ?? null,
21594
+ ...isMemoryLevel(row.level) && { level: row.level },
21595
+ embedding: row.embedding ? JSON.stringify(row.embedding) : null,
21596
+ embeddingModel: row.embedding_model ?? null,
21597
+ sourceChunkIds: row.source_chunk_ids === void 0 ? null : sourceIds(row.source_chunk_ids),
21598
+ proofCount: row.proof_count ?? null,
21599
+ source: row.source ?? null,
21600
+ media: parseMedia(row.media),
21601
+ eventTimeStart: row.event_time_start ?? null,
21602
+ eventTimeEnd: row.event_time_end ?? null,
21603
+ eventTimeKind: row.event_time_kind ?? null,
21604
+ topicsUserManaged: row.topics_user_managed ?? false,
21605
+ topics: parseTopics(row.topics),
21606
+ topicsUpdatedAt: row.topics_updated_at ?? null,
21607
+ topicsExtractedAt: row.topics_extracted_at ?? null,
21608
+ topicsExtractedVersion: row.topics_extracted_version ?? null,
21609
+ supersededBy: row.superseded_by ?? null,
21610
+ supersededAt: row.superseded_at ?? null,
21611
+ lastObservedAt: row.last_observed_at ?? null,
21612
+ factType: row.fact_type ?? null,
21613
+ archivedAt: row.archived_at ?? null,
21614
+ trustTier: row.trust_tier ?? null,
21615
+ visibility: row.visibility === "public" ? "public" : "private",
21616
+ twinOptIn: row.twin_opt_in ?? false,
21617
+ publishedAt: row.published_at ?? null,
21618
+ geohash: row.geohash ?? null,
21619
+ createdAt: new Date(row.created_at),
21620
+ updatedAt: new Date(row.updated_at),
21621
+ isDeleted: row.is_deleted
21622
+ };
21623
+ }
21624
+ function createRemoteMemoryPipeline(options) {
21625
+ const { persistence, embeddingOptions } = options;
21626
+ const model = embeddingOptions.model ?? DEFAULT_API_EMBEDDING_MODEL;
21627
+ const operation = (mode) => {
21628
+ const rejectUndecryptable = (failed) => {
21629
+ if (!failed.length) return;
21630
+ if (mode === "retain")
21631
+ throw new Error(
21632
+ `Remote memories could not decrypt ${failed.length} candidate row(s); refusing to retain until they are repaired`
21633
+ );
21634
+ getLogger().warn(
21635
+ `[memory/remote] Skipping ${failed.length} undecryptable candidate row(s)`,
21636
+ failed.map((failure) => failure.memory_id)
21637
+ );
21638
+ };
21639
+ const snapshots = /* @__PURE__ */ new Map();
21640
+ const remember = (items) => {
21641
+ items.forEach((item) => snapshots.set(item.memory.memory_id, item));
21642
+ return items.map((item) => stored(item.memory));
21643
+ };
21644
+ const get = async (id) => {
21645
+ const snapshot = snapshots.get(id) ?? await persistence.get(id);
21646
+ if (!snapshot || snapshot.memory.is_deleted || snapshot.memory.superseded_by) return null;
21647
+ snapshots.set(id, snapshot);
21648
+ return stored(snapshot.memory);
21649
+ };
21650
+ const prepare = async (query, search = {}) => {
21651
+ if (search.folderId !== void 0)
21652
+ throw new Error("Remote memories do not support folder filters");
21653
+ const facets = normalizeSubQueries(search.subQueries);
21654
+ const facetQueries = facets.length >= 2 ? facets : [];
21655
+ const start = Date.now();
21656
+ const budgetMs = search.queryEmbedTotalTimeoutMs ?? 8e3;
21657
+ const embed = (texts) => generateEmbeddings(texts, {
21658
+ ...embeddingOptions,
21659
+ totalTimeoutMs: budgetMs
21660
+ });
21661
+ const embedFacets = async () => {
21662
+ if (!facetQueries.length) return [];
21663
+ try {
21664
+ const vectors2 = await embed(facetQueries);
21665
+ if (vectors2.length !== facetQueries.length)
21666
+ throw new Error("Incomplete facet embeddings");
21667
+ return vectors2.map(storedVector);
21668
+ } catch (error) {
21669
+ getLogger().warn(
21670
+ "[memory/remote] Facet embeddings unavailable; using primary query",
21671
+ error
21672
+ );
21673
+ return [];
21674
+ }
21675
+ };
21676
+ const [primary, facetEmbeddings] = await Promise.all([
21677
+ search.queryEmbedding ?? embed([query]).then((vectors2) => vectors2[0]),
21678
+ embedFacets()
21679
+ ]);
21680
+ const queryEmbedding = storedVector(primary);
21681
+ const queryEmbedMs = Date.now() - start;
21682
+ const graph = search.entityRanking ?? [];
21683
+ const temporal = search.temporalRanking ?? [];
21684
+ const forced = /* @__PURE__ */ new Set();
21685
+ for (let i = 0; i < Math.max(graph.length, temporal.length) && forced.size < 100; i++) {
21686
+ if (graph[i] !== void 0) forced.add(graph[i]);
21687
+ if (forced.size < 100 && temporal[i] !== void 0) forced.add(temporal[i]);
21688
+ }
21689
+ const forceIds = [...forced];
21690
+ const windowOptions = (i, signal) => ({
21691
+ limit: Math.min(100, Math.max((search.limit ?? 8) * 3, 30)),
21692
+ force_ids: i === 0 ? forceIds : [],
21693
+ ...search.scopes && { scopes: search.scopes },
21694
+ ...search.factTypes && { fact_types: search.factTypes },
21695
+ ...search.memoryIds !== void 0 && { memory_ids: search.memoryIds },
21696
+ include_archived: search.includeArchived,
21697
+ embedding_model: model,
21698
+ ...signal && { signal }
21699
+ });
21700
+ const vectors = [queryEmbedding, ...facetEmbeddings];
21701
+ let windows;
21702
+ if (mode === "retain") {
21703
+ windows = await Promise.all(
21704
+ vectors.map((embedding, i) => persistence.candidateSet(embedding, windowOptions(i)))
21705
+ );
21706
+ } else {
21707
+ const deadline = new AbortController();
21708
+ const timer = setTimeout(
21709
+ () => deadline.abort(
21710
+ new RemoteMemoryError("Remote recall exceeded its query budget", 408, "timeout")
21711
+ ),
21712
+ Math.max(0, start + budgetMs - Date.now())
21713
+ );
21714
+ try {
21715
+ windows = await Promise.all(
21716
+ vectors.map(
21717
+ (embedding, i) => persistence.candidates(embedding, windowOptions(i, deadline.signal))
21718
+ )
21719
+ );
21720
+ } finally {
21721
+ clearTimeout(timer);
21722
+ }
21723
+ }
21724
+ rejectUndecryptable([
21725
+ ...new Map(
21726
+ windows.flatMap((window2) => window2.failed).map((failure) => [failure.memory_id, failure])
21727
+ ).values()
21728
+ ]);
21729
+ const items = [
21730
+ ...new Map(
21731
+ windows.flatMap((window2) => window2.items).map((item) => [item.memory.memory_id, item])
21732
+ ).values()
21733
+ ];
21734
+ const memories = remember(items);
21735
+ return {
21736
+ memories,
21737
+ embeddedItems: memories.map((memory) => ({
21738
+ id: memory.uniqueId,
21739
+ content: memory.content,
21740
+ embedding: JSON.parse(memory.embedding ?? "[]"),
21741
+ createdAt: memory.createdAt,
21742
+ updatedAt: memory.updatedAt,
21743
+ proofCount: memory.proofCount,
21744
+ lastObservedAt: memory.lastObservedAt,
21745
+ eventTimeStart: memory.eventTimeStart,
21746
+ eventTimeEnd: memory.eventTimeEnd,
21747
+ eventTimeKind: memory.eventTimeKind === "point" || memory.eventTimeKind === "range" || memory.eventTimeKind === "ongoing" ? memory.eventTimeKind : null,
21748
+ factType: memory.factType,
21749
+ sourceChunkIds: memory.sourceChunkIds
21750
+ })),
21751
+ queryEmbedding,
21752
+ facetEmbeddings,
21753
+ vaultSize: Math.max(windows[0].total_count ?? 0, items.length),
21754
+ embeddingFailure: windows.some((window2) => (window2.unavailable_count ?? 0) > 0),
21755
+ embeddingsUnavailable: (windows[0].total_count ?? items.length) > 0 && !memories.some((memory) => memory.embedding),
21756
+ decryptLast: true,
21757
+ rowsDecrypted: items.length,
21758
+ queryEmbedMs,
21759
+ rowsEmbedded: 0
21760
+ };
21761
+ };
21762
+ const createRow = (input) => {
21763
+ if (input.folderId !== void 0 && input.folderId !== null)
21764
+ throw new Error("Remote memories do not support folders");
21765
+ const now = Date.now();
21766
+ return {
21767
+ memory_id: uuidv75(),
21768
+ content: input.content,
21769
+ scope: input.scope ?? "private",
21770
+ created_at: now,
21771
+ updated_at: now,
21772
+ is_deleted: false,
21773
+ ...input.embedding !== void 0 && {
21774
+ embedding: storedVector(JSON.parse(input.embedding)),
21775
+ embedding_model: input.embeddingModel
21776
+ },
21777
+ source_chunk_ids: JSON.stringify(input.sourceChunkIds ?? []),
21778
+ proof_count: input.proofCount ?? 1,
21779
+ source: input.source ?? "manual",
21780
+ ...input.eventTime && {
21781
+ event_time_start: input.eventTime.start ?? void 0,
21782
+ event_time_end: input.eventTime.end ?? void 0,
21783
+ event_time_kind: input.eventTime.kind ?? void 0
21784
+ },
21785
+ fact_type: input.factType,
21786
+ trust_tier: normalizeTrustTier(input.trustTier) ?? void 0,
21787
+ geohash: input.geohash,
21788
+ visibility: "private",
21789
+ twin_opt_in: false
21790
+ };
21791
+ };
21792
+ const write = async (memory, snapshot) => remember([await persistence.put(memory, snapshot)])[0];
21793
+ const port = {
21794
+ prepare,
21795
+ get,
21796
+ getFresh: async (id) => {
21797
+ const current = await persistence.get(id);
21798
+ return current && !current.memory.is_deleted && !current.memory.superseded_by ? stored(current.memory) : null;
21799
+ },
21800
+ tombstones: async (embedding, embeddingModel, scope, folderId) => {
21801
+ if (folderId !== void 0) throw new Error("Remote memories do not support folders");
21802
+ const window2 = await persistence.candidateSet(storedVector(embedding), {
21803
+ limit: 1,
21804
+ scopes: [scope],
21805
+ embedding_model: embeddingModel,
21806
+ strict_model: true,
21807
+ include_deleted: true,
21808
+ deleted_only: true
21809
+ });
21810
+ rejectUndecryptable(window2.failed);
21811
+ return remember(window2.items);
21812
+ },
21813
+ create: (input) => write(createRow(input), 0),
21814
+ update: async (id, patch) => {
21815
+ const existing = await get(id);
21816
+ if (!existing || patch.freeFormOnly && existing.kind !== null && existing.kind !== void 0)
21817
+ return null;
21818
+ const snapshot = snapshots.get(id);
21819
+ const memory = {
21820
+ ...snapshot.memory,
21821
+ content: patch.content,
21822
+ updated_at: patch.preserveUpdatedAt ? snapshot.memory.updated_at : Date.now()
21823
+ };
21824
+ if (patch.scope !== void 0) memory.scope = patch.scope;
21825
+ if (patch.embedding === void 0 && patch.content !== snapshot.memory.content) {
21826
+ delete memory.embedding;
21827
+ delete memory.embedding_model;
21828
+ }
21829
+ if (patch.embedding !== void 0) {
21830
+ memory.embedding = patch.embedding === null ? [] : storedVector(JSON.parse(patch.embedding));
21831
+ memory.embedding_model = patch.embeddingModel ?? void 0;
21832
+ }
21833
+ const observed = sourceIds(memory.source_chunk_ids);
21834
+ const replay = !!patch.observationSourceIds?.length && patch.observationSourceIds.every((id2) => observed.includes(id2));
21835
+ if (patch.sourceChunkIds !== void 0)
21836
+ memory.source_chunk_ids = JSON.stringify(
21837
+ patch.observationSourceIds?.length ? [.../* @__PURE__ */ new Set([...observed, ...patch.sourceChunkIds])] : patch.sourceChunkIds
21838
+ );
21839
+ if (!replay) {
21840
+ if (patch.proofCountIncrement !== void 0)
21841
+ memory.proof_count = (memory.proof_count ?? 1) + patch.proofCountIncrement;
21842
+ else if (patch.proofCount !== void 0) memory.proof_count = patch.proofCount;
21843
+ if (patch.lastObservedAt !== void 0) memory.last_observed_at = patch.lastObservedAt;
21844
+ }
21845
+ if (patch.source !== void 0) memory.source = patch.source;
21846
+ if (patch.factType !== void 0) memory.fact_type = patch.factType;
21847
+ if (patch.trustTier !== void 0)
21848
+ memory.trust_tier = normalizeTrustTier(patch.trustTier) ?? void 0;
21849
+ if (patch.topicsUserManaged !== void 0)
21850
+ memory.topics_user_managed = patch.topicsUserManaged;
21851
+ if (patch.eventTime !== void 0) {
21852
+ memory.event_time_start = patch.eventTime.start ?? void 0;
21853
+ memory.event_time_end = patch.eventTime.end ?? void 0;
21854
+ memory.event_time_kind = patch.eventTime.kind ?? void 0;
21855
+ }
21856
+ if (patch.restore) memory.archived_at = void 0;
21857
+ return write(memory, snapshot);
21858
+ },
21859
+ supersede: async (id, successor) => {
21860
+ const [target, newer] = await Promise.all([get(id), get(successor)]);
21861
+ if (!target || !newer || id === successor) return false;
21862
+ const old = snapshots.get(id);
21863
+ const next = snapshots.get(successor);
21864
+ remember(
21865
+ await persistence.putMany([
21866
+ {
21867
+ memory: { ...old.memory, superseded_by: successor, superseded_at: Date.now() },
21868
+ expectedVersion: old
21869
+ },
21870
+ { memory: next.memory, expectedVersion: next }
21871
+ ])
21872
+ );
21873
+ return true;
21874
+ },
21875
+ createSuperseding: async (input, targetId) => {
21876
+ const target = await get(targetId);
21877
+ if (!target) return { created: null, retired: false };
21878
+ const snapshot = snapshots.get(targetId);
21879
+ const successor = createRow(input);
21880
+ const rows = remember(
21881
+ await persistence.putMany([
21882
+ { memory: successor, expectedVersion: 0 },
21883
+ {
21884
+ memory: {
21885
+ ...snapshot.memory,
21886
+ superseded_by: successor.memory_id,
21887
+ superseded_at: Date.now()
21888
+ },
21889
+ expectedVersion: snapshot
21890
+ }
21891
+ ])
21892
+ );
21893
+ return { created: rows[0], retired: true };
21894
+ }
21895
+ };
21896
+ return { prepare, port };
21897
+ };
21898
+ return {
21899
+ recall: async (query, recallOptions = {}) => {
21900
+ const { prepare } = operation("recall");
21901
+ return recall(
21902
+ query,
21903
+ {
21904
+ embeddingOptions,
21905
+ factSource: {
21906
+ graphRanking: options.graphRanking,
21907
+ temporalRanking: options.temporalRanking,
21908
+ search: async (text12, searchOptions) => {
21909
+ const prepared = await prepare(text12, searchOptions);
21910
+ const ranked = await rankPreparedVaultCandidates(
21911
+ text12,
21912
+ prepared,
21913
+ embeddingOptions,
21914
+ searchOptions
21915
+ );
21916
+ return {
21917
+ ...ranked,
21918
+ rankedOnCosine: prepared.memories.length > 0 && !prepared.embeddingsUnavailable,
21919
+ decryptLast: true,
21920
+ rowsDecrypted: prepared.rowsDecrypted,
21921
+ queryEmbedMs: prepared.queryEmbedMs,
21922
+ rowsEmbedded: 0
21923
+ };
21924
+ }
21925
+ }
21926
+ },
21927
+ { ...recallOptions, types: ["fact"] }
21928
+ );
21929
+ },
21930
+ retain: async (content, retainOptions) => {
21931
+ const { port } = operation("retain");
21932
+ return retainWithPersistence(
21933
+ content,
21934
+ {
21935
+ persistence: port,
21936
+ embeddingOptions,
21937
+ vaultCache: /* @__PURE__ */ new Map(),
21938
+ normalizeEmbedding: storedVector
21939
+ },
21940
+ retainOptions
21941
+ );
21942
+ }
21943
+ };
21944
+ }
21945
+
20955
21946
  // src/lib/memory/synthesizeProfile.ts
20956
21947
  var DEFAULT_SYNTHESIS_MODEL = "inclusionai/ling-2.6-flash";
20957
21948
  var DEFAULT_FACET_RECALL_LIMIT = 20;
@@ -27206,7 +28197,7 @@ async function uploadFileToICloud(filename, content) {
27206
28197
  const recordName = `backup_${filename.replace(/[^a-zA-Z0-9]/g, "_")}`;
27207
28198
  const arrayBuffer = await content.arrayBuffer();
27208
28199
  const base64Data = uint8ArrayToBase64(new Uint8Array(arrayBuffer));
27209
- const record = {
28200
+ const record2 = {
27210
28201
  recordType: RECORD_TYPE,
27211
28202
  recordName,
27212
28203
  fields: {
@@ -27216,7 +28207,7 @@ async function uploadFileToICloud(filename, content) {
27216
28207
  contentType: { value: content.type || "application/json" }
27217
28208
  }
27218
28209
  };
27219
- const response = await database.saveRecords(record);
28210
+ const response = await database.saveRecords(record2);
27220
28211
  if (!response.records || response.records.length === 0) {
27221
28212
  throw new Error("Failed to upload file to iCloud");
27222
28213
  }
@@ -27242,11 +28233,11 @@ async function listICloudFiles() {
27242
28233
  while (response.continuationMarker) {
27243
28234
  break;
27244
28235
  }
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
28236
+ const files = allRecords.map((record2) => ({
28237
+ recordName: record2.recordName,
28238
+ filename: record2.fields.filename?.value ?? "",
28239
+ modifiedAt: new Date(record2.modified?.timestamp ?? Date.now()),
28240
+ size: typeof record2.fields.data?.value === "object" && record2.fields.data?.value !== null ? record2.fields.data.value.size : 0
27250
28241
  }));
27251
28242
  return files.sort((a, b) => b.modifiedAt.getTime() - a.modifiedAt.getTime());
27252
28243
  }
@@ -27259,8 +28250,8 @@ async function downloadICloudFile(recordName) {
27259
28250
  if (!response.records || response.records.length === 0) {
27260
28251
  throw new Error(`File not found: ${recordName}`);
27261
28252
  }
27262
- const record = response.records[0];
27263
- const dataField = record.fields.data?.value;
28253
+ const record2 = response.records[0];
28254
+ const dataField = record2.fields.data?.value;
27264
28255
  if (!dataField) {
27265
28256
  throw new Error("No data in record");
27266
28257
  }
@@ -27294,12 +28285,12 @@ async function findICloudFile(filename) {
27294
28285
  if (!response.records || response.records.length === 0) {
27295
28286
  return null;
27296
28287
  }
27297
- const record = response.records[0];
28288
+ const record2 = response.records[0];
27298
28289
  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
28290
+ recordName: record2.recordName,
28291
+ filename: record2.fields.filename?.value ?? "",
28292
+ modifiedAt: new Date(record2.modified?.timestamp ?? Date.now()),
28293
+ size: typeof record2.fields.data?.value === "object" && record2.fields.data?.value !== null ? record2.fields.data.value.size : 0
27303
28294
  };
27304
28295
  }
27305
28296
 
@@ -27457,8 +28448,8 @@ async function getStoredTokenData5(provider, walletAddress) {
27457
28448
  return null;
27458
28449
  }
27459
28450
  }
27460
- async function readTokenRow(stored, provider, walletAddress) {
27461
- if (stored.startsWith(ENCRYPTED_PREFIX6)) {
28451
+ async function readTokenRow(stored2, provider, walletAddress) {
28452
+ if (stored2.startsWith(ENCRYPTED_PREFIX6)) {
27462
28453
  if (!walletAddress) {
27463
28454
  getLogger().warn(
27464
28455
  `Encrypted OAuth token found for ${provider} but no wallet address provided`
@@ -27466,7 +28457,7 @@ async function readTokenRow(stored, provider, walletAddress) {
27466
28457
  return null;
27467
28458
  }
27468
28459
  try {
27469
- const encryptedData = stored.slice(ENCRYPTED_PREFIX6.length);
28460
+ const encryptedData = stored2.slice(ENCRYPTED_PREFIX6.length);
27470
28461
  let decryptedJson;
27471
28462
  try {
27472
28463
  decryptedJson = await decryptData(encryptedData, walletAddress);
@@ -27481,7 +28472,7 @@ async function readTokenRow(stored, provider, walletAddress) {
27481
28472
  return null;
27482
28473
  }
27483
28474
  }
27484
- return parsePlaintextToken(stored, walletAddress);
28475
+ return parsePlaintextToken(stored2, walletAddress);
27485
28476
  }
27486
28477
  async function storeTokenData5(provider, data, walletAddress) {
27487
28478
  if (typeof window === "undefined") return;
@@ -27557,8 +28548,8 @@ async function migrateUnencryptedTokens(provider, walletAddress) {
27557
28548
  const keys = [scopedKey, legacyKey];
27558
28549
  const isEncrypted2 = (value) => !!value && value.startsWith(ENCRYPTED_PREFIX6);
27559
28550
  const plaintextAt = (key) => {
27560
- const stored = sessionStorage.getItem(key) ?? localStorage.getItem(key);
27561
- return stored && !isEncrypted2(stored) ? stored : null;
28551
+ const stored2 = sessionStorage.getItem(key) ?? localStorage.getItem(key);
28552
+ return stored2 && !isEncrypted2(stored2) ? stored2 : null;
27562
28553
  };
27563
28554
  let tokenToMigrate = null;
27564
28555
  for (const key of keys) {
@@ -27570,8 +28561,8 @@ async function migrateUnencryptedTokens(provider, walletAddress) {
27570
28561
  }
27571
28562
  if (!tokenToMigrate) {
27572
28563
  for (const key of keys) {
27573
- const stored = sessionStorage.getItem(key);
27574
- if (isEncrypted2(localStorage.getItem(key)) && stored && !isEncrypted2(stored)) {
28564
+ const stored2 = sessionStorage.getItem(key);
28565
+ if (isEncrypted2(localStorage.getItem(key)) && stored2 && !isEncrypted2(stored2)) {
27575
28566
  sessionStorage.removeItem(key);
27576
28567
  }
27577
28568
  }
@@ -27627,17 +28618,17 @@ function storeOAuthState2(state) {
27627
28618
  }
27628
28619
  function getAndClearOAuthState4() {
27629
28620
  if (typeof window === "undefined") return null;
27630
- const stored = sessionStorage.getItem(STATE_STORAGE_KEY);
28621
+ const stored2 = sessionStorage.getItem(STATE_STORAGE_KEY);
27631
28622
  sessionStorage.removeItem(STATE_STORAGE_KEY);
27632
- if (!stored) return null;
28623
+ if (!stored2) return null;
27633
28624
  try {
27634
- const parsed = JSON.parse(stored);
28625
+ const parsed = JSON.parse(stored2);
27635
28626
  if (parsed && typeof parsed === "object" && "state" in parsed) {
27636
28627
  return parsed.state;
27637
28628
  }
27638
28629
  } catch {
27639
28630
  }
27640
- return stored;
28631
+ return stored2;
27641
28632
  }
27642
28633
  function isDropboxCallback() {
27643
28634
  if (typeof window === "undefined") return false;
@@ -27820,17 +28811,17 @@ function storeOAuthState3(state) {
27820
28811
  }
27821
28812
  function getAndClearOAuthState5() {
27822
28813
  if (typeof window === "undefined") return null;
27823
- const stored = sessionStorage.getItem(CODE_STORAGE_KEY4);
28814
+ const stored2 = sessionStorage.getItem(CODE_STORAGE_KEY4);
27824
28815
  sessionStorage.removeItem(CODE_STORAGE_KEY4);
27825
- if (!stored) return null;
28816
+ if (!stored2) return null;
27826
28817
  try {
27827
- const parsed = JSON.parse(stored);
28818
+ const parsed = JSON.parse(stored2);
27828
28819
  if (parsed && typeof parsed === "object" && "state" in parsed) {
27829
28820
  return parsed.state;
27830
28821
  }
27831
28822
  } catch {
27832
28823
  }
27833
- return stored;
28824
+ return stored2;
27834
28825
  }
27835
28826
  function isGoogleDriveCallback() {
27836
28827
  if (typeof window === "undefined") return false;
@@ -29760,18 +30751,18 @@ async function blobToDataUri(blob) {
29760
30751
  reader.readAsDataURL(blob);
29761
30752
  });
29762
30753
  }
29763
- async function storedToLlmapiMessage(stored, encryptionKey, resolveMediaByIds) {
29764
- let textContent = stored.content;
30754
+ async function storedToLlmapiMessage(stored2, encryptionKey, resolveMediaByIds) {
30755
+ let textContent = stored2.content;
29765
30756
  const fileUrlMap = /* @__PURE__ */ new Map();
29766
30757
  const imageParts = [];
29767
- if (stored.role !== "assistant" && stored.files?.length) {
29768
- for (const file of stored.files) {
30758
+ if (stored2.role !== "assistant" && stored2.files?.length) {
30759
+ for (const file of stored2.files) {
29769
30760
  if (isSendableImageURL(file.url)) {
29770
30761
  imageParts.push({
29771
30762
  type: "image_url",
29772
30763
  image_url: { url: file.url }
29773
30764
  });
29774
- } else if (file.sourceUrl && !isR2UrlExpired(file.sourceUrl, stored.createdAt)) {
30765
+ } else if (file.sourceUrl && !isR2UrlExpired(file.sourceUrl, stored2.createdAt)) {
29775
30766
  imageParts.push({
29776
30767
  type: "image_url",
29777
30768
  image_url: { url: file.sourceUrl }
@@ -29791,11 +30782,11 @@ async function storedToLlmapiMessage(stored, encryptionKey, resolveMediaByIds) {
29791
30782
  }
29792
30783
  }
29793
30784
  }
29794
- } else if (stored.role === "assistant" && stored.files?.length) {
30785
+ } else if (stored2.role === "assistant" && stored2.files?.length) {
29795
30786
  const expiredFileIds = [];
29796
- for (const file of stored.files) {
30787
+ for (const file of stored2.files) {
29797
30788
  if (file.sourceUrl) {
29798
- if (!isR2UrlExpired(file.sourceUrl, stored.createdAt)) {
30789
+ if (!isR2UrlExpired(file.sourceUrl, stored2.createdAt)) {
29799
30790
  fileUrlMap.set(file.id, file.sourceUrl);
29800
30791
  } else {
29801
30792
  expiredFileIds.push(file.id);
@@ -29808,11 +30799,11 @@ async function storedToLlmapiMessage(stored, encryptionKey, resolveMediaByIds) {
29808
30799
  [${expiredFileIds.length} expired image URL${expiredFileIds.length > 1 ? "s" : ""} omitted \u2014 the user can still see ${expiredFileIds.length > 1 ? "them" : "it"} locally]`;
29809
30800
  }
29810
30801
  }
29811
- if (stored.fileIds?.length && resolveMediaByIds) {
30802
+ if (stored2.fileIds?.length && resolveMediaByIds) {
29812
30803
  try {
29813
- const mediaItems = await resolveMediaByIds(stored.fileIds);
30804
+ const mediaItems = await resolveMediaByIds(stored2.fileIds);
29814
30805
  for (const media of mediaItems) {
29815
- if (media.sourceUrl && !isR2UrlExpired(media.sourceUrl, stored.createdAt)) {
30806
+ if (media.sourceUrl && !isR2UrlExpired(media.sourceUrl, stored2.createdAt)) {
29816
30807
  fileUrlMap.set(media.mediaId, media.sourceUrl);
29817
30808
  }
29818
30809
  }
@@ -29836,7 +30827,7 @@ async function storedToLlmapiMessage(stored, encryptionKey, resolveMediaByIds) {
29836
30827
  return "";
29837
30828
  }
29838
30829
  );
29839
- if (stored.role === "assistant" && fileUrlMap.size > 0) {
30830
+ if (stored2.role === "assistant" && fileUrlMap.size > 0) {
29840
30831
  const unreferencedImages = [...fileUrlMap.entries()].filter(
29841
30832
  ([, url]) => !textContent.includes(url)
29842
30833
  );
@@ -29848,11 +30839,11 @@ async function storedToLlmapiMessage(stored, encryptionKey, resolveMediaByIds) {
29848
30839
  textContent = textContent.replace(/\n{3,}/g, "\n\n").trim();
29849
30840
  const content = [{ type: "text", text: textContent }, ...imageParts];
29850
30841
  const messages = [];
29851
- if (stored.role === "assistant" && stored.toolCallEvents?.length) {
30842
+ if (stored2.role === "assistant" && stored2.toolCallEvents?.length) {
29852
30843
  messages.push({
29853
- role: stored.role,
30844
+ role: stored2.role,
29854
30845
  content: void 0,
29855
- tool_calls: stored.toolCallEvents.map((event) => ({
30846
+ tool_calls: stored2.toolCallEvents.map((event) => ({
29856
30847
  id: event.id,
29857
30848
  type: "function",
29858
30849
  function: {
@@ -29861,7 +30852,7 @@ async function storedToLlmapiMessage(stored, encryptionKey, resolveMediaByIds) {
29861
30852
  }
29862
30853
  }))
29863
30854
  });
29864
- for (const event of stored.toolCallEvents) {
30855
+ for (const event of stored2.toolCallEvents) {
29865
30856
  if (event.id && event.output !== void 0 && event.output !== null) {
29866
30857
  messages.push({
29867
30858
  role: "tool",
@@ -29872,12 +30863,12 @@ async function storedToLlmapiMessage(stored, encryptionKey, resolveMediaByIds) {
29872
30863
  }
29873
30864
  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
30865
  messages.push({
29875
- role: stored.role,
30866
+ role: stored2.role,
29876
30867
  content: [{ type: "text", text: postToolText }]
29877
30868
  });
29878
30869
  } else {
29879
30870
  messages.push({
29880
- role: stored.role,
30871
+ role: stored2.role,
29881
30872
  content
29882
30873
  });
29883
30874
  }
@@ -33708,19 +34699,19 @@ function startObserve(entry, walletAddress) {
33708
34699
  "updated_at"
33709
34700
  ]).subscribe({
33710
34701
  next: (records) => {
33711
- const record = records[0];
33712
- if (!record) return;
34702
+ const record2 = records[0];
34703
+ if (!record2) return;
33713
34704
  const patch = {
33714
34705
  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
34706
+ uniqueId: record2.id,
34707
+ walletAddress: record2.walletAddress,
34708
+ nickname: record2.nickname,
34709
+ occupation: record2.occupation,
34710
+ description: record2.description,
34711
+ models: record2.models,
34712
+ personality: record2.personality,
34713
+ createdAt: record2.createdAt,
34714
+ updatedAt: record2.updatedAt
33724
34715
  }
33725
34716
  };
33726
34717
  if (isInitialEmission) {
@@ -34930,7 +35921,10 @@ export {
34930
35921
  LoggerProvider,
34931
35922
  MAX_HOPS,
34932
35923
  MEDIUM_TTL_MS,
35924
+ MEMORY_KINDS,
35925
+ MEMORY_LEVELS,
34933
35926
  MemoryEntity as MemoryEntityModel,
35927
+ MemoryLevelError,
34934
35928
  NEVER_TTL_MS,
34935
35929
  NODE_BUDGET,
34936
35930
  PAST_EVENT_GRACE_MS,
@@ -34943,6 +35937,7 @@ export {
34943
35937
  R2_DEFAULT_TTL_MS,
34944
35938
  RECALL_MAX_LIMIT,
34945
35939
  RECALL_TOOL_NAME,
35940
+ RemoteMemoryError,
34946
35941
  RerankerUnavailableError,
34947
35942
  SDK_SCHEMA_VERSION,
34948
35943
  SERVER_TOOL_DEPENDENCY_SETS,
@@ -35034,6 +36029,8 @@ export {
35034
36029
  createPlatformCursorStore,
35035
36030
  createProjectOp,
35036
36031
  createRecallTool,
36032
+ createRemoteMemoryPersistence,
36033
+ createRemoteMemoryPipeline,
35037
36034
  createSavedToolOp,
35038
36035
  createServerToolsFilter,
35039
36036
  createStockPricePreProcessor,