@anuma/sdk 10.10.0 → 11.0.1

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.
@@ -2394,9 +2394,9 @@ async function refreshEncryptionKeyIfMatches(walletAddress, probeCiphertext, sig
2394
2394
  return false;
2395
2395
  }
2396
2396
  const startEpoch = sessionEpoch;
2397
- const cached = refreshCandidatesByAddress.get(walletAddress);
2398
- if (cached) {
2399
- return tryCommitCandidatesIfProbeMatches(walletAddress, parsed, cached, startEpoch);
2397
+ const cached2 = refreshCandidatesByAddress.get(walletAddress);
2398
+ if (cached2) {
2399
+ return tryCommitCandidatesIfProbeMatches(walletAddress, parsed, cached2, startEpoch);
2400
2400
  }
2401
2401
  let derivePromise = pendingCandidateDerives.get(walletAddress);
2402
2402
  if (!derivePromise) {
@@ -2748,10 +2748,10 @@ function parsePlaintextToken(raw, walletAddress) {
2748
2748
  return null;
2749
2749
  }
2750
2750
  if (!parsed || typeof parsed !== "object") return null;
2751
- const record2 = parsed;
2752
- const data = record2.token?.accessToken ? record2.token : record2;
2751
+ const record3 = parsed;
2752
+ const data = record3.token?.accessToken ? record3.token : record3;
2753
2753
  if (!data?.accessToken) return null;
2754
- if (record2.wallet && record2.wallet !== walletAddress) return null;
2754
+ if (record3.wallet && record3.wallet !== walletAddress) return null;
2755
2755
  return data;
2756
2756
  }
2757
2757
  function promoteUnscopedRow(raw, data, store, scopedKey, unscopedKey, walletAddress) {
@@ -2843,10 +2843,10 @@ async function discoverOAuthMetadata() {
2843
2843
  }
2844
2844
  async function getOAuthMetadata() {
2845
2845
  if (typeof window !== "undefined") {
2846
- const cached = sessionStorage.getItem(OAUTH_METADATA_KEY);
2847
- if (cached) {
2846
+ const cached2 = sessionStorage.getItem(OAUTH_METADATA_KEY);
2847
+ if (cached2) {
2848
2848
  try {
2849
- return JSON.parse(cached);
2849
+ return JSON.parse(cached2);
2850
2850
  } catch {
2851
2851
  }
2852
2852
  }
@@ -2950,8 +2950,8 @@ async function storeTokenData(data, walletAddress) {
2950
2950
  } catch {
2951
2951
  }
2952
2952
  }
2953
- const record2 = { wallet: walletAddress, token: data };
2954
- sessionStorage.setItem(getTokenStorageKey(walletAddress), JSON.stringify(record2));
2953
+ const record3 = { wallet: walletAddress, token: data };
2954
+ sessionStorage.setItem(getTokenStorageKey(walletAddress), JSON.stringify(record3));
2955
2955
  }
2956
2956
  async function getStoredTokenData(walletAddress) {
2957
2957
  if (typeof window === "undefined") return null;
@@ -3355,25 +3355,25 @@ var TRUNCATION_MARKER_HEAD = "... (tool output truncated, ";
3355
3355
  var TRUNCATION_MARKER_TAIL = " characters omitted)";
3356
3356
  var MAX_PERSISTED_TOOL_RESULT_CHARS = 1e5;
3357
3357
  function buildToolResultContent(results) {
3358
- const entries = results.map(
3358
+ const entries2 = results.map(
3359
3359
  (r) => `Tool "${r.name}" returned: ${JSON.stringify(r.result)}`.replace(/\u2028/g, "\\u2028").replace(/\u2029/g, "\\u2029")
3360
3360
  );
3361
- const framing = HEADER.length + FOOTER.length + ENTRY_SEPARATOR.length * Math.max(0, entries.length - 1);
3362
- const summary = capEntries(entries, MAX_PERSISTED_TOOL_RESULT_CHARS - framing).join(
3361
+ const framing = HEADER.length + FOOTER.length + ENTRY_SEPARATOR.length * Math.max(0, entries2.length - 1);
3362
+ const summary = capEntries(entries2, MAX_PERSISTED_TOOL_RESULT_CHARS - framing).join(
3363
3363
  ENTRY_SEPARATOR
3364
3364
  );
3365
3365
  return `${HEADER}${summary}${FOOTER}`;
3366
3366
  }
3367
- function capToolResultEntries(entries, budget) {
3368
- return capEntries(entries, budget);
3367
+ function capToolResultEntries(entries2, budget) {
3368
+ return capEntries(entries2, budget);
3369
3369
  }
3370
- function capEntries(entries, budget) {
3371
- const smallestFirst = entries.map((_, index) => index).sort((a, b) => entries[a].length - entries[b].length);
3372
- const capped = [...entries];
3370
+ function capEntries(entries2, budget) {
3371
+ const smallestFirst = entries2.map((_, index) => index).sort((a, b) => entries2[a].length - entries2[b].length);
3372
+ const capped = [...entries2];
3373
3373
  let remaining = budget;
3374
- let unassigned = entries.length;
3374
+ let unassigned = entries2.length;
3375
3375
  for (const index of smallestFirst) {
3376
- capped[index] = truncateEntry(entries[index], Math.floor(remaining / unassigned));
3376
+ capped[index] = truncateEntry(entries2[index], Math.floor(remaining / unassigned));
3377
3377
  remaining -= capped[index].length;
3378
3378
  unassigned--;
3379
3379
  }
@@ -4265,11 +4265,11 @@ var ToolCallEventIndex = class {
4265
4265
  this.pending = /* @__PURE__ */ new Map();
4266
4266
  this.resetCount = collection.database._resetCount;
4267
4267
  collection.experimentalSubscribe((changes) => {
4268
- for (const { record: record2, type } of changes) {
4268
+ for (const { record: record3, type } of changes) {
4269
4269
  this.replace(
4270
- record2.id,
4271
- type === "destroyed" ? void 0 : record2.conversationId,
4272
- type === "destroyed" ? void 0 : record2._getRaw("tool_call_events")
4270
+ record3.id,
4271
+ type === "destroyed" ? void 0 : record3.conversationId,
4272
+ type === "destroyed" ? void 0 : record3._getRaw("tool_call_events")
4273
4273
  );
4274
4274
  }
4275
4275
  });
@@ -5712,15 +5712,15 @@ async function searchChunksOp(ctx, queryVector, options) {
5712
5712
  staleSkipped++;
5713
5713
  continue;
5714
5714
  }
5715
- const cached = chunkCache?.get(key3.id);
5716
- if (!cached || cached.version !== key3.version) {
5715
+ const cached2 = chunkCache?.get(key3.id);
5716
+ if (!cached2 || cached2.version !== key3.version) {
5717
5717
  missIds.push(key3.id);
5718
5718
  continue;
5719
5719
  }
5720
5720
  cacheHits++;
5721
- if (cached.chunks.length > 0) {
5722
- for (let ci = 0; ci < cached.chunks.length; ci++) {
5723
- const vec = cached.chunks[ci];
5721
+ if (cached2.chunks.length > 0) {
5722
+ for (let ci = 0; ci < cached2.chunks.length; ci++) {
5723
+ const vec = cached2.chunks[ci];
5724
5724
  if (vec.length === 0) continue;
5725
5725
  const similarity = cosineSimilarity(queryVector, vec);
5726
5726
  if (similarity >= minSimilarity) {
@@ -5733,8 +5733,8 @@ async function searchChunksOp(ctx, queryVector, options) {
5733
5733
  });
5734
5734
  }
5735
5735
  }
5736
- } else if (cached.fallback) {
5737
- const similarity = cosineSimilarity(queryVector, cached.fallback);
5736
+ } else if (cached2.fallback) {
5737
+ const similarity = cosineSimilarity(queryVector, cached2.fallback);
5738
5738
  if (similarity >= minSimilarity) {
5739
5739
  candidates.push({
5740
5740
  id: key3.id,
@@ -6550,11 +6550,11 @@ var mergeConfigs = (a, b) => {
6550
6550
  return config;
6551
6551
  };
6552
6552
  var headersEntries = (headers) => {
6553
- const entries = [];
6553
+ const entries2 = [];
6554
6554
  headers.forEach((value, key3) => {
6555
- entries.push([key3, value]);
6555
+ entries2.push([key3, value]);
6556
6556
  });
6557
- return entries;
6557
+ return entries2;
6558
6558
  };
6559
6559
  var mergeHeaders = (...headers) => {
6560
6560
  const mergedHeaders = new Headers();
@@ -7034,9 +7034,9 @@ async function embedOne(text16, options, outer) {
7034
7034
  const { cache } = options;
7035
7035
  if (!cache) return Array.from(await requestEmbedding(text16, options, outer));
7036
7036
  const model = options.model ?? DEFAULT_API_EMBEDDING_MODEL;
7037
- const cached = cache.get(text16);
7038
- const cachedModel = cached && cachedEmbeddingModels.get(cached);
7039
- if (cached && (cachedModel === void 0 || cachedModel === model)) return Array.from(cached);
7037
+ const cached2 = cache.get(text16);
7038
+ const cachedModel = cached2 && cachedEmbeddingModels.get(cached2);
7039
+ if (cached2 && (cachedModel === void 0 || cachedModel === model)) return Array.from(cached2);
7040
7040
  const inFlight = inFlightByCache.get(cache) ?? /* @__PURE__ */ new Map();
7041
7041
  inFlightByCache.set(cache, inFlight);
7042
7042
  const requestKey = JSON.stringify([model, text16]);
@@ -7151,10 +7151,10 @@ async function embedMany(texts, options, outer) {
7151
7151
  const uncachedTexts = [];
7152
7152
  for (let i = 0; i < texts.length; i++) {
7153
7153
  if (cache) {
7154
- const cached = cache.get(texts[i]);
7155
- const cachedModel = cached && cachedEmbeddingModels.get(cached);
7156
- if (cached && (cachedModel === void 0 || cachedModel === embeddingModel)) {
7157
- results[i] = Array.from(cached);
7154
+ const cached2 = cache.get(texts[i]);
7155
+ const cachedModel = cached2 && cachedEmbeddingModels.get(cached2);
7156
+ if (cached2 && (cachedModel === void 0 || cachedModel === embeddingModel)) {
7157
+ results[i] = Array.from(cached2);
7158
7158
  continue;
7159
7159
  }
7160
7160
  }
@@ -7540,8 +7540,12 @@ function createCryptoPricePreProcessor(options = {}) {
7540
7540
  }
7541
7541
 
7542
7542
  // src/lib/memory/store/remotePersistence.ts
7543
+ init_logger();
7543
7544
  init_portalLlm();
7544
7545
 
7546
+ // src/lib/memory/store/remoteTopics.ts
7547
+ init_logger();
7548
+
7545
7549
  // src/lib/db/entities/types.ts
7546
7550
  var ENTITY_KINDS = [
7547
7551
  "person",
@@ -7598,58 +7602,337 @@ function parseTopics(value) {
7598
7602
  return out;
7599
7603
  }
7600
7604
 
7605
+ // src/lib/memory/store/topicCodec.ts
7606
+ var ciphertextPattern = /^enc:v\d+:[0-9a-f]+$/i;
7607
+ var topicHashPattern = /^[0-9a-f]{64}$/;
7608
+ var MAX_SEALED_TOPIC_NAME_BYTES = 1024;
7609
+ function normalizeTopicName(name) {
7610
+ return normalizeEntityName(name).normalize("NFC");
7611
+ }
7612
+ function sealedTopicNamesFit(json5) {
7613
+ return (entries(json5) ?? []).every(
7614
+ (entry) => !hashed(entry) || typeof entry.name !== "string" || entry.name.length <= MAX_SEALED_TOPIC_NAME_BYTES
7615
+ );
7616
+ }
7617
+ function record(value) {
7618
+ return typeof value === "object" && value !== null && !Array.isArray(value);
7619
+ }
7620
+ function hashed(entry) {
7621
+ return record(entry) && typeof entry.name_hash === "string";
7622
+ }
7623
+ function entries(json5) {
7624
+ if (typeof json5 !== "string") return void 0;
7625
+ try {
7626
+ const parsed = JSON.parse(json5);
7627
+ return Array.isArray(parsed) ? parsed : void 0;
7628
+ } catch {
7629
+ return void 0;
7630
+ }
7631
+ }
7632
+ function cached(cache, key3, load) {
7633
+ let pending = cache.get(key3);
7634
+ if (!pending) {
7635
+ const loading = load();
7636
+ pending = loading;
7637
+ cache.set(key3, loading);
7638
+ loading.catch(() => {
7639
+ if (cache.get(key3) === loading) cache.delete(key3);
7640
+ });
7641
+ }
7642
+ return pending;
7643
+ }
7644
+ function createTopicCodec(cipher) {
7645
+ const hashes = /* @__PURE__ */ new Map();
7646
+ const opened = /* @__PURE__ */ new Map();
7647
+ const seals = /* @__PURE__ */ new Map();
7648
+ const legacyNames = /* @__PURE__ */ new Map();
7649
+ const hash = async (name) => {
7650
+ const normalized2 = normalizeTopicName(name);
7651
+ if (!normalized2) return null;
7652
+ return cached(hashes, normalized2, async () => {
7653
+ const digest = await cipher.hashTopic(normalized2);
7654
+ if (!topicHashPattern.test(digest))
7655
+ throw new Error("Topic hashing must return 64 lowercase hex characters");
7656
+ return digest;
7657
+ });
7658
+ };
7659
+ const seal = async (display) => {
7660
+ const nameHash = await hash(display);
7661
+ if (nameHash === null) return null;
7662
+ return cached(seals, display, async () => {
7663
+ const name = await cipher.encrypt(display);
7664
+ if (name === display || !ciphertextPattern.test(name))
7665
+ throw new Error(
7666
+ "Topic encryption must return SDK ciphertext; refusing to upload plaintext"
7667
+ );
7668
+ opened.set(name, Promise.resolve(display));
7669
+ return { name_hash: nameHash, name };
7670
+ });
7671
+ };
7672
+ const plain2 = (name) => {
7673
+ if (!ciphertextPattern.test(name)) return Promise.resolve(name);
7674
+ let pending = legacyNames.get(name);
7675
+ if (!pending) {
7676
+ pending = cipher.decrypt(name).catch(() => name);
7677
+ legacyNames.set(name, pending);
7678
+ }
7679
+ return pending;
7680
+ };
7681
+ const open = async ({ name, name_hash: nameHash }) => {
7682
+ if (nameHash === void 0) return plain2(name);
7683
+ if (typeof name !== "string" || typeof nameHash !== "string" || !topicHashPattern.test(nameHash) || !ciphertextPattern.test(name))
7684
+ throw new Error("Nearby returned a malformed topic name");
7685
+ const plaintext = await cached(opened, name, async () => {
7686
+ const value = await cipher.decrypt(name);
7687
+ if (value === name) throw new Error("Topic decryption failed");
7688
+ return value;
7689
+ });
7690
+ if (await hash(plaintext) !== nameHash) throw new Error("Topic name does not match its hash");
7691
+ if (!seals.has(plaintext)) seals.set(plaintext, Promise.resolve({ name_hash: nameHash, name }));
7692
+ return plaintext;
7693
+ };
7694
+ return {
7695
+ hash,
7696
+ seal,
7697
+ open,
7698
+ encodeTopics: async (json5) => {
7699
+ const list = entries(json5);
7700
+ if (!list) return json5;
7701
+ const sealed2 = await Promise.all(
7702
+ list.map(async (entry) => {
7703
+ if (!record(entry) || typeof entry.name !== "string") return null;
7704
+ const name = await seal(await plain2(entry.name));
7705
+ return name && { ...entry, name: name.name, name_hash: name.name_hash };
7706
+ })
7707
+ );
7708
+ return JSON.stringify(sealed2.filter((entry) => entry !== null));
7709
+ },
7710
+ decodeTopics: async (json5) => {
7711
+ const list = entries(json5);
7712
+ if (!list?.some(
7713
+ (entry) => hashed(entry) || record(entry) && typeof entry.name === "string" && ciphertextPattern.test(entry.name)
7714
+ ))
7715
+ return json5;
7716
+ const decoded = await Promise.all(
7717
+ list.map(async (entry) => {
7718
+ if (!hashed(entry))
7719
+ return record(entry) && typeof entry.name === "string" ? { ...entry, name: await plain2(entry.name) } : entry;
7720
+ const { name_hash: nameHash, ...rest } = entry;
7721
+ return { ...rest, name: await open({ name: entry.name, name_hash: nameHash }) };
7722
+ })
7723
+ );
7724
+ return JSON.stringify(decoded);
7725
+ },
7726
+ isLegacy: (json5) => (entries(json5) ?? []).some(
7727
+ (entry) => record(entry) && typeof entry.name === "string" && !hashed(entry)
7728
+ ),
7729
+ matchesLegacy: async (json5, names, hashes2) => {
7730
+ const list = typeof json5 === "string" ? entries(json5) ?? [] : [];
7731
+ if (list.some((entry) => hashed(entry) && hashes2.has(entry.name_hash))) return false;
7732
+ const legacy = await Promise.all(
7733
+ list.map(
7734
+ async (entry) => record(entry) && typeof entry.name === "string" && !hashed(entry) ? normalizeTopicName(await plain2(entry.name)) : null
7735
+ )
7736
+ );
7737
+ return legacy.some((name) => name !== null && names.has(name));
7738
+ },
7739
+ encodeCatalog: async (topic2) => {
7740
+ const sealed2 = await seal(normalizeTopicName(await plain2(topic2.name)));
7741
+ return sealed2 && { ...topic2, name: sealed2.name, name_hash: sealed2.name_hash };
7742
+ },
7743
+ decodeCatalog: async (item) => {
7744
+ const { name_hash: nameHash, ...rest } = item;
7745
+ return { ...rest, name: await open({ name: item.name, name_hash: nameHash }) };
7746
+ }
7747
+ };
7748
+ }
7749
+
7601
7750
  // src/lib/memory/store/remoteTopics.ts
7751
+ var RETIRE_CONCURRENCY = 8;
7602
7752
  function topic(value) {
7603
7753
  const t = value;
7604
- 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")
7754
+ 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")
7605
7755
  throw new Error("Invalid nearby topic");
7606
7756
  return t;
7607
7757
  }
7608
- function createRemoteTopicPersistence(request) {
7758
+ async function wireTopics(request, signal) {
7759
+ const out = [];
7760
+ let cursor;
7761
+ do {
7762
+ const page = await request(
7763
+ "/topics?limit=200" + (cursor ? `&cursor=${encodeURIComponent(cursor)}` : ""),
7764
+ {},
7765
+ signal
7766
+ );
7767
+ if (!Array.isArray(page.items) || page.next_cursor !== void 0 && typeof page.next_cursor !== "string")
7768
+ throw new Error("Invalid nearby topic page");
7769
+ out.push(...page.items.map(topic));
7770
+ cursor = page.next_cursor;
7771
+ } while (cursor);
7772
+ return out;
7773
+ }
7774
+ function hashesOf(items) {
7775
+ return new Set(items.flatMap((t) => t.name_hash === void 0 ? [] : [t.name_hash]));
7776
+ }
7777
+ async function sealedImport(request, codec, topics, signal) {
7778
+ let oversized = 0;
7779
+ for (let i = 0; i < topics.length; i += 50) {
7780
+ signal?.throwIfAborted();
7781
+ const sealed2 = (await Promise.all(topics.slice(i, i + 50).map((t) => codec.encodeCatalog(t)))).filter((t) => {
7782
+ if (t === null) return false;
7783
+ if (t.name.length <= MAX_SEALED_TOPIC_NAME_BYTES) return true;
7784
+ oversized++;
7785
+ return false;
7786
+ });
7787
+ if (sealed2.length)
7788
+ await request(
7789
+ "/topics/import",
7790
+ { method: "POST", body: JSON.stringify({ topics: sealed2 }) },
7791
+ signal
7792
+ );
7793
+ }
7794
+ signal?.throwIfAborted();
7795
+ if (oversized)
7796
+ getLogger().warn(
7797
+ `[memory/remote] Skipped ${oversized} topic catalog entries whose sealed name exceeds ${MAX_SEALED_TOPIC_NAME_BYTES} bytes`
7798
+ );
7799
+ }
7800
+ function createRemoteTopicPersistence(request, codec) {
7801
+ let legacyOnly = /* @__PURE__ */ new Set();
7609
7802
  return {
7610
7803
  topics: async () => {
7611
- const out = [];
7612
- let cursor;
7613
- do {
7614
- const page = await request(
7615
- "/topics?limit=200" + (cursor ? `&cursor=${encodeURIComponent(cursor)}` : ""),
7616
- {}
7617
- );
7618
- if (!Array.isArray(page.items) || page.next_cursor !== void 0 && typeof page.next_cursor !== "string")
7619
- throw new Error("Invalid nearby topic page");
7620
- out.push(...page.items.map(topic));
7621
- cursor = page.next_cursor;
7622
- } while (cursor);
7623
- return out;
7804
+ const items = await wireTopics(request);
7805
+ const hashed2 = hashesOf(items);
7806
+ const legacy = /* @__PURE__ */ new Set();
7807
+ const decoded = await Promise.all(
7808
+ items.map(async (item) => {
7809
+ const plain2 = await codec.decodeCatalog(item);
7810
+ const name = normalizeTopicName(plain2.name);
7811
+ if (item.name_hash === void 0) {
7812
+ const hash = await codec.hash(name);
7813
+ if (hash !== null && hashed2.has(hash)) return null;
7814
+ legacy.add(name);
7815
+ }
7816
+ return { ...plain2, name };
7817
+ })
7818
+ );
7819
+ legacyOnly = legacy;
7820
+ return decoded.filter((t) => t !== null);
7624
7821
  },
7625
7822
  putTopic: async (value, expectedVersion) => {
7626
7823
  if (!Number.isSafeInteger(expectedVersion) || expectedVersion < 0)
7627
7824
  throw new Error("Expected topic version must be a nonnegative integer");
7628
- return topic(
7825
+ const sealed2 = await codec.encodeCatalog(value);
7826
+ if (!sealed2) throw new Error("Topic name must not be empty");
7827
+ const saved = topic(
7629
7828
  await request("/topics", {
7630
7829
  method: "PUT",
7631
- body: JSON.stringify({ topic: value, expected_version: expectedVersion })
7830
+ body: JSON.stringify({
7831
+ topic: sealed2,
7832
+ expected_version: legacyOnly.has(normalizeTopicName(value.name)) ? 0 : expectedVersion
7833
+ })
7632
7834
  })
7633
7835
  );
7634
- },
7635
- importTopics: async (topics, signal) => {
7636
- for (let i = 0; i < topics.length; i += 50) {
7637
- signal?.throwIfAborted();
7638
- await request(
7639
- "/topics/import",
7640
- {
7641
- method: "POST",
7642
- body: JSON.stringify({ topics: topics.slice(i, i + 50) })
7643
- },
7644
- signal
7645
- );
7646
- }
7836
+ const decoded = await codec.decodeCatalog(saved);
7837
+ legacyOnly.delete(decoded.name);
7838
+ return decoded;
7839
+ },
7840
+ importTopics: (topics, signal) => sealedImport(
7841
+ request,
7842
+ codec,
7843
+ topics.map(({ name, kind }) => ({ name, ...kind !== void 0 && { kind } })),
7844
+ signal
7845
+ )
7846
+ };
7847
+ }
7848
+ async function retireLegacyTopics(request, codec, topics, imported, signal) {
7849
+ const failures = [];
7850
+ const put = async (topic2, expectedVersion) => {
7851
+ try {
7852
+ await request(
7853
+ "/topics",
7854
+ { method: "PUT", body: JSON.stringify({ topic: topic2, expected_version: expectedVersion }) },
7855
+ signal
7856
+ );
7857
+ return "saved";
7858
+ } catch (error) {
7859
+ if (signal?.aborted) throw error;
7860
+ if (error instanceof RemoteMemoryError && error.status === 409) return "conflict";
7861
+ failures.push(error);
7862
+ return "failed";
7863
+ }
7864
+ };
7865
+ const retire = (item) => put(
7866
+ { name: item.name, ...item.kind !== void 0 && { kind: item.kind }, is_deleted: true },
7867
+ item.version
7868
+ );
7869
+ const changed = [];
7870
+ let next = 0;
7871
+ const worker = async () => {
7872
+ while (next < topics.length) {
7647
7873
  signal?.throwIfAborted();
7874
+ const item = topics[next++];
7875
+ if (await retire(item) === "conflict") changed.push(item);
7648
7876
  }
7649
7877
  };
7878
+ await Promise.all(
7879
+ Array.from({ length: Math.min(RETIRE_CONCURRENCY, topics.length) }, () => worker())
7880
+ );
7881
+ if (changed.length) {
7882
+ const current = await wireTopics(request, signal);
7883
+ for (const stale of changed) {
7884
+ const legacy = current.find((t) => t.name_hash === void 0 && t.name === stale.name);
7885
+ if (!legacy || legacy.is_deleted) continue;
7886
+ const hash = await codec.hash(await codec.open(legacy));
7887
+ const copy = current.find((t) => t.name_hash !== void 0 && t.name_hash === hash);
7888
+ if (!copy || hash === null) continue;
7889
+ const newer = imported.has(hash) || Date.parse(legacy.server_updated_at) > Date.parse(copy.server_updated_at);
7890
+ if (newer && (copy.is_deleted || legacy.kind !== copy.kind)) {
7891
+ const sealed2 = await codec.encodeCatalog({
7892
+ name: legacy.name,
7893
+ ...legacy.kind !== void 0 && { kind: legacy.kind },
7894
+ is_deleted: false
7895
+ });
7896
+ if (!sealed2 || await put(sealed2, copy.version) !== "saved") continue;
7897
+ }
7898
+ await retire(legacy);
7899
+ }
7900
+ }
7901
+ if (failures.length)
7902
+ getLogger().warn(
7903
+ `[memory/remote] Could not retire ${failures.length} upgraded topic catalog entries:`,
7904
+ failures[0]
7905
+ );
7906
+ }
7907
+ async function upgradeLegacyTopicCatalog(request, codec, signal) {
7908
+ const items = await wireTopics(request, signal);
7909
+ const hashed2 = hashesOf(items);
7910
+ const hashes = await Promise.all(
7911
+ items.map(
7912
+ async (item) => item.name_hash === void 0 ? codec.hash(await codec.open(item)) : null
7913
+ )
7914
+ );
7915
+ const sources = /* @__PURE__ */ new Map();
7916
+ const live2 = [];
7917
+ items.forEach((item, i) => {
7918
+ const hash = hashes[i];
7919
+ if (hash === null) return;
7920
+ if (!item.is_deleted) live2.push(item);
7921
+ if (hashed2.has(hash)) return;
7922
+ const source = sources.get(hash);
7923
+ if (!source || source.is_deleted && !item.is_deleted) sources.set(hash, item);
7924
+ });
7925
+ const legacy = [...sources.values()].map((item) => ({
7926
+ name: item.name,
7927
+ ...item.kind !== void 0 && { kind: item.kind },
7928
+ ...item.is_deleted && { is_deleted: true }
7929
+ }));
7930
+ await sealedImport(request, codec, legacy, signal);
7931
+ await retireLegacyTopics(request, codec, live2, new Set(sources.keys()), signal);
7932
+ return legacy.length;
7650
7933
  }
7651
7934
  async function createRemoteTopic(persistence, name) {
7652
- const canonical = normalizeEntityName(name);
7935
+ const canonical = normalizeTopicName(name);
7653
7936
  if (!canonical) return null;
7654
7937
  const existing = (await persistence.topics()).find((t) => t.name === canonical);
7655
7938
  if (existing && !existing.is_deleted) return canonical;
@@ -7738,7 +8021,10 @@ var RemoteMemoryError = class extends Error {
7738
8021
  this.name = "RemoteMemoryError";
7739
8022
  }
7740
8023
  };
7741
- var ciphertextPattern = /^enc:v\d+:[0-9a-f]+$/i;
8024
+ var TOPIC_UPGRADE_PROCESSOR = "topic-hash-v1";
8025
+ var TOPIC_UPGRADE_PAGE = 50;
8026
+ var LEGACY_TOPIC_CURSOR = "legacy-topics:";
8027
+ var LEGACY_TOPIC_RECHECK_MS = 6e4;
7742
8028
  var memoryFields = {
7743
8029
  memory_id: true,
7744
8030
  content: true,
@@ -7798,7 +8084,8 @@ var queryFields = [
7798
8084
  "fact_types",
7799
8085
  "visibility",
7800
8086
  "memory_ids",
7801
- "topics",
8087
+ "topic_hashes",
8088
+ "topics_legacy",
7802
8089
  "updated_after",
7803
8090
  "topics_due",
7804
8091
  "topics_extracted",
@@ -7808,11 +8095,17 @@ var queryFields = [
7808
8095
  "limit",
7809
8096
  "include_embeddings"
7810
8097
  ];
7811
- function record(value) {
8098
+ function isVersionConflict(error) {
8099
+ return error instanceof RemoteMemoryError && error.code === "version_conflict";
8100
+ }
8101
+ function isRejectedRow(error) {
8102
+ return error instanceof RemoteMemoryError && error.status === 400;
8103
+ }
8104
+ function record2(value) {
7812
8105
  return typeof value === "object" && value !== null && !Array.isArray(value);
7813
8106
  }
7814
8107
  function memoryRecord(value) {
7815
- 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))) {
8108
+ 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))) {
7816
8109
  throw new Error("Invalid nearby private-memory response");
7817
8110
  }
7818
8111
  return value;
@@ -7892,14 +8185,14 @@ function createNearbyRequest(options, apiPath = "/api/private-memories") {
7892
8185
  const body = await response.json().catch(() => null);
7893
8186
  const retryAfter = parseRetryAfterMs(response.headers.get("Retry-After"));
7894
8187
  const error = new RemoteMemoryError(
7895
- record(body) && typeof body.detail === "string" ? body.detail : `Nearby request failed (${response.status})`,
8188
+ record2(body) && typeof body.detail === "string" ? body.detail : `Nearby request failed (${response.status})`,
7896
8189
  response.status,
7897
- record(body) && typeof body.code === "string" ? body.code : void 0,
8190
+ record2(body) && typeof body.code === "string" ? body.code : void 0,
7898
8191
  retryAfter ?? void 0,
7899
- record(body) && typeof body.rate_limit_bucket === "string" ? body.rate_limit_bucket : void 0
8192
+ record2(body) && typeof body.rate_limit_bucket === "string" ? body.rate_limit_bucket : void 0
7900
8193
  );
7901
8194
  if (response.status === 429 && retryAfter !== null && retryAfter > 0 && (!error.code || error.code === "rate_limited")) {
7902
- const bucket = error.rateLimitBucket && budgets.includes(error.rateLimitBucket) ? error.rateLimitBucket : record(body) && (body.limit_scope === "account" || body.limit_scope === "ip") && !error.rateLimitBucket ? "*" : route;
8195
+ const bucket = error.rateLimitBucket && budgets.includes(error.rateLimitBucket) ? error.rateLimitBucket : record2(body) && (body.limit_scope === "account" || body.limit_scope === "ip") && !error.rateLimitBucket ? "*" : route;
7903
8196
  cooldowns.set(bucket, { until: Date.now() + retryAfter, error });
7904
8197
  }
7905
8198
  throw error;
@@ -7922,7 +8215,7 @@ async function createRemoteMemoryPersistence(options) {
7922
8215
  throw new Error("A canonical keyId is required");
7923
8216
  const request = createNearbyRequest(options);
7924
8217
  const account = await request("/account", {}, options.signal);
7925
- if (!record(account) || account.state !== "active") {
8218
+ if (!record2(account) || account.state !== "active") {
7926
8219
  throw new RemoteMemoryError(
7927
8220
  "Complete and verify migration before using remote memories",
7928
8221
  409,
@@ -7936,6 +8229,25 @@ async function createRemoteMemoryPersistence(options) {
7936
8229
  "key_mismatch"
7937
8230
  );
7938
8231
  }
8232
+ const codec = createTopicCodec(options);
8233
+ let legacyTopicRows = typeof account.legacy_topic_memories === "number" && account.legacy_topic_memories > 0;
8234
+ if (typeof account.legacy_topic_catalog === "number" && account.legacy_topic_catalog > 0)
8235
+ void upgradeLegacyTopicCatalog(request, codec, options.signal).catch((error) => {
8236
+ if (!options.signal?.aborted)
8237
+ getLogger().warn("[memory/remote] Topic catalog upgrade failed:", error);
8238
+ });
8239
+ let legacyCheckedAt = Date.now();
8240
+ let legacyCheck;
8241
+ const recheckLegacyTopicRows = () => {
8242
+ if (legacyCheck || Date.now() - legacyCheckedAt < LEGACY_TOPIC_RECHECK_MS) return;
8243
+ legacyCheckedAt = Date.now();
8244
+ legacyCheck = request("/account", {}, options.signal).then((current) => {
8245
+ if (record2(current) && current.legacy_topic_memories === 0) legacyTopicRows = false;
8246
+ }).catch(() => {
8247
+ }).finally(() => {
8248
+ legacyCheck = void 0;
8249
+ });
8250
+ };
7939
8251
  const snapshots = /* @__PURE__ */ new WeakMap();
7940
8252
  const decode = async (value) => {
7941
8253
  const item = memoryRecord(value);
@@ -7953,6 +8265,9 @@ async function createRemoteMemoryPersistence(options) {
7953
8265
  content: item.memory.is_deleted && item.memory.content === "" ? "" : await decrypt(item.memory.content),
7954
8266
  ...item.memory.kind_value !== void 0 && {
7955
8267
  kind_value: await decrypt(item.memory.kind_value)
8268
+ },
8269
+ ...item.memory.topics !== void 0 && {
8270
+ topics: await codec.decodeTopics(item.memory.topics)
7956
8271
  }
7957
8272
  }
7958
8273
  };
@@ -7964,8 +8279,10 @@ async function createRemoteMemoryPersistence(options) {
7964
8279
  version: item.version,
7965
8280
  content: decoded.memory.content,
7966
8281
  kindValue: decoded.memory.kind_value,
8282
+ topics: decoded.memory.topics,
7967
8283
  encryptedContent: item.memory.content,
7968
- encryptedKindValue: item.memory.kind_value
8284
+ encryptedKindValue: item.memory.kind_value,
8285
+ encryptedTopics: item.memory.topics
7969
8286
  });
7970
8287
  return decoded;
7971
8288
  };
@@ -7987,7 +8304,7 @@ async function createRemoteMemoryPersistence(options) {
7987
8304
  };
7988
8305
  const decodeCommitted = async (value, write) => {
7989
8306
  const item = memoryRecord(value);
7990
- 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)
8307
+ 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)
7991
8308
  return decode(item);
7992
8309
  return remember(
7993
8310
  {
@@ -7995,7 +8312,8 @@ async function createRemoteMemoryPersistence(options) {
7995
8312
  memory: {
7996
8313
  ...item.memory,
7997
8314
  content: write.content,
7998
- ...write.kindValue !== void 0 && { kind_value: write.kindValue }
8315
+ ...write.kindValue !== void 0 && { kind_value: write.kindValue },
8316
+ ...write.topics !== void 0 && { topics: write.topics }
7999
8317
  }
8000
8318
  },
8001
8319
  item
@@ -8047,13 +8365,21 @@ async function createRemoteMemoryPersistence(options) {
8047
8365
  const reusableContent = snapshot?.encryptedContent ?? existing?.memory.content;
8048
8366
  const content = reusableContent && (snapshot?.content ?? decoded?.memory.content) === memory.content ? reusableContent : await encryptField2(memory.content);
8049
8367
  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);
8368
+ const wireTopics2 = snapshot ? snapshot.encryptedTopics : existing?.memory.topics;
8369
+ 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);
8050
8370
  return {
8051
8371
  body: {
8052
8372
  expected_version: expectedVersion,
8053
- memory: { ...memory, content, ...kindValue !== void 0 && { kind_value: kindValue } }
8373
+ memory: {
8374
+ ...memory,
8375
+ content,
8376
+ ...kindValue !== void 0 && { kind_value: kindValue },
8377
+ ...topics !== void 0 && { topics }
8378
+ }
8054
8379
  },
8055
8380
  content: memory.content,
8056
- kindValue: memory.kind_value
8381
+ kindValue: memory.kind_value,
8382
+ topics: memory.topics
8057
8383
  };
8058
8384
  };
8059
8385
  const fetchCandidates = async (embedding2, candidateOptions, withCounts) => {
@@ -8102,32 +8428,72 @@ async function createRemoteMemoryPersistence(options) {
8102
8428
  },
8103
8429
  candidateOptions.signal
8104
8430
  );
8105
- if (!record(result) || !Array.isArray(result.items))
8431
+ if (!record2(result) || !Array.isArray(result.items))
8106
8432
  throw new Error("Invalid nearby candidate response");
8107
8433
  return result;
8108
8434
  };
8109
8435
  const fetchQueryPage = async (queryOptions) => {
8110
- const { signal, ...query } = queryOptions;
8111
- if (query.limit !== void 0 && (!Number.isInteger(query.limit) || query.limit < 1 || query.limit > 200))
8436
+ const { signal, topics: names, ...wire2 } = queryOptions;
8437
+ if (wire2.limit !== void 0 && (!Number.isInteger(wire2.limit) || wire2.limit < 1 || wire2.limit > 200))
8112
8438
  throw new Error("Page limit must be 1\u2013200");
8113
8439
  for (const [key3, max] of queryListLimits) {
8114
- const values = query[key3];
8440
+ const values = queryOptions[key3];
8115
8441
  if (values && values.length > max)
8116
8442
  throw new Error(`Query ${key3} accepts at most ${max} entries (got ${values.length})`);
8117
8443
  }
8444
+ const body = wire2;
8445
+ if (names === void 0) return postQuery(body, signal);
8446
+ const hashes = [
8447
+ ...new Set(
8448
+ (await Promise.all(names.map((name) => codec.hash(name)))).filter((h) => h !== null)
8449
+ )
8450
+ ];
8451
+ if (names.length > 0 && hashes.length === 0) return { items: [] };
8452
+ if (hashes.length > 0 && wire2.cursor?.startsWith(LEGACY_TOPIC_CURSOR)) {
8453
+ const page2 = await postQuery(
8454
+ {
8455
+ ...wire2,
8456
+ cursor: wire2.cursor.slice(LEGACY_TOPIC_CURSOR.length) || void 0,
8457
+ topics_legacy: true
8458
+ },
8459
+ signal
8460
+ );
8461
+ const wanted = new Set(names.map(normalizeTopicName));
8462
+ const hashed2 = new Set(hashes);
8463
+ const matches = await Promise.all(
8464
+ page2.items.map(
8465
+ (item) => codec.matchesLegacy(
8466
+ record2(item) && record2(item.memory) ? item.memory.topics : void 0,
8467
+ wanted,
8468
+ hashed2
8469
+ )
8470
+ )
8471
+ );
8472
+ return {
8473
+ ...page2,
8474
+ items: page2.items.filter((_, i) => matches[i]),
8475
+ next_cursor: page2.next_cursor === void 0 ? void 0 : LEGACY_TOPIC_CURSOR + page2.next_cursor
8476
+ };
8477
+ }
8478
+ const page = await postQuery({ ...body, topic_hashes: hashes }, signal);
8479
+ if (hashes.length === 0 || page.next_cursor !== void 0 || !legacyTopicRows) return page;
8480
+ recheckLegacyTopicRows();
8481
+ return { ...page, next_cursor: LEGACY_TOPIC_CURSOR };
8482
+ };
8483
+ const postQuery = async (body, signal) => {
8118
8484
  const page = await request(
8119
8485
  "/memories/query",
8120
8486
  {
8121
8487
  method: "POST",
8122
8488
  body: JSON.stringify(
8123
8489
  Object.fromEntries(
8124
- queryFields.filter((key3) => query[key3] !== void 0).map((key3) => [key3, query[key3]])
8490
+ queryFields.filter((key3) => body[key3] !== void 0).map((key3) => [key3, body[key3]])
8125
8491
  )
8126
8492
  )
8127
8493
  },
8128
8494
  signal
8129
8495
  );
8130
- 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")
8496
+ 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")
8131
8497
  throw new Error("Invalid nearby private-memory page");
8132
8498
  return page;
8133
8499
  };
@@ -8141,13 +8507,13 @@ async function createRemoteMemoryPersistence(options) {
8141
8507
  unavailable_count: result.unavailable_count
8142
8508
  };
8143
8509
  };
8144
- return {
8145
- ...createRemoteTopicPersistence(request),
8510
+ const persistence = {
8511
+ ...createRemoteTopicPersistence(request, codec),
8146
8512
  ...createRemoteWorkPersistence(request),
8147
8513
  supportsRealtimeChanges: account.realtime_changes === true,
8148
8514
  counts: async () => {
8149
8515
  const result = await request("/counts", {});
8150
- if (!record(result) || ["live", "archived", "quarantined"].some(
8516
+ if (!record2(result) || ["live", "archived", "quarantined"].some(
8151
8517
  (key3) => !Number.isSafeInteger(result[key3]) || result[key3] < 0
8152
8518
  ))
8153
8519
  throw new Error("Invalid nearby memory counts");
@@ -8164,8 +8530,8 @@ async function createRemoteMemoryPersistence(options) {
8164
8530
  method: "POST",
8165
8531
  body: JSON.stringify({ ...window2, limit })
8166
8532
  });
8167
- if (!record(result) || !Array.isArray(result.items) || result.items.some(
8168
- (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
8533
+ if (!record2(result) || !Array.isArray(result.items) || result.items.some(
8534
+ (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
8169
8535
  ))
8170
8536
  throw new Error("Invalid nearby temporal candidates");
8171
8537
  return result.items.map((item) => item.memory_id);
@@ -8196,7 +8562,7 @@ async function createRemoteMemoryPersistence(options) {
8196
8562
  if (query[key3] !== void 0) params.set(key3, String(query[key3]));
8197
8563
  }
8198
8564
  const page = await request("/memories?" + params.toString(), {}, signal);
8199
- if (!record(page) || !Array.isArray(page.items) || page.next_cursor !== void 0 && typeof page.next_cursor !== "string") {
8565
+ if (!record2(page) || !Array.isArray(page.items) || page.next_cursor !== void 0 && typeof page.next_cursor !== "string") {
8200
8566
  throw new Error("Invalid nearby private-memory page");
8201
8567
  }
8202
8568
  return {
@@ -8236,7 +8602,7 @@ async function createRemoteMemoryPersistence(options) {
8236
8602
  },
8237
8603
  signal
8238
8604
  );
8239
- if (!record(result) || !Array.isArray(result.items) || result.items.length !== prepared.length)
8605
+ if (!record2(result) || !Array.isArray(result.items) || result.items.length !== prepared.length)
8240
8606
  throw new Error("Invalid nearby batch response");
8241
8607
  return Promise.all(result.items.map((item, i) => decodeCommitted(item, prepared[i])));
8242
8608
  },
@@ -8251,20 +8617,87 @@ async function createRemoteMemoryPersistence(options) {
8251
8617
  queryMetadata: async (queryOptions = {}) => {
8252
8618
  const page = await fetchQueryPage(queryOptions);
8253
8619
  return {
8254
- items: page.items.map((item) => {
8255
- const {
8256
- memory: { content: _content, kind_value: _kindValue, ...memory },
8257
- version,
8258
- server_updated_at
8259
- } = memoryRecord(item);
8260
- return { memory, version, server_updated_at };
8261
- }),
8620
+ items: await Promise.all(
8621
+ page.items.map(async (item) => {
8622
+ const {
8623
+ memory: { content: _content, kind_value: _kindValue, topics, ...memory },
8624
+ version,
8625
+ server_updated_at
8626
+ } = memoryRecord(item);
8627
+ const plain2 = topics === void 0 ? void 0 : await codec.decodeTopics(topics).catch(() => null);
8628
+ return {
8629
+ memory: { ...memory, ...typeof plain2 === "string" && { topics: plain2 } },
8630
+ version,
8631
+ server_updated_at
8632
+ };
8633
+ })
8634
+ ),
8262
8635
  ...page.next_cursor !== void 0 && { next_cursor: page.next_cursor }
8263
8636
  };
8264
8637
  },
8265
8638
  candidateSet,
8266
8639
  candidates: async (embedding2, candidateOptions = {}) => decodeAll((await fetchCandidates(embedding2, candidateOptions, false)).items)
8267
8640
  };
8641
+ let rejectedRows = 0;
8642
+ const rewriteLegacyTopics = async (records, token) => {
8643
+ const write = (batch) => persistence.putMany(
8644
+ batch.map((item) => ({ memory: item.memory, expectedVersion: item })),
8645
+ options.signal,
8646
+ token
8647
+ );
8648
+ try {
8649
+ await write(records);
8650
+ return true;
8651
+ } catch (error) {
8652
+ if (!isVersionConflict(error) && !isRejectedRow(error)) throw error;
8653
+ if (records.length === 1) {
8654
+ if (isRejectedRow(error)) rejectedRows++;
8655
+ return false;
8656
+ }
8657
+ let complete = true;
8658
+ for (const item of records)
8659
+ await write([item]).catch((rowError) => {
8660
+ if (isRejectedRow(rowError)) rejectedRows++;
8661
+ else if (!isVersionConflict(rowError)) throw rowError;
8662
+ complete = false;
8663
+ });
8664
+ return complete;
8665
+ }
8666
+ };
8667
+ const upgradeLegacyTopics = () => withRemoteWorkLease(persistence, "topics", TOPIC_UPGRADE_PROCESSOR, async (token, lease) => {
8668
+ let cursor;
8669
+ let complete = true;
8670
+ do {
8671
+ options.signal?.throwIfAborted();
8672
+ if (lease.aborted) return false;
8673
+ const page = await fetchQueryPage({
8674
+ topics_legacy: true,
8675
+ include_archived: true,
8676
+ include_quarantined: true,
8677
+ include_superseded: true,
8678
+ limit: TOPIC_UPGRADE_PAGE,
8679
+ ...cursor !== void 0 && { cursor },
8680
+ signal: options.signal
8681
+ });
8682
+ const { items } = await decodeAll(page.items);
8683
+ const legacy = items.filter((item) => codec.isLegacy(snapshots.get(item)?.encryptedTopics));
8684
+ if (legacy.length && !await rewriteLegacyTopics(legacy, token)) complete = false;
8685
+ cursor = page.next_cursor;
8686
+ } while (cursor);
8687
+ if (rejectedRows)
8688
+ getLogger().warn(
8689
+ `[memory/remote] Nearby rejected ${rejectedRows} rows during the topic upgrade; they keep legacy topics`
8690
+ );
8691
+ return complete;
8692
+ });
8693
+ if (legacyTopicRows)
8694
+ void upgradeLegacyTopics().then((complete) => {
8695
+ if (complete) legacyTopicRows = false;
8696
+ }).catch((error) => {
8697
+ if (!options.signal?.aborted)
8698
+ getLogger().warn("[memory/remote] Topic upgrade failed:", error);
8699
+ });
8700
+ return persistence;
8268
8701
  }
8269
8702
 
8270
8703
  // src/lib/chat/inbox.ts
@@ -8826,9 +9259,9 @@ function toResponsesFormat(tool) {
8826
9259
  function getCachedServerTools() {
8827
9260
  if (typeof localStorage === "undefined") return null;
8828
9261
  try {
8829
- const cached = localStorage.getItem(SERVER_TOOLS_CACHE_KEY);
8830
- if (!cached) return null;
8831
- const parsed = JSON.parse(cached);
9262
+ const cached2 = localStorage.getItem(SERVER_TOOLS_CACHE_KEY);
9263
+ if (!cached2) return null;
9264
+ const parsed = JSON.parse(cached2);
8832
9265
  if (parsed.version !== CACHE_VERSION) {
8833
9266
  removeLocalStorageCache();
8834
9267
  return null;
@@ -8872,8 +9305,8 @@ function clearServerToolsCache(cache = localStorageToolsCache) {
8872
9305
  return cache.clear?.();
8873
9306
  }
8874
9307
  function getToolsChecksum2(cache = localStorageToolsCache) {
8875
- const cached = cache.get();
8876
- return cached instanceof Promise ? cached.then((c) => c?.checksum) : cached?.checksum;
9308
+ const cached2 = cache.get();
9309
+ return cached2 instanceof Promise ? cached2.then((c) => c?.checksum) : cached2?.checksum;
8877
9310
  }
8878
9311
  function shouldRefreshTools(responseChecksum, cache = localStorageToolsCache) {
8879
9312
  if (!responseChecksum) {
@@ -8936,33 +9369,33 @@ async function getServerTools(options) {
8936
9369
  } catch (error) {
8937
9370
  getLogger().warn("[serverTools] Cache read failed; falling through to server fetch:", error);
8938
9371
  }
8939
- const cached = rawCached && rawCached.version === CACHE_VERSION ? rawCached : null;
8940
- const cacheValid = !isCacheExpired(cached, cacheExpirationMs);
8941
- if (cached && cacheValid && !forceRefresh) {
8942
- return cached.tools;
9372
+ const cached2 = rawCached && rawCached.version === CACHE_VERSION ? rawCached : null;
9373
+ const cacheValid = !isCacheExpired(cached2, cacheExpirationMs);
9374
+ if (cached2 && cacheValid && !forceRefresh) {
9375
+ return cached2.tools;
8943
9376
  }
8944
9377
  try {
8945
9378
  const { BASE_URL: BASE_URL2 } = await Promise.resolve().then(() => (init_clientConfig(), clientConfig_exports));
8946
9379
  const effectiveBaseUrl = baseUrl ?? BASE_URL2;
8947
- const validator = cached && !forceRefresh ? cached.etag : void 0;
9380
+ const validator = cached2 && !forceRefresh ? cached2.etag : void 0;
8948
9381
  let authHeaders;
8949
9382
  if (apiKey) {
8950
9383
  authHeaders = { "X-API-Key": apiKey };
8951
9384
  } else {
8952
9385
  if (!getToken) {
8953
9386
  getLogger().warn("[serverTools] No auth method available for fetching tools");
8954
- return cached?.tools ?? [];
9387
+ return cached2?.tools ?? [];
8955
9388
  }
8956
9389
  const token = await getToken();
8957
9390
  if (!token) {
8958
9391
  getLogger().warn("[serverTools] No auth token available for fetching tools");
8959
- return cached?.tools ?? [];
9392
+ return cached2?.tools ?? [];
8960
9393
  }
8961
9394
  authHeaders = { Authorization: `Bearer ${token}` };
8962
9395
  }
8963
9396
  const result = await fetchServerToolsFromApi(effectiveBaseUrl, authHeaders, validator);
8964
9397
  if (result.notModified) {
8965
- const confirmed = cached;
9398
+ const confirmed = cached2;
8966
9399
  await persistCache({ ...confirmed, timestamp: Date.now() });
8967
9400
  return confirmed.tools;
8968
9401
  }
@@ -8970,9 +9403,9 @@ async function getServerTools(options) {
8970
9403
  return result.tools;
8971
9404
  } catch (error) {
8972
9405
  getLogger().error("[serverTools] Failed to fetch server tools:", error);
8973
- if (cached?.tools) {
9406
+ if (cached2?.tools) {
8974
9407
  getLogger().warn("[serverTools] Using stale cached tools due to fetch error");
8975
- return cached.tools;
9408
+ return cached2.tools;
8976
9409
  }
8977
9410
  return [];
8978
9411
  }
@@ -10110,13 +10543,13 @@ function extractParamGroups(content) {
10110
10543
  }
10111
10544
  function mergeXaiInlineParameterTags(content, toolCalls) {
10112
10545
  if (!content || !content.includes(PARAM_MARKER)) return content;
10113
- const entries = Array.from(toolCalls.values());
10114
- if (entries.length === 0) return content;
10546
+ const entries2 = Array.from(toolCalls.values());
10547
+ if (entries2.length === 0) return content;
10115
10548
  const groups = extractParamGroups(content);
10116
10549
  if (groups.length === 0) return content;
10117
- const pairCount = Math.min(groups.length, entries.length);
10550
+ const pairCount = Math.min(groups.length, entries2.length);
10118
10551
  for (let i = 0; i < pairCount; i++) {
10119
- const target = entries[i];
10552
+ const target = entries2[i];
10120
10553
  const params = groups[i];
10121
10554
  if (!target || !params) continue;
10122
10555
  let args = {};
@@ -13438,21 +13871,21 @@ function contextFields(context) {
13438
13871
  );
13439
13872
  }
13440
13873
  function conversationContext(data) {
13441
- const entries = Object.entries(data).filter(([field10]) => field10.startsWith(CONTEXT_FIELD_PREFIX)).map(([field10, value]) => [field10.slice(CONTEXT_FIELD_PREFIX.length), value]);
13442
- return entries.length > 0 ? plain(Object.fromEntries(entries)) : void 0;
13874
+ const entries2 = Object.entries(data).filter(([field10]) => field10.startsWith(CONTEXT_FIELD_PREFIX)).map(([field10, value]) => [field10.slice(CONTEXT_FIELD_PREFIX.length), value]);
13875
+ return entries2.length > 0 ? plain(Object.fromEntries(entries2)) : void 0;
13443
13876
  }
13444
- function toConversation(record2) {
13445
- const pinnedAt = number(record2.data.pinnedAt);
13446
- const projectId = text3(record2.data.projectId);
13447
- const context = conversationContext(record2.data);
13877
+ function toConversation(record3) {
13878
+ const pinnedAt = number(record3.data.pinnedAt);
13879
+ const projectId = text3(record3.data.projectId);
13880
+ const context = conversationContext(record3.data);
13448
13881
  return {
13449
- uniqueId: record2.id,
13450
- conversationId: record2.id,
13451
- title: text3(record2.data.title) ?? "",
13882
+ uniqueId: record3.id,
13883
+ conversationId: record3.id,
13884
+ title: text3(record3.data.title) ?? "",
13452
13885
  ...projectId ? { projectId } : {},
13453
- createdAt: new Date(record2.createdAt),
13454
- updatedAt: new Date(record2.updatedAt),
13455
- isDeleted: record2.isDeleted,
13886
+ createdAt: new Date(record3.createdAt),
13887
+ updatedAt: new Date(record3.updatedAt),
13888
+ isDeleted: record3.isDeleted,
13456
13889
  pinnedAt: pinnedAt ? new Date(pinnedAt) : null,
13457
13890
  ...context ? { context } : {}
13458
13891
  };
@@ -13474,21 +13907,21 @@ function messageData(options) {
13474
13907
  ...anuma ? { anuma } : {}
13475
13908
  });
13476
13909
  }
13477
- function toMessage(record2) {
13478
- const { chunkOffsets: _offsets, truncated: _truncated, anuma: rawAnuma, ...fields } = record2.data;
13910
+ function toMessage(record3) {
13911
+ const { chunkOffsets: _offsets, truncated: _truncated, anuma: rawAnuma, ...fields } = record3.data;
13479
13912
  const anuma = readAnumaTurn(rawAnuma);
13480
13913
  return {
13481
13914
  ...anuma ? { anuma } : {},
13482
13915
  ...fields,
13483
- uniqueId: record2.id,
13484
- messageId: record2.sortKey,
13485
- conversationId: record2.conversationId,
13486
- createdAt: new Date(record2.createdAt),
13487
- updatedAt: new Date(record2.updatedAt)
13916
+ uniqueId: record3.id,
13917
+ messageId: record3.sortKey,
13918
+ conversationId: record3.conversationId,
13919
+ createdAt: new Date(record3.createdAt),
13920
+ updatedAt: new Date(record3.updatedAt)
13488
13921
  };
13489
13922
  }
13490
- function chunkOffsets(record2) {
13491
- const offsets = record2.data.chunkOffsets;
13923
+ function chunkOffsets(record3) {
13924
+ const offsets = record3.data.chunkOffsets;
13492
13925
  return Array.isArray(offsets) ? offsets : void 0;
13493
13926
  }
13494
13927
  function toSkeletons(records) {
@@ -13509,15 +13942,15 @@ function toSkeletons(records) {
13509
13942
  };
13510
13943
  });
13511
13944
  }
13512
- function toSummary(record2) {
13945
+ function toSummary(record3) {
13513
13946
  return {
13514
- uniqueId: record2.id,
13515
- conversationId: record2.id,
13516
- summary: text3(record2.data.summary) ?? "",
13517
- summarizedUpTo: text3(record2.data.summarizedUpTo) ?? "",
13518
- tokenCount: number(record2.data.tokenCount) ?? 0,
13519
- createdAt: new Date(record2.createdAt),
13520
- updatedAt: new Date(record2.updatedAt)
13947
+ uniqueId: record3.id,
13948
+ conversationId: record3.id,
13949
+ summary: text3(record3.data.summary) ?? "",
13950
+ summarizedUpTo: text3(record3.data.summarizedUpTo) ?? "",
13951
+ tokenCount: number(record3.data.tokenCount) ?? 0,
13952
+ createdAt: new Date(record3.createdAt),
13953
+ updatedAt: new Date(record3.updatedAt)
13521
13954
  };
13522
13955
  }
13523
13956
  function links(data) {
@@ -13543,10 +13976,10 @@ function applyLinkOps(data, ops) {
13543
13976
  }
13544
13977
  return plain({ links: current });
13545
13978
  }
13546
- function toLinks(record2) {
13547
- return links(record2.data).map((l) => ({
13548
- uniqueId: `${record2.id}:${l.memoryId}`,
13549
- conversationId: record2.id,
13979
+ function toLinks(record3) {
13980
+ return links(record3.data).map((l) => ({
13981
+ uniqueId: `${record3.id}:${l.memoryId}`,
13982
+ conversationId: record3.id,
13550
13983
  memoryId: l.memoryId,
13551
13984
  score: l.score,
13552
13985
  createdAt: new Date(l.createdAt)
@@ -13555,24 +13988,24 @@ function toLinks(record2) {
13555
13988
  function bytes(value) {
13556
13989
  return new TextEncoder().encode(JSON.stringify(value)).length;
13557
13990
  }
13558
- function fitRecord(record2) {
13559
- if (record2.kind !== "message" || bytes(record2) <= recordBudgetBytes) return record2;
13560
- const data = { ...record2.data };
13991
+ function fitRecord(record3) {
13992
+ if (record3.kind !== "message" || bytes(record3) <= recordBudgetBytes) return record3;
13993
+ const data = { ...record3.data };
13561
13994
  const truncated = [];
13562
13995
  for (const field10 of droppable) {
13563
- if (bytes({ ...record2, data }) <= recordBudgetBytes) break;
13996
+ if (bytes({ ...record3, data }) <= recordBudgetBytes) break;
13564
13997
  if (data[field10] === void 0) continue;
13565
13998
  delete data[field10];
13566
13999
  truncated.push(field10);
13567
14000
  }
13568
14001
  const content = text3(data.content) ?? "";
13569
- const over = bytes({ ...record2, data }) - recordBudgetBytes;
14002
+ const over = bytes({ ...record3, data }) - recordBudgetBytes;
13570
14003
  if (over > 0) {
13571
14004
  const encoded = new TextEncoder().encode(content);
13572
14005
  data.content = new TextDecoder().decode(encoded.slice(0, Math.max(0, encoded.length - over - 64))).replace(/�$/, "");
13573
14006
  truncated.push("content");
13574
14007
  }
13575
- return { ...record2, data: { ...data, truncated } };
14008
+ return { ...record3, data: { ...data, truncated } };
13576
14009
  }
13577
14010
  function acceptedVector(vector2) {
13578
14011
  if (!vector2 || !acceptedDims.has(vector2.length)) return void 0;
@@ -13616,8 +14049,8 @@ function anumaTurnContent(bubbles) {
13616
14049
  return bubbles.join("\n\n");
13617
14050
  }
13618
14051
  function anumaLastReadSortKey(conversation) {
13619
- const record2 = conversation && "record" in conversation ? conversation.record : conversation;
13620
- const state = record2?.data.anuma;
14052
+ const record3 = conversation && "record" in conversation ? conversation.record : conversation;
14053
+ const state = record3?.data.anuma;
13621
14054
  if (!isObject(state)) return 0;
13622
14055
  const sortKey = state.lastReadSortKey;
13623
14056
  return Number.isSafeInteger(sortKey) && sortKey > 0 ? sortKey : 0;
@@ -13670,19 +14103,19 @@ async function markAnumaRead(store, sortKey, options = {}) {
13670
14103
  const current = await ensureAnumaConversation(store, options);
13671
14104
  const read = anumaLastReadSortKey(current);
13672
14105
  if (sortKey <= read) return current;
13673
- const record2 = current.record;
13674
- const state = isObject(record2.data.anuma) ? record2.data.anuma : {};
13675
- const data = plain({ ...record2.data, anuma: { ...state, lastReadSortKey: sortKey } });
14106
+ const record3 = current.record;
14107
+ const state = isObject(record3.data.anuma) ? record3.data.anuma : {};
14108
+ const data = plain({ ...record3.data, anuma: { ...state, lastReadSortKey: sortKey } });
13676
14109
  try {
13677
14110
  const [written] = await store.putMany(
13678
14111
  [
13679
14112
  {
13680
14113
  expectedVersion: current.version,
13681
14114
  record: {
13682
- ...record2,
14115
+ ...record3,
13683
14116
  data,
13684
- sortKey: conversationSortKey(data, record2.createdAt),
13685
- updatedAt: Math.max(record2.updatedAt, now())
14117
+ sortKey: conversationSortKey(data, record3.createdAt),
14118
+ updatedAt: Math.max(record3.updatedAt, now())
13686
14119
  }
13687
14120
  }
13688
14121
  ],
@@ -13718,22 +14151,22 @@ function createSummaryContext(database, encryption = {}) {
13718
14151
  summariesCollection: database.get("conversation_summaries")
13719
14152
  };
13720
14153
  }
13721
- function modelToStored(record2, summary) {
14154
+ function modelToStored(record3, summary) {
13722
14155
  return {
13723
- uniqueId: record2.id,
13724
- conversationId: record2.conversationId,
14156
+ uniqueId: record3.id,
14157
+ conversationId: record3.conversationId,
13725
14158
  summary,
13726
- summarizedUpTo: record2.summarizedUpTo,
13727
- tokenCount: record2.tokenCount,
13728
- createdAt: record2.createdAt,
13729
- updatedAt: record2.updatedAt
14159
+ summarizedUpTo: record3.summarizedUpTo,
14160
+ tokenCount: record3.tokenCount,
14161
+ createdAt: record3.createdAt,
14162
+ updatedAt: record3.updatedAt
13730
14163
  };
13731
14164
  }
13732
14165
  async function getConversationSummaryOp(ctx, conversationId) {
13733
14166
  const results = await ctx.summariesCollection.query(import_watermelondb6.Q.where("conversation_id", conversationId)).fetch();
13734
14167
  if (results.length === 0) return null;
13735
- const record2 = results[0];
13736
- const stored2 = modelToStored(record2, record2.summary);
14168
+ const record3 = results[0];
14169
+ const stored2 = modelToStored(record3, record3.summary);
13737
14170
  if (ctx.walletAddress && isEncrypted(stored2.summary)) {
13738
14171
  if (ctx.signMessage) {
13739
14172
  try {
@@ -13752,7 +14185,7 @@ async function getConversationSummaryOp(ctx, conversationId) {
13752
14185
  ctx.embeddedWalletSigner
13753
14186
  );
13754
14187
  await ctx.database.write(async () => {
13755
- const current = await ctx.summariesCollection.query(import_watermelondb6.Q.where("id", record2.id)).fetch();
14188
+ const current = await ctx.summariesCollection.query(import_watermelondb6.Q.where("id", record3.id)).fetch();
13756
14189
  if (current[0]?.summary === stored2.summary) {
13757
14190
  await current[0].update((rec) => {
13758
14191
  rec.summary = encryptedSummary;
@@ -13767,19 +14200,19 @@ async function getConversationSummaryOp(ctx, conversationId) {
13767
14200
  }
13768
14201
  async function upsertConversationSummaryOp(ctx, conversationId, summary, summarizedUpTo, tokenCount) {
13769
14202
  const revision2 = getConversationRevision(ctx.database, conversationId);
13770
- let record2;
14203
+ let record3;
13771
14204
  const encryptedSummary = ctx.walletAddress ? await encryptField(summary, ctx.walletAddress, ctx.signMessage, ctx.embeddedWalletSigner) : summary;
13772
14205
  await ctx.database.write(async () => {
13773
14206
  assertConversationRevision(ctx.database, conversationId, revision2);
13774
14207
  const existing = await ctx.summariesCollection.query(import_watermelondb6.Q.where("conversation_id", conversationId)).fetch();
13775
14208
  if (existing.length > 0) {
13776
- record2 = await existing[0].update((rec) => {
14209
+ record3 = await existing[0].update((rec) => {
13777
14210
  rec.summary = encryptedSummary;
13778
14211
  rec.summarizedUpTo = summarizedUpTo;
13779
14212
  rec.tokenCount = tokenCount;
13780
14213
  });
13781
14214
  } else {
13782
- record2 = await ctx.summariesCollection.create((rec) => {
14215
+ record3 = await ctx.summariesCollection.create((rec) => {
13783
14216
  rec.conversationId = conversationId;
13784
14217
  rec.summary = encryptedSummary;
13785
14218
  rec.summarizedUpTo = summarizedUpTo;
@@ -13787,13 +14220,13 @@ async function upsertConversationSummaryOp(ctx, conversationId, summary, summari
13787
14220
  });
13788
14221
  }
13789
14222
  });
13790
- return modelToStored(record2, summary);
14223
+ return modelToStored(record3, summary);
13791
14224
  }
13792
14225
  async function deleteConversationSummaryOp(ctx, conversationId) {
13793
14226
  await ctx.database.write(async () => {
13794
14227
  const existing = await ctx.summariesCollection.query(import_watermelondb6.Q.where("conversation_id", conversationId)).fetch();
13795
- for (const record2 of existing) {
13796
- await record2.destroyPermanently();
14228
+ for (const record3 of existing) {
14229
+ await record3.destroyPermanently();
13797
14230
  }
13798
14231
  });
13799
14232
  }
@@ -13869,7 +14302,7 @@ function messageRecord(message) {
13869
14302
  const fitted = chunks3?.length ? fitChunks(chunks3) : void 0;
13870
14303
  const single = fitted ? void 0 : acceptedVector(vector2);
13871
14304
  const embeddings2 = fitted?.map((c) => c.vector) ?? (single ? [single] : void 0);
13872
- const record2 = fitRecord({
14305
+ const record3 = fitRecord({
13873
14306
  kind: "message",
13874
14307
  id: message.uniqueId,
13875
14308
  conversationId: message.conversationId,
@@ -13883,7 +14316,7 @@ function messageRecord(message) {
13883
14316
  }
13884
14317
  });
13885
14318
  return {
13886
- record: record2,
14319
+ record: record3,
13887
14320
  ...embeddings2 ? { embeddings: embeddings2 } : {},
13888
14321
  ...embeddings2 && message.embeddingModel ? { embeddingModel: message.embeddingModel } : {}
13889
14322
  };
@@ -14031,15 +14464,15 @@ function ref(value) {
14031
14464
  function sameMetadata(a, b) {
14032
14465
  return metadata.every((key3) => a[key3] === b[key3]);
14033
14466
  }
14034
- function wire(record2, payload) {
14467
+ function wire(record3, payload) {
14035
14468
  return {
14036
- kind: record2.kind,
14037
- id: record2.id,
14038
- conversation_id: record2.conversationId,
14039
- sort_key: record2.sortKey,
14040
- created_at: record2.createdAt,
14041
- updated_at: record2.updatedAt,
14042
- is_deleted: record2.isDeleted,
14469
+ kind: record3.kind,
14470
+ id: record3.id,
14471
+ conversation_id: record3.conversationId,
14472
+ sort_key: record3.sortKey,
14473
+ created_at: record3.createdAt,
14474
+ updated_at: record3.updatedAt,
14475
+ is_deleted: record3.isDeleted,
14043
14476
  payload
14044
14477
  };
14045
14478
  }
@@ -14096,10 +14529,10 @@ async function createRemoteChatStore(options) {
14096
14529
  serverUpdatedAt: value.server_updated_at
14097
14530
  };
14098
14531
  };
14099
- const seal = async (record2, signal) => {
14100
- if (record2.isDeleted) return "";
14532
+ const seal = async (record3, signal) => {
14533
+ if (record3.isDeleted) return "";
14101
14534
  const payload = await encrypt(
14102
- JSON.stringify({ schema: 1, account_id: accountId, key_id: keyId, record: record2 })
14535
+ JSON.stringify({ schema: 1, account_id: accountId, key_id: keyId, record: record3 })
14103
14536
  );
14104
14537
  signal?.throwIfAborted();
14105
14538
  if (!cipherPattern.test(payload) || payload.length > maxPayload) invalid();
@@ -14463,8 +14896,8 @@ var emptyMessage = {
14463
14896
  var maxPasses = 5;
14464
14897
  var verifyBatch = 1e3;
14465
14898
  var writeBatch = 25;
14466
- function key(record2) {
14467
- return `${record2.kind}/${record2.id}`;
14899
+ function key(record3) {
14900
+ return `${record3.kind}/${record3.id}`;
14468
14901
  }
14469
14902
  function sealed(value) {
14470
14903
  if (typeof value === "string") return isEncrypted(value);
@@ -14593,11 +15026,11 @@ async function missing(store, records, signal) {
14593
15026
  const out = /* @__PURE__ */ new Set();
14594
15027
  for (let i = 0; i < records.length; i += verifyBatch) {
14595
15028
  const refs = await store.verify(
14596
- records.slice(i, i + verifyBatch).map(({ record: record2 }) => ({
14597
- kind: record2.kind,
14598
- id: record2.id,
14599
- updatedAt: record2.updatedAt,
14600
- isDeleted: record2.isDeleted
15029
+ records.slice(i, i + verifyBatch).map(({ record: record3 }) => ({
15030
+ kind: record3.kind,
15031
+ id: record3.id,
15032
+ updatedAt: record3.updatedAt,
15033
+ isDeleted: record3.isDeleted
14601
15034
  })),
14602
15035
  signal
14603
15036
  );
@@ -14637,14 +15070,14 @@ async function deletedSinceUpload(store, journal, local, signal) {
14637
15070
  const live2 = (await store.getMany(gone.map(ref2), signal)).filter((s) => !s.record.isDeleted);
14638
15071
  const tombstoning = new Set(live2.map((s) => key(s.record)));
14639
15072
  await journal.drop(gone.filter((k) => !tombstoning.has(k)));
14640
- return live2.map(({ record: record2, version }) => {
14641
- const empty = emptied[record2.kind];
15073
+ return live2.map(({ record: record3, version }) => {
15074
+ const empty = emptied[record3.kind];
14642
15075
  return {
14643
15076
  record: {
14644
- ...record2,
15077
+ ...record3,
14645
15078
  isDeleted: !empty,
14646
15079
  data: empty ?? {},
14647
- updatedAt: Math.max(Date.now(), record2.updatedAt + 1)
15080
+ updatedAt: Math.max(Date.now(), record3.updatedAt + 1)
14648
15081
  },
14649
15082
  expectedVersion: version
14650
15083
  };
@@ -14993,8 +15426,8 @@ function createVaultAttachments(options) {
14993
15426
  },
14994
15427
  async read(attachmentId, signal) {
14995
15428
  if (!attachmentIdPattern2.test(attachmentId)) invalidAttachment();
14996
- const cached = await cache?.get(attachmentId).catch(() => null);
14997
- if (cached) return cached;
15429
+ const cached2 = await cache?.get(attachmentId).catch(() => null);
15430
+ if (cached2) return cached2;
14998
15431
  for (let attempt = 0; ; attempt++) {
14999
15432
  const found = await withRetry(() => store.attachments.get(attachmentId, signal), signal);
15000
15433
  if (!found?.download) return null;
@@ -15023,8 +15456,8 @@ function validRef(value) {
15023
15456
  const ref3 = value;
15024
15457
  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;
15025
15458
  }
15026
- function vaultAttachmentRefs(record2) {
15027
- const refs = record2.data.vaultAttachments;
15459
+ function vaultAttachmentRefs(record3) {
15460
+ const refs = record3.data.vaultAttachments;
15028
15461
  return Array.isArray(refs) ? refs.filter(validRef) : [];
15029
15462
  }
15030
15463
  function journalKey(messageId, fileId) {
@@ -15232,14 +15665,14 @@ function sameRecord(a, b) {
15232
15665
  return a.sortKey === b.sortKey && a.isDeleted === b.isDeleted && sameJson(a.data, b.data);
15233
15666
  }
15234
15667
  function toWrite(base, patch) {
15235
- const record2 = applyPatch(base?.record, patch);
15236
- if (!record2) return void 0;
15237
- if (base && patch.embeddings === void 0 && sameRecord(base.record, record2)) return null;
15668
+ const record3 = applyPatch(base?.record, patch);
15669
+ if (!record3) return void 0;
15670
+ if (base && patch.embeddings === void 0 && sameRecord(base.record, record3)) return null;
15238
15671
  return {
15239
- record: fitRecord(record2),
15672
+ record: fitRecord(record3),
15240
15673
  expectedVersion: base?.version ?? 0,
15241
- ...patch.embeddings !== void 0 && !record2.isDeleted ? { embeddings: patch.embeddings } : {},
15242
- ...patch.embeddingModel !== void 0 && !record2.isDeleted ? { embeddingModel: patch.embeddingModel } : {}
15674
+ ...patch.embeddings !== void 0 && !record3.isDeleted ? { embeddings: patch.embeddings } : {},
15675
+ ...patch.embeddingModel !== void 0 && !record3.isDeleted ? { embeddingModel: patch.embeddingModel } : {}
15243
15676
  };
15244
15677
  }
15245
15678
  var maxWrites = 25;
@@ -15373,11 +15806,11 @@ function createVaultChatBackend(options) {
15373
15806
  for (const listener of [...listeners]) listener(event);
15374
15807
  };
15375
15808
  const view = (k) => {
15376
- let record2 = confirmed.get(k)?.record;
15809
+ let record3 = confirmed.get(k)?.record;
15377
15810
  for (const patch of [inflight.get(k), pending.get(k)]) {
15378
- if (patch) record2 = applyPatch(record2, patch) ?? record2;
15811
+ if (patch) record3 = applyPatch(record3, patch) ?? record3;
15379
15812
  }
15380
- return record2;
15813
+ return record3;
15381
15814
  };
15382
15815
  const conversationLive = (conversationId) => {
15383
15816
  const conversation2 = view(key2("conversation", conversationId));
@@ -15388,10 +15821,10 @@ function createVaultChatBackend(options) {
15388
15821
  const out = [];
15389
15822
  for (const k of keys) {
15390
15823
  if (!k.startsWith(`${kind}/`)) continue;
15391
- const record2 = view(k);
15392
- if (!record2 || record2.isDeleted && !includeDeleted) continue;
15393
- if (conversationId !== void 0 && record2.conversationId !== conversationId) continue;
15394
- out.push(record2);
15824
+ const record3 = view(k);
15825
+ if (!record3 || record3.isDeleted && !includeDeleted) continue;
15826
+ if (conversationId !== void 0 && record3.conversationId !== conversationId) continue;
15827
+ out.push(record3);
15395
15828
  }
15396
15829
  return out;
15397
15830
  };
@@ -15402,7 +15835,7 @@ function createVaultChatBackend(options) {
15402
15835
  account: cache.account,
15403
15836
  cursor: cursor ?? "",
15404
15837
  records: [...confirmed.values()].filter(
15405
- ({ record: record2 }) => record2.kind === "conversation" || record2.kind !== "project" && keep.has(record2.conversationId)
15838
+ ({ record: record3 }) => record3.kind === "conversation" || record3.kind !== "project" && keep.has(record3.conversationId)
15406
15839
  ),
15407
15840
  threads: kept,
15408
15841
  absent: [...checked].filter((k) => {
@@ -15716,17 +16149,17 @@ function createVaultChatBackend(options) {
15716
16149
  return loading;
15717
16150
  };
15718
16151
  const applyRemote = (snapshot) => {
15719
- const { record: record2 } = snapshot;
15720
- const k = key2(record2.kind, record2.id);
15721
- if (record2.kind === "conversation") {
16152
+ const { record: record3 } = snapshot;
16153
+ const k = key2(record3.kind, record3.id);
16154
+ if (record3.kind === "conversation") {
15722
16155
  if (!merge(snapshot)) return;
15723
- if (record2.isDeleted) forgetConversation(record2.id);
15724
- announce([record2]);
16156
+ if (record3.isDeleted) forgetConversation(record3.id);
16157
+ announce([record3]);
15725
16158
  return;
15726
16159
  }
15727
- if (record2.kind === "project") return;
15728
- const relevant2 = threads.has(record2.conversationId) || confirmed.has(k) || checked.has(k) && record2.kind !== "message";
15729
- if (relevant2 && merge(snapshot)) announce([record2]);
16160
+ if (record3.kind === "project") return;
16161
+ const relevant2 = threads.has(record3.conversationId) || confirmed.has(k) || checked.has(k) && record3.kind !== "message";
16162
+ if (relevant2 && merge(snapshot)) announce([record3]);
15730
16163
  };
15731
16164
  const listIndex = async (source) => {
15732
16165
  const index = [];
@@ -15877,8 +16310,8 @@ function createVaultChatBackend(options) {
15877
16310
  checked.add(k);
15878
16311
  if (found) merge(found);
15879
16312
  }
15880
- const record2 = view(k);
15881
- return record2 && !record2.isDeleted && conversationLive(record2.conversationId) ? record2 : void 0;
16313
+ const record3 = view(k);
16314
+ return record3 && !record3.isDeleted && conversationLive(record3.conversationId) ? record3 : void 0;
15882
16315
  };
15883
16316
  const child = async (kind, conversationId) => {
15884
16317
  await available2();
@@ -15915,19 +16348,19 @@ function createVaultChatBackend(options) {
15915
16348
  await backend.deleteSummary(conversationId);
15916
16349
  };
15917
16350
  const storedMessage = async (uniqueId) => {
15918
- const record2 = await message(uniqueId);
15919
- return record2 ? toMessage(record2) : null;
16351
+ const record3 = await message(uniqueId);
16352
+ return record3 ? toMessage(record3) : null;
15920
16353
  };
15921
16354
  const patchMessage = async (uniqueId, patch) => {
15922
- const record2 = await message(uniqueId);
15923
- if (!record2) return null;
16355
+ const record3 = await message(uniqueId);
16356
+ if (!record3) return null;
15924
16357
  await enqueue({
15925
16358
  kind: "message",
15926
16359
  id: uniqueId,
15927
- conversationId: record2.conversationId,
16360
+ conversationId: record3.conversationId,
15928
16361
  ...patch
15929
16362
  });
15930
- emit({ type: "messages", conversationId: record2.conversationId, origin: "local" });
16363
+ emit({ type: "messages", conversationId: record3.conversationId, origin: "local" });
15931
16364
  const updated = view(key2("message", uniqueId));
15932
16365
  return updated && !updated.isDeleted ? toMessage(updated) : null;
15933
16366
  };
@@ -15952,12 +16385,12 @@ function createVaultChatBackend(options) {
15952
16385
  });
15953
16386
  const backend = {
15954
16387
  async getConversation(conversationId) {
15955
- const record2 = await conversation(conversationId);
15956
- return record2 && !record2.isDeleted ? toConversation(record2) : null;
16388
+ const record3 = await conversation(conversationId);
16389
+ return record3 && !record3.isDeleted ? toConversation(record3) : null;
15957
16390
  },
15958
16391
  async getConversations(query) {
15959
16392
  await available2();
15960
- return all("conversation").filter((record2) => record2.id !== ANUMA_CONVERSATION_ID).map(toConversation).filter(
16393
+ return all("conversation").filter((record3) => record3.id !== ANUMA_CONVERSATION_ID).map(toConversation).filter(
15961
16394
  (c) => query?.projectId === void 0 || (query.projectId === null ? !c.projectId : c.projectId === query.projectId)
15962
16395
  ).sort((a, b) => b.createdAt.getTime() - a.createdAt.getTime());
15963
16396
  },
@@ -15996,13 +16429,13 @@ function createVaultChatBackend(options) {
15996
16429
  async updateConversationContext(conversationId, context) {
15997
16430
  const set = contextFields(context);
15998
16431
  if (Object.keys(set).length > 0) return updateConversation(conversationId, set);
15999
- const record2 = await conversation(conversationId);
16000
- return !!record2 && !record2.isDeleted;
16432
+ const record3 = await conversation(conversationId);
16433
+ return !!record3 && !record3.isDeleted;
16001
16434
  },
16002
16435
  async deleteConversation(conversationId) {
16003
16436
  if (conversationId === ANUMA_CONVERSATION_ID) return false;
16004
- const record2 = await conversation(conversationId);
16005
- if (!record2 || record2.isDeleted) return false;
16437
+ const record3 = await conversation(conversationId);
16438
+ if (!record3 || record3.isDeleted) return false;
16006
16439
  for (const [k, patch] of pending)
16007
16440
  if (patch.conversationId === conversationId) pending.delete(k);
16008
16441
  await enqueue({ kind: "conversation", id: conversationId, conversationId: "", delete: true });
@@ -16038,8 +16471,8 @@ function createVaultChatBackend(options) {
16038
16471
  const unknown = ids.map((id2) => key2("message", id2)).filter((k) => !view(k) && !checked.has(k));
16039
16472
  await refresh(unknown);
16040
16473
  return ids.flatMap((id2) => {
16041
- const record2 = view(key2("message", id2));
16042
- return record2 && !record2.isDeleted && conversationLive(record2.conversationId) ? [toMessage(record2)] : [];
16474
+ const record3 = view(key2("message", id2));
16475
+ return record3 && !record3.isDeleted && conversationLive(record3.conversationId) ? [toMessage(record3)] : [];
16043
16476
  });
16044
16477
  },
16045
16478
  async getMessageCount(conversationId) {
@@ -16047,8 +16480,8 @@ function createVaultChatBackend(options) {
16047
16480
  },
16048
16481
  async getToolCallEventIds(conversationId) {
16049
16482
  const ids = /* @__PURE__ */ new Set();
16050
- for (const record2 of await thread(conversationId)) {
16051
- const events = record2.data.toolCallEvents;
16483
+ for (const record3 of await thread(conversationId)) {
16484
+ const events = record3.data.toolCallEvents;
16052
16485
  if (!Array.isArray(events)) continue;
16053
16486
  for (const event of events)
16054
16487
  if (event && typeof event === "object" && !Array.isArray(event) && typeof event.id === "string")
@@ -16141,21 +16574,21 @@ function createVaultChatBackend(options) {
16141
16574
  },
16142
16575
  async clearMessages(conversationId) {
16143
16576
  await invalidateSummary(conversationId);
16144
- for (const record2 of await thread(conversationId))
16145
- await enqueue({ kind: "message", id: record2.id, conversationId, delete: true });
16577
+ for (const record3 of await thread(conversationId))
16578
+ await enqueue({ kind: "message", id: record3.id, conversationId, delete: true });
16146
16579
  emit({ type: "messages", conversationId, origin: "local" });
16147
16580
  },
16148
16581
  async deleteMessage(uniqueId) {
16149
- const record2 = await message(uniqueId);
16150
- if (!record2) return null;
16151
- await invalidateSummary(record2.conversationId, record2);
16582
+ const record3 = await message(uniqueId);
16583
+ if (!record3) return null;
16584
+ await invalidateSummary(record3.conversationId, record3);
16152
16585
  await enqueue({
16153
16586
  kind: "message",
16154
16587
  id: uniqueId,
16155
- conversationId: record2.conversationId,
16588
+ conversationId: record3.conversationId,
16156
16589
  delete: true
16157
16590
  });
16158
- emit({ type: "messages", conversationId: record2.conversationId, origin: "local" });
16591
+ emit({ type: "messages", conversationId: record3.conversationId, origin: "local" });
16159
16592
  return uniqueId;
16160
16593
  },
16161
16594
  observeMessages(conversationId) {
@@ -16168,13 +16601,13 @@ function createVaultChatBackend(options) {
16168
16601
  await available2();
16169
16602
  if (query?.conversationId) await loadThread(query.conversationId);
16170
16603
  const files = [];
16171
- for (const record2 of all("message", query?.conversationId)) {
16172
- if (!conversationLive(record2.conversationId)) continue;
16173
- const stored2 = toMessage(record2);
16604
+ for (const record3 of all("message", query?.conversationId)) {
16605
+ if (!conversationLive(record3.conversationId)) continue;
16606
+ const stored2 = toMessage(record3);
16174
16607
  for (const file of stored2.files ?? [])
16175
16608
  files.push({
16176
16609
  ...file,
16177
- conversationId: record2.conversationId,
16610
+ conversationId: record3.conversationId,
16178
16611
  createdAt: stored2.createdAt,
16179
16612
  messageRole: stored2.role
16180
16613
  });
@@ -16213,8 +16646,8 @@ function createVaultChatBackend(options) {
16213
16646
  return results;
16214
16647
  },
16215
16648
  async getSummary(conversationId) {
16216
- const record2 = await child("summary", conversationId);
16217
- return record2 && !record2.isDeleted && record2.data.summarizedUpTo ? toSummary(record2) : null;
16649
+ const record3 = await child("summary", conversationId);
16650
+ return record3 && !record3.isDeleted && record3.data.summarizedUpTo ? toSummary(record3) : null;
16218
16651
  },
16219
16652
  async upsertSummary(conversationId, summary, summarizedUpTo, tokenCount) {
16220
16653
  await child("summary", conversationId);
@@ -16230,8 +16663,8 @@ function createVaultChatBackend(options) {
16230
16663
  return toSummary(view(key2("summary", conversationId)));
16231
16664
  },
16232
16665
  async deleteSummary(conversationId) {
16233
- const record2 = await child("summary", conversationId);
16234
- if (!record2 || record2.isDeleted) return;
16666
+ const record3 = await child("summary", conversationId);
16667
+ if (!record3 || record3.isDeleted) return;
16235
16668
  await enqueue({
16236
16669
  kind: "summary",
16237
16670
  id: conversationId,
@@ -16241,8 +16674,8 @@ function createVaultChatBackend(options) {
16241
16674
  emit({ type: "summary", conversationId, origin: "local" });
16242
16675
  },
16243
16676
  async getMemoryLinks(conversationId) {
16244
- const record2 = await child("memory_links", conversationId);
16245
- return record2 && !record2.isDeleted ? toLinks(record2) : [];
16677
+ const record3 = await child("memory_links", conversationId);
16678
+ return record3 && !record3.isDeleted ? toLinks(record3) : [];
16246
16679
  },
16247
16680
  async addMemoryLinks(conversationId, items) {
16248
16681
  if (!conversationId || items.length === 0) return;
@@ -16257,8 +16690,8 @@ function createVaultChatBackend(options) {
16257
16690
  emit({ type: "links", conversationId, origin: "local" });
16258
16691
  },
16259
16692
  async clearMemoryLinks(conversationId) {
16260
- const record2 = await child("memory_links", conversationId);
16261
- if (!record2 || record2.isDeleted) return;
16693
+ const record3 = await child("memory_links", conversationId);
16694
+ if (!record3 || record3.isDeleted) return;
16262
16695
  await enqueue({
16263
16696
  kind: "memory_links",
16264
16697
  id: conversationId,
@@ -16276,8 +16709,8 @@ function createVaultChatBackend(options) {
16276
16709
  async importChats(chats) {
16277
16710
  await ready();
16278
16711
  const seen = /* @__PURE__ */ new Set();
16279
- const unique = (items) => items.filter(({ record: record2 }) => {
16280
- const k = key2(record2.kind, record2.id);
16712
+ const unique = (items) => items.filter(({ record: record3 }) => {
16713
+ const k = key2(record3.kind, record3.id);
16281
16714
  if (seen.has(k)) return false;
16282
16715
  seen.add(k);
16283
16716
  return true;
@@ -16301,15 +16734,15 @@ function createVaultChatBackend(options) {
16301
16734
  for (const batch of batches(messages))
16302
16735
  messageCount += await connected.importRecords(batch);
16303
16736
  } finally {
16304
- for (const { record: record2 } of messages) checked.delete(key2("message", record2.id));
16305
- await refresh(conversations.map(({ record: record2 }) => key2("conversation", record2.id))).catch(
16737
+ for (const { record: record3 } of messages) checked.delete(key2("message", record3.id));
16738
+ await refresh(conversations.map(({ record: record3 }) => key2("conversation", record3.id))).catch(
16306
16739
  () => void 0
16307
16740
  );
16308
- for (const { record: record2 } of conversations) threads.delete(record2.id);
16741
+ for (const { record: record3 } of conversations) threads.delete(record3.id);
16309
16742
  channel?.postMessage("changed");
16310
16743
  emit({ type: "conversations", origin: "local" });
16311
- for (const { record: record2 } of conversations)
16312
- emit({ type: "messages", conversationId: record2.id, origin: "local" });
16744
+ for (const { record: record3 } of conversations)
16745
+ emit({ type: "messages", conversationId: record3.id, origin: "local" });
16313
16746
  }
16314
16747
  return { conversations: conversationCount, messages: messageCount };
16315
16748
  },
@@ -16328,8 +16761,8 @@ function createVaultChatBackend(options) {
16328
16761
  }
16329
16762
  };
16330
16763
  const updateConversation = async (conversationId, set) => {
16331
- const record2 = await conversation(conversationId);
16332
- if (!record2 || record2.isDeleted) return false;
16764
+ const record3 = await conversation(conversationId);
16765
+ if (!record3 || record3.isDeleted) return false;
16333
16766
  await enqueue({ kind: "conversation", id: conversationId, conversationId: "", set });
16334
16767
  emit({ type: "conversations", origin: "local" });
16335
16768
  return true;
@@ -16505,10 +16938,10 @@ async function decryptConversationTitle(encryptedTitle, address) {
16505
16938
  );
16506
16939
  }
16507
16940
  const cacheKey = buildCacheKey(address, encryptedTitle);
16508
- const cached = titleCache.get(cacheKey);
16509
- if (cached !== void 0) {
16510
- touchEntry(cacheKey, cached);
16511
- return cached;
16941
+ const cached2 = titleCache.get(cacheKey);
16942
+ if (cached2 !== void 0) {
16943
+ touchEntry(cacheKey, cached2);
16944
+ return cached2;
16512
16945
  }
16513
16946
  const inFlight = pendingDecrypts.get(cacheKey);
16514
16947
  if (inFlight) return inFlight;
@@ -16767,25 +17200,25 @@ async function upsertEntitiesInWrite(ctx, entities) {
16767
17200
  const kindBackfills = existing.filter((e) => {
16768
17201
  const incoming = kindByName.get(e.canonicalName);
16769
17202
  return incoming !== void 0 && (e.kind === null || e.kind === void 0 || e.kind === "");
16770
- }).map((record2) => ({ record: record2, kind: kindByName.get(record2.canonicalName) }));
17203
+ }).map((record3) => ({ record: record3, kind: kindByName.get(record3.canonicalName) }));
16771
17204
  const missing2 = unique.filter((n) => !existingNames.has(n));
16772
17205
  const created = missing2.map(
16773
- (name) => ctx.entityCollection.prepareCreate((record2) => {
16774
- record2._setRaw("canonical_name", name);
17206
+ (name) => ctx.entityCollection.prepareCreate((record3) => {
17207
+ record3._setRaw("canonical_name", name);
16775
17208
  const kind = kindByName.get(name);
16776
- if (kind !== void 0) record2._setRaw("kind", kind);
17209
+ if (kind !== void 0) record3._setRaw("kind", kind);
16777
17210
  })
16778
17211
  );
16779
17212
  for (const e of existing) out.set(e.canonicalName, entityToStored(e));
16780
- for (const record2 of created) out.set(record2.canonicalName, entityToStored(record2));
16781
- for (const { record: record2, kind } of kindBackfills) {
16782
- out.set(record2.canonicalName, { ...entityToStored(record2), kind });
17213
+ for (const record3 of created) out.set(record3.canonicalName, entityToStored(record3));
17214
+ for (const { record: record3, kind } of kindBackfills) {
17215
+ out.set(record3.canonicalName, { ...entityToStored(record3), kind });
16783
17216
  }
16784
17217
  return { entities: out, operations: created, kindBackfills };
16785
17218
  }
16786
17219
  function prepareKindBackfills(backfills) {
16787
17220
  return backfills.map(
16788
- ({ record: record2, kind }) => record2.prepareUpdate((r) => {
17221
+ ({ record: record3, kind }) => record3.prepareUpdate((r) => {
16789
17222
  r._setRaw("kind", kind);
16790
17223
  })
16791
17224
  );
@@ -16913,10 +17346,10 @@ async function linkMemoryEntitiesOp(ctx, memoryId, entityInputs, options) {
16913
17346
  return;
16914
17347
  }
16915
17348
  const linkOps = toCreate.map(
16916
- (e) => ctx.memoryEntityCollection.prepareCreate((record2) => {
16917
- record2._setRaw("memory_id", memoryId);
16918
- record2._setRaw("entity_id", e.uniqueId);
16919
- if (userId !== void 0) record2._setRaw("user_id", userId);
17349
+ (e) => ctx.memoryEntityCollection.prepareCreate((record3) => {
17350
+ record3._setRaw("memory_id", memoryId);
17351
+ record3._setRaw("entity_id", e.uniqueId);
17352
+ if (userId !== void 0) record3._setRaw("user_id", userId);
16920
17353
  })
16921
17354
  );
16922
17355
  await ctx.database.batch(
@@ -16986,10 +17419,10 @@ async function replaceMemoryEntities(ctx, memoryId, entityInputs, options) {
16986
17419
  ...entityOps,
16987
17420
  ...prepareKindBackfills(kindBackfills),
16988
17421
  ...toCreate.map(
16989
- (e) => ctx.memoryEntityCollection.prepareCreate((record2) => {
16990
- record2._setRaw("memory_id", memoryId);
16991
- record2._setRaw("entity_id", e.uniqueId);
16992
- if (userId !== void 0) record2._setRaw("user_id", userId);
17422
+ (e) => ctx.memoryEntityCollection.prepareCreate((record3) => {
17423
+ record3._setRaw("memory_id", memoryId);
17424
+ record3._setRaw("entity_id", e.uniqueId);
17425
+ if (userId !== void 0) record3._setRaw("user_id", userId);
16993
17426
  })
16994
17427
  ),
16995
17428
  ...toDestroy.map((l) => l.prepareDestroyPermanently()),
@@ -18318,9 +18751,9 @@ var DatabaseManager = class {
18318
18751
  */
18319
18752
  getDatabase(walletAddress) {
18320
18753
  const dbName = this.getDbName(walletAddress);
18321
- const cached = this.databases.get(dbName);
18322
- if (cached) {
18323
- return cached;
18754
+ const cached2 = this.databases.get(dbName);
18755
+ if (cached2) {
18756
+ return cached2;
18324
18757
  }
18325
18758
  const needsMigration = this.handleSchemaMigration(walletAddress);
18326
18759
  if (needsMigration) {
@@ -19460,8 +19893,8 @@ function visibilityConditions(requested) {
19460
19893
  if (excluded.length === 0) return [];
19461
19894
  return [import_watermelondb24.Q.or(import_watermelondb24.Q.where("visibility", null), import_watermelondb24.Q.where("visibility", import_watermelondb24.Q.notIn(excluded)))];
19462
19895
  }
19463
- function isKinded(record2) {
19464
- return record2.kind !== null && record2.kind !== void 0;
19896
+ function isKinded(record3) {
19897
+ return record3.kind !== null && record3.kind !== void 0;
19465
19898
  }
19466
19899
  async function assertCanWrite2(ctx) {
19467
19900
  if (ctx.canWrite && !await ctx.canWrite()) {
@@ -19515,8 +19948,8 @@ function levelConditions(requested) {
19515
19948
  }
19516
19949
  return [byLevel];
19517
19950
  }
19518
- function isOwnedByCtxUser(ctx, record2) {
19519
- return ctx.userId === void 0 || record2.userId === ctx.userId;
19951
+ function isOwnedByCtxUser(ctx, record3) {
19952
+ return ctx.userId === void 0 || record3.userId === ctx.userId;
19520
19953
  }
19521
19954
  function baseVaultConditions(ctx, options) {
19522
19955
  return [
@@ -19599,43 +20032,43 @@ async function vaultMemoryToStored(memory, walletAddress, signMessage, embeddedW
19599
20032
  }
19600
20033
  return raw;
19601
20034
  }
19602
- function populateNewVaultMemory(record2, ctx, opts, encryptedContent, encryptedKindValue) {
20035
+ function populateNewVaultMemory(record3, ctx, opts, encryptedContent, encryptedKindValue) {
19603
20036
  const { level, scope } = resolveCreateLevel(opts);
19604
- record2._setRaw("content", encryptedContent);
19605
- record2._setRaw("scope", scope);
19606
- record2._setRaw("level", level);
19607
- record2._setRaw("kind", opts.kind ?? null);
19608
- record2._setRaw("kind_value", encryptedKindValue ?? null);
19609
- record2._setRaw("folder_id", opts.folderId ?? null);
19610
- record2._setRaw("user_id", ctx.userId ?? null);
19611
- record2._setRaw("is_deleted", false);
20037
+ record3._setRaw("content", encryptedContent);
20038
+ record3._setRaw("scope", scope);
20039
+ record3._setRaw("level", level);
20040
+ record3._setRaw("kind", opts.kind ?? null);
20041
+ record3._setRaw("kind_value", encryptedKindValue ?? null);
20042
+ record3._setRaw("folder_id", opts.folderId ?? null);
20043
+ record3._setRaw("user_id", ctx.userId ?? null);
20044
+ record3._setRaw("is_deleted", false);
19612
20045
  if (opts.embedding !== void 0) {
19613
- record2._setRaw("embedding", opts.embedding);
19614
- record2._setRaw("embedding_model", opts.embeddingModel ?? null);
20046
+ record3._setRaw("embedding", opts.embedding);
20047
+ record3._setRaw("embedding_model", opts.embeddingModel ?? null);
19615
20048
  }
19616
20049
  if (opts.sourceChunkIds !== void 0) {
19617
- record2._setRaw("source_chunk_ids", serializeSourceChunkIds(opts.sourceChunkIds));
20050
+ record3._setRaw("source_chunk_ids", serializeSourceChunkIds(opts.sourceChunkIds));
19618
20051
  }
19619
- record2._setRaw("proof_count", opts.proofCount ?? 1);
19620
- record2._setRaw("source", opts.source ?? "manual");
20052
+ record3._setRaw("proof_count", opts.proofCount ?? 1);
20053
+ record3._setRaw("source", opts.source ?? "manual");
19621
20054
  if (opts.eventTime) {
19622
- record2._setRaw("event_time_start", opts.eventTime.start ?? null);
19623
- record2._setRaw("event_time_end", opts.eventTime.end ?? null);
19624
- record2._setRaw("event_time_kind", opts.eventTime.kind ?? null);
20055
+ record3._setRaw("event_time_start", opts.eventTime.start ?? null);
20056
+ record3._setRaw("event_time_end", opts.eventTime.end ?? null);
20057
+ record3._setRaw("event_time_kind", opts.eventTime.kind ?? null);
19625
20058
  }
19626
20059
  if (opts.factType !== void 0) {
19627
- record2._setRaw("fact_type", opts.factType);
20060
+ record3._setRaw("fact_type", opts.factType);
19628
20061
  }
19629
20062
  if (opts.trustTier !== void 0) {
19630
- record2._setRaw("trust_tier", normalizeTrustTier(opts.trustTier));
20063
+ record3._setRaw("trust_tier", normalizeTrustTier(opts.trustTier));
19631
20064
  }
19632
- record2._setRaw("visibility", opts.visibility ?? "private");
19633
- record2._setRaw(
20065
+ record3._setRaw("visibility", opts.visibility ?? "private");
20066
+ record3._setRaw(
19634
20067
  "published_at",
19635
20068
  opts.visibility && opts.visibility !== "private" ? opts.publishedAt ?? Date.now() : null
19636
20069
  );
19637
20070
  if (opts.geohash !== void 0) {
19638
- record2._setRaw("geohash", opts.geohash);
20071
+ record3._setRaw("geohash", opts.geohash);
19639
20072
  }
19640
20073
  }
19641
20074
  async function createVaultMemoryOp(ctx, opts) {
@@ -19650,7 +20083,7 @@ async function createVaultMemoryOp(ctx, opts) {
19650
20083
  const created = await ctx.database.write(async () => {
19651
20084
  await assertCanWrite2(ctx);
19652
20085
  return ctx.vaultMemoryCollection.create(
19653
- (record2) => populateNewVaultMemory(record2, ctx, opts, encryptedContent, encryptedKindValue)
20086
+ (record3) => populateNewVaultMemory(record3, ctx, opts, encryptedContent, encryptedKindValue)
19654
20087
  );
19655
20088
  });
19656
20089
  return vaultMemoryToStored(created, ctx.walletAddress, ctx.signMessage, ctx.embeddedWalletSigner);
@@ -19677,7 +20110,7 @@ async function createSupersedingMemoryOp(ctx, opts, targetId) {
19677
20110
  if (target.isDeleted || target.supersededBy || isKinded(target) || !isOwnedByCtxUser(ctx, target))
19678
20111
  return;
19679
20112
  createdRecord = await ctx.vaultMemoryCollection.create(
19680
- (record2) => populateNewVaultMemory(record2, ctx, opts, encryptedContent, encryptedKindValue)
20113
+ (record3) => populateNewVaultMemory(record3, ctx, opts, encryptedContent, encryptedKindValue)
19681
20114
  );
19682
20115
  await target.update((r) => {
19683
20116
  r._setRaw("superseded_by", createdRecord.id);
@@ -19762,7 +20195,7 @@ async function createVaultMemoriesBatchOp(ctx, optionsArray) {
19762
20195
  await assertCanWrite2(ctx);
19763
20196
  const prepared = optionsArray.map(
19764
20197
  (opts, i) => ctx.vaultMemoryCollection.prepareCreate(
19765
- (record2) => populateNewVaultMemory(record2, ctx, opts, encryptedContents[i], encryptedKindValues[i])
20198
+ (record3) => populateNewVaultMemory(record3, ctx, opts, encryptedContents[i], encryptedKindValues[i])
19766
20199
  )
19767
20200
  );
19768
20201
  await ctx.database.batch(...prepared);
@@ -19770,16 +20203,16 @@ async function createVaultMemoriesBatchOp(ctx, optionsArray) {
19770
20203
  });
19771
20204
  return Promise.all(
19772
20205
  created.map(
19773
- (record2) => vaultMemoryToStored(record2, ctx.walletAddress, ctx.signMessage, ctx.embeddedWalletSigner)
20206
+ (record3) => vaultMemoryToStored(record3, ctx.walletAddress, ctx.signMessage, ctx.embeddedWalletSigner)
19774
20207
  )
19775
20208
  );
19776
20209
  }
19777
20210
  async function getVaultMemoryOp(ctx, id2) {
19778
20211
  try {
19779
- const record2 = await ctx.vaultMemoryCollection.find(id2);
19780
- if (record2.isDeleted || !isOwnedByCtxUser(ctx, record2)) return null;
20212
+ const record3 = await ctx.vaultMemoryCollection.find(id2);
20213
+ if (record3.isDeleted || !isOwnedByCtxUser(ctx, record3)) return null;
19781
20214
  return vaultMemoryToStored(
19782
- record2,
20215
+ record3,
19783
20216
  ctx.walletAddress,
19784
20217
  ctx.signMessage,
19785
20218
  ctx.embeddedWalletSigner
@@ -20118,29 +20551,29 @@ async function updateVaultMemoryOp(ctx, id2, opts) {
20118
20551
  ctx.embeddedWalletSigner
20119
20552
  ) : opts.content;
20120
20553
  let stale = false;
20121
- const record2 = probe;
20554
+ const record3 = probe;
20122
20555
  await ctx.database.write(async () => {
20123
20556
  await assertCanWrite2(ctx);
20124
- if (record2.isDeleted || record2.supersededBy || !isOwnedByCtxUser(ctx, record2) || opts.freeFormOnly && isKinded(record2) || opts.expectedContent !== void 0 && record2._getRaw("content") !== readStoredContent) {
20557
+ if (record3.isDeleted || record3.supersededBy || !isOwnedByCtxUser(ctx, record3) || opts.freeFormOnly && isKinded(record3) || opts.expectedContent !== void 0 && record3._getRaw("content") !== readStoredContent) {
20125
20558
  stale = true;
20126
20559
  return;
20127
20560
  }
20128
- const originalUpdatedAt = record2.updatedAt.getTime();
20129
- const nextKind = opts.kind !== void 0 ? opts.kind : record2.kind;
20130
- const nextLevel = levelAfter(record2);
20561
+ const originalUpdatedAt = record3.updatedAt.getTime();
20562
+ const nextKind = opts.kind !== void 0 ? opts.kind : record3.kind;
20563
+ const nextLevel = levelAfter(record3);
20131
20564
  assertValidKindLevel(nextKind, nextLevel);
20132
20565
  let observedSources = [];
20133
20566
  let replayedObservation = false;
20134
20567
  if (opts.observationSourceIds?.length) {
20135
20568
  try {
20136
- const parsed = JSON.parse(record2.sourceChunkIds ?? "[]");
20569
+ const parsed = JSON.parse(record3.sourceChunkIds ?? "[]");
20137
20570
  if (Array.isArray(parsed))
20138
20571
  observedSources = parsed.filter((id3) => typeof id3 === "string");
20139
20572
  } catch {
20140
20573
  }
20141
20574
  replayedObservation = opts.observationSourceIds.every((id3) => observedSources.includes(id3));
20142
20575
  }
20143
- await record2.update((r) => {
20576
+ await record3.update((r) => {
20144
20577
  if (encryptedContent !== void 0) r._setRaw("content", encryptedContent);
20145
20578
  if (opts.level !== void 0) {
20146
20579
  r._setRaw("level", nextLevel);
@@ -20207,7 +20640,7 @@ async function updateVaultMemoryOp(ctx, id2, opts) {
20207
20640
  });
20208
20641
  if (stale) return null;
20209
20642
  return vaultMemoryToStored(
20210
- record2,
20643
+ record3,
20211
20644
  ctx.walletAddress,
20212
20645
  ctx.signMessage,
20213
20646
  ctx.embeddedWalletSigner
@@ -20222,22 +20655,22 @@ async function setMemoryEntitiesOp(ctx, memoryId, entities) {
20222
20655
  if (!entityCtx) {
20223
20656
  throw new Error("setMemoryEntitiesOp requires ctx.entityCtx (entity collections)");
20224
20657
  }
20225
- let record2;
20658
+ let record3;
20226
20659
  try {
20227
- record2 = await ctx.vaultMemoryCollection.find(memoryId);
20660
+ record3 = await ctx.vaultMemoryCollection.find(memoryId);
20228
20661
  } catch {
20229
20662
  return null;
20230
20663
  }
20231
- if (record2.isDeleted || !isOwnedByCtxUser(ctx, record2)) return null;
20664
+ if (record3.isDeleted || !isOwnedByCtxUser(ctx, record3)) return null;
20232
20665
  let stale = false;
20233
- const originalUpdatedAt = record2.updatedAt.getTime();
20666
+ const originalUpdatedAt = record3.updatedAt.getTime();
20234
20667
  await ctx.database.write(async (writer) => {
20235
20668
  await assertCanWrite2(ctx);
20236
- if (record2.isDeleted || !isOwnedByCtxUser(ctx, record2)) {
20669
+ if (record3.isDeleted || !isOwnedByCtxUser(ctx, record3)) {
20237
20670
  stale = true;
20238
20671
  return;
20239
20672
  }
20240
- await record2.update((r) => {
20673
+ await record3.update((r) => {
20241
20674
  r._setRaw("topics_user_managed", true);
20242
20675
  r._setRaw("updated_at", originalUpdatedAt);
20243
20676
  });
@@ -20261,26 +20694,26 @@ async function setMemoryEntitiesOp(ctx, memoryId, entities) {
20261
20694
  );
20262
20695
  });
20263
20696
  if (stale) return null;
20264
- return vaultMemoryToStored(record2, ctx.walletAddress, ctx.signMessage, ctx.embeddedWalletSigner);
20697
+ return vaultMemoryToStored(record3, ctx.walletAddress, ctx.signMessage, ctx.embeddedWalletSigner);
20265
20698
  }
20266
20699
  async function clearMemoryTopicsOverrideOp(ctx, memoryId, options) {
20267
- let record2;
20700
+ let record3;
20268
20701
  try {
20269
- record2 = await ctx.vaultMemoryCollection.find(memoryId);
20702
+ record3 = await ctx.vaultMemoryCollection.find(memoryId);
20270
20703
  } catch {
20271
20704
  return false;
20272
20705
  }
20273
- if (record2.isDeleted || !isOwnedByCtxUser(ctx, record2)) return false;
20274
- const originalUpdatedAt = record2.updatedAt.getTime();
20706
+ if (record3.isDeleted || !isOwnedByCtxUser(ctx, record3)) return false;
20707
+ const originalUpdatedAt = record3.updatedAt.getTime();
20275
20708
  let cleared = false;
20276
20709
  await ctx.database.write(async () => {
20277
20710
  await assertCanWrite2(ctx);
20278
- if (options?.unlessTopicsRecorded && parseTopics(record2.topics) !== null) return;
20711
+ if (options?.unlessTopicsRecorded && parseTopics(record3.topics) !== null) return;
20279
20712
  cleared = true;
20280
- await record2.update((r) => {
20713
+ await record3.update((r) => {
20281
20714
  r._setRaw("topics_user_managed", false);
20282
20715
  r._setRaw("topics_extracted_version", null);
20283
- if (record2.topicsExtractedAt === null) {
20716
+ if (record3.topicsExtractedAt === null) {
20284
20717
  r._setRaw("topics_extracted_at", originalUpdatedAt);
20285
20718
  }
20286
20719
  r._setRaw("updated_at", originalUpdatedAt);
@@ -20289,23 +20722,23 @@ async function clearMemoryTopicsOverrideOp(ctx, memoryId, options) {
20289
20722
  return cleared;
20290
20723
  }
20291
20724
  async function setMemoryVisibilityOp(ctx, id2, opts) {
20292
- let record2;
20725
+ let record3;
20293
20726
  try {
20294
- record2 = await ctx.vaultMemoryCollection.find(id2);
20727
+ record3 = await ctx.vaultMemoryCollection.find(id2);
20295
20728
  } catch {
20296
20729
  return null;
20297
20730
  }
20298
- if (record2.isDeleted || !isOwnedByCtxUser(ctx, record2)) return null;
20731
+ if (record3.isDeleted || !isOwnedByCtxUser(ctx, record3)) return null;
20299
20732
  let stale = false;
20300
20733
  await ctx.database.write(async () => {
20301
20734
  await assertCanWrite2(ctx);
20302
- if (record2.isDeleted || !isOwnedByCtxUser(ctx, record2)) {
20735
+ if (record3.isDeleted || !isOwnedByCtxUser(ctx, record3)) {
20303
20736
  stale = true;
20304
20737
  return;
20305
20738
  }
20306
- const currentUpdatedAt = record2.updatedAt.getTime();
20307
- const currentPublishedAt = record2.publishedAt ?? null;
20308
- await record2.update((r) => {
20739
+ const currentUpdatedAt = record3.updatedAt.getTime();
20740
+ const currentPublishedAt = record3.publishedAt ?? null;
20741
+ await record3.update((r) => {
20309
20742
  r._setRaw("visibility", opts.visibility);
20310
20743
  if (opts.visibility === "private") {
20311
20744
  r._setRaw("published_at", null);
@@ -20319,20 +20752,20 @@ async function setMemoryVisibilityOp(ctx, id2, opts) {
20319
20752
  });
20320
20753
  });
20321
20754
  if (stale) return null;
20322
- return vaultMemoryToStored(record2, ctx.walletAddress, ctx.signMessage, ctx.embeddedWalletSigner);
20755
+ return vaultMemoryToStored(record3, ctx.walletAddress, ctx.signMessage, ctx.embeddedWalletSigner);
20323
20756
  }
20324
20757
  async function deleteVaultMemoryOp(ctx, id2) {
20325
20758
  try {
20326
- const record2 = await ctx.vaultMemoryCollection.find(id2);
20327
- if (record2.isDeleted || !isOwnedByCtxUser(ctx, record2)) return false;
20759
+ const record3 = await ctx.vaultMemoryCollection.find(id2);
20760
+ if (record3.isDeleted || !isOwnedByCtxUser(ctx, record3)) return false;
20328
20761
  let stale = false;
20329
20762
  await ctx.database.write(async () => {
20330
20763
  await assertCanWrite2(ctx);
20331
- if (record2.isDeleted || !isOwnedByCtxUser(ctx, record2)) {
20764
+ if (record3.isDeleted || !isOwnedByCtxUser(ctx, record3)) {
20332
20765
  stale = true;
20333
20766
  return;
20334
20767
  }
20335
- await record2.update((r) => {
20768
+ await record3.update((r) => {
20336
20769
  r._setRaw("is_deleted", true);
20337
20770
  });
20338
20771
  });
@@ -20351,9 +20784,9 @@ async function deleteVaultMemoryOp(ctx, id2) {
20351
20784
  async function supersedeVaultMemoryOp(ctx, id2, supersededById) {
20352
20785
  if (id2 === supersededById) return false;
20353
20786
  try {
20354
- const record2 = await ctx.vaultMemoryCollection.find(id2);
20355
- if (record2.isDeleted || record2.supersededBy || !isOwnedByCtxUser(ctx, record2)) return false;
20356
- if (isKinded(record2)) return false;
20787
+ const record3 = await ctx.vaultMemoryCollection.find(id2);
20788
+ if (record3.isDeleted || record3.supersededBy || !isOwnedByCtxUser(ctx, record3)) return false;
20789
+ if (isKinded(record3)) return false;
20357
20790
  let successor;
20358
20791
  try {
20359
20792
  successor = await ctx.vaultMemoryCollection.find(supersededById);
@@ -20366,7 +20799,7 @@ async function supersedeVaultMemoryOp(ctx, id2, supersededById) {
20366
20799
  let stale = false;
20367
20800
  await ctx.database.write(async () => {
20368
20801
  await assertCanWrite2(ctx);
20369
- if (record2.isDeleted || record2.supersededBy || !isOwnedByCtxUser(ctx, record2)) {
20802
+ if (record3.isDeleted || record3.supersededBy || !isOwnedByCtxUser(ctx, record3)) {
20370
20803
  stale = true;
20371
20804
  return;
20372
20805
  }
@@ -20374,7 +20807,7 @@ async function supersedeVaultMemoryOp(ctx, id2, supersededById) {
20374
20807
  stale = true;
20375
20808
  return;
20376
20809
  }
20377
- await record2.update((r) => {
20810
+ await record3.update((r) => {
20378
20811
  r._setRaw("superseded_by", supersededById);
20379
20812
  r._setRaw("superseded_at", Date.now());
20380
20813
  });
@@ -20393,7 +20826,7 @@ async function getUnfiledVaultMemoriesOp(ctx) {
20393
20826
  const results = await ctx.vaultMemoryCollection.query(...conditions).fetch();
20394
20827
  return mapInBatches(
20395
20828
  results,
20396
- (record2) => vaultMemoryToStored(record2, ctx.walletAddress, ctx.signMessage, ctx.embeddedWalletSigner)
20829
+ (record3) => vaultMemoryToStored(record3, ctx.walletAddress, ctx.signMessage, ctx.embeddedWalletSigner)
20397
20830
  );
20398
20831
  }
20399
20832
  var TOPICS_EXTRACTION_VERSION = 3;
@@ -20554,17 +20987,17 @@ async function stampTopicsExtractedAtOp(ctx, memoryIds, extractedAt, version = T
20554
20987
  }
20555
20988
  }
20556
20989
  const eligible = records.filter(
20557
- (record2) => !record2.isDeleted && isOwnedByCtxUser(ctx, record2) && !record2.topicsUserManaged
20990
+ (record3) => !record3.isDeleted && isOwnedByCtxUser(ctx, record3) && !record3.topicsUserManaged
20558
20991
  );
20559
- const prepared = eligible.map((record2) => {
20560
- const originalUpdatedAt = record2.updatedAt.getTime();
20561
- return record2.prepareUpdate((r) => {
20992
+ const prepared = eligible.map((record3) => {
20993
+ const originalUpdatedAt = record3.updatedAt.getTime();
20994
+ return record3.prepareUpdate((r) => {
20562
20995
  r._setRaw("topics_extracted_at", extractedAt);
20563
20996
  r._setRaw("topics_extracted_version", version);
20564
20997
  r._setRaw("updated_at", originalUpdatedAt);
20565
20998
  });
20566
20999
  });
20567
- for (const record2 of eligible) stamped.push(record2.id);
21000
+ for (const record3 of eligible) stamped.push(record3.id);
20568
21001
  if (prepared.length > 0) await ctx.database.batch(...prepared);
20569
21002
  });
20570
21003
  }
@@ -20580,14 +21013,14 @@ async function relinkMemoryTopicsOp(ctx, memoryIds) {
20580
21013
  try {
20581
21014
  await ctx.database.write(async (writer) => {
20582
21015
  await assertCanWrite2(ctx);
20583
- let record2;
21016
+ let record3;
20584
21017
  try {
20585
- record2 = await ctx.vaultMemoryCollection.find(id2);
21018
+ record3 = await ctx.vaultMemoryCollection.find(id2);
20586
21019
  } catch {
20587
21020
  return;
20588
21021
  }
20589
- if (record2.isDeleted || !isOwnedByCtxUser(ctx, record2)) return;
20590
- const topics = parseTopics(record2.topics);
21022
+ if (record3.isDeleted || !isOwnedByCtxUser(ctx, record3)) return;
21023
+ const topics = parseTopics(record3.topics);
20591
21024
  if (topics === null) return;
20592
21025
  await writer.callWriter(() => relinkMemoryEntitiesFromTopicsOp(entityCtx, id2, topics));
20593
21026
  relinked.push(id2);
@@ -20613,18 +21046,18 @@ async function backfillMemoryTopicsOp(ctx, memoryIds) {
20613
21046
  await assertCanWrite2(ctx);
20614
21047
  const records = [];
20615
21048
  for (const id2 of chunkIds) {
20616
- let record2;
21049
+ let record3;
20617
21050
  try {
20618
- record2 = await ctx.vaultMemoryCollection.find(id2);
21051
+ record3 = await ctx.vaultMemoryCollection.find(id2);
20619
21052
  } catch {
20620
21053
  continue;
20621
21054
  }
20622
- if (record2.isDeleted || !isOwnedByCtxUser(ctx, record2)) continue;
20623
- if (parseTopics(record2.topics) !== null) continue;
20624
- records.push(record2);
21055
+ if (record3.isDeleted || !isOwnedByCtxUser(ctx, record3)) continue;
21056
+ if (parseTopics(record3.topics) !== null) continue;
21057
+ records.push(record3);
20625
21058
  }
20626
21059
  if (records.length === 0) return;
20627
- const links2 = await entityCtx.memoryEntityCollection.query(import_watermelondb24.Q.where("memory_id", import_watermelondb24.Q.oneOf(records.map((record2) => record2.id)))).unsafeFetchRaw();
21060
+ const links2 = await entityCtx.memoryEntityCollection.query(import_watermelondb24.Q.where("memory_id", import_watermelondb24.Q.oneOf(records.map((record3) => record3.id)))).unsafeFetchRaw();
20628
21061
  const entityIds = Array.from(new Set(links2.map((link) => String(link.entity_id))));
20629
21062
  const entitiesById = /* @__PURE__ */ new Map();
20630
21063
  for (let j = 0; j < entityIds.length; j += CHUNK) {
@@ -20644,13 +21077,13 @@ async function backfillMemoryTopicsOp(ctx, memoryIds) {
20644
21077
  entities.add(entity);
20645
21078
  }
20646
21079
  const writes = [];
20647
- for (const record2 of records) {
20648
- const entities = entitiesByMemory.get(record2.id);
21080
+ for (const record3 of records) {
21081
+ const entities = entitiesByMemory.get(record3.id);
20649
21082
  if (!entities?.size) continue;
20650
- const source = record2.topicsUserManaged ? "user" : "auto";
21083
+ const source = record3.topicsUserManaged ? "user" : "auto";
20651
21084
  const write = await resolveMemoryTopicsWrite(
20652
21085
  entityCtx,
20653
- record2.id,
21086
+ record3.id,
20654
21087
  Array.from(entities),
20655
21088
  [],
20656
21089
  source
@@ -20672,7 +21105,7 @@ async function deleteAllVaultMemoriesForUserOp(ctx, userId) {
20672
21105
  await ctx.database.write(async () => {
20673
21106
  await assertCanWrite2(ctx);
20674
21107
  const prepared = records.map(
20675
- (record2) => record2.prepareUpdate((r) => {
21108
+ (record3) => record3.prepareUpdate((r) => {
20676
21109
  r._setRaw("is_deleted", true);
20677
21110
  })
20678
21111
  );
@@ -20743,22 +21176,22 @@ async function applyDecayTransitionsOp(ctx, candidates, opts) {
20743
21176
  import_watermelondb24.Q.where("id", import_watermelondb24.Q.oneOf(ids.slice(i, i + CHUNK))),
20744
21177
  ...ctx.userId !== void 0 ? [import_watermelondb24.Q.where("user_id", ctx.userId)] : []
20745
21178
  ).fetch();
20746
- const eligible = records.filter((record2) => {
20747
- if (record2.isDeleted || !isOwnedByCtxUser(ctx, record2)) return false;
21179
+ const eligible = records.filter((record3) => {
21180
+ if (record3.isDeleted || !isOwnedByCtxUser(ctx, record3)) return false;
20748
21181
  if (opts.transition === "delete") {
20749
- return record2.archivedAt !== null && opts.now - record2.archivedAt > opts.hardDeleteWindowMs;
21182
+ return record3.archivedAt !== null && opts.now - record3.archivedAt > opts.hardDeleteWindowMs;
20750
21183
  }
20751
- const candidate = byId.get(record2.id);
20752
- return record2.archivedAt === null && record2.updatedAt.getTime() === candidate.updatedAt && (record2.lastObservedAt ?? null) === (candidate.lastObservedAt ?? null);
21184
+ const candidate = byId.get(record3.id);
21185
+ return record3.archivedAt === null && record3.updatedAt.getTime() === candidate.updatedAt && (record3.lastObservedAt ?? null) === (candidate.lastObservedAt ?? null);
20753
21186
  });
20754
21187
  const prepared = eligible.map(
20755
- (record2) => record2.prepareUpdate((row) => {
21188
+ (record3) => record3.prepareUpdate((row) => {
20756
21189
  if (opts.transition === "archive") row._setRaw("archived_at", opts.now);
20757
21190
  else row._setRaw("is_deleted", true);
20758
21191
  })
20759
21192
  );
20760
21193
  if (prepared.length > 0) await ctx.database.batch(prepared);
20761
- applied = eligible.map((record2) => record2.id);
21194
+ applied = eligible.map((record3) => record3.id);
20762
21195
  });
20763
21196
  } catch {
20764
21197
  continue;
@@ -20776,21 +21209,21 @@ async function applyDecayTransitionsOp(ctx, candidates, opts) {
20776
21209
  }
20777
21210
  async function archiveVaultMemoryOp(ctx, id2, opts) {
20778
21211
  try {
20779
- const record2 = await ctx.vaultMemoryCollection.find(id2);
20780
- if (record2.isDeleted || !isOwnedByCtxUser(ctx, record2)) return false;
21212
+ const record3 = await ctx.vaultMemoryCollection.find(id2);
21213
+ if (record3.isDeleted || !isOwnedByCtxUser(ctx, record3)) return false;
20781
21214
  let stale = false;
20782
21215
  const archivedAtValue = opts?.now ?? Date.now();
20783
21216
  await ctx.database.write(async () => {
20784
21217
  await assertCanWrite2(ctx);
20785
- if (record2.isDeleted || !isOwnedByCtxUser(ctx, record2) || record2.archivedAt !== null) {
21218
+ if (record3.isDeleted || !isOwnedByCtxUser(ctx, record3) || record3.archivedAt !== null) {
20786
21219
  stale = true;
20787
21220
  return;
20788
21221
  }
20789
- if (opts?.expectedUpdatedAt !== void 0 && record2.updatedAt.getTime() !== opts.expectedUpdatedAt || opts?.expectedLastObservedAt !== void 0 && (record2.lastObservedAt ?? null) !== opts.expectedLastObservedAt) {
21222
+ if (opts?.expectedUpdatedAt !== void 0 && record3.updatedAt.getTime() !== opts.expectedUpdatedAt || opts?.expectedLastObservedAt !== void 0 && (record3.lastObservedAt ?? null) !== opts.expectedLastObservedAt) {
20790
21223
  stale = true;
20791
21224
  return;
20792
21225
  }
20793
- await record2.update((r) => {
21226
+ await record3.update((r) => {
20794
21227
  r._setRaw("archived_at", archivedAtValue);
20795
21228
  });
20796
21229
  });
@@ -20801,16 +21234,16 @@ async function archiveVaultMemoryOp(ctx, id2, opts) {
20801
21234
  }
20802
21235
  async function restoreVaultMemoryOp(ctx, id2) {
20803
21236
  try {
20804
- const record2 = await ctx.vaultMemoryCollection.find(id2);
20805
- if (record2.isDeleted || !isOwnedByCtxUser(ctx, record2)) return false;
21237
+ const record3 = await ctx.vaultMemoryCollection.find(id2);
21238
+ if (record3.isDeleted || !isOwnedByCtxUser(ctx, record3)) return false;
20806
21239
  let stale = false;
20807
21240
  await ctx.database.write(async () => {
20808
21241
  await assertCanWrite2(ctx);
20809
- if (record2.isDeleted || !isOwnedByCtxUser(ctx, record2)) {
21242
+ if (record3.isDeleted || !isOwnedByCtxUser(ctx, record3)) {
20810
21243
  stale = true;
20811
21244
  return;
20812
21245
  }
20813
- await record2.update((r) => {
21246
+ await record3.update((r) => {
20814
21247
  r._setRaw("archived_at", null);
20815
21248
  });
20816
21249
  });
@@ -20821,18 +21254,18 @@ async function restoreVaultMemoryOp(ctx, id2) {
20821
21254
  }
20822
21255
  async function hardDeleteDecayedOp(ctx, id2, opts) {
20823
21256
  try {
20824
- const record2 = await ctx.vaultMemoryCollection.find(id2);
20825
- if (record2.isDeleted || !isOwnedByCtxUser(ctx, record2)) return false;
21257
+ const record3 = await ctx.vaultMemoryCollection.find(id2);
21258
+ if (record3.isDeleted || !isOwnedByCtxUser(ctx, record3)) return false;
20826
21259
  const now = opts.now ?? Date.now();
20827
21260
  let stale = false;
20828
21261
  await ctx.database.write(async () => {
20829
21262
  await assertCanWrite2(ctx);
20830
- const archivedAt = record2.archivedAt;
20831
- if (record2.isDeleted || !isOwnedByCtxUser(ctx, record2) || archivedAt === null || now - archivedAt <= opts.hardDeleteWindowMs) {
21263
+ const archivedAt = record3.archivedAt;
21264
+ if (record3.isDeleted || !isOwnedByCtxUser(ctx, record3) || archivedAt === null || now - archivedAt <= opts.hardDeleteWindowMs) {
20832
21265
  stale = true;
20833
21266
  return;
20834
21267
  }
20835
- await record2.update((r) => {
21268
+ await record3.update((r) => {
20836
21269
  r._setRaw("is_deleted", true);
20837
21270
  });
20838
21271
  });
@@ -20850,14 +21283,14 @@ async function hardDeleteDecayedOp(ctx, id2, opts) {
20850
21283
  }
20851
21284
  async function updateVaultMemoryEmbeddingOp(ctx, id2, embedding2, embeddingModel, expected) {
20852
21285
  try {
20853
- const record2 = await ctx.vaultMemoryCollection.find(id2);
20854
- if (record2.isDeleted || !isOwnedByCtxUser(ctx, record2)) return false;
20855
- const readUpdatedAt = record2.updatedAt.getTime();
20856
- const readStoredContent = record2._getRaw("content");
21286
+ const record3 = await ctx.vaultMemoryCollection.find(id2);
21287
+ if (record3.isDeleted || !isOwnedByCtxUser(ctx, record3)) return false;
21288
+ const readUpdatedAt = record3.updatedAt.getTime();
21289
+ const readStoredContent = record3._getRaw("content");
20857
21290
  if (expected?.updatedAt !== void 0 && expected.updatedAt !== readUpdatedAt) return false;
20858
21291
  if (expected?.content !== void 0) {
20859
21292
  const current = await vaultMemoryToStored(
20860
- record2,
21293
+ record3,
20861
21294
  ctx.walletAddress,
20862
21295
  ctx.signMessage,
20863
21296
  ctx.embeddedWalletSigner
@@ -20867,11 +21300,11 @@ async function updateVaultMemoryEmbeddingOp(ctx, id2, embedding2, embeddingModel
20867
21300
  let written = false;
20868
21301
  await ctx.database.write(async () => {
20869
21302
  await assertCanWrite2(ctx);
20870
- if (record2.isDeleted || !isOwnedByCtxUser(ctx, record2)) return;
20871
- const originalUpdatedAt = record2.updatedAt.getTime();
20872
- if (originalUpdatedAt !== readUpdatedAt || record2._getRaw("content") !== readStoredContent)
21303
+ if (record3.isDeleted || !isOwnedByCtxUser(ctx, record3)) return;
21304
+ const originalUpdatedAt = record3.updatedAt.getTime();
21305
+ if (originalUpdatedAt !== readUpdatedAt || record3._getRaw("content") !== readStoredContent)
20873
21306
  return;
20874
- await record2.update((r) => {
21307
+ await record3.update((r) => {
20875
21308
  r._setRaw("embedding", embedding2);
20876
21309
  r._setRaw("embedding_model", embeddingModel);
20877
21310
  r._setRaw("updated_at", originalUpdatedAt);
@@ -21036,26 +21469,26 @@ async function ingestPublishedPhotoMemoriesOp(ctx, rows) {
21036
21469
  inserted = writable.length;
21037
21470
  if (writable.length === 0) return;
21038
21471
  const prepared = writable.map(
21039
- ({ row, content }) => ctx.vaultMemoryCollection.prepareCreate((record2) => {
21040
- record2._raw.id = row.memoryId;
21041
- record2._setRaw("content", content);
21042
- record2._setRaw("scope", "shared");
21043
- record2._setRaw("level", "matching");
21044
- record2._setRaw("folder_id", null);
21045
- record2._setRaw("user_id", ctx.userId ?? null);
21046
- record2._setRaw("is_deleted", false);
21047
- record2._setRaw("proof_count", 1);
21048
- record2._setRaw("source", SOURCE_PHOTO);
21049
- record2._setRaw(
21472
+ ({ row, content }) => ctx.vaultMemoryCollection.prepareCreate((record3) => {
21473
+ record3._raw.id = row.memoryId;
21474
+ record3._setRaw("content", content);
21475
+ record3._setRaw("scope", "shared");
21476
+ record3._setRaw("level", "matching");
21477
+ record3._setRaw("folder_id", null);
21478
+ record3._setRaw("user_id", ctx.userId ?? null);
21479
+ record3._setRaw("is_deleted", false);
21480
+ record3._setRaw("proof_count", 1);
21481
+ record3._setRaw("source", SOURCE_PHOTO);
21482
+ record3._setRaw(
21050
21483
  "media",
21051
21484
  row.media && row.media.length > 0 ? JSON.stringify(row.media) : null
21052
21485
  );
21053
- record2._setRaw("visibility", "public");
21054
- record2._setRaw("published_at", now);
21486
+ record3._setRaw("visibility", "public");
21487
+ record3._setRaw("published_at", now);
21055
21488
  if (row.eventTime) {
21056
- record2._setRaw("event_time_start", row.eventTime.start ?? null);
21057
- record2._setRaw("event_time_end", row.eventTime.end ?? null);
21058
- record2._setRaw("event_time_kind", row.eventTime.kind ?? null);
21489
+ record3._setRaw("event_time_start", row.eventTime.start ?? null);
21490
+ record3._setRaw("event_time_end", row.eventTime.end ?? null);
21491
+ record3._setRaw("event_time_kind", row.eventTime.kind ?? null);
21059
21492
  }
21060
21493
  })
21061
21494
  );
@@ -21887,11 +22320,11 @@ function folderToStored(folder) {
21887
22320
  }
21888
22321
  async function createVaultFolderOp(ctx, opts) {
21889
22322
  const created = await ctx.database.write(async () => {
21890
- return ctx.vaultFolderCollection.create((record2) => {
21891
- record2._setRaw("name", opts.name);
21892
- record2._setRaw("scope", opts.scope ?? "private");
21893
- record2._setRaw("is_system", opts.isSystem ?? false);
21894
- record2._setRaw("is_deleted", false);
22323
+ return ctx.vaultFolderCollection.create((record3) => {
22324
+ record3._setRaw("name", opts.name);
22325
+ record3._setRaw("scope", opts.scope ?? "private");
22326
+ record3._setRaw("is_system", opts.isSystem ?? false);
22327
+ record3._setRaw("is_deleted", false);
21895
22328
  });
21896
22329
  });
21897
22330
  return folderToStored(created);
@@ -21902,14 +22335,14 @@ async function getAllVaultFoldersOp(ctx) {
21902
22335
  }
21903
22336
  async function updateVaultFolderOp(ctx, id2, opts) {
21904
22337
  try {
21905
- const record2 = await ctx.vaultFolderCollection.find(id2);
21906
- if (record2.isDeleted) return null;
21907
- const scopeChanged = opts.scope !== void 0 && opts.scope !== record2.scope;
22338
+ const record3 = await ctx.vaultFolderCollection.find(id2);
22339
+ if (record3.isDeleted) return null;
22340
+ const scopeChanged = opts.scope !== void 0 && opts.scope !== record3.scope;
21908
22341
  const updated = await ctx.database.write(async () => {
21909
22342
  const memories = scopeChanged ? await ctx.vaultMemoryCollection.query(import_watermelondb32.Q.where("folder_id", id2), import_watermelondb32.Q.where("is_deleted", false)).fetch() : [];
21910
22343
  const updates = [];
21911
22344
  updates.push(
21912
- record2.prepareUpdate((r) => {
22345
+ record3.prepareUpdate((r) => {
21913
22346
  if (opts.name !== void 0) r._setRaw("name", opts.name);
21914
22347
  if (opts.scope !== void 0) r._setRaw("scope", opts.scope);
21915
22348
  })
@@ -21932,8 +22365,8 @@ async function updateVaultFolderOp(ctx, id2, opts) {
21932
22365
  }
21933
22366
  async function deleteVaultFolderOp(ctx, id2) {
21934
22367
  try {
21935
- const record2 = await ctx.vaultFolderCollection.find(id2);
21936
- if (record2.isDeleted) return false;
22368
+ const record3 = await ctx.vaultFolderCollection.find(id2);
22369
+ if (record3.isDeleted) return false;
21937
22370
  await ctx.database.write(async () => {
21938
22371
  const memories = await ctx.vaultMemoryCollection.query(import_watermelondb32.Q.where("folder_id", id2), import_watermelondb32.Q.where("is_deleted", false)).fetch();
21939
22372
  const preparedMemories = memories.map(
@@ -21943,7 +22376,7 @@ async function deleteVaultFolderOp(ctx, id2) {
21943
22376
  r._setRaw("scope", "private");
21944
22377
  })
21945
22378
  );
21946
- const preparedFolder = record2.prepareUpdate((r) => {
22379
+ const preparedFolder = record3.prepareUpdate((r) => {
21947
22380
  r._setRaw("is_deleted", true);
21948
22381
  });
21949
22382
  await ctx.database.batch(...preparedMemories, preparedFolder);
@@ -21990,11 +22423,11 @@ async function moveMemoriesToFolderOp(ctx, memoryIds, folderId) {
21990
22423
  }
21991
22424
  async function updateVaultFolderContextOp(ctx, id2, context) {
21992
22425
  try {
21993
- const record2 = await ctx.vaultFolderCollection.find(id2);
21994
- if (record2.isDeleted) return null;
22426
+ const record3 = await ctx.vaultFolderCollection.find(id2);
22427
+ if (record3.isDeleted) return null;
21995
22428
  const updated = await ctx.database.write(async () => {
21996
22429
  await ctx.database.batch(
21997
- record2.prepareUpdate((r) => {
22430
+ record3.prepareUpdate((r) => {
21998
22431
  r._setRaw("context", context);
21999
22432
  })
22000
22433
  );
@@ -23113,9 +23546,9 @@ function loadVaultCorpus(ctx, options, preparation) {
23113
23546
  const key3 = JSON.stringify(options ?? {});
23114
23547
  let request = pending.get(key3);
23115
23548
  if (!request) {
23116
- const entries = pending;
23549
+ const entries2 = pending;
23117
23550
  request = getAllVaultMemoriesOp(ctx, options).catch((error) => {
23118
- entries.delete(key3);
23551
+ entries2.delete(key3);
23119
23552
  throw error;
23120
23553
  });
23121
23554
  pending.set(key3, request);
@@ -23156,7 +23589,7 @@ function embedVaultRows(ctx, options, rows, preparation) {
23156
23589
  if (!pending.has(keys[index]) && !prepared?.has(keys[index])) missing2.set(keys[index], row);
23157
23590
  });
23158
23591
  if (missing2.size > 0) {
23159
- const entries = pending;
23592
+ const entries2 = pending;
23160
23593
  const batch = Promise.resolve().then(
23161
23594
  () => generateEmbeddings(
23162
23595
  [...missing2.values()].map((row) => row.content),
@@ -23173,16 +23606,16 @@ function embedVaultRows(ctx, options, rows, preparation) {
23173
23606
  });
23174
23607
  return vector2;
23175
23608
  }).finally(() => {
23176
- entries.delete(key3);
23177
- if (entries.size === 0) pendingRows.get(ctx)?.delete(options.maskInput);
23609
+ entries2.delete(key3);
23610
+ if (entries2.size === 0) pendingRows.get(ctx)?.delete(options.maskInput);
23178
23611
  });
23179
23612
  pending.set(key3, request);
23180
23613
  });
23181
23614
  }
23182
23615
  return Promise.all(
23183
23616
  keys.map((key3) => {
23184
- const cached = prepared?.get(key3);
23185
- if (cached) return cached;
23617
+ const cached2 = prepared?.get(key3);
23618
+ if (cached2) return cached2;
23186
23619
  const request = pending.get(key3);
23187
23620
  if (!prepared) return request;
23188
23621
  const retained = request.catch((error) => {
@@ -23882,10 +24315,10 @@ async function buildProjectedCorpus(query, vaultCtx, embeddingOptions, cache, qu
23882
24315
  const resolvedThisCall = /* @__PURE__ */ new Set();
23883
24316
  if (!embeddingsDegraded) {
23884
24317
  for (const k2 of keys) {
23885
- const cached = cachedRowVector(cache, k2.uniqueId, k2.updatedAt);
23886
- if (cached && cached.length === queryEmbedding.length) {
24318
+ const cached2 = cachedRowVector(cache, k2.uniqueId, k2.updatedAt);
24319
+ if (cached2 && cached2.length === queryEmbedding.length) {
23887
24320
  corpusStats.cacheHits++;
23888
- vectored.push({ uniqueId: k2.uniqueId, embedding: cached, updatedAt: k2.updatedAt });
24321
+ vectored.push({ uniqueId: k2.uniqueId, embedding: cached2, updatedAt: k2.updatedAt });
23889
24322
  continue;
23890
24323
  }
23891
24324
  corpusStats.cacheMisses++;
@@ -24183,12 +24616,12 @@ async function prepareVaultCandidates(query, vaultCtx, embeddingOptions, cache,
24183
24616
  for (let i = 0; queryEmbedding.length > 0 && i < memories.length; i++) {
24184
24617
  const content = memories[i].content;
24185
24618
  const memoryId = memories[i].uniqueId;
24186
- const cached = cachedRowVector(cache, memoryId, memories[i].updatedAt, content);
24187
- if (cached && cached.length === queryEmbedding.length) {
24188
- resolvedVectors.set(memoryId, cached);
24619
+ const cached2 = cachedRowVector(cache, memoryId, memories[i].updatedAt, content);
24620
+ if (cached2 && cached2.length === queryEmbedding.length) {
24621
+ resolvedVectors.set(memoryId, cached2);
24189
24622
  continue;
24190
24623
  }
24191
- if (cached) cache.delete(memoryId);
24624
+ if (cached2) cache.delete(memoryId);
24192
24625
  const storedModel = memories[i].embeddingModel;
24193
24626
  const modelCompatible = (storedModel ?? currentModel) === currentModel;
24194
24627
  if (memories[i].embedding && modelCompatible) {
@@ -25879,9 +26312,9 @@ function createDecaySweeperOver(backend, options) {
25879
26312
  if (ruleVerdict !== "keep") return rule;
25880
26313
  if (!classifier || !isBorderline(input)) return rule;
25881
26314
  if (input.id) {
25882
- const cached = classifierCache.get(input.id);
25883
- if (cached && cached.activityAt === lastActivityAt(input))
25884
- return { verdict: cached.verdict, source: "classifierDriven" };
26315
+ const cached2 = classifierCache.get(input.id);
26316
+ if (cached2 && cached2.activityAt === lastActivityAt(input))
26317
+ return { verdict: cached2.verdict, source: "classifierDriven" };
25885
26318
  }
25886
26319
  if (sweep.classifierCalls >= maxClassifierCalls) {
25887
26320
  sweep.classifierCapHits++;
@@ -27745,21 +28178,21 @@ async function extractAndLinkEntitiesForMemoriesOp(ctx, memoryIds, options) {
27745
28178
  };
27746
28179
  const inputs = [];
27747
28180
  for (const id2 of new Set(memoryIds)) {
27748
- let record2;
28181
+ let record3;
27749
28182
  try {
27750
- record2 = await ctx.vaultMemoryCollection.find(id2);
28183
+ record3 = await ctx.vaultMemoryCollection.find(id2);
27751
28184
  } catch (err) {
27752
28185
  log.warn("[memory/topics] vault lookup failed for extraction", err);
27753
28186
  skip(id2, "not-found");
27754
28187
  continue;
27755
28188
  }
27756
- if (record2.isDeleted || ctx.userId !== void 0 && record2.userId !== ctx.userId || record2.topicsUserManaged) {
28189
+ if (record3.isDeleted || ctx.userId !== void 0 && record3.userId !== ctx.userId || record3.topicsUserManaged) {
27757
28190
  skip(id2, "excluded");
27758
28191
  continue;
27759
28192
  }
27760
28193
  try {
27761
28194
  const stored2 = await vaultMemoryToStored(
27762
- record2,
28195
+ record3,
27763
28196
  ctx.walletAddress,
27764
28197
  ctx.signMessage,
27765
28198
  ctx.embeddedWalletSigner
@@ -28066,6 +28499,7 @@ function createLocalMemoryStore(options) {
28066
28499
 
28067
28500
  // src/lib/memory/store/memoryKeys.ts
28068
28501
  var KEY_ID_DOMAIN = "anuma-private-memory-key-id-v1";
28502
+ var TOPIC_HASH_INFO = "anuma-private-memory-topic-hash-v1";
28069
28503
  var MemoryKeyError = class extends Error {
28070
28504
  constructor(message) {
28071
28505
  super(message);
@@ -28081,17 +28515,40 @@ async function importAesKey(hex) {
28081
28515
  ["encrypt", "decrypt"]
28082
28516
  );
28083
28517
  }
28518
+ async function deriveTopicHashKey(hex) {
28519
+ const material = await crypto.subtle.importKey(
28520
+ "raw",
28521
+ hexToBytes(hex).buffer,
28522
+ { name: "HKDF" },
28523
+ false,
28524
+ ["deriveBits"]
28525
+ );
28526
+ const bits = await crypto.subtle.deriveBits(
28527
+ {
28528
+ name: "HKDF",
28529
+ hash: "SHA-256",
28530
+ salt: new Uint8Array(32),
28531
+ info: new TextEncoder().encode(TOPIC_HASH_INFO)
28532
+ },
28533
+ material,
28534
+ 256
28535
+ );
28536
+ return crypto.subtle.importKey("raw", bits, { name: "HMAC", hash: "SHA-256" }, false, ["sign"]);
28537
+ }
28538
+ function toHex(bytes4) {
28539
+ return Array.from(new Uint8Array(bytes4), (byte) => byte.toString(16).padStart(2, "0")).join("");
28540
+ }
28084
28541
  async function deriveMemoryKeyRing(signatureHex) {
28085
28542
  const v3Hex = await deriveKeyFromSignatureV3(signatureHex);
28086
28543
  const digest = await crypto.subtle.digest(
28087
28544
  "SHA-256",
28088
28545
  new TextEncoder().encode(`${KEY_ID_DOMAIN}:${v3Hex}`)
28089
28546
  );
28090
- const keyId = "v3:" + Array.from(new Uint8Array(digest), (byte) => byte.toString(16).padStart(2, "0")).join("");
28091
28547
  return {
28092
- keyId,
28548
+ keyId: "v3:" + toHex(digest),
28093
28549
  v3: await importAesKey(v3Hex),
28094
- v2: await importAesKey(await deriveKeyFromSignature(signatureHex))
28550
+ v2: await importAesKey(await deriveKeyFromSignature(signatureHex)),
28551
+ topicHash: await deriveTopicHashKey(v3Hex)
28095
28552
  };
28096
28553
  }
28097
28554
  async function decryptWith(value, rings) {
@@ -28112,7 +28569,10 @@ function memoryCipher(canonical) {
28112
28569
  if (!ciphertext.startsWith("enc:v3:") || !isEncrypted(ciphertext))
28113
28570
  throw new MemoryKeyError("Remote memory content must be enc:v3 ciphertext");
28114
28571
  return decryptWith(ciphertext, [canonical]);
28115
- }
28572
+ },
28573
+ hashTopic: async (normalized2) => toHex(
28574
+ await crypto.subtle.sign("HMAC", canonical.topicHash, new TextEncoder().encode(normalized2))
28575
+ )
28116
28576
  };
28117
28577
  }
28118
28578
  async function reencryptMemoryField(value, canonical, fallbacks = []) {
@@ -28548,8 +29008,9 @@ var DEFAULT_RATE_LIMIT_WAIT_MS = 1e4;
28548
29008
  var MAX_ID_BYTES = 128;
28549
29009
  var MAX_CONTENT_BYTES = 32 << 10;
28550
29010
  var MAX_TEXT_BYTES = 16 << 10;
29011
+ var MAX_TOPICS_BYTES = 32 << 10;
28551
29012
  var MAX_SHORT_BYTES = 256;
28552
- var TEXT_FIELDS = ["topics", "media", "source_chunk_ids"];
29013
+ var TEXT_FIELDS = ["media", "source_chunk_ids"];
28553
29014
  var SHORT_FIELDS = [
28554
29015
  "scope",
28555
29016
  "kind",
@@ -28652,7 +29113,7 @@ function bytes3(value) {
28652
29113
  return value === void 0 ? 0 : utf82.encode(value).length;
28653
29114
  }
28654
29115
  function fitsNearby(row) {
28655
- 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);
29116
+ 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);
28656
29117
  }
28657
29118
  function invalid2(raw) {
28658
29119
  const id2 = raw.id;
@@ -28696,7 +29157,7 @@ function defined(value) {
28696
29157
  Object.entries(value).filter(([, field10]) => field10 !== void 0)
28697
29158
  );
28698
29159
  }
28699
- async function prepareRow(raw, canonical, rings, model, updatedAt) {
29160
+ async function prepareRow(raw, canonical, codec, rings, model, updatedAt) {
28700
29161
  const deleted = bool(raw.is_deleted) ?? false;
28701
29162
  const { encrypt } = memoryCipher(canonical);
28702
29163
  const localKindValue = text15(raw.kind_value);
@@ -28710,10 +29171,12 @@ async function prepareRow(raw, canonical, rings, model, updatedAt) {
28710
29171
  plaintext = void 0;
28711
29172
  kindValue = void 0;
28712
29173
  }
29174
+ const fields = metadata2(raw, model);
28713
29175
  const row = {
28714
29176
  ...defined({
28715
- ...metadata2(raw, model),
28716
- kind_value: kindValue === void 0 ? void 0 : await encrypt(kindValue)
29177
+ ...fields,
29178
+ kind_value: kindValue === void 0 ? void 0 : await encrypt(kindValue),
29179
+ topics: fields.topics === void 0 ? void 0 : await codec.encodeTopics(fields.topics)
28717
29180
  }),
28718
29181
  memory_id: raw.id,
28719
29182
  content: await encrypt(plaintext ?? ""),
@@ -28757,6 +29220,8 @@ function sameMetadata2(local, remote, model) {
28757
29220
  if (field10 === "visibility") return (a ?? "private") === (b ?? "private");
28758
29221
  if (field10 === "is_deleted" || field10 === "topics_user_managed" || field10 === "twin_opt_in")
28759
29222
  return (a ?? false) === (b ?? false);
29223
+ if (field10 === "topics")
29224
+ return JSON.stringify(parseTopics(a)) === JSON.stringify(parseTopics(b));
28760
29225
  return a === b;
28761
29226
  });
28762
29227
  }
@@ -28812,7 +29277,7 @@ async function missingIds(request, revisions, signal) {
28812
29277
  }
28813
29278
  return missing2;
28814
29279
  }
28815
- async function remoteMetadata(request, ids, signal) {
29280
+ async function remoteMetadata(request, codec, ids, signal) {
28816
29281
  const rows = /* @__PURE__ */ new Map();
28817
29282
  for (const batch of chunks(ids, QUERY_IDS)) {
28818
29283
  let cursor;
@@ -28836,7 +29301,12 @@ async function remoteMetadata(request, ids, signal) {
28836
29301
  if (!Array.isArray(page.items)) throw new Error("Invalid nearby private-memory page");
28837
29302
  for (const item of page.items)
28838
29303
  if (item.memory && typeof item.memory.memory_id === "string")
28839
- rows.set(item.memory.memory_id, item.memory);
29304
+ rows.set(item.memory.memory_id, {
29305
+ ...item.memory,
29306
+ ...typeof item.memory.topics === "string" && {
29307
+ topics: await codec.decodeTopics(item.memory.topics).catch(() => null)
29308
+ }
29309
+ });
28840
29310
  cursor = typeof page.next_cursor === "string" ? page.next_cursor : void 0;
28841
29311
  } while (cursor);
28842
29312
  }
@@ -28854,6 +29324,7 @@ async function migrateMemoriesToRemote(options) {
28854
29324
  const rings = [canonical, ...options.fallbacks ?? []];
28855
29325
  const model = options.embeddingOptions?.model ?? DEFAULT_API_EMBEDDING_MODEL;
28856
29326
  const request = createNearbyRequest(options);
29327
+ const codec = createTopicCodec(memoryCipher(canonical));
28857
29328
  const account = await request("/account", {}, signal);
28858
29329
  if (typeof account.key_id === "string" && account.key_id !== canonical.keyId)
28859
29330
  throw new RemoteMemoryError(
@@ -28870,7 +29341,7 @@ async function migrateMemoriesToRemote(options) {
28870
29341
  ...typeof t.kind === "string" && { kind: t.kind }
28871
29342
  })).filter((t) => t.name.length > 0) : []);
28872
29343
  if (localTopics.length)
28873
- await createRemoteTopicPersistence(request).importTopics(localTopics, signal);
29344
+ await createRemoteTopicPersistence(request, codec).importTopics(localTopics, signal);
28874
29345
  const skipped = /* @__PURE__ */ new Map();
28875
29346
  const reembedded = /* @__PURE__ */ new Set();
28876
29347
  const unembedded = /* @__PURE__ */ new Set();
@@ -28889,6 +29360,7 @@ async function migrateMemoriesToRemote(options) {
28889
29360
  if (pending.size === 0 && !active) {
28890
29361
  const remote = await remoteMetadata(
28891
29362
  request,
29363
+ codec,
28892
29364
  candidates.map((raw) => raw.id),
28893
29365
  signal
28894
29366
  );
@@ -28933,7 +29405,7 @@ async function migrateMemoriesToRemote(options) {
28933
29405
  const updatedAt = pending.get(raw.id);
28934
29406
  if (updatedAt === void 0) continue;
28935
29407
  try {
28936
- prepared.push(await prepareRow(raw, canonical, rings, model, updatedAt));
29408
+ prepared.push(await prepareRow(raw, canonical, codec, rings, model, updatedAt));
28937
29409
  } catch (error) {
28938
29410
  if (!(error instanceof MemoryKeyError)) throw error;
28939
29411
  skipped.set(raw.id, "unreadable");
@@ -29093,7 +29565,7 @@ function topicInputs(topics, source) {
29093
29565
  function mergeTopics(existing, added) {
29094
29566
  const byName = /* @__PURE__ */ new Map();
29095
29567
  for (const topic2 of [...existing, ...added]) {
29096
- const key3 = normalizeEntityName(topic2.name);
29568
+ const key3 = normalizeTopicName(topic2.name);
29097
29569
  const kept = byName.get(key3);
29098
29570
  if (!kept) byName.set(key3, topic2);
29099
29571
  else if (kept.weight !== void 0 && topic2.weight !== void 0 && topic2.weight > kept.weight)
@@ -29108,7 +29580,7 @@ function sameTopics(stored2, next) {
29108
29580
  return next.every((t) => keys.has(key3(t)));
29109
29581
  }
29110
29582
  function canonicalTopics(row) {
29111
- return new Set((parseTopics(row.topics) ?? []).map((topic2) => normalizeEntityName(topic2.name)));
29583
+ return new Set((parseTopics(row.topics) ?? []).map((topic2) => normalizeTopicName(topic2.name)));
29112
29584
  }
29113
29585
  function createRemoteMemoryStore(options) {
29114
29586
  const { persistence, embeddingOptions } = options;
@@ -29155,10 +29627,10 @@ function createRemoteMemoryStore(options) {
29155
29627
  const notify = (change, records = []) => {
29156
29628
  invalidateReads();
29157
29629
  if (subscribers.size)
29158
- for (const record2 of records) {
29159
- const previous = seen.get(record2.memory.memory_id);
29160
- if ((previous?.version ?? 0) + 1 === record2.version)
29161
- seen.set(record2.memory.memory_id, subscriptionState(record2));
29630
+ for (const record3 of records) {
29631
+ const previous = seen.get(record3.memory.memory_id);
29632
+ if ((previous?.version ?? 0) + 1 === record3.version)
29633
+ seen.set(record3.memory.memory_id, subscriptionState(record3));
29162
29634
  }
29163
29635
  for (const subscriber of [...subscribers])
29164
29636
  if (relevant(change, subscriber.options)) safely(subscriber.onChange);
@@ -29211,7 +29683,7 @@ function createRemoteMemoryStore(options) {
29211
29683
  };
29212
29684
  const enumerate = (filters, max = Infinity) => pages(decrypted, filters, max);
29213
29685
  const memoriesByTopics = async (names) => {
29214
- const wanted = new Set(names.map(normalizeEntityName).filter(Boolean));
29686
+ const wanted = new Set(names.map(normalizeTopicName).filter(Boolean));
29215
29687
  const out = /* @__PURE__ */ new Map();
29216
29688
  const pages2 = await Promise.all(
29217
29689
  chunks2([...wanted], MAX_QUERY_TOPICS).map((topics) => enumerate({ topics }))
@@ -29223,7 +29695,7 @@ function createRemoteMemoryStore(options) {
29223
29695
  return out;
29224
29696
  };
29225
29697
  const topicGraphRanking = async (query, recallOptions = {}) => {
29226
- const wanted = new Set(extractQueryEntities(query).map(normalizeEntityName).filter(Boolean));
29698
+ const wanted = new Set(extractQueryEntities(query).map(normalizeTopicName).filter(Boolean));
29227
29699
  if (wanted.size === 0 || recallOptions.memoryIds?.length === 0) return [];
29228
29700
  const rows = await pages(
29229
29701
  metadata3,
@@ -29281,25 +29753,25 @@ function createRemoteMemoryStore(options) {
29281
29753
  return run;
29282
29754
  };
29283
29755
  const live2 = async (id2) => {
29284
- const record2 = await persistence.get(id2);
29285
- return record2 && !record2.memory.is_deleted ? record2 : null;
29756
+ const record3 = await persistence.get(id2);
29757
+ return record3 && !record3.memory.is_deleted ? record3 : null;
29286
29758
  };
29287
29759
  const mutateLocked = async (id2, change, edit, writeOptions) => {
29288
29760
  writeOptions?.signal?.throwIfAborted();
29289
- const record2 = writeOptions?.signal ? await persistence.get(id2, writeOptions.signal) : await live2(id2);
29290
- if (!record2) return null;
29291
- if (record2.memory.is_deleted) return null;
29761
+ const record3 = writeOptions?.signal ? await persistence.get(id2, writeOptions.signal) : await live2(id2);
29762
+ if (!record3) return null;
29763
+ if (record3.memory.is_deleted) return null;
29292
29764
  if (writeOptions?.canWrite && !await writeOptions.canWrite())
29293
29765
  throw new MemorySourceIneligibleError();
29294
29766
  writeOptions?.signal?.throwIfAborted();
29295
- const next = edit(structuredClone(record2.memory));
29767
+ const next = edit(structuredClone(record3.memory));
29296
29768
  if (!next) return null;
29297
29769
  const saved = writeOptions?.leaseToken ? (await persistence.putMany(
29298
- [{ memory: next, expectedVersion: record2 }],
29770
+ [{ memory: next, expectedVersion: record3 }],
29299
29771
  writeOptions.signal,
29300
29772
  writeOptions.leaseToken
29301
- ))[0] : writeOptions?.signal ? await persistence.put(next, record2, writeOptions.signal) : await persistence.put(next, record2);
29302
- notify(typeof change === "function" ? change(record2.memory) : change, [saved]);
29773
+ ))[0] : writeOptions?.signal ? await persistence.put(next, record3, writeOptions.signal) : await persistence.put(next, record3);
29774
+ notify(typeof change === "function" ? change(record3.memory) : change, [saved]);
29303
29775
  return saved;
29304
29776
  };
29305
29777
  const mutate = (id2, change, edit, writeOptions) => serialized(id2, () => mutateLocked(id2, change, edit, writeOptions));
@@ -29321,12 +29793,12 @@ function createRemoteMemoryStore(options) {
29321
29793
  }
29322
29794
  const { records, unreadable } = read;
29323
29795
  for (const id2 of slice) {
29324
- const record2 = records.get(id2);
29796
+ const record3 = records.get(id2);
29325
29797
  if (unreadable.has(id2)) failed.set(id2, new Error(`Memory ${id2} could not be decrypted`));
29326
- else if (!record2) failed.set(id2, new Error(`Memory ${id2} was not found`));
29327
- else if (!record2.memory.is_deleted) {
29328
- const memory = edit(structuredClone(record2.memory));
29329
- if (memory) writes.push({ before: record2, memory });
29798
+ else if (!record3) failed.set(id2, new Error(`Memory ${id2} was not found`));
29799
+ else if (!record3.memory.is_deleted) {
29800
+ const memory = edit(structuredClone(record3.memory));
29801
+ if (memory) writes.push({ before: record3, memory });
29330
29802
  }
29331
29803
  }
29332
29804
  if (writes.length === 0) return;
@@ -29337,10 +29809,10 @@ function createRemoteMemoryStore(options) {
29337
29809
  leaseToken
29338
29810
  );
29339
29811
  const byChange = /* @__PURE__ */ new Map();
29340
- written.forEach((record2, i) => {
29341
- saved.set(record2.memory.memory_id, record2);
29812
+ written.forEach((record3, i) => {
29813
+ saved.set(record3.memory.memory_id, record3);
29342
29814
  const kind = change(writes[i].before.memory);
29343
- byChange.set(kind, [...byChange.get(kind) ?? [], record2]);
29815
+ byChange.set(kind, [...byChange.get(kind) ?? [], record3]);
29344
29816
  });
29345
29817
  for (const [kind, changed] of byChange) notify(kind, changed);
29346
29818
  } catch (error) {
@@ -29354,13 +29826,13 @@ function createRemoteMemoryStore(options) {
29354
29826
  continue;
29355
29827
  }
29356
29828
  try {
29357
- const record2 = await mutateLocked(
29829
+ const record3 = await mutateLocked(
29358
29830
  id2,
29359
29831
  change,
29360
29832
  edit,
29361
29833
  leaseToken || signal ? { leaseToken, signal } : void 0
29362
29834
  );
29363
- if (record2) saved.set(id2, record2);
29835
+ if (record3) saved.set(id2, record3);
29364
29836
  } catch (rowError) {
29365
29837
  signal?.throwIfAborted();
29366
29838
  if (isRemoteWorkLeaseExpired(rowError)) throw rowError;
@@ -29456,12 +29928,12 @@ function createRemoteMemoryStore(options) {
29456
29928
  const created = (records, inputs) => {
29457
29929
  embedInBackground(records.filter((_, i) => inputs[i].embedding === void 0));
29458
29930
  notify("membership", records);
29459
- return records.map((record2) => stored(record2.memory));
29931
+ return records.map((record3) => stored(record3.memory));
29460
29932
  };
29461
- const asStored = (record2) => record2 ? stored(record2.memory) : null;
29933
+ const asStored = (record3) => record3 ? stored(record3.memory) : null;
29462
29934
  const knownKinds = async (topics, signal) => {
29463
29935
  const unkinded = [
29464
- ...new Set(topics.filter((t) => !t.kind).map((t) => normalizeEntityName(t.name)))
29936
+ ...new Set(topics.filter((t) => !t.kind).map((t) => normalizeTopicName(t.name)))
29465
29937
  ];
29466
29938
  const kinds2 = /* @__PURE__ */ new Map();
29467
29939
  for (const names of chunks2(unkinded, MAX_QUERY_TOPICS)) {
@@ -29473,13 +29945,13 @@ function createRemoteMemoryStore(options) {
29473
29945
  ...signal && { signal }
29474
29946
  })) {
29475
29947
  for (const topic2 of parseTopics(memory.topics) ?? []) {
29476
- const name = normalizeEntityName(topic2.name);
29948
+ const name = normalizeTopicName(topic2.name);
29477
29949
  if (topic2.kind && !kinds2.has(name)) kinds2.set(name, topic2.kind);
29478
29950
  }
29479
29951
  }
29480
29952
  }
29481
29953
  return (topic2) => {
29482
- const kind = topic2.kind ?? kinds2.get(normalizeEntityName(topic2.name));
29954
+ const kind = topic2.kind ?? kinds2.get(normalizeTopicName(topic2.name));
29483
29955
  return kind ? { ...topic2, kind } : topic2;
29484
29956
  };
29485
29957
  };
@@ -29502,7 +29974,7 @@ function createRemoteMemoryStore(options) {
29502
29974
  ...cursor2 && { cursor: cursor2 }
29503
29975
  });
29504
29976
  warnFailed(page.failed);
29505
- for (const record2 of page.items) records.set(record2.memory.memory_id, record2);
29977
+ for (const record3 of page.items) records.set(record3.memory.memory_id, record3);
29506
29978
  for (const failure of page.failed) unreadable.add(failure.memory_id);
29507
29979
  cursor2 = page.next_cursor;
29508
29980
  } while (cursor2);
@@ -29698,8 +30170,8 @@ function createRemoteMemoryStore(options) {
29698
30170
  const failed = /* @__PURE__ */ new Map();
29699
30171
  const collect = (page) => {
29700
30172
  warnFailed(page.failed);
29701
- for (const record2 of page.items)
29702
- records.push({ id: record2.memory.memory_id, state: subscriptionState(record2) });
30173
+ for (const record3 of page.items)
30174
+ records.push({ id: record3.memory.memory_id, state: subscriptionState(record3) });
29703
30175
  for (const failure of page.failed) failed.set(failure.memory_id, failure.version);
29704
30176
  };
29705
30177
  let resume = cursor2;
@@ -29904,7 +30376,7 @@ function createRemoteMemoryStore(options) {
29904
30376
  result.failed += targets.length;
29905
30377
  return finish();
29906
30378
  }
29907
- const writes = targets.flatMap((record2, i) => {
30379
+ const writes = targets.flatMap((record3, i) => {
29908
30380
  const vector2 = vectors[i];
29909
30381
  if (!vector2) {
29910
30382
  result.failed++;
@@ -29914,11 +30386,11 @@ function createRemoteMemoryStore(options) {
29914
30386
  return [
29915
30387
  {
29916
30388
  memory: {
29917
- ...record2.memory,
30389
+ ...record3.memory,
29918
30390
  embedding: storedVector(vector2),
29919
30391
  embedding_model: model
29920
30392
  },
29921
- expectedVersion: record2
30393
+ expectedVersion: record3
29922
30394
  }
29923
30395
  ];
29924
30396
  } catch {
@@ -29933,7 +30405,7 @@ function createRemoteMemoryStore(options) {
29933
30405
  signal?.throwIfAborted();
29934
30406
  const commit = async (slice) => {
29935
30407
  const saved = await persistence.putMany(slice, signal, leaseToken);
29936
- for (const record2 of saved) repaired.add(record2.memory.memory_id);
30408
+ for (const record3 of saved) repaired.add(record3.memory.memory_id);
29937
30409
  result.reembedded += saved.length;
29938
30410
  notify("embedding", saved);
29939
30411
  };
@@ -30017,7 +30489,7 @@ function createRemoteMemoryStore(options) {
30017
30489
  if (!topics.length) return;
30018
30490
  const existing = new Set((await readTopics()).map((topic2) => topic2.name));
30019
30491
  const missing2 = topics.flatMap((topic2) => {
30020
- const name = normalizeEntityName(topic2.name);
30492
+ const name = normalizeTopicName(topic2.name);
30021
30493
  if (existing.has(name)) return [];
30022
30494
  existing.add(name);
30023
30495
  return [{ ...topic2, name }];
@@ -30048,7 +30520,7 @@ function createRemoteMemoryStore(options) {
30048
30520
  include_superseded: true
30049
30521
  })) {
30050
30522
  for (const topic2 of parseTopics(memory.topics) ?? []) {
30051
- const name = normalizeEntityName(topic2.name);
30523
+ const name = normalizeTopicName(topic2.name);
30052
30524
  if (!name) continue;
30053
30525
  const entry = topics.get(name) ?? {
30054
30526
  name,
@@ -30086,7 +30558,7 @@ function createRemoteMemoryStore(options) {
30086
30558
  },
30087
30559
  get: async (id2) => asStored(await live2(id2)),
30088
30560
  listArchived: async () => (await enumerate({ archived_only: true, order: "archived", include_embeddings: true })).map(
30089
- (record2) => stored(record2.memory)
30561
+ (record3) => stored(record3.memory)
30090
30562
  ),
30091
30563
  memoriesByTopics,
30092
30564
  topicsByMemories: async (memoryIds) => {
@@ -30102,8 +30574,8 @@ function createRemoteMemoryStore(options) {
30102
30574
  return out;
30103
30575
  },
30104
30576
  create: async (input) => {
30105
- const record2 = await persistence.put(newRow(input), 0);
30106
- return created([record2], [input])[0];
30577
+ const record3 = await persistence.put(newRow(input), 0);
30578
+ return created([record3], [input])[0];
30107
30579
  },
30108
30580
  createMany: async (inputs) => {
30109
30581
  const out = [];
@@ -30190,12 +30662,12 @@ function createRemoteMemoryStore(options) {
30190
30662
  (memory) => memory.archived_at === void 0 || memory.archived_at === null ? { ...memory, archived_at: Date.now() } : null
30191
30663
  ),
30192
30664
  restore: (id2) => serialized(id2, async () => {
30193
- const record2 = await live2(id2);
30194
- if (!record2) return false;
30195
- if (record2.memory.archived_at === void 0 || record2.memory.archived_at === null)
30665
+ const record3 = await live2(id2);
30666
+ if (!record3) return false;
30667
+ if (record3.memory.archived_at === void 0 || record3.memory.archived_at === null)
30196
30668
  return true;
30197
- const { archived_at: _archivedAt, ...memory } = record2.memory;
30198
- notify("edit", [await persistence.put(memory, record2)]);
30669
+ const { archived_at: _archivedAt, ...memory } = record3.memory;
30670
+ notify("edit", [await persistence.put(memory, record3)]);
30199
30671
  return true;
30200
30672
  }),
30201
30673
  setTopics: async (memoryId, topics) => {
@@ -30228,8 +30700,8 @@ function createRemoteMemoryStore(options) {
30228
30700
  const now = /* @__PURE__ */ new Date();
30229
30701
  return mergeTopics([], added).map(
30230
30702
  (topic2) => ({
30231
- uniqueId: normalizeEntityName(topic2.name),
30232
- canonicalName: normalizeEntityName(topic2.name),
30703
+ uniqueId: normalizeTopicName(topic2.name),
30704
+ canonicalName: normalizeTopicName(topic2.name),
30233
30705
  kind: topic2.kind ?? null,
30234
30706
  createdAt: now,
30235
30707
  updatedAt: now
@@ -33606,16 +34078,16 @@ var ZipProcessor = class {
33606
34078
  try {
33607
34079
  const arrayBuffer = await dataUrlToArrayBuffer(file.dataUrl);
33608
34080
  const zip = await import_jszip.default.loadAsync(arrayBuffer);
33609
- const entries = [];
34081
+ const entries2 = [];
33610
34082
  const processedContents = [];
33611
34083
  zip.forEach((relativePath, zipEntry) => {
33612
- entries.push({
34084
+ entries2.push({
33613
34085
  path: relativePath,
33614
34086
  isDirectory: zipEntry.dir,
33615
34087
  zipObject: zipEntry
33616
34088
  });
33617
34089
  });
33618
- const visibleEntries = this.includeHidden ? entries : entries.filter((entry) => !this.isHidden(entry.path));
34090
+ const visibleEntries = this.includeHidden ? entries2 : entries2.filter((entry) => !this.isHidden(entry.path));
33619
34091
  visibleEntries.sort((a, b) => {
33620
34092
  if (a.isDirectory !== b.isDirectory) {
33621
34093
  return a.isDirectory ? -1 : 1;
@@ -33729,17 +34201,17 @@ var ZipProcessor = class {
33729
34201
  /**
33730
34202
  * Format the output with file listing and processed contents
33731
34203
  */
33732
- formatOutput(entries, processedContents) {
34204
+ formatOutput(entries2, processedContents) {
33733
34205
  const lines = [];
33734
34206
  lines.push("## Archive Contents\n");
33735
34207
  lines.push("```");
33736
- for (const entry of entries) {
34208
+ for (const entry of entries2) {
33737
34209
  const icon = entry.isDirectory ? "\u{1F4C1}" : "\u{1F4C4}";
33738
34210
  lines.push(`${icon} ${entry.path}`);
33739
34211
  }
33740
34212
  lines.push("```\n");
33741
- const fileCount = entries.filter((e) => !e.isDirectory).length;
33742
- const dirCount = entries.filter((e) => e.isDirectory).length;
34213
+ const fileCount = entries2.filter((e) => !e.isDirectory).length;
34214
+ const dirCount = entries2.filter((e) => e.isDirectory).length;
33743
34215
  lines.push(
33744
34216
  `**Summary:** ${fileCount} file${fileCount !== 1 ? "s" : ""}, ${dirCount} director${dirCount !== 1 ? "ies" : "y"}
33745
34217
  `
@@ -34923,13 +35395,13 @@ function serializeInline(node) {
34923
35395
  function openTag(node, indent, depth, selfClose, maxLineWidth) {
34924
35396
  const head = `<${tagName(node.tag)}`;
34925
35397
  const tail = selfClose ? " />" : ">";
34926
- const entries = Object.entries(node.attrs);
34927
- if (entries.length === 0) return `${head}${tail}`;
34928
- const single = `${head} ${entries.map(([k, v]) => formatAttr(k, v)).join(" ")}${tail}`;
35398
+ const entries2 = Object.entries(node.attrs);
35399
+ if (entries2.length === 0) return `${head}${tail}`;
35400
+ const single = `${head} ${entries2.map(([k, v]) => formatAttr(k, v)).join(" ")}${tail}`;
34929
35401
  if (single.length <= maxLineWidth) return single;
34930
35402
  const attrPad = indent.repeat(depth + 1);
34931
35403
  const closePad = indent.repeat(depth);
34932
- const body = entries.map(([k, v]) => `${attrPad}${formatAttr(k, v)}`).join("\n");
35404
+ const body = entries2.map(([k, v]) => `${attrPad}${formatAttr(k, v)}`).join("\n");
34933
35405
  return `${head}
34934
35406
  ${body}
34935
35407
  ${closePad}${selfClose ? "/>" : ">"}`;
@@ -34941,13 +35413,13 @@ function formatAttr(name, value) {
34941
35413
  return `${name}={${formatObjectAttr(value)}}`;
34942
35414
  }
34943
35415
  function formatObjectAttr(obj) {
34944
- const entries = Object.entries(obj).map(([k, v]) => {
35416
+ const entries2 = Object.entries(obj).map(([k, v]) => {
34945
35417
  const key3 = /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(k) ? k : JSON.stringify(k);
34946
35418
  if (typeof v === "string") return `${key3}: ${JSON.stringify(v)}`;
34947
35419
  if (typeof v === "number") return `${key3}: ${String(v)}`;
34948
35420
  return `${key3}: ${v ? "true" : "false"}`;
34949
35421
  });
34950
- return `{ ${entries.join(", ")} }`;
35422
+ return `{ ${entries2.join(", ")} }`;
34951
35423
  }
34952
35424
  function isSafeJsxText(text16) {
34953
35425
  if (/[<>{}&]/.test(text16)) return false;
@@ -35899,6 +36371,12 @@ function cx(...classes) {
35899
36371
  return classes.filter(Boolean).join(" ");
35900
36372
  }
35901
36373
  var THEMES = { light: "", dark: ".dark" };
36374
+ var SAFE_CSS_KEY = /^[\w-]+$/;
36375
+ var SAFE_CSS_COLOR = /^(?:#(?:[0-9a-f]{3,4}|[0-9a-f]{6}|[0-9a-f]{8})|[a-z]+|(?:rgba?|hsla?|hwb|lab|lch|oklab|oklch)\([\w\s.,%/+-]*\)|var\(--[\w-]+\))$/i;
36376
+ function isSafeCssColor(value) {
36377
+ if (typeof value !== "string" || !SAFE_CSS_COLOR.test(value)) return false;
36378
+ return typeof CSS === "undefined" || typeof CSS.supports !== "function" || CSS.supports("color", value);
36379
+ }
35902
36380
  var ChartContext = React2.createContext(null);
35903
36381
  function useChart() {
35904
36382
  const context = React2.useContext(ChartContext);
@@ -35908,7 +36386,9 @@ function useChart() {
35908
36386
  return context;
35909
36387
  }
35910
36388
  function ChartStyle({ id: id2, config }) {
35911
- const colorConfig = Object.entries(config).filter(([, cfg]) => cfg.theme || cfg.color);
36389
+ const colorConfig = Object.entries(config).filter(
36390
+ ([key3, cfg]) => SAFE_CSS_KEY.test(key3) && (cfg.theme || cfg.color)
36391
+ );
35912
36392
  if (!colorConfig.length) return null;
35913
36393
  return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
35914
36394
  "style",
@@ -35919,7 +36399,7 @@ function ChartStyle({ id: id2, config }) {
35919
36399
  ${prefix} [data-chart=${id2}] {
35920
36400
  ${colorConfig.map(([key3, itemConfig]) => {
35921
36401
  const color = itemConfig.theme?.[theme] || itemConfig.color;
35922
- return color ? ` --color-${key3}: ${color};` : null;
36402
+ return isSafeCssColor(color) ? ` --color-${key3}: ${color};` : null;
35923
36403
  }).join("\n")}
35924
36404
  }
35925
36405
  `
@@ -36108,12 +36588,37 @@ var DEFAULT_COLORS = [
36108
36588
  "var(--chart-4)",
36109
36589
  "var(--chart-5)"
36110
36590
  ];
36591
+ function paletteColor(index) {
36592
+ return index < DEFAULT_COLORS.length ? DEFAULT_COLORS[index] : `hsl(${Math.round(index * 137.508 % 360)} 65% 55%)`;
36593
+ }
36594
+ var compactNumber = new Intl.NumberFormat(void 0, {
36595
+ notation: "compact",
36596
+ maximumSignificantDigits: 3
36597
+ });
36598
+ function cellText(value) {
36599
+ return typeof value === "string" || typeof value === "number" || typeof value === "boolean" ? String(value) : "";
36600
+ }
36601
+ function formatTick(value) {
36602
+ return typeof value === "number" ? compactNumber.format(value) : String(value);
36603
+ }
36604
+ var VISUALLY_HIDDEN = {
36605
+ position: "absolute",
36606
+ width: 1,
36607
+ height: 1,
36608
+ padding: 0,
36609
+ margin: -1,
36610
+ overflow: "hidden",
36611
+ clip: "rect(0, 0, 0, 0)",
36612
+ whiteSpace: "nowrap",
36613
+ border: 0
36614
+ };
36111
36615
  function buildChartConfig(dataKeys, colors) {
36112
36616
  const config = {};
36113
36617
  dataKeys.forEach((key3, i) => {
36618
+ const custom = colors?.[key3];
36114
36619
  config[key3] = {
36115
36620
  label: key3.charAt(0).toUpperCase() + key3.slice(1),
36116
- color: colors?.[key3] || DEFAULT_COLORS[i % DEFAULT_COLORS.length]
36621
+ color: isSafeCssColor(custom) ? custom : paletteColor(i)
36117
36622
  };
36118
36623
  });
36119
36624
  return config;
@@ -36126,68 +36631,106 @@ function ChartCard({ data }) {
36126
36631
  return () => cancelAnimationFrame(frame);
36127
36632
  }, []);
36128
36633
  if ("error" in data) {
36129
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "my-4 max-w-lg", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "rounded-xl bg-sidebar dark:bg-card px-4 py-3", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { className: "text-sm text-muted-foreground", children: data.error }) }) });
36634
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "my-4 max-w-lg", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "rounded-xl bg-sidebar dark:bg-card px-4 py-3", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { className: "text-sm text-muted-foreground", children: "Couldn't display this chart." }) }) });
36130
36635
  }
36131
36636
  const { chartType, title, data: chartData, dataKeys, xAxisKey, colors } = data;
36132
36637
  const chartConfig = buildChartConfig(dataKeys, colors);
36133
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "my-4 max-w-lg", ref: containerRef, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "rounded-xl bg-sidebar dark:bg-card px-5 py-4", children: [
36134
- title && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { className: "text-sm font-medium mb-3", children: title }),
36135
- ready ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ChartContainer, { config: chartConfig, className: "aspect-auto h-[250px] w-full", children: chartType === "bar" ? /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_recharts.BarChart, { data: chartData, children: [
36136
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_recharts.CartesianGrid, { vertical: false }),
36137
- xAxisKey && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_recharts.XAxis, { dataKey: xAxisKey, tickLine: false, axisLine: false, tickMargin: 8 }),
36138
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_recharts.YAxis, { tickLine: false, axisLine: false }),
36139
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ChartTooltip, { content: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ChartTooltipContent, {}) }),
36140
- dataKeys.length > 1 && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ChartLegend, { content: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ChartLegendContent, {}) }),
36141
- dataKeys.map((key3) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_recharts.Bar, { dataKey: key3, fill: `var(--color-${key3})`, radius: 4 }, key3))
36142
- ] }) : chartType === "line" ? /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_recharts.LineChart, { data: chartData, children: [
36143
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_recharts.CartesianGrid, { vertical: false }),
36144
- xAxisKey && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_recharts.XAxis, { dataKey: xAxisKey, tickLine: false, axisLine: false, tickMargin: 8 }),
36145
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_recharts.YAxis, { tickLine: false, axisLine: false }),
36146
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ChartTooltip, { content: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ChartTooltipContent, {}) }),
36147
- dataKeys.length > 1 && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ChartLegend, { content: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ChartLegendContent, {}) }),
36148
- dataKeys.map((key3) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
36149
- import_recharts.Line,
36150
- {
36151
- dataKey: key3,
36152
- stroke: `var(--color-${key3})`,
36153
- strokeWidth: 2,
36154
- dot: false
36155
- },
36156
- key3
36157
- ))
36158
- ] }) : chartType === "area" ? /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_recharts.AreaChart, { data: chartData, children: [
36159
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_recharts.CartesianGrid, { vertical: false }),
36160
- xAxisKey && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_recharts.XAxis, { dataKey: xAxisKey, tickLine: false, axisLine: false, tickMargin: 8 }),
36161
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_recharts.YAxis, { tickLine: false, axisLine: false }),
36162
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ChartTooltip, { content: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ChartTooltipContent, {}) }),
36163
- dataKeys.length > 1 && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ChartLegend, { content: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ChartLegendContent, {}) }),
36164
- dataKeys.map((key3) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
36165
- import_recharts.Area,
36166
- {
36167
- dataKey: key3,
36168
- fill: `var(--color-${key3})`,
36169
- stroke: `var(--color-${key3})`,
36170
- fillOpacity: 0.3
36171
- },
36172
- key3
36173
- ))
36174
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_recharts.PieChart, { children: [
36175
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ChartTooltip, { content: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ChartTooltipContent, {}) }),
36176
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
36177
- import_recharts.Pie,
36178
- {
36179
- data: chartData,
36180
- dataKey: dataKeys[0],
36181
- nameKey: xAxisKey || "name",
36182
- cx: "50%",
36183
- cy: "50%",
36184
- outerRadius: 80,
36185
- children: chartData.map((_, index) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_recharts.Cell, { fill: DEFAULT_COLORS[index % DEFAULT_COLORS.length] }, index))
36186
- }
36187
- ),
36188
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ChartLegend, { content: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ChartLegendContent, { nameKey: xAxisKey || "name" }) })
36189
- ] }) }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "h-[250px] w-full" })
36190
- ] }) });
36638
+ const seriesColor = (key3) => chartConfig[key3]?.color;
36639
+ const longestTick = chartData.reduce(
36640
+ (longest, point) => dataKeys.reduce((max, key3) => {
36641
+ const value = point[key3];
36642
+ return typeof value === "number" ? Math.max(max, formatTick(value).length) : max;
36643
+ }, longest),
36644
+ 0
36645
+ );
36646
+ const yAxisProps = {
36647
+ tickLine: false,
36648
+ axisLine: false,
36649
+ tickFormatter: formatTick,
36650
+ width: Math.min(120, Math.max(40, longestTick * 7 + 16))
36651
+ };
36652
+ const labelKey = chartType === "pie" ? xAxisKey || "name" : xAxisKey;
36653
+ const valueKeys = chartType === "pie" ? dataKeys.slice(0, 1) : dataKeys;
36654
+ const tableColumns = labelKey ? [labelKey, ...valueKeys] : valueKeys;
36655
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
36656
+ "div",
36657
+ {
36658
+ className: "my-4 max-w-lg",
36659
+ ref: containerRef,
36660
+ role: "figure",
36661
+ "aria-label": [title, `${chartType} chart`].filter(Boolean).join(", "),
36662
+ children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "rounded-xl bg-sidebar dark:bg-card px-5 py-4", children: [
36663
+ title && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { className: "text-sm font-medium mb-3", children: title }),
36664
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("table", { style: VISUALLY_HIDDEN, children: [
36665
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("thead", { children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("tr", { children: tableColumns.map((column) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("th", { scope: "col", children: column }, column)) }) }),
36666
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("tbody", { children: chartData.map((point, row) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("tr", { children: tableColumns.map((column) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("td", { children: cellText(point[column]) }, column)) }, row)) })
36667
+ ] }),
36668
+ ready ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
36669
+ ChartContainer,
36670
+ {
36671
+ config: chartConfig,
36672
+ className: "aspect-auto h-[250px] w-full",
36673
+ "aria-hidden": "true",
36674
+ children: chartType === "bar" ? /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_recharts.BarChart, { data: chartData, children: [
36675
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_recharts.CartesianGrid, { vertical: false }),
36676
+ xAxisKey && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_recharts.XAxis, { dataKey: xAxisKey, tickLine: false, axisLine: false, tickMargin: 8 }),
36677
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_recharts.YAxis, { ...yAxisProps }),
36678
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ChartTooltip, { content: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ChartTooltipContent, {}) }),
36679
+ dataKeys.length > 1 && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ChartLegend, { content: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ChartLegendContent, {}) }),
36680
+ dataKeys.map((key3) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_recharts.Bar, { dataKey: key3, fill: seriesColor(key3), radius: 4 }, key3))
36681
+ ] }) : chartType === "line" ? /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_recharts.LineChart, { data: chartData, children: [
36682
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_recharts.CartesianGrid, { vertical: false }),
36683
+ xAxisKey && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_recharts.XAxis, { dataKey: xAxisKey, tickLine: false, axisLine: false, tickMargin: 8 }),
36684
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_recharts.YAxis, { ...yAxisProps }),
36685
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ChartTooltip, { content: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ChartTooltipContent, {}) }),
36686
+ dataKeys.length > 1 && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ChartLegend, { content: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ChartLegendContent, {}) }),
36687
+ dataKeys.map((key3) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
36688
+ import_recharts.Line,
36689
+ {
36690
+ dataKey: key3,
36691
+ stroke: seriesColor(key3),
36692
+ strokeWidth: 2,
36693
+ dot: false
36694
+ },
36695
+ key3
36696
+ ))
36697
+ ] }) : chartType === "area" ? /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_recharts.AreaChart, { data: chartData, children: [
36698
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_recharts.CartesianGrid, { vertical: false }),
36699
+ xAxisKey && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_recharts.XAxis, { dataKey: xAxisKey, tickLine: false, axisLine: false, tickMargin: 8 }),
36700
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_recharts.YAxis, { ...yAxisProps }),
36701
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ChartTooltip, { content: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ChartTooltipContent, {}) }),
36702
+ dataKeys.length > 1 && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ChartLegend, { content: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ChartLegendContent, {}) }),
36703
+ dataKeys.map((key3) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
36704
+ import_recharts.Area,
36705
+ {
36706
+ dataKey: key3,
36707
+ fill: seriesColor(key3),
36708
+ stroke: seriesColor(key3),
36709
+ fillOpacity: 0.3
36710
+ },
36711
+ key3
36712
+ ))
36713
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_recharts.PieChart, { children: [
36714
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ChartTooltip, { content: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ChartTooltipContent, {}) }),
36715
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
36716
+ import_recharts.Pie,
36717
+ {
36718
+ data: chartData,
36719
+ dataKey: dataKeys[0],
36720
+ nameKey: xAxisKey || "name",
36721
+ cx: "50%",
36722
+ cy: "50%",
36723
+ outerRadius: 80,
36724
+ children: chartData.map((_, index) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_recharts.Cell, { fill: paletteColor(index) }, index))
36725
+ }
36726
+ ),
36727
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ChartLegend, { content: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ChartLegendContent, { nameKey: xAxisKey || "name" }) })
36728
+ ] })
36729
+ }
36730
+ ) : /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "h-[250px] w-full" })
36731
+ ] })
36732
+ }
36733
+ );
36191
36734
  }
36192
36735
 
36193
36736
  // src/react/LoggerProvider.tsx
@@ -36334,7 +36877,7 @@ async function uploadFileToICloud(filename, content, backupRevision) {
36334
36877
  const recordName = `backup_${filename.replace(/[^a-zA-Z0-9]/g, "_")}`;
36335
36878
  const arrayBuffer = await content.arrayBuffer();
36336
36879
  const base64Data = uint8ArrayToBase64(new Uint8Array(arrayBuffer));
36337
- const record2 = {
36880
+ const record3 = {
36338
36881
  recordType: RECORD_TYPE,
36339
36882
  recordName,
36340
36883
  fields: {
@@ -36345,7 +36888,7 @@ async function uploadFileToICloud(filename, content, backupRevision) {
36345
36888
  ...backupRevision ? { backupRevision: { value: backupRevision } } : {}
36346
36889
  }
36347
36890
  };
36348
- const response = await database.saveRecords(record2);
36891
+ const response = await database.saveRecords(record3);
36349
36892
  if (!response.records || response.records.length === 0) {
36350
36893
  throw new Error("Failed to upload file to iCloud");
36351
36894
  }
@@ -36372,12 +36915,12 @@ async function listICloudFiles() {
36372
36915
  while (response.continuationMarker) {
36373
36916
  break;
36374
36917
  }
36375
- const files = allRecords.map((record2) => ({
36376
- recordName: record2.recordName,
36377
- filename: record2.fields.filename?.value ?? "",
36378
- modifiedAt: new Date(record2.modified?.timestamp ?? Date.now()),
36379
- backupRevision: record2.fields.backupRevision?.value,
36380
- size: typeof record2.fields.data?.value === "object" && record2.fields.data?.value !== null ? record2.fields.data.value.size : 0
36918
+ const files = allRecords.map((record3) => ({
36919
+ recordName: record3.recordName,
36920
+ filename: record3.fields.filename?.value ?? "",
36921
+ modifiedAt: new Date(record3.modified?.timestamp ?? Date.now()),
36922
+ backupRevision: record3.fields.backupRevision?.value,
36923
+ size: typeof record3.fields.data?.value === "object" && record3.fields.data?.value !== null ? record3.fields.data.value.size : 0
36381
36924
  }));
36382
36925
  return files.sort((a, b) => b.modifiedAt.getTime() - a.modifiedAt.getTime());
36383
36926
  }
@@ -36390,8 +36933,8 @@ async function downloadICloudFile(recordName) {
36390
36933
  if (!response.records || response.records.length === 0) {
36391
36934
  throw new Error(`File not found: ${recordName}`);
36392
36935
  }
36393
- const record2 = response.records[0];
36394
- const dataField = record2.fields.data?.value;
36936
+ const record3 = response.records[0];
36937
+ const dataField = record3.fields.data?.value;
36395
36938
  if (!dataField) {
36396
36939
  throw new Error("No data in record");
36397
36940
  }
@@ -36425,13 +36968,13 @@ async function findICloudFile(filename) {
36425
36968
  if (!response.records || response.records.length === 0) {
36426
36969
  return null;
36427
36970
  }
36428
- const record2 = response.records[0];
36971
+ const record3 = response.records[0];
36429
36972
  return {
36430
- recordName: record2.recordName,
36431
- filename: record2.fields.filename?.value ?? "",
36432
- modifiedAt: new Date(record2.modified?.timestamp ?? Date.now()),
36433
- backupRevision: record2.fields.backupRevision?.value,
36434
- size: typeof record2.fields.data?.value === "object" && record2.fields.data?.value !== null ? record2.fields.data.value.size : 0
36973
+ recordName: record3.recordName,
36974
+ filename: record3.fields.filename?.value ?? "",
36975
+ modifiedAt: new Date(record3.modified?.timestamp ?? Date.now()),
36976
+ backupRevision: record3.fields.backupRevision?.value,
36977
+ size: typeof record3.fields.data?.value === "object" && record3.fields.data?.value !== null ? record3.fields.data.value.size : 0
36435
36978
  };
36436
36979
  }
36437
36980
 
@@ -37787,13 +38330,13 @@ function useConversationRedactors(database, account, storage, secondaryStorage)
37787
38330
  return (0, import_react5.useCallback)(
37788
38331
  (conversationId, nerDetector) => {
37789
38332
  if (!scope.active) return retiredRedactor;
37790
- const cached = scope.redactors.get(conversationId);
37791
- if (cached && cached.detector === nerDetector) {
38333
+ const cached2 = scope.redactors.get(conversationId);
38334
+ if (cached2 && cached2.detector === nerDetector) {
37792
38335
  scope.redactors.delete(conversationId);
37793
- scope.redactors.set(conversationId, cached);
37794
- return cached.redactor;
38336
+ scope.redactors.set(conversationId, cached2);
38337
+ return cached2.redactor;
37795
38338
  }
37796
- if (cached) scope.evicted.push(cached.redactor);
38339
+ if (cached2) scope.evicted.push(cached2.redactor);
37797
38340
  const redactor = new PiiRedactor({ nerDetector });
37798
38341
  scope.redactors.set(conversationId, { redactor, detector: nerDetector });
37799
38342
  if (scope.redactors.size > REDACTOR_LIMIT) {
@@ -41285,11 +41828,11 @@ async function fetchAllModelPages(baseUrl, provider, headers, previous, signal)
41285
41828
  return { pages, models, fetchedAt: Date.now() };
41286
41829
  }
41287
41830
  function loadModels(key3, baseUrl, provider, headers, force, signal) {
41288
- const cached = modelsCache.get(key3);
41289
- if (cached && !force && Date.now() - cached.fetchedAt < MODELS_CACHE_TTL_MS) {
41290
- return Promise.resolve([...cached.models]);
41831
+ const cached2 = modelsCache.get(key3);
41832
+ if (cached2 && !force && Date.now() - cached2.fetchedAt < MODELS_CACHE_TTL_MS) {
41833
+ return Promise.resolve([...cached2.models]);
41291
41834
  }
41292
- const shared = (force ? void 0 : modelsInFlight.get(key3)) ?? startSharedRequest(key3, baseUrl, provider, headers, cached);
41835
+ const shared = (force ? void 0 : modelsInFlight.get(key3)) ?? startSharedRequest(key3, baseUrl, provider, headers, cached2);
41293
41836
  return waitForSharedRequest(key3, shared, signal).then((models) => [...models]);
41294
41837
  }
41295
41838
  function startSharedRequest(key3, baseUrl, provider, headers, previous) {
@@ -42146,20 +42689,20 @@ function startObserve(entry, walletAddress) {
42146
42689
  "updated_at"
42147
42690
  ]).subscribe({
42148
42691
  next: (records) => {
42149
- const record2 = records[0];
42150
- if (!record2) return;
42692
+ const record3 = records[0];
42693
+ if (!record3) return;
42151
42694
  const patch = {
42152
42695
  userPreference: {
42153
- uniqueId: record2.id,
42154
- walletAddress: record2.walletAddress,
42155
- nickname: record2.nickname,
42156
- occupation: record2.occupation,
42157
- description: record2.description,
42158
- models: record2.models,
42159
- personality: record2.personality,
42160
- externalWallets: record2.externalWallets,
42161
- createdAt: record2.createdAt,
42162
- updatedAt: record2.updatedAt
42696
+ uniqueId: record3.id,
42697
+ walletAddress: record3.walletAddress,
42698
+ nickname: record3.nickname,
42699
+ occupation: record3.occupation,
42700
+ description: record3.description,
42701
+ models: record3.models,
42702
+ personality: record3.personality,
42703
+ externalWallets: record3.externalWallets,
42704
+ createdAt: record3.createdAt,
42705
+ updatedAt: record3.updatedAt
42163
42706
  }
42164
42707
  };
42165
42708
  if (isInitialEmission) {