@anuma/sdk 3.9.3 → 3.9.5

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.
@@ -6181,6 +6181,14 @@ var init_lruCache = __esm({
6181
6181
  });
6182
6182
 
6183
6183
  // src/lib/memory/queryEntities.ts
6184
+ function hasMeaningfulCandidate(candidates) {
6185
+ for (const candidate of candidates) {
6186
+ if (!candidate.split(/\s+/).every((token) => FALLBACK_STOPWORDS.has(token))) {
6187
+ return true;
6188
+ }
6189
+ }
6190
+ return false;
6191
+ }
6184
6192
  function extractQueryEntities(query) {
6185
6193
  if (!query) return [];
6186
6194
  const matches = query.matchAll(ENTITY_REGEX);
@@ -6196,9 +6204,27 @@ function extractQueryEntities(query) {
6196
6204
  seen.add(candidate);
6197
6205
  }
6198
6206
  }
6199
- return [...seen];
6207
+ if (hasMeaningfulCandidate(seen)) return [...seen];
6208
+ return [.../* @__PURE__ */ new Set([...extractFallbackCandidates(query), ...seen])];
6200
6209
  }
6201
- var STOPWORDS2, ENTITY_REGEX;
6210
+ function extractFallbackCandidates(query) {
6211
+ const tokens = (query.match(/\p{L}[\p{L}'-]*/gu) ?? []).map(normalizeEntityName);
6212
+ const out = [];
6213
+ const seen = /* @__PURE__ */ new Set();
6214
+ for (let n = 1; n <= MAX_FALLBACK_TOKENS; n++) {
6215
+ for (let start = 0; start + n <= tokens.length; start++) {
6216
+ const gram = tokens.slice(start, start + n);
6217
+ if (gram.some((t) => t.length < 2 || FALLBACK_STOPWORDS.has(t))) continue;
6218
+ const candidate = gram.join(" ");
6219
+ if (seen.has(candidate)) continue;
6220
+ seen.add(candidate);
6221
+ out.push(candidate);
6222
+ if (out.length >= MAX_FALLBACK_CANDIDATES) return out;
6223
+ }
6224
+ }
6225
+ return out;
6226
+ }
6227
+ var STOPWORDS2, ENTITY_REGEX, FALLBACK_ONLY_STOPWORDS, FALLBACK_STOPWORDS, MAX_FALLBACK_CANDIDATES, MAX_FALLBACK_TOKENS;
6202
6228
  var init_queryEntities = __esm({
6203
6229
  "src/lib/memory/queryEntities.ts"() {
6204
6230
  "use strict";
@@ -6250,6 +6276,10 @@ var init_queryEntities = __esm({
6250
6276
  ].map((w) => w.toLowerCase())
6251
6277
  );
6252
6278
  ENTITY_REGEX = /\b\p{Lu}[\p{L}'-]{2,}(?:\s+\p{Lu}[\p{L}'-]+){0,2}\b/gu;
6279
+ FALLBACK_ONLY_STOPWORDS = "a an and or but nor not if then than because so too also just very really about above after again against all am any anyone anybody anything are around as at be been being before behind below between both by can cannot could currently did do does doing done down during each ever every everybody everyone everything few find finds finding for from get gets getting go goes going gone got had has have having he help her here hers him his hmm i in into is it its knew know knows later like liked likes live lived lives living look looked looking looks made make makes may me meet meets might mine more most must my near need needed needs never nobody nothing now of off okay on once only onto other our ours out over own people person please recently said same say says see seen shall she should since some somebody someone something soon still such talk tell tells thank that the their theirs them there these they think thinks this those thought through to today told tomorrow under until up us want wanted wants was we went were which while will with without work worked working works would yeah year years yep yesterday you your yours aren't can't couldn't didn't doesn't don't hadn't hasn't haven't he's how's i'd i'll i'm i've isn't it's let's she's shouldn't that's there's they're they've wasn't we're we've weren't what's when's where's who's why's won't wouldn't you'll you're you've".split(" ");
6280
+ FALLBACK_STOPWORDS = /* @__PURE__ */ new Set([...STOPWORDS2, ...FALLBACK_ONLY_STOPWORDS]);
6281
+ MAX_FALLBACK_CANDIDATES = 12;
6282
+ MAX_FALLBACK_TOKENS = 3;
6253
6283
  }
6254
6284
  });
6255
6285
 
@@ -7703,13 +7733,12 @@ async function buildProjectedCorpus(query, vaultCtx, embeddingOptions, cache, qu
7703
7733
  }));
