@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.
- package/dist/expo/{chunk-XW3LYSDA.mjs → chunk-WRZTH4OS.mjs} +38 -13
- package/dist/expo/{consolidate-4CQJYKRK.mjs → consolidate-HKL5EGZT.mjs} +1 -1
- package/dist/expo/index.cjs +201 -67
- package/dist/expo/index.d.mts +18 -5
- package/dist/expo/index.d.ts +18 -5
- package/dist/expo/index.mjs +164 -55
- package/dist/memory/context.d.mts +123 -0
- package/dist/memory/context.d.ts +123 -0
- package/dist/react/{chunk-7QX4J7KV.mjs → chunk-RSA3S6OA.mjs} +38 -13
- package/dist/react/{consolidate-WLDYJF6J.mjs → consolidate-WFTPBHDV.mjs} +1 -1
- package/dist/react/index.cjs +212 -77
- package/dist/react/index.d.mts +18 -5
- package/dist/react/index.d.ts +18 -5
- package/dist/react/index.mjs +180 -70
- package/dist/server/{chunk-AU3Z7NBC.mjs → chunk-QEROZ4VH.mjs} +38 -13
- package/dist/server/{consolidate-B6OSCZU4.mjs → consolidate-PYED62LW.mjs} +1 -1
- package/dist/server/index.cjs +198 -64
- package/dist/server/index.d.mts +18 -5
- package/dist/server/index.d.ts +18 -5
- package/dist/server/index.mjs +161 -52
- package/package.json +1 -1
|
@@ -723,6 +723,12 @@ function assertTransportMatchesEndpoint(transport, endpoint) {
|
|
|
723
723
|
`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.`
|
|
724
724
|
);
|
|
725
725
|
}
|
|
726
|
+
var TIME_BUDGET_EXHAUSTED = {
|
|
727
|
+
kind: "terminal",
|
|
728
|
+
code: "time-budget-exhausted",
|
|
729
|
+
reason: "time budget exhausted"
|
|
730
|
+
};
|
|
731
|
+
var MAX_TIMER_DELAY_MS = 2147483647;
|
|
726
732
|
var RETRYABLE_HTTP = /* @__PURE__ */ new Set([408, 409, 425, 429]);
|
|
727
733
|
function isRetryableStatus(status) {
|
|
728
734
|
return status >= 500 || RETRYABLE_HTTP.has(status);
|
|
@@ -778,7 +784,8 @@ async function callPortalJsonCompletion(req) {
|
|
|
778
784
|
}
|
|
779
785
|
const maxAttempts = Math.max(1, req.maxAttempts ?? 3);
|
|
780
786
|
const startedAt = Date.now();
|
|
781
|
-
const
|
|
787
|
+
const deadlineAt = req.totalTimeoutMs === void 0 ? void 0 : startedAt + req.totalTimeoutMs;
|
|
788
|
+
const overBudget = () => deadlineAt !== void 0 && Date.now() >= deadlineAt;
|
|
782
789
|
let lastFailure;
|
|
783
790
|
let reinforce = false;
|
|
784
791
|
const giveUp = () => {
|
|
@@ -791,17 +798,11 @@ async function callPortalJsonCompletion(req) {
|
|
|
791
798
|
lastFailure = { reason: "time-budget-exhausted", attempts: attempt - 1 };
|
|
792
799
|
break;
|
|
793
800
|
}
|
|
794
|
-
const attemptReq = req
|
|
795
|
-
...req,
|
|
796
|
-
timeoutMs: Math.max(
|
|
797
|
-
1,
|
|
798
|
-
Math.min(req.timeoutMs ?? 6e4, req.totalTimeoutMs - (Date.now() - startedAt))
|
|
799
|
-
),
|
|
800
|
-
...reinforce && { reinforceJsonContract: true }
|
|
801
|
-
} : reinforce ? { ...req, reinforceJsonContract: true } : req;
|
|
801
|
+
const attemptReq = reinforce ? { ...req, reinforceJsonContract: true } : req;
|
|
802
802
|
const outcome = await attemptPortalJson(
|
|
803
803
|
{ ...attemptReq, transport },
|
|
804
|
-
endpoint
|
|
804
|
+
endpoint,
|
|
805
|
+
deadlineAt
|
|
805
806
|
);
|
|
806
807
|
if (outcome.kind === "ok") {
|
|
807
808
|
req.onAttempt?.({ attempt, ok: true });
|
|
@@ -841,13 +842,38 @@ async function callPortalJsonCompletion(req) {
|
|
|
841
842
|
}
|
|
842
843
|
return giveUp();
|
|
843
844
|
}
|
|
844
|
-
async function attemptPortalJson(req, endpoint) {
|
|
845
|
+
async function attemptPortalJson(req, endpoint, deadlineAt) {
|
|
846
|
+
const controller = new AbortController();
|
|
847
|
+
if (deadlineAt === void 0 || deadlineAt - Date.now() > MAX_TIMER_DELAY_MS) {
|
|
848
|
+
return requestPortalJson(req, endpoint, controller);
|
|
849
|
+
}
|
|
850
|
+
const remainingMs = deadlineAt - Date.now();
|
|
851
|
+
if (remainingMs <= 0) return TIME_BUDGET_EXHAUSTED;
|
|
852
|
+
let timer;
|
|
853
|
+
try {
|
|
854
|
+
const outcome = await Promise.race([
|
|
855
|
+
new Promise((resolve) => {
|
|
856
|
+
timer = setTimeout(() => {
|
|
857
|
+
resolve(TIME_BUDGET_EXHAUSTED);
|
|
858
|
+
controller.abort();
|
|
859
|
+
}, remainingMs);
|
|
860
|
+
}),
|
|
861
|
+
requestPortalJson(req, endpoint, controller, deadlineAt)
|
|
862
|
+
]);
|
|
863
|
+
return Date.now() >= deadlineAt ? TIME_BUDGET_EXHAUSTED : outcome;
|
|
864
|
+
} finally {
|
|
865
|
+
clearTimeout(timer);
|
|
866
|
+
}
|
|
867
|
+
}
|
|
868
|
+
async function requestPortalJson(req, endpoint, controller, deadlineAt) {
|
|
845
869
|
const baseUrl = req.baseUrl ?? defaultBaseUrl();
|
|
846
870
|
const fetchImpl = req.fetchFn ?? fetch;
|
|
847
|
-
const timeoutMs = req.timeoutMs ?? 6e4;
|
|
848
871
|
const authHeaders = await resolvePortalAuthHeaders(req, req.tag);
|
|
872
|
+
const remainingMs = deadlineAt === void 0 ? Infinity : deadlineAt - Date.now();
|
|
873
|
+
if (controller.signal.aborted || remainingMs <= 0) return TIME_BUDGET_EXHAUSTED;
|
|
849
874
|
if (authHeaders === null)
|
|
850
875
|
return { kind: "terminal", code: "auth-unavailable", reason: "auth unavailable (no token)" };
|
|
876
|
+
const timeoutMs = Math.min(req.timeoutMs ?? 6e4, remainingMs);
|
|
851
877
|
const usesPrefill = req.transport !== "responses" && req.model.startsWith("anthropic/");
|
|
852
878
|
const prefill = usesPrefill ? "{" : "";
|
|
853
879
|
const messages = [
|
|
@@ -857,7 +883,6 @@ async function attemptPortalJson(req, endpoint) {
|
|
|
857
883
|
];
|
|
858
884
|
if (prefill) messages.push({ role: "assistant", content: prefill });
|
|
859
885
|
const supportsJsonObjectFormat = supportsResponseFormat(req.model);
|
|
860
|
-
const controller = new AbortController();
|
|
861
886
|
const timer = setTimeout(() => controller.abort(), timeoutMs);
|
|
862
887
|
const requestBody = req.transport === "responses" ? {
|
|
863
888
|
model: req.model,
|
package/dist/expo/index.cjs
CHANGED
|
@@ -875,7 +875,8 @@ async function callPortalJsonCompletion(req) {
|
|
|
875
875
|
}
|
|
876
876
|
const maxAttempts = Math.max(1, req.maxAttempts ?? 3);
|
|
877
877
|
const startedAt = Date.now();
|
|
878
|
-
const
|
|
878
|
+
const deadlineAt = req.totalTimeoutMs === void 0 ? void 0 : startedAt + req.totalTimeoutMs;
|
|
879
|
+
const overBudget = () => deadlineAt !== void 0 && Date.now() >= deadlineAt;
|
|
879
880
|
let lastFailure;
|
|
880
881
|
let reinforce = false;
|
|
881
882
|
const giveUp = () => {
|
|
@@ -888,17 +889,11 @@ async function callPortalJsonCompletion(req) {
|
|
|
888
889
|
lastFailure = { reason: "time-budget-exhausted", attempts: attempt - 1 };
|
|
889
890
|
break;
|
|
890
891
|
}
|
|
891
|
-
const attemptReq = req
|
|
892
|
-
...req,
|
|
893
|
-
timeoutMs: Math.max(
|
|
894
|
-
1,
|
|
895
|
-
Math.min(req.timeoutMs ?? 6e4, req.totalTimeoutMs - (Date.now() - startedAt))
|
|
896
|
-
),
|
|
897
|
-
...reinforce && { reinforceJsonContract: true }
|
|
898
|
-
} : reinforce ? { ...req, reinforceJsonContract: true } : req;
|
|
892
|
+
const attemptReq = reinforce ? { ...req, reinforceJsonContract: true } : req;
|
|
899
893
|
const outcome2 = await attemptPortalJson(
|
|
900
894
|
{ ...attemptReq, transport },
|
|
901
|
-
endpoint
|
|
895
|
+
endpoint,
|
|
896
|
+
deadlineAt
|
|
902
897
|
);
|
|
903
898
|
if (outcome2.kind === "ok") {
|
|
904
899
|
req.onAttempt?.({ attempt, ok: true });
|
|
@@ -938,13 +933,38 @@ async function callPortalJsonCompletion(req) {
|
|
|
938
933
|
}
|
|
939
934
|
return giveUp();
|
|
940
935
|
}
|
|
941
|
-
async function attemptPortalJson(req, endpoint) {
|
|
936
|
+
async function attemptPortalJson(req, endpoint, deadlineAt) {
|
|
937
|
+
const controller = new AbortController();
|
|
938
|
+
if (deadlineAt === void 0 || deadlineAt - Date.now() > MAX_TIMER_DELAY_MS) {
|
|
939
|
+
return requestPortalJson(req, endpoint, controller);
|
|
940
|
+
}
|
|
941
|
+
const remainingMs = deadlineAt - Date.now();
|
|
942
|
+
if (remainingMs <= 0) return TIME_BUDGET_EXHAUSTED;
|
|
943
|
+
let timer;
|
|
944
|
+
try {
|
|
945
|
+
const outcome2 = await Promise.race([
|
|
946
|
+
new Promise((resolve) => {
|
|
947
|
+
timer = setTimeout(() => {
|
|
948
|
+
resolve(TIME_BUDGET_EXHAUSTED);
|
|
949
|
+
controller.abort();
|
|
950
|
+
}, remainingMs);
|
|
951
|
+
}),
|
|
952
|
+
requestPortalJson(req, endpoint, controller, deadlineAt)
|
|
953
|
+
]);
|
|
954
|
+
return Date.now() >= deadlineAt ? TIME_BUDGET_EXHAUSTED : outcome2;
|
|
955
|
+
} finally {
|
|
956
|
+
clearTimeout(timer);
|
|
957
|
+
}
|
|
958
|
+
}
|
|
959
|
+
async function requestPortalJson(req, endpoint, controller, deadlineAt) {
|
|
942
960
|
const baseUrl = req.baseUrl ?? defaultBaseUrl();
|
|
943
961
|
const fetchImpl = req.fetchFn ?? fetch;
|
|
944
|
-
const timeoutMs = req.timeoutMs ?? 6e4;
|
|
945
962
|
const authHeaders = await resolvePortalAuthHeaders(req, req.tag);
|
|
963
|
+
const remainingMs = deadlineAt === void 0 ? Infinity : deadlineAt - Date.now();
|
|
964
|
+
if (controller.signal.aborted || remainingMs <= 0) return TIME_BUDGET_EXHAUSTED;
|
|
946
965
|
if (authHeaders === null)
|
|
947
966
|
return { kind: "terminal", code: "auth-unavailable", reason: "auth unavailable (no token)" };
|
|
967
|
+
const timeoutMs = Math.min(req.timeoutMs ?? 6e4, remainingMs);
|
|
948
968
|
const usesPrefill = req.transport !== "responses" && req.model.startsWith("anthropic/");
|
|
949
969
|
const prefill = usesPrefill ? "{" : "";
|
|
950
970
|
const messages = [
|
|
@@ -954,7 +974,6 @@ async function attemptPortalJson(req, endpoint) {
|
|
|
954
974
|
];
|
|
955
975
|
if (prefill) messages.push({ role: "assistant", content: prefill });
|
|
956
976
|
const supportsJsonObjectFormat = supportsResponseFormat(req.model);
|
|
957
|
-
const controller = new AbortController();
|
|
958
977
|
const timer = setTimeout(() => controller.abort(), timeoutMs);
|
|
959
978
|
const requestBody = req.transport === "responses" ? {
|
|
960
979
|
model: req.model,
|
|
@@ -1139,7 +1158,7 @@ function extractResponsesContent(body) {
|
|
|
1139
1158
|
const text14 = 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("");
|
|
1140
1159
|
return text14;
|
|
1141
1160
|
}
|
|
1142
|
-
var RESPONSE_FORMAT_OK, RESPONSE_SCHEMA_OK, JSON_CONTRACT_REMINDER, RESPONSES_ONLY_MODEL_PREFIXES, CHAT_TO_RESPONSES_FIELDS, FOREIGN_ENDPOINT_SUFFIX, RETRYABLE_HTTP;
|
|
1161
|
+
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;
|
|
1143
1162
|
var init_portalLlm = __esm({
|
|
1144
1163
|
"src/lib/memory/portalLlm.ts"() {
|
|
1145
1164
|
"use strict";
|
|
@@ -1159,6 +1178,12 @@ var init_portalLlm = __esm({
|
|
|
1159
1178
|
chat: "/responses",
|
|
1160
1179
|
responses: "/chat/completions"
|
|
1161
1180
|
};
|
|
1181
|
+
TIME_BUDGET_EXHAUSTED = {
|
|
1182
|
+
kind: "terminal",
|
|
1183
|
+
code: "time-budget-exhausted",
|
|
1184
|
+
reason: "time budget exhausted"
|
|
1185
|
+
};
|
|
1186
|
+
MAX_TIMER_DELAY_MS = 2147483647;
|
|
1162
1187
|
RETRYABLE_HTTP = /* @__PURE__ */ new Set([408, 409, 425, 429]);
|
|
1163
1188
|
}
|
|
1164
1189
|
});
|
|
@@ -2520,15 +2545,16 @@ async function refreshEncryptionKeyIfMatches(walletAddress, probeCiphertext, sig
|
|
|
2520
2545
|
if (!parsed) {
|
|
2521
2546
|
return false;
|
|
2522
2547
|
}
|
|
2548
|
+
const startEpoch = sessionEpoch;
|
|
2523
2549
|
const cached = refreshCandidatesByAddress.get(walletAddress);
|
|
2524
2550
|
if (cached) {
|
|
2525
|
-
return tryCommitCandidatesIfProbeMatches(walletAddress, parsed, cached);
|
|
2551
|
+
return tryCommitCandidatesIfProbeMatches(walletAddress, parsed, cached, startEpoch);
|
|
2526
2552
|
}
|
|
2527
2553
|
let derivePromise = pendingCandidateDerives.get(walletAddress);
|
|
2528
2554
|
if (!derivePromise) {
|
|
2529
2555
|
derivePromise = (async () => {
|
|
2530
2556
|
const candidates2 = await deriveRefreshCandidates(signMessage, embeddedWalletSigner);
|
|
2531
|
-
if (candidates2) {
|
|
2557
|
+
if (candidates2 && sessionEpoch === startEpoch) {
|
|
2532
2558
|
refreshCandidatesByAddress.set(walletAddress, candidates2);
|
|
2533
2559
|
}
|
|
2534
2560
|
return candidates2;
|
|
@@ -2540,10 +2566,10 @@ async function refreshEncryptionKeyIfMatches(walletAddress, probeCiphertext, sig
|
|
|
2540
2566
|
pendingCandidateDerives.set(walletAddress, derivePromise);
|
|
2541
2567
|
}
|
|
2542
2568
|
const candidates = await derivePromise;
|
|
2543
|
-
if (!candidates) {
|
|
2569
|
+
if (!candidates || sessionEpoch !== startEpoch) {
|
|
2544
2570
|
return false;
|
|
2545
2571
|
}
|
|
2546
|
-
return tryCommitCandidatesIfProbeMatches(walletAddress, parsed, candidates);
|
|
2572
|
+
return tryCommitCandidatesIfProbeMatches(walletAddress, parsed, candidates, startEpoch);
|
|
2547
2573
|
}
|
|
2548
2574
|
function parsePrefixedCiphertext(probeCiphertext) {
|
|
2549
2575
|
const version = probeCiphertext.startsWith("enc:v3:") ? "v3" : probeCiphertext.startsWith("enc:v2:") ? "v2" : null;
|
|
@@ -2586,7 +2612,7 @@ async function deriveRefreshCandidates(signMessage, embeddedWalletSigner) {
|
|
|
2586
2612
|
}
|
|
2587
2613
|
return { legacy: legacyKey, current: currentKey };
|
|
2588
2614
|
}
|
|
2589
|
-
async function tryCommitCandidatesIfProbeMatches(walletAddress, parsed, candidates) {
|
|
2615
|
+
async function tryCommitCandidatesIfProbeMatches(walletAddress, parsed, candidates, startEpoch) {
|
|
2590
2616
|
const candidateHex = parsed.version === "v2" ? candidates.legacy : candidates.current;
|
|
2591
2617
|
const keyBytes = hexToBytes(candidateHex);
|
|
2592
2618
|
const candidateCryptoKey = await crypto.subtle.importKey(
|
|
@@ -2604,6 +2630,9 @@ async function tryCommitCandidatesIfProbeMatches(walletAddress, parsed, candidat
|
|
|
2604
2630
|
);
|
|
2605
2631
|
return false;
|
|
2606
2632
|
}
|
|
2633
|
+
if (sessionEpoch !== startEpoch) {
|
|
2634
|
+
return false;
|
|
2635
|
+
}
|
|
2607
2636
|
setStoredKey(walletAddress, { legacy: candidates.legacy, current: candidates.current });
|
|
2608
2637
|
cryptoKeyCache.delete(`${walletAddress}:v2`);
|
|
2609
2638
|
cryptoKeyCache.delete(`${walletAddress}:v3`);
|
|
@@ -14967,6 +14996,16 @@ async function updateVaultMemoryOp(ctx, id2, opts) {
|
|
|
14967
14996
|
const probe = await ctx.vaultMemoryCollection.find(id2);
|
|
14968
14997
|
if (probe.isDeleted || probe.supersededBy || !isOwnedByCtxUser(ctx, probe)) return null;
|
|
14969
14998
|
if (opts.freeFormOnly && isKinded(probe)) return null;
|
|
14999
|
+
const readStoredContent = probe._getRaw("content");
|
|
15000
|
+
if (opts.expectedContent !== void 0) {
|
|
15001
|
+
const current = await vaultMemoryToStored(
|
|
15002
|
+
probe,
|
|
15003
|
+
ctx.walletAddress,
|
|
15004
|
+
ctx.signMessage,
|
|
15005
|
+
ctx.embeddedWalletSigner
|
|
15006
|
+
);
|
|
15007
|
+
if (current.content !== opts.expectedContent) return null;
|
|
15008
|
+
}
|
|
14970
15009
|
const levelAfter = (current) => {
|
|
14971
15010
|
if (opts.level !== void 0) return opts.level;
|
|
14972
15011
|
if (opts.scope === void 0) return resolveMemoryLevel(current.level, current.scope);
|
|
@@ -14974,7 +15013,7 @@ async function updateVaultMemoryOp(ctx, id2, opts) {
|
|
|
14974
15013
|
};
|
|
14975
15014
|
assertValidKindLevel(opts.kind !== void 0 ? opts.kind : probe.kind, levelAfter(probe));
|
|
14976
15015
|
const encryptedKindValue = await encryptKindValue(ctx, opts.kindValue);
|
|
14977
|
-
const encryptedContent = ctx.walletAddress && ctx.signMessage ? await encryptVaultMemoryContent(
|
|
15016
|
+
const encryptedContent = opts.content !== void 0 && ctx.walletAddress && ctx.signMessage ? await encryptVaultMemoryContent(
|
|
14978
15017
|
opts.content,
|
|
14979
15018
|
ctx.walletAddress,
|
|
14980
15019
|
ctx.signMessage,
|
|
@@ -14982,13 +15021,13 @@ async function updateVaultMemoryOp(ctx, id2, opts) {
|
|
|
14982
15021
|
) : opts.content;
|
|
14983
15022
|
let stale = false;
|
|
14984
15023
|
const record2 = probe;
|
|
14985
|
-
const originalUpdatedAt = record2.updatedAt.getTime();
|
|
14986
15024
|
await ctx.database.write(async () => {
|
|
14987
15025
|
await assertCanWrite2(ctx);
|
|
14988
|
-
if (record2.isDeleted || record2.supersededBy || !isOwnedByCtxUser(ctx, record2) || opts.freeFormOnly && isKinded(record2)) {
|
|
15026
|
+
if (record2.isDeleted || record2.supersededBy || !isOwnedByCtxUser(ctx, record2) || opts.freeFormOnly && isKinded(record2) || opts.expectedContent !== void 0 && record2._getRaw("content") !== readStoredContent) {
|
|
14989
15027
|
stale = true;
|
|
14990
15028
|
return;
|
|
14991
15029
|
}
|
|
15030
|
+
const originalUpdatedAt = record2.updatedAt.getTime();
|
|
14992
15031
|
const nextKind = opts.kind !== void 0 ? opts.kind : record2.kind;
|
|
14993
15032
|
const nextLevel = levelAfter(record2);
|
|
14994
15033
|
assertValidKindLevel(nextKind, nextLevel);
|
|
@@ -15004,7 +15043,7 @@ async function updateVaultMemoryOp(ctx, id2, opts) {
|
|
|
15004
15043
|
replayedObservation = opts.observationSourceIds.every((id3) => observedSources.includes(id3));
|
|
15005
15044
|
}
|
|
15006
15045
|
await record2.update((r) => {
|
|
15007
|
-
r._setRaw("content", encryptedContent);
|
|
15046
|
+
if (encryptedContent !== void 0) r._setRaw("content", encryptedContent);
|
|
15008
15047
|
if (opts.level !== void 0) {
|
|
15009
15048
|
r._setRaw("level", nextLevel);
|
|
15010
15049
|
r._setRaw("scope", scopeForLevel(nextLevel));
|
|
@@ -15772,7 +15811,7 @@ function classifyDecay(m, now, policy) {
|
|
|
15772
15811
|
if (m.source === "manual" || m.source === SOURCE_PHOTO) return "keep";
|
|
15773
15812
|
if (isTimeSensitiveType(m.factType) && m.eventTimeEnd !== null) {
|
|
15774
15813
|
if (m.eventTimeEnd < now - resolved.pastEventGraceMs) return "archive";
|
|
15775
|
-
|
|
15814
|
+
return "keep";
|
|
15776
15815
|
}
|
|
15777
15816
|
if (now - lastActivityAt(m) > ttlForType(m.factType, resolved)) return "archive";
|
|
15778
15817
|
return "keep";
|
|
@@ -17284,6 +17323,104 @@ function validate(parsed, originalQuery) {
|
|
|
17284
17323
|
return { mode, subQueries };
|
|
17285
17324
|
}
|
|
17286
17325
|
|
|
17326
|
+
// src/lib/memoryVault/vaultPreparation.ts
|
|
17327
|
+
function createVaultPreparation() {
|
|
17328
|
+
return { corpora: /* @__PURE__ */ new WeakMap(), rows: /* @__PURE__ */ new WeakMap() };
|
|
17329
|
+
}
|
|
17330
|
+
var pendingRows = /* @__PURE__ */ new WeakMap();
|
|
17331
|
+
function loadVaultCorpus(ctx, options, preparation) {
|
|
17332
|
+
if (!preparation) return getAllVaultMemoriesOp(ctx, options);
|
|
17333
|
+
const corpusCache = preparation.corpora;
|
|
17334
|
+
let pending = corpusCache.get(ctx);
|
|
17335
|
+
if (!pending) {
|
|
17336
|
+
pending = /* @__PURE__ */ new Map();
|
|
17337
|
+
corpusCache.set(ctx, pending);
|
|
17338
|
+
}
|
|
17339
|
+
const key = JSON.stringify(options ?? {});
|
|
17340
|
+
let request = pending.get(key);
|
|
17341
|
+
if (!request) {
|
|
17342
|
+
const entries = pending;
|
|
17343
|
+
request = getAllVaultMemoriesOp(ctx, options).catch((error) => {
|
|
17344
|
+
entries.delete(key);
|
|
17345
|
+
throw error;
|
|
17346
|
+
});
|
|
17347
|
+
pending.set(key, request);
|
|
17348
|
+
}
|
|
17349
|
+
return request;
|
|
17350
|
+
}
|
|
17351
|
+
function rowRequestsFor(registry2, ctx, maskInput) {
|
|
17352
|
+
let byMask = registry2.get(ctx);
|
|
17353
|
+
if (!byMask) {
|
|
17354
|
+
byMask = /* @__PURE__ */ new Map();
|
|
17355
|
+
registry2.set(ctx, byMask);
|
|
17356
|
+
}
|
|
17357
|
+
let requests = byMask.get(maskInput);
|
|
17358
|
+
if (!requests) {
|
|
17359
|
+
requests = /* @__PURE__ */ new Map();
|
|
17360
|
+
byMask.set(maskInput, requests);
|
|
17361
|
+
}
|
|
17362
|
+
return requests;
|
|
17363
|
+
}
|
|
17364
|
+
function embedVaultRows(ctx, options, rows, preparation) {
|
|
17365
|
+
const pending = rowRequestsFor(pendingRows, ctx, options.maskInput);
|
|
17366
|
+
const prepared = preparation && rowRequestsFor(preparation.rows, ctx, options.maskInput);
|
|
17367
|
+
const model = options.model ?? DEFAULT_API_EMBEDDING_MODEL;
|
|
17368
|
+
const keys = rows.map(
|
|
17369
|
+
(row) => JSON.stringify([
|
|
17370
|
+
row.uniqueId,
|
|
17371
|
+
row.updatedAt?.getTime(),
|
|
17372
|
+
row.content,
|
|
17373
|
+
model,
|
|
17374
|
+
options.baseUrl,
|
|
17375
|
+
options.timeoutMs,
|
|
17376
|
+
options.tokenTimeoutMs,
|
|
17377
|
+
options.totalTimeoutMs
|
|
17378
|
+
])
|
|
17379
|
+
);
|
|
17380
|
+
const missing = /* @__PURE__ */ new Map();
|
|
17381
|
+
rows.forEach((row, index) => {
|
|
17382
|
+
if (!pending.has(keys[index]) && !prepared?.has(keys[index])) missing.set(keys[index], row);
|
|
17383
|
+
});
|
|
17384
|
+
if (missing.size > 0) {
|
|
17385
|
+
const entries = pending;
|
|
17386
|
+
const batch = Promise.resolve().then(
|
|
17387
|
+
() => generateEmbeddings(
|
|
17388
|
+
[...missing.values()].map((row) => row.content),
|
|
17389
|
+
options
|
|
17390
|
+
)
|
|
17391
|
+
);
|
|
17392
|
+
[...missing].forEach(([key, row], index) => {
|
|
17393
|
+
const request = batch.then((vectors) => {
|
|
17394
|
+
const vector = vectors[index];
|
|
17395
|
+
updateVaultMemoryEmbeddingOp(ctx, row.uniqueId, JSON.stringify(vector), model, {
|
|
17396
|
+
content: row.content,
|
|
17397
|
+
updatedAt: row.updatedAt?.getTime()
|
|
17398
|
+
}).catch(() => {
|
|
17399
|
+
});
|
|
17400
|
+
return vector;
|
|
17401
|
+
}).finally(() => {
|
|
17402
|
+
entries.delete(key);
|
|
17403
|
+
if (entries.size === 0) pendingRows.get(ctx)?.delete(options.maskInput);
|
|
17404
|
+
});
|
|
17405
|
+
pending.set(key, request);
|
|
17406
|
+
});
|
|
17407
|
+
}
|
|
17408
|
+
return Promise.all(
|
|
17409
|
+
keys.map((key) => {
|
|
17410
|
+
const cached = prepared?.get(key);
|
|
17411
|
+
if (cached) return cached;
|
|
17412
|
+
const request = pending.get(key);
|
|
17413
|
+
if (!prepared) return request;
|
|
17414
|
+
const retained = request.catch((error) => {
|
|
17415
|
+
prepared.delete(key);
|
|
17416
|
+
throw error;
|
|
17417
|
+
});
|
|
17418
|
+
prepared.set(key, retained);
|
|
17419
|
+
return retained;
|
|
17420
|
+
})
|
|
17421
|
+
);
|
|
17422
|
+
}
|
|
17423
|
+
|
|
17287
17424
|
// src/lib/memoryVault/vectorVersion.ts
|
|
17288
17425
|
var vectorRowVersion = /* @__PURE__ */ new WeakMap();
|
|
17289
17426
|
function contentFingerprint(content) {
|
|
@@ -17846,11 +17983,11 @@ async function rankComposite(originalQuery, originalQueryEmbedding, subQueries,
|
|
|
17846
17983
|
return combined.slice(0, limit);
|
|
17847
17984
|
}
|
|
17848
17985
|
async function preEmbedVaultMemories(vaultCtx, embeddingOptions, cache, options) {
|
|
17849
|
-
const memories = await
|
|
17986
|
+
const memories = await loadVaultCorpus(vaultCtx, options);
|
|
17850
17987
|
const currentModel = embeddingOptions.model ?? DEFAULT_API_EMBEDDING_MODEL;
|
|
17851
17988
|
const uncachedTexts = [];
|
|
17852
17989
|
const uncachedKeys = [];
|
|
17853
|
-
const
|
|
17990
|
+
const uncachedRows = [];
|
|
17854
17991
|
const uncachedVersions = [];
|
|
17855
17992
|
for (const m of memories) {
|
|
17856
17993
|
const content = m.content;
|
|
@@ -17869,12 +18006,12 @@ async function preEmbedVaultMemories(vaultCtx, embeddingOptions, cache, options)
|
|
|
17869
18006
|
}
|
|
17870
18007
|
uncachedTexts.push(m.content);
|
|
17871
18008
|
uncachedKeys.push(m.uniqueId);
|
|
17872
|
-
|
|
18009
|
+
uncachedRows.push(m);
|
|
17873
18010
|
uncachedVersions.push(m.updatedAt);
|
|
17874
18011
|
}
|
|
17875
18012
|
}
|
|
17876
18013
|
if (uncachedTexts.length > 0) {
|
|
17877
|
-
const embeddings = await
|
|
18014
|
+
const embeddings = await embedVaultRows(vaultCtx, embeddingOptions, uncachedRows);
|
|
17878
18015
|
for (let i = 0; i < uncachedKeys.length; i++) {
|
|
17879
18016
|
cacheRowVector(
|
|
17880
18017
|
cache,
|
|
@@ -17883,13 +18020,6 @@ async function preEmbedVaultMemories(vaultCtx, embeddingOptions, cache, options)
|
|
|
17883
18020
|
uncachedVersions[i],
|
|
17884
18021
|
uncachedTexts[i]
|
|
17885
18022
|
);
|
|
17886
|
-
updateVaultMemoryEmbeddingOp(
|
|
17887
|
-
vaultCtx,
|
|
17888
|
-
uncachedIds[i],
|
|
17889
|
-
JSON.stringify(embeddings[i]),
|
|
17890
|
-
currentModel
|
|
17891
|
-
).catch(() => {
|
|
17892
|
-
});
|
|
17893
18023
|
}
|
|
17894
18024
|
}
|
|
17895
18025
|
}
|
|
@@ -18031,10 +18161,7 @@ async function buildProjectedCorpus(query, vaultCtx, embeddingOptions, cache, qu
|
|
|
18031
18161
|
let laneVecs;
|
|
18032
18162
|
if (opts.embedStats) opts.embedStats.rowsEmbedded += laneRows.length;
|
|
18033
18163
|
try {
|
|
18034
|
-
laneVecs = await
|
|
18035
|
-
laneRows.map((m) => m.content),
|
|
18036
|
-
embeddingOptions
|
|
18037
|
-
);
|
|
18164
|
+
laneVecs = await embedVaultRows(vaultCtx, embeddingOptions, laneRows);
|
|
18038
18165
|
} catch (err) {
|
|
18039
18166
|
laneEmbedFailed = true;
|
|
18040
18167
|
getLogger().warn(
|
|
@@ -18048,13 +18175,6 @@ async function buildProjectedCorpus(query, vaultCtx, embeddingOptions, cache, qu
|
|
|
18048
18175
|
cacheRowVector(cache, m.uniqueId, vec, m.updatedAt, m.content);
|
|
18049
18176
|
resolvedThisCall.add(m.uniqueId);
|
|
18050
18177
|
vectored.push({ uniqueId: m.uniqueId, embedding: vec, updatedAt: m.updatedAt });
|
|
18051
|
-
updateVaultMemoryEmbeddingOp(
|
|
18052
|
-
vaultCtx,
|
|
18053
|
-
m.uniqueId,
|
|
18054
|
-
JSON.stringify(vecs[i]),
|
|
18055
|
-
currentModel
|
|
18056
|
-
).catch(() => {
|
|
18057
|
-
});
|
|
18058
18178
|
});
|
|
18059
18179
|
}
|
|
18060
18180
|
}
|
|
@@ -18246,9 +18366,10 @@ async function prepareVaultCandidates(query, vaultCtx, embeddingOptions, cache,
|
|
|
18246
18366
|
};
|
|
18247
18367
|
}
|
|
18248
18368
|
} else {
|
|
18249
|
-
const loaded = await
|
|
18369
|
+
const loaded = await loadVaultCorpus(
|
|
18250
18370
|
vaultCtx,
|
|
18251
|
-
Object.keys(queryOpts).length > 0 ? queryOpts : void 0
|
|
18371
|
+
Object.keys(queryOpts).length > 0 ? queryOpts : void 0,
|
|
18372
|
+
searchOptions?.vaultPreparation
|
|
18252
18373
|
);
|
|
18253
18374
|
vaultSize = loaded.length;
|
|
18254
18375
|
rowsDecrypted = loaded.length;
|
|
@@ -18321,7 +18442,12 @@ async function prepareVaultCandidates(query, vaultCtx, embeddingOptions, cache,
|
|
|
18321
18442
|
let newEmbeddings;
|
|
18322
18443
|
embedStats.rowsEmbedded += uncachedTexts.length;
|
|
18323
18444
|
try {
|
|
18324
|
-
newEmbeddings = await
|
|
18445
|
+
newEmbeddings = await embedVaultRows(
|
|
18446
|
+
vaultCtx,
|
|
18447
|
+
embeddingOptions,
|
|
18448
|
+
uncachedIndices.map((index) => memories[index]),
|
|
18449
|
+
searchOptions?.vaultPreparation
|
|
18450
|
+
);
|
|
18325
18451
|
} catch (err) {
|
|
18326
18452
|
embeddingFailure = true;
|
|
18327
18453
|
getLogger().warn(
|
|
@@ -18337,13 +18463,6 @@ async function prepareVaultCandidates(query, vaultCtx, embeddingOptions, cache,
|
|
|
18337
18463
|
memories[uncachedIndices[j]].updatedAt,
|
|
18338
18464
|
memories[uncachedIndices[j]].content
|
|
18339
18465
|
);
|
|
18340
|
-
updateVaultMemoryEmbeddingOp(
|
|
18341
|
-
vaultCtx,
|
|
18342
|
-
memories[uncachedIndices[j]].uniqueId,
|
|
18343
|
-
JSON.stringify(newEmbeddings[j]),
|
|
18344
|
-
currentModel
|
|
18345
|
-
).catch(() => {
|
|
18346
|
-
});
|
|
18347
18466
|
}
|
|
18348
18467
|
}
|
|
18349
18468
|
}
|
|
@@ -18748,7 +18867,6 @@ async function retainWithPersistence(content, ctx, options = {}) {
|
|
|
18748
18867
|
const factTypeUpdate = pickFactTypeUpdate(existing, options.factType);
|
|
18749
18868
|
const resurrect = resurrectFields(existing);
|
|
18750
18869
|
const updated = await ctx.persistence.update(targetId, {
|
|
18751
|
-
content: existing.content,
|
|
18752
18870
|
freeFormOnly: true,
|
|
18753
18871
|
proofCountIncrement: 1,
|
|
18754
18872
|
observationSourceIds: options.sourceChunkIds,
|
|
@@ -18987,7 +19105,6 @@ async function tryConsolidate(trimmed, ctx, options, prepared) {
|
|
|
18987
19105
|
const factTypeUpdate = pickFactTypeUpdate(existing, options.factType);
|
|
18988
19106
|
const resurrect = resurrectFields(existing);
|
|
18989
19107
|
const updated = await ctx.persistence.update(decision.targetId, {
|
|
18990
|
-
content: existing.content,
|
|
18991
19108
|
freeFormOnly: true,
|
|
18992
19109
|
proofCountIncrement: 1,
|
|
18993
19110
|
observationSourceIds: options.sourceChunkIds,
|
|
@@ -19015,6 +19132,10 @@ async function tryConsolidate(trimmed, ctx, options, prepared) {
|
|
|
19015
19132
|
};
|
|
19016
19133
|
}
|
|
19017
19134
|
if (decision.action === "update" && decision.targetId && decision.content) {
|
|
19135
|
+
const expectedContent = candidates.find(
|
|
19136
|
+
(candidate) => candidate.id === decision.targetId
|
|
19137
|
+
)?.content;
|
|
19138
|
+
if (expectedContent === void 0) return null;
|
|
19018
19139
|
const existing = await ctx.persistence.get(decision.targetId);
|
|
19019
19140
|
if (!existing || existing.supersededBy) {
|
|
19020
19141
|
return abandonToRace(
|
|
@@ -19022,6 +19143,9 @@ async function tryConsolidate(trimmed, ctx, options, prepared) {
|
|
|
19022
19143
|
`update: target ${decision.targetId} ${existing ? "superseded" : "deleted"} before the write`
|
|
19023
19144
|
);
|
|
19024
19145
|
}
|
|
19146
|
+
if (existing.content !== expectedContent) {
|
|
19147
|
+
return abandonToRace(options, `update: target ${decision.targetId} edited before the write`);
|
|
19148
|
+
}
|
|
19025
19149
|
const mergedSourceIds = unionStrings(
|
|
19026
19150
|
existing.sourceChunkIds ?? [],
|
|
19027
19151
|
options.sourceChunkIds ?? []
|
|
@@ -19034,6 +19158,7 @@ async function tryConsolidate(trimmed, ctx, options, prepared) {
|
|
|
19034
19158
|
const resurrect = resurrectFields(existing);
|
|
19035
19159
|
const updated = await ctx.persistence.update(decision.targetId, {
|
|
19036
19160
|
content: decision.content,
|
|
19161
|
+
expectedContent,
|
|
19037
19162
|
freeFormOnly: true,
|
|
19038
19163
|
proofCountIncrement: 1,
|
|
19039
19164
|
observationSourceIds: options.sourceChunkIds,
|
|
@@ -19046,10 +19171,10 @@ async function tryConsolidate(trimmed, ctx, options, prepared) {
|
|
|
19046
19171
|
...factTypeUpdate !== void 0 && { factType: factTypeUpdate }
|
|
19047
19172
|
});
|
|
19048
19173
|
if (!updated) {
|
|
19049
|
-
await assertMergeTargetGoneOrThrow(ctx, decision.targetId);
|
|
19174
|
+
await assertMergeTargetGoneOrThrow(ctx, decision.targetId, expectedContent);
|
|
19050
19175
|
return abandonToRace(
|
|
19051
19176
|
options,
|
|
19052
|
-
`update: target ${decision.targetId}
|
|
19177
|
+
`update: target ${decision.targetId} changed mid-write (consolidated rewrite lost)`
|
|
19053
19178
|
);
|
|
19054
19179
|
}
|
|
19055
19180
|
cacheRowVector(
|
|
@@ -19076,9 +19201,9 @@ async function tryConsolidate(trimmed, ctx, options, prepared) {
|
|
|
19076
19201
|
);
|
|
19077
19202
|
return null;
|
|
19078
19203
|
}
|
|
19079
|
-
async function assertMergeTargetGoneOrThrow(ctx, targetId) {
|
|
19204
|
+
async function assertMergeTargetGoneOrThrow(ctx, targetId, expectedContent) {
|
|
19080
19205
|
const stillExists = await (ctx.persistence.getFresh ? ctx.persistence.getFresh(targetId) : ctx.persistence.get(targetId));
|
|
19081
|
-
if (stillExists && (stillExists.kind === null || stillExists.kind === void 0)) {
|
|
19206
|
+
if (stillExists && (stillExists.kind === null || stillExists.kind === void 0) && (expectedContent === void 0 || stillExists.content === expectedContent)) {
|
|
19082
19207
|
throw new RetainError(
|
|
19083
19208
|
"merge-not-persisted",
|
|
19084
19209
|
`retain: merge into memory ${targetId} failed to persist`
|
|
@@ -20898,6 +21023,7 @@ async function recall(query, ctx, options = {}) {
|
|
|
20898
21023
|
},
|
|
20899
21024
|
...options.rrfK !== void 0 && { rrfK: options.rrfK },
|
|
20900
21025
|
...options.decryptLast !== void 0 && { decryptLast: options.decryptLast },
|
|
21026
|
+
...options.vaultPreparation && { vaultPreparation: options.vaultPreparation },
|
|
20901
21027
|
...subQueries && { subQueries },
|
|
20902
21028
|
...options.scopes && { scopes: options.scopes },
|
|
20903
21029
|
...options.folderId !== void 0 && { folderId: options.folderId },
|
|
@@ -22489,16 +22615,16 @@ function createRemoteMemoryPipeline(options) {
|
|
|
22489
22615
|
create: (input) => write(createRow(input), 0),
|
|
22490
22616
|
update: async (id2, patch) => {
|
|
22491
22617
|
const existing = await get(id2);
|
|
22492
|
-
if (!existing || patch.freeFormOnly && existing.kind !== null && existing.kind !== void 0)
|
|
22618
|
+
if (!existing || patch.expectedContent !== void 0 && existing.content !== patch.expectedContent || patch.freeFormOnly && existing.kind !== null && existing.kind !== void 0)
|
|
22493
22619
|
return null;
|
|
22494
22620
|
const snapshot = snapshots.get(id2);
|
|
22495
22621
|
const memory = {
|
|
22496
22622
|
...snapshot.memory,
|
|
22497
|
-
content: patch.content,
|
|
22623
|
+
content: patch.content ?? snapshot.memory.content,
|
|
22498
22624
|
updated_at: patch.preserveUpdatedAt ? snapshot.memory.updated_at : Math.max(Date.now(), (snapshot.memory.topics_extracted_at ?? 0) + 1)
|
|
22499
22625
|
};
|
|
22500
22626
|
if (patch.scope !== void 0) memory.scope = patch.scope;
|
|
22501
|
-
if (patch.embedding === void 0 && patch.content !== snapshot.memory.content) {
|
|
22627
|
+
if (patch.embedding === void 0 && patch.content !== void 0 && patch.content !== snapshot.memory.content) {
|
|
22502
22628
|
delete memory.embedding;
|
|
22503
22629
|
delete memory.embedding_model;
|
|
22504
22630
|
}
|
|
@@ -24503,13 +24629,20 @@ async function synthesizeProfile(ctx, options = {}) {
|
|
|
24503
24629
|
}
|
|
24504
24630
|
}
|
|
24505
24631
|
}
|
|
24632
|
+
const vaultPreparation = createVaultPreparation();
|
|
24506
24633
|
const settled = await Promise.allSettled(
|
|
24507
24634
|
facets.map(async (facet) => {
|
|
24508
24635
|
const prior = previous?.sections.find((s) => s.key === facet.key);
|
|
24509
24636
|
if (prior && !staleKeys.has(facet.key)) {
|
|
24510
24637
|
return prior;
|
|
24511
24638
|
}
|
|
24512
|
-
return synthesizeFacet(
|
|
24639
|
+
return synthesizeFacet(
|
|
24640
|
+
facet,
|
|
24641
|
+
recallCtx,
|
|
24642
|
+
options,
|
|
24643
|
+
fallbackPriors.get(facet.key),
|
|
24644
|
+
vaultPreparation
|
|
24645
|
+
);
|
|
24513
24646
|
})
|
|
24514
24647
|
);
|
|
24515
24648
|
const sections = settled.map((r, i) => {
|
|
@@ -24663,7 +24796,7 @@ async function attributeFacts(ctx, candidates, facets) {
|
|
|
24663
24796
|
}
|
|
24664
24797
|
return keys;
|
|
24665
24798
|
}
|
|
24666
|
-
async function synthesizeFacet(facet, ctx, options, prior) {
|
|
24799
|
+
async function synthesizeFacet(facet, ctx, options, prior, vaultPreparation) {
|
|
24667
24800
|
const scopes = options.scopes ?? DEFAULT_SCOPES;
|
|
24668
24801
|
const limit = options.limit ?? DEFAULT_FACET_RECALL_LIMIT;
|
|
24669
24802
|
const factTypeWeights = { ...DEFAULT_PROFILE_FACT_TYPE_WEIGHTS, ...options.factTypeWeights };
|
|
@@ -24680,6 +24813,7 @@ async function synthesizeFacet(facet, ctx, options, prior) {
|
|
|
24680
24813
|
};
|
|
24681
24814
|
}
|
|
24682
24815
|
const recalled = await recall(facet.query, ctx, {
|
|
24816
|
+
vaultPreparation,
|
|
24683
24817
|
scopes,
|
|
24684
24818
|
limit: hasReviewGate ? RECALL_MAX_LIMIT : limit,
|
|
24685
24819
|
types: ["fact"],
|