@anuma/sdk 3.9.4 → 3.9.6

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.
@@ -4485,24 +4485,25 @@ function tokenize(text) {
4485
4485
  if (!m) return [];
4486
4486
  return m.filter((t) => !STOPWORDS.has(t));
4487
4487
  }
4488
- function scoreBM25(query, items) {
4489
- const queryTerms = tokenize(query);
4490
- if (queryTerms.length === 0 || items.length === 0) return /* @__PURE__ */ new Map();
4488
+ function prepareBM25Corpus(items) {
4489
+ const ids = items.map((i) => i.id);
4491
4490
  const docTokens = items.map((i) => tokenize(i.content));
4492
4491
  const docLens = docTokens.map((t) => t.length);
4493
- const avgdl = docLens.reduce((a, b) => a + b, 0) / docLens.length;
4494
- const queryTermSet = new Set(queryTerms);
4492
+ const avgdl = docLens.length ? docLens.reduce((a, b) => a + b, 0) / docLens.length : 0;
4495
4493
  const df = /* @__PURE__ */ new Map();
4496
4494
  for (const tokens of docTokens) {
4497
- const seen = /* @__PURE__ */ new Set();
4498
- for (const t of tokens) {
4499
- if (queryTermSet.has(t)) seen.add(t);
4500
- }
4495
+ const seen = new Set(tokens);
4501
4496
  for (const t of seen) df.set(t, (df.get(t) ?? 0) + 1);
4502
4497
  }
4503
- const N = items.length;
4498
+ return { ids, docTokens, docLens, avgdl, df, n: items.length };
4499
+ }
4500
+ function scoreBM25Prepared(query, corpus) {
4501
+ const queryTerms = tokenize(query);
4504
4502
  const scores = /* @__PURE__ */ new Map();
4505
- for (let i = 0; i < items.length; i++) {
4503
+ if (queryTerms.length === 0 || corpus.n === 0) return scores;
4504
+ const queryTermSet = new Set(queryTerms);
4505
+ const { ids, docTokens, docLens, avgdl, df, n: N } = corpus;
4506
+ for (let i = 0; i < N; i++) {
4506
4507
  const tokens = docTokens[i];
4507
4508
  const dl = docLens[i];
4508
4509
  if (dl === 0) continue;
@@ -4518,10 +4519,15 @@ function scoreBM25(query, items) {
4518
4519
  const tfNorm = f * (K1 + 1) / (f + K1 * (1 - B + B * dl / avgdl));
4519
4520
  score += idf * tfNorm;
4520
4521
  }
4521
- scores.set(items[i].id, score);
4522
+ scores.set(ids[i], score);
4522
4523
  }
4523
4524
  return scores;
4524
4525
  }
4526
+ function scoreBM25(query, items) {
4527
+ if (items.length === 0) return /* @__PURE__ */ new Map();
4528
+ if (tokenize(query).length === 0) return /* @__PURE__ */ new Map();
4529
+ return scoreBM25Prepared(query, prepareBM25Corpus(items));
4530
+ }
4525
4531
 
4526
4532
  // src/lib/memoryVault/decomposeQuery.ts
4527
4533
  var DEFAULT_MODEL = "inclusionai/ling-2.6-flash";
@@ -4776,7 +4782,7 @@ function rankFusedVaultMemories(query, queryEmbedding, items, options) {
4776
4782
  }
4777
4783
  });
4778
4784
  const baseIds = new Set(baseRanked.map((r) => r.uniqueId));
