@anuma/sdk 9.1.5 → 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 +69 -28
- package/dist/expo/index.d.mts +9 -5
- package/dist/expo/index.d.ts +9 -5
- package/dist/expo/index.mjs +32 -16
- 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 +80 -38
- package/dist/react/index.d.mts +9 -5
- package/dist/react/index.d.ts +9 -5
- package/dist/react/index.mjs +48 -31
- 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 +66 -25
- package/dist/server/index.d.mts +9 -5
- package/dist/server/index.d.ts +9 -5
- package/dist/server/index.mjs +29 -13
- 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/react/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
|
});
|
|
@@ -16788,6 +16813,16 @@ async function updateVaultMemoryOp(ctx, id2, opts) {
|
|
|
16788
16813
|
const probe = await ctx.vaultMemoryCollection.find(id2);
|
|
16789
16814
|
if (probe.isDeleted || probe.supersededBy || !isOwnedByCtxUser(ctx, probe)) return null;
|
|
16790
16815
|
if (opts.freeFormOnly && isKinded(probe)) return null;
|
|
16816
|
+
const readStoredContent = probe._getRaw("content");
|
|
16817
|
+
if (opts.expectedContent !== void 0) {
|
|
16818
|
+
const current = await vaultMemoryToStored(
|
|
16819
|
+
probe,
|
|
16820
|
+
ctx.walletAddress,
|
|
16821
|
+
ctx.signMessage,
|
|
16822
|
+
ctx.embeddedWalletSigner
|
|
16823
|
+
);
|
|
16824
|
+
if (current.content !== opts.expectedContent) return null;
|
|
16825
|
+
}
|
|
16791
16826
|
const levelAfter = (current) => {
|
|
16792
16827
|
if (opts.level !== void 0) return opts.level;
|
|
16793
16828
|
if (opts.scope === void 0) return resolveMemoryLevel(current.level, current.scope);
|
|
@@ -16795,7 +16830,7 @@ async function updateVaultMemoryOp(ctx, id2, opts) {
|
|
|
16795
16830
|
};
|
|
16796
16831
|
assertValidKindLevel(opts.kind !== void 0 ? opts.kind : probe.kind, levelAfter(probe));
|
|
16797
16832
|
const encryptedKindValue = await encryptKindValue(ctx, opts.kindValue);
|
|
16798
|
-
const encryptedContent = ctx.walletAddress && ctx.signMessage ? await encryptVaultMemoryContent(
|
|
16833
|
+
const encryptedContent = opts.content !== void 0 && ctx.walletAddress && ctx.signMessage ? await encryptVaultMemoryContent(
|
|
16799
16834
|
opts.content,
|
|
16800
16835
|
ctx.walletAddress,
|
|
16801
16836
|
ctx.signMessage,
|
|
@@ -16803,13 +16838,13 @@ async function updateVaultMemoryOp(ctx, id2, opts) {
|
|
|
16803
16838
|
) : opts.content;
|
|
16804
16839
|
let stale = false;
|
|
16805
16840
|
const record2 = probe;
|
|
16806
|
-
const originalUpdatedAt = record2.updatedAt.getTime();
|
|
16807
16841
|
await ctx.database.write(async () => {
|
|
16808
16842
|
await assertCanWrite2(ctx);
|
|
16809
|
-
if (record2.isDeleted || record2.supersededBy || !isOwnedByCtxUser(ctx, record2) || opts.freeFormOnly && isKinded(record2)) {
|
|
16843
|
+
if (record2.isDeleted || record2.supersededBy || !isOwnedByCtxUser(ctx, record2) || opts.freeFormOnly && isKinded(record2) || opts.expectedContent !== void 0 && record2._getRaw("content") !== readStoredContent) {
|
|
16810
16844
|
stale = true;
|
|
16811
16845
|
return;
|
|
16812
16846
|
}
|
|
16847
|
+
const originalUpdatedAt = record2.updatedAt.getTime();
|
|
16813
16848
|
const nextKind = opts.kind !== void 0 ? opts.kind : record2.kind;
|
|
16814
16849
|
const nextLevel = levelAfter(record2);
|
|
16815
16850
|
assertValidKindLevel(nextKind, nextLevel);
|
|
@@ -16825,7 +16860,7 @@ async function updateVaultMemoryOp(ctx, id2, opts) {
|
|
|
16825
16860
|
replayedObservation = opts.observationSourceIds.every((id3) => observedSources.includes(id3));
|
|
16826
16861
|
}
|
|
16827
16862
|
await record2.update((r) => {
|
|
16828
|
-
r._setRaw("content", encryptedContent);
|
|
16863
|
+
if (encryptedContent !== void 0) r._setRaw("content", encryptedContent);
|
|
16829
16864
|
if (opts.level !== void 0) {
|
|
16830
16865
|
r._setRaw("level", nextLevel);
|
|
16831
16866
|
r._setRaw("scope", scopeForLevel(nextLevel));
|
|
@@ -17593,7 +17628,7 @@ function classifyDecay(m, now, policy) {
|
|
|
17593
17628
|
if (m.source === "manual" || m.source === SOURCE_PHOTO) return "keep";
|
|
17594
17629
|
if (isTimeSensitiveType(m.factType) && m.eventTimeEnd !== null) {
|
|
17595
17630
|
if (m.eventTimeEnd < now - resolved.pastEventGraceMs) return "archive";
|
|
17596
|
-
|
|
17631
|
+
return "keep";
|
|
17597
17632
|
}
|
|
17598
17633
|
if (now - lastActivityAt(m) > ttlForType(m.factType, resolved)) return "archive";
|
|
17599
17634
|
return "keep";
|
|
@@ -21119,7 +21154,6 @@ async function retainWithPersistence(content, ctx, options = {}) {
|
|
|
21119
21154
|
const factTypeUpdate = pickFactTypeUpdate(existing, options.factType);
|
|
21120
21155
|
const resurrect = resurrectFields(existing);
|
|
21121
21156
|
const updated = await ctx.persistence.update(targetId, {
|
|
21122
|
-
content: existing.content,
|
|
21123
21157
|
freeFormOnly: true,
|
|
21124
21158
|
proofCountIncrement: 1,
|
|
21125
21159
|
observationSourceIds: options.sourceChunkIds,
|
|
@@ -21358,7 +21392,6 @@ async function tryConsolidate(trimmed, ctx, options, prepared) {
|
|
|
21358
21392
|
const factTypeUpdate = pickFactTypeUpdate(existing, options.factType);
|
|
21359
21393
|
const resurrect = resurrectFields(existing);
|
|
21360
21394
|
const updated = await ctx.persistence.update(decision.targetId, {
|
|
21361
|
-
content: existing.content,
|
|
21362
21395
|
freeFormOnly: true,
|
|
21363
21396
|
proofCountIncrement: 1,
|
|
21364
21397
|
observationSourceIds: options.sourceChunkIds,
|
|
@@ -21386,6 +21419,10 @@ async function tryConsolidate(trimmed, ctx, options, prepared) {
|
|
|
21386
21419
|
};
|
|
21387
21420
|
}
|
|
21388
21421
|
if (decision.action === "update" && decision.targetId && decision.content) {
|
|
21422
|
+
const expectedContent = candidates.find(
|
|
21423
|
+
(candidate) => candidate.id === decision.targetId
|
|
21424
|
+
)?.content;
|
|
21425
|
+
if (expectedContent === void 0) return null;
|
|
21389
21426
|
const existing = await ctx.persistence.get(decision.targetId);
|
|
21390
21427
|
if (!existing || existing.supersededBy) {
|
|
21391
21428
|
return abandonToRace(
|
|
@@ -21393,6 +21430,9 @@ async function tryConsolidate(trimmed, ctx, options, prepared) {
|
|
|
21393
21430
|
`update: target ${decision.targetId} ${existing ? "superseded" : "deleted"} before the write`
|
|
21394
21431
|
);
|
|
21395
21432
|
}
|
|
21433
|
+
if (existing.content !== expectedContent) {
|
|
21434
|
+
return abandonToRace(options, `update: target ${decision.targetId} edited before the write`);
|
|
21435
|
+
}
|
|
21396
21436
|
const mergedSourceIds = unionStrings(
|
|
21397
21437
|
existing.sourceChunkIds ?? [],
|
|
21398
21438
|
options.sourceChunkIds ?? []
|
|
@@ -21405,6 +21445,7 @@ async function tryConsolidate(trimmed, ctx, options, prepared) {
|
|
|
21405
21445
|
const resurrect = resurrectFields(existing);
|
|
21406
21446
|
const updated = await ctx.persistence.update(decision.targetId, {
|
|
21407
21447
|
content: decision.content,
|
|
21448
|
+
expectedContent,
|
|
21408
21449
|
freeFormOnly: true,
|
|
21409
21450
|
proofCountIncrement: 1,
|
|
21410
21451
|
observationSourceIds: options.sourceChunkIds,
|
|
@@ -21417,10 +21458,10 @@ async function tryConsolidate(trimmed, ctx, options, prepared) {
|
|
|
21417
21458
|
...factTypeUpdate !== void 0 && { factType: factTypeUpdate }
|
|
21418
21459
|
});
|
|
21419
21460
|
if (!updated) {
|
|
21420
|
-
await assertMergeTargetGoneOrThrow(ctx, decision.targetId);
|
|
21461
|
+
await assertMergeTargetGoneOrThrow(ctx, decision.targetId, expectedContent);
|
|
21421
21462
|
return abandonToRace(
|
|
21422
21463
|
options,
|
|
21423
|
-
`update: target ${decision.targetId}
|
|
21464
|
+
`update: target ${decision.targetId} changed mid-write (consolidated rewrite lost)`
|
|
21424
21465
|
);
|
|
21425
21466
|
}
|
|
21426
21467
|
cacheRowVector(
|
|
@@ -21447,9 +21488,9 @@ async function tryConsolidate(trimmed, ctx, options, prepared) {
|
|
|
21447
21488
|
);
|
|
21448
21489
|
return null;
|
|
21449
21490
|
}
|
|
21450
|
-
async function assertMergeTargetGoneOrThrow(ctx, targetId) {
|
|
21491
|
+
async function assertMergeTargetGoneOrThrow(ctx, targetId, expectedContent) {
|
|
21451
21492
|
const stillExists = await (ctx.persistence.getFresh ? ctx.persistence.getFresh(targetId) : ctx.persistence.get(targetId));
|
|
21452
|
-
if (stillExists && (stillExists.kind === null || stillExists.kind === void 0)) {
|
|
21493
|
+
if (stillExists && (stillExists.kind === null || stillExists.kind === void 0) && (expectedContent === void 0 || stillExists.content === expectedContent)) {
|
|
21453
21494
|
throw new RetainError(
|
|
21454
21495
|
"merge-not-persisted",
|
|
21455
21496
|
`retain: merge into memory ${targetId} failed to persist`
|
|
@@ -24887,16 +24928,16 @@ function createRemoteMemoryPipeline(options) {
|
|
|
24887
24928
|
create: (input) => write(createRow(input), 0),
|
|
24888
24929
|
update: async (id2, patch) => {
|
|
24889
24930
|
const existing = await get(id2);
|
|
24890
|
-
if (!existing || patch.freeFormOnly && existing.kind !== null && existing.kind !== void 0)
|
|
24931
|
+
if (!existing || patch.expectedContent !== void 0 && existing.content !== patch.expectedContent || patch.freeFormOnly && existing.kind !== null && existing.kind !== void 0)
|
|
24891
24932
|
return null;
|
|
24892
24933
|
const snapshot = snapshots.get(id2);
|
|
24893
24934
|
const memory = {
|
|
24894
24935
|
...snapshot.memory,
|
|
24895
|
-
content: patch.content,
|
|
24936
|
+
content: patch.content ?? snapshot.memory.content,
|
|
24896
24937
|
updated_at: patch.preserveUpdatedAt ? snapshot.memory.updated_at : Math.max(Date.now(), (snapshot.memory.topics_extracted_at ?? 0) + 1)
|
|
24897
24938
|
};
|
|
24898
24939
|
if (patch.scope !== void 0) memory.scope = patch.scope;
|
|
24899
|
-
if (patch.embedding === void 0 && patch.content !== snapshot.memory.content) {
|
|
24940
|
+
if (patch.embedding === void 0 && patch.content !== void 0 && patch.content !== snapshot.memory.content) {
|
|
24900
24941
|
delete memory.embedding;
|
|
24901
24942
|
delete memory.embedding_model;
|
|
24902
24943
|
}
|
|
@@ -38650,17 +38691,24 @@ var import_react20 = require("react");
|
|
|
38650
38691
|
init_clientConfig();
|
|
38651
38692
|
function useTools(options) {
|
|
38652
38693
|
const { getToken, baseUrl = BASE_URL, includeTools, autoFetch = true } = options;
|
|
38653
|
-
const [
|
|
38694
|
+
const [allTools, setAllTools] = (0, import_react20.useState)([]);
|
|
38654
38695
|
const [checksum, setChecksum] = (0, import_react20.useState)(getToolsChecksum2);
|
|
38655
38696
|
const [isLoading, setIsLoading] = (0, import_react20.useState)(false);
|
|
38656
38697
|
const [error, setError] = (0, import_react20.useState)(null);
|
|
38698
|
+
const includeToolsRef = (0, import_react20.useRef)(includeTools);
|
|
38699
|
+
if (includeTools !== includeToolsRef.current && (includeTools === void 0 || includeToolsRef.current === void 0 || includeTools.length !== includeToolsRef.current.length || includeTools.some((name, i) => name !== includeToolsRef.current?.[i]))) {
|
|
38700
|
+
includeToolsRef.current = includeTools;
|
|
38701
|
+
}
|
|
38702
|
+
const stableIncludeTools = includeToolsRef.current;
|
|
38703
|
+
const tools = (0, import_react20.useMemo)(
|
|
38704
|
+
() => filterServerTools(allTools, stableIncludeTools),
|
|
38705
|
+
[allTools, stableIncludeTools]
|
|
38706
|
+
);
|
|
38657
38707
|
const getTokenRef = (0, import_react20.useRef)(getToken);
|
|
38658
38708
|
const baseUrlRef = (0, import_react20.useRef)(baseUrl);
|
|
38659
|
-
const includeToolsRef = (0, import_react20.useRef)(includeTools);
|
|
38660
38709
|
(0, import_react20.useEffect)(() => {
|
|
38661
38710
|
getTokenRef.current = getToken;
|
|
38662
38711
|
baseUrlRef.current = baseUrl;
|
|
38663
|
-
includeToolsRef.current = includeTools;
|
|
38664
38712
|
});
|
|
38665
38713
|
const fetchTools = (0, import_react20.useCallback)(async (forceRefresh = false) => {
|
|
38666
38714
|
setIsLoading(true);
|
|
@@ -38671,8 +38719,7 @@ function useTools(options) {
|
|
|
38671
38719
|
baseUrl: baseUrlRef.current,
|
|
38672
38720
|
forceRefresh
|
|
38673
38721
|
});
|
|
38674
|
-
|
|
38675
|
-
setTools(filteredTools);
|
|
38722
|
+
setAllTools(fetchedTools);
|
|
38676
38723
|
setChecksum(getToolsChecksum2());
|
|
38677
38724
|
} catch (err) {
|
|
38678
38725
|
setError(err instanceof Error ? err : new Error(String(err)));
|
|
@@ -38696,11 +38743,6 @@ function useTools(options) {
|
|
|
38696
38743
|
},
|
|
38697
38744
|
[refresh]
|
|
38698
38745
|
);
|
|
38699
|
-
(0, import_react20.useEffect)(() => {
|
|
38700
|
-
if (tools.length > 0 && includeTools !== void 0) {
|
|
38701
|
-
setTools((currentTools) => filterServerTools(currentTools, includeTools));
|
|
38702
|
-
}
|
|
38703
|
-
}, [includeTools, tools.length]);
|
|
38704
38746
|
const hasFetchedRef = (0, import_react20.useRef)(false);
|
|
38705
38747
|
(0, import_react20.useEffect)(() => {
|
|
38706
38748
|
if (autoFetch && !hasFetchedRef.current) {
|
package/dist/react/index.d.mts
CHANGED
|
@@ -6185,7 +6185,8 @@ interface CreateVaultMemoryOptions {
|
|
|
6185
6185
|
geohash?: string;
|
|
6186
6186
|
}
|
|
6187
6187
|
interface UpdateVaultMemoryOptions {
|
|
6188
|
-
content
|
|
6188
|
+
content?: string;
|
|
6189
|
+
expectedContent?: string;
|
|
6189
6190
|
/** When true, the write is skipped (returns null) if the row carries a profile kind. */
|
|
6190
6191
|
freeFormOnly?: boolean;
|
|
6191
6192
|
/**
|
|
@@ -6878,9 +6879,10 @@ declare function ttlForType(factType: string | null, policy?: Partial<DecayPolic
|
|
|
6878
6879
|
* null `eventTimeEnd` is still ongoing, so this rule does not fire for it.
|
|
6879
6880
|
* 4. Age fallback — `now - updatedAt > TTL(factType)` → archive. Durable types
|
|
6880
6881
|
* have Infinity TTL, so this never fires for them; null/unknown use medium.
|
|
6881
|
-
* EXCEPTION: a `plan
|
|
6882
|
-
* (`eventTimeEnd >= now
|
|
6883
|
-
*
|
|
6882
|
+
* EXCEPTION: a `plan` / `ongoing_context` with an upcoming event or an event
|
|
6883
|
+
* within the grace period (`eventTimeEnd >= now - pastEventGraceMs`) stays
|
|
6884
|
+
* active, even after its activity TTL expires. Rule 3 archives it after the
|
|
6885
|
+
* grace period ends.
|
|
6884
6886
|
* 5. Otherwise → keep.
|
|
6885
6887
|
*
|
|
6886
6888
|
* @param m Plaintext decay inputs for one row.
|
|
@@ -7211,7 +7213,9 @@ type MemoryCreate = Pick<CreateVaultMemoryOptions, "content" | "scope" | "factTy
|
|
|
7211
7213
|
* `embedding` (with `embeddingModel`) only when you already have the new one.
|
|
7212
7214
|
* @public
|
|
7213
7215
|
*/
|
|
7214
|
-
type MemoryUpdate = Pick<UpdateVaultMemoryOptions, "
|
|
7216
|
+
type MemoryUpdate = Pick<UpdateVaultMemoryOptions, "scope" | "factType" | "eventTime" | "embedding" | "embeddingModel" | "kind" | "kindValue" | "level"> & {
|
|
7217
|
+
content: string;
|
|
7218
|
+
};
|
|
7215
7219
|
/**
|
|
7216
7220
|
* Fact-only recall. Conversation chunks are message storage, not memory, so
|
|
7217
7221
|
* the chunk-lane knobs are not part of this surface; nor is `folderId` (see
|
package/dist/react/index.d.ts
CHANGED
|
@@ -6185,7 +6185,8 @@ interface CreateVaultMemoryOptions {
|
|
|
6185
6185
|
geohash?: string;
|
|
6186
6186
|
}
|
|
6187
6187
|
interface UpdateVaultMemoryOptions {
|
|
6188
|
-
content
|
|
6188
|
+
content?: string;
|
|
6189
|
+
expectedContent?: string;
|
|
6189
6190
|
/** When true, the write is skipped (returns null) if the row carries a profile kind. */
|
|
6190
6191
|
freeFormOnly?: boolean;
|
|
6191
6192
|
/**
|
|
@@ -6878,9 +6879,10 @@ declare function ttlForType(factType: string | null, policy?: Partial<DecayPolic
|
|
|
6878
6879
|
* null `eventTimeEnd` is still ongoing, so this rule does not fire for it.
|
|
6879
6880
|
* 4. Age fallback — `now - updatedAt > TTL(factType)` → archive. Durable types
|
|
6880
6881
|
* have Infinity TTL, so this never fires for them; null/unknown use medium.
|
|
6881
|
-
* EXCEPTION: a `plan
|
|
6882
|
-
* (`eventTimeEnd >= now
|
|
6883
|
-
*
|
|
6882
|
+
* EXCEPTION: a `plan` / `ongoing_context` with an upcoming event or an event
|
|
6883
|
+
* within the grace period (`eventTimeEnd >= now - pastEventGraceMs`) stays
|
|
6884
|
+
* active, even after its activity TTL expires. Rule 3 archives it after the
|
|
6885
|
+
* grace period ends.
|
|
6884
6886
|
* 5. Otherwise → keep.
|
|
6885
6887
|
*
|
|
6886
6888
|
* @param m Plaintext decay inputs for one row.
|
|
@@ -7211,7 +7213,9 @@ type MemoryCreate = Pick<CreateVaultMemoryOptions, "content" | "scope" | "factTy
|
|
|
7211
7213
|
* `embedding` (with `embeddingModel`) only when you already have the new one.
|
|
7212
7214
|
* @public
|
|
7213
7215
|
*/
|
|
7214
|
-
type MemoryUpdate = Pick<UpdateVaultMemoryOptions, "
|
|
7216
|
+
type MemoryUpdate = Pick<UpdateVaultMemoryOptions, "scope" | "factType" | "eventTime" | "embedding" | "embeddingModel" | "kind" | "kindValue" | "level"> & {
|
|
7217
|
+
content: string;
|
|
7218
|
+
};
|
|
7215
7219
|
/**
|
|
7216
7220
|
* Fact-only recall. Conversation chunks are message storage, not memory, so
|
|
7217
7221
|
* the chunk-lane knobs are not part of this surface; nor is `folderId` (see
|