7704
7734
  return { memories, embeddedItems, queryEmbedding, vaultSize };
7705
7735
  }
7706
- async function searchVaultMemoriesWithSize(query, vaultCtx, embeddingOptions, cache, searchOptions) {
7707
- const limit = searchOptions?.limit ?? 5;
7708
- const minSimilarity = searchOptions?.minSimilarity ?? 0.1;
7709
- const scopes = searchOptions?.scopes;
7736
+ async function prepareVaultCandidates(query, vaultCtx, embeddingOptions, cache, searchOptions) {
7710
7737
  if (!query || typeof query !== "string") {
7711
- return { results: [], vaultSize: 0, reranked: false, hadV2Head: false };
7738
+ return { memories: [], embeddedItems: [], queryEmbedding: [], vaultSize: 0 };
7712
7739
  }
7740
+ const limit = searchOptions?.limit ?? 5;
7741
+ const scopes = searchOptions?.scopes;
7713
7742
  const folderId = searchOptions?.folderId;
7714
7743
  const queryOpts = {};
7715
7744
  if (scopes?.length) queryOpts.scopes = scopes;
@@ -7736,11 +7765,11 @@ async function searchVaultMemoriesWithSize(query, vaultCtx, embeddingOptions, ca
7736
7765
  ...forceIncludeIds.length > 0 && { forceIncludeIds }
7737
7766
  });
7738
7767
  if (corpus.vaultSize === 0) {
7739
- return { results: [], vaultSize: 0, reranked: false, hadV2Head: false };
7768
+ return { memories: [], embeddedItems: [], queryEmbedding: [], vaultSize: 0 };
7740
7769
  }
7741
7770
  ({ memories, embeddedItems, queryEmbedding, vaultSize } = corpus);
7742
7771
  if (memories.length === 0) {
7743
- return { results: [], vaultSize, reranked: false, hadV2Head: false };
7772
+ return { memories: [], embeddedItems: [], queryEmbedding: [], vaultSize };
7744
7773
  }
7745
7774
  } else {
7746
7775
  const loaded = await getAllVaultMemoriesOp(
@@ -7755,7 +7784,7 @@ async function searchVaultMemoriesWithSize(query, vaultCtx, embeddingOptions, ca
7755
7784
  );
7756
7785
  }
7757
7786
  if (memories.length === 0) {
7758
- return { results: [], vaultSize: loaded.length, reranked: false, hadV2Head: false };
7787
+ return { memories: [], embeddedItems: [], queryEmbedding: [], vaultSize: loaded.length };
7759
7788
  }
7760
7789
  queryEmbedding = await generateEmbedding(query, embeddingOptions);
7761
7790
  const currentModel = embeddingOptions.model ?? DEFAULT_API_EMBEDDING_MODEL;
@@ -7820,6 +7849,12 @@ async function searchVaultMemoriesWithSize(query, vaultCtx, embeddingOptions, ca
7820
7849
  factType: m.factType
7821
7850
  }));
7822
7851
  }
