@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.mjs
CHANGED
|
@@ -2681,8 +2681,9 @@ async function getConversationsByProjectOp(ctx, projectId) {
|
|
|
2681
2681
|
)
|
|
2682
2682
|
);
|
|
2683
2683
|
}
|
|
2684
|
-
async function getMessagesOp(ctx, convId) {
|
|
2685
|
-
const
|
|
2684
|
+
async function getMessagesOp(ctx, convId, opts) {
|
|
2685
|
+
const fetched = await ctx.messagesCollection.query(Q.where("conversation_id", convId), Q.sortBy("message_id", Q.asc)).unsafeFetchRaw();
|
|
2686
|
+
const results = opts?.rawFilter ? fetched.filter(opts.rawFilter) : fetched;
|
|
2686
2687
|
return Promise.all(
|
|
2687
2688
|
results.map(
|
|
2688
2689
|
(raw) => messageRawToStored(raw, ctx.walletAddress, ctx.signMessage, ctx.embeddedWalletSigner)
|
|
@@ -4536,6 +4537,22 @@ var postApiV1WalletsBinding = (options) => (options.client ?? client).post({
|
|
|
4536
4537
|
var postApiV1WalletsBindingNonce = (options) => (options?.client ?? client).post({ url: "/api/v1/wallets/binding/nonce", ...options });
|
|
4537
4538
|
var deleteApiV1WalletsBindingByAddress = (options) => (options.client ?? client).delete({ url: "/api/v1/wallets/binding/{address}", ...options });
|
|
4538
4539
|
|
|
4540
|
+
// src/lib/memoryEngine/embeddingCacheState.ts
|
|
4541
|
+
var EMBEDDING_CACHE_STATE_KEY = /* @__PURE__ */ Symbol.for("@anuma/sdk/embedding-cache/v1");
|
|
4542
|
+
var cacheGlobal = globalThis;
|
|
4543
|
+
var fallbackState = {
|
|
4544
|
+
scopedViews: /* @__PURE__ */ new WeakMap(),
|
|
4545
|
+
inFlightByCache: /* @__PURE__ */ new WeakMap(),
|
|
4546
|
+
cachedEmbeddingModels: /* @__PURE__ */ new WeakMap()
|
|
4547
|
+
};
|
|
4548
|
+
function getEmbeddingCacheState() {
|
|
4549
|
+
try {
|
|
4550
|
+
return cacheGlobal[EMBEDDING_CACHE_STATE_KEY] ?? (cacheGlobal[EMBEDDING_CACHE_STATE_KEY] = fallbackState);
|
|
4551
|
+
} catch {
|
|
4552
|
+
return fallbackState;
|
|
4553
|
+
}
|
|
4554
|
+
}
|
|
4555
|
+
|
|
4539
4556
|
// src/lib/memoryEngine/generate.ts
|
|
4540
4557
|
var EMBED_MAX_ATTEMPTS = 4;
|
|
4541
4558
|
var DEFAULT_EMBEDDING_REQUEST_TIMEOUT_MS = 15e3;
|
|
@@ -4627,15 +4644,18 @@ async function generateEmbedding(text14, options) {
|
|
|
4627
4644
|
if (total === void 0) return embedOne(text14, options, void 0);
|
|
4628
4645
|
return withDeadline((signal) => embedOne(text14, options, signal), total, "embedding");
|
|
4629
4646
|
}
|
|
4630
|
-
var inFlightByCache
|
|
4647
|
+
var { inFlightByCache, cachedEmbeddingModels } = getEmbeddingCacheState();
|
|
4631
4648
|
async function embedOne(text14, options, outer) {
|
|
4632
4649
|
const { cache } = options;
|
|
4633
4650
|
if (!cache) return Array.from(await requestEmbedding(text14, options, outer));
|
|
4651
|
+
const model = options.model ?? DEFAULT_API_EMBEDDING_MODEL;
|
|
4634
4652
|
const cached = cache.get(text14);
|
|
4635
|
-
|
|
4653
|
+
const cachedModel = cached && cachedEmbeddingModels.get(cached);
|
|
4654
|
+
if (cached && (cachedModel === void 0 || cachedModel === model)) return Array.from(cached);
|
|
4636
4655
|
const inFlight = inFlightByCache.get(cache) ?? /* @__PURE__ */ new Map();
|
|
4637
4656
|
inFlightByCache.set(cache, inFlight);
|
|
4638
|
-
const
|
|
4657
|
+
const requestKey = JSON.stringify([model, text14]);
|
|
4658
|
+
const pending = inFlight.get(requestKey);
|
|
4639
4659
|
if (pending) {
|
|
4640
4660
|
try {
|
|
4641
4661
|
return Array.from(await pending);
|
|
@@ -4644,13 +4664,14 @@ async function embedOne(text14, options, outer) {
|
|
|
4644
4664
|
}
|
|
4645
4665
|
}
|
|
4646
4666
|
const request = requestEmbedding(text14, options, outer);
|
|
4647
|
-
inFlight.set(
|
|
4667
|
+
inFlight.set(requestKey, request);
|
|
4648
4668
|
try {
|
|
4649
4669
|
const embedding2 = await request;
|
|
4670
|
+
cachedEmbeddingModels.set(embedding2, model);
|
|
4650
4671
|
cache.set(text14, embedding2);
|
|
4651
4672
|
return Array.from(embedding2);
|
|
4652
4673
|
} finally {
|
|
4653
|
-
if (inFlight.get(
|
|
4674
|
+
if (inFlight.get(requestKey) === request) inFlight.delete(requestKey);
|
|
4654
4675
|
}
|
|
4655
4676
|
}
|
|
4656
4677
|
async function requestEmbedding(text14, options, outer) {
|
|
@@ -4733,13 +4754,15 @@ async function embedMany(texts, options, outer) {
|
|
|
4733
4754
|
const { baseUrl = BASE_URL, model, batchSize, cache } = options;
|
|
4734
4755
|
const timeoutMs = options.timeoutMs ?? DEFAULT_EMBEDDING_REQUEST_TIMEOUT_MS;
|
|
4735
4756
|
const chunkSize = batchSize ?? DEFAULT_EMBEDDING_BATCH_SIZE;
|
|
4757
|
+
const embeddingModel = model ?? DEFAULT_API_EMBEDDING_MODEL;
|
|
4736
4758
|
const results = new Array(texts.length).fill(null);
|
|
4737
4759
|
const uncachedIndices = [];
|
|
4738
4760
|
const uncachedTexts = [];
|
|
4739
4761
|
for (let i = 0; i < texts.length; i++) {
|
|
4740
4762
|
if (cache) {
|
|
4741
4763
|
const cached = cache.get(texts[i]);
|
|
4742
|
-
|
|
4764
|
+
const cachedModel = cached && cachedEmbeddingModels.get(cached);
|
|
4765
|
+
if (cached && (cachedModel === void 0 || cachedModel === embeddingModel)) {
|
|
4743
4766
|
results[i] = Array.from(cached);
|
|
4744
4767
|
continue;
|
|
4745
4768
|
}
|
|
@@ -4755,7 +4778,6 @@ async function embedMany(texts, options, outer) {
|
|
|
4755
4778
|
...taskTypeHeader(options.taskType)
|
|
4756
4779
|
};
|
|
4757
4780
|
if (outer?.aborted) throw outer.reason;
|
|
4758
|
-
const embeddingModel = model ?? DEFAULT_API_EMBEDDING_MODEL;
|
|
4759
4781
|
let newEmbeddings;
|
|
4760
4782
|
if (uncachedTexts.length <= chunkSize) {
|
|
4761
4783
|
newEmbeddings = await generateEmbeddingsBatch(
|
|
@@ -4803,6 +4825,7 @@ async function embedMany(texts, options, outer) {
|
|
|
4803
4825
|
const f32Embedding = Float32Array.from(newEmbeddings[i]);
|
|
4804
4826
|
results[uncachedIndices[i]] = Array.from(f32Embedding);
|
|
4805
4827
|
if (cache) {
|
|
4828
|
+
cachedEmbeddingModels.set(f32Embedding, embeddingModel);
|
|
4806
4829
|
cache.set(uncachedTexts[i], f32Embedding);
|
|
4807
4830
|
}
|
|
4808
4831
|
}
|
|
@@ -4927,6 +4950,37 @@ async function chunkAndEmbedMessage(ctx, messageId, options) {
|
|
|
4927
4950
|
}));
|
|
4928
4951
|
return updateMessageChunksOp(ctx, messageId, messageChunks, embeddingModel);
|
|
4929
4952
|
}
|
|
4953
|
+
var MIN_SEALED_EMBEDDING_HEX = 256;
|
|
4954
|
+
function rawHasEmbedding(value) {
|
|
4955
|
+
if (Array.isArray(value)) return value.length > 0;
|
|
4956
|
+
if (typeof value !== "string" || value.length === 0) return false;
|
|
4957
|
+
if (isEncrypted(value)) {
|
|
4958
|
+
return value.length - value.indexOf(":", 4) - 1 >= MIN_SEALED_EMBEDDING_HEX;
|
|
4959
|
+
}
|
|
4960
|
+
try {
|
|
4961
|
+
const parsed = JSON.parse(value);
|
|
4962
|
+
return Array.isArray(parsed) && parsed.length > 0;
|
|
4963
|
+
} catch {
|
|
4964
|
+
return false;
|
|
4965
|
+
}
|
|
4966
|
+
}
|
|
4967
|
+
function sealedVersion(value) {
|
|
4968
|
+
if (typeof value !== "string" || !isEncrypted(value)) return null;
|
|
4969
|
+
return value.startsWith("enc:v2:") ? "v2" : "v3";
|
|
4970
|
+
}
|
|
4971
|
+
function mayNeedChunkEmbedding(raw, embeddingModel, filter) {
|
|
4972
|
+
const role = raw.role;
|
|
4973
|
+
if (role === "system") return false;
|
|
4974
|
+
if (filter?.roles && !filter.roles.includes(role ?? "")) return false;
|
|
4975
|
+
if (isNonEmbeddableOrigin(raw.origin, filter?.reembedDiscarded)) {
|
|
4976
|
+
return false;
|
|
4977
|
+
}
|
|
4978
|
+
const model = raw.embedding_model;
|
|
4979
|
+
if (typeof model === "string" && model !== embeddingModel) return true;
|
|
4980
|
+
if (rawHasEmbedding(raw.chunks)) return false;
|
|
4981
|
+
if (rawHasEmbedding(raw.vector) && !filter?.rechunkExisting) return false;
|
|
4982
|
+
return true;
|
|
4983
|
+
}
|
|
4930
4984
|
async function chunkAndEmbedAllMessages(ctx, options, filter) {
|
|
4931
4985
|
const embeddingModel = options.model ?? DEFAULT_API_EMBEDDING_MODEL;
|
|
4932
4986
|
const { chunkSize = DEFAULT_CHUNK_SIZE } = options;
|
|
@@ -4939,11 +4993,31 @@ async function chunkAndEmbedAllMessages(ctx, options, filter) {
|
|
|
4939
4993
|
let considered = 0;
|
|
4940
4994
|
let sealedRowsSeen = 0;
|
|
4941
4995
|
let rowsSeen = 0;
|
|
4996
|
+
const keptSealed = /* @__PURE__ */ new Map();
|
|
4997
|
+
const candidatesStillSealed = /* @__PURE__ */ new Map();
|
|
4998
|
+
const droppedSealed = /* @__PURE__ */ new Map();
|
|
4999
|
+
const rawFilter = (raw) => {
|
|
5000
|
+
rowsSeen++;
|
|
5001
|
+
const keep = mayNeedChunkEmbedding(raw, embeddingModel, filter);
|
|
5002
|
+
const version = sealedVersion(raw.content);
|
|
5003
|
+
if (!version) return keep;
|
|
5004
|
+
if (keep) {
|
|
5005
|
+
keptSealed.set(version, (keptSealed.get(version) ?? 0) + 1);
|
|
5006
|
+
} else {
|
|
5007
|
+
const dropped = droppedSealed.get(version);
|
|
5008
|
+
if (dropped) dropped.count++;
|
|
5009
|
+
else droppedSealed.set(version, { count: 1, probeId: raw.id });
|
|
5010
|
+
}
|
|
5011
|
+
return keep;
|
|
5012
|
+
};
|
|
4942
5013
|
for (const conv of targetConversations) {
|
|
4943
|
-
const messages = await getMessagesOp(ctx, conv.conversationId);
|
|
5014
|
+
const messages = await getMessagesOp(ctx, conv.conversationId, { rawFilter });
|
|
4944
5015
|
for (const message of messages) {
|
|
4945
|
-
|
|
4946
|
-
if (
|
|
5016
|
+
const stillSealed = sealedVersion(message.content);
|
|
5017
|
+
if (stillSealed) {
|
|
5018
|
+
sealedRowsSeen++;
|
|
5019
|
+
candidatesStillSealed.set(stillSealed, (candidatesStillSealed.get(stillSealed) ?? 0) + 1);
|
|
5020
|
+
}
|
|
4947
5021
|
const isStale = message.embeddingModel !== void 0 && message.embeddingModel !== null && message.embeddingModel !== embeddingModel;
|
|
4948
5022
|
if (message.chunks && message.chunks.length > 0 && !isStale) continue;
|
|
4949
5023
|
const hasVector = message.vector && message.vector.length > 0;
|
|
@@ -4956,6 +5030,7 @@ async function chunkAndEmbedAllMessages(ctx, options, filter) {
|
|
|
4956
5030
|
stillEncrypted++;
|
|
4957
5031
|
continue;
|
|
4958
5032
|
}
|
|
5033
|
+
if (isToolResultsRow(message)) continue;
|
|
4959
5034
|
if (message.content.length < minLength) continue;
|
|
4960
5035
|
if (shouldChunkMessage(message.content, chunkSize)) {
|
|
4961
5036
|
longMessages.push({
|
|
@@ -4967,6 +5042,12 @@ async function chunkAndEmbedAllMessages(ctx, options, filter) {
|
|
|
4967
5042
|
}
|
|
4968
5043
|
}
|
|
4969
5044
|
}
|
|
5045
|
+
for (const [version, dropped] of droppedSealed) {
|
|
5046
|
+
const keyOpenedACandidate = (keptSealed.get(version) ?? 0) > (candidatesStillSealed.get(version) ?? 0);
|
|
5047
|
+
if (keyOpenedACandidate) continue;
|
|
5048
|
+
const probe = await getMessageOp(ctx, dropped.probeId);
|
|
5049
|
+
if (!probe || isEncrypted(probe.content)) sealedRowsSeen += dropped.count;
|
|
5050
|
+
}
|
|
4970
5051
|
if (stillEncrypted > 0 || sealedRowsSeen > 0) {
|
|
4971
5052
|
getLogger().error(
|
|
4972
5053
|
"memoryEngine: messages still encrypted (key unavailable?) \u2014 excluded from embedding",
|
|
@@ -10414,6 +10495,11 @@ function parseTopics(value) {
|
|
|
10414
10495
|
}
|
|
10415
10496
|
|
|
10416
10497
|
// src/lib/db/entities/operations.ts
|
|
10498
|
+
async function assertCanWrite(ctx) {
|
|
10499
|
+
if (ctx.canWrite && !await ctx.canWrite()) {
|
|
10500
|
+
throw new Error("Memory source is no longer eligible");
|
|
10501
|
+
}
|
|
10502
|
+
}
|
|
10417
10503
|
function entityToStored(e) {
|
|
10418
10504
|
return {
|
|
10419
10505
|
uniqueId: e.id,
|
|
@@ -10554,6 +10640,7 @@ async function linkMemoryEntitiesOp(ctx, memoryId, entityInputs, options) {
|
|
|
10554
10640
|
let skipped = false;
|
|
10555
10641
|
let entities = [];
|
|
10556
10642
|
await ctx.database.write(async () => {
|
|
10643
|
+
await assertCanWrite(ctx);
|
|
10557
10644
|
const {
|
|
10558
10645
|
entities: byName,
|
|
10559
10646
|
operations: entityOps,
|
|
@@ -10629,6 +10716,7 @@ async function replaceMemoryEntities(ctx, memoryId, entityInputs, options) {
|
|
|
10629
10716
|
let skipped = false;
|
|
10630
10717
|
let entities = [];
|
|
10631
10718
|
await ctx.database.write(async () => {
|
|
10719
|
+
await assertCanWrite(ctx);
|
|
10632
10720
|
const vaultRow = await findVaultRowInWrite(ctx, memoryId);
|
|
10633
10721
|
if (options.guarded && autoLinkBlocked(vaultRow)) {
|
|
10634
10722
|
skipped = true;
|
|
@@ -10689,6 +10777,7 @@ async function unlinkMemoryEntitiesOp(ctx, memoryIds) {
|
|
|
10689
10777
|
const links = await ctx.memoryEntityCollection.query(Q5.where("memory_id", Q5.oneOf(Array.from(memoryIds)))).fetch();
|
|
10690
10778
|
if (links.length === 0) return;
|
|
10691
10779
|
await ctx.database.write(async () => {
|
|
10780
|
+
await assertCanWrite(ctx);
|
|
10692
10781
|
await ctx.database.batch(...links.map((l) => l.prepareDestroyPermanently()));
|
|
10693
10782
|
});
|
|
10694
10783
|
}
|
|
@@ -10697,6 +10786,7 @@ async function unlinkAllMemoryEntitiesForUserOp(ctx, userId) {
|
|
|
10697
10786
|
const links = await ctx.memoryEntityCollection.query(Q5.where("user_id", userId)).fetch();
|
|
10698
10787
|
if (links.length === 0) return;
|
|
10699
10788
|
await ctx.database.write(async () => {
|
|
10789
|
+
await assertCanWrite(ctx);
|
|
10700
10790
|
await ctx.database.batch(...links.map((l) => l.prepareDestroyPermanently()));
|
|
10701
10791
|
});
|
|
10702
10792
|
}
|
|
@@ -10716,6 +10806,7 @@ async function backfillMemoryEntityUserIdsOp(ctx, vaultMemoryCollection) {
|
|
|
10716
10806
|
}
|
|
10717
10807
|
if (toUpdate.length === 0) return 0;
|
|
10718
10808
|
await ctx.database.write(async () => {
|
|
10809
|
+
await assertCanWrite(ctx);
|
|
10719
10810
|
await ctx.database.batch(
|
|
10720
10811
|
...toUpdate.map(({ link, userId }) => link.prepareUpdate((r) => r._setRaw("user_id", userId)))
|
|
10721
10812
|
);
|
|
@@ -13109,6 +13200,11 @@ function visibilityConditions(requested) {
|
|
|
13109
13200
|
function isKinded(record2) {
|
|
13110
13201
|
return record2.kind !== null && record2.kind !== void 0;
|
|
13111
13202
|
}
|
|
13203
|
+
async function assertCanWrite2(ctx) {
|
|
13204
|
+
if (ctx.canWrite && !await ctx.canWrite()) {
|
|
13205
|
+
throw new Error("Memory source is no longer eligible");
|
|
13206
|
+
}
|
|
13207
|
+
}
|
|
13112
13208
|
function assertValidKindLevel(kind, level) {
|
|
13113
13209
|
const hasKind = kind !== null && kind !== void 0;
|
|
13114
13210
|
if (hasKind && !MEMORY_KINDS.includes(kind)) {
|
|
@@ -13289,8 +13385,7 @@ async function createVaultMemoryOp(ctx, opts) {
|
|
|
13289
13385
|
ctx.embeddedWalletSigner
|
|
13290
13386
|
) : opts.content;
|
|
13291
13387
|
const created = await ctx.database.write(async () => {
|
|
13292
|
-
|
|
13293
|
-
throw new Error("Memory source is no longer eligible");
|
|
13388
|
+
await assertCanWrite2(ctx);
|
|
13294
13389
|
return ctx.vaultMemoryCollection.create(
|
|
13295
13390
|
(record2) => populateNewVaultMemory(record2, ctx, opts, encryptedContent, encryptedKindValue)
|
|
13296
13391
|
);
|
|
@@ -13309,8 +13404,7 @@ async function createSupersedingMemoryOp(ctx, opts, targetId) {
|
|
|
13309
13404
|
) : opts.content;
|
|
13310
13405
|
let createdRecord = null;
|
|
13311
13406
|
await ctx.database.write(async () => {
|
|
13312
|
-
|
|
13313
|
-
throw new Error("Memory source is no longer eligible");
|
|
13407
|
+
await assertCanWrite2(ctx);
|
|
13314
13408
|
let target;
|
|
13315
13409
|
try {
|
|
13316
13410
|
target = await ctx.vaultMemoryCollection.find(targetId);
|
|
@@ -13402,8 +13496,7 @@ async function createVaultMemoriesBatchOp(ctx, optionsArray) {
|
|
|
13402
13496
|
})
|
|
13403
13497
|
);
|
|
13404
13498
|
const created = await ctx.database.write(async () => {
|
|
13405
|
-
|
|
13406
|
-
throw new Error("Memory source is no longer eligible");
|
|
13499
|
+
await assertCanWrite2(ctx);
|
|
13407
13500
|
const prepared = optionsArray.map(
|
|
13408
13501
|
(opts, i) => ctx.vaultMemoryCollection.prepareCreate(
|
|
13409
13502
|
(record2) => populateNewVaultMemory(record2, ctx, opts, encryptedContents[i], encryptedKindValues[i])
|
|
@@ -13708,8 +13801,7 @@ async function updateVaultMemoryOp(ctx, id, opts) {
|
|
|
13708
13801
|
const record2 = probe;
|
|
13709
13802
|
const originalUpdatedAt = record2.updatedAt.getTime();
|
|
13710
13803
|
await ctx.database.write(async () => {
|
|
13711
|
-
|
|
13712
|
-
throw new Error("Memory source is no longer eligible");
|
|
13804
|
+
await assertCanWrite2(ctx);
|
|
13713
13805
|
if (record2.isDeleted || record2.supersededBy || !isOwnedByCtxUser(ctx, record2) || opts.freeFormOnly && isKinded(record2)) {
|
|
13714
13806
|
stale = true;
|
|
13715
13807
|
return;
|
|
@@ -13820,6 +13912,7 @@ async function setMemoryEntitiesOp(ctx, memoryId, entities) {
|
|
|
13820
13912
|
let stale = false;
|
|
13821
13913
|
const originalUpdatedAt = record2.updatedAt.getTime();
|
|
13822
13914
|
await ctx.database.write(async (writer) => {
|
|
13915
|
+
await assertCanWrite2(ctx);
|
|
13823
13916
|
if (record2.isDeleted || !isOwnedByCtxUser(ctx, record2)) {
|
|
13824
13917
|
stale = true;
|
|
13825
13918
|
return;
|
|
@@ -13861,6 +13954,7 @@ async function clearMemoryTopicsOverrideOp(ctx, memoryId, options) {
|
|
|
13861
13954
|
const originalUpdatedAt = record2.updatedAt.getTime();
|
|
13862
13955
|
let cleared = false;
|
|
13863
13956
|
await ctx.database.write(async () => {
|
|
13957
|
+
await assertCanWrite2(ctx);
|
|
13864
13958
|
if (options?.unlessTopicsRecorded && parseTopics(record2.topics) !== null) return;
|
|
13865
13959
|
cleared = true;
|
|
13866
13960
|
await record2.update((r) => {
|
|
@@ -13884,6 +13978,7 @@ async function setMemoryVisibilityOp(ctx, id, opts) {
|
|
|
13884
13978
|
if (record2.isDeleted || !isOwnedByCtxUser(ctx, record2)) return null;
|
|
13885
13979
|
let stale = false;
|
|
13886
13980
|
await ctx.database.write(async () => {
|
|
13981
|
+
await assertCanWrite2(ctx);
|
|
13887
13982
|
if (record2.isDeleted || !isOwnedByCtxUser(ctx, record2)) {
|
|
13888
13983
|
stale = true;
|
|
13889
13984
|
return;
|
|
@@ -13912,6 +14007,7 @@ async function deleteVaultMemoryOp(ctx, id) {
|
|
|
13912
14007
|
if (record2.isDeleted || !isOwnedByCtxUser(ctx, record2)) return false;
|
|
13913
14008
|
let stale = false;
|
|
13914
14009
|
await ctx.database.write(async () => {
|
|
14010
|
+
await assertCanWrite2(ctx);
|
|
13915
14011
|
if (record2.isDeleted || !isOwnedByCtxUser(ctx, record2)) {
|
|
13916
14012
|
stale = true;
|
|
13917
14013
|
return;
|
|
@@ -13949,8 +14045,7 @@ async function supersedeVaultMemoryOp(ctx, id, supersededById) {
|
|
|
13949
14045
|
}
|
|
13950
14046
|
let stale = false;
|
|
13951
14047
|
await ctx.database.write(async () => {
|
|
13952
|
-
|
|
13953
|
-
throw new Error("Memory source is no longer eligible");
|
|
14048
|
+
await assertCanWrite2(ctx);
|
|
13954
14049
|
if (record2.isDeleted || record2.supersededBy || !isOwnedByCtxUser(ctx, record2)) {
|
|
13955
14050
|
stale = true;
|
|
13956
14051
|
return;
|
|
@@ -14112,6 +14207,7 @@ async function stampTopicsExtractedAtOp(ctx, memoryIds, extractedAt, version = T
|
|
|
14112
14207
|
for (let i = 0; i < uniqueIds.length; i += CHUNK) {
|
|
14113
14208
|
const chunkIds = uniqueIds.slice(i, i + CHUNK);
|
|
14114
14209
|
await ctx.database.write(async () => {
|
|
14210
|
+
await assertCanWrite2(ctx);
|
|
14115
14211
|
const records = [];
|
|
14116
14212
|
for (const id of chunkIds) {
|
|
14117
14213
|
try {
|
|
@@ -14145,6 +14241,7 @@ async function relinkMemoryTopicsOp(ctx, memoryIds) {
|
|
|
14145
14241
|
for (const id of Array.from(new Set(memoryIds))) {
|
|
14146
14242
|
try {
|
|
14147
14243
|
await ctx.database.write(async (writer) => {
|
|
14244
|
+
await assertCanWrite2(ctx);
|
|
14148
14245
|
let record2;
|
|
14149
14246
|
try {
|
|
14150
14247
|
record2 = await ctx.vaultMemoryCollection.find(id);
|
|
@@ -14175,6 +14272,7 @@ async function backfillMemoryTopicsOp(ctx, memoryIds) {
|
|
|
14175
14272
|
for (let i = 0; i < uniqueIds.length; i += CHUNK) {
|
|
14176
14273
|
const chunkIds = uniqueIds.slice(i, i + CHUNK);
|
|
14177
14274
|
await ctx.database.write(async () => {
|
|
14275
|
+
await assertCanWrite2(ctx);
|
|
14178
14276
|
const writes = [];
|
|
14179
14277
|
for (const id of chunkIds) {
|
|
14180
14278
|
let record2;
|
|
@@ -14207,6 +14305,7 @@ async function deleteAllVaultMemoriesForUserOp(ctx, userId) {
|
|
|
14207
14305
|
const records = await ctx.vaultMemoryCollection.query(Q8.where("user_id", userId), Q8.where("is_deleted", false)).fetch();
|
|
14208
14306
|
if (records.length === 0) return 0;
|
|
14209
14307
|
await ctx.database.write(async () => {
|
|
14308
|
+
await assertCanWrite2(ctx);
|
|
14210
14309
|
const prepared = records.map(
|
|
14211
14310
|
(record2) => record2.prepareUpdate((r) => {
|
|
14212
14311
|
r._setRaw("is_deleted", true);
|
|
@@ -14261,6 +14360,7 @@ async function archiveVaultMemoryOp(ctx, id, opts) {
|
|
|
14261
14360
|
let stale = false;
|
|
14262
14361
|
const archivedAtValue = opts?.now ?? Date.now();
|
|
14263
14362
|
await ctx.database.write(async () => {
|
|
14363
|
+
await assertCanWrite2(ctx);
|
|
14264
14364
|
if (record2.isDeleted || !isOwnedByCtxUser(ctx, record2) || record2.archivedAt !== null) {
|
|
14265
14365
|
stale = true;
|
|
14266
14366
|
return;
|
|
@@ -14284,6 +14384,7 @@ async function restoreVaultMemoryOp(ctx, id) {
|
|
|
14284
14384
|
if (record2.isDeleted || !isOwnedByCtxUser(ctx, record2)) return false;
|
|
14285
14385
|
let stale = false;
|
|
14286
14386
|
await ctx.database.write(async () => {
|
|
14387
|
+
await assertCanWrite2(ctx);
|
|
14287
14388
|
if (record2.isDeleted || !isOwnedByCtxUser(ctx, record2)) {
|
|
14288
14389
|
stale = true;
|
|
14289
14390
|
return;
|
|
@@ -14304,6 +14405,7 @@ async function hardDeleteDecayedOp(ctx, id, opts) {
|
|
|
14304
14405
|
const now = opts.now ?? Date.now();
|
|
14305
14406
|
let stale = false;
|
|
14306
14407
|
await ctx.database.write(async () => {
|
|
14408
|
+
await assertCanWrite2(ctx);
|
|
14307
14409
|
const archivedAt = record2.archivedAt;
|
|
14308
14410
|
if (record2.isDeleted || !isOwnedByCtxUser(ctx, record2) || archivedAt === null || now - archivedAt <= opts.hardDeleteWindowMs) {
|
|
14309
14411
|
stale = true;
|
|
@@ -14343,6 +14445,7 @@ async function updateVaultMemoryEmbeddingOp(ctx, id, embedding2, embeddingModel,
|
|
|
14343
14445
|
}
|
|
14344
14446
|
let written = false;
|
|
14345
14447
|
await ctx.database.write(async () => {
|
|
14448
|
+
await assertCanWrite2(ctx);
|
|
14346
14449
|
if (record2.isDeleted || !isOwnedByCtxUser(ctx, record2)) return;
|
|
14347
14450
|
const originalUpdatedAt = record2.updatedAt.getTime();
|
|
14348
14451
|
if (originalUpdatedAt !== readUpdatedAt || record2._getRaw("content") !== readStoredContent)
|
|
@@ -18312,6 +18415,13 @@ function restoreCandidates(candidates, redactor, ownNames) {
|
|
|
18312
18415
|
).map((c) => c.candidate);
|
|
18313
18416
|
}
|
|
18314
18417
|
async function extractAndRetain(messages, retainCtx, options) {
|
|
18418
|
+
const { memoryStore, signal } = options;
|
|
18419
|
+
if (memoryStore === null) throw new Error("Memory store is not ready");
|
|
18420
|
+
if (memoryStore && options.folderId !== void 0 && options.folderId !== null)
|
|
18421
|
+
throw new Error("Remote memory extraction does not support folders");
|
|
18422
|
+
if (memoryStore && options.extract.piiRedaction && !memoryStore.masksEmbeddingInput)
|
|
18423
|
+
throw new Error("PII-redacted extraction requires a memory store that masks embedding inputs");
|
|
18424
|
+
signal?.throwIfAborted();
|
|
18315
18425
|
const minConfidence = options.minConfidence ?? DEFAULT_MIN_CONFIDENCE;
|
|
18316
18426
|
const resolvedConsolidatePii = options.consolidateOptions?.piiRedaction ?? options.extract.piiRedaction;
|
|
18317
18427
|
const consolidateOptions = options.consolidateOptions !== void 0 ? {
|
|
@@ -18345,6 +18455,7 @@ async function extractAndRetain(messages, retainCtx, options) {
|
|
|
18345
18455
|
}
|
|
18346
18456
|
});
|
|
18347
18457
|
const extractMs = Date.now() - tExtract;
|
|
18458
|
+
signal?.throwIfAborted();
|
|
18348
18459
|
const filtered = candidates.filter((c) => c.confidence >= minConfidence);
|
|
18349
18460
|
const log = getLogger();
|
|
18350
18461
|
const screened = screenCandidatesForInjection(filtered);
|
|
@@ -18392,16 +18503,33 @@ async function extractAndRetain(messages, retainCtx, options) {
|
|
|
18392
18503
|
const results = [];
|
|
18393
18504
|
const quarantinedInfo = [];
|
|
18394
18505
|
let failedWrites = 0;
|
|
18506
|
+
let auditRows;
|
|
18395
18507
|
const tRetain = Date.now();
|
|
18396
18508
|
for (const { candidate, isQuarantined, reason, signature } of toRetain) {
|
|
18397
18509
|
try {
|
|
18510
|
+
signal?.throwIfAborted();
|
|
18398
18511
|
if (isQuarantined) {
|
|
18399
|
-
|
|
18400
|
-
|
|
18401
|
-
|
|
18402
|
-
|
|
18403
|
-
|
|
18404
|
-
|
|
18512
|
+
let existingId;
|
|
18513
|
+
if (memoryStore) {
|
|
18514
|
+
auditRows ?? (auditRows = memoryStore.list({
|
|
18515
|
+
scopes: [options.scope ?? "private"],
|
|
18516
|
+
includeArchived: true,
|
|
18517
|
+
includeQuarantined: true,
|
|
18518
|
+
includeSuperseded: true
|
|
18519
|
+
}));
|
|
18520
|
+
const sourceKey = [...new Set(candidate.sourceMessageIds)].sort().join("\0");
|
|
18521
|
+
const normalize = (value) => value.normalize("NFKC").trim().replace(/\s+/g, " ").toLowerCase();
|
|
18522
|
+
existingId = (await auditRows).find(
|
|
18523
|
+
(row) => row.trustTier === "quarantined" && row.scope === (options.scope ?? "private") && [...new Set(row.sourceChunkIds ?? [])].sort().join("\0") === sourceKey && normalize(row.content) === normalize(candidate.content)
|
|
18524
|
+
)?.uniqueId ?? null;
|
|
18525
|
+
} else {
|
|
18526
|
+
existingId = await findQuarantinedDuplicateOp(
|
|
18527
|
+
retainCtx.vaultCtx,
|
|
18528
|
+
candidate.content,
|
|
18529
|
+
candidate.sourceMessageIds,
|
|
18530
|
+
{ scope: options.scope ?? "private", folderId: options.folderId ?? null }
|
|
18531
|
+
).catch(() => null);
|
|
18532
|
+
}
|
|
18405
18533
|
if (existingId) {
|
|
18406
18534
|
quarantinedInfo.push({
|
|
18407
18535
|
candidate,
|
|
@@ -18412,18 +18540,26 @@ async function extractAndRetain(messages, retainCtx, options) {
|
|
|
18412
18540
|
continue;
|
|
18413
18541
|
}
|
|
18414
18542
|
}
|
|
18415
|
-
const
|
|
18543
|
+
const retainOptions = {
|
|
18416
18544
|
source: "auto-extracted",
|
|
18417
18545
|
sourceChunkIds: candidate.sourceMessageIds,
|
|
18418
18546
|
respectTombstones: true,
|
|
18419
18547
|
...options.scope !== void 0 && { scope: options.scope },
|
|
18420
|
-
...options.folderId !== void 0 && { folderId: options.folderId },
|
|
18421
18548
|
...consolidateOptions !== void 0 && { consolidateOptions },
|
|
18422
18549
|
...candidate.eventTime !== null && { eventTime: candidate.eventTime },
|
|
18423
18550
|
factType: candidate.type,
|
|
18424
18551
|
...isQuarantined && { trustTier: "quarantined", enableAutoMerge: false }
|
|
18552
|
+
};
|
|
18553
|
+
const result = memoryStore ? await memoryStore.retain(candidate.content, {
|
|
18554
|
+
...retainOptions,
|
|
18555
|
+
canWrite: retainCtx.vaultCtx.canWrite,
|
|
18556
|
+
signal
|
|
18557
|
+
}) : await retain(candidate.content, retainCtx, {
|
|
18558
|
+
...retainOptions,
|
|
18559
|
+
...options.folderId !== void 0 && { folderId: options.folderId }
|
|
18425
18560
|
});
|
|
18426
18561
|
if (isQuarantined) {
|
|
18562
|
+
auditRows = void 0;
|
|
18427
18563
|
const info = {
|
|
18428
18564
|
candidate,
|
|
18429
18565
|
memoryId: result.memoryId,
|
|
@@ -18442,9 +18578,16 @@ async function extractAndRetain(messages, retainCtx, options) {
|
|
|
18442
18578
|
}
|
|
18443
18579
|
succeededCandidates.push(candidate);
|
|
18444
18580
|
results.push(result);
|
|
18445
|
-
if (result.action !== "suppressed" &&
|
|
18581
|
+
if (result.action !== "suppressed" && candidate.entities.length > 0) {
|
|
18446
18582
|
try {
|
|
18447
|
-
|
|
18583
|
+
signal?.throwIfAborted();
|
|
18584
|
+
if (memoryStore) {
|
|
18585
|
+
await memoryStore.addTopics(result.memoryId, candidate.entities, {
|
|
18586
|
+
unlessUserManaged: true,
|
|
18587
|
+
canWrite: retainCtx.vaultCtx.canWrite,
|
|
18588
|
+
signal
|
|
18589
|
+
});
|
|
18590
|
+
} else if (options.entityCtx && !await isMemoryTopicsUserManaged(options.entityCtx, result.memoryId)) {
|
|
18448
18591
|
await linkMemoryEntitiesOp(options.entityCtx, result.memoryId, candidate.entities, {
|
|
18449
18592
|
unlessTopicsUserManaged: true
|
|
18450
18593
|
});
|
|
@@ -18692,7 +18835,7 @@ function createAutoExtractor(options) {
|
|
|
18692
18835
|
};
|
|
18693
18836
|
const consolidateOptions = options.consolidate ? { ...options.consolidate, ...subPassAuth(options.consolidate.baseUrl) } : void 0;
|
|
18694
18837
|
const injectionClassifierOptions = options.injectionClassifier ? { ...options.injectionClassifier, ...subPassAuth(options.injectionClassifier.baseUrl) } : void 0;
|
|
18695
|
-
if (options.retainCtx.vaultCtx.entityCtx && !options.entityCtx) {
|
|
18838
|
+
if (!options.memoryStore && options.retainCtx.vaultCtx.entityCtx && !options.entityCtx) {
|
|
18696
18839
|
getLogger().warn(
|
|
18697
18840
|
"[memory/extract] retainCtx.vaultCtx.entityCtx is set but extractor was created without `entityCtx` \u2014 W5 graph lane will receive no writes"
|
|
18698
18841
|
);
|
|
@@ -18737,6 +18880,8 @@ function createAutoExtractor(options) {
|
|
|
18737
18880
|
try {
|
|
18738
18881
|
const { candidates, results, failedCount, outcome: outcome2, failure, funnel, timings, model } = await extractAndRetain(window2, retainCtx, {
|
|
18739
18882
|
extract,
|
|
18883
|
+
memoryStore: options.memoryStore,
|
|
18884
|
+
signal: options.signal,
|
|
18740
18885
|
...options.minConfidence !== void 0 && { minConfidence: options.minConfidence },
|
|
18741
18886
|
...options.entityCtx !== void 0 && { entityCtx: options.entityCtx },
|
|
18742
18887
|
...options.scope !== void 0 && { scope: options.scope },
|
|
@@ -19389,7 +19534,7 @@ var MaskScopedEmbeddingCache = class extends Map {
|
|
|
19389
19534
|
return this;
|
|
19390
19535
|
}
|
|
19391
19536
|
};
|
|
19392
|
-
var scopedViews =
|
|
19537
|
+
var { scopedViews } = getEmbeddingCacheState();
|
|
19393
19538
|
function maskScopedEmbeddingCache(cache, masked) {
|
|
19394
19539
|
const views = scopedViews.get(cache) ?? {};
|
|
19395
19540
|
scopedViews.set(cache, views);
|
|
@@ -19811,44 +19956,48 @@ async function recall(query, ctx, options = {}) {
|
|
|
19811
19956
|
embeddingOptions,
|
|
19812
19957
|
ctx.vaultCache,
|
|
19813
19958
|
searchOptions
|
|
19814
|
-
)))(
|
|
19815
|
-
|
|
19816
|
-
|
|
19817
|
-
|
|
19818
|
-
|
|
19819
|
-
|
|
19820
|
-
|
|
19821
|
-
|
|
19822
|
-
|
|
19823
|
-
|
|
19824
|
-
|
|
19825
|
-
|
|
19826
|
-
|
|
19827
|
-
|
|
19828
|
-
|
|
19829
|
-
|
|
19830
|
-
|
|
19831
|
-
|
|
19832
|
-
|
|
19833
|
-
|
|
19834
|
-
|
|
19835
|
-
|
|
19836
|
-
|
|
19837
|
-
|
|
19959
|
+
)))(
|
|
19960
|
+
query,
|
|
19961
|
+
{
|
|
19962
|
+
limit: types.includes("chunk") ? Math.max(limit * 2, 16) : limit,
|
|
19963
|
+
minSimilarity: vaultMinScore,
|
|
19964
|
+
useFusion: true,
|
|
19965
|
+
rerank: flags.rerank,
|
|
19966
|
+
...options.rerankTopN !== void 0 && { rerankTopN: options.rerankTopN },
|
|
19967
|
+
...options.ceWeight !== void 0 && { ceWeight: options.ceWeight },
|
|
19968
|
+
...options.rerankLoadTimeoutMs !== void 0 && {
|
|
19969
|
+
rerankLoadTimeoutMs: options.rerankLoadTimeoutMs
|
|
19970
|
+
},
|
|
19971
|
+
...options.recencyAlpha !== void 0 && { recencyAlpha: options.recencyAlpha },
|
|
19972
|
+
...options.recency && { recency: options.recency },
|
|
19973
|
+
...options.mmr !== void 0 && { mmr: options.mmr },
|
|
19974
|
+
...options.supersessionBoost !== void 0 && {
|
|
19975
|
+
supersessionBoost: options.supersessionBoost
|
|
19976
|
+
},
|
|
19977
|
+
...options.supersessionWindow !== void 0 && {
|
|
19978
|
+
supersessionWindow: options.supersessionWindow
|
|
19979
|
+
},
|
|
19980
|
+
...options.proofCountAlpha !== void 0 && {
|
|
19981
|
+
proofCountAlpha: options.proofCountAlpha
|
|
19982
|
+
},
|
|
19983
|
+
...options.bm25AdmissionDivisor !== void 0 && {
|
|
19984
|
+
bm25AdmissionDivisor: options.bm25AdmissionDivisor
|
|
19985
|
+
},
|
|
19986
|
+
...options.rrfK !== void 0 && { rrfK: options.rrfK },
|
|
19987
|
+
...options.decryptLast !== void 0 && { decryptLast: options.decryptLast },
|
|
19988
|
+
...subQueries && { subQueries },
|
|
19989
|
+
...options.scopes && { scopes: options.scopes },
|
|
19990
|
+
...options.folderId !== void 0 && { folderId: options.folderId },
|
|
19991
|
+
...options.factTypes?.length && { factTypes: options.factTypes },
|
|
19992
|
+
...options.memoryIds !== void 0 && { memoryIds: options.memoryIds },
|
|
19993
|
+
...options.factTypeWeights && { factTypeWeights: options.factTypeWeights },
|
|
19994
|
+
...entityRanking.length > 0 && { entityRanking },
|
|
19995
|
+
...temporalRanking.length > 0 && { temporalRanking },
|
|
19996
|
+
...needsChunkEmbedding && { queryEmbedding: queryEmbedding ?? [] },
|
|
19997
|
+
queryEmbedTotalTimeoutMs
|
|
19838
19998
|
},
|
|
19839
|
-
|
|
19840
|
-
|
|
19841
|
-
...subQueries && { subQueries },
|
|
19842
|
-
...options.scopes && { scopes: options.scopes },
|
|
19843
|
-
...options.folderId !== void 0 && { folderId: options.folderId },
|
|
19844
|
-
...options.factTypes?.length && { factTypes: options.factTypes },
|
|
19845
|
-
...options.memoryIds !== void 0 && { memoryIds: options.memoryIds },
|
|
19846
|
-
...options.factTypeWeights && { factTypeWeights: options.factTypeWeights },
|
|
19847
|
-
...entityRanking.length > 0 && { entityRanking },
|
|
19848
|
-
...temporalRanking.length > 0 && { temporalRanking },
|
|
19849
|
-
...needsChunkEmbedding && { queryEmbedding: queryEmbedding ?? [] },
|
|
19850
|
-
queryEmbedTotalTimeoutMs
|
|
19851
|
-
});
|
|
19999
|
+
options.embeddingCache
|
|
20000
|
+
);
|
|
19852
20001
|
factResults.push(
|
|
19853
20002
|
...dedupeBy(
|
|
19854
20003
|
results,
|
|
@@ -20845,6 +20994,7 @@ function createLocalMemoryStore(options) {
|
|
|
20845
20994
|
database,
|
|
20846
20995
|
entityCollection: database.get("entity"),
|
|
20847
20996
|
memoryEntityCollection: database.get("memory_entity"),
|
|
20997
|
+
canWrite: options.canWrite,
|
|
20848
20998
|
...userId !== void 0 && { userId },
|
|
20849
20999
|
...options.allowUnscopedRows !== void 0 && {
|
|
20850
21000
|
allowUnscopedRows: options.allowUnscopedRows
|
|
@@ -20856,10 +21006,21 @@ function createLocalMemoryStore(options) {
|
|
|
20856
21006
|
walletAddress: options.walletAddress,
|
|
20857
21007
|
signMessage: options.signMessage,
|
|
20858
21008
|
embeddedWalletSigner: options.embeddedWalletSigner,
|
|
21009
|
+
canWrite: options.canWrite,
|
|
20859
21010
|
...userId !== void 0 && { userId },
|
|
20860
21011
|
...options.singleTenant !== void 0 && { singleTenant: options.singleTenant },
|
|
20861
21012
|
entityCtx
|
|
20862
21013
|
};
|
|
21014
|
+
const assertWrite = async (writeOptions) => {
|
|
21015
|
+
writeOptions?.signal?.throwIfAborted();
|
|
21016
|
+
if (writeOptions?.canWrite && !await writeOptions.canWrite()) {
|
|
21017
|
+
throw new Error("Memory source is no longer eligible");
|
|
21018
|
+
}
|
|
21019
|
+
if (options.canWrite && !await options.canWrite()) {
|
|
21020
|
+
throw new Error("Memory source is no longer eligible");
|
|
21021
|
+
}
|
|
21022
|
+
writeOptions?.signal?.throwIfAborted();
|
|
21023
|
+
};
|
|
20863
21024
|
const vaultCache = options.vaultCache ?? createVaultEmbeddingCache();
|
|
20864
21025
|
const ownedBy = userId !== void 0 ? [Q15.where("user_id", userId)] : [];
|
|
20865
21026
|
const linksOwnedBy = userId === void 0 ? [] : options.allowUnscopedRows ? [Q15.or(Q15.where("user_id", userId), Q15.where("user_id", null))] : [Q15.where("user_id", userId)];
|
|
@@ -20971,9 +21132,25 @@ function createLocalMemoryStore(options) {
|
|
|
20971
21132
|
archive: (id) => archiveVaultMemoryOp(vaultCtx, id),
|
|
20972
21133
|
restore: (id) => restoreVaultMemoryOp(vaultCtx, id),
|
|
20973
21134
|
setTopics: (memoryId, topics) => setMemoryEntitiesOp(vaultCtx, memoryId, topics),
|
|
20974
|
-
addTopics: (memoryId, topics) => database.write(async (writer) => {
|
|
21135
|
+
addTopics: (memoryId, topics, writeOptions) => database.write(async (writer) => {
|
|
21136
|
+
await assertWrite(writeOptions);
|
|
20975
21137
|
const owned = await vaultCtx.vaultMemoryCollection.query(Q15.where("id", memoryId), Q15.where("is_deleted", false), ...ownedBy).fetchCount();
|
|
20976
|
-
return owned > 0 ? writer.callWriter(
|
|
21138
|
+
return owned > 0 ? writer.callWriter(
|
|
21139
|
+
() => linkMemoryEntitiesOp(
|
|
21140
|
+
{
|
|
21141
|
+
...entityCtx,
|
|
21142
|
+
canWrite: async () => {
|
|
21143
|
+
await assertWrite(writeOptions);
|
|
21144
|
+
return true;
|
|
21145
|
+
}
|
|
21146
|
+
},
|
|
21147
|
+
memoryId,
|
|
21148
|
+
topics,
|
|
21149
|
+
{
|
|
21150
|
+
unlessTopicsUserManaged: writeOptions?.unlessUserManaged
|
|
21151
|
+
}
|
|
21152
|
+
)
|
|
21153
|
+
) : [];
|
|
20977
21154
|
}),
|
|
20978
21155
|
setVisibility: (id, visibility, visibilityOptions) => setMemoryVisibilityOp(vaultCtx, id, { visibility, ...visibilityOptions }),
|
|
20979
21156
|
recall: (query, recallOptions) => recall(
|
|
@@ -20983,14 +21160,33 @@ function createLocalMemoryStore(options) {
|
|
|
20983
21160
|
),
|
|
20984
21161
|
retain: (content, retainOptions) => retain(
|
|
20985
21162
|
content,
|
|
20986
|
-
{
|
|
21163
|
+
{
|
|
21164
|
+
vaultCtx: {
|
|
21165
|
+
...vaultCtx,
|
|
21166
|
+
canWrite: async () => {
|
|
21167
|
+
await assertWrite(retainOptions);
|
|
21168
|
+
return true;
|
|
21169
|
+
}
|
|
21170
|
+
},
|
|
21171
|
+
embeddingOptions: options.embeddingOptions,
|
|
21172
|
+
vaultCache
|
|
21173
|
+
},
|
|
20987
21174
|
retainOptions
|
|
20988
21175
|
),
|
|
20989
21176
|
factSource: {
|
|
20990
|
-
search: (query, searchOptions) => searchVaultMemoriesWithSize(
|
|
21177
|
+
search: (query, searchOptions, embeddingCache) => searchVaultMemoriesWithSize(
|
|
20991
21178
|
query,
|
|
20992
21179
|
vaultCtx,
|
|
20993
|
-
{
|
|
21180
|
+
{
|
|
21181
|
+
...options.embeddingOptions,
|
|
21182
|
+
taskType: "memory_recall_embed",
|
|
21183
|
+
...embeddingCache && !options.embeddingOptions.cache && {
|
|
21184
|
+
cache: maskScopedEmbeddingCache(
|
|
21185
|
+
embeddingCache,
|
|
21186
|
+
Boolean(options.embeddingOptions.maskInput)
|
|
21187
|
+
)
|
|
21188
|
+
}
|
|
21189
|
+
},
|
|
20994
21190
|
vaultCache,
|
|
20995
21191
|
searchOptions
|
|
20996
21192
|
),
|
|
@@ -21620,7 +21816,14 @@ function stored(row) {
|
|
|
21620
21816
|
function createRemoteMemoryPipeline(options) {
|
|
21621
21817
|
const { persistence, embeddingOptions } = options;
|
|
21622
21818
|
const model = embeddingOptions.model ?? DEFAULT_API_EMBEDDING_MODEL;
|
|
21623
|
-
const operation = (mode) => {
|
|
21819
|
+
const operation = (mode, queryOptions = embeddingOptions, writeOptions) => {
|
|
21820
|
+
const signal = writeOptions?.signal;
|
|
21821
|
+
const assertWrite = async () => {
|
|
21822
|
+
signal?.throwIfAborted();
|
|
21823
|
+
if (writeOptions?.canWrite && !await writeOptions.canWrite())
|
|
21824
|
+
throw new Error("Memory source is no longer eligible");
|
|
21825
|
+
signal?.throwIfAborted();
|
|
21826
|
+
};
|
|
21624
21827
|
const rejectUndecryptable = (failed) => {
|
|
21625
21828
|
if (!failed.length) return;
|
|
21626
21829
|
if (mode === "retain")
|
|
@@ -21638,7 +21841,7 @@ function createRemoteMemoryPipeline(options) {
|
|
|
21638
21841
|
return items.map((item) => stored(item.memory));
|
|
21639
21842
|
};
|
|
21640
21843
|
const get = async (id) => {
|
|
21641
|
-
const snapshot = snapshots.get(id) ?? await persistence.get(id);
|
|
21844
|
+
const snapshot = snapshots.get(id) ?? await (signal ? persistence.get(id, signal) : persistence.get(id));
|
|
21642
21845
|
if (!snapshot || snapshot.memory.is_deleted || snapshot.memory.superseded_by) return null;
|
|
21643
21846
|
snapshots.set(id, snapshot);
|
|
21644
21847
|
return stored(snapshot.memory);
|
|
@@ -21651,7 +21854,7 @@ function createRemoteMemoryPipeline(options) {
|
|
|
21651
21854
|
const start = Date.now();
|
|
21652
21855
|
const budgetMs = search.queryEmbedTotalTimeoutMs ?? 8e3;
|
|
21653
21856
|
const embed = (texts) => generateEmbeddings(texts, {
|
|
21654
|
-
...
|
|
21857
|
+
...queryOptions,
|
|
21655
21858
|
taskType: mode === "retain" ? "memory_retain_embed" : "memory_recall_embed",
|
|
21656
21859
|
totalTimeoutMs: budgetMs
|
|
21657
21860
|
});
|
|
@@ -21671,7 +21874,11 @@ function createRemoteMemoryPipeline(options) {
|
|
|
21671
21874
|
}
|
|
21672
21875
|
};
|
|
21673
21876
|
const [primary, facetEmbeddings] = await Promise.all([
|
|
21674
|
-
search.queryEmbedding ??
|
|
21877
|
+
search.queryEmbedding ?? (mode === "recall" && queryOptions.cache ? generateEmbedding(query, {
|
|
21878
|
+
...queryOptions,
|
|
21879
|
+
taskType: "memory_recall_embed",
|
|
21880
|
+
totalTimeoutMs: budgetMs
|
|
21881
|
+
}) : embed([query]).then((vectors2) => vectors2[0])),
|
|
21675
21882
|
embedFacets()
|
|
21676
21883
|
]);
|
|
21677
21884
|
const queryEmbedding = storedVector(primary);
|
|
@@ -21684,7 +21891,7 @@ function createRemoteMemoryPipeline(options) {
|
|
|
21684
21891
|
if (forced.size < 100 && temporal[i] !== void 0) forced.add(temporal[i]);
|
|
21685
21892
|
}
|
|
21686
21893
|
const forceIds = [...forced];
|
|
21687
|
-
const windowOptions = (i,
|
|
21894
|
+
const windowOptions = (i, signal2) => ({
|
|
21688
21895
|
limit: Math.min(100, Math.max((search.limit ?? 8) * 3, 30)),
|
|
21689
21896
|
force_ids: i === 0 ? forceIds : [],
|
|
21690
21897
|
...search.scopes && { scopes: search.scopes },
|
|
@@ -21692,13 +21899,15 @@ function createRemoteMemoryPipeline(options) {
|
|
|
21692
21899
|
...search.memoryIds !== void 0 && { memory_ids: search.memoryIds },
|
|
21693
21900
|
include_archived: search.includeArchived,
|
|
21694
21901
|
embedding_model: model,
|
|
21695
|
-
...
|
|
21902
|
+
...signal2 && { signal: signal2 }
|
|
21696
21903
|
});
|
|
21697
21904
|
const vectors = [queryEmbedding, ...facetEmbeddings];
|
|
21698
21905
|
let windows;
|
|
21699
21906
|
if (mode === "retain") {
|
|
21700
21907
|
windows = await Promise.all(
|
|
21701
|
-
vectors.map(
|
|
21908
|
+
vectors.map(
|
|
21909
|
+
(embedding2, i) => persistence.candidateSet(embedding2, windowOptions(i, signal))
|
|
21910
|
+
)
|
|
21702
21911
|
);
|
|
21703
21912
|
} else {
|
|
21704
21913
|
const deadline = new AbortController();
|
|
@@ -21786,12 +21995,15 @@ function createRemoteMemoryPipeline(options) {
|
|
|
21786
21995
|
twin_opt_in: false
|
|
21787
21996
|
};
|
|
21788
21997
|
};
|
|
21789
|
-
const write = async (memory, snapshot) =>
|
|
21998
|
+
const write = async (memory, snapshot) => {
|
|
21999
|
+
await assertWrite();
|
|
22000
|
+
return remember([await persistence.put(memory, snapshot, signal)])[0];
|
|
22001
|
+
};
|
|
21790
22002
|
const port = {
|
|
21791
22003
|
prepare,
|
|
21792
22004
|
get,
|
|
21793
22005
|
getFresh: async (id) => {
|
|
21794
|
-
const current = await persistence.get(id);
|
|
22006
|
+
const current = await (signal ? persistence.get(id, signal) : persistence.get(id));
|
|
21795
22007
|
return current && !current.memory.is_deleted && !current.memory.superseded_by ? stored(current.memory) : null;
|
|
21796
22008
|
},
|
|
21797
22009
|
tombstones: async (embedding2, embeddingModel, scope, folderId) => {
|
|
@@ -21802,7 +22014,8 @@ function createRemoteMemoryPipeline(options) {
|
|
|
21802
22014
|
embedding_model: embeddingModel,
|
|
21803
22015
|
strict_model: true,
|
|
21804
22016
|
include_deleted: true,
|
|
21805
|
-
deleted_only: true
|
|
22017
|
+
deleted_only: true,
|
|
22018
|
+
signal
|
|
21806
22019
|
});
|
|
21807
22020
|
rejectUndecryptable(window2.failed);
|
|
21808
22021
|
return remember(window2.items);
|
|
@@ -21858,14 +22071,18 @@ function createRemoteMemoryPipeline(options) {
|
|
|
21858
22071
|
if (!target || !newer || id === successor) return false;
|
|
21859
22072
|
const old = snapshots.get(id);
|
|
21860
22073
|
const next = snapshots.get(successor);
|
|
22074
|
+
await assertWrite();
|
|
21861
22075
|
remember(
|
|
21862
|
-
await persistence.putMany(
|
|
21863
|
-
|
|
21864
|
-
|
|
21865
|
-
|
|
21866
|
-
|
|
21867
|
-
|
|
21868
|
-
|
|
22076
|
+
await persistence.putMany(
|
|
22077
|
+
[
|
|
22078
|
+
{
|
|
22079
|
+
memory: { ...old.memory, superseded_by: successor, superseded_at: Date.now() },
|
|
22080
|
+
expectedVersion: old
|
|
22081
|
+
},
|
|
22082
|
+
{ memory: next.memory, expectedVersion: next }
|
|
22083
|
+
],
|
|
22084
|
+
signal
|
|
22085
|
+
)
|
|
21869
22086
|
);
|
|
21870
22087
|
return true;
|
|
21871
22088
|
},
|
|
@@ -21874,18 +22091,22 @@ function createRemoteMemoryPipeline(options) {
|
|
|
21874
22091
|
if (!target) return { created: null, retired: false };
|
|
21875
22092
|
const snapshot = snapshots.get(targetId);
|
|
21876
22093
|
const successor = createRow(input);
|
|
22094
|
+
await assertWrite();
|
|
21877
22095
|
const rows = remember(
|
|
21878
|
-
await persistence.putMany(
|
|
21879
|
-
|
|
21880
|
-
|
|
21881
|
-
|
|
21882
|
-
|
|
21883
|
-
|
|
21884
|
-
|
|
21885
|
-
|
|
21886
|
-
|
|
21887
|
-
|
|
21888
|
-
|
|
22096
|
+
await persistence.putMany(
|
|
22097
|
+
[
|
|
22098
|
+
{ memory: successor, expectedVersion: 0 },
|
|
22099
|
+
{
|
|
22100
|
+
memory: {
|
|
22101
|
+
...snapshot.memory,
|
|
22102
|
+
superseded_by: successor.memory_id,
|
|
22103
|
+
superseded_at: Date.now()
|
|
22104
|
+
},
|
|
22105
|
+
expectedVersion: snapshot
|
|
22106
|
+
}
|
|
22107
|
+
],
|
|
22108
|
+
signal
|
|
22109
|
+
)
|
|
21889
22110
|
);
|
|
21890
22111
|
return { created: rows[0], retired: true };
|
|
21891
22112
|
}
|
|
@@ -21895,15 +22116,17 @@ function createRemoteMemoryPipeline(options) {
|
|
|
21895
22116
|
const factSource = {
|
|
21896
22117
|
graphRanking: options.graphRanking,
|
|
21897
22118
|
temporalRanking: options.temporalRanking,
|
|
21898
|
-
search: async (text14, searchOptions) => {
|
|
21899
|
-
const
|
|
22119
|
+
search: async (text14, searchOptions, embeddingCache) => {
|
|
22120
|
+
const queryOptions = {
|
|
22121
|
+
...embeddingOptions,
|
|
22122
|
+
taskType: "memory_recall_embed",
|
|
22123
|
+
...embeddingCache && !embeddingOptions.cache && {
|
|
22124
|
+
cache: maskScopedEmbeddingCache(embeddingCache, Boolean(embeddingOptions.maskInput))
|
|
22125
|
+
}
|
|
22126
|
+
};
|
|
22127
|
+
const { prepare } = operation("recall", queryOptions);
|
|
21900
22128
|
const prepared = await prepare(text14, searchOptions);
|
|
21901
|
-
const ranked = await rankPreparedVaultCandidates(
|
|
21902
|
-
text14,
|
|
21903
|
-
prepared,
|
|
21904
|
-
{ ...embeddingOptions, taskType: "memory_recall_embed" },
|
|
21905
|
-
searchOptions
|
|
21906
|
-
);
|
|
22129
|
+
const ranked = await rankPreparedVaultCandidates(text14, prepared, queryOptions, searchOptions);
|
|
21907
22130
|
return {
|
|
21908
22131
|
...ranked,
|
|
21909
22132
|
rankedOnCosine: prepared.memories.length > 0 && !prepared.embeddingsUnavailable,
|
|
@@ -21918,7 +22141,7 @@ function createRemoteMemoryPipeline(options) {
|
|
|
21918
22141
|
factSource,
|
|
21919
22142
|
recall: async (query, recallOptions = {}) => recall(query, { embeddingOptions, factSource }, { ...recallOptions, types: ["fact"] }),
|
|
21920
22143
|
retain: async (content, retainOptions) => {
|
|
21921
|
-
const { port } = operation("retain");
|
|
22144
|
+
const { port } = operation("retain", embeddingOptions, retainOptions);
|
|
21922
22145
|
return retainWithPersistence(
|
|
21923
22146
|
content,
|
|
21924
22147
|
{
|
|
@@ -22500,16 +22723,21 @@ function createRemoteMemoryStore(options) {
|
|
|
22500
22723
|
const record2 = await persistence.get(id);
|
|
22501
22724
|
return record2 && !record2.memory.is_deleted ? record2 : null;
|
|
22502
22725
|
};
|
|
22503
|
-
const mutateLocked = async (id, change, edit) => {
|
|
22504
|
-
|
|
22726
|
+
const mutateLocked = async (id, change, edit, writeOptions) => {
|
|
22727
|
+
writeOptions?.signal?.throwIfAborted();
|
|
22728
|
+
const record2 = writeOptions?.signal ? await persistence.get(id, writeOptions.signal) : await live(id);
|
|
22505
22729
|
if (!record2) return null;
|
|
22730
|
+
if (record2.memory.is_deleted) return null;
|
|
22731
|
+
if (writeOptions?.canWrite && !await writeOptions.canWrite())
|
|
22732
|
+
throw new Error("Memory source is no longer eligible");
|
|
22733
|
+
writeOptions?.signal?.throwIfAborted();
|
|
22506
22734
|
const next = edit(structuredClone(record2.memory));
|
|
22507
22735
|
if (!next) return null;
|
|
22508
|
-
const saved = await persistence.put(next, record2);
|
|
22736
|
+
const saved = writeOptions?.signal ? await persistence.put(next, record2, writeOptions.signal) : await persistence.put(next, record2);
|
|
22509
22737
|
notify(typeof change === "function" ? change(record2.memory) : change, [saved]);
|
|
22510
22738
|
return saved;
|
|
22511
22739
|
};
|
|
22512
|
-
const mutate = (id, change, edit) => serialized(id, () => mutateLocked(id, change, edit));
|
|
22740
|
+
const mutate = (id, change, edit, writeOptions) => serialized(id, () => mutateLocked(id, change, edit, writeOptions));
|
|
22513
22741
|
const serializedAll = (ids, task) => [...new Set(ids)].sort().reduceRight((inner, id) => () => serialized(id, inner), task)();
|
|
22514
22742
|
const mutateMany = async (ids, change, edit) => {
|
|
22515
22743
|
const saved = /* @__PURE__ */ new Map();
|
|
@@ -23022,13 +23250,21 @@ function createRemoteMemoryStore(options) {
|
|
|
23022
23250
|
}))
|
|
23023
23251
|
);
|
|
23024
23252
|
},
|
|
23025
|
-
addTopics: async (memoryId, topics) => {
|
|
23253
|
+
addTopics: async (memoryId, topics, writeOptions) => {
|
|
23026
23254
|
const added = await withKnownKinds(topicInputs(topics, "auto"));
|
|
23027
|
-
const saved = await mutate(
|
|
23028
|
-
|
|
23029
|
-
|
|
23030
|
-
|
|
23031
|
-
|
|
23255
|
+
const saved = await mutate(
|
|
23256
|
+
memoryId,
|
|
23257
|
+
"edit",
|
|
23258
|
+
(memory) => {
|
|
23259
|
+
if (writeOptions?.unlessUserManaged && memory.topics_user_managed) return null;
|
|
23260
|
+
return {
|
|
23261
|
+
...memory,
|
|
23262
|
+
topics: serializeTopics(mergeTopics(parseTopics(memory.topics) ?? [], added)),
|
|
23263
|
+
topics_updated_at: Date.now()
|
|
23264
|
+
};
|
|
23265
|
+
},
|
|
23266
|
+
writeOptions
|
|
23267
|
+
);
|
|
23032
23268
|
if (!saved) return [];
|
|
23033
23269
|
const now = /* @__PURE__ */ new Date();
|
|
23034
23270
|
return mergeTopics([], added).map(
|
|
@@ -23879,6 +24115,7 @@ function createDurableAutoExtractor(options) {
|
|
|
23879
24115
|
};
|
|
23880
24116
|
const folderId = options.folderId ?? null;
|
|
23881
24117
|
let disposed = false;
|
|
24118
|
+
let activeBatch = null;
|
|
23882
24119
|
let running = false;
|
|
23883
24120
|
let wakeRequested = false;
|
|
23884
24121
|
let timer;
|
|
@@ -23915,14 +24152,18 @@ function createDurableAutoExtractor(options) {
|
|
|
23915
24152
|
}, delay);
|
|
23916
24153
|
}
|
|
23917
24154
|
async function extractBatch(messages, conversationId, ids, jobScope, jobFolderId) {
|
|
24155
|
+
if (disposed) throw new Error("Extraction session was disposed");
|
|
23918
24156
|
let watchdog;
|
|
23919
24157
|
let cancelled = false;
|
|
24158
|
+
const controller = new AbortController();
|
|
24159
|
+
activeBatch = controller;
|
|
23920
24160
|
const model = options.modelForScope?.(jobScope) ?? options.extract.model;
|
|
23921
24161
|
try {
|
|
23922
24162
|
return await Promise.race([
|
|
23923
24163
|
new Promise((resolve, reject) => {
|
|
23924
24164
|
const worker = createAutoExtractor({
|
|
23925
24165
|
...options,
|
|
24166
|
+
signal: controller.signal,
|
|
23926
24167
|
retainCtx: {
|
|
23927
24168
|
...options.retainCtx,
|
|
23928
24169
|
vaultCtx: {
|
|
@@ -23951,6 +24192,8 @@ function createDurableAutoExtractor(options) {
|
|
|
23951
24192
|
]);
|
|
23952
24193
|
} finally {
|
|
23953
24194
|
cancelled = true;
|
|
24195
|
+
controller.abort();
|
|
24196
|
+
if (activeBatch === controller) activeBatch = null;
|
|
23954
24197
|
if (watchdog !== void 0) clearTimeout(watchdog);
|
|
23955
24198
|
}
|
|
23956
24199
|
}
|
|
@@ -23962,6 +24205,7 @@ function createDurableAutoExtractor(options) {
|
|
|
23962
24205
|
for (const message of loaded)
|
|
23963
24206
|
if (message && message.messageId > 0) sequences.set(message.uniqueId, message.messageId);
|
|
23964
24207
|
await database.write(async () => {
|
|
24208
|
+
if (disposed) return;
|
|
23965
24209
|
const current = idsOf(job);
|
|
23966
24210
|
const acknowledged = ids.filter((id) => current.includes(id));
|
|
23967
24211
|
if (!acknowledged.length) return;
|
|
@@ -24134,6 +24378,7 @@ function createDurableAutoExtractor(options) {
|
|
|
24134
24378
|
jobScope,
|
|
24135
24379
|
jobFolderId
|
|
24136
24380
|
);
|
|
24381
|
+
if (disposed) throw new Error("Extraction session was disposed");
|
|
24137
24382
|
options.onTurnComplete?.(result);
|
|
24138
24383
|
return result;
|
|
24139
24384
|
};
|
|
@@ -24170,6 +24415,7 @@ function createDurableAutoExtractor(options) {
|
|
|
24170
24415
|
);
|
|
24171
24416
|
scheduleAfterSuccess = true;
|
|
24172
24417
|
} catch (error) {
|
|
24418
|
+
if (disposed) break;
|
|
24173
24419
|
attempts.set(job.id, attempted + 1);
|
|
24174
24420
|
retry = true;
|
|
24175
24421
|
reportError(error, conversationId);
|
|
@@ -24192,6 +24438,14 @@ function createDurableAutoExtractor(options) {
|
|
|
24192
24438
|
schedule(retry ? options.retryDelayMs ?? 3e4 : 0);
|
|
24193
24439
|
}
|
|
24194
24440
|
}
|
|
24441
|
+
function dispose() {
|
|
24442
|
+
disposed = true;
|
|
24443
|
+
activeBatch?.abort(options.signal?.reason);
|
|
24444
|
+
if (timer !== void 0) clearTimeout(timer);
|
|
24445
|
+
options.signal?.removeEventListener("abort", dispose);
|
|
24446
|
+
}
|
|
24447
|
+
if (options.signal?.aborted) dispose();
|
|
24448
|
+
else options.signal?.addEventListener("abort", dispose, { once: true });
|
|
24195
24449
|
schedule(0);
|
|
24196
24450
|
return {
|
|
24197
24451
|
processTurn(messages, conversationId) {
|
|
@@ -24271,10 +24525,7 @@ function createDurableAutoExtractor(options) {
|
|
|
24271
24525
|
return true;
|
|
24272
24526
|
},
|
|
24273
24527
|
isProcessing: () => running,
|
|
24274
|
-
dispose
|
|
24275
|
-
disposed = true;
|
|
24276
|
-
if (timer !== void 0) clearTimeout(timer);
|
|
24277
|
-
}
|
|
24528
|
+
dispose
|
|
24278
24529
|
};
|
|
24279
24530
|
}
|
|
24280
24531
|
|
|
@@ -30535,6 +30786,7 @@ var CONVERSATION_REDACTOR_LIMIT = 50;
|
|
|
30535
30786
|
var NO_CONVERSATION_KEY = "__no_conversation__";
|
|
30536
30787
|
var NO_STORE_FOLDERS = "Folders are not supported with a memoryStore";
|
|
30537
30788
|
var NO_STORE_MASK = "piiRedaction needs a memoryStore built with embeddingOptions.maskInput";
|
|
30789
|
+
var MEMORY_STORE_NOT_READY = "Memory store is not ready";
|
|
30538
30790
|
var conversationRedactors = /* @__PURE__ */ new Map();
|
|
30539
30791
|
function getConversationRedactor(conversationId, nerDetector) {
|
|
30540
30792
|
const key = conversationId ?? NO_CONVERSATION_KEY;
|
|
@@ -30625,7 +30877,7 @@ function useChatStorage(options) {
|
|
|
30625
30877
|
() => ({ getToken, baseUrl, model: embeddingModel, maskInput: maskEmbeddingInput }),
|
|
30626
30878
|
[getToken, baseUrl, embeddingModel, maskEmbeddingInput]
|
|
30627
30879
|
);
|
|
30628
|
-
const storeMaskMissing = memoryStore !== void 0 && maskEmbeddingInput !== void 0 && !memoryStore.masksEmbeddingInput;
|
|
30880
|
+
const storeMaskMissing = memoryStore !== void 0 && memoryStore !== null && maskEmbeddingInput !== void 0 && !memoryStore.masksEmbeddingInput;
|
|
30629
30881
|
const blobManagerRef = useRef4(new BlobUrlManager());
|
|
30630
30882
|
useEffect4(() => {
|
|
30631
30883
|
const manager = blobManagerRef.current;
|
|
@@ -30902,6 +31154,7 @@ function useChatStorage(options) {
|
|
|
30902
31154
|
);
|
|
30903
31155
|
const retainVaultMemory = useCallback5(
|
|
30904
31156
|
async (input) => {
|
|
31157
|
+
if (memoryStore === null) throw new Error(MEMORY_STORE_NOT_READY);
|
|
30905
31158
|
if (memoryStore) {
|
|
30906
31159
|
if (storeMaskMissing) throw new Error(NO_STORE_MASK);
|
|
30907
31160
|
if (input.folderId !== void 0) throw new Error(NO_STORE_FOLDERS);
|
|
@@ -30933,6 +31186,7 @@ function useChatStorage(options) {
|
|
|
30933
31186
|
);
|
|
30934
31187
|
const createMemoryVaultTool2 = useCallback5(
|
|
30935
31188
|
(options2) => {
|
|
31189
|
+
if (memoryStore === null) throw new Error(MEMORY_STORE_NOT_READY);
|
|
30936
31190
|
if (storeMaskMissing) throw new Error(NO_STORE_MASK);
|
|
30937
31191
|
const embOpts = getToken ? vaultEmbeddingOptions : void 0;
|
|
30938
31192
|
return createMemoryVaultTool(
|
|
@@ -30954,6 +31208,7 @@ function useChatStorage(options) {
|
|
|
30954
31208
|
);
|
|
30955
31209
|
const getVaultMemories = useCallback5(
|
|
30956
31210
|
(options2) => {
|
|
31211
|
+
if (memoryStore === null) return Promise.resolve([]);
|
|
30957
31212
|
if (!memoryStore) return getAllVaultMemoriesOp(vaultCtx, options2);
|
|
30958
31213
|
const { folderId, levels, kinds, ...listOptions } = options2 ?? {};
|
|
30959
31214
|
if (folderId !== void 0) throw new Error(NO_STORE_FOLDERS);
|
|
@@ -30965,6 +31220,7 @@ function useChatStorage(options) {
|
|
|
30965
31220
|
);
|
|
30966
31221
|
const createVaultMemory = useCallback5(
|
|
30967
31222
|
async (content, scope) => {
|
|
31223
|
+
if (memoryStore === null) throw new Error(MEMORY_STORE_NOT_READY);
|
|
30968
31224
|
if (storeMaskMissing) throw new Error(NO_STORE_MASK);
|
|
30969
31225
|
if (memoryStore) return memoryStore.create({ content, scope });
|
|
30970
31226
|
const result = await createVaultMemoryOp(vaultCtx, { content, scope });
|
|
@@ -30986,6 +31242,7 @@ function useChatStorage(options) {
|
|
|
30986
31242
|
);
|
|
30987
31243
|
const updateVaultMemory = useCallback5(
|
|
30988
31244
|
async (id, content, scope) => {
|
|
31245
|
+
if (memoryStore === null) throw new Error(MEMORY_STORE_NOT_READY);
|
|
30989
31246
|
if (storeMaskMissing) throw new Error(NO_STORE_MASK);
|
|
30990
31247
|
if (memoryStore) return memoryStore.update(id, { content, scope });
|
|
30991
31248
|
const existing = await getVaultMemoryOp(vaultCtx, id);
|
|
@@ -31011,6 +31268,7 @@ function useChatStorage(options) {
|
|
|
31011
31268
|
);
|
|
31012
31269
|
const deleteVaultMemory = useCallback5(
|
|
31013
31270
|
async (id) => {
|
|
31271
|
+
if (memoryStore === null) throw new Error(MEMORY_STORE_NOT_READY);
|
|
31014
31272
|
if (memoryStore) return memoryStore.delete(id);
|
|
31015
31273
|
const existing = await getVaultMemoryOp(vaultCtx, id);
|
|
31016
31274
|
const result = await deleteVaultMemoryOp(vaultCtx, id);
|
|
@@ -31024,7 +31282,7 @@ function useChatStorage(options) {
|
|
|
31024
31282
|
const chunkVectorCacheRef = useRef4(createChunkVectorCache());
|
|
31025
31283
|
const clientToolEmbeddingsCacheRef = useRef4(/* @__PURE__ */ new Map());
|
|
31026
31284
|
useEffect4(() => {
|
|
31027
|
-
if (!getToken || memoryStore) return;
|
|
31285
|
+
if (!getToken || memoryStore !== void 0) return;
|
|
31028
31286
|
void (async () => {
|
|
31029
31287
|
try {
|
|
31030
31288
|
await preEmbedVaultMemories(vaultCtx, vaultEmbeddingOptions, vaultEmbeddingCache);
|
|
@@ -31040,6 +31298,7 @@ function useChatStorage(options) {
|
|
|
31040
31298
|
}, [vaultEmbeddingCache]);
|
|
31041
31299
|
const createMemoryVaultSearchTool2 = useCallback5(
|
|
31042
31300
|
(searchOptions) => {
|
|
31301
|
+
if (memoryStore === null) throw new Error(MEMORY_STORE_NOT_READY);
|
|
31043
31302
|
if (!getToken && !memoryStore) {
|
|
31044
31303
|
throw new Error("getToken is required for memory vault search tool");
|
|
31045
31304
|
}
|
|
@@ -31055,6 +31314,7 @@ function useChatStorage(options) {
|
|
|
31055
31314
|
);
|
|
31056
31315
|
const createRecallTool2 = useCallback5(
|
|
31057
31316
|
(toolOptions, callbacks) => {
|
|
31317
|
+
if (memoryStore === null) throw new Error(MEMORY_STORE_NOT_READY);
|
|
31058
31318
|
if (!getToken && !memoryStore) {
|
|
31059
31319
|
throw new Error("getToken is required for recall tool");
|
|
31060
31320
|
}
|
|
@@ -31094,6 +31354,7 @@ function useChatStorage(options) {
|
|
|
31094
31354
|
);
|
|
31095
31355
|
const searchVaultMemoriesFn = useCallback5(
|
|
31096
31356
|
async (query, searchOptions) => {
|
|
31357
|
+
if (memoryStore === null) return [];
|
|
31097
31358
|
if (storeMaskMissing) throw new Error(NO_STORE_MASK);
|
|
31098
31359
|
if (memoryStore) return (await memoryStore.factSource.search(query, searchOptions)).results;
|
|
31099
31360
|
if (!getToken) return [];
|
|
@@ -31109,7 +31370,7 @@ function useChatStorage(options) {
|
|
|
31109
31370
|
);
|
|
31110
31371
|
const recallFn = useCallback5(
|
|
31111
31372
|
async (query, options2) => {
|
|
31112
|
-
if (!getToken && !memoryStore) {
|
|
31373
|
+
if (memoryStore === null || !getToken && !memoryStore) {
|
|
31113
31374
|
return {
|
|
31114
31375
|
memories: [],
|
|
31115
31376
|
usedBudget: options2?.budget ?? "low",
|