@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/server/index.cjs
CHANGED
|
@@ -16574,6 +16574,10 @@ __export(index_exports, {
|
|
|
16574
16574
|
});
|
|
16575
16575
|
module.exports = __toCommonJS(index_exports);
|
|
16576
16576
|
|
|
16577
|
+
// src/lib/chat/toolResultMessage.ts
|
|
16578
|
+
var FOOTER = "\n\nBased on these results, continue with the task.";
|
|
16579
|
+
var TOOL_RESULT_FOOTER_LINE = FOOTER.trim();
|
|
16580
|
+
|
|
16577
16581
|
// src/lib/tools/toolCatalog.ts
|
|
16578
16582
|
var TOOL_CATALOG = {
|
|
16579
16583
|
gmail_search_messages: { label: "Search emails", provider: "gmail", connector: "Gmail" },
|
|
@@ -16750,7 +16754,32 @@ ${neutralised}
|
|
|
16750
16754
|
}
|
|
16751
16755
|
|
|
16752
16756
|
// src/lib/chat/toolResults.ts
|
|
16757
|
+
var TOOL_RESULTS_PREFIX = "[Tool Execution Results]";
|
|
16758
|
+
var TOOL_LINE = /^Tool "([^"]+)" returned: (.*)$/;
|
|
16753
16759
|
var TOOL_RESULT_ORIGIN = "tool_result";
|
|
16760
|
+
function isToolResultsRow(row) {
|
|
16761
|
+
if (row.origin === TOOL_RESULT_ORIGIN) return true;
|
|
16762
|
+
if (typeof row.origin === "string") return false;
|
|
16763
|
+
if (row.role !== "user" || !row.content.startsWith(TOOL_RESULTS_PREFIX)) return false;
|
|
16764
|
+
return parseToolResultSegments(row.content).length > 0;
|
|
16765
|
+
}
|
|
16766
|
+
function parseToolResultSegments(content) {
|
|
16767
|
+
const segments = [];
|
|
16768
|
+
for (const raw of content.split("\n")) {
|
|
16769
|
+
const line = raw.trim();
|
|
16770
|
+
const match = TOOL_LINE.exec(line);
|
|
16771
|
+
if (match) {
|
|
16772
|
+
segments.push({ name: match[1], line });
|
|
16773
|
+
continue;
|
|
16774
|
+
}
|
|
16775
|
+
const current = segments[segments.length - 1];
|
|
16776
|
+
if (!current || line === "" || line === TOOL_RESULT_FOOTER_LINE) continue;
|
|
16777
|
+
if (line === TOOL_RESULTS_PREFIX) continue;
|
|
16778
|
+
current.line = `${current.line}
|
|
16779
|
+
${line}`;
|
|
16780
|
+
}
|
|
16781
|
+
return segments;
|
|
16782
|
+
}
|
|
16754
16783
|
|
|
16755
16784
|
// src/lib/db/chat/operations.ts
|
|
16756
16785
|
var import_watermelondb2 = __toESM(require_watermelondb());
|
|
@@ -18373,8 +18402,9 @@ async function getConversationsByProjectOp(ctx, projectId) {
|
|
|
18373
18402
|
)
|
|
18374
18403
|
);
|
|
18375
18404
|
}
|
|
18376
|
-
async function getMessagesOp(ctx, convId) {
|
|
18377
|
-
const
|
|
18405
|
+
async function getMessagesOp(ctx, convId, opts) {
|
|
18406
|
+
const fetched = await ctx.messagesCollection.query(import_watermelondb2.Q.where("conversation_id", convId), import_watermelondb2.Q.sortBy("message_id", import_watermelondb2.Q.asc)).unsafeFetchRaw();
|
|
18407
|
+
const results = opts?.rawFilter ? fetched.filter(opts.rawFilter) : fetched;
|
|
18378
18408
|
return Promise.all(
|
|
18379
18409
|
results.map(
|
|
18380
18410
|
(raw) => messageRawToStored(raw, ctx.walletAddress, ctx.signMessage, ctx.embeddedWalletSigner)
|
|
@@ -20108,6 +20138,24 @@ var postApiV1Embeddings = (options) => (options.client ?? client).post({
|
|
|
20108
20138
|
// src/lib/memoryEngine/generate.ts
|
|
20109
20139
|
init_clientConfig();
|
|
20110
20140
|
init_taskType();
|
|
20141
|
+
|
|
20142
|
+
// src/lib/memoryEngine/embeddingCacheState.ts
|
|
20143
|
+
var EMBEDDING_CACHE_STATE_KEY = /* @__PURE__ */ Symbol.for("@anuma/sdk/embedding-cache/v1");
|
|
20144
|
+
var cacheGlobal = globalThis;
|
|
20145
|
+
var fallbackState = {
|
|
20146
|
+
scopedViews: /* @__PURE__ */ new WeakMap(),
|
|
20147
|
+
inFlightByCache: /* @__PURE__ */ new WeakMap(),
|
|
20148
|
+
cachedEmbeddingModels: /* @__PURE__ */ new WeakMap()
|
|
20149
|
+
};
|
|
20150
|
+
function getEmbeddingCacheState() {
|
|
20151
|
+
try {
|
|
20152
|
+
return cacheGlobal[EMBEDDING_CACHE_STATE_KEY] ?? (cacheGlobal[EMBEDDING_CACHE_STATE_KEY] = fallbackState);
|
|
20153
|
+
} catch {
|
|
20154
|
+
return fallbackState;
|
|
20155
|
+
}
|
|
20156
|
+
}
|
|
20157
|
+
|
|
20158
|
+
// src/lib/memoryEngine/generate.ts
|
|
20111
20159
|
var EMBED_MAX_ATTEMPTS = 4;
|
|
20112
20160
|
var DEFAULT_EMBEDDING_REQUEST_TIMEOUT_MS = 15e3;
|
|
20113
20161
|
var DEFAULT_EMBEDDING_TOKEN_TIMEOUT_MS = 1e4;
|
|
@@ -20198,15 +20246,18 @@ async function generateEmbedding(text12, options) {
|
|
|
20198
20246
|
if (total === void 0) return embedOne(text12, options, void 0);
|
|
20199
20247
|
return withDeadline((signal) => embedOne(text12, options, signal), total, "embedding");
|
|
20200
20248
|
}
|
|
20201
|
-
var inFlightByCache
|
|
20249
|
+
var { inFlightByCache, cachedEmbeddingModels } = getEmbeddingCacheState();
|
|
20202
20250
|
async function embedOne(text12, options, outer) {
|
|
20203
20251
|
const { cache } = options;
|
|
20204
20252
|
if (!cache) return Array.from(await requestEmbedding(text12, options, outer));
|
|
20253
|
+
const model = options.model ?? DEFAULT_API_EMBEDDING_MODEL;
|
|
20205
20254
|
const cached = cache.get(text12);
|
|
20206
|
-
|
|
20255
|
+
const cachedModel = cached && cachedEmbeddingModels.get(cached);
|
|
20256
|
+
if (cached && (cachedModel === void 0 || cachedModel === model)) return Array.from(cached);
|
|
20207
20257
|
const inFlight = inFlightByCache.get(cache) ?? /* @__PURE__ */ new Map();
|
|
20208
20258
|
inFlightByCache.set(cache, inFlight);
|
|
20209
|
-
const
|
|
20259
|
+
const requestKey = JSON.stringify([model, text12]);
|
|
20260
|
+
const pending = inFlight.get(requestKey);
|
|
20210
20261
|
if (pending) {
|
|
20211
20262
|
try {
|
|
20212
20263
|
return Array.from(await pending);
|
|
@@ -20215,13 +20266,14 @@ async function embedOne(text12, options, outer) {
|
|
|
20215
20266
|
}
|
|
20216
20267
|
}
|
|
20217
20268
|
const request = requestEmbedding(text12, options, outer);
|
|
20218
|
-
inFlight.set(
|
|
20269
|
+
inFlight.set(requestKey, request);
|
|
20219
20270
|
try {
|
|
20220
20271
|
const embedding = await request;
|
|
20272
|
+
cachedEmbeddingModels.set(embedding, model);
|
|
20221
20273
|
cache.set(text12, embedding);
|
|
20222
20274
|
return Array.from(embedding);
|
|
20223
20275
|
} finally {
|
|
20224
|
-
if (inFlight.get(
|
|
20276
|
+
if (inFlight.get(requestKey) === request) inFlight.delete(requestKey);
|
|
20225
20277
|
}
|
|
20226
20278
|
}
|
|
20227
20279
|
async function requestEmbedding(text12, options, outer) {
|
|
@@ -20304,13 +20356,15 @@ async function embedMany(texts, options, outer) {
|
|
|
20304
20356
|
const { baseUrl = BASE_URL, model, batchSize, cache } = options;
|
|
20305
20357
|
const timeoutMs = options.timeoutMs ?? DEFAULT_EMBEDDING_REQUEST_TIMEOUT_MS;
|
|
20306
20358
|
const chunkSize = batchSize ?? DEFAULT_EMBEDDING_BATCH_SIZE;
|
|
20359
|
+
const embeddingModel = model ?? DEFAULT_API_EMBEDDING_MODEL;
|
|
20307
20360
|
const results = new Array(texts.length).fill(null);
|
|
20308
20361
|
const uncachedIndices = [];
|
|
20309
20362
|
const uncachedTexts = [];
|
|
20310
20363
|
for (let i = 0; i < texts.length; i++) {
|
|
20311
20364
|
if (cache) {
|
|
20312
20365
|
const cached = cache.get(texts[i]);
|
|
20313
|
-
|
|
20366
|
+
const cachedModel = cached && cachedEmbeddingModels.get(cached);
|
|
20367
|
+
if (cached && (cachedModel === void 0 || cachedModel === embeddingModel)) {
|
|
20314
20368
|
results[i] = Array.from(cached);
|
|
20315
20369
|
continue;
|
|
20316
20370
|
}
|
|
@@ -20326,7 +20380,6 @@ async function embedMany(texts, options, outer) {
|
|
|
20326
20380
|
...taskTypeHeader(options.taskType)
|
|
20327
20381
|
};
|
|
20328
20382
|
if (outer?.aborted) throw outer.reason;
|
|
20329
|
-
const embeddingModel = model ?? DEFAULT_API_EMBEDDING_MODEL;
|
|
20330
20383
|
let newEmbeddings;
|
|
20331
20384
|
if (uncachedTexts.length <= chunkSize) {
|
|
20332
20385
|
newEmbeddings = await generateEmbeddingsBatch(
|
|
@@ -20374,6 +20427,7 @@ async function embedMany(texts, options, outer) {
|
|
|
20374
20427
|
const f32Embedding = Float32Array.from(newEmbeddings[i]);
|
|
20375
20428
|
results[uncachedIndices[i]] = Array.from(f32Embedding);
|
|
20376
20429
|
if (cache) {
|
|
20430
|
+
cachedEmbeddingModels.set(f32Embedding, embeddingModel);
|
|
20377
20431
|
cache.set(uncachedTexts[i], f32Embedding);
|
|
20378
20432
|
}
|
|
20379
20433
|
}
|
|
@@ -20498,6 +20552,37 @@ async function chunkAndEmbedMessage(ctx, messageId, options) {
|
|
|
20498
20552
|
}));
|
|
20499
20553
|
return updateMessageChunksOp(ctx, messageId, messageChunks, embeddingModel);
|
|
20500
20554
|
}
|
|
20555
|
+
var MIN_SEALED_EMBEDDING_HEX = 256;
|
|
20556
|
+
function rawHasEmbedding(value) {
|
|
20557
|
+
if (Array.isArray(value)) return value.length > 0;
|
|
20558
|
+
if (typeof value !== "string" || value.length === 0) return false;
|
|
20559
|
+
if (isEncrypted(value)) {
|
|
20560
|
+
return value.length - value.indexOf(":", 4) - 1 >= MIN_SEALED_EMBEDDING_HEX;
|
|
20561
|
+
}
|
|
20562
|
+
try {
|
|
20563
|
+
const parsed = JSON.parse(value);
|
|
20564
|
+
return Array.isArray(parsed) && parsed.length > 0;
|
|
20565
|
+
} catch {
|
|
20566
|
+
return false;
|
|
20567
|
+
}
|
|
20568
|
+
}
|
|
20569
|
+
function sealedVersion(value) {
|
|
20570
|
+
if (typeof value !== "string" || !isEncrypted(value)) return null;
|
|
20571
|
+
return value.startsWith("enc:v2:") ? "v2" : "v3";
|
|
20572
|
+
}
|
|
20573
|
+
function mayNeedChunkEmbedding(raw, embeddingModel, filter) {
|
|
20574
|
+
const role = raw.role;
|
|
20575
|
+
if (role === "system") return false;
|
|
20576
|
+
if (filter?.roles && !filter.roles.includes(role ?? "")) return false;
|
|
20577
|
+
if (isNonEmbeddableOrigin(raw.origin, filter?.reembedDiscarded)) {
|
|
20578
|
+
return false;
|
|
20579
|
+
}
|
|
20580
|
+
const model = raw.embedding_model;
|
|
20581
|
+
if (typeof model === "string" && model !== embeddingModel) return true;
|
|
20582
|
+
if (rawHasEmbedding(raw.chunks)) return false;
|
|
20583
|
+
if (rawHasEmbedding(raw.vector) && !filter?.rechunkExisting) return false;
|
|
20584
|
+
return true;
|
|
20585
|
+
}
|
|
20501
20586
|
async function chunkAndEmbedAllMessages(ctx, options, filter) {
|
|
20502
20587
|
const embeddingModel = options.model ?? DEFAULT_API_EMBEDDING_MODEL;
|
|
20503
20588
|
const { chunkSize = DEFAULT_CHUNK_SIZE } = options;
|
|
@@ -20510,11 +20595,31 @@ async function chunkAndEmbedAllMessages(ctx, options, filter) {
|
|
|
20510
20595
|
let considered = 0;
|
|
20511
20596
|
let sealedRowsSeen = 0;
|
|
20512
20597
|
let rowsSeen = 0;
|
|
20598
|
+
const keptSealed = /* @__PURE__ */ new Map();
|
|
20599
|
+
const candidatesStillSealed = /* @__PURE__ */ new Map();
|
|
20600
|
+
const droppedSealed = /* @__PURE__ */ new Map();
|
|
20601
|
+
const rawFilter = (raw) => {
|
|
20602
|
+
rowsSeen++;
|
|
20603
|
+
const keep = mayNeedChunkEmbedding(raw, embeddingModel, filter);
|
|
20604
|
+
const version = sealedVersion(raw.content);
|
|
20605
|
+
if (!version) return keep;
|
|
20606
|
+
if (keep) {
|
|
20607
|
+
keptSealed.set(version, (keptSealed.get(version) ?? 0) + 1);
|
|
20608
|
+
} else {
|
|
20609
|
+
const dropped = droppedSealed.get(version);
|
|
20610
|
+
if (dropped) dropped.count++;
|
|
20611
|
+
else droppedSealed.set(version, { count: 1, probeId: raw.id });
|
|
20612
|
+
}
|
|
20613
|
+
return keep;
|
|
20614
|
+
};
|
|
20513
20615
|
for (const conv of targetConversations) {
|
|
20514
|
-
const messages = await getMessagesOp(ctx, conv.conversationId);
|
|
20616
|
+
const messages = await getMessagesOp(ctx, conv.conversationId, { rawFilter });
|
|
20515
20617
|
for (const message of messages) {
|
|
20516
|
-
|
|
20517
|
-
if (
|
|
20618
|
+
const stillSealed = sealedVersion(message.content);
|
|
20619
|
+
if (stillSealed) {
|
|
20620
|
+
sealedRowsSeen++;
|
|
20621
|
+
candidatesStillSealed.set(stillSealed, (candidatesStillSealed.get(stillSealed) ?? 0) + 1);
|
|
20622
|
+
}
|
|
20518
20623
|
const isStale = message.embeddingModel !== void 0 && message.embeddingModel !== null && message.embeddingModel !== embeddingModel;
|
|
20519
20624
|
if (message.chunks && message.chunks.length > 0 && !isStale) continue;
|
|
20520
20625
|
const hasVector = message.vector && message.vector.length > 0;
|
|
@@ -20527,6 +20632,7 @@ async function chunkAndEmbedAllMessages(ctx, options, filter) {
|
|
|
20527
20632
|
stillEncrypted++;
|
|
20528
20633
|
continue;
|
|
20529
20634
|
}
|
|
20635
|
+
if (isToolResultsRow(message)) continue;
|
|
20530
20636
|
if (message.content.length < minLength) continue;
|
|
20531
20637
|
if (shouldChunkMessage(message.content, chunkSize)) {
|
|
20532
20638
|
longMessages.push({
|
|
@@ -20538,6 +20644,12 @@ async function chunkAndEmbedAllMessages(ctx, options, filter) {
|
|
|
20538
20644
|
}
|
|
20539
20645
|
}
|
|
20540
20646
|
}
|
|
20647
|
+
for (const [version, dropped] of droppedSealed) {
|
|
20648
|
+
const keyOpenedACandidate = (keptSealed.get(version) ?? 0) > (candidatesStillSealed.get(version) ?? 0);
|
|
20649
|
+
if (keyOpenedACandidate) continue;
|
|
20650
|
+
const probe = await getMessageOp(ctx, dropped.probeId);
|
|
20651
|
+
if (!probe || isEncrypted(probe.content)) sealedRowsSeen += dropped.count;
|
|
20652
|
+
}
|
|
20541
20653
|
if (stillEncrypted > 0 || sealedRowsSeen > 0) {
|
|
20542
20654
|
getLogger().error(
|
|
20543
20655
|
"memoryEngine: messages still encrypted (key unavailable?) \u2014 excluded from embedding",
|
|
@@ -27712,6 +27824,11 @@ function parseTopics(value) {
|
|
|
27712
27824
|
}
|
|
27713
27825
|
|
|
27714
27826
|
// src/lib/db/entities/operations.ts
|
|
27827
|
+
async function assertCanWrite(ctx) {
|
|
27828
|
+
if (ctx.canWrite && !await ctx.canWrite()) {
|
|
27829
|
+
throw new Error("Memory source is no longer eligible");
|
|
27830
|
+
}
|
|
27831
|
+
}
|
|
27715
27832
|
function entityToStored(e) {
|
|
27716
27833
|
return {
|
|
27717
27834
|
uniqueId: e.id,
|
|
@@ -27852,6 +27969,7 @@ async function linkMemoryEntitiesOp(ctx, memoryId, entityInputs, options) {
|
|
|
27852
27969
|
let skipped = false;
|
|
27853
27970
|
let entities = [];
|
|
27854
27971
|
await ctx.database.write(async () => {
|
|
27972
|
+
await assertCanWrite(ctx);
|
|
27855
27973
|
const {
|
|
27856
27974
|
entities: byName,
|
|
27857
27975
|
operations: entityOps,
|
|
@@ -27927,6 +28045,7 @@ async function replaceMemoryEntities(ctx, memoryId, entityInputs, options) {
|
|
|
27927
28045
|
let skipped = false;
|
|
27928
28046
|
let entities = [];
|
|
27929
28047
|
await ctx.database.write(async () => {
|
|
28048
|
+
await assertCanWrite(ctx);
|
|
27930
28049
|
const vaultRow = await findVaultRowInWrite(ctx, memoryId);
|
|
27931
28050
|
if (options.guarded && autoLinkBlocked(vaultRow)) {
|
|
27932
28051
|
skipped = true;
|
|
@@ -27987,6 +28106,7 @@ async function unlinkMemoryEntitiesOp(ctx, memoryIds) {
|
|
|
27987
28106
|
const links = await ctx.memoryEntityCollection.query(import_watermelondb18.Q.where("memory_id", import_watermelondb18.Q.oneOf(Array.from(memoryIds)))).fetch();
|
|
27988
28107
|
if (links.length === 0) return;
|
|
27989
28108
|
await ctx.database.write(async () => {
|
|
28109
|
+
await assertCanWrite(ctx);
|
|
27990
28110
|
await ctx.database.batch(...links.map((l) => l.prepareDestroyPermanently()));
|
|
27991
28111
|
});
|
|
27992
28112
|
}
|
|
@@ -27995,6 +28115,7 @@ async function unlinkAllMemoryEntitiesForUserOp(ctx, userId) {
|
|
|
27995
28115
|
const links = await ctx.memoryEntityCollection.query(import_watermelondb18.Q.where("user_id", userId)).fetch();
|
|
27996
28116
|
if (links.length === 0) return;
|
|
27997
28117
|
await ctx.database.write(async () => {
|
|
28118
|
+
await assertCanWrite(ctx);
|
|
27998
28119
|
await ctx.database.batch(...links.map((l) => l.prepareDestroyPermanently()));
|
|
27999
28120
|
});
|
|
28000
28121
|
}
|
|
@@ -28159,6 +28280,11 @@ function visibilityConditions(requested) {
|
|
|
28159
28280
|
function isKinded(record) {
|
|
28160
28281
|
return record.kind !== null && record.kind !== void 0;
|
|
28161
28282
|
}
|
|
28283
|
+
async function assertCanWrite2(ctx) {
|
|
28284
|
+
if (ctx.canWrite && !await ctx.canWrite()) {
|
|
28285
|
+
throw new Error("Memory source is no longer eligible");
|
|
28286
|
+
}
|
|
28287
|
+
}
|
|
28162
28288
|
function assertValidKindLevel(kind, level) {
|
|
28163
28289
|
const hasKind = kind !== null && kind !== void 0;
|
|
28164
28290
|
if (hasKind && !MEMORY_KINDS.includes(kind)) {
|
|
@@ -28339,8 +28465,7 @@ async function createVaultMemoryOp(ctx, opts) {
|
|
|
28339
28465
|
ctx.embeddedWalletSigner
|
|
28340
28466
|
) : opts.content;
|
|
28341
28467
|
const created = await ctx.database.write(async () => {
|
|
28342
|
-
|
|
28343
|
-
throw new Error("Memory source is no longer eligible");
|
|
28468
|
+
await assertCanWrite2(ctx);
|
|
28344
28469
|
return ctx.vaultMemoryCollection.create(
|
|
28345
28470
|
(record) => populateNewVaultMemory(record, ctx, opts, encryptedContent, encryptedKindValue)
|
|
28346
28471
|
);
|
|
@@ -28359,8 +28484,7 @@ async function createSupersedingMemoryOp(ctx, opts, targetId) {
|
|
|
28359
28484
|
) : opts.content;
|
|
28360
28485
|
let createdRecord = null;
|
|
28361
28486
|
await ctx.database.write(async () => {
|
|
28362
|
-
|
|
28363
|
-
throw new Error("Memory source is no longer eligible");
|
|
28487
|
+
await assertCanWrite2(ctx);
|
|
28364
28488
|
let target;
|
|
28365
28489
|
try {
|
|
28366
28490
|
target = await ctx.vaultMemoryCollection.find(targetId);
|
|
@@ -28452,8 +28576,7 @@ async function createVaultMemoriesBatchOp(ctx, optionsArray) {
|
|
|
28452
28576
|
})
|
|
28453
28577
|
);
|
|
28454
28578
|
const created = await ctx.database.write(async () => {
|
|
28455
|
-
|
|
28456
|
-
throw new Error("Memory source is no longer eligible");
|
|
28579
|
+
await assertCanWrite2(ctx);
|
|
28457
28580
|
const prepared = optionsArray.map(
|
|
28458
28581
|
(opts, i) => ctx.vaultMemoryCollection.prepareCreate(
|
|
28459
28582
|
(record) => populateNewVaultMemory(record, ctx, opts, encryptedContents[i], encryptedKindValues[i])
|
|
@@ -28744,8 +28867,7 @@ async function updateVaultMemoryOp(ctx, id, opts) {
|
|
|
28744
28867
|
const record = probe;
|
|
28745
28868
|
const originalUpdatedAt = record.updatedAt.getTime();
|
|
28746
28869
|
await ctx.database.write(async () => {
|
|
28747
|
-
|
|
28748
|
-
throw new Error("Memory source is no longer eligible");
|
|
28870
|
+
await assertCanWrite2(ctx);
|
|
28749
28871
|
if (record.isDeleted || record.supersededBy || !isOwnedByCtxUser(ctx, record) || opts.freeFormOnly && isKinded(record)) {
|
|
28750
28872
|
stale = true;
|
|
28751
28873
|
return;
|
|
@@ -28856,6 +28978,7 @@ async function setMemoryEntitiesOp(ctx, memoryId, entities) {
|
|
|
28856
28978
|
let stale = false;
|
|
28857
28979
|
const originalUpdatedAt = record.updatedAt.getTime();
|
|
28858
28980
|
await ctx.database.write(async (writer) => {
|
|
28981
|
+
await assertCanWrite2(ctx);
|
|
28859
28982
|
if (record.isDeleted || !isOwnedByCtxUser(ctx, record)) {
|
|
28860
28983
|
stale = true;
|
|
28861
28984
|
return;
|
|
@@ -28897,6 +29020,7 @@ async function clearMemoryTopicsOverrideOp(ctx, memoryId, options) {
|
|
|
28897
29020
|
const originalUpdatedAt = record.updatedAt.getTime();
|
|
28898
29021
|
let cleared = false;
|
|
28899
29022
|
await ctx.database.write(async () => {
|
|
29023
|
+
await assertCanWrite2(ctx);
|
|
28900
29024
|
if (options?.unlessTopicsRecorded && parseTopics(record.topics) !== null) return;
|
|
28901
29025
|
cleared = true;
|
|
28902
29026
|
await record.update((r) => {
|
|
@@ -28920,6 +29044,7 @@ async function setMemoryVisibilityOp(ctx, id, opts) {
|
|
|
28920
29044
|
if (record.isDeleted || !isOwnedByCtxUser(ctx, record)) return null;
|
|
28921
29045
|
let stale = false;
|
|
28922
29046
|
await ctx.database.write(async () => {
|
|
29047
|
+
await assertCanWrite2(ctx);
|
|
28923
29048
|
if (record.isDeleted || !isOwnedByCtxUser(ctx, record)) {
|
|
28924
29049
|
stale = true;
|
|
28925
29050
|
return;
|
|
@@ -28948,6 +29073,7 @@ async function deleteVaultMemoryOp(ctx, id) {
|
|
|
28948
29073
|
if (record.isDeleted || !isOwnedByCtxUser(ctx, record)) return false;
|
|
28949
29074
|
let stale = false;
|
|
28950
29075
|
await ctx.database.write(async () => {
|
|
29076
|
+
await assertCanWrite2(ctx);
|
|
28951
29077
|
if (record.isDeleted || !isOwnedByCtxUser(ctx, record)) {
|
|
28952
29078
|
stale = true;
|
|
28953
29079
|
return;
|
|
@@ -28985,8 +29111,7 @@ async function supersedeVaultMemoryOp(ctx, id, supersededById) {
|
|
|
28985
29111
|
}
|
|
28986
29112
|
let stale = false;
|
|
28987
29113
|
await ctx.database.write(async () => {
|
|
28988
|
-
|
|
28989
|
-
throw new Error("Memory source is no longer eligible");
|
|
29114
|
+
await assertCanWrite2(ctx);
|
|
28990
29115
|
if (record.isDeleted || record.supersededBy || !isOwnedByCtxUser(ctx, record)) {
|
|
28991
29116
|
stale = true;
|
|
28992
29117
|
return;
|
|
@@ -29148,6 +29273,7 @@ async function stampTopicsExtractedAtOp(ctx, memoryIds, extractedAt, version = T
|
|
|
29148
29273
|
for (let i = 0; i < uniqueIds.length; i += CHUNK) {
|
|
29149
29274
|
const chunkIds = uniqueIds.slice(i, i + CHUNK);
|
|
29150
29275
|
await ctx.database.write(async () => {
|
|
29276
|
+
await assertCanWrite2(ctx);
|
|
29151
29277
|
const records = [];
|
|
29152
29278
|
for (const id of chunkIds) {
|
|
29153
29279
|
try {
|
|
@@ -29181,6 +29307,7 @@ async function relinkMemoryTopicsOp(ctx, memoryIds) {
|
|
|
29181
29307
|
for (const id of Array.from(new Set(memoryIds))) {
|
|
29182
29308
|
try {
|
|
29183
29309
|
await ctx.database.write(async (writer) => {
|
|
29310
|
+
await assertCanWrite2(ctx);
|
|
29184
29311
|
let record;
|
|
29185
29312
|
try {
|
|
29186
29313
|
record = await ctx.vaultMemoryCollection.find(id);
|
|
@@ -29211,6 +29338,7 @@ async function backfillMemoryTopicsOp(ctx, memoryIds) {
|
|
|
29211
29338
|
for (let i = 0; i < uniqueIds.length; i += CHUNK) {
|
|
29212
29339
|
const chunkIds = uniqueIds.slice(i, i + CHUNK);
|
|
29213
29340
|
await ctx.database.write(async () => {
|
|
29341
|
+
await assertCanWrite2(ctx);
|
|
29214
29342
|
const writes = [];
|
|
29215
29343
|
for (const id of chunkIds) {
|
|
29216
29344
|
let record;
|
|
@@ -29243,6 +29371,7 @@ async function deleteAllVaultMemoriesForUserOp(ctx, userId) {
|
|
|
29243
29371
|
const records = await ctx.vaultMemoryCollection.query(import_watermelondb19.Q.where("user_id", userId), import_watermelondb19.Q.where("is_deleted", false)).fetch();
|
|
29244
29372
|
if (records.length === 0) return 0;
|
|
29245
29373
|
await ctx.database.write(async () => {
|
|
29374
|
+
await assertCanWrite2(ctx);
|
|
29246
29375
|
const prepared = records.map(
|
|
29247
29376
|
(record) => record.prepareUpdate((r) => {
|
|
29248
29377
|
r._setRaw("is_deleted", true);
|
|
@@ -29297,6 +29426,7 @@ async function archiveVaultMemoryOp(ctx, id, opts) {
|
|
|
29297
29426
|
let stale = false;
|
|
29298
29427
|
const archivedAtValue = opts?.now ?? Date.now();
|
|
29299
29428
|
await ctx.database.write(async () => {
|
|
29429
|
+
await assertCanWrite2(ctx);
|
|
29300
29430
|
if (record.isDeleted || !isOwnedByCtxUser(ctx, record) || record.archivedAt !== null) {
|
|
29301
29431
|
stale = true;
|
|
29302
29432
|
return;
|
|
@@ -29320,6 +29450,7 @@ async function restoreVaultMemoryOp(ctx, id) {
|
|
|
29320
29450
|
if (record.isDeleted || !isOwnedByCtxUser(ctx, record)) return false;
|
|
29321
29451
|
let stale = false;
|
|
29322
29452
|
await ctx.database.write(async () => {
|
|
29453
|
+
await assertCanWrite2(ctx);
|
|
29323
29454
|
if (record.isDeleted || !isOwnedByCtxUser(ctx, record)) {
|
|
29324
29455
|
stale = true;
|
|
29325
29456
|
return;
|
|
@@ -29340,6 +29471,7 @@ async function hardDeleteDecayedOp(ctx, id, opts) {
|
|
|
29340
29471
|
const now = opts.now ?? Date.now();
|
|
29341
29472
|
let stale = false;
|
|
29342
29473
|
await ctx.database.write(async () => {
|
|
29474
|
+
await assertCanWrite2(ctx);
|
|
29343
29475
|
const archivedAt = record.archivedAt;
|
|
29344
29476
|
if (record.isDeleted || !isOwnedByCtxUser(ctx, record) || archivedAt === null || now - archivedAt <= opts.hardDeleteWindowMs) {
|
|
29345
29477
|
stale = true;
|
|
@@ -29379,6 +29511,7 @@ async function updateVaultMemoryEmbeddingOp(ctx, id, embedding, embeddingModel,
|
|
|
29379
29511
|
}
|
|
29380
29512
|
let written = false;
|
|
29381
29513
|
await ctx.database.write(async () => {
|
|
29514
|
+
await assertCanWrite2(ctx);
|
|
29382
29515
|
if (record.isDeleted || !isOwnedByCtxUser(ctx, record)) return;
|
|
29383
29516
|
const originalUpdatedAt = record.updatedAt.getTime();
|
|
29384
29517
|
if (originalUpdatedAt !== readUpdatedAt || record._getRaw("content") !== readStoredContent)
|
|
@@ -33071,6 +33204,13 @@ function restoreCandidates(candidates, redactor, ownNames) {
|
|
|
33071
33204
|
).map((c) => c.candidate);
|
|
33072
33205
|
}
|
|
33073
33206
|
async function extractAndRetain(messages, retainCtx, options) {
|
|
33207
|
+
const { memoryStore, signal } = options;
|
|
33208
|
+
if (memoryStore === null) throw new Error("Memory store is not ready");
|
|
33209
|
+
if (memoryStore && options.folderId !== void 0 && options.folderId !== null)
|
|
33210
|
+
throw new Error("Remote memory extraction does not support folders");
|
|
33211
|
+
if (memoryStore && options.extract.piiRedaction && !memoryStore.masksEmbeddingInput)
|
|
33212
|
+
throw new Error("PII-redacted extraction requires a memory store that masks embedding inputs");
|
|
33213
|
+
signal?.throwIfAborted();
|
|
33074
33214
|
const minConfidence = options.minConfidence ?? DEFAULT_MIN_CONFIDENCE;
|
|
33075
33215
|
const resolvedConsolidatePii = options.consolidateOptions?.piiRedaction ?? options.extract.piiRedaction;
|
|
33076
33216
|
const consolidateOptions = options.consolidateOptions !== void 0 ? {
|
|
@@ -33104,6 +33244,7 @@ async function extractAndRetain(messages, retainCtx, options) {
|
|
|
33104
33244
|
}
|
|
33105
33245
|
});
|
|
33106
33246
|
const extractMs = Date.now() - tExtract;
|
|
33247
|
+
signal?.throwIfAborted();
|
|
33107
33248
|
const filtered = candidates.filter((c) => c.confidence >= minConfidence);
|
|
33108
33249
|
const log = getLogger();
|
|
33109
33250
|
const screened = screenCandidatesForInjection(filtered);
|
|
@@ -33151,16 +33292,33 @@ async function extractAndRetain(messages, retainCtx, options) {
|
|
|
33151
33292
|
const results = [];
|
|
33152
33293
|
const quarantinedInfo = [];
|
|
33153
33294
|
let failedWrites = 0;
|
|
33295
|
+
let auditRows;
|
|
33154
33296
|
const tRetain = Date.now();
|
|
33155
33297
|
for (const { candidate, isQuarantined, reason, signature } of toRetain) {
|
|
33156
33298
|
try {
|
|
33299
|
+
signal?.throwIfAborted();
|
|
33157
33300
|
if (isQuarantined) {
|
|
33158
|
-
|
|
33159
|
-
|
|
33160
|
-
|
|
33161
|
-
|
|
33162
|
-
|
|
33163
|
-
|
|
33301
|
+
let existingId;
|
|
33302
|
+
if (memoryStore) {
|
|
33303
|
+
auditRows ?? (auditRows = memoryStore.list({
|
|
33304
|
+
scopes: [options.scope ?? "private"],
|
|
33305
|
+
includeArchived: true,
|
|
33306
|
+
includeQuarantined: true,
|
|
33307
|
+
includeSuperseded: true
|
|
33308
|
+
}));
|
|
33309
|
+
const sourceKey = [...new Set(candidate.sourceMessageIds)].sort().join("\0");
|
|
33310
|
+
const normalize = (value) => value.normalize("NFKC").trim().replace(/\s+/g, " ").toLowerCase();
|
|
33311
|
+
existingId = (await auditRows).find(
|
|
33312
|
+
(row) => row.trustTier === "quarantined" && row.scope === (options.scope ?? "private") && [...new Set(row.sourceChunkIds ?? [])].sort().join("\0") === sourceKey && normalize(row.content) === normalize(candidate.content)
|
|
33313
|
+
)?.uniqueId ?? null;
|
|
33314
|
+
} else {
|
|
33315
|
+
existingId = await findQuarantinedDuplicateOp(
|
|
33316
|
+
retainCtx.vaultCtx,
|
|
33317
|
+
candidate.content,
|
|
33318
|
+
candidate.sourceMessageIds,
|
|
33319
|
+
{ scope: options.scope ?? "private", folderId: options.folderId ?? null }
|
|
33320
|
+
).catch(() => null);
|
|
33321
|
+
}
|
|
33164
33322
|
if (existingId) {
|
|
33165
33323
|
quarantinedInfo.push({
|
|
33166
33324
|
candidate,
|
|
@@ -33171,18 +33329,26 @@ async function extractAndRetain(messages, retainCtx, options) {
|
|
|
33171
33329
|
continue;
|
|
33172
33330
|
}
|
|
33173
33331
|
}
|
|
33174
|
-
const
|
|
33332
|
+
const retainOptions = {
|
|
33175
33333
|
source: "auto-extracted",
|
|
33176
33334
|
sourceChunkIds: candidate.sourceMessageIds,
|
|
33177
33335
|
respectTombstones: true,
|
|
33178
33336
|
...options.scope !== void 0 && { scope: options.scope },
|
|
33179
|
-
...options.folderId !== void 0 && { folderId: options.folderId },
|
|
33180
33337
|
...consolidateOptions !== void 0 && { consolidateOptions },
|
|
33181
33338
|
...candidate.eventTime !== null && { eventTime: candidate.eventTime },
|
|
33182
33339
|
factType: candidate.type,
|
|
33183
33340
|
...isQuarantined && { trustTier: "quarantined", enableAutoMerge: false }
|
|
33341
|
+
};
|
|
33342
|
+
const result = memoryStore ? await memoryStore.retain(candidate.content, {
|
|
33343
|
+
...retainOptions,
|
|
33344
|
+
canWrite: retainCtx.vaultCtx.canWrite,
|
|
33345
|
+
signal
|
|
33346
|
+
}) : await retain(candidate.content, retainCtx, {
|
|
33347
|
+
...retainOptions,
|
|
33348
|
+
...options.folderId !== void 0 && { folderId: options.folderId }
|
|
33184
33349
|
});
|
|
33185
33350
|
if (isQuarantined) {
|
|
33351
|
+
auditRows = void 0;
|
|
33186
33352
|
const info = {
|
|
33187
33353
|
candidate,
|
|
33188
33354
|
memoryId: result.memoryId,
|
|
@@ -33201,9 +33367,16 @@ async function extractAndRetain(messages, retainCtx, options) {
|
|
|
33201
33367
|
}
|
|
33202
33368
|
succeededCandidates.push(candidate);
|
|
33203
33369
|
results.push(result);
|
|
33204
|
-
if (result.action !== "suppressed" &&
|
|
33370
|
+
if (result.action !== "suppressed" && candidate.entities.length > 0) {
|
|
33205
33371
|
try {
|
|
33206
|
-
|
|
33372
|
+
signal?.throwIfAborted();
|
|
33373
|
+
if (memoryStore) {
|
|
33374
|
+
await memoryStore.addTopics(result.memoryId, candidate.entities, {
|
|
33375
|
+
unlessUserManaged: true,
|
|
33376
|
+
canWrite: retainCtx.vaultCtx.canWrite,
|
|
33377
|
+
signal
|
|
33378
|
+
});
|
|
33379
|
+
} else if (options.entityCtx && !await isMemoryTopicsUserManaged(options.entityCtx, result.memoryId)) {
|
|
33207
33380
|
await linkMemoryEntitiesOp(options.entityCtx, result.memoryId, candidate.entities, {
|
|
33208
33381
|
unlessTopicsUserManaged: true
|
|
33209
33382
|
});
|
|
@@ -33453,7 +33626,7 @@ function createAutoExtractor(options) {
|
|
|
33453
33626
|
};
|
|
33454
33627
|
const consolidateOptions = options.consolidate ? { ...options.consolidate, ...subPassAuth(options.consolidate.baseUrl) } : void 0;
|
|
33455
33628
|
const injectionClassifierOptions = options.injectionClassifier ? { ...options.injectionClassifier, ...subPassAuth(options.injectionClassifier.baseUrl) } : void 0;
|
|
33456
|
-
if (options.retainCtx.vaultCtx.entityCtx && !options.entityCtx) {
|
|
33629
|
+
if (!options.memoryStore && options.retainCtx.vaultCtx.entityCtx && !options.entityCtx) {
|
|
33457
33630
|
getLogger().warn(
|
|
33458
33631
|
"[memory/extract] retainCtx.vaultCtx.entityCtx is set but extractor was created without `entityCtx` \u2014 W5 graph lane will receive no writes"
|
|
33459
33632
|
);
|
|
@@ -33498,6 +33671,8 @@ function createAutoExtractor(options) {
|
|
|
33498
33671
|
try {
|
|
33499
33672
|
const { candidates, results, failedCount, outcome, failure, funnel, timings, model } = await extractAndRetain(window2, retainCtx, {
|
|
33500
33673
|
extract,
|
|
33674
|
+
memoryStore: options.memoryStore,
|
|
33675
|
+
signal: options.signal,
|
|
33501
33676
|
...options.minConfidence !== void 0 && { minConfidence: options.minConfidence },
|
|
33502
33677
|
...options.entityCtx !== void 0 && { entityCtx: options.entityCtx },
|
|
33503
33678
|
...options.scope !== void 0 && { scope: options.scope },
|
|
@@ -34158,7 +34333,7 @@ var MaskScopedEmbeddingCache = class extends Map {
|
|
|
34158
34333
|
return this;
|
|
34159
34334
|
}
|
|
34160
34335
|
};
|
|
34161
|
-
var scopedViews =
|
|
34336
|
+
var { scopedViews } = getEmbeddingCacheState();
|
|
34162
34337
|
function maskScopedEmbeddingCache(cache, masked) {
|
|
34163
34338
|
const views = scopedViews.get(cache) ?? {};
|
|
34164
34339
|
scopedViews.set(cache, views);
|
|
@@ -34583,44 +34758,48 @@ async function recall(query, ctx, options = {}) {
|
|
|
34583
34758
|
embeddingOptions,
|
|
34584
34759
|
ctx.vaultCache,
|
|
34585
34760
|
searchOptions
|
|
34586
|
-
)))(
|
|
34587
|
-
|
|
34588
|
-
|
|
34589
|
-
|
|
34590
|
-
|
|
34591
|
-
|
|
34592
|
-
|
|
34593
|
-
|
|
34594
|
-
|
|
34595
|
-
|
|
34596
|
-
|
|
34597
|
-
|
|
34598
|
-
|
|
34599
|
-
|
|
34600
|
-
|
|
34601
|
-
|
|
34602
|
-
|
|
34603
|
-
|
|
34604
|
-
|
|
34605
|
-
|
|
34606
|
-
|
|
34607
|
-
|
|
34608
|
-
|
|
34609
|
-
|
|
34761
|
+
)))(
|
|
34762
|
+
query,
|
|
34763
|
+
{
|
|
34764
|
+
limit: types.includes("chunk") ? Math.max(limit * 2, 16) : limit,
|
|
34765
|
+
minSimilarity: vaultMinScore,
|
|
34766
|
+
useFusion: true,
|
|
34767
|
+
rerank: flags.rerank,
|
|
34768
|
+
...options.rerankTopN !== void 0 && { rerankTopN: options.rerankTopN },
|
|
34769
|
+
...options.ceWeight !== void 0 && { ceWeight: options.ceWeight },
|
|
34770
|
+
...options.rerankLoadTimeoutMs !== void 0 && {
|
|
34771
|
+
rerankLoadTimeoutMs: options.rerankLoadTimeoutMs
|
|
34772
|
+
},
|
|
34773
|
+
...options.recencyAlpha !== void 0 && { recencyAlpha: options.recencyAlpha },
|
|
34774
|
+
...options.recency && { recency: options.recency },
|
|
34775
|
+
...options.mmr !== void 0 && { mmr: options.mmr },
|
|
34776
|
+
...options.supersessionBoost !== void 0 && {
|
|
34777
|
+
supersessionBoost: options.supersessionBoost
|
|
34778
|
+
},
|
|
34779
|
+
...options.supersessionWindow !== void 0 && {
|
|
34780
|
+
supersessionWindow: options.supersessionWindow
|
|
34781
|
+
},
|
|
34782
|
+
...options.proofCountAlpha !== void 0 && {
|
|
34783
|
+
proofCountAlpha: options.proofCountAlpha
|
|
34784
|
+
},
|
|
34785
|
+
...options.bm25AdmissionDivisor !== void 0 && {
|
|
34786
|
+
bm25AdmissionDivisor: options.bm25AdmissionDivisor
|
|
34787
|
+
},
|
|
34788
|
+
...options.rrfK !== void 0 && { rrfK: options.rrfK },
|
|
34789
|
+
...options.decryptLast !== void 0 && { decryptLast: options.decryptLast },
|
|
34790
|
+
...subQueries && { subQueries },
|
|
34791
|
+
...options.scopes && { scopes: options.scopes },
|
|
34792
|
+
...options.folderId !== void 0 && { folderId: options.folderId },
|
|
34793
|
+
...options.factTypes?.length && { factTypes: options.factTypes },
|
|
34794
|
+
...options.memoryIds !== void 0 && { memoryIds: options.memoryIds },
|
|
34795
|
+
...options.factTypeWeights && { factTypeWeights: options.factTypeWeights },
|
|
34796
|
+
...entityRanking.length > 0 && { entityRanking },
|
|
34797
|
+
...temporalRanking.length > 0 && { temporalRanking },
|
|
34798
|
+
...needsChunkEmbedding && { queryEmbedding: queryEmbedding ?? [] },
|
|
34799
|
+
queryEmbedTotalTimeoutMs
|
|
34610
34800
|
},
|
|
34611
|
-
|
|
34612
|
-
|
|
34613
|
-
...subQueries && { subQueries },
|
|
34614
|
-
...options.scopes && { scopes: options.scopes },
|
|
34615
|
-
...options.folderId !== void 0 && { folderId: options.folderId },
|
|
34616
|
-
...options.factTypes?.length && { factTypes: options.factTypes },
|
|
34617
|
-
...options.memoryIds !== void 0 && { memoryIds: options.memoryIds },
|
|
34618
|
-
...options.factTypeWeights && { factTypeWeights: options.factTypeWeights },
|
|
34619
|
-
...entityRanking.length > 0 && { entityRanking },
|
|
34620
|
-
...temporalRanking.length > 0 && { temporalRanking },
|
|
34621
|
-
...needsChunkEmbedding && { queryEmbedding: queryEmbedding ?? [] },
|
|
34622
|
-
queryEmbedTotalTimeoutMs
|
|
34623
|
-
});
|
|
34801
|
+
options.embeddingCache
|
|
34802
|
+
);
|
|
34624
34803
|
factResults.push(
|
|
34625
34804
|
...dedupeBy(
|
|
34626
34805
|
results,
|
|
@@ -35625,6 +35804,7 @@ function createLocalMemoryStore(options) {
|
|
|
35625
35804
|
database,
|
|
35626
35805
|
entityCollection: database.get("entity"),
|
|
35627
35806
|
memoryEntityCollection: database.get("memory_entity"),
|
|
35807
|
+
canWrite: options.canWrite,
|
|
35628
35808
|
...userId !== void 0 && { userId },
|
|
35629
35809
|
...options.allowUnscopedRows !== void 0 && {
|
|
35630
35810
|
allowUnscopedRows: options.allowUnscopedRows
|
|
@@ -35636,10 +35816,21 @@ function createLocalMemoryStore(options) {
|
|
|
35636
35816
|
walletAddress: options.walletAddress,
|
|
35637
35817
|
signMessage: options.signMessage,
|
|
35638
35818
|
embeddedWalletSigner: options.embeddedWalletSigner,
|
|
35819
|
+
canWrite: options.canWrite,
|
|
35639
35820
|
...userId !== void 0 && { userId },
|
|
35640
35821
|
...options.singleTenant !== void 0 && { singleTenant: options.singleTenant },
|
|
35641
35822
|
entityCtx
|
|
35642
35823
|
};
|
|
35824
|
+
const assertWrite = async (writeOptions) => {
|
|
35825
|
+
writeOptions?.signal?.throwIfAborted();
|
|
35826
|
+
if (writeOptions?.canWrite && !await writeOptions.canWrite()) {
|
|
35827
|
+
throw new Error("Memory source is no longer eligible");
|
|
35828
|
+
}
|
|
35829
|
+
if (options.canWrite && !await options.canWrite()) {
|
|
35830
|
+
throw new Error("Memory source is no longer eligible");
|
|
35831
|
+
}
|
|
35832
|
+
writeOptions?.signal?.throwIfAborted();
|
|
35833
|
+
};
|
|
35643
35834
|
const vaultCache = options.vaultCache ?? createVaultEmbeddingCache();
|
|
35644
35835
|
const ownedBy = userId !== void 0 ? [import_watermelondb24.Q.where("user_id", userId)] : [];
|
|
35645
35836
|
const linksOwnedBy = userId === void 0 ? [] : options.allowUnscopedRows ? [import_watermelondb24.Q.or(import_watermelondb24.Q.where("user_id", userId), import_watermelondb24.Q.where("user_id", null))] : [import_watermelondb24.Q.where("user_id", userId)];
|
|
@@ -35751,9 +35942,25 @@ function createLocalMemoryStore(options) {
|
|
|
35751
35942
|
archive: (id) => archiveVaultMemoryOp(vaultCtx, id),
|
|
35752
35943
|
restore: (id) => restoreVaultMemoryOp(vaultCtx, id),
|
|
35753
35944
|
setTopics: (memoryId, topics) => setMemoryEntitiesOp(vaultCtx, memoryId, topics),
|
|
35754
|
-
addTopics: (memoryId, topics) => database.write(async (writer) => {
|
|
35945
|
+
addTopics: (memoryId, topics, writeOptions) => database.write(async (writer) => {
|
|
35946
|
+
await assertWrite(writeOptions);
|
|
35755
35947
|
const owned = await vaultCtx.vaultMemoryCollection.query(import_watermelondb24.Q.where("id", memoryId), import_watermelondb24.Q.where("is_deleted", false), ...ownedBy).fetchCount();
|
|
35756
|
-
return owned > 0 ? writer.callWriter(
|
|
35948
|
+
return owned > 0 ? writer.callWriter(
|
|
35949
|
+
() => linkMemoryEntitiesOp(
|
|
35950
|
+
{
|
|
35951
|
+
...entityCtx,
|
|
35952
|
+
canWrite: async () => {
|
|
35953
|
+
await assertWrite(writeOptions);
|
|
35954
|
+
return true;
|
|
35955
|
+
}
|
|
35956
|
+
},
|
|
35957
|
+
memoryId,
|
|
35958
|
+
topics,
|
|
35959
|
+
{
|
|
35960
|
+
unlessTopicsUserManaged: writeOptions?.unlessUserManaged
|
|
35961
|
+
}
|
|
35962
|
+
)
|
|
35963
|
+
) : [];
|
|
35757
35964
|
}),
|
|
35758
35965
|
setVisibility: (id, visibility, visibilityOptions) => setMemoryVisibilityOp(vaultCtx, id, { visibility, ...visibilityOptions }),
|
|
35759
35966
|
recall: (query, recallOptions) => recall(
|
|
@@ -35763,14 +35970,33 @@ function createLocalMemoryStore(options) {
|
|
|
35763
35970
|
),
|
|
35764
35971
|
retain: (content, retainOptions) => retain(
|
|
35765
35972
|
content,
|
|
35766
|
-
{
|
|
35973
|
+
{
|
|
35974
|
+
vaultCtx: {
|
|
35975
|
+
...vaultCtx,
|
|
35976
|
+
canWrite: async () => {
|
|
35977
|
+
await assertWrite(retainOptions);
|
|
35978
|
+
return true;
|
|
35979
|
+
}
|
|
35980
|
+
},
|
|
35981
|
+
embeddingOptions: options.embeddingOptions,
|
|
35982
|
+
vaultCache
|
|
35983
|
+
},
|
|
35767
35984
|
retainOptions
|
|
35768
35985
|
),
|
|
35769
35986
|
factSource: {
|
|
35770
|
-
search: (query, searchOptions) => searchVaultMemoriesWithSize(
|
|
35987
|
+
search: (query, searchOptions, embeddingCache) => searchVaultMemoriesWithSize(
|
|
35771
35988
|
query,
|
|
35772
35989
|
vaultCtx,
|
|
35773
|
-
{
|
|
35990
|
+
{
|
|
35991
|
+
...options.embeddingOptions,
|
|
35992
|
+
taskType: "memory_recall_embed",
|
|
35993
|
+
...embeddingCache && !options.embeddingOptions.cache && {
|
|
35994
|
+
cache: maskScopedEmbeddingCache(
|
|
35995
|
+
embeddingCache,
|
|
35996
|
+
Boolean(options.embeddingOptions.maskInput)
|
|
35997
|
+
)
|
|
35998
|
+
}
|
|
35999
|
+
},
|
|
35774
36000
|
vaultCache,
|
|
35775
36001
|
searchOptions
|
|
35776
36002
|
),
|
|
@@ -36606,6 +36832,7 @@ function createDurableAutoExtractor(options) {
|
|
|
36606
36832
|
};
|
|
36607
36833
|
const folderId = options.folderId ?? null;
|
|
36608
36834
|
let disposed = false;
|
|
36835
|
+
let activeBatch = null;
|
|
36609
36836
|
let running = false;
|
|
36610
36837
|
let wakeRequested = false;
|
|
36611
36838
|
let timer;
|
|
@@ -36642,14 +36869,18 @@ function createDurableAutoExtractor(options) {
|
|
|
36642
36869
|
}, delay);
|
|
36643
36870
|
}
|
|
36644
36871
|
async function extractBatch(messages, conversationId, ids, jobScope, jobFolderId) {
|
|
36872
|
+
if (disposed) throw new Error("Extraction session was disposed");
|
|
36645
36873
|
let watchdog;
|
|
36646
36874
|
let cancelled = false;
|
|
36875
|
+
const controller = new AbortController();
|
|
36876
|
+
activeBatch = controller;
|
|
36647
36877
|
const model = options.modelForScope?.(jobScope) ?? options.extract.model;
|
|
36648
36878
|
try {
|
|
36649
36879
|
return await Promise.race([
|
|
36650
36880
|
new Promise((resolve, reject) => {
|
|
36651
36881
|
const worker = createAutoExtractor({
|
|
36652
36882
|
...options,
|
|
36883
|
+
signal: controller.signal,
|
|
36653
36884
|
retainCtx: {
|
|
36654
36885
|
...options.retainCtx,
|
|
36655
36886
|
vaultCtx: {
|
|
@@ -36678,6 +36909,8 @@ function createDurableAutoExtractor(options) {
|
|
|
36678
36909
|
]);
|
|
36679
36910
|
} finally {
|
|
36680
36911
|
cancelled = true;
|
|
36912
|
+
controller.abort();
|
|
36913
|
+
if (activeBatch === controller) activeBatch = null;
|
|
36681
36914
|
if (watchdog !== void 0) clearTimeout(watchdog);
|
|
36682
36915
|
}
|
|
36683
36916
|
}
|
|
@@ -36689,6 +36922,7 @@ function createDurableAutoExtractor(options) {
|
|
|
36689
36922
|
for (const message of loaded)
|
|
36690
36923
|
if (message && message.messageId > 0) sequences.set(message.uniqueId, message.messageId);
|
|
36691
36924
|
await database.write(async () => {
|
|
36925
|
+
if (disposed) return;
|
|
36692
36926
|
const current = idsOf(job);
|
|
36693
36927
|
const acknowledged = ids.filter((id) => current.includes(id));
|
|
36694
36928
|
if (!acknowledged.length) return;
|
|
@@ -36861,6 +37095,7 @@ function createDurableAutoExtractor(options) {
|
|
|
36861
37095
|
jobScope,
|
|
36862
37096
|
jobFolderId
|
|
36863
37097
|
);
|
|
37098
|
+
if (disposed) throw new Error("Extraction session was disposed");
|
|
36864
37099
|
options.onTurnComplete?.(result);
|
|
36865
37100
|
return result;
|
|
36866
37101
|
};
|
|
@@ -36897,6 +37132,7 @@ function createDurableAutoExtractor(options) {
|
|
|
36897
37132
|
);
|
|
36898
37133
|
scheduleAfterSuccess = true;
|
|
36899
37134
|
} catch (error) {
|
|
37135
|
+
if (disposed) break;
|
|
36900
37136
|
attempts.set(job.id, attempted + 1);
|
|
36901
37137
|
retry = true;
|
|
36902
37138
|
reportError(error, conversationId);
|
|
@@ -36919,6 +37155,14 @@ function createDurableAutoExtractor(options) {
|
|
|
36919
37155
|
schedule(retry ? options.retryDelayMs ?? 3e4 : 0);
|
|
36920
37156
|
}
|
|
36921
37157
|
}
|
|
37158
|
+
function dispose() {
|
|
37159
|
+
disposed = true;
|
|
37160
|
+
activeBatch?.abort(options.signal?.reason);
|
|
37161
|
+
if (timer !== void 0) clearTimeout(timer);
|
|
37162
|
+
options.signal?.removeEventListener("abort", dispose);
|
|
37163
|
+
}
|
|
37164
|
+
if (options.signal?.aborted) dispose();
|
|
37165
|
+
else options.signal?.addEventListener("abort", dispose, { once: true });
|
|
36922
37166
|
schedule(0);
|
|
36923
37167
|
return {
|
|
36924
37168
|
processTurn(messages, conversationId) {
|
|
@@ -36998,10 +37242,7 @@ function createDurableAutoExtractor(options) {
|
|
|
36998
37242
|
return true;
|
|
36999
37243
|
},
|
|
37000
37244
|
isProcessing: () => running,
|
|
37001
|
-
dispose
|
|
37002
|
-
disposed = true;
|
|
37003
|
-
if (timer !== void 0) clearTimeout(timer);
|
|
37004
|
-
}
|
|
37245
|
+
dispose
|
|
37005
37246
|
};
|
|
37006
37247
|
}
|
|
37007
37248
|
|