@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.cjs
CHANGED
|
@@ -12292,6 +12292,11 @@ function parseTopics(value) {
|
|
|
12292
12292
|
}
|
|
12293
12293
|
|
|
12294
12294
|
// src/lib/db/entities/operations.ts
|
|
12295
|
+
async function assertCanWrite(ctx) {
|
|
12296
|
+
if (ctx.canWrite && !await ctx.canWrite()) {
|
|
12297
|
+
throw new Error("Memory source is no longer eligible");
|
|
12298
|
+
}
|
|
12299
|
+
}
|
|
12295
12300
|
function entityToStored(e) {
|
|
12296
12301
|
return {
|
|
12297
12302
|
uniqueId: e.id,
|
|
@@ -12432,6 +12437,7 @@ async function linkMemoryEntitiesOp(ctx, memoryId, entityInputs, options) {
|
|
|
12432
12437
|
let skipped = false;
|
|
12433
12438
|
let entities = [];
|
|
12434
12439
|
await ctx.database.write(async () => {
|
|
12440
|
+
await assertCanWrite(ctx);
|
|
12435
12441
|
const {
|
|
12436
12442
|
entities: byName,
|
|
12437
12443
|
operations: entityOps,
|
|
@@ -12507,6 +12513,7 @@ async function replaceMemoryEntities(ctx, memoryId, entityInputs, options) {
|
|
|
12507
12513
|
let skipped = false;
|
|
12508
12514
|
let entities = [];
|
|
12509
12515
|
await ctx.database.write(async () => {
|
|
12516
|
+
await assertCanWrite(ctx);
|
|
12510
12517
|
const vaultRow = await findVaultRowInWrite(ctx, memoryId);
|
|
12511
12518
|
if (options.guarded && autoLinkBlocked(vaultRow)) {
|
|
12512
12519
|
skipped = true;
|
|
@@ -12567,6 +12574,7 @@ async function unlinkMemoryEntitiesOp(ctx, memoryIds) {
|
|
|
12567
12574
|
const links = await ctx.memoryEntityCollection.query(import_watermelondb11.Q.where("memory_id", import_watermelondb11.Q.oneOf(Array.from(memoryIds)))).fetch();
|
|
12568
12575
|
if (links.length === 0) return;
|
|
12569
12576
|
await ctx.database.write(async () => {
|
|
12577
|
+
await assertCanWrite(ctx);
|
|
12570
12578
|
await ctx.database.batch(...links.map((l) => l.prepareDestroyPermanently()));
|
|
12571
12579
|
});
|
|
12572
12580
|
}
|
|
@@ -12575,6 +12583,7 @@ async function unlinkAllMemoryEntitiesForUserOp(ctx, userId) {
|
|
|
12575
12583
|
const links = await ctx.memoryEntityCollection.query(import_watermelondb11.Q.where("user_id", userId)).fetch();
|
|
12576
12584
|
if (links.length === 0) return;
|
|
12577
12585
|
await ctx.database.write(async () => {
|
|
12586
|
+
await assertCanWrite(ctx);
|
|
12578
12587
|
await ctx.database.batch(...links.map((l) => l.prepareDestroyPermanently()));
|
|
12579
12588
|
});
|
|
12580
12589
|
}
|
|
@@ -12594,6 +12603,7 @@ async function backfillMemoryEntityUserIdsOp(ctx, vaultMemoryCollection) {
|
|
|
12594
12603
|
}
|
|
12595
12604
|
if (toUpdate.length === 0) return 0;
|
|
12596
12605
|
await ctx.database.write(async () => {
|
|
12606
|
+
await assertCanWrite(ctx);
|
|
12597
12607
|
await ctx.database.batch(
|
|
12598
12608
|
...toUpdate.map(({ link, userId }) => link.prepareUpdate((r) => r._setRaw("user_id", userId)))
|
|
12599
12609
|
);
|
|
@@ -14915,6 +14925,17 @@ async function decryptVaultMemoryFields(memory, address, signMessage, embeddedWa
|
|
|
14915
14925
|
};
|
|
14916
14926
|
}
|
|
14917
14927
|
|
|
14928
|
+
// src/lib/db/memoryVault/sourceChunkIds.ts
|
|
14929
|
+
var MAX_SOURCE_CHUNK_IDS_BYTES = 16 << 10;
|
|
14930
|
+
var utf8 = new TextEncoder();
|
|
14931
|
+
function serializeSourceChunkIds(ids) {
|
|
14932
|
+
const sizes = ids.map((id) => utf8.encode(JSON.stringify(id)).length + 1);
|
|
14933
|
+
let total = sizes.reduce((sum, size) => sum + size, 1);
|
|
14934
|
+
let start = 0;
|
|
14935
|
+
while (total > MAX_SOURCE_CHUNK_IDS_BYTES && start < ids.length) total -= sizes[start++];
|
|
14936
|
+
return JSON.stringify(ids.slice(start));
|
|
14937
|
+
}
|
|
14938
|
+
|
|
14918
14939
|
// src/lib/db/memoryVault/types.ts
|
|
14919
14940
|
var MEMORY_KINDS = [
|
|
14920
14941
|
"display_name",
|
|
@@ -14987,6 +15008,11 @@ function visibilityConditions(requested) {
|
|
|
14987
15008
|
function isKinded(record2) {
|
|
14988
15009
|
return record2.kind !== null && record2.kind !== void 0;
|
|
14989
15010
|
}
|
|
15011
|
+
async function assertCanWrite2(ctx) {
|
|
15012
|
+
if (ctx.canWrite && !await ctx.canWrite()) {
|
|
15013
|
+
throw new Error("Memory source is no longer eligible");
|
|
15014
|
+
}
|
|
15015
|
+
}
|
|
14990
15016
|
function assertValidKindLevel(kind, level) {
|
|
14991
15017
|
const hasKind = kind !== null && kind !== void 0;
|
|
14992
15018
|
if (hasKind && !MEMORY_KINDS.includes(kind)) {
|
|
@@ -15062,15 +15088,15 @@ async function mapInBatches(items, fn) {
|
|
|
15062
15088
|
return results;
|
|
15063
15089
|
}
|
|
15064
15090
|
function vaultMemoryToStoredRaw(memory) {
|
|
15065
|
-
let
|
|
15091
|
+
let sourceChunkIds2 = null;
|
|
15066
15092
|
if (memory.sourceChunkIds) {
|
|
15067
15093
|
try {
|
|
15068
15094
|
const parsed = JSON.parse(memory.sourceChunkIds);
|
|
15069
15095
|
if (Array.isArray(parsed)) {
|
|
15070
|
-
|
|
15096
|
+
sourceChunkIds2 = parsed.filter((s) => typeof s === "string");
|
|
15071
15097
|
}
|
|
15072
15098
|
} catch {
|
|
15073
|
-
|
|
15099
|
+
sourceChunkIds2 = null;
|
|
15074
15100
|
}
|
|
15075
15101
|
}
|
|
15076
15102
|
return {
|
|
@@ -15084,7 +15110,7 @@ function vaultMemoryToStoredRaw(memory) {
|
|
|
15084
15110
|
userId: memory.userId ?? null,
|
|
15085
15111
|
embedding: memory.embedding ?? null,
|
|
15086
15112
|
embeddingModel: memory.embeddingModel ?? null,
|
|
15087
|
-
sourceChunkIds,
|
|
15113
|
+
sourceChunkIds: sourceChunkIds2,
|
|
15088
15114
|
proofCount: memory.proofCount ?? null,
|
|
15089
15115
|
source: memory.source ?? null,
|
|
15090
15116
|
media: parseMedia(memory.media),
|
|
@@ -15133,7 +15159,7 @@ function populateNewVaultMemory(record2, ctx, opts, encryptedContent, encryptedK
|
|
|
15133
15159
|
record2._setRaw("embedding_model", opts.embeddingModel ?? null);
|
|
15134
15160
|
}
|
|
15135
15161
|
if (opts.sourceChunkIds !== void 0) {
|
|
15136
|
-
record2._setRaw("source_chunk_ids",
|
|
15162
|
+
record2._setRaw("source_chunk_ids", serializeSourceChunkIds(opts.sourceChunkIds));
|
|
15137
15163
|
}
|
|
15138
15164
|
record2._setRaw("proof_count", opts.proofCount ?? 1);
|
|
15139
15165
|
record2._setRaw("source", opts.source ?? "manual");
|
|
@@ -15167,8 +15193,7 @@ async function createVaultMemoryOp(ctx, opts) {
|
|
|
15167
15193
|
ctx.embeddedWalletSigner
|
|
15168
15194
|
) : opts.content;
|
|
15169
15195
|
const created = await ctx.database.write(async () => {
|
|
15170
|
-
|
|
15171
|
-
throw new Error("Memory source is no longer eligible");
|
|
15196
|
+
await assertCanWrite2(ctx);
|
|
15172
15197
|
return ctx.vaultMemoryCollection.create(
|
|
15173
15198
|
(record2) => populateNewVaultMemory(record2, ctx, opts, encryptedContent, encryptedKindValue)
|
|
15174
15199
|
);
|
|
@@ -15187,8 +15212,7 @@ async function createSupersedingMemoryOp(ctx, opts, targetId) {
|
|
|
15187
15212
|
) : opts.content;
|
|
15188
15213
|
let createdRecord = null;
|
|
15189
15214
|
await ctx.database.write(async () => {
|
|
15190
|
-
|
|
15191
|
-
throw new Error("Memory source is no longer eligible");
|
|
15215
|
+
await assertCanWrite2(ctx);
|
|
15192
15216
|
let target;
|
|
15193
15217
|
try {
|
|
15194
15218
|
target = await ctx.vaultMemoryCollection.find(targetId);
|
|
@@ -15280,8 +15304,7 @@ async function createVaultMemoriesBatchOp(ctx, optionsArray) {
|
|
|
15280
15304
|
})
|
|
15281
15305
|
);
|
|
15282
15306
|
const created = await ctx.database.write(async () => {
|
|
15283
|
-
|
|
15284
|
-
throw new Error("Memory source is no longer eligible");
|
|
15307
|
+
await assertCanWrite2(ctx);
|
|
15285
15308
|
const prepared = optionsArray.map(
|
|
15286
15309
|
(opts, i) => ctx.vaultMemoryCollection.prepareCreate(
|
|
15287
15310
|
(record2) => populateNewVaultMemory(record2, ctx, opts, encryptedContents[i], encryptedKindValues[i])
|
|
@@ -15311,16 +15334,16 @@ async function getVaultMemoryOp(ctx, id) {
|
|
|
15311
15334
|
}
|
|
15312
15335
|
}
|
|
15313
15336
|
function vaultMemoryRawToStoredRaw(raw) {
|
|
15314
|
-
let
|
|
15337
|
+
let sourceChunkIds2 = null;
|
|
15315
15338
|
const rawChunks = raw.source_chunk_ids;
|
|
15316
15339
|
if (typeof rawChunks === "string" && rawChunks) {
|
|
15317
15340
|
try {
|
|
15318
15341
|
const parsed = JSON.parse(rawChunks);
|
|
15319
15342
|
if (Array.isArray(parsed)) {
|
|
15320
|
-
|
|
15343
|
+
sourceChunkIds2 = parsed.filter((s) => typeof s === "string");
|
|
15321
15344
|
}
|
|
15322
15345
|
} catch {
|
|
15323
|
-
|
|
15346
|
+
sourceChunkIds2 = null;
|
|
15324
15347
|
}
|
|
15325
15348
|
}
|
|
15326
15349
|
return {
|
|
@@ -15334,7 +15357,7 @@ function vaultMemoryRawToStoredRaw(raw) {
|
|
|
15334
15357
|
userId: raw.user_id ?? null,
|
|
15335
15358
|
embedding: raw.embedding ?? null,
|
|
15336
15359
|
embeddingModel: raw.embedding_model ?? null,
|
|
15337
|
-
sourceChunkIds,
|
|
15360
|
+
sourceChunkIds: sourceChunkIds2,
|
|
15338
15361
|
proofCount: raw.proof_count ?? null,
|
|
15339
15362
|
source: raw.source ?? null,
|
|
15340
15363
|
eventTimeStart: raw.event_time_start ?? null,
|
|
@@ -15586,8 +15609,7 @@ async function updateVaultMemoryOp(ctx, id, opts) {
|
|
|
15586
15609
|
const record2 = probe;
|
|
15587
15610
|
const originalUpdatedAt = record2.updatedAt.getTime();
|
|
15588
15611
|
await ctx.database.write(async () => {
|
|
15589
|
-
|
|
15590
|
-
throw new Error("Memory source is no longer eligible");
|
|
15612
|
+
await assertCanWrite2(ctx);
|
|
15591
15613
|
if (record2.isDeleted || record2.supersededBy || !isOwnedByCtxUser(ctx, record2) || opts.freeFormOnly && isKinded(record2)) {
|
|
15592
15614
|
stale = true;
|
|
15593
15615
|
return;
|
|
@@ -15631,7 +15653,7 @@ async function updateVaultMemoryOp(ctx, id, opts) {
|
|
|
15631
15653
|
if (opts.sourceChunkIds !== void 0) {
|
|
15632
15654
|
r._setRaw(
|
|
15633
15655
|
"source_chunk_ids",
|
|
15634
|
-
|
|
15656
|
+
serializeSourceChunkIds(
|
|
15635
15657
|
opts.observationSourceIds?.length ? [.../* @__PURE__ */ new Set([...observedSources, ...opts.sourceChunkIds])] : opts.sourceChunkIds
|
|
15636
15658
|
)
|
|
15637
15659
|
);
|
|
@@ -15698,6 +15720,7 @@ async function setMemoryEntitiesOp(ctx, memoryId, entities) {
|
|
|
15698
15720
|
let stale = false;
|
|
15699
15721
|
const originalUpdatedAt = record2.updatedAt.getTime();
|
|
15700
15722
|
await ctx.database.write(async (writer) => {
|
|
15723
|
+
await assertCanWrite2(ctx);
|
|
15701
15724
|
if (record2.isDeleted || !isOwnedByCtxUser(ctx, record2)) {
|
|
15702
15725
|
stale = true;
|
|
15703
15726
|
return;
|
|
@@ -15739,6 +15762,7 @@ async function clearMemoryTopicsOverrideOp(ctx, memoryId, options) {
|
|
|
15739
15762
|
const originalUpdatedAt = record2.updatedAt.getTime();
|
|
15740
15763
|
let cleared = false;
|
|
15741
15764
|
await ctx.database.write(async () => {
|
|
15765
|
+
await assertCanWrite2(ctx);
|
|
15742
15766
|
if (options?.unlessTopicsRecorded && parseTopics(record2.topics) !== null) return;
|
|
15743
15767
|
cleared = true;
|
|
15744
15768
|
await record2.update((r) => {
|
|
@@ -15762,6 +15786,7 @@ async function setMemoryVisibilityOp(ctx, id, opts) {
|
|
|
15762
15786
|
if (record2.isDeleted || !isOwnedByCtxUser(ctx, record2)) return null;
|
|
15763
15787
|
let stale = false;
|
|
15764
15788
|
await ctx.database.write(async () => {
|
|
15789
|
+
await assertCanWrite2(ctx);
|
|
15765
15790
|
if (record2.isDeleted || !isOwnedByCtxUser(ctx, record2)) {
|
|
15766
15791
|
stale = true;
|
|
15767
15792
|
return;
|
|
@@ -15790,6 +15815,7 @@ async function deleteVaultMemoryOp(ctx, id) {
|
|
|
15790
15815
|
if (record2.isDeleted || !isOwnedByCtxUser(ctx, record2)) return false;
|
|
15791
15816
|
let stale = false;
|
|
15792
15817
|
await ctx.database.write(async () => {
|
|
15818
|
+
await assertCanWrite2(ctx);
|
|
15793
15819
|
if (record2.isDeleted || !isOwnedByCtxUser(ctx, record2)) {
|
|
15794
15820
|
stale = true;
|
|
15795
15821
|
return;
|
|
@@ -15827,8 +15853,7 @@ async function supersedeVaultMemoryOp(ctx, id, supersededById) {
|
|
|
15827
15853
|
}
|
|
15828
15854
|
let stale = false;
|
|
15829
15855
|
await ctx.database.write(async () => {
|
|
15830
|
-
|
|
15831
|
-
throw new Error("Memory source is no longer eligible");
|
|
15856
|
+
await assertCanWrite2(ctx);
|
|
15832
15857
|
if (record2.isDeleted || record2.supersededBy || !isOwnedByCtxUser(ctx, record2)) {
|
|
15833
15858
|
stale = true;
|
|
15834
15859
|
return;
|
|
@@ -15990,6 +16015,7 @@ async function stampTopicsExtractedAtOp(ctx, memoryIds, extractedAt, version = T
|
|
|
15990
16015
|
for (let i = 0; i < uniqueIds.length; i += CHUNK) {
|
|
15991
16016
|
const chunkIds = uniqueIds.slice(i, i + CHUNK);
|
|
15992
16017
|
await ctx.database.write(async () => {
|
|
16018
|
+
await assertCanWrite2(ctx);
|
|
15993
16019
|
const records = [];
|
|
15994
16020
|
for (const id of chunkIds) {
|
|
15995
16021
|
try {
|
|
@@ -16023,6 +16049,7 @@ async function relinkMemoryTopicsOp(ctx, memoryIds) {
|
|
|
16023
16049
|
for (const id of Array.from(new Set(memoryIds))) {
|
|
16024
16050
|
try {
|
|
16025
16051
|
await ctx.database.write(async (writer) => {
|
|
16052
|
+
await assertCanWrite2(ctx);
|
|
16026
16053
|
let record2;
|
|
16027
16054
|
try {
|
|
16028
16055
|
record2 = await ctx.vaultMemoryCollection.find(id);
|
|
@@ -16053,6 +16080,7 @@ async function backfillMemoryTopicsOp(ctx, memoryIds) {
|
|
|
16053
16080
|
for (let i = 0; i < uniqueIds.length; i += CHUNK) {
|
|
16054
16081
|
const chunkIds = uniqueIds.slice(i, i + CHUNK);
|
|
16055
16082
|
await ctx.database.write(async () => {
|
|
16083
|
+
await assertCanWrite2(ctx);
|
|
16056
16084
|
const writes = [];
|
|
16057
16085
|
for (const id of chunkIds) {
|
|
16058
16086
|
let record2;
|
|
@@ -16085,6 +16113,7 @@ async function deleteAllVaultMemoriesForUserOp(ctx, userId) {
|
|
|
16085
16113
|
const records = await ctx.vaultMemoryCollection.query(import_watermelondb23.Q.where("user_id", userId), import_watermelondb23.Q.where("is_deleted", false)).fetch();
|
|
16086
16114
|
if (records.length === 0) return 0;
|
|
16087
16115
|
await ctx.database.write(async () => {
|
|
16116
|
+
await assertCanWrite2(ctx);
|
|
16088
16117
|
const prepared = records.map(
|
|
16089
16118
|
(record2) => record2.prepareUpdate((r) => {
|
|
16090
16119
|
r._setRaw("is_deleted", true);
|
|
@@ -16139,6 +16168,7 @@ async function archiveVaultMemoryOp(ctx, id, opts) {
|
|
|
16139
16168
|
let stale = false;
|
|
16140
16169
|
const archivedAtValue = opts?.now ?? Date.now();
|
|
16141
16170
|
await ctx.database.write(async () => {
|
|
16171
|
+
await assertCanWrite2(ctx);
|
|
16142
16172
|
if (record2.isDeleted || !isOwnedByCtxUser(ctx, record2) || record2.archivedAt !== null) {
|
|
16143
16173
|
stale = true;
|
|
16144
16174
|
return;
|
|
@@ -16162,6 +16192,7 @@ async function restoreVaultMemoryOp(ctx, id) {
|
|
|
16162
16192
|
if (record2.isDeleted || !isOwnedByCtxUser(ctx, record2)) return false;
|
|
16163
16193
|
let stale = false;
|
|
16164
16194
|
await ctx.database.write(async () => {
|
|
16195
|
+
await assertCanWrite2(ctx);
|
|
16165
16196
|
if (record2.isDeleted || !isOwnedByCtxUser(ctx, record2)) {
|
|
16166
16197
|
stale = true;
|
|
16167
16198
|
return;
|
|
@@ -16182,6 +16213,7 @@ async function hardDeleteDecayedOp(ctx, id, opts) {
|
|
|
16182
16213
|
const now = opts.now ?? Date.now();
|
|
16183
16214
|
let stale = false;
|
|
16184
16215
|
await ctx.database.write(async () => {
|
|
16216
|
+
await assertCanWrite2(ctx);
|
|
16185
16217
|
const archivedAt = record2.archivedAt;
|
|
16186
16218
|
if (record2.isDeleted || !isOwnedByCtxUser(ctx, record2) || archivedAt === null || now - archivedAt <= opts.hardDeleteWindowMs) {
|
|
16187
16219
|
stale = true;
|
|
@@ -16221,6 +16253,7 @@ async function updateVaultMemoryEmbeddingOp(ctx, id, embedding2, embeddingModel,
|
|
|
16221
16253
|
}
|
|
16222
16254
|
let written = false;
|
|
16223
16255
|
await ctx.database.write(async () => {
|
|
16256
|
+
await assertCanWrite2(ctx);
|
|
16224
16257
|
if (record2.isDeleted || !isOwnedByCtxUser(ctx, record2)) return;
|
|
16225
16258
|
const originalUpdatedAt = record2.updatedAt.getTime();
|
|
16226
16259
|
if (originalUpdatedAt !== readUpdatedAt || record2._getRaw("content") !== readStoredContent)
|
|
@@ -20217,6 +20250,13 @@ function restoreCandidates(candidates, redactor, ownNames) {
|
|
|
20217
20250
|
).map((c) => c.candidate);
|
|
20218
20251
|
}
|
|
20219
20252
|
async function extractAndRetain(messages, retainCtx, options) {
|
|
20253
|
+
const { memoryStore, signal } = options;
|
|
20254
|
+
if (memoryStore === null) throw new Error("Memory store is not ready");
|
|
20255
|
+
if (memoryStore && options.folderId !== void 0 && options.folderId !== null)
|
|
20256
|
+
throw new Error("Remote memory extraction does not support folders");
|
|
20257
|
+
if (memoryStore && options.extract.piiRedaction && !memoryStore.masksEmbeddingInput)
|
|
20258
|
+
throw new Error("PII-redacted extraction requires a memory store that masks embedding inputs");
|
|
20259
|
+
signal?.throwIfAborted();
|
|
20220
20260
|
const minConfidence = options.minConfidence ?? DEFAULT_MIN_CONFIDENCE;
|
|
20221
20261
|
const resolvedConsolidatePii = options.consolidateOptions?.piiRedaction ?? options.extract.piiRedaction;
|
|
20222
20262
|
const consolidateOptions = options.consolidateOptions !== void 0 ? {
|
|
@@ -20250,6 +20290,7 @@ async function extractAndRetain(messages, retainCtx, options) {
|
|
|
20250
20290
|
}
|
|
20251
20291
|
});
|
|
20252
20292
|
const extractMs = Date.now() - tExtract;
|
|
20293
|
+
signal?.throwIfAborted();
|
|
20253
20294
|
const filtered = candidates.filter((c) => c.confidence >= minConfidence);
|
|
20254
20295
|
const log = getLogger();
|
|
20255
20296
|
const screened = screenCandidatesForInjection(filtered);
|
|
@@ -20297,16 +20338,33 @@ async function extractAndRetain(messages, retainCtx, options) {
|
|
|
20297
20338
|
const results = [];
|
|
20298
20339
|
const quarantinedInfo = [];
|
|
20299
20340
|
let failedWrites = 0;
|
|
20341
|
+
let auditRows;
|
|
20300
20342
|
const tRetain = Date.now();
|
|
20301
20343
|
for (const { candidate, isQuarantined, reason, signature } of toRetain) {
|
|
20302
20344
|
try {
|
|
20345
|
+
signal?.throwIfAborted();
|
|
20303
20346
|
if (isQuarantined) {
|
|
20304
|
-
|
|
20305
|
-
|
|
20306
|
-
|
|
20307
|
-
|
|
20308
|
-
|
|
20309
|
-
|
|
20347
|
+
let existingId;
|
|
20348
|
+
if (memoryStore) {
|
|
20349
|
+
auditRows ?? (auditRows = memoryStore.list({
|
|
20350
|
+
scopes: [options.scope ?? "private"],
|
|
20351
|
+
includeArchived: true,
|
|
20352
|
+
includeQuarantined: true,
|
|
20353
|
+
includeSuperseded: true
|
|
20354
|
+
}));
|
|
20355
|
+
const sourceKey = [...new Set(candidate.sourceMessageIds)].sort().join("\0");
|
|
20356
|
+
const normalize = (value) => value.normalize("NFKC").trim().replace(/\s+/g, " ").toLowerCase();
|
|
20357
|
+
existingId = (await auditRows).find(
|
|
20358
|
+
(row) => row.trustTier === "quarantined" && row.scope === (options.scope ?? "private") && [...new Set(row.sourceChunkIds ?? [])].sort().join("\0") === sourceKey && normalize(row.content) === normalize(candidate.content)
|
|
20359
|
+
)?.uniqueId ?? null;
|
|
20360
|
+
} else {
|
|
20361
|
+
existingId = await findQuarantinedDuplicateOp(
|
|
20362
|
+
retainCtx.vaultCtx,
|
|
20363
|
+
candidate.content,
|
|
20364
|
+
candidate.sourceMessageIds,
|
|
20365
|
+
{ scope: options.scope ?? "private", folderId: options.folderId ?? null }
|
|
20366
|
+
).catch(() => null);
|
|
20367
|
+
}
|
|
20310
20368
|
if (existingId) {
|
|
20311
20369
|
quarantinedInfo.push({
|
|
20312
20370
|
candidate,
|
|
@@ -20317,18 +20375,26 @@ async function extractAndRetain(messages, retainCtx, options) {
|
|
|
20317
20375
|
continue;
|
|
20318
20376
|
}
|
|
20319
20377
|
}
|
|
20320
|
-
const
|
|
20378
|
+
const retainOptions = {
|
|
20321
20379
|
source: "auto-extracted",
|
|
20322
20380
|
sourceChunkIds: candidate.sourceMessageIds,
|
|
20323
20381
|
respectTombstones: true,
|
|
20324
20382
|
...options.scope !== void 0 && { scope: options.scope },
|
|
20325
|
-
...options.folderId !== void 0 && { folderId: options.folderId },
|
|
20326
20383
|
...consolidateOptions !== void 0 && { consolidateOptions },
|
|
20327
20384
|
...candidate.eventTime !== null && { eventTime: candidate.eventTime },
|
|
20328
20385
|
factType: candidate.type,
|
|
20329
20386
|
...isQuarantined && { trustTier: "quarantined", enableAutoMerge: false }
|
|
20387
|
+
};
|
|
20388
|
+
const result = memoryStore ? await memoryStore.retain(candidate.content, {
|
|
20389
|
+
...retainOptions,
|
|
20390
|
+
canWrite: retainCtx.vaultCtx.canWrite,
|
|
20391
|
+
signal
|
|
20392
|
+
}) : await retain(candidate.content, retainCtx, {
|
|
20393
|
+
...retainOptions,
|
|
20394
|
+
...options.folderId !== void 0 && { folderId: options.folderId }
|
|
20330
20395
|
});
|
|
20331
20396
|
if (isQuarantined) {
|
|
20397
|
+
auditRows = void 0;
|
|
20332
20398
|
const info = {
|
|
20333
20399
|
candidate,
|
|
20334
20400
|
memoryId: result.memoryId,
|
|
@@ -20347,9 +20413,16 @@ async function extractAndRetain(messages, retainCtx, options) {
|
|
|
20347
20413
|
}
|
|
20348
20414
|
succeededCandidates.push(candidate);
|
|
20349
20415
|
results.push(result);
|
|
20350
|
-
if (result.action !== "suppressed" &&
|
|
20416
|
+
if (result.action !== "suppressed" && candidate.entities.length > 0) {
|
|
20351
20417
|
try {
|
|
20352
|
-
|
|
20418
|
+
signal?.throwIfAborted();
|
|
20419
|
+
if (memoryStore) {
|
|
20420
|
+
await memoryStore.addTopics(result.memoryId, candidate.entities, {
|
|
20421
|
+
unlessUserManaged: true,
|
|
20422
|
+
canWrite: retainCtx.vaultCtx.canWrite,
|
|
20423
|
+
signal
|
|
20424
|
+
});
|
|
20425
|
+
} else if (options.entityCtx && !await isMemoryTopicsUserManaged(options.entityCtx, result.memoryId)) {
|
|
20353
20426
|
await linkMemoryEntitiesOp(options.entityCtx, result.memoryId, candidate.entities, {
|
|
20354
20427
|
unlessTopicsUserManaged: true
|
|
20355
20428
|
});
|
|
@@ -20599,7 +20672,7 @@ function createAutoExtractor(options) {
|
|
|
20599
20672
|
};
|
|
20600
20673
|
const consolidateOptions = options.consolidate ? { ...options.consolidate, ...subPassAuth(options.consolidate.baseUrl) } : void 0;
|
|
20601
20674
|
const injectionClassifierOptions = options.injectionClassifier ? { ...options.injectionClassifier, ...subPassAuth(options.injectionClassifier.baseUrl) } : void 0;
|
|
20602
|
-
if (options.retainCtx.vaultCtx.entityCtx && !options.entityCtx) {
|
|
20675
|
+
if (!options.memoryStore && options.retainCtx.vaultCtx.entityCtx && !options.entityCtx) {
|
|
20603
20676
|
getLogger().warn(
|
|
20604
20677
|
"[memory/extract] retainCtx.vaultCtx.entityCtx is set but extractor was created without `entityCtx` \u2014 W5 graph lane will receive no writes"
|
|
20605
20678
|
);
|
|
@@ -20644,6 +20717,8 @@ function createAutoExtractor(options) {
|
|
|
20644
20717
|
try {
|
|
20645
20718
|
const { candidates, results, failedCount, outcome: outcome2, failure, funnel, timings, model } = await extractAndRetain(window2, retainCtx, {
|
|
20646
20719
|
extract,
|
|
20720
|
+
memoryStore: options.memoryStore,
|
|
20721
|
+
signal: options.signal,
|
|
20647
20722
|
...options.minConfidence !== void 0 && { minConfidence: options.minConfidence },
|
|
20648
20723
|
...options.entityCtx !== void 0 && { entityCtx: options.entityCtx },
|
|
20649
20724
|
...options.scope !== void 0 && { scope: options.scope },
|
|
@@ -22775,6 +22850,7 @@ function createLocalMemoryStore(options) {
|
|
|
22775
22850
|
database,
|
|
22776
22851
|
entityCollection: database.get("entity"),
|
|
22777
22852
|
memoryEntityCollection: database.get("memory_entity"),
|
|
22853
|
+
canWrite: options.canWrite,
|
|
22778
22854
|
...userId !== void 0 && { userId },
|
|
22779
22855
|
...options.allowUnscopedRows !== void 0 && {
|
|
22780
22856
|
allowUnscopedRows: options.allowUnscopedRows
|
|
@@ -22786,10 +22862,21 @@ function createLocalMemoryStore(options) {
|
|
|
22786
22862
|
walletAddress: options.walletAddress,
|
|
22787
22863
|
signMessage: options.signMessage,
|
|
22788
22864
|
embeddedWalletSigner: options.embeddedWalletSigner,
|
|
22865
|
+
canWrite: options.canWrite,
|
|
22789
22866
|
...userId !== void 0 && { userId },
|
|
22790
22867
|
...options.singleTenant !== void 0 && { singleTenant: options.singleTenant },
|
|
22791
22868
|
entityCtx
|
|
22792
22869
|
};
|
|
22870
|
+
const assertWrite = async (writeOptions) => {
|
|
22871
|
+
writeOptions?.signal?.throwIfAborted();
|
|
22872
|
+
if (writeOptions?.canWrite && !await writeOptions.canWrite()) {
|
|
22873
|
+
throw new Error("Memory source is no longer eligible");
|
|
22874
|
+
}
|
|
22875
|
+
if (options.canWrite && !await options.canWrite()) {
|
|
22876
|
+
throw new Error("Memory source is no longer eligible");
|
|
22877
|
+
}
|
|
22878
|
+
writeOptions?.signal?.throwIfAborted();
|
|
22879
|
+
};
|
|
22793
22880
|
const vaultCache = options.vaultCache ?? createVaultEmbeddingCache();
|
|
22794
22881
|
const ownedBy = userId !== void 0 ? [import_watermelondb32.Q.where("user_id", userId)] : [];
|
|
22795
22882
|
const linksOwnedBy = userId === void 0 ? [] : options.allowUnscopedRows ? [import_watermelondb32.Q.or(import_watermelondb32.Q.where("user_id", userId), import_watermelondb32.Q.where("user_id", null))] : [import_watermelondb32.Q.where("user_id", userId)];
|
|
@@ -22901,9 +22988,25 @@ function createLocalMemoryStore(options) {
|
|
|
22901
22988
|
archive: (id) => archiveVaultMemoryOp(vaultCtx, id),
|
|
22902
22989
|
restore: (id) => restoreVaultMemoryOp(vaultCtx, id),
|
|
22903
22990
|
setTopics: (memoryId, topics) => setMemoryEntitiesOp(vaultCtx, memoryId, topics),
|
|
22904
|
-
addTopics: (memoryId, topics) => database.write(async (writer) => {
|
|
22991
|
+
addTopics: (memoryId, topics, writeOptions) => database.write(async (writer) => {
|
|
22992
|
+
await assertWrite(writeOptions);
|
|
22905
22993
|
const owned = await vaultCtx.vaultMemoryCollection.query(import_watermelondb32.Q.where("id", memoryId), import_watermelondb32.Q.where("is_deleted", false), ...ownedBy).fetchCount();
|
|
22906
|
-
return owned > 0 ? writer.callWriter(
|
|
22994
|
+
return owned > 0 ? writer.callWriter(
|
|
22995
|
+
() => linkMemoryEntitiesOp(
|
|
22996
|
+
{
|
|
22997
|
+
...entityCtx,
|
|
22998
|
+
canWrite: async () => {
|
|
22999
|
+
await assertWrite(writeOptions);
|
|
23000
|
+
return true;
|
|
23001
|
+
}
|
|
23002
|
+
},
|
|
23003
|
+
memoryId,
|
|
23004
|
+
topics,
|
|
23005
|
+
{
|
|
23006
|
+
unlessTopicsUserManaged: writeOptions?.unlessUserManaged
|
|
23007
|
+
}
|
|
23008
|
+
)
|
|
23009
|
+
) : [];
|
|
22907
23010
|
}),
|
|
22908
23011
|
setVisibility: (id, visibility, visibilityOptions) => setMemoryVisibilityOp(vaultCtx, id, { visibility, ...visibilityOptions }),
|
|
22909
23012
|
recall: (query, recallOptions) => recall(
|
|
@@ -22913,7 +23016,17 @@ function createLocalMemoryStore(options) {
|
|
|
22913
23016
|
),
|
|
22914
23017
|
retain: (content, retainOptions) => retain(
|
|
22915
23018
|
content,
|
|
22916
|
-
{
|
|
23019
|
+
{
|
|
23020
|
+
vaultCtx: {
|
|
23021
|
+
...vaultCtx,
|
|
23022
|
+
canWrite: async () => {
|
|
23023
|
+
await assertWrite(retainOptions);
|
|
23024
|
+
return true;
|
|
23025
|
+
}
|
|
23026
|
+
},
|
|
23027
|
+
embeddingOptions: options.embeddingOptions,
|
|
23028
|
+
vaultCache
|
|
23029
|
+
},
|
|
22917
23030
|
retainOptions
|
|
22918
23031
|
),
|
|
22919
23032
|
factSource: {
|
|
@@ -23017,13 +23130,20 @@ function memoryCipher(canonical) {
|
|
|
23017
23130
|
};
|
|
23018
23131
|
}
|
|
23019
23132
|
async function reencryptMemoryField(value, canonical, fallbacks = []) {
|
|
23020
|
-
|
|
23021
|
-
|
|
23133
|
+
return memoryCipher(canonical).encrypt(
|
|
23134
|
+
await decryptMemoryField(value, [canonical, ...fallbacks])
|
|
23135
|
+
);
|
|
23136
|
+
}
|
|
23137
|
+
async function decryptMemoryField(value, rings) {
|
|
23138
|
+
if (!value.startsWith("enc:")) return value;
|
|
23022
23139
|
if (!isEncrypted(value))
|
|
23023
23140
|
throw new MemoryKeyError("Field has an encryption prefix but an invalid payload");
|
|
23024
|
-
return
|
|
23141
|
+
return decryptWith(value, rings);
|
|
23025
23142
|
}
|
|
23026
23143
|
|
|
23144
|
+
// src/lib/memory/store/remoteMigration.ts
|
|
23145
|
+
init_logger();
|
|
23146
|
+
|
|
23027
23147
|
// src/lib/memory/store/remotePersistence.ts
|
|
23028
23148
|
init_portalLlm();
|
|
23029
23149
|
var RemoteMemoryError = class extends Error {
|
|
@@ -23561,7 +23681,14 @@ function stored(row) {
|
|
|
23561
23681
|
function createRemoteMemoryPipeline(options) {
|
|
23562
23682
|
const { persistence, embeddingOptions } = options;
|
|
23563
23683
|
const model = embeddingOptions.model ?? DEFAULT_API_EMBEDDING_MODEL;
|
|
23564
|
-
const operation = (mode, queryOptions = embeddingOptions) => {
|
|
23684
|
+
const operation = (mode, queryOptions = embeddingOptions, writeOptions) => {
|
|
23685
|
+
const signal = writeOptions?.signal;
|
|
23686
|
+
const assertWrite = async () => {
|
|
23687
|
+
signal?.throwIfAborted();
|
|
23688
|
+
if (writeOptions?.canWrite && !await writeOptions.canWrite())
|
|
23689
|
+
throw new Error("Memory source is no longer eligible");
|
|
23690
|
+
signal?.throwIfAborted();
|
|
23691
|
+
};
|
|
23565
23692
|
const rejectUndecryptable = (failed) => {
|
|
23566
23693
|
if (!failed.length) return;
|
|
23567
23694
|
if (mode === "retain")
|
|
@@ -23579,7 +23706,7 @@ function createRemoteMemoryPipeline(options) {
|
|
|
23579
23706
|
return items.map((item) => stored(item.memory));
|
|
23580
23707
|
};
|
|
23581
23708
|
const get = async (id) => {
|
|
23582
|
-
const snapshot = snapshots.get(id) ?? await persistence.get(id);
|
|
23709
|
+
const snapshot = snapshots.get(id) ?? await (signal ? persistence.get(id, signal) : persistence.get(id));
|
|
23583
23710
|
if (!snapshot || snapshot.memory.is_deleted || snapshot.memory.superseded_by) return null;
|
|
23584
23711
|
snapshots.set(id, snapshot);
|
|
23585
23712
|
return stored(snapshot.memory);
|
|
@@ -23629,7 +23756,7 @@ function createRemoteMemoryPipeline(options) {
|
|
|
23629
23756
|
if (forced.size < 100 && temporal[i] !== void 0) forced.add(temporal[i]);
|
|
23630
23757
|
}
|
|
23631
23758
|
const forceIds = [...forced];
|
|
23632
|
-
const windowOptions = (i,
|
|
23759
|
+
const windowOptions = (i, signal2) => ({
|
|
23633
23760
|
limit: Math.min(100, Math.max((search.limit ?? 8) * 3, 30)),
|
|
23634
23761
|
force_ids: i === 0 ? forceIds : [],
|
|
23635
23762
|
...search.scopes && { scopes: search.scopes },
|
|
@@ -23637,13 +23764,15 @@ function createRemoteMemoryPipeline(options) {
|
|
|
23637
23764
|
...search.memoryIds !== void 0 && { memory_ids: search.memoryIds },
|
|
23638
23765
|
include_archived: search.includeArchived,
|
|
23639
23766
|
embedding_model: model,
|
|
23640
|
-
...
|
|
23767
|
+
...signal2 && { signal: signal2 }
|
|
23641
23768
|
});
|
|
23642
23769
|
const vectors = [queryEmbedding, ...facetEmbeddings];
|
|
23643
23770
|
let windows;
|
|
23644
23771
|
if (mode === "retain") {
|
|
23645
23772
|
windows = await Promise.all(
|
|
23646
|
-
vectors.map(
|
|
23773
|
+
vectors.map(
|
|
23774
|
+
(embedding2, i) => persistence.candidateSet(embedding2, windowOptions(i, signal))
|
|
23775
|
+
)
|
|
23647
23776
|
);
|
|
23648
23777
|
} else {
|
|
23649
23778
|
const deadline = new AbortController();
|
|
@@ -23716,7 +23845,7 @@ function createRemoteMemoryPipeline(options) {
|
|
|
23716
23845
|
embedding: storedVector(JSON.parse(input.embedding)),
|
|
23717
23846
|
embedding_model: input.embeddingModel
|
|
23718
23847
|
},
|
|
23719
|
-
source_chunk_ids:
|
|
23848
|
+
source_chunk_ids: serializeSourceChunkIds(input.sourceChunkIds ?? []),
|
|
23720
23849
|
proof_count: input.proofCount ?? 1,
|
|
23721
23850
|
source: input.source ?? "manual",
|
|
23722
23851
|
...input.eventTime && {
|
|
@@ -23731,12 +23860,15 @@ function createRemoteMemoryPipeline(options) {
|
|
|
23731
23860
|
twin_opt_in: false
|
|
23732
23861
|
};
|
|
23733
23862
|
};
|
|
23734
|
-
const write = async (memory, snapshot) =>
|
|
23863
|
+
const write = async (memory, snapshot) => {
|
|
23864
|
+
await assertWrite();
|
|
23865
|
+
return remember([await persistence.put(memory, snapshot, signal)])[0];
|
|
23866
|
+
};
|
|
23735
23867
|
const port = {
|
|
23736
23868
|
prepare,
|
|
23737
23869
|
get,
|
|
23738
23870
|
getFresh: async (id) => {
|
|
23739
|
-
const current = await persistence.get(id);
|
|
23871
|
+
const current = await (signal ? persistence.get(id, signal) : persistence.get(id));
|
|
23740
23872
|
return current && !current.memory.is_deleted && !current.memory.superseded_by ? stored(current.memory) : null;
|
|
23741
23873
|
},
|
|
23742
23874
|
tombstones: async (embedding2, embeddingModel, scope, folderId) => {
|
|
@@ -23747,7 +23879,8 @@ function createRemoteMemoryPipeline(options) {
|
|
|
23747
23879
|
embedding_model: embeddingModel,
|
|
23748
23880
|
strict_model: true,
|
|
23749
23881
|
include_deleted: true,
|
|
23750
|
-
deleted_only: true
|
|
23882
|
+
deleted_only: true,
|
|
23883
|
+
signal
|
|
23751
23884
|
});
|
|
23752
23885
|
rejectUndecryptable(window2.failed);
|
|
23753
23886
|
return remember(window2.items);
|
|
@@ -23775,7 +23908,7 @@ function createRemoteMemoryPipeline(options) {
|
|
|
23775
23908
|
const observed = sourceIds(memory.source_chunk_ids);
|
|
23776
23909
|
const replay = !!patch.observationSourceIds?.length && patch.observationSourceIds.every((id2) => observed.includes(id2));
|
|
23777
23910
|
if (patch.sourceChunkIds !== void 0)
|
|
23778
|
-
memory.source_chunk_ids =
|
|
23911
|
+
memory.source_chunk_ids = serializeSourceChunkIds(
|
|
23779
23912
|
patch.observationSourceIds?.length ? [.../* @__PURE__ */ new Set([...observed, ...patch.sourceChunkIds])] : patch.sourceChunkIds
|
|
23780
23913
|
);
|
|
23781
23914
|
if (!replay) {
|
|
@@ -23803,14 +23936,18 @@ function createRemoteMemoryPipeline(options) {
|
|
|
23803
23936
|
if (!target || !newer || id === successor) return false;
|
|
23804
23937
|
const old = snapshots.get(id);
|
|
23805
23938
|
const next = snapshots.get(successor);
|
|
23939
|
+
await assertWrite();
|
|
23806
23940
|
remember(
|
|
23807
|
-
await persistence.putMany(
|
|
23808
|
-
|
|
23809
|
-
|
|
23810
|
-
|
|
23811
|
-
|
|
23812
|
-
|
|
23813
|
-
|
|
23941
|
+
await persistence.putMany(
|
|
23942
|
+
[
|
|
23943
|
+
{
|
|
23944
|
+
memory: { ...old.memory, superseded_by: successor, superseded_at: Date.now() },
|
|
23945
|
+
expectedVersion: old
|
|
23946
|
+
},
|
|
23947
|
+
{ memory: next.memory, expectedVersion: next }
|
|
23948
|
+
],
|
|
23949
|
+
signal
|
|
23950
|
+
)
|
|
23814
23951
|
);
|
|
23815
23952
|
return true;
|
|
23816
23953
|
},
|
|
@@ -23819,18 +23956,22 @@ function createRemoteMemoryPipeline(options) {
|
|
|
23819
23956
|
if (!target) return { created: null, retired: false };
|
|
23820
23957
|
const snapshot = snapshots.get(targetId);
|
|
23821
23958
|
const successor = createRow(input);
|
|
23959
|
+
await assertWrite();
|
|
23822
23960
|
const rows = remember(
|
|
23823
|
-
await persistence.putMany(
|
|
23824
|
-
|
|
23825
|
-
|
|
23826
|
-
|
|
23827
|
-
|
|
23828
|
-
|
|
23829
|
-
|
|
23830
|
-
|
|
23831
|
-
|
|
23832
|
-
|
|
23833
|
-
|
|
23961
|
+
await persistence.putMany(
|
|
23962
|
+
[
|
|
23963
|
+
{ memory: successor, expectedVersion: 0 },
|
|
23964
|
+
{
|
|
23965
|
+
memory: {
|
|
23966
|
+
...snapshot.memory,
|
|
23967
|
+
superseded_by: successor.memory_id,
|
|
23968
|
+
superseded_at: Date.now()
|
|
23969
|
+
},
|
|
23970
|
+
expectedVersion: snapshot
|
|
23971
|
+
}
|
|
23972
|
+
],
|
|
23973
|
+
signal
|
|
23974
|
+
)
|
|
23834
23975
|
);
|
|
23835
23976
|
return { created: rows[0], retired: true };
|
|
23836
23977
|
}
|
|
@@ -23865,7 +24006,7 @@ function createRemoteMemoryPipeline(options) {
|
|
|
23865
24006
|
factSource,
|
|
23866
24007
|
recall: async (query, recallOptions = {}) => recall(query, { embeddingOptions, factSource }, { ...recallOptions, types: ["fact"] }),
|
|
23867
24008
|
retain: async (content, retainOptions) => {
|
|
23868
|
-
const { port } = operation("retain");
|
|
24009
|
+
const { port } = operation("retain", embeddingOptions, retainOptions);
|
|
23869
24010
|
return retainWithPersistence(
|
|
23870
24011
|
content,
|
|
23871
24012
|
{
|
|
@@ -23882,6 +24023,8 @@ function createRemoteMemoryPipeline(options) {
|
|
|
23882
24023
|
|
|
23883
24024
|
// src/lib/memory/store/remoteMigration.ts
|
|
23884
24025
|
var IMPORT_BATCH = 50;
|
|
24026
|
+
var EMBED_BATCH = 100;
|
|
24027
|
+
var LOCAL_VECTOR_DIMS = 4096;
|
|
23885
24028
|
var VERIFY_BATCH = 1e3;
|
|
23886
24029
|
var QUERY_IDS = 1e3;
|
|
23887
24030
|
var QUERY_PAGE = 200;
|
|
@@ -23907,7 +24050,7 @@ var SHORT_FIELDS = [
|
|
|
23907
24050
|
"visibility",
|
|
23908
24051
|
"geohash"
|
|
23909
24052
|
];
|
|
23910
|
-
var
|
|
24053
|
+
var utf82 = new TextEncoder();
|
|
23911
24054
|
var METADATA_FIELDS = [
|
|
23912
24055
|
"scope",
|
|
23913
24056
|
"kind",
|
|
@@ -23958,17 +24101,34 @@ function revision(raw) {
|
|
|
23958
24101
|
last_observed_at: num(raw.last_observed_at) ?? null
|
|
23959
24102
|
};
|
|
23960
24103
|
}
|
|
23961
|
-
function embedding(raw) {
|
|
24104
|
+
function embedding(raw, model) {
|
|
23962
24105
|
const value = text13(raw.embedding);
|
|
23963
24106
|
if (!value) return void 0;
|
|
23964
24107
|
try {
|
|
23965
|
-
|
|
24108
|
+
const vector = JSON.parse(value);
|
|
24109
|
+
const stored2 = text13(raw.embedding_model);
|
|
24110
|
+
if (stored2 === void 0 ? vector.length !== LOCAL_VECTOR_DIMS : stored2 !== model)
|
|
24111
|
+
return void 0;
|
|
24112
|
+
return storedVector(vector);
|
|
24113
|
+
} catch {
|
|
24114
|
+
return void 0;
|
|
24115
|
+
}
|
|
24116
|
+
}
|
|
24117
|
+
function stringArray(value) {
|
|
24118
|
+
try {
|
|
24119
|
+
const parsed = JSON.parse(value);
|
|
24120
|
+
return Array.isArray(parsed) && parsed.every((id) => typeof id === "string") ? parsed : void 0;
|
|
23966
24121
|
} catch {
|
|
23967
24122
|
return void 0;
|
|
23968
24123
|
}
|
|
23969
24124
|
}
|
|
24125
|
+
function sourceChunkIds(raw) {
|
|
24126
|
+
const value = text13(raw.source_chunk_ids);
|
|
24127
|
+
const ids = value && stringArray(value);
|
|
24128
|
+
return ids ? serializeSourceChunkIds(ids) : value;
|
|
24129
|
+
}
|
|
23970
24130
|
function bytes(value) {
|
|
23971
|
-
return value === void 0 ? 0 :
|
|
24131
|
+
return value === void 0 ? 0 : utf82.encode(value).length;
|
|
23972
24132
|
}
|
|
23973
24133
|
function fitsNearby(row) {
|
|
23974
24134
|
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);
|
|
@@ -23977,16 +24137,16 @@ function invalid(raw) {
|
|
|
23977
24137
|
const id = raw.id;
|
|
23978
24138
|
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;
|
|
23979
24139
|
}
|
|
23980
|
-
function metadata(raw) {
|
|
23981
|
-
const vector = embedding(raw);
|
|
24140
|
+
function metadata(raw, model) {
|
|
24141
|
+
const vector = embedding(raw, model);
|
|
23982
24142
|
return {
|
|
23983
24143
|
scope: raw.scope,
|
|
23984
24144
|
kind: text13(raw.kind),
|
|
23985
24145
|
level: text13(raw.level),
|
|
23986
24146
|
folder_id: text13(raw.folder_id),
|
|
23987
24147
|
is_deleted: bool(raw.is_deleted) ?? false,
|
|
23988
|
-
...vector && { embedding: vector, embedding_model:
|
|
23989
|
-
source_chunk_ids:
|
|
24148
|
+
...vector && { embedding: vector, embedding_model: model },
|
|
24149
|
+
source_chunk_ids: sourceChunkIds(raw),
|
|
23990
24150
|
proof_count: num(raw.proof_count),
|
|
23991
24151
|
source: text13(raw.source),
|
|
23992
24152
|
event_time_start: num(raw.event_time_start),
|
|
@@ -24015,30 +24175,63 @@ function defined(value) {
|
|
|
24015
24175
|
Object.entries(value).filter(([, field10]) => field10 !== void 0)
|
|
24016
24176
|
);
|
|
24017
24177
|
}
|
|
24018
|
-
async function
|
|
24019
|
-
const
|
|
24020
|
-
|
|
24021
|
-
|
|
24022
|
-
|
|
24023
|
-
|
|
24024
|
-
|
|
24025
|
-
|
|
24178
|
+
async function prepareRow(raw, canonical, rings, model, updatedAt) {
|
|
24179
|
+
const deleted = bool(raw.is_deleted) ?? false;
|
|
24180
|
+
const { encrypt } = memoryCipher(canonical);
|
|
24181
|
+
const localKindValue = text13(raw.kind_value);
|
|
24182
|
+
let plaintext;
|
|
24183
|
+
let kindValue;
|
|
24184
|
+
try {
|
|
24185
|
+
plaintext = await decryptMemoryField(typeof raw.content === "string" ? raw.content : "", rings);
|
|
24186
|
+
kindValue = localKindValue && await decryptMemoryField(localKindValue, rings);
|
|
24187
|
+
} catch (error) {
|
|
24188
|
+
if (!deleted || !(error instanceof MemoryKeyError)) throw error;
|
|
24189
|
+
plaintext = void 0;
|
|
24190
|
+
kindValue = void 0;
|
|
24191
|
+
}
|
|
24026
24192
|
const row = {
|
|
24027
|
-
...defined({
|
|
24193
|
+
...defined({
|
|
24194
|
+
...metadata(raw, model),
|
|
24195
|
+
kind_value: kindValue === void 0 ? void 0 : await encrypt(kindValue)
|
|
24196
|
+
}),
|
|
24028
24197
|
memory_id: raw.id,
|
|
24029
|
-
content,
|
|
24198
|
+
content: await encrypt(plaintext ?? ""),
|
|
24030
24199
|
scope: raw.scope,
|
|
24031
24200
|
created_at: raw.created_at,
|
|
24032
24201
|
updated_at: updatedAt,
|
|
24033
|
-
is_deleted:
|
|
24202
|
+
is_deleted: deleted
|
|
24034
24203
|
};
|
|
24035
|
-
return
|
|
24204
|
+
return { row, plaintext };
|
|
24205
|
+
}
|
|
24206
|
+
async function embedMissing(prepared, options, model, signal) {
|
|
24207
|
+
const needed = prepared.filter((p) => !p.row.embedding && p.plaintext);
|
|
24208
|
+
for (const batch of chunks(needed, EMBED_BATCH)) {
|
|
24209
|
+
if (signal?.aborted) throw aborted(signal);
|
|
24210
|
+
try {
|
|
24211
|
+
const vectors = await generateEmbeddings(
|
|
24212
|
+
batch.map((p) => p.plaintext),
|
|
24213
|
+
{ ...options, taskType: "memory_retain_embed" }
|
|
24214
|
+
);
|
|
24215
|
+
if (vectors.length !== batch.length) throw new Error("Incomplete migration embeddings");
|
|
24216
|
+
const stored2 = vectors.map(storedVector);
|
|
24217
|
+
batch.forEach((p, i) => {
|
|
24218
|
+
p.row.embedding = stored2[i];
|
|
24219
|
+
p.row.embedding_model = model;
|
|
24220
|
+
});
|
|
24221
|
+
} catch (error) {
|
|
24222
|
+
getLogger().warn(
|
|
24223
|
+
`[memory/migration] Uploading ${batch.length} row(s) without a vector: embedding failed`,
|
|
24224
|
+
error
|
|
24225
|
+
);
|
|
24226
|
+
}
|
|
24227
|
+
}
|
|
24036
24228
|
}
|
|
24037
|
-
function sameMetadata(local, remote) {
|
|
24038
|
-
const mine = metadata(local);
|
|
24229
|
+
function sameMetadata(local, remote, model) {
|
|
24230
|
+
const mine = metadata(local, model);
|
|
24039
24231
|
return METADATA_FIELDS.every((field10) => {
|
|
24040
24232
|
const a = mine[field10] ?? null;
|
|
24041
24233
|
const b = remote[field10] ?? null;
|
|
24234
|
+
if (field10 === "embedding_model" && a === null) return true;
|
|
24042
24235
|
if (field10 === "visibility") return (a ?? "private") === (b ?? "private");
|
|
24043
24236
|
if (field10 === "is_deleted" || field10 === "topics_user_managed" || field10 === "twin_opt_in")
|
|
24044
24237
|
return (a ?? false) === (b ?? false);
|
|
@@ -24134,7 +24327,8 @@ async function backfillTopics(ctx) {
|
|
|
24134
24327
|
}
|
|
24135
24328
|
async function migrateMemoriesToRemote(options) {
|
|
24136
24329
|
const { canonical, signal } = options;
|
|
24137
|
-
const
|
|
24330
|
+
const rings = [canonical, ...options.fallbacks ?? []];
|
|
24331
|
+
const model = options.embeddingOptions?.model ?? DEFAULT_API_EMBEDDING_MODEL;
|
|
24138
24332
|
const request = createNearbyRequest(options);
|
|
24139
24333
|
const account = await request("/account", {}, signal);
|
|
24140
24334
|
if (typeof account.key_id === "string" && account.key_id !== canonical.keyId)
|
|
@@ -24145,8 +24339,13 @@ async function migrateMemoriesToRemote(options) {
|
|
|
24145
24339
|
);
|
|
24146
24340
|
const active = account.state === "active";
|
|
24147
24341
|
let claimed = account.key_id === canonical.keyId;
|
|
24342
|
+
if (!active) await createDecaySweeper({ vaultCtx: options.vaultCtx }).runSweep();
|
|
24148
24343
|
await backfillTopics(options.vaultCtx);
|
|
24149
24344
|
const skipped = /* @__PURE__ */ new Map();
|
|
24345
|
+
const reembedded = /* @__PURE__ */ new Set();
|
|
24346
|
+
const unembedded = /* @__PURE__ */ new Set();
|
|
24347
|
+
const placeholders = /* @__PURE__ */ new Set();
|
|
24348
|
+
const truncated = /* @__PURE__ */ new Set();
|
|
24150
24349
|
let imported = 0;
|
|
24151
24350
|
for (let pass = 0; ; pass++) {
|
|
24152
24351
|
const rows = await getAllVaultMemoryRowsOp(options.vaultCtx);
|
|
@@ -24162,9 +24361,10 @@ async function migrateMemoriesToRemote(options) {
|
|
|
24162
24361
|
candidates.map((raw) => raw.id),
|
|
24163
24362
|
signal
|
|
24164
24363
|
);
|
|
24364
|
+
const needsVector = (raw, server) => !!options.embeddingOptions && !embedding(raw, model) && server.embedding_model !== model;
|
|
24165
24365
|
for (const raw of candidates) {
|
|
24166
24366
|
const server = remote.get(raw.id);
|
|
24167
|
-
if (server && server.updated_at === raw.updated_at && !sameMetadata(raw, server))
|
|
24367
|
+
if (server && server.updated_at === raw.updated_at && (!sameMetadata(raw, server, model) || needsVector(raw, server)))
|
|
24168
24368
|
pending.set(raw.id, raw.updated_at + 1);
|
|
24169
24369
|
}
|
|
24170
24370
|
}
|
|
@@ -24173,7 +24373,11 @@ async function migrateMemoriesToRemote(options) {
|
|
|
24173
24373
|
state,
|
|
24174
24374
|
total: rows.length,
|
|
24175
24375
|
imported,
|
|
24176
|
-
skipped: [...skipped].map(([memoryId, reason]) => ({ memoryId, reason }))
|
|
24376
|
+
skipped: [...skipped].map(([memoryId, reason]) => ({ memoryId, reason })),
|
|
24377
|
+
reembedded: reembedded.size,
|
|
24378
|
+
unembedded: unembedded.size,
|
|
24379
|
+
placeholderTombstones: placeholders.size,
|
|
24380
|
+
truncatedSourceChunkIds: truncated.size
|
|
24177
24381
|
});
|
|
24178
24382
|
if (skipped.size > 0 && !options.allowSkipped) return result("migrating");
|
|
24179
24383
|
if (!claimed) await importBatch(request, canonical.keyId, [], signal);
|
|
@@ -24191,19 +24395,35 @@ async function migrateMemoriesToRemote(options) {
|
|
|
24191
24395
|
409,
|
|
24192
24396
|
"migration_incomplete"
|
|
24193
24397
|
);
|
|
24194
|
-
const
|
|
24398
|
+
const prepared = [];
|
|
24195
24399
|
for (const raw of candidates) {
|
|
24196
24400
|
const updatedAt = pending.get(raw.id);
|
|
24197
24401
|
if (updatedAt === void 0) continue;
|
|
24198
24402
|
try {
|
|
24199
|
-
|
|
24200
|
-
if (row) upload.push(row);
|
|
24201
|
-
else skipped.set(raw.id, "invalid");
|
|
24403
|
+
prepared.push(await prepareRow(raw, canonical, rings, model, updatedAt));
|
|
24202
24404
|
} catch (error) {
|
|
24203
24405
|
if (!(error instanceof MemoryKeyError)) throw error;
|
|
24204
24406
|
skipped.set(raw.id, "unreadable");
|
|
24205
24407
|
}
|
|
24206
24408
|
}
|
|
24409
|
+
const usable = new Set(prepared.filter((p) => p.row.embedding).map((p) => p.row.memory_id));
|
|
24410
|
+
if (options.embeddingOptions)
|
|
24411
|
+
await embedMissing(prepared, options.embeddingOptions, model, signal);
|
|
24412
|
+
const local = new Map(candidates.map((raw) => [raw.id, raw]));
|
|
24413
|
+
const upload = [];
|
|
24414
|
+
for (const { row, plaintext } of prepared) {
|
|
24415
|
+
const id = row.memory_id;
|
|
24416
|
+
if (!fitsNearby(row)) {
|
|
24417
|
+
skipped.set(id, "invalid");
|
|
24418
|
+
continue;
|
|
24419
|
+
}
|
|
24420
|
+
upload.push(row);
|
|
24421
|
+
const track = (set, on) => on ? set.add(id) : set.delete(id);
|
|
24422
|
+
track(reembedded, !!row.embedding && !usable.has(id));
|
|
24423
|
+
track(unembedded, !row.embedding);
|
|
24424
|
+
track(placeholders, plaintext === void 0);
|
|
24425
|
+
track(truncated, row.source_chunk_ids !== text13(local.get(id).source_chunk_ids));
|
|
24426
|
+
}
|
|
24207
24427
|
let sent = 0;
|
|
24208
24428
|
options.onProgress?.({ imported: sent, toImport: upload.length });
|
|
24209
24429
|
for (const batch of chunks(upload, IMPORT_BATCH)) {
|
|
@@ -24448,16 +24668,21 @@ function createRemoteMemoryStore(options) {
|
|
|
24448
24668
|
const record2 = await persistence.get(id);
|
|
24449
24669
|
return record2 && !record2.memory.is_deleted ? record2 : null;
|
|
24450
24670
|
};
|
|
24451
|
-
const mutateLocked = async (id, change, edit) => {
|
|
24452
|
-
|
|
24671
|
+
const mutateLocked = async (id, change, edit, writeOptions) => {
|
|
24672
|
+
writeOptions?.signal?.throwIfAborted();
|
|
24673
|
+
const record2 = writeOptions?.signal ? await persistence.get(id, writeOptions.signal) : await live(id);
|
|
24453
24674
|
if (!record2) return null;
|
|
24675
|
+
if (record2.memory.is_deleted) return null;
|
|
24676
|
+
if (writeOptions?.canWrite && !await writeOptions.canWrite())
|
|
24677
|
+
throw new Error("Memory source is no longer eligible");
|
|
24678
|
+
writeOptions?.signal?.throwIfAborted();
|
|
24454
24679
|
const next = edit(structuredClone(record2.memory));
|
|
24455
24680
|
if (!next) return null;
|
|
24456
|
-
const saved = await persistence.put(next, record2);
|
|
24681
|
+
const saved = writeOptions?.signal ? await persistence.put(next, record2, writeOptions.signal) : await persistence.put(next, record2);
|
|
24457
24682
|
notify(typeof change === "function" ? change(record2.memory) : change, [saved]);
|
|
24458
24683
|
return saved;
|
|
24459
24684
|
};
|
|
24460
|
-
const mutate = (id, change, edit) => serialized(id, () => mutateLocked(id, change, edit));
|
|
24685
|
+
const mutate = (id, change, edit, writeOptions) => serialized(id, () => mutateLocked(id, change, edit, writeOptions));
|
|
24461
24686
|
const serializedAll = (ids, task) => [...new Set(ids)].sort().reduceRight((inner, id) => () => serialized(id, inner), task)();
|
|
24462
24687
|
const mutateMany = async (ids, change, edit) => {
|
|
24463
24688
|
const saved = /* @__PURE__ */ new Map();
|
|
@@ -24970,13 +25195,21 @@ function createRemoteMemoryStore(options) {
|
|
|
24970
25195
|
}))
|
|
24971
25196
|
);
|
|
24972
25197
|
},
|
|
24973
|
-
addTopics: async (memoryId, topics) => {
|
|
25198
|
+
addTopics: async (memoryId, topics, writeOptions) => {
|
|
24974
25199
|
const added = await withKnownKinds(topicInputs(topics, "auto"));
|
|
24975
|
-
const saved = await mutate(
|
|
24976
|
-
|
|
24977
|
-
|
|
24978
|
-
|
|
24979
|
-
|
|
25200
|
+
const saved = await mutate(
|
|
25201
|
+
memoryId,
|
|
25202
|
+
"edit",
|
|
25203
|
+
(memory) => {
|
|
25204
|
+
if (writeOptions?.unlessUserManaged && memory.topics_user_managed) return null;
|
|
25205
|
+
return {
|
|
25206
|
+
...memory,
|
|
25207
|
+
topics: serializeTopics(mergeTopics(parseTopics(memory.topics) ?? [], added)),
|
|
25208
|
+
topics_updated_at: Date.now()
|
|
25209
|
+
};
|
|
25210
|
+
},
|
|
25211
|
+
writeOptions
|
|
25212
|
+
);
|
|
24980
25213
|
if (!saved) return [];
|
|
24981
25214
|
const now = /* @__PURE__ */ new Date();
|
|
24982
25215
|
return mergeTopics([], added).map(
|
|
@@ -25829,6 +26062,7 @@ function createDurableAutoExtractor(options) {
|
|
|
25829
26062
|
};
|
|
25830
26063
|
const folderId = options.folderId ?? null;
|
|
25831
26064
|
let disposed = false;
|
|
26065
|
+
let activeBatch = null;
|
|
25832
26066
|
let running = false;
|
|
25833
26067
|
let wakeRequested = false;
|
|
25834
26068
|
let timer;
|
|
@@ -25865,14 +26099,18 @@ function createDurableAutoExtractor(options) {
|
|
|
25865
26099
|
}, delay);
|
|
25866
26100
|
}
|
|
25867
26101
|
async function extractBatch(messages, conversationId, ids, jobScope, jobFolderId) {
|
|
26102
|
+
if (disposed) throw new Error("Extraction session was disposed");
|
|
25868
26103
|
let watchdog;
|
|
25869
26104
|
let cancelled = false;
|
|
26105
|
+
const controller = new AbortController();
|
|
26106
|
+
activeBatch = controller;
|
|
25870
26107
|
const model = options.modelForScope?.(jobScope) ?? options.extract.model;
|
|
25871
26108
|
try {
|
|
25872
26109
|
return await Promise.race([
|
|
25873
26110
|
new Promise((resolve, reject) => {
|
|
25874
26111
|
const worker = createAutoExtractor({
|
|
25875
26112
|
...options,
|
|
26113
|
+
signal: controller.signal,
|
|
25876
26114
|
retainCtx: {
|
|
25877
26115
|
...options.retainCtx,
|
|
25878
26116
|
vaultCtx: {
|
|
@@ -25901,6 +26139,8 @@ function createDurableAutoExtractor(options) {
|
|
|
25901
26139
|
]);
|
|
25902
26140
|
} finally {
|
|
25903
26141
|
cancelled = true;
|
|
26142
|
+
controller.abort();
|
|
26143
|
+
if (activeBatch === controller) activeBatch = null;
|
|
25904
26144
|
if (watchdog !== void 0) clearTimeout(watchdog);
|
|
25905
26145
|
}
|
|
25906
26146
|
}
|
|
@@ -25912,6 +26152,7 @@ function createDurableAutoExtractor(options) {
|
|
|
25912
26152
|
for (const message of loaded)
|
|
25913
26153
|
if (message && message.messageId > 0) sequences.set(message.uniqueId, message.messageId);
|
|
25914
26154
|
await database.write(async () => {
|
|
26155
|
+
if (disposed) return;
|
|
25915
26156
|
const current = idsOf(job);
|
|
25916
26157
|
const acknowledged = ids.filter((id) => current.includes(id));
|
|
25917
26158
|
if (!acknowledged.length) return;
|
|
@@ -26084,6 +26325,7 @@ function createDurableAutoExtractor(options) {
|
|
|
26084
26325
|
jobScope,
|
|
26085
26326
|
jobFolderId
|
|
26086
26327
|
);
|
|
26328
|
+
if (disposed) throw new Error("Extraction session was disposed");
|
|
26087
26329
|
options.onTurnComplete?.(result);
|
|
26088
26330
|
return result;
|
|
26089
26331
|
};
|
|
@@ -26120,6 +26362,7 @@ function createDurableAutoExtractor(options) {
|
|
|
26120
26362
|
);
|
|
26121
26363
|
scheduleAfterSuccess = true;
|
|
26122
26364
|
} catch (error) {
|
|
26365
|
+
if (disposed) break;
|
|
26123
26366
|
attempts.set(job.id, attempted + 1);
|
|
26124
26367
|
retry = true;
|
|
26125
26368
|
reportError(error, conversationId);
|
|
@@ -26142,6 +26385,14 @@ function createDurableAutoExtractor(options) {
|
|
|
26142
26385
|
schedule(retry ? options.retryDelayMs ?? 3e4 : 0);
|
|
26143
26386
|
}
|
|
26144
26387
|
}
|
|
26388
|
+
function dispose() {
|
|
26389
|
+
disposed = true;
|
|
26390
|
+
activeBatch?.abort(options.signal?.reason);
|
|
26391
|
+
if (timer !== void 0) clearTimeout(timer);
|
|
26392
|
+
options.signal?.removeEventListener("abort", dispose);
|
|
26393
|
+
}
|
|
26394
|
+
if (options.signal?.aborted) dispose();
|
|
26395
|
+
else options.signal?.addEventListener("abort", dispose, { once: true });
|
|
26145
26396
|
schedule(0);
|
|
26146
26397
|
return {
|
|
26147
26398
|
processTurn(messages, conversationId) {
|
|
@@ -26221,10 +26472,7 @@ function createDurableAutoExtractor(options) {
|
|
|
26221
26472
|
return true;
|
|
26222
26473
|
},
|
|
26223
26474
|
isProcessing: () => running,
|
|
26224
|
-
dispose
|
|
26225
|
-
disposed = true;
|
|
26226
|
-
if (timer !== void 0) clearTimeout(timer);
|
|
26227
|
-
}
|
|
26475
|
+
dispose
|
|
26228
26476
|
};
|
|
26229
26477
|
}
|
|
26230
26478
|
|
|
@@ -32495,6 +32743,7 @@ var CONVERSATION_REDACTOR_LIMIT = 50;
|
|
|
32495
32743
|
var NO_CONVERSATION_KEY = "__no_conversation__";
|
|
32496
32744
|
var NO_STORE_FOLDERS = "Folders are not supported with a memoryStore";
|
|
32497
32745
|
var NO_STORE_MASK = "piiRedaction needs a memoryStore built with embeddingOptions.maskInput";
|
|
32746
|
+
var MEMORY_STORE_NOT_READY = "Memory store is not ready";
|
|
32498
32747
|
var conversationRedactors = /* @__PURE__ */ new Map();
|
|
32499
32748
|
function getConversationRedactor(conversationId, nerDetector) {
|
|
32500
32749
|
const key = conversationId ?? NO_CONVERSATION_KEY;
|
|
@@ -32585,7 +32834,7 @@ function useChatStorage(options) {
|
|
|
32585
32834
|
() => ({ getToken, baseUrl, model: embeddingModel, maskInput: maskEmbeddingInput }),
|
|
32586
32835
|
[getToken, baseUrl, embeddingModel, maskEmbeddingInput]
|
|
32587
32836
|
);
|
|
32588
|
-
const storeMaskMissing = memoryStore !== void 0 && maskEmbeddingInput !== void 0 && !memoryStore.masksEmbeddingInput;
|
|
32837
|
+
const storeMaskMissing = memoryStore !== void 0 && memoryStore !== null && maskEmbeddingInput !== void 0 && !memoryStore.masksEmbeddingInput;
|
|
32589
32838
|
const blobManagerRef = (0, import_react6.useRef)(new BlobUrlManager());
|
|
32590
32839
|
(0, import_react6.useEffect)(() => {
|
|
32591
32840
|
const manager = blobManagerRef.current;
|
|
@@ -32862,6 +33111,7 @@ function useChatStorage(options) {
|
|
|
32862
33111
|
);
|
|
32863
33112
|
const retainVaultMemory = (0, import_react6.useCallback)(
|
|
32864
33113
|
async (input) => {
|
|
33114
|
+
if (memoryStore === null) throw new Error(MEMORY_STORE_NOT_READY);
|
|
32865
33115
|
if (memoryStore) {
|
|
32866
33116
|
if (storeMaskMissing) throw new Error(NO_STORE_MASK);
|
|
32867
33117
|
if (input.folderId !== void 0) throw new Error(NO_STORE_FOLDERS);
|
|
@@ -32893,6 +33143,7 @@ function useChatStorage(options) {
|
|
|
32893
33143
|
);
|
|
32894
33144
|
const createMemoryVaultTool2 = (0, import_react6.useCallback)(
|
|
32895
33145
|
(options2) => {
|
|
33146
|
+
if (memoryStore === null) throw new Error(MEMORY_STORE_NOT_READY);
|
|
32896
33147
|
if (storeMaskMissing) throw new Error(NO_STORE_MASK);
|
|
32897
33148
|
const embOpts = getToken ? vaultEmbeddingOptions : void 0;
|
|
32898
33149
|
return createMemoryVaultTool(
|
|
@@ -32914,6 +33165,7 @@ function useChatStorage(options) {
|
|
|
32914
33165
|
);
|
|
32915
33166
|
const getVaultMemories = (0, import_react6.useCallback)(
|
|
32916
33167
|
(options2) => {
|
|
33168
|
+
if (memoryStore === null) return Promise.resolve([]);
|
|
32917
33169
|
if (!memoryStore) return getAllVaultMemoriesOp(vaultCtx, options2);
|
|
32918
33170
|
const { folderId, levels, kinds, ...listOptions } = options2 ?? {};
|
|
32919
33171
|
if (folderId !== void 0) throw new Error(NO_STORE_FOLDERS);
|
|
@@ -32925,6 +33177,7 @@ function useChatStorage(options) {
|
|
|
32925
33177
|
);
|
|
32926
33178
|
const createVaultMemory = (0, import_react6.useCallback)(
|
|
32927
33179
|
async (content, scope) => {
|
|
33180
|
+
if (memoryStore === null) throw new Error(MEMORY_STORE_NOT_READY);
|
|
32928
33181
|
if (storeMaskMissing) throw new Error(NO_STORE_MASK);
|
|
32929
33182
|
if (memoryStore) return memoryStore.create({ content, scope });
|
|
32930
33183
|
const result = await createVaultMemoryOp(vaultCtx, { content, scope });
|
|
@@ -32946,6 +33199,7 @@ function useChatStorage(options) {
|
|
|
32946
33199
|
);
|
|
32947
33200
|
const updateVaultMemory = (0, import_react6.useCallback)(
|
|
32948
33201
|
async (id, content, scope) => {
|
|
33202
|
+
if (memoryStore === null) throw new Error(MEMORY_STORE_NOT_READY);
|
|
32949
33203
|
if (storeMaskMissing) throw new Error(NO_STORE_MASK);
|
|
32950
33204
|
if (memoryStore) return memoryStore.update(id, { content, scope });
|
|
32951
33205
|
const existing = await getVaultMemoryOp(vaultCtx, id);
|
|
@@ -32971,6 +33225,7 @@ function useChatStorage(options) {
|
|
|
32971
33225
|
);
|
|
32972
33226
|
const deleteVaultMemory = (0, import_react6.useCallback)(
|
|
32973
33227
|
async (id) => {
|
|
33228
|
+
if (memoryStore === null) throw new Error(MEMORY_STORE_NOT_READY);
|
|
32974
33229
|
if (memoryStore) return memoryStore.delete(id);
|
|
32975
33230
|
const existing = await getVaultMemoryOp(vaultCtx, id);
|
|
32976
33231
|
const result = await deleteVaultMemoryOp(vaultCtx, id);
|
|
@@ -32984,7 +33239,7 @@ function useChatStorage(options) {
|
|
|
32984
33239
|
const chunkVectorCacheRef = (0, import_react6.useRef)(createChunkVectorCache());
|
|
32985
33240
|
const clientToolEmbeddingsCacheRef = (0, import_react6.useRef)(/* @__PURE__ */ new Map());
|
|
32986
33241
|
(0, import_react6.useEffect)(() => {
|
|
32987
|
-
if (!getToken || memoryStore) return;
|
|
33242
|
+
if (!getToken || memoryStore !== void 0) return;
|
|
32988
33243
|
void (async () => {
|
|
32989
33244
|
try {
|
|
32990
33245
|
await preEmbedVaultMemories(vaultCtx, vaultEmbeddingOptions, vaultEmbeddingCache);
|
|
@@ -33000,6 +33255,7 @@ function useChatStorage(options) {
|
|
|
33000
33255
|
}, [vaultEmbeddingCache]);
|
|
33001
33256
|
const createMemoryVaultSearchTool2 = (0, import_react6.useCallback)(
|
|
33002
33257
|
(searchOptions) => {
|
|
33258
|
+
if (memoryStore === null) throw new Error(MEMORY_STORE_NOT_READY);
|
|
33003
33259
|
if (!getToken && !memoryStore) {
|
|
33004
33260
|
throw new Error("getToken is required for memory vault search tool");
|
|
33005
33261
|
}
|
|
@@ -33015,6 +33271,7 @@ function useChatStorage(options) {
|
|
|
33015
33271
|
);
|
|
33016
33272
|
const createRecallTool2 = (0, import_react6.useCallback)(
|
|
33017
33273
|
(toolOptions, callbacks) => {
|
|
33274
|
+
if (memoryStore === null) throw new Error(MEMORY_STORE_NOT_READY);
|
|
33018
33275
|
if (!getToken && !memoryStore) {
|
|
33019
33276
|
throw new Error("getToken is required for recall tool");
|
|
33020
33277
|
}
|
|
@@ -33054,6 +33311,7 @@ function useChatStorage(options) {
|
|
|
33054
33311
|
);
|
|
33055
33312
|
const searchVaultMemoriesFn = (0, import_react6.useCallback)(
|
|
33056
33313
|
async (query, searchOptions) => {
|
|
33314
|
+
if (memoryStore === null) return [];
|
|
33057
33315
|
if (storeMaskMissing) throw new Error(NO_STORE_MASK);
|
|
33058
33316
|
if (memoryStore) return (await memoryStore.factSource.search(query, searchOptions)).results;
|
|
33059
33317
|
if (!getToken) return [];
|
|
@@ -33069,7 +33327,7 @@ function useChatStorage(options) {
|
|
|
33069
33327
|
);
|
|
33070
33328
|
const recallFn = (0, import_react6.useCallback)(
|
|
33071
33329
|
async (query, options2) => {
|
|
33072
|
-
if (!getToken && !memoryStore) {
|
|
33330
|
+
if (memoryStore === null || !getToken && !memoryStore) {
|
|
33073
33331
|
return {
|
|
33074
33332
|
memories: [],
|
|
33075
33333
|
usedBudget: options2?.budget ?? "low",
|