4779
- const bm25Scores = scoreBM25(
4785
+ const bm25Scores = options?.preparedBM25Corpus ? scoreBM25Prepared(query, options.preparedBM25Corpus) : scoreBM25(
4780
4786
  query,
4781
4787
  items.map((i) => ({ id: i.id, content: i.content }))
4782
4788
  );
@@ -4973,7 +4979,11 @@ async function rankComposite(originalQuery, originalQueryEmbedding, subQueries,
4973
4979
  const limit = options?.limit ?? 5;
4974
4980
  const perFacetTopN = options?.perFacetTopN ?? 10;
4975
4981
  if (items.length === 0 || subQueries.length === 0) return [];
4982
+ const preparedBM25Corpus = prepareBM25Corpus(
4983
+ items.map((i) => ({ id: i.id, content: i.content }))
4984
+ );
4976
4985
  const facetTuning = {
4986
+ preparedBM25Corpus,
4977
4987
  ...options?.recencyAlpha !== void 0 && { recencyAlpha: options.recencyAlpha },
4978
4988
  ...options?.recency && { recency: options.recency },
4979
4989
  ...options?.supersessionBoost !== void 0 && {
@@ -5283,13 +5293,12 @@ async function buildProjectedCorpus(query, vaultCtx, embeddingOptions, cache, qu
5283
5293
  }));
5284
5294
  return { memories, embeddedItems, queryEmbedding, vaultSize };
5285
5295
  }
5286
- async function searchVaultMemoriesWithSize(query, vaultCtx, embeddingOptions, cache, searchOptions) {
5287
- const limit = searchOptions?.limit ?? 5;
5288
- const minSimilarity = searchOptions?.minSimilarity ?? 0.1;
5289
- const scopes = searchOptions?.scopes;
5296
+ async function prepareVaultCandidates(query, vaultCtx, embeddingOptions, cache, searchOptions) {
5290
5297
  if (!query || typeof query !== "string") {
5291
- return { results: [], vaultSize: 0, reranked: false, hadV2Head: false };
5298
+ return { memories: [], embeddedItems: [], queryEmbedding: [], vaultSize: 0 };
5292
5299
  }
5300
+ const limit = searchOptions?.limit ?? 5;
5301
+ const scopes = searchOptions?.scopes;
5293
5302
  const folderId = searchOptions?.folderId;
5294
5303
  const queryOpts = {};
5295
5304
  if (scopes?.length) queryOpts.scopes = scopes;
@@ -5316,11 +5325,11 @@ async function searchVaultMemoriesWithSize(query, vaultCtx, embeddingOptions, ca
5316
5325
  ...forceIncludeIds.length > 0 && { forceIncludeIds }
5317
5326
  });
5318
5327
  if (corpus.vaultSize === 0) {
5319
- return { results: [], vaultSize: 0, reranked: false, hadV2Head: false };
5328
+ return { memories: [], embeddedItems: [], queryEmbedding: [], vaultSize: 0 };
5320
5329
  }
5321
5330
  ({ memories, embeddedItems, queryEmbedding, vaultSize } = corpus);
5322
5331
  if (memories.length === 0) {
5323
- return { results: [], vaultSize, reranked: false, hadV2Head: false };
5332
+ return { memories: [], embeddedItems: [], queryEmbedding: [], vaultSize };
5324
5333
  }
5325
5334
  } else {
5326
5335
  const loaded = await getAllVaultMemoriesOp(
@@ -5335,7 +5344,7 @@ async function searchVaultMemoriesWithSize(query, vaultCtx, embeddingOptions, ca
5335
5344
  );
5336
5345
  }
5337
5346
  if (memories.length === 0) {
5338
- return { results: [], vaultSize: loaded.length, reranked: false, hadV2Head: false };
5347
+ return { memories: [], embeddedItems: [], queryEmbedding: [], vaultSize: loaded.length };
5339
5348
  }
5340
5349
  queryEmbedding = await generateEmbedding(query, embeddingOptions);
5341
5350
  const currentModel = embeddingOptions.model ?? DEFAULT_API_EMBEDDING_MODEL;
@@ -5400,6 +5409,12 @@ async function searchVaultMemoriesWithSize(query, vaultCtx, embeddingOptions, ca
5400
5409
  factType: m.factType
5401
5410
  }));
5402
5411
  }
