@anuma/sdk 10.9.0 → 11.0.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.
@@ -544,9 +544,9 @@ async function refreshEncryptionKeyIfMatches(walletAddress, probeCiphertext, sig
544
544
  return false;
545
545
  }
546
546
  const startEpoch = sessionEpoch;
547
- const cached = refreshCandidatesByAddress.get(walletAddress);
548
- if (cached) {
549
- return tryCommitCandidatesIfProbeMatches(walletAddress, parsed, cached, startEpoch);
547
+ const cached2 = refreshCandidatesByAddress.get(walletAddress);
548
+ if (cached2) {
549
+ return tryCommitCandidatesIfProbeMatches(walletAddress, parsed, cached2, startEpoch);
550
550
  }
551
551
  let derivePromise = pendingCandidateDerives.get(walletAddress);
552
552
  if (!derivePromise) {
@@ -895,10 +895,10 @@ function parsePlaintextToken(raw, walletAddress) {
895
895
  return null;
896
896
  }
897
897
  if (!parsed || typeof parsed !== "object") return null;
898
- const record2 = parsed;
899
- const data = record2.token?.accessToken ? record2.token : record2;
898
+ const record3 = parsed;
899
+ const data = record3.token?.accessToken ? record3.token : record3;
900
900
  if (!data?.accessToken) return null;
901
- if (record2.wallet && record2.wallet !== walletAddress) return null;
901
+ if (record3.wallet && record3.wallet !== walletAddress) return null;
902
902
  return data;
903
903
  }
904
904
  function promoteUnscopedRow(raw, data, store, scopedKey, unscopedKey, walletAddress) {
@@ -990,10 +990,10 @@ async function discoverOAuthMetadata() {
990
990
  }
991
991
  async function getOAuthMetadata() {
992
992
  if (typeof window !== "undefined") {
993
- const cached = sessionStorage.getItem(OAUTH_METADATA_KEY);
994
- if (cached) {
993
+ const cached2 = sessionStorage.getItem(OAUTH_METADATA_KEY);
994
+ if (cached2) {
995
995
  try {
996
- return JSON.parse(cached);
996
+ return JSON.parse(cached2);
997
997
  } catch {
998
998
  }
999
999
  }
@@ -1097,8 +1097,8 @@ async function storeTokenData(data, walletAddress) {
1097
1097
  } catch {
1098
1098
  }
1099
1099
  }
1100
- const record2 = { wallet: walletAddress, token: data };
1101
- sessionStorage.setItem(getTokenStorageKey(walletAddress), JSON.stringify(record2));
1100
+ const record3 = { wallet: walletAddress, token: data };
1101
+ sessionStorage.setItem(getTokenStorageKey(walletAddress), JSON.stringify(record3));
1102
1102
  }
1103
1103
  async function getStoredTokenData(walletAddress) {
1104
1104
  if (typeof window === "undefined") return null;
@@ -1502,25 +1502,25 @@ var TRUNCATION_MARKER_HEAD = "... (tool output truncated, ";
1502
1502
  var TRUNCATION_MARKER_TAIL = " characters omitted)";
1503
1503
  var MAX_PERSISTED_TOOL_RESULT_CHARS = 1e5;
1504
1504
  function buildToolResultContent(results) {
1505
- const entries = results.map(
1505
+ const entries2 = results.map(
1506
1506
  (r) => `Tool "${r.name}" returned: ${JSON.stringify(r.result)}`.replace(/\u2028/g, "\\u2028").replace(/\u2029/g, "\\u2029")
1507
1507
  );
1508
- const framing = HEADER.length + FOOTER.length + ENTRY_SEPARATOR.length * Math.max(0, entries.length - 1);
1509
- const summary = capEntries(entries, MAX_PERSISTED_TOOL_RESULT_CHARS - framing).join(
1508
+ const framing = HEADER.length + FOOTER.length + ENTRY_SEPARATOR.length * Math.max(0, entries2.length - 1);
1509
+ const summary = capEntries(entries2, MAX_PERSISTED_TOOL_RESULT_CHARS - framing).join(
1510
1510
  ENTRY_SEPARATOR
1511
1511
  );
1512
1512
  return `${HEADER}${summary}${FOOTER}`;
1513
1513
  }
1514
- function capToolResultEntries(entries, budget) {
1515
- return capEntries(entries, budget);
1514
+ function capToolResultEntries(entries2, budget) {
1515
+ return capEntries(entries2, budget);
1516
1516
  }
1517
- function capEntries(entries, budget) {
1518
- const smallestFirst = entries.map((_, index) => index).sort((a, b) => entries[a].length - entries[b].length);
1519
- const capped = [...entries];
1517
+ function capEntries(entries2, budget) {
1518
+ const smallestFirst = entries2.map((_, index) => index).sort((a, b) => entries2[a].length - entries2[b].length);
1519
+ const capped = [...entries2];
1520
1520
  let remaining = budget;
1521
- let unassigned = entries.length;
1521
+ let unassigned = entries2.length;
1522
1522
  for (const index of smallestFirst) {
1523
- capped[index] = truncateEntry(entries[index], Math.floor(remaining / unassigned));
1523
+ capped[index] = truncateEntry(entries2[index], Math.floor(remaining / unassigned));
1524
1524
  remaining -= capped[index].length;
1525
1525
  unassigned--;
1526
1526
  }
@@ -2408,11 +2408,11 @@ var ToolCallEventIndex = class {
2408
2408
  this.pending = /* @__PURE__ */ new Map();
2409
2409
  this.resetCount = collection.database._resetCount;
2410
2410
  collection.experimentalSubscribe((changes) => {
2411
- for (const { record: record2, type } of changes) {
2411
+ for (const { record: record3, type } of changes) {
2412
2412
  this.replace(
2413
- record2.id,
2414
- type === "destroyed" ? void 0 : record2.conversationId,
2415
- type === "destroyed" ? void 0 : record2._getRaw("tool_call_events")
2413
+ record3.id,
2414
+ type === "destroyed" ? void 0 : record3.conversationId,
2415
+ type === "destroyed" ? void 0 : record3._getRaw("tool_call_events")
2416
2416
  );
2417
2417
  }
2418
2418
  });
@@ -3538,7 +3538,7 @@ async function updateMessageErrorOp(ctx, uniqueId, error) {
3538
3538
  }
3539
3539
  await ctx.database.write(async () => {
3540
3540
  await message.update((msg) => {
3541
- msg._setRaw("error", error);
3541
+ msg._setRaw("error", error ?? "");
3542
3542
  });
3543
3543
  });
3544
3544
  return messageToStored(message, ctx.walletAddress, ctx.signMessage, ctx.embeddedWalletSigner);
@@ -3855,15 +3855,15 @@ async function searchChunksOp(ctx, queryVector, options) {
3855
3855
  staleSkipped++;
3856
3856
  continue;
3857
3857
  }
3858
- const cached = chunkCache?.get(key3.id);
3859
- if (!cached || cached.version !== key3.version) {
3858
+ const cached2 = chunkCache?.get(key3.id);
3859
+ if (!cached2 || cached2.version !== key3.version) {
3860
3860
  missIds.push(key3.id);
3861
3861
  continue;
3862
3862
  }
3863
3863
  cacheHits++;
3864
- if (cached.chunks.length > 0) {
3865
- for (let ci = 0; ci < cached.chunks.length; ci++) {
3866
- const vec = cached.chunks[ci];
3864
+ if (cached2.chunks.length > 0) {
3865
+ for (let ci = 0; ci < cached2.chunks.length; ci++) {
3866
+ const vec = cached2.chunks[ci];
3867
3867
  if (vec.length === 0) continue;
3868
3868
  const similarity = cosineSimilarity(queryVector, vec);
3869
3869
  if (similarity >= minSimilarity) {
@@ -3876,8 +3876,8 @@ async function searchChunksOp(ctx, queryVector, options) {
3876
3876
  });
3877
3877
  }
3878
3878
  }
3879
- } else if (cached.fallback) {
3880
- const similarity = cosineSimilarity(queryVector, cached.fallback);
3879
+ } else if (cached2.fallback) {
3880
+ const similarity = cosineSimilarity(queryVector, cached2.fallback);
3881
3881
  if (similarity >= minSimilarity) {
3882
3882
  candidates.push({
3883
3883
  id: key3.id,
@@ -4690,11 +4690,11 @@ var mergeConfigs = (a, b) => {
4690
4690
  return config;
4691
4691
  };
4692
4692
  var headersEntries = (headers) => {
4693
- const entries = [];
4693
+ const entries2 = [];
4694
4694
  headers.forEach((value, key3) => {
4695
- entries.push([key3, value]);
4695
+ entries2.push([key3, value]);
4696
4696
  });
4697
- return entries;
4697
+ return entries2;
4698
4698
  };
4699
4699
  var mergeHeaders = (...headers) => {
4700
4700
  const mergedHeaders = new Headers();
@@ -5169,9 +5169,9 @@ async function embedOne(text16, options, outer) {
5169
5169
  const { cache } = options;
5170
5170
  if (!cache) return Array.from(await requestEmbedding(text16, options, outer));
5171
5171
  const model = options.model ?? DEFAULT_API_EMBEDDING_MODEL;
5172
- const cached = cache.get(text16);
5173
- const cachedModel = cached && cachedEmbeddingModels.get(cached);
5174
- if (cached && (cachedModel === void 0 || cachedModel === model)) return Array.from(cached);
5172
+ const cached2 = cache.get(text16);
5173
+ const cachedModel = cached2 && cachedEmbeddingModels.get(cached2);
5174
+ if (cached2 && (cachedModel === void 0 || cachedModel === model)) return Array.from(cached2);
5175
5175
  const inFlight = inFlightByCache.get(cache) ?? /* @__PURE__ */ new Map();
5176
5176
  inFlightByCache.set(cache, inFlight);
5177
5177
  const requestKey = JSON.stringify([model, text16]);
@@ -5286,10 +5286,10 @@ async function embedMany(texts, options, outer) {
5286
5286
  const uncachedTexts = [];
5287
5287
  for (let i = 0; i < texts.length; i++) {
5288
5288
  if (cache) {
5289
- const cached = cache.get(texts[i]);
5290
- const cachedModel = cached && cachedEmbeddingModels.get(cached);
5291
- if (cached && (cachedModel === void 0 || cachedModel === embeddingModel)) {
5292
- results[i] = Array.from(cached);
5289
+ const cached2 = cache.get(texts[i]);
5290
+ const cachedModel = cached2 && cachedEmbeddingModels.get(cached2);
5291
+ if (cached2 && (cachedModel === void 0 || cachedModel === embeddingModel)) {
5292
+ results[i] = Array.from(cached2);
5293
5293
  continue;
5294
5294
  }
5295
5295
  }
@@ -5730,58 +5730,337 @@ function parseTopics(value) {
5730
5730
  return out;
5731
5731
  }
5732
5732
 
5733
+ // src/lib/memory/store/topicCodec.ts
5734
+ var ciphertextPattern = /^enc:v\d+:[0-9a-f]+$/i;
5735
+ var topicHashPattern = /^[0-9a-f]{64}$/;
5736
+ var MAX_SEALED_TOPIC_NAME_BYTES = 1024;
5737
+ function normalizeTopicName(name) {
5738
+ return normalizeEntityName(name).normalize("NFC");
5739
+ }
5740
+ function sealedTopicNamesFit(json5) {
5741
+ return (entries(json5) ?? []).every(
5742
+ (entry) => !hashed(entry) || typeof entry.name !== "string" || entry.name.length <= MAX_SEALED_TOPIC_NAME_BYTES
5743
+ );
5744
+ }
5745
+ function record(value) {
5746
+ return typeof value === "object" && value !== null && !Array.isArray(value);
5747
+ }
5748
+ function hashed(entry) {
5749
+ return record(entry) && typeof entry.name_hash === "string";
5750
+ }
5751
+ function entries(json5) {
5752
+ if (typeof json5 !== "string") return void 0;
5753
+ try {
5754
+ const parsed = JSON.parse(json5);
5755
+ return Array.isArray(parsed) ? parsed : void 0;
5756
+ } catch {
5757
+ return void 0;
5758
+ }
5759
+ }
5760
+ function cached(cache, key3, load) {
5761
+ let pending = cache.get(key3);
5762
+ if (!pending) {
5763
+ const loading = load();
5764
+ pending = loading;
5765
+ cache.set(key3, loading);
5766
+ loading.catch(() => {
5767
+ if (cache.get(key3) === loading) cache.delete(key3);
5768
+ });
5769
+ }
5770
+ return pending;
5771
+ }
5772
+ function createTopicCodec(cipher) {
5773
+ const hashes = /* @__PURE__ */ new Map();
5774
+ const opened = /* @__PURE__ */ new Map();
5775
+ const seals = /* @__PURE__ */ new Map();
5776
+ const legacyNames = /* @__PURE__ */ new Map();
5777
+ const hash = async (name) => {
5778
+ const normalized2 = normalizeTopicName(name);
5779
+ if (!normalized2) return null;
5780
+ return cached(hashes, normalized2, async () => {
5781
+ const digest = await cipher.hashTopic(normalized2);
5782
+ if (!topicHashPattern.test(digest))
5783
+ throw new Error("Topic hashing must return 64 lowercase hex characters");
5784
+ return digest;
5785
+ });
5786
+ };
5787
+ const seal = async (display) => {
5788
+ const nameHash = await hash(display);
5789
+ if (nameHash === null) return null;
5790
+ return cached(seals, display, async () => {
5791
+ const name = await cipher.encrypt(display);
5792
+ if (name === display || !ciphertextPattern.test(name))
5793
+ throw new Error(
5794
+ "Topic encryption must return SDK ciphertext; refusing to upload plaintext"
5795
+ );
5796
+ opened.set(name, Promise.resolve(display));
5797
+ return { name_hash: nameHash, name };
5798
+ });
5799
+ };
5800
+ const plain2 = (name) => {
5801
+ if (!ciphertextPattern.test(name)) return Promise.resolve(name);
5802
+ let pending = legacyNames.get(name);
5803
+ if (!pending) {
5804
+ pending = cipher.decrypt(name).catch(() => name);
5805
+ legacyNames.set(name, pending);
5806
+ }
5807
+ return pending;
5808
+ };
5809
+ const open = async ({ name, name_hash: nameHash }) => {
5810
+ if (nameHash === void 0) return plain2(name);
5811
+ if (typeof name !== "string" || typeof nameHash !== "string" || !topicHashPattern.test(nameHash) || !ciphertextPattern.test(name))
5812
+ throw new Error("Nearby returned a malformed topic name");
5813
+ const plaintext = await cached(opened, name, async () => {
5814
+ const value = await cipher.decrypt(name);
5815
+ if (value === name) throw new Error("Topic decryption failed");
5816
+ return value;
5817
+ });
5818
+ if (await hash(plaintext) !== nameHash) throw new Error("Topic name does not match its hash");
5819
+ if (!seals.has(plaintext)) seals.set(plaintext, Promise.resolve({ name_hash: nameHash, name }));
5820
+ return plaintext;
5821
+ };
5822
+ return {
5823
+ hash,
5824
+ seal,
5825
+ open,
5826
+ encodeTopics: async (json5) => {
5827
+ const list = entries(json5);
5828
+ if (!list) return json5;
5829
+ const sealed2 = await Promise.all(
5830
+ list.map(async (entry) => {
5831
+ if (!record(entry) || typeof entry.name !== "string") return null;
5832
+ const name = await seal(await plain2(entry.name));
5833
+ return name && { ...entry, name: name.name, name_hash: name.name_hash };
5834
+ })
5835
+ );
5836
+ return JSON.stringify(sealed2.filter((entry) => entry !== null));
5837
+ },
5838
+ decodeTopics: async (json5) => {
5839
+ const list = entries(json5);
5840
+ if (!list?.some(
5841
+ (entry) => hashed(entry) || record(entry) && typeof entry.name === "string" && ciphertextPattern.test(entry.name)
5842
+ ))
5843
+ return json5;
5844
+ const decoded = await Promise.all(
5845
+ list.map(async (entry) => {
5846
+ if (!hashed(entry))
5847
+ return record(entry) && typeof entry.name === "string" ? { ...entry, name: await plain2(entry.name) } : entry;
5848
+ const { name_hash: nameHash, ...rest } = entry;
5849
+ return { ...rest, name: await open({ name: entry.name, name_hash: nameHash }) };
5850
+ })
5851
+ );
5852
+ return JSON.stringify(decoded);
5853
+ },
5854
+ isLegacy: (json5) => (entries(json5) ?? []).some(
5855
+ (entry) => record(entry) && typeof entry.name === "string" && !hashed(entry)
5856
+ ),
5857
+ matchesLegacy: async (json5, names, hashes2) => {
5858
+ const list = typeof json5 === "string" ? entries(json5) ?? [] : [];
5859
+ if (list.some((entry) => hashed(entry) && hashes2.has(entry.name_hash))) return false;
5860
+ const legacy = await Promise.all(
5861
+ list.map(
5862
+ async (entry) => record(entry) && typeof entry.name === "string" && !hashed(entry) ? normalizeTopicName(await plain2(entry.name)) : null
5863
+ )
5864
+ );
5865
+ return legacy.some((name) => name !== null && names.has(name));
5866
+ },
5867
+ encodeCatalog: async (topic2) => {
5868
+ const sealed2 = await seal(normalizeTopicName(await plain2(topic2.name)));
5869
+ return sealed2 && { ...topic2, name: sealed2.name, name_hash: sealed2.name_hash };
5870
+ },
5871
+ decodeCatalog: async (item) => {
5872
+ const { name_hash: nameHash, ...rest } = item;
5873
+ return { ...rest, name: await open({ name: item.name, name_hash: nameHash }) };
5874
+ }
5875
+ };
5876
+ }
5877
+
5733
5878
  // src/lib/memory/store/remoteTopics.ts
5879
+ var RETIRE_CONCURRENCY = 8;
5734
5880
  function topic(value) {
5735
5881
  const t = value;
5736
- if (!t || typeof t.name !== "string" || !t.name || !Number.isSafeInteger(t.version) || t.version < 1 || typeof t.is_deleted !== "boolean" || typeof t.server_updated_at !== "string" || t.kind !== void 0 && typeof t.kind !== "string")
5882
+ if (!t || typeof t.name !== "string" || !t.name || t.name_hash !== void 0 && typeof t.name_hash !== "string" || !Number.isSafeInteger(t.version) || t.version < 1 || typeof t.is_deleted !== "boolean" || typeof t.server_updated_at !== "string" || t.kind !== void 0 && typeof t.kind !== "string")
5737
5883
  throw new Error("Invalid nearby topic");
5738
5884
  return t;
5739
5885
  }
5740
- function createRemoteTopicPersistence(request) {
5886
+ async function wireTopics(request, signal) {
5887
+ const out = [];
5888
+ let cursor;
5889
+ do {
5890
+ const page = await request(
5891
+ "/topics?limit=200" + (cursor ? `&cursor=${encodeURIComponent(cursor)}` : ""),
5892
+ {},
5893
+ signal
5894
+ );
5895
+ if (!Array.isArray(page.items) || page.next_cursor !== void 0 && typeof page.next_cursor !== "string")
5896
+ throw new Error("Invalid nearby topic page");
5897
+ out.push(...page.items.map(topic));
5898
+ cursor = page.next_cursor;
5899
+ } while (cursor);
5900
+ return out;
5901
+ }
5902
+ function hashesOf(items) {
5903
+ return new Set(items.flatMap((t) => t.name_hash === void 0 ? [] : [t.name_hash]));
5904
+ }
5905
+ async function sealedImport(request, codec, topics, signal) {
5906
+ let oversized = 0;
5907
+ for (let i = 0; i < topics.length; i += 50) {
5908
+ signal?.throwIfAborted();
5909
+ const sealed2 = (await Promise.all(topics.slice(i, i + 50).map((t) => codec.encodeCatalog(t)))).filter((t) => {
5910
+ if (t === null) return false;
5911
+ if (t.name.length <= MAX_SEALED_TOPIC_NAME_BYTES) return true;
5912
+ oversized++;
5913
+ return false;
5914
+ });
5915
+ if (sealed2.length)
5916
+ await request(
5917
+ "/topics/import",
5918
+ { method: "POST", body: JSON.stringify({ topics: sealed2 }) },
5919
+ signal
5920
+ );
5921
+ }
5922
+ signal?.throwIfAborted();
5923
+ if (oversized)
5924
+ getLogger().warn(
5925
+ `[memory/remote] Skipped ${oversized} topic catalog entries whose sealed name exceeds ${MAX_SEALED_TOPIC_NAME_BYTES} bytes`
5926
+ );
5927
+ }
5928
+ function createRemoteTopicPersistence(request, codec) {
5929
+ let legacyOnly = /* @__PURE__ */ new Set();
5741
5930
  return {
5742
5931
  topics: async () => {
5743
- const out = [];
5744
- let cursor;
5745
- do {
5746
- const page = await request(
5747
- "/topics?limit=200" + (cursor ? `&cursor=${encodeURIComponent(cursor)}` : ""),
5748
- {}
5749
- );
5750
- if (!Array.isArray(page.items) || page.next_cursor !== void 0 && typeof page.next_cursor !== "string")
5751
- throw new Error("Invalid nearby topic page");
5752
- out.push(...page.items.map(topic));
5753
- cursor = page.next_cursor;
5754
- } while (cursor);
5755
- return out;
5932
+ const items = await wireTopics(request);
5933
+ const hashed2 = hashesOf(items);
5934
+ const legacy = /* @__PURE__ */ new Set();
5935
+ const decoded = await Promise.all(
5936
+ items.map(async (item) => {
5937
+ const plain2 = await codec.decodeCatalog(item);
5938
+ const name = normalizeTopicName(plain2.name);
5939
+ if (item.name_hash === void 0) {
5940
+ const hash = await codec.hash(name);
5941
+ if (hash !== null && hashed2.has(hash)) return null;
5942
+ legacy.add(name);
5943
+ }
5944
+ return { ...plain2, name };
5945
+ })
5946
+ );
5947
+ legacyOnly = legacy;
5948
+ return decoded.filter((t) => t !== null);
5756
5949
  },
5757
5950
  putTopic: async (value, expectedVersion) => {
5758
5951
  if (!Number.isSafeInteger(expectedVersion) || expectedVersion < 0)
5759
5952
  throw new Error("Expected topic version must be a nonnegative integer");
5760
- return topic(
5953
+ const sealed2 = await codec.encodeCatalog(value);
5954
+ if (!sealed2) throw new Error("Topic name must not be empty");
5955
+ const saved = topic(
5761
5956
  await request("/topics", {
5762
5957
  method: "PUT",
5763
- body: JSON.stringify({ topic: value, expected_version: expectedVersion })
5958
+ body: JSON.stringify({
5959
+ topic: sealed2,
5960
+ expected_version: legacyOnly.has(normalizeTopicName(value.name)) ? 0 : expectedVersion
5961
+ })
5764
5962
  })
5765
5963
  );
5766
- },
5767
- importTopics: async (topics, signal) => {
5768
- for (let i = 0; i < topics.length; i += 50) {
5769
- signal?.throwIfAborted();
5770
- await request(
5771
- "/topics/import",
5772
- {
5773
- method: "POST",
5774
- body: JSON.stringify({ topics: topics.slice(i, i + 50) })
5775
- },
5776
- signal
5777
- );
5778
- }
5964
+ const decoded = await codec.decodeCatalog(saved);
5965
+ legacyOnly.delete(decoded.name);
5966
+ return decoded;
5967
+ },
5968
+ importTopics: (topics, signal) => sealedImport(
5969
+ request,
5970
+ codec,
5971
+ topics.map(({ name, kind }) => ({ name, ...kind !== void 0 && { kind } })),
5972
+ signal
5973
+ )
5974
+ };
5975
+ }
5976
+ async function retireLegacyTopics(request, codec, topics, imported, signal) {
5977
+ const failures = [];
5978
+ const put = async (topic2, expectedVersion) => {
5979
+ try {
5980
+ await request(
5981
+ "/topics",
5982
+ { method: "PUT", body: JSON.stringify({ topic: topic2, expected_version: expectedVersion }) },
5983
+ signal
5984
+ );
5985
+ return "saved";
5986
+ } catch (error) {
5987
+ if (signal?.aborted) throw error;
5988
+ if (error instanceof RemoteMemoryError && error.status === 409) return "conflict";
5989
+ failures.push(error);
5990
+ return "failed";
5991
+ }
5992
+ };
5993
+ const retire = (item) => put(
5994
+ { name: item.name, ...item.kind !== void 0 && { kind: item.kind }, is_deleted: true },
5995
+ item.version
5996
+ );
5997
+ const changed = [];
5998
+ let next = 0;
5999
+ const worker = async () => {
6000
+ while (next < topics.length) {
5779
6001
  signal?.throwIfAborted();
6002
+ const item = topics[next++];
6003
+ if (await retire(item) === "conflict") changed.push(item);
5780
6004
  }
5781
6005
  };
6006
+ await Promise.all(
6007
+ Array.from({ length: Math.min(RETIRE_CONCURRENCY, topics.length) }, () => worker())
6008
+ );
6009
+ if (changed.length) {
6010
+ const current = await wireTopics(request, signal);
6011
+ for (const stale of changed) {
6012
+ const legacy = current.find((t) => t.name_hash === void 0 && t.name === stale.name);
6013
+ if (!legacy || legacy.is_deleted) continue;
6014
+ const hash = await codec.hash(await codec.open(legacy));
6015
+ const copy = current.find((t) => t.name_hash !== void 0 && t.name_hash === hash);
6016
+ if (!copy || hash === null) continue;
6017
+ const newer = imported.has(hash) || Date.parse(legacy.server_updated_at) > Date.parse(copy.server_updated_at);
6018
+ if (newer && (copy.is_deleted || legacy.kind !== copy.kind)) {
6019
+ const sealed2 = await codec.encodeCatalog({
6020
+ name: legacy.name,
6021
+ ...legacy.kind !== void 0 && { kind: legacy.kind },
6022
+ is_deleted: false
6023
+ });
6024
+ if (!sealed2 || await put(sealed2, copy.version) !== "saved") continue;
6025
+ }
6026
+ await retire(legacy);
6027
+ }
6028
+ }
6029
+ if (failures.length)
6030
+ getLogger().warn(
6031
+ `[memory/remote] Could not retire ${failures.length} upgraded topic catalog entries:`,
6032
+ failures[0]
6033
+ );
6034
+ }
6035
+ async function upgradeLegacyTopicCatalog(request, codec, signal) {
6036
+ const items = await wireTopics(request, signal);
6037
+ const hashed2 = hashesOf(items);
6038
+ const hashes = await Promise.all(
6039
+ items.map(
6040
+ async (item) => item.name_hash === void 0 ? codec.hash(await codec.open(item)) : null
6041
+ )
6042
+ );
6043
+ const sources = /* @__PURE__ */ new Map();
6044
+ const live2 = [];
6045
+ items.forEach((item, i) => {
6046
+ const hash = hashes[i];
6047
+ if (hash === null) return;
6048
+ if (!item.is_deleted) live2.push(item);
6049
+ if (hashed2.has(hash)) return;
6050
+ const source = sources.get(hash);
6051
+ if (!source || source.is_deleted && !item.is_deleted) sources.set(hash, item);
6052
+ });
6053
+ const legacy = [...sources.values()].map((item) => ({
6054
+ name: item.name,
6055
+ ...item.kind !== void 0 && { kind: item.kind },
6056
+ ...item.is_deleted && { is_deleted: true }
6057
+ }));
6058
+ await sealedImport(request, codec, legacy, signal);
6059
+ await retireLegacyTopics(request, codec, live2, new Set(sources.keys()), signal);
6060
+ return legacy.length;
5782
6061
  }
5783
6062
  async function createRemoteTopic(persistence, name) {
5784
- const canonical = normalizeEntityName(name);
6063
+ const canonical = normalizeTopicName(name);
5785
6064
  if (!canonical) return null;
5786
6065
  const existing = (await persistence.topics()).find((t) => t.name === canonical);
5787
6066
  if (existing && !existing.is_deleted) return canonical;
@@ -5869,7 +6148,10 @@ var RemoteMemoryError = class extends Error {
5869
6148
  this.name = "RemoteMemoryError";
5870
6149
  }
5871
6150
  };
5872
- var ciphertextPattern = /^enc:v\d+:[0-9a-f]+$/i;
6151
+ var TOPIC_UPGRADE_PROCESSOR = "topic-hash-v1";
6152
+ var TOPIC_UPGRADE_PAGE = 50;
6153
+ var LEGACY_TOPIC_CURSOR = "legacy-topics:";
6154
+ var LEGACY_TOPIC_RECHECK_MS = 6e4;
5873
6155
  var memoryFields = {
5874
6156
  memory_id: true,
5875
6157
  content: true,
@@ -5929,7 +6211,8 @@ var queryFields = [
5929
6211
  "fact_types",
5930
6212
  "visibility",
5931
6213
  "memory_ids",
5932
- "topics",
6214
+ "topic_hashes",
6215
+ "topics_legacy",
5933
6216
  "updated_after",
5934
6217
  "topics_due",
5935
6218
  "topics_extracted",
@@ -5939,11 +6222,17 @@ var queryFields = [
5939
6222
  "limit",
5940
6223
  "include_embeddings"
5941
6224
  ];
5942
- function record(value) {
6225
+ function isVersionConflict(error) {
6226
+ return error instanceof RemoteMemoryError && error.code === "version_conflict";
6227
+ }
6228
+ function isRejectedRow(error) {
6229
+ return error instanceof RemoteMemoryError && error.status === 400;
6230
+ }
6231
+ function record2(value) {
5943
6232
  return typeof value === "object" && value !== null && !Array.isArray(value);
5944
6233
  }
5945
6234
  function memoryRecord(value) {
5946
- 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))) {
6235
+ if (!record2(value) || !record2(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))) {
5947
6236
  throw new Error("Invalid nearby private-memory response");
5948
6237
  }
5949
6238
  return value;
@@ -6023,14 +6312,14 @@ function createNearbyRequest(options, apiPath = "/api/private-memories") {
6023
6312
  const body = await response.json().catch(() => null);
6024
6313
  const retryAfter = parseRetryAfterMs(response.headers.get("Retry-After"));
6025
6314
  const error = new RemoteMemoryError(
6026
- record(body) && typeof body.detail === "string" ? body.detail : `Nearby request failed (${response.status})`,
6315
+ record2(body) && typeof body.detail === "string" ? body.detail : `Nearby request failed (${response.status})`,
6027
6316
  response.status,
6028
- record(body) && typeof body.code === "string" ? body.code : void 0,
6317
+ record2(body) && typeof body.code === "string" ? body.code : void 0,
6029
6318
  retryAfter ?? void 0,
6030
- record(body) && typeof body.rate_limit_bucket === "string" ? body.rate_limit_bucket : void 0
6319
+ record2(body) && typeof body.rate_limit_bucket === "string" ? body.rate_limit_bucket : void 0
6031
6320
  );
6032
6321
  if (response.status === 429 && retryAfter !== null && retryAfter > 0 && (!error.code || error.code === "rate_limited")) {
6033
- const bucket = error.rateLimitBucket && budgets.includes(error.rateLimitBucket) ? error.rateLimitBucket : record(body) && (body.limit_scope === "account" || body.limit_scope === "ip") && !error.rateLimitBucket ? "*" : route;
6322
+ const bucket = error.rateLimitBucket && budgets.includes(error.rateLimitBucket) ? error.rateLimitBucket : record2(body) && (body.limit_scope === "account" || body.limit_scope === "ip") && !error.rateLimitBucket ? "*" : route;
6034
6323
  cooldowns.set(bucket, { until: Date.now() + retryAfter, error });
6035
6324
  }
6036
6325
  throw error;
@@ -6053,7 +6342,7 @@ async function createRemoteMemoryPersistence(options) {
6053
6342
  throw new Error("A canonical keyId is required");
6054
6343
  const request = createNearbyRequest(options);
6055
6344
  const account = await request("/account", {}, options.signal);
6056
- if (!record(account) || account.state !== "active") {
6345
+ if (!record2(account) || account.state !== "active") {
6057
6346
  throw new RemoteMemoryError(
6058
6347
  "Complete and verify migration before using remote memories",
6059
6348
  409,
@@ -6067,6 +6356,25 @@ async function createRemoteMemoryPersistence(options) {
6067
6356
  "key_mismatch"
6068
6357
  );
6069
6358
  }
6359
+ const codec = createTopicCodec(options);
6360
+ let legacyTopicRows = typeof account.legacy_topic_memories === "number" && account.legacy_topic_memories > 0;
6361
+ if (typeof account.legacy_topic_catalog === "number" && account.legacy_topic_catalog > 0)
6362
+ void upgradeLegacyTopicCatalog(request, codec, options.signal).catch((error) => {
6363
+ if (!options.signal?.aborted)
6364
+ getLogger().warn("[memory/remote] Topic catalog upgrade failed:", error);
6365
+ });
6366
+ let legacyCheckedAt = Date.now();
6367
+ let legacyCheck;
6368
+ const recheckLegacyTopicRows = () => {
6369
+ if (legacyCheck || Date.now() - legacyCheckedAt < LEGACY_TOPIC_RECHECK_MS) return;
6370
+ legacyCheckedAt = Date.now();
6371
+ legacyCheck = request("/account", {}, options.signal).then((current) => {
6372
+ if (record2(current) && current.legacy_topic_memories === 0) legacyTopicRows = false;
6373
+ }).catch(() => {
6374
+ }).finally(() => {
6375
+ legacyCheck = void 0;
6376
+ });
6377
+ };
6070
6378
  const snapshots = /* @__PURE__ */ new WeakMap();
6071
6379
  const decode = async (value) => {
6072
6380
  const item = memoryRecord(value);
@@ -6084,6 +6392,9 @@ async function createRemoteMemoryPersistence(options) {
6084
6392
  content: item.memory.is_deleted && item.memory.content === "" ? "" : await decrypt(item.memory.content),
6085
6393
  ...item.memory.kind_value !== void 0 && {
6086
6394
  kind_value: await decrypt(item.memory.kind_value)
6395
+ },
6396
+ ...item.memory.topics !== void 0 && {
6397
+ topics: await codec.decodeTopics(item.memory.topics)
6087
6398
  }
6088
6399
  }
6089
6400
  };
@@ -6095,8 +6406,10 @@ async function createRemoteMemoryPersistence(options) {
6095
6406
  version: item.version,
6096
6407
  content: decoded.memory.content,
6097
6408
  kindValue: decoded.memory.kind_value,
6409
+ topics: decoded.memory.topics,
6098
6410
  encryptedContent: item.memory.content,
6099
- encryptedKindValue: item.memory.kind_value
6411
+ encryptedKindValue: item.memory.kind_value,
6412
+ encryptedTopics: item.memory.topics
6100
6413
  });
6101
6414
  return decoded;
6102
6415
  };
@@ -6118,7 +6431,7 @@ async function createRemoteMemoryPersistence(options) {
6118
6431
  };
6119
6432
  const decodeCommitted = async (value, write) => {
6120
6433
  const item = memoryRecord(value);
6121
- 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)
6434
+ 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 || item.memory.topics !== write.body.memory.topics)
6122
6435
  return decode(item);
6123
6436
  return remember(
6124
6437
  {
@@ -6126,7 +6439,8 @@ async function createRemoteMemoryPersistence(options) {
6126
6439
  memory: {
6127
6440
  ...item.memory,
6128
6441
  content: write.content,
6129
- ...write.kindValue !== void 0 && { kind_value: write.kindValue }
6442
+ ...write.kindValue !== void 0 && { kind_value: write.kindValue },
6443
+ ...write.topics !== void 0 && { topics: write.topics }
6130
6444
  }
6131
6445
  },
6132
6446
  item
@@ -6178,13 +6492,21 @@ async function createRemoteMemoryPersistence(options) {
6178
6492
  const reusableContent = snapshot?.encryptedContent ?? existing?.memory.content;
6179
6493
  const content = reusableContent && (snapshot?.content ?? decoded?.memory.content) === memory.content ? reusableContent : await encryptField2(memory.content);
6180
6494
  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);
6495
+ const wireTopics2 = snapshot ? snapshot.encryptedTopics : existing?.memory.topics;
6496
+ const topics = memory.topics === void 0 ? void 0 : (snapshot?.topics ?? decoded?.memory.topics) === memory.topics && wireTopics2 !== void 0 && !codec.isLegacy(wireTopics2) ? wireTopics2 : await codec.encodeTopics(memory.topics);
6181
6497
  return {
6182
6498
  body: {
6183
6499
  expected_version: expectedVersion,
6184
- memory: { ...memory, content, ...kindValue !== void 0 && { kind_value: kindValue } }
6500
+ memory: {
6501
+ ...memory,
6502
+ content,
6503
+ ...kindValue !== void 0 && { kind_value: kindValue },
6504
+ ...topics !== void 0 && { topics }
6505
+ }
6185
6506
  },
6186
6507
  content: memory.content,
6187
- kindValue: memory.kind_value
6508
+ kindValue: memory.kind_value,
6509
+ topics: memory.topics
6188
6510
  };
6189
6511
  };
6190
6512
  const fetchCandidates = async (embedding2, candidateOptions, withCounts) => {
@@ -6233,32 +6555,72 @@ async function createRemoteMemoryPersistence(options) {
6233
6555
  },
6234
6556
  candidateOptions.signal
6235
6557
  );
6236
- if (!record(result) || !Array.isArray(result.items))
6558
+ if (!record2(result) || !Array.isArray(result.items))
6237
6559
  throw new Error("Invalid nearby candidate response");
6238
6560
  return result;
6239
6561
  };
6240
6562
  const fetchQueryPage = async (queryOptions) => {
6241
- const { signal, ...query } = queryOptions;
6242
- if (query.limit !== void 0 && (!Number.isInteger(query.limit) || query.limit < 1 || query.limit > 200))
6563
+ const { signal, topics: names, ...wire2 } = queryOptions;
6564
+ if (wire2.limit !== void 0 && (!Number.isInteger(wire2.limit) || wire2.limit < 1 || wire2.limit > 200))
6243
6565
  throw new Error("Page limit must be 1\u2013200");
6244
6566
  for (const [key3, max] of queryListLimits) {
6245
- const values = query[key3];
6567
+ const values = queryOptions[key3];
6246
6568
  if (values && values.length > max)
6247
6569
  throw new Error(`Query ${key3} accepts at most ${max} entries (got ${values.length})`);
6248
6570
  }
6571
+ const body = wire2;
6572
+ if (names === void 0) return postQuery(body, signal);
6573
+ const hashes = [
6574
+ ...new Set(
6575
+ (await Promise.all(names.map((name) => codec.hash(name)))).filter((h) => h !== null)
6576
+ )
6577
+ ];
6578
+ if (names.length > 0 && hashes.length === 0) return { items: [] };
6579
+ if (hashes.length > 0 && wire2.cursor?.startsWith(LEGACY_TOPIC_CURSOR)) {
6580
+ const page2 = await postQuery(
6581
+ {
6582
+ ...wire2,
6583
+ cursor: wire2.cursor.slice(LEGACY_TOPIC_CURSOR.length) || void 0,
6584
+ topics_legacy: true
6585
+ },
6586
+ signal
6587
+ );
6588
+ const wanted = new Set(names.map(normalizeTopicName));
6589
+ const hashed2 = new Set(hashes);
6590
+ const matches = await Promise.all(
6591
+ page2.items.map(
6592
+ (item) => codec.matchesLegacy(
6593
+ record2(item) && record2(item.memory) ? item.memory.topics : void 0,
6594
+ wanted,
6595
+ hashed2
6596
+ )
6597
+ )
6598
+ );
6599
+ return {
6600
+ ...page2,
6601
+ items: page2.items.filter((_, i) => matches[i]),
6602
+ next_cursor: page2.next_cursor === void 0 ? void 0 : LEGACY_TOPIC_CURSOR + page2.next_cursor
6603
+ };
6604
+ }
6605
+ const page = await postQuery({ ...body, topic_hashes: hashes }, signal);
6606
+ if (hashes.length === 0 || page.next_cursor !== void 0 || !legacyTopicRows) return page;
6607
+ recheckLegacyTopicRows();
6608
+ return { ...page, next_cursor: LEGACY_TOPIC_CURSOR };
6609
+ };
6610
+ const postQuery = async (body, signal) => {
6249
6611
  const page = await request(
6250
6612
  "/memories/query",
6251
6613
  {
6252
6614
  method: "POST",
6253
6615
  body: JSON.stringify(
6254
6616
  Object.fromEntries(
6255
- queryFields.filter((key3) => query[key3] !== void 0).map((key3) => [key3, query[key3]])
6617
+ queryFields.filter((key3) => body[key3] !== void 0).map((key3) => [key3, body[key3]])
6256
6618
  )
6257
6619
  )
6258
6620
  },
6259
6621
  signal
6260
6622
  );
6261
- if (!record(page) || !Array.isArray(page.items) || page.next_cursor !== void 0 && typeof page.next_cursor !== "string" || page.changes_cursor !== void 0 && typeof page.changes_cursor !== "string")
6623
+ if (!record2(page) || !Array.isArray(page.items) || page.next_cursor !== void 0 && typeof page.next_cursor !== "string" || page.changes_cursor !== void 0 && typeof page.changes_cursor !== "string")
6262
6624
  throw new Error("Invalid nearby private-memory page");
6263
6625
  return page;
6264
6626
  };
@@ -6272,13 +6634,13 @@ async function createRemoteMemoryPersistence(options) {
6272
6634
  unavailable_count: result.unavailable_count
6273
6635
  };
6274
6636
  };
6275
- return {
6276
- ...createRemoteTopicPersistence(request),
6637
+ const persistence = {
6638
+ ...createRemoteTopicPersistence(request, codec),
6277
6639
  ...createRemoteWorkPersistence(request),
6278
6640
  supportsRealtimeChanges: account.realtime_changes === true,
6279
6641
  counts: async () => {
6280
6642
  const result = await request("/counts", {});
6281
- if (!record(result) || ["live", "archived", "quarantined"].some(
6643
+ if (!record2(result) || ["live", "archived", "quarantined"].some(
6282
6644
  (key3) => !Number.isSafeInteger(result[key3]) || result[key3] < 0
6283
6645
  ))
6284
6646
  throw new Error("Invalid nearby memory counts");
@@ -6295,8 +6657,8 @@ async function createRemoteMemoryPersistence(options) {
6295
6657
  method: "POST",
6296
6658
  body: JSON.stringify({ ...window2, limit })
6297
6659
  });
6298
- if (!record(result) || !Array.isArray(result.items) || result.items.some(
6299
- (item) => !record(item) || typeof item.memory_id !== "string" || !item.memory_id || typeof item.score !== "number" || !Number.isFinite(item.score) || item.score <= 0 || item.score > 1
6660
+ if (!record2(result) || !Array.isArray(result.items) || result.items.some(
6661
+ (item) => !record2(item) || typeof item.memory_id !== "string" || !item.memory_id || typeof item.score !== "number" || !Number.isFinite(item.score) || item.score <= 0 || item.score > 1
6300
6662
  ))
6301
6663
  throw new Error("Invalid nearby temporal candidates");
6302
6664
  return result.items.map((item) => item.memory_id);
@@ -6327,7 +6689,7 @@ async function createRemoteMemoryPersistence(options) {
6327
6689
  if (query[key3] !== void 0) params.set(key3, String(query[key3]));
6328
6690
  }
6329
6691
  const page = await request("/memories?" + params.toString(), {}, signal);
6330
- if (!record(page) || !Array.isArray(page.items) || page.next_cursor !== void 0 && typeof page.next_cursor !== "string") {
6692
+ if (!record2(page) || !Array.isArray(page.items) || page.next_cursor !== void 0 && typeof page.next_cursor !== "string") {
6331
6693
  throw new Error("Invalid nearby private-memory page");
6332
6694
  }
6333
6695
  return {
@@ -6367,7 +6729,7 @@ async function createRemoteMemoryPersistence(options) {
6367
6729
  },
6368
6730
  signal
6369
6731
  );
6370
- if (!record(result) || !Array.isArray(result.items) || result.items.length !== prepared.length)
6732
+ if (!record2(result) || !Array.isArray(result.items) || result.items.length !== prepared.length)
6371
6733
  throw new Error("Invalid nearby batch response");
6372
6734
  return Promise.all(result.items.map((item, i) => decodeCommitted(item, prepared[i])));
6373
6735
  },
@@ -6382,20 +6744,87 @@ async function createRemoteMemoryPersistence(options) {
6382
6744
  queryMetadata: async (queryOptions = {}) => {
6383
6745
  const page = await fetchQueryPage(queryOptions);
6384
6746
  return {
6385
- items: page.items.map((item) => {
6386
- const {
6387
- memory: { content: _content, kind_value: _kindValue, ...memory },
6388
- version,
6389
- server_updated_at
6390
- } = memoryRecord(item);
6391
- return { memory, version, server_updated_at };
6392
- }),
6747
+ items: await Promise.all(
6748
+ page.items.map(async (item) => {
6749
+ const {
6750
+ memory: { content: _content, kind_value: _kindValue, topics, ...memory },
6751
+ version,
6752
+ server_updated_at
6753
+ } = memoryRecord(item);
6754
+ const plain2 = topics === void 0 ? void 0 : await codec.decodeTopics(topics).catch(() => null);
6755
+ return {
6756
+ memory: { ...memory, ...typeof plain2 === "string" && { topics: plain2 } },
6757
+ version,
6758
+ server_updated_at
6759
+ };
6760
+ })
6761
+ ),
6393
6762
  ...page.next_cursor !== void 0 && { next_cursor: page.next_cursor }
6394
6763
  };
6395
6764
  },
6396
6765
  candidateSet,
6397
6766
  candidates: async (embedding2, candidateOptions = {}) => decodeAll((await fetchCandidates(embedding2, candidateOptions, false)).items)
6398
6767
  };
6768
+ let rejectedRows = 0;
6769
+ const rewriteLegacyTopics = async (records, token) => {
6770
+ const write = (batch) => persistence.putMany(
6771
+ batch.map((item) => ({ memory: item.memory, expectedVersion: item })),
6772
+ options.signal,
6773
+ token
6774
+ );
6775
+ try {
6776
+ await write(records);
6777
+ return true;
6778
+ } catch (error) {
6779
+ if (!isVersionConflict(error) && !isRejectedRow(error)) throw error;
6780
+ if (records.length === 1) {
6781
+ if (isRejectedRow(error)) rejectedRows++;
6782
+ return false;
6783
+ }
6784
+ let complete = true;
6785
+ for (const item of records)
6786
+ await write([item]).catch((rowError) => {
6787
+ if (isRejectedRow(rowError)) rejectedRows++;
6788
+ else if (!isVersionConflict(rowError)) throw rowError;
6789
+ complete = false;
6790
+ });
6791
+ return complete;
6792
+ }
6793
+ };
6794
+ const upgradeLegacyTopics = () => withRemoteWorkLease(persistence, "topics", TOPIC_UPGRADE_PROCESSOR, async (token, lease) => {
6795
+ let cursor;
6796
+ let complete = true;
6797
+ do {
6798
+ options.signal?.throwIfAborted();
6799
+ if (lease.aborted) return false;
6800
+ const page = await fetchQueryPage({
6801
+ topics_legacy: true,
6802
+ include_archived: true,
6803
+ include_quarantined: true,
6804
+ include_superseded: true,
6805
+ limit: TOPIC_UPGRADE_PAGE,
6806
+ ...cursor !== void 0 && { cursor },
6807
+ signal: options.signal
6808
+ });
6809
+ const { items } = await decodeAll(page.items);
6810
+ const legacy = items.filter((item) => codec.isLegacy(snapshots.get(item)?.encryptedTopics));
6811
+ if (legacy.length && !await rewriteLegacyTopics(legacy, token)) complete = false;
6812
+ cursor = page.next_cursor;
6813
+ } while (cursor);
6814
+ if (rejectedRows)
6815
+ getLogger().warn(
6816
+ `[memory/remote] Nearby rejected ${rejectedRows} rows during the topic upgrade; they keep legacy topics`
6817
+ );
6818
+ return complete;
6819
+ });
6820
+ if (legacyTopicRows)
6821
+ void upgradeLegacyTopics().then((complete) => {
6822
+ if (complete) legacyTopicRows = false;
6823
+ }).catch((error) => {
6824
+ if (!options.signal?.aborted)
6825
+ getLogger().warn("[memory/remote] Topic upgrade failed:", error);
6826
+ });
6827
+ return persistence;
6399
6828
  }
6400
6829
 
6401
6830
  // src/lib/chat/inbox.ts
@@ -6485,6 +6914,67 @@ async function openInboxItem(item, keyPair) {
6485
6914
  }
6486
6915
  return opened;
6487
6916
  }
6917
+ function inboxReplaces(row, opened) {
6918
+ if (row.error) return true;
6919
+ return row.wasStopped === true && opened.status === "completed";
6920
+ }
6921
+ async function clearTurnErrors(backend, answer) {
6922
+ const parentId = answer.parentMessageId;
6923
+ if (parentId) {
6924
+ const [parent] = await backend.getMessagesByIds([parentId]);
6925
+ if (parent?.error) await backend.updateMessageError(parentId, null);
6926
+ }
6927
+ if (!answer.error) return answer;
6928
+ return await backend.updateMessageError(answer.uniqueId, null) ?? answer;
6929
+ }
6930
+ async function deliverInboxAnswers(options) {
6931
+ const { inbox, keyPair, backend, store } = options;
6932
+ const results = [];
6933
+ for (const item of await inbox.list()) {
6934
+ let opened;
6935
+ try {
6936
+ opened = await openInboxItem(item, keyPair);
6937
+ } catch (err) {
6938
+ results.push({
6939
+ id: item.id,
6940
+ conversationId: null,
6941
+ status: "unreadable",
6942
+ assistantMessage: null,
6943
+ error: err instanceof Error ? err.message : String(err)
6944
+ });
6945
+ continue;
6946
+ }
6947
+ const base = { id: item.id, conversationId: opened.conversation_id };
6948
+ try {
6949
+ const messageId = opened.assistant_message_id ?? `msg_bg_${opened.inference_id}`;
6950
+ const [found] = await backend.getMessagesByIds([messageId]);
6951
+ const existing = found && inboxReplaces(found, opened) ? void 0 : found;
6952
+ if (!found) {
6953
+ const parent = opened.parent_message_id;
6954
+ const ownsTurn = parent ? (await backend.getMessagesByIds([parent])).length > 0 : await backend.getConversation(opened.conversation_id) !== null;
6955
+ if (!ownsTurn) {
6956
+ results.push({ ...base, status: "elsewhere", assistantMessage: null });
6957
+ continue;
6958
+ }
6959
+ }
6960
+ const stored2 = existing ?? await store(opened, messageId);
6961
+ await inbox.remove(item.id);
6962
+ results.push({
6963
+ ...base,
6964
+ status: existing ? "delivered" : "stored",
6965
+ assistantMessage: stored2
6966
+ });
6967
+ } catch (err) {
6968
+ results.push({
6969
+ ...base,
6970
+ status: "retry",
6971
+ assistantMessage: null,
6972
+ error: err instanceof Error ? err.message : String(err)
6973
+ });
6974
+ }
6975
+ }
6976
+ return results;
6977
+ }
6488
6978
 
6489
6979
  // src/lib/chat/reservationReceipts.ts
6490
6980
  var ACTIONS = [
@@ -6885,9 +7375,9 @@ function toResponsesFormat(tool) {
6885
7375
  function getCachedServerTools() {
6886
7376
  if (typeof localStorage === "undefined") return null;
6887
7377
  try {
6888
- const cached = localStorage.getItem(SERVER_TOOLS_CACHE_KEY);
6889
- if (!cached) return null;
6890
- const parsed = JSON.parse(cached);
7378
+ const cached2 = localStorage.getItem(SERVER_TOOLS_CACHE_KEY);
7379
+ if (!cached2) return null;
7380
+ const parsed = JSON.parse(cached2);
6891
7381
  if (parsed.version !== CACHE_VERSION) {
6892
7382
  removeLocalStorageCache();
6893
7383
  return null;
@@ -6931,8 +7421,8 @@ function clearServerToolsCache(cache = localStorageToolsCache) {
6931
7421
  return cache.clear?.();
6932
7422
  }
6933
7423
  function getToolsChecksum2(cache = localStorageToolsCache) {
6934
- const cached = cache.get();
6935
- return cached instanceof Promise ? cached.then((c) => c?.checksum) : cached?.checksum;
7424
+ const cached2 = cache.get();
7425
+ return cached2 instanceof Promise ? cached2.then((c) => c?.checksum) : cached2?.checksum;
6936
7426
  }
6937
7427
  function shouldRefreshTools(responseChecksum, cache = localStorageToolsCache) {
6938
7428
  if (!responseChecksum) {
@@ -6995,33 +7485,33 @@ async function getServerTools(options) {
6995
7485
  } catch (error) {
6996
7486
  getLogger().warn("[serverTools] Cache read failed; falling through to server fetch:", error);
6997
7487
  }
6998
- const cached = rawCached && rawCached.version === CACHE_VERSION ? rawCached : null;
6999
- const cacheValid = !isCacheExpired(cached, cacheExpirationMs);
7000
- if (cached && cacheValid && !forceRefresh) {
7001
- return cached.tools;
7488
+ const cached2 = rawCached && rawCached.version === CACHE_VERSION ? rawCached : null;
7489
+ const cacheValid = !isCacheExpired(cached2, cacheExpirationMs);
7490
+ if (cached2 && cacheValid && !forceRefresh) {
7491
+ return cached2.tools;
7002
7492
  }
7003
7493
  try {
7004
7494
  const { BASE_URL: BASE_URL2 } = await import("./clientConfig-VPOGQRNP.mjs");
7005
7495
  const effectiveBaseUrl = baseUrl ?? BASE_URL2;
7006
- const validator = cached && !forceRefresh ? cached.etag : void 0;
7496
+ const validator = cached2 && !forceRefresh ? cached2.etag : void 0;
7007
7497
  let authHeaders;
7008
7498
  if (apiKey) {
7009
7499
  authHeaders = { "X-API-Key": apiKey };
7010
7500
  } else {
7011
7501
  if (!getToken) {
7012
7502
  getLogger().warn("[serverTools] No auth method available for fetching tools");
7013
- return cached?.tools ?? [];
7503
+ return cached2?.tools ?? [];
7014
7504
  }
7015
7505
  const token = await getToken();
7016
7506
  if (!token) {
7017
7507
  getLogger().warn("[serverTools] No auth token available for fetching tools");
7018
- return cached?.tools ?? [];
7508
+ return cached2?.tools ?? [];
7019
7509
  }
7020
7510
  authHeaders = { Authorization: `Bearer ${token}` };
7021
7511
  }
7022
7512
  const result = await fetchServerToolsFromApi(effectiveBaseUrl, authHeaders, validator);
7023
7513
  if (result.notModified) {
7024
- const confirmed = cached;
7514
+ const confirmed = cached2;
7025
7515
  await persistCache({ ...confirmed, timestamp: Date.now() });
7026
7516
  return confirmed.tools;
7027
7517
  }
@@ -7029,9 +7519,9 @@ async function getServerTools(options) {
7029
7519
  return result.tools;
7030
7520
  } catch (error) {
7031
7521
  getLogger().error("[serverTools] Failed to fetch server tools:", error);
7032
- if (cached?.tools) {
7522
+ if (cached2?.tools) {
7033
7523
  getLogger().warn("[serverTools] Using stale cached tools due to fetch error");
7034
- return cached.tools;
7524
+ return cached2.tools;
7035
7525
  }
7036
7526
  return [];
7037
7527
  }
@@ -7961,6 +8451,13 @@ function createErrorResult(message, onError) {
7961
8451
  function isAbortError(err) {
7962
8452
  return err instanceof Error && err.name === "AbortError";
7963
8453
  }
8454
+ var ProviderStreamError = class extends Error {
8455
+ constructor(message, code) {
8456
+ super(message);
8457
+ this.name = "ProviderStreamError";
8458
+ this.code = code;
8459
+ }
8460
+ };
7964
8461
  function getInStreamErrorMessage(chunk) {
7965
8462
  if (!chunk || typeof chunk !== "object") return null;
7966
8463
  const obj = chunk;
@@ -8158,13 +8655,13 @@ function extractParamGroups(content) {
8158
8655
  }
8159
8656
  function mergeXaiInlineParameterTags(content, toolCalls) {
8160
8657
  if (!content || !content.includes(PARAM_MARKER)) return content;
8161
- const entries = Array.from(toolCalls.values());
8162
- if (entries.length === 0) return content;
8658
+ const entries2 = Array.from(toolCalls.values());
8659
+ if (entries2.length === 0) return content;
8163
8660
  const groups = extractParamGroups(content);
8164
8661
  if (groups.length === 0) return content;
8165
- const pairCount = Math.min(groups.length, entries.length);
8662
+ const pairCount = Math.min(groups.length, entries2.length);
8166
8663
  for (let i = 0; i < pairCount; i++) {
8167
- const target = entries[i];
8664
+ const target = entries2[i];
8168
8665
  const params = groups[i];
8169
8666
  if (!target || !params) continue;
8170
8667
  let args = {};
@@ -8247,7 +8744,7 @@ var CompletionsStrategy = class {
8247
8744
  processStreamChunk(chunk, accumulator) {
8248
8745
  const result = { content: null, thinking: null };
8249
8746
  const inStreamErr = getInStreamErrorMessage(chunk);
8250
- if (inStreamErr) throw new Error(inStreamErr);
8747
+ if (inStreamErr) throw new ProviderStreamError(inStreamErr);
8251
8748
  const rawChunk = chunk;
8252
8749
  const typedChunk = rawChunk.response && rawChunk.type === "response" ? rawChunk.response : chunk;
8253
8750
  if (typedChunk.id && !accumulator.responseId) {
@@ -9098,7 +9595,7 @@ var ResponsesStrategy = class {
9098
9595
  const result = { content: null, thinking: null };
9099
9596
  const typedChunk = chunk;
9100
9597
  const inStreamErr = getInStreamErrorMessage(chunk);
9101
- if (inStreamErr) throw new Error(inStreamErr);
9598
+ if (inStreamErr) throw new ProviderStreamError(inStreamErr);
9102
9599
  if (typedChunk.type === "response.failed") {
9103
9600
  const resp = typedChunk.response;
9104
9601
  const err = resp?.error;
@@ -9115,9 +9612,12 @@ var ResponsesStrategy = class {
9115
9612
  }
9116
9613
  }
9117
9614
  const label = code ? `[${code}] ` : "";
9118
- throw new Error(`${label}${message || "Upstream request failed"}`);
9615
+ throw new ProviderStreamError(
9616
+ `${label}${message || "Upstream request failed"}`,
9617
+ code || void 0
9618
+ );
9119
9619
  }
9120
- throw new Error("Upstream request failed (response.failed)");
9620
+ throw new ProviderStreamError("Upstream request failed (response.failed)");
9121
9621
  }
9122
9622
  if (typedChunk.type === "response" && typedChunk.response) {
9123
9623
  const resp = typedChunk.response;
@@ -9741,13 +10241,6 @@ function isRetriableStreamError(err) {
9741
10241
  if (msg.includes("connection refused") || msg.includes("connect error")) return true;
9742
10242
  return false;
9743
10243
  }
9744
- var ProviderStreamError = class extends Error {
9745
- constructor(message, code) {
9746
- super(message);
9747
- this.name = "ProviderStreamError";
9748
- this.code = code;
9749
- }
9750
- };
9751
10244
  function extractProviderStreamError(chunk) {
9752
10245
  if (!chunk || typeof chunk !== "object") return null;
9753
10246
  const errField = chunk.error;
@@ -10128,6 +10621,7 @@ async function runToolLoop(options) {
10128
10621
  thinking: redactor.deAnonymize(acc.thinking)
10129
10622
  }) : strategy.buildFinalResponse(acc);
10130
10623
  const finalContentText = (acc) => redactor ? redactor.deAnonymize(acc.content) : acc.content;
10624
+ let streamingAccumulator = null;
10131
10625
  try {
10132
10626
  let sseError = null;
10133
10627
  let apiTools = toolsToApiFormat(tools, resolved);
@@ -10279,6 +10773,7 @@ async function runToolLoop(options) {
10279
10773
  }
10280
10774
  });
10281
10775
  accumulator = createStreamAccumulator(model || void 0);
10776
+ streamingAccumulator = accumulator;
10282
10777
  contentSmoother = new StreamSmoother((text16) => {
10283
10778
  if (emitData) emitData(text16);
10284
10779
  }, smoothing);
@@ -10789,6 +11284,7 @@ Executing tool: ${toolInfo}
10789
11284
  }
10790
11285
  });
10791
11286
  currentAccumulator = createStreamAccumulator(model || void 0);
11287
+ streamingAccumulator = currentAccumulator;
10792
11288
  contContentSmoother = new StreamSmoother((text16) => {
10793
11289
  if (emitData) emitData(text16);
10794
11290
  }, smoothing);
@@ -10986,7 +11482,7 @@ Executing tool: ${toolInfo}
10986
11482
  const statusCode = err instanceof Error && "statusCode" in err ? err.statusCode : void 0;
10987
11483
  const connectionLost = !(err instanceof ProviderStreamError) && !(err instanceof SseError);
10988
11484
  return {
10989
- data: null,
11485
+ data: connectionLost && streamingAccumulator ? buildResponseFinal(streamingAccumulator) : null,
10990
11486
  error: errorMsg,
10991
11487
  statusCode,
10992
11488
  ...connectionLost ? { connectionLost: true } : {}
@@ -11487,21 +11983,21 @@ function contextFields(context) {
11487
11983
  );
11488
11984
  }
11489
11985
  function conversationContext(data) {
11490
- const entries = Object.entries(data).filter(([field10]) => field10.startsWith(CONTEXT_FIELD_PREFIX)).map(([field10, value]) => [field10.slice(CONTEXT_FIELD_PREFIX.length), value]);
11491
- return entries.length > 0 ? plain(Object.fromEntries(entries)) : void 0;
11986
+ const entries2 = Object.entries(data).filter(([field10]) => field10.startsWith(CONTEXT_FIELD_PREFIX)).map(([field10, value]) => [field10.slice(CONTEXT_FIELD_PREFIX.length), value]);
11987
+ return entries2.length > 0 ? plain(Object.fromEntries(entries2)) : void 0;
11492
11988
  }
11493
- function toConversation(record2) {
11494
- const pinnedAt = number(record2.data.pinnedAt);
11495
- const projectId = text3(record2.data.projectId);
11496
- const context = conversationContext(record2.data);
11989
+ function toConversation(record3) {
11990
+ const pinnedAt = number(record3.data.pinnedAt);
11991
+ const projectId = text3(record3.data.projectId);
11992
+ const context = conversationContext(record3.data);
11497
11993
  return {
11498
- uniqueId: record2.id,
11499
- conversationId: record2.id,
11500
- title: text3(record2.data.title) ?? "",
11994
+ uniqueId: record3.id,
11995
+ conversationId: record3.id,
11996
+ title: text3(record3.data.title) ?? "",
11501
11997
  ...projectId ? { projectId } : {},
11502
- createdAt: new Date(record2.createdAt),
11503
- updatedAt: new Date(record2.updatedAt),
11504
- isDeleted: record2.isDeleted,
11998
+ createdAt: new Date(record3.createdAt),
11999
+ updatedAt: new Date(record3.updatedAt),
12000
+ isDeleted: record3.isDeleted,
11505
12001
  pinnedAt: pinnedAt ? new Date(pinnedAt) : null,
11506
12002
  ...context ? { context } : {}
11507
12003
  };
@@ -11523,21 +12019,21 @@ function messageData(options) {
11523
12019
  ...anuma ? { anuma } : {}
11524
12020
  });
11525
12021
  }
11526
- function toMessage(record2) {
11527
- const { chunkOffsets: _offsets, truncated: _truncated, anuma: rawAnuma, ...fields } = record2.data;
12022
+ function toMessage(record3) {
12023
+ const { chunkOffsets: _offsets, truncated: _truncated, anuma: rawAnuma, ...fields } = record3.data;
11528
12024
  const anuma = readAnumaTurn(rawAnuma);
11529
12025
  return {
11530
12026
  ...anuma ? { anuma } : {},
11531
12027
  ...fields,
11532
- uniqueId: record2.id,
11533
- messageId: record2.sortKey,
11534
- conversationId: record2.conversationId,
11535
- createdAt: new Date(record2.createdAt),
11536
- updatedAt: new Date(record2.updatedAt)
12028
+ uniqueId: record3.id,
12029
+ messageId: record3.sortKey,
12030
+ conversationId: record3.conversationId,
12031
+ createdAt: new Date(record3.createdAt),
12032
+ updatedAt: new Date(record3.updatedAt)
11537
12033
  };
11538
12034
  }
11539
- function chunkOffsets(record2) {
11540
- const offsets = record2.data.chunkOffsets;
12035
+ function chunkOffsets(record3) {
12036
+ const offsets = record3.data.chunkOffsets;
11541
12037
  return Array.isArray(offsets) ? offsets : void 0;
11542
12038
  }
11543
12039
  function toSkeletons(records) {
@@ -11558,15 +12054,15 @@ function toSkeletons(records) {
11558
12054
  };
11559
12055
  });
11560
12056
  }
11561
- function toSummary(record2) {
12057
+ function toSummary(record3) {
11562
12058
  return {
11563
- uniqueId: record2.id,
11564
- conversationId: record2.id,
11565
- summary: text3(record2.data.summary) ?? "",
11566
- summarizedUpTo: text3(record2.data.summarizedUpTo) ?? "",
11567
- tokenCount: number(record2.data.tokenCount) ?? 0,
11568
- createdAt: new Date(record2.createdAt),
11569
- updatedAt: new Date(record2.updatedAt)
12059
+ uniqueId: record3.id,
12060
+ conversationId: record3.id,
12061
+ summary: text3(record3.data.summary) ?? "",
12062
+ summarizedUpTo: text3(record3.data.summarizedUpTo) ?? "",
12063
+ tokenCount: number(record3.data.tokenCount) ?? 0,
12064
+ createdAt: new Date(record3.createdAt),
12065
+ updatedAt: new Date(record3.updatedAt)
11570
12066
  };
11571
12067
  }
11572
12068
  function links(data) {
@@ -11592,10 +12088,10 @@ function applyLinkOps(data, ops) {
11592
12088
  }
11593
12089
  return plain({ links: current });
11594
12090
  }
11595
- function toLinks(record2) {
11596
- return links(record2.data).map((l) => ({
11597
- uniqueId: `${record2.id}:${l.memoryId}`,
11598
- conversationId: record2.id,
12091
+ function toLinks(record3) {
12092
+ return links(record3.data).map((l) => ({
12093
+ uniqueId: `${record3.id}:${l.memoryId}`,
12094
+ conversationId: record3.id,
11599
12095
  memoryId: l.memoryId,
11600
12096
  score: l.score,
11601
12097
  createdAt: new Date(l.createdAt)
@@ -11604,24 +12100,24 @@ function toLinks(record2) {
11604
12100
  function bytes(value) {
11605
12101
  return new TextEncoder().encode(JSON.stringify(value)).length;
11606
12102
  }
11607
- function fitRecord(record2) {
11608
- if (record2.kind !== "message" || bytes(record2) <= recordBudgetBytes) return record2;
11609
- const data = { ...record2.data };
12103
+ function fitRecord(record3) {
12104
+ if (record3.kind !== "message" || bytes(record3) <= recordBudgetBytes) return record3;
12105
+ const data = { ...record3.data };
11610
12106
  const truncated = [];
11611
12107
  for (const field10 of droppable) {
11612
- if (bytes({ ...record2, data }) <= recordBudgetBytes) break;
12108
+ if (bytes({ ...record3, data }) <= recordBudgetBytes) break;
11613
12109
  if (data[field10] === void 0) continue;
11614
12110
  delete data[field10];
11615
12111
  truncated.push(field10);
11616
12112
  }
11617
12113
  const content = text3(data.content) ?? "";
11618
- const over = bytes({ ...record2, data }) - recordBudgetBytes;
12114
+ const over = bytes({ ...record3, data }) - recordBudgetBytes;
11619
12115
  if (over > 0) {
11620
12116
  const encoded = new TextEncoder().encode(content);
11621
12117
  data.content = new TextDecoder().decode(encoded.slice(0, Math.max(0, encoded.length - over - 64))).replace(/�$/, "");
11622
12118
  truncated.push("content");
11623
12119
  }
11624
- return { ...record2, data: { ...data, truncated } };
12120
+ return { ...record3, data: { ...data, truncated } };
11625
12121
  }
11626
12122
  function acceptedVector(vector2) {
11627
12123
  if (!vector2 || !acceptedDims.has(vector2.length)) return void 0;
@@ -11665,8 +12161,8 @@ function anumaTurnContent(bubbles) {
11665
12161
  return bubbles.join("\n\n");
11666
12162
  }
11667
12163
  function anumaLastReadSortKey(conversation) {
11668
- const record2 = conversation && "record" in conversation ? conversation.record : conversation;
11669
- const state = record2?.data.anuma;
12164
+ const record3 = conversation && "record" in conversation ? conversation.record : conversation;
12165
+ const state = record3?.data.anuma;
11670
12166
  if (!isObject(state)) return 0;
11671
12167
  const sortKey = state.lastReadSortKey;
11672
12168
  return Number.isSafeInteger(sortKey) && sortKey > 0 ? sortKey : 0;
@@ -11719,19 +12215,19 @@ async function markAnumaRead(store, sortKey, options = {}) {
11719
12215
  const current = await ensureAnumaConversation(store, options);
11720
12216
  const read = anumaLastReadSortKey(current);
11721
12217
  if (sortKey <= read) return current;
11722
- const record2 = current.record;
11723
- const state = isObject(record2.data.anuma) ? record2.data.anuma : {};
11724
- const data = plain({ ...record2.data, anuma: { ...state, lastReadSortKey: sortKey } });
12218
+ const record3 = current.record;
12219
+ const state = isObject(record3.data.anuma) ? record3.data.anuma : {};
12220
+ const data = plain({ ...record3.data, anuma: { ...state, lastReadSortKey: sortKey } });
11725
12221
  try {
11726
12222
  const [written] = await store.putMany(
11727
12223
  [
11728
12224
  {
11729
12225
  expectedVersion: current.version,
11730
12226
  record: {
11731
- ...record2,
12227
+ ...record3,
11732
12228
  data,
11733
- sortKey: conversationSortKey(data, record2.createdAt),
11734
- updatedAt: Math.max(record2.updatedAt, now())
12229
+ sortKey: conversationSortKey(data, record3.createdAt),
12230
+ updatedAt: Math.max(record3.updatedAt, now())
11735
12231
  }
11736
12232
  }
11737
12233
  ],
@@ -11766,22 +12262,22 @@ function createSummaryContext(database, encryption = {}) {
11766
12262
  summariesCollection: database.get("conversation_summaries")
11767
12263
  };
11768
12264
  }
11769
- function modelToStored(record2, summary) {
12265
+ function modelToStored(record3, summary) {
11770
12266
  return {
11771
- uniqueId: record2.id,
11772
- conversationId: record2.conversationId,
12267
+ uniqueId: record3.id,
12268
+ conversationId: record3.conversationId,
11773
12269
  summary,
11774
- summarizedUpTo: record2.summarizedUpTo,
11775
- tokenCount: record2.tokenCount,
11776
- createdAt: record2.createdAt,
11777
- updatedAt: record2.updatedAt
12270
+ summarizedUpTo: record3.summarizedUpTo,
12271
+ tokenCount: record3.tokenCount,
12272
+ createdAt: record3.createdAt,
12273
+ updatedAt: record3.updatedAt
11778
12274
  };
11779
12275
  }
11780
12276
  async function getConversationSummaryOp(ctx, conversationId) {
11781
12277
  const results = await ctx.summariesCollection.query(Q4.where("conversation_id", conversationId)).fetch();
11782
12278
  if (results.length === 0) return null;
11783
- const record2 = results[0];
11784
- const stored2 = modelToStored(record2, record2.summary);
12279
+ const record3 = results[0];
12280
+ const stored2 = modelToStored(record3, record3.summary);
11785
12281
  if (ctx.walletAddress && isEncrypted(stored2.summary)) {
11786
12282
  if (ctx.signMessage) {
11787
12283
  try {
@@ -11800,7 +12296,7 @@ async function getConversationSummaryOp(ctx, conversationId) {
11800
12296
  ctx.embeddedWalletSigner
11801
12297
  );
11802
12298
  await ctx.database.write(async () => {
11803
- const current = await ctx.summariesCollection.query(Q4.where("id", record2.id)).fetch();
12299
+ const current = await ctx.summariesCollection.query(Q4.where("id", record3.id)).fetch();
11804
12300
  if (current[0]?.summary === stored2.summary) {
11805
12301
  await current[0].update((rec) => {
11806
12302
  rec.summary = encryptedSummary;
@@ -11815,19 +12311,19 @@ async function getConversationSummaryOp(ctx, conversationId) {
11815
12311
  }
11816
12312
  async function upsertConversationSummaryOp(ctx, conversationId, summary, summarizedUpTo, tokenCount) {
11817
12313
  const revision2 = getConversationRevision(ctx.database, conversationId);
11818
- let record2;
12314
+ let record3;
11819
12315
  const encryptedSummary = ctx.walletAddress ? await encryptField(summary, ctx.walletAddress, ctx.signMessage, ctx.embeddedWalletSigner) : summary;
11820
12316
  await ctx.database.write(async () => {
11821
12317
  assertConversationRevision(ctx.database, conversationId, revision2);
11822
12318
  const existing = await ctx.summariesCollection.query(Q4.where("conversation_id", conversationId)).fetch();
11823
12319
  if (existing.length > 0) {
11824
- record2 = await existing[0].update((rec) => {
12320
+ record3 = await existing[0].update((rec) => {
11825
12321
  rec.summary = encryptedSummary;
11826
12322
  rec.summarizedUpTo = summarizedUpTo;
11827
12323
  rec.tokenCount = tokenCount;
11828
12324
  });
11829
12325
  } else {
11830
- record2 = await ctx.summariesCollection.create((rec) => {
12326
+ record3 = await ctx.summariesCollection.create((rec) => {
11831
12327
  rec.conversationId = conversationId;
11832
12328
  rec.summary = encryptedSummary;
11833
12329
  rec.summarizedUpTo = summarizedUpTo;
@@ -11835,13 +12331,13 @@ async function upsertConversationSummaryOp(ctx, conversationId, summary, summari
11835
12331
  });
11836
12332
  }
11837
12333
  });
11838
- return modelToStored(record2, summary);
12334
+ return modelToStored(record3, summary);
11839
12335
  }
11840
12336
  async function deleteConversationSummaryOp(ctx, conversationId) {
11841
12337
  await ctx.database.write(async () => {
11842
12338
  const existing = await ctx.summariesCollection.query(Q4.where("conversation_id", conversationId)).fetch();
11843
- for (const record2 of existing) {
11844
- await record2.destroyPermanently();
12339
+ for (const record3 of existing) {
12340
+ await record3.destroyPermanently();
11845
12341
  }
11846
12342
  });
11847
12343
  }
@@ -11917,7 +12413,7 @@ function messageRecord(message) {
11917
12413
  const fitted = chunks3?.length ? fitChunks(chunks3) : void 0;
11918
12414
  const single = fitted ? void 0 : acceptedVector(vector2);
11919
12415
  const embeddings2 = fitted?.map((c) => c.vector) ?? (single ? [single] : void 0);
11920
- const record2 = fitRecord({
12416
+ const record3 = fitRecord({
11921
12417
  kind: "message",
11922
12418
  id: message.uniqueId,
11923
12419
  conversationId: message.conversationId,
@@ -11931,7 +12427,7 @@ function messageRecord(message) {
11931
12427
  }
11932
12428
  });
11933
12429
  return {
11934
- record: record2,
12430
+ record: record3,
11935
12431
  ...embeddings2 ? { embeddings: embeddings2 } : {},
11936
12432
  ...embeddings2 && message.embeddingModel ? { embeddingModel: message.embeddingModel } : {}
11937
12433
  };
@@ -12079,15 +12575,15 @@ function ref(value) {
12079
12575
  function sameMetadata(a, b) {
12080
12576
  return metadata.every((key3) => a[key3] === b[key3]);
12081
12577
  }
12082
- function wire(record2, payload) {
12578
+ function wire(record3, payload) {
12083
12579
  return {
12084
- kind: record2.kind,
12085
- id: record2.id,
12086
- conversation_id: record2.conversationId,
12087
- sort_key: record2.sortKey,
12088
- created_at: record2.createdAt,
12089
- updated_at: record2.updatedAt,
12090
- is_deleted: record2.isDeleted,
12580
+ kind: record3.kind,
12581
+ id: record3.id,
12582
+ conversation_id: record3.conversationId,
12583
+ sort_key: record3.sortKey,
12584
+ created_at: record3.createdAt,
12585
+ updated_at: record3.updatedAt,
12586
+ is_deleted: record3.isDeleted,
12091
12587
  payload
12092
12588
  };
12093
12589
  }
@@ -12144,10 +12640,10 @@ async function createRemoteChatStore(options) {
12144
12640
  serverUpdatedAt: value.server_updated_at
12145
12641
  };
12146
12642
  };
12147
- const seal = async (record2, signal) => {
12148
- if (record2.isDeleted) return "";
12643
+ const seal = async (record3, signal) => {
12644
+ if (record3.isDeleted) return "";
12149
12645
  const payload = await encrypt(
12150
- JSON.stringify({ schema: 1, account_id: accountId, key_id: keyId, record: record2 })
12646
+ JSON.stringify({ schema: 1, account_id: accountId, key_id: keyId, record: record3 })
12151
12647
  );
12152
12648
  signal?.throwIfAborted();
12153
12649
  if (!cipherPattern.test(payload) || payload.length > maxPayload) invalid();
@@ -12511,8 +13007,8 @@ var emptyMessage = {
12511
13007
  var maxPasses = 5;
12512
13008
  var verifyBatch = 1e3;
12513
13009
  var writeBatch = 25;
12514
- function key(record2) {
12515
- return `${record2.kind}/${record2.id}`;
13010
+ function key(record3) {
13011
+ return `${record3.kind}/${record3.id}`;
12516
13012
  }
12517
13013
  function sealed(value) {
12518
13014
  if (typeof value === "string") return isEncrypted(value);
@@ -12641,11 +13137,11 @@ async function missing(store, records, signal) {
12641
13137
  const out = /* @__PURE__ */ new Set();
12642
13138
  for (let i = 0; i < records.length; i += verifyBatch) {
12643
13139
  const refs = await store.verify(
12644
- records.slice(i, i + verifyBatch).map(({ record: record2 }) => ({
12645
- kind: record2.kind,
12646
- id: record2.id,
12647
- updatedAt: record2.updatedAt,
12648
- isDeleted: record2.isDeleted
13140
+ records.slice(i, i + verifyBatch).map(({ record: record3 }) => ({
13141
+ kind: record3.kind,
13142
+ id: record3.id,
13143
+ updatedAt: record3.updatedAt,
13144
+ isDeleted: record3.isDeleted
12649
13145
  })),
12650
13146
  signal
12651
13147
  );
@@ -12685,14 +13181,14 @@ async function deletedSinceUpload(store, journal, local, signal) {
12685
13181
  const live2 = (await store.getMany(gone.map(ref2), signal)).filter((s) => !s.record.isDeleted);
12686
13182
  const tombstoning = new Set(live2.map((s) => key(s.record)));
12687
13183
  await journal.drop(gone.filter((k) => !tombstoning.has(k)));
12688
- return live2.map(({ record: record2, version }) => {
12689
- const empty = emptied[record2.kind];
13184
+ return live2.map(({ record: record3, version }) => {
13185
+ const empty = emptied[record3.kind];
12690
13186
  return {
12691
13187
  record: {
12692
- ...record2,
13188
+ ...record3,
12693
13189
  isDeleted: !empty,
12694
13190
  data: empty ?? {},
12695
- updatedAt: Math.max(Date.now(), record2.updatedAt + 1)
13191
+ updatedAt: Math.max(Date.now(), record3.updatedAt + 1)
12696
13192
  },
12697
13193
  expectedVersion: version
12698
13194
  };
@@ -13041,8 +13537,8 @@ function createVaultAttachments(options) {
13041
13537
  },
13042
13538
  async read(attachmentId, signal) {
13043
13539
  if (!attachmentIdPattern2.test(attachmentId)) invalidAttachment();
13044
- const cached = await cache?.get(attachmentId).catch(() => null);
13045
- if (cached) return cached;
13540
+ const cached2 = await cache?.get(attachmentId).catch(() => null);
13541
+ if (cached2) return cached2;
13046
13542
  for (let attempt = 0; ; attempt++) {
13047
13543
  const found = await withRetry(() => store.attachments.get(attachmentId, signal), signal);
13048
13544
  if (!found?.download) return null;
@@ -13071,8 +13567,8 @@ function validRef(value) {
13071
13567
  const ref3 = value;
13072
13568
  return typeof ref3.attachmentId === "string" && attachmentIdPattern2.test(ref3.attachmentId) && typeof ref3.fileId === "string" && ref3.fileId.length > 0 && typeof ref3.name === "string" && typeof ref3.type === "string" && Number.isSafeInteger(ref3.size) && ref3.size >= 0;
13073
13569
  }
13074
- function vaultAttachmentRefs(record2) {
13075
- const refs = record2.data.vaultAttachments;
13570
+ function vaultAttachmentRefs(record3) {
13571
+ const refs = record3.data.vaultAttachments;
13076
13572
  return Array.isArray(refs) ? refs.filter(validRef) : [];
13077
13573
  }
13078
13574
  function journalKey(messageId, fileId) {
@@ -13280,14 +13776,14 @@ function sameRecord(a, b) {
13280
13776
  return a.sortKey === b.sortKey && a.isDeleted === b.isDeleted && sameJson(a.data, b.data);
13281
13777
  }
13282
13778
  function toWrite(base, patch) {
13283
- const record2 = applyPatch(base?.record, patch);
13284
- if (!record2) return void 0;
13285
- if (base && patch.embeddings === void 0 && sameRecord(base.record, record2)) return null;
13779
+ const record3 = applyPatch(base?.record, patch);
13780
+ if (!record3) return void 0;
13781
+ if (base && patch.embeddings === void 0 && sameRecord(base.record, record3)) return null;
13286
13782
  return {
13287
- record: fitRecord(record2),
13783
+ record: fitRecord(record3),
13288
13784
  expectedVersion: base?.version ?? 0,
13289
- ...patch.embeddings !== void 0 && !record2.isDeleted ? { embeddings: patch.embeddings } : {},
13290
- ...patch.embeddingModel !== void 0 && !record2.isDeleted ? { embeddingModel: patch.embeddingModel } : {}
13785
+ ...patch.embeddings !== void 0 && !record3.isDeleted ? { embeddings: patch.embeddings } : {},
13786
+ ...patch.embeddingModel !== void 0 && !record3.isDeleted ? { embeddingModel: patch.embeddingModel } : {}
13291
13787
  };
13292
13788
  }
13293
13789
  var maxWrites = 25;
@@ -13421,11 +13917,11 @@ function createVaultChatBackend(options) {
13421
13917
  for (const listener of [...listeners]) listener(event);
13422
13918
  };
13423
13919
  const view = (k) => {
13424
- let record2 = confirmed.get(k)?.record;
13920
+ let record3 = confirmed.get(k)?.record;
13425
13921
  for (const patch of [inflight.get(k), pending.get(k)]) {
13426
- if (patch) record2 = applyPatch(record2, patch) ?? record2;
13922
+ if (patch) record3 = applyPatch(record3, patch) ?? record3;
13427
13923
  }
13428
- return record2;
13924
+ return record3;
13429
13925
  };
13430
13926
  const conversationLive = (conversationId) => {
13431
13927
  const conversation2 = view(key2("conversation", conversationId));
@@ -13436,10 +13932,10 @@ function createVaultChatBackend(options) {
13436
13932
  const out = [];
13437
13933
  for (const k of keys) {
13438
13934
  if (!k.startsWith(`${kind}/`)) continue;
13439
- const record2 = view(k);
13440
- if (!record2 || record2.isDeleted && !includeDeleted) continue;
13441
- if (conversationId !== void 0 && record2.conversationId !== conversationId) continue;
13442
- out.push(record2);
13935
+ const record3 = view(k);
13936
+ if (!record3 || record3.isDeleted && !includeDeleted) continue;
13937
+ if (conversationId !== void 0 && record3.conversationId !== conversationId) continue;
13938
+ out.push(record3);
13443
13939
  }
13444
13940
  return out;
13445
13941
  };
@@ -13450,7 +13946,7 @@ function createVaultChatBackend(options) {
13450
13946
  account: cache.account,
13451
13947
  cursor: cursor ?? "",
13452
13948
  records: [...confirmed.values()].filter(
13453
- ({ record: record2 }) => record2.kind === "conversation" || record2.kind !== "project" && keep.has(record2.conversationId)
13949
+ ({ record: record3 }) => record3.kind === "conversation" || record3.kind !== "project" && keep.has(record3.conversationId)
13454
13950
  ),
13455
13951
  threads: kept,
13456
13952
  absent: [...checked].filter((k) => {
@@ -13764,17 +14260,17 @@ function createVaultChatBackend(options) {
13764
14260
  return loading;
13765
14261
  };
13766
14262
  const applyRemote = (snapshot) => {
13767
- const { record: record2 } = snapshot;
13768
- const k = key2(record2.kind, record2.id);
13769
- if (record2.kind === "conversation") {
14263
+ const { record: record3 } = snapshot;
14264
+ const k = key2(record3.kind, record3.id);
14265
+ if (record3.kind === "conversation") {
13770
14266
  if (!merge(snapshot)) return;
13771
- if (record2.isDeleted) forgetConversation(record2.id);
13772
- announce([record2]);
14267
+ if (record3.isDeleted) forgetConversation(record3.id);
14268
+ announce([record3]);
13773
14269
  return;
13774
14270
  }
13775
- if (record2.kind === "project") return;
13776
- const relevant2 = threads.has(record2.conversationId) || confirmed.has(k) || checked.has(k) && record2.kind !== "message";
13777
- if (relevant2 && merge(snapshot)) announce([record2]);
14271
+ if (record3.kind === "project") return;
14272
+ const relevant2 = threads.has(record3.conversationId) || confirmed.has(k) || checked.has(k) && record3.kind !== "message";
14273
+ if (relevant2 && merge(snapshot)) announce([record3]);
13778
14274
  };
13779
14275
  const listIndex = async (source) => {
13780
14276
  const index = [];
@@ -13925,8 +14421,8 @@ function createVaultChatBackend(options) {
13925
14421
  checked.add(k);
13926
14422
  if (found) merge(found);
13927
14423
  }
13928
- const record2 = view(k);
13929
- return record2 && !record2.isDeleted && conversationLive(record2.conversationId) ? record2 : void 0;
14424
+ const record3 = view(k);
14425
+ return record3 && !record3.isDeleted && conversationLive(record3.conversationId) ? record3 : void 0;
13930
14426
  };
13931
14427
  const child = async (kind, conversationId) => {
13932
14428
  await available2();
@@ -13963,19 +14459,19 @@ function createVaultChatBackend(options) {
13963
14459
  await backend.deleteSummary(conversationId);
13964
14460
  };
13965
14461
  const storedMessage = async (uniqueId) => {
13966
- const record2 = await message(uniqueId);
13967
- return record2 ? toMessage(record2) : null;
14462
+ const record3 = await message(uniqueId);
14463
+ return record3 ? toMessage(record3) : null;
13968
14464
  };
13969
14465
  const patchMessage = async (uniqueId, patch) => {
13970
- const record2 = await message(uniqueId);
13971
- if (!record2) return null;
14466
+ const record3 = await message(uniqueId);
14467
+ if (!record3) return null;
13972
14468
  await enqueue({
13973
14469
  kind: "message",
13974
14470
  id: uniqueId,
13975
- conversationId: record2.conversationId,
14471
+ conversationId: record3.conversationId,
13976
14472
  ...patch
13977
14473
  });
13978
- emit({ type: "messages", conversationId: record2.conversationId, origin: "local" });
14474
+ emit({ type: "messages", conversationId: record3.conversationId, origin: "local" });
13979
14475
  const updated = view(key2("message", uniqueId));
13980
14476
  return updated && !updated.isDeleted ? toMessage(updated) : null;
13981
14477
  };
@@ -14000,12 +14496,12 @@ function createVaultChatBackend(options) {
14000
14496
  });
14001
14497
  const backend = {
14002
14498
  async getConversation(conversationId) {
14003
- const record2 = await conversation(conversationId);
14004
- return record2 && !record2.isDeleted ? toConversation(record2) : null;
14499
+ const record3 = await conversation(conversationId);
14500
+ return record3 && !record3.isDeleted ? toConversation(record3) : null;
14005
14501
  },
14006
14502
  async getConversations(query) {
14007
14503
  await available2();
14008
- return all("conversation").filter((record2) => record2.id !== ANUMA_CONVERSATION_ID).map(toConversation).filter(
14504
+ return all("conversation").filter((record3) => record3.id !== ANUMA_CONVERSATION_ID).map(toConversation).filter(
14009
14505
  (c) => query?.projectId === void 0 || (query.projectId === null ? !c.projectId : c.projectId === query.projectId)
14010
14506
  ).sort((a, b) => b.createdAt.getTime() - a.createdAt.getTime());
14011
14507
  },
@@ -14044,13 +14540,13 @@ function createVaultChatBackend(options) {
14044
14540
  async updateConversationContext(conversationId, context) {
14045
14541
  const set = contextFields(context);
14046
14542
  if (Object.keys(set).length > 0) return updateConversation(conversationId, set);
14047
- const record2 = await conversation(conversationId);
14048
- return !!record2 && !record2.isDeleted;
14543
+ const record3 = await conversation(conversationId);
14544
+ return !!record3 && !record3.isDeleted;
14049
14545
  },
14050
14546
  async deleteConversation(conversationId) {
14051
14547
  if (conversationId === ANUMA_CONVERSATION_ID) return false;
14052
- const record2 = await conversation(conversationId);
14053
- if (!record2 || record2.isDeleted) return false;
14548
+ const record3 = await conversation(conversationId);
14549
+ if (!record3 || record3.isDeleted) return false;
14054
14550
  for (const [k, patch] of pending)
14055
14551
  if (patch.conversationId === conversationId) pending.delete(k);
14056
14552
  await enqueue({ kind: "conversation", id: conversationId, conversationId: "", delete: true });
@@ -14086,8 +14582,8 @@ function createVaultChatBackend(options) {
14086
14582
  const unknown = ids.map((id2) => key2("message", id2)).filter((k) => !view(k) && !checked.has(k));
14087
14583
  await refresh(unknown);
14088
14584
  return ids.flatMap((id2) => {
14089
- const record2 = view(key2("message", id2));
14090
- return record2 && !record2.isDeleted && conversationLive(record2.conversationId) ? [toMessage(record2)] : [];
14585
+ const record3 = view(key2("message", id2));
14586
+ return record3 && !record3.isDeleted && conversationLive(record3.conversationId) ? [toMessage(record3)] : [];
14091
14587
  });
14092
14588
  },
14093
14589
  async getMessageCount(conversationId) {
@@ -14095,8 +14591,8 @@ function createVaultChatBackend(options) {
14095
14591
  },
14096
14592
  async getToolCallEventIds(conversationId) {
14097
14593
  const ids = /* @__PURE__ */ new Set();
14098
- for (const record2 of await thread(conversationId)) {
14099
- const events = record2.data.toolCallEvents;
14594
+ for (const record3 of await thread(conversationId)) {
14595
+ const events = record3.data.toolCallEvents;
14100
14596
  if (!Array.isArray(events)) continue;
14101
14597
  for (const event of events)
14102
14598
  if (event && typeof event === "object" && !Array.isArray(event) && typeof event.id === "string")
@@ -14189,21 +14685,21 @@ function createVaultChatBackend(options) {
14189
14685
  },
14190
14686
  async clearMessages(conversationId) {
14191
14687
  await invalidateSummary(conversationId);
14192
- for (const record2 of await thread(conversationId))
14193
- await enqueue({ kind: "message", id: record2.id, conversationId, delete: true });
14688
+ for (const record3 of await thread(conversationId))
14689
+ await enqueue({ kind: "message", id: record3.id, conversationId, delete: true });
14194
14690
  emit({ type: "messages", conversationId, origin: "local" });
14195
14691
  },
14196
14692
  async deleteMessage(uniqueId) {
14197
- const record2 = await message(uniqueId);
14198
- if (!record2) return null;
14199
- await invalidateSummary(record2.conversationId, record2);
14693
+ const record3 = await message(uniqueId);
14694
+ if (!record3) return null;
14695
+ await invalidateSummary(record3.conversationId, record3);
14200
14696
  await enqueue({
14201
14697
  kind: "message",
14202
14698
  id: uniqueId,
14203
- conversationId: record2.conversationId,
14699
+ conversationId: record3.conversationId,
14204
14700
  delete: true
14205
14701
  });
14206
- emit({ type: "messages", conversationId: record2.conversationId, origin: "local" });
14702
+ emit({ type: "messages", conversationId: record3.conversationId, origin: "local" });
14207
14703
  return uniqueId;
14208
14704
  },
14209
14705
  observeMessages(conversationId) {
@@ -14216,13 +14712,13 @@ function createVaultChatBackend(options) {
14216
14712
  await available2();
14217
14713
  if (query?.conversationId) await loadThread(query.conversationId);
14218
14714
  const files = [];
14219
- for (const record2 of all("message", query?.conversationId)) {
14220
- if (!conversationLive(record2.conversationId)) continue;
14221
- const stored2 = toMessage(record2);
14715
+ for (const record3 of all("message", query?.conversationId)) {
14716
+ if (!conversationLive(record3.conversationId)) continue;
14717
+ const stored2 = toMessage(record3);
14222
14718
  for (const file of stored2.files ?? [])
14223
14719
  files.push({
14224
14720
  ...file,
14225
- conversationId: record2.conversationId,
14721
+ conversationId: record3.conversationId,
14226
14722
  createdAt: stored2.createdAt,
14227
14723
  messageRole: stored2.role
14228
14724
  });
@@ -14261,8 +14757,8 @@ function createVaultChatBackend(options) {
14261
14757
  return results;
14262
14758
  },
14263
14759
  async getSummary(conversationId) {
14264
- const record2 = await child("summary", conversationId);
14265
- return record2 && !record2.isDeleted && record2.data.summarizedUpTo ? toSummary(record2) : null;
14760
+ const record3 = await child("summary", conversationId);
14761
+ return record3 && !record3.isDeleted && record3.data.summarizedUpTo ? toSummary(record3) : null;
14266
14762
  },
14267
14763
  async upsertSummary(conversationId, summary, summarizedUpTo, tokenCount) {
14268
14764
  await child("summary", conversationId);
@@ -14278,8 +14774,8 @@ function createVaultChatBackend(options) {
14278
14774
  return toSummary(view(key2("summary", conversationId)));
14279
14775
  },
14280
14776
  async deleteSummary(conversationId) {
14281
- const record2 = await child("summary", conversationId);
14282
- if (!record2 || record2.isDeleted) return;
14777
+ const record3 = await child("summary", conversationId);
14778
+ if (!record3 || record3.isDeleted) return;
14283
14779
  await enqueue({
14284
14780
  kind: "summary",
14285
14781
  id: conversationId,
@@ -14289,8 +14785,8 @@ function createVaultChatBackend(options) {
14289
14785
  emit({ type: "summary", conversationId, origin: "local" });
14290
14786
  },
14291
14787
  async getMemoryLinks(conversationId) {
14292
- const record2 = await child("memory_links", conversationId);
14293
- return record2 && !record2.isDeleted ? toLinks(record2) : [];
14788
+ const record3 = await child("memory_links", conversationId);
14789
+ return record3 && !record3.isDeleted ? toLinks(record3) : [];
14294
14790
  },
14295
14791
  async addMemoryLinks(conversationId, items) {
14296
14792
  if (!conversationId || items.length === 0) return;
@@ -14305,8 +14801,8 @@ function createVaultChatBackend(options) {
14305
14801
  emit({ type: "links", conversationId, origin: "local" });
14306
14802
  },
14307
14803
  async clearMemoryLinks(conversationId) {
14308
- const record2 = await child("memory_links", conversationId);
14309
- if (!record2 || record2.isDeleted) return;
14804
+ const record3 = await child("memory_links", conversationId);
14805
+ if (!record3 || record3.isDeleted) return;
14310
14806
  await enqueue({
14311
14807
  kind: "memory_links",
14312
14808
  id: conversationId,
@@ -14324,8 +14820,8 @@ function createVaultChatBackend(options) {
14324
14820
  async importChats(chats) {
14325
14821
  await ready();
14326
14822
  const seen = /* @__PURE__ */ new Set();
14327
- const unique = (items) => items.filter(({ record: record2 }) => {
14328
- const k = key2(record2.kind, record2.id);
14823
+ const unique = (items) => items.filter(({ record: record3 }) => {
14824
+ const k = key2(record3.kind, record3.id);
14329
14825
  if (seen.has(k)) return false;
14330
14826
  seen.add(k);
14331
14827
  return true;
@@ -14349,15 +14845,15 @@ function createVaultChatBackend(options) {
14349
14845
  for (const batch of batches(messages))
14350
14846
  messageCount += await connected.importRecords(batch);
14351
14847
  } finally {
14352
- for (const { record: record2 } of messages) checked.delete(key2("message", record2.id));
14353
- await refresh(conversations.map(({ record: record2 }) => key2("conversation", record2.id))).catch(
14848
+ for (const { record: record3 } of messages) checked.delete(key2("message", record3.id));
14849
+ await refresh(conversations.map(({ record: record3 }) => key2("conversation", record3.id))).catch(
14354
14850
  () => void 0
14355
14851
  );
14356
- for (const { record: record2 } of conversations) threads.delete(record2.id);
14852
+ for (const { record: record3 } of conversations) threads.delete(record3.id);
14357
14853
  channel?.postMessage("changed");
14358
14854
  emit({ type: "conversations", origin: "local" });
14359
- for (const { record: record2 } of conversations)
14360
- emit({ type: "messages", conversationId: record2.id, origin: "local" });
14855
+ for (const { record: record3 } of conversations)
14856
+ emit({ type: "messages", conversationId: record3.id, origin: "local" });
14361
14857
  }
14362
14858
  return { conversations: conversationCount, messages: messageCount };
14363
14859
  },
@@ -14376,8 +14872,8 @@ function createVaultChatBackend(options) {
14376
14872
  }
14377
14873
  };
14378
14874
  const updateConversation = async (conversationId, set) => {
14379
- const record2 = await conversation(conversationId);
14380
- if (!record2 || record2.isDeleted) return false;
14875
+ const record3 = await conversation(conversationId);
14876
+ if (!record3 || record3.isDeleted) return false;
14381
14877
  await enqueue({ kind: "conversation", id: conversationId, conversationId: "", set });
14382
14878
  emit({ type: "conversations", origin: "local" });
14383
14879
  return true;
@@ -14553,10 +15049,10 @@ async function decryptConversationTitle(encryptedTitle, address) {
14553
15049
  );
14554
15050
  }
14555
15051
  const cacheKey = buildCacheKey(address, encryptedTitle);
14556
- const cached = titleCache.get(cacheKey);
14557
- if (cached !== void 0) {
14558
- touchEntry(cacheKey, cached);
14559
- return cached;
15052
+ const cached2 = titleCache.get(cacheKey);
15053
+ if (cached2 !== void 0) {
15054
+ touchEntry(cacheKey, cached2);
15055
+ return cached2;
14560
15056
  }
14561
15057
  const inFlight = pendingDecrypts.get(cacheKey);
14562
15058
  if (inFlight) return inFlight;
@@ -14815,25 +15311,25 @@ async function upsertEntitiesInWrite(ctx, entities) {
14815
15311
  const kindBackfills = existing.filter((e) => {
14816
15312
  const incoming = kindByName.get(e.canonicalName);
14817
15313
  return incoming !== void 0 && (e.kind === null || e.kind === void 0 || e.kind === "");
14818
- }).map((record2) => ({ record: record2, kind: kindByName.get(record2.canonicalName) }));
15314
+ }).map((record3) => ({ record: record3, kind: kindByName.get(record3.canonicalName) }));
14819
15315
  const missing2 = unique.filter((n) => !existingNames.has(n));
14820
15316
  const created = missing2.map(
14821
- (name) => ctx.entityCollection.prepareCreate((record2) => {
14822
- record2._setRaw("canonical_name", name);
15317
+ (name) => ctx.entityCollection.prepareCreate((record3) => {
15318
+ record3._setRaw("canonical_name", name);
14823
15319
  const kind = kindByName.get(name);
14824
- if (kind !== void 0) record2._setRaw("kind", kind);
15320
+ if (kind !== void 0) record3._setRaw("kind", kind);
14825
15321
  })
14826
15322
  );
14827
15323
  for (const e of existing) out.set(e.canonicalName, entityToStored(e));
14828
- for (const record2 of created) out.set(record2.canonicalName, entityToStored(record2));
14829
- for (const { record: record2, kind } of kindBackfills) {
14830
- out.set(record2.canonicalName, { ...entityToStored(record2), kind });
15324
+ for (const record3 of created) out.set(record3.canonicalName, entityToStored(record3));
15325
+ for (const { record: record3, kind } of kindBackfills) {
15326
+ out.set(record3.canonicalName, { ...entityToStored(record3), kind });
14831
15327
  }
14832
15328
  return { entities: out, operations: created, kindBackfills };
14833
15329
  }
14834
15330
  function prepareKindBackfills(backfills) {
14835
15331
  return backfills.map(
14836
- ({ record: record2, kind }) => record2.prepareUpdate((r) => {
15332
+ ({ record: record3, kind }) => record3.prepareUpdate((r) => {
14837
15333
  r._setRaw("kind", kind);
14838
15334
  })
14839
15335
  );
@@ -14961,10 +15457,10 @@ async function linkMemoryEntitiesOp(ctx, memoryId, entityInputs, options) {
14961
15457
  return;
14962
15458
  }
14963
15459
  const linkOps = toCreate.map(
14964
- (e) => ctx.memoryEntityCollection.prepareCreate((record2) => {
14965
- record2._setRaw("memory_id", memoryId);
14966
- record2._setRaw("entity_id", e.uniqueId);
14967
- if (userId !== void 0) record2._setRaw("user_id", userId);
15460
+ (e) => ctx.memoryEntityCollection.prepareCreate((record3) => {
15461
+ record3._setRaw("memory_id", memoryId);
15462
+ record3._setRaw("entity_id", e.uniqueId);
15463
+ if (userId !== void 0) record3._setRaw("user_id", userId);
14968
15464
  })
14969
15465
  );
14970
15466
  await ctx.database.batch(
@@ -15034,10 +15530,10 @@ async function replaceMemoryEntities(ctx, memoryId, entityInputs, options) {
15034
15530
  ...entityOps,
15035
15531
  ...prepareKindBackfills(kindBackfills),
15036
15532
  ...toCreate.map(
15037
- (e) => ctx.memoryEntityCollection.prepareCreate((record2) => {
15038
- record2._setRaw("memory_id", memoryId);
15039
- record2._setRaw("entity_id", e.uniqueId);
15040
- if (userId !== void 0) record2._setRaw("user_id", userId);
15533
+ (e) => ctx.memoryEntityCollection.prepareCreate((record3) => {
15534
+ record3._setRaw("memory_id", memoryId);
15535
+ record3._setRaw("entity_id", e.uniqueId);
15536
+ if (userId !== void 0) record3._setRaw("user_id", userId);
15041
15537
  })
15042
15538
  ),
15043
15539
  ...toDestroy.map((l) => l.prepareDestroyPermanently()),
@@ -16371,9 +16867,9 @@ var DatabaseManager = class {
16371
16867
  */
16372
16868
  getDatabase(walletAddress) {
16373
16869
  const dbName = this.getDbName(walletAddress);
16374
- const cached = this.databases.get(dbName);
16375
- if (cached) {
16376
- return cached;
16870
+ const cached2 = this.databases.get(dbName);
16871
+ if (cached2) {
16872
+ return cached2;
16377
16873
  }
16378
16874
  const needsMigration = this.handleSchemaMigration(walletAddress);
16379
16875
  if (needsMigration) {
@@ -17508,8 +18004,8 @@ function visibilityConditions(requested) {
17508
18004
  if (excluded.length === 0) return [];
17509
18005
  return [Q9.or(Q9.where("visibility", null), Q9.where("visibility", Q9.notIn(excluded)))];
17510
18006
  }
17511
- function isKinded(record2) {
17512
- return record2.kind !== null && record2.kind !== void 0;
18007
+ function isKinded(record3) {
18008
+ return record3.kind !== null && record3.kind !== void 0;
17513
18009
  }
17514
18010
  async function assertCanWrite2(ctx) {
17515
18011
  if (ctx.canWrite && !await ctx.canWrite()) {
@@ -17563,8 +18059,8 @@ function levelConditions(requested) {
17563
18059
  }
17564
18060
  return [byLevel];
17565
18061
  }
17566
- function isOwnedByCtxUser(ctx, record2) {
17567
- return ctx.userId === void 0 || record2.userId === ctx.userId;
18062
+ function isOwnedByCtxUser(ctx, record3) {
18063
+ return ctx.userId === void 0 || record3.userId === ctx.userId;
17568
18064
  }
17569
18065
  function baseVaultConditions(ctx, options) {
17570
18066
  return [
@@ -17647,43 +18143,43 @@ async function vaultMemoryToStored(memory, walletAddress, signMessage, embeddedW
17647
18143
  }
17648
18144
  return raw;
17649
18145
  }
17650
- function populateNewVaultMemory(record2, ctx, opts, encryptedContent, encryptedKindValue) {
18146
+ function populateNewVaultMemory(record3, ctx, opts, encryptedContent, encryptedKindValue) {
17651
18147
  const { level, scope } = resolveCreateLevel(opts);
17652
- record2._setRaw("content", encryptedContent);
17653
- record2._setRaw("scope", scope);
17654
- record2._setRaw("level", level);
17655
- record2._setRaw("kind", opts.kind ?? null);
17656
- record2._setRaw("kind_value", encryptedKindValue ?? null);
17657
- record2._setRaw("folder_id", opts.folderId ?? null);
17658
- record2._setRaw("user_id", ctx.userId ?? null);
17659
- record2._setRaw("is_deleted", false);
18148
+ record3._setRaw("content", encryptedContent);
18149
+ record3._setRaw("scope", scope);
18150
+ record3._setRaw("level", level);
18151
+ record3._setRaw("kind", opts.kind ?? null);
18152
+ record3._setRaw("kind_value", encryptedKindValue ?? null);
18153
+ record3._setRaw("folder_id", opts.folderId ?? null);
18154
+ record3._setRaw("user_id", ctx.userId ?? null);
18155
+ record3._setRaw("is_deleted", false);
17660
18156
  if (opts.embedding !== void 0) {
17661
- record2._setRaw("embedding", opts.embedding);
17662
- record2._setRaw("embedding_model", opts.embeddingModel ?? null);
18157
+ record3._setRaw("embedding", opts.embedding);
18158
+ record3._setRaw("embedding_model", opts.embeddingModel ?? null);
17663
18159
  }
17664
18160
  if (opts.sourceChunkIds !== void 0) {
17665
- record2._setRaw("source_chunk_ids", serializeSourceChunkIds(opts.sourceChunkIds));
18161
+ record3._setRaw("source_chunk_ids", serializeSourceChunkIds(opts.sourceChunkIds));
17666
18162
  }
17667
- record2._setRaw("proof_count", opts.proofCount ?? 1);
17668
- record2._setRaw("source", opts.source ?? "manual");
18163
+ record3._setRaw("proof_count", opts.proofCount ?? 1);
18164
+ record3._setRaw("source", opts.source ?? "manual");
17669
18165
  if (opts.eventTime) {
17670
- record2._setRaw("event_time_start", opts.eventTime.start ?? null);
17671
- record2._setRaw("event_time_end", opts.eventTime.end ?? null);
17672
- record2._setRaw("event_time_kind", opts.eventTime.kind ?? null);
18166
+ record3._setRaw("event_time_start", opts.eventTime.start ?? null);
18167
+ record3._setRaw("event_time_end", opts.eventTime.end ?? null);
18168
+ record3._setRaw("event_time_kind", opts.eventTime.kind ?? null);
17673
18169
  }
17674
18170
  if (opts.factType !== void 0) {
17675
- record2._setRaw("fact_type", opts.factType);
18171
+ record3._setRaw("fact_type", opts.factType);
17676
18172
  }
17677
18173
  if (opts.trustTier !== void 0) {
17678
- record2._setRaw("trust_tier", normalizeTrustTier(opts.trustTier));
18174
+ record3._setRaw("trust_tier", normalizeTrustTier(opts.trustTier));
17679
18175
  }
17680
- record2._setRaw("visibility", opts.visibility ?? "private");
17681
- record2._setRaw(
18176
+ record3._setRaw("visibility", opts.visibility ?? "private");
18177
+ record3._setRaw(
17682
18178
  "published_at",
17683
18179
  opts.visibility && opts.visibility !== "private" ? opts.publishedAt ?? Date.now() : null
17684
18180
  );
17685
18181
  if (opts.geohash !== void 0) {
17686
- record2._setRaw("geohash", opts.geohash);
18182
+ record3._setRaw("geohash", opts.geohash);
17687
18183
  }
17688
18184
  }
17689
18185
  async function createVaultMemoryOp(ctx, opts) {
@@ -17698,7 +18194,7 @@ async function createVaultMemoryOp(ctx, opts) {
17698
18194
  const created = await ctx.database.write(async () => {
17699
18195
  await assertCanWrite2(ctx);
17700
18196
  return ctx.vaultMemoryCollection.create(
17701
- (record2) => populateNewVaultMemory(record2, ctx, opts, encryptedContent, encryptedKindValue)
18197
+ (record3) => populateNewVaultMemory(record3, ctx, opts, encryptedContent, encryptedKindValue)
17702
18198
  );
17703
18199
  });
17704
18200
  return vaultMemoryToStored(created, ctx.walletAddress, ctx.signMessage, ctx.embeddedWalletSigner);
@@ -17725,7 +18221,7 @@ async function createSupersedingMemoryOp(ctx, opts, targetId) {
17725
18221
  if (target.isDeleted || target.supersededBy || isKinded(target) || !isOwnedByCtxUser(ctx, target))
17726
18222
  return;
17727
18223
  createdRecord = await ctx.vaultMemoryCollection.create(
17728
- (record2) => populateNewVaultMemory(record2, ctx, opts, encryptedContent, encryptedKindValue)
18224
+ (record3) => populateNewVaultMemory(record3, ctx, opts, encryptedContent, encryptedKindValue)
17729
18225
  );
17730
18226
  await target.update((r) => {
17731
18227
  r._setRaw("superseded_by", createdRecord.id);
@@ -17810,7 +18306,7 @@ async function createVaultMemoriesBatchOp(ctx, optionsArray) {
17810
18306
  await assertCanWrite2(ctx);
17811
18307
  const prepared = optionsArray.map(
17812
18308
  (opts, i) => ctx.vaultMemoryCollection.prepareCreate(
17813
- (record2) => populateNewVaultMemory(record2, ctx, opts, encryptedContents[i], encryptedKindValues[i])
18309
+ (record3) => populateNewVaultMemory(record3, ctx, opts, encryptedContents[i], encryptedKindValues[i])
17814
18310
  )
17815
18311
  );
17816
18312
  await ctx.database.batch(...prepared);
@@ -17818,16 +18314,16 @@ async function createVaultMemoriesBatchOp(ctx, optionsArray) {
17818
18314
  });
17819
18315
  return Promise.all(
17820
18316
  created.map(
17821
- (record2) => vaultMemoryToStored(record2, ctx.walletAddress, ctx.signMessage, ctx.embeddedWalletSigner)
18317
+ (record3) => vaultMemoryToStored(record3, ctx.walletAddress, ctx.signMessage, ctx.embeddedWalletSigner)
17822
18318
  )
17823
18319
  );
17824
18320
  }
17825
18321
  async function getVaultMemoryOp(ctx, id2) {
17826
18322
  try {
17827
- const record2 = await ctx.vaultMemoryCollection.find(id2);
17828
- if (record2.isDeleted || !isOwnedByCtxUser(ctx, record2)) return null;
18323
+ const record3 = await ctx.vaultMemoryCollection.find(id2);
18324
+ if (record3.isDeleted || !isOwnedByCtxUser(ctx, record3)) return null;
17829
18325
  return vaultMemoryToStored(
17830
- record2,
18326
+ record3,
17831
18327
  ctx.walletAddress,
17832
18328
  ctx.signMessage,
17833
18329
  ctx.embeddedWalletSigner
@@ -18166,29 +18662,29 @@ async function updateVaultMemoryOp(ctx, id2, opts) {
18166
18662
  ctx.embeddedWalletSigner
18167
18663
  ) : opts.content;
18168
18664
  let stale = false;
18169
- const record2 = probe;
18665
+ const record3 = probe;
18170
18666
  await ctx.database.write(async () => {
18171
18667
  await assertCanWrite2(ctx);
18172
- if (record2.isDeleted || record2.supersededBy || !isOwnedByCtxUser(ctx, record2) || opts.freeFormOnly && isKinded(record2) || opts.expectedContent !== void 0 && record2._getRaw("content") !== readStoredContent) {
18668
+ if (record3.isDeleted || record3.supersededBy || !isOwnedByCtxUser(ctx, record3) || opts.freeFormOnly && isKinded(record3) || opts.expectedContent !== void 0 && record3._getRaw("content") !== readStoredContent) {
18173
18669
  stale = true;
18174
18670
  return;
18175
18671
  }
18176
- const originalUpdatedAt = record2.updatedAt.getTime();
18177
- const nextKind = opts.kind !== void 0 ? opts.kind : record2.kind;
18178
- const nextLevel = levelAfter(record2);
18672
+ const originalUpdatedAt = record3.updatedAt.getTime();
18673
+ const nextKind = opts.kind !== void 0 ? opts.kind : record3.kind;
18674
+ const nextLevel = levelAfter(record3);
18179
18675
  assertValidKindLevel(nextKind, nextLevel);
18180
18676
  let observedSources = [];
18181
18677
  let replayedObservation = false;
18182
18678
  if (opts.observationSourceIds?.length) {
18183
18679
  try {
18184
- const parsed = JSON.parse(record2.sourceChunkIds ?? "[]");
18680
+ const parsed = JSON.parse(record3.sourceChunkIds ?? "[]");
18185
18681
  if (Array.isArray(parsed))
18186
18682
  observedSources = parsed.filter((id3) => typeof id3 === "string");
18187
18683
  } catch {
18188
18684
  }
18189
18685
  replayedObservation = opts.observationSourceIds.every((id3) => observedSources.includes(id3));
18190
18686
  }
18191
- await record2.update((r) => {
18687
+ await record3.update((r) => {
18192
18688
  if (encryptedContent !== void 0) r._setRaw("content", encryptedContent);
18193
18689
  if (opts.level !== void 0) {
18194
18690
  r._setRaw("level", nextLevel);
@@ -18255,7 +18751,7 @@ async function updateVaultMemoryOp(ctx, id2, opts) {
18255
18751
  });
18256
18752
  if (stale) return null;
18257
18753
  return vaultMemoryToStored(
18258
- record2,
18754
+ record3,
18259
18755
  ctx.walletAddress,
18260
18756
  ctx.signMessage,
18261
18757
  ctx.embeddedWalletSigner
@@ -18270,22 +18766,22 @@ async function setMemoryEntitiesOp(ctx, memoryId, entities) {
18270
18766
  if (!entityCtx) {
18271
18767
  throw new Error("setMemoryEntitiesOp requires ctx.entityCtx (entity collections)");
18272
18768
  }
18273
- let record2;
18769
+ let record3;
18274
18770
  try {
18275
- record2 = await ctx.vaultMemoryCollection.find(memoryId);
18771
+ record3 = await ctx.vaultMemoryCollection.find(memoryId);
18276
18772
  } catch {
18277
18773
  return null;
18278
18774
  }
18279
- if (record2.isDeleted || !isOwnedByCtxUser(ctx, record2)) return null;
18775
+ if (record3.isDeleted || !isOwnedByCtxUser(ctx, record3)) return null;
18280
18776
  let stale = false;
18281
- const originalUpdatedAt = record2.updatedAt.getTime();
18777
+ const originalUpdatedAt = record3.updatedAt.getTime();
18282
18778
  await ctx.database.write(async (writer) => {
18283
18779
  await assertCanWrite2(ctx);
18284
- if (record2.isDeleted || !isOwnedByCtxUser(ctx, record2)) {
18780
+ if (record3.isDeleted || !isOwnedByCtxUser(ctx, record3)) {
18285
18781
  stale = true;
18286
18782
  return;
18287
18783
  }
18288
- await record2.update((r) => {
18784
+ await record3.update((r) => {
18289
18785
  r._setRaw("topics_user_managed", true);
18290
18786
  r._setRaw("updated_at", originalUpdatedAt);
18291
18787
  });
@@ -18309,26 +18805,26 @@ async function setMemoryEntitiesOp(ctx, memoryId, entities) {
18309
18805
  );
18310
18806
  });
18311
18807
  if (stale) return null;
18312
- return vaultMemoryToStored(record2, ctx.walletAddress, ctx.signMessage, ctx.embeddedWalletSigner);
18808
+ return vaultMemoryToStored(record3, ctx.walletAddress, ctx.signMessage, ctx.embeddedWalletSigner);
18313
18809
  }
18314
18810
  async function clearMemoryTopicsOverrideOp(ctx, memoryId, options) {
18315
- let record2;
18811
+ let record3;
18316
18812
  try {
18317
- record2 = await ctx.vaultMemoryCollection.find(memoryId);
18813
+ record3 = await ctx.vaultMemoryCollection.find(memoryId);
18318
18814
  } catch {
18319
18815
  return false;
18320
18816
  }
18321
- if (record2.isDeleted || !isOwnedByCtxUser(ctx, record2)) return false;
18322
- const originalUpdatedAt = record2.updatedAt.getTime();
18817
+ if (record3.isDeleted || !isOwnedByCtxUser(ctx, record3)) return false;
18818
+ const originalUpdatedAt = record3.updatedAt.getTime();
18323
18819
  let cleared = false;
18324
18820
  await ctx.database.write(async () => {
18325
18821
  await assertCanWrite2(ctx);
18326
- if (options?.unlessTopicsRecorded && parseTopics(record2.topics) !== null) return;
18822
+ if (options?.unlessTopicsRecorded && parseTopics(record3.topics) !== null) return;
18327
18823
  cleared = true;
18328
- await record2.update((r) => {
18824
+ await record3.update((r) => {
18329
18825
  r._setRaw("topics_user_managed", false);
18330
18826
  r._setRaw("topics_extracted_version", null);
18331
- if (record2.topicsExtractedAt === null) {
18827
+ if (record3.topicsExtractedAt === null) {
18332
18828
  r._setRaw("topics_extracted_at", originalUpdatedAt);
18333
18829
  }
18334
18830
  r._setRaw("updated_at", originalUpdatedAt);
@@ -18337,23 +18833,23 @@ async function clearMemoryTopicsOverrideOp(ctx, memoryId, options) {
18337
18833
  return cleared;
18338
18834
  }
18339
18835
  async function setMemoryVisibilityOp(ctx, id2, opts) {
18340
- let record2;
18836
+ let record3;
18341
18837
  try {
18342
- record2 = await ctx.vaultMemoryCollection.find(id2);
18838
+ record3 = await ctx.vaultMemoryCollection.find(id2);
18343
18839
  } catch {
18344
18840
  return null;
18345
18841
  }
18346
- if (record2.isDeleted || !isOwnedByCtxUser(ctx, record2)) return null;
18842
+ if (record3.isDeleted || !isOwnedByCtxUser(ctx, record3)) return null;
18347
18843
  let stale = false;
18348
18844
  await ctx.database.write(async () => {
18349
18845
  await assertCanWrite2(ctx);
18350
- if (record2.isDeleted || !isOwnedByCtxUser(ctx, record2)) {
18846
+ if (record3.isDeleted || !isOwnedByCtxUser(ctx, record3)) {
18351
18847
  stale = true;
18352
18848
  return;
18353
18849
  }
18354
- const currentUpdatedAt = record2.updatedAt.getTime();
18355
- const currentPublishedAt = record2.publishedAt ?? null;
18356
- await record2.update((r) => {
18850
+ const currentUpdatedAt = record3.updatedAt.getTime();
18851
+ const currentPublishedAt = record3.publishedAt ?? null;
18852
+ await record3.update((r) => {
18357
18853
  r._setRaw("visibility", opts.visibility);
18358
18854
  if (opts.visibility === "private") {
18359
18855
  r._setRaw("published_at", null);
@@ -18367,20 +18863,20 @@ async function setMemoryVisibilityOp(ctx, id2, opts) {
18367
18863
  });
18368
18864
  });
18369
18865
  if (stale) return null;
18370
- return vaultMemoryToStored(record2, ctx.walletAddress, ctx.signMessage, ctx.embeddedWalletSigner);
18866
+ return vaultMemoryToStored(record3, ctx.walletAddress, ctx.signMessage, ctx.embeddedWalletSigner);
18371
18867
  }
18372
18868
  async function deleteVaultMemoryOp(ctx, id2) {
18373
18869
  try {
18374
- const record2 = await ctx.vaultMemoryCollection.find(id2);
18375
- if (record2.isDeleted || !isOwnedByCtxUser(ctx, record2)) return false;
18870
+ const record3 = await ctx.vaultMemoryCollection.find(id2);
18871
+ if (record3.isDeleted || !isOwnedByCtxUser(ctx, record3)) return false;
18376
18872
  let stale = false;
18377
18873
  await ctx.database.write(async () => {
18378
18874
  await assertCanWrite2(ctx);
18379
- if (record2.isDeleted || !isOwnedByCtxUser(ctx, record2)) {
18875
+ if (record3.isDeleted || !isOwnedByCtxUser(ctx, record3)) {
18380
18876
  stale = true;
18381
18877
  return;
18382
18878
  }
18383
- await record2.update((r) => {
18879
+ await record3.update((r) => {
18384
18880
  r._setRaw("is_deleted", true);
18385
18881
  });
18386
18882
  });
@@ -18399,9 +18895,9 @@ async function deleteVaultMemoryOp(ctx, id2) {
18399
18895
  async function supersedeVaultMemoryOp(ctx, id2, supersededById) {
18400
18896
  if (id2 === supersededById) return false;
18401
18897
  try {
18402
- const record2 = await ctx.vaultMemoryCollection.find(id2);
18403
- if (record2.isDeleted || record2.supersededBy || !isOwnedByCtxUser(ctx, record2)) return false;
18404
- if (isKinded(record2)) return false;
18898
+ const record3 = await ctx.vaultMemoryCollection.find(id2);
18899
+ if (record3.isDeleted || record3.supersededBy || !isOwnedByCtxUser(ctx, record3)) return false;
18900
+ if (isKinded(record3)) return false;
18405
18901
  let successor;
18406
18902
  try {
18407
18903
  successor = await ctx.vaultMemoryCollection.find(supersededById);
@@ -18414,7 +18910,7 @@ async function supersedeVaultMemoryOp(ctx, id2, supersededById) {
18414
18910
  let stale = false;
18415
18911
  await ctx.database.write(async () => {
18416
18912
  await assertCanWrite2(ctx);
18417
- if (record2.isDeleted || record2.supersededBy || !isOwnedByCtxUser(ctx, record2)) {
18913
+ if (record3.isDeleted || record3.supersededBy || !isOwnedByCtxUser(ctx, record3)) {
18418
18914
  stale = true;
18419
18915
  return;
18420
18916
  }
@@ -18422,7 +18918,7 @@ async function supersedeVaultMemoryOp(ctx, id2, supersededById) {
18422
18918
  stale = true;
18423
18919
  return;
18424
18920
  }
18425
- await record2.update((r) => {
18921
+ await record3.update((r) => {
18426
18922
  r._setRaw("superseded_by", supersededById);
18427
18923
  r._setRaw("superseded_at", Date.now());
18428
18924
  });
@@ -18441,7 +18937,7 @@ async function getUnfiledVaultMemoriesOp(ctx) {
18441
18937
  const results = await ctx.vaultMemoryCollection.query(...conditions).fetch();
18442
18938
  return mapInBatches(
18443
18939
  results,
18444
- (record2) => vaultMemoryToStored(record2, ctx.walletAddress, ctx.signMessage, ctx.embeddedWalletSigner)
18940
+ (record3) => vaultMemoryToStored(record3, ctx.walletAddress, ctx.signMessage, ctx.embeddedWalletSigner)
18445
18941
  );
18446
18942
  }
18447
18943
  var TOPICS_EXTRACTION_VERSION = 3;
@@ -18602,17 +19098,17 @@ async function stampTopicsExtractedAtOp(ctx, memoryIds, extractedAt, version = T
18602
19098
  }
18603
19099
  }
18604
19100
  const eligible = records.filter(
18605
- (record2) => !record2.isDeleted && isOwnedByCtxUser(ctx, record2) && !record2.topicsUserManaged
19101
+ (record3) => !record3.isDeleted && isOwnedByCtxUser(ctx, record3) && !record3.topicsUserManaged
18606
19102
  );
18607
- const prepared = eligible.map((record2) => {
18608
- const originalUpdatedAt = record2.updatedAt.getTime();
18609
- return record2.prepareUpdate((r) => {
19103
+ const prepared = eligible.map((record3) => {
19104
+ const originalUpdatedAt = record3.updatedAt.getTime();
19105
+ return record3.prepareUpdate((r) => {
18610
19106
  r._setRaw("topics_extracted_at", extractedAt);
18611
19107
  r._setRaw("topics_extracted_version", version);
18612
19108
  r._setRaw("updated_at", originalUpdatedAt);
18613
19109
  });
18614
19110
  });
18615
- for (const record2 of eligible) stamped.push(record2.id);
19111
+ for (const record3 of eligible) stamped.push(record3.id);
18616
19112
  if (prepared.length > 0) await ctx.database.batch(...prepared);
18617
19113
  });
18618
19114
  }
@@ -18628,14 +19124,14 @@ async function relinkMemoryTopicsOp(ctx, memoryIds) {
18628
19124
  try {
18629
19125
  await ctx.database.write(async (writer) => {
18630
19126
  await assertCanWrite2(ctx);
18631
- let record2;
19127
+ let record3;
18632
19128
  try {
18633
- record2 = await ctx.vaultMemoryCollection.find(id2);
19129
+ record3 = await ctx.vaultMemoryCollection.find(id2);
18634
19130
  } catch {
18635
19131
  return;
18636
19132
  }
18637
- if (record2.isDeleted || !isOwnedByCtxUser(ctx, record2)) return;
18638
- const topics = parseTopics(record2.topics);
19133
+ if (record3.isDeleted || !isOwnedByCtxUser(ctx, record3)) return;
19134
+ const topics = parseTopics(record3.topics);
18639
19135
  if (topics === null) return;
18640
19136
  await writer.callWriter(() => relinkMemoryEntitiesFromTopicsOp(entityCtx, id2, topics));
18641
19137
  relinked.push(id2);
@@ -18661,18 +19157,18 @@ async function backfillMemoryTopicsOp(ctx, memoryIds) {
18661
19157
  await assertCanWrite2(ctx);
18662
19158
  const records = [];
18663
19159
  for (const id2 of chunkIds) {
18664
- let record2;
19160
+ let record3;
18665
19161
  try {
18666
- record2 = await ctx.vaultMemoryCollection.find(id2);
19162
+ record3 = await ctx.vaultMemoryCollection.find(id2);
18667
19163
  } catch {
18668
19164
  continue;
18669
19165
  }
18670
- if (record2.isDeleted || !isOwnedByCtxUser(ctx, record2)) continue;
18671
- if (parseTopics(record2.topics) !== null) continue;
18672
- records.push(record2);
19166
+ if (record3.isDeleted || !isOwnedByCtxUser(ctx, record3)) continue;
19167
+ if (parseTopics(record3.topics) !== null) continue;
19168
+ records.push(record3);
18673
19169
  }
18674
19170
  if (records.length === 0) return;
18675
- const links2 = await entityCtx.memoryEntityCollection.query(Q9.where("memory_id", Q9.oneOf(records.map((record2) => record2.id)))).unsafeFetchRaw();
19171
+ const links2 = await entityCtx.memoryEntityCollection.query(Q9.where("memory_id", Q9.oneOf(records.map((record3) => record3.id)))).unsafeFetchRaw();
18676
19172
  const entityIds = Array.from(new Set(links2.map((link) => String(link.entity_id))));
18677
19173
  const entitiesById = /* @__PURE__ */ new Map();
18678
19174
  for (let j = 0; j < entityIds.length; j += CHUNK) {
@@ -18692,13 +19188,13 @@ async function backfillMemoryTopicsOp(ctx, memoryIds) {
18692
19188
  entities.add(entity);
18693
19189
  }
18694
19190
  const writes = [];
18695
- for (const record2 of records) {
18696
- const entities = entitiesByMemory.get(record2.id);
19191
+ for (const record3 of records) {
19192
+ const entities = entitiesByMemory.get(record3.id);
18697
19193
  if (!entities?.size) continue;
18698
- const source = record2.topicsUserManaged ? "user" : "auto";
19194
+ const source = record3.topicsUserManaged ? "user" : "auto";
18699
19195
  const write = await resolveMemoryTopicsWrite(
18700
19196
  entityCtx,
18701
- record2.id,
19197
+ record3.id,
18702
19198
  Array.from(entities),
18703
19199
  [],
18704
19200
  source
@@ -18720,7 +19216,7 @@ async function deleteAllVaultMemoriesForUserOp(ctx, userId) {
18720
19216
  await ctx.database.write(async () => {
18721
19217
  await assertCanWrite2(ctx);
18722
19218
  const prepared = records.map(
18723
- (record2) => record2.prepareUpdate((r) => {
19219
+ (record3) => record3.prepareUpdate((r) => {
18724
19220
  r._setRaw("is_deleted", true);
18725
19221
  })
18726
19222
  );
@@ -18791,22 +19287,22 @@ async function applyDecayTransitionsOp(ctx, candidates, opts) {
18791
19287
  Q9.where("id", Q9.oneOf(ids.slice(i, i + CHUNK))),
18792
19288
  ...ctx.userId !== void 0 ? [Q9.where("user_id", ctx.userId)] : []
18793
19289
  ).fetch();
18794
- const eligible = records.filter((record2) => {
18795
- if (record2.isDeleted || !isOwnedByCtxUser(ctx, record2)) return false;
19290
+ const eligible = records.filter((record3) => {
19291
+ if (record3.isDeleted || !isOwnedByCtxUser(ctx, record3)) return false;
18796
19292
  if (opts.transition === "delete") {
18797
- return record2.archivedAt !== null && opts.now - record2.archivedAt > opts.hardDeleteWindowMs;
19293
+ return record3.archivedAt !== null && opts.now - record3.archivedAt > opts.hardDeleteWindowMs;
18798
19294
  }
18799
- const candidate = byId.get(record2.id);
18800
- return record2.archivedAt === null && record2.updatedAt.getTime() === candidate.updatedAt && (record2.lastObservedAt ?? null) === (candidate.lastObservedAt ?? null);
19295
+ const candidate = byId.get(record3.id);
19296
+ return record3.archivedAt === null && record3.updatedAt.getTime() === candidate.updatedAt && (record3.lastObservedAt ?? null) === (candidate.lastObservedAt ?? null);
18801
19297
  });
18802
19298
  const prepared = eligible.map(
18803
- (record2) => record2.prepareUpdate((row) => {
19299
+ (record3) => record3.prepareUpdate((row) => {
18804
19300
  if (opts.transition === "archive") row._setRaw("archived_at", opts.now);
18805
19301
  else row._setRaw("is_deleted", true);
18806
19302
  })
18807
19303
  );
18808
19304
  if (prepared.length > 0) await ctx.database.batch(prepared);
18809
- applied = eligible.map((record2) => record2.id);
19305
+ applied = eligible.map((record3) => record3.id);
18810
19306
  });
18811
19307
  } catch {
18812
19308
  continue;
@@ -18824,21 +19320,21 @@ async function applyDecayTransitionsOp(ctx, candidates, opts) {
18824
19320
  }
18825
19321
  async function archiveVaultMemoryOp(ctx, id2, opts) {
18826
19322
  try {
18827
- const record2 = await ctx.vaultMemoryCollection.find(id2);
18828
- if (record2.isDeleted || !isOwnedByCtxUser(ctx, record2)) return false;
19323
+ const record3 = await ctx.vaultMemoryCollection.find(id2);
19324
+ if (record3.isDeleted || !isOwnedByCtxUser(ctx, record3)) return false;
18829
19325
  let stale = false;
18830
19326
  const archivedAtValue = opts?.now ?? Date.now();
18831
19327
  await ctx.database.write(async () => {
18832
19328
  await assertCanWrite2(ctx);
18833
- if (record2.isDeleted || !isOwnedByCtxUser(ctx, record2) || record2.archivedAt !== null) {
19329
+ if (record3.isDeleted || !isOwnedByCtxUser(ctx, record3) || record3.archivedAt !== null) {
18834
19330
  stale = true;
18835
19331
  return;
18836
19332
  }
18837
- if (opts?.expectedUpdatedAt !== void 0 && record2.updatedAt.getTime() !== opts.expectedUpdatedAt || opts?.expectedLastObservedAt !== void 0 && (record2.lastObservedAt ?? null) !== opts.expectedLastObservedAt) {
19333
+ if (opts?.expectedUpdatedAt !== void 0 && record3.updatedAt.getTime() !== opts.expectedUpdatedAt || opts?.expectedLastObservedAt !== void 0 && (record3.lastObservedAt ?? null) !== opts.expectedLastObservedAt) {
18838
19334
  stale = true;
18839
19335
  return;
18840
19336
  }
18841
- await record2.update((r) => {
19337
+ await record3.update((r) => {
18842
19338
  r._setRaw("archived_at", archivedAtValue);
18843
19339
  });
18844
19340
  });
@@ -18849,16 +19345,16 @@ async function archiveVaultMemoryOp(ctx, id2, opts) {
18849
19345
  }
18850
19346
  async function restoreVaultMemoryOp(ctx, id2) {
18851
19347
  try {
18852
- const record2 = await ctx.vaultMemoryCollection.find(id2);
18853
- if (record2.isDeleted || !isOwnedByCtxUser(ctx, record2)) return false;
19348
+ const record3 = await ctx.vaultMemoryCollection.find(id2);
19349
+ if (record3.isDeleted || !isOwnedByCtxUser(ctx, record3)) return false;
18854
19350
  let stale = false;
18855
19351
  await ctx.database.write(async () => {
18856
19352
  await assertCanWrite2(ctx);
18857
- if (record2.isDeleted || !isOwnedByCtxUser(ctx, record2)) {
19353
+ if (record3.isDeleted || !isOwnedByCtxUser(ctx, record3)) {
18858
19354
  stale = true;
18859
19355
  return;
18860
19356
  }
18861
- await record2.update((r) => {
19357
+ await record3.update((r) => {
18862
19358
  r._setRaw("archived_at", null);
18863
19359
  });
18864
19360
  });
@@ -18869,18 +19365,18 @@ async function restoreVaultMemoryOp(ctx, id2) {
18869
19365
  }
18870
19366
  async function hardDeleteDecayedOp(ctx, id2, opts) {
18871
19367
  try {
18872
- const record2 = await ctx.vaultMemoryCollection.find(id2);
18873
- if (record2.isDeleted || !isOwnedByCtxUser(ctx, record2)) return false;
19368
+ const record3 = await ctx.vaultMemoryCollection.find(id2);
19369
+ if (record3.isDeleted || !isOwnedByCtxUser(ctx, record3)) return false;
18874
19370
  const now = opts.now ?? Date.now();
18875
19371
  let stale = false;
18876
19372
  await ctx.database.write(async () => {
18877
19373
  await assertCanWrite2(ctx);
18878
- const archivedAt = record2.archivedAt;
18879
- if (record2.isDeleted || !isOwnedByCtxUser(ctx, record2) || archivedAt === null || now - archivedAt <= opts.hardDeleteWindowMs) {
19374
+ const archivedAt = record3.archivedAt;
19375
+ if (record3.isDeleted || !isOwnedByCtxUser(ctx, record3) || archivedAt === null || now - archivedAt <= opts.hardDeleteWindowMs) {
18880
19376
  stale = true;
18881
19377
  return;
18882
19378
  }
18883
- await record2.update((r) => {
19379
+ await record3.update((r) => {
18884
19380
  r._setRaw("is_deleted", true);
18885
19381
  });
18886
19382
  });
@@ -18898,14 +19394,14 @@ async function hardDeleteDecayedOp(ctx, id2, opts) {
18898
19394
  }
18899
19395
  async function updateVaultMemoryEmbeddingOp(ctx, id2, embedding2, embeddingModel, expected) {
18900
19396
  try {
18901
- const record2 = await ctx.vaultMemoryCollection.find(id2);
18902
- if (record2.isDeleted || !isOwnedByCtxUser(ctx, record2)) return false;
18903
- const readUpdatedAt = record2.updatedAt.getTime();
18904
- const readStoredContent = record2._getRaw("content");
19397
+ const record3 = await ctx.vaultMemoryCollection.find(id2);
19398
+ if (record3.isDeleted || !isOwnedByCtxUser(ctx, record3)) return false;
19399
+ const readUpdatedAt = record3.updatedAt.getTime();
19400
+ const readStoredContent = record3._getRaw("content");
18905
19401
  if (expected?.updatedAt !== void 0 && expected.updatedAt !== readUpdatedAt) return false;
18906
19402
  if (expected?.content !== void 0) {
18907
19403
  const current = await vaultMemoryToStored(
18908
- record2,
19404
+ record3,
18909
19405
  ctx.walletAddress,
18910
19406
  ctx.signMessage,
18911
19407
  ctx.embeddedWalletSigner
@@ -18915,11 +19411,11 @@ async function updateVaultMemoryEmbeddingOp(ctx, id2, embedding2, embeddingModel
18915
19411
  let written = false;
18916
19412
  await ctx.database.write(async () => {
18917
19413
  await assertCanWrite2(ctx);
18918
- if (record2.isDeleted || !isOwnedByCtxUser(ctx, record2)) return;
18919
- const originalUpdatedAt = record2.updatedAt.getTime();
18920
- if (originalUpdatedAt !== readUpdatedAt || record2._getRaw("content") !== readStoredContent)
19414
+ if (record3.isDeleted || !isOwnedByCtxUser(ctx, record3)) return;
19415
+ const originalUpdatedAt = record3.updatedAt.getTime();
19416
+ if (originalUpdatedAt !== readUpdatedAt || record3._getRaw("content") !== readStoredContent)
18921
19417
  return;
18922
- await record2.update((r) => {
19418
+ await record3.update((r) => {
18923
19419
  r._setRaw("embedding", embedding2);
18924
19420
  r._setRaw("embedding_model", embeddingModel);
18925
19421
  r._setRaw("updated_at", originalUpdatedAt);
@@ -19083,26 +19579,26 @@ async function ingestPublishedPhotoMemoriesOp(ctx, rows) {
19083
19579
  inserted = writable.length;
19084
19580
  if (writable.length === 0) return;
19085
19581
  const prepared = writable.map(
19086
- ({ row, content }) => ctx.vaultMemoryCollection.prepareCreate((record2) => {
19087
- record2._raw.id = row.memoryId;
19088
- record2._setRaw("content", content);
19089
- record2._setRaw("scope", "shared");
19090
- record2._setRaw("level", "matching");
19091
- record2._setRaw("folder_id", null);
19092
- record2._setRaw("user_id", ctx.userId ?? null);
19093
- record2._setRaw("is_deleted", false);
19094
- record2._setRaw("proof_count", 1);
19095
- record2._setRaw("source", SOURCE_PHOTO);
19096
- record2._setRaw(
19582
+ ({ row, content }) => ctx.vaultMemoryCollection.prepareCreate((record3) => {
19583
+ record3._raw.id = row.memoryId;
19584
+ record3._setRaw("content", content);
19585
+ record3._setRaw("scope", "shared");
19586
+ record3._setRaw("level", "matching");
19587
+ record3._setRaw("folder_id", null);
19588
+ record3._setRaw("user_id", ctx.userId ?? null);
19589
+ record3._setRaw("is_deleted", false);
19590
+ record3._setRaw("proof_count", 1);
19591
+ record3._setRaw("source", SOURCE_PHOTO);
19592
+ record3._setRaw(
19097
19593
  "media",
19098
19594
  row.media && row.media.length > 0 ? JSON.stringify(row.media) : null
19099
19595
  );
19100
- record2._setRaw("visibility", "public");
19101
- record2._setRaw("published_at", now);
19596
+ record3._setRaw("visibility", "public");
19597
+ record3._setRaw("published_at", now);
19102
19598
  if (row.eventTime) {
19103
- record2._setRaw("event_time_start", row.eventTime.start ?? null);
19104
- record2._setRaw("event_time_end", row.eventTime.end ?? null);
19105
- record2._setRaw("event_time_kind", row.eventTime.kind ?? null);
19599
+ record3._setRaw("event_time_start", row.eventTime.start ?? null);
19600
+ record3._setRaw("event_time_end", row.eventTime.end ?? null);
19601
+ record3._setRaw("event_time_kind", row.eventTime.kind ?? null);
19106
19602
  }
19107
19603
  })
19108
19604
  );
@@ -19933,11 +20429,11 @@ function folderToStored(folder) {
19933
20429
  }
19934
20430
  async function createVaultFolderOp(ctx, opts) {
19935
20431
  const created = await ctx.database.write(async () => {
19936
- return ctx.vaultFolderCollection.create((record2) => {
19937
- record2._setRaw("name", opts.name);
19938
- record2._setRaw("scope", opts.scope ?? "private");
19939
- record2._setRaw("is_system", opts.isSystem ?? false);
19940
- record2._setRaw("is_deleted", false);
20432
+ return ctx.vaultFolderCollection.create((record3) => {
20433
+ record3._setRaw("name", opts.name);
20434
+ record3._setRaw("scope", opts.scope ?? "private");
20435
+ record3._setRaw("is_system", opts.isSystem ?? false);
20436
+ record3._setRaw("is_deleted", false);
19941
20437
  });
19942
20438
  });
19943
20439
  return folderToStored(created);
@@ -19948,14 +20444,14 @@ async function getAllVaultFoldersOp(ctx) {
19948
20444
  }
19949
20445
  async function updateVaultFolderOp(ctx, id2, opts) {
19950
20446
  try {
19951
- const record2 = await ctx.vaultFolderCollection.find(id2);
19952
- if (record2.isDeleted) return null;
19953
- const scopeChanged = opts.scope !== void 0 && opts.scope !== record2.scope;
20447
+ const record3 = await ctx.vaultFolderCollection.find(id2);
20448
+ if (record3.isDeleted) return null;
20449
+ const scopeChanged = opts.scope !== void 0 && opts.scope !== record3.scope;
19954
20450
  const updated = await ctx.database.write(async () => {
19955
20451
  const memories = scopeChanged ? await ctx.vaultMemoryCollection.query(Q15.where("folder_id", id2), Q15.where("is_deleted", false)).fetch() : [];
19956
20452
  const updates = [];
19957
20453
  updates.push(
19958
- record2.prepareUpdate((r) => {
20454
+ record3.prepareUpdate((r) => {
19959
20455
  if (opts.name !== void 0) r._setRaw("name", opts.name);
19960
20456
  if (opts.scope !== void 0) r._setRaw("scope", opts.scope);
19961
20457
  })
@@ -19978,8 +20474,8 @@ async function updateVaultFolderOp(ctx, id2, opts) {
19978
20474
  }
19979
20475
  async function deleteVaultFolderOp(ctx, id2) {
19980
20476
  try {
19981
- const record2 = await ctx.vaultFolderCollection.find(id2);
19982
- if (record2.isDeleted) return false;
20477
+ const record3 = await ctx.vaultFolderCollection.find(id2);
20478
+ if (record3.isDeleted) return false;
19983
20479
  await ctx.database.write(async () => {
19984
20480
  const memories = await ctx.vaultMemoryCollection.query(Q15.where("folder_id", id2), Q15.where("is_deleted", false)).fetch();
19985
20481
  const preparedMemories = memories.map(
@@ -19989,7 +20485,7 @@ async function deleteVaultFolderOp(ctx, id2) {
19989
20485
  r._setRaw("scope", "private");
19990
20486
  })
19991
20487
  );
19992
- const preparedFolder = record2.prepareUpdate((r) => {
20488
+ const preparedFolder = record3.prepareUpdate((r) => {
19993
20489
  r._setRaw("is_deleted", true);
19994
20490
  });
19995
20491
  await ctx.database.batch(...preparedMemories, preparedFolder);
@@ -20036,11 +20532,11 @@ async function moveMemoriesToFolderOp(ctx, memoryIds, folderId) {
20036
20532
  }
20037
20533
  async function updateVaultFolderContextOp(ctx, id2, context) {
20038
20534
  try {
20039
- const record2 = await ctx.vaultFolderCollection.find(id2);
20040
- if (record2.isDeleted) return null;
20535
+ const record3 = await ctx.vaultFolderCollection.find(id2);
20536
+ if (record3.isDeleted) return null;
20041
20537
  const updated = await ctx.database.write(async () => {
20042
20538
  await ctx.database.batch(
20043
- record2.prepareUpdate((r) => {
20539
+ record3.prepareUpdate((r) => {
20044
20540
  r._setRaw("context", context);
20045
20541
  })
20046
20542
  );
@@ -21134,9 +21630,9 @@ function loadVaultCorpus(ctx, options, preparation) {
21134
21630
  const key3 = JSON.stringify(options ?? {});
21135
21631
  let request = pending.get(key3);
21136
21632
  if (!request) {
21137
- const entries = pending;
21633
+ const entries2 = pending;
21138
21634
  request = getAllVaultMemoriesOp(ctx, options).catch((error) => {
21139
- entries.delete(key3);
21635
+ entries2.delete(key3);
21140
21636
  throw error;
21141
21637
  });
21142
21638
  pending.set(key3, request);
@@ -21177,7 +21673,7 @@ function embedVaultRows(ctx, options, rows, preparation) {
21177
21673
  if (!pending.has(keys[index]) && !prepared?.has(keys[index])) missing2.set(keys[index], row);
21178
21674
  });
21179
21675
  if (missing2.size > 0) {
21180
- const entries = pending;
21676
+ const entries2 = pending;
21181
21677
  const batch = Promise.resolve().then(
21182
21678
  () => generateEmbeddings(
21183
21679
  [...missing2.values()].map((row) => row.content),
@@ -21194,16 +21690,16 @@ function embedVaultRows(ctx, options, rows, preparation) {
21194
21690
  });
21195
21691
  return vector2;
21196
21692
  }).finally(() => {
21197
- entries.delete(key3);
21198
- if (entries.size === 0) pendingRows.get(ctx)?.delete(options.maskInput);
21693
+ entries2.delete(key3);
21694
+ if (entries2.size === 0) pendingRows.get(ctx)?.delete(options.maskInput);
21199
21695
  });
21200
21696
  pending.set(key3, request);
21201
21697
  });
21202
21698
  }
21203
21699
  return Promise.all(
21204
21700
  keys.map((key3) => {
21205
- const cached = prepared?.get(key3);
21206
- if (cached) return cached;
21701
+ const cached2 = prepared?.get(key3);
21702
+ if (cached2) return cached2;
21207
21703
  const request = pending.get(key3);
21208
21704
  if (!prepared) return request;
21209
21705
  const retained = request.catch((error) => {
@@ -21903,10 +22399,10 @@ async function buildProjectedCorpus(query, vaultCtx, embeddingOptions, cache, qu
21903
22399
  const resolvedThisCall = /* @__PURE__ */ new Set();
21904
22400
  if (!embeddingsDegraded) {
21905
22401
  for (const k2 of keys) {
21906
- const cached = cachedRowVector(cache, k2.uniqueId, k2.updatedAt);
21907
- if (cached && cached.length === queryEmbedding.length) {
22402
+ const cached2 = cachedRowVector(cache, k2.uniqueId, k2.updatedAt);
22403
+ if (cached2 && cached2.length === queryEmbedding.length) {
21908
22404
  corpusStats.cacheHits++;
21909
- vectored.push({ uniqueId: k2.uniqueId, embedding: cached, updatedAt: k2.updatedAt });
22405
+ vectored.push({ uniqueId: k2.uniqueId, embedding: cached2, updatedAt: k2.updatedAt });
21910
22406
  continue;
21911
22407
  }
21912
22408
  corpusStats.cacheMisses++;
@@ -22204,12 +22700,12 @@ async function prepareVaultCandidates(query, vaultCtx, embeddingOptions, cache,
22204
22700
  for (let i = 0; queryEmbedding.length > 0 && i < memories.length; i++) {
22205
22701
  const content = memories[i].content;
22206
22702
  const memoryId = memories[i].uniqueId;
22207
- const cached = cachedRowVector(cache, memoryId, memories[i].updatedAt, content);
22208
- if (cached && cached.length === queryEmbedding.length) {
22209
- resolvedVectors.set(memoryId, cached);
22703
+ const cached2 = cachedRowVector(cache, memoryId, memories[i].updatedAt, content);
22704
+ if (cached2 && cached2.length === queryEmbedding.length) {
22705
+ resolvedVectors.set(memoryId, cached2);
22210
22706
  continue;
22211
22707
  }
22212
- if (cached) cache.delete(memoryId);
22708
+ if (cached2) cache.delete(memoryId);
22213
22709
  const storedModel = memories[i].embeddingModel;
22214
22710
  const modelCompatible = (storedModel ?? currentModel) === currentModel;
22215
22711
  if (memories[i].embedding && modelCompatible) {
@@ -23893,9 +24389,9 @@ function createDecaySweeperOver(backend, options) {
23893
24389
  if (ruleVerdict !== "keep") return rule;
23894
24390
  if (!classifier || !isBorderline(input)) return rule;
23895
24391
  if (input.id) {
23896
- const cached = classifierCache.get(input.id);
23897
- if (cached && cached.activityAt === lastActivityAt(input))
23898
- return { verdict: cached.verdict, source: "classifierDriven" };
24392
+ const cached2 = classifierCache.get(input.id);
24393
+ if (cached2 && cached2.activityAt === lastActivityAt(input))
24394
+ return { verdict: cached2.verdict, source: "classifierDriven" };
23899
24395
  }
23900
24396
  if (sweep.classifierCalls >= maxClassifierCalls) {
23901
24397
  sweep.classifierCapHits++;
@@ -25744,21 +26240,21 @@ async function extractAndLinkEntitiesForMemoriesOp(ctx, memoryIds, options) {
25744
26240
  };
25745
26241
  const inputs = [];
25746
26242
  for (const id2 of new Set(memoryIds)) {
25747
- let record2;
26243
+ let record3;
25748
26244
  try {
25749
- record2 = await ctx.vaultMemoryCollection.find(id2);
26245
+ record3 = await ctx.vaultMemoryCollection.find(id2);
25750
26246
  } catch (err) {
25751
26247
  log.warn("[memory/topics] vault lookup failed for extraction", err);
25752
26248
  skip(id2, "not-found");
25753
26249
  continue;
25754
26250
  }
25755
- if (record2.isDeleted || ctx.userId !== void 0 && record2.userId !== ctx.userId || record2.topicsUserManaged) {
26251
+ if (record3.isDeleted || ctx.userId !== void 0 && record3.userId !== ctx.userId || record3.topicsUserManaged) {
25756
26252
  skip(id2, "excluded");
25757
26253
  continue;
25758
26254
  }
25759
26255
  try {
25760
26256
  const stored2 = await vaultMemoryToStored(
25761
- record2,
26257
+ record3,
25762
26258
  ctx.walletAddress,
25763
26259
  ctx.signMessage,
25764
26260
  ctx.embeddedWalletSigner
@@ -26065,6 +26561,7 @@ function createLocalMemoryStore(options) {
26065
26561
 
26066
26562
  // src/lib/memory/store/memoryKeys.ts
26067
26563
  var KEY_ID_DOMAIN = "anuma-private-memory-key-id-v1";
26564
+ var TOPIC_HASH_INFO = "anuma-private-memory-topic-hash-v1";
26068
26565
  var MemoryKeyError = class extends Error {
26069
26566
  constructor(message) {
26070
26567
  super(message);
@@ -26080,17 +26577,40 @@ async function importAesKey(hex) {
26080
26577
  ["encrypt", "decrypt"]
26081
26578
  );
26082
26579
  }
26580
+ async function deriveTopicHashKey(hex) {
26581
+ const material = await crypto.subtle.importKey(
26582
+ "raw",
26583
+ hexToBytes(hex).buffer,
26584
+ { name: "HKDF" },
26585
+ false,
26586
+ ["deriveBits"]
26587
+ );
26588
+ const bits = await crypto.subtle.deriveBits(
26589
+ {
26590
+ name: "HKDF",
26591
+ hash: "SHA-256",
26592
+ salt: new Uint8Array(32),
26593
+ info: new TextEncoder().encode(TOPIC_HASH_INFO)
26594
+ },
26595
+ material,
26596
+ 256
26597
+ );
26598
+ return crypto.subtle.importKey("raw", bits, { name: "HMAC", hash: "SHA-256" }, false, ["sign"]);
26599
+ }
26600
+ function toHex(bytes4) {
26601
+ return Array.from(new Uint8Array(bytes4), (byte) => byte.toString(16).padStart(2, "0")).join("");
26602
+ }
26083
26603
  async function deriveMemoryKeyRing(signatureHex) {
26084
26604
  const v3Hex = await deriveKeyFromSignatureV3(signatureHex);
26085
26605
  const digest = await crypto.subtle.digest(
26086
26606
  "SHA-256",
26087
26607
  new TextEncoder().encode(`${KEY_ID_DOMAIN}:${v3Hex}`)
26088
26608
  );
26089
- const keyId = "v3:" + Array.from(new Uint8Array(digest), (byte) => byte.toString(16).padStart(2, "0")).join("");
26090
26609
  return {
26091
- keyId,
26610
+ keyId: "v3:" + toHex(digest),
26092
26611
  v3: await importAesKey(v3Hex),
26093
- v2: await importAesKey(await deriveKeyFromSignature(signatureHex))
26612
+ v2: await importAesKey(await deriveKeyFromSignature(signatureHex)),
26613
+ topicHash: await deriveTopicHashKey(v3Hex)
26094
26614
  };
26095
26615
  }
26096
26616
  async function decryptWith(value, rings) {
@@ -26111,7 +26631,10 @@ function memoryCipher(canonical) {
26111
26631
  if (!ciphertext.startsWith("enc:v3:") || !isEncrypted(ciphertext))
26112
26632
  throw new MemoryKeyError("Remote memory content must be enc:v3 ciphertext");
26113
26633
  return decryptWith(ciphertext, [canonical]);
26114
- }
26634
+ },
26635
+ hashTopic: async (normalized2) => toHex(
26636
+ await crypto.subtle.sign("HMAC", canonical.topicHash, new TextEncoder().encode(normalized2))
26637
+ )
26115
26638
  };
26116
26639
  }
26117
26640
  async function reencryptMemoryField(value, canonical, fallbacks = []) {
@@ -26543,8 +27066,9 @@ var DEFAULT_RATE_LIMIT_WAIT_MS = 1e4;
26543
27066
  var MAX_ID_BYTES = 128;
26544
27067
  var MAX_CONTENT_BYTES = 32 << 10;
26545
27068
  var MAX_TEXT_BYTES = 16 << 10;
27069
+ var MAX_TOPICS_BYTES = 32 << 10;
26546
27070
  var MAX_SHORT_BYTES = 256;
26547
- var TEXT_FIELDS = ["topics", "media", "source_chunk_ids"];
27071
+ var TEXT_FIELDS = ["media", "source_chunk_ids"];
26548
27072
  var SHORT_FIELDS = [
26549
27073
  "scope",
26550
27074
  "kind",
@@ -26647,7 +27171,7 @@ function bytes3(value) {
26647
27171
  return value === void 0 ? 0 : utf82.encode(value).length;
26648
27172
  }
26649
27173
  function fitsNearby(row) {
26650
- return bytes3(row.memory_id) <= MAX_ID_BYTES && bytes3(row.content) <= MAX_CONTENT_BYTES && bytes3(row.kind_value) <= MAX_CONTENT_BYTES && TEXT_FIELDS.every((field10) => bytes3(row[field10]) <= MAX_TEXT_BYTES) && SHORT_FIELDS.every((field10) => bytes3(row[field10]) <= MAX_SHORT_BYTES);
27174
+ return bytes3(row.memory_id) <= MAX_ID_BYTES && bytes3(row.content) <= MAX_CONTENT_BYTES && bytes3(row.kind_value) <= MAX_CONTENT_BYTES && bytes3(row.topics) <= MAX_TOPICS_BYTES && sealedTopicNamesFit(row.topics) && TEXT_FIELDS.every((field10) => bytes3(row[field10]) <= MAX_TEXT_BYTES) && SHORT_FIELDS.every((field10) => bytes3(row[field10]) <= MAX_SHORT_BYTES);
26651
27175
  }
26652
27176
  function invalid2(raw) {
26653
27177
  const id2 = raw.id;
@@ -26691,7 +27215,7 @@ function defined(value) {
26691
27215
  Object.entries(value).filter(([, field10]) => field10 !== void 0)
26692
27216
  );
26693
27217
  }
26694
- async function prepareRow(raw, canonical, rings, model, updatedAt) {
27218
+ async function prepareRow(raw, canonical, codec, rings, model, updatedAt) {
26695
27219
  const deleted = bool(raw.is_deleted) ?? false;
26696
27220
  const { encrypt } = memoryCipher(canonical);
26697
27221
  const localKindValue = text15(raw.kind_value);
@@ -26705,10 +27229,12 @@ async function prepareRow(raw, canonical, rings, model, updatedAt) {
26705
27229
  plaintext = void 0;
26706
27230
  kindValue = void 0;
26707
27231
  }
27232
+ const fields = metadata2(raw, model);
26708
27233
  const row = {
26709
27234
  ...defined({
26710
- ...metadata2(raw, model),
26711
- kind_value: kindValue === void 0 ? void 0 : await encrypt(kindValue)
27235
+ ...fields,
27236
+ kind_value: kindValue === void 0 ? void 0 : await encrypt(kindValue),
27237
+ topics: fields.topics === void 0 ? void 0 : await codec.encodeTopics(fields.topics)
26712
27238
  }),
26713
27239
  memory_id: raw.id,
26714
27240
  content: await encrypt(plaintext ?? ""),
@@ -26752,6 +27278,8 @@ function sameMetadata2(local, remote, model) {
26752
27278
  if (field10 === "visibility") return (a ?? "private") === (b ?? "private");
26753
27279
  if (field10 === "is_deleted" || field10 === "topics_user_managed" || field10 === "twin_opt_in")
26754
27280
  return (a ?? false) === (b ?? false);
27281
+ if (field10 === "topics")
27282
+ return JSON.stringify(parseTopics(a)) === JSON.stringify(parseTopics(b));
26755
27283
  return a === b;
26756
27284
  });
26757
27285
  }
@@ -26807,7 +27335,7 @@ async function missingIds(request, revisions, signal) {
26807
27335
  }
26808
27336
  return missing2;
26809
27337
  }
26810
- async function remoteMetadata(request, ids, signal) {
27338
+ async function remoteMetadata(request, codec, ids, signal) {
26811
27339
  const rows = /* @__PURE__ */ new Map();
26812
27340
  for (const batch of chunks(ids, QUERY_IDS)) {
26813
27341
  let cursor;
@@ -26831,7 +27359,12 @@ async function remoteMetadata(request, ids, signal) {
26831
27359
  if (!Array.isArray(page.items)) throw new Error("Invalid nearby private-memory page");
26832
27360
  for (const item of page.items)
26833
27361
  if (item.memory && typeof item.memory.memory_id === "string")
26834
- rows.set(item.memory.memory_id, item.memory);
27362
+ rows.set(item.memory.memory_id, {
27363
+ ...item.memory,
27364
+ ...typeof item.memory.topics === "string" && {
27365
+ topics: await codec.decodeTopics(item.memory.topics).catch(() => null)
27366
+ }
27367
+ });
26835
27368
  cursor = typeof page.next_cursor === "string" ? page.next_cursor : void 0;
26836
27369
  } while (cursor);
26837
27370
  }
@@ -26849,6 +27382,7 @@ async function migrateMemoriesToRemote(options) {
26849
27382
  const rings = [canonical, ...options.fallbacks ?? []];
26850
27383
  const model = options.embeddingOptions?.model ?? DEFAULT_API_EMBEDDING_MODEL;
26851
27384
  const request = createNearbyRequest(options);
27385
+ const codec = createTopicCodec(memoryCipher(canonical));
26852
27386
  const account = await request("/account", {}, signal);
26853
27387
  if (typeof account.key_id === "string" && account.key_id !== canonical.keyId)
26854
27388
  throw new RemoteMemoryError(
@@ -26865,7 +27399,7 @@ async function migrateMemoriesToRemote(options) {
26865
27399
  ...typeof t.kind === "string" && { kind: t.kind }
26866
27400
  })).filter((t) => t.name.length > 0) : []);
26867
27401
  if (localTopics.length)
26868
- await createRemoteTopicPersistence(request).importTopics(localTopics, signal);
27402
+ await createRemoteTopicPersistence(request, codec).importTopics(localTopics, signal);
26869
27403
  const skipped = /* @__PURE__ */ new Map();
26870
27404
  const reembedded = /* @__PURE__ */ new Set();
26871
27405
  const unembedded = /* @__PURE__ */ new Set();
@@ -26884,6 +27418,7 @@ async function migrateMemoriesToRemote(options) {
26884
27418
  if (pending.size === 0 && !active) {
26885
27419
  const remote = await remoteMetadata(
26886
27420
  request,
27421
+ codec,
26887
27422
  candidates.map((raw) => raw.id),
26888
27423
  signal
26889
27424
  );
@@ -26928,7 +27463,7 @@ async function migrateMemoriesToRemote(options) {
26928
27463
  const updatedAt = pending.get(raw.id);
26929
27464
  if (updatedAt === void 0) continue;
26930
27465
  try {
26931
- prepared.push(await prepareRow(raw, canonical, rings, model, updatedAt));
27466
+ prepared.push(await prepareRow(raw, canonical, codec, rings, model, updatedAt));
26932
27467
  } catch (error) {
26933
27468
  if (!(error instanceof MemoryKeyError)) throw error;
26934
27469
  skipped.set(raw.id, "unreadable");
@@ -27087,7 +27622,7 @@ function topicInputs(topics, source) {
27087
27622
  function mergeTopics(existing, added) {
27088
27623
  const byName = /* @__PURE__ */ new Map();
27089
27624
  for (const topic2 of [...existing, ...added]) {
27090
- const key3 = normalizeEntityName(topic2.name);
27625
+ const key3 = normalizeTopicName(topic2.name);
27091
27626
  const kept = byName.get(key3);
27092
27627
  if (!kept) byName.set(key3, topic2);
27093
27628
  else if (kept.weight !== void 0 && topic2.weight !== void 0 && topic2.weight > kept.weight)
@@ -27102,7 +27637,7 @@ function sameTopics(stored2, next) {
27102
27637
  return next.every((t) => keys.has(key3(t)));
27103
27638
  }
27104
27639
  function canonicalTopics(row) {
27105
- return new Set((parseTopics(row.topics) ?? []).map((topic2) => normalizeEntityName(topic2.name)));
27640
+ return new Set((parseTopics(row.topics) ?? []).map((topic2) => normalizeTopicName(topic2.name)));
27106
27641
  }
27107
27642
  function createRemoteMemoryStore(options) {
27108
27643
  const { persistence, embeddingOptions } = options;
@@ -27149,10 +27684,10 @@ function createRemoteMemoryStore(options) {
27149
27684
  const notify = (change, records = []) => {
27150
27685
  invalidateReads();
27151
27686
  if (subscribers.size)
27152
- for (const record2 of records) {
27153
- const previous = seen.get(record2.memory.memory_id);
27154
- if ((previous?.version ?? 0) + 1 === record2.version)
27155
- seen.set(record2.memory.memory_id, subscriptionState(record2));
27687
+ for (const record3 of records) {
27688
+ const previous = seen.get(record3.memory.memory_id);
27689
+ if ((previous?.version ?? 0) + 1 === record3.version)
27690
+ seen.set(record3.memory.memory_id, subscriptionState(record3));
27156
27691
  }
27157
27692
  for (const subscriber of [...subscribers])
27158
27693
  if (relevant(change, subscriber.options)) safely(subscriber.onChange);
@@ -27205,7 +27740,7 @@ function createRemoteMemoryStore(options) {
27205
27740
  };
27206
27741
  const enumerate = (filters, max = Infinity) => pages(decrypted, filters, max);
27207
27742
  const memoriesByTopics = async (names) => {
27208
- const wanted = new Set(names.map(normalizeEntityName).filter(Boolean));
27743
+ const wanted = new Set(names.map(normalizeTopicName).filter(Boolean));
27209
27744
  const out = /* @__PURE__ */ new Map();
27210
27745
  const pages2 = await Promise.all(
27211
27746
  chunks2([...wanted], MAX_QUERY_TOPICS).map((topics) => enumerate({ topics }))
@@ -27217,7 +27752,7 @@ function createRemoteMemoryStore(options) {
27217
27752
  return out;
27218
27753
  };
27219
27754
  const topicGraphRanking = async (query, recallOptions = {}) => {
27220
- const wanted = new Set(extractQueryEntities(query).map(normalizeEntityName).filter(Boolean));
27755
+ const wanted = new Set(extractQueryEntities(query).map(normalizeTopicName).filter(Boolean));
27221
27756
  if (wanted.size === 0 || recallOptions.memoryIds?.length === 0) return [];
27222
27757
  const rows = await pages(
27223
27758
  metadata3,
@@ -27275,25 +27810,25 @@ function createRemoteMemoryStore(options) {
27275
27810
  return run;
27276
27811
  };
27277
27812
  const live2 = async (id2) => {
27278
- const record2 = await persistence.get(id2);
27279
- return record2 && !record2.memory.is_deleted ? record2 : null;
27813
+ const record3 = await persistence.get(id2);
27814
+ return record3 && !record3.memory.is_deleted ? record3 : null;
27280
27815
  };
27281
27816
  const mutateLocked = async (id2, change, edit, writeOptions) => {
27282
27817
  writeOptions?.signal?.throwIfAborted();
27283
- const record2 = writeOptions?.signal ? await persistence.get(id2, writeOptions.signal) : await live2(id2);
27284
- if (!record2) return null;
27285
- if (record2.memory.is_deleted) return null;
27818
+ const record3 = writeOptions?.signal ? await persistence.get(id2, writeOptions.signal) : await live2(id2);
27819
+ if (!record3) return null;
27820
+ if (record3.memory.is_deleted) return null;
27286
27821
  if (writeOptions?.canWrite && !await writeOptions.canWrite())
27287
27822
  throw new MemorySourceIneligibleError();
27288
27823
  writeOptions?.signal?.throwIfAborted();
27289
- const next = edit(structuredClone(record2.memory));
27824
+ const next = edit(structuredClone(record3.memory));
27290
27825
  if (!next) return null;
27291
27826
  const saved = writeOptions?.leaseToken ? (await persistence.putMany(
27292
- [{ memory: next, expectedVersion: record2 }],
27827
+ [{ memory: next, expectedVersion: record3 }],
27293
27828
  writeOptions.signal,
27294
27829
  writeOptions.leaseToken
27295
- ))[0] : writeOptions?.signal ? await persistence.put(next, record2, writeOptions.signal) : await persistence.put(next, record2);
27296
- notify(typeof change === "function" ? change(record2.memory) : change, [saved]);
27830
+ ))[0] : writeOptions?.signal ? await persistence.put(next, record3, writeOptions.signal) : await persistence.put(next, record3);
27831
+ notify(typeof change === "function" ? change(record3.memory) : change, [saved]);
27297
27832
  return saved;
27298
27833
  };
27299
27834
  const mutate = (id2, change, edit, writeOptions) => serialized(id2, () => mutateLocked(id2, change, edit, writeOptions));
@@ -27315,12 +27850,12 @@ function createRemoteMemoryStore(options) {
27315
27850
  }
27316
27851
  const { records, unreadable } = read;
27317
27852
  for (const id2 of slice) {
27318
- const record2 = records.get(id2);
27853
+ const record3 = records.get(id2);
27319
27854
  if (unreadable.has(id2)) failed.set(id2, new Error(`Memory ${id2} could not be decrypted`));
27320
- else if (!record2) failed.set(id2, new Error(`Memory ${id2} was not found`));
27321
- else if (!record2.memory.is_deleted) {
27322
- const memory = edit(structuredClone(record2.memory));
27323
- if (memory) writes.push({ before: record2, memory });
27855
+ else if (!record3) failed.set(id2, new Error(`Memory ${id2} was not found`));
27856
+ else if (!record3.memory.is_deleted) {
27857
+ const memory = edit(structuredClone(record3.memory));
27858
+ if (memory) writes.push({ before: record3, memory });
27324
27859
  }
27325
27860
  }
27326
27861
  if (writes.length === 0) return;
@@ -27331,10 +27866,10 @@ function createRemoteMemoryStore(options) {
27331
27866
  leaseToken
27332
27867
  );
27333
27868
  const byChange = /* @__PURE__ */ new Map();
27334
- written.forEach((record2, i) => {
27335
- saved.set(record2.memory.memory_id, record2);
27869
+ written.forEach((record3, i) => {
27870
+ saved.set(record3.memory.memory_id, record3);
27336
27871
  const kind = change(writes[i].before.memory);
27337
- byChange.set(kind, [...byChange.get(kind) ?? [], record2]);
27872
+ byChange.set(kind, [...byChange.get(kind) ?? [], record3]);
27338
27873
  });
27339
27874
  for (const [kind, changed] of byChange) notify(kind, changed);
27340
27875
  } catch (error) {
@@ -27348,13 +27883,13 @@ function createRemoteMemoryStore(options) {
27348
27883
  continue;
27349
27884
  }
27350
27885
  try {
27351
- const record2 = await mutateLocked(
27886
+ const record3 = await mutateLocked(
27352
27887
  id2,
27353
27888
  change,
27354
27889
  edit,
27355
27890
  leaseToken || signal ? { leaseToken, signal } : void 0
27356
27891
  );
27357
- if (record2) saved.set(id2, record2);
27892
+ if (record3) saved.set(id2, record3);
27358
27893
  } catch (rowError) {
27359
27894
  signal?.throwIfAborted();
27360
27895
  if (isRemoteWorkLeaseExpired(rowError)) throw rowError;
@@ -27450,12 +27985,12 @@ function createRemoteMemoryStore(options) {
27450
27985
  const created = (records, inputs) => {
27451
27986
  embedInBackground(records.filter((_, i) => inputs[i].embedding === void 0));
27452
27987
  notify("membership", records);
27453
- return records.map((record2) => stored(record2.memory));
27988
+ return records.map((record3) => stored(record3.memory));
27454
27989
  };
27455
- const asStored = (record2) => record2 ? stored(record2.memory) : null;
27990
+ const asStored = (record3) => record3 ? stored(record3.memory) : null;
27456
27991
  const knownKinds = async (topics, signal) => {
27457
27992
  const unkinded = [
27458
- ...new Set(topics.filter((t) => !t.kind).map((t) => normalizeEntityName(t.name)))
27993
+ ...new Set(topics.filter((t) => !t.kind).map((t) => normalizeTopicName(t.name)))
27459
27994
  ];
27460
27995
  const kinds2 = /* @__PURE__ */ new Map();
27461
27996
  for (const names of chunks2(unkinded, MAX_QUERY_TOPICS)) {
@@ -27467,13 +28002,13 @@ function createRemoteMemoryStore(options) {
27467
28002
  ...signal && { signal }
27468
28003
  })) {
27469
28004
  for (const topic2 of parseTopics(memory.topics) ?? []) {
27470
- const name = normalizeEntityName(topic2.name);
28005
+ const name = normalizeTopicName(topic2.name);
27471
28006
  if (topic2.kind && !kinds2.has(name)) kinds2.set(name, topic2.kind);
27472
28007
  }
27473
28008
  }
27474
28009
  }
27475
28010
  return (topic2) => {
27476
- const kind = topic2.kind ?? kinds2.get(normalizeEntityName(topic2.name));
28011
+ const kind = topic2.kind ?? kinds2.get(normalizeTopicName(topic2.name));
27477
28012
  return kind ? { ...topic2, kind } : topic2;
27478
28013
  };
27479
28014
  };
@@ -27496,7 +28031,7 @@ function createRemoteMemoryStore(options) {
27496
28031
  ...cursor2 && { cursor: cursor2 }
27497
28032
  });
27498
28033
  warnFailed(page.failed);
27499
- for (const record2 of page.items) records.set(record2.memory.memory_id, record2);
28034
+ for (const record3 of page.items) records.set(record3.memory.memory_id, record3);
27500
28035
  for (const failure of page.failed) unreadable.add(failure.memory_id);
27501
28036
  cursor2 = page.next_cursor;
27502
28037
  } while (cursor2);
@@ -27692,8 +28227,8 @@ function createRemoteMemoryStore(options) {
27692
28227
  const failed = /* @__PURE__ */ new Map();
27693
28228
  const collect = (page) => {
27694
28229
  warnFailed(page.failed);
27695
- for (const record2 of page.items)
27696
- records.push({ id: record2.memory.memory_id, state: subscriptionState(record2) });
28230
+ for (const record3 of page.items)
28231
+ records.push({ id: record3.memory.memory_id, state: subscriptionState(record3) });
27697
28232
  for (const failure of page.failed) failed.set(failure.memory_id, failure.version);
27698
28233
  };
27699
28234
  let resume = cursor2;
@@ -27898,7 +28433,7 @@ function createRemoteMemoryStore(options) {
27898
28433
  result.failed += targets.length;
27899
28434
  return finish();
27900
28435
  }
27901
- const writes = targets.flatMap((record2, i) => {
28436
+ const writes = targets.flatMap((record3, i) => {
27902
28437
  const vector2 = vectors[i];
27903
28438
  if (!vector2) {
27904
28439
  result.failed++;
@@ -27908,11 +28443,11 @@ function createRemoteMemoryStore(options) {
27908
28443
  return [
27909
28444
  {
27910
28445
  memory: {
27911
- ...record2.memory,
28446
+ ...record3.memory,
27912
28447
  embedding: storedVector(vector2),
27913
28448
  embedding_model: model
27914
28449
  },
27915
- expectedVersion: record2
28450
+ expectedVersion: record3
27916
28451
  }
27917
28452
  ];
27918
28453
  } catch {
@@ -27927,7 +28462,7 @@ function createRemoteMemoryStore(options) {
27927
28462
  signal?.throwIfAborted();
27928
28463
  const commit = async (slice) => {
27929
28464
  const saved = await persistence.putMany(slice, signal, leaseToken);
27930
- for (const record2 of saved) repaired.add(record2.memory.memory_id);
28465
+ for (const record3 of saved) repaired.add(record3.memory.memory_id);
27931
28466
  result.reembedded += saved.length;
27932
28467
  notify("embedding", saved);
27933
28468
  };
@@ -28011,7 +28546,7 @@ function createRemoteMemoryStore(options) {
28011
28546
  if (!topics.length) return;
28012
28547
  const existing = new Set((await readTopics()).map((topic2) => topic2.name));
28013
28548
  const missing2 = topics.flatMap((topic2) => {
28014
- const name = normalizeEntityName(topic2.name);
28549
+ const name = normalizeTopicName(topic2.name);
28015
28550
  if (existing.has(name)) return [];
28016
28551
  existing.add(name);
28017
28552
  return [{ ...topic2, name }];
@@ -28042,7 +28577,7 @@ function createRemoteMemoryStore(options) {
28042
28577
  include_superseded: true
28043
28578
  })) {
28044
28579
  for (const topic2 of parseTopics(memory.topics) ?? []) {
28045
- const name = normalizeEntityName(topic2.name);
28580
+ const name = normalizeTopicName(topic2.name);
28046
28581
  if (!name) continue;
28047
28582
  const entry = topics.get(name) ?? {
28048
28583
  name,
@@ -28080,7 +28615,7 @@ function createRemoteMemoryStore(options) {
28080
28615
  },
28081
28616
  get: async (id2) => asStored(await live2(id2)),
28082
28617
  listArchived: async () => (await enumerate({ archived_only: true, order: "archived", include_embeddings: true })).map(
28083
- (record2) => stored(record2.memory)
28618
+ (record3) => stored(record3.memory)
28084
28619
  ),
28085
28620
  memoriesByTopics,
28086
28621
  topicsByMemories: async (memoryIds) => {
@@ -28096,8 +28631,8 @@ function createRemoteMemoryStore(options) {
28096
28631
  return out;
28097
28632
  },
28098
28633
  create: async (input) => {
28099
- const record2 = await persistence.put(newRow(input), 0);
28100
- return created([record2], [input])[0];
28634
+ const record3 = await persistence.put(newRow(input), 0);
28635
+ return created([record3], [input])[0];
28101
28636
  },
28102
28637
  createMany: async (inputs) => {
28103
28638
  const out = [];
@@ -28184,12 +28719,12 @@ function createRemoteMemoryStore(options) {
28184
28719
  (memory) => memory.archived_at === void 0 || memory.archived_at === null ? { ...memory, archived_at: Date.now() } : null
28185
28720
  ),
28186
28721
  restore: (id2) => serialized(id2, async () => {
28187
- const record2 = await live2(id2);
28188
- if (!record2) return false;
28189
- if (record2.memory.archived_at === void 0 || record2.memory.archived_at === null)
28722
+ const record3 = await live2(id2);
28723
+ if (!record3) return false;
28724
+ if (record3.memory.archived_at === void 0 || record3.memory.archived_at === null)
28190
28725
  return true;
28191
- const { archived_at: _archivedAt, ...memory } = record2.memory;
28192
- notify("edit", [await persistence.put(memory, record2)]);
28726
+ const { archived_at: _archivedAt, ...memory } = record3.memory;
28727
+ notify("edit", [await persistence.put(memory, record3)]);
28193
28728
  return true;
28194
28729
  }),
28195
28730
  setTopics: async (memoryId, topics) => {
@@ -28222,8 +28757,8 @@ function createRemoteMemoryStore(options) {
28222
28757
  const now = /* @__PURE__ */ new Date();
28223
28758
  return mergeTopics([], added).map(
28224
28759
  (topic2) => ({
28225
- uniqueId: normalizeEntityName(topic2.name),
28226
- canonicalName: normalizeEntityName(topic2.name),
28760
+ uniqueId: normalizeTopicName(topic2.name),
28761
+ canonicalName: normalizeTopicName(topic2.name),
28227
28762
  kind: topic2.kind ?? null,
28228
28763
  createdAt: now,
28229
28764
  updatedAt: now
@@ -31585,16 +32120,16 @@ var ZipProcessor = class {
31585
32120
  try {
31586
32121
  const arrayBuffer = await dataUrlToArrayBuffer(file.dataUrl);
31587
32122
  const zip = await JSZip.loadAsync(arrayBuffer);
31588
- const entries = [];
32123
+ const entries2 = [];
31589
32124
  const processedContents = [];
31590
32125
  zip.forEach((relativePath, zipEntry) => {
31591
- entries.push({
32126
+ entries2.push({
31592
32127
  path: relativePath,
31593
32128
  isDirectory: zipEntry.dir,
31594
32129
  zipObject: zipEntry
31595
32130
  });
31596
32131
  });
31597
- const visibleEntries = this.includeHidden ? entries : entries.filter((entry) => !this.isHidden(entry.path));
32132
+ const visibleEntries = this.includeHidden ? entries2 : entries2.filter((entry) => !this.isHidden(entry.path));
31598
32133
  visibleEntries.sort((a, b) => {
31599
32134
  if (a.isDirectory !== b.isDirectory) {
31600
32135
  return a.isDirectory ? -1 : 1;
@@ -31708,17 +32243,17 @@ var ZipProcessor = class {
31708
32243
  /**
31709
32244
  * Format the output with file listing and processed contents
31710
32245
  */
31711
- formatOutput(entries, processedContents) {
32246
+ formatOutput(entries2, processedContents) {
31712
32247
  const lines = [];
31713
32248
  lines.push("## Archive Contents\n");
31714
32249
  lines.push("```");
31715
- for (const entry of entries) {
32250
+ for (const entry of entries2) {
31716
32251
  const icon = entry.isDirectory ? "\u{1F4C1}" : "\u{1F4C4}";
31717
32252
  lines.push(`${icon} ${entry.path}`);
31718
32253
  }
31719
32254
  lines.push("```\n");
31720
- const fileCount = entries.filter((e) => !e.isDirectory).length;
31721
- const dirCount = entries.filter((e) => e.isDirectory).length;
32255
+ const fileCount = entries2.filter((e) => !e.isDirectory).length;
32256
+ const dirCount = entries2.filter((e) => e.isDirectory).length;
31722
32257
  lines.push(
31723
32258
  `**Summary:** ${fileCount} file${fileCount !== 1 ? "s" : ""}, ${dirCount} director${dirCount !== 1 ? "ies" : "y"}
31724
32259
  `
@@ -32901,13 +33436,13 @@ function serializeInline(node) {
32901
33436
  function openTag(node, indent, depth, selfClose, maxLineWidth) {
32902
33437
  const head = `<${tagName(node.tag)}`;
32903
33438
  const tail = selfClose ? " />" : ">";
32904
- const entries = Object.entries(node.attrs);
32905
- if (entries.length === 0) return `${head}${tail}`;
32906
- const single = `${head} ${entries.map(([k, v]) => formatAttr(k, v)).join(" ")}${tail}`;
33439
+ const entries2 = Object.entries(node.attrs);
33440
+ if (entries2.length === 0) return `${head}${tail}`;
33441
+ const single = `${head} ${entries2.map(([k, v]) => formatAttr(k, v)).join(" ")}${tail}`;
32907
33442
  if (single.length <= maxLineWidth) return single;
32908
33443
  const attrPad = indent.repeat(depth + 1);
32909
33444
  const closePad = indent.repeat(depth);
32910
- const body = entries.map(([k, v]) => `${attrPad}${formatAttr(k, v)}`).join("\n");
33445
+ const body = entries2.map(([k, v]) => `${attrPad}${formatAttr(k, v)}`).join("\n");
32911
33446
  return `${head}
32912
33447
  ${body}
32913
33448
  ${closePad}${selfClose ? "/>" : ">"}`;
@@ -32919,13 +33454,13 @@ function formatAttr(name, value) {
32919
33454
  return `${name}={${formatObjectAttr(value)}}`;
32920
33455
  }
32921
33456
  function formatObjectAttr(obj) {
32922
- const entries = Object.entries(obj).map(([k, v]) => {
33457
+ const entries2 = Object.entries(obj).map(([k, v]) => {
32923
33458
  const key3 = /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(k) ? k : JSON.stringify(k);
32924
33459
  if (typeof v === "string") return `${key3}: ${JSON.stringify(v)}`;
32925
33460
  if (typeof v === "number") return `${key3}: ${String(v)}`;
32926
33461
  return `${key3}: ${v ? "true" : "false"}`;
32927
33462
  });
32928
- return `{ ${entries.join(", ")} }`;
33463
+ return `{ ${entries2.join(", ")} }`;
32929
33464
  }
32930
33465
  function isSafeJsxText(text16) {
32931
33466
  if (/[<>{}&]/.test(text16)) return false;
@@ -34323,7 +34858,7 @@ async function uploadFileToICloud(filename, content, backupRevision) {
34323
34858
  const recordName = `backup_${filename.replace(/[^a-zA-Z0-9]/g, "_")}`;
34324
34859
  const arrayBuffer = await content.arrayBuffer();
34325
34860
  const base64Data = uint8ArrayToBase64(new Uint8Array(arrayBuffer));
34326
- const record2 = {
34861
+ const record3 = {
34327
34862
  recordType: RECORD_TYPE,
34328
34863
  recordName,
34329
34864
  fields: {
@@ -34334,7 +34869,7 @@ async function uploadFileToICloud(filename, content, backupRevision) {
34334
34869
  ...backupRevision ? { backupRevision: { value: backupRevision } } : {}
34335
34870
  }
34336
34871
  };
34337
- const response = await database.saveRecords(record2);
34872
+ const response = await database.saveRecords(record3);
34338
34873
  if (!response.records || response.records.length === 0) {
34339
34874
  throw new Error("Failed to upload file to iCloud");
34340
34875
  }
@@ -34361,12 +34896,12 @@ async function listICloudFiles() {
34361
34896
  while (response.continuationMarker) {
34362
34897
  break;
34363
34898
  }
34364
- const files = allRecords.map((record2) => ({
34365
- recordName: record2.recordName,
34366
- filename: record2.fields.filename?.value ?? "",
34367
- modifiedAt: new Date(record2.modified?.timestamp ?? Date.now()),
34368
- backupRevision: record2.fields.backupRevision?.value,
34369
- size: typeof record2.fields.data?.value === "object" && record2.fields.data?.value !== null ? record2.fields.data.value.size : 0
34899
+ const files = allRecords.map((record3) => ({
34900
+ recordName: record3.recordName,
34901
+ filename: record3.fields.filename?.value ?? "",
34902
+ modifiedAt: new Date(record3.modified?.timestamp ?? Date.now()),
34903
+ backupRevision: record3.fields.backupRevision?.value,
34904
+ size: typeof record3.fields.data?.value === "object" && record3.fields.data?.value !== null ? record3.fields.data.value.size : 0
34370
34905
  }));
34371
34906
  return files.sort((a, b) => b.modifiedAt.getTime() - a.modifiedAt.getTime());
34372
34907
  }
@@ -34379,8 +34914,8 @@ async function downloadICloudFile(recordName) {
34379
34914
  if (!response.records || response.records.length === 0) {
34380
34915
  throw new Error(`File not found: ${recordName}`);
34381
34916
  }
34382
- const record2 = response.records[0];
34383
- const dataField = record2.fields.data?.value;
34917
+ const record3 = response.records[0];
34918
+ const dataField = record3.fields.data?.value;
34384
34919
  if (!dataField) {
34385
34920
  throw new Error("No data in record");
34386
34921
  }
@@ -34414,13 +34949,13 @@ async function findICloudFile(filename) {
34414
34949
  if (!response.records || response.records.length === 0) {
34415
34950
  return null;
34416
34951
  }
34417
- const record2 = response.records[0];
34952
+ const record3 = response.records[0];
34418
34953
  return {
34419
- recordName: record2.recordName,
34420
- filename: record2.fields.filename?.value ?? "",
34421
- modifiedAt: new Date(record2.modified?.timestamp ?? Date.now()),
34422
- backupRevision: record2.fields.backupRevision?.value,
34423
- size: typeof record2.fields.data?.value === "object" && record2.fields.data?.value !== null ? record2.fields.data.value.size : 0
34954
+ recordName: record3.recordName,
34955
+ filename: record3.fields.filename?.value ?? "",
34956
+ modifiedAt: new Date(record3.modified?.timestamp ?? Date.now()),
34957
+ backupRevision: record3.fields.backupRevision?.value,
34958
+ size: typeof record3.fields.data?.value === "object" && record3.fields.data?.value !== null ? record3.fields.data.value.size : 0
34424
34959
  };
34425
34960
  }
34426
34961
 
@@ -35770,13 +36305,13 @@ function useConversationRedactors(database, account, storage, secondaryStorage)
35770
36305
  return useCallback4(
35771
36306
  (conversationId, nerDetector) => {
35772
36307
  if (!scope.active) return retiredRedactor;
35773
- const cached = scope.redactors.get(conversationId);
35774
- if (cached && cached.detector === nerDetector) {
36308
+ const cached2 = scope.redactors.get(conversationId);
36309
+ if (cached2 && cached2.detector === nerDetector) {
35775
36310
  scope.redactors.delete(conversationId);
35776
- scope.redactors.set(conversationId, cached);
35777
- return cached.redactor;
36311
+ scope.redactors.set(conversationId, cached2);
36312
+ return cached2.redactor;
35778
36313
  }
35779
- if (cached) scope.evicted.push(cached.redactor);
36314
+ if (cached2) scope.evicted.push(cached2.redactor);
35780
36315
  const redactor = new PiiRedactor({ nerDetector });
35781
36316
  scope.redactors.set(conversationId, { redactor, detector: nerDetector });
35782
36317
  if (scope.redactors.size > REDACTOR_LIMIT) {
@@ -38233,82 +38768,45 @@ function useChatStorage(options) {
38233
38768
  await inbox.putPublicKey(publicKey);
38234
38769
  registeredInboxKeyRef.current = { inbox, publicKey };
38235
38770
  }
38236
- const results = [];
38237
- for (const item of await inbox.list()) {
38238
- let opened;
38239
- try {
38240
- opened = await openInboxItem(item, keyPair);
38241
- } catch (err) {
38242
- results.push({
38243
- id: item.id,
38244
- conversationId: null,
38245
- status: "unreadable",
38246
- assistantMessage: null,
38247
- error: err instanceof Error ? err.message : String(err)
38771
+ return deliverInboxAnswers({
38772
+ inbox,
38773
+ keyPair,
38774
+ backend,
38775
+ store: async (opened, messageId) => {
38776
+ const { redactor } = resolveCallPii(
38777
+ void 0,
38778
+ piiRedaction,
38779
+ () => getConversationRedactor(opened.conversation_id, nerDetectorRef.current)
38780
+ );
38781
+ const knownToolCallEventIds = await backend.getToolCallEventIds(opened.conversation_id);
38782
+ const { fields, fileIds } = await toAssistantMessageFields(
38783
+ opened.response,
38784
+ opened.conversation_id,
38785
+ knownToolCallEventIds
38786
+ );
38787
+ const upserted = await backend.upsertMessage({
38788
+ ...fields,
38789
+ content: redactor ? redactor.deAnonymize(fields.content) : fields.content,
38790
+ thinking: redactor && fields.thinking ? redactor.deAnonymize(fields.thinking) : fields.thinking,
38791
+ conversationId: opened.conversation_id,
38792
+ role: "assistant",
38793
+ model: opened.model,
38794
+ parentMessageId: opened.parent_message_id ?? void 0,
38795
+ wasStopped: opened.status === "tool_request",
38796
+ uniqueId: messageId
38248
38797
  });
38249
- continue;
38250
- }
38251
- const base = { id: item.id, conversationId: opened.conversation_id };
38252
- try {
38253
- const messageId = opened.assistant_message_id ?? `msg_bg_${opened.inference_id}`;
38254
- const [existing] = await backend.getMessagesByIds([messageId]);
38255
- if (!existing) {
38256
- const parent = opened.parent_message_id;
38257
- const ownsTurn = parent ? (await backend.getMessagesByIds([parent])).length > 0 : await backend.getConversation(opened.conversation_id) !== null;
38258
- if (!ownsTurn) {
38259
- results.push({ ...base, status: "elsewhere", assistantMessage: null });
38260
- continue;
38261
- }
38262
- }
38263
- let stored2 = existing;
38264
- if (!stored2) {
38265
- const { redactor } = resolveCallPii(
38266
- void 0,
38267
- piiRedaction,
38268
- () => getConversationRedactor(opened.conversation_id, nerDetectorRef.current)
38269
- );
38270
- const knownToolCallEventIds = await backend.getToolCallEventIds(opened.conversation_id);
38271
- const { fields, fileIds } = await toAssistantMessageFields(
38272
- opened.response,
38273
- opened.conversation_id,
38274
- knownToolCallEventIds
38275
- );
38276
- stored2 = await backend.createMessage({
38277
- ...fields,
38278
- content: redactor ? redactor.deAnonymize(fields.content) : fields.content,
38279
- thinking: redactor && fields.thinking ? redactor.deAnonymize(fields.thinking) : fields.thinking,
38280
- conversationId: opened.conversation_id,
38281
- role: "assistant",
38282
- model: opened.model,
38283
- parentMessageId: opened.parent_message_id ?? void 0,
38284
- wasStopped: opened.status === "tool_request" ? true : void 0,
38285
- uniqueId: messageId
38286
- });
38287
- if (fileIds.length > 0) {
38288
- try {
38289
- await updateMediaMessageIdBatchOp(mediaCtx, fileIds, stored2.uniqueId);
38290
- } catch (err) {
38291
- getLogger().warn("[useChatStorage] Failed to link inbox media:", err);
38292
- }
38798
+ const stored2 = await clearTurnErrors(backend, upserted);
38799
+ if (fileIds.length > 0) {
38800
+ try {
38801
+ await updateMediaMessageIdBatchOp(mediaCtx, fileIds, stored2.uniqueId);
38802
+ } catch (err) {
38803
+ getLogger().warn("[useChatStorage] Failed to link inbox media:", err);
38293
38804
  }
38294
- void embedMessageAsync(stored2, (text16) => redactor ? redactor.maskText(text16) : text16);
38295
38805
  }
38296
- await inbox.remove(item.id);
38297
- results.push({
38298
- ...base,
38299
- status: existing ? "delivered" : "stored",
38300
- assistantMessage: stored2
38301
- });
38302
- } catch (err) {
38303
- results.push({
38304
- ...base,
38305
- status: "retry",
38306
- assistantMessage: null,
38307
- error: err instanceof Error ? err.message : String(err)
38308
- });
38806
+ void embedMessageAsync(stored2, (text16) => redactor ? redactor.maskText(text16) : text16);
38807
+ return stored2;
38309
38808
  }
38310
- }
38311
- return results;
38809
+ });
38312
38810
  }, [
38313
38811
  inbox,
38314
38812
  walletAddress,
@@ -39308,11 +39806,11 @@ async function fetchAllModelPages(baseUrl, provider, headers, previous, signal)
39308
39806
  return { pages, models, fetchedAt: Date.now() };
39309
39807
  }
39310
39808
  function loadModels(key3, baseUrl, provider, headers, force, signal) {
39311
- const cached = modelsCache.get(key3);
39312
- if (cached && !force && Date.now() - cached.fetchedAt < MODELS_CACHE_TTL_MS) {
39313
- return Promise.resolve([...cached.models]);
39809
+ const cached2 = modelsCache.get(key3);
39810
+ if (cached2 && !force && Date.now() - cached2.fetchedAt < MODELS_CACHE_TTL_MS) {
39811
+ return Promise.resolve([...cached2.models]);
39314
39812
  }
39315
- const shared = (force ? void 0 : modelsInFlight.get(key3)) ?? startSharedRequest(key3, baseUrl, provider, headers, cached);
39813
+ const shared = (force ? void 0 : modelsInFlight.get(key3)) ?? startSharedRequest(key3, baseUrl, provider, headers, cached2);
39316
39814
  return waitForSharedRequest(key3, shared, signal).then((models) => [...models]);
39317
39815
  }
39318
39816
  function startSharedRequest(key3, baseUrl, provider, headers, previous) {
@@ -40165,20 +40663,20 @@ function startObserve(entry, walletAddress) {
40165
40663
  "updated_at"
40166
40664
  ]).subscribe({
40167
40665
  next: (records) => {
40168
- const record2 = records[0];
40169
- if (!record2) return;
40666
+ const record3 = records[0];
40667
+ if (!record3) return;
40170
40668
  const patch = {
40171
40669
  userPreference: {
40172
- uniqueId: record2.id,
40173
- walletAddress: record2.walletAddress,
40174
- nickname: record2.nickname,
40175
- occupation: record2.occupation,
40176
- description: record2.description,
40177
- models: record2.models,
40178
- personality: record2.personality,
40179
- externalWallets: record2.externalWallets,
40180
- createdAt: record2.createdAt,
40181
- updatedAt: record2.updatedAt
40670
+ uniqueId: record3.id,
40671
+ walletAddress: record3.walletAddress,
40672
+ nickname: record3.nickname,
40673
+ occupation: record3.occupation,
40674
+ description: record3.description,
40675
+ models: record3.models,
40676
+ personality: record3.personality,
40677
+ externalWallets: record3.externalWallets,
40678
+ createdAt: record3.createdAt,
40679
+ updatedAt: record3.updatedAt
40182
40680
  }
40183
40681
  };
40184
40682
  if (isInitialEmission) {