@anuma/sdk 7.0.3 → 7.0.4-next.20261015012621
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 +388 -130
- package/dist/expo/index.d.mts +25 -12
- package/dist/expo/index.d.ts +25 -12
- package/dist/expo/index.mjs +386 -130
- package/dist/index.cjs +29 -7
- package/dist/index.mjs +29 -7
- package/dist/memory/context.d.mts +1 -0
- package/dist/memory/context.d.ts +1 -0
- package/dist/react/index.cjs +393 -130
- package/dist/react/index.d.mts +25 -12
- package/dist/react/index.d.ts +25 -12
- package/dist/react/index.mjs +391 -130
- package/dist/server/index.cjs +321 -80
- package/dist/server/index.d.mts +27 -4
- package/dist/server/index.d.ts +27 -4
- package/dist/server/index.mjs +319 -80
- package/dist/tools/selection/index.cjs +29 -7
- package/dist/tools/selection/index.mjs +29 -7
- package/package.json +2 -2
package/dist/react/index.cjs
CHANGED
|
@@ -4456,8 +4456,9 @@ async function getConversationsByProjectOp(ctx, projectId) {
|
|
|
4456
4456
|
)
|
|
4457
4457
|
);
|
|
4458
4458
|
}
|
|
4459
|
-
async function getMessagesOp(ctx, convId) {
|
|
4460
|
-
const
|
|
4459
|
+
async function getMessagesOp(ctx, convId, opts) {
|
|
4460
|
+
const fetched = await ctx.messagesCollection.query(import_watermelondb2.Q.where("conversation_id", convId), import_watermelondb2.Q.sortBy("message_id", import_watermelondb2.Q.asc)).unsafeFetchRaw();
|
|
4461
|
+
const results = opts?.rawFilter ? fetched.filter(opts.rawFilter) : fetched;
|
|
4461
4462
|
return Promise.all(
|
|
4462
4463
|
results.map(
|
|
4463
4464
|
(raw) => messageRawToStored(raw, ctx.walletAddress, ctx.signMessage, ctx.embeddedWalletSigner)
|
|
@@ -6318,6 +6319,24 @@ var deleteApiV1WalletsBindingByAddress = (options) => (options.client ?? client)
|
|
|
6318
6319
|
// src/lib/memoryEngine/generate.ts
|
|
6319
6320
|
init_clientConfig();
|
|
6320
6321
|
init_taskType();
|
|
6322
|
+
|
|
6323
|
+
// src/lib/memoryEngine/embeddingCacheState.ts
|
|
6324
|
+
var EMBEDDING_CACHE_STATE_KEY = /* @__PURE__ */ Symbol.for("@anuma/sdk/embedding-cache/v1");
|
|
6325
|
+
var cacheGlobal = globalThis;
|
|
6326
|
+
var fallbackState = {
|
|
6327
|
+
scopedViews: /* @__PURE__ */ new WeakMap(),
|
|
6328
|
+
inFlightByCache: /* @__PURE__ */ new WeakMap(),
|
|
6329
|
+
cachedEmbeddingModels: /* @__PURE__ */ new WeakMap()
|
|
6330
|
+
};
|
|
6331
|
+
function getEmbeddingCacheState() {
|
|
6332
|
+
try {
|
|
6333
|
+
return cacheGlobal[EMBEDDING_CACHE_STATE_KEY] ?? (cacheGlobal[EMBEDDING_CACHE_STATE_KEY] = fallbackState);
|
|
6334
|
+
} catch {
|
|
6335
|
+
return fallbackState;
|
|
6336
|
+
}
|
|
6337
|
+
}
|
|
6338
|
+
|
|
6339
|
+
// src/lib/memoryEngine/generate.ts
|
|
6321
6340
|
var EMBED_MAX_ATTEMPTS = 4;
|
|
6322
6341
|
var DEFAULT_EMBEDDING_REQUEST_TIMEOUT_MS = 15e3;
|
|
6323
6342
|
var DEFAULT_EMBEDDING_TOKEN_TIMEOUT_MS = 1e4;
|
|
@@ -6408,15 +6427,18 @@ async function generateEmbedding(text14, options) {
|
|
|
6408
6427
|
if (total === void 0) return embedOne(text14, options, void 0);
|
|
6409
6428
|
return withDeadline((signal) => embedOne(text14, options, signal), total, "embedding");
|
|
6410
6429
|
}
|
|
6411
|
-
var inFlightByCache
|
|
6430
|
+
var { inFlightByCache, cachedEmbeddingModels } = getEmbeddingCacheState();
|
|
6412
6431
|
async function embedOne(text14, options, outer) {
|
|
6413
6432
|
const { cache } = options;
|
|
6414
6433
|
if (!cache) return Array.from(await requestEmbedding(text14, options, outer));
|
|
6434
|
+
const model = options.model ?? DEFAULT_API_EMBEDDING_MODEL;
|
|
6415
6435
|
const cached = cache.get(text14);
|
|
6416
|
-
|
|
6436
|
+
const cachedModel = cached && cachedEmbeddingModels.get(cached);
|
|
6437
|
+
if (cached && (cachedModel === void 0 || cachedModel === model)) return Array.from(cached);
|
|
6417
6438
|
const inFlight = inFlightByCache.get(cache) ?? /* @__PURE__ */ new Map();
|
|
6418
6439
|
inFlightByCache.set(cache, inFlight);
|
|
6419
|
-
const
|
|
6440
|
+
const requestKey = JSON.stringify([model, text14]);
|
|
6441
|
+
const pending = inFlight.get(requestKey);
|
|
6420
6442
|
if (pending) {
|
|
6421
6443
|
try {
|
|
6422
6444
|
return Array.from(await pending);
|
|
@@ -6425,13 +6447,14 @@ async function embedOne(text14, options, outer) {
|
|
|
6425
6447
|
}
|
|
6426
6448
|
}
|
|
6427
6449
|
const request = requestEmbedding(text14, options, outer);
|
|
6428
|
-
inFlight.set(
|
|
6450
|
+
inFlight.set(requestKey, request);
|
|
6429
6451
|
try {
|
|
6430
6452
|
const embedding2 = await request;
|
|
6453
|
+
cachedEmbeddingModels.set(embedding2, model);
|
|
6431
6454
|
cache.set(text14, embedding2);
|
|
6432
6455
|
return Array.from(embedding2);
|
|
6433
6456
|
} finally {
|
|
6434
|
-
if (inFlight.get(
|
|
6457
|
+
if (inFlight.get(requestKey) === request) inFlight.delete(requestKey);
|
|
6435
6458
|
}
|
|
6436
6459
|
}
|
|
6437
6460
|
async function requestEmbedding(text14, options, outer) {
|
|
@@ -6514,13 +6537,15 @@ async function embedMany(texts, options, outer) {
|
|
|
6514
6537
|
const { baseUrl = BASE_URL, model, batchSize, cache } = options;
|
|
6515
6538
|
const timeoutMs = options.timeoutMs ?? DEFAULT_EMBEDDING_REQUEST_TIMEOUT_MS;
|
|
6516
6539
|
const chunkSize = batchSize ?? DEFAULT_EMBEDDING_BATCH_SIZE;
|
|
6540
|
+
const embeddingModel = model ?? DEFAULT_API_EMBEDDING_MODEL;
|
|
6517
6541
|
const results = new Array(texts.length).fill(null);
|
|
6518
6542
|
const uncachedIndices = [];
|
|
6519
6543
|
const uncachedTexts = [];
|
|
6520
6544
|
for (let i = 0; i < texts.length; i++) {
|
|
6521
6545
|
if (cache) {
|
|
6522
6546
|
const cached = cache.get(texts[i]);
|
|
6523
|
-
|
|
6547
|
+
const cachedModel = cached && cachedEmbeddingModels.get(cached);
|
|
6548
|
+
if (cached && (cachedModel === void 0 || cachedModel === embeddingModel)) {
|
|
6524
6549
|
results[i] = Array.from(cached);
|
|
6525
6550
|
continue;
|
|
6526
6551
|
}
|
|
@@ -6536,7 +6561,6 @@ async function embedMany(texts, options, outer) {
|
|
|
6536
6561
|
...taskTypeHeader(options.taskType)
|
|
6537
6562
|
};
|
|
6538
6563
|
if (outer?.aborted) throw outer.reason;
|
|
6539
|
-
const embeddingModel = model ?? DEFAULT_API_EMBEDDING_MODEL;
|
|
6540
6564
|
let newEmbeddings;
|
|
6541
6565
|
if (uncachedTexts.length <= chunkSize) {
|
|
6542
6566
|
newEmbeddings = await generateEmbeddingsBatch(
|
|
@@ -6584,6 +6608,7 @@ async function embedMany(texts, options, outer) {
|
|
|
6584
6608
|
const f32Embedding = Float32Array.from(newEmbeddings[i]);
|
|
6585
6609
|
results[uncachedIndices[i]] = Array.from(f32Embedding);
|
|
6586
6610
|
if (cache) {
|
|
6611
|
+
cachedEmbeddingModels.set(f32Embedding, embeddingModel);
|
|
6587
6612
|
cache.set(uncachedTexts[i], f32Embedding);
|
|
6588
6613
|
}
|
|
6589
6614
|
}
|
|
@@ -6708,6 +6733,37 @@ async function chunkAndEmbedMessage(ctx, messageId, options) {
|
|
|
6708
6733
|
}));
|
|
6709
6734
|
return updateMessageChunksOp(ctx, messageId, messageChunks, embeddingModel);
|
|
6710
6735
|
}
|
|
6736
|
+
var MIN_SEALED_EMBEDDING_HEX = 256;
|
|
6737
|
+
function rawHasEmbedding(value) {
|
|
6738
|
+
if (Array.isArray(value)) return value.length > 0;
|
|
6739
|
+
if (typeof value !== "string" || value.length === 0) return false;
|
|
6740
|
+
if (isEncrypted(value)) {
|
|
6741
|
+
return value.length - value.indexOf(":", 4) - 1 >= MIN_SEALED_EMBEDDING_HEX;
|
|
6742
|
+
}
|
|
6743
|
+
try {
|
|
6744
|
+
const parsed = JSON.parse(value);
|
|
6745
|
+
return Array.isArray(parsed) && parsed.length > 0;
|
|
6746
|
+
} catch {
|
|
6747
|
+
return false;
|
|
6748
|
+
}
|
|
6749
|
+
}
|
|
6750
|
+
function sealedVersion(value) {
|
|
6751
|
+
if (typeof value !== "string" || !isEncrypted(value)) return null;
|
|
6752
|
+
return value.startsWith("enc:v2:") ? "v2" : "v3";
|
|
6753
|
+
}
|
|
6754
|
+
function mayNeedChunkEmbedding(raw, embeddingModel, filter) {
|
|
6755
|
+
const role = raw.role;
|
|
6756
|
+
if (role === "system") return false;
|
|
6757
|
+
if (filter?.roles && !filter.roles.includes(role ?? "")) return false;
|
|
6758
|
+
if (isNonEmbeddableOrigin(raw.origin, filter?.reembedDiscarded)) {
|
|
6759
|
+
return false;
|
|
6760
|
+
}
|
|
6761
|
+
const model = raw.embedding_model;
|
|
6762
|
+
if (typeof model === "string" && model !== embeddingModel) return true;
|
|
6763
|
+
if (rawHasEmbedding(raw.chunks)) return false;
|
|
6764
|
+
if (rawHasEmbedding(raw.vector) && !filter?.rechunkExisting) return false;
|
|
6765
|
+
return true;
|
|
6766
|
+
}
|
|
6711
6767
|
async function chunkAndEmbedAllMessages(ctx, options, filter) {
|
|
6712
6768
|
const embeddingModel = options.model ?? DEFAULT_API_EMBEDDING_MODEL;
|
|
6713
6769
|
const { chunkSize = DEFAULT_CHUNK_SIZE } = options;
|
|
@@ -6720,11 +6776,31 @@ async function chunkAndEmbedAllMessages(ctx, options, filter) {
|
|
|
6720
6776
|
let considered = 0;
|
|
6721
6777
|
let sealedRowsSeen = 0;
|
|
6722
6778
|
let rowsSeen = 0;
|
|
6779
|
+
const keptSealed = /* @__PURE__ */ new Map();
|
|
6780
|
+
const candidatesStillSealed = /* @__PURE__ */ new Map();
|
|
6781
|
+
const droppedSealed = /* @__PURE__ */ new Map();
|
|
6782
|
+
const rawFilter = (raw) => {
|
|
6783
|
+
rowsSeen++;
|
|
6784
|
+
const keep = mayNeedChunkEmbedding(raw, embeddingModel, filter);
|
|
6785
|
+
const version = sealedVersion(raw.content);
|
|
6786
|
+
if (!version) return keep;
|
|
6787
|
+
if (keep) {
|
|
6788
|
+
keptSealed.set(version, (keptSealed.get(version) ?? 0) + 1);
|
|
6789
|
+
} else {
|
|
6790
|
+
const dropped = droppedSealed.get(version);
|
|
6791
|
+
if (dropped) dropped.count++;
|
|
6792
|
+
else droppedSealed.set(version, { count: 1, probeId: raw.id });
|
|
6793
|
+
}
|
|
6794
|
+
return keep;
|
|
6795
|
+
};
|
|
6723
6796
|
for (const conv of targetConversations) {
|
|
6724
|
-
const messages = await getMessagesOp(ctx, conv.conversationId);
|
|
6797
|
+
const messages = await getMessagesOp(ctx, conv.conversationId, { rawFilter });
|
|
6725
6798
|
for (const message of messages) {
|
|
6726
|
-
|
|
6727
|
-
if (
|
|
6799
|
+
const stillSealed = sealedVersion(message.content);
|
|
6800
|
+
if (stillSealed) {
|
|
6801
|
+
sealedRowsSeen++;
|
|
6802
|
+
candidatesStillSealed.set(stillSealed, (candidatesStillSealed.get(stillSealed) ?? 0) + 1);
|
|
6803
|
+
}
|
|
6728
6804
|
const isStale = message.embeddingModel !== void 0 && message.embeddingModel !== null && message.embeddingModel !== embeddingModel;
|
|
6729
6805
|
if (message.chunks && message.chunks.length > 0 && !isStale) continue;
|
|
6730
6806
|
const hasVector = message.vector && message.vector.length > 0;
|
|
@@ -6737,6 +6813,7 @@ async function chunkAndEmbedAllMessages(ctx, options, filter) {
|
|
|
6737
6813
|
stillEncrypted++;
|
|
6738
6814
|
continue;
|
|
6739
6815
|
}
|
|
6816
|
+
if (isToolResultsRow(message)) continue;
|
|
6740
6817
|
if (message.content.length < minLength) continue;
|
|
6741
6818
|
if (shouldChunkMessage(message.content, chunkSize)) {
|
|
6742
6819
|
longMessages.push({
|
|
@@ -6748,6 +6825,12 @@ async function chunkAndEmbedAllMessages(ctx, options, filter) {
|
|
|
6748
6825
|
}
|
|
6749
6826
|
}
|
|
6750
6827
|
}
|
|
6828
|
+
for (const [version, dropped] of droppedSealed) {
|
|
6829
|
+
const keyOpenedACandidate = (keptSealed.get(version) ?? 0) > (candidatesStillSealed.get(version) ?? 0);
|
|
6830
|
+
if (keyOpenedACandidate) continue;
|
|
6831
|
+
const probe = await getMessageOp(ctx, dropped.probeId);
|
|
6832
|
+
if (!probe || isEncrypted(probe.content)) sealedRowsSeen += dropped.count;
|
|
6833
|
+
}
|
|
6751
6834
|
if (stillEncrypted > 0 || sealedRowsSeen > 0) {
|
|
6752
6835
|
getLogger().error(
|
|
6753
6836
|
"memoryEngine: messages still encrypted (key unavailable?) \u2014 excluded from embedding",
|
|
@@ -12209,6 +12292,11 @@ function parseTopics(value) {
|
|
|
12209
12292
|
}
|
|
12210
12293
|
|
|
12211
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
|
+
}
|
|
12212
12300
|
function entityToStored(e) {
|
|
12213
12301
|
return {
|
|
12214
12302
|
uniqueId: e.id,
|
|
@@ -12349,6 +12437,7 @@ async function linkMemoryEntitiesOp(ctx, memoryId, entityInputs, options) {
|
|
|
12349
12437
|
let skipped = false;
|
|
12350
12438
|
let entities = [];
|
|
12351
12439
|
await ctx.database.write(async () => {
|
|
12440
|
+
await assertCanWrite(ctx);
|
|
12352
12441
|
const {
|
|
12353
12442
|
entities: byName,
|
|
12354
12443
|
operations: entityOps,
|
|
@@ -12424,6 +12513,7 @@ async function replaceMemoryEntities(ctx, memoryId, entityInputs, options) {
|
|
|
12424
12513
|
let skipped = false;
|
|
12425
12514
|
let entities = [];
|
|
12426
12515
|
await ctx.database.write(async () => {
|
|
12516
|
+
await assertCanWrite(ctx);
|
|
12427
12517
|
const vaultRow = await findVaultRowInWrite(ctx, memoryId);
|
|
12428
12518
|
if (options.guarded && autoLinkBlocked(vaultRow)) {
|
|
12429
12519
|
skipped = true;
|
|
@@ -12484,6 +12574,7 @@ async function unlinkMemoryEntitiesOp(ctx, memoryIds) {
|
|
|
12484
12574
|
const links = await ctx.memoryEntityCollection.query(import_watermelondb11.Q.where("memory_id", import_watermelondb11.Q.oneOf(Array.from(memoryIds)))).fetch();
|
|
12485
12575
|
if (links.length === 0) return;
|
|
12486
12576
|
await ctx.database.write(async () => {
|
|
12577
|
+
await assertCanWrite(ctx);
|
|
12487
12578
|
await ctx.database.batch(...links.map((l) => l.prepareDestroyPermanently()));
|
|
12488
12579
|
});
|
|
12489
12580
|
}
|
|
@@ -12492,6 +12583,7 @@ async function unlinkAllMemoryEntitiesForUserOp(ctx, userId) {
|
|
|
12492
12583
|
const links = await ctx.memoryEntityCollection.query(import_watermelondb11.Q.where("user_id", userId)).fetch();
|
|
12493
12584
|
if (links.length === 0) return;
|
|
12494
12585
|
await ctx.database.write(async () => {
|
|
12586
|
+
await assertCanWrite(ctx);
|
|
12495
12587
|
await ctx.database.batch(...links.map((l) => l.prepareDestroyPermanently()));
|
|
12496
12588
|
});
|
|
12497
12589
|
}
|
|
@@ -12511,6 +12603,7 @@ async function backfillMemoryEntityUserIdsOp(ctx, vaultMemoryCollection) {
|
|
|
12511
12603
|
}
|
|
12512
12604
|
if (toUpdate.length === 0) return 0;
|
|
12513
12605
|
await ctx.database.write(async () => {
|
|
12606
|
+
await assertCanWrite(ctx);
|
|
12514
12607
|
await ctx.database.batch(
|
|
12515
12608
|
...toUpdate.map(({ link, userId }) => link.prepareUpdate((r) => r._setRaw("user_id", userId)))
|
|
12516
12609
|
);
|
|
@@ -14904,6 +14997,11 @@ function visibilityConditions(requested) {
|
|
|
14904
14997
|
function isKinded(record2) {
|
|
14905
14998
|
return record2.kind !== null && record2.kind !== void 0;
|
|
14906
14999
|
}
|
|
15000
|
+
async function assertCanWrite2(ctx) {
|
|
15001
|
+
if (ctx.canWrite && !await ctx.canWrite()) {
|
|
15002
|
+
throw new Error("Memory source is no longer eligible");
|
|
15003
|
+
}
|
|
15004
|
+
}
|
|
14907
15005
|
function assertValidKindLevel(kind, level) {
|
|
14908
15006
|
const hasKind = kind !== null && kind !== void 0;
|
|
14909
15007
|
if (hasKind && !MEMORY_KINDS.includes(kind)) {
|
|
@@ -15084,8 +15182,7 @@ async function createVaultMemoryOp(ctx, opts) {
|
|
|
15084
15182
|
ctx.embeddedWalletSigner
|
|
15085
15183
|
) : opts.content;
|
|
15086
15184
|
const created = await ctx.database.write(async () => {
|
|
15087
|
-
|
|
15088
|
-
throw new Error("Memory source is no longer eligible");
|
|
15185
|
+
await assertCanWrite2(ctx);
|
|
15089
15186
|
return ctx.vaultMemoryCollection.create(
|
|
15090
15187
|
(record2) => populateNewVaultMemory(record2, ctx, opts, encryptedContent, encryptedKindValue)
|
|
15091
15188
|
);
|
|
@@ -15104,8 +15201,7 @@ async function createSupersedingMemoryOp(ctx, opts, targetId) {
|
|
|
15104
15201
|
) : opts.content;
|
|
15105
15202
|
let createdRecord = null;
|
|
15106
15203
|
await ctx.database.write(async () => {
|
|
15107
|
-
|
|
15108
|
-
throw new Error("Memory source is no longer eligible");
|
|
15204
|
+
await assertCanWrite2(ctx);
|
|
15109
15205
|
let target;
|
|
15110
15206
|
try {
|
|
15111
15207
|
target = await ctx.vaultMemoryCollection.find(targetId);
|
|
@@ -15197,8 +15293,7 @@ async function createVaultMemoriesBatchOp(ctx, optionsArray) {
|
|
|
15197
15293
|
})
|
|
15198
15294
|
);
|
|
15199
15295
|
const created = await ctx.database.write(async () => {
|
|
15200
|
-
|
|
15201
|
-
throw new Error("Memory source is no longer eligible");
|
|
15296
|
+
await assertCanWrite2(ctx);
|
|
15202
15297
|
const prepared = optionsArray.map(
|
|
15203
15298
|
(opts, i) => ctx.vaultMemoryCollection.prepareCreate(
|
|
15204
15299
|
(record2) => populateNewVaultMemory(record2, ctx, opts, encryptedContents[i], encryptedKindValues[i])
|
|
@@ -15503,8 +15598,7 @@ async function updateVaultMemoryOp(ctx, id, opts) {
|
|
|
15503
15598
|
const record2 = probe;
|
|
15504
15599
|
const originalUpdatedAt = record2.updatedAt.getTime();
|
|
15505
15600
|
await ctx.database.write(async () => {
|
|
15506
|
-
|
|
15507
|
-
throw new Error("Memory source is no longer eligible");
|
|
15601
|
+
await assertCanWrite2(ctx);
|
|
15508
15602
|
if (record2.isDeleted || record2.supersededBy || !isOwnedByCtxUser(ctx, record2) || opts.freeFormOnly && isKinded(record2)) {
|
|
15509
15603
|
stale = true;
|
|
15510
15604
|
return;
|
|
@@ -15615,6 +15709,7 @@ async function setMemoryEntitiesOp(ctx, memoryId, entities) {
|
|
|
15615
15709
|
let stale = false;
|
|
15616
15710
|
const originalUpdatedAt = record2.updatedAt.getTime();
|
|
15617
15711
|
await ctx.database.write(async (writer) => {
|
|
15712
|
+
await assertCanWrite2(ctx);
|
|
15618
15713
|
if (record2.isDeleted || !isOwnedByCtxUser(ctx, record2)) {
|
|
15619
15714
|
stale = true;
|
|
15620
15715
|
return;
|
|
@@ -15656,6 +15751,7 @@ async function clearMemoryTopicsOverrideOp(ctx, memoryId, options) {
|
|
|
15656
15751
|
const originalUpdatedAt = record2.updatedAt.getTime();
|
|
15657
15752
|
let cleared = false;
|
|
15658
15753
|
await ctx.database.write(async () => {
|
|
15754
|
+
await assertCanWrite2(ctx);
|
|
15659
15755
|
if (options?.unlessTopicsRecorded && parseTopics(record2.topics) !== null) return;
|
|
15660
15756
|
cleared = true;
|
|
15661
15757
|
await record2.update((r) => {
|
|
@@ -15679,6 +15775,7 @@ async function setMemoryVisibilityOp(ctx, id, opts) {
|
|
|
15679
15775
|
if (record2.isDeleted || !isOwnedByCtxUser(ctx, record2)) return null;
|
|
15680
15776
|
let stale = false;
|
|
15681
15777
|
await ctx.database.write(async () => {
|
|
15778
|
+
await assertCanWrite2(ctx);
|
|
15682
15779
|
if (record2.isDeleted || !isOwnedByCtxUser(ctx, record2)) {
|
|
15683
15780
|
stale = true;
|
|
15684
15781
|
return;
|
|
@@ -15707,6 +15804,7 @@ async function deleteVaultMemoryOp(ctx, id) {
|
|
|
15707
15804
|
if (record2.isDeleted || !isOwnedByCtxUser(ctx, record2)) return false;
|
|
15708
15805
|
let stale = false;
|
|
15709
15806
|
await ctx.database.write(async () => {
|
|
15807
|
+
await assertCanWrite2(ctx);
|
|
15710
15808
|
if (record2.isDeleted || !isOwnedByCtxUser(ctx, record2)) {
|
|
15711
15809
|
stale = true;
|
|
15712
15810
|
return;
|
|
@@ -15744,8 +15842,7 @@ async function supersedeVaultMemoryOp(ctx, id, supersededById) {
|
|
|
15744
15842
|
}
|
|
15745
15843
|
let stale = false;
|
|
15746
15844
|
await ctx.database.write(async () => {
|
|
15747
|
-
|
|
15748
|
-
throw new Error("Memory source is no longer eligible");
|
|
15845
|
+
await assertCanWrite2(ctx);
|
|
15749
15846
|
if (record2.isDeleted || record2.supersededBy || !isOwnedByCtxUser(ctx, record2)) {
|
|
15750
15847
|
stale = true;
|
|
15751
15848
|
return;
|
|
@@ -15907,6 +16004,7 @@ async function stampTopicsExtractedAtOp(ctx, memoryIds, extractedAt, version = T
|
|
|
15907
16004
|
for (let i = 0; i < uniqueIds.length; i += CHUNK) {
|
|
15908
16005
|
const chunkIds = uniqueIds.slice(i, i + CHUNK);
|
|
15909
16006
|
await ctx.database.write(async () => {
|
|
16007
|
+
await assertCanWrite2(ctx);
|
|
15910
16008
|
const records = [];
|
|
15911
16009
|
for (const id of chunkIds) {
|
|
15912
16010
|
try {
|
|
@@ -15940,6 +16038,7 @@ async function relinkMemoryTopicsOp(ctx, memoryIds) {
|
|
|
15940
16038
|
for (const id of Array.from(new Set(memoryIds))) {
|
|
15941
16039
|
try {
|
|
15942
16040
|
await ctx.database.write(async (writer) => {
|
|
16041
|
+
await assertCanWrite2(ctx);
|
|
15943
16042
|
let record2;
|
|
15944
16043
|
try {
|
|
15945
16044
|
record2 = await ctx.vaultMemoryCollection.find(id);
|
|
@@ -15970,6 +16069,7 @@ async function backfillMemoryTopicsOp(ctx, memoryIds) {
|
|
|
15970
16069
|
for (let i = 0; i < uniqueIds.length; i += CHUNK) {
|
|
15971
16070
|
const chunkIds = uniqueIds.slice(i, i + CHUNK);
|
|
15972
16071
|
await ctx.database.write(async () => {
|
|
16072
|
+
await assertCanWrite2(ctx);
|
|
15973
16073
|
const writes = [];
|
|
15974
16074
|
for (const id of chunkIds) {
|
|
15975
16075
|
let record2;
|
|
@@ -16002,6 +16102,7 @@ async function deleteAllVaultMemoriesForUserOp(ctx, userId) {
|
|
|
16002
16102
|
const records = await ctx.vaultMemoryCollection.query(import_watermelondb23.Q.where("user_id", userId), import_watermelondb23.Q.where("is_deleted", false)).fetch();
|
|
16003
16103
|
if (records.length === 0) return 0;
|
|
16004
16104
|
await ctx.database.write(async () => {
|
|
16105
|
+
await assertCanWrite2(ctx);
|
|
16005
16106
|
const prepared = records.map(
|
|
16006
16107
|
(record2) => record2.prepareUpdate((r) => {
|
|
16007
16108
|
r._setRaw("is_deleted", true);
|
|
@@ -16056,6 +16157,7 @@ async function archiveVaultMemoryOp(ctx, id, opts) {
|
|
|
16056
16157
|
let stale = false;
|
|
16057
16158
|
const archivedAtValue = opts?.now ?? Date.now();
|
|
16058
16159
|
await ctx.database.write(async () => {
|
|
16160
|
+
await assertCanWrite2(ctx);
|
|
16059
16161
|
if (record2.isDeleted || !isOwnedByCtxUser(ctx, record2) || record2.archivedAt !== null) {
|
|
16060
16162
|
stale = true;
|
|
16061
16163
|
return;
|
|
@@ -16079,6 +16181,7 @@ async function restoreVaultMemoryOp(ctx, id) {
|
|
|
16079
16181
|
if (record2.isDeleted || !isOwnedByCtxUser(ctx, record2)) return false;
|
|
16080
16182
|
let stale = false;
|
|
16081
16183
|
await ctx.database.write(async () => {
|
|
16184
|
+
await assertCanWrite2(ctx);
|
|
16082
16185
|
if (record2.isDeleted || !isOwnedByCtxUser(ctx, record2)) {
|
|
16083
16186
|
stale = true;
|
|
16084
16187
|
return;
|
|
@@ -16099,6 +16202,7 @@ async function hardDeleteDecayedOp(ctx, id, opts) {
|
|
|
16099
16202
|
const now = opts.now ?? Date.now();
|
|
16100
16203
|
let stale = false;
|
|
16101
16204
|
await ctx.database.write(async () => {
|
|
16205
|
+
await assertCanWrite2(ctx);
|
|
16102
16206
|
const archivedAt = record2.archivedAt;
|
|
16103
16207
|
if (record2.isDeleted || !isOwnedByCtxUser(ctx, record2) || archivedAt === null || now - archivedAt <= opts.hardDeleteWindowMs) {
|
|
16104
16208
|
stale = true;
|
|
@@ -16138,6 +16242,7 @@ async function updateVaultMemoryEmbeddingOp(ctx, id, embedding2, embeddingModel,
|
|
|
16138
16242
|
}
|
|
16139
16243
|
let written = false;
|
|
16140
16244
|
await ctx.database.write(async () => {
|
|
16245
|
+
await assertCanWrite2(ctx);
|
|
16141
16246
|
if (record2.isDeleted || !isOwnedByCtxUser(ctx, record2)) return;
|
|
16142
16247
|
const originalUpdatedAt = record2.updatedAt.getTime();
|
|
16143
16248
|
if (originalUpdatedAt !== readUpdatedAt || record2._getRaw("content") !== readStoredContent)
|
|
@@ -20134,6 +20239,13 @@ function restoreCandidates(candidates, redactor, ownNames) {
|
|
|
20134
20239
|
).map((c) => c.candidate);
|
|
20135
20240
|
}
|
|
20136
20241
|
async function extractAndRetain(messages, retainCtx, options) {
|
|
20242
|
+
const { memoryStore, signal } = options;
|
|
20243
|
+
if (memoryStore === null) throw new Error("Memory store is not ready");
|
|
20244
|
+
if (memoryStore && options.folderId !== void 0 && options.folderId !== null)
|
|
20245
|
+
throw new Error("Remote memory extraction does not support folders");
|
|
20246
|
+
if (memoryStore && options.extract.piiRedaction && !memoryStore.masksEmbeddingInput)
|
|
20247
|
+
throw new Error("PII-redacted extraction requires a memory store that masks embedding inputs");
|
|
20248
|
+
signal?.throwIfAborted();
|
|
20137
20249
|
const minConfidence = options.minConfidence ?? DEFAULT_MIN_CONFIDENCE;
|
|
20138
20250
|
const resolvedConsolidatePii = options.consolidateOptions?.piiRedaction ?? options.extract.piiRedaction;
|
|
20139
20251
|
const consolidateOptions = options.consolidateOptions !== void 0 ? {
|
|
@@ -20167,6 +20279,7 @@ async function extractAndRetain(messages, retainCtx, options) {
|
|
|
20167
20279
|
}
|
|
20168
20280
|
});
|
|
20169
20281
|
const extractMs = Date.now() - tExtract;
|
|
20282
|
+
signal?.throwIfAborted();
|
|
20170
20283
|
const filtered = candidates.filter((c) => c.confidence >= minConfidence);
|
|
20171
20284
|
const log = getLogger();
|
|
20172
20285
|
const screened = screenCandidatesForInjection(filtered);
|
|
@@ -20214,16 +20327,33 @@ async function extractAndRetain(messages, retainCtx, options) {
|
|
|
20214
20327
|
const results = [];
|
|
20215
20328
|
const quarantinedInfo = [];
|
|
20216
20329
|
let failedWrites = 0;
|
|
20330
|
+
let auditRows;
|
|
20217
20331
|
const tRetain = Date.now();
|
|
20218
20332
|
for (const { candidate, isQuarantined, reason, signature } of toRetain) {
|
|
20219
20333
|
try {
|
|
20334
|
+
signal?.throwIfAborted();
|
|
20220
20335
|
if (isQuarantined) {
|
|
20221
|
-
|
|
20222
|
-
|
|
20223
|
-
|
|
20224
|
-
|
|
20225
|
-
|
|
20226
|
-
|
|
20336
|
+
let existingId;
|
|
20337
|
+
if (memoryStore) {
|
|
20338
|
+
auditRows ?? (auditRows = memoryStore.list({
|
|
20339
|
+
scopes: [options.scope ?? "private"],
|
|
20340
|
+
includeArchived: true,
|
|
20341
|
+
includeQuarantined: true,
|
|
20342
|
+
includeSuperseded: true
|
|
20343
|
+
}));
|
|
20344
|
+
const sourceKey = [...new Set(candidate.sourceMessageIds)].sort().join("\0");
|
|
20345
|
+
const normalize = (value) => value.normalize("NFKC").trim().replace(/\s+/g, " ").toLowerCase();
|
|
20346
|
+
existingId = (await auditRows).find(
|
|
20347
|
+
(row) => row.trustTier === "quarantined" && row.scope === (options.scope ?? "private") && [...new Set(row.sourceChunkIds ?? [])].sort().join("\0") === sourceKey && normalize(row.content) === normalize(candidate.content)
|
|
20348
|
+
)?.uniqueId ?? null;
|
|
20349
|
+
} else {
|
|
20350
|
+
existingId = await findQuarantinedDuplicateOp(
|
|
20351
|
+
retainCtx.vaultCtx,
|
|
20352
|
+
candidate.content,
|
|
20353
|
+
candidate.sourceMessageIds,
|
|
20354
|
+
{ scope: options.scope ?? "private", folderId: options.folderId ?? null }
|
|
20355
|
+
).catch(() => null);
|
|
20356
|
+
}
|
|
20227
20357
|
if (existingId) {
|
|
20228
20358
|
quarantinedInfo.push({
|
|
20229
20359
|
candidate,
|
|
@@ -20234,18 +20364,26 @@ async function extractAndRetain(messages, retainCtx, options) {
|
|
|
20234
20364
|
continue;
|
|
20235
20365
|
}
|
|
20236
20366
|
}
|
|
20237
|
-
const
|
|
20367
|
+
const retainOptions = {
|
|
20238
20368
|
source: "auto-extracted",
|
|
20239
20369
|
sourceChunkIds: candidate.sourceMessageIds,
|
|
20240
20370
|
respectTombstones: true,
|
|
20241
20371
|
...options.scope !== void 0 && { scope: options.scope },
|
|
20242
|
-
...options.folderId !== void 0 && { folderId: options.folderId },
|
|
20243
20372
|
...consolidateOptions !== void 0 && { consolidateOptions },
|
|
20244
20373
|
...candidate.eventTime !== null && { eventTime: candidate.eventTime },
|
|
20245
20374
|
factType: candidate.type,
|
|
20246
20375
|
...isQuarantined && { trustTier: "quarantined", enableAutoMerge: false }
|
|
20376
|
+
};
|
|
20377
|
+
const result = memoryStore ? await memoryStore.retain(candidate.content, {
|
|
20378
|
+
...retainOptions,
|
|
20379
|
+
canWrite: retainCtx.vaultCtx.canWrite,
|
|
20380
|
+
signal
|
|
20381
|
+
}) : await retain(candidate.content, retainCtx, {
|
|
20382
|
+
...retainOptions,
|
|
20383
|
+
...options.folderId !== void 0 && { folderId: options.folderId }
|
|
20247
20384
|
});
|
|
20248
20385
|
if (isQuarantined) {
|
|
20386
|
+
auditRows = void 0;
|
|
20249
20387
|
const info = {
|
|
20250
20388
|
candidate,
|
|
20251
20389
|
memoryId: result.memoryId,
|
|
@@ -20264,9 +20402,16 @@ async function extractAndRetain(messages, retainCtx, options) {
|
|
|
20264
20402
|
}
|
|
20265
20403
|
succeededCandidates.push(candidate);
|
|
20266
20404
|
results.push(result);
|
|
20267
|
-
if (result.action !== "suppressed" &&
|
|
20405
|
+
if (result.action !== "suppressed" && candidate.entities.length > 0) {
|
|
20268
20406
|
try {
|
|
20269
|
-
|
|
20407
|
+
signal?.throwIfAborted();
|
|
20408
|
+
if (memoryStore) {
|
|
20409
|
+
await memoryStore.addTopics(result.memoryId, candidate.entities, {
|
|
20410
|
+
unlessUserManaged: true,
|
|
20411
|
+
canWrite: retainCtx.vaultCtx.canWrite,
|
|
20412
|
+
signal
|
|
20413
|
+
});
|
|
20414
|
+
} else if (options.entityCtx && !await isMemoryTopicsUserManaged(options.entityCtx, result.memoryId)) {
|
|
20270
20415
|
await linkMemoryEntitiesOp(options.entityCtx, result.memoryId, candidate.entities, {
|
|
20271
20416
|
unlessTopicsUserManaged: true
|
|
20272
20417
|
});
|
|
@@ -20516,7 +20661,7 @@ function createAutoExtractor(options) {
|
|
|
20516
20661
|
};
|
|
20517
20662
|
const consolidateOptions = options.consolidate ? { ...options.consolidate, ...subPassAuth(options.consolidate.baseUrl) } : void 0;
|
|
20518
20663
|
const injectionClassifierOptions = options.injectionClassifier ? { ...options.injectionClassifier, ...subPassAuth(options.injectionClassifier.baseUrl) } : void 0;
|
|
20519
|
-
if (options.retainCtx.vaultCtx.entityCtx && !options.entityCtx) {
|
|
20664
|
+
if (!options.memoryStore && options.retainCtx.vaultCtx.entityCtx && !options.entityCtx) {
|
|
20520
20665
|
getLogger().warn(
|
|
20521
20666
|
"[memory/extract] retainCtx.vaultCtx.entityCtx is set but extractor was created without `entityCtx` \u2014 W5 graph lane will receive no writes"
|
|
20522
20667
|
);
|
|
@@ -20561,6 +20706,8 @@ function createAutoExtractor(options) {
|
|
|
20561
20706
|
try {
|
|
20562
20707
|
const { candidates, results, failedCount, outcome: outcome2, failure, funnel, timings, model } = await extractAndRetain(window2, retainCtx, {
|
|
20563
20708
|
extract,
|
|
20709
|
+
memoryStore: options.memoryStore,
|
|
20710
|
+
signal: options.signal,
|
|
20564
20711
|
...options.minConfidence !== void 0 && { minConfidence: options.minConfidence },
|
|
20565
20712
|
...options.entityCtx !== void 0 && { entityCtx: options.entityCtx },
|
|
20566
20713
|
...options.scope !== void 0 && { scope: options.scope },
|
|
@@ -21221,7 +21368,7 @@ var MaskScopedEmbeddingCache = class extends Map {
|
|
|
21221
21368
|
return this;
|
|
21222
21369
|
}
|
|
21223
21370
|
};
|
|
21224
|
-
var scopedViews =
|
|
21371
|
+
var { scopedViews } = getEmbeddingCacheState();
|
|
21225
21372
|
function maskScopedEmbeddingCache(cache, masked) {
|
|
21226
21373
|
const views = scopedViews.get(cache) ?? {};
|
|
21227
21374
|
scopedViews.set(cache, views);
|
|
@@ -21646,44 +21793,48 @@ async function recall(query, ctx, options = {}) {
|
|
|
21646
21793
|
embeddingOptions,
|
|
21647
21794
|
ctx.vaultCache,
|
|
21648
21795
|
searchOptions
|
|
21649
|
-
)))(
|
|
21650
|
-
|
|
21651
|
-
|
|
21652
|
-
|
|
21653
|
-
|
|
21654
|
-
|
|
21655
|
-
|
|
21656
|
-
|
|
21657
|
-
|
|
21658
|
-
|
|
21659
|
-
|
|
21660
|
-
|
|
21661
|
-
|
|
21662
|
-
|
|
21663
|
-
|
|
21664
|
-
|
|
21665
|
-
|
|
21666
|
-
|
|
21667
|
-
|
|
21668
|
-
|
|
21669
|
-
|
|
21670
|
-
|
|
21671
|
-
|
|
21672
|
-
|
|
21796
|
+
)))(
|
|
21797
|
+
query,
|
|
21798
|
+
{
|
|
21799
|
+
limit: types.includes("chunk") ? Math.max(limit * 2, 16) : limit,
|
|
21800
|
+
minSimilarity: vaultMinScore,
|
|
21801
|
+
useFusion: true,
|
|
21802
|
+
rerank: flags.rerank,
|
|
21803
|
+
...options.rerankTopN !== void 0 && { rerankTopN: options.rerankTopN },
|
|
21804
|
+
...options.ceWeight !== void 0 && { ceWeight: options.ceWeight },
|
|
21805
|
+
...options.rerankLoadTimeoutMs !== void 0 && {
|
|
21806
|
+
rerankLoadTimeoutMs: options.rerankLoadTimeoutMs
|
|
21807
|
+
},
|
|
21808
|
+
...options.recencyAlpha !== void 0 && { recencyAlpha: options.recencyAlpha },
|
|
21809
|
+
...options.recency && { recency: options.recency },
|
|
21810
|
+
...options.mmr !== void 0 && { mmr: options.mmr },
|
|
21811
|
+
...options.supersessionBoost !== void 0 && {
|
|
21812
|
+
supersessionBoost: options.supersessionBoost
|
|
21813
|
+
},
|
|
21814
|
+
...options.supersessionWindow !== void 0 && {
|
|
21815
|
+
supersessionWindow: options.supersessionWindow
|
|
21816
|
+
},
|
|
21817
|
+
...options.proofCountAlpha !== void 0 && {
|
|
21818
|
+
proofCountAlpha: options.proofCountAlpha
|
|
21819
|
+
},
|
|
21820
|
+
...options.bm25AdmissionDivisor !== void 0 && {
|
|
21821
|
+
bm25AdmissionDivisor: options.bm25AdmissionDivisor
|
|
21822
|
+
},
|
|
21823
|
+
...options.rrfK !== void 0 && { rrfK: options.rrfK },
|
|
21824
|
+
...options.decryptLast !== void 0 && { decryptLast: options.decryptLast },
|
|
21825
|
+
...subQueries && { subQueries },
|
|
21826
|
+
...options.scopes && { scopes: options.scopes },
|
|
21827
|
+
...options.folderId !== void 0 && { folderId: options.folderId },
|
|
21828
|
+
...options.factTypes?.length && { factTypes: options.factTypes },
|
|
21829
|
+
...options.memoryIds !== void 0 && { memoryIds: options.memoryIds },
|
|
21830
|
+
...options.factTypeWeights && { factTypeWeights: options.factTypeWeights },
|
|
21831
|
+
...entityRanking.length > 0 && { entityRanking },
|
|
21832
|
+
...temporalRanking.length > 0 && { temporalRanking },
|
|
21833
|
+
...needsChunkEmbedding && { queryEmbedding: queryEmbedding ?? [] },
|
|
21834
|
+
queryEmbedTotalTimeoutMs
|
|
21673
21835
|
},
|
|
21674
|
-
|
|
21675
|
-
|
|
21676
|
-
...subQueries && { subQueries },
|
|
21677
|
-
...options.scopes && { scopes: options.scopes },
|
|
21678
|
-
...options.folderId !== void 0 && { folderId: options.folderId },
|
|
21679
|
-
...options.factTypes?.length && { factTypes: options.factTypes },
|
|
21680
|
-
...options.memoryIds !== void 0 && { memoryIds: options.memoryIds },
|
|
21681
|
-
...options.factTypeWeights && { factTypeWeights: options.factTypeWeights },
|
|
21682
|
-
...entityRanking.length > 0 && { entityRanking },
|
|
21683
|
-
...temporalRanking.length > 0 && { temporalRanking },
|
|
21684
|
-
...needsChunkEmbedding && { queryEmbedding: queryEmbedding ?? [] },
|
|
21685
|
-
queryEmbedTotalTimeoutMs
|
|
21686
|
-
});
|
|
21836
|
+
options.embeddingCache
|
|
21837
|
+
);
|
|
21687
21838
|
factResults.push(
|
|
21688
21839
|
...dedupeBy(
|
|
21689
21840
|
results,
|
|
@@ -22688,6 +22839,7 @@ function createLocalMemoryStore(options) {
|
|
|
22688
22839
|
database,
|
|
22689
22840
|
entityCollection: database.get("entity"),
|
|
22690
22841
|
memoryEntityCollection: database.get("memory_entity"),
|
|
22842
|
+
canWrite: options.canWrite,
|
|
22691
22843
|
...userId !== void 0 && { userId },
|
|
22692
22844
|
...options.allowUnscopedRows !== void 0 && {
|
|
22693
22845
|
allowUnscopedRows: options.allowUnscopedRows
|
|
@@ -22699,10 +22851,21 @@ function createLocalMemoryStore(options) {
|
|
|
22699
22851
|
walletAddress: options.walletAddress,
|
|
22700
22852
|
signMessage: options.signMessage,
|
|
22701
22853
|
embeddedWalletSigner: options.embeddedWalletSigner,
|
|
22854
|
+
canWrite: options.canWrite,
|
|
22702
22855
|
...userId !== void 0 && { userId },
|
|
22703
22856
|
...options.singleTenant !== void 0 && { singleTenant: options.singleTenant },
|
|
22704
22857
|
entityCtx
|
|
22705
22858
|
};
|
|
22859
|
+
const assertWrite = async (writeOptions) => {
|
|
22860
|
+
writeOptions?.signal?.throwIfAborted();
|
|
22861
|
+
if (writeOptions?.canWrite && !await writeOptions.canWrite()) {
|
|
22862
|
+
throw new Error("Memory source is no longer eligible");
|
|
22863
|
+
}
|
|
22864
|
+
if (options.canWrite && !await options.canWrite()) {
|
|
22865
|
+
throw new Error("Memory source is no longer eligible");
|
|
22866
|
+
}
|
|
22867
|
+
writeOptions?.signal?.throwIfAborted();
|
|
22868
|
+
};
|
|
22706
22869
|
const vaultCache = options.vaultCache ?? createVaultEmbeddingCache();
|
|
22707
22870
|
const ownedBy = userId !== void 0 ? [import_watermelondb32.Q.where("user_id", userId)] : [];
|
|
22708
22871
|
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)];
|
|
@@ -22814,9 +22977,25 @@ function createLocalMemoryStore(options) {
|
|
|
22814
22977
|
archive: (id) => archiveVaultMemoryOp(vaultCtx, id),
|
|
22815
22978
|
restore: (id) => restoreVaultMemoryOp(vaultCtx, id),
|
|
22816
22979
|
setTopics: (memoryId, topics) => setMemoryEntitiesOp(vaultCtx, memoryId, topics),
|
|
22817
|
-
addTopics: (memoryId, topics) => database.write(async (writer) => {
|
|
22980
|
+
addTopics: (memoryId, topics, writeOptions) => database.write(async (writer) => {
|
|
22981
|
+
await assertWrite(writeOptions);
|
|
22818
22982
|
const owned = await vaultCtx.vaultMemoryCollection.query(import_watermelondb32.Q.where("id", memoryId), import_watermelondb32.Q.where("is_deleted", false), ...ownedBy).fetchCount();
|
|
22819
|
-
return owned > 0 ? writer.callWriter(
|
|
22983
|
+
return owned > 0 ? writer.callWriter(
|
|
22984
|
+
() => linkMemoryEntitiesOp(
|
|
22985
|
+
{
|
|
22986
|
+
...entityCtx,
|
|
22987
|
+
canWrite: async () => {
|
|
22988
|
+
await assertWrite(writeOptions);
|
|
22989
|
+
return true;
|
|
22990
|
+
}
|
|
22991
|
+
},
|
|
22992
|
+
memoryId,
|
|
22993
|
+
topics,
|
|
22994
|
+
{
|
|
22995
|
+
unlessTopicsUserManaged: writeOptions?.unlessUserManaged
|
|
22996
|
+
}
|
|
22997
|
+
)
|
|
22998
|
+
) : [];
|
|
22820
22999
|
}),
|
|
22821
23000
|
setVisibility: (id, visibility, visibilityOptions) => setMemoryVisibilityOp(vaultCtx, id, { visibility, ...visibilityOptions }),
|
|
22822
23001
|
recall: (query, recallOptions) => recall(
|
|
@@ -22826,14 +23005,33 @@ function createLocalMemoryStore(options) {
|
|
|
22826
23005
|
),
|
|
22827
23006
|
retain: (content, retainOptions) => retain(
|
|
22828
23007
|
content,
|
|
22829
|
-
{
|
|
23008
|
+
{
|
|
23009
|
+
vaultCtx: {
|
|
23010
|
+
...vaultCtx,
|
|
23011
|
+
canWrite: async () => {
|
|
23012
|
+
await assertWrite(retainOptions);
|
|
23013
|
+
return true;
|
|
23014
|
+
}
|
|
23015
|
+
},
|
|
23016
|
+
embeddingOptions: options.embeddingOptions,
|
|
23017
|
+
vaultCache
|
|
23018
|
+
},
|
|
22830
23019
|
retainOptions
|
|
22831
23020
|
),
|
|
22832
23021
|
factSource: {
|
|
22833
|
-
search: (query, searchOptions) => searchVaultMemoriesWithSize(
|
|
23022
|
+
search: (query, searchOptions, embeddingCache) => searchVaultMemoriesWithSize(
|
|
22834
23023
|
query,
|
|
22835
23024
|
vaultCtx,
|
|
22836
|
-
{
|
|
23025
|
+
{
|
|
23026
|
+
...options.embeddingOptions,
|
|
23027
|
+
taskType: "memory_recall_embed",
|
|
23028
|
+
...embeddingCache && !options.embeddingOptions.cache && {
|
|
23029
|
+
cache: maskScopedEmbeddingCache(
|
|
23030
|
+
embeddingCache,
|
|
23031
|
+
Boolean(options.embeddingOptions.maskInput)
|
|
23032
|
+
)
|
|
23033
|
+
}
|
|
23034
|
+
},
|
|
22837
23035
|
vaultCache,
|
|
22838
23036
|
searchOptions
|
|
22839
23037
|
),
|
|
@@ -23465,7 +23663,14 @@ function stored(row) {
|
|
|
23465
23663
|
function createRemoteMemoryPipeline(options) {
|
|
23466
23664
|
const { persistence, embeddingOptions } = options;
|
|
23467
23665
|
const model = embeddingOptions.model ?? DEFAULT_API_EMBEDDING_MODEL;
|
|
23468
|
-
const operation = (mode) => {
|
|
23666
|
+
const operation = (mode, queryOptions = embeddingOptions, writeOptions) => {
|
|
23667
|
+
const signal = writeOptions?.signal;
|
|
23668
|
+
const assertWrite = async () => {
|
|
23669
|
+
signal?.throwIfAborted();
|
|
23670
|
+
if (writeOptions?.canWrite && !await writeOptions.canWrite())
|
|
23671
|
+
throw new Error("Memory source is no longer eligible");
|
|
23672
|
+
signal?.throwIfAborted();
|
|
23673
|
+
};
|
|
23469
23674
|
const rejectUndecryptable = (failed) => {
|
|
23470
23675
|
if (!failed.length) return;
|
|
23471
23676
|
if (mode === "retain")
|
|
@@ -23483,7 +23688,7 @@ function createRemoteMemoryPipeline(options) {
|
|
|
23483
23688
|
return items.map((item) => stored(item.memory));
|
|
23484
23689
|
};
|
|
23485
23690
|
const get = async (id) => {
|
|
23486
|
-
const snapshot = snapshots.get(id) ?? await persistence.get(id);
|
|
23691
|
+
const snapshot = snapshots.get(id) ?? await (signal ? persistence.get(id, signal) : persistence.get(id));
|
|
23487
23692
|
if (!snapshot || snapshot.memory.is_deleted || snapshot.memory.superseded_by) return null;
|
|
23488
23693
|
snapshots.set(id, snapshot);
|
|
23489
23694
|
return stored(snapshot.memory);
|
|
@@ -23496,7 +23701,7 @@ function createRemoteMemoryPipeline(options) {
|
|
|
23496
23701
|
const start = Date.now();
|
|
23497
23702
|
const budgetMs = search.queryEmbedTotalTimeoutMs ?? 8e3;
|
|
23498
23703
|
const embed = (texts) => generateEmbeddings(texts, {
|
|
23499
|
-
...
|
|
23704
|
+
...queryOptions,
|
|
23500
23705
|
taskType: mode === "retain" ? "memory_retain_embed" : "memory_recall_embed",
|
|
23501
23706
|
totalTimeoutMs: budgetMs
|
|
23502
23707
|
});
|
|
@@ -23516,7 +23721,11 @@ function createRemoteMemoryPipeline(options) {
|
|
|
23516
23721
|
}
|
|
23517
23722
|
};
|
|
23518
23723
|
const [primary, facetEmbeddings] = await Promise.all([
|
|
23519
|
-
search.queryEmbedding ??
|
|
23724
|
+
search.queryEmbedding ?? (mode === "recall" && queryOptions.cache ? generateEmbedding(query, {
|
|
23725
|
+
...queryOptions,
|
|
23726
|
+
taskType: "memory_recall_embed",
|
|
23727
|
+
totalTimeoutMs: budgetMs
|
|
23728
|
+
}) : embed([query]).then((vectors2) => vectors2[0])),
|
|
23520
23729
|
embedFacets()
|
|
23521
23730
|
]);
|
|
23522
23731
|
const queryEmbedding = storedVector(primary);
|
|
@@ -23529,7 +23738,7 @@ function createRemoteMemoryPipeline(options) {
|
|
|
23529
23738
|
if (forced.size < 100 && temporal[i] !== void 0) forced.add(temporal[i]);
|
|
23530
23739
|
}
|
|
23531
23740
|
const forceIds = [...forced];
|
|
23532
|
-
const windowOptions = (i,
|
|
23741
|
+
const windowOptions = (i, signal2) => ({
|
|
23533
23742
|
limit: Math.min(100, Math.max((search.limit ?? 8) * 3, 30)),
|
|
23534
23743
|
force_ids: i === 0 ? forceIds : [],
|
|
23535
23744
|
...search.scopes && { scopes: search.scopes },
|
|
@@ -23537,13 +23746,15 @@ function createRemoteMemoryPipeline(options) {
|
|
|
23537
23746
|
...search.memoryIds !== void 0 && { memory_ids: search.memoryIds },
|
|
23538
23747
|
include_archived: search.includeArchived,
|
|
23539
23748
|
embedding_model: model,
|
|
23540
|
-
...
|
|
23749
|
+
...signal2 && { signal: signal2 }
|
|
23541
23750
|
});
|
|
23542
23751
|
const vectors = [queryEmbedding, ...facetEmbeddings];
|
|
23543
23752
|
let windows;
|
|
23544
23753
|
if (mode === "retain") {
|
|
23545
23754
|
windows = await Promise.all(
|
|
23546
|
-
vectors.map(
|
|
23755
|
+
vectors.map(
|
|
23756
|
+
(embedding2, i) => persistence.candidateSet(embedding2, windowOptions(i, signal))
|
|
23757
|
+
)
|
|
23547
23758
|
);
|
|
23548
23759
|
} else {
|
|
23549
23760
|
const deadline = new AbortController();
|
|
@@ -23631,12 +23842,15 @@ function createRemoteMemoryPipeline(options) {
|
|
|
23631
23842
|
twin_opt_in: false
|
|
23632
23843
|
};
|
|
23633
23844
|
};
|
|
23634
|
-
const write = async (memory, snapshot) =>
|
|
23845
|
+
const write = async (memory, snapshot) => {
|
|
23846
|
+
await assertWrite();
|
|
23847
|
+
return remember([await persistence.put(memory, snapshot, signal)])[0];
|
|
23848
|
+
};
|
|
23635
23849
|
const port = {
|
|
23636
23850
|
prepare,
|
|
23637
23851
|
get,
|
|
23638
23852
|
getFresh: async (id) => {
|
|
23639
|
-
const current = await persistence.get(id);
|
|
23853
|
+
const current = await (signal ? persistence.get(id, signal) : persistence.get(id));
|
|
23640
23854
|
return current && !current.memory.is_deleted && !current.memory.superseded_by ? stored(current.memory) : null;
|
|
23641
23855
|
},
|
|
23642
23856
|
tombstones: async (embedding2, embeddingModel, scope, folderId) => {
|
|
@@ -23647,7 +23861,8 @@ function createRemoteMemoryPipeline(options) {
|
|
|
23647
23861
|
embedding_model: embeddingModel,
|
|
23648
23862
|
strict_model: true,
|
|
23649
23863
|
include_deleted: true,
|
|
23650
|
-
deleted_only: true
|
|
23864
|
+
deleted_only: true,
|
|
23865
|
+
signal
|
|
23651
23866
|
});
|
|
23652
23867
|
rejectUndecryptable(window2.failed);
|
|
23653
23868
|
return remember(window2.items);
|
|
@@ -23703,14 +23918,18 @@ function createRemoteMemoryPipeline(options) {
|
|
|
23703
23918
|
if (!target || !newer || id === successor) return false;
|
|
23704
23919
|
const old = snapshots.get(id);
|
|
23705
23920
|
const next = snapshots.get(successor);
|
|
23921
|
+
await assertWrite();
|
|
23706
23922
|
remember(
|
|
23707
|
-
await persistence.putMany(
|
|
23708
|
-
|
|
23709
|
-
|
|
23710
|
-
|
|
23711
|
-
|
|
23712
|
-
|
|
23713
|
-
|
|
23923
|
+
await persistence.putMany(
|
|
23924
|
+
[
|
|
23925
|
+
{
|
|
23926
|
+
memory: { ...old.memory, superseded_by: successor, superseded_at: Date.now() },
|
|
23927
|
+
expectedVersion: old
|
|
23928
|
+
},
|
|
23929
|
+
{ memory: next.memory, expectedVersion: next }
|
|
23930
|
+
],
|
|
23931
|
+
signal
|
|
23932
|
+
)
|
|
23714
23933
|
);
|
|
23715
23934
|
return true;
|
|
23716
23935
|
},
|
|
@@ -23719,18 +23938,22 @@ function createRemoteMemoryPipeline(options) {
|
|
|
23719
23938
|
if (!target) return { created: null, retired: false };
|
|
23720
23939
|
const snapshot = snapshots.get(targetId);
|
|
23721
23940
|
const successor = createRow(input);
|
|
23941
|
+
await assertWrite();
|
|
23722
23942
|
const rows = remember(
|
|
23723
|
-
await persistence.putMany(
|
|
23724
|
-
|
|
23725
|
-
|
|
23726
|
-
|
|
23727
|
-
|
|
23728
|
-
|
|
23729
|
-
|
|
23730
|
-
|
|
23731
|
-
|
|
23732
|
-
|
|
23733
|
-
|
|
23943
|
+
await persistence.putMany(
|
|
23944
|
+
[
|
|
23945
|
+
{ memory: successor, expectedVersion: 0 },
|
|
23946
|
+
{
|
|
23947
|
+
memory: {
|
|
23948
|
+
...snapshot.memory,
|
|
23949
|
+
superseded_by: successor.memory_id,
|
|
23950
|
+
superseded_at: Date.now()
|
|
23951
|
+
},
|
|
23952
|
+
expectedVersion: snapshot
|
|
23953
|
+
}
|
|
23954
|
+
],
|
|
23955
|
+
signal
|
|
23956
|
+
)
|
|
23734
23957
|
);
|
|
23735
23958
|
return { created: rows[0], retired: true };
|
|
23736
23959
|
}
|
|
@@ -23740,15 +23963,17 @@ function createRemoteMemoryPipeline(options) {
|
|
|
23740
23963
|
const factSource = {
|
|
23741
23964
|
graphRanking: options.graphRanking,
|
|
23742
23965
|
temporalRanking: options.temporalRanking,
|
|
23743
|
-
search: async (text14, searchOptions) => {
|
|
23744
|
-
const
|
|
23966
|
+
search: async (text14, searchOptions, embeddingCache) => {
|
|
23967
|
+
const queryOptions = {
|
|
23968
|
+
...embeddingOptions,
|
|
23969
|
+
taskType: "memory_recall_embed",
|
|
23970
|
+
...embeddingCache && !embeddingOptions.cache && {
|
|
23971
|
+
cache: maskScopedEmbeddingCache(embeddingCache, Boolean(embeddingOptions.maskInput))
|
|
23972
|
+
}
|
|
23973
|
+
};
|
|
23974
|
+
const { prepare } = operation("recall", queryOptions);
|
|
23745
23975
|
const prepared = await prepare(text14, searchOptions);
|
|
23746
|
-
const ranked = await rankPreparedVaultCandidates(
|
|
23747
|
-
text14,
|
|
23748
|
-
prepared,
|
|
23749
|
-
{ ...embeddingOptions, taskType: "memory_recall_embed" },
|
|
23750
|
-
searchOptions
|
|
23751
|
-
);
|
|
23976
|
+
const ranked = await rankPreparedVaultCandidates(text14, prepared, queryOptions, searchOptions);
|
|
23752
23977
|
return {
|
|
23753
23978
|
...ranked,
|
|
23754
23979
|
rankedOnCosine: prepared.memories.length > 0 && !prepared.embeddingsUnavailable,
|
|
@@ -23763,7 +23988,7 @@ function createRemoteMemoryPipeline(options) {
|
|
|
23763
23988
|
factSource,
|
|
23764
23989
|
recall: async (query, recallOptions = {}) => recall(query, { embeddingOptions, factSource }, { ...recallOptions, types: ["fact"] }),
|
|
23765
23990
|
retain: async (content, retainOptions) => {
|
|
23766
|
-
const { port } = operation("retain");
|
|
23991
|
+
const { port } = operation("retain", embeddingOptions, retainOptions);
|
|
23767
23992
|
return retainWithPersistence(
|
|
23768
23993
|
content,
|
|
23769
23994
|
{
|
|
@@ -24346,16 +24571,21 @@ function createRemoteMemoryStore(options) {
|
|
|
24346
24571
|
const record2 = await persistence.get(id);
|
|
24347
24572
|
return record2 && !record2.memory.is_deleted ? record2 : null;
|
|
24348
24573
|
};
|
|
24349
|
-
const mutateLocked = async (id, change, edit) => {
|
|
24350
|
-
|
|
24574
|
+
const mutateLocked = async (id, change, edit, writeOptions) => {
|
|
24575
|
+
writeOptions?.signal?.throwIfAborted();
|
|
24576
|
+
const record2 = writeOptions?.signal ? await persistence.get(id, writeOptions.signal) : await live(id);
|
|
24351
24577
|
if (!record2) return null;
|
|
24578
|
+
if (record2.memory.is_deleted) return null;
|
|
24579
|
+
if (writeOptions?.canWrite && !await writeOptions.canWrite())
|
|
24580
|
+
throw new Error("Memory source is no longer eligible");
|
|
24581
|
+
writeOptions?.signal?.throwIfAborted();
|
|
24352
24582
|
const next = edit(structuredClone(record2.memory));
|
|
24353
24583
|
if (!next) return null;
|
|
24354
|
-
const saved = await persistence.put(next, record2);
|
|
24584
|
+
const saved = writeOptions?.signal ? await persistence.put(next, record2, writeOptions.signal) : await persistence.put(next, record2);
|
|
24355
24585
|
notify(typeof change === "function" ? change(record2.memory) : change, [saved]);
|
|
24356
24586
|
return saved;
|
|
24357
24587
|
};
|
|
24358
|
-
const mutate = (id, change, edit) => serialized(id, () => mutateLocked(id, change, edit));
|
|
24588
|
+
const mutate = (id, change, edit, writeOptions) => serialized(id, () => mutateLocked(id, change, edit, writeOptions));
|
|
24359
24589
|
const serializedAll = (ids, task) => [...new Set(ids)].sort().reduceRight((inner, id) => () => serialized(id, inner), task)();
|
|
24360
24590
|
const mutateMany = async (ids, change, edit) => {
|
|
24361
24591
|
const saved = /* @__PURE__ */ new Map();
|
|
@@ -24868,13 +25098,21 @@ function createRemoteMemoryStore(options) {
|
|
|
24868
25098
|
}))
|
|
24869
25099
|
);
|
|
24870
25100
|
},
|
|
24871
|
-
addTopics: async (memoryId, topics) => {
|
|
25101
|
+
addTopics: async (memoryId, topics, writeOptions) => {
|
|
24872
25102
|
const added = await withKnownKinds(topicInputs(topics, "auto"));
|
|
24873
|
-
const saved = await mutate(
|
|
24874
|
-
|
|
24875
|
-
|
|
24876
|
-
|
|
24877
|
-
|
|
25103
|
+
const saved = await mutate(
|
|
25104
|
+
memoryId,
|
|
25105
|
+
"edit",
|
|
25106
|
+
(memory) => {
|
|
25107
|
+
if (writeOptions?.unlessUserManaged && memory.topics_user_managed) return null;
|
|
25108
|
+
return {
|
|
25109
|
+
...memory,
|
|
25110
|
+
topics: serializeTopics(mergeTopics(parseTopics(memory.topics) ?? [], added)),
|
|
25111
|
+
topics_updated_at: Date.now()
|
|
25112
|
+
};
|
|
25113
|
+
},
|
|
25114
|
+
writeOptions
|
|
25115
|
+
);
|
|
24878
25116
|
if (!saved) return [];
|
|
24879
25117
|
const now = /* @__PURE__ */ new Date();
|
|
24880
25118
|
return mergeTopics([], added).map(
|
|
@@ -25727,6 +25965,7 @@ function createDurableAutoExtractor(options) {
|
|
|
25727
25965
|
};
|
|
25728
25966
|
const folderId = options.folderId ?? null;
|
|
25729
25967
|
let disposed = false;
|
|
25968
|
+
let activeBatch = null;
|
|
25730
25969
|
let running = false;
|
|
25731
25970
|
let wakeRequested = false;
|
|
25732
25971
|
let timer;
|
|
@@ -25763,14 +26002,18 @@ function createDurableAutoExtractor(options) {
|
|
|
25763
26002
|
}, delay);
|
|
25764
26003
|
}
|
|
25765
26004
|
async function extractBatch(messages, conversationId, ids, jobScope, jobFolderId) {
|
|
26005
|
+
if (disposed) throw new Error("Extraction session was disposed");
|
|
25766
26006
|
let watchdog;
|
|
25767
26007
|
let cancelled = false;
|
|
26008
|
+
const controller = new AbortController();
|
|
26009
|
+
activeBatch = controller;
|
|
25768
26010
|
const model = options.modelForScope?.(jobScope) ?? options.extract.model;
|
|
25769
26011
|
try {
|
|
25770
26012
|
return await Promise.race([
|
|
25771
26013
|
new Promise((resolve, reject) => {
|
|
25772
26014
|
const worker = createAutoExtractor({
|
|
25773
26015
|
...options,
|
|
26016
|
+
signal: controller.signal,
|
|
25774
26017
|
retainCtx: {
|
|
25775
26018
|
...options.retainCtx,
|
|
25776
26019
|
vaultCtx: {
|
|
@@ -25799,6 +26042,8 @@ function createDurableAutoExtractor(options) {
|
|
|
25799
26042
|
]);
|
|
25800
26043
|
} finally {
|
|
25801
26044
|
cancelled = true;
|
|
26045
|
+
controller.abort();
|
|
26046
|
+
if (activeBatch === controller) activeBatch = null;
|
|
25802
26047
|
if (watchdog !== void 0) clearTimeout(watchdog);
|
|
25803
26048
|
}
|
|
25804
26049
|
}
|
|
@@ -25810,6 +26055,7 @@ function createDurableAutoExtractor(options) {
|
|
|
25810
26055
|
for (const message of loaded)
|
|
25811
26056
|
if (message && message.messageId > 0) sequences.set(message.uniqueId, message.messageId);
|
|
25812
26057
|
await database.write(async () => {
|
|
26058
|
+
if (disposed) return;
|
|
25813
26059
|
const current = idsOf(job);
|
|
25814
26060
|
const acknowledged = ids.filter((id) => current.includes(id));
|
|
25815
26061
|
if (!acknowledged.length) return;
|
|
@@ -25982,6 +26228,7 @@ function createDurableAutoExtractor(options) {
|
|
|
25982
26228
|
jobScope,
|
|
25983
26229
|
jobFolderId
|
|
25984
26230
|
);
|
|
26231
|
+
if (disposed) throw new Error("Extraction session was disposed");
|
|
25985
26232
|
options.onTurnComplete?.(result);
|
|
25986
26233
|
return result;
|
|
25987
26234
|
};
|
|
@@ -26018,6 +26265,7 @@ function createDurableAutoExtractor(options) {
|
|
|
26018
26265
|
);
|
|
26019
26266
|
scheduleAfterSuccess = true;
|
|
26020
26267
|
} catch (error) {
|
|
26268
|
+
if (disposed) break;
|
|
26021
26269
|
attempts.set(job.id, attempted + 1);
|
|
26022
26270
|
retry = true;
|
|
26023
26271
|
reportError(error, conversationId);
|
|
@@ -26040,6 +26288,14 @@ function createDurableAutoExtractor(options) {
|
|
|
26040
26288
|
schedule(retry ? options.retryDelayMs ?? 3e4 : 0);
|
|
26041
26289
|
}
|
|
26042
26290
|
}
|
|
26291
|
+
function dispose() {
|
|
26292
|
+
disposed = true;
|
|
26293
|
+
activeBatch?.abort(options.signal?.reason);
|
|
26294
|
+
if (timer !== void 0) clearTimeout(timer);
|
|
26295
|
+
options.signal?.removeEventListener("abort", dispose);
|
|
26296
|
+
}
|
|
26297
|
+
if (options.signal?.aborted) dispose();
|
|
26298
|
+
else options.signal?.addEventListener("abort", dispose, { once: true });
|
|
26043
26299
|
schedule(0);
|
|
26044
26300
|
return {
|
|
26045
26301
|
processTurn(messages, conversationId) {
|
|
@@ -26119,10 +26375,7 @@ function createDurableAutoExtractor(options) {
|
|
|
26119
26375
|
return true;
|
|
26120
26376
|
},
|
|
26121
26377
|
isProcessing: () => running,
|
|
26122
|
-
dispose
|
|
26123
|
-
disposed = true;
|
|
26124
|
-
if (timer !== void 0) clearTimeout(timer);
|
|
26125
|
-
}
|
|
26378
|
+
dispose
|
|
26126
26379
|
};
|
|
26127
26380
|
}
|
|
26128
26381
|
|
|
@@ -32392,6 +32645,7 @@ var CONVERSATION_REDACTOR_LIMIT = 50;
|
|
|
32392
32645
|
var NO_CONVERSATION_KEY = "__no_conversation__";
|
|
32393
32646
|
var NO_STORE_FOLDERS = "Folders are not supported with a memoryStore";
|
|
32394
32647
|
var NO_STORE_MASK = "piiRedaction needs a memoryStore built with embeddingOptions.maskInput";
|
|
32648
|
+
var MEMORY_STORE_NOT_READY = "Memory store is not ready";
|
|
32395
32649
|
var conversationRedactors = /* @__PURE__ */ new Map();
|
|
32396
32650
|
function getConversationRedactor(conversationId, nerDetector) {
|
|
32397
32651
|
const key = conversationId ?? NO_CONVERSATION_KEY;
|
|
@@ -32482,7 +32736,7 @@ function useChatStorage(options) {
|
|
|
32482
32736
|
() => ({ getToken, baseUrl, model: embeddingModel, maskInput: maskEmbeddingInput }),
|
|
32483
32737
|
[getToken, baseUrl, embeddingModel, maskEmbeddingInput]
|
|
32484
32738
|
);
|
|
32485
|
-
const storeMaskMissing = memoryStore !== void 0 && maskEmbeddingInput !== void 0 && !memoryStore.masksEmbeddingInput;
|
|
32739
|
+
const storeMaskMissing = memoryStore !== void 0 && memoryStore !== null && maskEmbeddingInput !== void 0 && !memoryStore.masksEmbeddingInput;
|
|
32486
32740
|
const blobManagerRef = (0, import_react6.useRef)(new BlobUrlManager());
|
|
32487
32741
|
(0, import_react6.useEffect)(() => {
|
|
32488
32742
|
const manager = blobManagerRef.current;
|
|
@@ -32759,6 +33013,7 @@ function useChatStorage(options) {
|
|
|
32759
33013
|
);
|
|
32760
33014
|
const retainVaultMemory = (0, import_react6.useCallback)(
|
|
32761
33015
|
async (input) => {
|
|
33016
|
+
if (memoryStore === null) throw new Error(MEMORY_STORE_NOT_READY);
|
|
32762
33017
|
if (memoryStore) {
|
|
32763
33018
|
if (storeMaskMissing) throw new Error(NO_STORE_MASK);
|
|
32764
33019
|
if (input.folderId !== void 0) throw new Error(NO_STORE_FOLDERS);
|
|
@@ -32790,6 +33045,7 @@ function useChatStorage(options) {
|
|
|
32790
33045
|
);
|
|
32791
33046
|
const createMemoryVaultTool2 = (0, import_react6.useCallback)(
|
|
32792
33047
|
(options2) => {
|
|
33048
|
+
if (memoryStore === null) throw new Error(MEMORY_STORE_NOT_READY);
|
|
32793
33049
|
if (storeMaskMissing) throw new Error(NO_STORE_MASK);
|
|
32794
33050
|
const embOpts = getToken ? vaultEmbeddingOptions : void 0;
|
|
32795
33051
|
return createMemoryVaultTool(
|
|
@@ -32811,6 +33067,7 @@ function useChatStorage(options) {
|
|
|
32811
33067
|
);
|
|
32812
33068
|
const getVaultMemories = (0, import_react6.useCallback)(
|
|
32813
33069
|
(options2) => {
|
|
33070
|
+
if (memoryStore === null) return Promise.resolve([]);
|
|
32814
33071
|
if (!memoryStore) return getAllVaultMemoriesOp(vaultCtx, options2);
|
|
32815
33072
|
const { folderId, levels, kinds, ...listOptions } = options2 ?? {};
|
|
32816
33073
|
if (folderId !== void 0) throw new Error(NO_STORE_FOLDERS);
|
|
@@ -32822,6 +33079,7 @@ function useChatStorage(options) {
|
|
|
32822
33079
|
);
|
|
32823
33080
|
const createVaultMemory = (0, import_react6.useCallback)(
|
|
32824
33081
|
async (content, scope) => {
|
|
33082
|
+
if (memoryStore === null) throw new Error(MEMORY_STORE_NOT_READY);
|
|
32825
33083
|
if (storeMaskMissing) throw new Error(NO_STORE_MASK);
|
|
32826
33084
|
if (memoryStore) return memoryStore.create({ content, scope });
|
|
32827
33085
|
const result = await createVaultMemoryOp(vaultCtx, { content, scope });
|
|
@@ -32843,6 +33101,7 @@ function useChatStorage(options) {
|
|
|
32843
33101
|
);
|
|
32844
33102
|
const updateVaultMemory = (0, import_react6.useCallback)(
|
|
32845
33103
|
async (id, content, scope) => {
|
|
33104
|
+
if (memoryStore === null) throw new Error(MEMORY_STORE_NOT_READY);
|
|
32846
33105
|
if (storeMaskMissing) throw new Error(NO_STORE_MASK);
|
|
32847
33106
|
if (memoryStore) return memoryStore.update(id, { content, scope });
|
|
32848
33107
|
const existing = await getVaultMemoryOp(vaultCtx, id);
|
|
@@ -32868,6 +33127,7 @@ function useChatStorage(options) {
|
|
|
32868
33127
|
);
|
|
32869
33128
|
const deleteVaultMemory = (0, import_react6.useCallback)(
|
|
32870
33129
|
async (id) => {
|
|
33130
|
+
if (memoryStore === null) throw new Error(MEMORY_STORE_NOT_READY);
|
|
32871
33131
|
if (memoryStore) return memoryStore.delete(id);
|
|
32872
33132
|
const existing = await getVaultMemoryOp(vaultCtx, id);
|
|
32873
33133
|
const result = await deleteVaultMemoryOp(vaultCtx, id);
|
|
@@ -32881,7 +33141,7 @@ function useChatStorage(options) {
|
|
|
32881
33141
|
const chunkVectorCacheRef = (0, import_react6.useRef)(createChunkVectorCache());
|
|
32882
33142
|
const clientToolEmbeddingsCacheRef = (0, import_react6.useRef)(/* @__PURE__ */ new Map());
|
|
32883
33143
|
(0, import_react6.useEffect)(() => {
|
|
32884
|
-
if (!getToken || memoryStore) return;
|
|
33144
|
+
if (!getToken || memoryStore !== void 0) return;
|
|
32885
33145
|
void (async () => {
|
|
32886
33146
|
try {
|
|
32887
33147
|
await preEmbedVaultMemories(vaultCtx, vaultEmbeddingOptions, vaultEmbeddingCache);
|
|
@@ -32897,6 +33157,7 @@ function useChatStorage(options) {
|
|
|
32897
33157
|
}, [vaultEmbeddingCache]);
|
|
32898
33158
|
const createMemoryVaultSearchTool2 = (0, import_react6.useCallback)(
|
|
32899
33159
|
(searchOptions) => {
|
|
33160
|
+
if (memoryStore === null) throw new Error(MEMORY_STORE_NOT_READY);
|
|
32900
33161
|
if (!getToken && !memoryStore) {
|
|
32901
33162
|
throw new Error("getToken is required for memory vault search tool");
|
|
32902
33163
|
}
|
|
@@ -32912,6 +33173,7 @@ function useChatStorage(options) {
|
|
|
32912
33173
|
);
|
|
32913
33174
|
const createRecallTool2 = (0, import_react6.useCallback)(
|
|
32914
33175
|
(toolOptions, callbacks) => {
|
|
33176
|
+
if (memoryStore === null) throw new Error(MEMORY_STORE_NOT_READY);
|
|
32915
33177
|
if (!getToken && !memoryStore) {
|
|
32916
33178
|
throw new Error("getToken is required for recall tool");
|
|
32917
33179
|
}
|
|
@@ -32951,6 +33213,7 @@ function useChatStorage(options) {
|
|
|
32951
33213
|
);
|
|
32952
33214
|
const searchVaultMemoriesFn = (0, import_react6.useCallback)(
|
|
32953
33215
|
async (query, searchOptions) => {
|
|
33216
|
+
if (memoryStore === null) return [];
|
|
32954
33217
|
if (storeMaskMissing) throw new Error(NO_STORE_MASK);
|
|
32955
33218
|
if (memoryStore) return (await memoryStore.factSource.search(query, searchOptions)).results;
|
|
32956
33219
|
if (!getToken) return [];
|
|
@@ -32966,7 +33229,7 @@ function useChatStorage(options) {
|
|
|
32966
33229
|
);
|
|
32967
33230
|
const recallFn = (0, import_react6.useCallback)(
|
|
32968
33231
|
async (query, options2) => {
|
|
32969
|
-
if (!getToken && !memoryStore) {
|
|
33232
|
+
if (memoryStore === null || !getToken && !memoryStore) {
|
|
32970
33233
|
return {
|
|
32971
33234
|
memories: [],
|
|
32972
33235
|
usedBudget: options2?.budget ?? "low",
|