7852
+ return { memories, embeddedItems, queryEmbedding, vaultSize };
7853
+ }
7854
+ async function rankPreparedVaultCandidates(query, prepared, embeddingOptions, searchOptions) {
7855
+ const limit = searchOptions?.limit ?? 5;
7856
+ const minSimilarity = searchOptions?.minSimilarity ?? 0.1;
7857
+ const { memories, embeddedItems, queryEmbedding, vaultSize } = prepared;
7823
7858
  if (queryEmbedding.length > 0) {
7824
7859
  const mismatched = embeddedItems.filter(
7825
7860
  (it) => it.embedding.length > 0 && it.embedding.length !== queryEmbedding.length
@@ -7957,6 +7992,25 @@ async function searchVaultMemoriesWithSize(query, vaultCtx, embeddingOptions, ca
7957
7992
  });
7958
7993
  return stampTimestamps({ results, vaultSize, hadV2Head: results.length > 0 });
7959
7994
  }
7995
+ async function searchVaultMemoriesWithSize(query, vaultCtx, embeddingOptions, cache, searchOptions) {
7996
+ if (!query || typeof query !== "string") {
7997
+ return { results: [], vaultSize: 0, reranked: false, hadV2Head: false };
7998
+ }
7999
+ const prepared = await prepareVaultCandidates(
8000
+ query,
8001
+ vaultCtx,
8002
+ embeddingOptions,
8003
+ cache,
8004
+ searchOptions
8005
+ );
8006
+ if (prepared.vaultSize === 0) {
8007
+ return { results: [], vaultSize: 0, reranked: false, hadV2Head: false };
8008
+ }
8009
+ if (prepared.memories.length === 0) {
8010
+ return { results: [], vaultSize: prepared.vaultSize, reranked: false, hadV2Head: false };
8011
+ }
8012
+ return rankPreparedVaultCandidates(query, prepared, embeddingOptions, searchOptions);
8013
+ }
7960
8014
  async function searchVaultMemories(query, vaultCtx, embeddingOptions, cache, searchOptions) {
7961
8015
  const { results } = await searchVaultMemoriesWithSize(
7962
8016
  query,
@@ -15770,9 +15824,25 @@ async function retain(content, ctx, options = {}) {
15770
15824
  const resolvedScope = options.scope ?? DEFAULT_SCOPE;
15771
15825
  let supersedeTargetIds = [];
15772
15826
  let supersedeContent;
15827
+ let prepared;
15773
15828
  if (enableAutoMerge) {
15829
+ prepared = await prepareVaultCandidates(
15830
+ trimmed,
15831
+ ctx.vaultCtx,
15832
+ ctx.embeddingOptions,
15833
+ ctx.vaultCache,
15834
+ {
15835
+ limit: Math.max(options.consolidateTopK ?? DEFAULT_CONSOLIDATE_TOP_K, 1),
15836
+ useFusion: false,
15837
+ scopes: [resolvedScope],
15838
+ // PR5 — include archived rows as merge candidates so a re-observed fact
15839
+ // resurrects (un-archives) the decayed row instead of duplicating it.
15840
+ includeArchived: true,
15841
+ ...options.folderId !== void 0 && { folderId: options.folderId }
15842
+ }
15843
+ );
15774
15844
  if (options.consolidateOptions) {
15775
- const outcome = await tryConsolidate(trimmed, ctx, options);
15845
+ const outcome = await tryConsolidate(trimmed, ctx, options, prepared);
15776
15846
  if (outcome) {
15777
15847
  if ("done" in outcome) return outcome.done;
15778
15848
  supersedeTargetIds = outcome.supersede;
@@ -15780,23 +15850,14 @@ async function retain(content, ctx, options = {}) {
15780
15850
  }
15781
15851
  }
15782
15852
  if (supersedeTargetIds.length === 0) {
15783
- const matches = await searchVaultMemories(
15853
+ const { results: matches } = await rankPreparedVaultCandidates(
15784
15854
  trimmed,
15785
- ctx.vaultCtx,
15855
+ prepared,
15786
15856
  ctx.embeddingOptions,
15787
- ctx.vaultCache,
15788
15857
  {
15789
15858
  limit: 1,
15790
15859
  minSimilarity: threshold,
15791
- useFusion: false,
15792
- scopes: [resolvedScope],
15793
- // PR5 — include archived rows as merge candidates so a re-observed
15794
- // fact resurrects (un-archives) the decayed row instead of creating a
15795
- // fresh duplicate. The resurrection is applied on the merge write
15796
- // below, but ONLY for a row that is not superseded/deleted (the
15797
- // guards below preserve main's tombstone/supersession suppression).
15798
- includeArchived: true,
15799
- ...options.folderId !== void 0 && { folderId: options.folderId }
15860
+ useFusion: false
15800
15861
  }
15801
15862
  );
15802
15863
  if (matches.length > 0) {
@@ -15844,7 +15905,8 @@ async function retain(content, ctx, options = {}) {
15844
15905
  }
15845
15906
  }
15846
15907
  const contentToWrite = supersedeContent ?? trimmed;
15847
- const embedding = await generateEmbedding(contentToWrite, ctx.embeddingOptions);
15908
+ const reusableQueryEmbedding = supersedeContent === void 0 && prepared && prepared.queryEmbedding.length > 0 ? prepared.queryEmbedding : void 0;
15909
+ const embedding = reusableQueryEmbedding ?? await generateEmbedding(contentToWrite, ctx.embeddingOptions);
15848
15910
  const embeddingModel = ctx.embeddingOptions.model ?? DEFAULT_API_EMBEDDING_MODEL;
15849
15911
  if (options.respectTombstones) {
15850
15912
  const tombstoneId = await findTombstoneMatch(embedding, embeddingModel, resolvedScope, ctx, {
@@ -15973,26 +16035,19 @@ function pickFactTypeUpdate(existing, incoming) {
15973
16035
  function resurrectFields(existing) {
15974
16036
  return typeof existing.archivedAt === "number" ? { restore: true } : { preserveUpdatedAt: true };
15975
16037
  }
15976
- async function tryConsolidate(trimmed, ctx, options) {
16038
+ async function tryConsolidate(trimmed, ctx, options, prepared) {
15977
16039
  const consolidateOptions = options.consolidateOptions;
15978
16040
  if (!consolidateOptions) return null;
15979
16041
  const consolidateThreshold = options.consolidateThreshold ?? DEFAULT_CONSOLIDATE_THRESHOLD;
15980
16042
  const topK = options.consolidateTopK ?? DEFAULT_CONSOLIDATE_TOP_K;
15981
- const resolvedScope = options.scope ?? DEFAULT_SCOPE;
15982
- const matches = await searchVaultMemories(
16043
+ const { results: matches } = await rankPreparedVaultCandidates(
15983
16044
  trimmed,
15984
- ctx.vaultCtx,
16045
+ prepared,
15985
16046
  ctx.embeddingOptions,
15986
- ctx.vaultCache,
15987
16047
  {
15988
16048
  limit: topK,
15989
16049
  minSimilarity: consolidateThreshold,
15990
- useFusion: false,
15991
- scopes: [resolvedScope],
15992
- // PR5 — archived rows are consolidation candidates too, so a paraphrased
15993
- // re-observation resurrects a decayed row rather than duplicating it.
15994
- includeArchived: true,
15995
- ...options.folderId !== void 0 && { folderId: options.folderId }
16050
+ useFusion: false
15996
16051
  }
15997
16052
  );
15998
16053
  if (matches.length === 0) return null;
@@ -125,6 +125,8 @@ import {
125
125
  postAuthOauthByProviderRefresh,
126
126
  postAuthOauthByProviderRevoke,
127
127
  preEmbedVaultMemories,
128
+ prepareVaultCandidates,
129
+ rankPreparedVaultCandidates,
128
130
  recall,
129
131
  replaceMemoryEntitiesGuardedOp,
130
132
  requestEncryptionKey,
@@ -153,7 +155,7 @@ import {
153
155
  updateVaultMemoryOp,
154
156
  useEncryption,
155
157
  vaultMemoryToStored
156
- } from "./chunk-HLBQICNL.mjs";
158
+ } from "./chunk-IWR7BNER.mjs";
157
159
  import {
158
160
  PiiRedactor,
159
161
  createStreamingDeAnonymizer,
@@ -7181,9 +7183,25 @@ async function retain(content, ctx, options = {}) {
7181
7183
  const resolvedScope = options.scope ?? DEFAULT_SCOPE;
7182
7184
  let supersedeTargetIds = [];
7183
7185
  let supersedeContent;
7186
+ let prepared;
7184
7187
  if (enableAutoMerge) {
7188
+ prepared = await prepareVaultCandidates(
7189
+ trimmed,
7190
+ ctx.vaultCtx,
7191
+ ctx.embeddingOptions,
7192
+ ctx.vaultCache,
7193
+ {
7194
+ limit: Math.max(options.consolidateTopK ?? DEFAULT_CONSOLIDATE_TOP_K, 1),
7195
+ useFusion: false,
7196
+ scopes: [resolvedScope],
7197
+ // PR5 — include archived rows as merge candidates so a re-observed fact
7198
+ // resurrects (un-archives) the decayed row instead of duplicating it.
7199
+ includeArchived: true,
7200
+ ...options.folderId !== void 0 && { folderId: options.folderId }
7201
+ }
7202
+ );
7185
7203
  if (options.consolidateOptions) {
7186
- const outcome = await tryConsolidate(trimmed, ctx, options);
7204
+ const outcome = await tryConsolidate(trimmed, ctx, options, prepared);
7187
7205
  if (outcome) {
7188
7206
  if ("done" in outcome) return outcome.done;
7189
7207
  supersedeTargetIds = outcome.supersede;
@@ -7191,23 +7209,14 @@ async function retain(content, ctx, options = {}) {
7191
7209
  }
7192
7210
  }
7193
7211
  if (supersedeTargetIds.length === 0) {
7194
- const matches = await searchVaultMemories(
7212
+ const { results: matches } = await rankPreparedVaultCandidates(
7195
7213
  trimmed,
7196
- ctx.vaultCtx,
7214
+ prepared,
7197
7215
  ctx.embeddingOptions,
7198
- ctx.vaultCache,
7199
7216
  {
7200
7217
  limit: 1,
7201
7218
  minSimilarity: threshold,
7202
- useFusion: false,
7203
- scopes: [resolvedScope],
7204
- // PR5 — include archived rows as merge candidates so a re-observed
7205
- // fact resurrects (un-archives) the decayed row instead of creating a
7206
- // fresh duplicate. The resurrection is applied on the merge write
7207
- // below, but ONLY for a row that is not superseded/deleted (the
7208
- // guards below preserve main's tombstone/supersession suppression).
7209
- includeArchived: true,
7210
- ...options.folderId !== void 0 && { folderId: options.folderId }
7219
+ useFusion: false
7211
7220
  }
7212
7221
  );
7213
7222
  if (matches.length > 0) {
@@ -7255,7 +7264,8 @@ async function retain(content, ctx, options = {}) {
7255
7264
  }
7256
7265
  }
7257
7266
  const contentToWrite = supersedeContent ?? trimmed;
7258
- const embedding = await generateEmbedding(contentToWrite, ctx.embeddingOptions);
7267
+ const reusableQueryEmbedding = supersedeContent === void 0 && prepared && prepared.queryEmbedding.length > 0 ? prepared.queryEmbedding : void 0;
7268
+ const embedding = reusableQueryEmbedding ?? await generateEmbedding(contentToWrite, ctx.embeddingOptions);
7259
7269
  const embeddingModel = ctx.embeddingOptions.model ?? DEFAULT_API_EMBEDDING_MODEL;
7260
7270
  if (options.respectTombstones) {
7261
7271
  const tombstoneId = await findTombstoneMatch(embedding, embeddingModel, resolvedScope, ctx, {
@@ -7384,26 +7394,19 @@ function pickFactTypeUpdate(existing, incoming) {
7384
7394
  function resurrectFields(existing) {
7385
7395
  return typeof existing.archivedAt === "number" ? { restore: true } : { preserveUpdatedAt: true };
7386
7396
  }
7387
- async function tryConsolidate(trimmed, ctx, options) {
7397
+ async function tryConsolidate(trimmed, ctx, options, prepared) {
7388
7398
  const consolidateOptions = options.consolidateOptions;
7389
7399
  if (!consolidateOptions) return null;
7390
7400
  const consolidateThreshold = options.consolidateThreshold ?? DEFAULT_CONSOLIDATE_THRESHOLD;
7391
7401
  const topK = options.consolidateTopK ?? DEFAULT_CONSOLIDATE_TOP_K;
7392
- const resolvedScope = options.scope ?? DEFAULT_SCOPE;
7393
- const matches = await searchVaultMemories(
7402
+ const { results: matches } = await rankPreparedVaultCandidates(
7394
7403
  trimmed,
7395
- ctx.vaultCtx,
7404
+ prepared,
7396
7405
  ctx.embeddingOptions,
7397
- ctx.vaultCache,
7398
7406
  {
7399
7407
  limit: topK,
7400
7408
  minSimilarity: consolidateThreshold,
7401
- useFusion: false,
7402
- scopes: [resolvedScope],
7403
- // PR5 — archived rows are consolidation candidates too, so a paraphrased
7404
- // re-observation resurrects a decayed row rather than duplicating it.
7405
- includeArchived: true,
7406
- ...options.folderId !== void 0 && { folderId: options.folderId }
7409
+ useFusion: false
7407
7410
  }
7408
7411
  );
7409
7412
  if (matches.length === 0) return null;
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  recall
3
- } from "./chunk-HLBQICNL.mjs";
3
+ } from "./chunk-IWR7BNER.mjs";
4
4
  import "./chunk-BOY27A2C.mjs";
5
5
  import "./chunk-GYKJOWEO.mjs";
6
6
  export {
@@ -19474,13 +19474,12 @@ async function buildProjectedCorpus(query, vaultCtx, embeddingOptions, cache, qu
19474
19474
  }));
19475
19475
  return { memories, embeddedItems, queryEmbedding, vaultSize };
19476
19476
  }
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;
19477
+ async function prepareVaultCandidates(query, vaultCtx, embeddingOptions, cache, searchOptions) {
19481
19478
  if (!query || typeof query !== "string") {
19482
- return { results: [], vaultSize: 0, reranked: false, hadV2Head: false };
19479
+ return { memories: [], embeddedItems: [], queryEmbedding: [], vaultSize: 0 };
19483
19480
  }
19481
+ const limit = searchOptions?.limit ?? 5;
19482
+ const scopes = searchOptions?.scopes;
19484
19483
  const folderId = searchOptions?.folderId;
19485
19484
  const queryOpts = {};
19486
19485
  if (scopes?.length) queryOpts.scopes = scopes;
@@ -19507,11 +19506,11 @@ async function searchVaultMemoriesWithSize(query, vaultCtx, embeddingOptions, ca
19507
19506
  ...forceIncludeIds.length > 0 && { forceIncludeIds }
19508
19507
  });
19509
19508
  if (corpus.vaultSize === 0) {
19510
- return { results: [], vaultSize: 0, reranked: false, hadV2Head: false };
19509
+ return { memories: [], embeddedItems: [], queryEmbedding: [], vaultSize: 0 };
19511
19510
  }
19512
19511
  ({ memories, embeddedItems, queryEmbedding, vaultSize } = corpus);
19513
19512
  if (memories.length === 0) {
19514
- return { results: [], vaultSize, reranked: false, hadV2Head: false };
19513
+ return { memories: [], embeddedItems: [], queryEmbedding: [], vaultSize };
19515
19514
  }
19516
19515
  } else {
19517
19516
  const loaded = await getAllVaultMemoriesOp(
@@ -19526,7 +19525,7 @@ async function searchVaultMemoriesWithSize(query, vaultCtx, embeddingOptions, ca
19526
19525
  );
19527
19526
  }
19528
19527
  if (memories.length === 0) {
19529
- return { results: [], vaultSize: loaded.length, reranked: false, hadV2Head: false };
19528
+ return { memories: [], embeddedItems: [], queryEmbedding: [], vaultSize: loaded.length };
19530
19529
  }
19531
19530
  queryEmbedding = await generateEmbedding(query, embeddingOptions);
19532
19531
  const currentModel = embeddingOptions.model ?? DEFAULT_API_EMBEDDING_MODEL;
@@ -19591,6 +19590,12 @@ async function searchVaultMemoriesWithSize(query, vaultCtx, embeddingOptions, ca
19591
19590
  factType: m.factType
19592
19591
  }));
19593
19592
  }
19593
+ return { memories, embeddedItems, queryEmbedding, vaultSize };
19594
+ }
19595
+ async function rankPreparedVaultCandidates(query, prepared, embeddingOptions, searchOptions) {
19596
+ const limit = searchOptions?.limit ?? 5;
19597
+ const minSimilarity = searchOptions?.minSimilarity ?? 0.1;
19598
+ const { memories, embeddedItems, queryEmbedding, vaultSize } = prepared;
19594
19599
  if (queryEmbedding.length > 0) {
19595
19600
  const mismatched = embeddedItems.filter(
19596
19601
  (it) => it.embedding.length > 0 && it.embedding.length !== queryEmbedding.length
@@ -19728,6 +19733,25 @@ async function searchVaultMemoriesWithSize(query, vaultCtx, embeddingOptions, ca
19728
19733
  });
19729
19734
  return stampTimestamps({ results, vaultSize, hadV2Head: results.length > 0 });
19730
19735
  }
19736
+ async function searchVaultMemoriesWithSize(query, vaultCtx, embeddingOptions, cache, searchOptions) {
19737
+ if (!query || typeof query !== "string") {
19738
+ return { results: [], vaultSize: 0, reranked: false, hadV2Head: false };
19739
+ }
19740
+ const prepared = await prepareVaultCandidates(
19741
+ query,
19742
+ vaultCtx,
19743
+ embeddingOptions,
19744
+ cache,
19745
+ searchOptions
19746
+ );
19747
+ if (prepared.vaultSize === 0) {
19748
+ return { results: [], vaultSize: 0, reranked: false, hadV2Head: false };
19749
+ }
19750
+ if (prepared.memories.length === 0) {
19751
+ return { results: [], vaultSize: prepared.vaultSize, reranked: false, hadV2Head: false };
19752
+ }
19753
+ return rankPreparedVaultCandidates(query, prepared, embeddingOptions, searchOptions);
19754
+ }
19731
19755
  async function searchVaultMemories(query, vaultCtx, embeddingOptions, cache, searchOptions) {
19732
19756
  const { results } = await searchVaultMemoriesWithSize(
19733
19757
  query,
@@ -19815,7 +19839,7 @@ function createMemoryVaultSearchTool(vaultCtx, embeddingOptions, cache, searchOp
19815
19839
  legacy.map((r) => ({ id: r.uniqueId, content: r.content, score: r.similarity }))
19816
19840
  );
19817
19841
  }
19818
- const { recall: recall2 } = await import("./recall-5OW4RJVC.mjs");
19842
+ const { recall: recall2 } = await import("./recall-RVRZ4RQT.mjs");
19819
19843
  const result = await recall2(
19820
19844
  query,
19821
19845
  { vaultCtx, embeddingOptions, vaultCache: cache },
@@ -19908,6 +19932,18 @@ var STOPWORDS2 = new Set(
19908
19932
  ].map((w) => w.toLowerCase())
19909
19933
  );
19910
19934
  var ENTITY_REGEX = /\b\p{Lu}[\p{L}'-]{2,}(?:\s+\p{Lu}[\p{L}'-]+){0,2}\b/gu;
19935
+ var FALLBACK_ONLY_STOPWORDS = "a an and or but nor not if then than because so too also just very really about above after again against all am any anyone anybody anything are around as at be been being before behind below between both by can cannot could currently did do does doing done down during each ever every everybody everyone everything few find finds finding for from get gets getting go goes going gone got had has have having he help her here hers him his hmm i in into is it its knew know knows later like liked likes live lived lives living look looked looking looks made make makes may me meet meets might mine more most must my near need needed needs never nobody nothing now of off okay on once only onto other our ours out over own people person please recently said same say says see seen shall she should since some somebody someone something soon still such talk tell tells thank that the their theirs them there these they think thinks this those thought through to today told tomorrow under until up us want wanted wants was we went were which while will with without work worked working works would yeah year years yep yesterday you your yours aren't can't couldn't didn't doesn't don't hadn't hasn't haven't he's how's i'd i'll i'm i've isn't it's let's she's shouldn't that's there's they're they've wasn't we're we've weren't what's when's where's who's why's won't wouldn't you'll you're you've".split(" ");
19936
+ var FALLBACK_STOPWORDS = /* @__PURE__ */ new Set([...STOPWORDS2, ...FALLBACK_ONLY_STOPWORDS]);
19937
+ var MAX_FALLBACK_CANDIDATES = 12;
19938
+ var MAX_FALLBACK_TOKENS = 3;
19939
+ function hasMeaningfulCandidate(candidates) {
19940
+ for (const candidate of candidates) {
19941
+ if (!candidate.split(/\s+/).every((token) => FALLBACK_STOPWORDS.has(token))) {
19942
+ return true;
19943
+ }
19944
+ }
19945
+ return false;
19946
+ }
19911
19947
  function extractQueryEntities(query) {
19912
19948
  if (!query) return [];
19913
19949
  const matches = query.matchAll(ENTITY_REGEX);
@@ -19923,7 +19959,25 @@ function extractQueryEntities(query) {
19923
19959
  seen.add(candidate);
19924
19960
  }
19925
19961
  }
19926
- return [...seen];
19962
+ if (hasMeaningfulCandidate(seen)) return [...seen];
19963
+ return [.../* @__PURE__ */ new Set([...extractFallbackCandidates(query), ...seen])];
19964
+ }
19965
+ function extractFallbackCandidates(query) {
19966
+ const tokens = (query.match(/\p{L}[\p{L}'-]*/gu) ?? []).map(normalizeEntityName);
19967
+ const out = [];
19968
+ const seen = /* @__PURE__ */ new Set();
19969
+ for (let n = 1; n <= MAX_FALLBACK_TOKENS; n++) {
19970
+ for (let start = 0; start + n <= tokens.length; start++) {
19971
+ const gram = tokens.slice(start, start + n);
19972
+ if (gram.some((t) => t.length < 2 || FALLBACK_STOPWORDS.has(t))) continue;
19973
+ const candidate = gram.join(" ");
19974
+ if (seen.has(candidate)) continue;
19975
+ seen.add(candidate);
19976
+ out.push(candidate);
19977
+ if (out.length >= MAX_FALLBACK_CANDIDATES) return out;
19978
+ }
19979
+ }
19980
+ return out;
19927
19981
  }
19928
19982
 
19929
19983
  // src/lib/memory/graphTraversal.ts
@@ -20816,6 +20870,8 @@ export {
20816
20870
  recall,
20817
20871
  preEmbedVaultMemories,
20818
20872
  eagerEmbedContent,
20873
+ prepareVaultCandidates,
20874
+ rankPreparedVaultCandidates,
20819
20875
  searchVaultMemories,
20820
20876
  createMemoryVaultSearchTool
20821
20877
  };