@anuma/sdk 7.0.6 → 7.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/expo/index.cjs +365 -112
- package/dist/expo/index.d.mts +34 -4
- package/dist/expo/index.d.ts +34 -4
- package/dist/expo/index.mjs +362 -112
- package/dist/memory/context.d.mts +1 -0
- package/dist/memory/context.d.ts +1 -0
- package/dist/react/index.cjs +370 -112
- package/dist/react/index.d.mts +34 -4
- package/dist/react/index.d.ts +34 -4
- package/dist/react/index.mjs +367 -112
- package/dist/server/index.cjs +157 -30
- package/dist/server/index.d.mts +22 -2
- package/dist/server/index.d.ts +22 -2
- package/dist/server/index.mjs +157 -30
- package/package.json +1 -1
package/dist/react/index.mjs
CHANGED
|
@@ -10495,6 +10495,11 @@ function parseTopics(value) {
|
|
|
10495
10495
|
}
|
|
10496
10496
|
|
|
10497
10497
|
// src/lib/db/entities/operations.ts
|
|
10498
|
+
async function assertCanWrite(ctx) {
|
|
10499
|
+
if (ctx.canWrite && !await ctx.canWrite()) {
|
|
10500
|
+
throw new Error("Memory source is no longer eligible");
|
|
10501
|
+
}
|
|
10502
|
+
}
|
|
10498
10503
|
function entityToStored(e) {
|
|
10499
10504
|
return {
|
|
10500
10505
|
uniqueId: e.id,
|
|
@@ -10635,6 +10640,7 @@ async function linkMemoryEntitiesOp(ctx, memoryId, entityInputs, options) {
|
|
|
10635
10640
|
let skipped = false;
|
|
10636
10641
|
let entities = [];
|
|
10637
10642
|
await ctx.database.write(async () => {
|
|
10643
|
+
await assertCanWrite(ctx);
|
|
10638
10644
|
const {
|
|
10639
10645
|
entities: byName,
|
|
10640
10646
|
operations: entityOps,
|
|
@@ -10710,6 +10716,7 @@ async function replaceMemoryEntities(ctx, memoryId, entityInputs, options) {
|
|
|
10710
10716
|
let skipped = false;
|
|
10711
10717
|
let entities = [];
|
|
10712
10718
|
await ctx.database.write(async () => {
|
|
10719
|
+
await assertCanWrite(ctx);
|
|
10713
10720
|
const vaultRow = await findVaultRowInWrite(ctx, memoryId);
|
|
10714
10721
|
if (options.guarded && autoLinkBlocked(vaultRow)) {
|
|
10715
10722
|
skipped = true;
|
|
@@ -10770,6 +10777,7 @@ async function unlinkMemoryEntitiesOp(ctx, memoryIds) {
|
|
|
10770
10777
|
const links = await ctx.memoryEntityCollection.query(Q5.where("memory_id", Q5.oneOf(Array.from(memoryIds)))).fetch();
|
|
10771
10778
|
if (links.length === 0) return;
|
|
10772
10779
|
await ctx.database.write(async () => {
|
|
10780
|
+
await assertCanWrite(ctx);
|
|
10773
10781
|
await ctx.database.batch(...links.map((l) => l.prepareDestroyPermanently()));
|
|
10774
10782
|
});
|
|
10775
10783
|
}
|
|
@@ -10778,6 +10786,7 @@ async function unlinkAllMemoryEntitiesForUserOp(ctx, userId) {
|
|
|
10778
10786
|
const links = await ctx.memoryEntityCollection.query(Q5.where("user_id", userId)).fetch();
|
|
10779
10787
|
if (links.length === 0) return;
|
|
10780
10788
|
await ctx.database.write(async () => {
|
|
10789
|
+
await assertCanWrite(ctx);
|
|
10781
10790
|
await ctx.database.batch(...links.map((l) => l.prepareDestroyPermanently()));
|
|
10782
10791
|
});
|
|
10783
10792
|
}
|
|
@@ -10797,6 +10806,7 @@ async function backfillMemoryEntityUserIdsOp(ctx, vaultMemoryCollection) {
|
|
|
10797
10806
|
}
|
|
10798
10807
|
if (toUpdate.length === 0) return 0;
|
|
10799
10808
|
await ctx.database.write(async () => {
|
|
10809
|
+
await assertCanWrite(ctx);
|
|
10800
10810
|
await ctx.database.batch(
|
|
10801
10811
|
...toUpdate.map(({ link, userId }) => link.prepareUpdate((r) => r._setRaw("user_id", userId)))
|
|
10802
10812
|
);
|
|
@@ -13118,6 +13128,17 @@ async function decryptVaultMemoryFields(memory, address, signMessage, embeddedWa
|
|
|
13118
13128
|
};
|
|
13119
13129
|
}
|
|
13120
13130
|
|
|
13131
|
+
// src/lib/db/memoryVault/sourceChunkIds.ts
|
|
13132
|
+
var MAX_SOURCE_CHUNK_IDS_BYTES = 16 << 10;
|
|
13133
|
+
var utf8 = new TextEncoder();
|
|
13134
|
+
function serializeSourceChunkIds(ids) {
|
|
13135
|
+
const sizes = ids.map((id) => utf8.encode(JSON.stringify(id)).length + 1);
|
|
13136
|
+
let total = sizes.reduce((sum, size) => sum + size, 1);
|
|
13137
|
+
let start = 0;
|
|
13138
|
+
while (total > MAX_SOURCE_CHUNK_IDS_BYTES && start < ids.length) total -= sizes[start++];
|
|
13139
|
+
return JSON.stringify(ids.slice(start));
|
|
13140
|
+
}
|
|
13141
|
+
|
|
13121
13142
|
// src/lib/db/memoryVault/types.ts
|
|
13122
13143
|
var MEMORY_KINDS = [
|
|
13123
13144
|
"display_name",
|
|
@@ -13190,6 +13211,11 @@ function visibilityConditions(requested) {
|
|
|
13190
13211
|
function isKinded(record2) {
|
|
13191
13212
|
return record2.kind !== null && record2.kind !== void 0;
|
|
13192
13213
|
}
|
|
13214
|
+
async function assertCanWrite2(ctx) {
|
|
13215
|
+
if (ctx.canWrite && !await ctx.canWrite()) {
|
|
13216
|
+
throw new Error("Memory source is no longer eligible");
|
|
13217
|
+
}
|
|
13218
|
+
}
|
|
13193
13219
|
function assertValidKindLevel(kind, level) {
|
|
13194
13220
|
const hasKind = kind !== null && kind !== void 0;
|
|
13195
13221
|
if (hasKind && !MEMORY_KINDS.includes(kind)) {
|
|
@@ -13265,15 +13291,15 @@ async function mapInBatches(items, fn) {
|
|
|
13265
13291
|
return results;
|
|
13266
13292
|
}
|
|
13267
13293
|
function vaultMemoryToStoredRaw(memory) {
|
|
13268
|
-
let
|
|
13294
|
+
let sourceChunkIds2 = null;
|
|
13269
13295
|
if (memory.sourceChunkIds) {
|
|
13270
13296
|
try {
|
|
13271
13297
|
const parsed = JSON.parse(memory.sourceChunkIds);
|
|
13272
13298
|
if (Array.isArray(parsed)) {
|
|
13273
|
-
|
|
13299
|
+
sourceChunkIds2 = parsed.filter((s) => typeof s === "string");
|
|
13274
13300
|
}
|
|
13275
13301
|
} catch {
|
|
13276
|
-
|
|
13302
|
+
sourceChunkIds2 = null;
|
|
13277
13303
|
}
|
|
13278
13304
|
}
|
|
13279
13305
|
return {
|
|
@@ -13287,7 +13313,7 @@ function vaultMemoryToStoredRaw(memory) {
|
|
|
13287
13313
|
userId: memory.userId ?? null,
|
|
13288
13314
|
embedding: memory.embedding ?? null,
|
|
13289
13315
|
embeddingModel: memory.embeddingModel ?? null,
|
|
13290
|
-
sourceChunkIds,
|
|
13316
|
+
sourceChunkIds: sourceChunkIds2,
|
|
13291
13317
|
proofCount: memory.proofCount ?? null,
|
|
13292
13318
|
source: memory.source ?? null,
|
|
13293
13319
|
media: parseMedia(memory.media),
|
|
@@ -13336,7 +13362,7 @@ function populateNewVaultMemory(record2, ctx, opts, encryptedContent, encryptedK
|
|
|
13336
13362
|
record2._setRaw("embedding_model", opts.embeddingModel ?? null);
|
|
13337
13363
|
}
|
|
13338
13364
|
if (opts.sourceChunkIds !== void 0) {
|
|
13339
|
-
record2._setRaw("source_chunk_ids",
|
|
13365
|
+
record2._setRaw("source_chunk_ids", serializeSourceChunkIds(opts.sourceChunkIds));
|
|
13340
13366
|
}
|
|
13341
13367
|
record2._setRaw("proof_count", opts.proofCount ?? 1);
|
|
13342
13368
|
record2._setRaw("source", opts.source ?? "manual");
|
|
@@ -13370,8 +13396,7 @@ async function createVaultMemoryOp(ctx, opts) {
|
|
|
13370
13396
|
ctx.embeddedWalletSigner
|
|
13371
13397
|
) : opts.content;
|
|
13372
13398
|
const created = await ctx.database.write(async () => {
|
|
13373
|
-
|
|
13374
|
-
throw new Error("Memory source is no longer eligible");
|
|
13399
|
+
await assertCanWrite2(ctx);
|
|
13375
13400
|
return ctx.vaultMemoryCollection.create(
|
|
13376
13401
|
(record2) => populateNewVaultMemory(record2, ctx, opts, encryptedContent, encryptedKindValue)
|
|
13377
13402
|
);
|
|
@@ -13390,8 +13415,7 @@ async function createSupersedingMemoryOp(ctx, opts, targetId) {
|
|
|
13390
13415
|
) : opts.content;
|
|
13391
13416
|
let createdRecord = null;
|
|
13392
13417
|
await ctx.database.write(async () => {
|
|
13393
|
-
|
|
13394
|
-
throw new Error("Memory source is no longer eligible");
|
|
13418
|
+
await assertCanWrite2(ctx);
|
|
13395
13419
|
let target;
|
|
13396
13420
|
try {
|
|
13397
13421
|
target = await ctx.vaultMemoryCollection.find(targetId);
|
|
@@ -13483,8 +13507,7 @@ async function createVaultMemoriesBatchOp(ctx, optionsArray) {
|
|
|
13483
13507
|
})
|
|
13484
13508
|
);
|
|
13485
13509
|
const created = await ctx.database.write(async () => {
|
|
13486
|
-
|
|
13487
|
-
throw new Error("Memory source is no longer eligible");
|
|
13510
|
+
await assertCanWrite2(ctx);
|
|
13488
13511
|
const prepared = optionsArray.map(
|
|
13489
13512
|
(opts, i) => ctx.vaultMemoryCollection.prepareCreate(
|
|
13490
13513
|
(record2) => populateNewVaultMemory(record2, ctx, opts, encryptedContents[i], encryptedKindValues[i])
|
|
@@ -13514,16 +13537,16 @@ async function getVaultMemoryOp(ctx, id) {
|
|
|
13514
13537
|
}
|
|
13515
13538
|
}
|
|
13516
13539
|
function vaultMemoryRawToStoredRaw(raw) {
|
|
13517
|
-
let
|
|
13540
|
+
let sourceChunkIds2 = null;
|
|
13518
13541
|
const rawChunks = raw.source_chunk_ids;
|
|
13519
13542
|
if (typeof rawChunks === "string" && rawChunks) {
|
|
13520
13543
|
try {
|
|
13521
13544
|
const parsed = JSON.parse(rawChunks);
|
|
13522
13545
|
if (Array.isArray(parsed)) {
|
|
13523
|
-
|
|
13546
|
+
sourceChunkIds2 = parsed.filter((s) => typeof s === "string");
|
|
13524
13547
|
}
|
|
13525
13548
|
} catch {
|
|
13526
|
-
|
|
13549
|
+
sourceChunkIds2 = null;
|
|
13527
13550
|
}
|
|
13528
13551
|
}
|
|
13529
13552
|
return {
|
|
@@ -13537,7 +13560,7 @@ function vaultMemoryRawToStoredRaw(raw) {
|
|
|
13537
13560
|
userId: raw.user_id ?? null,
|
|
13538
13561
|
embedding: raw.embedding ?? null,
|
|
13539
13562
|
embeddingModel: raw.embedding_model ?? null,
|
|
13540
|
-
sourceChunkIds,
|
|
13563
|
+
sourceChunkIds: sourceChunkIds2,
|
|
13541
13564
|
proofCount: raw.proof_count ?? null,
|
|
13542
13565
|
source: raw.source ?? null,
|
|
13543
13566
|
eventTimeStart: raw.event_time_start ?? null,
|
|
@@ -13789,8 +13812,7 @@ async function updateVaultMemoryOp(ctx, id, opts) {
|
|
|
13789
13812
|
const record2 = probe;
|
|
13790
13813
|
const originalUpdatedAt = record2.updatedAt.getTime();
|
|
13791
13814
|
await ctx.database.write(async () => {
|
|
13792
|
-
|
|
13793
|
-
throw new Error("Memory source is no longer eligible");
|
|
13815
|
+
await assertCanWrite2(ctx);
|
|
13794
13816
|
if (record2.isDeleted || record2.supersededBy || !isOwnedByCtxUser(ctx, record2) || opts.freeFormOnly && isKinded(record2)) {
|
|
13795
13817
|
stale = true;
|
|
13796
13818
|
return;
|
|
@@ -13834,7 +13856,7 @@ async function updateVaultMemoryOp(ctx, id, opts) {
|
|
|
13834
13856
|
if (opts.sourceChunkIds !== void 0) {
|
|
13835
13857
|
r._setRaw(
|
|
13836
13858
|
"source_chunk_ids",
|
|
13837
|
-
|
|
13859
|
+
serializeSourceChunkIds(
|
|
13838
13860
|
opts.observationSourceIds?.length ? [.../* @__PURE__ */ new Set([...observedSources, ...opts.sourceChunkIds])] : opts.sourceChunkIds
|
|
13839
13861
|
)
|
|
13840
13862
|
);
|
|
@@ -13901,6 +13923,7 @@ async function setMemoryEntitiesOp(ctx, memoryId, entities) {
|
|
|
13901
13923
|
let stale = false;
|
|
13902
13924
|
const originalUpdatedAt = record2.updatedAt.getTime();
|
|
13903
13925
|
await ctx.database.write(async (writer) => {
|
|
13926
|
+
await assertCanWrite2(ctx);
|
|
13904
13927
|
if (record2.isDeleted || !isOwnedByCtxUser(ctx, record2)) {
|
|
13905
13928
|
stale = true;
|
|
13906
13929
|
return;
|
|
@@ -13942,6 +13965,7 @@ async function clearMemoryTopicsOverrideOp(ctx, memoryId, options) {
|
|
|
13942
13965
|
const originalUpdatedAt = record2.updatedAt.getTime();
|
|
13943
13966
|
let cleared = false;
|
|
13944
13967
|
await ctx.database.write(async () => {
|
|
13968
|
+
await assertCanWrite2(ctx);
|
|
13945
13969
|
if (options?.unlessTopicsRecorded && parseTopics(record2.topics) !== null) return;
|
|
13946
13970
|
cleared = true;
|
|
13947
13971
|
await record2.update((r) => {
|
|
@@ -13965,6 +13989,7 @@ async function setMemoryVisibilityOp(ctx, id, opts) {
|
|
|
13965
13989
|
if (record2.isDeleted || !isOwnedByCtxUser(ctx, record2)) return null;
|
|
13966
13990
|
let stale = false;
|
|
13967
13991
|
await ctx.database.write(async () => {
|
|
13992
|
+
await assertCanWrite2(ctx);
|
|
13968
13993
|
if (record2.isDeleted || !isOwnedByCtxUser(ctx, record2)) {
|
|
13969
13994
|
stale = true;
|
|
13970
13995
|
return;
|
|
@@ -13993,6 +14018,7 @@ async function deleteVaultMemoryOp(ctx, id) {
|
|
|
13993
14018
|
if (record2.isDeleted || !isOwnedByCtxUser(ctx, record2)) return false;
|
|
13994
14019
|
let stale = false;
|
|
13995
14020
|
await ctx.database.write(async () => {
|
|
14021
|
+
await assertCanWrite2(ctx);
|
|
13996
14022
|
if (record2.isDeleted || !isOwnedByCtxUser(ctx, record2)) {
|
|
13997
14023
|
stale = true;
|
|
13998
14024
|
return;
|
|
@@ -14030,8 +14056,7 @@ async function supersedeVaultMemoryOp(ctx, id, supersededById) {
|
|
|
14030
14056
|
}
|
|
14031
14057
|
let stale = false;
|
|
14032
14058
|
await ctx.database.write(async () => {
|
|
14033
|
-
|
|
14034
|
-
throw new Error("Memory source is no longer eligible");
|
|
14059
|
+
await assertCanWrite2(ctx);
|
|
14035
14060
|
if (record2.isDeleted || record2.supersededBy || !isOwnedByCtxUser(ctx, record2)) {
|
|
14036
14061
|
stale = true;
|
|
14037
14062
|
return;
|
|
@@ -14193,6 +14218,7 @@ async function stampTopicsExtractedAtOp(ctx, memoryIds, extractedAt, version = T
|
|
|
14193
14218
|
for (let i = 0; i < uniqueIds.length; i += CHUNK) {
|
|
14194
14219
|
const chunkIds = uniqueIds.slice(i, i + CHUNK);
|
|
14195
14220
|
await ctx.database.write(async () => {
|
|
14221
|
+
await assertCanWrite2(ctx);
|
|
14196
14222
|
const records = [];
|
|
14197
14223
|
for (const id of chunkIds) {
|
|
14198
14224
|
try {
|
|
@@ -14226,6 +14252,7 @@ async function relinkMemoryTopicsOp(ctx, memoryIds) {
|
|
|
14226
14252
|
for (const id of Array.from(new Set(memoryIds))) {
|
|
14227
14253
|
try {
|
|
14228
14254
|
await ctx.database.write(async (writer) => {
|
|
14255
|
+
await assertCanWrite2(ctx);
|
|
14229
14256
|
let record2;
|
|
14230
14257
|
try {
|
|
14231
14258
|
record2 = await ctx.vaultMemoryCollection.find(id);
|
|
@@ -14256,6 +14283,7 @@ async function backfillMemoryTopicsOp(ctx, memoryIds) {
|
|
|
14256
14283
|
for (let i = 0; i < uniqueIds.length; i += CHUNK) {
|
|
14257
14284
|
const chunkIds = uniqueIds.slice(i, i + CHUNK);
|
|
14258
14285
|
await ctx.database.write(async () => {
|
|
14286
|
+
await assertCanWrite2(ctx);
|
|
14259
14287
|
const writes = [];
|
|
14260
14288
|
for (const id of chunkIds) {
|
|
14261
14289
|
let record2;
|
|
@@ -14288,6 +14316,7 @@ async function deleteAllVaultMemoriesForUserOp(ctx, userId) {
|
|
|
14288
14316
|
const records = await ctx.vaultMemoryCollection.query(Q8.where("user_id", userId), Q8.where("is_deleted", false)).fetch();
|
|
14289
14317
|
if (records.length === 0) return 0;
|
|
14290
14318
|
await ctx.database.write(async () => {
|
|
14319
|
+
await assertCanWrite2(ctx);
|
|
14291
14320
|
const prepared = records.map(
|
|
14292
14321
|
(record2) => record2.prepareUpdate((r) => {
|
|
14293
14322
|
r._setRaw("is_deleted", true);
|
|
@@ -14342,6 +14371,7 @@ async function archiveVaultMemoryOp(ctx, id, opts) {
|
|
|
14342
14371
|
let stale = false;
|
|
14343
14372
|
const archivedAtValue = opts?.now ?? Date.now();
|
|
14344
14373
|
await ctx.database.write(async () => {
|
|
14374
|
+
await assertCanWrite2(ctx);
|
|
14345
14375
|
if (record2.isDeleted || !isOwnedByCtxUser(ctx, record2) || record2.archivedAt !== null) {
|
|
14346
14376
|
stale = true;
|
|
14347
14377
|
return;
|
|
@@ -14365,6 +14395,7 @@ async function restoreVaultMemoryOp(ctx, id) {
|
|
|
14365
14395
|
if (record2.isDeleted || !isOwnedByCtxUser(ctx, record2)) return false;
|
|
14366
14396
|
let stale = false;
|
|
14367
14397
|
await ctx.database.write(async () => {
|
|
14398
|
+
await assertCanWrite2(ctx);
|
|
14368
14399
|
if (record2.isDeleted || !isOwnedByCtxUser(ctx, record2)) {
|
|
14369
14400
|
stale = true;
|
|
14370
14401
|
return;
|
|
@@ -14385,6 +14416,7 @@ async function hardDeleteDecayedOp(ctx, id, opts) {
|
|
|
14385
14416
|
const now = opts.now ?? Date.now();
|
|
14386
14417
|
let stale = false;
|
|
14387
14418
|
await ctx.database.write(async () => {
|
|
14419
|
+
await assertCanWrite2(ctx);
|
|
14388
14420
|
const archivedAt = record2.archivedAt;
|
|
14389
14421
|
if (record2.isDeleted || !isOwnedByCtxUser(ctx, record2) || archivedAt === null || now - archivedAt <= opts.hardDeleteWindowMs) {
|
|
14390
14422
|
stale = true;
|
|
@@ -14424,6 +14456,7 @@ async function updateVaultMemoryEmbeddingOp(ctx, id, embedding2, embeddingModel,
|
|
|
14424
14456
|
}
|
|
14425
14457
|
let written = false;
|
|
14426
14458
|
await ctx.database.write(async () => {
|
|
14459
|
+
await assertCanWrite2(ctx);
|
|
14427
14460
|
if (record2.isDeleted || !isOwnedByCtxUser(ctx, record2)) return;
|
|
14428
14461
|
const originalUpdatedAt = record2.updatedAt.getTime();
|
|
14429
14462
|
if (originalUpdatedAt !== readUpdatedAt || record2._getRaw("content") !== readStoredContent)
|
|
@@ -18393,6 +18426,13 @@ function restoreCandidates(candidates, redactor, ownNames) {
|
|
|
18393
18426
|
).map((c) => c.candidate);
|
|
18394
18427
|
}
|
|
18395
18428
|
async function extractAndRetain(messages, retainCtx, options) {
|
|
18429
|
+
const { memoryStore, signal } = options;
|
|
18430
|
+
if (memoryStore === null) throw new Error("Memory store is not ready");
|
|
18431
|
+
if (memoryStore && options.folderId !== void 0 && options.folderId !== null)
|
|
18432
|
+
throw new Error("Remote memory extraction does not support folders");
|
|
18433
|
+
if (memoryStore && options.extract.piiRedaction && !memoryStore.masksEmbeddingInput)
|
|
18434
|
+
throw new Error("PII-redacted extraction requires a memory store that masks embedding inputs");
|
|
18435
|
+
signal?.throwIfAborted();
|
|
18396
18436
|
const minConfidence = options.minConfidence ?? DEFAULT_MIN_CONFIDENCE;
|
|
18397
18437
|
const resolvedConsolidatePii = options.consolidateOptions?.piiRedaction ?? options.extract.piiRedaction;
|
|
18398
18438
|
const consolidateOptions = options.consolidateOptions !== void 0 ? {
|
|
@@ -18426,6 +18466,7 @@ async function extractAndRetain(messages, retainCtx, options) {
|
|
|
18426
18466
|
}
|
|
18427
18467
|
});
|
|
18428
18468
|
const extractMs = Date.now() - tExtract;
|
|
18469
|
+
signal?.throwIfAborted();
|
|
18429
18470
|
const filtered = candidates.filter((c) => c.confidence >= minConfidence);
|
|
18430
18471
|
const log = getLogger();
|
|
18431
18472
|
const screened = screenCandidatesForInjection(filtered);
|
|
@@ -18473,16 +18514,33 @@ async function extractAndRetain(messages, retainCtx, options) {
|
|
|
18473
18514
|
const results = [];
|
|
18474
18515
|
const quarantinedInfo = [];
|
|
18475
18516
|
let failedWrites = 0;
|
|
18517
|
+
let auditRows;
|
|
18476
18518
|
const tRetain = Date.now();
|
|
18477
18519
|
for (const { candidate, isQuarantined, reason, signature } of toRetain) {
|
|
18478
18520
|
try {
|
|
18521
|
+
signal?.throwIfAborted();
|
|
18479
18522
|
if (isQuarantined) {
|
|
18480
|
-
|
|
18481
|
-
|
|
18482
|
-
|
|
18483
|
-
|
|
18484
|
-
|
|
18485
|
-
|
|
18523
|
+
let existingId;
|
|
18524
|
+
if (memoryStore) {
|
|
18525
|
+
auditRows ?? (auditRows = memoryStore.list({
|
|
18526
|
+
scopes: [options.scope ?? "private"],
|
|
18527
|
+
includeArchived: true,
|
|
18528
|
+
includeQuarantined: true,
|
|
18529
|
+
includeSuperseded: true
|
|
18530
|
+
}));
|
|
18531
|
+
const sourceKey = [...new Set(candidate.sourceMessageIds)].sort().join("\0");
|
|
18532
|
+
const normalize = (value) => value.normalize("NFKC").trim().replace(/\s+/g, " ").toLowerCase();
|
|
18533
|
+
existingId = (await auditRows).find(
|
|
18534
|
+
(row) => row.trustTier === "quarantined" && row.scope === (options.scope ?? "private") && [...new Set(row.sourceChunkIds ?? [])].sort().join("\0") === sourceKey && normalize(row.content) === normalize(candidate.content)
|
|
18535
|
+
)?.uniqueId ?? null;
|
|
18536
|
+
} else {
|
|
18537
|
+
existingId = await findQuarantinedDuplicateOp(
|
|
18538
|
+
retainCtx.vaultCtx,
|
|
18539
|
+
candidate.content,
|
|
18540
|
+
candidate.sourceMessageIds,
|
|
18541
|
+
{ scope: options.scope ?? "private", folderId: options.folderId ?? null }
|
|
18542
|
+
).catch(() => null);
|
|
18543
|
+
}
|
|
18486
18544
|
if (existingId) {
|
|
18487
18545
|
quarantinedInfo.push({
|
|
18488
18546
|
candidate,
|
|
@@ -18493,18 +18551,26 @@ async function extractAndRetain(messages, retainCtx, options) {
|
|
|
18493
18551
|
continue;
|
|
18494
18552
|
}
|
|
18495
18553
|
}
|
|
18496
|
-
const
|
|
18554
|
+
const retainOptions = {
|
|
18497
18555
|
source: "auto-extracted",
|
|
18498
18556
|
sourceChunkIds: candidate.sourceMessageIds,
|
|
18499
18557
|
respectTombstones: true,
|
|
18500
18558
|
...options.scope !== void 0 && { scope: options.scope },
|
|
18501
|
-
...options.folderId !== void 0 && { folderId: options.folderId },
|
|
18502
18559
|
...consolidateOptions !== void 0 && { consolidateOptions },
|
|
18503
18560
|
...candidate.eventTime !== null && { eventTime: candidate.eventTime },
|
|
18504
18561
|
factType: candidate.type,
|
|
18505
18562
|
...isQuarantined && { trustTier: "quarantined", enableAutoMerge: false }
|
|
18563
|
+
};
|
|
18564
|
+
const result = memoryStore ? await memoryStore.retain(candidate.content, {
|
|
18565
|
+
...retainOptions,
|
|
18566
|
+
canWrite: retainCtx.vaultCtx.canWrite,
|
|
18567
|
+
signal
|
|
18568
|
+
}) : await retain(candidate.content, retainCtx, {
|
|
18569
|
+
...retainOptions,
|
|
18570
|
+
...options.folderId !== void 0 && { folderId: options.folderId }
|
|
18506
18571
|
});
|
|
18507
18572
|
if (isQuarantined) {
|
|
18573
|
+
auditRows = void 0;
|
|
18508
18574
|
const info = {
|
|
18509
18575
|
candidate,
|
|
18510
18576
|
memoryId: result.memoryId,
|
|
@@ -18523,9 +18589,16 @@ async function extractAndRetain(messages, retainCtx, options) {
|
|
|
18523
18589
|
}
|
|
18524
18590
|
succeededCandidates.push(candidate);
|
|
18525
18591
|
results.push(result);
|
|
18526
|
-
if (result.action !== "suppressed" &&
|
|
18592
|
+
if (result.action !== "suppressed" && candidate.entities.length > 0) {
|
|
18527
18593
|
try {
|
|
18528
|
-
|
|
18594
|
+
signal?.throwIfAborted();
|
|
18595
|
+
if (memoryStore) {
|
|
18596
|
+
await memoryStore.addTopics(result.memoryId, candidate.entities, {
|
|
18597
|
+
unlessUserManaged: true,
|
|
18598
|
+
canWrite: retainCtx.vaultCtx.canWrite,
|
|
18599
|
+
signal
|
|
18600
|
+
});
|
|
18601
|
+
} else if (options.entityCtx && !await isMemoryTopicsUserManaged(options.entityCtx, result.memoryId)) {
|
|
18529
18602
|
await linkMemoryEntitiesOp(options.entityCtx, result.memoryId, candidate.entities, {
|
|
18530
18603
|
unlessTopicsUserManaged: true
|
|
18531
18604
|
});
|
|
@@ -18773,7 +18846,7 @@ function createAutoExtractor(options) {
|
|
|
18773
18846
|
};
|
|
18774
18847
|
const consolidateOptions = options.consolidate ? { ...options.consolidate, ...subPassAuth(options.consolidate.baseUrl) } : void 0;
|
|
18775
18848
|
const injectionClassifierOptions = options.injectionClassifier ? { ...options.injectionClassifier, ...subPassAuth(options.injectionClassifier.baseUrl) } : void 0;
|
|
18776
|
-
if (options.retainCtx.vaultCtx.entityCtx && !options.entityCtx) {
|
|
18849
|
+
if (!options.memoryStore && options.retainCtx.vaultCtx.entityCtx && !options.entityCtx) {
|
|
18777
18850
|
getLogger().warn(
|
|
18778
18851
|
"[memory/extract] retainCtx.vaultCtx.entityCtx is set but extractor was created without `entityCtx` \u2014 W5 graph lane will receive no writes"
|
|
18779
18852
|
);
|
|
@@ -18818,6 +18891,8 @@ function createAutoExtractor(options) {
|
|
|
18818
18891
|
try {
|
|
18819
18892
|
const { candidates, results, failedCount, outcome: outcome2, failure, funnel, timings, model } = await extractAndRetain(window2, retainCtx, {
|
|
18820
18893
|
extract,
|
|
18894
|
+
memoryStore: options.memoryStore,
|
|
18895
|
+
signal: options.signal,
|
|
18821
18896
|
...options.minConfidence !== void 0 && { minConfidence: options.minConfidence },
|
|
18822
18897
|
...options.entityCtx !== void 0 && { entityCtx: options.entityCtx },
|
|
18823
18898
|
...options.scope !== void 0 && { scope: options.scope },
|
|
@@ -20930,6 +21005,7 @@ function createLocalMemoryStore(options) {
|
|
|
20930
21005
|
database,
|
|
20931
21006
|
entityCollection: database.get("entity"),
|
|
20932
21007
|
memoryEntityCollection: database.get("memory_entity"),
|
|
21008
|
+
canWrite: options.canWrite,
|
|
20933
21009
|
...userId !== void 0 && { userId },
|
|
20934
21010
|
...options.allowUnscopedRows !== void 0 && {
|
|
20935
21011
|
allowUnscopedRows: options.allowUnscopedRows
|
|
@@ -20941,10 +21017,21 @@ function createLocalMemoryStore(options) {
|
|
|
20941
21017
|
walletAddress: options.walletAddress,
|
|
20942
21018
|
signMessage: options.signMessage,
|
|
20943
21019
|
embeddedWalletSigner: options.embeddedWalletSigner,
|
|
21020
|
+
canWrite: options.canWrite,
|
|
20944
21021
|
...userId !== void 0 && { userId },
|
|
20945
21022
|
...options.singleTenant !== void 0 && { singleTenant: options.singleTenant },
|
|
20946
21023
|
entityCtx
|
|
20947
21024
|
};
|
|
21025
|
+
const assertWrite = async (writeOptions) => {
|
|
21026
|
+
writeOptions?.signal?.throwIfAborted();
|
|
21027
|
+
if (writeOptions?.canWrite && !await writeOptions.canWrite()) {
|
|
21028
|
+
throw new Error("Memory source is no longer eligible");
|
|
21029
|
+
}
|
|
21030
|
+
if (options.canWrite && !await options.canWrite()) {
|
|
21031
|
+
throw new Error("Memory source is no longer eligible");
|
|
21032
|
+
}
|
|
21033
|
+
writeOptions?.signal?.throwIfAborted();
|
|
21034
|
+
};
|
|
20948
21035
|
const vaultCache = options.vaultCache ?? createVaultEmbeddingCache();
|
|
20949
21036
|
const ownedBy = userId !== void 0 ? [Q15.where("user_id", userId)] : [];
|
|
20950
21037
|
const linksOwnedBy = userId === void 0 ? [] : options.allowUnscopedRows ? [Q15.or(Q15.where("user_id", userId), Q15.where("user_id", null))] : [Q15.where("user_id", userId)];
|
|
@@ -21056,9 +21143,25 @@ function createLocalMemoryStore(options) {
|
|
|
21056
21143
|
archive: (id) => archiveVaultMemoryOp(vaultCtx, id),
|
|
21057
21144
|
restore: (id) => restoreVaultMemoryOp(vaultCtx, id),
|
|
21058
21145
|
setTopics: (memoryId, topics) => setMemoryEntitiesOp(vaultCtx, memoryId, topics),
|
|
21059
|
-
addTopics: (memoryId, topics) => database.write(async (writer) => {
|
|
21146
|
+
addTopics: (memoryId, topics, writeOptions) => database.write(async (writer) => {
|
|
21147
|
+
await assertWrite(writeOptions);
|
|
21060
21148
|
const owned = await vaultCtx.vaultMemoryCollection.query(Q15.where("id", memoryId), Q15.where("is_deleted", false), ...ownedBy).fetchCount();
|
|
21061
|
-
return owned > 0 ? writer.callWriter(
|
|
21149
|
+
return owned > 0 ? writer.callWriter(
|
|
21150
|
+
() => linkMemoryEntitiesOp(
|
|
21151
|
+
{
|
|
21152
|
+
...entityCtx,
|
|
21153
|
+
canWrite: async () => {
|
|
21154
|
+
await assertWrite(writeOptions);
|
|
21155
|
+
return true;
|
|
21156
|
+
}
|
|
21157
|
+
},
|
|
21158
|
+
memoryId,
|
|
21159
|
+
topics,
|
|
21160
|
+
{
|
|
21161
|
+
unlessTopicsUserManaged: writeOptions?.unlessUserManaged
|
|
21162
|
+
}
|
|
21163
|
+
)
|
|
21164
|
+
) : [];
|
|
21062
21165
|
}),
|
|
21063
21166
|
setVisibility: (id, visibility, visibilityOptions) => setMemoryVisibilityOp(vaultCtx, id, { visibility, ...visibilityOptions }),
|
|
21064
21167
|
recall: (query, recallOptions) => recall(
|
|
@@ -21068,7 +21171,17 @@ function createLocalMemoryStore(options) {
|
|
|
21068
21171
|
),
|
|
21069
21172
|
retain: (content, retainOptions) => retain(
|
|
21070
21173
|
content,
|
|
21071
|
-
{
|
|
21174
|
+
{
|
|
21175
|
+
vaultCtx: {
|
|
21176
|
+
...vaultCtx,
|
|
21177
|
+
canWrite: async () => {
|
|
21178
|
+
await assertWrite(retainOptions);
|
|
21179
|
+
return true;
|
|
21180
|
+
}
|
|
21181
|
+
},
|
|
21182
|
+
embeddingOptions: options.embeddingOptions,
|
|
21183
|
+
vaultCache
|
|
21184
|
+
},
|
|
21072
21185
|
retainOptions
|
|
21073
21186
|
),
|
|
21074
21187
|
factSource: {
|
|
@@ -21172,11 +21285,15 @@ function memoryCipher(canonical) {
|
|
|
21172
21285
|
};
|
|
21173
21286
|
}
|
|
21174
21287
|
async function reencryptMemoryField(value, canonical, fallbacks = []) {
|
|
21175
|
-
|
|
21176
|
-
|
|
21288
|
+
return memoryCipher(canonical).encrypt(
|
|
21289
|
+
await decryptMemoryField(value, [canonical, ...fallbacks])
|
|
21290
|
+
);
|
|
21291
|
+
}
|
|
21292
|
+
async function decryptMemoryField(value, rings) {
|
|
21293
|
+
if (!value.startsWith("enc:")) return value;
|
|
21177
21294
|
if (!isEncrypted(value))
|
|
21178
21295
|
throw new MemoryKeyError("Field has an encryption prefix but an invalid payload");
|
|
21179
|
-
return
|
|
21296
|
+
return decryptWith(value, rings);
|
|
21180
21297
|
}
|
|
21181
21298
|
|
|
21182
21299
|
// src/lib/memory/store/remotePersistence.ts
|
|
@@ -21714,7 +21831,14 @@ function stored(row) {
|
|
|
21714
21831
|
function createRemoteMemoryPipeline(options) {
|
|
21715
21832
|
const { persistence, embeddingOptions } = options;
|
|
21716
21833
|
const model = embeddingOptions.model ?? DEFAULT_API_EMBEDDING_MODEL;
|
|
21717
|
-
const operation = (mode, queryOptions = embeddingOptions) => {
|
|
21834
|
+
const operation = (mode, queryOptions = embeddingOptions, writeOptions) => {
|
|
21835
|
+
const signal = writeOptions?.signal;
|
|
21836
|
+
const assertWrite = async () => {
|
|
21837
|
+
signal?.throwIfAborted();
|
|
21838
|
+
if (writeOptions?.canWrite && !await writeOptions.canWrite())
|
|
21839
|
+
throw new Error("Memory source is no longer eligible");
|
|
21840
|
+
signal?.throwIfAborted();
|
|
21841
|
+
};
|
|
21718
21842
|
const rejectUndecryptable = (failed) => {
|
|
21719
21843
|
if (!failed.length) return;
|
|
21720
21844
|
if (mode === "retain")
|
|
@@ -21732,7 +21856,7 @@ function createRemoteMemoryPipeline(options) {
|
|
|
21732
21856
|
return items.map((item) => stored(item.memory));
|
|
21733
21857
|
};
|
|
21734
21858
|
const get = async (id) => {
|
|
21735
|
-
const snapshot = snapshots.get(id) ?? await persistence.get(id);
|
|
21859
|
+
const snapshot = snapshots.get(id) ?? await (signal ? persistence.get(id, signal) : persistence.get(id));
|
|
21736
21860
|
if (!snapshot || snapshot.memory.is_deleted || snapshot.memory.superseded_by) return null;
|
|
21737
21861
|
snapshots.set(id, snapshot);
|
|
21738
21862
|
return stored(snapshot.memory);
|
|
@@ -21782,7 +21906,7 @@ function createRemoteMemoryPipeline(options) {
|
|
|
21782
21906
|
if (forced.size < 100 && temporal[i] !== void 0) forced.add(temporal[i]);
|
|
21783
21907
|
}
|
|
21784
21908
|
const forceIds = [...forced];
|
|
21785
|
-
const windowOptions = (i,
|
|
21909
|
+
const windowOptions = (i, signal2) => ({
|
|
21786
21910
|
limit: Math.min(100, Math.max((search.limit ?? 8) * 3, 30)),
|
|
21787
21911
|
force_ids: i === 0 ? forceIds : [],
|
|
21788
21912
|
...search.scopes && { scopes: search.scopes },
|
|
@@ -21790,13 +21914,15 @@ function createRemoteMemoryPipeline(options) {
|
|
|
21790
21914
|
...search.memoryIds !== void 0 && { memory_ids: search.memoryIds },
|
|
21791
21915
|
include_archived: search.includeArchived,
|
|
21792
21916
|
embedding_model: model,
|
|
21793
|
-
...
|
|
21917
|
+
...signal2 && { signal: signal2 }
|
|
21794
21918
|
});
|
|
21795
21919
|
const vectors = [queryEmbedding, ...facetEmbeddings];
|
|
21796
21920
|
let windows;
|
|
21797
21921
|
if (mode === "retain") {
|
|
21798
21922
|
windows = await Promise.all(
|
|
21799
|
-
vectors.map(
|
|
21923
|
+
vectors.map(
|
|
21924
|
+
(embedding2, i) => persistence.candidateSet(embedding2, windowOptions(i, signal))
|
|
21925
|
+
)
|
|
21800
21926
|
);
|
|
21801
21927
|
} else {
|
|
21802
21928
|
const deadline = new AbortController();
|
|
@@ -21869,7 +21995,7 @@ function createRemoteMemoryPipeline(options) {
|
|
|
21869
21995
|
embedding: storedVector(JSON.parse(input.embedding)),
|
|
21870
21996
|
embedding_model: input.embeddingModel
|
|
21871
21997
|
},
|
|
21872
|
-
source_chunk_ids:
|
|
21998
|
+
source_chunk_ids: serializeSourceChunkIds(input.sourceChunkIds ?? []),
|
|
21873
21999
|
proof_count: input.proofCount ?? 1,
|
|
21874
22000
|
source: input.source ?? "manual",
|
|
21875
22001
|
...input.eventTime && {
|
|
@@ -21884,12 +22010,15 @@ function createRemoteMemoryPipeline(options) {
|
|
|
21884
22010
|
twin_opt_in: false
|
|
21885
22011
|
};
|
|
21886
22012
|
};
|
|
21887
|
-
const write = async (memory, snapshot) =>
|
|
22013
|
+
const write = async (memory, snapshot) => {
|
|
22014
|
+
await assertWrite();
|
|
22015
|
+
return remember([await persistence.put(memory, snapshot, signal)])[0];
|
|
22016
|
+
};
|
|
21888
22017
|
const port = {
|
|
21889
22018
|
prepare,
|
|
21890
22019
|
get,
|
|
21891
22020
|
getFresh: async (id) => {
|
|
21892
|
-
const current = await persistence.get(id);
|
|
22021
|
+
const current = await (signal ? persistence.get(id, signal) : persistence.get(id));
|
|
21893
22022
|
return current && !current.memory.is_deleted && !current.memory.superseded_by ? stored(current.memory) : null;
|
|
21894
22023
|
},
|
|
21895
22024
|
tombstones: async (embedding2, embeddingModel, scope, folderId) => {
|
|
@@ -21900,7 +22029,8 @@ function createRemoteMemoryPipeline(options) {
|
|
|
21900
22029
|
embedding_model: embeddingModel,
|
|
21901
22030
|
strict_model: true,
|
|
21902
22031
|
include_deleted: true,
|
|
21903
|
-
deleted_only: true
|
|
22032
|
+
deleted_only: true,
|
|
22033
|
+
signal
|
|
21904
22034
|
});
|
|
21905
22035
|
rejectUndecryptable(window2.failed);
|
|
21906
22036
|
return remember(window2.items);
|
|
@@ -21928,7 +22058,7 @@ function createRemoteMemoryPipeline(options) {
|
|
|
21928
22058
|
const observed = sourceIds(memory.source_chunk_ids);
|
|
21929
22059
|
const replay = !!patch.observationSourceIds?.length && patch.observationSourceIds.every((id2) => observed.includes(id2));
|
|
21930
22060
|
if (patch.sourceChunkIds !== void 0)
|
|
21931
|
-
memory.source_chunk_ids =
|
|
22061
|
+
memory.source_chunk_ids = serializeSourceChunkIds(
|
|
21932
22062
|
patch.observationSourceIds?.length ? [.../* @__PURE__ */ new Set([...observed, ...patch.sourceChunkIds])] : patch.sourceChunkIds
|
|
21933
22063
|
);
|
|
21934
22064
|
if (!replay) {
|
|
@@ -21956,14 +22086,18 @@ function createRemoteMemoryPipeline(options) {
|
|
|
21956
22086
|
if (!target || !newer || id === successor) return false;
|
|
21957
22087
|
const old = snapshots.get(id);
|
|
21958
22088
|
const next = snapshots.get(successor);
|
|
22089
|
+
await assertWrite();
|
|
21959
22090
|
remember(
|
|
21960
|
-
await persistence.putMany(
|
|
21961
|
-
|
|
21962
|
-
|
|
21963
|
-
|
|
21964
|
-
|
|
21965
|
-
|
|
21966
|
-
|
|
22091
|
+
await persistence.putMany(
|
|
22092
|
+
[
|
|
22093
|
+
{
|
|
22094
|
+
memory: { ...old.memory, superseded_by: successor, superseded_at: Date.now() },
|
|
22095
|
+
expectedVersion: old
|
|
22096
|
+
},
|
|
22097
|
+
{ memory: next.memory, expectedVersion: next }
|
|
22098
|
+
],
|
|
22099
|
+
signal
|
|
22100
|
+
)
|
|
21967
22101
|
);
|
|
21968
22102
|
return true;
|
|
21969
22103
|
},
|
|
@@ -21972,18 +22106,22 @@ function createRemoteMemoryPipeline(options) {
|
|
|
21972
22106
|
if (!target) return { created: null, retired: false };
|
|
21973
22107
|
const snapshot = snapshots.get(targetId);
|
|
21974
22108
|
const successor = createRow(input);
|
|
22109
|
+
await assertWrite();
|
|
21975
22110
|
const rows = remember(
|
|
21976
|
-
await persistence.putMany(
|
|
21977
|
-
|
|
21978
|
-
|
|
21979
|
-
|
|
21980
|
-
|
|
21981
|
-
|
|
21982
|
-
|
|
21983
|
-
|
|
21984
|
-
|
|
21985
|
-
|
|
21986
|
-
|
|
22111
|
+
await persistence.putMany(
|
|
22112
|
+
[
|
|
22113
|
+
{ memory: successor, expectedVersion: 0 },
|
|
22114
|
+
{
|
|
22115
|
+
memory: {
|
|
22116
|
+
...snapshot.memory,
|
|
22117
|
+
superseded_by: successor.memory_id,
|
|
22118
|
+
superseded_at: Date.now()
|
|
22119
|
+
},
|
|
22120
|
+
expectedVersion: snapshot
|
|
22121
|
+
}
|
|
22122
|
+
],
|
|
22123
|
+
signal
|
|
22124
|
+
)
|
|
21987
22125
|
);
|
|
21988
22126
|
return { created: rows[0], retired: true };
|
|
21989
22127
|
}
|
|
@@ -22018,7 +22156,7 @@ function createRemoteMemoryPipeline(options) {
|
|
|
22018
22156
|
factSource,
|
|
22019
22157
|
recall: async (query, recallOptions = {}) => recall(query, { embeddingOptions, factSource }, { ...recallOptions, types: ["fact"] }),
|
|
22020
22158
|
retain: async (content, retainOptions) => {
|
|
22021
|
-
const { port } = operation("retain");
|
|
22159
|
+
const { port } = operation("retain", embeddingOptions, retainOptions);
|
|
22022
22160
|
return retainWithPersistence(
|
|
22023
22161
|
content,
|
|
22024
22162
|
{
|
|
@@ -22035,6 +22173,8 @@ function createRemoteMemoryPipeline(options) {
|
|
|
22035
22173
|
|
|
22036
22174
|
// src/lib/memory/store/remoteMigration.ts
|
|
22037
22175
|
var IMPORT_BATCH = 50;
|
|
22176
|
+
var EMBED_BATCH = 100;
|
|
22177
|
+
var LOCAL_VECTOR_DIMS = 4096;
|
|
22038
22178
|
var VERIFY_BATCH = 1e3;
|
|
22039
22179
|
var QUERY_IDS = 1e3;
|
|
22040
22180
|
var QUERY_PAGE = 200;
|
|
@@ -22060,7 +22200,7 @@ var SHORT_FIELDS = [
|
|
|
22060
22200
|
"visibility",
|
|
22061
22201
|
"geohash"
|
|
22062
22202
|
];
|
|
22063
|
-
var
|
|
22203
|
+
var utf82 = new TextEncoder();
|
|
22064
22204
|
var METADATA_FIELDS = [
|
|
22065
22205
|
"scope",
|
|
22066
22206
|
"kind",
|
|
@@ -22111,17 +22251,34 @@ function revision(raw) {
|
|
|
22111
22251
|
last_observed_at: num(raw.last_observed_at) ?? null
|
|
22112
22252
|
};
|
|
22113
22253
|
}
|
|
22114
|
-
function embedding(raw) {
|
|
22254
|
+
function embedding(raw, model) {
|
|
22115
22255
|
const value = text13(raw.embedding);
|
|
22116
22256
|
if (!value) return void 0;
|
|
22117
22257
|
try {
|
|
22118
|
-
|
|
22258
|
+
const vector = JSON.parse(value);
|
|
22259
|
+
const stored2 = text13(raw.embedding_model);
|
|
22260
|
+
if (stored2 === void 0 ? vector.length !== LOCAL_VECTOR_DIMS : stored2 !== model)
|
|
22261
|
+
return void 0;
|
|
22262
|
+
return storedVector(vector);
|
|
22263
|
+
} catch {
|
|
22264
|
+
return void 0;
|
|
22265
|
+
}
|
|
22266
|
+
}
|
|
22267
|
+
function stringArray(value) {
|
|
22268
|
+
try {
|
|
22269
|
+
const parsed = JSON.parse(value);
|
|
22270
|
+
return Array.isArray(parsed) && parsed.every((id) => typeof id === "string") ? parsed : void 0;
|
|
22119
22271
|
} catch {
|
|
22120
22272
|
return void 0;
|
|
22121
22273
|
}
|
|
22122
22274
|
}
|
|
22275
|
+
function sourceChunkIds(raw) {
|
|
22276
|
+
const value = text13(raw.source_chunk_ids);
|
|
22277
|
+
const ids = value && stringArray(value);
|
|
22278
|
+
return ids ? serializeSourceChunkIds(ids) : value;
|
|
22279
|
+
}
|
|
22123
22280
|
function bytes(value) {
|
|
22124
|
-
return value === void 0 ? 0 :
|
|
22281
|
+
return value === void 0 ? 0 : utf82.encode(value).length;
|
|
22125
22282
|
}
|
|
22126
22283
|
function fitsNearby(row) {
|
|
22127
22284
|
return bytes(row.memory_id) <= MAX_ID_BYTES && bytes(row.content) <= MAX_CONTENT_BYTES && bytes(row.kind_value) <= MAX_CONTENT_BYTES && TEXT_FIELDS.every((field10) => bytes(row[field10]) <= MAX_TEXT_BYTES) && SHORT_FIELDS.every((field10) => bytes(row[field10]) <= MAX_SHORT_BYTES);
|
|
@@ -22130,16 +22287,16 @@ function invalid(raw) {
|
|
|
22130
22287
|
const id = raw.id;
|
|
22131
22288
|
return typeof id !== "string" || id === "" || bytes(id) > MAX_ID_BYTES || !text13(raw.scope) || (num(raw.created_at) ?? 0) <= 0 || (num(raw.updated_at) ?? 0) <= 0;
|
|
22132
22289
|
}
|
|
22133
|
-
function metadata(raw) {
|
|
22134
|
-
const vector = embedding(raw);
|
|
22290
|
+
function metadata(raw, model) {
|
|
22291
|
+
const vector = embedding(raw, model);
|
|
22135
22292
|
return {
|
|
22136
22293
|
scope: raw.scope,
|
|
22137
22294
|
kind: text13(raw.kind),
|
|
22138
22295
|
level: text13(raw.level),
|
|
22139
22296
|
folder_id: text13(raw.folder_id),
|
|
22140
22297
|
is_deleted: bool(raw.is_deleted) ?? false,
|
|
22141
|
-
...vector && { embedding: vector, embedding_model:
|
|
22142
|
-
source_chunk_ids:
|
|
22298
|
+
...vector && { embedding: vector, embedding_model: model },
|
|
22299
|
+
source_chunk_ids: sourceChunkIds(raw),
|
|
22143
22300
|
proof_count: num(raw.proof_count),
|
|
22144
22301
|
source: text13(raw.source),
|
|
22145
22302
|
event_time_start: num(raw.event_time_start),
|
|
@@ -22168,30 +22325,63 @@ function defined(value) {
|
|
|
22168
22325
|
Object.entries(value).filter(([, field10]) => field10 !== void 0)
|
|
22169
22326
|
);
|
|
22170
22327
|
}
|
|
22171
|
-
async function
|
|
22172
|
-
const
|
|
22173
|
-
|
|
22174
|
-
|
|
22175
|
-
|
|
22176
|
-
|
|
22177
|
-
|
|
22178
|
-
|
|
22328
|
+
async function prepareRow(raw, canonical, rings, model, updatedAt) {
|
|
22329
|
+
const deleted = bool(raw.is_deleted) ?? false;
|
|
22330
|
+
const { encrypt } = memoryCipher(canonical);
|
|
22331
|
+
const localKindValue = text13(raw.kind_value);
|
|
22332
|
+
let plaintext;
|
|
22333
|
+
let kindValue;
|
|
22334
|
+
try {
|
|
22335
|
+
plaintext = await decryptMemoryField(typeof raw.content === "string" ? raw.content : "", rings);
|
|
22336
|
+
kindValue = localKindValue && await decryptMemoryField(localKindValue, rings);
|
|
22337
|
+
} catch (error) {
|
|
22338
|
+
if (!deleted || !(error instanceof MemoryKeyError)) throw error;
|
|
22339
|
+
plaintext = void 0;
|
|
22340
|
+
kindValue = void 0;
|
|
22341
|
+
}
|
|
22179
22342
|
const row = {
|
|
22180
|
-
...defined({
|
|
22343
|
+
...defined({
|
|
22344
|
+
...metadata(raw, model),
|
|
22345
|
+
kind_value: kindValue === void 0 ? void 0 : await encrypt(kindValue)
|
|
22346
|
+
}),
|
|
22181
22347
|
memory_id: raw.id,
|
|
22182
|
-
content,
|
|
22348
|
+
content: await encrypt(plaintext ?? ""),
|
|
22183
22349
|
scope: raw.scope,
|
|
22184
22350
|
created_at: raw.created_at,
|
|
22185
22351
|
updated_at: updatedAt,
|
|
22186
|
-
is_deleted:
|
|
22352
|
+
is_deleted: deleted
|
|
22187
22353
|
};
|
|
22188
|
-
return
|
|
22354
|
+
return { row, plaintext };
|
|
22189
22355
|
}
|
|
22190
|
-
function
|
|
22191
|
-
const
|
|
22356
|
+
async function embedMissing(prepared, options, model, signal) {
|
|
22357
|
+
const needed = prepared.filter((p) => !p.row.embedding && p.plaintext);
|
|
22358
|
+
for (const batch of chunks(needed, EMBED_BATCH)) {
|
|
22359
|
+
if (signal?.aborted) throw aborted(signal);
|
|
22360
|
+
try {
|
|
22361
|
+
const vectors = await generateEmbeddings(
|
|
22362
|
+
batch.map((p) => p.plaintext),
|
|
22363
|
+
{ ...options, taskType: "memory_retain_embed" }
|
|
22364
|
+
);
|
|
22365
|
+
if (vectors.length !== batch.length) throw new Error("Incomplete migration embeddings");
|
|
22366
|
+
const stored2 = vectors.map(storedVector);
|
|
22367
|
+
batch.forEach((p, i) => {
|
|
22368
|
+
p.row.embedding = stored2[i];
|
|
22369
|
+
p.row.embedding_model = model;
|
|
22370
|
+
});
|
|
22371
|
+
} catch (error) {
|
|
22372
|
+
getLogger().warn(
|
|
22373
|
+
`[memory/migration] Uploading ${batch.length} row(s) without a vector: embedding failed`,
|
|
22374
|
+
error
|
|
22375
|
+
);
|
|
22376
|
+
}
|
|
22377
|
+
}
|
|
22378
|
+
}
|
|
22379
|
+
function sameMetadata(local, remote, model) {
|
|
22380
|
+
const mine = metadata(local, model);
|
|
22192
22381
|
return METADATA_FIELDS.every((field10) => {
|
|
22193
22382
|
const a = mine[field10] ?? null;
|
|
22194
22383
|
const b = remote[field10] ?? null;
|
|
22384
|
+
if (field10 === "embedding_model" && a === null) return true;
|
|
22195
22385
|
if (field10 === "visibility") return (a ?? "private") === (b ?? "private");
|
|
22196
22386
|
if (field10 === "is_deleted" || field10 === "topics_user_managed" || field10 === "twin_opt_in")
|
|
22197
22387
|
return (a ?? false) === (b ?? false);
|
|
@@ -22287,7 +22477,8 @@ async function backfillTopics(ctx) {
|
|
|
22287
22477
|
}
|
|
22288
22478
|
async function migrateMemoriesToRemote(options) {
|
|
22289
22479
|
const { canonical, signal } = options;
|
|
22290
|
-
const
|
|
22480
|
+
const rings = [canonical, ...options.fallbacks ?? []];
|
|
22481
|
+
const model = options.embeddingOptions?.model ?? DEFAULT_API_EMBEDDING_MODEL;
|
|
22291
22482
|
const request = createNearbyRequest(options);
|
|
22292
22483
|
const account = await request("/account", {}, signal);
|
|
22293
22484
|
if (typeof account.key_id === "string" && account.key_id !== canonical.keyId)
|
|
@@ -22298,8 +22489,13 @@ async function migrateMemoriesToRemote(options) {
|
|
|
22298
22489
|
);
|
|
22299
22490
|
const active = account.state === "active";
|
|
22300
22491
|
let claimed = account.key_id === canonical.keyId;
|
|
22492
|
+
if (!active) await createDecaySweeper({ vaultCtx: options.vaultCtx }).runSweep();
|
|
22301
22493
|
await backfillTopics(options.vaultCtx);
|
|
22302
22494
|
const skipped = /* @__PURE__ */ new Map();
|
|
22495
|
+
const reembedded = /* @__PURE__ */ new Set();
|
|
22496
|
+
const unembedded = /* @__PURE__ */ new Set();
|
|
22497
|
+
const placeholders = /* @__PURE__ */ new Set();
|
|
22498
|
+
const truncated = /* @__PURE__ */ new Set();
|
|
22303
22499
|
let imported = 0;
|
|
22304
22500
|
for (let pass = 0; ; pass++) {
|
|
22305
22501
|
const rows = await getAllVaultMemoryRowsOp(options.vaultCtx);
|
|
@@ -22315,9 +22511,10 @@ async function migrateMemoriesToRemote(options) {
|
|
|
22315
22511
|
candidates.map((raw) => raw.id),
|
|
22316
22512
|
signal
|
|
22317
22513
|
);
|
|
22514
|
+
const needsVector = (raw, server) => !!options.embeddingOptions && !embedding(raw, model) && server.embedding_model !== model;
|
|
22318
22515
|
for (const raw of candidates) {
|
|
22319
22516
|
const server = remote.get(raw.id);
|
|
22320
|
-
if (server && server.updated_at === raw.updated_at && !sameMetadata(raw, server))
|
|
22517
|
+
if (server && server.updated_at === raw.updated_at && (!sameMetadata(raw, server, model) || needsVector(raw, server)))
|
|
22321
22518
|
pending.set(raw.id, raw.updated_at + 1);
|
|
22322
22519
|
}
|
|
22323
22520
|
}
|
|
@@ -22326,7 +22523,11 @@ async function migrateMemoriesToRemote(options) {
|
|
|
22326
22523
|
state,
|
|
22327
22524
|
total: rows.length,
|
|
22328
22525
|
imported,
|
|
22329
|
-
skipped: [...skipped].map(([memoryId, reason]) => ({ memoryId, reason }))
|
|
22526
|
+
skipped: [...skipped].map(([memoryId, reason]) => ({ memoryId, reason })),
|
|
22527
|
+
reembedded: reembedded.size,
|
|
22528
|
+
unembedded: unembedded.size,
|
|
22529
|
+
placeholderTombstones: placeholders.size,
|
|
22530
|
+
truncatedSourceChunkIds: truncated.size
|
|
22330
22531
|
});
|
|
22331
22532
|
if (skipped.size > 0 && !options.allowSkipped) return result("migrating");
|
|
22332
22533
|
if (!claimed) await importBatch(request, canonical.keyId, [], signal);
|
|
@@ -22344,19 +22545,35 @@ async function migrateMemoriesToRemote(options) {
|
|
|
22344
22545
|
409,
|
|
22345
22546
|
"migration_incomplete"
|
|
22346
22547
|
);
|
|
22347
|
-
const
|
|
22548
|
+
const prepared = [];
|
|
22348
22549
|
for (const raw of candidates) {
|
|
22349
22550
|
const updatedAt = pending.get(raw.id);
|
|
22350
22551
|
if (updatedAt === void 0) continue;
|
|
22351
22552
|
try {
|
|
22352
|
-
|
|
22353
|
-
if (row) upload.push(row);
|
|
22354
|
-
else skipped.set(raw.id, "invalid");
|
|
22553
|
+
prepared.push(await prepareRow(raw, canonical, rings, model, updatedAt));
|
|
22355
22554
|
} catch (error) {
|
|
22356
22555
|
if (!(error instanceof MemoryKeyError)) throw error;
|
|
22357
22556
|
skipped.set(raw.id, "unreadable");
|
|
22358
22557
|
}
|
|
22359
22558
|
}
|
|
22559
|
+
const usable = new Set(prepared.filter((p) => p.row.embedding).map((p) => p.row.memory_id));
|
|
22560
|
+
if (options.embeddingOptions)
|
|
22561
|
+
await embedMissing(prepared, options.embeddingOptions, model, signal);
|
|
22562
|
+
const local = new Map(candidates.map((raw) => [raw.id, raw]));
|
|
22563
|
+
const upload = [];
|
|
22564
|
+
for (const { row, plaintext } of prepared) {
|
|
22565
|
+
const id = row.memory_id;
|
|
22566
|
+
if (!fitsNearby(row)) {
|
|
22567
|
+
skipped.set(id, "invalid");
|
|
22568
|
+
continue;
|
|
22569
|
+
}
|
|
22570
|
+
upload.push(row);
|
|
22571
|
+
const track = (set, on) => on ? set.add(id) : set.delete(id);
|
|
22572
|
+
track(reembedded, !!row.embedding && !usable.has(id));
|
|
22573
|
+
track(unembedded, !row.embedding);
|
|
22574
|
+
track(placeholders, plaintext === void 0);
|
|
22575
|
+
track(truncated, row.source_chunk_ids !== text13(local.get(id).source_chunk_ids));
|
|
22576
|
+
}
|
|
22360
22577
|
let sent = 0;
|
|
22361
22578
|
options.onProgress?.({ imported: sent, toImport: upload.length });
|
|
22362
22579
|
for (const batch of chunks(upload, IMPORT_BATCH)) {
|
|
@@ -22600,16 +22817,21 @@ function createRemoteMemoryStore(options) {
|
|
|
22600
22817
|
const record2 = await persistence.get(id);
|
|
22601
22818
|
return record2 && !record2.memory.is_deleted ? record2 : null;
|
|
22602
22819
|
};
|
|
22603
|
-
const mutateLocked = async (id, change, edit) => {
|
|
22604
|
-
|
|
22820
|
+
const mutateLocked = async (id, change, edit, writeOptions) => {
|
|
22821
|
+
writeOptions?.signal?.throwIfAborted();
|
|
22822
|
+
const record2 = writeOptions?.signal ? await persistence.get(id, writeOptions.signal) : await live(id);
|
|
22605
22823
|
if (!record2) return null;
|
|
22824
|
+
if (record2.memory.is_deleted) return null;
|
|
22825
|
+
if (writeOptions?.canWrite && !await writeOptions.canWrite())
|
|
22826
|
+
throw new Error("Memory source is no longer eligible");
|
|
22827
|
+
writeOptions?.signal?.throwIfAborted();
|
|
22606
22828
|
const next = edit(structuredClone(record2.memory));
|
|
22607
22829
|
if (!next) return null;
|
|
22608
|
-
const saved = await persistence.put(next, record2);
|
|
22830
|
+
const saved = writeOptions?.signal ? await persistence.put(next, record2, writeOptions.signal) : await persistence.put(next, record2);
|
|
22609
22831
|
notify(typeof change === "function" ? change(record2.memory) : change, [saved]);
|
|
22610
22832
|
return saved;
|
|
22611
22833
|
};
|
|
22612
|
-
const mutate = (id, change, edit) => serialized(id, () => mutateLocked(id, change, edit));
|
|
22834
|
+
const mutate = (id, change, edit, writeOptions) => serialized(id, () => mutateLocked(id, change, edit, writeOptions));
|
|
22613
22835
|
const serializedAll = (ids, task) => [...new Set(ids)].sort().reduceRight((inner, id) => () => serialized(id, inner), task)();
|
|
22614
22836
|
const mutateMany = async (ids, change, edit) => {
|
|
22615
22837
|
const saved = /* @__PURE__ */ new Map();
|
|
@@ -23122,13 +23344,21 @@ function createRemoteMemoryStore(options) {
|
|
|
23122
23344
|
}))
|
|
23123
23345
|
);
|
|
23124
23346
|
},
|
|
23125
|
-
addTopics: async (memoryId, topics) => {
|
|
23347
|
+
addTopics: async (memoryId, topics, writeOptions) => {
|
|
23126
23348
|
const added = await withKnownKinds(topicInputs(topics, "auto"));
|
|
23127
|
-
const saved = await mutate(
|
|
23128
|
-
|
|
23129
|
-
|
|
23130
|
-
|
|
23131
|
-
|
|
23349
|
+
const saved = await mutate(
|
|
23350
|
+
memoryId,
|
|
23351
|
+
"edit",
|
|
23352
|
+
(memory) => {
|
|
23353
|
+
if (writeOptions?.unlessUserManaged && memory.topics_user_managed) return null;
|
|
23354
|
+
return {
|
|
23355
|
+
...memory,
|
|
23356
|
+
topics: serializeTopics(mergeTopics(parseTopics(memory.topics) ?? [], added)),
|
|
23357
|
+
topics_updated_at: Date.now()
|
|
23358
|
+
};
|
|
23359
|
+
},
|
|
23360
|
+
writeOptions
|
|
23361
|
+
);
|
|
23132
23362
|
if (!saved) return [];
|
|
23133
23363
|
const now = /* @__PURE__ */ new Date();
|
|
23134
23364
|
return mergeTopics([], added).map(
|
|
@@ -23979,6 +24209,7 @@ function createDurableAutoExtractor(options) {
|
|
|
23979
24209
|
};
|
|
23980
24210
|
const folderId = options.folderId ?? null;
|
|
23981
24211
|
let disposed = false;
|
|
24212
|
+
let activeBatch = null;
|
|
23982
24213
|
let running = false;
|
|
23983
24214
|
let wakeRequested = false;
|
|
23984
24215
|
let timer;
|
|
@@ -24015,14 +24246,18 @@ function createDurableAutoExtractor(options) {
|
|
|
24015
24246
|
}, delay);
|
|
24016
24247
|
}
|
|
24017
24248
|
async function extractBatch(messages, conversationId, ids, jobScope, jobFolderId) {
|
|
24249
|
+
if (disposed) throw new Error("Extraction session was disposed");
|
|
24018
24250
|
let watchdog;
|
|
24019
24251
|
let cancelled = false;
|
|
24252
|
+
const controller = new AbortController();
|
|
24253
|
+
activeBatch = controller;
|
|
24020
24254
|
const model = options.modelForScope?.(jobScope) ?? options.extract.model;
|
|
24021
24255
|
try {
|
|
24022
24256
|
return await Promise.race([
|
|
24023
24257
|
new Promise((resolve, reject) => {
|
|
24024
24258
|
const worker = createAutoExtractor({
|
|
24025
24259
|
...options,
|
|
24260
|
+
signal: controller.signal,
|
|
24026
24261
|
retainCtx: {
|
|
24027
24262
|
...options.retainCtx,
|
|
24028
24263
|
vaultCtx: {
|
|
@@ -24051,6 +24286,8 @@ function createDurableAutoExtractor(options) {
|
|
|
24051
24286
|
]);
|
|
24052
24287
|
} finally {
|
|
24053
24288
|
cancelled = true;
|
|
24289
|
+
controller.abort();
|
|
24290
|
+
if (activeBatch === controller) activeBatch = null;
|
|
24054
24291
|
if (watchdog !== void 0) clearTimeout(watchdog);
|
|
24055
24292
|
}
|
|
24056
24293
|
}
|
|
@@ -24062,6 +24299,7 @@ function createDurableAutoExtractor(options) {
|
|
|
24062
24299
|
for (const message of loaded)
|
|
24063
24300
|
if (message && message.messageId > 0) sequences.set(message.uniqueId, message.messageId);
|
|
24064
24301
|
await database.write(async () => {
|
|
24302
|
+
if (disposed) return;
|
|
24065
24303
|
const current = idsOf(job);
|
|
24066
24304
|
const acknowledged = ids.filter((id) => current.includes(id));
|
|
24067
24305
|
if (!acknowledged.length) return;
|
|
@@ -24234,6 +24472,7 @@ function createDurableAutoExtractor(options) {
|
|
|
24234
24472
|
jobScope,
|
|
24235
24473
|
jobFolderId
|
|
24236
24474
|
);
|
|
24475
|
+
if (disposed) throw new Error("Extraction session was disposed");
|
|
24237
24476
|
options.onTurnComplete?.(result);
|
|
24238
24477
|
return result;
|
|
24239
24478
|
};
|
|
@@ -24270,6 +24509,7 @@ function createDurableAutoExtractor(options) {
|
|
|
24270
24509
|
);
|
|
24271
24510
|
scheduleAfterSuccess = true;
|
|
24272
24511
|
} catch (error) {
|
|
24512
|
+
if (disposed) break;
|
|
24273
24513
|
attempts.set(job.id, attempted + 1);
|
|
24274
24514
|
retry = true;
|
|
24275
24515
|
reportError(error, conversationId);
|
|
@@ -24292,6 +24532,14 @@ function createDurableAutoExtractor(options) {
|
|
|
24292
24532
|
schedule(retry ? options.retryDelayMs ?? 3e4 : 0);
|
|
24293
24533
|
}
|
|
24294
24534
|
}
|
|
24535
|
+
function dispose() {
|
|
24536
|
+
disposed = true;
|
|
24537
|
+
activeBatch?.abort(options.signal?.reason);
|
|
24538
|
+
if (timer !== void 0) clearTimeout(timer);
|
|
24539
|
+
options.signal?.removeEventListener("abort", dispose);
|
|
24540
|
+
}
|
|
24541
|
+
if (options.signal?.aborted) dispose();
|
|
24542
|
+
else options.signal?.addEventListener("abort", dispose, { once: true });
|
|
24295
24543
|
schedule(0);
|
|
24296
24544
|
return {
|
|
24297
24545
|
processTurn(messages, conversationId) {
|
|
@@ -24371,10 +24619,7 @@ function createDurableAutoExtractor(options) {
|
|
|
24371
24619
|
return true;
|
|
24372
24620
|
},
|
|
24373
24621
|
isProcessing: () => running,
|
|
24374
|
-
dispose
|
|
24375
|
-
disposed = true;
|
|
24376
|
-
if (timer !== void 0) clearTimeout(timer);
|
|
24377
|
-
}
|
|
24622
|
+
dispose
|
|
24378
24623
|
};
|
|
24379
24624
|
}
|
|
24380
24625
|
|
|
@@ -30636,6 +30881,7 @@ var CONVERSATION_REDACTOR_LIMIT = 50;
|
|
|
30636
30881
|
var NO_CONVERSATION_KEY = "__no_conversation__";
|
|
30637
30882
|
var NO_STORE_FOLDERS = "Folders are not supported with a memoryStore";
|
|
30638
30883
|
var NO_STORE_MASK = "piiRedaction needs a memoryStore built with embeddingOptions.maskInput";
|
|
30884
|
+
var MEMORY_STORE_NOT_READY = "Memory store is not ready";
|
|
30639
30885
|
var conversationRedactors = /* @__PURE__ */ new Map();
|
|
30640
30886
|
function getConversationRedactor(conversationId, nerDetector) {
|
|
30641
30887
|
const key = conversationId ?? NO_CONVERSATION_KEY;
|
|
@@ -30726,7 +30972,7 @@ function useChatStorage(options) {
|
|
|
30726
30972
|
() => ({ getToken, baseUrl, model: embeddingModel, maskInput: maskEmbeddingInput }),
|
|
30727
30973
|
[getToken, baseUrl, embeddingModel, maskEmbeddingInput]
|
|
30728
30974
|
);
|
|
30729
|
-
const storeMaskMissing = memoryStore !== void 0 && maskEmbeddingInput !== void 0 && !memoryStore.masksEmbeddingInput;
|
|
30975
|
+
const storeMaskMissing = memoryStore !== void 0 && memoryStore !== null && maskEmbeddingInput !== void 0 && !memoryStore.masksEmbeddingInput;
|
|
30730
30976
|
const blobManagerRef = useRef4(new BlobUrlManager());
|
|
30731
30977
|
useEffect4(() => {
|
|
30732
30978
|
const manager = blobManagerRef.current;
|
|
@@ -31003,6 +31249,7 @@ function useChatStorage(options) {
|
|
|
31003
31249
|
);
|
|
31004
31250
|
const retainVaultMemory = useCallback5(
|
|
31005
31251
|
async (input) => {
|
|
31252
|
+
if (memoryStore === null) throw new Error(MEMORY_STORE_NOT_READY);
|
|
31006
31253
|
if (memoryStore) {
|
|
31007
31254
|
if (storeMaskMissing) throw new Error(NO_STORE_MASK);
|
|
31008
31255
|
if (input.folderId !== void 0) throw new Error(NO_STORE_FOLDERS);
|
|
@@ -31034,6 +31281,7 @@ function useChatStorage(options) {
|
|
|
31034
31281
|
);
|
|
31035
31282
|
const createMemoryVaultTool2 = useCallback5(
|
|
31036
31283
|
(options2) => {
|
|
31284
|
+
if (memoryStore === null) throw new Error(MEMORY_STORE_NOT_READY);
|
|
31037
31285
|
if (storeMaskMissing) throw new Error(NO_STORE_MASK);
|
|
31038
31286
|
const embOpts = getToken ? vaultEmbeddingOptions : void 0;
|
|
31039
31287
|
return createMemoryVaultTool(
|
|
@@ -31055,6 +31303,7 @@ function useChatStorage(options) {
|
|
|
31055
31303
|
);
|
|
31056
31304
|
const getVaultMemories = useCallback5(
|
|
31057
31305
|
(options2) => {
|
|
31306
|
+
if (memoryStore === null) return Promise.resolve([]);
|
|
31058
31307
|
if (!memoryStore) return getAllVaultMemoriesOp(vaultCtx, options2);
|
|
31059
31308
|
const { folderId, levels, kinds, ...listOptions } = options2 ?? {};
|
|
31060
31309
|
if (folderId !== void 0) throw new Error(NO_STORE_FOLDERS);
|
|
@@ -31066,6 +31315,7 @@ function useChatStorage(options) {
|
|
|
31066
31315
|
);
|
|
31067
31316
|
const createVaultMemory = useCallback5(
|
|
31068
31317
|
async (content, scope) => {
|
|
31318
|
+
if (memoryStore === null) throw new Error(MEMORY_STORE_NOT_READY);
|
|
31069
31319
|
if (storeMaskMissing) throw new Error(NO_STORE_MASK);
|
|
31070
31320
|
if (memoryStore) return memoryStore.create({ content, scope });
|
|
31071
31321
|
const result = await createVaultMemoryOp(vaultCtx, { content, scope });
|
|
@@ -31087,6 +31337,7 @@ function useChatStorage(options) {
|
|
|
31087
31337
|
);
|
|
31088
31338
|
const updateVaultMemory = useCallback5(
|
|
31089
31339
|
async (id, content, scope) => {
|
|
31340
|
+
if (memoryStore === null) throw new Error(MEMORY_STORE_NOT_READY);
|
|
31090
31341
|
if (storeMaskMissing) throw new Error(NO_STORE_MASK);
|
|
31091
31342
|
if (memoryStore) return memoryStore.update(id, { content, scope });
|
|
31092
31343
|
const existing = await getVaultMemoryOp(vaultCtx, id);
|
|
@@ -31112,6 +31363,7 @@ function useChatStorage(options) {
|
|
|
31112
31363
|
);
|
|
31113
31364
|
const deleteVaultMemory = useCallback5(
|
|
31114
31365
|
async (id) => {
|
|
31366
|
+
if (memoryStore === null) throw new Error(MEMORY_STORE_NOT_READY);
|
|
31115
31367
|
if (memoryStore) return memoryStore.delete(id);
|
|
31116
31368
|
const existing = await getVaultMemoryOp(vaultCtx, id);
|
|
31117
31369
|
const result = await deleteVaultMemoryOp(vaultCtx, id);
|
|
@@ -31125,7 +31377,7 @@ function useChatStorage(options) {
|
|
|
31125
31377
|
const chunkVectorCacheRef = useRef4(createChunkVectorCache());
|
|
31126
31378
|
const clientToolEmbeddingsCacheRef = useRef4(/* @__PURE__ */ new Map());
|
|
31127
31379
|
useEffect4(() => {
|
|
31128
|
-
if (!getToken || memoryStore) return;
|
|
31380
|
+
if (!getToken || memoryStore !== void 0) return;
|
|
31129
31381
|
void (async () => {
|
|
31130
31382
|
try {
|
|
31131
31383
|
await preEmbedVaultMemories(vaultCtx, vaultEmbeddingOptions, vaultEmbeddingCache);
|
|
@@ -31141,6 +31393,7 @@ function useChatStorage(options) {
|
|
|
31141
31393
|
}, [vaultEmbeddingCache]);
|
|
31142
31394
|
const createMemoryVaultSearchTool2 = useCallback5(
|
|
31143
31395
|
(searchOptions) => {
|
|
31396
|
+
if (memoryStore === null) throw new Error(MEMORY_STORE_NOT_READY);
|
|
31144
31397
|
if (!getToken && !memoryStore) {
|
|
31145
31398
|
throw new Error("getToken is required for memory vault search tool");
|
|
31146
31399
|
}
|
|
@@ -31156,6 +31409,7 @@ function useChatStorage(options) {
|
|
|
31156
31409
|
);
|
|
31157
31410
|
const createRecallTool2 = useCallback5(
|
|
31158
31411
|
(toolOptions, callbacks) => {
|
|
31412
|
+
if (memoryStore === null) throw new Error(MEMORY_STORE_NOT_READY);
|
|
31159
31413
|
if (!getToken && !memoryStore) {
|
|
31160
31414
|
throw new Error("getToken is required for recall tool");
|
|
31161
31415
|
}
|
|
@@ -31195,6 +31449,7 @@ function useChatStorage(options) {
|
|
|
31195
31449
|
);
|
|
31196
31450
|
const searchVaultMemoriesFn = useCallback5(
|
|
31197
31451
|
async (query, searchOptions) => {
|
|
31452
|
+
if (memoryStore === null) return [];
|
|
31198
31453
|
if (storeMaskMissing) throw new Error(NO_STORE_MASK);
|
|
31199
31454
|
if (memoryStore) return (await memoryStore.factSource.search(query, searchOptions)).results;
|
|
31200
31455
|
if (!getToken) return [];
|
|
@@ -31210,7 +31465,7 @@ function useChatStorage(options) {
|
|
|
31210
31465
|
);
|
|
31211
31466
|
const recallFn = useCallback5(
|
|
31212
31467
|
async (query, options2) => {
|
|
31213
|
-
if (!getToken && !memoryStore) {
|
|
31468
|
+
if (memoryStore === null || !getToken && !memoryStore) {
|
|
31214
31469
|
return {
|
|
31215
31470
|
memories: [],
|
|
31216
31471
|
usedBudget: options2?.budget ?? "low",
|