@anuma/sdk 6.33.2 → 6.34.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -19969,7 +19969,7 @@ async function embedOne(text12, options, outer) {
19969
19969
  }
19970
19970
  var DEFAULT_EMBEDDING_BATCH_SIZE = 100;
19971
19971
  var DEFAULT_EMBEDDING_BATCH_CONCURRENCY = 3;
19972
- async function generateEmbeddingsBatch(texts, headers, baseUrl, model, onUsage, maskInput, timeoutMs) {
19972
+ async function generateEmbeddingsBatch(texts, headers, baseUrl, model, onUsage, maskInput, timeoutMs, outer) {
19973
19973
  const response = await withEmbeddingRetry(
19974
19974
  () => withDeadline(
19975
19975
  (signal) => postApiV1Embeddings({
@@ -19979,8 +19979,10 @@ async function generateEmbeddingsBatch(texts, headers, baseUrl, model, onUsage,
19979
19979
  ...signal && { signal }
19980
19980
  }),
19981
19981
  timeoutMs,
19982
- "embedding batch request"
19983
- )
19982
+ "embedding batch request",
19983
+ outer
19984
+ ),
19985
+ outer
19984
19986
  );
19985
19987
  if (response.error) {
19986
19988
  throw embeddingErrorFrom(response);
@@ -19998,6 +20000,11 @@ async function generateEmbeddingsBatch(texts, headers, baseUrl, model, onUsage,
19998
20000
  }
19999
20001
  async function generateEmbeddings(texts, options) {
20000
20002
  if (texts.length === 0) return [];
20003
+ const total = options.totalTimeoutMs;
20004
+ if (total === void 0) return embedMany(texts, options, void 0);
20005
+ return withDeadline((signal) => embedMany(texts, options, signal), total, "embedding batch");
20006
+ }
20007
+ async function embedMany(texts, options, outer) {
20001
20008
  const { baseUrl = BASE_URL, model, batchSize, cache } = options;
20002
20009
  const timeoutMs = options.timeoutMs ?? DEFAULT_EMBEDDING_REQUEST_TIMEOUT_MS;
20003
20010
  const chunkSize = batchSize ?? DEFAULT_EMBEDDING_BATCH_SIZE;
@@ -20018,7 +20025,8 @@ async function generateEmbeddings(texts, options) {
20018
20025
  if (uncachedTexts.length === 0) {
20019
20026
  return results;
20020
20027
  }
20021
- const headers = await resolveAuthHeaders(options);
20028
+ const headers = await resolveAuthHeaders(options, outer);
20029
+ if (outer?.aborted) throw outer.reason;
20022
20030
  const embeddingModel = model ?? DEFAULT_API_EMBEDDING_MODEL;
20023
20031
  let newEmbeddings;
20024
20032
  if (uncachedTexts.length <= chunkSize) {
@@ -20029,7 +20037,8 @@ async function generateEmbeddings(texts, options) {
20029
20037
  embeddingModel,
20030
20038
  options.onUsage,
20031
20039
  options.maskInput,
20032
- timeoutMs
20040
+ timeoutMs,
20041
+ outer
20033
20042
  );
20034
20043
  } else {
20035
20044
  const chunks = [];
@@ -20040,6 +20049,7 @@ async function generateEmbeddings(texts, options) {
20040
20049
  let nextIndex = 0;
20041
20050
  const worker = async () => {
20042
20051
  while (nextIndex < chunks.length) {
20052
+ if (outer?.aborted) throw outer.reason;
20043
20053
  const idx = nextIndex++;
20044
20054
  allEmbeddings[idx] = await generateEmbeddingsBatch(
20045
20055
  chunks[idx],
@@ -20048,7 +20058,8 @@ async function generateEmbeddings(texts, options) {
20048
20058
  embeddingModel,
20049
20059
  options.onUsage,
20050
20060
  options.maskInput,
20051
- timeoutMs
20061
+ timeoutMs,
20062
+ outer
20052
20063
  );
20053
20064
  }
20054
20065
  };
@@ -20059,6 +20070,7 @@ async function generateEmbeddings(texts, options) {
20059
20070
  await Promise.all(workers);
20060
20071
  newEmbeddings = allEmbeddings.flat();
20061
20072
  }
20073
+ if (outer?.aborted) throw outer.reason;
20062
20074
  for (let i = 0; i < uncachedIndices.length; i++) {
20063
20075
  const f32Embedding = Float32Array.from(newEmbeddings[i]);
20064
20076
  results[uncachedIndices[i]] = Array.from(f32Embedding);
@@ -31574,7 +31586,7 @@ async function rankPreparedVaultCandidates(query, prepared, embeddingOptions, se
31574
31586
  if (useFusion && !embeddingsUnavailable && facetQueries) {
31575
31587
  let subEmbeddings;
31576
31588
  try {
31577
- subEmbeddings = await generateEmbeddings(facetQueries, embeddingOptions);
31589
+ subEmbeddings = prepared.facetEmbeddings ?? await generateEmbeddings(facetQueries, embeddingOptions);
31578
31590
  } catch (err) {
31579
31591
  getLogger().warn(
31580
31592
  "memoryVault: sub-query embedding failed \u2014 falling back to single-query ranking: " + (err instanceof Error ? err.message : String(err))
@@ -31760,6 +31772,35 @@ var DEFAULT_SCOPE = "private";
31760
31772
  var DEFAULT_CONSOLIDATE_THRESHOLD = 0.55;
31761
31773
  var DEFAULT_CONSOLIDATE_TOP_K = 20;
31762
31774
  async function retain(content, ctx, options = {}) {
31775
+ return retainWithPersistence(
31776
+ content,
31777
+ {
31778
+ embeddingOptions: ctx.embeddingOptions,
31779
+ vaultCache: ctx.vaultCache,
31780
+ persistence: {
31781
+ prepare: (query, searchOptions) => prepareVaultCandidates(
31782
+ query,
31783
+ ctx.vaultCtx,
31784
+ ctx.embeddingOptions,
31785
+ ctx.vaultCache,
31786
+ searchOptions
31787
+ ),
31788
+ get: (id) => getVaultMemoryOp(ctx.vaultCtx, id),
31789
+ tombstones: (_embedding, _model, scope, folderId) => getAllVaultMemoriesOp(ctx.vaultCtx, {
31790
+ includeDeleted: true,
31791
+ scopes: [scope],
31792
+ ...folderId !== void 0 && { folderId }
31793
+ }),
31794
+ create: (input) => createVaultMemoryOp(ctx.vaultCtx, input),
31795
+ update: (id, patch) => updateVaultMemoryOp(ctx.vaultCtx, id, patch),
31796
+ supersede: (id, successor) => supersedeVaultMemoryOp(ctx.vaultCtx, id, successor),
31797
+ createSuperseding: (input, target) => createSupersedingMemoryOp(ctx.vaultCtx, input, target)
31798
+ }
31799
+ },
31800
+ options
31801
+ );
31802
+ }
31803
+ async function retainWithPersistence(content, ctx, options = {}) {
31763
31804
  const trimmed = content.trim();
31764
31805
  if (trimmed.length === 0) {
31765
31806
  throw new Error("retain: content cannot be empty");
@@ -31772,19 +31813,13 @@ async function retain(content, ctx, options = {}) {
31772
31813
  let supersedeContent;
31773
31814
  let prepared;
31774
31815
  if (enableAutoMerge) {
31775
- prepared = await prepareVaultCandidates(
31776
- trimmed,
31777
- ctx.vaultCtx,
31778
- ctx.embeddingOptions,
31779
- ctx.vaultCache,
31780
- {
31781
- limit: Math.max(options.consolidateTopK ?? DEFAULT_CONSOLIDATE_TOP_K, 1),
31782
- useFusion: false,
31783
- scopes: [resolvedScope],
31784
- includeArchived: true,
31785
- ...options.folderId !== void 0 && { folderId: options.folderId }
31786
- }
31787
- );
31816
+ prepared = await ctx.persistence.prepare(trimmed, {
31817
+ limit: Math.max(options.consolidateTopK ?? DEFAULT_CONSOLIDATE_TOP_K, 1),
31818
+ useFusion: false,
31819
+ scopes: [resolvedScope],
31820
+ includeArchived: true,
31821
+ ...options.folderId !== void 0 && { folderId: options.folderId }
31822
+ });
31788
31823
  if (prepared.embeddingFailure || prepared.embeddingsUnavailable) {
31789
31824
  throw new Error(
31790
31825
  "retain: embeddings unavailable \u2014 refusing to auto-merge against an inert cosine lane, which would create a duplicate instead of merging into the existing memory. Retry when embeddings recover, or pass enableAutoMerge: false to force a create."
@@ -31815,7 +31850,7 @@ async function retain(content, ctx, options = {}) {
31815
31850
  );
31816
31851
  if (matches.length > 0) {
31817
31852
  const targetId = matches[0].uniqueId;
31818
- const existing = await getVaultMemoryOp(ctx.vaultCtx, targetId);
31853
+ const existing = await ctx.persistence.get(targetId);
31819
31854
  if (existing && !existing.supersededBy) {
31820
31855
  const mergedSourceIds = unionStrings(
31821
31856
  existing.sourceChunkIds ?? [],
@@ -31824,7 +31859,7 @@ async function retain(content, ctx, options = {}) {
31824
31859
  const eventTimeUpdate = pickEventTimeUpdate(existing, options.eventTime);
31825
31860
  const factTypeUpdate = pickFactTypeUpdate(existing, options.factType);
31826
31861
  const resurrect = resurrectFields(existing);
31827
- const updated = await updateVaultMemoryOp(ctx.vaultCtx, targetId, {
31862
+ const updated = await ctx.persistence.update(targetId, {
31828
31863
  content: existing.content,
31829
31864
  proofCountIncrement: 1,
31830
31865
  observationSourceIds: options.sourceChunkIds,
@@ -31851,7 +31886,8 @@ async function retain(content, ctx, options = {}) {
31851
31886
  }
31852
31887
  const contentToWrite = supersedeContent ?? trimmed;
31853
31888
  const reusableQueryEmbedding = supersedeContent === void 0 && prepared && prepared.queryEmbedding.length > 0 ? prepared.queryEmbedding : void 0;
31854
- const embedding = reusableQueryEmbedding ?? await generateEmbedding(contentToWrite, ctx.embeddingOptions);
31889
+ const generatedEmbedding = reusableQueryEmbedding ?? await generateEmbedding(contentToWrite, ctx.embeddingOptions);
31890
+ const embedding = ctx.normalizeEmbedding?.(generatedEmbedding) ?? generatedEmbedding;
31855
31891
  const embeddingModel = ctx.embeddingOptions.model ?? DEFAULT_API_EMBEDDING_MODEL;
31856
31892
  if (options.respectTombstones) {
31857
31893
  const tombstone = await findTombstoneMatch(embedding, embeddingModel, resolvedScope, ctx, {
@@ -31891,8 +31927,7 @@ async function retain(content, ctx, options = {}) {
31891
31927
  };
31892
31928
  if (supersedeTargetIds.length > 0) {
31893
31929
  const [primaryTargetId, ...restTargetIds] = supersedeTargetIds;
31894
- const { created: created2, retired } = await createSupersedingMemoryOp(
31895
- ctx.vaultCtx,
31930
+ const { created: created2, retired } = await ctx.persistence.createSuperseding(
31896
31931
  createOpts,
31897
31932
  primaryTargetId
31898
31933
  );
@@ -31908,11 +31943,11 @@ async function retain(content, ctx, options = {}) {
31908
31943
  for (const staleId of restTargetIds) {
31909
31944
  let ok = false;
31910
31945
  try {
31911
- ok = await supersedeVaultMemoryOp(ctx.vaultCtx, staleId, created2.uniqueId) === true;
31946
+ ok = await ctx.persistence.supersede(staleId, created2.uniqueId) === true;
31912
31947
  } catch {
31913
31948
  }
31914
31949
  if (ok) continue;
31915
- const stillLive = await getVaultMemoryOp(ctx.vaultCtx, staleId).catch(() => null);
31950
+ const stillLive = await (ctx.persistence.getFresh ? ctx.persistence.getFresh(staleId) : ctx.persistence.get(staleId)).catch(() => null);
31916
31951
  if (stillLive && !stillLive.supersededBy) liveLeftovers.push(staleId);
31917
31952
  }
31918
31953
  if (liveLeftovers.length > 0) {
@@ -31939,7 +31974,7 @@ async function retain(content, ctx, options = {}) {
31939
31974
  `supersede: primary target ${primaryTargetId} retired or deleted inside the atomic write`
31940
31975
  );
31941
31976
  }
31942
- const created = await createVaultMemoryOp(ctx.vaultCtx, createOpts);
31977
+ const created = await ctx.persistence.create(createOpts);
31943
31978
  cacheRowVector(
31944
31979
  ctx.vaultCache,
31945
31980
  created.uniqueId,
@@ -31958,11 +31993,7 @@ function unionStrings(a, b) {
31958
31993
  return [.../* @__PURE__ */ new Set([...a, ...b])];
31959
31994
  }
31960
31995
  async function findTombstoneMatch(embedding, embeddingModel, scope, ctx, opts) {
31961
- const rows = await getAllVaultMemoriesOp(ctx.vaultCtx, {
31962
- includeDeleted: true,
31963
- scopes: [scope],
31964
- ...opts.folderId !== void 0 && { folderId: opts.folderId }
31965
- });
31996
+ const rows = await ctx.persistence.tombstones(embedding, embeddingModel, scope, opts.folderId);
31966
31997
  let bestId = null;
31967
31998
  let bestSim = opts.threshold;
31968
31999
  for (const row of rows) {
@@ -32029,7 +32060,7 @@ async function tryConsolidate(trimmed, ctx, options, prepared) {
32029
32060
  if (requestedIds.length === 0) return null;
32030
32061
  const valid = [];
32031
32062
  for (const id of requestedIds) {
32032
- const existing = await getVaultMemoryOp(ctx.vaultCtx, id);
32063
+ const existing = await ctx.persistence.get(id);
32033
32064
  if (existing && !existing.supersededBy) valid.push(id);
32034
32065
  }
32035
32066
  if (valid.length === 0) {
@@ -32041,7 +32072,7 @@ async function tryConsolidate(trimmed, ctx, options, prepared) {
32041
32072
  return { supersede: valid, content: decision.content };
32042
32073
  }
32043
32074
  if (decision.action === "noop" && decision.targetId) {
32044
- const existing = await getVaultMemoryOp(ctx.vaultCtx, decision.targetId);
32075
+ const existing = await ctx.persistence.get(decision.targetId);
32045
32076
  if (!existing || existing.supersededBy) {
32046
32077
  return abandonToRace(
32047
32078
  options,
@@ -32055,7 +32086,7 @@ async function tryConsolidate(trimmed, ctx, options, prepared) {
32055
32086
  const eventTimeUpdate = pickEventTimeUpdate(existing, options.eventTime);
32056
32087
  const factTypeUpdate = pickFactTypeUpdate(existing, options.factType);
32057
32088
  const resurrect = resurrectFields(existing);
32058
- const updated = await updateVaultMemoryOp(ctx.vaultCtx, decision.targetId, {
32089
+ const updated = await ctx.persistence.update(decision.targetId, {
32059
32090
  content: existing.content,
32060
32091
  proofCountIncrement: 1,
32061
32092
  observationSourceIds: options.sourceChunkIds,
@@ -32083,7 +32114,7 @@ async function tryConsolidate(trimmed, ctx, options, prepared) {
32083
32114
  };
32084
32115
  }
32085
32116
  if (decision.action === "update" && decision.targetId && decision.content) {
32086
- const existing = await getVaultMemoryOp(ctx.vaultCtx, decision.targetId);
32117
+ const existing = await ctx.persistence.get(decision.targetId);
32087
32118
  if (!existing || existing.supersededBy) {
32088
32119
  return abandonToRace(
32089
32120
  options,
@@ -32094,12 +32125,13 @@ async function tryConsolidate(trimmed, ctx, options, prepared) {
32094
32125
  existing.sourceChunkIds ?? [],
32095
32126
  options.sourceChunkIds ?? []
32096
32127
  );
32097
- const newEmbedding = await generateEmbedding(decision.content, ctx.embeddingOptions);
32128
+ const generatedEmbedding = await generateEmbedding(decision.content, ctx.embeddingOptions);
32129
+ const newEmbedding = ctx.normalizeEmbedding?.(generatedEmbedding) ?? generatedEmbedding;
32098
32130
  const consolidatedModel = ctx.embeddingOptions.model ?? DEFAULT_API_EMBEDDING_MODEL;
32099
32131
  const eventTimeUpdate = pickEventTimeUpdate(existing, options.eventTime);
32100
32132
  const factTypeUpdate = pickFactTypeUpdate(existing, options.factType);
32101
32133
  const resurrect = resurrectFields(existing);
32102
- const updated = await updateVaultMemoryOp(ctx.vaultCtx, decision.targetId, {
32134
+ const updated = await ctx.persistence.update(decision.targetId, {
32103
32135
  content: decision.content,
32104
32136
  proofCountIncrement: 1,
32105
32137
  observationSourceIds: options.sourceChunkIds,
@@ -32143,7 +32175,7 @@ async function tryConsolidate(trimmed, ctx, options, prepared) {
32143
32175
  return null;
32144
32176
  }
32145
32177
  async function assertMergeTargetGoneOrThrow(ctx, targetId) {
32146
- const stillExists = await getVaultMemoryOp(ctx.vaultCtx, targetId);
32178
+ const stillExists = await (ctx.persistence.getFresh ? ctx.persistence.getFresh(targetId) : ctx.persistence.get(targetId));
32147
32179
  if (stillExists) {
32148
32180
  throw new Error(`retain: merge into memory ${targetId} failed to persist`);
32149
32181
  }
@@ -33642,7 +33674,7 @@ async function recall(query, ctx, options = {}) {
33642
33674
  if (graphLaneFailed) degraded.push("graph-lane-failed");
33643
33675
  if (temporalLaneFailed) degraded.push("temporal-lane-failed");
33644
33676
  if (chunksScopeRestricted) degraded.push("chunks-scope-restricted");
33645
- const laneRan = types.includes("fact") && !!ctx.vaultCtx && !!ctx.vaultCache || types.includes("chunk") && !!ctx.storageCtx || chunksScopeRestricted && !!ctx.storageCtx;
33677
+ const laneRan = types.includes("fact") && (!!ctx.factSource || !!ctx.vaultCtx && !!ctx.vaultCache) || types.includes("chunk") && !!ctx.storageCtx || chunksScopeRestricted && !!ctx.storageCtx;
33646
33678
  const scores = admitted.map((m) => m.score);
33647
33679
  const minScoreApplied = factResults.length > 0 ? factFloor : chunkResults.length > 0 ? chunkFloor : factFloor >= 0 ? factFloor : chunkFloor;
33648
33680
  const diagnostics = {
@@ -33684,7 +33716,7 @@ async function recall(query, ctx, options = {}) {
33684
33716
  return { memories: [], usedBudget, reranked: false, candidateCount: 0 };
33685
33717
  }
33686
33718
  const needsChunkEmbedding = types.includes("chunk") && ctx.storageCtx;
33687
- const wantsTemporal = types.includes("fact") && ctx.vaultCtx;
33719
+ const wantsTemporal = types.includes("fact") && (ctx.factSource || ctx.vaultCtx);
33688
33720
  const graphRefiner = flags.traverse && options.graphRefine && options.decomposeOptions ? createLlmNeighborRefiner(options.decomposeOptions) : void 0;
33689
33721
  const queryEmbedTotalTimeoutMs = options.queryEmbedTotalTimeoutMs ?? DEFAULT_QUERY_EMBED_TOTAL_TIMEOUT_MS;
33690
33722
  const prepStart = nowMs2();
@@ -33714,7 +33746,7 @@ async function recall(query, ctx, options = {}) {
33714
33746
  safeLane(
33715
33747
  "graph",
33716
33748
  () => graphLaneFailed = true,
33717
- () => buildGraphLaneRanking(query, ctx, flags.traverse, {
33749
+ () => ctx.factSource ? ctx.factSource.graphRanking(query, flags.traverse, options) : buildGraphLaneRanking(query, ctx, flags.traverse, {
33718
33750
  ...options.maxHops !== void 0 && { maxHops: options.maxHops },
33719
33751
  ...options.entityFanout !== void 0 && { entityFanout: options.entityFanout },
33720
33752
  ...options.nodeBudget !== void 0 && { nodeBudget: options.nodeBudget },
@@ -33725,13 +33757,13 @@ async function recall(query, ctx, options = {}) {
33725
33757
  wantsTemporal ? safeLane(
33726
33758
  "temporal",
33727
33759
  () => temporalLaneFailed = true,
33728
- () => buildTemporalLaneRanking(query, ctx.vaultCtx, options.now)
33760
+ () => ctx.factSource ? ctx.factSource.temporalRanking(query, options.now) : buildTemporalLaneRanking(query, ctx.vaultCtx, options.now)
33729
33761
  ) : Promise.resolve([])
33730
33762
  ]);
33731
33763
  prepMs = nowMs2() - prepStart;
33732
33764
  graphLaneCount = entityRanking.length;
33733
33765
  temporalLaneCount = temporalRanking.length;
33734
- if (types.includes("fact") && ctx.vaultCtx && ctx.vaultCache) {
33766
+ if (types.includes("fact") && (ctx.factSource || ctx.vaultCtx && ctx.vaultCache)) {
33735
33767
  const factStart = nowMs2();
33736
33768
  const vaultMinScore = options.minScore ?? DEFAULT_FACT_MIN_SCORE;
33737
33769
  factFloor = vaultMinScore;
@@ -33747,50 +33779,50 @@ async function recall(query, ctx, options = {}) {
33747
33779
  rankedOnCosine: factRankedOnCosine,
33748
33780
  decryptLast: factDecryptLast,
33749
33781
  rowsDecrypted: factRowsDecrypted
33750
- } = await searchVaultMemoriesWithSize(
33751
- query,
33782
+ } = await (ctx.factSource?.search.bind(ctx.factSource) ?? ((searchQuery, searchOptions) => searchVaultMemoriesWithSize(
33783
+ searchQuery,
33752
33784
  ctx.vaultCtx,
33753
33785
  ctx.embeddingOptions,
33754
33786
  ctx.vaultCache,
33755
- {
33756
- limit: types.includes("chunk") ? Math.max(limit * 2, 16) : limit,
33757
- minSimilarity: vaultMinScore,
33758
- useFusion: true,
33759
- rerank: flags.rerank,
33760
- ...options.rerankTopN !== void 0 && { rerankTopN: options.rerankTopN },
33761
- ...options.ceWeight !== void 0 && { ceWeight: options.ceWeight },
33762
- ...options.rerankLoadTimeoutMs !== void 0 && {
33763
- rerankLoadTimeoutMs: options.rerankLoadTimeoutMs
33764
- },
33765
- ...options.recencyAlpha !== void 0 && { recencyAlpha: options.recencyAlpha },
33766
- ...options.recency && { recency: options.recency },
33767
- ...options.mmr !== void 0 && { mmr: options.mmr },
33768
- ...options.supersessionBoost !== void 0 && {
33769
- supersessionBoost: options.supersessionBoost
33770
- },
33771
- ...options.supersessionWindow !== void 0 && {
33772
- supersessionWindow: options.supersessionWindow
33773
- },
33774
- ...options.proofCountAlpha !== void 0 && {
33775
- proofCountAlpha: options.proofCountAlpha
33776
- },
33777
- ...options.bm25AdmissionDivisor !== void 0 && {
33778
- bm25AdmissionDivisor: options.bm25AdmissionDivisor
33779
- },
33780
- ...options.rrfK !== void 0 && { rrfK: options.rrfK },
33781
- ...options.decryptLast !== void 0 && { decryptLast: options.decryptLast },
33782
- ...subQueries && { subQueries },
33783
- ...options.scopes && { scopes: options.scopes },
33784
- ...options.folderId !== void 0 && { folderId: options.folderId },
33785
- ...options.factTypes?.length && { factTypes: options.factTypes },
33786
- ...options.memoryIds !== void 0 && { memoryIds: options.memoryIds },
33787
- ...options.factTypeWeights && { factTypeWeights: options.factTypeWeights },
33788
- ...entityRanking.length > 0 && { entityRanking },
33789
- ...temporalRanking.length > 0 && { temporalRanking },
33790
- ...needsChunkEmbedding && { queryEmbedding: queryEmbedding ?? [] },
33791
- queryEmbedTotalTimeoutMs
33792
- }
33793
- );
33787
+ searchOptions
33788
+ )))(query, {
33789
+ limit: types.includes("chunk") ? Math.max(limit * 2, 16) : limit,
33790
+ minSimilarity: vaultMinScore,
33791
+ useFusion: true,
33792
+ rerank: flags.rerank,
33793
+ ...options.rerankTopN !== void 0 && { rerankTopN: options.rerankTopN },
33794
+ ...options.ceWeight !== void 0 && { ceWeight: options.ceWeight },
33795
+ ...options.rerankLoadTimeoutMs !== void 0 && {
33796
+ rerankLoadTimeoutMs: options.rerankLoadTimeoutMs
33797
+ },
33798
+ ...options.recencyAlpha !== void 0 && { recencyAlpha: options.recencyAlpha },
33799
+ ...options.recency && { recency: options.recency },
33800
+ ...options.mmr !== void 0 && { mmr: options.mmr },
33801
+ ...options.supersessionBoost !== void 0 && {
33802
+ supersessionBoost: options.supersessionBoost
33803
+ },
33804
+ ...options.supersessionWindow !== void 0 && {
33805
+ supersessionWindow: options.supersessionWindow
33806
+ },
33807
+ ...options.proofCountAlpha !== void 0 && {
33808
+ proofCountAlpha: options.proofCountAlpha
33809
+ },
33810
+ ...options.bm25AdmissionDivisor !== void 0 && {
33811
+ bm25AdmissionDivisor: options.bm25AdmissionDivisor
33812
+ },
33813
+ ...options.rrfK !== void 0 && { rrfK: options.rrfK },
33814
+ ...options.decryptLast !== void 0 && { decryptLast: options.decryptLast },
33815
+ ...subQueries && { subQueries },
33816
+ ...options.scopes && { scopes: options.scopes },
33817
+ ...options.folderId !== void 0 && { folderId: options.folderId },
33818
+ ...options.factTypes?.length && { factTypes: options.factTypes },
33819
+ ...options.memoryIds !== void 0 && { memoryIds: options.memoryIds },
33820
+ ...options.factTypeWeights && { factTypeWeights: options.factTypeWeights },
33821
+ ...entityRanking.length > 0 && { entityRanking },
33822
+ ...temporalRanking.length > 0 && { temporalRanking },
33823
+ ...needsChunkEmbedding && { queryEmbedding: queryEmbedding ?? [] },
33824
+ queryEmbedTotalTimeoutMs
33825
+ });
33794
33826
  factResults.push(
33795
33827
  ...dedupeBy(
33796
33828
  results,
@@ -1227,13 +1227,13 @@ interface EmbeddingOptions {
1227
1227
  */
1228
1228
  tokenTimeoutMs?: number;
1229
1229
  /**
1230
- * Overall deadline, in ms, for one `generateEmbedding` call — the token read,
1230
+ * Overall deadline, in ms, for one `generateEmbedding` or `generateEmbeddings` call — the token read,
1231
1231
  * every retry attempt and the backoff between them. Unset (the default) means
1232
1232
  * only the per-attempt deadlines apply, which is right for background/bulk
1233
1233
  * embeds. The recall query path sets it (see
1234
1234
  * `RecallOptions.queryEmbedTotalTimeoutMs`) so an outage degrades a turn to
1235
- * BM25 within a few seconds instead of ~4 x `timeoutMs`. Not applied by
1236
- * `generateEmbeddings`.
1235
+ * BM25 within a few seconds instead of ~4 x `timeoutMs`. Batch calls share
1236
+ * one budget across authentication, all chunks, retries and backoff.
1237
1237
  */
1238
1238
  totalTimeoutMs?: number;
1239
1239
  }
@@ -5998,6 +5998,55 @@ interface VaultSearchResult {
5998
5998
  * these to suppress the originating chunk in the chunk lane. */
5999
5999
  sourceChunkIds?: string[] | null;
6000
6000
  }
6001
+ /**
6002
+ * Search + rank in one call. Thin wrapper over {@link prepareVaultCandidates} +
6003
+ * {@link rankPreparedVaultCandidates}; behavior is unchanged.
6004
+ */
6005
+ declare function searchVaultMemoriesWithSize(query: string, vaultCtx: VaultMemoryOperationsContext, embeddingOptions: EmbeddingOptions, cache: VaultEmbeddingCache, searchOptions?: MemoryVaultSearchOptions): Promise<{
6006
+ results: VaultSearchResult[];
6007
+ vaultSize: number;
6008
+ reranked: boolean;
6009
+ /**
6010
+ * Wall-clock ms this search spent inside the cross-encoder.
6011
+ *
6012
+ * 0 on every path that did not reach the CE, which `reranked` already
6013
+ * distinguishes from "ran and cost nothing". Reported because `factLane`
6014
+ * timing alone could not separate the rerank from the query embed, the vault
6015
+ * read and the fused ranking — see {@link RerankStats}.
6016
+ */
6017
+ rerankMs: number;
6018
+ hadV2Head: boolean;
6019
+ /** True when this search had no usable cosine lane and ranked on BM25 alone. */
6020
+ embeddingsUnavailable: boolean;
6021
+ /**
6022
+ * True when this search actually scored rows against a real query vector.
6023
+ *
6024
+ * NOT the inverse of `embeddingsUnavailable`. That flag answers "did cosine
6025
+ * break?", and it is `false` on the degenerate returns below — an invalid
6026
+ * query, an empty scope, nothing decryptable — where cosine did not break so
6027
+ * much as never run. A caller asking "can this lane vouch that semantic
6028
+ * ranking happened?" (recall's chunk-lane reconciliation) must not read those
6029
+ * as a healthy cosine pass.
6030
+ */
6031
+ rankedOnCosine: boolean;
6032
+ /**
6033
+ * Which vault read path ran — projected key scan (`true`) or legacy whole-vault
6034
+ * load (`false`). See {@link PreparedVaultCandidates.decryptLast}.
6035
+ */
6036
+ decryptLast: boolean;
6037
+ /**
6038
+ * Rows this search paid to decrypt. Read against `vaultSize` — see
6039
+ * {@link PreparedVaultCandidates.rowsDecrypted}.
6040
+ */
6041
+ rowsDecrypted: number;
6042
+ /**
6043
+ * Wall-clock ms spent embedding the query, and rows the lane had to re-embed
6044
+ * because their stored vector was unusable — see
6045
+ * {@link PreparedVaultCandidates.queryEmbedMs} and `rowsEmbedded`.
6046
+ */
6047
+ queryEmbedMs: number;
6048
+ rowsEmbedded: number;
6049
+ }>;
6001
6050
  /**
6002
6051
  * Search vault memories by semantic similarity. Returns structured results
6003
6052
  * sorted by descending similarity, filtered by threshold and limit.
@@ -6262,7 +6311,15 @@ interface RecallOptions {
6262
6311
  */
6263
6312
  graphRefine?: boolean;
6264
6313
  }
6314
+ /** A fact source supplies bounded candidates; recall owns ranking and result handling. */
6315
+ interface RecallFactSource {
6316
+ search: (query: string, options?: MemoryVaultSearchOptions) => ReturnType<typeof searchVaultMemoriesWithSize>;
6317
+ graphRanking: (query: string, traverse: boolean, options: RecallOptions) => Promise<string[]>;
6318
+ temporalRanking: (query: string, now?: number) => Promise<string[]>;
6319
+ }
6265
6320
  interface RecallContext {
6321
+ /** Alternative to a WatermelonDB vault for fact-only recall. */
6322
+ factSource?: RecallFactSource;
6266
6323
  /** Required when `types` includes 'fact'. */
6267
6324
  vaultCtx?: VaultMemoryOperationsContext;
6268
6325
  /** Required when `types` includes 'chunk'. */
@@ -10606,6 +10663,23 @@ interface PostgreSQLAdapterOptions {
10606
10663
  * @param pgSchema - PostgreSQL schema namespace (defaults to "public")
10607
10664
  */
10608
10665
  declare function schemaToCreateSQL(schema: AppSchema, pgSchema?: string): string[];
10666
+ /**
10667
+ * WatermelonDB `DatabaseAdapter` backed by any `pg.Pool`-compatible pool, so SDK operations run unchanged on the server.
10668
+ *
10669
+ * @example
10670
+ * ```typescript
10671
+ * import pg from "pg";
10672
+ * import { PostgreSQLAdapter, sdkSchema, sdkMigrations } from "@anuma/sdk/server";
10673
+ *
10674
+ * const pool = new pg.Pool({ connectionString: process.env.DATABASE_URL });
10675
+ * const adapter = new PostgreSQLAdapter({
10676
+ * pool,
10677
+ * schema: sdkSchema,
10678
+ * migrations: sdkMigrations,
10679
+ * dbName: "anuma-server-wallet123",
10680
+ * });
10681
+ * ```
10682
+ */
10609
10683
  declare class PostgreSQLAdapter implements DatabaseAdapter {
10610
10684
  schema: AppSchema;
10611
10685
  dbName: string;
@@ -1227,13 +1227,13 @@ interface EmbeddingOptions {
1227
1227
  */
1228
1228
  tokenTimeoutMs?: number;
1229
1229
  /**
1230
- * Overall deadline, in ms, for one `generateEmbedding` call — the token read,
1230
+ * Overall deadline, in ms, for one `generateEmbedding` or `generateEmbeddings` call — the token read,
1231
1231
  * every retry attempt and the backoff between them. Unset (the default) means
1232
1232
  * only the per-attempt deadlines apply, which is right for background/bulk
1233
1233
  * embeds. The recall query path sets it (see
1234
1234
  * `RecallOptions.queryEmbedTotalTimeoutMs`) so an outage degrades a turn to
1235
- * BM25 within a few seconds instead of ~4 x `timeoutMs`. Not applied by
1236
- * `generateEmbeddings`.
1235
+ * BM25 within a few seconds instead of ~4 x `timeoutMs`. Batch calls share
1236
+ * one budget across authentication, all chunks, retries and backoff.
1237
1237
  */
1238
1238
  totalTimeoutMs?: number;
1239
1239
  }
@@ -5998,6 +5998,55 @@ interface VaultSearchResult {
5998
5998
  * these to suppress the originating chunk in the chunk lane. */
5999
5999
  sourceChunkIds?: string[] | null;
6000
6000
  }
6001
+ /**
6002
+ * Search + rank in one call. Thin wrapper over {@link prepareVaultCandidates} +
6003
+ * {@link rankPreparedVaultCandidates}; behavior is unchanged.
6004
+ */
6005
+ declare function searchVaultMemoriesWithSize(query: string, vaultCtx: VaultMemoryOperationsContext, embeddingOptions: EmbeddingOptions, cache: VaultEmbeddingCache, searchOptions?: MemoryVaultSearchOptions): Promise<{
6006
+ results: VaultSearchResult[];
6007
+ vaultSize: number;
6008
+ reranked: boolean;
6009
+ /**
6010
+ * Wall-clock ms this search spent inside the cross-encoder.
6011
+ *
6012
+ * 0 on every path that did not reach the CE, which `reranked` already
6013
+ * distinguishes from "ran and cost nothing". Reported because `factLane`
6014
+ * timing alone could not separate the rerank from the query embed, the vault
6015
+ * read and the fused ranking — see {@link RerankStats}.
6016
+ */
6017
+ rerankMs: number;
6018
+ hadV2Head: boolean;
6019
+ /** True when this search had no usable cosine lane and ranked on BM25 alone. */
6020
+ embeddingsUnavailable: boolean;
6021
+ /**
6022
+ * True when this search actually scored rows against a real query vector.
6023
+ *
6024
+ * NOT the inverse of `embeddingsUnavailable`. That flag answers "did cosine
6025
+ * break?", and it is `false` on the degenerate returns below — an invalid
6026
+ * query, an empty scope, nothing decryptable — where cosine did not break so
6027
+ * much as never run. A caller asking "can this lane vouch that semantic
6028
+ * ranking happened?" (recall's chunk-lane reconciliation) must not read those
6029
+ * as a healthy cosine pass.
6030
+ */
6031
+ rankedOnCosine: boolean;
6032
+ /**
6033
+ * Which vault read path ran — projected key scan (`true`) or legacy whole-vault
6034
+ * load (`false`). See {@link PreparedVaultCandidates.decryptLast}.
6035
+ */
6036
+ decryptLast: boolean;
6037
+ /**
6038
+ * Rows this search paid to decrypt. Read against `vaultSize` — see
6039
+ * {@link PreparedVaultCandidates.rowsDecrypted}.
6040
+ */
6041
+ rowsDecrypted: number;
6042
+ /**
6043
+ * Wall-clock ms spent embedding the query, and rows the lane had to re-embed
6044
+ * because their stored vector was unusable — see
6045
+ * {@link PreparedVaultCandidates.queryEmbedMs} and `rowsEmbedded`.
6046
+ */
6047
+ queryEmbedMs: number;
6048
+ rowsEmbedded: number;
6049
+ }>;
6001
6050
  /**
6002
6051
  * Search vault memories by semantic similarity. Returns structured results
6003
6052
  * sorted by descending similarity, filtered by threshold and limit.
@@ -6262,7 +6311,15 @@ interface RecallOptions {
6262
6311
  */
6263
6312
  graphRefine?: boolean;
6264
6313
  }
6314
+ /** A fact source supplies bounded candidates; recall owns ranking and result handling. */
6315
+ interface RecallFactSource {
6316
+ search: (query: string, options?: MemoryVaultSearchOptions) => ReturnType<typeof searchVaultMemoriesWithSize>;
6317
+ graphRanking: (query: string, traverse: boolean, options: RecallOptions) => Promise<string[]>;
6318
+ temporalRanking: (query: string, now?: number) => Promise<string[]>;
6319
+ }
6265
6320
  interface RecallContext {
6321
+ /** Alternative to a WatermelonDB vault for fact-only recall. */
6322
+ factSource?: RecallFactSource;
6266
6323
  /** Required when `types` includes 'fact'. */
6267
6324
  vaultCtx?: VaultMemoryOperationsContext;
6268
6325
  /** Required when `types` includes 'chunk'. */
@@ -10606,6 +10663,23 @@ interface PostgreSQLAdapterOptions {
10606
10663
  * @param pgSchema - PostgreSQL schema namespace (defaults to "public")
10607
10664
  */
10608
10665
  declare function schemaToCreateSQL(schema: AppSchema, pgSchema?: string): string[];
10666
+ /**
10667
+ * WatermelonDB `DatabaseAdapter` backed by any `pg.Pool`-compatible pool, so SDK operations run unchanged on the server.
10668
+ *
10669
+ * @example
10670
+ * ```typescript
10671
+ * import pg from "pg";
10672
+ * import { PostgreSQLAdapter, sdkSchema, sdkMigrations } from "@anuma/sdk/server";
10673
+ *
10674
+ * const pool = new pg.Pool({ connectionString: process.env.DATABASE_URL });
10675
+ * const adapter = new PostgreSQLAdapter({
10676
+ * pool,
10677
+ * schema: sdkSchema,
10678
+ * migrations: sdkMigrations,
10679
+ * dbName: "anuma-server-wallet123",
10680
+ * });
10681
+ * ```
10682
+ */
10609
10683
  declare class PostgreSQLAdapter implements DatabaseAdapter {
10610
10684
  schema: AppSchema;
10611
10685
  dbName: string;