@anuma/sdk 6.33.2 → 6.34.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1437,6 +1437,7 @@ __export(index_exports, {
1437
1437
  R2_DEFAULT_TTL_MS: () => R2_DEFAULT_TTL_MS,
1438
1438
  RECALL_MAX_LIMIT: () => RECALL_MAX_LIMIT,
1439
1439
  RECALL_TOOL_NAME: () => RECALL_TOOL_NAME,
1440
+ RemoteMemoryError: () => RemoteMemoryError,
1440
1441
  RerankerUnavailableError: () => RerankerUnavailableError,
1441
1442
  SDK_SCHEMA_VERSION: () => SDK_SCHEMA_VERSION,
1442
1443
  SERVER_TOOL_DEPENDENCY_SETS: () => SERVER_TOOL_DEPENDENCY_SETS,
@@ -1528,6 +1529,8 @@ __export(index_exports, {
1528
1529
  createPlatformCursorStore: () => createPlatformCursorStore,
1529
1530
  createProjectOp: () => createProjectOp,
1530
1531
  createRecallTool: () => createRecallTool,
1532
+ createRemoteMemoryPersistence: () => createRemoteMemoryPersistence,
1533
+ createRemoteMemoryPipeline: () => createRemoteMemoryPipeline,
1531
1534
  createSavedToolOp: () => createSavedToolOp,
1532
1535
  createServerToolsFilter: () => createServerToolsFilter,
1533
1536
  createStockPricePreProcessor: () => createStockPricePreProcessor,
@@ -3554,10 +3557,10 @@ function parsePlaintextToken(raw, walletAddress) {
3554
3557
  return null;
3555
3558
  }
3556
3559
  if (!parsed || typeof parsed !== "object") return null;
3557
- const record = parsed;
3558
- const data = record.token?.accessToken ? record.token : record;
3560
+ const record2 = parsed;
3561
+ const data = record2.token?.accessToken ? record2.token : record2;
3559
3562
  if (!data?.accessToken) return null;
3560
- if (record.wallet && record.wallet !== walletAddress) return null;
3563
+ if (record2.wallet && record2.wallet !== walletAddress) return null;
3561
3564
  return data;
3562
3565
  }
3563
3566
  function promoteUnscopedRow(raw, data, store, scopedKey, unscopedKey, walletAddress) {
@@ -3681,8 +3684,8 @@ async function storeTokenData(data, walletAddress) {
3681
3684
  getLogger().warn("Failed to encrypt GitHub OAuth token:", error);
3682
3685
  }
3683
3686
  }
3684
- const record = { wallet: walletAddress, token: data };
3685
- sessionStorage.setItem(getTokenStorageKey(walletAddress), JSON.stringify(record));
3687
+ const record2 = { wallet: walletAddress, token: data };
3688
+ sessionStorage.setItem(getTokenStorageKey(walletAddress), JSON.stringify(record2));
3686
3689
  }
3687
3690
  function clearGithubToken(walletAddress) {
3688
3691
  if (typeof window === "undefined") return;
@@ -3731,17 +3734,17 @@ function storeOAuthState(state) {
3731
3734
  }
3732
3735
  function getAndClearOAuthState() {
3733
3736
  if (typeof window === "undefined") return null;
3734
- const stored = sessionStorage.getItem(CODE_STORAGE_KEY);
3737
+ const stored2 = sessionStorage.getItem(CODE_STORAGE_KEY);
3735
3738
  sessionStorage.removeItem(CODE_STORAGE_KEY);
3736
- if (!stored) return null;
3739
+ if (!stored2) return null;
3737
3740
  try {
3738
- const parsed = JSON.parse(stored);
3741
+ const parsed = JSON.parse(stored2);
3739
3742
  if (parsed && typeof parsed === "object" && "state" in parsed) {
3740
3743
  return parsed.state;
3741
3744
  }
3742
3745
  } catch {
3743
3746
  }
3744
- return stored;
3747
+ return stored2;
3745
3748
  }
3746
3749
  function isGithubCallback(callbackPath) {
3747
3750
  if (typeof window === "undefined") return false;
@@ -4034,8 +4037,8 @@ async function storeTokenData2(data, walletAddress) {
4034
4037
  getLogger().warn("Failed to encrypt Calendar OAuth token:", error);
4035
4038
  }
4036
4039
  }
4037
- const record = { wallet: walletAddress, token: data };
4038
- sessionStorage.setItem(getTokenStorageKey2(walletAddress), JSON.stringify(record));
4040
+ const record2 = { wallet: walletAddress, token: data };
4041
+ sessionStorage.setItem(getTokenStorageKey2(walletAddress), JSON.stringify(record2));
4039
4042
  }
4040
4043
  function clearCalendarToken(walletAddress) {
4041
4044
  if (typeof window === "undefined") return;
@@ -4075,17 +4078,17 @@ function getRedirectUri2(callbackPath) {
4075
4078
  }
4076
4079
  function getAndClearOAuthState2() {
4077
4080
  if (typeof window === "undefined") return null;
4078
- const stored = sessionStorage.getItem(CODE_STORAGE_KEY2);
4081
+ const stored2 = sessionStorage.getItem(CODE_STORAGE_KEY2);
4079
4082
  sessionStorage.removeItem(CODE_STORAGE_KEY2);
4080
- if (!stored) return null;
4083
+ if (!stored2) return null;
4081
4084
  try {
4082
- const parsed = JSON.parse(stored);
4085
+ const parsed = JSON.parse(stored2);
4083
4086
  if (parsed && typeof parsed === "object" && "state" in parsed) {
4084
4087
  return parsed.state;
4085
4088
  }
4086
4089
  } catch {
4087
4090
  }
4088
- return stored;
4091
+ return stored2;
4089
4092
  }
4090
4093
  function isCalendarCallback(callbackPath) {
4091
4094
  if (typeof window === "undefined") return false;
@@ -4360,8 +4363,8 @@ async function storeTokenData3(data, walletAddress) {
4360
4363
  getLogger().warn("Failed to encrypt Drive OAuth token:", error);
4361
4364
  }
4362
4365
  }
4363
- const record = { wallet: walletAddress, token: data };
4364
- sessionStorage.setItem(getTokenStorageKey3(walletAddress), JSON.stringify(record));
4366
+ const record2 = { wallet: walletAddress, token: data };
4367
+ sessionStorage.setItem(getTokenStorageKey3(walletAddress), JSON.stringify(record2));
4365
4368
  }
4366
4369
  function clearDriveToken(walletAddress) {
4367
4370
  if (typeof window === "undefined") return;
@@ -4401,17 +4404,17 @@ function getRedirectUri3(callbackPath) {
4401
4404
  }
4402
4405
  function getAndClearOAuthState3() {
4403
4406
  if (typeof window === "undefined") return null;
4404
- const stored = sessionStorage.getItem(CODE_STORAGE_KEY3);
4407
+ const stored2 = sessionStorage.getItem(CODE_STORAGE_KEY3);
4405
4408
  sessionStorage.removeItem(CODE_STORAGE_KEY3);
4406
- if (!stored) return null;
4409
+ if (!stored2) return null;
4407
4410
  try {
4408
- const parsed = JSON.parse(stored);
4411
+ const parsed = JSON.parse(stored2);
4409
4412
  if (parsed && typeof parsed === "object" && "state" in parsed) {
4410
4413
  return parsed.state;
4411
4414
  }
4412
4415
  } catch {
4413
4416
  }
4414
- return stored;
4417
+ return stored2;
4415
4418
  }
4416
4419
  function isDriveCallback(callbackPath) {
4417
4420
  if (typeof window === "undefined") return false;
@@ -4741,11 +4744,11 @@ function storePKCEState(pkce) {
4741
4744
  }
4742
4745
  function getAndClearPKCEState() {
4743
4746
  if (typeof window === "undefined") return null;
4744
- const stored = sessionStorage.getItem(PKCE_STORAGE_KEY);
4747
+ const stored2 = sessionStorage.getItem(PKCE_STORAGE_KEY);
4745
4748
  sessionStorage.removeItem(PKCE_STORAGE_KEY);
4746
- if (!stored) return null;
4749
+ if (!stored2) return null;
4747
4750
  try {
4748
- return JSON.parse(stored);
4751
+ return JSON.parse(stored2);
4749
4752
  } catch {
4750
4753
  return null;
4751
4754
  }
@@ -4763,8 +4766,8 @@ async function storeTokenData4(data, walletAddress) {
4763
4766
  } catch {
4764
4767
  }
4765
4768
  }
4766
- const record = { wallet: walletAddress, token: data };
4767
- sessionStorage.setItem(getTokenStorageKey4(walletAddress), JSON.stringify(record));
4769
+ const record2 = { wallet: walletAddress, token: data };
4770
+ sessionStorage.setItem(getTokenStorageKey4(walletAddress), JSON.stringify(record2));
4768
4771
  }
4769
4772
  async function getStoredTokenData4(walletAddress) {
4770
4773
  if (typeof window === "undefined") return null;
@@ -4780,12 +4783,12 @@ async function getStoredTokenData4(walletAddress) {
4780
4783
  cachedWalletAddress4 = null;
4781
4784
  }
4782
4785
  try {
4783
- const stored = localStorage.getItem(getTokenStorageKey4(walletAddress));
4784
- if (stored?.startsWith(ENCRYPTED_PREFIX5)) {
4786
+ const stored2 = localStorage.getItem(getTokenStorageKey4(walletAddress));
4787
+ if (stored2?.startsWith(ENCRYPTED_PREFIX5)) {
4785
4788
  if (walletAddress && hasEncryptionKey(walletAddress)) {
4786
4789
  try {
4787
4790
  const cryptoKey = await getEncryptionKey(walletAddress);
4788
- const encrypted = stored.slice(ENCRYPTED_PREFIX5.length);
4791
+ const encrypted = stored2.slice(ENCRYPTED_PREFIX5.length);
4789
4792
  const decrypted = await decryptDataWithKey(encrypted, cryptoKey);
4790
4793
  const data = JSON.parse(decrypted);
4791
4794
  if (data.accessToken) return data;
@@ -4894,12 +4897,12 @@ async function getClientRegistration(walletAddress) {
4894
4897
  if (typeof window === "undefined") return null;
4895
4898
  try {
4896
4899
  const scopedKey = getClientRegistrationStorageKey(walletAddress);
4897
- const stored = localStorage.getItem(scopedKey);
4898
- if (stored?.startsWith(ENCRYPTED_PREFIX5)) {
4900
+ const stored2 = localStorage.getItem(scopedKey);
4901
+ if (stored2?.startsWith(ENCRYPTED_PREFIX5)) {
4899
4902
  if (walletAddress && hasEncryptionKey(walletAddress)) {
4900
4903
  try {
4901
4904
  const cryptoKey = await getEncryptionKey(walletAddress);
4902
- const encrypted = stored.slice(ENCRYPTED_PREFIX5.length);
4905
+ const encrypted = stored2.slice(ENCRYPTED_PREFIX5.length);
4903
4906
  const decrypted = await decryptDataWithKey(encrypted, cryptoKey);
4904
4907
  const data = JSON.parse(decrypted);
4905
4908
  if (data.clientId) {
@@ -4909,8 +4912,8 @@ async function getClientRegistration(walletAddress) {
4909
4912
  }
4910
4913
  }
4911
4914
  }
4912
- if (stored && !stored.startsWith(ENCRYPTED_PREFIX5)) {
4913
- const data = JSON.parse(stored);
4915
+ if (stored2 && !stored2.startsWith(ENCRYPTED_PREFIX5)) {
4916
+ const data = JSON.parse(stored2);
4914
4917
  if (!data.clientId) return null;
4915
4918
  return data;
4916
4919
  }
@@ -6755,13 +6758,13 @@ async function searchMessagesOp(ctx, queryVector, options) {
6755
6758
  const topK = candidates.sort((a, b) => b.similarity - a.similarity).slice(0, limit);
6756
6759
  return Promise.all(
6757
6760
  topK.map(async ({ message, similarity }) => {
6758
- const stored = await messageRawToStored(
6761
+ const stored2 = await messageRawToStored(
6759
6762
  message,
6760
6763
  ctx.walletAddress,
6761
6764
  ctx.signMessage,
6762
6765
  ctx.embeddedWalletSigner
6763
6766
  );
6764
- return { ...stored, similarity };
6767
+ return { ...stored2, similarity };
6765
6768
  })
6766
6769
  );
6767
6770
  }
@@ -6865,13 +6868,13 @@ async function searchChunksOp(ctx, queryVector, options) {
6865
6868
  const storedById = new Map(
6866
6869
  await Promise.all(
6867
6870
  Array.from(uniqueMessages, async ([id, m]) => {
6868
- const stored = await messageRawToStored(
6871
+ const stored2 = await messageRawToStored(
6869
6872
  m,
6870
6873
  ctx.walletAddress,
6871
6874
  ctx.signMessage,
6872
6875
  ctx.embeddedWalletSigner
6873
6876
  );
6874
- return [id, stored];
6877
+ return [id, stored2];
6875
6878
  })
6876
6879
  )
6877
6880
  );
@@ -6889,18 +6892,18 @@ async function searchChunksOp(ctx, queryVector, options) {
6889
6892
  })
6890
6893
  );
6891
6894
  return topK.map(({ message, similarity, chunkTextSource }) => {
6892
- const stored = { ...storedById.get(message.id) };
6895
+ const stored2 = { ...storedById.get(message.id) };
6893
6896
  let chunkText2;
6894
6897
  if (chunkTextSource.kind === "chunk") {
6895
- chunkText2 = resolveChunkText(stored.content, chunkTextSource.chunk, chunkTextSource.siblings);
6898
+ chunkText2 = resolveChunkText(stored2.content, chunkTextSource.chunk, chunkTextSource.siblings);
6896
6899
  } else if (chunkTextSource.kind === "chunk-cached") {
6897
6900
  const state = chunkStateByMsgId.get(message.id);
6898
6901
  const chunk = state && state.version === chunkTextSource.version ? state.chunks[chunkTextSource.chunkIndex] : void 0;
6899
- chunkText2 = resolveChunkText(stored.content, chunk, state?.chunks);
6902
+ chunkText2 = resolveChunkText(stored2.content, chunk, state?.chunks);
6900
6903
  } else {
6901
- chunkText2 = stored.content;
6904
+ chunkText2 = stored2.content;
6902
6905
  }
6903
- return { chunkText: chunkText2, message: stored, similarity };
6906
+ return { chunkText: chunkText2, message: stored2, similarity };
6904
6907
  });
6905
6908
  }
6906
6909
  async function getAllFilesOp(ctx, options) {
@@ -7250,7 +7253,7 @@ async function embedOne(text12, options, outer) {
7250
7253
  }
7251
7254
  var DEFAULT_EMBEDDING_BATCH_SIZE = 100;
7252
7255
  var DEFAULT_EMBEDDING_BATCH_CONCURRENCY = 3;
7253
- async function generateEmbeddingsBatch(texts, headers, baseUrl, model, onUsage, maskInput, timeoutMs) {
7256
+ async function generateEmbeddingsBatch(texts, headers, baseUrl, model, onUsage, maskInput, timeoutMs, outer) {
7254
7257
  const response = await withEmbeddingRetry(
7255
7258
  () => withDeadline(
7256
7259
  (signal) => postApiV1Embeddings({
@@ -7260,8 +7263,10 @@ async function generateEmbeddingsBatch(texts, headers, baseUrl, model, onUsage,
7260
7263
  ...signal && { signal }
7261
7264
  }),
7262
7265
  timeoutMs,
7263
- "embedding batch request"
7264
- )
7266
+ "embedding batch request",
7267
+ outer
7268
+ ),
7269
+ outer
7265
7270
  );
7266
7271
  if (response.error) {
7267
7272
  throw embeddingErrorFrom(response);
@@ -7279,6 +7284,11 @@ async function generateEmbeddingsBatch(texts, headers, baseUrl, model, onUsage,
7279
7284
  }
7280
7285
  async function generateEmbeddings(texts, options) {
7281
7286
  if (texts.length === 0) return [];
7287
+ const total = options.totalTimeoutMs;
7288
+ if (total === void 0) return embedMany(texts, options, void 0);
7289
+ return withDeadline((signal) => embedMany(texts, options, signal), total, "embedding batch");
7290
+ }
7291
+ async function embedMany(texts, options, outer) {
7282
7292
  const { baseUrl = BASE_URL, model, batchSize, cache } = options;
7283
7293
  const timeoutMs = options.timeoutMs ?? DEFAULT_EMBEDDING_REQUEST_TIMEOUT_MS;
7284
7294
  const chunkSize = batchSize ?? DEFAULT_EMBEDDING_BATCH_SIZE;
@@ -7299,7 +7309,8 @@ async function generateEmbeddings(texts, options) {
7299
7309
  if (uncachedTexts.length === 0) {
7300
7310
  return results;
7301
7311
  }
7302
- const headers = await resolveAuthHeaders(options);
7312
+ const headers = await resolveAuthHeaders(options, outer);
7313
+ if (outer?.aborted) throw outer.reason;
7303
7314
  const embeddingModel = model ?? DEFAULT_API_EMBEDDING_MODEL;
7304
7315
  let newEmbeddings;
7305
7316
  if (uncachedTexts.length <= chunkSize) {
@@ -7310,7 +7321,8 @@ async function generateEmbeddings(texts, options) {
7310
7321
  embeddingModel,
7311
7322
  options.onUsage,
7312
7323
  options.maskInput,
7313
- timeoutMs
7324
+ timeoutMs,
7325
+ outer
7314
7326
  );
7315
7327
  } else {
7316
7328
  const chunks = [];
@@ -7321,6 +7333,7 @@ async function generateEmbeddings(texts, options) {
7321
7333
  let nextIndex = 0;
7322
7334
  const worker = async () => {
7323
7335
  while (nextIndex < chunks.length) {
7336
+ if (outer?.aborted) throw outer.reason;
7324
7337
  const idx = nextIndex++;
7325
7338
  allEmbeddings[idx] = await generateEmbeddingsBatch(
7326
7339
  chunks[idx],
@@ -7329,7 +7342,8 @@ async function generateEmbeddings(texts, options) {
7329
7342
  embeddingModel,
7330
7343
  options.onUsage,
7331
7344
  options.maskInput,
7332
- timeoutMs
7345
+ timeoutMs,
7346
+ outer
7333
7347
  );
7334
7348
  }
7335
7349
  };
@@ -7340,6 +7354,7 @@ async function generateEmbeddings(texts, options) {
7340
7354
  await Promise.all(workers);
7341
7355
  newEmbeddings = allEmbeddings.flat();
7342
7356
  }
7357
+ if (outer?.aborted) throw outer.reason;
7343
7358
  for (let i = 0; i < uncachedIndices.length; i++) {
7344
7359
  const f32Embedding = Float32Array.from(newEmbeddings[i]);
7345
7360
  results[uncachedIndices[i]] = Array.from(f32Embedding);
@@ -12513,15 +12528,15 @@ function createSummaryContext(database) {
12513
12528
  summariesCollection: database.get("conversation_summaries")
12514
12529
  };
12515
12530
  }
12516
- function modelToStored(record) {
12531
+ function modelToStored(record2) {
12517
12532
  return {
12518
- uniqueId: record.id,
12519
- conversationId: record.conversationId,
12520
- summary: record.summary,
12521
- summarizedUpTo: record.summarizedUpTo,
12522
- tokenCount: record.tokenCount,
12523
- createdAt: record.createdAt,
12524
- updatedAt: record.updatedAt
12533
+ uniqueId: record2.id,
12534
+ conversationId: record2.conversationId,
12535
+ summary: record2.summary,
12536
+ summarizedUpTo: record2.summarizedUpTo,
12537
+ tokenCount: record2.tokenCount,
12538
+ createdAt: record2.createdAt,
12539
+ updatedAt: record2.updatedAt
12525
12540
  };
12526
12541
  }
12527
12542
  async function getConversationSummaryOp(ctx, conversationId) {
@@ -12530,17 +12545,17 @@ async function getConversationSummaryOp(ctx, conversationId) {
12530
12545
  return modelToStored(results[0]);
12531
12546
  }
12532
12547
  async function upsertConversationSummaryOp(ctx, conversationId, summary, summarizedUpTo, tokenCount) {
12533
- let record;
12548
+ let record2;
12534
12549
  await ctx.database.write(async () => {
12535
12550
  const existing = await ctx.summariesCollection.query(import_watermelondb7.Q.where("conversation_id", conversationId)).fetch();
12536
12551
  if (existing.length > 0) {
12537
- record = await existing[0].update((rec) => {
12552
+ record2 = await existing[0].update((rec) => {
12538
12553
  rec.summary = summary;
12539
12554
  rec.summarizedUpTo = summarizedUpTo;
12540
12555
  rec.tokenCount = tokenCount;
12541
12556
  });
12542
12557
  } else {
12543
- record = await ctx.summariesCollection.create((rec) => {
12558
+ record2 = await ctx.summariesCollection.create((rec) => {
12544
12559
  rec.conversationId = conversationId;
12545
12560
  rec.summary = summary;
12546
12561
  rec.summarizedUpTo = summarizedUpTo;
@@ -12548,13 +12563,13 @@ async function upsertConversationSummaryOp(ctx, conversationId, summary, summari
12548
12563
  });
12549
12564
  }
12550
12565
  });
12551
- return modelToStored(record);
12566
+ return modelToStored(record2);
12552
12567
  }
12553
12568
  async function deleteConversationSummaryOp(ctx, conversationId) {
12554
12569
  await ctx.database.write(async () => {
12555
12570
  const existing = await ctx.summariesCollection.query(import_watermelondb7.Q.where("conversation_id", conversationId)).fetch();
12556
- for (const record of existing) {
12557
- await record.destroyPermanently();
12571
+ for (const record2 of existing) {
12572
+ await record2.destroyPermanently();
12558
12573
  }
12559
12574
  });
12560
12575
  }
@@ -12747,25 +12762,25 @@ async function upsertEntitiesInWrite(ctx, entities) {
12747
12762
  const kindBackfills = existing.filter((e) => {
12748
12763
  const incoming = kindByName.get(e.canonicalName);
12749
12764
  return incoming !== void 0 && (e.kind === null || e.kind === void 0 || e.kind === "");
12750
- }).map((record) => ({ record, kind: kindByName.get(record.canonicalName) }));
12765
+ }).map((record2) => ({ record: record2, kind: kindByName.get(record2.canonicalName) }));
12751
12766
  const missing = unique.filter((n) => !existingNames.has(n));
12752
12767
  const created = missing.map(
12753
- (name) => ctx.entityCollection.prepareCreate((record) => {
12754
- record._setRaw("canonical_name", name);
12768
+ (name) => ctx.entityCollection.prepareCreate((record2) => {
12769
+ record2._setRaw("canonical_name", name);
12755
12770
  const kind = kindByName.get(name);
12756
- if (kind !== void 0) record._setRaw("kind", kind);
12771
+ if (kind !== void 0) record2._setRaw("kind", kind);
12757
12772
  })
12758
12773
  );
12759
12774
  for (const e of existing) out.set(e.canonicalName, entityToStored(e));
12760
- for (const record of created) out.set(record.canonicalName, entityToStored(record));
12761
- for (const { record, kind } of kindBackfills) {
12762
- out.set(record.canonicalName, { ...entityToStored(record), kind });
12775
+ for (const record2 of created) out.set(record2.canonicalName, entityToStored(record2));
12776
+ for (const { record: record2, kind } of kindBackfills) {
12777
+ out.set(record2.canonicalName, { ...entityToStored(record2), kind });
12763
12778
  }
12764
12779
  return { entities: out, operations: created, kindBackfills };
12765
12780
  }
12766
12781
  function prepareKindBackfills(backfills) {
12767
12782
  return backfills.map(
12768
- ({ record, kind }) => record.prepareUpdate((r) => {
12783
+ ({ record: record2, kind }) => record2.prepareUpdate((r) => {
12769
12784
  r._setRaw("kind", kind);
12770
12785
  })
12771
12786
  );
@@ -12796,10 +12811,10 @@ function displayNamesOf(entities) {
12796
12811
  }
12797
12812
  return out;
12798
12813
  }
12799
- function topicsEqual(stored, computed) {
12800
- if (stored === null || stored.length !== computed.length) return false;
12814
+ function topicsEqual(stored2, computed) {
12815
+ if (stored2 === null || stored2.length !== computed.length) return false;
12801
12816
  const key = (t) => JSON.stringify([t.name, t.kind ?? null, t.source]);
12802
- const storedKeys = stored.map(key).sort();
12817
+ const storedKeys = stored2.map(key).sort();
12803
12818
  const computedKeys = computed.map(key).sort();
12804
12819
  return storedKeys.every((k, i) => k === computedKeys[i]);
12805
12820
  }
@@ -12865,10 +12880,10 @@ async function linkMemoryEntitiesOp(ctx, memoryId, entityInputs, options) {
12865
12880
  return;
12866
12881
  }
12867
12882
  const linkOps = toCreate.map(
12868
- (e) => ctx.memoryEntityCollection.prepareCreate((record) => {
12869
- record._setRaw("memory_id", memoryId);
12870
- record._setRaw("entity_id", e.uniqueId);
12871
- if (userId !== void 0) record._setRaw("user_id", userId);
12883
+ (e) => ctx.memoryEntityCollection.prepareCreate((record2) => {
12884
+ record2._setRaw("memory_id", memoryId);
12885
+ record2._setRaw("entity_id", e.uniqueId);
12886
+ if (userId !== void 0) record2._setRaw("user_id", userId);
12872
12887
  })
12873
12888
  );
12874
12889
  await ctx.database.batch(
@@ -12936,10 +12951,10 @@ async function replaceMemoryEntities(ctx, memoryId, entityInputs, options) {
12936
12951
  ...entityOps,
12937
12952
  ...prepareKindBackfills(kindBackfills),
12938
12953
  ...toCreate.map(
12939
- (e) => ctx.memoryEntityCollection.prepareCreate((record) => {
12940
- record._setRaw("memory_id", memoryId);
12941
- record._setRaw("entity_id", e.uniqueId);
12942
- if (userId !== void 0) record._setRaw("user_id", userId);
12954
+ (e) => ctx.memoryEntityCollection.prepareCreate((record2) => {
12955
+ record2._setRaw("memory_id", memoryId);
12956
+ record2._setRaw("entity_id", e.uniqueId);
12957
+ if (userId !== void 0) record2._setRaw("user_id", userId);
12943
12958
  })
12944
12959
  ),
12945
12960
  ...toDestroy.map((l) => l.prepareDestroyPermanently()),
@@ -15009,13 +15024,13 @@ async function relinkMisclassifiedVideosOp(ctx, walletAddress) {
15009
15024
  toRelink.push({ media, ext: mime.split("/")[1] || "mp4" });
15010
15025
  continue;
15011
15026
  }
15012
- const stored = await mediaToStored(
15027
+ const stored2 = await mediaToStored(
15013
15028
  media,
15014
15029
  ctx.walletAddress,
15015
15030
  ctx.signMessage,
15016
15031
  ctx.embeddedWalletSigner
15017
15032
  );
15018
- const ext = videoExtensionOf(stored.sourceUrl) ?? videoExtensionOf(stored.name);
15033
+ const ext = videoExtensionOf(stored2.sourceUrl) ?? videoExtensionOf(stored2.name);
15019
15034
  if (ext) {
15020
15035
  toRelink.push({ media, ext });
15021
15036
  }
@@ -15313,8 +15328,8 @@ function visibilityConditions(requested) {
15313
15328
  if (excluded.length === 0) return [];
15314
15329
  return [import_watermelondb23.Q.or(import_watermelondb23.Q.where("visibility", null), import_watermelondb23.Q.where("visibility", import_watermelondb23.Q.notIn(excluded)))];
15315
15330
  }
15316
- function isOwnedByCtxUser(ctx, record) {
15317
- return ctx.userId === void 0 || record.userId === ctx.userId;
15331
+ function isOwnedByCtxUser(ctx, record2) {
15332
+ return ctx.userId === void 0 || record2.userId === ctx.userId;
15318
15333
  }
15319
15334
  function baseVaultConditions(ctx, options) {
15320
15335
  return [
@@ -15394,39 +15409,39 @@ async function vaultMemoryToStored(memory, walletAddress, signMessage, embeddedW
15394
15409
  }
15395
15410
  return raw;
15396
15411
  }
15397
- function populateNewVaultMemory(record, ctx, opts, encryptedContent) {
15398
- record._setRaw("content", encryptedContent);
15399
- record._setRaw("scope", opts.scope ?? "private");
15400
- record._setRaw("folder_id", opts.folderId ?? null);
15401
- record._setRaw("user_id", ctx.userId ?? null);
15402
- record._setRaw("is_deleted", false);
15412
+ function populateNewVaultMemory(record2, ctx, opts, encryptedContent) {
15413
+ record2._setRaw("content", encryptedContent);
15414
+ record2._setRaw("scope", opts.scope ?? "private");
15415
+ record2._setRaw("folder_id", opts.folderId ?? null);
15416
+ record2._setRaw("user_id", ctx.userId ?? null);
15417
+ record2._setRaw("is_deleted", false);
15403
15418
  if (opts.embedding !== void 0) {
15404
- record._setRaw("embedding", opts.embedding);
15405
- record._setRaw("embedding_model", opts.embeddingModel ?? null);
15419
+ record2._setRaw("embedding", opts.embedding);
15420
+ record2._setRaw("embedding_model", opts.embeddingModel ?? null);
15406
15421
  }
15407
15422
  if (opts.sourceChunkIds !== void 0) {
15408
- record._setRaw("source_chunk_ids", JSON.stringify(opts.sourceChunkIds));
15423
+ record2._setRaw("source_chunk_ids", JSON.stringify(opts.sourceChunkIds));
15409
15424
  }
15410
- record._setRaw("proof_count", opts.proofCount ?? 1);
15411
- record._setRaw("source", opts.source ?? "manual");
15425
+ record2._setRaw("proof_count", opts.proofCount ?? 1);
15426
+ record2._setRaw("source", opts.source ?? "manual");
15412
15427
  if (opts.eventTime) {
15413
- record._setRaw("event_time_start", opts.eventTime.start ?? null);
15414
- record._setRaw("event_time_end", opts.eventTime.end ?? null);
15415
- record._setRaw("event_time_kind", opts.eventTime.kind ?? null);
15428
+ record2._setRaw("event_time_start", opts.eventTime.start ?? null);
15429
+ record2._setRaw("event_time_end", opts.eventTime.end ?? null);
15430
+ record2._setRaw("event_time_kind", opts.eventTime.kind ?? null);
15416
15431
  }
15417
15432
  if (opts.factType !== void 0) {
15418
- record._setRaw("fact_type", opts.factType);
15433
+ record2._setRaw("fact_type", opts.factType);
15419
15434
  }
15420
15435
  if (opts.trustTier !== void 0) {
15421
- record._setRaw("trust_tier", normalizeTrustTier(opts.trustTier));
15436
+ record2._setRaw("trust_tier", normalizeTrustTier(opts.trustTier));
15422
15437
  }
15423
- record._setRaw("visibility", opts.visibility ?? "private");
15424
- record._setRaw(
15438
+ record2._setRaw("visibility", opts.visibility ?? "private");
15439
+ record2._setRaw(
15425
15440
  "published_at",
15426
15441
  opts.visibility && opts.visibility !== "private" ? opts.publishedAt ?? Date.now() : null
15427
15442
  );
15428
15443
  if (opts.geohash !== void 0) {
15429
- record._setRaw("geohash", opts.geohash);
15444
+ record2._setRaw("geohash", opts.geohash);
15430
15445
  }
15431
15446
  }
15432
15447
  async function createVaultMemoryOp(ctx, opts) {
@@ -15440,7 +15455,7 @@ async function createVaultMemoryOp(ctx, opts) {
15440
15455
  if (ctx.canWrite && !await ctx.canWrite())
15441
15456
  throw new Error("Memory source is no longer eligible");
15442
15457
  return ctx.vaultMemoryCollection.create(
15443
- (record) => populateNewVaultMemory(record, ctx, opts, encryptedContent)
15458
+ (record2) => populateNewVaultMemory(record2, ctx, opts, encryptedContent)
15444
15459
  );
15445
15460
  });
15446
15461
  return vaultMemoryToStored(created, ctx.walletAddress, ctx.signMessage, ctx.embeddedWalletSigner);
@@ -15465,7 +15480,7 @@ async function createSupersedingMemoryOp(ctx, opts, targetId) {
15465
15480
  }
15466
15481
  if (target.isDeleted || target.supersededBy || !isOwnedByCtxUser(ctx, target)) return;
15467
15482
  createdRecord = await ctx.vaultMemoryCollection.create(
15468
- (record) => populateNewVaultMemory(record, ctx, opts, encryptedContent)
15483
+ (record2) => populateNewVaultMemory(record2, ctx, opts, encryptedContent)
15469
15484
  );
15470
15485
  await target.update((r) => {
15471
15486
  r._setRaw("superseded_by", createdRecord.id);
@@ -15547,7 +15562,7 @@ async function createVaultMemoriesBatchOp(ctx, optionsArray) {
15547
15562
  throw new Error("Memory source is no longer eligible");
15548
15563
  const prepared = optionsArray.map(
15549
15564
  (opts, i) => ctx.vaultMemoryCollection.prepareCreate(
15550
- (record) => populateNewVaultMemory(record, ctx, opts, encryptedContents[i])
15565
+ (record2) => populateNewVaultMemory(record2, ctx, opts, encryptedContents[i])
15551
15566
  )
15552
15567
  );
15553
15568
  await ctx.database.batch(...prepared);
@@ -15555,16 +15570,16 @@ async function createVaultMemoriesBatchOp(ctx, optionsArray) {
15555
15570
  });
15556
15571
  return Promise.all(
15557
15572
  created.map(
15558
- (record) => vaultMemoryToStored(record, ctx.walletAddress, ctx.signMessage, ctx.embeddedWalletSigner)
15573
+ (record2) => vaultMemoryToStored(record2, ctx.walletAddress, ctx.signMessage, ctx.embeddedWalletSigner)
15559
15574
  )
15560
15575
  );
15561
15576
  }
15562
15577
  async function getVaultMemoryOp(ctx, id) {
15563
15578
  try {
15564
- const record = await ctx.vaultMemoryCollection.find(id);
15565
- if (record.isDeleted || !isOwnedByCtxUser(ctx, record)) return null;
15579
+ const record2 = await ctx.vaultMemoryCollection.find(id);
15580
+ if (record2.isDeleted || !isOwnedByCtxUser(ctx, record2)) return null;
15566
15581
  return vaultMemoryToStored(
15567
- record,
15582
+ record2,
15568
15583
  ctx.walletAddress,
15569
15584
  ctx.signMessage,
15570
15585
  ctx.embeddedWalletSigner
@@ -15622,11 +15637,11 @@ function vaultMemoryRawToStoredRaw(raw) {
15622
15637
  };
15623
15638
  }
15624
15639
  async function vaultMemoryRawToStored(raw, walletAddress, signMessage, embeddedWalletSigner) {
15625
- const stored = vaultMemoryRawToStoredRaw(raw);
15640
+ const stored2 = vaultMemoryRawToStoredRaw(raw);
15626
15641
  if (walletAddress) {
15627
- return decryptVaultMemoryFields(stored, walletAddress, signMessage, embeddedWalletSigner);
15642
+ return decryptVaultMemoryFields(stored2, walletAddress, signMessage, embeddedWalletSigner);
15628
15643
  }
15629
- return stored;
15644
+ return stored2;
15630
15645
  }
15631
15646
  async function getAllVaultMemoriesOp(ctx, options) {
15632
15647
  const conditions = [
@@ -15778,13 +15793,13 @@ async function getVaultMemoriesByIdsOp(ctx, ids, options) {
15778
15793
  async function getAllVaultMemoryContentsOp(ctx, options) {
15779
15794
  const results = await ctx.vaultMemoryCollection.query(...baseVaultConditions(ctx, options)).unsafeFetchRaw();
15780
15795
  return mapInBatches(results, async (raw) => {
15781
- const stored = await vaultMemoryRawToStored(
15796
+ const stored2 = await vaultMemoryRawToStored(
15782
15797
  raw,
15783
15798
  ctx.walletAddress,
15784
15799
  ctx.signMessage,
15785
15800
  ctx.embeddedWalletSigner
15786
15801
  );
15787
- return stored.content;
15802
+ return stored2.content;
15788
15803
  });
15789
15804
  }
15790
15805
  async function countActiveVaultMemoriesOp(ctx) {
@@ -15806,12 +15821,12 @@ async function updateVaultMemoryOp(ctx, id, opts) {
15806
15821
  ctx.embeddedWalletSigner
15807
15822
  ) : opts.content;
15808
15823
  let stale = false;
15809
- const record = probe;
15810
- const originalUpdatedAt = record.updatedAt.getTime();
15824
+ const record2 = probe;
15825
+ const originalUpdatedAt = record2.updatedAt.getTime();
15811
15826
  await ctx.database.write(async () => {
15812
15827
  if (ctx.canWrite && !await ctx.canWrite())
15813
15828
  throw new Error("Memory source is no longer eligible");
15814
- if (record.isDeleted || record.supersededBy || !isOwnedByCtxUser(ctx, record)) {
15829
+ if (record2.isDeleted || record2.supersededBy || !isOwnedByCtxUser(ctx, record2)) {
15815
15830
  stale = true;
15816
15831
  return;
15817
15832
  }
@@ -15819,14 +15834,14 @@ async function updateVaultMemoryOp(ctx, id, opts) {
15819
15834
  let replayedObservation = false;
15820
15835
  if (opts.observationSourceIds?.length) {
15821
15836
  try {
15822
- const parsed = JSON.parse(record.sourceChunkIds ?? "[]");
15837
+ const parsed = JSON.parse(record2.sourceChunkIds ?? "[]");
15823
15838
  if (Array.isArray(parsed))
15824
15839
  observedSources = parsed.filter((id2) => typeof id2 === "string");
15825
15840
  } catch {
15826
15841
  }
15827
15842
  replayedObservation = opts.observationSourceIds.every((id2) => observedSources.includes(id2));
15828
15843
  }
15829
- await record.update((r) => {
15844
+ await record2.update((r) => {
15830
15845
  r._setRaw("content", encryptedContent);
15831
15846
  if (opts.scope !== void 0) {
15832
15847
  r._setRaw("scope", opts.scope);
@@ -15883,7 +15898,7 @@ async function updateVaultMemoryOp(ctx, id, opts) {
15883
15898
  });
15884
15899
  if (stale) return null;
15885
15900
  return vaultMemoryToStored(
15886
- record,
15901
+ record2,
15887
15902
  ctx.walletAddress,
15888
15903
  ctx.signMessage,
15889
15904
  ctx.embeddedWalletSigner
@@ -15897,21 +15912,21 @@ async function setMemoryEntitiesOp(ctx, memoryId, entities) {
15897
15912
  if (!entityCtx) {
15898
15913
  throw new Error("setMemoryEntitiesOp requires ctx.entityCtx (entity collections)");
15899
15914
  }
15900
- let record;
15915
+ let record2;
15901
15916
  try {
15902
- record = await ctx.vaultMemoryCollection.find(memoryId);
15917
+ record2 = await ctx.vaultMemoryCollection.find(memoryId);
15903
15918
  } catch {
15904
15919
  return null;
15905
15920
  }
15906
- if (record.isDeleted || !isOwnedByCtxUser(ctx, record)) return null;
15921
+ if (record2.isDeleted || !isOwnedByCtxUser(ctx, record2)) return null;
15907
15922
  let stale = false;
15908
- const originalUpdatedAt = record.updatedAt.getTime();
15923
+ const originalUpdatedAt = record2.updatedAt.getTime();
15909
15924
  await ctx.database.write(async (writer) => {
15910
- if (record.isDeleted || !isOwnedByCtxUser(ctx, record)) {
15925
+ if (record2.isDeleted || !isOwnedByCtxUser(ctx, record2)) {
15911
15926
  stale = true;
15912
15927
  return;
15913
15928
  }
15914
- await record.update((r) => {
15929
+ await record2.update((r) => {
15915
15930
  r._setRaw("topics_user_managed", true);
15916
15931
  r._setRaw("updated_at", originalUpdatedAt);
15917
15932
  });
@@ -15935,25 +15950,25 @@ async function setMemoryEntitiesOp(ctx, memoryId, entities) {
15935
15950
  );
15936
15951
  });
15937
15952
  if (stale) return null;
15938
- return vaultMemoryToStored(record, ctx.walletAddress, ctx.signMessage, ctx.embeddedWalletSigner);
15953
+ return vaultMemoryToStored(record2, ctx.walletAddress, ctx.signMessage, ctx.embeddedWalletSigner);
15939
15954
  }
15940
15955
  async function clearMemoryTopicsOverrideOp(ctx, memoryId, options) {
15941
- let record;
15956
+ let record2;
15942
15957
  try {
15943
- record = await ctx.vaultMemoryCollection.find(memoryId);
15958
+ record2 = await ctx.vaultMemoryCollection.find(memoryId);
15944
15959
  } catch {
15945
15960
  return false;
15946
15961
  }
15947
- if (record.isDeleted || !isOwnedByCtxUser(ctx, record)) return false;
15948
- const originalUpdatedAt = record.updatedAt.getTime();
15962
+ if (record2.isDeleted || !isOwnedByCtxUser(ctx, record2)) return false;
15963
+ const originalUpdatedAt = record2.updatedAt.getTime();
15949
15964
  let cleared = false;
15950
15965
  await ctx.database.write(async () => {
15951
- if (options?.unlessTopicsRecorded && parseTopics(record.topics) !== null) return;
15966
+ if (options?.unlessTopicsRecorded && parseTopics(record2.topics) !== null) return;
15952
15967
  cleared = true;
15953
- await record.update((r) => {
15968
+ await record2.update((r) => {
15954
15969
  r._setRaw("topics_user_managed", false);
15955
15970
  r._setRaw("topics_extracted_version", null);
15956
- if (record.topicsExtractedAt === null) {
15971
+ if (record2.topicsExtractedAt === null) {
15957
15972
  r._setRaw("topics_extracted_at", originalUpdatedAt);
15958
15973
  }
15959
15974
  r._setRaw("updated_at", originalUpdatedAt);
@@ -15962,22 +15977,22 @@ async function clearMemoryTopicsOverrideOp(ctx, memoryId, options) {
15962
15977
  return cleared;
15963
15978
  }
15964
15979
  async function setMemoryVisibilityOp(ctx, id, opts) {
15965
- let record;
15980
+ let record2;
15966
15981
  try {
15967
- record = await ctx.vaultMemoryCollection.find(id);
15982
+ record2 = await ctx.vaultMemoryCollection.find(id);
15968
15983
  } catch {
15969
15984
  return null;
15970
15985
  }
15971
- if (record.isDeleted || !isOwnedByCtxUser(ctx, record)) return null;
15986
+ if (record2.isDeleted || !isOwnedByCtxUser(ctx, record2)) return null;
15972
15987
  let stale = false;
15973
15988
  await ctx.database.write(async () => {
15974
- if (record.isDeleted || !isOwnedByCtxUser(ctx, record)) {
15989
+ if (record2.isDeleted || !isOwnedByCtxUser(ctx, record2)) {
15975
15990
  stale = true;
15976
15991
  return;
15977
15992
  }
15978
- const currentUpdatedAt = record.updatedAt.getTime();
15979
- const currentPublishedAt = record.publishedAt ?? null;
15980
- await record.update((r) => {
15993
+ const currentUpdatedAt = record2.updatedAt.getTime();
15994
+ const currentPublishedAt = record2.publishedAt ?? null;
15995
+ await record2.update((r) => {
15981
15996
  r._setRaw("visibility", opts.visibility);
15982
15997
  if (opts.visibility === "private") {
15983
15998
  r._setRaw("published_at", null);
@@ -15991,19 +16006,19 @@ async function setMemoryVisibilityOp(ctx, id, opts) {
15991
16006
  });
15992
16007
  });
15993
16008
  if (stale) return null;
15994
- return vaultMemoryToStored(record, ctx.walletAddress, ctx.signMessage, ctx.embeddedWalletSigner);
16009
+ return vaultMemoryToStored(record2, ctx.walletAddress, ctx.signMessage, ctx.embeddedWalletSigner);
15995
16010
  }
15996
16011
  async function deleteVaultMemoryOp(ctx, id) {
15997
16012
  try {
15998
- const record = await ctx.vaultMemoryCollection.find(id);
15999
- if (record.isDeleted || !isOwnedByCtxUser(ctx, record)) return false;
16013
+ const record2 = await ctx.vaultMemoryCollection.find(id);
16014
+ if (record2.isDeleted || !isOwnedByCtxUser(ctx, record2)) return false;
16000
16015
  let stale = false;
16001
16016
  await ctx.database.write(async () => {
16002
- if (record.isDeleted || !isOwnedByCtxUser(ctx, record)) {
16017
+ if (record2.isDeleted || !isOwnedByCtxUser(ctx, record2)) {
16003
16018
  stale = true;
16004
16019
  return;
16005
16020
  }
16006
- await record.update((r) => {
16021
+ await record2.update((r) => {
16007
16022
  r._setRaw("is_deleted", true);
16008
16023
  });
16009
16024
  });
@@ -16022,8 +16037,8 @@ async function deleteVaultMemoryOp(ctx, id) {
16022
16037
  async function supersedeVaultMemoryOp(ctx, id, supersededById) {
16023
16038
  if (id === supersededById) return false;
16024
16039
  try {
16025
- const record = await ctx.vaultMemoryCollection.find(id);
16026
- if (record.isDeleted || record.supersededBy || !isOwnedByCtxUser(ctx, record)) return false;
16040
+ const record2 = await ctx.vaultMemoryCollection.find(id);
16041
+ if (record2.isDeleted || record2.supersededBy || !isOwnedByCtxUser(ctx, record2)) return false;
16027
16042
  let successor;
16028
16043
  try {
16029
16044
  successor = await ctx.vaultMemoryCollection.find(supersededById);
@@ -16037,7 +16052,7 @@ async function supersedeVaultMemoryOp(ctx, id, supersededById) {
16037
16052
  await ctx.database.write(async () => {
16038
16053
  if (ctx.canWrite && !await ctx.canWrite())
16039
16054
  throw new Error("Memory source is no longer eligible");
16040
- if (record.isDeleted || record.supersededBy || !isOwnedByCtxUser(ctx, record)) {
16055
+ if (record2.isDeleted || record2.supersededBy || !isOwnedByCtxUser(ctx, record2)) {
16041
16056
  stale = true;
16042
16057
  return;
16043
16058
  }
@@ -16045,7 +16060,7 @@ async function supersedeVaultMemoryOp(ctx, id, supersededById) {
16045
16060
  stale = true;
16046
16061
  return;
16047
16062
  }
16048
- await record.update((r) => {
16063
+ await record2.update((r) => {
16049
16064
  r._setRaw("superseded_by", supersededById);
16050
16065
  r._setRaw("superseded_at", Date.now());
16051
16066
  });
@@ -16064,7 +16079,7 @@ async function getUnfiledVaultMemoriesOp(ctx) {
16064
16079
  const results = await ctx.vaultMemoryCollection.query(...conditions).fetch();
16065
16080
  return mapInBatches(
16066
16081
  results,
16067
- (record) => vaultMemoryToStored(record, ctx.walletAddress, ctx.signMessage, ctx.embeddedWalletSigner)
16082
+ (record2) => vaultMemoryToStored(record2, ctx.walletAddress, ctx.signMessage, ctx.embeddedWalletSigner)
16068
16083
  );
16069
16084
  }
16070
16085
  var TOPICS_EXTRACTION_VERSION = 3;
@@ -16206,17 +16221,17 @@ async function stampTopicsExtractedAtOp(ctx, memoryIds, extractedAt, version = T
16206
16221
  }
16207
16222
  }
16208
16223
  const eligible = records.filter(
16209
- (record) => !record.isDeleted && isOwnedByCtxUser(ctx, record) && !record.topicsUserManaged
16224
+ (record2) => !record2.isDeleted && isOwnedByCtxUser(ctx, record2) && !record2.topicsUserManaged
16210
16225
  );
16211
- const prepared = eligible.map((record) => {
16212
- const originalUpdatedAt = record.updatedAt.getTime();
16213
- return record.prepareUpdate((r) => {
16226
+ const prepared = eligible.map((record2) => {
16227
+ const originalUpdatedAt = record2.updatedAt.getTime();
16228
+ return record2.prepareUpdate((r) => {
16214
16229
  r._setRaw("topics_extracted_at", extractedAt);
16215
16230
  r._setRaw("topics_extracted_version", version);
16216
16231
  r._setRaw("updated_at", originalUpdatedAt);
16217
16232
  });
16218
16233
  });
16219
- for (const record of eligible) stamped.push(record.id);
16234
+ for (const record2 of eligible) stamped.push(record2.id);
16220
16235
  if (prepared.length > 0) await ctx.database.batch(...prepared);
16221
16236
  });
16222
16237
  }
@@ -16231,14 +16246,14 @@ async function relinkMemoryTopicsOp(ctx, memoryIds) {
16231
16246
  for (const id of Array.from(new Set(memoryIds))) {
16232
16247
  try {
16233
16248
  await ctx.database.write(async (writer) => {
16234
- let record;
16249
+ let record2;
16235
16250
  try {
16236
- record = await ctx.vaultMemoryCollection.find(id);
16251
+ record2 = await ctx.vaultMemoryCollection.find(id);
16237
16252
  } catch {
16238
16253
  return;
16239
16254
  }
16240
- if (record.isDeleted || !isOwnedByCtxUser(ctx, record)) return;
16241
- const topics = parseTopics(record.topics);
16255
+ if (record2.isDeleted || !isOwnedByCtxUser(ctx, record2)) return;
16256
+ const topics = parseTopics(record2.topics);
16242
16257
  if (topics === null) return;
16243
16258
  await writer.callWriter(() => relinkMemoryEntitiesFromTopicsOp(entityCtx, id, topics));
16244
16259
  relinked.push(id);
@@ -16263,20 +16278,20 @@ async function backfillMemoryTopicsOp(ctx, memoryIds) {
16263
16278
  await ctx.database.write(async () => {
16264
16279
  const writes = [];
16265
16280
  for (const id of chunkIds) {
16266
- let record;
16281
+ let record2;
16267
16282
  try {
16268
- record = await ctx.vaultMemoryCollection.find(id);
16283
+ record2 = await ctx.vaultMemoryCollection.find(id);
16269
16284
  } catch {
16270
16285
  continue;
16271
16286
  }
16272
- if (record.isDeleted || !isOwnedByCtxUser(ctx, record)) continue;
16273
- if (parseTopics(record.topics) !== null) continue;
16287
+ if (record2.isDeleted || !isOwnedByCtxUser(ctx, record2)) continue;
16288
+ if (parseTopics(record2.topics) !== null) continue;
16274
16289
  const links = await entityCtx.memoryEntityCollection.query(import_watermelondb23.Q.where("memory_id", id)).unsafeFetchRaw();
16275
16290
  const entityIds = links.map((l) => String(l.entity_id));
16276
16291
  if (entityIds.length === 0) continue;
16277
16292
  const entities = await entityCtx.entityCollection.query(import_watermelondb23.Q.where("id", import_watermelondb23.Q.oneOf(entityIds))).fetch();
16278
16293
  if (entities.length === 0) continue;
16279
- const source = record.topicsUserManaged ? "user" : "auto";
16294
+ const source = record2.topicsUserManaged ? "user" : "auto";
16280
16295
  const write = await resolveMemoryTopicsWrite(entityCtx, id, entities, [], source);
16281
16296
  if (write) writes.push(write);
16282
16297
  }
@@ -16294,7 +16309,7 @@ async function deleteAllVaultMemoriesForUserOp(ctx, userId) {
16294
16309
  if (records.length === 0) return 0;
16295
16310
  await ctx.database.write(async () => {
16296
16311
  const prepared = records.map(
16297
- (record) => record.prepareUpdate((r) => {
16312
+ (record2) => record2.prepareUpdate((r) => {
16298
16313
  r._setRaw("is_deleted", true);
16299
16314
  })
16300
16315
  );
@@ -16339,20 +16354,20 @@ async function getDecayCandidatesRawOp(ctx) {
16339
16354
  }
16340
16355
  async function archiveVaultMemoryOp(ctx, id, opts) {
16341
16356
  try {
16342
- const record = await ctx.vaultMemoryCollection.find(id);
16343
- if (record.isDeleted || !isOwnedByCtxUser(ctx, record)) return false;
16357
+ const record2 = await ctx.vaultMemoryCollection.find(id);
16358
+ if (record2.isDeleted || !isOwnedByCtxUser(ctx, record2)) return false;
16344
16359
  let stale = false;
16345
16360
  const archivedAtValue = opts?.now ?? Date.now();
16346
16361
  await ctx.database.write(async () => {
16347
- if (record.isDeleted || !isOwnedByCtxUser(ctx, record) || record.archivedAt !== null) {
16362
+ if (record2.isDeleted || !isOwnedByCtxUser(ctx, record2) || record2.archivedAt !== null) {
16348
16363
  stale = true;
16349
16364
  return;
16350
16365
  }
16351
- if (opts?.expectedUpdatedAt !== void 0 && record.updatedAt.getTime() !== opts.expectedUpdatedAt || opts?.expectedLastObservedAt !== void 0 && (record.lastObservedAt ?? null) !== opts.expectedLastObservedAt) {
16366
+ if (opts?.expectedUpdatedAt !== void 0 && record2.updatedAt.getTime() !== opts.expectedUpdatedAt || opts?.expectedLastObservedAt !== void 0 && (record2.lastObservedAt ?? null) !== opts.expectedLastObservedAt) {
16352
16367
  stale = true;
16353
16368
  return;
16354
16369
  }
16355
- await record.update((r) => {
16370
+ await record2.update((r) => {
16356
16371
  r._setRaw("archived_at", archivedAtValue);
16357
16372
  });
16358
16373
  });
@@ -16363,15 +16378,15 @@ async function archiveVaultMemoryOp(ctx, id, opts) {
16363
16378
  }
16364
16379
  async function restoreVaultMemoryOp(ctx, id) {
16365
16380
  try {
16366
- const record = await ctx.vaultMemoryCollection.find(id);
16367
- if (record.isDeleted || !isOwnedByCtxUser(ctx, record)) return false;
16381
+ const record2 = await ctx.vaultMemoryCollection.find(id);
16382
+ if (record2.isDeleted || !isOwnedByCtxUser(ctx, record2)) return false;
16368
16383
  let stale = false;
16369
16384
  await ctx.database.write(async () => {
16370
- if (record.isDeleted || !isOwnedByCtxUser(ctx, record)) {
16385
+ if (record2.isDeleted || !isOwnedByCtxUser(ctx, record2)) {
16371
16386
  stale = true;
16372
16387
  return;
16373
16388
  }
16374
- await record.update((r) => {
16389
+ await record2.update((r) => {
16375
16390
  r._setRaw("archived_at", null);
16376
16391
  });
16377
16392
  });
@@ -16382,17 +16397,17 @@ async function restoreVaultMemoryOp(ctx, id) {
16382
16397
  }
16383
16398
  async function hardDeleteDecayedOp(ctx, id, opts) {
16384
16399
  try {
16385
- const record = await ctx.vaultMemoryCollection.find(id);
16386
- if (record.isDeleted || !isOwnedByCtxUser(ctx, record)) return false;
16400
+ const record2 = await ctx.vaultMemoryCollection.find(id);
16401
+ if (record2.isDeleted || !isOwnedByCtxUser(ctx, record2)) return false;
16387
16402
  const now = opts.now ?? Date.now();
16388
16403
  let stale = false;
16389
16404
  await ctx.database.write(async () => {
16390
- const archivedAt = record.archivedAt;
16391
- if (record.isDeleted || !isOwnedByCtxUser(ctx, record) || archivedAt === null || now - archivedAt <= opts.hardDeleteWindowMs) {
16405
+ const archivedAt = record2.archivedAt;
16406
+ if (record2.isDeleted || !isOwnedByCtxUser(ctx, record2) || archivedAt === null || now - archivedAt <= opts.hardDeleteWindowMs) {
16392
16407
  stale = true;
16393
16408
  return;
16394
16409
  }
16395
- await record.update((r) => {
16410
+ await record2.update((r) => {
16396
16411
  r._setRaw("is_deleted", true);
16397
16412
  });
16398
16413
  });
@@ -16410,14 +16425,14 @@ async function hardDeleteDecayedOp(ctx, id, opts) {
16410
16425
  }
16411
16426
  async function updateVaultMemoryEmbeddingOp(ctx, id, embedding, embeddingModel, expected) {
16412
16427
  try {
16413
- const record = await ctx.vaultMemoryCollection.find(id);
16414
- if (record.isDeleted || !isOwnedByCtxUser(ctx, record)) return false;
16415
- const readUpdatedAt = record.updatedAt.getTime();
16416
- const readStoredContent = record._getRaw("content");
16428
+ const record2 = await ctx.vaultMemoryCollection.find(id);
16429
+ if (record2.isDeleted || !isOwnedByCtxUser(ctx, record2)) return false;
16430
+ const readUpdatedAt = record2.updatedAt.getTime();
16431
+ const readStoredContent = record2._getRaw("content");
16417
16432
  if (expected?.updatedAt !== void 0 && expected.updatedAt !== readUpdatedAt) return false;
16418
16433
  if (expected?.content !== void 0) {
16419
16434
  const current = await vaultMemoryToStored(
16420
- record,
16435
+ record2,
16421
16436
  ctx.walletAddress,
16422
16437
  ctx.signMessage,
16423
16438
  ctx.embeddedWalletSigner
@@ -16426,11 +16441,11 @@ async function updateVaultMemoryEmbeddingOp(ctx, id, embedding, embeddingModel,
16426
16441
  }
16427
16442
  let written = false;
16428
16443
  await ctx.database.write(async () => {
16429
- if (record.isDeleted || !isOwnedByCtxUser(ctx, record)) return;
16430
- const originalUpdatedAt = record.updatedAt.getTime();
16431
- if (originalUpdatedAt !== readUpdatedAt || record._getRaw("content") !== readStoredContent)
16444
+ if (record2.isDeleted || !isOwnedByCtxUser(ctx, record2)) return;
16445
+ const originalUpdatedAt = record2.updatedAt.getTime();
16446
+ if (originalUpdatedAt !== readUpdatedAt || record2._getRaw("content") !== readStoredContent)
16432
16447
  return;
16433
- await record.update((r) => {
16448
+ await record2.update((r) => {
16434
16449
  r._setRaw("embedding", embedding);
16435
16450
  r._setRaw("embedding_model", embeddingModel);
16436
16451
  r._setRaw("updated_at", originalUpdatedAt);
@@ -16445,8 +16460,8 @@ async function updateVaultMemoryEmbeddingOp(ctx, id, embedding, embeddingModel,
16445
16460
  function normalizeForDedupe(content) {
16446
16461
  return content.normalize("NFKC").trim().replace(/\s+/g, " ").toLowerCase();
16447
16462
  }
16448
- async function findQuarantinedDuplicateOp(ctx, content, sourceIds, where) {
16449
- const wanted = [...new Set(sourceIds)].sort().join("\0");
16463
+ async function findQuarantinedDuplicateOp(ctx, content, sourceIds2, where) {
16464
+ const wanted = [...new Set(sourceIds2)].sort().join("\0");
16450
16465
  const target = normalizeForDedupe(content);
16451
16466
  const rows = await ctx.vaultMemoryCollection.query(
16452
16467
  import_watermelondb23.Q.where("trust_tier", "quarantined"),
@@ -16465,13 +16480,13 @@ async function findQuarantinedDuplicateOp(ctx, content, sourceIds, where) {
16465
16480
  if (!Array.isArray(ids)) continue;
16466
16481
  const key = [...new Set(ids.filter((id) => typeof id === "string"))].sort().join("\0");
16467
16482
  if (key !== wanted) continue;
16468
- const stored = await vaultMemoryRawToStored(
16483
+ const stored2 = await vaultMemoryRawToStored(
16469
16484
  raw,
16470
16485
  ctx.walletAddress,
16471
16486
  ctx.signMessage,
16472
16487
  ctx.embeddedWalletSigner
16473
16488
  );
16474
- if (normalizeForDedupe(stored.content) === target) return stored.uniqueId;
16489
+ if (normalizeForDedupe(stored2.content) === target) return stored2.uniqueId;
16475
16490
  }
16476
16491
  return null;
16477
16492
  }
@@ -16581,25 +16596,25 @@ async function ingestPublishedPhotoMemoriesOp(ctx, rows) {
16581
16596
  inserted = writable.length;
16582
16597
  if (writable.length === 0) return;
16583
16598
  const prepared = writable.map(
16584
- ({ row, content }) => ctx.vaultMemoryCollection.prepareCreate((record) => {
16585
- record._raw.id = row.memoryId;
16586
- record._setRaw("content", content);
16587
- record._setRaw("scope", "shared");
16588
- record._setRaw("folder_id", null);
16589
- record._setRaw("user_id", ctx.userId ?? null);
16590
- record._setRaw("is_deleted", false);
16591
- record._setRaw("proof_count", 1);
16592
- record._setRaw("source", SOURCE_PHOTO);
16593
- record._setRaw(
16599
+ ({ row, content }) => ctx.vaultMemoryCollection.prepareCreate((record2) => {
16600
+ record2._raw.id = row.memoryId;
16601
+ record2._setRaw("content", content);
16602
+ record2._setRaw("scope", "shared");
16603
+ record2._setRaw("folder_id", null);
16604
+ record2._setRaw("user_id", ctx.userId ?? null);
16605
+ record2._setRaw("is_deleted", false);
16606
+ record2._setRaw("proof_count", 1);
16607
+ record2._setRaw("source", SOURCE_PHOTO);
16608
+ record2._setRaw(
16594
16609
  "media",
16595
16610
  row.media && row.media.length > 0 ? JSON.stringify(row.media) : null
16596
16611
  );
16597
- record._setRaw("visibility", "public");
16598
- record._setRaw("published_at", now);
16612
+ record2._setRaw("visibility", "public");
16613
+ record2._setRaw("published_at", now);
16599
16614
  if (row.eventTime) {
16600
- record._setRaw("event_time_start", row.eventTime.start ?? null);
16601
- record._setRaw("event_time_end", row.eventTime.end ?? null);
16602
- record._setRaw("event_time_kind", row.eventTime.kind ?? null);
16615
+ record2._setRaw("event_time_start", row.eventTime.start ?? null);
16616
+ record2._setRaw("event_time_end", row.eventTime.end ?? null);
16617
+ record2._setRaw("event_time_kind", row.eventTime.kind ?? null);
16603
16618
  }
16604
16619
  })
16605
16620
  );
@@ -17421,11 +17436,11 @@ function folderToStored(folder) {
17421
17436
  }
17422
17437
  async function createVaultFolderOp(ctx, opts) {
17423
17438
  const created = await ctx.database.write(async () => {
17424
- return ctx.vaultFolderCollection.create((record) => {
17425
- record._setRaw("name", opts.name);
17426
- record._setRaw("scope", opts.scope ?? "private");
17427
- record._setRaw("is_system", opts.isSystem ?? false);
17428
- record._setRaw("is_deleted", false);
17439
+ return ctx.vaultFolderCollection.create((record2) => {
17440
+ record2._setRaw("name", opts.name);
17441
+ record2._setRaw("scope", opts.scope ?? "private");
17442
+ record2._setRaw("is_system", opts.isSystem ?? false);
17443
+ record2._setRaw("is_deleted", false);
17429
17444
  });
17430
17445
  });
17431
17446
  return folderToStored(created);
@@ -17436,14 +17451,14 @@ async function getAllVaultFoldersOp(ctx) {
17436
17451
  }
17437
17452
  async function updateVaultFolderOp(ctx, id, opts) {
17438
17453
  try {
17439
- const record = await ctx.vaultFolderCollection.find(id);
17440
- if (record.isDeleted) return null;
17441
- const scopeChanged = opts.scope !== void 0 && opts.scope !== record.scope;
17454
+ const record2 = await ctx.vaultFolderCollection.find(id);
17455
+ if (record2.isDeleted) return null;
17456
+ const scopeChanged = opts.scope !== void 0 && opts.scope !== record2.scope;
17442
17457
  const updated = await ctx.database.write(async () => {
17443
17458
  const memories = scopeChanged ? await ctx.vaultMemoryCollection.query(import_watermelondb30.Q.where("folder_id", id), import_watermelondb30.Q.where("is_deleted", false)).fetch() : [];
17444
17459
  const updates = [];
17445
17460
  updates.push(
17446
- record.prepareUpdate((r) => {
17461
+ record2.prepareUpdate((r) => {
17447
17462
  if (opts.name !== void 0) r._setRaw("name", opts.name);
17448
17463
  if (opts.scope !== void 0) r._setRaw("scope", opts.scope);
17449
17464
  })
@@ -17465,8 +17480,8 @@ async function updateVaultFolderOp(ctx, id, opts) {
17465
17480
  }
17466
17481
  async function deleteVaultFolderOp(ctx, id) {
17467
17482
  try {
17468
- const record = await ctx.vaultFolderCollection.find(id);
17469
- if (record.isDeleted) return false;
17483
+ const record2 = await ctx.vaultFolderCollection.find(id);
17484
+ if (record2.isDeleted) return false;
17470
17485
  await ctx.database.write(async () => {
17471
17486
  const memories = await ctx.vaultMemoryCollection.query(import_watermelondb30.Q.where("folder_id", id), import_watermelondb30.Q.where("is_deleted", false)).fetch();
17472
17487
  const preparedMemories = memories.map(
@@ -17475,7 +17490,7 @@ async function deleteVaultFolderOp(ctx, id) {
17475
17490
  r._setRaw("scope", "private");
17476
17491
  })
17477
17492
  );
17478
- const preparedFolder = record.prepareUpdate((r) => {
17493
+ const preparedFolder = record2.prepareUpdate((r) => {
17479
17494
  r._setRaw("is_deleted", true);
17480
17495
  });
17481
17496
  await ctx.database.batch(...preparedMemories, preparedFolder);
@@ -17521,11 +17536,11 @@ async function moveMemoriesToFolderOp(ctx, memoryIds, folderId) {
17521
17536
  }
17522
17537
  async function updateVaultFolderContextOp(ctx, id, context) {
17523
17538
  try {
17524
- const record = await ctx.vaultFolderCollection.find(id);
17525
- if (record.isDeleted) return null;
17539
+ const record2 = await ctx.vaultFolderCollection.find(id);
17540
+ if (record2.isDeleted) return null;
17526
17541
  const updated = await ctx.database.write(async () => {
17527
17542
  await ctx.database.batch(
17528
- record.prepareUpdate((r) => {
17543
+ record2.prepareUpdate((r) => {
17529
17544
  r._setRaw("context", context);
17530
17545
  })
17531
17546
  );
@@ -19606,7 +19621,7 @@ async function rankPreparedVaultCandidates(query, prepared, embeddingOptions, se
19606
19621
  if (useFusion && !embeddingsUnavailable && facetQueries) {
19607
19622
  let subEmbeddings;
19608
19623
  try {
19609
- subEmbeddings = await generateEmbeddings(facetQueries, embeddingOptions);
19624
+ subEmbeddings = prepared.facetEmbeddings ?? await generateEmbeddings(facetQueries, embeddingOptions);
19610
19625
  } catch (err) {
19611
19626
  getLogger().warn(
19612
19627
  "memoryVault: sub-query embedding failed \u2014 falling back to single-query ranking: " + (err instanceof Error ? err.message : String(err))
@@ -19792,6 +19807,35 @@ var DEFAULT_SCOPE = "private";
19792
19807
  var DEFAULT_CONSOLIDATE_THRESHOLD = 0.55;
19793
19808
  var DEFAULT_CONSOLIDATE_TOP_K = 20;
19794
19809
  async function retain(content, ctx, options = {}) {
19810
+ return retainWithPersistence(
19811
+ content,
19812
+ {
19813
+ embeddingOptions: ctx.embeddingOptions,
19814
+ vaultCache: ctx.vaultCache,
19815
+ persistence: {
19816
+ prepare: (query, searchOptions) => prepareVaultCandidates(
19817
+ query,
19818
+ ctx.vaultCtx,
19819
+ ctx.embeddingOptions,
19820
+ ctx.vaultCache,
19821
+ searchOptions
19822
+ ),
19823
+ get: (id) => getVaultMemoryOp(ctx.vaultCtx, id),
19824
+ tombstones: (_embedding, _model, scope, folderId) => getAllVaultMemoriesOp(ctx.vaultCtx, {
19825
+ includeDeleted: true,
19826
+ scopes: [scope],
19827
+ ...folderId !== void 0 && { folderId }
19828
+ }),
19829
+ create: (input) => createVaultMemoryOp(ctx.vaultCtx, input),
19830
+ update: (id, patch) => updateVaultMemoryOp(ctx.vaultCtx, id, patch),
19831
+ supersede: (id, successor) => supersedeVaultMemoryOp(ctx.vaultCtx, id, successor),
19832
+ createSuperseding: (input, target) => createSupersedingMemoryOp(ctx.vaultCtx, input, target)
19833
+ }
19834
+ },
19835
+ options
19836
+ );
19837
+ }
19838
+ async function retainWithPersistence(content, ctx, options = {}) {
19795
19839
  const trimmed = content.trim();
19796
19840
  if (trimmed.length === 0) {
19797
19841
  throw new Error("retain: content cannot be empty");
@@ -19804,19 +19848,13 @@ async function retain(content, ctx, options = {}) {
19804
19848
  let supersedeContent;
19805
19849
  let prepared;
19806
19850
  if (enableAutoMerge) {
19807
- prepared = await prepareVaultCandidates(
19808
- trimmed,
19809
- ctx.vaultCtx,
19810
- ctx.embeddingOptions,
19811
- ctx.vaultCache,
19812
- {
19813
- limit: Math.max(options.consolidateTopK ?? DEFAULT_CONSOLIDATE_TOP_K, 1),
19814
- useFusion: false,
19815
- scopes: [resolvedScope],
19816
- includeArchived: true,
19817
- ...options.folderId !== void 0 && { folderId: options.folderId }
19818
- }
19819
- );
19851
+ prepared = await ctx.persistence.prepare(trimmed, {
19852
+ limit: Math.max(options.consolidateTopK ?? DEFAULT_CONSOLIDATE_TOP_K, 1),
19853
+ useFusion: false,
19854
+ scopes: [resolvedScope],
19855
+ includeArchived: true,
19856
+ ...options.folderId !== void 0 && { folderId: options.folderId }
19857
+ });
19820
19858
  if (prepared.embeddingFailure || prepared.embeddingsUnavailable) {
19821
19859
  throw new Error(
19822
19860
  "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."
@@ -19847,7 +19885,7 @@ async function retain(content, ctx, options = {}) {
19847
19885
  );
19848
19886
  if (matches.length > 0) {
19849
19887
  const targetId = matches[0].uniqueId;
19850
- const existing = await getVaultMemoryOp(ctx.vaultCtx, targetId);
19888
+ const existing = await ctx.persistence.get(targetId);
19851
19889
  if (existing && !existing.supersededBy) {
19852
19890
  const mergedSourceIds = unionStrings(
19853
19891
  existing.sourceChunkIds ?? [],
@@ -19856,7 +19894,7 @@ async function retain(content, ctx, options = {}) {
19856
19894
  const eventTimeUpdate = pickEventTimeUpdate(existing, options.eventTime);
19857
19895
  const factTypeUpdate = pickFactTypeUpdate(existing, options.factType);
19858
19896
  const resurrect = resurrectFields(existing);
19859
- const updated = await updateVaultMemoryOp(ctx.vaultCtx, targetId, {
19897
+ const updated = await ctx.persistence.update(targetId, {
19860
19898
  content: existing.content,
19861
19899
  proofCountIncrement: 1,
19862
19900
  observationSourceIds: options.sourceChunkIds,
@@ -19883,7 +19921,8 @@ async function retain(content, ctx, options = {}) {
19883
19921
  }
19884
19922
  const contentToWrite = supersedeContent ?? trimmed;
19885
19923
  const reusableQueryEmbedding = supersedeContent === void 0 && prepared && prepared.queryEmbedding.length > 0 ? prepared.queryEmbedding : void 0;
19886
- const embedding = reusableQueryEmbedding ?? await generateEmbedding(contentToWrite, ctx.embeddingOptions);
19924
+ const generatedEmbedding = reusableQueryEmbedding ?? await generateEmbedding(contentToWrite, ctx.embeddingOptions);
19925
+ const embedding = ctx.normalizeEmbedding?.(generatedEmbedding) ?? generatedEmbedding;
19887
19926
  const embeddingModel = ctx.embeddingOptions.model ?? DEFAULT_API_EMBEDDING_MODEL;
19888
19927
  if (options.respectTombstones) {
19889
19928
  const tombstone = await findTombstoneMatch(embedding, embeddingModel, resolvedScope, ctx, {
@@ -19923,8 +19962,7 @@ async function retain(content, ctx, options = {}) {
19923
19962
  };
19924
19963
  if (supersedeTargetIds.length > 0) {
19925
19964
  const [primaryTargetId, ...restTargetIds] = supersedeTargetIds;
19926
- const { created: created2, retired } = await createSupersedingMemoryOp(
19927
- ctx.vaultCtx,
19965
+ const { created: created2, retired } = await ctx.persistence.createSuperseding(
19928
19966
  createOpts,
19929
19967
  primaryTargetId
19930
19968
  );
@@ -19940,11 +19978,11 @@ async function retain(content, ctx, options = {}) {
19940
19978
  for (const staleId of restTargetIds) {
19941
19979
  let ok = false;
19942
19980
  try {
19943
- ok = await supersedeVaultMemoryOp(ctx.vaultCtx, staleId, created2.uniqueId) === true;
19981
+ ok = await ctx.persistence.supersede(staleId, created2.uniqueId) === true;
19944
19982
  } catch {
19945
19983
  }
19946
19984
  if (ok) continue;
19947
- const stillLive = await getVaultMemoryOp(ctx.vaultCtx, staleId).catch(() => null);
19985
+ const stillLive = await (ctx.persistence.getFresh ? ctx.persistence.getFresh(staleId) : ctx.persistence.get(staleId)).catch(() => null);
19948
19986
  if (stillLive && !stillLive.supersededBy) liveLeftovers.push(staleId);
19949
19987
  }
19950
19988
  if (liveLeftovers.length > 0) {
@@ -19971,7 +20009,7 @@ async function retain(content, ctx, options = {}) {
19971
20009
  `supersede: primary target ${primaryTargetId} retired or deleted inside the atomic write`
19972
20010
  );
19973
20011
  }
19974
- const created = await createVaultMemoryOp(ctx.vaultCtx, createOpts);
20012
+ const created = await ctx.persistence.create(createOpts);
19975
20013
  cacheRowVector(
19976
20014
  ctx.vaultCache,
19977
20015
  created.uniqueId,
@@ -19990,11 +20028,7 @@ function unionStrings(a, b) {
19990
20028
  return [.../* @__PURE__ */ new Set([...a, ...b])];
19991
20029
  }
19992
20030
  async function findTombstoneMatch(embedding, embeddingModel, scope, ctx, opts) {
19993
- const rows = await getAllVaultMemoriesOp(ctx.vaultCtx, {
19994
- includeDeleted: true,
19995
- scopes: [scope],
19996
- ...opts.folderId !== void 0 && { folderId: opts.folderId }
19997
- });
20031
+ const rows = await ctx.persistence.tombstones(embedding, embeddingModel, scope, opts.folderId);
19998
20032
  let bestId = null;
19999
20033
  let bestSim = opts.threshold;
20000
20034
  for (const row of rows) {
@@ -20061,7 +20095,7 @@ async function tryConsolidate(trimmed, ctx, options, prepared) {
20061
20095
  if (requestedIds.length === 0) return null;
20062
20096
  const valid = [];
20063
20097
  for (const id of requestedIds) {
20064
- const existing = await getVaultMemoryOp(ctx.vaultCtx, id);
20098
+ const existing = await ctx.persistence.get(id);
20065
20099
  if (existing && !existing.supersededBy) valid.push(id);
20066
20100
  }
20067
20101
  if (valid.length === 0) {
@@ -20073,7 +20107,7 @@ async function tryConsolidate(trimmed, ctx, options, prepared) {
20073
20107
  return { supersede: valid, content: decision.content };
20074
20108
  }
20075
20109
  if (decision.action === "noop" && decision.targetId) {
20076
- const existing = await getVaultMemoryOp(ctx.vaultCtx, decision.targetId);
20110
+ const existing = await ctx.persistence.get(decision.targetId);
20077
20111
  if (!existing || existing.supersededBy) {
20078
20112
  return abandonToRace(
20079
20113
  options,
@@ -20087,7 +20121,7 @@ async function tryConsolidate(trimmed, ctx, options, prepared) {
20087
20121
  const eventTimeUpdate = pickEventTimeUpdate(existing, options.eventTime);
20088
20122
  const factTypeUpdate = pickFactTypeUpdate(existing, options.factType);
20089
20123
  const resurrect = resurrectFields(existing);
20090
- const updated = await updateVaultMemoryOp(ctx.vaultCtx, decision.targetId, {
20124
+ const updated = await ctx.persistence.update(decision.targetId, {
20091
20125
  content: existing.content,
20092
20126
  proofCountIncrement: 1,
20093
20127
  observationSourceIds: options.sourceChunkIds,
@@ -20115,7 +20149,7 @@ async function tryConsolidate(trimmed, ctx, options, prepared) {
20115
20149
  };
20116
20150
  }
20117
20151
  if (decision.action === "update" && decision.targetId && decision.content) {
20118
- const existing = await getVaultMemoryOp(ctx.vaultCtx, decision.targetId);
20152
+ const existing = await ctx.persistence.get(decision.targetId);
20119
20153
  if (!existing || existing.supersededBy) {
20120
20154
  return abandonToRace(
20121
20155
  options,
@@ -20126,12 +20160,13 @@ async function tryConsolidate(trimmed, ctx, options, prepared) {
20126
20160
  existing.sourceChunkIds ?? [],
20127
20161
  options.sourceChunkIds ?? []
20128
20162
  );
20129
- const newEmbedding = await generateEmbedding(decision.content, ctx.embeddingOptions);
20163
+ const generatedEmbedding = await generateEmbedding(decision.content, ctx.embeddingOptions);
20164
+ const newEmbedding = ctx.normalizeEmbedding?.(generatedEmbedding) ?? generatedEmbedding;
20130
20165
  const consolidatedModel = ctx.embeddingOptions.model ?? DEFAULT_API_EMBEDDING_MODEL;
20131
20166
  const eventTimeUpdate = pickEventTimeUpdate(existing, options.eventTime);
20132
20167
  const factTypeUpdate = pickFactTypeUpdate(existing, options.factType);
20133
20168
  const resurrect = resurrectFields(existing);
20134
- const updated = await updateVaultMemoryOp(ctx.vaultCtx, decision.targetId, {
20169
+ const updated = await ctx.persistence.update(decision.targetId, {
20135
20170
  content: decision.content,
20136
20171
  proofCountIncrement: 1,
20137
20172
  observationSourceIds: options.sourceChunkIds,
@@ -20175,7 +20210,7 @@ async function tryConsolidate(trimmed, ctx, options, prepared) {
20175
20210
  return null;
20176
20211
  }
20177
20212
  async function assertMergeTargetGoneOrThrow(ctx, targetId) {
20178
- const stillExists = await getVaultMemoryOp(ctx.vaultCtx, targetId);
20213
+ const stillExists = await (ctx.persistence.getFresh ? ctx.persistence.getFresh(targetId) : ctx.persistence.get(targetId));
20179
20214
  if (stillExists) {
20180
20215
  throw new Error(`retain: merge into memory ${targetId} failed to persist`);
20181
20216
  }
@@ -20692,9 +20727,9 @@ function createAutoExtractor(options) {
20692
20727
  const persistCursor = (conversationId, messages, advancedToId, contiguous) => {
20693
20728
  if (!cursorStore || conversationId === void 0 || !contiguous) return;
20694
20729
  try {
20695
- const stored = cursorStore.get(conversationId);
20696
- if (stored && stored !== advancedToId) {
20697
- const storedIdx = messages.findIndex((m) => m.id === stored);
20730
+ const stored2 = cursorStore.get(conversationId);
20731
+ if (stored2 && stored2 !== advancedToId) {
20732
+ const storedIdx = messages.findIndex((m) => m.id === stored2);
20698
20733
  const newIdx = messages.findIndex((m) => m.id === advancedToId);
20699
20734
  if (storedIdx !== -1 && newIdx !== -1 && storedIdx >= newIdx) return;
20700
20735
  }
@@ -21674,7 +21709,7 @@ async function recall(query, ctx, options = {}) {
21674
21709
  if (graphLaneFailed) degraded.push("graph-lane-failed");
21675
21710
  if (temporalLaneFailed) degraded.push("temporal-lane-failed");
21676
21711
  if (chunksScopeRestricted) degraded.push("chunks-scope-restricted");
21677
- const laneRan = types.includes("fact") && !!ctx.vaultCtx && !!ctx.vaultCache || types.includes("chunk") && !!ctx.storageCtx || chunksScopeRestricted && !!ctx.storageCtx;
21712
+ const laneRan = types.includes("fact") && (!!ctx.factSource || !!ctx.vaultCtx && !!ctx.vaultCache) || types.includes("chunk") && !!ctx.storageCtx || chunksScopeRestricted && !!ctx.storageCtx;
21678
21713
  const scores = admitted.map((m) => m.score);
21679
21714
  const minScoreApplied = factResults.length > 0 ? factFloor : chunkResults.length > 0 ? chunkFloor : factFloor >= 0 ? factFloor : chunkFloor;
21680
21715
  const diagnostics = {
@@ -21716,7 +21751,7 @@ async function recall(query, ctx, options = {}) {
21716
21751
  return { memories: [], usedBudget, reranked: false, candidateCount: 0 };
21717
21752
  }
21718
21753
  const needsChunkEmbedding = types.includes("chunk") && ctx.storageCtx;
21719
- const wantsTemporal = types.includes("fact") && ctx.vaultCtx;
21754
+ const wantsTemporal = types.includes("fact") && (ctx.factSource || ctx.vaultCtx);
21720
21755
  const graphRefiner = flags.traverse && options.graphRefine && options.decomposeOptions ? createLlmNeighborRefiner(options.decomposeOptions) : void 0;
21721
21756
  const queryEmbedTotalTimeoutMs = options.queryEmbedTotalTimeoutMs ?? DEFAULT_QUERY_EMBED_TOTAL_TIMEOUT_MS;
21722
21757
  const prepStart = nowMs2();
@@ -21746,7 +21781,7 @@ async function recall(query, ctx, options = {}) {
21746
21781
  safeLane(
21747
21782
  "graph",
21748
21783
  () => graphLaneFailed = true,
21749
- () => buildGraphLaneRanking(query, ctx, flags.traverse, {
21784
+ () => ctx.factSource ? ctx.factSource.graphRanking(query, flags.traverse, options) : buildGraphLaneRanking(query, ctx, flags.traverse, {
21750
21785
  ...options.maxHops !== void 0 && { maxHops: options.maxHops },
21751
21786
  ...options.entityFanout !== void 0 && { entityFanout: options.entityFanout },
21752
21787
  ...options.nodeBudget !== void 0 && { nodeBudget: options.nodeBudget },
@@ -21757,13 +21792,13 @@ async function recall(query, ctx, options = {}) {
21757
21792
  wantsTemporal ? safeLane(
21758
21793
  "temporal",
21759
21794
  () => temporalLaneFailed = true,
21760
- () => buildTemporalLaneRanking(query, ctx.vaultCtx, options.now)
21795
+ () => ctx.factSource ? ctx.factSource.temporalRanking(query, options.now) : buildTemporalLaneRanking(query, ctx.vaultCtx, options.now)
21761
21796
  ) : Promise.resolve([])
21762
21797
  ]);
21763
21798
  prepMs = nowMs2() - prepStart;
21764
21799
  graphLaneCount = entityRanking.length;
21765
21800
  temporalLaneCount = temporalRanking.length;
21766
- if (types.includes("fact") && ctx.vaultCtx && ctx.vaultCache) {
21801
+ if (types.includes("fact") && (ctx.factSource || ctx.vaultCtx && ctx.vaultCache)) {
21767
21802
  const factStart = nowMs2();
21768
21803
  const vaultMinScore = options.minScore ?? DEFAULT_FACT_MIN_SCORE;
21769
21804
  factFloor = vaultMinScore;
@@ -21779,50 +21814,50 @@ async function recall(query, ctx, options = {}) {
21779
21814
  rankedOnCosine: factRankedOnCosine,
21780
21815
  decryptLast: factDecryptLast,
21781
21816
  rowsDecrypted: factRowsDecrypted
21782
- } = await searchVaultMemoriesWithSize(
21783
- query,
21817
+ } = await (ctx.factSource?.search.bind(ctx.factSource) ?? ((searchQuery, searchOptions) => searchVaultMemoriesWithSize(
21818
+ searchQuery,
21784
21819
  ctx.vaultCtx,
21785
21820
  ctx.embeddingOptions,
21786
21821
  ctx.vaultCache,
21787
- {
21788
- limit: types.includes("chunk") ? Math.max(limit * 2, 16) : limit,
21789
- minSimilarity: vaultMinScore,
21790
- useFusion: true,
21791
- rerank: flags.rerank,
21792
- ...options.rerankTopN !== void 0 && { rerankTopN: options.rerankTopN },
21793
- ...options.ceWeight !== void 0 && { ceWeight: options.ceWeight },
21794
- ...options.rerankLoadTimeoutMs !== void 0 && {
21795
- rerankLoadTimeoutMs: options.rerankLoadTimeoutMs
21796
- },
21797
- ...options.recencyAlpha !== void 0 && { recencyAlpha: options.recencyAlpha },
21798
- ...options.recency && { recency: options.recency },
21799
- ...options.mmr !== void 0 && { mmr: options.mmr },
21800
- ...options.supersessionBoost !== void 0 && {
21801
- supersessionBoost: options.supersessionBoost
21802
- },
21803
- ...options.supersessionWindow !== void 0 && {
21804
- supersessionWindow: options.supersessionWindow
21805
- },
21806
- ...options.proofCountAlpha !== void 0 && {
21807
- proofCountAlpha: options.proofCountAlpha
21808
- },
21809
- ...options.bm25AdmissionDivisor !== void 0 && {
21810
- bm25AdmissionDivisor: options.bm25AdmissionDivisor
21811
- },
21812
- ...options.rrfK !== void 0 && { rrfK: options.rrfK },
21813
- ...options.decryptLast !== void 0 && { decryptLast: options.decryptLast },
21814
- ...subQueries && { subQueries },
21815
- ...options.scopes && { scopes: options.scopes },
21816
- ...options.folderId !== void 0 && { folderId: options.folderId },
21817
- ...options.factTypes?.length && { factTypes: options.factTypes },
21818
- ...options.memoryIds !== void 0 && { memoryIds: options.memoryIds },
21819
- ...options.factTypeWeights && { factTypeWeights: options.factTypeWeights },
21820
- ...entityRanking.length > 0 && { entityRanking },
21821
- ...temporalRanking.length > 0 && { temporalRanking },
21822
- ...needsChunkEmbedding && { queryEmbedding: queryEmbedding ?? [] },
21823
- queryEmbedTotalTimeoutMs
21824
- }
21825
- );
21822
+ searchOptions
21823
+ )))(query, {
21824
+ limit: types.includes("chunk") ? Math.max(limit * 2, 16) : limit,
21825
+ minSimilarity: vaultMinScore,
21826
+ useFusion: true,
21827
+ rerank: flags.rerank,
21828
+ ...options.rerankTopN !== void 0 && { rerankTopN: options.rerankTopN },
21829
+ ...options.ceWeight !== void 0 && { ceWeight: options.ceWeight },
21830
+ ...options.rerankLoadTimeoutMs !== void 0 && {
21831
+ rerankLoadTimeoutMs: options.rerankLoadTimeoutMs
21832
+ },
21833
+ ...options.recencyAlpha !== void 0 && { recencyAlpha: options.recencyAlpha },
21834
+ ...options.recency && { recency: options.recency },
21835
+ ...options.mmr !== void 0 && { mmr: options.mmr },
21836
+ ...options.supersessionBoost !== void 0 && {
21837
+ supersessionBoost: options.supersessionBoost
21838
+ },
21839
+ ...options.supersessionWindow !== void 0 && {
21840
+ supersessionWindow: options.supersessionWindow
21841
+ },
21842
+ ...options.proofCountAlpha !== void 0 && {
21843
+ proofCountAlpha: options.proofCountAlpha
21844
+ },
21845
+ ...options.bm25AdmissionDivisor !== void 0 && {
21846
+ bm25AdmissionDivisor: options.bm25AdmissionDivisor
21847
+ },
21848
+ ...options.rrfK !== void 0 && { rrfK: options.rrfK },
21849
+ ...options.decryptLast !== void 0 && { decryptLast: options.decryptLast },
21850
+ ...subQueries && { subQueries },
21851
+ ...options.scopes && { scopes: options.scopes },
21852
+ ...options.folderId !== void 0 && { folderId: options.folderId },
21853
+ ...options.factTypes?.length && { factTypes: options.factTypes },
21854
+ ...options.memoryIds !== void 0 && { memoryIds: options.memoryIds },
21855
+ ...options.factTypeWeights && { factTypeWeights: options.factTypeWeights },
21856
+ ...entityRanking.length > 0 && { entityRanking },
21857
+ ...temporalRanking.length > 0 && { temporalRanking },
21858
+ ...needsChunkEmbedding && { queryEmbedding: queryEmbedding ?? [] },
21859
+ queryEmbedTotalTimeoutMs
21860
+ });
21826
21861
  factResults.push(
21827
21862
  ...dedupeBy(
21828
21863
  results,
@@ -22635,26 +22670,26 @@ async function extractAndLinkEntitiesForMemoriesOp(ctx, memoryIds, options) {
22635
22670
  };
22636
22671
  const inputs = [];
22637
22672
  for (const id of new Set(memoryIds)) {
22638
- let record;
22673
+ let record2;
22639
22674
  try {
22640
- record = await ctx.vaultMemoryCollection.find(id);
22675
+ record2 = await ctx.vaultMemoryCollection.find(id);
22641
22676
  } catch (err) {
22642
22677
  log.warn("[memory/topics] vault lookup failed for extraction", err);
22643
22678
  skip(id, "not-found");
22644
22679
  continue;
22645
22680
  }
22646
- if (record.isDeleted || ctx.userId !== void 0 && record.userId !== ctx.userId || record.topicsUserManaged) {
22681
+ if (record2.isDeleted || ctx.userId !== void 0 && record2.userId !== ctx.userId || record2.topicsUserManaged) {
22647
22682
  skip(id, "excluded");
22648
22683
  continue;
22649
22684
  }
22650
22685
  try {
22651
- const stored = await vaultMemoryToStored(
22652
- record,
22686
+ const stored2 = await vaultMemoryToStored(
22687
+ record2,
22653
22688
  ctx.walletAddress,
22654
22689
  ctx.signMessage,
22655
22690
  ctx.embeddedWalletSigner
22656
22691
  );
22657
- inputs.push({ id, content: stored.content });
22692
+ inputs.push({ id, content: stored2.content });
22658
22693
  } catch (err) {
22659
22694
  log.warn("[memory/topics] failed to load memory for extraction", err);
22660
22695
  skip(id, "unreadable");
@@ -22839,6 +22874,774 @@ function createLocalMemoryStore(options) {
22839
22874
  };
22840
22875
  }
22841
22876
 
22877
+ // src/lib/memory/store/remotePersistence.ts
22878
+ var RemoteMemoryError = class extends Error {
22879
+ constructor(message, status, code) {
22880
+ super(message);
22881
+ this.status = status;
22882
+ this.code = code;
22883
+ this.name = "RemoteMemoryError";
22884
+ }
22885
+ };
22886
+ var ciphertextPattern = /^enc:v\d+:[0-9a-f]+$/i;
22887
+ var memoryFields = {
22888
+ memory_id: true,
22889
+ content: true,
22890
+ scope: true,
22891
+ created_at: true,
22892
+ updated_at: true,
22893
+ is_deleted: true,
22894
+ embedding: true,
22895
+ embedding_model: true,
22896
+ kind: true,
22897
+ kind_value: true,
22898
+ level: true,
22899
+ folder_id: true,
22900
+ source_chunk_ids: true,
22901
+ proof_count: true,
22902
+ source: true,
22903
+ event_time_start: true,
22904
+ event_time_end: true,
22905
+ event_time_kind: true,
22906
+ topics_user_managed: true,
22907
+ topics: true,
22908
+ topics_updated_at: true,
22909
+ media: true,
22910
+ topics_extracted_at: true,
22911
+ topics_extracted_version: true,
22912
+ superseded_by: true,
22913
+ superseded_at: true,
22914
+ last_observed_at: true,
22915
+ fact_type: true,
22916
+ archived_at: true,
22917
+ trust_tier: true,
22918
+ visibility: true,
22919
+ twin_opt_in: true,
22920
+ published_at: true,
22921
+ geohash: true
22922
+ };
22923
+ var candidateListLimits = [
22924
+ ["scopes", 20],
22925
+ ["fact_types", 20],
22926
+ ["memory_ids", 1e3],
22927
+ ["force_ids", 100]
22928
+ ];
22929
+ function record(value) {
22930
+ return typeof value === "object" && value !== null && !Array.isArray(value);
22931
+ }
22932
+ function memoryRecord(value) {
22933
+ 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))) {
22934
+ throw new Error("Invalid nearby private-memory response");
22935
+ }
22936
+ return value;
22937
+ }
22938
+ async function createRemoteMemoryPersistence(options) {
22939
+ const base = new URL(options.baseUrl);
22940
+ if (!/^https?:$/.test(base.protocol) || base.username || base.password || base.search || base.hash) {
22941
+ throw new Error(
22942
+ "baseUrl must be an HTTP(S) origin or base path without credentials, query or fragment"
22943
+ );
22944
+ }
22945
+ if (!options.keyId || options.keyId.length > 256)
22946
+ throw new Error("A canonical keyId is required");
22947
+ const timeoutMs = options.timeoutMs ?? 3e4;
22948
+ if (!Number.isFinite(timeoutMs) || timeoutMs <= 0)
22949
+ throw new Error("timeoutMs must be a positive number");
22950
+ const root = base.href.replace(/\/$/, "") + "/api/private-memories";
22951
+ const fetcher = options.fetch ?? globalThis.fetch;
22952
+ const request = async (path, init = {}, signal) => {
22953
+ const controller = new AbortController();
22954
+ let timedOut = false;
22955
+ const timer = setTimeout(() => {
22956
+ timedOut = true;
22957
+ controller.abort();
22958
+ }, timeoutMs);
22959
+ const forwardAbort = () => controller.abort(signal?.reason);
22960
+ if (signal?.aborted) forwardAbort();
22961
+ else signal?.addEventListener("abort", forwardAbort, { once: true });
22962
+ let rejectAborted;
22963
+ const aborted = new Promise((_, reject) => {
22964
+ rejectAborted = () => reject(
22965
+ controller.signal.reason instanceof Error ? controller.signal.reason : new Error("Nearby request aborted")
22966
+ );
22967
+ if (controller.signal.aborted) rejectAborted();
22968
+ else controller.signal.addEventListener("abort", rejectAborted, { once: true });
22969
+ });
22970
+ aborted.catch(() => void 0);
22971
+ try {
22972
+ const token = await Promise.race([options.getToken(), aborted]);
22973
+ if (controller.signal.aborted) await aborted;
22974
+ if (!token) throw new RemoteMemoryError("Authentication required", 401);
22975
+ const response = await fetcher(root + path, {
22976
+ ...init,
22977
+ headers: {
22978
+ Authorization: `Bearer ${token}`,
22979
+ ...init.body ? { "Content-Type": "application/json" } : {}
22980
+ },
22981
+ redirect: "error",
22982
+ signal: controller.signal
22983
+ });
22984
+ if (!response.ok) {
22985
+ const body = await response.json().catch(() => null);
22986
+ throw new RemoteMemoryError(
22987
+ record(body) && typeof body.detail === "string" ? body.detail : `Nearby request failed (${response.status})`,
22988
+ response.status,
22989
+ record(body) && typeof body.code === "string" ? body.code : void 0
22990
+ );
22991
+ }
22992
+ return await response.json();
22993
+ } catch (error) {
22994
+ if (timedOut) throw new RemoteMemoryError("Nearby request timed out", 408, "timeout");
22995
+ throw error;
22996
+ } finally {
22997
+ clearTimeout(timer);
22998
+ signal?.removeEventListener("abort", forwardAbort);
22999
+ if (rejectAborted) controller.signal.removeEventListener("abort", rejectAborted);
23000
+ }
23001
+ };
23002
+ const account = await request("/account", {}, options.signal);
23003
+ if (!record(account) || account.state !== "active") {
23004
+ throw new RemoteMemoryError(
23005
+ "Complete and verify migration before using remote memories",
23006
+ 409,
23007
+ "memory_not_active"
23008
+ );
23009
+ }
23010
+ if (account.key_id !== options.keyId) {
23011
+ throw new RemoteMemoryError(
23012
+ "The canonical memory key does not match this account",
23013
+ 409,
23014
+ "key_mismatch"
23015
+ );
23016
+ }
23017
+ const snapshots = /* @__PURE__ */ new WeakMap();
23018
+ const decode = async (value) => {
23019
+ const item = memoryRecord(value);
23020
+ const decrypt = async (ciphertext) => {
23021
+ if (!ciphertextPattern.test(ciphertext))
23022
+ throw new Error("Nearby returned unencrypted memory content");
23023
+ const plaintext = await options.decrypt(ciphertext);
23024
+ if (plaintext === ciphertext) throw new Error("Memory decryption failed");
23025
+ return plaintext;
23026
+ };
23027
+ const decoded = {
23028
+ ...item,
23029
+ memory: {
23030
+ ...item.memory,
23031
+ content: await decrypt(item.memory.content),
23032
+ ...item.memory.kind_value !== void 0 && {
23033
+ kind_value: await decrypt(item.memory.kind_value)
23034
+ }
23035
+ }
23036
+ };
23037
+ return remember(decoded, item);
23038
+ };
23039
+ const remember = (decoded, item) => {
23040
+ snapshots.set(decoded, {
23041
+ id: item.memory.memory_id,
23042
+ version: item.version,
23043
+ content: decoded.memory.content,
23044
+ kindValue: decoded.memory.kind_value,
23045
+ encryptedContent: item.memory.content,
23046
+ encryptedKindValue: item.memory.kind_value
23047
+ });
23048
+ return decoded;
23049
+ };
23050
+ const decodeAll = async (values) => {
23051
+ const records = values.map(memoryRecord);
23052
+ const settled = await Promise.allSettled(records.map(decode));
23053
+ const items = [];
23054
+ const failed = [];
23055
+ settled.forEach((result, i) => {
23056
+ if (result.status === "fulfilled") items.push(result.value);
23057
+ else
23058
+ failed.push({
23059
+ memory_id: records[i].memory.memory_id,
23060
+ version: records[i].version,
23061
+ error: result.reason instanceof Error ? result.reason : new Error(String(result.reason))
23062
+ });
23063
+ });
23064
+ return { items, failed };
23065
+ };
23066
+ const decodeCommitted = async (value, write) => {
23067
+ const item = memoryRecord(value);
23068
+ 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)
23069
+ return decode(item);
23070
+ return remember(
23071
+ {
23072
+ ...item,
23073
+ memory: {
23074
+ ...item.memory,
23075
+ content: write.content,
23076
+ ...write.kindValue !== void 0 && { kind_value: write.kindValue }
23077
+ }
23078
+ },
23079
+ item
23080
+ );
23081
+ };
23082
+ const encryptField2 = async (plaintext) => {
23083
+ const ciphertext = await options.encrypt(plaintext);
23084
+ if (ciphertext === plaintext || !ciphertextPattern.test(ciphertext))
23085
+ throw new Error("Field encryption must return SDK ciphertext; refusing to upload plaintext");
23086
+ return ciphertext;
23087
+ };
23088
+ const memoryPath = (id) => {
23089
+ if (!id || id.length > 128) throw new Error("memory_id must be 1\u2013128 characters");
23090
+ return "/memories/" + encodeURIComponent(id);
23091
+ };
23092
+ const prepareWrite = async (memory, expectedVersion, signal) => {
23093
+ const unknown = Object.keys(memory).filter(
23094
+ (key) => !Object.prototype.hasOwnProperty.call(memoryFields, key)
23095
+ );
23096
+ if (unknown.length) {
23097
+ throw new RemoteMemoryError(
23098
+ `Unknown private-memory fields (${unknown.join(", ")}); refusing to forward them`,
23099
+ 400,
23100
+ "unknown_field"
23101
+ );
23102
+ }
23103
+ memory = { ...memory, ...memory.embedding && { embedding: [...memory.embedding] } };
23104
+ const path = memoryPath(memory.memory_id);
23105
+ const snapshot = typeof expectedVersion === "number" ? void 0 : snapshots.get(expectedVersion);
23106
+ if (typeof expectedVersion !== "number" && (!snapshot || snapshot.id !== memory.memory_id || snapshot.version !== expectedVersion.version))
23107
+ throw new Error(
23108
+ "Expected snapshot must be an unmodified version from this persistence instance"
23109
+ );
23110
+ expectedVersion = typeof expectedVersion === "number" ? expectedVersion : snapshot.version;
23111
+ if (!Number.isSafeInteger(expectedVersion) || expectedVersion < 0)
23112
+ throw new Error("expectedVersion must be a nonnegative integer");
23113
+ const conflict = () => new RemoteMemoryError("The memory changed since it was read", 409, "version_conflict");
23114
+ let existing;
23115
+ if (expectedVersion !== 0 && !snapshot) {
23116
+ try {
23117
+ existing = memoryRecord(await request(path, {}, signal));
23118
+ } catch (error) {
23119
+ if (error instanceof RemoteMemoryError && error.status === 404) throw conflict();
23120
+ throw error;
23121
+ }
23122
+ }
23123
+ if (existing && existing.version !== expectedVersion) throw conflict();
23124
+ const decoded = existing ? await decode(existing).catch(() => void 0) : void 0;
23125
+ const content = (snapshot?.content ?? decoded?.memory.content) === memory.content ? snapshot?.encryptedContent ?? existing.memory.content : await encryptField2(memory.content);
23126
+ 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);
23127
+ return {
23128
+ body: {
23129
+ expected_version: expectedVersion,
23130
+ memory: { ...memory, content, ...kindValue !== void 0 && { kind_value: kindValue } }
23131
+ },
23132
+ content: memory.content,
23133
+ kindValue: memory.kind_value
23134
+ };
23135
+ };
23136
+ const fetchCandidates = async (embedding, candidateOptions, withCounts) => {
23137
+ const limit = candidateOptions.limit ?? 100;
23138
+ if (!Number.isInteger(limit) || limit < 1 || limit > 100)
23139
+ throw new Error("Candidate limit must be 1\u2013100");
23140
+ for (const [key, max] of candidateListLimits) {
23141
+ const values = candidateOptions[key];
23142
+ if (values && values.length > max)
23143
+ throw new Error(`Candidate ${key} accepts at most ${max} entries (got ${values.length})`);
23144
+ }
23145
+ const result = await request(
23146
+ "/candidates",
23147
+ {
23148
+ method: "POST",
23149
+ body: JSON.stringify({
23150
+ embedding,
23151
+ limit,
23152
+ force_ids: candidateOptions.force_ids ?? [],
23153
+ ...withCounts && { with_counts: true },
23154
+ ...Object.fromEntries(
23155
+ [
23156
+ "scopes",
23157
+ "memory_ids",
23158
+ "embedding_model",
23159
+ "strict_model",
23160
+ "include_deleted",
23161
+ "deleted_only"
23162
+ ].filter(
23163
+ (key) => candidateOptions[key] !== void 0
23164
+ ).map((key) => [key, candidateOptions[key]])
23165
+ ),
23166
+ ...candidateOptions.fact_types !== void 0 && {
23167
+ fact_types: candidateOptions.fact_types
23168
+ },
23169
+ ...candidateOptions.include_archived !== void 0 && {
23170
+ include_archived: candidateOptions.include_archived
23171
+ },
23172
+ ...candidateOptions.include_quarantined !== void 0 && {
23173
+ include_quarantined: candidateOptions.include_quarantined
23174
+ },
23175
+ ...candidateOptions.include_superseded !== void 0 && {
23176
+ include_superseded: candidateOptions.include_superseded
23177
+ }
23178
+ })
23179
+ },
23180
+ candidateOptions.signal
23181
+ );
23182
+ if (!record(result) || !Array.isArray(result.items))
23183
+ throw new Error("Invalid nearby candidate response");
23184
+ return result;
23185
+ };
23186
+ const candidateSet = async (embedding, candidateOptions = {}) => {
23187
+ const result = await fetchCandidates(embedding, candidateOptions, true);
23188
+ if (!Number.isSafeInteger(result.total_count) || result.total_count < 0 || !Number.isSafeInteger(result.unavailable_count) || result.unavailable_count < 0)
23189
+ throw new Error("Invalid nearby candidate response");
23190
+ return {
23191
+ ...await decodeAll(result.items),
23192
+ total_count: result.total_count,
23193
+ unavailable_count: result.unavailable_count
23194
+ };
23195
+ };
23196
+ return {
23197
+ get: async (id, signal) => {
23198
+ try {
23199
+ return await decode(await request(memoryPath(id), {}, signal));
23200
+ } catch (error) {
23201
+ if (error instanceof RemoteMemoryError && error.status === 404) return null;
23202
+ throw error;
23203
+ }
23204
+ },
23205
+ list: async (listOptions = {}) => {
23206
+ const { signal, ...query } = listOptions;
23207
+ if (query.limit !== void 0 && (!Number.isInteger(query.limit) || query.limit < 1 || query.limit > 200)) {
23208
+ throw new Error("Page limit must be 1\u2013200");
23209
+ }
23210
+ const params = new URLSearchParams();
23211
+ for (const key of [
23212
+ "cursor",
23213
+ "limit",
23214
+ "include_deleted",
23215
+ "include_archived",
23216
+ "include_quarantined",
23217
+ "include_superseded",
23218
+ "include_embeddings"
23219
+ ]) {
23220
+ if (query[key] !== void 0) params.set(key, String(query[key]));
23221
+ }
23222
+ const page = await request("/memories?" + params.toString(), {}, signal);
23223
+ if (!record(page) || !Array.isArray(page.items) || page.next_cursor !== void 0 && typeof page.next_cursor !== "string") {
23224
+ throw new Error("Invalid nearby private-memory page");
23225
+ }
23226
+ return {
23227
+ ...await decodeAll(page.items),
23228
+ ...page.next_cursor !== void 0 && { next_cursor: page.next_cursor }
23229
+ };
23230
+ },
23231
+ put: async (memory, expectedVersion, signal) => {
23232
+ const write = await prepareWrite(memory, expectedVersion, signal);
23233
+ return decodeCommitted(
23234
+ await request(
23235
+ memoryPath(write.body.memory.memory_id),
23236
+ {
23237
+ method: "PUT",
23238
+ body: JSON.stringify({ key_id: options.keyId, ...write.body })
23239
+ },
23240
+ signal
23241
+ ),
23242
+ write
23243
+ );
23244
+ },
23245
+ putMany: async (writes, signal) => {
23246
+ if (writes.length < 1 || writes.length > 50 || new Set(writes.map((w) => w.memory.memory_id)).size !== writes.length)
23247
+ throw new Error("Batch must contain 1\u201350 distinct memory ids");
23248
+ const prepared = await Promise.all(
23249
+ writes.map((w) => prepareWrite(w.memory, w.expectedVersion, signal))
23250
+ );
23251
+ const result = await request(
23252
+ "/memories/batch",
23253
+ {
23254
+ method: "POST",
23255
+ body: JSON.stringify({ key_id: options.keyId, writes: prepared.map((w) => w.body) })
23256
+ },
23257
+ signal
23258
+ );
23259
+ if (!record(result) || !Array.isArray(result.items) || result.items.length !== prepared.length)
23260
+ throw new Error("Invalid nearby batch response");
23261
+ return Promise.all(result.items.map((item, i) => decodeCommitted(item, prepared[i])));
23262
+ },
23263
+ candidateSet,
23264
+ candidates: async (embedding, candidateOptions = {}) => decodeAll((await fetchCandidates(embedding, candidateOptions, false)).items)
23265
+ };
23266
+ }
23267
+
23268
+ // src/lib/memory/store/remotePipeline.ts
23269
+ var import_uuid5 = require("uuid");
23270
+ init_logger();
23271
+ function storedVector(vector) {
23272
+ if (!Array.isArray(vector) || vector.length !== 1536 && vector.length !== 4096 || vector.some((v) => !Number.isFinite(v)))
23273
+ throw new Error("Remote memories require a finite 1536/4096-dimensional vector");
23274
+ const out = vector.slice(0, 1536);
23275
+ const norm = Math.sqrt(out.reduce((sum, v) => sum + v * v, 0));
23276
+ if (!norm) throw new Error("Remote query/content vector has no direction after MRL truncation");
23277
+ return out.map((v) => v / norm);
23278
+ }
23279
+ function sourceIds(value) {
23280
+ if (!value) return [];
23281
+ try {
23282
+ const parsed = JSON.parse(value);
23283
+ return Array.isArray(parsed) ? parsed.filter((id) => typeof id === "string") : [];
23284
+ } catch {
23285
+ return [];
23286
+ }
23287
+ }
23288
+ function stored(row) {
23289
+ return {
23290
+ uniqueId: row.memory_id,
23291
+ content: row.content,
23292
+ scope: row.scope,
23293
+ folderId: row.folder_id ?? null,
23294
+ userId: null,
23295
+ embedding: row.embedding ? JSON.stringify(row.embedding) : null,
23296
+ embeddingModel: row.embedding_model ?? null,
23297
+ sourceChunkIds: row.source_chunk_ids === void 0 ? null : sourceIds(row.source_chunk_ids),
23298
+ proofCount: row.proof_count ?? null,
23299
+ source: row.source ?? null,
23300
+ media: parseMedia(row.media),
23301
+ eventTimeStart: row.event_time_start ?? null,
23302
+ eventTimeEnd: row.event_time_end ?? null,
23303
+ eventTimeKind: row.event_time_kind ?? null,
23304
+ topicsUserManaged: row.topics_user_managed ?? false,
23305
+ topics: parseTopics(row.topics),
23306
+ topicsUpdatedAt: row.topics_updated_at ?? null,
23307
+ topicsExtractedAt: row.topics_extracted_at ?? null,
23308
+ topicsExtractedVersion: row.topics_extracted_version ?? null,
23309
+ supersededBy: row.superseded_by ?? null,
23310
+ supersededAt: row.superseded_at ?? null,
23311
+ lastObservedAt: row.last_observed_at ?? null,
23312
+ factType: row.fact_type ?? null,
23313
+ archivedAt: row.archived_at ?? null,
23314
+ trustTier: row.trust_tier ?? null,
23315
+ visibility: row.visibility === "public" ? "public" : "private",
23316
+ twinOptIn: row.twin_opt_in ?? false,
23317
+ publishedAt: row.published_at ?? null,
23318
+ geohash: row.geohash ?? null,
23319
+ createdAt: new Date(row.created_at),
23320
+ updatedAt: new Date(row.updated_at),
23321
+ isDeleted: row.is_deleted
23322
+ };
23323
+ }
23324
+ function createRemoteMemoryPipeline(options) {
23325
+ const { persistence, embeddingOptions } = options;
23326
+ const model = embeddingOptions.model ?? DEFAULT_API_EMBEDDING_MODEL;
23327
+ const operation = (mode) => {
23328
+ const rejectUndecryptable = (failed) => {
23329
+ if (!failed.length) return;
23330
+ if (mode === "retain")
23331
+ throw new Error(
23332
+ `Remote memories could not decrypt ${failed.length} candidate row(s); refusing to retain until they are repaired`
23333
+ );
23334
+ getLogger().warn(
23335
+ `[memory/remote] Skipping ${failed.length} undecryptable candidate row(s)`,
23336
+ failed.map((failure) => failure.memory_id)
23337
+ );
23338
+ };
23339
+ const snapshots = /* @__PURE__ */ new Map();
23340
+ const remember = (items) => {
23341
+ items.forEach((item) => snapshots.set(item.memory.memory_id, item));
23342
+ return items.map((item) => stored(item.memory));
23343
+ };
23344
+ const get = async (id) => {
23345
+ const snapshot = snapshots.get(id) ?? await persistence.get(id);
23346
+ if (!snapshot || snapshot.memory.is_deleted || snapshot.memory.superseded_by) return null;
23347
+ snapshots.set(id, snapshot);
23348
+ return stored(snapshot.memory);
23349
+ };
23350
+ const prepare = async (query, search = {}) => {
23351
+ if (search.folderId !== void 0)
23352
+ throw new Error("Remote memories do not support folder filters");
23353
+ const facets = normalizeSubQueries(search.subQueries);
23354
+ const facetQueries = facets.length >= 2 ? facets : [];
23355
+ const start = Date.now();
23356
+ const budgetMs = search.queryEmbedTotalTimeoutMs ?? 8e3;
23357
+ const embed = (texts) => generateEmbeddings(texts, {
23358
+ ...embeddingOptions,
23359
+ totalTimeoutMs: budgetMs
23360
+ });
23361
+ const embedFacets = async () => {
23362
+ if (!facetQueries.length) return [];
23363
+ try {
23364
+ const vectors2 = await embed(facetQueries);
23365
+ if (vectors2.length !== facetQueries.length)
23366
+ throw new Error("Incomplete facet embeddings");
23367
+ return vectors2.map(storedVector);
23368
+ } catch (error) {
23369
+ getLogger().warn(
23370
+ "[memory/remote] Facet embeddings unavailable; using primary query",
23371
+ error
23372
+ );
23373
+ return [];
23374
+ }
23375
+ };
23376
+ const [primary, facetEmbeddings] = await Promise.all([
23377
+ search.queryEmbedding ?? embed([query]).then((vectors2) => vectors2[0]),
23378
+ embedFacets()
23379
+ ]);
23380
+ const queryEmbedding = storedVector(primary);
23381
+ const queryEmbedMs = Date.now() - start;
23382
+ const graph = search.entityRanking ?? [];
23383
+ const temporal = search.temporalRanking ?? [];
23384
+ const forced = /* @__PURE__ */ new Set();
23385
+ for (let i = 0; i < Math.max(graph.length, temporal.length) && forced.size < 100; i++) {
23386
+ if (graph[i] !== void 0) forced.add(graph[i]);
23387
+ if (forced.size < 100 && temporal[i] !== void 0) forced.add(temporal[i]);
23388
+ }
23389
+ const forceIds = [...forced];
23390
+ const windowOptions = (i, signal) => ({
23391
+ limit: Math.min(100, Math.max((search.limit ?? 8) * 3, 30)),
23392
+ force_ids: i === 0 ? forceIds : [],
23393
+ ...search.scopes && { scopes: search.scopes },
23394
+ ...search.factTypes && { fact_types: search.factTypes },
23395
+ ...search.memoryIds !== void 0 && { memory_ids: search.memoryIds },
23396
+ include_archived: search.includeArchived,
23397
+ embedding_model: model,
23398
+ ...signal && { signal }
23399
+ });
23400
+ const vectors = [queryEmbedding, ...facetEmbeddings];
23401
+ let windows;
23402
+ if (mode === "retain") {
23403
+ windows = await Promise.all(
23404
+ vectors.map((embedding, i) => persistence.candidateSet(embedding, windowOptions(i)))
23405
+ );
23406
+ } else {
23407
+ const deadline = new AbortController();
23408
+ const timer = setTimeout(
23409
+ () => deadline.abort(
23410
+ new RemoteMemoryError("Remote recall exceeded its query budget", 408, "timeout")
23411
+ ),
23412
+ Math.max(0, start + budgetMs - Date.now())
23413
+ );
23414
+ try {
23415
+ windows = await Promise.all(
23416
+ vectors.map(
23417
+ (embedding, i) => persistence.candidates(embedding, windowOptions(i, deadline.signal))
23418
+ )
23419
+ );
23420
+ } finally {
23421
+ clearTimeout(timer);
23422
+ }
23423
+ }
23424
+ rejectUndecryptable([
23425
+ ...new Map(
23426
+ windows.flatMap((window2) => window2.failed).map((failure) => [failure.memory_id, failure])
23427
+ ).values()
23428
+ ]);
23429
+ const items = [
23430
+ ...new Map(
23431
+ windows.flatMap((window2) => window2.items).map((item) => [item.memory.memory_id, item])
23432
+ ).values()
23433
+ ];
23434
+ const memories = remember(items);
23435
+ return {
23436
+ memories,
23437
+ embeddedItems: memories.map((memory) => ({
23438
+ id: memory.uniqueId,
23439
+ content: memory.content,
23440
+ embedding: JSON.parse(memory.embedding ?? "[]"),
23441
+ createdAt: memory.createdAt,
23442
+ updatedAt: memory.updatedAt,
23443
+ proofCount: memory.proofCount,
23444
+ lastObservedAt: memory.lastObservedAt,
23445
+ eventTimeStart: memory.eventTimeStart,
23446
+ eventTimeEnd: memory.eventTimeEnd,
23447
+ eventTimeKind: memory.eventTimeKind === "point" || memory.eventTimeKind === "range" || memory.eventTimeKind === "ongoing" ? memory.eventTimeKind : null,
23448
+ factType: memory.factType,
23449
+ sourceChunkIds: memory.sourceChunkIds
23450
+ })),
23451
+ queryEmbedding,
23452
+ facetEmbeddings,
23453
+ vaultSize: Math.max(windows[0].total_count ?? 0, items.length),
23454
+ embeddingFailure: windows.some((window2) => (window2.unavailable_count ?? 0) > 0),
23455
+ embeddingsUnavailable: (windows[0].total_count ?? items.length) > 0 && !memories.some((memory) => memory.embedding),
23456
+ decryptLast: true,
23457
+ rowsDecrypted: items.length,
23458
+ queryEmbedMs,
23459
+ rowsEmbedded: 0
23460
+ };
23461
+ };
23462
+ const createRow = (input) => {
23463
+ if (input.folderId !== void 0 && input.folderId !== null)
23464
+ throw new Error("Remote memories do not support folders");
23465
+ const now = Date.now();
23466
+ return {
23467
+ memory_id: (0, import_uuid5.v7)(),
23468
+ content: input.content,
23469
+ scope: input.scope ?? "private",
23470
+ created_at: now,
23471
+ updated_at: now,
23472
+ is_deleted: false,
23473
+ ...input.embedding !== void 0 && {
23474
+ embedding: storedVector(JSON.parse(input.embedding)),
23475
+ embedding_model: input.embeddingModel
23476
+ },
23477
+ source_chunk_ids: JSON.stringify(input.sourceChunkIds ?? []),
23478
+ proof_count: input.proofCount ?? 1,
23479
+ source: input.source ?? "manual",
23480
+ ...input.eventTime && {
23481
+ event_time_start: input.eventTime.start ?? void 0,
23482
+ event_time_end: input.eventTime.end ?? void 0,
23483
+ event_time_kind: input.eventTime.kind ?? void 0
23484
+ },
23485
+ fact_type: input.factType,
23486
+ trust_tier: normalizeTrustTier(input.trustTier) ?? void 0,
23487
+ geohash: input.geohash,
23488
+ visibility: "private",
23489
+ twin_opt_in: false
23490
+ };
23491
+ };
23492
+ const write = async (memory, snapshot) => remember([await persistence.put(memory, snapshot)])[0];
23493
+ const port = {
23494
+ prepare,
23495
+ get,
23496
+ getFresh: async (id) => {
23497
+ const current = await persistence.get(id);
23498
+ return current && !current.memory.is_deleted && !current.memory.superseded_by ? stored(current.memory) : null;
23499
+ },
23500
+ tombstones: async (embedding, embeddingModel, scope, folderId) => {
23501
+ if (folderId !== void 0) throw new Error("Remote memories do not support folders");
23502
+ const window2 = await persistence.candidateSet(storedVector(embedding), {
23503
+ limit: 1,
23504
+ scopes: [scope],
23505
+ embedding_model: embeddingModel,
23506
+ strict_model: true,
23507
+ include_deleted: true,
23508
+ deleted_only: true
23509
+ });
23510
+ rejectUndecryptable(window2.failed);
23511
+ return remember(window2.items);
23512
+ },
23513
+ create: (input) => write(createRow(input), 0),
23514
+ update: async (id, patch) => {
23515
+ const existing = await get(id);
23516
+ if (!existing) return null;
23517
+ const snapshot = snapshots.get(id);
23518
+ const memory = {
23519
+ ...snapshot.memory,
23520
+ content: patch.content,
23521
+ updated_at: patch.preserveUpdatedAt ? snapshot.memory.updated_at : Date.now()
23522
+ };
23523
+ if (patch.scope !== void 0) memory.scope = patch.scope;
23524
+ if (patch.embedding === void 0 && patch.content !== snapshot.memory.content) {
23525
+ delete memory.embedding;
23526
+ delete memory.embedding_model;
23527
+ }
23528
+ if (patch.embedding !== void 0) {
23529
+ memory.embedding = patch.embedding === null ? [] : storedVector(JSON.parse(patch.embedding));
23530
+ memory.embedding_model = patch.embeddingModel ?? void 0;
23531
+ }
23532
+ const observed = sourceIds(memory.source_chunk_ids);
23533
+ const replay = !!patch.observationSourceIds?.length && patch.observationSourceIds.every((id2) => observed.includes(id2));
23534
+ if (patch.sourceChunkIds !== void 0)
23535
+ memory.source_chunk_ids = JSON.stringify(
23536
+ patch.observationSourceIds?.length ? [.../* @__PURE__ */ new Set([...observed, ...patch.sourceChunkIds])] : patch.sourceChunkIds
23537
+ );
23538
+ if (!replay) {
23539
+ if (patch.proofCountIncrement !== void 0)
23540
+ memory.proof_count = (memory.proof_count ?? 1) + patch.proofCountIncrement;
23541
+ else if (patch.proofCount !== void 0) memory.proof_count = patch.proofCount;
23542
+ if (patch.lastObservedAt !== void 0) memory.last_observed_at = patch.lastObservedAt;
23543
+ }
23544
+ if (patch.source !== void 0) memory.source = patch.source;
23545
+ if (patch.factType !== void 0) memory.fact_type = patch.factType;
23546
+ if (patch.trustTier !== void 0)
23547
+ memory.trust_tier = normalizeTrustTier(patch.trustTier) ?? void 0;
23548
+ if (patch.topicsUserManaged !== void 0)
23549
+ memory.topics_user_managed = patch.topicsUserManaged;
23550
+ if (patch.eventTime !== void 0) {
23551
+ memory.event_time_start = patch.eventTime.start ?? void 0;
23552
+ memory.event_time_end = patch.eventTime.end ?? void 0;
23553
+ memory.event_time_kind = patch.eventTime.kind ?? void 0;
23554
+ }
23555
+ if (patch.restore) memory.archived_at = void 0;
23556
+ return write(memory, snapshot);
23557
+ },
23558
+ supersede: async (id, successor) => {
23559
+ const [target, newer] = await Promise.all([get(id), get(successor)]);
23560
+ if (!target || !newer || id === successor) return false;
23561
+ const old = snapshots.get(id);
23562
+ const next = snapshots.get(successor);
23563
+ remember(
23564
+ await persistence.putMany([
23565
+ {
23566
+ memory: { ...old.memory, superseded_by: successor, superseded_at: Date.now() },
23567
+ expectedVersion: old
23568
+ },
23569
+ { memory: next.memory, expectedVersion: next }
23570
+ ])
23571
+ );
23572
+ return true;
23573
+ },
23574
+ createSuperseding: async (input, targetId) => {
23575
+ const target = await get(targetId);
23576
+ if (!target) return { created: null, retired: false };
23577
+ const snapshot = snapshots.get(targetId);
23578
+ const successor = createRow(input);
23579
+ const rows = remember(
23580
+ await persistence.putMany([
23581
+ { memory: successor, expectedVersion: 0 },
23582
+ {
23583
+ memory: {
23584
+ ...snapshot.memory,
23585
+ superseded_by: successor.memory_id,
23586
+ superseded_at: Date.now()
23587
+ },
23588
+ expectedVersion: snapshot
23589
+ }
23590
+ ])
23591
+ );
23592
+ return { created: rows[0], retired: true };
23593
+ }
23594
+ };
23595
+ return { prepare, port };
23596
+ };
23597
+ return {
23598
+ recall: async (query, recallOptions = {}) => {
23599
+ const { prepare } = operation("recall");
23600
+ return recall(
23601
+ query,
23602
+ {
23603
+ embeddingOptions,
23604
+ factSource: {
23605
+ graphRanking: options.graphRanking,
23606
+ temporalRanking: options.temporalRanking,
23607
+ search: async (text12, searchOptions) => {
23608
+ const prepared = await prepare(text12, searchOptions);
23609
+ const ranked = await rankPreparedVaultCandidates(
23610
+ text12,
23611
+ prepared,
23612
+ embeddingOptions,
23613
+ searchOptions
23614
+ );
23615
+ return {
23616
+ ...ranked,
23617
+ rankedOnCosine: prepared.memories.length > 0 && !prepared.embeddingsUnavailable,
23618
+ decryptLast: true,
23619
+ rowsDecrypted: prepared.rowsDecrypted,
23620
+ queryEmbedMs: prepared.queryEmbedMs,
23621
+ rowsEmbedded: 0
23622
+ };
23623
+ }
23624
+ }
23625
+ },
23626
+ { ...recallOptions, types: ["fact"] }
23627
+ );
23628
+ },
23629
+ retain: async (content, retainOptions) => {
23630
+ const { port } = operation("retain");
23631
+ return retainWithPersistence(
23632
+ content,
23633
+ {
23634
+ persistence: port,
23635
+ embeddingOptions,
23636
+ vaultCache: /* @__PURE__ */ new Map(),
23637
+ normalizeEmbedding: storedVector
23638
+ },
23639
+ retainOptions
23640
+ );
23641
+ }
23642
+ };
23643
+ }
23644
+
22842
23645
  // src/lib/memory/synthesizeProfile.ts
22843
23646
  init_internalFlowMarker();
22844
23647
  init_logger();
@@ -29098,7 +29901,7 @@ async function uploadFileToICloud(filename, content) {
29098
29901
  const recordName = `backup_${filename.replace(/[^a-zA-Z0-9]/g, "_")}`;
29099
29902
  const arrayBuffer = await content.arrayBuffer();
29100
29903
  const base64Data = uint8ArrayToBase64(new Uint8Array(arrayBuffer));
29101
- const record = {
29904
+ const record2 = {
29102
29905
  recordType: RECORD_TYPE,
29103
29906
  recordName,
29104
29907
  fields: {
@@ -29108,7 +29911,7 @@ async function uploadFileToICloud(filename, content) {
29108
29911
  contentType: { value: content.type || "application/json" }
29109
29912
  }
29110
29913
  };
29111
- const response = await database.saveRecords(record);
29914
+ const response = await database.saveRecords(record2);
29112
29915
  if (!response.records || response.records.length === 0) {
29113
29916
  throw new Error("Failed to upload file to iCloud");
29114
29917
  }
@@ -29134,11 +29937,11 @@ async function listICloudFiles() {
29134
29937
  while (response.continuationMarker) {
29135
29938
  break;
29136
29939
  }
29137
- const files = allRecords.map((record) => ({
29138
- recordName: record.recordName,
29139
- filename: record.fields.filename?.value ?? "",
29140
- modifiedAt: new Date(record.modified?.timestamp ?? Date.now()),
29141
- size: typeof record.fields.data?.value === "object" && record.fields.data?.value !== null ? record.fields.data.value.size : 0
29940
+ const files = allRecords.map((record2) => ({
29941
+ recordName: record2.recordName,
29942
+ filename: record2.fields.filename?.value ?? "",
29943
+ modifiedAt: new Date(record2.modified?.timestamp ?? Date.now()),
29944
+ size: typeof record2.fields.data?.value === "object" && record2.fields.data?.value !== null ? record2.fields.data.value.size : 0
29142
29945
  }));
29143
29946
  return files.sort((a, b) => b.modifiedAt.getTime() - a.modifiedAt.getTime());
29144
29947
  }
@@ -29151,8 +29954,8 @@ async function downloadICloudFile(recordName) {
29151
29954
  if (!response.records || response.records.length === 0) {
29152
29955
  throw new Error(`File not found: ${recordName}`);
29153
29956
  }
29154
- const record = response.records[0];
29155
- const dataField = record.fields.data?.value;
29957
+ const record2 = response.records[0];
29958
+ const dataField = record2.fields.data?.value;
29156
29959
  if (!dataField) {
29157
29960
  throw new Error("No data in record");
29158
29961
  }
@@ -29186,12 +29989,12 @@ async function findICloudFile(filename) {
29186
29989
  if (!response.records || response.records.length === 0) {
29187
29990
  return null;
29188
29991
  }
29189
- const record = response.records[0];
29992
+ const record2 = response.records[0];
29190
29993
  return {
29191
- recordName: record.recordName,
29192
- filename: record.fields.filename?.value ?? "",
29193
- modifiedAt: new Date(record.modified?.timestamp ?? Date.now()),
29194
- size: typeof record.fields.data?.value === "object" && record.fields.data?.value !== null ? record.fields.data.value.size : 0
29994
+ recordName: record2.recordName,
29995
+ filename: record2.fields.filename?.value ?? "",
29996
+ modifiedAt: new Date(record2.modified?.timestamp ?? Date.now()),
29997
+ size: typeof record2.fields.data?.value === "object" && record2.fields.data?.value !== null ? record2.fields.data.value.size : 0
29195
29998
  };
29196
29999
  }
29197
30000
 
@@ -29346,8 +30149,8 @@ async function getStoredTokenData5(provider, walletAddress) {
29346
30149
  return null;
29347
30150
  }
29348
30151
  }
29349
- async function readTokenRow(stored, provider, walletAddress) {
29350
- if (stored.startsWith(ENCRYPTED_PREFIX6)) {
30152
+ async function readTokenRow(stored2, provider, walletAddress) {
30153
+ if (stored2.startsWith(ENCRYPTED_PREFIX6)) {
29351
30154
  if (!walletAddress) {
29352
30155
  getLogger().warn(
29353
30156
  `Encrypted OAuth token found for ${provider} but no wallet address provided`
@@ -29355,7 +30158,7 @@ async function readTokenRow(stored, provider, walletAddress) {
29355
30158
  return null;
29356
30159
  }
29357
30160
  try {
29358
- const encryptedData = stored.slice(ENCRYPTED_PREFIX6.length);
30161
+ const encryptedData = stored2.slice(ENCRYPTED_PREFIX6.length);
29359
30162
  let decryptedJson;
29360
30163
  try {
29361
30164
  decryptedJson = await decryptData(encryptedData, walletAddress);
@@ -29370,7 +30173,7 @@ async function readTokenRow(stored, provider, walletAddress) {
29370
30173
  return null;
29371
30174
  }
29372
30175
  }
29373
- return parsePlaintextToken(stored, walletAddress);
30176
+ return parsePlaintextToken(stored2, walletAddress);
29374
30177
  }
29375
30178
  async function storeTokenData5(provider, data, walletAddress) {
29376
30179
  if (typeof window === "undefined") return;
@@ -29446,8 +30249,8 @@ async function migrateUnencryptedTokens(provider, walletAddress) {
29446
30249
  const keys = [scopedKey, legacyKey];
29447
30250
  const isEncrypted2 = (value) => !!value && value.startsWith(ENCRYPTED_PREFIX6);
29448
30251
  const plaintextAt = (key) => {
29449
- const stored = sessionStorage.getItem(key) ?? localStorage.getItem(key);
29450
- return stored && !isEncrypted2(stored) ? stored : null;
30252
+ const stored2 = sessionStorage.getItem(key) ?? localStorage.getItem(key);
30253
+ return stored2 && !isEncrypted2(stored2) ? stored2 : null;
29451
30254
  };
29452
30255
  let tokenToMigrate = null;
29453
30256
  for (const key of keys) {
@@ -29459,8 +30262,8 @@ async function migrateUnencryptedTokens(provider, walletAddress) {
29459
30262
  }
29460
30263
  if (!tokenToMigrate) {
29461
30264
  for (const key of keys) {
29462
- const stored = sessionStorage.getItem(key);
29463
- if (isEncrypted2(localStorage.getItem(key)) && stored && !isEncrypted2(stored)) {
30265
+ const stored2 = sessionStorage.getItem(key);
30266
+ if (isEncrypted2(localStorage.getItem(key)) && stored2 && !isEncrypted2(stored2)) {
29464
30267
  sessionStorage.removeItem(key);
29465
30268
  }
29466
30269
  }
@@ -29516,17 +30319,17 @@ function storeOAuthState2(state) {
29516
30319
  }
29517
30320
  function getAndClearOAuthState4() {
29518
30321
  if (typeof window === "undefined") return null;
29519
- const stored = sessionStorage.getItem(STATE_STORAGE_KEY);
30322
+ const stored2 = sessionStorage.getItem(STATE_STORAGE_KEY);
29520
30323
  sessionStorage.removeItem(STATE_STORAGE_KEY);
29521
- if (!stored) return null;
30324
+ if (!stored2) return null;
29522
30325
  try {
29523
- const parsed = JSON.parse(stored);
30326
+ const parsed = JSON.parse(stored2);
29524
30327
  if (parsed && typeof parsed === "object" && "state" in parsed) {
29525
30328
  return parsed.state;
29526
30329
  }
29527
30330
  } catch {
29528
30331
  }
29529
- return stored;
30332
+ return stored2;
29530
30333
  }
29531
30334
  function isDropboxCallback() {
29532
30335
  if (typeof window === "undefined") return false;
@@ -29710,17 +30513,17 @@ function storeOAuthState3(state) {
29710
30513
  }
29711
30514
  function getAndClearOAuthState5() {
29712
30515
  if (typeof window === "undefined") return null;
29713
- const stored = sessionStorage.getItem(CODE_STORAGE_KEY4);
30516
+ const stored2 = sessionStorage.getItem(CODE_STORAGE_KEY4);
29714
30517
  sessionStorage.removeItem(CODE_STORAGE_KEY4);
29715
- if (!stored) return null;
30518
+ if (!stored2) return null;
29716
30519
  try {
29717
- const parsed = JSON.parse(stored);
30520
+ const parsed = JSON.parse(stored2);
29718
30521
  if (parsed && typeof parsed === "object" && "state" in parsed) {
29719
30522
  return parsed.state;
29720
30523
  }
29721
30524
  } catch {
29722
30525
  }
29723
- return stored;
30526
+ return stored2;
29724
30527
  }
29725
30528
  function isGoogleDriveCallback() {
29726
30529
  if (typeof window === "undefined") return false;
@@ -31664,18 +32467,18 @@ async function blobToDataUri(blob) {
31664
32467
  reader.readAsDataURL(blob);
31665
32468
  });
31666
32469
  }
31667
- async function storedToLlmapiMessage(stored, encryptionKey, resolveMediaByIds) {
31668
- let textContent = stored.content;
32470
+ async function storedToLlmapiMessage(stored2, encryptionKey, resolveMediaByIds) {
32471
+ let textContent = stored2.content;
31669
32472
  const fileUrlMap = /* @__PURE__ */ new Map();
31670
32473
  const imageParts = [];
31671
- if (stored.role !== "assistant" && stored.files?.length) {
31672
- for (const file of stored.files) {
32474
+ if (stored2.role !== "assistant" && stored2.files?.length) {
32475
+ for (const file of stored2.files) {
31673
32476
  if (isSendableImageURL(file.url)) {
31674
32477
  imageParts.push({
31675
32478
  type: "image_url",
31676
32479
  image_url: { url: file.url }
31677
32480
  });
31678
- } else if (file.sourceUrl && !isR2UrlExpired(file.sourceUrl, stored.createdAt)) {
32481
+ } else if (file.sourceUrl && !isR2UrlExpired(file.sourceUrl, stored2.createdAt)) {
31679
32482
  imageParts.push({
31680
32483
  type: "image_url",
31681
32484
  image_url: { url: file.sourceUrl }
@@ -31695,11 +32498,11 @@ async function storedToLlmapiMessage(stored, encryptionKey, resolveMediaByIds) {
31695
32498
  }
31696
32499
  }
31697
32500
  }
31698
- } else if (stored.role === "assistant" && stored.files?.length) {
32501
+ } else if (stored2.role === "assistant" && stored2.files?.length) {
31699
32502
  const expiredFileIds = [];
31700
- for (const file of stored.files) {
32503
+ for (const file of stored2.files) {
31701
32504
  if (file.sourceUrl) {
31702
- if (!isR2UrlExpired(file.sourceUrl, stored.createdAt)) {
32505
+ if (!isR2UrlExpired(file.sourceUrl, stored2.createdAt)) {
31703
32506
  fileUrlMap.set(file.id, file.sourceUrl);
31704
32507
  } else {
31705
32508
  expiredFileIds.push(file.id);
@@ -31712,11 +32515,11 @@ async function storedToLlmapiMessage(stored, encryptionKey, resolveMediaByIds) {
31712
32515
  [${expiredFileIds.length} expired image URL${expiredFileIds.length > 1 ? "s" : ""} omitted \u2014 the user can still see ${expiredFileIds.length > 1 ? "them" : "it"} locally]`;
31713
32516
  }
31714
32517
  }
31715
- if (stored.fileIds?.length && resolveMediaByIds) {
32518
+ if (stored2.fileIds?.length && resolveMediaByIds) {
31716
32519
  try {
31717
- const mediaItems = await resolveMediaByIds(stored.fileIds);
32520
+ const mediaItems = await resolveMediaByIds(stored2.fileIds);
31718
32521
  for (const media of mediaItems) {
31719
- if (media.sourceUrl && !isR2UrlExpired(media.sourceUrl, stored.createdAt)) {
32522
+ if (media.sourceUrl && !isR2UrlExpired(media.sourceUrl, stored2.createdAt)) {
31720
32523
  fileUrlMap.set(media.mediaId, media.sourceUrl);
31721
32524
  }
31722
32525
  }
@@ -31740,7 +32543,7 @@ async function storedToLlmapiMessage(stored, encryptionKey, resolveMediaByIds) {
31740
32543
  return "";
31741
32544
  }
31742
32545
  );
31743
- if (stored.role === "assistant" && fileUrlMap.size > 0) {
32546
+ if (stored2.role === "assistant" && fileUrlMap.size > 0) {
31744
32547
  const unreferencedImages = [...fileUrlMap.entries()].filter(
31745
32548
  ([, url]) => !textContent.includes(url)
31746
32549
  );
@@ -31752,11 +32555,11 @@ async function storedToLlmapiMessage(stored, encryptionKey, resolveMediaByIds) {
31752
32555
  textContent = textContent.replace(/\n{3,}/g, "\n\n").trim();
31753
32556
  const content = [{ type: "text", text: textContent }, ...imageParts];
31754
32557
  const messages = [];
31755
- if (stored.role === "assistant" && stored.toolCallEvents?.length) {
32558
+ if (stored2.role === "assistant" && stored2.toolCallEvents?.length) {
31756
32559
  messages.push({
31757
- role: stored.role,
32560
+ role: stored2.role,
31758
32561
  content: void 0,
31759
- tool_calls: stored.toolCallEvents.map((event) => ({
32562
+ tool_calls: stored2.toolCallEvents.map((event) => ({
31760
32563
  id: event.id,
31761
32564
  type: "function",
31762
32565
  function: {
@@ -31765,7 +32568,7 @@ async function storedToLlmapiMessage(stored, encryptionKey, resolveMediaByIds) {
31765
32568
  }
31766
32569
  }))
31767
32570
  });
31768
- for (const event of stored.toolCallEvents) {
32571
+ for (const event of stored2.toolCallEvents) {
31769
32572
  if (event.id && event.output !== void 0 && event.output !== null) {
31770
32573
  messages.push({
31771
32574
  role: "tool",
@@ -31776,12 +32579,12 @@ async function storedToLlmapiMessage(stored, encryptionKey, resolveMediaByIds) {
31776
32579
  }
31777
32580
  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();
31778
32581
  messages.push({
31779
- role: stored.role,
32582
+ role: stored2.role,
31780
32583
  content: [{ type: "text", text: postToolText }]
31781
32584
  });
31782
32585
  } else {
31783
32586
  messages.push({
31784
- role: stored.role,
32587
+ role: stored2.role,
31785
32588
  content
31786
32589
  });
31787
32590
  }
@@ -35600,19 +36403,19 @@ function startObserve(entry, walletAddress) {
35600
36403
  "updated_at"
35601
36404
  ]).subscribe({
35602
36405
  next: (records) => {
35603
- const record = records[0];
35604
- if (!record) return;
36406
+ const record2 = records[0];
36407
+ if (!record2) return;
35605
36408
  const patch = {
35606
36409
  userPreference: {
35607
- uniqueId: record.id,
35608
- walletAddress: record.walletAddress,
35609
- nickname: record.nickname,
35610
- occupation: record.occupation,
35611
- description: record.description,
35612
- models: record.models,
35613
- personality: record.personality,
35614
- createdAt: record.createdAt,
35615
- updatedAt: record.updatedAt
36410
+ uniqueId: record2.id,
36411
+ walletAddress: record2.walletAddress,
36412
+ nickname: record2.nickname,
36413
+ occupation: record2.occupation,
36414
+ description: record2.description,
36415
+ models: record2.models,
36416
+ personality: record2.personality,
36417
+ createdAt: record2.createdAt,
36418
+ updatedAt: record2.updatedAt
35616
36419
  }
35617
36420
  };
35618
36421
  if (isInitialEmission) {
@@ -36831,6 +37634,7 @@ function useWalletBinding(options = {}) {
36831
37634
  R2_DEFAULT_TTL_MS,
36832
37635
  RECALL_MAX_LIMIT,
36833
37636
  RECALL_TOOL_NAME,
37637
+ RemoteMemoryError,
36834
37638
  RerankerUnavailableError,
36835
37639
  SDK_SCHEMA_VERSION,
36836
37640
  SERVER_TOOL_DEPENDENCY_SETS,
@@ -36922,6 +37726,8 @@ function useWalletBinding(options = {}) {
36922
37726
  createPlatformCursorStore,
36923
37727
  createProjectOp,
36924
37728
  createRecallTool,
37729
+ createRemoteMemoryPersistence,
37730
+ createRemoteMemoryPipeline,
36925
37731
  createSavedToolOp,
36926
37732
  createServerToolsFilter,
36927
37733
  createStockPricePreProcessor,