@anuma/sdk 3.8.5 → 3.9.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.
@@ -2381,6 +2381,85 @@ async function getAllVaultMemoriesOp(ctx, options) {
2381
2381
  (raw) => vaultMemoryRawToStored(raw, ctx.walletAddress, ctx.signMessage, ctx.embeddedWalletSigner)
2382
2382
  );
2383
2383
  }
2384
+ function baseVaultSql(ctx) {
2385
+ const clauses = [
2386
+ '"is_deleted" = 0',
2387
+ '"archived_at" is null',
2388
+ `"trust_tier" is not 'quarantined'`,
2389
+ '"superseded_by" is null'
2390
+ ];
2391
+ const args = [];
2392
+ if (ctx.userId !== void 0) {
2393
+ clauses.push('"user_id" = ?');
2394
+ args.push(ctx.userId);
2395
+ }
2396
+ return { sql: clauses.join(" and "), args };
2397
+ }
2398
+ async function getVaultCandidateKeysOp(ctx, options) {
2399
+ const mapRaw = (raw) => ({
2400
+ uniqueId: raw.id,
2401
+ folderId: raw.folder_id ?? null,
2402
+ scope: raw.scope ?? "",
2403
+ embeddingModel: raw.embedding_model ?? null,
2404
+ updatedAt: new Date(raw.updated_at)
2405
+ });
2406
+ try {
2407
+ const base = baseVaultSql(ctx);
2408
+ const clauses = [base.sql];
2409
+ const args = [...base.args];
2410
+ if (options?.scopes?.length) {
2411
+ clauses.push(`"scope" in (${options.scopes.map(() => "?").join(",")})`);
2412
+ args.push(...options.scopes);
2413
+ }
2414
+ if (options?.folderId !== void 0) {
2415
+ clauses.push(options.folderId === null ? '"folder_id" is null' : '"folder_id" = ?');
2416
+ if (options.folderId !== null) args.push(options.folderId);
2417
+ }
2418
+ const sql = `select "id", "scope", "folder_id", "embedding_model", "updated_at" from "memory_vault" where ${clauses.join(" and ")}`;
2419
+ const rows = await ctx.vaultMemoryCollection.query(Q3.unsafeSqlQuery(sql, args)).unsafeFetchRaw();
2420
+ return rows.map(mapRaw);
2421
+ } catch (err) {
2422
+ getLogger().debug(
2423
+ "memoryVault: getVaultCandidateKeysOp projected SQL unavailable, using full-load fallback: " + (err instanceof Error ? err.message : String(err))
2424
+ );
2425
+ const conditions = [
2426
+ ...baseVaultConditions(ctx),
2427
+ ...options?.scopes?.length ? [Q3.where("scope", Q3.oneOf(options.scopes))] : [],
2428
+ ...options?.folderId !== void 0 ? [Q3.where("folder_id", options.folderId)] : []
2429
+ ];
2430
+ const rows = await ctx.vaultMemoryCollection.query(...conditions).unsafeFetchRaw();
2431
+ return rows.map(mapRaw);
2432
+ }
2433
+ }
2434
+ async function getVaultEmbeddingsByIdsOp(ctx, ids) {
2435
+ if (ids.length === 0) return [];
2436
+ const mapRaw = (raw) => ({
2437
+ uniqueId: raw.id,
2438
+ embedding: raw.embedding ?? null,
2439
+ embeddingModel: raw.embedding_model ?? null
2440
+ });
2441
+ try {
2442
+ const base = baseVaultSql(ctx);
2443
+ const sql = `select "id", "embedding", "embedding_model" from "memory_vault" where ${base.sql} and "id" in (${ids.map(() => "?").join(",")})`;
2444
+ const rows = await ctx.vaultMemoryCollection.query(Q3.unsafeSqlQuery(sql, [...base.args, ...ids])).unsafeFetchRaw();
2445
+ return rows.map(mapRaw);
2446
+ } catch (err) {
2447
+ getLogger().debug(
2448
+ "memoryVault: getVaultEmbeddingsByIdsOp projected SQL unavailable, using full-load fallback: " + (err instanceof Error ? err.message : String(err))
2449
+ );
2450
+ const rows = await ctx.vaultMemoryCollection.query(...baseVaultConditions(ctx), Q3.where("id", Q3.oneOf(ids))).unsafeFetchRaw();
2451
+ return rows.map(mapRaw);
2452
+ }
2453
+ }
2454
+ async function getVaultMemoriesByIdsOp(ctx, ids) {
2455
+ if (ids.length === 0) return [];
2456
+ const conditions = [...baseVaultConditions(ctx), Q3.where("id", Q3.oneOf(ids))];
2457
+ const results = await ctx.vaultMemoryCollection.query(...conditions).unsafeFetchRaw();
2458
+ return mapInBatches(
2459
+ results,
2460
+ (raw) => vaultMemoryRawToStored(raw, ctx.walletAddress, ctx.signMessage, ctx.embeddedWalletSigner)
2461
+ );
2462
+ }
2384
2463
  async function getAllVaultMemoryContentsOp(ctx, options) {
2385
2464
  const results = await ctx.vaultMemoryCollection.query(...baseVaultConditions(ctx, options)).unsafeFetchRaw();
2386
2465
  return mapInBatches(results, async (raw) => {
@@ -5071,80 +5150,97 @@ async function eagerEmbedContent(content, embeddingOptions, cache, vaultCtx, mem
5071
5150
  );
5072
5151
  }
5073
5152
  }
5074
- async function searchVaultMemoriesWithSize(query, vaultCtx, embeddingOptions, cache, searchOptions) {
5075
- const limit = searchOptions?.limit ?? 5;
5076
- const minSimilarity = searchOptions?.minSimilarity ?? 0.1;
5077
- const scopes = searchOptions?.scopes;
5078
- if (!query || typeof query !== "string") {
5079
- return { results: [], vaultSize: 0, reranked: false, hadV2Head: false };
5080
- }
5081
- const folderId = searchOptions?.folderId;
5082
- const queryOpts = {};
5083
- if (scopes?.length) queryOpts.scopes = scopes;
5084
- if (folderId !== void 0) queryOpts.folderId = folderId;
5085
- if (searchOptions?.factTypes?.length) queryOpts.factTypes = searchOptions.factTypes;
5086
- if (searchOptions?.includeArchived) queryOpts.includeArchived = true;
5087
- const loaded = await getAllVaultMemoriesOp(
5153
+ function admitVaultProjections(queryEmbedding, vectored, k) {
5154
+ 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);
5155
+ }
5156
+ async function buildProjectedCorpus(query, vaultCtx, embeddingOptions, cache, queryOpts, opts) {
5157
+ const keys = await getVaultCandidateKeysOp(
5088
5158
  vaultCtx,
5089
5159
  Object.keys(queryOpts).length > 0 ? queryOpts : void 0
5090
5160
  );
5091
- const memories = loaded.filter((m) => !isEncrypted(m.content));
5092
- if (memories.length < loaded.length) {
5093
- getLogger().warn(
5094
- `memoryVault: ${loaded.length - memories.length}/${loaded.length} memories still encrypted (key unavailable?) \u2014 excluded from search`
5095
- );
5096
- }
5097
- if (memories.length === 0) {
5098
- return { results: [], vaultSize: loaded.length, reranked: false, hadV2Head: false };
5161
+ const vaultSize = keys.length;
5162
+ if (keys.length === 0) {
5163
+ return { memories: [], embeddedItems: [], queryEmbedding: [], vaultSize: 0 };
5099
5164
  }
5100
5165
  const queryEmbedding = await generateEmbedding(query, embeddingOptions);
5101
5166
  const currentModel = embeddingOptions.model ?? DEFAULT_API_EMBEDDING_MODEL;
5102
- const uncachedTexts = [];
5103
- const uncachedIndices = [];
5104
- let staleReembedCount = 0;
5105
- for (let i = 0; i < memories.length; i++) {
5106
- const content = memories[i].content;
5107
- const memoryId = memories[i].uniqueId;
5108
- const cached = cache.get(memoryId);
5109
- if (cached && cached.length === queryEmbedding.length) continue;
5110
- if (cached) cache.delete(memoryId);
5111
- const storedModel = memories[i].embeddingModel;
5112
- const modelCompatible = (storedModel ?? currentModel) === currentModel;
5113
- if (memories[i].embedding && modelCompatible) {
5167
+ const vectored = [];
5168
+ const missIds = [];
5169
+ const noVectorIds = [];
5170
+ const keyById = new Map(keys.map((k2) => [k2.uniqueId, k2]));
5171
+ for (const k2 of keys) {
5172
+ const cached = cache.get(k2.uniqueId);
5173
+ if (cached && cached.length === queryEmbedding.length) {
5174
+ vectored.push({ uniqueId: k2.uniqueId, embedding: cached, updatedAt: k2.updatedAt });
5175
+ continue;
5176
+ }
5177
+ const modelCompatible = (k2.embeddingModel ?? currentModel) === currentModel;
5178
+ if (modelCompatible) missIds.push(k2.uniqueId);
5179
+ else noVectorIds.push(k2.uniqueId);
5180
+ }
5181
+ if (missIds.length > 0) {
5182
+ const rows = await getVaultEmbeddingsByIdsOp(vaultCtx, missIds);
5183
+ const gotVector = /* @__PURE__ */ new Set();
5184
+ for (const r of rows) {
5185
+ if (!r.embedding) continue;
5114
5186
  try {
5115
- const parsed = JSON.parse(memories[i].embedding);
5187
+ const parsed = JSON.parse(r.embedding);
5116
5188
  if (Array.isArray(parsed) && parsed.length === queryEmbedding.length) {
5117
- cache.set(memoryId, Float32Array.from(parsed));
5118
- continue;
5189
+ const vec = Float32Array.from(parsed);
5190
+ cache.set(r.uniqueId, vec);
5191
+ const k2 = keyById.get(r.uniqueId);
5192
+ vectored.push({ uniqueId: r.uniqueId, embedding: vec, updatedAt: k2.updatedAt });
5193
+ gotVector.add(r.uniqueId);
5119
5194
  }
5120
5195
  } catch {
5121
5196
  }
5122
5197
  }
5123
- if (memories[i].embedding && !modelCompatible) staleReembedCount++;
5124
- uncachedTexts.push(content);
5125
- uncachedIndices.push(i);
5198
+ for (const id of missIds) if (!gotVector.has(id)) noVectorIds.push(id);
5126
5199
  }
5127
- if (staleReembedCount > 0) {
5128
- getLogger().warn(
5129
- `memoryVault: re-embedding ${staleReembedCount} memories whose stored embedding model differs from the current model (${currentModel}) \u2014 embedding-model change detected`
5200
+ if (noVectorIds.length > 0) {
5201
+ const laneIds = noVectorIds.slice(0, opts.unembeddedCap);
5202
+ if (noVectorIds.length > laneIds.length) {
5203
+ getLogger().warn(
5204
+ `memoryVault: projected search un-embedded lane capped at ${laneIds.length}/${noVectorIds.length}`
5205
+ );
5206
+ }
5207
+ const laneRows = (await getVaultMemoriesByIdsOp(vaultCtx, laneIds)).filter(
5208
+ (m) => !isEncrypted(m.content)
5130
5209
  );
5131
- }
5132
- if (uncachedTexts.length > 0) {
5133
- const newEmbeddings = await generateEmbeddings(uncachedTexts, embeddingOptions);
5134
- for (let j = 0; j < uncachedTexts.length; j++) {
5135
- cache.set(memories[uncachedIndices[j]].uniqueId, Float32Array.from(newEmbeddings[j]));
5136
- updateVaultMemoryEmbeddingOp(
5137
- vaultCtx,
5138
- memories[uncachedIndices[j]].uniqueId,
5139
- JSON.stringify(newEmbeddings[j]),
5140
- currentModel
5141
- ).catch(
5142
- // Silently swallow – SDK must not use console.*; embedding will be retried on next search
5143
- () => {
5144
- }
5210
+ if (laneRows.length > 0) {
5211
+ const laneVecs = await generateEmbeddings(
5212
+ laneRows.map((m) => m.content),
5213
+ embeddingOptions
5145
5214
  );
5215
+ laneRows.forEach((m, i) => {
5216
+ const vec = Float32Array.from(laneVecs[i]);
5217
+ cache.set(m.uniqueId, vec);
5218
+ vectored.push({ uniqueId: m.uniqueId, embedding: vec, updatedAt: m.updatedAt });
5219
+ updateVaultMemoryEmbeddingOp(
5220
+ vaultCtx,
5221
+ m.uniqueId,
5222
+ JSON.stringify(laneVecs[i]),
5223
+ currentModel
5224
+ ).catch(() => {
5225
+ });
5226
+ });
5227
+ }
5228
+ }
5229
+ const k = Math.max(opts.limit * opts.admitFactor, opts.admitFloor);
5230
+ const admittedIds = admitVaultProjections(queryEmbedding, vectored, k);
5231
+ const admissionSet = new Set(admittedIds);
5232
+ if (opts.forceIncludeIds) {
5233
+ for (const id of opts.forceIncludeIds) {
5234
+ if (keyById.has(id)) admissionSet.add(id);
5146
5235
  }
5147
5236
  }
5237
+ const admittedRows = await getVaultMemoriesByIdsOp(vaultCtx, [...admissionSet]);
5238
+ const memories = admittedRows.filter((m) => !isEncrypted(m.content));
5239
+ if (memories.length < admittedRows.length) {
5240
+ getLogger().warn(
5241
+ `memoryVault: ${admittedRows.length - memories.length}/${admittedRows.length} admitted memories still encrypted (key unavailable?) \u2014 excluded from projected search`
5242
+ );
5243
+ }
5148
5244
  const embeddedItems = memories.map((m) => ({
5149
5245
  id: m.uniqueId,
5150
5246
  content: m.content,
@@ -5159,6 +5255,125 @@ async function searchVaultMemoriesWithSize(query, vaultCtx, embeddingOptions, ca
5159
5255
  eventTimeKind: normalizeEventTimeKind(m.eventTimeKind),
5160
5256
  factType: m.factType
5161
5257
  }));
5258
+ return { memories, embeddedItems, queryEmbedding, vaultSize };
5259
+ }
5260
+ async function searchVaultMemoriesWithSize(query, vaultCtx, embeddingOptions, cache, searchOptions) {
5261
+ const limit = searchOptions?.limit ?? 5;
5262
+ const minSimilarity = searchOptions?.minSimilarity ?? 0.1;
5263
+ const scopes = searchOptions?.scopes;
5264
+ if (!query || typeof query !== "string") {
5265
+ return { results: [], vaultSize: 0, reranked: false, hadV2Head: false };
5266
+ }
5267
+ const folderId = searchOptions?.folderId;
5268
+ const queryOpts = {};
5269
+ if (scopes?.length) queryOpts.scopes = scopes;
5270
+ if (folderId !== void 0) queryOpts.folderId = folderId;
5271
+ if (searchOptions?.factTypes?.length) queryOpts.factTypes = searchOptions.factTypes;
5272
+ if (searchOptions?.includeArchived) queryOpts.includeArchived = true;
5273
+ const ADMIT_FACTOR = searchOptions?.admitFactor ?? 3;
5274
+ const ADMIT_FLOOR = searchOptions?.admitFloor ?? 30;
5275
+ const UNEMBEDDED_CAP = 200;
5276
+ let memories;
5277
+ let embeddedItems;
5278
+ let queryEmbedding;
5279
+ let vaultSize;
5280
+ if (searchOptions?.decryptLast) {
5281
+ const forceIncludeIds = [
5282
+ ...searchOptions.entityRanking ?? [],
5283
+ ...searchOptions.temporalRanking ?? []
5284
+ ];
5285
+ const corpus = await buildProjectedCorpus(query, vaultCtx, embeddingOptions, cache, queryOpts, {
5286
+ limit,
5287
+ admitFactor: ADMIT_FACTOR,
5288
+ admitFloor: ADMIT_FLOOR,
5289
+ unembeddedCap: UNEMBEDDED_CAP,
5290
+ ...forceIncludeIds.length > 0 && { forceIncludeIds }
5291
+ });
5292
+ if (corpus.vaultSize === 0) {
5293
+ return { results: [], vaultSize: 0, reranked: false, hadV2Head: false };
5294
+ }
5295
+ ({ memories, embeddedItems, queryEmbedding, vaultSize } = corpus);
5296
+ if (memories.length === 0) {
5297
+ return { results: [], vaultSize, reranked: false, hadV2Head: false };
5298
+ }
5299
+ } else {
5300
+ const loaded = await getAllVaultMemoriesOp(
5301
+ vaultCtx,
5302
+ Object.keys(queryOpts).length > 0 ? queryOpts : void 0
5303
+ );
5304
+ vaultSize = loaded.length;
5305
+ memories = loaded.filter((m) => !isEncrypted(m.content));
5306
+ if (memories.length < loaded.length) {
5307
+ getLogger().warn(
5308
+ `memoryVault: ${loaded.length - memories.length}/${loaded.length} memories still encrypted (key unavailable?) \u2014 excluded from search`
5309
+ );
5310
+ }
5311
+ if (memories.length === 0) {
5312
+ return { results: [], vaultSize: loaded.length, reranked: false, hadV2Head: false };
5313
+ }
5314
+ queryEmbedding = await generateEmbedding(query, embeddingOptions);
5315
+ const currentModel = embeddingOptions.model ?? DEFAULT_API_EMBEDDING_MODEL;
5316
+ const uncachedTexts = [];
5317
+ const uncachedIndices = [];
5318
+ let staleReembedCount = 0;
5319
+ for (let i = 0; i < memories.length; i++) {
5320
+ const content = memories[i].content;
5321
+ const memoryId = memories[i].uniqueId;
5322
+ const cached = cache.get(memoryId);
5323
+ if (cached && cached.length === queryEmbedding.length) continue;
5324
+ if (cached) cache.delete(memoryId);
5325
+ const storedModel = memories[i].embeddingModel;
5326
+ const modelCompatible = (storedModel ?? currentModel) === currentModel;
5327
+ if (memories[i].embedding && modelCompatible) {
5328
+ try {
5329
+ const parsed = JSON.parse(memories[i].embedding);
5330
+ if (Array.isArray(parsed) && parsed.length === queryEmbedding.length) {
5331
+ cache.set(memoryId, Float32Array.from(parsed));
5332
+ continue;
5333
+ }
5334
+ } catch {
5335
+ }
5336
+ }
5337
+ if (memories[i].embedding && !modelCompatible) staleReembedCount++;
5338
+ uncachedTexts.push(content);
5339
+ uncachedIndices.push(i);
5340
+ }
5341
+ if (staleReembedCount > 0) {
5342
+ getLogger().warn(
5343
+ `memoryVault: re-embedding ${staleReembedCount} memories whose stored embedding model differs from the current model (${currentModel}) \u2014 embedding-model change detected`
5344
+ );
5345
+ }
5346
+ if (uncachedTexts.length > 0) {
5347
+ const newEmbeddings = await generateEmbeddings(uncachedTexts, embeddingOptions);
5348
+ for (let j = 0; j < uncachedTexts.length; j++) {
5349
+ cache.set(memories[uncachedIndices[j]].uniqueId, Float32Array.from(newEmbeddings[j]));
5350
+ updateVaultMemoryEmbeddingOp(
5351
+ vaultCtx,
5352
+ memories[uncachedIndices[j]].uniqueId,
5353
+ JSON.stringify(newEmbeddings[j]),
5354
+ currentModel
5355
+ ).catch(
5356
+ // Silently swallow – SDK must not use console.*; embedding will be retried on next search
5357
+ () => {
5358
+ }
5359
+ );
5360
+ }
5361
+ }
5362
+ embeddedItems = memories.map((m) => ({
5363
+ id: m.uniqueId,
5364
+ content: m.content,
5365
+ embedding: cache.get(m.uniqueId) ?? [],
5366
+ createdAt: m.createdAt,
5367
+ updatedAt: m.updatedAt,
5368
+ proofCount: m.proofCount,
5369
+ lastObservedAt: m.lastObservedAt,
5370
+ eventTimeStart: m.eventTimeStart,
5371
+ sourceChunkIds: m.sourceChunkIds,
5372
+ eventTimeEnd: m.eventTimeEnd,
5373
+ eventTimeKind: normalizeEventTimeKind(m.eventTimeKind),
5374
+ factType: m.factType
5375
+ }));
5376
+ }
5162
5377
  if (queryEmbedding.length > 0) {
5163
5378
  const mismatched = embeddedItems.filter(
5164
5379
  (it) => it.embedding.length > 0 && it.embedding.length !== queryEmbedding.length
@@ -5244,7 +5459,7 @@ async function searchVaultMemoriesWithSize(query, vaultCtx, embeddingOptions, ca
5244
5459
  });
5245
5460
  return stampTimestamps({
5246
5461
  results: composite,
5247
- vaultSize: loaded.length,
5462
+ vaultSize,
5248
5463
  reranked: rerankStats.applied,
5249
5464
  hadV2Head: v2HeadStats.hadResults
5250
5465
  });
@@ -5269,7 +5484,7 @@ async function searchVaultMemoriesWithSize(query, vaultCtx, embeddingOptions, ca
5269
5484
  });
5270
5485
  return stampTimestamps({
5271
5486
  results: results2,
5272
- vaultSize: loaded.length,
5487
+ vaultSize,
5273
5488
  reranked: rerankStats.applied,
5274
5489
  hadV2Head: v2HeadStats.hadResults
5275
5490
  });
@@ -5282,7 +5497,7 @@ async function searchVaultMemoriesWithSize(query, vaultCtx, embeddingOptions, ca
5282
5497
  ...searchOptions?.entityRanking && { entityRanking: searchOptions.entityRanking },
5283
5498
  ...searchOptions?.temporalRanking && { temporalRanking: searchOptions.temporalRanking }
5284
5499
  });
5285
- return stampTimestamps({ results: results2, vaultSize: loaded.length, hadV2Head: results2.length > 0 });
5500
+ return stampTimestamps({ results: results2, vaultSize, hadV2Head: results2.length > 0 });
5286
5501
  }
5287
5502
  const results = rankVaultMemories(query, queryEmbedding, embeddedItems, {
5288
5503
  limit,
@@ -5294,7 +5509,7 @@ async function searchVaultMemoriesWithSize(query, vaultCtx, embeddingOptions, ca
5294
5509
  supersessionWindow: searchOptions.supersessionWindow
5295
5510
  }
5296
5511
  });
5297
- return stampTimestamps({ results, vaultSize: loaded.length, hadV2Head: results.length > 0 });
5512
+ return stampTimestamps({ results, vaultSize, hadV2Head: results.length > 0 });
5298
5513
  }
5299
5514
  async function searchVaultMemories(query, vaultCtx, embeddingOptions, cache, searchOptions) {
5300
5515
  const { results } = await searchVaultMemoriesWithSize(
@@ -5383,7 +5598,7 @@ function createMemoryVaultSearchTool(vaultCtx, embeddingOptions, cache, searchOp
5383
5598
  legacy.map((r) => ({ id: r.uniqueId, content: r.content, score: r.similarity }))
5384
5599
  );
5385
5600
  }
5386
- const { recall: recall2 } = await import("./recall-JFZ3Z6EX.mjs");
5601
+ const { recall: recall2 } = await import("./recall-KWTVD4IR.mjs");
5387
5602
  const result = await recall2(
5388
5603
  query,
5389
5604
  { vaultCtx, embeddingOptions, vaultCache: cache },
@@ -6030,6 +6245,7 @@ async function recall(query, ctx, options = {}) {
6030
6245
  bm25AdmissionDivisor: options.bm25AdmissionDivisor
6031
6246
  },
6032
6247
  ...options.rrfK !== void 0 && { rrfK: options.rrfK },
6248
+ ...options.decryptLast !== void 0 && { decryptLast: options.decryptLast },
6033
6249
  ...decomposeAvailable && {
6034
6250
  decompose: "llm",
6035
6251
  decomposeOptions: options.decomposeOptions