@anuma/sdk 6.33.2 → 6.35.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1424,7 +1424,10 @@ __export(index_exports, {
1424
1424
  LoggerProvider: () => LoggerProvider,
1425
1425
  MAX_HOPS: () => MAX_HOPS,
1426
1426
  MEDIUM_TTL_MS: () => MEDIUM_TTL_MS,
1427
+ MEMORY_KINDS: () => MEMORY_KINDS,
1428
+ MEMORY_LEVELS: () => MEMORY_LEVELS,
1427
1429
  MemoryEntityModel: () => MemoryEntity,
1430
+ MemoryLevelError: () => MemoryLevelError,
1428
1431
  NEVER_TTL_MS: () => NEVER_TTL_MS,
1429
1432
  NODE_BUDGET: () => NODE_BUDGET,
1430
1433
  PAST_EVENT_GRACE_MS: () => PAST_EVENT_GRACE_MS,
@@ -1437,6 +1440,7 @@ __export(index_exports, {
1437
1440
  R2_DEFAULT_TTL_MS: () => R2_DEFAULT_TTL_MS,
1438
1441
  RECALL_MAX_LIMIT: () => RECALL_MAX_LIMIT,
1439
1442
  RECALL_TOOL_NAME: () => RECALL_TOOL_NAME,
1443
+ RemoteMemoryError: () => RemoteMemoryError,
1440
1444
  RerankerUnavailableError: () => RerankerUnavailableError,
1441
1445
  SDK_SCHEMA_VERSION: () => SDK_SCHEMA_VERSION,
1442
1446
  SERVER_TOOL_DEPENDENCY_SETS: () => SERVER_TOOL_DEPENDENCY_SETS,
@@ -1528,6 +1532,8 @@ __export(index_exports, {
1528
1532
  createPlatformCursorStore: () => createPlatformCursorStore,
1529
1533
  createProjectOp: () => createProjectOp,
1530
1534
  createRecallTool: () => createRecallTool,
1535
+ createRemoteMemoryPersistence: () => createRemoteMemoryPersistence,
1536
+ createRemoteMemoryPipeline: () => createRemoteMemoryPipeline,
1531
1537
  createSavedToolOp: () => createSavedToolOp,
1532
1538
  createServerToolsFilter: () => createServerToolsFilter,
1533
1539
  createStockPricePreProcessor: () => createStockPricePreProcessor,
@@ -3554,10 +3560,10 @@ function parsePlaintextToken(raw, walletAddress) {
3554
3560
  return null;
3555
3561
  }
3556
3562
  if (!parsed || typeof parsed !== "object") return null;
3557
- const record = parsed;
3558
- const data = record.token?.accessToken ? record.token : record;
3563
+ const record2 = parsed;
3564
+ const data = record2.token?.accessToken ? record2.token : record2;
3559
3565
  if (!data?.accessToken) return null;
3560
- if (record.wallet && record.wallet !== walletAddress) return null;
3566
+ if (record2.wallet && record2.wallet !== walletAddress) return null;
3561
3567
  return data;
3562
3568
  }
3563
3569
  function promoteUnscopedRow(raw, data, store, scopedKey, unscopedKey, walletAddress) {
@@ -3681,8 +3687,8 @@ async function storeTokenData(data, walletAddress) {
3681
3687
  getLogger().warn("Failed to encrypt GitHub OAuth token:", error);
3682
3688
  }
3683
3689
  }
3684
- const record = { wallet: walletAddress, token: data };
3685
- sessionStorage.setItem(getTokenStorageKey(walletAddress), JSON.stringify(record));
3690
+ const record2 = { wallet: walletAddress, token: data };
3691
+ sessionStorage.setItem(getTokenStorageKey(walletAddress), JSON.stringify(record2));
3686
3692
  }
3687
3693
  function clearGithubToken(walletAddress) {
3688
3694
  if (typeof window === "undefined") return;
@@ -3731,17 +3737,17 @@ function storeOAuthState(state) {
3731
3737
  }
3732
3738
  function getAndClearOAuthState() {
3733
3739
  if (typeof window === "undefined") return null;
3734
- const stored = sessionStorage.getItem(CODE_STORAGE_KEY);
3740
+ const stored2 = sessionStorage.getItem(CODE_STORAGE_KEY);
3735
3741
  sessionStorage.removeItem(CODE_STORAGE_KEY);
3736
- if (!stored) return null;
3742
+ if (!stored2) return null;
3737
3743
  try {
3738
- const parsed = JSON.parse(stored);
3744
+ const parsed = JSON.parse(stored2);
3739
3745
  if (parsed && typeof parsed === "object" && "state" in parsed) {
3740
3746
  return parsed.state;
3741
3747
  }
3742
3748
  } catch {
3743
3749
  }
3744
- return stored;
3750
+ return stored2;
3745
3751
  }
3746
3752
  function isGithubCallback(callbackPath) {
3747
3753
  if (typeof window === "undefined") return false;
@@ -4034,8 +4040,8 @@ async function storeTokenData2(data, walletAddress) {
4034
4040
  getLogger().warn("Failed to encrypt Calendar OAuth token:", error);
4035
4041
  }
4036
4042
  }
4037
- const record = { wallet: walletAddress, token: data };
4038
- sessionStorage.setItem(getTokenStorageKey2(walletAddress), JSON.stringify(record));
4043
+ const record2 = { wallet: walletAddress, token: data };
4044
+ sessionStorage.setItem(getTokenStorageKey2(walletAddress), JSON.stringify(record2));
4039
4045
  }
4040
4046
  function clearCalendarToken(walletAddress) {
4041
4047
  if (typeof window === "undefined") return;
@@ -4075,17 +4081,17 @@ function getRedirectUri2(callbackPath) {
4075
4081
  }
4076
4082
  function getAndClearOAuthState2() {
4077
4083
  if (typeof window === "undefined") return null;
4078
- const stored = sessionStorage.getItem(CODE_STORAGE_KEY2);
4084
+ const stored2 = sessionStorage.getItem(CODE_STORAGE_KEY2);
4079
4085
  sessionStorage.removeItem(CODE_STORAGE_KEY2);
4080
- if (!stored) return null;
4086
+ if (!stored2) return null;
4081
4087
  try {
4082
- const parsed = JSON.parse(stored);
4088
+ const parsed = JSON.parse(stored2);
4083
4089
  if (parsed && typeof parsed === "object" && "state" in parsed) {
4084
4090
  return parsed.state;
4085
4091
  }
4086
4092
  } catch {
4087
4093
  }
4088
- return stored;
4094
+ return stored2;
4089
4095
  }
4090
4096
  function isCalendarCallback(callbackPath) {
4091
4097
  if (typeof window === "undefined") return false;
@@ -4360,8 +4366,8 @@ async function storeTokenData3(data, walletAddress) {
4360
4366
  getLogger().warn("Failed to encrypt Drive OAuth token:", error);
4361
4367
  }
4362
4368
  }
4363
- const record = { wallet: walletAddress, token: data };
4364
- sessionStorage.setItem(getTokenStorageKey3(walletAddress), JSON.stringify(record));
4369
+ const record2 = { wallet: walletAddress, token: data };
4370
+ sessionStorage.setItem(getTokenStorageKey3(walletAddress), JSON.stringify(record2));
4365
4371
  }
4366
4372
  function clearDriveToken(walletAddress) {
4367
4373
  if (typeof window === "undefined") return;
@@ -4401,17 +4407,17 @@ function getRedirectUri3(callbackPath) {
4401
4407
  }
4402
4408
  function getAndClearOAuthState3() {
4403
4409
  if (typeof window === "undefined") return null;
4404
- const stored = sessionStorage.getItem(CODE_STORAGE_KEY3);
4410
+ const stored2 = sessionStorage.getItem(CODE_STORAGE_KEY3);
4405
4411
  sessionStorage.removeItem(CODE_STORAGE_KEY3);
4406
- if (!stored) return null;
4412
+ if (!stored2) return null;
4407
4413
  try {
4408
- const parsed = JSON.parse(stored);
4414
+ const parsed = JSON.parse(stored2);
4409
4415
  if (parsed && typeof parsed === "object" && "state" in parsed) {
4410
4416
  return parsed.state;
4411
4417
  }
4412
4418
  } catch {
4413
4419
  }
4414
- return stored;
4420
+ return stored2;
4415
4421
  }
4416
4422
  function isDriveCallback(callbackPath) {
4417
4423
  if (typeof window === "undefined") return false;
@@ -4741,11 +4747,11 @@ function storePKCEState(pkce) {
4741
4747
  }
4742
4748
  function getAndClearPKCEState() {
4743
4749
  if (typeof window === "undefined") return null;
4744
- const stored = sessionStorage.getItem(PKCE_STORAGE_KEY);
4750
+ const stored2 = sessionStorage.getItem(PKCE_STORAGE_KEY);
4745
4751
  sessionStorage.removeItem(PKCE_STORAGE_KEY);
4746
- if (!stored) return null;
4752
+ if (!stored2) return null;
4747
4753
  try {
4748
- return JSON.parse(stored);
4754
+ return JSON.parse(stored2);
4749
4755
  } catch {
4750
4756
  return null;
4751
4757
  }
@@ -4763,8 +4769,8 @@ async function storeTokenData4(data, walletAddress) {
4763
4769
  } catch {
4764
4770
  }
4765
4771
  }
4766
- const record = { wallet: walletAddress, token: data };
4767
- sessionStorage.setItem(getTokenStorageKey4(walletAddress), JSON.stringify(record));
4772
+ const record2 = { wallet: walletAddress, token: data };
4773
+ sessionStorage.setItem(getTokenStorageKey4(walletAddress), JSON.stringify(record2));
4768
4774
  }
4769
4775
  async function getStoredTokenData4(walletAddress) {
4770
4776
  if (typeof window === "undefined") return null;
@@ -4780,12 +4786,12 @@ async function getStoredTokenData4(walletAddress) {
4780
4786
  cachedWalletAddress4 = null;
4781
4787
  }
4782
4788
  try {
4783
- const stored = localStorage.getItem(getTokenStorageKey4(walletAddress));
4784
- if (stored?.startsWith(ENCRYPTED_PREFIX5)) {
4789
+ const stored2 = localStorage.getItem(getTokenStorageKey4(walletAddress));
4790
+ if (stored2?.startsWith(ENCRYPTED_PREFIX5)) {
4785
4791
  if (walletAddress && hasEncryptionKey(walletAddress)) {
4786
4792
  try {
4787
4793
  const cryptoKey = await getEncryptionKey(walletAddress);
4788
- const encrypted = stored.slice(ENCRYPTED_PREFIX5.length);
4794
+ const encrypted = stored2.slice(ENCRYPTED_PREFIX5.length);
4789
4795
  const decrypted = await decryptDataWithKey(encrypted, cryptoKey);
4790
4796
  const data = JSON.parse(decrypted);
4791
4797
  if (data.accessToken) return data;
@@ -4894,12 +4900,12 @@ async function getClientRegistration(walletAddress) {
4894
4900
  if (typeof window === "undefined") return null;
4895
4901
  try {
4896
4902
  const scopedKey = getClientRegistrationStorageKey(walletAddress);
4897
- const stored = localStorage.getItem(scopedKey);
4898
- if (stored?.startsWith(ENCRYPTED_PREFIX5)) {
4903
+ const stored2 = localStorage.getItem(scopedKey);
4904
+ if (stored2?.startsWith(ENCRYPTED_PREFIX5)) {
4899
4905
  if (walletAddress && hasEncryptionKey(walletAddress)) {
4900
4906
  try {
4901
4907
  const cryptoKey = await getEncryptionKey(walletAddress);
4902
- const encrypted = stored.slice(ENCRYPTED_PREFIX5.length);
4908
+ const encrypted = stored2.slice(ENCRYPTED_PREFIX5.length);
4903
4909
  const decrypted = await decryptDataWithKey(encrypted, cryptoKey);
4904
4910
  const data = JSON.parse(decrypted);
4905
4911
  if (data.clientId) {
@@ -4909,8 +4915,8 @@ async function getClientRegistration(walletAddress) {
4909
4915
  }
4910
4916
  }
4911
4917
  }
4912
- if (stored && !stored.startsWith(ENCRYPTED_PREFIX5)) {
4913
- const data = JSON.parse(stored);
4918
+ if (stored2 && !stored2.startsWith(ENCRYPTED_PREFIX5)) {
4919
+ const data = JSON.parse(stored2);
4914
4920
  if (!data.clientId) return null;
4915
4921
  return data;
4916
4922
  }
@@ -6755,13 +6761,13 @@ async function searchMessagesOp(ctx, queryVector, options) {
6755
6761
  const topK = candidates.sort((a, b) => b.similarity - a.similarity).slice(0, limit);
6756
6762
  return Promise.all(
6757
6763
  topK.map(async ({ message, similarity }) => {
6758
- const stored = await messageRawToStored(
6764
+ const stored2 = await messageRawToStored(
6759
6765
  message,
6760
6766
  ctx.walletAddress,
6761
6767
  ctx.signMessage,
6762
6768
  ctx.embeddedWalletSigner
6763
6769
  );
6764
- return { ...stored, similarity };
6770
+ return { ...stored2, similarity };
6765
6771
  })
6766
6772
  );
6767
6773
  }
@@ -6865,13 +6871,13 @@ async function searchChunksOp(ctx, queryVector, options) {
6865
6871
  const storedById = new Map(
6866
6872
  await Promise.all(
6867
6873
  Array.from(uniqueMessages, async ([id, m]) => {
6868
- const stored = await messageRawToStored(
6874
+ const stored2 = await messageRawToStored(
6869
6875
  m,
6870
6876
  ctx.walletAddress,
6871
6877
  ctx.signMessage,
6872
6878
  ctx.embeddedWalletSigner
6873
6879
  );
6874
- return [id, stored];
6880
+ return [id, stored2];
6875
6881
  })
6876
6882
  )
6877
6883
  );
@@ -6889,18 +6895,18 @@ async function searchChunksOp(ctx, queryVector, options) {
6889
6895
  })
6890
6896
  );
6891
6897
  return topK.map(({ message, similarity, chunkTextSource }) => {
6892
- const stored = { ...storedById.get(message.id) };
6898
+ const stored2 = { ...storedById.get(message.id) };
6893
6899
  let chunkText2;
6894
6900
  if (chunkTextSource.kind === "chunk") {
6895
- chunkText2 = resolveChunkText(stored.content, chunkTextSource.chunk, chunkTextSource.siblings);
6901
+ chunkText2 = resolveChunkText(stored2.content, chunkTextSource.chunk, chunkTextSource.siblings);
6896
6902
  } else if (chunkTextSource.kind === "chunk-cached") {
6897
6903
  const state = chunkStateByMsgId.get(message.id);
6898
6904
  const chunk = state && state.version === chunkTextSource.version ? state.chunks[chunkTextSource.chunkIndex] : void 0;
6899
- chunkText2 = resolveChunkText(stored.content, chunk, state?.chunks);
6905
+ chunkText2 = resolveChunkText(stored2.content, chunk, state?.chunks);
6900
6906
  } else {
6901
- chunkText2 = stored.content;
6907
+ chunkText2 = stored2.content;
6902
6908
  }
6903
- return { chunkText: chunkText2, message: stored, similarity };
6909
+ return { chunkText: chunkText2, message: stored2, similarity };
6904
6910
  });
6905
6911
  }
6906
6912
  async function getAllFilesOp(ctx, options) {
@@ -7250,7 +7256,7 @@ async function embedOne(text12, options, outer) {
7250
7256
  }
7251
7257
  var DEFAULT_EMBEDDING_BATCH_SIZE = 100;
7252
7258
  var DEFAULT_EMBEDDING_BATCH_CONCURRENCY = 3;
7253
- async function generateEmbeddingsBatch(texts, headers, baseUrl, model, onUsage, maskInput, timeoutMs) {
7259
+ async function generateEmbeddingsBatch(texts, headers, baseUrl, model, onUsage, maskInput, timeoutMs, outer) {
7254
7260
  const response = await withEmbeddingRetry(
7255
7261
  () => withDeadline(
7256
7262
  (signal) => postApiV1Embeddings({
@@ -7260,8 +7266,10 @@ async function generateEmbeddingsBatch(texts, headers, baseUrl, model, onUsage,
7260
7266
  ...signal && { signal }
7261
7267
  }),
7262
7268
  timeoutMs,
7263
- "embedding batch request"
7264
- )
7269
+ "embedding batch request",
7270
+ outer
7271
+ ),
7272
+ outer
7265
7273
  );
7266
7274
  if (response.error) {
7267
7275
  throw embeddingErrorFrom(response);
@@ -7279,6 +7287,11 @@ async function generateEmbeddingsBatch(texts, headers, baseUrl, model, onUsage,
7279
7287
  }
7280
7288
  async function generateEmbeddings(texts, options) {
7281
7289
  if (texts.length === 0) return [];
7290
+ const total = options.totalTimeoutMs;
7291
+ if (total === void 0) return embedMany(texts, options, void 0);
7292
+ return withDeadline((signal) => embedMany(texts, options, signal), total, "embedding batch");
7293
+ }
7294
+ async function embedMany(texts, options, outer) {
7282
7295
  const { baseUrl = BASE_URL, model, batchSize, cache } = options;
7283
7296
  const timeoutMs = options.timeoutMs ?? DEFAULT_EMBEDDING_REQUEST_TIMEOUT_MS;
7284
7297
  const chunkSize = batchSize ?? DEFAULT_EMBEDDING_BATCH_SIZE;
@@ -7299,7 +7312,8 @@ async function generateEmbeddings(texts, options) {
7299
7312
  if (uncachedTexts.length === 0) {
7300
7313
  return results;
7301
7314
  }
7302
- const headers = await resolveAuthHeaders(options);
7315
+ const headers = await resolveAuthHeaders(options, outer);
7316
+ if (outer?.aborted) throw outer.reason;
7303
7317
  const embeddingModel = model ?? DEFAULT_API_EMBEDDING_MODEL;
7304
7318
  let newEmbeddings;
7305
7319
  if (uncachedTexts.length <= chunkSize) {
@@ -7310,7 +7324,8 @@ async function generateEmbeddings(texts, options) {
7310
7324
  embeddingModel,
7311
7325
  options.onUsage,
7312
7326
  options.maskInput,
7313
- timeoutMs
7327
+ timeoutMs,
7328
+ outer
7314
7329
  );
7315
7330
  } else {
7316
7331
  const chunks = [];
@@ -7321,6 +7336,7 @@ async function generateEmbeddings(texts, options) {
7321
7336
  let nextIndex = 0;
7322
7337
  const worker = async () => {
7323
7338
  while (nextIndex < chunks.length) {
7339
+ if (outer?.aborted) throw outer.reason;
7324
7340
  const idx = nextIndex++;
7325
7341
  allEmbeddings[idx] = await generateEmbeddingsBatch(
7326
7342
  chunks[idx],
@@ -7329,7 +7345,8 @@ async function generateEmbeddings(texts, options) {
7329
7345
  embeddingModel,
7330
7346
  options.onUsage,
7331
7347
  options.maskInput,
7332
- timeoutMs
7348
+ timeoutMs,
7349
+ outer
7333
7350
  );
7334
7351
  }
7335
7352
  };
@@ -7340,6 +7357,7 @@ async function generateEmbeddings(texts, options) {
7340
7357
  await Promise.all(workers);
7341
7358
  newEmbeddings = allEmbeddings.flat();
7342
7359
  }
7360
+ if (outer?.aborted) throw outer.reason;
7343
7361
  for (let i = 0; i < uncachedIndices.length; i++) {
7344
7362
  const f32Embedding = Float32Array.from(newEmbeddings[i]);
7345
7363
  results[uncachedIndices[i]] = Array.from(f32Embedding);
@@ -12513,15 +12531,15 @@ function createSummaryContext(database) {
12513
12531
  summariesCollection: database.get("conversation_summaries")
12514
12532
  };
12515
12533
  }
12516
- function modelToStored(record) {
12534
+ function modelToStored(record2) {
12517
12535
  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
12536
+ uniqueId: record2.id,
12537
+ conversationId: record2.conversationId,
12538
+ summary: record2.summary,
12539
+ summarizedUpTo: record2.summarizedUpTo,
12540
+ tokenCount: record2.tokenCount,
12541
+ createdAt: record2.createdAt,
12542
+ updatedAt: record2.updatedAt
12525
12543
  };
12526
12544
  }
12527
12545
  async function getConversationSummaryOp(ctx, conversationId) {
@@ -12530,17 +12548,17 @@ async function getConversationSummaryOp(ctx, conversationId) {
12530
12548
  return modelToStored(results[0]);
12531
12549
  }
12532
12550
  async function upsertConversationSummaryOp(ctx, conversationId, summary, summarizedUpTo, tokenCount) {
12533
- let record;
12551
+ let record2;
12534
12552
  await ctx.database.write(async () => {
12535
12553
  const existing = await ctx.summariesCollection.query(import_watermelondb7.Q.where("conversation_id", conversationId)).fetch();
12536
12554
  if (existing.length > 0) {
12537
- record = await existing[0].update((rec) => {
12555
+ record2 = await existing[0].update((rec) => {
12538
12556
  rec.summary = summary;
12539
12557
  rec.summarizedUpTo = summarizedUpTo;
12540
12558
  rec.tokenCount = tokenCount;
12541
12559
  });
12542
12560
  } else {
12543
- record = await ctx.summariesCollection.create((rec) => {
12561
+ record2 = await ctx.summariesCollection.create((rec) => {
12544
12562
  rec.conversationId = conversationId;
12545
12563
  rec.summary = summary;
12546
12564
  rec.summarizedUpTo = summarizedUpTo;
@@ -12548,13 +12566,13 @@ async function upsertConversationSummaryOp(ctx, conversationId, summary, summari
12548
12566
  });
12549
12567
  }
12550
12568
  });
12551
- return modelToStored(record);
12569
+ return modelToStored(record2);
12552
12570
  }
12553
12571
  async function deleteConversationSummaryOp(ctx, conversationId) {
12554
12572
  await ctx.database.write(async () => {
12555
12573
  const existing = await ctx.summariesCollection.query(import_watermelondb7.Q.where("conversation_id", conversationId)).fetch();
12556
- for (const record of existing) {
12557
- await record.destroyPermanently();
12574
+ for (const record2 of existing) {
12575
+ await record2.destroyPermanently();
12558
12576
  }
12559
12577
  });
12560
12578
  }
@@ -12747,25 +12765,25 @@ async function upsertEntitiesInWrite(ctx, entities) {
12747
12765
  const kindBackfills = existing.filter((e) => {
12748
12766
  const incoming = kindByName.get(e.canonicalName);
12749
12767
  return incoming !== void 0 && (e.kind === null || e.kind === void 0 || e.kind === "");
12750
- }).map((record) => ({ record, kind: kindByName.get(record.canonicalName) }));
12768
+ }).map((record2) => ({ record: record2, kind: kindByName.get(record2.canonicalName) }));
12751
12769
  const missing = unique.filter((n) => !existingNames.has(n));
12752
12770
  const created = missing.map(
12753
- (name) => ctx.entityCollection.prepareCreate((record) => {
12754
- record._setRaw("canonical_name", name);
12771
+ (name) => ctx.entityCollection.prepareCreate((record2) => {
12772
+ record2._setRaw("canonical_name", name);
12755
12773
  const kind = kindByName.get(name);
12756
- if (kind !== void 0) record._setRaw("kind", kind);
12774
+ if (kind !== void 0) record2._setRaw("kind", kind);
12757
12775
  })
12758
12776
  );
12759
12777
  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 });
12778
+ for (const record2 of created) out.set(record2.canonicalName, entityToStored(record2));
12779
+ for (const { record: record2, kind } of kindBackfills) {
12780
+ out.set(record2.canonicalName, { ...entityToStored(record2), kind });
12763
12781
  }
12764
12782
  return { entities: out, operations: created, kindBackfills };
12765
12783
  }
12766
12784
  function prepareKindBackfills(backfills) {
12767
12785
  return backfills.map(
12768
- ({ record, kind }) => record.prepareUpdate((r) => {
12786
+ ({ record: record2, kind }) => record2.prepareUpdate((r) => {
12769
12787
  r._setRaw("kind", kind);
12770
12788
  })
12771
12789
  );
@@ -12796,10 +12814,10 @@ function displayNamesOf(entities) {
12796
12814
  }
12797
12815
  return out;
12798
12816
  }
12799
- function topicsEqual(stored, computed) {
12800
- if (stored === null || stored.length !== computed.length) return false;
12817
+ function topicsEqual(stored2, computed) {
12818
+ if (stored2 === null || stored2.length !== computed.length) return false;
12801
12819
  const key = (t) => JSON.stringify([t.name, t.kind ?? null, t.source]);
12802
- const storedKeys = stored.map(key).sort();
12820
+ const storedKeys = stored2.map(key).sort();
12803
12821
  const computedKeys = computed.map(key).sort();
12804
12822
  return storedKeys.every((k, i) => k === computedKeys[i]);
12805
12823
  }
@@ -12865,10 +12883,10 @@ async function linkMemoryEntitiesOp(ctx, memoryId, entityInputs, options) {
12865
12883
  return;
12866
12884
  }
12867
12885
  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);
12886
+ (e) => ctx.memoryEntityCollection.prepareCreate((record2) => {
12887
+ record2._setRaw("memory_id", memoryId);
12888
+ record2._setRaw("entity_id", e.uniqueId);
12889
+ if (userId !== void 0) record2._setRaw("user_id", userId);
12872
12890
  })
12873
12891
  );
12874
12892
  await ctx.database.batch(
@@ -12936,10 +12954,10 @@ async function replaceMemoryEntities(ctx, memoryId, entityInputs, options) {
12936
12954
  ...entityOps,
12937
12955
  ...prepareKindBackfills(kindBackfills),
12938
12956
  ...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);
12957
+ (e) => ctx.memoryEntityCollection.prepareCreate((record2) => {
12958
+ record2._setRaw("memory_id", memoryId);
12959
+ record2._setRaw("entity_id", e.uniqueId);
12960
+ if (userId !== void 0) record2._setRaw("user_id", userId);
12943
12961
  })
12944
12962
  ),
12945
12963
  ...toDestroy.map((l) => l.prepareDestroyPermanently()),
@@ -13140,6 +13158,15 @@ __decorateClass([
13140
13158
  __decorateClass([
13141
13159
  (0, import_decorators6.text)("scope")
13142
13160
  ], VaultMemory.prototype, "scope", 2);
13161
+ __decorateClass([
13162
+ (0, import_decorators6.field)("kind")
13163
+ ], VaultMemory.prototype, "kind", 2);
13164
+ __decorateClass([
13165
+ (0, import_decorators6.field)("kind_value")
13166
+ ], VaultMemory.prototype, "kindValue", 2);
13167
+ __decorateClass([
13168
+ (0, import_decorators6.field)("level")
13169
+ ], VaultMemory.prototype, "level", 2);
13143
13170
  __decorateClass([
13144
13171
  (0, import_decorators6.field)("folder_id")
13145
13172
  ], VaultMemory.prototype, "folderId", 2);
@@ -13365,7 +13392,7 @@ __decorateClass([
13365
13392
  ], VaultFolder.prototype, "context", 2);
13366
13393
 
13367
13394
  // src/lib/db/schema.ts
13368
- var SDK_SCHEMA_VERSION = 47;
13395
+ var SDK_SCHEMA_VERSION = 48;
13369
13396
  var sdkSchema = (0, import_watermelondb19.appSchema)({
13370
13397
  version: SDK_SCHEMA_VERSION,
13371
13398
  tables: [
@@ -13460,6 +13487,9 @@ var sdkSchema = (0, import_watermelondb19.appSchema)({
13460
13487
  columns: [
13461
13488
  { name: "content", type: "string" },
13462
13489
  { name: "scope", type: "string", isIndexed: true },
13490
+ { name: "kind", type: "string", isOptional: true, isIndexed: true },
13491
+ { name: "kind_value", type: "string", isOptional: true },
13492
+ { name: "level", type: "string", isOptional: true, isIndexed: true },
13463
13493
  { name: "folder_id", type: "string", isOptional: true, isIndexed: true },
13464
13494
  { name: "created_at", type: "number", isIndexed: true },
13465
13495
  { name: "updated_at", type: "number", isIndexed: true },
@@ -14136,6 +14166,22 @@ var sdkMigrations = (0, import_migrations2.schemaMigrations)({
14136
14166
  ]
14137
14167
  })
14138
14168
  ]
14169
+ },
14170
+ {
14171
+ toVersion: 48,
14172
+ steps: [
14173
+ (0, import_migrations2.addColumns)({
14174
+ table: "memory_vault",
14175
+ columns: [
14176
+ { name: "kind", type: "string", isOptional: true, isIndexed: true },
14177
+ { name: "kind_value", type: "string", isOptional: true },
14178
+ { name: "level", type: "string", isOptional: true, isIndexed: true }
14179
+ ]
14180
+ }),
14181
+ (0, import_migrations2.unsafeExecuteSql)(
14182
+ "UPDATE memory_vault SET level = CASE WHEN scope IN ('shared', 'public') THEN 'matching' ELSE 'private' END WHERE level IS NULL;"
14183
+ )
14184
+ ]
14139
14185
  }
14140
14186
  ]
14141
14187
  });
@@ -15009,13 +15055,13 @@ async function relinkMisclassifiedVideosOp(ctx, walletAddress) {
15009
15055
  toRelink.push({ media, ext: mime.split("/")[1] || "mp4" });
15010
15056
  continue;
15011
15057
  }
15012
- const stored = await mediaToStored(
15058
+ const stored2 = await mediaToStored(
15013
15059
  media,
15014
15060
  ctx.walletAddress,
15015
15061
  ctx.signMessage,
15016
15062
  ctx.embeddedWalletSigner
15017
15063
  );
15018
- const ext = videoExtensionOf(stored.sourceUrl) ?? videoExtensionOf(stored.name);
15064
+ const ext = videoExtensionOf(stored2.sourceUrl) ?? videoExtensionOf(stored2.name);
15019
15065
  if (ext) {
15020
15066
  toRelink.push({ media, ext });
15021
15067
  }
@@ -15277,13 +15323,54 @@ async function decryptVaultMemoryFields(memory, address, signMessage, embeddedWa
15277
15323
  }
15278
15324
  }
15279
15325
  const decryptedContent = await decryptField(memory.content, address);
15326
+ const decryptedKindValue = typeof memory.kindValue === "string" ? await decryptField(memory.kindValue, address) : memory.kindValue;
15280
15327
  return {
15281
15328
  ...memory,
15282
- content: decryptedContent
15329
+ content: decryptedContent,
15330
+ ...decryptedKindValue !== void 0 && { kindValue: decryptedKindValue }
15283
15331
  };
15284
15332
  }
15285
15333
 
15286
15334
  // src/lib/db/memoryVault/types.ts
15335
+ var MEMORY_KINDS = [
15336
+ "display_name",
15337
+ "birth_date",
15338
+ "bio",
15339
+ "occupation",
15340
+ "interest",
15341
+ "gender",
15342
+ "height_cm",
15343
+ "looking_for",
15344
+ "politics",
15345
+ "religion",
15346
+ "ethnicity",
15347
+ "smoking",
15348
+ "drinking",
15349
+ "exercise",
15350
+ "sexuality",
15351
+ "prompt"
15352
+ ];
15353
+ var MEMORY_LEVELS = ["private", "matching", "profile"];
15354
+ var MemoryLevelError = class extends Error {
15355
+ constructor(message) {
15356
+ super(message);
15357
+ this.name = "MemoryLevelError";
15358
+ }
15359
+ };
15360
+ var PUBLISHED_SCOPES = /* @__PURE__ */ new Set(["shared", "public"]);
15361
+ function levelFromScope(scope) {
15362
+ return typeof scope === "string" && PUBLISHED_SCOPES.has(scope) ? "matching" : "private";
15363
+ }
15364
+ function scopeForLevel(level) {
15365
+ return level === "private" ? "private" : "shared";
15366
+ }
15367
+ function resolveMemoryLevel(level, scope) {
15368
+ return typeof level === "string" && MEMORY_LEVELS.includes(level) ? level : levelFromScope(scope);
15369
+ }
15370
+ function levelForScopeChange(current, nextScope) {
15371
+ const implied = levelFromScope(nextScope);
15372
+ return implied === "matching" && resolveMemoryLevel(current.level, current.scope) === "profile" ? "profile" : implied;
15373
+ }
15287
15374
  function parseMedia(value) {
15288
15375
  if (typeof value !== "string" || value === "") return null;
15289
15376
  try {
@@ -15313,8 +15400,58 @@ function visibilityConditions(requested) {
15313
15400
  if (excluded.length === 0) return [];
15314
15401
  return [import_watermelondb23.Q.or(import_watermelondb23.Q.where("visibility", null), import_watermelondb23.Q.where("visibility", import_watermelondb23.Q.notIn(excluded)))];
15315
15402
  }
15316
- function isOwnedByCtxUser(ctx, record) {
15317
- return ctx.userId === void 0 || record.userId === ctx.userId;
15403
+ function isKinded(record2) {
15404
+ return record2.kind !== null && record2.kind !== void 0;
15405
+ }
15406
+ function assertValidKindLevel(kind, level) {
15407
+ const hasKind = kind !== null && kind !== void 0;
15408
+ if (hasKind && !MEMORY_KINDS.includes(kind)) {
15409
+ throw new MemoryLevelError(`Unknown memory kind: ${kind}`);
15410
+ }
15411
+ if (level !== void 0 && !MEMORY_LEVELS.includes(level)) {
15412
+ throw new MemoryLevelError(`Unknown memory level: ${level}`);
15413
+ }
15414
+ if (level === "profile" && !hasKind) {
15415
+ throw new MemoryLevelError("Only a memory with a kind can be at level 'profile'");
15416
+ }
15417
+ }
15418
+ function resolveCreateLevel(opts) {
15419
+ if (opts.level !== void 0) return { level: opts.level, scope: scopeForLevel(opts.level) };
15420
+ if (opts.scope !== void 0) return { level: levelFromScope(opts.scope), scope: opts.scope };
15421
+ return { level: "private", scope: "private" };
15422
+ }
15423
+ async function encryptKindValue(ctx, value) {
15424
+ if (typeof value !== "string" || !ctx.walletAddress || !ctx.signMessage) return value;
15425
+ return encryptVaultMemoryContent(
15426
+ value,
15427
+ ctx.walletAddress,
15428
+ ctx.signMessage,
15429
+ ctx.embeddedWalletSigner
15430
+ );
15431
+ }
15432
+ function levelConditions(requested) {
15433
+ if (!requested?.length) return [];
15434
+ const published = ["shared", "public"];
15435
+ const wantsMatching = requested.includes("matching");
15436
+ const wantsPrivate = requested.includes("private");
15437
+ const unresolved = import_watermelondb23.Q.or(import_watermelondb23.Q.where("level", null), import_watermelondb23.Q.where("level", import_watermelondb23.Q.notIn([...MEMORY_LEVELS])));
15438
+ const byLevel = import_watermelondb23.Q.where("level", import_watermelondb23.Q.oneOf([...requested]));
15439
+ if (wantsMatching && wantsPrivate) return [import_watermelondb23.Q.or(byLevel, unresolved)];
15440
+ if (wantsMatching) {
15441
+ return [import_watermelondb23.Q.or(byLevel, import_watermelondb23.Q.and(unresolved, import_watermelondb23.Q.where("scope", import_watermelondb23.Q.oneOf(published))))];
15442
+ }
15443
+ if (wantsPrivate) {
15444
+ return [
15445
+ import_watermelondb23.Q.or(
15446
+ byLevel,
15447
+ import_watermelondb23.Q.and(unresolved, import_watermelondb23.Q.or(import_watermelondb23.Q.where("scope", null), import_watermelondb23.Q.where("scope", import_watermelondb23.Q.notIn(published))))
15448
+ )
15449
+ ];
15450
+ }
15451
+ return [byLevel];
15452
+ }
15453
+ function isOwnedByCtxUser(ctx, record2) {
15454
+ return ctx.userId === void 0 || record2.userId === ctx.userId;
15318
15455
  }
15319
15456
  function baseVaultConditions(ctx, options) {
15320
15457
  return [
@@ -15356,6 +15493,9 @@ function vaultMemoryToStoredRaw(memory) {
15356
15493
  uniqueId: memory.id,
15357
15494
  content: memory.content,
15358
15495
  scope: memory.scope,
15496
+ kind: memory.kind ?? null,
15497
+ kindValue: memory.kindValue ?? null,
15498
+ level: resolveMemoryLevel(memory.level, memory.scope),
15359
15499
  folderId: memory.folderId ?? null,
15360
15500
  userId: memory.userId ?? null,
15361
15501
  embedding: memory.embedding ?? null,
@@ -15394,42 +15534,48 @@ async function vaultMemoryToStored(memory, walletAddress, signMessage, embeddedW
15394
15534
  }
15395
15535
  return raw;
15396
15536
  }
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);
15537
+ function populateNewVaultMemory(record2, ctx, opts, encryptedContent, encryptedKindValue) {
15538
+ const { level, scope } = resolveCreateLevel(opts);
15539
+ record2._setRaw("content", encryptedContent);
15540
+ record2._setRaw("scope", scope);
15541
+ record2._setRaw("level", level);
15542
+ record2._setRaw("kind", opts.kind ?? null);
15543
+ record2._setRaw("kind_value", encryptedKindValue ?? null);
15544
+ record2._setRaw("folder_id", opts.folderId ?? null);
15545
+ record2._setRaw("user_id", ctx.userId ?? null);
15546
+ record2._setRaw("is_deleted", false);
15403
15547
  if (opts.embedding !== void 0) {
15404
- record._setRaw("embedding", opts.embedding);
15405
- record._setRaw("embedding_model", opts.embeddingModel ?? null);
15548
+ record2._setRaw("embedding", opts.embedding);
15549
+ record2._setRaw("embedding_model", opts.embeddingModel ?? null);
15406
15550
  }
15407
15551
  if (opts.sourceChunkIds !== void 0) {
15408
- record._setRaw("source_chunk_ids", JSON.stringify(opts.sourceChunkIds));
15552
+ record2._setRaw("source_chunk_ids", JSON.stringify(opts.sourceChunkIds));
15409
15553
  }
15410
- record._setRaw("proof_count", opts.proofCount ?? 1);
15411
- record._setRaw("source", opts.source ?? "manual");
15554
+ record2._setRaw("proof_count", opts.proofCount ?? 1);
15555
+ record2._setRaw("source", opts.source ?? "manual");
15412
15556
  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);
15557
+ record2._setRaw("event_time_start", opts.eventTime.start ?? null);
15558
+ record2._setRaw("event_time_end", opts.eventTime.end ?? null);
15559
+ record2._setRaw("event_time_kind", opts.eventTime.kind ?? null);
15416
15560
  }
15417
15561
  if (opts.factType !== void 0) {
15418
- record._setRaw("fact_type", opts.factType);
15562
+ record2._setRaw("fact_type", opts.factType);
15419
15563
  }
15420
15564
  if (opts.trustTier !== void 0) {
15421
- record._setRaw("trust_tier", normalizeTrustTier(opts.trustTier));
15565
+ record2._setRaw("trust_tier", normalizeTrustTier(opts.trustTier));
15422
15566
  }
15423
- record._setRaw("visibility", opts.visibility ?? "private");
15424
- record._setRaw(
15567
+ record2._setRaw("visibility", opts.visibility ?? "private");
15568
+ record2._setRaw(
15425
15569
  "published_at",
15426
15570
  opts.visibility && opts.visibility !== "private" ? opts.publishedAt ?? Date.now() : null
15427
15571
  );
15428
15572
  if (opts.geohash !== void 0) {
15429
- record._setRaw("geohash", opts.geohash);
15573
+ record2._setRaw("geohash", opts.geohash);
15430
15574
  }
15431
15575
  }
15432
15576
  async function createVaultMemoryOp(ctx, opts) {
15577
+ assertValidKindLevel(opts.kind, resolveCreateLevel(opts).level);
15578
+ const encryptedKindValue = await encryptKindValue(ctx, opts.kindValue);
15433
15579
  const encryptedContent = ctx.walletAddress && ctx.signMessage ? await encryptVaultMemoryContent(
15434
15580
  opts.content,
15435
15581
  ctx.walletAddress,
@@ -15440,13 +15586,15 @@ async function createVaultMemoryOp(ctx, opts) {
15440
15586
  if (ctx.canWrite && !await ctx.canWrite())
15441
15587
  throw new Error("Memory source is no longer eligible");
15442
15588
  return ctx.vaultMemoryCollection.create(
15443
- (record) => populateNewVaultMemory(record, ctx, opts, encryptedContent)
15589
+ (record2) => populateNewVaultMemory(record2, ctx, opts, encryptedContent, encryptedKindValue)
15444
15590
  );
15445
15591
  });
15446
15592
  return vaultMemoryToStored(created, ctx.walletAddress, ctx.signMessage, ctx.embeddedWalletSigner);
15447
15593
  }
15448
15594
  async function createSupersedingMemoryOp(ctx, opts, targetId) {
15449
15595
  if (!targetId) return { created: null, retired: false };
15596
+ assertValidKindLevel(opts.kind, resolveCreateLevel(opts).level);
15597
+ const encryptedKindValue = await encryptKindValue(ctx, opts.kindValue);
15450
15598
  const encryptedContent = ctx.walletAddress && ctx.signMessage ? await encryptVaultMemoryContent(
15451
15599
  opts.content,
15452
15600
  ctx.walletAddress,
@@ -15463,9 +15611,10 @@ async function createSupersedingMemoryOp(ctx, opts, targetId) {
15463
15611
  } catch {
15464
15612
  return;
15465
15613
  }
15466
- if (target.isDeleted || target.supersededBy || !isOwnedByCtxUser(ctx, target)) return;
15614
+ if (target.isDeleted || target.supersededBy || isKinded(target) || !isOwnedByCtxUser(ctx, target))
15615
+ return;
15467
15616
  createdRecord = await ctx.vaultMemoryCollection.create(
15468
- (record) => populateNewVaultMemory(record, ctx, opts, encryptedContent)
15617
+ (record2) => populateNewVaultMemory(record2, ctx, opts, encryptedContent, encryptedKindValue)
15469
15618
  );
15470
15619
  await target.update((r) => {
15471
15620
  r._setRaw("superseded_by", createdRecord.id);
@@ -15529,6 +15678,10 @@ async function getMemoriesByEventTimeOp(ctx, windowStart, windowEnd) {
15529
15678
  }
15530
15679
  async function createVaultMemoriesBatchOp(ctx, optionsArray) {
15531
15680
  if (optionsArray.length === 0) return [];
15681
+ for (const opts of optionsArray) assertValidKindLevel(opts.kind, resolveCreateLevel(opts).level);
15682
+ const encryptedKindValues = await Promise.all(
15683
+ optionsArray.map((opts) => encryptKindValue(ctx, opts.kindValue))
15684
+ );
15532
15685
  const encryptedContents = await Promise.all(
15533
15686
  optionsArray.map(async (opts) => {
15534
15687
  if (ctx.walletAddress && ctx.signMessage) {
@@ -15547,7 +15700,7 @@ async function createVaultMemoriesBatchOp(ctx, optionsArray) {
15547
15700
  throw new Error("Memory source is no longer eligible");
15548
15701
  const prepared = optionsArray.map(
15549
15702
  (opts, i) => ctx.vaultMemoryCollection.prepareCreate(
15550
- (record) => populateNewVaultMemory(record, ctx, opts, encryptedContents[i])
15703
+ (record2) => populateNewVaultMemory(record2, ctx, opts, encryptedContents[i], encryptedKindValues[i])
15551
15704
  )
15552
15705
  );
15553
15706
  await ctx.database.batch(...prepared);
@@ -15555,16 +15708,16 @@ async function createVaultMemoriesBatchOp(ctx, optionsArray) {
15555
15708
  });
15556
15709
  return Promise.all(
15557
15710
  created.map(
15558
- (record) => vaultMemoryToStored(record, ctx.walletAddress, ctx.signMessage, ctx.embeddedWalletSigner)
15711
+ (record2) => vaultMemoryToStored(record2, ctx.walletAddress, ctx.signMessage, ctx.embeddedWalletSigner)
15559
15712
  )
15560
15713
  );
15561
15714
  }
15562
15715
  async function getVaultMemoryOp(ctx, id) {
15563
15716
  try {
15564
- const record = await ctx.vaultMemoryCollection.find(id);
15565
- if (record.isDeleted || !isOwnedByCtxUser(ctx, record)) return null;
15717
+ const record2 = await ctx.vaultMemoryCollection.find(id);
15718
+ if (record2.isDeleted || !isOwnedByCtxUser(ctx, record2)) return null;
15566
15719
  return vaultMemoryToStored(
15567
- record,
15720
+ record2,
15568
15721
  ctx.walletAddress,
15569
15722
  ctx.signMessage,
15570
15723
  ctx.embeddedWalletSigner
@@ -15590,6 +15743,9 @@ function vaultMemoryRawToStoredRaw(raw) {
15590
15743
  uniqueId: raw.id,
15591
15744
  content: raw.content ?? "",
15592
15745
  scope: raw.scope ?? "",
15746
+ kind: raw.kind ?? null,
15747
+ kindValue: raw.kind_value ?? null,
15748
+ level: resolveMemoryLevel(raw.level, raw.scope),
15593
15749
  folderId: raw.folder_id ?? null,
15594
15750
  userId: raw.user_id ?? null,
15595
15751
  embedding: raw.embedding ?? null,
@@ -15622,17 +15778,19 @@ function vaultMemoryRawToStoredRaw(raw) {
15622
15778
  };
15623
15779
  }
15624
15780
  async function vaultMemoryRawToStored(raw, walletAddress, signMessage, embeddedWalletSigner) {
15625
- const stored = vaultMemoryRawToStoredRaw(raw);
15781
+ const stored2 = vaultMemoryRawToStoredRaw(raw);
15626
15782
  if (walletAddress) {
15627
- return decryptVaultMemoryFields(stored, walletAddress, signMessage, embeddedWalletSigner);
15783
+ return decryptVaultMemoryFields(stored2, walletAddress, signMessage, embeddedWalletSigner);
15628
15784
  }
15629
- return stored;
15785
+ return stored2;
15630
15786
  }
15631
15787
  async function getAllVaultMemoriesOp(ctx, options) {
15632
15788
  const conditions = [
15633
15789
  ...baseVaultConditions(ctx, options),
15634
15790
  ...options?.scopes?.length ? [import_watermelondb23.Q.where("scope", import_watermelondb23.Q.oneOf(options.scopes))] : [],
15635
15791
  ...visibilityConditions(options?.visibility),
15792
+ ...levelConditions(options?.levels),
15793
+ ...options?.kinds?.length ? [import_watermelondb23.Q.where("kind", import_watermelondb23.Q.oneOf(options.kinds))] : [],
15636
15794
  ...options?.folderId !== void 0 ? [import_watermelondb23.Q.where("folder_id", options.folderId)] : [],
15637
15795
  ...options?.factTypes?.length ? [import_watermelondb23.Q.where("fact_type", import_watermelondb23.Q.oneOf(options.factTypes))] : [],
15638
15796
  import_watermelondb23.Q.sortBy(options?.since ? "updated_at" : "created_at", import_watermelondb23.Q.desc),
@@ -15778,13 +15936,13 @@ async function getVaultMemoriesByIdsOp(ctx, ids, options) {
15778
15936
  async function getAllVaultMemoryContentsOp(ctx, options) {
15779
15937
  const results = await ctx.vaultMemoryCollection.query(...baseVaultConditions(ctx, options)).unsafeFetchRaw();
15780
15938
  return mapInBatches(results, async (raw) => {
15781
- const stored = await vaultMemoryRawToStored(
15939
+ const stored2 = await vaultMemoryRawToStored(
15782
15940
  raw,
15783
15941
  ctx.walletAddress,
15784
15942
  ctx.signMessage,
15785
15943
  ctx.embeddedWalletSigner
15786
15944
  );
15787
- return stored.content;
15945
+ return stored2.content;
15788
15946
  });
15789
15947
  }
15790
15948
  async function countActiveVaultMemoriesOp(ctx) {
@@ -15799,6 +15957,14 @@ async function updateVaultMemoryOp(ctx, id, opts) {
15799
15957
  try {
15800
15958
  const probe = await ctx.vaultMemoryCollection.find(id);
15801
15959
  if (probe.isDeleted || probe.supersededBy || !isOwnedByCtxUser(ctx, probe)) return null;
15960
+ if (opts.freeFormOnly && isKinded(probe)) return null;
15961
+ const levelAfter = (current) => {
15962
+ if (opts.level !== void 0) return opts.level;
15963
+ if (opts.scope === void 0) return resolveMemoryLevel(current.level, current.scope);
15964
+ return levelForScopeChange(current, opts.scope);
15965
+ };
15966
+ assertValidKindLevel(opts.kind !== void 0 ? opts.kind : probe.kind, levelAfter(probe));
15967
+ const encryptedKindValue = await encryptKindValue(ctx, opts.kindValue);
15802
15968
  const encryptedContent = ctx.walletAddress && ctx.signMessage ? await encryptVaultMemoryContent(
15803
15969
  opts.content,
15804
15970
  ctx.walletAddress,
@@ -15806,30 +15972,43 @@ async function updateVaultMemoryOp(ctx, id, opts) {
15806
15972
  ctx.embeddedWalletSigner
15807
15973
  ) : opts.content;
15808
15974
  let stale = false;
15809
- const record = probe;
15810
- const originalUpdatedAt = record.updatedAt.getTime();
15975
+ const record2 = probe;
15976
+ const originalUpdatedAt = record2.updatedAt.getTime();
15811
15977
  await ctx.database.write(async () => {
15812
15978
  if (ctx.canWrite && !await ctx.canWrite())
15813
15979
  throw new Error("Memory source is no longer eligible");
15814
- if (record.isDeleted || record.supersededBy || !isOwnedByCtxUser(ctx, record)) {
15980
+ if (record2.isDeleted || record2.supersededBy || !isOwnedByCtxUser(ctx, record2) || opts.freeFormOnly && isKinded(record2)) {
15815
15981
  stale = true;
15816
15982
  return;
15817
15983
  }
15984
+ const nextKind = opts.kind !== void 0 ? opts.kind : record2.kind;
15985
+ const nextLevel = levelAfter(record2);
15986
+ assertValidKindLevel(nextKind, nextLevel);
15818
15987
  let observedSources = [];
15819
15988
  let replayedObservation = false;
15820
15989
  if (opts.observationSourceIds?.length) {
15821
15990
  try {
15822
- const parsed = JSON.parse(record.sourceChunkIds ?? "[]");
15991
+ const parsed = JSON.parse(record2.sourceChunkIds ?? "[]");
15823
15992
  if (Array.isArray(parsed))
15824
15993
  observedSources = parsed.filter((id2) => typeof id2 === "string");
15825
15994
  } catch {
15826
15995
  }
15827
15996
  replayedObservation = opts.observationSourceIds.every((id2) => observedSources.includes(id2));
15828
15997
  }
15829
- await record.update((r) => {
15998
+ await record2.update((r) => {
15830
15999
  r._setRaw("content", encryptedContent);
15831
- if (opts.scope !== void 0) {
16000
+ if (opts.level !== void 0) {
16001
+ r._setRaw("level", nextLevel);
16002
+ r._setRaw("scope", scopeForLevel(nextLevel));
16003
+ } else if (opts.scope !== void 0) {
15832
16004
  r._setRaw("scope", opts.scope);
16005
+ r._setRaw("level", nextLevel);
16006
+ }
16007
+ if (opts.kind !== void 0) {
16008
+ r._setRaw("kind", opts.kind);
16009
+ }
16010
+ if (encryptedKindValue !== void 0) {
16011
+ r._setRaw("kind_value", encryptedKindValue);
15833
16012
  }
15834
16013
  if (opts.folderId !== void 0) {
15835
16014
  r._setRaw("folder_id", opts.folderId);
@@ -15883,12 +16062,13 @@ async function updateVaultMemoryOp(ctx, id, opts) {
15883
16062
  });
15884
16063
  if (stale) return null;
15885
16064
  return vaultMemoryToStored(
15886
- record,
16065
+ record2,
15887
16066
  ctx.walletAddress,
15888
16067
  ctx.signMessage,
15889
16068
  ctx.embeddedWalletSigner
15890
16069
  );
15891
- } catch {
16070
+ } catch (err) {
16071
+ if (err instanceof MemoryLevelError) throw err;
15892
16072
  return null;
15893
16073
  }
15894
16074
  }
@@ -15897,21 +16077,21 @@ async function setMemoryEntitiesOp(ctx, memoryId, entities) {
15897
16077
  if (!entityCtx) {
15898
16078
  throw new Error("setMemoryEntitiesOp requires ctx.entityCtx (entity collections)");
15899
16079
  }
15900
- let record;
16080
+ let record2;
15901
16081
  try {
15902
- record = await ctx.vaultMemoryCollection.find(memoryId);
16082
+ record2 = await ctx.vaultMemoryCollection.find(memoryId);
15903
16083
  } catch {
15904
16084
  return null;
15905
16085
  }
15906
- if (record.isDeleted || !isOwnedByCtxUser(ctx, record)) return null;
16086
+ if (record2.isDeleted || !isOwnedByCtxUser(ctx, record2)) return null;
15907
16087
  let stale = false;
15908
- const originalUpdatedAt = record.updatedAt.getTime();
16088
+ const originalUpdatedAt = record2.updatedAt.getTime();
15909
16089
  await ctx.database.write(async (writer) => {
15910
- if (record.isDeleted || !isOwnedByCtxUser(ctx, record)) {
16090
+ if (record2.isDeleted || !isOwnedByCtxUser(ctx, record2)) {
15911
16091
  stale = true;
15912
16092
  return;
15913
16093
  }
15914
- await record.update((r) => {
16094
+ await record2.update((r) => {
15915
16095
  r._setRaw("topics_user_managed", true);
15916
16096
  r._setRaw("updated_at", originalUpdatedAt);
15917
16097
  });
@@ -15935,25 +16115,25 @@ async function setMemoryEntitiesOp(ctx, memoryId, entities) {
15935
16115
  );
15936
16116
  });
15937
16117
  if (stale) return null;
15938
- return vaultMemoryToStored(record, ctx.walletAddress, ctx.signMessage, ctx.embeddedWalletSigner);
16118
+ return vaultMemoryToStored(record2, ctx.walletAddress, ctx.signMessage, ctx.embeddedWalletSigner);
15939
16119
  }
15940
16120
  async function clearMemoryTopicsOverrideOp(ctx, memoryId, options) {
15941
- let record;
16121
+ let record2;
15942
16122
  try {
15943
- record = await ctx.vaultMemoryCollection.find(memoryId);
16123
+ record2 = await ctx.vaultMemoryCollection.find(memoryId);
15944
16124
  } catch {
15945
16125
  return false;
15946
16126
  }
15947
- if (record.isDeleted || !isOwnedByCtxUser(ctx, record)) return false;
15948
- const originalUpdatedAt = record.updatedAt.getTime();
16127
+ if (record2.isDeleted || !isOwnedByCtxUser(ctx, record2)) return false;
16128
+ const originalUpdatedAt = record2.updatedAt.getTime();
15949
16129
  let cleared = false;
15950
16130
  await ctx.database.write(async () => {
15951
- if (options?.unlessTopicsRecorded && parseTopics(record.topics) !== null) return;
16131
+ if (options?.unlessTopicsRecorded && parseTopics(record2.topics) !== null) return;
15952
16132
  cleared = true;
15953
- await record.update((r) => {
16133
+ await record2.update((r) => {
15954
16134
  r._setRaw("topics_user_managed", false);
15955
16135
  r._setRaw("topics_extracted_version", null);
15956
- if (record.topicsExtractedAt === null) {
16136
+ if (record2.topicsExtractedAt === null) {
15957
16137
  r._setRaw("topics_extracted_at", originalUpdatedAt);
15958
16138
  }
15959
16139
  r._setRaw("updated_at", originalUpdatedAt);
@@ -15962,22 +16142,22 @@ async function clearMemoryTopicsOverrideOp(ctx, memoryId, options) {
15962
16142
  return cleared;
15963
16143
  }
15964
16144
  async function setMemoryVisibilityOp(ctx, id, opts) {
15965
- let record;
16145
+ let record2;
15966
16146
  try {
15967
- record = await ctx.vaultMemoryCollection.find(id);
16147
+ record2 = await ctx.vaultMemoryCollection.find(id);
15968
16148
  } catch {
15969
16149
  return null;
15970
16150
  }
15971
- if (record.isDeleted || !isOwnedByCtxUser(ctx, record)) return null;
16151
+ if (record2.isDeleted || !isOwnedByCtxUser(ctx, record2)) return null;
15972
16152
  let stale = false;
15973
16153
  await ctx.database.write(async () => {
15974
- if (record.isDeleted || !isOwnedByCtxUser(ctx, record)) {
16154
+ if (record2.isDeleted || !isOwnedByCtxUser(ctx, record2)) {
15975
16155
  stale = true;
15976
16156
  return;
15977
16157
  }
15978
- const currentUpdatedAt = record.updatedAt.getTime();
15979
- const currentPublishedAt = record.publishedAt ?? null;
15980
- await record.update((r) => {
16158
+ const currentUpdatedAt = record2.updatedAt.getTime();
16159
+ const currentPublishedAt = record2.publishedAt ?? null;
16160
+ await record2.update((r) => {
15981
16161
  r._setRaw("visibility", opts.visibility);
15982
16162
  if (opts.visibility === "private") {
15983
16163
  r._setRaw("published_at", null);
@@ -15991,19 +16171,19 @@ async function setMemoryVisibilityOp(ctx, id, opts) {
15991
16171
  });
15992
16172
  });
15993
16173
  if (stale) return null;
15994
- return vaultMemoryToStored(record, ctx.walletAddress, ctx.signMessage, ctx.embeddedWalletSigner);
16174
+ return vaultMemoryToStored(record2, ctx.walletAddress, ctx.signMessage, ctx.embeddedWalletSigner);
15995
16175
  }
15996
16176
  async function deleteVaultMemoryOp(ctx, id) {
15997
16177
  try {
15998
- const record = await ctx.vaultMemoryCollection.find(id);
15999
- if (record.isDeleted || !isOwnedByCtxUser(ctx, record)) return false;
16178
+ const record2 = await ctx.vaultMemoryCollection.find(id);
16179
+ if (record2.isDeleted || !isOwnedByCtxUser(ctx, record2)) return false;
16000
16180
  let stale = false;
16001
16181
  await ctx.database.write(async () => {
16002
- if (record.isDeleted || !isOwnedByCtxUser(ctx, record)) {
16182
+ if (record2.isDeleted || !isOwnedByCtxUser(ctx, record2)) {
16003
16183
  stale = true;
16004
16184
  return;
16005
16185
  }
16006
- await record.update((r) => {
16186
+ await record2.update((r) => {
16007
16187
  r._setRaw("is_deleted", true);
16008
16188
  });
16009
16189
  });
@@ -16022,8 +16202,9 @@ async function deleteVaultMemoryOp(ctx, id) {
16022
16202
  async function supersedeVaultMemoryOp(ctx, id, supersededById) {
16023
16203
  if (id === supersededById) return false;
16024
16204
  try {
16025
- const record = await ctx.vaultMemoryCollection.find(id);
16026
- if (record.isDeleted || record.supersededBy || !isOwnedByCtxUser(ctx, record)) return false;
16205
+ const record2 = await ctx.vaultMemoryCollection.find(id);
16206
+ if (record2.isDeleted || record2.supersededBy || !isOwnedByCtxUser(ctx, record2)) return false;
16207
+ if (isKinded(record2)) return false;
16027
16208
  let successor;
16028
16209
  try {
16029
16210
  successor = await ctx.vaultMemoryCollection.find(supersededById);
@@ -16037,7 +16218,7 @@ async function supersedeVaultMemoryOp(ctx, id, supersededById) {
16037
16218
  await ctx.database.write(async () => {
16038
16219
  if (ctx.canWrite && !await ctx.canWrite())
16039
16220
  throw new Error("Memory source is no longer eligible");
16040
- if (record.isDeleted || record.supersededBy || !isOwnedByCtxUser(ctx, record)) {
16221
+ if (record2.isDeleted || record2.supersededBy || !isOwnedByCtxUser(ctx, record2)) {
16041
16222
  stale = true;
16042
16223
  return;
16043
16224
  }
@@ -16045,7 +16226,7 @@ async function supersedeVaultMemoryOp(ctx, id, supersededById) {
16045
16226
  stale = true;
16046
16227
  return;
16047
16228
  }
16048
- await record.update((r) => {
16229
+ await record2.update((r) => {
16049
16230
  r._setRaw("superseded_by", supersededById);
16050
16231
  r._setRaw("superseded_at", Date.now());
16051
16232
  });
@@ -16064,7 +16245,7 @@ async function getUnfiledVaultMemoriesOp(ctx) {
16064
16245
  const results = await ctx.vaultMemoryCollection.query(...conditions).fetch();
16065
16246
  return mapInBatches(
16066
16247
  results,
16067
- (record) => vaultMemoryToStored(record, ctx.walletAddress, ctx.signMessage, ctx.embeddedWalletSigner)
16248
+ (record2) => vaultMemoryToStored(record2, ctx.walletAddress, ctx.signMessage, ctx.embeddedWalletSigner)
16068
16249
  );
16069
16250
  }
16070
16251
  var TOPICS_EXTRACTION_VERSION = 3;
@@ -16206,17 +16387,17 @@ async function stampTopicsExtractedAtOp(ctx, memoryIds, extractedAt, version = T
16206
16387
  }
16207
16388
  }
16208
16389
  const eligible = records.filter(
16209
- (record) => !record.isDeleted && isOwnedByCtxUser(ctx, record) && !record.topicsUserManaged
16390
+ (record2) => !record2.isDeleted && isOwnedByCtxUser(ctx, record2) && !record2.topicsUserManaged
16210
16391
  );
16211
- const prepared = eligible.map((record) => {
16212
- const originalUpdatedAt = record.updatedAt.getTime();
16213
- return record.prepareUpdate((r) => {
16392
+ const prepared = eligible.map((record2) => {
16393
+ const originalUpdatedAt = record2.updatedAt.getTime();
16394
+ return record2.prepareUpdate((r) => {
16214
16395
  r._setRaw("topics_extracted_at", extractedAt);
16215
16396
  r._setRaw("topics_extracted_version", version);
16216
16397
  r._setRaw("updated_at", originalUpdatedAt);
16217
16398
  });
16218
16399
  });
16219
- for (const record of eligible) stamped.push(record.id);
16400
+ for (const record2 of eligible) stamped.push(record2.id);
16220
16401
  if (prepared.length > 0) await ctx.database.batch(...prepared);
16221
16402
  });
16222
16403
  }
@@ -16231,14 +16412,14 @@ async function relinkMemoryTopicsOp(ctx, memoryIds) {
16231
16412
  for (const id of Array.from(new Set(memoryIds))) {
16232
16413
  try {
16233
16414
  await ctx.database.write(async (writer) => {
16234
- let record;
16415
+ let record2;
16235
16416
  try {
16236
- record = await ctx.vaultMemoryCollection.find(id);
16417
+ record2 = await ctx.vaultMemoryCollection.find(id);
16237
16418
  } catch {
16238
16419
  return;
16239
16420
  }
16240
- if (record.isDeleted || !isOwnedByCtxUser(ctx, record)) return;
16241
- const topics = parseTopics(record.topics);
16421
+ if (record2.isDeleted || !isOwnedByCtxUser(ctx, record2)) return;
16422
+ const topics = parseTopics(record2.topics);
16242
16423
  if (topics === null) return;
16243
16424
  await writer.callWriter(() => relinkMemoryEntitiesFromTopicsOp(entityCtx, id, topics));
16244
16425
  relinked.push(id);
@@ -16263,20 +16444,20 @@ async function backfillMemoryTopicsOp(ctx, memoryIds) {
16263
16444
  await ctx.database.write(async () => {
16264
16445
  const writes = [];
16265
16446
  for (const id of chunkIds) {
16266
- let record;
16447
+ let record2;
16267
16448
  try {
16268
- record = await ctx.vaultMemoryCollection.find(id);
16449
+ record2 = await ctx.vaultMemoryCollection.find(id);
16269
16450
  } catch {
16270
16451
  continue;
16271
16452
  }
16272
- if (record.isDeleted || !isOwnedByCtxUser(ctx, record)) continue;
16273
- if (parseTopics(record.topics) !== null) continue;
16453
+ if (record2.isDeleted || !isOwnedByCtxUser(ctx, record2)) continue;
16454
+ if (parseTopics(record2.topics) !== null) continue;
16274
16455
  const links = await entityCtx.memoryEntityCollection.query(import_watermelondb23.Q.where("memory_id", id)).unsafeFetchRaw();
16275
16456
  const entityIds = links.map((l) => String(l.entity_id));
16276
16457
  if (entityIds.length === 0) continue;
16277
16458
  const entities = await entityCtx.entityCollection.query(import_watermelondb23.Q.where("id", import_watermelondb23.Q.oneOf(entityIds))).fetch();
16278
16459
  if (entities.length === 0) continue;
16279
- const source = record.topicsUserManaged ? "user" : "auto";
16460
+ const source = record2.topicsUserManaged ? "user" : "auto";
16280
16461
  const write = await resolveMemoryTopicsWrite(entityCtx, id, entities, [], source);
16281
16462
  if (write) writes.push(write);
16282
16463
  }
@@ -16294,7 +16475,7 @@ async function deleteAllVaultMemoriesForUserOp(ctx, userId) {
16294
16475
  if (records.length === 0) return 0;
16295
16476
  await ctx.database.write(async () => {
16296
16477
  const prepared = records.map(
16297
- (record) => record.prepareUpdate((r) => {
16478
+ (record2) => record2.prepareUpdate((r) => {
16298
16479
  r._setRaw("is_deleted", true);
16299
16480
  })
16300
16481
  );
@@ -16324,7 +16505,10 @@ function assertVaultScopeForSweep(ctx) {
16324
16505
  }
16325
16506
  async function getDecayCandidatesRawOp(ctx) {
16326
16507
  assertVaultScopeForSweep(ctx);
16327
- const results = await ctx.vaultMemoryCollection.query(...baseVaultConditions(ctx, { includeArchived: true, includeQuarantined: true })).unsafeFetchRaw();
16508
+ const results = await ctx.vaultMemoryCollection.query(
16509
+ ...baseVaultConditions(ctx, { includeArchived: true, includeQuarantined: true }),
16510
+ import_watermelondb23.Q.where("kind", null)
16511
+ ).unsafeFetchRaw();
16328
16512
  return results.map((raw) => ({
16329
16513
  uniqueId: raw.id,
16330
16514
  factType: raw.fact_type ?? null,
@@ -16339,20 +16523,20 @@ async function getDecayCandidatesRawOp(ctx) {
16339
16523
  }
16340
16524
  async function archiveVaultMemoryOp(ctx, id, opts) {
16341
16525
  try {
16342
- const record = await ctx.vaultMemoryCollection.find(id);
16343
- if (record.isDeleted || !isOwnedByCtxUser(ctx, record)) return false;
16526
+ const record2 = await ctx.vaultMemoryCollection.find(id);
16527
+ if (record2.isDeleted || !isOwnedByCtxUser(ctx, record2)) return false;
16344
16528
  let stale = false;
16345
16529
  const archivedAtValue = opts?.now ?? Date.now();
16346
16530
  await ctx.database.write(async () => {
16347
- if (record.isDeleted || !isOwnedByCtxUser(ctx, record) || record.archivedAt !== null) {
16531
+ if (record2.isDeleted || !isOwnedByCtxUser(ctx, record2) || record2.archivedAt !== null) {
16348
16532
  stale = true;
16349
16533
  return;
16350
16534
  }
16351
- if (opts?.expectedUpdatedAt !== void 0 && record.updatedAt.getTime() !== opts.expectedUpdatedAt || opts?.expectedLastObservedAt !== void 0 && (record.lastObservedAt ?? null) !== opts.expectedLastObservedAt) {
16535
+ if (opts?.expectedUpdatedAt !== void 0 && record2.updatedAt.getTime() !== opts.expectedUpdatedAt || opts?.expectedLastObservedAt !== void 0 && (record2.lastObservedAt ?? null) !== opts.expectedLastObservedAt) {
16352
16536
  stale = true;
16353
16537
  return;
16354
16538
  }
16355
- await record.update((r) => {
16539
+ await record2.update((r) => {
16356
16540
  r._setRaw("archived_at", archivedAtValue);
16357
16541
  });
16358
16542
  });
@@ -16363,15 +16547,15 @@ async function archiveVaultMemoryOp(ctx, id, opts) {
16363
16547
  }
16364
16548
  async function restoreVaultMemoryOp(ctx, id) {
16365
16549
  try {
16366
- const record = await ctx.vaultMemoryCollection.find(id);
16367
- if (record.isDeleted || !isOwnedByCtxUser(ctx, record)) return false;
16550
+ const record2 = await ctx.vaultMemoryCollection.find(id);
16551
+ if (record2.isDeleted || !isOwnedByCtxUser(ctx, record2)) return false;
16368
16552
  let stale = false;
16369
16553
  await ctx.database.write(async () => {
16370
- if (record.isDeleted || !isOwnedByCtxUser(ctx, record)) {
16554
+ if (record2.isDeleted || !isOwnedByCtxUser(ctx, record2)) {
16371
16555
  stale = true;
16372
16556
  return;
16373
16557
  }
16374
- await record.update((r) => {
16558
+ await record2.update((r) => {
16375
16559
  r._setRaw("archived_at", null);
16376
16560
  });
16377
16561
  });
@@ -16382,17 +16566,17 @@ async function restoreVaultMemoryOp(ctx, id) {
16382
16566
  }
16383
16567
  async function hardDeleteDecayedOp(ctx, id, opts) {
16384
16568
  try {
16385
- const record = await ctx.vaultMemoryCollection.find(id);
16386
- if (record.isDeleted || !isOwnedByCtxUser(ctx, record)) return false;
16569
+ const record2 = await ctx.vaultMemoryCollection.find(id);
16570
+ if (record2.isDeleted || !isOwnedByCtxUser(ctx, record2)) return false;
16387
16571
  const now = opts.now ?? Date.now();
16388
16572
  let stale = false;
16389
16573
  await ctx.database.write(async () => {
16390
- const archivedAt = record.archivedAt;
16391
- if (record.isDeleted || !isOwnedByCtxUser(ctx, record) || archivedAt === null || now - archivedAt <= opts.hardDeleteWindowMs) {
16574
+ const archivedAt = record2.archivedAt;
16575
+ if (record2.isDeleted || !isOwnedByCtxUser(ctx, record2) || archivedAt === null || now - archivedAt <= opts.hardDeleteWindowMs) {
16392
16576
  stale = true;
16393
16577
  return;
16394
16578
  }
16395
- await record.update((r) => {
16579
+ await record2.update((r) => {
16396
16580
  r._setRaw("is_deleted", true);
16397
16581
  });
16398
16582
  });
@@ -16410,14 +16594,14 @@ async function hardDeleteDecayedOp(ctx, id, opts) {
16410
16594
  }
16411
16595
  async function updateVaultMemoryEmbeddingOp(ctx, id, embedding, embeddingModel, expected) {
16412
16596
  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");
16597
+ const record2 = await ctx.vaultMemoryCollection.find(id);
16598
+ if (record2.isDeleted || !isOwnedByCtxUser(ctx, record2)) return false;
16599
+ const readUpdatedAt = record2.updatedAt.getTime();
16600
+ const readStoredContent = record2._getRaw("content");
16417
16601
  if (expected?.updatedAt !== void 0 && expected.updatedAt !== readUpdatedAt) return false;
16418
16602
  if (expected?.content !== void 0) {
16419
16603
  const current = await vaultMemoryToStored(
16420
- record,
16604
+ record2,
16421
16605
  ctx.walletAddress,
16422
16606
  ctx.signMessage,
16423
16607
  ctx.embeddedWalletSigner
@@ -16426,11 +16610,11 @@ async function updateVaultMemoryEmbeddingOp(ctx, id, embedding, embeddingModel,
16426
16610
  }
16427
16611
  let written = false;
16428
16612
  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)
16613
+ if (record2.isDeleted || !isOwnedByCtxUser(ctx, record2)) return;
16614
+ const originalUpdatedAt = record2.updatedAt.getTime();
16615
+ if (originalUpdatedAt !== readUpdatedAt || record2._getRaw("content") !== readStoredContent)
16432
16616
  return;
16433
- await record.update((r) => {
16617
+ await record2.update((r) => {
16434
16618
  r._setRaw("embedding", embedding);
16435
16619
  r._setRaw("embedding_model", embeddingModel);
16436
16620
  r._setRaw("updated_at", originalUpdatedAt);
@@ -16445,8 +16629,8 @@ async function updateVaultMemoryEmbeddingOp(ctx, id, embedding, embeddingModel,
16445
16629
  function normalizeForDedupe(content) {
16446
16630
  return content.normalize("NFKC").trim().replace(/\s+/g, " ").toLowerCase();
16447
16631
  }
16448
- async function findQuarantinedDuplicateOp(ctx, content, sourceIds, where) {
16449
- const wanted = [...new Set(sourceIds)].sort().join("\0");
16632
+ async function findQuarantinedDuplicateOp(ctx, content, sourceIds2, where) {
16633
+ const wanted = [...new Set(sourceIds2)].sort().join("\0");
16450
16634
  const target = normalizeForDedupe(content);
16451
16635
  const rows = await ctx.vaultMemoryCollection.query(
16452
16636
  import_watermelondb23.Q.where("trust_tier", "quarantined"),
@@ -16465,13 +16649,13 @@ async function findQuarantinedDuplicateOp(ctx, content, sourceIds, where) {
16465
16649
  if (!Array.isArray(ids)) continue;
16466
16650
  const key = [...new Set(ids.filter((id) => typeof id === "string"))].sort().join("\0");
16467
16651
  if (key !== wanted) continue;
16468
- const stored = await vaultMemoryRawToStored(
16652
+ const stored2 = await vaultMemoryRawToStored(
16469
16653
  raw,
16470
16654
  ctx.walletAddress,
16471
16655
  ctx.signMessage,
16472
16656
  ctx.embeddedWalletSigner
16473
16657
  );
16474
- if (normalizeForDedupe(stored.content) === target) return stored.uniqueId;
16658
+ if (normalizeForDedupe(stored2.content) === target) return stored2.uniqueId;
16475
16659
  }
16476
16660
  return null;
16477
16661
  }
@@ -16581,25 +16765,26 @@ async function ingestPublishedPhotoMemoriesOp(ctx, rows) {
16581
16765
  inserted = writable.length;
16582
16766
  if (writable.length === 0) return;
16583
16767
  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(
16768
+ ({ row, content }) => ctx.vaultMemoryCollection.prepareCreate((record2) => {
16769
+ record2._raw.id = row.memoryId;
16770
+ record2._setRaw("content", content);
16771
+ record2._setRaw("scope", "shared");
16772
+ record2._setRaw("level", "matching");
16773
+ record2._setRaw("folder_id", null);
16774
+ record2._setRaw("user_id", ctx.userId ?? null);
16775
+ record2._setRaw("is_deleted", false);
16776
+ record2._setRaw("proof_count", 1);
16777
+ record2._setRaw("source", SOURCE_PHOTO);
16778
+ record2._setRaw(
16594
16779
  "media",
16595
16780
  row.media && row.media.length > 0 ? JSON.stringify(row.media) : null
16596
16781
  );
16597
- record._setRaw("visibility", "public");
16598
- record._setRaw("published_at", now);
16782
+ record2._setRaw("visibility", "public");
16783
+ record2._setRaw("published_at", now);
16599
16784
  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);
16785
+ record2._setRaw("event_time_start", row.eventTime.start ?? null);
16786
+ record2._setRaw("event_time_end", row.eventTime.end ?? null);
16787
+ record2._setRaw("event_time_kind", row.eventTime.kind ?? null);
16603
16788
  }
16604
16789
  })
16605
16790
  );
@@ -17421,11 +17606,11 @@ function folderToStored(folder) {
17421
17606
  }
17422
17607
  async function createVaultFolderOp(ctx, opts) {
17423
17608
  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);
17609
+ return ctx.vaultFolderCollection.create((record2) => {
17610
+ record2._setRaw("name", opts.name);
17611
+ record2._setRaw("scope", opts.scope ?? "private");
17612
+ record2._setRaw("is_system", opts.isSystem ?? false);
17613
+ record2._setRaw("is_deleted", false);
17429
17614
  });
17430
17615
  });
17431
17616
  return folderToStored(created);
@@ -17436,14 +17621,14 @@ async function getAllVaultFoldersOp(ctx) {
17436
17621
  }
17437
17622
  async function updateVaultFolderOp(ctx, id, opts) {
17438
17623
  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;
17624
+ const record2 = await ctx.vaultFolderCollection.find(id);
17625
+ if (record2.isDeleted) return null;
17626
+ const scopeChanged = opts.scope !== void 0 && opts.scope !== record2.scope;
17442
17627
  const updated = await ctx.database.write(async () => {
17443
17628
  const memories = scopeChanged ? await ctx.vaultMemoryCollection.query(import_watermelondb30.Q.where("folder_id", id), import_watermelondb30.Q.where("is_deleted", false)).fetch() : [];
17444
17629
  const updates = [];
17445
17630
  updates.push(
17446
- record.prepareUpdate((r) => {
17631
+ record2.prepareUpdate((r) => {
17447
17632
  if (opts.name !== void 0) r._setRaw("name", opts.name);
17448
17633
  if (opts.scope !== void 0) r._setRaw("scope", opts.scope);
17449
17634
  })
@@ -17451,6 +17636,7 @@ async function updateVaultFolderOp(ctx, id, opts) {
17451
17636
  for (const memory of memories) {
17452
17637
  updates.push(
17453
17638
  memory.prepareUpdate((r) => {
17639
+ r._setRaw("level", levelForScopeChange(r, opts.scope));
17454
17640
  r._setRaw("scope", opts.scope);
17455
17641
  })
17456
17642
  );
@@ -17465,17 +17651,18 @@ async function updateVaultFolderOp(ctx, id, opts) {
17465
17651
  }
17466
17652
  async function deleteVaultFolderOp(ctx, id) {
17467
17653
  try {
17468
- const record = await ctx.vaultFolderCollection.find(id);
17469
- if (record.isDeleted) return false;
17654
+ const record2 = await ctx.vaultFolderCollection.find(id);
17655
+ if (record2.isDeleted) return false;
17470
17656
  await ctx.database.write(async () => {
17471
17657
  const memories = await ctx.vaultMemoryCollection.query(import_watermelondb30.Q.where("folder_id", id), import_watermelondb30.Q.where("is_deleted", false)).fetch();
17472
17658
  const preparedMemories = memories.map(
17473
17659
  (memory) => memory.prepareUpdate((r) => {
17474
17660
  r._setRaw("folder_id", null);
17661
+ r._setRaw("level", levelForScopeChange(r, "private"));
17475
17662
  r._setRaw("scope", "private");
17476
17663
  })
17477
17664
  );
17478
- const preparedFolder = record.prepareUpdate((r) => {
17665
+ const preparedFolder = record2.prepareUpdate((r) => {
17479
17666
  r._setRaw("is_deleted", true);
17480
17667
  });
17481
17668
  await ctx.database.batch(...preparedMemories, preparedFolder);
@@ -17508,6 +17695,7 @@ async function moveMemoriesToFolderOp(ctx, memoryIds, folderId) {
17508
17695
  const prepared = memories.map(
17509
17696
  (memory) => memory.prepareUpdate((r) => {
17510
17697
  r._setRaw("folder_id", folderId);
17698
+ r._setRaw("level", levelForScopeChange(r, targetScope));
17511
17699
  r._setRaw("scope", targetScope);
17512
17700
  })
17513
17701
  );
@@ -17521,11 +17709,11 @@ async function moveMemoriesToFolderOp(ctx, memoryIds, folderId) {
17521
17709
  }
17522
17710
  async function updateVaultFolderContextOp(ctx, id, context) {
17523
17711
  try {
17524
- const record = await ctx.vaultFolderCollection.find(id);
17525
- if (record.isDeleted) return null;
17712
+ const record2 = await ctx.vaultFolderCollection.find(id);
17713
+ if (record2.isDeleted) return null;
17526
17714
  const updated = await ctx.database.write(async () => {
17527
17715
  await ctx.database.batch(
17528
- record.prepareUpdate((r) => {
17716
+ record2.prepareUpdate((r) => {
17529
17717
  r._setRaw("context", context);
17530
17718
  })
17531
17719
  );
@@ -19606,7 +19794,7 @@ async function rankPreparedVaultCandidates(query, prepared, embeddingOptions, se
19606
19794
  if (useFusion && !embeddingsUnavailable && facetQueries) {
19607
19795
  let subEmbeddings;
19608
19796
  try {
19609
- subEmbeddings = await generateEmbeddings(facetQueries, embeddingOptions);
19797
+ subEmbeddings = prepared.facetEmbeddings ?? await generateEmbeddings(facetQueries, embeddingOptions);
19610
19798
  } catch (err) {
19611
19799
  getLogger().warn(
19612
19800
  "memoryVault: sub-query embedding failed \u2014 falling back to single-query ranking: " + (err instanceof Error ? err.message : String(err))
@@ -19792,6 +19980,35 @@ var DEFAULT_SCOPE = "private";
19792
19980
  var DEFAULT_CONSOLIDATE_THRESHOLD = 0.55;
19793
19981
  var DEFAULT_CONSOLIDATE_TOP_K = 20;
19794
19982
  async function retain(content, ctx, options = {}) {
19983
+ return retainWithPersistence(
19984
+ content,
19985
+ {
19986
+ embeddingOptions: ctx.embeddingOptions,
19987
+ vaultCache: ctx.vaultCache,
19988
+ persistence: {
19989
+ prepare: (query, searchOptions) => prepareVaultCandidates(
19990
+ query,
19991
+ ctx.vaultCtx,
19992
+ ctx.embeddingOptions,
19993
+ ctx.vaultCache,
19994
+ searchOptions
19995
+ ),
19996
+ get: (id) => getVaultMemoryOp(ctx.vaultCtx, id),
19997
+ tombstones: (_embedding, _model, scope, folderId) => getAllVaultMemoriesOp(ctx.vaultCtx, {
19998
+ includeDeleted: true,
19999
+ scopes: [scope],
20000
+ ...folderId !== void 0 && { folderId }
20001
+ }),
20002
+ create: (input) => createVaultMemoryOp(ctx.vaultCtx, input),
20003
+ update: (id, patch) => updateVaultMemoryOp(ctx.vaultCtx, id, patch),
20004
+ supersede: (id, successor) => supersedeVaultMemoryOp(ctx.vaultCtx, id, successor),
20005
+ createSuperseding: (input, target) => createSupersedingMemoryOp(ctx.vaultCtx, input, target)
20006
+ }
20007
+ },
20008
+ options
20009
+ );
20010
+ }
20011
+ async function retainWithPersistence(content, ctx, options = {}) {
19795
20012
  const trimmed = content.trim();
19796
20013
  if (trimmed.length === 0) {
19797
20014
  throw new Error("retain: content cannot be empty");
@@ -19804,19 +20021,14 @@ async function retain(content, ctx, options = {}) {
19804
20021
  let supersedeContent;
19805
20022
  let prepared;
19806
20023
  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
- );
20024
+ prepared = await ctx.persistence.prepare(trimmed, {
20025
+ limit: Math.max(options.consolidateTopK ?? DEFAULT_CONSOLIDATE_TOP_K, 1),
20026
+ useFusion: false,
20027
+ scopes: [resolvedScope],
20028
+ includeArchived: true,
20029
+ ...options.folderId !== void 0 && { folderId: options.folderId }
20030
+ });
20031
+ prepared = withoutKindedRows(prepared);
19820
20032
  if (prepared.embeddingFailure || prepared.embeddingsUnavailable) {
19821
20033
  throw new Error(
19822
20034
  "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 +20059,7 @@ async function retain(content, ctx, options = {}) {
19847
20059
  );
19848
20060
  if (matches.length > 0) {
19849
20061
  const targetId = matches[0].uniqueId;
19850
- const existing = await getVaultMemoryOp(ctx.vaultCtx, targetId);
20062
+ const existing = await ctx.persistence.get(targetId);
19851
20063
  if (existing && !existing.supersededBy) {
19852
20064
  const mergedSourceIds = unionStrings(
19853
20065
  existing.sourceChunkIds ?? [],
@@ -19856,8 +20068,9 @@ async function retain(content, ctx, options = {}) {
19856
20068
  const eventTimeUpdate = pickEventTimeUpdate(existing, options.eventTime);
19857
20069
  const factTypeUpdate = pickFactTypeUpdate(existing, options.factType);
19858
20070
  const resurrect = resurrectFields(existing);
19859
- const updated = await updateVaultMemoryOp(ctx.vaultCtx, targetId, {
20071
+ const updated = await ctx.persistence.update(targetId, {
19860
20072
  content: existing.content,
20073
+ freeFormOnly: true,
19861
20074
  proofCountIncrement: 1,
19862
20075
  observationSourceIds: options.sourceChunkIds,
19863
20076
  sourceChunkIds: mergedSourceIds,
@@ -19883,7 +20096,8 @@ async function retain(content, ctx, options = {}) {
19883
20096
  }
19884
20097
  const contentToWrite = supersedeContent ?? trimmed;
19885
20098
  const reusableQueryEmbedding = supersedeContent === void 0 && prepared && prepared.queryEmbedding.length > 0 ? prepared.queryEmbedding : void 0;
19886
- const embedding = reusableQueryEmbedding ?? await generateEmbedding(contentToWrite, ctx.embeddingOptions);
20099
+ const generatedEmbedding = reusableQueryEmbedding ?? await generateEmbedding(contentToWrite, ctx.embeddingOptions);
20100
+ const embedding = ctx.normalizeEmbedding?.(generatedEmbedding) ?? generatedEmbedding;
19887
20101
  const embeddingModel = ctx.embeddingOptions.model ?? DEFAULT_API_EMBEDDING_MODEL;
19888
20102
  if (options.respectTombstones) {
19889
20103
  const tombstone = await findTombstoneMatch(embedding, embeddingModel, resolvedScope, ctx, {
@@ -19923,8 +20137,7 @@ async function retain(content, ctx, options = {}) {
19923
20137
  };
19924
20138
  if (supersedeTargetIds.length > 0) {
19925
20139
  const [primaryTargetId, ...restTargetIds] = supersedeTargetIds;
19926
- const { created: created2, retired } = await createSupersedingMemoryOp(
19927
- ctx.vaultCtx,
20140
+ const { created: created2, retired } = await ctx.persistence.createSuperseding(
19928
20141
  createOpts,
19929
20142
  primaryTargetId
19930
20143
  );
@@ -19940,11 +20153,11 @@ async function retain(content, ctx, options = {}) {
19940
20153
  for (const staleId of restTargetIds) {
19941
20154
  let ok = false;
19942
20155
  try {
19943
- ok = await supersedeVaultMemoryOp(ctx.vaultCtx, staleId, created2.uniqueId) === true;
20156
+ ok = await ctx.persistence.supersede(staleId, created2.uniqueId) === true;
19944
20157
  } catch {
19945
20158
  }
19946
20159
  if (ok) continue;
19947
- const stillLive = await getVaultMemoryOp(ctx.vaultCtx, staleId).catch(() => null);
20160
+ const stillLive = await (ctx.persistence.getFresh ? ctx.persistence.getFresh(staleId) : ctx.persistence.get(staleId)).catch(() => null);
19948
20161
  if (stillLive && !stillLive.supersededBy) liveLeftovers.push(staleId);
19949
20162
  }
19950
20163
  if (liveLeftovers.length > 0) {
@@ -19971,7 +20184,7 @@ async function retain(content, ctx, options = {}) {
19971
20184
  `supersede: primary target ${primaryTargetId} retired or deleted inside the atomic write`
19972
20185
  );
19973
20186
  }
19974
- const created = await createVaultMemoryOp(ctx.vaultCtx, createOpts);
20187
+ const created = await ctx.persistence.create(createOpts);
19975
20188
  cacheRowVector(
19976
20189
  ctx.vaultCache,
19977
20190
  created.uniqueId,
@@ -19986,15 +20199,22 @@ async function retain(content, ctx, options = {}) {
19986
20199
  ...consolidationDecidedCreate && { consolidation: "create" }
19987
20200
  };
19988
20201
  }
20202
+ function withoutKindedRows(prepared) {
20203
+ const kinded = new Set(
20204
+ prepared.memories.filter((m) => m.kind !== null && m.kind !== void 0).map((m) => m.uniqueId)
20205
+ );
20206
+ if (kinded.size === 0) return prepared;
20207
+ return {
20208
+ ...prepared,
20209
+ memories: prepared.memories.filter((m) => !kinded.has(m.uniqueId)),
20210
+ embeddedItems: prepared.embeddedItems.filter((item) => !kinded.has(item.id))
20211
+ };
20212
+ }
19989
20213
  function unionStrings(a, b) {
19990
20214
  return [.../* @__PURE__ */ new Set([...a, ...b])];
19991
20215
  }
19992
20216
  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
- });
20217
+ const rows = await ctx.persistence.tombstones(embedding, embeddingModel, scope, opts.folderId);
19998
20218
  let bestId = null;
19999
20219
  let bestSim = opts.threshold;
20000
20220
  for (const row of rows) {
@@ -20061,7 +20281,7 @@ async function tryConsolidate(trimmed, ctx, options, prepared) {
20061
20281
  if (requestedIds.length === 0) return null;
20062
20282
  const valid = [];
20063
20283
  for (const id of requestedIds) {
20064
- const existing = await getVaultMemoryOp(ctx.vaultCtx, id);
20284
+ const existing = await ctx.persistence.get(id);
20065
20285
  if (existing && !existing.supersededBy) valid.push(id);
20066
20286
  }
20067
20287
  if (valid.length === 0) {
@@ -20073,7 +20293,7 @@ async function tryConsolidate(trimmed, ctx, options, prepared) {
20073
20293
  return { supersede: valid, content: decision.content };
20074
20294
  }
20075
20295
  if (decision.action === "noop" && decision.targetId) {
20076
- const existing = await getVaultMemoryOp(ctx.vaultCtx, decision.targetId);
20296
+ const existing = await ctx.persistence.get(decision.targetId);
20077
20297
  if (!existing || existing.supersededBy) {
20078
20298
  return abandonToRace(
20079
20299
  options,
@@ -20087,8 +20307,9 @@ async function tryConsolidate(trimmed, ctx, options, prepared) {
20087
20307
  const eventTimeUpdate = pickEventTimeUpdate(existing, options.eventTime);
20088
20308
  const factTypeUpdate = pickFactTypeUpdate(existing, options.factType);
20089
20309
  const resurrect = resurrectFields(existing);
20090
- const updated = await updateVaultMemoryOp(ctx.vaultCtx, decision.targetId, {
20310
+ const updated = await ctx.persistence.update(decision.targetId, {
20091
20311
  content: existing.content,
20312
+ freeFormOnly: true,
20092
20313
  proofCountIncrement: 1,
20093
20314
  observationSourceIds: options.sourceChunkIds,
20094
20315
  sourceChunkIds: mergedSourceIds,
@@ -20115,7 +20336,7 @@ async function tryConsolidate(trimmed, ctx, options, prepared) {
20115
20336
  };
20116
20337
  }
20117
20338
  if (decision.action === "update" && decision.targetId && decision.content) {
20118
- const existing = await getVaultMemoryOp(ctx.vaultCtx, decision.targetId);
20339
+ const existing = await ctx.persistence.get(decision.targetId);
20119
20340
  if (!existing || existing.supersededBy) {
20120
20341
  return abandonToRace(
20121
20342
  options,
@@ -20126,13 +20347,15 @@ async function tryConsolidate(trimmed, ctx, options, prepared) {
20126
20347
  existing.sourceChunkIds ?? [],
20127
20348
  options.sourceChunkIds ?? []
20128
20349
  );
20129
- const newEmbedding = await generateEmbedding(decision.content, ctx.embeddingOptions);
20350
+ const generatedEmbedding = await generateEmbedding(decision.content, ctx.embeddingOptions);
20351
+ const newEmbedding = ctx.normalizeEmbedding?.(generatedEmbedding) ?? generatedEmbedding;
20130
20352
  const consolidatedModel = ctx.embeddingOptions.model ?? DEFAULT_API_EMBEDDING_MODEL;
20131
20353
  const eventTimeUpdate = pickEventTimeUpdate(existing, options.eventTime);
20132
20354
  const factTypeUpdate = pickFactTypeUpdate(existing, options.factType);
20133
20355
  const resurrect = resurrectFields(existing);
20134
- const updated = await updateVaultMemoryOp(ctx.vaultCtx, decision.targetId, {
20356
+ const updated = await ctx.persistence.update(decision.targetId, {
20135
20357
  content: decision.content,
20358
+ freeFormOnly: true,
20136
20359
  proofCountIncrement: 1,
20137
20360
  observationSourceIds: options.sourceChunkIds,
20138
20361
  sourceChunkIds: mergedSourceIds,
@@ -20175,8 +20398,8 @@ async function tryConsolidate(trimmed, ctx, options, prepared) {
20175
20398
  return null;
20176
20399
  }
20177
20400
  async function assertMergeTargetGoneOrThrow(ctx, targetId) {
20178
- const stillExists = await getVaultMemoryOp(ctx.vaultCtx, targetId);
20179
- if (stillExists) {
20401
+ const stillExists = await (ctx.persistence.getFresh ? ctx.persistence.getFresh(targetId) : ctx.persistence.get(targetId));
20402
+ if (stillExists && (stillExists.kind === null || stillExists.kind === void 0)) {
20180
20403
  throw new Error(`retain: merge into memory ${targetId} failed to persist`);
20181
20404
  }
20182
20405
  }
@@ -20692,9 +20915,9 @@ function createAutoExtractor(options) {
20692
20915
  const persistCursor = (conversationId, messages, advancedToId, contiguous) => {
20693
20916
  if (!cursorStore || conversationId === void 0 || !contiguous) return;
20694
20917
  try {
20695
- const stored = cursorStore.get(conversationId);
20696
- if (stored && stored !== advancedToId) {
20697
- const storedIdx = messages.findIndex((m) => m.id === stored);
20918
+ const stored2 = cursorStore.get(conversationId);
20919
+ if (stored2 && stored2 !== advancedToId) {
20920
+ const storedIdx = messages.findIndex((m) => m.id === stored2);
20698
20921
  const newIdx = messages.findIndex((m) => m.id === advancedToId);
20699
20922
  if (storedIdx !== -1 && newIdx !== -1 && storedIdx >= newIdx) return;
20700
20923
  }
@@ -21674,7 +21897,7 @@ async function recall(query, ctx, options = {}) {
21674
21897
  if (graphLaneFailed) degraded.push("graph-lane-failed");
21675
21898
  if (temporalLaneFailed) degraded.push("temporal-lane-failed");
21676
21899
  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;
21900
+ const laneRan = types.includes("fact") && (!!ctx.factSource || !!ctx.vaultCtx && !!ctx.vaultCache) || types.includes("chunk") && !!ctx.storageCtx || chunksScopeRestricted && !!ctx.storageCtx;
21678
21901
  const scores = admitted.map((m) => m.score);
21679
21902
  const minScoreApplied = factResults.length > 0 ? factFloor : chunkResults.length > 0 ? chunkFloor : factFloor >= 0 ? factFloor : chunkFloor;
21680
21903
  const diagnostics = {
@@ -21716,7 +21939,7 @@ async function recall(query, ctx, options = {}) {
21716
21939
  return { memories: [], usedBudget, reranked: false, candidateCount: 0 };
21717
21940
  }
21718
21941
  const needsChunkEmbedding = types.includes("chunk") && ctx.storageCtx;
21719
- const wantsTemporal = types.includes("fact") && ctx.vaultCtx;
21942
+ const wantsTemporal = types.includes("fact") && (ctx.factSource || ctx.vaultCtx);
21720
21943
  const graphRefiner = flags.traverse && options.graphRefine && options.decomposeOptions ? createLlmNeighborRefiner(options.decomposeOptions) : void 0;
21721
21944
  const queryEmbedTotalTimeoutMs = options.queryEmbedTotalTimeoutMs ?? DEFAULT_QUERY_EMBED_TOTAL_TIMEOUT_MS;
21722
21945
  const prepStart = nowMs2();
@@ -21746,7 +21969,7 @@ async function recall(query, ctx, options = {}) {
21746
21969
  safeLane(
21747
21970
  "graph",
21748
21971
  () => graphLaneFailed = true,
21749
- () => buildGraphLaneRanking(query, ctx, flags.traverse, {
21972
+ () => ctx.factSource ? ctx.factSource.graphRanking(query, flags.traverse, options) : buildGraphLaneRanking(query, ctx, flags.traverse, {
21750
21973
  ...options.maxHops !== void 0 && { maxHops: options.maxHops },
21751
21974
  ...options.entityFanout !== void 0 && { entityFanout: options.entityFanout },
21752
21975
  ...options.nodeBudget !== void 0 && { nodeBudget: options.nodeBudget },
@@ -21757,13 +21980,13 @@ async function recall(query, ctx, options = {}) {
21757
21980
  wantsTemporal ? safeLane(
21758
21981
  "temporal",
21759
21982
  () => temporalLaneFailed = true,
21760
- () => buildTemporalLaneRanking(query, ctx.vaultCtx, options.now)
21983
+ () => ctx.factSource ? ctx.factSource.temporalRanking(query, options.now) : buildTemporalLaneRanking(query, ctx.vaultCtx, options.now)
21761
21984
  ) : Promise.resolve([])
21762
21985
  ]);
21763
21986
  prepMs = nowMs2() - prepStart;
21764
21987
  graphLaneCount = entityRanking.length;
21765
21988
  temporalLaneCount = temporalRanking.length;
21766
- if (types.includes("fact") && ctx.vaultCtx && ctx.vaultCache) {
21989
+ if (types.includes("fact") && (ctx.factSource || ctx.vaultCtx && ctx.vaultCache)) {
21767
21990
  const factStart = nowMs2();
21768
21991
  const vaultMinScore = options.minScore ?? DEFAULT_FACT_MIN_SCORE;
21769
21992
  factFloor = vaultMinScore;
@@ -21779,50 +22002,50 @@ async function recall(query, ctx, options = {}) {
21779
22002
  rankedOnCosine: factRankedOnCosine,
21780
22003
  decryptLast: factDecryptLast,
21781
22004
  rowsDecrypted: factRowsDecrypted
21782
- } = await searchVaultMemoriesWithSize(
21783
- query,
22005
+ } = await (ctx.factSource?.search.bind(ctx.factSource) ?? ((searchQuery, searchOptions) => searchVaultMemoriesWithSize(
22006
+ searchQuery,
21784
22007
  ctx.vaultCtx,
21785
22008
  ctx.embeddingOptions,
21786
22009
  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
- );
22010
+ searchOptions
22011
+ )))(query, {
22012
+ limit: types.includes("chunk") ? Math.max(limit * 2, 16) : limit,
22013
+ minSimilarity: vaultMinScore,
22014
+ useFusion: true,
22015
+ rerank: flags.rerank,
22016
+ ...options.rerankTopN !== void 0 && { rerankTopN: options.rerankTopN },
22017
+ ...options.ceWeight !== void 0 && { ceWeight: options.ceWeight },
22018
+ ...options.rerankLoadTimeoutMs !== void 0 && {
22019
+ rerankLoadTimeoutMs: options.rerankLoadTimeoutMs
22020
+ },
22021
+ ...options.recencyAlpha !== void 0 && { recencyAlpha: options.recencyAlpha },
22022
+ ...options.recency && { recency: options.recency },
22023
+ ...options.mmr !== void 0 && { mmr: options.mmr },
22024
+ ...options.supersessionBoost !== void 0 && {
22025
+ supersessionBoost: options.supersessionBoost
22026
+ },
22027
+ ...options.supersessionWindow !== void 0 && {
22028
+ supersessionWindow: options.supersessionWindow
22029
+ },
22030
+ ...options.proofCountAlpha !== void 0 && {
22031
+ proofCountAlpha: options.proofCountAlpha
22032
+ },
22033
+ ...options.bm25AdmissionDivisor !== void 0 && {
22034
+ bm25AdmissionDivisor: options.bm25AdmissionDivisor
22035
+ },
22036
+ ...options.rrfK !== void 0 && { rrfK: options.rrfK },
22037
+ ...options.decryptLast !== void 0 && { decryptLast: options.decryptLast },
22038
+ ...subQueries && { subQueries },
22039
+ ...options.scopes && { scopes: options.scopes },
22040
+ ...options.folderId !== void 0 && { folderId: options.folderId },
22041
+ ...options.factTypes?.length && { factTypes: options.factTypes },
22042
+ ...options.memoryIds !== void 0 && { memoryIds: options.memoryIds },
22043
+ ...options.factTypeWeights && { factTypeWeights: options.factTypeWeights },
22044
+ ...entityRanking.length > 0 && { entityRanking },
22045
+ ...temporalRanking.length > 0 && { temporalRanking },
22046
+ ...needsChunkEmbedding && { queryEmbedding: queryEmbedding ?? [] },
22047
+ queryEmbedTotalTimeoutMs
22048
+ });
21826
22049
  factResults.push(
21827
22050
  ...dedupeBy(
21828
22051
  results,
@@ -22635,26 +22858,26 @@ async function extractAndLinkEntitiesForMemoriesOp(ctx, memoryIds, options) {
22635
22858
  };
22636
22859
  const inputs = [];
22637
22860
  for (const id of new Set(memoryIds)) {
22638
- let record;
22861
+ let record2;
22639
22862
  try {
22640
- record = await ctx.vaultMemoryCollection.find(id);
22863
+ record2 = await ctx.vaultMemoryCollection.find(id);
22641
22864
  } catch (err) {
22642
22865
  log.warn("[memory/topics] vault lookup failed for extraction", err);
22643
22866
  skip(id, "not-found");
22644
22867
  continue;
22645
22868
  }
22646
- if (record.isDeleted || ctx.userId !== void 0 && record.userId !== ctx.userId || record.topicsUserManaged) {
22869
+ if (record2.isDeleted || ctx.userId !== void 0 && record2.userId !== ctx.userId || record2.topicsUserManaged) {
22647
22870
  skip(id, "excluded");
22648
22871
  continue;
22649
22872
  }
22650
22873
  try {
22651
- const stored = await vaultMemoryToStored(
22652
- record,
22874
+ const stored2 = await vaultMemoryToStored(
22875
+ record2,
22653
22876
  ctx.walletAddress,
22654
22877
  ctx.signMessage,
22655
22878
  ctx.embeddedWalletSigner
22656
22879
  );
22657
- inputs.push({ id, content: stored.content });
22880
+ inputs.push({ id, content: stored2.content });
22658
22881
  } catch (err) {
22659
22882
  log.warn("[memory/topics] failed to load memory for extraction", err);
22660
22883
  skip(id, "unreadable");
@@ -22839,6 +23062,781 @@ function createLocalMemoryStore(options) {
22839
23062
  };
22840
23063
  }
22841
23064
 
23065
+ // src/lib/memory/store/remotePersistence.ts
23066
+ var RemoteMemoryError = class extends Error {
23067
+ constructor(message, status, code) {
23068
+ super(message);
23069
+ this.status = status;
23070
+ this.code = code;
23071
+ this.name = "RemoteMemoryError";
23072
+ }
23073
+ };
23074
+ var ciphertextPattern = /^enc:v\d+:[0-9a-f]+$/i;
23075
+ var memoryFields = {
23076
+ memory_id: true,
23077
+ content: true,
23078
+ scope: true,
23079
+ created_at: true,
23080
+ updated_at: true,
23081
+ is_deleted: true,
23082
+ embedding: true,
23083
+ embedding_model: true,
23084
+ kind: true,
23085
+ kind_value: true,
23086
+ level: true,
23087
+ folder_id: true,
23088
+ source_chunk_ids: true,
23089
+ proof_count: true,
23090
+ source: true,
23091
+ event_time_start: true,
23092
+ event_time_end: true,
23093
+ event_time_kind: true,
23094
+ topics_user_managed: true,
23095
+ topics: true,
23096
+ topics_updated_at: true,
23097
+ media: true,
23098
+ topics_extracted_at: true,
23099
+ topics_extracted_version: true,
23100
+ superseded_by: true,
23101
+ superseded_at: true,
23102
+ last_observed_at: true,
23103
+ fact_type: true,
23104
+ archived_at: true,
23105
+ trust_tier: true,
23106
+ visibility: true,
23107
+ twin_opt_in: true,
23108
+ published_at: true,
23109
+ geohash: true
23110
+ };
23111
+ var candidateListLimits = [
23112
+ ["scopes", 20],
23113
+ ["fact_types", 20],
23114
+ ["memory_ids", 1e3],
23115
+ ["force_ids", 100]
23116
+ ];
23117
+ function record(value) {
23118
+ return typeof value === "object" && value !== null && !Array.isArray(value);
23119
+ }
23120
+ function memoryRecord(value) {
23121
+ 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))) {
23122
+ throw new Error("Invalid nearby private-memory response");
23123
+ }
23124
+ return value;
23125
+ }
23126
+ async function createRemoteMemoryPersistence(options) {
23127
+ const base = new URL(options.baseUrl);
23128
+ if (!/^https?:$/.test(base.protocol) || base.username || base.password || base.search || base.hash) {
23129
+ throw new Error(
23130
+ "baseUrl must be an HTTP(S) origin or base path without credentials, query or fragment"
23131
+ );
23132
+ }
23133
+ if (!options.keyId || options.keyId.length > 256)
23134
+ throw new Error("A canonical keyId is required");
23135
+ const timeoutMs = options.timeoutMs ?? 3e4;
23136
+ if (!Number.isFinite(timeoutMs) || timeoutMs <= 0)
23137
+ throw new Error("timeoutMs must be a positive number");
23138
+ const root = base.href.replace(/\/$/, "") + "/api/private-memories";
23139
+ const fetcher = options.fetch ?? globalThis.fetch;
23140
+ const request = async (path, init = {}, signal) => {
23141
+ const controller = new AbortController();
23142
+ let timedOut = false;
23143
+ const timer = setTimeout(() => {
23144
+ timedOut = true;
23145
+ controller.abort();
23146
+ }, timeoutMs);
23147
+ const forwardAbort = () => controller.abort(signal?.reason);
23148
+ if (signal?.aborted) forwardAbort();
23149
+ else signal?.addEventListener("abort", forwardAbort, { once: true });
23150
+ let rejectAborted;
23151
+ const aborted = new Promise((_, reject) => {
23152
+ rejectAborted = () => reject(
23153
+ controller.signal.reason instanceof Error ? controller.signal.reason : new Error("Nearby request aborted")
23154
+ );
23155
+ if (controller.signal.aborted) rejectAborted();
23156
+ else controller.signal.addEventListener("abort", rejectAborted, { once: true });
23157
+ });
23158
+ aborted.catch(() => void 0);
23159
+ try {
23160
+ const token = await Promise.race([options.getToken(), aborted]);
23161
+ if (controller.signal.aborted) await aborted;
23162
+ if (!token) throw new RemoteMemoryError("Authentication required", 401);
23163
+ const response = await fetcher(root + path, {
23164
+ ...init,
23165
+ headers: {
23166
+ Authorization: `Bearer ${token}`,
23167
+ ...init.body ? { "Content-Type": "application/json" } : {}
23168
+ },
23169
+ redirect: "error",
23170
+ signal: controller.signal
23171
+ });
23172
+ if (!response.ok) {
23173
+ const body = await response.json().catch(() => null);
23174
+ throw new RemoteMemoryError(
23175
+ record(body) && typeof body.detail === "string" ? body.detail : `Nearby request failed (${response.status})`,
23176
+ response.status,
23177
+ record(body) && typeof body.code === "string" ? body.code : void 0
23178
+ );
23179
+ }
23180
+ return await response.json();
23181
+ } catch (error) {
23182
+ if (timedOut) throw new RemoteMemoryError("Nearby request timed out", 408, "timeout");
23183
+ throw error;
23184
+ } finally {
23185
+ clearTimeout(timer);
23186
+ signal?.removeEventListener("abort", forwardAbort);
23187
+ if (rejectAborted) controller.signal.removeEventListener("abort", rejectAborted);
23188
+ }
23189
+ };
23190
+ const account = await request("/account", {}, options.signal);
23191
+ if (!record(account) || account.state !== "active") {
23192
+ throw new RemoteMemoryError(
23193
+ "Complete and verify migration before using remote memories",
23194
+ 409,
23195
+ "memory_not_active"
23196
+ );
23197
+ }
23198
+ if (account.key_id !== options.keyId) {
23199
+ throw new RemoteMemoryError(
23200
+ "The canonical memory key does not match this account",
23201
+ 409,
23202
+ "key_mismatch"
23203
+ );
23204
+ }
23205
+ const snapshots = /* @__PURE__ */ new WeakMap();
23206
+ const decode = async (value) => {
23207
+ const item = memoryRecord(value);
23208
+ const decrypt = async (ciphertext) => {
23209
+ if (!ciphertextPattern.test(ciphertext))
23210
+ throw new Error("Nearby returned unencrypted memory content");
23211
+ const plaintext = await options.decrypt(ciphertext);
23212
+ if (plaintext === ciphertext) throw new Error("Memory decryption failed");
23213
+ return plaintext;
23214
+ };
23215
+ const decoded = {
23216
+ ...item,
23217
+ memory: {
23218
+ ...item.memory,
23219
+ content: await decrypt(item.memory.content),
23220
+ ...item.memory.kind_value !== void 0 && {
23221
+ kind_value: await decrypt(item.memory.kind_value)
23222
+ }
23223
+ }
23224
+ };
23225
+ return remember(decoded, item);
23226
+ };
23227
+ const remember = (decoded, item) => {
23228
+ snapshots.set(decoded, {
23229
+ id: item.memory.memory_id,
23230
+ version: item.version,
23231
+ content: decoded.memory.content,
23232
+ kindValue: decoded.memory.kind_value,
23233
+ encryptedContent: item.memory.content,
23234
+ encryptedKindValue: item.memory.kind_value
23235
+ });
23236
+ return decoded;
23237
+ };
23238
+ const decodeAll = async (values) => {
23239
+ const records = values.map(memoryRecord);
23240
+ const settled = await Promise.allSettled(records.map(decode));
23241
+ const items = [];
23242
+ const failed = [];
23243
+ settled.forEach((result, i) => {
23244
+ if (result.status === "fulfilled") items.push(result.value);
23245
+ else
23246
+ failed.push({
23247
+ memory_id: records[i].memory.memory_id,
23248
+ version: records[i].version,
23249
+ error: result.reason instanceof Error ? result.reason : new Error(String(result.reason))
23250
+ });
23251
+ });
23252
+ return { items, failed };
23253
+ };
23254
+ const decodeCommitted = async (value, write) => {
23255
+ const item = memoryRecord(value);
23256
+ 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)
23257
+ return decode(item);
23258
+ return remember(
23259
+ {
23260
+ ...item,
23261
+ memory: {
23262
+ ...item.memory,
23263
+ content: write.content,
23264
+ ...write.kindValue !== void 0 && { kind_value: write.kindValue }
23265
+ }
23266
+ },
23267
+ item
23268
+ );
23269
+ };
23270
+ const encryptField2 = async (plaintext) => {
23271
+ const ciphertext = await options.encrypt(plaintext);
23272
+ if (ciphertext === plaintext || !ciphertextPattern.test(ciphertext))
23273
+ throw new Error("Field encryption must return SDK ciphertext; refusing to upload plaintext");
23274
+ return ciphertext;
23275
+ };
23276
+ const memoryPath = (id) => {
23277
+ if (!id || id.length > 128) throw new Error("memory_id must be 1\u2013128 characters");
23278
+ return "/memories/" + encodeURIComponent(id);
23279
+ };
23280
+ const prepareWrite = async (memory, expectedVersion, signal) => {
23281
+ const unknown = Object.keys(memory).filter(
23282
+ (key) => !Object.prototype.hasOwnProperty.call(memoryFields, key)
23283
+ );
23284
+ if (unknown.length) {
23285
+ throw new RemoteMemoryError(
23286
+ `Unknown private-memory fields (${unknown.join(", ")}); refusing to forward them`,
23287
+ 400,
23288
+ "unknown_field"
23289
+ );
23290
+ }
23291
+ memory = { ...memory, ...memory.embedding && { embedding: [...memory.embedding] } };
23292
+ const path = memoryPath(memory.memory_id);
23293
+ const snapshot = typeof expectedVersion === "number" ? void 0 : snapshots.get(expectedVersion);
23294
+ if (typeof expectedVersion !== "number" && (!snapshot || snapshot.id !== memory.memory_id || snapshot.version !== expectedVersion.version))
23295
+ throw new Error(
23296
+ "Expected snapshot must be an unmodified version from this persistence instance"
23297
+ );
23298
+ expectedVersion = typeof expectedVersion === "number" ? expectedVersion : snapshot.version;
23299
+ if (!Number.isSafeInteger(expectedVersion) || expectedVersion < 0)
23300
+ throw new Error("expectedVersion must be a nonnegative integer");
23301
+ const conflict = () => new RemoteMemoryError("The memory changed since it was read", 409, "version_conflict");
23302
+ let existing;
23303
+ if (expectedVersion !== 0 && !snapshot) {
23304
+ try {
23305
+ existing = memoryRecord(await request(path, {}, signal));
23306
+ } catch (error) {
23307
+ if (error instanceof RemoteMemoryError && error.status === 404) throw conflict();
23308
+ throw error;
23309
+ }
23310
+ }
23311
+ if (existing && existing.version !== expectedVersion) throw conflict();
23312
+ const decoded = existing ? await decode(existing).catch(() => void 0) : void 0;
23313
+ const content = (snapshot?.content ?? decoded?.memory.content) === memory.content ? snapshot?.encryptedContent ?? existing.memory.content : await encryptField2(memory.content);
23314
+ 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);
23315
+ return {
23316
+ body: {
23317
+ expected_version: expectedVersion,
23318
+ memory: { ...memory, content, ...kindValue !== void 0 && { kind_value: kindValue } }
23319
+ },
23320
+ content: memory.content,
23321
+ kindValue: memory.kind_value
23322
+ };
23323
+ };
23324
+ const fetchCandidates = async (embedding, candidateOptions, withCounts) => {
23325
+ const limit = candidateOptions.limit ?? 100;
23326
+ if (!Number.isInteger(limit) || limit < 1 || limit > 100)
23327
+ throw new Error("Candidate limit must be 1\u2013100");
23328
+ for (const [key, max] of candidateListLimits) {
23329
+ const values = candidateOptions[key];
23330
+ if (values && values.length > max)
23331
+ throw new Error(`Candidate ${key} accepts at most ${max} entries (got ${values.length})`);
23332
+ }
23333
+ const result = await request(
23334
+ "/candidates",
23335
+ {
23336
+ method: "POST",
23337
+ body: JSON.stringify({
23338
+ embedding,
23339
+ limit,
23340
+ force_ids: candidateOptions.force_ids ?? [],
23341
+ ...withCounts && { with_counts: true },
23342
+ ...Object.fromEntries(
23343
+ [
23344
+ "scopes",
23345
+ "memory_ids",
23346
+ "embedding_model",
23347
+ "strict_model",
23348
+ "include_deleted",
23349
+ "deleted_only"
23350
+ ].filter(
23351
+ (key) => candidateOptions[key] !== void 0
23352
+ ).map((key) => [key, candidateOptions[key]])
23353
+ ),
23354
+ ...candidateOptions.fact_types !== void 0 && {
23355
+ fact_types: candidateOptions.fact_types
23356
+ },
23357
+ ...candidateOptions.include_archived !== void 0 && {
23358
+ include_archived: candidateOptions.include_archived
23359
+ },
23360
+ ...candidateOptions.include_quarantined !== void 0 && {
23361
+ include_quarantined: candidateOptions.include_quarantined
23362
+ },
23363
+ ...candidateOptions.include_superseded !== void 0 && {
23364
+ include_superseded: candidateOptions.include_superseded
23365
+ }
23366
+ })
23367
+ },
23368
+ candidateOptions.signal
23369
+ );
23370
+ if (!record(result) || !Array.isArray(result.items))
23371
+ throw new Error("Invalid nearby candidate response");
23372
+ return result;
23373
+ };
23374
+ const candidateSet = async (embedding, candidateOptions = {}) => {
23375
+ const result = await fetchCandidates(embedding, candidateOptions, true);
23376
+ if (!Number.isSafeInteger(result.total_count) || result.total_count < 0 || !Number.isSafeInteger(result.unavailable_count) || result.unavailable_count < 0)
23377
+ throw new Error("Invalid nearby candidate response");
23378
+ return {
23379
+ ...await decodeAll(result.items),
23380
+ total_count: result.total_count,
23381
+ unavailable_count: result.unavailable_count
23382
+ };
23383
+ };
23384
+ return {
23385
+ get: async (id, signal) => {
23386
+ try {
23387
+ return await decode(await request(memoryPath(id), {}, signal));
23388
+ } catch (error) {
23389
+ if (error instanceof RemoteMemoryError && error.status === 404) return null;
23390
+ throw error;
23391
+ }
23392
+ },
23393
+ list: async (listOptions = {}) => {
23394
+ const { signal, ...query } = listOptions;
23395
+ if (query.limit !== void 0 && (!Number.isInteger(query.limit) || query.limit < 1 || query.limit > 200)) {
23396
+ throw new Error("Page limit must be 1\u2013200");
23397
+ }
23398
+ const params = new URLSearchParams();
23399
+ for (const key of [
23400
+ "cursor",
23401
+ "limit",
23402
+ "include_deleted",
23403
+ "include_archived",
23404
+ "include_quarantined",
23405
+ "include_superseded",
23406
+ "include_embeddings"
23407
+ ]) {
23408
+ if (query[key] !== void 0) params.set(key, String(query[key]));
23409
+ }
23410
+ const page = await request("/memories?" + params.toString(), {}, signal);
23411
+ if (!record(page) || !Array.isArray(page.items) || page.next_cursor !== void 0 && typeof page.next_cursor !== "string") {
23412
+ throw new Error("Invalid nearby private-memory page");
23413
+ }
23414
+ return {
23415
+ ...await decodeAll(page.items),
23416
+ ...page.next_cursor !== void 0 && { next_cursor: page.next_cursor }
23417
+ };
23418
+ },
23419
+ put: async (memory, expectedVersion, signal) => {
23420
+ const write = await prepareWrite(memory, expectedVersion, signal);
23421
+ return decodeCommitted(
23422
+ await request(
23423
+ memoryPath(write.body.memory.memory_id),
23424
+ {
23425
+ method: "PUT",
23426
+ body: JSON.stringify({ key_id: options.keyId, ...write.body })
23427
+ },
23428
+ signal
23429
+ ),
23430
+ write
23431
+ );
23432
+ },
23433
+ putMany: async (writes, signal) => {
23434
+ if (writes.length < 1 || writes.length > 50 || new Set(writes.map((w) => w.memory.memory_id)).size !== writes.length)
23435
+ throw new Error("Batch must contain 1\u201350 distinct memory ids");
23436
+ const prepared = await Promise.all(
23437
+ writes.map((w) => prepareWrite(w.memory, w.expectedVersion, signal))
23438
+ );
23439
+ const result = await request(
23440
+ "/memories/batch",
23441
+ {
23442
+ method: "POST",
23443
+ body: JSON.stringify({ key_id: options.keyId, writes: prepared.map((w) => w.body) })
23444
+ },
23445
+ signal
23446
+ );
23447
+ if (!record(result) || !Array.isArray(result.items) || result.items.length !== prepared.length)
23448
+ throw new Error("Invalid nearby batch response");
23449
+ return Promise.all(result.items.map((item, i) => decodeCommitted(item, prepared[i])));
23450
+ },
23451
+ candidateSet,
23452
+ candidates: async (embedding, candidateOptions = {}) => decodeAll((await fetchCandidates(embedding, candidateOptions, false)).items)
23453
+ };
23454
+ }
23455
+
23456
+ // src/lib/memory/store/remotePipeline.ts
23457
+ var import_uuid5 = require("uuid");
23458
+ init_logger();
23459
+ function storedVector(vector) {
23460
+ if (!Array.isArray(vector) || vector.length !== 1536 && vector.length !== 4096 || vector.some((v) => !Number.isFinite(v)))
23461
+ throw new Error("Remote memories require a finite 1536/4096-dimensional vector");
23462
+ const out = vector.slice(0, 1536);
23463
+ const norm = Math.sqrt(out.reduce((sum, v) => sum + v * v, 0));
23464
+ if (!norm) throw new Error("Remote query/content vector has no direction after MRL truncation");
23465
+ return out.map((v) => v / norm);
23466
+ }
23467
+ function sourceIds(value) {
23468
+ if (!value) return [];
23469
+ try {
23470
+ const parsed = JSON.parse(value);
23471
+ return Array.isArray(parsed) ? parsed.filter((id) => typeof id === "string") : [];
23472
+ } catch {
23473
+ return [];
23474
+ }
23475
+ }
23476
+ function isMemoryLevel(value) {
23477
+ return MEMORY_LEVELS.includes(value);
23478
+ }
23479
+ function stored(row) {
23480
+ return {
23481
+ uniqueId: row.memory_id,
23482
+ content: row.content,
23483
+ scope: row.scope,
23484
+ folderId: row.folder_id ?? null,
23485
+ userId: null,
23486
+ kind: row.kind ?? null,
23487
+ kindValue: row.kind_value ?? null,
23488
+ ...isMemoryLevel(row.level) && { level: row.level },
23489
+ embedding: row.embedding ? JSON.stringify(row.embedding) : null,
23490
+ embeddingModel: row.embedding_model ?? null,
23491
+ sourceChunkIds: row.source_chunk_ids === void 0 ? null : sourceIds(row.source_chunk_ids),
23492
+ proofCount: row.proof_count ?? null,
23493
+ source: row.source ?? null,
23494
+ media: parseMedia(row.media),
23495
+ eventTimeStart: row.event_time_start ?? null,
23496
+ eventTimeEnd: row.event_time_end ?? null,
23497
+ eventTimeKind: row.event_time_kind ?? null,
23498
+ topicsUserManaged: row.topics_user_managed ?? false,
23499
+ topics: parseTopics(row.topics),
23500
+ topicsUpdatedAt: row.topics_updated_at ?? null,
23501
+ topicsExtractedAt: row.topics_extracted_at ?? null,
23502
+ topicsExtractedVersion: row.topics_extracted_version ?? null,
23503
+ supersededBy: row.superseded_by ?? null,
23504
+ supersededAt: row.superseded_at ?? null,
23505
+ lastObservedAt: row.last_observed_at ?? null,
23506
+ factType: row.fact_type ?? null,
23507
+ archivedAt: row.archived_at ?? null,
23508
+ trustTier: row.trust_tier ?? null,
23509
+ visibility: row.visibility === "public" ? "public" : "private",
23510
+ twinOptIn: row.twin_opt_in ?? false,
23511
+ publishedAt: row.published_at ?? null,
23512
+ geohash: row.geohash ?? null,
23513
+ createdAt: new Date(row.created_at),
23514
+ updatedAt: new Date(row.updated_at),
23515
+ isDeleted: row.is_deleted
23516
+ };
23517
+ }
23518
+ function createRemoteMemoryPipeline(options) {
23519
+ const { persistence, embeddingOptions } = options;
23520
+ const model = embeddingOptions.model ?? DEFAULT_API_EMBEDDING_MODEL;
23521
+ const operation = (mode) => {
23522
+ const rejectUndecryptable = (failed) => {
23523
+ if (!failed.length) return;
23524
+ if (mode === "retain")
23525
+ throw new Error(
23526
+ `Remote memories could not decrypt ${failed.length} candidate row(s); refusing to retain until they are repaired`
23527
+ );
23528
+ getLogger().warn(
23529
+ `[memory/remote] Skipping ${failed.length} undecryptable candidate row(s)`,
23530
+ failed.map((failure) => failure.memory_id)
23531
+ );
23532
+ };
23533
+ const snapshots = /* @__PURE__ */ new Map();
23534
+ const remember = (items) => {
23535
+ items.forEach((item) => snapshots.set(item.memory.memory_id, item));
23536
+ return items.map((item) => stored(item.memory));
23537
+ };
23538
+ const get = async (id) => {
23539
+ const snapshot = snapshots.get(id) ?? await persistence.get(id);
23540
+ if (!snapshot || snapshot.memory.is_deleted || snapshot.memory.superseded_by) return null;
23541
+ snapshots.set(id, snapshot);
23542
+ return stored(snapshot.memory);
23543
+ };
23544
+ const prepare = async (query, search = {}) => {
23545
+ if (search.folderId !== void 0)
23546
+ throw new Error("Remote memories do not support folder filters");
23547
+ const facets = normalizeSubQueries(search.subQueries);
23548
+ const facetQueries = facets.length >= 2 ? facets : [];
23549
+ const start = Date.now();
23550
+ const budgetMs = search.queryEmbedTotalTimeoutMs ?? 8e3;
23551
+ const embed = (texts) => generateEmbeddings(texts, {
23552
+ ...embeddingOptions,
23553
+ totalTimeoutMs: budgetMs
23554
+ });
23555
+ const embedFacets = async () => {
23556
+ if (!facetQueries.length) return [];
23557
+ try {
23558
+ const vectors2 = await embed(facetQueries);
23559
+ if (vectors2.length !== facetQueries.length)
23560
+ throw new Error("Incomplete facet embeddings");
23561
+ return vectors2.map(storedVector);
23562
+ } catch (error) {
23563
+ getLogger().warn(
23564
+ "[memory/remote] Facet embeddings unavailable; using primary query",
23565
+ error
23566
+ );
23567
+ return [];
23568
+ }
23569
+ };
23570
+ const [primary, facetEmbeddings] = await Promise.all([
23571
+ search.queryEmbedding ?? embed([query]).then((vectors2) => vectors2[0]),
23572
+ embedFacets()
23573
+ ]);
23574
+ const queryEmbedding = storedVector(primary);
23575
+ const queryEmbedMs = Date.now() - start;
23576
+ const graph = search.entityRanking ?? [];
23577
+ const temporal = search.temporalRanking ?? [];
23578
+ const forced = /* @__PURE__ */ new Set();
23579
+ for (let i = 0; i < Math.max(graph.length, temporal.length) && forced.size < 100; i++) {
23580
+ if (graph[i] !== void 0) forced.add(graph[i]);
23581
+ if (forced.size < 100 && temporal[i] !== void 0) forced.add(temporal[i]);
23582
+ }
23583
+ const forceIds = [...forced];
23584
+ const windowOptions = (i, signal) => ({
23585
+ limit: Math.min(100, Math.max((search.limit ?? 8) * 3, 30)),
23586
+ force_ids: i === 0 ? forceIds : [],
23587
+ ...search.scopes && { scopes: search.scopes },
23588
+ ...search.factTypes && { fact_types: search.factTypes },
23589
+ ...search.memoryIds !== void 0 && { memory_ids: search.memoryIds },
23590
+ include_archived: search.includeArchived,
23591
+ embedding_model: model,
23592
+ ...signal && { signal }
23593
+ });
23594
+ const vectors = [queryEmbedding, ...facetEmbeddings];
23595
+ let windows;
23596
+ if (mode === "retain") {
23597
+ windows = await Promise.all(
23598
+ vectors.map((embedding, i) => persistence.candidateSet(embedding, windowOptions(i)))
23599
+ );
23600
+ } else {
23601
+ const deadline = new AbortController();
23602
+ const timer = setTimeout(
23603
+ () => deadline.abort(
23604
+ new RemoteMemoryError("Remote recall exceeded its query budget", 408, "timeout")
23605
+ ),
23606
+ Math.max(0, start + budgetMs - Date.now())
23607
+ );
23608
+ try {
23609
+ windows = await Promise.all(
23610
+ vectors.map(
23611
+ (embedding, i) => persistence.candidates(embedding, windowOptions(i, deadline.signal))
23612
+ )
23613
+ );
23614
+ } finally {
23615
+ clearTimeout(timer);
23616
+ }
23617
+ }
23618
+ rejectUndecryptable([
23619
+ ...new Map(
23620
+ windows.flatMap((window2) => window2.failed).map((failure) => [failure.memory_id, failure])
23621
+ ).values()
23622
+ ]);
23623
+ const items = [
23624
+ ...new Map(
23625
+ windows.flatMap((window2) => window2.items).map((item) => [item.memory.memory_id, item])
23626
+ ).values()
23627
+ ];
23628
+ const memories = remember(items);
23629
+ return {
23630
+ memories,
23631
+ embeddedItems: memories.map((memory) => ({
23632
+ id: memory.uniqueId,
23633
+ content: memory.content,
23634
+ embedding: JSON.parse(memory.embedding ?? "[]"),
23635
+ createdAt: memory.createdAt,
23636
+ updatedAt: memory.updatedAt,
23637
+ proofCount: memory.proofCount,
23638
+ lastObservedAt: memory.lastObservedAt,
23639
+ eventTimeStart: memory.eventTimeStart,
23640
+ eventTimeEnd: memory.eventTimeEnd,
23641
+ eventTimeKind: memory.eventTimeKind === "point" || memory.eventTimeKind === "range" || memory.eventTimeKind === "ongoing" ? memory.eventTimeKind : null,
23642
+ factType: memory.factType,
23643
+ sourceChunkIds: memory.sourceChunkIds
23644
+ })),
23645
+ queryEmbedding,
23646
+ facetEmbeddings,
23647
+ vaultSize: Math.max(windows[0].total_count ?? 0, items.length),
23648
+ embeddingFailure: windows.some((window2) => (window2.unavailable_count ?? 0) > 0),
23649
+ embeddingsUnavailable: (windows[0].total_count ?? items.length) > 0 && !memories.some((memory) => memory.embedding),
23650
+ decryptLast: true,
23651
+ rowsDecrypted: items.length,
23652
+ queryEmbedMs,
23653
+ rowsEmbedded: 0
23654
+ };
23655
+ };
23656
+ const createRow = (input) => {
23657
+ if (input.folderId !== void 0 && input.folderId !== null)
23658
+ throw new Error("Remote memories do not support folders");
23659
+ const now = Date.now();
23660
+ return {
23661
+ memory_id: (0, import_uuid5.v7)(),
23662
+ content: input.content,
23663
+ scope: input.scope ?? "private",
23664
+ created_at: now,
23665
+ updated_at: now,
23666
+ is_deleted: false,
23667
+ ...input.embedding !== void 0 && {
23668
+ embedding: storedVector(JSON.parse(input.embedding)),
23669
+ embedding_model: input.embeddingModel
23670
+ },
23671
+ source_chunk_ids: JSON.stringify(input.sourceChunkIds ?? []),
23672
+ proof_count: input.proofCount ?? 1,
23673
+ source: input.source ?? "manual",
23674
+ ...input.eventTime && {
23675
+ event_time_start: input.eventTime.start ?? void 0,
23676
+ event_time_end: input.eventTime.end ?? void 0,
23677
+ event_time_kind: input.eventTime.kind ?? void 0
23678
+ },
23679
+ fact_type: input.factType,
23680
+ trust_tier: normalizeTrustTier(input.trustTier) ?? void 0,
23681
+ geohash: input.geohash,
23682
+ visibility: "private",
23683
+ twin_opt_in: false
23684
+ };
23685
+ };
23686
+ const write = async (memory, snapshot) => remember([await persistence.put(memory, snapshot)])[0];
23687
+ const port = {
23688
+ prepare,
23689
+ get,
23690
+ getFresh: async (id) => {
23691
+ const current = await persistence.get(id);
23692
+ return current && !current.memory.is_deleted && !current.memory.superseded_by ? stored(current.memory) : null;
23693
+ },
23694
+ tombstones: async (embedding, embeddingModel, scope, folderId) => {
23695
+ if (folderId !== void 0) throw new Error("Remote memories do not support folders");
23696
+ const window2 = await persistence.candidateSet(storedVector(embedding), {
23697
+ limit: 1,
23698
+ scopes: [scope],
23699
+ embedding_model: embeddingModel,
23700
+ strict_model: true,
23701
+ include_deleted: true,
23702
+ deleted_only: true
23703
+ });
23704
+ rejectUndecryptable(window2.failed);
23705
+ return remember(window2.items);
23706
+ },
23707
+ create: (input) => write(createRow(input), 0),
23708
+ update: async (id, patch) => {
23709
+ const existing = await get(id);
23710
+ if (!existing || patch.freeFormOnly && existing.kind !== null && existing.kind !== void 0)
23711
+ return null;
23712
+ const snapshot = snapshots.get(id);
23713
+ const memory = {
23714
+ ...snapshot.memory,
23715
+ content: patch.content,
23716
+ updated_at: patch.preserveUpdatedAt ? snapshot.memory.updated_at : Date.now()
23717
+ };
23718
+ if (patch.scope !== void 0) memory.scope = patch.scope;
23719
+ if (patch.embedding === void 0 && patch.content !== snapshot.memory.content) {
23720
+ delete memory.embedding;
23721
+ delete memory.embedding_model;
23722
+ }
23723
+ if (patch.embedding !== void 0) {
23724
+ memory.embedding = patch.embedding === null ? [] : storedVector(JSON.parse(patch.embedding));
23725
+ memory.embedding_model = patch.embeddingModel ?? void 0;
23726
+ }
23727
+ const observed = sourceIds(memory.source_chunk_ids);
23728
+ const replay = !!patch.observationSourceIds?.length && patch.observationSourceIds.every((id2) => observed.includes(id2));
23729
+ if (patch.sourceChunkIds !== void 0)
23730
+ memory.source_chunk_ids = JSON.stringify(
23731
+ patch.observationSourceIds?.length ? [.../* @__PURE__ */ new Set([...observed, ...patch.sourceChunkIds])] : patch.sourceChunkIds
23732
+ );
23733
+ if (!replay) {
23734
+ if (patch.proofCountIncrement !== void 0)
23735
+ memory.proof_count = (memory.proof_count ?? 1) + patch.proofCountIncrement;
23736
+ else if (patch.proofCount !== void 0) memory.proof_count = patch.proofCount;
23737
+ if (patch.lastObservedAt !== void 0) memory.last_observed_at = patch.lastObservedAt;
23738
+ }
23739
+ if (patch.source !== void 0) memory.source = patch.source;
23740
+ if (patch.factType !== void 0) memory.fact_type = patch.factType;
23741
+ if (patch.trustTier !== void 0)
23742
+ memory.trust_tier = normalizeTrustTier(patch.trustTier) ?? void 0;
23743
+ if (patch.topicsUserManaged !== void 0)
23744
+ memory.topics_user_managed = patch.topicsUserManaged;
23745
+ if (patch.eventTime !== void 0) {
23746
+ memory.event_time_start = patch.eventTime.start ?? void 0;
23747
+ memory.event_time_end = patch.eventTime.end ?? void 0;
23748
+ memory.event_time_kind = patch.eventTime.kind ?? void 0;
23749
+ }
23750
+ if (patch.restore) memory.archived_at = void 0;
23751
+ return write(memory, snapshot);
23752
+ },
23753
+ supersede: async (id, successor) => {
23754
+ const [target, newer] = await Promise.all([get(id), get(successor)]);
23755
+ if (!target || !newer || id === successor) return false;
23756
+ const old = snapshots.get(id);
23757
+ const next = snapshots.get(successor);
23758
+ remember(
23759
+ await persistence.putMany([
23760
+ {
23761
+ memory: { ...old.memory, superseded_by: successor, superseded_at: Date.now() },
23762
+ expectedVersion: old
23763
+ },
23764
+ { memory: next.memory, expectedVersion: next }
23765
+ ])
23766
+ );
23767
+ return true;
23768
+ },
23769
+ createSuperseding: async (input, targetId) => {
23770
+ const target = await get(targetId);
23771
+ if (!target) return { created: null, retired: false };
23772
+ const snapshot = snapshots.get(targetId);
23773
+ const successor = createRow(input);
23774
+ const rows = remember(
23775
+ await persistence.putMany([
23776
+ { memory: successor, expectedVersion: 0 },
23777
+ {
23778
+ memory: {
23779
+ ...snapshot.memory,
23780
+ superseded_by: successor.memory_id,
23781
+ superseded_at: Date.now()
23782
+ },
23783
+ expectedVersion: snapshot
23784
+ }
23785
+ ])
23786
+ );
23787
+ return { created: rows[0], retired: true };
23788
+ }
23789
+ };
23790
+ return { prepare, port };
23791
+ };
23792
+ return {
23793
+ recall: async (query, recallOptions = {}) => {
23794
+ const { prepare } = operation("recall");
23795
+ return recall(
23796
+ query,
23797
+ {
23798
+ embeddingOptions,
23799
+ factSource: {
23800
+ graphRanking: options.graphRanking,
23801
+ temporalRanking: options.temporalRanking,
23802
+ search: async (text12, searchOptions) => {
23803
+ const prepared = await prepare(text12, searchOptions);
23804
+ const ranked = await rankPreparedVaultCandidates(
23805
+ text12,
23806
+ prepared,
23807
+ embeddingOptions,
23808
+ searchOptions
23809
+ );
23810
+ return {
23811
+ ...ranked,
23812
+ rankedOnCosine: prepared.memories.length > 0 && !prepared.embeddingsUnavailable,
23813
+ decryptLast: true,
23814
+ rowsDecrypted: prepared.rowsDecrypted,
23815
+ queryEmbedMs: prepared.queryEmbedMs,
23816
+ rowsEmbedded: 0
23817
+ };
23818
+ }
23819
+ }
23820
+ },
23821
+ { ...recallOptions, types: ["fact"] }
23822
+ );
23823
+ },
23824
+ retain: async (content, retainOptions) => {
23825
+ const { port } = operation("retain");
23826
+ return retainWithPersistence(
23827
+ content,
23828
+ {
23829
+ persistence: port,
23830
+ embeddingOptions,
23831
+ vaultCache: /* @__PURE__ */ new Map(),
23832
+ normalizeEmbedding: storedVector
23833
+ },
23834
+ retainOptions
23835
+ );
23836
+ }
23837
+ };
23838
+ }
23839
+
22842
23840
  // src/lib/memory/synthesizeProfile.ts
22843
23841
  init_internalFlowMarker();
22844
23842
  init_logger();
@@ -29098,7 +30096,7 @@ async function uploadFileToICloud(filename, content) {
29098
30096
  const recordName = `backup_${filename.replace(/[^a-zA-Z0-9]/g, "_")}`;
29099
30097
  const arrayBuffer = await content.arrayBuffer();
29100
30098
  const base64Data = uint8ArrayToBase64(new Uint8Array(arrayBuffer));
29101
- const record = {
30099
+ const record2 = {
29102
30100
  recordType: RECORD_TYPE,
29103
30101
  recordName,
29104
30102
  fields: {
@@ -29108,7 +30106,7 @@ async function uploadFileToICloud(filename, content) {
29108
30106
  contentType: { value: content.type || "application/json" }
29109
30107
  }
29110
30108
  };
29111
- const response = await database.saveRecords(record);
30109
+ const response = await database.saveRecords(record2);
29112
30110
  if (!response.records || response.records.length === 0) {
29113
30111
  throw new Error("Failed to upload file to iCloud");
29114
30112
  }
@@ -29134,11 +30132,11 @@ async function listICloudFiles() {
29134
30132
  while (response.continuationMarker) {
29135
30133
  break;
29136
30134
  }
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
30135
+ const files = allRecords.map((record2) => ({
30136
+ recordName: record2.recordName,
30137
+ filename: record2.fields.filename?.value ?? "",
30138
+ modifiedAt: new Date(record2.modified?.timestamp ?? Date.now()),
30139
+ size: typeof record2.fields.data?.value === "object" && record2.fields.data?.value !== null ? record2.fields.data.value.size : 0
29142
30140
  }));
29143
30141
  return files.sort((a, b) => b.modifiedAt.getTime() - a.modifiedAt.getTime());
29144
30142
  }
@@ -29151,8 +30149,8 @@ async function downloadICloudFile(recordName) {
29151
30149
  if (!response.records || response.records.length === 0) {
29152
30150
  throw new Error(`File not found: ${recordName}`);
29153
30151
  }
29154
- const record = response.records[0];
29155
- const dataField = record.fields.data?.value;
30152
+ const record2 = response.records[0];
30153
+ const dataField = record2.fields.data?.value;
29156
30154
  if (!dataField) {
29157
30155
  throw new Error("No data in record");
29158
30156
  }
@@ -29186,12 +30184,12 @@ async function findICloudFile(filename) {
29186
30184
  if (!response.records || response.records.length === 0) {
29187
30185
  return null;
29188
30186
  }
29189
- const record = response.records[0];
30187
+ const record2 = response.records[0];
29190
30188
  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
30189
+ recordName: record2.recordName,
30190
+ filename: record2.fields.filename?.value ?? "",
30191
+ modifiedAt: new Date(record2.modified?.timestamp ?? Date.now()),
30192
+ size: typeof record2.fields.data?.value === "object" && record2.fields.data?.value !== null ? record2.fields.data.value.size : 0
29195
30193
  };
29196
30194
  }
29197
30195
 
@@ -29346,8 +30344,8 @@ async function getStoredTokenData5(provider, walletAddress) {
29346
30344
  return null;
29347
30345
  }
29348
30346
  }
29349
- async function readTokenRow(stored, provider, walletAddress) {
29350
- if (stored.startsWith(ENCRYPTED_PREFIX6)) {
30347
+ async function readTokenRow(stored2, provider, walletAddress) {
30348
+ if (stored2.startsWith(ENCRYPTED_PREFIX6)) {
29351
30349
  if (!walletAddress) {
29352
30350
  getLogger().warn(
29353
30351
  `Encrypted OAuth token found for ${provider} but no wallet address provided`
@@ -29355,7 +30353,7 @@ async function readTokenRow(stored, provider, walletAddress) {
29355
30353
  return null;
29356
30354
  }
29357
30355
  try {
29358
- const encryptedData = stored.slice(ENCRYPTED_PREFIX6.length);
30356
+ const encryptedData = stored2.slice(ENCRYPTED_PREFIX6.length);
29359
30357
  let decryptedJson;
29360
30358
  try {
29361
30359
  decryptedJson = await decryptData(encryptedData, walletAddress);
@@ -29370,7 +30368,7 @@ async function readTokenRow(stored, provider, walletAddress) {
29370
30368
  return null;
29371
30369
  }
29372
30370
  }
29373
- return parsePlaintextToken(stored, walletAddress);
30371
+ return parsePlaintextToken(stored2, walletAddress);
29374
30372
  }
29375
30373
  async function storeTokenData5(provider, data, walletAddress) {
29376
30374
  if (typeof window === "undefined") return;
@@ -29446,8 +30444,8 @@ async function migrateUnencryptedTokens(provider, walletAddress) {
29446
30444
  const keys = [scopedKey, legacyKey];
29447
30445
  const isEncrypted2 = (value) => !!value && value.startsWith(ENCRYPTED_PREFIX6);
29448
30446
  const plaintextAt = (key) => {
29449
- const stored = sessionStorage.getItem(key) ?? localStorage.getItem(key);
29450
- return stored && !isEncrypted2(stored) ? stored : null;
30447
+ const stored2 = sessionStorage.getItem(key) ?? localStorage.getItem(key);
30448
+ return stored2 && !isEncrypted2(stored2) ? stored2 : null;
29451
30449
  };
29452
30450
  let tokenToMigrate = null;
29453
30451
  for (const key of keys) {
@@ -29459,8 +30457,8 @@ async function migrateUnencryptedTokens(provider, walletAddress) {
29459
30457
  }
29460
30458
  if (!tokenToMigrate) {
29461
30459
  for (const key of keys) {
29462
- const stored = sessionStorage.getItem(key);
29463
- if (isEncrypted2(localStorage.getItem(key)) && stored && !isEncrypted2(stored)) {
30460
+ const stored2 = sessionStorage.getItem(key);
30461
+ if (isEncrypted2(localStorage.getItem(key)) && stored2 && !isEncrypted2(stored2)) {
29464
30462
  sessionStorage.removeItem(key);
29465
30463
  }
29466
30464
  }
@@ -29516,17 +30514,17 @@ function storeOAuthState2(state) {
29516
30514
  }
29517
30515
  function getAndClearOAuthState4() {
29518
30516
  if (typeof window === "undefined") return null;
29519
- const stored = sessionStorage.getItem(STATE_STORAGE_KEY);
30517
+ const stored2 = sessionStorage.getItem(STATE_STORAGE_KEY);
29520
30518
  sessionStorage.removeItem(STATE_STORAGE_KEY);
29521
- if (!stored) return null;
30519
+ if (!stored2) return null;
29522
30520
  try {
29523
- const parsed = JSON.parse(stored);
30521
+ const parsed = JSON.parse(stored2);
29524
30522
  if (parsed && typeof parsed === "object" && "state" in parsed) {
29525
30523
  return parsed.state;
29526
30524
  }
29527
30525
  } catch {
29528
30526
  }
29529
- return stored;
30527
+ return stored2;
29530
30528
  }
29531
30529
  function isDropboxCallback() {
29532
30530
  if (typeof window === "undefined") return false;
@@ -29710,17 +30708,17 @@ function storeOAuthState3(state) {
29710
30708
  }
29711
30709
  function getAndClearOAuthState5() {
29712
30710
  if (typeof window === "undefined") return null;
29713
- const stored = sessionStorage.getItem(CODE_STORAGE_KEY4);
30711
+ const stored2 = sessionStorage.getItem(CODE_STORAGE_KEY4);
29714
30712
  sessionStorage.removeItem(CODE_STORAGE_KEY4);
29715
- if (!stored) return null;
30713
+ if (!stored2) return null;
29716
30714
  try {
29717
- const parsed = JSON.parse(stored);
30715
+ const parsed = JSON.parse(stored2);
29718
30716
  if (parsed && typeof parsed === "object" && "state" in parsed) {
29719
30717
  return parsed.state;
29720
30718
  }
29721
30719
  } catch {
29722
30720
  }
29723
- return stored;
30721
+ return stored2;
29724
30722
  }
29725
30723
  function isGoogleDriveCallback() {
29726
30724
  if (typeof window === "undefined") return false;
@@ -31664,18 +32662,18 @@ async function blobToDataUri(blob) {
31664
32662
  reader.readAsDataURL(blob);
31665
32663
  });
31666
32664
  }
31667
- async function storedToLlmapiMessage(stored, encryptionKey, resolveMediaByIds) {
31668
- let textContent = stored.content;
32665
+ async function storedToLlmapiMessage(stored2, encryptionKey, resolveMediaByIds) {
32666
+ let textContent = stored2.content;
31669
32667
  const fileUrlMap = /* @__PURE__ */ new Map();
31670
32668
  const imageParts = [];
31671
- if (stored.role !== "assistant" && stored.files?.length) {
31672
- for (const file of stored.files) {
32669
+ if (stored2.role !== "assistant" && stored2.files?.length) {
32670
+ for (const file of stored2.files) {
31673
32671
  if (isSendableImageURL(file.url)) {
31674
32672
  imageParts.push({
31675
32673
  type: "image_url",
31676
32674
  image_url: { url: file.url }
31677
32675
  });
31678
- } else if (file.sourceUrl && !isR2UrlExpired(file.sourceUrl, stored.createdAt)) {
32676
+ } else if (file.sourceUrl && !isR2UrlExpired(file.sourceUrl, stored2.createdAt)) {
31679
32677
  imageParts.push({
31680
32678
  type: "image_url",
31681
32679
  image_url: { url: file.sourceUrl }
@@ -31695,11 +32693,11 @@ async function storedToLlmapiMessage(stored, encryptionKey, resolveMediaByIds) {
31695
32693
  }
31696
32694
  }
31697
32695
  }
31698
- } else if (stored.role === "assistant" && stored.files?.length) {
32696
+ } else if (stored2.role === "assistant" && stored2.files?.length) {
31699
32697
  const expiredFileIds = [];
31700
- for (const file of stored.files) {
32698
+ for (const file of stored2.files) {
31701
32699
  if (file.sourceUrl) {
31702
- if (!isR2UrlExpired(file.sourceUrl, stored.createdAt)) {
32700
+ if (!isR2UrlExpired(file.sourceUrl, stored2.createdAt)) {
31703
32701
  fileUrlMap.set(file.id, file.sourceUrl);
31704
32702
  } else {
31705
32703
  expiredFileIds.push(file.id);
@@ -31712,11 +32710,11 @@ async function storedToLlmapiMessage(stored, encryptionKey, resolveMediaByIds) {
31712
32710
  [${expiredFileIds.length} expired image URL${expiredFileIds.length > 1 ? "s" : ""} omitted \u2014 the user can still see ${expiredFileIds.length > 1 ? "them" : "it"} locally]`;
31713
32711
  }
31714
32712
  }
31715
- if (stored.fileIds?.length && resolveMediaByIds) {
32713
+ if (stored2.fileIds?.length && resolveMediaByIds) {
31716
32714
  try {
31717
- const mediaItems = await resolveMediaByIds(stored.fileIds);
32715
+ const mediaItems = await resolveMediaByIds(stored2.fileIds);
31718
32716
  for (const media of mediaItems) {
31719
- if (media.sourceUrl && !isR2UrlExpired(media.sourceUrl, stored.createdAt)) {
32717
+ if (media.sourceUrl && !isR2UrlExpired(media.sourceUrl, stored2.createdAt)) {
31720
32718
  fileUrlMap.set(media.mediaId, media.sourceUrl);
31721
32719
  }
31722
32720
  }
@@ -31740,7 +32738,7 @@ async function storedToLlmapiMessage(stored, encryptionKey, resolveMediaByIds) {
31740
32738
  return "";
31741
32739
  }
31742
32740
  );
31743
- if (stored.role === "assistant" && fileUrlMap.size > 0) {
32741
+ if (stored2.role === "assistant" && fileUrlMap.size > 0) {
31744
32742
  const unreferencedImages = [...fileUrlMap.entries()].filter(
31745
32743
  ([, url]) => !textContent.includes(url)
31746
32744
  );
@@ -31752,11 +32750,11 @@ async function storedToLlmapiMessage(stored, encryptionKey, resolveMediaByIds) {
31752
32750
  textContent = textContent.replace(/\n{3,}/g, "\n\n").trim();
31753
32751
  const content = [{ type: "text", text: textContent }, ...imageParts];
31754
32752
  const messages = [];
31755
- if (stored.role === "assistant" && stored.toolCallEvents?.length) {
32753
+ if (stored2.role === "assistant" && stored2.toolCallEvents?.length) {
31756
32754
  messages.push({
31757
- role: stored.role,
32755
+ role: stored2.role,
31758
32756
  content: void 0,
31759
- tool_calls: stored.toolCallEvents.map((event) => ({
32757
+ tool_calls: stored2.toolCallEvents.map((event) => ({
31760
32758
  id: event.id,
31761
32759
  type: "function",
31762
32760
  function: {
@@ -31765,7 +32763,7 @@ async function storedToLlmapiMessage(stored, encryptionKey, resolveMediaByIds) {
31765
32763
  }
31766
32764
  }))
31767
32765
  });
31768
- for (const event of stored.toolCallEvents) {
32766
+ for (const event of stored2.toolCallEvents) {
31769
32767
  if (event.id && event.output !== void 0 && event.output !== null) {
31770
32768
  messages.push({
31771
32769
  role: "tool",
@@ -31776,12 +32774,12 @@ async function storedToLlmapiMessage(stored, encryptionKey, resolveMediaByIds) {
31776
32774
  }
31777
32775
  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
32776
  messages.push({
31779
- role: stored.role,
32777
+ role: stored2.role,
31780
32778
  content: [{ type: "text", text: postToolText }]
31781
32779
  });
31782
32780
  } else {
31783
32781
  messages.push({
31784
- role: stored.role,
32782
+ role: stored2.role,
31785
32783
  content
31786
32784
  });
31787
32785
  }
@@ -35600,19 +36598,19 @@ function startObserve(entry, walletAddress) {
35600
36598
  "updated_at"
35601
36599
  ]).subscribe({
35602
36600
  next: (records) => {
35603
- const record = records[0];
35604
- if (!record) return;
36601
+ const record2 = records[0];
36602
+ if (!record2) return;
35605
36603
  const patch = {
35606
36604
  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
36605
+ uniqueId: record2.id,
36606
+ walletAddress: record2.walletAddress,
36607
+ nickname: record2.nickname,
36608
+ occupation: record2.occupation,
36609
+ description: record2.description,
36610
+ models: record2.models,
36611
+ personality: record2.personality,
36612
+ createdAt: record2.createdAt,
36613
+ updatedAt: record2.updatedAt
35616
36614
  }
35617
36615
  };
35618
36616
  if (isInitialEmission) {
@@ -36818,7 +37816,10 @@ function useWalletBinding(options = {}) {
36818
37816
  LoggerProvider,
36819
37817
  MAX_HOPS,
36820
37818
  MEDIUM_TTL_MS,
37819
+ MEMORY_KINDS,
37820
+ MEMORY_LEVELS,
36821
37821
  MemoryEntityModel,
37822
+ MemoryLevelError,
36822
37823
  NEVER_TTL_MS,
36823
37824
  NODE_BUDGET,
36824
37825
  PAST_EVENT_GRACE_MS,
@@ -36831,6 +37832,7 @@ function useWalletBinding(options = {}) {
36831
37832
  R2_DEFAULT_TTL_MS,
36832
37833
  RECALL_MAX_LIMIT,
36833
37834
  RECALL_TOOL_NAME,
37835
+ RemoteMemoryError,
36834
37836
  RerankerUnavailableError,
36835
37837
  SDK_SCHEMA_VERSION,
36836
37838
  SERVER_TOOL_DEPENDENCY_SETS,
@@ -36922,6 +37924,8 @@ function useWalletBinding(options = {}) {
36922
37924
  createPlatformCursorStore,
36923
37925
  createProjectOp,
36924
37926
  createRecallTool,
37927
+ createRemoteMemoryPersistence,
37928
+ createRemoteMemoryPipeline,
36925
37929
  createSavedToolOp,
36926
37930
  createServerToolsFilter,
36927
37931
  createStockPricePreProcessor,