@anuma/sdk 3.8.5 → 3.9.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.
@@ -4622,6 +4622,85 @@ async function getAllVaultMemoriesOp(ctx, options) {
4622
4622
  (raw) => vaultMemoryRawToStored(raw, ctx.walletAddress, ctx.signMessage, ctx.embeddedWalletSigner)
4623
4623
  );
4624
4624
  }
4625
+ function baseVaultSql(ctx) {
4626
+ const clauses = [
4627
+ '"is_deleted" = 0',
4628
+ '"archived_at" is null',
4629
+ `"trust_tier" is not 'quarantined'`,
4630
+ '"superseded_by" is null'
4631
+ ];
4632
+ const args = [];
4633
+ if (ctx.userId !== void 0) {
4634
+ clauses.push('"user_id" = ?');
4635
+ args.push(ctx.userId);
4636
+ }
4637
+ return { sql: clauses.join(" and "), args };
4638
+ }
4639
+ async function getVaultCandidateKeysOp(ctx, options) {
4640
+ const mapRaw = (raw) => ({
4641
+ uniqueId: raw.id,
4642
+ folderId: raw.folder_id ?? null,
4643
+ scope: raw.scope ?? "",
4644
+ embeddingModel: raw.embedding_model ?? null,
4645
+ updatedAt: new Date(raw.updated_at)
4646
+ });
4647
+ try {
4648
+ const base = baseVaultSql(ctx);
4649
+ const clauses = [base.sql];
4650
+ const args = [...base.args];
4651
+ if (options?.scopes?.length) {
4652
+ clauses.push(`"scope" in (${options.scopes.map(() => "?").join(",")})`);
4653
+ args.push(...options.scopes);
4654
+ }
4655
+ if (options?.folderId !== void 0) {
4656
+ clauses.push(options.folderId === null ? '"folder_id" is null' : '"folder_id" = ?');
4657
+ if (options.folderId !== null) args.push(options.folderId);
4658
+ }
4659
+ const sql = `select "id", "scope", "folder_id", "embedding_model", "updated_at" from "memory_vault" where ${clauses.join(" and ")}`;
4660
+ const rows = await ctx.vaultMemoryCollection.query(import_watermelondb9.Q.unsafeSqlQuery(sql, args)).unsafeFetchRaw();
4661
+ return rows.map(mapRaw);
4662
+ } catch (err) {
4663
+ getLogger().debug(
4664
+ "memoryVault: getVaultCandidateKeysOp projected SQL unavailable, using full-load fallback: " + (err instanceof Error ? err.message : String(err))
4665
+ );
4666
+ const conditions = [
4667
+ ...baseVaultConditions(ctx),
4668
+ ...options?.scopes?.length ? [import_watermelondb9.Q.where("scope", import_watermelondb9.Q.oneOf(options.scopes))] : [],
4669
+ ...options?.folderId !== void 0 ? [import_watermelondb9.Q.where("folder_id", options.folderId)] : []
4670
+ ];
4671
+ const rows = await ctx.vaultMemoryCollection.query(...conditions).unsafeFetchRaw();
4672
+ return rows.map(mapRaw);
4673
+ }
4674
+ }
4675
+ async function getVaultEmbeddingsByIdsOp(ctx, ids) {
4676
+ if (ids.length === 0) return [];
4677
+ const mapRaw = (raw) => ({
4678
+ uniqueId: raw.id,
4679
+ embedding: raw.embedding ?? null,
4680
+ embeddingModel: raw.embedding_model ?? null
4681
+ });
4682
+ try {
4683
+ const base = baseVaultSql(ctx);
4684
+ const sql = `select "id", "embedding", "embedding_model" from "memory_vault" where ${base.sql} and "id" in (${ids.map(() => "?").join(",")})`;
4685
+ const rows = await ctx.vaultMemoryCollection.query(import_watermelondb9.Q.unsafeSqlQuery(sql, [...base.args, ...ids])).unsafeFetchRaw();
4686
+ return rows.map(mapRaw);
4687
+ } catch (err) {
4688
+ getLogger().debug(
4689
+ "memoryVault: getVaultEmbeddingsByIdsOp projected SQL unavailable, using full-load fallback: " + (err instanceof Error ? err.message : String(err))
4690
+ );
4691
+ const rows = await ctx.vaultMemoryCollection.query(...baseVaultConditions(ctx), import_watermelondb9.Q.where("id", import_watermelondb9.Q.oneOf(ids))).unsafeFetchRaw();
4692
+ return rows.map(mapRaw);
4693
+ }
4694
+ }
4695
+ async function getVaultMemoriesByIdsOp(ctx, ids) {
4696
+ if (ids.length === 0) return [];
4697
+ const conditions = [...baseVaultConditions(ctx), import_watermelondb9.Q.where("id", import_watermelondb9.Q.oneOf(ids))];
4698
+ const results = await ctx.vaultMemoryCollection.query(...conditions).unsafeFetchRaw();
4699
+ return mapInBatches(
4700
+ results,
4701
+ (raw) => vaultMemoryRawToStored(raw, ctx.walletAddress, ctx.signMessage, ctx.embeddedWalletSigner)
4702
+ );
4703
+ }
4625
4704
  async function getAllVaultMemoryContentsOp(ctx, options) {
4626
4705
  const results = await ctx.vaultMemoryCollection.query(...baseVaultConditions(ctx, options)).unsafeFetchRaw();
4627
4706
  return mapInBatches(results, async (raw) => {
@@ -5014,6 +5093,7 @@ var init_operations3 = __esm({
5014
5093
  "src/lib/db/memoryVault/operations.ts"() {
5015
5094
  "use strict";
5016
5095
  import_watermelondb9 = require("@nozbe/watermelondb");
5096
+ init_logger();
5017
5097
  init_operations2();
5018
5098
  init_encryption2();
5019
5099
  KNOWN_TRUST_TIERS = /* @__PURE__ */ new Set(["quarantined", "trusted"]);
@@ -6406,6 +6486,7 @@ async function recall(query, ctx, options = {}) {
6406
6486
  bm25AdmissionDivisor: options.bm25AdmissionDivisor
6407
6487
  },
6408
6488
  ...options.rrfK !== void 0 && { rrfK: options.rrfK },
6489
+ ...options.decryptLast !== void 0 && { decryptLast: options.decryptLast },
6409
6490
  ...decomposeAvailable && {
6410
6491
  decompose: "llm",
6411
6492
  decomposeOptions: options.decomposeOptions
@@ -7188,80 +7269,97 @@ async function eagerEmbedContent(content, embeddingOptions, cache, vaultCtx, mem
7188
7269
  );
7189
7270
  }
7190
7271
  }
7191
- async function searchVaultMemoriesWithSize(query, vaultCtx, embeddingOptions, cache, searchOptions) {
7192
- const limit = searchOptions?.limit ?? 5;
7193
- const minSimilarity = searchOptions?.minSimilarity ?? 0.1;
7194
- const scopes = searchOptions?.scopes;
7195
- if (!query || typeof query !== "string") {
7196
- return { results: [], vaultSize: 0, reranked: false, hadV2Head: false };
7197
- }
7198
- const folderId = searchOptions?.folderId;
7199
- const queryOpts = {};
7200
- if (scopes?.length) queryOpts.scopes = scopes;
7201
- if (folderId !== void 0) queryOpts.folderId = folderId;
7202
- if (searchOptions?.factTypes?.length) queryOpts.factTypes = searchOptions.factTypes;
7203
- if (searchOptions?.includeArchived) queryOpts.includeArchived = true;
7204
- const loaded = await getAllVaultMemoriesOp(
7272
+ function admitVaultProjections(queryEmbedding, vectored, k) {
7273
+ return vectored.map((it) => ({ it, score: cosineSimilarity(queryEmbedding, it.embedding) })).sort((a, b) => b.score - a.score || b.it.updatedAt.getTime() - a.it.updatedAt.getTime()).slice(0, k).map((s) => s.it.uniqueId);
7274
+ }
7275
+ async function buildProjectedCorpus(query, vaultCtx, embeddingOptions, cache, queryOpts, opts) {
7276
+ const keys = await getVaultCandidateKeysOp(
7205
7277
  vaultCtx,
7206
7278
  Object.keys(queryOpts).length > 0 ? queryOpts : void 0
7207
7279
  );
7208
- const memories = loaded.filter((m) => !isEncrypted(m.content));
7209
- if (memories.length < loaded.length) {
7210
- getLogger().warn(
7211
- `memoryVault: ${loaded.length - memories.length}/${loaded.length} memories still encrypted (key unavailable?) \u2014 excluded from search`
7212
- );
7213
- }
7214
- if (memories.length === 0) {
7215
- return { results: [], vaultSize: loaded.length, reranked: false, hadV2Head: false };
7280
+ const vaultSize = keys.length;
7281
+ if (keys.length === 0) {
7282
+ return { memories: [], embeddedItems: [], queryEmbedding: [], vaultSize: 0 };
7216
7283
  }
7217
7284
  const queryEmbedding = await generateEmbedding(query, embeddingOptions);
7218
7285
  const currentModel = embeddingOptions.model ?? DEFAULT_API_EMBEDDING_MODEL;
7219
- const uncachedTexts = [];
7220
- const uncachedIndices = [];
7221
- let staleReembedCount = 0;
7222
- for (let i = 0; i < memories.length; i++) {
7223
- const content = memories[i].content;
7224
- const memoryId = memories[i].uniqueId;
7225
- const cached = cache.get(memoryId);
7226
- if (cached && cached.length === queryEmbedding.length) continue;
7227
- if (cached) cache.delete(memoryId);
7228
- const storedModel = memories[i].embeddingModel;
7229
- const modelCompatible = (storedModel ?? currentModel) === currentModel;
7230
- if (memories[i].embedding && modelCompatible) {
7286
+ const vectored = [];
7287
+ const missIds = [];
7288
+ const noVectorIds = [];
7289
+ const keyById = new Map(keys.map((k2) => [k2.uniqueId, k2]));
7290
+ for (const k2 of keys) {
7291
+ const cached = cache.get(k2.uniqueId);
7292
+ if (cached && cached.length === queryEmbedding.length) {
7293
+ vectored.push({ uniqueId: k2.uniqueId, embedding: cached, updatedAt: k2.updatedAt });
7294
+ continue;
7295
+ }
7296
+ const modelCompatible = (k2.embeddingModel ?? currentModel) === currentModel;
7297
+ if (modelCompatible) missIds.push(k2.uniqueId);
7298
+ else noVectorIds.push(k2.uniqueId);
7299
+ }
7300
+ if (missIds.length > 0) {
7301
+ const rows = await getVaultEmbeddingsByIdsOp(vaultCtx, missIds);
7302
+ const gotVector = /* @__PURE__ */ new Set();
7303
+ for (const r of rows) {
7304
+ if (!r.embedding) continue;
7231
7305
  try {
7232
- const parsed = JSON.parse(memories[i].embedding);
7306
+ const parsed = JSON.parse(r.embedding);
7233
7307
  if (Array.isArray(parsed) && parsed.length === queryEmbedding.length) {
7234
- cache.set(memoryId, Float32Array.from(parsed));
7235
- continue;
7308
+ const vec = Float32Array.from(parsed);
7309
+ cache.set(r.uniqueId, vec);
7310
+ const k2 = keyById.get(r.uniqueId);
7311
+ vectored.push({ uniqueId: r.uniqueId, embedding: vec, updatedAt: k2.updatedAt });
7312
+ gotVector.add(r.uniqueId);
7236
7313
  }
7237
7314
  } catch {
7238
7315
  }
7239
7316
  }
7240
- if (memories[i].embedding && !modelCompatible) staleReembedCount++;
7241
- uncachedTexts.push(content);
7242
- uncachedIndices.push(i);
7317
+ for (const id of missIds) if (!gotVector.has(id)) noVectorIds.push(id);
7243
7318
  }
7244
- if (staleReembedCount > 0) {
7245
- getLogger().warn(
7246
- `memoryVault: re-embedding ${staleReembedCount} memories whose stored embedding model differs from the current model (${currentModel}) \u2014 embedding-model change detected`
7319
+ if (noVectorIds.length > 0) {
7320
+ const laneIds = noVectorIds.slice(0, opts.unembeddedCap);
7321
+ if (noVectorIds.length > laneIds.length) {
7322
+ getLogger().warn(
7323
+ `memoryVault: projected search un-embedded lane capped at ${laneIds.length}/${noVectorIds.length}`
7324
+ );
7325
+ }
7326
+ const laneRows = (await getVaultMemoriesByIdsOp(vaultCtx, laneIds)).filter(
7327
+ (m) => !isEncrypted(m.content)
7247
7328
  );
7248
- }
7249
- if (uncachedTexts.length > 0) {
7250
- const newEmbeddings = await generateEmbeddings(uncachedTexts, embeddingOptions);
7251
- for (let j = 0; j < uncachedTexts.length; j++) {
7252
- cache.set(memories[uncachedIndices[j]].uniqueId, Float32Array.from(newEmbeddings[j]));
7253
- updateVaultMemoryEmbeddingOp(
7254
- vaultCtx,
7255
- memories[uncachedIndices[j]].uniqueId,
7256
- JSON.stringify(newEmbeddings[j]),
7257
- currentModel
7258
- ).catch(
7259
- // Silently swallow – SDK must not use console.*; embedding will be retried on next search
7260
- () => {
7261
- }
7329
+ if (laneRows.length > 0) {
7330
+ const laneVecs = await generateEmbeddings(
7331
+ laneRows.map((m) => m.content),
7332
+ embeddingOptions
7262
7333
  );
7334
+ laneRows.forEach((m, i) => {
7335
+ const vec = Float32Array.from(laneVecs[i]);
7336
+ cache.set(m.uniqueId, vec);
7337
+ vectored.push({ uniqueId: m.uniqueId, embedding: vec, updatedAt: m.updatedAt });
7338
+ updateVaultMemoryEmbeddingOp(
7339
+ vaultCtx,
7340
+ m.uniqueId,
7341
+ JSON.stringify(laneVecs[i]),
7342
+ currentModel
7343
+ ).catch(() => {
7344
+ });
7345
+ });
7346
+ }
7347
+ }
7348
+ const k = Math.max(opts.limit * opts.admitFactor, opts.admitFloor);
7349
+ const admittedIds = admitVaultProjections(queryEmbedding, vectored, k);
7350
+ const admissionSet = new Set(admittedIds);
7351
+ if (opts.forceIncludeIds) {
7352
+ for (const id of opts.forceIncludeIds) {
7353
+ if (keyById.has(id)) admissionSet.add(id);
7263
7354
  }
7264
7355
  }
7356
+ const admittedRows = await getVaultMemoriesByIdsOp(vaultCtx, [...admissionSet]);
7357
+ const memories = admittedRows.filter((m) => !isEncrypted(m.content));
7358
+ if (memories.length < admittedRows.length) {
7359
+ getLogger().warn(
7360
+ `memoryVault: ${admittedRows.length - memories.length}/${admittedRows.length} admitted memories still encrypted (key unavailable?) \u2014 excluded from projected search`
7361
+ );
7362
+ }
7265
7363
  const embeddedItems = memories.map((m) => ({
7266
7364
  id: m.uniqueId,
7267
7365
  content: m.content,
@@ -7276,6 +7374,125 @@ async function searchVaultMemoriesWithSize(query, vaultCtx, embeddingOptions, ca
7276
7374
  eventTimeKind: normalizeEventTimeKind(m.eventTimeKind),
7277
7375
  factType: m.factType
7278
7376
  }));
7377
+ return { memories, embeddedItems, queryEmbedding, vaultSize };
7378
+ }
7379
+ async function searchVaultMemoriesWithSize(query, vaultCtx, embeddingOptions, cache, searchOptions) {
7380
+ const limit = searchOptions?.limit ?? 5;
7381
+ const minSimilarity = searchOptions?.minSimilarity ?? 0.1;
7382
+ const scopes = searchOptions?.scopes;
7383
+ if (!query || typeof query !== "string") {
7384
+ return { results: [], vaultSize: 0, reranked: false, hadV2Head: false };
7385
+ }
7386
+ const folderId = searchOptions?.folderId;
7387
+ const queryOpts = {};
7388
+ if (scopes?.length) queryOpts.scopes = scopes;
7389
+ if (folderId !== void 0) queryOpts.folderId = folderId;
7390
+ if (searchOptions?.factTypes?.length) queryOpts.factTypes = searchOptions.factTypes;
7391
+ if (searchOptions?.includeArchived) queryOpts.includeArchived = true;
7392
+ const ADMIT_FACTOR = searchOptions?.admitFactor ?? 3;
7393
+ const ADMIT_FLOOR = searchOptions?.admitFloor ?? 30;
7394
+ const UNEMBEDDED_CAP = 200;
7395
+ let memories;
7396
+ let embeddedItems;
7397
+ let queryEmbedding;
7398
+ let vaultSize;
7399
+ if (searchOptions?.decryptLast) {
7400
+ const forceIncludeIds = [
7401
+ ...searchOptions.entityRanking ?? [],
7402
+ ...searchOptions.temporalRanking ?? []
7403
+ ];
7404
+ const corpus = await buildProjectedCorpus(query, vaultCtx, embeddingOptions, cache, queryOpts, {
7405
+ limit,
7406
+ admitFactor: ADMIT_FACTOR,
7407
+ admitFloor: ADMIT_FLOOR,
7408
+ unembeddedCap: UNEMBEDDED_CAP,
7409
+ ...forceIncludeIds.length > 0 && { forceIncludeIds }
7410
+ });
7411
+ if (corpus.vaultSize === 0) {
7412
+ return { results: [], vaultSize: 0, reranked: false, hadV2Head: false };
7413
+ }
7414
+ ({ memories, embeddedItems, queryEmbedding, vaultSize } = corpus);
7415
+ if (memories.length === 0) {
7416
+ return { results: [], vaultSize, reranked: false, hadV2Head: false };
7417
+ }
7418
+ } else {
7419
+ const loaded = await getAllVaultMemoriesOp(
7420
+ vaultCtx,
7421
+ Object.keys(queryOpts).length > 0 ? queryOpts : void 0
7422
+ );
7423
+ vaultSize = loaded.length;
7424
+ memories = loaded.filter((m) => !isEncrypted(m.content));
7425
+ if (memories.length < loaded.length) {
7426
+ getLogger().warn(
7427
+ `memoryVault: ${loaded.length - memories.length}/${loaded.length} memories still encrypted (key unavailable?) \u2014 excluded from search`
7428
+ );
7429
+ }
7430
+ if (memories.length === 0) {
7431
+ return { results: [], vaultSize: loaded.length, reranked: false, hadV2Head: false };
7432
+ }
7433
+ queryEmbedding = await generateEmbedding(query, embeddingOptions);
7434
+ const currentModel = embeddingOptions.model ?? DEFAULT_API_EMBEDDING_MODEL;
7435
+ const uncachedTexts = [];
7436
+ const uncachedIndices = [];
7437
+ let staleReembedCount = 0;
7438
+ for (let i = 0; i < memories.length; i++) {
7439
+ const content = memories[i].content;
7440
+ const memoryId = memories[i].uniqueId;
7441
+ const cached = cache.get(memoryId);
7442
+ if (cached && cached.length === queryEmbedding.length) continue;
7443
+ if (cached) cache.delete(memoryId);
7444
+ const storedModel = memories[i].embeddingModel;
7445
+ const modelCompatible = (storedModel ?? currentModel) === currentModel;
7446
+ if (memories[i].embedding && modelCompatible) {
7447
+ try {
7448
+ const parsed = JSON.parse(memories[i].embedding);
7449
+ if (Array.isArray(parsed) && parsed.length === queryEmbedding.length) {
7450
+ cache.set(memoryId, Float32Array.from(parsed));
7451
+ continue;
7452
+ }
7453
+ } catch {
7454
+ }
7455
+ }
7456
+ if (memories[i].embedding && !modelCompatible) staleReembedCount++;
7457
+ uncachedTexts.push(content);
7458
+ uncachedIndices.push(i);
7459
+ }
7460
+ if (staleReembedCount > 0) {
7461
+ getLogger().warn(
7462
+ `memoryVault: re-embedding ${staleReembedCount} memories whose stored embedding model differs from the current model (${currentModel}) \u2014 embedding-model change detected`
7463
+ );
7464
+ }
7465
+ if (uncachedTexts.length > 0) {
7466
+ const newEmbeddings = await generateEmbeddings(uncachedTexts, embeddingOptions);
7467
+ for (let j = 0; j < uncachedTexts.length; j++) {
7468
+ cache.set(memories[uncachedIndices[j]].uniqueId, Float32Array.from(newEmbeddings[j]));
7469
+ updateVaultMemoryEmbeddingOp(
7470
+ vaultCtx,
7471
+ memories[uncachedIndices[j]].uniqueId,
7472
+ JSON.stringify(newEmbeddings[j]),
7473
+ currentModel
7474
+ ).catch(
7475
+ // Silently swallow – SDK must not use console.*; embedding will be retried on next search
7476
+ () => {
7477
+ }
7478
+ );
7479
+ }
7480
+ }
7481
+ embeddedItems = memories.map((m) => ({
7482
+ id: m.uniqueId,
7483
+ content: m.content,
7484
+ embedding: cache.get(m.uniqueId) ?? [],
7485
+ createdAt: m.createdAt,
7486
+ updatedAt: m.updatedAt,
7487
+ proofCount: m.proofCount,
7488
+ lastObservedAt: m.lastObservedAt,
7489
+ eventTimeStart: m.eventTimeStart,
7490
+ sourceChunkIds: m.sourceChunkIds,
7491
+ eventTimeEnd: m.eventTimeEnd,
7492
+ eventTimeKind: normalizeEventTimeKind(m.eventTimeKind),
7493
+ factType: m.factType
7494
+ }));
7495
+ }
7279
7496
  if (queryEmbedding.length > 0) {
7280
7497
  const mismatched = embeddedItems.filter(
7281
7498
  (it) => it.embedding.length > 0 && it.embedding.length !== queryEmbedding.length
@@ -7361,7 +7578,7 @@ async function searchVaultMemoriesWithSize(query, vaultCtx, embeddingOptions, ca
7361
7578
  });
7362
7579
  return stampTimestamps({
7363
7580
  results: composite,
7364
- vaultSize: loaded.length,
7581
+ vaultSize,
7365
7582
  reranked: rerankStats.applied,
7366
7583
  hadV2Head: v2HeadStats.hadResults
7367
7584
  });
@@ -7386,7 +7603,7 @@ async function searchVaultMemoriesWithSize(query, vaultCtx, embeddingOptions, ca
7386
7603
  });
7387
7604
  return stampTimestamps({
7388
7605
  results: results2,
7389
- vaultSize: loaded.length,
7606
+ vaultSize,
7390
7607
  reranked: rerankStats.applied,
7391
7608
  hadV2Head: v2HeadStats.hadResults
7392
7609
  });
@@ -7399,7 +7616,7 @@ async function searchVaultMemoriesWithSize(query, vaultCtx, embeddingOptions, ca
7399
7616
  ...searchOptions?.entityRanking && { entityRanking: searchOptions.entityRanking },
7400
7617
  ...searchOptions?.temporalRanking && { temporalRanking: searchOptions.temporalRanking }
7401
7618
  });
7402
- return stampTimestamps({ results: results2, vaultSize: loaded.length, hadV2Head: results2.length > 0 });
7619
+ return stampTimestamps({ results: results2, vaultSize, hadV2Head: results2.length > 0 });
7403
7620
  }
7404
7621
  const results = rankVaultMemories(query, queryEmbedding, embeddedItems, {
7405
7622
  limit,
@@ -7411,7 +7628,7 @@ async function searchVaultMemoriesWithSize(query, vaultCtx, embeddingOptions, ca
7411
7628
  supersessionWindow: searchOptions.supersessionWindow
7412
7629
  }
7413
7630
  });
7414
- return stampTimestamps({ results, vaultSize: loaded.length, hadV2Head: results.length > 0 });
7631
+ return stampTimestamps({ results, vaultSize, hadV2Head: results.length > 0 });
7415
7632
  }
7416
7633
  async function searchVaultMemories(query, vaultCtx, embeddingOptions, cache, searchOptions) {
7417
7634
  const { results } = await searchVaultMemoriesWithSize(
@@ -4867,6 +4867,18 @@ interface MemoryVaultSearchOptions {
4867
4867
  * pass-through from `recall()` when the query has a temporal phrase.
4868
4868
  */
4869
4869
  temporalRanking?: string[];
4870
+ /**
4871
+ * B2 decrypt-last — when set, build the ranking corpus from a
4872
+ * column-projected key scan + vector LRU (no whole-vault blob load),
4873
+ * decrypting content only for the admission window via
4874
+ * {@link buildProjectedCorpus}. Default OFF: the legacy whole-vault
4875
+ * prefix stays byte-identical.
4876
+ */
4877
+ decryptLast?: boolean;
4878
+ /** Admission window multiplier for decrypt-last (`limit * admitFactor`). Default 3. */
4879
+ admitFactor?: number;
4880
+ /** Admission window floor for decrypt-last. Default 30. */
4881
+ admitFloor?: number;
4870
4882
  }
4871
4883
  /**
4872
4884
  * Pre-embed all vault memories that are not yet in the cache.
@@ -5147,6 +5159,13 @@ interface RecallOptions {
5147
5159
  bm25AdmissionDivisor?: number;
5148
5160
  /** RRF smoothing constant for lane fusion (facts × chunks and side lanes). Default: 60. */
5149
5161
  rrfK?: number;
5162
+ /**
5163
+ * Decrypt vault memory content only for the top-N ranked candidates
5164
+ * instead of the whole vault. Forwarded verbatim to the vault search
5165
+ * pipeline's `MemoryVaultSearchOptions`. Default: off (legacy
5166
+ * whole-vault decrypt path).
5167
+ */
5168
+ decryptLast?: boolean;
5150
5169
  /** Total graph hops incl. the seed lookup (hop 1). Default: 1 (seed only). */
5151
5170
  maxHops?: number;
5152
5171
  /** Max neighbor entities expanded per hop. Default: 8. */
@@ -4867,6 +4867,18 @@ interface MemoryVaultSearchOptions {
4867
4867
  * pass-through from `recall()` when the query has a temporal phrase.
4868
4868
  */
4869
4869
  temporalRanking?: string[];
4870
+ /**
4871
+ * B2 decrypt-last — when set, build the ranking corpus from a
4872
+ * column-projected key scan + vector LRU (no whole-vault blob load),
4873
+ * decrypting content only for the admission window via
4874
+ * {@link buildProjectedCorpus}. Default OFF: the legacy whole-vault
4875
+ * prefix stays byte-identical.
4876
+ */
4877
+ decryptLast?: boolean;
4878
+ /** Admission window multiplier for decrypt-last (`limit * admitFactor`). Default 3. */
4879
+ admitFactor?: number;
4880
+ /** Admission window floor for decrypt-last. Default 30. */
4881
+ admitFloor?: number;
4870
4882
  }
4871
4883
  /**
4872
4884
  * Pre-embed all vault memories that are not yet in the cache.
@@ -5147,6 +5159,13 @@ interface RecallOptions {
5147
5159
  bm25AdmissionDivisor?: number;
5148
5160
  /** RRF smoothing constant for lane fusion (facts × chunks and side lanes). Default: 60. */
5149
5161
  rrfK?: number;
5162
+ /**
5163
+ * Decrypt vault memory content only for the top-N ranked candidates
5164
+ * instead of the whole vault. Forwarded verbatim to the vault search
5165
+ * pipeline's `MemoryVaultSearchOptions`. Default: off (legacy
5166
+ * whole-vault decrypt path).
5167
+ */
5168
+ decryptLast?: boolean;
5150
5169
  /** Total graph hops incl. the seed lookup (hop 1). Default: 1 (seed only). */
5151
5170
  maxHops?: number;
5152
5171
  /** Max neighbor entities expanded per hop. Default: 8. */
@@ -108,7 +108,7 @@ import {
108
108
  upsertMessageOp,
109
109
  useEncryption,
110
110
  vaultMemoryToStored
111
- } from "./chunk-42Y42CAZ.mjs";
111
+ } from "./chunk-YFJAHJMB.mjs";
112
112
  import {
113
113
  PII_PATTERNS,
114
114
  PiiRedactor,
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  recall
3
- } from "./chunk-42Y42CAZ.mjs";
3
+ } from "./chunk-YFJAHJMB.mjs";
4
4
  import "./chunk-BOY27A2C.mjs";
5
5
  import "./chunk-GYKJOWEO.mjs";
6
6
  export {