@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.
@@ -18676,24 +18676,25 @@ function tokenize(text) {
18676
18676
  if (!m) return [];
18677
18677
  return m.filter((t) => !STOPWORDS.has(t));
18678
18678
  }
18679
- function scoreBM25(query, items) {
18680
- const queryTerms = tokenize(query);
18681
- if (queryTerms.length === 0 || items.length === 0) return /* @__PURE__ */ new Map();
18679
+ function prepareBM25Corpus(items) {
18680
+ const ids = items.map((i) => i.id);
18682
18681
  const docTokens = items.map((i) => tokenize(i.content));
18683
18682
  const docLens = docTokens.map((t) => t.length);
18684
- const avgdl = docLens.reduce((a, b) => a + b, 0) / docLens.length;
18685
- const queryTermSet = new Set(queryTerms);
18683
+ const avgdl = docLens.length ? docLens.reduce((a, b) => a + b, 0) / docLens.length : 0;
18686
18684
  const df = /* @__PURE__ */ new Map();
18687
18685
  for (const tokens of docTokens) {
18688
- const seen = /* @__PURE__ */ new Set();
18689
- for (const t of tokens) {
18690
- if (queryTermSet.has(t)) seen.add(t);
18691
- }
18686
+ const seen = new Set(tokens);
18692
18687
  for (const t of seen) df.set(t, (df.get(t) ?? 0) + 1);
18693
18688
  }
18694
- const N = items.length;
18689
+ return { ids, docTokens, docLens, avgdl, df, n: items.length };
18690
+ }
18691
+ function scoreBM25Prepared(query, corpus) {
18692
+ const queryTerms = tokenize(query);
18695
18693
  const scores = /* @__PURE__ */ new Map();
18696
- for (let i = 0; i < items.length; i++) {
18694
+ if (queryTerms.length === 0 || corpus.n === 0) return scores;
18695
+ const queryTermSet = new Set(queryTerms);
18696
+ const { ids, docTokens, docLens, avgdl, df, n: N } = corpus;
18697
+ for (let i = 0; i < N; i++) {
18697
18698
  const tokens = docTokens[i];
18698
18699
  const dl = docLens[i];
18699
18700
  if (dl === 0) continue;
@@ -18709,10 +18710,15 @@ function scoreBM25(query, items) {
18709
18710
  const tfNorm = f * (K1 + 1) / (f + K1 * (1 - B + B * dl / avgdl));
18710
18711
  score += idf * tfNorm;
18711
18712
  }
18712
- scores.set(items[i].id, score);
18713
+ scores.set(ids[i], score);
18713
18714
  }
18714
18715
  return scores;
18715
18716
  }
18717
+ function scoreBM25(query, items) {
18718
+ if (items.length === 0) return /* @__PURE__ */ new Map();
18719
+ if (tokenize(query).length === 0) return /* @__PURE__ */ new Map();
18720
+ return scoreBM25Prepared(query, prepareBM25Corpus(items));
18721
+ }
18716
18722
 
18717
18723
  // src/lib/memoryVault/decomposeQuery.ts
18718
18724
  var DEFAULT_MODEL = "inclusionai/ling-2.6-flash";
@@ -18967,7 +18973,7 @@ function rankFusedVaultMemories(query, queryEmbedding, items, options) {
18967
18973
  }
18968
18974
  });
18969
18975
  const baseIds = new Set(baseRanked.map((r) => r.uniqueId));
