@anuma/sdk 6.35.0 → 6.36.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/expo/index.cjs +646 -38
- package/dist/expo/index.d.mts +74 -1
- package/dist/expo/index.d.ts +74 -1
- package/dist/expo/index.mjs +639 -38
- package/dist/react/index.cjs +636 -28
- package/dist/react/index.d.mts +74 -1
- package/dist/react/index.d.ts +74 -1
- package/dist/react/index.mjs +629 -28
- package/package.json +1 -1
package/dist/expo/index.cjs
CHANGED
|
@@ -1391,6 +1391,7 @@ __export(index_exports, {
|
|
|
1391
1391
|
MEDIUM_TTL_MS: () => MEDIUM_TTL_MS,
|
|
1392
1392
|
MEMORY_KINDS: () => MEMORY_KINDS,
|
|
1393
1393
|
MEMORY_LEVELS: () => MEMORY_LEVELS,
|
|
1394
|
+
MemoryKeyError: () => MemoryKeyError,
|
|
1394
1395
|
MemoryLevelError: () => MemoryLevelError,
|
|
1395
1396
|
NEVER_TTL_MS: () => NEVER_TTL_MS,
|
|
1396
1397
|
NODE_BUDGET: () => NODE_BUDGET,
|
|
@@ -1403,6 +1404,7 @@ __export(index_exports, {
|
|
|
1403
1404
|
RECALL_MAX_LIMIT: () => RECALL_MAX_LIMIT,
|
|
1404
1405
|
RECALL_TOOL_NAME: () => RECALL_TOOL_NAME,
|
|
1405
1406
|
RemoteMemoryError: () => RemoteMemoryError,
|
|
1407
|
+
RemoteMemoryPartialCreateError: () => RemoteMemoryPartialCreateError,
|
|
1406
1408
|
RerankerUnavailableError: () => RerankerUnavailableError,
|
|
1407
1409
|
SDK_SCHEMA_VERSION: () => SDK_SCHEMA_VERSION,
|
|
1408
1410
|
SHORT_TTL_MS: () => SHORT_TTL_MS,
|
|
@@ -1468,6 +1470,7 @@ __export(index_exports, {
|
|
|
1468
1470
|
createRecallTool: () => createRecallTool,
|
|
1469
1471
|
createRemoteMemoryPersistence: () => createRemoteMemoryPersistence,
|
|
1470
1472
|
createRemoteMemoryPipeline: () => createRemoteMemoryPipeline,
|
|
1473
|
+
createRemoteMemoryStore: () => createRemoteMemoryStore,
|
|
1471
1474
|
createStockPricePreProcessor: () => createStockPricePreProcessor,
|
|
1472
1475
|
createStreamingDeAnonymizer: () => createStreamingDeAnonymizer,
|
|
1473
1476
|
createVaultEmbeddingCache: () => createVaultEmbeddingCache,
|
|
@@ -1484,6 +1487,7 @@ __export(index_exports, {
|
|
|
1484
1487
|
deleteVaultMemoryOp: () => deleteVaultMemoryOp,
|
|
1485
1488
|
dequantizeEmbedding: () => dequantizeEmbedding,
|
|
1486
1489
|
deriveKeyFromSignatureBytes: () => deriveKeyFromSignatureBytes,
|
|
1490
|
+
deriveMemoryKeyRing: () => deriveMemoryKeyRing,
|
|
1487
1491
|
discoverNotionOAuthEndpoints: () => discoverNotionOAuthEndpoints,
|
|
1488
1492
|
eagerEmbedContent: () => eagerEmbedContent,
|
|
1489
1493
|
embedAllMessages: () => embedAllMessages,
|
|
@@ -1527,6 +1531,7 @@ __export(index_exports, {
|
|
|
1527
1531
|
isPiiRedactor: () => isPiiRedactor,
|
|
1528
1532
|
isRerankerAvailable: () => isRerankerAvailable,
|
|
1529
1533
|
maskScopedEmbeddingCache: () => maskScopedEmbeddingCache,
|
|
1534
|
+
memoryCipher: () => memoryCipher,
|
|
1530
1535
|
moveMemoriesToFolderOp: () => moveMemoriesToFolderOp,
|
|
1531
1536
|
noopLogger: () => noopLogger,
|
|
1532
1537
|
onKeyAvailable: () => onKeyAvailable,
|
|
@@ -1536,6 +1541,7 @@ __export(index_exports, {
|
|
|
1536
1541
|
queueManager: () => queueManager,
|
|
1537
1542
|
rankProfileCandidates: () => rankProfileCandidates,
|
|
1538
1543
|
recall: () => recall,
|
|
1544
|
+
reencryptMemoryField: () => reencryptMemoryField,
|
|
1539
1545
|
reflect: () => reflect,
|
|
1540
1546
|
refreshEncryptionKeyIfMatches: () => refreshEncryptionKeyIfMatches,
|
|
1541
1547
|
refreshNotionAccessToken: () => refreshNotionAccessToken,
|
|
@@ -3919,14 +3925,14 @@ async function updateMessageEmbeddingOp(ctx, uniqueId, vector, embeddingModel) {
|
|
|
3919
3925
|
});
|
|
3920
3926
|
return messageToStored(message, ctx.walletAddress, ctx.signMessage, ctx.embeddedWalletSigner);
|
|
3921
3927
|
}
|
|
3922
|
-
async function updateMessageChunksOp(ctx, uniqueId,
|
|
3928
|
+
async function updateMessageChunksOp(ctx, uniqueId, chunks2, embeddingModel) {
|
|
3923
3929
|
let message;
|
|
3924
3930
|
try {
|
|
3925
3931
|
message = await ctx.messagesCollection.find(uniqueId);
|
|
3926
3932
|
} catch {
|
|
3927
3933
|
return null;
|
|
3928
3934
|
}
|
|
3929
|
-
const storedChunks =
|
|
3935
|
+
const storedChunks = chunks2.map(({ text: _text, ...rest }) => rest);
|
|
3930
3936
|
await ctx.database.write(async () => {
|
|
3931
3937
|
await message.update((msg) => {
|
|
3932
3938
|
msg._setRaw("chunks", JSON.stringify(storedChunks));
|
|
@@ -3970,12 +3976,12 @@ async function stripLegacyChunkTextOp(ctx) {
|
|
|
3970
3976
|
const messages = await ctx.messagesCollection.query(import_watermelondb2.Q.where("id", import_watermelondb2.Q.oneOf(changedIds))).fetch();
|
|
3971
3977
|
const updates = messages.flatMap((message) => {
|
|
3972
3978
|
const raw = message._raw;
|
|
3973
|
-
const
|
|
3974
|
-
if (!
|
|
3979
|
+
const chunks2 = chunksWithoutText(raw.chunks);
|
|
3980
|
+
if (!chunks2) return [];
|
|
3975
3981
|
const updatedAt = raw.updated_at;
|
|
3976
3982
|
return [
|
|
3977
3983
|
message.prepareUpdate((msg) => {
|
|
3978
|
-
msg._setRaw("chunks", JSON.stringify(
|
|
3984
|
+
msg._setRaw("chunks", JSON.stringify(chunks2));
|
|
3979
3985
|
msg._setRaw("updated_at", updatedAt);
|
|
3980
3986
|
})
|
|
3981
3987
|
];
|
|
@@ -4136,15 +4142,15 @@ async function searchChunksOp(ctx, queryVector, options) {
|
|
|
4136
4142
|
}
|
|
4137
4143
|
continue;
|
|
4138
4144
|
}
|
|
4139
|
-
const
|
|
4140
|
-
if (
|
|
4141
|
-
const vectors =
|
|
4145
|
+
const chunks2 = await readRawJsonField(message, "chunks", ctx.walletAddress);
|
|
4146
|
+
if (chunks2 && chunks2.length > 0) {
|
|
4147
|
+
const vectors = chunks2.map(
|
|
4142
4148
|
(chunk) => decodeChunkVector(chunk.vector, () => {
|
|
4143
4149
|
unreadableVectors++;
|
|
4144
4150
|
})
|
|
4145
4151
|
);
|
|
4146
4152
|
chunkCache?.set(message.id, { version, chunks: vectors });
|
|
4147
|
-
for (let ci = 0; ci <
|
|
4153
|
+
for (let ci = 0; ci < chunks2.length; ci++) {
|
|
4148
4154
|
const vec = vectors[ci];
|
|
4149
4155
|
if (vec.length === 0) continue;
|
|
4150
4156
|
const similarity = cosineSimilarity(queryVector, vec);
|
|
@@ -4152,7 +4158,7 @@ async function searchChunksOp(ctx, queryVector, options) {
|
|
|
4152
4158
|
candidates.push({
|
|
4153
4159
|
message,
|
|
4154
4160
|
similarity,
|
|
4155
|
-
chunkTextSource: { kind: "chunk", chunk:
|
|
4161
|
+
chunkTextSource: { kind: "chunk", chunk: chunks2[ci], siblings: chunks2 }
|
|
4156
4162
|
});
|
|
4157
4163
|
}
|
|
4158
4164
|
}
|
|
@@ -4304,7 +4310,7 @@ function chunkText(text12, options) {
|
|
|
4304
4310
|
];
|
|
4305
4311
|
}
|
|
4306
4312
|
const sentences = splitIntoSentences(text12);
|
|
4307
|
-
const
|
|
4313
|
+
const chunks2 = [];
|
|
4308
4314
|
let currentChunkSentences = [];
|
|
4309
4315
|
let currentChunkStart = 0;
|
|
4310
4316
|
let currentOffset = 0;
|
|
@@ -4318,7 +4324,7 @@ function chunkText(text12, options) {
|
|
|
4318
4324
|
if (sentence.length > chunkSize) {
|
|
4319
4325
|
if (currentChunkSentences.length > 0) {
|
|
4320
4326
|
const chunkText2 = currentChunkSentences.join(" ");
|
|
4321
|
-
|
|
4327
|
+
chunks2.push({
|
|
4322
4328
|
text: chunkText2,
|
|
4323
4329
|
startOffset: currentChunkStart,
|
|
4324
4330
|
endOffset: currentOffset
|
|
@@ -4329,7 +4335,7 @@ function chunkText(text12, options) {
|
|
|
4329
4335
|
const chunkEnd = Math.min(j + chunkSize, sentence.length);
|
|
4330
4336
|
const chunk = sentence.slice(j, chunkEnd);
|
|
4331
4337
|
if (chunk.length >= minChunkSize) {
|
|
4332
|
-
|
|
4338
|
+
chunks2.push({
|
|
4333
4339
|
text: chunk,
|
|
4334
4340
|
startOffset: sentenceStart + j,
|
|
4335
4341
|
endOffset: sentenceStart + chunkEnd
|
|
@@ -4343,7 +4349,7 @@ function chunkText(text12, options) {
|
|
|
4343
4349
|
const currentText = currentChunkSentences.join(" ");
|
|
4344
4350
|
const potentialLength = currentText.length + (currentText ? 1 : 0) + sentence.length;
|
|
4345
4351
|
if (potentialLength > chunkSize && currentChunkSentences.length > 0) {
|
|
4346
|
-
|
|
4352
|
+
chunks2.push({
|
|
4347
4353
|
text: currentText,
|
|
4348
4354
|
startOffset: currentChunkStart,
|
|
4349
4355
|
endOffset: currentOffset
|
|
@@ -4374,14 +4380,14 @@ function chunkText(text12, options) {
|
|
|
4374
4380
|
if (currentChunkSentences.length > 0) {
|
|
4375
4381
|
const chunkText2 = currentChunkSentences.join(" ");
|
|
4376
4382
|
if (chunkText2.length >= minChunkSize) {
|
|
4377
|
-
|
|
4383
|
+
chunks2.push({
|
|
4378
4384
|
text: chunkText2,
|
|
4379
4385
|
startOffset: currentChunkStart,
|
|
4380
4386
|
endOffset: text12.length
|
|
4381
4387
|
});
|
|
4382
4388
|
}
|
|
4383
4389
|
}
|
|
4384
|
-
if (
|
|
4390
|
+
if (chunks2.length === 0) {
|
|
4385
4391
|
const trimmedText = text12.trim();
|
|
4386
4392
|
if (trimmedText.length > 0) {
|
|
4387
4393
|
return [
|
|
@@ -4393,7 +4399,7 @@ function chunkText(text12, options) {
|
|
|
4393
4399
|
];
|
|
4394
4400
|
}
|
|
4395
4401
|
}
|
|
4396
|
-
return
|
|
4402
|
+
return chunks2;
|
|
4397
4403
|
}
|
|
4398
4404
|
function shouldChunkMessage(content, chunkSize = DEFAULT_CHUNK_SIZE) {
|
|
4399
4405
|
return content.length > chunkSize;
|
|
@@ -4465,9 +4471,9 @@ function createSseClient({
|
|
|
4465
4471
|
if (done) break;
|
|
4466
4472
|
buffer += value;
|
|
4467
4473
|
buffer = buffer.replace(/\r\n?/g, "\n");
|
|
4468
|
-
const
|
|
4469
|
-
buffer =
|
|
4470
|
-
for (const chunk of
|
|
4474
|
+
const chunks2 = buffer.split("\n\n");
|
|
4475
|
+
buffer = chunks2.pop() ?? "";
|
|
4476
|
+
for (const chunk of chunks2) {
|
|
4471
4477
|
const lines = chunk.split("\n");
|
|
4472
4478
|
const dataLines = [];
|
|
4473
4479
|
let eventName;
|
|
@@ -5414,18 +5420,18 @@ async function embedMany(texts, options, outer) {
|
|
|
5414
5420
|
outer
|
|
5415
5421
|
);
|
|
5416
5422
|
} else {
|
|
5417
|
-
const
|
|
5423
|
+
const chunks2 = [];
|
|
5418
5424
|
for (let i = 0; i < uncachedTexts.length; i += chunkSize) {
|
|
5419
|
-
|
|
5425
|
+
chunks2.push(uncachedTexts.slice(i, i + chunkSize));
|
|
5420
5426
|
}
|
|
5421
|
-
const allEmbeddings = new Array(
|
|
5427
|
+
const allEmbeddings = new Array(chunks2.length);
|
|
5422
5428
|
let nextIndex = 0;
|
|
5423
5429
|
const worker = async () => {
|
|
5424
|
-
while (nextIndex <
|
|
5430
|
+
while (nextIndex < chunks2.length) {
|
|
5425
5431
|
if (outer?.aborted) throw outer.reason;
|
|
5426
5432
|
const idx = nextIndex++;
|
|
5427
5433
|
allEmbeddings[idx] = await generateEmbeddingsBatch(
|
|
5428
|
-
|
|
5434
|
+
chunks2[idx],
|
|
5429
5435
|
headers,
|
|
5430
5436
|
baseUrl,
|
|
5431
5437
|
embeddingModel,
|
|
@@ -5437,7 +5443,7 @@ async function embedMany(texts, options, outer) {
|
|
|
5437
5443
|
}
|
|
5438
5444
|
};
|
|
5439
5445
|
const workers = Array.from(
|
|
5440
|
-
{ length: Math.min(DEFAULT_EMBEDDING_BATCH_CONCURRENCY,
|
|
5446
|
+
{ length: Math.min(DEFAULT_EMBEDDING_BATCH_CONCURRENCY, chunks2.length) },
|
|
5441
5447
|
() => worker()
|
|
5442
5448
|
);
|
|
5443
5449
|
await Promise.all(workers);
|
|
@@ -10087,7 +10093,7 @@ function sseFailureMessage(status, statusText, detail = "") {
|
|
|
10087
10093
|
return `SSE failed: ${status} ${statusText}${detail}`;
|
|
10088
10094
|
}
|
|
10089
10095
|
function parseSseChunks(raw, incompleteBuffer) {
|
|
10090
|
-
const
|
|
10096
|
+
const chunks2 = [];
|
|
10091
10097
|
const text12 = incompleteBuffer + raw;
|
|
10092
10098
|
const lines = text12.split("\n");
|
|
10093
10099
|
const remaining = raw.endsWith("\n") ? "" : lines.pop() ?? "";
|
|
@@ -10096,11 +10102,11 @@ function parseSseChunks(raw, incompleteBuffer) {
|
|
|
10096
10102
|
const data = line.substring(6).trim();
|
|
10097
10103
|
if (data === "[DONE]") continue;
|
|
10098
10104
|
try {
|
|
10099
|
-
|
|
10105
|
+
chunks2.push(JSON.parse(data));
|
|
10100
10106
|
} catch {
|
|
10101
10107
|
}
|
|
10102
10108
|
}
|
|
10103
|
-
return { chunks, remaining };
|
|
10109
|
+
return { chunks: chunks2, remaining };
|
|
10104
10110
|
}
|
|
10105
10111
|
var xhrTransport = (options) => {
|
|
10106
10112
|
const queue = [];
|
|
@@ -10169,18 +10175,18 @@ var xhrTransport = (options) => {
|
|
|
10169
10175
|
const newData = xhr.responseText.substring(lastProcessedIndex);
|
|
10170
10176
|
lastProcessedIndex = xhr.responseText.length;
|
|
10171
10177
|
if (newData.length > 0) options.onActivity?.();
|
|
10172
|
-
const { chunks, remaining } = parseSseChunks(newData, incompleteBuffer);
|
|
10178
|
+
const { chunks: chunks2, remaining } = parseSseChunks(newData, incompleteBuffer);
|
|
10173
10179
|
incompleteBuffer = remaining;
|
|
10174
|
-
for (const chunk of
|
|
10180
|
+
for (const chunk of chunks2) {
|
|
10175
10181
|
push({ type: "data", value: chunk });
|
|
10176
10182
|
}
|
|
10177
10183
|
};
|
|
10178
10184
|
xhr.onload = () => {
|
|
10179
10185
|
options.signal?.removeEventListener("abort", abortHandler);
|
|
10180
10186
|
if (incompleteBuffer) {
|
|
10181
|
-
const { chunks } = parseSseChunks(incompleteBuffer + "\n", "");
|
|
10187
|
+
const { chunks: chunks2 } = parseSseChunks(incompleteBuffer + "\n", "");
|
|
10182
10188
|
incompleteBuffer = "";
|
|
10183
|
-
for (const chunk of
|
|
10189
|
+
for (const chunk of chunks2) {
|
|
10184
10190
|
push({ type: "data", value: chunk });
|
|
10185
10191
|
}
|
|
10186
10192
|
}
|
|
@@ -19691,6 +19697,65 @@ function createLocalMemoryStore(options) {
|
|
|
19691
19697
|
};
|
|
19692
19698
|
}
|
|
19693
19699
|
|
|
19700
|
+
// src/lib/memory/store/memoryKeys.ts
|
|
19701
|
+
var KEY_ID_DOMAIN = "anuma-private-memory-key-id-v1";
|
|
19702
|
+
var MemoryKeyError = class extends Error {
|
|
19703
|
+
constructor(message) {
|
|
19704
|
+
super(message);
|
|
19705
|
+
this.name = "MemoryKeyError";
|
|
19706
|
+
}
|
|
19707
|
+
};
|
|
19708
|
+
async function importAesKey(hex) {
|
|
19709
|
+
return crypto.subtle.importKey(
|
|
19710
|
+
"raw",
|
|
19711
|
+
hexToBytes(hex).buffer,
|
|
19712
|
+
{ name: "AES-GCM" },
|
|
19713
|
+
false,
|
|
19714
|
+
["encrypt", "decrypt"]
|
|
19715
|
+
);
|
|
19716
|
+
}
|
|
19717
|
+
async function deriveMemoryKeyRing(signatureHex) {
|
|
19718
|
+
const v3Hex = await deriveKeyFromSignatureV3(signatureHex);
|
|
19719
|
+
const digest = await crypto.subtle.digest(
|
|
19720
|
+
"SHA-256",
|
|
19721
|
+
new TextEncoder().encode(`${KEY_ID_DOMAIN}:${v3Hex}`)
|
|
19722
|
+
);
|
|
19723
|
+
const keyId = "v3:" + Array.from(new Uint8Array(digest), (byte) => byte.toString(16).padStart(2, "0")).join("");
|
|
19724
|
+
return {
|
|
19725
|
+
keyId,
|
|
19726
|
+
v3: await importAesKey(v3Hex),
|
|
19727
|
+
v2: await importAesKey(await deriveKeyFromSignature(signatureHex))
|
|
19728
|
+
};
|
|
19729
|
+
}
|
|
19730
|
+
async function decryptWith(value, rings) {
|
|
19731
|
+
const version = value.startsWith("enc:v3:") ? "v3" : "v2";
|
|
19732
|
+
for (const ring of rings) {
|
|
19733
|
+
try {
|
|
19734
|
+
return await decryptDataWithKey(value.slice(`enc:${version}:`.length), ring[version]);
|
|
19735
|
+
} catch {
|
|
19736
|
+
continue;
|
|
19737
|
+
}
|
|
19738
|
+
}
|
|
19739
|
+
throw new MemoryKeyError(`No supplied key decrypts this enc:${version} field`);
|
|
19740
|
+
}
|
|
19741
|
+
function memoryCipher(canonical) {
|
|
19742
|
+
return {
|
|
19743
|
+
encrypt: async (plaintext) => `enc:v3:${await encryptDataWithKey(plaintext, canonical.v3)}`,
|
|
19744
|
+
decrypt: async (ciphertext) => {
|
|
19745
|
+
if (!ciphertext.startsWith("enc:v3:") || !isEncrypted(ciphertext))
|
|
19746
|
+
throw new MemoryKeyError("Remote memory content must be enc:v3 ciphertext");
|
|
19747
|
+
return decryptWith(ciphertext, [canonical]);
|
|
19748
|
+
}
|
|
19749
|
+
};
|
|
19750
|
+
}
|
|
19751
|
+
async function reencryptMemoryField(value, canonical, fallbacks = []) {
|
|
19752
|
+
const { encrypt } = memoryCipher(canonical);
|
|
19753
|
+
if (!value.startsWith("enc:")) return encrypt(value);
|
|
19754
|
+
if (!isEncrypted(value))
|
|
19755
|
+
throw new MemoryKeyError("Field has an encryption prefix but an invalid payload");
|
|
19756
|
+
return encrypt(await decryptWith(value, [canonical, ...fallbacks]));
|
|
19757
|
+
}
|
|
19758
|
+
|
|
19694
19759
|
// src/lib/memory/store/remotePersistence.ts
|
|
19695
19760
|
var RemoteMemoryError = class extends Error {
|
|
19696
19761
|
constructor(message, status, code) {
|
|
@@ -19743,6 +19808,30 @@ var candidateListLimits = [
|
|
|
19743
19808
|
["memory_ids", 1e3],
|
|
19744
19809
|
["force_ids", 100]
|
|
19745
19810
|
];
|
|
19811
|
+
var queryListLimits = [
|
|
19812
|
+
["scopes", 20],
|
|
19813
|
+
["fact_types", 20],
|
|
19814
|
+
["visibility", 20],
|
|
19815
|
+
["memory_ids", 1e3],
|
|
19816
|
+
["topics", 100]
|
|
19817
|
+
];
|
|
19818
|
+
var queryFields = [
|
|
19819
|
+
"include_deleted",
|
|
19820
|
+
"include_archived",
|
|
19821
|
+
"include_quarantined",
|
|
19822
|
+
"include_superseded",
|
|
19823
|
+
"archived_only",
|
|
19824
|
+
"scopes",
|
|
19825
|
+
"fact_types",
|
|
19826
|
+
"visibility",
|
|
19827
|
+
"memory_ids",
|
|
19828
|
+
"topics",
|
|
19829
|
+
"updated_after",
|
|
19830
|
+
"order",
|
|
19831
|
+
"cursor",
|
|
19832
|
+
"limit",
|
|
19833
|
+
"include_embeddings"
|
|
19834
|
+
];
|
|
19746
19835
|
function record(value) {
|
|
19747
19836
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
19748
19837
|
}
|
|
@@ -20077,6 +20166,35 @@ async function createRemoteMemoryPersistence(options) {
|
|
|
20077
20166
|
throw new Error("Invalid nearby batch response");
|
|
20078
20167
|
return Promise.all(result.items.map((item, i) => decodeCommitted(item, prepared[i])));
|
|
20079
20168
|
},
|
|
20169
|
+
query: async (queryOptions = {}) => {
|
|
20170
|
+
const { signal, ...query } = queryOptions;
|
|
20171
|
+
if (query.limit !== void 0 && (!Number.isInteger(query.limit) || query.limit < 1 || query.limit > 200))
|
|
20172
|
+
throw new Error("Page limit must be 1\u2013200");
|
|
20173
|
+
for (const [key, max] of queryListLimits) {
|
|
20174
|
+
const values = query[key];
|
|
20175
|
+
if (values && values.length > max)
|
|
20176
|
+
throw new Error(`Query ${key} accepts at most ${max} entries (got ${values.length})`);
|
|
20177
|
+
}
|
|
20178
|
+
const page = await request(
|
|
20179
|
+
"/memories/query",
|
|
20180
|
+
{
|
|
20181
|
+
method: "POST",
|
|
20182
|
+
body: JSON.stringify(
|
|
20183
|
+
Object.fromEntries(
|
|
20184
|
+
queryFields.filter((key) => query[key] !== void 0).map((key) => [key, query[key]])
|
|
20185
|
+
)
|
|
20186
|
+
)
|
|
20187
|
+
},
|
|
20188
|
+
signal
|
|
20189
|
+
);
|
|
20190
|
+
if (!record(page) || !Array.isArray(page.items) || page.next_cursor !== void 0 && typeof page.next_cursor !== "string" || page.changes_cursor !== void 0 && typeof page.changes_cursor !== "string")
|
|
20191
|
+
throw new Error("Invalid nearby private-memory page");
|
|
20192
|
+
return {
|
|
20193
|
+
...await decodeAll(page.items),
|
|
20194
|
+
...page.next_cursor !== void 0 && { next_cursor: page.next_cursor },
|
|
20195
|
+
...page.changes_cursor !== void 0 && { changes_cursor: page.changes_cursor }
|
|
20196
|
+
};
|
|
20197
|
+
},
|
|
20080
20198
|
candidateSet,
|
|
20081
20199
|
candidates: async (embedding, candidateOptions = {}) => decodeAll((await fetchCandidates(embedding, candidateOptions, false)).items)
|
|
20082
20200
|
};
|
|
@@ -20466,6 +20584,490 @@ function createRemoteMemoryPipeline(options) {
|
|
|
20466
20584
|
};
|
|
20467
20585
|
}
|
|
20468
20586
|
|
|
20587
|
+
// src/lib/memory/store/remoteStore.ts
|
|
20588
|
+
var import_uuid5 = require("uuid");
|
|
20589
|
+
init_logger();
|
|
20590
|
+
function relevant(change, options) {
|
|
20591
|
+
return options.includeDeleted ? change === "membership" : change !== "embedding" || !!options.embeddings;
|
|
20592
|
+
}
|
|
20593
|
+
function safely(onChange) {
|
|
20594
|
+
try {
|
|
20595
|
+
onChange();
|
|
20596
|
+
} catch (error) {
|
|
20597
|
+
getLogger().warn("[memory/remote-store] Subscriber threw:", error);
|
|
20598
|
+
}
|
|
20599
|
+
}
|
|
20600
|
+
var MAX_BATCH = 50;
|
|
20601
|
+
var MAX_QUERY_IDS = 1e3;
|
|
20602
|
+
var MAX_QUERY_TOPICS = 100;
|
|
20603
|
+
var MAX_QUERY_FILTER = 20;
|
|
20604
|
+
var RemoteMemoryPartialCreateError = class extends Error {
|
|
20605
|
+
constructor(created, cause) {
|
|
20606
|
+
super(`createMany stored ${created.length} memories before a batch failed`);
|
|
20607
|
+
this.created = created;
|
|
20608
|
+
this.cause = cause;
|
|
20609
|
+
this.name = "RemoteMemoryPartialCreateError";
|
|
20610
|
+
}
|
|
20611
|
+
};
|
|
20612
|
+
function warnFailed(failed) {
|
|
20613
|
+
if (failed.length)
|
|
20614
|
+
getLogger().warn(
|
|
20615
|
+
`[memory/remote-store] Skipping ${failed.length} undecryptable row(s)`,
|
|
20616
|
+
failed.map((failure) => failure.memory_id)
|
|
20617
|
+
);
|
|
20618
|
+
}
|
|
20619
|
+
function bounded(filters, key) {
|
|
20620
|
+
const values = filters[key];
|
|
20621
|
+
if (!values || values.length <= MAX_QUERY_FILTER) return [filters];
|
|
20622
|
+
return chunks(values, MAX_QUERY_FILTER).map((chunk) => ({ ...filters, [key]: chunk }));
|
|
20623
|
+
}
|
|
20624
|
+
function chunks(values, size) {
|
|
20625
|
+
const out = [];
|
|
20626
|
+
for (let i = 0; i < values.length; i += size) out.push(values.slice(i, i + size));
|
|
20627
|
+
return out;
|
|
20628
|
+
}
|
|
20629
|
+
function stateFilters(options) {
|
|
20630
|
+
return {
|
|
20631
|
+
include_deleted: options.includeDeleted,
|
|
20632
|
+
include_archived: options.includeArchived,
|
|
20633
|
+
include_quarantined: options.includeQuarantined,
|
|
20634
|
+
include_superseded: options.includeSuperseded
|
|
20635
|
+
};
|
|
20636
|
+
}
|
|
20637
|
+
function hidden(memory, options) {
|
|
20638
|
+
if (memory.trust_tier === "quarantined") return true;
|
|
20639
|
+
if (options.includeDeleted) return false;
|
|
20640
|
+
return !!memory.is_deleted || memory.archived_at !== void 0 && memory.archived_at !== null || !!memory.superseded_by;
|
|
20641
|
+
}
|
|
20642
|
+
function subscriptionKey({ memory, version }, options) {
|
|
20643
|
+
if (hidden(memory, options)) return void 0;
|
|
20644
|
+
if (options.includeDeleted) return String(!!memory.is_deleted);
|
|
20645
|
+
return JSON.stringify([
|
|
20646
|
+
options.embeddings ? version : null,
|
|
20647
|
+
memory.content,
|
|
20648
|
+
memory.scope,
|
|
20649
|
+
memory.updated_at,
|
|
20650
|
+
memory.fact_type,
|
|
20651
|
+
memory.event_time_start,
|
|
20652
|
+
memory.event_time_end,
|
|
20653
|
+
memory.event_time_kind,
|
|
20654
|
+
memory.trust_tier,
|
|
20655
|
+
memory.visibility,
|
|
20656
|
+
memory.published_at,
|
|
20657
|
+
memory.geohash,
|
|
20658
|
+
memory.topics,
|
|
20659
|
+
memory.topics_user_managed,
|
|
20660
|
+
memory.media,
|
|
20661
|
+
memory.source
|
|
20662
|
+
]);
|
|
20663
|
+
}
|
|
20664
|
+
function topicInputs(topics, source) {
|
|
20665
|
+
return topics.flatMap((topic) => {
|
|
20666
|
+
const name = (typeof topic === "string" ? topic : topic.name).trim();
|
|
20667
|
+
const kind = typeof topic === "string" ? void 0 : topic.kind;
|
|
20668
|
+
return name ? [{ name, ...kind && { kind }, source }] : [];
|
|
20669
|
+
});
|
|
20670
|
+
}
|
|
20671
|
+
function mergeTopics(existing, added) {
|
|
20672
|
+
const byName = /* @__PURE__ */ new Map();
|
|
20673
|
+
for (const topic of [...existing, ...added]) {
|
|
20674
|
+
const key = normalizeEntityName(topic.name);
|
|
20675
|
+
if (!byName.has(key)) byName.set(key, topic);
|
|
20676
|
+
}
|
|
20677
|
+
return [...byName.values()];
|
|
20678
|
+
}
|
|
20679
|
+
function canonicalTopics(row) {
|
|
20680
|
+
return new Set((parseTopics(row.topics) ?? []).map((topic) => normalizeEntityName(topic.name)));
|
|
20681
|
+
}
|
|
20682
|
+
function createRemoteMemoryStore(options) {
|
|
20683
|
+
const { persistence, embeddingOptions } = options;
|
|
20684
|
+
const model = embeddingOptions.model ?? DEFAULT_API_EMBEDDING_MODEL;
|
|
20685
|
+
const pollIntervalMs = options.pollIntervalMs ?? 6e4;
|
|
20686
|
+
const pipeline = createRemoteMemoryPipeline(options);
|
|
20687
|
+
const subscribers = /* @__PURE__ */ new Set();
|
|
20688
|
+
const seen = /* @__PURE__ */ new Map();
|
|
20689
|
+
let timer;
|
|
20690
|
+
const notify = (change, records = []) => {
|
|
20691
|
+
if (timer) for (const record2 of records) seen.set(record2.memory.memory_id, record2);
|
|
20692
|
+
for (const subscriber of [...subscribers])
|
|
20693
|
+
if (relevant(change, subscriber.options)) safely(subscriber.onChange);
|
|
20694
|
+
};
|
|
20695
|
+
const enumerate = async (filters, max = Infinity) => {
|
|
20696
|
+
const records = [];
|
|
20697
|
+
let cursor2;
|
|
20698
|
+
do {
|
|
20699
|
+
const page = await persistence.query({
|
|
20700
|
+
...filters,
|
|
20701
|
+
limit: Math.min(200, Math.max(1, max - records.length)),
|
|
20702
|
+
...cursor2 && { cursor: cursor2 }
|
|
20703
|
+
});
|
|
20704
|
+
warnFailed(page.failed);
|
|
20705
|
+
records.push(...page.items);
|
|
20706
|
+
cursor2 = page.next_cursor;
|
|
20707
|
+
} while (cursor2 && records.length < max);
|
|
20708
|
+
return records.slice(0, max);
|
|
20709
|
+
};
|
|
20710
|
+
const enumerateIds = async (ids, filters) => (await Promise.all(
|
|
20711
|
+
chunks([...new Set(ids)], MAX_QUERY_IDS).map(
|
|
20712
|
+
(memory_ids) => enumerate({ ...filters, memory_ids })
|
|
20713
|
+
)
|
|
20714
|
+
)).flat();
|
|
20715
|
+
const queues = /* @__PURE__ */ new Map();
|
|
20716
|
+
const serialized = (id, task) => {
|
|
20717
|
+
const run = (queues.get(id) ?? Promise.resolve()).then(task, task);
|
|
20718
|
+
const settled = run.catch(() => void 0);
|
|
20719
|
+
queues.set(id, settled);
|
|
20720
|
+
void settled.then(() => {
|
|
20721
|
+
if (queues.get(id) === settled) queues.delete(id);
|
|
20722
|
+
});
|
|
20723
|
+
return run;
|
|
20724
|
+
};
|
|
20725
|
+
const live = async (id) => {
|
|
20726
|
+
const record2 = await persistence.get(id);
|
|
20727
|
+
return record2 && !record2.memory.is_deleted ? record2 : null;
|
|
20728
|
+
};
|
|
20729
|
+
const mutate = async (id, change, edit) => serialized(id, async () => {
|
|
20730
|
+
const record2 = await live(id);
|
|
20731
|
+
if (!record2) return null;
|
|
20732
|
+
const next = edit(structuredClone(record2.memory));
|
|
20733
|
+
if (!next) return null;
|
|
20734
|
+
const saved = await persistence.put(next, record2);
|
|
20735
|
+
notify(change, [saved]);
|
|
20736
|
+
return saved;
|
|
20737
|
+
});
|
|
20738
|
+
const embedInBackground = ({ memory: { memory_id: id, content } }) => {
|
|
20739
|
+
generateEmbedding(content, embeddingOptions).then(
|
|
20740
|
+
(vector) => serialized(id, async () => {
|
|
20741
|
+
const current = await live(id);
|
|
20742
|
+
if (!current || current.memory.content !== content || current.memory.embedding?.length)
|
|
20743
|
+
return;
|
|
20744
|
+
const saved = await persistence.put(
|
|
20745
|
+
{ ...current.memory, embedding: storedVector(vector), embedding_model: model },
|
|
20746
|
+
current
|
|
20747
|
+
);
|
|
20748
|
+
notify("embedding", [saved]);
|
|
20749
|
+
})
|
|
20750
|
+
).catch((error) => {
|
|
20751
|
+
getLogger().warn("[memory/remote-store] Failed to embed memory:", error);
|
|
20752
|
+
});
|
|
20753
|
+
};
|
|
20754
|
+
const newRow = (input) => {
|
|
20755
|
+
const now = Date.now();
|
|
20756
|
+
const scope = input.scope ?? "private";
|
|
20757
|
+
return {
|
|
20758
|
+
memory_id: (0, import_uuid5.v7)(),
|
|
20759
|
+
content: input.content,
|
|
20760
|
+
scope,
|
|
20761
|
+
level: levelFromScope(scope),
|
|
20762
|
+
created_at: now,
|
|
20763
|
+
updated_at: now,
|
|
20764
|
+
is_deleted: false,
|
|
20765
|
+
...input.embedding !== void 0 && {
|
|
20766
|
+
embedding: storedVector(JSON.parse(input.embedding)),
|
|
20767
|
+
embedding_model: input.embeddingModel ?? model
|
|
20768
|
+
},
|
|
20769
|
+
proof_count: 1,
|
|
20770
|
+
source: "manual",
|
|
20771
|
+
...input.eventTime && {
|
|
20772
|
+
event_time_start: input.eventTime.start ?? void 0,
|
|
20773
|
+
event_time_end: input.eventTime.end ?? void 0,
|
|
20774
|
+
event_time_kind: input.eventTime.kind ?? void 0
|
|
20775
|
+
},
|
|
20776
|
+
fact_type: input.factType,
|
|
20777
|
+
geohash: input.geohash,
|
|
20778
|
+
visibility: "private",
|
|
20779
|
+
twin_opt_in: false
|
|
20780
|
+
};
|
|
20781
|
+
};
|
|
20782
|
+
const created = (records, inputs) => {
|
|
20783
|
+
records.forEach((record2, i) => {
|
|
20784
|
+
if (inputs[i].embedding === void 0) embedInBackground(record2);
|
|
20785
|
+
});
|
|
20786
|
+
notify("membership", records);
|
|
20787
|
+
return records.map((record2) => stored(record2.memory));
|
|
20788
|
+
};
|
|
20789
|
+
const asStored = (record2) => record2 ? stored(record2.memory) : null;
|
|
20790
|
+
const everyState = {
|
|
20791
|
+
include_deleted: true,
|
|
20792
|
+
include_archived: true,
|
|
20793
|
+
include_quarantined: true,
|
|
20794
|
+
include_superseded: true
|
|
20795
|
+
};
|
|
20796
|
+
const changesSince = async (cursor2, pending2) => {
|
|
20797
|
+
const records = [];
|
|
20798
|
+
const failed = /* @__PURE__ */ new Set();
|
|
20799
|
+
const collect = (page) => {
|
|
20800
|
+
warnFailed(page.failed);
|
|
20801
|
+
records.push(...page.items);
|
|
20802
|
+
for (const failure of page.failed) failed.add(failure.memory_id);
|
|
20803
|
+
};
|
|
20804
|
+
let resume = cursor2;
|
|
20805
|
+
let next;
|
|
20806
|
+
do {
|
|
20807
|
+
const page = await persistence.query({
|
|
20808
|
+
...everyState,
|
|
20809
|
+
order: "changed",
|
|
20810
|
+
limit: 200,
|
|
20811
|
+
...(next ?? resume) && { cursor: next ?? resume }
|
|
20812
|
+
});
|
|
20813
|
+
collect(page);
|
|
20814
|
+
resume = page.changes_cursor ?? resume;
|
|
20815
|
+
next = page.next_cursor;
|
|
20816
|
+
} while (next);
|
|
20817
|
+
for (const memory_ids of chunks([...pending2], MAX_QUERY_IDS)) {
|
|
20818
|
+
let retry;
|
|
20819
|
+
do {
|
|
20820
|
+
const page = await persistence.query({
|
|
20821
|
+
...everyState,
|
|
20822
|
+
memory_ids,
|
|
20823
|
+
limit: 200,
|
|
20824
|
+
...retry && { cursor: retry }
|
|
20825
|
+
});
|
|
20826
|
+
collect(page);
|
|
20827
|
+
retry = page.next_cursor;
|
|
20828
|
+
} while (retry);
|
|
20829
|
+
}
|
|
20830
|
+
return { records, resume, failed };
|
|
20831
|
+
};
|
|
20832
|
+
let generation = 0;
|
|
20833
|
+
let ready = false;
|
|
20834
|
+
let cursor;
|
|
20835
|
+
let pending = /* @__PURE__ */ new Set();
|
|
20836
|
+
let polling = false;
|
|
20837
|
+
const poll = () => {
|
|
20838
|
+
if (polling) return;
|
|
20839
|
+
polling = true;
|
|
20840
|
+
const current = generation;
|
|
20841
|
+
changesSince(cursor, pending).then(({ records, resume, failed }) => {
|
|
20842
|
+
if (current !== generation) return;
|
|
20843
|
+
const changed = /* @__PURE__ */ new Set();
|
|
20844
|
+
for (const record2 of records) {
|
|
20845
|
+
const id = record2.memory.memory_id;
|
|
20846
|
+
const previous = seen.get(id);
|
|
20847
|
+
seen.set(id, record2);
|
|
20848
|
+
if (!ready) continue;
|
|
20849
|
+
for (const subscriber of subscribers) {
|
|
20850
|
+
const before = previous && subscriptionKey(previous, subscriber.options);
|
|
20851
|
+
if (before !== subscriptionKey(record2, subscriber.options)) changed.add(subscriber);
|
|
20852
|
+
}
|
|
20853
|
+
}
|
|
20854
|
+
ready = true;
|
|
20855
|
+
cursor = resume;
|
|
20856
|
+
pending = failed;
|
|
20857
|
+
for (const subscriber of changed)
|
|
20858
|
+
if (subscribers.has(subscriber)) safely(subscriber.onChange);
|
|
20859
|
+
}).catch((error) => {
|
|
20860
|
+
getLogger().warn("[memory/remote-store] Subscription poll failed:", error);
|
|
20861
|
+
}).finally(() => {
|
|
20862
|
+
polling = false;
|
|
20863
|
+
});
|
|
20864
|
+
};
|
|
20865
|
+
return {
|
|
20866
|
+
list: async (listOptions = {}) => {
|
|
20867
|
+
const order = listOptions.since ? "updated" : "created";
|
|
20868
|
+
const filters = {
|
|
20869
|
+
...stateFilters(listOptions),
|
|
20870
|
+
include_embeddings: true,
|
|
20871
|
+
order,
|
|
20872
|
+
...listOptions.scopes?.length && { scopes: listOptions.scopes },
|
|
20873
|
+
...listOptions.factTypes?.length && { fact_types: listOptions.factTypes },
|
|
20874
|
+
...listOptions.visibility?.length && { visibility: listOptions.visibility },
|
|
20875
|
+
...listOptions.since && { updated_after: listOptions.since.getTime() }
|
|
20876
|
+
};
|
|
20877
|
+
const max = listOptions.limit && listOptions.limit > 0 ? listOptions.limit : Infinity;
|
|
20878
|
+
const variants = bounded(filters, "scopes").flatMap((f) => bounded(f, "fact_types"));
|
|
20879
|
+
if (!listOptions.memoryIds && variants.length === 1)
|
|
20880
|
+
return (await enumerate(filters, max)).map((r) => stored(r.memory));
|
|
20881
|
+
const fetched = await Promise.all(
|
|
20882
|
+
variants.map(
|
|
20883
|
+
(variant) => listOptions.memoryIds ? enumerateIds(listOptions.memoryIds, variant) : enumerate(variant, max)
|
|
20884
|
+
)
|
|
20885
|
+
);
|
|
20886
|
+
const rows = [...new Map(fetched.flat().map((r) => [r.memory.memory_id, r])).values()].map((record2) => stored(record2.memory)).sort(
|
|
20887
|
+
(a, b) => order === "updated" ? b.updatedAt.getTime() - a.updatedAt.getTime() || (a.uniqueId < b.uniqueId ? 1 : -1) : b.createdAt.getTime() - a.createdAt.getTime() || (a.uniqueId < b.uniqueId ? 1 : -1)
|
|
20888
|
+
);
|
|
20889
|
+
return rows.slice(0, max);
|
|
20890
|
+
},
|
|
20891
|
+
get: async (id) => asStored(await live(id)),
|
|
20892
|
+
listArchived: async () => (await enumerate({ archived_only: true, order: "archived", include_embeddings: true })).map(
|
|
20893
|
+
(record2) => stored(record2.memory)
|
|
20894
|
+
),
|
|
20895
|
+
memoriesByTopics: async (names) => {
|
|
20896
|
+
const wanted = new Set(names.map(normalizeEntityName).filter(Boolean));
|
|
20897
|
+
const out = /* @__PURE__ */ new Map();
|
|
20898
|
+
const pages = await Promise.all(
|
|
20899
|
+
chunks([...wanted], MAX_QUERY_TOPICS).map((topics) => enumerate({ topics }))
|
|
20900
|
+
);
|
|
20901
|
+
for (const { memory } of pages.flat()) {
|
|
20902
|
+
const matched = [...canonicalTopics(memory)].filter((name) => wanted.has(name));
|
|
20903
|
+
if (matched.length) out.set(memory.memory_id, new Set(matched));
|
|
20904
|
+
}
|
|
20905
|
+
return out;
|
|
20906
|
+
},
|
|
20907
|
+
topicsByMemories: async (memoryIds) => {
|
|
20908
|
+
const out = /* @__PURE__ */ new Map();
|
|
20909
|
+
for (const { memory } of await enumerateIds(memoryIds, {
|
|
20910
|
+
include_archived: true,
|
|
20911
|
+
include_superseded: true,
|
|
20912
|
+
include_quarantined: true
|
|
20913
|
+
})) {
|
|
20914
|
+
const topics = canonicalTopics(memory);
|
|
20915
|
+
if (topics.size) out.set(memory.memory_id, topics);
|
|
20916
|
+
}
|
|
20917
|
+
return out;
|
|
20918
|
+
},
|
|
20919
|
+
create: async (input) => {
|
|
20920
|
+
const record2 = await persistence.put(newRow(input), 0);
|
|
20921
|
+
return created([record2], [input])[0];
|
|
20922
|
+
},
|
|
20923
|
+
createMany: async (inputs) => {
|
|
20924
|
+
const out = [];
|
|
20925
|
+
for (const batch of chunks(inputs, MAX_BATCH)) {
|
|
20926
|
+
let records;
|
|
20927
|
+
try {
|
|
20928
|
+
records = await persistence.putMany(
|
|
20929
|
+
batch.map((input) => ({ memory: newRow(input), expectedVersion: 0 }))
|
|
20930
|
+
);
|
|
20931
|
+
} catch (error) {
|
|
20932
|
+
if (out.length === 0) throw error;
|
|
20933
|
+
throw new RemoteMemoryPartialCreateError(out, error);
|
|
20934
|
+
}
|
|
20935
|
+
out.push(...created(records, batch));
|
|
20936
|
+
}
|
|
20937
|
+
return out;
|
|
20938
|
+
},
|
|
20939
|
+
update: async (id, patch) => {
|
|
20940
|
+
const saved = await mutate(id, "edit", (memory) => {
|
|
20941
|
+
if (memory.superseded_by) return null;
|
|
20942
|
+
memory.content = patch.content;
|
|
20943
|
+
memory.updated_at = Date.now();
|
|
20944
|
+
if (patch.scope !== void 0) {
|
|
20945
|
+
memory.level = levelForScopeChange(
|
|
20946
|
+
{ level: memory.level, scope: memory.scope },
|
|
20947
|
+
patch.scope
|
|
20948
|
+
);
|
|
20949
|
+
memory.scope = patch.scope;
|
|
20950
|
+
}
|
|
20951
|
+
if (patch.factType !== void 0) memory.fact_type = patch.factType ?? void 0;
|
|
20952
|
+
if (patch.eventTime !== void 0) {
|
|
20953
|
+
memory.event_time_start = patch.eventTime?.start ?? void 0;
|
|
20954
|
+
memory.event_time_end = patch.eventTime?.end ?? void 0;
|
|
20955
|
+
memory.event_time_kind = patch.eventTime?.kind ?? void 0;
|
|
20956
|
+
}
|
|
20957
|
+
if (patch.embedding === void 0 || patch.embedding === null) {
|
|
20958
|
+
memory.embedding = [];
|
|
20959
|
+
delete memory.embedding_model;
|
|
20960
|
+
} else {
|
|
20961
|
+
memory.embedding = storedVector(JSON.parse(patch.embedding));
|
|
20962
|
+
memory.embedding_model = patch.embeddingModel ?? model;
|
|
20963
|
+
}
|
|
20964
|
+
return memory;
|
|
20965
|
+
});
|
|
20966
|
+
if (saved && patch.embedding === void 0) embedInBackground(saved);
|
|
20967
|
+
return asStored(saved);
|
|
20968
|
+
},
|
|
20969
|
+
delete: async (id) => !!await mutate(id, "membership", (memory) => ({ ...memory, is_deleted: true })),
|
|
20970
|
+
supersede: async (id, supersededById) => {
|
|
20971
|
+
if (id === supersededById) return false;
|
|
20972
|
+
const [first, second] = [id, supersededById].sort();
|
|
20973
|
+
return serialized(
|
|
20974
|
+
first,
|
|
20975
|
+
() => serialized(second, async () => {
|
|
20976
|
+
const [old, next] = await Promise.all([live(id), live(supersededById)]);
|
|
20977
|
+
if (!old || !next || old.memory.superseded_by || next.memory.superseded_by) return false;
|
|
20978
|
+
if (old.memory.kind !== void 0 && old.memory.kind !== null) return false;
|
|
20979
|
+
const saved = await persistence.putMany([
|
|
20980
|
+
{
|
|
20981
|
+
memory: { ...old.memory, superseded_by: supersededById, superseded_at: Date.now() },
|
|
20982
|
+
expectedVersion: old
|
|
20983
|
+
},
|
|
20984
|
+
{ memory: next.memory, expectedVersion: next }
|
|
20985
|
+
]);
|
|
20986
|
+
notify("membership", saved);
|
|
20987
|
+
return true;
|
|
20988
|
+
})
|
|
20989
|
+
);
|
|
20990
|
+
},
|
|
20991
|
+
archive: async (id) => !!await mutate(
|
|
20992
|
+
id,
|
|
20993
|
+
"edit",
|
|
20994
|
+
(memory) => memory.archived_at === void 0 || memory.archived_at === null ? { ...memory, archived_at: Date.now() } : null
|
|
20995
|
+
),
|
|
20996
|
+
restore: (id) => serialized(id, async () => {
|
|
20997
|
+
const record2 = await live(id);
|
|
20998
|
+
if (!record2) return false;
|
|
20999
|
+
if (record2.memory.archived_at === void 0 || record2.memory.archived_at === null)
|
|
21000
|
+
return true;
|
|
21001
|
+
const { archived_at: _archivedAt, ...memory } = record2.memory;
|
|
21002
|
+
notify("edit", [await persistence.put(memory, record2)]);
|
|
21003
|
+
return true;
|
|
21004
|
+
}),
|
|
21005
|
+
setTopics: async (memoryId, topics) => asStored(
|
|
21006
|
+
await mutate(memoryId, "edit", (memory) => ({
|
|
21007
|
+
...memory,
|
|
21008
|
+
topics: serializeTopics(mergeTopics([], topicInputs(topics, "user"))),
|
|
21009
|
+
topics_user_managed: true,
|
|
21010
|
+
topics_updated_at: Date.now()
|
|
21011
|
+
}))
|
|
21012
|
+
),
|
|
21013
|
+
addTopics: async (memoryId, topics) => {
|
|
21014
|
+
const added = topicInputs(topics, "auto");
|
|
21015
|
+
const saved = await mutate(memoryId, "edit", (memory) => ({
|
|
21016
|
+
...memory,
|
|
21017
|
+
topics: serializeTopics(mergeTopics(parseTopics(memory.topics) ?? [], added)),
|
|
21018
|
+
topics_updated_at: Date.now()
|
|
21019
|
+
}));
|
|
21020
|
+
if (!saved) return [];
|
|
21021
|
+
const now = /* @__PURE__ */ new Date();
|
|
21022
|
+
return mergeTopics([], added).map(
|
|
21023
|
+
(topic) => ({
|
|
21024
|
+
uniqueId: normalizeEntityName(topic.name),
|
|
21025
|
+
canonicalName: normalizeEntityName(topic.name),
|
|
21026
|
+
kind: topic.kind ?? null,
|
|
21027
|
+
createdAt: now,
|
|
21028
|
+
updatedAt: now
|
|
21029
|
+
})
|
|
21030
|
+
);
|
|
21031
|
+
},
|
|
21032
|
+
setVisibility: async (id, visibility, visibilityOptions) => asStored(
|
|
21033
|
+
await mutate(id, "edit", (memory) => {
|
|
21034
|
+
memory.visibility = visibility;
|
|
21035
|
+
if (visibility === "private") delete memory.published_at;
|
|
21036
|
+
else memory.published_at ?? (memory.published_at = Date.now());
|
|
21037
|
+
if (visibilityOptions?.twinOptIn !== void 0)
|
|
21038
|
+
memory.twin_opt_in = visibilityOptions.twinOptIn;
|
|
21039
|
+
return memory;
|
|
21040
|
+
})
|
|
21041
|
+
),
|
|
21042
|
+
recall: (query, recallOptions) => pipeline.recall(query, recallOptions),
|
|
21043
|
+
retain: async (content, retainOptions) => {
|
|
21044
|
+
const result = await pipeline.retain(content, retainOptions);
|
|
21045
|
+
if (result.action === "create" || result.action === "supersede") notify("membership");
|
|
21046
|
+
else if (result.action === "update" || result.action === "merge") notify("edit");
|
|
21047
|
+
return result;
|
|
21048
|
+
},
|
|
21049
|
+
subscribe: (onChange, subscribeOptions = {}) => {
|
|
21050
|
+
const subscriber = { onChange, options: subscribeOptions };
|
|
21051
|
+
subscribers.add(subscriber);
|
|
21052
|
+
if (pollIntervalMs > 0 && !timer) {
|
|
21053
|
+
timer = setInterval(poll, pollIntervalMs);
|
|
21054
|
+
poll();
|
|
21055
|
+
}
|
|
21056
|
+
return () => {
|
|
21057
|
+
subscribers.delete(subscriber);
|
|
21058
|
+
if (subscribers.size || !timer) return;
|
|
21059
|
+
clearInterval(timer);
|
|
21060
|
+
timer = void 0;
|
|
21061
|
+
generation++;
|
|
21062
|
+
seen.clear();
|
|
21063
|
+
ready = false;
|
|
21064
|
+
cursor = void 0;
|
|
21065
|
+
pending = /* @__PURE__ */ new Set();
|
|
21066
|
+
};
|
|
21067
|
+
}
|
|
21068
|
+
};
|
|
21069
|
+
}
|
|
21070
|
+
|
|
20469
21071
|
// src/lib/memory/synthesizeProfile.ts
|
|
20470
21072
|
init_internalFlowMarker();
|
|
20471
21073
|
init_logger();
|
|
@@ -23891,7 +24493,7 @@ function useChat(options) {
|
|
|
23891
24493
|
|
|
23892
24494
|
// src/expo/useChatStorage.ts
|
|
23893
24495
|
var import_react5 = require("react");
|
|
23894
|
-
var
|
|
24496
|
+
var import_uuid7 = require("uuid");
|
|
23895
24497
|
init_clientConfig();
|
|
23896
24498
|
|
|
23897
24499
|
// src/lib/chat/assembleMessages.ts
|
|
@@ -24554,9 +25156,9 @@ async function decryptMediaFields(media, address, signMessage, embeddedWalletSig
|
|
|
24554
25156
|
}
|
|
24555
25157
|
|
|
24556
25158
|
// src/lib/db/media/types.ts
|
|
24557
|
-
var
|
|
25159
|
+
var import_uuid6 = require("uuid");
|
|
24558
25160
|
function generateMediaId() {
|
|
24559
|
-
return `media_${(0,
|
|
25161
|
+
return `media_${(0, import_uuid6.v7)()}`;
|
|
24560
25162
|
}
|
|
24561
25163
|
|
|
24562
25164
|
// src/lib/db/media/operations.ts
|
|
@@ -25516,7 +26118,7 @@ function useChatStorage(options) {
|
|
|
25516
26118
|
};
|
|
25517
26119
|
};
|
|
25518
26120
|
pendingResumeRef.current = null;
|
|
25519
|
-
const effectiveAssistantUniqueId = assistantUniqueId ?? (resumable ? `msg_${(0,
|
|
26121
|
+
const effectiveAssistantUniqueId = assistantUniqueId ?? (resumable ? `msg_${(0, import_uuid7.v7)()}` : void 0);
|
|
25520
26122
|
const embedToolText = (text12, mask, masked, token) => {
|
|
25521
26123
|
const opts = {
|
|
25522
26124
|
getToken: token,
|
|
@@ -26034,7 +26636,7 @@ function useChatStorage(options) {
|
|
|
26034
26636
|
const detachedResult = result;
|
|
26035
26637
|
if (detachedResult.detached) {
|
|
26036
26638
|
recordToolSetTurn(database, convId, matchedToolSets);
|
|
26037
|
-
const rowId = effectiveAssistantUniqueId ?? `msg_${(0,
|
|
26639
|
+
const rowId = effectiveAssistantUniqueId ?? `msg_${(0, import_uuid7.v7)()}`;
|
|
26038
26640
|
pendingResumeRef.current = {
|
|
26039
26641
|
handle: detachedResult.resume ?? null,
|
|
26040
26642
|
convId,
|
|
@@ -26546,6 +27148,7 @@ function useChatStorage(options) {
|
|
|
26546
27148
|
MEDIUM_TTL_MS,
|
|
26547
27149
|
MEMORY_KINDS,
|
|
26548
27150
|
MEMORY_LEVELS,
|
|
27151
|
+
MemoryKeyError,
|
|
26549
27152
|
MemoryLevelError,
|
|
26550
27153
|
NEVER_TTL_MS,
|
|
26551
27154
|
NODE_BUDGET,
|
|
@@ -26558,6 +27161,7 @@ function useChatStorage(options) {
|
|
|
26558
27161
|
RECALL_MAX_LIMIT,
|
|
26559
27162
|
RECALL_TOOL_NAME,
|
|
26560
27163
|
RemoteMemoryError,
|
|
27164
|
+
RemoteMemoryPartialCreateError,
|
|
26561
27165
|
RerankerUnavailableError,
|
|
26562
27166
|
SDK_SCHEMA_VERSION,
|
|
26563
27167
|
SHORT_TTL_MS,
|
|
@@ -26623,6 +27227,7 @@ function useChatStorage(options) {
|
|
|
26623
27227
|
createRecallTool,
|
|
26624
27228
|
createRemoteMemoryPersistence,
|
|
26625
27229
|
createRemoteMemoryPipeline,
|
|
27230
|
+
createRemoteMemoryStore,
|
|
26626
27231
|
createStockPricePreProcessor,
|
|
26627
27232
|
createStreamingDeAnonymizer,
|
|
26628
27233
|
createVaultEmbeddingCache,
|
|
@@ -26639,6 +27244,7 @@ function useChatStorage(options) {
|
|
|
26639
27244
|
deleteVaultMemoryOp,
|
|
26640
27245
|
dequantizeEmbedding,
|
|
26641
27246
|
deriveKeyFromSignatureBytes,
|
|
27247
|
+
deriveMemoryKeyRing,
|
|
26642
27248
|
discoverNotionOAuthEndpoints,
|
|
26643
27249
|
eagerEmbedContent,
|
|
26644
27250
|
embedAllMessages,
|
|
@@ -26682,6 +27288,7 @@ function useChatStorage(options) {
|
|
|
26682
27288
|
isPiiRedactor,
|
|
26683
27289
|
isRerankerAvailable,
|
|
26684
27290
|
maskScopedEmbeddingCache,
|
|
27291
|
+
memoryCipher,
|
|
26685
27292
|
moveMemoriesToFolderOp,
|
|
26686
27293
|
noopLogger,
|
|
26687
27294
|
onKeyAvailable,
|
|
@@ -26691,6 +27298,7 @@ function useChatStorage(options) {
|
|
|
26691
27298
|
queueManager,
|
|
26692
27299
|
rankProfileCandidates,
|
|
26693
27300
|
recall,
|
|
27301
|
+
reencryptMemoryField,
|
|
26694
27302
|
reflect,
|
|
26695
27303
|
refreshEncryptionKeyIfMatches,
|
|
26696
27304
|
refreshNotionAccessToken,
|