5412
+ return { memories, embeddedItems, queryEmbedding, vaultSize };
5413
+ }
5414
+ async function rankPreparedVaultCandidates(query, prepared, embeddingOptions, searchOptions) {
5415
+ const limit = searchOptions?.limit ?? 5;
5416
+ const minSimilarity = searchOptions?.minSimilarity ?? 0.1;
5417
+ const { memories, embeddedItems, queryEmbedding, vaultSize } = prepared;
5403
5418
  if (queryEmbedding.length > 0) {
5404
5419
  const mismatched = embeddedItems.filter(
5405
5420
  (it) => it.embedding.length > 0 && it.embedding.length !== queryEmbedding.length
@@ -5537,6 +5552,25 @@ async function searchVaultMemoriesWithSize(query, vaultCtx, embeddingOptions, ca
5537
5552
  });
5538
5553
  return stampTimestamps({ results, vaultSize, hadV2Head: results.length > 0 });
5539
5554
  }
5555
+ async function searchVaultMemoriesWithSize(query, vaultCtx, embeddingOptions, cache, searchOptions) {
5556
+ if (!query || typeof query !== "string") {
5557
+ return { results: [], vaultSize: 0, reranked: false, hadV2Head: false };
5558
+ }
5559
+ const prepared = await prepareVaultCandidates(
5560
+ query,
5561
+ vaultCtx,
5562
+ embeddingOptions,
5563
+ cache,
5564
+ searchOptions
5565
+ );
5566
+ if (prepared.vaultSize === 0) {
5567
+ return { results: [], vaultSize: 0, reranked: false, hadV2Head: false };
5568
+ }
5569
+ if (prepared.memories.length === 0) {
5570
+ return { results: [], vaultSize: prepared.vaultSize, reranked: false, hadV2Head: false };
5571
+ }
5572
+ return rankPreparedVaultCandidates(query, prepared, embeddingOptions, searchOptions);
5573
+ }
5540
5574
  async function searchVaultMemories(query, vaultCtx, embeddingOptions, cache, searchOptions) {
5541
5575
  const { results } = await searchVaultMemoriesWithSize(
5542
5576
  query,
@@ -5624,7 +5658,7 @@ function createMemoryVaultSearchTool(vaultCtx, embeddingOptions, cache, searchOp
5624
5658
  legacy.map((r) => ({ id: r.uniqueId, content: r.content, score: r.similarity }))
5625
5659
  );
5626
5660
  }
5627
- const { recall: recall2 } = await import("./recall-XGRLGIEH.mjs");
5661
+ const { recall: recall2 } = await import("./recall-JA6SOQRR.mjs");
5628
5662
  const result = await recall2(
5629
5663
  query,
5630
5664
  { vaultCtx, embeddingOptions, vaultCache: cache },
@@ -6638,6 +6672,8 @@ export {
6638
6672
  recall,
6639
6673
  preEmbedVaultMemories,
6640
6674
  eagerEmbedContent,
6675
+ prepareVaultCandidates,
6676
+ rankPreparedVaultCandidates,
6641
6677
  searchVaultMemories,
6642
6678
  createMemoryVaultSearchTool
6643
6679
  };
@@ -8,7 +8,7 @@ import {
8
8
  import "./chunk-GYKJOWEO.mjs";
9
9
 
10
10
  // src/lib/memory/consolidate.ts
11
- var DEFAULT_MODEL = "inclusionai/ling-2.6-flash";
11
+ var DEFAULT_CONSOLIDATION_MODEL = "inclusionai/ling-2.6-flash";
12
12
  var DEFAULT_CONSOLIDATE_ATTEMPTS = 3;
13
13
  var DEFAULT_CONSOLIDATE_TOTAL_TIMEOUT_MS = 2e4;
14
14
  var SYSTEM_PROMPT = `You consolidate a new memory against existing memories from the same user.
@@ -70,7 +70,7 @@ ${candidateText}`;
70
70
  ...options.apiKey !== void 0 && { apiKey: options.apiKey },
71
71
  ...options.getToken !== void 0 && { getToken: options.getToken },
72
72
  ...options.baseUrl !== void 0 && { baseUrl: options.baseUrl },
73
- model: options.model ?? DEFAULT_MODEL,
73
+ model: options.model ?? DEFAULT_CONSOLIDATION_MODEL,
74
74
  systemPrompt: SYSTEM_PROMPT,
75
75
  userMessage,
76
76
  tag: "memory/consolidate",
@@ -147,5 +147,6 @@ function validate(parsed, newContent, validIds) {
147
147
  return { action: "update", targetId, content: c };
148
148
  }
149
149
  export {
150
+ DEFAULT_CONSOLIDATION_MODEL,
150
151
  consolidateMemory
151
152
  };
@@ -5568,24 +5568,25 @@ function tokenize(text12) {
5568
5568
  if (!m) return [];
5569
5569
  return m.filter((t) => !STOPWORDS.has(t));
5570
5570
  }
5571
- function scoreBM25(query, items) {
5572
- const queryTerms = tokenize(query);
5573
- if (queryTerms.length === 0 || items.length === 0) return /* @__PURE__ */ new Map();
5571
+ function prepareBM25Corpus(items) {
5572
+ const ids = items.map((i) => i.id);
5574
5573
  const docTokens = items.map((i) => tokenize(i.content));
5575
5574
  const docLens = docTokens.map((t) => t.length);
5576
- const avgdl = docLens.reduce((a, b) => a + b, 0) / docLens.length;
5577
- const queryTermSet = new Set(queryTerms);
5575
+ const avgdl = docLens.length ? docLens.reduce((a, b) => a + b, 0) / docLens.length : 0;
5578
5576
  const df = /* @__PURE__ */ new Map();
5579
5577
  for (const tokens of docTokens) {
5580
- const seen = /* @__PURE__ */ new Set();
5581
- for (const t of tokens) {
5582
- if (queryTermSet.has(t)) seen.add(t);
5583
- }
5578
+ const seen = new Set(tokens);
5584
5579
  for (const t of seen) df.set(t, (df.get(t) ?? 0) + 1);
5585
5580
  }
5586
- const N = items.length;
5581
+ return { ids, docTokens, docLens, avgdl, df, n: items.length };
5582
+ }
5583
+ function scoreBM25Prepared(query, corpus) {
5584
+ const queryTerms = tokenize(query);
5587
5585
  const scores = /* @__PURE__ */ new Map();
5588
- for (let i = 0; i < items.length; i++) {
5586
+ if (queryTerms.length === 0 || corpus.n === 0) return scores;
5587
+ const queryTermSet = new Set(queryTerms);
5588
+ const { ids, docTokens, docLens, avgdl, df, n: N } = corpus;
5589
+ for (let i = 0; i < N; i++) {
5589
5590
  const tokens = docTokens[i];
5590
5591
  const dl = docLens[i];
5591
5592
  if (dl === 0) continue;
@@ -5601,10 +5602,15 @@ function scoreBM25(query, items) {
5601
5602
  const tfNorm = f * (K1 + 1) / (f + K1 * (1 - B + B * dl / avgdl));
5602
5603
  score += idf * tfNorm;
5603
5604
  }
5604
- scores.set(items[i].id, score);
5605
+ scores.set(ids[i], score);
5605
5606
  }
5606
5607
  return scores;
5607
5608
  }
5609
+ function scoreBM25(query, items) {
5610
+ if (items.length === 0) return /* @__PURE__ */ new Map();
5611
+ if (tokenize(query).length === 0) return /* @__PURE__ */ new Map();
5612
+ return scoreBM25Prepared(query, prepareBM25Corpus(items));
5613
+ }
5608
5614
  var K1, B, TOKEN_RE, STOPWORDS;
5609
5615
  var init_bm25 = __esm({
5610
5616
  "src/lib/memoryVault/bm25.ts"() {
@@ -6925,7 +6931,7 @@ function rankFusedVaultMemories(query, queryEmbedding, items, options) {
6925
6931
  }
6926
6932
  });
6927
6933
  const baseIds = new Set(baseRanked.map((r) => r.uniqueId));
6928
- const bm25Scores = scoreBM25(
6934
+ const bm25Scores = options?.preparedBM25Corpus ? scoreBM25Prepared(query, options.preparedBM25Corpus) : scoreBM25(
6929
6935
  query,
6930
6936
  items.map((i) => ({ id: i.id, content: i.content }))
6931
6937
  );
@@ -7122,7 +7128,11 @@ async function rankComposite(originalQuery, originalQueryEmbedding, subQueries,
7122
7128
  const limit = options?.limit ?? 5;
7123
7129
  const perFacetTopN = options?.perFacetTopN ?? 10;
7124
7130
  if (items.length === 0 || subQueries.length === 0) return [];
7131
+ const preparedBM25Corpus = prepareBM25Corpus(
7132
+ items.map((i) => ({ id: i.id, content: i.content }))
7133
+ );
7125
7134
  const facetTuning = {
7135
+ preparedBM25Corpus,
7126
7136
  ...options?.recencyAlpha !== void 0 && { recencyAlpha: options.recencyAlpha },
7127
7137
  ...options?.recency && { recency: options.recency },
7128
7138
  ...options?.supersessionBoost !== void 0 && {
@@ -7432,13 +7442,12 @@ async function buildProjectedCorpus(query, vaultCtx, embeddingOptions, cache, qu
7432
7442
  }));
7433
7443
  return { memories, embeddedItems, queryEmbedding, vaultSize };
7434
7444
  }
7435
- async function searchVaultMemoriesWithSize(query, vaultCtx, embeddingOptions, cache, searchOptions) {
7436
- const limit = searchOptions?.limit ?? 5;
7437
- const minSimilarity = searchOptions?.minSimilarity ?? 0.1;
7438
- const scopes = searchOptions?.scopes;
7445
+ async function prepareVaultCandidates(query, vaultCtx, embeddingOptions, cache, searchOptions) {
7439
7446
  if (!query || typeof query !== "string") {
7440
- return { results: [], vaultSize: 0, reranked: false, hadV2Head: false };
7447
+ return { memories: [], embeddedItems: [], queryEmbedding: [], vaultSize: 0 };
7441
7448
  }
7449
+ const limit = searchOptions?.limit ?? 5;
7450
+ const scopes = searchOptions?.scopes;
7442
7451
  const folderId = searchOptions?.folderId;
7443
7452
  const queryOpts = {};
7444
7453
  if (scopes?.length) queryOpts.scopes = scopes;
@@ -7465,11 +7474,11 @@ async function searchVaultMemoriesWithSize(query, vaultCtx, embeddingOptions, ca
7465
7474
  ...forceIncludeIds.length > 0 && { forceIncludeIds }
7466
7475
  });
7467
7476
  if (corpus.vaultSize === 0) {
7468
- return { results: [], vaultSize: 0, reranked: false, hadV2Head: false };
7477
+ return { memories: [], embeddedItems: [], queryEmbedding: [], vaultSize: 0 };
7469
7478
  }
7470
7479
  ({ memories, embeddedItems, queryEmbedding, vaultSize } = corpus);
7471
7480
  if (memories.length === 0) {
7472
- return { results: [], vaultSize, reranked: false, hadV2Head: false };
7481
+ return { memories: [], embeddedItems: [], queryEmbedding: [], vaultSize };
7473
7482
  }
7474
7483
  } else {
7475
7484
  const loaded = await getAllVaultMemoriesOp(
@@ -7484,7 +7493,7 @@ async function searchVaultMemoriesWithSize(query, vaultCtx, embeddingOptions, ca
7484
7493
  );
7485
7494
  }
7486
7495
  if (memories.length === 0) {
7487
- return { results: [], vaultSize: loaded.length, reranked: false, hadV2Head: false };
7496
+ return { memories: [], embeddedItems: [], queryEmbedding: [], vaultSize: loaded.length };
7488
7497
  }
7489
7498
  queryEmbedding = await generateEmbedding(query, embeddingOptions);
7490
7499
  const currentModel = embeddingOptions.model ?? DEFAULT_API_EMBEDDING_MODEL;
@@ -7549,6 +7558,12 @@ async function searchVaultMemoriesWithSize(query, vaultCtx, embeddingOptions, ca
7549
7558
  factType: m.factType
7550
7559
  }));
7551
7560
  }
7561
+ return { memories, embeddedItems, queryEmbedding, vaultSize };
7562
+ }
7563
+ async function rankPreparedVaultCandidates(query, prepared, embeddingOptions, searchOptions) {
7564
+ const limit = searchOptions?.limit ?? 5;
7565
+ const minSimilarity = searchOptions?.minSimilarity ?? 0.1;
7566
+ const { memories, embeddedItems, queryEmbedding, vaultSize } = prepared;
7552
7567
  if (queryEmbedding.length > 0) {
7553
7568
  const mismatched = embeddedItems.filter(
7554
7569
  (it) => it.embedding.length > 0 && it.embedding.length !== queryEmbedding.length
@@ -7686,6 +7701,25 @@ async function searchVaultMemoriesWithSize(query, vaultCtx, embeddingOptions, ca
7686
7701
  });
7687
7702
  return stampTimestamps({ results, vaultSize, hadV2Head: results.length > 0 });
7688
7703
  }
7704
+ async function searchVaultMemoriesWithSize(query, vaultCtx, embeddingOptions, cache, searchOptions) {
7705
+ if (!query || typeof query !== "string") {
7706
+ return { results: [], vaultSize: 0, reranked: false, hadV2Head: false };
7707
+ }
7708
+ const prepared = await prepareVaultCandidates(
7709
+ query,
7710
+ vaultCtx,
7711
+ embeddingOptions,
7712
+ cache,
7713
+ searchOptions
7714
+ );
7715
+ if (prepared.vaultSize === 0) {
7716
+ return { results: [], vaultSize: 0, reranked: false, hadV2Head: false };
7717
+ }
7718
+ if (prepared.memories.length === 0) {
7719
+ return { results: [], vaultSize: prepared.vaultSize, reranked: false, hadV2Head: false };
7720
+ }
7721
+ return rankPreparedVaultCandidates(query, prepared, embeddingOptions, searchOptions);
7722
+ }
7689
7723
  async function searchVaultMemories(query, vaultCtx, embeddingOptions, cache, searchOptions) {
7690
7724
  const { results } = await searchVaultMemoriesWithSize(
7691
7725
  query,
@@ -7844,6 +7878,7 @@ var init_searchTool = __esm({
7844
7878
  // src/lib/memory/consolidate.ts
7845
7879
  var consolidate_exports = {};
7846
7880
  __export(consolidate_exports, {
7881
+ DEFAULT_CONSOLIDATION_MODEL: () => DEFAULT_CONSOLIDATION_MODEL,
7847
7882
  consolidateMemory: () => consolidateMemory
7848
7883
  });
7849
7884
  async function consolidateMemory(newContent, candidates, options) {
@@ -7872,7 +7907,7 @@ ${candidateText}`;
7872
7907
  ...options.apiKey !== void 0 && { apiKey: options.apiKey },
7873
7908
  ...options.getToken !== void 0 && { getToken: options.getToken },
7874
7909
  ...options.baseUrl !== void 0 && { baseUrl: options.baseUrl },
7875
- model: options.model ?? DEFAULT_MODEL3,
7910
+ model: options.model ?? DEFAULT_CONSOLIDATION_MODEL,
7876
7911
  systemPrompt: SYSTEM_PROMPT3,
7877
7912
  userMessage,
7878
7913
  tag: "memory/consolidate",
@@ -7948,14 +7983,14 @@ function validate2(parsed, newContent, validIds) {
7948
7983
  if (!targetId || !validIds.has(targetId)) return null;
7949
7984
  return { action: "update", targetId, content: c };
7950
7985
  }
7951
- var DEFAULT_MODEL3, DEFAULT_CONSOLIDATE_ATTEMPTS, DEFAULT_CONSOLIDATE_TOTAL_TIMEOUT_MS, SYSTEM_PROMPT3;
7986
+ var DEFAULT_CONSOLIDATION_MODEL, DEFAULT_CONSOLIDATE_ATTEMPTS, DEFAULT_CONSOLIDATE_TOTAL_TIMEOUT_MS, SYSTEM_PROMPT3;
7952
7987
  var init_consolidate = __esm({
7953
7988
  "src/lib/memory/consolidate.ts"() {
7954
7989
  "use strict";
7955
7990
  init_logger();
7956
7991
  init_redactor();
7957
7992
  init_portalLlm();
7958
- DEFAULT_MODEL3 = "inclusionai/ling-2.6-flash";
7993
+ DEFAULT_CONSOLIDATION_MODEL = "inclusionai/ling-2.6-flash";
7959
7994
  DEFAULT_CONSOLIDATE_ATTEMPTS = 3;
7960
7995
  DEFAULT_CONSOLIDATE_TOTAL_TIMEOUT_MS = 2e4;
7961
7996
  SYSTEM_PROMPT3 = `You consolidate a new memory against existing memories from the same user.
@@ -14483,9 +14518,25 @@ async function retain(content, ctx, options = {}) {
14483
14518
  const resolvedScope = options.scope ?? DEFAULT_SCOPE;
14484
14519
  let supersedeTargetIds = [];
14485
14520
  let supersedeContent;
14521
+ let prepared;
14486
14522
  if (enableAutoMerge) {
14523
+ prepared = await prepareVaultCandidates(
14524
+ trimmed,
14525
+ ctx.vaultCtx,
14526
+ ctx.embeddingOptions,
14527
+ ctx.vaultCache,
14528
+ {
14529
+ limit: Math.max(options.consolidateTopK ?? DEFAULT_CONSOLIDATE_TOP_K, 1),
14530
+ useFusion: false,
14531
+ scopes: [resolvedScope],
14532
+ // PR5 — include archived rows as merge candidates so a re-observed fact
14533
+ // resurrects (un-archives) the decayed row instead of duplicating it.
14534
+ includeArchived: true,
14535
+ ...options.folderId !== void 0 && { folderId: options.folderId }
14536
+ }
14537
+ );
14487
14538
  if (options.consolidateOptions) {
14488
- const outcome = await tryConsolidate(trimmed, ctx, options);
14539
+ const outcome = await tryConsolidate(trimmed, ctx, options, prepared);
14489
14540
  if (outcome) {
14490
14541
  if ("done" in outcome) return outcome.done;
14491
14542
  supersedeTargetIds = outcome.supersede;
@@ -14493,23 +14544,14 @@ async function retain(content, ctx, options = {}) {
14493
14544
  }
14494
14545
  }
14495
14546
  if (supersedeTargetIds.length === 0) {
14496
- const matches = await searchVaultMemories(
14547
+ const { results: matches } = await rankPreparedVaultCandidates(
14497
14548
  trimmed,
14498
- ctx.vaultCtx,
14549
+ prepared,
14499
14550
  ctx.embeddingOptions,
14500
- ctx.vaultCache,
14501
14551
  {
14502
14552
  limit: 1,
14503
14553
  minSimilarity: threshold,
14504
- useFusion: false,
14505
- scopes: [resolvedScope],
14506
- // PR5 — include archived rows as merge candidates so a re-observed
14507
- // fact resurrects (un-archives) the decayed row instead of creating a
14508
- // fresh duplicate. The resurrection is applied on the merge write
14509
- // below, but ONLY for a row that is not superseded/deleted (the
14510
- // guards below preserve main's tombstone/supersession suppression).
14511
- includeArchived: true,
14512
- ...options.folderId !== void 0 && { folderId: options.folderId }
14554
+ useFusion: false
14513
14555
  }
14514
14556
  );
14515
14557
  if (matches.length > 0) {
@@ -14557,7 +14599,8 @@ async function retain(content, ctx, options = {}) {
14557
14599
  }
14558
14600
  }
14559
14601
  const contentToWrite = supersedeContent ?? trimmed;
14560
- const embedding = await generateEmbedding(contentToWrite, ctx.embeddingOptions);
14602
+ const reusableQueryEmbedding = supersedeContent === void 0 && prepared && prepared.queryEmbedding.length > 0 ? prepared.queryEmbedding : void 0;
14603
+ const embedding = reusableQueryEmbedding ?? await generateEmbedding(contentToWrite, ctx.embeddingOptions);
14561
14604
  const embeddingModel = ctx.embeddingOptions.model ?? DEFAULT_API_EMBEDDING_MODEL;
14562
14605
  if (options.respectTombstones) {
14563
14606
  const tombstoneId = await findTombstoneMatch(embedding, embeddingModel, resolvedScope, ctx, {
@@ -14686,26 +14729,19 @@ function pickFactTypeUpdate(existing, incoming) {
14686
14729
  function resurrectFields(existing) {
14687
14730
  return typeof existing.archivedAt === "number" ? { restore: true } : { preserveUpdatedAt: true };
14688
14731
  }
14689
- async function tryConsolidate(trimmed, ctx, options) {
14732
+ async function tryConsolidate(trimmed, ctx, options, prepared) {
14690
14733
  const consolidateOptions = options.consolidateOptions;
14691
14734
  if (!consolidateOptions) return null;
14692
14735
  const consolidateThreshold = options.consolidateThreshold ?? DEFAULT_CONSOLIDATE_THRESHOLD;
14693
14736
  const topK = options.consolidateTopK ?? DEFAULT_CONSOLIDATE_TOP_K;
14694
- const resolvedScope = options.scope ?? DEFAULT_SCOPE;
14695
- const matches = await searchVaultMemories(
14737
+ const { results: matches } = await rankPreparedVaultCandidates(
14696
14738
  trimmed,
14697
- ctx.vaultCtx,
14739
+ prepared,
14698
14740
  ctx.embeddingOptions,
14699
- ctx.vaultCache,
14700
14741
  {
14701
14742
  limit: topK,
14702
14743
  minSimilarity: consolidateThreshold,
14703
- useFusion: false,
14704
- scopes: [resolvedScope],
14705
- // PR5 — archived rows are consolidation candidates too, so a paraphrased
14706
- // re-observation resurrects a decayed row rather than duplicating it.
14707
- includeArchived: true,
14708
- ...options.folderId !== void 0 && { folderId: options.folderId }
14744
+ useFusion: false
14709
14745
  }
14710
14746
  );
14711
14747
  if (matches.length === 0) return null;
@@ -15488,7 +15524,7 @@ function classifyDecay(m, now, policy) {
15488
15524
  init_logger();
15489
15525
  init_redactor();
15490
15526
  init_portalLlm();
15491
- var DEFAULT_MODEL4 = "inclusionai/ling-2.6-flash";
15527
+ var DEFAULT_MODEL3 = "inclusionai/ling-2.6-flash";
15492
15528
  var DEFAULT_ATTEMPTS2 = 2;
15493
15529
  var DEFAULT_TOTAL_TIMEOUT_MS2 = 12e3;
15494
15530
  var MAX_CONTENT_CHARS = 400;
@@ -15527,7 +15563,7 @@ function createLlmDecayClassifier(options) {
15527
15563
  ...options.apiKey !== void 0 && { apiKey: options.apiKey },
15528
15564
  ...options.getToken !== void 0 && { getToken: options.getToken },
15529
15565
  ...options.baseUrl !== void 0 && { baseUrl: options.baseUrl },
15530
- model: options.model ?? DEFAULT_MODEL4,
15566
+ model: options.model ?? DEFAULT_MODEL3,
15531
15567
  systemPrompt: SYSTEM_PROMPT5,
15532
15568
  userMessage: `Memory content:
15533
15569
  ${safe}
@@ -15960,7 +15996,7 @@ init_logger();
15960
15996
  init_portalLlm();
15961
15997
  init_recall();
15962
15998
  var DEFAULT_BASE_URL2 = BASE_URL;
15963
- var DEFAULT_MODEL5 = "anthropic/claude-sonnet-4-6";
15999
+ var DEFAULT_MODEL4 = "anthropic/claude-sonnet-4-6";
15964
16000
  var DEFAULT_MAX_TOKENS = 4096;
15965
16001
  var REQUEST_TIMEOUT_MS = 6e4;
15966
16002
  var DEFAULT_SYSTEM_PROMPT = `You are a personal assistant with access to the user's memory. Answer the user's question using the supplied memories as evidence.
@@ -15992,7 +16028,7 @@ async function reflect(query, ctx, options) {
15992
16028
  const evidence = recalledMemories.map((m, i) => `[${i + 1}] (id: ${m.id}, kind: ${m.kind})
15993
16029
  ${m.content}`).join("\n\n");
15994
16030
  const baseUrl = options.baseUrl ?? DEFAULT_BASE_URL2;
15995
- const model = options.llmModel ?? DEFAULT_MODEL5;
16031
+ const model = options.llmModel ?? DEFAULT_MODEL4;
15996
16032
  const wantsStructured = !!options.responseSchema;
15997
16033
  const sendResponseFormat = wantsStructured && supportsResponseFormat(model, "json_schema");
15998
16034
  const basePrompt = options.systemPrompt ?? DEFAULT_SYSTEM_PROMPT;
@@ -85,6 +85,8 @@ import {
85
85
  onKeyAvailable,
86
86
  postApiV1CreditsPurchase,
87
87
  preEmbedVaultMemories,
88
+ prepareVaultCandidates,
89
+ rankPreparedVaultCandidates,
88
90
  recall,
89
91
  replaceMemoryEntitiesGuardedOp,
90
92
  requestEncryptionKey,
@@ -108,7 +110,7 @@ import {
108
110
  upsertMessageOp,
109
111
  useEncryption,
110
112
  vaultMemoryToStored
111
- } from "./chunk-4VXLX7SL.mjs";
113
+ } from "./chunk-FFB4CDPC.mjs";
112
114
  import {
113
115
  PII_PATTERNS,
114
116
  PiiRedactor,
@@ -6364,9 +6366,25 @@ async function retain(content, ctx, options = {}) {
6364
6366
  const resolvedScope = options.scope ?? DEFAULT_SCOPE;
6365
6367
  let supersedeTargetIds = [];
6366
6368
  let supersedeContent;
6369
+ let prepared;
6367
6370
  if (enableAutoMerge) {
6371
+ prepared = await prepareVaultCandidates(
6372
+ trimmed,
6373
+ ctx.vaultCtx,
6374
+ ctx.embeddingOptions,
6375
+ ctx.vaultCache,
6376
+ {
6377
+ limit: Math.max(options.consolidateTopK ?? DEFAULT_CONSOLIDATE_TOP_K, 1),
6378
+ useFusion: false,
6379
+ scopes: [resolvedScope],
6380
+ // PR5 — include archived rows as merge candidates so a re-observed fact
6381
+ // resurrects (un-archives) the decayed row instead of duplicating it.
6382
+ includeArchived: true,
6383
+ ...options.folderId !== void 0 && { folderId: options.folderId }
6384
+ }
6385
+ );
6368
6386
  if (options.consolidateOptions) {
6369
- const outcome = await tryConsolidate(trimmed, ctx, options);
6387
+ const outcome = await tryConsolidate(trimmed, ctx, options, prepared);
6370
6388
  if (outcome) {
6371
6389
  if ("done" in outcome) return outcome.done;
6372
6390
  supersedeTargetIds = outcome.supersede;
@@ -6374,23 +6392,14 @@ async function retain(content, ctx, options = {}) {
6374
6392
  }
6375
6393
  }
6376
6394
  if (supersedeTargetIds.length === 0) {
6377
- const matches = await searchVaultMemories(
6395
+ const { results: matches } = await rankPreparedVaultCandidates(
6378
6396
  trimmed,
6379
- ctx.vaultCtx,
6397
+ prepared,
6380
6398
  ctx.embeddingOptions,
6381
- ctx.vaultCache,
6382
6399
  {
6383
6400
  limit: 1,
6384
6401
  minSimilarity: threshold,
6385
- useFusion: false,
6386
- scopes: [resolvedScope],
6387
- // PR5 — include archived rows as merge candidates so a re-observed
6388
- // fact resurrects (un-archives) the decayed row instead of creating a
6389
- // fresh duplicate. The resurrection is applied on the merge write
6390
- // below, but ONLY for a row that is not superseded/deleted (the
6391
- // guards below preserve main's tombstone/supersession suppression).
6392
- includeArchived: true,
6393
- ...options.folderId !== void 0 && { folderId: options.folderId }
6402
+ useFusion: false
6394
6403
  }
6395
6404
  );
6396
6405
  if (matches.length > 0) {
@@ -6438,7 +6447,8 @@ async function retain(content, ctx, options = {}) {
6438
6447
  }
6439
6448
  }
6440
6449
  const contentToWrite = supersedeContent ?? trimmed;
6441
- const embedding = await generateEmbedding(contentToWrite, ctx.embeddingOptions);
6450
+ const reusableQueryEmbedding = supersedeContent === void 0 && prepared && prepared.queryEmbedding.length > 0 ? prepared.queryEmbedding : void 0;
6451
+ const embedding = reusableQueryEmbedding ?? await generateEmbedding(contentToWrite, ctx.embeddingOptions);
6442
6452
  const embeddingModel = ctx.embeddingOptions.model ?? DEFAULT_API_EMBEDDING_MODEL;
6443
6453
  if (options.respectTombstones) {
6444
6454
  const tombstoneId = await findTombstoneMatch(embedding, embeddingModel, resolvedScope, ctx, {
@@ -6567,26 +6577,19 @@ function pickFactTypeUpdate(existing, incoming) {
6567
6577
  function resurrectFields(existing) {
6568
6578
  return typeof existing.archivedAt === "number" ? { restore: true } : { preserveUpdatedAt: true };
6569
6579
  }
6570
- async function tryConsolidate(trimmed, ctx, options) {
6580
+ async function tryConsolidate(trimmed, ctx, options, prepared) {
6571
6581
  const consolidateOptions = options.consolidateOptions;
6572
6582
  if (!consolidateOptions) return null;
6573
6583
  const consolidateThreshold = options.consolidateThreshold ?? DEFAULT_CONSOLIDATE_THRESHOLD;
6574
6584
  const topK = options.consolidateTopK ?? DEFAULT_CONSOLIDATE_TOP_K;
6575
- const resolvedScope = options.scope ?? DEFAULT_SCOPE;
6576
- const matches = await searchVaultMemories(
6585
+ const { results: matches } = await rankPreparedVaultCandidates(
6577
6586
  trimmed,
6578
- ctx.vaultCtx,
6587
+ prepared,
6579
6588
  ctx.embeddingOptions,
6580
- ctx.vaultCache,
6581
6589
  {
6582
6590
  limit: topK,
6583
6591
  minSimilarity: consolidateThreshold,
6584
- useFusion: false,
6585
- scopes: [resolvedScope],
6586
- // PR5 — archived rows are consolidation candidates too, so a paraphrased
6587
- // re-observation resurrects a decayed row rather than duplicating it.
6588
- includeArchived: true,
6589
- ...options.folderId !== void 0 && { folderId: options.folderId }
6592
+ useFusion: false
6590
6593
  }
6591
6594
  );
6592
6595
  if (matches.length === 0) return null;
@@ -6595,7 +6598,7 @@ async function tryConsolidate(trimmed, ctx, options) {
6595
6598
  content: m.content,
6596
6599
  similarity: m.similarity
6597
6600
  }));
6598
- const { consolidateMemory: doConsolidate } = await import("./consolidate-HKN32P5W.mjs");
6601
+ const { consolidateMemory: doConsolidate } = await import("./consolidate-NC5DOC5J.mjs");
6599
6602
  const decision = await doConsolidate(trimmed, candidates, consolidateOptions);
6600
6603
  if (decision.action === "create") return null;
6601
6604
  if (decision.action === "supersede" && decision.content) {
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  recall
3
- } from "./chunk-P5ED24DP.mjs";
3
+ } from "./chunk-FFB4CDPC.mjs";
4
4
  import "./chunk-BOY27A2C.mjs";
5
5
  import "./chunk-GYKJOWEO.mjs";
6
6
  export {