18970
- const bm25Scores = scoreBM25(
18976
+ const bm25Scores = options?.preparedBM25Corpus ? scoreBM25Prepared(query, options.preparedBM25Corpus) : scoreBM25(
18971
18977
  query,
18972
18978
  items.map((i) => ({ id: i.id, content: i.content }))
18973
18979
  );
@@ -19164,7 +19170,11 @@ async function rankComposite(originalQuery, originalQueryEmbedding, subQueries,
19164
19170
  const limit = options?.limit ?? 5;
19165
19171
  const perFacetTopN = options?.perFacetTopN ?? 10;
19166
19172
  if (items.length === 0 || subQueries.length === 0) return [];
19173
+ const preparedBM25Corpus = prepareBM25Corpus(
19174
+ items.map((i) => ({ id: i.id, content: i.content }))
19175
+ );
19167
19176
  const facetTuning = {
19177
+ preparedBM25Corpus,
19168
19178
  ...options?.recencyAlpha !== void 0 && { recencyAlpha: options.recencyAlpha },
19169
19179
  ...options?.recency && { recency: options.recency },
19170
19180
  ...options?.supersessionBoost !== void 0 && {
@@ -19474,13 +19484,12 @@ async function buildProjectedCorpus(query, vaultCtx, embeddingOptions, cache, qu
19474
19484
  }));
19475
19485
  return { memories, embeddedItems, queryEmbedding, vaultSize };
19476
19486
  }
19477
- async function searchVaultMemoriesWithSize(query, vaultCtx, embeddingOptions, cache, searchOptions) {
19478
- const limit = searchOptions?.limit ?? 5;
19479
- const minSimilarity = searchOptions?.minSimilarity ?? 0.1;
19480
- const scopes = searchOptions?.scopes;
19487
+ async function prepareVaultCandidates(query, vaultCtx, embeddingOptions, cache, searchOptions) {
19481
19488
  if (!query || typeof query !== "string") {
19482
- return { results: [], vaultSize: 0, reranked: false, hadV2Head: false };
19489
+ return { memories: [], embeddedItems: [], queryEmbedding: [], vaultSize: 0 };
19483
19490
  }
19491
+ const limit = searchOptions?.limit ?? 5;
19492
+ const scopes = searchOptions?.scopes;
19484
19493
  const folderId = searchOptions?.folderId;
19485
19494
  const queryOpts = {};
19486
19495
  if (scopes?.length) queryOpts.scopes = scopes;
@@ -19507,11 +19516,11 @@ async function searchVaultMemoriesWithSize(query, vaultCtx, embeddingOptions, ca
19507
19516
  ...forceIncludeIds.length > 0 && { forceIncludeIds }
19508
19517
  });
19509
19518
  if (corpus.vaultSize === 0) {
19510
- return { results: [], vaultSize: 0, reranked: false, hadV2Head: false };
19519
+ return { memories: [], embeddedItems: [], queryEmbedding: [], vaultSize: 0 };
19511
19520
  }
19512
19521
  ({ memories, embeddedItems, queryEmbedding, vaultSize } = corpus);
19513
19522
  if (memories.length === 0) {
19514
- return { results: [], vaultSize, reranked: false, hadV2Head: false };
19523
+ return { memories: [], embeddedItems: [], queryEmbedding: [], vaultSize };
19515
19524
  }
19516
19525
  } else {
19517
19526
  const loaded = await getAllVaultMemoriesOp(
@@ -19526,7 +19535,7 @@ async function searchVaultMemoriesWithSize(query, vaultCtx, embeddingOptions, ca
19526
19535
  );
19527
19536
  }
19528
19537
  if (memories.length === 0) {
19529
- return { results: [], vaultSize: loaded.length, reranked: false, hadV2Head: false };
19538
+ return { memories: [], embeddedItems: [], queryEmbedding: [], vaultSize: loaded.length };
19530
19539
  }
19531
19540
  queryEmbedding = await generateEmbedding(query, embeddingOptions);
19532
19541
  const currentModel = embeddingOptions.model ?? DEFAULT_API_EMBEDDING_MODEL;
@@ -19591,6 +19600,12 @@ async function searchVaultMemoriesWithSize(query, vaultCtx, embeddingOptions, ca
19591
19600
  factType: m.factType
19592
19601
  }));
19593
19602
  }
