@anuma/sdk 9.1.4 → 9.1.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.
@@ -710,6 +710,12 @@ function assertTransportMatchesEndpoint(transport, endpoint) {
710
710
  `endpointOverride "${endpoint}" is the other transport's endpoint, but transport is "${transport}". The request body is built for the transport, so this sends the wrong shape and 400s without retry.`
711
711
  );
712
712
  }
713
+ var TIME_BUDGET_EXHAUSTED = {
714
+ kind: "terminal",
715
+ code: "time-budget-exhausted",
716
+ reason: "time budget exhausted"
717
+ };
718
+ var MAX_TIMER_DELAY_MS = 2147483647;
713
719
  var RETRYABLE_HTTP = /* @__PURE__ */ new Set([408, 409, 425, 429]);
714
720
  function isRetryableStatus(status) {
715
721
  return status >= 500 || RETRYABLE_HTTP.has(status);
@@ -765,7 +771,8 @@ async function callPortalJsonCompletion(req) {
765
771
  }
766
772
  const maxAttempts = Math.max(1, req.maxAttempts ?? 3);
767
773
  const startedAt = Date.now();
768
- const overBudget = () => req.totalTimeoutMs !== void 0 && Date.now() - startedAt >= req.totalTimeoutMs;
774
+ const deadlineAt = req.totalTimeoutMs === void 0 ? void 0 : startedAt + req.totalTimeoutMs;
775
+ const overBudget = () => deadlineAt !== void 0 && Date.now() >= deadlineAt;
769
776
  let lastFailure;
770
777
  let reinforce = false;
771
778
  const giveUp = () => {
@@ -778,17 +785,11 @@ async function callPortalJsonCompletion(req) {
778
785
  lastFailure = { reason: "time-budget-exhausted", attempts: attempt - 1 };
779
786
  break;
780
787
  }
781
- const attemptReq = req.totalTimeoutMs !== void 0 ? {
782
- ...req,
783
- timeoutMs: Math.max(
784
- 1,
785
- Math.min(req.timeoutMs ?? 6e4, req.totalTimeoutMs - (Date.now() - startedAt))
786
- ),
787
- ...reinforce && { reinforceJsonContract: true }
788
- } : reinforce ? { ...req, reinforceJsonContract: true } : req;
788
+ const attemptReq = reinforce ? { ...req, reinforceJsonContract: true } : req;
789
789
  const outcome = await attemptPortalJson(
790
790
  { ...attemptReq, transport },
791
- endpoint
791
+ endpoint,
792
+ deadlineAt
792
793
  );
793
794
  if (outcome.kind === "ok") {
794
795
  req.onAttempt?.({ attempt, ok: true });
@@ -828,13 +829,38 @@ async function callPortalJsonCompletion(req) {
828
829
  }
829
830
  return giveUp();
830
831
  }
831
- async function attemptPortalJson(req, endpoint) {
832
+ async function attemptPortalJson(req, endpoint, deadlineAt) {
833
+ const controller = new AbortController();
834
+ if (deadlineAt === void 0 || deadlineAt - Date.now() > MAX_TIMER_DELAY_MS) {
835
+ return requestPortalJson(req, endpoint, controller);
836
+ }
837
+ const remainingMs = deadlineAt - Date.now();
838
+ if (remainingMs <= 0) return TIME_BUDGET_EXHAUSTED;
839
+ let timer;
840
+ try {
841
+ const outcome = await Promise.race([
842
+ new Promise((resolve) => {
843
+ timer = setTimeout(() => {
844
+ resolve(TIME_BUDGET_EXHAUSTED);
845
+ controller.abort();
846
+ }, remainingMs);
847
+ }),
848
+ requestPortalJson(req, endpoint, controller, deadlineAt)
849
+ ]);
850
+ return Date.now() >= deadlineAt ? TIME_BUDGET_EXHAUSTED : outcome;
851
+ } finally {
852
+ clearTimeout(timer);
853
+ }
854
+ }
855
+ async function requestPortalJson(req, endpoint, controller, deadlineAt) {
832
856
  const baseUrl = req.baseUrl ?? defaultBaseUrl();
833
857
  const fetchImpl = req.fetchFn ?? fetch;
834
- const timeoutMs = req.timeoutMs ?? 6e4;
835
858
  const authHeaders = await resolvePortalAuthHeaders(req, req.tag);
859
+ const remainingMs = deadlineAt === void 0 ? Infinity : deadlineAt - Date.now();
860
+ if (controller.signal.aborted || remainingMs <= 0) return TIME_BUDGET_EXHAUSTED;
836
861
  if (authHeaders === null)
837
862
  return { kind: "terminal", code: "auth-unavailable", reason: "auth unavailable (no token)" };
863
+ const timeoutMs = Math.min(req.timeoutMs ?? 6e4, remainingMs);
838
864
  const usesPrefill = req.transport !== "responses" && req.model.startsWith("anthropic/");
839
865
  const prefill = usesPrefill ? "{" : "";
840
866
  const messages = [
@@ -844,7 +870,6 @@ async function attemptPortalJson(req, endpoint) {
844
870
  ];
845
871
  if (prefill) messages.push({ role: "assistant", content: prefill });
846
872
  const supportsJsonObjectFormat = supportsResponseFormat(req.model);
847
- const controller = new AbortController();
848
873
  const timer = setTimeout(() => controller.abort(), timeoutMs);
849
874
  const requestBody = req.transport === "responses" ? {
850
875
  model: req.model,
@@ -4,7 +4,7 @@ import {
4
4
  notifyConsolidationFallback,
5
5
  requiresResponsesTransport,
6
6
  resolvePiiRedactor
7
- } from "./chunk-AU3Z7NBC.mjs";
7
+ } from "./chunk-QEROZ4VH.mjs";
8
8
  import "./chunk-3RPGXXPZ.mjs";
9
9
 
10
10
  // src/lib/memory/consolidate.ts
@@ -15742,7 +15742,8 @@ async function callPortalJsonCompletion(req) {
15742
15742
  }
15743
15743
  const maxAttempts = Math.max(1, req.maxAttempts ?? 3);
15744
15744
  const startedAt = Date.now();
15745
- const overBudget = () => req.totalTimeoutMs !== void 0 && Date.now() - startedAt >= req.totalTimeoutMs;
15745
+ const deadlineAt = req.totalTimeoutMs === void 0 ? void 0 : startedAt + req.totalTimeoutMs;
15746
+ const overBudget = () => deadlineAt !== void 0 && Date.now() >= deadlineAt;
15746
15747
  let lastFailure;
15747
15748
  let reinforce = false;
15748
15749
  const giveUp = () => {
@@ -15755,17 +15756,11 @@ async function callPortalJsonCompletion(req) {
15755
15756
  lastFailure = { reason: "time-budget-exhausted", attempts: attempt - 1 };
15756
15757
  break;
15757
15758
  }
15758
- const attemptReq = req.totalTimeoutMs !== void 0 ? {
15759
- ...req,
15760
- timeoutMs: Math.max(
15761
- 1,
15762
- Math.min(req.timeoutMs ?? 6e4, req.totalTimeoutMs - (Date.now() - startedAt))
15763
- ),
15764
- ...reinforce && { reinforceJsonContract: true }
15765
- } : reinforce ? { ...req, reinforceJsonContract: true } : req;
15759
+ const attemptReq = reinforce ? { ...req, reinforceJsonContract: true } : req;
15766
15760
  const outcome = await attemptPortalJson(
15767
15761
  { ...attemptReq, transport },
15768
- endpoint
15762
+ endpoint,
15763
+ deadlineAt
15769
15764
  );
15770
15765
  if (outcome.kind === "ok") {
15771
15766
  req.onAttempt?.({ attempt, ok: true });
@@ -15805,13 +15800,38 @@ async function callPortalJsonCompletion(req) {
15805
15800
  }
15806
15801
  return giveUp();
15807
15802
  }
15808
- async function attemptPortalJson(req, endpoint) {
15803
+ async function attemptPortalJson(req, endpoint, deadlineAt) {
15804
+ const controller = new AbortController();
15805
+ if (deadlineAt === void 0 || deadlineAt - Date.now() > MAX_TIMER_DELAY_MS) {
15806
+ return requestPortalJson(req, endpoint, controller);
15807
+ }
15808
+ const remainingMs = deadlineAt - Date.now();
15809
+ if (remainingMs <= 0) return TIME_BUDGET_EXHAUSTED;
15810
+ let timer;
15811
+ try {
15812
+ const outcome = await Promise.race([
15813
+ new Promise((resolve) => {
15814
+ timer = setTimeout(() => {
15815
+ resolve(TIME_BUDGET_EXHAUSTED);
15816
+ controller.abort();
15817
+ }, remainingMs);
15818
+ }),
15819
+ requestPortalJson(req, endpoint, controller, deadlineAt)
15820
+ ]);
15821
+ return Date.now() >= deadlineAt ? TIME_BUDGET_EXHAUSTED : outcome;
15822
+ } finally {
15823
+ clearTimeout(timer);
15824
+ }
15825
+ }
15826
+ async function requestPortalJson(req, endpoint, controller, deadlineAt) {
15809
15827
  const baseUrl = req.baseUrl ?? defaultBaseUrl();
15810
15828
  const fetchImpl = req.fetchFn ?? fetch;
15811
- const timeoutMs = req.timeoutMs ?? 6e4;
15812
15829
  const authHeaders = await resolvePortalAuthHeaders(req, req.tag);
15830
+ const remainingMs = deadlineAt === void 0 ? Infinity : deadlineAt - Date.now();
15831
+ if (controller.signal.aborted || remainingMs <= 0) return TIME_BUDGET_EXHAUSTED;
15813
15832
  if (authHeaders === null)
15814
15833
  return { kind: "terminal", code: "auth-unavailable", reason: "auth unavailable (no token)" };
15834
+ const timeoutMs = Math.min(req.timeoutMs ?? 6e4, remainingMs);
15815
15835
  const usesPrefill = req.transport !== "responses" && req.model.startsWith("anthropic/");
15816
15836
  const prefill = usesPrefill ? "{" : "";
15817
15837
  const messages = [
@@ -15821,7 +15841,6 @@ async function attemptPortalJson(req, endpoint) {
15821
15841
  ];
15822
15842
  if (prefill) messages.push({ role: "assistant", content: prefill });
15823
15843
  const supportsJsonObjectFormat = supportsResponseFormat(req.model);
15824
- const controller = new AbortController();
15825
15844
  const timer = setTimeout(() => controller.abort(), timeoutMs);
15826
15845
  const requestBody = req.transport === "responses" ? {
15827
15846
  model: req.model,
@@ -16006,7 +16025,7 @@ function extractResponsesContent(body) {
16006
16025
  const text12 = root.output.filter((item) => asRecord(item)?.type === "message").flatMap((item) => Array.isArray(item.content) ? item.content : []).map((part) => asRecord(part)?.text).filter((t) => typeof t === "string").join("");
16007
16026
  return text12;
16008
16027
  }
16009
- var RESPONSE_FORMAT_OK, RESPONSE_SCHEMA_OK, JSON_CONTRACT_REMINDER, RESPONSES_ONLY_MODEL_PREFIXES, CHAT_TO_RESPONSES_FIELDS, FOREIGN_ENDPOINT_SUFFIX, RETRYABLE_HTTP;
16028
+ var RESPONSE_FORMAT_OK, RESPONSE_SCHEMA_OK, JSON_CONTRACT_REMINDER, RESPONSES_ONLY_MODEL_PREFIXES, CHAT_TO_RESPONSES_FIELDS, FOREIGN_ENDPOINT_SUFFIX, TIME_BUDGET_EXHAUSTED, MAX_TIMER_DELAY_MS, RETRYABLE_HTTP;
16010
16029
  var init_portalLlm = __esm({
16011
16030
  "src/lib/memory/portalLlm.ts"() {
16012
16031
  "use strict";
@@ -16026,6 +16045,12 @@ var init_portalLlm = __esm({
16026
16045
  chat: "/responses",
16027
16046
  responses: "/chat/completions"
16028
16047
  };
16048
+ TIME_BUDGET_EXHAUSTED = {
16049
+ kind: "terminal",
16050
+ code: "time-budget-exhausted",
16051
+ reason: "time budget exhausted"
16052
+ };
16053
+ MAX_TIMER_DELAY_MS = 2147483647;
16029
16054
  RETRYABLE_HTTP = /* @__PURE__ */ new Set([408, 409, 425, 429]);
16030
16055
  }
16031
16056
  });
@@ -17323,15 +17348,16 @@ async function refreshEncryptionKeyIfMatches(walletAddress, probeCiphertext, sig
17323
17348
  if (!parsed) {
17324
17349
  return false;
17325
17350
  }
17351
+ const startEpoch = sessionEpoch;
17326
17352
  const cached = refreshCandidatesByAddress.get(walletAddress);
17327
17353
  if (cached) {
17328
- return tryCommitCandidatesIfProbeMatches(walletAddress, parsed, cached);
17354
+ return tryCommitCandidatesIfProbeMatches(walletAddress, parsed, cached, startEpoch);
17329
17355
  }
17330
17356
  let derivePromise = pendingCandidateDerives.get(walletAddress);
17331
17357
  if (!derivePromise) {
17332
17358
  derivePromise = (async () => {
17333
17359
  const candidates2 = await deriveRefreshCandidates(signMessage, embeddedWalletSigner);
17334
- if (candidates2) {
17360
+ if (candidates2 && sessionEpoch === startEpoch) {
17335
17361
  refreshCandidatesByAddress.set(walletAddress, candidates2);
17336
17362
  }
17337
17363
  return candidates2;
@@ -17343,10 +17369,10 @@ async function refreshEncryptionKeyIfMatches(walletAddress, probeCiphertext, sig
17343
17369
  pendingCandidateDerives.set(walletAddress, derivePromise);
17344
17370
  }
17345
17371
  const candidates = await derivePromise;
17346
- if (!candidates) {
17372
+ if (!candidates || sessionEpoch !== startEpoch) {
17347
17373
  return false;
17348
17374
  }
17349
- return tryCommitCandidatesIfProbeMatches(walletAddress, parsed, candidates);
17375
+ return tryCommitCandidatesIfProbeMatches(walletAddress, parsed, candidates, startEpoch);
17350
17376
  }
17351
17377
  function parsePrefixedCiphertext(probeCiphertext) {
17352
17378
  const version = probeCiphertext.startsWith("enc:v3:") ? "v3" : probeCiphertext.startsWith("enc:v2:") ? "v2" : null;
@@ -17389,7 +17415,7 @@ async function deriveRefreshCandidates(signMessage, embeddedWalletSigner) {
17389
17415
  }
17390
17416
  return { legacy: legacyKey, current: currentKey };
17391
17417
  }
17392
- async function tryCommitCandidatesIfProbeMatches(walletAddress, parsed, candidates) {
17418
+ async function tryCommitCandidatesIfProbeMatches(walletAddress, parsed, candidates, startEpoch) {
17393
17419
  const candidateHex = parsed.version === "v2" ? candidates.legacy : candidates.current;
17394
17420
  const keyBytes = hexToBytes(candidateHex);
17395
17421
  const candidateCryptoKey = await crypto.subtle.importKey(
@@ -17407,6 +17433,9 @@ async function tryCommitCandidatesIfProbeMatches(walletAddress, parsed, candidat
17407
17433
  );
17408
17434
  return false;
17409
17435
  }
17436
+ if (sessionEpoch !== startEpoch) {
17437
+ return false;
17438
+ }
17410
17439
  setStoredKey(walletAddress, { legacy: candidates.legacy, current: candidates.current });
17411
17440
  cryptoKeyCache.delete(`${walletAddress}:v2`);
17412
17441
  cryptoKeyCache.delete(`${walletAddress}:v3`);
@@ -29068,6 +29097,16 @@ async function updateVaultMemoryOp(ctx, id, opts) {
29068
29097
  const probe = await ctx.vaultMemoryCollection.find(id);
29069
29098
  if (probe.isDeleted || probe.supersededBy || !isOwnedByCtxUser(ctx, probe)) return null;
29070
29099
  if (opts.freeFormOnly && isKinded(probe)) return null;
29100
+ const readStoredContent = probe._getRaw("content");
29101
+ if (opts.expectedContent !== void 0) {
29102
+ const current = await vaultMemoryToStored(
29103
+ probe,
29104
+ ctx.walletAddress,
29105
+ ctx.signMessage,
29106
+ ctx.embeddedWalletSigner
29107
+ );
29108
+ if (current.content !== opts.expectedContent) return null;
29109
+ }
29071
29110
  const levelAfter = (current) => {
29072
29111
  if (opts.level !== void 0) return opts.level;
29073
29112
  if (opts.scope === void 0) return resolveMemoryLevel(current.level, current.scope);
@@ -29075,7 +29114,7 @@ async function updateVaultMemoryOp(ctx, id, opts) {
29075
29114
  };
29076
29115
  assertValidKindLevel(opts.kind !== void 0 ? opts.kind : probe.kind, levelAfter(probe));
29077
29116
  const encryptedKindValue = await encryptKindValue(ctx, opts.kindValue);
29078
- const encryptedContent = ctx.walletAddress && ctx.signMessage ? await encryptVaultMemoryContent(
29117
+ const encryptedContent = opts.content !== void 0 && ctx.walletAddress && ctx.signMessage ? await encryptVaultMemoryContent(
29079
29118
  opts.content,
29080
29119
  ctx.walletAddress,
29081
29120
  ctx.signMessage,
@@ -29083,13 +29122,13 @@ async function updateVaultMemoryOp(ctx, id, opts) {
29083
29122
  ) : opts.content;
29084
29123
  let stale = false;
29085
29124
  const record = probe;
29086
- const originalUpdatedAt = record.updatedAt.getTime();
29087
29125
  await ctx.database.write(async () => {
29088
29126
  await assertCanWrite2(ctx);
29089
- if (record.isDeleted || record.supersededBy || !isOwnedByCtxUser(ctx, record) || opts.freeFormOnly && isKinded(record)) {
29127
+ if (record.isDeleted || record.supersededBy || !isOwnedByCtxUser(ctx, record) || opts.freeFormOnly && isKinded(record) || opts.expectedContent !== void 0 && record._getRaw("content") !== readStoredContent) {
29090
29128
  stale = true;
29091
29129
  return;
29092
29130
  }
29131
+ const originalUpdatedAt = record.updatedAt.getTime();
29093
29132
  const nextKind = opts.kind !== void 0 ? opts.kind : record.kind;
29094
29133
  const nextLevel = levelAfter(record);
29095
29134
  assertValidKindLevel(nextKind, nextLevel);
@@ -29105,7 +29144,7 @@ async function updateVaultMemoryOp(ctx, id, opts) {
29105
29144
  replayedObservation = opts.observationSourceIds.every((id2) => observedSources.includes(id2));
29106
29145
  }
29107
29146
  await record.update((r) => {
29108
- r._setRaw("content", encryptedContent);
29147
+ if (encryptedContent !== void 0) r._setRaw("content", encryptedContent);
29109
29148
  if (opts.level !== void 0) {
29110
29149
  r._setRaw("level", nextLevel);
29111
29150
  r._setRaw("scope", scopeForLevel(nextLevel));
@@ -29873,7 +29912,7 @@ function classifyDecay(m, now, policy) {
29873
29912
  if (m.source === "manual" || m.source === SOURCE_PHOTO) return "keep";
29874
29913
  if (isTimeSensitiveType(m.factType) && m.eventTimeEnd !== null) {
29875
29914
  if (m.eventTimeEnd < now - resolved.pastEventGraceMs) return "archive";
29876
- if (m.eventTimeEnd >= now) return "keep";
29915
+ return "keep";
29877
29916
  }
29878
29917
  if (now - lastActivityAt(m) > ttlForType(m.factType, resolved)) return "archive";
29879
29918
  return "keep";
@@ -31550,6 +31589,104 @@ function validate(parsed, originalQuery) {
31550
31589
  return { mode, subQueries };
31551
31590
  }
31552
31591
 
31592
+ // src/lib/memoryVault/vaultPreparation.ts
31593
+ function createVaultPreparation() {
31594
+ return { corpora: /* @__PURE__ */ new WeakMap(), rows: /* @__PURE__ */ new WeakMap() };
31595
+ }
31596
+ var pendingRows = /* @__PURE__ */ new WeakMap();
31597
+ function loadVaultCorpus(ctx, options, preparation) {
31598
+ if (!preparation) return getAllVaultMemoriesOp(ctx, options);
31599
+ const corpusCache = preparation.corpora;
31600
+ let pending = corpusCache.get(ctx);
31601
+ if (!pending) {
31602
+ pending = /* @__PURE__ */ new Map();
31603
+ corpusCache.set(ctx, pending);
31604
+ }
31605
+ const key = JSON.stringify(options ?? {});
31606
+ let request = pending.get(key);
31607
+ if (!request) {
31608
+ const entries = pending;
31609
+ request = getAllVaultMemoriesOp(ctx, options).catch((error) => {
31610
+ entries.delete(key);
31611
+ throw error;
31612
+ });
31613
+ pending.set(key, request);
31614
+ }
31615
+ return request;
31616
+ }
31617
+ function rowRequestsFor(registry, ctx, maskInput) {
31618
+ let byMask = registry.get(ctx);
31619
+ if (!byMask) {
31620
+ byMask = /* @__PURE__ */ new Map();
31621
+ registry.set(ctx, byMask);
31622
+ }
31623
+ let requests = byMask.get(maskInput);
31624
+ if (!requests) {
31625
+ requests = /* @__PURE__ */ new Map();
31626
+ byMask.set(maskInput, requests);
31627
+ }
31628
+ return requests;
31629
+ }
31630
+ function embedVaultRows(ctx, options, rows, preparation) {
31631
+ const pending = rowRequestsFor(pendingRows, ctx, options.maskInput);
31632
+ const prepared = preparation && rowRequestsFor(preparation.rows, ctx, options.maskInput);
31633
+ const model = options.model ?? DEFAULT_API_EMBEDDING_MODEL;
31634
+ const keys = rows.map(
31635
+ (row) => JSON.stringify([
31636
+ row.uniqueId,
31637
+ row.updatedAt?.getTime(),
31638
+ row.content,
31639
+ model,
31640
+ options.baseUrl,
31641
+ options.timeoutMs,
31642
+ options.tokenTimeoutMs,
31643
+ options.totalTimeoutMs
31644
+ ])
31645
+ );
31646
+ const missing = /* @__PURE__ */ new Map();
31647
+ rows.forEach((row, index) => {
31648
+ if (!pending.has(keys[index]) && !prepared?.has(keys[index])) missing.set(keys[index], row);
31649
+ });
31650
+ if (missing.size > 0) {
31651
+ const entries = pending;
31652
+ const batch = Promise.resolve().then(
31653
+ () => generateEmbeddings(
31654
+ [...missing.values()].map((row) => row.content),
31655
+ options
31656
+ )
31657
+ );
31658
+ [...missing].forEach(([key, row], index) => {
31659
+ const request = batch.then((vectors) => {
31660
+ const vector = vectors[index];
31661
+ updateVaultMemoryEmbeddingOp(ctx, row.uniqueId, JSON.stringify(vector), model, {
31662
+ content: row.content,
31663
+ updatedAt: row.updatedAt?.getTime()
31664
+ }).catch(() => {
31665
+ });
31666
+ return vector;
31667
+ }).finally(() => {
31668
+ entries.delete(key);
31669
+ if (entries.size === 0) pendingRows.get(ctx)?.delete(options.maskInput);
31670
+ });
31671
+ pending.set(key, request);
31672
+ });
31673
+ }
31674
+ return Promise.all(
31675
+ keys.map((key) => {
31676
+ const cached = prepared?.get(key);
31677
+ if (cached) return cached;
31678
+ const request = pending.get(key);
31679
+ if (!prepared) return request;
31680
+ const retained = request.catch((error) => {
31681
+ prepared.delete(key);
31682
+ throw error;
31683
+ });
31684
+ prepared.set(key, retained);
31685
+ return retained;
31686
+ })
31687
+ );
31688
+ }
31689
+
31553
31690
  // src/lib/memoryVault/vectorVersion.ts
31554
31691
  var vectorRowVersion = /* @__PURE__ */ new WeakMap();
31555
31692
  function contentFingerprint(content) {
@@ -32112,11 +32249,11 @@ async function rankComposite(originalQuery, originalQueryEmbedding, subQueries,
32112
32249
  return combined.slice(0, limit);
32113
32250
  }
32114
32251
  async function preEmbedVaultMemories(vaultCtx, embeddingOptions, cache, options) {
32115
- const memories = await getAllVaultMemoriesOp(vaultCtx, options);
32252
+ const memories = await loadVaultCorpus(vaultCtx, options);
32116
32253
  const currentModel = embeddingOptions.model ?? DEFAULT_API_EMBEDDING_MODEL;
32117
32254
  const uncachedTexts = [];
32118
32255
  const uncachedKeys = [];
32119
- const uncachedIds = [];
32256
+ const uncachedRows = [];
32120
32257
  const uncachedVersions = [];
32121
32258
  for (const m of memories) {
32122
32259
  const content = m.content;
@@ -32135,12 +32272,12 @@ async function preEmbedVaultMemories(vaultCtx, embeddingOptions, cache, options)
32135
32272
  }
32136
32273
  uncachedTexts.push(m.content);
32137
32274
  uncachedKeys.push(m.uniqueId);
32138
- uncachedIds.push(m.uniqueId);
32275
+ uncachedRows.push(m);
32139
32276
  uncachedVersions.push(m.updatedAt);
32140
32277
  }
32141
32278
  }
32142
32279
  if (uncachedTexts.length > 0) {
32143
- const embeddings = await generateEmbeddings(uncachedTexts, embeddingOptions);
32280
+ const embeddings = await embedVaultRows(vaultCtx, embeddingOptions, uncachedRows);
32144
32281
  for (let i = 0; i < uncachedKeys.length; i++) {
32145
32282
  cacheRowVector(
32146
32283
  cache,
@@ -32149,13 +32286,6 @@ async function preEmbedVaultMemories(vaultCtx, embeddingOptions, cache, options)
32149
32286
  uncachedVersions[i],
32150
32287
  uncachedTexts[i]
32151
32288
  );
32152
- updateVaultMemoryEmbeddingOp(
32153
- vaultCtx,
32154
- uncachedIds[i],
32155
- JSON.stringify(embeddings[i]),
32156
- currentModel
32157
- ).catch(() => {
32158
- });
32159
32289
  }
32160
32290
  }
32161
32291
  }
@@ -32297,10 +32427,7 @@ async function buildProjectedCorpus(query, vaultCtx, embeddingOptions, cache, qu
32297
32427
  let laneVecs;
32298
32428
  if (opts.embedStats) opts.embedStats.rowsEmbedded += laneRows.length;
32299
32429
  try {
32300
- laneVecs = await generateEmbeddings(
32301
- laneRows.map((m) => m.content),
32302
- embeddingOptions
32303
- );
32430
+ laneVecs = await embedVaultRows(vaultCtx, embeddingOptions, laneRows);
32304
32431
  } catch (err) {
32305
32432
  laneEmbedFailed = true;
32306
32433
  getLogger().warn(
@@ -32314,13 +32441,6 @@ async function buildProjectedCorpus(query, vaultCtx, embeddingOptions, cache, qu
32314
32441
  cacheRowVector(cache, m.uniqueId, vec, m.updatedAt, m.content);
32315
32442
  resolvedThisCall.add(m.uniqueId);
32316
32443
  vectored.push({ uniqueId: m.uniqueId, embedding: vec, updatedAt: m.updatedAt });
32317
- updateVaultMemoryEmbeddingOp(
32318
- vaultCtx,
32319
- m.uniqueId,
32320
- JSON.stringify(vecs[i]),
32321
- currentModel
32322
- ).catch(() => {
32323
- });
32324
32444
  });
32325
32445
  }
32326
32446
  }
@@ -32512,9 +32632,10 @@ async function prepareVaultCandidates(query, vaultCtx, embeddingOptions, cache,
32512
32632
  };
32513
32633
  }
32514
32634
  } else {
32515
- const loaded = await getAllVaultMemoriesOp(
32635
+ const loaded = await loadVaultCorpus(
32516
32636
  vaultCtx,
32517
- Object.keys(queryOpts).length > 0 ? queryOpts : void 0
32637
+ Object.keys(queryOpts).length > 0 ? queryOpts : void 0,
32638
+ searchOptions?.vaultPreparation
32518
32639
  );
32519
32640
  vaultSize = loaded.length;
32520
32641
  rowsDecrypted = loaded.length;
@@ -32587,7 +32708,12 @@ async function prepareVaultCandidates(query, vaultCtx, embeddingOptions, cache,
32587
32708
  let newEmbeddings;
32588
32709
  embedStats.rowsEmbedded += uncachedTexts.length;
32589
32710
  try {
32590
- newEmbeddings = await generateEmbeddings(uncachedTexts, embeddingOptions);
32711
+ newEmbeddings = await embedVaultRows(
32712
+ vaultCtx,
32713
+ embeddingOptions,
32714
+ uncachedIndices.map((index) => memories[index]),
32715
+ searchOptions?.vaultPreparation
32716
+ );
32591
32717
  } catch (err) {
32592
32718
  embeddingFailure = true;
32593
32719
  getLogger().warn(
@@ -32603,13 +32729,6 @@ async function prepareVaultCandidates(query, vaultCtx, embeddingOptions, cache,
32603
32729
  memories[uncachedIndices[j]].updatedAt,
32604
32730
  memories[uncachedIndices[j]].content
32605
32731
  );
32606
- updateVaultMemoryEmbeddingOp(
32607
- vaultCtx,
32608
- memories[uncachedIndices[j]].uniqueId,
32609
- JSON.stringify(newEmbeddings[j]),
32610
- currentModel
32611
- ).catch(() => {
32612
- });
32613
32732
  }
32614
32733
  }
32615
32734
  }
@@ -33014,7 +33133,6 @@ async function retainWithPersistence(content, ctx, options = {}) {
33014
33133
  const factTypeUpdate = pickFactTypeUpdate(existing, options.factType);
33015
33134
  const resurrect = resurrectFields(existing);
33016
33135
  const updated = await ctx.persistence.update(targetId, {
33017
- content: existing.content,
33018
33136
  freeFormOnly: true,
33019
33137
  proofCountIncrement: 1,
33020
33138
  observationSourceIds: options.sourceChunkIds,
@@ -33253,7 +33371,6 @@ async function tryConsolidate(trimmed, ctx, options, prepared) {
33253
33371
  const factTypeUpdate = pickFactTypeUpdate(existing, options.factType);
33254
33372
  const resurrect = resurrectFields(existing);
33255
33373
  const updated = await ctx.persistence.update(decision.targetId, {
33256
- content: existing.content,
33257
33374
  freeFormOnly: true,
33258
33375
  proofCountIncrement: 1,
33259
33376
  observationSourceIds: options.sourceChunkIds,
@@ -33281,6 +33398,10 @@ async function tryConsolidate(trimmed, ctx, options, prepared) {
33281
33398
  };
33282
33399
  }
33283
33400
  if (decision.action === "update" && decision.targetId && decision.content) {
33401
+ const expectedContent = candidates.find(
33402
+ (candidate) => candidate.id === decision.targetId
33403
+ )?.content;
33404
+ if (expectedContent === void 0) return null;
33284
33405
  const existing = await ctx.persistence.get(decision.targetId);
33285
33406
  if (!existing || existing.supersededBy) {
33286
33407
  return abandonToRace(
@@ -33288,6 +33409,9 @@ async function tryConsolidate(trimmed, ctx, options, prepared) {
33288
33409
  `update: target ${decision.targetId} ${existing ? "superseded" : "deleted"} before the write`
33289
33410
  );
33290
33411
  }
33412
+ if (existing.content !== expectedContent) {
33413
+ return abandonToRace(options, `update: target ${decision.targetId} edited before the write`);
33414
+ }
33291
33415
  const mergedSourceIds = unionStrings(
33292
33416
  existing.sourceChunkIds ?? [],
33293
33417
  options.sourceChunkIds ?? []
@@ -33300,6 +33424,7 @@ async function tryConsolidate(trimmed, ctx, options, prepared) {
33300
33424
  const resurrect = resurrectFields(existing);
33301
33425
  const updated = await ctx.persistence.update(decision.targetId, {
33302
33426
  content: decision.content,
33427
+ expectedContent,
33303
33428
  freeFormOnly: true,
33304
33429
  proofCountIncrement: 1,
33305
33430
  observationSourceIds: options.sourceChunkIds,
@@ -33312,10 +33437,10 @@ async function tryConsolidate(trimmed, ctx, options, prepared) {
33312
33437
  ...factTypeUpdate !== void 0 && { factType: factTypeUpdate }
33313
33438
  });
33314
33439
  if (!updated) {
33315
- await assertMergeTargetGoneOrThrow(ctx, decision.targetId);
33440
+ await assertMergeTargetGoneOrThrow(ctx, decision.targetId, expectedContent);
33316
33441
  return abandonToRace(
33317
33442
  options,
33318
- `update: target ${decision.targetId} deleted mid-write (consolidated rewrite lost)`
33443
+ `update: target ${decision.targetId} changed mid-write (consolidated rewrite lost)`
33319
33444
  );
33320
33445
  }
33321
33446
  cacheRowVector(
@@ -33342,9 +33467,9 @@ async function tryConsolidate(trimmed, ctx, options, prepared) {
33342
33467
  );
33343
33468
  return null;
33344
33469
  }
33345
- async function assertMergeTargetGoneOrThrow(ctx, targetId) {
33470
+ async function assertMergeTargetGoneOrThrow(ctx, targetId, expectedContent) {
33346
33471
  const stillExists = await (ctx.persistence.getFresh ? ctx.persistence.getFresh(targetId) : ctx.persistence.get(targetId));
33347
- if (stillExists && (stillExists.kind === null || stillExists.kind === void 0)) {
33472
+ if (stillExists && (stillExists.kind === null || stillExists.kind === void 0) && (expectedContent === void 0 || stillExists.content === expectedContent)) {
33348
33473
  throw new RetainError(
33349
33474
  "merge-not-persisted",
33350
33475
  `retain: merge into memory ${targetId} failed to persist`
@@ -35190,6 +35315,7 @@ async function recall(query, ctx, options = {}) {
35190
35315
  },
35191
35316
  ...options.rrfK !== void 0 && { rrfK: options.rrfK },
35192
35317
  ...options.decryptLast !== void 0 && { decryptLast: options.decryptLast },
35318
+ ...options.vaultPreparation && { vaultPreparation: options.vaultPreparation },
35193
35319
  ...subQueries && { subQueries },
35194
35320
  ...options.scopes && { scopes: options.scopes },
35195
35321
  ...options.folderId !== void 0 && { folderId: options.folderId },
@@ -36622,13 +36748,20 @@ async function synthesizeProfile(ctx, options = {}) {
36622
36748
  }
36623
36749
  }
36624
36750
  }
36751
+ const vaultPreparation = createVaultPreparation();
36625
36752
  const settled = await Promise.allSettled(
36626
36753
  facets.map(async (facet) => {
36627
36754
  const prior = previous?.sections.find((s) => s.key === facet.key);
36628
36755
  if (prior && !staleKeys.has(facet.key)) {
36629
36756
  return prior;
36630
36757
  }
36631
- return synthesizeFacet(facet, recallCtx, options, fallbackPriors.get(facet.key));
36758
+ return synthesizeFacet(
36759
+ facet,
36760
+ recallCtx,
36761
+ options,
36762
+ fallbackPriors.get(facet.key),
36763
+ vaultPreparation
36764
+ );
36632
36765
  })
36633
36766
  );
36634
36767
  const sections = settled.map((r, i) => {
@@ -36782,7 +36915,7 @@ async function attributeFacts(ctx, candidates, facets) {
36782
36915
  }
36783
36916
  return keys;
36784
36917
  }
36785
- async function synthesizeFacet(facet, ctx, options, prior) {
36918
+ async function synthesizeFacet(facet, ctx, options, prior, vaultPreparation) {
36786
36919
  const scopes = options.scopes ?? DEFAULT_SCOPES;
36787
36920
  const limit = options.limit ?? DEFAULT_FACET_RECALL_LIMIT;
36788
36921
  const factTypeWeights = { ...DEFAULT_PROFILE_FACT_TYPE_WEIGHTS, ...options.factTypeWeights };
@@ -36799,6 +36932,7 @@ async function synthesizeFacet(facet, ctx, options, prior) {
36799
36932
  };
36800
36933
  }
36801
36934
  const recalled = await recall(facet.query, ctx, {
36935
+ vaultPreparation,
36802
36936
  scopes,
36803
36937
  limit: hasReviewGate ? RECALL_MAX_LIMIT : limit,
36804
36938
  types: ["fact"],