@anuma/sdk 7.0.5 → 7.0.7

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.
@@ -13097,6 +13097,17 @@ async function decryptVaultMemoryFields(memory, address, signMessage, embeddedWa
13097
13097
  };
13098
13098
  }
13099
13099
 
13100
+ // src/lib/db/memoryVault/sourceChunkIds.ts
13101
+ var MAX_SOURCE_CHUNK_IDS_BYTES = 16 << 10;
13102
+ var utf8 = new TextEncoder();
13103
+ function serializeSourceChunkIds(ids) {
13104
+ const sizes = ids.map((id) => utf8.encode(JSON.stringify(id)).length + 1);
13105
+ let total = sizes.reduce((sum, size) => sum + size, 1);
13106
+ let start = 0;
13107
+ while (total > MAX_SOURCE_CHUNK_IDS_BYTES && start < ids.length) total -= sizes[start++];
13108
+ return JSON.stringify(ids.slice(start));
13109
+ }
13110
+
13100
13111
  // src/lib/db/memoryVault/types.ts
13101
13112
  var MEMORY_KINDS = [
13102
13113
  "display_name",
@@ -13244,15 +13255,15 @@ async function mapInBatches(items, fn) {
13244
13255
  return results;
13245
13256
  }
13246
13257
  function vaultMemoryToStoredRaw(memory) {
13247
- let sourceChunkIds = null;
13258
+ let sourceChunkIds2 = null;
13248
13259
  if (memory.sourceChunkIds) {
13249
13260
  try {
13250
13261
  const parsed = JSON.parse(memory.sourceChunkIds);
13251
13262
  if (Array.isArray(parsed)) {
13252
- sourceChunkIds = parsed.filter((s) => typeof s === "string");
13263
+ sourceChunkIds2 = parsed.filter((s) => typeof s === "string");
13253
13264
  }
13254
13265
  } catch {
13255
- sourceChunkIds = null;
13266
+ sourceChunkIds2 = null;
13256
13267
  }
13257
13268
  }
13258
13269
  return {
@@ -13266,7 +13277,7 @@ function vaultMemoryToStoredRaw(memory) {
13266
13277
  userId: memory.userId ?? null,
13267
13278
  embedding: memory.embedding ?? null,
13268
13279
  embeddingModel: memory.embeddingModel ?? null,
13269
- sourceChunkIds,
13280
+ sourceChunkIds: sourceChunkIds2,
13270
13281
  proofCount: memory.proofCount ?? null,
13271
13282
  source: memory.source ?? null,
13272
13283
  media: parseMedia(memory.media),
@@ -13315,7 +13326,7 @@ function populateNewVaultMemory(record2, ctx, opts, encryptedContent, encryptedK
13315
13326
  record2._setRaw("embedding_model", opts.embeddingModel ?? null);
13316
13327
  }
13317
13328
  if (opts.sourceChunkIds !== void 0) {
13318
- record2._setRaw("source_chunk_ids", JSON.stringify(opts.sourceChunkIds));
13329
+ record2._setRaw("source_chunk_ids", serializeSourceChunkIds(opts.sourceChunkIds));
13319
13330
  }
13320
13331
  record2._setRaw("proof_count", opts.proofCount ?? 1);
13321
13332
  record2._setRaw("source", opts.source ?? "manual");
@@ -13493,16 +13504,16 @@ async function getVaultMemoryOp(ctx, id) {
13493
13504
  }
13494
13505
  }
13495
13506
  function vaultMemoryRawToStoredRaw(raw) {
13496
- let sourceChunkIds = null;
13507
+ let sourceChunkIds2 = null;
13497
13508
  const rawChunks = raw.source_chunk_ids;
13498
13509
  if (typeof rawChunks === "string" && rawChunks) {
13499
13510
  try {
13500
13511
  const parsed = JSON.parse(rawChunks);
13501
13512
  if (Array.isArray(parsed)) {
13502
- sourceChunkIds = parsed.filter((s) => typeof s === "string");
13513
+ sourceChunkIds2 = parsed.filter((s) => typeof s === "string");
13503
13514
  }
13504
13515
  } catch {
13505
- sourceChunkIds = null;
13516
+ sourceChunkIds2 = null;
13506
13517
  }
13507
13518
  }
13508
13519
  return {
@@ -13516,7 +13527,7 @@ function vaultMemoryRawToStoredRaw(raw) {
13516
13527
  userId: raw.user_id ?? null,
13517
13528
  embedding: raw.embedding ?? null,
13518
13529
  embeddingModel: raw.embedding_model ?? null,
13519
- sourceChunkIds,
13530
+ sourceChunkIds: sourceChunkIds2,
13520
13531
  proofCount: raw.proof_count ?? null,
13521
13532
  source: raw.source ?? null,
13522
13533
  eventTimeStart: raw.event_time_start ?? null,
@@ -13813,7 +13824,7 @@ async function updateVaultMemoryOp(ctx, id, opts) {
13813
13824
  if (opts.sourceChunkIds !== void 0) {
13814
13825
  r._setRaw(
13815
13826
  "source_chunk_ids",
13816
- JSON.stringify(
13827
+ serializeSourceChunkIds(
13817
13828
  opts.observationSourceIds?.length ? [.../* @__PURE__ */ new Set([...observedSources, ...opts.sourceChunkIds])] : opts.sourceChunkIds
13818
13829
  )
13819
13830
  );
@@ -20713,13 +20724,20 @@ function memoryCipher(canonical) {
20713
20724
  };
20714
20725
  }
20715
20726
  async function reencryptMemoryField(value, canonical, fallbacks = []) {
20716
- const { encrypt } = memoryCipher(canonical);
20717
- if (!value.startsWith("enc:")) return encrypt(value);
20727
+ return memoryCipher(canonical).encrypt(
20728
+ await decryptMemoryField(value, [canonical, ...fallbacks])
20729
+ );
20730
+ }
20731
+ async function decryptMemoryField(value, rings) {
20732
+ if (!value.startsWith("enc:")) return value;
20718
20733
  if (!isEncrypted(value))
20719
20734
  throw new MemoryKeyError("Field has an encryption prefix but an invalid payload");
20720
- return encrypt(await decryptWith(value, [canonical, ...fallbacks]));
20735
+ return decryptWith(value, rings);
20721
20736
  }
20722
20737
 
20738
+ // src/lib/memory/store/remoteMigration.ts
20739
+ init_logger();
20740
+
20723
20741
  // src/lib/memory/store/remotePersistence.ts
20724
20742
  init_portalLlm();
20725
20743
  var RemoteMemoryError = class extends Error {
@@ -21412,7 +21430,7 @@ function createRemoteMemoryPipeline(options) {
21412
21430
  embedding: storedVector(JSON.parse(input.embedding)),
21413
21431
  embedding_model: input.embeddingModel
21414
21432
  },
21415
- source_chunk_ids: JSON.stringify(input.sourceChunkIds ?? []),
21433
+ source_chunk_ids: serializeSourceChunkIds(input.sourceChunkIds ?? []),
21416
21434
  proof_count: input.proofCount ?? 1,
21417
21435
  source: input.source ?? "manual",
21418
21436
  ...input.eventTime && {
@@ -21471,7 +21489,7 @@ function createRemoteMemoryPipeline(options) {
21471
21489
  const observed = sourceIds(memory.source_chunk_ids);
21472
21490
  const replay = !!patch.observationSourceIds?.length && patch.observationSourceIds.every((id2) => observed.includes(id2));
21473
21491
  if (patch.sourceChunkIds !== void 0)
21474
- memory.source_chunk_ids = JSON.stringify(
21492
+ memory.source_chunk_ids = serializeSourceChunkIds(
21475
21493
  patch.observationSourceIds?.length ? [.../* @__PURE__ */ new Set([...observed, ...patch.sourceChunkIds])] : patch.sourceChunkIds
21476
21494
  );
21477
21495
  if (!replay) {
@@ -21578,6 +21596,8 @@ function createRemoteMemoryPipeline(options) {
21578
21596
 
21579
21597
  // src/lib/memory/store/remoteMigration.ts
21580
21598
  var IMPORT_BATCH = 50;
21599
+ var EMBED_BATCH = 100;
21600
+ var LOCAL_VECTOR_DIMS = 4096;
21581
21601
  var VERIFY_BATCH = 1e3;
21582
21602
  var QUERY_IDS = 1e3;
21583
21603
  var QUERY_PAGE = 200;
@@ -21603,7 +21623,7 @@ var SHORT_FIELDS = [
21603
21623
  "visibility",
21604
21624
  "geohash"
21605
21625
  ];
21606
- var utf8 = new TextEncoder();
21626
+ var utf82 = new TextEncoder();
21607
21627
  var METADATA_FIELDS = [
21608
21628
  "scope",
21609
21629
  "kind",
@@ -21654,17 +21674,34 @@ function revision(raw) {
21654
21674
  last_observed_at: num(raw.last_observed_at) ?? null
21655
21675
  };
21656
21676
  }
21657
- function embedding(raw) {
21677
+ function embedding(raw, model) {
21658
21678
  const value = text13(raw.embedding);
21659
21679
  if (!value) return void 0;
21660
21680
  try {
21661
- return storedVector(JSON.parse(value));
21681
+ const vector = JSON.parse(value);
21682
+ const stored2 = text13(raw.embedding_model);
21683
+ if (stored2 === void 0 ? vector.length !== LOCAL_VECTOR_DIMS : stored2 !== model)
21684
+ return void 0;
21685
+ return storedVector(vector);
21662
21686
  } catch {
21663
21687
  return void 0;
21664
21688
  }
21665
21689
  }
21690
+ function stringArray(value) {
21691
+ try {
21692
+ const parsed = JSON.parse(value);
21693
+ return Array.isArray(parsed) && parsed.every((id) => typeof id === "string") ? parsed : void 0;
21694
+ } catch {
21695
+ return void 0;
21696
+ }
21697
+ }
21698
+ function sourceChunkIds(raw) {
21699
+ const value = text13(raw.source_chunk_ids);
21700
+ const ids = value && stringArray(value);
21701
+ return ids ? serializeSourceChunkIds(ids) : value;
21702
+ }
21666
21703
  function bytes(value) {
21667
- return value === void 0 ? 0 : utf8.encode(value).length;
21704
+ return value === void 0 ? 0 : utf82.encode(value).length;
21668
21705
  }
21669
21706
  function fitsNearby(row) {
21670
21707
  return bytes(row.memory_id) <= MAX_ID_BYTES && bytes(row.content) <= MAX_CONTENT_BYTES && bytes(row.kind_value) <= MAX_CONTENT_BYTES && TEXT_FIELDS.every((field10) => bytes(row[field10]) <= MAX_TEXT_BYTES) && SHORT_FIELDS.every((field10) => bytes(row[field10]) <= MAX_SHORT_BYTES);
@@ -21673,16 +21710,16 @@ function invalid(raw) {
21673
21710
  const id = raw.id;
21674
21711
  return typeof id !== "string" || id === "" || bytes(id) > MAX_ID_BYTES || !text13(raw.scope) || (num(raw.created_at) ?? 0) <= 0 || (num(raw.updated_at) ?? 0) <= 0;
21675
21712
  }
21676
- function metadata(raw) {
21677
- const vector = embedding(raw);
21713
+ function metadata(raw, model) {
21714
+ const vector = embedding(raw, model);
21678
21715
  return {
21679
21716
  scope: raw.scope,
21680
21717
  kind: text13(raw.kind),
21681
21718
  level: text13(raw.level),
21682
21719
  folder_id: text13(raw.folder_id),
21683
21720
  is_deleted: bool(raw.is_deleted) ?? false,
21684
- ...vector && { embedding: vector, embedding_model: text13(raw.embedding_model) },
21685
- source_chunk_ids: text13(raw.source_chunk_ids),
21721
+ ...vector && { embedding: vector, embedding_model: model },
21722
+ source_chunk_ids: sourceChunkIds(raw),
21686
21723
  proof_count: num(raw.proof_count),
21687
21724
  source: text13(raw.source),
21688
21725
  event_time_start: num(raw.event_time_start),
@@ -21711,30 +21748,63 @@ function defined(value) {
21711
21748
  Object.entries(value).filter(([, field10]) => field10 !== void 0)
21712
21749
  );
21713
21750
  }
21714
- async function remoteRow(raw, canonical, fallbacks, updatedAt) {
21715
- const content = await reencryptMemoryField(
21716
- typeof raw.content === "string" ? raw.content : "",
21717
- canonical,
21718
- fallbacks
21719
- );
21720
- const kindValue = text13(raw.kind_value);
21721
- const encryptedKindValue = kindValue ? await reencryptMemoryField(kindValue, canonical, fallbacks) : void 0;
21751
+ async function prepareRow(raw, canonical, rings, model, updatedAt) {
21752
+ const deleted = bool(raw.is_deleted) ?? false;
21753
+ const { encrypt } = memoryCipher(canonical);
21754
+ const localKindValue = text13(raw.kind_value);
21755
+ let plaintext;
21756
+ let kindValue;
21757
+ try {
21758
+ plaintext = await decryptMemoryField(typeof raw.content === "string" ? raw.content : "", rings);
21759
+ kindValue = localKindValue && await decryptMemoryField(localKindValue, rings);
21760
+ } catch (error) {
21761
+ if (!deleted || !(error instanceof MemoryKeyError)) throw error;
21762
+ plaintext = void 0;
21763
+ kindValue = void 0;
21764
+ }
21722
21765
  const row = {
21723
- ...defined({ ...metadata(raw), kind_value: encryptedKindValue }),
21766
+ ...defined({
21767
+ ...metadata(raw, model),
21768
+ kind_value: kindValue === void 0 ? void 0 : await encrypt(kindValue)
21769
+ }),
21724
21770
  memory_id: raw.id,
21725
- content,
21771
+ content: await encrypt(plaintext ?? ""),
21726
21772
  scope: raw.scope,
21727
21773
  created_at: raw.created_at,
21728
21774
  updated_at: updatedAt,
21729
- is_deleted: bool(raw.is_deleted) ?? false
21775
+ is_deleted: deleted
21730
21776
  };
21731
- return fitsNearby(row) ? row : null;
21777
+ return { row, plaintext };
21732
21778
  }
21733
- function sameMetadata(local, remote) {
21734
- const mine = metadata(local);
21779
+ async function embedMissing(prepared, options, model, signal) {
21780
+ const needed = prepared.filter((p) => !p.row.embedding && p.plaintext);
21781
+ for (const batch of chunks(needed, EMBED_BATCH)) {
21782
+ if (signal?.aborted) throw aborted(signal);
21783
+ try {
21784
+ const vectors = await generateEmbeddings(
21785
+ batch.map((p) => p.plaintext),
21786
+ { ...options, taskType: "memory_retain_embed" }
21787
+ );
21788
+ if (vectors.length !== batch.length) throw new Error("Incomplete migration embeddings");
21789
+ const stored2 = vectors.map(storedVector);
21790
+ batch.forEach((p, i) => {
21791
+ p.row.embedding = stored2[i];
21792
+ p.row.embedding_model = model;
21793
+ });
21794
+ } catch (error) {
21795
+ getLogger().warn(
21796
+ `[memory/migration] Uploading ${batch.length} row(s) without a vector: embedding failed`,
21797
+ error
21798
+ );
21799
+ }
21800
+ }
21801
+ }
21802
+ function sameMetadata(local, remote, model) {
21803
+ const mine = metadata(local, model);
21735
21804
  return METADATA_FIELDS.every((field10) => {
21736
21805
  const a = mine[field10] ?? null;
21737
21806
  const b = remote[field10] ?? null;
21807
+ if (field10 === "embedding_model" && a === null) return true;
21738
21808
  if (field10 === "visibility") return (a ?? "private") === (b ?? "private");
21739
21809
  if (field10 === "is_deleted" || field10 === "topics_user_managed" || field10 === "twin_opt_in")
21740
21810
  return (a ?? false) === (b ?? false);
@@ -21830,7 +21900,8 @@ async function backfillTopics(ctx) {
21830
21900
  }
21831
21901
  async function migrateMemoriesToRemote(options) {
21832
21902
  const { canonical, signal } = options;
21833
- const fallbacks = options.fallbacks ?? [];
21903
+ const rings = [canonical, ...options.fallbacks ?? []];
21904
+ const model = options.embeddingOptions?.model ?? DEFAULT_API_EMBEDDING_MODEL;
21834
21905
  const request = createNearbyRequest(options);
21835
21906
  const account = await request("/account", {}, signal);
21836
21907
  if (typeof account.key_id === "string" && account.key_id !== canonical.keyId)
@@ -21841,8 +21912,13 @@ async function migrateMemoriesToRemote(options) {
21841
21912
  );
21842
21913
  const active = account.state === "active";
21843
21914
  let claimed = account.key_id === canonical.keyId;
21915
+ if (!active) await createDecaySweeper({ vaultCtx: options.vaultCtx }).runSweep();
21844
21916
  await backfillTopics(options.vaultCtx);
21845
21917
  const skipped = /* @__PURE__ */ new Map();
21918
+ const reembedded = /* @__PURE__ */ new Set();
21919
+ const unembedded = /* @__PURE__ */ new Set();
21920
+ const placeholders = /* @__PURE__ */ new Set();
21921
+ const truncated = /* @__PURE__ */ new Set();
21846
21922
  let imported = 0;
21847
21923
  for (let pass = 0; ; pass++) {
21848
21924
  const rows = await getAllVaultMemoryRowsOp(options.vaultCtx);
@@ -21858,9 +21934,10 @@ async function migrateMemoriesToRemote(options) {
21858
21934
  candidates.map((raw) => raw.id),
21859
21935
  signal
21860
21936
  );
21937
+ const needsVector = (raw, server) => !!options.embeddingOptions && !embedding(raw, model) && server.embedding_model !== model;
21861
21938
  for (const raw of candidates) {
21862
21939
  const server = remote.get(raw.id);
21863
- if (server && server.updated_at === raw.updated_at && !sameMetadata(raw, server))
21940
+ if (server && server.updated_at === raw.updated_at && (!sameMetadata(raw, server, model) || needsVector(raw, server)))
21864
21941
  pending.set(raw.id, raw.updated_at + 1);
21865
21942
  }
21866
21943
  }
@@ -21869,7 +21946,11 @@ async function migrateMemoriesToRemote(options) {
21869
21946
  state,
21870
21947
  total: rows.length,
21871
21948
  imported,
21872
- skipped: [...skipped].map(([memoryId, reason]) => ({ memoryId, reason }))
21949
+ skipped: [...skipped].map(([memoryId, reason]) => ({ memoryId, reason })),
21950
+ reembedded: reembedded.size,
21951
+ unembedded: unembedded.size,
21952
+ placeholderTombstones: placeholders.size,
21953
+ truncatedSourceChunkIds: truncated.size
21873
21954
  });
21874
21955
  if (skipped.size > 0 && !options.allowSkipped) return result("migrating");
21875
21956
  if (!claimed) await importBatch(request, canonical.keyId, [], signal);
@@ -21887,19 +21968,35 @@ async function migrateMemoriesToRemote(options) {
21887
21968
  409,
21888
21969
  "migration_incomplete"
21889
21970
  );
21890
- const upload = [];
21971
+ const prepared = [];
21891
21972
  for (const raw of candidates) {
21892
21973
  const updatedAt = pending.get(raw.id);
21893
21974
  if (updatedAt === void 0) continue;
21894
21975
  try {
21895
- const row = await remoteRow(raw, canonical, fallbacks, updatedAt);
21896
- if (row) upload.push(row);
21897
- else skipped.set(raw.id, "invalid");
21976
+ prepared.push(await prepareRow(raw, canonical, rings, model, updatedAt));
21898
21977
  } catch (error) {
21899
21978
  if (!(error instanceof MemoryKeyError)) throw error;
21900
21979
  skipped.set(raw.id, "unreadable");
21901
21980
  }
21902
21981
  }
21982
+ const usable = new Set(prepared.filter((p) => p.row.embedding).map((p) => p.row.memory_id));
21983
+ if (options.embeddingOptions)
21984
+ await embedMissing(prepared, options.embeddingOptions, model, signal);
21985
+ const local = new Map(candidates.map((raw) => [raw.id, raw]));
21986
+ const upload = [];
21987
+ for (const { row, plaintext } of prepared) {
21988
+ const id = row.memory_id;
21989
+ if (!fitsNearby(row)) {
21990
+ skipped.set(id, "invalid");
21991
+ continue;
21992
+ }
21993
+ upload.push(row);
21994
+ const track = (set, on) => on ? set.add(id) : set.delete(id);
21995
+ track(reembedded, !!row.embedding && !usable.has(id));
21996
+ track(unembedded, !row.embedding);
21997
+ track(placeholders, plaintext === void 0);
21998
+ track(truncated, row.source_chunk_ids !== text13(local.get(id).source_chunk_ids));
21999
+ }
21903
22000
  let sent = 0;
21904
22001
  options.onProgress?.({ imported: sent, toImport: upload.length });
21905
22002
  for (const batch of chunks(upload, IMPORT_BATCH)) {
@@ -27782,11 +27879,15 @@ function useChatStorage(options) {
27782
27879
  const retirementStopRequestedRef = (0, import_react5.useRef)(false);
27783
27880
  const createConversation = (0, import_react5.useCallback)(
27784
27881
  async (opts) => {
27882
+ const conversationOpts = {
27883
+ ...opts,
27884
+ conversationId: opts?.conversationId || generateConversationId()
27885
+ };
27785
27886
  const { result, queued } = await writeOrQueue(
27786
27887
  "createConversation",
27787
- { conversationId: opts?.conversationId, title: opts?.title, projectId: opts?.projectId },
27788
- () => createConversationOp(storageCtx, opts, defaultConversationTitle),
27789
- () => makeSyntheticStoredConversation(opts, defaultConversationTitle)
27888
+ conversationOpts,
27889
+ () => createConversationOp(storageCtx, conversationOpts, defaultConversationTitle),
27890
+ () => makeSyntheticStoredConversation(conversationOpts, defaultConversationTitle)
27790
27891
  );
27791
27892
  if (queued) {
27792
27893
  syntheticConvIdsRef.current.add(result.conversationId);
@@ -28492,6 +28593,7 @@ function useChatStorage(options) {
28492
28593
  url: file.url && !file.url.startsWith("data:") ? file.url : void 0
28493
28594
  }));
28494
28595
  const userMsgOpts = {
28596
+ uniqueId: `msg_${(0, import_uuid7.v7)()}`,
28495
28597
  conversationId: convId,
28496
28598
  role: "user",
28497
28599
  content: contentForStorage,
@@ -28846,7 +28948,7 @@ function useChatStorage(options) {
28846
28948
  thinking: thinkingContent,
28847
28949
  parentMessageId: storedUserMessage.uniqueId,
28848
28950
  toolCallEvents: currentTurnToolCallEvents && currentTurnToolCallEvents.length > 0 ? currentTurnToolCallEvents : void 0,
28849
- uniqueId: effectiveAssistantUniqueId
28951
+ uniqueId: effectiveAssistantUniqueId || `msg_${(0, import_uuid7.v7)()}`
28850
28952
  };
28851
28953
  let storedAssistantMessage;
28852
28954
  let assistantMsgQueueId;
@@ -28874,6 +28976,7 @@ function useChatStorage(options) {
28874
28976
  let storedToolResultsMessage;
28875
28977
  if (autoToolResults && autoToolResults.length > 0) {
28876
28978
  const toolResultsOpts = {
28979
+ uniqueId: `msg_${(0, import_uuid7.v7)()}`,
28877
28980
  conversationId: convId,
28878
28981
  role: "user",
28879
28982
  content: buildToolResultContent(autoToolResults),
@@ -9728,6 +9728,8 @@ interface MemoryMigrationOptions extends Pick<RemoteMemoryPersistenceOptions, "b
9728
9728
  fallbacks?: readonly MemoryKeyRing[];
9729
9729
  /** Activate even when some rows could not be migrated. Default false. */
9730
9730
  allowSkipped?: boolean;
9731
+ /** Re-embeds rows whose local vector nearby could not rank; without it those rows upload unembedded. */
9732
+ embeddingOptions?: EmbeddingOptions;
9731
9733
  signal?: AbortSignal;
9732
9734
  onProgress?: (progress: MemoryMigrationProgress) => void;
9733
9735
  }
@@ -9754,6 +9756,14 @@ interface MemoryMigrationResult {
9754
9756
  total: number;
9755
9757
  imported: number;
9756
9758
  skipped: MemoryMigrationSkip[];
9759
+ /** Rows uploaded with a vector embedded during migration. */
9760
+ reembedded: number;
9761
+ /** Rows uploaded without a vector nearby can rank. */
9762
+ unembedded: number;
9763
+ /** Deleted rows no supplied key decrypts, uploaded with placeholder content. */
9764
+ placeholderTombstones: number;
9765
+ /** Rows whose oldest source ids were dropped to fit nearby's limit. */
9766
+ truncatedSourceChunkIds: number;
9757
9767
  }
9758
9768
  /**
9759
9769
  * Upload this device's local memories to nearby and, once nearby holds every one, make it authoritative.
@@ -9728,6 +9728,8 @@ interface MemoryMigrationOptions extends Pick<RemoteMemoryPersistenceOptions, "b
9728
9728
  fallbacks?: readonly MemoryKeyRing[];
9729
9729
  /** Activate even when some rows could not be migrated. Default false. */
9730
9730
  allowSkipped?: boolean;
9731
+ /** Re-embeds rows whose local vector nearby could not rank; without it those rows upload unembedded. */
9732
+ embeddingOptions?: EmbeddingOptions;
9731
9733
  signal?: AbortSignal;
9732
9734
  onProgress?: (progress: MemoryMigrationProgress) => void;
9733
9735
  }
@@ -9754,6 +9756,14 @@ interface MemoryMigrationResult {
9754
9756
  total: number;
9755
9757
  imported: number;
9756
9758
  skipped: MemoryMigrationSkip[];
9759
+ /** Rows uploaded with a vector embedded during migration. */
9760
+ reembedded: number;
9761
+ /** Rows uploaded without a vector nearby can rank. */
9762
+ unembedded: number;
9763
+ /** Deleted rows no supplied key decrypts, uploaded with placeholder content. */
9764
+ placeholderTombstones: number;
9765
+ /** Rows whose oldest source ids were dropped to fit nearby's limit. */
9766
+ truncatedSourceChunkIds: number;
9757
9767
  }
9758
9768
  /**
9759
9769
  * Upload this device's local memories to nearby and, once nearby holds every one, make it authoritative.