@anuma/sdk 10.3.0 → 10.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1534,6 +1534,7 @@ __export(index_exports, {
1534
1534
  createSelectPaymentWalletTool: () => createSelectPaymentWalletTool,
1535
1535
  createStockPricePreProcessor: () => createStockPricePreProcessor,
1536
1536
  createStreamingDeAnonymizer: () => createStreamingDeAnonymizer,
1537
+ createVaultAttachments: () => createVaultAttachments,
1537
1538
  createVaultChatBackend: () => createVaultChatBackend,
1538
1539
  createVaultEmbeddingCache: () => createVaultEmbeddingCache,
1539
1540
  createVaultFolderOp: () => createVaultFolderOp,
@@ -1598,9 +1599,11 @@ __export(index_exports, {
1598
1599
  isRerankerAvailable: () => isRerankerAvailable,
1599
1600
  localChatBackend: () => localChatBackend,
1600
1601
  maskScopedEmbeddingCache: () => maskScopedEmbeddingCache,
1602
+ maxVaultAttachmentBytes: () => maxVaultAttachmentBytes,
1601
1603
  memoryCipher: () => memoryCipher,
1602
1604
  migrateChatsToRemote: () => migrateChatsToRemote,
1603
1605
  migrateMemoriesToRemote: () => migrateMemoriesToRemote,
1606
+ migrateMessageAttachments: () => migrateMessageAttachments,
1604
1607
  moveMemoriesToFolderOp: () => moveMemoriesToFolderOp,
1605
1608
  noopLogger: () => noopLogger,
1606
1609
  onKeyAvailable: () => onKeyAvailable,
@@ -1654,6 +1657,7 @@ __export(index_exports, {
1654
1657
  useCredits: () => useCredits,
1655
1658
  useEncryption: () => useEncryption,
1656
1659
  useModels: () => useModels,
1660
+ vaultAttachmentRefs: () => vaultAttachmentRefs,
1657
1661
  vaultChatBackend: () => vaultChatBackend,
1658
1662
  verifyMemoriesForPublish: () => verifyMemoriesForPublish,
1659
1663
  xhrTransport: () => xhrTransport
@@ -13521,6 +13525,360 @@ async function migrateChatsToRemote(options) {
13521
13525
  return passes(false);
13522
13526
  }
13523
13527
 
13528
+ // src/lib/chatStore/vaultAttachments.ts
13529
+ var frameVersion = 1;
13530
+ var ivBytes = 12;
13531
+ var tagBytes = 16;
13532
+ var frameOverhead = 1 + ivBytes + tagBytes;
13533
+ var maxCiphertextBytes = 50 * 1024 * 1024;
13534
+ var expirySkewMs = 3e4;
13535
+ var maxRetryAfterMs = 3e4;
13536
+ var maxRefWrites = 5;
13537
+ var uploadWindowMs = 16 * 6e4;
13538
+ var attachmentIdPattern2 = /^[0-9a-f]{32}$/;
13539
+ var maxVaultAttachmentBytes = maxCiphertextBytes - frameOverhead;
13540
+ function additionalData(attachmentId) {
13541
+ return new TextEncoder().encode(`anuma-chat-attachment-v1:${attachmentId}`);
13542
+ }
13543
+ function invalidAttachment() {
13544
+ throw new ChatStoreError("Attachment does not decrypt under this key", 0, "invalid_attachment");
13545
+ }
13546
+ function sendableHeaders(headers) {
13547
+ return Object.fromEntries(
13548
+ Object.entries(headers).filter(([name]) => name.toLowerCase() !== "content-length")
13549
+ );
13550
+ }
13551
+ function transientStatus(status) {
13552
+ return status === 429 || status >= 500;
13553
+ }
13554
+ async function discardBody(response) {
13555
+ await response.body?.cancel().catch(() => void 0);
13556
+ }
13557
+ function createVaultAttachments(options) {
13558
+ const { store, keyRing, cache } = options;
13559
+ const fetcher = options.fetch ?? globalThis.fetch.bind(globalThis);
13560
+ const retries = options.retries ?? 3;
13561
+ const retryDelayMs = options.retryDelayMs ?? 500;
13562
+ const now = options.now ?? Date.now;
13563
+ const sleep4 = (ms2, signal) => new Promise((resolve, reject) => {
13564
+ signal?.throwIfAborted();
13565
+ const timer = setTimeout(() => {
13566
+ signal?.removeEventListener("abort", onAbort);
13567
+ resolve();
13568
+ }, ms2);
13569
+ const onAbort = () => {
13570
+ clearTimeout(timer);
13571
+ reject(signal?.reason);
13572
+ };
13573
+ signal?.addEventListener("abort", onAbort, { once: true });
13574
+ });
13575
+ const pause = (attempt, signal, atLeast = 0) => sleep4(Math.max(atLeast, retryDelayMs * 2 ** attempt), signal);
13576
+ const withRetry = async (call, signal) => {
13577
+ for (let attempt = 0; ; attempt++) {
13578
+ try {
13579
+ return await call();
13580
+ } catch (error) {
13581
+ if (!(error instanceof ChatStoreError) || !transientStatus(error.status) || attempt >= retries || (error.retryAfterMs ?? 0) > maxRetryAfterMs)
13582
+ throw error;
13583
+ await pause(attempt, signal, error.retryAfterMs);
13584
+ }
13585
+ }
13586
+ };
13587
+ const expired = (url) => now() >= Date.parse(url.expiresAt) - expirySkewMs;
13588
+ const seal = async (bytes4, attachmentId) => {
13589
+ const iv = crypto.getRandomValues(new Uint8Array(ivBytes));
13590
+ const sealed2 = new Uint8Array(
13591
+ await crypto.subtle.encrypt(
13592
+ { name: "AES-GCM", iv, additionalData: additionalData(attachmentId) },
13593
+ keyRing.v3,
13594
+ bytes4
13595
+ )
13596
+ );
13597
+ const frame = new Uint8Array(1 + ivBytes + sealed2.length);
13598
+ frame[0] = frameVersion;
13599
+ frame.set(iv, 1);
13600
+ frame.set(sealed2, 1 + ivBytes);
13601
+ return frame;
13602
+ };
13603
+ const open = async (frame, attachmentId) => {
13604
+ if (frame.length < frameOverhead || frame[0] !== frameVersion) invalidAttachment();
13605
+ try {
13606
+ return new Uint8Array(
13607
+ await crypto.subtle.decrypt(
13608
+ {
13609
+ name: "AES-GCM",
13610
+ iv: frame.slice(1, 1 + ivBytes),
13611
+ additionalData: additionalData(attachmentId)
13612
+ },
13613
+ keyRing.v3,
13614
+ frame.slice(1 + ivBytes)
13615
+ )
13616
+ );
13617
+ } catch {
13618
+ return invalidAttachment();
13619
+ }
13620
+ };
13621
+ const put = async (upload, body, signal) => {
13622
+ for (let attempt = 0; ; attempt++) {
13623
+ if (expired(upload)) return "expired";
13624
+ let response;
13625
+ try {
13626
+ response = await fetcher(upload.url, {
13627
+ method: upload.method,
13628
+ headers: sendableHeaders(upload.headers),
13629
+ body,
13630
+ signal
13631
+ });
13632
+ } catch (error) {
13633
+ if (signal?.aborted || attempt >= retries) throw error;
13634
+ await pause(attempt, signal);
13635
+ continue;
13636
+ }
13637
+ await discardBody(response);
13638
+ if (response.ok) return "stored";
13639
+ if (response.status === 403) return "expired";
13640
+ if (!transientStatus(response.status) || attempt >= retries)
13641
+ throw new ChatStoreError(
13642
+ `Attachment upload failed with ${response.status}`,
13643
+ response.status,
13644
+ "attachment_upload_failed"
13645
+ );
13646
+ await pause(attempt, signal);
13647
+ }
13648
+ };
13649
+ const download = async (url, signal) => {
13650
+ for (let attempt = 0; ; attempt++) {
13651
+ if (expired(url)) return "expired";
13652
+ let response;
13653
+ try {
13654
+ response = await fetcher(url.url, {
13655
+ method: url.method,
13656
+ headers: sendableHeaders(url.headers),
13657
+ signal
13658
+ });
13659
+ if (response.ok) return new Uint8Array(await response.arrayBuffer());
13660
+ } catch (error) {
13661
+ if (signal?.aborted || attempt >= retries) throw error;
13662
+ await pause(attempt, signal);
13663
+ continue;
13664
+ }
13665
+ await discardBody(response);
13666
+ if (response.status === 403) return "expired";
13667
+ if (response.status === 404) return "missing";
13668
+ if (!transientStatus(response.status) || attempt >= retries)
13669
+ throw new ChatStoreError(
13670
+ `Attachment download failed with ${response.status}`,
13671
+ response.status,
13672
+ "attachment_download_failed"
13673
+ );
13674
+ await pause(attempt, signal);
13675
+ }
13676
+ };
13677
+ const remove = async (attachmentId, signal) => {
13678
+ try {
13679
+ await withRetry(() => store.attachments.delete(attachmentId, signal), signal);
13680
+ } catch (error) {
13681
+ if (!(error instanceof ChatStoreError) || error.status !== 404) throw error;
13682
+ }
13683
+ await cache?.delete(attachmentId).catch(() => void 0);
13684
+ };
13685
+ const discardPending = async (attachmentId) => {
13686
+ const found = await store.attachments.get(attachmentId);
13687
+ if (found?.attachment.state === "pending") await remove(attachmentId);
13688
+ };
13689
+ return {
13690
+ async upload(bytes4, uploadOptions) {
13691
+ const signal = uploadOptions?.signal;
13692
+ if (!(bytes4 instanceof Uint8Array) || bytes4.length > maxVaultAttachmentBytes)
13693
+ throw new ChatStoreError(
13694
+ "Attachment is larger than vault accepts",
13695
+ 413,
13696
+ "attachment_too_large"
13697
+ );
13698
+ const size = bytes4.length + frameOverhead;
13699
+ for (let attempt = 0; ; attempt++) {
13700
+ const { attachment: attachment2, upload } = await withRetry(
13701
+ () => store.attachments.create(size, signal),
13702
+ signal
13703
+ );
13704
+ try {
13705
+ await uploadOptions?.onReserved?.(attachment2.id);
13706
+ const frame = await seal(bytes4, attachment2.id);
13707
+ if (await put(upload, frame, signal) === "stored") return attachment2.id;
13708
+ } catch (error) {
13709
+ await discardPending(attachment2.id).catch(() => void 0);
13710
+ throw error;
13711
+ }
13712
+ await remove(attachment2.id).catch(() => void 0);
13713
+ if (attempt >= retries)
13714
+ throw new ChatStoreError(
13715
+ "Attachment storage rejected the upload URL",
13716
+ 403,
13717
+ "attachment_upload_rejected"
13718
+ );
13719
+ }
13720
+ },
13721
+ commit(attachmentId, owner, signal) {
13722
+ return withRetry(() => store.attachments.commit(attachmentId, owner, signal), signal);
13723
+ },
13724
+ async read(attachmentId, signal) {
13725
+ if (!attachmentIdPattern2.test(attachmentId)) invalidAttachment();
13726
+ const cached = await cache?.get(attachmentId).catch(() => null);
13727
+ if (cached) return cached;
13728
+ for (let attempt = 0; ; attempt++) {
13729
+ const found = await withRetry(() => store.attachments.get(attachmentId, signal), signal);
13730
+ if (!found?.download) return null;
13731
+ const frame = await download(found.download, signal);
13732
+ if (frame === "missing") return null;
13733
+ if (frame === "expired") {
13734
+ if (attempt >= retries)
13735
+ throw new ChatStoreError(
13736
+ "Attachment storage rejected the download URL",
13737
+ 403,
13738
+ "attachment_download_rejected"
13739
+ );
13740
+ continue;
13741
+ }
13742
+ if (frame.length !== found.attachment.sizeBytes) invalidAttachment();
13743
+ const bytes4 = await open(frame, attachmentId);
13744
+ await cache?.set(attachmentId, bytes4).catch(() => void 0);
13745
+ return bytes4;
13746
+ }
13747
+ },
13748
+ delete: remove
13749
+ };
13750
+ }
13751
+ function validRef(value) {
13752
+ if (value === null || typeof value !== "object" || Array.isArray(value)) return false;
13753
+ const ref3 = value;
13754
+ 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;
13755
+ }
13756
+ function vaultAttachmentRefs(record2) {
13757
+ const refs = record2.data.vaultAttachments;
13758
+ return Array.isArray(refs) ? refs.filter(validRef) : [];
13759
+ }
13760
+ function journalKey(messageId, fileId) {
13761
+ return JSON.stringify([messageId, fileId]);
13762
+ }
13763
+ async function migrateMessageAttachments(options) {
13764
+ const { store, attachments, journal, messageId, signal } = options;
13765
+ const now = options.now ?? Date.now;
13766
+ const owner = { kind: "message", id: messageId };
13767
+ const ownerGone = () => new ChatStoreError("Message is not in vault", 409, "attachment_owner_not_found");
13768
+ let snapshot = await store.get("message", messageId, signal);
13769
+ if (!snapshot || snapshot.record.isDeleted) throw ownerGone();
13770
+ const present = new Map(vaultAttachmentRefs(snapshot.record).map((r) => [r.fileId, r]));
13771
+ const uploadable = (attachment2) => attachment2.state === "pending" && now() < Date.parse(attachment2.createdAt) + uploadWindowMs;
13772
+ const lookup = async (attachmentId) => attachmentId && attachmentIdPattern2.test(attachmentId) ? (await store.attachments.get(attachmentId, signal))?.attachment ?? null : null;
13773
+ const bind = async (found) => {
13774
+ if (!found) return null;
13775
+ if (found.state === "committed")
13776
+ return found.ownerKind === owner.kind && found.ownerId === owner.id ? found : null;
13777
+ try {
13778
+ return await attachments.commit(found.id, owner, signal);
13779
+ } catch (error) {
13780
+ if (!(error instanceof ChatStoreError) || error.code !== "attachment_not_uploaded")
13781
+ throw error;
13782
+ if (uploadable(found)) return "busy";
13783
+ await attachments.delete(found.id, signal);
13784
+ return null;
13785
+ }
13786
+ };
13787
+ const added = [];
13788
+ const settled = [];
13789
+ const missing2 = [];
13790
+ const oversized = [];
13791
+ const deferred = [];
13792
+ const stale = /* @__PURE__ */ new Set();
13793
+ let uploaded = 0;
13794
+ for (const file of options.files) {
13795
+ signal?.throwIfAborted();
13796
+ const key3 = journalKey(messageId, file.fileId);
13797
+ const recorded = present.get(file.fileId);
13798
+ if (recorded) {
13799
+ const bound = await bind(await lookup(recorded.attachmentId));
13800
+ if (bound === "busy") {
13801
+ deferred.push(file.fileId);
13802
+ continue;
13803
+ }
13804
+ if (bound) {
13805
+ const stray = await lookup(await journal.get(key3));
13806
+ if (stray && stray.id !== recorded.attachmentId) {
13807
+ if (uploadable(stray)) continue;
13808
+ await attachments.delete(stray.id, signal);
13809
+ }
13810
+ settled.push(key3);
13811
+ continue;
13812
+ }
13813
+ stale.add(recorded.attachmentId);
13814
+ }
13815
+ const meta = { fileId: file.fileId, name: file.name, type: file.type };
13816
+ const resumed = await bind(await lookup(await journal.get(key3)));
13817
+ if (resumed === "busy") {
13818
+ deferred.push(file.fileId);
13819
+ continue;
13820
+ }
13821
+ if (resumed) {
13822
+ added.push({ attachmentId: resumed.id, ...meta, size: resumed.sizeBytes - frameOverhead });
13823
+ settled.push(key3);
13824
+ continue;
13825
+ }
13826
+ const bytes4 = await file.read();
13827
+ if (!bytes4) {
13828
+ missing2.push(file.fileId);
13829
+ continue;
13830
+ }
13831
+ if (bytes4.length > maxVaultAttachmentBytes) {
13832
+ oversized.push(file.fileId);
13833
+ continue;
13834
+ }
13835
+ const attachmentId = await attachments.upload(bytes4, {
13836
+ signal,
13837
+ onReserved: (id2) => journal.set(key3, id2)
13838
+ });
13839
+ uploaded++;
13840
+ await attachments.commit(attachmentId, owner, signal);
13841
+ added.push({ attachmentId, ...meta, size: bytes4.length });
13842
+ settled.push(key3);
13843
+ }
13844
+ const superseded = [];
13845
+ for (let attempt = 0; added.length > 0; attempt++) {
13846
+ const refs = new Map(vaultAttachmentRefs(snapshot.record).map((r) => [r.fileId, r]));
13847
+ superseded.length = 0;
13848
+ for (const ref3 of added) {
13849
+ const prior = refs.get(ref3.fileId);
13850
+ if (prior && prior.attachmentId !== ref3.attachmentId && !stale.has(prior.attachmentId))
13851
+ superseded.push(ref3.attachmentId);
13852
+ else refs.set(ref3.fileId, ref3);
13853
+ }
13854
+ if (superseded.length === added.length) break;
13855
+ try {
13856
+ [snapshot] = await store.putMany(
13857
+ [
13858
+ {
13859
+ record: {
13860
+ ...snapshot.record,
13861
+ data: { ...snapshot.record.data, ...plain({ vaultAttachments: [...refs.values()] }) }
13862
+ },
13863
+ expectedVersion: snapshot.version
13864
+ }
13865
+ ],
13866
+ signal
13867
+ );
13868
+ break;
13869
+ } catch (error) {
13870
+ if (!(error instanceof ChatStoreError) || error.code !== "version_conflict" || attempt + 1 >= maxRefWrites)
13871
+ throw error;
13872
+ const latest = await store.get("message", messageId, signal);
13873
+ if (!latest || latest.record.isDeleted) throw ownerGone();
13874
+ snapshot = latest;
13875
+ }
13876
+ }
13877
+ for (const id2 of superseded) await attachments.delete(id2, signal);
13878
+ for (const key3 of settled) await journal.set(key3, null);
13879
+ return { refs: vaultAttachmentRefs(snapshot.record), uploaded, missing: missing2, oversized, deferred };
13880
+ }
13881
+
13524
13882
  // src/lib/chatStore/vaultBackend.ts
13525
13883
  var import_uuid3 = require("uuid");
13526
13884
 
@@ -13660,6 +14018,7 @@ var resumableFields = [
13660
14018
  "imageModel",
13661
14019
  "files",
13662
14020
  "fileIds",
14021
+ "vaultAttachments",
13663
14022
  "usage",
13664
14023
  "sources",
13665
14024
  "responseDuration",
@@ -25944,7 +26303,7 @@ function createRemoteMemoryStore(options) {
25944
26303
  };
25945
26304
  const mutate = (id2, change, edit, writeOptions) => serialized(id2, () => mutateLocked(id2, change, edit, writeOptions));
25946
26305
  const serializedAll = (ids, task) => [...new Set(ids)].sort().reduceRight((inner, id2) => () => serialized(id2, inner), task)();
25947
- const mutateMany = async (ids, change, edit, leaseToken, signal) => {
26306
+ const mutateMany = async (ids, change, edit, leaseToken, signal, includeEmbeddings = false) => {
25948
26307
  const saved = /* @__PURE__ */ new Map();
25949
26308
  const failed = /* @__PURE__ */ new Map();
25950
26309
  for (const slice of chunks2([...new Set(ids)], MAX_BATCH)) {
@@ -25953,7 +26312,7 @@ function createRemoteMemoryStore(options) {
25953
26312
  const writes = [];
25954
26313
  let read;
25955
26314
  try {
25956
- read = await readEveryState(slice, signal);
26315
+ read = await readEveryState(slice, signal, includeEmbeddings);
25957
26316
  } catch (error) {
25958
26317
  signal?.throwIfAborted();
25959
26318
  for (const id2 of slice) failed.set(id2, error);
@@ -26012,21 +26371,55 @@ function createRemoteMemoryStore(options) {
26012
26371
  }
26013
26372
  return { saved, failed };
26014
26373
  };
26015
- const embedInBackground = ({ memory: { memory_id: id2, content } }) => {
26016
- generateEmbedding(content, embeddingOptions).then(
26017
- (vector2) => serialized(id2, async () => {
26018
- const current = await live(id2);
26019
- if (!current || current.memory.content !== content || current.memory.embedding?.length)
26020
- return;
26021
- const saved = await persistence.put(
26022
- { ...current.memory, embedding: storedVector(vector2), embedding_model: model },
26023
- current
26024
- );
26025
- notify("embedding", [saved]);
26026
- })
26027
- ).catch((error) => {
26028
- getLogger().warn("[memory/remote-store] Failed to embed memory:", error);
26029
- });
26374
+ const pendingEmbeddings = /* @__PURE__ */ new Map();
26375
+ let embeddingActive = false;
26376
+ const drainEmbeddings = async () => {
26377
+ try {
26378
+ while (pendingEmbeddings.size) {
26379
+ const batch = /* @__PURE__ */ new Map();
26380
+ for (const [id2, content] of pendingEmbeddings) {
26381
+ pendingEmbeddings.delete(id2);
26382
+ batch.set(id2, content);
26383
+ if (batch.size === MAX_BATCH) break;
26384
+ }
26385
+ try {
26386
+ const vectors = await generateEmbeddings([...batch.values()], embeddingOptions);
26387
+ const embeddings2 = /* @__PURE__ */ new Map();
26388
+ [...batch.keys()].forEach((id2, i) => {
26389
+ try {
26390
+ embeddings2.set(id2, storedVector(vectors[i]));
26391
+ } catch (error) {
26392
+ getLogger().warn("[memory/remote-store] Failed to embed memory:", error);
26393
+ }
26394
+ });
26395
+ if (!embeddings2.size) continue;
26396
+ const { failed } = await mutateMany(
26397
+ [...embeddings2.keys()],
26398
+ () => "embedding",
26399
+ (memory) => memory.content !== batch.get(memory.memory_id) || memory.embedding?.length ? null : {
26400
+ ...memory,
26401
+ embedding: embeddings2.get(memory.memory_id),
26402
+ embedding_model: model
26403
+ },
26404
+ void 0,
26405
+ void 0,
26406
+ true
26407
+ );
26408
+ for (const error of failed.values())
26409
+ getLogger().warn("[memory/remote-store] Failed to embed memory:", error);
26410
+ } catch (error) {
26411
+ getLogger().warn("[memory/remote-store] Failed to embed memories:", error);
26412
+ }
26413
+ }
26414
+ } finally {
26415
+ embeddingActive = false;
26416
+ }
26417
+ };
26418
+ const embedInBackground = (records) => {
26419
+ for (const { memory } of records) pendingEmbeddings.set(memory.memory_id, memory.content);
26420
+ if (embeddingActive || !pendingEmbeddings.size) return;
26421
+ embeddingActive = true;
26422
+ void drainEmbeddings();
26030
26423
  };
26031
26424
  const newRow = (input) => {
26032
26425
  const now = Date.now();
@@ -26060,9 +26453,7 @@ function createRemoteMemoryStore(options) {
26060
26453
  };
26061
26454
  };
26062
26455
  const created = (records, inputs) => {
26063
- records.forEach((record2, i) => {
26064
- if (inputs[i].embedding === void 0) embedInBackground(record2);
26065
- });
26456
+ embedInBackground(records.filter((_, i) => inputs[i].embedding === void 0));
26066
26457
  notify("membership", records);
26067
26458
  return records.map((record2) => stored(record2.memory));
26068
26459
  };
@@ -26092,7 +26483,7 @@ function createRemoteMemoryStore(options) {
26092
26483
  };
26093
26484
  };
26094
26485
  const withKnownKinds = async (topics) => topics.map(await knownKinds(topics));
26095
- const readEveryState = async (ids, signal) => {
26486
+ const readEveryState = async (ids, signal, includeEmbeddings = false) => {
26096
26487
  const records = /* @__PURE__ */ new Map();
26097
26488
  const unreadable = /* @__PURE__ */ new Set();
26098
26489
  for (const memory_ids of chunks2(ids, MAX_QUERY_IDS)) {
@@ -26104,6 +26495,7 @@ function createRemoteMemoryStore(options) {
26104
26495
  include_archived: true,
26105
26496
  include_quarantined: true,
26106
26497
  include_superseded: true,
26498
+ ...includeEmbeddings && { include_embeddings: true },
26107
26499
  limit: 200,
26108
26500
  ...signal && { signal },
26109
26501
  ...cursor2 && { cursor: cursor2 }
@@ -26766,7 +27158,7 @@ function createRemoteMemoryStore(options) {
26766
27158
  }
26767
27159
  return memory;
26768
27160
  });
26769
- if (saved && patch.embedding === void 0) embedInBackground(saved);
27161
+ if (saved && patch.embedding === void 0) embedInBackground([saved]);
26770
27162
  return asStored(saved);
26771
27163
  },
26772
27164
  delete: async (id2) => !!await mutate(id2, "membership", (memory) => ({ ...memory, is_deleted: true })),
@@ -34081,6 +34473,7 @@ function useChatStorage(options) {
34081
34473
  createSelectPaymentWalletTool,
34082
34474
  createStockPricePreProcessor,
34083
34475
  createStreamingDeAnonymizer,
34476
+ createVaultAttachments,
34084
34477
  createVaultChatBackend,
34085
34478
  createVaultEmbeddingCache,
34086
34479
  createVaultFolderOp,
@@ -34145,9 +34538,11 @@ function useChatStorage(options) {
34145
34538
  isRerankerAvailable,
34146
34539
  localChatBackend,
34147
34540
  maskScopedEmbeddingCache,
34541
+ maxVaultAttachmentBytes,
34148
34542
  memoryCipher,
34149
34543
  migrateChatsToRemote,
34150
34544
  migrateMemoriesToRemote,
34545
+ migrateMessageAttachments,
34151
34546
  moveMemoriesToFolderOp,
34152
34547
  noopLogger,
34153
34548
  onKeyAvailable,
@@ -34201,6 +34596,7 @@ function useChatStorage(options) {
34201
34596
  useCredits,
34202
34597
  useEncryption,
34203
34598
  useModels,
34599
+ vaultAttachmentRefs,
34204
34600
  vaultChatBackend,
34205
34601
  verifyMemoriesForPublish,
34206
34602
  xhrTransport