19603
+ return { memories, embeddedItems, queryEmbedding, vaultSize };
19604
+ }
19605
+ async function rankPreparedVaultCandidates(query, prepared, embeddingOptions, searchOptions) {
19606
+ const limit = searchOptions?.limit ?? 5;
19607
+ const minSimilarity = searchOptions?.minSimilarity ?? 0.1;
19608
+ const { memories, embeddedItems, queryEmbedding, vaultSize } = prepared;
19594
19609
  if (queryEmbedding.length > 0) {
19595
19610
  const mismatched = embeddedItems.filter(
19596
19611
  (it) => it.embedding.length > 0 && it.embedding.length !== queryEmbedding.length
@@ -19728,6 +19743,25 @@ async function searchVaultMemoriesWithSize(query, vaultCtx, embeddingOptions, ca
19728
19743
  });
19729
19744
  return stampTimestamps({ results, vaultSize, hadV2Head: results.length > 0 });
19730
19745
  }
19746
+ async function searchVaultMemoriesWithSize(query, vaultCtx, embeddingOptions, cache, searchOptions) {
19747
+ if (!query || typeof query !== "string") {
19748
+ return { results: [], vaultSize: 0, reranked: false, hadV2Head: false };
19749
+ }
19750
+ const prepared = await prepareVaultCandidates(
19751
+ query,
19752
+ vaultCtx,
19753
+ embeddingOptions,
19754
+ cache,
19755
+ searchOptions
19756
+ );
19757
+ if (prepared.vaultSize === 0) {
19758
+ return { results: [], vaultSize: 0, reranked: false, hadV2Head: false };
19759
+ }
19760
+ if (prepared.memories.length === 0) {
19761
+ return { results: [], vaultSize: prepared.vaultSize, reranked: false, hadV2Head: false };
19762
+ }
19763
+ return rankPreparedVaultCandidates(query, prepared, embeddingOptions, searchOptions);
19764
+ }
19731
19765
  async function searchVaultMemories(query, vaultCtx, embeddingOptions, cache, searchOptions) {
19732
19766
  const { results } = await searchVaultMemoriesWithSize(
19733
19767
  query,
@@ -19815,7 +19849,7 @@ function createMemoryVaultSearchTool(vaultCtx, embeddingOptions, cache, searchOp
19815
19849
  legacy.map((r) => ({ id: r.uniqueId, content: r.content, score: r.similarity }))
19816
19850
  );
19817
19851
  }
19818
- const { recall: recall2 } = await import("./recall-23VTTAEG.mjs");
19852
+ const { recall: recall2 } = await import("./recall-VZO4USXK.mjs");
19819
19853
  const result = await recall2(
19820
19854
  query,
19821
19855
  { vaultCtx, embeddingOptions, vaultCache: cache },
@@ -20846,6 +20880,8 @@ export {
20846
20880
  recall,
20847
20881
  preEmbedVaultMemories,
20848
20882
  eagerEmbedContent,
20883
+ prepareVaultCandidates,
20884
+ rankPreparedVaultCandidates,
20849
20885
  searchVaultMemories,
20850
20886
  createMemoryVaultSearchTool
20851
20887
  };
@@ -8,7 +8,7 @@ import {
8
8
  import "./chunk-3RPGXXPZ.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
  };
@@ -19494,24 +19494,25 @@ function tokenize(text12) {
19494
19494
  if (!m) return [];
19495
19495
  return m.filter((t) => !STOPWORDS.has(t));
19496
19496
  }
19497
- function scoreBM25(query, items) {
19498
- const queryTerms = tokenize(query);
19499
- if (queryTerms.length === 0 || items.length === 0) return /* @__PURE__ */ new Map();
19497
+ function prepareBM25Corpus(items) {
19498
+ const ids = items.map((i) => i.id);
19500
19499
  const docTokens = items.map((i) => tokenize(i.content));
19501
19500
  const docLens = docTokens.map((t) => t.length);
19502
- const avgdl = docLens.reduce((a, b) => a + b, 0) / docLens.length;
19503
- const queryTermSet = new Set(queryTerms);
19501
+ const avgdl = docLens.length ? docLens.reduce((a, b) => a + b, 0) / docLens.length : 0;
19504
19502
  const df = /* @__PURE__ */ new Map();
19505
19503
  for (const tokens of docTokens) {
19506
- const seen = /* @__PURE__ */ new Set();
19507
- for (const t of tokens) {
19508
- if (queryTermSet.has(t)) seen.add(t);
19509
- }
19504
+ const seen = new Set(tokens);
19510
19505
  for (const t of seen) df.set(t, (df.get(t) ?? 0) + 1);
19511
19506
  }
19512
- const N = items.length;
19507
+ return { ids, docTokens, docLens, avgdl, df, n: items.length };
19508
+ }
19509
+ function scoreBM25Prepared(query, corpus) {
19510
+ const queryTerms = tokenize(query);
19513
19511
  const scores = /* @__PURE__ */ new Map();
19514
- for (let i = 0; i < items.length; i++) {
19512
+ if (queryTerms.length === 0 || corpus.n === 0) return scores;
19513
+ const queryTermSet = new Set(queryTerms);
19514
+ const { ids, docTokens, docLens, avgdl, df, n: N } = corpus;
19515
+ for (let i = 0; i < N; i++) {
19515
19516
  const tokens = docTokens[i];
19516
19517
  const dl = docLens[i];
19517
19518
  if (dl === 0) continue;
@@ -19527,10 +19528,15 @@ function scoreBM25(query, items) {
19527
19528
  const tfNorm = f * (K1 + 1) / (f + K1 * (1 - B + B * dl / avgdl));
19528
19529
  score += idf * tfNorm;
19529
19530
  }
19530
- scores.set(items[i].id, score);
19531
+ scores.set(ids[i], score);
19531
19532
  }
19532
19533
  return scores;
19533
19534
  }
19535
+ function scoreBM25(query, items) {
19536
+ if (items.length === 0) return /* @__PURE__ */ new Map();
19537
+ if (tokenize(query).length === 0) return /* @__PURE__ */ new Map();
19538
+ return scoreBM25Prepared(query, prepareBM25Corpus(items));
19539
+ }
19534
19540
  var K1, B, TOKEN_RE, STOPWORDS;
19535
19541
  var init_bm25 = __esm({
19536
19542
  "src/lib/memoryVault/bm25.ts"() {
@@ -21098,7 +21104,7 @@ function rankFusedVaultMemories(query, queryEmbedding, items, options) {
21098
21104
  }
21099
21105
  });
21100
21106
  const baseIds = new Set(baseRanked.map((r) => r.uniqueId));
21101
- const bm25Scores = scoreBM25(
21107
+ const bm25Scores = options?.preparedBM25Corpus ? scoreBM25Prepared(query, options.preparedBM25Corpus) : scoreBM25(
21102
21108
  query,
21103
21109
  items.map((i) => ({ id: i.id, content: i.content }))
21104
21110
  );
@@ -21295,7 +21301,11 @@ async function rankComposite(originalQuery, originalQueryEmbedding, subQueries,
21295
21301
  const limit = options?.limit ?? 5;
21296
21302
  const perFacetTopN = options?.perFacetTopN ?? 10;
21297
21303
  if (items.length === 0 || subQueries.length === 0) return [];
21304
+ const preparedBM25Corpus = prepareBM25Corpus(
21305
+ items.map((i) => ({ id: i.id, content: i.content }))
21306
+ );
21298
21307
  const facetTuning = {
21308
+ preparedBM25Corpus,
21299
21309
  ...options?.recencyAlpha !== void 0 && { recencyAlpha: options.recencyAlpha },
21300
21310
  ...options?.recency && { recency: options.recency },
21301
21311
  ...options?.supersessionBoost !== void 0 && {
@@ -21605,13 +21615,12 @@ async function buildProjectedCorpus(query, vaultCtx, embeddingOptions, cache, qu
21605
21615
  }));
21606
21616
  return { memories, embeddedItems, queryEmbedding, vaultSize };
21607
21617
  }
21608
- async function searchVaultMemoriesWithSize(query, vaultCtx, embeddingOptions, cache, searchOptions) {
21609
- const limit = searchOptions?.limit ?? 5;
21610
- const minSimilarity = searchOptions?.minSimilarity ?? 0.1;
21611
- const scopes = searchOptions?.scopes;
21618
+ async function prepareVaultCandidates(query, vaultCtx, embeddingOptions, cache, searchOptions) {
21612
21619
  if (!query || typeof query !== "string") {
21613
- return { results: [], vaultSize: 0, reranked: false, hadV2Head: false };
21620
+ return { memories: [], embeddedItems: [], queryEmbedding: [], vaultSize: 0 };
21614
21621
  }
21622
+ const limit = searchOptions?.limit ?? 5;
21623
+ const scopes = searchOptions?.scopes;
21615
21624
  const folderId = searchOptions?.folderId;
21616
21625
  const queryOpts = {};
21617
21626
  if (scopes?.length) queryOpts.scopes = scopes;
@@ -21638,11 +21647,11 @@ async function searchVaultMemoriesWithSize(query, vaultCtx, embeddingOptions, ca
21638
21647
  ...forceIncludeIds.length > 0 && { forceIncludeIds }
21639
21648
  });
21640
21649
  if (corpus.vaultSize === 0) {
21641
- return { results: [], vaultSize: 0, reranked: false, hadV2Head: false };
21650
+ return { memories: [], embeddedItems: [], queryEmbedding: [], vaultSize: 0 };
21642
21651
  }
21643
21652
  ({ memories, embeddedItems, queryEmbedding, vaultSize } = corpus);
21644
21653
  if (memories.length === 0) {
21645
- return { results: [], vaultSize, reranked: false, hadV2Head: false };
21654
+ return { memories: [], embeddedItems: [], queryEmbedding: [], vaultSize };
21646
21655
  }
21647
21656
  } else {
21648
21657
  const loaded = await getAllVaultMemoriesOp(
@@ -21657,7 +21666,7 @@ async function searchVaultMemoriesWithSize(query, vaultCtx, embeddingOptions, ca
21657
21666
  );
21658
21667
  }
21659
21668
  if (memories.length === 0) {
21660
- return { results: [], vaultSize: loaded.length, reranked: false, hadV2Head: false };
21669
+ return { memories: [], embeddedItems: [], queryEmbedding: [], vaultSize: loaded.length };
21661
21670
  }
21662
21671
  queryEmbedding = await generateEmbedding(query, embeddingOptions);
21663
21672
  const currentModel = embeddingOptions.model ?? DEFAULT_API_EMBEDDING_MODEL;
@@ -21722,6 +21731,12 @@ async function searchVaultMemoriesWithSize(query, vaultCtx, embeddingOptions, ca
21722
21731
  factType: m.factType
21723
21732
  }));
21724
21733
  }
21734
+ return { memories, embeddedItems, queryEmbedding, vaultSize };
21735
+ }
21736
+ async function rankPreparedVaultCandidates(query, prepared, embeddingOptions, searchOptions) {
21737
+ const limit = searchOptions?.limit ?? 5;
21738
+ const minSimilarity = searchOptions?.minSimilarity ?? 0.1;
21739
+ const { memories, embeddedItems, queryEmbedding, vaultSize } = prepared;
21725
21740
  if (queryEmbedding.length > 0) {
21726
21741
  const mismatched = embeddedItems.filter(
21727
21742
  (it) => it.embedding.length > 0 && it.embedding.length !== queryEmbedding.length
@@ -21859,6 +21874,25 @@ async function searchVaultMemoriesWithSize(query, vaultCtx, embeddingOptions, ca
21859
21874
  });
21860
21875
  return stampTimestamps({ results, vaultSize, hadV2Head: results.length > 0 });
21861
21876
  }
21877
+ async function searchVaultMemoriesWithSize(query, vaultCtx, embeddingOptions, cache, searchOptions) {
21878
+ if (!query || typeof query !== "string") {
21879
+ return { results: [], vaultSize: 0, reranked: false, hadV2Head: false };
21880
+ }
21881
+ const prepared = await prepareVaultCandidates(
21882
+ query,
21883
+ vaultCtx,
21884
+ embeddingOptions,
21885
+ cache,
21886
+ searchOptions
21887
+ );
21888
+ if (prepared.vaultSize === 0) {
21889
+ return { results: [], vaultSize: 0, reranked: false, hadV2Head: false };
21890
+ }
21891
+ if (prepared.memories.length === 0) {
21892
+ return { results: [], vaultSize: prepared.vaultSize, reranked: false, hadV2Head: false };
21893
+ }
21894
+ return rankPreparedVaultCandidates(query, prepared, embeddingOptions, searchOptions);
21895
+ }
21862
21896
  async function searchVaultMemories(query, vaultCtx, embeddingOptions, cache, searchOptions) {
21863
21897
  const { results } = await searchVaultMemoriesWithSize(
21864
21898
  query,
@@ -22669,6 +22703,7 @@ var init_redactor = __esm({
22669
22703
  // src/lib/memory/consolidate.ts
22670
22704
  var consolidate_exports = {};
22671
22705
  __export(consolidate_exports, {
22706
+ DEFAULT_CONSOLIDATION_MODEL: () => DEFAULT_CONSOLIDATION_MODEL,
22672
22707
  consolidateMemory: () => consolidateMemory
22673
22708
  });
22674
22709
  async function consolidateMemory(newContent, candidates, options) {
@@ -22697,7 +22732,7 @@ ${candidateText}`;
22697
22732
  ...options.apiKey !== void 0 && { apiKey: options.apiKey },
22698
22733
  ...options.getToken !== void 0 && { getToken: options.getToken },
22699
22734
  ...options.baseUrl !== void 0 && { baseUrl: options.baseUrl },
22700
- model: options.model ?? DEFAULT_MODEL3,
22735
+ model: options.model ?? DEFAULT_CONSOLIDATION_MODEL,
22701
22736
  systemPrompt: SYSTEM_PROMPT3,
22702
22737
  userMessage,
22703
22738
  tag: "memory/consolidate",
@@ -22773,14 +22808,14 @@ function validate2(parsed, newContent, validIds) {
22773
22808
  if (!targetId || !validIds.has(targetId)) return null;
22774
22809
  return { action: "update", targetId, content: c };
22775
22810
  }
22776
- var DEFAULT_MODEL3, DEFAULT_CONSOLIDATE_ATTEMPTS, DEFAULT_CONSOLIDATE_TOTAL_TIMEOUT_MS, SYSTEM_PROMPT3;
22811
+ var DEFAULT_CONSOLIDATION_MODEL, DEFAULT_CONSOLIDATE_ATTEMPTS, DEFAULT_CONSOLIDATE_TOTAL_TIMEOUT_MS, SYSTEM_PROMPT3;
22777
22812
  var init_consolidate = __esm({
22778
22813
  "src/lib/memory/consolidate.ts"() {
22779
22814
  "use strict";
22780
22815
  init_logger();
22781
22816
  init_redactor();
22782
22817
  init_portalLlm();
22783
- DEFAULT_MODEL3 = "inclusionai/ling-2.6-flash";
22818
+ DEFAULT_CONSOLIDATION_MODEL = "inclusionai/ling-2.6-flash";
22784
22819
  DEFAULT_CONSOLIDATE_ATTEMPTS = 3;
22785
22820
  DEFAULT_CONSOLIDATE_TOTAL_TIMEOUT_MS = 2e4;
22786
22821
  SYSTEM_PROMPT3 = `You consolidate a new memory against existing memories from the same user.
@@ -27639,9 +27674,25 @@ async function retain(content, ctx, options = {}) {
27639
27674
  const resolvedScope = options.scope ?? DEFAULT_SCOPE;
27640
27675
  let supersedeTargetIds = [];
27641
27676
  let supersedeContent;
27677
+ let prepared;
27642
27678
  if (enableAutoMerge) {
27679
+ prepared = await prepareVaultCandidates(
27680
+ trimmed,
27681
+ ctx.vaultCtx,
27682
+ ctx.embeddingOptions,
27683
+ ctx.vaultCache,
27684
+ {
27685
+ limit: Math.max(options.consolidateTopK ?? DEFAULT_CONSOLIDATE_TOP_K, 1),
27686
+ useFusion: false,
27687
+ scopes: [resolvedScope],
27688
+ // PR5 — include archived rows as merge candidates so a re-observed fact
27689
+ // resurrects (un-archives) the decayed row instead of duplicating it.
27690
+ includeArchived: true,
27691
+ ...options.folderId !== void 0 && { folderId: options.folderId }
27692
+ }
27693
+ );
27643
27694
  if (options.consolidateOptions) {
27644
- const outcome = await tryConsolidate(trimmed, ctx, options);
27695
+ const outcome = await tryConsolidate(trimmed, ctx, options, prepared);
27645
27696
  if (outcome) {
27646
27697
  if ("done" in outcome) return outcome.done;
27647
27698
  supersedeTargetIds = outcome.supersede;
@@ -27649,23 +27700,14 @@ async function retain(content, ctx, options = {}) {
27649
27700
  }
27650
27701
  }
27651
27702
  if (supersedeTargetIds.length === 0) {
27652
- const matches = await searchVaultMemories(
27703
+ const { results: matches } = await rankPreparedVaultCandidates(
27653
27704
  trimmed,
27654
- ctx.vaultCtx,
27705
+ prepared,
27655
27706
  ctx.embeddingOptions,
27656
- ctx.vaultCache,
27657
27707
  {
27658
27708
  limit: 1,
27659
27709
  minSimilarity: threshold,
27660
- useFusion: false,
27661
- scopes: [resolvedScope],
27662
- // PR5 — include archived rows as merge candidates so a re-observed
27663
- // fact resurrects (un-archives) the decayed row instead of creating a
27664
- // fresh duplicate. The resurrection is applied on the merge write
27665
- // below, but ONLY for a row that is not superseded/deleted (the
27666
- // guards below preserve main's tombstone/supersession suppression).
27667
- includeArchived: true,
27668
- ...options.folderId !== void 0 && { folderId: options.folderId }
27710
+ useFusion: false
27669
27711
  }
27670
27712
  );
27671
27713
  if (matches.length > 0) {
@@ -27713,7 +27755,8 @@ async function retain(content, ctx, options = {}) {
27713
27755
  }
27714
27756
  }
27715
27757
  const contentToWrite = supersedeContent ?? trimmed;
27716
- const embedding = await generateEmbedding(contentToWrite, ctx.embeddingOptions);
27758
+ const reusableQueryEmbedding = supersedeContent === void 0 && prepared && prepared.queryEmbedding.length > 0 ? prepared.queryEmbedding : void 0;
27759
+ const embedding = reusableQueryEmbedding ?? await generateEmbedding(contentToWrite, ctx.embeddingOptions);
27717
27760
  const embeddingModel = ctx.embeddingOptions.model ?? DEFAULT_API_EMBEDDING_MODEL;
27718
27761
  if (options.respectTombstones) {
27719
27762
  const tombstoneId = await findTombstoneMatch(embedding, embeddingModel, resolvedScope, ctx, {
@@ -27842,26 +27885,19 @@ function pickFactTypeUpdate(existing, incoming) {
27842
27885
  function resurrectFields(existing) {
27843
27886
  return typeof existing.archivedAt === "number" ? { restore: true } : { preserveUpdatedAt: true };
27844
27887
  }
27845
- async function tryConsolidate(trimmed, ctx, options) {
27888
+ async function tryConsolidate(trimmed, ctx, options, prepared) {
27846
27889
  const consolidateOptions = options.consolidateOptions;
27847
27890
  if (!consolidateOptions) return null;
27848
27891
  const consolidateThreshold = options.consolidateThreshold ?? DEFAULT_CONSOLIDATE_THRESHOLD;
27849
27892
  const topK = options.consolidateTopK ?? DEFAULT_CONSOLIDATE_TOP_K;
27850
- const resolvedScope = options.scope ?? DEFAULT_SCOPE;
27851
- const matches = await searchVaultMemories(
27893
+ const { results: matches } = await rankPreparedVaultCandidates(
27852
27894
  trimmed,
27853
- ctx.vaultCtx,
27895
+ prepared,
27854
27896
  ctx.embeddingOptions,
27855
- ctx.vaultCache,
27856
27897
  {
27857
27898
  limit: topK,
27858
27899
  minSimilarity: consolidateThreshold,
27859
- useFusion: false,
27860
- scopes: [resolvedScope],
27861
- // PR5 — archived rows are consolidation candidates too, so a paraphrased
27862
- // re-observation resurrects a decayed row rather than duplicating it.
27863
- includeArchived: true,
27864
- ...options.folderId !== void 0 && { folderId: options.folderId }
27900
+ useFusion: false
27865
27901
  }
27866
27902
  );
27867
27903
  if (matches.length === 0) return null;
@@ -28644,7 +28680,7 @@ function classifyDecay(m, now, policy) {
28644
28680
  init_logger();
28645
28681
  init_redactor();
28646
28682
  init_portalLlm();
28647
- var DEFAULT_MODEL4 = "inclusionai/ling-2.6-flash";
28683
+ var DEFAULT_MODEL3 = "inclusionai/ling-2.6-flash";
28648
28684
  var DEFAULT_ATTEMPTS2 = 2;
28649
28685
  var DEFAULT_TOTAL_TIMEOUT_MS2 = 12e3;
28650
28686
  var MAX_CONTENT_CHARS = 400;
@@ -28683,7 +28719,7 @@ function createLlmDecayClassifier(options) {
28683
28719
  ...options.apiKey !== void 0 && { apiKey: options.apiKey },
28684
28720
  ...options.getToken !== void 0 && { getToken: options.getToken },
28685
28721
  ...options.baseUrl !== void 0 && { baseUrl: options.baseUrl },
28686
- model: options.model ?? DEFAULT_MODEL4,
28722
+ model: options.model ?? DEFAULT_MODEL3,
28687
28723
  systemPrompt: SYSTEM_PROMPT5,
28688
28724
  userMessage: `Memory content:
28689
28725
  ${safe}
@@ -29116,7 +29152,7 @@ init_logger();
29116
29152
  init_portalLlm();
29117
29153
  init_recall();
29118
29154
  var DEFAULT_BASE_URL2 = BASE_URL;
29119
- var DEFAULT_MODEL5 = "anthropic/claude-sonnet-4-6";
29155
+ var DEFAULT_MODEL4 = "anthropic/claude-sonnet-4-6";
29120
29156
  var DEFAULT_MAX_TOKENS = 4096;
29121
29157
  var REQUEST_TIMEOUT_MS = 6e4;
29122
29158
  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.
@@ -29148,7 +29184,7 @@ async function reflect(query, ctx, options) {
29148
29184
  const evidence = recalledMemories.map((m, i) => `[${i + 1}] (id: ${m.id}, kind: ${m.kind})
29149
29185
  ${m.content}`).join("\n\n");
29150
29186
  const baseUrl = options.baseUrl ?? DEFAULT_BASE_URL2;
29151
- const model = options.llmModel ?? DEFAULT_MODEL5;
29187
+ const model = options.llmModel ?? DEFAULT_MODEL4;
29152
29188
  const wantsStructured = !!options.responseSchema;
29153
29189
  const sendResponseFormat = wantsStructured && supportsResponseFormat(model, "json_schema");
29154
29190
  const basePrompt = options.systemPrompt ?? DEFAULT_SYSTEM_PROMPT;
@@ -88,6 +88,8 @@ import {
88
88
  onClearAllEncryptionState,
89
89
  onKeyAvailable,
90
90
  preEmbedVaultMemories,
91
+ prepareVaultCandidates,
92
+ rankPreparedVaultCandidates,
91
93
  recall,
92
94
  replaceMemoryEntitiesGuardedOp,
93
95
  requestEncryptionKey,
@@ -125,7 +127,7 @@ import {
125
127
  updateVaultMemoryOp,
126
128
  upsertMessageOp,
127
129
  vaultMemoryToStored
128
- } from "./chunk-FJFPCJRI.mjs";
130
+ } from "./chunk-FXS3EUKX.mjs";
129
131
  import {
130
132
  createStreamingDeAnonymizer,
131
133
  resolvePiiRedactor
@@ -5265,9 +5267,25 @@ async function retain(content, ctx, options = {}) {
5265
5267
  const resolvedScope = options.scope ?? DEFAULT_SCOPE;
5266
5268
  let supersedeTargetIds = [];
5267
5269
  let supersedeContent;
5270
+ let prepared;
5268
5271
  if (enableAutoMerge) {
5272
+ prepared = await prepareVaultCandidates(
5273
+ trimmed,
5274
+ ctx.vaultCtx,
5275
+ ctx.embeddingOptions,
5276
+ ctx.vaultCache,
5277
+ {
5278
+ limit: Math.max(options.consolidateTopK ?? DEFAULT_CONSOLIDATE_TOP_K, 1),
5279
+ useFusion: false,
5280
+ scopes: [resolvedScope],
5281
+ // PR5 — include archived rows as merge candidates so a re-observed fact
5282
+ // resurrects (un-archives) the decayed row instead of duplicating it.
5283
+ includeArchived: true,
5284
+ ...options.folderId !== void 0 && { folderId: options.folderId }
5285
+ }
5286
+ );
5269
5287
  if (options.consolidateOptions) {
5270
- const outcome = await tryConsolidate(trimmed, ctx, options);
5288
+ const outcome = await tryConsolidate(trimmed, ctx, options, prepared);
5271
5289
  if (outcome) {
5272
5290
  if ("done" in outcome) return outcome.done;
5273
5291
  supersedeTargetIds = outcome.supersede;
@@ -5275,23 +5293,14 @@ async function retain(content, ctx, options = {}) {
5275
5293
  }
5276
5294
  }
5277
5295
  if (supersedeTargetIds.length === 0) {
5278
- const matches = await searchVaultMemories(
5296
+ const { results: matches } = await rankPreparedVaultCandidates(
5279
5297
  trimmed,
5280
- ctx.vaultCtx,
5298
+ prepared,
5281
5299
  ctx.embeddingOptions,
5282
- ctx.vaultCache,
5283
5300
  {
5284
5301
  limit: 1,
5285
5302
  minSimilarity: threshold,
5286
- useFusion: false,
5287
- scopes: [resolvedScope],
5288
- // PR5 — include archived rows as merge candidates so a re-observed
5289
- // fact resurrects (un-archives) the decayed row instead of creating a
5290
- // fresh duplicate. The resurrection is applied on the merge write
5291
- // below, but ONLY for a row that is not superseded/deleted (the
5292
- // guards below preserve main's tombstone/supersession suppression).
5293
- includeArchived: true,
5294
- ...options.folderId !== void 0 && { folderId: options.folderId }
5303
+ useFusion: false
5295
5304
  }
5296
5305
  );
5297
5306
  if (matches.length > 0) {
@@ -5339,7 +5348,8 @@ async function retain(content, ctx, options = {}) {
5339
5348
  }
5340
5349
  }
5341
5350
  const contentToWrite = supersedeContent ?? trimmed;
5342
- const embedding = await generateEmbedding(contentToWrite, ctx.embeddingOptions);
5351
+ const reusableQueryEmbedding = supersedeContent === void 0 && prepared && prepared.queryEmbedding.length > 0 ? prepared.queryEmbedding : void 0;
5352
+ const embedding = reusableQueryEmbedding ?? await generateEmbedding(contentToWrite, ctx.embeddingOptions);
5343
5353
  const embeddingModel = ctx.embeddingOptions.model ?? DEFAULT_API_EMBEDDING_MODEL;
5344
5354
  if (options.respectTombstones) {
5345
5355
  const tombstoneId = await findTombstoneMatch(embedding, embeddingModel, resolvedScope, ctx, {
@@ -5468,26 +5478,19 @@ function pickFactTypeUpdate(existing, incoming) {
5468
5478
  function resurrectFields(existing) {
5469
5479
  return typeof existing.archivedAt === "number" ? { restore: true } : { preserveUpdatedAt: true };
5470
5480
  }
5471
- async function tryConsolidate(trimmed, ctx, options) {
5481
+ async function tryConsolidate(trimmed, ctx, options, prepared) {
5472
5482
  const consolidateOptions = options.consolidateOptions;
5473
5483
  if (!consolidateOptions) return null;
5474
5484
  const consolidateThreshold = options.consolidateThreshold ?? DEFAULT_CONSOLIDATE_THRESHOLD;
5475
5485
  const topK = options.consolidateTopK ?? DEFAULT_CONSOLIDATE_TOP_K;
5476
- const resolvedScope = options.scope ?? DEFAULT_SCOPE;
5477
- const matches = await searchVaultMemories(
5486
+ const { results: matches } = await rankPreparedVaultCandidates(
5478
5487
  trimmed,
5479
- ctx.vaultCtx,
5488
+ prepared,
5480
5489
  ctx.embeddingOptions,
5481
- ctx.vaultCache,
5482
5490
  {
5483
5491
  limit: topK,
5484
5492
  minSimilarity: consolidateThreshold,
5485
- useFusion: false,
5486
- scopes: [resolvedScope],
5487
- // PR5 — archived rows are consolidation candidates too, so a paraphrased
5488
- // re-observation resurrects a decayed row rather than duplicating it.
5489
- includeArchived: true,
5490
- ...options.folderId !== void 0 && { folderId: options.folderId }
5493
+ useFusion: false
5491
5494
  }
5492
5495
  );
5493
5496
  if (matches.length === 0) return null;
@@ -5496,7 +5499,7 @@ async function tryConsolidate(trimmed, ctx, options) {
5496
5499
  content: m.content,
5497
5500
  similarity: m.similarity
5498
5501
  }));
5499
- const { consolidateMemory: doConsolidate } = await import("./consolidate-BKLNVH5Y.mjs");
5502
+ const { consolidateMemory: doConsolidate } = await import("./consolidate-YCD45CXO.mjs");
5500
5503
  const decision = await doConsolidate(trimmed, candidates, consolidateOptions);
5501
5504
  if (decision.action === "create") return null;
5502
5505
  if (decision.action === "supersede" && decision.content) {
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  recall
3
- } from "./chunk-FJFPCJRI.mjs";
3
+ } from "./chunk-FXS3EUKX.mjs";
4
4
  import "./chunk-MIXEASUP.mjs";
5
5
  import "./chunk-3RPGXXPZ.mjs";
6
6
  export {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@anuma/sdk",
3
- "version": "3.9.4",
3
+ "version": "3.9.6",
4
4
  "description": "",
5
5
  "main": "./dist/index.cjs",
6
6
  "module": "./dist/index.mjs",